Further improved lc_printf() and friends.
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sat, 8 Jan 2011 00:26:48 +0000 (00:26 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sat, 8 Jan 2011 00:26:48 +0000 (00:26 +0000)
- add support for h and hh type modifier
- add __attribute__((format ...)) for all printf-like functions
- fixed size_t related warnings

[r28222]

ir/libcore/lc_config.h
ir/libcore/lc_printf.c
ir/libcore/lc_printf.h
ir/libcore/lc_printf_arg_types.def

index 1842ca3..323f5fe 100644 (file)
@@ -31,6 +31,7 @@
 #define inline         __inline__
 #define LC_FUNCNAME    __FUNCTION__
 #define LC_UNUSED(x)   x __attribute__((__unused__))
+#define LC_PRINTF(m) __attribute__((format(printf,m,(m)+1)))
 
 #ifdef __STRICT_ANSI__
 #define LC_LONGLONG    long
@@ -44,6 +45,8 @@
 
 #define LC_FUNCNAME    "<unknown>"
 #define LC_UNUSED(x)   x
+#define LC_PRINTF(m)
+
 #define LC_LONGLONG    __int64
 #define LC_LONGDOUBLE  long double
 
@@ -66,13 +69,14 @@ typedef unsigned __int64            uint64;
 #endif /* _MSC_VER <= 1200 */
 
 /* default definitions */
-#else /* defined(_MSC_VER) */
+#else /* !defined(__GNUC__) && !defined(_MSC_VER) */
 
 #define inline
 #define LC_FUNCNAME "<unknown>"
 #define LC_UNUSED(x)
 #define LC_LONGLONG long
 #define LC_LONGDOUBLE double
+#define LC_PRINTF(m)
 
 #endif
 
index bfe0355..959200d 100644 (file)
@@ -203,6 +203,12 @@ static char *make_fmt(char *buf, size_t len, const lc_arg_occ_t *occ)
                                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",
@@ -222,12 +228,14 @@ 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;
@@ -272,7 +280,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;
 
index 0d48e73..0048c02 100644 (file)
@@ -94,25 +94,25 @@ lc_arg_env_t *lc_arg_add_std(lc_arg_env_t *env);
 
 int lc_arg_append(lc_appendable_t *app, const lc_arg_occ_t *occ, const char *str, size_t len);
 
-int lc_epprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, ...);
+int lc_epprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, ...) LC_PRINTF(3);
 int lc_evpprintf(const lc_arg_env_t *env, lc_appendable_t *app, const char *fmt, va_list args);
-int lc_pprintf(lc_appendable_t *app, const char *fmt, ...);
+int lc_pprintf(lc_appendable_t *app, const char *fmt, ...) LC_PRINTF(2);
 int lc_vpprintf(lc_appendable_t *app, const char *fmt, va_list args);
 
-int lc_eprintf(const lc_arg_env_t *env, const char *fmt, ...);
-int lc_esnprintf(const lc_arg_env_t *env, char *buf, size_t len, const char *fmt, ...);
-int lc_efprintf(const lc_arg_env_t *env, FILE *file, const char *fmt, ...);
-int lc_eoprintf(const lc_arg_env_t *env, struct obstack *obst, const char *fmt, ...);
+int lc_eprintf(const lc_arg_env_t *env, const char *fmt, ...) LC_PRINTF(2);
+int lc_esnprintf(const lc_arg_env_t *env, char *buf, size_t len, const char *fmt, ...) LC_PRINTF(4);
+int lc_efprintf(const lc_arg_env_t *env, FILE *file, const char *fmt, ...) LC_PRINTF(3);
+int lc_eoprintf(const lc_arg_env_t *env, struct obstack *obst, const char *fmt, ...) LC_PRINTF(3);
 
 int lc_evprintf(const lc_arg_env_t *env, const char *fmt, va_list args);
 int lc_evsnprintf(const lc_arg_env_t *env, char *buf, size_t len, const char *fmt, va_list args);
 int lc_evfprintf(const lc_arg_env_t *env, FILE *f, const char *fmt, va_list args);
 int lc_evoprintf(const lc_arg_env_t *env, struct obstack *obst, const char *fmt, va_list args);
 
-int lc_printf(const char *fmt, ...);
-int lc_snprintf(char *buf, size_t len, const char *fmt, ...);
-int lc_fprintf(FILE *f, const char *fmt, ...);
-int lc_oprintf(struct obstack *obst, const char *fmt, ...);
+int lc_printf(const char *fmt, ...) LC_PRINTF(1);
+int lc_snprintf(char *buf, size_t len, const char *fmt, ...) LC_PRINTF(3);
+int lc_fprintf(FILE *f, const char *fmt, ...) LC_PRINTF(2);
+int lc_oprintf(struct obstack *obst, const char *fmt, ...) LC_PRINTF(2);
 
 int lc_vprintf(const char *fmt, va_list args);
 int lc_vsnprintf(char *buf, size_t len, const char *fmt, va_list args);
index 254d3e9..54ee829 100644 (file)
@@ -1,3 +1,5 @@
+LC_ARG_TYPE(char, char)
+LC_ARG_TYPE(short, short)
 LC_ARG_TYPE(int, int)
 LC_ARG_TYPE(long, long)
 LC_ARG_TYPE(LC_LONGLONG, long_long)