aboutsummaryrefslogtreecommitdiff
path: root/files.lua
blob: 130a880fff25baed66cfe874e061804e5e2a7c0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
local files = { }
local _FILE_CACHE = { }
files.spoof = function(filename, contents)
  _FILE_CACHE[filename] = contents
end
files.read = function(filename)
  do
    local file_contents = _FILE_CACHE[filename]
    if file_contents then
      return file_contents
    end
  end
  local file = io.open(filename)
  if package.nomsupath and not file then
    for nomsupath in package.nomsupath:gmatch("[^;]+") do
      file = io.open(nomsupath .. "/" .. filename)
      if file then
        break
      end
    end
  end
  if not (file) then
    return nil
  end
  local contents = file:read("*a")
  file:close()
  _FILE_CACHE[filename] = contents
  return contents
end
local iterate_single
iterate_single = function(item, prev)
  if item == prev then
    return nil
  else
    return item
  end
end
local match, gsub
do
  local _obj_0 = string
  match, gsub = _obj_0.match, _obj_0.gsub
end
iterate_single = function(item, prev)
  if item == prev then
    return nil
  else
    return item
  end
end
local ok, lfs = pcall(require, "lfs")
if ok then
  files.walk = function(path)
    local browse
    browse = function(filename)
      local file_type = lfs.attributes(filename, 'mode')
      if file_type == 'file' then
        if match(filename, "%.nom$") or match(filename, "%.lua$") then
          coroutine.yield(filename)
          return true
        end
      elseif file_type == 'directory' then
        for subfile in lfs.dir(filename) do
          if not (subfile == "." or subfile == ".." or not subfile:match("%.nom$")) then
            browse(filename .. "/" .. subfile)
          end
        end
        return true
      elseif file_type == 'char device' then
        coroutine.yield(filename)
        return true
      end
      return false
    end
    return coroutine.wrap(function()
      if not browse(path) and package.nomsupath then
        for nomsupath in package.nomsupath:gmatch("[^;]+") do
          if browse(nomsupath .. "/" .. path) then
            break
          end
        end
      end
      return nil
    end)
  end
else
  local ret = os.execute('find . -maxdepth 0')
  if not (ret == true or ret == 0) then
    error("Could not find 'luafilesystem' module and couldn't run system command `find` (this might happen on Windows). Please install `luafilesystem` (which can be found at: http://keplerproject.github.io/luafilesystem/ or `luarocks install luafilesystem`)", 0)
  end
  files.walk = function(path)
    if match(path, "%.nom$") or match(path, "%.lua$") or match(path, "^/dev/fd/[012]$") then
      return iterate_single, path
    end
    path = gsub(path, "\\", "\\\\")
    path = gsub(path, "`", "")
    path = gsub(path, '"', '\\"')
    path = gsub(path, "$", "")
    return coroutine.wrap(function()
      local f = io.popen('find -L "' .. path .. '" -not -path "*/\\.*" -type f -name "*.nom"')
      local found = false
      for line in f:lines() do
        found = true
        coroutine.yield(line)
      end
      if not found and package.nomsupath then
        f:close()
        for nomsupath in package.nomsupath:gmatch("[^;]+") do
          f = io.popen('find -L "' .. package.nomsupath .. '/' .. path .. '" -not -path "*/\\.*" -type f -name "*.nom"')
          for line in f:lines() do
            found = true
            coroutine.yield(line)
          end
          f:close()
          if found then
            break
          end
        end
      end
      if not (found) then
        return error("Invalid file path: " .. tostring(path))
      end
    end)
  end
end
return files