Exemplo n.º 1
0
Arquivo: var.c Projeto: aharri/base
/* Delete a variable and all the space associated with it.
 */
static void
delete_var(Var *v)
{
	if ((v->flags & VAR_DUMMY) == 0)
		Buf_Destroy(&(v->val));
	free(v);
}
Exemplo n.º 2
0
Arquivo: var.c Projeto: aharri/base
/* POSIX says that variable assignments passed on the command line should be
 * propagated to sub makes through MAKEFLAGS.
 */
void
Var_AddCmdline(const char *name)
{
	Var *v;
	unsigned int i;
	BUFFER buf;
	char *s;

	Buf_Init(&buf, MAKE_BSIZE);

	for (v = ohash_first(&global_variables, &i); v != NULL;
	    v = ohash_next(&global_variables, &i)) {
		/* This is not as expensive as it looks: this function is
		 * called before parsing Makefiles, so there are just a
		 * few non cmdling variables in there.
		 */
		if (!(v->flags & VAR_FROM_CMD)) {
			continue;
		}
		/* We assume variable names don't need quoting */
		Buf_AddString(&buf, v->name);
		Buf_AddChar(&buf, '=');
		for (s = var_get_value(v); *s != '\0'; s++) {
			if (strchr(quotable, *s))
				Buf_AddChar(&buf, '\\');
			Buf_AddChar(&buf, *s);
		}
		Buf_AddSpace(&buf);
	}
	Var_Append(name, Buf_Retrieve(&buf));
	Buf_Destroy(&buf);
}
Exemplo n.º 3
0
Arquivo: var.c Projeto: aharri/base
void
Var_DeleteLoopVar(struct LoopVar *l)
{
	if ((l->me->flags & VAR_DUMMY) == 0)
		Buf_Destroy(&(l->me->val));
	*(l->me) = l->old;
	free(l);
}
Exemplo n.º 4
0
static Token
CondHandleString(bool doEval)
{
	char *lhs;
	const char *begin;
	BUFFER buf;

	/* find the extent of the string */
	begin = ++condExpr;
	while (*condExpr && *condExpr != '"') {
		condExpr++;
	}

	Buf_Init(&buf, 0);
	Buf_Addi(&buf, begin, condExpr);
	if (*condExpr == '"')
		condExpr++;
	lhs = Var_Subst(Buf_Retrieve(&buf), NULL, doEval);
	Buf_Destroy(&buf);
	return CondHandleComparison(lhs, true, doEval);
}
Exemplo n.º 5
0
static Token
CondHandleVarSpec(bool doEval)
{
	char *lhs;
	size_t varSpecLen;
	bool doFree;

	/* Parse the variable spec and skip over it, saving its
	 * value in lhs.  */
	lhs = Var_Parse(condExpr, NULL, doEval,&varSpecLen,&doFree);
	if (lhs == var_Error)
		/* Even if !doEval, we still report syntax errors, which
		 * is what getting var_Error back with !doEval means.  */
		return Err;
	condExpr += varSpecLen;

	if (!isspace(*condExpr) &&
		strchr("!=><", *condExpr) == NULL) {
		BUFFER buf;

		Buf_Init(&buf, 0);

		Buf_AddString(&buf, lhs);

		if (doFree)
			free(lhs);

		for (;*condExpr && !isspace(*condExpr); condExpr++)
			Buf_AddChar(&buf, *condExpr);

		lhs = Var_Subst(Buf_Retrieve(&buf), NULL, doEval);
		Buf_Destroy(&buf);
		doFree = true;
	}

	return CondHandleComparison(lhs, doFree, doEval);
}
Exemplo n.º 6
0
/* coverity:[+alloc : arg-*2] */
static char *
CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS)
{
    Buffer buf;
    char *cp;
    char *str;
    int	len;
    int qt;
    char *start;

    Buf_Init(&buf, 0);
    str = NULL;
    *freeIt = NULL;
    *quoted = qt = *condExpr == '"' ? 1 : 0;
    if (qt)
	condExpr++;
    for (start = condExpr; *condExpr && str == NULL; condExpr++) {
	switch (*condExpr) {
	case '\\':
	    if (condExpr[1] != '\0') {
		condExpr++;
		Buf_AddByte(&buf, *condExpr);
	    }
	    break;
	case '"':
	    if (qt) {
		condExpr++;		/* we don't want the quotes */
		goto got_str;
	    } else
		Buf_AddByte(&buf, *condExpr); /* likely? */
	    break;
	case ')':
	case '!':
	case '=':
	case '>':
	case '<':
	case ' ':
	case '\t':
	    if (!qt)
		goto got_str;
	    else
		Buf_AddByte(&buf, *condExpr);
	    break;
	case '$':
	    /* if we are in quotes, then an undefined variable is ok */
	    str = Var_Parse(condExpr, VAR_CMD,
			    ((!qt && doEval) ? VARF_UNDEFERR : 0) |
			    VARF_WANTRES, &len, freeIt);
	    if (str == var_Error) {
		if (*freeIt) {
		    free(*freeIt);
		    *freeIt = NULL;
		}
		/*
		 * Even if !doEval, we still report syntax errors, which
		 * is what getting var_Error back with !doEval means.
		 */
		str = NULL;
		goto cleanup;
	    }
	    condExpr += len;
	    /*
	     * If the '$' was first char (no quotes), and we are
	     * followed by space, the operator or end of expression,
	     * we are done.
	     */
	    if ((condExpr == start + len) &&
		(*condExpr == '\0' ||
		 isspace((unsigned char) *condExpr) ||
		 strchr("!=><)", *condExpr))) {
		goto cleanup;
	    }
	    /*
	     * Nope, we better copy str to buf
	     */
	    for (cp = str; *cp; cp++) {
		Buf_AddByte(&buf, *cp);
	    }
	    if (*freeIt) {
		free(*freeIt);
		*freeIt = NULL;
	    }
	    str = NULL;			/* not finished yet */
	    condExpr--;			/* don't skip over next char */
	    break;
	default:
	    if (strictLHS && !qt && *start != '$' &&
		!isdigit((unsigned char) *start)) {
		/* lhs must be quoted, a variable reference or number */
		if (*freeIt) {
		    free(*freeIt);
		    *freeIt = NULL;
		}
		str = NULL;
		goto cleanup;
	    }
	    Buf_AddByte(&buf, *condExpr);
	    break;
	}
    }
 got_str:
    str = Buf_GetAll(&buf, NULL);
    *freeIt = str;
 cleanup:
    Buf_Destroy(&buf, FALSE);
    return str;
}
Exemplo n.º 7
0
/*-
 *-----------------------------------------------------------------------
 * CondGetArg --
 *	Find the argument of a built-in function.
 *
 * Input:
 *	parens		TRUE if arg should be bounded by parens
 *
 * Results:
 *	The length of the argument and the address of the argument.
 *
 * Side Effects:
 *	The pointer is set to point to the closing parenthesis of the
 *	function call.
 *
 *-----------------------------------------------------------------------
 */
