diff --git a/core/import-cobalt.cpp b/core/import-cobalt.cpp index 3e150c64b..1155c7091 100644 --- a/core/import-cobalt.cpp +++ b/core/import-cobalt.cpp @@ -131,7 +131,7 @@ static int cobalt_dive(void *param, int, char **data, char **) settings_start(state); dc_settings_start(state); if (data[9]) { - utf8_string(data[9], &state->cur_settings.dc.serial_nr); + utf8_string_std(data[9], &state->cur_settings.dc.serial_nr); state->cur_settings.dc.deviceid = atoi(data[9]); state->cur_settings.dc.model = strdup("Cobalt import"); } @@ -211,14 +211,12 @@ extern "C" int parse_cobalt_buffer(sqlite3 *handle, const char *url, const char int retval; struct parser_state state; - init_parser_state(&state); state.log = log; state.sql_handle = handle; char get_dives[] = "select Id,strftime('%s',DiveStartTime),LocationId,'buddy','notes',Units,(MaxDepthPressure*10000/SurfacePressure)-10000,DiveMinutes,SurfacePressure,SerialNumber,'model' from Dive where IsViewDeleted = 0"; retval = sqlite3_exec(handle, get_dives, &cobalt_dive, &state, NULL); - free_parser_state(&state); if (retval != SQLITE_OK) { fprintf(stderr, "Database query failed '%s'.\n", url); diff --git a/core/import-divinglog.cpp b/core/import-divinglog.cpp index e146604f6..4609b2207 100644 --- a/core/import-divinglog.cpp +++ b/core/import-divinglog.cpp @@ -388,14 +388,12 @@ extern "C" int parse_divinglog_buffer(sqlite3 *handle, const char *url, const ch int retval; struct parser_state state; - init_parser_state(&state); state.log = log; state.sql_handle = handle; char get_dives[] = "select Number,strftime('%s',Divedate || ' ' || ifnull(Entrytime,'00:00')),Country || ' - ' || City || ' - ' || Place,Buddy,Comments,Depth,Divetime,Divemaster,Airtemp,Watertemp,Weight,Divesuit,Computer,ID,Visibility,SupplyType from Logbook where UUID not in (select UUID from DeletedRecords)"; retval = sqlite3_exec(handle, get_dives, &divinglog_dive, &state, NULL); - free_parser_state(&state); if (retval != SQLITE_OK) { fprintf(stderr, "Database query failed '%s'.\n", url); diff --git a/core/import-seac.cpp b/core/import-seac.cpp index 4d0efd3dd..ac52ea18a 100644 --- a/core/import-seac.cpp +++ b/core/import-seac.cpp @@ -205,8 +205,10 @@ static int seac_dive(void *param, int, char **data, char **) settings_start(state); dc_settings_start(state); - utf8_string(data[1], &state->cur_dive->dc.serial); - utf8_string(data[12], &state->cur_dive->dc.fw_version); + // These dc values are const char *, therefore we have to cast. + // Will be fixed by converting to std::string + utf8_string(data[1], (char **)&state->cur_dive->dc.serial); + utf8_string(data[12], (char **)&state->cur_dive->dc.fw_version); state->cur_dive->dc.model = strdup("Seac Action"); state->cur_dive->dc.deviceid = calculate_string_hash(data[1]); @@ -268,7 +270,6 @@ extern "C" int parse_seac_buffer(sqlite3 *handle, const char *url, const char *, char *err = NULL; struct parser_state state; - init_parser_state(&state); state.log = log; state.sql_handle = handle; @@ -290,7 +291,6 @@ extern "C" int parse_seac_buffer(sqlite3 *handle, const char *url, const char *, */ retval = sqlite3_exec(handle, get_dives, &seac_dive, &state, &err); - free_parser_state(&state); if (retval != SQLITE_OK) { fprintf(stderr, "Database query failed '%s'.\n", url); diff --git a/core/import-shearwater.cpp b/core/import-shearwater.cpp index 0bf330444..8bb0708cc 100644 --- a/core/import-shearwater.cpp +++ b/core/import-shearwater.cpp @@ -262,7 +262,7 @@ static int shearwater_dive(void *param, int, char **data, char **) settings_start(state); dc_settings_start(state); if (data[9]) - utf8_string(data[9], &state->cur_settings.dc.serial_nr); + utf8_string_std(data[9], &state->cur_settings.dc.serial_nr); if (data[10]) { switch (atoi(data[10])) { case 2: @@ -392,7 +392,7 @@ static int shearwater_cloud_dive(void *param, int, char **data, char **) settings_start(state); dc_settings_start(state); if (data[9]) - utf8_string(data[9], &state->cur_settings.dc.serial_nr); + utf8_string_std(data[9], &state->cur_settings.dc.serial_nr); if (data[10]) { switch (atoi(data[10])) { case 2: @@ -477,7 +477,6 @@ extern "C" int parse_shearwater_buffer(sqlite3 *handle, const char *url, const c int retval; struct parser_state state; - init_parser_state(&state); state.log = log; state.sql_handle = handle; @@ -487,7 +486,6 @@ extern "C" int parse_shearwater_buffer(sqlite3 *handle, const char *url, const c char get_dives[] = "select l.number,timestamp,location||' / '||site,buddy,notes,imperialUnits,maxDepth,maxTime,startSurfacePressure,computerSerial,computerModel,i.diveId FROM dive_info AS i JOIN dive_logs AS l ON i.diveId=l.diveId"; retval = sqlite3_exec(handle, get_dives, &shearwater_dive, &state, NULL); - free_parser_state(&state); if (retval != SQLITE_OK) { fprintf(stderr, "Database query failed '%s'.\n", url); @@ -502,14 +500,12 @@ extern "C" int parse_shearwater_cloud_buffer(sqlite3 *handle, const char *url, c int retval; struct parser_state state; - init_parser_state(&state); state.log = log; state.sql_handle = handle; char get_dives[] = "select l.number,strftime('%s', DiveDate),location||' / '||site,buddy,notes,imperialUnits,maxDepth,DiveLengthTime,startSurfacePressure,computerSerial,computerModel,d.diveId,l.sampleRateMs / 1000 FROM dive_details AS d JOIN dive_logs AS l ON d.diveId=l.diveId"; retval = sqlite3_exec(handle, get_dives, &shearwater_cloud_dive, &state, NULL); - free_parser_state(&state); if (retval != SQLITE_OK) { fprintf(stderr, "Database query failed '%s'.\n", url); diff --git a/core/import-suunto.cpp b/core/import-suunto.cpp index 3d76888e8..af5fa256b 100644 --- a/core/import-suunto.cpp +++ b/core/import-suunto.cpp @@ -198,9 +198,9 @@ static int dm4_dive(void *param, int, char **data, char **) settings_start(state); dc_settings_start(state); if (data[4]) - utf8_string(data[4], &state->cur_settings.dc.serial_nr); + utf8_string_std(data[4], &state->cur_settings.dc.serial_nr); if (data[5]) - utf8_string(data[5], &state->cur_settings.dc.model); + utf8_string_std(data[5], &state->cur_settings.dc.model); state->cur_settings.dc.deviceid = 0xffffffff; dc_settings_end(state); @@ -293,7 +293,6 @@ extern "C" int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *, char *err = NULL; struct parser_state state; - init_parser_state(&state); state.log = log; state.sql_handle = handle; @@ -302,7 +301,6 @@ extern "C" int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *, char get_dives[] = "select D.DiveId,StartTime/10000000-62135596800,Note,Duration,SourceSerialNumber,Source,MaxDepth,SampleInterval,StartTemperature,BottomTemperature,D.StartPressure,D.EndPressure,Size,CylinderWorkPressure,SurfacePressure,DiveTime,SampleInterval,ProfileBlob,TemperatureBlob,PressureBlob,Oxygen,Helium,MIX.StartPressure,MIX.EndPressure FROM Dive AS D JOIN DiveMixture AS MIX ON D.DiveId=MIX.DiveId"; retval = sqlite3_exec(handle, get_dives, &dm4_dive, &state, &err); - free_parser_state(&state); if (retval != SQLITE_OK) { fprintf(stderr, "Database query failed '%s'.\n", url); @@ -391,11 +389,11 @@ static int dm5_dive(void *param, int, char **data, char **) settings_start(state); dc_settings_start(state); if (data[4]) { - utf8_string(data[4], &state->cur_settings.dc.serial_nr); + utf8_string_std(data[4], &state->cur_settings.dc.serial_nr); state->cur_settings.dc.deviceid = atoi(data[4]); } if (data[5]) - utf8_string(data[5], &state->cur_settings.dc.model); + utf8_string_std(data[5], &state->cur_settings.dc.model); dc_settings_end(state); settings_end(state); @@ -410,8 +408,10 @@ static int dm5_dive(void *param, int, char **data, char **) if (data[4]) { state->cur_dive->dc.deviceid = atoi(data[4]); } + // Ugh. dc.model is const char * -> we are not supposed to write into it. This will + // change when we convert to std::string. if (data[5]) - utf8_string(data[5], &state->cur_dive->dc.model); + utf8_string(data[5], (char **)&state->cur_dive->dc.model); if (data[25]) { switch(atoi(data[25])) { @@ -565,7 +565,6 @@ extern "C" int parse_dm5_buffer(sqlite3 *handle, const char *url, const char *, char *err = NULL; struct parser_state state; - init_parser_state(&state); state.log = log; state.sql_handle = handle; @@ -574,7 +573,6 @@ extern "C" int parse_dm5_buffer(sqlite3 *handle, const char *url, const char *, char get_dives[] = "select DiveId,StartTime/10000000-62135596800,Note,Duration,coalesce(SourceSerialNumber,SerialNumber),Source,MaxDepth,SampleInterval,StartTemperature,BottomTemperature,StartPressure,EndPressure,'','',SurfacePressure,DiveTime,SampleInterval,ProfileBlob,TemperatureBlob,PressureBlob,'','','','',SampleBlob,Mode FROM Dive where Deleted is null"; retval = sqlite3_exec(handle, get_dives, &dm5_dive, &state, &err); - free_parser_state(&state); if (retval != SQLITE_OK) { fprintf(stderr, "Database query failed '%s'.\n", url); @@ -583,4 +581,3 @@ extern "C" int parse_dm5_buffer(sqlite3 *handle, const char *url, const char *, return 0; } - diff --git a/core/parse-xml.cpp b/core/parse-xml.cpp index 0d0e2d864..eb2364003 100644 --- a/core/parse-xml.cpp +++ b/core/parse-xml.cpp @@ -383,11 +383,10 @@ static void duration(const char *buffer, duration_t *time) * store the dive time as 44.00 instead of 44:00; * This attempts to parse this in a fairly robust way */ if (!strchr(buffer, ':') && strchr(buffer, '.')) { - char *mybuffer = strdup(buffer); - char *dot = strchr(mybuffer, '.'); + std::string mybuffer(buffer); + char *dot = strchr(mybuffer.data(), '.'); *dot = ':'; - sampletime(mybuffer, time); - free(mybuffer); + sampletime(mybuffer.data(), time); } else { sampletime(buffer, time); } @@ -739,15 +738,15 @@ static void parse_libdc_deco(const char *buffer, struct sample *s) static void try_to_fill_dc_settings(const char *name, char *buf, struct parser_state *state) { start_match("divecomputerid", name, buf); - if (MATCH("model.divecomputerid", utf8_string, &state->cur_settings.dc.model)) + if (MATCH("model.divecomputerid", utf8_string_std, &state->cur_settings.dc.model)) return; if (MATCH("deviceid.divecomputerid", hex_value, &state->cur_settings.dc.deviceid)) return; - if (MATCH("nickname.divecomputerid", utf8_string, &state->cur_settings.dc.nickname)) + if (MATCH("nickname.divecomputerid", utf8_string_std, &state->cur_settings.dc.nickname)) return; - if (MATCH("serial.divecomputerid", utf8_string, &state->cur_settings.dc.serial_nr)) + if (MATCH("serial.divecomputerid", utf8_string_std, &state->cur_settings.dc.serial_nr)) return; - if (MATCH("firmware.divecomputerid", utf8_string, &state->cur_settings.dc.firmware)) + if (MATCH("firmware.divecomputerid", utf8_string_std, &state->cur_settings.dc.firmware)) return; nonmatch("divecomputerid", name, buf); @@ -764,7 +763,7 @@ static void try_to_fill_fingerprint(const char *name, char *buf, struct parser_s return; if (MATCH("diveid.fingerprint", hex_value, &state->cur_settings.fingerprint.fdiveid)) return; - if (MATCH("data.fingerprint", utf8_string, &state->cur_settings.fingerprint.data)) + if (MATCH("data.fingerprint", utf8_string_std, &state->cur_settings.fingerprint.data)) return; nonmatch("fingerprint", name, buf); } @@ -830,9 +829,9 @@ static int match_dc_data_fields(struct divecomputer *dc, const char *name, char return 1; if (MATCH("salinity.water", salinity, &dc->salinity)) return 1; - if (MATCH("key.extradata", utf8_string, &state->cur_extra_data.key)) + if (MATCH("key.extradata", utf8_string, (char **)&state->cur_extra_data.key)) return 1; - if (MATCH("value.extradata", utf8_string, &state->cur_extra_data.value)) + if (MATCH("value.extradata", utf8_string, (char **)&state->cur_extra_data.value)) return 1; if (MATCH("divemode", get_dc_type, &dc->divemode)) return 1; @@ -854,7 +853,7 @@ static void try_to_fill_dc(struct divecomputer *dc, const char *name, char *buf, return; if (MATCH_STATE("time", divetime, &dc->when)) return; - if (MATCH("model", utf8_string, &dc->model)) + if (MATCH("model", utf8_string, (char **)&dc->model)) return; if (MATCH("deviceid", hex_value, &deviceid)) return; @@ -968,11 +967,11 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu return; switch (state->import_source) { - case DIVINGLOG: + case parser_state::DIVINGLOG: if (divinglog_fill_sample(sample, name, buf, state)) return; break; - case UDDF: + case parser_state::UDDF: if (uddf_fill_sample(sample, name, buf, state)) return; break; @@ -992,27 +991,25 @@ static void divinglog_place(const char *place, struct dive *d, struct parser_sta snprintf(buffer, sizeof(buffer), "%s%s%s%s%s", place, - state->city ? ", " : "", - state->city ? state->city : "", - state->country ? ", " : "", - state->country ? state->country : ""); + !state->city.empty() ? ", " : "", + !state->city.empty() ? state->city.c_str() : "", + !state->country.empty() ? ", " : "", + !state->country.empty() ? state->country.c_str() : ""); ds = get_dive_site_by_name(buffer, state->log->sites); if (!ds) ds = create_dive_site(buffer, state->log->sites); add_dive_to_dive_site(d, ds); // TODO: capture the country / city info in the taxonomy instead - free(state->city); - free(state->country); - state->city = NULL; - state->country = NULL; + state->city.clear(); + state->country.clear(); } static int divinglog_dive_match(struct dive *dive, const char *name, char *buf, struct parser_state *state) { /* For cylinder related fields, we might have to create a cylinder first. */ cylinder_t cyl = empty_cylinder; - if (MATCH("tanktype", utf8_string, &cyl.type.description)) { + if (MATCH("tanktype", utf8_string, (char **)&cyl.type.description)) { cylinder_t *cyl0 = get_or_create_cylinder(dive, 0); free((void *)cyl0->type.description); cyl0->type.description = cyl.type.description; @@ -1041,8 +1038,8 @@ static int divinglog_dive_match(struct dive *dive, const char *name, char *buf, MATCH_STATE("depthavg", depth, &dive->dc.meandepth) || MATCH("comments", utf8_string, &dive->notes) || MATCH("names.buddy", utf8_string, &dive->buddy) || - MATCH("name.country", utf8_string, &state->country) || - MATCH("name.city", utf8_string, &state->city) || + MATCH("name.country", utf8_string_std, &state->country) || + MATCH("name.city", utf8_string_std, &state->city) || MATCH_STATE("name.place", divinglog_place, dive) || 0; } @@ -1259,12 +1256,12 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, str start_match("dive", name, buf); switch (state->import_source) { - case DIVINGLOG: + case parser_state::DIVINGLOG: if (divinglog_dive_match(dive, name, buf, state)) return; break; - case UDDF: + case parser_state::UDDF: if (uddf_dive_match(dive, name, buf, state)) return; break; @@ -1362,7 +1359,7 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, str if (MATCH_STATE("airpressure.dive", pressure, &dive->surface_pressure)) return; if (ws) { - if (MATCH("description.weightsystem", utf8_string, &ws->description)) + if (MATCH("description.weightsystem", utf8_string, (char **)&ws->description)) return; if (MATCH_STATE("weight.weightsystem", weight, &ws->weight)) return; @@ -1378,7 +1375,7 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, str return; if (MATCH_STATE("workpressure.cylinder", pressure, &cyl->type.workingpressure)) return; - if (MATCH("description.cylinder", utf8_string, &cyl->type.description)) + if (MATCH("description.cylinder", utf8_string, (char **)&cyl->type.description)) return; if (MATCH_STATE("start.cylinder", pressure, &cyl->start)) return; @@ -1424,7 +1421,7 @@ static void try_to_fill_trip(dive_trip_t *dive_trip, const char *name, char *buf static void try_to_fill_dive_site(struct parser_state *state, const char *name, char *buf) { struct dive_site *ds = state->cur_dive_site; - char *taxonomy_value = NULL; + std::string taxonomy_value; start_match("divesite", name, buf); @@ -1442,7 +1439,7 @@ static void try_to_fill_dive_site(struct parser_state *state, const char *name, return; if (MATCH("origin.geo", get_index, &state->taxonomy_origin)) return; - if (MATCH("value.geo", utf8_string, &taxonomy_value)) { + if (MATCH("value.geo", utf8_string_std, &taxonomy_value)) { /* The code assumes that "value.geo" comes last, which is against * the expectations of an XML file. Let's at least make sure that * cat and origin have been set! */ @@ -1450,10 +1447,9 @@ static void try_to_fill_dive_site(struct parser_state *state, const char *name, report_error("Warning: taxonomy value without origin or category"); } else { taxonomy_set_category(&ds->taxonomy, (taxonomy_category)state->taxonomy_category, - taxonomy_value, (taxonomy_origin)state->taxonomy_origin); + taxonomy_value.c_str(), (taxonomy_origin)state->taxonomy_origin); } state->taxonomy_category = state->taxonomy_origin = -1; - free(taxonomy_value); return; } @@ -1464,10 +1460,9 @@ static void try_to_fill_filter(struct filter_preset *filter, const char *name, c { start_match("filterpreset", name, buf); - char *s = NULL; - if (MATCH("name", utf8_string, &s)) { - filter_preset_set_name(filter, s); - free(s); + std::string s; + if (MATCH("name", utf8_string_std, &s)) { + filter_preset_set_name(filter, s.c_str()); return; } @@ -1478,9 +1473,9 @@ static void try_to_fill_fulltext(const char *name, char *buf, struct parser_stat { start_match("fulltext", name, buf); - if (MATCH("mode", utf8_string, &state->fulltext_string_mode)) + if (MATCH("mode", utf8_string_std, &state->fulltext_string_mode)) return; - if (MATCH("fulltext", utf8_string, &state->fulltext)) + if (MATCH("fulltext", utf8_string_std, &state->fulltext)) return; nonmatch("fulltext", name, buf); @@ -1490,15 +1485,15 @@ static void try_to_fill_filter_constraint(const char *name, char *buf, struct pa { start_match("fulltext", name, buf); - if (MATCH("type", utf8_string, &state->filter_constraint_type)) + if (MATCH("type", utf8_string_std, &state->filter_constraint_type)) return; - if (MATCH("string_mode", utf8_string, &state->filter_constraint_string_mode)) + if (MATCH("string_mode", utf8_string_std, &state->filter_constraint_string_mode)) return; - if (MATCH("range_mode", utf8_string, &state->filter_constraint_range_mode)) + if (MATCH("range_mode", utf8_string_std, &state->filter_constraint_range_mode)) return; if (MATCH("negate", get_bool, &state->filter_constraint_negate)) return; - if (MATCH("constraint", utf8_string, &state->filter_constraint)) + if (MATCH("constraint", utf8_string_std, &state->filter_constraint)) return; nonmatch("fulltext", name, buf); @@ -1536,7 +1531,7 @@ static bool entry(const char *name, char *buf, struct parser_state *state) try_to_fill_filter(state->cur_filter, name, buf); return true; } - if (!state->cur_event.deleted) { + if (state->event_active) { try_to_fill_event(name, buf, state); return true; } @@ -1633,7 +1628,7 @@ static bool visit(xmlNode *n, struct parser_state *state) static void DivingLog_importer(struct parser_state *state) { - state->import_source = DIVINGLOG; + state->import_source = parser_state::DIVINGLOG; /* * Diving Log units are really strange. @@ -1650,7 +1645,7 @@ static void DivingLog_importer(struct parser_state *state) static void uddf_importer(struct parser_state *state) { - state->import_source = UDDF; + state->import_source = parser_state::UDDF; state->xml_parsing_units = SI_units; state->xml_parsing_units.pressure = units::PASCALS; state->xml_parsing_units.temperature = units::KELVIN; @@ -1737,7 +1732,7 @@ static void reset_all(struct parser_state *state) * dive for that format. */ state->xml_parsing_units = SI_units; - state->import_source = UNKNOWN; + state->import_source = parser_state::UNKNOWN; } /* divelog.de sends us xml files that claim to be iso-8859-1 @@ -1773,7 +1768,6 @@ extern "C" int parse_xml_buffer(const char *url, const char *buffer, int, struct int ret = 0; struct parser_state state; - init_parser_state(&state); state.log = log; state.fingerprints = &fingerprint_table; // simply use the global table for now doc = xmlReadMemory(res, strlen(res), url, NULL, XML_PARSE_HUGE | XML_PARSE_RECOVER); @@ -1794,7 +1788,6 @@ extern "C" int parse_xml_buffer(const char *url, const char *buffer, int, struct ret = -1; } dive_end(&state); - free_parser_state(&state); xmlFreeDoc(doc); return ret; } @@ -1837,7 +1830,6 @@ extern "C" int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divel cylinder_t *cyl; struct parser_state state; - init_parser_state(&state); state.log = log; // Check for the correct file magic @@ -2307,7 +2299,6 @@ extern "C" int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divel divecomputer_end(&state); dive_end(&state); - free_parser_state(&state); return 0; } diff --git a/core/parse.cpp b/core/parse.cpp index a9a19be3d..ee5150c18 100644 --- a/core/parse.cpp +++ b/core/parse.cpp @@ -19,41 +19,21 @@ #include "device.h" #include "gettext.h" -extern "C" void init_parser_state(struct parser_state *state) +parser_state::~parser_state() { - memset(state, 0, sizeof(*state)); - state->metric = true; - state->cur_event.deleted = 1; - state->sample_rate = 0; -} - -extern "C" void free_parser_state(struct parser_state *state) -{ - free_dive(state->cur_dive); - free_trip(state->cur_trip); - free_dive_site(state->cur_dive_site); - free_filter_preset(state->cur_filter); - free((void *)state->cur_extra_data.key); - free((void *)state->cur_extra_data.value); - free((void *)state->cur_settings.dc.model); - free((void *)state->cur_settings.dc.nickname); - free((void *)state->cur_settings.dc.serial_nr); - free((void *)state->cur_settings.dc.firmware); - free(state->country); - free(state->city); - free(state->fulltext); - free(state->fulltext_string_mode); - free(state->filter_constraint_type); - free(state->filter_constraint_string_mode); - free(state->filter_constraint_range_mode); - free(state->filter_constraint); + free_dive(cur_dive); + free_trip(cur_trip); + free_dive_site(cur_dive_site); + free_filter_preset(cur_filter); + free((void *)cur_extra_data.key); + free((void *)cur_extra_data.value); } /* * If we don't have an explicit dive computer, * we use the implicit one that every dive has.. */ -extern "C" struct divecomputer *get_dc(struct parser_state *state) +struct divecomputer *get_dc(struct parser_state *state) { return state->cur_dc ?: &state->cur_dive->dc; } @@ -80,13 +60,13 @@ extern "C" void nonmatch(const char *type, const char *name, char *buffer) type, name, buffer); } -extern "C" void event_start(struct parser_state *state) +void event_start(struct parser_state *state) { memset(&state->cur_event, 0, sizeof(state->cur_event)); - state->cur_event.deleted = 0; /* Active */ + state->event_active = true; /* Active */ } -extern "C" void event_end(struct parser_state *state) +void event_end(struct parser_state *state) { struct divecomputer *dc = get_dc(state); if (state->cur_event.type == 123) { @@ -121,7 +101,7 @@ extern "C" void event_end(struct parser_state *state) ev->gas.mix = state->cur_event.gas.mix; } } - state->cur_event.deleted = 1; /* No longer active */ + state->event_active = false; /* No longer active */ } /* @@ -136,81 +116,76 @@ extern "C" void event_end(struct parser_state *state) * to make a dive valid, but if it has no location, no date and no * samples I'm pretty sure it's useless. */ -extern "C" bool is_dive(struct parser_state *state) +bool is_dive(struct parser_state *state) { return state->cur_dive && (state->cur_dive->dive_site || state->cur_dive->when || state->cur_dive->dc.samples); } -extern "C" void reset_dc_info(struct divecomputer *, struct parser_state *state) +void reset_dc_info(struct divecomputer *, struct parser_state *state) { /* WARN: reset dc info does't touch the dc? */ state->lastcylinderindex = 0; } -extern "C" void reset_dc_settings(struct parser_state *state) +void reset_dc_settings(struct parser_state *state) { - free((void *)state->cur_settings.dc.model); - free((void *)state->cur_settings.dc.nickname); - free((void *)state->cur_settings.dc.serial_nr); - free((void *)state->cur_settings.dc.firmware); - state->cur_settings.dc.model = NULL; - state->cur_settings.dc.nickname = NULL; - state->cur_settings.dc.serial_nr = NULL; - state->cur_settings.dc.firmware = NULL; + state->cur_settings.dc.model.clear(); + state->cur_settings.dc.nickname.clear(); + state->cur_settings.dc.serial_nr.clear(); + state->cur_settings.dc.firmware.clear(); state->cur_settings.dc.deviceid = 0; } -extern "C" void reset_fingerprint(struct parser_state *state) +void reset_fingerprint(struct parser_state *state) { - free((void *)state->cur_settings.fingerprint.data); - state->cur_settings.fingerprint.data = NULL; + state->cur_settings.fingerprint.data.clear(); state->cur_settings.fingerprint.model = 0; state->cur_settings.fingerprint.serial = 0; state->cur_settings.fingerprint.fdeviceid = 0; state->cur_settings.fingerprint.fdiveid = 0; } -extern "C" void settings_start(struct parser_state *state) +void settings_start(struct parser_state *state) { state->in_settings = true; } -extern "C" void settings_end(struct parser_state *state) +void settings_end(struct parser_state *state) { state->in_settings = false; } -extern "C" void fingerprint_settings_start(struct parser_state *state) +void fingerprint_settings_start(struct parser_state *state) { reset_fingerprint(state); } -extern "C" void fingerprint_settings_end(struct parser_state *state) +void fingerprint_settings_end(struct parser_state *state) { create_fingerprint_node_from_hex(state->fingerprints, state->cur_settings.fingerprint.model, state->cur_settings.fingerprint.serial, - state->cur_settings.fingerprint.data, + state->cur_settings.fingerprint.data.c_str(), state->cur_settings.fingerprint.fdeviceid, state->cur_settings.fingerprint.fdiveid); } -extern "C" void dc_settings_start(struct parser_state *state) +void dc_settings_start(struct parser_state *state) { reset_dc_settings(state); } -extern "C" void dc_settings_end(struct parser_state *state) +void dc_settings_end(struct parser_state *state) { create_device_node(state->log->devices, - state->cur_settings.dc.model, - state->cur_settings.dc.serial_nr, - state->cur_settings.dc.nickname); + state->cur_settings.dc.model.c_str(), + state->cur_settings.dc.serial_nr.c_str(), + state->cur_settings.dc.nickname.c_str()); reset_dc_settings(state); } -extern "C" void dive_site_start(struct parser_state *state) +void dive_site_start(struct parser_state *state) { if (state->cur_dive_site) return; @@ -219,7 +194,7 @@ extern "C" void dive_site_start(struct parser_state *state) state->cur_dive_site = (dive_site *)calloc(1, sizeof(struct dive_site)); } -extern "C" void dive_site_end(struct parser_state *state) +void dive_site_end(struct parser_state *state) { if (!state->cur_dive_site) return; @@ -234,66 +209,60 @@ extern "C" void dive_site_end(struct parser_state *state) state->cur_dive_site = NULL; } -extern "C" void filter_preset_start(struct parser_state *state) +void filter_preset_start(struct parser_state *state) { if (state->cur_filter) return; state->cur_filter = alloc_filter_preset(); } -extern "C" void filter_preset_end(struct parser_state *state) +void filter_preset_end(struct parser_state *state) { add_filter_preset_to_table(state->cur_filter, state->log->filter_presets); free_filter_preset(state->cur_filter); state->cur_filter = NULL; } -extern "C" void fulltext_start(struct parser_state *state) +void fulltext_start(struct parser_state *state) { if (!state->cur_filter) return; state->in_fulltext = true; } -extern "C" void fulltext_end(struct parser_state *state) +void fulltext_end(struct parser_state *state) { if (!state->in_fulltext) return; - filter_preset_set_fulltext(state->cur_filter, state->fulltext, state->fulltext_string_mode); - free(state->fulltext); - free(state->fulltext_string_mode); - state->fulltext = NULL; - state->fulltext_string_mode = NULL; + filter_preset_set_fulltext(state->cur_filter, state->fulltext.c_str(), state->fulltext_string_mode.c_str()); + state->fulltext.clear(); + state->fulltext_string_mode.clear(); state->in_fulltext = false; } -extern "C" void filter_constraint_start(struct parser_state *state) +void filter_constraint_start(struct parser_state *state) { if (!state->cur_filter) return; state->in_filter_constraint = true; } -extern "C" void filter_constraint_end(struct parser_state *state) +void filter_constraint_end(struct parser_state *state) { if (!state->in_filter_constraint) return; - filter_preset_add_constraint(state->cur_filter, state->filter_constraint_type, state->filter_constraint_string_mode, - state->filter_constraint_range_mode, state->filter_constraint_negate, state->filter_constraint); - free(state->filter_constraint_type); - free(state->filter_constraint_string_mode); - free(state->filter_constraint_range_mode); - free(state->filter_constraint); + filter_preset_add_constraint(state->cur_filter, state->filter_constraint_type.c_str(), state->filter_constraint_string_mode.c_str(), + state->filter_constraint_range_mode.c_str(), state->filter_constraint_negate, state->filter_constraint.c_str()); - state->filter_constraint_type = NULL; - state->filter_constraint_string_mode = NULL; - state->filter_constraint_range_mode = NULL; + state->filter_constraint_type.clear(); + state->filter_constraint_string_mode.clear(); + state->filter_constraint_range_mode.clear(); state->filter_constraint_negate = false; - state->filter_constraint = NULL; + state->filter_constraint.clear(); state->in_filter_constraint = false; } -extern "C" void dive_start(struct parser_state *state) +void dive_start(struct parser_state *state) { if (state->cur_dive) return; @@ -303,7 +272,7 @@ extern "C" void dive_start(struct parser_state *state) state->o2pressure_sensor = 1; } -extern "C" void dive_end(struct parser_state *state) +void dive_end(struct parser_state *state) { if (!state->cur_dive) return; @@ -320,7 +289,7 @@ extern "C" void dive_end(struct parser_state *state) state->cur_location.lon.udeg = 0; } -extern "C" void trip_start(struct parser_state *state) +void trip_start(struct parser_state *state) { if (state->cur_trip) return; @@ -329,7 +298,7 @@ extern "C" void trip_start(struct parser_state *state) memset(&state->cur_tm, 0, sizeof(state->cur_tm)); } -extern "C" void trip_end(struct parser_state *state) +void trip_end(struct parser_state *state) { if (!state->cur_trip) return; @@ -337,32 +306,32 @@ extern "C" void trip_end(struct parser_state *state) state->cur_trip = NULL; } -extern "C" void picture_start(struct parser_state *state) +void picture_start(struct parser_state *state) { } -extern "C" void picture_end(struct parser_state *state) +void picture_end(struct parser_state *state) { add_picture(&state->cur_dive->pictures, state->cur_picture); /* dive_add_picture took ownership, we can just clear out copy of the data */ state->cur_picture = empty_picture; } -extern "C" cylinder_t *cylinder_start(struct parser_state *state) +cylinder_t *cylinder_start(struct parser_state *state) { return add_empty_cylinder(&state->cur_dive->cylinders); } -extern "C" void cylinder_end(struct parser_state *state) +void cylinder_end(struct parser_state *state) { } -extern "C" void ws_start(struct parser_state *state) +void ws_start(struct parser_state *state) { add_cloned_weightsystem(&state->cur_dive->weightsystems, empty_weightsystem); } -extern "C" void ws_end(struct parser_state *state) +void ws_end(struct parser_state *state) { } @@ -392,7 +361,7 @@ static int sanitize_sensor_id(const struct dive *d, int nr) * or the second cylinder depending on what isn't an * oxygen cylinder. */ -extern "C" void sample_start(struct parser_state *state) +void sample_start(struct parser_state *state) { struct divecomputer *dc = get_dc(state); struct sample *sample = prepare_sample(dc); @@ -409,7 +378,7 @@ extern "C" void sample_start(struct parser_state *state) state->next_o2_sensor = 0; } -extern "C" void sample_end(struct parser_state *state) +void sample_end(struct parser_state *state) { if (!state->cur_dive) return; @@ -418,7 +387,7 @@ extern "C" void sample_end(struct parser_state *state) state->cur_sample = NULL; } -extern "C" void divecomputer_start(struct parser_state *state) +void divecomputer_start(struct parser_state *state) { struct divecomputer *dc; @@ -441,19 +410,19 @@ extern "C" void divecomputer_start(struct parser_state *state) reset_dc_info(dc, state); } -extern "C" void divecomputer_end(struct parser_state *state) +void divecomputer_end(struct parser_state *state) { if (!state->cur_dc->when) state->cur_dc->when = state->cur_dive->when; state->cur_dc = NULL; } -extern "C" void userid_start(struct parser_state *state) +void userid_start(struct parser_state *state) { state->in_userid = true; } -extern "C" void userid_stop(struct parser_state *state) +void userid_stop(struct parser_state *state) { state->in_userid = false; } @@ -463,9 +432,8 @@ extern "C" void userid_stop(struct parser_state *state) * therefore make sure to only pass in to NULL-initialized pointers or pointers * to owned strings */ -extern "C" void utf8_string(const char *buffer, void *_res) +extern "C" void utf8_string(const char *buffer, char **res) { - char **res = (char **)_res; free(*res); while (isspace(*buffer)) ++buffer; @@ -496,7 +464,7 @@ void utf8_string_std(const char *buffer, std::string *res) *res = std::string(buffer, end - buffer); } -extern "C" void add_dive_site(const char *ds_name, struct dive *dive, struct parser_state *state) +void add_dive_site(const char *ds_name, struct dive *dive, struct parser_state *state) { const char *buffer = ds_name; std::string trimmed = trimspace(buffer); diff --git a/core/parse.h b/core/parse.h index 9a1c1d26b..d8da4ace8 100644 --- a/core/parse.h +++ b/core/parse.h @@ -21,89 +21,85 @@ typedef union { char allocation[sizeof(struct event) + MAX_EVENT_NAME]; } event_allocation_t; +#ifdef __cplusplus + /* * Dive info as it is being built up.. + * C++-only so we can use std::string */ struct parser_settings { struct { - const char *model; - uint32_t deviceid; - const char *nickname, *serial_nr, *firmware; + std::string model; + uint32_t deviceid = 0; + std::string nickname, serial_nr, firmware; } dc; struct { uint32_t model; uint32_t serial; uint32_t fdeviceid; uint32_t fdiveid; - const char *data; + std::string data; } fingerprint; }; -enum import_source { - UNKNOWN, - LIBDIVECOMPUTER, - DIVINGLOG, - UDDF, -}; - /* * 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(). + * "owning" marks pointers to objects that are freed in the destructor. * In contrast, "non-owning" marks pointers to objects that are owned * by other data-structures. */ struct parser_state { - bool metric; + enum import_source { + UNKNOWN, + LIBDIVECOMPUTER, + DIVINGLOG, + UDDF, + }; + + bool metric = true; struct parser_settings cur_settings; - enum import_source import_source; + enum import_source import_source = UNKNOWN; - struct divecomputer *cur_dc; /* non-owning */ - struct dive *cur_dive; /* owning */ - struct dive_site *cur_dive_site; /* owning */ - location_t cur_location; - struct dive_trip *cur_trip; /* owning */ - struct sample *cur_sample; /* non-owning */ - struct picture cur_picture; /* owning */ - struct filter_preset *cur_filter; /* owning */ - char *fulltext; /* owning */ - char *fulltext_string_mode; /* owning */ - char *filter_constraint_type; /* owning */ - char *filter_constraint_string_mode; /* owning */ - char *filter_constraint_range_mode; /* owning */ - bool filter_constraint_negate; - char *filter_constraint; /* owning */ - char *country, *city; /* owning */ - int taxonomy_category, taxonomy_origin; + struct divecomputer *cur_dc = nullptr; /* non-owning */ + struct dive *cur_dive = nullptr; /* owning */ + struct dive_site *cur_dive_site = nullptr; /* owning */ + location_t cur_location { 0 }; + struct dive_trip *cur_trip = nullptr; /* owning */ + struct sample *cur_sample = nullptr; /* non-owning */ + struct picture cur_picture { 0 }; /* owning */ + struct filter_preset *cur_filter = nullptr; /* owning */ + std::string fulltext; /* owning */ + std::string fulltext_string_mode; /* owning */ + std::string filter_constraint_type; /* owning */ + std::string filter_constraint_string_mode; /* owning */ + std::string filter_constraint_range_mode; /* owning */ + bool filter_constraint_negate = false; + std::string filter_constraint; /* owning */ + std::string country, city; /* owning */ + int taxonomy_category = 0, taxonomy_origin = 0; - bool in_settings; - bool in_userid; - bool in_fulltext; - bool in_filter_constraint; - struct tm cur_tm; - int lastcylinderindex, next_o2_sensor; - int o2pressure_sensor; - int sample_rate; - struct extra_data cur_extra_data; + bool in_settings = false; + bool in_userid = false; + bool in_fulltext = false; + bool in_filter_constraint = false; + struct tm cur_tm{ 0 }; + int lastcylinderindex = 0, next_o2_sensor = 0; + int o2pressure_sensor = 0; + int sample_rate = 0; + struct extra_data cur_extra_data{ 0 }; struct units xml_parsing_units; - struct divelog *log; /* non-owning */ - struct fingerprint_table *fingerprints; /* non-owning */ + struct divelog *log = nullptr; /* non-owning */ + struct fingerprint_table *fingerprints = nullptr; /* non-owning */ - sqlite3 *sql_handle; /* for SQL based parsers */ + sqlite3 *sql_handle = nullptr; /* for SQL based parsers */ + bool event_active = false; event_allocation_t event_allocation; + ~parser_state(); }; #define cur_event event_allocation.event -#ifdef __cplusplus -extern "C" { -#endif -void init_parser_state(struct parser_state *state); -void free_parser_state(struct parser_state *state); - -void start_match(const char *type, const char *name, char *buffer); -void nonmatch(const char *type, const char *name, char *buffer); void event_start(struct parser_state *state); void event_end(struct parser_state *state); struct divecomputer *get_dc(struct parser_state *state); @@ -142,10 +138,18 @@ 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(const char *buffer, void *_res); +void utf8_string_std(const char *buffer, std::string *res); void add_dive_site(const char *ds_name, struct dive *dive, struct parser_state *state); + +extern "C" { +#endif + +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); int atoi_n(char *ptr, unsigned int len); +void utf8_string(const char *buffer, char **res); void parse_xml_init(void); int parse_xml_buffer(const char *url, const char *buf, int size, struct divelog *log, const struct xml_params *params);