version 1.34, 2000/06/23 16:18:09 |
version 1.35, 2000/06/23 16:20:01 |
|
|
#include <regex.h> |
#include <regex.h> |
#endif |
#endif |
#include <stdlib.h> |
#include <stdlib.h> |
|
#include <stddef.h> |
#include "make.h" |
#include "make.h" |
#include "buf.h" |
#include "buf.h" |
|
|
|
|
char *val; |
char *val; |
GNode *gn; |
GNode *gn; |
{ |
{ |
Var_Set(varnames[idx], val, gn); |
Var_Set(varnames[idx], val, &gn->context); |
} |
} |
|
|
void |
void |
|
|
char *val; |
char *val; |
GNode *gn; |
GNode *gn; |
{ |
{ |
Var_Append(varnames[idx], val, gn); |
Var_Append(varnames[idx], val, &gn->context); |
} |
} |
|
|
char * |
char * |
|
|
int idx; |
int idx; |
GNode *gn; |
GNode *gn; |
{ |
{ |
return Var_Value(varnames[idx], gn); |
return Var_Value(varnames[idx], &gn->context); |
} |
} |
|
|
Boolean |
Boolean |
|
|
int idx; |
int idx; |
GNode *gn; |
GNode *gn; |
{ |
{ |
return Var_Exists(varnames[idx], gn); |
return Var_Exists(varnames[idx], &gn->context); |
} |
} |
|
|
/* |
/* |
|
|
* The four contexts are searched in the reverse order from which they are |
* The four contexts are searched in the reverse order from which they are |
* listed. |
* listed. |
*/ |
*/ |
GNode *VAR_GLOBAL; /* variables from the makefile */ |
SymTable *VAR_GLOBAL; /* variables from the makefile */ |
GNode *VAR_CMD; /* variables defined on the command-line */ |
SymTable *VAR_CMD; /* variables defined on the command-line */ |
static GNode *VAR_ENV; /* variables read from env */ |
static SymTable *VAR_ENV; /* variables read from env */ |
|
|
static LIST allVars; /* List of all variables */ |
static LIST allVars; /* List of all variables */ |
|
|
|
|
|
|
#define VarValue(v) Buf_Retrieve(&((v)->val)) |
#define VarValue(v) Buf_Retrieve(&((v)->val)) |
static int VarCmp __P((void *, void *)); |
static int VarCmp __P((void *, void *)); |
static Var *VarFind __P((char *, GNode *, int)); |
static Var *VarFind __P((char *, SymTable *, int)); |
static Var *VarAdd __P((char *, char *, GNode *)); |
static Var *VarAdd __P((char *, char *, SymTable *)); |
static void VarDelete __P((void *)); |
static void VarDelete __P((void *)); |
static Boolean VarHead __P((char *, Boolean, Buffer, void *)); |
static Boolean VarHead __P((char *, Boolean, Buffer, void *)); |
static Boolean VarTail __P((char *, Boolean, Buffer, void *)); |
static Boolean VarTail __P((char *, Boolean, Buffer, void *)); |
|
|
static Boolean VarRESubstitute __P((char *, Boolean, Buffer, void *)); |
static Boolean VarRESubstitute __P((char *, Boolean, Buffer, void *)); |
#endif |
#endif |
static Boolean VarSubstitute __P((char *, Boolean, Buffer, void *)); |
static Boolean VarSubstitute __P((char *, Boolean, Buffer, void *)); |
static char *VarGetPattern __P((GNode *, int, char **, int, int *, size_t *, |
static char *VarGetPattern __P((SymTable *, int, char **, int, int *, size_t *, |
VarPattern *)); |
VarPattern *)); |
static char *VarQuote __P((char *)); |
static char *VarQuote __P((char *)); |
static char *VarModify __P((char *, Boolean (*)(char *, Boolean, Buffer, void *), void *)); |
static char *VarModify __P((char *, Boolean (*)(char *, Boolean, Buffer, void *), void *)); |
static void VarPrintVar __P((void *)); |
static void VarPrintVar __P((void *)); |
static Boolean VarUppercase __P((char *word, Boolean addSpace, Buffer buf, void *dummy)); |
static Boolean VarUppercase __P((char *word, Boolean addSpace, Buffer buf, void *dummy)); |
static Boolean VarLowercase __P((char *word, Boolean addSpace, Buffer buf, void *dummy)); |
static Boolean VarLowercase __P((char *word, Boolean addSpace, Buffer buf, void *dummy)); |
|
static char *context_name __P((SymTable *)); |
|
|
|
|
|
static char * |
|
context_name(ctxt) |
|
SymTable *ctxt; |
|
{ |
|
GNode *g; |
|
|
|
/* specific handling for GLOBAL, CMD, ENV contexts, which are not |
|
owned by a GNode */ |
|
if (ctxt == VAR_GLOBAL) |
|
return "Global"; |
|
if (ctxt == VAR_CMD) |
|
return "Command"; |
|
if (ctxt == VAR_ENV) |
|
return "Environment"; |
|
g = (GNode *)((char *)ctxt - offsetof(GNode, context)); |
|
return g->name; |
|
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* VarCmp -- |
* VarCmp -- |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Var * |
static Var * |
VarFind (name, ctxt, flags) |
VarFind(name, ctxt, flags) |
char *name; /* name to find */ |
char *name; /* name to find */ |
GNode *ctxt; /* context in which to find it */ |
SymTable *ctxt; /* context in which to find it */ |
int flags; /* FIND_GLOBAL set means to look in the |
int flags; /* FIND_GLOBAL set means to look in the |
* VAR_GLOBAL context as well. |
* VAR_GLOBAL context as well. |
* FIND_CMD set means to look in the VAR_CMD |
* FIND_CMD set means to look in the VAR_CMD |
|
|
* look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order, |
* look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order, |
* depending on the FIND_* flags in 'flags' |
* depending on the FIND_* flags in 'flags' |
*/ |
*/ |
var = Lst_Find(&ctxt->context, VarCmp, name); |
var = Lst_Find(ctxt, VarCmp, name); |
|
|
if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) |
if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) |
var = Lst_Find(&VAR_CMD->context, VarCmp, name); |
var = Lst_Find(VAR_CMD, VarCmp, name); |
if (!checkEnvFirst && (var == NULL) && (flags & FIND_GLOBAL) && |
if (!checkEnvFirst && (var == NULL) && (flags & FIND_GLOBAL) && |
(ctxt != VAR_GLOBAL)) { |
(ctxt != VAR_GLOBAL)) { |
var = Lst_Find(&VAR_GLOBAL->context, VarCmp, name); |
var = Lst_Find(VAR_GLOBAL, VarCmp, name); |
} |
} |
if ((var == NULL) && (flags & FIND_ENV)) { |
if ((var == NULL) && (flags & FIND_ENV)) { |
var = Lst_Find(&VAR_ENV->context, VarCmp, name); |
var = Lst_Find(VAR_ENV, VarCmp, name); |
if (var == NULL) { |
if (var == NULL) { |
char *env; |
char *env; |
|
|
|
|
} |
} |
if (var == NULL && checkEnvFirst && (flags & FIND_GLOBAL) && |
if (var == NULL && checkEnvFirst && (flags & FIND_GLOBAL) && |
(ctxt != VAR_GLOBAL)) |
(ctxt != VAR_GLOBAL)) |
var = Lst_Find(&VAR_GLOBAL->context, VarCmp, name); |
var = Lst_Find(VAR_GLOBAL, VarCmp, name); |
if (var == NULL) |
if (var == NULL) |
return NULL; |
return NULL; |
else |
else |
|
|
VarAdd(name, val, ctxt) |
VarAdd(name, val, ctxt) |
char *name; /* name of variable to add */ |
char *name; /* name of variable to add */ |
char *val; /* value to set it to */ |
char *val; /* value to set it to */ |
GNode *ctxt; /* context in which to set it */ |
SymTable *ctxt; /* context in which to set it */ |
{ |
{ |
register Var *v; |
register Var *v; |
int len; |
int len; |
|
|
v = (Var *) emalloc (sizeof (Var)); |
v = (Var *) emalloc(sizeof(Var)); |
|
|
v->name = estrdup (name); |
v->name = estrdup(name); |
|
|
len = val ? strlen(val) : 0; |
len = val ? strlen(val) : 0; |
Buf_Init(&(v->val), len+1); |
Buf_Init(&(v->val), len+1); |
|
|
|
|
v->flags = 0; |
v->flags = 0; |
|
|
Lst_AtFront(&ctxt->context, v); |
Lst_AtFront(ctxt, v); |
Lst_AtEnd(&allVars, v); |
Lst_AtEnd(&allVars, v); |
if (DEBUG(VAR)) { |
if (DEBUG(VAR)) { |
printf("%s:%s = %s\n", ctxt->name, name, val); |
printf("%s:%s = %s\n", context_name(ctxt), name, val); |
} |
} |
return v; |
return v; |
} |
} |
|
|
void |
void |
Var_Delete(name, ctxt) |
Var_Delete(name, ctxt) |
char *name; |
char *name; |
GNode *ctxt; |
SymTable *ctxt; |
{ |
{ |
LstNode ln; |
LstNode ln; |
|
|
if (DEBUG(VAR)) { |
if (DEBUG(VAR)) { |
printf("%s:delete %s\n", ctxt->name, name); |
printf("%s:delete %s\n", context_name(ctxt), name); |
} |
} |
ln = Lst_Find(&ctxt->context, VarCmp, name); |
ln = Lst_Find(ctxt, VarCmp, name); |
if (ln != NULL) { |
if (ln != NULL) { |
register Var *v; |
register Var *v; |
|
|
v = (Var *)Lst_Datum(ln); |
v = (Var *)Lst_Datum(ln); |
Lst_Remove(&ctxt->context, ln); |
Lst_Remove(ctxt, ln); |
ln = Lst_Member(&allVars, v); |
ln = Lst_Member(&allVars, v); |
Lst_Remove(&allVars, ln); |
Lst_Remove(&allVars, ln); |
VarDelete(v); |
VarDelete(v); |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Var_Set (name, val, ctxt) |
Var_Set(name, val, ctxt) |
char *name; /* name of variable to set */ |
char *name; /* name of variable to set */ |
char *val; /* value to give to the variable */ |
char *val; /* value to give to the variable */ |
GNode *ctxt; /* context in which to set it */ |
SymTable *ctxt; /* context in which to set it */ |
{ |
{ |
register Var *v; |
register Var *v; |
|
|
|
|
* here will override anything in a lower context, so there's not much |
* here will override anything in a lower context, so there's not much |
* point in searching them all just to save a bit of memory... |
* point in searching them all just to save a bit of memory... |
*/ |
*/ |
v = VarFind (name, ctxt, 0); |
v = VarFind(name, ctxt, 0); |
if (v == NULL) { |
if (v == NULL) { |
(void)VarAdd(name, val, ctxt); |
(void)VarAdd(name, val, ctxt); |
} else { |
} else { |
|
|
Buf_AddString(&(v->val), val); |
Buf_AddString(&(v->val), val); |
|
|
if (DEBUG(VAR)) { |
if (DEBUG(VAR)) { |
printf("%s:%s = %s\n", ctxt->name, name, val); |
printf("%s:%s = %s\n", context_name(ctxt), name, val); |
} |
} |
} |
} |
/* |
/* |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Var_Append (name, val, ctxt) |
Var_Append(name, val, ctxt) |
char *name; /* Name of variable to modify */ |
char *name; /* Name of variable to modify */ |
char *val; /* String to append to it */ |
char *val; /* String to append to it */ |
GNode *ctxt; /* Context in which this should occur */ |
SymTable *ctxt; /* Context in which this should occur */ |
{ |
{ |
register Var *v; |
register Var *v; |
|
|
v = VarFind (name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0); |
v = VarFind(name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0); |
|
|
if (v == NULL) { |
if (v == NULL) { |
(void)VarAdd(name, val, ctxt); |
(void)VarAdd(name, val, ctxt); |
|
|
Buf_AddString(&(v->val), val); |
Buf_AddString(&(v->val), val); |
|
|
if (DEBUG(VAR)) { |
if (DEBUG(VAR)) { |
printf("%s:%s = %s\n", ctxt->name, name, VarValue(v)); |
printf("%s:%s = %s\n", context_name(ctxt), name, VarValue(v)); |
} |
} |
|
|
} |
} |
|
|
Boolean |
Boolean |
Var_Exists(name, ctxt) |
Var_Exists(name, ctxt) |
char *name; /* Variable to find */ |
char *name; /* Variable to find */ |
GNode *ctxt; /* Context in which to start search */ |
SymTable *ctxt; /* Context in which to start search */ |
{ |
{ |
Var *v; |
Var *v; |
|
|
|
|
char * |
char * |
Var_Value(name, ctxt) |
Var_Value(name, ctxt) |
char *name; /* name to find */ |
char *name; /* name to find */ |
GNode *ctxt; /* context in which to search for it */ |
SymTable *ctxt; /* context in which to search for it */ |
{ |
{ |
Var *v; |
Var *v; |
|
|
|
|
*/ |
*/ |
static char * |
static char * |
VarGetPattern(ctxt, err, tstr, delim, flags, length, pattern) |
VarGetPattern(ctxt, err, tstr, delim, flags, length, pattern) |
GNode *ctxt; |
SymTable *ctxt; |
int err; |
int err; |
char **tstr; |
char **tstr; |
int delim; |
int delim; |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
char * |
char * |
Var_Parse (str, ctxt, err, lengthPtr, freePtr) |
Var_Parse(str, ctxt, err, lengthPtr, freePtr) |
char *str; /* The string to parse */ |
char *str; /* The string to parse */ |
GNode *ctxt; /* The context for the variable */ |
SymTable *ctxt; /* The context for the variable */ |
Boolean err; /* TRUE if undefined variables are an error */ |
Boolean err; /* TRUE if undefined variables are an error */ |
size_t *lengthPtr; /* OUT: The length of the specification */ |
size_t *lengthPtr; /* OUT: The length of the specification */ |
Boolean *freePtr; /* OUT: TRUE if caller should free result */ |
Boolean *freePtr; /* OUT: TRUE if caller should free result */ |
|
|
char * |
char * |
Var_Subst(str, ctxt, undefErr) |
Var_Subst(str, ctxt, undefErr) |
char *str; /* the string in which to substitute */ |
char *str; /* the string in which to substitute */ |
GNode *ctxt; /* the context wherein to find variables */ |
SymTable *ctxt; /* the context wherein to find variables */ |
Boolean undefErr; /* TRUE if undefineds are an error */ |
Boolean undefErr; /* TRUE if undefineds are an error */ |
{ |
{ |
BUFFER buf; /* Buffer for forming things */ |
BUFFER buf; /* Buffer for forming things */ |
|
|
Buffer buf; /* Where to store the result */ |
Buffer buf; /* Where to store the result */ |
char *str; /* The string in which to substitute */ |
char *str; /* The string in which to substitute */ |
const char *var; /* Named variable */ |
const char *var; /* Named variable */ |
GNode *ctxt; /* The context wherein to find variables */ |
SymTable *ctxt; /* The context wherein to find variables */ |
{ |
{ |
char *val; /* Value substituted for a variable */ |
char *val; /* Value substituted for a variable */ |
size_t length; /* Length of the variable invocation */ |
size_t length; /* Length of the variable invocation */ |
|
|
void |
void |
Var_Init() |
Var_Init() |
{ |
{ |
VAR_GLOBAL = Targ_NewGN("Global"); |
static SymTable global_vars, cmd_vars, env_vars; |
VAR_CMD = Targ_NewGN("Command"); |
|
VAR_ENV = Targ_NewGN("Environment"); |
VAR_GLOBAL = &global_vars; |
|
VAR_CMD = &cmd_vars; |
|
VAR_ENV = &env_vars; |
|
Lst_Init(VAR_GLOBAL); |
|
Lst_Init(VAR_CMD); |
|
Lst_Init(VAR_ENV); |
Lst_Init(&allVars); |
Lst_Init(&allVars); |
|
|
} |
} |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Var_Dump (ctxt) |
Var_Dump(ctxt) |
GNode *ctxt; |
SymTable *ctxt; |
{ |
{ |
Lst_Every(&ctxt->context, VarPrintVar); |
Lst_Every(ctxt, VarPrintVar); |
} |
} |