Annotation of libwww/Library/src/HTAnchor.c, revision 1.15

1.14      frystyk     1: /*                                                                  HTAnchor.c
                      2: **     HYPERTEXT "ANCHOR" OBJECT
1.1       timbl       3: **
1.14      frystyk     4: **     (c) COPYRIGHT CERN 1994.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
                      6: **
                      7: **     An anchor represents a region of a hypertext document which is
                      8: **     linked to another anchor in the same or a different document.
1.1       timbl       9: **
                     10: ** History
                     11: **         Nov 1990  Written in Objective-C for the NeXT browser (TBL)
                     12: **     24-Oct-1991 (JFG), written in C, browser-independant 
                     13: **     21-Nov-1991 (JFG), first complete version
                     14: **
                     15: */
                     16: 
1.15    ! roeber     17: #include "sysdep.h"
        !            18: 
1.7       luotonen   19: #include "HTFormat.h"
1.1       timbl      20: #include "HTUtils.h"
                     21: #include "HTParse.h"
1.11      frystyk    22: #include "HTFWriter.h"                                   /* for cache stuff */
                     23: #include "HTAnchor.h"                                   /* Implemented here */
                     24: 
                     25: #define HASH_SIZE 101          /* Arbitrary prime. Memory/speed tradeoff */
1.1       timbl      26: 
                     27: typedef struct _HyperDoc Hyperdoc;
1.15    ! roeber     28: #ifdef NO_PTR_UNDEF_STRUCT
1.1       timbl      29: struct _HyperDoc {
1.15    ! roeber     30:        int junk;       /* some platforms cannot handle pointers to undefined structs */
1.1       timbl      31: };
                     32: #endif
                     33: 
                     34: PRIVATE HTList **adult_table=0;  /* Point to table of lists of all parents */
                     35: 
                     36: /*                             Creation Methods
                     37: **                             ================
                     38: **
                     39: **     Do not use "new" by itself outside this module. In order to enforce
                     40: **     consistency, we insist that you furnish more information about the
                     41: **     anchor you are creating : use newWithParent or newWithAddress.
                     42: */
                     43: 
                     44: PRIVATE HTParentAnchor * HTParentAnchor_new
                     45:   NOARGS
                     46: {
                     47:   HTParentAnchor *newAnchor = 
                     48:     (HTParentAnchor *) calloc (1, sizeof (HTParentAnchor));  /* zero-filled */
                     49:   newAnchor->parent = newAnchor;
                     50:   return newAnchor;
                     51: }
                     52: 
                     53: PRIVATE HTChildAnchor * HTChildAnchor_new
                     54:   NOARGS
                     55: {
                     56:   return (HTChildAnchor *) calloc (1, sizeof (HTChildAnchor));  /* zero-filled */
                     57: }
                     58: 
                     59: 
                     60: /*     Case insensitive string comparison
                     61: **     ----------------------------------
                     62: ** On entry,
                     63: **     s       Points to one string, null terminated
                     64: **     t       points to the other.
                     65: ** On exit,
                     66: **     returns YES if the strings are equivalent ignoring case
                     67: **             NO if they differ in more than  their case.
                     68: */
                     69: 
                     70: PRIVATE BOOL equivalent
                     71:   ARGS2 (CONST char *,s, CONST char *,t)
                     72: {
                     73:   if (s && t) {  /* Make sure they point to something */
                     74:     for ( ; *s && *t ; s++, t++) {
                     75:         if (TOUPPER(*s) != TOUPPER(*t))
                     76:          return NO;
                     77:     }
                     78:     return TOUPPER(*s) == TOUPPER(*t);
                     79:   } else
                     80:     return s == t;  /* Two NULLs are equivalent, aren't they ? */
                     81: }
                     82: 
                     83: 
                     84: /*     Create new or find old sub-anchor
                     85: **     ---------------------------------
                     86: **
1.3       timbl      87: **     Me one is for a new anchor being edited into an existing
1.1       timbl      88: **     document. The parent anchor must already exist.
                     89: */
                     90: 
