summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2008-05-08 17:18:26 +0000
committerTed Trask <ttrask01@yahoo.com>2008-05-08 17:18:26 +0000
commitacd1228fe832030822c2d551332dc5d6b310ec91 (patch)
tree55e347f5386ce874f5c6150e998e60c12c0ca95f
parentedfd85ee749aebacddee51c143902f2a2918b817 (diff)
downloadacf-core-acd1228fe832030822c2d551332dc5d6b310ec91.tar.bz2
acf-core-acd1228fe832030822c2d551332dc5d6b310ec91.tar.xz
Rewrote getopts.setoptsinfile function and fixed bugs in getopts.getoptsfromfile
git-svn-id: svn://svn.alpinelinux.org/acf/core/trunk@1114 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r--lib/getopts.lua167
1 files changed, 126 insertions, 41 deletions
diff --git a/lib/getopts.lua b/lib/getopts.lua
index e2de912..0970e20 100644
--- a/lib/getopts.lua
+++ b/lib/getopts.lua
@@ -1,85 +1,170 @@
module (..., package.seeall)
require("fs")
+-- Create a new config file entry
+-- see function description for setoptsinfile
+-- line is the current line for this name:value if it exists
+local create_entry = function(search_name, value, to_table, optionvalue, line)
+ local oldvalue, comment = "", ""
+ if line then
+ -- find the old value
+ oldvalue = string.match ( line, '^%s*%S+%s*%=%s*(.*)$' ) or ""
+ -- split out comment
+ if string.find ( oldvalue, '#' ) then
+ oldvalue, comment = string.match ( oldvalue, '^(.*)(#.*)$' )
+ if comment then
+ comment = " " .. string.match ( comment, '^(.*%S)%s*$' )
+ else
+ comment = ""
+ end
+ end
+ -- remove spaces
+ oldvalue = string.match ( oldvalue, '^%s*(.*%S)%s*$' ) or ""
+ end
+
+ if to_table == true then
+ local table = opts_to_table(oldvalue) or {}
+ table[value] = optionvalue
+ return search_name .. "=" .. table_to_opts(table) .. comment
+ else
+ if value then
+ return search_name .. "=" .. value .. comment
+ else
+ return nil
+ end
+ end
+end
+
-- Search the option string for separate options (-x or --xyz) and put them in a table
-local opts_to_table = function ( optstring, filter )
+opts_to_table = function ( optstring, filter )
local optsparams
if optstring then
- local optstr = " " .. optstring .. " "
- for o in string.gmatch(optstr, "%s%-%-?%a+%s+%a*") do
+ local optstr = optstring .. " "
+ for o in string.gmatch(optstr, "%-%-?%a+%s+[^-%s]*") do
local option = string.match(o, "%-%-?%a+")
if not filter or filter == option then
if not optsparams then optsparams = {} end
- optsparams[option] = string.match(o, "%a*$")
+ optsparams[option] = string.match(o, "%S*$")
end
end
end
return optsparams
end
-function setoptsinfile (file, search, option, value)
- local opts = {}
- local newfilecontent = nil
- local filecontent = nil
- opts = getoptsfromfile(file) or {}
- filecontent = fs.read_file(file) or ""
- if (filecontent == "") or (opts[search] == "") or (opts[search] == nil) then
- opts[search] = {}
- end
- if not (search) or not (option) then
- return fales, nil, "Systeminformation - Invalid usage of function getopts.setoptsinfile()"
+-- Go through an options table and create the option string
+table_to_opts = function ( optsparams )
+ local optstring = {}
+ for opt,val in pairs(optsparams) do
+ if val ~= "" then
+ optstring[#optstring + 1] = opt .. " " .. val
+ else
+ optstring[#optstring + 1] = opt
+ end
end
+ return table.concat(optstring, " ")
+end
- --Change to new value
- opts[search][option] = value
-
- local optstr = ""
- for k,v in pairs(opts) do
- if (k == search) then
- optstr = optstr.. k .. "=\""
- for kk,vv in pairs(v) do
- optstr = optstr .. kk .. " " .. vv .. " "
+-- Set a name=value pair
+-- If search_section is undefined or "", goes in the default section
+-- If to_table is false or undefined
+-- if value is defined we put "search_name=value" into search_section
+-- if value is undefined, we clear search_name out of search section
+-- If to_table is true (and value is defined)
+-- if optionvalue defined, we add "search_value optionvalue" to the value for search_name in search_section
+-- if optionvalue undefined, we remove search_value from the value of search_name in search_section
+-- Try not to touch anything but the value we're interested in (although will combine multi-line into one)
+-- If the search_section is not found, we'll add it at the end of the file
+-- If the search_name is not found, we'll add it at the end of the section
+function setoptsinfile (file, search_section, search_name, value, to_table, optionvalue)
+ if not file or file == "" or not search_name or search_name == "" or (to_table == true and not value) then
+ return false, nil, "Invalid input for getopts.setoptsinfile()"
+ end
+ search_section = search_section or ""
+ local conf_file = fs.read_file_as_array ( file )
+ local new_conf_file = {}
+ local section = ""
+ local done = false
+ local skip_lines = 0
+ for i,l in ipairs(conf_file) do
+ if skip_lines>0 then
+ skip_lines = skip_lines-1
+ else
+ -- check if comment line
+ if done == false and not string.find ( l, "^%s*#" ) then
+ -- first, concat lines
+ local j = 1
+ while string.find ( l, "\\%s*$" ) and conf_file[i+j] do
+ l = string.match ( l, "^(.*)\\%s*$" ) .. " " .. conf_file[i+j]
+ j = j+1
+ end
+ if j>1 then skip_lines = j-1 end
+ -- find section name
+ local a = string.match ( l, "^%s*%[%s*(%S+)%s*%]" )
+ if a then
+ -- we reached a new section, if we were in the one we wanted
+ -- we have to add in the name:value pair now
+ if (search_section == section) then
+ new_conf_file[#new_conf_file + 1] = create_entry(search_name, value, to_table, optionvalue, nil)
+ done = true
+ end
+ section = a
+ elseif (search_section == section) then
+ -- find name
+ a = string.match ( l, "^%s*(%S+)%s*=" )
+ if a and (search_name == a) then
+ -- We found the name, change the value
+ l = create_entry(search_name, value, to_table, optionvalue, l)
+ done = true
+ end
+ end
end
- optstr = string.match(optstr, "(.-)%s*$") .. "\""
+ new_conf_file[#new_conf_file + 1] = l
end
end
- newfilecontent = string.gsub(filecontent, "%s*[;#]?" .. search .. "%s*=.-\n?$", "\n" .. optstr .. "\n") or ""
- if (string.find(newfilecontent, search .. "%s*=" ) == nil) or (newfilecontent == "") then
- fs.write_file(file,string.match(filecontent, "(.-)\n*$") .. "\n" .. optstr .. "\n")
- else
- fs.write_file(file,string.match(newfilecontent, "(.-)\n*$"))
+ if done == false then
+ -- we didn't find the section:name, add it now
+ if section ~= search_section then
+ new_conf_file[#new_conf_file + 1] = '[' .. search_section .. ']'
+ end
+ new_conf_file[#new_conf_file + 1] = create_entry(search_name, value, to_table, optionvalue, nil)
end
- return true, "File '" .. file .. "' has been modifyed!", nil
+
+ fs.write_file(file, table.concat(new_conf_file, '\n'))
+ return true, "File '" .. file .. "' has been modified!", nil
end
--- Parse file for options returned in a table
--- If search_section is defined, only report options in matching section
--- If search_option is defined, only report matching options
--- If to_table is true, attempt to convert option string to array of options
+-- Parse file for name=value pairs, returned in a table
+-- If search_section is defined, only report values in matching section
+-- If search_name is defined, only report matching name (possibly in multiple sections)
+-- If to_table is true, attempt to convert value string to array of options
-- If filter is defined (and table is true), only list option matching filter
-function getoptsfromfile (file, search_section, search_option, to_table, filter)
+function getoptsfromfile (file, search_section, search_name, to_table, filter)
local opts = nil
if not (fs.is_file(file)) then return nil end
local conf_file = fs.read_file_as_array ( file )
local section = ""
+ local skip_lines = 0
for i,l in ipairs(conf_file) do
+ if skip_lines>0 then
+ skip_lines = skip_lines-1
-- check if comment line
- if not string.find ( l, "^%s*#" ) then
+ elseif not string.find ( l, "^%s*#" ) then
-- first, concat lines
local j = 1
while string.find ( l, "\\%s*$" ) and conf_file[i+j] do
l = string.match ( l, "^(.*)\\%s*$" ) .. " " .. conf_file[i+j]
j = j+1
end
+ if j>1 then skip_lines = j-1 end
-- find section name
local a = string.match ( l, "^%s*%[%s*(%S+)%s*%]" )
if a then
section = a
elseif not (search_section) or (search_section == section) then
- -- find option name
+ -- find name
a = string.match ( l, "^%s*(%S+)%s*=" )
- if a and (not (search_option) or (search_option == a)) then
+ if a and (not (search_name) or (search_name == a)) then
-- Figure out the value
local b = string.match ( l, '^%s*%S+%s*%=%s*(.*)$' ) or ""
-- remove comments from end of line
@@ -112,8 +197,8 @@ function getoptsfromfile (file, search_section, search_option, to_table, filter)
end
end
- if opts and search_section and search_option then
- return opts[search_section][search_option]
+ if opts and search_section and search_name then
+ return opts[search_section][search_name]
elseif opts and search_section then
return opts[search_section]
end