var Library = {
// stdio.h
printf: function() {
__print__(Pointer_stringify(__formatString.apply(null, arguments)));
},
fprintf: function() {
var file = arguments[0]; // TODO: something clever with this
var args = Array.prototype.slice.call(arguments, 1);
__print__(Pointer_stringify(__formatString.apply(null, args)));
},
sprintf: function() {
var str = arguments[0];
var args = Array.prototype.slice.call(arguments, 1);
_strcpy(str, __formatString.apply(null, args)); // not terribly efficient
},
fflush: function(file) {
__print__(null);
},
puts: function(p) {
__print__(Pointer_stringify(p) + '\n');
},
fputs: function(p, stream) {
__print__(Pointer_stringify(p) + '\n');
},
fputc: function(chr, stream) {
__print__(String.fromCharCode(chr));
},
putchar: function(p) {
__print__(String.fromCharCode(p));
},
_ZNSo3putEc: 'putchar',
fopen: function(filename, mode) {
return 1; // XXX
},
__01fopen64_: 'fopen',
getc: function(file) {
return -1; // EOF
},
getc_unlocked: 'getc',
_IO_getc: 'getc',
ungetc: function(chr, stream) {
return chr;
},
feof: function(stream) {
return 1;
},
ferror: function(stream) {
return 0;
},
fwrite: function(ptr, size, count, stream) {
__print__(intArrayToString(Array_copy(ptr, count)));
return count;
},
fclose: function(stream) {
return 0;
},
_ZNSo5flushEv: function() {
__print__('\n');
},
vsnprintf: function(dst, num, src, ptr) {
var text = __formatString(-src, ptr); // |-|src tells formatstring to use C-style params (typically they are from varargs)
var i;
for (i = 0; i < num; i++) {
IHEAP[dst+i] = IHEAP[text+i];
if (IHEAP[dst+i] == 0) break;
}
return i; // Actually, should return how many *would* have been written, if the |num| had not stopped us.
},
fileno: function(file) {
return 1; // XXX
},
isatty: function(file) {
return 0; // XXX
},
clearerr: function(stream) {
},
flockfile: function(file) {
},
funlockfile: function(file) {
},
// stdlib.h
abs: 'Math.abs',
atexit: function(func) {
__ATEXIT__.push(func);
},
__cxa_atexit: 'atexit',
abort: function(code) {
ABORT = true;
throw 'ABORT: ' + code + ', at ' + (new Error().stack);
},
realloc: function(ptr, size) {
// Very simple, inefficient implementation - if you use a real malloc, best to use
// a real realloc with it
if (!size) {
if (ptr) _free(ptr);
return 0;
}
var ret = _malloc(size);
if (ptr) {
_memcpy(ret, ptr, size); // might be some invalid reads
_free(ptr);
}
return ret;
},
getenv: function(name_) {
return 0; // TODO
},
strtod__deps: ['isspace', 'isdigit'],
strtod: function(str, endptr) {
// XXX handles only whitespace + |[0-9]+(.[0.9]+)?|, no e+
while (_isspace(str)) str++;
var chr;
var ret = 0;
while(1) {
chr = IHEAP[str];
if (!_isdigit(chr)) break;
ret = ret*10 + chr - '0'.charCodeAt(0);
str++;
}
if (IHEAP[str] == '.'.charCodeAt(0)) {
str++;
var mul=1/10;
while(1) {
chr = IHEAP[str];
if (!_isdigit(chr)) break;
ret += mul*(chr - '0'.charCodeAt(0));
mul /= 10;
str++;
}
}
if (endptr) {
IHEAP[endptr] = str;
#if SAFE_HEAP
SAFE_HEAP_ACCESS(endptr, null, true);
#endif
}
return ret;
},
qsort: function(base, num, size, comparator) {
// forward calls to the JavaScript sort method
// first, sort the items logically
comparator = FUNCTION_TABLE[comparator];
var keys = [];
for (var i = 0; i < num; i++) keys.push(i);
keys.sort(function(a, b) {
return comparator(base+a*size, base+b*size);
});
// apply the sort
var temp = _malloc(num*size);
_memcpy(temp, base, num*size);
for (var i = 0; i < num; i++