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/relocatable.h"
28 #include "gl/xalloc.h"
32 struct getl_source *included_from; /* File that this is nested inside. */
33 struct getl_source *includes; /* File nested inside this file. */
35 struct ll ll; /* Element in the sources list */
37 struct getl_interface *interface;
38 enum syntax_mode syntax_mode;
39 enum error_mode error_mode;
44 struct ll_list sources ; /* List of source files. */
45 struct string_array include_path;
49 getl_include_path (const struct source_stream *ss_)
51 struct source_stream *ss = CONST_CAST (struct source_stream *, ss_);
52 string_array_terminate_null (&ss->include_path);
53 return ss->include_path.strings;
56 static struct getl_source *
57 current_source (const struct source_stream *ss)
59 const struct ll *ll = ll_head (&ss->sources);
60 return ll_data (ll, struct getl_source, ll );
64 source_stream_current_syntax_mode (const struct source_stream *ss)
66 struct getl_source *cs = current_source (ss);
68 return cs->syntax_mode;
74 source_stream_current_error_mode (const struct source_stream *ss)
76 struct getl_source *cs = current_source (ss);
78 return cs->error_mode;
83 /* Initialize getl. */
84 struct source_stream *
85 create_source_stream (void)
87 struct source_stream *ss;
89 ss = xzalloc (sizeof (*ss));
90 ll_init (&ss->sources);
92 string_array_init (&ss->include_path);
93 string_array_append (&ss->include_path, ".");
94 if (getenv ("HOME") != NULL)
95 string_array_append_nocopy (&ss->include_path,
96 xasprintf ("%s/.pspp", getenv ("HOME")));
97 string_array_append (&ss->include_path, relocate (PKGDATADIR));
102 /* Delete everything from the include path. */
104 getl_clear_include_path (struct source_stream *ss)
106 string_array_clear (&ss->include_path);
109 /* Add to the include path. */
111 getl_add_include_dir (struct source_stream *ss, const char *path)
113 string_array_append (&ss->include_path, path);
116 /* Appends source S to the list of source files. */
118 getl_append_source (struct source_stream *ss,
119 struct getl_interface *i,
120 enum syntax_mode syntax_mode,
121 enum error_mode err_mode)
123 struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
126 s->syntax_mode = syntax_mode;
127 s->error_mode = err_mode;
129 ll_push_tail (&ss->sources, &s->ll);
132 /* Nests source S within the current source file. */
134 getl_include_source (struct source_stream *ss,
135 struct getl_interface *i,
136 enum syntax_mode syntax_mode,
137 enum error_mode err_mode)
139 struct getl_source *current = current_source (ss);
140 struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
144 s->included_from = current ;
146 s->syntax_mode = syntax_mode;
147 s->error_mode = err_mode;
148 current->includes = s;
150 ll_push_head (&ss->sources, &s->ll);
153 /* Closes the current source, and move the current source to the
154 next file in the chain. */
156 close_source (struct source_stream *ss)
158 struct getl_source *s = current_source (ss);
160 if ( s->interface->close )
161 s->interface->close (s->interface);
163 ll_pop_head (&ss->sources);
165 if (s->included_from != NULL)
166 current_source (ss)->includes = NULL;
171 /* Closes all sources until an interactive source is
174 getl_abort_noninteractive (struct source_stream *ss)
176 while ( ! ll_is_empty (&ss->sources))
178 const struct getl_source *s = current_source (ss);
180 if ( !s->interface->interactive (s->interface) )
185 /* Returns true if the current source is interactive,
188 getl_is_interactive (const struct source_stream *ss)
190 const struct getl_source *s = current_source (ss);
192 if (ll_is_empty (&ss->sources) )
195 return s->interface->interactive (s->interface);
198 /* Returns the name of the current source, or NULL if there is no
201 getl_source_name (const struct source_stream *ss)
203 const struct getl_source *s = current_source (ss);
205 if ( ll_is_empty (&ss->sources) )
208 if ( ! s->interface->name )
211 return s->interface->name (s->interface);
214 /* Returns the location within the current source, or -1 if there is
217 getl_source_location (const struct source_stream *ss)
219 const struct getl_source *s = current_source (ss);
221 if ( ll_is_empty (&ss->sources) )
224 if ( !s->interface->location )
227 return s->interface->location (s->interface);
233 destroy_source_stream (struct source_stream *ss)
235 while ( !ll_is_empty (&ss->sources))
237 string_array_destroy (&ss->include_path);
243 /* Reads a single line into LINE.
244 Returns true when a line has been read, false at end of input.
247 getl_read_line (struct source_stream *ss, struct string *line)
250 while (!ll_is_empty (&ss->sources))
252 struct getl_source *s = current_source (ss);
255 if (s->interface->read (s->interface, line))
259 if (s->interface->filter)
260 s->interface->filter (s->interface, line);
261 s = s->included_from;