chiark
/
gitweb
/
~mdw
/
mLib
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
@@@ m4
[mLib]
/
struct
/
dstr-putf.c
diff --git
a/struct/dstr-putf.c
b/struct/dstr-putf.c
index 6f699e4f74947808ba12803beeabd066998d6e86..270f9a3f84bdd96e4cdf83c772c6da86daaf6ee7 100644
(file)
--- a/
struct/dstr-putf.c
+++ b/
struct/dstr-putf.c
@@
-31,7
+31,7
@@
#include <assert.h>
#include <ctype.h>
#include <assert.h>
#include <ctype.h>
-#include <
math
.h>
+#include <
limits
.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@
-41,8
+41,13
@@
# include <float.h>
#endif
# include <float.h>
#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
#include "darray.h"
#include "dstr.h"
#include "darray.h"
#include "dstr.h"
+#include "macros.h"
/*----- Tunable constants -------------------------------------------------*/
/*----- Tunable constants -------------------------------------------------*/
@@
-55,18
+60,45
@@
/*----- Preliminary definitions -------------------------------------------*/
/*----- 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) \
#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(_) \
_(s, char *) \
_(p, void *) \
_(f, double) \
_(Lf, long double)
#define PERCENT_N_FMTTYPES(_) \
- _(hn, short *) \
_(n, int *) \
_(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(_) \
#define FMTTYPES(_) \
OUTPUT_FMTTYPES(_) \
@@
-93,9
+125,13
@@
DA_DECL(fmtarg_v, fmtarg);
enum {
len_std = 0,
enum {
len_std = 0,
+ len_hh,
len_h,
len_l,
len_ll,
len_h,
len_l,
len_ll,
+ len_z,
+ len_t,
+ len_j,
len_L
};
len_L
};
@@
-166,7
+202,7
@@
int dstr_vputf(dstr *d, const char *p, va_list *ap)
/* --- Initial pass through the input, parsing format specifiers --- *
*
* We essentially compile the format string into a vector of @fmtspec@
/* --- Initial pass through the input, parsing format specifiers --- *
*
* We essentially compile the format string into a vector of @fmtspec@
- * objects, each of which represnts a chunk of literal text followed by a
+ * objects, each of which repres
e
nts a chunk of literal text followed by a
* (possibly imaginary, in the case of the final one) formatting directive.
* Output then simply consists of interpreting these specifiers in order.
*/
* (possibly imaginary, in the case of the final one) formatting directive.
* Output then simply consists of interpreting these specifiers in order.
*/
@@
-212,7
+248,7
@@
int dstr_vputf(dstr *d, const char *p, va_list *ap)
done_flags:
i = 0;
done_flags:
i = 0;
- while (
isdigit((unsigned char)
*p)) i = 10*i + *p++ - '0';
+ while (
ISDIGIT(
*p)) i = 10*i + *p++ - '0';
/* --- Snag: this might have been an argument position indicator --- */
/* --- Snag: this might have been an argument position indicator --- */
@@
-234,11
+270,11
@@
int dstr_vputf(dstr *d, const char *p, va_list *ap)
fs->wd = i;
} else if (*p == '*') {
p++;
fs->wd = i;
} else if (*p == '*') {
p++;
- if (!
isdigit((unsigned char)
*p))
+ if (!
ISDIGIT(
*p))
i = anext++;
else {
i = *p++ - '0';
i = anext++;
else {
i = *p++ - '0';
- while (
isdigit((unsigned char)
*p)) i = 10*i + *p++ - '0';
+ while (
ISDIGIT(
*p)) i = 10*i + *p++ - '0';
assert(*p == '$'); p++;
assert(i > 0); i--;
}
assert(*p == '$'); p++;
assert(i > 0); i--;
}
@@
-251,19
+287,19
@@
int dstr_vputf(dstr *d, const char *p, va_list *ap)
if (*p == '.') {
p++;
f |= f_prec;
if (*p == '.') {
p++;
f |= f_prec;
- if (
isdigit((unsigned char)
*p)) {
+ if (
ISDIGIT(
*p)) {
i = *p++ - '0';
i = *p++ - '0';
- while (
isdigit((unsigned char)
*p)) i = 10*i + *p++ - '0';
+ while (
ISDIGIT(
*p)) i = 10*i + *p++ - '0';
fs->prec = i;
} else if (*p != '*')
fs->prec = 0;
else {
p++;
fs->prec = i;
} else if (*p != '*')
fs->prec = 0;
else {
p++;
- if (!
isdigit((unsigned char)
*p))
+ if (!
ISDIGIT(
*p))
i = anext++;
else {
i = *p++ - '0';
i = anext++;
else {
i = *p++ - '0';
- while (
isdigit((unsigned char)
*p)) i = 10*i + *p++ - '0';
+ while (
ISDIGIT(
*p)) i = 10*i + *p++ - '0';
assert(*p == '$'); p++;
assert(i > 0); i--;
}
assert(*p == '$'); p++;
assert(i > 0); i--;
}
@@
-275,9
+311,18
@@
int dstr_vputf(dstr *d, const char *p, va_list *ap)
/* --- Maybe some length flags --- */
switch (*p) {
/* --- 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 '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 --- */
}
/* --- 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 '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;
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;
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) {
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_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;
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) {
/* --- Write out the length gadget --- */
switch (f & f_len) {
+ case len_hh: DPUTC(&dd, 'h'); /* fall through */
case len_h: DPUTC(&dd, 'h'); break;
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_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;
case len_L: DPUTC(&dd, 'L'); break;
+ IF_INTMAX( case len_j: DPUTC(&dd, 'j'); break; )
case len_std: break;
default: abort();
}
case len_std: break;
default: abort();
}
@@
-476,6
+536,8
@@
int dstr_vputf(dstr *d, const char *p, va_list *ap)
DPUTZ(d);
DDESTROY(&dd);
DPUTZ(d);
DDESTROY(&dd);
+ DA_DESTROY(&av);
+ DA_DESTROY(&sv);
return (d->len - n);
}
return (d->len - n);
}