diff options
Diffstat (limited to 'libraries/base/jsbits/base.js')
-rw-r--r-- | libraries/base/jsbits/base.js | 839 |
1 files changed, 839 insertions, 0 deletions
diff --git a/libraries/base/jsbits/base.js b/libraries/base/jsbits/base.js new file mode 100644 index 0000000000..dd491bac00 --- /dev/null +++ b/libraries/base/jsbits/base.js @@ -0,0 +1,839 @@ +//#OPTIONS: CPP +#include "HsBaseConfig.h" + +// #define GHCJS_TRACE_IO 1 + +#ifdef GHCJS_TRACE_IO +function h$logIO() { h$log.apply(h$log, arguments); } +#define TRACE_IO(args...) h$logIO(args) +#else +#define TRACE_IO(args...) +#endif + +function h$base_access(file, file_off, mode, c) { + TRACE_IO("base_access") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.stat(fd, function(err, fs) { + if(err) { + h$handleErrnoC(err, -1, 0, c); + } else { + c(mode & fs.mode); // fixme is this ok? + } + }); + } else +#endif + h$unsupported(-1, c); +} + +function h$base_chmod(file, file_off, mode, c) { + TRACE_IO("base_chmod") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.chmod(h$decodeUtf8z(file, file_off), mode, function(err) { + h$handleErrnoC(err, -1, 0, c); + }); + } else +#endif + h$unsupported(-1, c); +} + +function h$base_close(fd, c) { + TRACE_IO("base_close fd: " + fd) + var fdo = h$base_fds[fd]; + if(fdo) { + delete h$base_fds[fd]; + if(--fdo.refs < 1) { + TRACE_IO("base_close: closing underlying fd") + if(fdo.close) { + fdo.close(fd, fdo, c); + } else { + c(0); + } + } else { + TRACE_IO("base_close: remaining references, not closing underlying fd") + c(0); + } + } else { + TRACE_IO("base_close: file descriptor not found, already closed?") + h$errno = CONST_EINVAL; + c(-1); + } +} + +function h$base_dup(fd, c) { + // h$log("h$base_dup al: " + arguments.length); + h$base_dup2(fd, h$base_fdN--, c); +} + +function h$base_dup2(fd, new_fd, c) { + TRACE_IO("base_dup2 " + fd + " " + new_fd) + // if(new_fd >= 0 && new_fd <= 2) { + + // } + // h$log("h$base_dup2 al: " + arguments.length); + // if(fd >= 0 && fd < 2) { + // h$errno = CONST_EINVAL; + // c(-1); + // fixme make sure it can't be called again! + // return; + // } // && new_fd ) + + /* Fixme: + The two descriptors do not share file descriptor flags + (the close-on-exec flag). The close-on-exec flag + (FD_CLOEXEC; see fcntl(2)) for the duplicate descriptor is off. + */ + var fdo = h$base_fds[fd]; + if(!fdo) { + TRACE_IO("file descriptor not found") + h$errno = CONST_EINVAL; + c(-1); + } else { + var new_fdo = h$base_fds[new_fd]; + function f() { + h$base_fds[new_fd] = fdo; + fdo.refs++; + c(new_fd); + } + if(new_fdo) { + TRACE_IO("closing existing fd") + h$base_close(new_fd, f); + } else { + f(); + } // h$new_fdo.close(); + } +} + +function h$base_fstat(fd, stat, stat_off, c) { + TRACE_IO("base_stat") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.fstat(fd, function(err, fs) { + if(err) { + h$handleErrnoC(err, -1, 0, c); + } else { + h$base_fillStat(fs, stat, stat_off); + c(0); + } + }); + } else +#endif + h$unsupported(-1, c); +} + +function h$base_isatty(fd) { + TRACE_IO("base_isatty " + fd) + // return 1; // fixme debug + var fdo = h$base_fds[fd]; + if(fdo && typeof fdo.isatty !== 'undefined') { + if(typeof fdo.isatty === 'function') return fdo.isatty() ? 1 : 0; + return fdo.isatty ? 1 : 0; + } + return 0; +} + + +#define TWO_PWR_32_DBL_ 0x100000000 +#define TWO_PWR_63_DBL_ 0x8000000000000000 +#define CLOSEST_FLOAT_NUMBER(h,l) (((h)*TWO_PWR_32_DBL_) + ((l)>>>0)) + +/** + * Returns a 64-bit represention of the given number. + * NaN will be returned as zero. + * Infinity is converted to max value and + * -Infinity to min value. + * @param {f} The number in question. + * @param {c} the continuation taking high and low bits + */ +function h$long_from_number(f,c) { + if (f > 0) { + if (f >= TWO_PWR_63_DBL_) { + // return max value + return c(0x7FFFFFFF,0xFFFFFFFF); + } + return c(f / TWO_PWR_32_DBL_, f); + } else if (f < 0) { + if (f <= -TWO_PWR_63_DBL_) { + // return min value + return c(0x80000000,0); + } + var h = -f / TWO_PWR_32_DBL_; + var l = -f; + // negate h l + var nl = (~l + 1) | 0; + var nh = (~h + !nl) | 0; + return c(nh,nl); + } else { + // NaN or 0. + return c(0,0); + } +} + +function h$base_lseek(fd, pos_h, pos_l, whence, c) { + TRACE_IO("base_lseek") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + var p = CLOSEST_FLOAT_NUMBER(pos_h,pos_l); + var o = h$base_fds[fd]; + if(!o) { + h$errno = CONST_BADF; + c(-1,-1); + } else { + switch(whence) { + case 0: /* SET */ + o.pos = p; + c(pos_h, pos_l); + break; + case 1: /* CUR */ + o.pos += p; + h$long_from_number(o.pos,c); + break; + case 2: /* END */ + h$fs.fstat(fd, function(err, fs) { + if(err) { + h$setErrno(err); + c(-1,-1); + } else { + o.pos = fs.size + p; + h$long_from_number(o.pos,c); + } + }); + break; + default: + h$errno = CONST_EINVAL; + c(-1,-1); + } + } + } else { +#endif + h$unsupported(); + c(-1, -1); +#ifndef GHCJS_BROWSER + } +#endif +} + +function h$base_lstat(file, file_off, stat, stat_off, c) { + TRACE_IO("base_lstat") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.lstat(h$decodeUtf8z(file, file_off), function(err, fs) { + if(err) { + h$handleErrnoC(err, -1, 0, c); + } else { + h$base_fillStat(fs, stat, stat_off); + c(0); + } + }); + } else +#endif + h$unsupported(-1, c); +} +function h$base_open(file, file_off, how, mode, c) { +#ifndef GHCJS_BROWSER + if(h$isNode()) { + var flags, off; + var fp = h$decodeUtf8z(file, file_off); + TRACE_IO("base_open: " + fp) + var acc = how & h$base_o_accmode; + // passing a number lets node.js use it directly as the flags (undocumented) + if(acc === h$base_o_rdonly) { + flags = h$processConstants['fs']['O_RDONLY']; + } else if(acc === h$base_o_wronly) { + flags = h$processConstants['fs']['O_WRONLY']; + } else { // r+w + flags = h$processConstants['fs']['O_RDWR']; + } + off = (how & h$base_o_append) ? -1 : 0; + flags = flags | ((how & h$base_o_trunc) ? h$processConstants['fs']['O_TRUNC'] : 0) + | ((how & h$base_o_creat) ? h$processConstants['fs']['O_CREAT'] : 0) + | ((how & h$base_o_excl) ? h$processConstants['fs']['O_EXCL'] : 0) + | ((how & h$base_o_append) ? h$processConstants['fs']['O_APPEND'] : 0); + h$fs.open(fp, flags, mode, function(err, fd) { + if(err) { + h$handleErrnoC(err, -1, 0, c); + } else { + var f = function(p) { + h$base_fds[fd] = { read: h$base_readFile + , write: h$base_writeFile + , close: h$base_closeFile + , fd: fd + , pos: p + , refs: 1 + }; + TRACE_IO("base_open: " + fp + " -> " + fd) + c(fd); + } + if(off === -1) { + h$fs.stat(fp, function(err, fs) { + if(err) h$handleErrnoC(err, -1, 0, c); else f(fs.size); + }); + } else { + f(0); + } + } + }); + } else +#endif + h$unsupported(-1, c); +} +function h$base_read(fd, buf, buf_off, n, c) { + TRACE_IO("base_read: " + fd) + var fdo = h$base_fds[fd]; + if(fdo && fdo.read) { + fdo.read(fd, fdo, buf, buf_off, n, c); + } else { + h$fs.read(fd, buf.u8, buf_off, n, null, function(err, bytesRead, buf0) { + h$handleErrnoC(err, -1, bytesRead, c); + }); + } +} +function h$base_stat(file, file_off, stat, stat_off, c) { + TRACE_IO("base_stat") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.stat(h$decodeUtf8z(file, file_off), function(err, fs) { + if(err) { + h$handleErrnoC(err, -1, 0, c); + } else { + h$base_fillStat(fs, stat, stat_off); + c(0); + } + }); + } else +#endif + h$unsupported(-1, c); +} +function h$base_umask(mode) { + TRACE_IO("base_umask: " + mode) +#ifndef GHCJS_BROWSER + if(h$isNode()) return process.umask(mode); +#endif + return 0; +} + +function h$base_write(fd, buf, buf_off, n, c) { +// fd: file descriptor number +// buf: buffer to write +// buf_off: offset in the buffer +// n: number of bytes to write +// c: continuation + TRACE_IO("base_write: " + fd) + + var fdo = h$base_fds[fd]; + + if(fdo && fdo.write) { + fdo.write(fd, fdo, buf, buf_off, n, c); + } else { + h$fs.write(fd, buf.u8, buf_off, n, function(err, bytesWritten, buf0) { + h$handleErrnoC(err, -1, bytesWritten, c); + }); + } +} + +function h$base_ftruncate(fd, pos_h, pos_l, c) { + TRACE_IO("base_ftruncate") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.ftruncate(fd, CLOSEST_FLOAT_NUMBER(pos_h,pos_l), function(err) { + h$handleErrnoC(err, -1, 0, c); + }); + } else +#endif + h$unsupported(-1, c); +} +function h$base_unlink(file, file_off, c) { + TRACE_IO("base_unlink") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.unlink(h$decodeUtf8z(file, file_off), function(err) { + h$handleErrnoC(err, -1, 0, c); + }); + } else +#endif + h$unsupported(-1, c); +} +function h$base_getpid() { + TRACE_IO("base_getpid") +#ifndef GHCJS_BROWSER + if(h$isNode()) return process.pid; +#endif + return 0; +} +function h$base_link(file1, file1_off, file2, file2_off, c) { + TRACE_IO("base_link") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.link(h$decodeUtf8z(file1, file1_off), h$decodeUtf8z(file2, file2_off), function(err) { + h$handleErrnoC(err, -1, 0, c); + }); + } else +#endif + h$unsupported(-1, c); +} +function h$base_mkfifo(file, file_off, mode, c) { + throw "h$base_mkfifo"; +} +function h$base_sigemptyset(sigset, sigset_off) { + return 0; + // throw "h$base_sigemptyset"; +} +function h$base_sigaddset(sigset, sigset_off, sig) { + return 0; + // throw "h$base_sigaddset"; +} +function h$base_sigprocmask(sig, sigset1, sigset1_off, sigset2, sigset2_off) { + return 0; + // throw "h$base_sigprocmask"; +} +function h$base_tcgetattr(attr, termios, termios_off) { + return 0; +} +function h$base_tcsetattr(attr, val, termios, termios_off) { + return 0; +} +function h$base_utime(file, file_off, timbuf, timbuf_off, c) { + TRACE_IO("base_utime") +#ifndef GHCJS_BROWSER + if(h$isNode()) { + h$fs.fstat(h$decodeUtf8z(file, file_off), function(err, fs) { + if(err) { + h$handleErrnoC(err, 0, -1, c); // fixme + } else { + h$long_from_number(fs.atime.getTime(), (h,l) => { + timbuf.i3[0] = h; + timbuf.i3[1] = l; + }); + h$long_from_number(fs.mtime.getTime(), (h,l) => { + timbuf.i3[2] = h; + timbuf.i3[3] = l; + }); + h$long_from_number(fs.ctime.getTime(), (h,l) => { + timbuf.i3[4] = h; + timbuf.i3[5] = l; + }); + c(0); + } + }); + } else +#endif + h$unsupported(-1, c); +} +function h$base_waitpid(pid, stat, stat_off, options, c) { + throw "h$base_waitpid"; +} +/** @const */ var h$base_o_rdonly = 0x00000; +/** @const */ var h$base_o_wronly = 0x00001; +/** @const */ var h$base_o_rdwr = 0x00002; +/** @const */ var h$base_o_accmode = 0x00003; +/** @const */ var h$base_o_append = 0x00008; +/** @const */ var h$base_o_creat = 0x00200; +/** @const */ var h$base_o_trunc = 0x00400; +/** @const */ var h$base_o_excl = 0x00800; +/** @const */ var h$base_o_noctty = 0x20000; +/** @const */ var h$base_o_nonblock = 0x00004; +/** @const */ var h$base_o_binary = 0x00000; + +function h$base_c_s_isreg(mode) { + return 1; +} +function h$base_c_s_ischr(mode) { + return 0; +} +function h$base_c_s_isblk(mode) { + return 0; +} +function h$base_c_s_isdir(mode) { + return 0; // fixme +} +function h$base_c_s_isfifo(mode) { + return 0; +} + +#ifndef GHCJS_BROWSER +function h$base_fillStat(fs, b, off) { + if(off%4) throw "h$base_fillStat: not aligned"; + var o = off>>2; + b.i3[o+0] = fs.mode; + h$long_from_number(fs.size, (h,l) => { + b.i3[o+1] = h; + b.i3[o+2] = l; + }); + + b.i3[o+3] = 0; // fixme + b.i3[o+4] = 0; // fixme + b.i3[o+5] = fs.dev; + h$long_from_number(fs.ino, (h,l) => { + b.i3[o+6] = h; + b.i3[o+7] = l; + }); + b.i3[o+8] = fs.uid; + b.i3[o+9] = fs.gid; +} +#endif + +// [mode,size1,size2,mtime1,mtime2,dev,ino1,ino2,uid,gid] all 32 bit +/** @const */ var h$base_sizeof_stat = 40; + +function h$base_st_mtime(stat, stat_off) { + RETURN_UBX_TUP2(stat.i3[(stat_off>>2)+3], stat.i3[(stat_off>>2)+4]); +} + +function h$base_st_size(stat, stat_off) { + RETURN_UBX_TUP2(stat.i3[(stat_off>>2)+1], stat.i3[(stat_off>>2)+2]); +} + +function h$base_st_mode(stat, stat_off) { + return stat.i3[stat_off>>2]; +} + +function h$base_st_dev(stat, stat_off) { + return stat.i3[(stat_off>>2)+5]; +} + +function h$base_st_ino(stat, stat_off) { + RETURN_UBX_TUP2(stat.i3[(stat_off>>2)+6], stat.i3[(stat_off>>2)+7]); +} + +/** @const */ var h$base_echo = 1; +/** @const */ var h$base_tcsanow = 2; +/** @const */ var h$base_icanon = 4; +/** @const */ var h$base_vmin = 8; +/** @const */ var h$base_vtime = 16; +/** @const */ var h$base_sigttou = 0; +/** @const */ var h$base_sig_block = 0; +/** @const */ var h$base_sig_setmask = 0; +/** @const */ var h$base_f_getfl = 0; +/** @const */ var h$base_f_setfl = 0; +/** @const */ var h$base_f_setfd = 0; +/** @const */ var h$base_fd_cloexec = 0; +/** @const */ var h$base_sizeof_termios = 4; +/** @const */ var h$base_sizeof_sigset_t = 4; + +function h$base_lflag(termios, termios_off) { + return 0; +} + +function h$base_poke_lflag(termios, termios_off, flag) { + return 0; +} + +function h$base_ptr_c_cc(termios, termios_off) { + RETURN_UBX_TUP2(h$newByteArray(8), 0); +} + +/** @const */ var h$base_default_buffer_size = 32768; + +function h$base_c_s_issock(mode) { + return 0; // fixme +} + +/** @const */ var h$base_SEEK_SET = 0; +/** @const */ var h$base_SEEK_CUR = 1; +/** @const */ var h$base_SEEK_END = 2; + +function h$base_set_saved_termios(a, b, c) { + RETURN_UBX_TUP2(null, 0); +} + +function h$base_get_saved_termios(r) { + RETURN_UBX_TUP2(null, 0); +} + +// fixme +function h$lockFile(fd, dev, ino, for_writing) { + TRACE_IO("lockFile:" + fd) + return 0; +} +function h$unlockFile(fd) { + TRACE_IO("unlockFile:" + fd) + return 0; +} + + + +// engine-dependent setup +var h$base_readStdin , h$base_writeStderr, h$base_writeStdout; +var h$base_isattyStdin = false, h$base_isattyStdout = false, h$base_isattyStderr = false; +var h$base_closeStdin = null, h$base_closeStderr = null, h$base_closeStdout = null; +var h$base_readFile, h$base_writeFile, h$base_closeFile; +#ifndef GHCJS_BROWSER +var h$base_stdin_waiting = new h$Queue(); +var h$base_stdin_chunk = { buf: null + , pos: 0 + , processing: false + }; +var h$base_stdin_eof = false; +var h$base_process_stdin = function() { + var c = h$base_stdin_chunk; + var q = h$base_stdin_waiting; + if(!q.length() || c.processing) return; + c.processing = true; + if(!c.buf) { c.pos = 0; c.buf = process.stdin.read(); } + while(c.buf && q.length()) { + var x = q.dequeue(); + var n = Math.min(c.buf.length - c.pos, x.n); + for(var i=0;i<n;i++) { + x.buf.u8[i+x.off] = c.buf[c.pos+i]; + } + c.pos += n; + x.c(n); + if(c.pos >= c.buf.length) c.buf = null; + if(!c.buf && q.length()) { c.pos = 0; c.buf = process.stdin.read(); } + } + while(h$base_stdin_eof && q.length()) q.dequeue().c(0); + c.processing = false; +} + +if(h$isNode()) { + h$base_closeFile = function(fd, fdo, c) { + TRACE_IO("base_closeFile: " + fd + " (" + fdo.fd + ")") + var real_fd = typeof fdo.fd === 'number' ? fdo.fd : fd; + h$fs.close(real_fd, function(err) { + delete h$base_fds[fd]; + h$handleErrnoC(err, -1, 0, c); + }); + } + + h$base_readFile = function(fd, fdo, buf, buf_offset, n, c) { + var pos = typeof fdo.pos === 'number' ? fdo.pos : null; + TRACE_IO("base_readFile: " + fd + " (" + fdo.fd + ") " + pos + " " + buf_offset + " " + n) + var real_fd = typeof fdo.fd === 'number' ? fdo.fd : fd; + h$fs.read(real_fd, Buffer.alloc(n), 0, n, pos, function(err, bytesRead, nbuf) { + if(err) { + h$setErrno(err); + c(-1); + } else { + for(var i=bytesRead-1;i>=0;i--) buf.u8[buf_offset+i] = nbuf[i]; + if(typeof fdo.pos === 'number') fdo.pos += bytesRead; + c(bytesRead); + } + }); + } + + h$base_readStdin = function(fd, fdo, buf, buf_offset, n, c) { + TRACE_IO("read stdin") + h$base_stdin_waiting.enqueue({buf: buf, off: buf_offset, n: n, c: c}); + h$base_process_stdin(); + } + + h$base_closeStdin = function(fd, fdo, c) { + TRACE_IO("close stdin") + // process.stdin.close(); fixme + c(0); + } + + h$base_writeFile = function(fd, fdo, buf, buf_offset, n, c) { + var pos = typeof fdo.pos === 'number' ? fdo.pos : null; + TRACE_IO("base_writeFile: " + fd + " (" + fdo.fd + ") " + pos + " " + buf_offset + " " + n) + var nbuf = Buffer.alloc(n); + for(var i=0;i<n;i++) nbuf[i] = buf.u8[i+buf_offset]; + var real_fd = typeof fdo.fd === 'number' ? fdo.fd : fd; + if(typeof fdo.pos === 'number') fdo.pos += n; + h$fs.write(real_fd, nbuf, 0, n, pos, function(err, bytesWritten) { + TRACE_IO("written file: " + fd + " (" + fdo.fd + ")") + if(err) { + h$setErrno(err); + if(typeof fdo.pos === 'number') fdo.pos -= n; + if(h$errno === CONST_EAGAIN) + setTimeout(function() { h$base_writeFile(fd, fdo, buf, buf_offset, n, c); }, 20); + else c(-1); + } else { + if(typeof fdo.pos === 'number') fdo.pos += bytesWritten - n; + c(bytesWritten); + } + }); + } + + h$base_writeStdout = function(fd, fdo, buf, buf_offset, n, c) { + TRACE_IO("write stdout") + h$base_writeFile(1, fdo, buf, buf_offset, n, c); + } + + h$base_closeStdout = function(fd, fdo, c) { + TRACE_IO("close stdout") + // not actually closed, fixme? + c(0); + } + + h$base_writeStderr = function(fd, fdo, buf, buf_offset, n, c) { + TRACE_IO("write stderr") + h$base_writeFile(2, fdo, buf, buf_offset, n, c); + } + + h$base_closeStderr = function(fd, fdo, c) { + TRACE_IO("close stderr") + // not actually closed, fixme? + c(0); + } + + process.stdin.on('readable', h$base_process_stdin); + process.stdin.on('end', function() { h$base_stdin_eof = true; h$base_process_stdin(); }); + + h$base_isattyStdin = function() { return process.stdin.isTTY; }; + h$base_isattyStdout = function() { return process.stdout.isTTY; }; + h$base_isattyStderr = function() { return process.stderr.isTTY; }; + +} else if (h$isJsShell()) { + h$base_readStdin = function(fd, fdo, buf, buf_offset, n, c) { + c(0); + } + h$base_writeStdout = function(fd, fdo, buf, buf_offset, n, c) { + putstr(h$decodeUtf8(buf, n, buf_offset)); + c(n); + } + h$base_writeStderr = function(fd, fdo, buf, buf_offset, n, c) { + printErr(h$decodeUtf8(buf, n, buf_offset)); + c(n); + } +} else if(h$isJsCore()) { + h$base_readStdin = function(fd, fdo, buf, buf_offset, n, c) { + c(0); + } + var h$base_stdoutLeftover = { f: print, val: null }; + var h$base_stderrLeftover = { f: debug, val: null }; + var h$base_writeWithLeftover = function(buf, n, buf_offset, c, lo) { + var lines = h$decodeUtf8(buf, n, buf_offset).split(/\r?\n/); + if(lines.length === 1) { + if(lines[0].length) { + if(lo.val !== null) lo.val += lines[0]; + else lo.val = lines[0]; + } + } else { + lo.f(((lo.val !== null) ? lo.val : '') + lines[0]); + for(var i=1;i<lines.length-1;i++) lo.f(lines[i]); + if(lines[lines.length-1].length) lo.val = lines[lines.length-1]; + else lo.val = null; + } + c(n); + } + h$base_writeStdout = function(fd, fdo, buf, buf_offset, n, c) { + h$base_writeWithLeftover(buf, n, buf_offset, c, h$base_stdoutLeftover); + } + h$base_writeStderr = function(fd, fdo, buf, buf_offset, n, c) { + // writing to stderr not supported, write to stdout + h$base_writeWithLeftover(buf, n, buf_offset, c, h$base_stderrLeftover); + } +} else { // browser / fallback +#endif + h$base_readStdin = function(fd, fdo, buf, buf_offset, n, c) { + c(0); + } + h$base_writeStdout = function(fd, fdo, buf, buf_offset, n, c) { + console.log(h$decodeUtf8(buf, n, buf_offset)); + c(n); + } + h$base_writeStderr = function(fd, fdo, buf, buf_offset, n, c) { + console.log(h$decodeUtf8(buf, n, buf_offset)); + c(n); + } +#ifndef GHCJS_BROWSER +} +#endif + +var h$base_stdin_fd = + { read: h$base_readStdin + , close: h$base_closeStdin + , isatty: h$base_isattyStdin + , refs: 1 + }; +var h$base_stdout_fd = + { write: h$base_writeStdout + , close: h$base_closeStdout + , isatty: h$base_isattyStdout + , refs: 1 + }; +var h$base_stderr_fd = + { write: h$base_writeStderr + , close: h$base_closeStderr + , isatty: h$base_isattyStderr + , refs: 1 + }; + +var h$base_fdN = -2; // negative file descriptors are 'virtual', -1 is already used to indicated error +var h$base_fds = [h$base_stdin_fd, h$base_stdout_fd, h$base_stderr_fd]; + +function h$shutdownHaskellAndExit(code, fast) { +#ifndef GHCJS_BROWSER +#ifdef GHCJS_LOG_BUFFER + if(h$isNode()) console.log(h$logBuffer); + if(h$isJsShell() || h$isJsCore()) print(h$logBuffer); +#endif +#endif + h$exitProcess(code); +} + +// RAND_MAX = 32767 +function h$rand() { + return (32768 * Math.random()) & 32767; +} + +// SIGUSR1, SIGTERM, SIGINT, SIGPIPE, SIGHUP, SIGTERM, SIGINT +// SIGBREAK, SIGWINCH, SIGKILL, SIGSTOP, SIGBUS, SIGFPE +// SIGSEGV, SIGILL + +// returns old action code +function h$stg_sig_install(sigNo, actionCode, sigSet_d, sigSet_o) { + // XXX dummy implementation + return 0; +} + +const h$putchar_buf = h$newByteArray(1); + +function h$putchar(c) { + h$putchar_buf.u8[0] = c; + h$base_write(1, h$putchar_buf, 0, 1, null); + return h$errno; +} + +function h$__hscore_set_errno(n) { + h$errno = n; +} + +/******************************************* + * Directory API + *******************************************/ + +function h$opendir(path) { + if(!h$isNode()) { + throw "h$opendir unsupported"; + } + + const d = fs.opendirSync(h$decodeUtf8z(path,0)); + RETURN_UBX_TUP2(d,0); +} + +function h$closedir(d,o) { + if(!h$isNode()) { + throw "h$closedir unsupported"; + } + d.closeSync(); + return 0; +} + +function h$readdir(d,o) { + if(!h$isNode()) { + throw "h$readdir unsupported"; + } + const c = d.readSync(); + RETURN_UBX_TUP2(c,0); +} + +function h$__hscore_readdir(d,o,dst_a,dst_o) { + if(!h$isNode()) { + throw "h$readdir unsupported"; + } + const e = d.readSync(); + + if (!dst_a.arr) dst_a.arr = []; + dst_a.arr[dst_o*2] = [e,0]; + return 0; +} + +function h$__hscore_free_dirent(a,o) { +} + +function h$__hscore_d_name(a,o) { + RETURN_UBX_TUP2(h$encodeModifiedUtf8(a.name),0); +} |