/** * Syntax Error Handler * * @par tokptr: the sequence of tokens * @par sno: the stream numbet * * Implicit arguments: * + */ Term Yap_syntax_error(TokEntry *errtok, int sno) { CACHE_REGS Term info; Term startline, errline, endline; Term tf[4]; Term *tailp = tf + 3; CELL *Hi = HR; TokEntry *tok = LOCAL_tokptr; Int cline = tok->TokPos; startline = MkIntegerTerm(cline); if (errtok != LOCAL_toktide) { errtok = LOCAL_toktide; } LOCAL_Error_TYPE = YAP_NO_ERROR; errline = MkIntegerTerm(errtok->TokPos); if (LOCAL_ErrorMessage) tf[0] = MkStringTerm(LOCAL_ErrorMessage); else tf[0] = MkStringTerm(""); while (tok) { Term ts[2]; if (HR > ASP - 1024) { errline = MkIntegerTerm(0); endline = MkIntegerTerm(0); /* for some reason moving this earlier confuses gcc on solaris */ HR = Hi; break; } if (tok->TokPos != cline) { *tailp = MkPairTerm(TermNewLine, TermNil); tailp = RepPair(*tailp) + 1; cline = tok->TokPos; } if (tok == errtok && tok->Tok != Error_tok) { *tailp = MkPairTerm(MkAtomTerm(AtomError), TermNil); tailp = RepPair(*tailp) + 1; } info = tok->TokInfo; switch (tok->Tok) { case Name_tok: { Term t0[1]; if (info) { t0[0] = MkAtomTerm((Atom)info); } else { t0[0] = TermNil; } ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomAtom, 1), 1, t0); } break; case QuasiQuotes_tok: { Term t0[2]; t0[0] = MkAtomTerm(Yap_LookupAtom("<QQ>")); ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomAtom, 1), 1, t0); } break; case WQuasiQuotes_tok: { Term t0[2]; t0[0] = MkAtomTerm(Yap_LookupAtom("<WideQQ>")); ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomAtom, 1), 1, t0); } break; case Number_tok: ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomNumber, 1), 1, &(tok->TokInfo)); break; case Var_tok: { Term t[2]; VarEntry *varinfo = (VarEntry *)info; t[0] = MkIntTerm(0); t[1] = Yap_CharsToString(varinfo->VarRep, ENC_ISO_LATIN1 PASS_REGS); ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomGVar, 2), 2, t); } break; case String_tok: { Term t0 = Yap_CharsToTDQ((char *)info, CurrentModule, ENC_ISO_LATIN1 PASS_REGS); if (!t0) { return 0; } ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomString, 1), 1, &t0); } break; case WString_tok: { Term t0 = Yap_WCharsToTDQ((wchar_t *)info, CurrentModule PASS_REGS); if (!t0) return 0; ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomString, 1), 1, &t0); } break; case BQString_tok: { Term t0 = Yap_CharsToTBQ((char *)info, CurrentModule, ENC_ISO_LATIN1 PASS_REGS); ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomString, 1), 1, &t0); } break; case WBQString_tok: { Term t0 = Yap_WCharsToTBQ((wchar_t *)info, CurrentModule PASS_REGS); ts[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomString, 1), 1, &t0); } break; case Error_tok: { ts[0] = MkAtomTerm(AtomError); } break; case eot_tok: endline = MkIntegerTerm(tok->TokPos); ts[0] = MkAtomTerm(Yap_LookupAtom("EOT")); break; case Ponctuation_tok: { char s[2]; s[1] = '\0'; if ((info) == 'l') { s[0] = '('; } else { s[0] = (char)info; } ts[0] = MkAtomTerm(Yap_LookupAtom(s)); } } tok = tok->TokNext; if (!tok) break; *tailp = MkPairTerm(ts[0], TermNil); tailp = RepPair(*tailp) + 1; } { Term t[3]; t[0] = startline; t[1] = errline; t[2] = endline; tf[1] = Yap_MkApplTerm(Yap_MkFunctor(AtomBetween, 3), 3, t); } /* 0: id */ /* 1: strat, error, end line */ /*2 msg */ /* file */ tf[2] = Yap_StreamUserName(sno); clean_vars(LOCAL_VarTable); clean_vars(LOCAL_AnonVarTable); Term terr = Yap_MkApplTerm(FunctorSyntaxError, 4, tf); Term tn[2]; tn[0] = Yap_MkApplTerm(FunctorShortSyntaxError, 1, &terr); tn[1] = TermNil; terr = Yap_MkApplTerm(FunctorError, 2, tn); #if DEBUG if (Yap_ExecutionMode == YAP_BOOT_MODE) { fprintf(stderr, "SYNTAX ERROR while booting: "); Yap_DebugPlWriteln(terr); } #endif return terr; }
static Int read_line_to_string(USES_REGS1) { int sno = Yap_CheckStream(ARG1, Input_Stream_f, "read_line_to_codes/2"); Int status; UInt max_inp, buf_sz; unsigned char *buf; size_t sz; StreamDesc *st = GLOBAL_Stream + sno; int ch; if (sno < 0) return false; status = GLOBAL_Stream[sno].status; if (status & Eof_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof)); } max_inp = (ASP - HR) / 2 - 1024; buf = (unsigned char *)TR; buf_sz = (unsigned char *)LOCAL_TrailTop - buf; if (buf_sz > max_inp) { buf_sz = max_inp; } if (st->status & Binary_Stream_f) { char *b = (char *)TR; sz = fread(b, 1, buf_sz, GLOBAL_Stream[sno].file); } else { unsigned char *pt = buf; do { ch = st->stream_wgetc_for_read(sno); if (ch < 127) { *pt++ = ch; if (ch < 0) { ch = '\n'; pt[-1] = '\n'; } } else { pt += get_utf8(pt, 4, &ch); if (pt + 4 == buf + buf_sz) break; } } while (ch != '\n'); sz = pt - buf; } if (sz == -1 || sz == 0) { if (GLOBAL_Stream[sno].status & Eof_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); return Yap_unify_constant(ARG2, MkAtomTerm(AtomEof)); } UNLOCK(GLOBAL_Stream[sno].streamlock); return false; } if (GLOBAL_Stream[sno].status & Eof_Stream_f || buf[sz - 1] == 10) { /* we're done */ if (!(GLOBAL_Stream[sno].status & Eof_Stream_f)) { UNLOCK(GLOBAL_Stream[sno].streamlock); /* handle CR before NL */ if ((Int)sz - 2 >= 0 && buf[sz - 2] == 13) buf[sz - 2] = '\0'; else { buf[sz - 1] = '\0'; } } else { UNLOCK(GLOBAL_Stream[sno].streamlock); } } if (GLOBAL_Stream[sno].encoding == ENC_ISO_UTF8) { return Yap_unify(ARG2, Yap_UTF8ToString((const char *)TR PASS_REGS)); } else if (GLOBAL_Stream[sno].encoding == ENC_WCHAR) { return Yap_unify(ARG2, Yap_WCharsToString((const wchar_t *)TR PASS_REGS)); } else { return Yap_unify( ARG2, Yap_CharsToString((const char *)TR, ENC_ISO_LATIN1 PASS_REGS)); } buf += (buf_sz - 1); max_inp -= (buf_sz - 1); if (max_inp <= 0) { UNLOCK(GLOBAL_Stream[sno].streamlock); Yap_Error(RESOURCE_ERROR_STACK, ARG1, NULL); return FALSE; } }