1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006, 2009, 2010 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "libpspp/getl.h"
23 #include "libpspp/ll.h"
24 #include "libpspp/str.h"
25 #include "libpspp/string-array.h"
27 #include "gl/configmake.h"
28 #include "gl/relocatable.h"
29 #include "gl/xalloc.h"
33 struct getl_source *included_from; /* File that this is nested inside. */
34 struct getl_source *includes; /* File nested inside this file. */
36 struct ll ll; /* Element in the sources list */
38 struct getl_interface *interface;
39 enum syntax_mode syntax_mode;
40 enum error_mode error_mode;
45 struct ll_list sources ; /* List of source files. */
46 struct string_array include_path;
50 getl_include_path (const struct source_stream *ss_)
52 struct source_stream *ss = CONST_CAST (struct source_stream *, ss_);
53 string_array_terminate_null (&ss->include_path);
54 return ss->include_path.strings;
57 static struct getl_source *
58 current_source (const struct source_stream *ss)
60 const struct ll *ll = ll_head (&ss->sources);
61 return ll_data (ll, struct getl_source, ll );
65 source_stream_current_syntax_mode (const struct source_stream *ss)
67 struct getl_source *cs = current_source (ss);
69 return cs->syntax_mode;
75 source_stream_current_error_mode (const struct source_stream *ss)
77 struct getl_source *cs = current_source (ss);
79 return cs->error_mode;
84 /* Initialize getl. */
85 struct source_stream *
86 create_source_stream (void)
88 struct source_stream *ss;
90 ss = xzalloc (sizeof (*ss));
91 ll_init (&ss->sources);
93 string_array_init (&ss->include_path);
94 string_array_append (&ss->include_path, ".");
95 if (getenv ("HOME") != NULL)
96 string_array_append_nocopy (&ss->include_path,
97 xasprintf ("%s/.pspp", getenv ("HOME")));
98 string_array_append (&ss->include_path, relocate (PKGDATADIR));
103 /* Delete everything from the include path. */
105 getl_clear_include_path (struct source_stream *ss)
107 string_array_clear (&ss->include_path);
110 /* Add to the include path. */
112 getl_add_include_dir (struct source_stream *ss, const char *path)
114 string_array_append (&ss->include_path, path);
117 /* Appends source S to the list of source files. */
119 getl_append_source (struct source_stream *ss,
120 struct getl_interface *i,
121 enum syntax_mode syntax_mode,
122 enum error_mode err_mode)
124 struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
127 s->syntax_mode = syntax_mode;
128 s->error_mode = err_mode;
130 ll_push_tail (&ss->sources, &s->ll);
133 /* Nests source S within the current source file. */
135 getl_include_source (struct source_stream *ss,
136 struct getl_interface *i,
137 enum syntax_mode syntax_mode,
138 enum error_mode err_mode)
140 struct getl_source *current = current_source (ss);
141 struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
145 s->included_from = current ;
147 s->syntax_mode = syntax_mode;
148 s->error_mode = err_mode;
149 current->includes = s;
151 ll_push_head (&ss->sources, &s->ll);
154 /* Closes the current source, and move the current source to the
155 next file in the chain. */
157 close_source (struct source_stream *ss)
159 struct getl_source *s = current_source (ss);
161 if ( s->interface->close )
162 s->interface->close (s->interface);
164 ll_pop_head (&ss->sources);
166 if (s->included_from != NULL)
167 current_source (ss)->includes = NULL;
172 /* Closes all sources until an interactive source is
175 getl_abort_noninteractive (struct source_stream *ss)
177 while ( ! ll_is_empty (&ss->sources))
179 const struct getl_source *s = current_source (ss);
181 if ( !s->interface->interactive (s->interface) )
186 /* Returns true if the current source is interactive,
189 getl_is_interactive (const struct source_stream *ss)
191 const struct getl_source *s = current_source (ss);
193 if (ll_is_empty (&ss->sources) )
196 return s->interface->interactive (s->interface);
199 /* Returns the name of the current source, or NULL if there is no
202 getl_source_name (const struct source_stream *ss)
204 const struct getl_source *s = current_source (ss);
206 if ( ll_is_empty (&ss->sources) )
209 if ( ! s->interface->name )
212 return s->interface->name (s->interface);
215 /* Returns the location within the current source, or -1 if there is
218 getl_source_location (const struct source_stream *ss)
220 const struct getl_source *s = current_source (ss);
222 if ( ll_is_empty (&ss->sources) )
225 if ( !s->interface->location )
228 return s->interface->location (s->interface);
234 destroy_source_stream (struct source_stream *ss)
236 while ( !ll_is_empty (&ss->sources))
238 string_array_destroy (&ss->include_path);
244 /* Reads a single line into LINE.
245 Returns true when a line has been read, false at end of input.
248 getl_read_line (struct source_stream *ss, struct string *line)
251 while (!ll_is_empty (&ss->sources))
253 struct getl_source *s = current_source (ss);
256 if (s->interface->read (s->interface, line))
260 if (s->interface->filter)
261 s->interface->filter (s->interface, line);
262 s = s->included_from;