svn commit: r246522 - head/bin/sh

Jilles Tjoelker jilles at FreeBSD.org
Thu Feb 7 22:42:34 UTC 2013


Author: jilles
Date: Thu Feb  7 22:42:33 2013
New Revision: 246522
URL: http://svnweb.freebsd.org/changeset/base/246522

Log:
  sh: Simplify mksyntax and make it fit for cross-compiling.
  
  Now it outputs fixed files, which use constants provided by the C standard
  library to determine appropriate values for the target machine.
  
  Before, mksyntax inspected the host machine which resulted in subtle
  breakage if e.g. char is signed on the host and unsigned on the target such
  as when cross-compiling on x86 for ARM.
  
  Tested using -funsigned-char on amd64. Compiling build-tools without it and
  sh itself with it causes various tests to fail without this change but not
  with this change. With consistent -funsigned-char, tests pass with or
  without this change.
  
  The mksyntax program could be removed and syntax.c and syntax.h committed to
  the repository.
  
  Submitted by:	Christoph Mallon
  MFC after:	2 weeks

Modified:
  head/bin/sh/mksyntax.c

Modified: head/bin/sh/mksyntax.c
==============================================================================
--- head/bin/sh/mksyntax.c	Thu Feb  7 22:40:26 2013	(r246521)
+++ head/bin/sh/mksyntax.c	Thu Feb  7 22:42:33 2013	(r246522)
@@ -103,23 +103,16 @@ static char writer[] = "\
 
 static FILE *cfile;
 static FILE *hfile;
-static const char *syntax[513];
-static int base;
-static int size;	/* number of values which a char variable can have */
-static int nbits;	/* number of bits in a character */
 
-static void filltable(const char *);
-static void init(void);
+static void add_default(void);
+static void finish(void);
+static void init(const char *);
 static void add(const char *, const char *);
-static void print(const char *);
 static void output_type_macros(void);
 
 int
 main(int argc __unused, char **argv __unused)
 {
-	char c;
-	char d;
-	int sign;
 	int i;
 	char buf[80];
 	int pos;
@@ -136,27 +129,8 @@ main(int argc __unused, char **argv __un
 	fputs(writer, hfile);
 	fputs(writer, cfile);
 
-	/* Determine the characteristics of chars. */
-	c = -1;
-	sign = (c > 0) ? 0 : 1;
-	for (nbits = 1 ; ; nbits++) {
-		d = (1 << nbits) - 1;
-		if (d == c)
-			break;
-	}
-#if 0
-	printf("%s %d bit chars\n", sign? "signed" : "unsigned", nbits);
-#endif
-	if (nbits > 9) {
-		fputs("Characters can't have more than 9 bits\n", stderr);
-		exit(2);
-	}
-	size = (1 << nbits) + 1;
-	base = 1;
-	if (sign)
-		base += 1 << (nbits - 1);
-
 	fputs("#include <sys/cdefs.h>\n", hfile);
+	fputs("#include <limits.h>\n\n", hfile);
 
 	/* Generate the #define statements in the header file */
 	fputs("/* Syntax classes */\n", hfile);
@@ -177,8 +151,8 @@ main(int argc __unused, char **argv __un
 		fprintf(hfile, "/* %s */\n", is_entry[i].comment);
 	}
 	putc('\n', hfile);
-	fprintf(hfile, "#define SYNBASE %d\n", base);
-	fprintf(hfile, "#define PEOF %d\n\n", -base);
+	fputs("#define SYNBASE (1 - CHAR_MIN)\n", hfile);
+	fputs("#define PEOF -SYNBASE\n\n", hfile);
 	putc('\n', hfile);
 	fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile);
 	fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile);
