diff --git a/Objective-J/sprintf.js b/Objective-J/sprintf.js index d5df1b2a5..9ad4723a5 100644 --- a/Objective-J/sprintf.js +++ b/Objective-J/sprintf.js @@ -22,8 +22,8 @@ // sprintf: -var formatRegex = new RegExp("([^%]+|%[\\+\\-\\ \\#0]*[0-9\\*]*(.[0-9\\*]+)?[hlL]?[cbBdieEfgGosuxXpn%@])", "g"); -var tagRegex = new RegExp("(%)([\\+\\-\\ \\#0]*)([0-9\\*]*)((.[0-9\\*]+)?)([hlL]?)([cbBdieEfgGosuxXpn%@])"); +var formatRegex = new RegExp("([^%]+|%(?:\\d+\\$)?[\\+\\-\\ \\#0]*[0-9\\*]*(.[0-9\\*]+)?[hlL]?[cbBdieEfgGosuxXpn%@])", "g"); +var tagRegex = new RegExp("(%)(?:(\\d+)\\$)?([\\+\\-\\ \\#0]*)([0-9\\*]*)((?:.[0-9\\*]+)?)([hlL]?)([cbBdieEfgGosuxXpn%@])"); exports.sprintf = function(format) { @@ -55,21 +55,27 @@ exports.sprintf = function(format) } var percentSign = subtokens[1], - flags = subtokens[2], - widthString = subtokens[3], - precisionString = subtokens[4], + argIndex = subtokens[2], + flags = subtokens[3], + widthString = subtokens[4], + precisionString = subtokens[5], length = subtokens[6], specifier = subtokens[7]; + if (argIndex === undefined || argIndex === null || argIndex === "") + argIndex = arg++; + else + argIndex = Number(argIndex); + var width = null; if (widthString == "*") - width = arguments[arg++]; + width = arguments[argIndex]; else if (widthString != "") width = Number(widthString); var precision = null; if (precisionString == ".*") - precision = arguments[arg++]; + precision = arguments[argIndex]; else if (precisionString != "") precision = Number(precisionString.substring(1)); @@ -80,7 +86,7 @@ exports.sprintf = function(format) if (RegExp("[bBdiufeExXo]").test(specifier)) { - var num = Number(arguments[arg++]); + var num = Number(arguments[argIndex]); var sign = ""; if (num < 0) @@ -154,12 +160,11 @@ exports.sprintf = function(format) if (specifier == "%") subresult = "%"; else if (specifier == "c") - subresult = String(arguments[arg++]).charAt(0); + subresult = String(arguments[argIndex]).charAt(0); else if (specifier == "s" || specifier == "@") - subresult = String(arguments[arg++]); + subresult = String(arguments[argIndex]); else if (specifier == "p" || specifier == "n") { - arg++; subresult = ""; } diff --git a/Tests/Objective-J/sprintfTest.j b/Tests/Objective-J/sprintfTest.j index b51bb7cd0..785c7707c 100644 --- a/Tests/Objective-J/sprintfTest.j +++ b/Tests/Objective-J/sprintfTest.j @@ -1,20 +1,37 @@ - -// TODO: add many many more of these... -var sprintfTestCases = [ - [["[%@]", "hello world"], "[hello world]"], - [["[%d]", 123], "[123]"], - [["[%f]", 123.1234], "[123.1234]"], - [["[%d]", 123.1234], "[123]"] -]; +var sprintf = ObjectiveJ.sprintf; @implementation sprintfTest : OJTestCase -- (void)test_sprintf +// TODO: add many many more of these... + +- (void)testObjectWithPrefixAndSuffix { - for (var i = 0; i < sprintfTestCases.length; i++) - { - [self assert:ObjectiveJ.sprintf.apply(null, sprintfTestCases[i][0]) equals:sprintfTestCases[i][1]]; - } + [self assert:@"[hello world]" equals:sprintf(@"[%@]", @"hello world")]; +} + +- (void)testDecimalWithPrefixAndSuffix +{ + [self assert:@"[123]" equals:sprintf(@"[%d]", 123)]; +} + +- (void)testFloatWithPrefixAndSuffix +{ + [self assert:@"[123.1234]" equals:sprintf(@"[%f]", 123.1234)]; +} + +- (void)testZeroPaddingWithWidthAndPercentEscaping +{ + [self assert:@"099%" equals:sprintf(@"%03d%%", 99)]; +} + +- (void)testOutOfOrderExplicitFormatParameterIndexes +{ + [self assert:@"2 > 1" equals:sprintf(@"%2$d > %1$d", 1, 2)]; +} + +- (void)testMixingImplicitAndExplicitFormatParameterIndexes +{ + [self assert:@"a < b && b > a" equals:sprintf(@"%@ < %2$@ && %@ > %1$@", @"a", @"b")]; } @end