"Fossies" - the Fresh Open Source Software Archive 
Member "tin-2.6.2/src/makecfg.c" (9 Dec 2022, 11250 Bytes) of package /linux/misc/tin-2.6.2.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "makecfg.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.6.1_vs_2.6.2.
1 /*
2 * Project : tin - a Usenet reader
3 * Module : makecfg.c
4 * Author : Thomas E. Dickey
5 * Created : 1997-08-23
6 * Updated : 2022-04-09
7 * Notes : #defines and structs for options_menu.c
8 *
9 * Copyright (c) 1997-2023 Thomas E. Dickey <dickey@invisible-island.net>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * 3. Neither the name of the copyright holder nor the names of its
24 * contributors may be used to endorse or promote products derived from
25 * this software without specific prior written permission.
26 *
27 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40
41 #define __BUILD__
42 #define PROTO_H 1 /* don't include proto.h */
43 #ifndef TIN_H
44 # include "tin.h"
45 #endif /* !TIN_H */
46
47 #define L_CURL '{'
48 #define R_CURL '}'
49
50 #define MAXNAME 36 /* maximum name-length (just for readability formatting) */
51 #define MAXTYPE 5 /* limits opt_type to keep names unique within 31 chars */
52
53 #define MYDATA struct mydata
54 MYDATA {
55 MYDATA *link;
56 char *name;
57 char *type;
58 };
59
60 static MYDATA *all_data;
61 static int line_no;
62
63 _Noreturn static void
64 failed(
65 const char *message)
66 {
67 perror(message);
68 exit(EXIT_FAILURE);
69 }
70
71 static FILE *
72 open_it(
73 const char *filename,
74 const char *mode)
75 {
76 FILE *fp = fopen(filename, mode);
77
78 if (fp == NULL)
79 failed(filename);
80 return fp;
81 }
82
83 static char *
84 string_dup(
85 const char *string)
86 {
87 char *buf;
88
89 if ((buf = malloc(strlen(string) + 1)) == NULL)
90 failed("malloc() failed");
91
92 return strcpy(buf, string);
93 }
94
95 static void
96 store_data(
97 const char *name,
98 const char *type)
99 {
100 MYDATA *p, *q;
101
102 if ((p = (MYDATA *) malloc(sizeof(MYDATA))) == NULL)
103 failed("malloc() failed");
104
105 p->link = NULL;
106 p->name = string_dup(name);
107 p->type = string_dup(type);
108
109 if ((q = all_data) == NULL)
110 all_data = p;
111 else {
112 while (q->link != NULL)
113 q = q->link;
114 q->link = p;
115 }
116 }
117
118 static void
119 parse_tbl(
120 char *buffer)
121 {
122 char *s = buffer;
123 char *t = s + strlen(s);
124
125 /* strip leading/trailing blanks */
126 do {
127 t--;
128 if (isspace ((int)*t))
129 *t = '\0';
130 else
131 break;
132 } while (t > s);
133 while (isspace ((int)*s))
134 s++;
135 buffer = s;
136
137 line_no++;
138 if (*buffer != ';' && *buffer != '\0') { /* ignore comments */
139 if (*buffer == '#') {
140 store_data(buffer, "");
141 } else {
142 /*
143 * otherwise the data consists of 2 blank
144 * separated columns (name, type).
145 */
146 while (*s && !isspace ((int)*s))
147 s++;
148 while (isspace ((int)*s))
149 *s++ = '\0';
150 store_data(buffer, s);
151 }
152 }
153 }
154
155 static void
156 write_it(
157 FILE *ofp,
158 const char * const *table)
159 {
160 int n;
161
162 for (n = 0; table[n] != NULL; n++)
163 fprintf(ofp, "%s\n", table[n]);
164 }
165
166 static int
167 index_of(
168 MYDATA *p)
169 {
170 int result = 0;
171 MYDATA *q;
172
173 for (q = all_data; q != NULL && q != p; q = q->link) {
174 if (!strcmp(p->type, q->type))
175 result++;
176 }
177 return result;
178 }
179
180 static int
181 is_title(
182 MYDATA *p)
183 {
184 return !strcmp(p->type, "OPT_TITLE");
185 }
186
187 static int
188 type_is_int(
189 MYDATA *p)
190 {
191 return strcmp(p->type, "OPT_TITLE")
192 && strcmp(p->type, "OPT_STRING")
193 && strcmp(p->type, "OPT_CHAR")
194 && strcmp(p->type, "OPT_ON_OFF");
195 }
196
197 static const char *
198 typename_of(
199 MYDATA *p)
200 {
201 if (!strcmp(p->type, "OPT_STRING"))
202 return "char *";
203 if (!strcmp(p->type, "OPT_CHAR"))
204 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
205 return "wchar_t *";
206 #else
207 return "char *";
208 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
209 if (!strcmp(p->type, "OPT_ON_OFF"))
210 return "t_bool *";
211 return "int *";
212 }
213
214 static void
215 generate_tbl(
216 FILE *ofp)
217 {
218 static const char *const table_1[] =
219 {
220 ""
221 ,"#define OPT_TITLE 0"
222 ,"#define OPT_ON_OFF 1"
223 ,"#define OPT_LIST 2"
224 ,"#define OPT_STRING 3"
225 ,"#define OPT_NUM 4"
226 ,"#define OPT_CHAR 5"
227 ,""
228 ,"struct t_option option_table[]={"
229 ,0
230 };
231 static const char *const table_2[] =
232 {
233 "};"
234 ,0
235 };
236 static const char prefix[] = " { ";
237 static const char suffix[] = "},";
238 MYDATA *p;
239 char temp[BUFSIZ];
240
241 /* generate the access table */
242 write_it(ofp, table_1);
243 for (p = all_data; p != NULL; p = p->link) {
244 if (p->name[0] == '#')
245 fprintf(ofp, "%s\n", p->name);
246 else {
247 int is_opt = !strncmp(p->type, "OPT_", 4);
248 int is_int = type_is_int(p);
249 char *dft_name = p->name;
250 /* TODO: is this still necessary? */
251 /* shorten message-variable names */
252 if (!strncmp(dft_name, "default_", 8))
253 dft_name += 8;
254 else if (!strncmp(dft_name, "attrib_", 7))
255 dft_name += 7;
256
257 fprintf(ofp, "%s", prefix);
258 sprintf(temp, "%s,", is_opt ? p->type : "OPT_LIST");
259 fprintf(ofp, "%-13s", temp);
260
261 if (is_title(p)) {
262 fprintf(ofp, "0, NULL, ");
263 } else if (!is_int) {
264 fprintf(ofp, "OINX_%s, 0, ", p->name);
265 } else {
266 fprintf(ofp, "0, &tinrc.%s, ", p->name);
267 }
268
269 if (is_opt)
270 fprintf(ofp, "NULL, ");
271 else
272 fprintf(ofp, "%s, ", p->type);
273 fprintf(ofp, "&txt_%s ", dft_name);
274 fprintf(ofp, "%s\n", suffix);
275 }
276 }
277
278 write_it(ofp, table_2);
279 }
280
281 static void
282 generate_enum(
283 FILE *ofp2)
284 {
285 MYDATA *p;
286
287 static const char *const table_1[] = {
288 "enum option_enum {",
289 0
290 };
291 static const char *const table_2[] = {
292 "\tSIGNAL_HANDLER };",
293 "",
294 "#define LAST_OPT (SIGNAL_HANDLER - 1)",
295 0
296 };
297
298 /* generate enumerated type */
299 write_it(ofp2, table_1);
300 for (p = all_data; p != NULL; p = p->link) {
301 if (p->name[0] == '#')
302 fprintf(ofp2, "%s\n", p->name);
303 else {
304 char *s = p->name;
305
306 fprintf(ofp2, "\tOPT_");
307 while (*s != '\0') {
308 fprintf(ofp2, "%c",
309 (*s >= 'a' && *s <= 'z')
310 ? ((unsigned char) ((*s) - 'a' + 'A'))
311 : *s);
312 s++;
313 }
314 fprintf(ofp2, ",\n");
315 }
316 }
317 write_it(ofp2, table_2);
318 }
319
320 static void
321 generate_ptr(
322 FILE *ofp,
323 const char *opt_type,
324 const char *ptr_type,
325 int mode)
326 {
327 MYDATA *p, *q;
328 int after;
329 const char *addr = !strcmp(opt_type, "OPT_STRING") ? "" : "&";
330
331 switch (mode) {
332 case 0:
333 fprintf(ofp, "\n%s %s_list[] = %c\n", ptr_type, opt_type, L_CURL);
334 break;
335 case 1:
336 fprintf(ofp, "\ntypedef OTYP %c\n", L_CURL);
337 break;
338 case 2:
339 fprintf(ofp, "\n");
340 break;
341 }
342 after = FALSE;
343
344 for (p = all_data, q = NULL; p != NULL; p = p->link) {
345 if (p->name[0] == '#') {
346 if (!strcmp(p->name, "#endif")) {
347 if (after) {
348 fprintf(ofp, "%s\n", p->name);
349 after = FALSE;
350 }
351 q = NULL;
352 } else {
353 q = p;
354 }
355 } else if (!strcmp(p->type, opt_type)) {
356 if (q != NULL) {
357 fprintf(ofp, "%s\n", q->name);
358 q = NULL;
359 after = TRUE;
360 }
361 switch (mode) {
362 case 0:
363 fprintf(ofp, "\t%stinrc.%s,%*s/* %2d: %s__ */\n",
364 addr,
365 p->name,
366 MAXNAME - (int)(strlen(addr) + strlen(p->name)),
367 " ",
368 index_of(p),
369 p->name);
370 break;
371 case 1:
372 fprintf(ofp, "\tOVAL(oinx_%.*s, %s__)\n",
373 MAXTYPE, opt_type,
374 p->name);
375 break;
376 case 2:
377 fprintf(ofp, "#define OINX_%-*.*s OINX(oinx_%.*s, %s__)\n",
378 MAXNAME, MAXNAME,
379 p->name,
380 MAXTYPE, opt_type,
381 p->name);
382 break;
383 }
384 }
385 }
386
387 switch (mode) {
388 case 0:
389 fprintf(ofp, "%c;\n", R_CURL);
390 break;
391 case 1:
392 fprintf(ofp, "\tOVAL(oinx_%.*s, s_MAX)\n", MAXTYPE, opt_type);
393 fprintf(ofp, "\tOEND(oinx_%.*s, Q1)\n", MAXTYPE, opt_type);
394 fprintf(ofp, "%c oinx_%.*s;\n", R_CURL, MAXTYPE, opt_type);
395 break;
396 case 2:
397 break;
398 }
399 }
400
401 static void
402 makecfg(
403 FILE *ifp,
404 FILE *ofp,
405 FILE *ofp2)
406 {
407 char buffer[BUFSIZ];
408 MYDATA *p, *q;
409
410 static const char *const table_1[] =
411 {
412 "/* This file is generated by MAKECFG */"
413 ,""
414 ,"#ifndef TINCFG_H"
415 ,"#define TINCFG_H 1"
416 ,""
417 ,"/* Macros for defining symbolic offsets that can be ifdef'd */"
418 ,"#undef OINX"
419 ,"#undef OVAL"
420 ,"#undef OEND"
421 ,"#undef OTYP"
422 ,""
423 ,"#ifdef lint"
424 ,"#\tdefine OINX(T, M) 0 /* 'lint -c' cannot be appeased */"
425 ,"#\tdefine OVAL(T, M) char M;"
426 ,"#\tdefine OEND(T, M) char M;"
427 ,"#\tdefine OTYP struct"
428 ,"#else"
429 ,"#\tifdef CPP_DOES_CONCAT"
430 ,"#\t\tdefine OINX(T, M) T ## M"
431 ,"#\t\tdefine OVAL(T, M) T ## M,"
432 ,"#\t\tdefine OEND(T, M) T ## M"
433 ,"#\t\tdefine OTYP enum"
434 ,"#\telse"
435 ,"#\t\tdefine OINX(T, M) \\"
436 ,"\t\t\t(((int)&(((T*)0)->M))/ \\"
437 ,"\t\t\t ((int)&(((T*)0)->Q1) - (int)&(((T*)0)->s_MAX)))"
438 ,"#\t\tdefine OVAL(T, M) char M;"
439 ,"#\t\tdefine OEND(T, M) char M;"
440 ,"#\t\tdefine OTYP struct"
441 ,"#\tendif /* CPP_DOES_CONCAT */"
442 ,"#endif /* lint */"
443 ,0
444 };
445 static const char *const table_2[] =
446 {
447 ""
448 ,"/* We needed these only to make the table compile */"
449 ,"#undef OINX"
450 ,"#undef OVAL"
451 ,"#undef OEND"
452 ,"#undef OTYP"
453 ,""
454 ,"#endif /* TINCFG_H */"
455 ,0
456 };
457 static const char *const table_3[] = {
458 "/* This file is generated by MAKECFG */",
459 "",
460 "#ifndef OPTIONS_MENU_H",
461 "#define OPTIONS_MENU_H 1",
462 "",
463 0
464 };
465 static const char *const table_4[] = {
466 "",
467 "#endif /* OPTIONS_MENU_H */",
468 0
469 };
470
471 /*
472 * Process the input file.
473 */
474 line_no = 0;
475 while (fgets(buffer, sizeof(buffer) - 1, ifp))
476 parse_tbl(buffer);
477 fclose(ifp);
478
479 /*
480 * Generate the output file
481 */
482 write_it(ofp, table_1);
483
484 /*
485 * For each type used in the table, generate a list of pointers to
486 * that type.
487 */
488 for (p = all_data; p != NULL; p = p->link) {
489 int found = FALSE;
490
491 if (p->name[0] == '#')
492 continue;
493 if (type_is_int(p) || is_title(p))
494 continue;
495
496 for (q = all_data; p != q; q = q->link) {
497 if (!strcmp(p->type, q->type)) {
498 found = TRUE;
499 break;
500 }
501 }
502 if (!found
503 && !strncmp(p->type, "OPT_", 4)) {
504 generate_ptr (ofp, p->type, typename_of(p), 0);
505 generate_ptr (ofp, p->type, typename_of(p), 1);
506 generate_ptr (ofp, p->type, typename_of(p), 2);
507 }
508 }
509 generate_tbl(ofp);
510
511 write_it(ofp, table_2);
512
513 fclose(ofp);
514
515 if (ofp2) {
516 write_it(ofp2, table_3);
517
518 generate_enum(ofp2);
519
520 write_it(ofp2, table_4);
521
522 fclose(ofp2);
523 }
524 }
525
526 int
527 main(
528 int argc,
529 char *argv[])
530 {
531 FILE *input = stdin;
532 FILE *output = stdout;
533 FILE *output2 = open_it("options_menu.h", "w");
534 MYDATA *m, *n;
535
536 if (argc > 1)
537 input = open_it(argv[1], "r");
538 if (argc > 2)
539 output = open_it(argv[2], "w");
540 makecfg(input, output, output2);
541
542 m = all_data;
543 while (m) {
544 n = m->link;
545 FreeIfNeeded(m->name);
546 FreeIfNeeded(m->type);
547 free(m);
548 m = n;
549 }
550
551 return (0);
552 }