@@ -189,10 +163,13 @@ main(int argc __unused, char **argv __un
 	putc('\n', hfile);
 
 	/* Generate the syntax tables. */
+	fputs("#include \"parser.h\"\n", cfile);
 	fputs("#include \"shell.h\"\n", cfile);
 	fputs("#include \"syntax.h\"\n\n", cfile);
-	init();
+
 	fputs("/* syntax table used when not in quotes */\n", cfile);
+	init("basesyntax");
+	add_default();
 	add("\n", "CNL");
 	add("\\", "CBACK");
 	add("'", "CSQUOTE");
@@ -201,9 +178,11 @@ main(int argc __unused, char **argv __un
 	add("$", "CVAR");
 	add("}", "CENDVAR");
 	add("<>();&| \t", "CSPCL");
-	print("basesyntax");
-	init();
+	finish();
+
 	fputs("\n/* syntax table used when in double quotes */\n", cfile);
+	init("dqsyntax");
+	add_default();
 	add("\n", "CNL");
 	add("\\", "CBACK");
 	add("\"", "CENDQUOTE");
@@ -212,17 +191,21 @@ main(int argc __unused, char **argv __un
 	add("}", "CENDVAR");
 	/* ':/' for tilde expansion, '-^]' for [a\-x] pattern ranges */
 	add("!*?[]=~:/-^", "CCTL");
-	print("dqsyntax");
-	init();
+	finish();
+
 	fputs("\n/* syntax table used when in single quotes */\n", cfile);
+	init("sqsyntax");
+	add_default();
 	add("\n", "CNL");
 	add("\\", "CSBACK");
 	add("'", "CENDQUOTE");
 	/* ':/' for tilde expansion, '-^]' for [a\-x] pattern ranges */
 	add("!*?[]=~:/-^", "CCTL");
-	print("sqsyntax");
-	init();
+	finish();
+
 	fputs("\n/* syntax table used when in arithmetic */\n", cfile);
+	init("arisyntax");
+	add_default();
 	add("\n", "CNL");
 	add("\\", "CBACK");
 	add("`", "CBQUOTE");
@@ -231,100 +214,95 @@ main(int argc __unused, char **argv __un
 	add("}", "CENDVAR");
 	add("(", "CLP");
 	add(")", "CRP");
-	print("arisyntax");
-	filltable("0");
+	finish();
+
 	fputs("\n/* character classification table */\n", cfile);
+	init("is_type");
 	add("0123456789", "ISDIGIT");
 	add("abcdefghijklmnopqrstuvwxyz", "ISLOWER");
 	add("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ISUPPER");
 	add("_", "ISUNDER");
 	add("#?$!-*@", "ISSPECL");
-	print("is_type");
+	finish();
+
 	exit(0);
 }
 
 
-
 /*
- * Clear the syntax table.
+ * Output the header and declaration of a syntax table.
  */
 
 static void
-filltable(const char *dftval)
+init(const char *name)
 {
-	int i;
+	fprintf(hfile, "extern const char %s[];\n", name);
+	fprintf(cfile, "const char %s[SYNBASE + CHAR_MAX + 1] = {\n", name);
+}
+
 
-	for (i = 0 ; i < size ; i++)
-		syntax[i] = dftval;
+static void
+add_one(const char *key, const char *type)
+{
+	fprintf(cfile, "\t[SYNBASE + %s] = %s,\n", key, type);
 }
 
 
 /*
- * Initialize the syntax table with default values.
+ * Add default values to the syntax table.
  */
 
 static void
-init(void)
+add_default(void)
 {
-	filltable("CWORD");
-	syntax[0] = "CEOF";
-	syntax[base + CTLESC] = "CCTL";
-	syntax[base + CTLVAR] = "CCTL";
-	syntax[base + CTLENDVAR] = "CCTL";
-	syntax[base + CTLBACKQ] = "CCTL";
-	syntax[base + CTLBACKQ + CTLQUOTE] = "CCTL";
-	syntax[base + CTLARI] = "CCTL";
-	syntax[base + CTLENDARI] = "CCTL";
-	syntax[base + CTLQUOTEMARK] = "CCTL";
-	syntax[base + CTLQUOTEEND] = "CCTL";
+	add_one("PEOF",                "CEOF");
+	add_one("CTLESC",              "CCTL");
+	add_one("CTLVAR",              "CCTL");
+	add_one("CTLENDVAR",           "CCTL");
+	add_one("CTLBACKQ",            "CCTL");
+	add_one("CTLBACKQ + CTLQUOTE", "CCTL");
+	add_one("CTLARI",              "CCTL");
+	add_one("CTLENDARI",           "CCTL");
+	add_one("CTLQUOTEMARK",        "CCTL");
+	add_one("CTLQUOTEEND",         "CCTL");
 }
 
 
 /*
- * Add entries to the syntax table.
+ * Output the footer of a syntax table.
  */
 
 static void
-add(const char *p, const char *type)
+finish(void)
 {
-	while (*p)
-		syntax[*p++ + base] = type;
+	fputs("};\n", cfile);
 }
 
 
-
 /*
- * Output the syntax table.
+ * Add entries to the syntax table.
  */
 
 static void
-print(const char *name)
+add(const char *p, const char *type)
 {
-	int i;
-	int col;
-
-	fprintf(hfile, "extern const char %s[];\n", name);
-	fprintf(cfile, "const char %s[%d] = {\n", name, size);
-	col = 0;
-	for (i = 0 ; i < size ; i++) {
-		if (i == 0) {
-			fputs("      ", cfile);
-		} else if ((i & 03) == 0) {
-			fputs(",\n      ", cfile);
-			col = 0;
-		} else {
-			putc(',', cfile);
-			while (++col < 9 * (i & 03))
-				putc(' ', cfile);
+	for (; *p; ++p) {
+		char c = *p;
+		switch (c) {
+		case '\t': c = 't';  break;
+		case '\n': c = 'n';  break;
+		case '\'': c = '\''; break;
+		case '\\': c = '\\'; break;
+
+		default:
+			fprintf(cfile, "\t[SYNBASE + '%c'] = %s,\n", c, type);
+			continue;
 		}
-		fputs(syntax[i], cfile);
-		col += strlen(syntax[i]);
+		fprintf(cfile, "\t[SYNBASE + '\\%c'] = %s,\n", c, type);
 	}
-	fputs("\n};\n", cfile);
 }
 
 
-
 /*
  * Output character classification macros (e.g. is_digit).  If digits are
  * contiguous, we can test for them quickly.


More information about the svn-src-head mailing list