int write_file(char *path, buffer b) { descriptor d = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666); if(d >= 0) { write(d, bref(b, 0), buffer_length(b)); close(d); return 1; } return 0; }
void prf(char *format, ...) { string b = allocate_string(prf_heap); va_list ap; string f = alloca_string(format); va_start(ap, format); vbprintf(b, f, ap); va_end(ap); write(1, bref(b, 0), buffer_length(b)); // deallocate_buffer(b); }
buffer read_file(heap h, char *path) { int d; // consider where this line should be drawn between the // os specific and general parts if ((d = open(path, O_RDONLY)) >= 0) { struct stat k; fstat(d, &k); int bytes = k.st_size; buffer b = allocate_buffer(h, bytes); if (read(d, bref(b,0), bytes) == bytes) { b->end = bytes; return b; } } return 0; }
void vbprintf(string s, string fmt, va_list ap) { character i; int state = 0; int base = 0; int pad; int count = 0; string_foreach(fmt, i) { switch (state){ case 2: for (int j = 0; j < count; j++) string_insert(s, i); state = 0; break; case 0: base = 10; pad = 0; if (i == '%') state = 3; else string_insert(s, i); break; case 1: if ((i >= '0') && (i <= '9')) { pad = pad * 10 + digit_of(i); break; } else { state = 3; } case 3: switch (i) { case '0': state = 1; break; case '%': string_insert(s, '\%'); break; case 't': print_time(s, va_arg(ap, ticks)); break; case 'b': string_concat(s, (va_arg(ap, string))); break; case 'n': count = va_arg(ap, unsigned int); state = 2; break; case 'c': string_insert(s, va_arg(ap, int)); break; case 's': { char *c = va_arg(ap, char *); if (!c) c = (char *)"(null)"; int len = cstring_length(c); for (int i =0 ; i < pad; i++) string_insert(s, ' '); pad = 0; for (; *c; c++) string_insert(s, *c); } break; case 'S': { unsigned int x = va_arg(ap, unsigned int); for (int i =0 ; i < x; i++) string_insert(s, ' '); break; } case 'p': pad = 16; unsigned long x = va_arg(ap, unsigned long); format_number(s, x, 16, pad?pad:1); break; case 'l': pad = 0; unsigned long z = va_arg(ap, unsigned long); format_number(s, z, 10, pad?pad:1); break; case 'x': base=16; case 'o': if (base == 10) base=8; case 'u': { unsigned int x = va_arg(ap, unsigned int); format_number(s, x, base, pad?pad:1); break; } // xxx - layer violation..meh // also generalize string pad support case 'v': if (pad) { // xxx transient or resizable stack head buffer b = allocate_string(s->h); print_value(b, va_arg(ap, void *)); // xxx utf token length for (int i =0 ; i < (pad-buffer_length(b)); i++) string_insert(s, ' '); buffer_append(s, bref(b, 0), buffer_length(b)); pad = 0; state = 0; } else print_value(s, va_arg(ap, void *)); break; case 'r': if (pad) { // xxx transient or resizable stack head buffer b = allocate_string(s->h); print_value_raw(b, va_arg(ap, void *)); // xxx utf token length for (int i =0 ; i < (pad-buffer_length(b)); i++) string_insert(s, ' '); buffer_append(s, bref(b, 0), buffer_length(b)); pad = 0; state = 0; } else print_value_raw(s, va_arg(ap, void *)); break; case 'V': print_value_vector(s, va_arg(ap, void *)); break; case 'X': // xxx - utf8 will break this { buffer xx = va_arg(ap, buffer); string_foreach(xx, i){ print_byte(s, i); } } break; case 'd': case 'i': { int x = va_arg(ap, int); if (x <0){ string_insert(s, '-'); x = -x; } format_number(s, (unsigned int)x, base, pad?pad:1); break; } default: break; } // badness if (state == 3) state = 0; break; } }