X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fgetl.c;h=9db6c3ae56260d3be735efd45588622b4eb2077b;hb=afdf3096926b561f4e6511c10fcf73fc6796b9d2;hp=f3d7198184894dd805551294534b485769e85785;hpb=b8b67a1e1f709640ccdb3422a591b938edb0ceea;p=pspp-builds.git diff --git a/src/libpspp/getl.c b/src/libpspp/getl.c index f3d71981..9db6c3ae 100644 --- a/src/libpspp/getl.c +++ b/src/libpspp/getl.c @@ -1,130 +1,170 @@ -/* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. - Written by Ben Pfaff . +/* PSPP - a program for statistical analysis. + Copyright (C) 1997-9, 2000, 2006, 2009, 2010 Free Software Foundation, Inc. - 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 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 3 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. + 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 + along with this program. If not, see . */ #include -#include "getl.h" +#include "libpspp/getl.h" + +#include -#include -#include -#include -#include +#include "libpspp/ll.h" +#include "libpspp/str.h" +#include "libpspp/string-array.h" -#include +#include "gl/configmake.h" +#include "gl/relocatable.h" +#include "gl/xalloc.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; + enum syntax_mode syntax_mode; + enum error_mode error_mode; }; -/* List of source files. */ -static struct ll_list sources ; - -static struct string the_include_path; +struct source_stream + { + struct ll_list sources ; /* List of source files. */ + struct string_array include_path; + }; -const char * -getl_include_path (void) +char ** +getl_include_path (const struct source_stream *ss_) { - return ds_cstr (&the_include_path); + struct source_stream *ss = CONST_CAST (struct source_stream *, ss_); + string_array_terminate_null (&ss->include_path); + return ss->include_path.strings; } static struct getl_source * -current_source (struct ll_list *list) +current_source (const struct source_stream *ss) { - const struct ll *ll = ll_head (list); + const struct ll *ll = ll_head (&ss->sources); return ll_data (ll, struct getl_source, ll ); } +enum syntax_mode +source_stream_current_syntax_mode (const struct source_stream *ss) +{ + struct getl_source *cs = current_source (ss); + + return cs->syntax_mode; +} + + + +enum error_mode +source_stream_current_error_mode (const struct source_stream *ss) +{ + struct getl_source *cs = current_source (ss); + + return cs->error_mode; +} + + + /* Initialize getl. */ -void -getl_initialize (void) +struct source_stream * +create_source_stream (void) { - ll_init (&sources); - ds_init_cstr (&the_include_path, - fn_getenv_default ("STAT_INCLUDE_PATH", include_path)); + struct source_stream *ss; + + ss = xzalloc (sizeof (*ss)); + ll_init (&ss->sources); + + string_array_init (&ss->include_path); + string_array_append (&ss->include_path, "."); + if (getenv ("HOME") != NULL) + string_array_append_nocopy (&ss->include_path, + xasprintf ("%s/.pspp", getenv ("HOME"))); + string_array_append (&ss->include_path, relocate (PKGDATADIR)); + + return ss; } /* Delete everything from the include path. */ void -getl_clear_include_path (void) +getl_clear_include_path (struct source_stream *ss) { - ds_clear (&the_include_path); + string_array_clear (&ss->include_path); } /* Add to the include path. */ void -getl_add_include_dir (const char *path) +getl_add_include_dir (struct source_stream *ss, const char *path) { - if (ds_length (&the_include_path)) - ds_put_char (&the_include_path, ':'); - - ds_put_cstr (&the_include_path, path); + string_array_append (&ss->include_path, path); } /* Appends source S to the list of source files. */ void -getl_append_source (struct getl_interface *i) +getl_append_source (struct source_stream *ss, + struct getl_interface *i, + enum syntax_mode syntax_mode, + enum error_mode err_mode) { struct getl_source *s = xzalloc (sizeof ( struct getl_source )); s->interface = i ; + s->syntax_mode = syntax_mode; + s->error_mode = err_mode; - ll_push_head (&sources, &s->ll); + ll_push_tail (&ss->sources, &s->ll); } /* Nests source S within the current source file. */ void -getl_include_source (struct getl_interface *i) +getl_include_source (struct source_stream *ss, + struct getl_interface *i, + enum syntax_mode syntax_mode, + enum error_mode err_mode) { - struct getl_source *current = current_source (&sources); + struct getl_source *current = current_source (ss); struct getl_source *s = xzalloc (sizeof ( struct getl_source )); s->interface = i; s->included_from = current ; s->includes = NULL; + s->syntax_mode = syntax_mode; + s->error_mode = err_mode; current->includes = s; - ll_push_head (&sources, &s->ll); + ll_push_head (&ss->sources, &s->ll); } -/* Closes the current source, and move the current source to the +/* Closes the current source, and move the current source to the next file in the chain. */ static void -close_source (void) +close_source (struct source_stream *ss) { - struct getl_source *s = current_source (&sources); + struct getl_source *s = current_source (ss); - if ( s->interface->close ) + if ( s->interface->close ) s->interface->close (s->interface); - ll_pop_head (&sources); + ll_pop_head (&ss->sources); if (s->included_from != NULL) - current_source (&sources)->includes = NULL; + current_source (ss)->includes = NULL; free (s); } @@ -132,58 +172,58 @@ close_source (void) /* Closes all sources until an interactive source is encountered. */ void -getl_abort_noninteractive (void) +getl_abort_noninteractive (struct source_stream *ss) { - while ( ! ll_is_empty (&sources)) + while ( ! ll_is_empty (&ss->sources)) { - const struct getl_source *s = current_source (&sources); - - if ( !s->interface->interactive (s->interface) ) - close_source (); + const struct getl_source *s = current_source (ss); + + if ( !s->interface->interactive (s->interface) ) + close_source (ss); } } /* Returns true if the current source is interactive, false otherwise. */ bool -getl_is_interactive (void) +getl_is_interactive (const struct source_stream *ss) { - const struct getl_source *s = current_source (&sources); + const struct getl_source *s = current_source (ss); - if (ll_is_empty (&sources) ) + if (ll_is_empty (&ss->sources) ) return false; return s->interface->interactive (s->interface); } -/* Returns the name of the current source, or NULL if there is no +/* Returns the name of the current source, or NULL if there is no current source */ const char * -getl_source_name (void) +getl_source_name (const struct source_stream *ss) { - const struct getl_source *s = current_source (&sources); + const struct getl_source *s = current_source (ss); - if ( ll_is_empty (&sources) ) + if ( ll_is_empty (&ss->sources) ) return NULL; - if ( ! s->interface->name ) + 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 */ +/* Returns the line number within the current source, or 0 if there is no + current source. */ int -getl_source_location (void) +getl_source_location (const struct source_stream *ss) { - const struct getl_source *s = current_source (&sources); + const struct getl_source *s = current_source (ss); - if ( ll_is_empty (&sources) ) - return -1; + if ( ll_is_empty (&ss->sources) ) + return 0; if ( !s->interface->location ) - return -1; + return 0; return s->interface->location (s->interface); } @@ -191,42 +231,40 @@ getl_source_location (void) /* Close getl. */ void -getl_uninitialize (void) +destroy_source_stream (struct source_stream *ss) { - while ( !ll_is_empty (&sources)) - close_source (); - ds_destroy (&the_include_path); + while ( !ll_is_empty (&ss->sources)) + close_source (ss); + string_array_destroy (&ss->include_path); + + free (ss); } /* 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) +getl_read_line (struct source_stream *ss, struct string *line) { - while (!ll_is_empty (&sources)) + assert (ss != NULL); + while (!ll_is_empty (&ss->sources)) { - struct getl_source *s = current_source (&sources); + struct getl_source *s = current_source (ss); ds_clear (line); if (s->interface->read (s->interface, line)) { - if (interactive != NULL) - *interactive = s->interface->interactive (s->interface); - - while ((s)) + while (s) { if (s->interface->filter) s->interface->filter (s->interface, line); s = s->included_from; } - + return true; } - close_source (); + close_source (ss); } return false;