shrink load mode if not all bits are used
[libfirm] / ir / libcore / lc_printf.c
index e740c03..416fc66 100644 (file)
 #include <assert.h>
 #include <ctype.h>
 
-#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 */
@@ -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 = (const lc_arg_t*)p1;
        const lc_arg_t *a2 = (const lc_arg_t*)p2;
+       (void) size;
        return strcmp(a1->name, a2->name);
 }
 
@@ -104,16 +104,16 @@ 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 = (lc_arg_t*)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)
                map[letter - base] = ent;
@@ -121,8 +121,10 @@ int lc_arg_register(lc_arg_env_t *env, const char *name, char letter, const lc_a
        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)
@@ -134,7 +136,7 @@ int lc_arg_append(lc_appendable_t *app, const lc_arg_occ_t *occ, const char *str
        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);
 }
 
 
@@ -144,7 +146,7 @@ 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) \
+#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
@@ -170,8 +172,47 @@ static char *make_fmt(char *buf, size_t len, const lc_arg_occ_t *occ)
 
        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
                }
@@ -241,7 +282,7 @@ static int std_emit(lc_appendable_t *app, const lc_arg_occ_t *occ, const lc_arg_
                case 'n':
                        {
                                int *num = (int*)val->v_ptr;
-                               *num = app->written;
+                               *num = (int)app->written;
                        }
                        break;
 
@@ -256,7 +297,7 @@ static int std_emit(lc_appendable_t *app, const lc_arg_occ_t *occ, const lc_arg_
 
                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);
@@ -359,12 +400,12 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt,
 
                /* read the precision if given */
                if (*s == '.') {
-                       int val;
-                       s = read_int(s + 1, &val);
+                       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);
                }
 
                /*
@@ -384,7 +425,8 @@ 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) {
                                                size_t n = s - named;
@@ -396,7 +438,7 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt,
                                                name[n] = '\0';
                                                tmp.name = name;
 
-                                               arg = (lc_arg_t*)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;
 
@@ -420,12 +462,12 @@ 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;
                                                }
@@ -452,7 +494,8 @@ int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt,
 
                        /* 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;
+#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
                        }