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 : * Threaded Interpretive Code (T. I. C.)-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 : * We are going to implement a strategy that takes better advantage
38 : * of the concept of Threaded Interpretive Code (well, okay,
39 : * it won't really be interpretive ... ) We will use it to
40 : * implement a small (but expandable) subset of FORTH-like
41 : * commands in Tokenizer-Escape mode, as well as a few other
42 : * things, such as conditional-tokenization.
43 : *
44 : * The Threaded Interpretive Code Header data structure is described
45 : * in detail in the accompanying ticvocab.h header-file.
46 : *
47 : * In most cases, the contents of a beginning portion of the vocabulary
48 : * are known at compile-time, and later parts are added by the
49 : * user at run-time. (The linked-list structure is needed to allow
50 : * for that.) We can initialize the known start of the vocabulary
51 : * easily, except for the link-pointers, as an array.
52 : * We can either explicitly state an index for each entry's link-pointer
53 : * to the previous entry (which can become a problem to maintain) or
54 : * have a function to initialize the links dynamically, at run-time.
55 : * I think I will (regretfully, resignedly) choose the latter.
56 : *
57 : * We will define a few general-purpose functions for dealing with
58 : * T. I. C. -type vocabularies. Eventually, it might be a good
59 : * idea to convert all the vocabularies to this structure...
60 : *
61 : **************************************************************************** */
62 :
63 : /* **************************************************************************
64 : *
65 : *
66 : * Revision History:
67 : * Mon, 19 Dec 2005 by David L. Paktor
68 : * Begin converting most, if not all, of the vocabularies to
69 : * T. I. C. -type structure.
70 : *
71 : **************************************************************************** */
72 :
73 :
74 : /* **************************************************************************
75 : *
76 : * Functions Exported:
77 : * init_tic_vocab Initialize a TIC_HDR -type vocabulary
78 : * add_tic_entry Add an entry to a TIC_HDR -type vocabulary
79 : * lookup_tic_entry Look for a name in a TIC_HDR -type vocabulary
80 : * handle_tic_vocab Perform a function in a TIC_HDR -type vocab
81 : * exists_in_tic_vocab Confirm whether a given name exists in a
82 : * TIC_HDR -type vocabulary
83 : * create_tic_alias Duplicate the behavior of one name with
84 : * another name. Return a "success" flag.
85 : * reset_tic_vocab Reset a given TIC_HDR -type vocabulary to
86 : * its "Built-In" position.
87 : *
88 : **************************************************************************** */
89 :
90 :
91 : /* **************************************************************************
92 : *
93 : * Global Variables Exported
94 : * tic_found The entry, in a TIC_HDR -type vocabulary,
95 : * that has just been found and is being
96 : * "handled". Needed for protection against
97 : * recursion in a User-defined Macro (which
98 : * should occur only rarely).
99 : *
100 : **************************************************************************** */
101 :
102 :
103 : #include <stdlib.h>
104 : #include <string.h>
105 : #include "ticvocab.h"
106 : #include "errhandler.h"
107 :
108 : tic_hdr_t *tic_found;
109 :
110 : /* **************************************************************************
111 : *
112 : * Function name: init_tic_vocab
113 : * Synopsis: Dynamically initialize the link-pointers
114 : * of the.given TIC_HDR -type vocabulary
115 : *
116 : * Inputs:
117 : * Parameters:
118 : * tic_vocab_tbl Pointer to the initial TIC_HDR vocab array
119 : * max_indx Maximum Index of the initial array.
120 : * tic_vocab_ptr Pointer to the vocab "tail"
121 : *
122 : * Outputs:
123 : * Returned Value: None
124 : * Global Variables:
125 : * The link-fields of the initial TIC_HDR vocab array entries
126 : * will be filled in.
127 : * Supplied Pointers:
128 : * *tic_vocab_ptr Points to the last element in the array
129 : *
130 : * Process Explanation:
131 : * The value that tic_vocab_ptr has upon entry to the routine
132 : * (which may point to the end of another array which is to
133 : * precede this one in the voacbulary) gets entered into
134 : * the link-pointer field of the first element of the array.
135 : * For this reason, it is important that all TIC_HDR vocabulary
136 : * pointers that will be pased to this routine have their
137 : * initial values explicitly declared NULL.
138 : *
139 : **************************************************************************** */
140 :
141 : void init_tic_vocab( tic_hdr_t *tic_vocab_tbl,
142 : int max_indx,
143 : tic_hdr_t **tic_vocab_ptr)
144 924 : {
145 : int indx;
146 94248 : for ( indx = 0 ; indx < max_indx ; indx++ )
147 : {
148 93324 : tic_vocab_tbl[indx].next = *tic_vocab_ptr;
149 93324 : *tic_vocab_ptr = &tic_vocab_tbl[indx];
150 : }
151 924 : }
152 :
153 :
154 : /* **************************************************************************
155 : *
156 : * Function name: add_tic_entry
157 : * Synopsis: Add an entry to the given TIC_HDR -type vocabulary
158 : *
159 : * Inputs:
160 : * Parameters:
161 : * tname Pointer to space containing the name of the entry
162 : * tfunct Pointer to the routine the new entry will call
163 : * tparam The "parameter field" value (may be a pointer)
164 : * fw_defr FWord Token of the entry's Definer
165 : * pfldsiz Size of "param field" (if a pointer to alloc'd mem)
166 : * ign_fnc Pointer to "ignoring" routine for new entry
167 : * tic_vocab Pointer to ptr to "tail" of T.I.C.-type vocab-list
168 : *
169 : * Outputs:
170 : * Returned Value: NONE
171 : * Supplied Pointers:
172 : * *tic_vocab Will point to new entry
173 : * Memory Allocated:
174 : * For the new entry.
175 : * When Freed?
176 : * When reset_tic_vocab() is applied to the same vocab-list.
177 : *
178 : * Error Detection:
179 : * Failure to allocate memory is a Fatal Error.
180 : *
181 : * Process Explanation:
182 : * The name pointer is presumed to already point to a stable,
183 : * newly-allocated memory-space. If the parameter field is
184 : * actually a pointer, it, too, is presumed to already have
185 : * been allocated.
186 : * Memory will be allocated for the entry itself; its pointers
187 : * will be entered and the given pointer-to-the-tail-of-the-
188 : * -vocabulary will be updated to point to the new entry.
189 : *
190 : **************************************************************************** */
191 :
192 : void add_tic_entry( char *tname,
193 : void (*tfunct)(),
194 : TIC_P_DEFLT_TYPE tparam,
195 : fwtoken fw_defr,
196 : int pfldsiz,
197 : void (*ign_fnc)(),
198 : tic_hdr_t **tic_vocab )
199 10647 : {
200 : tic_hdr_t *new_entry;
201 :
202 10647 : new_entry = safe_malloc(sizeof(tic_hdr_t), "adding tic_entry");
203 10647 : new_entry->name = tname;
204 10647 : new_entry->next = *tic_vocab;
205 10647 : new_entry->funct = tfunct;
206 10647 : new_entry->pfield.deflt_elem = tparam;
207 10647 : new_entry->fword_defr = fw_defr;
208 10647 : new_entry->ign_func = ign_fnc;
209 10647 : new_entry->pfld_size = pfldsiz;
210 :
211 10647 : *tic_vocab = new_entry;
212 :
213 10647 : }
214 :
215 : /* **************************************************************************
216 : *
217 : * Function name: lookup_tic_entry
218 : * Synopsis: Look for a name in the given TIC_HDR -type vocabulary
219 : *
220 : * Inputs:
221 : * Parameters:
222 : * tname The "target" name for which to look
223 : * tic_vocab Pointer to the T. I. C. -type vocabulary
224 : *
225 : * Outputs:
226 : * Returned Value: Pointer to the relevant entry, or
227 : * NULL if name not found.
228 : *
229 : * Extraneous Remarks:
230 : * We don't set the global tic_found here because this routine
231 : * is not always called when the found function is going to
232 : * be executed; sometimes it is called for error-detection,
233 : * for instance...
234 : *
235 : **************************************************************************** */
236 :
237 : tic_hdr_t *lookup_tic_entry( char *tname, tic_hdr_t *tic_vocab )
238 422767 : {
239 : tic_hdr_t *curr ;
240 :
241 83713444 : for (curr = tic_vocab ; curr != NULL ; curr=curr->next)
242 : {
243 83528659 : if ( strcasecmp(tname, curr->name) == 0 )
244 : {
245 237982 : break;
246 : }
247 : }
248 :
249 422767 : return ( curr ) ;
250 : }
251 :
252 : /* **************************************************************************
253 : *
254 : * Function name: exists_in_tic_vocab
255 : * Synopsis: Confirm whether the given name exists in the
256 : * given TIC_HDR -type vocabulary
257 : *
258 : * Inputs:
259 : * Parameters:
260 : * tname The name for which to look
261 : * tic_vocab Pointer to the T. I. C. -type vocabulary
262 : *
263 : * Outputs:
264 : * Returned Value: TRUE if name is found,
265 : *
266 : **************************************************************************** */
267 :
268 : bool exists_in_tic_vocab( char *tname, tic_hdr_t *tic_vocab )
269 7 : {
270 : tic_hdr_t *found ;
271 7 : bool retval = FALSE;
272 :
273 7 : found = lookup_tic_entry( tname, tic_vocab );
274 7 : if ( found != NULL )
275 : {
276 1 : retval = TRUE;
277 : }
278 :
279 7 : return ( retval );
280 : }
281 :
282 :
283 : /* **************************************************************************
284 : *
285 : * Function name: create_tic_alias
286 : * Synopsis: Create an Alias in a TIC_HDR -type vocabulary
287 : * Return a "success" flag.
288 : *
289 : * Associated FORTH word: ALIAS
290 : *
291 : * Inputs:
292 : * Parameters:
293 : * old_name Name of existing entry
294 : * new_name New name for which to create an entry
295 : * *tic_vocab Pointer to the "tail" of the
296 : * T. I. C. -type vocab-list
297 : *
298 : * Outputs:
299 : * Returned Value: TRUE if old_name found in given vocab
300 : * Supplied Pointers:
301 : * *tic_vocab Will be updated to point to the new entry
302 : * Memory Allocated:
303 : * For the new entry, by the support routine.
304 : * When Freed?
305 : * When reset_tic_vocab() is applied to the same vocab-list.
306 : *
307 : * Process Explanation:
308 : * Both the "old" and "new" names are presumed to already point to
309 : * stable, freshly allocated memory-spaces.
310 : * Even if the "old" entry's pfld_size is not zero, meaning its
311 : * param-field is a pointer to allocated memory, we still do
312 : * not need to copy it into a freshly allocated memory-space,
313 : * as long as we make the new alias-entry's pfld_size zero:
314 : * the reference to the old space will work, and the old
315 : * entry's param-field memory space will not be freed with
316 : * the alias-entry but only with the "old" entry.
317 : *
318 : **************************************************************************** */
319 :
320 : bool create_tic_alias( char *new_name, char *old_name, tic_hdr_t **tic_vocab )
321 338 : {
322 : tic_hdr_t *found ;
323 338 : bool retval = FALSE;
324 :
325 338 : found = lookup_tic_entry( old_name, *tic_vocab );
326 338 : if ( found != NULL )
327 : {
328 145 : add_tic_entry( new_name, found->funct,
329 : found->pfield.deflt_elem,
330 : found->fword_defr,
331 : 0, found->ign_func, tic_vocab );
332 145 : retval = TRUE;
333 : }
334 :
335 338 : return ( retval );
336 : }
337 :
338 :
339 : /* **************************************************************************
340 : *
341 : * Function name: handle_tic_vocab
342 : * Synopsis: Perform the function associated with the given name
343 : * in the given TIC_HDR -type vocabulary
344 : *
345 : * Inputs:
346 : * Parameters:
347 : * tname The "target" name for which to look
348 : * tic_vocab Pointer to the T. I. C. -type vocabulary
349 : *
350 : * Outputs:
351 : * Returned Value: TRUE if the given name is valid in the given vocab
352 : * Global Variables:
353 : * tic_found Points to the TIC entry of the "target"
354 : * name, if it was found; else, NULL.
355 : * Global Behavior:
356 : * Whatever the associated function does...
357 : *
358 : * Process Explanation:
359 : * Find the name and execute its associated function.
360 : * If the name is not in the given vocabulary, return
361 : * an indication; leave it to the calling routine
362 : * to decide how to proceed.
363 : *
364 : **************************************************************************** */
365 :
366 : bool handle_tic_vocab( char *tname, tic_hdr_t *tic_vocab )
367 106338 : {
368 106338 : bool retval = FALSE;
369 :
370 106338 : tic_found = lookup_tic_entry( tname, tic_vocab );
371 106338 : if ( tic_found != NULL )
372 : {
373 106337 : tic_found->funct( tic_found->pfield);
374 106337 : retval = TRUE;
375 : }
376 :
377 106338 : return ( retval ) ;
378 : }
379 :
380 : /* **************************************************************************
381 : *
382 : * Function name: reset_tic_vocab
383 : * Synopsis: Reset a given TIC_HDR -type vocabulary to
384 : * its given "Built-In" position.
385 : *
386 : * Inputs:
387 : * Parameters:
388 : * *tic_vocab Pointer to the T. I. C.-type vocab-list
389 : * reset_position Position to which to reset the list
390 : *
391 : * Outputs:
392 : * Returned Value: NONE
393 : * Supplied Pointers:
394 : * *tic_vocab Reset to given "Built-In" position.
395 : * Memory Freed
396 : * All memory allocated by user-definitions will be freed
397 : *
398 : * Process Explanation:
399 : * The "stable memory-spaces" to which the name and parameter
400 : * field pointers point are presumed to have been acquired
401 : * by allocation of memory, which is reasonable for entries
402 : * created by the user as opposed to the built-in entries,
403 : * which we are, in any case, not releasing.
404 : * The parameter-field size field tells us whether we need to
405 : * free() the parameter-field pointer.
406 : *
407 : **************************************************************************** */
408 :
409 : void reset_tic_vocab( tic_hdr_t **tic_vocab, tic_hdr_t *reset_position )
410 1004 : {
411 : tic_hdr_t *next_t;
412 :
413 1004 : next_t = *tic_vocab;
414 12318 : while ( next_t != reset_position )
415 : {
416 10310 : next_t = (*tic_vocab)->next ;
417 :
418 10310 : free( (*tic_vocab)->name );
419 10310 : if ( (*tic_vocab)->pfld_size != 0 )
420 : {
421 89 : free( (*tic_vocab)->pfield.chr_ptr );
422 : }
423 10310 : free( *tic_vocab );
424 10310 : *tic_vocab = next_t ;
425 : }
426 1004 : }
|