1 /*****************************************************************************
2  *
3  *  Elmer, A Finite Element Software for Multiphysical Problems
4  *
5  *  Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library (in file ../LGPL-2.1); if not, write
19  * to the Free Software Foundation, Inc., 51 Franklin Street,
20  * Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  *****************************************************************************/
23 
24 /*******************************************************************************
25  *
26  *     List handling utilities.
27  *
28  *******************************************************************************
29  *
30  *                     Author:       Juha Ruokolainen
31  *
32  *                    Address: CSC - IT Center for Science Ltd.
33  *                                Keilaranta 14, P.O. BOX 405
34  *                                  02101 Espoo, Finland
35  *                                  Tel. +358 0 457 2723
36  *                                Telefax: +358 0 457 2302
37  *                              EMail: Juha.Ruokolainen@csc.fi
38  *
39  *                       Date: 30 May 1996
40  *
41  *                Modified by:
42  *
43  *       Date of modification:
44  *
45  ******************************************************************************/
46 /***********************************************************************
47 |
48 |  LISTS.C - Last Edited 7. 8. 1988
49 |
50 |  Handling of global lists. Starts of global lists are hold in a
51 |  global array named listheaders and type of LIST. For each routine
52 |  managing one of lists you provide an index to this array. There
53 |  are definitions in MATC.H to make these indexes more abstract
54 |  entities.
55 |
56 |  List structure is currently as follows
57 |
58 |       struct list
59 |       {
60 |         struct list *next;
61 |         char *name;
62 |       };
63 |
64 |  This is typedef'ed to LIST.
65 |
66 ***********************************************************************/
67 
68 /*======================================================================
69 |Syntax of the manual pages:
70 |
71 |FUNCTION NAME(...) params ...
72 |
73 $  usage of the function and type of the parameters
74 ?  explane the effects of the function
75 =  return value and the type of value if not of type int
76 @  globals effected directly by this routine
77 !  current known bugs or limitations
78 &  functions called by this function
79 ~  these functions may interest you as an alternative function or
80 |  because they control this function somehow
81 ^=====================================================================*/
82 
83 
84 /*
85  * $Id: lists.c,v 1.1.1.1 2005/04/14 13:29:14 vierinen Exp $
86  *
87  * $Log: lists.c,v $
88  * Revision 1.1.1.1  2005/04/14 13:29:14  vierinen
89  * initial matc automake package
90  *
91  * Revision 1.2  1998/08/01 12:34:44  jpr
92  *
93  * Added Id, started Log.
94  *
95  *
96  */
97 
98 #include "elmer/matc.h"
99 
lst_addtail(list,item)100 void lst_addtail(list, item) int list; LIST *item;
101 /*======================================================================
102 ?  Add specified item to end of a list given.
103 ^=====================================================================*/
104 {
105    LIST *lst;
106 
107   /*
108    *   check if the list exists, if not just make this item first in list
109    */
110    if (listheaders[list].next == (LIST *)NULL)
111      listheaders[list].next = item;
112 
113   /*
114    * else look for current last item in list
115    */
116    else
117    {
118      for(lst = listheaders[list].next; NEXT(lst); lst = NEXT(lst));
119 
120      /*
121       *  and make the link
122       */
123      NEXT(lst) = item;
124    }
125 }
126 
lst_addhead(list,item)127 void lst_addhead(list, item) int list; LIST *item;
128 /*======================================================================
129 ?  add specified item to start of list given.
130 ^=====================================================================*/
131 {
132   /*
133    *  make the link.
134    */
135    NEXT(item) = listheaders[list].next;
136    listheaders[list].next = item;
137 }
138 
lst_add(list,item)139 void lst_add(list, item) int list; LIST *item;
140 /*======================================================================
141 ?  add item to lexically right place in the list.
142 |
143 &  strcmp()
144 ^=====================================================================*/
145 {
146    LIST *lst, *lstn;
147 
148    /*
149     *  if the list is empty make this item first and return.
150     */
151    if ((lst = listheaders[list].next) == (LIST *)NULL)
152    {
153      lst_addhead(list, item); return;
154    }
155 
156    /*
157     *  if the name of the new item is lexically
158     *  smaller than first item in the list, add it
159     *  to beginning of the list.
160     */
161    if (strcmp(NAME(lst), NAME(item)) > 0)
162    {
163      lst_addhead(list, item); return;
164    }
165 
166    /*
167     *  look for right place to add.
168     */
169    for(; NEXT(lst); lst = NEXT(lst))
170      if (strcmp(NAME(NEXT(lst)), NAME(item)) > 0)
171      {
172        lstn = NEXT(lst);
173        NEXT(lst) = item;
174        NEXT(item) = lstn;
175        return;
176      }
177 
178    /*
179     *  fell of the loop. item should be added to the tail of the list.
180     */
181    NEXT(lst) = item;
182 }
183 
lst_unlink(list,item)184 void lst_unlink(list, item) int list; LIST *item;
185 /*======================================================================
186 ?  unlink specified item from a list given.
187 ^=====================================================================*/
188 {
189   LIST *lst;
190 
191   /*
192    *  if the list is empty return
193    */
194   if ((lst = listheaders[list].next) == (LIST *)NULL) return;
195 
196   /*
197    *  it's not the header, look if it is in list at all
198    */
199   if (lst != item)
200   {
201 
202     for(; NEXT(lst); lst = NEXT(lst))
203     {
204       if (NEXT(lst) == item) break;
205     }
206 
207     /*
208      *  item was not found from the list. do nothing.
209      */
210     if (NEXT(lst) == (LIST *)NULL) return;
211 
212     /*
213      *   found, unlink
214      */
215     NEXT(lst) = NEXT(item);
216   }
217 
218   /*
219    *  item was the header, unlink it
220    */
221   else
222     listheaders[list].next = NEXT(item);
223 }
224 
lst_free(list,item)225 void lst_free(list, item) int list; LIST *item;
226 /*======================================================================
227 ?  Unlink item from list and free memory used by it.
228 |
229 &  lst_unlink(), FREEMEM
230 ^=====================================================================*/
231 {
232    lst_unlink(list, item);
233 
234    FREEMEM(NAME(item));
235    FREEMEM((char *)item);
236 }
237 
lst_find(list,name)238 LIST *lst_find(list, name) int list; char *name;
239 /*======================================================================
240 ?  Look for a named item from given list.
241 |
242 &  strcmp()
243 ^=====================================================================*/
244 {
245   LIST *lst;
246 
247   /*
248    *   look for item
249    */
250   for( lst = listheaders[list].next; lst; lst = NEXT(lst) )
251   {
252       if ( NAME(lst) && strcmp(name, NAME(lst)) == 0 ) break;
253   }
254 
255   return lst;
256 }
257 
lst_purge(list)258 void lst_purge(list) int list;
259 /*======================================================================
260 ?  Delete list and free memory allocated to it.
261 |
262 &  FREEMEM
263 ^=====================================================================*/
264 {
265   LIST *lst, *lstn;
266 
267   /*
268    *  free memory allocated for this list
269    */
270   for(lst = listheaders[list].next; lst;)
271   {
272     lstn = NEXT(lst);
273     FREEMEM(NAME(lst));
274     FREEMEM((char *)lst);
275     lst = lstn;
276   }
277 
278   listheaders[list].next = (LIST *)NULL;  /* security */
279 }
280 
lst_print(list)281 VARIABLE *lst_print(list) int list;
282 /*======================================================================
283 ?  Print list name and item names from given list
284 |
285 !  Output looks real ugly, should do something to that. The command
286 |  to get here is "help" but it really is not very helpful.
287 |
288 &  fprintf(), strlen()
289 ^=====================================================================*/
290 {
291    LIST *lst;
292 
293    int i, spc, len;
294 
295    /*
296     *  if empty list return.
297     */
298    if ( listheaders[list].next == (LIST *)NULL )
299        return (VARIABLE *)NULL;
300 
301    /*
302     *  name of the list
303     */
304     PrintOut( "\n%s\n\n", listheaders[list].name );
305 
306    /*
307     * and finally list all item names one by one.
308     * try printing as many names as possible to
309     * each output line.
310     */
311     for(len = 0,lst = listheaders[list].next; lst; lst = NEXT(lst))
312     {
313       if ( NAME(lst) )
314       {
315         if (len >= 80)
316         {
317           PrintOut("\n");
318           len = 0;
319         } else len += 20;
320         PrintOut("%-20s\t", NAME(lst));
321 		if ( strlen(NAME(lst)) >= 20 ) { PrintOut("%-20%s\t", " "); len+= 20; }
322 		/*
323         spc = 20 - spc;
324         for(i=0; i<spc && len<80; i++)
325         {
326           PrintOut(" "); len++;
327         }
328 		*/
329       }
330     }
331     PrintOut("\n");
332 
333     return (VARIABLE *)NULL;
334 }
335