diff options
author | Ted Trask <ttrask01@yahoo.com> | 2008-05-08 17:18:26 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2008-05-08 17:18:26 +0000 |
commit | acd1228fe832030822c2d551332dc5d6b310ec91 (patch) | |
tree | 55e347f5386ce874f5c6150e998e60c12c0ca95f | |
parent | edfd85ee749aebacddee51c143902f2a2918b817 (diff) | |
download | acf-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.lua | 167 |
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 |