Paste: clay directory listing

Author: ceninan
Mode: factor
Date: Wed, 4 Aug 2010 02:34:40
Plain Text |
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]);
}

Annotation: .

Author: ceninan
Mode: c++
Date: Wed, 4 Aug 2010 14:07:32
Plain Text |
// ///// Example //////////////////
import io.directories.*;

main() {
    for (x in directoryListing("/home"))
        println(x);
}

// ////////////////////////////////
import libc.*;
import unix.errno.*;



//
// directoryListing
//

directoryListing(x) = map(direntPointerToString, direntSequence(x));

private direntPointerToString(x) = String(Pointer[Int8](&x^.d_name));



//
// DirentSequence
//

private record DirentSequence {
    dirp : Pointer[DIR];
}

[T | String?(T)]
direntSequence(x:T) = DirentSequence(cstring(x));

overload DirentSequence(x:Pointer[CChar]) {
    var ret = DirentSequence(opendir(x));
    if (null?(ret.dirp)) {
        throw errno();
    }
    return ret;
}

overload iterator(x:DirentSequence) = DirentIterator(x.dirp, false, null(Struct_dirent));



//
// DirentIterator
//

private record DirentIterator {
    dirp : Pointer[DIR];
    queued? : Bool;
    entry : Pointer[Struct_dirent];
}

overload destroy(x:DirentIterator) {
    if (closedir(x.dirp) > 0)
        throw errno();
}

overload hasNext?(x:DirentIterator) {
    if (not x.queued?) {
        x.queued? = true;

        if (not(null?(x.entry)))
            destroy(x.entry);

        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:DirentIterator) {
    if (not x.queued?)
        hasNext?(x);
    x.queued? = false;
    return x.entry;
}

Annotation: ok? anything else?

Author: ceninan
Mode: factor
Date: Wed, 4 Aug 2010 21:26:39
Plain Text |
import unix.*;
import libc;


//
// directoryListing
//

directoryListing(x) = map(direntPointerToString, direntSequence(x));

private direntPointerToString(x) = CStringRef(Pointer[Int8](&x^.d_name));



//
// DirentSequence
//

private record DirentSequence {
    path : StringConstant;
}

[T | String?(T)]
direntSequence(x:T) = DirentSequence(x);

overload iterator(x:DirentSequence) = DirentIterator(x.path);



//
// DirentIterator
//

private record DirentIterator {
    dirp : Pointer[DIR];
    queued? : Bool;
    entry : Pointer[Struct_dirent];
}

[T | String?(T)]
overload DirentIterator(x:T) {
    var dirp = opendir(cstring(x));
    if (null?(dirp))
        error("failed to open directory: ", errorMessage());
    return DirentIterator(dirp, false, null(Struct_dirent));
}

overload destroy(x:DirentIterator) {
    if (closedir(x.dirp) > 0)
        error("failed to close directory: ", errorMessage());
}

overload hasNext?(x:DirentIterator) {
    if (not x.queued?) {
        x.queued? = true;

        if (not null?(x.entry))
            destroy(x.entry);

        var returnCode = readdir_r(x.dirp, allocateMemory(Struct_dirent, 1), &x.entry);

        if (returnCode != 0)
            error("failed to read directory: ", errorMessage());
    }
    return not null?(x.entry);
}

overload next(x:DirentIterator) {
    if (not x.queued?)
        hasNext?(x);
    x.queued? = false;
    return x.entry;
}



//
// currentDirectory
//

currentDirectory() {
    var buf = String();
    resize(buf, 1024);

    while (true) {
        var result = getcwd(Pointer[CChar](&buf[0]), size(buf));
        if (not null?(result))
            break;
        if (errno() != ERANGE)
            error("failed to get current directory: ", errorMessage());
        resize(buf, 2*size(buf));
    }
 
    resize(buf, libc.strlen(Pointer[CChar](&buf[0])));
    return move(buf);
}



//
// pathToExecutable
//

pathToExecutable() {
    var path_max = pathconf(cstring("/proc/self/exe"), _PC_PATH_MAX);
    if (path_max < 0)
        path_max = 1024;

    var buf = String();
    resize(buf, path_max);

    var size = readlink(cstring("/proc/self/exe"), Pointer[CChar](&buf[0]), size_t(path_max));
    if (size < 0)
        error("failed to get path to current executable: ", errorMessage());

    resize(buf, size);
    return move(buf);
}

Annotation: factor to readLink()

Author: ceninan
Mode: c
Date: Wed, 4 Aug 2010 21:47:21
Plain Text |
readLink(x) {
    var path_max = pathconf(cstring(x), _PC_PATH_MAX);
    if (path_max < 0)
        path_max = 4096;

    var buf = String();
    resize(buf, path_max);

    var size = readlink(cstring(x), Pointer[CChar](&buf[0]), size_t(path_max));
    if (size < 0)
        error("failed to read link: ", errorMessage());

    resize(buf, size);
    return move(buf);
}

pathToExecutable() = readLink("/proc/self/exe");

New Annotation

Summary:
Author:
Mode:
Body: