diff options
| author | Hisham Muhammad <hisham@gobolinux.org> | 2012-05-20 23:27:38 -0300 |
|---|---|---|
| committer | Hisham Muhammad <hisham@gobolinux.org> | 2012-05-20 23:28:43 -0300 |
| commit | d0aa4e236883fc7e118cab32207e8d585a935023 (patch) | |
| tree | 1ec8ab7e08f6e5e0733aa5a3659eaf775d1d9e2e /src | |
| parent | 4375316b4385cbc6c7268a547c3aa0415dc034ee (diff) | |
| download | luarocks-d0aa4e236883fc7e118cab32207e8d585a935023.tar.gz luarocks-d0aa4e236883fc7e118cab32207e8d585a935023.tar.bz2 luarocks-d0aa4e236883fc7e118cab32207e8d585a935023.zip | |
Add support for a priority table when writing files.
Diffstat (limited to 'src')
| -rw-r--r-- | src/luarocks/persist.lua | 68 | ||||
| -rw-r--r-- | src/luarocks/util.lua | 35 |
2 files changed, 79 insertions, 24 deletions
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua index 182b3da6..0d37b04a 100644 --- a/src/luarocks/persist.lua +++ b/src/luarocks/persist.lua | |||
| @@ -45,6 +45,37 @@ function load_into_table(filename, tbl) | |||
| 45 | return result | 45 | return result |
| 46 | end | 46 | end |
| 47 | 47 | ||
| 48 | local write_table | ||
| 49 | |||
| 50 | --- Write a value as Lua code, invoking write_table. | ||
| 51 | -- This function handles only numbers, strings and tables | ||
| 52 | -- are keys (tables are handled recursively). | ||
| 53 | -- @param out userdata: a file object, open for writing. | ||
| 54 | -- @param v: the value to be written. | ||
| 55 | -- @param level number: the indentation level | ||
| 56 | -- @param sub_order table: optional prioritization table | ||
| 57 | -- @see write_table | ||
| 58 | local function write_value(out, v, level, sub_order) | ||
| 59 | if type(v) == "table" then | ||
| 60 | write_table(out, v, level + 1, sub_order) | ||
| 61 | elseif type(v) == "string" then | ||
| 62 | if v:match("\n") then | ||
| 63 | local open, close = "[[", "]]" | ||
| 64 | local equals = 0 | ||
| 65 | while v:find(open,1,true) or v:find(close,1,true) do | ||
| 66 | equals = equals + 1 | ||
| 67 | local eqs = ("="):rep(equals) | ||
| 68 | open, close = "["..eqs.."[", "]"..eqs.."]" | ||
| 69 | end | ||
| 70 | out:write(open.."\n"..v..close) | ||
| 71 | else | ||
| 72 | out:write("\""..v:gsub("\"", "\\\"").."\"") | ||
| 73 | end | ||
| 74 | else | ||
| 75 | out:write(tostring(v)) | ||
| 76 | end | ||
| 77 | end | ||
| 78 | |||
| 48 | --- Write a table as Lua code representing a table to disk | 79 | --- Write a table as Lua code representing a table to disk |
| 49 | -- (that is, in curly brackets notation). | 80 | -- (that is, in curly brackets notation). |
| 50 | -- This function handles only numbers, strings and tables | 81 | -- This function handles only numbers, strings and tables |
| @@ -52,21 +83,23 @@ end | |||
| 52 | -- @param out userdata: a file object, open for writing. | 83 | -- @param out userdata: a file object, open for writing. |
| 53 | -- @param tbl table: the table to be written. | 84 | -- @param tbl table: the table to be written. |
| 54 | -- @param level number: the indentation level | 85 | -- @param level number: the indentation level |
| 55 | local function write_table(out, tbl, level) | 86 | -- @param field_order table: optional prioritization table |
| 87 | write_table = function(out, tbl, level, field_order) | ||
| 56 | out:write("{") | 88 | out:write("{") |
| 57 | local sep = "\n" | 89 | local sep = "\n" |
| 90 | local indentation = " " | ||
| 58 | local indent = true | 91 | local indent = true |
| 59 | local i = 1 | 92 | local i = 1 |
| 60 | for k, v in util.sortedpairs(tbl) do | 93 | for k, v, sub_order in util.sortedpairs(tbl, field_order) do |
| 61 | out:write(sep) | 94 | out:write(sep) |
| 62 | if indent then | 95 | if indent then |
| 63 | for n = 1,level do out:write(" ") end | 96 | for n = 1,level do out:write(indentation) end |
| 64 | end | 97 | end |
| 65 | sep = ",\n" | 98 | sep = ",\n" |
| 66 | indent = true | 99 | indent = true |
| 67 | if type(k) == "number" then | 100 | if type(k) == "number" then |
| 68 | if k ~= i then | 101 | if k ~= i then |
| 69 | out:write('['..tostring(k).."]=") | 102 | out:write("["..tostring(k).."]=") |
| 70 | else | 103 | else |
| 71 | i = i + 1 | 104 | i = i + 1 |
| 72 | end | 105 | end |
| @@ -75,25 +108,19 @@ local function write_table(out, tbl, level) | |||
| 75 | elseif type(k) == "table" then | 108 | elseif type(k) == "table" then |
| 76 | out:write("[") | 109 | out:write("[") |
| 77 | write_table(out, k, level + 1) | 110 | write_table(out, k, level + 1) |
| 78 | out:write("]=") | 111 | out:write("] = ") |
| 79 | else | 112 | else |
| 80 | if k:match("^[a-z_]+$") then | 113 | if k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then |
| 81 | out:write(k.."=") | 114 | out:write(k.." = ") |
| 82 | else | 115 | else |
| 83 | out:write("['"..k:gsub("'", "\\'").."']=") | 116 | out:write("['"..k:gsub("'", "\\'").."'] = ") |
| 84 | end | 117 | end |
| 85 | end | 118 | end |
| 86 | if type(v) == "table" then | 119 | write_value(out, v, level, sub_order) |
| 87 | write_table(out, v, level + 1) | ||
| 88 | elseif type(v) == "string" then | ||
| 89 | out:write("'"..v:gsub("'", "\\'").."'") | ||
| 90 | else | ||
| 91 | out:write(tostring(v)) | ||
| 92 | end | ||
| 93 | end | 120 | end |
| 94 | if sep ~= "\n" then | 121 | if sep ~= "\n" then |
| 95 | out:write("\n") | 122 | out:write("\n") |
| 96 | for n = 1,level-1 do out:write(" ") end | 123 | for n = 1,level-1 do out:write(indentation) end |
| 97 | end | 124 | end |
| 98 | out:write("}") | 125 | out:write("}") |
| 99 | end | 126 | end |
| @@ -102,16 +129,19 @@ end | |||
| 102 | -- Each element of the table is saved as a global assignment. | 129 | -- Each element of the table is saved as a global assignment. |
| 103 | -- Only numbers, strings and tables (containing numbers, strings | 130 | -- Only numbers, strings and tables (containing numbers, strings |
| 104 | -- or other recursively processed tables) are supported. | 131 | -- or other recursively processed tables) are supported. |
| 132 | -- @param filename string: the output filename | ||
| 133 | -- @param tbl table: the table containing the data to be written | ||
| 134 | -- @param field_order table: an optional array indicating the order of top-level fields. | ||
| 105 | -- @return boolean or (nil, string): true if successful, or nil and a | 135 | -- @return boolean or (nil, string): true if successful, or nil and a |
| 106 | -- message in case of errors. | 136 | -- message in case of errors. |
| 107 | function save_from_table(filename, tbl) | 137 | function save_from_table(filename, tbl, field_order) |
| 108 | local out = io.open(filename, "w") | 138 | local out = io.open(filename, "w") |
| 109 | if not out then | 139 | if not out then |
| 110 | return nil, "Cannot create file at "..filename | 140 | return nil, "Cannot create file at "..filename |
| 111 | end | 141 | end |
| 112 | for k, v in util.sortedpairs(tbl) do | 142 | for k, v, sub_order in util.sortedpairs(tbl, field_order) do |
| 113 | out:write(k.." = ") | 143 | out:write(k.." = ") |
| 114 | write_table(out, v, 1) | 144 | write_value(out, v, 0, sub_order) |
| 115 | out:write("\n") | 145 | out:write("\n") |
| 116 | end | 146 | end |
| 117 | out:close() | 147 | out:close() |
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 96ea03b8..2955be50 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua | |||
| @@ -236,17 +236,42 @@ end | |||
| 236 | -- @see sortedpairs | 236 | -- @see sortedpairs |
| 237 | local function sortedpairs_iterator(tbl, sort_function) | 237 | local function sortedpairs_iterator(tbl, sort_function) |
| 238 | local ks = keys(tbl) | 238 | local ks = keys(tbl) |
| 239 | table.sort(ks, sort_function or default_sort) | 239 | if not sort_function or type(sort_function) == "function" then |
| 240 | for _, k in ipairs(ks) do | 240 | table.sort(ks, sort_function or default_sort) |
| 241 | coroutine.yield(k, tbl[k]) | 241 | for _, k in ipairs(ks) do |
| 242 | coroutine.yield(k, tbl[k]) | ||
| 243 | end | ||
| 244 | else | ||
| 245 | local order = sort_function | ||
| 246 | local done = {} | ||
| 247 | for _, k in ipairs(order) do | ||
| 248 | local sub_order | ||
| 249 | if type(k) == "table" then | ||
| 250 | sub_order = k[2] | ||
| 251 | k = k[1] | ||
| 252 | end | ||
| 253 | if tbl[k] then | ||
| 254 | done[k] = true | ||
| 255 | coroutine.yield(k, tbl[k], sub_order) | ||
| 256 | end | ||
| 257 | end | ||
| 258 | table.sort(ks, default_sort) | ||
| 259 | for _, k in ipairs(ks) do | ||
| 260 | if not done[k] then | ||
| 261 | coroutine.yield(k, tbl[k]) | ||
| 262 | end | ||
| 263 | end | ||
| 242 | end | 264 | end |
| 243 | end | 265 | end |
| 244 | 266 | ||
| 245 | --- A table iterator generator that returns elements sorted by key, | 267 | --- A table iterator generator that returns elements sorted by key, |
| 246 | -- to be used in "for" loops. | 268 | -- to be used in "for" loops. |
| 247 | -- @param tbl table: The table to be iterated. | 269 | -- @param tbl table: The table to be iterated. |
| 248 | -- @param sort_function function or nil: An optional comparison function | 270 | -- @param sort_function function or table or nil: An optional comparison function |
| 249 | -- to be used by table.sort when sorting keys. | 271 | -- to be used by table.sort when sorting keys, or an array listing an explicit order |
| 272 | -- for keys. If a value itself is an array, it is taken so that the first element | ||
| 273 | -- is a string representing the field name, and the second element is a priority table | ||
| 274 | -- for that key. | ||
| 250 | -- @return function: the iterator function. | 275 | -- @return function: the iterator function. |
| 251 | function sortedpairs(tbl, sort_function) | 276 | function sortedpairs(tbl, sort_function) |
| 252 | return coroutine.wrap(function() sortedpairs_iterator(tbl, sort_function) end) | 277 | return coroutine.wrap(function() sortedpairs_iterator(tbl, sort_function) end) |
