aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/luarocks/persist.lua92
1 files changed, 48 insertions, 44 deletions
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua
index 9a40785c..04440670 100644
--- a/src/luarocks/persist.lua
+++ b/src/luarocks/persist.lua
@@ -9,8 +9,14 @@ package.loaded["luarocks.persist"] = persist
9 9
10local util = require("luarocks.util") 10local util = require("luarocks.util")
11 11
12--- Load and run a Lua file in an environment.
13-- @param filename string: the name of the file.
14-- @param env table: the environment table.
15-- @return (true, any) or (nil, string, string): true and the return value
16-- of the file, or nil, an error message and an error code ("open", "load"
17-- or "run") in case of errors.
12local function run_file(filename, env) 18local function run_file(filename, env)
13 local fd, err, errno = io.open(filename) 19 local fd, err = io.open(filename)
14 if not fd then 20 if not fd then
15 return nil, err, "open" 21 return nil, err, "open"
16 end 22 end
@@ -28,7 +34,7 @@ local function run_file(filename, env)
28 ran, err = pcall(chunk) 34 ran, err = pcall(chunk)
29 end 35 end
30 else -- Lua 5.2 36 else -- Lua 5.2
31 chunk, err = loadfile(filename, "t", env) 37 chunk, err = load(str, filename, "t", env)
32 if chunk then 38 if chunk then
33 ran, err = pcall(chunk) 39 ran, err = pcall(chunk)
34 end 40 end
@@ -47,9 +53,10 @@ end
47-- @param filename string: the name of the file. 53-- @param filename string: the name of the file.
48-- @param tbl table or nil: if given, this table is used to store 54-- @param tbl table or nil: if given, this table is used to store
49-- loaded values. 55-- loaded values.
50-- @return table or (nil, string, string): a table with the file's assignments 56-- @return (table, table) or (nil, string, string): a table with the file's
51-- as fields, or nil, an error message and an error code ("load" or "run") 57-- assignments as fields and set of undefined globals accessed in file,
52-- in case of errors. 58-- or nil, an error message and an error code ("open", "load" or "run") in
59-- case of errors.
53function persist.load_into_table(filename, tbl) 60function persist.load_into_table(filename, tbl)
54 assert(type(filename) == "string") 61 assert(type(filename) == "string")
55 assert(type(tbl) == "table" or not tbl) 62 assert(type(tbl) == "table" or not tbl)
@@ -57,9 +64,8 @@ function persist.load_into_table(filename, tbl)
57 local result = tbl or {} 64 local result = tbl or {}
58 local globals = {} 65 local globals = {}
59 local globals_mt = { 66 local globals_mt = {
60 __index = function(t, n) 67 __index = function(t, k)
61 globals[n] = true 68 globals[k] = true
62 return rawget(t, n)
63 end 69 end
64 } 70 }
65 local save_mt = getmetatable(result) 71 local save_mt = getmetatable(result)
@@ -77,10 +83,10 @@ end
77 83
78local write_table 84local write_table
79 85
80--- Write a value as Lua code, invoking write_table. 86--- Write a value as Lua code.
81-- This function handles only numbers, strings and tables 87-- This function handles only numbers and strings, invoking write_table
82-- are keys (tables are handled recursively). 88-- to write tables.
83-- @param out userdata: a file object, open for writing. 89-- @param out table or userdata: a writer object supporting :write() method.
84-- @param v: the value to be written. 90-- @param v: the value to be written.
85-- @param level number: the indentation level 91-- @param level number: the indentation level
86-- @param sub_order table: optional prioritization table 92-- @param sub_order table: optional prioritization table
@@ -89,28 +95,27 @@ local function write_value(out, v, level, sub_order)
89 if type(v) == "table" then 95 if type(v) == "table" then
90 write_table(out, v, level + 1, sub_order) 96 write_table(out, v, level + 1, sub_order)
91 elseif type(v) == "string" then 97 elseif type(v) == "string" then
92 if v:match("\n") then 98 if v:match("[\r\n]") then
93 local open, close = "[[", "]]" 99 local open, close = "[[", "]]"
94 local equals = 0 100 local equals = 0
95 while v:find(open,1,true) or v:find(close,1,true) do 101 while v:find(close, 1, true) do
96 equals = equals + 1 102 equals = equals + 1
97 local eqs = ("="):rep(equals) 103 local eqs = ("="):rep(equals)
98 open, close = "["..eqs.."[", "]"..eqs.."]" 104 open, close = "["..eqs.."[", "]"..eqs.."]"
99 end 105 end
100 out:write(open.."\n"..v..close) 106 out:write(open.."\n"..v..close)
101 else 107 else
102 out:write("\""..v:gsub("\"", "\\\"").."\"") 108 out:write("\""..v:gsub("\\", "\\\\"):gsub("\"", "\\\"").."\"")
103 end 109 end
104 else 110 else
105 out:write(tostring(v)) 111 out:write(tostring(v))
106 end 112 end
107end 113end
108 114
109--- 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.
110-- (that is, in curly brackets notation). 116-- Only numbers, strings and tables (containing numbers, strings
111-- This function handles only numbers, strings and tables 117-- or other recursively processed tables) are supported.
112-- are keys (tables are handled recursively). 118-- @param out table or userdata: a writer object supporting :write() method.
113-- @param out userdata: a file object, open for writing.
114-- @param tbl table: the table to be written. 119-- @param tbl table: the table to be written.
115-- @param level number: the indentation level 120-- @param level number: the indentation level
116-- @param field_order table: optional prioritization table 121-- @param field_order table: optional prioritization table
@@ -125,28 +130,29 @@ write_table = function(out, tbl, level, field_order)
125 if indent then 130 if indent then
126 for n = 1,level do out:write(indentation) end 131 for n = 1,level do out:write(indentation) end
127 end 132 end
128 sep = ",\n" 133
129 indent = true 134 if k == i then
130 if type(k) == "number" then 135 i = i + 1
131 if k ~= i then
132 out:write("["..tostring(k).."]=")
133 else
134 i = i + 1
135 end
136 indent = false
137 sep = ", "
138 elseif type(k) == "table" then
139 out:write("[")
140 write_table(out, k, level + 1)
141 out:write("] = ")
142 else 136 else
143 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
144 out:write(k.." = ") 138 out:write(k)
145 else 139 else
146 out:write("['"..k:gsub("'", "\\'").."'] = ") 140 out:write("[")
141 write_value(out, k, level)
142 out:write("]")
147 end 143 end
144
145 out:write(" = ")
148 end 146 end
147
149 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
150 end 156 end
151 if sep ~= "\n" then 157 if sep ~= "\n" then
152 out:write("\n") 158 out:write("\n")
@@ -155,18 +161,16 @@ write_table = function(out, tbl, level, field_order)
155 out:write("}") 161 out:write("}")
156end 162end
157 163
158--- Writes a table to an io-like object. 164--- Write a table as series of assignments to a writer object.
159-- @param out userdata: a file object, open for writing. 165-- @param out table or userdata: a writer object supporting :write() method.
160-- @param tbl table: the table to be written. 166-- @param tbl table: the table to be written.
161-- @param field_order table: optional prioritization table 167-- @param field_order table: optional prioritization table
162-- @return userdata The file object originally passed in as the `out` parameter. 168local function write_table_as_assignments(out, tbl, field_order)
163local function write_table(out, tbl, field_order)
164 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
165 out:write(k.." = ") 170 out:write(k.." = ")
166 write_value(out, v, 0, sub_order) 171 write_value(out, v, 0, sub_order)
167 out:write("\n") 172 out:write("\n")
168 end 173 end
169 return out
170end 174end
171 175
172--- Save the contents of a table to a string. 176--- Save the contents of a table to a string.
@@ -179,7 +183,7 @@ end
179function persist.save_from_table_to_string(tbl, field_order) 183function persist.save_from_table_to_string(tbl, field_order)
180 local out = {buffer = {}} 184 local out = {buffer = {}}
181 function out:write(data) table.insert(self.buffer, data) end 185 function out:write(data) table.insert(self.buffer, data) end
182 write_table(out, tbl, field_order) 186 write_table_as_assignments(out, tbl, field_order)
183 return table.concat(out.buffer) 187 return table.concat(out.buffer)
184end 188end
185 189
@@ -197,7 +201,7 @@ function persist.save_from_table(filename, tbl, field_order)
197 if not out then 201 if not out then
198 return nil, "Cannot create file at "..filename 202 return nil, "Cannot create file at "..filename
199 end 203 end
200 write_table(out, tbl, field_order) 204 write_table_as_assignments(out, tbl, field_order)
201 out:close() 205 out:close()
202 return true 206 return true
203end 207end