With -Wextra, gcc/g++ complains that compound initialization
of weightsystem_t misses the auto_filled parameter. Add it.
For C++ code we might think about writing a constructor. However,
we use two versions: with and without copied string.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We have this odd legacy notion of a divecomputer 'device', that was
originally just basically the libdivecomputer 'EVENT_DEVINFO' report
that was associated with each dive. So it had firmware version,
deviceid, and serial number.
It had also gotten extended to do 'nickname' handling, and it was all
confusing, ugly and bad. It was particularly bad because it wasn't
actually a 'per device' thing at all: due to the firmware field, a dive
computer that got a firmware update forced a new 'device'.
To make matters worse, the 'deviceid' was also almost random, because
we've calculated it a couple of different ways, and libdivecomputer
itself has changed how the legacy 32-bit 'serial number' is expressed.
Finally, because of all these issues, we didn't even try to make the
thing unique, so it really ended up being a random snapshot of the state
of the dive computer at the time of a dive, and sometimes we'd pick one,
and sometimes another, since they weren't really well-defined.
So get rid of all this confusion.
The new rules:
- the actual random dive computer state at the time of a dive is kept
in the dive data. So if you want to know the firmware version, it
should be in the 'extra data'
- the only serial number that matters is the string one in the extra
data, because that's the one that actually matches what the dive
computer reports, and isn't some random 32-bit integer with ambiguous
formatting.
- the 'device id' - the thing we match with (together with the model
name, eg "Suunto EON Steel") is purely a hash of the real serial
number.
The device ID that libdivecomputer reports in EVENT_DEVINFO is
ignored, as is the device ID we've saved in the XML or git files. If
we have a serial number, the device ID will be uniquely associated
with that serial number, and if we don't have one, the device ID will
be zero (for 'match anything').
So now 'deviceid' is literally just a shorthand for the serial number
string, and the two are joined at the hip.
- the 'device' managament is _only_ used to track devices that have
serial numbers _and_ nicknames. So no more different device
structures just because one had a nickname and the other didn't etc.
Without a serial number, the device is 'anonymous' and fundamentally
cannot be distinguished from other devices of the same model, so a
nickname is meaningless. And without a nickname, there is no point in
creating a device data structure, since all the data is in the dive
itself and the device structure wouldn't add any value..
These rules mean that we no longer have ambiguous 'device' structures,
and we can never have duplicates that can confuse us.
This does mean that you can't give a nickname to a device that cannot be
uniquely identified with a serial number, but those are happily fairly
rare (and mostly older ones). Dirk said he'd look at what it takes to
give more dive computers proper serial numbers, and I already did it for
the Garmin Descent family yesterday.
(Honesty in advertizing: right now you can't add a nickname to a dive
computer that doesn't already have one, because such a dive computer
will not have a device structure. But that's a UI issue, and I'll sort
that out separately)
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The list of known tank types were kept in a fixed size table.
Instead, use a dynamic table with our horrendous table macros.
This is more flexible and sensible.
While doing this, clean up the TankInfoModel, which was leaking
memory.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In one weird case (suunto), the code in libdivecomputer.c
generates a device node directly instead of going the usual
way (setting the data in the dc-structure of the imported
dive). It is unclear to me whether that has to be that way,
as it depends on the chronological order of callbacks to
event_cb() and dive_cb().
Therefore add a device_table pointer to device_data_t
so that the downloader can add the device to this table. This
only adds the pointer, but does not yet use it in the
downloading code.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
So far, we added a non-global device table to the parser states.
Now, create device nodes in that table instead of in the global
table. Thus, on undo of dive-import, the new device nodes will
be removed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of accessing the global device table directly, add a parameter
to all device-table accessing functions. This makes all places in
the code that access the global device table grep-able, which is
necessary to include the device-table code in the undo system.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We don't really expect to get Nº of dives greater than the biggest
integer value.
Signed-off-by: Salvador Cuñat <salvador,cunat@gmail.com>
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
WLog is a Win32 based ancient shareware program whose target was:
1) fully support divelogs coming from DataTrak (DOS or Win)
2) fill some meaningful data which wasn't supported by Uwatec software
3) have a more user-friendly GUI than Datatrak had
The problem achieving goals 1) and 2) at the same time was solved by
adding a complementary file with .add extension and - mandatory - same
base name than .log file (including directory tree).
This .add file has a fixed structure composed of a 12 bytes header,
including file type check and Nº of dives following; then a fixed 850
bytes size for each dive in the log file. Data fields size and position
are fixed inside these blocks and heavily zero padded, so they are easy
to parse.
A serious restriction imposed to the WLog user was *Do not edit the logs
with other software than Wlog*; this was due the order of dives in .log
file being the same than the order of dives in .add file. Thought you
could show a WLog divelog in Datatrak, editing it resulted in mixing all
extended data for dives following the edited one.
Thus, we have to trust files are correct and is to the user ensure this
is so. If extended data are mangled, they are mangled in WLog too and we
are not trying to fix the mess, just importing.
On the technical side, we try to be smart about tank names as neither
DataTrak nor WLog record them. So we just take the first tank in users
list matching the volume recorded in WLog.
For weights we add a translatable "unknown" string as an empty string
results in weight not being shown in subsurface-mobile (which could be a
reportable issue, BTW).
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
Instead of accessing the cylinder table directly, use the get_cylinder()
function. This gives less unwieldy expressions. But more importantly,
the function does bound checking. This is crucial for now as the code
hasn't be properly audited since the change to arbitrarily sized
cylinder tables. Accesses of invalid cylinder indexes may lead to
silent data-corruption that is sometimes not even noticed by
valgrind. Returning NULL instead of an invalid pointer will make
debugging much easier.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of using fixed size arrays, use a new cylinder_table structure.
The code copies the weightsystem code, but is significantly more complex
because cylinders are such an integral part of the core.
Two functions to access the cylinders were added:
get_cylinder() and get_or_create_cylinder()
The former does a simple array access and supposes that the cylinder
exists. The latter is used by the parser(s) and if a cylinder with
the given id does not exist, cylinders up to that id are generated.
One point will make C programmers cringe: the cylinder structure is
passed by value. This is due to the way the table-macros work. A
refactoring of the table macros is planned. It has to be noted that
the size of a cylinder_t is 64 bytes, i.e. 8 long words on a 64-bit
architecture, so passing on the stack is probably not even significantly
slower than passing as reference.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
While this is debatably correct, free will happily accept (and ignore
the NULL pointer), so let's just always call it and make Coverity happy.
Fixes CID 45163
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Move the declarations of the "report_error()" and "set_error_cb()"
functions and the "verbose" variable to errorhelper.h.
Thus, error-reporting translation units don't have to import the
big dive.h header file.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Make dive.h a bit slimmer. It's only a drop in the bucket - but at
least when modifying tag functions not the *whole* application is
rebuilt anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of setting dive->dive_site directly, call the
add_dive_to_dive_site() and unregister_dive_from_dive_site()
functions. In the parser this turned out to be a bit tricky.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Add a dive site table to each dive site to keep track of dives
that have been added to a dive site. Add two functions to add
dives to / remove dives from dive sites.
Since dive sites now contain a dive table, the order of includes
had to be changed: "divesite.h" now includes "dive.h" and not
vice-versa. This caused some include churn.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since the UUID will be overwritten on save and is only used on save
and load, set it only on save or load. For other created dive sites,
leave the UUID field uninitialized.
This means that the UUID will change between saves. Let's see how
the git saver handles that.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To extend the undo system to dive sites, the importers and downloaders
must not parse directly into the global dive site table. Instead,
pass a dive_site_table argument to parse into.
For now, always pass the global dive_site_table so that this commit
should not cause any functional change.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To enable undo of dive site functions, it is crucial to work
with different dive site tables. Therefore add a dive site table
parameter to dive site functions. For now, always pass the global
dive site table. Thus, this commit shouldn't alter any functionality.
After this change, a simple search for dive_site_table reveals all
places where the global dive site table is accessed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To test single bits, datatrak.c would transform bytes into
malloc()ed char[8] buffers. Instead, simply introduce a function
to test individual bits. This should make it distinctly easier for
the compiler to optimize away.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It's a drop in the bucket, but let's remove some unnecessary
global variables. With one exception these variables were only
used in one function anyway. The other one can be passed as a
parameter.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To allow parsing into arbitrary trip_tables, add the corresponding
parameter to the parsing functions and the parser state. Currently,
all callers pass the global trip_table so there should be no change
in functionality. These arguments will be replaced in subsequent commits.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Rename
- dive_get_insertion_index() -> dive_table_get_insertion_index()
- unregister_dive_from_table() -> remove_from_dive_table()
- get_idx_in_table() -> get_idx_in_dive_table()
- sort_table() -> sort_dive_table()
This will make it more straight-forward to generate these functions
from macros.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Replace the UUID reference of struct dive by a pointer to dive_site.
This commit is rather large in lines, but nevertheless quite simple
since most of the UUID->pointer work was done in previous commits.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This changes more of the dive-site interface to return pointers
instead of UUIDs. Currently, most call sites directly extract
UUIDs afterwards. Ultimately, the UUIDs will be generally replaced
by pointers, which will then simplify these callers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
As a first step in removing dive-site uuids, change the interface
of the get_dive_site_*() functions to return pointers instead
of uuids. This makes code a bit more complicated in places where
the uuid is extracted afterwards (needed NULL check). Nevertheless,
these places should disappear once pointers instead of uuids are
stored in the dive-structures.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In d815e0c947 a dive_table pointer
was added to the parsing functions to allow parsing into tables
other than the global dive table. This will be necessary for undo of
import and implementation a cleaner interface. A few cases, notably
CSV and proprietary formats were forgotten.
Implement parsing into arbitrary tables also for these cases.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The format option "%m" doesn't work for MINGW/Windows and is reported as
an unknown conversation type and this sscanf() call would not work.
The alternative is to malloc() enough space manually - e.g.
strlen(input) + 1.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
datatrak_import() is the main function called from parse_file(), but
dt_dive_parser() is where the hard work is done, for both, drop file
seeking/reading and use memory pointers instead.
datatrak_import() now returns 0 on success or 1 on failure and abort
import if parser function fails instead of keeping on trying.
dt_dive_parser() emits a warning if libdc_model is zero (manual dives).
Do not parse profiles if libdc_model is zero, for unknown models we set
a fake 0xEE value coverted to Aladin Air X/Z libdc model number. Func
now takes a pointer to a buffer and moves along the dive, when done
returns a pointer to the actual memory position or NULL if something
went wrong.
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
Remove dtrak_profile() profile parsing func as this work is left to
libdivecomputer.
Simplifies read_file_header() to return the number of dives in the log
file as we don't use the rest of header data.
Add dtrak_prepare_data() to achieve a device_data_t structure and get
the correct libdc model number for the device.
Remove checking macro substituted with JUMP in header file.
Add dt_libdc_buffer() to get a buffer parseable with libdivecomputer.
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
The following pragma is Clang specific:
It produces a warning:
warning: ignoring #pragma clang diagnostic [-Wunknown-pragmas]
Only enable it for Clang by checking the __clang__ macro.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Not using lrint(f) when converting double/float to int
creates rounding errors.
This error was detected by TestParse::testParseDM4 failure
on Windows. It was creating rounding inconsistencies
on Linux too, see change in TestDiveDM4.xml.
Enable -Wfloat-conversion for gcc version greater than 4.9.0
Signed-off-by: Jeremie Guichard <djebrest@gmail.com>