summaryrefslogtreecommitdiffstats
path: root/core/parse.h
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2018-10-17 18:45:22 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2018-10-23 08:06:17 +0100
commit138f27f65d7f92e313be212cdcaee05aa09a7586 (patch)
tree65d608f9cbae7487cd30f4ac6a3b8c5bfa32cce1 /core/parse.h
parent343808271c22942992f4470c05e138d8597a630b (diff)
downloadsubsurface-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.h127
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