stream_Property/2:
allow sp(X,Y), sp(u,Y), sp(X,t(Y)) fix lines
This commit is contained in:
parent
bc71e54f20
commit
eec32e698a
6
C/args.c
6
C/args.c
@ -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);
|
||||||
|
@ -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);
|
||||||
|
187
os/streams.c
187
os/streams.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user