Line 0
Link Here
|
|
|
1 |
--- dialog4ports.c.orig 2016-07-08 14:49:08 UTC |
2 |
+++ dialog4ports.c |
3 |
@@ -43,6 +43,7 @@ |
4 |
|
5 |
static int list_no = 0; |
6 |
static int group = 0; |
7 |
+static char const *env_delimiter = " \t"; |
8 |
|
9 |
/* The initial items size */ |
10 |
static int items_sz = 5; |
11 |
@@ -50,6 +51,12 @@ static int items_sz = 5; |
12 |
static StringList *enable_items = NULL; |
13 |
/* New items */ |
14 |
static StringList *new_items = NULL; |
15 |
+/* One options section */ |
16 |
+struct section_and_type { |
17 |
+ char env_name[32]; |
18 |
+ char section_name[256]; |
19 |
+ int type; |
20 |
+}; |
21 |
|
22 |
/* add item to items */ |
23 |
static void |
24 |
@@ -126,74 +133,161 @@ parse_env_sl(char const *env_name) |
25 |
|
26 |
/* parsing part */ |
27 |
static int |
28 |
-parsing_env(dialog_mixedlist **items, char const *env_name, int type) |
29 |
+parse_env_all(dialog_mixedlist **items, char const *env_name, int type) |
30 |
{ |
31 |
- char *env, buf[256]; |
32 |
- char const *delimiter = " \t"; |
33 |
- char *token, *token2; |
34 |
+ char *env; |
35 |
+ char *token; |
36 |
char *temp, *tofree; |
37 |
- char *temp2, *tofree2; |
38 |
|
39 |
env = getenv(env_name); |
40 |
if (env == NULL) |
41 |
return (0); |
42 |
|
43 |
- if (strcmp(env_name, "ALL_OPTIONS") == 0) { |
44 |
- tofree = temp = strdup(env); |
45 |
+ tofree = temp = strdup(env); |
46 |
+ while ((token = strsep(&temp, env_delimiter)) != NULL) { |
47 |
+ if (token[0] == '\0') |
48 |
+ continue; |
49 |
+ add_item(items, token, get_desc(token, ""), is_enable(token), |
50 |
+ is_new(token), type, group); |
51 |
+ } |
52 |
+ free(tofree); |
53 |
|
54 |
- while ((token = strsep(&temp, delimiter)) != NULL) { |
55 |
- if (token[0] == '\0') |
56 |
- continue; |
57 |
- add_item(items, token, get_desc(token, ""), is_enable(token), |
58 |
- is_new(token), type, group); |
59 |
+ group++; |
60 |
+ |
61 |
+ return (0); |
62 |
+} |
63 |
+ |
64 |
+static void |
65 |
+order_sections(struct section_and_type **sections, int sections_size) |
66 |
+{ |
67 |
+ char *env; |
68 |
+ char *token, *temp, *tofree; |
69 |
+ struct section_and_type *ordered_sections, *sec; |
70 |
+ int i; |
71 |
+ |
72 |
+ env = getenv("OPTIONS_SECTION_ORDER"); |
73 |
+ if (env == NULL || env[0] == '\0') |
74 |
+ return; |
75 |
+ |
76 |
+ if (sections_size == 0) |
77 |
+ errx(EXIT_FAILURE, "OPTIONS_SECTION_ORDER is defined, but there are no option sections"); |
78 |
+ |
79 |
+ ordered_sections = malloc(sizeof(struct section_and_type)*sections_size); |
80 |
+ sec = ordered_sections; |
81 |
+ found = 0; |
82 |
+ |
83 |
+ tofree = temp = strdup(env); |
84 |
+ while ((token = strsep(&temp, env_delimiter)) != NULL) { |
85 |
+ if (token[0] == '\0') |
86 |
+ continue; |
87 |
+ |
88 |
+ for (i = 0; i < sections_size; i++) { |
89 |
+ if (strcmp((*sections)[i].section_name, token) == 0) { |
90 |
+ *sec++ = (*sections)[i]; |
91 |
+ found++; |
92 |
+ break; |
93 |
+ } |
94 |
} |
95 |
- free(tofree); |
96 |
- } else { |
97 |
+ if (i >= sections_size) |
98 |
+ errx(EXIT_FAILURE, "can't find section %s from OPTIONS_SECTION_ORDER in any option group", token); |
99 |
+ } |
100 |
+ free(tofree); |
101 |
+ |
102 |
+ if (found != sections_size) |
103 |
+ errx(EXIT_FAILURE, "Items in OPTIONS_SECTION_ORDER should match the declared option sections"); |
104 |
+ |
105 |
+ free(*sections); |
106 |
+ *sections = ordered_sections; |
107 |
+} |
108 |
+ |
109 |
+static void |
110 |
+read_env_section(struct section_and_type **sections, int *sections_size, char const *env_name, int type) |
111 |
+{ |
112 |
+ char *env; |
113 |
+ char *token; |
114 |
+ char *temp, *tofree; |
115 |
+ struct section_and_type *new_section; |
116 |
+ |
117 |
+ env = getenv(env_name); |
118 |
+ if (env == NULL) |
119 |
+ return; |
120 |
+ |
121 |
+ tofree = temp = strdup(env); |
122 |
+ while ((token = strsep(&temp, env_delimiter)) != NULL) { |
123 |
+ if (token[0] == '\0') |
124 |
+ continue; |
125 |
+ |
126 |
+ if (*sections_size == 0) |
127 |
+ *sections = malloc(sizeof(struct section_and_type)); |
128 |
+ else |
129 |
+ *sections = realloc(*sections, sizeof(struct section_and_type) * (*sections_size + 1)); |
130 |
+ |
131 |
+ new_section = *sections + *sections_size; |
132 |
+ |
133 |
+ strcpy(new_section->env_name, env_name); |
134 |
+ strncpy(new_section->section_name, token, sizeof(new_section->section_name)); |
135 |
+ new_section->type = type; |
136 |
+ |
137 |
+ ++*sections_size; |
138 |
+ } |
139 |
+ free(tofree); |
140 |
+} |
141 |
+ |
142 |
+static int |
143 |
+add_sections(dialog_mixedlist **items, struct section_and_type *sections, int sections_size) |
144 |
+{ |
145 |
+ int i; |
146 |
+ char *env, buf[256]; |
147 |
+ char *token; |
148 |
+ char *temp, *tofree; |
149 |
+ struct section_and_type *sec = sections; |
150 |
+ |
151 |
+ for (i = 0; i < sections_size; i++, sec++) { |
152 |
+ add_item(items, get_desc(sec->section_name, sec->section_name), "", false, false, |
153 |
+ ITEM_SEPARATOR, group); |
154 |
+ |
155 |
+ snprintf(buf, sizeof(buf), "%s_%s", sec->env_name, sec->section_name); |
156 |
+ env = getenv(buf); |
157 |
+ if (env == NULL) |
158 |
+ errx(EXIT_FAILURE, "%s does not exists", buf); |
159 |
+ |
160 |
tofree = temp = strdup(env); |
161 |
- while ((token = strsep(&temp, delimiter)) != NULL) { |
162 |
+ while ((token = strsep(&temp, env_delimiter)) != NULL) { |
163 |
if (token[0] == '\0') |
164 |
continue; |
165 |
- add_item(items, get_desc(token, token), "", false, false, |
166 |
- ITEM_SEPARATOR, group); |
167 |
- |
168 |
- snprintf(buf, sizeof(buf), "%s_%s", env_name, token); |
169 |
- env = getenv(buf); |
170 |
- if (env == NULL) |
171 |
- errx(EXIT_FAILURE, "%s does not exists", buf); |
172 |
- tofree2 = temp2 = strdup(env); |
173 |
- while ((token2 = strsep(&temp2, delimiter)) != NULL) { |
174 |
- if (token2[0] == '\0') |
175 |
- continue; |
176 |
- add_item(items, token2, get_desc(token2, ""), |
177 |
- is_enable(token2), is_new(token2), type, group); |
178 |
- } |
179 |
- free(tofree2); |
180 |
- group++; |
181 |
+ add_item(items, token, get_desc(token, ""), |
182 |
+ is_enable(token), is_new(token), sec->type, group); |
183 |
} |
184 |
- |
185 |
free(tofree); |
186 |
+ group++; |
187 |
} |
188 |
+ |
189 |
if (group == 0) |
190 |
group++; |
191 |
|
192 |
return (0); |
193 |
} |
194 |
|
195 |
- |
196 |
/* prepare items for next drawing*/ |
197 |
static dialog_mixedlist * |
198 |
prepare_items(void) |
199 |
{ |
200 |
dialog_mixedlist *items = NULL; |
201 |
+ struct section_and_type *sections = NULL; |
202 |
+ int sections_size = 0; |
203 |
|
204 |
enable_items = parse_env_sl("PORT_OPTIONS"); |
205 |
new_items = parse_env_sl("NEW_OPTIONS"); |
206 |
|
207 |
- parsing_env(&items, "ALL_OPTIONS", ITEM_CHECK); |
208 |
- parsing_env(&items, "OPTIONS_GROUP", ITEM_CHECK); |
209 |
- parsing_env(&items, "OPTIONS_MULTI", ITEM_CHECK); |
210 |
- parsing_env(&items, "OPTIONS_SINGLE", ITEM_RADIO); |
211 |
- parsing_env(&items, "OPTIONS_RADIO", ITEM_RADIO); |
212 |
+ parse_env_all(&items, "ALL_OPTIONS", ITEM_CHECK); |
213 |
+ read_env_section(§ions, §ions_size, "OPTIONS_GROUP", ITEM_CHECK); |
214 |
+ read_env_section(§ions, §ions_size, "OPTIONS_MULTI", ITEM_CHECK); |
215 |
+ read_env_section(§ions, §ions_size, "OPTIONS_SINGLE", ITEM_RADIO); |
216 |
+ read_env_section(§ions, §ions_size, "OPTIONS_RADIO", ITEM_RADIO); |
217 |
+ |
218 |
+ order_sections(§ions, sections_size); |
219 |
+ |
220 |
+ add_sections(&items, sections, sections_size); |
221 |
|
222 |
return (items); |
223 |
} |