From 9f469a06780e66135cb3da9cfdedb48763931160 Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Thu, 31 Dec 2009 14:27:23 +0000 Subject: Moved non-ACF-specific libraries to acf-lib package, moved cfe_unpack function to viewfunctions library. --- lib/format.lua | 512 --------------------------------------------------------- 1 file changed, 512 deletions(-) delete mode 100644 lib/format.lua (limited to 'lib/format.lua') diff --git a/lib/format.lua b/lib/format.lua deleted file mode 100644 index 0076fdf..0000000 --- a/lib/format.lua +++ /dev/null @@ -1,512 +0,0 @@ ---[[ - module for format changes in tables and strings - try to keep non input specific -]]-- - -module (..., package.seeall) - --- find all return characters and removes them, may get this from a browser --- that is why didn't do file specific - -function dostounix ( str ) - local data = string.gsub(str, "\r", "") - return data -end - --- Escape Lua magic characters -function escapemagiccharacters ( str ) - return (string.gsub(str or "", "[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%1")) -end - --- Escape shell special characters -function escapespecialcharacters ( str ) - return (string.gsub(str or "", "[~`#%$&%*%(%)\\|%[%]{};\'\"<>/]", "\\%1")) -end - --- search and remove all blank and commented lines from a string or table of lines --- returns a table to iterate over without the blank or commented lines - -function parse_lines ( input, comment ) - local lines = {} - comment = comment or "#" - - function parse(line) - if not string.match(line, "^%s*$") and not string.match(line, "^%s*"..comment) then - lines[#lines + 1] = line - end - end - - if type(input) == "string" then - for line in string.gmatch(input, "([^\n]*)\n?") do - parse(line) - end - elseif type(input) == "table" then - for i,line in ipairs(input) do - parse(line) - end - end - - return lines -end - --- search and remove all blank and commented lines from a string or table of lines --- parse the lines for words, looking for quotes and removing comments --- returns a table with an array of words for each line - -function parse_linesandwords ( input, comment ) - local lines = {} - local linenum = 0 - comment = comment or "#" - - function parse(line) - linenum = linenum + 1 - if not string.match(line, "^%s*$") and not string.match(line, "^%s*"..comment) then - local linetable = {linenum=linenum, line=line} - local offset = 1 - while string.find(line, "%S", offset) do - local word = string.match(line, "%S+", offset) - local endword - if string.find(word, "^"..comment) then - break - elseif string.find(word, "^\"") then - endword = select(2, string.find(line, "\"[^\"]*\"", offset)) - word = string.sub(line, string.find(line, "\"", offset), endword) - else - endword = select(2, string.find(line, "%S+", offset)) - end - table.insert(linetable, word) - offset = endword + 1 - end - lines[#lines + 1] = linetable - end - end - - if type(input) == "string" then - for line in string.gmatch(input, "([^\n]*)\n?") do - parse(line) - end - elseif type(input) == "table" then - for i,line in ipairs(input) do - parse(line) - end - end - - return lines -end - --- returns a table with label value pairs - -function parse_configfile( input, comment ) - local config = {} - local lines = parse_linesandwords(input, comment) - - for i,linetable in ipairs(lines) do - config[linetable[1]] = table.concat(linetable, " ", 2) or "" - end - return config -end - --- search and replace through a table --- string is easy string.gsub(string, find, replace) - -function search_replace (input, find, replace) - local lines = {} - for i,line in ipairs(input) do - lines[#lines + 1] = string.gsub(line, find, replace) - end - return lines -end - --- great for line searches through a file. /etc/conf.d/ ??? --- might be looking for more than one thing so will return a table --- will likely want to match whole line entries --- so we change find to include the rest of the line --- say want all the _OPTS from a file format.search_for_lines (fs.read_file("/etc/conf.d/cron"), "OPT") --- if want to avoid commented lines, call parse_lines first - -function search_for_lines (input, find) - local lines = {} - - function findfn(line) - if string.find(line, find) then - lines[#lines + 1] = line - end - end - - if type(input) == "string" then - for line in string.gmatch(input, "([^\n]*)\n?") do - findfn(line) - end - elseif type(input) == "table" then - for i,line in ipairs(input) do - findfn(line) - end - end - - return lines -end - ---string format function to capitalize the beginging of each word. -function cap_begin_word ( str ) - --first need to do the first word - local data = string.gsub(str, "^%l", string.upper) - --word is any space cause no <> regex - data = string.gsub(data, "%s%l", string.upper) - return data -end - ---for cut functionality do something like ---print(format.string_to_table("This is a test", " ")[2]) ---gives you the second field which is .... is - --- This code comes from http://lua-users.org/wiki/SplitJoin --- example: format.string_to_table( "Anna, Bob, Charlie,Dolores", ",%s*") -function string_to_table ( text, delimiter) - local list = {} - if text then - -- this would result in endless loops - if string.find("", delimiter) then - -- delimiter matches empty string! - for i=1,#text do - list[#list + 1] = string.sub(text, i, i) - end - else - local pos = 1 - while 1 do - local first, last = string.find(text, delimiter, pos) - if first then -- found? - table.insert(list, string.sub(text, pos, first-1)) - pos = last+1 - else - table.insert(list, string.sub(text, pos)) - break - end - end - end - end - return list -end - - --- Takes a str and expands any ${...} constructs with the Lua variable --- ex: a="foo"; print(expand_bash_syntax_vars("a=${a}) - > "a=foo" -expand_bash_syntax_vars = function (str) - local deref = function (f) - local v = getfenv(3) -- get the upstream global env - for w in string.gfind(f, "[%w_]+") do - if v then v = v[w] end - end - return v - end - - for w in string.gmatch (str, "${[^}]*}" ) do - local rvar = string.sub(w,3,-2) - local rval = ( deref(rvar) or "nil" ) - str = string.gsub (str, w, escapespecialcharacters(rval)) - end - - return (str) -end - --- Removes the linenum line from str and replaces it with line. --- Do nothing if doesn't exist --- Set line to nil to remove the line -function replace_line(str, linenum, line) - -- Split the str to remove the line - local startchar, endchar = string.match(str, "^" .. string.rep("[^\n]*\n", linenum-1) .. "()[^\n]*\n?()") - if startchar and endchar then - local lines = {} - lines[1] = string.sub(str, 1, startchar-1) - lines[2] = string.sub(str, endchar, -1) - if line then - table.insert(lines, 2, line .. "\n") - end - str = table.concat(lines) - end - return str -end - --- Inserts the line into the str after the linenum (or at the end) -function insert_line(str, linenum, line) - -- Split the str to remove the line - local startchar = string.match(str, "^" .. string.rep("[^\n]*\n", linenum) .. "()") - local lines = {} - if startchar then - lines[1] = string.sub(str, 1, startchar-1) - lines[2] = string.sub(str, startchar, -1) - else - lines[1] = str - end - if line then - table.insert(lines, 2, line .. "\n") - end - str = table.concat(lines) - return str -end - -function get_line(str, linenum) - -- Split the str to remove the line - local startchar, endchar = string.match(str, "^" .. string.rep("[^\n]*\n", linenum-1) .. "()[^\n]*()") - local line - if startchar and endchar then - line = string.sub(str, startchar, endchar-1) - end - return line -end - --- Search the option string for separate options (-x or --xyz) and put them in a table -function opts_to_table ( optstring, filter ) - local optsparams - if optstring then - 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, "%S*$") - end - end - end - return optsparams -end - --- Go through an options table and create the option string -function table_to_opts ( optsparams ) - local optstring = {} - for opt,val in pairs(optsparams) do - optstring[#optstring + 1] = opt - if val ~= "" then - optstring[#optstring + 1] = val - end - end - return table.concat(optstring, " ") -end - --- The following functions deal with ini files. ini files contain comments, sections, names and values --- commented lines begin with '#' or ';', in-line comments begin with '#' and run to the end of the line --- sections are defined by "[section]" on a line. Anything before the first section definition is in section "" --- name value pairs are defined by "name = value". Names and values may contain spaces but not '#' --- lines ending with '\' are continued on the next line - - --- Set a name=value pair in a string --- If search_section is undefined or "", goes in the default section --- If value is defined we put "search_name=value" into search_section --- If value is undefined, we clear search_name out of 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 string --- If the search_name is not found, we'll add it at the end of the section -function update_ini_file (file, search_section, search_name, value) - if not file or not search_name or search_name == "" then - return file, false - end - - search_section = search_section or "" - local new_conf_file = {} - local section = "" - local done = false - local skip_lines = {} - for l in string.gmatch(file, "([^\n]*)\n?") do - if done == false then - if string.find ( l, "\\%s*$" ) then - skip_lines[#skip_lines+1] = string.match(l, "^(.*)\\%s*$") - l = nil - else - if #skip_lines then - skip_lines[#skip_lines+1] = l - l = table.concat(skip_lines, " ") - end - -- check if comment line - if not string.find ( l, "^%s*[#;]" ) then - -- 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] = search_name.."="..value - 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, keep any comment - local comment = string.match(l, " #.*$") or "" - l = search_name.."="..value..comment - skip_lines = {} -- replacing line - done = true - end - end - end - if #skip_lines > 0 then - for i,line in ipairs(skip_lines) do - new_conf_file[#new_conf_file + 1] = line - end - skip_lines = {} - l = nil - end - end - end - new_conf_file[#new_conf_file + 1] = l - end - - 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] = search_name.."="..value - end - - file = table.concat(new_conf_file, '\n') - - return file, true -end - --- Parse string 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) -function parse_ini_file (file, search_section, search_name) - if not file or file == "" then - return nil - end - local opts = nil - local section = "" - local skip_lines = {} - for l in string.gmatch(file, "([^\n]*)\n?") do - if string.find ( l, "\\%s*$" ) then - skip_lines[#skip_lines+1] = string.match(l, "^(.*)\\%s*$") - else - if #skip_lines then - skip_lines[#skip_lines+1] = l - l = table.concat(skip_lines, " ") - skip_lines = {} - end - -- check if comment line - if not string.find ( l, "^%s*[#;]" ) then - -- find section name - local a = string.match ( l, "^%s*%[%s*(%S+)%s*%]" ) - if a then - if (search_section == section) then break end - section = a - elseif not (search_section) or (search_section == section) then - -- find name - a = string.match ( l, "^%s*([^=]*%S)%s*=" ) - if a and (not (search_name) or (search_name == a)) then - -- Figure out the value - local b = string.match ( l, '=%s*(.*)$' ) or "" - -- remove comments from end of line - if string.find ( b, '#' ) then - b = string.match ( b, '^(.*)#.*$' ) or "" - end - -- remove spaces from front and back - b = string.gsub ( b, '%s+$', '' ) - if not (opts) then opts = {} end - if not (opts[section]) then opts[section] = {} end - opts[section][a] = b - end - end - end - end - end - - 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 - return opts -end - -function get_ini_section (file, search_section) - if not file then - return nil - end - search_section = search_section or "" - local sectionlines = {} - local section = "" - for l in string.gmatch(file, "([^\n]*)\n?") do - -- find section name - local a = string.match ( l, "^%s*%[%s*(%S+)%s*%]" ) - if a then - if (search_section == section) then break end - section = a - elseif (search_section == section) then - sectionlines[#sectionlines + 1] = l - end - end - - return table.concat(sectionlines, "\n") -end - -function set_ini_section (file, search_section, section_content) - if not file then - return file, false - end - search_section = search_section or "" - section_content = section_content or "" - local new_conf_file = {} - local done = false - local section = "" - if search_section == "" then new_conf_file[1] = section_content end - for l in string.gmatch(file, "([^\n]*)\n?") do - -- find section name - if not done then - local a = string.match ( l, "^%s*%[%s*(%S+)%s*%]" ) - if a then - if (search_section == section) then - done = true - else - section = a - if (search_section == section) then - l = l .. "\n" .. section_content - end - end - elseif (search_section == section) then - l = nil - end - end - new_conf_file[#new_conf_file + 1] = l - end - - if not done then - -- we didn't find the section, add it now - if section ~= search_section then - new_conf_file[#new_conf_file + 1] = '[' .. search_section .. ']' - new_conf_file[#new_conf_file + 1] = section_content - end - end - - file = table.concat(new_conf_file, '\n') - - return file, true -end - --- Find the value of an entry allowing for parent section and $variables --- the file parameter can be a string or structure returned by parse_ini_file --- beginning and ending quotes are removed --- returns value or "" if not found -function get_ini_entry (file, section, value) - local opts = file - if not file or not value then - return nil - elseif type(file) == "string" then - opts = parse_ini_file(file) - end - section = section or "" - local result = opts[section][value] - if not result then - section = "" - result = opts[section][value] or "" - end - while string.find(result, "%$[%w_]+") do - local sub = string.match(result, "%$[%w_]+") - result = string.gsub(result, escapemagiccharacters(sub), get_ini_entry(opts, section, sub)) - end - if string.find(result, '^"') and string.find(result, '"$') then - result = string.sub(result, 2, -2) - end - return result -end -- cgit v1.2.3