Annotate

util/format.lua @ 11875:210a785dfa8a

mod_mam: Use util.dataforms timestamp validation
author Kim Alvefur <zash@zash.se>
date Tue, 26 Oct 2021 13:31:40 +0200
parent 11648:96d3cbeb9275
child 12031:87bc26f23d9b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
1 --
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
2 -- A string.format wrapper that gracefully handles invalid arguments
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
3 --
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
4
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
5 local tostring = tostring;
8417
e88db5668cfb util.format: Import unpack from table lib in Lua 5.2+
Kim Alvefur <zash@zash.se>
parents: 8383
diff changeset
6 local unpack = table.unpack or unpack; -- luacheck: ignore 113/unpack
9687
8c92ef4270c9 util.format: Use pack from util.table
Kim Alvefur <zash@zash.se>
parents: 9656
diff changeset
7 local pack = require "util.table".pack; -- TODO table.pack in 5.2+
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
8 local type = type;
9693
6ed0d6224d64 util.format: Serialize values for the %q format
Kim Alvefur <zash@zash.se>
parents: 9687
diff changeset
9 local dump = require "util.serialization".new("debug");
10035
386f085820e6 util.format: Handle integer formats the same way on Lua versions without integer support
Kim Alvefur <zash@zash.se>
parents: 10034
diff changeset
10 local num_type = math.type or function (n)
386f085820e6 util.format: Handle integer formats the same way on Lua versions without integer support
Kim Alvefur <zash@zash.se>
parents: 10034
diff changeset
11 return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float";
386f085820e6 util.format: Handle integer formats the same way on Lua versions without integer support
Kim Alvefur <zash@zash.se>
parents: 10034
diff changeset
12 end
10034
4fca92d60040 util.format: Handle formats expecting an integer in Lua 5.3+ (fixes #1371)
Kim Alvefur <zash@zash.se>
parents: 9693
diff changeset
13
10035
386f085820e6 util.format: Handle integer formats the same way on Lua versions without integer support
Kim Alvefur <zash@zash.se>
parents: 10034
diff changeset
14 -- In Lua 5.3+ these formats throw an error if given a float
386f085820e6 util.format: Handle integer formats the same way on Lua versions without integer support
Kim Alvefur <zash@zash.se>
parents: 10034
diff changeset
15 local expects_integer = { c = true, d = true, i = true, o = true, u = true, X = true, x = true, };
11638
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
16 -- Printable Unicode replacements for control characters
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
17 local control_symbols = {
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
18 -- 0x00 .. 0x1F --> U+2400 .. U+241F, 0x7F --> U+2421
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
19 ["\000"] = "\226\144\128", ["\001"] = "\226\144\129", ["\002"] = "\226\144\130",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
20 ["\003"] = "\226\144\131", ["\004"] = "\226\144\132", ["\005"] = "\226\144\133",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
21 ["\006"] = "\226\144\134", ["\007"] = "\226\144\135", ["\008"] = "\226\144\136",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
22 ["\009"] = "\226\144\137", ["\010"] = "\226\144\138", ["\011"] = "\226\144\139",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
23 ["\012"] = "\226\144\140", ["\013"] = "\226\144\141", ["\014"] = "\226\144\142",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
24 ["\015"] = "\226\144\143", ["\016"] = "\226\144\144", ["\017"] = "\226\144\145",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
25 ["\018"] = "\226\144\146", ["\019"] = "\226\144\147", ["\020"] = "\226\144\148",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
26 ["\021"] = "\226\144\149", ["\022"] = "\226\144\150", ["\023"] = "\226\144\151",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
27 ["\024"] = "\226\144\152", ["\025"] = "\226\144\153", ["\026"] = "\226\144\154",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
28 ["\027"] = "\226\144\155", ["\028"] = "\226\144\156", ["\029"] = "\226\144\157",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
29 ["\030"] = "\226\144\158", ["\031"] = "\226\144\159", ["\127"] = "\226\144\161",
5f4a657136bc util.format: Escape ASCII control characters in output
Kim Alvefur <zash@zash.se>
parents: 10035
diff changeset
30 };
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
31
8382
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8225
diff changeset
32 local function format(formatstring, ...)
9687
8c92ef4270c9 util.format: Use pack from util.table
Kim Alvefur <zash@zash.se>
parents: 9656
diff changeset
33 local args = pack(...);
8c92ef4270c9 util.format: Use pack from util.table
Kim Alvefur <zash@zash.se>
parents: 9656
diff changeset
34 local args_length = args.n;
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
35
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
36 -- format specifier spec:
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
37 -- 1. Start: '%%'
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
38 -- 2. Flags: '[%-%+ #0]'
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
39 -- 3. Width: '%d?%d?'
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
40 -- 4. Precision: '%.?%d?%d?'
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
41 -- 5. Option: '[cdiouxXaAeEfgGqs%%]'
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
42 --
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
43 -- 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.
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
44 -- This function does not accept string values containing embedded zeros, except as arguments to the q option.
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
45 -- a and A are only in Lua 5.2+
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
46
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
47
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
48 -- process each format specifier
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
49 local i = 0;
8382
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8225
diff changeset
50 formatstring = formatstring:gsub("%%[^cdiouxXaAeEfgGqs%%]*[cdiouxXaAeEfgGqs%%]", function(spec)
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
51 if spec ~= "%%" then
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
52 i = i + 1;
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
53 local arg = args[i];
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
54
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
55 local option = spec:sub(-1);
9656
3da6cc927ee6 util.format: Tweak how nil values are handled
Kim Alvefur <zash@zash.se>
parents: 8417
diff changeset
56 if arg == nil then
3da6cc927ee6 util.format: Tweak how nil values are handled
Kim Alvefur <zash@zash.se>
parents: 8417
diff changeset
57 args[i] = "nil";
11644
fc1b8fe94d04 util.format: Change formatting of nil values to avoid looking like XML
Kim Alvefur <zash@zash.se>
parents: 11638
diff changeset
58 spec = "(%s)";
9693
6ed0d6224d64 util.format: Serialize values for the %q format
Kim Alvefur <zash@zash.se>
parents: 9687
diff changeset
59 elseif option == "q" then
6ed0d6224d64 util.format: Serialize values for the %q format
Kim Alvefur <zash@zash.se>
parents: 9687
diff changeset
60 args[i] = dump(arg);
6ed0d6224d64 util.format: Serialize values for the %q format
Kim Alvefur <zash@zash.se>
parents: 9687
diff changeset
61 spec = "%s";
6ed0d6224d64 util.format: Serialize values for the %q format
Kim Alvefur <zash@zash.se>
parents: 9687
diff changeset
62 elseif option == "s" then
11647
0fe6a9a3676f util.format: Allow newlines but ensure following lines are indented
Kim Alvefur <zash@zash.se>
parents: 11646
diff changeset
63 args[i] = tostring(arg):gsub("[%z\1-\8\11-\31\127]", control_symbols):gsub("\n\t?", "\n\t");
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
64 elseif type(arg) ~= "number" then -- arg isn't number as expected?
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
65 args[i] = tostring(arg);
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
66 spec = "[%s]";
10034
4fca92d60040 util.format: Handle formats expecting an integer in Lua 5.3+ (fixes #1371)
Kim Alvefur <zash@zash.se>
parents: 9693
diff changeset
67 elseif expects_integer[option] and num_type(arg) ~= "integer" then
4fca92d60040 util.format: Handle formats expecting an integer in Lua 5.3+ (fixes #1371)
Kim Alvefur <zash@zash.se>
parents: 9693
diff changeset
68 args[i] = tostring(arg);
4fca92d60040 util.format: Handle formats expecting an integer in Lua 5.3+ (fixes #1371)
Kim Alvefur <zash@zash.se>
parents: 9693
diff changeset
69 spec = "[%s]";
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
70 end
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
71 end
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
72 return spec;
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
73 end);
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
74
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
75 -- process extra args
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
76 while i < args_length do
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
77 i = i + 1;
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
78 local arg = args[i];
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
79 if arg == nil then
11644
fc1b8fe94d04 util.format: Change formatting of nil values to avoid looking like XML
Kim Alvefur <zash@zash.se>
parents: 11638
diff changeset
80 args[i] = "(nil)";
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
81 else
11648
96d3cbeb9275 util.format: Escape ASCII control characters also in extra arguments
Kim Alvefur <zash@zash.se>
parents: 11647
diff changeset
82 args[i] = tostring(arg):gsub("[%z\1-\8\11-\31\127]", control_symbols):gsub("\n\t?", "\n\t");
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
83 end
8382
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8225
diff changeset
84 formatstring = formatstring .. " [%s]"
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
85 end
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
86
8382
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8225
diff changeset
87 return formatstring:format(unpack(args));
8225
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
88 end
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
89
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
90 return {
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
91 format = format;
70cb72f46a3b util.format: A string.format wrapper that gracefully handles invalid arguments
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
92 };