Esempio n. 1
0
static void
expand_call_args(void)
{
    int il = 0;
    int len;
    char *rl;
    char *raw_line = gp_strdup(gp_input_line);

    rl = raw_line;
    *gp_input_line = '\0';
    while (*rl) {
	if (*rl == '$') {
	    const char *sub = expand_call_arg(*(++rl));
	    len = strlen(sub);
	    while (gp_input_line_len - il < len + 1)
		extend_input_line();
	    strcpy(gp_input_line + il, sub);
	    il += len;
	} else {
	    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);
}
Esempio n. 2
0
/* substitute output from ` `
 * *strp points to the input string.  (*strp)[current] is expected to
 * be the initial back tic.  Characters through the following back tic
 * are replaced by the output of the command.  extend_input_line()
 * is called to extend *strp array if needed.
 */
static void
substitute(char **strp, size_t *str_lenp, int current)
{
    char *last;
    char c;
    char *str, *pgm, *rest = NULL;
    char *output;
    size_t pgm_len, rest_len = 0;
    int output_pos;

    /* forgive missing closing backquote at end of line */
    str = *strp + current;
    last = str;
    while (*++last) {
	if (*last == '`')
	    break;
    }
    pgm_len = last - str;
    pgm = gp_alloc(pgm_len, "command string");
    safe_strncpy(pgm, str + 1, pgm_len); /* omit ` to leave room for NUL */

    /* save rest of line, if any */
    if (*last) {
	last++;			/* advance past ` */
	rest_len = strlen(last) + 1;
	if (rest_len > 1) {
	    rest = gp_alloc(rest_len, "input line copy");
	    strcpy(rest, last);
	}
    }

    /* do system call */
    (void) do_system_func(pgm, &output);
    free(pgm);

    /* now replace ` ` with output */
    output_pos = 0;
    while ((c = output[output_pos++])) {
	if (c != '\n' && c != '\r')
	    (*strp)[current++] = c;
	if (current == *str_lenp)
	    extend_input_line();
    }
    (*strp)[current] = 0;
    free(output);

    /* tack on rest of line to output */
    if (rest) {
	while (current + rest_len > *str_lenp)
	    extend_input_line();
	strcpy(*strp + current, rest);
	free(rest);
    }
    screen_ok = FALSE;

}
Esempio n. 3
0
void init_memory()
{
    extend_input_line();
    extend_token_table();
    replot_line = gp_alloc(1, "string");
    *replot_line = NUL;
}
Esempio n. 4
0
static void
init_memory()
{
    extend_input_line();
    extend_token_table();
    replot_line = gp_strdup("");
}
Esempio n. 5
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, name, NULL); /* save state for errors and recursion */
    do_load_arg_substitution = can_do_args;

    if (fp == (FILE *) NULL) {
	os_error(NO_CARET, "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 {
	call_argc = 0;
	if (can_do_args) {
	    prepare_call();
	    lf_head->c_token = c_token; /* update after prepare_call() */
	}
	/* things to do after lf_push */
	inline_num = 0;
	/* go into non-interactive mode during load */
	/* will be undone below, or in load_file_error */
	interactive = FALSE;

	while (!stop) {	/* read all lines in file */
	    left = gp_input_line_len;
	    start = 0;
	    more = TRUE;

	    /* read one logical line */
	    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 {
			/* EAM May 2011 - handle multi-line bracketed clauses {...}.
			 * Introduces a requirement for scanner.c and scanner.h
			 * This code is redundant with part of do_line(),
			 * but do_line() assumes continuation lines come from stdin.
			 */

			/* macros in a clause are problematic, as they are */
			/* only expanded once even if the clause is replayed */
			string_expand_macros();

			/* Strip off trailing comment and count curly braces */
			num_tokens = scanner(&gp_input_line, &gp_input_line_len);
			if (gp_input_line[token[num_tokens].start_index] == '#') {
			    gp_input_line[token[num_tokens].start_index] = NUL;
			    start = token[num_tokens].start_index;
			    left = gp_input_line_len - start;
			}
			/* Read additional lines if necessary to complete a
			 * bracketed clause {...}
			 */
			if (curly_brace_count < 0)
			    int_error(NO_CARET, "Unexpected }");
			if (curly_brace_count > 0) {
			    if (len + 4 > gp_input_line_len)
				extend_input_line();
			    strcat(gp_input_line,";\n");
			    start = strlen(gp_input_line);
			    left = gp_input_line_len - start;
			    continue;
			}
			
			more = FALSE;
		    }

		}
	    }

	    /* process line */
	    if (strlen(gp_input_line) > 0) {
		if (can_do_args)
		  expand_call_args();

		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 */
}
Esempio n. 6
0
/*
 * load_file() is called from
 * (1) the "load" command, no arguments substitution is done
 * (2) the "call" command, arguments are substituted for $0, $1, etc.
 * (3) on program entry to load initialization files (acts like "load")
 * (4) to execute script files given on the command line (acts like "load")
 * (5) to execute a single script file given with -c (acts like "call")
 */
void
load_file(FILE *fp, char *name, int calltype)
{
    int len;

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

    /* Provide a user-visible copy of the current line number in the input file */
    udvt_entry *gpval_lineno = add_udv_by_name("GPVAL_LINENO");
    Ginteger(&gpval_lineno->udv_value, 0);
    gpval_lineno->udv_undef = FALSE;

    lf_push(fp, name, NULL); /* save state for errors and recursion */

    if (fp == (FILE *) NULL) {
	int_error(NO_CARET, "Cannot open script file '%s'", name);
	return; /* won't actually reach here */
    }

    if (fp == stdin) {
	/* DBT 10-6-98  go interactive if "-" named as load file */
	interactive = TRUE;
	while (!com_line());
	(void) lf_pop();
	return;
    }

    /* We actually will read from a file */
    prepare_call(calltype);

    /* things to do after lf_push */
    inline_num = 0;
    /* go into non-interactive mode during load */
    /* will be undone below, or in load_file_error */
    interactive = FALSE;

    while (!stop) {	/* read all lines in file */
	left = gp_input_line_len;
	start = 0;
	more = TRUE;

	/* read one logical line */
	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++;
		gpval_lineno->udv_value.v.int_val = inline_num;	/* User visible copy */
		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 {
		    /* EAM May 2011 - handle multi-line bracketed clauses {...}.
		     * Introduces a requirement for scanner.c and scanner.h
		     * This code is redundant with part of do_line(),
		     * but do_line() assumes continuation lines come from stdin.
		     */

		    /* macros in a clause are problematic, as they are */
		    /* only expanded once even if the clause is replayed */
		    string_expand_macros();

		    /* Strip off trailing comment and count curly braces */
		    num_tokens = scanner(&gp_input_line, &gp_input_line_len);
		    if (gp_input_line[token[num_tokens].start_index] == '#') {
			gp_input_line[token[num_tokens].start_index] = NUL;
			start = token[num_tokens].start_index;
			left = gp_input_line_len - start;
		    }
		    /* Read additional lines if necessary to complete a
		     * bracketed clause {...}
		     */
		    if (curly_brace_count < 0)
			int_error(NO_CARET, "Unexpected }");
		    if (curly_brace_count > 0) {
			if ((len + 4) > gp_input_line_len)
			    extend_input_line();
			strcat(gp_input_line,";\n");
			start = strlen(gp_input_line);
			left = gp_input_line_len - start;
			continue;
		    }
		    
		    more = FALSE;
		}

	    }
	}

	/* process line */
	if (strlen(gp_input_line) > 0) {
#ifdef OLD_STYLE_CALL_ARGS
	    if (calltype == 2 || calltype == 5)
		expand_call_args();
#endif
	    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 */
}
Esempio n. 7
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 */
}