Oops. committing new files
authorJohn Darrington <john@darrington.wattle.id.au>
Wed, 29 Nov 2006 12:19:07 +0000 (12:19 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Wed, 29 Nov 2006 12:19:07 +0000 (12:19 +0000)
src/language/line-buffer.c [deleted file]
src/language/line-buffer.h [deleted file]
src/language/prompt.c [new file with mode: 0644]
src/language/prompt.h [new file with mode: 0644]
src/language/syntax-file.c [new file with mode: 0644]
src/language/syntax-file.h [new file with mode: 0644]
src/libpspp/getl.c [new file with mode: 0644]
src/libpspp/getl.h [new file with mode: 0644]
src/libpspp/msg-locator.c [new file with mode: 0644]
src/libpspp/msg-locator.h [new file with mode: 0644]

diff --git a/src/language/line-buffer.c b/src/language/line-buffer.c
deleted file mode 100644 (file)
index 0dcb70f..0000000
+++ /dev/null
@@ -1,587 +0,0 @@
-/* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA. */
-
-#include <config.h>
-
-#include <language/line-buffer.h>
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include <data/file-name.h>
-#include <data/settings.h>
-#include <data/variable.h>
-#include <language/command.h>
-#include <language/lexer/lexer.h>
-#include <libpspp/alloc.h>
-#include <libpspp/assertion.h>
-#include <libpspp/message.h>
-#include <libpspp/message.h>
-#include <libpspp/str.h>
-#include <libpspp/verbose-msg.h>
-#include <libpspp/version.h>
-#include <output/table.h>
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-/* Source file. */
-struct getl_source
-  {
-    struct getl_source *included_from; /* File that this is nested inside. */
-    struct getl_source *includes;      /* File nested inside this file. */
-    struct getl_source *next;          /* Next file in list. */
-
-    /* Current location. */
-    char *fn;                          /* File name. */
-    int ln;                            /* Line number. */
-
-    enum getl_source_type
-      {
-        SYNTAX_FILE,
-        FILTER,
-        FUNCTION,
-        INTERACTIVE
-      }
-    type;
-
-    union 
-      {
-        /* SYNTAX_FILE. */
-        FILE *syntax_file;
-
-        /* FILTER. */
-        struct 
-          {
-            void (*filter) (struct string *line, void *aux);
-            void (*close) (void *aux);
-            void *aux;
-          }
-        filter;
-
-        /* FUNCTION. */
-        struct 
-          {
-            bool (*read) (struct string *line, char **fn, int *ln, void *aux);
-            void (*close) (void *aux);
-            void *aux;
-          }
-        function;
-
-        /* INTERACTIVE. */
-        bool (*interactive) (struct string *line, enum getl_prompt_style);
-      }
-    u;
-
-  };
-
-/* List of source files. */
-static struct getl_source *cur_source;
-static struct getl_source *last_source;
-
-static struct string getl_include_path;
-
-
-static void close_source (void);
-
-static void init_prompts (void);
-static void uninit_prompts (void);
-static enum getl_prompt_style get_prompt_style (void);
-
-
-/* Initialize getl. */
-void
-getl_initialize (void)
-{
-  ds_init_cstr (&getl_include_path,
-                fn_getenv_default ("STAT_INCLUDE_PATH", include_path));
-  init_prompts ();
-}
-
-
-/* Delete everything from the include path. */
-void
-getl_clear_include_path (void)
-{
-  ds_clear (&getl_include_path);
-}
-
-/* Add to the include path. */
-void
-getl_add_include_dir (const char *path)
-{
-  if (ds_length (&getl_include_path))
-    ds_put_char (&getl_include_path, ':');
-
-  ds_put_cstr (&getl_include_path, path);
-}
-
-/* Appends source S to the list of source files. */
-static void
-append_source (struct getl_source *s) 
-{
-  s->included_from = s->includes = s->next = NULL;
-  if (last_source == NULL)
-    cur_source = s;
-  else
-    last_source->next = s;
-  last_source = s;
-}
-
-/* Nests source S within the current source file. */
-static void
-include_source (struct getl_source *s) 
-{
-  if (last_source == NULL)
-    append_source (s);
-  else 
-    {
-      s->included_from = cur_source;
-      s->includes = s->next = NULL;
-      s->next = NULL;
-      cur_source->includes = s;
-      cur_source = s;
-    }
-}
-
-/* Creates a source of the given TYPE.
-   Type-specific data must be initialized by the caller. */
-static struct getl_source *
-create_source (enum getl_source_type type) 
-{
-  struct getl_source *s = xmalloc (sizeof *s);
-  s->fn = NULL;
-  s->ln = 0;
-  s->type = type;
-  return s;
-}
-
-/* Creates a syntax file source with file name FN. */
-static struct getl_source *
-create_syntax_file_source (const char *fn) 
-{
-  struct getl_source *s = create_source (SYNTAX_FILE);
-  s->fn = xstrdup (fn);
-  s->u.syntax_file = NULL;
-  return s;
-}
-
-/* Creates a filter source with the given FILTER and CLOSE
-   functions that receive auxiliary data AUX. */
-static struct getl_source *
-create_filter_source (void (*filter) (struct string *, void *aux),
-                      void (*close) (void *aux),
-                      void *aux)
-{
-  struct getl_source *s = create_source (FILTER);
-  s->u.filter.filter = filter;
-  s->u.filter.close = close;
-  s->u.filter.aux = aux;
-  return s;
-}
-
-/* Creates a function source with the given READ and CLOSE
-   functions that receive auxiliary data AUX. */
-static struct getl_source *
-create_function_source (bool (*read) (struct string *line,
-                                      char **fn, int *ln, void *aux),
-                        void (*close) (void *aux),
-                        void *aux)
-{
-  struct getl_source *s = create_source (FUNCTION);
-  s->u.function.read = read;
-  s->u.function.close = close;
-  s->u.function.aux = aux;
-  return s;
-}
-
-/* Creates an interactive source with the given FUNCTION. */
-static struct getl_source *
-create_interactive_source (bool (*function) (struct string *line,
-                                             enum getl_prompt_style)) 
-{
-  struct getl_source *s = xmalloc (sizeof *s);
-  s->fn = NULL;
-  s->ln = 0;
-  s->type = INTERACTIVE;
-  s->u.interactive = function;
-  return s;
-}
-
-/* Adds FN to the tail end of the list of source files to
-   execute. */
-void
-getl_append_syntax_file (const char *fn)
-{
-  append_source (create_syntax_file_source (fn));
-}
-
-/* Inserts the given file with name FN into the current file
-   after the current line. */
-void
-getl_include_syntax_file (const char *fn)
-{
-  if (cur_source != NULL) 
-    {
-      char *found_fn = fn_search_path (fn, ds_cstr (&getl_include_path),
-                                       fn_dir_name (cur_source->fn));
-      if (found_fn != NULL) 
-        {
-          include_source (create_syntax_file_source (found_fn));
-          free (found_fn); 
-        }
-      else
-        msg (SE, _("Can't find `%s' in include file search path."), fn);
-    }
-  else 
-    getl_append_syntax_file (fn); 
-}
-
-/* Inserts the given filter into the current file after the
-   current line.  Each line read while the filter is in place
-   will be passed through FILTER, which may modify it as
-   necessary.  When the filter is closed, CLOSE will be called.
-   AUX will be passed to both functions.
-
-   The filter cannot itself output any new lines, and it will be
-   closed as soon as any line would be read from it.  This means
-   that, for a filter to be useful, another source must be nested
-   inside it with, e.g., getl_include_syntax_file(). */
-void
-getl_include_filter (void (*filter) (struct string *, void *aux),
-                     void (*close) (void *aux),
-                     void *aux) 
-{
-  include_source (create_filter_source (filter, close, aux));
-}
-
-/* Inserts the given functional source into the current file
-   after the current line.  Lines are read by calling READ, which
-   should write the next line in LINE, store the file name and
-   line number of the line in *FN and *LN, and return true.  The
-   string stored in *FN will not be freed by getl.  When no lines
-   are left, READ should return false.
-
-   When the source is closed, CLOSE will be called.
-
-   AUX will be passed to both READ and CLOSE. */
-void
-getl_include_function (bool (*read) (struct string *line,
-                                     char **fn, int *ln, void *aux),
-                       void (*close) (void *aux),
-                       void *aux) 
-{
-  include_source (create_function_source (read, close, aux));
-}
-
-/* Adds an interactive source to the end of the list of sources.
-   FUNCTION will be called to obtain a line.  It should store the
-   line in LINE.  PROMPT is the prompt to be displayed to the
-   user.  FUNCTION should return true when a line has been
-   obtained or false at end of file. */
-void
-getl_append_interactive (bool (*function) (struct string *line,
-                                           enum getl_prompt_style)) 
-{
-  append_source (create_interactive_source (function));
-}
-
-/* Closes all sources until an interactive source is
-   encountered. */
-void
-getl_abort_noninteractive (void) 
-{
-  while (cur_source != NULL && cur_source->type != INTERACTIVE)
-    close_source ();
-}
-
-/* Returns true if the current source is interactive,
-   false otherwise. */
-bool
-getl_is_interactive (void) 
-{
-  return cur_source != NULL && cur_source->type == INTERACTIVE;
-}
-
-/* Closes the current file, whether it be a main file or included
-   file, then moves cur_source to the next file in the chain. */
-static void
-close_source (void)
-{
-  struct getl_source *s;
-
-  s = cur_source;
-  switch (s->type) 
-    {
-    case SYNTAX_FILE:
-      if (s->u.syntax_file && EOF == fn_close (s->fn, s->u.syntax_file))
-        msg (MW, _("Closing `%s': %s."), s->fn, strerror (errno));
-      free (s->fn);
-      break;
-
-    case FILTER:
-      if (s->u.filter.close != NULL)
-        s->u.filter.close (s->u.filter.aux);
-      break;
-
-    case FUNCTION:
-      if (s->u.function.close != NULL)
-        s->u.function.close (s->u.function.aux);
-      break;
-
-    case INTERACTIVE:
-      break;
-    }
-
-  if (s->included_from != NULL)
-    {
-      cur_source = s->included_from;
-      cur_source->includes = NULL;
-    }
-  else
-    {
-      cur_source = s->next;
-      if (cur_source == NULL)
-       last_source = NULL;
-    }
-
-  free (s);
-}
-
-/* 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 = cur_source ? cur_source->fn : "";
-  if (ln != NULL)
-    *ln = cur_source ? cur_source->ln : -1;
-}
-
-/* File locator stack. */
-static const struct msg_locator **file_loc;
-
-static int nfile_loc, mfile_loc;
-\f
-/* Close getl. */
-void
-getl_uninitialize (void)
-{
-  while (cur_source != NULL)
-    close_source ();
-  ds_destroy (&getl_include_path);
-  free(file_loc);
-  file_loc = NULL;
-  nfile_loc = mfile_loc = 0;
-  uninit_prompts ();
-}
-
-
-/* File locator stack functions. */
-
-/* Pushes F onto the stack of file locations. */
-void
-msg_push_msg_locator (const struct msg_locator *loc)
-{
-  if (nfile_loc >= mfile_loc)
-    {
-      if (mfile_loc == 0)
-       mfile_loc = 8;
-      else
-       mfile_loc *= 2;
-
-      file_loc = xnrealloc (file_loc, mfile_loc, sizeof *file_loc);
-    }
-
-  file_loc[nfile_loc++] = loc;
-}
-
-/* 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
-msg_pop_msg_locator (const struct msg_locator *loc)
-{
-  assert (nfile_loc >= 0 && file_loc[nfile_loc - 1] == loc);
-  nfile_loc--;
-}
-
-/* Puts the current file and line number into LOC, or NULL and -1 if
-   none. */
-void
-get_msg_location (struct msg_locator *loc)
-{
-  if (nfile_loc)
-    *loc = *file_loc[nfile_loc - 1];
-  else
-    getl_location (&loc->file_name, &loc->line_number);
-}
-
-/* Reads a line from syntax file source S into LINE.
-   Returns true if successful, false at end of file. */
-static bool
-read_syntax_file (struct string *line, struct getl_source *s)
-{
-  /* Open file, if not yet opened. */
-  if (s->u.syntax_file == NULL)
-    {
-      verbose_msg (1, _("opening \"%s\" as syntax file"), s->fn);
-      s->u.syntax_file = fn_open (s->fn, "r");
-
-      if (s->u.syntax_file == NULL)
-        {
-          msg (ME, _("Opening `%s': %s."), s->fn, strerror (errno));
-          return false;
-        }
-    }
-
-  /* Read line from file and remove new-line.
-     Skip initial "#! /usr/bin/pspp" line. */
-  do 
-    {
-      s->ln++;
-      if (!ds_read_line (line, s->u.syntax_file))
-        {
-          if (ferror (s->u.syntax_file))
-            msg (ME, _("Reading `%s': %s."), s->fn, strerror (errno));
-          return false;
-        }
-      ds_chomp (line, '\n');
-    }
-  while (s->ln == 1 && !memcmp (ds_cstr (line), "#!", 2));
-
-  /* Echo to listing file, if configured to do so. */
-  if (get_echo ())
-    tab_output_text (TAB_LEFT | TAB_FIX, ds_cstr (line));
-
-  return true;
-}
-
-/* Reads a line from source S into LINE.
-   Returns true if successful, false at end of file. */
-static bool
-read_line_from_source (struct string *line, struct getl_source *s)
-{
-  ds_clear (line);
-  switch (s->type) 
-    {
-    case SYNTAX_FILE:
-      return read_syntax_file (line, s);
-    case FILTER:
-      return false;
-    case FUNCTION:
-      return s->u.function.read (line, &s->fn, &s->ln, s->u.function.aux);
-    case INTERACTIVE:
-      return s->u.interactive (line, get_prompt_style ());
-    }
-
-  NOT_REACHED ();
-}
-
-/* Reads a single line into LINE.
-   Returns true when a line has been read, false at end of input.
-   If INTERACTIVE is non-null, then when true is returned
-   *INTERACTIVE will be set to true if the line was obtained
-   interactively, false otherwise. */
-bool
-do_read_line (struct string *line, bool *interactive)
-{
-  while (cur_source != NULL)
-    {
-      struct getl_source *s = cur_source;
-      if (read_line_from_source (line, s))
-        {
-          if (interactive != NULL)
-            *interactive = s->type == INTERACTIVE;
-
-          while ((s = s->included_from) != NULL)
-            if (s->type == FILTER)
-              s->u.filter.filter (line, s->u.filter.aux);
-
-          return true;
-        }
-      close_source ();
-    }
-
-  return false;
-}
-
-\f
-/* Current prompts in each style. */
-static char *prompts[GETL_PROMPT_CNT];
-
-/* Current prompting style. */
-static enum getl_prompt_style current_style;
-
-/* Initializes prompts. */
-static void
-init_prompts (void) 
-{
-  prompts[GETL_PROMPT_FIRST] = xstrdup ("PSPP> ");
-  prompts[GETL_PROMPT_LATER] = xstrdup ("    > ");
-  prompts[GETL_PROMPT_DATA] = xstrdup ("data> ");
-  current_style = GETL_PROMPT_FIRST;
-}
-
-/* Frees prompts. */
-static void
-uninit_prompts (void) 
-{
-  int i;
-
-  for (i = 0; i < GETL_PROMPT_CNT; i++) 
-    {
-      free (prompts[i]);
-      prompts[i] = NULL;
-    }
-}
-
-/* Gets the command prompt for the given STYLE. */
-const char * 
-getl_get_prompt (enum getl_prompt_style style)
-{
-  assert (style < GETL_PROMPT_CNT);
-  return prompts[style];
-}
-
-/* Sets the given STYLE's prompt to STRING. */
-void
-getl_set_prompt (enum getl_prompt_style style, const char *string)
-{
-  assert (style < GETL_PROMPT_CNT);
-  free (prompts[style]);
-  prompts[style] = xstrdup (string);
-}
-
-/* Sets STYLE as the current prompt style. */
-void
-getl_set_prompt_style (enum getl_prompt_style style) 
-{
-  assert (style < GETL_PROMPT_CNT);
-  current_style = style;
-}
-
-/* Returns the current prompt. */
-static enum getl_prompt_style
-get_prompt_style (void) 
-{
-  return current_style;
-}
diff --git a/src/language/line-buffer.h b/src/language/line-buffer.h
deleted file mode 100644 (file)
index ee3db55..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA. */
-
-#ifndef GETL_H
-#define GETL_H 1
-
-#include <stdbool.h>
-#include <libpspp/str.h>
-
-enum getl_prompt_style
-  {
-    GETL_PROMPT_FIRST,         /* First line of command. */
-    GETL_PROMPT_LATER,          /* Second or later line of command. */
-    GETL_PROMPT_DATA,          /* Between BEGIN DATA and END DATA. */
-    GETL_PROMPT_CNT
-  };
-
-
-void getl_initialize (void);
-void getl_uninitialize (void);
-
-void getl_clear_include_path (void);
-void getl_add_include_dir (const char *);
-
-void getl_append_syntax_file (const char *);
-void getl_include_syntax_file (const char *);
-void getl_include_filter (void (*filter) (struct string *, void *aux),
-                          void (*close) (void *aux),
-                          void *aux);
-void getl_include_function (bool (*read) (struct string *line,
-                                          char **fn, int *ln, void *aux),
-                            void (*close) (void *aux),
-                            void *aux);
-void getl_append_interactive (bool (*function) (struct string *line,
-                                                enum getl_prompt_style));
-void getl_abort_noninteractive (void);
-bool getl_is_interactive (void);
-
-bool getl_read_line (bool *interactive);
-
-const char *getl_get_prompt (enum getl_prompt_style);
-void getl_set_prompt (enum getl_prompt_style, const char *);
-void getl_set_prompt_style (enum getl_prompt_style);
-
-struct msg_locator;
-void get_msg_location (struct msg_locator *loc);
-
-void getl_location (const char **fn, int *ln);
-
-bool do_read_line (struct string *line, bool *interactive);
-
-
-#endif /* line-buffer.h */
diff --git a/src/language/prompt.c b/src/language/prompt.c
new file mode 100644 (file)
index 0000000..5640c50
--- /dev/null
@@ -0,0 +1,101 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "prompt.h"
+
+#include <data/file-name.h>
+#include <data/settings.h>
+#include <data/variable.h>
+#include <language/command.h>
+#include <language/lexer/lexer.h>
+#include <libpspp/alloc.h>
+#include <libpspp/assertion.h>
+#include <libpspp/message.h>
+#include <libpspp/message.h>
+#include <libpspp/str.h>
+#include <libpspp/verbose-msg.h>
+#include <libpspp/version.h>
+#include <output/table.h>
+
+/* Current prompts in each style. */
+static char *prompts[PROMPT_CNT];
+
+/* Current prompting style. */
+static enum prompt_style current_style;
+
+/* Initializes prompts. */
+void
+prompt_init (void) 
+{
+  prompts[PROMPT_FIRST] = xstrdup ("PSPP> ");
+  prompts[PROMPT_LATER] = xstrdup ("    > ");
+  prompts[PROMPT_DATA] = xstrdup ("data> ");
+  current_style = PROMPT_FIRST;
+}
+
+/* Frees prompts. */
+void
+prompt_done (void) 
+{
+  int i;
+
+  for (i = 0; i < PROMPT_CNT; i++) 
+    {
+      free (prompts[i]);
+      prompts[i] = NULL;
+    }
+}
+
+/* Gets the command prompt for the given STYLE. */
+const char * 
+prompt_get (enum prompt_style style)
+{
+  assert (style < PROMPT_CNT);
+  return prompts[style];
+}
+
+/* Sets the given STYLE's prompt to STRING. */
+void
+prompt_set (enum prompt_style style, const char *string)
+{
+  assert (style < PROMPT_CNT);
+  free (prompts[style]);
+  prompts[style] = xstrdup (string);
+}
+
+/* Sets STYLE as the current prompt style. */
+void
+prompt_set_style (enum prompt_style style) 
+{
+  assert (style < PROMPT_CNT);
+  current_style = style;
+}
+
+/* Returns the current prompt. */
+enum prompt_style
+prompt_get_style (void) 
+{
+  return current_style;
+}
diff --git a/src/language/prompt.h b/src/language/prompt.h
new file mode 100644 (file)
index 0000000..e10c324
--- /dev/null
@@ -0,0 +1,44 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#ifndef PROMPT_H
+#define PROMPT_H 1
+
+#include <stdbool.h>
+
+enum prompt_style
+  {
+    PROMPT_FIRST,              /* First line of command. */
+    PROMPT_LATER,          /* Second or later line of command. */
+    PROMPT_DATA,               /* Between BEGIN DATA and END DATA. */
+    PROMPT_CNT
+  };
+
+
+void prompt_init (void);
+void prompt_done (void);
+
+enum prompt_style prompt_get_style (void);
+
+const char *prompt_get (enum prompt_style);
+void prompt_set (enum prompt_style, const char *);
+void prompt_set_style (enum prompt_style);
+
+
+#endif /* PROMPT_H */
diff --git a/src/language/syntax-file.c b/src/language/syntax-file.c
new file mode 100644 (file)
index 0000000..e41466c
--- /dev/null
@@ -0,0 +1,155 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <config.h>
+
+#include "syntax-file.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <data/file-name.h>
+#include <data/settings.h>
+#include <data/variable.h>
+#include <language/command.h>
+#include <language/lexer/lexer.h>
+#include <libpspp/alloc.h>
+#include <libpspp/assertion.h>
+#include <libpspp/message.h>
+#include <libpspp/message.h>
+#include <libpspp/str.h>
+#include <libpspp/verbose-msg.h>
+#include <libpspp/version.h>
+#include <output/table.h>
+
+#include <libpspp/ll.h>
+
+#include "prompt.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+#include <libpspp/getl.h>
+
+
+struct syntax_file_source 
+  {
+    struct getl_interface parent ;
+
+    FILE *syntax_file;
+
+    /* Current location. */
+    char *fn;                          /* File name. */
+    int ln;                            /* Line number. */
+  };
+
+static const char *
+name (const struct getl_interface *s)
+{
+  const struct syntax_file_source *sfs = (const struct syntax_file_source *) s;
+  return sfs->fn;
+}
+
+static int
+line_number (const struct getl_interface *s)
+{
+  const struct syntax_file_source *sfs = (const struct syntax_file_source *) s;
+  return sfs->ln;
+}
+
+
+/* Reads a line from syntax file source S into LINE.
+   Returns true if successful, false at end of file. */
+bool
+read_syntax_file (struct getl_interface *s, struct string *line)
+{
+  struct syntax_file_source *sfs = (struct syntax_file_source *) s;
+
+  /* Open file, if not yet opened. */
+  if (sfs->syntax_file == NULL)
+    {
+      verbose_msg (1, _("opening \"%s\" as syntax file"), sfs->fn);
+      sfs->syntax_file = fn_open (sfs->fn, "r");
+
+      if (sfs->syntax_file == NULL)
+        {
+          msg (ME, _("Opening `%s': %s."), sfs->fn, strerror (errno));
+          return false;
+        }
+    }
+
+  /* Read line from file and remove new-line.
+     Skip initial "#! /usr/bin/pspp" line. */
+  do 
+    {
+      sfs->ln++;
+      if (!ds_read_line (line, sfs->syntax_file))
+        {
+          if (ferror (sfs->syntax_file))
+            msg (ME, _("Reading `%s': %s."), sfs->fn, strerror (errno));
+          return false;
+        }
+      ds_chomp (line, '\n');
+    }
+  while (sfs->ln == 1 && !memcmp (ds_cstr (line), "#!", 2));
+
+  /* Echo to listing file, if configured to do so. */
+  if (get_echo ())
+    tab_output_text (TAB_LEFT | TAB_FIX, ds_cstr (line));
+
+  return true;
+}
+
+static void
+syntax_close (struct getl_interface *s)
+{
+  struct syntax_file_source *sfs = (struct syntax_file_source *) s;
+
+  if (sfs->syntax_file && EOF == fn_close (sfs->fn, sfs->syntax_file))
+    msg (MW, _("Closing `%s': %s."), sfs->fn, strerror (errno));
+  free (sfs->fn);
+  free (sfs);
+}
+
+static bool
+always_false (const struct getl_interface *s UNUSED)
+{
+  return false;
+}
+
+
+/* Creates a syntax file source with file name FN. */
+struct getl_interface *
+create_syntax_file_source (const char *fn) 
+{
+  struct syntax_file_source *ss = xzalloc (sizeof (*ss));
+
+  ss->fn = xstrdup (fn);
+
+  ss->parent.interactive = always_false;
+  ss->parent.read = read_syntax_file ;
+  ss->parent.filter = NULL;
+  ss->parent.close = syntax_close ;
+  ss->parent.name = name ;
+  ss->parent.location = line_number;
+
+  return (struct getl_interface *) ss;
+}
+
diff --git a/src/language/syntax-file.h b/src/language/syntax-file.h
new file mode 100644 (file)
index 0000000..c09af21
--- /dev/null
@@ -0,0 +1,34 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#if !SYNTAX_FILE
+#define SYNTAX_FILE 1
+
+#include <stdbool.h>
+
+struct string;
+struct getl_interface;
+struct getl_source;
+
+bool read_syntax_file (struct getl_interface *s, struct string *line);
+
+/* Creates a syntax file source with file name FN. */
+struct getl_interface * create_syntax_file_source (const char *fn) ;
+
+#endif
diff --git a/src/libpspp/getl.c b/src/libpspp/getl.c
new file mode 100644 (file)
index 0000000..f3d7198
--- /dev/null
@@ -0,0 +1,233 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include <config.h>
+
+#include "getl.h"
+
+#include <libpspp/str.h>
+#include <libpspp/ll.h>
+#include <libpspp/version.h>
+#include <libpspp/alloc.h>
+
+#include <data/file-name.h>
+
+struct getl_source
+  {
+    struct getl_source *included_from; /* File that this is nested inside. */
+    struct getl_source *includes;      /* File nested inside this file. */
+    
+    struct ll  ll;   /* Element in the sources list */
+
+    struct getl_interface *interface;
+  };
+
+/* List of source files. */
+static struct ll_list sources ;
+
+static struct string the_include_path;
+
+const char *
+getl_include_path (void)
+{
+  return ds_cstr (&the_include_path);
+}
+
+static struct getl_source *
+current_source (struct ll_list *list)
+{
+  const struct ll *ll = ll_head (list);
+  return ll_data (ll, struct getl_source, ll );
+}
+
+/* Initialize getl. */
+void
+getl_initialize (void)
+{
+  ll_init (&sources);
+  ds_init_cstr (&the_include_path,
+                fn_getenv_default ("STAT_INCLUDE_PATH", include_path));
+}
+
+/* Delete everything from the include path. */
+void
+getl_clear_include_path (void)
+{
+  ds_clear (&the_include_path);
+}
+
+/* Add to the include path. */
+void
+getl_add_include_dir (const char *path)
+{
+  if (ds_length (&the_include_path))
+    ds_put_char (&the_include_path, ':');
+
+  ds_put_cstr (&the_include_path, path);
+}
+
+/* Appends source S to the list of source files. */
+void
+getl_append_source (struct getl_interface *i) 
+{
+  struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
+
+  s->interface = i ;
+
+  ll_push_head (&sources, &s->ll);
+}
+
+/* Nests source S within the current source file. */
+void
+getl_include_source (struct getl_interface *i) 
+{
+  struct getl_source *current = current_source (&sources);
+  struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
+
+  s->interface = i;
+
+  s->included_from = current ;
+  s->includes  = NULL;
+  current->includes = s;
+
+  ll_push_head (&sources, &s->ll);
+}
+
+/* Closes the current source, and move  the current source to the 
+   next file in the chain. */
+static void
+close_source (void)
+{
+  struct getl_source *s = current_source (&sources);
+
+  if ( s->interface->close ) 
+    s->interface->close (s->interface);
+
+  ll_pop_head (&sources);
+
+  if (s->included_from != NULL)
+    current_source (&sources)->includes = NULL;
+
+  free (s);
+}
+
+/* Closes all sources until an interactive source is
+   encountered. */
+void
+getl_abort_noninteractive (void) 
+{
+  while ( ! ll_is_empty (&sources))
+    {
+      const struct getl_source *s = current_source (&sources);
+      
+      if ( !s->interface->interactive (s->interface) ) 
+       close_source ();
+    }
+}
+
+/* Returns true if the current source is interactive,
+   false otherwise. */
+bool
+getl_is_interactive (void) 
+{
+  const struct getl_source *s = current_source (&sources);
+
+  if (ll_is_empty (&sources) ) 
+    return false;
+
+  return s->interface->interactive (s->interface);
+}
+
+/* Returns the name of the current source, or NULL if there is no 
+   current source */
+const char *
+getl_source_name (void)
+{
+  const struct getl_source *s = current_source (&sources);
+
+  if ( ll_is_empty (&sources) )
+    return NULL;
+
+  if ( ! s->interface->name ) 
+    return NULL;
+
+  return s->interface->name (s->interface);
+}
+
+/* Returns the location within the current source, or -1 if there is
+   no current source */
+int
+getl_source_location (void)
+{
+  const struct getl_source *s = current_source (&sources);
+
+  if ( ll_is_empty (&sources) )
+    return -1;
+
+  if ( !s->interface->location )
+    return -1;
+
+  return s->interface->location (s->interface);
+}
+
+
+/* Close getl. */
+void
+getl_uninitialize (void)
+{
+  while ( !ll_is_empty (&sources))
+    close_source ();
+  ds_destroy (&the_include_path);
+}
+
+
+/* Reads a single line into LINE.
+   Returns true when a line has been read, false at end of input.
+   If INTERACTIVE is non-null, then when true is returned
+   *INTERACTIVE will be set to true if the line was obtained
+   interactively, false otherwise. */
+bool
+do_read_line (struct string *line, bool *interactive)
+{
+  while (!ll_is_empty (&sources))
+    {
+      struct getl_source *s = current_source (&sources);
+
+      ds_clear (line);
+      if (s->interface->read (s->interface, line))
+        {
+          if (interactive != NULL)
+            *interactive = s->interface->interactive (s->interface);
+
+          while ((s))
+           {
+             if (s->interface->filter)
+               s->interface->filter (s->interface, line);
+             s = s->included_from;
+           }
+         
+          return true;
+        }
+      close_source ();
+    }
+
+  return false;
+}
diff --git a/src/libpspp/getl.h b/src/libpspp/getl.h
new file mode 100644 (file)
index 0000000..34c9b91
--- /dev/null
@@ -0,0 +1,74 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#ifndef GETL_H
+#define GETL_H 1
+
+#include <stdbool.h>
+#include <libpspp/ll.h>
+
+struct string; 
+
+struct getl_source;
+
+
+/* An abstract base class for objects which act as line buffers for the 
+   PSPP.  Ie anything which might contain content for the lexer */
+struct getl_interface 
+  {
+    /* Returns true, if the interface is interactive */
+    bool  (*interactive) (const struct getl_interface *); 
+
+    /* Read a line from the interface */
+    bool  (*read)  (struct getl_interface *, struct string *);
+
+    /* Close and destroy the interface */
+    void  (*close) (struct getl_interface *);
+
+    /* Filter for current and all included sources.  May be NULL */
+    void  (*filter) (struct getl_interface *, struct string *line);
+
+    /* Returns the name of the source */
+    const char * (*name) (const struct getl_interface *);
+
+    /* Returns the current location within the source */
+    int (*location) (const struct getl_interface *);
+  };
+
+void getl_initialize (void);
+void getl_uninitialize (void);
+
+void getl_clear_include_path (void);
+void getl_add_include_dir (const char *);
+const char * getl_include_path (void);
+
+void getl_abort_noninteractive (void);
+bool getl_is_interactive (void);
+
+bool getl_read_line (bool *interactive);
+
+bool do_read_line (struct string *line, bool *interactive);
+
+void getl_append_source (struct getl_interface *s) ;
+void getl_include_source (struct getl_interface *s) ;
+
+const char * getl_source_name (void);
+int getl_source_location (void);
+
+#endif /* line-buffer.h */
diff --git a/src/libpspp/msg-locator.c b/src/libpspp/msg-locator.c
new file mode 100644 (file)
index 0000000..5f7e5dd
--- /dev/null
@@ -0,0 +1,85 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <config.h>
+#include <stdlib.h>
+#include <libpspp/alloc.h>
+#include "msg-locator.h"
+#include <libpspp/message.h>
+#include <libpspp/assertion.h>
+#include "getl.h"
+
+/* File locator stack. */
+static const struct msg_locator **file_loc;
+
+static int nfile_loc, mfile_loc;
+
+void
+msg_locator_done (void)
+{
+  free(file_loc);
+  file_loc = NULL;
+  nfile_loc = mfile_loc = 0;
+}
+
+
+/* File locator stack functions. */
+
+/* Pushes F onto the stack of file locations. */
+void
+msg_push_msg_locator (const struct msg_locator *loc)
+{
+  if (nfile_loc >= mfile_loc)
+    {
+      if (mfile_loc == 0)
+       mfile_loc = 8;
+      else
+       mfile_loc *= 2;
+
+      file_loc = xnrealloc (file_loc, mfile_loc, sizeof *file_loc);
+    }
+
+  file_loc[nfile_loc++] = loc;
+}
+
+/* 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
+msg_pop_msg_locator (const struct msg_locator *loc)
+{
+  assert (nfile_loc >= 0 && file_loc[nfile_loc - 1] == loc);
+  nfile_loc--;
+}
+
+/* Puts the current file and line number into LOC, or NULL and -1 if
+   none. */
+void
+get_msg_location (struct msg_locator *loc)
+{
+  if (nfile_loc)
+    {
+      *loc = *file_loc[nfile_loc - 1];
+    }
+  else
+    {
+      loc->file_name = getl_source_name ();
+      loc->line_number = getl_source_location ();
+    }
+}
diff --git a/src/libpspp/msg-locator.h b/src/libpspp/msg-locator.h
new file mode 100644 (file)
index 0000000..b39ea6d
--- /dev/null
@@ -0,0 +1,36 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+struct msg_locator ;
+
+void msg_locator_done (void);
+
+/* File locator stack functions. */
+
+/* Pushes F onto the stack of file locations. */
+void msg_push_msg_locator (const struct msg_locator *loc);
+
+/* 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 msg_pop_msg_locator (const struct msg_locator *loc);
+
+/* Puts the current file and line number into LOC, or NULL and -1 if
+   none. */
+void get_msg_location (struct msg_locator *loc);