📄 htanchor.c
字号:
return foundAnchor;}/* Create new or find old named anchor - simple form** -------------------------------------------------**** Like HTAnchor_findAddress, but simpler to use for simple cases.** No post data etc. can be supplied. - kw*/PUBLIC HTParentAnchor * HTAnchor_findSimpleAddress ARGS1( CONST char *, url){ DocAddress urldoc; urldoc.address = (char *)url; /* ignore warning, it IS treated like const - kw */ urldoc.post_data = NULL; urldoc.post_content_type = NULL; urldoc.bookmark = NULL; urldoc.isHEAD = FALSE; urldoc.safe = FALSE; return HTAnchor_findAddress(&urldoc);}/* Link me Anchor to another given one** -------------------------------------*/PRIVATE BOOL HTAnchor_link ARGS3( HTChildAnchor *, child, HTAnchor *, destination, HTLinkType *, type){ if (!(child && destination)) return(NO); /* Can't link to/from non-existing anchor */ CTRACE((tfp, "Linking child %p to anchor %p\n", child, destination)); if (child->dest) { CTRACE((tfp, "*** child anchor already has destination, exiting!\n")); return(NO); } child->dest = destination; child->type = type; if (child->parent != destination->parent) /* link only foreign children */ HTList_linkObject(&destination->parent->sources, child, &child->_add_sources); return(YES); /* Success */}/* Delete an anchor and possibly related things (auto garbage collection)** --------------------------------------------**** The anchor is only deleted if the corresponding document is not loaded.** All outgoing links from children are deleted, and children are** removed from the sources lists of theirs targets.** We also try to delete the targets whose documents are not loaded.** If this anchor's sources list is empty, we delete it and its children.*//* * Recursively try to delete destination anchor of this child. * In any event, this will tell destination anchor that we * no longer consider it a destination. */PRIVATE void deleteLinks ARGS1( HTChildAnchor *, me){ /* * Unregister me with our destination anchor's parent. */ if (me->dest) { HTParentAnchor0 *parent = me->dest->parent; /* * Start. Set the dest pointer to zero. */ me->dest = NULL; /* * Remove me from the parent's sources so that the * parent knows one less anchor is its dest. */ if ((me->parent != parent) && !HTList_isEmpty(&parent->sources)) { /* * Really should only need to deregister once. */ HTList_unlinkObject(&parent->sources, (void *)me); } /* * Recursive call. * Test here to avoid calling overhead. * Don't delete if document is loaded or being loaded. */ if ((me->parent != parent) && !parent->underway && (!parent->info || !parent->info->document)) { HTAnchor_delete(parent); } /* * At this point, we haven't a destination. Set it to be * so. * Leave the HTAtom pointed to by type up to other code to * handle (reusable, near static). */ me->type = NULL; }}PRIVATE void HTParentAnchor_free PARAMS(( HTParentAnchor * me));PUBLIC BOOL HTAnchor_delete ARGS1( HTParentAnchor0 *, me){ /* * Memory leaks fixed. * 05-27-94 Lynx 2-3-1 Garrett Arch Blythe */ HTBTElement *ele; HTChildAnchor *child; /* * Do nothing if nothing to do. */ if (!me) { return(NO); } /* * Don't delete if document is loaded or being loaded. */ if (me->underway || (me->info && me->info->document)) { return(NO); } /* * Mark ourselves busy, so that recursive calls of this function * on this HTParentAnchor0 will not free it from under our feet. - kw */ me->underway = TRUE; { /* * Delete all outgoing links from named children. * Do not delete named children itself (may have incoming links). */ if (me->children) { ele = HTBTree_next(me->children, NULL); while (ele != NULL) { child = (HTChildAnchor *)HTBTree_object(ele); if (child->dest) deleteLinks(child); ele = HTBTree_next(me->children, ele); } } } me->underway = FALSE; /* * There are still incoming links to this one (we are the * destination of another anchor). */ if (!HTList_isEmpty(&me->sources)) { /* * Can't delete parent, still have sources. */ return(NO); } /* * No more incoming and outgoing links : kill everything * First, delete named children. */ if (me->children) { ele = HTBTree_next(me->children, NULL); while (ele != NULL) { child = (HTChildAnchor *)HTBTree_object(ele); FREE(child->tag); FREE(child); ele = HTBTree_next(me->children, ele); } HTBTree_free(me->children); } /* * Delete the ParentAnchor, if any. (Document was already deleted). */ if (me->info) { HTParentAnchor_free(me->info); FREE(me->info); } /* * Remove ourselves from the hash table's list. */ HTList_unlinkObject(&(adult_table[me->adult_hash]), (void *)me); /* * Free the address. */ FREE(me->address); /* * Finally, kill the parent anchor passed in. */ FREE(me); return(YES);}/* * Unnamed children (children_notag) have no sence without HText - * delete them and their links if we are about to free HText. * Document currently exists. Called within HText_free(). */PUBLIC void HTAnchor_delete_links ARGS1( HTParentAnchor *, me){ HTList *cur; HTChildAnchor *child; /* * Do nothing if nothing to do. */ if (!me || !me->document) { return; } /* * Mark ourselves busy, so that recursive calls * on this HTParentAnchor0 will not free it from under our feet. - kw */ me->parent->underway = TRUE; /* * Delete all outgoing links from unnamed children. */ if (!HTList_isEmpty(&me->children_notag)) { cur = &me->children_notag; while ((child = (HTChildAnchor *)HTList_unlinkLastObject(cur)) != 0) { deleteLinks(child); /* child allocated in HText pool, HText_free() will free it later*/ } } me->parent->underway = FALSE;}PRIVATE void HTParentAnchor_free ARGS1( HTParentAnchor *, me){ /* * Delete the methods list. */ if (me->methods) { /* * Leave what the methods point to up in memory for * other code (near static stuff). */ HTList_delete(me->methods); me->methods = NULL; } /* * Free up all allocated members. */ FREE(me->charset); FREE(me->isIndexAction); FREE(me->isIndexPrompt); FREE(me->title); FREE(me->physical); BStrFree(me->post_data); FREE(me->post_content_type); FREE(me->bookmark); FREE(me->owner); FREE(me->RevTitle); FREE(me->citehost);#ifdef USE_SOURCE_CACHE HTAnchor_clearSourceCache(me);#endif if (me->FileCache) { FILE *fd; if ((fd = fopen(me->FileCache, "r")) != NULL) { fclose(fd); remove(me->FileCache); } FREE(me->FileCache); } FREE(me->SugFname); FREE(me->cache_control); FREE(me->content_type); FREE(me->content_language); FREE(me->content_encoding); FREE(me->content_base); FREE(me->content_disposition); FREE(me->content_location); FREE(me->content_md5); FREE(me->message_id); FREE(me->subject); FREE(me->date); FREE(me->expires); FREE(me->last_modified); FREE(me->ETag); FREE(me->server);#ifdef USE_COLOR_STYLE FREE(me->style);#endif /* * Original code wanted a way to clean out the HTFormat if no * longer needed (ref count?). I'll leave it alone since * those HTAtom objects are a little harder to know where * they are being referenced all at one time. (near static) */ FREE(me->UCStages); ImageMapList_free(me->imaps);}#ifdef USE_SOURCE_CACHEPUBLIC void HTAnchor_clearSourceCache ARGS1( HTParentAnchor *, me){ /* * Clean up the source cache, if any. */ if (me->source_cache_file) { CTRACE((tfp, "SourceCache: Removing file %s\n", me->source_cache_file)); LYRemoveTemp(me->source_cache_file); FREE(me->source_cache_file); } if (me->source_cache_chunk) { CTRACE((tfp, "SourceCache: Removing memory chunk %p\n", (void *)me->source_cache_chunk)); HTChunkFree(me->source_cache_chunk); me->source_cache_chunk = NULL; }}#endif /* USE_SOURCE_CACHE *//* Data access functions** ---------------------*/PUBLIC HTParentAnchor * HTAnchor_parent ARGS1( HTAnchor *, me){ if (!me) return NULL; if (me->parent->info) return me->parent->info; /* else: create a new structure */ return HTParentAnchor_new(me->parent);}PUBLIC void HTAnchor_setDocument ARGS2( HTParentAnchor *, me, HyperDoc *, doc){ if (me) me->document = doc;}PUBLIC HyperDoc * HTAnchor_document ARGS1( HTParentAnchor *, me){ return( me ? me->document : NULL);}PUBLIC char * HTAnchor_address ARGS1( HTAnchor *, me){ char *addr = NULL; if (me) { if (((HTParentAnchor0 *)me == me->parent) || ((HTParentAnchor *)me == me->parent->info) || !((HTChildAnchor *)me)->tag) { /* it's an adult or no tag */ StrAllocCopy(addr, me->parent->address); } else { /* it's a named child */ HTSprintf0(&addr, "%s#%s", me->parent->address, ((HTChildAnchor *)me)->tag); } } return(addr);}PUBLIC void HTAnchor_setFormat ARGS2( HTParentAnchor *, me, HTFormat, form){ if (me) me->format = form;}PUBLIC HTFormat HTAnchor_format ARGS1( HTParentAnchor *, me){ return( me ? me->format : NULL);}PUBLIC void HTAnchor_setIndex ARGS2( HTParentAnchor *, me, CONST char *, address){ if (me) { me->isIndex = YES; StrAllocCopy(me->isIndexAction, address); }}PUBLIC void HTAnchor_setPrompt ARGS2( HTParentAnchor *, me, CONST char *, prompt){ if (me) { StrAllocCopy(me->isIndexPrompt, prompt); }}PUBLIC BOOL HTAnchor_isIndex ARGS1( HTParentAnchor *, me){ return( me ? me->isIndex : NO);}/* Whether Anchor has been designated as an ISMAP link** (normally by presence of an ISMAP attribute on A or IMG) - KW*/PUBLIC BOOL HTAnchor_isISMAPScript ARGS1( HTAnchor *, me){ return( (me && me->parent->info) ? me->parent->info->isISMAPScript : NO);}#if defined(USE_COLOR_STYLE)/* Style handling.*/PUBLIC CONST char * HTAnchor_style ARGS1( HTParentAnchor *, me){ return( me ? me->style : NULL);}PUBLIC void HTAnchor_setStyle ARGS2( HTParentAnchor *, me, CONST char *, style){ if (me) { StrAllocCopy(me->style, style); }}#endif/* Title handling.*/PUBLIC CONST char * HTAnchor_title ARGS1( HTParentAnchor *, me){ return( me ? me->title : NULL);}PUBLIC void HTAnchor_setTitle ARGS2( HTParentAnchor *, me, CONST char *, title){ int i; if (me) { if (title) { StrAllocCopy(me->title, title); for (i = 0; me->title[i]; i++) { if (UCH(me->title[i]) == 1 ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -