X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fgetl.c;h=2b689696a60eb3f480b20375f285f7caea483e95;hb=53ceff2865473a6b561b521986fafd31a993a1a6;hp=65ecb12716c9a35834c8767c18c072fa60114299;hpb=4de79b34b329d1da6cdeb145993d3efd911e2967;p=pspp diff --git a/src/getl.c b/src/getl.c index 65ecb12716..2b689696a6 100644 --- a/src/getl.c +++ b/src/getl.c @@ -38,36 +38,6 @@ #include "gettext.h" #define _(msgid) gettext (msgid) -/* Global variables. */ -struct string getl_buf; -struct getl_script *getl_head; -struct getl_script *getl_tail; -int getl_interactive; -int getl_welcomed; -int getl_mode; -int getl_prompt; - -#if HAVE_LIBREADLINE -#include -#endif - -#if HAVE_LIBHISTORY -static char *history_file; - -#if HAVE_READLINE_HISTORY_H -#include -#else /* no readline/history.h */ -extern void add_history (char *); -extern void using_history (void); -extern int read_history (char *); -extern void stifle_history (int); -extern int write_history (char *); -#endif /* no readline/history.h */ -#endif /* -lhistory */ - - -extern struct cmd_set cmd; - static struct string getl_include_path; /* Number of levels of DO REPEAT structures we're nested inside. If @@ -75,7 +45,8 @@ static struct string getl_include_path; performed. */ static int DO_REPEAT_level; -static int read_console (void); +struct string getl_buf; + /* Initialize getl. */ void @@ -84,23 +55,13 @@ getl_initialize (void) ds_create (&getl_include_path, fn_getenv_default ("STAT_INCLUDE_PATH", include_path)); ds_init (&getl_buf, 256); -#if HAVE_LIBREADLINE - rl_completion_entry_function = pspp_completion_function; -#endif } -/* Close getl. */ -void -getl_uninitialize (void) -{ - getl_close_all(); -#if HAVE_LIBHISTORY && defined (unix) - if (history_file) - write_history (history_file); -#endif - ds_destroy (&getl_buf); - ds_destroy (&getl_include_path); -} + + +struct getl_script *getl_head; +struct getl_script *getl_tail; + /* Returns a string that represents the directory that the syntax file currently being read resides in. If there is no syntax file then @@ -227,7 +188,6 @@ getl_add_virtual_file (struct getl_script *file) void getl_add_DO_REPEAT_file (struct getl_script *file) { - /* getl_head == NULL can't happen. */ assert (getl_head); DO_REPEAT_level++; @@ -242,28 +202,11 @@ getl_add_DO_REPEAT_file (struct getl_script *file) file->f = NULL; } -/* Display a welcoming message. */ -static void -welcome (void) -{ - getl_welcomed = 1; - fputs ("PSPP is free software and you are welcome to distribute copies of " - "it\nunder certain conditions; type \"show copying.\" to see the " - "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show " - "warranty.\" for details.\n", stdout); - puts (stat_version); -} - -/* Reads a single line from the user's terminal. */ - -/* From repeat.c. */ -extern void perform_DO_REPEAT_substitutions (void); - /* Reads a single line from the line buffer associated with getl_head. Returns 1 if a line was successfully read or 0 if no more lines are available. */ -static int -handle_line_buffer (void) +int +getl_handle_line_buffer (void) { struct getl_script *s = getl_head; @@ -297,84 +240,6 @@ handle_line_buffer (void) return 1; } -/* Reads a single line into getl_buf from the list of files. Will not - read from the eof of one file to the beginning of another unless - the options field on the new file's getl_script is nonzero. Return - zero on eof. */ -int -getl_read_line (void) -{ - getl_mode = GETL_MODE_BATCH; - - while (getl_head) - { - struct getl_script *s = getl_head; - - ds_clear (&getl_buf); - if (s->separate) - return 0; - - if (s->first_line) - { - if (!handle_line_buffer ()) - { - getl_close_file (); - continue; - } - perform_DO_REPEAT_substitutions (); - if (getl_head->print) - tab_output_text (TAB_LEFT | TAT_FIX | TAT_PRINTF, "+%s", - ds_c_str (&getl_buf)); - return 1; - } - - if (s->f == NULL) - { - msg (VM (1), _("%s: Opening as syntax file."), s->fn); - s->f = fn_open (s->fn, "r"); - - if (s->f == NULL) - { - msg (ME, _("Opening `%s': %s."), s->fn, strerror (errno)); - getl_close_file (); - continue; - } - } - - if (!ds_gets (&getl_buf, s->f)) - { - if (ferror (s->f)) - msg (ME, _("Reading `%s': %s."), s->fn, strerror (errno)); - getl_close_file (); - continue; - } - if (ds_length (&getl_buf) > 0 && ds_end (&getl_buf)[-1] == '\n') - ds_truncate (&getl_buf, ds_length (&getl_buf) - 1); - - if (get_echo()) - tab_output_text (TAB_LEFT | TAT_FIX, ds_c_str (&getl_buf)); - - getl_head->ln++; - - /* Allows shebang invocation: `#! /usr/local/bin/pspp'. */ - if (ds_c_str (&getl_buf)[0] == '#' - && ds_c_str (&getl_buf)[1] == '!') - continue; - - return 1; - } - - if (getl_interactive == 0) - return 0; - - getl_mode = GETL_MODE_INTERACTIVE; - - if (getl_welcomed == 0) - welcome (); - - return read_console (); -} - /* Closes the current file, whether it be a main file or included file, then moves getl_head to the next file in the chain. */ void @@ -420,121 +285,101 @@ getl_close_file (void) free (s); } -/* PORTME: Adapt to your local system's idea of the terminal. */ -#if HAVE_LIBREADLINE - -#if HAVE_READLINE_READLINE_H -#include -#else /* no readline/readline.h */ -extern char *readline (char *); -#endif /* no readline/readline.h */ - -static int -read_console (void) +/* Closes all files. */ +void +getl_close_all (void) { - char *line; - char *prompt; - - err_error_count = err_warning_count = 0; - err_already_flagged = 0; + while (getl_head) + getl_close_file (); +} -#if HAVE_LIBHISTORY - if (!history_file) - { -#ifdef unix - history_file = tilde_expand (HISTORY_FILE); -#endif - using_history (); - read_history (history_file); - stifle_history (MAX_HISTORY); - } -#endif /* -lhistory */ +bool +getl_is_separate(void) +{ + return (getl_head && getl_head->separate); +} - switch (getl_prompt) - { - case GETL_PRPT_STANDARD: - prompt = get_prompt(); - break; +void +getl_set_separate(bool sep) +{ + assert (getl_head); - case GETL_PRPT_CONTINUATION: - prompt = get_cprompt(); - break; + getl_head->separate = sep ; +} - case GETL_PRPT_DATA: - prompt = get_dprompt(); - break; - default: - assert (0); - abort (); - } +/* Puts the current file and line number in *FN and *LN, respectively, + or NULL and -1 if none. */ +void +getl_location (const char **fn, int *ln) +{ + if (fn != NULL) + *fn = getl_head ? getl_head->fn : NULL; + if (ln != NULL) + *ln = getl_head ? getl_head->ln : -1; +} - line = readline (prompt); - if (!line) - return 0; +bool +getl_reading_script (void) +{ + return (getl_head != NULL); +} -#if HAVE_LIBHISTORY - if (*line) - add_history (line); -#endif +/* File locator stack. */ +static const struct file_locator **file_loc; +static int nfile_loc, mfile_loc; + +/* Close getl. */ +void +getl_uninitialize (void) +{ + getl_close_all(); + ds_destroy (&getl_buf); + ds_destroy (&getl_include_path); + free(file_loc); + file_loc = NULL; + nfile_loc = mfile_loc = 0; +} - ds_clear (&getl_buf); - ds_puts (&getl_buf, line); - free (line); +/* File locator stack functions. */ - return 1; -} -#else /* no -lreadline */ -static int -read_console (void) +/* Pushes F onto the stack of file locations. */ +void +err_push_file_locator (const struct file_locator *f) { - err_error_count = err_warning_count = 0; - err_already_flagged = 0; - - fputs (getl_prompt ? get_cprompt() : get_prompt(), stdout); - ds_clear (&getl_buf); - if (ds_gets (&getl_buf, stdin)) - return 1; + if (nfile_loc >= mfile_loc) + { + if (mfile_loc == 0) + mfile_loc = 8; + else + mfile_loc *= 2; - if (ferror (stdin)) - msg (FE, "stdin: fgets(): %s.", strerror (errno)); + file_loc = xnrealloc (file_loc, mfile_loc, sizeof *file_loc); + } - return 0; + file_loc[nfile_loc++] = f; } -#endif /* no -lreadline */ -/* Closes all files. */ +/* Pops F off the stack of file locations. + Argument F is only used for verification that that is actually the + item on top of the stack. */ void -getl_close_all (void) -{ - while (getl_head) - getl_close_file (); -} - -/* Sets the options flag of the current script to 0, thus allowing it - to be read in. Returns nonzero if this action was taken, zero - otherwise. */ -int -getl_perform_delayed_reset (void) +err_pop_file_locator (const struct file_locator *f) { - if (getl_head && getl_head->separate) - { - getl_head->separate = 0; - discard_variables (); - lex_reset_eof (); - return 1; - } - return 0; + assert (nfile_loc >= 0 && file_loc[nfile_loc - 1] == f); + nfile_loc--; } -/* Puts the current file and line number in *FN and *LN, respectively, - or NULL and -1 if none. */ +/* Puts the current file and line number in F, or NULL and -1 if + none. */ void -getl_location (const char **fn, int *ln) +err_location (struct file_locator *f) { - if (fn != NULL) - *fn = getl_head ? getl_head->fn : NULL; - if (ln != NULL) - *ln = getl_head ? getl_head->ln : -1; + if (nfile_loc) + *f = *file_loc[nfile_loc - 1]; + else + getl_location (&f->filename, &f->line_number); } + +