aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@home.transmeta.com>2003-04-07 16:23:10 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:00:20 -0700
commitb23fc8af8e708eaf90ae8b55dad1f5e991360edc (patch)
tree6a645df662ad48e4166f776051cb8d84abd130be
parent80978796514dffe612db7b37088320b4cb91e5bc (diff)
downloadsparse-dev-b23fc8af8e708eaf90ae8b55dad1f5e991360edc.tar.gz
Add "check" program that just evaluates the tree and does nothing
else. This is useful to get warnings from the parser and type evaluator.
-rw-r--r--Makefile5
-rw-r--r--check.c112
2 files changed, 116 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 1f3a5694..8205e97d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
CC=gcc
CFLAGS=-g -Wall
-PROGRAMS=test-lexing test-parsing obfuscate
+PROGRAMS=test-lexing test-parsing obfuscate check
HEADERS=token.h parse.h lib.h symbol.h scope.h expression.h target.h
@@ -19,6 +19,9 @@ test-parsing: test-parsing.o $(COMMON)
obfuscate: obfuscate.o $(COMMON)
gcc -o $@ $< $(COMMON)
+check: check.o $(COMMON)
+ gcc -o $@ $< $(COMMON)
+
evaluate.o: $(HEADERS)
expression.o: $(HEADERS)
lib.o: $(HEADERS)
diff --git a/check.c b/check.c
new file mode 100644
index 00000000..cc6ac664
--- /dev/null
+++ b/check.c
@@ -0,0 +1,112 @@
+/*
+ * Example trivial client program that uses the sparse library
+ * to tokenize, pre-process and parse a C file, and prints out
+ * the results.
+ *
+ * Copyright (C) 2003 Transmeta Corp, all rights reserved.
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "lib.h"
+#include "token.h"
+#include "parse.h"
+#include "symbol.h"
+#include "expression.h"
+
+static unsigned int pre_buffer_size = 0;
+static unsigned char pre_buffer[8192];
+
+static void add_pre_buffer(const char *fmt, ...)
+{
+ va_list args;
+ unsigned int size;
+
+ va_start(args, fmt);
+ size = pre_buffer_size;
+ size += vsnprintf(pre_buffer + size,
+ sizeof(pre_buffer) - size,
+ fmt, args);
+ pre_buffer_size = size;
+ va_end(args);
+}
+
+static void handle_switch(char *arg)
+{
+ switch (*arg) {
+ case 'D': {
+ const char *name = arg+1;
+ const char *value = "";
+ for (;;) {
+ char c;
+ c = *++arg;
+ if (!c)
+ break;
+ if (isspace(c) || c == '=') {
+ *arg = '\0';
+ value = arg+1;
+ break;
+ }
+ }
+ add_pre_buffer("#define %s %s\n", name, value);
+ return;
+ }
+
+ case 'I':
+ add_pre_buffer("#add_include \"%s/\"\n", arg+1);
+ return;
+ default:
+ fprintf(stderr, "unknown switch '%s'\n", arg);
+ }
+}
+
+static void clean_up_symbol(struct symbol *sym, void *_parent, int flags)
+{
+ evaluate_symbol(sym);
+}
+
+int main(int argc, char **argv)
+{
+ int i, fd;
+ char *filename = NULL;
+ struct token *token;
+
+ // Initialize symbol stream first, so that we can add defines etc
+ init_symbols();
+
+ for (i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ if (arg[0] == '-') {
+ handle_switch(arg+1);
+ continue;
+ }
+ filename = arg;
+ }
+
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ die("No such file: %s", argv[1]);
+
+ // Tokenize the input stream
+ token = tokenize(filename, fd, NULL);
+ close(fd);
+
+ // Prepend the initial built-in stream
+ token = tokenize_buffer(pre_buffer, pre_buffer_size, token);
+
+ // Pre-process the stream
+ token = preprocess(token);
+
+ // Parse the resulting C code
+ translation_unit(token, &used_list);
+
+ // Do type evaluation and simplify
+ symbol_iterate(used_list, clean_up_symbol, NULL);
+ return 0;
+}