From 5e81570b16fb7fe35f4f1fcca6b14fdf308780e6 Mon Sep 17 00:00:00 2001 From: Sebastian Hack Date: Mon, 29 Nov 2004 10:35:30 +0000 Subject: [PATCH] Added printf style dumping facility for firm types. [r4488] --- ir/ir/Makefile.in | 4 +- ir/ir/irprintf.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++ ir/ir/irprintf.h | 38 ++++++++++ 3 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 ir/ir/irprintf.c create mode 100644 ir/ir/irprintf.h diff --git a/ir/ir/Makefile.in b/ir/ir/Makefile.in index bfc5b69f7..7b9bf92bf 100644 --- a/ir/ir/Makefile.in +++ b/ir/ir/Makefile.in @@ -17,7 +17,7 @@ subdir := ir/ir INSTALL_HEADERS = irprog.h irgraph.h irnode.h irmode.h irop.h ircons.h \ irflag.h irvrfy.h irgwalk.h irgmod.h iropt.h irdump.h \ - irgopt.h ircgcons.h ircgopt.h irreflect.h irarch.h + irgopt.h ircgcons.h ircgopt.h irreflect.h irarch.h irprintf.h SOURCES = $(INSTALL_HEADERS) @@ -25,7 +25,7 @@ SOURCES += Makefile.in \ ircons.c ircons_t.h irgmod.c irgraph_t.h irnode.c iropt.c iropt_t.h irvrfy.c \ irgwalk.c irgwalk_blk.c irdump.c irdumptxt.c irgopt.c irgopt_t.h irnode_t.h \ irmode.c irop.c irprog.c irflag.c irflag_t.h irgraph.c \ - irmode_t.h irop_t.h irprog_t.h ircgcons.c ircgopt.c irreflect.c irarch.c + irmode_t.h irop_t.h irprog_t.h ircgcons.c ircgopt.c irreflect.c irarch.c irprintf.c include $(topdir)/MakeRules diff --git a/ir/ir/irprintf.c b/ir/ir/irprintf.c new file mode 100644 index 000000000..c610b379e --- /dev/null +++ b/ir/ir/irprintf.c @@ -0,0 +1,173 @@ +/** + * A little printf helper funterstanding firm types. + * @author Sebastian Hack + * @date 29.11.2004 + */ + +#include +#include +#include + +#include "irmode.h" +#include "irnode.h" +#include "tv.h" +#include "irprintf.h" + +/** + * Something that can append strings and chars to somewhere. + */ +typedef struct _appender_t { + void (*append_char)(void *subject, size_t n, char ch); + void (*append_str)(void *subject, size_t n, const char *str); +} appender_t; + +static void str_append_char(void *subject, size_t n, char ch) +{ + char buf[2]; + + buf[0] = ch; + buf[1] = 0; + + strncat(subject, buf, n); +} + +static void str_append_str(void *subject, size_t n, const char *str) +{ + strncat(subject, str, n); +} + +static void file_append_char(void *subject, size_t n, char ch) +{ + fputc(ch, subject); +} + +static void file_append_str(void *subject, size_t n, const char *str) +{ + fputs(str, subject); +} + +static const appender_t file_appender = { + file_append_char, + file_append_str +}; + +static const appender_t str_appender = { + str_append_char, + str_append_str +}; + + +/** + * A small printf helper routine for ir nodes. + * @param app An appender (this determines where the stuff is dumped + * to). + * @param subject A target passed to the appender. + * @param limit The maximum number of characters to dump. + * @param fmt The format string. + * @param args A va_list. + */ +static void ir_common_vprintf(const appender_t *app, void *subject, + size_t limit, const char *fmt, va_list args) +{ + char buf[256]; + int i, n; + +#define DUMP_STR(s) app->append_str(subject, limit, s) +#define DUMP_CH(ch) app->append_char(subject, limit, ch) + + for(i = 0, n = strlen(fmt); i < n; ++i) { + char ch = fmt[i]; + + if(ch == '%') { + char next_ch = fmt[++i]; + + /* Clear the temporary buffer */ + buf[0] = '\0'; + + switch(next_ch) { + case '%': + DUMP_CH('%'); + break; + case 's': + DUMP_STR(va_arg(args, const char *)); + break; + + case 'p': + snprintf(buf, sizeof(buf), "%p", va_arg(args, void *)); + break; + + case 't': + tarval_snprintf(buf, sizeof(buf), va_arg(args, tarval *)); + break; + + case 'N': + { + ir_node *irn = va_arg(args, ir_node *); + snprintf(buf, sizeof(buf), "%s%s:%ld", + get_irn_opname(irn), get_mode_name(get_irn_mode(irn)), get_irn_node_nr(irn)); + } + break; + + case 'o': + DUMP_STR(get_irn_opname(va_arg(args, ir_node *))); + break; + + case 'n': + snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(va_arg(args, ir_node *))); + break; + + case 'm': + DUMP_STR(get_mode_name(va_arg(args, ir_mode *))); + break; + + case 'b': + snprintf(buf, sizeof(buf), "%ld", + get_irn_node_nr(get_nodes_block(va_arg(args, ir_node *)))); + break; + } + + /* Dump the temporary buffer, if something is in it. */ + if(buf[0] != '\0') + DUMP_STR(buf); + } + + else + DUMP_CH(ch); + } + +#undef DUMP_STR +#undef DUMP_CH +} + +/** + * Convencience for stdout dumping. + */ +void ir_printf(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + ir_common_vprintf(&file_appender, stdout, 0, fmt, args); + va_end(args); +} + +/** + * Convencience for file dumping. + */ +void ir_fprintf(FILE *f, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + ir_common_vprintf(&file_appender, f, 0, fmt, args); + va_end(args); +} + +/** + * Convencience for string dumping. + */ +void ir_snprintf(char *buf, size_t len, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + ir_common_vprintf(&str_appender, buf, len, fmt, args); + va_end(args); +} diff --git a/ir/ir/irprintf.h b/ir/ir/irprintf.h new file mode 100644 index 000000000..e471629d6 --- /dev/null +++ b/ir/ir/irprintf.h @@ -0,0 +1,38 @@ +/** + * A little printf understanding some firm types. + * @author Sebastian Hack + * @date 29.11.2004 + */ + +#ifndef _IRPRINTF_H +#define _IRPRINTF_H + +/** + * A string formatting routine for ir nodes. + * This function rudimentarily implements a kind of printf(3) for ir + * nodes. Following conversion specifiers. No length, special or field + * width specifiers are accepted. + * - %p A pointer. + * - %s A string. + * - %N A full description of a node. + * - %o The opcode name of an ir node. + * - %m The mode name of an ir mode. + * - %n The node number of an ir node. + * - %b The block node number of the nodes block. + * - %t A tarval. + * + * @param fmt The format string. + */ +void ir_printf(const char *fmt, ...); + +/** + * @see irn_printf. + */ +void ir_fprintf(FILE *f, const char *fmt, ...); + +/** + * @see irn_printf. + */ +void ir_snprintf(char *buf, size_t n, const char *fmt, ...); + +#endif -- 2.20.1