import libc.*; findFirstFile(path) { var dirp = opendir(cstring(path)); if (null?(dirp)) throw 1; return dirp; } findNextFile(dirp) = FileSequence(dirp); findClose(dirp) = closedir(dirp); // // FileSequence // private record FileSequence { d : Pointer[DIR]; } overload iterator(x:FileSequence) = FileIterator(x.d, false, null(Struct_dirent)); // // FileIterator // private record FileIterator { dirp : Pointer[DIR]; queued? : Bool; entry : Pointer[Struct_dirent]; } overload hasNext?(x:FileIterator) { if (not x.queued?) { x.queued? = true; var returnCode = readdir_r(x.dirp, allocateMemory(Struct_dirent, 1), &x.entry); if (returnCode != 0) throw returnCode; } return not(null?(x.entry)); } overload next(x:FileIterator) { if (not x.queued?) hasNext?(x); x.queued? = false; return x.entry; } // ///////////////////////////////////////////////////// main() { for (x in findNextFile(findFirstFile("/home"))) puts(&x^.d_name[0]); }