1 : /*
2 : * OpenBIOS - free your system!
3 : * ( FCode tokenizer )
4 : *
5 : * This program is part of a free implementation of the IEEE 1275-1994
6 : * Standard for Boot (Initialization Configuration) Firmware.
7 : *
8 : * Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org>
9 : *
10 : * This program is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License as published by
12 : * the Free Software Foundation; version 2 of the License.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program; if not, write to the Free Software
21 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
22 : *
23 : */
24 :
25 : /* **************************************************************************
26 : *
27 : * General-purpose support functions for
28 : * String-Substitution-type vocabularies
29 : *
30 : * (C) Copyright 2005 IBM Corporation. All Rights Reserved.
31 : * Module Author: David L. Paktor dlpaktor@us.ibm.com
32 : *
33 : **************************************************************************** */
34 :
35 : /* **************************************************************************
36 : *
37 : * A String-Substitution vocabulary, as the name implies, is one in
38 : * in which each an entry consists of two strings; one that is
39 : * sought, and one that is returned as a substitute. Macros and
40 : * aliases are implemented this way, as are also user-supplied
41 : * command-line symbol definitions.
42 : *
43 : **************************************************************************** */
44 :
45 : /* **************************************************************************
46 : *
47 : * Functions Exported:
48 : * init_str_sub_vocab Initialize a String-Substitution vocab
49 : * add_str_sub_entry Add an entry to a Str-Subst vocab
50 : * lookup_str_sub Look for a name in a String-Substitution
51 : * vocab, return the substitution string.
52 : * exists_in_str_sub Confirm whether a given name exists in a
53 : * String-Substitution vocabulary
54 : * create_str_sub_alias Duplicate the behavior of one name with
55 : * another name. Return a "success" flag.
56 : * reset_str_sub_vocab Reset a given Str-Subst vocab to its initial
57 : * "Built-In" position.
58 : *
59 : *
60 : **************************************************************************** */
61 :
62 : #include <stdio.h>
63 : #include <stdlib.h>
64 : #if defined(__linux__) && ! defined(__USE_BSD)
65 : #define __USE_BSD
66 : #endif
67 : #include <string.h>
68 :
69 : #include "errhandler.h"
70 : #include "strsubvocab.h"
71 :
72 :
73 : /* **************************************************************************
74 : *
75 : * Function name: init_str_sub_vocab
76 : * Synopsis: Dynamically initialize the link-pointers
77 : * of the.given String-Substitution vocabulary
78 : *
79 : * Inputs:
80 : * Parameters:
81 : * str_sub_vocab_tbl Pointer to the initial Str-Subst vocab array
82 : * max_indx Maximum Index of the initial array.
83 : *
84 : * Outputs:
85 : * Returned Value: None
86 : * Global Variables:
87 : * The link-fields of the initial Str-Subs vocab array entries
88 : * will be filled in.
89 : *
90 : **************************************************************************** */
91 :
92 : void init_str_sub_vocab( str_sub_vocab_t *str_sub_vocab_tbl, int max_indx)
93 0 : {
94 : int indx;
95 0 : for ( indx = 1 ; indx < max_indx ; indx++ )
96 : {
97 0 : str_sub_vocab_tbl[indx].next = &str_sub_vocab_tbl[indx-1];
98 : }
99 0 : }
100 :
101 : /* **************************************************************************
102 : *
103 : * Function name: add_str_sub_entry
104 : * Synopsis: Add an entry to the given Str-Subst vocab
105 : *
106 : * Inputs:
107 : * Parameters: Pointer to:
108 : * ename space containing the name of the entry
109 : * subst_str space containing the substitution string
110 : * *str_sub_vocab the "tail" of the Str-Subst vocab-list
111 : *
112 : * Outputs:
113 : * Returned Value: NONE
114 : * Supplied Pointers:
115 : * *str_sub_vocab Will point to new entry
116 : * Memory Allocated:
117 : * Memory for the new entry will be allocated.
118 : * When Freed?
119 : * When reset_str_sub_vocab() is applied to the same vocab-list.
120 : * In some instances, the new entry will be freed upon end
121 : * of tokenization; in others, only on termination of program.
122 : *
123 : * Error Detection:
124 : * Failure to allocate memory is a Fatal Error.
125 : *
126 : * Process Explanation:
127 : * The name and substitution-string pointers are presumed to already
128 : * point to stable memory-spaces. Memory will be allocated
129 : * for the entry itself; its pointers will be entered and the
130 : * given pointer-to-the-tail-of-the-vocabulary will be updated.
131 : *
132 : * Extraneous Remarks:
133 : * This might have been where we would have checked for re-aliasing,
134 : * but the introduction of the approach to aliasing embodied in
135 : * the various create_..._alias() routines neatly bypasses it.
136 : *
137 : **************************************************************************** */
138 :
139 : void add_str_sub_entry( char *ename,
140 : char *subst_str,
141 : str_sub_vocab_t **str_sub_vocab )
142 29 : {
143 : str_sub_vocab_t *new_entry;
144 :
145 29 : new_entry = safe_malloc(sizeof(str_sub_vocab_t), "adding str_sub_entry");
146 29 : new_entry->name = ename;
147 29 : new_entry->alias = subst_str;
148 29 : new_entry->next = *str_sub_vocab;
149 :
150 29 : *str_sub_vocab = new_entry;
151 :
152 29 : }
153 :
154 :
155 : /* **************************************************************************
156 : *
157 : * Function name: lookup_str_sub
158 : * Synopsis: Look for a name in the given Str-Subst vocabulary
159 : *
160 : * Inputs:
161 : * Parameters:
162 : * tname The "target" name for which to look
163 : * str_sub_vocab The Str-Subst vocab-list
164 : *
165 : * Outputs:
166 : * Returned Value: Pointer to the substitution string, or
167 : * NULL pointer if name not found.
168 : * May be NULL if subst'n string is NULL.
169 : *
170 : **************************************************************************** */
171 :
172 : char *lookup_str_sub( char *tname, str_sub_vocab_t *str_sub_vocab )
173 26 : {
174 : str_sub_vocab_t *curr;
175 26 : char *retval = NULL;
176 :
177 27 : for (curr = str_sub_vocab ; curr != NULL ; curr=curr->next)
178 : {
179 27 : if ( strcasecmp(tname, curr->name) == 0 )
180 : {
181 26 : retval = curr->alias;
182 26 : break;
183 : }
184 : }
185 26 : return ( retval ) ;
186 : }
187 :
188 : /* **************************************************************************
189 : *
190 : * Function name: exists_in_str_sub
191 : * Synopsis: Confirm whether a given name exists in a given
192 : * String-Substitution vocabulary
193 : *
194 : * Inputs:
195 : * Parameters:
196 : * tname The "target" name for which to look
197 : * str_sub_vocab Pointer to the Str-Subst vocab-list
198 : *
199 : * Outputs:
200 : * Returned Value: TRUE if the name is found
201 : *
202 : * Extraneous Remarks:
203 : * Because the Returned Value of lookup_str_sub() may be NULL for
204 : * other reasons than that the name was not found, we cannot
205 : * rely on that routine, and must replicate the outer-shell
206 : * of its structure.
207 : *
208 : **************************************************************************** */
209 :
210 : bool exists_in_str_sub( char *tname, str_sub_vocab_t *str_sub_vocab )
211 95 : {
212 : str_sub_vocab_t *curr;
213 95 : bool retval = FALSE;
214 :
215 121 : for (curr = str_sub_vocab ; curr != NULL ; curr=curr->next)
216 : {
217 72 : if ( strcasecmp(tname, curr->name) == 0 )
218 : {
219 46 : retval = TRUE;
220 46 : break;
221 : }
222 : }
223 95 : return ( retval );
224 :
225 : }
226 :
227 : /* **************************************************************************
228 : *
229 : * Function name: create_str_sub_alias
230 : * Synopsis: Create an Alias in a String-Substitution vocabulary
231 : * Return a "success" flag.
232 : *
233 : * Associated FORTH word: ALIAS
234 : *
235 : * Inputs:
236 : * Parameters:
237 : * old_name Name of existing entry
238 : * new_name New name for which to create an entry
239 : * *str_sub_vocab Pointer to "tail" of Str-Subst vocab-list
240 : *
241 : * Outputs:
242 : * Returned Value: TRUE if old_name found in str_sub_vocab
243 : * Supplied Pointers:
244 : * *str_sub_vocab Will be updated to point to the new entry
245 : * Memory Allocated:
246 : * A copy of the "old" name's substitution string.
247 : * When Freed?
248 : * When reset_str_sub_vocab() is applied to the same vocab-list.
249 : * In some instances, the new entry will be freed when the
250 : * device-node in which it was created is "finish"ed; in
251 : * others, only on termination of the program.
252 : *
253 : * Process Explanation:
254 : * The "new" name is presumed to point to a stable memory-space.
255 : * If the given "old" name exists in the given Str-Subst vocab-list,
256 : * duplicate the substitution string into newly-allocated memory
257 : * and pass the duplicated string and the "new" name along to
258 : * the add_str_sub_entry() routine and return TRUE.
259 : * If the given "old" name does not exist in the given vocab-list,
260 : * return FALSE.
261 : *
262 : * Extraneous Remarks:
263 : * This neatly bypasses the question of re-aliasing... ;-)
264 : *
265 : * We can rely on testing for a returned NULL from lookup_str_sub()
266 : * because we won't be applying this routine to any vocabulary
267 : * that permits a NULL in its substitution string.
268 : *
269 : **************************************************************************** */
270 :
271 : bool create_str_sub_alias(char *new_name,
272 : char *old_name,
273 : str_sub_vocab_t **str_sub_vocab )
274 0 : {
275 0 : bool retval = FALSE;
276 0 : char *old_subst_str = lookup_str_sub( old_name, *str_sub_vocab );
277 0 : if ( old_subst_str != NULL )
278 : {
279 0 : char *new_subst_str = strdup(old_subst_str );
280 0 : add_str_sub_entry(new_name, new_subst_str, str_sub_vocab );
281 0 : retval = TRUE ;
282 : }
283 :
284 0 : return ( retval );
285 : }
286 :
287 :
288 : /* **************************************************************************
289 : *
290 : * Function name: reset_str_sub_vocab
291 : * Synopsis: Reset a given Str-Subst vocab to its initial
292 : * "Built-In" position.
293 : *
294 : * Inputs:
295 : * Parameters:
296 : * *str_sub_vocab Pointer to the Str-Subst vocab-list
297 : * reset_position Position to which to reset the list
298 : *
299 : * Outputs:
300 : * Returned Value: NONE
301 : * Supplied Pointers:
302 : * *str_sub_vocab Reset to given "Built-In" position.
303 : * Memory Freed
304 : * All memory allocated by user-definitions will be freed
305 : *
306 : * Process Explanation:
307 : * The "stable memory-spaces" to which the name and substitution
308 : * string pointers point are presumed to have been acquired
309 : * by allocation of memory, which is reasonable for entries
310 : * created by the user as opposed to the built-in entries,
311 : * which we are, in any case, not releasing.
312 : * The substitution-string pointer may be null; watch out when
313 : * we free() it; not all C implementations forgive that.
314 : *
315 : **************************************************************************** */
316 :
317 : void reset_str_sub_vocab(
318 : str_sub_vocab_t **str_sub_vocab ,
319 : str_sub_vocab_t *reset_position )
320 0 : {
321 : str_sub_vocab_t *next_t;
322 :
323 0 : next_t = *str_sub_vocab;
324 0 : while ( next_t != reset_position )
325 : {
326 0 : next_t = (*str_sub_vocab)->next ;
327 :
328 0 : free( (*str_sub_vocab)->name );
329 0 : if ( !(*str_sub_vocab)->alias )
330 : {
331 0 : free( (*str_sub_vocab)->alias );
332 : }
333 0 : free( *str_sub_vocab );
334 0 : *str_sub_vocab = next_t ;
335 : }
336 0 : }
337 :
|