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

ticvocab.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  *      Threaded Interpretive Code (T. I. C.)-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  *      We are going to implement a strategy that takes better advantage
00038  *          of the concept of Threaded Interpretive Code  (well, okay,
00039  *          it won't really be interpretive ... )  We will use it to
00040  *          implement a small (but expandable) subset of FORTH-like
00041  *          commands in Tokenizer-Escape mode, as well as a few other
00042  *          things, such as conditional-tokenization.
00043  *
00044  *      The Threaded Interpretive Code Header data structure is described
00045  *          in detail in the accompanying  ticvocab.h  header-file.
00046  *
00047  *      In most cases, the contents of a beginning portion of the vocabulary
00048  *          are known at compile-time, and later parts are added by the
00049  *          user at run-time.  (The linked-list structure is needed to allow
00050  *          for that.)  We can initialize the known start of the vocabulary
00051  *          easily, except for the link-pointers, as an array.
00052  *      We can either explicitly state an index for each entry's link-pointer
00053  *          to the previous entry (which can become a problem to maintain) or
00054  *          have a function to initialize the links dynamically, at run-time.
00055  *      I think I will (regretfully, resignedly) choose the latter.
00056  *          
00057  *      We will define a few general-purpose functions for dealing with
00058  *          T. I. C. -type vocabularies.  Eventually, it might be a good
00059  *          idea to convert all the vocabularies to this structure...
00060  *
00061  **************************************************************************** */
00062 
00063 /* **************************************************************************
00064  *
00065  *
00066  *      Revision History:
00067  *          Mon, 19 Dec 2005 by David L. Paktor
00068  *          Begin converting most, if not all, of the vocabularies to
00069  *              T. I. C. -type structure.
00070  *
00071  **************************************************************************** */
00072 
00073 
00074 /* **************************************************************************
00075  *
00076  *      Functions Exported:
00077  *          init_tic_vocab        Initialize a TIC_HDR -type vocabulary
00078  *          add_tic_entry         Add an entry to a TIC_HDR -type vocabulary
00079  *          lookup_tic_entry      Look for a name in a TIC_HDR -type vocabulary
00080  *          handle_tic_vocab      Perform a function in a TIC_HDR -type vocab
00081  *          exists_in_tic_vocab   Confirm whether a given name exists in a
00082  *                                    TIC_HDR -type vocabulary
00083  *          create_tic_alias      Duplicate the behavior of one name with
00084  *                                     another name.  Return a "success" flag.
00085  *          reset_tic_vocab       Reset a given TIC_HDR -type vocabulary to
00086  *                                    its "Built-In" position.
00087  *
00088  **************************************************************************** */
00089 
00090 
00091 /* **************************************************************************
00092  *
00093  *          Global Variables Exported
00094  *              tic_found       The entry, in a TIC_HDR -type vocabulary,
00095  *                                  that has just been found and is being 
00096  *                                  "handled".  Needed for protection against
00097  *                                  recursion in a User-defined Macro (which
00098  *                                  should occur only rarely).
00099  *
00100  **************************************************************************** */
00101 
00102 
00103 #include <stdlib.h>
00104 #include <string.h>
00105 #include "ticvocab.h"
00106 #include "errhandler.h"
00107 
00108 tic_hdr_t *tic_found;
00109 
00110 /* **************************************************************************
00111  *
00112  *      Function name:  init_tic_vocab
00113  *      Synopsis:       Dynamically initialize the link-pointers
00114  *                          of the.given TIC_HDR -type vocabulary
00115  *
00116  *      Inputs:
00117  *         Parameters:
00118  *             tic_vocab_tbl       Pointer to the initial TIC_HDR vocab array
00119  *             max_indx            Maximum Index of the initial array.
00120  *             tic_vocab_ptr       Pointer to the vocab "tail"
00121  *
00122  *      Outputs:
00123  *         Returned Value:         None
00124  *         Global Variables:
00125  *              The link-fields of the initial TIC_HDR vocab array entries
00126  *                  will be filled in.
00127  *         Supplied Pointers:
00128  *             *tic_vocab_ptr       Points to the last element in the array
00129  *
00130  *      Process Explanation:
00131  *          The value that  tic_vocab_ptr  has upon entry to the routine
00132  *              (which may point to the end of another array which is to
00133  *              precede this one in the voacbulary) gets entered into
00134  *              the link-pointer field of the first element of the array.
00135  *          For this reason, it is important that all TIC_HDR vocabulary
00136  *              pointers that will be pased to this routine have their
00137  *              initial values explicitly declared NULL. 
00138  *
00139  **************************************************************************** */
00140 
00141 void init_tic_vocab( tic_hdr_t *tic_vocab_tbl,
00142                          int max_indx,
00143                              tic_hdr_t **tic_vocab_ptr)
00144 {
00145     int indx;
00146     for ( indx = 0 ; indx < max_indx ; indx++ )
00147     {
00148         tic_vocab_tbl[indx].next = *tic_vocab_ptr;
00149         *tic_vocab_ptr = &tic_vocab_tbl[indx];
00150     }
00151 }
00152 
00153 
00154 /* **************************************************************************
00155  *
00156  *      Function name:  add_tic_entry
00157  *      Synopsis:       Add an entry to the given TIC_HDR -type vocabulary
00158  *
00159  *      Inputs:
00160  *         Parameters:
00161  *             tname         Pointer to space containing the name of the entry
00162  *             tfunct        Pointer to the routine the new entry will call
00163  *             tparam        The "parameter field" value (may be a pointer)
00164  *             fw_defr       FWord Token of the entry's Definer
00165  *             pfldsiz       Size of "param field" (if a pointer to alloc'd mem)
00166  *             ign_fnc       Pointer to "ignoring" routine for new entry
00167  *             tic_vocab     Pointer to ptr to "tail" of T.I.C.-type vocab-list 
00168  *
00169  *      Outputs:
00170  *         Returned Value:          NONE
00171  *         Supplied Pointers:
00172  *             *tic_vocab           Will point to new entry
00173  *         Memory Allocated:
00174  *             For the new entry.
00175  *         When Freed?
00176  *             When reset_tic_vocab() is applied to the same vocab-list.
00177  *
00178  *      Error Detection:
00179  *          Failure to allocate memory is a Fatal Error.
00180  *
00181  *      Process Explanation:
00182  *          The name pointer is presumed to already point to a stable,
00183  *              newly-allocated memory-space.  If the parameter field is
00184  *              actually a pointer, it, too, is presumed to already have
00185  *              been allocated.
00186  *          Memory will be allocated for the entry itself; its pointers
00187  *              will be entered and the given pointer-to-the-tail-of-the-
00188  *              -vocabulary will be updated to point to the new entry.
00189  *
00190  **************************************************************************** */
00191 
00192 void add_tic_entry( char *tname,
00193                         void (*tfunct)(),
00194                              TIC_P_DEFLT_TYPE tparam,
00195                                  fwtoken fw_defr,
00196                                      int pfldsiz,
00197                                          void (*ign_fnc)(),
00198                                              tic_hdr_t **tic_vocab )
00199 {
00200     tic_hdr_t *new_entry;
00201 
00202     new_entry = safe_malloc(sizeof(tic_hdr_t), "adding tic_entry");
00203     new_entry->name              =  tname;
00204     new_entry->next              = *tic_vocab;
00205     new_entry->funct             =  tfunct;
00206     new_entry->pfield.deflt_elem =  tparam;
00207     new_entry->fword_defr        =  fw_defr;
00208     new_entry->ign_func          =  ign_fnc;
00209     new_entry->pfld_size         =  pfldsiz;
00210 
00211     *tic_vocab = new_entry;
00212 
00213 }
00214 
00215 /* **************************************************************************
00216  *
00217  *      Function name:  lookup_tic_entry
00218  *      Synopsis:       Look for a name in the given TIC_HDR -type vocabulary
00219  *
00220  *      Inputs:
00221  *         Parameters:
00222  *             tname                The "target" name for which to look
00223  *             tic_vocab            Pointer to the T. I. C. -type vocabulary
00224  *
00225  *      Outputs:
00226  *         Returned Value:          Pointer to the relevant entry, or
00227  *                                      NULL if name not found.
00228  *
00229  *      Extraneous Remarks:
00230  *          We don't set the global  tic_found  here because this routine
00231  *              is not always called when the found function is going to
00232  *              be executed; sometimes it is called for error-detection,
00233  *              for instance...
00234  *
00235  **************************************************************************** */
00236  
00237 tic_hdr_t *lookup_tic_entry( char *tname, tic_hdr_t *tic_vocab )
00238 {
00239     tic_hdr_t *curr ;
00240 
00241     for (curr = tic_vocab ; curr != NULL ; curr=curr->next)
00242     {
00243         if ( strcasecmp(tname, curr->name) == 0 )
00244         {
00245             break;
00246         }
00247     }
00248 
00249     return ( curr ) ;
00250 }
00251 
00252 /* **************************************************************************
00253  *
00254  *      Function name:  exists_in_tic_vocab
00255  *      Synopsis:       Confirm whether the given name exists in the
00256  *                      given TIC_HDR -type vocabulary
00257  *
00258  *      Inputs:
00259  *         Parameters:
00260  *             tname                The name for which to look
00261  *             tic_vocab            Pointer to the T. I. C. -type vocabulary
00262  *
00263  *      Outputs:
00264  *         Returned Value:          TRUE if name is found,
00265  *
00266  **************************************************************************** */
00267 
00268 bool exists_in_tic_vocab( char *tname, tic_hdr_t *tic_vocab )
00269 {
00270     tic_hdr_t *found ;
00271     bool retval = FALSE;
00272 
00273     found = lookup_tic_entry( tname, tic_vocab );
00274     if ( found != NULL )
00275     {
00276         retval = TRUE;
00277     }
00278 
00279     return ( retval );
00280 }
00281 
00282 
00283 /* **************************************************************************
00284  *
00285  *      Function name:  create_tic_alias
00286  *      Synopsis:       Create an Alias in a TIC_HDR -type vocabulary
00287  *                          Return a "success" flag.
00288  *
00289  *      Associated FORTH word:                 ALIAS
00290  *
00291  *      Inputs:
00292  *         Parameters:
00293  *             old_name             Name of existing entry
00294  *             new_name             New name for which to create an entry
00295  *             *tic_vocab           Pointer to the "tail" of the
00296  *                                      T. I. C. -type vocab-list 
00297  *
00298  *      Outputs:
00299  *         Returned Value:          TRUE if  old_name  found in given vocab
00300  *         Supplied Pointers:
00301  *             *tic_vocab           Will be updated to point to the new entry
00302  *         Memory Allocated:
00303  *             For the new entry, by the support routine.
00304  *         When Freed?
00305  *             When reset_tic_vocab() is applied to the same vocab-list.
00306  *
00307  *      Process Explanation:
00308  *          Both the "old" and "new" names are presumed to already point to
00309  *              stable, freshly allocated memory-spaces.
00310  *          Even if the "old" entry's  pfld_size  is not zero, meaning its
00311  *              param-field is a pointer to allocated memory, we still do
00312  *              not need to copy it into a freshly allocated memory-space,
00313  *              as long as we make the new alias-entry's  pfld_size  zero:
00314  *              the reference to the old space will work, and the old
00315  *              entry's param-field memory space will not be freed with
00316  *              the alias-entry but only with the "old" entry.
00317  *
00318  **************************************************************************** */
00319 
00320 bool create_tic_alias( char *new_name, char *old_name, tic_hdr_t **tic_vocab )
00321 {
00322     tic_hdr_t *found ;
00323     bool retval = FALSE;
00324 
00325     found = lookup_tic_entry( old_name, *tic_vocab );
00326     if ( found != NULL )
00327     {
00328         add_tic_entry( new_name, found->funct,
00329                            found->pfield.deflt_elem,
00330                                found->fword_defr,
00331                                    0, found->ign_func, tic_vocab );
00332         retval = TRUE;
00333     }
00334 
00335     return ( retval );
00336 }
00337 
00338 
00339 /* **************************************************************************
00340  *
00341  *      Function name:  handle_tic_vocab
00342  *      Synopsis:       Perform the function associated with the given name
00343  *                      in the given TIC_HDR -type vocabulary
00344  *
00345  *      Inputs:
00346  *         Parameters:
00347  *             tname                The "target" name for which to look
00348  *             tic_vocab            Pointer to the T. I. C. -type vocabulary
00349  *
00350  *      Outputs:
00351  *         Returned Value:   TRUE if the given name is valid in the given vocab
00352  *         Global Variables:
00353  *             tic_found            Points to the TIC entry of the "target"
00354  *                                      name, if it was found; else, NULL.
00355  *         Global Behavior:
00356  *             Whatever the associated function does...
00357  *
00358  *      Process Explanation:
00359  *          Find the name and execute its associated function.
00360  *          If the name is not in the given vocabulary, return
00361  *              an indication; leave it to the calling routine
00362  *              to decide how to proceed.
00363  *
00364  **************************************************************************** */
00365  
00366 bool handle_tic_vocab( char *tname, tic_hdr_t *tic_vocab )
00367 {
00368     bool retval = FALSE;
00369     
00370     tic_found = lookup_tic_entry( tname, tic_vocab );
00371     if ( tic_found != NULL )
00372     {
00373         tic_found->funct( tic_found->pfield);
00374         retval = TRUE;
00375     }
00376 
00377     return ( retval ) ;
00378 }
00379 
00380 /* **************************************************************************
00381  *
00382  *      Function name:  reset_tic_vocab
00383  *      Synopsis:       Reset a given TIC_HDR -type vocabulary to
00384  *                          its given "Built-In" position.
00385  *
00386  *      Inputs:
00387  *         Parameters:
00388  *             *tic_vocab            Pointer to the T. I. C.-type vocab-list
00389  *             reset_position        Position to which to reset the list
00390  *
00391  *      Outputs:
00392  *         Returned Value:         NONE
00393  *         Supplied Pointers:
00394  *             *tic_vocab          Reset to given "Built-In" position.
00395  *         Memory Freed
00396  *             All memory allocated by user-definitions will be freed
00397  *
00398  *      Process Explanation:
00399  *          The "stable memory-spaces" to which the name and parameter
00400  *              field pointers point are presumed to have been acquired
00401  *              by allocation of memory, which is reasonable for entries
00402  *              created by the user as opposed to the built-in entries,
00403  *              which we are, in any case, not releasing.
00404  *          The parameter-field size field tells us whether we need to
00405  *              free()  the parameter-field pointer.
00406  *
00407  **************************************************************************** */
00408 
00409 void reset_tic_vocab( tic_hdr_t **tic_vocab, tic_hdr_t *reset_position )
00410 {
00411     tic_hdr_t *next_t;
00412 
00413     next_t = *tic_vocab;
00414     while ( next_t != reset_position  )
00415     {
00416         next_t = (*tic_vocab)->next ;
00417 
00418         free( (*tic_vocab)->name );
00419         if ( (*tic_vocab)->pfld_size != 0 )
00420         {
00421             free( (*tic_vocab)->pfield.chr_ptr );
00422         }
00423         free( *tic_vocab );
00424         *tic_vocab = next_t ;
00425     }
00426 }

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