The C type part and the preprocessor part of a symbol are supposed
[smatch.git] / check.c
blob67f3475813051f4ee5511a6a54173c0582a1bc73
1 /*
2 * Example trivial client program that uses the sparse library
3 * to tokenize, pre-process and parse a C file, and prints out
4 * the results.
6 * Copyright (C) 2003 Transmeta Corp, all rights reserved.
7 */
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <unistd.h>
14 #include <fcntl.h>
16 #include "lib.h"
17 #include "token.h"
18 #include "parse.h"
19 #include "symbol.h"
20 #include "expression.h"
22 static unsigned int pre_buffer_size = 0;
23 static unsigned char pre_buffer[8192];
25 static void add_pre_buffer(const char *fmt, ...)
27 va_list args;
28 unsigned int size;
30 va_start(args, fmt);
31 size = pre_buffer_size;
32 size += vsnprintf(pre_buffer + size,
33 sizeof(pre_buffer) - size,
34 fmt, args);
35 pre_buffer_size = size;
36 va_end(args);
39 static void handle_switch(char *arg)
41 switch (*arg) {
42 case 'D': {
43 const char *name = arg+1;
44 const char *value = "";
45 for (;;) {
46 char c;
47 c = *++arg;
48 if (!c)
49 break;
50 if (isspace(c) || c == '=') {
51 *arg = '\0';
52 value = arg+1;
53 break;
56 add_pre_buffer("#define %s %s\n", name, value);
57 return;
60 case 'I':
61 add_pre_buffer("#add_include \"%s/\"\n", arg+1);
62 return;
63 default:
64 fprintf(stderr, "unknown switch '%s'\n", arg);
68 static void clean_up_symbol(struct symbol *sym, void *_parent, int flags)
70 evaluate_symbol(sym);
73 int main(int argc, char **argv)
75 int i, fd;
76 char *filename = NULL;
77 struct token *token;
79 // Initialize symbol stream first, so that we can add defines etc
80 init_symbols();
82 add_pre_buffer("#define __CHECKER__ 1\n");
83 add_pre_buffer("#nostdinc\n");
84 add_pre_buffer("#add_include \"/home/torvalds/v2.5/linux/include/\"\n");
85 add_pre_buffer("#add_include \"/home/torvalds/v2.5/linux/include/asm-i386/mach-default/\"\n");
86 add_pre_buffer("#add_include \"/home/torvalds/v2.5/linux/arch/i386/mach-default/\"\n");
87 add_pre_buffer("#add_include \"\"\n");
88 add_pre_buffer("#define __KERNEL__\n");
89 add_pre_buffer("#define __GNUC__ 2\n");
90 add_pre_buffer("#define __GNUC_MINOR__ 95\n");
91 add_pre_buffer("#define __builtin_constant_p(x) 0\n");
92 add_pre_buffer("#define __func__ \"function\"\n");
95 for (i = 1; i < argc; i++) {
96 char *arg = argv[i];
97 if (arg[0] == '-') {
98 handle_switch(arg+1);
99 continue;
101 filename = arg;
105 fd = open(filename, O_RDONLY);
106 if (fd < 0)
107 die("No such file: %s", argv[1]);
109 // Tokenize the input stream
110 token = tokenize(filename, fd, NULL);
111 close(fd);
113 // Prepend the initial built-in stream
114 token = tokenize_buffer(pre_buffer, pre_buffer_size, token);
116 // Pre-process the stream
117 token = preprocess(token);
119 // Parse the resulting C code
120 translation_unit(token, &used_list);
122 // Do type evaluation and simplify
123 symbol_iterate(used_list, clean_up_symbol, NULL);
124 return 0;