shithub: scc

Download patch

ref: 47c4f8aebf11f33fa841c25d85ab33410668ea24
parent: e56b22693ff12207d5106ed3c9aab1ba77cbb096
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Jan 19 09:06:30 EST 2016

Add initializators from strings

There are two cases of initializators in this case,
iniitializator of array of char, and initializators of
pointers to char. In this case we are dealing with array
initializators.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -341,6 +341,7 @@
 extern void killsym(Symbol *sym);
 extern Symbol *newlabel(void);
 extern void keywords(struct keyword *key, int ns);
+extern Symbol *newstring(char *s, size_t len);
 
 /* stmt.c */
 extern void compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
--- a/cc1/init.c
+++ b/cc1/init.c
@@ -91,14 +91,36 @@
 static Node *
 initialize(Type *tp)
 {
-	Node *np;
+	Node *np, *aux;
+	Symbol *sym;
+	Type *btp;
+	size_t len;
 
-	np = (accept('{')) ? initlist(tp) : decay(assign());
-	if ((np = convert(np, tp, 0)) == NULL) {
-		errorp("incorrect initializer");
-		np = constnode(zero);
+	np = (accept('{')) ? initlist(tp) : assign();
+	sym = np->sym;
+	if (sym && (sym->flags & ISSTRING) != 0 && tp->op == ARY) {
+		btp = tp->type;
+		if (btp != chartype && btp != uchartype && btp != schartype) {
+			errorp("array of inappropriate type initialized from string constant");
+			goto return_zero;
+		}
+		len = strlen(sym->u.s);
+		if (!tp->defined) {
+			tp->defined = 1;
+			tp->n.elem = len;
+		} else if (tp->n.elem < len) {
+			warn("initializer-string for array of chars is too long");
+			np->sym = newstring(sym->u.s, tp->n.elem);
+		}
+
+		return np;
 	}
-	return np;
+	if ((aux = convert(decay(np), tp, 0)) != NULL)
+		return aux;
+
+	errorp("incorrect initializer");
+return_zero:
+	return constnode(zero);
 }
 
 static Node *
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -483,10 +483,7 @@
 	*bp = '\0';
 
 	yylen = bp - yytext + 1;
-	yylval.sym = newsym(NS_IDEN);
-	yylval.sym->flags |= ISSTRING | ISCONSTANT;
-	yylval.sym->u.s = xstrdup(yytext+1);
-	yylval.sym->type = mktype(chartype, ARY, yylen - 2, NULL);
+	yylval.sym = newstring(yytext+1, yylen-2);
 	*bp++ = '"';
 	*bp = '\0';
 	return CONSTANT;
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
@@ -226,6 +226,18 @@
 }
 
 Symbol *
+newstring(char *s, size_t len)
+{
+	Symbol *sym = newsym(NS_IDEN);
+
+	sym->flags |= ISSTRING | ISCONSTANT;
+	sym->u.s = xmalloc(len);
+	memcpy(sym->u.s, s, len);
+	sym->type = mktype(chartype, ARY, len, NULL);
+	return sym;
+}
+
+Symbol *
 newlabel(void)
 {
 	Symbol *sym = newsym(NS_LABEL);