@@ -194,7 +194,6 @@ type formatState struct {
194
194
name string // Printf, Sprintf etc.
195
195
flags []byte // the list of # + etc.
196
196
argNums []int // the successive argument numbers that are consumed, adjusted to refer to actual arg in call
197
- indexed bool // whether an indexing expression appears: %[1]d.
198
197
firstArg int // Index of first argument after the format in the Printf call.
199
198
// Used only during parse.
200
199
file * File
@@ -223,7 +222,7 @@ func (f *File) checkPrintf(call *ast.CallExpr, name string) {
223
222
}
224
223
// Hard part: check formats against args.
225
224
argNum := firstArg
226
- indexed := false
225
+ maxArgNum := firstArg
227
226
for i , w := 0 , 0 ; i < len (format ); i += w {
228
227
w = 1
229
228
if format [i ] == '%' {
@@ -232,26 +231,27 @@ func (f *File) checkPrintf(call *ast.CallExpr, name string) {
232
231
return
233
232
}
234
233
w = len (state .format )
235
- if state .indexed {
236
- indexed = true
237
- }
238
234
if ! f .okPrintfArg (call , state ) { // One error per format is enough.
239
235
return
240
236
}
241
237
if len (state .argNums ) > 0 {
242
238
// Continue with the next sequential argument.
243
239
argNum = state .argNums [len (state .argNums )- 1 ] + 1
244
240
}
241
+ for _ , n := range state .argNums {
242
+ if n >= maxArgNum {
243
+ maxArgNum = n + 1
244
+ }
245
+ }
245
246
}
246
247
}
247
248
// Dotdotdot is hard.
248
- if call .Ellipsis .IsValid () && argNum >= len (call .Args )- 1 {
249
+ if call .Ellipsis .IsValid () && maxArgNum >= len (call .Args )- 1 {
249
250
return
250
251
}
251
- // If the arguments were direct indexed, we assume the programmer knows what's up.
252
- // Otherwise, there should be no leftover arguments.
253
- if ! indexed && argNum != len (call .Args ) {
254
- expect := argNum - firstArg
252
+ // There should be no leftover arguments.
253
+ if maxArgNum != len (call .Args ) {
254
+ expect := maxArgNum - firstArg
255
255
numArgs := len (call .Args ) - firstArg
256
256
f .Badf (call .Pos (), "wrong number of args for format in %s call: %d needed but %d args" , name , expect , numArgs )
257
257
}
@@ -286,17 +286,20 @@ func (s *formatState) parseIndex() bool {
286
286
return true
287
287
}
288
288
// Argument index present.
289
- s .indexed = true
290
289
s .nbytes ++ // skip '['
291
290
start := s .nbytes
292
291
s .scanNum ()
293
292
if s .nbytes == len (s .format ) || s .nbytes == start || s .format [s .nbytes ] != ']' {
294
- s .file .Badf (s .call .Pos (), "illegal syntax for printf argument index" )
293
+ end := strings .Index (s .format , "]" )
294
+ if end < 0 {
295
+ end = len (s .format )
296
+ }
297
+ s .file .Badf (s .call .Pos (), "bad syntax for printf argument index: [%s]" , s .format [start :end ])
295
298
return false
296
299
}
297
300
arg32 , err := strconv .ParseInt (s .format [start :s .nbytes ], 10 , 32 )
298
301
if err != nil {
299
- s .file .Badf (s .call .Pos (), "illegal syntax for printf argument index: %s" , err )
302
+ s .file .Badf (s .call .Pos (), "bad syntax for printf argument index: %s" , err )
300
303
return false
301
304
}
302
305
s .nbytes ++ // skip ']'
@@ -349,14 +352,12 @@ func (f *File) parsePrintfVerb(call *ast.CallExpr, name, format string, firstArg
349
352
argNum : argNum ,
350
353
argNums : make ([]int , 0 , 1 ),
351
354
nbytes : 1 , // There's guaranteed to be a percent sign.
352
- indexed : false ,
353
355
firstArg : firstArg ,
354
356
file : f ,
355
357
call : call ,
356
358
}
357
359
// There may be flags.
358
360
state .parseFlags ()
359
- indexPending := false
360
361
// There may be an index.
361
362
if ! state .parseIndex () {
362
363
return nil
@@ -370,7 +371,7 @@ func (f *File) parsePrintfVerb(call *ast.CallExpr, name, format string, firstArg
370
371
return nil
371
372
}
372
373
// Now a verb, possibly prefixed by an index (which we may already have).
373
- if ! indexPending && ! state .parseIndex () {
374
+ if ! state . indexPending && ! state .parseIndex () {
374
375
return nil
375
376
}
376
377
if state .nbytes == len (state .format ) {
0 commit comments