# Requires util.tnsl ;struct Path { {}{}uint8 dirs, {}uint8 file } /; method Path /; rel_file ({}uint8 rpath) [Path] ;{}{}uint8 spl = split(rpath, '/') ;Path out = {{}, ""} /; loop (int i = 0; i < len (self.dirs)) [i++] ;out.dirs.append(self.dirs{i}) ;/ /; loop (int i = 0; i < len spl - 1) [i++] ;out.dirs.append(spl{i}) ;/ ;out.file = spl{len spl - 1} ;return out ;/ /; full_path [{}uint8] ;{}uint8 out = join((self.dirs), '/') /; if (len (self.dirs) > 0) ;out.append('/') ;/ ;add_strings(~out, ~(self.file)) ;return out ;/ /; open_w [tnsl.io.File] ;return tnsl.io.writeFile(self.full_path()) ;/ /; open_r [tnsl.io.File] ;return tnsl.io.readFile(self.full_path()) ;/ /; extension_is ({}uint8 chk) [bool] ;{}uint8 ext = "" ;int dot = -1 /; loop (int i = len (self.file) - 1; i > 0) [i = i - 1] /; if (self.file{i} == '.') ;dot = i ;break ;/ ;/ /; if (dot > 0) ;dot++ /; loop (dot < len (self.file)) [dot++] ;ext.append(self.file{dot}) ;/ ;/ ;return string_equate(chk, ext) ;/ ;/ /; split({}uint8 str, uint8 c) [{}{}uint8] ;{}{}uint8 out = {} ;{}uint8 tmp = "" /; loop (int i = 0; i < len str) [i++] /; if (str{i} == c) ;out.append(tmp) ;{}uint8 tmp = "" ;true # work around for interpreter bug ;; else ;tmp.append(str{i}) ;/ ;/ ;out.append(tmp) ;return out ;/ /; join ({}{}uint8 s, uint8 jc) [{}uint8] ;{}uint8 out = "" /; loop (int i = 0; i < len s) [i++] /; loop (int j = 0; j < len s{i}) [j++] ;out.append(s{i}{j}) ;/ /; if (i < len s - 1) ;out.append(jc) ;/ ;/ ;return out ;/ /; path_from_str ({}uint8 f) [Path] ;{}{}uint8 spl = split(f, '/') ;Path out = {{}, ""} /; loop (int i = 0; i < len spl - 1) [i++] ;out.dirs.append(spl{i}) ;/ ;out.file = spl{len spl - 1} ;return out ;/