diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-10-17 18:45:22 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-10-23 08:06:17 +0100 |
commit | 138f27f65d7f92e313be212cdcaee05aa09a7586 (patch) | |
tree | 65d608f9cbae7487cd30f4ac6a3b8c5bfa32cce1 /core/parse.h | |
parent | 343808271c22942992f4470c05e138d8597a630b (diff) | |
download | subsurface-138f27f65d7f92e313be212cdcaee05aa09a7586.tar.gz |
Parser: make parser (mostly) reentrant
Introduce a parser_state structure, which describes (most) of the
global parser state. Create such a structure in the entry routines
to the parser and pass it down to the individual functions. The
parser state is initialized and freed with the init_parser_state()
and free_parser_state() functions.
The main benefits are:
1) Isolation of parser state.
2) Keeping the global name space tidy.
3) Prevent memory leaks which could happen in truncated files by
freeing all the parser state after parse.
A somewhat controversial point might be that the individual
parsing functions are split in those that need parser-state and
those that don't. This means that there are now two versions of
the MATCH macro, viz. one for the former and one for the latter.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core/parse.h')
-rw-r--r-- | core/parse.h | 127 |
1 files changed, 72 insertions, 55 deletions
diff --git a/core/parse.h b/core/parse.h index bcdbe03c6..d56609e79 100644 --- a/core/parse.h +++ b/core/parse.h @@ -9,20 +9,9 @@ typedef union { char allocation[sizeof(struct event) + MAX_EVENT_NAME]; } event_allocation_t; -extern event_allocation_t event_allocation; -#define cur_event event_allocation.event - /* * Dive info as it is being built up.. */ -extern struct divecomputer *cur_dc; -extern struct dive *cur_dive; -extern struct dive_site *cur_dive_site; -extern location_t cur_location; -extern dive_trip_t *cur_trip; -extern struct sample *cur_sample; -extern struct picture *cur_picture; - struct parser_settings { struct { @@ -31,66 +20,94 @@ struct parser_settings { const char *nickname, *serial_nr, *firmware; } dc; }; -extern struct parser_settings cur_settings; - -extern bool in_settings; -extern bool in_userid; -extern struct tm cur_tm; -extern int cur_cylinder_index, cur_ws_index; -extern int lastcylinderindex, next_o2_sensor; -extern int o2pressure_sensor; -extern struct extra_data cur_extra_data; enum import_source { UNKNOWN, LIBDIVECOMPUTER, DIVINGLOG, UDDF, -} import_source; +}; + +/* + * parser_state is the state needed by the parser(s). It is initialized + * with init_parser_state() and resources are freed with free_parser_state(). + * "owning" marks pointers to objects that are freed in free_parser_state(). + * In contrast, "non-owning" marks pointers to objects that are owned + * by other data-structures. + */ +struct parser_state { + bool metric; + struct parser_settings cur_settings; + enum import_source import_source; + + struct divecomputer *cur_dc; /* non-owning */ + struct dive *cur_dive; /* owning */ + struct dive_site *cur_dive_site; /* owning */ + location_t cur_location; + dive_trip_t *cur_trip; /* owning */ + struct sample *cur_sample; /* non-owning */ + struct picture *cur_picture; /* owning */ + char *country, *city; /* owning */ + + bool in_settings; + bool in_userid; + struct tm cur_tm; + int cur_cylinder_index, cur_ws_index; + int lastcylinderindex, next_o2_sensor; + int o2pressure_sensor; + struct extra_data cur_extra_data; + struct units xml_parsing_units; + struct dive_table *target_table; /* non-owning */ + + sqlite3 *sql_handle; /* for SQL based parsers */ + event_allocation_t event_allocation; +}; + +#define cur_event event_allocation.event + +void init_parser_state(struct parser_state *state); +void free_parser_state(struct parser_state *state); /* the dive table holds the overall dive list; target table points at * the table we are currently filling */ extern struct dive_table dive_table; -extern struct dive_table *target_table; - -extern int metric; int trimspace(char *buffer); void start_match(const char *type, const char *name, char *buffer); void nonmatch(const char *type, const char *name, char *buffer); -void event_start(void); -void event_end(void); -struct divecomputer *get_dc(void); - -bool is_dive(void); -void reset_dc_info(struct divecomputer *dc); -void reset_dc_settings(void); -void settings_start(void); -void settings_end(void); -void dc_settings_start(void); -void dc_settings_end(void); -void dive_site_start(void); -void dive_site_end(void); -void dive_start(void); -void dive_end(void); -void trip_start(void); -void trip_end(void); -void picture_start(void); -void picture_end(void); -void cylinder_start(void); -void cylinder_end(void); -void ws_start(void); -void ws_end(void); - -void sample_start(void); -void sample_end(void); -void divecomputer_start(void); -void divecomputer_end(void); -void userid_start(void); -void userid_stop(void); +void event_start(struct parser_state *state); +void event_end(struct parser_state *state); +struct divecomputer *get_dc(struct parser_state *state); + +bool is_dive(struct parser_state *state); +void reset_dc_info(struct divecomputer *dc, struct parser_state *state); +void reset_dc_settings(struct parser_state *state); +void settings_start(struct parser_state *state); +void settings_end(struct parser_state *state); +void dc_settings_start(struct parser_state *state); +void dc_settings_end(struct parser_state *state); +void dive_site_start(struct parser_state *state); +void dive_site_end(struct parser_state *state); +void dive_start(struct parser_state *state); +void dive_end(struct parser_state *state); +void trip_start(struct parser_state *state); +void trip_end(struct parser_state *state); +void picture_start(struct parser_state *state); +void picture_end(struct parser_state *state); +void cylinder_start(struct parser_state *state); +void cylinder_end(struct parser_state *state); +void ws_start(struct parser_state *state); +void ws_end(struct parser_state *state); + +void sample_start(struct parser_state *state); +void sample_end(struct parser_state *state); +void divecomputer_start(struct parser_state *state); +void divecomputer_end(struct parser_state *state); +void userid_start(struct parser_state *state); +void userid_stop(struct parser_state *state); void utf8_string(char *buffer, void *_res); -void add_dive_site(char *ds_name, struct dive *dive); +void add_dive_site(char *ds_name, struct dive *dive, struct parser_state *state); int atoi_n(char *ptr, unsigned int len); #endif |