PRIVATE HTChildAnchor * HTAnchor_findChild ARGS2 (HTParentAnchor *,parent, CONST char *,tag) { HTChildAnchor *child; HTList *kids; if (! parent) { if (TRACE) printf ("HTAnchor_findChild called with NULL parent.\n"); return NULL; } if (kids = parent->children) { /* parent has children : search them */ if (tag && *tag) { /* TBL */ while (child = HTList_nextObject (kids)) { if (equivalent(child->tag, tag)) { /* Case sensitive 920226 */ if (TRACE) printf ( "Child anchor %p of parent %p with name `%s' already exists.\n", child, parent, tag); return child; } } } /* end if tag is void */ } else /* parent doesn't have any children yet : create family */ parent->children = HTList_new (); child = HTChildAnchor_new (); if (TRACE) fprintf(stderr, "new Anchor %p named `%s' is child of %p\n", child, (int)tag ? tag : (CONST char *)"" , parent); /* int for apollo */ HTList_addObject (parent->children, child); child->parent = parent; StrAllocCopy(child->tag, tag); return child; }
/* Create new or find old child anchor ** ----------------------------------- ** ** Me one is for a new anchor being edited into an existing ** document. The parent anchor must already exist. All ** children without tags (no NAME attribut) points to the same NULL ** child. ** Children are now hashed for performance reasons. Thanks to ** Michael Farrar */ PUBLIC HTChildAnchor * HTAnchor_findChild (HTParentAnchor * parent, const char * tag) { HTChildAnchor * child = NULL; HTList * kids = NULL; if (!parent) { HTTRACE(ANCH_TRACE, "Child Anchor Bad argument\n"); return NULL; } /* Find a hash for this tag (if any) */ { int hash = 0; /* ** If tag is empty then use hash value 0 */ if (tag) { const char * ptr = tag; for(; *ptr; ptr++) hash = (int) ((hash*3 + (*(unsigned char*)ptr)) % CHILD_HASH_SIZE); } if (!parent->children) { if (!(parent->children = (HTList **) HT_CALLOC(CHILD_HASH_SIZE, sizeof(HTList *)))) HT_OUTOFMEM("HTAnchor_findChild"); } if (!parent->children[hash]) parent->children[hash] = HTList_new(); kids = parent->children[hash]; } /* First search list of children to see if tag is already there */ if (tag && *tag) { HTList * cur = kids; while ((child = (HTChildAnchor *) HTList_nextObject(cur))) { if (child->tag && !strcmp(child->tag, tag)) { HTTRACE(ANCH_TRACE, "Child Anchor %p of parent %p with name `%s' already exists.\n" _ (void *) child _ (void *) parent _ tag); return child; } } } /* If not found then create a new child anchor */ child = HTChildAnchor_new(); HTList_addObject(kids, (void *) child); child->parent = parent; if (tag) StrAllocCopy(child->tag, tag); HTTRACE(ANCH_TRACE, "Child Anchor New Anchor %p named `%s' is child of %p\n" _ (void *) child _ tag ? tag : (const char *) "" _ (void *)parent); return child; }
/* Create new or find old sub-anchor ** --------------------------------- ** ** This one is for a named child. ** The parent anchor must already exist. */ PRIVATE HTChildAnchor * HTAnchor_findNamedChild ARGS2( HTParentAnchor0 *, parent, CONST char *, tag) { HTChildAnchor *child; if (parent && tag && *tag) { /* TBL */ if (parent->children) { /* ** Parent has children. Search them. */ HTChildAnchor sample; sample.tag = (char*)tag; /* for compare_anchors() only */ child = (HTChildAnchor *)HTBTree_search(parent->children, &sample); if (child != NULL) { CTRACE((tfp, "Child anchor %p of parent %p with name `%s' already exists.\n", (void *)child, (void *)parent, tag)); return(child); } } else { /* parent doesn't have any children yet : create family */ parent->children = HTBTree_new(compare_anchors); } child = HTChildAnchor_new(parent); CTRACE((tfp, "HTAnchor: New Anchor %p named `%s' is child of %p\n", (void *)child, NonNull(tag), (void *)child->parent)); StrAllocCopy(child->tag, tag); /* should be set before HTBTree_add */ HTBTree_add(parent->children, child); return(child); } else { CTRACE((tfp, "HTAnchor_findNamedChild called with NULL parent.\n")); return(NULL); } }