aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2012-05-20 23:27:38 -0300
committerHisham Muhammad <hisham@gobolinux.org>2012-05-20 23:28:43 -0300
commitd0aa4e236883fc7e118cab32207e8d585a935023 (patch)
tree1ec8ab7e08f6e5e0733aa5a3659eaf775d1d9e2e
parent4375316b4385cbc6c7268a547c3aa0415dc034ee (diff)
downloadluarocks-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.lua68
-rw-r--r--src/luarocks/util.lua35
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
46end 46end
47 47
48local 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
58local 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
77end
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
55local function write_table(out, tbl, level) 86-- @param field_order table: optional prioritization table
87write_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("}")
99end 126end
@@ -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.
107function save_from_table(filename, tbl) 137function 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
237local function sortedpairs_iterator(tbl, sort_function) 237local 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
243end 265end
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.
251function sortedpairs(tbl, sort_function) 276function 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)