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

strsubvocab.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  *          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 

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