1.2       timbl      91: PUBLIC HTChildAnchor * HTAnchor_findChild
1.1       timbl      92:   ARGS2 (HTParentAnchor *,parent, CONST char *,tag)
                     93: {
                     94:   HTChildAnchor *child;
                     95:   HTList *kids;
                     96: 
                     97:   if (! parent) {
1.11      frystyk    98:     if (ANCH_TRACE)
1.8       frystyk    99:        fprintf(stderr, "HTAnchor_findChild called with NULL parent.\n");
1.1       timbl     100:     return NULL;
                    101:   }
1.7       luotonen  102:   if ((kids = parent->children)) {  /* parent has children : search them */
1.1       timbl     103:     if (tag && *tag) {         /* TBL */
1.12      frystyk   104:        while ((child = (HTChildAnchor *) HTList_nextObject (kids))) {
1.1       timbl     105:            if (equivalent(child->tag, tag)) { /* Case sensitive 920226 */
1.11      frystyk   106:                if (ANCH_TRACE) fprintf (stderr,
                    107:               "AnchorChild. %p of parent %p with name `%s' already exists.\n",
1.4       timbl     108:                    (void*)child, (void*)parent, tag);
1.1       timbl     109:                return child;
                    110:            }
                    111:        }
                    112:      }  /*  end if tag is void */
                    113:   } else  /* parent doesn't have any children yet : create family */
                    114:     parent->children = HTList_new ();
                    115: 
                    116:   child = HTChildAnchor_new ();
1.13      frystyk   117:   /* int for apollo */
                    118:   if (ANCH_TRACE)
                    119:       fprintf(stderr, "AnchorChild. New Anchor %p named `%s' is child of %p\n",
                    120:              (void *) child, tag ? tag : (CONST char *) "", (void *) parent);
1.1       timbl     121:   HTList_addObject (parent->children, child);
                    122:   child->parent = parent;
                    123:   StrAllocCopy(child->tag, tag);
                    124:   return child;
                    125: }
                    126: 
                    127: 
                    128: /*     Create or find a child anchor with a possible link
                    129: **     --------------------------------------------------
                    130: **
                    131: **     Create new anchor with a given parent and possibly
                    132: **     a name, and possibly a link to a _relatively_ named anchor.
                    133: **     (Code originally in ParseHTML.h)
                    134: */
                    135: PUBLIC HTChildAnchor * HTAnchor_findChildAndLink
                    136:   ARGS4(
                    137:        HTParentAnchor *,parent,        /* May not be 0 */
                    138:        CONST char *,tag,       /* May be "" or 0 */
                    139:        CONST char *,href,      /* May be "" or 0 */
                    140:        HTLinkType *,ltype      /* May be 0 */
                    141:        )
                    142: {
                    143:   HTChildAnchor * child = HTAnchor_findChild(parent, tag);
                    144:   if (href && *href) {
1.2       timbl     145:     char * relative_to = HTAnchor_address((HTAnchor *) parent);
                    146:     char * parsed_address = HTParse(href, relative_to, PARSE_ALL);
                    147:     HTAnchor * dest = HTAnchor_findAddress(parsed_address);
1.1       timbl     148:     HTAnchor_link((HTAnchor *) child, dest, ltype);
                    149:     free(parsed_address);
1.2       timbl     150:     free(relative_to);
1.1       timbl     151:   }
                    152:   return child;
                    153: }
                    154: 
                    155: 
                    156: /*     Create new or find old named anchor
                    157: **     -----------------------------------
                    158: **
1.3       timbl     159: **     Me one is for a reference which is found in a document, and might
1.1       timbl     160: **     not be already loaded.
                    161: **     Note: You are not guaranteed a new anchor -- you might get an old one,
                    162: **     like with fonts.
                    163: */
                    164: 
