00001 /* 00002 * OpenBIOS - free your system! 00003 * ( FCode tokenizer ) 00004 * 00005 * This program is part of a free implementation of the IEEE 1275-1994 00006 * Standard for Boot (Initialization Configuration) Firmware. 00007 * 00008 * Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org> 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; version 2 of the License. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA 00022 * 00023 */ 00024 00025 /* ************************************************************************** 00026 * 00027 * General-purpose support functions for 00028 * String-Substitution-type vocabularies 00029 * 00030 * (C) Copyright 2005 IBM Corporation. All Rights Reserved. 00031 * Module Author: David L. Paktor dlpaktor@us.ibm.com 00032 * 00033 **************************************************************************** */ 00034 00035 /* ************************************************************************** 00036 * 00037 * A String-Substitution vocabulary, as the name implies, is one in 00038 * in which each an entry consists of two strings; one that is 00039 * sought, and one that is returned as a substitute. Macros and 00040 * aliases are implemented this way, as are also user-supplied 00041 * command-line symbol definitions. 00042 * 00043 **************************************************************************** */ 00044 00045 /* ************************************************************************** 00046 * 00047 * Functions Exported: 00048 * init_str_sub_vocab Initialize a String-Substitution vocab 00049 * add_str_sub_entry Add an entry to a Str-Subst vocab 00050 * lookup_str_sub Look for a name in a String-Substitution 00051 * vocab, return the substitution string. 00052 * exists_in_str_sub Confirm whether a given name exists in a 00053 * String-Substitution vocabulary 00054 * create_str_sub_alias Duplicate the behavior of one name with 00055 * another name. Return a "success" flag. 00056 * reset_str_sub_vocab Reset a given Str-Subst vocab to its initial 00057 * "Built-In" position. 00058 * 00059 * 00060 **************************************************************************** */ 00061 00062 #include <stdio.h> 00063 #include <stdlib.h> 00064 #if defined(__linux__) && ! defined(__USE_BSD) 00065 #define __USE_BSD 00066 #endif 00067 #include <string.h> 00068 00069 #include "errhandler.h" 00070 #include "strsubvocab.h" 00071 00072 00073 /* ************************************************************************** 00074 * 00075 * Function name: init_str_sub_vocab 00076 * Synopsis: Dynamically initialize the link-pointers 00077 * of the.given String-Substitution vocabulary 00078 * 00079 * Inputs: 00080 * Parameters: 00081 * str_sub_vocab_tbl Pointer to the initial Str-Subst vocab array 00082 * max_indx Maximum Index of the initial array. 00083 * 00084 * Outputs: 00085 * Returned Value: None 00086 * Global Variables: 00087 * The link-fields of the initial Str-Subs vocab array entries 00088 * will be filled in. 00089 * 00090 **************************************************************************** */ 00091 00092 void init_str_sub_vocab( str_sub_vocab_t *str_sub_vocab_tbl, int max_indx) 00093 { 00094 int indx; 00095 for ( indx = 1 ; indx < max_indx ; indx++ ) 00096 { 00097 str_sub_vocab_tbl[indx].next = &str_sub_vocab_tbl[indx-1]; 00098 } 00099 } 00100 00101 /* ************************************************************************** 00102 * 00103 * Function name: add_str_sub_entry 00104 * Synopsis: Add an entry to the given Str-Subst vocab 00105 * 00106 * Inputs: 00107 * Parameters: Pointer to: 00108 * ename space containing the name of the entry 00109 * subst_str space containing the substitution string 00110 * *str_sub_vocab the "tail" of the Str-Subst vocab-list 00111 * 00112 * Outputs: 00113 * Returned Value: NONE 00114 * Supplied Pointers: 00115 * *str_sub_vocab Will point to new entry 00116 * Memory Allocated: 00117 * Memory for the new entry will be allocated. 00118 * When Freed? 00119 * When reset_str_sub_vocab() is applied to the same vocab-list. 00120 * In some instances, the new entry will be freed upon end 00121 * of tokenization; in others, only on termination of program. 00122 * 00123 * Error Detection: 00124 * Failure to allocate memory is a Fatal Error. 00125 * 00126 * Process Explanation: 00127 * The name and substitution-string pointers are presumed to already 00128 * point to stable memory-spaces. Memory will be allocated 00129 * for the entry itself; its pointers will be entered and the 00130 * given pointer-to-the-tail-of-the-vocabulary will be updated. 00131 * 00132 * Extraneous Remarks: 00133 * This might have been where we would have checked for re-aliasing, 00134 * but the introduction of the approach to aliasing embodied in 00135 * the various create_..._alias() routines neatly bypasses it. 00136 * 00137 **************************************************************************** */ 00138 00139 void add_str_sub_entry( char *ename, 00140 char *subst_str, 00141 str_sub_vocab_t **str_sub_vocab ) 00142 { 00143 str_sub_vocab_t *new_entry; 00144 00145 new_entry = safe_malloc(sizeof(str_sub_vocab_t), "adding str_sub_entry"); 00146 new_entry->name = ename; 00147 new_entry->alias = subst_str; 00148 new_entry->next = *str_sub_vocab; 00149 00150 *str_sub_vocab = new_entry; 00151 00152 } 00153 00154 00155 /* ************************************************************************** 00156 * 00157 * Function name: lookup_str_sub 00158 * Synopsis: Look for a name in the given Str-Subst vocabulary 00159 * 00160 * Inputs: 00161 * Parameters: 00162 * tname The "target" name for which to look 00163 * str_sub_vocab The Str-Subst vocab-list 00164 * 00165 * Outputs: 00166 * Returned Value: Pointer to the substitution string, or 00167 * NULL pointer if name not found. 00168 * May be NULL if subst'n string is NULL. 00169 * 00170 **************************************************************************** */ 00171 00172 char *lookup_str_sub( char *tname, str_sub_vocab_t *str_sub_vocab ) 00173 { 00174 str_sub_vocab_t *curr; 00175 char *retval = NULL; 00176 00177 for (curr = str_sub_vocab ; curr != NULL ; curr=curr->next) 00178 { 00179 if ( strcasecmp(tname, curr->name) == 0 ) 00180 { 00181 retval = curr->alias; 00182 break; 00183 } 00184 } 00185 return ( retval ) ; 00186 } 00187 00188 /* ************************************************************************** 00189 * 00190 * Function name: exists_in_str_sub 00191 * Synopsis: Confirm whether a given name exists in a given 00192 * String-Substitution vocabulary 00193 * 00194 * Inputs: 00195 * Parameters: 00196 * tname The "target" name for which to look 00197 * str_sub_vocab Pointer to the Str-Subst vocab-list 00198 * 00199 * Outputs: 00200 * Returned Value: TRUE if the name is found 00201 * 00202 * Extraneous Remarks: 00203 * Because the Returned Value of lookup_str_sub() may be NULL for 00204 * other reasons than that the name was not found, we cannot 00205 * rely on that routine, and must replicate the outer-shell 00206 * of its structure. 00207 * 00208 **************************************************************************** */ 00209 00210 bool exists_in_str_sub( char *tname, str_sub_vocab_t *str_sub_vocab ) 00211 { 00212 str_sub_vocab_t *curr; 00213 bool retval = FALSE; 00214 00215 for (curr = str_sub_vocab ; curr != NULL ; curr=curr->next) 00216 { 00217 if ( strcasecmp(tname, curr->name) == 0 ) 00218 { 00219 retval = TRUE; 00220 break; 00221 } 00222 } 00223 return ( retval ); 00224 00225 } 00226 00227 /* ************************************************************************** 00228 * 00229 * Function name: create_str_sub_alias 00230 * Synopsis: Create an Alias in a String-Substitution vocabulary 00231 * Return a "success" flag. 00232 * 00233 * Associated FORTH word: ALIAS 00234 * 00235 * Inputs: 00236 * Parameters: 00237 * old_name Name of existing entry 00238 * new_name New name for which to create an entry 00239 * *str_sub_vocab Pointer to "tail" of Str-Subst vocab-list 00240 * 00241 * Outputs: 00242 * Returned Value: TRUE if old_name found in str_sub_vocab 00243 * Supplied Pointers: 00244 * *str_sub_vocab Will be updated to point to the new entry 00245 * Memory Allocated: 00246 * A copy of the "old" name's substitution string. 00247 * When Freed? 00248 * When reset_str_sub_vocab() is applied to the same vocab-list. 00249 * In some instances, the new entry will be freed when the 00250 * device-node in which it was created is "finish"ed; in 00251 * others, only on termination of the program. 00252 * 00253 * Process Explanation: 00254 * The "new" name is presumed to point to a stable memory-space. 00255 * If the given "old" name exists in the given Str-Subst vocab-list, 00256 * duplicate the substitution string into newly-allocated memory 00257 * and pass the duplicated string and the "new" name along to 00258 * the add_str_sub_entry() routine and return TRUE. 00259 * If the given "old" name does not exist in the given vocab-list, 00260 * return FALSE. 00261 * 00262 * Extraneous Remarks: 00263 * This neatly bypasses the question of re-aliasing... ;-) 00264 * 00265 * We can rely on testing for a returned NULL from lookup_str_sub() 00266 * because we won't be applying this routine to any vocabulary 00267 * that permits a NULL in its substitution string. 00268 * 00269 **************************************************************************** */ 00270 00271 bool create_str_sub_alias(char *new_name, 00272 char *old_name, 00273 str_sub_vocab_t **str_sub_vocab ) 00274 { 00275 bool retval = FALSE; 00276 char *old_subst_str = lookup_str_sub( old_name, *str_sub_vocab ); 00277 if ( old_subst_str != NULL ) 00278 { 00279 char *new_subst_str = strdup(old_subst_str ); 00280 add_str_sub_entry(new_name, new_subst_str, str_sub_vocab ); 00281 retval = TRUE ; 00282 } 00283 00284 return ( retval ); 00285 } 00286 00287 00288 /* ************************************************************************** 00289 * 00290 * Function name: reset_str_sub_vocab 00291 * Synopsis: Reset a given Str-Subst vocab to its initial 00292 * "Built-In" position. 00293 * 00294 * Inputs: 00295 * Parameters: 00296 * *str_sub_vocab Pointer to the Str-Subst vocab-list 00297 * reset_position Position to which to reset the list 00298 * 00299 * Outputs: 00300 * Returned Value: NONE 00301 * Supplied Pointers: 00302 * *str_sub_vocab Reset to given "Built-In" position. 00303 * Memory Freed 00304 * All memory allocated by user-definitions will be freed 00305 * 00306 * Process Explanation: 00307 * The "stable memory-spaces" to which the name and substitution 00308 * string pointers point are presumed to have been acquired 00309 * by allocation of memory, which is reasonable for entries 00310 * created by the user as opposed to the built-in entries, 00311 * which we are, in any case, not releasing. 00312 * The substitution-string pointer may be null; watch out when 00313 * we free() it; not all C implementations forgive that. 00314 * 00315 **************************************************************************** */ 00316 00317 void reset_str_sub_vocab( 00318 str_sub_vocab_t **str_sub_vocab , 00319 str_sub_vocab_t *reset_position ) 00320 { 00321 str_sub_vocab_t *next_t; 00322 00323 next_t = *str_sub_vocab; 00324 while ( next_t != reset_position ) 00325 { 00326 next_t = (*str_sub_vocab)->next ; 00327 00328 free( (*str_sub_vocab)->name ); 00329 if ( !(*str_sub_vocab)->alias ) 00330 { 00331 free( (*str_sub_vocab)->alias ); 00332 } 00333 free( *str_sub_vocab ); 00334 *str_sub_vocab = next_t ; 00335 } 00336 } 00337