commit c4e05cd31ffe16a2f49bd611d300841ef6435642
parent 272a09b4b4196efc5b059de9a2b5e82d835c4527
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Mon, 28 Sep 2015 15:47:55 +0200
Add flag -I and convert test001.c into an actual "hello world"
Diffstat:
6 files changed, 68 insertions(+), 28 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -395,6 +395,7 @@ extern void initializer(Symbol *sym, Type *tp, int nelem);
extern void icpp(void);
extern bool cpp(void);
extern bool expand(char *begin, Symbol *sym);
+extern void incdir(char *dir);
/*
* Definition of global variables
diff --git a/cc1/cpp.c b/cc1/cpp.c
@@ -19,6 +19,8 @@ static char *argp, *macroname;
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 @@ delete:
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,49 +417,41 @@ include(void)
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;
}
static void
diff --git a/cc1/main.c b/cc1/main.c
@@ -39,6 +39,7 @@ main(int argc, char *argv[])
atexit(clean);
for (;;) {
+ nextiter:
--argc, ++argv;
if (!*argv || argv[0][0] != '-' || argv[0][1] == '-')
break;
@@ -50,6 +51,9 @@ main(int argc, char *argv[])
case 'E':
onlycpp = 1;
break;
+ case 'I':
+ incdir(cp+1);
+ goto nextiter;
case 'o':
if (!*++argv || argv[0][0] == '-')
usage();
diff --git a/cc1/tests/chktest.sh b/cc1/tests/chktest.sh
@@ -30,7 +30,7 @@ do
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]"
diff --git a/cc1/tests/stdio.h b/cc1/tests/stdio.h
@@ -0,0 +1,6 @@
+#ifndef _STDIO_H
+#define _STDIO_H
+
+int printf(const char *fmt, ...);
+
+#endif
diff --git a/cc1/tests/test001.c b/cc1/tests/test001.c
@@ -13,7 +13,7 @@ G6 F5 main
}
*/
-int printf(char *fmt, ...);
+#include <stdio.h>
int
main(void)