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 * User-defined command-line compilation-control symbols 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 * The syntax for user-defined command-line compilation-control symbols 00038 * is <NAME>[=<VALUE>] 00039 * 00040 * The name is always required; the equal-sign and value is optional. 00041 * If you wish the "value" to contain spaces or quotes, you can 00042 * accomplish that using the shell escape conventions. 00043 * 00044 * The operations that can be performed upon these symbols will be 00045 * described by the operators that use them as operands, but, 00046 * broadly speaking, the tests will either be to simply verify 00047 * the existence of a symbol, or to evaluate the defined value. 00048 * 00049 * Once a symbol is defined on the command-line, it stays in effect 00050 * for the duration of the entire batch of tokenizations (i.e., 00051 * if there are multiple input files named on the command line). 00052 * Also, there are no symbols defined at the outset. Therefore, 00053 * there is no need for either an "init" or a "reset" routine. 00054 * 00055 **************************************************************************** */ 00056 00057 /* ************************************************************************** 00058 * 00059 * User-defined command-line compilation-control symbols are 00060 * implemented as a String-Substitution-type vocabulary. 00061 * 00062 **************************************************************************** */ 00063 00064 /* ************************************************************************** 00065 * 00066 * Functions Exported: 00067 * add_user_symbol Add a user-defined symbol to the list 00068 * lookup_user_symbol Look for a user-defined symbol, return 00069 * the assigned value. 00070 * exists_as_user_symbol Confirm whether a given name exists 00071 * as a user-defined symbol. 00072 * eval_user_symbol Tokenize the value assigned to a user 00073 * symbol. 00074 * list_user_symbols Print the list of user-defined symbols 00075 * for the Logfile. 00076 * 00077 **************************************************************************** */ 00078 00079 /* ************************************************************************** 00080 * 00081 * Still to be done: 00082 * Convert the handling of user-defined symbols to the T.I.C. 00083 * data-structure and its support routines. This should 00084 * eliminate any further need of String-Substitution-type 00085 * vocabularies. User-defined symbols will, however, still 00086 * need to be a separate vocabulary from the Global, because 00087 * they are required to stay in effect for the duration of 00088 * the entire batch of tokenizations... 00089 * (Afterthought: This is only true for user-defined symbols that 00090 * were created on the command-line; if we ever allow symbols 00091 * to be defined in the Source file, they should be as volatile 00092 * as anything else that comes from a source file... 00093 * Putting source-file-derived user-defined symbols into the Global 00094 * Vocabulary could be a quasi-simple way to accomplish this.) 00095 * 00096 * Enable the definition of user-symbols from the Source file, using 00097 * a syntax like: [define] symbol or [define] symbol=<value> 00098 * (How to allow spaces into the <value>? Maybe make the syntax 00099 * [define] symbol = <value components to end of line> 00100 * delimited in a manner similar to Macro definitions. 00101 * There might be a need to be able to [undefine] a user-symbol 00102 * that would entail defining an unlink_tic_entry function. 00103 * Not difficult; just keeping this around as a reminder... 00104 * 00105 **************************************************************************** */ 00106 00107 00108 00109 #include <stdio.h> 00110 #include <stdlib.h> 00111 #if defined(__linux__) && ! defined(__USE_BSD) 00112 #define __USE_BSD 00113 #endif 00114 #include <string.h> 00115 00116 #include "errhandler.h" 00117 #include "strsubvocab.h" 00118 #include "usersymbols.h" 00119 #include "scanner.h" 00120 00121 00122 /* ************************************************************************** 00123 * 00124 * Internal Static Variables 00125 * user_symbol_list Pointer to the "tail" of the list of 00126 * user-defined symbols. 00127 * user_symbol_count Count of how many are defined 00128 * 00129 **************************************************************************** */ 00130 00131 static str_sub_vocab_t *user_symbol_list = NULL; 00132 static int user_symbol_count = 0; 00133 00134 /* ************************************************************************** 00135 * 00136 * Function name: add_user_symbol 00137 * Synopsis: Add a user-defined symbol to the list 00138 * 00139 * Inputs: 00140 * Parameters: 00141 * raw_symb The string as supplied on the command-line. 00142 * Local Static Variables: 00143 * user_symbol_list Pointer to the list of user-defined symbols. 00144 * 00145 * Outputs: 00146 * Returned Value: NONE 00147 * Local Static Variables: 00148 * user_symbol_list Will be updated. 00149 * user_symbol_count Will be incremented 00150 * Memory Allocated: 00151 * for the string(s) and the new entry 00152 * When Freed? 00153 * Never. Well, only on termination of the program. User-defined 00154 * symbols endure for the entire batch of tokenizations. 00155 * 00156 * Process Explanation: 00157 * The string in raw_symb may or may not include the optional 00158 * equal-sign and value pair. If the equal-sign is present, 00159 * the remainder of the string will become the "value" that 00160 * will be returned by the "lookup" routine. 00161 * Memory for the name string and for the value, if there is one, 00162 * will be allocated here, in one step. Memory for the data 00163 * structure itself will be allocated by the support routine. 00164 * 00165 **************************************************************************** */ 00166 00167 void add_user_symbol(char *raw_symb) 00168 { 00169 char *symb_nam; 00170 char *symb_valu; 00171 00172 symb_nam = strdup(raw_symb); 00173 symb_valu = strchr(symb_nam,'='); 00174 if ( symb_valu != NULL ) 00175 { 00176 *symb_valu = 0; 00177 symb_valu++; 00178 } 00179 add_str_sub_entry(symb_nam, symb_valu, &user_symbol_list ); 00180 user_symbol_count++; 00181 } 00182 00183 00184 /* ************************************************************************** 00185 * 00186 * Function name: lookup_user_symbol 00187 * Synopsis: Look for the given name as user-defined symbol, return 00188 * the assigned value. 00189 * 00190 * Inputs: 00191 * Parameters: 00192 * symb_nam The name for which to look. 00193 * Local Static Variables: 00194 * user_symbol_list Pointer to the list of user-defined symbols. 00195 * 00196 * Outputs: 00197 * Returned Value: Pointer to the "value" string, or NULL 00198 * pointer if the name was not found. 00199 * May also be NULL if "value" is NULL. 00200 * 00201 **************************************************************************** */ 00202 00203 char *lookup_user_symbol(char *symb_nam) 00204 { 00205 char *symb_valu; 00206 00207 symb_valu = lookup_str_sub(symb_nam, user_symbol_list ); 00208 return (symb_valu); 00209 } 00210 00211 /* ************************************************************************** 00212 * 00213 * Function name: exists_as_user_symbol 00214 * Synopsis: Confirm whether a given name exists 00215 * as a user-defined symbol. 00216 * 00217 * Inputs: 00218 * Parameters: 00219 * symb_nam The name for which to look. 00220 * Local Static Variables: 00221 * user_symbol_list Pointer to the list of user-defined symbols. 00222 * 00223 * Outputs: 00224 * Returned Value: TRUE if the name is found 00225 * 00226 **************************************************************************** */ 00227 00228 bool exists_as_user_symbol(char *symb_nam) 00229 { 00230 bool retval; 00231 00232 retval = exists_in_str_sub(symb_nam, user_symbol_list ); 00233 return (retval); 00234 } 00235 00236 /* ************************************************************************** 00237 * 00238 * Function name: eval_user_symbol 00239 * Synopsis: Tokenize the value assigned to a user-symbol. 00240 * 00241 * Associated Tokenizer directive (synonyms): [DEFINED] 00242 * #DEFINED 00243 * [#DEFINED] 00244 * 00245 * Syntax Notes: 00246 * (1) The User-Defined-Symbol must appear 00247 * on the same line as the directive. 00248 * (2) This is not (yet) implemented in contexts that 00249 * directly read input from the stream, e.g., 00250 * after ['] or after H# etc. 00251 * 00252 * Inputs: 00253 * Parameters: 00254 * symbol The User-Defined-Symbol to evaluate 00255 * Local Static Variables: 00256 * user_symbol_list Pointer to the list of user-defined symbols. 00257 * 00258 * Outputs: 00259 * Returned Value: NONE 00260 * The assigned value will be tokenized. 00261 * 00262 * Error Detection: 00263 * Calling routine is responsible for verifying that the user-symbol 00264 * is on the same line as the directive. 00265 * WARNING if the symbol is not found or has no assigned value. 00266 * 00267 * Process Explanation: 00268 * Look up the parameter in the User Symbol List, and retrieve 00269 * its associated value. 00270 * If it is not found, or if it has no associated value, issue 00271 * a WARNING and do nothing further. Otherwise... 00272 * Interpret the associated value as though it were source. 00273 * 00274 * Still to be done: 00275 * Hook-in this routine to the processing of: ['] F['] H# FLOAD 00276 * etc., and wherever else it might be needed or useful. 00277 * 00278 **************************************************************************** */ 00279 00280 void eval_user_symbol(char *symbol ) 00281 { 00282 char *symb_valu; 00283 symb_valu = lookup_user_symbol(symbol ); 00284 if ( symb_valu == NULL ) 00285 { 00286 tokenization_error ( WARNING, 00287 "No value assigned to command-line symbol %s\n", symbol ); 00288 }else{ 00289 eval_string( symb_valu ); 00290 } 00291 00292 } 00293 /* ************************************************************************** 00294 * 00295 * Function name: list_user_symbols 00296 * Synopsis: Print the list of user symbols for the Logfile. 00297 * 00298 * Inputs: 00299 * Parameters: NONE 00300 * Local Static Variables: 00301 * user_symbol_list Pointer to the list of user-defined symbols. 00302 * user_symbol_count Count of user-defined symbols. 00303 * 00304 * Outputs: 00305 * Returned Value: NONE 00306 * Printout: List of user symbols and their definitions; 00307 * nothing if user_symbol_list is NULL. 00308 * 00309 * Process Explanation: 00310 * We want to display the symbols in the same order they were created. 00311 * We will: 00312 * Allocate a temporary array of pointers. 00313 * Step backwards through the linked-list of symbols, and 00314 * enter their pointers into the array. 00315 * Collect the maximum length of the symbol names. 00316 * Step through the array in the reverse order, printing 00317 * as we go. 00318 * Use the max name length to space the equal-signs evenly 00319 * Free the temporary array. 00320 * 00321 **************************************************************************** */ 00322 00323 void list_user_symbols(void ) 00324 { 00325 str_sub_vocab_t *curr; 00326 00327 if ( user_symbol_list != NULL ) 00328 { 00329 /* Collect the pointers and max length */ 00330 str_sub_vocab_t **symb_ptr; 00331 int indx = 0; 00332 int maxlen = 0; 00333 00334 symb_ptr = (str_sub_vocab_t **)safe_malloc( 00335 (sizeof(str_sub_vocab_t *) * user_symbol_count), 00336 "collecting user-symbol pointers" ); 00337 00338 for (curr = user_symbol_list ; curr != NULL ; curr=curr->next) 00339 { 00340 symb_ptr[indx] = curr; 00341 indx++; 00342 if ( strlen(curr->name) > maxlen ) maxlen = strlen(curr->name); 00343 } 00344 00345 /* Now print 'em out */ 00346 printf("\nUser-Defined Symbols:\n"); 00347 while ( indx > 0 ) 00348 { 00349 indx--; 00350 curr = symb_ptr[indx]; 00351 printf("\t%s",curr->name); 00352 if ( curr->alias != NULL ) 00353 { 00354 int strindx; 00355 for ( strindx = strlen(curr->name) ; 00356 strindx < maxlen ; strindx++ ) printf(" "); 00357 printf(" = %s",curr->alias); 00358 } 00359 printf("\n"); 00360 } 00361 free(symb_ptr); 00362 } 00363 }