1.10      frystyk   165: PUBLIC HTAnchor * HTAnchor_findAddress
1.1       timbl     166:   ARGS1 (CONST char *,address)
                    167: {
                    168:   char *tag = HTParse (address, "", PARSE_ANCHOR);  /* Anchor tag specified ? */
                    169: 
                    170:   /* If the address represents a sub-anchor, we recursively load its parent,
                    171:      then we create a child anchor within that document. */
                    172:   if (*tag) {
                    173:     char *docAddress = HTParse(address, "", PARSE_ACCESS | PARSE_HOST |
                    174:                                            PARSE_PATH | PARSE_PUNCTUATION);
                    175:     HTParentAnchor * foundParent =
                    176:       (HTParentAnchor *) HTAnchor_findAddress (docAddress);
                    177:     HTChildAnchor * foundAnchor = HTAnchor_findChild (foundParent, tag);
                    178:     free (docAddress);
                    179:     free (tag);
                    180:     return (HTAnchor *) foundAnchor;
                    181:   }
                    182:   
1.3       timbl     183:   else { /* If the address has no anchor tag, 
                    184:            check whether we have this node */
1.1       timbl     185:     int hash;
                    186:     CONST char *p;
                    187:     HTList * adults;
                    188:     HTList *grownups;
                    189:     HTParentAnchor * foundAnchor;
                    190: 
                    191:     free (tag);
                    192:     
                    193:     /* Select list from hash table */
1.2       timbl     194:     for(p=address, hash=0; *p; p++)
1.11      frystyk   195:        hash = (int) ((hash * 3 + (*(unsigned char*)p)) % HASH_SIZE);
1.1       timbl     196:     if (!adult_table)
                    197:         adult_table = (HTList**) calloc(HASH_SIZE, sizeof(HTList*));
                    198:     if (!adult_table[hash]) adult_table[hash] = HTList_new();
                    199:     adults = adult_table[hash];
                    200: 
                    201:     /* Search list for anchor */
                    202:     grownups = adults;
1.12      frystyk   203:     while ((foundAnchor = (HTParentAnchor *) HTList_nextObject (grownups))) {
1.2       timbl     204:        if (equivalent(foundAnchor->address, address)) {
1.11      frystyk   205:        if (ANCH_TRACE)
                    206:            fprintf(stderr, "FindAnchor.. %p with address `%s' already exists.\n",
1.8       frystyk   207:                    (void*) foundAnchor, address);
1.1       timbl     208:        return (HTAnchor *) foundAnchor;
                    209:       }
                    210:     }
                    211:     
1.11      frystyk   212:     /* Node not found : create new anchor. */
1.1       timbl     213:     foundAnchor = HTParentAnchor_new ();
1.11      frystyk   214:     if (ANCH_TRACE) fprintf(stderr, "FindAnchor.. %p with hash %d and address `%s' created\n", (void*)foundAnchor, hash, address);
                    215: 
                    216:     /* This is done earlier in the Proxy server */
                    217:     if (HTImProxy) {
                    218:        StrAllocCopy(foundAnchor->address, address);
                    219:     } else {
                    220:        StrAllocCopy(foundAnchor->address, address);
                    221:        foundAnchor->address = HTSimplify(foundAnchor->address);
                    222:     }
1.1       timbl     223:     HTList_addObject (adults, foundAnchor);
                    224:     return (HTAnchor *) foundAnchor;
                    225:   }
                    226: }
                    227: 
                    228: 
                    229: /*     Delete an anchor and possibly related things (auto garbage collection)
                    230: **     --------------------------------------------
                    231: **
                    232: **     The anchor is only deleted if the corresponding document is not loaded.
1.10      frystyk   233: **     All outgoing links from parent and children are deleted, and this
                    234: **     anchor is removed from the sources list of all its targets.
1.1       timbl     235: **     We also try to delete the targets whose documents are not loaded.
                    236: **     If this anchor's source list is empty, we delete it and its children.
                    237: */
                    238: 
                    239: PRIVATE void deleteLinks
