stream_Property/2:

allow sp(X,Y), sp(u,Y), sp(X,t(Y))
 fix lines
This commit is contained in:
Vítor Santos Costa 2016-02-20 01:30:52 +00:00
parent bc71e54f20
commit eec32e698a
3 changed files with 125 additions and 70 deletions

View File

@ -58,6 +58,7 @@ xarg *
Yap_ArgListToVector (Term listl, const param_t *def, int n) Yap_ArgListToVector (Term listl, const param_t *def, int n)
{ {
CACHE_REGS CACHE_REGS
listl = Deref(listl);
xarg *a = calloc( n , sizeof(xarg) ); xarg *a = calloc( n , sizeof(xarg) );
LOCAL_Error_TYPE = YAP_NO_ERROR; LOCAL_Error_TYPE = YAP_NO_ERROR;
if (IsApplTerm(listl) && FunctorOfTerm(listl) == FunctorModule) if (IsApplTerm(listl) && FunctorOfTerm(listl) == FunctorModule)
@ -84,6 +85,9 @@ Yap_ArgListToVector (Term listl, const param_t *def, int n)
if (!na) { if (!na) {
return failed( TYPE_ERROR_LIST, listl, a); return failed( TYPE_ERROR_LIST, listl, a);
} }
na->used = true;
na->tvalue = ArgOfTerm(1,listl);
return a;
} else { } else {
return failed( TYPE_ERROR_LIST, listl, a); return failed( TYPE_ERROR_LIST, listl, a);
} }
@ -119,7 +123,7 @@ Yap_ArgListToVector (Term listl, const param_t *def, int n)
if (!na) { if (!na) {
return failed( DOMAIN_ERROR_GENERIC_ARGUMENT, hd, a); return failed( DOMAIN_ERROR_GENERIC_ARGUMENT, hd, a);
} }
na->used = 1; na->used = true;
na->tvalue = ArgOfTerm(1, hd); na->tvalue = ArgOfTerm(1, hd);
} else { } else {
return failed( TYPE_ERROR_PARAMETER, hd, a); return failed( TYPE_ERROR_PARAMETER, hd, a);

View File

@ -1741,7 +1741,7 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
} else } else
ch = getchr(inp_stream); ch = getchr(inp_stream);
break; break;
case SY: case SY:
if (ch == '.' && (pch = Yap_peek(inp_stream - GLOBAL_Stream)) && if (ch == '.' && (pch = Yap_peek(inp_stream - GLOBAL_Stream)) &&
(chtype(pch) == BS || chtype(pch) == EF || pch == '%')) { (chtype(pch) == BS || chtype(pch) == EF || pch == '%')) {
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);

View File

@ -146,6 +146,40 @@ int GetFreeStreamD(void) {
int Yap_GetFreeStreamD(void) { return GetFreeStreamD(); } int Yap_GetFreeStreamD(void) { return GetFreeStreamD(); }
static Term lineCount(int sno)
{
Term tout;
/* one has to be somewhat more careful because of terminals */
if (GLOBAL_Stream[sno].status & Tty_Stream_f) {
Int no = 1;
int i;
Atom my_stream;
#if HAVE_SOCKET
if (GLOBAL_Stream[sno].status & Socket_Stream_f)
my_stream = AtomSocket;
else
#endif
if (GLOBAL_Stream[sno].status & Pipe_Stream_f)
my_stream = AtomPipe;
else if (GLOBAL_Stream[sno].status & InMemory_Stream_f)
my_stream = AtomCharsio;
else
my_stream = GLOBAL_Stream[sno].name;
for (i = 0; i < MaxStreams; i++) {
if ((GLOBAL_Stream[i].status & ( Socket_Stream_f |
Pipe_Stream_f | InMemory_Stream_f)) &&
!(GLOBAL_Stream[i].status & ( Free_Stream_f)) &&
GLOBAL_Stream[i].name == my_stream)
no += GLOBAL_Stream[i].linecount - 1;
}
tout = MkIntTerm(no);
} else
tout = MkIntTerm(GLOBAL_Stream[sno].linecount);
UNLOCK(GLOBAL_Stream[sno].streamlock);
return tout;
}
static Int stream_flags(USES_REGS1) { /* '$stream_flags'(+N,-Flags) */ static Int stream_flags(USES_REGS1) { /* '$stream_flags'(+N,-Flags) */
Term trm; Term trm;
trm = Deref(ARG1); trm = Deref(ARG1);
@ -204,7 +238,7 @@ has_reposition(int sno,
Term t2 USES_REGS) { /* '$set_output'(+Stream,-ErrorMessage) */ Term t2 USES_REGS) { /* '$set_output'(+Stream,-ErrorMessage) */
bool rc = GLOBAL_Stream[sno].status & Seekable_Stream_f; bool rc = GLOBAL_Stream[sno].status & Seekable_Stream_f;
if (!IsVarTerm(t2) && !booleanFlag(t2)) { if (!IsVarTerm(t2) && !booleanFlag(t2)) {
return FALSE; return false;
} }
if (rc) { if (rc) {
return Yap_unify_constant(t2, TermTrue); return Yap_unify_constant(t2, TermTrue);
@ -365,14 +399,14 @@ stream_position(int sno,
static bool stream_line_count( static bool stream_line_count(
int sno, Term t2 USES_REGS) { /* '$set_output'(+Stream,-ErrorMessage) */ int sno, Term t2 USES_REGS) { /* '$set_output'(+Stream,-ErrorMessage) */
Term tout = StreamPosition(GLOBAL_Stream[sno].linecount); Term tout = lineCount(sno);
return Yap_unify(t2, MkIntegerTerm(tout)); return Yap_unify(t2, tout);
} }
static bool stream_line_number( static bool stream_line_number(
int sno, Term t2 USES_REGS) { /* '$set_output'(+Stream,-ErrorMessage) */ int sno, Term t2 USES_REGS) { /* '$set_output'(+Stream,-ErrorMessage) */
Term tout = StreamPosition(GLOBAL_Stream[sno].linecount); Term tout = MkIntegerTerm(GLOBAL_Stream[sno].linecount);
return Yap_unify(t2, MkIntegerTerm(tout)); return Yap_unify(t2, tout);
} }
static bool static bool
@ -525,7 +559,7 @@ static bool do_stream_property(int sno,
break; break;
case STREAM_PROPERTY_REPOSITION: case STREAM_PROPERTY_REPOSITION:
rc = rc && rc = rc &&
has_reposition(sno, args[STREAM_PROPERTY_MODE].tvalue PASS_REGS); has_reposition(sno, args[STREAM_PROPERTY_REPOSITION].tvalue PASS_REGS);
break; break;
case STREAM_PROPERTY_REPRESENTATION_ERRORS: case STREAM_PROPERTY_REPRESENTATION_ERRORS:
rc = rc && rc = rc &&
@ -546,74 +580,111 @@ static bool do_stream_property(int sno,
} }
} }
} }
UNLOCK(GLOBAL_Stream[sno].streamlock);
return rc; return rc;
} }
static xarg *generate_property(int sno, Term t2,
stream_property_choices_t p USES_REGS)
{
if (p == STREAM_PROPERTY_INPUT) Yap_unify(t2, MkAtomTerm(AtomInput));
else if (p == STREAM_PROPERTY_OUTPUT) Yap_unify(t2, MkAtomTerm(AtomOutput));
else {
Term t0 = MkVarTerm();
Functor f = Yap_MkFunctor(Yap_LookupAtom(stream_property_defs[p].name), 1);
Yap_unify( t2, Yap_MkApplTerm(f, 1, &t0));
}
return Yap_ArgListToVector(t2, stream_property_defs,
STREAM_PROPERTY_END);
}
static Int cont_stream_property(USES_REGS1) { /* current_stream */ static Int cont_stream_property(USES_REGS1) { /* current_stream */
bool det; bool det;
xarg *args; xarg *args;
int i = IntOfTerm(EXTRA_CBACK_ARG(2, 1)); int i = IntOfTerm(EXTRA_CBACK_ARG(2, 1));
stream_property_choices_t p = STREAM_PROPERTY_END;
bool rc; bool rc;
Term t2 = Deref(ARG2);
Term t1 = Deref(ARG1);
args = Yap_ArgListToVector(Deref(ARG2), stream_property_defs, if (IsVarTerm(t2)) {
STREAM_PROPERTY_END); p = IntOfTerm(EXTRA_CBACK_ARG(2, 2));
args = generate_property(i, t2, p++ PASS_REGS);
EXTRA_CBACK_ARG(2, 2) = MkIntTerm(p%STREAM_PROPERTY_END);
// otherwise, just drop through
} else {
args = Yap_ArgListToVector(t2, stream_property_defs,
STREAM_PROPERTY_END);
}
if (args == NULL) { if (args == NULL) {
if (LOCAL_Error_TYPE != YAP_NO_ERROR) { if (LOCAL_Error_TYPE != YAP_NO_ERROR) {
if (LOCAL_Error_TYPE == DOMAIN_ERROR_PROLOG_FLAG) if (LOCAL_Error_TYPE == DOMAIN_ERROR_GENERIC_ARGUMENT)
LOCAL_Error_TYPE = DOMAIN_ERROR_STREAM_PROPERTY_OPTION; LOCAL_Error_TYPE = DOMAIN_ERROR_STREAM_PROPERTY_OPTION;
Yap_Error( LOCAL_Error_TYPE, LOCAL_Error_Term, NULL ); Yap_Error( LOCAL_Error_TYPE, LOCAL_Error_Term, NULL );
return false;
} }
cut_fail(); cut_fail();
} }
LOCK(GLOBAL_StreamDescLock); LOCK(GLOBAL_Stream[i].streamlock);
if (args[STREAM_PROPERTY_ALIAS].tvalue && if (args[STREAM_PROPERTY_ALIAS].tvalue &&
IsAtomTerm(args[STREAM_PROPERTY_ALIAS].tvalue)) { IsAtomTerm(args[STREAM_PROPERTY_ALIAS].tvalue)) {
// one solution only // one solution only
det = true; LOCK(GLOBAL_Stream[i].streamlock);
i = Yap_CheckAlias(AtomOfTerm(args[STREAM_PROPERTY_ALIAS].tvalue)); UNLOCK(GLOBAL_Stream[i].streamlock);
UNLOCK(GLOBAL_StreamDescLock); i = Yap_CheckAlias(AtomOfTerm(args[STREAM_PROPERTY_ALIAS].tvalue));
if (i < 0) { UNLOCK(GLOBAL_Stream[i].streamlock);
if (i < 0 ||!Yap_unify(ARG1, Yap_MkStream(i) ) ) {
cut_fail(); cut_fail();
} }
rc = true; cut_succeed();
} else { }
while (GLOBAL_Stream[i].status & Free_Stream_f) { LOCK(GLOBAL_Stream[i].streamlock);
++i; rc = do_stream_property(i, args PASS_REGS);
if (i == MaxStreams) { UNLOCK(GLOBAL_Stream[i].streamlock);
UNLOCK(GLOBAL_StreamDescLock); if ( IsVarTerm(t1)) {
cut_fail(); if (rc)
}
}
LOCK(GLOBAL_Stream[i].streamlock);
UNLOCK(GLOBAL_StreamDescLock);
rc = do_stream_property(i, args PASS_REGS);
UNLOCK(GLOBAL_Stream[i].streamlock);
}
if (rc)
rc = Yap_unify(ARG1, Yap_MkStream(i)); rc = Yap_unify(ARG1, Yap_MkStream(i));
if (p == STREAM_PROPERTY_END ) {
// move to next existing stream
LOCK(GLOBAL_StreamDescLock);
while (++i < MaxStreams && GLOBAL_Stream[i].status & Free_Stream_f) ;
UNLOCK(GLOBAL_StreamDescLock);
if (i < MaxStreams) {
EXTRA_CBACK_ARG(2, 1) = MkIntTerm(i);
det = false;
} else {
det = true;
}
} else {
det = false;
}
} else {
// done
det = (p == STREAM_PROPERTY_END );
}
if (rc) { if (rc) {
if (det) if (det)
cut_succeed(); cut_succeed();
else { else {
EXTRA_CBACK_ARG(2, 1) = MkIntTerm(i + 1);
return true; return true;
} }
} else if (det) } else if (det) {
cut_fail(); cut_fail();
else { } else {
EXTRA_CBACK_ARG(2, 1) = MkIntTerm(i + 1);
return false; return false;
} }
} }
static Int stream_property(USES_REGS1) { /* Init current_stream */ static Int stream_property(USES_REGS1) { /* Init current_stream */
Term t1 = Deref(ARG1); Term t1 = Deref(ARG1);
Term t2 = Deref(ARG2);
// Yap_DebugPlWrite(ARG1);fprintf(stderr,", "); // Yap_DebugPlWrite(ARG1);fprintf(stderr,", ");
// Yap_DebugPlWrite(ARG2);fprintf(stderr,"\n"); // Yap_DebugPlWrite(ARG2);fprintf(stderr,"\n");
/* make valgrind happy by always filling in memory */ /* make valgrind happy by always filling in memory */
EXTRA_CBACK_ARG(2, 1) = MkIntTerm(0); EXTRA_CBACK_ARG(2, 1) = MkIntTerm(0);
EXTRA_CBACK_ARG(2, 2) = MkIntTerm(0);
if (!IsVarTerm(t1)) { if (!IsVarTerm(t1)) {
Int i; Int i;
xarg *args; xarg *args;
@ -622,15 +693,18 @@ static Int stream_property(USES_REGS1) { /* Init current_stream */
"current_stream/3"); "current_stream/3");
if (i < 0) { if (i < 0) {
UNLOCK(GLOBAL_Stream[i].streamlock); UNLOCK(GLOBAL_Stream[i].streamlock);
cut_fail(); return false; // error...
} }
if (IsVarTerm(t2))
return cont_stream_property(PASS_REGS1);
args = Yap_ArgListToVector(Deref(ARG2), stream_property_defs, args = Yap_ArgListToVector(Deref(ARG2), stream_property_defs,
STREAM_PROPERTY_END); STREAM_PROPERTY_END);
if (args == NULL) { if (args == NULL) {
if (LOCAL_Error_TYPE != YAP_NO_ERROR) { if (LOCAL_Error_TYPE != YAP_NO_ERROR) {
if (LOCAL_Error_TYPE == DOMAIN_ERROR_PROLOG_FLAG) if (LOCAL_Error_TYPE == DOMAIN_ERROR_PROLOG_FLAG)
LOCAL_Error_TYPE = DOMAIN_ERROR_STREAM_PROPERTY_OPTION; LOCAL_Error_TYPE = DOMAIN_ERROR_STREAM_PROPERTY_OPTION;
Yap_Error( LOCAL_Error_TYPE, LOCAL_Error_Term, NULL ); Yap_Error( LOCAL_Error_TYPE, LOCAL_Error_Term, NULL );
return false;
} }
UNLOCK(GLOBAL_Stream[i].streamlock); UNLOCK(GLOBAL_Stream[i].streamlock);
cut_fail(); cut_fail();
@ -685,7 +759,7 @@ static bool do_set_stream(int sno,
args = Yap_ArgListToVector(opts, set_stream_defs, SET_STREAM_END); args = Yap_ArgListToVector(opts, set_stream_defs, SET_STREAM_END);
if (args == NULL) { if (args == NULL) {
if (LOCAL_Error_TYPE != YAP_NO_ERROR) { if (LOCAL_Error_TYPE != YAP_NO_ERROR) {
if (LOCAL_Error_TYPE == DOMAIN_ERROR_PROLOG_FLAG) if (LOCAL_Error_TYPE == DOMAIN_ERROR_GENERIC_ARGUMENT)
LOCAL_Error_TYPE = DOMAIN_ERROR_SET_STREAM_OPTION; LOCAL_Error_TYPE = DOMAIN_ERROR_SET_STREAM_OPTION;
Yap_Error( LOCAL_Error_TYPE, LOCAL_Error_Term, NULL ); Yap_Error( LOCAL_Error_TYPE, LOCAL_Error_Term, NULL );
} }
@ -1002,32 +1076,7 @@ static Int line_count(USES_REGS1) { /* '$current_line_number'(+Stream,-N) */
"current_line_number/2"); "current_line_number/2");
if (sno < 0) if (sno < 0)
return (false); return (false);
/* one has to be somewhat more careful because of terminals */ tout = lineCount(sno);
if (GLOBAL_Stream[sno].status & Tty_Stream_f) {
Int no = 1;
int i;
Atom my_stream;
#if HAVE_SOCKET
if (GLOBAL_Stream[sno].status & Socket_Stream_f)
my_stream = AtomSocket;
else
#endif
if (GLOBAL_Stream[sno].status & Pipe_Stream_f)
my_stream = AtomPipe;
else if (GLOBAL_Stream[sno].status & InMemory_Stream_f)
my_stream = AtomCharsio;
else
my_stream = GLOBAL_Stream[sno].name;
for (i = 0; i < MaxStreams; i++) {
if (!(GLOBAL_Stream[i].status & (Free_Stream_f | Socket_Stream_f |
Pipe_Stream_f | InMemory_Stream_f)) &&
GLOBAL_Stream[i].name == my_stream)
no += GLOBAL_Stream[i].linecount - 1;
}
tout = MkIntTerm(no);
} else
tout = MkIntTerm(GLOBAL_Stream[sno].linecount);
UNLOCK(GLOBAL_Stream[sno].streamlock);
return (Yap_unify_constant(ARG2, tout)); return (Yap_unify_constant(ARG2, tout));
} }
@ -1377,9 +1426,11 @@ FILE *Yap_FileDescriptorFromStream(Term t) {
void void
Yap_InitBackIO (void) Yap_InitBackIO (
void)
{ {
Yap_InitCPredBack("stream_property", 2, 1, stream_property, Yap_InitCPredBack("stream_property", 2, 2, stream_property,
cont_stream_property, SafePredFlag | SyncPredFlag); cont_stream_property, SafePredFlag | SyncPredFlag);
} }