18static char SccsId[] =
"%W% %G%";
61#if HAVE_SYS_SELECT_H && !_MSC_VER && !defined(__MINGW32__)
62#include <sys/select.h>
84#define strncat(X, Y, Z) strcat(X, Y)
87#define strncpy(X, Y, Z) strcpy(X, Y)
89#if _MSC_VER || defined(__MINGW32__)
95#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
101static yap_error_number bind_variable_names(Term t USES_REGS) {
102 while (!IsVarTerm(t) && IsPairTerm(t)) {
103 Term th = HeadOfTerm(t);
109 if ((f = FunctorOfTerm(th)) != FunctorEq) {
112 t1 = ArgOfTerm(1, th);
114 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"variable_names");
117 t2 = ArgOfTerm(2, th);
119 Term nt2 = Yap_MkApplTerm(FunctorDollarVar, 1, &t1);
121 return RESOURCE_ERROR_STACK;
123 YapBind(VarOfTerm(t2), nt2);
131static Term readFromBuffer(
const char *s, Term opts) {
134 encoding_t enc = ENC_ISO_UTF8;
135 sno = Yap_open_buf_read_stream( NULL,
136 (
char *)s, strlen_utf8((
unsigned char *)s), &enc, MEM_BUF_USER,
137 Yap_LookupAtom(Yap_StrPrefix((
char *)s, 16)), TermNone);
140 Yap_CloseStream(sno);
144#if _MSC_VER || defined(__MINGW32__)
145#define SYSTEM_STAT _stat
147#define SYSTEM_STAT stat
150static bool write_term(
int output_stream, Term t,
bool b, yap_error_number *errp,
xarg *args USES_REGS) {
152 Term cm = CurrentModule;
156 yhandle_t ynames = 0;
157 int depth, flags = 0;
161 *errp = YAP_NO_ERROR;
162 if (args[WRITE_VARIABLE_NAMES].used ||
163 args[WRITE_SINGLETONS].used ||
164 args[WRITE_CYCLES].used
166 Term l = TermNil, *lp;
167 if (!args[WRITE_CYCLES].used || (args[WRITE_CYCLES].used
168 && args[WRITE_CYCLES].tvalue == TermTrue)) {
169 flags |= Handle_cyclics_f;
174 Term t1 = CopyTermToArena(t,
false,
false, errp, NULL, lp PASS_REGS);
179 if (args[WRITE_VARIABLE_NAMES].used) {
182 tnames = args[WRITE_VARIABLE_NAMES].tvalue;
183 ynames = Yap_InitHandle(tnames);
185 tnames = Yap_GetFromHandle(ynames);
187 if ((*errp = bind_variable_names(tnames PASS_REGS))==YAP_NO_ERROR) {
188 flags |= Named_vars_f;
194 if (args[WRITE_SINGLETONS].used) {
196 *errp = RESOURCE_ERROR_STACK;
199 flags |= Singleton_vars_f;
202 if (args[WRITE_ATTRIBUTES].used) {
203 Term ctl = args[WRITE_ATTRIBUTES].tvalue;
204 if (ctl == TermWrite) {
205 flags |= AttVar_None_f;
206 }
else if (ctl == TermPortray) {
207 flags |= AttVar_None_f | AttVar_Portray_f;
208 }
else if (ctl == TermDots) {
209 flags |= AttVar_Dots_f;
210 }
else if (ctl != TermIgnore) {
212 DOMAIN_ERROR_WRITE_OPTION, ctl,
213 "write attributes should be one of {dots,ignore,portray,write}");
218 if (args[WRITE_NUMBERVARS].used) {
219 if (args[WRITE_NUMBERVARS].tvalue == TermTrue) {
220 flags |= Handle_vars_f;
223 flags |= Handle_vars_f;
226 if (args[WRITE_QUOTED].used && args[WRITE_QUOTED].tvalue == TermTrue) {
227 flags |= Quote_illegal_f;
229 if (args[WRITE_IGNORE_OPS].used &&
230 args[WRITE_IGNORE_OPS].tvalue == TermTrue) {
231 flags |= Ignore_ops_f;
233 if (args[WRITE_PORTRAY].used && args[WRITE_IGNORE_OPS].tvalue == TermTrue) {
234 flags |= Ignore_ops_f;
236 if (args[WRITE_PORTRAYED].used && args[WRITE_PORTRAYED].tvalue == TermTrue) {
237 flags |= Use_portray_f;
239 if (args[WRITE_CHARACTER_ESCAPES].used &&
240 args[WRITE_CHARACTER_ESCAPES].tvalue == TermFalse) {
241 flags |= No_Escapes_f;
243 if (args[WRITE_BACKQUOTES].used &&
244 args[WRITE_BACKQUOTES].tvalue == TermTrue) {
245 flags |= BackQuote_String_f;
247 if (args[WRITE_BRACE_TERMS].used &&
248 args[WRITE_BRACE_TERMS].tvalue == TermFalse) {
249 flags |= No_Brace_Terms_f;
251 if (args[WRITE_FULLSTOP].used && args[WRITE_FULLSTOP].tvalue == TermTrue) {
254 if (args[WRITE_NL].used && args[WRITE_NL].tvalue == TermTrue) {
258 if (args[WRITE_MAX_DEPTH].used) {
259 depth = IntegerOfTerm(args[WRITE_MAX_DEPTH].tvalue);
261 depth = LOCAL_max_depth;
262 Yap_plwrite(t, GLOBAL_Stream + output_stream, depth,HR, flags, args)
264 UNLOCK(GLOBAL_Stream[output_stream].streamlock);
274#define PAR(x, y, z) \
277static const param_t write_defs[] = {WRITE_DEFS()};
283bool Yap_WriteTerm(
int output_stream, Term t, Term opts USES_REGS) {
284 yap_error_number err = YAP_NO_ERROR;
285 int lvl = push_text_stack();
287 yhandle_t y0 = Yap_StartHandles(),
288 ylow = Yap_InitHandle(MkVarTerm()),
289 yt = Yap_InitHandle(t),
290 yargs = Yap_InitHandle(opts);
291 int mytr = TR-B->cp_tr;
292 LOCK(GLOBAL_Stream[output_stream].streamlock);
294 if (err != YAP_NO_ERROR) {
295 HR = VarOfTerm(Yap_GetFromHandle(ylow));
297 clean_tr(B->cp_tr+mytr PASS_REGS);
298 Yap_CloseHandles(y0);
300 if (err == RESOURCE_ERROR_TRAIL) {
302 if (!Yap_growtrail(0,
false)) {
303 Yap_ThrowError(RESOURCE_ERROR_TRAIL, TermNil,
"while visiting terms");
305 }
else if (err == RESOURCE_ERROR_STACK) {
309 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
314 t = Yap_GetFromHandle(yt);
315 opts = Yap_GetFromHandle(yargs);
317 args = Yap_ArgListToVector(opts, write_defs, WRITE_END,NULL,
318 DOMAIN_ERROR_WRITE_OPTION);
322 bool o = write_term(output_stream, t,
false,&err, args PASS_REGS);
323 if (args) free(args);
327 clean_tr(B->cp_tr+mytr PASS_REGS);
328 Yap_CloseHandles(y0);
329 UNLOCK(GLOBAL_Stream[output_stream].streamlock);
330 Yap_CloseHandles(y0);
378static Int write_term2(USES_REGS1) {
383 return Yap_WriteTerm(LOCAL_c_output_stream, ARG1, ARG2 PASS_REGS);
393static Int write_term3(USES_REGS1) {
395 int output_stream = Yap_CheckTextStream(ARG1, Output_Stream_f,
"write/2");
396 if (output_stream < 0) {
399 return Yap_WriteTerm(output_stream, ARG2, ARG3 PASS_REGS);
409static Int write2(USES_REGS1) {
415 int output_stream = Yap_CheckTextStream(ARG1, Output_Stream_f,
"write/2");
416 if (output_stream < 0)
418 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorSingletons,1,&t), TermNil);
419 return Yap_WriteTerm(output_stream, ARG2, opts PASS_REGS);
430static Int write1(USES_REGS1) {
433 int output_stream = LOCAL_c_output_stream;
434 if (output_stream == -1)
436 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorSingletons,1,&t), TermNil);
437 return Yap_WriteTerm(output_stream, ARG1, opts PASS_REGS);
447static Int write_canonical1(USES_REGS1) {
450 Term nv = getAtomicLocalPrologFlag(NUMBERVARS_FUNCTOR_FLAG);
451 setAtomicLocalPrologFlag(NUMBERVARS_FUNCTOR_FLAG,TermDollarUVar);
452 int output_stream = LOCAL_c_output_stream;
453 if (output_stream == -1)
455 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorSingletons,1,&t),
456 MkPairTerm(Yap_MkApplTerm(FunctorIgnoreOps,1,&t),
457 MkPairTerm(Yap_MkApplTerm(FunctorQuoted,1,&t),
458 MkPairTerm(Yap_MkApplTerm(FunctorCycles,1,&t),
460 Int f = Yap_WriteTerm(output_stream, ARG1, opts PASS_REGS);
461 setAtomicLocalPrologFlag(NUMBERVARS_FUNCTOR_FLAG,nv);
473static Int write_canonical(USES_REGS1) {
475 int output_stream = Yap_CheckTextStream(ARG1, Output_Stream_f,
"write/2");
476 if (output_stream < 0) {
479 Term nv = getAtomicLocalPrologFlag(NUMBERVARS_FUNCTOR_FLAG);
480 setAtomicLocalPrologFlag(NUMBERVARS_FUNCTOR_FLAG,TermDollarUVar);
481 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorSingletons,1,&t),
482 MkPairTerm(Yap_MkApplTerm(FunctorIgnoreOps,1,&t),
483 MkPairTerm(Yap_MkApplTerm(FunctorNumberVars,1,&t),
484 MkPairTerm(Yap_MkApplTerm(FunctorQuoted,1,&t),
485 MkPairTerm(Yap_MkApplTerm(FunctorCycles,1,&t),
487 Int f = Yap_WriteTerm(output_stream, ARG2, opts PASS_REGS);
488 setAtomicLocalPrologFlag(NUMBERVARS_FUNCTOR_FLAG,nv);
492static Int writeq1(USES_REGS1) {
495 int output_stream = LOCAL_c_output_stream;
496 if (output_stream == -1)
498 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorQuoted,1,&t),
500 return Yap_WriteTerm(output_stream, ARG1, opts PASS_REGS);
509static Int writeq(USES_REGS1) {
512 int output_stream = Yap_CheckTextStream(ARG1, Output_Stream_f,
"write/2");
513 if (output_stream < 0) {
516 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorQuoted,1,&t),
517 MkPairTerm(Yap_MkApplTerm(FunctorNumberVars,1,&t),
519 return Yap_WriteTerm(output_stream, ARG2, opts PASS_REGS);
522static Int print1(USES_REGS1) {
524 int output_stream = LOCAL_c_output_stream;
525 if (output_stream == -1)
527 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorPortray,1,&t),
528 MkPairTerm(Yap_MkApplTerm(FunctorNumberVars,1,&t),
530 return Yap_WriteTerm(output_stream, ARG1, opts PASS_REGS);
540static Int print(USES_REGS1) {
542 int output_stream = Yap_CheckTextStream(ARG1, Output_Stream_f,
"write/2");
543 if (output_stream < 0) {
546 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorPortray,1,&t),
547 MkPairTerm(Yap_MkApplTerm(FunctorNumberVars,1,&t),
549 return Yap_WriteTerm(output_stream, ARG2, opts PASS_REGS);
560static Int display1(USES_REGS1) {
562 int output_stream = LOCAL_c_output_stream;
563 if (output_stream == -1)
565 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorIgnoreOps,1,&t),TermNil);
566 return Yap_WriteTerm(output_stream, ARG1, opts PASS_REGS);
575static Int display(USES_REGS1) {
577 int output_stream = Yap_CheckTextStream(ARG1, Output_Stream_f,
"writeln/2");
578 if (output_stream < 0) {
581 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorIgnoreOps,1,&t),TermNil);
582 return Yap_WriteTerm(output_stream, ARG2, opts PASS_REGS);
586static Int writeln1(USES_REGS1) {
588 int output_stream = LOCAL_c_output_stream;
589 if (output_stream == -1)
591 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorNl,1,&t),
592 MkPairTerm(Yap_MkApplTerm(FunctorNumberVars,1,&t),
593 MkPairTerm(Yap_MkApplTerm(FunctorCycles,1,&t),
595 return Yap_WriteTerm(output_stream, ARG1, opts PASS_REGS);
598static Int writeln(USES_REGS1) {
600 int output_stream = Yap_CheckTextStream(ARG1, Output_Stream_f,
"writeln/2");
601 if (output_stream < 0) {
604 Term opts = MkPairTerm(Yap_MkApplTerm(FunctorNl,1,&t),
606 MkPairTerm(Yap_MkApplTerm(FunctorNumberVars,1,&t),
607 MkPairTerm(Yap_MkApplTerm(FunctorCycles,1,&t),
609 return Yap_WriteTerm(output_stream, ARG2, opts PASS_REGS);
612static Int p_write_depth(USES_REGS1) {
613 Term t1 = Deref(ARG1);
614 Term t2 = Deref(ARG2);
615 Term t3 = Deref(ARG3);
617 if (!IsVarTerm(t1) && !IsIntegerTerm(t1)) {
618 Yap_ThrowError(TYPE_ERROR_INTEGER, t1,
"write_depth/3");
621 if (!IsVarTerm(t2)) {
622 Term t = MkIntegerTerm(LOCAL_max_list);
623 if (!Yap_unify_constant(t2, t))
626 LOCAL_max_list = IntegerOfTerm(t2);
628 Term t = MkIntegerTerm(LOCAL_max_write_args);
629 if (!Yap_unify_constant(t3, t))
632 LOCAL_max_write_args = IntegerOfTerm(t3);
636static Int dollar_var(USES_REGS1) {
640 Term tv = Yap_MkNewApplTerm(FunctorDollarVar, 1);
641 if(!Yap_unify(tv, ARG1))
return false;
642 if (!IsVarTerm((t2 = Deref(ARG2)))) {
643 if (IsApplTerm(t2) && ArityOfFunctor(FunctorOfTerm(t2)) == 1) {
644 FunctorDollarVar= FunctorOfTerm(t2);
647 Yap_ThrowError(TYPE_ERROR_COMPOUND, ARG2,
"");
650 Yap_ThrowError(INSTANTIATION_ERROR, ARG2,
"");
657static Int term_to_string(USES_REGS1) {
658 Term t2 = Deref(ARG2), t1 = Deref(ARG1);
661 s = Yap_TermToBuffer(t1, Quote_illegal_f | Handle_vars_f);
662 if (!s || !MkStringTerm(s)) {
663 Yap_ThrowError(RESOURCE_ERROR_HEAP, t1,
664 "Could not get memory from the operating system");
667 return Yap_unify(ARG2, MkStringTerm(s));
668 }
else if (!IsStringTerm(t2)) {
669 Yap_ThrowError(TYPE_ERROR_STRING, t2,
"term_to_string/3");
672 s = StringOfTerm(t2);
674 yhandle_t y0 = Yap_StartHandles();
675 yhandle_t y1 = Yap_InitHandle( t1 );
676 Term tf = readFromBuffer(s, TermNil);
677 Int rc = Yap_unify(tf, Yap_PopHandle(y1));
678 Yap_CloseHandles(y0);
686static Int term_to_atom(USES_REGS1) {
687 Term t2 = Deref(ARG2), ctl, rc =
false;
691 Yap_TermToBuffer(Deref(ARG1), Quote_illegal_f | Handle_vars_f);
692 if (!s || !(at = Yap_UTF8ToAtom((
const unsigned char *)s))) {
693 Yap_ThrowError(RESOURCE_ERROR_HEAP, t2,
694 "Could not get memory from the operating system");
697 return Yap_unify(ARG2, MkAtomTerm(at));
698 }
else if (!IsAtomTerm(t2)) {
699 Yap_ThrowError(TYPE_ERROR_ATOM, t2,
"atom_to_term/2");
705 return ((rc = Yap_UBufferToTerm(RepAtom(at)->UStrOfAE, ctl))) &&
711char *Yap_TermToBuffer(Term t,
int flags) {
713 int sno = Yap_open_buf_write_stream(LOCAL_encoding, flags);
721 GLOBAL_Stream[sno].encoding = LOCAL_encoding;
722 GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
723 GLOBAL_Stream[sno].status &= ~FreeOnClose_Stream_f;
724 Yap_plwrite(t, GLOBAL_Stream + sno, LOCAL_max_depth,HR, flags, NULL);
725 char *
new = Yap_MemExportStreamPtr(sno);
726 Yap_CloseStream(sno);
730void Yap_InitWriteTPreds(
void) {
731 Yap_InitCPred(
"write_term", 2, write_term2, SyncPredFlag);
732 Yap_InitCPred(
"write_term", 3, write_term3, SyncPredFlag);
733 Yap_InitCPred(
"write", 1, write1, SyncPredFlag);
734 Yap_InitCPred(
"write", 2, write2, SyncPredFlag);
735 Yap_InitCPred(
"writeq", 1, writeq1, SyncPredFlag);
736 Yap_InitCPred(
"writeq", 2, writeq, SyncPredFlag);
737 Yap_InitCPred(
"writeln", 1, writeln1, SyncPredFlag);
738 Yap_InitCPred(
"writeln", 2, writeln, SyncPredFlag);
739 Yap_InitCPred(
"write_canonical", 1, write_canonical1, SyncPredFlag);
740 Yap_InitCPred(
"write_canonical", 2, write_canonical, SyncPredFlag);
741 Yap_InitCPred(
"display", 1, display1, SyncPredFlag);
742 Yap_InitCPred(
"display", 2, display, SyncPredFlag);
743 Yap_InitCPred(
"print", 1, print1, SyncPredFlag);
744 Yap_InitCPred(
"print", 2, print, SyncPredFlag);
745 Yap_InitCPred(
"write_depth", 3, p_write_depth, SafePredFlag | SyncPredFlag);
746 Yap_InitCPred(
"term_to_string", 2, term_to_string, 0);
747 Yap_InitCPred(
"term_to_atom", 2, term_to_atom, 0);
748 Yap_InitCPred(
"write_depth", 3, p_write_depth, SafePredFlag | SyncPredFlag);
750 Yap_InitCPred(
"current_dollar_var", 2, dollar_var, SafePredFlag);
int Yap_NumberVars(Term t, int numbv, bool handle_singles USES_REGS)
numbervariables in term t
Term Yap_read_term(int sno, Term opts, bool clause)
generic routine to read terms from a stream