1.3       timbl     240:   ARGS1 (HTAnchor *,me)
1.1       timbl     241: {
1.3       timbl     242:   if (! me)
1.1       timbl     243:     return;
                    244: 
                    245:   /* Recursively try to delete target anchors */
1.3       timbl     246:   if (me->mainLink.dest) {
                    247:     HTParentAnchor *parent = me->mainLink.dest->parent;
                    248:     HTList_removeObject (parent->sources, me);
1.1       timbl     249:     if (! parent->document)  /* Test here to avoid calling overhead */
                    250:       HTAnchor_delete (parent);
                    251:   }
1.3       timbl     252:   if (me->links) {  /* Extra destinations */
1.1       timbl     253:     HTLink *target;
1.12      frystyk   254:     while ((target = (HTLink *) HTList_removeLastObject (me->links))) {
1.1       timbl     255:       HTParentAnchor *parent = target->dest->parent;
1.3       timbl     256:       HTList_removeObject (parent->sources, me);
1.1       timbl     257:       if (! parent->document)  /* Test here to avoid calling overhead */
                    258:        HTAnchor_delete (parent);
                    259:     }
                    260:   }
                    261: }
                    262: 
                    263: PUBLIC BOOL HTAnchor_delete
1.3       timbl     264:   ARGS1 (HTParentAnchor *,me)
1.1       timbl     265: {
                    266:   HTChildAnchor *child;
                    267: 
                    268:   /* Don't delete if document is loaded */
1.3       timbl     269:   if (me->document)
1.1       timbl     270:     return NO;
                    271: 
                    272:   /* Recursively try to delete target anchors */
1.3       timbl     273:   deleteLinks ((HTAnchor *) me);
1.1       timbl     274: 
1.3       timbl     275:   if (! HTList_isEmpty (me->sources)) {  /* There are still incoming links */
1.1       timbl     276:     /* Delete all outgoing links from children, if any */
1.3       timbl     277:     HTList *kids = me->children;
1.12      frystyk   278:     while ((child = (HTChildAnchor *) HTList_nextObject (kids)))
1.1       timbl     279:       deleteLinks ((HTAnchor *) child);
                    280:     return NO;  /* Parent not deleted */
                    281:   }
                    282: 
                    283:   /* No more incoming links : kill everything */
                    284:   /* First, recursively delete children */
1.12      frystyk   285:   while ((child = (HTChildAnchor *) HTList_removeLastObject (me->children))) {
1.1       timbl     286:     deleteLinks ((HTAnchor *) child);
                    287:     free (child->tag);
                    288:     free (child);
                    289:   }
                    290: 
                    291:   /* Now kill myself */
1.3       timbl     292:   HTList_delete (me->children);
                    293:   HTList_delete (me->sources);
                    294:   free (me->address);
1.1       timbl     295:   /* Devise a way to clean out the HTFormat if no longer needed (ref count?) */
1.3       timbl     296:   free (me);
1.6       timbl     297:   if (me->cacheItems) {
                    298:       HTCacheClear(me->cacheItems);
                    299:   }
1.1       timbl     300:   return YES;  /* Parent deleted */
                    301: }
                    302: 
                    303: 
                    304: /*             Move an anchor to the head of the list of its siblings
                    305: **             ------------------------------------------------------
                    306: **
                    307: **     This is to ensure that an anchor which might have already existed
                    308: **     is put in the correct order as we load the document.
                    309: */
                    310: 
