Main Page | Data Structures | File List | Data Fields | Globals

usersymbols.c

Go to the documentation of this file.
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 }

Generated on Fri Aug 18 14:03:39 2006 for Toke1.0 by  doxygen 1.4.4