Software /
code /
prosody
Comparison
util/format.lua @ 8225:70cb72f46a3b
util.format: A string.format wrapper that gracefully handles invalid arguments
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Sun, 10 Sep 2017 12:42:05 -0400 |
child | 8382:e5d00bf4a4d5 |
comparison
equal
deleted
inserted
replaced
8207:8ea0484871e8 | 8225:70cb72f46a3b |
---|---|
1 -- | |
2 -- A string.format wrapper that gracefully handles invalid arguments | |
3 -- | |
4 | |
5 local tostring = tostring; | |
6 local select = select; | |
7 local assert = assert; | |
8 local unpack = unpack; | |
9 local type = type; | |
10 | |
11 local function format(format, ...) | |
12 local args, args_length = { ... }, select('#', ...); | |
13 | |
14 -- format specifier spec: | |
15 -- 1. Start: '%%' | |
16 -- 2. Flags: '[%-%+ #0]' | |
17 -- 3. Width: '%d?%d?' | |
18 -- 4. Precision: '%.?%d?%d?' | |
19 -- 5. Option: '[cdiouxXaAeEfgGqs%%]' | |
20 -- | |
21 -- The options c, d, E, e, f, g, G, i, o, u, X, and x all expect a number as argument, whereas q and s expect a string. | |
22 -- This function does not accept string values containing embedded zeros, except as arguments to the q option. | |
23 -- a and A are only in Lua 5.2+ | |
24 | |
25 | |
26 -- process each format specifier | |
27 local i = 0; | |
28 format = format:gsub("%%[^cdiouxXaAeEfgGqs%%]*[cdiouxXaAeEfgGqs%%]", function(spec) | |
29 if spec ~= "%%" then | |
30 i = i + 1; | |
31 local arg = args[i]; | |
32 if arg == nil then -- special handling for nil | |
33 arg = "<nil>" | |
34 args[i] = "<nil>"; | |
35 end | |
36 | |
37 local option = spec:sub(-1); | |
38 if option == "q" or option == "s" then -- arg should be string | |
39 args[i] = tostring(arg); | |
40 elseif type(arg) ~= "number" then -- arg isn't number as expected? | |
41 args[i] = tostring(arg); | |
42 spec = "[%s]"; | |
43 end | |
44 end | |
45 return spec; | |
46 end); | |
47 | |
48 -- process extra args | |
49 while i < args_length do | |
50 i = i + 1; | |
51 local arg = args[i]; | |
52 if arg == nil then | |
53 args[i] = "<nil>"; | |
54 else | |
55 args[i] = tostring(arg); | |
56 end | |
57 format = format .. " [%s]" | |
58 end | |
59 | |
60 return format:format(unpack(args)); | |
61 end | |
62 | |
63 local function test() | |
64 assert(format("%s", "hello") == "hello"); | |
65 assert(format("%s") == "<nil>"); | |
66 assert(format("%s", true) == "true"); | |
67 assert(format("%d", true) == "[true]"); | |
68 assert(format("%%", true) == "% [true]"); | |
69 end | |
70 | |
71 return { | |
72 format = format; | |
73 test = test; | |
74 }; |