projects
/
cparser
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
some testcases I had lying around here
[cparser]
/
format_check.c
diff --git
a/format_check.c
b/format_check.c
index
5d1b6a7
..
3ac9110
100644
(file)
--- a/
format_check.c
+++ b/
format_check.c
@@
-148,15
+148,12
@@
static bool atend(vchar_t *self) {
static void check_format_arguments(const call_argument_t *arg, unsigned idx_fmt,
unsigned idx_param)
{
static void check_format_arguments(const call_argument_t *arg, unsigned idx_fmt,
unsigned idx_param)
{
- const call_argument_t *fmt_arg;
- unsigned idx = 0;
-
/* find format arg */
/* find format arg */
- for(idx = 0; idx < idx_fmt; ++idx)
+ unsigned idx = 0;
+ for (; idx < idx_fmt; ++idx)
arg = arg->next;
arg = arg->next;
- fmt_arg = arg;
- const expression_t *fmt_expr =
fmt_
arg->expression;
+ const expression_t *fmt_expr = arg->expression;
if (fmt_expr->kind == EXPR_UNARY_CAST_IMPLICIT) {
fmt_expr = fmt_expr->unary.value;
}
if (fmt_expr->kind == EXPR_UNARY_CAST_IMPLICIT) {
fmt_expr = fmt_expr->unary.value;
}
@@
-182,7
+179,8
@@
static void check_format_arguments(const call_argument_t *arg, unsigned idx_fmt,
arg = arg->next;
const source_position_t *pos = &fmt_expr->base.source_position;
arg = arg->next;
const source_position_t *pos = &fmt_expr->base.source_position;
- unsigned fmt = vchar.first(&vchar);
+ unsigned fmt = vchar.first(&vchar);
+ unsigned num_fmt = 0;
for (; fmt != '\0'; fmt = vchar.next(&vchar)) {
if (fmt != '%')
continue;
for (; fmt != '\0'; fmt = vchar.next(&vchar)) {
if (fmt != '%')
continue;
@@
-191,6
+189,8
@@
static void check_format_arguments(const call_argument_t *arg, unsigned idx_fmt,
if (fmt == '%')
continue;
if (fmt == '%')
continue;
+ ++num_fmt;
+
format_flags_t fmt_flags = FMT_FLAG_NONE;
if (fmt == '0') {
fmt = vchar.next(&vchar);
format_flags_t fmt_flags = FMT_FLAG_NONE;
if (fmt == '0') {
fmt = vchar.next(&vchar);
@@
-223,14
+223,14
@@
static void check_format_arguments(const call_argument_t *arg, unsigned idx_fmt,
case ' ':
if (fmt_flags & FMT_FLAG_PLUS) {
case ' ':
if (fmt_flags & FMT_FLAG_PLUS) {
- warningf(pos, "' ' is overridden by prior '+' in conversion specification
"
);
+ warningf(pos, "' ' is overridden by prior '+' in conversion specification
%u", num_fmt
);
}
flag = FMT_FLAG_SPACE;
break;
case '+':
if (fmt_flags & FMT_FLAG_SPACE) {
}
flag = FMT_FLAG_SPACE;
break;
case '+':
if (fmt_flags & FMT_FLAG_SPACE) {
- warningf(pos, "'+' overrides prior ' ' in conversion specification
"
);
+ warningf(pos, "'+' overrides prior ' ' in conversion specification
%u", num_fmt
);
}
flag = FMT_FLAG_PLUS;
break;
}
flag = FMT_FLAG_PLUS;
break;
@@
-238,7
+238,7
@@
static void check_format_arguments(const call_argument_t *arg, unsigned idx_fmt,
default: goto break_fmt_flags;
}
if (fmt_flags & flag) {
default: goto break_fmt_flags;
}
if (fmt_flags & flag) {
- warningf(pos, "repeated flag '%c' in conversion specification
", (char)
fmt);
+ warningf(pos, "repeated flag '%c' in conversion specification
%u", (char)fmt, num_
fmt);
}
fmt_flags |= flag;
fmt = vchar.next(&vchar);
}
fmt_flags |= flag;
fmt = vchar.next(&vchar);
@@
-249,12
+249,12
@@
break_fmt_flags:
if (fmt == '*') {
fmt = vchar.next(&vchar);
if (arg == NULL) {
if (fmt == '*') {
fmt = vchar.next(&vchar);
if (arg == NULL) {
- warningf(pos, "missing argument for '*' field width in conversion specification
"
);
+ warningf(pos, "missing argument for '*' field width in conversion specification
%u", num_fmt
);
return;
}
const type_t *const arg_type = arg->expression->base.type;
if (arg_type != type_int) {
return;
}
const type_t *const arg_type = arg->expression->base.type;
if (arg_type != type_int) {
- warningf(pos, "argument for '*' field width in conversion specification
is not an 'int', but an '%T'"
, arg_type);
+ warningf(pos, "argument for '*' field width in conversion specification
%u is not an 'int', but an '%T'", num_fmt
, arg_type);
}
arg = arg->next;
} else {
}
arg = arg->next;
} else {
@@
-270,12
+270,12
@@
break_fmt_flags:
if (fmt == '*') {
fmt = vchar.next(&vchar);
if (arg == NULL) {
if (fmt == '*') {
fmt = vchar.next(&vchar);
if (arg == NULL) {
- warningf(pos, "missing argument for '*' precision in conversion specification
"
);
+ warningf(pos, "missing argument for '*' precision in conversion specification
%u", num_fmt
);
return;
}
const type_t *const arg_type = arg->expression->base.type;
if (arg_type != type_int) {
return;
}
const type_t *const arg_type = arg->expression->base.type;
if (arg_type != type_int) {
- warningf(pos, "argument for '*' precision in conversion specification
is not an 'int', but an '%T'"
, arg_type);
+ warningf(pos, "argument for '*' precision in conversion specification
%u is not an 'int', but an '%T'", num_fmt
, arg_type);
}
arg = arg->next;
} else {
}
arg = arg->next;
} else {
@@
-389,7
+389,6
@@
break_fmt_flags:
case 'x':
allowed_flags = FMT_FLAG_MINUS | FMT_FLAG_HASH | FMT_FLAG_ZERO;
goto eval_fmt_mod_unsigned;
case 'x':
allowed_flags = FMT_FLAG_MINUS | FMT_FLAG_HASH | FMT_FLAG_ZERO;
goto eval_fmt_mod_unsigned;
- break;
case 'u':
allowed_flags = FMT_FLAG_MINUS | FMT_FLAG_ZERO;
case 'u':
allowed_flags = FMT_FLAG_MINUS | FMT_FLAG_ZERO;
@@
-508,7
+507,7
@@
eval_fmt_mod_unsigned:
break;
default:
break;
default:
- warningf(pos, "encountered unknown conversion specifier '%%%C'
", (wint_t)
fmt);
+ warningf(pos, "encountered unknown conversion specifier '%%%C'
at position %u", (wint_t)fmt, num_
fmt);
goto next_arg;
}
goto next_arg;
}
@@
-524,7
+523,7
@@
eval_fmt_mod_unsigned:
if (wrong_flags & FMT_FLAG_TICK) wrong[idx++] = '\'';
wrong[idx] = '\0';
if (wrong_flags & FMT_FLAG_TICK) wrong[idx++] = '\'';
wrong[idx] = '\0';
- warningf(pos, "invalid format flags \"%s\" in conversion specification %%%c
", wrong,
fmt);
+ warningf(pos, "invalid format flags \"%s\" in conversion specification %%%c
at position %u", wrong, fmt, num_
fmt);
}
if (arg == NULL) {
}
if (arg == NULL) {
@@
-552,8
+551,8
@@
eval_fmt_mod_unsigned:
}
if (is_type_valid(arg_skip)) {
warningf(pos,
}
if (is_type_valid(arg_skip)) {
warningf(pos,
- "argument type '%T' does not match conversion specifier '%%%s%c'",
- arg_type, get_length_modifier_name(fmt_mod), (char)fmt);
+ "argument type '%T' does not match conversion specifier '%%%s%c'
at position %u
",
+ arg_type, get_length_modifier_name(fmt_mod), (char)fmt
, num_fmt
);
}
}
next_arg:
}
}
next_arg:
@@
-563,7
+562,14
@@
next_arg:
warningf(pos, "format string contains NUL");
}
if (arg != NULL) {
warningf(pos, "format string contains NUL");
}
if (arg != NULL) {
- warningf(pos, "too many arguments for format string");
+ unsigned num_args = num_fmt;
+ while (arg != NULL) {
+ ++num_args;
+ arg = arg->next;
+ }
+ warningf(pos, "%u argument%s but only %u format string%s",
+ num_args, num_args != 1 ? "s" : "",
+ num_fmt, num_fmt != 1 ? "s" : "");
}
}
}
}