summaryrefslogtreecommitdiffstats
path: root/subsurface-core
diff options
context:
space:
mode:
Diffstat (limited to 'subsurface-core')
-rw-r--r--subsurface-core/cochran.c5
-rw-r--r--subsurface-core/compressibility.r115
-rw-r--r--subsurface-core/datatrak.c3
-rw-r--r--subsurface-core/deco.c18
-rw-r--r--subsurface-core/deco.h1
-rw-r--r--subsurface-core/dive.c35
-rw-r--r--subsurface-core/dive.h15
-rw-r--r--subsurface-core/divelist.c58
-rw-r--r--subsurface-core/equipment.c3
-rw-r--r--subsurface-core/file.c15
-rw-r--r--subsurface-core/gas-model.c31
-rw-r--r--subsurface-core/gaspressures.c3
-rw-r--r--subsurface-core/git-access.c5
-rw-r--r--subsurface-core/gpslocation.cpp17
-rw-r--r--subsurface-core/imagedownloader.cpp26
-rw-r--r--subsurface-core/imagedownloader.h2
-rw-r--r--subsurface-core/libdivecomputer.c10
-rw-r--r--subsurface-core/linux.c11
-rw-r--r--subsurface-core/load-git.c3
-rw-r--r--subsurface-core/macos.c9
-rw-r--r--subsurface-core/membuffer.c3
-rw-r--r--subsurface-core/metrics.cpp8
-rw-r--r--subsurface-core/metrics.h3
-rw-r--r--subsurface-core/parse-xml.c13
-rw-r--r--subsurface-core/planner.c29
-rw-r--r--subsurface-core/profile.c22
-rw-r--r--subsurface-core/qthelper.cpp16
-rw-r--r--subsurface-core/qtserialbluetooth.cpp1
-rw-r--r--subsurface-core/save-git.c3
-rw-r--r--subsurface-core/save-html.c3
-rw-r--r--subsurface-core/save-xml.c3
-rw-r--r--subsurface-core/statistics.c8
-rw-r--r--subsurface-core/statistics.h2
-rw-r--r--subsurface-core/subsurfacestartup.c16
-rw-r--r--subsurface-core/time.c6
-rw-r--r--subsurface-core/uemis-downloader.c18
-rw-r--r--subsurface-core/uemis.c6
-rw-r--r--subsurface-core/uemis.h2
-rw-r--r--subsurface-core/units.h2
-rw-r--r--subsurface-core/windows.c6
-rw-r--r--subsurface-core/worldmap-save.c3
41 files changed, 421 insertions, 137 deletions
diff --git a/subsurface-core/cochran.c b/subsurface-core/cochran.c
index 40149d577..b42ed8233 100644
--- a/subsurface-core/cochran.c
+++ b/subsurface-core/cochran.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -431,7 +434,7 @@ static void cochran_dive_event(struct divecomputer *dc, const unsigned char *s,
* Parse sample data, extract events and build a dive
*/
static void cochran_parse_samples(struct dive *dive, const unsigned char *log,
- const unsigned char *samples, int size,
+ const unsigned char *samples, unsigned int size,
unsigned int *duration, double *max_depth,
double *avg_depth, double *min_temp)
{
diff --git a/subsurface-core/compressibility.r b/subsurface-core/compressibility.r
new file mode 100644
index 000000000..66310f3aa
--- /dev/null
+++ b/subsurface-core/compressibility.r
@@ -0,0 +1,115 @@
+# Compressibility data gathered by Lubomir I Ivanov:
+#
+# "Data obtained by finding two books online:
+#
+# [1]
+# PERRY’S CHEMICAL ENGINEERS’ HANDBOOK SEVENTH EDITION
+# pretty serious book, from which the wiki AIR values come from!
+#
+# http://www.unhas.ac.id/rhiza/arsip/kuliah/Sistem-dan-Tekn-Kendali-Proses/PDF_Collections/REFERENSI/Perrys_Chemical_Engineering_Handbook.pdf
+# page 2-165
+#
+# [*](Computed from pressure-volume-temperature tables in Vasserman monographs)
+# ^ i have no idea idea what this means, but the values might not be exactly
+# experimental?!
+#
+# the only thing this book is missing is helium, thus [2]!
+#
+# [2]
+# VOLUMETRIC BEHAVIOR OF HELIUM-ARGON MIXTURES AT HIGH PRESSURE AND MODERATE TEMPERATURE.
+#
+# https://shareok.org/bitstream/handle/11244/2062/6614196.PDF?sequence=1
+# page 108
+#
+#
+# the book has some tables with pressure values in atmosphere units. i'm
+# converting them bars. one of the relevant tables is for 323K and one for 273K
+# (both almost equal distance from 300K).
+#
+# this again is a linear mix operation between isotherms, which is probably not
+# the most accurate solution but it works.
+#
+# all data sets contain Z values at 300k, while the pressures are in bars in
+# the 1 to 500 range
+#
+#
+
+x = c(1, 5, 10, 20, 40, 60, 80, 100, 200, 300, 400, 500)
+o2 = c(0.9994, 0.9968, 0.9941, 0.9884, 0.9771, 0.9676, 0.9597, 0.9542, 0.9560, 0.9972, 1.0689, 1.1572)
+n2 = c(0.9998, 0.9990, 0.9983, 0.9971, 0.9964, 0.9973, 1.0000, 1.0052, 1.0559, 1.1422, 1.2480, 1.3629)
+he = c(1.0005, 1.0024, 1.0048, 1.0096, 1.0191, 1.0286, 1.0381, 1.0476, 1.0943, 1.1402, 1.1854, 1.2297)
+
+options(digits=15)
+
+#
+# Get the O2 virial coefficients
+#
+plot(x,o2)
+o2fit = nls(o2 ~ 1.0 + p1*x + p2 *x^2 + p3*x^3, start=list(p1=0,p2=0,p3=0))
+summary(o2fit)
+
+new = data.frame(x = seq(min(x),max(x),len=200))
+lines(new$x,predict(o2fit,newdata=new))
+
+#
+# Get the N2 virial coefficients
+#
+plot(x,n2)
+n2fit = nls(n2 ~ 1.0 + p1*x + p2 *x^2 + p3*x^3, start=list(p1=0,p2=0,p3=0))
+summary(n2fit)
+
+new = data.frame(x = seq(min(x),max(x),len=200))
+lines(new$x,predict(n2fit,newdata=new))
+
+#
+# Get the He virial coefficients
+#
+# NOTE! This will not confirm convergence, thus the warnOnly.
+# That may be a sign that the data is possibly artificial.
+#
+plot(x,he)
+hefit = nls(he ~ 1.0 + p1*x + p2 *x^2 + p3*x^3,
+ start=list(p1=0,p2=0,p3=0),
+ control=nls.control(warnOnly=TRUE))
+summary(hefit)
+
+new = data.frame(x = seq(min(x),max(x),len=200))
+lines(new$x,predict(hefit,newdata=new))
+
+#
+# Raw data from VOLUMETRIC BEHAVIOR OF HELIUM-ARGON MIXTURES [..]
+# T=323.15K (50 C)
+p323atm = c(674.837, 393.223, 237.310, 146.294, 91.4027, 57.5799, 36.4620, 23.1654, 14.7478, 9.4017, 5.9987, 3.8300,
+ 540.204, 319.943, 195.008, 120.951, 75.8599, 47.9005, 30.3791, 19.3193, 12.3080, 7.8495, 5.0100, 3.1992)
+
+Hez323 = c(1.28067, 1.16782, 1.10289, 1.06407, 1.04028, 1.02548, 1.01617, 1.01029, 1.00656, 1.00418, 1.00267, 1.00171,
+ 1.22738, 1.13754, 1.08493, 1.05312, 1.03349, 1.02122, 1.01349, 1.00859, 1.00548, 1.00349, 1.00223, 1.00143)
+
+
+# T=273.15 (0 C)
+p273atm = c(683.599, 391.213, 233.607, 143.091, 89.0521, 55.9640, 35.3851, 22.4593, 14.2908, 9.1072, 5.8095, 3.7083,
+ 534.047, 312.144, 188.741, 116.508, 72.8529, 45.9194, 29.0883, 18.4851, 11.7702, 7.5040, 4.7881, 3.0570)
+
+Hez273 = c(1.33969, 1.19985, 1.12121, 1.07494, 1.04689, 1.02957, 1.01874, 1.01191, 1.00758, 1.00484, 1.00309, 1.00197,
+ 1.26914, 1.16070, 1.09837, 1.06118, 1.03843, 1.02429, 1.01541, 1.00980, 1.00625, 1.00398, 1.00254, 1.00162)
+
+p323 = p323atm * 1.01325
+p273 = p273atm * 1.01325
+
+x2=append(p323,p273)
+he2=append(Hez323,Hez273)
+
+plot(x2,he2)
+
+hefit2 = nls(he2 ~ 1.0 + p1*x2 + p2*x2^2 + p3*x2^3,
+ start=list(p1=0,p2=0,p3=0))
+summary(hefit2)
+
+he3 = function(bar)
+{
+ 1.0 +0.00047961098687979363 * bar -0.00000004077670019935 * bar^2 +0.00000000000077707035 * bar^3
+}
+
+new = data.frame(x2 = seq(min(x2),max(x2),len=200))
+lines(new$x2,predict(hefit2,newdata=new))
+curve(he3, min(x2),max(x2),add=TRUE)
diff --git a/subsurface-core/datatrak.c b/subsurface-core/datatrak.c
index fb05c1701..204ebd9b3 100644
--- a/subsurface-core/datatrak.c
+++ b/subsurface-core/datatrak.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
diff --git a/subsurface-core/deco.c b/subsurface-core/deco.c
index dff88d338..3cd8c4a16 100644
--- a/subsurface-core/deco.c
+++ b/subsurface-core/deco.c
@@ -34,13 +34,13 @@ extern pressure_t first_ceiling_pressure;
//! Option structure for Buehlmann decompression.
struct buehlmann_config {
- double satmult; //! safety at inert gas accumulation as percentage of effect (more than 100).
- double desatmult; //! safety at inert gas depletion as percentage of effect (less than 100).
- unsigned int last_deco_stop_in_mtr; //! depth of last_deco_stop.
- double gf_high; //! gradient factor high (at surface).
- double gf_low; //! gradient factor low (at bottom/start of deco calculation).
- double gf_low_position_min; //! gf_low_position below surface_min_shallow.
- bool gf_low_at_maxdepth; //! if true, gf_low applies at max depth instead of at deepest ceiling.
+ double satmult; //! safety at inert gas accumulation as percentage of effect (more than 100).
+ double desatmult; //! safety at inert gas depletion as percentage of effect (less than 100).
+ int last_deco_stop_in_mtr; //! depth of last_deco_stop.
+ double gf_high; //! gradient factor high (at surface).
+ double gf_low; //! gradient factor low (at bottom/start of deco calculation).
+ double gf_low_position_min; //! gf_low_position below surface_min_shallow.
+ bool gf_low_at_maxdepth; //! if true, gf_low applies at max depth instead of at deepest ceiling.
};
struct buehlmann_config buehlmann_config = {
@@ -572,9 +572,9 @@ void restore_deco_state(char *data)
memcpy(&ci_pointing_to_guiding_tissue, data, sizeof(int));
}
-unsigned int deco_allowed_depth(double tissues_tolerance, double surface_pressure, struct dive *dive, bool smooth)
+int deco_allowed_depth(double tissues_tolerance, double surface_pressure, struct dive *dive, bool smooth)
{
- unsigned int depth;
+ int depth;
double pressure_delta;
/* Avoid negative depths */
diff --git a/subsurface-core/deco.h b/subsurface-core/deco.h
index 08ff93422..fd3b94a9f 100644
--- a/subsurface-core/deco.h
+++ b/subsurface-core/deco.h
@@ -11,6 +11,7 @@ extern double tissue_inertgas_saturation[16];
extern double buehlmann_inertgas_a[16], buehlmann_inertgas_b[16];
extern double gf_low_pressure_this_dive;
+extern int deco_allowed_depth(double tissues_tolerance, double surface_pressure, struct dive *dive, bool smooth);
#ifdef __cplusplus
}
diff --git a/subsurface-core/dive.c b/subsurface-core/dive.c
index 083767582..8fc9e993b 100644
--- a/subsurface-core/dive.c
+++ b/subsurface-core/dive.c
@@ -58,7 +58,7 @@ int event_gasmix_redundant(struct event *ev)
he == ev->gas.mix.he.permille;
}
-struct event *add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name)
+struct event *add_event(struct divecomputer *dc, unsigned int time, int type, int flags, int value, const char *name)
{
int gas_index = -1;
struct event *ev, **p;
@@ -738,7 +738,8 @@ void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *me
{
int i;
int depthtime[MAX_CYLINDERS] = { 0, };
- int lasttime = 0, lastdepth = 0;
+ uint32_t lasttime = 0;
+ int lastdepth = 0;
int idx = 0;
for (i = 0; i < MAX_CYLINDERS; i++)
@@ -765,7 +766,7 @@ void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *me
dc = fake_dc(dc, false);
for (i = 0; i < dc->samples; i++) {
struct sample *sample = dc->sample + i;
- int time = sample->time.seconds;
+ uint32_t time = sample->time.seconds;
int depth = sample->depth.mm;
/* Make sure to move the event past 'lasttime' */
@@ -2619,7 +2620,8 @@ static struct divetag *taglist_add_divetag(struct tag_entry **tag_list, struct d
struct divetag *taglist_add_tag(struct tag_entry **tag_list, const char *tag)
{
- int i = 0, is_default_tag = 0;
+ size_t i = 0;
+ int is_default_tag = 0;
struct divetag *ret_tag, *new_tag;
const char *translation;
new_tag = malloc(sizeof(struct divetag));
@@ -2675,7 +2677,7 @@ static void taglist_merge(struct tag_entry **dst, struct tag_entry *src1, struct
void taglist_init_global()
{
- int i;
+ size_t i;
for (i = 0; i < sizeof(default_tags) / sizeof(char *); i++)
taglist_add_tag(&g_tag_list, default_tags[i]);
@@ -2846,7 +2848,7 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer
MERGE_TXT(res, a, b, divemaster);
MERGE_MAX(res, a, b, rating);
MERGE_TXT(res, a, b, suit);
- MERGE_MIN(res, a, b, number);
+ MERGE_MAX(res, a, b, number);
MERGE_NONZERO(res, a, b, cns);
MERGE_NONZERO(res, a, b, visibility);
MERGE_NONZERO(res, a, b, picture_list);
@@ -2920,7 +2922,8 @@ static void force_fixup_dive(struct dive *d)
*/
static int split_dive_at(struct dive *dive, int a, int b)
{
- int i, t, nr;
+ int i, nr;
+ uint32_t t;
struct dive *d1, *d2;
struct divecomputer *dc1, *dc2;
struct event *event, **evp;
@@ -3371,7 +3374,7 @@ void dive_set_geodata_from_picture(struct dive *dive, struct picture *picture)
}
}
-static void picture_free(struct picture *picture)
+void picture_free(struct picture *picture)
{
if (!picture)
return;
@@ -3380,6 +3383,18 @@ static void picture_free(struct picture *picture)
free(picture);
}
+// When handling pictures in different threads, we need to copy them so we don't
+// run into problems when the main thread frees the picture.
+
+struct picture *clone_picture(struct picture *src)
+{
+ struct picture *dst;
+
+ dst = alloc_picture();
+ copy_pl(src, dst);
+ return dst;
+}
+
void dive_remove_picture(char *filename)
{
struct picture **picture = &current_dive->picture_list;
@@ -3415,7 +3430,7 @@ void make_first_dc()
}
/* always acts on the current dive */
-int count_divecomputers(void)
+unsigned int count_divecomputers(void)
{
int ret = 1;
struct divecomputer *dc = current_dive->dc.next;
@@ -3455,7 +3470,7 @@ void delete_current_divecomputer(void)
/* helper function to make it easier to work with our structures
* we don't interpolate here, just use the value from the last sample up to that time */
-int get_depth_at_time(struct divecomputer *dc, int time)
+int get_depth_at_time(struct divecomputer *dc, unsigned int time)
{
int depth = 0;
if (dc && dc->sample)
diff --git a/subsurface-core/dive.h b/subsurface-core/dive.h
index f8970b237..204d34819 100644
--- a/subsurface-core/dive.h
+++ b/subsurface-core/dive.h
@@ -376,6 +376,7 @@ struct picture {
for (struct picture *picture = (_divestruct).picture_list; picture; picture = picture->next)
extern struct picture *alloc_picture();
+extern struct picture *clone_picture(struct picture *src);
extern bool dive_check_picture_time(struct dive *d, int shift_time, timestamp_t timestamp);
extern void dive_create_picture(struct dive *d, char *filename, int shift_time, bool match_all);
extern void dive_add_picture(struct dive *d, struct picture *newpic);
@@ -385,9 +386,10 @@ extern bool picture_check_valid(char *filename, int shift_time);
extern void picture_load_exif_data(struct picture *p);
extern timestamp_t picture_get_timestamp(char *filename);
extern void dive_set_geodata_from_picture(struct dive *d, struct picture *pic);
+extern void picture_free(struct picture *picture);
extern int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc);
-extern int get_depth_at_time(struct divecomputer *dc, int time);
+extern int get_depth_at_time(struct divecomputer *dc, unsigned int time);
static inline int get_surface_pressure_in_mbar(const struct dive *dive, bool non_null)
{
@@ -493,7 +495,7 @@ extern const struct units SI_units, IMPERIAL_units;
extern struct units xml_parsing_units;
extern struct units *get_units(void);
-extern int run_survey, verbose, quit;
+extern int run_survey, verbose, quit, force_root;
struct dive_table {
int nr, allocated, preexisting;
@@ -567,7 +569,7 @@ static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr)
extern timestamp_t dive_endtime(const struct dive *dive);
extern void make_first_dc(void);
-extern int count_divecomputers(void);
+extern unsigned int count_divecomputers(void);
extern void delete_current_divecomputer(void);
/*
@@ -695,6 +697,7 @@ extern struct zip *subsurface_zip_open_readonly(const char *path, int flags, int
extern int subsurface_zip_close(struct zip *zip);
extern void subsurface_console_init(bool dedicated);
extern void subsurface_console_exit(void);
+extern bool subsurface_user_is_root(void);
extern void shift_times(const timestamp_t amount);
extern timestamp_t get_times();
@@ -728,7 +731,6 @@ extern unsigned int dc_watertemp(struct divecomputer *dc);
extern int split_dive(struct dive *);
extern struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer_downloaded);
extern struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded);
-extern void renumber_dives(int start_nr, bool selected_only);
extern struct event *clone_event(const struct event *src_ev);
extern void copy_events(struct divecomputer *s, struct divecomputer *d);
extern void free_events(struct event *ev);
@@ -737,7 +739,7 @@ extern void copy_samples(struct divecomputer *s, struct divecomputer *d);
extern bool is_cylinder_used(struct dive *dive, int idx);
extern void fill_default_cylinder(cylinder_t *cyl);
extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx);
-extern struct event *add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name);
+extern struct event *add_event(struct divecomputer *dc, unsigned int time, int type, int flags, int value, const char *name);
extern void remove_event(struct event *event);
extern void update_event_name(struct dive *d, struct event* event, char *name);
extern void add_extra_data(struct divecomputer *dc, const char *key, const char *value);
@@ -792,7 +794,6 @@ extern void subsurface_command_line_exit(int *, char ***);
extern void add_segment(double pressure, const struct gasmix *gasmix, int period_in_seconds, int setpoint, const struct dive *dive, int sac);
extern void clear_deco(double surface_pressure);
extern void dump_tissues(void);
-extern unsigned int deco_allowed_depth(double tissues_tolerance, double surface_pressure, struct dive *dive, bool smooth);
extern void set_gf(short gflow, short gfhigh, bool gf_low_at_maxdepth);
extern void cache_deco_state(char **datap);
extern void restore_deco_state(char *data);
@@ -804,7 +805,7 @@ extern double tissue_tolerance_calc(const struct dive *dive, double pressure);
/* this should be converted to use our types */
struct divedatapoint {
int time;
- unsigned int depth;
+ int depth;
struct gasmix gasmix;
int setpoint;
bool entered;
diff --git a/subsurface-core/divelist.c b/subsurface-core/divelist.c
index 1e9065d8b..543d9e17b 100644
--- a/subsurface-core/divelist.c
+++ b/subsurface-core/divelist.c
@@ -44,6 +44,7 @@
#include "display.h"
#include "planner.h"
#include "qthelperfromc.h"
+#include "git-access.h"
static short dive_list_changed = false;
@@ -205,7 +206,8 @@ int const cns_table[][3] = {
* so we calculated it "by hand" */
static int calculate_cns(struct dive *dive)
{
- int i, j, divenr;
+ int i, divenr;
+ size_t j;
double cns = 0.0;
struct divecomputer *dc = &dive->dc;
struct dive *prev_dive;
@@ -833,10 +835,14 @@ bool consecutive_selected()
return consecutive;
}
+/*
+ * Merge two dives. 'a' is always before 'b' in the dive list
+ * (and thus in time).
+ */
struct dive *merge_two_dives(struct dive *a, struct dive *b)
{
struct dive *res;
- int i, j, factor;
+ int i, j, nr, nrdiff;
int id;
if (!a || !b)
@@ -852,7 +858,30 @@ struct dive *merge_two_dives(struct dive *a, struct dive *b)
if (!res)
return NULL;
- factor = (a->number == 0 || b->number == 0) ? 0 : abs(b->number - a->number);
+ /*
+ * If 'a' and 'b' were numbered, and in proper order,
+ * then the resulting dive will get the first number,
+ * and the subsequent dives will be renumbered by the
+ * difference.
+ *
+ * So if you had a dive list 1 3 6 7 8, and you
+ * merge 1 and 3, the resulting numbered list will
+ * be 1 4 5 6, because we assume that there were
+ * some missing dives (originally dives 4 and 5),
+ * that now will still be missing (dives 2 and 3
+ * in the renumbered world).
+ *
+ * Obviously the normal case is that everything is
+ * consecutive, and the difference will be 1, so the
+ * above example is not supposed to be normal.
+ */
+ nrdiff = 0;
+ nr = a->number;
+ if (a->number && b->number > a->number) {
+ res->number = nr;
+ nrdiff = b->number - nr;
+ }
+
add_single_dive(i, res);
delete_single_dive(i + 1);
delete_single_dive(j);
@@ -863,9 +892,25 @@ struct dive *merge_two_dives(struct dive *a, struct dive *b)
// renumber dives from merged one in advance by difference between
// merged dives numbers. Do not renumber if actual number is zero.
- for (; j < dive_table.nr; j++)
- if (!dive_table.dives[j]->number == 0)
- dive_table.dives[j]->number -= factor;
+ for (; j < dive_table.nr; j++) {
+ struct dive *dive = dive_table.dives[j];
+ int newnr;
+
+ if (!dive->number)
+ continue;
+ newnr = dive->number - nrdiff;
+
+ /*
+ * Don't renumber stuff that isn't in order!
+ *
+ * So if the new dive number isn't larger than the
+ * previous dive number, just stop here.
+ */
+ if (newnr <= nr)
+ break;
+ dive->number = newnr;
+ nr = newnr;
+ }
mark_divelist_changed(true);
return res;
@@ -1158,4 +1203,5 @@ void clear_dive_file_data()
existing_filename = NULL;
reset_min_datafile_version();
+ saved_git_id = "";
}
diff --git a/subsurface-core/equipment.c b/subsurface-core/equipment.c
index 47c439735..9f3e49039 100644
--- a/subsurface-core/equipment.c
+++ b/subsurface-core/equipment.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
/* equipment.c */
#include <stdio.h>
#include <string.h>
diff --git a/subsurface-core/file.c b/subsurface-core/file.c
index 8286ce9f5..1337da3a2 100644
--- a/subsurface-core/file.c
+++ b/subsurface-core/file.c
@@ -57,7 +57,7 @@ int readfile(const char *filename, struct memblock *mem)
if (ret < 0)
goto free;
buf[ret] = 0;
- if (ret == mem->size)
+ if (ret == (int)mem->size) // converting to int loses a bit but size will never be that big
goto out;
errno = EIO;
ret = -1;
@@ -453,8 +453,7 @@ int check_git_sha(const char *filename)
if (git && git != dummy_git_repository) {
const char *sha = get_sha(git, branch);
if (!same_string(sha, "") &&
- same_string(sha, saved_git_id) &&
- !unsaved_changes()) {
+ same_string(sha, saved_git_id)) {
fprintf(stderr, "already have loaded SHA %s - don't load again\n", sha);
return 0;
}
@@ -466,6 +465,7 @@ int parse_file(const char *filename)
{
struct git_repository *git;
const char *branch = NULL;
+ char *current_sha = copy_string(saved_git_id);
struct memblock mem;
char *fmt;
int ret;
@@ -473,22 +473,25 @@ int parse_file(const char *filename)
git = is_git_repository(filename, &branch, NULL, false);
if (prefs.cloud_git_url &&
strstr(filename, prefs.cloud_git_url)
- && git == dummy_git_repository)
+ && git == dummy_git_repository) {
/* opening the cloud storage repository failed for some reason
* give up here and don't send errors about git repositories */
+ free(current_sha);
return 0;
-
+ }
/* if this is a git repository, do we already have this exact state loaded ?
* get the SHA and compare with what we currently have */
if (git && git != dummy_git_repository) {
const char *sha = get_sha(git, branch);
if (!same_string(sha, "") &&
- same_string(sha, saved_git_id) &&
+ same_string(sha, current_sha) &&
!unsaved_changes()) {
fprintf(stderr, "already have loaded SHA %s - don't load again\n", sha);
+ free(current_sha);
return 0;
}
}
+ free(current_sha);
if (git)
return git_load_dives(git, branch);
diff --git a/subsurface-core/gas-model.c b/subsurface-core/gas-model.c
index 81765e003..ad1160f3b 100644
--- a/subsurface-core/gas-model.c
+++ b/subsurface-core/gas-model.c
@@ -26,36 +26,39 @@
double gas_compressibility_factor(struct gasmix *gas, double bar)
{
static const double o2_coefficients[3] = {
- -0.00071809207370164567,
- +0.00000281852572807643,
- -0.00000000150290620491
+ -7.18092073703e-04,
+ +2.81852572808e-06,
+ -1.50290620492e-09
};
static const double n2_coefficients[3] = {
- -0.00021926035329221337,
- +0.00000292844845531647,
- -0.00000000207613482075
+ -2.19260353292e-04,
+ +2.92844845532e-06,
+ -2.07613482075e-09
};
static const double he_coefficients[3] = {
- +0.00047961098687979363,
- -0.00000004077670019935,
- +0.00000000000077707035
+ +4.87320026468e-04,
+ -8.83632921053e-08,
+ +5.33304543646e-11
};
- double o2, he;
+ int o2, he;
double x1, x2, x3;
double Z;
- o2 = get_o2(gas) / 1000.0;
- he = get_he(gas) / 1000.0;
+ o2 = get_o2(gas);
+ he = get_he(gas);
x1 = bar; x2 = x1*x1; x3 = x2*x1;
Z = virial_m1(o2_coefficients, x1, x2, x3) * o2 +
virial_m1(he_coefficients, x1, x2, x3) * he +
- virial_m1(n2_coefficients, x1, x2, x3) * (1.0 - o2 - he);
+ virial_m1(n2_coefficients, x1, x2, x3) * (1000 - o2 - he);
/*
* We add the 1.0 at the very end - the linear mixing of the
* three 1.0 terms is still 1.0 regardless of the gas mix.
+ *
+ * The * 0.001 is because we did the linear mixing using the
+ * raw permille gas values.
*/
- return Z + 1.0;
+ return Z * 0.001 + 1.0;
}
diff --git a/subsurface-core/gaspressures.c b/subsurface-core/gaspressures.c
index 3cbb36773..5d3fc9791 100644
--- a/subsurface-core/gaspressures.c
+++ b/subsurface-core/gaspressures.c
@@ -200,7 +200,7 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
{
int cyl, i;
struct plot_data *entry;
- pr_interpolate_t interpolate = { 0 };
+ pr_interpolate_t interpolate = { 0, 0, 0, 0 };
pr_track_t *last_segment = NULL;
int cur_pr[MAX_CYLINDERS]; // cur_pr[MAX_CYLINDERS] is the CCR diluent cylinder
@@ -347,6 +347,7 @@ static void debug_print_pressures(struct plot_info *pi)
*/
void populate_pressure_information(struct dive *dive, struct divecomputer *dc, struct plot_info *pi, int o2_flag)
{
+ (void) dc;
int i, cylinderid, cylinderindex = -1;
pr_track_t *track_pr[MAX_CYLINDERS] = { NULL, };
pr_track_t *current = NULL;
diff --git a/subsurface-core/git-access.c b/subsurface-core/git-access.c
index e986607ab..c902bf60b 100644
--- a/subsurface-core/git-access.c
+++ b/subsurface-core/git-access.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdio.h>
#include <ctype.h>
#include <string.h>
@@ -664,7 +667,7 @@ static git_repository *create_local_repo(const char *localdir, const char *remot
* to our cloud storage and the branch doesn't exist.
* So we need to create the branch and push it to the remote */
cloned_repo = create_and_push_remote(localdir, remote, branch);
-#if !defined(DEBUG)
+#if !defined(DEBUG) && !defined(SUBSURFACE_MOBILE)
} else if (is_subsurface_cloud) {
report_error(translate("gettextFromC", "Error connecting to Subsurface cloud storage"));
#endif
diff --git a/subsurface-core/gpslocation.cpp b/subsurface-core/gpslocation.cpp
index 9f1961cbf..075b1c046 100644
--- a/subsurface-core/gpslocation.cpp
+++ b/subsurface-core/gpslocation.cpp
@@ -33,7 +33,7 @@ GpsLocation::GpsLocation(void (*showMsgCB)(const char *), QObject *parent) : QOb
QString("org.subsurfacedivelog"), QString("subsurfacelocation"), this);
#ifdef SUBSURFACE_MOBILE
if (hasLocationsSource())
- status("Found GPS");
+ status(QString("Found GPS with positioning methods %1").arg(QString::number(m_GpsSource->supportedPositioningMethods(), 16)));
#endif
userAgent = getUserAgent();
loadFromStorage();
@@ -59,8 +59,7 @@ QGeoPositionInfoSource *GpsLocation::getGpsSource()
#ifndef SUBSURFACE_MOBILE
if (verbose)
#endif
- status("created GPS source");
- QString msg = QString("have position source %1").arg(m_GpsSource->sourceName());
+ status(QString("Created position source %1").arg(m_GpsSource->sourceName()));
connect(m_GpsSource, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(newPosition(QGeoPositionInfo)));
connect(m_GpsSource, SIGNAL(updateTimeout()), this, SLOT(updateTimeout()));
m_GpsSource->setUpdateInterval(5 * 60 * 1000); // 5 minutes so the device doesn't drain the battery
@@ -89,7 +88,7 @@ void GpsLocation::serviceEnable(bool toggle)
}
if (toggle) {
gpsSource->startUpdates();
- status("Starting Subsurface GPS service");
+ status(QString("Starting Subsurface GPS service with update interval %1").arg(gpsSource->updateInterval()));
} else {
gpsSource->stopUpdates();
status("Stopping Subsurface GPS service");
@@ -117,10 +116,8 @@ QString GpsLocation::currentPosition()
void GpsLocation::newPosition(QGeoPositionInfo pos)
{
- int64_t lastTime;
+ int64_t lastTime = 0;
QGeoCoordinate lastCoord;
- QString msg("received new position %1");
- status(qPrintable(msg.arg(pos.coordinate().toString())));
int nr = m_trackers.count();
if (nr) {
gpsTracker gt = m_trackers.last();
@@ -131,9 +128,11 @@ void GpsLocation::newPosition(QGeoPositionInfo pos)
// if we are waiting for a position update or
// if we have no record stored or if at least the configured minimum
// time has passed or we moved at least the configured minimum distance
- if (!nr || waitingForPosition ||
- (int64_t)pos.timestamp().toTime_t() > lastTime + prefs.time_threshold ||
+ int64_t delta = (int64_t)pos.timestamp().toTime_t() + gettimezoneoffset() - lastTime;
+ if (!nr || waitingForPosition || delta > prefs.time_threshold ||
lastCoord.distanceTo(pos.coordinate()) > prefs.distance_threshold) {
+ QString msg("received new position %1 after delta %2 threshold %3");
+ status(qPrintable(msg.arg(pos.coordinate().toString()).arg(delta).arg(prefs.time_threshold)));
waitingForPosition = false;
gpsTracker gt;
gt.when = pos.timestamp().toTime_t();
diff --git a/subsurface-core/imagedownloader.cpp b/subsurface-core/imagedownloader.cpp
index 9451f8a1b..daa49eadf 100644
--- a/subsurface-core/imagedownloader.cpp
+++ b/subsurface-core/imagedownloader.cpp
@@ -17,8 +17,14 @@ ImageDownloader::ImageDownloader(struct picture *pic)
picture = pic;
}
+ImageDownloader::~ImageDownloader()
+{
+ picture_free(picture);
+}
+
void ImageDownloader::load(bool fromHash){
QUrl url;
+ loadFromHash = fromHash;
if(fromHash)
url = cloudImageURL(picture->hash);
else
@@ -40,8 +46,11 @@ void ImageDownloader::saveImage(QNetworkReply *reply)
QByteArray imageData = reply->readAll();
QImage image = QImage();
image.loadFromData(imageData);
- if (image.isNull())
+ if (image.isNull()) {
+ if (loadFromHash)
+ load(false);
return;
+ }
QCryptographicHash hash(QCryptographicHash::Sha1);
hash.addData(imageData);
QString path = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first();
@@ -59,6 +68,11 @@ void ImageDownloader::saveImage(QNetworkReply *reply)
}
reply->manager()->deleteLater();
reply->deleteLater();
+ // This should be called to make the picture actually show.
+ // Problem is DivePictureModel is not in subsurface-core.
+ // Nevertheless, the image shows when the dive is selected the next time.
+ // DivePictureModel::instance()->updateDivePictures();
+
}
void loadPicture(struct picture *picture, bool fromHash)
@@ -69,7 +83,7 @@ void loadPicture(struct picture *picture, bool fromHash)
SHashedImage::SHashedImage(struct picture *picture) : QImage()
{
- QUrl url = QUrl::fromUserInput(QString(picture->filename));
+ QUrl url = QUrl::fromUserInput(localFilePath(QString(picture->filename)));
if(url.isLocalFile())
load(url.toLocalFile());
if (isNull()) {
@@ -79,21 +93,21 @@ SHashedImage::SHashedImage(struct picture *picture) : QImage()
if (filename.isNull()) {
// That didn't produce a local filename.
// Try the cloud server
- QtConcurrent::run(loadPicture, picture, true);
+ QtConcurrent::run(loadPicture, clone_picture(picture), true);
} else {
// Load locally from translated file name
load(filename);
if (!isNull()) {
// Make sure the hash still matches the image file
- QtConcurrent::run(updateHash, picture);
+ QtConcurrent::run(updateHash, clone_picture(picture));
} else {
// Interpret filename as URL
- QtConcurrent::run(loadPicture, picture, false);
+ QtConcurrent::run(loadPicture, clone_picture(picture), false);
}
}
} else {
// We loaded successfully. Now, make sure hash is up to date.
- QtConcurrent::run(hashPicture, picture);
+ QtConcurrent::run(hashPicture, clone_picture(picture));
}
}
diff --git a/subsurface-core/imagedownloader.h b/subsurface-core/imagedownloader.h
index cd85c9509..f4e3df875 100644
--- a/subsurface-core/imagedownloader.h
+++ b/subsurface-core/imagedownloader.h
@@ -14,11 +14,13 @@ class ImageDownloader : public QObject {
Q_OBJECT;
public:
ImageDownloader(struct picture *picture);
+ ~ImageDownloader();
void load(bool fromHash);
private:
struct picture *picture;
QNetworkAccessManager manager;
+ bool loadFromHash;
private slots:
void saveImage(QNetworkReply *reply);
diff --git a/subsurface-core/libdivecomputer.c b/subsurface-core/libdivecomputer.c
index 0d0b397dc..549b894ce 100644
--- a/subsurface-core/libdivecomputer.c
+++ b/subsurface-core/libdivecomputer.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
@@ -68,13 +71,14 @@ static dc_status_t create_parser(device_data_t *devdata, dc_parser_t **parser)
return dc_parser_new(parser, devdata->device);
}
-static int parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_parser_t *parser, int ngases)
+static int parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_parser_t *parser, unsigned int ngases)
{
static bool shown_warning = false;
- int i, rc;
+ unsigned int i;
+ int rc;
#if DC_VERSION_CHECK(0, 5, 0) && defined(DC_GASMIX_UNKNOWN)
- int ntanks = 0;
+ unsigned int ntanks = 0;
rc = dc_parser_get_field(parser, DC_FIELD_TANK_COUNT, 0, &ntanks);
if (rc == DC_STATUS_SUCCESS) {
if (ntanks && ntanks != ngases) {
diff --git a/subsurface-core/linux.c b/subsurface-core/linux.c
index d4131c7ea..b81f6bf53 100644
--- a/subsurface-core/linux.c
+++ b/subsurface-core/linux.c
@@ -25,6 +25,7 @@ void subsurface_OS_pref_setup(void)
bool subsurface_ignore_font(const char *font)
{
// there are no old default fonts to ignore
+ (void)font;
return false;
}
@@ -41,7 +42,7 @@ void subsurface_user_info(struct user_info *user)
}
if (username && *username) {
char hostname[64];
- struct membuffer mb = { 0 };
+ struct membuffer mb = {};
gethostname(hostname, sizeof(hostname));
put_format(&mb, "%s@%s", username, hostname);
user->email = mb_cstring(&mb);
@@ -126,7 +127,7 @@ int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
char filename[1024];
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
- if (n >= sizeof(filename)) {
+ if (n >= (int)sizeof(filename)) {
closedir(dp);
return -1;
}
@@ -216,6 +217,7 @@ int subsurface_zip_close(struct zip *zip)
/* win32 console */
void subsurface_console_init(bool dedicated)
{
+ (void)dedicated;
/* NOP */
}
@@ -223,3 +225,8 @@ void subsurface_console_exit(void)
{
/* NOP */
}
+
+bool subsurface_user_is_root()
+{
+ return (geteuid() == 0);
+}
diff --git a/subsurface-core/load-git.c b/subsurface-core/load-git.c
index cc702f6ae..a78082c07 100644
--- a/subsurface-core/load-git.c
+++ b/subsurface-core/load-git.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdio.h>
#include <ctype.h>
#include <string.h>
diff --git a/subsurface-core/macos.c b/subsurface-core/macos.c
index 8ca2c1c6f..500412cd8 100644
--- a/subsurface-core/macos.c
+++ b/subsurface-core/macos.c
@@ -119,7 +119,7 @@ int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
char filename[1024];
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
- if (n >= sizeof(filename)) {
+ if (n >= (int)sizeof(filename)) {
closedir(dp);
return -1;
}
@@ -145,7 +145,7 @@ int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
if (fnmatch("UEMISSDA", ep->d_name, 0) == 0) {
char filename[1024];
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
- if (n >= sizeof(filename)) {
+ if (n >= (int)sizeof(filename)) {
closedir(dp);
return -1;
}
@@ -211,3 +211,8 @@ void subsurface_console_exit(void)
{
/* NOP */
}
+
+bool subsurface_user_is_root()
+{
+ return (geteuid() == 0);
+}
diff --git a/subsurface-core/membuffer.c b/subsurface-core/membuffer.c
index 2889a0cdc..053edb8f0 100644
--- a/subsurface-core/membuffer.c
+++ b/subsurface-core/membuffer.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
diff --git a/subsurface-core/metrics.cpp b/subsurface-core/metrics.cpp
index db636794d..3c66528b8 100644
--- a/subsurface-core/metrics.cpp
+++ b/subsurface-core/metrics.cpp
@@ -15,7 +15,8 @@ IconMetrics::IconMetrics() :
sz_med(-1),
sz_big(-1),
sz_pic(-1),
- spacing(-1)
+ spacing(-1),
+ dpr(1.0)
{
}
@@ -57,3 +58,8 @@ const IconMetrics & defaultIconMetrics()
return dfltIconMetrics;
}
+
+void updateDevicePixelRatio(double dpr)
+{
+ dfltIconMetrics.dpr = dpr;
+}
diff --git a/subsurface-core/metrics.h b/subsurface-core/metrics.h
index 03d6b22e2..ca281b3b1 100644
--- a/subsurface-core/metrics.h
+++ b/subsurface-core/metrics.h
@@ -25,9 +25,12 @@ struct IconMetrics {
int sz_pic; // ex 128px
// icon spacing
int spacing; // ex 2px
+ // devicePixelRatio
+ double dpr; // 1.0 for traditional screens, HiDPI screens up to 3.0
IconMetrics();
};
const IconMetrics & defaultIconMetrics();
+void updateDevicePixelRatio(double dpr);
#endif // METRICS_H
diff --git a/subsurface-core/parse-xml.c b/subsurface-core/parse-xml.c
index a617648fb..e8782251e 100644
--- a/subsurface-core/parse-xml.c
+++ b/subsurface-core/parse-xml.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdio.h>
#include <ctype.h>
#include <string.h>
@@ -20,7 +23,7 @@
#include "device.h"
#include "membuffer.h"
-int verbose, quit;
+int verbose, quit, force_root;
int metric = 1;
int last_xml_version = -1;
int diveid = -1;
@@ -2010,7 +2013,7 @@ const char *preprocess_divelog_de(const char *buffer)
if (ret) {
xmlParserCtxtPtr ctx;
char buf[] = "";
- int i;
+ size_t i;
for (i = 0; i < strlen(ret); ++i)
if (!isascii(ret[i]))
@@ -2257,7 +2260,8 @@ extern int dm4_dive(void *param, int columns, char **data, char **column)
{
(void) columns;
(void) column;
- int i, interval, retval = 0;
+ unsigned int i;
+ int interval, retval = 0;
sqlite3 *handle = (sqlite3 *)param;
float *profileBlob;
unsigned char *tempBlob;
@@ -2385,7 +2389,8 @@ extern int dm5_dive(void *param, int columns, char **data, char **column)
{
(void) columns;
(void) column;
- int i, interval, retval = 0, block_size;
+ unsigned int i;
+ int interval, retval = 0, block_size;
sqlite3 *handle = (sqlite3 *)param;
unsigned const char *sampleBlob;
char *err = NULL;
diff --git a/subsurface-core/planner.c b/subsurface-core/planner.c
index 1828d5a11..705aad1cb 100644
--- a/subsurface-core/planner.c
+++ b/subsurface-core/planner.c
@@ -9,6 +9,7 @@
#include <ctype.h>
#include <string.h>
#include "dive.h"
+#include "deco.h"
#include "divelist.h"
#include "planner.h"
#include "gettext.h"
@@ -103,7 +104,7 @@ int get_gasidx(struct dive *dive, struct gasmix *mix)
void interpolate_transition(struct dive *dive, duration_t t0, duration_t t1, depth_t d0, depth_t d1, const struct gasmix *gasmix, o2pressure_t po2)
{
- int j;
+ uint32_t j;
for (j = t0.seconds; j < t1.seconds; j++) {
int depth = interpolate(d0.mm, d1.mm, j - t0.seconds, t1.seconds - t0.seconds);
@@ -476,11 +477,11 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, int *gascha
}
/* sort all the stops into one ordered list */
-static unsigned int *sort_stops(int *dstops, int dnr, struct gaschanges *gstops, int gnr)
+static int *sort_stops(int *dstops, int dnr, struct gaschanges *gstops, int gnr)
{
int i, gi, di;
int total = dnr + gnr;
- unsigned int *stoplevels = malloc(total * sizeof(int));
+ int *stoplevels = malloc(total * sizeof(int));
/* no gaschanges */
if (gnr == 0) {
@@ -534,7 +535,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool
const unsigned int sz_temp = 100000;
char *buffer = (char *)malloc(sz_buffer);
char *temp = (char *)malloc(sz_temp);
- char *deco;
+ char *deco, *segmentsymbol;
static char buf[1000];
int len, lastdepth = 0, lasttime = 0, lastsetpoint = -1, newdepth = 0, lastprintdepth = 0, lastprintsetpoint = -1;
struct gasmix lastprintgasmix = {{ -1 }, { -1 }};
@@ -596,7 +597,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool
translate("gettextFromC", "Subsurface dive plan"), temp);
if (!plan_verbatim) {
- len += snprintf(buffer + len, sz_buffer - len, "<div><table><thead><tr><th>%s</th>",
+ len += snprintf(buffer + len, sz_buffer - len, "<div><table><thead><tr><th></th><th>%s</th>",
translate("gettextFromC", "depth"));
if (plan_display_duration)
len += snprintf(buffer + len, sz_buffer - len, "<th style='padding-left: 10px;'>%s</th>",
@@ -710,8 +711,20 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool
(!isascent && gaschange_before && nextdp && dp->depth != nextdp->depth) ||
(gaschange_after && lastentered) || (gaschange_after && !isascent) ||
(isascent && gaschange_after && nextdp && dp->depth != nextdp->depth )) {
+ // Print a symbol to indicate whether segment is an ascent, descent, constant depth (user entered) or deco stop
+ if (isascent)
+ segmentsymbol = "&#10138;"; // up-right arrow for ascent
+ else if (dp->depth > lastdepth)
+ segmentsymbol = "&#10136;"; // down-right arrow for descent
+ else if (dp->entered)
+ segmentsymbol = "&#10137;"; // right arrow for entered entered segment at constant depth
+ else
+ segmentsymbol = "&#10134;"; // heavey minus sign for deco stop
+
+ len += snprintf(buffer + len, sz_buffer - len, "<tr><td style='padding-left: 10px; float: right;'>%s</td>", segmentsymbol);
+
snprintf(temp, sz_temp, translate("gettextFromC", "%3.0f%s"), depthvalue, depth_unit);
- len += snprintf(buffer + len, sz_buffer - len, "<tr><td style='padding-left: 10px; float: right;'>%s</td>", temp);
+ len += snprintf(buffer + len, sz_buffer - len, "<td style='padding-left: 10px; float: right;'>%s</td>", temp);
if (plan_display_duration) {
snprintf(temp, sz_temp, translate("gettextFromC", "%3dmin"), (dp->time - lasttime + 30) / 60);
len += snprintf(buffer + len, sz_buffer - len, "<td style='padding-left: 10px; float: right;'>%s</td>", temp);
@@ -969,13 +982,13 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
int po2;
int transitiontime, gi;
int current_cylinder;
- unsigned int stopidx;
+ int stopidx;
int depth;
struct gaschanges *gaschanges = NULL;
int gaschangenr;
int *decostoplevels;
int decostoplevelcount;
- unsigned int *stoplevels = NULL;
+ int *stoplevels = NULL;
bool stopping = false;
bool pendinggaschange = false;
int clock, previous_point_time;
diff --git a/subsurface-core/profile.c b/subsurface-core/profile.c
index 4d9a8444f..6576f6453 100644
--- a/subsurface-core/profile.c
+++ b/subsurface-core/profile.c
@@ -377,7 +377,7 @@ static int count_events(struct divecomputer *dc)
return result;
}
-static int set_cylinder_index(struct plot_info *pi, int i, int cylinderindex, unsigned int end)
+static int set_cylinder_index(struct plot_info *pi, int i, int cylinderindex, int end)
{
while (i < pi->nr) {
struct plot_data *entry = pi->entry + i;
@@ -392,7 +392,7 @@ static int set_cylinder_index(struct plot_info *pi, int i, int cylinderindex, un
return i;
}
-static int set_setpoint(struct plot_info *pi, int i, int setpoint, unsigned int end)
+static int set_setpoint(struct plot_info *pi, int i, int setpoint, int end)
{
while (i < pi->nr) {
struct plot_data *entry = pi->entry + i;
@@ -405,7 +405,7 @@ static int set_setpoint(struct plot_info *pi, int i, int setpoint, unsigned int
}
/* normally the first cylinder has index 0... if not, we need to fix this up here */
-static int set_first_cylinder_index(struct plot_info *pi, int i, int cylinderindex, unsigned int end)
+static int set_first_cylinder_index(struct plot_info *pi, int i, int cylinderindex, int end)
{
while (i < pi->nr) {
struct plot_data *entry = pi->entry + i;
@@ -425,7 +425,7 @@ static void check_gas_change_events(struct dive *dive, struct divecomputer *dc,
// for dive computers that tell us their first gas as an event on the first sample
// we need to make sure things are setup correctly
cylinderindex = explicit_first_cylinder(dive, dc);
- set_first_cylinder_index(pi, 0, cylinderindex, ~0u);
+ set_first_cylinder_index(pi, 0, cylinderindex, INT_MAX);
if (!ev)
return;
@@ -435,7 +435,7 @@ static void check_gas_change_events(struct dive *dive, struct divecomputer *dc,
cylinderindex = get_cylinder_index(dive, ev);
ev = get_next_event(ev->next, "gaschange");
} while (ev);
- set_cylinder_index(pi, i, cylinderindex, ~0u);
+ set_cylinder_index(pi, i, cylinderindex, INT_MAX);
}
static void check_setpoint_events(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
@@ -456,7 +456,7 @@ static void check_setpoint_events(struct dive *dive, struct divecomputer *dc, st
dc->divemode = CCR;
ev = get_next_event(ev->next, "SP change");
} while (ev);
- set_setpoint(pi, i, setpoint.mbar, ~0u);
+ set_setpoint(pi, i, setpoint.mbar, INT_MAX);
}
@@ -466,7 +466,7 @@ struct plot_info calculate_max_limits_new(struct dive *dive, struct divecomputer
bool seen = false;
static struct plot_info pi;
int maxdepth = dive->maxdepth.mm;
- int maxtime = 0;
+ unsigned int maxtime = 0;
int maxpressure = 0, minpressure = INT_MAX;
int maxhr = 0, minhr = INT_MAX;
int mintemp = dive->mintemp.mkelvin;
@@ -606,7 +606,7 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *
break;
/* Add events if they are between plot entries */
- while (ev && ev->time.seconds < lasttime + offset) {
+ while (ev && (int)ev->time.seconds < lasttime + offset) {
INSERT_ENTRY(ev->time.seconds, interpolate(lastdepth, depth, ev->time.seconds - lasttime, delta), sac);
ev = ev->next;
}
@@ -615,12 +615,12 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *
INSERT_ENTRY(lasttime + offset, interpolate(lastdepth, depth, offset, delta), sac);
/* skip events that happened at this time */
- while (ev && ev->time.seconds == lasttime + offset)
+ while (ev && (int)ev->time.seconds == lasttime + offset)
ev = ev->next;
}
/* Add events if they are between plot entries */
- while (ev && ev->time.seconds < time) {
+ while (ev && (int)ev->time.seconds < time) {
INSERT_ENTRY(ev->time.seconds, interpolate(lastdepth, depth, ev->time.seconds - lasttime, delta), sac);
ev = ev->next;
}
@@ -659,7 +659,7 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *
if (sample->rbt.seconds)
entry->rbt = sample->rbt.seconds;
/* skip events that happened at this time */
- while (ev && ev->time.seconds == time)
+ while (ev && (int)ev->time.seconds == time)
ev = ev->next;
lasttime = time;
lastdepth = depth;
diff --git a/subsurface-core/qthelper.cpp b/subsurface-core/qthelper.cpp
index 7c67e0993..e103b44e5 100644
--- a/subsurface-core/qthelper.cpp
+++ b/subsurface-core/qthelper.cpp
@@ -1108,11 +1108,14 @@ QString fileFromHash(char *hash)
return localFilenameOf[QByteArray::fromHex(hash)];
}
+// This needs to operate on a copy of picture as it frees it after finishing!
void updateHash(struct picture *picture) {
QByteArray hash = hashFile(fileFromHash(picture->hash));
learnHash(picture, hash);
+ picture_free(picture);
}
+// This needs to operate on a copy of picture as it frees it after finishing!
void hashPicture(struct picture *picture)
{
char *oldHash = copy_string(picture->hash);
@@ -1120,13 +1123,14 @@ void hashPicture(struct picture *picture)
if (!same_string(picture->hash, "") && !same_string(picture->hash, oldHash))
mark_divelist_changed((true));
free(oldHash);
+ picture_free(picture);
}
extern "C" void cache_picture(struct picture *picture)
{
QString filename = picture->filename;
if (!hashOf.contains(filename))
- QtConcurrent::run(hashPicture, picture);
+ QtConcurrent::run(hashPicture, clone_picture(picture));
}
void learnImages(const QDir dir, int max_recursions)
@@ -1476,7 +1480,12 @@ void loadPreferences()
s.beginGroup("CloudStorage");
GET_TXT("email", cloud_storage_email);
+#ifndef SUBSURFACE_MOBILE
GET_BOOL("save_password_local", save_password_local);
+#else
+ // always save the password in Subsurface-mobile
+ prefs.save_password_local = true;
+#endif
if (prefs.save_password_local) { // GET_TEXT macro is not a single statement
GET_TXT("password", cloud_storage_password);
}
@@ -1513,6 +1522,11 @@ void loadPreferences()
GET_ENUM("cat2", taxonomy_category, geocoding.category[2]);
s.endGroup();
+ // GPS service time and distance thresholds
+ s.beginGroup("LocationService");
+ GET_INT("time_threshold", time_threshold);
+ GET_INT("distance_threshold", distance_threshold);
+ s.endGroup();
}
extern "C" bool isCloudUrl(const char *filename)
diff --git a/subsurface-core/qtserialbluetooth.cpp b/subsurface-core/qtserialbluetooth.cpp
index 025ab8c34..6b104157a 100644
--- a/subsurface-core/qtserialbluetooth.cpp
+++ b/subsurface-core/qtserialbluetooth.cpp
@@ -313,6 +313,7 @@ static int qt_serial_write(serial_t *device, const void* data, unsigned int size
static int qt_serial_flush(serial_t *device, int queue)
{
+ (void)queue;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
#if !defined(Q_OS_WIN)
diff --git a/subsurface-core/save-git.c b/subsurface-core/save-git.c
index 054c7e9b4..d089095b6 100644
--- a/subsurface-core/save-git.c
+++ b/subsurface-core/save-git.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdio.h>
#include <ctype.h>
#include <string.h>
diff --git a/subsurface-core/save-html.c b/subsurface-core/save-html.c
index 5fc5b000a..2d0ea9cf3 100644
--- a/subsurface-core/save-html.c
+++ b/subsurface-core/save-html.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include "save-html.h"
#include "qthelperfromc.h"
#include "gettext.h"
diff --git a/subsurface-core/save-xml.c b/subsurface-core/save-xml.c
index eabcf4f26..2335637e8 100644
--- a/subsurface-core/save-xml.c
+++ b/subsurface-core/save-xml.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdio.h>
#include <ctype.h>
#include <string.h>
diff --git a/subsurface-core/statistics.c b/subsurface-core/statistics.c
index 373a6a0d0..6a05cffc1 100644
--- a/subsurface-core/statistics.c
+++ b/subsurface-core/statistics.c
@@ -48,7 +48,7 @@ static void process_temperatures(struct dive *dp, stats_t *stats)
static void process_dive(struct dive *dp, stats_t *stats)
{
int old_tt, sac_time = 0;
- int duration = dp->duration.seconds;
+ uint32_t duration = dp->duration.seconds;
old_tt = stats->total_time.seconds;
stats->total_time.seconds += duration;
@@ -297,14 +297,14 @@ static void get_ranges(char *buffer, int size)
}
}
-void get_selected_dives_text(char *buffer, int size)
+void get_selected_dives_text(char *buffer, size_t size)
{
if (amount_selected == 1) {
if (current_dive)
snprintf(buffer, size, translate("gettextFromC", "for dive #%d"), current_dive->number);
else
snprintf(buffer, size, "%s", translate("gettextFromC", "for selected dive"));
- } else if (amount_selected == dive_table.nr) {
+ } else if (amount_selected == (unsigned int)dive_table.nr) {
snprintf(buffer, size, "%s", translate("gettextFromC", "for all dives"));
} else if (amount_selected == 0) {
snprintf(buffer, size, "%s", translate("gettextFromC", "(no dives)"));
@@ -313,7 +313,7 @@ void get_selected_dives_text(char *buffer, int size)
if (strlen(buffer) == size - 1) {
/* add our own ellipse... the way Pango does this is ugly
* as it will leave partial numbers there which I don't like */
- int offset = 4;
+ size_t offset = 4;
while (offset < size && isdigit(buffer[size - offset]))
offset++;
strcpy(buffer + size - offset, "...");
diff --git a/subsurface-core/statistics.h b/subsurface-core/statistics.h
index 890e6e53c..015c3481e 100644
--- a/subsurface-core/statistics.h
+++ b/subsurface-core/statistics.h
@@ -44,7 +44,7 @@ extern stats_t *stats_by_type;
extern char *get_time_string_s(int seconds, int maxdays, bool freediving);
extern char *get_minutes(int seconds);
extern void process_all_dives(struct dive *dive, struct dive **prev_dive);
-extern void get_selected_dives_text(char *buffer, int size);
+extern void get_selected_dives_text(char *buffer, size_t size);
extern void get_gas_used(struct dive *dive, volume_t gases[MAX_CYLINDERS]);
extern void process_selected_dives(void);
void selected_dives_gas_parts(volume_t *o2_tot, volume_t *he_tot);
diff --git a/subsurface-core/subsurfacestartup.c b/subsurface-core/subsurfacestartup.c
index 864134724..6e0dede1c 100644
--- a/subsurface-core/subsurfacestartup.c
+++ b/subsurface-core/subsurfacestartup.c
@@ -217,6 +217,10 @@ void parse_argument(const char *arg)
run_survey = true;
return;
}
+ if (strcmp(arg, "--allow_run_as_root") == 0) {
+ ++force_root;
+ return;
+ }
if (strcmp(arg, "--win32console") == 0)
return;
/* fallthrough */
@@ -233,18 +237,6 @@ void parse_argument(const char *arg)
} while (*++p);
}
-void renumber_dives(int start_nr, bool selected_only)
-{
- int i, nr = start_nr;
- struct dive *dive;
-
- for_each_dive (i, dive) {
- if (dive->selected)
- dive->number = nr++;
- }
- mark_divelist_changed(true);
-}
-
/*
* Under a POSIX setup, the locale string should have a format
* like [language[_territory][.codeset][@modifier]].
diff --git a/subsurface-core/time.c b/subsurface-core/time.c
index b658954bc..0893f19d8 100644
--- a/subsurface-core/time.c
+++ b/subsurface-core/time.c
@@ -11,16 +11,16 @@
*/
void utc_mkdate(timestamp_t timestamp, struct tm *tm)
{
- static const int mdays[] = {
+ static const unsigned int mdays[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
};
- static const int mdays_leap[] = {
+ static const unsigned int mdays_leap[] = {
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
};
unsigned long val;
unsigned int leapyears;
int m;
- const int *mp;
+ const unsigned int *mp;
memset(tm, 0, sizeof(*tm));
diff --git a/subsurface-core/uemis-downloader.c b/subsurface-core/uemis-downloader.c
index 6f5c5f177..b9b532303 100644
--- a/subsurface-core/uemis-downloader.c
+++ b/subsurface-core/uemis-downloader.c
@@ -506,7 +506,8 @@ static bool uemis_get_answer(const char *path, char *request, int n_param_in,
#if UEMIS_DEBUG & 4
fprintf(debugfile, "::w req.txt \"%s\"\n", sb);
#endif
- if (write(reqtxt_file, sb, strlen(sb)) != strlen(sb)) {
+ int written = write(reqtxt_file, sb, strlen(sb));
+ if (written == -1 || (size_t)written != strlen(sb)) {
*error_text = translate("gettextFromC", ERR_FS_SHORT_WRITE);
return false;
}
@@ -784,7 +785,7 @@ static bool uemis_delete_dive(device_data_t *devdata, uint32_t diveid)
* index into yet another data store that we read out later. In order to
* correctly populate the location and gps data from that we need to remember
* the addresses of those fields for every dive that references the divespot. */
-static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, char *inbuf, char **max_divenr, bool keep_number, int *for_dive)
+static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, char *inbuf, char **max_divenr, int *for_dive)
{
char *buf = strdup(inbuf);
char *tp, *bp, *tag, *type, *val;
@@ -793,7 +794,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, char *
char *endptr = buf + inbuflen;
bool is_log = false, is_dive = false;
char *sections[10];
- int s, nr_sections = 0;
+ size_t s, nr_sections = 0;
struct dive *dive = NULL;
char dive_no[10];
@@ -974,7 +975,7 @@ static char *uemis_get_divenr(char *deviceidstr, int force)
maxdiveid = dc->diveid;
}
}
- if (max_deleted_seen >= 0 && maxdiveid < max_deleted_seen) {
+ if (max_deleted_seen >= 0 && maxdiveid < (uint32_t)max_deleted_seen) {
maxdiveid = max_deleted_seen;
#if UEMIS_DEBUG & 4
fprintf(debugfile, "overriding max seen with max deleted seen %d\n", max_deleted_seen);
@@ -1154,7 +1155,7 @@ static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, stru
* we mark the search successful even if the dive has been deleted. */
found = true;
if (strstr(mbuf, "deleted{bool{true") == NULL) {
- process_raw_buffer(data, deviceidnr, mbuf, &newmax, false, NULL);
+ process_raw_buffer(data, deviceidnr, mbuf, &newmax, NULL);
/* remember the last log file number as it is very likely that subsequent dives
* have the same or higher logfile number.
* UEMIS unfortunately deletes dives by deleting the dive details and not the logs. */
@@ -1223,7 +1224,7 @@ const char *do_uemis_import(device_data_t *data)
char *deviceid = NULL;
const char *result = NULL;
char *endptr;
- bool success, keep_number = false, once = true;
+ bool success, once = true;
int match_dive_and_log = 0;
int uemis_mem_status = UEMIS_MEM_OK;
@@ -1231,9 +1232,6 @@ const char *do_uemis_import(device_data_t *data)
home = getenv("HOME");
user = getenv("LOGNAME");
#endif
- if (dive_table.nr == 0)
- keep_number = true;
-
uemis_info(translate("gettextFromC", "Initialise communication"));
if (!uemis_init(mountpath)) {
free(reqtxt_path);
@@ -1287,7 +1285,7 @@ const char *do_uemis_import(device_data_t *data)
do_dump_buffer_to_file(realmbuf, "Divelogs");
#endif
/* process the buffer we have assembled */
- if (!process_raw_buffer(data, deviceidnr, realmbuf, &newmax, keep_number, NULL)) {
+ if (!process_raw_buffer(data, deviceidnr, realmbuf, &newmax, NULL)) {
/* if no dives were downloaded, mark end appropriately */
if (end == -2)
end = start - 1;
diff --git a/subsurface-core/uemis.c b/subsurface-core/uemis.c
index 4135e0cfe..5635d5630 100644
--- a/subsurface-core/uemis.c
+++ b/subsurface-core/uemis.c
@@ -98,7 +98,7 @@ static int uemis_convert_base64(char *base64, uint8_t **data)
}
struct uemis_helper {
- int diveid;
+ uint32_t diveid;
int lbs;
int divespot;
int dive_site_uuid;
@@ -106,7 +106,7 @@ struct uemis_helper {
};
static struct uemis_helper *uemis_helper = NULL;
-static struct uemis_helper *uemis_get_helper(int diveid)
+static struct uemis_helper *uemis_get_helper(uint32_t diveid)
{
struct uemis_helper **php = &uemis_helper;
struct uemis_helper *hp = *php;
@@ -134,7 +134,7 @@ static void uemis_weight_unit(int diveid, int lbs)
hp->lbs = lbs;
}
-int uemis_get_weight_unit(int diveid)
+int uemis_get_weight_unit(uint32_t diveid)
{
struct uemis_helper *hp = uemis_helper;
while (hp) {
diff --git a/subsurface-core/uemis.h b/subsurface-core/uemis.h
index 5f32fe76c..1758b4b32 100644
--- a/subsurface-core/uemis.h
+++ b/subsurface-core/uemis.h
@@ -13,7 +13,7 @@ extern "C" {
#endif
void uemis_parse_divelog_binary(char *base64, void *divep);
-int uemis_get_weight_unit(int diveid);
+int uemis_get_weight_unit(uint32_t diveid);
void uemis_mark_divelocation(int diveid, int divespot, uint32_t dive_site_uuid);
void uemis_set_divelocation(int divespot, char *text, double longitude, double latitude);
int uemis_get_divespot_id_by_diveid(uint32_t diveid);
diff --git a/subsurface-core/units.h b/subsurface-core/units.h
index 9ad4b7282..029bb64fa 100644
--- a/subsurface-core/units.h
+++ b/subsurface-core/units.h
@@ -99,7 +99,7 @@ typedef struct
typedef struct
{
- int32_t mkelvin; // up to 1750 degrees K
+ uint32_t mkelvin; // up to 1750 degrees K (temperatures in K are always positive)
} temperature_t;
typedef struct
diff --git a/subsurface-core/windows.c b/subsurface-core/windows.c
index a2386fd83..58d3beaad 100644
--- a/subsurface-core/windows.c
+++ b/subsurface-core/windows.c
@@ -446,3 +446,9 @@ void subsurface_console_exit(void)
FreeConsole();
#endif
}
+
+bool subsurface_user_is_root()
+{
+ /* FIXME: Detect admin rights */
+ return (false);
+}
diff --git a/subsurface-core/worldmap-save.c b/subsurface-core/worldmap-save.c
index f79978495..e7e8bcc30 100644
--- a/subsurface-core/worldmap-save.c
+++ b/subsurface-core/worldmap-save.c
@@ -1,3 +1,6 @@
+// Clang has a bug on zero-initialization of C structs.
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>