Renamed reg_export_comments.h regression_export.h
[pspp] / src / getl.c
index a02244d7cabd680b2917852819952365390b9e42..2b689696a60eb3f480b20375f285f7caea483e95 100644 (file)
 #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 <readline/readline.h>
-#endif
-
-#if HAVE_LIBHISTORY
-static char *history_file;
-
-#if HAVE_READLINE_HISTORY_H
-#include <readline/history.h>
-#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 <readline/readline.h>
-#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;
-  const 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;
+\f
+/* 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);
 }
+
+