X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Flibcore%2Flc_printf.c;h=416fc664fa8f1fec27a834973a19bff17247d3b1;hb=2f8553d98a05815a9d24eb5746cab1e17858a2a0;hp=458d3dcf7c2369a7a42fbc196fd9fae9cfb50746;hpb=bb9f2e36362333c6635b89f5258171b06c786608;p=libfirm diff --git a/ir/libcore/lc_printf.c b/ir/libcore/lc_printf.c index 458d3dcf7..416fc664f 100644 --- a/ir/libcore/lc_printf.c +++ b/ir/libcore/lc_printf.c @@ -33,27 +33,26 @@ #include #include -#include "lc_common_t.h" #include "xmalloc.h" #include "lc_printf.h" -#include "lc_defines.h" #include "hashptr.h" +#include "util.h" #include "set.h" /* printf implementation */ -typedef struct _lc_arg_t { - struct _lc_arg_t *next; +typedef struct lc_arg_t { + struct lc_arg_t *next; const char *name; char letter; int lc_arg_type; const lc_arg_handler_t *handler; } lc_arg_t; -struct _lc_arg_env_t { - set *args; /**< Map for named arguments. */ - lc_arg_t *lower[26]; /**< Map for lower conversion specifiers. */ - lc_arg_t *upper[26]; /**< Map for upper conversion specifiers. */ +struct lc_arg_env_t { + set *args; /**< Map for named arguments. */ + lc_arg_t *lower[26]; /**< Map for lower conversion specifiers. */ + lc_arg_t *upper[26]; /**< Map for upper conversion specifiers. */ }; /** The default argument environment. */ @@ -61,7 +60,7 @@ static lc_arg_env_t *default_env = NULL; static inline lc_arg_env_t *_lc_arg_get_default_env(void) { - if(!default_env) + if (!default_env) default_env = lc_arg_add_std(lc_arg_new_env()); return default_env; @@ -72,10 +71,11 @@ lc_arg_env_t *lc_arg_get_default_env(void) return _lc_arg_get_default_env(); } -static int lc_arg_cmp(const void *p1, const void *p2, UNUSED(size_t size)) +static int lc_arg_cmp(const void *p1, const void *p2, size_t size) { - const lc_arg_t *a1 = p1; - const lc_arg_t *a2 = p2; + const lc_arg_t *a1 = (const lc_arg_t*)p1; + const lc_arg_t *a2 = (const lc_arg_t*)p2; + (void) size; return strcmp(a1->name, a2->name); } @@ -104,25 +104,27 @@ int lc_arg_register(lc_arg_env_t *env, const char *name, char letter, const lc_a arg.letter = letter; arg.handler = handler; - if(isupper(letter)) { + if (isupper((unsigned char)letter)) { map = env->upper; base = 'A'; } - else if(islower(letter)) { + else if (islower((unsigned char)letter)) { map = env->lower; base = 'a'; } - ent = set_insert(env->args, &arg, sizeof(arg), HASH_STR(name, strlen(name))); + ent = set_insert(lc_arg_t, env->args, &arg, sizeof(arg), hash_str(name)); - if(ent && base != 0) + if (ent && base != 0) map[letter - base] = ent; return ent != NULL; } -void lc_arg_unregister(UNUSED(lc_arg_env_t *env), UNUSED(const char *name)) +void lc_arg_unregister(lc_arg_env_t *env, const char *name) { + (void) env; + (void) name; } int lc_arg_append(lc_appendable_t *app, const lc_arg_occ_t *occ, const char *str, size_t len) @@ -131,10 +133,10 @@ int lc_arg_append(lc_appendable_t *app, const lc_arg_occ_t *occ, const char *str /* Set the padding to zero, if the zero is given and we are not left * justified. (A minus overrides the zero). See printf(3). */ - if(!occ->flag_minus && occ->flag_zero) + if (!occ->flag_minus && occ->flag_zero) pad = '0'; - return lc_appendable_snwadd(app, str, len, LC_MAX(0, occ->width), occ->flag_minus, pad); + return lc_appendable_snwadd(app, str, len, MAX(0, occ->width), occ->flag_minus, pad); } @@ -143,8 +145,8 @@ static int dispatch_snprintf(char *buf, size_t len, const char *fmt, { int res = 0; - switch(lc_arg_type) { -#define LC_ARG_TYPE(type,name) \ + switch (lc_arg_type) { +#define LC_ARG_TYPE(type,name,va_type) \ case lc_arg_type_ ## name: res = snprintf(buf, len, fmt, val->v_ ## name); break; #include "lc_printf_arg_types.def" #undef LC_ARG_TYPE @@ -162,16 +164,55 @@ static char *make_fmt(char *buf, size_t len, const lc_arg_occ_t *occ) prec[0] = '\0'; width[0] = '\0'; - if(occ->precision > 0) + if (occ->precision > 0) snprintf(prec, sizeof(prec), ".%d", occ->precision); - if(occ->width > 0) + if (occ->width > 0) snprintf(width, sizeof(width), "%d", occ->width); assert(occ->modifier && "modifier must not be NULL"); strncpy(mod, occ->modifier, sizeof(mod) - 1); - mod[LC_MIN(sizeof(mod) - 1, occ->modifier_length)] = '\0'; - + mod[MIN(sizeof(mod) - 1, occ->modifier_length)] = '\0'; + +#ifdef _MSC_VER + /* work-around for buggy mscrt not supporting z, j, and t modifier */ + if (occ->modifier_length == 1) { + if (mod[0] == 'z') { + if (sizeof(size_t) == sizeof(int)) + mod[0] = '\0'; + if (sizeof(size_t) == sizeof(__int64)) { + mod[0] = 'I'; + mod[1] = '6'; + mod[2] = '4'; + mod[3] = '\0'; + } + } else if (mod[0] == 't') { + if (sizeof(ptrdiff_t) == sizeof(int)) + mod[0] = '\0'; + if (sizeof(ptrdiff_t) == sizeof(__int64)) { + mod[0] = 'I'; + mod[1] = '6'; + mod[2] = '4'; + mod[3] = '\0'; + } + } else if (mod[0] == 'j') { + if (sizeof(intmax_t) == sizeof(int)) + mod[0] = '\0'; + if (sizeof(intmax_t) == sizeof(__int64)) { + mod[0] = 'I'; + mod[1] = '6'; + mod[2] = '4'; + mod[3] = '\0'; + } + } + } else if (occ->modifier_length == 2) { + if (mod[0] == 'h' && mod[1] == 'h') { + /* no support for char in mscrt, but we can safely ignore it + * because the size is handled by the argument reader code */ + mod[0] = '\0'; + } + } +#endif snprintf(buf, len, "%%%s%s%s%s%s%s%s%s%c", occ->flag_space ? "#" : "", occ->flag_hash ? "#" : "", @@ -189,20 +230,20 @@ static char *make_fmt(char *buf, size_t len, const lc_arg_occ_t *occ) */ static int std_get_lc_arg_type(const lc_arg_occ_t *occ) { - int modlen = occ->modifier_length; + size_t modlen = occ->modifier_length; /* check, if the type can be derived from the modifier */ if (modlen > 0) { const char *mod = occ->modifier; switch (mod[0]) { + case 'h': + return modlen > 1 && mod[1] == 'h' ? lc_arg_type_char : lc_arg_type_short; case 'l': return modlen > 1 && mod[1] == 'l' ? lc_arg_type_long_long : lc_arg_type_long; -#define TYPE_CASE(letter,type) case letter: return lc_arg_type_ ## type; -#if 0 +#define TYPE_CASE(letter,type) case letter: return lc_arg_type_ ## type TYPE_CASE('j', intmax_t); TYPE_CASE('z', size_t); TYPE_CASE('t', ptrdiff_t); -#endif TYPE_CASE('L', long_double); #undef TYPE_CASE } @@ -234,14 +275,14 @@ static int std_emit(lc_appendable_t *app, const lc_arg_occ_t *occ, const lc_arg_ make_fmt(fmt, sizeof(fmt), occ); - switch(occ->conversion) { + switch (occ->conversion) { /* Store the number of written characters in the given * int pointer location */ case 'n': { - int *num = val->v_ptr; - *num = app->written; + int *num = (int*)val->v_ptr; + *num = (int)app->written; } break; @@ -249,14 +290,14 @@ static int std_emit(lc_appendable_t *app, const lc_arg_occ_t *occ, const lc_arg_ * buffer of 128 letters for all other types should be enough. */ case 's': { - const char *str = val->v_ptr; + const char *str = (const char*)val->v_ptr; res = lc_arg_append(app, occ, str, strlen(str)); } break; default: { - int len = LC_MAX(128, occ->width + 1); + int len = MAX(128, occ->width + 1); char *buf = XMALLOCN(char, len); res = dispatch_snprintf(buf, len, fmt, occ->lc_arg_type, val); res = lc_appendable_snadd(app, buf, res); @@ -318,7 +359,7 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, /* Emit the text before the first % was found */ lc_appendable_snadd(app, fmt, (s ? s : last) - fmt); - while(s != NULL) { + while (s != NULL) { lc_arg_occ_t occ; lc_arg_value_t val; const lc_arg_t *arg = NULL; @@ -332,8 +373,8 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, memset(&occ, 0, sizeof(occ)); /* Eat all flags and set the corresponding flags in the occ struct */ - for(++s; strchr("#0-+", *s); ++s) { - switch(*s) { + for (++s; strchr("#0-+", *s); ++s) { + switch (*s) { case '#': occ.flag_hash = 1; break; @@ -358,13 +399,13 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, occ.precision = -1; /* read the precision if given */ - if(*s == '.') { - int val; - s = read_int(s + 1, &val); + if (*s == '.') { + int precision; + s = read_int(s + 1, &precision); /* Negative or lacking precision after a '.' is treated as * precision 0. */ - occ.precision = LC_MAX(0, val); + occ.precision = MAX(0, precision); } /* @@ -374,7 +415,7 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, * - or some other character, which ends this format invalidly */ ch = *s; - switch(ch) { + switch (ch) { case '%': s++; res += lc_appendable_chadd(app, '%'); @@ -384,32 +425,33 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, const char *named = ++s; /* Read until the closing brace or end of the string. */ - for(ch = *s; ch != '}' && ch != '\0'; ch = *++s); + for (ch = *s; ch != '}' && ch != '\0'; ch = *++s) { + } - if(s - named) { - int n = s - named; + if (s - named) { + size_t n = s - named; char *name; lc_arg_t tmp; - name = malloc(sizeof(char) * (n + 1)); + name = (char*) malloc(sizeof(char) * (n + 1)); memcpy(name, named, sizeof(char) * n); name[n] = '\0'; tmp.name = name; - arg = set_find(env->args, &tmp, sizeof(tmp), HASH_STR(named, n)); + arg = set_find(lc_arg_t, env->args, &tmp, sizeof(tmp), hash_str(named)); occ.modifier = ""; occ.modifier_length = 0; /* Set the conversion specifier of the occurrence to the * letter specified in the argument description. */ - if(arg) + if (arg) occ.conversion = arg->letter; free(name); /* If we ended with a closing brace, move the current * pointer after it, since it is not to be dumped. */ - if(ch == '}') + if (ch == '}') s++; } } @@ -420,17 +462,17 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, const char *mod = s; /* Read, as long there are letters */ - while(isalpha(ch) && !arg) { + while (isalpha((unsigned char)ch) && !arg) { int base = 'a'; lc_arg_t * const *map = env->lower; /* If uppercase, select the uppercase map from the environment */ - if(isupper(ch)) { + if (isupper((unsigned char)ch)) { base = 'A'; map = env->upper; } - if(map[ch - base] != NULL) { + if (map[ch - base] != NULL) { occ.modifier = mod; occ.modifier_length = s - mod; occ.conversion = ch; @@ -443,7 +485,7 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, } /* Call the handler if an argument was determined */ - if(arg != NULL && arg->handler != NULL) { + if (arg != NULL && arg->handler != NULL) { const lc_arg_handler_t *handler = arg->handler; /* Let the handler determine the type of the argument based on the @@ -451,8 +493,9 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, occ.lc_arg_type = handler->get_lc_arg_type(&occ); /* Store the value according to argument information */ - switch(occ.lc_arg_type) { -#define LC_ARG_TYPE(type,name) case lc_arg_type_ ## name: val.v_ ## name = va_arg(args, type); break; + switch (occ.lc_arg_type) { +#define LC_ARG_TYPE(type,name,va_type) \ + case lc_arg_type_ ## name: val.v_ ## name = va_arg(args, va_type); break; #include "lc_printf_arg_types.def" #undef LC_ARG_TYPE }