File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / list.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 19:53:30 2014 UTC (10 years ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_9_1p0, v2_9_1, HEAD
libxml2 2.9.1

    1: /*
    2:  * list.c: lists handling implementation
    3:  *
    4:  * Copyright (C) 2000 Gary Pennington and Daniel Veillard.
    5:  *
    6:  * Permission to use, copy, modify, and distribute this software for any
    7:  * purpose with or without fee is hereby granted, provided that the above
    8:  * copyright notice and this permission notice appear in all copies.
    9:  *
   10:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
   11:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
   12:  * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
   13:  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
   14:  *
   15:  * Author: Gary.Pennington@uk.sun.com
   16:  */
   17: 
   18: #define IN_LIBXML
   19: #include "libxml.h"
   20: 
   21: #include <stdlib.h>
   22: #include <string.h>
   23: #include <libxml/xmlmemory.h>
   24: #include <libxml/list.h>
   25: #include <libxml/globals.h>
   26: 
   27: /*
   28:  * Type definition are kept internal
   29:  */
   30: 
   31: struct _xmlLink
   32: {
   33:     struct _xmlLink *next;
   34:     struct _xmlLink *prev;
   35:     void *data;
   36: };
   37: 
   38: struct _xmlList
   39: {
   40:     xmlLinkPtr sentinel;
   41:     void (*linkDeallocator)(xmlLinkPtr );
   42:     int (*linkCompare)(const void *, const void*);
   43: };
   44: 
   45: /************************************************************************
   46:  *                                    *
   47:  *                Interfaces                *
   48:  *                                    *
   49:  ************************************************************************/
   50: 
   51: /**
   52:  * xmlLinkDeallocator:
   53:  * @l:  a list
   54:  * @lk:  a link
   55:  *
   56:  * Unlink and deallocate @lk from list @l
   57:  */
   58: static void
   59: xmlLinkDeallocator(xmlListPtr l, xmlLinkPtr lk)
   60: {
   61:     (lk->prev)->next = lk->next;
   62:     (lk->next)->prev = lk->prev;
   63:     if(l->linkDeallocator)
   64:         l->linkDeallocator(lk);
   65:     xmlFree(lk);
   66: }
   67: 
   68: /**
   69:  * xmlLinkCompare:
   70:  * @data0:  first data
   71:  * @data1:  second data
   72:  *
   73:  * Compares two arbitrary data
   74:  *
   75:  * Returns -1, 0 or 1 depending on whether data1 is greater equal or smaller
   76:  *          than data0
   77:  */
   78: static int
   79: xmlLinkCompare(const void *data0, const void *data1)
   80: {
   81:     if (data0 < data1)
   82:         return (-1);
   83:     else if (data0 == data1)
   84: 	return (0);
   85:     return (1);
   86: }
   87: 
   88: /**
   89:  * xmlListLowerSearch:
   90:  * @l:  a list
   91:  * @data:  a data
   92:  *
   93:  * Search data in the ordered list walking from the beginning
   94:  *
   95:  * Returns the link containing the data or NULL
   96:  */
   97: static xmlLinkPtr
   98: xmlListLowerSearch(xmlListPtr l, void *data)
   99: {
  100:     xmlLinkPtr lk;
  101: 
  102:     if (l == NULL)
  103:         return(NULL);
  104:     for(lk = l->sentinel->next;lk != l->sentinel && l->linkCompare(lk->data, data) <0 ;lk = lk->next);
  105:     return lk;
  106: }
  107: 
  108: /**
  109:  * xmlListHigherSearch:
  110:  * @l:  a list
  111:  * @data:  a data
  112:  *
  113:  * Search data in the ordered list walking backward from the end
  114:  *
  115:  * Returns the link containing the data or NULL
  116:  */
  117: static xmlLinkPtr
  118: xmlListHigherSearch(xmlListPtr l, void *data)
  119: {
  120:     xmlLinkPtr lk;
  121: 
  122:     if (l == NULL)
  123:         return(NULL);
  124:     for(lk = l->sentinel->prev;lk != l->sentinel && l->linkCompare(lk->data, data) >0 ;lk = lk->prev);
  125:     return lk;
  126: }
  127: 
  128: /**
  129:  * xmlListSearch:
  130:  * @l:  a list
  131:  * @data:  a data
  132:  *
  133:  * Search data in the list
  134:  *
  135:  * Returns the link containing the data or NULL
  136:  */
  137: static xmlLinkPtr
  138: xmlListLinkSearch(xmlListPtr l, void *data)
  139: {
  140:     xmlLinkPtr lk;
  141:     if (l == NULL)
  142:         return(NULL);
  143:     lk = xmlListLowerSearch(l, data);
  144:     if (lk == l->sentinel)
  145:         return NULL;
  146:     else {
  147:         if (l->linkCompare(lk->data, data) ==0)
  148:             return lk;
  149:         return NULL;
  150:     }
  151: }
  152: 
  153: /**
  154:  * xmlListLinkReverseSearch:
  155:  * @l:  a list
  156:  * @data:  a data
  157:  *
  158:  * Search data in the list processing backward
  159:  *
  160:  * Returns the link containing the data or NULL
  161:  */
  162: static xmlLinkPtr
  163: xmlListLinkReverseSearch(xmlListPtr l, void *data)
  164: {
  165:     xmlLinkPtr lk;
  166:     if (l == NULL)
  167:         return(NULL);
  168:     lk = xmlListHigherSearch(l, data);
  169:     if (lk == l->sentinel)
  170:         return NULL;
  171:     else {
  172:         if (l->linkCompare(lk->data, data) ==0)
  173:             return lk;
  174:         return NULL;
  175:     }
  176: }
  177: 
  178: /**
  179:  * xmlListCreate:
  180:  * @deallocator:  an optional deallocator function
  181:  * @compare:  an optional comparison function
  182:  *
  183:  * Create a new list
  184:  *
  185:  * Returns the new list or NULL in case of error
  186:  */
  187: xmlListPtr
  188: xmlListCreate(xmlListDeallocator deallocator, xmlListDataCompare compare)
  189: {
  190:     xmlListPtr l;
  191:     if (NULL == (l = (xmlListPtr )xmlMalloc( sizeof(xmlList)))) {
  192:         xmlGenericError(xmlGenericErrorContext,
  193: 		        "Cannot initialize memory for list");
  194:         return (NULL);
  195:     }
  196:     /* Initialize the list to NULL */
  197:     memset(l, 0, sizeof(xmlList));
  198: 
  199:     /* Add the sentinel */
  200:     if (NULL ==(l->sentinel = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
  201:         xmlGenericError(xmlGenericErrorContext,
  202: 		        "Cannot initialize memory for sentinel");
  203: 	xmlFree(l);
  204:         return (NULL);
  205:     }
  206:     l->sentinel->next = l->sentinel;
  207:     l->sentinel->prev = l->sentinel;
  208:     l->sentinel->data = NULL;
  209: 
  210:     /* If there is a link deallocator, use it */
  211:     if (deallocator != NULL)
  212:         l->linkDeallocator = deallocator;
  213:     /* If there is a link comparator, use it */
  214:     if (compare != NULL)
  215:         l->linkCompare = compare;
  216:     else /* Use our own */
  217:         l->linkCompare = xmlLinkCompare;
  218:     return l;
  219: }
  220: 
  221: /**
  222:  * xmlListSearch:
  223:  * @l:  a list
  224:  * @data:  a search value
  225:  *
  226:  * Search the list for an existing value of @data
  227:  *
  228:  * Returns the value associated to @data or NULL in case of error
  229:  */
  230: void *
  231: xmlListSearch(xmlListPtr l, void *data)
  232: {
  233:     xmlLinkPtr lk;
  234:     if (l == NULL)
  235:         return(NULL);
  236:     lk = xmlListLinkSearch(l, data);
  237:     if (lk)
  238:         return (lk->data);
  239:     return NULL;
  240: }
  241: 
  242: /**
  243:  * xmlListReverseSearch:
  244:  * @l:  a list
  245:  * @data:  a search value
  246:  *
  247:  * Search the list in reverse order for an existing value of @data
  248:  *
  249:  * Returns the value associated to @data or NULL in case of error
  250:  */
  251: void *
  252: xmlListReverseSearch(xmlListPtr l, void *data)
  253: {
  254:     xmlLinkPtr lk;
  255:     if (l == NULL)
  256:         return(NULL);
  257:     lk = xmlListLinkReverseSearch(l, data);
  258:     if (lk)
  259:         return (lk->data);
  260:     return NULL;
  261: }
  262: 
  263: /**
  264:  * xmlListInsert:
  265:  * @l:  a list
  266:  * @data:  the data
  267:  *
  268:  * Insert data in the ordered list at the beginning for this value
  269:  *
  270:  * Returns 0 in case of success, 1 in case of failure
  271:  */
  272: int
  273: xmlListInsert(xmlListPtr l, void *data)
  274: {
  275:     xmlLinkPtr lkPlace, lkNew;
  276: 
  277:     if (l == NULL)
  278:         return(1);
  279:     lkPlace = xmlListLowerSearch(l, data);
  280:     /* Add the new link */
  281:     lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
  282:     if (lkNew == NULL) {
  283:         xmlGenericError(xmlGenericErrorContext,
  284: 		        "Cannot initialize memory for new link");
  285:         return (1);
  286:     }
  287:     lkNew->data = data;
  288:     lkPlace = lkPlace->prev;
  289:     lkNew->next = lkPlace->next;
  290:     (lkPlace->next)->prev = lkNew;
  291:     lkPlace->next = lkNew;
  292:     lkNew->prev = lkPlace;
  293:     return 0;
  294: }
  295: 
  296: /**
  297:  * xmlListAppend:
  298:  * @l:  a list
  299:  * @data:  the data
  300:  *
  301:  * Insert data in the ordered list at the end for this value
  302:  *
  303:  * Returns 0 in case of success, 1 in case of failure
  304:  */
  305: int xmlListAppend(xmlListPtr l, void *data)
  306: {
  307:     xmlLinkPtr lkPlace, lkNew;
  308: 
  309:     if (l == NULL)
  310:         return(1);
  311:     lkPlace = xmlListHigherSearch(l, data);
  312:     /* Add the new link */
  313:     lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
  314:     if (lkNew == NULL) {
  315:         xmlGenericError(xmlGenericErrorContext,
  316: 		        "Cannot initialize memory for new link");
  317:         return (1);
  318:     }
  319:     lkNew->data = data;
  320:     lkNew->next = lkPlace->next;
  321:     (lkPlace->next)->prev = lkNew;
  322:     lkPlace->next = lkNew;
  323:     lkNew->prev = lkPlace;
  324:     return 0;
  325: }
  326: 
  327: /**
  328:  * xmlListDelete:
  329:  * @l:  a list
  330:  *
  331:  * Deletes the list and its associated data
  332:  */
  333: void xmlListDelete(xmlListPtr l)
  334: {
  335:     if (l == NULL)
  336:         return;
  337: 
  338:     xmlListClear(l);
  339:     xmlFree(l->sentinel);
  340:     xmlFree(l);
  341: }
  342: 
  343: /**
  344:  * xmlListRemoveFirst:
  345:  * @l:  a list
  346:  * @data:  list data
  347:  *
  348:  * Remove the first instance associated to data in the list
  349:  *
  350:  * Returns 1 if a deallocation occured, or 0 if not found
  351:  */
  352: int
  353: xmlListRemoveFirst(xmlListPtr l, void *data)
  354: {
  355:     xmlLinkPtr lk;
  356: 
  357:     if (l == NULL)
  358:         return(0);
  359:     /*Find the first instance of this data */
  360:     lk = xmlListLinkSearch(l, data);
  361:     if (lk != NULL) {
  362:         xmlLinkDeallocator(l, lk);
  363:         return 1;
  364:     }
  365:     return 0;
  366: }
  367: 
  368: /**
  369:  * xmlListRemoveLast:
  370:  * @l:  a list
  371:  * @data:  list data
  372:  *
  373:  * Remove the last instance associated to data in the list
  374:  *
  375:  * Returns 1 if a deallocation occured, or 0 if not found
  376:  */
  377: int
  378: xmlListRemoveLast(xmlListPtr l, void *data)
  379: {
  380:     xmlLinkPtr lk;
  381: 
  382:     if (l == NULL)
  383:         return(0);
  384:     /*Find the last instance of this data */
  385:     lk = xmlListLinkReverseSearch(l, data);
  386:     if (lk != NULL) {
  387: 	xmlLinkDeallocator(l, lk);
  388:         return 1;
  389:     }
  390:     return 0;
  391: }
  392: 
  393: /**
  394:  * xmlListRemoveAll:
  395:  * @l:  a list
  396:  * @data:  list data
  397:  *
  398:  * Remove the all instance associated to data in the list
  399:  *
  400:  * Returns the number of deallocation, or 0 if not found
  401:  */
  402: int
  403: xmlListRemoveAll(xmlListPtr l, void *data)
  404: {
  405:     int count=0;
  406: 
  407:     if (l == NULL)
  408:         return(0);
  409: 
  410:     while(xmlListRemoveFirst(l, data))
  411:         count++;
  412:     return count;
  413: }
  414: 
  415: /**
  416:  * xmlListClear:
  417:  * @l:  a list
  418:  *
  419:  * Remove the all data in the list
  420:  */
  421: void
  422: xmlListClear(xmlListPtr l)
  423: {
  424:     xmlLinkPtr  lk;
  425: 
  426:     if (l == NULL)
  427:         return;
  428:     lk = l->sentinel->next;
  429:     while(lk != l->sentinel) {
  430:         xmlLinkPtr next = lk->next;
  431: 
  432:         xmlLinkDeallocator(l, lk);
  433:         lk = next;
  434:     }
  435: }
  436: 
  437: /**
  438:  * xmlListEmpty:
  439:  * @l:  a list
  440:  *
  441:  * Is the list empty ?
  442:  *
  443:  * Returns 1 if the list is empty, 0 if not empty and -1 in case of error
  444:  */
  445: int
  446: xmlListEmpty(xmlListPtr l)
  447: {
  448:     if (l == NULL)
  449:         return(-1);
  450:     return (l->sentinel->next == l->sentinel);
  451: }
  452: 
  453: /**
  454:  * xmlListFront:
  455:  * @l:  a list
  456:  *
  457:  * Get the first element in the list
  458:  *
  459:  * Returns the first element in the list, or NULL
  460:  */
  461: xmlLinkPtr
  462: xmlListFront(xmlListPtr l)
  463: {
  464:     if (l == NULL)
  465:         return(NULL);
  466:     return (l->sentinel->next);
  467: }
  468: 
  469: /**
  470:  * xmlListEnd:
  471:  * @l:  a list
  472:  *
  473:  * Get the last element in the list
  474:  *
  475:  * Returns the last element in the list, or NULL
  476:  */
  477: xmlLinkPtr
  478: xmlListEnd(xmlListPtr l)
  479: {
  480:     if (l == NULL)
  481:         return(NULL);
  482:     return (l->sentinel->prev);
  483: }
  484: 
  485: /**
  486:  * xmlListSize:
  487:  * @l:  a list
  488:  *
  489:  * Get the number of elements in the list
  490:  *
  491:  * Returns the number of elements in the list or -1 in case of error
  492:  */
  493: int
  494: xmlListSize(xmlListPtr l)
  495: {
  496:     xmlLinkPtr lk;
  497:     int count=0;
  498: 
  499:     if (l == NULL)
  500:         return(-1);
  501:     /* TODO: keep a counter in xmlList instead */
  502:     for(lk = l->sentinel->next; lk != l->sentinel; lk = lk->next, count++);
  503:     return count;
  504: }
  505: 
  506: /**
  507:  * xmlListPopFront:
  508:  * @l:  a list
  509:  *
  510:  * Removes the first element in the list
  511:  */
  512: void
  513: xmlListPopFront(xmlListPtr l)
  514: {
  515:     if(!xmlListEmpty(l))
  516:         xmlLinkDeallocator(l, l->sentinel->next);
  517: }
  518: 
  519: /**
  520:  * xmlListPopBack:
  521:  * @l:  a list
  522:  *
  523:  * Removes the last element in the list
  524:  */
  525: void
  526: xmlListPopBack(xmlListPtr l)
  527: {
  528:     if(!xmlListEmpty(l))
  529:         xmlLinkDeallocator(l, l->sentinel->prev);
  530: }
  531: 
  532: /**
  533:  * xmlListPushFront:
  534:  * @l:  a list
  535:  * @data:  new data
  536:  *
  537:  * add the new data at the beginning of the list
  538:  *
  539:  * Returns 1 if successful, 0 otherwise
  540:  */
  541: int
  542: xmlListPushFront(xmlListPtr l, void *data)
  543: {
  544:     xmlLinkPtr lkPlace, lkNew;
  545: 
  546:     if (l == NULL)
  547:         return(0);
  548:     lkPlace = l->sentinel;
  549:     /* Add the new link */
  550:     lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
  551:     if (lkNew == NULL) {
  552:         xmlGenericError(xmlGenericErrorContext,
  553: 		        "Cannot initialize memory for new link");
  554:         return (0);
  555:     }
  556:     lkNew->data = data;
  557:     lkNew->next = lkPlace->next;
  558:     (lkPlace->next)->prev = lkNew;
  559:     lkPlace->next = lkNew;
  560:     lkNew->prev = lkPlace;
  561:     return 1;
  562: }
  563: 
  564: /**
  565:  * xmlListPushBack:
  566:  * @l:  a list
  567:  * @data:  new data
  568:  *
  569:  * add the new data at the end of the list
  570:  *
  571:  * Returns 1 if successful, 0 otherwise
  572:  */
  573: int
  574: xmlListPushBack(xmlListPtr l, void *data)
  575: {
  576:     xmlLinkPtr lkPlace, lkNew;
  577: 
  578:     if (l == NULL)
  579:         return(0);
  580:     lkPlace = l->sentinel->prev;
  581:     /* Add the new link */
  582:     if (NULL ==(lkNew = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
  583:         xmlGenericError(xmlGenericErrorContext,
  584: 		        "Cannot initialize memory for new link");
  585:         return (0);
  586:     }
  587:     lkNew->data = data;
  588:     lkNew->next = lkPlace->next;
  589:     (lkPlace->next)->prev = lkNew;
  590:     lkPlace->next = lkNew;
  591:     lkNew->prev = lkPlace;
  592:     return 1;
  593: }
  594: 
  595: /**
  596:  * xmlLinkGetData:
  597:  * @lk:  a link
  598:  *
  599:  * See Returns.
  600:  *
  601:  * Returns a pointer to the data referenced from this link
  602:  */
  603: void *
  604: xmlLinkGetData(xmlLinkPtr lk)
  605: {
  606:     if (lk == NULL)
  607:         return(NULL);
  608:     return lk->data;
  609: }
  610: 
  611: /**
  612:  * xmlListReverse:
  613:  * @l:  a list
  614:  *
  615:  * Reverse the order of the elements in the list
  616:  */
  617: void
  618: xmlListReverse(xmlListPtr l)
  619: {
  620:     xmlLinkPtr lk;
  621:     xmlLinkPtr lkPrev;
  622: 
  623:     if (l == NULL)
  624:         return;
  625:     lkPrev = l->sentinel;
  626:     for (lk = l->sentinel->next; lk != l->sentinel; lk = lk->next) {
  627:         lkPrev->next = lkPrev->prev;
  628:         lkPrev->prev = lk;
  629:         lkPrev = lk;
  630:     }
  631:     /* Fix up the last node */
  632:     lkPrev->next = lkPrev->prev;
  633:     lkPrev->prev = lk;
  634: }
  635: 
  636: /**
  637:  * xmlListSort:
  638:  * @l:  a list
  639:  *
  640:  * Sort all the elements in the list
  641:  */
  642: void
  643: xmlListSort(xmlListPtr l)
  644: {
  645:     xmlListPtr lTemp;
  646: 
  647:     if (l == NULL)
  648:         return;
  649:     if(xmlListEmpty(l))
  650:         return;
  651: 
  652:     /* I think that the real answer is to implement quicksort, the
  653:      * alternative is to implement some list copying procedure which
  654:      * would be based on a list copy followed by a clear followed by
  655:      * an insert. This is slow...
  656:      */
  657: 
  658:     if (NULL ==(lTemp = xmlListDup(l)))
  659:         return;
  660:     xmlListClear(l);
  661:     xmlListMerge(l, lTemp);
  662:     xmlListDelete(lTemp);
  663:     return;
  664: }
  665: 
  666: /**
  667:  * xmlListWalk:
  668:  * @l:  a list
  669:  * @walker:  a processing function
  670:  * @user:  a user parameter passed to the walker function
  671:  *
  672:  * Walk all the element of the first from first to last and
  673:  * apply the walker function to it
  674:  */
  675: void
  676: xmlListWalk(xmlListPtr l, xmlListWalker walker, const void *user) {
  677:     xmlLinkPtr lk;
  678: 
  679:     if ((l == NULL) || (walker == NULL))
  680:         return;
  681:     for(lk = l->sentinel->next; lk != l->sentinel; lk = lk->next) {
  682:         if((walker(lk->data, user)) == 0)
  683:                 break;
  684:     }
  685: }
  686: 
  687: /**
  688:  * xmlListReverseWalk:
  689:  * @l:  a list
  690:  * @walker:  a processing function
  691:  * @user:  a user parameter passed to the walker function
  692:  *
  693:  * Walk all the element of the list in reverse order and
  694:  * apply the walker function to it
  695:  */
  696: void
  697: xmlListReverseWalk(xmlListPtr l, xmlListWalker walker, const void *user) {
  698:     xmlLinkPtr lk;
  699: 
  700:     if ((l == NULL) || (walker == NULL))
  701:         return;
  702:     for(lk = l->sentinel->prev; lk != l->sentinel; lk = lk->prev) {
  703:         if((walker(lk->data, user)) == 0)
  704:                 break;
  705:     }
  706: }
  707: 
  708: /**
  709:  * xmlListMerge:
  710:  * @l1:  the original list
  711:  * @l2:  the new list
  712:  *
  713:  * include all the elements of the second list in the first one and
  714:  * clear the second list
  715:  */
  716: void
  717: xmlListMerge(xmlListPtr l1, xmlListPtr l2)
  718: {
  719:     xmlListCopy(l1, l2);
  720:     xmlListClear(l2);
  721: }
  722: 
  723: /**
  724:  * xmlListDup:
  725:  * @old:  the list
  726:  *
  727:  * Duplicate the list
  728:  *
  729:  * Returns a new copy of the list or NULL in case of error
  730:  */
  731: xmlListPtr
  732: xmlListDup(const xmlListPtr old)
  733: {
  734:     xmlListPtr cur;
  735: 
  736:     if (old == NULL)
  737:         return(NULL);
  738:     /* Hmmm, how to best deal with allocation issues when copying
  739:      * lists. If there is a de-allocator, should responsibility lie with
  740:      * the new list or the old list. Surely not both. I'll arbitrarily
  741:      * set it to be the old list for the time being whilst I work out
  742:      * the answer
  743:      */
  744:     if (NULL ==(cur = xmlListCreate(NULL, old->linkCompare)))
  745:         return (NULL);
  746:     if (0 != xmlListCopy(cur, old))
  747:         return NULL;
  748:     return cur;
  749: }
  750: 
  751: /**
  752:  * xmlListCopy:
  753:  * @cur:  the new list
  754:  * @old:  the old list
  755:  *
  756:  * Move all the element from the old list in the new list
  757:  *
  758:  * Returns 0 in case of success 1 in case of error
  759:  */
  760: int
  761: xmlListCopy(xmlListPtr cur, const xmlListPtr old)
  762: {
  763:     /* Walk the old tree and insert the data into the new one */
  764:     xmlLinkPtr lk;
  765: 
  766:     if ((old == NULL) || (cur == NULL))
  767:         return(1);
  768:     for(lk = old->sentinel->next; lk != old->sentinel; lk = lk->next) {
  769:         if (0 !=xmlListInsert(cur, lk->data)) {
  770:             xmlListDelete(cur);
  771:             return (1);
  772:         }
  773:     }
  774:     return (0);
  775: }
  776: /* xmlListUnique() */
  777: /* xmlListSwap */
  778: #define bottom_list
  779: #include "elfgcchack.h"

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>