Adpated to changes in libcore
[libfirm] / ir / ir / irargs.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irargs.c
4  * Purpose:     Support for libcore IR object output.
5  * Author:      Sebastian Hack
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2005 Universitaet Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include "bitset.h"
18
19 #include <ctype.h>
20 #include <libcore/lc_printf.h>
21
22 #include "firm_common.h"
23 #include "irnode_t.h"
24 #include "entity_t.h"
25 #include "irloop_t.h"
26 #include "tv_t.h"
27 #include "dbginfo_t.h"
28
29 /**
30  * identify a firm object type
31  */
32 static int firm_get_lc_arg_type(const lc_arg_occ_t *occ) {
33   /* Firm objects are always pointer */
34   return lc_arg_type_ptr;
35 }
36
37 static int firm_get_lc_arg_type_int(const lc_arg_occ_t *occ) {
38   return lc_arg_type_int;
39 }
40
41
42 static int bitset_get_lc_arg_type(const lc_arg_occ_t *occ) {
43   return lc_arg_type_ptr;
44 }
45
46 static int bitset_emit(lc_appendable_t *app,
47     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
48 {
49   int res = 2;
50   bitset_t *b = arg->v_ptr;
51   bitset_pos_t p;
52   char buf[32];
53   const char *prefix = "";
54
55   lc_arg_append(app, occ, "[", 1);
56   for(p = bitset_next_set(b, 0); p != -1; p = bitset_next_set(b, p)) {
57     int n;
58
59     n = snprintf(buf, sizeof(buf), "%s%d", prefix, (int) p);
60     lc_arg_append(app, occ, buf, n);
61     prefix = ", ";
62     res += n;
63   }
64   lc_arg_append(app, occ, "]", 1);
65
66   return res;
67 }
68
69 /**
70  * emit an opaque Firm dbg_info object
71  */
72 static int firm_emit_dbg(lc_appendable_t *app,
73     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
74 {
75   char buf[1024];
76   ir_node *irn = arg->v_ptr;
77   dbg_info *dbg = get_irn_dbg_info(irn);
78
79   buf[0] = '\0';
80   if (dbg && __dbg_info_snprint) {
81     if (__dbg_info_snprint(buf, sizeof(buf), dbg) <= 0)
82       buf[0] = '\0';
83   }
84   return lc_arg_append(app, occ, buf, strlen(buf));
85 }
86
87 /**
88  * emit a Firm object
89  */
90 static int firm_emit(lc_appendable_t *app,
91     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
92 {
93 #define A(s)    occ->flag_hash ? s " ": ""
94
95   void *X = arg->v_ptr;
96   firm_kind *obj = X;
97   int i, n;
98   ir_node *block;
99   char add[64];
100   char buf[256];
101   char tv[256];
102
103   buf[0] = '\0';
104   add[0] = '\0';
105
106   if (! X)
107     strncpy(buf, "(null)", sizeof(buf));
108   else {
109     switch (*obj) {
110     case k_BAD:
111       snprintf(buf, sizeof(buf), "BAD");
112       snprintf(add, sizeof(add), "[%p]", X);
113       break;
114     case k_entity:
115       snprintf(buf, sizeof(buf), "%s%s", A("ent"),
116           isupper(occ->conversion) ? get_entity_ld_name(X): get_entity_name(X));
117       snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
118       break;
119     case k_type:
120       snprintf(buf, sizeof(buf), "%s%s:%s", A("type"), get_type_tpop_name(X), get_type_name(X));
121       snprintf(add, sizeof(add), "[%ld]", get_type_nr(X));
122       break;
123     case k_ir_graph:
124       snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
125       snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
126       break;
127     case k_ir_node:
128       switch (occ->conversion) {
129       case 'B':
130         block = is_no_Block(X) ? get_nodes_block(X) : X;
131         snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(block),
132             get_mode_name(get_irn_mode(block)));
133         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(block));
134         break;
135       case 'N':
136         snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
137         break;
138       default:
139         if (is_Const(X)) {
140           tarval_snprintf(tv, sizeof(tv), get_Const_tarval(X));
141           snprintf(buf, sizeof(buf), "%s%s%s<%s>", A("irn"), get_irn_opname(X),
142             get_mode_name(get_irn_mode(X)), tv);
143         }
144         else
145           snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
146             get_mode_name(get_irn_mode(X)));
147         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(X));
148       }
149       break;
150     case k_ir_mode:
151       snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
152       break;
153     case k_tarval:
154       tarval_snprintf(tv, sizeof(tv), X);
155       snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv);
156       break;
157     case k_ir_loop:
158       snprintf(buf, sizeof(buf), "ldepth[%d]", get_loop_depth(X));
159       break;
160     case k_ir_op:
161       snprintf(buf, sizeof(buf), "%s%s", A("op"), get_op_name(X));
162       break;
163     case k_ir_compound_graph_path:
164       strncat(buf, A("cgp"), sizeof(buf));
165
166       n = get_compound_graph_path_length(X);
167       for (i = 0; i < n; ++i) {
168         entity *ent = get_compound_graph_path_node(X, i);
169         strncat(buf, get_entity_name(ent), sizeof(buf));
170         if (i < n - 1)
171           strncat(buf, ".", sizeof(buf));
172       }
173       break;
174     default:
175       snprintf(buf, sizeof(buf), "UNKWN");
176       snprintf(add, sizeof(add), "[%p]", X);
177     }
178   }
179
180   if(occ->flag_plus)
181         strncat(buf, add, sizeof(buf));
182
183   return lc_arg_append(app, occ, buf, strlen(buf));
184
185 #undef A
186 }
187
188 /**
189  * emit an ident
190  */
191 static int firm_emit_ident(lc_appendable_t *app,
192     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
193 {
194   ident *id = (ident *)arg->v_ptr;
195   const char *p = id ? get_id_str(id) : "(null)";
196
197   return lc_arg_append(app, occ, p, strlen(p));
198 }
199
200 /**
201  * Emit indent.
202  */
203 static int firm_emit_indent(lc_appendable_t *app,
204     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
205 {
206         int i;
207         int amount = arg->v_int;
208
209         for(i = 0; i < amount; ++i)
210                 lc_appendable_chadd(app, ' ');
211
212         return amount;
213 }
214
215 /**
216  * Emit pnc.
217  */
218 static int firm_emit_pnc(lc_appendable_t *app,
219     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
220 {
221   int value = arg->v_int;
222   const char *p = get_pnc_string(value);
223
224   return lc_arg_append(app, occ, p, strlen(p));
225 }
226
227 lc_arg_env_t *firm_get_lc_arg_env(void)
228 {
229 #define X(name, letter) {"firm:" name, letter}
230
231   static lc_arg_env_t *env = NULL;
232
233   static lc_arg_handler_t firm_handler   = { firm_get_lc_arg_type, firm_emit };
234   static lc_arg_handler_t ident_handler  = { firm_get_lc_arg_type, firm_emit_ident };
235   static lc_arg_handler_t indent_handler = { firm_get_lc_arg_type_int, firm_emit_indent };
236   static lc_arg_handler_t pnc_handler    = { firm_get_lc_arg_type_int, firm_emit_pnc };
237   static lc_arg_handler_t bitset_handler = { bitset_get_lc_arg_type, bitset_emit };
238   static lc_arg_handler_t debug_handler  = { firm_get_lc_arg_type, firm_emit_dbg };
239
240   static struct {
241     const char *name;
242     char letter;
243   } args[] = {
244     X("type",      't'),
245     X("entity",    'e'),
246     X("entity_ld", 'E'),
247     X("tarval",    'T'),
248     X("irn",       'n'),
249     X("op",        'O'),
250     X("irn_nr",    'N'),
251     X("mode",      'm'),
252     X("block",     'B'),
253     X("pnc",       '='),
254   };
255
256   int i;
257
258   if(env == NULL) {
259     env = lc_arg_new_env();
260     lc_arg_add_std(env);
261
262     lc_arg_register(env, "firm", 'F', &firm_handler);
263     for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
264       lc_arg_register(env, args[i].name, args[i].letter, &firm_handler);
265
266     lc_arg_register(env, "firm:ident", 'I', &ident_handler);
267     lc_arg_register(env, "firm:indent", 'D', &indent_handler);
268     lc_arg_register(env, "firm:pnc",      '=', &pnc_handler);
269     lc_arg_register(env, "firm:dbg_info", 'g', &debug_handler);
270     /* lc_arg_register(env, "firm:bitset", 'b', &bitset_handler); */
271   }
272
273   return env;
274 }