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 /* ************************************************************************** cand_destructor(void * arg)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 are 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 * exists_as_user_symbol Confirm whether a given name exists 69 * as a user-defined symbol. 70 * eval_user_symbol Evaluate the value assigned to a user 71 * symbol. 72 * list_user_symbols Print the list of user-defined symbols 73 * for the Logfile. 74 * 75 **************************************************************************** */ 76 77 /* ************************************************************************** 78 * 79 * Still to be done: 80 * Convert the handling of user-defined symbols to the T.I.C. 81 * data-structure and its support routines. This should 82 * eliminate any further need of String-Substitution-type 83 * vocabularies. User-defined symbols will, however, still 84 * need to be a separate vocabulary from the Global, because 85 * they are required to stay in effect for the duration of 86 * the entire batch of tokenizations... 87 * (Afterthought: This is only true for user-defined symbols that 88 * were created on the command-line; if we ever allow symbols 89 * to be defined in the Source file, they should be as volatile 90 * as anything else that comes from a source file... 91 * Appending source-file-derived user-defined symbols to the Global 92 * Vocabulary could be a quasi-simple way to accomplish this.) 93 * 94 * Enable the definition of user-symbols from the Source file, using 95 * a syntax like: [define] symbol or [define] symbol=<value> 96 * (How to allow spaces into the <value>? Maybe make the syntax 97 * [define] symbol = <value components to end of line> 98 * delimited in a manner similar to Macro definitions. 99 * There might be a need to be able to [undefine] a user-symbol 100 * that would entail defining an unlink_tic_entry function. 101 * Not difficult; just keeping this around as a reminder... 102 * 103 **************************************************************************** */ 104 105 106 107 #include <stdio.h> 108 #include <stdlib.h> 109 #if defined(__linux__) && ! defined(__USE_BSD) 110 #define __USE_BSD 111 #endif 112 #include <string.h> 113 114 #include "errhandler.h" 115 #include "strsubvocab.h" 116 #include "usersymbols.h" 117 #include "scanner.h" 118 119 120 /* ************************************************************************** 121 * 122 * Internal Static Variables 123 * user_symbol_list Pointer to the "tail" of the list of 124 * user-defined symbols. 125 * user_symbol_count Count of how many are defined 126 * 127 **************************************************************************** */ 128 129 static str_sub_vocab_t *user_symbol_list = NULL; 130 static int user_symbol_count = 0; 131 132 /* ************************************************************************** 133 * 134 * Function name: add_user_symbol 135 * Synopsis: Add a user-defined symbol to the list 136 * 137 * Inputs: 138 * Parameters: icem_rcand_add(struct icem * icem,enum ice_cand_type type,unsigned compid,uint32_t prio,const struct sa * addr,const struct sa * rel_addr,const struct pl * foundation)139 * raw_symb The string as supplied on the command-line. 140 * Local Static Variables: 141 * user_symbol_list Pointer to the list of user-defined symbols. 142 * 143 * Outputs: 144 * Returned Value: NONE 145 * Local Static Variables: 146 * user_symbol_list Will be updated. 147 * user_symbol_count Will be incremented 148 * Memory Allocated: 149 * for the string(s) and the new entry 150 * When Freed? 151 * Never. Well, upon termination of the program. User-defined 152 * symbols endure for the entire batch of tokenizations. 153 * 154 * Process Explanation: 155 * The string in raw_symb may or may not include the optional 156 * equal-sign and value pair. If the equal-sign is present, 157 * the remainder of the string will become the "value" that 158 * will be returned by the "lookup" routine. 159 * Memory for the name string and for the value, if there is one, 160 * will be allocated here, in one step. Memory for the data 161 * structure itself will be allocated by the support routine. 162 * 163 **************************************************************************** */ 164 165 void add_user_symbol(char *raw_symb) 166 { 167 char *symb_nam; 168 char *symb_valu; 169 170 symb_nam = strdup(raw_symb); 171 symb_valu = strchr(symb_nam,'='); 172 if ( symb_valu != NULL ) 173 { 174 *symb_valu = 0; 175 symb_valu++; 176 } 177 add_str_sub_entry(symb_nam, symb_valu, &user_symbol_list ); 178 user_symbol_count++; 179 } 180 181 182 /* ************************************************************************** 183 * 184 * Function name: exists_as_user_symbol 185 * Synopsis: Confirm whether a given name exists 186 * as a user-defined symbol. 187 * 188 * Inputs: 189 * Parameters: 190 * symb_nam The name for which to look. 191 * Local Static Variables: 192 * user_symbol_list Pointer to the list of user-defined symbols. 193 * 194 * Outputs: 195 * Returned Value: TRUE if the name is found 196 * 197 **************************************************************************** */ 198 199 bool exists_as_user_symbol(char *symb_nam) 200 { 201 bool retval; 202 203 retval = exists_in_str_sub(symb_nam, user_symbol_list ); 204 return (retval); 205 } 206 207 /* ************************************************************************** 208 * 209 * Function name: eval_user_symbol icem_cand_find(const struct list * lst,unsigned compid,const struct sa * addr)210 * Synopsis: Evaluate the value assigned to a user-symbol. 211 * 212 * Associated Tokenizer directive (synonyms): [DEFINED] 213 * #DEFINED 214 * [#DEFINED] 215 * 216 * Syntax Notes: 217 * (1) The User-Defined-Symbol must appear 218 * on the same line as the directive. 219 * (2) This is not (yet) implemented in contexts that 220 * directly read input from the stream, e.g., 221 * after ['] or after H# etc. 222 * 223 * Inputs: 224 * Parameters: 225 * symb_nam Name of the User-Defined-Symbol to evaluate 226 * Local Static Variables: 227 * user_symbol_list Pointer to the list of user-defined symbols. 228 * 229 * Outputs: 230 * Returned Value: NONE 231 * The assigned value will be tokenized. 232 * 233 * Error Detection: 234 * Calling routine is responsible for verifying that the user-symbol 235 * is on the same line as the directive. 236 * ERROR if the symbol is not found 237 * WARNING if the symbol has no assigned value. 238 * 239 * Process Explanation: 240 * Look up the parameter in the User Symbol List, 241 * If it is not found, issue an ERROR and do nothing further. 242 * If it is found, attempt to retrieve its associated value 243 * If it has no associated value, issue a WARNING and 244 * do nothing further. Otherwise... 245 * Interpret the associated value as though it were source. 246 * 247 * Still to be done: 248 * Hook-in this routine to the processing of: ['] F['] H# FLOAD 249 * etc., and wherever else it might be needed or useful. 250 * 251 **************************************************************************** */ 252 253 void eval_user_symbol( char *symb_nam) 254 { 255 str_sub_vocab_t *found = NULL; 256 257 258 found = lookup_str_sub( symb_nam, user_symbol_list ); 259 if ( found == NULL ) 260 { 261 tokenization_error ( TKERROR, 262 "Command-line symbol %s is not defined.\n", symb_nam); 263 }else{ 264 char *symb_valu = found->alias; 265 266 if ( symb_valu == NULL ) 267 { 268 tokenization_error ( WARNING, 269 "No value assigned to command-line symbol %s\n", symb_nam ); 270 }else{ 271 eval_string( symb_valu ); 272 } 273 } 274 275 } 276 /* ************************************************************************** 277 * icem_cands_debug(struct re_printf * pf,const struct list * lst)278 * Function name: list_user_symbols 279 * Synopsis: Print the list of user symbols for the Logfile. 280 * 281 * Inputs: 282 * Parameters: NONE 283 * Local Static Variables: 284 * user_symbol_list Pointer to the list of user-defined symbols. 285 * user_symbol_count Count of user-defined symbols. 286 * 287 * Outputs: 288 * Returned Value: NONE 289 * Printout: List of user symbols and their definitions; 290 * nothing if user_symbol_list is NULL. 291 * 292 * Process Explanation: 293 * We want to display the symbols in the same order they were created. 294 * We will: 295 * Allocate a temporary array of pointers. 296 * Step backwards through the linked-list of symbols, and 297 * enter their pointers into the array. The array order 298 * reflects the backward-linked order of the linked-list 299 * of symbols is kept and searched, 300 * Collect the maximum length of the symbol names. 301 * Step through the array in the reverse order, to follow the 302 * order in which the symbols were defined. 303 * Check for a duplicate of the current symbol name: 304 * Look backwards through the array, at the names we 305 * have not yet printed, which were defined later. 306 * Since the later-defined value will prevail, the 307 * notation should be on the earlier one. 308 * Print the current name 309 * Use the maximum name-length to space the equal-signs or 310 * duplicate-name notation, as required, evenly. 311 * Free the temporary array. 312 * 313 * Revision History: 314 * Updated Thu, 07 Sep 2006 by David L. Paktor 315 * Report duplicated symbol names. 316 * 317 * Still to be done: 318 * Space the duplicate-name notation evenly; line it up past 319 * the longest name-with-value. 320 * 321 **************************************************************************** */ 322 323 void list_user_symbols(void ) 324 { 325 str_sub_vocab_t *curr; 326 327 if ( user_symbol_list != NULL ) 328 { 329 /* Collect the pointers and max length */ 330 str_sub_vocab_t **symb_ptr; 331 int indx = 0; 332 int maxlen = 0; 333 334 symb_ptr = (str_sub_vocab_t **)safe_malloc( 335 (sizeof(str_sub_vocab_t *) * user_symbol_count), 336 "collecting user-symbol pointers" ); 337 338 for (curr = user_symbol_list ; curr != NULL ; curr=curr->next) 339 { 340 symb_ptr[indx] = curr; 341 indx++; 342 if ( strlen(curr->name) > maxlen ) maxlen = strlen(curr->name); 343 } 344 345 /* Now print 'em out */ 346 printf("\nUser-Defined Symbols:\n"); 347 while ( indx > 0 ) 348 { 349 bool is_dup; 350 int dup_srch_indx; 351 indx--; 352 curr = symb_ptr[indx]; 353 354 /* Detect duplicate names. */ 355 dup_srch_indx = indx; 356 is_dup = FALSE; 357 while ( dup_srch_indx > 0 ) 358 { 359 str_sub_vocab_t *dup_cand; 360 dup_srch_indx--; 361 dup_cand = symb_ptr[dup_srch_indx]; 362 if ( strcmp( curr->name, dup_cand->name) == 0 ) 363 { 364 is_dup = TRUE; 365 break; 366 } 367 } 368 369 printf("\t%s",curr->name); 370 371 if ( ( curr->alias != NULL ) || is_dup ) 372 { 373 int strindx; 374 for ( strindx = strlen(curr->name) ; 375 strindx < maxlen ; 376 strindx++ ) 377 { 378 printf(" "); 379 } 380 } 381 if ( curr->alias != NULL ) 382 { 383 printf(" = %s",curr->alias); 384 } 385 if ( is_dup ) 386 { 387 printf(" *** Over-ridden" ); 388 } 389 printf("\n"); 390 } 391 free(symb_ptr); 392 } 393 } 394