local PathObj = {} local posix_separator = '/' local windows_separator = '\\' local function split( s, sep, include_sep ) local include = include_sep or false local fields, index = {}, 1 repeat local occurence = s:find(sep, index, true) if include == true then fields[#fields + 1] = s:sub(index - 1, occurence and occurence - 1) else fields[#fields + 1] = s:sub(index, occurence and occurence - 1) end index = occurence and occurence + #sep until not index return fields end local function slice( t, first, last, step ) local sliced = {} local first_index = first or 1 local last_index = last or #t local step_size = step or 1 for i = first_index, last_index, step_size do sliced[#sliced + 1] = t[i] end return sliced end function PathObj:new( path ) local obj = {} local path_blocks = split(path, posix_separator) local slash_count = 0 for i, part in ipairs(path_blocks) do if part == '' then slash_count = slash_count + 1 else break end end if slash_count == 0 then obj.root = '' elseif slash_count == 2 then obj.root = posix_separator .. posix_separator path_blocks = slice(path_blocks, 3) else obj.root = posix_separator path_blocks = slice(path_blocks, slash_count + 1) end if obj.root ~= '' then obj.parts = {obj.root, table.unpack(path_blocks)} else obj.parts = path_block end obj.drive = '' obj.anchor = obj.drive .. obj.root obj._segments = path_blocks obj.name = path_blocks[#path_blocks] local suffices = slice(split(obj.name, ".", true), 2) obj.suffix = suffices[#suffices] obj.suffices = suffices setmetatable(obj, self) self.__index = self return obj end function PathObj:to_string() local out = self.drive .. self.root for i = 1, #self._segments - 1 do out = out .. self._segments[i] .. '/' end out = out .. self._segments[#self._segments] return out end function PathObj:data_repr() print("root = " .. self.root) local segments = "segments = [" for _, seg in ipairs(self.parts) do segments = segments .. seg .. "," end segments = segments .. "]" print(segments) print("name = " .. self.name) print("suffix = " .. self.suffix) local suffices = "suffices = [" for _, seg in ipairs(self.suffices) do suffices = suffices .. seg .. "," end suffices = suffices .. "]" print(suffices) end function PathObj:is_absolute() return self.root ~= '' end print(PathObj:new( "home/folkert/test.ads" ):to_string()) print(PathObj:new( "/home/folkert/test.ads" ):to_string()) print(PathObj:new( "//home/folkert/test.ads" ):to_string()) print(PathObj:new( "///home/folkert/test.ads" ):is_absolute()) local x = PathObj:new( "/home/foo/bar/baz.c" ) print(x:to_string()) return PathObj