From a4ee47bd186b7384dc857e41ce0f5ac86eb30272 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Sat, 8 Jan 2011 00:26:48 +0000 Subject: [PATCH] Further improved lc_printf() and friends. - 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 | 6 +++++- ir/libcore/lc_printf.c | 12 ++++++++++-- ir/libcore/lc_printf.h | 20 ++++++++++---------- ir/libcore/lc_printf_arg_types.def | 2 ++ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/ir/libcore/lc_config.h b/ir/libcore/lc_config.h index 1842ca3a0..323f5fe67 100644 --- a/ir/libcore/lc_config.h +++ b/ir/libcore/lc_config.h @@ -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 "" #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 "" #define LC_UNUSED(x) #define LC_LONGLONG long #define LC_LONGDOUBLE double +#define LC_PRINTF(m) #endif diff --git a/ir/libcore/lc_printf.c b/ir/libcore/lc_printf.c index bfe0355e9..959200d93 100644 --- a/ir/libcore/lc_printf.c +++ b/ir/libcore/lc_printf.c @@ -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; diff --git a/ir/libcore/lc_printf.h b/ir/libcore/lc_printf.h index 0d48e73c1..0048c0229 100644 --- a/ir/libcore/lc_printf.h +++ b/ir/libcore/lc_printf.h @@ -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); diff --git a/ir/libcore/lc_printf_arg_types.def b/ir/libcore/lc_printf_arg_types.def index 254d3e944..54ee82939 100644 --- a/ir/libcore/lc_printf_arg_types.def +++ b/ir/libcore/lc_printf_arg_types.def @@ -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) -- 2.20.1