digitalmars.D - Request some guidance regarding I/O
- Tyro[17] (141/141) Nov 04 2012 Thanks to Jacob Carlborg's suggestion
Thanks to Jacob Carlborg's suggestion (news://new.digitalmars.com:119/k6d9se$i46$1 digitalmars.com), I decided to create my own little installer for MAC OSX. Albeit a very naive implementation, it does what I ask it to do... (D2 only). Along the way, I picked up a little understanding about I/O, so I decided to try my hand at it. There are a whole lot of things my eyes doesn't yet see and my brain doesn't yet grasp so I wanted to ask the community's making this a better product. The focus is on the I/O piece vice what's implemented in main(). Also, does D allow function scope extern(C) declarations? If so, what is the proper way to do it? If not, why not? What would be the harm in doing so? I would like to make this completely unicode aware but had a little trouble because I don't fully understand what I am doing. Any suggestion would be greatly appreciated. Andrew ---------- module io; import std.process:system; import core.sys.posix.sys.types; import core.sys.posix.fcntl; private static char[] rbuffer; static this() { rbuffer.length = 1024; } enum nl = "\n"; enum stdin = 0; enum stdout = 1; enum stderr = 2; private extern (C) { size_t write(int fd, const void* buf, size_t nbytes); int open(in char* path, int oflags); int open(in char* path, int oflags, mode_t mode); int read(int fildes, void* buf, size_t nbytes); int close(int filedes); } void emit(Args...)(const auto ref Args args) { string buffer; import std.traits:isPointer; import std.string:xformat; foreach (element; args) { static if(isPointer!(typeof(element))) { buffer ~= xformat("%s", *element); } else { buffer ~= xformat("%s", element); } } write(stdout, buffer.ptr, buffer.length); } void emitln(Args...)(Args args) { emit(args, nl); } void save(Args...)(int fd, Args args) { import std.string:format; string buffer = format("%s", args); write(fd, buffer.ptr, buffer.length); } int scan(A)(ref A data) { import std.traits:isPointer, isNumeric, isSomeChar; import std.algorithm:findAmong, stride; import std.ascii:whitespace; import std.conv:to; auto len = read(stdin, rbuffer.ptr, rbuffer.length); auto white = findAmong(rbuffer[0 .. len-1], whitespace); static if(isPointer!(typeof(data))) { if(isNumeric!(typeof(*data)) && white.length) return -1; if (len > 1) { if (isSomeChar!(typeof(*data))) { foreach (c; stride(rbuffer, 1)) { *data = to!(typeof(*data))(c); break; } } else { *data = (to!(typeof(*data))(rbuffer[0 .. len-1])); } } else { len = -1; } } else { if(isNumeric!(typeof(data)) && white.length) return -1; if (len > 1) { if (isSomeChar!(typeof(data))) { data = to!(typeof(data))(rbuffer[0]); } else { data = (to!(typeof(data))(rbuffer[0 .. len-1])); } } else { len = -1; } } return len; } void main(string[] args) { emit("DMD version to be downloaded: "); string v; scan(v); string link = "https://github.com/downloads/D-Programming-Language/dmd/"; string dmd = "dmd." ~ v ~ ".zip"; string curl = "curl -L -o '" ~ dmd ~ "' '" ~ link ~ dmd ~ "'"; //curl.writeln; emitln("Downloading... ", dmd); system(curl); emitln("Preparing installation! ", ); system("unzip " ~ dmd); system("rm -r dmd2/freebsd"); system("rm -r dmd2/linux"); system("rm -r dmd2/windows"); system("mv dmd2/osx/bin dmd2/"); system("mv dmd2/osx/lib dmd2/"); system("rm -r dmd2/osx"); system("rm dmd2/bin/dmd.conf"); system("rm " ~ dmd); int fd = open("dmd2/bin/dmd.conf", O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); scope(exit) assert(close(fd) >= 0); if (fd >= 0) { save(fd, "[Environment]", nl, nl); save(fd, "DFLAGS=-I% P%/../src/phobos -I% P%/../src/druntime/import -L-L% P%/../lib", nl); } else { emit("Error opening file."); } system("sudo rm -r /usr/share/dmd2"); system("sudo mv dmd2 /usr/share/"); }
Nov 04 2012