lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I use a 'split' function (see below) to iterate over
possible locations.  It accepts nested (possibly
empty) branches between parentheses.  Also, it treats
`|' and `;' as equivalent separators.

Here's an example:

split("(.|wim(/aap|/noot))/?(|.lua;.lc);mod/?.(mod|mc)",
print)

output:

./?
./?.lua
./?.lc
wim/aap/?
wim/aap/?.lua
wim/aap/?.lc
wim/noot/?
wim/noot/?.lua
wim/noot/?.lc
mod/?.mod
mod/?.mc

Here's the implementation of split:

local split

do

local cache = setmetatable({}, {__mode = "v"})

local function topsplit(path, fun)
  local open, close = string.find(path, "%b()")
  local pos = string.find(path, "[|;]")
  local first = 1
  while pos do
    if open and pos > open and pos < close then
      pos = close + 1
      open, close = string.find(path, "%b()", pos)
    else
      fun(string.sub(path, first, pos - 1))
      pos = pos + 1
      first = pos
    end
    pos = string.find(path, "[|;]", pos)
  end
  fun(string.sub(path, first))
end

local function subsplit(part, fun)
  local open, close = string.find(part, "%b()")
  if open then
    local pre = string.sub(part, 1, open - 1)
    local post = string.sub(part, close + 1)
    split(string.sub(part, open + 1, close - 1),
function(part)
      local head = pre .. part
      subsplit(post, function(tail)
        fun(head .. tail)
      end)
    end)
  else
    fun(part)
  end
end

function split(path, fun)
  local c = cache[path]
  if c then
    for i, p in ipairs(c) do fun(p) end
  else
    c = {}

    local function add(part)
      table.insert(c, part)
      fun(part)
    end

    topsplit(path, function(part)
      subsplit(part, add)
    end)

    cache[path] = c
  end
end

end


--
Wim


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com