diff options
Diffstat (limited to 'dive.c')
-rw-r--r-- | dive.c | 109 |
1 files changed, 40 insertions, 69 deletions
@@ -206,7 +206,6 @@ struct dive *alloc_dive(void) if (!dive) exit(1); memset(dive, 0, sizeof(*dive)); - taglist_init(&(dive->tag_list)); return dive; } @@ -1954,7 +1953,7 @@ int taglist_get_tagstring(struct tag_entry *tag_list, char *buffer, int len) { int i = 0; struct tag_entry *tmp; - tmp = tag_list->next; + tmp = tag_list; memset(buffer, 0, len); while (tmp != NULL) { int newlength = strlen(tmp->tag->name); @@ -1976,21 +1975,6 @@ int taglist_get_tagstring(struct tag_entry *tag_list, char *buffer, int len) return i; } -struct divetag *taglist_get_tag(struct tag_entry *tag_list, const char *tag) -{ - struct tag_entry *tmp; - tmp = tag_list->next; - while (tmp != NULL) { - if (tmp->tag != NULL) { - if (strcmp(tmp->tag->name, tag) == 0) - return tmp->tag; - else - tmp = tmp->next; - } - } - return NULL; -} - static inline void taglist_free_divetag(struct divetag *tag) { if (tag->name != NULL) @@ -2001,29 +1985,32 @@ static inline void taglist_free_divetag(struct divetag *tag) } /* Add a tag to the tag_list, keep the list sorted */ -static struct divetag *taglist_add_divetag(struct tag_entry *tag_list, struct divetag *tag) -{ - struct tag_entry *tmp, *last; - last = tag_list; - tmp = tag_list->next; - while (1) { - if (tmp == NULL || strcmp(tmp->tag->name, tag->name) > 0) { - /* Insert in front of it */ - last->next = malloc(sizeof(struct tag_entry)); - last->next->next = tmp; - last->next->tag = tag; - return last->next->tag; - } else if (strcmp(tmp->tag->name, tag->name) == 0) { - /* Already in list */ - return tmp->tag; - } else { - last = tmp; - tmp = tmp->next; - } +static struct divetag *taglist_add_divetag(struct tag_entry **tag_list, struct divetag *tag) +{ + struct tag_entry *next, *entry; + + while ((next = *tag_list) != NULL) { + int cmp = strcmp(next->tag->name, tag->name); + + /* Already have it? */ + if (!cmp) + return next->tag; + /* Is the entry larger? If so, insert here */ + if (cmp > 0) + break; + /* Continue traversing the list */ + tag_list = &next->next; } + + /* Insert in front of it */ + entry = malloc(sizeof(struct tag_entry)); + entry->next = next; + entry->tag = tag; + *tag_list = entry; + return tag; } -struct divetag *taglist_add_tag(struct tag_entry *tag_list, const char *tag) +struct divetag *taglist_add_tag(struct tag_entry **tag_list, const char *tag) { int i = 0, is_default_tag = 0; struct divetag *ret_tag, *new_tag; @@ -2049,8 +2036,8 @@ struct divetag *taglist_add_tag(struct tag_entry *tag_list, const char *tag) memcpy(new_tag->name, tag, strlen(tag) + 1); } /* Try to insert new_tag into g_tag_list if we are not operating on it */ - if (tag_list != g_tag_list) { - ret_tag = taglist_add_divetag(g_tag_list, new_tag); + if (tag_list != &g_tag_list) { + ret_tag = taglist_add_divetag(&g_tag_list, new_tag); /* g_tag_list already contains new_tag, free the duplicate */ if (ret_tag != new_tag) taglist_free_divetag(new_tag); @@ -2063,49 +2050,33 @@ struct divetag *taglist_add_tag(struct tag_entry *tag_list, const char *tag) return ret_tag; } -void taglist_init(struct tag_entry **tag_list) -{ - *tag_list = malloc(sizeof(struct tag_entry)); - (*tag_list)->next = NULL; - (*tag_list)->tag = NULL; -} - /* Clear everything but the first element */ -void taglist_clear(struct tag_entry *tag_list) +void taglist_free(struct tag_entry *entry) { - struct tag_entry *current_tag_entry, *next; - current_tag_entry = tag_list->next; - while (current_tag_entry != NULL) { - next = current_tag_entry->next; - free(current_tag_entry); - current_tag_entry = next; + while (entry) { + struct tag_entry *next = entry->next; + free(entry); + entry = next; } - tag_list->next = NULL; } /* Merge src1 and src2, write to *dst */ -static void taglist_merge(struct tag_entry *dst, struct tag_entry *src1, struct tag_entry *src2) +static void taglist_merge(struct tag_entry **dst, struct tag_entry *src1, struct tag_entry *src2) { - struct tag_entry *current_tag_entry; - current_tag_entry = src1->next; - while (current_tag_entry != NULL) { - taglist_add_divetag(dst, current_tag_entry->tag); - current_tag_entry = current_tag_entry->next; - } - current_tag_entry = src2->next; - while (current_tag_entry != NULL) { - taglist_add_divetag(dst, current_tag_entry->tag); - current_tag_entry = current_tag_entry->next; - } + struct tag_entry *entry; + + for (entry = src1; entry; entry = entry->next) + taglist_add_divetag(dst, entry->tag); + for (entry = src2; entry; entry = entry->next) + taglist_add_divetag(dst, entry->tag); } void taglist_init_global() { int i; - taglist_init(&g_tag_list); for (i = 0; i < sizeof(default_tags) / sizeof(char *); i++) - taglist_add_tag(g_tag_list, default_tags[i]); + taglist_add_tag(&g_tag_list, default_tags[i]); } struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer_downloaded) @@ -2144,7 +2115,7 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer MERGE_MAX(res, a, b, number); MERGE_NONZERO(res, a, b, cns); MERGE_NONZERO(res, a, b, visibility); - taglist_merge(res->tag_list, a->tag_list, b->tag_list); + taglist_merge(&res->tag_list, a->tag_list, b->tag_list); merge_equipment(res, a, b); merge_airtemps(res, a, b); if (dl) { |