1.10      frystyk   311: PUBLIC void HTAnchor_makeLastChild
1.3       timbl     312:   ARGS1(HTChildAnchor *,me)
1.1       timbl     313: {
1.3       timbl     314:   if (me->parent != (HTParentAnchor *) me) {  /* Make sure it's a child */
                    315:     HTList * siblings = me->parent->children;
                    316:     HTList_removeObject (siblings, me);
                    317:     HTList_addObject (siblings, me);
1.1       timbl     318:   }
                    319: }
                    320: 
                    321: /*     Data access functions
                    322: **     ---------------------
                    323: */
                    324: 
                    325: PUBLIC HTParentAnchor * HTAnchor_parent
1.3       timbl     326:   ARGS1 (HTAnchor *,me)
1.1       timbl     327: {
1.3       timbl     328:   return me ? me->parent : NULL;
1.1       timbl     329: }
                    330: 
1.10      frystyk   331: PUBLIC void HTAnchor_setDocument
1.3       timbl     332:   ARGS2 (HTParentAnchor *,me, HyperDoc *,doc)
1.1       timbl     333: {
1.3       timbl     334:   if (me)
                    335:     me->document = doc;
1.1       timbl     336: }
                    337: 
1.10      frystyk   338: PUBLIC HyperDoc * HTAnchor_document
1.3       timbl     339:   ARGS1 (HTParentAnchor *,me)
1.1       timbl     340: {
1.3       timbl     341:   return me ? me->document : NULL;
1.1       timbl     342: }
                    343: 
                    344: 
1.10      frystyk   345: #if 0
                    346: PUBLIC void HTAnchor_setAddress
1.3       timbl     347:   ARGS2 (HTAnchor *,me, char *,addr)
1.1       timbl     348: {
1.3       timbl     349:   if (me)
                    350:     StrAllocCopy (me->parent->address, addr);
1.1       timbl     351: }
1.10      frystyk   352: #endif
                    353: 
1.1       timbl     354: 
1.10      frystyk   355: PUBLIC char * HTAnchor_address
1.3       timbl     356:   ARGS1 (HTAnchor *,me)
1.1       timbl     357: {
                    358:   char *addr = NULL;
1.3       timbl     359:   if (me) {
                    360:     if (((HTParentAnchor *) me == me->parent) ||
                    361:        !((HTChildAnchor *) me)->tag) {  /* it's an adult or no tag */
                    362:       StrAllocCopy (addr, me->parent->address);
1.1       timbl     363:     }
                    364:     else {  /* it's a named child */
1.12      frystyk   365:       addr = (char *) malloc (2 + strlen (me->parent->address)
                    366:                              + strlen (((HTChildAnchor *) me)->tag));
1.1       timbl     367:       if (addr == NULL) outofmem(__FILE__, "HTAnchor_address");
1.3       timbl     368:       sprintf (addr, "%s#%s", me->parent->address,
                    369:               ((HTChildAnchor *) me)->tag);
1.1       timbl     370:     }
                    371:   }
                    372:   return addr;
                    373: }
                    374: 
                    375: 
                    376: 
1.10      frystyk   377: PUBLIC void HTAnchor_setFormat
1.3       timbl     378:   ARGS2 (HTParentAnchor *,me, HTFormat ,form)
1.1       timbl     379: {
1.3       timbl     380:   if (me)
                    381:     me->format = form;
1.1       timbl     382: }
                    383: 
1.10      frystyk   384: PUBLIC HTFormat HTAnchor_format
1.3       timbl     385:   ARGS1 (HTParentAnchor *,me)
1.1       timbl     386: {
1.3       timbl     387:   return me ? me->format : NULL;
1.1       timbl     388: }
                    389: 
1.10      frystyk   390: PUBLIC void HTAnchor_clearIndex
1.9       frystyk   391:   ARGS1 (HTParentAnchor *,me)
                    392: {
                    393:   if (me)
                    394:     me->isIndex = NO;
                    395: }
