block->parent.location = do_repeat_location;
if (!ll_is_empty (&block->lines))
- getl_include_source (&block->parent);
+ getl_include_source (lex_get_source_stream (lexer), &block->parent);
else
pool_destroy (block->pool);
ds_init_string (&text, lex_entire_line_ds (lexer));
/* Record file name. */
- cur_file_name = getl_source_name ();
+ cur_file_name = getl_source_name (lex_get_source_stream (lexer));
if (cur_file_name != NULL &&
(previous_file_name == NULL
|| !strcmp (cur_file_name, previous_file_name)))
/* Create a line structure. */
line = pool_alloc (block->pool, sizeof *line);
line->file_name = previous_file_name;
- line->line_number = getl_source_location ();
+ line->line_number = getl_source_location (lex_get_source_stream (lexer));
ss_alloc_substring_pool (&line->text, ds_ss (&text), block->pool);
line->syntax = syntax;
{
struct string line_buffer;
- bool (*read_line) (struct string *, enum getl_syntax *);
+ struct source_stream *ss;
int token; /* Current token. */
double tokval; /* T_POS_NUM, T_NEG_NUM: the token's value. */
/* Initializes the lexer. */
struct lexer *
-lex_create (bool (*read_line_func) (struct string *, enum getl_syntax *))
+lex_create (struct source_stream *ss)
{
struct lexer *lexer = xzalloc (sizeof (*lexer));
ds_init_empty (&lexer->tokstr);
ds_init_empty (&lexer->put_tokstr);
ds_init_empty (&lexer->line_buffer);
- lexer->read_line = read_line_func;
+ lexer->ss = ss;
if (!lex_get_line (lexer))
lexer->eof = true;
return lexer;
}
+struct source_stream *
+lex_get_source_stream (const struct lexer *lex)
+{
+ return lex->ss;
+}
+
+
void
lex_destroy (struct lexer *lexer)
{
void
lex_discard_rest_of_command (struct lexer *lexer)
{
- if (!getl_is_interactive ())
+ if (!getl_is_interactive (lexer->ss))
{
while (lexer->token != T_STOP && lexer->token != '.')
lex_get (lexer);
lex_get_line_raw (struct lexer *lexer, enum getl_syntax *syntax)
{
enum getl_syntax dummy;
- bool ok = lexer->read_line (&lexer->line_buffer,
+ bool ok = getl_read_line (lexer->ss, &lexer->line_buffer,
syntax != NULL ? syntax : &dummy);
return ok;
}
}
}
-/* We're not at eof any more. */
-void
-lex_reset_eof (struct lexer *lexer)
-{
- lexer->eof = false;
-}
-
/* Skip a COMMENT command. */
void
lex_skip_comment (struct lexer *lexer)
struct lexer;
/* Initialization. */
-struct lexer * lex_create (bool (*)(struct string *, enum getl_syntax *));
+struct lexer * lex_create (struct source_stream *);
void lex_destroy (struct lexer *);
-
+struct source_stream * lex_get_source_stream (const struct lexer *);
/* Common functions. */
/* Really weird functions. */
void lex_negative_to_dash (struct lexer *);
-void lex_reset_eof (struct lexer *);
void lex_skip_comment (struct lexer *);
#endif /* !lexer_h */
int
cmd_include (struct lexer *lexer, struct dataset *ds UNUSED)
{
+ struct source_stream *ss;
char *found_fn;
char *target_fn;
target_fn = ds_cstr (lex_tokstr (lexer));
- found_fn = fn_search_path (target_fn,
- getl_include_path (),
- NULL);
+ ss = lex_get_source_stream (lexer);
+ found_fn = fn_search_path (target_fn, getl_include_path ( ss ), NULL);
if (found_fn != NULL)
{
- getl_include_source (create_syntax_file_source (found_fn));
+ getl_include_source (ss, create_syntax_file_source (found_fn));
free (found_fn);
}
else
struct getl_interface *interface;
};
-/* List of source files. */
-static struct ll_list sources ;
+struct source_stream
+ {
+ struct ll_list sources ; /* List of source files. */
-static struct string the_include_path;
+ struct string the_include_path;
+ };
const char *
-getl_include_path (void)
+getl_include_path (const struct source_stream *ss)
{
- return ds_cstr (&the_include_path);
+ return ds_cstr (&ss->the_include_path);
}
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 );
}
/* Initialize getl. */
-void
-getl_initialize (void)
+struct source_stream *
+create_source_stream (void)
{
- ll_init (&sources);
- ds_init_cstr (&the_include_path,
+ struct source_stream *ss = xzalloc (sizeof (*ss));
+ ll_init (&ss->sources);
+ ds_init_cstr (&ss->the_include_path,
fn_getenv_default ("STAT_INCLUDE_PATH", include_path));
+ 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);
+ ds_clear (&ss->the_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, ':');
+ if (ds_length (&ss->the_include_path))
+ ds_put_char (&ss->the_include_path, ':');
- ds_put_cstr (&the_include_path, path);
+ ds_put_cstr (&ss->the_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)
{
struct getl_source *s = xzalloc (sizeof ( struct getl_source ));
s->interface = i ;
- ll_push_head (&sources, &s->ll);
+ ll_push_head (&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)
{
- 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->includes = NULL;
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
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 )
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);
}
/* 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);
+ const struct getl_source *s = current_source (ss);
if ( !s->interface->interactive (s->interface) )
- close_source ();
+ 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
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 )
/* Returns the location within the current source, or -1 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) )
+ if ( ll_is_empty (&ss->sources) )
return -1;
if ( !s->interface->location )
/* 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);
+ ds_destroy (&ss->the_include_path);
+
+ free (ss);
}
Returns true when a line has been read, false at end of input.
On success, sets *SYNTAX to the style of the syntax read. */
bool
-do_read_line (struct string *line, enum getl_syntax *syntax)
+getl_read_line (struct source_stream *ss, struct string *line,
+ enum getl_syntax *syntax)
{
- while (!ll_is_empty (&sources))
+ 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, syntax))
s->interface->filter (s->interface, line, *syntax);
s = s->included_from;
}
-
+
return true;
}
- close_source ();
+ close_source (ss);
}
return false;
#include <stdbool.h>
#include <libpspp/ll.h>
-struct string;
+struct string;
struct getl_source;
/* Syntax rules that apply to a given source line. */
-enum getl_syntax
+enum getl_syntax
{
/* Each line that begins in column 1 starts a new command. A
`+' or `-' in column 1 is ignored to allow visual
GETL_INTERACTIVE
};
-/* An abstract base class for objects which act as line buffers for the
+/* An abstract base class for objects which act as line buffers for the
PSPP. Ie anything which might contain content for the lexer */
-struct getl_interface
+struct getl_interface
{
/* Returns true if the interface is interactive, that is, if
it prompts a human user. This property is independent of
the syntax mode returned by the read member function. */
- bool (*interactive) (const struct getl_interface *);
+ bool (*interactive) (const struct getl_interface *);
/* Read a line the intended syntax mode from the interface.
Returns true if succesful, false on failure or at end of
int (*location) (const struct getl_interface *);
};
-void getl_initialize (void);
-void getl_uninitialize (void);
+struct source_stream;
-void getl_clear_include_path (void);
-void getl_add_include_dir (const char *);
-const char * getl_include_path (void);
+struct source_stream * create_source_stream (void);
+void destroy_source_stream (struct source_stream *);
-void getl_abort_noninteractive (void);
-bool getl_is_interactive (void);
+void getl_clear_include_path (struct source_stream *);
+void getl_add_include_dir (struct source_stream *, const char *);
+const char * getl_include_path (const struct source_stream *);
-bool getl_read_line (bool *interactive);
+void getl_abort_noninteractive (struct source_stream *);
+bool getl_is_interactive (const struct source_stream *);
-bool do_read_line (struct string *line, enum getl_syntax *syntax);
+bool getl_read_line (struct source_stream *, struct string *,
+ enum getl_syntax *);
-void getl_append_source (struct getl_interface *s) ;
-void getl_include_source (struct getl_interface *s) ;
+void getl_append_source (struct source_stream *, struct getl_interface *s) ;
+void getl_include_source (struct source_stream *, struct getl_interface *s) ;
-const char * getl_source_name (void);
-int getl_source_location (void);
+const char * getl_source_name (const struct source_stream *);
+int getl_source_location (const struct source_stream *);
#endif /* line-buffer.h */
msg_emit (&m);
}
+static struct source_stream *s_stream;
+
void
-msg_init ( void (*handler) (const struct msg *) )
+msg_init (struct source_stream *ss, void (*handler) (const struct msg *) )
{
+ s_stream = ss;
msg_handler = handler;
}
void
msg_emit (struct msg *m)
{
- get_msg_location (&m->where);
+ get_msg_location (s_stream, &m->where);
if (!messages_disabled)
msg_handler (m);
free (m->text);
char *text; /* Error text. */
};
+struct source_stream ;
+
/* Initialization. */
-void msg_init ( void (*handler) (const struct msg *) );
+void msg_init (struct source_stream *, void (*handler) (const struct msg *) );
void msg_done (void);
/* Puts the current file and line number into LOC, or NULL and -1 if
none. */
void
-get_msg_location (struct msg_locator *loc)
+get_msg_location (const struct source_stream *ss, struct msg_locator *loc)
{
if (nfile_loc)
{
}
else
{
- loc->file_name = getl_source_name ();
- loc->line_number = getl_source_location ();
+ loc->file_name = getl_source_name (ss);
+ loc->line_number = getl_source_location (ss);
}
}
item on top of the stack. */
void msg_pop_msg_locator (const struct msg_locator *loc);
+struct source_stream ;
/* Puts the current file and line number into LOC, or NULL and -1 if
none. */
-void get_msg_location (struct msg_locator *loc);
+void get_msg_location (const struct source_stream *ss, struct msg_locator *loc);
void
-message_dialog_init (void)
+message_dialog_init (struct source_stream *ss)
{
message_queue = g_queue_new();
- msg_init (enqueue_msg);
+ msg_init (ss, enqueue_msg);
}
void
#include <libpspp/message.h>
-void message_dialog_init (void);
+struct source_stream ;
+
+void message_dialog_init (struct source_stream *);
void message_dialog_done (void);
void popup_message(const struct msg *m);
void create_icon_factory (void);
+static struct source_stream *the_source_stream ;
+
int
main(int argc, char *argv[])
{
fmt_init();
settings_init();
- getl_initialize ();
- message_dialog_init();
+ the_source_stream = create_source_stream ();
+ message_dialog_init (the_source_stream);
the_dictionary = psppire_dict_new();
/* start the event loop */
gtk_main();
- getl_uninitialize ();
+ destroy_source_stream (the_source_stream);
message_dialog_done();
settings_done();
char *subst_vars (char *);
+
/* Parses the command line specified by ARGC and ARGV as received by
main(). Returns true if normal execution should proceed,
false if the command-line indicates that PSPP should exit. */
bool
-parse_command_line (int argc, char **argv)
+parse_command_line (int argc, char **argv, struct source_stream *ss)
{
static struct option long_options[] =
{
break;
case 'I':
if (optarg == NULL || !strcmp (optarg, "-"))
- getl_clear_include_path ();
+ getl_clear_include_path (ss);
else
- getl_add_include_dir (optarg);
+ getl_add_include_dir (ss, optarg);
break;
case 'l':
outp_list_classes ();
char *pspprc_fn = fn_search_path ("rc", config_path, NULL);
if (pspprc_fn != NULL)
{
- getl_append_source (create_syntax_file_source (pspprc_fn));
+ getl_append_source (ss, create_syntax_file_source (pspprc_fn));
free (pspprc_fn);
}
outp_configure_macro (argv[i]);
else
{
- getl_append_source (create_syntax_file_source (argv[i]));
+ getl_append_source (ss, create_syntax_file_source (argv[i]));
syntax_files++;
}
if (!syntax_files || interactive_mode)
- getl_append_source (create_readln_source () );
+ getl_append_source (ss, create_readln_source () );
return true;
}
#include <stdbool.h>
-bool parse_command_line (int argc, char **argv);
+struct source_stream ;
+
+bool parse_command_line (int argc, char **argv, struct source_stream *);
#endif /* cmdline.h */
static struct dataset * the_dataset = NULL;
static struct lexer *the_lexer;
+static struct source_stream *the_source_stream ;
+
/* Program entry point. */
int
outp_init ();
fn_init ();
fh_init ();
- getl_initialize ();
+ the_source_stream = create_source_stream ();
prompt_init ();
readln_initialize ();
settings_init ();
random_init ();
the_dataset = create_dataset ();
- if (parse_command_line (argc, argv))
+ if (parse_command_line (argc, argv, the_source_stream))
{
- msg_ui_init ();
+ msg_ui_init (the_source_stream);
outp_read_devices ();
- the_lexer = lex_create (do_read_line);
+ the_lexer = lex_create (the_source_stream);
for (;;)
{
? CMD_STATE_DATA : CMD_STATE_INITIAL);
if (result == CMD_EOF || result == CMD_FINISH)
break;
- if (result == CMD_CASCADING_FAILURE && !getl_is_interactive ())
+ if (result == CMD_CASCADING_FAILURE &&
+ !getl_is_interactive (the_source_stream))
{
msg (SE, _("Stopping syntax file processing here to avoid "
"a cascade of dependent command failures."));
- getl_abort_noninteractive ();
+ getl_abort_noninteractive (the_source_stream);
}
else
- check_msg_count ();
+ check_msg_count (the_source_stream);
}
}
settings_done ();
fh_done ();
lex_destroy (the_lexer);
- getl_uninitialize ();
+ destroy_source_stream (the_source_stream);
prompt_done ();
readln_uninitialize ();
}
void
-msg_ui_init (void)
+msg_ui_init (struct source_stream *ss)
{
msg_file = stdout;
msg_file = stdout;
}
}
- msg_init (handle_msg);
+ msg_init (ss, handle_msg);
}
void
fclose (msg_file);
}
-
/* Checks whether we've had so many errors that it's time to quit
processing this syntax file. */
void
-check_msg_count (void)
+check_msg_count (struct source_stream *ss)
{
- if (!getl_is_interactive ())
+ if (!getl_is_interactive (ss))
{
if (get_errorbreak () && error_count)
msg (MN, _("Terminating execution of syntax file due to error."));
else
return;
- getl_abort_noninteractive ();
+ getl_abort_noninteractive (ss);
}
}
#include <stdbool.h>
+struct source_stream ;
+
void msg_ui_set_error_file (const char *filename);
-void msg_ui_init (void);
+void msg_ui_init (struct source_stream *);
void msg_ui_done (void);
-void check_msg_count (void);
+void check_msg_count (struct source_stream *);
void reset_msg_count (void);
bool any_errors (void);