2 * Example trivial client program that uses the sparse library
3 * to tokenize, pre-process and parse a C file, and prints out
6 * Copyright (C) 2003 Transmeta Corp.
8 * Licensed under the Open Software License version 1.1
22 #include "expression.h"
24 static unsigned int pre_buffer_size
= 0;
25 static unsigned char pre_buffer
[8192];
27 static int preprocess_only
;
28 static char *include
= NULL
;
29 static int include_fd
= -1;
31 static void add_pre_buffer(const char *fmt
, ...)
37 size
= pre_buffer_size
;
38 size
+= vsnprintf(pre_buffer
+ size
,
39 sizeof(pre_buffer
) - size
,
41 pre_buffer_size
= size
;
45 static char ** handle_switch(char *arg
, char **next
)
49 const char *name
= arg
+1;
50 const char *value
= "";
56 if (isspace(c
) || c
== '=') {
62 add_pre_buffer("#define %s %s\n", name
, value
);
73 add_pre_buffer("#add_include \"%s/\"\n", arg
+1);
76 if (*next
&& !strcmp(arg
, "include")) {
78 int fd
= open(name
, O_RDONLY
);
87 /* Ignore unknown command line options - they're probably gcc switches */
93 static void clean_up_symbol(struct symbol
*sym
, void *_parent
, int flags
)
95 check_duplicates(sym
);
99 int main(int argc
, char **argv
)
102 char *filename
= NULL
, **args
;
105 // Initialize symbol stream first, so that we can add defines etc
108 add_pre_buffer("#define __i386__ 1\n");
109 add_pre_buffer("#define __linux__ 1\n");
110 add_pre_buffer("#define __STDC__ 1\n");
111 add_pre_buffer("#define linux linux\n");
112 add_pre_buffer("#define __CHECKER__ 1\n");
113 add_pre_buffer("#define cond_syscall(x)\n");
114 add_pre_buffer("#define __GNUC__ 2\n");
115 add_pre_buffer("#define __GNUC_MINOR__ 95\n");
116 add_pre_buffer("#define __func__ \"function\"\n");
117 add_pre_buffer("#define __extension__\n");
118 add_pre_buffer("#define __pragma__\n");
119 add_pre_buffer("extern void *__builtin_memcpy(void *, const void *, unsigned long);\n");
120 add_pre_buffer("extern void * __builtin_return_address(int);\n");
121 add_pre_buffer("#define __builtin_stdarg_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n");
122 add_pre_buffer("#define __builtin_va_arg(arg,type) ((type)0)\n");
123 add_pre_buffer("#define __builtin_va_end(arg)\n");
131 args
= handle_switch(arg
+1, args
);
138 fd
= open(filename
, O_RDONLY
);
140 die("No such file: %s", filename
);
142 // Tokenize the input stream
143 token
= tokenize(filename
, fd
, NULL
);
146 // Prepend any "include" file to the stream.
148 token
= tokenize(include
, include_fd
, token
);
150 // Prepend the initial built-in stream
151 token
= tokenize_buffer(pre_buffer
, pre_buffer_size
, token
);
153 // Pre-process the stream
154 token
= preprocess(token
);
156 if (preprocess_only
) {
157 while (!eof_token(token
)) {
159 struct token
*next
= token
->next
;
160 char * separator
= "";
161 if (next
->pos
.whitespace
)
163 if (next
->pos
.newline
) {
164 separator
= "\n\t\t\t\t\t";
165 prec
= next
->pos
.pos
;
169 printf("%s%.*s", show_token(token
), prec
, separator
);
177 // Parse the resulting C code
178 translation_unit(token
, &used_list
);
180 // Do type evaluation and simplify
181 symbol_iterate(used_list
, clean_up_symbol
, NULL
);