1#!/usr/bin/awk -f
2# vile: awkmode
3function noident(given) {
4	gsub(/\$/,"@", given);
5	return given;
6}
7BEGIN { havesection = 0;
8	version = "Id: skel2c,v 1.4 2016/06/07 00:26:09 tom Exp ";
9	nsec = 0;
10	ifdef = "";
11	printf  "/* This file generated automatically using\n * %s\n */\n\n",
12		noident(version);
13      }
14/[$]Id[:][^$]*[$]/ {
15	printf "%s\n", noident($0);
16	next;
17      }
18/^%% *insert *VERSION *here/ {
19	printf "    CONCAT1(\"#define YYMAJOR \", YYMAJOR),\n";
20	printf "    CONCAT1(\"#define YYMINOR \", YYMINOR),\n";
21	printf "#ifdef YYPATCH\n";
22	printf "    CONCAT1(\"#define YYPATCH \", YYPATCH),\n";
23	printf "#endif\n";
24	next;
25      }
26/^%%ifdef/ {
27	if (NF >= 2) {
28	    printf "#if defined(%s)\n", $2;
29	    printf "    \"#if %s\",\n", $2;
30	} else {
31	    _abort_exit = 1;
32	    printf "skel2c: ill-formed %%ifdef in skeleton file on line %d\n", FNR > "/dev/stderr";
33	    exit 2;
34	}
35	if (ifdef != "") {
36	    printf "skel2c: nested %%ifdef in skeleton file on line %d\n", FNR > "/dev/stderr";
37	    exit 2;
38	}
39	ifdef = $2;
40	next;
41      }
42/^%%endif/ {
43	if (ifdef != "") {
44	    if (NF >= 2) {
45		printf "    \"#endif /* %s */\",\n", $2;
46		printf "#endif\t\t\t/* defined(%s) */\n", $2;
47	    } else {
48		printf "    \"#endif /* %s */\",\n", ifdef;
49		printf "#endif\t\t\t/* defined(%s) */\n", ifdef;
50	    }
51	    ifdef = "";
52	} else {
53	    printf "    \"#endif\",\n";
54	    printf "#endif\n";
55	    printf "skel2c: unmatched %endif in skeleton file on line %d\n", FNR > "/dev/stderr";
56	    exit 2;
57	}
58	next;
59      }
60/^%%/ { if (havesection) {
61	    printf "    0\n};\n\n";
62	}
63	if (NF >= 2) {
64	    havesection = 1;
65	    section = $2;
66	    seclist[nsec] = section;
67	    nsec = nsec + 1;
68	    printf "const char *const %s[] =\n{\n", $2;
69	} else {
70	    havesection = 0;
71	}
72	next;
73      }
74      { if (havesection) {
75	    # Could use 'gsub(/\\/, "\\\\")' instead of the following
76	    # two lines, but there's a bug in mawk and the original
77	    # awk (not in gawk) which is triggered by that.
78	    gsub(/\\/, "\\\1");
79	    gsub(/\1/, "\\");
80#	    gsub(/\t/, "\\t"); # change '\t' to "\\t"
81	    gsub(/\"/, "\\\"");
82	    printf "    \"%s\",\n", $0;
83	} else {
84	    print $0;
85	}
86      }
87END   { if (_abort_exit)
88	    exit 2;
89	if (havesection) {
90	    print "    0\n};\n";
91	}
92	if (nsec > 0) {
93	    print "void";
94	    print "write_section(FILE * fp, const char *const section[])";
95	    print "{";
96	    print "    int i;";
97	    print "    const char *s;\n";
98	    print "    for (i = 0; (s = section[i]) != 0; ++i)";
99	    print "    {";
100	    print "\tif (fp == code_file)";
101	    print "\t    ++outline;";
102	    print "\tfprintf(fp, \"%s\\n\", s);";
103	    print "    }";
104	    print "}";
105	} else {
106	    print "skel2c: no sections defined in skeleton file" > "/dev/stderr";
107	    exit 2;
108	}
109	if (ifdef != "") {
110	    printf "skel2c: unmatched %%ifdef %s at end of skeleton file\n", $ifdef > "/dev/stderr";
111	    exit 2;
112	}
113      }
114