On Fri, Oct 26, 2018 at 04:26:32PM +0100, Ben Dooks wrote: > --- > evaluate.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 157 insertions(+), 1 deletion(-) > > diff --git a/evaluate.c b/evaluate.c > index b96696d..82ddf9f 100644 > --- a/evaluate.c > +++ b/evaluate.c > @@ -2243,11 +2243,154 @@ static struct symbol *evaluate_alignof(struct expression *expr) > return size_t_ctype; > } > > +static int decompose_format_printf(const char *string, struct symbol **result) > +{ > + int count = 0; > + > + for (; string[0] != '\0'; string++) { > + if (string[0] == '%') { > + int len = 0; > + struct symbol *sym = NULL; > + if (string[1] == '%') { > + string++; > + continue; > + } > + > + /* get rid of any formatting width bits */ > + while (isdigit(string[1]) || string[1] == '+' || string[1] == '-') > + string++; > + > + switch (string[1]) { > + case 'C': > + /* TODO - same as lc */ > + break; > + case 'c': > + /* TODO - can take l modifier */ > + sym = &char_ctype; > + break; > + case 'f': > + case 'g': > + sym = &double_ctype; > + break; > + case 'h': > + /* TODO hh */ > + len = -1; > + break; > + case 'j': /* ignore intmax/uintmax for the moment */ > + break; > + case 'L': > + sym = &ldouble_ctype; > + break; > + case 'l': > + len++; > + break; > + case 'p': > + /* TODO - deal with void * not being de-referenced in some cases*/ > + sym = &ptr_ctype; > + break; > + case 'q': > + len = 2; > + break; > + case 's': > + sym = &string_ctype; > + break; > + case 'n': > + /* TODO - actually pointer to integer */ > + sym = &ptr_ctype; > + break; > + /* note, d is out of alpha order */ > + case 'd': > + switch (len) { > + case -1: sym = &short_ctype; break; > + case 0: sym = &int_ctype; break; > + case 1: sym = &long_ctype; break; > + case 2: sym = &llong_ctype; break; > + case 3: sym = &lllong_ctype; break; > + } > + break; > + case 'u': > + switch (len) { > + case -1: sym = &ushort_ctype; break; > + case 0: sym = &uint_ctype; break; > + case 1: sym = &ulong_ctype; break; > + case 2: sym = &ullong_ctype; break; > + case 3: sym = &ulllong_ctype; break; > + } > + break; > + case 'x': > + case 'X': > + switch (len) { > + case 0: sym = &uint_ctype; break; > + case 1: sym = &ulong_ctype; break; > + case 2: sym = &ullong_ctype; break; > + case 3: sym = &ulllong_ctype; break; > + } > + break; This can be simplified into: + case 'd': + case 'u': + case 'x': + case 'X': + switch (len) { + case -1: sym = &short_ctype; break; + case 0: sym = &int_ctype; break; + case 1: sym = &long_ctype; break; + case 2: sym = &llong_ctype; break; + case 3: sym = &lllong_ctype; break; + } + break; because it's irrelevant if the argument is unsigned or not. -- Luc