Skip to content

Commit 334cba4

Browse files
committed
printf argnum (parameter swapping) support from Morten Poulsen
1 parent 066547a commit 334cba4

File tree

3 files changed

+47
-22
lines changed

3 files changed

+47
-22
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ PHP 4.0 NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33

44
?? ??? 200?, Version 4.0.6
5+
- printf argnum (parameter swapping) support (Morten Poulsen, Rasmus)
56
- Add DIRECTORY_SEPARATOR constant ('/' on UNIX, '\' on Windows) (Stig)
67
- Added small change to php_odbc module, to check for failed SQLDisconnects
78
and to close any outstanding transactions if the call fails, then disconnect

ext/standard/formatted_print.c

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,8 @@ static char *
390390
php_formatted_print(int ht, int *len)
391391
{
392392
pval ***args;
393-
int argc, size = 240, inpos = 0, outpos = 0;
394-
int alignment, width, precision, currarg, adjusting;
393+
int argc, size = 240, inpos = 0, outpos = 0, temppos;
394+
int alignment, width, precision, currarg, adjusting, argnum;
395395
char *format, *result, padding;
396396

397397
argc = ZEND_NUM_ARGS();
@@ -437,7 +437,23 @@ php_formatted_print(int ht, int *len)
437437
PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n",
438438
format[inpos], inpos));
439439
if (isascii((int)format[inpos]) && !isalpha((int)format[inpos])) {
440-
/* first look for modifiers */
440+
/* first look for argnum */
441+
temppos = inpos;
442+
while (isdigit((int)format[temppos])) temppos++;
443+
if (format[temppos] == '$') {
444+
argnum = php_sprintf_getnumber(format, &inpos);
445+
inpos++; /* skip the '$' */
446+
} else {
447+
argnum = currarg++;
448+
}
449+
if (argnum >= argc) {
450+
efree(result);
451+
efree(args);
452+
php_error(E_WARNING, "%s(): too few arguments",get_active_function_name());
453+
return NULL;
454+
}
455+
456+
/* after argnum comes modifiers */
441457
PRINTF_DEBUG(("sprintf: looking for modifiers\n"
442458
"sprintf: now looking at '%c', inpos=%d\n",
443459
format[inpos], inpos));
@@ -469,7 +485,7 @@ php_formatted_print(int ht, int *len)
469485
}
470486
PRINTF_DEBUG(("sprintf: width=%d\n", width));
471487

472-
/* after width comes precision */
488+
/* after width and argnum comes precision */
473489
if (format[inpos] == '.') {
474490
inpos++;
475491
PRINTF_DEBUG(("sprintf: getting precision\n"));
@@ -486,6 +502,7 @@ php_formatted_print(int ht, int *len)
486502
PRINTF_DEBUG(("sprintf: precision=%d\n", precision));
487503
} else {
488504
width = precision = 0;
505+
argnum = currarg++;
489506
}
490507

491508
if (format[inpos] == 'l') {
@@ -495,67 +512,67 @@ php_formatted_print(int ht, int *len)
495512
/* now we expect to find a type specifier */
496513
switch (format[inpos]) {
497514
case 's':
498-
convert_to_string_ex(args[currarg]);
515+
convert_to_string_ex(args[argnum]);
499516
php_sprintf_appendstring(&result, &outpos, &size,
500-
(*args[currarg])->value.str.val,
517+
(*args[argnum])->value.str.val,
501518
width, precision, padding,
502519
alignment,
503-
(*args[currarg])->value.str.len,
520+
(*args[argnum])->value.str.len,
504521
0, expprec);
505522
break;
506523

507524
case 'd':
508-
convert_to_long_ex(args[currarg]);
525+
convert_to_long_ex(args[argnum]);
509526
php_sprintf_appendint(&result, &outpos, &size,
510-
(*args[currarg])->value.lval,
527+
(*args[argnum])->value.lval,
511528
width, padding, alignment);
512529
break;
513530

514531
case 'e':
515532
case 'f':
516533
/* XXX not done */
517-
convert_to_double_ex(args[currarg]);
534+
convert_to_double_ex(args[argnum]);
518535
php_sprintf_appenddouble(&result, &outpos, &size,
519-
(*args[currarg])->value.dval,
536+
(*args[argnum])->value.dval,
520537
width, padding, alignment,
521538
precision, adjusting,
522539
format[inpos]);
523540
break;
524541

525542
case 'c':
526-
convert_to_long_ex(args[currarg]);
543+
convert_to_long_ex(args[argnum]);
527544
php_sprintf_appendchar(&result, &outpos, &size,
528-
(char) (*args[currarg])->value.lval);
545+
(char) (*args[argnum])->value.lval);
529546
break;
530547

531548
case 'o':
532-
convert_to_long_ex(args[currarg]);
549+
convert_to_long_ex(args[argnum]);
533550
php_sprintf_append2n(&result, &outpos, &size,
534-
(*args[currarg])->value.lval,
551+
(*args[argnum])->value.lval,
535552
width, padding, alignment, 3,
536553
hexchars, expprec);
537554
break;
538555

539556
case 'x':
540-
convert_to_long_ex(args[currarg]);
557+
convert_to_long_ex(args[argnum]);
541558
php_sprintf_append2n(&result, &outpos, &size,
542-
(*args[currarg])->value.lval,
559+
(*args[argnum])->value.lval,
543560
width, padding, alignment, 4,
544561
hexchars, expprec);
545562
break;
546563

547564
case 'X':
548-
convert_to_long_ex(args[currarg]);
565+
convert_to_long_ex(args[argnum]);
549566
php_sprintf_append2n(&result, &outpos, &size,
550-
(*args[currarg])->value.lval,
567+
(*args[argnum])->value.lval,
551568
width, padding, alignment, 4,
552569
HEXCHARS, expprec);
553570
break;
554571

555572
case 'b':
556-
convert_to_long_ex(args[currarg]);
573+
convert_to_long_ex(args[argnum]);
557574
php_sprintf_append2n(&result, &outpos, &size,
558-
(*args[currarg])->value.lval,
575+
(*args[argnum])->value.lval,
559576
width, padding, alignment, 1,
560577
hexchars, expprec);
561578
break;
@@ -567,7 +584,6 @@ php_formatted_print(int ht, int *len)
567584
default:
568585
break;
569586
}
570-
currarg++;
571587
inpos++;
572588
}
573589
}

tests/strings/002.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ printf("printf test 22:%016x\n", 170);
3434
printf("printf test 23:%016X\n", 170);
3535
printf("printf test 24:%.5s\n", "abcdefghij");
3636
printf("printf test 25:%-2s\n", "gazonk");
37+
printf("printf test 26:%2\$d %1\$d\n", 1, 2);
38+
printf("printf test 27:%3\$d %d %d\n", 1, 2, 3);
39+
printf("printf test 28:%2\$02d %1\$2d\n", 1, 2);
40+
printf("printf test 29:%2\$-2d %1\$2d\n", 1, 2);
3741

3842
?>
3943
--EXPECT--
@@ -64,3 +68,7 @@ printf test 22:00000000000000aa
6468
printf test 23:00000000000000AA
6569
printf test 24:abcde
6670
printf test 25:gazonk
71+
printf test 26:2 1
72+
printf test 27:3 1 2
73+
printf test 28:02 1
74+
printf test 29:2 1

0 commit comments

Comments
 (0)