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); }
/* 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; }
void init_memory() { extend_input_line(); extend_token_table(); replot_line = gp_alloc(1, "string"); *replot_line = NUL; }
static void init_memory() { extend_input_line(); extend_token_table(); replot_line = gp_strdup(""); }
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 */ }
/* * 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 */ }
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 */ }