Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 674 lines (663 sloc) 20.106 kB
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
1 /*
2 quIRC - simple terminal-based IRC client
1bd8f39 Nudge copyright year (to "2010-12")
ec429 authored
3 Copyright (C) 2010-12 Edward Cree
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
4
5 See quirc.c for license information
6 genconfig.c: generate various bits of config-parsing code from a cdl file
7 */
8
9 // TODO: refactor this quite a lot, it's a mess
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdbool.h>
14 #include <string.h>
15 #include <unistd.h>
16
17 typedef struct
18 {
19 enum {INT, BOOL} type;
20 char *cname;
21 int value;
22 int min,max;
23 char *rc_name;
24 char *cmdline_name;
25 char *set_name;
26 char *set_msg;
27 enum {SET, LEVEL, BOOLEAN} set_type;
28 }
29 ent;
30
31 char * fgetl(FILE *); // gets a line of string data; returns a malloc-like pointer
32 void init_char(char **buf, int *l, int *i); // initialises a string buffer in heap. *buf becomes a malloc-like pointer
33 void append_char(char **buf, int *l, int *i, char c); // adds a character to a string buffer in heap (and realloc()s if needed)
34
35 int main(int argc, char **argv)
36 {
37 if(argc!=2)
38 {
39 fprintf(stderr, "usage: genconfig <outtype>\n");
40 return(EXIT_FAILURE);
41 }
42 int otype;
43 if(strcmp(argv[1], "config_globals.h")==0)
44 otype=0;
45 else if(strcmp(argv[1], "config_check.c")==0)
46 otype=1;
47 else if(strcmp(argv[1], "config_def.c")==0)
48 otype=2;
49 else if(strcmp(argv[1], "config_rcread.c")==0)
50 otype=3;
51 else if(strcmp(argv[1], "config_pargs.c")==0)
52 otype=4;
53 else if(strcmp(argv[1], "config_set.c")==0)
54 otype=5;
55 else if(strcmp(argv[1], "config_need.c")==0)
56 otype=6;
f5e7385 Generated options list for --help output
ec429 authored
57 else if(strcmp(argv[1], "config_help.c")==0)
58 otype=7;
76d7bce HTML Reference table for the genconfig stuff (/set, rc, cmdline options)
ec429 authored
59 else if(strcmp(argv[1], "config_ref.htm")==0)
60 otype=8;
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
61 else
62 {
63 fprintf(stderr, "genconfig: unrecognised outtype '%s'\n", argv[1]);
64 return(EXIT_FAILURE);
65 }
66 int nents=0;
67 ent *ents=NULL;
68 while(!feof(stdin))
69 {
70 char *line=fgetl(stdin);
71 if(!*line)
72 {
73 free(line);
74 continue;
75 }
76 int nent=nents++;
77 ents=realloc(ents, nents*sizeof(ent));
78 if(!ents)
79 {
80 perror("genconfig: realloc");
81 return(EXIT_FAILURE);
82 }
83 char *p=line;
84 int tocolon=strcspn(p, ":");
85 if(strncmp(p, "int", tocolon)==0)
86 ents[nent].type=INT;
87 else if(strncmp(p, "bool", tocolon)==0)
88 ents[nent].type=BOOL;
89 else
90 {
91 fprintf(stderr, "genconfig: unrecognised type %.*s\n", tocolon, p);
92 return(EXIT_FAILURE);
93 }
94 p+=tocolon;
95 if(!*p)
96 {
97 fprintf(stderr, "genconfig: premature end of line %u\n", nents);
98 return(EXIT_FAILURE);
99 }
100 p++;tocolon=strcspn(p, ":");
101 ents[nent].cname=malloc(tocolon+1);
102 if(!ents[nent].cname)
103 {
104 perror("genconfig: malloc");
105 return(EXIT_FAILURE);
106 }
107 strncpy(ents[nent].cname, p, tocolon);
108 ents[nent].cname[tocolon]=0;
109 p+=tocolon;
110 if(!*p)
111 {
112 fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
113 return(EXIT_FAILURE);
114 }
115 p++;tocolon=strcspn(p, ":");
116 if(tocolon)
117 {
118 char *value=malloc(tocolon+1);
119 if(!value)
120 {
121 perror("genconfig: malloc");
122 return(EXIT_FAILURE);
123 }
124 strncpy(value, p, tocolon);
125 value[tocolon]=0;
03bb3ce config: fix bug with boolean constants in .cdl file
ec429 authored
126 switch(ents[nent].type)
127 {
128 case INT:
129 if(!sscanf(value, "%d", &ents[nent].value)) ents[nent].value=-1;
130 break;
131 case BOOL:
132 if(strcmp(value, "true")==0)
133 ents[nent].value=1;
134 else if(strcmp(value, "false")==0)
135 ents[nent].value=0;
136 else if(!sscanf(value, "%d", &ents[nent].value))
137 ents[nent].value=1; // default to true
138 break;
139 }
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
140 free(value);
141 p+=tocolon;
142 }
143 else
144 {
145 ents[nent].value=-1;
146 }
147 if(!*p)
148 {
149 fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
150 return(EXIT_FAILURE);
151 }
152 p++;tocolon=strcspn(p, ":");
153 if(tocolon)
154 {
155 char *min=malloc(tocolon+1);
156 if(!min)
157 {
158 perror("genconfig: malloc");
159 return(EXIT_FAILURE);
160 }
161 strncpy(min, p, tocolon);
162 min[tocolon]=0;
163 if(!sscanf(min, "%d", &ents[nent].min)) ents[nent].min=-1;
164 free(min);
165 p+=tocolon;
166 }
167 else
168 {
169 ents[nent].min=-1;
170 }
171 if(!*p)
172 {
173 fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
174 return(EXIT_FAILURE);
175 }
176 p++;tocolon=strcspn(p, ":");
177 if(tocolon)
178 {
179 char *max=malloc(tocolon+1);
180 if(!max)
181 {
182 perror("genconfig: malloc");
183 return(EXIT_FAILURE);
184 }
185 strncpy(max, p, tocolon);
186 max[tocolon]=0;
187 if(!sscanf(max, "%d", &ents[nent].max)) ents[nent].max=-1;
188 free(max);
189 p+=tocolon;
190 }
191 else
192 {
193 ents[nent].max=-1;
194 }
195 if(!*p)
196 {
197 fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
198 return(EXIT_FAILURE);
199 }
200 p++;tocolon=strcspn(p, ":");
201 if(tocolon)
202 {
203 ents[nent].rc_name=malloc(tocolon+1);
204 if(!ents[nent].rc_name)
205 {
206 perror("genconfig: malloc");
207 return(EXIT_FAILURE);
208 }
209 strncpy(ents[nent].rc_name, p, tocolon);
210 ents[nent].rc_name[tocolon]=0;
211 p+=tocolon;
212 }
213 else
214 {
215 ents[nent].rc_name=NULL;
216 }
217 if(!*p)
218 {
219 fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
220 return(EXIT_FAILURE);
221 }
222 p++;tocolon=strcspn(p, ":");
223 if(tocolon)
224 {
225 ents[nent].cmdline_name=malloc(tocolon+1);
226 if(!ents[nent].cmdline_name)
227 {
228 perror("genconfig: malloc");
229 return(EXIT_FAILURE);
230 }
231 strncpy(ents[nent].cmdline_name, p, tocolon);
232 ents[nent].cmdline_name[tocolon]=0;
233 p+=tocolon;
234 }
235 else
236 {
237 ents[nent].cmdline_name=NULL;
238 }
239 if(!*p)
240 {
241 fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
242 return(EXIT_FAILURE);
243 }
244 p++;tocolon=strcspn(p, ":");
245 if(tocolon)
246 {
247 ents[nent].set_name=malloc(tocolon+1);
248 if(!ents[nent].set_name)
249 {
250 perror("genconfig: malloc");
251 return(EXIT_FAILURE);
252 }
253 strncpy(ents[nent].set_name, p, tocolon);
254 ents[nent].set_name[tocolon]=0;
255 p+=tocolon;
256 }
257 else
258 {
259 ents[nent].set_name=NULL;
260 }
261 if(!*p)
262 {
263 fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
264 return(EXIT_FAILURE);
265 }
266 p++;tocolon=strcspn(p, ":");
267 if(strncmp(p, "SET", tocolon)==0)
268 ents[nent].set_type=SET;
269 else if(strncmp(p, "LEVEL", tocolon)==0)
270 ents[nent].set_type=LEVEL;
271 else if(strncmp(p, "BOOLEAN", tocolon)==0)
272 ents[nent].set_type=BOOLEAN;
273 else
274 {
275 fprintf(stderr, "genconfig: unrecognised set_type %.*s in line %u (%s)\n", tocolon, p, nents, ents[nent].cname);
276 return(EXIT_FAILURE);
277 }
278 p+=tocolon;
279 if(!*p)
280 {
281 fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
282 return(EXIT_FAILURE);
283 }
284 p++;tocolon=strcspn(p, ":");
285 if(tocolon)
286 {
287 ents[nent].set_msg=malloc(tocolon+1);
288 if(!ents[nent].set_msg)
289 {
290 perror("genconfig: malloc");
291 return(EXIT_FAILURE);
292 }
293 strncpy(ents[nent].set_msg, p, tocolon);
294 ents[nent].set_msg[tocolon]=0;
295 }
296 else
297 {
298 ents[nent].set_msg=NULL;
299 }
300 free(line);
301 }
76d7bce HTML Reference table for the genconfig stuff (/set, rc, cmdline options)
ec429 authored
302 if(otype==8)
303 printf("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\
304 <html xmlns=\"http://www.w3.org/1999/xhtml\">\n\
305 <head>\n\
306 \t<title>quIRC: configuration reference</title>\n\
307 \t<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8;\" />\n\
308 \t<link rel=\"stylesheet\" href=\"readme.css\" />\n\t<style type=\"text/css\">\n\
309 \t\ttt {margin-left:4em;}\n\
310 \t\ttd {border:1px solid; border-color:#1f273f; padding:2px;}\n\
311 \t\t.int {background-color:#376f4f; color:black;}\n\
312 \t\t.bool {background-color:#374f6f; color:black;}\n\
313 \t\t.na {background-color:#2f2f37; color:#7f7f9f};\n\
314 \t</style>\n\
315 </head>\n\
316 <body>\n\
317 <div id=\"title\">\n\
318 <h1>quIRC: reference</h1>\n\
319 <h5>A reference table for quIRC's configuration options, and how to set them.<br>\n\
320 Generated by <small>genconfig</small></h5>\n\
321 </div><!--#title-->\n\
322 <div id=\"key\">\n\
323 <h2>Key to Columns</h2>\n\
324 <dl>\n\
325 <dt>name</dt>\n\
326 \t<dd>The internal name of the setting.</dd>\n\
327 <dt>type</dt>\n\
328 \t<dd>The setting's type, either <span class=\"int\">INT</span> (integer) or <span class=\"bool\">BOOL</span> (boolean).</dd>\n\
329 <dt>default</dt>\n\
330 \t<dd>The setting's default value.</dd>\n\
331 <dt>rc</dt>\n\
332 \t<dd>The setting's name in the rc file (typically ~/.quirc/rc), if settable there.</dd>\n\
333 <dt>cmdline</dt>\n\
334 \t<dd>The setting's name on the command line, if settable there.</dd>\n\
335 <dt>/set</dt>\n\
336 \t<dd>The name to use with the /set command. If the setting is an <span class=\"int\">INT</span>, use <small>/set &lt;name&gt; &lt;value&gt;</small>; omitting <small>&lt;value&gt;</small> sets to the default value. If the setting is a <span class=\"bool\">BOOL</span>, use <small>/set &lt;name&gt;</small> to enable, and <small>/set no-&lt;name&gt;</small> to disable (you can also use other forms, such as supplying a <small>&lt;value&gt;</small> of + or 1 to enable and - or 0 to disable).</dd>\n\
337 <dt>description</dt>\n\
338 \t<dd>A short description of the setting, as used in messages produced by /set.</dd>\n\
339 </dl>\n\
340 </div><!--#key-->\n\
341 <div id=\"table\">\n\
342 <table style=\"border:1px solid;\">\n\
343 <tr style=\"text-align:center\"><td>name</td><td>type</td><td>default</td><td>rc</td><td>cmdline</td><td>/set</td><td>description</td></tr>\n");
344 else
345 printf("/* Generated by genconfig */\n");
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
346 switch(otype)
347 {
348 case 1:
349 printf("int conf_check(void)\n{\n");
350 break;
351 }
352 int i;
353 bool first=true;
354 for(i=0;i<nents;i++)
355 {
356 switch(otype)
357 {
358 case 0:
359 switch(ents[i].type)
360 {
361 case INT:
362 printf("unsigned int ");
363 break;
364 case BOOL:
365 printf("bool ");
366 break;
367 default:
368 fprintf(stderr, "Unsupported type %d in %s\n", ents[i].type, ents[i].cname);
369 return(EXIT_FAILURE);
370 }
371 printf("%s; // %s\n", ents[i].cname, ents[i].set_msg);
372 break;
373 case 1:
374 switch(ents[i].type)
375 {
376 case INT:
377 if(ents[i].min>0)
378 {
e184c8b Ring-buffer for debug messages. Complicated (see full message).
ec429 authored
379 printf("\tif(%s<%d)\n\t{\n\t\tatr_failsafe(&s_buf, STA, \"%s set to minimum %d\", \"init: \");\n\t\t%s=%d;\n\t}\n", ents[i].cname, ents[i].min, ents[i].set_name, ents[i].min, ents[i].cname, ents[i].min);
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
380 }
381 if(ents[i].max!=-1)
382 {
e184c8b Ring-buffer for debug messages. Complicated (see full message).
ec429 authored
383 printf("\tif(%s>%d)\n\t{\n\t\tatr_failsafe(&s_buf, STA, \"%s set to maximum %d\", \"init: \");\n\t\t%s=%d;\n\t}\n", ents[i].cname, ents[i].max, ents[i].set_name, ents[i].max, ents[i].cname, ents[i].max);
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
384 }
385 break;
386 case BOOL:
387 break;
388 default:
389 fprintf(stderr, "Unsupported type %d in %s\n", ents[i].type, ents[i].cname);
390 return(EXIT_FAILURE);
391 }
392 break;
393 case 2:
394 printf("\t%s=%d;\n", ents[i].cname, ents[i].value);
395 break;
396 case 3:
397 if(ents[i].rc_name)
398 {
399 switch(ents[i].type)
400 {
401 case BOOL:
402 case INT:
0275d65 config: more permissive of the 'no-foo' form in rc file
ec429 authored
403 if((ents[i].set_type==BOOLEAN)||(ents[i].set_type==LEVEL))
404 {
405 printf("\t\t\telse if(strcmp(cmd, \"no-%s\")==0)\n", ents[i].rc_name);
406 printf("\t\t\t\t%s=false;\n", ents[i].cname);
407 }
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
408 printf("\t\t\telse if(strcmp(cmd, \"%s\")==0)\n", ents[i].rc_name);
409 printf("\t\t\t{\n");
410 printf("\t\t\t\tunsigned int value;\n");
411 printf("\t\t\t\tif(rest&&sscanf(rest, \"%%u\", &value))\n");
412 printf("\t\t\t\t\t%s=value;\n", ents[i].cname);
413 printf("\t\t\t\telse\n");
414 if(ents[i].type==BOOL)
415 printf("\t\t\t\t\t%s=true;\n", ents[i].cname);
416 else
417 {
418 printf("\t\t\t\t{\n");
e184c8b Ring-buffer for debug messages. Complicated (see full message).
ec429 authored
419 printf("\t\t\t\t\tatr_failsafe(&s_buf, ERR, \"Malformed rc entry for %s (value not numeric)\", \"init: \");\n", ents[i].rc_name);
420 printf("\t\t\t\t\tatr_failsafe(&s_buf, ERR, rest, \"init: \");\n");
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
421 printf("\t\t\t\t}\n");
422 }
423 printf("\t\t\t}\n");
424 break;
425 default:
426 fprintf(stderr, "Unsupported type %d in %s\n", ents[i].type, ents[i].cname);
427 return(EXIT_FAILURE);
428 }
429 }
430 break;
431 case 4:
432 if(ents[i].cmdline_name)
433 {
434 switch(ents[i].type)
435 {
436 case BOOL:
437 printf("\t\telse if(strcmp(argv[arg], \"--%s\")==0)\n", ents[i].cmdline_name);
438 printf("\t\t\t%s=true;\n", ents[i].cname);
439 printf("\t\telse if(strcmp(argv[arg], \"--no-%s\")==0)\n", ents[i].cmdline_name);
440 printf("\t\t\t%s=false;\n", ents[i].cname);
441 break;
442 case INT:
020eb42 Fix warnings on Fedora (size_t, %zu and friends)
ec429 authored
443 printf("\t\telse if(strncmp(argv[arg], \"--%s=\", %zu)==0)\n", ents[i].cmdline_name, strlen(ents[i].cmdline_name)+3);
444 printf("\t\t\tsscanf(argv[arg]+%zu, \"%%u\", &%s);\n", strlen(ents[i].cmdline_name)+3, ents[i].cname);
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
445 break;
446 }
447 }
448 break;
449 case 5:
450 if(ents[i].set_name)
451 {
452 printf("\t\t\t\t");
453 if(!first) printf("else ");
454 first=false;
42b7022 Better handling of boolean options (genconfig); added input clock (/s…
ec429 authored
455 printf("if(strcmp(opt, \"%s\")==0)\n", ents[i].set_name);
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
456 printf("\t\t\t\t{\n");
42b7022 Better handling of boolean options (genconfig); added input clock (/s…
ec429 authored
457 if(ents[i].set_type==BOOLEAN)
458 {
459 printf("\t\t\t\t\tif(val)\n");
460 printf("\t\t\t\t\t{\n");
461 printf("\t\t\t\t\t\tif(isdigit(*val))\n");
462 printf("\t\t\t\t\t\t{\n");
463 printf("\t\t\t\t\t\t\tunsigned int value;\n");
464 printf("\t\t\t\t\t\t\tsscanf(val, \"%%u\", &value);\n");
465 printf("\t\t\t\t\t\t\t%s=value;\n", ents[i].cname);
466 printf("\t\t\t\t\t\t}\n");
467 printf("\t\t\t\t\t\telse if(strcmp(val, \"+\")==0)\n");
468 printf("\t\t\t\t\t\t{\n");
469 printf("\t\t\t\t\t\t\t%s=true;\n", ents[i].cname);
470 printf("\t\t\t\t\t\t}\n");
471 printf("\t\t\t\t\t\telse if(strcmp(val, \"-\")==0)\n");
472 printf("\t\t\t\t\t\t{\n");
473 printf("\t\t\t\t\t\t\t%s=false;\n", ents[i].cname);
474 printf("\t\t\t\t\t\t}\n");
475 printf("\t\t\t\t\t\telse\n");
476 printf("\t\t\t\t\t\t{\n");
30c1746 Implemented priorities (so quiet mode & debug are retroactive)
ec429 authored
477 printf("\t\t\t\t\t\t\tadd_to_buffer(cbuf, ERR, NORMAL, 0, false, \"option '%s' is boolean, use only 0/1 or -/+ to set\", \"/set: \");\n", ents[i].set_name);
42b7022 Better handling of boolean options (genconfig); added input clock (/s…
ec429 authored
478 printf("\t\t\t\t\t\t}\n");
479 printf("\t\t\t\t\t}\n");
480 printf("\t\t\t\t\telse\n");
481 printf("\t\t\t\t\t\t%s=true;\n", ents[i].cname);
482 }
483 else
484 {
485 printf("\t\t\t\t\tif(val)\n");
486 printf("\t\t\t\t\t{\n");
487 printf("\t\t\t\t\t\tunsigned int value;\n");
488 printf("\t\t\t\t\t\tsscanf(val, \"%%u\", &value);\n");
489 printf("\t\t\t\t\t\t%s=value;\n", ents[i].cname);
490 printf("\t\t\t\t\t}\n");
491 printf("\t\t\t\t\telse\n");
492 printf("\t\t\t\t\t\t%s=%d;\n", ents[i].cname, ents[i].value);
5eea39e genconfig: fix bug with /set out-of-range values
ec429 authored
493 if(ents[i].min>0)
494 {
495 printf("\t\t\t\t\tif(%s<%d)\n", ents[i].cname, ents[i].min);
496 printf("\t\t\t\t\t\t%s=%d;\n", ents[i].cname, ents[i].min);
497 }
498 if(ents[i].max>=0)
499 {
500 printf("\t\t\t\t\tif(%s>%d)\n", ents[i].cname, ents[i].max);
501 printf("\t\t\t\t\t\t%s=%d;\n", ents[i].cname, ents[i].max);
502 }
42b7022 Better handling of boolean options (genconfig); added input clock (/s…
ec429 authored
503 }
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
504 switch(ents[i].set_type)
505 {
506 case BOOLEAN:
30c1746 Implemented priorities (so quiet mode & debug are retroactive)
ec429 authored
507 printf("\t\t\t\t\tif(%s)\n", ents[i].cname);
508 printf("\t\t\t\t\t\tadd_to_buffer(cbuf, STA, QUIET, 0, false, \"%s enabled\", \"/set: \");\n", ents[i].set_msg);
509 printf("\t\t\t\t\telse\n");
510 printf("\t\t\t\t\t\tadd_to_buffer(cbuf, STA, QUIET, 0, false, \"%s disabled\", \"/set: \");\n", ents[i].set_msg);
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
511 break;
512 case LEVEL:
30c1746 Implemented priorities (so quiet mode & debug are retroactive)
ec429 authored
513 printf("\t\t\t\t\tif(%s)\n", ents[i].cname);
514 printf("\t\t\t\t\t{\n");
515 printf("\t\t\t\t\t\tchar lmsg[%zu];\n", strlen(ents[i].set_msg)+32);
516 printf("\t\t\t\t\t\tsprintf(lmsg, \"%s level %%u enabled\", %s);\n", ents[i].set_msg, ents[i].cname);
517 printf("\t\t\t\t\t\tadd_to_buffer(cbuf, STA, QUIET, 0, false, lmsg, \"/set: \");\n");
518 printf("\t\t\t\t\t}\n");
519 printf("\t\t\t\t\telse\n");
520 printf("\t\t\t\t\t\tadd_to_buffer(cbuf, STA, QUIET, 0, false, \"%s disabled\", \"/set: \");\n", ents[i].set_msg);
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
521 break;
522 case SET:
30c1746 Implemented priorities (so quiet mode & debug are retroactive)
ec429 authored
523 printf("\t\t\t\t\tchar smsg[%zu];\n", strlen(ents[i].set_msg)+24);
524 printf("\t\t\t\t\tsprintf(smsg, \"%s set to %%u\", %s);\n", ents[i].set_msg, ents[i].cname);
525 printf("\t\t\t\t\tadd_to_buffer(cbuf, STA, QUIET, 0, false, smsg, \"/set: \");\n");
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
526 break;
527 }
3d938cf Timestamp display (/set ts <level>, /set utc)
ec429 authored
528 printf("\t\t\t\t\tint buf;\n");
529 printf("\t\t\t\t\tfor(buf=0;buf<nbufs;buf++)\n");
530 printf("\t\t\t\t\t\tbufs[buf].dirty=true;\n");
531 printf("\t\t\t\t\tredraw_buffer();\n");
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
532 printf("\t\t\t\t}\n");
533 if((ents[i].set_type==BOOLEAN)||(ents[i].set_type==LEVEL))
534 {
535 printf("\t\t\t\telse if(strcmp(opt, \"no-%s\")==0)\n", ents[i].set_name);
536 printf("\t\t\t\t{\n");
537 printf("\t\t\t\t\t%s=0;\n", ents[i].cname);
30c1746 Implemented priorities (so quiet mode & debug are retroactive)
ec429 authored
538 printf("\t\t\t\t\tadd_to_buffer(cbuf, STA, QUIET, 0, false, \"%s disabled\", \"/set: \");\n", ents[i].set_msg);
3d938cf Timestamp display (/set ts <level>, /set utc)
ec429 authored
539 printf("\t\t\t\t\tint buf;\n");
540 printf("\t\t\t\t\tfor(buf=0;buf<nbufs;buf++)\n");
541 printf("\t\t\t\t\t\tbufs[buf].dirty=true;\n");
542 printf("\t\t\t\t\tredraw_buffer();\n");
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
543 printf("\t\t\t\t}\n");
544 }
545 }
546 break;
547 case 6:
a98d517 genconfig: fix bug with "(null)" in config_need.c
ec429 authored
548 if(ents[i].rc_name)
549 {
550 printf("\t\t\tif(strcmp(cmd, \"%s\")==0) need=false;\n", ents[i].rc_name);
551 if((ents[i].set_type==BOOLEAN)||(ents[i].set_type==LEVEL))
552 printf("\t\t\tif(strcmp(cmd, \"no-%s\")==0) need=false;\n", ents[i].rc_name);
553 }
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
554 break;
f5e7385 Generated options list for --help output
ec429 authored
555 case 7:
556 if(ents[i].cmdline_name)
557 {
558 int j;
559 switch(ents[i].type)
560 {
561 case BOOL:
562 printf("\t\t\tfprintf(stderr, \"\\t--[no-]%s", ents[i].cmdline_name);
563 for(j=strlen(ents[i].cmdline_name);j<25;j++)
564 putchar(' ');
565 break;
566 case INT:
567 if((ents[i].min!=-1)&&(ents[i].max!=-1))
568 {
569 printf("\t\t\tfprintf(stderr, \"\\t--%s=<%d to %d>", ents[i].cmdline_name, ents[i].min, ents[i].max);
570 for(j=strlen(ents[i].cmdline_name);j<21;j++)
571 putchar(' ');
572 }
573 else
574 {
575 printf("\t\t\tfprintf(stderr, \"\\t--%s=<numeric>", ents[i].cmdline_name);
576 for(j=strlen(ents[i].cmdline_name);j<20;j++)
577 putchar(' ');
578 }
579 break;
580 }
76d7bce HTML Reference table for the genconfig stuff (/set, rc, cmdline options)
ec429 authored
581 printf(": %s\\n\");\n", ents[i].set_msg);
582 }
583 break;
584 case 8:
585 switch(ents[i].type)
586 {
587 case BOOL:
588 printf("<tr><td>%s</td><td><span class=\"bool\">BOOL</span></td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", ents[i].cname, ents[i].value?"true":"false", ents[i].rc_name?ents[i].rc_name:"<span class=\"na\">[N/A]</span>", ents[i].cmdline_name?ents[i].cmdline_name:"<span class=\"na\">[N/A]</span>", ents[i].set_name?ents[i].set_name:"<span class=\"na\">[N/A]</span>", ents[i].set_msg?ents[i].set_msg:"<span class=\"na\">[N/A]</span>");
589 break;
590 case INT:
591 printf("<tr><td>%s</td><td><span class=\"int\">INT</span></td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", ents[i].cname, ents[i].value, ents[i].rc_name?ents[i].rc_name:"<span class=\"na\">[N/A]</span>", ents[i].cmdline_name?ents[i].cmdline_name:"<span class=\"na\">[N/A]</span>", ents[i].set_name?ents[i].set_name:"<span class=\"na\">[N/A]</span>", ents[i].set_msg?ents[i].set_msg:"<span class=\"na\">[N/A]</span>");
592 break;
593 default:
594 printf("<tr><td>%s</td><td><em>(unknown type)</em></td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", ents[i].cname, ents[i].value, ents[i].rc_name?ents[i].rc_name:"<span class=\"na\">[N/A]</span>", ents[i].cmdline_name?ents[i].cmdline_name:"<span class=\"na\">[N/A]</span>", ents[i].set_name?ents[i].set_name:"<span class=\"na\">[N/A]</span>", ents[i].set_msg?ents[i].set_msg:"<span class=\"na\">[N/A]</span>");
595 break;
f5e7385 Generated options list for --help output
ec429 authored
596 }
597 break;
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
598 default:
599 fprintf(stderr, "genconfig: otype %d not implemented!\n", otype);
600 return(EXIT_FAILURE);
601 break;
602 }
603 }
604 switch(otype)
605 {
606 case 1:
607 printf("\treturn(0);\n}\n");
608 break;
76d7bce HTML Reference table for the genconfig stuff (/set, rc, cmdline options)
ec429 authored
609 case 8:
610 printf("</table>\n</div><!--#table-->\n</body>\n</html>\n");
611 break;
de4ae60 config: generate much of the config code from a concise descriptions …
ec429 authored
612 }
613
614 }
615
616 char * fgetl(FILE *fp)
617 {
618 char * lout;
619 int l,i;
620 init_char(&lout, &l, &i);
621 signed int c;
622 while(!feof(fp))
623 {
624 c=fgetc(fp);
625 if((c==EOF)||(c=='\n'))
626 break;
627 if(c!=0)
628 {
629 append_char(&lout, &l, &i, c);
630 }
631 }
632 return(lout);
633 }
634
635 void append_char(char **buf, int *l, int *i, char c)
636 {
637 if(!((c==0)||(c==EOF)))
638 {
639 if(*buf)
640 {
641 (*buf)[(*i)++]=c;
642 }
643 else
644 {
645 init_char(buf, l, i);
646 append_char(buf, l, i, c);
647 }
648 char *nbuf=*buf;
649 if((*i)>=(*l))
650 {
651 *l=*i*2;
652 nbuf=(char *)realloc(*buf, *l);
653 }
654 if(nbuf)
655 {
656 *buf=nbuf;
657 (*buf)[*i]=0;
658 }
659 else
660 {
661 free(*buf);
662 init_char(buf, l, i);
663 }
664 }
665 }
666
667 void init_char(char **buf, int *l, int *i)
668 {
669 *l=80;
670 *buf=(char *)malloc(*l);
671 (*buf)[0]=0;
672 *i=0;
673 }
Something went wrong with that request. Please try again.