1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006 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/>. */
22 #include <libpspp/str.h>
23 #include <libpspp/ll.h>
24 #include <libpspp/version.h>
30 struct getl_source *included_from; /* File that this is nested inside. */
31 struct getl_source *includes; /* File nested inside this file. */
33 struct ll ll; /* Element in the sources list */
35 struct getl_interface *interface;
36 enum syntax_mode syntax_mode;
37 enum error_mode error_mode;
42 struct ll_list sources ; /* List of source files. */
44 struct string the_include_path;
48 getl_include_path (const struct source_stream *ss)
50 return ds_cstr (&ss->the_include_path);
53 static struct getl_source *
54 current_source (const struct source_stream *ss)
56 const struct ll *ll = ll_head (&ss->sources);
57 return ll_data (ll, struct getl_source, ll );
61 source_stream_current_syntax_mode (const struct source_stream *ss)
63 struct getl_source *cs = current_source (ss);
65 return cs->syntax_mode;
71 source_stream_current_error_mode (const struct source_stream *ss)
73 struct getl_source *cs = current_source (ss);
75 return cs->error_mode;
80 /* Initialize getl. */
81 struct source_stream *
82 create_source_stream (const char *initial_include_path)
84 struct source_stream *ss = xzalloc (sizeof (*ss));
85 ll_init (&ss->sources);
87 ds_init_cstr (&ss->the_include_path,
88 fn_getenv_default ("STAT_INCLUDE_PATH", include_path));
90 ds_init_cstr (&ss->the_include_path, initial_include_path);
95 /* Delete everything from the include path. */
97 getl_clear_include_path (struct source_stream *ss)
99 ds_clear (&ss->the_include_path);
102 /* Add to the include path. */
104 getl_add_include_dir (struct source_stream *ss, const char *path)
106 if (ds_length (&ss->the_include_path))
107 ds_put_char (&ss->the_include_path, ':');
109 ds_put_cstr (&ss->the_include_path, path);
112 /* Appends source S to the list of source files. */
114 getl_append_source (struct source_stream *ss,
115 struct getl_interface *i,
116 enum syntax_mode syntax_mode,
117 enum error_mode err_mode)
119 struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
122 s->syntax_mode = syntax_mode;
123 s->error_mode = err_mode;
125 ll_push_tail (&ss->sources, &s->ll);
128 /* Nests source S within the current source file. */
130 getl_include_source (struct source_stream *ss,
131 struct getl_interface *i,
132 enum syntax_mode syntax_mode,
133 enum error_mode err_mode)
135 struct getl_source *current = current_source (ss);
136 struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
140 s->included_from = current ;
142 s->syntax_mode = syntax_mode;
143 s->error_mode = err_mode;
144 current->includes = s;
146 ll_push_head (&ss->sources, &s->ll);
149 /* Closes the current source, and move the current source to the
150 next file in the chain. */
152 close_source (struct source_stream *ss)
154 struct getl_source *s = current_source (ss);
156 if ( s->interface->close )
157 s->interface->close (s->interface);
159 ll_pop_head (&ss->sources);
161 if (s->included_from != NULL)
162 current_source (ss)->includes = NULL;
167 /* Closes all sources until an interactive source is
170 getl_abort_noninteractive (struct source_stream *ss)
172 while ( ! ll_is_empty (&ss->sources))
174 const struct getl_source *s = current_source (ss);
176 if ( !s->interface->interactive (s->interface) )
181 /* Returns true if the current source is interactive,
184 getl_is_interactive (const struct source_stream *ss)
186 const struct getl_source *s = current_source (ss);
188 if (ll_is_empty (&ss->sources) )
191 return s->interface->interactive (s->interface);
194 /* Returns the name of the current source, or NULL if there is no
197 getl_source_name (const struct source_stream *ss)
199 const struct getl_source *s = current_source (ss);
201 if ( ll_is_empty (&ss->sources) )
204 if ( ! s->interface->name )
207 return s->interface->name (s->interface);
210 /* Returns the location within the current source, or -1 if there is
213 getl_source_location (const struct source_stream *ss)
215 const struct getl_source *s = current_source (ss);
217 if ( ll_is_empty (&ss->sources) )
220 if ( !s->interface->location )
223 return s->interface->location (s->interface);
229 destroy_source_stream (struct source_stream *ss)
231 while ( !ll_is_empty (&ss->sources))
233 ds_destroy (&ss->the_include_path);
239 /* Reads a single line into LINE.
240 Returns true when a line has been read, false at end of input.
243 getl_read_line (struct source_stream *ss, struct string *line)
246 while (!ll_is_empty (&ss->sources))
248 struct getl_source *s = current_source (ss);
251 if (s->interface->read (s->interface, line))
255 if (s->interface->filter)
256 s->interface->filter (s->interface, line);
257 s = s->included_from;