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>
25 #include <libpspp/alloc.h>
29 struct getl_source *included_from; /* File that this is nested inside. */
30 struct getl_source *includes; /* File nested inside this file. */
32 struct ll ll; /* Element in the sources list */
34 struct getl_interface *interface;
35 enum syntax_mode syntax_mode;
36 enum error_mode error_mode;
41 struct ll_list sources ; /* List of source files. */
43 struct string the_include_path;
47 getl_include_path (const struct source_stream *ss)
49 return ds_cstr (&ss->the_include_path);
52 static struct getl_source *
53 current_source (const struct source_stream *ss)
55 const struct ll *ll = ll_head (&ss->sources);
56 return ll_data (ll, struct getl_source, ll );
60 source_stream_current_syntax_mode (const struct source_stream *ss)
62 struct getl_source *cs = current_source (ss);
64 return cs->syntax_mode;
70 source_stream_current_error_mode (const struct source_stream *ss)
72 struct getl_source *cs = current_source (ss);
74 return cs->error_mode;
79 /* Initialize getl. */
80 struct source_stream *
81 create_source_stream (const char *initial_include_path)
83 struct source_stream *ss = xzalloc (sizeof (*ss));
84 ll_init (&ss->sources);
86 ds_init_cstr (&ss->the_include_path,
87 fn_getenv_default ("STAT_INCLUDE_PATH", include_path));
89 ds_init_cstr (&ss->the_include_path, initial_include_path);
94 /* Delete everything from the include path. */
96 getl_clear_include_path (struct source_stream *ss)
98 ds_clear (&ss->the_include_path);
101 /* Add to the include path. */
103 getl_add_include_dir (struct source_stream *ss, const char *path)
105 if (ds_length (&ss->the_include_path))
106 ds_put_char (&ss->the_include_path, ':');
108 ds_put_cstr (&ss->the_include_path, path);
111 /* Appends source S to the list of source files. */
113 getl_append_source (struct source_stream *ss,
114 struct getl_interface *i,
115 enum syntax_mode syntax_mode,
116 enum error_mode err_mode)
118 struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
121 s->syntax_mode = syntax_mode;
122 s->error_mode = err_mode;
124 ll_push_tail (&ss->sources, &s->ll);
127 /* Nests source S within the current source file. */
129 getl_include_source (struct source_stream *ss,
130 struct getl_interface *i,
131 enum syntax_mode syntax_mode,
132 enum error_mode err_mode)
134 struct getl_source *current = current_source (ss);
135 struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
139 s->included_from = current ;
141 s->syntax_mode = syntax_mode;
142 s->error_mode = err_mode;
143 current->includes = s;
145 ll_push_head (&ss->sources, &s->ll);
148 /* Closes the current source, and move the current source to the
149 next file in the chain. */
151 close_source (struct source_stream *ss)
153 struct getl_source *s = current_source (ss);
155 if ( s->interface->close )
156 s->interface->close (s->interface);
158 ll_pop_head (&ss->sources);
160 if (s->included_from != NULL)
161 current_source (ss)->includes = NULL;
166 /* Closes all sources until an interactive source is
169 getl_abort_noninteractive (struct source_stream *ss)
171 while ( ! ll_is_empty (&ss->sources))
173 const struct getl_source *s = current_source (ss);
175 if ( !s->interface->interactive (s->interface) )
180 /* Returns true if the current source is interactive,
183 getl_is_interactive (const struct source_stream *ss)
185 const struct getl_source *s = current_source (ss);
187 if (ll_is_empty (&ss->sources) )
190 return s->interface->interactive (s->interface);
193 /* Returns the name of the current source, or NULL if there is no
196 getl_source_name (const struct source_stream *ss)
198 const struct getl_source *s = current_source (ss);
200 if ( ll_is_empty (&ss->sources) )
203 if ( ! s->interface->name )
206 return s->interface->name (s->interface);
209 /* Returns the location within the current source, or -1 if there is
212 getl_source_location (const struct source_stream *ss)
214 const struct getl_source *s = current_source (ss);
216 if ( ll_is_empty (&ss->sources) )
219 if ( !s->interface->location )
222 return s->interface->location (s->interface);
228 destroy_source_stream (struct source_stream *ss)
230 while ( !ll_is_empty (&ss->sources))
232 ds_destroy (&ss->the_include_path);
238 /* Reads a single line into LINE.
239 Returns true when a line has been read, false at end of input.
242 getl_read_line (struct source_stream *ss, struct string *line)
245 while (!ll_is_empty (&ss->sources))
247 struct getl_source *s = current_source (ss);
250 if (s->interface->read (s->interface, line))
254 if (s->interface->filter)
255 s->interface->filter (s->interface, line);
256 s = s->included_from;