static int
CondGetArg(char **linePtr, char **argPtr, const char *func)
{
    char	  *cp;
    int	    	  argLen;
    Buffer	  buf;
    int           paren_depth;
    char          ch;

    cp = *linePtr;
    if (func != NULL)
	/* Skip opening '(' - verfied by caller */
	cp++;

    if (*cp == '\0') {
	/*
	 * No arguments whatsoever. Because 'make' and 'defined' aren't really
	 * "reserved words", we don't print a message. I think this is better
	 * than hitting the user with a warning message every time s/he uses
	 * the word 'make' or 'defined' at the beginning of a symbol...
	 */
	*argPtr = NULL;
	return (0);
    }

    while (*cp == ' ' || *cp == '\t') {
	cp++;
    }

    /*
     * Create a buffer for the argument and start it out at 16 characters
     * long. Why 16? Why not?
     */
    Buf_Init(&buf, 16);

    paren_depth = 0;
    for (;;) {
	ch = *cp;
	if (ch == 0 || ch == ' ' || ch == '\t')
	    break;
	if ((ch == '&' || ch == '|') && paren_depth == 0)
	    break;
	if (*cp == '$') {
	    /*
	     * Parse the variable spec and install it as part of the argument
	     * if it's valid. We tell Var_Parse to complain on an undefined
	     * variable, so we don't do it too. Nor do we return an error,
	     * though perhaps we should...
	     */
	    char  	*cp2;
	    int		len;
	    void	*freeIt;

	    cp2 = Var_Parse(cp, VAR_CMD, VARF_UNDEFERR|VARF_WANTRES,
			    &len, &freeIt);
	    Buf_AddBytes(&buf, strlen(cp2), cp2);
	    free(freeIt);
	    cp += len;
	    continue;
	}
	if (ch == '(')
	    paren_depth++;
	else
	    if (ch == ')' && --paren_depth < 0)
		break;
	Buf_AddByte(&buf, *cp);
	cp++;
    }

    *argPtr = Buf_GetAll(&buf, &argLen);
    Buf_Destroy(&buf, FALSE);

    while (*cp == ' ' || *cp == '\t') {
	cp++;
    }

    if (func != NULL && *cp++ != ')') {
	Parse_Error(PARSE_WARNING, "Missing closing parenthesis for %s()",
		     func);
	return (0);
    }

    *linePtr = cp;
    return (argLen);
}
Exemplo n.º 8
-1
void
For_Run(For *arg)
{
	arg->text = Buf_Retrieve(&arg->buf);
	arg->guess = Buf_Size(&arg->buf) + GUESS_EXPANSION;

	arg->var = NULL;
	Lst_ForEach(&arg->lst, ForExec, arg);
	Buf_Destroy(&arg->buf);
	Lst_Destroy(&arg->vars, (SimpleProc)Var_DeleteLoopVar);
	Lst_Destroy(&arg->lst, (SimpleProc)free);
	free(arg);
}