diff --git a/BEAM/eam_am.c b/BEAM/eam_am.c index 4ed220d05..e02dc2e40 100644 --- a/BEAM/eam_am.c +++ b/BEAM/eam_am.c @@ -140,7 +140,7 @@ int showTime(void); struct AND_BOX *choose_leftmost(void); extern Cell BEAM_is(void); extern void do_eam_indexing(struct Predicates *); -extern void Yap_plwrite(Term, int (*mywrite) (int, int), int, int); +extern void Yap_plwrite(Term, void *, int, int); #if Debug_Dump_State void dump_eam_state(void); @@ -2511,7 +2511,7 @@ break_debug(contador); #endif #ifdef DEBUG - Yap_plwrite ((Term) beam_X[1], Yap_DebugPutc, 0, 1200); + Yap_plwrite ((Term) beam_X[1], NULL, 0, 1200); #else extern int beam_write (void); beam_write(); diff --git a/BEAM/toeam.c b/BEAM/toeam.c index ce016f5a8..96480aa61 100644 --- a/BEAM/toeam.c +++ b/BEAM/toeam.c @@ -742,10 +742,10 @@ void ShowCode_new2(int op, int new1,CELL new4) switch (ch = *f++) { case '1': - Yap_plwrite(MkIntTerm(new1), Yap_DebugPutc, 0, 1200); + Yap_plwrite(MkIntTerm(new1), NULL, 0, 1200); break; case '4': - Yap_plwrite(MkIntTerm(new4), Yap_DebugPutc, 0, 1200); + Yap_plwrite(MkIntTerm(new4), NULL, 0, 1200); break; default: Yap_DebugPutc (LOCAL_c_error_stream,'%'); diff --git a/C/iopreds.c b/C/iopreds.c index d42d56d55..a12603a80 100644 --- a/C/iopreds.c +++ b/C/iopreds.c @@ -199,7 +199,7 @@ Yap_DebugPutc(int sno, wchar_t ch) void Yap_DebugPlWrite(Term t) { - Yap_plwrite(t, Yap_DebugPutc, 0, 1200); + Yap_plwrite(t, NULL, 0, 1200); } void @@ -238,7 +238,7 @@ typedef struct stream_ref int beam_write (void) { Yap_StartSlots(); - Yap_plwrite (ARG1, Stream[LOCAL_c_output_stream].stream_wputc, 0, 1200); + Yap_plwrite (ARG1, NULL, 0, 1200); Yap_CloseSlots(); if (EX != 0L) { Term ball = Yap_PopTermFromDB(EX); diff --git a/C/tracer.c b/C/tracer.c index f2d80aaa1..6c7376451 100644 --- a/C/tracer.c +++ b/C/tracer.c @@ -26,17 +26,8 @@ #include "clause.h" #include "tracer.h" -STATIC_PROTO(int TracePutchar, (int, int)); STATIC_PROTO(void send_tracer_message, (char *, char *, Int, char *, CELL *)); - - -static int -TracePutchar(int sno, int ch) -{ - return(putc(ch, GLOBAL_stderr)); /* use standard error stream, which is supposed to be 2*/ -} - static void send_tracer_message(char *start, char *name, Int arity, char *mname, CELL *args) { @@ -66,7 +57,7 @@ send_tracer_message(char *start, char *name, Int arity, char *mname, CELL *args) Yap_Portray_delays = TRUE; #endif #endif - Yap_plwrite(args[i], TracePutchar, Handle_vars_f, 1200); + Yap_plwrite(args[i], NULL, Handle_vars_f, 1200); #if DEBUG #if COROUTINING Yap_Portray_delays = FALSE; diff --git a/C/write.c b/C/write.c index 23f44c607..754941a1c 100644 --- a/C/write.c +++ b/C/write.c @@ -45,7 +45,7 @@ typedef enum { static wtype lastw; -typedef int (*wrf) (int, wchar_t); +typedef void *wrf; typedef struct union_slots { Int old; @@ -67,10 +67,11 @@ typedef struct rewind_term { } rwts; typedef struct write_globs { - wrf writewch; + void *stream; int Quote_illegal, Ignore_ops, Handle_vars, Use_portray; int keep_terms; int Write_Loops; + int Write_strings; UInt MaxDepth, MaxArgs; } wglbs; @@ -85,20 +86,20 @@ STATIC_PROTO(wtype AtomIsSymbols, (unsigned char *)); STATIC_PROTO(void putAtom, (Atom, int, wrf)); STATIC_PROTO(void writeTerm, (Term, int, int, int, struct write_globs *, struct rewind_term *)); -#define wrputc(X,WF) ((*WF)(LOCAL_c_output_stream,X)) /* writes a character */ +#define wrputc(X,WF) Sputcode(X,WF) /* writes a character */ static void -wrputn(Int n, wrf writewch) /* writes an integer */ - +wrputn(Int n, wrf stream) /* writes an integer */ + { CACHE_REGS char s[256], *s1=s; /* that should be enough for most integers */ if (n < 0) { if (lastw == symbol) - wrputc(' ', writewch); + wrputc(' ', stream); } else { if (lastw == alphanum) - wrputc(' ', writewch); + wrputc(' ', stream); } #if HAVE_SNPRINTF snprintf(s, 256, Int_FORMAT, n); @@ -106,25 +107,18 @@ wrputn(Int n, wrf writewch) /* writes an integer */ sprintf(s, Int_FORMAT, n); #endif while (*s1) - wrputc(*s1++, writewch); + wrputc(*s1++, stream); lastw = alphanum; } -static void -wrputs(char *s, wrf writewch) /* writes a string */ -{ - CACHE_REGS - while (*s) { - wrputc((unsigned char)(*s++), writewch); - } -} +#define wrputs(s, stream) Sfputs(s, stream) static void -wrputws(wchar_t *s, wrf writewch) /* writes a string */ +wrputws(wchar_t *s, wrf stream) /* writes a string */ { CACHE_REGS while (*s) - wrputc(*s++, writewch); + wrputc(*s++, stream); } #ifdef USE_GMP @@ -168,27 +162,27 @@ ensure_space(size_t sz) { } static void -write_mpint(MP_INT *big, wrf writewch) { +write_mpint(MP_INT *big, wrf stream) { CACHE_REGS char *s; s = ensure_space(3+mpz_sizeinbase(big, 10)); if (mpz_sgn(big) < 0) { if (lastw == symbol) - wrputc(' ', writewch); + wrputc(' ', stream); } else { if (lastw == alphanum) - wrputc(' ', writewch); + wrputc(' ', stream); } if (!s) { s = mpz_get_str(NULL, 10, big); if (!s) return; - wrputs(s,writewch); + wrputs(s,stream); free(s); } else { mpz_get_str(s, 10, big); - wrputs(s,writewch); + wrputs(s,stream); } } #endif @@ -203,7 +197,7 @@ writebig(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, stru if (pt[0] == BIG_INT) { MP_INT *big = Yap_BigIntOfTerm(t); - write_mpint(big, wglb->writewch); + write_mpint(big, wglb->stream); return; } else if (pt[0] == BIG_RATIONAL) { Term trat = Yap_RatTermToApplTerm(t); @@ -212,103 +206,62 @@ writebig(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, stru } #endif if (pt[0] == BLOB_STRING) { - wrputc('"',wglb->writewch); - wrputs(Yap_BlobStringOfTerm(t),wglb->writewch); - wrputc('"',wglb->writewch); + if (wglb->Write_strings) + wrputc('`',wglb->stream); + else + wrputc('"',wglb->stream); + wrputs(Yap_BlobStringOfTerm(t),wglb->stream); + if (wglb->Write_strings) + wrputc('`',wglb->stream); + else + wrputc('"',wglb->stream); return; - } else if (pt[0] == BLOB_STRING) { + } else if (pt[0] == BLOB_WIDE_STRING) { wchar_t *s = Yap_BlobWideStringOfTerm(t); - wrputc('"', wglb->writewch); + if (wglb->Write_strings) + wrputc('`',wglb->stream); + else + wrputc('"', wglb->stream); while (*s) { - wrputc(*s++, wglb->writewch); + wrputc(*s++, wglb->stream); } - wrputc('"',wglb->writewch); + if (wglb->Write_strings) + wrputc('`',wglb->stream); + else + wrputc('"',wglb->stream); return; } - wrputs("0",wglb->writewch); + wrputs("0",wglb->stream); } static void -wrputf(Float f, wrf writewch) /* writes a float */ +wrputf(Float f, wrf stream) /* writes a float */ { + char *format_float(double f, char *buf); CACHE_REGS - char s[256], *pt = s, ch; - int found_dot = FALSE, found_exp = FALSE; + char s[256]; + char *buf; -#if HAVE_ISNAN || defined(__WIN32) - if (isnan(f)) { - wrputs("(nan)", writewch); - lastw = separator; - return; - } -#endif - if (f < 0) { -#if HAVE_ISINF || defined(_WIN32) - if (isinf(f)) { - wrputs("(-inf)", writewch); - lastw = separator; - return; - } -#endif - if (lastw == symbol) - wrputc(' ', writewch); - } else { -#if HAVE_ISINF || defined(_WIN32) - if (isinf(f)) { - wrputs("(+inf)", writewch); - lastw = separator; - return; - } -#endif - if (lastw == alphanum) - wrputc(' ', writewch); - } - lastw = alphanum; - // sprintf(s, "%.15g", f); - sprintf(s, RepAtom(AtomFloatFormat)->StrOfAE, f); - while (*pt == ' ') - pt++; - if (*pt == '-') { - wrputc('-', writewch); - pt++; - } - while ((ch = *pt) != '\0') { - switch (ch) { - case '.': - found_dot = TRUE; - wrputc('.', writewch); - break; - case 'e': - case 'E': - if (!found_dot) { - found_dot = TRUE; - wrputs(".0", writewch); - } - found_exp = TRUE; - default: - wrputc(ch, writewch); - } - pt++; - } - if (!found_dot) { - wrputs(".0", writewch); - } + /* use SWI's format_float */ + buf = format_float(f, s); + if (!buf) return; + wrputs(buf, stream); } static void -wrputref(CODEADDR ref, int Quote_illegal, wrf writewch) /* writes a data base reference */ +wrputref(CODEADDR ref, int Quote_illegal, wrf stream) /* writes a data base reference */ { char s[256]; - putAtom(AtomDBref, Quote_illegal, writewch); + putAtom(AtomDBref, Quote_illegal, stream); #if defined(__linux__) || defined(__APPLE__) sprintf(s, "(%p," UInt_FORMAT ")", ref, ((LogUpdClause*)ref)->ClRefCount); #else sprintf(s, "(0x%p," UInt_FORMAT ")", ref, ((LogUpdClause*)ref)->ClRefCount); #endif - wrputs(s, writewch); + wrputs(s, stream); lastw = alphanum; } @@ -361,55 +314,55 @@ AtomIsSymbols(unsigned char *s) /* Is this atom just formed by symbols ? */ } static void -write_quoted(int ch, int quote, wrf writewch) +write_quoted(int ch, int quote, wrf stream) { CACHE_REGS if (yap_flags[CHARACTER_ESCAPE_FLAG] == CPROLOG_CHARACTER_ESCAPES) { - wrputc(ch, writewch); + wrputc(ch, stream); if (ch == '\'') - wrputc('\'', writewch); /* be careful about quotes */ + wrputc('\'', stream); /* be careful about quotes */ return; } if (!(ch < 0xff && chtype(ch) == BS) && ch != '\'' && ch != '\\') { - wrputc(ch, writewch); + wrputc(ch, stream); } else { switch (ch) { case '\\': case '\'': - wrputc('\\', writewch); - wrputc(ch, writewch); + wrputc('\\', stream); + wrputc(ch, stream); break; case 7: - wrputc('\\', writewch); - wrputc('a', writewch); + wrputc('\\', stream); + wrputc('a', stream); break; case '\b': - wrputc('\\', writewch); - wrputc('b', writewch); + wrputc('\\', stream); + wrputc('b', stream); break; case '\t': - wrputc('\\', writewch); - wrputc('t', writewch); + wrputc('\\', stream); + wrputc('t', stream); break; case ' ': case 160: - wrputc(' ', writewch); + wrputc(' ', stream); break; case '\n': - wrputc('\\', writewch); - wrputc('n', writewch); + wrputc('\\', stream); + wrputc('n', stream); break; case 11: - wrputc('\\', writewch); - wrputc('v', writewch); + wrputc('\\', stream); + wrputc('v', stream); break; case '\r': - wrputc('\\', writewch); - wrputc('r', writewch); + wrputc('\\', stream); + wrputc('r', stream); break; case '\f': - wrputc('\\', writewch); - wrputc('f', writewch); + wrputc('\\', stream); + wrputc('f', stream); break; default: if ( ch <= 0xff ) { @@ -421,7 +374,7 @@ write_quoted(int ch, int quote, wrf writewch) /* last backslash in ISO mode */ sprintf(esc, "\\%03o\\", ch); } - wrputs(esc, writewch); + wrputs(esc, stream); } } } @@ -429,7 +382,7 @@ write_quoted(int ch, int quote, wrf writewch) static void -putAtom(Atom atom, int Quote_illegal, wrf writewch) /* writes an atom */ +putAtom(Atom atom, int Quote_illegal, wrf stream) /* writes an atom */ { CACHE_REGS @@ -441,41 +394,41 @@ putAtom(Atom atom, int Quote_illegal, wrf writewch) /* writes an atom */ if (Yap_GetValue(AtomCryptAtoms) != TermNil && Yap_GetAProp(atom, OpProperty) == NIL) { char s[16]; sprintf(s,"x%x", (CELL)s); - wrputs(s, writewch); + wrputs(s, stream); return; } #endif if (IsBlob(atom)) { - wrputref((CODEADDR)RepAtom(atom),1,writewch); + wrputref((CODEADDR)RepAtom(atom),1,stream); return; } if (IsWideAtom(atom)) { wchar_t *ws = (wchar_t *)s; if (Quote_illegal) { - wrputc('\'', writewch); + wrputc('\'', stream); while (*ws) { wchar_t ch = *ws++; - write_quoted(ch, '\'', writewch); + write_quoted(ch, '\'', stream); } - wrputc('\'', writewch); + wrputc('\'', stream); } else { - wrputws(ws, writewch); + wrputws(ws, stream); } return; } if (lastw == atom_or_symbol && atom_or_symbol != separator /* solo */) - wrputc(' ', writewch); + wrputc(' ', stream); lastw = atom_or_symbol; if (Quote_illegal && !legalAtom(s)) { - wrputc('\'', writewch); + wrputc('\'', stream); while (*s) { wchar_t ch = *s++; - write_quoted(ch, '\'', writewch); + write_quoted(ch, '\'', stream); } - wrputc('\'', writewch); + wrputc('\'', stream); } else { - wrputs((char *)s, writewch); + wrputs((char *)s, stream); } } @@ -502,28 +455,28 @@ IsStringTerm(Term string) /* checks whether this is a string */ } static void -putString(Term string, wrf writewch) /* writes a string */ +putString(Term string, wrf stream) /* writes a string */ { CACHE_REGS - wrputc('"', writewch); + wrputc('"', stream); while (string != TermNil) { int ch = IntOfTerm(HeadOfTerm(string)); - write_quoted(ch, '"', writewch); + write_quoted(ch, '"', stream); string = TailOfTerm(string); } - wrputc('"', writewch); + wrputc('"', stream); lastw = alphanum; } static void -putUnquotedString(Term string, wrf writewch) /* writes a string */ +putUnquotedString(Term string, wrf stream) /* writes a string */ { CACHE_REGS while (string != TermNil) { int ch = IntOfTerm(HeadOfTerm(string)); - wrputc(ch, writewch); + wrputc(ch, stream); string = TailOfTerm(string); } lastw = alphanum; @@ -535,9 +488,9 @@ write_var(CELL *t, struct write_globs *wglb, struct rewind_term *rwt) { CACHE_REGS if (lastw == alphanum) { - wrputc(' ', wglb->writewch); + wrputc(' ', wglb->stream); } - wrputc('_', wglb->writewch); + wrputc('_', wglb->stream); /* make sure we don't get no creepy spaces where they shouldn't be */ lastw = separator; if (IsAttVar(t)) { @@ -553,31 +506,31 @@ write_var(CELL *t, struct write_globs *wglb, struct rewind_term *rwt) Int sl = 0; Term l = attv->Atts; - wrputs("$AT(",wglb->writewch); + wrputs("$AT(",wglb->stream); write_var(t, wglb, rwt); - wrputc(',', wglb->writewch); + wrputc(',', wglb->stream); if (wglb->keep_terms) { /* garbage collection may be called */ sl = Yap_InitSlot((CELL)attv PASS_REGS); } writeTerm((Term)&(attv->Value), 999, 1, FALSE, wglb, rwt); - wrputc(',', wglb->writewch); + wrputc(',', wglb->stream); writeTerm(l, 999, 1, FALSE, wglb, rwt); if (wglb->keep_terms) { attv = (attvar_record *)Yap_GetFromSlot(sl PASS_REGS); Yap_RecoverSlots(1 PASS_REGS); } - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); } Yap_Portray_delays = TRUE; return; } #endif - wrputc('D', wglb->writewch); - wrputn(vcount,wglb->writewch); + wrputc('D', wglb->stream); + wrputn(vcount,wglb->stream); #endif } else { - wrputn(((Int) (t- H0)),wglb->writewch); + wrputn(((Int) (t- H0)),wglb->stream); } } @@ -689,16 +642,16 @@ write_list(Term t, int direction, int depth, struct write_globs *wglb, struct re if (ndirection > 0) { do_jump = (direction <= 0); } else if (ndirection == 0) { - wrputc(',', wglb->writewch); - putAtom(AtomFoundVar, wglb->Quote_illegal, wglb->writewch); + wrputc(',', wglb->stream); + putAtom(AtomFoundVar, wglb->Quote_illegal, wglb->stream); lastw = separator; return; } else { do_jump = (direction >= 0); } if (wglb->MaxDepth != 0 && depth > wglb->MaxDepth) { - wrputc('|', wglb->writewch); - putAtom(Atom3Dots, wglb->Quote_illegal, wglb->writewch); + wrputc('|', wglb->stream); + putAtom(Atom3Dots, wglb->Quote_illegal, wglb->stream); return; } lastw = separator; @@ -706,23 +659,23 @@ write_list(Term t, int direction, int depth, struct write_globs *wglb, struct re depth++; if (do_jump) break; - wrputc(',', wglb->writewch); + wrputc(',', wglb->stream); t = ti; } if (IsPairTerm(ti)) { Term nt = from_pointer(RepPair(t)+1, &nrwt, wglb); /* we found an infinite loop */ if (IsAtomTerm(nt)) { - wrputc('|', wglb->writewch); + wrputc('|', wglb->stream); writeTerm(nt, 999, depth, FALSE, wglb, rwt); } else { /* keep going on the list */ - wrputc(',', wglb->writewch); + wrputc(',', wglb->stream); write_list(nt, direction, depth, wglb, &nrwt); } restore_from_write(&nrwt, wglb); } else if (ti != MkAtomTerm(AtomNil)) { - wrputc('|', wglb->writewch); + wrputc('|', wglb->stream); lastw = separator; writeTerm(from_pointer(RepPair(t)+1, &nrwt, wglb), 999, depth, FALSE, wglb, &nrwt); restore_from_write(&nrwt, wglb); @@ -741,7 +694,7 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str nrwt.u.s.ptr = 0; if (wglb->MaxDepth != 0 && depth > wglb->MaxDepth) { - putAtom(Atom3Dots, wglb->Quote_illegal, wglb->writewch); + putAtom(Atom3Dots, wglb->Quote_illegal, wglb->stream); return; } if (EX) @@ -750,14 +703,14 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str if (IsVarTerm(t)) { write_var((CELL *)t, wglb, &nrwt); } else if (IsIntTerm(t)) { - wrputn((Int) IntOfTerm(t),wglb->writewch); + wrputn((Int) IntOfTerm(t),wglb->stream); } else if (IsAtomTerm(t)) { - putAtom(AtomOfTerm(t), wglb->Quote_illegal, wglb->writewch); + putAtom(AtomOfTerm(t), wglb->Quote_illegal, wglb->stream); } else if (IsPairTerm(t)) { if (wglb->Ignore_ops) { Int sl = 0; - wrputs("'.'(",wglb->writewch); + wrputs("'.'(",wglb->stream); lastw = separator; if (wglb->keep_terms) { /* garbage collection may be called */ @@ -770,7 +723,7 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str t = Yap_GetFromSlot(sl PASS_REGS); Yap_RecoverSlots(1 PASS_REGS); } - wrputs(",",wglb->writewch); + wrputs(",",wglb->stream); if (wglb->keep_terms) { /* garbage collection may be called */ sl = Yap_InitSlot(t PASS_REGS); @@ -782,7 +735,7 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str t = Yap_GetFromSlot(sl PASS_REGS); Yap_RecoverSlots(1 PASS_REGS); } - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; return; } @@ -803,13 +756,13 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str return; } if (yap_flags[WRITE_QUOTED_STRING_FLAG] && IsStringTerm(t)) { - putString(t, wglb->writewch); + putString(t, wglb->stream); } else { - wrputc('[', wglb->writewch); + wrputc('[', wglb->stream); lastw = separator; /* we assume t was already saved in the stack */ write_list(t, 0, depth, wglb, rwt); - wrputc(']', wglb->writewch); + wrputc(']', wglb->stream); lastw = separator; } } else { /* compound term */ @@ -821,16 +774,16 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str if (IsExtensionFunctor(functor)) { switch((CELL)functor) { case (CELL)FunctorDouble: - wrputf(FloatOfTerm(t),wglb->writewch); + wrputf(FloatOfTerm(t),wglb->stream); return; case (CELL)FunctorAttVar: write_var(RepAppl(t)+1, wglb, &nrwt); return; case (CELL)FunctorDBRef: - wrputref(RefOfTerm(t), wglb->Quote_illegal, wglb->writewch); + wrputref(RefOfTerm(t), wglb->Quote_illegal, wglb->stream); return; case (CELL)FunctorLongInt: - wrputn(LongIntOfTerm(t),wglb->writewch); + wrputn(LongIntOfTerm(t),wglb->stream); return; /* case (CELL)FunctorBigInt: */ default: @@ -844,14 +797,14 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str if (Arity == SFArity) { int argno = 1; CELL *p = ArgsOfSFTerm(t); - putAtom(atom, wglb->Quote_illegal, wglb->writewch); - wrputc('(', wglb->writewch); + putAtom(atom, wglb->Quote_illegal, wglb->stream); + wrputc('(', wglb->stream); lastw = separator; while (*p) { Int sl = 0; while (argno < *p) { - wrputc('_', wglb->writewch), wrputc(',', wglb->writewch); + wrputc('_', wglb->stream), wrputc(',', wglb->stream); ++argno; } *p++; @@ -869,10 +822,10 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str Yap_RecoverSlots(1); } if (*p) - wrputc(',', wglb->writewch); + wrputc(',', wglb->stream); argno++; } - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; return; } @@ -911,23 +864,23 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str if (op > p) { /* avoid stuff such as \+ (a,b) being written as \+(a,b) */ if (lastw != separator && !rinfixarg) - wrputc(' ', wglb->writewch); - wrputc('(', wglb->writewch); + wrputc(' ', wglb->stream); + wrputc('(', wglb->stream); lastw = separator; } - putAtom(atom, wglb->Quote_illegal, wglb->writewch); + putAtom(atom, wglb->Quote_illegal, wglb->stream); if (bracket_right) { - wrputc('(', wglb->writewch); + wrputc('(', wglb->stream); lastw = separator; } writeTerm(from_pointer(RepAppl(t)+1, &nrwt, wglb), rp, depth + 1, FALSE, wglb, &nrwt); restore_from_write(&nrwt, wglb); if (bracket_right) { - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } if (op > p) { - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } } else if (!wglb->Ignore_ops && @@ -941,12 +894,12 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str if (op > p) { /* avoid stuff such as \+ (a,b) being written as \+(a,b) */ if (lastw != separator && !rinfixarg) - wrputc(' ', wglb->writewch); - wrputc('(', wglb->writewch); + wrputc(' ', wglb->stream); + wrputc('(', wglb->stream); lastw = separator; } if (bracket_left) { - wrputc('(', wglb->writewch); + wrputc('(', wglb->stream); lastw = separator; } if (wglb->keep_terms) { @@ -961,12 +914,12 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str Yap_RecoverSlots(1 PASS_REGS); } if (bracket_left) { - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } - putAtom(atom, wglb->Quote_illegal, wglb->writewch); + putAtom(atom, wglb->Quote_illegal, wglb->stream); if (op > p) { - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } } else if (!wglb->Ignore_ops && @@ -985,12 +938,12 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str if (op > p) { /* avoid stuff such as \+ (a,b) being written as \+(a,b) */ if (lastw != separator && !rinfixarg) - wrputc(' ', wglb->writewch); - wrputc('(', wglb->writewch); + wrputc(' ', wglb->stream); + wrputc('(', wglb->stream); lastw = separator; } if (bracket_left) { - wrputc('(', wglb->writewch); + wrputc('(', wglb->stream); lastw = separator; } if (wglb->keep_terms) { @@ -1005,58 +958,58 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str Yap_RecoverSlots(1 PASS_REGS); } if (bracket_left) { - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } /* avoid quoting commas */ if (strcmp(RepAtom(atom)->StrOfAE,",")) - putAtom(atom, wglb->Quote_illegal, wglb->writewch); + putAtom(atom, wglb->Quote_illegal, wglb->stream); else { - wrputc(',', wglb->writewch); + wrputc(',', wglb->stream); lastw = separator; } if (bracket_right) { - wrputc('(', wglb->writewch); + wrputc('(', wglb->stream); lastw = separator; } writeTerm(from_pointer(RepAppl(t)+2, &nrwt, wglb), rp, depth + 1, TRUE, wglb, &nrwt); restore_from_write(&nrwt, wglb); if (bracket_right) { - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } if (op > p) { - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } } else if (wglb->Handle_vars && functor == FunctorVar) { Term ti = ArgOfTerm(1, t); if (lastw == alphanum) { - wrputc(' ', wglb->writewch); + wrputc(' ', wglb->stream); } if (!IsVarTerm(ti) && (IsIntTerm(ti) || IsStringTerm(ti))) { if (IsIntTerm(ti)) { Int k = IntOfTerm(ti); if (k == -1) { - wrputc('_', wglb->writewch); + wrputc('_', wglb->stream); lastw = alphanum; return; } else { - wrputc((k % 26) + 'A', wglb->writewch); + wrputc((k % 26) + 'A', wglb->stream); if (k >= 26) { /* make sure we don't get confused about our context */ lastw = separator; - wrputn( k / 26 ,wglb->writewch); + wrputn( k / 26 ,wglb->stream); } else lastw = alphanum; } } else { - putUnquotedString(ti, wglb->writewch); + putUnquotedString(ti, wglb->stream); } } else { Int sl = 0; - wrputs("'$VAR'(",wglb->writewch); + wrputs("'$VAR'(",wglb->stream); lastw = separator; if (wglb->keep_terms) { /* garbage collection may be called */ @@ -1069,26 +1022,24 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str t = Yap_GetFromSlot(sl PASS_REGS); Yap_RecoverSlots(1 PASS_REGS); } - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } } else if (!wglb->Ignore_ops && functor == FunctorBraces) { - wrputc('{', wglb->writewch); + wrputc('{', wglb->stream); lastw = separator; writeTerm(from_pointer(RepAppl(t)+1, &nrwt, wglb), 1200, depth + 1, FALSE, wglb, &nrwt); restore_from_write(&nrwt, wglb); - wrputc('}', wglb->writewch); + wrputc('}', wglb->stream); lastw = separator; } else if (atom == AtomArray) { Int sl = 0; - wrputc('{', wglb->writewch); + wrputc('{', wglb->stream); lastw = separator; for (op = 1; op <= Arity; ++op) { if (op == wglb->MaxArgs) { - wrputc('.', wglb->writewch); - wrputc('.', wglb->writewch); - wrputc('.', wglb->writewch); + wrputs('...', wglb->stream); break; } if (wglb->keep_terms) { @@ -1103,23 +1054,23 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str Yap_RecoverSlots(1 PASS_REGS); } if (op != Arity) { - wrputc(',', wglb->writewch); + wrputc(',', wglb->stream); lastw = separator; } } - wrputc('}', wglb->writewch); + wrputc('}', wglb->stream); lastw = separator; } else { - putAtom(atom, wglb->Quote_illegal, wglb->writewch); + putAtom(atom, wglb->Quote_illegal, wglb->stream); lastw = separator; - wrputc('(', wglb->writewch); + wrputc('(', wglb->stream); for (op = 1; op <= Arity; ++op) { Int sl = 0; if (op == wglb->MaxArgs) { - wrputc('.', wglb->writewch); - wrputc('.', wglb->writewch); - wrputc('.', wglb->writewch); + wrputc('.', wglb->stream); + wrputc('.', wglb->stream); + wrputc('.', wglb->stream); break; } if (wglb->keep_terms) { @@ -1134,18 +1085,18 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str Yap_RecoverSlots(1 PASS_REGS); } if (op != Arity) { - wrputc(',', wglb->writewch); + wrputc(',', wglb->stream); lastw = separator; } } - wrputc(')', wglb->writewch); + wrputc(')', wglb->stream); lastw = separator; } } } void -Yap_plwrite(Term t, int (*mywrite) (int, wchar_t), int flags, int priority) +Yap_plwrite(Term t, void *mywrite, int flags, int priority) /* term to be written */ /* consumer */ /* write options */ @@ -1153,19 +1104,24 @@ Yap_plwrite(Term t, int (*mywrite) (int, wchar_t), int flags, int priority) struct write_globs wglb; struct rewind_term rwt; - wglb.writewch = mywrite; + if (!mywrite) + wglb.stream = Serror; + else + wglb.stream = mywrite; + lastw = separator; wglb.Quote_illegal = flags & Quote_illegal_f; wglb.Handle_vars = flags & Handle_vars_f; wglb.Use_portray = flags & Use_portray_f; wglb.MaxDepth = 15L; - wglb.MaxArgs = 15L; + wglb.MaxArgs = 60L; /* notice: we must have ASP well set when using portray, otherwise we cannot make recursive Prolog calls */ wglb.keep_terms = (flags & (Use_portray_f|To_heap_f)); /* initialise wglb */ rwt.parent = NULL; wglb.Ignore_ops = flags & Ignore_ops_f; + wglb.Write_strings = flags & BackQuote_String_f; /* protect slots for portray */ writeTerm(from_pointer(&t, &rwt, &wglb), priority, 1, FALSE, &wglb, &rwt); restore_from_write(&rwt, &wglb); diff --git a/H/Yapproto.h b/H/Yapproto.h index 43e55867c..7049d290f 100644 --- a/H/Yapproto.h +++ b/H/Yapproto.h @@ -406,7 +406,7 @@ Int STD_PROTO(Yap_SkipList,(Term *, Term **)); /* write.c */ -void STD_PROTO(Yap_plwrite,(Term,int (*)(int, wchar_t), int, int)); +void STD_PROTO(Yap_plwrite,(Term, void *, int, int)); /* MYDDAS */ diff --git a/H/pl-yap.h b/H/pl-yap.h index b474639f2..34f98ec14 100644 --- a/H/pl-yap.h +++ b/H/pl-yap.h @@ -148,7 +148,7 @@ atomLength(Atom atom) #define MODULE_user YAP_ModuleUser() #define _PL_predicate(A,B,C,D) PL_predicate(A,B,C) #define predicateHasClauses(A) (YAP_NumberOfClausesForPredicate((YAP_PredEntryPtr)A) != 0) -#define lookupModule(A) ((Module)PL_new_module(A)) +#define lookupModule(A) Yap_Module(MkAtomTerm(YAP_AtomFromSWIAtom(A))) #define charEscapeWriteOption(A) FALSE // VSC: to implement #define wordToTermRef(A) YAP_InitSlot(*(A)) #define isTaggedInt(A) IsIntegerTerm(A) diff --git a/H/yapio.h b/H/yapio.h index 1b2f0abd8..b5f2a8124 100644 --- a/H/yapio.h +++ b/H/yapio.h @@ -194,6 +194,8 @@ typedef struct VARSTRUCT { } VarEntry; */ +#ifndef _PL_WRITE_ + /* Character types for tokenizer and write.c */ #define UC 1 /* Upper case */ @@ -211,6 +213,7 @@ typedef struct VARSTRUCT { #define EOFCHAR EOF +#endif /* info on aliases */ typedef struct AliasDescS { @@ -300,6 +303,11 @@ Atom STD_PROTO(Yap_LookupWideAtom,(wchar_t *)); #define To_heap_f 0x10 #define Unfold_cyclics_f 0x20 #define Use_SWI_Stream_f 0x40 +#define BackQuote_String_f 0x80 +#define AttVar_None_f 0x100 +#define AttVar_Dots_f 0x200 +#define AttVar_Portray_f 0x400 +#define Blob_Portray_f 0x800 diff --git a/os/pl-write.c b/os/pl-write.c index 230663ffb..34b1e6a5e 100644 --- a/os/pl-write.c +++ b/os/pl-write.c @@ -42,6 +42,14 @@ #define HAVE_FPCLASSIFY 1 #endif +#if __YAP_PROLOG__ + +#define _PL_WRITE_ 1 + +#include "yapio.h" + +#endif + typedef struct visited { Word address; /* we have done this address */ struct visited *next; /* next already visited */ @@ -52,666 +60,27 @@ typedef struct int max_depth; /* depth limit */ int depth; /* current depth */ atom_t spacing; /* Where to insert spaces */ - Module module; /* Module for operators */ + Term module; /* Module for operators */ IOSTREAM *out; /* stream to write to */ visited *visited; /* visited (attributed-) variables */ } write_options; -static bool writeTerm2(term_t term, int prec, - write_options *options, bool arg) WUNUSED; -static bool writeTerm(term_t t, int prec, - write_options *options) WUNUSED; -static bool writeArgTerm(term_t t, int prec, - write_options *options, bool arg) WUNUSED; +word +pl_nl1(term_t stream) +{ IOSTREAM *s; -#if __YAP_PROLOG__ -static Word -address_of(term_t t) -{ - return YAP_AddressFromSlot(t); /* non-recursive structure */ -} -#else -static Word -address_of(term_t t) -{ GET_LD - Word adr = valTermRef(t); - - deRef(adr); - switch(tag(*adr)) - { case TAG_ATTVAR: - return adr; - case TAG_COMPOUND: - return valPtr(*adr); - default: - return NULL; /* non-recursive structure */ - } -} -#endif - - -static int -has_visited(visited *v, Word addr) -{ for( ; v; v=v->next ) - { if ( v->address == addr ) - succeed; + if ( getOutputStream(stream, &s) ) + { Sputcode('\n', s); + return streamStatus(s); } fail; } - -char * -varName(term_t t, char *name) -#if __YAP_PROLOG__ -{ - YAP_Int adr = YAP_VarSlotToNumber(t); - - if (adr < 0) - Ssprintf(name, "_L%ld", -adr); - else - Ssprintf(name, "_G%ld", adr); - - return name; +word +pl_nl(void) +{ return pl_nl1(0); } -#else -{ GET_LD - Word adr = valTermRef(t); - - deRef(adr); - - if (adr > (Word) lBase) - Ssprintf(name, "_L%ld", (Word)adr - (Word)lBase); - else - Ssprintf(name, "_G%ld", (Word)adr - (Word)gBase); - - return name; -} -#endif - - -#define AT_LOWER 0 -#define AT_QUOTE 1 -#define AT_FULLSTOP 2 -#define AT_SYMBOL 3 -#define AT_SOLO 4 -#define AT_SPECIAL 5 - -/* Note: this only deals with ISO Latin-1 atoms; wide atoms are handled - by writeUCSAtom() -*/ - -static int -atomType(atom_t a, IOSTREAM *fd) -{ Atom atom = atomValue(a); - char *s = atomName(atom); - size_t len = atomLength(atom); - - if ( len == 0 ) - return AT_QUOTE; - - if ( isLower(*s) ) - { for(++s; --len > 0 && isAlpha(*s) && Scanrepresent(*s, fd)==0; s++) - ; - return len == 0 ? AT_LOWER : AT_QUOTE; - } - - if ( a == ATOM_dot ) - return AT_FULLSTOP; - - if ( isSymbol(*s) ) - { if ( len >= 2 && s[0] == '/' && s[1] == '*' ) - return AT_QUOTE; - - for(++s; --len > 0 && isSymbol(*s) && Scanrepresent(*s, fd)==0; s++) - ; - - return len == 0 ? AT_SYMBOL : AT_QUOTE; - } - - /* % should be quoted! */ - if ( len == 1 && *s != '%' ) - { if ( isSolo(*s) ) - return AT_SOLO; - } - - if ( a == ATOM_nil || a == ATOM_curl ) - return AT_SPECIAL; - - return AT_QUOTE; -} - - - /******************************* - * PRIMITIVE WRITES * - *******************************/ - -#define TRUE_WITH_SPACE 2 /* OK, and emitted leading space before token */ - -static bool -Putc(int c, IOSTREAM *s) -{ return Sputcode(c, s) == EOF ? FALSE : TRUE; -} - - -static bool -PutString(const char *str, IOSTREAM *s) -{ const unsigned char *q = (const unsigned char *)str; - - for( ; *q != EOS; q++ ) - { if ( Sputcode(*q, s) == EOF ) - return FALSE; - } - - return TRUE; -} - - -static bool -PutComma(write_options *options) -{ if ( options->spacing == ATOM_next_argument ) - return PutString(", ", options->out); - else - return PutString(",", options->out); -} - - -static bool -PutStringN(const char *str, size_t length, IOSTREAM *s) -{ size_t i; - const unsigned char *q = (const unsigned char *)str; - - for(i=0; ilastc = EOF; - return FALSE; - } else if ( s->lastc != EOF && - ((isAlphaW(s->lastc) && isAlphaW(c)) || - (isSymbolW(s->lastc) && isSymbolW(c)) || - (s->lastc != '(' && !isBlank(s->lastc) && c == '(') || - (c == '\'' && isDigit(s->lastc))) ) - { return TRUE; - } - - return FALSE; -} - - -static int -PutOpenToken(int c, IOSTREAM *s) -{ if ( needSpace(c, s) ) - { TRY(Putc(' ', s)); - return TRUE_WITH_SPACE; - } - - return TRUE; -} - - -static int -PutToken(const char *s, IOSTREAM *stream) -{ if ( s[0] ) - { int rc; - - TRY(rc=PutOpenToken(s[0]&0xff, stream)); - TRY(PutString(s, stream)); - - return rc; - } - - return TRUE; -} - -static int -PutTokenN(const char *s, size_t len, IOSTREAM *stream) -{ if ( len > 0 ) - { int rc; - - TRY(rc=PutOpenToken(s[0]&0xff, stream)); - TRY(PutStringN(s, len, stream)); - - return rc; - } - - return TRUE; -} - -#if __YAP_PROLOG__ -static bool -PutWideStringN(const wchar_t *str, size_t length, IOSTREAM *s) -{ size_t i; - const wchar_t *q = (const wchar_t *)str; - - for(i=0; i 0 ) - { int rc; - - TRY(rc=PutOpenToken(s[0]&0xff, stream)); - TRY(PutWideStringN(s, len, stream)); - - return rc; - } - - return TRUE; -} - -#endif - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PutOpenBrace()/PutCloseBrace() are used to put additional braces around -a term to avoid an operator precedence problem. If the last emitted -character is alphanumerical, there should be a space before the -openbrace to avoid interpretation as a term. E.g. not (a,b) instead of -not(a,b). Reported by Stefan.Mueller@dfki.de. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -static int -PutOpenBrace(IOSTREAM *s) -{ int rc; - - TRY(rc=PutOpenToken('(', s)); - TRY(Putc('(', s)); - - return rc; -} - - -static bool -PutCloseBrace(IOSTREAM *s) -{ return Putc(')', s); -} - - -static bool -putQuoted(int c, int quote, int flags, IOSTREAM *stream) -{ if ( (flags & PL_WRT_CHARESCAPES) ) - { if ( !(c < 0xff && isControl(c)) && c != quote && c != '\\' ) - { TRY(Putc(c, stream)); - } else - { char esc[8]; - - esc[1] = EOS; - - if ( c == quote ) - { esc[0] = c; - } else - { switch(c) - { case 7: - esc[0] = 'a'; - break; - case '\b': - esc[0] = 'b'; - break; - case '\t': - esc[0] = 't'; - break; - case '\n': - esc[0] = 'n'; - break; - case 11: - esc[0] = 'v'; - break; - case '\r': - esc[0] = 'r'; - break; - case '\f': - esc[0] = 'f'; - break; - case '\\': - esc[0] = '\\'; - break; - default: - if ( c <= 0xff ) - Ssprintf(esc, "%03o\\", c); - else - assert(0); /* to be done */ - } - } - if ( !Putc('\\', stream) || - !PutString(esc, stream) ) - fail; - } - } else - { if ( !Putc(c, stream) ) - fail; - if ( c == quote || c == '\\' ) /* write '' or \\ */ - { if ( !Putc(c, stream) ) - fail; - } - } - - return TRUE; -} - - - -static bool -writeQuoted(IOSTREAM *stream, const char *text, size_t len, int quote, - write_options *options) -{ const unsigned char *s = (const unsigned char *)text; - - TRY(Putc(quote, stream)); - - while(len-- > 0) - { TRY(putQuoted(*s++, quote, options->flags, stream)); - } - - return Putc(quote, stream); -} - - -#if O_ATTVAR -static bool -writeAttVar(term_t av, write_options *options) -{ GET_LD - char buf[32]; - - TRY(PutToken(varName(av, buf), options->out)); - - if ( (options->flags & PL_WRT_ATTVAR_DOTS) ) - { return PutString("{...}", options->out); - } else if ( (options->flags & PL_WRT_ATTVAR_WRITE) ) - { fid_t fid; - term_t a; - visited v; - - if ( !(fid = PL_open_foreign_frame()) ) - return FALSE; - - v.address = address_of(av); - if ( has_visited(options->visited, v.address) ) - succeed; - v.next = options->visited; - options->visited = &v; - Sputcode('{', options->out); - a = PL_new_term_ref(); - PL_get_attr__LD(av, a PASS_LD); - if ( !writeTerm(a, 1200, options) ) - goto error; - Sputcode('}', options->out); - PL_discard_foreign_frame(fid); - - options->visited = v.next; - succeed; - - error: - options->visited = v.next; - fail; - } else if ( (options->flags & PL_WRT_ATTVAR_PORTRAY) && - GD->cleaning <= CLN_PROLOG ) - { fid_t fid; - predicate_t pred; - IOSTREAM *old; - - if ( !(fid = PL_open_foreign_frame()) ) - return FALSE; - - pred = _PL_predicate("portray_attvar", 1, "$attvar", - &GD->procedures.portray_attvar1); - - old = Scurout; - Scurout = options->out; - PL_call_predicate(NULL, PL_Q_NODEBUG, pred, av); - Scurout = old; - - PL_discard_foreign_frame(fid); - } - - succeed; -} -#endif - - -static bool -writeBlob(atom_t a, write_options *options) -{ Atom atom = atomValue(a); - unsigned char const *s, *e; - - TRY(PutString("<#", options->out)); - s = (unsigned char const *)atomName(atom); - for (e = s + atomLength(atom); s != e; s++) - { static char *digits = "0123456789abcdef"; - - TRY(Putc(digits[(*s >> 4) & 0xf], options->out)); - TRY(Putc(digits[(*s ) & 0xf], options->out)); - } - - return PutString(">", options->out); -} - - -static int /* FALSE, TRUE or TRUE_WITH_SPACE */ -writeAtom(atom_t a, write_options *options) -{ Atom atom = atomValue(a); - - if ( (options->flags & PL_WRT_BLOB_PORTRAY) && - false(atomBlobType(atom), PL_BLOB_TEXT) && - GD->cleaning <= CLN_PROLOG ) - { GET_LD - int rc; - fid_t fid; - predicate_t pred; - IOSTREAM *old; - term_t av; - - if ( !(fid = PL_open_foreign_frame()) ) - return FALSE; - av = PL_new_term_ref(); - PL_put_atom(av, a); - - pred = _PL_predicate("portray", 1, "user", - &GD->procedures.portray); - - old = Scurout; - Scurout = options->out; - rc = PL_call_predicate(NULL, PL_Q_NODEBUG, pred, av); - Scurout = old; - - PL_discard_foreign_frame(fid); - if ( rc == TRUE ) - return TRUE; - } - - if ( atomBlobType(atom)->write ) - return (*atomBlobType(atom)->write)(options->out, a, options->flags); - if ( false(atomBlobType(atom), PL_BLOB_TEXT) ) - return writeBlob(a, options); -#if __YAP_PROLOG__ - if (isWideAtom(atom)) { - return writeUCSAtom(options->out, a, options->flags); - } -#endif - - if ( true(options, PL_WRT_QUOTED) ) - { switch( atomType(a, options->out) ) - { case AT_LOWER: - case AT_SYMBOL: - case AT_SOLO: - case AT_SPECIAL: - return PutToken(nameOfAtom(atom), options->out); - case AT_QUOTE: - case AT_FULLSTOP: - default: - { int rc; - - TRY(rc=PutOpenToken('\'', options->out)); - TRY(writeQuoted(options->out, - nameOfAtom(atom), - atomLength(atom), - '\'', options)); - return rc; - } - } - } else { - return PutTokenN(nameOfAtom(atom), atomLength(atom), options->out); - } -} - - -int -writeAtomToStream(IOSTREAM *s, atom_t atom) -{ write_options options; - - memset(&options, 0, sizeof(options)); - options.out = s; - options.module = MODULE_user; - - return writeAtom(atom, &options); -} - - -int -writeUCSAtom(IOSTREAM *fd, atom_t atom, int flags) -{ Atom a = atomValue(atom); - pl_wchar_t *s = (pl_wchar_t*)atomName(a); - size_t len = atomLength(a)/sizeof(pl_wchar_t); - pl_wchar_t *e = &s[len]; - - if ( flags & PL_WRT_QUOTED ) - { pl_wchar_t quote = L'\''; - int rc; - - if ( isLowerW(*s) ) - { pl_wchar_t *q; - - for(q=s; qencoding) - { case ENC_ISO_LATIN_1: - return t->text.t[index]&0xff; - case ENC_WCHAR: - return t->text.w[index]; - default: - assert(0); - return 0; - } -} - - -static int -writeString(term_t t, write_options *options) -{ GET_LD - PL_chars_t txt; - - PL_get_text(t, &txt, CVT_STRING); - - if ( true(options, PL_WRT_QUOTED) ) - { int quote; - unsigned int i; - - if ( true(options, PL_WRT_BACKQUOTED_STRING) ) - quote = '`'; - else - quote = '"'; - - TRY(Putc(quote, options->out)); - - for(i=0; iflags, options->out)); - } - - return Putc(quote, options->out); - } else - { unsigned int i; - - for(i=0; iout)); - } - } - - succeed; -} - -#endif /*O_STRING*/ - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Formatting a float. This used to use sprintf(), but there are two @@ -797,525 +166,56 @@ format_float(double f, char *buf) } -static bool -WriteNumber(Number n, write_options *options) -{ GET_LD +char * +varName(term_t t, char *name) +{ CELL *adr = (CELL *)Yap_GetFromSlot(t); - switch(n->type) - { case V_INTEGER: - { char buf[32]; - - sprintf(buf, INT64_FORMAT, n->value.i); - return PutToken(buf, options->out); - } -#ifdef O_GMP - case V_MPZ: - { char tmp[1024]; - char *buf; - size_t sz = mpz_sizeinbase(n->value.mpz, 10) + 2; - bool rc; - - if ( sz <= sizeof(tmp) ) - buf = tmp; - else - buf = PL_malloc(sz); - - /* mpz_get_str() can perform large intermediate allocations :-( */ - EXCEPTION_GUARDED({ LD->gmp.persistent++; - mpz_get_str(buf, 10, n->value.mpz); - LD->gmp.persistent--; - }, - { LD->gmp.persistent--; - rc = PL_rethrow(); - }) - rc = PutToken(buf, options->out); - if ( buf != tmp ) - PL_free(buf); - - return rc; - } - case V_MPQ: /* should not get here */ -#endif - case V_FLOAT: - assert(0); + if (IsAttVar(adr)) { + Ssprintf(name, "_D%ld", (CELL)adr - (CELL)H0); + } else { + Ssprintf(name, "_%ld", (CELL)adr - (CELL)H0); } - fail; + return name; } - -static bool -writePrimitive(term_t t, write_options *options) -{ GET_LD - double f; - atom_t a; - char buf[32]; - IOSTREAM *out = options->out; - -#if O_ATTVAR - if ( PL_is_attvar(t) ) - return writeAttVar(t, options); -#endif - - if ( PL_is_variable(t) ) - return PutToken(varName(t, buf), out); - - if ( PL_get_atom(t, &a) ) - return writeAtom(a, options); - - if ( PL_is_integer(t) ) /* beware of automatic conversion */ - { number n; - - PL_get_number(t, &n); - - return WriteNumber(&n, options); - } - - if ( PL_get_float(t, &f) ) - { char *s = NULL; - -#ifdef HAVE_FPCLASSIFY - switch(fpclassify(f)) - { case FP_NAN: - s = (true(options, PL_WRT_QUOTED) ? "'$NaN'" : "NaN"); - break; - case FP_INFINITE: - s = (true(options, PL_WRT_QUOTED) ? "'$Infinity'" : "Infinity"); - break; - } -#else -#ifdef HAVE_FPCLASS - switch(fpclass(f)) - { case FP_SNAN: - case FP_QNAN: - s = (true(options, PL_WRT_QUOTED) ? "'$NaN'" : "NaN"); - break; - case FP_NINF: - case FP_PINF: - s = (true(options, PL_WRT_QUOTED) ? "'$Infinity'" : "Infinity"); - break; - case FP_NDENORM: /* pos/neg denormalized non-zero */ - case FP_PDENORM: - case FP_NNORM: /* pos/neg normalized non-zero */ - case FP_PNORM: - case FP_NZERO: /* pos/neg zero */ - case FP_PZERO: - break; - } -#else -#ifdef HAVE__FPCLASS - switch(_fpclass(f)) - { case _FPCLASS_SNAN: - case _FPCLASS_QNAN: - s = (true(options, PL_WRT_QUOTED) ? "'$NaN'" : "NaN"); - break; - case _FPCLASS_NINF: - case _FPCLASS_PINF: - s = (true(options, PL_WRT_QUOTED) ? "'$Infinity'" : "Infinity"); - break; - } -#else -#ifdef HAVE_ISINF - if ( isinf(f) ) - { s = (true(options, PL_WRT_QUOTED) ? "'$Infinity'" : "Infinity"); - } else -#endif -#ifdef HAVE_ISNAN - if ( isnan(f) ) - { s = (true(options, PL_WRT_QUOTED) ? "'$NaN'" : "NaN"); - } -#endif -#endif /*HAVE__FPCLASS*/ -#endif /*HAVE_FPCLASS*/ -#endif /*HAVE_FPCLASSIFY*/ - - if ( s ) - { return PutToken(s, out); - } else - { char buf[100]; - - format_float(f, buf); - - return PutToken(buf, out); - } - } - -#if O_STRING - if ( PL_is_string(t) ) - return writeString(t, options); -#endif /* O_STRING */ - -#if __YAP_PROLOG__ - { - Opaque_CallOnWrite f; - - if ( (f = Yap_blob_write_handler_from_slot(t)) ) { - return (f)(options->out, Yap_blob_tag_from_slot(t), Yap_blob_info_from_slot(t), options->flags); - } else { - number n; - n.type = V_INTEGER; - n.value.i = 0; - return WriteNumber(&n, options); - } - } -#endif - - assert(0); - fail; -} - - -word -pl_nl1(term_t stream) -{ IOSTREAM *s; - - if ( getOutputStream(stream, &s) ) - { Sputcode('\n', s); - return streamStatus(s); - } - - fail; -} - -word -pl_nl(void) -{ return pl_nl1(0); -} - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Call user:portray/1 if defined. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -static int -callPortray(term_t arg, write_options *options) -{ predicate_t portray; - - if ( GD->cleaning > CLN_PROLOG ) - fail; /* avoid dangerous callbacks */ - - portray = _PL_predicate("portray", 1, "user", &GD->procedures.portray); - - if ( predicateHasClauses(portray) ) - { GET_LD - wakeup_state wstate; - IOSTREAM *old = Scurout; - int rval; - - if ( !saveWakeup(&wstate, TRUE PASS_LD) ) - return FALSE; - Scurout = options->out; - rval = PL_call_predicate(NULL, PL_Q_NODEBUG|PL_Q_PASS_EXCEPTION, - portray, arg); - if ( !rval && PL_exception(0) ) - rval = -1; - Scurout = old; - restoreWakeup(&wstate PASS_LD); - - return rval; - } - - fail; -} - - -static bool -writeArgTerm(term_t t, int prec, write_options *options, bool arg) -{ int rval; - int levelSave = options->depth; - fid_t fid; - - if ( !(fid = PL_open_foreign_frame()) ) - return FALSE; - - if ( PL_handle_signals() < 0 ) - { rval = FALSE; - goto out; - } - - if ( ++options->depth > options->max_depth && options->max_depth ) - rval = PutString("...", options->out); - else if ( PL_is_compound(t) ) - { visited v; - - v.address = address_of(t); - if ( has_visited(options->visited, v.address) ) - { rval = PutString("**", options->out); - } else - { v.next = options->visited; - options->visited = &v; - rval = writeTerm2(t, prec, options, arg); - options->visited = v.next; - } - } else - { rval = writeTerm2(t, prec, options, arg); - } - -out: - options->depth = levelSave; - PL_close_foreign_frame(fid); - - return rval; -} - static bool writeTerm(term_t t, int prec, write_options *options) { - return writeArgTerm(t, prec, options, FALSE); + UInt yap_flag = Use_SWI_Stream_f; + int flags = options->flags; + Term old_module; + + if (flags & PL_WRT_QUOTED) + yap_flag |= Quote_illegal_f; + if (options->flags & PL_WRT_NUMBERVARS) + yap_flag |= Handle_vars_f; + if (options->flags & PL_WRT_IGNOREOPS) + yap_flag |= Ignore_ops_f; + if (flags & PL_WRT_PORTRAY) + yap_flag |= Use_portray_f; + if (flags & PL_WRT_BACKQUOTED_STRING) + yap_flag |= BackQuote_String_f; + if (flags & PL_WRT_ATTVAR_IGNORE) + yap_flag |= 0L; + if (flags & PL_WRT_ATTVAR_DOTS) + yap_flag |= AttVar_Dots_f; + if (flags & PL_WRT_ATTVAR_PORTRAY) + yap_flag |= AttVar_Portray_f; + if (flags & PL_WRT_BLOB_PORTRAY) + yap_flag |= Blob_Portray_f; + old_module = CurrentModule; + CurrentModule = options->module; + Yap_plwrite(Yap_GetFromSlot(t), options->out, yap_flag, prec); + CurrentModule = old_module; + return TRUE; } -static bool -writeList2(term_t list, write_options *options, int cyclic) -{ GET_LD - term_t head = PL_new_term_ref(); - term_t l = PL_copy_term_ref(list); - - TRY(Putc('[', options->out)); - for(;;) - { PL_get_list(l, head, l); - TRY(writeArgTerm(head, 999, options, TRUE)); - - if ( PL_get_nil(l) ) - break; - if ( ++options->depth >= options->max_depth && options->max_depth ) - return PutString("|...]", options->out); - if ( !PL_is_functor(l, FUNCTOR_dot2) ) - { TRY(Putc('|', options->out)); - TRY(writeArgTerm(l, 999, options, TRUE)); - break; - } - - /* cycle detection */ - { Word addr = address_of(l); - - if ( has_visited(options->visited, addr) ) - { return PutString("|**]", options->out); - } else if ( cyclic ) - { visited *v = alloca(sizeof(*v)); - v->address = addr; - v->next = options->visited; - options->visited = v; - } - } - - TRY(PutComma(options)); - } - - return Putc(']', options->out); -} - - -static bool -writeList(term_t list, write_options *options) -{ GET_LD - visited *v = options->visited; - Word tail; - int rc; - - skip_list(valTermRef(list), &tail PASS_LD); - rc = writeList2(list, options, isList(*tail)); - options->visited = v; - - return rc; -} - - - -static bool -writeTerm2(term_t t, int prec, write_options *options, bool arg) -{ GET_LD - atom_t functor; - int arity, n; - int op_type, op_pri; - atom_t a; - IOSTREAM *out = options->out; - - if ( !PL_is_variable(t) && - true(options, PL_WRT_PORTRAY) ) - { switch( callPortray(t, options) ) - { case TRUE: - return TRUE; - case FALSE: - break; - default: - return FALSE; - } - } - -#if __YAP_PROLOG__ - t = Yap_CvtTerm(t); -#endif - if ( PL_get_atom(t, &a) ) - { if ( !arg && prec < 1200 && priorityOperator((Module)NULL, a) > 0 ) - { if ( PutOpenBrace(out) && - writeAtom(a, options) && - PutCloseBrace(out) ) - succeed; - } else - return writeAtom(a, options); - } - - if ( !PL_get_name_arity(t, &functor, &arity) ) - { return writePrimitive(t, options); - } else - { if ( arity == 1 && - functor == ATOM_isovar && /* $VAR/1 */ - true(options, PL_WRT_NUMBERVARS) ) - { int n; - atom_t a; - term_t arg = PL_new_term_ref(); - - _PL_get_arg(1, t, arg); -#if __YAP_PROLOG__ - /* YAP supports $VAR(-1) as a quick hack to write singleton variables */ -#define MIN_DOLLAR_VAR -1 -#else -#define MIN_DOLLAR_VAR 0 -#endif - if ( PL_get_integer(arg, &n) && n >= MIN_DOLLAR_VAR ) - { int i = n % 26; - int j = n / 26; - char buf[16]; - -#if __YAP_PROLOG__ - if ( n == -1 ) { - buf[0] = '_'; - buf[1] = EOS; - } else -#endif - if ( j == 0 ) - { buf[0] = i+'A'; - buf[1] = EOS; - } else - { sprintf(buf, "%c%d", i+'A', j); - } - - return PutToken(buf, out); - } - if ( PL_get_atom(arg, &a) ) - { write_options o2 = *options; - clear(&o2, PL_WRT_QUOTED); - - return writeAtom(a, &o2); - } - } - - - if ( false(options, PL_WRT_IGNOREOPS) ) - { term_t arg = PL_new_term_ref(); - - if ( arity == 1 ) - { if ( functor == ATOM_curl ) /* {a,b,c} */ - { _PL_get_arg(1, t, arg); - TRY(Putc('{', out)); - TRY(writeTerm(arg, 1200, options) && - Putc('}', out)); - - succeed; - } - - /* op */ - if ( currentOperator(options->module, functor, OP_PREFIX, - &op_type, &op_pri) ) - { term_t arg = PL_new_term_ref(); - int embrace; - - embrace = ( op_pri > prec ); - - _PL_get_arg(1, t, arg); - if ( embrace ) - { TRY(PutOpenBrace(out)); - } - TRY(writeAtom(functor, options)); - - /* +/-(Number) : avoid parsing as number */ - if ( (functor == ATOM_minus || functor == ATOM_plus) && - PL_is_number(arg) ) - { TRY(Putc('(', out)); - TRY(writeTerm(arg, 999, options)); - TRY(Putc(')', out)); - } else - { TRY(writeTerm(arg, - op_type == OP_FX ? op_pri-1 : op_pri, - options)); - } - if ( embrace ) - { TRY(PutCloseBrace(out)); - } - - succeed; - } - - /* op */ - if ( currentOperator(options->module, functor, OP_POSTFIX, - &op_type, &op_pri) ) - { term_t arg = PL_new_term_ref(); - - _PL_get_arg(1, t, arg); - if ( op_pri > prec ) - TRY(PutOpenBrace(out)); - TRY(writeTerm(arg, - op_type == OP_XF ? op_pri-1 : op_pri, - options)); - TRY(writeAtom(functor, options)); - if (op_pri > prec) - TRY(PutCloseBrace(out)); - - succeed; - } - } else if ( arity == 2 ) - { if ( functor == ATOM_dot ) /* [...] */ - return writeList(t, options); - - /* op */ - if ( currentOperator(options->module, functor, OP_INFIX, - &op_type, &op_pri) ) - { term_t l = PL_new_term_ref(); - term_t r = PL_new_term_ref(); - - _PL_get_arg(1, t, l); - _PL_get_arg(2, t, r); - - if ( op_pri > prec ) - TRY(PutOpenBrace(out)); - TRY(writeTerm(l, - op_type == OP_XFX || op_type == OP_XFY - ? op_pri-1 : op_pri, - options)); - if ( functor == ATOM_comma ) - { TRY(PutComma(options)); - } else - { switch(writeAtom(functor, options)) - { case FALSE: - fail; - case TRUE_WITH_SPACE: - TRY(Putc(' ', out)); - } - } - TRY(writeTerm(r, - op_type == OP_XFX || op_type == OP_YFX - ? op_pri-1 : op_pri, - options)); - if ( op_pri > prec ) - TRY(PutCloseBrace(out)); - succeed; - } - } - } - /* functor( ...) */ - { term_t a = PL_new_term_ref(); - - TRY(writeAtom(functor, options) && - Putc('(', out)); - for(n=0; n 0) - TRY(PutComma(options)); - _PL_get_arg(n+1, t, a); - TRY(writeArgTerm(a, 999, options, TRUE)); - } - return Putc(')', out); - } - } +int +writeAtomToStream(IOSTREAM *s, atom_t atom) +{ Yap_plwrite(MkAtomTerm(YAP_AtomFromSWIAtom(atom)), s, 0, 1200); + return 1; } @@ -1362,6 +262,59 @@ static const opt_spec write_term_options[] = { NULL_ATOM, 0 } }; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +PutOpenToken() inserts a space in the output stream if the last-written +and given character require a space to ensure a token-break. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#define TRUE_WITH_SPACE 2 /* OK, and emitted leading space before token */ + +static bool +Putc(int c, IOSTREAM *s) +{ return Sputcode(c, s) == EOF ? FALSE : TRUE; +} + +#define LAST_C_RESERVED 0x110000 /* Above Unicode range */ +#define PREFIX_SIGN (LAST_C_RESERVED+1) + +#define isquote(c) ((c) == '\'' || (c) == '"') + +static bool +needSpace(int c, IOSTREAM *s) +{ if ( c == EOF ) + { s->lastc = EOF; + return FALSE; + } + + if ( s->lastc == PREFIX_SIGN ) /* avoid passing to is*W() functions */ + { if ( isDigit(c) || isSymbolW(c) ) + return TRUE; + return FALSE; + } + + if ( s->lastc != EOF && + ((isAlphaW(s->lastc) && isAlphaW(c)) || + (isSymbolW(s->lastc) && isSymbolW(c)) || + (s->lastc != '(' && !isBlank(s->lastc) && c == '(') || + (c == '\'' && (isDigit(s->lastc))) || + (isquote(c) && s->lastc == c) + ) ) + return TRUE; + + return FALSE; +} + + +static int +PutOpenToken(int c, IOSTREAM *s) +{ if ( needSpace(c, s) ) + { TRY(Putc(' ', s)); + return TRUE_WITH_SPACE; + } + + return TRUE; +} + word pl_write_term3(term_t stream, term_t term, term_t opts) { GET_LD @@ -1471,7 +424,7 @@ PL_write_term(IOSTREAM *s, term_t term, int precedence, int flags) memset(&options, 0, sizeof(options)); options.flags = flags; options.out = s; - options.module = MODULE_user; + options.module = USER_MODULE; //MODULE_user; PutOpenToken(EOF, s); /* reset this */ return writeTerm(term, precedence, &options); @@ -1490,7 +443,7 @@ do_write2(term_t stream, term_t term, int flags) memset(&options, 0, sizeof(options)); options.flags = flags; options.out = s; - options.module = MODULE_user; + options.module = USER_MODULE; // MODULE_user; // if ( options.module && true(options.module, CHARESCAPE) ) if (charEscapeWriteOption(options)) options.flags |= PL_WRT_CHARESCAPES; @@ -1574,30 +527,10 @@ pl_writeln(term_t term) } -static -PRED_IMPL("$put_token", 2, put_token, 0) -{ char *s; - size_t len; - IOSTREAM *out; - - if ( !PL_get_stream_handle(A1, &out) ) - fail; - if ( !PL_get_nchars(A2, &len, &s, CVT_ATOM|CVT_STRING|CVT_EXCEPTION) ) - fail; - - if ( PutTokenN(s, len, out) ) - return PL_release_stream(out); - - PL_release_stream(out); - fail; -} - - /******************************* * PUBLISH PREDICATES * *******************************/ BeginPredDefs(write) - PRED_DEF("$put_token", 2, put_token, 0) EndPredDefs diff --git a/packages/real b/packages/real index c1584e1ac..f4c629b19 160000 --- a/packages/real +++ b/packages/real @@ -1 +1 @@ -Subproject commit c1584e1ac73304ffc83b5d75b91f5e785ce5d41e +Subproject commit f4c629b195e560662d211ad11054dda458de4ddb