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 | |
parent | 4375316b4385cbc6c7268a547c3aa0415dc034ee (diff) | |
download | luarocks-d0aa4e236883fc7e118cab32207e8d585a935023.tar.gz luarocks-d0aa4e236883fc7e118cab32207e8d585a935023.tar.bz2 luarocks-d0aa4e236883fc7e118cab32207e8d585a935023.zip |
Add support for a priority table when writing files.
-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) |