1/* list.c - Functions for manipulating linked lists of objects. */
2
3/* Copyright (C) 1996
4   Free Software Foundation, Inc.
5
6   This file is part of GNU Bash, the Bourne Again SHell.
7
8   Bash is free software; you can redistribute it and/or modify it under
9   the terms of the GNU General Public License as published by the Free
10   Software Foundation; either version 2, or (at your option) any later
11   version.
12
13   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14   WARRANTY; without even the implied warranty of MERCHANTABILITY or
15   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16   for more details.
17
18   You should have received a copy of the GNU General Public License along
19   with Bash; see the file COPYING.  If not, write to the Free Software
20   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
21
22#include "config.h"
23
24#if defined (HAVE_UNISTD_H)
25#  ifdef _MINIX
26#    include <sys/types.h>
27#  endif
28#  include <unistd.h>
29#endif
30
31#include "shell.h"
32
33/* A global variable which acts as a sentinel for an `error' list return. */
34GENERIC_LIST global_error_list;
35
36#ifdef INCLUDE_UNUSED
37/* Call FUNCTION on every member of LIST, a generic list. */
38void
39list_walk (list, function)
40     GENERIC_LIST *list;
41     sh_glist_func_t *function;
42{
43  for ( ; list; list = list->next)
44    if ((*function) (list) < 0)
45      return;
46}
47
48/* Call FUNCTION on every string in WORDS. */
49void
50wlist_walk (words, function)
51     WORD_LIST *words;
52     sh_icpfunc_t *function;
53{
54  for ( ; words; words = words->next)
55    if ((*function) (words->word->word) < 0)
56      return;
57}
58#endif /* INCLUDE_UNUSED */
59
60/* Reverse the chain of structures in LIST.  Output the new head
61   of the chain.  You should always assign the output value of this
62   function to something, or you will lose the chain. */
63GENERIC_LIST *
64list_reverse (list)
65     GENERIC_LIST *list;
66{
67  register GENERIC_LIST *next, *prev;
68
69  for (prev = (GENERIC_LIST *)NULL; list; )
70    {
71      next = list->next;
72      list->next = prev;
73      prev = list;
74      list = next;
75    }
76  return (prev);
77}
78
79/* Return the number of elements in LIST, a generic list. */
80int
81list_length (list)
82     GENERIC_LIST *list;
83{
84  register int i;
85
86  for (i = 0; list; list = list->next, i++);
87  return (i);
88}
89
90/* Append TAIL to HEAD.  Return the header of the list. */
91GENERIC_LIST *
92list_append (head, tail)
93     GENERIC_LIST *head, *tail;
94{
95  register GENERIC_LIST *t_head;
96
97  if (head == 0)
98    return (tail);
99
100  for (t_head = head; t_head->next; t_head = t_head->next)
101    ;
102  t_head->next = tail;
103  return (head);
104}
105
106#ifdef INCLUDE_UNUSED
107/* Delete the element of LIST which satisfies the predicate function COMPARER.
108   Returns the element that was deleted, so you can dispose of it, or -1 if
109   the element wasn't found.  COMPARER is called with the list element and
110   then ARG.  Note that LIST contains the address of a variable which points
111   to the list.  You might call this function like this:
112
113   SHELL_VAR *elt = list_remove (&variable_list, check_var_has_name, "foo");
114   dispose_variable (elt);
115*/
116GENERIC_LIST *
117list_remove (list, comparer, arg)
118     GENERIC_LIST **list;
119     Function *comparer;
120     char *arg;
121{
122  register GENERIC_LIST *prev, *temp;
123
124  for (prev = (GENERIC_LIST *)NULL, temp = *list; temp; prev = temp, temp = temp->next)
125    {
126      if ((*comparer) (temp, arg))
127	{
128	  if (prev)
129	    prev->next = temp->next;
130	  else
131	    *list = temp->next;
132	  return (temp);
133	}
134    }
135  return ((GENERIC_LIST *)&global_error_list);
136}
137#endif
138