summaryrefslogtreecommitdiffstats
path: root/smtk-import/smartrak.c
diff options
context:
space:
mode:
Diffstat (limited to 'smtk-import/smartrak.c')
-rw-r--r--smtk-import/smartrak.c244
1 files changed, 170 insertions, 74 deletions
diff --git a/smtk-import/smartrak.c b/smtk-import/smartrak.c
index 826ad6a9d..ed4717287 100644
--- a/smtk-import/smartrak.c
+++ b/smtk-import/smartrak.c
@@ -506,16 +506,16 @@ static void merge_cylinder_type(cylinder_type_t *src, cylinder_type_t *dst)
}
}
-static void merge_cylinder_mix(struct gasmix *src, struct gasmix *dst)
+static void merge_cylinder_mix(struct gasmix src, struct gasmix *dst)
{
if (!dst->o2.permille)
- *dst = *src;
+ *dst = src;
}
static void merge_cylinder_info(cylinder_t *src, cylinder_t *dst)
{
merge_cylinder_type(&src->type, &dst->type);
- merge_cylinder_mix(&src->gasmix, &dst->gasmix);
+ merge_cylinder_mix(src->gasmix, &dst->gasmix);
MERGE_MAX(dst, dst, src, start.mbar);
MERGE_MIN(dst, dst, src, end.mbar);
if (!dst->cylinder_use)
@@ -550,63 +550,127 @@ static int smtk_clean_cylinders(struct dive *d)
}
/*
- * Parses a relation table and fills a list with the relations for a dive idx.
- * Returns the number of relations found for a given dive idx.
+ * List related functions
+ */
+struct types_list {
+ int idx;
+ char *text;
+ struct types_list *next;
+};
+
+/* Head insert types_list items in a list */
+static void smtk_head_insert(struct types_list **head, int index, char *txt)
+{
+ struct types_list *item = (struct types_list *) malloc(sizeof(struct types_list));
+
+ item->next = *head;
+ item->idx = index;
+ item->text = txt;
+ *head = item;
+ item = NULL;
+ free(item);
+}
+
+/* Clean types_list lists */
+static void smtk_list_free(struct types_list *head)
+{
+ struct types_list *p = head;
+ while (p) {
+ struct types_list *nxt = p->next;
+ free(p->text);
+ free(p);
+ p = nxt;
+ }
+}
+
+/*
+ * Build a list from a given table_name (Type, Gear, etc)
+ * Managed tables formats: Just consider Idx and Text
+ * Type:
+ * | Idx | Text | Default (bool)
+ * Activity:
+ * | Idx | Text | Default (bool)
+ * Gear:
+ * | Idx | Text | Vendor | Type | Typenum | Notes | Default (bool) | TrakId
+ * Fish:
+ * | Idx | Text | Name | Latin name | Typelength | Maxlength | Picture | Default (bool)| TrakId
+ * TODO: Although all divelogs I've seen use *only* the Text field, a concerned diver could
+ * be using some other like Vendor (in Gear) or Latin name (in Fish). I'll take a look at this
+ * in the future, may be something like Buddy table...
+ */
+static void smtk_build_list(MdbHandle *mdb, char *table_name, struct types_list **head)
+{
+ MdbTableDef *table;
+ MdbColumn *col[MDB_MAX_COLS];
+ char *bound_values[MDB_MAX_COLS];
+ struct types_list *p = NULL;
+
+ table = smtk_open_table(mdb, table_name, col, bound_values);
+ if (!table)
+ return;
+
+ /* Read the table items into an structured list */
+ while (mdb_fetch_row(table))
+ smtk_head_insert(&p, atoi(col[0]->bind_ptr), copy_string(col[1]->bind_ptr));
+ *head = p;
+
+ /* clean up and exit */
+ p = NULL;
+ free(p);
+ smtk_free(bound_values, table->num_cols);
+ mdb_free_tabledef(table);
+}
+
+/*
+ * Parses a relation table and returns a list with the relations for a dive idx.
+ * Use types_list items with text set to NULL.
+ * Returns a pointer to the list head.
* Table relation format:
* | Diveidx | Idx |
*/
-static int smtk_index_list(MdbHandle *mdb, char *table_name, char *dive_idx, int idx_list[])
+static struct types_list *smtk_index_list(MdbHandle *mdb, char *table_name, char *dive_idx)
{
- int n = 0, i = 0;
MdbTableDef *table;
MdbColumn *cols[MDB_MAX_COLS];
char *bounders[MDB_MAX_COLS];
+ struct types_list *item, *head = NULL;
table = smtk_open_table(mdb, table_name, cols, bounders);
/* Sanity check */
if (!table)
- return 0;
+ return NULL;
/* Parse the table searching for dive_idx */
while (mdb_fetch_row(table)) {
- if (!strcmp(dive_idx, cols[0]->bind_ptr)) {
- idx_list[n] = atoi(cols[1]->bind_ptr);
- n++;
- }
+ if (!strcmp(dive_idx, cols[0]->bind_ptr))
+ smtk_head_insert(&head, atoi(cols[1]->bind_ptr), NULL);
}
/* Clean up and exit */
smtk_free(bounders, table->num_cols);
mdb_free_tabledef(table);
- return n;
+ return head;
}
/*
- * Returns string with buddies names as registered in smartrak (may be a nickname).
+ * "Buddy" is a bit special table that needs some extra work, so we can't just use smtk_build_list.
* "Buddy" table is a buddies relation with lots and lots and lots of data (even buddy mother's
* maiden name ;-) ) most of them useless for a dive log. Let's just consider the nickname as main
* field and the full name if this exists and its construction is different from the nickname.
* Buddy table format:
* | Idx | Text (nickname) | Name | Firstname | Middlename | Title | Picture | Phone | ...
*/
-static char *smtk_locate_buddy(MdbHandle *mdb, char *dive_idx)
-{
- char *str = NULL, *fullname = NULL, *bounder[MDB_MAX_COLS] = { NULL }, *buddies[256] = { NULL };
+static void smtk_build_buddies(MdbHandle *mdb, struct types_list **buddies_head) {
MdbTableDef *table;
MdbColumn *col[MDB_MAX_COLS];
- int i, n, rel[256] = { 0 };
+ char *bound_values[MDB_MAX_COLS], *fullname = NULL, *str = NULL;
+ struct types_list *p = NULL;
- n = smtk_index_list(mdb, "BuddyRelation", dive_idx, rel);
- if (!n)
- return str;
- table = smtk_open_table(mdb, "Buddy", col, bounder);
+ table = smtk_open_table(mdb, "Buddy", col, bound_values);
if (!table)
- return str;
- /*
- * Buddies in a single dive aren't (usually) a big number, so probably
- * it's not a good idea to use a complex data structure and algorithm.
- */
+ return;
+
while (mdb_fetch_row(table)) {
if (!empty_string(col[3]->bind_ptr))
fullname = smtk_concat_str(fullname, " ", "%s", col[3]->bind_ptr);
@@ -615,19 +679,46 @@ static char *smtk_locate_buddy(MdbHandle *mdb, char *dive_idx)
if (!empty_string(col[2]->bind_ptr))
fullname = smtk_concat_str(fullname, " ", "%s", col[2]->bind_ptr);
if (fullname && !same_string(col[1]->bind_ptr, fullname))
- buddies[atoi(col[0]->bind_ptr)] = smtk_concat_str(buddies[atoi(col[0]->bind_ptr)], "", "%s (%s)", col[1]->bind_ptr, fullname);
+ smtk_head_insert(&p, atoi(col[0]->bind_ptr), smtk_concat_str(str, "", "%s (%s)", col[1]->bind_ptr, fullname));
else
- buddies[atoi(col[0]->bind_ptr)] = smtk_concat_str(buddies[atoi(col[0]->bind_ptr)], "", "%s", col[1]->bind_ptr);
+ smtk_head_insert(&p, atoi(col[0]->bind_ptr), smtk_concat_str(str, "", "%s", col[1]->bind_ptr));
free(fullname);
fullname = NULL;
}
- for (i = 0; i < n; i++)
- str = smtk_concat_str(str, ", ", "%s", buddies[rel[i]]);
+ *buddies_head = p;
- /* Clean up and exit */
- smtk_free(buddies, 256);
- smtk_free(bounder, MDB_MAX_COLS);
+ p = NULL;
+ free(p);
+ free(str);
+ smtk_free(bound_values, table->num_cols);
mdb_free_tabledef(table);
+}
+
+/*
+ * Returns string with buddies names as registered in smartrak (may be a nickname).
+ */
+static char *smtk_locate_buddy(MdbHandle *mdb, char *dive_idx, struct types_list *buddies_head)
+{
+ char *str = NULL;
+ struct types_list *rel, *rel_head, *bud;
+
+ rel_head = smtk_index_list(mdb, "BuddyRelation", dive_idx);
+ if (!rel_head)
+ return str;
+
+ for (rel = rel_head; rel; ) {
+ for (bud = buddies_head; bud; ) {
+ if (bud->idx == rel->idx) {
+ str = smtk_concat_str(str, ", ", "%s", bud->text);
+ break;
+ }
+ bud = bud->next;
+ }
+ rel = rel->next;
+ }
+
+ /* Clean up and exit */
+ smtk_list_free(rel_head);
return str;
}
@@ -636,50 +727,37 @@ static char *smtk_locate_buddy(MdbHandle *mdb, char *dive_idx)
* (SCR, CCR or so), set the dive mode too.
* The "tag" parameter is used to mark if we want this table to be imported
* into tags or into notes.
- * Managed tables formats: Just consider Idx and Text
- * Type:
- * | Idx | Text | Default (bool)
- * Activity:
- * | Idx | Text | Default (bool)
- * Gear:
- * | Idx | Text | Vendor | Type | Typenum | Notes | Default (bool) | TrakId
- * Fish:
- * | Idx | Text | Name | Latin name | Typelength | Maxlength | Picture | Default (bool)| TrakId
*/
-static void smtk_parse_relations(MdbHandle *mdb, struct dive *dive, char *dive_idx, char *table_name, char *rel_table_name, bool tag)
+static void smtk_parse_relations(MdbHandle *mdb, struct dive *dive, char *dive_idx, char *table_name, char *rel_table_name, struct types_list *list, bool tag)
{
- MdbTableDef *table;
- MdbColumn *col[MDB_MAX_COLS];
- char *bound_values[MDB_MAX_COLS], *tmp = NULL, *types[64] = { NULL };
- int i = 0, n = 0, rels[256] = { 0 };
+ char *tmp = NULL;
+ struct types_list *diverel_head, *d_runner, *t_runner;
- n = smtk_index_list(mdb, rel_table_name, dive_idx, rels);
- if (!n)
- return;
- table = smtk_open_table(mdb, table_name, col, bound_values);
- if (!table)
+ diverel_head = smtk_index_list(mdb, rel_table_name, dive_idx);
+ if (!diverel_head)
return;
- while (mdb_fetch_row(table))
- types[atoi(col[0]->bind_ptr)] = copy_string(col[1]->bind_ptr);
- for (i = 0; i < n; i++) {
- if (tag)
- taglist_add_tag(&dive->tag_list, types[rels[i]]);
- else
- tmp = smtk_concat_str(tmp, ", ", "%s", types[rels[i]]);
- if (strstr(types[rels[i]], "SCR"))
- dive->dc.divemode = PSCR;
- else if (strstr(types[rels[i]], "CCR"))
- dive->dc.divemode = CCR;
+ /* Get the text associated with the relations */
+ for (d_runner = diverel_head; d_runner; ) {
+ for (t_runner = list; t_runner; ) {
+ if (t_runner->idx == d_runner->idx) {
+ if (tag)
+ taglist_add_tag(&dive->tag_list, t_runner->text);
+ else
+ tmp = smtk_concat_str(tmp, ", ", "%s", t_runner->text);
+ if (strstr(t_runner->text, "SCR"))
+ dive->dc.divemode = PSCR;
+ else if (strstr(t_runner->text, "CCR"))
+ dive->dc.divemode = CCR;
+ break;
+ }
+ t_runner = t_runner->next;
+ }
+ d_runner = d_runner->next;
}
if (tmp)
dive->notes = smtk_concat_str(dive->notes, "\n", "Smartrak %s: %s", table_name, tmp);
free(tmp);
-
- /* clean up and exit */
- smtk_free(types, 64);
- smtk_free(bound_values, table->num_cols);
- mdb_free_tabledef(table);
}
/*
@@ -840,6 +918,7 @@ void smartrak_import(const char *file, struct dive_table *divetable)
MdbColumn *col[MDB_MAX_COLS];
char *bound_values[MDB_MAX_COLS], *ver;
int i, dc_model;
+ struct types_list *type_list = NULL, *activity_list = NULL, *gear_list = NULL, *fish_list = NULL, *buddy_list=NULL;
// Set an european style locale to work date/time conversion
setlocale(LC_TIME, "POSIX");
@@ -861,6 +940,13 @@ void smartrak_import(const char *file, struct dive_table *divetable)
free(ver);
tanks = (smtk_version < 10213) ? 3 : 10;
+ /* Load auxiliary tables into lists */
+ smtk_build_list(mdb_clon, "Type", &type_list);
+ smtk_build_list(mdb_clon, "Activity", &activity_list);
+ smtk_build_list(mdb_clon, "Gear", &gear_list);
+ smtk_build_list(mdb_clon, "Fish", &fish_list);
+ smtk_build_buddies(mdb_clon, &buddy_list);
+
mdb_table = smtk_open_table(mdb, "Dives", col, bound_values);
if (!mdb_table) {
report_error("[Error][smartrak_import]\tFile %s does not seem to be an SmartTrak file.", file);
@@ -973,17 +1059,27 @@ void smartrak_import(const char *file, struct dive_table *divetable)
smtkdive->weightsystem[0].weight.grams = lrint(strtod(col[coln(WEIGHT)]->bind_ptr, NULL) * 1000);
smtkdive->suit = smtk_value_by_idx(mdb_clon, "Suit", 1, col[coln(SUITIDX)]->bind_ptr);
smtk_build_location(mdb_clon, col[coln(SITEIDX)]->bind_ptr, smtkdive->when, &smtkdive->dive_site_uuid);
- smtkdive->buddy = smtk_locate_buddy(mdb_clon, col[0]->bind_ptr);
- smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Type", "TypeRelation", true);
- smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Activity", "ActivityRelation", false);
- smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Gear", "GearRelation", false);
- smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Fish", "FishRelation", false);
+ if (buddy_list)
+ smtkdive->buddy = smtk_locate_buddy(mdb_clon, col[0]->bind_ptr, buddy_list);
+ if (type_list)
+ smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Type", "TypeRelation", type_list, true);
+ if (activity_list)
+ smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Activity", "ActivityRelation", activity_list, false);
+ if (gear_list)
+ smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Gear", "GearRelation", gear_list, false);
+ if (fish_list)
+ smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Fish", "FishRelation", fish_list, false);
smtk_parse_bookmarks(mdb_clon, smtkdive, col[0]->bind_ptr);
smtkdive->notes = smtk_concat_str(smtkdive->notes, "\n", "%s", col[coln(REMARKS)]->bind_ptr);
record_dive_to_table(smtkdive, divetable);
free(devdata);
}
+ smtk_list_free(type_list);
+ smtk_list_free(activity_list);
+ smtk_list_free(gear_list);
+ smtk_list_free(fish_list);
+ smtk_list_free(buddy_list);
smtk_free(bound_values, mdb_table->num_cols);
mdb_free_tabledef(mdb_table);
mdb_free_catalog(mdb_clon);