Index: Mk/bsd.port.mk =================================================================== --- Mk/bsd.port.mk +++ Mk/bsd.port.mk @@ -4864,6 +4864,7 @@ OPTIONS_SINGLE="${OPTIONS_SINGLE}" \ OPTIONS_RADIO="${OPTIONS_RADIO}" \ OPTIONS_GROUP="${OPTIONS_GROUP}" \ + OPTIONS_SECTION_ORDER="${OPTIONS_SECTION_ORDER}" \ NEW_OPTIONS="${NEW_OPTIONS}" \ DIALOG4PORTS="${DIALOG4PORTS}" \ PREFIX="${PREFIX}" \ Index: ports-mgmt/dialog4ports/Makefile =================================================================== --- ports-mgmt/dialog4ports/Makefile +++ ports-mgmt/dialog4ports/Makefile @@ -3,7 +3,7 @@ PORTNAME= dialog4ports PORTVERSION= 0.1.6 -PORTREVISION?= 0 +PORTREVISION?= 1 CATEGORIES= ports-mgmt MASTER_SITES= http://m1cro.me/dialog4ports/ \ http://files.etoilebsd.net/dialog4ports/ \ Index: ports-mgmt/dialog4ports/files/patch-dialog4ports.c =================================================================== --- /dev/null +++ ports-mgmt/dialog4ports/files/patch-dialog4ports.c @@ -0,0 +1,257 @@ +--- dialog4ports.c.orig 2016-07-08 14:49:08 UTC ++++ dialog4ports.c +@@ -43,6 +43,7 @@ + + static int list_no = 0; + static int group = 0; ++static char const *env_delimiter = " \t"; + + /* The initial items size */ + static int items_sz = 5; +@@ -50,16 +51,22 @@ static int items_sz = 5; + static StringList *enable_items = NULL; + /* New items */ + static StringList *new_items = NULL; ++/* One options section */ ++typedef struct { ++ char env_name[32]; ++ char section_name[256]; ++ int type; ++} dialog_section; + + /* add item to items */ + static void +-add_item(dialog_mixedlist **items, char const *name, char const *text, ++add_item(dialog_option_item **items, char const *name, char const *text, + bool state, bool new, int type, int grp) + { + + if ((list_no + 1 > items_sz) || *items == NULL) { + items_sz *= 2; +- *items = realloc(*items, items_sz * sizeof(dialog_mixedlist)); ++ *items = realloc(*items, items_sz * sizeof(dialog_option_item)); + if (*items == NULL) + err(EXIT_FAILURE, "Need more memory!"); + } +@@ -126,81 +133,171 @@ parse_env_sl(char const *env_name) + + /* parsing part */ + static int +-parsing_env(dialog_mixedlist **items, char const *env_name, int type) ++parse_env_all(dialog_option_item **items, char const *env_name, int type) + { +- char *env, buf[256]; +- char const *delimiter = " \t"; +- char *token, *token2; ++ char *env; ++ char *token; + char *temp, *tofree; +- char *temp2, *tofree2; + + env = getenv(env_name); + if (env == NULL) + return (0); + +- if (strcmp(env_name, "ALL_OPTIONS") == 0) { +- tofree = temp = strdup(env); ++ tofree = temp = strdup(env); ++ while ((token = strsep(&temp, env_delimiter)) != NULL) { ++ if (token[0] == '\0') ++ continue; ++ add_item(items, token, get_desc(token, ""), is_enable(token), ++ is_new(token), type, group); ++ } ++ free(tofree); + +- while ((token = strsep(&temp, delimiter)) != NULL) { +- if (token[0] == '\0') +- continue; +- add_item(items, token, get_desc(token, ""), is_enable(token), +- is_new(token), type, group); ++ group++; ++ ++ return (0); ++} ++ ++static void ++order_sections(dialog_section **sections, int sections_size) ++{ ++ char *env; ++ char *token, *temp, *tofree; ++ dialog_section *ordered_sections, *sec; ++ int i, found; ++ ++ env = getenv("OPTIONS_SECTION_ORDER"); ++ if (env == NULL || env[0] == '\0') ++ return; ++ ++ if (sections_size == 0) ++ errx(EXIT_FAILURE, "OPTIONS_SECTION_ORDER is defined, but there are no option sections"); ++ ++ ordered_sections = malloc(sizeof(dialog_section)*sections_size); ++ sec = ordered_sections; ++ found = 0; ++ ++ tofree = temp = strdup(env); ++ while ((token = strsep(&temp, env_delimiter)) != NULL) { ++ if (token[0] == '\0') ++ continue; ++ ++ for (i = 0; i < sections_size; i++) { ++ if (strcmp((*sections)[i].section_name, token) == 0) { ++ *sec++ = (*sections)[i]; ++ found++; ++ break; ++ } + } +- free(tofree); +- } else { ++ if (i >= sections_size) ++ errx(EXIT_FAILURE, "can't find section %s from OPTIONS_SECTION_ORDER in any option group", token); ++ } ++ free(tofree); ++ ++ if (found != sections_size) ++ errx(EXIT_FAILURE, "Items in OPTIONS_SECTION_ORDER should match the declared option sections"); ++ ++ free(*sections); ++ *sections = ordered_sections; ++} ++ ++static void ++read_env_section(dialog_section **sections, int *sections_size, char const *env_name, int type) ++{ ++ char *env; ++ char *token; ++ char *temp, *tofree; ++ dialog_section *new_section; ++ ++ env = getenv(env_name); ++ if (env == NULL) ++ return; ++ ++ tofree = temp = strdup(env); ++ while ((token = strsep(&temp, env_delimiter)) != NULL) { ++ if (token[0] == '\0') ++ continue; ++ ++ if (*sections_size == 0) ++ *sections = malloc(sizeof(dialog_section)); ++ else ++ *sections = realloc(*sections, sizeof(dialog_section) * (*sections_size + 1)); ++ ++ new_section = *sections + *sections_size; ++ ++ strcpy(new_section->env_name, env_name); ++ strncpy(new_section->section_name, token, sizeof(new_section->section_name)); ++ new_section->type = type; ++ ++ ++*sections_size; ++ } ++ free(tofree); ++} ++ ++static int ++add_sections(dialog_option_item **items, dialog_section *sections, int sections_size) ++{ ++ int i; ++ char *env, buf[256]; ++ char *token; ++ char *temp, *tofree; ++ dialog_section *sec = sections; ++ ++ for (i = 0; i < sections_size; i++, sec++) { ++ add_item(items, get_desc(sec->section_name, sec->section_name), "", false, false, ++ ITEM_SEPARATOR, group); ++ ++ snprintf(buf, sizeof(buf), "%s_%s", sec->env_name, sec->section_name); ++ env = getenv(buf); ++ if (env == NULL) ++ errx(EXIT_FAILURE, "%s does not exists", buf); ++ + tofree = temp = strdup(env); +- while ((token = strsep(&temp, delimiter)) != NULL) { ++ while ((token = strsep(&temp, env_delimiter)) != NULL) { + if (token[0] == '\0') + continue; +- add_item(items, get_desc(token, token), "", false, false, +- ITEM_SEPARATOR, group); +- +- snprintf(buf, sizeof(buf), "%s_%s", env_name, token); +- env = getenv(buf); +- if (env == NULL) +- errx(EXIT_FAILURE, "%s does not exists", buf); +- tofree2 = temp2 = strdup(env); +- while ((token2 = strsep(&temp2, delimiter)) != NULL) { +- if (token2[0] == '\0') +- continue; +- add_item(items, token2, get_desc(token2, ""), +- is_enable(token2), is_new(token2), type, group); +- } +- free(tofree2); +- group++; ++ add_item(items, token, get_desc(token, ""), ++ is_enable(token), is_new(token), sec->type, group); + } +- + free(tofree); ++ group++; + } ++ + if (group == 0) + group++; + + return (0); + } + +- + /* prepare items for next drawing*/ +-static dialog_mixedlist * ++static dialog_option_item * + prepare_items(void) + { +- dialog_mixedlist *items = NULL; ++ dialog_option_item *items = NULL; ++ dialog_section *sections = NULL; ++ int sections_size = 0; + + enable_items = parse_env_sl("PORT_OPTIONS"); + new_items = parse_env_sl("NEW_OPTIONS"); + +- parsing_env(&items, "ALL_OPTIONS", ITEM_CHECK); +- parsing_env(&items, "OPTIONS_GROUP", ITEM_CHECK); +- parsing_env(&items, "OPTIONS_MULTI", ITEM_CHECK); +- parsing_env(&items, "OPTIONS_SINGLE", ITEM_RADIO); +- parsing_env(&items, "OPTIONS_RADIO", ITEM_RADIO); ++ parse_env_all(&items, "ALL_OPTIONS", ITEM_CHECK); ++ read_env_section(§ions, §ions_size, "OPTIONS_GROUP", ITEM_CHECK); ++ read_env_section(§ions, §ions_size, "OPTIONS_MULTI", ITEM_CHECK); ++ read_env_section(§ions, §ions_size, "OPTIONS_SINGLE", ITEM_RADIO); ++ read_env_section(§ions, §ions_size, "OPTIONS_RADIO", ITEM_RADIO); ++ ++ order_sections(§ions, sections_size); ++ ++ add_sections(&items, sections, sections_size); ++ ++ if (sections != NULL) ++ free(sections); + + return (items); + } + + static int + mixedlist_show(const char *title, const char *cprompt, int height, +- int min_height, int width, dialog_mixedlist *items, bool align_center, ++ int min_height, int width, dialog_option_item *items, bool align_center, + bool fullscreen) + { + int res; +@@ -235,7 +332,7 @@ main(int argc, char *argv[]) + bool align_center = 0; + bool fullscreen = 0; + char *helpfile; +- dialog_mixedlist *items; ++ dialog_option_item *items; + + setlocale(LC_ALL, ""); + errno = 0; Index: ports-mgmt/dialog4ports/files/patch-mixedlist.h =================================================================== --- /dev/null +++ ports-mgmt/dialog4ports/files/patch-mixedlist.h @@ -0,0 +1,20 @@ +--- mixedlist.h.orig 2018-02-01 07:50:50 UTC ++++ mixedlist.h +@@ -15,7 +15,7 @@ typedef struct { + int group; + bool state; + bool new; +-} dialog_mixedlist; ++} dialog_option_item; + + /* List of items */ + #define ITEM_CHECK 1 +@@ -23,7 +23,7 @@ typedef struct { + #define ITEM_SEPARATOR 3 + + int dlg_mixedlist(const char *title, const char *cprompt, int height, +- int min_height, int width, int item_no, dialog_mixedlist *items, ++ int min_height, int width, int item_no, dialog_option_item *items, + bool align_center, bool fullscreen); + + #endif Index: ports-mgmt/dialog4ports/files/patch-mixedlist.c =================================================================== --- /dev/null +++ ports-mgmt/dialog4ports/files/patch-mixedlist.c @@ -0,0 +1,38 @@ +--- mixedlist.c.orig 2018-02-01 07:53:26 UTC ++++ mixedlist.c +@@ -36,7 +36,7 @@ static int list_width, check_x, item_x; + #define MIN_HIGH (1 + (5 * MARGIN)) + + static int +-d4p_default_mixlistitem(dialog_mixedlist *items) ++d4p_default_mixlistitem(dialog_option_item *items) + { + int result = 0; + +@@ -55,7 +55,7 @@ d4p_default_mixlistitem(dialog_mixedlist + } + + static int +-d4p_calc_mixlist_width(int item_no, dialog_mixedlist *items) ++d4p_calc_mixlist_width(int item_no, dialog_option_item *items) + { + int n, i, len1 = 0, len2 = 0; + for (i = 0; i < item_no; ++i) { +@@ -140,7 +140,7 @@ d4p_clean_window(WINDOW *dialog) + */ + static void + print_item(WINDOW *win, +- dialog_mixedlist *items, ++ dialog_option_item *items, + int choice, + bool selected) + { +@@ -250,7 +250,7 @@ dlg_mixedlist(const char *title, + int min_height, + int width, + int item_no, +- dialog_mixedlist *items, ++ dialog_option_item *items, + bool align_center, + bool fullscreen) + {