From bf431d6cd9411714f849050a10071dc0fe0d7741 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Thu, 14 Apr 2011 12:49:44 +0200 Subject: Use generic lists for todo items. Use the new generic list implementation instead of "next" pointers in todo items. Signed-off-by: Lukas Fleischer --- src/args.c | 19 ++++--- src/calcurse.c | 1 + src/calcurse.h | 4 +- src/dmon.c | 1 + src/io.c | 31 +++++----- src/todo.c | 177 +++++++++++++++++++++++---------------------------------- 6 files changed, 103 insertions(+), 130 deletions(-) diff --git a/src/args.c b/src/args.c index e1cd1bc..18a8887 100644 --- a/src/args.c +++ b/src/args.c @@ -242,7 +242,7 @@ print_notefile (FILE *out, char *filename, int nbtab) static void todo_arg (int priority, int print_note, regex_t *regex) { - struct todo *i; + llist_item_t *i; int title = 1; char *titlestr, priority_str[BUFSIZ] = ""; char *all_todos_title = _("to do:\n"); @@ -259,20 +259,21 @@ todo_arg (int priority, int print_note, regex_t *regex) } while (0) #define DISPLAY_TODO do { \ - (void)snprintf (priority_str, BUFSIZ, "%d. ", abs (i->id)); \ + (void)snprintf (priority_str, BUFSIZ, "%d. ", abs (todo->id)); \ fputs (priority_str, stdout); \ - fputs (i->mesg, stdout); \ + fputs (todo->mesg, stdout); \ fputs ("\n", stdout); \ - if (print_note && i->note) \ - print_notefile (stdout, i->note, 1); \ + if (print_note && todo->note) \ + print_notefile (stdout, todo->note, 1); \ } while (0) - for (i = todolist; i != NULL; i = i->next) + LLIST_FOREACH (&todolist, i) { - if (regex && regexec (regex, i->mesg, 0, 0, 0) != 0) + struct todo *todo = LLIST_TS_GET_DATA (i); + if (regex && regexec (regex, todo->mesg, 0, 0, 0) != 0) continue; - if (i->id < 0) /* completed task */ + if (todo->id < 0) /* completed task */ { if (priority == 0) { @@ -282,7 +283,7 @@ todo_arg (int priority, int print_note, regex_t *regex) } else { - if (priority < 0 || i->id == priority) + if (priority < 0 || todo->id == priority) { DISPLAY_TITLE; DISPLAY_TODO; diff --git a/src/calcurse.c b/src/calcurse.c index 95c9de8..3741614 100644 --- a/src/calcurse.c +++ b/src/calcurse.c @@ -77,6 +77,7 @@ main (int argc, char **argv) /* Initialize non-thread-safe data structures. */ event_llist_init (); + todo_init_list (); /* * Begin by parsing and handling command line arguments. diff --git a/src/calcurse.h b/src/calcurse.h index a4f33fa..7bcdb31 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -278,7 +278,6 @@ struct event { /* Todo item definition. */ struct todo { - struct todo *next; char *mesg; int id; char *note; @@ -810,7 +809,7 @@ void sigs_init (void); unsigned sigs_set_hdlr (int, void (*)(int)); /* todo.c */ -extern struct todo *todolist; +extern llist_t todolist; void todo_hilt_set (int); void todo_hilt_decrease (void); void todo_hilt_increase (void); @@ -831,6 +830,7 @@ void todo_edit_item (void); void todo_update_panel (int); void todo_edit_note (char *); void todo_view_note (char *); +void todo_init_list (void); void todo_free_list (void); /* utils.c */ diff --git a/src/dmon.c b/src/dmon.c index 234cf67..89ef80d 100644 --- a/src/dmon.c +++ b/src/dmon.c @@ -173,6 +173,7 @@ dmon_start (int parent_exit_status) apoint_llist_init (); recur_apoint_llist_init (); event_llist_init (); + todo_init_list (); io_load_app (); data_loaded = 1; diff --git a/src/io.c b/src/io.c index 2e6fcf1..d6f6565 100644 --- a/src/io.c +++ b/src/io.c @@ -637,16 +637,17 @@ pcal_export_apoints (FILE *stream) static void ical_export_todo (FILE *stream) { - struct todo *i; + llist_item_t *i; - for (i = todolist; i != NULL; i = i->next) + LLIST_FOREACH (&todolist, i) { - if (i->id < 0) /* completed items */ + struct todo *todo = LLIST_TS_GET_DATA (i); + if (todo->id < 0) /* completed items */ continue; (void)fprintf (stream, "BEGIN:VTODO\n"); - (void)fprintf (stream, "PRIORITY:%d\n", i->id); - (void)fprintf (stream, "SUMMARY:%s\n", i->mesg); + (void)fprintf (stream, "PRIORITY:%d\n", todo->id); + (void)fprintf (stream, "SUMMARY:%s\n", todo->mesg); (void)fprintf (stream, "END:VTODO\n"); } } @@ -654,16 +655,17 @@ ical_export_todo (FILE *stream) static void pcal_export_todo (FILE *stream) { - struct todo *i; + llist_item_t *i; (void)fprintf (stream, "#\n# Todos\n#\n"); - for (i = todolist; i != NULL; i = i->next) + LLIST_FOREACH (&todolist, i) { - if (i->id < 0) /* completed items */ + struct todo *todo = LLIST_TS_GET_DATA (i); + if (todo->id < 0) /* completed items */ continue; (void)fprintf (stream, "note all "); - (void)fprintf (stream, "%d. %s\n", i->id, i->mesg); + (void)fprintf (stream, "%d. %s\n", todo->id, todo->mesg); } (void)fprintf (stream, "\n"); } @@ -999,18 +1001,19 @@ io_save_apts (void) unsigned io_save_todo (void) { - struct todo *t; + llist_item_t *i; FILE *fp; if ((fp = fopen (path_todo, "w")) == NULL) return 0; - for (t = todolist; t != NULL; t = t->next) + LLIST_FOREACH (&todolist, i) { - if (t->note) - (void)fprintf (fp, "[%d]>%s %s\n", t->id, t->note, t->mesg); + struct todo *todo = LLIST_TS_GET_DATA (i); + if (todo->note) + (void)fprintf (fp, "[%d]>%s %s\n", todo->id, todo->note, todo->mesg); else - (void)fprintf (fp, "[%d] %s\n", t->id, t->mesg); + (void)fprintf (fp, "[%d] %s\n", todo->id, todo->mesg); } file_close (fp, __FILE_POS__); diff --git a/src/todo.c b/src/todo.c index 125b128..47c5ea2 100644 --- a/src/todo.c +++ b/src/todo.c @@ -40,7 +40,7 @@ #include "calcurse.h" -struct todo *todolist; +llist_t todolist; static int hilt = 0; static int todos = 0; static int first = 1; @@ -50,15 +50,7 @@ static char *msgsav; static struct todo * todo_get_item (int item_number) { - struct todo *o; - int i; - - o = todolist; - for (i = 1; i < item_number; i++) - { - o = o->next; - } - return (o); + return LLIST_GET_DATA (LLIST_NTH (&todolist, item_number - 1)); } /* Sets which todo is highlighted. */ @@ -159,87 +151,67 @@ todo_new_item (void) } } +static int +todo_cmp_id (struct todo *a, struct todo *b) +{ + /* + * As of version 2.6, todo items can have a negative id, which means they + * were completed. To keep them sorted, we need to consider the absolute id + * value. + */ + int abs_a = abs (a->id); + int abs_b = abs (b->id); + + return (abs_a < abs_b ? -1 : (abs_a == abs_b ? 0 : 1)); +} + /* * Add an item in the todo linked list. */ struct todo * todo_add (char *mesg, int id, char *note) { - struct todo *o, **i; - int absid; + struct todo *todo; - o = mem_malloc (sizeof (struct todo)); - o->mesg = mem_strdup (mesg); - o->id = id; - o->note = (note != NULL && note[0] != '\0') ? mem_strdup (note) : NULL; - i = &todolist; + todo = mem_malloc (sizeof (struct todo)); + todo->mesg = mem_strdup (mesg); + todo->id = id; + todo->note = (note != NULL && note[0] != '\0') ? mem_strdup (note) : NULL; - /* - * As of version 2.6, todo items can have a negative id, which means they - * were completed. To keep them sorted, we need to consider the absolute id - * value. - */ - absid = abs (id); - for (;;) - { - if (*i == NULL || abs ((*i)->id) > absid) - { - o->next = *i; - *i = o; - break; - } - i = &(*i)->next; - } - return (o); + LLIST_ADD_SORTED (&todolist, todo, todo_cmp_id); + + return todo; } /* Delete a note previously attached to a todo item. */ static void todo_delete_note_bynum (unsigned num) { - unsigned n; - struct todo *i; + llist_item_t *i = LLIST_NTH (&todolist, num); - n = 0; - for (i = todolist; i != NULL; i = i->next) - { - if (n == num) - { - if (i->note == NULL) - EXIT (_("no note attached")); - erase_note (&i->note, ERASE_FORCE_ONLY_NOTE); - return; - } - n++; - } - /* NOTREACHED */ - EXIT (_("no such todo")); + if (!i) + EXIT (_("no such todo")); + struct todo *todo = LLIST_TS_GET_DATA (i); + + if (!todo->note) + EXIT (_("no note attached")); + erase_note (&todo->note, ERASE_FORCE_ONLY_NOTE); } /* Delete an item from the todo linked list. */ static void todo_delete_bynum (unsigned num, enum eraseflg flag) { - unsigned n; - struct todo *i, **iptr; + llist_item_t *i = LLIST_NTH (&todolist, num); - n = 0; - iptr = &todolist; - for (i = todolist; i != NULL; i = i->next) - { - if (n == num) - { - *iptr = i->next; - mem_free (i->mesg); - erase_note (&i->note, flag); - mem_free (i); - return; - } - iptr = &i->next; - n++; - } - /* NOTREACHED */ - EXIT (_("no such todo")); + if (!i) + EXIT (_("no such todo")); + struct todo *todo = LLIST_TS_GET_DATA (i); + + LLIST_REMOVE (&todolist, i); + mem_free (todo->mesg); + erase_note (&todo->note, flag); + mem_free (todo); } /* @@ -330,29 +302,20 @@ todo_delete (struct conf *conf) * given todo item. */ static int -todo_get_position (struct todo *i) +todo_get_position (struct todo *needle) { - struct todo *o; - int n = 1, found = 0; + llist_item_t *i; + int n = 0; - for (o = todolist; o; o = o->next) + LLIST_FOREACH (&todolist, i) { - if (o == i) - { - found = 1; - break; - } n++; + if (LLIST_TS_GET_DATA (i) == needle) + return n; } - if (found) - { - return (n); - } - else - { - EXIT (_("todo not found")); - return -1; /* avoid compiler warnings */ - } + + EXIT (_("todo not found")); + return -1; /* avoid compiler warnings */ } /* Change an item priority by pressing '+' or '-' inside TODO panel. */ @@ -438,7 +401,7 @@ display_todo_item (int incolor, char *msg, int prio, int note, int len, int y, void todo_update_panel (int which_pan) { - struct todo *i; + llist_item_t *i; int len = win[TOD].w - 8; int num_todo = 0; int y_offset = 3, x_offset = 1; @@ -451,17 +414,18 @@ todo_update_panel (int which_pan) /* Print todo item in the panel. */ erase_window_part (win[TOD].p, 1, title_lines, win[TOD].w - 2, win[TOD].h - 2); - for (i = todolist; i != NULL; i = i->next) + LLIST_FOREACH (&todolist, i) { + struct todo *todo = LLIST_TS_GET_DATA (i); num_todo++; t_realpos = num_todo - first; incolor = num_todo - hilt; if (incolor == 0) - msgsav = i->mesg; + msgsav = todo->mesg; if (t_realpos >= 0 && t_realpos < max_items) { - display_todo_item (incolor, i->mesg, i->id, - (i->note != NULL) ? 1 : 0, len, y_offset, + display_todo_item (incolor, todo->mesg, todo->id, + (todo->note != NULL) ? 1 : 0, len, y_offset, x_offset); y_offset = y_offset + todo_lines; } @@ -523,19 +487,22 @@ todo_view_note (char *pager) } void -todo_free_list (void) +todo_free (struct todo *todo) { - struct todo *o, **i; + mem_free (todo->mesg); + erase_note (&todo->note, ERASE_FORCE_KEEP_NOTE); + mem_free (todo); +} - i = &todolist; - while (*i) - { - o = *i; - *i = o->next; - mem_free (o->mesg); - erase_note (&o->note, ERASE_FORCE_KEEP_NOTE); - mem_free (o); - } - if (todolist) - mem_free (todolist); +void +todo_init_list (void) +{ + LLIST_INIT (&todolist); +} + +void +todo_free_list (void) +{ + LLIST_FREE_INNER (&todolist, todo_free); + LLIST_FREE (&todolist); } -- cgit v1.2.3-54-g00ecf