static Var *var_name_with_dollar __P((char *, char **, SymTable *, Boolean, char));
static Var *getvar __P((GSymT *, const char *, const char *, u_int32_t));voidSymTable_Init(ctxt)    SymTable	*ctxt;{    static SymTable sym_template;    memcpy(ctxt, &sym_template, sizeof(*ctxt));}voidSymTable_Destroy(ctxt)    SymTable	*ctxt;{    int i;    for (i = 0; i < LOCAL_SIZE; i++)	if (ctxt->locals[i] != NULL)	    VarDelete(ctxt->locals[i]);}static intquick_lookup(name, end, pk)    const char *name;    const char **end;    u_int32_t *pk;{    size_t len;    *pk = hash_interval(name, end);    len = *end - name;	/* substitute short version for long local name */    switch (*pk % MAGICSLOTS) {		    /* MAGICSLOTS should be the    */    case K_LONGALLSRC % MAGICSLOTS:	    /* smallest constant yielding  */					    /* distinct case values        */	if (*pk == K_LONGALLSRC && strncmp(name, LONGALLSRC, len) == 0 &&	    len == strlen(LONGALLSRC))	    return ALLSRC_INDEX;	break;    case K_LONGARCHIVE % MAGICSLOTS:	if (*pk == K_LONGARCHIVE && strncmp(name, LONGARCHIVE, len) == 0 &&	    len == strlen(LONGARCHIVE))	    return ARCHIVE_INDEX;	break;    case K_LONGIMPSRC % MAGICSLOTS:	if (*pk == K_LONGIMPSRC && strncmp(name, LONGIMPSRC, len) == 0 &&	    len == strlen(LONGIMPSRC))	    return IMPSRC_INDEX;	break;    case K_LONGMEMBER % MAGICSLOTS:	if (*pk == K_LONGMEMBER && strncmp(name, LONGMEMBER, len) == 0 &&	    len == strlen(LONGMEMBER))	    return MEMBER_INDEX;	break;    case K_LONGOODATE % MAGICSLOTS:	if (*pk == K_LONGOODATE && strncmp(name, LONGOODATE, len) == 0 &&	    len == strlen(LONGOODATE))	    return OODATE_INDEX;	break;    case K_LONGPREFIX % MAGICSLOTS:	if (*pk == K_LONGPREFIX && strncmp(name, LONGPREFIX, len) == 0 &&	    len == strlen(LONGPREFIX))	    return PREFIX_INDEX;	break;    case K_LONGTARGET % MAGICSLOTS:	if (*pk == K_LONGTARGET && strncmp(name, LONGTARGET, len) == 0 &&	    len == strlen(LONGTARGET))	    return TARGET_INDEX;	break;    case K_TARGET % MAGICSLOTS:	if (name[0] == TARGET[0] && len == 1)	    return TARGET_INDEX;	break;    case K_OODATE % MAGICSLOTS:	if (name[0] == OODATE[0] && len == 1)	    return OODATE_INDEX;	break;    case K_ALLSRC % MAGICSLOTS:	if (name[0] == ALLSRC[0] && len == 1)	    return ALLSRC_INDEX;	break;    case K_IMPSRC % MAGICSLOTS:	if (name[0] == IMPSRC[0] && len == 1)	    return IMPSRC_INDEX;	break;    case K_PREFIX % MAGICSLOTS:	if (name[0] == PREFIX[0] && len == 1)	    return PREFIX_INDEX;	break;    case K_ARCHIVE % MAGICSLOTS:	if (name[0] == ARCHIVE[0] && len == 1)	    return ARCHIVE_INDEX;	break;    case K_MEMBER % MAGICSLOTS:	if (name[0] == MEMBER[0] && len == 1)	    return MEMBER_INDEX;	break;    default:	break;    }    return -1;}void Varq_Set(idx, val, gn)    int 	idx;    char 	*val;    GNode 	*gn;{    /* We only look for a variable in the given context since anything set     * 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...  */    Var *v = gn->context.locals[idx];    if (v == NULL) {    	v = new_var(varnames[idx], val);	v->flags = 0;	gn->context.locals[idx] = v;    } else {	Buf_Reset(&(v->val));	Buf_AddString(&(v->val), val);    }    if (DEBUG(VAR))	printf("%s:%s = %s\n", gn->name, varnames[idx], val);}void Varq_Append(idx, val, gn)    int		idx;    char	*val;    GNode	*gn;{    Var *v = gn->context.locals[idx];    if (v == NULL) {    	v = new_var(varnames[idx], val);	v->flags = 0;	gn->context.locals[idx] = v;    } else {	Buf_AddSpace(&(v->val));	Buf_AddString(&(v->val), val);    }    if (DEBUG(VAR))	printf("%s:%s = %s\n", gn->name, varnames[idx], VarValue(v));}char *Varq_Value(idx, gn)    int		idx;    GNode	*gn;{    Var *v = gn->context.locals[idx];    if (v != NULL)    	return VarValue(v);    else    	return NULL;}BooleanVarq_Exists(idx, gn)    int		idx;    GNode	*gn;{    return gn->context.locals[idx] != NULL;}static const char *context_name(ctxt)    GSymT *ctxt;{    if (ctxt == VAR_GLOBAL)    	return "Global";    else if (ctxt == VAR_CMD)    	return "Command";    else    	return "Environment";}    /* Create a variable, to pass to VarAdd.  */static Var *new_var(name, val)    const char *name;    const char *val;{    Var *v;    const char *end = NULL;    v = hash_create_entry(&var_info, name, &end);    if (val != NULL) {    	size_t len = strlen(val);	Buf_Init(&(v->val), len+1);	Buf_AddChars(&(v->val), len, val);    } else    	Buf_Init(&(v->val), 1);    return v;}static Var *getvar(ctxt, name, end, k)    GSymT	*ctxt;    const char 	*name;    const char	*end;    u_int32_t	k;{    return hash_find(ctxt, hash_lookup_interval(ctxt, name, end, k));}