diff options
| author | Hans Hagen <pragma@wxs.nl> | 2010-01-14 18:25:00 +0100 | 
|---|---|---|
| committer | Hans Hagen <pragma@wxs.nl> | 2010-01-14 18:25:00 +0100 | 
| commit | 45d11a2f318b118a2592b9db7eb530a4cf613a00 (patch) | |
| tree | 060a66d60c1e5e7c3326e5776476ee90e2cb1e43 /scripts | |
| parent | 3dbcef73aec79246dfc4238eb7af28d3fa54e1f3 (diff) | |
| download | context-45d11a2f318b118a2592b9db7eb530a4cf613a00.tar.gz | |
beta 2010.01.14 18:25
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/context/lua/luatools.lua | 179 | ||||
| -rw-r--r-- | scripts/context/lua/mtx-watch.lua | 18 | ||||
| -rw-r--r-- | scripts/context/lua/mtxrun.lua | 445 | ||||
| -rw-r--r-- | scripts/context/stubs/mswin/luatools.lua | 179 | ||||
| -rw-r--r-- | scripts/context/stubs/mswin/mtxrun.lua | 445 | ||||
| -rwxr-xr-x | scripts/context/stubs/unix/luatools | 179 | ||||
| -rwxr-xr-x | scripts/context/stubs/unix/mtxrun | 445 | 
7 files changed, 1196 insertions, 694 deletions
diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua index 9f34bea72..5fcc30d3c 100644 --- a/scripts/context/lua/luatools.lua +++ b/scripts/context/lua/luatools.lua @@ -530,7 +530,7 @@ end  function table.keys(t)      local k = { } -    for key,_ in next, t do +    for key, _ in next, t do          k[#k+1] = key      end      return k @@ -1755,6 +1755,12 @@ end  os.type = os.type or (io.pathseparator == ";"       and "windows") or "unix"  os.name = os.name or (os.type          == "windows" and "mswin"  ) or "linux" +if os.type == "windows" then +    os.libsuffix, os.binsuffix = 'dll', 'exe' +else +    os.libsuffix, os.binsuffix = 'so', '' +end +  function os.launch(str)      if os.type == "windows" then          os.execute("start " .. str) -- os.spawn ? @@ -1763,10 +1769,6 @@ function os.launch(str)      end  end -if not os.setenv then -    function os.setenv() return false end -end -  if not os.times then      -- utime  = user time      -- stime  = system time @@ -1798,63 +1800,153 @@ end  -- no need for function anymore as we have more clever code and helpers now -os.platform  = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then -    if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then -        os.platform = "mswin-64" -    else -        os.platform = "mswin" +osmt.__index = function(t,k) +    return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + +    -- we still store them but they won't be seen in +    -- child processes although we might pass them some day +    -- using command concatination + +    local env, getenv = { }, os.getenv + +    function os.setenv(k,v) +        env[k] = v      end -    os.libsuffix = 'dll' -    os.binsuffix = 'exe' -else -    local architecture = os.getenv("HOSTTYPE") or "" -    if architecture == "" then -        architecture = os.resultof("uname -m") or "" + +    function os.getenv(k) +        return env[k] or getenv(k) +    end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() +    local architecture = os.resultof("uname -m") or "" +    if architecture ~= "" then +        return architecture      end -    if architecture == "" then -        local architecture = os.resultof("echo $HOSTTYPE") +    architecture = os.getenv("HOSTTYPE") or "" +    if architecture ~= "" then +        return architecture      end -    if name == "linux" then +    return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + +    os.platform = platform + +elseif os.type == "windows" then + +    -- we could set the variable directly, no function needed here + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" +        if find(architecture,"AMD64") then +            platform = "mswin-64" +        else +            platform = "mswin" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "linux" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""          if find(architecture,"x86_64") then -            os.platform = "linux-64" +            platform = "linux-64"          elseif find(architecture,"ppc") then -            os.platform = "linux-ppc" +            platform = "linux-ppc"          else -            os.platform = "linux" +            platform = "linux" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "macosx" then -- a rather inconsistent mess + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or "" +        if architecture == "" then +            architecture = os.getenv("HOSTTYPE") or "" +        end +        if architecture == "" then +            architecture = os.resultof("echo $HOSTTYPE") or ""          end -    elseif name == "macosx" then          if find(architecture,"i386") then -            os.platform = "osx-intel" +            platform = "osx-intel"          elseif find(architecture,"x86_64") then -            os.platform = "osx-64" +            platform = "osx-64"          else -            os.platform = "osx-ppc" +            platform = "osx-ppc"          end -    elseif name == "sunos" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "sunos" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"sparc") then -            os.platform = "solaris-sparc" +            platform = "solaris-sparc"          else -- if architecture == 'i86pc' -            os.platform = "solaris-intel" +            platform = "solaris-intel"          end -    elseif name == "freebsd" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "freebsd" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"amd64") then -            os.platform = "freebsd-amd64" +            platform = "freebsd-amd64"          else -            os.platform = "freebsd" +            platform = "freebsd"          end -    else -        os.platform = 'linux' +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +else + +    -- platform = "linux" +    -- os.setenv("MTX_PLATFORM",platform) +    -- os.platform = platform + +    function os.resolvers.platform(t,k) +        local platform = "linux" +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end +  end  -- beware, we set the randomseed ---  -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the  -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1863,7 +1955,6 @@ end  --  -- as we don't call this function too often there is not so much risk on repetition -  local t = { 8, 9, "a", "b" }  function os.uuid() @@ -2266,7 +2357,9 @@ local hexdigit  = lpeg.R("09","AF","af")  local plus      = lpeg.P("+")  local escaped   = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) -local scheme    =                 lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("") +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme    =                 lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon + lpeg.Cc("")  local authority = slash * slash * lpeg.Cs((escaped+(1-      slash-qmark-hash))^0)         + lpeg.Cc("")  local path      = slash *         lpeg.Cs((escaped+(1-            qmark-hash))^0)         + lpeg.Cc("")  local query     = qmark         * lpeg.Cs((escaped+(1-                  hash))^0)         + lpeg.Cc("") @@ -3181,6 +3274,8 @@ if not modules then modules = { } end modules ['l-aux'] = {      license   = "see context related readme files"  } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end +  aux = aux or { }  local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -3273,6 +3368,8 @@ local pattern   = lpeg.Ct(value*(separator*value)^0)  aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache +  function aux.settings_to_array(str)      if not str or str == "" then          return { } diff --git a/scripts/context/lua/mtx-watch.lua b/scripts/context/lua/mtx-watch.lua index d897d6beb..fa4cd0eab 100644 --- a/scripts/context/lua/mtx-watch.lua +++ b/scripts/context/lua/mtx-watch.lua @@ -13,16 +13,13 @@ local format, concat, difftime, time = string.format, table.concat, os.difftime,  local pairs, ipairs, next, type = pairs, ipairs, next, type  function scripts.watch.save_exa_modes(joblog,ctmname) -    if joblog then +    local values = joblog and joblog.values +    if values then          local t= { }          t[#t+1] = "<?xml version='1.0' standalone='yes'?>\n"          t[#t+1] = "<exa:variables xmlns:exa='htpp://www.pragma-ade.com/schemas/exa-variables.rng'>" -        if joblog.values then -            for k, v in pairs(joblog.values) do -                t[#t+1] = format("\t<exa:variable label='%s'>%s</exa:variable>", k, tostring(v)) -            end -        else -            t[#t+1] = "<!-- no modes -->" +        for k, v in pairs(joblog.values) do +            t[#t+1] = format("\t<exa:variable label='%s'>%s</exa:variable>", k, tostring(v))          end          t[#t+1] = "</exa:variables>"          io.savedata(ctmname,concat(t,"\n")) @@ -147,11 +144,12 @@ function scripts.watch.watch()                                  joblog.status = "no command"                              end                              -- pcall, when error sleep + again +                            -- todo: just one log file and append                              io.savedata(name, table.serialize(joblog,true)) -                            if logpath ~= "" then -                                local name = os.uuid() .. ".lua" +                            if logpath and logpath ~= "" then +                                local name = file.join(logpath,os.uuid() .. ".lua")                                  io.savedata(name, table.serialize(joblog,true)) -                                logs.report("watch", "saving joblog ".. name) +                                logs.report("watch", "saving joblog in " .. name)                              end                          end                      end diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 051cd0fa8..0b2a9cd02 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -539,7 +539,7 @@ end  function table.keys(t)      local k = { } -    for key,_ in next, t do +    for key, _ in next, t do          k[#k+1] = key      end      return k @@ -1764,6 +1764,12 @@ end  os.type = os.type or (io.pathseparator == ";"       and "windows") or "unix"  os.name = os.name or (os.type          == "windows" and "mswin"  ) or "linux" +if os.type == "windows" then +    os.libsuffix, os.binsuffix = 'dll', 'exe' +else +    os.libsuffix, os.binsuffix = 'so', '' +end +  function os.launch(str)      if os.type == "windows" then          os.execute("start " .. str) -- os.spawn ? @@ -1772,10 +1778,6 @@ function os.launch(str)      end  end -if not os.setenv then -    function os.setenv() return false end -end -  if not os.times then      -- utime  = user time      -- stime  = system time @@ -1807,63 +1809,153 @@ end  -- no need for function anymore as we have more clever code and helpers now -os.platform  = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then -    if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then -        os.platform = "mswin-64" -    else -        os.platform = "mswin" +osmt.__index = function(t,k) +    return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + +    -- we still store them but they won't be seen in +    -- child processes although we might pass them some day +    -- using command concatination + +    local env, getenv = { }, os.getenv + +    function os.setenv(k,v) +        env[k] = v      end -    os.libsuffix = 'dll' -    os.binsuffix = 'exe' -else -    local architecture = os.getenv("HOSTTYPE") or "" -    if architecture == "" then -        architecture = os.resultof("uname -m") or "" + +    function os.getenv(k) +        return env[k] or getenv(k) +    end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() +    local architecture = os.resultof("uname -m") or "" +    if architecture ~= "" then +        return architecture +    end +    architecture = os.getenv("HOSTTYPE") or "" +    if architecture ~= "" then +        return architecture      end -    if architecture == "" then -        local architecture = os.resultof("echo $HOSTTYPE") +    return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + +    os.platform = platform + +elseif os.type == "windows" then + +    -- we could set the variable directly, no function needed here + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" +        if find(architecture,"AMD64") then +            platform = "mswin-64" +        else +            platform = "mswin" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end -    if name == "linux" then + +elseif name == "linux" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""          if find(architecture,"x86_64") then -            os.platform = "linux-64" +            platform = "linux-64"          elseif find(architecture,"ppc") then -            os.platform = "linux-ppc" +            platform = "linux-ppc"          else -            os.platform = "linux" +            platform = "linux" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "macosx" then -- a rather inconsistent mess + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or "" +        if architecture == "" then +            architecture = os.getenv("HOSTTYPE") or "" +        end +        if architecture == "" then +            architecture = os.resultof("echo $HOSTTYPE") or ""          end -    elseif name == "macosx" then          if find(architecture,"i386") then -            os.platform = "osx-intel" +            platform = "osx-intel"          elseif find(architecture,"x86_64") then -            os.platform = "osx-64" +            platform = "osx-64"          else -            os.platform = "osx-ppc" +            platform = "osx-ppc"          end -    elseif name == "sunos" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "sunos" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"sparc") then -            os.platform = "solaris-sparc" +            platform = "solaris-sparc"          else -- if architecture == 'i86pc' -            os.platform = "solaris-intel" +            platform = "solaris-intel"          end -    elseif name == "freebsd" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "freebsd" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"amd64") then -            os.platform = "freebsd-amd64" +            platform = "freebsd-amd64"          else -            os.platform = "freebsd" +            platform = "freebsd"          end -    else -        os.platform = 'linux' +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end + +else + +    -- platform = "linux" +    -- os.setenv("MTX_PLATFORM",platform) +    -- os.platform = platform + +    function os.resolvers.platform(t,k) +        local platform = "linux" +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end +  end  -- beware, we set the randomseed ---  -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the  -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1872,7 +1964,6 @@ end  --  -- as we don't call this function too often there is not so much risk on repetition -  local t = { 8, 9, "a", "b" }  function os.uuid() @@ -2879,6 +2970,8 @@ if not modules then modules = { } end modules ['l-aux'] = {      license   = "see context related readme files"  } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end +  aux = aux or { }  local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -2971,6 +3064,8 @@ local pattern   = lpeg.Ct(value*(separator*value)^0)  aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache +  function aux.settings_to_array(str)      if not str or str == "" then          return { } @@ -3991,12 +4086,14 @@ local function xmlconvert(data, settings)          else              errorstr = "invalid xml file - parsed text"          end -    else +    elseif type(data) == "string" then          if lpegmatch(grammar_unparsed_text,data) then              errorstr = ""          else              errorstr = "invalid xml file - unparsed text"          end +    else +        errorstr = "invalid xml file - no text at all"      end      if errorstr and errorstr ~= "" then          result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } } } @@ -4033,6 +4130,19 @@ end  xml.convert = xmlconvert +function xml.inheritedconvert(data,xmldata) +    local settings = xmldata.settings +    settings.parent_root = xmldata -- to be tested + -- settings.no_root = true +    local xc = xmlconvert(data,settings) + -- xc.settings = nil + -- xc.entities = nil + -- xc.special = nil + -- xc.ri = nil + -- print(xc.tg) +    return xc +end +  --[[ldx--  <p>Packaging data in an xml like table is done with the following  function. Maybe it will go away (when not used).</p> @@ -5840,25 +5950,15 @@ if not modules then modules = { } end modules ['lxml-aux'] = {  local trace_manipulations = false  trackers.register("lxml.manipulations", function(v) trace_manipulations = v end) -local xmlparseapply, xmlconvert, xmlcopy = xml.parse_apply, xml.convert, xml.copy +local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name +local xmlinheritedconvert = xml.inheritedconvert  local type = type  local insert, remove = table.insert, table.remove  local gmatch, gsub = string.gmatch, string.gsub - -function xml.inheritedconvert(data,xmldata) -    local settings = xmldata.settings -    settings.parent_root = xmldata -- to be tested ---~ settings.no_root = true -    local xc = xmlconvert(data,settings) ---~ xc.settings = nil ---~ xc.entities = nil ---~ xc.special = nil ---~ xc.ri = nil ---~ print(xc.tg) ---    for k,v in pairs(xc) do print(k,tostring(v)) end -    return xc +local function report(what,pattern,c,e) +    logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)  end  local function withelements(e,handle,depth) @@ -5914,7 +6014,7 @@ end  xml.elements_only = xml.collected -function xml.each_element(root, pattern, handle, reverse) +function xml.each_element(root,pattern,handle,reverse)      local collected = xmlparseapply({ root },pattern)      if collected then          if reverse then @@ -5932,7 +6032,7 @@ end  xml.process_elements = xml.each_element -function xml.process_attributes(root, pattern, handle) +function xml.process_attributes(root,pattern,handle)      local collected = xmlparseapply({ root },pattern)      if collected and handle then          for c=1,#collected do @@ -5983,7 +6083,7 @@ function xml.collect_tags(root, pattern, nonamespace)  end  --[[ldx-- -<p>We've now arrives at the functions that manipulate the tree.</p> +<p>We've now arrived at the functions that manipulate the tree.</p>  --ldx]]--  local no_root = { no_root = true } @@ -5997,120 +6097,44 @@ function xml.redo_ni(d)      end  end -function xml.inject_element(root, pattern, element, prepend) -    if root and element then -        if type(element) == "string" then ---~             element = xmlconvert(element,no_root) -            element = xml.inheritedconvert(element,root) -        end -        if element then -            if element.ri then -                element = element.dt[element.ri].dt -            else -                element = element.dt -            end -            -- we need to re-index -            local collected = xmlparseapply({ root },pattern) -            if collected then -                for c=1,#collected do -                    local e = collected[c] -                    local r, d, k = e.__p__, r.dt, e.ni -                    local edt -                    if r.ri then -                        edt = r.dt[r.ri].dt -                    else -                        edt = d and d[k] and d[k].dt -                    end -                    if edt then -                        local be, af -                        if prepend then -                            be, af = xmlcopy(element), edt -be.__p__ = e - -                        else -                            be, af = edt, xmlcopy(element) -af.__p__ = e -                        end -                        for i=1,#af do -                            be[#be+1] = af[i] -                        end -                        if r.ri then -                            r.dt[r.ri].dt = be -                        else -                            d[k].dt = be -                        end -                    else -                        -- r.dt = element.dt -- todo -                    end -xml.redo_ni(d) -                end -            end -        end +local function xmltoelement(whatever,root) +    if not whatever then +        return nil +    end +    local element +    if type(whatever) == "string" then +        element = xmlinheritedconvert(whatever,root) +    else +        element = whatever -- we assume a table      end +    if element.error then +        return whatever -- string +    end +    if element then +    --~ if element.ri then +    --~     element = element.dt[element.ri].dt +    --~ else +    --~     element = element.dt +    --~ end +    end +    return element  end --- todo: copy ! +xml.toelement = xmltoelement -function xml.insert_element(root, pattern, element, before) -- todo: element als functie -    if root and element then -        if pattern == "/" then -            xml.inject_element(root, pattern, element, before) -        else -            local matches, collect = { }, nil -            if type(element) == "string" then ---~                 element = xmlconvert(element,no_root) -                element = xml.inheritedconvert(element,root) -            end -            if element and element.ri then -                element = element.dt[element.ri] -            end -            if element then -                local collected = xmlparseapply({ root },pattern) -                if collected then -                    for c=1,#collected do -                        local e = collected[c] -                        local r = e.__p__ -                        local d = r.dt -                        local k = e.ni -                        if not before then -                            k = k + 1 -                        end -                        local ce = xmlcopy(element) -ce.__p__ = r -                        if element.tg then -                            insert(d,k,ce) -- untested -                        else -                            -- maybe bugged -                            local edt = ce.dt -                            if edt then -                                for i=1,#edt do -local edti = edt[i] -                                    insert(d,k,edti) -if type(edti) == "table" then -    edti.__p__ = r -end -                                    k = k + 1 -                                end -                            end -                        end -xml.redo_ni(d) -                    end -                end -            end +local function copiedelement(element,newparent) +    if type(element) == "string" then +        return element +    else +        element = xmlcopy(element).dt +        if newparent and type(element) == "table" then +            element.__p__ = newparent          end +        return element      end  end -xml.insert_element_after  =                 xml.insert_element -xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end -xml.inject_element_after  =                 xml.inject_element -xml.inject_element_before = function(r,p,e) xml.inject_element(r,p,e,true) end - -local function report(what,pattern,c,e) -    logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xml.name(e),xml.name(e.__p__),c,e.ni,pattern) -end - -function xml.delete_element(root, pattern) +function xml.delete_element(root,pattern)      local collected = xmlparseapply({ root },pattern)      if collected then          for c=1,#collected do @@ -6118,43 +6142,90 @@ function xml.delete_element(root, pattern)              local p = e.__p__              if p then                  if trace_manipulations then -                    report('deleting',pattern,c,tostring(e)) -- fails +                    report('deleting',pattern,c,e)                  end                  local d = p.dt                  remove(d,e.ni) -xml.redo_ni(d) +                xml.redo_ni(d) -- can be made faster and inlined              end          end      end  end -function xml.replace_element(root, pattern, element) -    if type(element) == "string" then ---~         element = xmlconvert(element,true) -            element = xml.inheritedconvert(element,root) -    end -    if element and element.ri then -        element = element.dt[element.ri] +function xml.replace_element(root,pattern,whatever) +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local p = e.__p__ +            if p then +                if trace_manipulations then +                    report('replacing',pattern,c,e) +                end +                local d = p.dt +                d[e.ni] = copiedelement(element,p) +                xml.redo_ni(d) -- probably not needed +            end +        end      end -    if element then -        local collected = xmlparseapply({ root },pattern) -        if collected then -            for c=1,#collected do -                local e = collected[c] -                local p = e.__p__ -                if p then -                    if trace_manipulations then -                        report('replacing',pattern,c,e) -                    end -                    local d = p.dt -                    d[e.ni] = element.dt -- maybe not clever enough ---~ xml.redo_ni(d) +end + +local function inject_element(root,pattern,whatever,prepend) +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local r = e.__p__ +            local d, k, rri = r.dt, e.ni, r.ri +            local edt = (rri and d[rri].dt) or (d and d[k] and d[k].dt) +            if edt then +                local be, af +                local cp = copiedelement(element,e) +                if prepend then +                    be, af = cp, edt +                else +                    be, af = edt, cp                  end +                for i=1,#af do +                    be[#be+1] = af[i] +                end +                if rri then +                    r.dt[rri].dt = be +                else +                    d[k].dt = be +                end +                xml.redo_ni(d) +            end +        end +    end +end + +local function insert_element(root,pattern,whatever,before) -- todo: element als functie +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local r = e.__p__ +            local d, k = r.dt, e.ni +            if not before then +                k = k + 1              end +            insert(d,k,copiedelement(element,r)) +            xml.redo_ni(d)          end      end  end +xml.insert_element        =                 insert_element +xml.insert_element_after  =                 insert_element +xml.insert_element_before = function(r,p,e) insert_element(r,p,e,true) end +xml.inject_element        =                 inject_element +xml.inject_element_after  =                 inject_element +xml.inject_element_before = function(r,p,e) inject_element(r,p,e,true) end +  local function include(xmldata,pattern,attribute,recursive,loaddata)      -- parse="text" (default: xml), encoding="" (todo)      -- attribute = attribute or 'href' @@ -6187,7 +6258,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)  --~                 local settings = xmldata.settings  --~                 settings.parent_root = xmldata -- to be tested  --~                 local xi = xmlconvert(data,settings) -                local xi = xml.inheritedconvert(data,xmldata) +                local xi = xmlinheritedconvert(data,xmldata)                  if not xi then                      epdt[ek.ni] = "" -- xml.empty(d,k)                  else diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua index 9f34bea72..5fcc30d3c 100644 --- a/scripts/context/stubs/mswin/luatools.lua +++ b/scripts/context/stubs/mswin/luatools.lua @@ -530,7 +530,7 @@ end  function table.keys(t)      local k = { } -    for key,_ in next, t do +    for key, _ in next, t do          k[#k+1] = key      end      return k @@ -1755,6 +1755,12 @@ end  os.type = os.type or (io.pathseparator == ";"       and "windows") or "unix"  os.name = os.name or (os.type          == "windows" and "mswin"  ) or "linux" +if os.type == "windows" then +    os.libsuffix, os.binsuffix = 'dll', 'exe' +else +    os.libsuffix, os.binsuffix = 'so', '' +end +  function os.launch(str)      if os.type == "windows" then          os.execute("start " .. str) -- os.spawn ? @@ -1763,10 +1769,6 @@ function os.launch(str)      end  end -if not os.setenv then -    function os.setenv() return false end -end -  if not os.times then      -- utime  = user time      -- stime  = system time @@ -1798,63 +1800,153 @@ end  -- no need for function anymore as we have more clever code and helpers now -os.platform  = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then -    if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then -        os.platform = "mswin-64" -    else -        os.platform = "mswin" +osmt.__index = function(t,k) +    return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + +    -- we still store them but they won't be seen in +    -- child processes although we might pass them some day +    -- using command concatination + +    local env, getenv = { }, os.getenv + +    function os.setenv(k,v) +        env[k] = v      end -    os.libsuffix = 'dll' -    os.binsuffix = 'exe' -else -    local architecture = os.getenv("HOSTTYPE") or "" -    if architecture == "" then -        architecture = os.resultof("uname -m") or "" + +    function os.getenv(k) +        return env[k] or getenv(k) +    end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() +    local architecture = os.resultof("uname -m") or "" +    if architecture ~= "" then +        return architecture      end -    if architecture == "" then -        local architecture = os.resultof("echo $HOSTTYPE") +    architecture = os.getenv("HOSTTYPE") or "" +    if architecture ~= "" then +        return architecture      end -    if name == "linux" then +    return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + +    os.platform = platform + +elseif os.type == "windows" then + +    -- we could set the variable directly, no function needed here + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" +        if find(architecture,"AMD64") then +            platform = "mswin-64" +        else +            platform = "mswin" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "linux" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""          if find(architecture,"x86_64") then -            os.platform = "linux-64" +            platform = "linux-64"          elseif find(architecture,"ppc") then -            os.platform = "linux-ppc" +            platform = "linux-ppc"          else -            os.platform = "linux" +            platform = "linux" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "macosx" then -- a rather inconsistent mess + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or "" +        if architecture == "" then +            architecture = os.getenv("HOSTTYPE") or "" +        end +        if architecture == "" then +            architecture = os.resultof("echo $HOSTTYPE") or ""          end -    elseif name == "macosx" then          if find(architecture,"i386") then -            os.platform = "osx-intel" +            platform = "osx-intel"          elseif find(architecture,"x86_64") then -            os.platform = "osx-64" +            platform = "osx-64"          else -            os.platform = "osx-ppc" +            platform = "osx-ppc"          end -    elseif name == "sunos" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "sunos" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"sparc") then -            os.platform = "solaris-sparc" +            platform = "solaris-sparc"          else -- if architecture == 'i86pc' -            os.platform = "solaris-intel" +            platform = "solaris-intel"          end -    elseif name == "freebsd" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "freebsd" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"amd64") then -            os.platform = "freebsd-amd64" +            platform = "freebsd-amd64"          else -            os.platform = "freebsd" +            platform = "freebsd"          end -    else -        os.platform = 'linux' +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +else + +    -- platform = "linux" +    -- os.setenv("MTX_PLATFORM",platform) +    -- os.platform = platform + +    function os.resolvers.platform(t,k) +        local platform = "linux" +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end +  end  -- beware, we set the randomseed ---  -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the  -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1863,7 +1955,6 @@ end  --  -- as we don't call this function too often there is not so much risk on repetition -  local t = { 8, 9, "a", "b" }  function os.uuid() @@ -2266,7 +2357,9 @@ local hexdigit  = lpeg.R("09","AF","af")  local plus      = lpeg.P("+")  local escaped   = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) -local scheme    =                 lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("") +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme    =                 lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon + lpeg.Cc("")  local authority = slash * slash * lpeg.Cs((escaped+(1-      slash-qmark-hash))^0)         + lpeg.Cc("")  local path      = slash *         lpeg.Cs((escaped+(1-            qmark-hash))^0)         + lpeg.Cc("")  local query     = qmark         * lpeg.Cs((escaped+(1-                  hash))^0)         + lpeg.Cc("") @@ -3181,6 +3274,8 @@ if not modules then modules = { } end modules ['l-aux'] = {      license   = "see context related readme files"  } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end +  aux = aux or { }  local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -3273,6 +3368,8 @@ local pattern   = lpeg.Ct(value*(separator*value)^0)  aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache +  function aux.settings_to_array(str)      if not str or str == "" then          return { } diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 051cd0fa8..0b2a9cd02 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -539,7 +539,7 @@ end  function table.keys(t)      local k = { } -    for key,_ in next, t do +    for key, _ in next, t do          k[#k+1] = key      end      return k @@ -1764,6 +1764,12 @@ end  os.type = os.type or (io.pathseparator == ";"       and "windows") or "unix"  os.name = os.name or (os.type          == "windows" and "mswin"  ) or "linux" +if os.type == "windows" then +    os.libsuffix, os.binsuffix = 'dll', 'exe' +else +    os.libsuffix, os.binsuffix = 'so', '' +end +  function os.launch(str)      if os.type == "windows" then          os.execute("start " .. str) -- os.spawn ? @@ -1772,10 +1778,6 @@ function os.launch(str)      end  end -if not os.setenv then -    function os.setenv() return false end -end -  if not os.times then      -- utime  = user time      -- stime  = system time @@ -1807,63 +1809,153 @@ end  -- no need for function anymore as we have more clever code and helpers now -os.platform  = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then -    if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then -        os.platform = "mswin-64" -    else -        os.platform = "mswin" +osmt.__index = function(t,k) +    return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + +    -- we still store them but they won't be seen in +    -- child processes although we might pass them some day +    -- using command concatination + +    local env, getenv = { }, os.getenv + +    function os.setenv(k,v) +        env[k] = v      end -    os.libsuffix = 'dll' -    os.binsuffix = 'exe' -else -    local architecture = os.getenv("HOSTTYPE") or "" -    if architecture == "" then -        architecture = os.resultof("uname -m") or "" + +    function os.getenv(k) +        return env[k] or getenv(k) +    end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() +    local architecture = os.resultof("uname -m") or "" +    if architecture ~= "" then +        return architecture +    end +    architecture = os.getenv("HOSTTYPE") or "" +    if architecture ~= "" then +        return architecture      end -    if architecture == "" then -        local architecture = os.resultof("echo $HOSTTYPE") +    return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + +    os.platform = platform + +elseif os.type == "windows" then + +    -- we could set the variable directly, no function needed here + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" +        if find(architecture,"AMD64") then +            platform = "mswin-64" +        else +            platform = "mswin" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end -    if name == "linux" then + +elseif name == "linux" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""          if find(architecture,"x86_64") then -            os.platform = "linux-64" +            platform = "linux-64"          elseif find(architecture,"ppc") then -            os.platform = "linux-ppc" +            platform = "linux-ppc"          else -            os.platform = "linux" +            platform = "linux" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "macosx" then -- a rather inconsistent mess + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or "" +        if architecture == "" then +            architecture = os.getenv("HOSTTYPE") or "" +        end +        if architecture == "" then +            architecture = os.resultof("echo $HOSTTYPE") or ""          end -    elseif name == "macosx" then          if find(architecture,"i386") then -            os.platform = "osx-intel" +            platform = "osx-intel"          elseif find(architecture,"x86_64") then -            os.platform = "osx-64" +            platform = "osx-64"          else -            os.platform = "osx-ppc" +            platform = "osx-ppc"          end -    elseif name == "sunos" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "sunos" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"sparc") then -            os.platform = "solaris-sparc" +            platform = "solaris-sparc"          else -- if architecture == 'i86pc' -            os.platform = "solaris-intel" +            platform = "solaris-intel"          end -    elseif name == "freebsd" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "freebsd" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"amd64") then -            os.platform = "freebsd-amd64" +            platform = "freebsd-amd64"          else -            os.platform = "freebsd" +            platform = "freebsd"          end -    else -        os.platform = 'linux' +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end + +else + +    -- platform = "linux" +    -- os.setenv("MTX_PLATFORM",platform) +    -- os.platform = platform + +    function os.resolvers.platform(t,k) +        local platform = "linux" +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end +  end  -- beware, we set the randomseed ---  -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the  -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1872,7 +1964,6 @@ end  --  -- as we don't call this function too often there is not so much risk on repetition -  local t = { 8, 9, "a", "b" }  function os.uuid() @@ -2879,6 +2970,8 @@ if not modules then modules = { } end modules ['l-aux'] = {      license   = "see context related readme files"  } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end +  aux = aux or { }  local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -2971,6 +3064,8 @@ local pattern   = lpeg.Ct(value*(separator*value)^0)  aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache +  function aux.settings_to_array(str)      if not str or str == "" then          return { } @@ -3991,12 +4086,14 @@ local function xmlconvert(data, settings)          else              errorstr = "invalid xml file - parsed text"          end -    else +    elseif type(data) == "string" then          if lpegmatch(grammar_unparsed_text,data) then              errorstr = ""          else              errorstr = "invalid xml file - unparsed text"          end +    else +        errorstr = "invalid xml file - no text at all"      end      if errorstr and errorstr ~= "" then          result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } } } @@ -4033,6 +4130,19 @@ end  xml.convert = xmlconvert +function xml.inheritedconvert(data,xmldata) +    local settings = xmldata.settings +    settings.parent_root = xmldata -- to be tested + -- settings.no_root = true +    local xc = xmlconvert(data,settings) + -- xc.settings = nil + -- xc.entities = nil + -- xc.special = nil + -- xc.ri = nil + -- print(xc.tg) +    return xc +end +  --[[ldx--  <p>Packaging data in an xml like table is done with the following  function. Maybe it will go away (when not used).</p> @@ -5840,25 +5950,15 @@ if not modules then modules = { } end modules ['lxml-aux'] = {  local trace_manipulations = false  trackers.register("lxml.manipulations", function(v) trace_manipulations = v end) -local xmlparseapply, xmlconvert, xmlcopy = xml.parse_apply, xml.convert, xml.copy +local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name +local xmlinheritedconvert = xml.inheritedconvert  local type = type  local insert, remove = table.insert, table.remove  local gmatch, gsub = string.gmatch, string.gsub - -function xml.inheritedconvert(data,xmldata) -    local settings = xmldata.settings -    settings.parent_root = xmldata -- to be tested ---~ settings.no_root = true -    local xc = xmlconvert(data,settings) ---~ xc.settings = nil ---~ xc.entities = nil ---~ xc.special = nil ---~ xc.ri = nil ---~ print(xc.tg) ---    for k,v in pairs(xc) do print(k,tostring(v)) end -    return xc +local function report(what,pattern,c,e) +    logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)  end  local function withelements(e,handle,depth) @@ -5914,7 +6014,7 @@ end  xml.elements_only = xml.collected -function xml.each_element(root, pattern, handle, reverse) +function xml.each_element(root,pattern,handle,reverse)      local collected = xmlparseapply({ root },pattern)      if collected then          if reverse then @@ -5932,7 +6032,7 @@ end  xml.process_elements = xml.each_element -function xml.process_attributes(root, pattern, handle) +function xml.process_attributes(root,pattern,handle)      local collected = xmlparseapply({ root },pattern)      if collected and handle then          for c=1,#collected do @@ -5983,7 +6083,7 @@ function xml.collect_tags(root, pattern, nonamespace)  end  --[[ldx-- -<p>We've now arrives at the functions that manipulate the tree.</p> +<p>We've now arrived at the functions that manipulate the tree.</p>  --ldx]]--  local no_root = { no_root = true } @@ -5997,120 +6097,44 @@ function xml.redo_ni(d)      end  end -function xml.inject_element(root, pattern, element, prepend) -    if root and element then -        if type(element) == "string" then ---~             element = xmlconvert(element,no_root) -            element = xml.inheritedconvert(element,root) -        end -        if element then -            if element.ri then -                element = element.dt[element.ri].dt -            else -                element = element.dt -            end -            -- we need to re-index -            local collected = xmlparseapply({ root },pattern) -            if collected then -                for c=1,#collected do -                    local e = collected[c] -                    local r, d, k = e.__p__, r.dt, e.ni -                    local edt -                    if r.ri then -                        edt = r.dt[r.ri].dt -                    else -                        edt = d and d[k] and d[k].dt -                    end -                    if edt then -                        local be, af -                        if prepend then -                            be, af = xmlcopy(element), edt -be.__p__ = e - -                        else -                            be, af = edt, xmlcopy(element) -af.__p__ = e -                        end -                        for i=1,#af do -                            be[#be+1] = af[i] -                        end -                        if r.ri then -                            r.dt[r.ri].dt = be -                        else -                            d[k].dt = be -                        end -                    else -                        -- r.dt = element.dt -- todo -                    end -xml.redo_ni(d) -                end -            end -        end +local function xmltoelement(whatever,root) +    if not whatever then +        return nil +    end +    local element +    if type(whatever) == "string" then +        element = xmlinheritedconvert(whatever,root) +    else +        element = whatever -- we assume a table      end +    if element.error then +        return whatever -- string +    end +    if element then +    --~ if element.ri then +    --~     element = element.dt[element.ri].dt +    --~ else +    --~     element = element.dt +    --~ end +    end +    return element  end --- todo: copy ! +xml.toelement = xmltoelement -function xml.insert_element(root, pattern, element, before) -- todo: element als functie -    if root and element then -        if pattern == "/" then -            xml.inject_element(root, pattern, element, before) -        else -            local matches, collect = { }, nil -            if type(element) == "string" then ---~                 element = xmlconvert(element,no_root) -                element = xml.inheritedconvert(element,root) -            end -            if element and element.ri then -                element = element.dt[element.ri] -            end -            if element then -                local collected = xmlparseapply({ root },pattern) -                if collected then -                    for c=1,#collected do -                        local e = collected[c] -                        local r = e.__p__ -                        local d = r.dt -                        local k = e.ni -                        if not before then -                            k = k + 1 -                        end -                        local ce = xmlcopy(element) -ce.__p__ = r -                        if element.tg then -                            insert(d,k,ce) -- untested -                        else -                            -- maybe bugged -                            local edt = ce.dt -                            if edt then -                                for i=1,#edt do -local edti = edt[i] -                                    insert(d,k,edti) -if type(edti) == "table" then -    edti.__p__ = r -end -                                    k = k + 1 -                                end -                            end -                        end -xml.redo_ni(d) -                    end -                end -            end +local function copiedelement(element,newparent) +    if type(element) == "string" then +        return element +    else +        element = xmlcopy(element).dt +        if newparent and type(element) == "table" then +            element.__p__ = newparent          end +        return element      end  end -xml.insert_element_after  =                 xml.insert_element -xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end -xml.inject_element_after  =                 xml.inject_element -xml.inject_element_before = function(r,p,e) xml.inject_element(r,p,e,true) end - -local function report(what,pattern,c,e) -    logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xml.name(e),xml.name(e.__p__),c,e.ni,pattern) -end - -function xml.delete_element(root, pattern) +function xml.delete_element(root,pattern)      local collected = xmlparseapply({ root },pattern)      if collected then          for c=1,#collected do @@ -6118,43 +6142,90 @@ function xml.delete_element(root, pattern)              local p = e.__p__              if p then                  if trace_manipulations then -                    report('deleting',pattern,c,tostring(e)) -- fails +                    report('deleting',pattern,c,e)                  end                  local d = p.dt                  remove(d,e.ni) -xml.redo_ni(d) +                xml.redo_ni(d) -- can be made faster and inlined              end          end      end  end -function xml.replace_element(root, pattern, element) -    if type(element) == "string" then ---~         element = xmlconvert(element,true) -            element = xml.inheritedconvert(element,root) -    end -    if element and element.ri then -        element = element.dt[element.ri] +function xml.replace_element(root,pattern,whatever) +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local p = e.__p__ +            if p then +                if trace_manipulations then +                    report('replacing',pattern,c,e) +                end +                local d = p.dt +                d[e.ni] = copiedelement(element,p) +                xml.redo_ni(d) -- probably not needed +            end +        end      end -    if element then -        local collected = xmlparseapply({ root },pattern) -        if collected then -            for c=1,#collected do -                local e = collected[c] -                local p = e.__p__ -                if p then -                    if trace_manipulations then -                        report('replacing',pattern,c,e) -                    end -                    local d = p.dt -                    d[e.ni] = element.dt -- maybe not clever enough ---~ xml.redo_ni(d) +end + +local function inject_element(root,pattern,whatever,prepend) +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local r = e.__p__ +            local d, k, rri = r.dt, e.ni, r.ri +            local edt = (rri and d[rri].dt) or (d and d[k] and d[k].dt) +            if edt then +                local be, af +                local cp = copiedelement(element,e) +                if prepend then +                    be, af = cp, edt +                else +                    be, af = edt, cp                  end +                for i=1,#af do +                    be[#be+1] = af[i] +                end +                if rri then +                    r.dt[rri].dt = be +                else +                    d[k].dt = be +                end +                xml.redo_ni(d) +            end +        end +    end +end + +local function insert_element(root,pattern,whatever,before) -- todo: element als functie +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local r = e.__p__ +            local d, k = r.dt, e.ni +            if not before then +                k = k + 1              end +            insert(d,k,copiedelement(element,r)) +            xml.redo_ni(d)          end      end  end +xml.insert_element        =                 insert_element +xml.insert_element_after  =                 insert_element +xml.insert_element_before = function(r,p,e) insert_element(r,p,e,true) end +xml.inject_element        =                 inject_element +xml.inject_element_after  =                 inject_element +xml.inject_element_before = function(r,p,e) inject_element(r,p,e,true) end +  local function include(xmldata,pattern,attribute,recursive,loaddata)      -- parse="text" (default: xml), encoding="" (todo)      -- attribute = attribute or 'href' @@ -6187,7 +6258,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)  --~                 local settings = xmldata.settings  --~                 settings.parent_root = xmldata -- to be tested  --~                 local xi = xmlconvert(data,settings) -                local xi = xml.inheritedconvert(data,xmldata) +                local xi = xmlinheritedconvert(data,xmldata)                  if not xi then                      epdt[ek.ni] = "" -- xml.empty(d,k)                  else diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools index 9f34bea72..5fcc30d3c 100755 --- a/scripts/context/stubs/unix/luatools +++ b/scripts/context/stubs/unix/luatools @@ -530,7 +530,7 @@ end  function table.keys(t)      local k = { } -    for key,_ in next, t do +    for key, _ in next, t do          k[#k+1] = key      end      return k @@ -1755,6 +1755,12 @@ end  os.type = os.type or (io.pathseparator == ";"       and "windows") or "unix"  os.name = os.name or (os.type          == "windows" and "mswin"  ) or "linux" +if os.type == "windows" then +    os.libsuffix, os.binsuffix = 'dll', 'exe' +else +    os.libsuffix, os.binsuffix = 'so', '' +end +  function os.launch(str)      if os.type == "windows" then          os.execute("start " .. str) -- os.spawn ? @@ -1763,10 +1769,6 @@ function os.launch(str)      end  end -if not os.setenv then -    function os.setenv() return false end -end -  if not os.times then      -- utime  = user time      -- stime  = system time @@ -1798,63 +1800,153 @@ end  -- no need for function anymore as we have more clever code and helpers now -os.platform  = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then -    if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then -        os.platform = "mswin-64" -    else -        os.platform = "mswin" +osmt.__index = function(t,k) +    return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + +    -- we still store them but they won't be seen in +    -- child processes although we might pass them some day +    -- using command concatination + +    local env, getenv = { }, os.getenv + +    function os.setenv(k,v) +        env[k] = v      end -    os.libsuffix = 'dll' -    os.binsuffix = 'exe' -else -    local architecture = os.getenv("HOSTTYPE") or "" -    if architecture == "" then -        architecture = os.resultof("uname -m") or "" + +    function os.getenv(k) +        return env[k] or getenv(k) +    end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() +    local architecture = os.resultof("uname -m") or "" +    if architecture ~= "" then +        return architecture      end -    if architecture == "" then -        local architecture = os.resultof("echo $HOSTTYPE") +    architecture = os.getenv("HOSTTYPE") or "" +    if architecture ~= "" then +        return architecture      end -    if name == "linux" then +    return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + +    os.platform = platform + +elseif os.type == "windows" then + +    -- we could set the variable directly, no function needed here + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" +        if find(architecture,"AMD64") then +            platform = "mswin-64" +        else +            platform = "mswin" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "linux" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""          if find(architecture,"x86_64") then -            os.platform = "linux-64" +            platform = "linux-64"          elseif find(architecture,"ppc") then -            os.platform = "linux-ppc" +            platform = "linux-ppc"          else -            os.platform = "linux" +            platform = "linux" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "macosx" then -- a rather inconsistent mess + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or "" +        if architecture == "" then +            architecture = os.getenv("HOSTTYPE") or "" +        end +        if architecture == "" then +            architecture = os.resultof("echo $HOSTTYPE") or ""          end -    elseif name == "macosx" then          if find(architecture,"i386") then -            os.platform = "osx-intel" +            platform = "osx-intel"          elseif find(architecture,"x86_64") then -            os.platform = "osx-64" +            platform = "osx-64"          else -            os.platform = "osx-ppc" +            platform = "osx-ppc"          end -    elseif name == "sunos" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "sunos" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"sparc") then -            os.platform = "solaris-sparc" +            platform = "solaris-sparc"          else -- if architecture == 'i86pc' -            os.platform = "solaris-intel" +            platform = "solaris-intel"          end -    elseif name == "freebsd" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "freebsd" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"amd64") then -            os.platform = "freebsd-amd64" +            platform = "freebsd-amd64"          else -            os.platform = "freebsd" +            platform = "freebsd"          end -    else -        os.platform = 'linux' +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +else + +    -- platform = "linux" +    -- os.setenv("MTX_PLATFORM",platform) +    -- os.platform = platform + +    function os.resolvers.platform(t,k) +        local platform = "linux" +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end +  end  -- beware, we set the randomseed ---  -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the  -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1863,7 +1955,6 @@ end  --  -- as we don't call this function too often there is not so much risk on repetition -  local t = { 8, 9, "a", "b" }  function os.uuid() @@ -2266,7 +2357,9 @@ local hexdigit  = lpeg.R("09","AF","af")  local plus      = lpeg.P("+")  local escaped   = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) -local scheme    =                 lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("") +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme    =                 lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon + lpeg.Cc("")  local authority = slash * slash * lpeg.Cs((escaped+(1-      slash-qmark-hash))^0)         + lpeg.Cc("")  local path      = slash *         lpeg.Cs((escaped+(1-            qmark-hash))^0)         + lpeg.Cc("")  local query     = qmark         * lpeg.Cs((escaped+(1-                  hash))^0)         + lpeg.Cc("") @@ -3181,6 +3274,8 @@ if not modules then modules = { } end modules ['l-aux'] = {      license   = "see context related readme files"  } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end +  aux = aux or { }  local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -3273,6 +3368,8 @@ local pattern   = lpeg.Ct(value*(separator*value)^0)  aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache +  function aux.settings_to_array(str)      if not str or str == "" then          return { } diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 051cd0fa8..0b2a9cd02 100755 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -539,7 +539,7 @@ end  function table.keys(t)      local k = { } -    for key,_ in next, t do +    for key, _ in next, t do          k[#k+1] = key      end      return k @@ -1764,6 +1764,12 @@ end  os.type = os.type or (io.pathseparator == ";"       and "windows") or "unix"  os.name = os.name or (os.type          == "windows" and "mswin"  ) or "linux" +if os.type == "windows" then +    os.libsuffix, os.binsuffix = 'dll', 'exe' +else +    os.libsuffix, os.binsuffix = 'so', '' +end +  function os.launch(str)      if os.type == "windows" then          os.execute("start " .. str) -- os.spawn ? @@ -1772,10 +1778,6 @@ function os.launch(str)      end  end -if not os.setenv then -    function os.setenv() return false end -end -  if not os.times then      -- utime  = user time      -- stime  = system time @@ -1807,63 +1809,153 @@ end  -- no need for function anymore as we have more clever code and helpers now -os.platform  = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = { } -local name = os.name +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then -    if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then -        os.platform = "mswin-64" -    else -        os.platform = "mswin" +osmt.__index = function(t,k) +    return (os.resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + +    -- we still store them but they won't be seen in +    -- child processes although we might pass them some day +    -- using command concatination + +    local env, getenv = { }, os.getenv + +    function os.setenv(k,v) +        env[k] = v      end -    os.libsuffix = 'dll' -    os.binsuffix = 'exe' -else -    local architecture = os.getenv("HOSTTYPE") or "" -    if architecture == "" then -        architecture = os.resultof("uname -m") or "" + +    function os.getenv(k) +        return env[k] or getenv(k) +    end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() +    local architecture = os.resultof("uname -m") or "" +    if architecture ~= "" then +        return architecture +    end +    architecture = os.getenv("HOSTTYPE") or "" +    if architecture ~= "" then +        return architecture      end -    if architecture == "" then -        local architecture = os.resultof("echo $HOSTTYPE") +    return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + +    os.platform = platform + +elseif os.type == "windows" then + +    -- we could set the variable directly, no function needed here + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" +        if find(architecture,"AMD64") then +            platform = "mswin-64" +        else +            platform = "mswin" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end -    if name == "linux" then + +elseif name == "linux" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""          if find(architecture,"x86_64") then -            os.platform = "linux-64" +            platform = "linux-64"          elseif find(architecture,"ppc") then -            os.platform = "linux-ppc" +            platform = "linux-ppc"          else -            os.platform = "linux" +            platform = "linux" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "macosx" then -- a rather inconsistent mess + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or "" +        if architecture == "" then +            architecture = os.getenv("HOSTTYPE") or "" +        end +        if architecture == "" then +            architecture = os.resultof("echo $HOSTTYPE") or ""          end -    elseif name == "macosx" then          if find(architecture,"i386") then -            os.platform = "osx-intel" +            platform = "osx-intel"          elseif find(architecture,"x86_64") then -            os.platform = "osx-64" +            platform = "osx-64"          else -            os.platform = "osx-ppc" +            platform = "osx-ppc"          end -    elseif name == "sunos" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "sunos" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"sparc") then -            os.platform = "solaris-sparc" +            platform = "solaris-sparc"          else -- if architecture == 'i86pc' -            os.platform = "solaris-intel" +            platform = "solaris-intel"          end -    elseif name == "freebsd" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "freebsd" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"amd64") then -            os.platform = "freebsd-amd64" +            platform = "freebsd-amd64"          else -            os.platform = "freebsd" +            platform = "freebsd"          end -    else -        os.platform = 'linux' +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end + +else + +    -- platform = "linux" +    -- os.setenv("MTX_PLATFORM",platform) +    -- os.platform = platform + +    function os.resolvers.platform(t,k) +        local platform = "linux" +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end +  end  -- beware, we set the randomseed ---  -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the  -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -1872,7 +1964,6 @@ end  --  -- as we don't call this function too often there is not so much risk on repetition -  local t = { 8, 9, "a", "b" }  function os.uuid() @@ -2879,6 +2970,8 @@ if not modules then modules = { } end modules ['l-aux'] = {      license   = "see context related readme files"  } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end +  aux = aux or { }  local concat, format, gmatch = table.concat, string.format, string.gmatch @@ -2971,6 +3064,8 @@ local pattern   = lpeg.Ct(value*(separator*value)^0)  aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache +  function aux.settings_to_array(str)      if not str or str == "" then          return { } @@ -3991,12 +4086,14 @@ local function xmlconvert(data, settings)          else              errorstr = "invalid xml file - parsed text"          end -    else +    elseif type(data) == "string" then          if lpegmatch(grammar_unparsed_text,data) then              errorstr = ""          else              errorstr = "invalid xml file - unparsed text"          end +    else +        errorstr = "invalid xml file - no text at all"      end      if errorstr and errorstr ~= "" then          result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } } } @@ -4033,6 +4130,19 @@ end  xml.convert = xmlconvert +function xml.inheritedconvert(data,xmldata) +    local settings = xmldata.settings +    settings.parent_root = xmldata -- to be tested + -- settings.no_root = true +    local xc = xmlconvert(data,settings) + -- xc.settings = nil + -- xc.entities = nil + -- xc.special = nil + -- xc.ri = nil + -- print(xc.tg) +    return xc +end +  --[[ldx--  <p>Packaging data in an xml like table is done with the following  function. Maybe it will go away (when not used).</p> @@ -5840,25 +5950,15 @@ if not modules then modules = { } end modules ['lxml-aux'] = {  local trace_manipulations = false  trackers.register("lxml.manipulations", function(v) trace_manipulations = v end) -local xmlparseapply, xmlconvert, xmlcopy = xml.parse_apply, xml.convert, xml.copy +local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name +local xmlinheritedconvert = xml.inheritedconvert  local type = type  local insert, remove = table.insert, table.remove  local gmatch, gsub = string.gmatch, string.gsub - -function xml.inheritedconvert(data,xmldata) -    local settings = xmldata.settings -    settings.parent_root = xmldata -- to be tested ---~ settings.no_root = true -    local xc = xmlconvert(data,settings) ---~ xc.settings = nil ---~ xc.entities = nil ---~ xc.special = nil ---~ xc.ri = nil ---~ print(xc.tg) ---    for k,v in pairs(xc) do print(k,tostring(v)) end -    return xc +local function report(what,pattern,c,e) +    logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)  end  local function withelements(e,handle,depth) @@ -5914,7 +6014,7 @@ end  xml.elements_only = xml.collected -function xml.each_element(root, pattern, handle, reverse) +function xml.each_element(root,pattern,handle,reverse)      local collected = xmlparseapply({ root },pattern)      if collected then          if reverse then @@ -5932,7 +6032,7 @@ end  xml.process_elements = xml.each_element -function xml.process_attributes(root, pattern, handle) +function xml.process_attributes(root,pattern,handle)      local collected = xmlparseapply({ root },pattern)      if collected and handle then          for c=1,#collected do @@ -5983,7 +6083,7 @@ function xml.collect_tags(root, pattern, nonamespace)  end  --[[ldx-- -<p>We've now arrives at the functions that manipulate the tree.</p> +<p>We've now arrived at the functions that manipulate the tree.</p>  --ldx]]--  local no_root = { no_root = true } @@ -5997,120 +6097,44 @@ function xml.redo_ni(d)      end  end -function xml.inject_element(root, pattern, element, prepend) -    if root and element then -        if type(element) == "string" then ---~             element = xmlconvert(element,no_root) -            element = xml.inheritedconvert(element,root) -        end -        if element then -            if element.ri then -                element = element.dt[element.ri].dt -            else -                element = element.dt -            end -            -- we need to re-index -            local collected = xmlparseapply({ root },pattern) -            if collected then -                for c=1,#collected do -                    local e = collected[c] -                    local r, d, k = e.__p__, r.dt, e.ni -                    local edt -                    if r.ri then -                        edt = r.dt[r.ri].dt -                    else -                        edt = d and d[k] and d[k].dt -                    end -                    if edt then -                        local be, af -                        if prepend then -                            be, af = xmlcopy(element), edt -be.__p__ = e - -                        else -                            be, af = edt, xmlcopy(element) -af.__p__ = e -                        end -                        for i=1,#af do -                            be[#be+1] = af[i] -                        end -                        if r.ri then -                            r.dt[r.ri].dt = be -                        else -                            d[k].dt = be -                        end -                    else -                        -- r.dt = element.dt -- todo -                    end -xml.redo_ni(d) -                end -            end -        end +local function xmltoelement(whatever,root) +    if not whatever then +        return nil +    end +    local element +    if type(whatever) == "string" then +        element = xmlinheritedconvert(whatever,root) +    else +        element = whatever -- we assume a table      end +    if element.error then +        return whatever -- string +    end +    if element then +    --~ if element.ri then +    --~     element = element.dt[element.ri].dt +    --~ else +    --~     element = element.dt +    --~ end +    end +    return element  end --- todo: copy ! +xml.toelement = xmltoelement -function xml.insert_element(root, pattern, element, before) -- todo: element als functie -    if root and element then -        if pattern == "/" then -            xml.inject_element(root, pattern, element, before) -        else -            local matches, collect = { }, nil -            if type(element) == "string" then ---~                 element = xmlconvert(element,no_root) -                element = xml.inheritedconvert(element,root) -            end -            if element and element.ri then -                element = element.dt[element.ri] -            end -            if element then -                local collected = xmlparseapply({ root },pattern) -                if collected then -                    for c=1,#collected do -                        local e = collected[c] -                        local r = e.__p__ -                        local d = r.dt -                        local k = e.ni -                        if not before then -                            k = k + 1 -                        end -                        local ce = xmlcopy(element) -ce.__p__ = r -                        if element.tg then -                            insert(d,k,ce) -- untested -                        else -                            -- maybe bugged -                            local edt = ce.dt -                            if edt then -                                for i=1,#edt do -local edti = edt[i] -                                    insert(d,k,edti) -if type(edti) == "table" then -    edti.__p__ = r -end -                                    k = k + 1 -                                end -                            end -                        end -xml.redo_ni(d) -                    end -                end -            end +local function copiedelement(element,newparent) +    if type(element) == "string" then +        return element +    else +        element = xmlcopy(element).dt +        if newparent and type(element) == "table" then +            element.__p__ = newparent          end +        return element      end  end -xml.insert_element_after  =                 xml.insert_element -xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end -xml.inject_element_after  =                 xml.inject_element -xml.inject_element_before = function(r,p,e) xml.inject_element(r,p,e,true) end - -local function report(what,pattern,c,e) -    logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xml.name(e),xml.name(e.__p__),c,e.ni,pattern) -end - -function xml.delete_element(root, pattern) +function xml.delete_element(root,pattern)      local collected = xmlparseapply({ root },pattern)      if collected then          for c=1,#collected do @@ -6118,43 +6142,90 @@ function xml.delete_element(root, pattern)              local p = e.__p__              if p then                  if trace_manipulations then -                    report('deleting',pattern,c,tostring(e)) -- fails +                    report('deleting',pattern,c,e)                  end                  local d = p.dt                  remove(d,e.ni) -xml.redo_ni(d) +                xml.redo_ni(d) -- can be made faster and inlined              end          end      end  end -function xml.replace_element(root, pattern, element) -    if type(element) == "string" then ---~         element = xmlconvert(element,true) -            element = xml.inheritedconvert(element,root) -    end -    if element and element.ri then -        element = element.dt[element.ri] +function xml.replace_element(root,pattern,whatever) +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local p = e.__p__ +            if p then +                if trace_manipulations then +                    report('replacing',pattern,c,e) +                end +                local d = p.dt +                d[e.ni] = copiedelement(element,p) +                xml.redo_ni(d) -- probably not needed +            end +        end      end -    if element then -        local collected = xmlparseapply({ root },pattern) -        if collected then -            for c=1,#collected do -                local e = collected[c] -                local p = e.__p__ -                if p then -                    if trace_manipulations then -                        report('replacing',pattern,c,e) -                    end -                    local d = p.dt -                    d[e.ni] = element.dt -- maybe not clever enough ---~ xml.redo_ni(d) +end + +local function inject_element(root,pattern,whatever,prepend) +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local r = e.__p__ +            local d, k, rri = r.dt, e.ni, r.ri +            local edt = (rri and d[rri].dt) or (d and d[k] and d[k].dt) +            if edt then +                local be, af +                local cp = copiedelement(element,e) +                if prepend then +                    be, af = cp, edt +                else +                    be, af = edt, cp                  end +                for i=1,#af do +                    be[#be+1] = af[i] +                end +                if rri then +                    r.dt[rri].dt = be +                else +                    d[k].dt = be +                end +                xml.redo_ni(d) +            end +        end +    end +end + +local function insert_element(root,pattern,whatever,before) -- todo: element als functie +    local element = root and xmltoelement(whatever,root) +    local collected = element and xmlparseapply({ root },pattern) +    if collected then +        for c=1,#collected do +            local e = collected[c] +            local r = e.__p__ +            local d, k = r.dt, e.ni +            if not before then +                k = k + 1              end +            insert(d,k,copiedelement(element,r)) +            xml.redo_ni(d)          end      end  end +xml.insert_element        =                 insert_element +xml.insert_element_after  =                 insert_element +xml.insert_element_before = function(r,p,e) insert_element(r,p,e,true) end +xml.inject_element        =                 inject_element +xml.inject_element_after  =                 inject_element +xml.inject_element_before = function(r,p,e) inject_element(r,p,e,true) end +  local function include(xmldata,pattern,attribute,recursive,loaddata)      -- parse="text" (default: xml), encoding="" (todo)      -- attribute = attribute or 'href' @@ -6187,7 +6258,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)  --~                 local settings = xmldata.settings  --~                 settings.parent_root = xmldata -- to be tested  --~                 local xi = xmlconvert(data,settings) -                local xi = xml.inheritedconvert(data,xmldata) +                local xi = xmlinheritedconvert(data,xmldata)                  if not xi then                      epdt[ek.ni] = "" -- xml.empty(d,k)                  else  | 
