bufio.om (2996B)
1 struct file { 2 a: *alloc; 3 fd: int; 4 buf: *byte; 5 r: int; 6 w: int; 7 cap: int; 8 eof: int; 9 noflush: int; 10 } 11 12 func fopen(fd: int, a: *alloc): *file { 13 var f: *file; 14 15 f = alloc(a, sizeof(*f)) as *file; 16 17 f.fd = fd; 18 f.a = a; 19 f.r = 0; 20 f.w = 0; 21 f.cap = 4096 * 16; 22 f.eof = 0; 23 24 f.buf = alloc(a, f.cap); 25 26 return f; 27 } 28 29 func fclose(f: *file): void { 30 fflush(f); 31 32 if (close(f.fd) != 0) { 33 die("write failed"); 34 } 35 36 free(f.a, f.buf); 37 38 free(f.a, f as *byte); 39 } 40 41 func fflush(f: *file): void { 42 var ret: int; 43 44 loop { 45 if (f.r == f.w) { 46 f.r = 0; 47 f.w = 0; 48 return; 49 } 50 51 ret = write(f.fd, &f.buf[f.r], f.w - f.r); 52 53 if (ret < 0) { 54 die("write failed"); 55 } 56 57 f.r = f.r + ret; 58 } 59 } 60 61 func ffill(f: *file): void { 62 var ret: int; 63 64 if (f.eof) { 65 return; 66 } 67 68 if (f.r == f.w) { 69 f.r = 0; 70 f.w = 0; 71 } 72 73 if (f.w == f.cap) { 74 die("out of space"); 75 } 76 77 ret = read(f.fd, &f.buf[f.w], f.cap - f.w); 78 79 if (ret < 0) { 80 die("read failed"); 81 } 82 83 if (ret == 0) { 84 f.eof = 1; 85 } 86 87 f.w = f.w + ret; 88 } 89 90 func fputc(f: *file, ch: int): void { 91 var b: byte; 92 93 if !f { 94 b = ch as byte; 95 if write(1, &b, 1) != 1 { 96 exit(3); 97 } 98 return; 99 } 100 101 if (f.w == f.cap) { 102 fflush(f); 103 } 104 105 f.buf[f.w] = ch as byte; 106 f.w = f.w + 1; 107 108 if (ch == '\n' && !f.noflush) { 109 fflush(f); 110 } 111 } 112 113 func fgetc(f: *file): int { 114 var ch: int; 115 116 if (f.r == f.w) { 117 ffill(f); 118 } 119 120 if (f.eof) { 121 return -1; 122 } 123 124 ch = f.buf[f.r] as int; 125 126 f.r = f.r + 1; 127 128 return ch; 129 } 130 131 func fgets(f: *file, buf: *byte, len: int): int { 132 var i: int; 133 var c: int; 134 135 if len == 1 { 136 buf[0] = 0 as byte; 137 return 0; 138 } 139 140 i = 0; 141 loop { 142 if i + 1 == len { 143 buf[i] = 0 as byte; 144 return i; 145 } 146 147 c = fgetc(f); 148 if c == -1 || c == '\n' { 149 buf[i] = 0 as byte; 150 return i; 151 } 152 153 buf[i] = c as byte; 154 i = i + 1; 155 } 156 } 157 158 func fputs(f: *file, s: *byte) { 159 var i: int; 160 i = 0; 161 loop { 162 if !s[i] { 163 break; 164 } 165 fputc(f, s[i] as int); 166 i = i + 1; 167 } 168 } 169 170 func fputb(f: *file, s: *byte, n: int) { 171 var i: int; 172 i = 0; 173 loop { 174 if i >= n { 175 break; 176 } 177 fputc(f, s[i] as int); 178 i = i + 1; 179 } 180 } 181 182 func fputd(out: *file, n: int) { 183 var a: int; 184 185 if (n < 0) { 186 fputc(out, '-'); 187 a = -(n % 10); 188 n = n / -10; 189 } else { 190 a = n % 10; 191 n = n / 10; 192 } 193 194 if (n != 0) { 195 fputd(out, n); 196 } 197 198 fputc(out, '0' + a); 199 } 200 201 func fputh(out: *file, n: int) { 202 var d: int; 203 204 d = n & 15; 205 206 n = n >> 4; 207 208 if n { 209 fputh(out, n); 210 } 211 212 fputc(out, "0123456789abcdef"[d] as int); 213 } 214 215 func fseek(f: *file, off: int) { 216 f.r = 0; 217 f.w = 0; 218 f.eof = 0; 219 if lseek(f.fd, off, 0) != off { 220 die("invalid seek"); 221 } 222 } 223 224 func freadall(f: *file, size: *int): *byte { 225 var i: int; 226 var cap: int; 227 var ret: *byte; 228 var tmp: *byte; 229 var ch: int; 230 231 i = 0; 232 cap = 0; 233 loop { 234 ch = fgetc(f); 235 if ch == -1 { 236 *size = i; 237 return ret; 238 } 239 240 if i == cap { 241 if cap == 0 { 242 cap = 4096; 243 ret = alloc(f.a, cap); 244 } else { 245 cap = cap * 2; 246 tmp = alloc(f.a, cap); 247 memcpy(tmp, ret, i); 248 free(f.a, ret); 249 ret = tmp; 250 } 251 } 252 253 ret[i] = ch as byte; 254 i = i + 1; 255 } 256 }