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 : * User-defined command-line compilation-control symbols
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 : * The syntax for user-defined command-line compilation-control symbols
38 : * is <NAME>[=<VALUE>]
39 : *
40 : * The name is always required; the equal-sign and value is optional.
41 : * If you wish the "value" to contain spaces or quotes, you can
42 : * accomplish that using the shell escape conventions.
43 : *
44 : * The operations that can be performed upon these symbols will be
45 : * described by the operators that use them as operands, but,
46 : * broadly speaking, the tests will either be to simply verify
47 : * the existence of a symbol, or to evaluate the defined value.
48 : *
49 : * Once a symbol is defined on the command-line, it stays in effect
50 : * for the duration of the entire batch of tokenizations (i.e.,
51 : * if there are multiple input files named on the command line).
52 : * Also, there are no symbols defined at the outset. Therefore,
53 : * there is no need for either an "init" or a "reset" routine.
54 : *
55 : **************************************************************************** */
56 :
57 : /* **************************************************************************
58 : *
59 : * User-defined command-line compilation-control symbols are
60 : * implemented as a String-Substitution-type vocabulary.
61 : *
62 : **************************************************************************** */
63 :
64 : /* **************************************************************************
65 : *
66 : * Functions Exported:
67 : * add_user_symbol Add a user-defined symbol to the list
68 : * lookup_user_symbol Look for a user-defined symbol, return
69 : * the assigned value.
70 : * exists_as_user_symbol Confirm whether a given name exists
71 : * as a user-defined symbol.
72 : * eval_user_symbol Tokenize the value assigned to a user
73 : * symbol.
74 : * list_user_symbols Print the list of user-defined symbols
75 : * for the Logfile.
76 : *
77 : **************************************************************************** */
78 :
79 : /* **************************************************************************
80 : *
81 : * Still to be done:
82 : * Convert the handling of user-defined symbols to the T.I.C.
83 : * data-structure and its support routines. This should
84 : * eliminate any further need of String-Substitution-type
85 : * vocabularies. User-defined symbols will, however, still
86 : * need to be a separate vocabulary from the Global, because
87 : * they are required to stay in effect for the duration of
88 : * the entire batch of tokenizations...
89 : * (Afterthought: This is only true for user-defined symbols that
90 : * were created on the command-line; if we ever allow symbols
91 : * to be defined in the Source file, they should be as volatile
92 : * as anything else that comes from a source file...
93 : * Putting source-file-derived user-defined symbols into the Global
94 : * Vocabulary could be a quasi-simple way to accomplish this.)
95 : *
96 : * Enable the definition of user-symbols from the Source file, using
97 : * a syntax like: [define] symbol or [define] symbol=<value>
98 : * (How to allow spaces into the <value>? Maybe make the syntax
99 : * [define] symbol = <value components to end of line>
100 : * delimited in a manner similar to Macro definitions.
101 : * There might be a need to be able to [undefine] a user-symbol
102 : * that would entail defining an unlink_tic_entry function.
103 : * Not difficult; just keeping this around as a reminder...
104 : *
105 : **************************************************************************** */
106 :
107 :
108 :
109 : #include <stdio.h>
110 : #include <stdlib.h>
111 : #if defined(__linux__) && ! defined(__USE_BSD)
112 : #define __USE_BSD
113 : #endif
114 : #include <string.h>
115 :
116 : #include "errhandler.h"
117 : #include "strsubvocab.h"
118 : #include "usersymbols.h"
119 : #include "scanner.h"
120 :
121 :
122 : /* **************************************************************************
123 : *
124 : * Internal Static Variables
125 : * user_symbol_list Pointer to the "tail" of the list of
126 : * user-defined symbols.
127 : * user_symbol_count Count of how many are defined
128 : *
129 : **************************************************************************** */
130 :
131 : static str_sub_vocab_t *user_symbol_list = NULL;
132 : static int user_symbol_count = 0;
133 :
134 : /* **************************************************************************
135 : *
136 : * Function name: add_user_symbol
137 : * Synopsis: Add a user-defined symbol to the list
138 : *
139 : * Inputs:
140 : * Parameters:
141 : * raw_symb The string as supplied on the command-line.
142 : * Local Static Variables:
143 : * user_symbol_list Pointer to the list of user-defined symbols.
144 : *
145 : * Outputs:
146 : * Returned Value: NONE
147 : * Local Static Variables:
148 : * user_symbol_list Will be updated.
149 : * user_symbol_count Will be incremented
150 : * Memory Allocated:
151 : * for the string(s) and the new entry
152 : * When Freed?
153 : * Never. Well, only on termination of the program. User-defined
154 : * symbols endure for the entire batch of tokenizations.
155 : *
156 : * Process Explanation:
157 : * The string in raw_symb may or may not include the optional
158 : * equal-sign and value pair. If the equal-sign is present,
159 : * the remainder of the string will become the "value" that
160 : * will be returned by the "lookup" routine.
161 : * Memory for the name string and for the value, if there is one,
162 : * will be allocated here, in one step. Memory for the data
163 : * structure itself will be allocated by the support routine.
164 : *
165 : **************************************************************************** */
166 :
167 : void add_user_symbol(char *raw_symb)
168 29 : {
169 : char *symb_nam;
170 : char *symb_valu;
171 :
172 29 : symb_nam = strdup(raw_symb);
173 29 : symb_valu = strchr(symb_nam,'=');
174 29 : if ( symb_valu != NULL )
175 : {
176 20 : *symb_valu = 0;
177 20 : symb_valu++;
178 : }
179 29 : add_str_sub_entry(symb_nam, symb_valu, &user_symbol_list );
180 29 : user_symbol_count++;
181 29 : }
182 :
183 :
184 : /* **************************************************************************
185 : *
186 : * Function name: lookup_user_symbol
187 : * Synopsis: Look for the given name as user-defined symbol, return
188 : * the assigned value.
189 : *
190 : * Inputs:
191 : * Parameters:
192 : * symb_nam The name for which to look.
193 : * Local Static Variables:
194 : * user_symbol_list Pointer to the list of user-defined symbols.
195 : *
196 : * Outputs:
197 : * Returned Value: Pointer to the "value" string, or NULL
198 : * pointer if the name was not found.
199 : * May also be NULL if "value" is NULL.
200 : *
201 : **************************************************************************** */
202 :
203 : char *lookup_user_symbol(char *symb_nam)
204 26 : {
205 : char *symb_valu;
206 :
207 26 : symb_valu = lookup_str_sub(symb_nam, user_symbol_list );
208 26 : return (symb_valu);
209 : }
210 :
211 : /* **************************************************************************
212 : *
213 : * Function name: exists_as_user_symbol
214 : * Synopsis: Confirm whether a given name exists
215 : * as a user-defined symbol.
216 : *
217 : * Inputs:
218 : * Parameters:
219 : * symb_nam The name for which to look.
220 : * Local Static Variables:
221 : * user_symbol_list Pointer to the list of user-defined symbols.
222 : *
223 : * Outputs:
224 : * Returned Value: TRUE if the name is found
225 : *
226 : **************************************************************************** */
227 :
228 : bool exists_as_user_symbol(char *symb_nam)
229 95 : {
230 : bool retval;
231 :
232 95 : retval = exists_in_str_sub(symb_nam, user_symbol_list );
233 95 : return (retval);
234 : }
235 :
236 : /* **************************************************************************
237 : *
238 : * Function name: eval_user_symbol
239 : * Synopsis: Tokenize the value assigned to a user-symbol.
240 : *
241 : * Associated Tokenizer directive (synonyms): [DEFINED]
242 : * #DEFINED
243 : * [#DEFINED]
244 : *
245 : * Syntax Notes:
246 : * (1) The User-Defined-Symbol must appear
247 : * on the same line as the directive.
248 : * (2) This is not (yet) implemented in contexts that
249 : * directly read input from the stream, e.g.,
250 : * after ['] or after H# etc.
251 : *
252 : * Inputs:
253 : * Parameters:
254 : * symbol The User-Defined-Symbol to evaluate
255 : * Local Static Variables:
256 : * user_symbol_list Pointer to the list of user-defined symbols.
257 : *
258 : * Outputs:
259 : * Returned Value: NONE
260 : * The assigned value will be tokenized.
261 : *
262 : * Error Detection:
263 : * Calling routine is responsible for verifying that the user-symbol
264 : * is on the same line as the directive.
265 : * WARNING if the symbol is not found or has no assigned value.
266 : *
267 : * Process Explanation:
268 : * Look up the parameter in the User Symbol List, and retrieve
269 : * its associated value.
270 : * If it is not found, or if it has no associated value, issue
271 : * a WARNING and do nothing further. Otherwise...
272 : * Interpret the associated value as though it were source.
273 : *
274 : * Still to be done:
275 : * Hook-in this routine to the processing of: ['] F['] H# FLOAD
276 : * etc., and wherever else it might be needed or useful.
277 : *
278 : **************************************************************************** */
279 :
280 : void eval_user_symbol(char *symbol )
281 26 : {
282 : char *symb_valu;
283 26 : symb_valu = lookup_user_symbol(symbol );
284 26 : if ( symb_valu == NULL )
285 : {
286 0 : tokenization_error ( WARNING,
287 : "No value assigned to command-line symbol %s\n", symbol );
288 : }else{
289 26 : eval_string( symb_valu );
290 : }
291 :
292 26 : }
293 : /* **************************************************************************
294 : *
295 : * Function name: list_user_symbols
296 : * Synopsis: Print the list of user symbols for the Logfile.
297 : *
298 : * Inputs:
299 : * Parameters: NONE
300 : * Local Static Variables:
301 : * user_symbol_list Pointer to the list of user-defined symbols.
302 : * user_symbol_count Count of user-defined symbols.
303 : *
304 : * Outputs:
305 : * Returned Value: NONE
306 : * Printout: List of user symbols and their definitions;
307 : * nothing if user_symbol_list is NULL.
308 : *
309 : * Process Explanation:
310 : * We want to display the symbols in the same order they were created.
311 : * We will:
312 : * Allocate a temporary array of pointers.
313 : * Step backwards through the linked-list of symbols, and
314 : * enter their pointers into the array.
315 : * Collect the maximum length of the symbol names.
316 : * Step through the array in the reverse order, printing
317 : * as we go.
318 : * Use the max name length to space the equal-signs evenly
319 : * Free the temporary array.
320 : *
321 : **************************************************************************** */
322 :
323 : void list_user_symbols(void )
324 153 : {
325 : str_sub_vocab_t *curr;
326 :
327 153 : if ( user_symbol_list != NULL )
328 : {
329 : /* Collect the pointers and max length */
330 : str_sub_vocab_t **symb_ptr;
331 25 : int indx = 0;
332 25 : int maxlen = 0;
333 :
334 25 : symb_ptr = (str_sub_vocab_t **)safe_malloc(
335 : (sizeof(str_sub_vocab_t *) * user_symbol_count),
336 : "collecting user-symbol pointers" );
337 :
338 54 : for (curr = user_symbol_list ; curr != NULL ; curr=curr->next)
339 : {
340 29 : symb_ptr[indx] = curr;
341 29 : indx++;
342 29 : if ( strlen(curr->name) > maxlen ) maxlen = strlen(curr->name);
343 : }
344 :
345 : /* Now print 'em out */
346 25 : printf("\nUser-Defined Symbols:\n");
347 79 : while ( indx > 0 )
348 : {
349 29 : indx--;
350 29 : curr = symb_ptr[indx];
351 29 : printf("\t%s",curr->name);
352 29 : if ( curr->alias != NULL )
353 : {
354 : int strindx;
355 20 : for ( strindx = strlen(curr->name) ;
356 20 : strindx < maxlen ; strindx++ ) printf(" ");
357 20 : printf(" = %s",curr->alias);
358 : }
359 29 : printf("\n");
360 : }
361 25 : free(symb_ptr);
362 : }
363 153 : }
|