Exemplo n.º 1
0
static void
prepare_call(void)
{
    call_argc = 0;
    /* Gnuplot "call" command can have up to 10 arguments "$0" to "$9" */
    while (!END_OF_COMMAND && call_argc <= 9) {
	if (isstring(c_token))
	    m_quote_capture(&call_args[call_argc++], c_token, c_token);
	else
	    m_capture(&call_args[call_argc++], c_token, c_token);
	c_token++;
    }
    if (!END_OF_COMMAND)
	int_error(++c_token, "too many arguments for 'call <file>'");
}
Exemplo n.º 2
0
Arquivo: parse.c Projeto: Reen/gnuplot
/* add action table entries for primary expressions, i.e. either a
 * parenthesized expression, a variable name, a numeric constant, a
 * function evaluation, a power operator or postfix '!' (factorial)
 * expression */
static void
parse_primary_expression()
{
    if (equals(c_token, "(")) {
	c_token++;
	parse_expression();

	/* Expressions may be separated by a comma */
	while (equals(c_token,",")) {
	    c_token++;
	    (void) add_action(POP);
	    parse_expression();
	}

	if (!equals(c_token, ")"))
	    int_error(c_token, "')' expected");
	c_token++;
    } else if (equals(c_token, "$")) {
	struct value a;

	c_token++;
	if (equals(c_token,"N")) {	/* $N == pseudocolumn -3 means "last column" */
	    c_token++;
	    Ginteger(&a, -3);
	    at_highest_column_used = -3;
	} else if (!isanumber(c_token)) {
	    int_error(c_token, "Column number expected");
	} else {
	    convert(&a, c_token++);
	    if (a.type != INTGR || a.v.int_val < 0)
		int_error(c_token, "Positive integer expected");
	    if (at_highest_column_used < a.v.int_val)
		at_highest_column_used = a.v.int_val;
	}
	add_action(DOLLARS)->v_arg = a;
    } else if (isanumber(c_token)) {
	/* work around HP 9000S/300 HP-UX 9.10 cc limitation ... */
	/* HBB 20010724: use this code for all platforms, then */
	union argument *foo = add_action(PUSHC);

	convert(&(foo->v_arg), c_token);
	c_token++;
    } else if (isletter(c_token)) {
	/* Found an identifier --- check whether its a function or a
	 * variable by looking for the parentheses of a function
	 * argument list */
	if (equals(c_token + 1, "(")) {
	    enum operators whichfunc = is_builtin_function(c_token);
	    struct value num_params;
	    num_params.type = INTGR;

#if (1)	    /* DEPRECATED */
	    if (whichfunc && (strcmp(ft[whichfunc].f_name,"defined")==0)) {
		/* Deprecated syntax:   if (defined(foo)) ...  */
		/* New syntax:          if (exists("foo")) ... */
		struct udvt_entry *udv = add_udv(c_token+2);
		union argument *foo = add_action(PUSHC);
		foo->v_arg.type = INTGR;
		foo->v_arg.v.int_val = udv->udv_undef ? 0 : 1;
		c_token += 4;  /* skip past "defined ( <foo> ) " */
		return;
	    }
#endif

	    if (whichfunc) {
		c_token += 2;	/* skip fnc name and '(' */
		parse_expression(); /* parse fnc argument */
		num_params.v.int_val = 1;
		while (equals(c_token, ",")) {
		    c_token++;
		    num_params.v.int_val++;
		    parse_expression();
		}

		if (!equals(c_token, ")"))
		    int_error(c_token, "')' expected");
		c_token++;

		/* So far sprintf is the only built-in function */
		/* with a variable number of arguments.         */
		if (!strcmp(ft[whichfunc].f_name,"sprintf"))
		    add_action(PUSHC)->v_arg = num_params;

		/* The column() function has side effects requiring special handling */
		if (!strcmp(ft[whichfunc].f_name,"column")) {
		    set_up_columnheader_parsing( &(at->actions[at->a_count-1]) );
		}

		(void) add_action(whichfunc);

	    } else {
		/* it's a call to a user-defined function */
		enum operators call_type = (int) CALL;
		int tok = c_token;

		c_token += 2;	/* skip func name and '(' */
		parse_expression();
		if (equals(c_token, ",")) { /* more than 1 argument? */
		    num_params.v.int_val = 1;
		    while (equals(c_token, ",")) {
			num_params.v.int_val += 1;
			c_token += 1;
			parse_expression();
		    }
		    add_action(PUSHC)->v_arg = num_params;
		    call_type = (int) CALLN;
		}
		if (!equals(c_token, ")"))
		    int_error(c_token, "')' expected");
		c_token++;
		add_action(call_type)->udf_arg = add_udf(tok);
	    }
	} else if (equals(c_token, "sum") && equals(c_token+1, "[")) {
            parse_sum_expression();
	/* dummy_func==NULL is a flag to say no dummy variables active */
	} else if (dummy_func) {
	    if (equals(c_token, c_dummy_var[0])) {
		c_token++;
		add_action(PUSHD1)->udf_arg = dummy_func;
		fit_dummy_var[0]++;
	    } else if (equals(c_token, c_dummy_var[1])) {
		c_token++;
		add_action(PUSHD2)->udf_arg = dummy_func;
		fit_dummy_var[1]++;
	    } else {
		int i, param = 0;

		for (i = 2; i < MAX_NUM_VAR; i++) {
		    if (equals(c_token, c_dummy_var[i])) {
			struct value num_params;
			num_params.type = INTGR;
			num_params.v.int_val = i;
			param = 1;
			c_token++;
			add_action(PUSHC)->v_arg = num_params;
			add_action(PUSHD)->udf_arg = dummy_func;
			fit_dummy_var[i]++;
			break;
		    }
		}
		if (!param) {	/* defined variable */
		    add_action(PUSH)->udv_arg = add_udv(c_token);
		    c_token++;
		}
	    }
	    /* its a variable, with no dummies active - div */
	} else {
	    add_action(PUSH)->udv_arg = add_udv(c_token);
	    c_token++;
	}
    }
    /* end if letter */

    /* Maybe it's a string constant */
    else if (isstring(c_token)) {
	union argument *foo = add_action(PUSHC);
	foo->v_arg.type = STRING;
	foo->v_arg.v.string_val = NULL;
	/* this dynamically allocated string will be freed by free_at() */
	m_quote_capture(&(foo->v_arg.v.string_val), c_token, c_token);
	c_token++;
    } else
	int_error(c_token, "invalid expression ");

    /* add action code for ! (factorial) operator */
    while (equals(c_token, "!")) {
	c_token++;
	(void) add_action(FACTORIAL);
    }
    /* add action code for ** operator */
    if (equals(c_token, "**")) {
	c_token++;
	parse_unary_expression();
	(void) add_action(POWER);
    }

    /* Parse and add actions for range specifier applying to previous entity.
     * Currently only used to generate substrings, but could also be used to
     * extract vector slices.
     */
    if (equals(c_token, "[") && !isanumber(c_token-1)) {
	/* handle '*' or empty start of range */
	if (equals(++c_token,"*") || equals(c_token,":")) {
	    union argument *empty = add_action(PUSHC);
	    empty->v_arg.type = INTGR;
	    empty->v_arg.v.int_val = 1;
	    if (equals(c_token,"*"))
		c_token++;
	} else
	    parse_expression();
	if (!equals(c_token, ":"))
	    int_error(c_token, "':' expected");
	/* handle '*' or empty end of range */
	if (equals(++c_token,"*") || equals(c_token,"]")) {
	    union argument *empty = add_action(PUSHC);
	    empty->v_arg.type = INTGR;
	    empty->v_arg.v.int_val = 65535; /* should be INT_MAX */
	    if (equals(c_token,"*"))
		c_token++;
	} else
	    parse_expression();
	if (!equals(c_token, "]"))
	    int_error(c_token, "']' expected");
	c_token++;
	(void) add_action(RANGE);
    }
}
Exemplo n.º 3
0
void
load_file(FILE *fp, char *name, TBOOLEAN can_do_args)
{
    int len;

    int start, left;
    int more;
    int stop = FALSE;

    lf_push(fp);		/* save state for errors and recursion */
    do_load_arg_substitution = can_do_args;

    if (fp == (FILE *) NULL) {
	os_error(c_token, "Cannot open %s file '%s'",
		 can_do_args ? "call" : "load", name);
    } else if (fp == stdin) {
	/* DBT 10-6-98  go interactive if "-" named as load file */
	interactive = TRUE;
	while (!com_line());
    } else {
	/* go into non-interactive mode during load */
	/* will be undone below, or in load_file_error */
	int argc = 0; /* number arguments passed by "call" */
	interactive = FALSE;
	inline_num = 0;
	lf_head->name = name;

	if (can_do_args) {
	    /* Gnuplot "call" command can have up to 10 arguments "$0" to "$9" */
	    while (!END_OF_COMMAND && argc <= 9) {
		if (isstring(c_token))
		    m_quote_capture(&call_args[argc++], c_token, c_token);
		else
		    m_capture(&call_args[argc++], c_token, c_token);
		c_token++;
	    }
	    if (!END_OF_COMMAND)
		int_error(++c_token, "too many arguments for 'call <file>'");
	}

	/* These were initialized to NULL in lf_push(); will be freed in lf_pop() */
	lf_head->c_token = c_token;
	lf_head->num_tokens = num_tokens;
	lf_head->tokens = gp_alloc(num_tokens * sizeof(struct lexical_unit), "lf tokens");
	memcpy(lf_head->tokens, token, num_tokens * sizeof(struct lexical_unit));
	lf_head->input_line = gp_strdup(gp_input_line);
	
	while (!stop) {		/* read all commands in file */
	    /* read one command */
	    left = gp_input_line_len;
	    start = 0;
	    more = TRUE;

	    while (more) {
		if (fgets(&(gp_input_line[start]), left, fp) == (char *) NULL) {
		    stop = TRUE;	/* EOF in file */
		    gp_input_line[start] = '\0';
		    more = FALSE;
		} else {
		    inline_num++;
		    len = strlen(gp_input_line) - 1;
		    if (gp_input_line[len] == '\n') {	/* remove any newline */
			gp_input_line[len] = '\0';
			/* Look, len was 1-1 = 0 before, take care here! */
			if (len > 0)
			    --len;
			if (gp_input_line[len] == '\r') {	/* remove any carriage return */
			    gp_input_line[len] = NUL;
			    if (len > 0)
				--len;
			}
		    } else if (len + 2 >= left) {
			extend_input_line();
			left = gp_input_line_len - len - 1;
			start = len + 1;
			continue;	/* don't check for '\' */
		    }
		    if (gp_input_line[len] == '\\') {
			/* line continuation */
			start = len;
			left = gp_input_line_len - start;
		    } else
			more = FALSE;
		}
	    }

	    if (strlen(gp_input_line) > 0) {
		if (can_do_args) {
		    int il = 0;
		    char *rl;
		    char *raw_line = gp_strdup(gp_input_line);

		    rl = raw_line;
		    *gp_input_line = '\0';
		    while (*rl) {
			int aix;
			if (*rl == '$'
			    && ((aix = *(++rl)) != 0)	/* HBB 980308: quiet BCC warning */
			    && ((aix >= '0' && aix <= '9') || aix == '#')) {
			    if (aix == '#') {
				/* replace $# by number of passed arguments */
				len = argc < 10 ? 1 : 2; /* argc can be 0 .. 10 */
				while (gp_input_line_len - il < len + 1) {
				    extend_input_line();
				}
				sprintf(gp_input_line + il, "%i", argc);
				il += len;
			    } else
			    if (call_args[aix -= '0']) {
				/* replace $n for n=0..9 by the passed argument */
				len = strlen(call_args[aix]);
				while (gp_input_line_len - il < len + 1) {
				    extend_input_line();
				}
				strcpy(gp_input_line + il, call_args[aix]);
				il += len;
			    }
			} else {
			    /* substitute for $<n> here */
			    if (il + 1 > gp_input_line_len) {
				extend_input_line();
			    }
			    gp_input_line[il++] = *rl;
			}
			rl++;
		    }
		    if (il + 1 > gp_input_line_len) {
			extend_input_line();
		    }
		    gp_input_line[il] = '\0';
		    free(raw_line);
		}
		screen_ok = FALSE;	/* make sure command line is
					   echoed on error */
		if (do_line())
		    stop = TRUE;
	    }
	}
    }

    /* pop state */
    (void) lf_pop();		/* also closes file fp */
}