1.1       timbl     396: 
1.10      frystyk   397: PUBLIC void HTAnchor_setIndex
1.3       timbl     398:   ARGS1 (HTParentAnchor *,me)
1.1       timbl     399: {
1.3       timbl     400:   if (me)
                    401:     me->isIndex = YES;
1.1       timbl     402: }
                    403: 
1.10      frystyk   404: PUBLIC BOOL HTAnchor_isIndex
1.3       timbl     405:   ARGS1 (HTParentAnchor *,me)
1.1       timbl     406: {
1.3       timbl     407:   return me ? me->isIndex : NO;
1.1       timbl     408: }
                    409: 
                    410: 
1.10      frystyk   411: PUBLIC BOOL HTAnchor_hasChildren
1.3       timbl     412:   ARGS1 (HTParentAnchor *,me)
1.1       timbl     413: {
1.3       timbl     414:   return me ? ! HTList_isEmpty(me->children) : NO;
1.1       timbl     415: }
                    416: 
                    417: /*     Title handling
                    418: */
1.10      frystyk   419: PUBLIC CONST char * HTAnchor_title
1.3       timbl     420:   ARGS1 (HTParentAnchor *,me)
1.1       timbl     421: {
1.3       timbl     422:   return me ? me->title : 0;
1.1       timbl     423: }
                    424: 
1.10      frystyk   425: PUBLIC void HTAnchor_setTitle
1.3       timbl     426:   ARGS2(HTParentAnchor *,me, CONST char *,title)
1.1       timbl     427: {
1.3       timbl     428:   StrAllocCopy(me->title, title);
1.1       timbl     429: }
                    430: 
1.10      frystyk   431: PUBLIC void HTAnchor_appendTitle
1.3       timbl     432:   ARGS2(HTParentAnchor *,me, CONST char *,title)
1.1       timbl     433: {
1.3       timbl     434:   StrAllocCat(me->title, title);
1.1       timbl     435: }
                    436: 
1.3       timbl     437: /*     Link me Anchor to another given one
1.1       timbl     438: **     -------------------------------------
                    439: */
                    440: 
1.10      frystyk   441: PUBLIC BOOL HTAnchor_link
1.1       timbl     442:   ARGS3(HTAnchor *,source, HTAnchor *,destination, HTLinkType *,type)
                    443: {
                    444:   if (! (source && destination))
                    445:     return NO;  /* Can't link to/from non-existing anchor */
1.11      frystyk   446:   if (ANCH_TRACE)
                    447:       fprintf(stderr, "LinkAnchor.. Linking anchor %p to anchor %p\n",
1.8       frystyk   448:              (void *) source, (void *) destination);
1.1       timbl     449:   if (! source->mainLink.dest) {
                    450:     source->mainLink.dest = destination;
                    451:     source->mainLink.type = type;
                    452:   } else {
                    453:     HTLink * newLink = (HTLink *) malloc (sizeof (HTLink));
                    454:     if (newLink == NULL) outofmem(__FILE__, "HTAnchor_link");
                    455:     newLink->dest = destination;
                    456:     newLink->type = type;
                    457:     if (! source->links)
                    458:       source->links = HTList_new ();
                    459:     HTList_addObject (source->links, newLink);
                    460:   }
                    461:   if (!destination->parent->sources)
                    462:     destination->parent->sources = HTList_new ();
                    463:   HTList_addObject (destination->parent->sources, source);
                    464:   return YES;  /* Success */
                    465: }
                    466: 
                    467: 
                    468: /*     Manipulation of links
                    469: **     ---------------------
                    470: */
                    471: 
1.10      frystyk   472: PUBLIC HTAnchor * HTAnchor_followMainLink
1.3       timbl     473:   ARGS1 (HTAnchor *,me)
1.1       timbl     474: {
1.3       timbl     475:   return me->mainLink.dest;
1.1       timbl     476: }
                    477: 
