diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index 356b5f1ce..b5ab6e7ec 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -62,8 +62,8 @@ SOURCES += subsurface-mobile-main.cpp \ core/globals.cpp \ core/liquivision.c \ core/load-git.cpp \ - core/parse-xml.c \ - core/parse.c \ + core/parse-xml.cpp \ + core/parse.cpp \ core/picture.c \ core/pictureobj.cpp \ core/sample.cpp \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index fb6428b94..3733fb2c9 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -134,8 +134,8 @@ set(SUBSURFACE_CORE_LIB_SRCS ostctools.c owning_ptrs.h parse-gpx.cpp - parse-xml.c - parse.c + parse-xml.cpp + parse.cpp parse.h picture.c picture.h diff --git a/core/divesite.c b/core/divesite.c index 46aceb79a..4ea2696d1 100644 --- a/core/divesite.c +++ b/core/divesite.c @@ -62,7 +62,7 @@ struct dive_site *get_dive_site_by_gps(const location_t *loc, struct dive_site_t /* to avoid a bug where we have two dive sites with different name and the same GPS coordinates * and first get the gps coordinates (reading a V2 file) and happen to get back "the other" name, * this function allows us to verify if a very specific name/GPS combination already exists */ -struct dive_site *get_dive_site_by_gps_and_name(char *name, const location_t *loc, struct dive_site_table *ds_table) +struct dive_site *get_dive_site_by_gps_and_name(const char *name, const location_t *loc, struct dive_site_table *ds_table) { int i; struct dive_site *ds; diff --git a/core/divesite.h b/core/divesite.h index a5ddefd8d..29002587f 100644 --- a/core/divesite.h +++ b/core/divesite.h @@ -62,7 +62,7 @@ struct dive_site *create_dive_site(const char *name, struct dive_site_table *ds_ struct dive_site *create_dive_site_with_gps(const char *name, const location_t *, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_name(const char *name, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_gps(const location_t *, struct dive_site_table *ds_table); -struct dive_site *get_dive_site_by_gps_and_name(char *name, const location_t *, struct dive_site_table *ds_table); +struct dive_site *get_dive_site_by_gps_and_name(const char *name, const location_t *, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_gps_proximity(const location_t *, int distance, struct dive_site_table *ds_table); struct dive_site *get_same_dive_site(const struct dive_site *); bool dive_site_is_empty(struct dive_site *ds); diff --git a/core/parse-xml.c b/core/parse-xml.cpp similarity index 92% rename from core/parse-xml.c rename to core/parse-xml.cpp index 895571c7e..0d0e2d864 100644 --- a/core/parse-xml.c +++ b/core/parse-xml.cpp @@ -5,6 +5,7 @@ #endif #include "ssrf.h" + #include #include #include @@ -12,7 +13,6 @@ #include #include #include -#define __USE_XOPEN #include #include #include @@ -42,9 +42,6 @@ int last_xml_version = -1; static xmlDoc *test_xslt_transforms(xmlDoc *doc, const struct xml_params *params); -const struct units SI_units = SI_UNITS; -const struct units IMPERIAL_units = IMPERIAL_UNITS; - static void divedate(const char *buffer, timestamp_t *when, struct parser_state *state) { int d, m, y; @@ -84,7 +81,7 @@ static void divetime(const char *buffer, timestamp_t *when, struct parser_state } /* Libdivecomputer: "2011-03-20 10:22:38" */ -static void divedatetime(char *buffer, timestamp_t *when, struct parser_state *state) +static void divedatetime(const char *buffer, timestamp_t *when, struct parser_state *state) { int y, m, d; int hr, min, sec; @@ -105,7 +102,7 @@ enum ParseState { FINDSTART, FINDEND }; -static void divetags(char *buffer, struct tag_entry **tags) +static void divetags(const char *buffer, struct tag_entry **tags) { int i = 0, start = 0, end = 0; enum ParseState state = FINDEND; @@ -118,9 +115,9 @@ static void divetags(char *buffer, struct tag_entry **tags) } else if (state == FINDEND) { /* Found end of tag */ if (i > 0 && buffer[i - 1] != '\\') { - buffer[i] = '\0'; + std::string s(buffer + start, i - start); state = FINDSTART; - taglist_add_tag(tags, buffer + start); + taglist_add_tag(tags, s.c_str()); } else { state = FINDSTART; } @@ -142,7 +139,7 @@ static void divetags(char *buffer, struct tag_entry **tags) if (end < start) end = len - 1; if (len > 0) { - buffer[end + 1] = '\0'; + std::string s(buffer + start, i - start); taglist_add_tag(tags, buffer + start); } } @@ -184,13 +181,13 @@ union int_or_float { double fp; }; -static enum number_type integer_or_float(char *buffer, union int_or_float *res) +static enum number_type integer_or_float(const char *buffer, union int_or_float *res) { const char *end; return parse_float(buffer, &res->fp, &end); } -static void pressure(char *buffer, pressure_t *pressure, struct parser_state *state) +static void pressure(const char *buffer, pressure_t *pressure, struct parser_state *state) { double mbar = 0.0; union int_or_float val; @@ -201,16 +198,16 @@ static void pressure(char *buffer, pressure_t *pressure, struct parser_state *st if (!val.fp) break; switch (state->xml_parsing_units.pressure) { - case PASCALS: + case units::PASCALS: mbar = val.fp / 100; break; - case BAR: + case units::BAR: /* Assume mbar, but if it's really small, it's bar */ mbar = val.fp; if (fabs(mbar) < 5000) mbar = mbar * 1000; break; - case PSI: + case units::PSI: mbar = psi_to_mbar(val.fp); break; } @@ -224,17 +221,30 @@ static void pressure(char *buffer, pressure_t *pressure, struct parser_state *st } } -static void cylinder_use(char *buffer, enum cylinderuse *cyl_use, struct parser_state *state) +std::string trimspace(const char *s) { - if (trimspace(buffer)) { - int use = cylinderuse_from_text(buffer); + while (isspace(*s)) + ++s; + if (!*s) + return std::string(); + const char *end = s + strlen(s); + while (isspace(end[-1])) + --end; + return std::string(s, end - s); +} + +static void cylinder_use(const char *buffer, enum cylinderuse *cyl_use, struct parser_state *state) +{ + std::string trimmed = trimspace(buffer); + if (!trimmed.empty()) { + enum cylinderuse use = cylinderuse_from_text(trimmed.c_str()); *cyl_use = use; if (use == OXYGEN) state->o2pressure_sensor = state->cur_dive->cylinders.nr - 1; } } -static void salinity(char *buffer, int *salinity) +static void salinity(const char *buffer, int *salinity) { union int_or_float val; switch (integer_or_float(buffer, &val)) { @@ -246,17 +256,17 @@ static void salinity(char *buffer, int *salinity) } } -static void depth(char *buffer, depth_t *depth, struct parser_state *state) +static void depth(const char *buffer, depth_t *depth, struct parser_state *state) { union int_or_float val; switch (integer_or_float(buffer, &val)) { case FLOATVAL: switch (state->xml_parsing_units.length) { - case METERS: + case units::METERS: depth->mm = lrint(val.fp * 1000); break; - case FEET: + case units::FEET: depth->mm = feet_to_mm(val.fp); break; } @@ -281,17 +291,17 @@ static void extra_data_end(struct parser_state *state) state->cur_extra_data.key = state->cur_extra_data.value = NULL; } -static void weight(char *buffer, weight_t *weight, struct parser_state *state) +static void weight(const char *buffer, weight_t *weight, struct parser_state *state) { union int_or_float val; switch (integer_or_float(buffer, &val)) { case FLOATVAL: switch (state->xml_parsing_units.weight) { - case KG: + case units::KG: weight->grams = lrint(val.fp * 1000); break; - case LBS: + case units::LBS: weight->grams = lbs_to_grams(val.fp); break; } @@ -301,20 +311,20 @@ static void weight(char *buffer, weight_t *weight, struct parser_state *state) } } -static void temperature(char *buffer, temperature_t *temperature, struct parser_state *state) +static void temperature(const char *buffer, temperature_t *temperature, struct parser_state *state) { union int_or_float val; switch (integer_or_float(buffer, &val)) { case FLOATVAL: switch (state->xml_parsing_units.temperature) { - case KELVIN: + case units::KELVIN: temperature->mkelvin = lrint(val.fp * 1000); break; - case CELSIUS: + case units::CELSIUS: temperature->mkelvin = C_to_mkelvin(val.fp); break; - case FAHRENHEIT: + case units::FAHRENHEIT: temperature->mkelvin = F_to_mkelvin(val.fp); break; } @@ -328,7 +338,7 @@ static void temperature(char *buffer, temperature_t *temperature, struct parser_ temperature->mkelvin = 0; } -static void sampletime(char *buffer, duration_t *time) +static void sampletime(const char *buffer, duration_t *time) { int i; int hr, min, sec; @@ -353,7 +363,7 @@ static void sampletime(char *buffer, duration_t *time) } } -static void offsettime(char *buffer, offset_t *time) +static void offsettime(const char *buffer, offset_t *time) { duration_t uoffset; int sign = 1; @@ -367,7 +377,7 @@ static void offsettime(char *buffer, offset_t *time) time->seconds = sign * uoffset.seconds; } -static void duration(char *buffer, duration_t *time) +static void duration(const char *buffer, duration_t *time) { /* DivingLog 5.08 (and maybe other versions) appear to sometimes * store the dive time as 44.00 instead of 44:00; @@ -383,7 +393,7 @@ static void duration(char *buffer, duration_t *time) } } -static void percent(char *buffer, fraction_t *fraction) +static void percent(const char *buffer, fraction_t *fraction) { double val; const char *end; @@ -409,7 +419,7 @@ static void percent(char *buffer, fraction_t *fraction) } } -static void gasmix(char *buffer, fraction_t *fraction, struct parser_state *state) +static void gasmix(const char *buffer, fraction_t *fraction, struct parser_state *state) { /* libdivecomputer does negative percentages. */ if (*buffer == '-') @@ -417,14 +427,12 @@ static void gasmix(char *buffer, fraction_t *fraction, struct parser_state *stat percent(buffer, fraction); } -static void gasmix_nitrogen(char *buffer, struct gasmix *gasmix) +static void gasmix_nitrogen(const char *, struct gasmix *) { - UNUSED(buffer); - UNUSED(gasmix); /* Ignore n2 percentages. There's no value in them. */ } -static void cylindersize(char *buffer, volume_t *volume) +static void cylindersize(const char *buffer, volume_t *volume) { union int_or_float val; @@ -439,27 +447,30 @@ static void cylindersize(char *buffer, volume_t *volume) } } -static void event_name(char *buffer, char *name) +static void event_name(const char *buffer, char *name) { - int size = trimspace(buffer); - if (size >= MAX_EVENT_NAME) - size = MAX_EVENT_NAME - 1; - memcpy(name, buffer, size); + std::string trimmed = trimspace(buffer); + size_t size = std::min(trimmed.size(), (size_t)MAX_EVENT_NAME); + memcpy(name, trimmed.data(), size); name[size] = 0; } // We don't use gauge as a mode, and pscr doesn't exist as a libdc divemode -const char *libdc_divemode_text[] = { "oc", "cc", "pscr", "freedive", "gauge"}; +static const char *libdc_divemode_text[] = { "oc", "cc", "pscr", "freedive", "gauge"}; /* Extract the dive computer type from the xml text buffer */ -static void get_dc_type(char *buffer, enum divemode_t *dct) +static void get_dc_type(const char *buffer, enum divemode_t *dct) { - if (trimspace(buffer)) { - for (enum divemode_t i = 0; i < NUM_DIVEMODE; i++) { - if (strcmp(buffer, divemode_text[i]) == 0) - *dct = i; - else if (strcmp(buffer, libdc_divemode_text[i]) == 0) - *dct = i; + std::string trimmed = trimspace(buffer); + if (!trimmed.empty()) { + for (int i = 0; i < NUM_DIVEMODE; i++) { + if (trimmed == divemode_text[i]) { + *dct = (divemode_t)i; + break; + } else if (trimmed == libdc_divemode_text[i]) { + *dct = (divemode_t)i; + break; + } } } } @@ -468,14 +479,11 @@ static void get_dc_type(char *buffer, enum divemode_t *dct) * the string contained in the xml divemode attribute and passed * in buffer, below. Typical xml input would be: * */ -static void event_divemode(char *buffer, int *value) +static void event_divemode(const char *buffer, int *value) { - int size = trimspace(buffer); - if (size >= MAX_EVENT_NAME) - size = MAX_EVENT_NAME - 1; - buffer[size] = 0x0; + std::string trimmed = trimspace(buffer); for (int i = 0; i < NUM_DIVEMODE; i++) { - if (!strcmp(buffer,divemode_text[i])) { + if (trimmed == divemode_text[i]) { *value = i; break; } @@ -492,7 +500,7 @@ static int match_name(const char *pattern, const char *name) return *pattern == '\0' && (*name == '\0' || *name == '.'); } -typedef void (*matchfn_t)(char *buffer, void *); +typedef void (*matchfn_t)(const char *buffer, void *); static int match(const char *pattern, const char *name, matchfn_t fn, char *buf, void *data) { @@ -502,7 +510,7 @@ static int match(const char *pattern, const char *name, return 1; } -typedef void (*matchfn_state_t)(char *buffer, void *, struct parser_state *state); +typedef void (*matchfn_state_t)(const char *buffer, void *, struct parser_state *state); static int match_state(const char *pattern, const char *name, matchfn_state_t fn, char *buf, void *data, struct parser_state *state) { @@ -522,32 +530,32 @@ static int match_state(const char *pattern, const char *name, if (0) (fn)("test", dest, state); \ match_state(pattern, name, (matchfn_state_t) (fn), buf, dest, state); }) -static void get_index(char *buffer, int *i) +static void get_index(const char *buffer, int *i) { *i = atoi(buffer); } -static void get_bool(char *buffer, bool *i) +static void get_bool(const char *buffer, bool *i) { *i = atoi(buffer); } -static void get_uint8(char *buffer, uint8_t *i) +static void get_uint8(const char *buffer, uint8_t *i) { *i = atoi(buffer); } -static void get_uint16(char *buffer, uint16_t *i) +static void get_uint16(const char *buffer, uint16_t *i) { *i = atoi(buffer); } -static void get_bearing(char *buffer, bearing_t *bearing) +static void get_bearing(const char *buffer, bearing_t *bearing) { bearing->degrees = atoi(buffer); } -static void get_rating(char *buffer, int *i) +static void get_rating(const char *buffer, int *i) { int j = atoi(buffer); if (j >= 0 && j <= 5) { @@ -555,24 +563,24 @@ static void get_rating(char *buffer, int *i) } } -static void double_to_o2pressure(char *buffer, o2pressure_t *i) +static void double_to_o2pressure(const char *buffer, o2pressure_t *i) { i->mbar = lrint(ascii_strtod(buffer, NULL) * 1000.0); } -static void hex_value(char *buffer, uint32_t *i) +static void hex_value(const char *buffer, uint32_t *i) { *i = strtoul(buffer, NULL, 16); } -static void dive_site(char *buffer, struct dive *d, struct parser_state *state) +static void dive_site(const char *buffer, struct dive *d, struct parser_state *state) { uint32_t uuid; hex_value(buffer, &uuid); add_dive_to_dive_site(d, get_dive_site_by_uuid(uuid, state->log->sites)); } -static void get_notrip(char *buffer, bool *notrip) +static void get_notrip(const char *buffer, bool *notrip) { *notrip = !strcmp(buffer, "NOTRIP"); } @@ -600,7 +608,7 @@ static void get_notrip(char *buffer, bool *notrip) * - temperature == 32.0 -> garbage, it's a missing temperature (zero converted from C to F) * - temperatures > 32.0 == Fahrenheit */ -static void fahrenheit(char *buffer, temperature_t *temperature) +static void fahrenheit(const char *buffer, temperature_t *temperature) { union int_or_float val; @@ -638,7 +646,7 @@ static void fahrenheit(char *buffer, temperature_t *temperature) * have to have some arbitrary cut-off point where we assume * that smaller values mean bar.. Not good. */ -static void psi_or_bar(char *buffer, pressure_t *pressure) +static void psi_or_bar(const char *buffer, pressure_t *pressure) { union int_or_float val; @@ -663,7 +671,7 @@ static int divinglog_fill_sample(struct sample *sample, const char *name, char * 0; } -static void uddf_gasswitch(char *buffer, struct sample *sample, struct parser_state *state) +static void uddf_gasswitch(const char *buffer, struct sample *sample, struct parser_state *state) { int idx = atoi(buffer); int seconds = sample->time.seconds; @@ -683,7 +691,7 @@ static int uddf_fill_sample(struct sample *sample, const char *name, char *buf, 0; } -static void eventtime(char *buffer, duration_t *duration, struct parser_state *state) +static void eventtime(const char *buffer, duration_t *duration, struct parser_state *state) { sampletime(buffer, duration); if (state->cur_sample) @@ -702,7 +710,7 @@ static void try_to_match_autogroup(const char *name, char *buf, struct parser_st nonmatch("autogroup", name, buf); } -static void get_cylinderindex(char *buffer, int16_t *i, struct parser_state *state) +static void get_cylinderindex(const char *buffer, int16_t *i, struct parser_state *state) { *i = atoi(buffer); if (state->lastcylinderindex != *i) { @@ -711,12 +719,12 @@ static void get_cylinderindex(char *buffer, int16_t *i, struct parser_state *sta } } -static void get_sensor(char *buffer, int16_t *i) +static void get_sensor(const char *buffer, int16_t *i) { *i = atoi(buffer); } -static void parse_libdc_deco(char *buffer, struct sample *s) +static void parse_libdc_deco(const char *buffer, struct sample *s) { if (strcmp(buffer, "deco") == 0) { s->in_deco = true; @@ -976,7 +984,7 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu nonmatch("sample", name, buf); } -static void divinglog_place(char *place, struct dive *d, struct parser_state *state) +static void divinglog_place(const char *place, struct dive *d, struct parser_state *state) { char buffer[1024]; struct dive_site *ds; @@ -1044,7 +1052,7 @@ static int divinglog_dive_match(struct dive *dive, const char *name, char *buf, * * There are many variations on that. This handles the useful cases. */ -static void uddf_datetime(char *buffer, timestamp_t *when, struct parser_state *state) +static void uddf_datetime(const char *buffer, timestamp_t *when, struct parser_state *state) { char c; int y, m, d, hh, mm, ss; @@ -1080,11 +1088,11 @@ success: *when = utc_mktime(&tm); } -#define uddf_datedata(name, offset) \ - static void uddf_##name(char *buffer, timestamp_t *when, struct parser_state *state) \ - { \ - state->cur_tm.tm_##name = atoi(buffer) + offset; \ - *when = utc_mktime(&state->cur_tm); \ +#define uddf_datedata(name, offset) \ + static void uddf_##name(const char *buffer, timestamp_t *when, struct parser_state *state) \ + { \ + state->cur_tm.tm_##name = atoi(buffer) + offset; \ + *when = utc_mktime(&state->cur_tm); \ } uddf_datedata(year, 0) @@ -1154,7 +1162,7 @@ static degrees_t parse_degrees(const char *buf, const char **end) return ret; } -static void gps_lat(char *buffer, struct dive *dive, struct parser_state *state) +static void gps_lat(const char *buffer, struct dive *dive, struct parser_state *state) { const char *end; location_t location = { }; @@ -1170,7 +1178,7 @@ static void gps_lat(char *buffer, struct dive *dive, struct parser_state *state) } } -static void gps_long(char *buffer, struct dive *dive, struct parser_state *state) +static void gps_long(const char *buffer, struct dive *dive, struct parser_state *state) { const char *end; location_t location = { }; @@ -1187,7 +1195,7 @@ static void gps_long(char *buffer, struct dive *dive, struct parser_state *state } /* We allow either spaces or a comma between the decimal degrees */ -void parse_location(const char *buffer, location_t *loc) +extern "C" void parse_location(const char *buffer, location_t *loc) { const char *end; loc->lat = parse_degrees(buffer, &end); @@ -1195,12 +1203,12 @@ void parse_location(const char *buffer, location_t *loc) loc->lon = parse_degrees(end, &end); } -static void gps_location(char *buffer, struct dive_site *ds) +static void gps_location(const char *buffer, struct dive_site *ds) { parse_location(buffer, &ds->location); } -static void gps_in_dive(char *buffer, struct dive *dive, struct parser_state *state) +static void gps_in_dive(const char *buffer, struct dive *dive, struct parser_state *state) { struct dive_site *ds = dive->dive_site; location_t location; @@ -1234,7 +1242,7 @@ static void gps_in_dive(char *buffer, struct dive *dive, struct parser_state *st } } -static void gps_picture_location(char *buffer, struct picture *pic) +static void gps_picture_location(const char *buffer, struct picture *pic) { parse_location(buffer, &pic->location); } @@ -1441,8 +1449,8 @@ static void try_to_fill_dive_site(struct parser_state *state, const char *name, if (state->taxonomy_category < 0 || state->taxonomy_origin < 0) { report_error("Warning: taxonomy value without origin or category"); } else { - taxonomy_set_category(&ds->taxonomy, state->taxonomy_category, - taxonomy_value, state->taxonomy_origin); + taxonomy_set_category(&ds->taxonomy, (taxonomy_category)state->taxonomy_category, + taxonomy_value, (taxonomy_origin)state->taxonomy_origin); } state->taxonomy_category = state->taxonomy_origin = -1; free(taxonomy_value); @@ -1644,8 +1652,8 @@ static void uddf_importer(struct parser_state *state) { state->import_source = UDDF; state->xml_parsing_units = SI_units; - state->xml_parsing_units.pressure = PASCALS; - state->xml_parsing_units.temperature = KELVIN; + state->xml_parsing_units.pressure = units::PASCALS; + state->xml_parsing_units.temperature = units::KELVIN; } typedef void (*parser_func)(struct parser_state *); @@ -1738,7 +1746,7 @@ static void reset_all(struct parser_state *state) * declaration and decode the HTML encoded characters */ static const char *preprocess_divelog_de(const char *buffer) { - char *ret = strstr(buffer, ""); + const char *ret = strstr(buffer, ""); if (ret) { xmlParserCtxtPtr ctx; @@ -1757,10 +1765,9 @@ static const char *preprocess_divelog_de(const char *buffer) return buffer; } -int parse_xml_buffer(const char *url, const char *buffer, int size, struct divelog *log, - const struct xml_params *params) +extern "C" int parse_xml_buffer(const char *url, const char *buffer, int, struct divelog *log, + const struct xml_params *params) { - UNUSED(size); xmlDoc *doc; const char *res = preprocess_divelog_de(buffer); int ret = 0; @@ -1810,7 +1817,7 @@ static timestamp_t parse_dlf_timestamp(unsigned char *buffer) return offset + 946684800; } -int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) +extern "C" int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) { unsigned char *ptr = buffer; unsigned char event; @@ -2136,8 +2143,8 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) char config_buf[256]; // Local variables to temporary decode into struct tm tm; - char *device; - char *deep_stops; + const char *device; + const char *deep_stops; case 0: // TEST_CCR_FULL_1 utc_mkdate(parse_dlf_timestamp(ptr + 12), &tm); snprintf(config_buf, sizeof(config_buf), "START=%04u-%02u-%02u %02u:%02u:%02u,TEST=%02X%02X%02X%02X,RESULT=%02X%02X%02X%02X", tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ptr[7], ptr[6], ptr[5], ptr[4], ptr[11], ptr[10], ptr[9], ptr[8]); @@ -2261,7 +2268,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) /* Recording the starting battery status to extra data */ if (battery_start.volt1) { size_t stringsize = snprintf(NULL, 0, "%dmV (%d%%)", battery_start.volt1, battery_start.percent1) + 1; - char *ptr = malloc(stringsize); + char *ptr = (char *)malloc(stringsize); if (ptr) { snprintf(ptr, stringsize, "%dmV (%d%%)", battery_start.volt1, battery_start.percent1); @@ -2270,7 +2277,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) } stringsize = snprintf(NULL, 0, "%dmV (%d%%)", battery_start.volt2, battery_start.percent2) + 1; - ptr = malloc(stringsize); + ptr = (char *)malloc(stringsize); if (ptr) { snprintf(ptr, stringsize, "%dmV (%d%%)", battery_start.volt2, battery_start.percent2); add_extra_data(state.cur_dc, "Battery 2 (start)", ptr); @@ -2281,7 +2288,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) /* Recording the ending battery status to extra data */ if (battery_end.volt1) { size_t stringsize = snprintf(NULL, 0, "%dmV (%d%%)", battery_end.volt1, battery_end.percent1) + 1; - char *ptr = malloc(stringsize); + char *ptr = (char *)malloc(stringsize); if (ptr) { snprintf(ptr, stringsize, "%dmV (%d%%)", battery_end.volt1, battery_end.percent1); @@ -2290,7 +2297,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) } stringsize = snprintf(NULL, 0, "%dmV (%d%%)", battery_end.volt2, battery_end.percent2) + 1; - ptr = malloc(stringsize); + ptr = (char *)malloc(stringsize); if (ptr) { snprintf(ptr, stringsize, "%dmV (%d%%)", battery_end.volt2, battery_end.percent2); add_extra_data(state.cur_dc, "Battery 2 (end)", ptr); @@ -2305,12 +2312,12 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) } -void parse_xml_init(void) +extern "C" void parse_xml_init(void) { LIBXML_TEST_VERSION } -void parse_xml_exit(void) +extern "C" void parse_xml_exit(void) { xmlCleanupParser(); } diff --git a/core/parse.c b/core/parse.cpp similarity index 75% rename from core/parse.c rename to core/parse.cpp index 5db945ba8..a9a19be3d 100644 --- a/core/parse.c +++ b/core/parse.cpp @@ -19,7 +19,7 @@ #include "device.h" #include "gettext.h" -void init_parser_state(struct parser_state *state) +extern "C" void init_parser_state(struct parser_state *state) { memset(state, 0, sizeof(*state)); state->metric = true; @@ -27,7 +27,7 @@ void init_parser_state(struct parser_state *state) state->sample_rate = 0; } -void free_parser_state(struct parser_state *state) +extern "C" void free_parser_state(struct parser_state *state) { free_dive(state->cur_dive); free_trip(state->cur_trip); @@ -53,63 +53,40 @@ void free_parser_state(struct parser_state *state) * If we don't have an explicit dive computer, * we use the implicit one that every dive has.. */ -struct divecomputer *get_dc(struct parser_state *state) +extern "C" struct divecomputer *get_dc(struct parser_state *state) { return state->cur_dc ?: &state->cur_dive->dc; } -/* Trim a character string by removing leading and trailing white space characters. - * Parameter: a pointer to a null-terminated character string (buffer); - * Return value: length of the trimmed string, excluding the terminal 0x0 byte - * The original pointer (buffer) remains valid after this function has been called - * and points to the trimmed string */ -int trimspace(char *buffer) -{ - int i, size, start, end; - size = strlen(buffer); - - if (!size) - return 0; - for(start = 0; isspace(buffer[start]); start++) - if (start >= size) return 0; // Find 1st character following leading whitespace - for(end = size - 1; isspace(buffer[end]); end--) // Find last character before trailing whitespace - if (end <= 0) return 0; - for(i = start; i <= end; i++) // Move the nonspace characters to the start of the string - buffer[i-start] = buffer[i]; - size = end - start + 1; - buffer[size] = 0x0; // then terminate the string - return size; // return string length -} - /* * Add a dive into the dive_table array */ -void record_dive_to_table(struct dive *dive, struct dive_table *table) +extern "C" void record_dive_to_table(struct dive *dive, struct dive_table *table) { add_to_dive_table(table, table->nr, fixup_dive(dive)); } -void start_match(const char *type, const char *name, char *buffer) +extern "C" void start_match(const char *type, const char *name, char *buffer) { if (verbose > 2) printf("Matching %s '%s' (%s)\n", type, name, buffer); } -void nonmatch(const char *type, const char *name, char *buffer) +extern "C" void nonmatch(const char *type, const char *name, char *buffer) { if (verbose > 1) printf("Unable to match %s '%s' (%s)\n", type, name, buffer); } -void event_start(struct parser_state *state) +extern "C" void event_start(struct parser_state *state) { memset(&state->cur_event, 0, sizeof(state->cur_event)); state->cur_event.deleted = 0; /* Active */ } -void event_end(struct parser_state *state) +extern "C" void event_end(struct parser_state *state) { struct divecomputer *dc = get_dc(state); if (state->cur_event.type == 123) { @@ -159,20 +136,19 @@ 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. */ -bool is_dive(struct parser_state *state) +extern "C" 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); } -void reset_dc_info(struct divecomputer *dc, struct parser_state *state) +extern "C" void reset_dc_info(struct divecomputer *, struct parser_state *state) { /* WARN: reset dc info does't touch the dc? */ - UNUSED(dc); state->lastcylinderindex = 0; } -void reset_dc_settings(struct parser_state *state) +extern "C" void reset_dc_settings(struct parser_state *state) { free((void *)state->cur_settings.dc.model); free((void *)state->cur_settings.dc.nickname); @@ -185,7 +161,7 @@ void reset_dc_settings(struct parser_state *state) state->cur_settings.dc.deviceid = 0; } -void reset_fingerprint(struct parser_state *state) +extern "C" void reset_fingerprint(struct parser_state *state) { free((void *)state->cur_settings.fingerprint.data); state->cur_settings.fingerprint.data = NULL; @@ -195,22 +171,22 @@ void reset_fingerprint(struct parser_state *state) state->cur_settings.fingerprint.fdiveid = 0; } -void settings_start(struct parser_state *state) +extern "C" void settings_start(struct parser_state *state) { state->in_settings = true; } -void settings_end(struct parser_state *state) +extern "C" void settings_end(struct parser_state *state) { state->in_settings = false; } -void fingerprint_settings_start(struct parser_state *state) +extern "C" void fingerprint_settings_start(struct parser_state *state) { reset_fingerprint(state); } -void fingerprint_settings_end(struct parser_state *state) +extern "C" void fingerprint_settings_end(struct parser_state *state) { create_fingerprint_node_from_hex(state->fingerprints, state->cur_settings.fingerprint.model, @@ -219,12 +195,13 @@ void fingerprint_settings_end(struct parser_state *state) state->cur_settings.fingerprint.fdeviceid, state->cur_settings.fingerprint.fdiveid); } -void dc_settings_start(struct parser_state *state) + +extern "C" void dc_settings_start(struct parser_state *state) { reset_dc_settings(state); } -void dc_settings_end(struct parser_state *state) +extern "C" void dc_settings_end(struct parser_state *state) { create_device_node(state->log->devices, state->cur_settings.dc.model, @@ -233,16 +210,16 @@ void dc_settings_end(struct parser_state *state) reset_dc_settings(state); } -void dive_site_start(struct parser_state *state) +extern "C" void dive_site_start(struct parser_state *state) { if (state->cur_dive_site) return; state->taxonomy_category = -1; state->taxonomy_origin = -1; - state->cur_dive_site = calloc(1, sizeof(struct dive_site)); + state->cur_dive_site = (dive_site *)calloc(1, sizeof(struct dive_site)); } -void dive_site_end(struct parser_state *state) +extern "C" void dive_site_end(struct parser_state *state) { if (!state->cur_dive_site) return; @@ -257,28 +234,28 @@ void dive_site_end(struct parser_state *state) state->cur_dive_site = NULL; } -void filter_preset_start(struct parser_state *state) +extern "C" void filter_preset_start(struct parser_state *state) { if (state->cur_filter) return; state->cur_filter = alloc_filter_preset(); } -void filter_preset_end(struct parser_state *state) +extern "C" 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; } -void fulltext_start(struct parser_state *state) +extern "C" void fulltext_start(struct parser_state *state) { if (!state->cur_filter) return; state->in_fulltext = true; } -void fulltext_end(struct parser_state *state) +extern "C" void fulltext_end(struct parser_state *state) { if (!state->in_fulltext) return; @@ -290,14 +267,14 @@ void fulltext_end(struct parser_state *state) state->in_fulltext = false; } -void filter_constraint_start(struct parser_state *state) +extern "C" void filter_constraint_start(struct parser_state *state) { if (!state->cur_filter) return; state->in_filter_constraint = true; } -void filter_constraint_end(struct parser_state *state) +extern "C" void filter_constraint_end(struct parser_state *state) { if (!state->in_filter_constraint) return; @@ -316,7 +293,7 @@ void filter_constraint_end(struct parser_state *state) state->in_filter_constraint = false; } -void dive_start(struct parser_state *state) +extern "C" void dive_start(struct parser_state *state) { if (state->cur_dive) return; @@ -326,7 +303,7 @@ void dive_start(struct parser_state *state) state->o2pressure_sensor = 1; } -void dive_end(struct parser_state *state) +extern "C" void dive_end(struct parser_state *state) { if (!state->cur_dive) return; @@ -343,7 +320,7 @@ void dive_end(struct parser_state *state) state->cur_location.lon.udeg = 0; } -void trip_start(struct parser_state *state) +extern "C" void trip_start(struct parser_state *state) { if (state->cur_trip) return; @@ -352,7 +329,7 @@ void trip_start(struct parser_state *state) memset(&state->cur_tm, 0, sizeof(state->cur_tm)); } -void trip_end(struct parser_state *state) +extern "C" void trip_end(struct parser_state *state) { if (!state->cur_trip) return; @@ -360,32 +337,32 @@ void trip_end(struct parser_state *state) state->cur_trip = NULL; } -void picture_start(struct parser_state *state) +extern "C" void picture_start(struct parser_state *state) { } -void picture_end(struct parser_state *state) +extern "C" 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; } -cylinder_t *cylinder_start(struct parser_state *state) +extern "C" cylinder_t *cylinder_start(struct parser_state *state) { return add_empty_cylinder(&state->cur_dive->cylinders); } -void cylinder_end(struct parser_state *state) +extern "C" void cylinder_end(struct parser_state *state) { } -void ws_start(struct parser_state *state) +extern "C" void ws_start(struct parser_state *state) { add_cloned_weightsystem(&state->cur_dive->weightsystems, empty_weightsystem); } -void ws_end(struct parser_state *state) +extern "C" void ws_end(struct parser_state *state) { } @@ -415,7 +392,7 @@ static int sanitize_sensor_id(const struct dive *d, int nr) * or the second cylinder depending on what isn't an * oxygen cylinder. */ -void sample_start(struct parser_state *state) +extern "C" void sample_start(struct parser_state *state) { struct divecomputer *dc = get_dc(state); struct sample *sample = prepare_sample(dc); @@ -432,7 +409,7 @@ void sample_start(struct parser_state *state) state->next_o2_sensor = 0; } -void sample_end(struct parser_state *state) +extern "C" void sample_end(struct parser_state *state) { if (!state->cur_dive) return; @@ -441,7 +418,7 @@ void sample_end(struct parser_state *state) state->cur_sample = NULL; } -void divecomputer_start(struct parser_state *state) +extern "C" void divecomputer_start(struct parser_state *state) { struct divecomputer *dc; @@ -452,7 +429,7 @@ void divecomputer_start(struct parser_state *state) /* Did we already fill that in? */ if (dc->samples || dc->model || dc->when) { - struct divecomputer *newdc = calloc(1, sizeof(*newdc)); + struct divecomputer *newdc = (divecomputer *)calloc(1, sizeof(*newdc)); if (newdc) { dc->next = newdc; dc = newdc; @@ -464,19 +441,19 @@ void divecomputer_start(struct parser_state *state) reset_dc_info(dc, state); } -void divecomputer_end(struct parser_state *state) +extern "C" void divecomputer_end(struct parser_state *state) { if (!state->cur_dc->when) state->cur_dc->when = state->cur_dive->when; state->cur_dc = NULL; } -void userid_start(struct parser_state *state) +extern "C" void userid_start(struct parser_state *state) { state->in_userid = true; } -void userid_stop(struct parser_state *state) +extern "C" void userid_stop(struct parser_state *state) { state->in_userid = false; } @@ -486,42 +463,64 @@ void userid_stop(struct parser_state *state) * therefore make sure to only pass in to NULL-initialized pointers or pointers * to owned strings */ -void utf8_string(char *buffer, void *_res) +extern "C" void utf8_string(const char *buffer, void *_res) { - char **res = _res; - int size; + char **res = (char **)_res; free(*res); - size = trimspace(buffer); - if(size) - *res = strdup(buffer); + while (isspace(*buffer)) + ++buffer; + if (!*buffer) { + *res = strdup(""); + return; + } + const char *end = buffer + strlen(buffer); + while (isspace(end[-1])) + --end; + size_t len = end - buffer; + *res = (char *)malloc(len + 1); + memcpy(*res, buffer, len); + (*res)[len] = '\0'; } -void add_dive_site(char *ds_name, struct dive *dive, struct parser_state *state) +void utf8_string_std(const char *buffer, std::string *res) { - char *buffer = ds_name; - char *to_free = NULL; - int size = trimspace(buffer); - if (size) { + while (isspace(*buffer)) + ++buffer; + if (!*buffer) { + res->clear(); + return; + } + const char *end = buffer + strlen(buffer); + while (isspace(end[-1])) + --end; + *res = std::string(buffer, end - buffer); +} + +extern "C" 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); + if (!trimmed.empty()) { struct dive_site *ds = dive->dive_site; if (!ds) { // if the dive doesn't have a dive site, check if there's already a dive site by this name - ds = get_dive_site_by_name(buffer, state->log->sites); + ds = get_dive_site_by_name(trimmed.c_str(), state->log->sites); } if (ds) { // we have a dive site, let's hope there isn't a different name if (empty_string(ds->name)) { - ds->name = copy_string(buffer); - } else if (!same_string(ds->name, buffer)) { + ds->name = copy_string(trimmed.c_str()); + } else if (trimmed != ds->name) { // if it's not the same name, it's not the same dive site // but wait, we could have gotten this one based on GPS coords and could // have had two different names for the same site... so let's search the other // way around - struct dive_site *exact_match = get_dive_site_by_gps_and_name(buffer, &ds->location, state->log->sites); + struct dive_site *exact_match = get_dive_site_by_gps_and_name(trimmed.c_str(), &ds->location, state->log->sites); if (exact_match) { unregister_dive_from_dive_site(dive); add_dive_to_dive_site(dive, exact_match); } else { - struct dive_site *newds = create_dive_site(buffer, state->log->sites); + struct dive_site *newds = create_dive_site(trimmed.c_str(), state->log->sites); unregister_dive_from_dive_site(dive); add_dive_to_dive_site(dive, newds); if (has_location(&state->cur_location)) { @@ -538,13 +537,12 @@ void add_dive_site(char *ds_name, struct dive *dive, struct parser_state *state) add_dive_to_dive_site(dive, ds); } } else { - add_dive_to_dive_site(dive, create_dive_site(buffer, state->log->sites)); + add_dive_to_dive_site(dive, create_dive_site(trimmed.c_str(), state->log->sites)); } } - free(to_free); } -int atoi_n(char *ptr, unsigned int len) +extern "C" int atoi_n(char *ptr, unsigned int len) { if (len < 10) { char buf[10]; diff --git a/core/parse.h b/core/parse.h index 108959649..9a1c1d26b 100644 --- a/core/parse.h +++ b/core/parse.h @@ -102,7 +102,6 @@ extern "C" { void init_parser_state(struct parser_state *state); void free_parser_state(struct parser_state *state); -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(struct parser_state *state); @@ -143,9 +142,9 @@ 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 utf8_string(const char *buffer, void *_res); -void add_dive_site(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); int atoi_n(char *ptr, unsigned int len); void parse_xml_init(void); @@ -161,6 +160,8 @@ int parse_divinglog_buffer(sqlite3 *handle, const char *url, const char *buf, in int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log); #ifdef __cplusplus } +#include +std::string trimspace(const char *buffer); #endif #endif diff --git a/core/units.c b/core/units.c index bc91a106e..6d4c5fbbb 100644 --- a/core/units.c +++ b/core/units.c @@ -3,6 +3,15 @@ #include "gettext.h" #include "pref.h" +#define IMPERIAL_UNITS \ + { \ + .length = FEET, .volume = CUFT, .pressure = PSI, .temperature = FAHRENHEIT, .weight = LBS, \ + .vertical_speed_time = MINUTES, .duration_units = MIXED, .show_units_table = false \ + } + +const struct units SI_units = SI_UNITS; +const struct units IMPERIAL_units = IMPERIAL_UNITS; + int get_pressure_units(int mb, const char **units) { int pressure; diff --git a/core/units.h b/core/units.h index 61d1a3e50..806649ba2 100644 --- a/core/units.h +++ b/core/units.h @@ -333,12 +333,6 @@ struct units { .vertical_speed_time = MINUTES, .duration_units = MIXED, .show_units_table = false \ } -#define IMPERIAL_UNITS \ - { \ - .length = FEET, .volume = CUFT, .pressure = PSI, .temperature = FAHRENHEIT, .weight = LBS, \ - .vertical_speed_time = MINUTES, .duration_units = MIXED, .show_units_table = false \ - } - extern const struct units SI_units, IMPERIAL_units; extern const struct units *get_units(void);