shithub: scc

Download patch

ref: c4e05cd31ffe16a2f49bd611d300841ef6435642
parent: 272a09b4b4196efc5b059de9a2b5e82d835c4527
author: Roberto E. Vargas Caballero <[email protected]>
date: Mon Sep 28 11:47:55 EDT 2015

Add flag -I and convert test001.c into an actual "hello world"

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -395,6 +395,7 @@
 extern void icpp(void);
 extern bool cpp(void);
 extern bool expand(char *begin, Symbol *sym);
+extern void incdir(char *dir);
 
 /*
  * Definition of global variables
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -19,6 +19,8 @@
 static unsigned arglen;
 static Symbol *symline, *symfile;
 static unsigned char ifstatus[NR_COND];
+static int ninclude;
+static char **dirinclude;
 
 unsigned cppctx;
 int disexpand;
@@ -358,16 +360,51 @@
 	delmacro(sym);
 }
 
+void
+incdir(char *dir)
+{
+	if (!dir || *dir == '\0')
+		die("incorrect -I flag");
+	++ninclude;
+	dirinclude = xrealloc(dirinclude, sizeof(*dirinclude) * ninclude);
+	dirinclude[ninclude-1] = dir;
+}
+
+static bool
+includefile(char *dir, char *file, size_t filelen)
+{
+	size_t dirlen;
+	char path[FILENAME_MAX];
+
+	if (!dir) {
+		dirlen = 0;
+		if (filelen > FILENAME_MAX-1)
+			return 0;
+	} else {
+		dirlen = strlen(dir);
+		if (dirlen + filelen > FILENAME_MAX-2)
+			return 0;
+		memcpy(path, dir, dirlen);
+		if (dir[dirlen-1] != '/')
+			path[dirlen++] = '/';
+	}
+	memcpy(path+dirlen, file, filelen);
+	path[dirlen + filelen] = '\0';
+
+	return addinput(path);
+}
+
 static void
 include(void)
 {
-	char **bp, *p, file[FILENAME_MAX], path[FILENAME_MAX];
+	char *file, *p, **bp;
+	size_t filelen;
 	static char *sysinclude[] = {
 		PREFIX"/include/",
 		PREFIX"/local/include/",
 		NULL
 	};
-	size_t filelen, dirlen;
+	int n;
 
 	if (cppoff)
 		return;
@@ -380,48 +417,40 @@
 		if ((p = strchr(input->begin, '>')) == NULL)
 			goto bad_include;
 		*p = '\0';
-		if (p - input->begin >= FILENAME_MAX)
-			goto too_long;
-		strcpy(file, input->begin);
+		file = input->begin;
+		filelen = strlen(file);
 		input->begin = input->p = p+1;
-		next();
 		break;
 	case '"':
 		if ((p = strchr(yytext + 1, '"')) == NULL)
 			goto bad_include;
 		*p = '\0';
-		if (p - yytext + 1 >= FILENAME_MAX)
-			goto too_long;
-		strcpy(file, yytext + 1);
-		next();
-		if (addinput(file))
-			return;
+		file = yytext+1;
+		filelen = strlen(file);
+		if (includefile(NULL, file, filelen))
+			goto its_done;
 		break;
 	default:
 		goto bad_include;
 	}
 
-	filelen = strlen(file);
+	n = ninclude;
+	for (bp = dirinclude; n--; ++bp) {
+		if (includefile(*bp, file, filelen))
+			goto its_done;
+	}
 	for (bp = sysinclude; *bp; ++bp) {
-		dirlen = strlen(*bp);
-		if (dirlen + filelen > FILENAME_MAX-1)
-			continue;
-		memcpy(path, *bp, dirlen);
-		memcpy(path+dirlen, file, filelen);
-		if (addinput(path))
-			break;
+		if (includefile(*bp, file, filelen))
+			goto its_done;
 	}
+	cpperror("included file '%s' not found", file);
 
-	if (*bp)
-		cpperror("included file '%s' not found", file);
-
+its_done:
+	next();
 	return;
 
 bad_include:
 	cpperror("#include expects \"FILENAME\" or <FILENAME>");
-	return;
-too_long:
-	cpperror("#include FILENAME too long");
 	return;
 }
 
--- a/cc1/main.c
+++ b/cc1/main.c
@@ -39,6 +39,7 @@
 	atexit(clean);
 
 	for (;;) {
+	nextiter:
 		--argc, ++argv;
 		if (!*argv || argv[0][0] != '-' || argv[0][1] == '-')
 			break;
@@ -50,6 +51,9 @@
 			case 'E':
 				onlycpp = 1;
 				break;
+			case 'I':
+				incdir(cp+1);
+				goto nextiter;
 			case 'o':
 				if (!*++argv || argv[0][0] == '-')
 					usage();
--- a/cc1/tests/chktest.sh
+++ b/cc1/tests/chktest.sh
@@ -30,7 +30,7 @@
 		print $0 >> chk
 	}
 	END {
-		system("../cc1 -w " test " > " out " 2>&1")
+		system("../cc1 -I. -w " test " > " out " 2>&1")
 		cmd="diff -c " chk " " out " >> " err
 		print test >> err
 		print system(cmd) ? "[FAILED]" : "[OK]"
--- /dev/null
+++ b/cc1/tests/stdio.h
@@ -1,0 +1,6 @@
+#ifndef _STDIO_H
+#define _STDIO_H
+
+int printf(const char *fmt, ...);
+
+#endif
--- a/cc1/tests/test001.c
+++ b/cc1/tests/test001.c
@@ -13,7 +13,7 @@
 }
 */
 
-int printf(char *fmt, ...);
+#include <stdio.h>
 
 int
 main(void)