shithub: trueawk

Download patch

ref: 6a8770929d4653725e75f4a7a3446f227c4c6817
parent: 5a18f63b8dfc35fb7bcda4688661e354783d2bb7
author: zoulasc <zoulasc@users.noreply.github.com>
date: Thu Jan 23 23:11:59 EST 2020

Small fixes (#68)

* sprinkle const, static
* account for lineno in unput
* Add an EMPTY string that is used when a non-const empty string is needed.
* make inputFS static and dynamically allocated
* Simplify and in the process avoid -Wwritable-strings
* make fs const to avoid -Wwritable-strings

--- a/awk.h
+++ b/awk.h
@@ -60,6 +60,7 @@
 #define	RECSIZE	(8 * 1024)	/* sets limit on records, fields, etc., etc. */
 extern int	recsize;	/* size of current record, orig RECSIZE */
 
+extern char	EMPTY[];
 extern char	**FS;
 extern char	**RS;
 extern char	**ORS;
@@ -78,8 +79,6 @@
 extern int	errorflag;	/* 1 if error has occurred */
 extern bool	donefld;	/* true if record broken into fields */
 extern bool	donerec;	/* true if record is valid (no fld has changed */
-extern char	inputFS[];	/* FS at time of input, for field splitting */
-
 extern int	dbg;
 
 extern const char *patbeg;	/* beginning of pattern matched */
--- a/b.c
+++ b/b.c
@@ -873,7 +873,7 @@
 
 #endif
 
-struct charclass {
+static const struct charclass {
 	const char *cc_name;
 	int cc_namelen;
 	int (*cc_func)(int);
@@ -1017,7 +1017,7 @@
 	static uschar *buf = NULL;
 	static int bufsz = 100;
 	uschar *bp;
-	struct charclass *cc;
+	const struct charclass *cc;
 	int i;
 	int num, m;
 	bool commafound, digitfound;
--- a/lex.c
+++ b/lex.c
@@ -43,7 +43,7 @@
 	int	type;
 } Keyword;
 
-Keyword keywords[] ={	/* keep sorted: binary searched */
+const Keyword keywords[] = {	/* keep sorted: binary searched */
 	{ "BEGIN",	XBEGIN,		XBEGIN },
 	{ "END",	XEND,		XEND },
 	{ "NF",		VARNF,		VARNF },
@@ -91,7 +91,7 @@
 
 #define	RET(x)	{ if(dbg)printf("lex %s\n", tokname(x)); return(x); }
 
-int peek(void)
+static int peek(void)
 {
 	int c = input();
 	unput(c);
@@ -98,7 +98,7 @@
 	return c;
 }
 
-int gettok(char **pbuf, int *psz)	/* get next input token */
+static int gettok(char **pbuf, int *psz)	/* get next input token */
 {
 	int c, retc;
 	char *buf = *pbuf;
@@ -440,7 +440,7 @@
 }
 
 
-int binsearch(char *w, Keyword *kp, int n)
+static int binsearch(char *w, const Keyword *kp, int n)
 {
 	int cond, low, mid, high;
 
@@ -460,7 +460,7 @@
 
 int word(char *w)
 {
-	Keyword *kp;
+	const Keyword *kp;
 	int c, n;
 
 	n = binsearch(w, keywords, sizeof(keywords)/sizeof(keywords[0]));
@@ -572,6 +572,8 @@
 
 void unput(int c)	/* put lexical character back on input */
 {
+	if (c == '\n')  
+		lineno--;
 	if (yysptr >= yysbuf + sizeof(yysbuf))
 		FATAL("pushed back too much: %.20s...", yysbuf);
 	*yysptr++ = c;
--- a/lib.c
+++ b/lib.c
@@ -32,8 +32,9 @@
 #include "awk.h"
 #include "ytab.h"
 
+char	EMPTY[] = { '\0' };
 FILE	*infile	= NULL;
-char	*file	= "";
+char	*file	= EMPTY;
 char	*record;
 int	recsize	= RECSIZE;
 char	*fields;
@@ -40,7 +41,8 @@
 int	fieldssize = RECSIZE;
 
 Cell	**fldtab;	/* pointers to Cells */
-char	inputFS[100] = " ";
+static size_t	len_inputFS = 0;
+static char	*inputFS = NULL; /* FS at time of input, for field splitting */
 
 #define	MAXFLD	2
 int	nfields	= MAXFLD;	/* last allocated slot for $i */
@@ -52,8 +54,8 @@
 int	argno	= 1;	/* current input argument number */
 extern	Awkfloat *ARGC;
 
-static Cell dollar0 = { OCELL, CFLD, NULL, "", 0.0, REC|STR|DONTFREE };
-static Cell dollar1 = { OCELL, CFLD, NULL, "", 0.0, FLD|STR|DONTFREE };
+static Cell dollar0 = { OCELL, CFLD, NULL, EMPTY, 0.0, REC|STR|DONTFREE };
+static Cell dollar1 = { OCELL, CFLD, NULL, EMPTY, 0.0, FLD|STR|DONTFREE };
 
 void recinit(unsigned int n)
 {
@@ -116,9 +118,17 @@
  */
 void savefs(void)
 {
-	if (strlen(getsval(fsloc)) >= sizeof (inputFS))
+	size_t len;
+	if ((len = strlen(getsval(fsloc))) < len_inputFS) {
+		strcpy(inputFS, *FS);	/* for subsequent field splitting */
+		return;
+	}
+
+	len_inputFS = len + 1;
+	inputFS = realloc(inputFS, len_inputFS);
+	if (inputFS == NULL)
 		FATAL("field separator %.10s... is too long", *FS);
-	strcpy(inputFS, *FS);
+	memcpy(inputFS, *FS, len_inputFS);
 }
 
 static bool firsttime = true;
@@ -404,7 +414,7 @@
 		p = fldtab[i];
 		if (freeable(p))
 			xfree(p->sval);
-		p->sval = "";
+		p->sval = EMPTY,
 		p->tval = FLD | STR | DONTFREE;
 	}
 }
--- a/maketab.c
+++ b/maketab.c
@@ -122,8 +122,6 @@
 	printf("#include <stdio.h>\n");
 	printf("#include \"awk.h\"\n");
 	printf("#include \"ytab.h\"\n\n");
-	for (i = SIZE; --i >= 0; )
-		names[i] = "";
 
 	if (argc != 2) {
 		fprintf(stderr, "usage: maketab YTAB_H\n");
@@ -160,10 +158,8 @@
 		table[p->token-FIRSTTOKEN] = p->name;
 	printf("\nCell *(*proctab[%d])(Node **, int) = {\n", SIZE);
 	for (i=0; i<SIZE; i++)
-		if (table[i]==NULL)
-			printf("\tnullproc,\t/* %s */\n", names[i]);
-		else
-			printf("\t%s,\t/* %s */\n", table[i], names[i]);
+		printf("\t%s,\t/* %s */\n",
+		    table[i] ? table[i] : "nullproc", names[i] ? names[i] : "");
 	printf("};\n\n");
 
 	printf("const char *tokname(int n)\n");	/* print a tokname() function */
--- a/run.c
+++ b/run.c
@@ -90,7 +90,7 @@
 Cell	*jexit	= &exitcell;
 static Cell	retcell		={ OJUMP, JRET, 0, 0, 0.0, NUM, NULL };
 Cell	*jret	= &retcell;
-static Cell	tempcell	={ OCELL, CTEMP, 0, "", 0.0, NUM|STR|DONTFREE, NULL };
+static Cell	tempcell	={ OCELL, CTEMP, 0, EMPTY, 0.0, NUM|STR|DONTFREE, NULL };
 
 Node	*curnode = NULL;	/* the node being executed, for debugging */
 
@@ -224,7 +224,7 @@
 
 Cell *call(Node **a, int n)	/* function call.  very kludgy and fragile */
 {
-	static Cell newcopycell = { OCELL, CCOPY, 0, "", 0.0, NUM|STR|DONTFREE, NULL };
+	static Cell newcopycell = { OCELL, CCOPY, 0, EMPTY, 0.0, NUM|STR|DONTFREE, NULL };
 	int i, ncall, ndef;
 	int freed = 0; /* handles potential double freeing when fcn & param share a tempcell */
 	Node *x;
@@ -1246,7 +1246,8 @@
 {
 	Cell *x = NULL, *y, *ap;
 	const char *s, *origs, *t;
-	char *fs = NULL, *origfs = NULL;
+	const char *fs = NULL;
+	char *origfs = NULL;
 	int sep;
 	char temp, num[50];
 	int n, tempstat, arg3type;
@@ -1258,7 +1259,7 @@
 		fs = getsval(fsloc);
 	else if (arg3type == STRING) {	/* split(str,arr,"string") */
 		x = execute(a[2]);
-		origfs = fs = strdup(getsval(x));
+		fs = origfs = strdup(getsval(x));
 		tempfree(x);
 	} else if (arg3type == REGEXPR)
 		fs = "(regexpr)";	/* split(str,arr,/regexpr/) */
--