Back to index

tetex-bin  3.0
str-llist.c
Go to the documentation of this file.
00001 /* str-llist.c: Implementation of a linked list of strings.
00002 
00003 Copyright (C) 1993 Karl Berry.
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Library General Public
00007 License as published by the Free Software Foundation; either
00008 version 2 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Library General Public License for more details.
00014 
00015 You should have received a copy of the GNU Library General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
00018 
00019 #include <kpathsea/config.h>
00020 
00021 #include <kpathsea/str-llist.h>
00022 
00023 
00024 /* Add the new string STR to the end of the list L.  */
00025 
00026 void
00027 str_llist_add P2C(str_llist_type *, l,  string, str)
00028 {
00029   str_llist_elt_type *e;
00030   str_llist_elt_type *new_elt = XTALLOC1 (str_llist_elt_type);
00031   
00032   /* The new element will be at the end of the list.  */
00033   STR_LLIST (*new_elt) = str;
00034   STR_LLIST_MOVED (*new_elt) = false;
00035   STR_LLIST_NEXT (*new_elt) = NULL;
00036   
00037   /* Find the current end of the list.  */
00038   for (e = *l; e && STR_LLIST_NEXT (*e); e = STR_LLIST_NEXT (*e))
00039     ;
00040   
00041   if (!e)
00042     *l = new_elt;
00043   else
00044     STR_LLIST_NEXT (*e) = new_elt;
00045 }
00046 
00047 /* Move an element towards the top. The idea is that when a file is
00048    found in a given directory, later files will likely be in that same
00049    directory, and looking for the file in all the directories in between
00050    is thus a waste.  */
00051 
00052 void
00053 str_llist_float P2C(str_llist_type *, l,  str_llist_elt_type *, mover)
00054 {
00055   str_llist_elt_type *last_moved, *unmoved;
00056   
00057   /* If we've already moved this element, never mind.  */
00058   if (STR_LLIST_MOVED (*mover))
00059     return;
00060   
00061   /* Find the first unmoved element (to insert before).  We're
00062      guaranteed this will terminate, since MOVER itself is currently
00063      unmoved, and it must be in L (by hypothesis).  */
00064   for (last_moved = NULL, unmoved = *l; STR_LLIST_MOVED (*unmoved);
00065        last_moved = unmoved, unmoved = STR_LLIST_NEXT (*unmoved))
00066     ;
00067 
00068   /* If we are the first unmoved element, nothing to relink.  */
00069   if (unmoved != mover)
00070     { /* Remember `mover's current successor, so we can relink `mover's
00071          predecessor to it.  */
00072       str_llist_elt_type *before_mover;
00073       str_llist_elt_type *after_mover = STR_LLIST_NEXT (*mover);
00074       
00075       /* Find `mover's predecessor.  */
00076       for (before_mover = unmoved; STR_LLIST_NEXT (*before_mover) != mover;
00077            before_mover = STR_LLIST_NEXT (*before_mover))
00078         ;
00079       
00080       /* `before_mover' now links to `after_mover'.  */
00081       STR_LLIST_NEXT (*before_mover) = after_mover;
00082 
00083       /* Insert `mover' before `unmoved' and after `last_moved' (or at
00084          the head of the list).  */
00085       STR_LLIST_NEXT (*mover) = unmoved;
00086       if (!last_moved)
00087         *l = mover;
00088       else
00089         STR_LLIST_NEXT (*last_moved) = mover;
00090     }
00091 
00092   /* We've moved it.  */
00093   STR_LLIST_MOVED (*mover) = true;
00094 }