The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

variable.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 1993, 2000 Christopher Seiwald.
00003  *
00004  * This file is part of Jam - see jam.c for Copyright information.
00005  */
00006 
00007 /*  This file is ALSO:
00008  *  (C) Copyright David Abrahams 2001. Permission to copy, use,
00009  *  modify, sell and distribute this software is granted provided this
00010  *  copyright notice appears in all copies. This software is provided
00011  *  "as is" without express or implied warranty, and with no claim as
00012  *  to its suitability for any purpose.
00013  */
00014 
00015 # include "jam.h"
00016 # include "lists.h"
00017 # include "parse.h"
00018 # include "variable.h"
00019 # include "expand.h"
00020 # include "hash.h"
00021 # include "filesys.h"
00022 # include "newstr.h"
00023 # include "strings.h"
00024 # include <stdlib.h>
00025 
00026 /*
00027  * variable.c - handle jam multi-element variables
00028  *
00029  * External routines:
00030  *
00031  *      var_defines() - load a bunch of variable=value settings
00032  *      var_string() - expand a string with variables in it
00033  *      var_get() - get value of a user defined symbol
00034  *      var_set() - set a variable in jam's user defined symbol table
00035  *      var_swap() - swap a variable's value with the given one
00036  *      var_done() - free variable tables
00037  *
00038  * Internal routines:
00039  *
00040  *      var_enter() - make new var symbol table entry, returning var ptr
00041  *      var_dump() - dump a variable to stdout
00042  *
00043  * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
00044  * 08/23/94 (seiwald) - Support for '+=' (append to variable)
00045  * 01/22/95 (seiwald) - split environment variables at blanks or :'s
00046  * 05/10/95 (seiwald) - split path variables at SPLITPATH (not :)
00047  * 09/11/00 (seiwald) - defunct var_list() removed
00048  */
00049 
00050 static struct hash *varhash = 0;
00051 
00052 /*
00053  * VARIABLE - a user defined multi-value variable
00054  */
00055 
00056 typedef struct _variable VARIABLE ;
00057 
00058 struct _variable {
00059         char    *symbol;
00060         LIST    *value;
00061 } ;
00062 
00063 static VARIABLE *var_enter( char *symbol );
00064 static void var_dump( char *symbol, LIST *value, char *what );
00065 
00066 
00067 
00068 /*
00069  * var_hash_swap() - swap all variable settings with those passed
00070  *
00071  * Used to implement separate settings spaces for modules
00072  */
00073 void var_hash_swap( struct hash** new_vars )
00074 {
00075     struct hash* old = varhash;
00076     varhash = *new_vars;
00077     *new_vars = old;
00078 }
00079 
00080 /*
00081  * var_defines() - load a bunch of variable=value settings
00082  *
00083  * If variable name ends in PATH, split value at :'s.  
00084  * Otherwise, split at blanks.
00085  */
00086 
00087 void
00088 var_defines( char **e )
00089 {
00090     string buf[1];
00091 
00092     string_new( buf );
00093 
00094         for( ; *e; e++ )
00095         {
00096             char *val;
00097 
00098             /* Just say "no": windows defines this in the env, */
00099             /* but we don't want it to override our notion of OS. */
00100 
00101             if( !strcmp( *e, "OS=Windows_NT" ) )
00102                 continue;
00103 
00104 # ifdef OS_MAC
00105             /* On the mac (MPW), the var=val is actually var\0val */
00106             /* Think different. */
00107         
00108             if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) )
00109 # else
00110             if( val = strchr( *e, '=' ) )
00111 # endif
00112             {
00113                 LIST *l = L0;
00114                 char *pp, *p;
00115 # ifdef OS_MAC
00116                 char split = ',';
00117 # else
00118                 char split = ' ';
00119 # endif
00120                 size_t len = strlen(val + 1);
00121                 if ( val[1] == '"' && val[len] == '"')
00122                 {
00123                     string_append_range( buf, val + 2, val + len );
00124                     l = list_new( l, newstr( buf->value ) );
00125                     string_truncate( buf, 0 );
00126                 }
00127                 else
00128                 {
00129                     /* Split *PATH at :'s, not spaces */
00130 
00131                     if( val - 4 >= *e )
00132                     {
00133                         if( !strncmp( val - 4, "PATH", 4 ) ||
00134                             !strncmp( val - 4, "Path", 4 ) ||
00135                             !strncmp( val - 4, "path", 4 ) )
00136                             split = SPLITPATH;
00137                     }
00138 
00139                     /* Do the split */
00140 
00141                     for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 )
00142                     {
00143                         string_append_range( buf, pp, p );
00144                         l = list_new( l, newstr( buf->value ) );
00145                         string_truncate( buf, 0 );
00146                     }
00147 
00148                     l = list_new( l, newstr( pp ) );
00149                 }
00150 
00151                 /* Get name */
00152                 string_append_range( buf, *e, val );
00153                 var_set( buf->value, l, VAR_SET );
00154                 string_truncate( buf, 0 );
00155             }
00156         }
00157         string_free( buf );
00158 }
00159 
00160 /*
00161  * var_string() - expand a string with variables in it
00162  *
00163  * Copies in to out; doesn't modify targets & sources.
00164  */
00165 
00166 int
00167 var_string(
00168         char    *in,
00169         char    *out,
00170         int     outsize,
00171         LOL     *lol )
00172 {
00173         char    *out0 = out;
00174         char    *oute = out + outsize - 1;
00175 
00176         while( *in )
00177         {
00178             char        *lastword;
00179             int         dollar = 0;
00180 
00181             /* Copy white space */
00182 
00183             while( isspace( *in ) )
00184             {
00185                 if( out >= oute )
00186                     return -1;
00187 
00188                 *out++ = *in++;
00189             }
00190 
00191             lastword = out;
00192 
00193             /* Copy non-white space, watching for variables */
00194 
00195             while( *in && !isspace( *in ) )
00196             {
00197                 if( out >= oute )
00198                     return -1;
00199 
00200                 if( in[0] == '$' && in[1] == '(' )
00201                     dollar++;
00202 
00203                 *out++ = *in++;
00204             }
00205 
00206         /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */
00207         if (out >= oute)
00208             return -1;
00209         /* Don't increment, intentionally. */
00210         *out= '\0';
00211            
00212             /* If a variable encountered, expand it and and embed the */
00213             /* space-separated members of the list in the output. */
00214 
00215             if( dollar )
00216             {
00217                 LIST    *l;
00218 
00219                 l = var_expand( L0, lastword, out, lol, 0 );
00220 
00221                 out = lastword;
00222 
00223                 for( ; l; l = list_next( l ) )
00224                 {
00225                     int so = strlen( l->string );
00226 
00227                     if( out + so >= oute )
00228                         return -1;
00229 
00230                     strcpy( out, l->string );
00231                     out += so;
00232                     *out++ = ' ';
00233                 }
00234 
00235                 list_free( l );
00236             }
00237         }
00238 
00239         if( out >= oute )
00240             return -1;
00241 
00242         *out++ = '\0';
00243 
00244         return out - out0;
00245 }
00246 
00247 /*
00248  * var_get() - get value of a user defined symbol
00249  *
00250  * Returns NULL if symbol unset.
00251  */
00252 
00253 LIST *
00254 var_get( char *symbol )
00255 {
00256         VARIABLE var, *v = &var;
00257 
00258         v->symbol = symbol;
00259 
00260         if( varhash && hashcheck( varhash, (HASHDATA **)&v ) )
00261         {
00262             if( DEBUG_VARGET )
00263                 var_dump( v->symbol, v->value, "get" );
00264             return v->value;
00265         }
00266     
00267         return 0;
00268 }
00269 
00270 /*
00271  * var_set() - set a variable in jam's user defined symbol table
00272  *
00273  * 'flag' controls the relationship between new and old values of
00274  * the variable: SET replaces the old with the new; APPEND appends
00275  * the new to the old; DEFAULT only uses the new if the variable
00276  * was previously unset.
00277  *
00278  * Copies symbol.  Takes ownership of value.
00279  */
00280 
00281 void
00282 var_set(
00283         char    *symbol,
00284         LIST    *value,
00285         int     flag )
00286 {
00287         VARIABLE *v = var_enter( symbol );
00288 
00289         if( DEBUG_VARSET )
00290             var_dump( symbol, value, "set" );
00291         
00292         switch( flag )
00293         {
00294         case VAR_SET:
00295             /* Replace value */
00296             list_free( v->value );
00297             v->value = value;
00298             break;
00299 
00300         case VAR_APPEND:
00301             /* Append value */
00302             v->value = list_append( v->value, value );
00303             break;
00304 
00305         case VAR_DEFAULT:
00306             /* Set only if unset */
00307             if( !v->value )
00308                 v->value = value;
00309             else
00310                 list_free( value );
00311             break;
00312         }
00313 }
00314 
00315 /*
00316  * var_swap() - swap a variable's value with the given one
00317  */
00318 
00319 LIST *
00320 var_swap(
00321         char    *symbol,
00322         LIST    *value )
00323 {
00324         VARIABLE *v = var_enter( symbol );
00325         LIST     *oldvalue = v->value;
00326 
00327         if( DEBUG_VARSET )
00328             var_dump( symbol, value, "set" );
00329 
00330         v->value = value;
00331 
00332         return oldvalue;
00333 }
00334 
00335 
00336 
00337 /*
00338  * var_enter() - make new var symbol table entry, returning var ptr
00339  */
00340 
00341 static VARIABLE *
00342 var_enter( char *symbol )
00343 {
00344         VARIABLE var, *v = &var;
00345 
00346         if( !varhash )
00347             varhash = hashinit( sizeof( VARIABLE ), "variables" );
00348 
00349         v->symbol = symbol;
00350         v->value = 0;
00351 
00352         if( hashenter( varhash, (HASHDATA **)&v ) )
00353             v->symbol = newstr( symbol );       /* never freed */
00354 
00355         return v;
00356 }
00357 
00358 /*
00359  * var_dump() - dump a variable to stdout
00360  */
00361 
00362 static void
00363 var_dump(
00364         char    *symbol,
00365         LIST    *value,
00366         char    *what )
00367 {
00368         printf( "%s %s = ", what, symbol );
00369         list_print( value );
00370         printf( "\n" );
00371 }
00372 
00373 /*
00374  * var_done() - free variable tables
00375  */
00376 static void delete_var_( void* xvar, void* data )
00377 {
00378     VARIABLE *v = (VARIABLE*)xvar;
00379     freestr( v->symbol );
00380     list_free( v-> value );
00381 }
00382 
00383 void
00384 var_done()
00385 {
00386     hashenumerate( varhash, delete_var_, (void*)0 );
00387         hashdone( varhash );
00388 }

Generated on Mon Nov 8 17:07:52 2004 for MPT by  doxygen 1.3.9.1