about summary refs log tree commit diff
path: root/parse.y
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2013-05-29 22:37:37 +0200
committerChristian Neukirchen <chneukirchen@gmail.com>2013-05-29 22:41:51 +0200
commit5515a365ba77cec3e7bf9797c3a4cc5e6c5c91ae (patch)
tree437f902828ef965474a0bcf9402f30bf937135cb /parse.y
parent843f18aaee1550344b8521d95d952502e064c5f0 (diff)
parent692d341dfc6b059db570356e9dfadba92dc93f19 (diff)
downloadcwm-5515a365ba77cec3e7bf9797c3a4cc5e6c5c91ae.tar.gz
cwm-5515a365ba77cec3e7bf9797c3a4cc5e6c5c91ae.tar.xz
cwm-5515a365ba77cec3e7bf9797c3a4cc5e6c5c91ae.zip
cvsimport
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y111
1 files changed, 66 insertions, 45 deletions
diff --git a/parse.y b/parse.y
index 376bc2b..9e93749 100644
--- a/parse.y
+++ b/parse.y
@@ -44,18 +44,17 @@ static struct file {
 	char			*name;
 	int			 lineno;
 	int			 errors;
-} *file;
-
-struct file		*pushfile(const char *);
-int			 popfile(void);
-int			 yyparse(void);
-int			 yylex(void);
-int			 yyerror(const char *, ...);
-int			 kw_cmp(const void *, const void *);
-int			 lookup(char *);
-int			 lgetc(int);
-int			 lungetc(int);
-int			 findeol(void);
+} *file, *topfile;
+struct file	*pushfile(const char *);
+int		 popfile(void);
+int		 yyparse(void);
+int		 yylex(void);
+int		 yyerror(const char *, ...);
+int		 kw_cmp(const void *, const void *);
+int		 lookup(char *);
+int		 lgetc(int);
+int		 lungetc(int);
+int		 findeol(void);
 
 static struct conf	*conf;
 
