void get_user_env() { if (user_homedir == NULL) { const char *env_home; if ((env_home = getenv(HOME)) #ifdef WIN32 || (env_home = appdata_directory()) || (env_home = getenv("USERPROFILE")) #endif #ifndef VMS || (env_home = getenv("HOME")) #endif ) user_homedir = (const char *) gp_strdup(env_home); else if (interactive) int_warn(NO_CARET, "no HOME found"); } /* Hhm ... what about VMS? */ if (user_shell == NULL) { const char *env_shell; if ((env_shell = getenv("SHELL")) == NULL) #if defined(MSDOS) || defined(_Windows) || defined(OS2) if ((env_shell = getenv("COMSPEC")) == NULL) #endif env_shell = SHELL; user_shell = (const char *) gp_strdup(env_shell); } }
FILE * fake_popen(const char * command, const char * type) { FILE * f = NULL; char tmppath[MAX_PATH]; char tmpfile[MAX_PATH]; DWORD ret; if (type == NULL) return NULL; pipe_type = NUL; if (pipe_filename != NULL) free(pipe_filename); /* Random temp file name in %TEMP% */ ret = GetTempPathA(sizeof(tmppath), tmppath); if ((ret == 0) || (ret > sizeof(tmppath))) return NULL; ret = GetTempFileNameA(tmppath, "gpp", 0, tmpfile); if (ret == 0) return NULL; pipe_filename = gp_strdup(tmpfile); if (*type == 'r') { char * cmd; int rc; LPWSTR wcmd; pipe_type = *type; /* Execute command with redirection of stdout to temporary file. */ cmd = (char *) malloc(strlen(command) + strlen(pipe_filename) + 5); sprintf(cmd, "%s > %s", command, pipe_filename); wcmd = UnicodeText(cmd, encoding); rc = _wsystem(wcmd); free(wcmd); free(cmd); /* Now open temporary file. */ /* system() returns 1 if the command could not be executed. */ if (rc != 1) { f = fopen(pipe_filename, "r"); } else { remove(pipe_filename); free(pipe_filename); pipe_filename = NULL; errno = EINVAL; } } else if (*type == 'w') { pipe_type = *type; /* Write output to temporary file and handle the rest in fake_pclose. */ if (type[1] == 'b') int_error(NO_CARET, "Could not execute pipe '%s'. Writing to binary pipes is not supported.", command); else f = fopen(pipe_filename, "w"); pipe_command = gp_strdup(command); } return f; }
void push_terminal(int is_interactive) { if (term) { free(push_term_name); free(push_term_opts); push_term_name = gp_strdup(term->name); push_term_opts = gp_strdup(term_options); if (is_interactive) fprintf(stderr, " pushed terminal %s %s\n", push_term_name, push_term_opts); } else { if (is_interactive) fputs("\tcurrent terminal type is unknown\n", stderr); } }
static void init_memory() { extend_input_line(); extend_token_table(); replot_line = gp_strdup(""); }
/* Look for a gnuplot init file in current or home directory */ static void load_rcfile() { FILE *plotrc = NULL; char *rcfile = NULL; #ifdef NOCWDRC /* inhibit check of init file in current directory for security reasons */ #else plotrc = fopen(PLOTRC, "r"); #endif /* !NOCWDRC */ if (plotrc == NULL) { if (user_homedir) { /* len of homedir + directory separator + len of file name + \0 */ rcfile = (char *) gp_alloc((user_homedir ? strlen(user_homedir) : 0) + 1 + strlen(PLOTRC) + 1, "rcfile"); strcpy(rcfile, user_homedir); PATH_CONCAT(rcfile, PLOTRC); plotrc = fopen(rcfile, "r"); } } if (plotrc) { char *rc = gp_strdup(rcfile ? rcfile : PLOTRC); load_file(plotrc, rc, FALSE); push_terminal(0); /* needed if terminal or its options were changed */ } free(rcfile); }
void f_value(union argument *arg) { struct udvt_entry *p = first_udv; struct value a; struct value result; (void) arg; (void) pop(&a); if (a.type != STRING) { /* int_warn(NO_CARET,"non-string value passed to value()"); */ push(&a); return; } while (p) { if (!strcmp(p->udv_name, a.v.string_val)) { result = p->udv_value; if (p->udv_undef) p = NULL; else if (result.type == STRING) result.v.string_val = gp_strdup(result.v.string_val); break; } p = p->next_udv; } gpfree_string(&a); if (!p) { /* int_warn(NO_CARET,"undefined variable name passed to value()"); */ result.type = CMPLX; result.v.cmplx_val.real = not_a_number(); } push(&result); }
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); }
/* * In-line data blocks are implemented as a here-document: * $FOO << EOD * data line 1 * data line 2 * ... * EOD * * The data block name must begin with $ followed by a letter. * The string EOD is arbitrary; lines of data will be read from the input stream * until the leading characters on the line match the given character string. * No attempt is made to parse the data at the time it is read in. */ void datablock_command() { FILE *fin; char *name, *eod; int nlines; int nsize = 4; struct udvt_entry *datablock; char dataline[MAX_LINE_LEN+1]; if (!isletter(c_token+1)) int_error(c_token, "illegal datablock name"); /* Create or recycle a datablock with the requested name */ name = parse_datablock_name(); datablock = add_udv_by_name(name); if (!datablock->udv_undef) gpfree_datablock(&datablock->udv_value); datablock->udv_undef = FALSE; datablock->udv_value.type = DATABLOCK; datablock->udv_value.v.data_array = NULL; if (!equals(c_token, "<<") || !isletter(c_token+1)) int_error(c_token, "data block name must be followed by << EODmarker"); c_token++; eod = gp_alloc(token[c_token].length +2, "datablock"); copy_str(&eod[0], c_token, token[c_token].length + 2); c_token++; /* Read in and store data lines until EOD */ fin = (lf_head == NULL) ? stdin : lf_head->fp; if (!fin) int_error(NO_CARET,"attempt to define data block from invalid context"); for (nlines = 0; fgets(dataline, MAX_LINE_LEN, fin); nlines++) { int n; if (!strncmp(eod, dataline, strlen(eod))) break; /* Allocate space for data lines plus at least 2 empty lines at the end. */ if (nlines >= nsize-4) { nsize *= 2; datablock->udv_value.v.data_array = gp_realloc( datablock->udv_value.v.data_array, nsize * sizeof(char *), "datablock"); memset(&datablock->udv_value.v.data_array[nlines], 0, (nsize - nlines) * sizeof(char *)); } /* Strip trailing newline character */ n = strlen(dataline); if (n > 0 && dataline[n - 1] == '\n') dataline[n - 1] = NUL; datablock->udv_value.v.data_array[nlines] = gp_strdup(dataline); } inline_num += nlines + 1; /* Update position in input file */ free(eod); return; }
char * getusername() { char *username = NULL; username=getenv("USER"); if (!username) username=getenv("USERNAME"); return gp_strdup(username); }
/* * Read commands from an initialization file. * where = 0: look for gnuplotrc in system shared directory * where = 1: look for .gnuplot in current directory * where = 2: look for .gnuplot in home directory */ static void load_rcfile(int where) { FILE *plotrc = NULL; char *rcfile = NULL; if (skip_gnuplotrc) return; if (where == 0) { #ifdef GNUPLOT_SHARE_DIR # if defined(_Windows) /* retrieve path relative to gnuplot executable, * whose path is in szModuleName (winmain.c) */ rcfile = gp_alloc(strlen((char *)szPackageDir) + 1 + strlen(GNUPLOT_SHARE_DIR) + 1 + strlen("gnuplotrc") + 1, "rcfile"); strcpy(rcfile, (char *)szPackageDir); PATH_CONCAT(rcfile, GNUPLOT_SHARE_DIR); # else rcfile = (char *) gp_alloc(strlen(GNUPLOT_SHARE_DIR) + 1 + strlen("gnuplotrc") + 1, "rcfile"); strcpy(rcfile, GNUPLOT_SHARE_DIR); # endif PATH_CONCAT(rcfile, "gnuplotrc"); plotrc = fopen(rcfile, "r"); #endif } else if (where == 1) { #ifdef USE_CWDRC /* Allow check for a .gnuplot init file in the current directory */ /* This is a security risk, as someone might leave a malicious */ /* init file in a shared directory. */ plotrc = fopen(PLOTRC, "r"); #endif /* !USE_CWDRC */ } else if (where == 2 && user_homedir) { /* length of homedir + directory separator + length of file name + \0 */ int len = (user_homedir ? strlen(user_homedir) : 0) + 1 + strlen(PLOTRC) + 1; rcfile = gp_alloc(len, "rcfile"); strcpy(rcfile, user_homedir); PATH_CONCAT(rcfile, PLOTRC); plotrc = fopen(rcfile, "r"); } if (plotrc) { char *rc = gp_strdup(rcfile ? rcfile : PLOTRC); load_file(plotrc, rc, FALSE); push_terminal(0); /* needed if terminal or its options were changed */ } free(rcfile); }
/* may return NULL */ char * fontpath_fullname(const char *filename) { FILE *fp; char *fullname = NULL; #if defined(PIPES) if (*filename == '<') { os_error(NO_CARET, "fontpath_fullname: No Pipe allowed"); } else #endif /* PIPES */ if ((fp = fopen(filename, "r")) == (FILE *) NULL) { /* try 'fontpath' variable */ char *tmppath, *path = NULL; while ((tmppath = get_fontpath()) != NULL) { TBOOLEAN subdirs = FALSE; path = gp_strdup(tmppath); if (path[strlen(path) - 1] == '!') { path[strlen(path) - 1] = '\0'; subdirs = TRUE; } /* if */ fullname = recursivefullname(path, filename, subdirs); if (fullname != NULL) { while (get_fontpath()); free(path); break; } free(path); } } else fullname = gp_strdup(filename); return fullname; }
/* * Read commands from an initialization file. * where = 0: look for gnuplotrc in system shared directory * where = 1: look for .gnuplot in current directory * where = 2: look for .gnuplot in home directory */ static void load_rcfile(int where) { FILE *plotrc = NULL; char *rcfile = NULL; if (skip_gnuplotrc) return; if (where == 0) { #ifdef GNUPLOT_SHARE_DIR # if defined(_WIN32) || defined(MSDOS) || defined(OS2) rcfile = RelativePathToGnuplot(GNUPLOT_SHARE_DIR "\\gnuplotrc"); # else rcfile = (char *) gp_alloc(strlen(GNUPLOT_SHARE_DIR) + 1 + strlen("gnuplotrc") + 1, "rcfile"); strcpy(rcfile, GNUPLOT_SHARE_DIR); PATH_CONCAT(rcfile, "gnuplotrc"); # endif plotrc = fopen(rcfile, "r"); #endif } else if (where == 1) { #ifdef USE_CWDRC /* Allow check for a .gnuplot init file in the current directory */ /* This is a security risk, as someone might leave a malicious */ /* init file in a shared directory. */ plotrc = fopen(PLOTRC, "r"); #endif /* !USE_CWDRC */ } else if (where == 2 && user_homedir) { /* length of homedir + directory separator + length of file name + \0 */ int len = (user_homedir ? strlen(user_homedir) : 0) + 1 + strlen(PLOTRC) + 1; rcfile = gp_alloc(len, "rcfile"); strcpy(rcfile, user_homedir); PATH_CONCAT(rcfile, PLOTRC); plotrc = fopen(rcfile, "r"); } if (plotrc) { char *rc = gp_strdup(rcfile ? rcfile : PLOTRC); load_file(plotrc, rc, 3); push_terminal(0); /* needed if terminal or its options were changed */ } free(rcfile); }
/* lf_push is called from two different contexts: * load_file passes fp and file name (3rd param NULL) * do_string_and_free passes cmdline (1st and 2nd params NULL) * In either case the routines lf_push/lf_pop save and restore state * information that may be changed by executing commands from a file * or from the passed command line. */ void lf_push(FILE *fp, char *name, char *cmdline) { LFS *lf; int argindex; lf = (LFS *) gp_alloc(sizeof(LFS), (char *) NULL); if (lf == (LFS *) NULL) { if (fp != (FILE *) NULL) (void) fclose(fp); /* it won't be otherwise */ int_error(c_token, "not enough memory to load file"); } lf->fp = fp; /* save this file pointer */ lf->name = name; lf->cmdline = cmdline; lf->interactive = interactive; /* save current state */ lf->inline_num = inline_num; /* save current line number */ lf->call_argc = call_argc; /* Call arguments are irrelevant if invoked from do_string_and_free */ if (cmdline == NULL) { for (argindex = 0; argindex < 10; argindex++) { lf->call_args[argindex] = call_args[argindex]; call_args[argindex] = NULL; /* initially no args */ } } lf->depth = lf_head ? lf_head->depth+1 : 0; /* recursion depth */ if (lf->depth > STACK_DEPTH) int_error(NO_CARET, "load/eval nested too deeply"); lf->if_depth = if_depth; lf->if_open_for_else = if_open_for_else; lf->if_condition = if_condition; lf->c_token = c_token; lf->num_tokens = num_tokens; lf->tokens = gp_alloc((num_tokens+1) * sizeof(struct lexical_unit), "lf tokens"); memcpy(lf->tokens, token, (num_tokens+1) * sizeof(struct lexical_unit)); lf->input_line = gp_strdup(gp_input_line); lf->prev = lf_head; /* link to stack */ lf_head = lf; }
/******** The 'unset' command ********/ void unset_command() { int found_token; int save_token; c_token++; check_for_iteration(); found_token = lookup_table(&set_tbl[0],c_token); /* HBB 20000506: rationalize occurences of c_token++ ... */ if (found_token != S_INVALID) c_token++; save_token = c_token; ITERATE: switch(found_token) { case S_ANGLES: unset_angles(); break; case S_ARROW: unset_arrow(); break; case S_AUTOSCALE: unset_autoscale(); break; case S_BARS: unset_bars(); break; case S_BORDER: unset_border(); break; case S_BOXWIDTH: unset_boxwidth(); break; case S_CLABEL: unset_clabel(); break; case S_CLIP: unset_clip(); break; case S_CNTRPARAM: unset_cntrparam(); break; case S_CONTOUR: unset_contour(); break; case S_DGRID3D: unset_dgrid3d(); break; case S_DUMMY: unset_dummy(); break; case S_ENCODING: unset_encoding(); break; case S_DECIMALSIGN: unset_decimalsign(); break; case S_FIT: unset_fit(); break; case S_FORMAT: unset_format(); break; case S_GRID: unset_grid(); break; case S_HIDDEN3D: unset_hidden3d(); break; case S_HISTORYSIZE: unset_historysize(); break; case S_ISOSAMPLES: unset_isosamples(); break; case S_KEY: unset_key(); break; case S_KEYTITLE: unset_keytitle(); break; case S_LABEL: unset_label(); break; case S_LOADPATH: unset_loadpath(); break; case S_LOCALE: unset_locale(); break; case S_LOGSCALE: unset_logscale(); break; #ifdef GP_MACROS case S_MACROS: unset_macros(); break; #endif case S_MAPPING: unset_mapping(); break; case S_BMARGIN: unset_margin(&bmargin); break; case S_LMARGIN: unset_margin(&lmargin); break; case S_RMARGIN: unset_margin(&rmargin); break; case S_TMARGIN: unset_margin(&tmargin); break; case S_DATAFILE: if (almost_equals(c_token,"fort$ran")) { df_fortran_constants = FALSE; c_token++; break; } df_fortran_constants = FALSE; unset_missing(); df_separator = '\0'; free(df_commentschars); df_commentschars = gp_strdup(DEFAULT_COMMENTS_CHARS); df_unset_datafile_binary(); break; #ifdef USE_MOUSE case S_MOUSE: unset_mouse(); break; #endif case S_MULTIPLOT: /* unset_multiplot(); */ term_end_multiplot(); break; case S_OFFSETS: unset_offsets(); break; case S_ORIGIN: unset_origin(); break; case SET_OUTPUT: unset_output(); break; case S_PARAMETRIC: unset_parametric(); break; case S_PM3D: unset_pm3d(); break; case S_PALETTE: unset_palette(); break; case S_COLORBOX: unset_colorbox(); break; case S_POINTSIZE: unset_pointsize(); break; case S_POLAR: unset_polar(); break; case S_PRINT: unset_print(); break; #ifdef EAM_OBJECTS case S_OBJECT: unset_object(); break; #endif case S_SAMPLES: unset_samples(); break; case S_SIZE: unset_size(); break; case S_STYLE: unset_style(); break; case S_SURFACE: unset_surface(); break; case S_TABLE: unset_table(); break; case S_TERMINAL: unset_terminal(); break; case S_TICS: unset_tics(AXIS_ARRAY_SIZE); break; case S_TICSCALE: unset_ticscale(); break; case S_TICSLEVEL: case S_XYPLANE: unset_ticslevel(); break; case S_TIMEFMT: unset_timefmt(); break; case S_TIMESTAMP: unset_timestamp(); break; case S_TITLE: unset_axislabel_or_title(&title); break; case S_VIEW: unset_view(); break; case S_ZERO: unset_zero(); break; /* FIXME - are the tics correct? */ case S_MXTICS: unset_minitics(FIRST_X_AXIS); break; case S_XTICS: unset_tics(FIRST_X_AXIS); break; case S_XDTICS: case S_XMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MYTICS: unset_minitics(FIRST_Y_AXIS); break; case S_YTICS: unset_tics(FIRST_Y_AXIS); break; case S_YDTICS: case S_YMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MX2TICS: unset_minitics(SECOND_X_AXIS); break; case S_X2TICS: unset_tics(SECOND_X_AXIS); break; case S_X2DTICS: case S_X2MTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MY2TICS: unset_minitics(SECOND_Y_AXIS); break; case S_Y2TICS: unset_tics(SECOND_Y_AXIS); break; case S_Y2DTICS: case S_Y2MTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MZTICS: unset_minitics(FIRST_Z_AXIS); break; case S_ZTICS: unset_tics(FIRST_Z_AXIS); break; case S_ZDTICS: case S_ZMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MCBTICS: unset_minitics(COLOR_AXIS); break; case S_CBTICS: unset_tics(COLOR_AXIS); break; case S_CBDTICS: case S_CBMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_XDATA: unset_timedata(FIRST_X_AXIS); /* FIXME HBB 20000506: does unsetting these axes make *any* * sense? After all, their content is never displayed, so * what would they need a corrected format for? */ unset_timedata(T_AXIS); unset_timedata(U_AXIS); break; case S_YDATA: unset_timedata(FIRST_Y_AXIS); /* FIXME: see above */ unset_timedata(V_AXIS); break; case S_ZDATA: unset_timedata(FIRST_Z_AXIS); break; case S_CBDATA: unset_timedata(COLOR_AXIS); break; case S_X2DATA: unset_timedata(SECOND_X_AXIS); break; case S_Y2DATA: unset_timedata(SECOND_Y_AXIS); break; case S_XLABEL: unset_axislabel(FIRST_X_AXIS); break; case S_YLABEL: unset_axislabel(FIRST_Y_AXIS); break; case S_ZLABEL: unset_axislabel(FIRST_Z_AXIS); break; case S_CBLABEL: unset_axislabel(COLOR_AXIS); break; case S_X2LABEL: unset_axislabel(SECOND_X_AXIS); break; case S_Y2LABEL: unset_axislabel(SECOND_Y_AXIS); break; case S_XRANGE: unset_range(FIRST_X_AXIS); break; case S_X2RANGE: unset_range(SECOND_X_AXIS); break; case S_YRANGE: unset_range(FIRST_Y_AXIS); break; case S_Y2RANGE: unset_range(SECOND_Y_AXIS); break; case S_ZRANGE: unset_range(FIRST_Z_AXIS); break; case S_CBRANGE: unset_range(COLOR_AXIS); break; case S_RRANGE: unset_range(R_AXIS); break; case S_TRANGE: unset_range(T_AXIS); break; case S_URANGE: unset_range(U_AXIS); break; case S_VRANGE: unset_range(V_AXIS); break; case S_XZEROAXIS: unset_zeroaxis(FIRST_X_AXIS); break; case S_YZEROAXIS: unset_zeroaxis(FIRST_Y_AXIS); break; case S_ZZEROAXIS: unset_zeroaxis(FIRST_Z_AXIS); break; case S_X2ZEROAXIS: unset_zeroaxis(SECOND_X_AXIS); break; case S_Y2ZEROAXIS: unset_zeroaxis(SECOND_Y_AXIS); break; case S_ZEROAXIS: unset_all_zeroaxes(); break; case S_INVALID: default: int_error(c_token, "Unrecognized option. See 'help unset'."); break; } if (next_iteration()) { c_token = save_token; goto ITERATE; } /* FIXME - Should this be inside the iteration loop? */ update_gpval_variables(0); }
int main(int argc, char **argv) #endif { LPSTR tail; int i; #ifdef WGP_CONSOLE HINSTANCE hInstance = GetModuleHandle(NULL), hPrevInstance = NULL; #endif #ifndef WGP_CONSOLE # if defined( __MINGW32__) && !defined(_W64) # define argc _argc # define argv _argv # else /* MSVC, WATCOM, MINGW-W64 */ # define argc __argc # define argv __argv # endif #endif /* WGP_CONSOLE */ szModuleName = (LPSTR)malloc(MAXSTR+1); CheckMemory(szModuleName); /* get path to EXE */ GetModuleFileName(hInstance, (LPSTR) szModuleName, MAXSTR); if ((tail = (LPSTR)_fstrrchr(szModuleName,'\\')) != (LPSTR)NULL) { tail++; *tail = 0; } szModuleName = (LPSTR)realloc(szModuleName, _fstrlen(szModuleName)+1); CheckMemory(szModuleName); if (_fstrlen(szModuleName) >= 5 && _fstrnicmp(&szModuleName[_fstrlen(szModuleName)-5], "\\bin\\", 5) == 0) { int len = _fstrlen(szModuleName)-4; szPackageDir = (LPSTR)malloc(len+1); CheckMemory(szPackageDir); _fstrncpy(szPackageDir, szModuleName, len); szPackageDir[len] = '\0'; } else szPackageDir = szModuleName; #ifndef WGP_CONSOLE textwin.hInstance = hInstance; textwin.hPrevInstance = hPrevInstance; textwin.nCmdShow = nCmdShow; textwin.Title = "gnuplot"; #endif /* create structure of first graph window */ graphwin = (LPGW) calloc(1, sizeof(GW)); listgraphs = graphwin; /* locate ini file */ { char * inifile; get_user_env(); /* this hasn't been called yet */ inifile = gp_strdup("~\\wgnuplot.ini"); gp_expand_tilde(&inifile); /* if tilde expansion fails use current directory as default - that was the previous default behaviour */ if (inifile[0] == '~') { free(inifile); inifile = "wgnuplot.ini"; } #ifndef WGP_CONSOLE textwin.IniFile = inifile; #endif graphwin->IniFile = inifile; ReadMainIni(inifile, "WGNUPLOT"); } #ifndef WGP_CONSOLE textwin.IniSection = "WGNUPLOT"; textwin.DragPre = "load '"; textwin.DragPost = "'\n"; textwin.lpmw = &menuwin; textwin.ScreenSize.x = 80; textwin.ScreenSize.y = 80; textwin.KeyBufSize = 2048; textwin.CursorFlag = 1; /* scroll to cursor after \n & \r */ textwin.shutdown = MakeProcInstance((FARPROC)ShutDown, hInstance); textwin.AboutText = (LPSTR)malloc(1024); CheckMemory(textwin.AboutText); sprintf(textwin.AboutText, "Version %s patchlevel %s\n" \ "last modified %s\n" \ "%s\n%s, %s and many others\n" \ "gnuplot home: http://www.gnuplot.info\n", gnuplot_version, gnuplot_patchlevel, gnuplot_date, gnuplot_copyright, authors[1], authors[0]); textwin.AboutText = (LPSTR)realloc(textwin.AboutText, _fstrlen(textwin.AboutText)+1); CheckMemory(textwin.AboutText); menuwin.szMenuName = szMenuName; #endif pausewin.hInstance = hInstance; pausewin.hPrevInstance = hPrevInstance; pausewin.Title = "gnuplot pause"; graphwin->hInstance = hInstance; graphwin->hPrevInstance = hPrevInstance; #ifdef WGP_CONSOLE graphwin->lptw = NULL; #else graphwin->lptw = &textwin; #endif /* init common controls */ { INITCOMMONCONTROLSEX initCtrls; initCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX); initCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&initCtrls); } #ifndef WGP_CONSOLE if (TextInit(&textwin)) gp_exit(EXIT_FAILURE); textwin.hIcon = LoadIcon(hInstance, "TEXTICON"); SetClassLongPtr(textwin.hWndParent, GCLP_HICON, (LONG_PTR)textwin.hIcon); /* Note: we want to know whether this is an interactive session so that we can * decide whether or not to write status information to stderr. The old test * for this was to see if (argc > 1) but the addition of optional command line * switches broke this. What we really wanted to know was whether any of the * command line arguments are file names or an explicit in-line "-e command". * (This is a copy of a code snippet from plot.c) */ for (i = 1; i < argc; i++) { if (!stricmp(argv[i], "/noend")) continue; if ((argv[i][0] != '-') || (argv[i][1] == 'e')) { interactive = FALSE; break; } } if (interactive) ShowWindow(textwin.hWndParent, textwin.nCmdShow); if (IsIconic(textwin.hWndParent)) { /* update icon */ RECT rect; GetClientRect(textwin.hWndParent, (LPRECT) &rect); InvalidateRect(textwin.hWndParent, (LPRECT) &rect, 1); UpdateWindow(textwin.hWndParent); } # ifndef __WATCOMC__ /* Finally, also redirect C++ standard output streams. */ RedirectOutputStreams(TRUE); # endif #else /* WGP_CONSOLE */ #ifdef CONSOLE_SWITCH_CP /* Change codepage of console to match that of the graph window. WinExit() will revert this. Attention: display of characters does not work correctly with "Terminal" font! Users will have to use "Lucida Console" or similar. */ cp_input = GetConsoleCP(); cp_output = GetConsoleOutputCP(); if (cp_input != GetACP()) { cp_changed = TRUE; SetConsoleCP(GetACP()); /* keyboard input */ SetConsoleOutputCP(GetACP()); /* screen output */ SetFileApisToANSI(); /* file names etc. */ } #endif #endif gp_atexit(WinExit); if (!isatty(fileno(stdin))) setmode(fileno(stdin), O_BINARY); gnu_main(argc, argv); /* First chance to close help system for console gnuplot, second for wgnuplot */ WinCloseHelp(); gp_exit_cleanup(); return 0; }
static char * fn_completion(size_t anchor_pos, int direction) { static char * completions[MAX_COMPLETIONS]; static int n_completions = 0; static int completion_idx = 0; if (direction == 0) { /* new completion */ DIR * dir; char * start, * path; char * t, * search; char * name = NULL; size_t nlen; if (n_completions != 0) { /* new completion, cleanup first */ int i; for (i = 0; i < n_completions; i++) free(completions[i]); memset(completions, 0, sizeof(completions)); n_completions = 0; completion_idx = 0; } /* extract path to complete */ start = cur_line + anchor_pos; if (anchor_pos > 0) { /* first, look for a quote to start the string */ for ( ; start > cur_line; start--) { if ((*start == '"') || (*start == '\'')) { start++; break; } } /* if not found, search for a space instead */ if (start == cur_line) { for (start = cur_line + anchor_pos ; start > cur_line; start--) { if ((*start == ' ') || (*start == '!')) { start++; break; } } } path = strndup(start, cur_line - start + anchor_pos); gp_expand_tilde(&path); } else { path = gp_strdup(""); } /* seperate directory and (partial) file directory name */ t = strrchr(path, DIRSEP1); #if DIRSEP2 != NUL if (t == NULL) t = strrchr(path, DIRSEP2); #endif if (t == NULL) { /* name... */ search = gp_strdup("."); name = strdup(path); } else if (t == path) { /* root dir: /name... */ search = strndup(path, 1); nlen = cur_pos - (t - path) - 1; name = strndup(t + 1, nlen); } else { /* normal case: dir/dir/name... */ search = strndup(path, t - path); nlen = cur_pos - (t - path) - 1; name = strndup(t + 1, nlen); } nlen = strlen(name); free(path); n_completions = 0; if ((dir = opendir(search))) { struct dirent * entry; while ((entry = readdir(dir)) != NULL) { /* ignore files and directories starting with a dot */ if (entry->d_name[0] == '.') continue; /* skip entries which don't match */ if (nlen > 0) if (strncmp(entry->d_name, name, nlen) != 0) continue; completions[n_completions] = gp_strdup(entry->d_name + nlen); n_completions++; /* limit number of completions */ if (n_completions == MAX_COMPLETIONS) break; } closedir(dir); free(search); if (name) free(name); if (n_completions > 0) return completions[0]; else return NULL; } free(search); if (name) free(name); } else { /* cycle trough previous results */ if (n_completions > 0) { if (direction > 0) completion_idx = (completion_idx + 1) % n_completions; else completion_idx = (completion_idx + n_completions - 1) % n_completions; return completions[completion_idx]; } else return NULL; } return NULL; }
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 */ }
int main(int argc, char **argv) #endif { int i; #ifdef LINUXVGA LINUX_setup(); /* setup VGA before dropping privilege DBT 4/5/99 */ drop_privilege(); #endif /* make sure that we really have revoked root access, this might happen if gnuplot is compiled without vga support but is installed suid by mistake */ #ifdef __linux__ setuid(getuid()); #endif #if defined(MSDOS) && !defined(_Windows) && !defined(__GNUC__) PC_setup(); #endif /* MSDOS !Windows */ /* HBB: Seems this isn't needed any more for DJGPP V2? */ /* HBB: disable all floating point exceptions, just keep running... */ #if defined(DJGPP) && (DJGPP!=2) _control87(MCW_EM, MCW_EM); #endif #if defined(OS2) int rc; #ifdef OS2_IPC char semInputReadyName[40]; sprintf( semInputReadyName, "\\SEM32\\GP%i_Input_Ready", getpid() ); rc = DosCreateEventSem(semInputReadyName,&semInputReady,0,0); if (rc != 0) fputs("DosCreateEventSem error\n",stderr); #endif rc = RexxRegisterSubcomExe("GNUPLOT", (PFN) RexxInterface, NULL); #endif /* malloc large blocks, otherwise problems with fragmented mem */ #ifdef MALLOCDEBUG malloc_debug(7); #endif /* get helpfile from home directory */ #ifdef __DJGPP__ { char *s; strcpy(HelpFile, argv[0]); for (s = HelpFile; *s; s++) if (*s == DIRSEP1) *s = DIRSEP2; /* '\\' to '/' */ strcpy(strrchr(HelpFile, DIRSEP2), "/gnuplot.gih"); } /* Add also some "paranoid" tests for '\\': AP */ #endif /* DJGPP */ #ifdef VMS unsigned int status[2] = { 1, 0 }; #endif #if defined(HAVE_LIBEDITLINE) rl_getc_function = getc_wrapper; #endif #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE) /* T.Walter 1999-06-24: 'rl_readline_name' must be this fix name. * It is used to parse a 'gnuplot' specific section in '~/.inputrc' * or gnuplot specific commands in '.editrc' (when using editline * instead of readline) */ rl_readline_name = "Gnuplot"; rl_terminal_name = getenv("TERM"); using_history(); #endif #if defined(HAVE_LIBREADLINE) && !defined(MISSING_RL_TILDE_EXPANSION) rl_complete_with_tilde_expansion = 1; #endif for (i = 1; i < argc; i++) { if (!argv[i]) continue; if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) { printf("gnuplot %s patchlevel %s\n", gnuplot_version, gnuplot_patchlevel); return 0; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { printf( "Usage: gnuplot [OPTION]... [FILE]\n" #ifdef X11 "for X11 options see 'help X11->command-line-options'\n" #endif " -V, --version\n" " -h, --help\n" " -p --persist\n" " -e \"command1; command2; ...\"\n" "gnuplot %s patchlevel %s\n" #ifdef DIST_CONTACT "Report bugs to "DIST_CONTACT"\n" " or %s\n", #else "Report bugs to %s\n", #endif gnuplot_version, gnuplot_patchlevel, bug_email); return 0; } else if (!strncmp(argv[i], "-persist", 2) || !strcmp(argv[i], "--persist")) { persist_cl = TRUE; } } #ifdef X11 /* the X11 terminal removes tokens that it recognizes from argv. */ { int n = X11_args(argc, argv); argv += n; argc -= n; } #endif setbuf(stderr, (char *) NULL); #ifdef HAVE_SETVBUF /* this was once setlinebuf(). Docs say this is * identical to setvbuf(,NULL,_IOLBF,0), but MS C * faults this (size out of range), so we try with * size of 1024 instead. [SAS/C does that, too. -lh] * Failing this, I propose we just make the call and * ignore the return : its probably not a big deal */ if (setvbuf(stdout, (char *) NULL, _IOLBF, (size_t) 1024) != 0) (void) fputs("Could not linebuffer stdout\n", stderr); #ifdef X11 /* This call used to be in x11.trm, with the following comment: * Multi-character inputs like escape sequences but also mouse-pasted * text got buffered and therefore didn't trigger the select() function * in X11_waitforinput(). Switching to unbuffered input solved this. * 23 Jan 2002 (joze) * But switching to unbuffered mode causes all characters in the input * buffer to be lost. So the only safe time to do it is on program entry. * The #ifdef X11 is probably unnecessary, but makes the change minimal. * Do any non-X platforms suffer from the same problem? * EAM - Jan 2004. */ setvbuf(stdin, (char *) NULL, _IONBF, 0); #endif #endif gpoutfile = stdout; /* Initialize pre-loaded user variables */ (void) Gcomplex(&udv_pi.udv_value, M_PI, 0.0); udv_NaN = add_udv_by_name("NaN"); (void) Gcomplex(&(udv_NaN->udv_value), not_a_number(), 0.0); udv_NaN->udv_undef = FALSE; init_memory(); interactive = FALSE; init_terminal(); /* can set term type if it likes */ push_terminal(0); /* remember the default terminal */ /* reset the terminal when exiting */ /* this is done through gp_atexit so that other terminal functions * can be registered to be executed before the terminal is reset. */ GP_ATEXIT(term_reset); # if defined(_Windows) && ! defined(WGP_CONSOLE) interactive = TRUE; # else interactive = isatty(fileno(stdin)); # endif if (argc > 1) interactive = noinputfiles = FALSE; else noinputfiles = TRUE; /* Need this before show_version is called for the first time */ #ifdef HAVE_SYS_UTSNAME_H { struct utsname uts; /* something is fundamentally wrong if this fails ... */ if (uname(&uts) > -1) { # ifdef _AIX strcpy(os_name, uts.sysname); sprintf(os_name, "%s.%s", uts.version, uts.release); # elif defined(SCO) strcpy(os_name, "SCO"); strcpy(os_rel, uts.release); # elif defined(DJGPP) if (!strncmp(uts.sysname, "??Un", 4)) /* don't print ??Unknow" */ strcpy(os_name, "Unknown"); else { strcpy(os_name, uts.sysname); strcpy(os_rel, uts.release); } # else strcpy(os_name, uts.sysname); strcpy(os_rel, uts.release); # ifdef OS2 if (!strchr(os_rel,'.')) /* write either "2.40" or "4.0", or empty -- don't print "OS/2 1" */ strcpy(os_rel, ""); # endif # endif } } #else /* ! HAVE_SYS_UTSNAME_H */ strcpy(os_name, OS); strcpy(os_rel, ""); #endif /* HAVE_SYS_UTSNAME_H */ if (interactive) show_version(stderr); else show_version(NULL); /* Only load GPVAL_COMPILE_OPTIONS */ #ifdef WGP_CONSOLE #ifdef CONSOLE_SWITCH_CP if (cp_changed && interactive) { fprintf(stderr, "\ngnuplot changed the codepage of this console from %i to %i to\n" \ "match the graph window. Some characters might only display correctly\n" \ "if you change the font to a non-raster type.\n", cp_input, GetConsoleCP()); } #else if ((GetConsoleCP() != GetACP()) && interactive) { fprintf(stderr, "\nWarning: The codepage of the graph window (%i) and that of the\n" \ "console (%i) differ. Use `set encoding` or `!chcp` if extended\n" \ "characters don't display correctly.\n", GetACP(), GetConsoleCP()); } #endif #endif update_gpval_variables(3); /* update GPVAL_ variables available to user */ #ifdef VMS /* initialise screen management routines for command recall */ if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL) done(status[1]); if (status[1] = smg$create_key_table(&vms_ktid) != SS$_NORMAL) done(status[1]); #endif /* VMS */ if (!SETJMP(command_line_env, 1)) { /* first time */ interrupt_setup(); /* should move this stuff another initialisation routine, * something like init_set() maybe */ get_user_env(); init_loadpath(); init_locale(); /* HBB: make sure all variables start in the same mode 'reset' * would set them to. Since the axis variables aren't in * initialized arrays any more, this is now necessary... */ reset_command(); init_color(); /* Initialization of color */ load_rcfile(); init_fit(); /* Initialization of fitting module */ if (interactive && term != 0) { /* not unknown */ #ifdef GNUPLOT_HISTORY FPRINTF((stderr, "Before read_history\n")); #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE) expanded_history_filename = tilde_expand(GNUPLOT_HISTORY_FILE); #else expanded_history_filename = gp_strdup(GNUPLOT_HISTORY_FILE); gp_expand_tilde(&expanded_history_filename); #endif FPRINTF((stderr, "expanded_history_filename = %s\n", expanded_history_filename)); read_history(expanded_history_filename); { /* BEGIN: Go local to get environment variable */ const char *temp_env = getenv ("GNUPLOT_HISTORY_SIZE"); if (temp_env) gnuplot_history_size = strtol (temp_env, (char **) NULL, 10); } /* END: Go local to get environment variable */ /* * It is safe to ignore the return values of 'atexit()' and * 'on_exit()'. In the worst case, there is no history of your * currrent session and you have to type all again in your next * session. * This is the default behaviour (traditional reasons), too. * In case you don't have one of these functions, or you don't * want to use them, 'write_history()' is called directly. */ GP_ATEXIT(wrapper_for_write_history); #endif /* GNUPLOT_HISTORY */ fprintf(stderr, "\nTerminal type set to '%s'\n", term->name); } /* if (interactive && term != 0) */ } else { /* come back here from int_error() */ if (interactive == FALSE) exit_status = EXIT_FAILURE; #ifdef HAVE_READLINE_RESET else { /* reset properly readline after a SIGINT+longjmp */ rl_reset_after_signal (); } #endif load_file_error(); /* if we were in load_file(), cleanup */ SET_CURSOR_ARROW; #ifdef VMS /* after catching interrupt */ /* VAX stuffs up stdout on SIGINT while writing to stdout, so reopen stdout. */ if (gpoutfile == stdout) { if ((stdout = freopen("SYS$OUTPUT", "w", stdout)) == NULL) { /* couldn't reopen it so try opening it instead */ if ((stdout = fopen("SYS$OUTPUT", "w")) == NULL) { /* don't use int_error here - causes infinite loop! */ fputs("Error opening SYS$OUTPUT as stdout\n", stderr); } } gpoutfile = stdout; } #endif /* VMS */ if (!interactive && !noinputfiles) { term_reset(); exit(EXIT_FAILURE); /* exit on non-interactive error */ } } if (argc > 1) { #ifdef _Windows TBOOLEAN noend = persist_cl; #endif /* load filenames given as arguments */ while (--argc > 0) { ++argv; c_token = 0; #ifdef _Windows if (stricmp(*argv, "-noend") == 0 || stricmp(*argv, "/noend") == 0 || stricmp(*argv, "-persist") == 0) noend = TRUE; else #endif if (!strncmp(*argv, "-persist", 2) || !strcmp(*argv, "--persist")) { FPRINTF((stderr,"'persist' command line option recognized\n")); } else if (strcmp(*argv, "-") == 0) { interactive = TRUE; while (!com_line()); interactive = FALSE; } else if (strcmp(*argv, "-e") == 0) { --argc; ++argv; if (argc <= 0) { fprintf(stderr, "syntax: gnuplot -e \"commands\"\n"); return 0; } do_string(*argv); } else { load_file(loadpath_fopen(*argv, "r"), gp_strdup(*argv), FALSE); } } #ifdef _Windows if (noend) { interactive = TRUE; while (!com_line()); } #endif } else { /* take commands from stdin */ while (!com_line()); } #if (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)) && defined(GNUPLOT_HISTORY) #if !defined(HAVE_ATEXIT) && !defined(HAVE_ON_EXIT) /* You should be here if you neither have 'atexit()' nor 'on_exit()' */ wrapper_for_write_history(); #endif /* !HAVE_ATEXIT && !HAVE_ON_EXIT */ #endif /* (HAVE_LIBREADLINE || HAVE_LIBEDITLINE) && GNUPLOT_HISTORY */ #ifdef OS2 RexxDeregisterSubcom("GNUPLOT", NULL); #endif /* HBB 20040223: Not all compilers like exit() to end main() */ /* exit(exit_status); */ return exit_status; }
/* pop from load_file state stack FALSE if stack was empty called by load_file and load_file_error */ TBOOLEAN lf_pop() { LFS *lf; int argindex; struct udvt_entry *udv; if (lf_head == NULL) return (FALSE); lf = lf_head; if (lf->fp == NULL || lf->fp == stdin) /* Do not close stdin in the case that "-" is named as a load file */ ; #if defined(PIPES) else if (lf->name != NULL && lf->name[0] == '<') pclose(lf->fp); #endif else fclose(lf->fp); /* call arguments are not relevant when invoked from do_string_and_free */ if (lf->cmdline == NULL) { for (argindex = 0; argindex < 10; argindex++) { if (call_args[argindex]) free(call_args[argindex]); call_args[argindex] = lf->call_args[argindex]; } call_argc = lf->call_argc; /* Restore ARGC and ARG0 ... ARG9 */ if ((udv = get_udv_by_name("ARGC"))) { Ginteger(&(udv->udv_value), call_argc); } if ((udv = get_udv_by_name("ARG0"))) { gpfree_string(&(udv->udv_value)); Gstring(&(udv->udv_value), (lf->prev && lf->prev->name) ? gp_strdup(lf->prev->name) : gp_strdup("")); } for (argindex = 1; argindex <= 9; argindex++) { if ((udv = get_udv_by_name(argname[argindex]))) { gpfree_string(&(udv->udv_value)); Gstring(&(udv->udv_value), gp_strdup(call_args[argindex-1])); if (!call_args[argindex-1]) udv->udv_undef = TRUE; } } } interactive = lf->interactive; inline_num = lf->inline_num; add_udv_by_name("GPVAL_LINENO")->udv_value.v.int_val = inline_num; if_depth = lf->if_depth; if_condition = lf->if_condition; if_open_for_else = lf->if_open_for_else; /* Restore saved input state and free the copy */ if (lf->tokens) { num_tokens = lf->num_tokens; c_token = lf->c_token; assert(token_table_size >= lf->num_tokens+1); memcpy(token, lf->tokens, (lf->num_tokens+1) * sizeof(struct lexical_unit)); free(lf->tokens); } if (lf->input_line) { strcpy(gp_input_line, lf->input_line); free(lf->input_line); } free(lf->name); free(lf->cmdline); lf_head = lf->prev; free(lf); return (TRUE); }
static void prepare_call(int calltype) { struct udvt_entry *udv; int argindex; if (calltype == 2) { call_argc = 0; while (!END_OF_COMMAND && call_argc <= 9) { call_args[call_argc] = try_to_get_string(); if (!call_args[call_argc]) { int save_token = c_token; /* This catches call "file" STRINGVAR (expression) */ if (type_udv(c_token) == STRING) { call_args[call_argc] = gp_strdup(add_udv(c_token)->udv_value.v.string_val); c_token++; /* Evaluates a parenthesized expression and store the result in a string */ } else if (equals(c_token, "(")) { char val_as_string[32]; struct value a; const_express(&a); switch(a.type) { case CMPLX: /* FIXME: More precision? Some way to provide a format? */ sprintf(val_as_string, "%g", a.v.cmplx_val.real); call_args[call_argc] = gp_strdup(val_as_string); break; default: int_error(save_token, "Unrecognized argument type"); break; case INTGR: sprintf(val_as_string, "%d", a.v.int_val); call_args[call_argc] = gp_strdup(val_as_string); break; } /* old (pre version 5) style wrapping of bare tokens as strings */ /* is still useful for passing unquoted numbers */ } else { m_capture(&call_args[call_argc], c_token, c_token); c_token++; } } call_argc++; } lf_head->c_token = c_token; if (!END_OF_COMMAND) int_error(++c_token, "too many arguments for 'call <file>'"); } else if (calltype == 5) { /* lf_push() moved our call arguments from call_args[] to lf->call_args[] */ /* call_argc was determined at program entry */ for (argindex = 0; argindex < 10; argindex++) { call_args[argindex] = lf_head->call_args[argindex]; lf_head->call_args[argindex] = NULL; /* just to be safe */ } } else { /* "load" command has no arguments */ call_argc = 0; } /* Old-style "call" arguments were referenced as $0 ... $9 and $# */ /* New-style has ARG0 = script-name, ARG1 ... ARG9 and ARGC */ /* FIXME: If we defined these on entry, we could use get_udv* here */ udv = add_udv_by_name("ARGC"); Ginteger(&(udv->udv_value), call_argc); udv->udv_undef = FALSE; udv = add_udv_by_name("ARG0"); gpfree_string(&(udv->udv_value)); Gstring(&(udv->udv_value), gp_strdup(lf_head->name)); udv->udv_undef = FALSE; for (argindex = 1; argindex <= 9; argindex++) { char *arg = gp_strdup(call_args[argindex-1]); udv = add_udv_by_name(argname[argindex]); gpfree_string(&(udv->udv_value)); Gstring(&(udv->udv_value), arg ? arg : gp_strdup("")); udv->udv_undef = FALSE; } }
int main(int argc, char **argv) #endif { /*WNDCLASS wndclass;*/ LPSTR tail; #ifdef WGP_CONSOLE # define _argv argv # define _argc argc HINSTANCE hInstance = GetModuleHandle(NULL), hPrevInstance = NULL; #else #if defined(__MSC__) || defined(__WATCOMC__) # define _argv __argv # define _argc __argc #endif #endif /* WGP_CONSOLE */ szModuleName = (LPSTR)malloc(MAXSTR+1); CheckMemory(szModuleName); /* get path to EXE */ GetModuleFileName(hInstance, (LPSTR) szModuleName, MAXSTR); if ((tail = (LPSTR)_fstrrchr(szModuleName,'\\')) != (LPSTR)NULL) { tail++; *tail = 0; } szModuleName = (LPSTR)realloc(szModuleName, _fstrlen(szModuleName)+1); CheckMemory(szModuleName); if (_fstrlen(szModuleName) >= 5 && _fstrnicmp(&szModuleName[_fstrlen(szModuleName)-5], "\\bin\\", 5) == 0) { int len = _fstrlen(szModuleName)-4; szPackageDir = (LPSTR)malloc(len+1); CheckMemory(szPackageDir); _fstrncpy(szPackageDir, szModuleName, len); szPackageDir[len] = '\0'; } else szPackageDir = szModuleName; #ifndef WGP_CONSOLE textwin.hInstance = hInstance; textwin.hPrevInstance = hPrevInstance; textwin.nCmdShow = nCmdShow; textwin.Title = "gnuplot"; #endif /* create structure of first graph window */ graphwin = calloc(1, sizeof(GW)); listgraphs = graphwin; /* locate ini file */ { char * inifile; get_user_env(); /* this hasn't been called yet */ inifile = gp_strdup("~\\wgnuplot.ini"); gp_expand_tilde(&inifile); /* if tilde expansion fails use current directory as default - that was the previous default behaviour */ if (inifile[0] == '~') { free(inifile); inifile = "wgnuplot.ini"; } #ifndef WGP_CONSOLE textwin.IniFile = inifile; #endif graphwin->IniFile = inifile; ReadMainIni(inifile, "WGNUPLOT"); } #ifndef WGP_CONSOLE textwin.IniSection = "WGNUPLOT"; textwin.DragPre = "load '"; textwin.DragPost = "'\n"; textwin.lpmw = &menuwin; textwin.ScreenSize.x = 80; textwin.ScreenSize.y = 80; textwin.KeyBufSize = 2048; textwin.CursorFlag = 1; /* scroll to cursor after \n & \r */ textwin.shutdown = MakeProcInstance((FARPROC)ShutDown, hInstance); textwin.AboutText = (LPSTR)malloc(1024); CheckMemory(textwin.AboutText); sprintf(textwin.AboutText, "Version %s patchlevel %s\n" \ "last modified %s\n" \ "%s\n%s, %s and many others\n" \ "gnuplot home: http://www.gnuplot.info\n", gnuplot_version, gnuplot_patchlevel, gnuplot_date, gnuplot_copyright, authors[1], authors[0]); textwin.AboutText = (LPSTR)realloc(textwin.AboutText, _fstrlen(textwin.AboutText)+1); CheckMemory(textwin.AboutText); menuwin.szMenuName = szMenuName; #endif pausewin.hInstance = hInstance; pausewin.hPrevInstance = hPrevInstance; pausewin.Title = "gnuplot pause"; graphwin->hInstance = hInstance; graphwin->hPrevInstance = hPrevInstance; #ifdef WGP_CONSOLE graphwin->lptw = NULL; #else graphwin->lptw = &textwin; #endif /* init common controls */ { INITCOMMONCONTROLSEX initCtrls; initCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX); initCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&initCtrls); } #ifndef WGP_CONSOLE if (TextInit(&textwin)) exit(1); textwin.hIcon = LoadIcon(hInstance, "TEXTICON"); SetClassLong(textwin.hWndParent, GCL_HICON, (DWORD)textwin.hIcon); if (_argc>1) { int i,noend=FALSE; for (i=0; i<_argc; ++i) if (!stricmp(_argv[i],"-noend") || !stricmp(_argv[i],"/noend") || !stricmp(_argv[i],"-persist")) noend = TRUE; if (noend) ShowWindow(textwin.hWndParent, textwin.nCmdShow); } else ShowWindow(textwin.hWndParent, textwin.nCmdShow); if (IsIconic(textwin.hWndParent)) { /* update icon */ RECT rect; GetClientRect(textwin.hWndParent, (LPRECT) &rect); InvalidateRect(textwin.hWndParent, (LPRECT) &rect, 1); UpdateWindow(textwin.hWndParent); } #else /* WGP_CONSOLE */ #ifdef CONSOLE_SWITCH_CP /* Change codepage of console to match that of the graph window. WinExit() will revert this. Attention: display of characters does not work correctly with "Terminal" font! Users will have to use "Lucida Console" or similar. */ cp_input = GetConsoleCP(); cp_output = GetConsoleOutputCP(); if (cp_input != GetACP()) { cp_changed = TRUE; SetConsoleCP(GetACP()); /* keyboard input */ SetConsoleOutputCP(GetACP()); /* screen output */ SetFileApisToANSI(); /* file names etc. */ } #endif #endif atexit(WinExit); if (!isatty(fileno(stdin))) setmode(fileno(stdin), O_BINARY); gnu_main(_argc, _argv, environ); /* First chance to close help system for console gnuplot, second for wgnuplot */ WinCloseHelp(); return 0; }
void statsrequest(void) { int i; int columns; int columnsread; double v[2]; static char *file_name = NULL; /* Vars to hold data and results */ long n; /* number of records retained */ long max_n; static double *data_x = NULL; static double *data_y = NULL; /* values read from file */ long invalid; /* number of missing/invalid records */ long blanks; /* number of blank lines */ long doubleblanks; /* number of repeated blank lines */ long out_of_range; /* number pts rejected, because out of range */ struct file_stats res_file; struct sgl_column_stats res_x, res_y; struct two_column_stats res_xy; float *matrix; /* matrix data. This must be float. */ int nc, nr; /* matrix dimensions. */ int index; /* Vars for variable handling */ static char *prefix = NULL; /* prefix for user-defined vars names */ /* Vars that control output */ TBOOLEAN do_output = TRUE; /* Generate formatted output */ c_token++; /* Parse ranges */ AXIS_INIT2D(FIRST_X_AXIS, 0); AXIS_INIT2D(FIRST_Y_AXIS, 0); parse_range(FIRST_X_AXIS); parse_range(FIRST_Y_AXIS); /* Initialize */ columnsread = 2; invalid = 0; /* number of missing/invalid records */ blanks = 0; /* number of blank lines */ doubleblanks = 0; /* number of repeated blank lines */ out_of_range = 0; /* number pts rejected, because out of range */ n = 0; /* number of records retained */ nr = 0; /* Matrix dimensions */ nc = 0; max_n = INITIAL_DATA_SIZE; free(data_x); free(data_y); data_x = vec(max_n); /* start with max. value */ data_y = vec(max_n); if ( !data_x || !data_y ) int_error( NO_CARET, "Internal error: out of memory in stats" ); n = invalid = blanks = doubleblanks = out_of_range = nr = 0; /* Get filename */ free ( file_name ); file_name = try_to_get_string(); if ( !file_name ) int_error(c_token, "missing filename"); /* =========================================================== v923z: insertion for treating matrices EAM: only handles ascii matrix with uniform grid, and fails to apply any input data transforms =========================================================== */ if ( almost_equals(c_token, "mat$rix") ) { df_open(file_name, 3, NULL); index = df_num_bin_records - 1; /* We take these values as set by df_determine_matrix_info See line 1996 in datafile.c */ nc = df_bin_record[index].scan_dim[0]; nr = df_bin_record[index].scan_dim[1]; n = nc * nr; matrix = (float *)df_bin_record[index].memory_data; /* Fill up a vector, so that we can use the existing code. */ if ( !redim_vec(&data_x, n ) ) { int_error( NO_CARET, "Out of memory in stats: too many datapoints (%d)?", n ); } for( i=0; i < n; i++ ) { data_y[i] = (double)matrix[i]; } /* We can close the file here, there is nothing else to do */ df_close(); /* We will invoke single column statistics for the matrix */ columns = 1; } else { /* Not a matrix */ columns = df_open(file_name, 2, NULL); /* up to 2 using specs allowed */ if (columns < 0) int_error(NO_CARET, "Can't read data file"); if (columns > 2 ) int_error(c_token, "Need 0 to 2 using specs for stats command"); /* If the user has set an explicit locale for numeric input, apply it here so that it affects data fields read from the input file. */ /* v923z: where exactly should this be? here or before the matrix case? * I think, we should move everything here to before trying to open the file. * There is no point in trying to read anything, if the axis is logarithmic, e.g. */ set_numeric_locale(); /* For all these below: we could save the state, switch off, then restore */ if ( axis_array[FIRST_X_AXIS].log || axis_array[FIRST_Y_AXIS].log ) int_error( NO_CARET, "Stats command not available with logscale active"); if ( axis_array[FIRST_X_AXIS].datatype == DT_TIMEDATE || axis_array[FIRST_Y_AXIS].datatype == DT_TIMEDATE ) int_error( NO_CARET, "Stats command not available in timedata mode"); if ( polar ) int_error( NO_CARET, "Stats command not available in polar mode" ); if ( parametric ) int_error( NO_CARET, "Stats command not available in parametric mode" ); /* The way readline and friends work is as follows: - df_open will return the number of columns requested in the using spec so that "columns" will be 0, 1, or 2 (no using, using 1, using 1:2) - readline always returns the same number of columns (for us: 1 or 2) - using 1:2 = return two columns, skipping lines w/ bad data - using 1 = return sgl column (supply zeros (0) for the second col) - no using = return two columns (first two), fail on bad data We need to know how many columns to process. If columns==1 or ==2 (that is, if there was a using spec), all is clear and we use the value of columns. But: if columns is 0, then we need to figure out the number of cols read from the return value of readline. If readline ever returns 1, we take that; only if it always returns 2 do we assume two cols. */ while( (i = df_readline(v, 2)) != DF_EOF ) { columnsread = ( i > columnsread ? i : columnsread ); if ( n >= max_n ) { max_n = (max_n * 3) / 2; /* increase max_n by factor of 1.5 */ /* Some of the reallocations went bad: */ if ( 0 || !redim_vec(&data_x, max_n) || !redim_vec(&data_y, max_n) ) { df_close(); int_error( NO_CARET, "Out of memory in stats: too many datapoints (%d)?", max_n ); } } /* if (need to extend storage space) */ switch (i) { case DF_MISSING: case DF_UNDEFINED: /* Invalids are only recognized if the syntax is like this: stats "file" using ($1):($2) If the syntax is simply: stats "file" using 1:2 then df_readline simply skips invalid records (does not return anything!) Status: 2009-11-02 */ invalid += 1; continue; case DF_FIRST_BLANK: blanks += 1; continue; case DF_SECOND_BLANK: blanks += 1; doubleblanks += 1; continue; case 0: int_error( NO_CARET, "bad data on line %d of file %s", df_line_number, df_filename ? df_filename : "" ); break; case 1: /* Read single column successfully */ if ( validate_data(v[0], FIRST_Y_AXIS) ) { data_y[n] = v[0]; n++; } else { out_of_range++; } break; case 2: /* Read two columns successfully */ if ( validate_data(v[0], FIRST_X_AXIS) && validate_data(v[1], FIRST_Y_AXIS) ) { data_x[n] = v[0]; data_y[n] = v[1]; n++; } else { out_of_range++; } break; } } /* end-while : done reading file */ df_close(); /* now resize fields to actual length: */ redim_vec(&data_x, n); redim_vec(&data_y, n); /* figure out how many columns where really read... */ if ( columns == 0 ) columns = columnsread; } /* end of case when the data file is not a matrix */ /* Now finished reading user input; return to C locale for internal use*/ reset_numeric_locale(); /* PKJ - TODO: similar for logscale, polar/parametric, timedata */ /* No data! Try to explain why. */ if ( n == 0 ) { if ( out_of_range > 0 ) int_error( NO_CARET, "All points out of range" ); else int_error( NO_CARET, "No valid data points found in file" ); } /* Parse the remainder of the command line: 0 to 2 tokens possible */ while( !(END_OF_COMMAND) ) { if ( almost_equals( c_token, "out$put" ) ) { do_output = TRUE; c_token++; } else if ( almost_equals( c_token, "noout$put" ) ) { do_output = FALSE; c_token++; } else if ( almost_equals(c_token, "pre$fix") || equals(c_token, "name")) { c_token++; free ( prefix ); prefix = try_to_get_string(); if (!legal_identifier(prefix) || !strcmp ("GPVAL_", prefix)) int_error( --c_token, "illegal prefix" ); } else { int_error( c_token, "Expecting [no]output or prefix"); } } /* Set defaults if not explicitly set by user */ if (!prefix) prefix = gp_strdup("STATS_"); i = strlen(prefix); if (prefix[i-1] != '_') { prefix = gp_realloc(prefix, i+2, "prefix"); strcat(prefix,"_"); } /* Do the actual analysis */ res_file = analyze_file( n, out_of_range, invalid, blanks, doubleblanks ); if ( columns == 1 ) { res_y = analyze_sgl_column( data_y, n, nr ); } if ( columns == 2 ) { /* If there are two columns, then the data file is not a matrix */ res_x = analyze_sgl_column( data_x, n, 0 ); res_y = analyze_sgl_column( data_y, n, 0 ); res_xy = analyze_two_columns( data_x, data_y, res_x, res_y, n ); } /* Store results in user-accessible variables */ /* Clear out any previous use of these variables */ del_udv_by_name( prefix, TRUE ); file_variables( res_file, prefix ); if ( columns == 1 ) { sgl_column_variables( res_y, prefix, "" ); } if ( columns == 2 ) { sgl_column_variables( res_x, prefix, "_x" ); sgl_column_variables( res_y, prefix, "_y" ); two_column_variables( res_xy, prefix ); } /* Output */ if ( do_output ) { file_output( res_file ); if ( columns == 1 ) sgl_column_output( res_y, res_file.records ); else two_column_output( res_x, res_y, res_xy, res_file.records ); } /* Cleanup */ free(data_x); free(data_y); data_x = NULL; data_y = NULL; free( file_name ); file_name = NULL; free( prefix ); prefix = NULL; }
int main(int argc, char **argv) #endif { LPTSTR tail; #ifdef WGP_CONSOLE HINSTANCE hInstance = GetModuleHandle(NULL), hPrevInstance = NULL; #else int i; #endif #ifndef WGP_CONSOLE # if defined( __MINGW32__) && !defined(_W64) # define argc _argc # define argv _argv # else /* MSVC, WATCOM, MINGW-W64 */ # define argc __argc # define argv __argv # endif #endif /* WGP_CONSOLE */ szModuleName = (LPTSTR) malloc((MAXSTR + 1) * sizeof(TCHAR)); CheckMemory(szModuleName); /* get path to gnuplot executable */ GetModuleFileName(hInstance, szModuleName, MAXSTR); if ((tail = _tcsrchr(szModuleName, '\\')) != NULL) { tail++; *tail = 0; } szModuleName = (LPTSTR) realloc(szModuleName, (_tcslen(szModuleName) + 1) * sizeof(TCHAR)); CheckMemory(szModuleName); if (_tcslen(szModuleName) >= 5 && _tcsnicmp(&szModuleName[_tcslen(szModuleName)-5], TEXT("\\bin\\"), 5) == 0) { size_t len = _tcslen(szModuleName) - 4; szPackageDir = (LPTSTR) malloc((len + 1) * sizeof(TCHAR)); CheckMemory(szPackageDir); _tcsncpy(szPackageDir, szModuleName, len); szPackageDir[len] = NUL; } else { szPackageDir = szModuleName; } #ifndef WGP_CONSOLE textwin.hInstance = hInstance; textwin.hPrevInstance = hPrevInstance; textwin.nCmdShow = nCmdShow; textwin.Title = L"gnuplot"; #endif /* create structure of first graph window */ graphwin = (LPGW) calloc(1, sizeof(GW)); listgraphs = graphwin; /* locate ini file */ { char * inifile; #ifdef UNICODE LPWSTR winifile; #endif get_user_env(); /* this hasn't been called yet */ inifile = gp_strdup("~\\wgnuplot.ini"); gp_expand_tilde(&inifile); /* if tilde expansion fails use current directory as default - that was the previous default behaviour */ if (inifile[0] == '~') { free(inifile); inifile = "wgnuplot.ini"; } #ifdef UNICODE graphwin->IniFile = winifile = UnicodeText(inifile, S_ENC_DEFAULT); #else graphwin->IniFile = inifile; #endif #ifndef WGP_CONSOLE textwin.IniFile = graphwin->IniFile; #endif ReadMainIni(graphwin->IniFile, TEXT("WGNUPLOT")); } #ifndef WGP_CONSOLE textwin.IniSection = TEXT("WGNUPLOT"); textwin.DragPre = L"load '"; textwin.DragPost = L"'\n"; textwin.lpmw = &menuwin; textwin.ScreenSize.x = 80; textwin.ScreenSize.y = 80; textwin.KeyBufSize = 2048; textwin.CursorFlag = 1; /* scroll to cursor after \n & \r */ textwin.shutdown = MakeProcInstance((FARPROC)ShutDown, hInstance); textwin.AboutText = (LPTSTR) malloc(1024 * sizeof(TCHAR)); CheckMemory(textwin.AboutText); wsprintf(textwin.AboutText, TEXT("Version %hs patchlevel %hs\n") \ TEXT("last modified %hs\n") \ TEXT("%hs\n%hs, %hs and many others\n") \ TEXT("gnuplot home: http://www.gnuplot.info\n"), gnuplot_version, gnuplot_patchlevel, gnuplot_date, gnuplot_copyright, authors[1], authors[0]); textwin.AboutText = (LPTSTR) realloc(textwin.AboutText, (_tcslen(textwin.AboutText) + 1) * sizeof(TCHAR)); CheckMemory(textwin.AboutText); menuwin.szMenuName = szMenuName; #endif pausewin.hInstance = hInstance; pausewin.hPrevInstance = hPrevInstance; pausewin.Title = L"gnuplot pause"; graphwin->hInstance = hInstance; graphwin->hPrevInstance = hPrevInstance; #ifdef WGP_CONSOLE graphwin->lptw = NULL; #else graphwin->lptw = &textwin; #endif /* init common controls */ { INITCOMMONCONTROLSEX initCtrls; initCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX); initCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&initCtrls); } #ifndef WGP_CONSOLE if (TextInit(&textwin)) gp_exit(EXIT_FAILURE); textwin.hIcon = LoadIcon(hInstance, TEXT("TEXTICON")); SetClassLongPtr(textwin.hWndParent, GCLP_HICON, (LONG_PTR)textwin.hIcon); /* Note: we want to know whether this is an interactive session so that we can * decide whether or not to write status information to stderr. The old test * for this was to see if (argc > 1) but the addition of optional command line * switches broke this. What we really wanted to know was whether any of the * command line arguments are file names or an explicit in-line "-e command". * (This is a copy of a code snippet from plot.c) */ for (i = 1; i < argc; i++) { if (!_stricmp(argv[i], "/noend")) continue; if ((argv[i][0] != '-') || (argv[i][1] == 'e')) { interactive = FALSE; break; } } if (interactive) ShowWindow(textwin.hWndParent, textwin.nCmdShow); if (IsIconic(textwin.hWndParent)) { /* update icon */ RECT rect; GetClientRect(textwin.hWndParent, (LPRECT) &rect); InvalidateRect(textwin.hWndParent, (LPRECT) &rect, 1); UpdateWindow(textwin.hWndParent); } # ifndef __WATCOMC__ /* Finally, also redirect C++ standard output streams. */ RedirectOutputStreams(TRUE); # endif #else /* !WGP_CONSOLE */ # ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING # define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 # endif { /* Enable Windows 10 Console Virtual Terminal Sequences */ HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); DWORD mode; GetConsoleMode(handle, &mode); SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); } #endif gp_atexit(WinExit); if (!_isatty(_fileno(stdin))) _setmode(_fileno(stdin), O_BINARY); gnu_main(argc, argv); /* First chance to close help system for console gnuplot, second for wgnuplot */ WinCloseHelp(); gp_exit_cleanup(); return 0; }
/* * char *loadpath_handler (int, char *) * */ char * loadpath_handler(int action, char *path) { /* loadpath variable * the path elements are '\0' separated (!) * this way, reading out loadpath is very * easy to implement */ static char *loadpath; /* index pointer, end of loadpath, * env section of loadpath, current limit, in that order */ static char *p, *last, *envptr, *limit; #ifdef X11 char *appdir; #endif switch (action) { case ACTION_CLEAR: /* Clear loadpath, fall through to init */ FPRINTF((stderr, "Clear loadpath\n")); free(loadpath); loadpath = p = last = NULL; /* HBB 20000726: 'limit' has to be initialized to NULL, too! */ limit = NULL; case ACTION_INIT: /* Init loadpath from environment */ FPRINTF((stderr, "Init loadpath from environment\n")); assert(loadpath == NULL); if (!loadpath) { char *envlib = getenv("GNUPLOT_LIB"); if (envlib) { int len = strlen(envlib); loadpath = gp_strdup(envlib); /* point to end of loadpath */ last = loadpath + len; /* convert all PATHSEPs to \0 */ PATHSEP_TO_NUL(loadpath); } /* else: NULL = empty */ } /* else: already initialised; int_warn (?) */ /* point to env portion of loadpath */ envptr = loadpath; break; case ACTION_SET: /* set the loadpath */ FPRINTF((stderr, "Set loadpath\n")); if (path && *path != NUL) { /* length of env portion */ size_t elen = last - envptr; size_t plen = strlen(path); if (loadpath && envptr) { /* we are prepending a path name; because * realloc() preserves only the contents up * to the minimum of old and new size, we move * the part to be preserved to the beginning * of the string; use memmove() because strings * may overlap */ memmove(loadpath, envptr, elen + 1); } loadpath = gp_realloc(loadpath, elen + 1 + plen + 1, "expand loadpath"); /* now move env part back to the end to make space for * the new path */ memmove(loadpath + plen + 1, loadpath, elen + 1); strcpy(loadpath, path); /* separate new path(s) and env path(s) */ loadpath[plen] = PATHSEP; /* adjust pointer to env part and last */ envptr = &loadpath[plen+1]; last = envptr + elen; PATHSEP_TO_NUL(loadpath); } /* else: NULL = empty */ break; case ACTION_SHOW: /* print the current, full loadpath */ FPRINTF((stderr, "Show loadpath\n")); if (loadpath) { fputs("\tloadpath is ", stderr); PRINT_PATHLIST(loadpath, envptr); if (envptr) { /* env part */ fputs("\tloadpath from GNUPLOT_LIB is ", stderr); PRINT_PATHLIST(envptr, last); } } else fputs("\tloadpath is empty\n", stderr); #ifdef GNUPLOT_SHARE_DIR fprintf(stderr,"\tgnuplotrc is read from %s\n",GNUPLOT_SHARE_DIR); #endif #ifdef X11 if ((appdir = getenv("XAPPLRESDIR"))) { fprintf(stderr,"\tenvironmental path for X11 application defaults: \"%s\"\n", appdir); } #ifdef XAPPLRESDIR else { fprintf(stderr,"\tno XAPPLRESDIR found in the environment,\n"); fprintf(stderr,"\t falling back to \"%s\"\n", XAPPLRESDIR); } #endif #endif break; case ACTION_SAVE: /* we don't save the load path taken from the * environment, so don't go beyond envptr when * extracting the path elements */ limit = envptr; case ACTION_GET: /* subsequent calls to get_loadpath() return all * elements of the loadpath until exhausted */ FPRINTF((stderr, "Get loadpath\n")); if (!loadpath) return NULL; if (!p) { /* init section */ p = loadpath; if (!limit) limit = last; } else { /* skip over '\0' */ p += strlen(p) + 1; } if (p >= limit) limit = p = NULL; return p; break; case ACTION_NULL: /* just return */ default: break; } /* should always be ignored - points to the * first path in the list */ return loadpath; }
/******** The 'unset' command ********/ void unset_command() { int found_token; int save_token; int i; c_token++; set_iterator = check_for_iteration(); found_token = lookup_table(&set_tbl[0],c_token); /* HBB 20000506: rationalize occurences of c_token++ ... */ if (found_token != S_INVALID) c_token++; save_token = c_token; ITERATE: switch(found_token) { case S_ANGLES: unset_angles(); break; case S_ARROW: unset_arrow(); break; case S_AUTOSCALE: unset_autoscale(); break; case S_BARS: unset_bars(); break; case S_BORDER: unset_border(); break; case S_BOXWIDTH: unset_boxwidth(); break; case S_CLIP: unset_clip(); break; case S_CNTRPARAM: unset_cntrparam(); break; case S_CNTRLABEL: unset_cntrlabel(); break; case S_CLABEL: /* deprecated command */ clabel_onecolor = TRUE; break; case S_CONTOUR: unset_contour(); break; case S_DASHTYPE: unset_dashtype(); break; case S_DGRID3D: unset_dgrid3d(); break; case S_DUMMY: unset_dummy(); break; case S_ENCODING: unset_encoding(); break; case S_DECIMALSIGN: unset_decimalsign(); break; case S_FIT: unset_fit(); break; case S_FORMAT: c_token--; set_format(); break; case S_GRID: unset_grid(); break; case S_HIDDEN3D: unset_hidden3d(); break; case S_HISTORY: break; /* FIXME: reset to default values? */ case S_HISTORYSIZE: /* Deprecated */ unset_historysize(); break; case S_ISOSAMPLES: unset_isosamples(); break; case S_KEY: unset_key(); break; case S_LABEL: unset_label(); break; case S_LINETYPE: unset_linetype(); break; case S_LINK: c_token--; link_command(); break; case S_LOADPATH: unset_loadpath(); break; case S_LOCALE: unset_locale(); break; case S_LOGSCALE: unset_logscale(); break; case S_MACROS: /* Aug 2013 - macros are always enabled */ break; case S_MAPPING: unset_mapping(); break; case S_BMARGIN: unset_margin(&bmargin); break; case S_LMARGIN: unset_margin(&lmargin); break; case S_RMARGIN: unset_margin(&rmargin); break; case S_TMARGIN: unset_margin(&tmargin); break; case S_DATAFILE: if (almost_equals(c_token,"fort$ran")) { df_fortran_constants = FALSE; c_token++; break; } else if (almost_equals(c_token,"miss$ing")) { unset_missing(); c_token++; break; } else if (almost_equals(c_token,"sep$arators")) { free(df_separators); df_separators = NULL; c_token++; break; } else if (almost_equals(c_token,"com$mentschars")) { free(df_commentschars); df_commentschars = gp_strdup(DEFAULT_COMMENTS_CHARS); c_token++; break; } else if (almost_equals(c_token,"bin$ary")) { df_unset_datafile_binary(); c_token++; break; } else if (almost_equals(c_token,"nofpe_trap")) { df_nofpe_trap = FALSE; c_token++; break; } df_fortran_constants = FALSE; unset_missing(); free(df_separators); df_separators = NULL; free(df_commentschars); df_commentschars = gp_strdup(DEFAULT_COMMENTS_CHARS); df_unset_datafile_binary(); break; #ifdef USE_MOUSE case S_MOUSE: unset_mouse(); break; #endif case S_MULTIPLOT: term_end_multiplot(); break; case S_OFFSETS: unset_offsets(); break; case S_ORIGIN: unset_origin(); break; case SET_OUTPUT: unset_output(); break; case S_PARAMETRIC: unset_parametric(); break; case S_PM3D: unset_pm3d(); break; case S_PALETTE: unset_palette(); break; case S_COLORBOX: unset_colorbox(); break; case S_POINTINTERVALBOX: unset_pointintervalbox(); break; case S_POINTSIZE: unset_pointsize(); break; case S_POLAR: unset_polar(); break; case S_PRINT: unset_print(); break; case S_PSDIR: unset_psdir(); break; #ifdef EAM_OBJECTS case S_OBJECT: unset_object(); break; #endif case S_RTICS: unset_tics(POLAR_AXIS); break; case S_PAXIS: i = int_expression(); if (i <= 0 || i > MAX_PARALLEL_AXES) int_error(c_token, "expecting parallel axis number"); if (almost_equals(c_token, "tic$s")) { unset_tics(PARALLEL_AXES+i-1); c_token++; } break; case S_SAMPLES: unset_samples(); break; case S_SIZE: unset_size(); break; case S_STYLE: unset_style(); break; case S_SURFACE: unset_surface(); break; case S_TABLE: unset_table(); break; case S_TERMINAL: unset_terminal(); break; case S_TICS: unset_tics(ALL_AXES); break; case S_TICSCALE: int_warn(c_token, "Deprecated syntax - use 'set tics scale default'"); break; case S_TICSLEVEL: case S_XYPLANE: unset_ticslevel(); break; case S_TIMEFMT: unset_timefmt(); break; case S_TIMESTAMP: unset_timestamp(); break; case S_TITLE: unset_axislabel_or_title(&title); break; case S_VIEW: unset_view(); break; case S_ZERO: unset_zero(); break; /* FIXME - are the tics correct? */ case S_MXTICS: unset_minitics(FIRST_X_AXIS); break; case S_XTICS: unset_tics(FIRST_X_AXIS); break; case S_XDTICS: case S_XMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MYTICS: unset_minitics(FIRST_Y_AXIS); break; case S_YTICS: unset_tics(FIRST_Y_AXIS); break; case S_YDTICS: case S_YMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MX2TICS: unset_minitics(SECOND_X_AXIS); break; case S_X2TICS: unset_tics(SECOND_X_AXIS); break; case S_X2DTICS: case S_X2MTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MY2TICS: unset_minitics(SECOND_Y_AXIS); break; case S_Y2TICS: unset_tics(SECOND_Y_AXIS); break; case S_Y2DTICS: case S_Y2MTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MZTICS: unset_minitics(FIRST_Z_AXIS); break; case S_ZTICS: unset_tics(FIRST_Z_AXIS); break; case S_ZDTICS: case S_ZMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MCBTICS: unset_minitics(COLOR_AXIS); break; case S_CBTICS: unset_tics(COLOR_AXIS); break; case S_CBDTICS: case S_CBMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MRTICS: unset_minitics(POLAR_AXIS); break; case S_XDATA: unset_timedata(FIRST_X_AXIS); break; case S_YDATA: unset_timedata(FIRST_Y_AXIS); break; case S_ZDATA: unset_timedata(FIRST_Z_AXIS); break; case S_CBDATA: unset_timedata(COLOR_AXIS); break; case S_X2DATA: unset_timedata(SECOND_X_AXIS); break; case S_Y2DATA: unset_timedata(SECOND_Y_AXIS); break; case S_XLABEL: unset_axislabel(FIRST_X_AXIS); break; case S_YLABEL: unset_axislabel(FIRST_Y_AXIS); break; case S_ZLABEL: unset_axislabel(FIRST_Z_AXIS); break; case S_CBLABEL: unset_axislabel(COLOR_AXIS); break; case S_X2LABEL: unset_axislabel(SECOND_X_AXIS); break; case S_Y2LABEL: unset_axislabel(SECOND_Y_AXIS); break; case S_XRANGE: unset_range(FIRST_X_AXIS); break; case S_X2RANGE: unset_range(SECOND_X_AXIS); break; case S_YRANGE: unset_range(FIRST_Y_AXIS); break; case S_Y2RANGE: unset_range(SECOND_Y_AXIS); break; case S_ZRANGE: unset_range(FIRST_Z_AXIS); break; case S_CBRANGE: unset_range(COLOR_AXIS); break; case S_RRANGE: unset_range(POLAR_AXIS); break; case S_TRANGE: unset_range(T_AXIS); break; case S_URANGE: unset_range(U_AXIS); break; case S_VRANGE: unset_range(V_AXIS); break; case S_RAXIS: raxis = FALSE; c_token++; break; case S_XZEROAXIS: unset_zeroaxis(FIRST_X_AXIS); break; case S_YZEROAXIS: unset_zeroaxis(FIRST_Y_AXIS); break; case S_ZZEROAXIS: unset_zeroaxis(FIRST_Z_AXIS); break; case S_X2ZEROAXIS: unset_zeroaxis(SECOND_X_AXIS); break; case S_Y2ZEROAXIS: unset_zeroaxis(SECOND_Y_AXIS); break; case S_ZEROAXIS: unset_all_zeroaxes(); break; case S_INVALID: default: int_error(c_token, "Unrecognized option. See 'help unset'."); break; } if (next_iteration(set_iterator)) { c_token = save_token; goto ITERATE; } update_gpval_variables(0); set_iterator = cleanup_iteration(set_iterator); }
int main(int argc_orig, char **argv) #endif { int i; /* We want the current value of argc to persist across a LONGJMP from int_error(). * Without this the compiler may put it on the stack, which LONGJMP clobbers. * Here we try make it a volatile variable that optimization will not affect. * Why do we not have to do the same for argv? I don't know. * But the test cases that broke with generic argc seem fine with generic argv. */ static volatile int argc; argc = argc_orig; #ifdef LINUXVGA LINUX_setup(); /* setup VGA before dropping privilege DBT 4/5/99 */ drop_privilege(); #endif /* make sure that we really have revoked root access, this might happen if gnuplot is compiled without vga support but is installed suid by mistake */ #ifdef __linux__ if (setuid(getuid()) != 0) { fprintf(stderr,"gnuplot: refusing to run at elevated privilege\n"); exit(EXIT_FAILURE); } #endif /* HBB: Seems this isn't needed any more for DJGPP V2? */ /* HBB: disable all floating point exceptions, just keep running... */ #if defined(DJGPP) && (DJGPP!=2) _control87(MCW_EM, MCW_EM); #endif #if defined(OS2) { int rc; #ifdef OS2_IPC char semInputReadyName[40]; sprintf(semInputReadyName, "\\SEM32\\GP%i_Input_Ready", getpid()); rc = DosCreateEventSem(semInputReadyName, &semInputReady, 0, 0); if (rc != 0) fputs("DosCreateEventSem error\n", stderr); #endif rc = RexxRegisterSubcomExe("GNUPLOT", (PFN) RexxInterface, NULL); } #endif /* malloc large blocks, otherwise problems with fragmented mem */ #ifdef MALLOCDEBUG malloc_debug(7); #endif /* init progpath and get helpfile from executable directory */ #if defined(MSDOS) || defined(OS2) { char *s; #ifdef __EMX__ _execname(progpath, sizeof(progpath)); #else safe_strncpy(progpath, argv[0], sizeof(progpath)); #endif /* convert '/' to '\\' */ for (s = progpath; *s != NUL; s++) if (*s == DIRSEP2) *s = DIRSEP1; /* cut program name */ s = strrchr(progpath, DIRSEP1); if (s != NULL) s++; else s = progpath; *s = NUL; /* init HelpFile */ strcpy(HelpFile, progpath); strcat(HelpFile, "gnuplot.gih"); /* remove trailing "bin/" from progpath */ if ((s != NULL) && (s - progpath >= 4)) { s -= 4; if (strncasecmp(s, "bin", 3) == 0) *s = NUL; } } #endif /* DJGPP */ #if (defined(PIPE_IPC) || defined(_WIN32)) && (defined(HAVE_LIBREADLINE) || (defined(HAVE_LIBEDITLINE) && defined(X11))) /* Editline needs this to be set before the very first call to readline(). */ /* Support for rl_getc_function is broken for utf-8 in editline. Since it is only really required for X11, disable this section when building without X11. */ rl_getc_function = getc_wrapper; #endif #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE) /* T.Walter 1999-06-24: 'rl_readline_name' must be this fix name. * It is used to parse a 'gnuplot' specific section in '~/.inputrc' * or gnuplot specific commands in '.editrc' (when using editline * instead of readline) */ rl_readline_name = "Gnuplot"; rl_terminal_name = getenv("TERM"); #if defined(HAVE_LIBREADLINE) using_history(); #else history_init(); #endif #endif #if defined(HAVE_LIBREADLINE) && !defined(MISSING_RL_TILDE_EXPANSION) rl_complete_with_tilde_expansion = 1; #endif for (i = 1; i < argc; i++) { if (!argv[i]) continue; if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) { printf("gnuplot %s patchlevel %s\n", gnuplot_version, gnuplot_patchlevel); return 0; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { printf( "Usage: gnuplot [OPTION] ... [FILE]\n" #ifdef X11 "for X11 options see 'help X11->command-line-options'\n" #endif " -V, --version\n" " -h, --help\n" " -p --persist\n" " -s --slow\n" " -d --default-settings\n" " -c scriptfile ARG1 ARG2 ... \n" " -e \"command1; command2; ...\"\n" "gnuplot %s patchlevel %s\n", gnuplot_version, gnuplot_patchlevel); #ifdef DEVELOPMENT_VERSION printf( #ifdef DIST_CONTACT "Report bugs to "DIST_CONTACT"\n" " or %s\n", #else "Report bugs to %s\n", #endif bug_email); #endif return 0; } else if (!strncmp(argv[i], "-persist", 2) || !strcmp(argv[i], "--persist") #ifdef _WIN32 || !stricmp(argv[i], "-noend") || !stricmp(argv[i], "/noend") #endif ) { persist_cl = TRUE; } else if (!strncmp(argv[i], "-slow", 2) || !strcmp(argv[i], "--slow")) { slow_font_startup = TRUE; } else if (!strncmp(argv[i], "-d", 2) || !strcmp(argv[i], "--default-settings")) { /* Skip local customization read from ~/.gnuplot */ skip_gnuplotrc = TRUE; } } #ifdef X11 /* the X11 terminal removes tokens that it recognizes from argv. */ { int n = X11_args(argc, argv); argv += n; argc -= n; } #endif setbuf(stderr, (char *) NULL); #ifdef HAVE_SETVBUF /* This was once setlinebuf(). Docs say this is * identical to setvbuf(,NULL,_IOLBF,0), but MS C * faults this (size out of range), so we try with * size of 1024 instead. [SAS/C does that, too. -lh] */ if (setvbuf(stdout, (char *) NULL, _IOLBF, (size_t) 1024) != 0) (void) fputs("Could not linebuffer stdout\n", stderr); /* Switching to unbuffered mode causes all characters in the input * buffer to be lost. So the only safe time to do it is on program entry. * Do any non-X platforms suffer from this problem? * EAM - Jan 2013 YES. */ setvbuf(stdin, (char *) NULL, _IONBF, 0); #endif gpoutfile = stdout; /* Initialize pre-loaded user variables */ /* "pi" is hard-wired as the first variable */ (void) add_udv_by_name("GNUTERM"); (void) add_udv_by_name("NaN"); init_constants(); udv_user_head = &(udv_NaN->next_udv); init_memory(); interactive = FALSE; /* April 2017: We used to call init_terminal() here, but now */ /* We defer initialization until error handling has been set up. */ # if defined(_WIN32) && !defined(WGP_CONSOLE) interactive = TRUE; # else interactive = isatty(fileno(stdin)); # endif /* Note: we want to know whether this is an interactive session so that we can * decide whether or not to write status information to stderr. The old test * for this was to see if (argc > 1) but the addition of optional command line * switches broke this. What we really wanted to know was whether any of the * command line arguments are file names or an explicit in-line "-e command". */ for (i = 1; i < argc; i++) { # ifdef _WIN32 if (!stricmp(argv[i], "/noend")) continue; # endif if ((argv[i][0] != '-') || (argv[i][1] == 'e') || (argv[i][1] == 'c') ) { interactive = FALSE; break; } } /* Need this before show_version is called for the first time */ if (interactive) show_version(stderr); else show_version(NULL); /* Only load GPVAL_COMPILE_OPTIONS */ update_gpval_variables(3); /* update GPVAL_ variables available to user */ #ifdef VMS /* initialise screen management routines for command recall */ { unsigned int ierror; if (ierror = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL) done(ierror); if (ierror = smg$create_key_table(&vms_ktid) != SS$_NORMAL) done(ierror); } #endif /* VMS */ if (!SETJMP(command_line_env, 1)) { /* first time */ interrupt_setup(); get_user_env(); init_loadpath(); init_locale(); memset(&sm_palette, 0, sizeof(sm_palette)); init_fit(); /* Initialization of fitting module */ #ifdef READLINE /* When using the built-in readline, we set the initial encoding according to the locale as this is required to properly handle keyboard input. */ init_encoding(); #endif init_gadgets(); /* April 2017: Now that error handling is in place, it is safe parse * GNUTERM during terminal initialization. * atexit processing is done in reverse order. We want * the generic terminal shutdown in term_reset to be executed before * any terminal specific cleanup requested by individual terminals. */ init_terminal(); push_terminal(0); /* remember the initial terminal */ gp_atexit(term_reset); /* Execute commands in ~/.gnuplot */ init_session(); if (interactive && term != 0) { /* not unknown */ #ifdef GNUPLOT_HISTORY #if (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)) && !defined(_WIN32) expanded_history_filename = tilde_expand(GNUPLOT_HISTORY_FILE); #else expanded_history_filename = gp_strdup(GNUPLOT_HISTORY_FILE); gp_expand_tilde(&expanded_history_filename); #endif read_history(expanded_history_filename); /* * It is safe to ignore the return values of 'atexit()' and * 'on_exit()'. In the worst case, there is no history of your * currrent session and you have to type all again in your next * session. */ gp_atexit(wrapper_for_write_history); #endif /* GNUPLOT_HISTORY */ #if defined(READLINE) && defined(WGP_CONSOLE) fprintf(stderr, "Encoding set to '%s'.\n", encoding_names[encoding]); #endif } /* if (interactive && term != 0) */ } else { /* come back here from int_error() */ if (!successful_initialization) { /* Only print the warning once */ successful_initialization = TRUE; fprintf(stderr,"WARNING: Error during initialization\n\n"); } if (interactive == FALSE) exit_status = EXIT_FAILURE; #ifdef HAVE_READLINE_RESET else { /* reset properly readline after a SIGINT+longjmp */ rl_reset_after_signal (); } #endif load_file_error(); /* if we were in load_file(), cleanup */ SET_CURSOR_ARROW; #ifdef VMS /* after catching interrupt */ /* VAX stuffs up stdout on SIGINT while writing to stdout, so reopen stdout. */ if (gpoutfile == stdout) { if ((stdout = freopen("SYS$OUTPUT", "w", stdout)) == NULL) { /* couldn't reopen it so try opening it instead */ if ((stdout = fopen("SYS$OUTPUT", "w")) == NULL) { /* don't use int_error here - causes infinite loop! */ fputs("Error opening SYS$OUTPUT as stdout\n", stderr); } } gpoutfile = stdout; } #endif /* VMS */ /* Why a goto? Because we exited the loop below via int_error */ /* using LONGJMP. The compiler was not expecting this, and */ /* "optimized" the handling of argc and argv such that simply */ /* entering the loop again from the top finds them messed up. */ /* If we reenter the loop via a goto then there is some hope */ /* that code reordering does not hurt us. */ if (reading_from_dash && interactive) goto RECOVER_FROM_ERROR_IN_DASH; reading_from_dash = FALSE; if (!interactive && !noinputfiles) { term_reset(); gp_exit(EXIT_FAILURE); /* exit on non-interactive error */ } } /* load filenames given as arguments */ while (--argc > 0) { ++argv; c_token = 0; if (!strncmp(*argv, "-persist", 2) || !strcmp(*argv, "--persist") #ifdef _WIN32 || !stricmp(*argv, "-noend") || !stricmp(*argv, "/noend") #endif ) { FPRINTF((stderr,"'persist' command line option recognized\n")); } else if (strcmp(*argv, "-") == 0) { #if defined(_WIN32) && !defined(WGP_CONSOLE) TextShow(&textwin); interactive = TRUE; #else interactive = isatty(fileno(stdin)); #endif RECOVER_FROM_ERROR_IN_DASH: reading_from_dash = TRUE; while (!com_line()); reading_from_dash = FALSE; interactive = FALSE; noinputfiles = FALSE; } else if (strcmp(*argv, "-e") == 0) { int save_state = interactive; --argc; ++argv; if (argc <= 0) { fprintf(stderr, "syntax: gnuplot -e \"commands\"\n"); return 0; } interactive = FALSE; noinputfiles = FALSE; do_string(*argv); interactive = save_state; } else if (!strncmp(*argv, "-slow", 2) || !strcmp(*argv, "--slow")) { slow_font_startup = TRUE; } else if (!strncmp(*argv, "-d", 2) || !strcmp(*argv, "--default-settings")) { /* Ignore this; it already had its effect */ FPRINTF((stderr, "ignoring -d\n")); } else if (strcmp(*argv, "-c") == 0) { /* Pass command line arguments to the gnuplot script in the next * argument. This consumes the remainder of the command line */ interactive = FALSE; noinputfiles = FALSE; --argc; ++argv; if (argc <= 0) { fprintf(stderr, "syntax: gnuplot -c scriptname args\n"); gp_exit(EXIT_FAILURE); } call_argc = GPMIN(9, argc - 1); for (i=0; i<=call_argc; i++) { /* Need to stash argv[i] somewhere visible to load_file() */ call_args[i] = gp_strdup(argv[i+1]); } load_file(loadpath_fopen(*argv, "r"), gp_strdup(*argv), 5); gp_exit(EXIT_SUCCESS); } else if (*argv[0] == '-') { fprintf(stderr, "unrecognized option %s\n", *argv); } else { interactive = FALSE; noinputfiles = FALSE; load_file(loadpath_fopen(*argv, "r"), gp_strdup(*argv), 4); } } /* take commands from stdin */ if (noinputfiles) { while (!com_line()) ctrlc_flag = FALSE; /* reset asynchronous Ctrl-C flag */ } #ifdef _WIN32 /* On Windows, handle 'persist' by keeping the main input loop running (windows/wxt), */ /* but only if there are any windows open. Note that qt handles this properly. */ if (persist_cl) { if (WinAnyWindowOpen()) { #ifdef WGP_CONSOLE if (!interactive) { /* no further input from pipe */ while (WinAnyWindowOpen()) win_sleep(100); } else #endif { interactive = TRUE; while (!com_line()) ctrlc_flag = FALSE; /* reset asynchronous Ctrl-C flag */ interactive = FALSE; } } } #endif #if (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)) && defined(GNUPLOT_HISTORY) #if !defined(HAVE_ATEXIT) && !defined(HAVE_ON_EXIT) /* You should be here if you neither have 'atexit()' nor 'on_exit()' */ wrapper_for_write_history(); #endif /* !HAVE_ATEXIT && !HAVE_ON_EXIT */ #endif /* (HAVE_LIBREADLINE || HAVE_LIBEDITLINE) && GNUPLOT_HISTORY */ #ifdef OS2 RexxDeregisterSubcom("GNUPLOT", NULL); #endif /* HBB 20040223: Not all compilers like exit() to end main() */ /* exit(exit_status); */ #if ! defined(_WIN32) /* Windows does the cleanup later */ gp_exit_cleanup(); #endif return exit_status; }
/* * char *fontpath_handler (int, char *) * */ char * fontpath_handler(int action, char *path) { /* fontpath variable * the path elements are '\0' separated (!) * this way, reading out fontpath is very * easy to implement */ static char *fontpath; /* index pointer, end of fontpath, * env section of fontpath, current limit, in that order */ static char *p, *last, *envptr, *limit; if (!fontpath_init_done) { fontpath_init_done = TRUE; init_fontpath(); } switch (action) { case ACTION_CLEAR: /* Clear fontpath, fall through to init */ FPRINTF((stderr, "Clear fontpath\n")); free(fontpath); fontpath = p = last = NULL; /* HBB 20000726: 'limit' has to be initialized to NULL, too! */ limit = NULL; case ACTION_INIT: /* Init fontpath from environment */ FPRINTF((stderr, "Init fontpath from environment\n")); assert(fontpath == NULL); if (!fontpath) { char *envlib = getenv("GNUPLOT_FONTPATH"); if (envlib) { /* get paths from environment */ int len = strlen(envlib); fontpath = gp_strdup(envlib); /* point to end of fontpath */ last = fontpath + len; /* convert all PATHSEPs to \0 */ PATHSEP_TO_NUL(fontpath); } #if defined(HAVE_DIRENT_H) || defined(_Windows) else { /* set hardcoded paths */ const struct path_table *curr_fontpath = fontpath_tbl; while (curr_fontpath->dir) { char *currdir = NULL; char *envbeg = NULL; # if defined(PIPES) char *cmdbeg = NULL; # endif TBOOLEAN subdirs = FALSE; currdir = gp_strdup( curr_fontpath->dir ); while ( (envbeg=strstr(currdir, "$(")) # if defined(PIPES) || (cmdbeg=strstr( currdir, "$`" )) # endif ) { /* Read environment variables */ if (envbeg) { char *tmpdir = NULL; char *envend = NULL, *envval = NULL; unsigned int envlen; envend = strchr(envbeg+2,')'); envend[0] = '\0'; envval = getenv(envbeg+2); envend[0] = ')'; envlen = envval ? strlen(envval) : 0; tmpdir = gp_alloc(strlen(currdir)+envlen +envbeg-envend+1, "expand fontpath"); strncpy(tmpdir,currdir,envbeg-currdir); if (envval) strcpy(tmpdir+(envbeg-currdir),envval); strcpy(tmpdir+(envbeg-currdir+envlen), envend+1); free(currdir); currdir = tmpdir; } # if defined(PIPES) /* Read environment variables */ else if (cmdbeg) { char *tmpdir = NULL; char *envend = NULL; char envval[256]; unsigned int envlen; FILE *fcmd; envend = strchr(cmdbeg+2,'`'); envend[0] = '\0'; restrict_popen(); fcmd = popen(cmdbeg+2,"r"); if (fcmd) { fgets(envval,255,fcmd); if (envval[strlen(envval)-1]=='\n') envval[strlen(envval)-1]='\0'; pclose(fcmd); } envend[0] = '`'; envlen = strlen(envval); tmpdir = gp_alloc(strlen(currdir)+envlen +cmdbeg-envend+1, "expand fontpath"); strncpy(tmpdir,currdir,cmdbeg-currdir); if (*envval) strcpy(tmpdir+(cmdbeg-currdir),envval); strcpy(tmpdir+(cmdbeg-currdir+envlen), envend+1); free(currdir); currdir = tmpdir; } # endif } if ( currdir[strlen(currdir)-1] == '!' ) { /* search subdirectories */ /* delete ! from directory name */ currdir[strlen(currdir)-1] = '\0'; subdirs = TRUE; } if ( existdir( currdir ) ) { size_t plen; if ( subdirs ) /* add ! to directory name again */ currdir[strlen(currdir)] = '!'; plen = strlen(currdir); if (fontpath) { size_t elen = strlen(fontpath); fontpath = gp_realloc(fontpath, elen + 1 + plen + 1, "expand fontpath"); last = fontpath+elen; *last = PATHSEP; ++last; *last = '\0'; } else { fontpath = gp_alloc(plen + 1, "expand fontpath"); last = fontpath; } strcpy(last, currdir ); last += plen; } curr_fontpath++; if (currdir) { free(currdir); currdir = NULL; } } /* convert all PATHSEPs to \0 */ if (fontpath) PATHSEP_TO_NUL(fontpath); } #endif /* HAVE_DIRENT_H */ } /* else: already initialised; int_warn (?) */ /* point to env portion of fontpath */ envptr = fontpath; break; case ACTION_SET: /* set the fontpath */ FPRINTF((stderr, "Set fontpath\n")); if (path && *path != NUL) { /* length of env portion */ size_t elen = last - envptr; size_t plen = strlen(path); if (fontpath && envptr) { /* we are prepending a path name; because * realloc() preserves only the contents up * to the minimum of old and new size, we move * the part to be preserved to the beginning * of the string; use memmove() because strings * may overlap */ memmove(fontpath, envptr, elen + 1); } fontpath = gp_realloc(fontpath, elen + 1 + plen + 1, "expand fontpath"); /* now move env part back to the end to make space for * the new path */ memmove(fontpath + plen + 1, fontpath, elen + 1); strcpy(fontpath, path); /* separate new path(s) and env path(s) */ fontpath[plen] = PATHSEP; /* adjust pointer to env part and last */ envptr = &fontpath[plen+1]; last = envptr + elen; PATHSEP_TO_NUL(fontpath); } /* else: NULL = empty */ break; case ACTION_SHOW: /* print the current, full fontpath */ FPRINTF((stderr, "Show fontpath\n")); if (fontpath) { fputs("\tfontpath is ", stderr); PRINT_PATHLIST(fontpath, envptr); if (envptr) { /* env part */ fputs("\tsystem fontpath is ", stderr); PRINT_PATHLIST(envptr, last); } } else fputs("\tfontpath is empty\n", stderr); break; case ACTION_SAVE: /* we don't save the font path taken from the * environment, so don't go beyond envptr when * extracting the path elements */ limit = envptr; case ACTION_GET: /* subsequent calls to get_fontpath() return all * elements of the fontpath until exhausted */ FPRINTF((stderr, "Get fontpath\n")); if (!fontpath) return NULL; if (!p) { /* init section */ p = fontpath; if (!limit) limit = last; } else { /* skip over '\0' */ p += strlen(p) + 1; } if (p >= limit) limit = p = NULL; return p; case ACTION_NULL: /* just return */ default: break; } /* should always be ignored - points to the * first path in the list */ return fontpath; }
int parse_dashtype(struct t_dashtype *dt) { int res = DASHTYPE_SOLID; int j = 0; int k = 0; char *dash_str = NULL; /* Erase any previous contents */ memset(dt, 0, sizeof(struct t_dashtype)); /* Fill in structure based on keyword ... */ if (equals(c_token, "solid")) { res = DASHTYPE_SOLID; c_token++; /* Or numerical pattern consisting of pairs solid,empty,solid,empty... */ } else if (equals(c_token, "(")) { c_token++; while (!END_OF_COMMAND) { if (j >= DASHPATTERN_LENGTH) { int_error(c_token, "too many pattern elements"); } dt->pattern[j++] = real_expression(); /* The solid portion */ if (!equals(c_token++, ",")) int_error(c_token, "expecting comma"); dt->pattern[j++] = real_expression(); /* The empty portion */ if (equals(c_token, ")")) break; if (!equals(c_token++, ",")) int_error(c_token, "expecting comma"); } if (!equals(c_token, ")")) int_error(c_token, "expecting , or )"); c_token++; res = DASHTYPE_CUSTOM; /* Or string representing pattern elements ... */ } else if ((dash_str = try_to_get_string())) { #define DSCALE 10. while (dash_str[j] && (k < DASHPATTERN_LENGTH || dash_str[j] == ' ')) { /* . Dot with short space * - Dash with regular space * _ Long dash with regular space * space Don't add new dash, just increase last space */ switch (dash_str[j]) { case '.': dt->pattern[k++] = 0.2 * DSCALE; dt->pattern[k++] = 0.5 * DSCALE; break; case '-': dt->pattern[k++] = 1.0 * DSCALE; dt->pattern[k++] = 1.0 * DSCALE; break; case '_': dt->pattern[k++] = 2.0 * DSCALE; dt->pattern[k++] = 1.0 * DSCALE; break; case ' ': if (k > 0) dt->pattern[k-1] += 1.0 * DSCALE; break; default: int_error(c_token - 1, "expecting one of . - _ or space"); } j++; #undef DSCALE } /* truncate dash_str if we ran out of space in the array representation */ dash_str[j] = '\0'; dt->str = gp_strdup(dash_str); free(dash_str); res = DASHTYPE_CUSTOM; /* Or index of previously defined dashtype */ /* FIXME: Is the index enough or should we copy its contents into this one? */ /* FIXME: What happens if there is a recursive definition? */ } else { res = int_expression() - 1; if (res < 0) int_error(c_token - 1, "tag must be > 0"); } return res; }
/* add line to the history */ void add_history(char *line) { static struct hist *first_entry = NULL; /* this points to first entry in history list, whereas "history" points to last entry */ static long int hist_count = 0; /* number of entries in history list */ struct hist *entry; entry = history; while (entry != NULL) { /* Don't store duplicate entries */ if (!strcmp(entry->line, line)) { /* cmd lines are equal, relink entry that was found last */ if (entry->next == NULL) { /* previous command repeated, no change */ return; } if (entry->prev == NULL) { /* current cmd line equals the first in the history */ (entry->next)->prev = NULL; first_entry = entry->next; history->next = entry; entry->prev = history; entry->next = NULL; history = entry; return; } /* bridge over entry's vacancy, then move it to the end */ (entry->prev)->next = entry->next; (entry->next)->prev = entry->prev; entry->prev = history; history->next = entry; entry->next = NULL; history = entry; return; } entry = entry->prev; } /* end of not-storing duplicated entries */ #ifdef GNUPLOT_HISTORY /* limit size of history list to "gnuplot_history_size" */ if (gnuplot_history_size != -1) { while ((hist_count >= gnuplot_history_size) && (first_entry != NULL)) { entry = first_entry; /* remove first entry from chain */ first_entry = first_entry->next; if (first_entry) { first_entry->prev = NULL; } hist_count--; /* remove references */ if (cur_entry == entry) cur_entry = first_entry; if (history == entry) { cur_entry = history = NULL; hist_count = 0; } free( entry->line ); free( entry ); } } #endif entry = (struct hist *) gp_alloc(sizeof(struct hist), "history"); entry->line = gp_strdup(line); entry->prev = history; entry->next = NULL; if (history != NULL) { history->next = entry; } else { first_entry = entry; } history = entry; hist_count++; }
char * locale_handler(int action, char *newlocale) { struct tm tm; int i; switch(action) { case ACTION_CLEAR: case ACTION_INIT: free(current_locale); #ifdef HAVE_LOCALE_H setlocale(LC_TIME, ""); setlocale(LC_CTYPE, ""); current_locale = gp_strdup(setlocale(LC_TIME,NULL)); #else current_locale = gp_strdup(INITIAL_LOCALE); #endif break; case ACTION_SET: #ifdef HAVE_LOCALE_H if (setlocale(LC_TIME, newlocale)) { free(current_locale); current_locale = gp_strdup(setlocale(LC_TIME,NULL)); } else { int_error(c_token, "Locale not available"); } /* we can do a *lot* better than this ; eg use system functions * where available; create values on first use, etc */ memset(&tm, 0, sizeof(struct tm)); for (i = 0; i < 7; ++i) { tm.tm_wday = i; /* hope this enough */ strftime(full_day_names[i], sizeof(full_day_names[i]), "%A", &tm); strftime(abbrev_day_names[i], sizeof(abbrev_day_names[i]), "%a", &tm); } for (i = 0; i < 12; ++i) { tm.tm_mon = i; /* hope this enough */ strftime(full_month_names[i], sizeof(full_month_names[i]), "%B", &tm); strftime(abbrev_month_names[i], sizeof(abbrev_month_names[i]), "%b", &tm); } #else current_locale = gp_realloc(current_locale, strlen(newlocale) + 1, "locale"); strcpy(current_locale, newlocale); #endif /* HAVE_LOCALE_H */ break; case ACTION_SHOW: #ifdef HAVE_LOCALE_H fprintf(stderr, "\tgnuplot LC_CTYPE %s\n", setlocale(LC_CTYPE,NULL)); fprintf(stderr, "\tgnuplot encoding %s\n", encoding_names[encoding]); fprintf(stderr, "\tgnuplot LC_TIME %s\n", setlocale(LC_TIME,NULL)); fprintf(stderr, "\tgnuplot LC_NUMERIC %s\n", numeric_locale ? numeric_locale : "C"); #else fprintf(stderr, "\tlocale is \"%s\"\n", current_locale); #endif break; case ACTION_GET: default: break; } return current_locale; }