File: tree.lua

package info (click to toggle)
lua-posix 36.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,720 kB
  • sloc: ansic: 5,462; makefile: 21; sh: 6
file content (62 lines) | stat: -rw-r--r-- 2,020 bytes parent folder | download
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
#! /usr/bin/env lua

-- tree view of the file system like the 'tree' unix utility
-- John Belmonte <jvb@prairienet.org>

local dir = require 'posix.dirent'.dir
local islink = require 'posix.sys.stat'.S_ISLNK
local isdir = require 'posix.sys.stat'.S_ISDIR
local readlink = require 'posix.unistd'.readlink
local stat = require 'posix.sys.stat'.stat

local leaf_indent = '|   '
local tail_leaf_indent = '   '
local leaf_prefix = '|-- '
local tail_leaf_prefix = '`-- '
local link_prefix = ' -> '

local function printf(...)
  io.write(string.format(...))
end

local function do_directory(directory, level, prefix)
   local num_dirs = 0
   local num_files = 0
   local files = dir(directory)
   local last_file_index = #files
   table.sort(files)
   for i, name in ipairs(files) do
      if name ~= '.' and name ~= '..' then
         local full_name = string.format('%s/%s', directory, name)
         local info = assert(stat(full_name))
         local is_tail = (i==last_file_index)
         local prefix2 = is_tail and tail_leaf_prefix or leaf_prefix
         local link = ''
         if islink(info.st_mode) ~= 0 then
            linked_name = assert(readlink(full_name))
            link = string.format('%s%s', link_prefix, linked_name)
         end
         printf('%s%s%s%s\n', prefix, prefix2, name, link)
         if isdir(info.st_mode) ~= 0 then
            local indent = is_tail and tail_leaf_indent or leaf_indent
            -- TODO: cache string concatenation
            sub_dirs, sub_files = do_directory(full_name, level+1,
               prefix .. indent)
            num_dirs = num_dirs + sub_dirs + 1
            num_files = num_files + sub_files
         else
            num_files = num_files + 1
         end
      end
   end
   return num_dirs, num_files
end

local function fore(directory)
   print(directory)
   num_dirs, num_files = do_directory(directory, 0, '')
   printf('\n%d directories, %d files\n', num_dirs, num_files)
end

directory = (arg and #arg > 0) and arg[1] or '.'
fore(directory)