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