14b88c807SRodney W. Grimes /*- 2*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*8a16b7a1SPedro F. Giffuni * 44b88c807SRodney W. Grimes * Copyright (c) 1991, 1993 54b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 64b88c807SRodney W. Grimes * 74b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 84b88c807SRodney W. Grimes * Kenneth Almquist. 94b88c807SRodney W. Grimes * 104b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 114b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 124b88c807SRodney W. Grimes * are met: 134b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 144b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 154b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 164b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 174b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 18fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 194b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 204b88c807SRodney W. Grimes * without specific prior written permission. 214b88c807SRodney W. Grimes * 224b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 234b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 244b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 254b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 264b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 274b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 284b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 294b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 304b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 314b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 324b88c807SRodney W. Grimes * SUCH DAMAGE. 334b88c807SRodney W. Grimes */ 344b88c807SRodney W. Grimes 3509a80d48SDavid E. O'Brien #if 0 364b88c807SRodney W. Grimes #ifndef lint 37ab0a2172SSteve Price static char const copyright[] = 384b88c807SRodney W. Grimes "@(#) Copyright (c) 1991, 1993\n\ 394b88c807SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 404b88c807SRodney W. Grimes #endif /* not lint */ 414b88c807SRodney W. Grimes 424b88c807SRodney W. Grimes #ifndef lint 433d7b5b93SPhilippe Charnier static char sccsid[] = "@(#)mksyntax.c 8.2 (Berkeley) 5/4/95"; 444b88c807SRodney W. Grimes #endif /* not lint */ 4509a80d48SDavid E. O'Brien #endif 462749b141SDavid E. O'Brien #include <sys/cdefs.h> 472749b141SDavid E. O'Brien __FBSDID("$FreeBSD$"); 484b88c807SRodney W. Grimes 494b88c807SRodney W. Grimes /* 504b88c807SRodney W. Grimes * This program creates syntax.h and syntax.c. 514b88c807SRodney W. Grimes */ 524b88c807SRodney W. Grimes 534b88c807SRodney W. Grimes #include <stdio.h> 5426f6b0fbSDag-Erling Smørgrav #include <stdlib.h> 55aa9caaf6SPeter Wemm #include <string.h> 564b88c807SRodney W. Grimes #include "parser.h" 574b88c807SRodney W. Grimes 584b88c807SRodney W. Grimes 594b88c807SRodney W. Grimes struct synclass { 60384aedabSJilles Tjoelker const char *name; 61384aedabSJilles Tjoelker const char *comment; 624b88c807SRodney W. Grimes }; 634b88c807SRodney W. Grimes 644b88c807SRodney W. Grimes /* Syntax classes */ 6558bdb076SJilles Tjoelker static const struct synclass synclass[] = { 66aa9caaf6SPeter Wemm { "CWORD", "character is nothing special" }, 67aa9caaf6SPeter Wemm { "CNL", "newline character" }, 68aa9caaf6SPeter Wemm { "CBACK", "a backslash character" }, 69a62ab027SJilles Tjoelker { "CSBACK", "a backslash character in single quotes" }, 70aa9caaf6SPeter Wemm { "CSQUOTE", "single quote" }, 71aa9caaf6SPeter Wemm { "CDQUOTE", "double quote" }, 72aa9caaf6SPeter Wemm { "CENDQUOTE", "a terminating quote" }, 73aa9caaf6SPeter Wemm { "CBQUOTE", "backwards single quote" }, 74aa9caaf6SPeter Wemm { "CVAR", "a dollar sign" }, 75aa9caaf6SPeter Wemm { "CENDVAR", "a '}' character" }, 76aa9caaf6SPeter Wemm { "CLP", "a left paren in arithmetic" }, 77aa9caaf6SPeter Wemm { "CRP", "a right paren in arithmetic" }, 78aa9caaf6SPeter Wemm { "CEOF", "end of file" }, 79aa9caaf6SPeter Wemm { "CCTL", "like CWORD, except it must be escaped" }, 80aa9caaf6SPeter Wemm { "CSPCL", "these terminate a word" }, 81d94c8673SJilles Tjoelker { "CIGN", "character should be ignored" }, 82aa9caaf6SPeter Wemm { NULL, NULL } 834b88c807SRodney W. Grimes }; 844b88c807SRodney W. Grimes 854b88c807SRodney W. Grimes 864b88c807SRodney W. Grimes /* 874b88c807SRodney W. Grimes * Syntax classes for is_ functions. Warning: if you add new classes 884b88c807SRodney W. Grimes * you may have to change the definition of the is_in_name macro. 894b88c807SRodney W. Grimes */ 9058bdb076SJilles Tjoelker static const struct synclass is_entry[] = { 91aa9caaf6SPeter Wemm { "ISDIGIT", "a digit" }, 92aa9caaf6SPeter Wemm { "ISUPPER", "an upper case letter" }, 93aa9caaf6SPeter Wemm { "ISLOWER", "a lower case letter" }, 94aa9caaf6SPeter Wemm { "ISUNDER", "an underscore" }, 95aa9caaf6SPeter Wemm { "ISSPECL", "the name of a special parameter" }, 96aa9caaf6SPeter Wemm { NULL, NULL } 974b88c807SRodney W. Grimes }; 984b88c807SRodney W. Grimes 9958bdb076SJilles Tjoelker static const char writer[] = "\ 1004b88c807SRodney W. Grimes /*\n\ 1014b88c807SRodney W. Grimes * This file was generated by the mksyntax program.\n\ 1024b88c807SRodney W. Grimes */\n\ 1034b88c807SRodney W. Grimes \n"; 1044b88c807SRodney W. Grimes 1054b88c807SRodney W. Grimes 106aa9caaf6SPeter Wemm static FILE *cfile; 107aa9caaf6SPeter Wemm static FILE *hfile; 1084b88c807SRodney W. Grimes 1091767d529SJilles Tjoelker static void add_default(void); 1101767d529SJilles Tjoelker static void finish(void); 1111767d529SJilles Tjoelker static void init(const char *); 112384aedabSJilles Tjoelker static void add(const char *, const char *); 1135134c3f7SWarner Losh static void output_type_macros(void); 1144b88c807SRodney W. Grimes 115aa9caaf6SPeter Wemm int 1165134c3f7SWarner Losh main(int argc __unused, char **argv __unused) 117aa9caaf6SPeter Wemm { 1184b88c807SRodney W. Grimes int i; 1194b88c807SRodney W. Grimes char buf[80]; 1204b88c807SRodney W. Grimes int pos; 1214b88c807SRodney W. Grimes 1224b88c807SRodney W. Grimes /* Create output files */ 1234b88c807SRodney W. Grimes if ((cfile = fopen("syntax.c", "w")) == NULL) { 1244b88c807SRodney W. Grimes perror("syntax.c"); 1254b88c807SRodney W. Grimes exit(2); 1264b88c807SRodney W. Grimes } 1274b88c807SRodney W. Grimes if ((hfile = fopen("syntax.h", "w")) == NULL) { 1284b88c807SRodney W. Grimes perror("syntax.h"); 1294b88c807SRodney W. Grimes exit(2); 1304b88c807SRodney W. Grimes } 1314b88c807SRodney W. Grimes fputs(writer, hfile); 1324b88c807SRodney W. Grimes fputs(writer, cfile); 1334b88c807SRodney W. Grimes 1344b88c807SRodney W. Grimes fputs("#include <sys/cdefs.h>\n", hfile); 1351767d529SJilles Tjoelker fputs("#include <limits.h>\n\n", hfile); 1364b88c807SRodney W. Grimes 1374b88c807SRodney W. Grimes /* Generate the #define statements in the header file */ 1384b88c807SRodney W. Grimes fputs("/* Syntax classes */\n", hfile); 1394b88c807SRodney W. Grimes for (i = 0 ; synclass[i].name ; i++) { 1404b88c807SRodney W. Grimes sprintf(buf, "#define %s %d", synclass[i].name, i); 1414b88c807SRodney W. Grimes fputs(buf, hfile); 142aa9caaf6SPeter Wemm for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07) 1434b88c807SRodney W. Grimes putc('\t', hfile); 1444b88c807SRodney W. Grimes fprintf(hfile, "/* %s */\n", synclass[i].comment); 1454b88c807SRodney W. Grimes } 1464b88c807SRodney W. Grimes putc('\n', hfile); 1474b88c807SRodney W. Grimes fputs("/* Syntax classes for is_ functions */\n", hfile); 1484b88c807SRodney W. Grimes for (i = 0 ; is_entry[i].name ; i++) { 1494b88c807SRodney W. Grimes sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i); 1504b88c807SRodney W. Grimes fputs(buf, hfile); 151aa9caaf6SPeter Wemm for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07) 1524b88c807SRodney W. Grimes putc('\t', hfile); 1534b88c807SRodney W. Grimes fprintf(hfile, "/* %s */\n", is_entry[i].comment); 1544b88c807SRodney W. Grimes } 1554b88c807SRodney W. Grimes putc('\n', hfile); 1561767d529SJilles Tjoelker fputs("#define SYNBASE (1 - CHAR_MIN)\n", hfile); 1571767d529SJilles Tjoelker fputs("#define PEOF -SYNBASE\n\n", hfile); 1584b88c807SRodney W. Grimes putc('\n', hfile); 1594b88c807SRodney W. Grimes fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile); 1604b88c807SRodney W. Grimes fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile); 1614b88c807SRodney W. Grimes fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile); 1624b88c807SRodney W. Grimes fputs("#define ARISYNTAX (arisyntax + SYNBASE)\n", hfile); 1634b88c807SRodney W. Grimes putc('\n', hfile); 1644b88c807SRodney W. Grimes output_type_macros(); /* is_digit, etc. */ 1654b88c807SRodney W. Grimes putc('\n', hfile); 1664b88c807SRodney W. Grimes 1674b88c807SRodney W. Grimes /* Generate the syntax tables. */ 1681767d529SJilles Tjoelker fputs("#include \"parser.h\"\n", cfile); 1694b88c807SRodney W. Grimes fputs("#include \"shell.h\"\n", cfile); 1704b88c807SRodney W. Grimes fputs("#include \"syntax.h\"\n\n", cfile); 1711767d529SJilles Tjoelker 1724b88c807SRodney W. Grimes fputs("/* syntax table used when not in quotes */\n", cfile); 1731767d529SJilles Tjoelker init("basesyntax"); 1741767d529SJilles Tjoelker add_default(); 1754b88c807SRodney W. Grimes add("\n", "CNL"); 1764b88c807SRodney W. Grimes add("\\", "CBACK"); 1774b88c807SRodney W. Grimes add("'", "CSQUOTE"); 1784b88c807SRodney W. Grimes add("\"", "CDQUOTE"); 1794b88c807SRodney W. Grimes add("`", "CBQUOTE"); 1804b88c807SRodney W. Grimes add("$", "CVAR"); 1814b88c807SRodney W. Grimes add("}", "CENDVAR"); 1824b88c807SRodney W. Grimes add("<>();&| \t", "CSPCL"); 1831767d529SJilles Tjoelker finish(); 1841767d529SJilles Tjoelker 1854b88c807SRodney W. Grimes fputs("\n/* syntax table used when in double quotes */\n", cfile); 1861767d529SJilles Tjoelker init("dqsyntax"); 1871767d529SJilles Tjoelker add_default(); 1884b88c807SRodney W. Grimes add("\n", "CNL"); 1894b88c807SRodney W. Grimes add("\\", "CBACK"); 1904b88c807SRodney W. Grimes add("\"", "CENDQUOTE"); 1914b88c807SRodney W. Grimes add("`", "CBQUOTE"); 1924b88c807SRodney W. Grimes add("$", "CVAR"); 1934b88c807SRodney W. Grimes add("}", "CENDVAR"); 1943a1b9c9eSJilles Tjoelker /* ':/' for tilde expansion, '-^]' for [a\-x] pattern ranges */ 1953a1b9c9eSJilles Tjoelker add("!*?[]=~:/-^", "CCTL"); 1961767d529SJilles Tjoelker finish(); 1971767d529SJilles Tjoelker 1984b88c807SRodney W. Grimes fputs("\n/* syntax table used when in single quotes */\n", cfile); 1991767d529SJilles Tjoelker init("sqsyntax"); 2001767d529SJilles Tjoelker add_default(); 2014b88c807SRodney W. Grimes add("\n", "CNL"); 202a62ab027SJilles Tjoelker add("\\", "CSBACK"); 2034b88c807SRodney W. Grimes add("'", "CENDQUOTE"); 2043a1b9c9eSJilles Tjoelker /* ':/' for tilde expansion, '-^]' for [a\-x] pattern ranges */ 2053a1b9c9eSJilles Tjoelker add("!*?[]=~:/-^", "CCTL"); 2061767d529SJilles Tjoelker finish(); 2071767d529SJilles Tjoelker 2084b88c807SRodney W. Grimes fputs("\n/* syntax table used when in arithmetic */\n", cfile); 2091767d529SJilles Tjoelker init("arisyntax"); 2101767d529SJilles Tjoelker add_default(); 2114b88c807SRodney W. Grimes add("\n", "CNL"); 2124b88c807SRodney W. Grimes add("\\", "CBACK"); 2134b88c807SRodney W. Grimes add("`", "CBQUOTE"); 214d94c8673SJilles Tjoelker add("\"", "CIGN"); 2154b88c807SRodney W. Grimes add("$", "CVAR"); 2164b88c807SRodney W. Grimes add("}", "CENDVAR"); 2174b88c807SRodney W. Grimes add("(", "CLP"); 2184b88c807SRodney W. Grimes add(")", "CRP"); 2191767d529SJilles Tjoelker finish(); 2201767d529SJilles Tjoelker 2214b88c807SRodney W. Grimes fputs("\n/* character classification table */\n", cfile); 2221767d529SJilles Tjoelker init("is_type"); 2234b88c807SRodney W. Grimes add("0123456789", "ISDIGIT"); 22440969e73SJilles Tjoelker add("abcdefghijklmnopqrstuvwxyz", "ISLOWER"); 22540969e73SJilles Tjoelker add("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ISUPPER"); 2264b88c807SRodney W. Grimes add("_", "ISUNDER"); 2274b88c807SRodney W. Grimes add("#?$!-*@", "ISSPECL"); 2281767d529SJilles Tjoelker finish(); 2291767d529SJilles Tjoelker 2304b88c807SRodney W. Grimes exit(0); 2314b88c807SRodney W. Grimes } 2324b88c807SRodney W. Grimes 2334b88c807SRodney W. Grimes 2344b88c807SRodney W. Grimes /* 2351767d529SJilles Tjoelker * Output the header and declaration of a syntax table. 2364b88c807SRodney W. Grimes */ 2374b88c807SRodney W. Grimes 238aa9caaf6SPeter Wemm static void 2391767d529SJilles Tjoelker init(const char *name) 2404b88c807SRodney W. Grimes { 2411767d529SJilles Tjoelker fprintf(hfile, "extern const char %s[];\n", name); 2421767d529SJilles Tjoelker fprintf(cfile, "const char %s[SYNBASE + CHAR_MAX + 1] = {\n", name); 2431767d529SJilles Tjoelker } 2444b88c807SRodney W. Grimes 2451767d529SJilles Tjoelker 2461767d529SJilles Tjoelker static void 2471767d529SJilles Tjoelker add_one(const char *key, const char *type) 2481767d529SJilles Tjoelker { 2491767d529SJilles Tjoelker fprintf(cfile, "\t[SYNBASE + %s] = %s,\n", key, type); 2504b88c807SRodney W. Grimes } 2514b88c807SRodney W. Grimes 2524b88c807SRodney W. Grimes 2534b88c807SRodney W. Grimes /* 2541767d529SJilles Tjoelker * Add default values to the syntax table. 2554b88c807SRodney W. Grimes */ 2564b88c807SRodney W. Grimes 257aa9caaf6SPeter Wemm static void 2581767d529SJilles Tjoelker add_default(void) 259aa9caaf6SPeter Wemm { 2601767d529SJilles Tjoelker add_one("PEOF", "CEOF"); 2611767d529SJilles Tjoelker add_one("CTLESC", "CCTL"); 2621767d529SJilles Tjoelker add_one("CTLVAR", "CCTL"); 2631767d529SJilles Tjoelker add_one("CTLENDVAR", "CCTL"); 2641767d529SJilles Tjoelker add_one("CTLBACKQ", "CCTL"); 2651767d529SJilles Tjoelker add_one("CTLBACKQ + CTLQUOTE", "CCTL"); 2661767d529SJilles Tjoelker add_one("CTLARI", "CCTL"); 2671767d529SJilles Tjoelker add_one("CTLENDARI", "CCTL"); 2681767d529SJilles Tjoelker add_one("CTLQUOTEMARK", "CCTL"); 2691767d529SJilles Tjoelker add_one("CTLQUOTEEND", "CCTL"); 2701767d529SJilles Tjoelker } 2711767d529SJilles Tjoelker 2721767d529SJilles Tjoelker 2731767d529SJilles Tjoelker /* 2741767d529SJilles Tjoelker * Output the footer of a syntax table. 2751767d529SJilles Tjoelker */ 2761767d529SJilles Tjoelker 2771767d529SJilles Tjoelker static void 2781767d529SJilles Tjoelker finish(void) 2791767d529SJilles Tjoelker { 2801767d529SJilles Tjoelker fputs("};\n", cfile); 2814b88c807SRodney W. Grimes } 2824b88c807SRodney W. Grimes 2834b88c807SRodney W. Grimes 2844b88c807SRodney W. Grimes /* 2854b88c807SRodney W. Grimes * Add entries to the syntax table. 2864b88c807SRodney W. Grimes */ 2874b88c807SRodney W. Grimes 288aa9caaf6SPeter Wemm static void 289384aedabSJilles Tjoelker add(const char *p, const char *type) 2904b88c807SRodney W. Grimes { 2911767d529SJilles Tjoelker for (; *p; ++p) { 2921767d529SJilles Tjoelker char c = *p; 2931767d529SJilles Tjoelker switch (c) { 2941767d529SJilles Tjoelker case '\t': c = 't'; break; 2951767d529SJilles Tjoelker case '\n': c = 'n'; break; 2961767d529SJilles Tjoelker case '\'': c = '\''; break; 2971767d529SJilles Tjoelker case '\\': c = '\\'; break; 2981767d529SJilles Tjoelker 2991767d529SJilles Tjoelker default: 3001767d529SJilles Tjoelker fprintf(cfile, "\t[SYNBASE + '%c'] = %s,\n", c, type); 3011767d529SJilles Tjoelker continue; 3024b88c807SRodney W. Grimes } 3031767d529SJilles Tjoelker fprintf(cfile, "\t[SYNBASE + '\\%c'] = %s,\n", c, type); 3044b88c807SRodney W. Grimes } 3054b88c807SRodney W. Grimes } 3064b88c807SRodney W. Grimes 3074b88c807SRodney W. Grimes 3084b88c807SRodney W. Grimes /* 3094b88c807SRodney W. Grimes * Output character classification macros (e.g. is_digit). If digits are 3104b88c807SRodney W. Grimes * contiguous, we can test for them quickly. 3114b88c807SRodney W. Grimes */ 3124b88c807SRodney W. Grimes 313384aedabSJilles Tjoelker static const char *macro[] = { 314eaf77199SJilles Tjoelker "#define is_digit(c)\t((unsigned int)((c) - '0') <= 9)", 315716b138bSStefan Farfeleder "#define is_eof(c)\t((c) == PEOF)", 316467fdf32SJilles Tjoelker "#define is_alpha(c)\t((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER))", 317467fdf32SJilles Tjoelker "#define is_name(c)\t((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER|ISUNDER))", 318467fdf32SJilles Tjoelker "#define is_in_name(c)\t((is_type+SYNBASE)[(int)c] & (ISUPPER|ISLOWER|ISUNDER|ISDIGIT))", 319fe5d61a4SJilles Tjoelker "#define is_special(c)\t((is_type+SYNBASE)[(int)c] & (ISSPECL|ISDIGIT))", 320eaf77199SJilles Tjoelker "#define digit_val(c)\t((c) - '0')", 3214b88c807SRodney W. Grimes NULL 3224b88c807SRodney W. Grimes }; 3234b88c807SRodney W. Grimes 324aa9caaf6SPeter Wemm static void 3255134c3f7SWarner Losh output_type_macros(void) 326aa9caaf6SPeter Wemm { 327384aedabSJilles Tjoelker const char **pp; 3284b88c807SRodney W. Grimes 3294b88c807SRodney W. Grimes for (pp = macro ; *pp ; pp++) 3304b88c807SRodney W. Grimes fprintf(hfile, "%s\n", *pp); 3314b88c807SRodney W. Grimes } 332