diff options
| author | mpeterv <mpeterval@gmail.com> | 2015-03-19 13:20:38 +0300 |
|---|---|---|
| committer | mpeterv <mpeterval@gmail.com> | 2015-03-19 13:32:12 +0300 |
| commit | cf1917849bc2e35a125c1d0142343c64da776fdf (patch) | |
| tree | 5ec39ed87d67b96340dab3a64b438371bacd3bce | |
| parent | 3c7c4722a5ab6aa32f62622643a5b68fa1e5a7d2 (diff) | |
| download | luarocks-cf1917849bc2e35a125c1d0142343c64da776fdf.tar.gz luarocks-cf1917849bc2e35a125c1d0142343c64da776fdf.tar.bz2 luarocks-cf1917849bc2e35a125c1d0142343c64da776fdf.zip | |
Refactor persist.save_from_table
* Update docstrings;
* Improve string quoting (don't produce broken code for strings with
backslashes);
* Use same function for writing keys and values;
* Don't use same name (write_table) for two different functions.
| -rw-r--r-- | src/luarocks/persist.lua | 70 |
1 files changed, 34 insertions, 36 deletions
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua index 8162c662..04440670 100644 --- a/src/luarocks/persist.lua +++ b/src/luarocks/persist.lua | |||
| @@ -83,10 +83,10 @@ end | |||
| 83 | 83 | ||
| 84 | local write_table | 84 | local write_table |
| 85 | 85 | ||
| 86 | --- Write a value as Lua code, invoking write_table. | 86 | --- Write a value as Lua code. |
| 87 | -- This function handles only numbers, strings and tables | 87 | -- This function handles only numbers and strings, invoking write_table |
| 88 | -- are keys (tables are handled recursively). | 88 | -- to write tables. |
| 89 | -- @param out userdata: a file object, open for writing. | 89 | -- @param out table or userdata: a writer object supporting :write() method. |
| 90 | -- @param v: the value to be written. | 90 | -- @param v: the value to be written. |
| 91 | -- @param level number: the indentation level | 91 | -- @param level number: the indentation level |
| 92 | -- @param sub_order table: optional prioritization table | 92 | -- @param sub_order table: optional prioritization table |
| @@ -95,28 +95,27 @@ local function write_value(out, v, level, sub_order) | |||
| 95 | if type(v) == "table" then | 95 | if type(v) == "table" then |
| 96 | write_table(out, v, level + 1, sub_order) | 96 | write_table(out, v, level + 1, sub_order) |
| 97 | elseif type(v) == "string" then | 97 | elseif type(v) == "string" then |
| 98 | if v:match("\n") then | 98 | if v:match("[\r\n]") then |
| 99 | local open, close = "[[", "]]" | 99 | local open, close = "[[", "]]" |
| 100 | local equals = 0 | 100 | local equals = 0 |
| 101 | while v:find(open,1,true) or v:find(close,1,true) do | 101 | while v:find(close, 1, true) do |
| 102 | equals = equals + 1 | 102 | equals = equals + 1 |
| 103 | local eqs = ("="):rep(equals) | 103 | local eqs = ("="):rep(equals) |
| 104 | open, close = "["..eqs.."[", "]"..eqs.."]" | 104 | open, close = "["..eqs.."[", "]"..eqs.."]" |
| 105 | end | 105 | end |
| 106 | out:write(open.."\n"..v..close) | 106 | out:write(open.."\n"..v..close) |
| 107 | else | 107 | else |
| 108 | out:write("\""..v:gsub("\"", "\\\"").."\"") | 108 | out:write("\""..v:gsub("\\", "\\\\"):gsub("\"", "\\\"").."\"") |
| 109 | end | 109 | end |
| 110 | else | 110 | else |
| 111 | out:write(tostring(v)) | 111 | out:write(tostring(v)) |
| 112 | end | 112 | end |
| 113 | end | 113 | end |
| 114 | 114 | ||
| 115 | --- Write a table as Lua code representing a table to disk | 115 | --- Write a table as Lua code in curly brackets notation to a writer object. |
| 116 | -- (that is, in curly brackets notation). | 116 | -- Only numbers, strings and tables (containing numbers, strings |
| 117 | -- This function handles only numbers, strings and tables | 117 | -- or other recursively processed tables) are supported. |
| 118 | -- are keys (tables are handled recursively). | 118 | -- @param out table or userdata: a writer object supporting :write() method. |
| 119 | -- @param out userdata: a file object, open for writing. | ||
| 120 | -- @param tbl table: the table to be written. | 119 | -- @param tbl table: the table to be written. |
| 121 | -- @param level number: the indentation level | 120 | -- @param level number: the indentation level |
| 122 | -- @param field_order table: optional prioritization table | 121 | -- @param field_order table: optional prioritization table |
| @@ -131,28 +130,29 @@ write_table = function(out, tbl, level, field_order) | |||
| 131 | if indent then | 130 | if indent then |
| 132 | for n = 1,level do out:write(indentation) end | 131 | for n = 1,level do out:write(indentation) end |
| 133 | end | 132 | end |
| 134 | sep = ",\n" | 133 | |
| 135 | indent = true | 134 | if k == i then |
| 136 | if type(k) == "number" then | 135 | i = i + 1 |
| 137 | if k ~= i then | ||
| 138 | out:write("["..tostring(k).."]=") | ||
| 139 | else | ||
| 140 | i = i + 1 | ||
| 141 | end | ||
| 142 | indent = false | ||
| 143 | sep = ", " | ||
| 144 | elseif type(k) == "table" then | ||
| 145 | out:write("[") | ||
| 146 | write_table(out, k, level + 1) | ||
| 147 | out:write("] = ") | ||
| 148 | else | 136 | else |
| 149 | if k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then | 137 | if type(k) == "string" and k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then |
| 150 | out:write(k.." = ") | 138 | out:write(k) |
| 151 | else | 139 | else |
| 152 | out:write("['"..k:gsub("'", "\\'").."'] = ") | 140 | out:write("[") |
| 141 | write_value(out, k, level) | ||
| 142 | out:write("]") | ||
| 153 | end | 143 | end |
| 144 | |||
| 145 | out:write(" = ") | ||
| 154 | end | 146 | end |
| 147 | |||
| 155 | write_value(out, v, level, sub_order) | 148 | write_value(out, v, level, sub_order) |
| 149 | if type(k) == "number" then | ||
| 150 | sep = ", " | ||
| 151 | indent = false | ||
| 152 | else | ||
| 153 | sep = ",\n" | ||
| 154 | indent = true | ||
| 155 | end | ||
| 156 | end | 156 | end |
| 157 | if sep ~= "\n" then | 157 | if sep ~= "\n" then |
| 158 | out:write("\n") | 158 | out:write("\n") |
| @@ -161,18 +161,16 @@ write_table = function(out, tbl, level, field_order) | |||
| 161 | out:write("}") | 161 | out:write("}") |
| 162 | end | 162 | end |
| 163 | 163 | ||
| 164 | --- Writes a table to an io-like object. | 164 | --- Write a table as series of assignments to a writer object. |
| 165 | -- @param out userdata: a file object, open for writing. | 165 | -- @param out table or userdata: a writer object supporting :write() method. |
| 166 | -- @param tbl table: the table to be written. | 166 | -- @param tbl table: the table to be written. |
| 167 | -- @param field_order table: optional prioritization table | 167 | -- @param field_order table: optional prioritization table |
| 168 | -- @return userdata The file object originally passed in as the `out` parameter. | 168 | local function write_table_as_assignments(out, tbl, field_order) |
| 169 | local function write_table(out, tbl, field_order) | ||
| 170 | for k, v, sub_order in util.sortedpairs(tbl, field_order) do | 169 | for k, v, sub_order in util.sortedpairs(tbl, field_order) do |
| 171 | out:write(k.." = ") | 170 | out:write(k.." = ") |
| 172 | write_value(out, v, 0, sub_order) | 171 | write_value(out, v, 0, sub_order) |
| 173 | out:write("\n") | 172 | out:write("\n") |
| 174 | end | 173 | end |
| 175 | return out | ||
| 176 | end | 174 | end |
| 177 | 175 | ||
| 178 | --- Save the contents of a table to a string. | 176 | --- Save the contents of a table to a string. |
| @@ -185,7 +183,7 @@ end | |||
| 185 | function persist.save_from_table_to_string(tbl, field_order) | 183 | function persist.save_from_table_to_string(tbl, field_order) |
| 186 | local out = {buffer = {}} | 184 | local out = {buffer = {}} |
| 187 | function out:write(data) table.insert(self.buffer, data) end | 185 | function out:write(data) table.insert(self.buffer, data) end |
| 188 | write_table(out, tbl, field_order) | 186 | write_table_as_assignments(out, tbl, field_order) |
| 189 | return table.concat(out.buffer) | 187 | return table.concat(out.buffer) |
| 190 | end | 188 | end |
| 191 | 189 | ||
| @@ -203,7 +201,7 @@ function persist.save_from_table(filename, tbl, field_order) | |||
| 203 | if not out then | 201 | if not out then |
| 204 | return nil, "Cannot create file at "..filename | 202 | return nil, "Cannot create file at "..filename |
| 205 | end | 203 | end |
| 206 | write_table(out, tbl, field_order) | 204 | write_table_as_assignments(out, tbl, field_order) |
| 207 | out:close() | 205 | out:close() |
| 208 | return true | 206 | return true |
| 209 | end | 207 | end |
