annotate src/ploki/IO.c @ 8065:591b1467ccdf

<int-e> le/rn paste/"Paste" is a short story by Henry James. Its contents has been cut into pieces and distributed over numerous tin boxes on the World Wide Web, little pearls of wisdom buried among ordinary pastes.
author HackBot
date Sun, 15 May 2016 13:14:57 +0000
parents ac0403686959
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4223
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
1 #include "config.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
2 #include "IO.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
3 #include "Str.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
4 #include "main.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
5 #include "main_io.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
6 #include "xmalloc.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
7 #include "zz.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
8
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
9 #include <errno.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
10 #include <stdio.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
11 #include <string.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
12 #include <assert.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
13
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
14 struct IO {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
15 struct IO *prev, *next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
16 enum io_flags mode;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
17 FILE *fp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
18 char *name;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
19 size_t refs;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
20 String *buf;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
21 long told;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
22 enum {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
23 DI_NONE,
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
24 DI_RD,
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
25 DI_WR
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
26 } dirct;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
27 };
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
28
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
29 static IO *Root;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
30
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
31 static void sanitycheck(enum io_flags m) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
32 #if !DEBUG_P
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
33 (void)m;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
34 #endif
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
35 assert(
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
36 (
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
37 m & IO_READ ||
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
38 m & IO_WRITE ||
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
39 m & IO_APPEND
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
40 ) &&
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
41 !(
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
42 m & IO_WRITE &&
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
43 m & IO_APPEND
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
44 ) &&
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
45 (
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
46 !(m & IO_BUFFERED) || m & IO_READ
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
47 ) &&
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
48 (
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
49 !(m & IO_AUTOFLUSH) ||
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
50 (
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
51 m & IO_WRITE ||
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
52 m & IO_APPEND
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
53 )
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
54 ) &&
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
55 (
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
56 !(m & IO_WRITE) || (m & IO_TRUNCATE || m & IO_READ)
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
57 ) &&
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
58 (
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
59 !(m & IO_TRUNCATE) || m & IO_WRITE
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
60 )
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
61 );
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
62 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
63
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
64 void io_init(void) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
65 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
66
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
67 static void io_delete(IO *io) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
68 if (io->mode & IO_BUFFERED) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
69 St_clear(io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
70 xfree(io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
71 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
72 if (io->fp && io->fp != stderr) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
73 if (fclose(io->fp)) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
74 fprintf(io_fp(Err), "%s: %s: %s\n", Prog, io->name, strerror(errno));
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
75 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
76 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
77 xfree(io->name);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
78 if (io->prev) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
79 io->prev->next = io->next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
80 } else {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
81 assert(io == Root);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
82 Root = io->next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
83 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
84 if (io->next) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
85 io->next->prev = io->prev;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
86 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
87 xfree(io);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
88 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
89
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
90 void io_end(void) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
91 while (Root) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
92 io_delete(Root);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
93 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
94 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
95
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
96 static char *xstrdup(const char *s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
97 const size_t len = strlen(s) + 1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
98 char *const tmp = xmalloc(len, sizeof *tmp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
99 memcpy(tmp, s, len);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
100 return tmp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
101 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
102
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
103 IO *io_enter(const char *name, FILE *fp, enum io_flags mode) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
104 IO *io;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
105 sanitycheck(mode);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
106 io = xmalloc(1, sizeof *io);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
107 io->fp = fp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
108 io->mode = mode;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
109 if (mode & IO_BUFFERED) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
110 io->buf = xmalloc(1, sizeof *io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
111 St_init(io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
112 io->told = -1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
113 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
114 io->name = xstrdup(name);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
115 io->refs = 1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
116
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
117 io->dirct = DI_NONE;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
118
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
119 io->prev = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
120 io->next = Root;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
121 if (Root) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
122 Root->prev = io;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
123 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
124 Root = io;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
125 return io;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
126 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
127
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
128 const char *io_name(const IO *io, String *s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
129 if (s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
130 St_cpy_s(s, io->name);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
131 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
132 return io->name;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
133 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
134
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
135 IO *io_open(const char *name, enum io_flags mode) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
136 FILE *fp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
137 char mbuf[4], *p = mbuf;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
138 sanitycheck(mode);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
139
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
140 if (mode & IO_APPEND) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
141 *p++ = 'a';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
142 if (mode & IO_READ) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
143 *p++ = '+';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
144 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
145 } else if (mode & IO_WRITE) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
146 if (mode & IO_TRUNCATE) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
147 *p++ = 'w';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
148 if (mode & IO_READ) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
149 *p++ = '+';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
150 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
151 } else {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
152 assert(mode & IO_READ);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
153 *p++ = 'r';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
154 *p++ = '+';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
155 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
156 } else {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
157 assert(mode & IO_READ);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
158 *p++ = 'r';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
159 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
160
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
161 if (mode & IO_BINARY) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
162 *p++ = 'b';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
163 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
164 *p = '\0';
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
165
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
166 if (!(fp = fopen(name, mbuf))) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
167 return NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
168 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
169 return io_enter(name, fp, mode);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
170 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
171
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
172 IO *io_incr(IO *io) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
173 ++io->refs;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
174 return io;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
175 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
176
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
177 void io_decr(IO *io) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
178 if (!--io->refs) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
179 io_delete(io);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
180 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
181 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
182
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
183 int io_close(IO *io) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
184 int ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
185 assert(io->fp != NULL);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
186 ret = fclose(io->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
187 io->fp = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
188 if (io->mode & IO_BUFFERED) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
189 St_clear(io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
190 xfree(io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
191 io->mode &= ~IO_BUFFERED;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
192 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
193 return ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
194 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
195
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
196 int io_bufred(const IO *io) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
197 return !!(io->mode & IO_BUFFERED);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
198 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
199
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
200 void io_unbuffer(IO *io) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
201 assert(io->mode & IO_BUFFERED);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
202 if (St_len(io->buf) && io->told != -1) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
203 io_seek(io, io->told, SEEK_SET);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
204 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
205 St_clear(io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
206 xfree(io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
207 io->mode &= ~IO_BUFFERED;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
208 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
209
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
210 FILE *io_fp(const IO *io) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
211 return io->fp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
212 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
213
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
214 static void bufk(IO *f, size_t n) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
215 String tmp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
216 assert(f->mode & IO_BUFFERED);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
217
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
218 if (St_len(f->buf) >= n || feof(f->fp) || ferror(f->fp)) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
219 return;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
220 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
221
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
222 assert(f->dirct != DI_WR);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
223 #if 0
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
224 if (f->dirct == DI_WR) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
225 io_seek(f, 0, SEEK_CUR);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
226 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
227 f->dirct = DI_RD;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
228 #endif
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
229
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
230 if (!(St_len(f->buf) || f->mode & IO_BINARY)) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
231 f->told = ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
232 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
233
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
234 St_init(&tmp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
235 while (
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
236 St_len(f->buf) < n &&
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
237 !feof(f->fp) && !ferror(f->fp) &&
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
238 St_read(&tmp, f->fp, n - St_len(f->buf))
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
239 ) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
240 St_cat(f->buf, &tmp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
241 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
242 St_clear(&tmp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
243 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
244
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
245 #ifdef EBADF
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
246 #define BADF ((void)(errno = EBADF))
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
247 #else
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
248 #define BADF ((void)0)
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
249 #endif
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
250
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
251 #define XMODE(c, x) \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
252 do { \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
253 if (!(c)) { \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
254 BADF; \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
255 return (x); \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
256 } \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
257 } while (0)
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
258
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
259 #define WMODE(f, x) XMODE((f)->mode & IO_WRITE || (f)->mode & IO_APPEND, (x))
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
260 #define PMODE(f, x) XMODE((f)->mode & IO_BUFFERED, (x))
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
261 #define RMODE(f, x) XMODE((f)->mode & IO_READ, (x))
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
262
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
263 const char *io_bufptr(IO *io) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
264 PMODE(io, NULL);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
265 return St_ptr(io->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
266 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
267
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
268 int io_flush(IO *f) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
269 WMODE(f, EOF);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
270 return fflush(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
271 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
272
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
273 int io_err(const IO *f) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
274 return ferror(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
275 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
276
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
277 int io_eof(const IO *f) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
278 return feof(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
279 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
280
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
281 int io_peek(IO *f, size_t pos) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
282 PMODE(f, EOF);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
283 bufk(f, pos + 1);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
284 if (St_len(f->buf) <= pos) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
285 return EOF;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
286 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
287 return ST_INDEX(f->buf, pos);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
288 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
289
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
290 int io_cmppeek(IO *f, size_t o, const void *p, size_t n) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
291 size_t i;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
292 PMODE(f, -1);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
293
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
294 for (i = 0; i < n; ++i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
295 bufk(f, o + i + 1u);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
296 if (ST_INDEX(f->buf, o + i) != i[(const unsigned char *)p]) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
297 return 1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
298 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
299 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
300 return 0;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
301 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
302
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
303 int io_xcmp(IO *f, size_t a, size_t b, size_t n) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
304 const size_t max = a > b ? a : b;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
305 PMODE(f, -1);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
306 bufk(f, max + n);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
307 if (St_len(f->buf) < max + n) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
308 return 1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
309 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
310 return memcmp(St_ptr(f->buf) + a, St_ptr(f->buf) + b, n) != 0;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
311 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
312
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
313 size_t io_read(IO *f, String *s, size_t n) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
314 RMODE(f, -1);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
315
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
316 if (f->mode & IO_BUFFERED) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
317 String null;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
318 size_t old;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
319
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
320 bufk(f, n);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
321 old = St_len(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
322 St_init(&null);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
323 St_substr(s, f->buf, 0, n, &null);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
324 St_clear(&null);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
325 old -= St_len(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
326 if (St_len(f->buf) && old && !(f->mode & IO_BINARY) && f->told != -1) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
327 const long keep = ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
328 if (fseek(f->fp, f->told, SEEK_SET) != -1) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
329 size_t i;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
330 for (i = 0; i < old; ++i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
331 getc(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
332 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
333 f->told = ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
334 f->dirct = DI_RD;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
335 fseek(f->fp, keep, SEEK_SET);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
336 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
337 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
338 return old;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
339 } else {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
340 if (f->dirct == DI_WR) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
341 fseek(f->fp, 0, SEEK_CUR);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
342 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
343 f->dirct = DI_RD;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
344 return St_read(s, f->fp, n);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
345 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
346 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
347
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
348 int io_getc(IO *f) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
349 RMODE(f, EOF);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
350
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
351 if (f->mode & IO_BUFFERED) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
352 int c;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
353 bufk(f, 1);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
354 c = St_shift(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
355 if (St_len(f->buf) && c != EOF && !(f->mode & IO_BINARY) && f->told != -1) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
356 const long keep = ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
357 if (fseek(f->fp, f->told, SEEK_SET) != -1) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
358 getc(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
359 f->told = ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
360 f->dirct = DI_RD;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
361 fseek(f->fp, keep, SEEK_SET);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
362 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
363 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
364 return c;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
365 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
366
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
367 if (f->dirct == DI_WR) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
368 fseek(f->fp, 0, SEEK_CUR);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
369 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
370 f->dirct = DI_RD;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
371 return getc(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
372 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
373
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
374 size_t io_getline(IO *f, String *s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
375 RMODE(f, -1);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
376
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
377 if (f->mode & IO_BUFFERED) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
378 size_t p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
379 size_t old;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
380
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
381 p = St_chr(f->buf, '\n') + 1u;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
382 if (p) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
383 old = St_len(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
384 if (s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
385 St_cpy_m(s, St_ptr(f->buf), p);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
386 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
387 St_del(f->buf, 0, p);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
388 } else {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
389 for (p = St_len(f->buf); io_peek(f, p) != EOF; ++p) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
390 if (ST_LASTCHAR(f->buf) == '\n') {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
391 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
392 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
393 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
394 old = St_len(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
395 if (s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
396 St_cpy(s, f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
397 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
398 St_zero(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
399 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
400 old -= St_len(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
401 if (St_len(f->buf) && old && !(f->mode & IO_BINARY) && f->told != -1) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
402 const long keep = ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
403 if (fseek(f->fp, f->told, SEEK_SET) != -1) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
404 size_t i;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
405 for (i = 0; i < old; ++i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
406 getc(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
407 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
408 f->dirct = DI_RD;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
409 f->told = ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
410 fseek(f->fp, keep, SEEK_SET);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
411 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
412 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
413 return old;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
414 } else {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
415 int c;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
416 size_t n;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
417
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
418 if (f->dirct == DI_WR) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
419 fseek(f->fp, 0, SEEK_CUR);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
420 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
421 f->dirct = DI_RD;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
422
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
423 if (s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
424 St_zero(s);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
425 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
426 n = 0;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
427 while ((c = getc(f->fp)) != EOF) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
428 if (s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
429 St_cat_c(s, c);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
430 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
431 ++n;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
432 if (c == '\n') {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
433 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
434 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
435 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
436 if (!n && ferror(f->fp)) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
437 return -1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
438 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
439 return n;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
440 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
441 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
442
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
443 size_t io_write(IO *f, const String *s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
444 size_t ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
445 WMODE(f, -1);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
446 if (f->dirct == DI_RD) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
447 fseek(f->fp, 0, SEEK_CUR);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
448 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
449 f->dirct = DI_WR;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
450 ret = ST_WRITE(s, f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
451 if (f->mode & IO_AUTOFLUSH) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
452 fflush(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
453 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
454 return ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
455 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
456
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
457 size_t io_write_m(IO *f, const void *p, size_t n) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
458 size_t ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
459 WMODE(f, -1);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
460 if (f->dirct == DI_RD) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
461 fseek(f->fp, 0, SEEK_CUR);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
462 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
463 f->dirct = DI_WR;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
464 ret = fwrite(p, 1, n, f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
465 if (f->mode & IO_AUTOFLUSH) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
466 fflush(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
467 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
468 return ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
469 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
470
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
471 size_t io_write_s(IO *f, const char *s) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
472 return io_write_m(f, s, strlen(s));
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
473 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
474
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
475 int io_putc(IO *f, int c) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
476 int ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
477 WMODE(f, EOF);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
478 if (f->dirct == DI_RD) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
479 fseek(f->fp, 0, SEEK_CUR);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
480 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
481 f->dirct = DI_WR;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
482 ret = putc(c, f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
483 if (f->mode & IO_AUTOFLUSH) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
484 fflush(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
485 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
486 return ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
487 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
488
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
489 long io_tell(IO *f) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
490 if (f->mode & IO_BUFFERED) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
491 if (f->mode & IO_BINARY) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
492 const long ret = ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
493 if (ret == -1) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
494 return ret;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
495 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
496 return ret - St_len(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
497 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
498 if (St_len(f->buf)) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
499 return f->told;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
500 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
501 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
502 return ftell(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
503 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
504
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
505 int io_seek(IO *f, long off, enum io_whence w) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
506 if (f->mode & IO_BUFFERED) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
507 St_zero(f->buf);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
508 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
509 f->dirct = DI_NONE;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
510 return fseek(f->fp, off, w);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
511 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
512
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
513 void io_clearerr(IO *f) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
514 clearerr(f->fp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
515 }