YAP 7.1.0
readutil.c
1/*************************************************************************
2* *
3* YAP Prolog *
4* *
5* Yap Prolog was developed at NCCUP - Universidade do Porto *
6* *
7* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8* *
9**************************************************************************
10* *
11* File: readutil.c *
12* Last rev: 2/8/06 *
13* mods: *
14* comments: readutil library support *
15* *
16*************************************************************************/
17#ifdef SCCS
18static char SccsId[] = "%W% %G%";
19#endif
20
21#include "Yap.h"
22#include "YapHeap.h"
23#include "YapText.h"
24#include "Yatom.h"
25#include "YapEncoding.h"
26#include "iopreds.h"
27#include "yapio.h"
28
36static Int rl_to_codes(Term TEnd, int do_as_binary, int end USES_REGS) {
37 int sno = Yap_CheckStream(ARG1, Input_Stream_f, "read_line_to_codes/2");
38 StreamDesc *st = GLOBAL_Stream + sno;
39 Int status;
40 size_t buf_sz, sz;
41 unsigned char *buf;
42 bool binary_stream;
43 utf8proc_int32_t ch;
44
45 if (sno < 0)
46 return false;
47 status = GLOBAL_Stream[sno].status;
48 binary_stream = GLOBAL_Stream[sno].status & Binary_Stream_f;
49 if (status & Eof_Stream_f) {
50 UNLOCK(GLOBAL_Stream[sno].streamlock);
51 return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof));
52 }
53 buf = Malloc(4096);
54 buf_sz = 4096;
55 while (true) {
56 if (do_as_binary && !binary_stream) {
57 GLOBAL_Stream[sno].status |= Binary_Stream_f;
58 }
59 if (st->status & Binary_Stream_f) {
60 sz = fread(buf, 1, buf_sz, GLOBAL_Stream[sno].file);
61 } else {
62 unsigned char *pt = buf;
63 do {
64 ch = st->stream_wgetc_for_read(sno);
65 if (ch < 127) {
66
67 if (ch < 0) {
68 break;
69 }
70 *pt++ = ch;
71 } else {
72
73 pt += get_utf8(pt, 4, &ch);
74 if (pt + 4 == buf + buf_sz)
75 break;
76 }
77 } while (ch != '\n');
78 sz = pt - buf;
79 }
80 if (do_as_binary && !binary_stream)
81 GLOBAL_Stream[sno].status &= ~Binary_Stream_f;
82 if (sz == -1 || sz == 0) {
83 if (GLOBAL_Stream[sno].status & Eof_Stream_f) {
84 UNLOCK(GLOBAL_Stream[sno].streamlock);
85 return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof));
86 }
87 UNLOCK(GLOBAL_Stream[sno].streamlock);
88 }
89 if (GLOBAL_Stream[sno].status & Eof_Stream_f || buf[sz - 1] == 10) {
90 /* we're done */
91 if (!(do_as_binary || GLOBAL_Stream[sno].status & Eof_Stream_f)) {
92 UNLOCK(GLOBAL_Stream[sno].streamlock);
93 /* handle CR before NL */
94 if ((Int)sz - 2 >= 0 && buf[sz - 2] == 13)
95 buf[sz - 2] = '\0';
96 else
97 buf[sz - 1] = '\0';
98 } else {
99 UNLOCK(GLOBAL_Stream[sno].streamlock);
100 }
101 return Yap_unify(
102 ARG2, Yap_UTF8ToDiffListOfCodes(buf, TEnd PASS_REGS));
103 }
104
105 }
106}
113static Int read_line_to_codes(USES_REGS1) {
114 return rl_to_codes(TermNil, FALSE, TermNil PASS_REGS);
115}
116
125static Int read_line_to_codes2(USES_REGS1) {
126 return rl_to_codes(TermNil, TRUE, TermNil PASS_REGS);
127}
128
129
138static Int read_line_to_string(USES_REGS1) {
139 int sno = Yap_CheckStream(ARG1, Input_Stream_f, "read_line_to_codes/2");
140 Int status;
141 UInt max_inp, buf_sz;
142 unsigned char *buf;
143 size_t sz;
144 StreamDesc *st = GLOBAL_Stream + sno;
145 utf8proc_int32_t ch;
146
147 if (sno < 0)
148 return false;
149 status = GLOBAL_Stream[sno].status;
150 if (status & Eof_Stream_f) {
151 UNLOCK(GLOBAL_Stream[sno].streamlock);
152 return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof));
153 }
154 max_inp = (ASP - HR) / 2 - 1024;
155 buf = (unsigned char *)TR;
156 buf_sz = (unsigned char *)LOCAL_TrailTop - buf;
157
158 if (buf_sz > max_inp) {
159 buf_sz = max_inp;
160 }
161 if (st->status & Binary_Stream_f) {
162 char *b = (char *)TR;
163 sz = fread(b, 1, buf_sz, GLOBAL_Stream[sno].file);
164 } else {
165 unsigned char *pt = buf;
166 do {
167 ch = st->stream_wgetc_for_read(sno);
168 if (ch < 127) {
169 if (ch < 0) {
170 break;
171 }
172 *pt++ = ch;
173 } else {
174 pt += get_utf8(pt, 4, &ch);
175 if (pt + 4 == buf + buf_sz)
176 break;
177 }
178 } while (ch != '\n');
179 sz = pt - buf;
180 }
181 if (sz == -1 || sz == 0) {
182 if (GLOBAL_Stream[sno].status & Eof_Stream_f) {
183 UNLOCK(GLOBAL_Stream[sno].streamlock);
184 return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof));
185 }
186 UNLOCK(GLOBAL_Stream[sno].streamlock);
187 return false;
188 }
189 if (GLOBAL_Stream[sno].status & Eof_Stream_f || buf[sz - 1] == 10) {
190 /* we're done */
191
192 if (!(GLOBAL_Stream[sno].status & Eof_Stream_f)) {
193 UNLOCK(GLOBAL_Stream[sno].streamlock);
194 /* handle CR before NL */
195 if ((Int)sz - 2 >= 0 && buf[sz - 2] == 13)
196 buf[sz - 2] = '\0';
197 else {
198 buf[sz - 1] = '\0';
199 }
200 } else {
201 UNLOCK(GLOBAL_Stream[sno].streamlock);
202 }
203 }
204 if (GLOBAL_Stream[sno].encoding == ENC_ISO_UTF8) {
205 return Yap_unify(ARG2, Yap_UTF8ToString((const char *)TR PASS_REGS));
206 } else if (GLOBAL_Stream[sno].encoding == ENC_WCHAR) {
207 return Yap_unify(ARG2, Yap_WCharsToString((const wchar_t *)TR PASS_REGS));
208 } else {
209 return Yap_unify(
210 ARG2, Yap_CharsToString((const char *)TR, ENC_ISO_LATIN1 PASS_REGS));
211 }
212 buf += (buf_sz - 1);
213 max_inp -= (buf_sz - 1);
214 if (max_inp <= 0) {
215 UNLOCK(GLOBAL_Stream[sno].streamlock);
216 Yap_Error(RESOURCE_ERROR_STACK, ARG1, NULL);
217 return FALSE;
218 }
219}
220
229static Int read_stream_to_codes(USES_REGS1) {
230 int sno = Yap_CheckStream(ARG1, Input_Stream_f,
231 "reaMkAtomTerm (AtomEofd_line_to_codes/2");
232 CELL *HBASE = HR;
233 CELL *h0 = &ARG4;
234
235 if (sno < 0)
236 return FALSE;
237 while (!(GLOBAL_Stream[sno].status & Eof_Stream_f)) {
238 /* skip errors */
239 Int ch = GLOBAL_Stream[sno].stream_getc(sno);
240 Term t;
241 if (ch == EOFCHAR)
242 break;
243 t = MkIntegerTerm(ch);
244 h0[0] = AbsPair(HR);
245 *HR = t;
246 HR += 2;
247 h0 = HR - 1;
248 yhandle_t news, news1, st = Yap_StartSlots();
249 if (HR >= ASP - 1024) {
250 RESET_VARIABLE(h0);
251 news = Yap_InitSlot(AbsPair(HBASE));
252 news1 = Yap_InitSlot((CELL)(h0));
253 if (!Yap_dogc(PASS_REGS1)) {
254 Yap_Error(RESOURCE_ERROR_STACK, ARG1, "read_stream_to_codes/3");
255 return false;
256 }
257 /* build a legal term again */
258 h0 = (CELL *)(Yap_GetFromSlot(news1));
259 HBASE = RepPair(Yap_GetFromSlot(news));
260 }
261 Yap_CloseSlots(st);
262 }
263 UNLOCK(GLOBAL_Stream[sno].streamlock);
264 if (HR == HBASE)
265 return Yap_unify(ARG2, ARG3);
266 RESET_VARIABLE(HR - 1);
267 Yap_unify(HR[-1], ARG3);
268 return Yap_unify(AbsPair(HBASE), ARG2);
269}
270
271
280static Int read_stream_to_terms(USES_REGS1) {
281 int sno = Yap_CheckStream(ARG1, Input_Stream_f, "read_line_to_codes/2");
282 Term t, r;
283 yhandle_t hdl, hd3, od;
284
285 if (sno < 0)
286 return FALSE;
287
288 hd3 = Yap_InitSlot((ARG3));
289 Term td = TermDec10;
290 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorSyntaxErrors,1,&td),TermNil);
291 od = Yap_InitSlot(opts);
292 hdl = Yap_InitSlot(ARG2);
293 while (!(GLOBAL_Stream[sno].status & Eof_Stream_f)) {
294 r = Yap_read_term(sno, opts, 2);
295 ;
296 Yap_DebugPlWriteln(r);
297 // just ignore failure
298 t = Deref(Yap_GetFromHandle(hdl));
299 if (Deref(r) == TermEOfCode) {
300 break;
301 } else {
302
303 if (IsVarTerm(t)) {
304 Yap_unify(t, Yap_MkNewPairTerm());
305 t = Deref(t);
306 } else if (!IsPairTerm(t))
307 return false;
308 Term h = HeadOfTerm(t);
309 if (!Yap_unify(h,r))
310 return false;
311 Yap_DebugPlWriteln(t);
312 Yap_PutInHandle(hdl,TailOfTerm(t));
313 }
314 }
315 UNLOCK(GLOBAL_Stream[sno].streamlock);
316 return Yap_unify( Yap_GetFromHandle(hdl), Yap_GetFromHandle(hd3));
317}
318
319void Yap_InitReadUtil(void) {
320 CACHE_REGS
321
322 Term cm = CurrentModule;
323 CurrentModule = READUTIL_MODULE;
324 Yap_InitCPred("read_line_to_string", 2, read_line_to_string, SyncPredFlag);
325 Yap_InitCPred("read_line_to_codes", 2, read_line_to_codes, SyncPredFlag);
326 Yap_InitCPred("read_line_to_codes", 3, read_line_to_codes2, SyncPredFlag);
327 Yap_InitCPred("read_stream_to_codes", 3, read_stream_to_codes, SyncPredFlag);
328 Yap_InitCPred("read_stream_to_terms", 3, read_stream_to_terms, SyncPredFlag);
329 CurrentModule = cm;
330}
331
Main definitions.
void * Malloc(size_t sz USES_REGS)
allocate a temporary text block
Definition: alloc.c:1759
@ encoding
support for coding systens, YAP relies on UTF-8 internally
Definition: YapLFlagInfo.h:83
Term Yap_read_term(int sno, Term opts, bool clause)
generic routine to read terms from a stream
Definition: readterm.c:1324
int(* stream_wgetc_for_read)(int)
direct handle to stream in that space
Definition: YapStreams.h:261