Split up the printout functions into a file of their own.
[smatch.git] / show-parse.c
bloba756e639bc96164d2f06d8583c71ef8541646db0
1 /*
2 * sparse/show-parse.c
4 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
6 * Print out results of parsing for debugging and testing.
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 "scope.h"
21 #include "expression.h"
24 * Symbol type printout. The type system is by far the most
25 * complicated part of C - everything else is trivial.
27 const char *modifier_string(unsigned long mod)
29 static char buffer[100];
30 char *p = buffer;
31 const char *res,**ptr, *names[] = {
32 "auto", "register", "static", "extern",
33 "const", "volatile", "signed", "unsigned",
34 "char", "short", "long", "long",
35 NULL
37 ptr = names;
38 while ((res = *ptr++) != NULL) {
39 if (mod & 1) {
40 char c;
41 *p++ = ' ';
42 while ((c = *res++) != '\0')
43 *p++ = c;
45 mod >>= 1;
47 *p++ = 0;
48 *p++ = 0;
49 return buffer+1;
52 const char *type_string(unsigned int modifiers, struct symbol *sym)
54 if (!sym)
55 return "<notype>";
57 if (sym == &int_type) {
58 if (modifiers & (SYM_CHAR | SYM_SHORT | SYM_LONG))
59 return "";
60 return "int";
62 if (sym == &fp_type)
63 return "float";
64 if (sym == &void_type)
65 return "void";
66 if (sym == &vector_type)
67 return "vector";
68 if (sym == &bad_type)
69 return "bad type";
70 if (sym->token)
71 return show_token(sym->token);
72 return "typedef";
75 static void show_one_symbol(struct symbol *sym, void *sep, int flags)
77 show_symbol(sym);
78 if (!(flags & ITERATE_LAST))
79 printf("%s", (const char *)sep);
82 void show_symbol_list(struct symbol_list *list, const char *sep)
84 symbol_iterate(list, show_one_symbol, (void *)sep);
87 void show_type_list(struct symbol *sym)
89 while (sym) {
90 show_symbol(sym);
91 sym = sym->next;
95 void show_type(struct symbol *sym)
97 struct ctype *ctype = &sym->ctype;
99 if (!sym) {
100 printf(" <typeless>");
101 return;
104 printf("%s", modifier_string(sym->ctype.modifiers));
106 switch (sym->type) {
107 case SYM_PTR:
108 printf("*(");
109 show_type(sym->ctype.base_type);
110 printf(")");
111 break;
113 case SYM_FN:
114 printf("<fn of>(");
115 show_type(sym->ctype.base_type);
116 printf(")(");
117 show_symbol_list(sym->arguments, ", ");
118 printf(")");
119 break;
121 case SYM_ARRAY:
122 printf("<array of>(");
123 show_type(sym->ctype.base_type);
124 printf(")[ ... ]");
125 break;
127 default:
128 printf("%s", type_string(ctype->modifiers, ctype->base_type));
129 break;
133 void show_symbol(struct symbol *sym)
135 if (!sym) {
136 printf("<anon symbol>");
137 return;
139 printf("Symbol %s: ", show_token(sym->token));
140 show_type(sym);
141 switch (sym->type) {
142 case SYM_FN:
143 printf("\n");
144 show_statement(sym->stmt);
145 break;
146 default:
147 break;
153 * Print out a statement
155 void show_statement(struct statement *stmt)
157 if (!stmt) {
158 printf("\t<nostatement>");
159 return;
161 switch (stmt->type) {
162 case STMT_RETURN:
163 printf("\treturn ");
164 show_expression(stmt->expression);
165 break;
166 case STMT_COMPOUND:
167 printf("{\n");
168 if (stmt->syms) {
169 printf("\t");
170 show_symbol_list(stmt->syms, "\n\t");
171 printf("\n\n");
173 show_statement_list(stmt->stmts, ";\n");
174 printf("\n}\n\n");
175 break;
176 case STMT_EXPRESSION:
177 printf("\t");
178 show_expression(stmt->expression);
179 return;
180 case STMT_IF:
181 printf("\tif (");
182 show_expression(stmt->if_conditional);
183 printf(")\n");
184 show_statement(stmt->if_true);
185 if (stmt->if_false) {
186 printf("\nelse\n");
187 show_statement(stmt->if_false);
189 break;
190 case STMT_SWITCH:
191 printf("\tswitch (");
192 show_expression(stmt->switch_expression);
193 printf(")\n");
194 show_statement(stmt->switch_statement);
195 break;
197 case STMT_CASE:
198 if (!stmt->case_expression)
199 printf("default");
200 else {
201 printf("case ");
202 show_expression(stmt->case_expression);
203 if (stmt->case_to) {
204 printf(" ... ");
205 show_expression(stmt->case_to);
208 printf(":");
209 show_statement(stmt->case_statement);
210 break;
212 case STMT_BREAK:
213 printf("\tbreak");
214 break;
216 case STMT_WHILE:
217 printf("\twhile (");
218 show_expression(stmt->e1);
219 printf(")\n");
220 show_statement(stmt->iterate);
221 break;
223 case STMT_DO:
224 printf("\tdo");
225 show_statement(stmt->iterate);
226 printf("\nwhile (");
227 show_expression(stmt->e1);
228 printf(")\n");
229 break;
231 case STMT_FOR:
232 printf("\tfor (" );
233 show_expression(stmt->e1);
234 printf(" ; ");
235 show_expression(stmt->e2);
236 printf(" ; ");
237 show_expression(stmt->e3);
238 printf(")\n");
239 show_statement(stmt->iterate);
240 break;
242 default:
243 printf("WTF");
247 static void show_one_statement(struct statement *stmt, void *sep, int flags)
249 show_statement(stmt);
250 if (!(flags & ITERATE_LAST))
251 printf("%s", (const char *)sep);
254 void show_statement_list(struct statement_list *stmt, const char *sep)
256 statement_iterate(stmt, show_one_statement, (void *)sep);
260 * Print out an expression
262 void show_expression(struct expression *expr)
264 if (!expr)
265 return;
267 printf("< ");
268 switch (expr->type) {
269 case EXPR_BINOP:
270 show_expression(expr->left);
271 printf(" %s ", show_special(expr->op));
272 show_expression(expr->right);
273 break;
274 case EXPR_PREOP:
275 printf("%s<", show_special(expr->op));
276 show_expression(expr->unop);
277 printf(">");
278 break;
279 case EXPR_POSTOP:
280 show_expression(expr->unop);
281 printf(" %s ", show_special(expr->op));
282 break;
283 case EXPR_CONSTANT:
284 printf("%s", show_token(expr->token));
285 break;
286 case EXPR_SYMBOL:
287 if (!expr->symbol) {
288 warn(expr->token, "undefined symbol '%s'", show_token(expr->token));
289 printf("<nosymbol>");
290 break;
292 printf("<%s:", show_token(expr->symbol->token));
293 show_type(expr->symbol);
294 printf(">");
295 break;
296 case EXPR_DEREF:
297 show_expression(expr->deref);
298 printf("%s", show_special(expr->op));
299 printf("%s", show_token(expr->member));
300 break;
301 case EXPR_CAST:
302 printf("<cast>(");
303 show_type(expr->cast_type);
304 printf(")");
305 show_expression(expr->cast_expression);
306 break;
307 default:
308 printf("WTF");
310 printf(" >");