From 5007fea9956f473c7b5522260994180dcd7cd9e6 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Mon, 16 Jun 2014 22:09:38 +0100 Subject: [PATCH 1/1] struct/dstr-putf.c: Different way to represent type lengths; new types. Support the full menagerie of C99 and POSIX types. --- configure.ac | 1 + struct/dstr-putf.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 2d4f0fb..5973f45 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,7 @@ dnl C programming environment. dnl Headers. AC_CHECK_HEADERS([float.h]) +AC_CHECK_HEADERS([stdint.h]) dnl Libraries. AC_SEARCH_LIBS([socket], [socket]) diff --git a/struct/dstr-putf.c b/struct/dstr-putf.c index 6f699e4..9ac8cf9 100644 --- a/struct/dstr-putf.c +++ b/struct/dstr-putf.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,10 @@ # include #endif +#ifdef HAVE_STDINT_H +# include +#endif + #include "darray.h" #include "dstr.h" @@ -55,18 +60,45 @@ /*----- Preliminary definitions -------------------------------------------*/ +#ifdef HAVE_FLOAT_H +# define IF_FLOAT(x) x +#else +# define IF_FLOAT(x) +#endif + +#if defined(LLONG_MAX) || defined(LONG_LONG_MAX) +# define IF_LONGLONG(x) x +#else +# define IF_LONGLONG(x) +#endif + +#ifdef INTMAX_MAX +# define IF_INTMAX(x) x +#else +# define IF_INTMAX(x) +#endif + #define OUTPUT_FMTTYPES(_) \ _(i, unsigned int) \ _(li, unsigned long) \ + IF_LONGLONG( _(lli, unsigned long long) ) \ + _(zi, size_t) \ + _(ti, ptrdiff_t) \ + IF_INTMAX( _(ji, uintmax_t) ) \ _(s, char *) \ _(p, void *) \ _(f, double) \ _(Lf, long double) #define PERCENT_N_FMTTYPES(_) \ - _(hn, short *) \ _(n, int *) \ - _(ln, long *) + _(hhn, char *) \ + _(hn, short *) \ + _(ln, long *) \ + _(zn, size_t *) \ + _(tn, ptrdiff_t *) \ + IF_LONGLONG( _(lln, long long *) ) \ + IF_INTMAX( _(jn, intmax_t *) ) #define FMTTYPES(_) \ OUTPUT_FMTTYPES(_) \ @@ -93,9 +125,13 @@ DA_DECL(fmtarg_v, fmtarg); enum { len_std = 0, + len_hh, len_h, len_l, len_ll, + len_z, + len_t, + len_j, len_L }; @@ -275,9 +311,18 @@ int dstr_vputf(dstr *d, const char *p, va_list *ap) /* --- Maybe some length flags --- */ switch (*p) { - case 'h': f |= len_h; p++; break; - case 'l': f |= len_l; p++; break; + case 'h': + p++; + if (*p == 'h') { f |= len_hh; p++; } else f |= len_h; + break; + case 'l': + p++; + IF_LONGLONG( if (*p == 'l') { f |= len_ll; p++; } else ) f |= len_l; + break; case 'L': f |= len_L; p++; break; + case 'z': f |= len_z; p++; break; + case 't': f |= len_t; p++; break; + IF_INTMAX( case 'j': f |= len_j; p++; break; ) } /* --- The flags are now ready --- */ @@ -294,9 +339,14 @@ int dstr_vputf(dstr *d, const char *p, va_list *ap) case 'd': case 'i': case 'x': case 'X': case 'o': case 'u': switch (f & f_len) { case len_l: fs->fmt = fmt_li; break; + case len_z: fs->fmt = fmt_zi; break; + case len_t: fs->fmt = fmt_ti; break; + IF_LONGLONG( case len_ll: fs->fmt = fmt_lli; break; ) + IF_INTMAX( case len_j: fs->fmt = fmt_ji; break; ) default: fs->fmt = fmt_i; } break; + case 'a': case 'A': case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': fs->fmt = (f & f_len) == len_L ? fmt_Lf : fmt_f; break; @@ -311,8 +361,13 @@ int dstr_vputf(dstr *d, const char *p, va_list *ap) break; case 'n': switch (f & f_len) { + case len_hh: fs->fmt = fmt_hhn; break; case len_h: fs->fmt = fmt_hn; break; case len_l: fs->fmt = fmt_ln; break; + case len_z: fs->fmt = fmt_zn; break; + case len_t: fs->fmt = fmt_tn; break; + IF_LONGLONG( case len_ll: fs->fmt = fmt_lln; break; ) + IF_INTMAX( case len_j: fs->fmt = fmt_jn; break; ) default: fs->fmt = fmt_n; } break; @@ -404,9 +459,14 @@ int dstr_vputf(dstr *d, const char *p, va_list *ap) /* --- Write out the length gadget --- */ switch (f & f_len) { + case len_hh: DPUTC(&dd, 'h'); /* fall through */ case len_h: DPUTC(&dd, 'h'); break; + IF_LONGLONG( case len_ll: DPUTC(&dd, 'l'); /* fall through */ ) case len_l: DPUTC(&dd, 'l'); break; + case len_z: DPUTC(&dd, 'z'); break; + case len_t: DPUTC(&dd, 't'); break; case len_L: DPUTC(&dd, 'L'); break; + IF_INTMAX( case len_j: DPUTC(&dd, 'j'); break; ) case len_std: break; default: abort(); } -- 2.11.0