/[gentoo-src]/ufed/ufed-curses-checklist.c
Gentoo

Contents of /ufed/ufed-curses-checklist.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations) (download) (as text)
Sun Nov 13 00:28:17 2005 UTC (8 years, 5 months ago) by truedfx
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +2 -2 lines
File MIME type: text/x-csrc
Fix use.defaults in CVS too (bug #111902)
Don't use A_NORMAL anymore

1 #include "ufed-curses.h"
2
3 #include <ctype.h>
4 #include <errno.h>
5 #include <limits.h>
6 #include <locale.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <strings.h>
10 #include <unistd.h>
11
12 #include "ufed-curses-help.h"
13
14 static char *getline(FILE *fp) {
15 size_t size;
16 char *result;
17
18 size = LINE_MAX;
19 result = malloc(size);
20 if(result==NULL)
21 exit(-1);
22 if(fgets(result, size, fp)==NULL)
23 return NULL;
24 {
25 char *p = strchr(result, '\n');
26 if(p!=NULL) {
27 *p++ = '\0';
28 p = realloc(result, p-result);
29 return p ? p : result;
30 }
31 }
32 for(;;) {
33 result = realloc(result, size+size/2);
34 if(result==NULL)
35 exit(-1);
36 if(fgets(result+size, size/2, fp)==NULL)
37 return NULL;
38 {
39 char *p = strchr(result+size, '\n');
40 if(p!=NULL) {
41 *p++ = '\0';
42 p = realloc(result, p-result);
43 return p ? p : result;
44 }
45 }
46 size += size/2;
47 }
48 }
49
50 static struct flag {
51 struct item item;
52 char *name;
53 char on;
54 char *state;
55 #if C99
56 char *descr[];
57 #else
58 __extension__ char *descr[0];
59 #endif
60 } *flags;
61 static int descriptionleft;
62
63 static void free_flags(void);
64 static void read_flags(void) {
65 FILE *input = fdopen(3, "r");
66 char *line;
67 int y=0;
68 if(input==NULL)
69 exit(-1);
70 atexit(&free_flags);
71 for(;;) {
72 struct {
73 int start, end;
74 } name, on, state;
75 int ndescr;
76 struct flag *flag;
77 line = getline(input);
78 if(line==NULL)
79 break;
80 if(sscanf(line, "%n%*s%n %n%*s%n %n(%*[ +-])%n %d",
81 &name.start, &name.end,
82 &on.start, &on.end,
83 &state.start, &state.end,
84 &ndescr)!=1)
85 exit(-1);
86 flag = malloc(sizeof *flag + ndescr * sizeof *flag->descr);
87 if(flag==NULL)
88 exit(-1);
89 flag->item.top = y;
90
91 line[name.end] = '\0';
92 if(name.end-name.start+12 > minwidth)
93 minwidth = name.end-name.start+12;
94 flag->name = &line[name.start];
95
96 line[on.end] = '\0';
97 if(!strcmp(&line[on.start], "on"))
98 flag->on = 'X';
99 else if(!strcmp(&line[on.start], "off"))
100 flag->on = ' ';
101 else
102 exit(-1);
103
104 line[state.end] = '\0';
105 if(state.end-state.start != 5)
106 exit(-1);
107 flag->state = &line[state.start];
108
109 flag->item.height = ndescr;
110 if(ndescr > minheight)
111 minheight = ndescr;
112 { int i; for(i=0; i<ndescr; i++) {
113 flag->descr[i] = getline(input);
114 } }
115
116 y += ndescr;
117
118 if(flags==NULL) {
119 flag->item.prev = (struct item *) flag;
120 flag->item.next = (struct item *) flag;
121 flags = flag;
122 } else {
123 flag->item.next = (struct item *) flags;
124 flag->item.prev = flags->item.prev;
125 flags->item.prev->next = (struct item *) flag;
126 flags->item.prev = (struct item *) flag;
127 }
128 }
129 fclose(input);
130 if(flags==NULL) {
131 fputs("No input!\n", stderr);
132 exit(-1);
133 }
134 }
135
136 static void free_flags(void) {
137 struct flag *flag = flags;
138 if(flag!=NULL) {
139 flag->item.prev->next = NULL;
140 do {
141 void *p = flag;
142 char **descr;
143 for(descr=&flag->descr[0]; descr!=&flag->descr[flag->item.height]; descr++)
144 free(*descr);
145 flag = (struct flag *) flag->item.next;
146 free(p);
147 } while(flag!=NULL);
148 flags = NULL;
149 }
150 }
151
152 static const struct key keys[] = {
153 #define key(x) x, sizeof(x)-1
154 { '?', key("Help (?)") },
155 { '\n', key("Save (Return/Enter)") },
156 { '\033', key("Cancel (Esc)") },
157 { '\0', key("") }
158 #undef key
159 };
160
161 static void drawflag(struct item *item, bool highlight) {
162 struct flag *flag = (struct flag *) item;
163 #if C99
164 char buf[wWidth(List)+1];
165 #else
166 char *buf = __builtin_alloca(wWidth(List)+1);
167 #endif
168 char **d;
169
170 int y = flag->item.top - topy;
171 if(!highlight)
172 wattrset(win(List), COLOR_PAIR(3));
173 else
174 wattrset(win(List), COLOR_PAIR(3) | A_BOLD | A_REVERSE);
175 if(y < 0) {
176 wmove(win(List), 0, 0);
177 d = &flag->descr[-y];
178 y = 0;
179 goto descriptiononly;
180 }
181 wmove(win(List), y, 0);
182 sprintf(buf, " [%c] %-*s %-5.5s ",
183 flag->on,
184 minwidth-12, flag->name,
185 flag->state);
186 d = &flag->descr[0];
187 if(d != &flag->descr[flag->item.height]) {
188 for(;;) {
189 sprintf(buf+minwidth, "%-*.*s",
190 wWidth(List)-minwidth, wWidth(List)-minwidth,
191 strlen(*d) > (size_t)descriptionleft
192 ? &(*d)[descriptionleft]
193 : "");
194 waddstr(win(List), buf);
195 d++;
196 y++;
197 descriptiononly:
198 if(d!=&flag->descr[flag->item.height] && y<wHeight(List)) {
199 char *p;
200 for(p=buf; p!=buf+minwidth; p++)
201 *p = ' ';
202 continue;
203 }
204 break;
205 }
206 } else {
207 memset(buf+minwidth, ' ', wWidth(List)-minwidth);
208 buf[wWidth(List)] = '\0';
209 waddstr(win(List), buf);
210 y++;
211 }
212 if(highlight)
213 wmove(win(List), flag->item.top - topy, 2);
214 wnoutrefresh(win(List));
215 }
216
217 static char *fayt;
218 static struct item **faytsave;
219
220 static int callback(struct item **currentitem, int key) {
221 if(*fayt!='\0' && key!=KEY_BACKSPACE && (key==' ' || key!=(unsigned char) key || !isprint(key))) {
222 *fayt = '\0';
223 wattrset(win(Input), COLOR_PAIR(3));
224 mvwhline(win(Input), 0, 0, ' ', wWidth(Input));
225 wrefresh(win(Input));
226 }
227 if(descriptionleft!=0 && key!=KEY_LEFT && key!=KEY_RIGHT) {
228 descriptionleft = 0;
229 drawflag(*currentitem, TRUE);
230 }
231 switch(key) {
232 default:
233 if(key==(unsigned char) key && isprint(key)) {
234 struct item *item = *currentitem;
235 int n = strlen(fayt);
236 if(strncasecmp(((struct flag *) item)->name, fayt, n)!=0)
237 n--;
238 fayt[n] = (char) key;
239 faytsave[n] = *currentitem;
240 n++;
241 fayt[n] = '\0';
242 if(strncasecmp(((struct flag *) item)->name, fayt, n)==0) {
243 wattrset(win(Input), COLOR_PAIR(3) | A_BOLD);
244 mvwaddstr(win(Input), 0, 0, fayt);
245 wrefresh(win(Input));
246 } else {
247 do item = item->next;
248 while(item!=*currentitem && strncasecmp(((struct flag *) item)->name, fayt, n)!=0);
249 if(item==*currentitem) {
250 wattrset(win(Input), COLOR_PAIR(4) | A_BOLD | A_REVERSE);
251 mvwaddstr(win(Input), 0, 0, fayt);
252 wmove(win(Input), 0, n-1);
253 wnoutrefresh(win(List));
254 wrefresh(win(Input));
255 } else {
256 drawflag(*currentitem, FALSE);
257 *currentitem = item;
258 scrollcurrent();
259 drawflag(*currentitem, TRUE);
260 wattrset(win(Input), COLOR_PAIR(3) | A_BOLD);
261 mvwaddstr(win(Input), 0, 0, fayt);
262 wnoutrefresh(win(List));
263 wrefresh(win(Input));
264 }
265 }
266 }
267 break;
268 case KEY_BACKSPACE: {
269 int n = strlen(fayt);
270 if(n==0)
271 break;
272 n--;
273 fayt[n] = '\0';
274 drawflag(*currentitem, FALSE);
275 *currentitem = faytsave[n];
276 scrollcurrent();
277 drawflag(*currentitem, TRUE);
278 wattrset(win(Input), COLOR_PAIR(3) | A_BOLD);
279 mvwaddstr(win(Input), 0, 0, fayt);
280 whline(win(Input), ' ', 2);
281 if(n==0) {
282 wmove(win(List), (*currentitem)->top-topy, 2);
283 wnoutrefresh(win(Input));
284 wrefresh(win(List));
285 } else {
286 wnoutrefresh(win(List));
287 wrefresh(win(Input));
288 }
289 break;
290 }
291 case '\n':
292 case KEY_ENTER:
293 if(yesno("Save and exit? (Y/N) "))
294 return 0;
295 break;
296 case '\033':
297 if(yesno("Cancel? (Y/N) "))
298 return 1;
299 break;
300 case ' ':
301 ((struct flag *) *currentitem)->on ^= ' '^'X';
302 wattrset(win(List), COLOR_PAIR(3) | A_BOLD | A_REVERSE);
303 mvwhline(win(List), (*currentitem)->top-topy, 2, ((struct flag *) *currentitem)->on, 1);
304 wrefresh(win(List));
305 break;
306 case KEY_LEFT:
307 if(descriptionleft>0)
308 descriptionleft--;
309 drawflag(*currentitem, TRUE);
310 wmove(win(List), (*currentitem)->top-topy, 2);
311 wrefresh(win(List));
312 break;
313 case KEY_RIGHT:
314 descriptionleft++;
315 drawflag(*currentitem, TRUE);
316 wmove(win(List), (*currentitem)->top-topy, 2);
317 wrefresh(win(List));
318 break;
319 #ifdef NCURSES_MOUSE_VERSION
320 case KEY_MOUSE:
321 ((struct flag *) *currentitem)->on ^= ' '^'X';
322 break;
323 #endif
324 case '?':
325 help();
326 break;
327 }
328 return -1;
329 }
330
331 int main(void) {
332 int result;
333
334 read_flags();
335 fayt = malloc((minwidth-12+2) * sizeof *fayt);
336 faytsave = malloc((minwidth-12+2) * sizeof *faytsave);
337 if(fayt==NULL || faytsave==NULL)
338 exit(-1);
339 fayt[0] = '\0';
340
341 initcurses();
342 result=maineventloop("Select desired USE flags from the list below:",
343 &callback, &drawflag, (struct item *) flags, keys);
344 cursesdone();
345
346 if(result==0) {
347 FILE *output = fdopen(4, "w");
348 struct flag *flag = flags;
349 do {
350 if(flag->on=='X')
351 fprintf(output, "%s\n", flag->name);
352 flag = (struct flag *) flag->item.next;
353 } while(flag!=flags);
354 fclose(output);
355 }
356
357 return result;
358 }

  ViewVC Help
Powered by ViewVC 1.1.20