summaryrefslogtreecommitdiffstats
path: root/smtk-import
diff options
context:
space:
mode:
authorGravatar Salvador Cuñat <salvador.cunat@gmail.com>2018-08-23 21:44:10 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2018-08-25 11:11:51 -0700
commit272dcf9514b59e2d337573284bc75faa4e91cf8d (patch)
treedd4f21ac4c6a05e14672745d81bdb51dc478cb8e /smtk-import
parent25491cf0776e2f22a50df830ee15f4d1c597f6fc (diff)
downloadsubsurface-272dcf9514b59e2d337573284bc75faa4e91cf8d.tar.gz
smtk-import: move from arrys to lists while parsing tables
In most cases we can not foresee the maximum number of data of a given type. It can be quite low or really big (a concerned diver can store thousands of different fishes in Fish table). Moving from arrays, where size has to be preset, to linked lists seems the more logical option. Here we set a (very limited) data structure, just an index and a text fields following the format of most SmartTrak tables. Some special table, like Buddy, needs a bit of processing before placing the data in the list. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
Diffstat (limited to 'smtk-import')
-rw-r--r--smtk-import/smartrak.c210
1 files changed, 144 insertions, 66 deletions
diff --git a/smtk-import/smartrak.c b/smtk-import/smartrak.c
index acc43e4f0..4577ca650 100644
--- a/smtk-import/smartrak.c
+++ b/smtk-import/smartrak.c
@@ -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);
}
/*