Code

Oops, fix enum_equals
[tig.git] / tig.c
diff --git a/tig.c b/tig.c
index 41d8123379eec382c30f9e7d9e9bb9c1f09892d2..d9f26dd0f850c345093bc02a386e25421734221d 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -297,6 +297,9 @@ string_enum_compare(const char *str1, const char *str2, int len)
        return 0;
 }
 
+#define enum_equals(entry, str, len) \
+       ((entry).namelen == (len) && !string_enum_compare((entry).name, str, len))
+
 struct enum_map {
        const char *name;
        int namelen;
@@ -330,8 +333,7 @@ map_enum_do(const struct enum_map *map, size_t map_size, int *value, const char
        int i;
 
        for (i = 0; i < map_size; i++)
-               if (namelen == map[i].namelen &&
-                   !string_enum_compare(name, map[i].name, namelen)) {
+               if (enum_equals(map[i], name, namelen)) {
                        *value = map[i].value;
                        return TRUE;
                }
@@ -381,14 +383,25 @@ static int local_tzoffset(time_t time)
        return offset * eastwest;
 }
 
+#define DATE_INFO \
+       DATE_(NO), \
+       DATE_(DEFAULT), \
+       DATE_(RELATIVE), \
+       DATE_(SHORT)
+
 enum date {
-       DATE_NONE = 0,
-       DATE_DEFAULT,
-       DATE_RELATIVE,
-       DATE_SHORT
+#define DATE_(name) DATE_##name
+       DATE_INFO
+#undef DATE_
 };
 
-static char *
+static const struct enum_map date_map[] = {
+#define DATE_(name) ENUM_MAP(#name, DATE_##name)
+       DATE_INFO
+#undef DATE_
+};
+
+static const char *
 string_date(const time_t *time, enum date date)
 {
        static char buf[DATE_COLS + 1];
@@ -981,8 +994,7 @@ get_request(const char *name)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(req_info); i++)
-               if (req_info[i].namelen == namelen &&
-                   !string_enum_compare(req_info[i].name, name, namelen))
+               if (enum_equals(req_info[i], name, namelen))
                        return req_info[i].request;
 
        return REQ_NONE;
@@ -1143,8 +1155,7 @@ get_line_info(const char *name)
        enum line_type type;
 
        for (type = 0; type < ARRAY_SIZE(line_info); type++)
-               if (namelen == line_info[type].namelen &&
-                   !string_enum_compare(line_info[type].name, name, namelen))
+               if (enum_equals(line_info[type], name, namelen))
                        return &line_info[type];
 
        return NULL;
@@ -1676,6 +1687,26 @@ static int parse_bool(bool *opt, const char *arg)
        return OK;
 }
 
+static int parse_enum_do(unsigned int *opt, const char *arg,
+                        const struct enum_map *map, size_t map_size)
+{
+       bool is_true;
+
+       assert(map_size > 1);
+
+       if (map_enum_do(map, map_size, (int *) opt, arg))
+               return OK;
+
+       if (parse_bool(&is_true, arg) != OK)
+               return ERR;
+
+       *opt = is_true ? map[1].value : map[0].value;
+       return OK;
+}
+
+#define parse_enum(opt, arg, map) \
+       parse_enum_do(opt, arg, map, ARRAY_SIZE(map))
+
 static int
 parse_string(char *opt, const char *arg, size_t optsize)
 {
@@ -1712,21 +1743,8 @@ option_set_command(int argc, const char *argv[])
        if (!strcmp(argv[0], "show-author"))
                return parse_bool(&opt_author, argv[2]);
 
-       if (!strcmp(argv[0], "show-date")) {
-               bool show_date;
-
-               if (!strcmp(argv[2], "relative")) {
-                       opt_date = DATE_RELATIVE;
-                       return OK;
-               } else if (!strcmp(argv[2], "short")) {
-                       opt_date = DATE_SHORT;
-                       return OK;
-               } else if (parse_bool(&show_date, argv[2]) == OK) {
-                       opt_date = show_date ? DATE_DEFAULT : DATE_NONE;
-                       return OK;
-               }
-               return ERR;
-       }
+       if (!strcmp(argv[0], "show-date"))
+               return parse_enum(&opt_date, argv[2], date_map);
 
        if (!strcmp(argv[0], "show-rev-graph"))
                return parse_bool(&opt_rev_graph, argv[2]);
@@ -2468,20 +2486,19 @@ redraw_display(bool clear)
 }
 
 static void
-toggle_date_option(enum date *date)
+toggle_enum_option_do(unsigned int *opt, const char *help,
+                     const struct enum_map *map, size_t size)
 {
-       static const char *help[] = {
-               "no",
-               "default",
-               "relative",
-               "short"
-       };
-
-       *date = (*date + 1) % ARRAY_SIZE(help);
+       *opt = (*opt + 1) % size;
        redraw_display(FALSE);
-       report("Displaying %s dates", help[*date]);
+       report("Displaying %s %s", enum_name(map[*opt]), help);
 }
 
+#define toggle_enum_option(opt, help, map) \
+       toggle_enum_option_do(opt, help, map, ARRAY_SIZE(map))
+
+#define toggle_date() toggle_enum_option(&opt_date, "dates", date_map)
+
 static void
 toggle_view_option(bool *option, const char *help)
 {
@@ -2505,7 +2522,7 @@ open_option_menu(void)
 
        if (prompt_menu("Toggle option", menu, &selected)) {
                if (menu[selected].data == &opt_date)
-                       toggle_date_option(menu[selected].data);
+                       toggle_date();
                else
                        toggle_view_option(menu[selected].data, menu[selected].text);
        }
@@ -3502,7 +3519,7 @@ view_driver(struct view *view, enum request request)
                break;
 
        case REQ_TOGGLE_DATE:
-               toggle_date_option(&opt_date);
+               toggle_date();
                break;
 
        case REQ_TOGGLE_AUTHOR: