Gentoo Archives: gentoo-commits

From: Sven Eden <sven.eden@×××.de>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/ufed:master commit in: /
Date: Fri, 01 Feb 2013 10:50:12
Message-Id: 1359656784.6deb584ee8b64b44b90d81bf58fb853cafebbf61.yamakuzure@gentoo
1 commit: 6deb584ee8b64b44b90d81bf58fb853cafebbf61
2 Author: Sven Eden <sven.eden <AT> gmx <DOT> de>
3 AuthorDate: Thu Jan 31 18:26:24 2013 +0000
4 Commit: Sven Eden <sven.eden <AT> gmx <DOT> de>
5 CommitDate: Thu Jan 31 18:26:24 2013 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/ufed.git;a=commit;h=6deb584e
7
8 Added support for the new data model to ufed-curses-checklist.c, which made the reading of the input and the generation of the flag list a lot easier and more convenient.
9
10 ---
11 ufed-curses-checklist.c | 722 ++++++++++++++++++++---------------------------
12 1 files changed, 305 insertions(+), 417 deletions(-)
13
14 diff --git a/ufed-curses-checklist.c b/ufed-curses-checklist.c
15 index 8c9b408..5950796 100644
16 --- a/ufed-curses-checklist.c
17 +++ b/ufed-curses-checklist.c
18 @@ -11,28 +11,16 @@
19
20 #include "ufed-curses-help.h"
21
22 -/* internal types */
23 -struct flag {
24 - struct item item;
25 - char *name;
26 - char on;
27 - char state[5];
28 - bool *isInstalled;
29 - char **pkgs;
30 - char **descr;
31 -};
32 -
33 -
34 /* internal members */
35 -static struct flag *flags;
36 -static int descriptionleft;
37 -static char *fayt;
38 -static struct item **faytsave;
39 -static size_t maxDescWidth = 0;
40 -static char *lineBuf = NULL;
41 +static int descriptionleft = 0;
42 +static char* fayt = NULL;
43 +static sFlag** faytsave = NULL;
44 +static size_t maxDescWidth = 0;
45 +static char* lineBuf = NULL;
46 +static sFlag* flags = NULL;
47
48 #define mkKey(x) x, sizeof(x)-1
49 -static const struct key keys[] = {
50 +static const sKey keys[] = {
51 { '?', mkKey("Help (?)") },
52 { '\n', mkKey("Save (Return/Enter)") },
53 { '\033', mkKey("Cancel (Esc)") },
54 @@ -52,20 +40,16 @@ static void free_flags(void);
55
56
57 /* external members */
58 -enum mask showMasked = show_unmasked; //!< Set whether to show masked, unmasked or both flags
59 -enum order pkgOrder = pkgs_left; //!< Set whether to display package lists left or right of the description
60 -enum scope showScope = show_all; //!< Set whether global, local or all flags are shown
61 -int lineCountGlobal;
62 -int lineCountGlobalInstalled;
63 -int lineCountLocal;
64 -int lineCountLocalInstalled;
65 -int lineCountMasked;
66 -int lineCountMaskedInstalled;
67 -int lineCountMasked;
68 +eMask e_mask = eMask_unmasked;
69 +eOrder e_order = eOrder_left;
70 +eScope e_scope = eScope_all;
71 +eState e_state = eState_all;
72 +sListStats listStats = { 0, 0, 0, 0, 0, 0 };
73 extern int bottomline, minwidth;
74
75 /* static functions */
76 -static char *getline(FILE *fp) {
77 +static char *getline(FILE *fp)
78 +{
79 static size_t size = LINE_MAX;
80
81 if (NULL == lineBuf) {
82 @@ -104,167 +88,80 @@ static char *getline(FILE *fp) {
83 return NULL; // never reached.
84 }
85
86 -static void read_flags(void) {
87 - FILE *input = fdopen(3, "r");
88 - int lineNum = 0;
89 - char *line = NULL;
90 +static void read_flags(void)
91 +{
92 + FILE* input = fdopen(3, "r");
93 + int lineNum = 0;
94 + char* line = NULL;
95 + int ndescr = 0;
96 + char endChar = 0;
97 + size_t fullWidth = 0;
98 + struct {
99 + int start, end;
100 + } name, desc, pkg, state;
101
102 if(input == NULL)
103 ERROR_EXIT(-1, "fdopen failed with error %d\n", errno);
104 atexit(&free_flags);
105
106 - // Initialize line count per type:
107 - lineCountGlobal = 0;
108 - lineCountGlobalInstalled = 0;
109 - lineCountLocal = 0;
110 - lineCountLocalInstalled = 0;
111 - lineCountMasked = 0;
112 - lineCountMaskedInstalled = 0;
113 - lineCountMasked = 0;
114 + for(line = getline(input); line ; line = getline(input)) {
115 + name.start = name.end = -1;
116 + state.start = state.end = -1;
117
118 - for(;;) {
119 - struct {
120 - int start, end;
121 - } name, on, state, pkgs, desc;
122 - int ndescr = 0;
123 - struct flag *flag = NULL;
124 - char descState = 0;
125 -
126 - line = getline(input);
127 - if(NULL == line)
128 - break;
129 - if(sscanf(line, "%n%*s%n %n%*s%n (%n%*[ +-]%n) %d",
130 + if (sscanf(line, "%n%*s%n [%n%*[ +-]%n] %d",
131 &name.start, &name.end,
132 - &on.start, &on.end,
133 &state.start, &state.end,
134 &ndescr) != 1)
135 - ERROR_EXIT(-1, "flag sscanf failed on line %d:\n\"%s\"\n", lineNum, line);
136 -
137 - /* Allocate memory for the struct and the arrays */
138 - // struct
139 - if (NULL == (flag = (struct flag*)malloc(sizeof(struct flag))))
140 - ERROR_EXIT(-1, "Can not allocate %lu bytes for flag\n", sizeof(struct flag));
141 - // isInstalled
142 - if (NULL == (flag->isInstalled = (bool*)calloc(ndescr, sizeof(bool))))
143 - ERROR_EXIT(-1, "Can not allocate %lu bytes for isInstalled array\n", ndescr * sizeof(bool));
144 - // name
145 - if (NULL == (flag->name = (char*)calloc(name.end - name.start + 1, sizeof(char))))
146 - ERROR_EXIT(-1, "Can not allocate %lu bytes for flag name\n",
147 - (name.end - name.start + 1) * sizeof(char));
148 - // pkgs
149 - if (NULL == (flag->pkgs = (char**)calloc(ndescr, sizeof(char*))))
150 - ERROR_EXIT(-1, "Can not allocate %lu bytes for pkg array\n", ndescr * sizeof(char*));
151 - // descr
152 - if (NULL == (flag->descr = (char**)calloc(ndescr, sizeof(char*))))
153 - ERROR_EXIT(-1, "Can not allocate %lu bytes for descr array\n", ndescr * sizeof(char*));
154 -
155 - /* note position and name of the flag */
156 - flag->item.listline = lineNum;
157 - flag->item.currline = 0;
158 + ERROR_EXIT(-1, "Flag read failed on line %d:\n\"%s\"\n", lineNum + 1, line);
159 +
160 + // Check stats
161 + if ((state.end - state.start) != 2)
162 + ERROR_EXIT(-1, "Illegal flag stats on line %d:\n\"%s\"\n", lineNum + 1, line);
163 +
164 + // Create a new flag
165 + line[name.end] = '\0';
166 + line[state.end] = '\0';
167 + sFlag* newFlag = addFlag(&flags, &line[name.start], lineNum, ndescr, &line[state.start]);
168
169 /* The minimum width of the left side display is:
170 - * Space + Selection + Space + name + Space + Mask brackets.
171 + * Space + Selection + Space + name + Space + Mask brackets/Force plus.
172 * = 1 + 3 + 1 + strlen(name) + 1 + 2
173 * = strlen(name) + 8
174 */
175 - if(name.end - name.start + 8 > minwidth)
176 + if( (name.end - name.start + 8) > minwidth)
177 minwidth = name.end - name.start + 8;
178 - strncpy(flag->name, &line[name.start], name.end - name.start);
179 -
180 - /* check and save current flag setting from configuration */
181 - line[on.end] = '\0';
182 - if(!strcmp(&line[on.start], "on"))
183 - flag->on = '+';
184 - else if(!strcmp(&line[on.start], "off"))
185 - flag->on = '-';
186 - else if(!strcmp(&line[on.start], "def"))
187 - flag->on = ' ';
188 - else
189 - ERROR_EXIT(-1, "flag->on can not be determined with \"%s\"\n", &line[on.start]);
190 -
191 - /* check and set flag state */
192 - if(state.end - state.start != 2)
193 - ERROR_EXIT(-1, "state length is %d (must be 2)\n", state.end - state.start);
194 - strncpy(flag->state, &line[state.start], 2);
195 -
196 - /* check and set flag item height */
197 - flag->item.ndescr = ndescr;
198
199 /* read description(s) and determine flag status */
200 - flag->item.isMasked = false;
201 - flag->item.isGlobal = false;
202 for (int i = 0; i < ndescr; ++i) {
203 - pkgs.start = pkgs.end = -1;
204 - desc.start = desc.end = -1;
205 + desc.start = desc.end = -1;
206 + pkg.start = pkg.end = -1;
207 + state.start = state.end = -1;
208
209 line = getline(input);
210 if (!line) break;
211
212 - /* There are two possible layouts:
213 - * a: "g [description]" for global flag descriptions and
214 - * b: "x (pkg(s)) [description]" for local flag descriptions
215 - * We therefore need two sscanf attempts. Use b first, as
216 - * it is more common.
217 - */
218 - if ((sscanf(line, "(%n%*[^)]%n) [%n%*[^]]%n] %c",
219 - &pkgs.start, &pkgs.end,
220 - &desc.start, &desc.end,
221 - &descState) !=1 )
222 - &&(sscanf(line, "[%n%*[^]]%n] %c",
223 + if ( (sscanf(line, "\t%n%*[^\t]%n\t (%n%*[^)]%n) [%n%*[ +-]%n%c",
224 &desc.start, &desc.end,
225 - &descState) !=1))
226 - ERROR_EXIT(-1, "desc sscanf failed on line\n\"%s\"\n", line);
227 -
228 - // Set general state of the flag
229 - flag->isInstalled[i] = false;
230 - if ('g' == descState) {
231 - flag->item.isGlobal = true;
232 - ++lineCountGlobal;
233 - }
234 - else if ('G' == descState) {
235 - flag->item.isGlobal = true;
236 - flag->isInstalled[i] = true;
237 - ++lineCountGlobalInstalled;
238 - }
239 - else if ('l' == descState) {
240 - ++lineCountLocal;
241 - }
242 - else if ('L' == descState) {
243 - flag->isInstalled[i] = true;
244 - ++lineCountLocalInstalled;
245 - }
246 - else if ('M' == descState) {
247 - flag->item.isMasked = true;
248 - flag->isInstalled[i] = true;
249 - ++lineCountMaskedInstalled;
250 - }
251 - else if ('m' == descState) {
252 - flag->item.isMasked = true;
253 - ++lineCountMasked;
254 - }
255 -
256 - // Save packages
257 - if (pkgs.start > -1) {
258 - int pkgLen = pkgs.end - pkgs.start;
259 - if (NULL == (flag->pkgs[i] = (char*)calloc(pkgLen + 1, sizeof(char))) )
260 - ERROR_EXIT(-1, "Unable to allocate %lu bytes for pkg list %d\n",
261 - sizeof(char) * (pkgLen + 1), i);
262 - strncpy(flag->pkgs[i], &line[pkgs.start], pkgLen);
263 - } else
264 - flag->pkgs[i] = NULL;
265 -
266 - // Save description
267 - if (desc.start > -1) {
268 - int descLen = desc.end - desc.start;
269 - if (NULL == (flag->descr[i] = (char*)calloc(descLen + 1, sizeof(char))) )
270 - ERROR_EXIT(-1, "Unable to allocate %lu bytes for description %d\n",
271 - sizeof(char) * (descLen + 1), i);
272 - strncpy(flag->descr[i], &line[desc.start], descLen);
273 + &pkg.start, &pkg.end,
274 + &state.start, &state.end,
275 + &endChar) != 1)
276 + || (']' != endChar) )
277 + ERROR_EXIT(-1, "Description read failed on line %d\n\"%s\"\n", lineNum + 1, line);
278 +
279 + // Check stats
280 + if ((state.end - state.start) != 5)
281 + ERROR_EXIT(-1, "Illegal description stats on line %d:\n\"%s\"\n", lineNum + 1, line);
282 +
283 + // Add description line to flag:
284 + line[desc.end] = '\0';
285 + line[state.end] = '\0';
286 + if ( (pkg.end - pkg.start) > 1) {
287 + line[pkg.end] = '\0';
288 + fullWidth = addFlagDesc(newFlag, &line[pkg.start], &line[desc.start], &line[state.start]);
289 } else
290 - ERROR_EXIT(-1, "Flag %s has no description at line %d\n", flag->name, i);
291 + fullWidth = addFlagDesc(newFlag, NULL, &line[desc.start], &line[state.start]);
292
293 // Note new max length if this line is longest:
294 - size_t fullWidth = 1 + strlen(flag->descr[i]) + (flag->pkgs[i] ? strlen(flag->pkgs[i]) + 3 : 0);
295 if (fullWidth > maxDescWidth)
296 maxDescWidth = fullWidth;
297
298 @@ -272,50 +169,30 @@ static void read_flags(void) {
299 ++lineNum;
300 } // loop through description lines
301
302 - /* Save flag in our linked list */
303 - if(flags==NULL) {
304 - flag->item.prev = (struct item *) flag;
305 - flag->item.next = (struct item *) flag;
306 - flags = flag;
307 - } else {
308 - flag->item.next = (struct item *) flags;
309 - flag->item.prev = flags->item.prev;
310 - flags->item.prev->next = (struct item *) flag;
311 - flags->item.prev = (struct item *) flag;
312 - }
313 + // Add line data to the list stats
314 + addLineStats(newFlag, &listStats);
315 } // loop while input given
316
317 fclose(input);
318
319 - if(flags==NULL) {
320 - fputs("No input!\n", stderr);
321 - exit(-1);
322 - }
323 + if(flags == NULL)
324 + ERROR_EXIT(-1, "Unable to start: %s\n", "No Input!");
325
326 // Save the last line, it is needed in several places
327 bottomline = lineNum;
328 }
329
330 -static void free_flags(void) {
331 - struct flag *flag = flags;
332 +static void free_flags(void)
333 +{
334 + sFlag* flag = flags->prev;
335
336 // Clear all flags
337 - if(flag != NULL) {
338 - flag->item.prev->next = NULL;
339 - do {
340 - void *p = flag;
341 - for (int i = 0; i < flag->item.ndescr; ++i) {
342 - if (flag->pkgs[i]) free(flag->pkgs[i]);
343 - if (flag->descr[i]) free(flag->descr[i]);
344 - }
345 - if (flag->name) free(flag->name);
346 - if (flag->isInstalled) free(flag->isInstalled);
347 - if (flag->pkgs) free(flag->pkgs);
348 - if (flag->descr) free(flag->descr);
349 - flag = (struct flag *) flag->item.next;
350 - free(p);
351 - } while(flag != NULL);
352 - flags = NULL;
353 + while (flags) {
354 + if (flag)
355 + destroyFlag(&flags, &flag);
356 + else
357 + destroyFlag(&flags, &flags);
358 + flag = flags ? flags->prev ? flags->prev : flags : NULL;
359 }
360
361 // Clear line buffer
362 @@ -324,16 +201,16 @@ static void free_flags(void) {
363 }
364
365
366 -static int drawflag(struct item *item, bool highlight) {
367 - struct flag *flag = (struct flag *) item;
368 +static int drawflag(sFlag* flag, bool highlight)
369 +{
370 char buf[wWidth(List)+1];
371 char desc[maxDescWidth];
372 int idx = 0;
373 int usedY = 0;
374 - int line = flag->item.currline;
375 + int line = flag->currline;
376
377 // Return early if there is nothing to display:
378 - if (!isLegalItem(&flag->item))
379 + if (!isFlagLegal(flag))
380 return 0;
381
382 /* Determine with which description to start.
383 @@ -342,7 +219,7 @@ static int drawflag(struct item *item, bool highlight) {
384 * themselves.
385 */
386 if (line < 0) {
387 - if (-line < getItemHeight(&flag->item)) {
388 + if (-line < getFlagHeight(flag)) {
389 idx = -line;
390 line = 0;
391 usedY = idx;
392 @@ -353,53 +230,65 @@ static int drawflag(struct item *item, bool highlight) {
393
394 memset(buf, 0, sizeof(char) * (wWidth(List)+1));
395
396 - /* print the selection, name and state of the flag */
397 - sprintf(buf, " %c%c%c %s%s%s%-*s ",
398 - /* State of selection */
399 - flag->on == ' ' ? '(' : '[',
400 - flag->on == ' '
401 - ? flag->on == ' '
402 - ? flag->state[0] : ' '
403 - : flag->on,
404 - flag->on == ' ' ? ')' : ']',
405 - /* name */
406 - flag->item.isMasked ? "(" : "", flag->name, flag->item.isMasked ? ")" : "",
407 - /* distance */
408 - (int)(minwidth - (flag->item.isMasked ? 4 : 6) - strlen(flag->name)), " ");
409 - // At this point buf is filled up to minwidth
410 -
411 - /* print descriptions according to filters
412 - * TODO: Implement installed/all filters
413 - */
414 - if(idx < flag->item.ndescr) {
415 - for(;;) {
416 - // Filter global description if it is not wanted:
417 - if (!idx && (show_local == showScope) && flag->item.isGlobal) {
418 - ++idx;
419 + // print descriptions according to filters
420 + if(idx < flag->ndesc) {
421 + int lHeight = wHeight(List);
422 + for( ; (idx < flag->ndesc) && (line < lHeight); ++idx) {
423 + // Continue if any of the filters apply:
424 + if (!isDescLegal(flag, idx))
425 continue;
426 - }
427
428 - // Break on local descriptions if they are not wanted:
429 - if (idx && (show_global == showScope))
430 - break;
431 -
432 - // Display flag state
433 - bool isGlobalDesc = flag->item.isGlobal && !flag->pkgs[idx] ? true : false;
434 - sprintf(buf + minwidth, " %s %c%c ",
435 - flag->state,
436 - isGlobalDesc ? ' ' : flag->item.isMasked ? 'M' : 'L',
437 - flag->isInstalled[idx] ? '*' : ' ');
438 + if (!buf[0]) {
439 + /* print the selection, name and state of the flag */
440 + char prefix[2] = { 0, 0 };
441 + char postfix[2] = { 0, 0 };
442 + int postlen = 5;
443 + if (isDescForced(flag, idx)) {
444 + prefix[0] = '+';
445 + postfix[0] = '+';
446 + postlen = 3;
447 + } else if (isDescMasked(flag, idx)) {
448 + prefix[0] = '(';
449 + postfix[0] = ')';
450 + postlen = 3;
451 + }
452 + sprintf(buf, " %c%c%c %s%s%s%-*s ",
453 + /* State of selection */
454 + flag->stateConf == ' ' ? '(' : '[',
455 + flag->stateConf,
456 + flag->stateConf == ' ' ? ')' : ']',
457 + /* name */
458 + prefix, flag->name, postfix,
459 + /* distance */
460 + (int)(minwidth - postlen - strlen(flag->name)), " ");
461 + // At this point buf is filled up to minwidth
462 + } // End of generating left side mask display
463 +
464 + /* Display flag state
465 + * The order in which the states are to be displayed is:
466 + * 1. make.defaults
467 + * 2. package.use
468 + * 3. make.conf
469 + * 4. global/local
470 + * 5. installed/not installed
471 + */
472 + sprintf(buf + minwidth, " %c%c%c %c%c ",
473 + flag->stateDefault,
474 + flag->desc[idx].statePackage,
475 + flag->stateConf,
476 + flag->desc[idx].isGlobal ? ' ' : 'L',
477 + flag->desc[idx].isInstalled ? 'i' : ' ');
478
479 // Assemble description line:
480 memset(desc, 0, maxDescWidth * sizeof(char));
481 - if (flag->pkgs[idx]) {
482 - if (pkgs_left == pkgOrder)
483 - sprintf(desc, "(%s) %s", flag->pkgs[idx], flag->descr[idx]);
484 + if (flag->desc[idx].pkg) {
485 + if (e_order == eOrder_left)
486 + sprintf(desc, "(%s) %s", flag->desc[idx].pkg, flag->desc[idx].desc);
487 else
488 - sprintf(desc, "%s (%s)", flag->descr[idx], flag->pkgs[idx]);
489 + sprintf(desc, "%s (%s)", flag->desc[idx].desc, flag->desc[idx].pkg);
490 }
491 else
492 - sprintf(desc, "%s", flag->descr[idx]);
493 + sprintf(desc, "%s", flag->desc[idx].desc);
494
495 // Now display the description line according to its horizontal position
496 sprintf(buf + minwidth + 8, "%-*.*s",
497 @@ -418,224 +307,223 @@ static int drawflag(struct item *item, bool highlight) {
498 // Finally put the line on the screen
499 mvwaddstr(win(List), line, 0, buf);
500 mvwaddch(win(List), line, minwidth, ACS_VLINE); // Before state
501 - mvwaddch(win(List), line, minwidth + 3, ACS_VLINE); // Between state and scope
502 - mvwaddch(win(List), line, minwidth + 6, ACS_VLINE); // After scope
503 + mvwaddch(win(List), line, minwidth + 4, ACS_VLINE); // Between state and scope
504 + mvwaddch(win(List), line, minwidth + 7, ACS_VLINE); // After scope
505 ++line;
506 - ++idx;
507 ++usedY;
508 - if((idx < flag->item.ndescr) && (line < wHeight(List)) ) {
509 + if(((idx + 1) < flag->ndesc) && (line < lHeight) ) {
510 char *p;
511 for(p = buf; p != buf + minwidth; p++)
512 *p = ' ';
513 - continue;
514 }
515 - break;
516 }
517 } else {
518 memset(buf+minwidth, ' ', wWidth(List)-minwidth);
519 buf[wWidth(List)] = '\0';
520 waddstr(win(List), buf);
521 }
522 +
523 if(highlight)
524 - wmove(win(List), max(flag->item.currline, 0), 2);
525 + wmove(win(List), max(flag->currline, 0), 2);
526 wnoutrefresh(win(List));
527 +
528 return usedY;
529 }
530
531 -static int callback(struct item **currentitem, int key) {
532 - if(*fayt!='\0' && key!=KEY_BACKSPACE && (key==' ' || key!=(unsigned char) key || !isprint(key))) {
533 - *fayt = '\0';
534 - wattrset(win(Input), COLOR_PAIR(3));
535 - mvwhline(win(Input), 0, 0, ' ', wWidth(Input));
536 - mvwaddch(win(Input), 0, minwidth, ACS_VLINE); // Before state
537 - mvwaddch(win(Input), 0, minwidth + 3, ACS_VLINE); // Between state and scope
538 - mvwaddch(win(Input), 0, minwidth + 6, ACS_VLINE); // After scope
539 - wmove(win(Input), 0, 0);
540 - wrefresh(win(Input));
541 +static int callback(sFlag** curr, int key)
542 +{
543 + WINDOW* wInp = win(Input);
544 + WINDOW* wLst = win(List);
545 + size_t fLen = 0;
546 + if ( fayt[0]
547 + && (key != KEY_BACKSPACE)
548 + && (key != KEY_DC)
549 + && (key != 0177)
550 + && ( (key == ' ') || (key != (unsigned char)key) || !isprint(key)) ) {
551 + fayt[0] = '\0';
552 + drawStatus(true);
553 + wrefresh(wInp);
554 }
555 - if(descriptionleft!=0 && key!=KEY_LEFT && key!=KEY_RIGHT) {
556 +
557 + // Reset possible side scrolling of the current flags description first
558 + if(descriptionleft && (key != KEY_LEFT) && (key != KEY_RIGHT) ) {
559 descriptionleft = 0;
560 - drawflag(*currentitem, TRUE);
561 + drawflag(*curr, TRUE);
562 }
563 +
564 switch(key) {
565 - default:
566 - if(key==(unsigned char) key && isprint(key)) {
567 - struct item *item = *currentitem;
568 - int n = strlen(fayt);
569 - if(strncasecmp(((struct flag *) item)->name, fayt, n)!=0)
570 - n--;
571 - fayt[n] = (char) key;
572 - faytsave[n] = *currentitem;
573 - n++;
574 - fayt[n] = '\0';
575 -
576 - /* if the current flag already matches the input string,
577 - * then update the input area only.
578 - */
579 - if(strncasecmp(((struct flag *) item)->name, fayt, n)==0) {
580 - wattrset(win(Input), COLOR_PAIR(3) | A_BOLD);
581 - mvwaddstr(win(Input), 0, 0, fayt);
582 - wrefresh(win(Input));
583 - }
584 - /* if the current flag does not match, search one that does. */
585 - else {
586 - do item = item->next;
587 - while( (item != *currentitem)
588 - && ( ( strncasecmp(((struct flag *) item)->name, fayt, n)
589 - || !isLegalItem(item)) ) );
590 -
591 - /* if there was no match (or the match is filtered),
592 - * update the input area to show that there is no match
593 - */
594 - if (item == *currentitem) {
595 - if (item != *currentitem)
596 - item = *currentitem;
597 - wattrset(win(Input), COLOR_PAIR(4) | A_BOLD | A_REVERSE);
598 - mvwaddstr(win(Input), 0, 0, fayt);
599 - wmove(win(Input), 0, n-1);
600 - wnoutrefresh(win(List));
601 - wrefresh(win(Input));
602 - } else {
603 - drawflag(*currentitem, FALSE);
604 - *currentitem = item;
605 - scrollcurrent();
606 - drawflag(*currentitem, TRUE);
607 - wattrset(win(Input), COLOR_PAIR(3) | A_BOLD);
608 - mvwaddstr(win(Input), 0, 0, fayt);
609 - wnoutrefresh(win(List));
610 - wrefresh(win(Input));
611 - }
612 - }
613 - }
614 - break;
615 - case KEY_BACKSPACE: {
616 - int n = strlen(fayt);
617 - if(n==0)
618 + case KEY_DC:
619 + case 0177:
620 + case KEY_BACKSPACE:
621 + fLen = strlen(fayt);
622 + if(0 == fLen)
623 break;
624 - n--;
625 - fayt[n] = '\0';
626 - drawflag(*currentitem, FALSE);
627 - *currentitem = faytsave[n];
628 + fayt[--fLen] = '\0';
629 + drawflag(*curr, FALSE);
630 + *curr = faytsave[fLen];
631 scrollcurrent();
632 - drawflag(*currentitem, TRUE);
633 - wattrset(win(Input), COLOR_PAIR(3) | A_BOLD);
634 - mvwaddstr(win(Input), 0, 0, fayt);
635 - whline(win(Input), ' ', 2);
636 - if(n==0) {
637 - wmove(win(List), (*currentitem)->currline, 2);
638 - wnoutrefresh(win(Input));
639 - wrefresh(win(List));
640 + drawflag(*curr, TRUE);
641 + wattrset(wInp, COLOR_PAIR(5) | A_BOLD);
642 + mvwaddstr(wInp, 0, 0, fayt);
643 + whline(wInp, ' ', 2);
644 + if(fLen == 0)
645 + wmove(wLst, (*curr)->currline, 2);
646 + wnoutrefresh(wLst);
647 + wrefresh(wInp);
648 + break;
649 + case '\n':
650 + case KEY_ENTER:
651 + if(yesno("Save and exit? (Y/N) "))
652 + return 0;
653 + break;
654 + case '\033':
655 + if(yesno("Cancel? (Y/N) "))
656 + return 1;
657 + break;
658 + case ' ':
659 + // Masked flags can be turned off, nothing else
660 + if ( (*curr)->globalMasked ) {
661 + if (' ' != (*curr)->stateConf)
662 + (*curr)->stateConf = ' ';
663 } else {
664 - wnoutrefresh(win(List));
665 - wrefresh(win(Input));
666 + switch ((*curr)->stateConf) {
667 + case '+':
668 + (*curr)->stateConf = '-';
669 + break;
670 + case '-':
671 + (*curr)->stateConf = ' ';
672 + break;
673 + default:
674 + (*curr)->stateConf = '+';
675 + break;
676 + }
677 }
678 + if (*curr != flags) {
679 + drawflag(*curr, TRUE);
680 + wmove(wLst, (*curr)->currline, 2);
681 + wrefresh(wLst);
682 + } else
683 + drawFlags();
684 + break;
685 + case KEY_LEFT:
686 + if(descriptionleft>0)
687 + descriptionleft--;
688 + drawflag(*curr, TRUE);
689 + wmove(wLst, (*curr)->currline, 2);
690 + wrefresh(wLst);
691 + break;
692 + case KEY_RIGHT:
693 + descriptionleft++;
694 + drawflag(*curr, TRUE);
695 + wmove(wLst, (*curr)->currline, 2);
696 + wrefresh(wLst);
697 break;
698 - }
699 - case '\n':
700 - case KEY_ENTER:
701 - if(yesno("Save and exit? (Y/N) "))
702 - return 0;
703 - break;
704 - case '\033':
705 - if(yesno("Cancel? (Y/N) "))
706 - return 1;
707 - break;
708 - case ' ': {
709 - // Masked flags can be turned off, nothing else
710 - if ( (*currentitem)->isMasked
711 - && (' ' != ((struct flag *) *currentitem)->on) )
712 - ((struct flag *) *currentitem)->on = ' ';
713 - else {
714 - switch (((struct flag *) *currentitem)->on) {
715 - case '+':
716 - ((struct flag *) *currentitem)->on = '-';
717 - break;
718 - case '-':
719 - ((struct flag *) *currentitem)->on = ' ';
720 - break;
721 - default:
722 - ((struct flag *) *currentitem)->on = '+';
723 - break;
724 - }
725 - }
726 - if (*currentitem != &flags->item) {
727 - drawflag(*currentitem, TRUE);
728 - wmove(win(List), (*currentitem)->currline, 2);
729 - wrefresh(win(List));
730 - } else {
731 - drawitems();
732 - }
733 - break;
734 - }
735 - case KEY_LEFT:
736 - if(descriptionleft>0)
737 - descriptionleft--;
738 - drawflag(*currentitem, TRUE);
739 - wmove(win(List), (*currentitem)->currline, 2);
740 - wrefresh(win(List));
741 - break;
742 - case KEY_RIGHT:
743 - descriptionleft++;
744 - drawflag(*currentitem, TRUE);
745 - wmove(win(List), (*currentitem)->currline, 2);
746 - wrefresh(win(List));
747 - break;
748 #ifdef NCURSES_MOUSE_VERSION
749 - case KEY_MOUSE:
750 - // Masked flags can be turned off, nothing else
751 - if ( (*currentitem)->isMasked
752 - && (' ' != ((struct flag *) *currentitem)->on) )
753 - ((struct flag *) *currentitem)->on = ' ';
754 - else {
755 - switch (((struct flag *) *currentitem)->on) {
756 - case '+':
757 - ((struct flag *) *currentitem)->on = '-';
758 - break;
759 - case '-':
760 - ((struct flag *) *currentitem)->on = ' ';
761 - break;
762 - default:
763 - ((struct flag *) *currentitem)->on = '+';
764 - break;
765 + case KEY_MOUSE:
766 + // Masked flags can be turned off, nothing else
767 + if ( (*curr)->globalMasked ) {
768 + if (' ' != (*curr)->stateConf)
769 + (*curr)->stateConf = ' ';
770 + } else {
771 + switch ((*curr)->stateConf) {
772 + case '+':
773 + (*curr)->stateConf = '-';
774 + break;
775 + case '-':
776 + (*curr)->stateConf = ' ';
777 + break;
778 + default:
779 + (*curr)->stateConf = '+';
780 + break;
781 + }
782 }
783 - }
784 - if (*currentitem != &flags->item) {
785 - drawflag(*currentitem, TRUE);
786 - wmove(win(List), (*currentitem)->currline, 2);
787 - wrefresh(win(List));
788 - } else {
789 - drawitems();
790 - }
791 - break;
792 + if (*curr != flags) {
793 + drawflag(*curr, TRUE);
794 + wmove(wLst, (*curr)->currline, 2);
795 + wrefresh(wLst);
796 + } else {
797 + drawFlags();
798 + }
799 + break;
800 #endif
801 - case '?':
802 - help();
803 - break;
804 + case '?':
805 + help();
806 + break;
807 + default:
808 + if( (key == (unsigned char) key) && isprint(key)) {
809 + sFlag* flag = *curr;
810 + fLen = strlen(fayt);
811 + if(fLen && strncasecmp(flag->name, fayt, fLen))
812 + --fLen;
813 + fayt[fLen] = (char) key;
814 + faytsave[fLen] = *curr;
815 + fayt[++fLen] = '\0';
816 +
817 + /* if the current flag already matches the input string,
818 + * then update the input area only.
819 + */
820 + if(!strncasecmp(flag->name, fayt, fLen)) {
821 + wattrset(wInp, COLOR_PAIR(5) | A_BOLD);
822 + mvwaddstr(wInp, 0, 0, fayt);
823 + wrefresh(wInp);
824 + }
825 + /* if the current flag does not match, search one that does. */
826 + else {
827 + do flag = flag->next;
828 + while( (flag != *curr)
829 + && ( ( strncasecmp(flag->name, fayt, fLen)
830 + || !isFlagLegal(flag)) ) );
831 +
832 + /* if there was no match (or the match is filtered),
833 + * update the input area to show that there is no match
834 + */
835 + if (flag == *curr) {
836 + wattrset(wInp, COLOR_PAIR(4) | A_BOLD | A_REVERSE);
837 + mvwaddstr(wInp, 0, 0, fayt);
838 + wmove(wInp, 0, fLen - 1);
839 + wnoutrefresh(wLst);
840 + wrefresh(wInp);
841 + } else {
842 + drawflag(*curr, FALSE);
843 + *curr = flag;
844 + scrollcurrent();
845 + drawflag(*curr, TRUE);
846 + wattrset(wInp, COLOR_PAIR(5) | A_BOLD);
847 + mvwaddstr(wInp, 0, 0, fayt);
848 + wnoutrefresh(wLst);
849 + wrefresh(wInp);
850 + }
851 + }
852 + }
853 + break;
854 }
855 return -1;
856 }
857
858 -int main(void) {
859 +int main(void)
860 +{
861 int result;
862
863 read_flags();
864 - fayt = malloc((minwidth-11+2) * sizeof *fayt);
865 - faytsave = malloc((minwidth-11+2) * sizeof *faytsave);
866 + fayt = (char*) calloc(minwidth, sizeof(*fayt));
867 + faytsave = (sFlag**)calloc(minwidth, sizeof(*faytsave));
868 if(fayt==NULL || faytsave==NULL)
869 - exit(-1);
870 + ERROR_EXIT(-1, "Unable to allocate %lu bytes for search buffer.\n",
871 + (minwidth * sizeof(*fayt)) + (minwidth * sizeof(*faytsave)));
872 fayt[0] = '\0';
873
874 initcurses();
875
876 - result=maineventloop("Select desired USE flags from the list below:",
877 - &callback, &drawflag, (struct item *) flags, keys);
878 + result = maineventloop("Select desired USE flags from the list below:",
879 + &callback, &drawflag, flags, keys, true);
880 +
881 cursesdone();
882
883 - if(result==0) {
884 + if(0 == result) {
885 FILE *output = fdopen(4, "w");
886 - struct flag *flag = flags;
887 + sFlag *flag = flags;
888 do {
889 - switch(flag->on)
890 + switch(flag->stateConf)
891 {
892 case '+':
893 fprintf(output, "%s\n", flag->name);
894 @@ -644,8 +532,8 @@ int main(void) {
895 fprintf(output, "-%s\n", flag->name);
896 break;
897 }
898 - flag = (struct flag *) flag->item.next;
899 - } while(flag!=flags);
900 + flag = flag->next;
901 + } while(flag != flags);
902 fclose(output);
903 }