It seems that smartrak was the only part of the code that cared
about freeing the dc_descriptor. Make that a general feature
of the new device_data_t destructor, which we could implement
now that things are in C++.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It was never clear what was a pointer to a static string from
libdivecomputer and what was allocated.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These can all just be local objects.
Also, don't overwrite them with 0. We later want to convert the
string to std::string, where this would be very sketchy.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Convert both files simultanously, because the SI_UNITS define works
either under C or under C++.
This was painful, because initialization of struct-members has to
be done in order of definition in C++. And it was completely out
of order. However, as long as not all is C++, we can't use
default initialization directly in the struct definition. :(
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code was wild: For the yearly statistics it would allocate
one entry per dive in the log. Of course, it would also leak
C-style strings.
Convert the whole thing to somewhat idiomatic C++.
Somewhat wasted work, because I'd like to convert the whole thing
to the new statistics code. But let's finish the conversion to C++
first.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
All have been converted to std::min() and std::max().
Moreover, this was Windows only and since we cross-compile, it
is not even clear if this is needed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was the umpteenth inefficient reinvention of a trivial
map. Replace by a hash-map (std::unordered_map). Might just
as well use a balanced binary tree or a sorted array. In the
end, it probably doesn't matter at all.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
uemis_get_divenr() returns maxdiveid and passes mindiveid as a
global variable.
Make this more reasonable by returning a min, max pair.
The way mindiveid is an unsigned int and then reinterpreted as
int is very sketchy. This commit attempts to not change that
behavior.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is only initialized and used in one loop. Very mysterious
why this should be a global variable.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This global variable is used in two function independently of
each other. I don't see how there should be transport of this
value from one function to the other. Ominous.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
uemis_get_answer() would put the raw response into a global variable.
This could be anywhere in the call stack and thus you never knew
when the existing buffer was removed under your feet.
Instead, return the buffer explicitly from uemis_get_answer().
I'm nit perfectly happy about the new interface: an error is
indicated by an empty buffer, which is awkward to test for.
If an empty buffer turns out to be a valid response, this
should be replaced by an std::optional<> or std::expected<>.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The string code of uemis-downloader.cpp was broken in more ways
than can be listed here. Notably, it brazenly refused to free any
memory allocated for the parameters buffer.
Using std::string and std::string_view should plug all those
memory holes. That made it necessary to do some major refactoring.
This was done blind and therefore will break.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
newmax was an integer variable kept as a string. Very ominous.
Moreover, memory management seems to be broken:
1) The string is never freed.
2) The string is passed as value from do_uemis_import() to
get_matching_dives(), which passes it as reference to
process_raw_buffer(), which may reallocate it, which means
that do_uemis_import() now possesses a pointer to a free()d
string.
Simplify all that by making newmax an integer variable and
passing it as a reference from do_uemis_import() to
get_matching_dives().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There were a number of fprintf()s that escaped the conversion
to report_info(), because they used "debugfile" instead of
"stderr" as target. However, debugfile was just #defined to
be stderr, so we might just use report_info() for consistency.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The uemis code is wild. It simply doesn't deallocate memory
and uses global variables. To get this under control, create
a "struct uemis" and make the functions exported by "uemis.h"
members of "struct uemis". Thus, we don't have to carry around
a parameter for the state of the importing process.
Turn a linked list of "helper" structures (one per imported dive)
into a std::unordered_map, to fix leaking of the helper structures.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was very obscure: the function that parses into a struct
dive was passed a void-pointer instead of a struct dive-pointer.
Why? Just pass the correct type.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The SHA1() helper function was only used when calculating a
SHA1 hash and taking the first four bytes of it as uint32.
Make that explicit by renaming the function into SHA1_uint32()
and directly returning an uint32_t.
Note that the usage in cochran.cpp is sketchy: it generates
a four-byte hash out of two-byte data. Why!?
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The strtod_flags() function allowed for fine control of how to
parse strings. However, only two different modes were actually
used: ascii mode ("C" locale) and permissive mode (accept ","
and "." as decimal separator).
The former had already its own function name (ascii_strtod).
Make the latter a separatge function as well (permissive_strtod)
and remove all the flags rigmarole.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Owing to bitrot, this union only contained a float and therefore
is pointless. Let's remove it.
That makes the function name "integer_or_float()" non-sensical.
Call it "parse_float()" instead.
Moreover, change the output-arguments of "parse_float()" from
pointers to references, as null-pointers are not supported.
Finally, remove the "errno" check after "ascii_strtod()". As far as
I can tell, errno is not set in "ascii_strtod()" and using a global
variable for error-reporting it is an incredibly silly interface
anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Some improvements:
- for constraints where the condition is applied to any one of a list of
items, show the condition as 'any X';
- when filtering for tags, do not include divemode as a 'tag' - this is
hard to impossible for users to understand, and we do have a dedicated
condition for the dive mode.
Signed-off-by: Michael Keller <github@ike.ch>
Fix loading of the negation of filter conditions. Unlike other
conditions that are persisted as `<key>="<value>"`, this is persisted
to git as `negate`.
This fix remediates this for all cases where the condition has already
been saved to the cloud storage.
Saving to XML takes a different approach and indicates negated
conditions with `negate="1"`, making it identical to all other
attributes. The question is if this approach should be implemented in
addition to the above fix, in order to unify the storage format.
Fixes#4246.
Signed-off-by: Michael Keller <github@ike.ch>
Fix an issue introduced in #4148.
Essentially the refactoring missed the fact that in the imperial system
tank size is tracked as the free gas volume, but in the metric system
(which is the one used in most of Subsurface's calculations) tank size
is tracked as water capacity.
So when updating a tank template tracking imperial measurements, the
given (metric) volume in l has to be multiplied by the working pressure,
and vice versa.
This also combines all the logic dealing with `tank_info` data in one
place, hopefully making it less likely that this will be broken by
inconsistencies in the future.
Fixes#4239.
Signed-off-by: Michael Keller <github@ike.ch>
- show the correct gasmix in the profile;
- make gases available for gas switches in the profile after they have
been added;
- persist gas changes;
- add air as a default gas when adding a dive.
This still has problems when undoing a gas switch - instead of
completely removing the gas switch it is just moved to the next point in the
profile.
Signed-off-by: Michael Keller <github@ike.ch>
The last use of these functions was removed in ae299d5e66.
And that's a good thing, because snprintf-style interfaces
make zero sense in times of variable-length character
encodings.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
A long standing issue: the dives_to_add, etc. tables need to be
manually freed. This kind of problem wouldn't arise with proper
C++ data structures.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
- standardise the naming;
- use it consistently;
- apply the 'samples < 50' only when putting manually added dives into
edit mode - everywhere else manually added dives should be treated as
such;
- do not show a warning before editing a manually added dive in planner.
Signed-off-by: Michael Keller <github@ike.ch>
Error introduced in da7ea17b66: the INFO() and ERROR() macros
pass stdout instead of the format string as first parameter
to report_error(). Ooooops. How did this ever pass the
compile tests!?
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
46cf2fc086 fixed a bug where clearing of a divelog, such as the one
used for import, would erase dives in the global(!) divelog.
However, the new code used the function clear_dive_table(), which
only cleared the table without unregistering the dives. In particular,
the dives were not removed from the trips, which means that the trips
were not free()d.
This reinstates the old code, but now passes a divelog paremeter
to delete_single_dive() instead of accessing the global divelog.
Moreover, delete dives from the back to avoid unnecessary
copying.
An alternative and definitely simpler solution might be to just
add a "clear_trip_table()" after "clear_dive_table()".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently editing of planned dives that have been merged with actual
(logged) dives only works if the 'Planned dive' divecomputer is the
first divecomputer, and this divecomputer is selected when clicking
'Edit planned dive'. In other cases the profile of the first
divecomputer is overlaid with the profile of the planned dive, and the
first divecomputer's profile is overwritten when saving the dive plan.
Fix this problem.
Triggered by @SeppoTakalo's comment (https://github.com/subsurface/subsurface/issues/1913#issuecomment-2075562119): Users don't like that planned dives show up as their own entries in the dive list, so being able to merge them with the actual dive after it has been executed is a good feature - but this wasn't working well until now.
Signed-off-by: Michael Keller <github@ike.ch>
Convert some C-style strings in uemis-downloader.cpp to std::string.
This has the side effect of fixing builds on Debian Trixie, which
currently fail with the (rather silly) error:
/build/subsurface-beta-202405060411/core/uemis-downloader.cpp: In function 'char* build_ans_path(const char*, int)':
/build/subsurface-beta-202405060411/core/uemis-downloader.cpp:290:32: error: '%s' directive output between 0 and 12 bytes may cause result to exceed 'INT_MAX' [-Werror=format-truncation=]
290 | snprintf(buf, len, "%s/%s", path, name);
| ^~
......
529 | ans_path = build_filename(intermediate, fl);
| ~~
cc1plus: some warnings being treated as errors
Signed-off-by: Richard Fuchs <dfx@dfx.at>