1.10      frystyk   478: PUBLIC HTAnchor * HTAnchor_followTypedLink
1.3       timbl     479:   ARGS2 (HTAnchor *,me, HTLinkType *,type)
1.1       timbl     480: {
1.3       timbl     481:   if (me->mainLink.type == type)
                    482:     return me->mainLink.dest;
                    483:   if (me->links) {
                    484:     HTList *links = me->links;
1.1       timbl     485:     HTLink *link;
1.12      frystyk   486:     while ((link = (HTLink *) HTList_nextObject (links)))
1.1       timbl     487:       if (link->type == type)
                    488:        return link->dest;
                    489:   }
1.3       timbl     490:   return NULL;  /* No link of me type */
1.1       timbl     491: }
                    492: 
1.2       timbl     493: 
                    494: /*     Make main link
                    495: */
1.10      frystyk   496: PUBLIC BOOL HTAnchor_makeMainLink
1.3       timbl     497:   ARGS2 (HTAnchor *,me, HTLink *,movingLink)
1.1       timbl     498: {
                    499:   /* Check that everything's OK */
1.3       timbl     500:   if (! (me && HTList_removeObject (me->links, movingLink)))
1.1       timbl     501:     return NO;  /* link not found or NULL anchor */
                    502:   else {
                    503:     /* First push current main link onto top of links list */
                    504:     HTLink *newLink = (HTLink*) malloc (sizeof (HTLink));
                    505:     if (newLink == NULL) outofmem(__FILE__, "HTAnchor_makeMainLink");
1.3       timbl     506:     memcpy (newLink, & me->mainLink, sizeof (HTLink));
                    507:     HTList_addObject (me->links, newLink);
1.1       timbl     508: 
                    509:     /* Now make movingLink the new main link, and free it */
1.3       timbl     510:     memcpy (& me->mainLink, movingLink, sizeof (HTLink));
1.1       timbl     511:     free (movingLink);
                    512:     return YES;
                    513:   }
1.2       timbl     514: }
                    515: 
                    516: 
                    517: /*     Methods List
                    518: **     ------------
                    519: */
                    520: 
1.3       timbl     521: PUBLIC HTList * HTAnchor_methods ARGS1(HTParentAnchor *, me)
1.2       timbl     522: {
1.3       timbl     523:     if (!me->methods) {
                    524:         me->methods = HTList_new();
1.2       timbl     525:     }
1.3       timbl     526:     return me->methods;
1.2       timbl     527: }
                    528: 
                    529: /*     Protocol
                    530: **     --------
                    531: */
                    532: 
1.3       timbl     533: PUBLIC void * HTAnchor_protocol ARGS1(HTParentAnchor *, me)
1.2       timbl     534: {
1.3       timbl     535:     return me->protocol;
1.2       timbl     536: }
                    537: 
1.3       timbl     538: PUBLIC void HTAnchor_setProtocol ARGS2(HTParentAnchor *, me,
1.2       timbl     539:        void*,  protocol)
                    540: {
1.3       timbl     541:     me->protocol = protocol;
1.2       timbl     542: }
                    543: 
                    544: /*     Physical Address
                    545: **     ----------------
                    546: */
                    547: 
1.3       timbl     548: PUBLIC char * HTAnchor_physical ARGS1(HTParentAnchor *, me)
1.2       timbl     549: {
1.3       timbl     550:     return me->physical;
1.2       timbl     551: }
                    552: 
1.3       timbl     553: PUBLIC void HTAnchor_setPhysical ARGS2(HTParentAnchor *, me,
1.2       timbl     554:        char *, physical)
                    555: {
1.9       frystyk   556:     if (!me || !physical) {
1.11      frystyk   557:        if (ANCH_TRACE)
1.9       frystyk   558:            fprintf(stderr, "HTAnchor.... setPhysical, called with null argument\n");
                    559:        return;
                    560:     }
1.3       timbl     561:     StrAllocCopy(me->physical, physical);
1.1       timbl     562: }
1.10      frystyk   563: 

Webmaster