YAP 7.1.0
charsio.c
Go to the documentation of this file.
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: charcodes.c *
12 * Last rev: 5/2/88 *
13 * mods: *
14 * comments: Character codes and character conversion *
15 * *
16 *************************************************************************/
17#ifdef SCCS
18static char SccsId[] = "%W% %G%";
19#endif
20
48#include "Yap.h"
49#include "YapHeap.h"
50#include "YapText.h"
51#include "Yatom.h"
52#include "yapio.h"
53#include <stdlib.h>
54#if HAVE_UNISTD_H
55#include <unistd.h>
56#endif
57#if HAVE_STDARG_H
58#include <stdarg.h>
59#endif
60#ifdef _WIN32
61#if HAVE_IO_H
62/* Windows */
63#include <io.h>
64#endif
65#if HAVE_SOCKET
66#include <winsock2.h>
67#endif
68#include <windows.h>
69#ifndef S_ISDIR
70#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
71#endif
72#endif
73#include "iopreds.h"
74
75static Int get_code(USES_REGS1);
76static Int get_byte(USES_REGS1);
77// static Int past_eof( USES_REGS1);
78static Int put_code(USES_REGS1);
79static Int put_byte(USES_REGS1);
80static Int skip(USES_REGS1);
81static Int flush_output(USES_REGS1);
82
90 Int CharOfAtom(Atom at) {
91 int32_t val;
92
93 get_utf8(at->UStrOfAE, 1, &val);
94 return val;
95}
96
97
98static int oops_c_from_w(int sno)
99{
100// StreamDesc *s = GLOBAL_Stream + sno;
101 fprintf(stderr, "oops_c_from_w\n" );
102 return 0;
103
104}
105
106 int Yap_popWide(int sno)
107{
108 StreamDesc *s = GLOBAL_Stream + sno;
109 s->buf.on = false;
110 Yap_DefaultStreamOps(s);
111 return s->buf.ch;
112
113}
114
115int Yap_peekWide(int sno) {
116 StreamDesc *s = GLOBAL_Stream + sno;
117 int ch;
118 Int pos = s->charcount;
119 Int line = s->linecount;
120 Int lpos = s->linestart;
121
122
123 if (s->file&&fileno(s->file)>=0) {
124 ch = fgetwc(s->file);
125 if (ch == WEOF) {
126 clearerr(s->file);
127 s->status &= ~Eof_Error_Stream_f;
128 } else {
129 // do not try doing error processing
130 ungetwc(ch, s->file);
131 }
132 }else {
133 ch = s->stream_wgetc(sno);
134 if (ch == EOF) {
135 s->status &= ~Eof_Error_Stream_f;
136 } else if (s->status & Seekable_Stream_f) {
137 Yap_SetCurInpPos(sno, pos);
138 } else {
139 s->buf.on = true;
140 s->buf.ch = ch;
141 s->stream_wgetc = Yap_popWide;
142 s->stream_getc = oops_c_from_w;
143 }
144 }
145 s->charcount = pos;
146 s->linecount = line;
147 s->linestart = lpos;
148 return ch;
149}
150
151
152static int oops_w_from_c(int sno)
153{
154// StreamDesc *s = GLOBAL_Stream + sno;
155 fprintf(stderr, "oops_w_from_c\n" );
156 return 0;
157
158}
159
160
161int Yap_popChar(int sno)
162{
163 StreamDesc *s = GLOBAL_Stream + sno;
164 s->buf.on = false;
165Yap_DefaultStreamOps(s);
166return s->buf.ch;
167
168}
169
170int Yap_peekChar(int sno) {
171 StreamDesc *s = GLOBAL_Stream + sno;
172 int ch;
173 if (s->file) {
174 ch = fgetc(s->file);
175 if (ch == EOF) {
176 clearerr(s->file);
177 s->status &= ~Eof_Error_Stream_f;
178 } else {
179 // do not try doing error processing
180 ungetc(ch, s->file);
181 }
182 }else {
183 Int pos = s->charcount;
184 Int line = s->linecount;
185 Int lpos = s->linestart;
186
187 ch = s->stream_wgetc(sno);
188 s->charcount = pos;
189 s->linecount = line;
190 s->linestart = lpos;
191 if (ch == EOF) {
192 s->status &= ~Eof_Error_Stream_f;
193 return ch;
194 } else {
195 s->buf.on = true;
196 s->buf.ch = ch;
197 s->stream_wgetc = oops_w_from_c;
198 s->stream_getc = Yap_popChar;
199 }
200 // Yap_SetCurInpPos(sno, pos);
201 }
202 return ch;
203}
204
205int Yap_peek(int sno) { return GLOBAL_Stream[sno].stream_wpeek(sno); }
206
207static int dopeek_byte(int sno) { return GLOBAL_Stream[sno].stream_peek(sno); }
208
209bool store_code(int ch, Term t USES_REGS) {
210 Term t2 = Deref(t);
211 bool rc = Yap_unify_constant(t2, MkIntegerTerm(ch));
212 if (!rc && !IsVarTerm(t2)) {
213 if (!IsIntegerTerm(t2)) {
214 Yap_ThrowError(TYPE_ERROR_INTEGER, t, "in output argument");
215 } else if (IntegerOfTerm(t2) < 0) {
216 Yap_ThrowError(REPRESENTATION_ERROR_IN_CHARACTER_CODE, t,
217 "in output argument");
218 }
219 }
220 return rc;
221}
222
230static Int at_end_of_stream(USES_REGS1) { /* at_end_of_stream */
231 /* the next character is a EOF */
232 int sno = Yap_CheckStream(ARG1, Input_Stream_f, NULL);
233 Int out;
234
235 if (sno < 0)
236 return (FALSE);
237 out = GLOBAL_Stream[sno].status & Eof_Stream_f;
238 if (!out) {
239 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
240 out = (dopeek_byte(sno) < 0);
241 } else {
242 out = (Yap_peek(sno) < 0);
243 }
244 }
245 UNLOCK(GLOBAL_Stream[sno].streamlock);
246 return out;
247}
248
257static Int at_end_of_stream_0(USES_REGS1) { /* at_end_of_stream */
258 /* the next character is a EOF */
259 Int out;
260
261 int sno = LOCAL_c_input_stream;
262 out = GLOBAL_Stream[sno].status & Eof_Stream_f;
263 if (!out) {
264 out = (Yap_peek(sno) < 0);
265 }
266 UNLOCK(GLOBAL_Stream[sno].streamlock);
267 return out;
268}
269
270static int yap_fflush(int sno) {
271#if USE_READLINE
272 Yap_ReadlineFlush(sno);
273#endif
274 if ((GLOBAL_Stream[sno].status & Output_Stream_f) &&
275 !(GLOBAL_Stream[sno].status &
276 (Null_Stream_f | InMemory_Stream_f | Socket_Stream_f | Pipe_Stream_f |
277 Free_Stream_f))) {
278 return (fflush(GLOBAL_Stream[sno].file));
279 } else
280 return (0);
281}
282
292static Int get(USES_REGS1) { /* '$get'(Stream,-N) */
293 int sno = Yap_CheckTextStream(ARG1, Input_Stream_f, "get/2");
294 int ch;
295 // Int status;
296
297 if (sno < 0)
298 return FALSE;
299 // status = GLOBAL_Stream[sno].status;
300 while ((ch = GLOBAL_Stream[sno].stream_wgetc(sno)) <= 32 && ch >= 0)
301 ;
302 UNLOCK(GLOBAL_Stream[sno].streamlock);
303 return store_code(ch, ARG2 PASS_REGS);
304}
305
312static Int get_char(USES_REGS1) { /* '$get'(Stream,-N) */
313 int sno = Yap_CheckTextStream(ARG1, Input_Stream_f, "get/2");
314 int ch;
315 // Int status;
316
317 if (sno < 0)
318 return false;
319 // status = GLOBAL_Stream[sno].status;
320 ch = GLOBAL_Stream[sno].stream_wgetc(sno);
321 UNLOCK(GLOBAL_Stream[sno].streamlock);
322 Term t2 = Deref(ARG2);
323 bool rc = Yap_unify_constant(t2, MkCharTerm(ch));
324 if (!rc) {
325 if (!IsAtomTerm(t2)) {
326 Yap_ThrowError(TYPE_ERROR_IN_CHARACTER, ARG2, "in input argument");
327 }
328 }
329 return rc;
330}
331
340static Int get_code(USES_REGS1) { /* get0(Stream,-N) */
341 int sno = Yap_CheckTextStream(ARG1, Input_Stream_f, "get0/2");
342 // Int status;
343 Int out;
344
345 if (sno < 0)
346 return (FALSE);
347 // status = GLOBAL_Stream[sno].status;
348 out = GLOBAL_Stream[sno].stream_wgetc(sno);
349 UNLOCK(GLOBAL_Stream[sno].streamlock);
350 return store_code(out, ARG2 PASS_REGS);
351}
352
364static Int get_1(USES_REGS1) { /* get_code1(Stream,-N) */
365 int sno = LOCAL_c_input_stream;
366 int ch;
367 // Int status;
368
369 LOCK(GLOBAL_Stream[sno].streamlock);
370 // status = GLOBAL_Stream[sno].status;
371 if ((GLOBAL_Stream[sno].status & Binary_Stream_f)) {
372 UNLOCK(GLOBAL_Stream[sno].streamlock);
373 Yap_ThrowError(PERMISSION_ERROR_INPUT_BINARY_STREAM, TermUserIn,
374 "while getting code");
375 return false;
376 }
377 while ((ch = GLOBAL_Stream[sno].stream_wgetc(sno)) <= 32 && ch >= 0)
378 ;
379 UNLOCK(GLOBAL_Stream[sno].streamlock);
380 return store_code(ch, ARG1 PASS_REGS);
381}
382
392static Int getcode_1(USES_REGS1) { /* get0(Stream,-N) */
393 int sno = LOCAL_c_input_stream;
394 // Int status;
395 Int out;
396
397 // status = GLOBAL_Stream[sno].status;
398 LOCK(GLOBAL_Stream[sno].streamlock);
399 if ((GLOBAL_Stream[sno].status & Binary_Stream_f)) {
400 UNLOCK(GLOBAL_Stream[sno].streamlock);
401 Yap_ThrowError(PERMISSION_ERROR_INPUT_BINARY_STREAM, TermUserIn,
402 "while getting code");
403 return false;
404 }
405 out = GLOBAL_Stream[sno].stream_wgetc(sno);
406 UNLOCK(GLOBAL_Stream[sno].streamlock);
407 return store_code(out, ARG1 PASS_REGS);
408}
409
419static Int getchar_1(USES_REGS1) { /* get0(Stream,-N) */
420 int sno = LOCAL_c_input_stream;
421 // Int status;
422 Int ch;
423
424 LOCK(GLOBAL_Stream[sno].streamlock);
425 // status = GLOBAL_Stream[sno].status;
426 ch = GLOBAL_Stream[sno].stream_wgetc(sno);
427 if ((GLOBAL_Stream[sno].status & Binary_Stream_f)) {
428 UNLOCK(GLOBAL_Stream[sno].streamlock);
429 Yap_ThrowError(PERMISSION_ERROR_INPUT_TEXT_STREAM, TermUserIn,
430 "while getting code");
431 return false;
432 }
433 UNLOCK(GLOBAL_Stream[sno].streamlock);
434 bool rc = Yap_unify_constant(ARG1, MkCharTerm(ch));
435 if (!rc) {
436 Term t2 = Deref(ARG1);
437 if (!IsAtomTerm(t2)) {
438 Yap_ThrowError(TYPE_ERROR_IN_CHARACTER, ARG1, "in input argument");
439 }
440 }
441 return rc;
442}
443
444static Int get0_line_codes(USES_REGS1) { /* '$get0'(Stream,-N) */
445 int sno = Yap_CheckTextStream(ARG1, Input_Stream_f, "get0/2");
446 // Int status;
447 Term out;
448 Int ch = '\0';
449 int rewind;
450
451 if (sno < 0)
452 return (FALSE);
453 rewind = FALSE;
454 // status = GLOBAL_Stream[sno].status;
455 out = read_line(sno);
456 UNLOCK(GLOBAL_Stream[sno].streamlock);
457 if (rewind)
458 return Yap_unify(MkPairTerm(MkIntegerTerm(ch), out), ARG2);
459 else
460 return Yap_unify(out, ARG2);
461}
462
471static Int get_byte(USES_REGS) { /* '$get_byte'(Stream,-N) */
472 Term out = Deref(ARG2);
473
474 if (!IsVarTerm(out)) {
475 if (!IsIntegerTerm(out)) Yap_ThrowError(TYPE_ERROR_IN_BYTE, ARG1, " bad type");
476 Int ch = IntegerOfTerm(out);
477 if (ch < -1 || ch > 255) Yap_ThrowError(TYPE_ERROR_IN_BYTE, ARG1, " bad type");
478 }
479
480 int sno = Yap_CheckBinaryStream(ARG1, Input_Stream_f, "get_byte/2");
481 if (sno < 0)
482 return (FALSE);
483 out = MkIntTerm(GLOBAL_Stream[sno].stream_getc(sno));
484 UNLOCK(GLOBAL_Stream[sno].streamlock);
485 return Yap_unify_constant(ARG2, out);
486}
487
497static Int get_byte_1(USES_REGS1) { /* '$get_byte'(Stream,-N) */
498 int sno = LOCAL_c_input_stream;
499 Int status;
500 Term out = Deref(ARG1);
501
502 if (!IsVarTerm(out)) {
503 if (!IsIntegerTerm(out)) Yap_ThrowError(TYPE_ERROR_IN_BYTE, ARG2, " bad type");
504 Int ch = IntegerOfTerm(out);
505 if (ch < -1 || ch > 255) Yap_ThrowError(TYPE_ERROR_IN_BYTE, ARG2, " bad type");
506 }
507 LOCK(GLOBAL_Stream[sno].streamlock);
508 status = GLOBAL_Stream[sno].status;
509 if (!(status & Binary_Stream_f)
510 // &&strictISOFlag()
511 ) {
512 UNLOCK(GLOBAL_Stream[sno].streamlock);
513 Yap_ThrowError(PERMISSION_ERROR_INPUT_TEXT_STREAM, ARG1, "get_byte/1");
514 return (FALSE);
515 }
516 out = MkIntTerm(GLOBAL_Stream[sno].stream_getc(sno));
517 UNLOCK(GLOBAL_Stream[sno].streamlock);
518 return Yap_unify_constant(ARG1, out);
519}
520
530static Int put_code_1(USES_REGS1) { /* '$put'(,N) */
531 int sno = LOCAL_c_output_stream, ch;
532 Term t2;
533
534 if (IsVarTerm(t2 = Deref(ARG1))) {
535 Yap_ThrowError(INSTANTIATION_ERROR, t2, "put_code/1");
536 return FALSE;
537 } else if (!IsIntegerTerm(t2)) {
538 Yap_ThrowError(TYPE_ERROR_INTEGER, t2, "put_code/1");
539 return FALSE;
540 } else if ((ch = IntegerOfTerm(t2)) < -1) {
541 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2, "put_code/1");
542 return FALSE;
543 }
544 LOCK(GLOBAL_Stream[sno].streamlock);
545 GLOBAL_Stream[sno].stream_wputc(sno, ch);
546 /*
547 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
548 * yap_fflush(GLOBAL_Stream[sno].file);
549 */
550 UNLOCK(GLOBAL_Stream[sno].streamlock);
551 return (TRUE);
552}
553
560static Int put_code(USES_REGS1) { /* '$put'(Stream,N) */
561 int ch;
562 Term t2;
563 int sno;
564
565 if (IsVarTerm(t2 = Deref(ARG2))) {
566 Yap_ThrowError(INSTANTIATION_ERROR, t2, "put_code/1");
567 return FALSE;
568 } else if (!IsIntegerTerm(t2)) {
569 Yap_ThrowError(TYPE_ERROR_INTEGER, t2, "put_code/1");
570 return FALSE;
571 } else if ((ch = IntegerOfTerm(t2)) < -1) {
572 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2, "put_code/1");
573 return FALSE;
574 }
575 sno = Yap_CheckTextStream(ARG1, Output_Stream_f, "put/2");
576 if (sno < 0)
577 return (FALSE);
578 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
579 UNLOCK(GLOBAL_Stream[sno].streamlock);
580 Yap_ThrowError(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "put/2");
581 return (FALSE);
582 }
583
584 GLOBAL_Stream[sno].stream_wputc(sno, ch);
585 /*
586 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
587 * yap_fflush(GLOBAL_Stream[sno].file);
588 */
589 UNLOCK(GLOBAL_Stream[sno].streamlock);
590 return (TRUE);
591}
592
602static Int put_char_1(USES_REGS1) { /* '$put'(,N) */
603 int sno = LOCAL_c_output_stream;
604 Term t2;
605 int ch;
606
607 if (IsVarTerm(t2 = Deref(ARG1))) {
608 Yap_ThrowError(INSTANTIATION_ERROR, t2, "put_char/1");
609 return FALSE;
610 } else if (!IsAtomTerm(t2)) {
611 Yap_ThrowError(TYPE_ERROR_INTEGER, t2, "put_char/1");
612 return FALSE;
613 } else if ((ch = CharOfAtom(AtomOfTerm(t2))) < -1) {
614 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2, "put_char/1");
615 return FALSE;
616 }
617 LOCK(GLOBAL_Stream[sno].streamlock);
618 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
619 UNLOCK(GLOBAL_Stream[sno].streamlock);
620 Yap_ThrowError(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "put/2");
621 return (FALSE);
622 }
623 GLOBAL_Stream[sno].stream_wputc(sno, ch);
624 /*
625 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
626 * yap_fflush(GLOBAL_Stream[sno].file);
627 */
628 UNLOCK(GLOBAL_Stream[sno].streamlock);
629 return (TRUE);
630}
631
638static Int put_char(USES_REGS1) { /* '$put'(Stream,N) */
639 Term t2;
640 int ch;
641 int sno;
642
643 if (IsVarTerm(t2 = Deref(ARG2))) {
644 Yap_ThrowError(INSTANTIATION_ERROR, t2, "put_char/1");
645 return FALSE;
646 } else if (!IsAtomTerm(t2)) {
647 Yap_ThrowError(TYPE_ERROR_INTEGER, t2, "put_char/1");
648 return FALSE;
649 } else if ((ch = CharOfAtom(AtomOfTerm(t2))) < -1) {
650 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2, "put_char/1");
651 return FALSE;
652 }
653 sno = Yap_CheckTextStream(ARG1, Output_Stream_f, "put/2");
654 if (sno < 0)
655 return (FALSE);
656 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
657 UNLOCK(GLOBAL_Stream[sno].streamlock);
658 Yap_ThrowError(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "put/2");
659 return (FALSE);
660 }
661 GLOBAL_Stream[sno].stream_wputc(sno, (int)IntegerOfTerm(Deref(ARG2)));
662 /*
663 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
664 * yap_fflush(GLOBAL_Stream[sno].file);
665 */
666 UNLOCK(GLOBAL_Stream[sno].streamlock);
667 return (TRUE);
668}
669
674static Int tab_1(USES_REGS1) { /* nl */
675 int sno = LOCAL_c_output_stream;
676 Term t1;
677 Int tabs, i;
678 if (IsVarTerm(t1 = Deref(ARG1))) {
679 Yap_ThrowError(INSTANTIATION_ERROR, t1, "first argument");
680 return FALSE;
681 } else if (!IsIntegerTerm(t1)) {
682 Yap_ThrowError(TYPE_ERROR_INTEGER, t1, "first argument");
683 return FALSE;
684 } else if ((tabs = IntegerOfTerm(t1)) < 0) {
685 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t1, "first argument");
686 return FALSE;
687 }
688
689 LOCK(GLOBAL_Stream[sno].streamlock);
690 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
691 UNLOCK(GLOBAL_Stream[sno].streamlock);
692 Yap_ThrowError(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "user_output");
693 return (FALSE);
694 }
695
696 for (i = 0; i < tabs; i++)
697 GLOBAL_Stream[sno].stream_wputc(sno, ' ');
698 /*
699 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
700 * yap_fflush(GLOBAL_Stream[sno].file);
701 */
702 UNLOCK(GLOBAL_Stream[sno].streamlock);
703 return (TRUE);
704}
705
712static Int tab(USES_REGS1) { /* nl(Stream) */
713 int sno;
714 Term t2;
715 Int tabs, i;
716 if (IsVarTerm(t2 = Deref(ARG2))) {
717 Yap_ThrowError(INSTANTIATION_ERROR, t2, "put_char/1");
718 return FALSE;
719 } else if (!IsIntegerTerm(t2)) {
720 Yap_ThrowError(TYPE_ERROR_INTEGER, t2, "put_char/1");
721 return FALSE;
722 } else if ((tabs = IntegerOfTerm(t2)) < 0) {
723 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2, "tab/1");
724 return FALSE;
725 }
726 sno = Yap_CheckTextStream(ARG1, Output_Stream_f, "nl/1");
727 if (sno < 0)
728 return (FALSE);
729
730 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
731 UNLOCK(GLOBAL_Stream[sno].streamlock);
732 Yap_ThrowError(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "nl/0");
733 return (FALSE);
734 }
735
736 for (i = 0; i < tabs; i++)
737 GLOBAL_Stream[sno].stream_wputc(sno, ' ');
738 /*
739 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
740 * yap_fflush(GLOBAL_Stream[sno].file);
741 */
742 UNLOCK(GLOBAL_Stream[sno].streamlock);
743 return (TRUE);
744}
745
750static Int nl_1(USES_REGS1) { /* nl */
751 int sno = LOCAL_c_output_stream;
752 LOCK(GLOBAL_Stream[sno].streamlock);
753 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
754 UNLOCK(GLOBAL_Stream[sno].streamlock);
755 Yap_ThrowError(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "nl/0");
756 return (FALSE);
757 }
758 GLOBAL_Stream[sno].stream_wputc(sno, 10);
759 /*
760 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
761 * yap_fflush(GLOBAL_Stream[sno].file);
762 */
763 UNLOCK(GLOBAL_Stream[sno].streamlock);
764 return (TRUE);
765}
766
776static Int nl(USES_REGS1) { /* nl(Stream) */
777 int sno = Yap_CheckTextStream(ARG1, Output_Stream_f, "nl/1");
778 if (sno < 0)
779 return (FALSE);
780 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
781 UNLOCK(GLOBAL_Stream[sno].streamlock);
782 Yap_ThrowError(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "put/2");
783 return (FALSE);
784 }
785 GLOBAL_Stream[sno].stream_wputc(sno, 10);
786 /*
787 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
788 * yap_fflush(GLOBAL_Stream[sno].file);
789 */
790 UNLOCK(GLOBAL_Stream[sno].streamlock);
791 return (TRUE);
792}
793
800static Int put_byte(USES_REGS1) { /* '$put_byte'(Stream,N) */
801 Term t2;
802 Int ch;
803 if (IsVarTerm(t2 = Deref(ARG2))) {
804 Yap_ThrowError(INSTANTIATION_ERROR, t2, "put_code/2");
805 return FALSE;
806 } else if (!IsIntegerTerm(t2)) {
807 Yap_ThrowError(TYPE_ERROR_BYTE, t2, "put_code/2");
808 return FALSE;
809 } else if ((ch = IntegerOfTerm(t2)) < -1) {
810 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2, "put_code/1");
811 return FALSE;
812 }
813 int sno = Yap_CheckBinaryStream(ARG1, Output_Stream_f, "put/2");
814 if (sno < 0)
815 return (FALSE);
816 GLOBAL_Stream[sno].stream_putc(sno, ch);
817 /*
818 * if (!(GLOBAL_Stream[sno].status & Null_Stream_f))
819 * yap_fflush(GLOBAL_Stream[sno].file);
820 */
821 UNLOCK(GLOBAL_Stream[sno].streamlock);
822 return (TRUE);
823}
824
833static Int put_byte_1(USES_REGS1) { /* '$put_byte'(Stream,N) */
834 Term t2;
835 Int ch;
836 int sno = LOCAL_c_output_stream;
837 if (IsVarTerm(t2 = Deref(ARG1))) {
838 Yap_ThrowError(INSTANTIATION_ERROR, t2, "put_code/1");
839 return FALSE;
840 } else if (!IsIntegerTerm(t2)) {
841 Yap_ThrowError(TYPE_ERROR_BYTE, t2, "put_code/1");
842 return FALSE;
843 } else if ((ch = IntegerOfTerm(t2)) < -1) {
844 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2, "put_code/1");
845 return FALSE;
846 }
847 LOCK(GLOBAL_Stream[sno].streamlock);
848 if (!(GLOBAL_Stream[sno].status & Binary_Stream_f)
849 //&& strictISOFlag()
850 ) {
851 UNLOCK(GLOBAL_Stream[sno].streamlock);
852 Yap_ThrowError(PERMISSION_ERROR_OUTPUT_TEXT_STREAM, ARG1, "get0/2");
853 return (FALSE);
854 }
855 GLOBAL_Stream[sno].stream_putc(sno, ch);
856 UNLOCK(GLOBAL_Stream[sno].streamlock);
857 return (TRUE);
858}
859
869static Int skip_1(USES_REGS1) { /* 'skip'(N) */
870 Int n;
871 Term t1;
872 int sno = LOCAL_c_output_stream;
873 int ch;
874
875 if (IsVarTerm(t1 = Deref(ARG1))) {
876 Yap_ThrowError(INSTANTIATION_ERROR, t1, "skip/1");
877 return FALSE;
878 } else if (!IsIntegerTerm(t1)) {
879 Yap_ThrowError(TYPE_ERROR_INTEGER, t1, "skip/1");
880 return FALSE;
881 } else if ((n = IntegerOfTerm(t1)) < 0) {
882 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t1, "skip/1");
883 return false;
884 }
885 while ((ch = GLOBAL_Stream[sno].stream_wgetc(sno)) != n && ch != -1)
886 ;
887 UNLOCK(GLOBAL_Stream[sno].streamlock);
888 return true;
889}
890
898static Int skip(USES_REGS1) { /* '$skip'(Stream,N) */
899 Int n;
900 Term t2;
901 int sno = Yap_CheckTextStream(ARG1, Input_Stream_f, "skip/2");
902 int ch;
903
904 if (sno < 0)
905 return (FALSE);
906 if (IsVarTerm(t2 = Deref(ARG2))) {
907 UNLOCK(GLOBAL_Stream[sno].streamlock);
908 Yap_ThrowError(INSTANTIATION_ERROR, t2, "skip/2");
909 return FALSE;
910 } else if (!IsIntegerTerm(t2)) {
911 UNLOCK(GLOBAL_Stream[sno].streamlock);
912 Yap_ThrowError(TYPE_ERROR_INTEGER, t2, "skip/2");
913 return FALSE;
914 } else if ((n = IntegerOfTerm(t2)) < 0) {
915 UNLOCK(GLOBAL_Stream[sno].streamlock);
916 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2, "skip/2");
917 return FALSE;
918 }
919 while ((ch = GLOBAL_Stream[sno].stream_wgetc(sno)) != n && ch != -1)
920 ;
921 UNLOCK(GLOBAL_Stream[sno].streamlock);
922 return (TRUE);
923}
924
934static Int flush_output(USES_REGS1) { /* flush_output(Stream) */
935 int sno = Yap_CheckStream(ARG1, Output_Stream_f, "flush_output/1");
936 if (sno < 0) {
937 UNLOCK(GLOBAL_Stream[sno].streamlock);
938 return (FALSE);
939 }
940 yap_fflush(sno);
941 UNLOCK(GLOBAL_Stream[sno].streamlock);
942 return (TRUE);
943}
944
954static Int flush_output0(USES_REGS1) { /* flush_output */
955 yap_fflush(LOCAL_c_output_stream);
956 return (TRUE);
957}
958
959static Int flush_all_streams(USES_REGS1) { /* $flush_all_streams */
960#if BROKEN_FFLUSH_NULL
961 int i;
962 for (i = 0; i < MaxStreams; ++i) {
963 LOCK(GLOBAL_Stream[i].streamlock);
964 yap_fflush(i);
965 UNLOCK(GLOBAL_Stream[i].streamlock);
966 }
967#else
968 fflush(NULL);
969#endif
970
971 return TRUE;
972}
973
982static Int peek_code(USES_REGS1) { /* at_end_of_stream */
983 /* the next character is a EOF */
984 int sno = Yap_CheckTextStream(ARG1, Input_Stream_f, "peek_code/2");
985 Int ch;
986
987 if (sno < 0)
988 return FALSE;
989 if ((ch = Yap_peek(sno)) < 0) {
990#ifdef PEEK_EOF
991 UNLOCK(GLOBAL_Stream[sno].streamlock);
992 return false;
993#endif
994 }
995 UNLOCK(GLOBAL_Stream[sno].streamlock);
996 return (Yap_unify_constant(ARG2, MkIntTerm(ch)));
997}
998
1008static Int peek_code_1(USES_REGS1) { /* at_end_of_stream */
1009 /* the next character is a EOF */
1010 int sno = LOCAL_c_input_stream;
1011 Int ch;
1012
1013 LOCK(GLOBAL_Stream[sno].streamlock);
1014 if (GLOBAL_Stream[sno].status & Binary_Stream_f) {
1015 UNLOCK(GLOBAL_Stream[sno].streamlock);
1016 Yap_ThrowError(PERMISSION_ERROR_INPUT_BINARY_STREAM, ARG1, "peek_code/2");
1017 return FALSE;
1018 }
1019 if ((ch = Yap_peek(sno)) < 0) {
1020#ifdef PEEK_EOF
1021 UNLOCK(GLOBAL_Stream[sno].streamlock);
1022 return false;
1023#endif
1024 }
1025 UNLOCK(GLOBAL_Stream[sno].streamlock);
1026 return (Yap_unify_constant(ARG1, MkIntTerm(ch)));
1027}
1028
1036static Int peek_byte(USES_REGS1) { /* at_end_of_stream */
1037 /* the next character is a EOF */
1038 int sno = Yap_CheckBinaryStream(ARG1, Input_Stream_f, "peek_byte/2");
1039 Int ch;
1040
1041 if (sno < 0)
1042 return false;
1043 if (!(GLOBAL_Stream[sno].status & Binary_Stream_f)) {
1044 UNLOCK(GLOBAL_Stream[sno].streamlock);
1045 Yap_ThrowError(PERMISSION_ERROR_INPUT_TEXT_STREAM, ARG1, "peek_byte/2");
1046 return (FALSE);
1047 }
1048 if ((ch = dopeek_byte(sno)) < 0) {
1049#ifdef PEEK_EOF
1050 UNLOCK(GLOBAL_Stream[sno].streamlock);
1051 return false;
1052#endif
1053 }
1054 UNLOCK(GLOBAL_Stream[sno].streamlock);
1055 return (Yap_unify_constant(ARG2, MkIntTerm(ch)));
1056}
1057
1065static Int peek_byte_1(USES_REGS1) { /* at_end_of_stream */
1066 /* the next character is a EOF */
1067 int sno = LOCAL_c_input_stream;
1068 Int ch;
1069
1070 if (sno < 0)
1071 return (FALSE);
1072 LOCK(GLOBAL_Stream[sno].streamlock);
1073 if (!(GLOBAL_Stream[sno].status & Binary_Stream_f)) {
1074 UNLOCK(GLOBAL_Stream[sno].streamlock);
1075 Yap_ThrowError(PERMISSION_ERROR_INPUT_TEXT_STREAM, ARG1, "peek_byte/2");
1076 return (FALSE);
1077 }
1078 if ((ch = dopeek_byte(sno)) < 0) {
1079#ifdef PEEK_EOF
1080 UNLOCK(GLOBAL_Stream[sno].streamlock);
1081 return false;
1082#endif
1083 }
1084 UNLOCK(GLOBAL_Stream[sno].streamlock);
1085 return (Yap_unify_constant(ARG1, MkIntTerm(ch)));
1086}
1087
1095static Int peek_char(USES_REGS1) {
1096 /* the next character is a EOF */
1097 int sno = Yap_CheckTextStream(ARG1, Input_Stream_f, "peek/2");
1098 unsigned char sinp[16];
1099 Int ch;
1100
1101 if (sno < 0)
1102 return false;
1103 ch = Yap_peek(sno);
1104 if (ch < 0) {
1105 UNLOCK(GLOBAL_Stream[sno].streamlock);
1106 return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof));
1107 }
1108 UNLOCK(GLOBAL_Stream[sno].streamlock);
1109 int off = put_utf8(sinp, ch);
1110 if (off < 0) {
1111 return false;
1112 }
1113 sinp[off] = '\0';
1114 return Yap_unify_constant(ARG2, MkAtomTerm(Yap_ULookupAtom(sinp)));
1115}
1116
1124static Int peek_char_1(USES_REGS1) {
1125 /* the next character is a EOF */
1126 int sno = LOCAL_c_input_stream;
1127 unsigned char sinp[10];
1128 Int ch;
1129
1130 LOCK(GLOBAL_Stream[sno].streamlock);
1131 if ((ch = Yap_peek(sno)) < 0) {
1132 UNLOCK(GLOBAL_Stream[sno].streamlock);
1133 return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof));
1134 // return false;
1135 }
1136 UNLOCK(GLOBAL_Stream[sno].streamlock);
1137 int off = put_utf8(sinp, ch);
1138 sinp[off] = '\0';
1139 return Yap_unify_constant(ARG2, MkAtomTerm(Yap_ULookupAtom(sinp)));
1140}
1141
1163void Yap_flush_all(void) { CACHE_REGS(void) flush_all_streams(PASS_REGS1); }
1164
1165void Yap_FlushStreams(void) { CACHE_REGS(void) flush_all_streams(PASS_REGS1); }
1166
1167void Yap_InitCharsio(void) {
1168 Yap_InitCPred("get", 2, get, SafePredFlag | SyncPredFlag);
1169 Yap_InitCPred("get_code", 2, get_code, SafePredFlag | SyncPredFlag);
1170 Yap_InitCPred("get_char", 2, get_char, SafePredFlag | SyncPredFlag);
1171 Yap_InitCPred("get0", 2, get_code, SafePredFlag | SyncPredFlag);
1172 Yap_InitCPred("get", 1, get_1, SafePredFlag | SyncPredFlag);
1173 Yap_InitCPred("get_code", 1, getcode_1, SafePredFlag | SyncPredFlag);
1174 Yap_InitCPred("get_char", 1, getchar_1, SafePredFlag | SyncPredFlag);
1175 Yap_InitCPred("get0", 1, getcode_1, SafePredFlag | SyncPredFlag);
1176 Yap_InitCPred("$get0_line_codes", 2, get0_line_codes,
1177 SafePredFlag | SyncPredFlag | HiddenPredFlag);
1178 Yap_InitCPred("get_byte", 2, get_byte, SafePredFlag | SyncPredFlag);
1179 Yap_InitCPred("get_byte", 1, get_byte_1, SafePredFlag | SyncPredFlag);
1180 Yap_InitCPred("put", 1, put_code_1, SafePredFlag | SyncPredFlag);
1181 Yap_InitCPred("put", 2, put_code, SafePredFlag | SyncPredFlag);
1182 Yap_InitCPred("put_code", 1, put_code_1, SafePredFlag | SyncPredFlag);
1183 Yap_InitCPred("put_code", 2, put_code, SafePredFlag | SyncPredFlag);
1184 Yap_InitCPred("put_char", 1, put_char_1, SafePredFlag | SyncPredFlag);
1185 Yap_InitCPred("put_char", 2, put_char, SafePredFlag | SyncPredFlag);
1186 Yap_InitCPred("put_byte", 2, put_byte, SafePredFlag | SyncPredFlag);
1187 Yap_InitCPred("put_byte", 1, put_byte_1, SafePredFlag | SyncPredFlag);
1188 Yap_InitCPred("put_char", 2, put_char, SafePredFlag | SyncPredFlag);
1189 Yap_InitCPred("put_char1", 1, put_char_1, SafePredFlag | SyncPredFlag);
1190 Yap_InitCPred("tab", 2, tab, SafePredFlag | SyncPredFlag);
1191 Yap_InitCPred("tab", 1, tab_1, SafePredFlag | SyncPredFlag);
1192 Yap_InitCPred("nl", 0, nl_1, SafePredFlag | SyncPredFlag);
1193 Yap_InitCPred("nl", 1, nl, SafePredFlag | SyncPredFlag);
1194
1195 Yap_InitCPred("$flush_all_streams", 0, flush_all_streams,
1196 SafePredFlag | SyncPredFlag | HiddenPredFlag);
1197 Yap_InitCPred("flush_output", 1, flush_output, SafePredFlag | SyncPredFlag);
1198 Yap_InitCPred("flush_output", 0, flush_output0, SafePredFlag | SyncPredFlag);
1199
1200 Yap_InitCPred("at_end_of_stream", 1, at_end_of_stream,
1201 SafePredFlag | SyncPredFlag);
1202 Yap_InitCPred("at_end_of_stream_0", 0, at_end_of_stream_0,
1203 SafePredFlag | SyncPredFlag);
1204 // Yap_InitCPred ("$past_eof", 1, past_eof, SafePredFlag|SyncPredFlag);
1205 Yap_InitCPred("peek", 2, peek_code, SafePredFlag | SyncPredFlag);
1206 Yap_InitCPred("peek_code", 2, peek_code, SafePredFlag | SyncPredFlag);
1207 Yap_InitCPred("peek_char", 2, peek_char, SafePredFlag | SyncPredFlag);
1208 Yap_InitCPred("peek_byte", 2, peek_byte, SafePredFlag | SyncPredFlag);
1209 Yap_InitCPred("peek", 1, peek_code_1, SafePredFlag | SyncPredFlag);
1210 Yap_InitCPred("peek_code", 1, peek_code_1, SafePredFlag | SyncPredFlag);
1211 Yap_InitCPred("peek_char", 1, peek_char_1, SafePredFlag | SyncPredFlag);
1212 Yap_InitCPred("peek_byte", 1, peek_byte_1, SafePredFlag | SyncPredFlag);
1213 Yap_InitCPred("skip", 2, skip, SafePredFlag | SyncPredFlag);
1214 Yap_InitCPred("skip", 1, skip_1, SafePredFlag | SyncPredFlag);
1215 Yap_InitCPred("tab", 2, tab, SafePredFlag | SyncPredFlag);
1216 Yap_InitCPred("tab", 1, tab_1, SafePredFlag | SyncPredFlag);
1217}
1218
Main definitions.
Int CharOfAtom(Atom at)
CharOfAtom: convert an atom into a single character.
Definition: charsio.c:90
int(* stream_getc)(int)
function the stream uses for writing a character
Definition: YapStreams.h:256
int(* stream_wgetc)(int)
function the stream uses for reading an octet
Definition: YapStreams.h:257