@@ -119,12 +118,24 @@ main		: FONTNAME STRING		{
 				conf->flags |= CONF_STICKY_GROUPS;
 		}
 		| BORDERWIDTH NUMBER {
+			if ($2 < 0) {
+				yyerror("invalid borderwidth: %d", $2);
+				YYERROR;
+			}
 			conf->bwidth = $2;
 		}
 		| MOVEAMOUNT NUMBER {
+			if ($2 < 0) {
+				yyerror("invalid movemount: %d", $2);
+				YYERROR;
+			}
 			conf->mamount = $2;
 		}
 		| SNAPDIST NUMBER {
+			if ($2 < 0) {
+				yyerror("invalid snapdist: %d", $2);
+				YYERROR;
+			}
 			conf->snapdist = $2;
 		}
 		| COMMAND STRING string		{
@@ -135,10 +146,9 @@ main		: FONTNAME STRING		{
 		| AUTOGROUP NUMBER STRING	{
 			if ($2 < 0 || $2 > 9) {
 				free($3);
-				yyerror("autogroup number out of range: %d", $2);
+				yyerror("invalid autogroup: %d", $2);
 				YYERROR;
 			}
-
 			conf_autogroup(conf, $2, $3);
 			free($3);
 		}
@@ -152,13 +162,23 @@ main		: FONTNAME STRING		{
 			free($3);
 		}
 		| GAP NUMBER NUMBER NUMBER NUMBER {
+			if ($2 < 0 || $3 < 0 || $4 < 0 || $5 < 0) {
+				yyerror("invalid gap: %d %d %d %d",
+				    $2, $3, $4, $5);
+				YYERROR;
+			}
 			conf->gap.top = $2;
 			conf->gap.bottom = $3;
 			conf->gap.left = $4;
 			conf->gap.right = $5;
 		}
 		| MOUSEBIND STRING string	{
-			conf_mousebind(conf, $2, $3);
+			if (!conf_mousebind(conf, $2, $3)) {
+				yyerror("invalid mousebind: %s %s", $2, $3);
+				free($2);
+				free($3);
+				YYERROR;
+			}
 			free($2);
 			free($3);
 		}
@@ -184,20 +204,20 @@ colors		: ACTIVEBORDER STRING {
 			conf->color[CWM_COLOR_BORDER_UNGROUP] = $2;
 		}
 		| MENUBG STRING {
-			free(conf->menucolor[CWM_COLOR_MENU_BG]);
-			conf->menucolor[CWM_COLOR_MENU_BG] = $2;
+			free(conf->color[CWM_COLOR_MENU_BG]);
+			conf->color[CWM_COLOR_MENU_BG] = $2;
 		}
 		| MENUFG STRING {
-			free(conf->menucolor[CWM_COLOR_MENU_FG]);
-			conf->menucolor[CWM_COLOR_MENU_FG] = $2;
+			free(conf->color[CWM_COLOR_MENU_FG]);
+			conf->color[CWM_COLOR_MENU_FG] = $2;
 		}
 		| FONTCOLOR STRING {
-			free(conf->menucolor[CWM_COLOR_MENU_FONT]);
-			conf->menucolor[CWM_COLOR_MENU_FONT] = $2;
+			free(conf->color[CWM_COLOR_MENU_FONT]);
+			conf->color[CWM_COLOR_MENU_FONT] = $2;
 		}
 		| FONTSELCOLOR STRING {
-			free(conf->menucolor[CWM_COLOR_MENU_FONT_SEL]);
-			conf->menucolor[CWM_COLOR_MENU_FONT_SEL] = $2;
+			free(conf->color[CWM_COLOR_MENU_FONT_SEL]);
+			conf->color[CWM_COLOR_MENU_FONT_SEL] = $2;
 		}
 		;
 %%
@@ -210,7 +230,7 @@ struct keywords {
 int
 yyerror(const char *fmt, ...)
 {
-	va_list ap;
+	va_list		 ap;
 
 	file->errors++;
 	va_start(ap, fmt);
@@ -294,8 +314,9 @@ lgetc(int quotec)
 
 	if (quotec) {
 		if ((c = getc(file->stream)) == EOF) {
-			yyerror("reached end of file while parsing quoted string");
-			if (popfile() == EOF)
+			yyerror("reached end of file while parsing "
+			    "quoted string");
+			if (file == topfile || popfile() == EOF)
 				return (EOF);
 			return (quotec);
 		}
@@ -313,7 +334,7 @@ lgetc(int quotec)
 	}
 
 	while (c == EOF) {
-		if (popfile() == EOF)
+		if (file == topfile || popfile() == EOF)
 			return (EOF);
 		c = getc(file->stream);
 	}
@@ -342,11 +363,13 @@ findeol(void)
 	int	c;
 
 	parsebuf = NULL;
-	pushback_index = 0;
 
 	/* skip to either EOF or the first real EOL */
 	while (1) {
-		c = lgetc(0);
+		if (pushback_index)
+			c = pushback_buffer[--pushback_index];
+		else
+			c = lgetc(0);
 		if (c == '\n') {
 			file->lineno++;
 			break;
@@ -447,9 +470,10 @@ nodigits:
 #define allowed_in_string(x) \
 	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
 	x != '{' && x != '}' && x != '<' && x != '>' && \
-	x != '!' && x != '=' && x != '#' && x != ','))
+	x != '!' && x != '=' && x != '/' && x != '#' && \
+	x != ','))
 
-	if (isalnum(c) || c == ':' || c == '_' || c == '*' || c == '/') {
+	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
 		do {
 			*p++ = c;
 			if ((unsigned)(p-buf) >= sizeof(buf)) {
@@ -481,6 +505,7 @@ pushfile(const char *name)
 	nfile->name = xstrdup(name);
 
 	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+		warn("%s", nfile->name);
 		free(nfile->name);
 		free(nfile);
 		return (NULL);
@@ -495,16 +520,15 @@ popfile(void)
 {
 	struct file	*prev;
 
-	if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
 		prev->errors += file->errors;
-		TAILQ_REMOVE(&files, file, entry);
-		fclose(file->stream);
-		free(file->name);
-		free(file);
-		file = prev;
-		return (0);
-	}
-	return (EOF);
+
+	TAILQ_REMOVE(&files, file, entry);
+	fclose(file->stream);
+	free(file->name);
+	free(file);
+	file = prev;
+	return (file ? 0 : EOF);
 }
 
 int
@@ -518,12 +542,12 @@ parse_config(const char *filename, struct conf *xconf)
 		free(conf);
 		return (-1);
 	}
+	topfile = file;
 
 	conf_init(conf);
 
 	yyparse();
 	errors = file->errors;
-	file->errors = 0;
 	popfile();
 
 	if (errors) {
@@ -575,12 +599,9 @@ parse_config(const char *filename, struct conf *xconf)
 		(void)strlcpy(xconf->lockpath, conf->lockpath,
 		    sizeof(xconf->lockpath));
 
-		for (i = 0; i < CWM_COLOR_BORDER_MAX; i++)
+		for (i = 0; i < CWM_COLOR_MAX; i++)
 			xconf->color[i] = conf->color[i];
 
-		for (i = 0; i < CWM_COLOR_MENU_MAX; i++)
-			xconf->menucolor[i] = conf->menucolor[i];
-
 		xconf->font = conf->font;
 	}