Merge branch 'master' of ssh://yap.git.sourceforge.net/gitroot/yap/yap-6.3

This commit is contained in:
Tiago Gomes 2013-01-25 13:50:09 +00:00
commit 31bff4dc84
112 changed files with 5508 additions and 3004 deletions

View File

@ -963,7 +963,7 @@ Yap_absmi(int inp)
/***************************************************************** /*****************************************************************
* EXO try - retry instructions * * EXO try - retry instructions *
*****************************************************************/ *****************************************************************/
/* try_exo Pred,Label */ /* enter_exo Pred,Label */
BOp(enter_exo, e); BOp(enter_exo, e);
{ {
yamop *pt; yamop *pt;
@ -1011,6 +1011,37 @@ Yap_absmi(int inp)
GONext(); GONext();
ENDOp(); ENDOp();
/* try_udi Pred,Label */
Op(try_udi, p);
/* check if enough space between trail and codespace */
check_trail(TR);
/* I use YREG =to go through the choicepoint. Usually YREG =is in a
* register, but sometimes (X86) not. In this case, have a
* new register to point at YREG =*/
CACHE_Y(YREG);
{
S_YREG[-1] = (CELL)SREG; /* the udi code did S = (CELL*)judyp; */
}
S_YREG--;
/* store arguments for procedure */
store_at_least_one_arg(PREG->u.lp.p->ArityOfPE);
/* store abstract machine registers */
store_yaam_regs(NEXTOP(PREG,lp), 0);
/* On a try_me, set cut to point at previous choicepoint,
* that is, to the B before the cut.
*/
set_cut(S_YREG, B);
/* now, install the new YREG =*/
B = B_YREG;
#ifdef YAPOR
SCH_set_load(B_YREG);
#endif /* YAPOR */
PREG = NEXTOP(NEXTOP(PREG, lp),lp);
SET_BB(B_YREG);
ENDCACHE_Y();
GONext();
ENDOp();
/* check if enough space between trail and codespace */ /* check if enough space between trail and codespace */
/* try_exo Pred,Label */ /* try_exo Pred,Label */
Op(try_all_exo, lp); Op(try_all_exo, lp);
@ -1097,6 +1128,61 @@ Yap_absmi(int inp)
GONext(); GONext();
ENDOp(); ENDOp();
/* retry_exo Pred */
Op(retry_udi, p);
BEGD(d0);
CACHE_Y(B);
{
// struct udi_index_t *jp = (struct udi_index_t *)((CELL *)(B+1))[it->arity];
/* operation has a side-effect: S = (CELL*)NextClause */
saveregs();
d0 = 0L; // Yap_UDI_NextAlt(jp);
setregs();
#ifdef SHADOW_S
SREG = S;
#endif
/* d0 says if we're last */
}
if (d0) {
/* After retry, cut should be pointing at the parent
* choicepoint for the current B */
restore_yaam_regs(PREG);
restore_at_least_one_arg(PREG->u.lp.p->ArityOfPE);
#ifdef FROZEN_STACKS
S_YREG = (CELL *) PROTECT_FROZEN_B(B_YREG);
set_cut(S_YREG, B->cp_b);
#else
set_cut(S_YREG, B_YREG->cp_b);
#endif /* FROZEN_STACKS */
SET_BB(B_YREG);
} else {
#ifdef YAPOR
if (SCH_top_shared_cp(B)) {
SCH_last_alternative(PREG, B_YREG);
restore_at_least_one_arg(PREG->u.lp.p->ArityOfPE);
#ifdef FROZEN_STACKS
S_YREG = (CELL *) PROTECT_FROZEN_B(B_YREG);
#endif /* FROZEN_STACKS */
set_cut(S_YREG, B->cp_b);
} else
#endif /* YAPOR */
{
pop_yaam_regs();
pop_at_least_one_arg(PREG->u.lp.p->ArityOfPE);
/* After trust, cut should be pointing at the new top
* choicepoint */
#ifdef FROZEN_STACKS
S_YREG = (CELL *) PROTECT_FROZEN_B(B_YREG);
#endif /* FROZEN_STACKS */
set_cut(S_YREG, B);
}
}
PREG = (yamop *)SREG;
ENDCACHE_Y();
ENDD(D0);
GONext();
ENDOp();
/* retry_exo Pred */ /* retry_exo Pred */
Op(retry_all_exo, lp); Op(retry_all_exo, lp);
BEGD(d0); BEGD(d0);
@ -7446,7 +7532,7 @@ Yap_absmi(int inp)
saveregs(); saveregs();
save_machine_regs(); save_machine_regs();
SREG = (CELL *) YAP_ExecuteFirst(PREG->u.OtapFs.p, (CPredicate)(PREG->u.OtapFs.f)); SREG = (CELL *) YAP_ExecuteFirst(PREG->u.OtapFs.p, (CPredicate)(PREG->u.OtapFs.f));
EX = 0L; EX = NULL;
restore_machine_regs(); restore_machine_regs();
setregs(); setregs();
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
@ -7489,7 +7575,7 @@ Yap_absmi(int inp)
saveregs(); saveregs();
save_machine_regs(); save_machine_regs();
SREG = (CELL *) YAP_ExecuteNext(PREG->u.OtapFs.p, (CPredicate)(PREG->u.OtapFs.f)); SREG = (CELL *) YAP_ExecuteNext(PREG->u.OtapFs.p, (CPredicate)(PREG->u.OtapFs.f));
EX = 0L; EX = NULL;
restore_machine_regs(); restore_machine_regs();
setregs(); setregs();
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;

View File

@ -523,8 +523,7 @@ eval1(Int fi, Term t) {
#endif #endif
#if HAVE_ISINF #if HAVE_ISINF
if (isinf(dbl)) { if (isinf(dbl)) {
return Yap_ArithError(EVALUATION_ERROR_INT_OVERFLOW, MkFloatTerm(dbl), "integer\ return Yap_ArithError(EVALUATION_ERROR_INT_OVERFLOW, MkFloatTerm(dbl), "integer (%f)",dbl);
(%f)",dbl);
} }
#endif #endif
if (dbl < 0.0) if (dbl < 0.0)

View File

@ -1663,6 +1663,10 @@ YAP_Execute(PredEntry *pe, CPredicate exec_code)
{ {
CACHE_REGS CACHE_REGS
Int ret; Int ret;
// Term omod = CurrentModule;
//if (pe->PredFlags & CArgsPredFlag) {
// CurrentModule = pe->ModuleOfPred;
//}
if (pe->PredFlags & SWIEnvPredFlag) { if (pe->PredFlags & SWIEnvPredFlag) {
CPredicateV codev = (CPredicateV)exec_code; CPredicateV codev = (CPredicateV)exec_code;
struct foreign_context ctx; struct foreign_context ctx;
@ -1683,6 +1687,7 @@ YAP_Execute(PredEntry *pe, CPredicate exec_code)
ret = (exec_code)( PASS_REGS1 ); ret = (exec_code)( PASS_REGS1 );
} }
PP = NULL; PP = NULL;
//CurrentModule = omod;
if (!ret) { if (!ret) {
Term t; Term t;
@ -2429,6 +2434,8 @@ YAP_RunGoal(Term t)
Yap_StartSlots( PASS_REGS1 ); Yap_StartSlots( PASS_REGS1 );
} else { } else {
ENV = B->cp_env; ENV = B->cp_env;
ENV = (CELL *)ENV[E_E];
CP = old_CP;
B = B->cp_b; B = B->cp_b;
LOCAL_AllowRestart = FALSE; LOCAL_AllowRestart = FALSE;
} }
@ -2503,11 +2510,13 @@ YAP_RunGoalOnce(Term t)
Term out; Term out;
yamop *old_CP = CP; yamop *old_CP = CP;
Int oldPrologMode = LOCAL_PrologMode; Int oldPrologMode = LOCAL_PrologMode;
Int oldSlot = CurSlot;
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
out = Yap_RunTopGoal(t); out = Yap_RunTopGoal(t);
LOCAL_PrologMode = oldPrologMode; LOCAL_PrologMode = oldPrologMode;
CurSlot = oldSlot;
if (!(oldPrologMode & UserCCallMode)) { if (!(oldPrologMode & UserCCallMode)) {
/* called from top-level */ /* called from top-level */
LOCAL_AllowRestart = FALSE; LOCAL_AllowRestart = FALSE;
@ -2538,10 +2547,9 @@ YAP_RunGoalOnce(Term t)
B = cut_pt; B = cut_pt;
} }
ASP = B->cp_env; ASP = B->cp_env;
Yap_PopSlots( PASS_REGS1 );
ENV = (CELL *)ASP[E_E]; ENV = (CELL *)ASP[E_E];
B = (choiceptr)ASP[E_CB]; B = (choiceptr)ASP[E_CB];
#ifdef DEPTH_LIMIT #ifdef DEPTH_LIMITxs
DEPTH = ASP[E_DEPTH]; DEPTH = ASP[E_DEPTH];
#endif #endif
P = (yamop *)ASP[E_CP]; P = (yamop *)ASP[E_CP];
@ -2567,7 +2575,6 @@ YAP_RestartGoal(void)
if (out == FALSE) { if (out == FALSE) {
/* cleanup */ /* cleanup */
Yap_trust_last(); Yap_trust_last();
Yap_CloseSlots( PASS_REGS1 );
LOCAL_AllowRestart = FALSE; LOCAL_AllowRestart = FALSE;
} }
} else { } else {
@ -3043,42 +3050,11 @@ YAP_Init(YAP_init_args *yap_init)
yap_init->SchedulerLoop, yap_init->SchedulerLoop,
yap_init->DelayedReleaseLoad yap_init->DelayedReleaseLoad
); );
#if THREADS
/* make sure we use the correct value of regcache */
regcache = ((REGSTORE *)pthread_getspecific(Yap_yaamregs_key));
#endif
#if USE_SYSTEM_MALLOC
if (Trail < MinTrailSpace)
Trail = MinTrailSpace;
if (Stack < MinStackSpace)
Stack = MinStackSpace;
if (!(LOCAL_GlobalBase = (ADDR)malloc((Trail+Stack)*1024))) {
yap_init->ErrorNo = RESOURCE_ERROR_MEMORY;
yap_init->ErrorCause = "could not allocate stack space for main thread";
return YAP_BOOT_ERROR;
}
#if THREADS
/* don't forget this is a thread */
LOCAL_ThreadHandle.stack_address = LOCAL_GlobalBase;
LOCAL_ThreadHandle.ssize = Trail+Stack;
#endif
#endif
GLOBAL_AllowGlobalExpansion = TRUE;
GLOBAL_AllowLocalExpansion = TRUE;
GLOBAL_AllowTrailExpansion = TRUE;
Yap_InitExStacks (0, Trail, Stack);
if (yap_init->QuietMode) { if (yap_init->QuietMode) {
yap_flags[QUIET_MODE_FLAG] = TRUE; yap_flags[QUIET_MODE_FLAG] = TRUE;
} }
{ BACKUP_MACHINE_REGS(); { if (yap_init->YapPrologRCFile != NULL) {
Yap_InitYaamRegs( 0 );
#if HAVE_MPE
Yap_InitMPE ();
#endif
if (yap_init->YapPrologRCFile != NULL) {
/* /*
This must be done before restore, otherwise This must be done before restore, otherwise
restore will print out messages .... restore will print out messages ....

View File

@ -5416,27 +5416,55 @@ Yap_dump_code_area_for_profiler(void) {
#endif /* LOW_PROF */ #endif /* LOW_PROF */
static UInt static UInt
index_ssz(StaticIndex *x) tree_index_ssz(StaticIndex *x)
{ {
UInt sz = x->ClSize; UInt sz = x->ClSize;
x = x->ChildIndex; x = x->ChildIndex;
while (x != NULL) { while (x != NULL) {
sz += index_ssz(x); sz += tree_index_ssz(x);
x = x->SiblingIndex; x = x->SiblingIndex;
} }
return sz; return sz;
} }
static UInt
index_ssz(StaticIndex *x, PredEntry *pe)
{
UInt sz = 0;
yamop *ep = ExpandClausesFirst;
if (pe->PredFlags & MegaClausePredFlag) {
MegaClause *mcl = ClauseCodeToMegaClause(pe->cs.p_code.FirstClause);
if (mcl->ClFlags & ExoMask) {
struct index_t *i = ((struct index_t **)(pe->cs.p_code.FirstClause))[0];
sz = 0;
while (i) {
sz = i->size+sz;
}
return sz;
}
}
/* expand clause blocks */
while (ep) {
if (ep->u.sssllp.p == pe)
sz += (UInt)NEXTOP((yamop *)NULL,sssllp)+ep->u.sssllp.s1*sizeof(yamop *);
ep = ep->u.sssllp.snext;
}
/* main indexing tree */
sz += tree_index_ssz(x);
return sz;
}
static Int static Int
static_statistics(PredEntry *pe) static_statistics(PredEntry *pe)
{ {
CACHE_REGS CACHE_REGS
UInt sz = 0, cls = 0, isz = 0; UInt sz = sizeof(PredEntry), cls = 0, isz = 0;
StaticClause *cl = ClauseCodeToStaticClause(pe->cs.p_code.FirstClause); StaticClause *cl = ClauseCodeToStaticClause(pe->cs.p_code.FirstClause);
if (pe->cs.p_code.NOfClauses > 1 && if (pe->cs.p_code.NOfClauses > 1 &&
pe->cs.p_code.TrueCodeOfPred != pe->cs.p_code.FirstClause) { pe->cs.p_code.TrueCodeOfPred != pe->cs.p_code.FirstClause) {
isz = index_ssz(ClauseCodeToStaticIndex(pe->cs.p_code.TrueCodeOfPred)); isz = index_ssz(ClauseCodeToStaticIndex(pe->cs.p_code.TrueCodeOfPred), pe);
} }
if (pe->PredFlags & MegaClausePredFlag) { if (pe->PredFlags & MegaClausePredFlag) {
MegaClause *mcl = ClauseCodeToMegaClause(pe->cs.p_code.FirstClause); MegaClause *mcl = ClauseCodeToMegaClause(pe->cs.p_code.FirstClause);

View File

@ -2109,14 +2109,14 @@ c_head(Term t, compiler_struct *cglobs)
if (IsAtomTerm(t)) { if (IsAtomTerm(t)) {
Yap_emit(name_op, (CELL) AtomOfTerm(t), Zero, &cglobs->cint); Yap_emit(name_op, (CELL) AtomOfTerm(t), Zero, &cglobs->cint);
#ifdef BEAM #ifdef BEAM
if (EAM) { if (EAM) {
Yap_emit(run_op,Zero,(UInt) cglobs->cint.CurrentPred,&cglobs->cint); Yap_emit(run_op,Zero,(UInt) cglobs->cint.CurrentPred,&cglobs->cint);
} }
#endif #endif
Yap_emit(ensure_space_op, Zero , Zero, &cglobs->cint);
cglobs->space_op = cglobs->cint.cpc;
return; return;
} }
Yap_emit(ensure_space_op, Zero , Zero, &cglobs->cint);
cglobs->space_op = cglobs->cint.cpc;
f = FunctorOfTerm(t); f = FunctorOfTerm(t);
Yap_emit(name_op, (CELL) NameOfFunctor(f), ArityOfFunctor(f), &cglobs->cint); Yap_emit(name_op, (CELL) NameOfFunctor(f), ArityOfFunctor(f), &cglobs->cint);
#ifdef BEAM #ifdef BEAM
@ -2124,8 +2124,10 @@ c_head(Term t, compiler_struct *cglobs)
Yap_emit(run_op,Zero,(UInt) cglobs->cint.CurrentPred,&cglobs->cint); Yap_emit(run_op,Zero,(UInt) cglobs->cint.CurrentPred,&cglobs->cint);
} }
#endif #endif
if (Yap_ExecutionMode == MIXED_MODE_USER) if (Yap_ExecutionMode == MIXED_MODE_USER)
Yap_emit(native_op, 0, 0, &cglobs->cint); Yap_emit(native_op, 0, 0, &cglobs->cint);
Yap_emit(ensure_space_op, Zero , Zero, &cglobs->cint);
cglobs->space_op = cglobs->cint.cpc;
c_args(t, 0, cglobs); c_args(t, 0, cglobs);
} }
@ -3537,6 +3539,10 @@ Yap_cclause(volatile Term inp_clause, Int NOfArgs, Term mod, volatile Term src)
} }
if (LOCAL_ErrorMessage) if (LOCAL_ErrorMessage)
return (0); return (0);
/* make sure we give enough space for the fact */
if (cglobs.space_op)
cglobs.space_op->rnd1 = cglobs.space_used;
#ifdef DEBUG #ifdef DEBUG
if (GLOBAL_Option['g' - 96]) if (GLOBAL_Option['g' - 96])
Yap_ShowCode(&cglobs.cint); Yap_ShowCode(&cglobs.cint);

View File

@ -3749,7 +3749,7 @@ index_sz(LogUpdIndex *x)
static Int static Int
lu_statistics(PredEntry *pe USES_REGS) lu_statistics(PredEntry *pe USES_REGS)
{ {
UInt sz = 0, cls = 0, isz = 0; UInt sz = sizeof(PredEntry), cls = 0, isz = 0;
/* count number of clauses and size */ /* count number of clauses and size */
LogUpdClause *x; LogUpdClause *x;
@ -3765,10 +3765,16 @@ lu_statistics(PredEntry *pe USES_REGS)
x = x->ClNext; x = x->ClNext;
} }
} }
isz = 0;
if (pe->PredFlags & IndexedPredFlag) { if (pe->PredFlags & IndexedPredFlag) {
isz = index_sz(ClauseCodeToLogUpdIndex(pe->cs.p_code.TrueCodeOfPred)); /* expand clause blocks */
} else { yamop *ep = ExpandClausesFirst;
isz = 0; while (ep) {
if (ep->u.sssllp.p == pe)
isz += (UInt)NEXTOP((yamop *)NULL,sssllp)+ep->u.sssllp.s1*sizeof(yamop *);
ep = ep->u.sssllp.snext;
}
isz += index_sz(ClauseCodeToLogUpdIndex(pe->cs.p_code.TrueCodeOfPred));
} }
return return
Yap_unify(ARG2,MkIntegerTerm(cls)) && Yap_unify(ARG2,MkIntegerTerm(cls)) &&

View File

@ -18,6 +18,11 @@
static char SccsId[] = "%W% %G%"; static char SccsId[] = "%W% %G%";
#endif /* SCCS */ #endif /* SCCS */
#include <math.h>
#ifndef INFINITY
#define INFINITY (1.0/0.0)
#endif
#include "Yap.h" #include "Yap.h"
#ifdef DEPTH_LIMIT #ifdef DEPTH_LIMIT
@ -29,7 +34,10 @@ STD_PROTO(static Int p_set_depth_limit, ( USES_REGS1 ));
static Int p_get_depth_limit( USES_REGS1 ) static Int p_get_depth_limit( USES_REGS1 )
{ {
return(Yap_unify_constant(ARG1, MkIntTerm(IntOfTerm(DEPTH/2)))); Int d = IntOfTerm(DEPTH);
if (d % 2 == 1)
return(Yap_unify(ARG1, MkFloatTerm(INFINITY)));
return(Yap_unify_constant(ARG1, MkIntTerm(d/2)));
} }
static Int p_set_depth_limit( USES_REGS1 ) static Int p_set_depth_limit( USES_REGS1 )
@ -40,8 +48,12 @@ static Int p_set_depth_limit( USES_REGS1 )
Yap_Error(INSTANTIATION_ERROR, d, "set-depth_limit"); Yap_Error(INSTANTIATION_ERROR, d, "set-depth_limit");
return(FALSE); return(FALSE);
} else if (!IsIntegerTerm(d)) { } else if (!IsIntegerTerm(d)) {
Yap_Error(TYPE_ERROR_INTEGER, d, "set-depth_limit"); if (IsFloatTerm(d) && isinf(FloatOfTerm(d))) {
return(FALSE); d = RESET_DEPTH();
} else {
Yap_Error(TYPE_ERROR_INTEGER, d, "set-depth_limit");
return(FALSE);
}
} }
d = MkIntTerm(IntegerOfTerm(d)*2); d = MkIntTerm(IntegerOfTerm(d)*2);
@ -59,6 +71,10 @@ static Int p_set_depth_limit_for_next_call( USES_REGS1 )
Yap_Error(INSTANTIATION_ERROR, d, "set-depth_limit"); Yap_Error(INSTANTIATION_ERROR, d, "set-depth_limit");
return(FALSE); return(FALSE);
} else if (!IsIntegerTerm(d)) { } else if (!IsIntegerTerm(d)) {
if (IsFloatTerm(d) && isinf(FloatOfTerm(d))) {
DEPTH = RESET_DEPTH();
return TRUE;
}
Yap_Error(TYPE_ERROR_INTEGER, d, "set-depth_limit"); Yap_Error(TYPE_ERROR_INTEGER, d, "set-depth_limit");
return(FALSE); return(FALSE);
} }

View File

@ -1441,6 +1441,17 @@ Yap_Error(yap_error_number type, Term where, char *format,...)
serious = TRUE; serious = TRUE;
} }
break; break;
case SAVED_STATE_ERROR:
{
int i;
i = strlen(tmpbuf);
nt[0] = MkAtomTerm(AtomSystemError);
psize -= i;
fun = FunctorError;
serious = TRUE;
}
break;
case SYSTEM_ERROR: case SYSTEM_ERROR:
{ {
int i; int i;

117
C/exec.c
View File

@ -33,6 +33,7 @@ STATIC_PROTO(Int EnterCreepMode, (Term, Term CACHE_TYPE));
STATIC_PROTO(Int p_save_cp, ( USES_REGS1 )); STATIC_PROTO(Int p_save_cp, ( USES_REGS1 ));
STATIC_PROTO(Int p_execute, ( USES_REGS1 )); STATIC_PROTO(Int p_execute, ( USES_REGS1 ));
STATIC_PROTO(Int p_execute0, ( USES_REGS1 )); STATIC_PROTO(Int p_execute0, ( USES_REGS1 ));
static int execute_pred(PredEntry *ppe, CELL *pt USES_REGS);
static Term static Term
cp_as_integer(choiceptr cp USES_REGS) cp_as_integer(choiceptr cp USES_REGS)
@ -666,7 +667,7 @@ p_do_goal_expansion( USES_REGS1 )
if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion2, cmod) ) ) && if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion2, cmod) ) ) &&
pe->OpcodeOfPred != FAIL_OPCODE && pe->OpcodeOfPred != FAIL_OPCODE &&
pe->OpcodeOfPred != UNDEF_OPCODE && pe->OpcodeOfPred != UNDEF_OPCODE &&
CallPredicate(pe, B, pe->CodeOfPred PASS_REGS) ) { execute_pred(pe, NULL PASS_REGS) ) {
out = TRUE; out = TRUE;
ARG3 = ARG2; ARG3 = ARG2;
goto complete; goto complete;
@ -675,7 +676,7 @@ p_do_goal_expansion( USES_REGS1 )
if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion2, SYSTEM_MODULE ) ) ) && if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion2, SYSTEM_MODULE ) ) ) &&
pe->OpcodeOfPred != FAIL_OPCODE && pe->OpcodeOfPred != FAIL_OPCODE &&
pe->OpcodeOfPred != UNDEF_OPCODE && pe->OpcodeOfPred != UNDEF_OPCODE &&
CallPredicate(pe, B, pe->CodeOfPred PASS_REGS) ) { execute_pred(pe, NULL PASS_REGS) ) {
out = TRUE; out = TRUE;
ARG3 = ARG2; ARG3 = ARG2;
goto complete; goto complete;
@ -686,7 +687,7 @@ p_do_goal_expansion( USES_REGS1 )
if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion, USER_MODULE ) ) ) && if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion, USER_MODULE ) ) ) &&
pe->OpcodeOfPred != FAIL_OPCODE && pe->OpcodeOfPred != FAIL_OPCODE &&
pe->OpcodeOfPred != UNDEF_OPCODE && pe->OpcodeOfPred != UNDEF_OPCODE &&
CallPredicate(pe, B, pe->CodeOfPred PASS_REGS) ) { execute_pred(pe, NULL PASS_REGS) ) {
out = TRUE; out = TRUE;
goto complete; goto complete;
} }
@ -696,7 +697,7 @@ p_do_goal_expansion( USES_REGS1 )
(pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion2, USER_MODULE ) ) ) && (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion2, USER_MODULE ) ) ) &&
pe->OpcodeOfPred != FAIL_OPCODE && pe->OpcodeOfPred != FAIL_OPCODE &&
pe->OpcodeOfPred != UNDEF_OPCODE && pe->OpcodeOfPred != UNDEF_OPCODE &&
CallPredicate(pe, B, pe->CodeOfPred PASS_REGS) ) { execute_pred(pe, NULL PASS_REGS) ) {
ARG3 = ARG2; ARG3 = ARG2;
out = TRUE; out = TRUE;
} }
@ -728,7 +729,7 @@ p_do_term_expansion( USES_REGS1 )
if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorTermExpansion, cmod) ) ) && if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorTermExpansion, cmod) ) ) &&
pe->OpcodeOfPred != FAIL_OPCODE && pe->OpcodeOfPred != FAIL_OPCODE &&
pe->OpcodeOfPred != UNDEF_OPCODE && pe->OpcodeOfPred != UNDEF_OPCODE &&
CallPredicate(pe, B, pe->CodeOfPred PASS_REGS) ) { execute_pred(pe, NULL PASS_REGS) ) {
out = TRUE; out = TRUE;
goto complete; goto complete;
} }
@ -736,7 +737,7 @@ p_do_term_expansion( USES_REGS1 )
if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorTermExpansion, SYSTEM_MODULE ) ) ) && if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorTermExpansion, SYSTEM_MODULE ) ) ) &&
pe->OpcodeOfPred != FAIL_OPCODE && pe->OpcodeOfPred != FAIL_OPCODE &&
pe->OpcodeOfPred != UNDEF_OPCODE && pe->OpcodeOfPred != UNDEF_OPCODE &&
CallPredicate(pe, B, pe->CodeOfPred PASS_REGS) ) { execute_pred(pe, NULL PASS_REGS) ) {
out = TRUE; out = TRUE;
goto complete; goto complete;
} }
@ -745,7 +746,7 @@ p_do_term_expansion( USES_REGS1 )
(pe = RepPredProp(Yap_GetPredPropByFunc(FunctorTermExpansion, USER_MODULE ) ) ) && (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorTermExpansion, USER_MODULE ) ) ) &&
pe->OpcodeOfPred != FAIL_OPCODE && pe->OpcodeOfPred != FAIL_OPCODE &&
pe->OpcodeOfPred != UNDEF_OPCODE && pe->OpcodeOfPred != UNDEF_OPCODE &&
CallPredicate(pe, B, pe->CodeOfPred PASS_REGS) ) { execute_pred(pe, NULL PASS_REGS) ) {
out = TRUE; out = TRUE;
} }
complete: complete:
@ -1142,7 +1143,7 @@ init_stack(int arity, CELL *pt, int top, choiceptr saved_b USES_REGS)
/* and now create a pseudo choicepoint for much the same reasons */ /* and now create a pseudo choicepoint for much the same reasons */
/* CP = YESCODE; */ /* CP = YESCODE; */
/* keep a place where you can inform you had an exception */ /* keep a place where you can inform you had an exception */
{ if (pt) {
int i; int i;
for (i = 0; i < arity; i++) { for (i = 0; i < arity; i++) {
XREGS[i+1] = *pt++; XREGS[i+1] = *pt++;
@ -1167,7 +1168,7 @@ init_stack(int arity, CELL *pt, int top, choiceptr saved_b USES_REGS)
} }
static Int static Int
do_goal(Term t, yamop *CodeAdr, int arity, CELL *pt, int top USES_REGS) do_goal(yamop *CodeAdr, int arity, CELL *pt, int top USES_REGS)
{ {
choiceptr saved_b = B; choiceptr saved_b = B;
Int out; Int out;
@ -1193,59 +1194,28 @@ Yap_exec_absmi(int top)
} }
Int static int
Yap_execute_goal(Term t, int nargs, Term mod) execute_pred(PredEntry *ppe, CELL *pt USES_REGS)
{ {
CACHE_REGS
Int out;
yamop *CodeAdr;
yamop *saved_p, *saved_cp; yamop *saved_p, *saved_cp;
Prop pe; Int saved_slot = CurSlot;
PredEntry *ppe; yamop *CodeAdr;
CELL *pt; Int out;
/* preserve the current restart environment */
/* visualc*/
/* just keep the difference because of possible garbage collections */
saved_p = P; saved_p = P;
saved_cp = CP; saved_cp = CP;
if (IsAtomTerm(t)) { PELOCK(81,ppe);
Atom a = AtomOfTerm(t); if (ppe->ArityOfPE == 0) {
pt = NULL;
pe = PredPropByAtom(a, mod);
} else if (IsApplTerm(t)) {
Functor f = FunctorOfTerm(t);
if (IsBlobFunctor(f)) {
Yap_Error(TYPE_ERROR_CALLABLE,t,"call/1");
return(FALSE);
}
/* I cannot use the standard macro here because
otherwise I would dereference the argument and
might skip a svar */
pt = RepAppl(t)+1;
pe = PredPropByFunc(f, mod);
} else {
Yap_Error(TYPE_ERROR_CALLABLE,t,"call/1");
return(FALSE);
}
ppe = RepPredProp(pe);
if (pe == NIL) {
return CallMetaCall(t, mod PASS_REGS);
}
PELOCK(81,RepPredProp(pe));
if (IsAtomTerm(t)) {
CodeAdr = ppe->CodeOfPred; CodeAdr = ppe->CodeOfPred;
UNLOCK(ppe->PELock); UNLOCK(ppe->PELock);
out = do_goal(t, CodeAdr, 0, pt, FALSE PASS_REGS); out = do_goal(CodeAdr, 0, pt, FALSE PASS_REGS);
} else { } else {
Functor f = FunctorOfTerm(t);
CodeAdr = ppe->CodeOfPred; CodeAdr = ppe->CodeOfPred;
UNLOCK(ppe->PELock); UNLOCK(ppe->PELock);
out = do_goal(t, CodeAdr, ArityOfFunctor(f), pt, FALSE PASS_REGS); out = do_goal(CodeAdr, ppe->ArityOfPE, pt, FALSE PASS_REGS);
} }
CurSlot = saved_slot;
if (out == 1) { if (out == 1) {
choiceptr cut_B; choiceptr cut_B;
@ -1284,15 +1254,13 @@ Yap_execute_goal(Term t, int nargs, Term mod)
DEPTH= ENV[E_DEPTH]; DEPTH= ENV[E_DEPTH];
#endif #endif
ENV = (CELL *)(ENV[E_E]); ENV = (CELL *)(ENV[E_E]);
Yap_StartSlots( PASS_REGS1 );
/* we have failed, and usually we would backtrack to this B, /* we have failed, and usually we would backtrack to this B,
trouble is, we may also have a delayed cut to do */ trouble is, we may also have a delayed cut to do */
if (B != NULL) if (B != NULL)
HB = B->cp_h; HB = B->cp_h;
YENV = ENV; YENV = ENV;
return(TRUE); return TRUE;
} else if (out == 0) { } else if (out == 0) {
ASP = B->cp_env;
P = saved_p; P = saved_p;
CP = saved_cp; CP = saved_cp;
H = B->cp_h; H = B->cp_h;
@ -1314,6 +1282,47 @@ Yap_execute_goal(Term t, int nargs, Term mod)
} }
} }
Int
Yap_execute_goal(Term t, int nargs, Term mod)
{
CACHE_REGS
Prop pe;
PredEntry *ppe;
CELL *pt;
/* preserve the current restart environment */
/* visualc*/
/* just keep the difference because of possible garbage collections */
if (IsAtomTerm(t)) {
Atom a = AtomOfTerm(t);
pt = NULL;
pe = PredPropByAtom(a, mod);
} else if (IsApplTerm(t)) {
Functor f = FunctorOfTerm(t);
if (IsBlobFunctor(f)) {
Yap_Error(TYPE_ERROR_CALLABLE,t,"call/1");
return(FALSE);
}
/* I cannot use the standard macro here because
otherwise I would dereference the argument and
might skip a svar */
pt = RepAppl(t)+1;
pe = PredPropByFunc(f, mod);
} else {
Yap_Error(TYPE_ERROR_CALLABLE,t,"call/1");
return(FALSE);
}
ppe = RepPredProp(pe);
if (pe == NIL) {
return CallMetaCall(t, mod PASS_REGS);
}
return execute_pred(ppe, pt PASS_REGS);
}
void void
Yap_trust_last(void) Yap_trust_last(void)
{ {
@ -1399,7 +1408,7 @@ Yap_RunTopGoal(Term t)
"unable to boot because of too little Trail space"); "unable to boot because of too little Trail space");
} }
#endif #endif
goal_out = do_goal(t, CodeAdr, arity, pt, TRUE PASS_REGS); goal_out = do_goal(CodeAdr, arity, pt, TRUE PASS_REGS);
return goal_out; return goal_out;
} }

View File

@ -143,6 +143,7 @@ INSERT(CELL *cl, struct index_t *it, UInt arity, UInt base, UInt hash0, UInt bnd
if (bnds[k]) { if (bnds[k]) {
if (*target != cl[k]) { if (*target != cl[k]) {
/* found a new forking point */ /* found a new forking point */
// printf("j=%ld hash0=%ld cl[j]=%lx\n", j, hash0, cl[j]);
INSERT(cl, it, arity, k, hash0, bnds); INSERT(cl, it, arity, k, hash0, bnds);
return; return;
} }
@ -229,6 +230,7 @@ fill_hash(UInt bmap, struct index_t *it, UInt bnds[])
static struct index_t * static struct index_t *
add_index(struct index_t **ip, UInt bmap, PredEntry *ap, UInt count, UInt bnds[]) add_index(struct index_t **ip, UInt bmap, PredEntry *ap, UInt count, UInt bnds[])
{ {
CACHE_REGS
UInt ncls = ap->cs.p_code.NOfClauses, j; UInt ncls = ap->cs.p_code.NOfClauses, j;
CELL *base = NULL; CELL *base = NULL;
struct index_t *i; struct index_t *i;
@ -264,6 +266,7 @@ add_index(struct index_t **ip, UInt bmap, PredEntry *ap, UInt count, UInt bnds[]
} }
bzero(base, 3*sizeof(CELL)*ncls); bzero(base, 3*sizeof(CELL)*ncls);
} }
i->size = sizeof(CELL)*(ncls+i->hsize)+sz+sizeof(struct index_t);
i->key = (CELL **)base; i->key = (CELL **)base;
i->links = (CELL *)(base+i->hsize); i->links = (CELL *)(base+i->hsize);
i->ncollisions = i->nentries = i->ntrys = 0; i->ncollisions = i->nentries = i->ntrys = 0;
@ -308,6 +311,7 @@ add_index(struct index_t **ip, UInt bmap, PredEntry *ap, UInt count, UInt bnds[]
ptr = NEXTOP(ptr, p); ptr = NEXTOP(ptr, p);
ptr->opc = Yap_opcode(_Ystop); ptr->opc = Yap_opcode(_Ystop);
ptr->u.l.l = i->code; ptr->u.l.l = i->code;
Yap_inform_profiler_of_clause((char *)(i->code), (char *)NEXTOP(ptr,l), ap, GPROF_INDEX);
return i; return i;
} }

View File

@ -4173,7 +4173,7 @@ call_gc(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop USES_REGS)
} }
/* /*
* debug for(save_total=1; save_total<=N; ++save_total) * debug for(save_total=1; save_total<=N; ++save_total)
* plwrite(XREGS[save_total],NULL,30,0,0); * plwrite(XREGS[save_total],NULL,30,0,0,0);
*/ */
return TRUE; return TRUE;
} }

View File

@ -884,6 +884,13 @@ InitStdPreds(void)
{ {
Yap_InitCPreds(); Yap_InitCPreds();
Yap_InitBackCPreds(); Yap_InitBackCPreds();
BACKUP_MACHINE_REGS();
Yap_InitYaamRegs( 0 );
#if HAVE_MPE
Yap_InitMPE ();
#endif
initIO();
} }
static void static void
@ -1005,9 +1012,12 @@ InitLogDBErasedMarker(void)
static void static void
InitSWIAtoms(void) InitSWIAtoms(void)
{ {
extern atom_t ATOM_;
int i=0, j=0; int i=0, j=0;
#include "iswiatoms.h" #include "iswiatoms.h"
Yap_InitSWIHash(); Yap_InitSWIHash();
ATOM_ = PL_new_atom("");
} }
static void static void
@ -1331,6 +1341,29 @@ Yap_InitWorkspace(UInt Heap, UInt Stack, UInt Trail, UInt Atts, UInt max_table_s
InitDebug(); InitDebug();
InitVersion(); InitVersion();
Yap_InitSysPath(); Yap_InitSysPath();
#if THREADS
/* make sure we use the correct value of regcache */
regcache = ((REGSTORE *)pthread_getspecific(Yap_yaamregs_key));
#endif
#if USE_SYSTEM_MALLOC
if (Trail < MinTrailSpace)
Trail = MinTrailSpace;
if (Stack < MinStackSpace)
Stack = MinStackSpace;
if (!(LOCAL_GlobalBase = (ADDR)malloc((Trail+Stack)*1024))) {
Yap_Error(RESOURCE_ERROR_MEMORY, 0, "could not allocate stack space for main thread");
Yap_exit(1);
}
#if THREADS
/* don't forget this is a thread */
LOCAL_ThreadHandle.stack_address = LOCAL_GlobalBase;
LOCAL_ThreadHandle.ssize = Trail+Stack;
#endif
#endif
GLOBAL_AllowGlobalExpansion = TRUE;
GLOBAL_AllowLocalExpansion = TRUE;
GLOBAL_AllowTrailExpansion = TRUE;
Yap_InitExStacks (0, Trail, Stack);
InitStdPreds(); InitStdPreds();
/* make sure tmp area is available */ /* make sure tmp area is available */
{ {

6
C/iopreds.c Normal file → Executable file
View File

@ -219,10 +219,10 @@ Yap_GetCharForSIGINT(void)
{ {
int ch; int ch;
/* ask for a new line */ /* ask for a new line */
fprintf(stderr, "Action (h for help): "); Sfprintf(Serror, "\nAction (h for help): ");
ch = getc(stdin); ch = Sgetchar();
/* first process up to end of line */ /* first process up to end of line */
while ((fgetc(stdin)) != '\n'); while ((Sfgetc(Sinput)) != '\n');
newline = TRUE; newline = TRUE;
return ch; return ch;
} }

View File

@ -27,10 +27,10 @@
* YAP_FindExecutable(argv[0]) should be called on yap initialization to * YAP_FindExecutable(argv[0]) should be called on yap initialization to
* locate the executable of Yap * locate the executable of Yap
*/ */
void char *
Yap_FindExecutable(char *name) Yap_FindExecutable(void)
{ {
return NULL; return "yap";
} }
void * void *

View File

@ -177,6 +177,23 @@ Yap_SetDefaultEncoding(IOENC new_encoding)
LD->encoding = new_encoding; LD->encoding = new_encoding;
} }
int
PL_qualify(term_t raw, term_t qualified)
{ GET_LD
Module m = NULL;
term_t mname;
if ( !(mname = PL_new_term_ref()) ||
!PL_strip_module(raw, &m, qualified) )
return FALSE;
/* modules are terms in YAP */
Yap_PutInSlot(mname, (Term)m PASS_REGS);
return PL_cons_functor(qualified, FUNCTOR_colon2, mname, qualified);
}
int int
valueExpression(term_t t, Number r ARG_LD) valueExpression(term_t t, Number r ARG_LD)
{ {
@ -284,6 +301,8 @@ int
_PL_unify_atomic(term_t t, PL_atomic_t a) _PL_unify_atomic(term_t t, PL_atomic_t a)
{ {
GET_LD GET_LD
if (IsApplTerm(a) || IsAtomTerm(a))
return Yap_unify(Yap_GetFromSlot(t PASS_REGS), a);
return PL_unify_atom(t, a); return PL_unify_atom(t, a);
} }
@ -482,8 +501,6 @@ PL_set_prolog_flag(const char *name, int type, ...)
int rval = TRUE; int rval = TRUE;
int flags = (type & FF_MASK); int flags = (type & FF_MASK);
initPrologFlagTable();
va_start(args, type); va_start(args, type);
switch(type & ~FF_MASK) switch(type & ~FF_MASK)
{ case PL_BOOL: { case PL_BOOL:
@ -496,7 +513,7 @@ PL_set_prolog_flag(const char *name, int type, ...)
{ const char *v = va_arg(args, const char *); { const char *v = va_arg(args, const char *);
#ifndef __YAP_PROLOG__ #ifndef __YAP_PROLOG__
if ( !GD->initialised ) if ( !GD->initialised )
initAtoms(); initAtoms();
#endif #endif
setPrologFlag(name, FT_ATOM|flags, v); setPrologFlag(name, FT_ATOM|flags, v);
break; break;
@ -509,13 +526,12 @@ PL_set_prolog_flag(const char *name, int type, ...)
default: default:
rval = FALSE; rval = FALSE;
} }
va_end(args); va_end(args);
return rval; return rval;
} }
int int
PL_unify_chars(term_t t, int flags, size_t len, const char *s) PL_unify_chars(term_t t, int flags, size_t len, const char *s)
{ PL_chars_t text; { PL_chars_t text;
@ -761,6 +777,12 @@ PL_get_list_nchars(term_t l, size_t *length, char **s, unsigned int flags)
fail; fail;
} }
void *
PL_malloc_uncollectable(size_t sz)
{
return malloc(sz);
}
int int
PL_get_list_chars(term_t l, char **s, unsigned flags) PL_get_list_chars(term_t l, char **s, unsigned flags)
{ return PL_get_list_nchars(l, NULL, s, flags); { return PL_get_list_nchars(l, NULL, s, flags);
@ -1213,6 +1235,68 @@ nameOfWideAtom(atom_t atom)
return RepAtom(a)->WStrOfAE; return RepAtom(a)->WStrOfAE;
} }
access_level_t
setAccessLevel(access_level_t accept)
{ GET_LD
bool old;
old = LD->prolog_flag.access_level;
LD->prolog_flag.access_level = accept;
return old;
}
static bool
vsysError(const char *fm, va_list args)
{ GET_LD
static int active = 0;
switch ( active++ )
{ case 1:
PL_halt(3);
case 2:
abort();
}
#ifdef O_PLMT
Sfprintf(Serror, "[PROLOG SYSTEM ERROR: Thread %d\n\t",
PL_thread_self());
#else
Sfprintf(Serror, "[PROLOG SYSTEM ERROR:\n\t");
#endif
Svfprintf(Serror, fm, args);
#if defined(O_DEBUGGER)
Sfprintf(Serror, "\n\nPROLOG STACK:\n");
PL_backtrace(10, 0);
Sfprintf(Serror, "]\n");
#endif /*O_DEBUGGER*/
#ifdef HAVE_GETPID
Sfprintf(Serror, "\n[pid=%d] Action? ", getpid());
#else
Sfprintf(Serror, "\nAction? ");
#endif
Sflush(Soutput);
ResetTty();
PL_halt(3);
return FALSE; /* not reached */
}
bool
sysError(const char *fm, ...)
{ va_list args;
va_start(args, fm);
vsysError(fm, args);
va_end(args);
PL_fail;
}
#if THREADS #if THREADS

View File

@ -47,6 +47,20 @@ typedef enum {
BAD_READ = 11 BAD_READ = 11
} qlfr_err_t; } qlfr_err_t;
static char *
qlyr_error[] = { "out of temporary space",
"out of temporary space",
"out of code space",
"unknown atom in saved space",
"unknown functor in saved space",
"unknown predicate in saved space",
"unknown YAAM opcode in saved space",
"unknown data-base reference in saved space",
"corrupted atom in saved space",
"formatting mismatch in saved space",
"foreign predicate has different definition in saved space",
"bad read" };
static char * static char *
Yap_AlwaysAllocCodeSpace(UInt size) Yap_AlwaysAllocCodeSpace(UInt size)
{ {
@ -62,7 +76,7 @@ Yap_AlwaysAllocCodeSpace(UInt size)
static void static void
QLYR_ERROR(qlfr_err_t my_err) QLYR_ERROR(qlfr_err_t my_err)
{ {
fprintf(stderr,"Error %d\n", my_err); Yap_Error(SAVED_STATE_ERROR,TermNil,"error %s in saved state %s",GLOBAL_RestoreFile, qlyr_error[my_err]);
exit(1); exit(1);
} }
@ -1056,8 +1070,10 @@ Yap_Restore(char *s, char *lib_dir)
IOSTREAM *stream = Yap_OpenRestore(s, lib_dir); IOSTREAM *stream = Yap_OpenRestore(s, lib_dir);
if (!stream) if (!stream)
return -1; return -1;
GLOBAL_RestoreFile = s;
read_module(stream); read_module(stream);
Sclose( stream ); Sclose( stream );
GLOBAL_RestoreFile = NULL;
return DO_ONLY_CODE; return DO_ONLY_CODE;
} }

View File

@ -685,8 +685,8 @@ check_header(CELL *info, CELL *ATrail, CELL *AStack, CELL *AHeap USES_REGS)
if (strcmp(pp, msg) != 0) { if (strcmp(pp, msg) != 0) {
LOCAL_ErrorMessage = LOCAL_ErrorSay; LOCAL_ErrorMessage = LOCAL_ErrorSay;
strncpy(LOCAL_ErrorMessage, "saved state ", MAX_ERROR_MSG_SIZE); strncpy(LOCAL_ErrorMessage, "saved state ", MAX_ERROR_MSG_SIZE);
strncat(LOCAL_ErrorMessage, LOCAL_FileNameBuf, MAX_ERROR_MSG_SIZE); strncat(LOCAL_ErrorMessage, LOCAL_FileNameBuf, MAX_ERROR_MSG_SIZE-1);
strncat(LOCAL_ErrorMessage, " failed to match version ID", MAX_ERROR_MSG_SIZE); strncat(LOCAL_ErrorMessage, " failed to match version ID", MAX_ERROR_MSG_SIZE-1);
LOCAL_Error_TYPE = CONSISTENCY_ERROR; LOCAL_Error_TYPE = CONSISTENCY_ERROR;
return FAIL_RESTORE; return FAIL_RESTORE;
} }

View File

@ -3886,12 +3886,12 @@ p_statistics_atom_info( USES_REGS1 )
while (catom != NIL) { while (catom != NIL) {
Atom ncatom; Atom ncatom;
count++; count++;
spaceused += sizeof(AtomEntry)+strlen(RepAtom(catom)->StrOfAE); spaceused += sizeof(AtomEntry)+strlen(RepAtom(catom)->StrOfAE)+1;
ncatom = RepAtom(catom)->NextOfAE; ncatom = RepAtom(catom)->NextOfAE;
if (ncatom != NIL) { if (ncatom != NIL) {
READ_LOCK(RepAtom(ncatom)->ARWLock); READ_LOCK(RepAtom(ncatom)->ARWLock);
} }
READ_UNLOCK(RepAtom(ncatom)->ARWLock); READ_UNLOCK(RepAtom(catom)->ARWLock);
catom = ncatom; catom = ncatom;
} }
} }
@ -3907,12 +3907,12 @@ p_statistics_atom_info( USES_REGS1 )
while (catom != NIL) { while (catom != NIL) {
Atom ncatom; Atom ncatom;
count++; count++;
spaceused += sizeof(AtomEntry)+wcslen((wchar_t *)( RepAtom(catom)->StrOfAE)); spaceused += sizeof(AtomEntry)+sizeof(wchar_t)*(wcslen((wchar_t *)( RepAtom(catom)->StrOfAE)+1));
ncatom = RepAtom(catom)->NextOfAE; ncatom = RepAtom(catom)->NextOfAE;
if (ncatom != NIL) { if (ncatom != NIL) {
READ_LOCK(RepAtom(ncatom)->ARWLock); READ_LOCK(RepAtom(ncatom)->ARWLock);
} }
READ_UNLOCK(RepAtom(ncatom)->ARWLock); READ_UNLOCK(RepAtom(catom)->ARWLock);
catom = ncatom; catom = ncatom;
} }
} }
@ -4361,10 +4361,6 @@ Yap_InitBackCPreds(void)
#if defined CUT_C && (defined MYDDAS_ODBC || defined MYDDAS_MYSQL) #if defined CUT_C && (defined MYDDAS_ODBC || defined MYDDAS_MYSQL)
Yap_InitBackMYDDAS_SharedPreds(); Yap_InitBackMYDDAS_SharedPreds();
#endif #endif
{
extern void initIO(void);
initIO();
}
} }
typedef void (*Proc)(void); typedef void (*Proc)(void);

View File

@ -2657,6 +2657,353 @@ p_new_variables_in_term( USES_REGS1 ) /* variables within term t */
return Yap_unify(ARG3,out); return Yap_unify(ARG3,out);
} }
static Term free_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end, tr_fr_ptr TR0 USES_REGS)
{
register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace();
CELL *InitialH = H;
*H++ = MkAtomTerm(AtomDollar);
to_visit0 = to_visit;
loop:
while (pt0 < pt0_end) {
register CELL d0;
register CELL *ptd0;
++ pt0;
ptd0 = pt0;
d0 = *ptd0;
deref_head(d0, vars_within_term_unk);
vars_within_term_nvar:
{
if (IsPairTerm(d0)) {
if (to_visit + 1024 >= (CELL **)AuxSp) {
goto aux_overflow;
}
#ifdef RATIONAL_TREES
to_visit[0] = pt0;
to_visit[1] = pt0_end;
to_visit[2] = (CELL *)*pt0;
to_visit += 3;
*pt0 = TermNil;
#else
if (pt0 < pt0_end) {
to_visit[0] = pt0;
to_visit[1] = pt0_end;
to_visit += 2;
}
#endif
pt0 = RepPair(d0) - 1;
pt0_end = RepPair(d0) + 1;
} else if (IsApplTerm(d0)) {
register Functor f;
register CELL *ap2;
/* store the terms to visit */
ap2 = RepAppl(d0);
f = (Functor)(*ap2);
if (IsExtensionFunctor(f)) {
continue;
}
/* store the terms to visit */
if (to_visit + 1024 >= (CELL **)AuxSp) {
goto aux_overflow;
}
#ifdef RATIONAL_TREES
to_visit[0] = pt0;
to_visit[1] = pt0_end;
to_visit[2] = (CELL *)*pt0;
to_visit += 3;
*pt0 = TermNil;
#else
if (pt0 < pt0_end) {
to_visit[0] = pt0;
to_visit[1] = pt0_end;
to_visit += 2;
}
#endif
d0 = ArityOfFunctor(f);
pt0 = ap2;
pt0_end = ap2 + d0;
}
continue;
}
derefa_body(d0, ptd0, vars_within_term_unk, vars_within_term_nvar);
/* do or pt2 are unbound */
*ptd0 = TermNil;
/* leave an empty slot to fill in later */
if (H+1024 > ASP) {
goto global_overflow;
}
H[0] = (CELL)ptd0;
H ++;
/* next make sure noone will see this as a variable again */
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) {
/* Trail overflow */
if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) {
goto trail_overflow;
}
}
TrailTerm(TR++) = (CELL)ptd0;
}
/* Do we still have compound terms to visit */
if (to_visit > to_visit0) {
#ifdef RATIONAL_TREES
to_visit -= 3;
pt0 = to_visit[0];
pt0_end = to_visit[1];
*pt0 = (CELL)to_visit[2];
#else
to_visit -= 2;
pt0 = to_visit[0];
pt0_end = to_visit[1];
#endif
goto loop;
}
clean_tr(TR0 PASS_REGS);
Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0);
if (H != InitialH+1) {
InitialH[0] = (CELL)Yap_MkFunctor(AtomDollar, (H-InitialH)-1);
return AbsAppl(InitialH);
} else {
return MkAtomTerm(AtomDollar);
}
trail_overflow:
#ifdef RATIONAL_TREES
while (to_visit > to_visit0) {
to_visit -= 3;
pt0 = to_visit[0];
*pt0 = (CELL)to_visit[2];
}
#endif
LOCAL_Error_TYPE = OUT_OF_TRAIL_ERROR;
LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *);
clean_tr(TR0 PASS_REGS);
Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0);
H = InitialH;
return 0L;
aux_overflow:
LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **);
#ifdef RATIONAL_TREES
while (to_visit > to_visit0) {
to_visit -= 3;
pt0 = to_visit[0];
*pt0 = (CELL)to_visit[2];
}
#endif
LOCAL_Error_TYPE = OUT_OF_AUXSPACE_ERROR;
clean_tr(TR0 PASS_REGS);
Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0);
H = InitialH;
return 0L;
global_overflow:
#ifdef RATIONAL_TREES
while (to_visit > to_visit0) {
to_visit -= 3;
pt0 = to_visit[0];
*pt0 = (CELL)to_visit[2];
}
#endif
clean_tr(TR0 PASS_REGS);
Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0);
H = InitialH;
LOCAL_Error_TYPE = OUT_OF_STACK_ERROR;
LOCAL_Error_Size = (ASP-H)*sizeof(CELL);
return 0L;
}
static Term bind_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end, tr_fr_ptr TR0 USES_REGS)
{
register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace();
CELL *InitialH = H;
to_visit0 = to_visit;
loop:
while (pt0 < pt0_end) {
register CELL d0;
register CELL *ptd0;
++ pt0;
ptd0 = pt0;
d0 = *ptd0;
deref_head(d0, vars_within_term_unk);
vars_within_term_nvar:
{
if (IsPairTerm(d0)) {
if (to_visit + 1024 >= (CELL **)AuxSp) {
goto aux_overflow;
}
#ifdef RATIONAL_TREES
to_visit[0] = pt0;
to_visit[1] = pt0_end;
to_visit[2] = (CELL *)*pt0;
to_visit += 3;
*pt0 = TermNil;
#else
if (pt0 < pt0_end) {
to_visit[0] = pt0;
to_visit[1] = pt0_end;
to_visit += 2;
}
#endif
pt0 = RepPair(d0) - 1;
pt0_end = RepPair(d0) + 1;
} else if (IsApplTerm(d0)) {
register Functor f;
register CELL *ap2;
/* store the terms to visit */
ap2 = RepAppl(d0);
f = (Functor)(*ap2);
if (IsExtensionFunctor(f)) {
continue;
}
/* store the terms to visit */
if (to_visit + 1024 >= (CELL **)AuxSp) {
goto aux_overflow;
}
#ifdef RATIONAL_TREES
to_visit[0] = pt0;
to_visit[1] = pt0_end;
to_visit[2] = (CELL *)*pt0;
to_visit += 3;
*pt0 = TermNil;
#else
if (pt0 < pt0_end) {
to_visit[0] = pt0;
to_visit[1] = pt0_end;
to_visit += 2;
}
#endif
d0 = ArityOfFunctor(f);
pt0 = ap2;
pt0_end = ap2 + d0;
}
continue;
}
derefa_body(d0, ptd0, vars_within_term_unk, vars_within_term_nvar);
/* do or pt2 are unbound */
*ptd0 = TermFoundVar;
/* next make sure noone will see this as a variable again */
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) {
/* Trail overflow */
if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) {
goto trail_overflow;
}
}
TrailTerm(TR++) = (CELL)ptd0;
}
/* Do we still have compound terms to visit */
if (to_visit > to_visit0) {
#ifdef RATIONAL_TREES
to_visit -= 3;
pt0 = to_visit[0];
pt0_end = to_visit[1];
*pt0 = (CELL)to_visit[2];
#else
to_visit -= 2;
pt0 = to_visit[0];
pt0_end = to_visit[1];
#endif
goto loop;
}
Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0);
return TermNil;
trail_overflow:
#ifdef RATIONAL_TREES
while (to_visit > to_visit0) {
to_visit -= 3;
pt0 = to_visit[0];
*pt0 = (CELL)to_visit[2];
}
#endif
LOCAL_Error_TYPE = OUT_OF_TRAIL_ERROR;
LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *);
clean_tr(TR0 PASS_REGS);
Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0);
H = InitialH;
return 0L;
aux_overflow:
LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **);
#ifdef RATIONAL_TREES
while (to_visit > to_visit0) {
to_visit -= 3;
pt0 = to_visit[0];
*pt0 = (CELL)to_visit[2];
}
#endif
LOCAL_Error_TYPE = OUT_OF_AUXSPACE_ERROR;
clean_tr(TR0 PASS_REGS);
Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0);
H = InitialH;
return 0L;
}
static Int
p_free_variables_in_term( USES_REGS1 ) /* variables within term t */
{
Term out;
Term t, t0;
Term found_module = 0L;
do {
tr_fr_ptr TR0 = TR;
t = t0 = Deref(ARG1);
while (!IsVarTerm(t) && IsApplTerm(t)) {
Functor f = FunctorOfTerm(t);
if (f == FunctorHat) {
out = bind_vars_in_complex_term(RepAppl(t),
RepAppl(t)+1, TR0 PASS_REGS);
if (out == 0L) {
goto trail_overflow;
}
} else if (f == FunctorModule) {
found_module = ArgOfTerm(1, t);
} else {
break;
}
t = ArgOfTerm(2,t);
}
if (IsVarTerm(t)) {
out = free_vars_in_complex_term(VarOfTerm(t)-1,
VarOfTerm(t), TR0 PASS_REGS);
} else if (IsPrimitiveTerm(t))
out = TermNil;
else if (IsPairTerm(t)) {
out = free_vars_in_complex_term(RepPair(t)-1,
RepPair(t)+1, TR0 PASS_REGS);
}
else {
Functor f = FunctorOfTerm(t);
out = free_vars_in_complex_term(RepAppl(t),
RepAppl(t)+
ArityOfFunctor(f), TR0 PASS_REGS);
}
if (out == 0L) {
trail_overflow:
if (!expand_vts( 3 PASS_REGS ))
return FALSE;
}
} while (out == 0L);
if (found_module && t!=t0) {
Term ts[2];
ts[0] = found_module;
ts[1] = t;
t = Yap_MkApplTerm(FunctorModule, 2, ts);
}
return
Yap_unify(ARG2, t) &&
Yap_unify(ARG3,out);
}
static Term non_singletons_in_complex_term(register CELL *pt0, register CELL *pt0_end USES_REGS) static Term non_singletons_in_complex_term(register CELL *pt0, register CELL *pt0_end USES_REGS)
{ {
@ -5196,6 +5543,7 @@ void Yap_InitUtilCPreds(void)
Yap_InitCPred("copy_term_nat", 2, p_copy_term_no_delays, 0); Yap_InitCPred("copy_term_nat", 2, p_copy_term_no_delays, 0);
Yap_InitCPred("ground", 1, p_ground, SafePredFlag); Yap_InitCPred("ground", 1, p_ground, SafePredFlag);
Yap_InitCPred("$variables_in_term", 3, p_variables_in_term, 0); Yap_InitCPred("$variables_in_term", 3, p_variables_in_term, 0);
Yap_InitCPred("$free_variables_in_term", 3, p_free_variables_in_term, 0);
Yap_InitCPred("$non_singletons_in_term", 3, p_non_singletons_in_term, 0); Yap_InitCPred("$non_singletons_in_term", 3, p_non_singletons_in_term, 0);
Yap_InitCPred("term_variables", 2, p_term_variables, 0); Yap_InitCPred("term_variables", 2, p_term_variables, 0);
Yap_InitCPred("term_variables", 3, p_term_variables3, 0); Yap_InitCPred("term_variables", 3, p_term_variables3, 0);

11
H/Yap.h
View File

@ -88,7 +88,7 @@
#undef USE_THREADED_CODE #undef USE_THREADED_CODE
#endif /* USE_THREADED_CODE */ #endif /* USE_THREADED_CODE */
#define inline __inline #define inline __inline
#define YAP_VERSION "YAP-6.3.2" #define YAP_VERSION "YAP-6.3.4"
#define BIN_DIR "c:\\Yap\\bin" #define BIN_DIR "c:\\Yap\\bin"
#define LIB_DIR "c:\\Yap\\lib\\Yap" #define LIB_DIR "c:\\Yap\\lib\\Yap"
#define SHARE_DIR "c:\\Yap\\share\\Yap" #define SHARE_DIR "c:\\Yap\\share\\Yap"
@ -121,6 +121,14 @@
#define DUMMY_FILLER_FOR_ABS_TYPE int dummy; #define DUMMY_FILLER_FOR_ABS_TYPE int dummy;
#endif /* HAVE_GCC */ #endif /* HAVE_GCC */
#ifdef HAVE___BUILTIN_EXPECT
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#ifdef THREADS #ifdef THREADS
#if USE_PTHREAD_LOCKING #if USE_PTHREAD_LOCKING
#ifndef _XOPEN_SOURCE #ifndef _XOPEN_SOURCE
@ -403,6 +411,7 @@ typedef enum
RESOURCE_ERROR_MEMORY, RESOURCE_ERROR_MEMORY,
RESOURCE_ERROR_STACK, RESOURCE_ERROR_STACK,
RETRY_COUNTER_UNDERFLOW, RETRY_COUNTER_UNDERFLOW,
SAVED_STATE_ERROR,
SYNTAX_ERROR, SYNTAX_ERROR,
SYSTEM_ERROR, SYSTEM_ERROR,
TYPE_ERROR_ARRAY, TYPE_ERROR_ARRAY,

View File

@ -9,8 +9,10 @@
OPCODE(trust_me ,Otapl), OPCODE(trust_me ,Otapl),
OPCODE(enter_exo ,e), OPCODE(enter_exo ,e),
OPCODE(try_exo ,lp), OPCODE(try_exo ,lp),
OPCODE(try_udi ,p),
OPCODE(try_all_exo ,lp), OPCODE(try_all_exo ,lp),
OPCODE(retry_exo ,lp), OPCODE(retry_exo ,lp),
OPCODE(retry_udi ,p),
OPCODE(retry_all_exo ,lp), OPCODE(retry_all_exo ,lp),
OPCODE(enter_profiling ,p), OPCODE(enter_profiling ,p),
OPCODE(retry_profiled ,p), OPCODE(retry_profiled ,p),

View File

@ -173,6 +173,7 @@ typedef struct index_t {
CELL **key; CELL **key;
CELL *cls; CELL *cls;
CELL *links; CELL *links;
size_t size;
yamop *code; yamop *code;
} Index_t; } Index_t;

View File

@ -98,4 +98,5 @@
#endif #endif
#define GLOBAL_RestoreFile Yap_global->RestoreFile_

View File

@ -433,3 +433,6 @@
#define LOCAL_ibnds LOCAL->ibnds_ #define LOCAL_ibnds LOCAL->ibnds_
#define REMOTE_ibnds(wid) REMOTE(wid)->ibnds_ #define REMOTE_ibnds(wid) REMOTE(wid)->ibnds_
#define LOCAL_search_atoms LOCAL->search_atoms_
#define REMOTE_search_atoms(wid) REMOTE(wid)->search_atoms_

View File

@ -98,4 +98,5 @@ typedef struct global_data {
#endif #endif
char* RestoreFile_;
} w_shared; } w_shared;

View File

@ -243,4 +243,6 @@ typedef struct worker_local {
Functor FunctorVar_; Functor FunctorVar_;
UInt ibnds_[256]; UInt ibnds_[256];
struct scan_atoms* search_atoms_;
} w_local; } w_local;

View File

@ -74,6 +74,7 @@
AtomDefault = Yap_LookupAtom("default"); AtomDefault = Yap_LookupAtom("default");
AtomDevNull = Yap_LookupAtom("/dev/null"); AtomDevNull = Yap_LookupAtom("/dev/null");
AtomDiff = Yap_LookupAtom("\\="); AtomDiff = Yap_LookupAtom("\\=");
AtomDollar = Yap_FullLookupAtom("$");
AtomDoLogUpdClause = Yap_FullLookupAtom("$do_log_upd_clause"); AtomDoLogUpdClause = Yap_FullLookupAtom("$do_log_upd_clause");
AtomDoLogUpdClause0 = Yap_FullLookupAtom("$do_log_upd_clause0"); AtomDoLogUpdClause0 = Yap_FullLookupAtom("$do_log_upd_clause0");
AtomDoLogUpdClauseErase = Yap_FullLookupAtom("$do_log_upd_clause_erase"); AtomDoLogUpdClauseErase = Yap_FullLookupAtom("$do_log_upd_clause_erase");
@ -127,6 +128,7 @@
AtomGlobalSp = Yap_LookupAtom("global_sp"); AtomGlobalSp = Yap_LookupAtom("global_sp");
AtomGlobalTrie = Yap_LookupAtom("global_trie"); AtomGlobalTrie = Yap_LookupAtom("global_trie");
AtomGoalExpansion = Yap_LookupAtom("goal_expansion"); AtomGoalExpansion = Yap_LookupAtom("goal_expansion");
AtomHat = Yap_LookupAtom("^");
AtomHERE = Yap_LookupAtom("\n <====HERE====> \n"); AtomHERE = Yap_LookupAtom("\n <====HERE====> \n");
AtomHandleThrow = Yap_FullLookupAtom("$handle_throw"); AtomHandleThrow = Yap_FullLookupAtom("$handle_throw");
AtomHeap = Yap_LookupAtom("heap"); AtomHeap = Yap_LookupAtom("heap");
@ -390,6 +392,7 @@
FunctorGoalExpansion2 = Yap_MkFunctor(AtomGoalExpansion,2); FunctorGoalExpansion2 = Yap_MkFunctor(AtomGoalExpansion,2);
FunctorGoalExpansion = Yap_MkFunctor(AtomGoalExpansion,3); FunctorGoalExpansion = Yap_MkFunctor(AtomGoalExpansion,3);
FunctorHandleThrow = Yap_MkFunctor(AtomHandleThrow,3); FunctorHandleThrow = Yap_MkFunctor(AtomHandleThrow,3);
FunctorHat = Yap_MkFunctor(AtomHat,2);
FunctorId = Yap_MkFunctor(AtomId,1); FunctorId = Yap_MkFunctor(AtomId,1);
FunctorIs = Yap_MkFunctor(AtomIs,2); FunctorIs = Yap_MkFunctor(AtomIs,2);
FunctorLastExecuteWithin = Yap_MkFunctor(AtomLastExecuteWithin,1); FunctorLastExecuteWithin = Yap_MkFunctor(AtomLastExecuteWithin,1);

View File

@ -98,4 +98,5 @@ static void InitGlobal(void) {
#endif #endif
} }

View File

@ -243,4 +243,6 @@ static void InitWorker(int wid) {
REMOTE_FunctorVar(wid) = FunctorVar; REMOTE_FunctorVar(wid) = FunctorVar;
} }

View File

@ -8,7 +8,9 @@
SWI_Atoms[i++] = Yap_LookupAtom("$aborted"); SWI_Atoms[i++] = Yap_LookupAtom("$aborted");
SWI_Atoms[i++] = Yap_LookupAtom("abs"); SWI_Atoms[i++] = Yap_LookupAtom("abs");
SWI_Atoms[i++] = Yap_LookupAtom("access"); SWI_Atoms[i++] = Yap_LookupAtom("access");
SWI_Atoms[i++] = Yap_LookupAtom("access_level");
SWI_Atoms[i++] = Yap_LookupAtom("acos"); SWI_Atoms[i++] = Yap_LookupAtom("acos");
SWI_Atoms[i++] = Yap_LookupAtom("acosh");
SWI_Atoms[i++] = Yap_LookupAtom("acyclic_term"); SWI_Atoms[i++] = Yap_LookupAtom("acyclic_term");
SWI_Atoms[i++] = Yap_LookupAtom("add_import"); SWI_Atoms[i++] = Yap_LookupAtom("add_import");
SWI_Atoms[i++] = Yap_LookupAtom("address"); SWI_Atoms[i++] = Yap_LookupAtom("address");
@ -32,6 +34,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("as"); SWI_Atoms[i++] = Yap_LookupAtom("as");
SWI_Atoms[i++] = Yap_LookupAtom("ascii"); SWI_Atoms[i++] = Yap_LookupAtom("ascii");
SWI_Atoms[i++] = Yap_LookupAtom("asin"); SWI_Atoms[i++] = Yap_LookupAtom("asin");
SWI_Atoms[i++] = Yap_LookupAtom("asinh");
SWI_Atoms[i++] = Yap_LookupAtom("assert"); SWI_Atoms[i++] = Yap_LookupAtom("assert");
SWI_Atoms[i++] = Yap_LookupAtom("asserta"); SWI_Atoms[i++] = Yap_LookupAtom("asserta");
SWI_Atoms[i++] = Yap_LookupAtom("at"); SWI_Atoms[i++] = Yap_LookupAtom("at");
@ -43,6 +46,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("@<"); SWI_Atoms[i++] = Yap_LookupAtom("@<");
SWI_Atoms[i++] = Yap_LookupAtom("@=<"); SWI_Atoms[i++] = Yap_LookupAtom("@=<");
SWI_Atoms[i++] = Yap_LookupAtom("atan"); SWI_Atoms[i++] = Yap_LookupAtom("atan");
SWI_Atoms[i++] = Yap_LookupAtom("atanh");
SWI_Atoms[i++] = Yap_LookupAtom("atan2"); SWI_Atoms[i++] = Yap_LookupAtom("atan2");
SWI_Atoms[i++] = Yap_LookupAtom("atom"); SWI_Atoms[i++] = Yap_LookupAtom("atom");
SWI_Atoms[i++] = Yap_LookupAtom("atom_garbage_collection"); SWI_Atoms[i++] = Yap_LookupAtom("atom_garbage_collection");
@ -56,8 +60,10 @@
SWI_Atoms[i++] = Yap_LookupAtom("\\"); SWI_Atoms[i++] = Yap_LookupAtom("\\");
SWI_Atoms[i++] = Yap_LookupAtom("backtrace"); SWI_Atoms[i++] = Yap_LookupAtom("backtrace");
SWI_Atoms[i++] = Yap_LookupAtom("|"); SWI_Atoms[i++] = Yap_LookupAtom("|");
SWI_Atoms[i++] = Yap_LookupAtom("base");
SWI_Atoms[i++] = Yap_LookupAtom("begin"); SWI_Atoms[i++] = Yap_LookupAtom("begin");
SWI_Atoms[i++] = Yap_LookupAtom("binary"); SWI_Atoms[i++] = Yap_LookupAtom("binary");
SWI_Atoms[i++] = Yap_LookupAtom("binary_stream");
SWI_Atoms[i++] = Yap_LookupAtom("bind"); SWI_Atoms[i++] = Yap_LookupAtom("bind");
SWI_Atoms[i++] = Yap_LookupAtom("\\/"); SWI_Atoms[i++] = Yap_LookupAtom("\\/");
SWI_Atoms[i++] = Yap_LookupAtom("blobs"); SWI_Atoms[i++] = Yap_LookupAtom("blobs");
@ -67,6 +73,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("boolean"); SWI_Atoms[i++] = Yap_LookupAtom("boolean");
SWI_Atoms[i++] = Yap_LookupAtom("brace_term_position"); SWI_Atoms[i++] = Yap_LookupAtom("brace_term_position");
SWI_Atoms[i++] = Yap_LookupAtom("break"); SWI_Atoms[i++] = Yap_LookupAtom("break");
SWI_Atoms[i++] = Yap_LookupAtom("break_level");
SWI_Atoms[i++] = Yap_LookupAtom("btree"); SWI_Atoms[i++] = Yap_LookupAtom("btree");
SWI_Atoms[i++] = Yap_LookupAtom("buffer"); SWI_Atoms[i++] = Yap_LookupAtom("buffer");
SWI_Atoms[i++] = Yap_LookupAtom("buffer_size"); SWI_Atoms[i++] = Yap_LookupAtom("buffer_size");
@ -80,6 +87,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("canceled"); SWI_Atoms[i++] = Yap_LookupAtom("canceled");
SWI_Atoms[i++] = Yap_LookupAtom("case_sensitive_file_names"); SWI_Atoms[i++] = Yap_LookupAtom("case_sensitive_file_names");
SWI_Atoms[i++] = Yap_LookupAtom("catch"); SWI_Atoms[i++] = Yap_LookupAtom("catch");
SWI_Atoms[i++] = Yap_LookupAtom("category");
SWI_Atoms[i++] = Yap_LookupAtom("ceil"); SWI_Atoms[i++] = Yap_LookupAtom("ceil");
SWI_Atoms[i++] = Yap_LookupAtom("ceiling"); SWI_Atoms[i++] = Yap_LookupAtom("ceiling");
SWI_Atoms[i++] = Yap_LookupAtom("char_type"); SWI_Atoms[i++] = Yap_LookupAtom("char_type");
@ -90,7 +98,9 @@
SWI_Atoms[i++] = Yap_LookupAtom("chdir"); SWI_Atoms[i++] = Yap_LookupAtom("chdir");
SWI_Atoms[i++] = Yap_LookupAtom("chmod"); SWI_Atoms[i++] = Yap_LookupAtom("chmod");
SWI_Atoms[i++] = Yap_LookupAtom("choice"); SWI_Atoms[i++] = Yap_LookupAtom("choice");
SWI_Atoms[i++] = Yap_LookupAtom("class");
SWI_Atoms[i++] = Yap_LookupAtom("clause"); SWI_Atoms[i++] = Yap_LookupAtom("clause");
SWI_Atoms[i++] = Yap_LookupAtom("clauses");
SWI_Atoms[i++] = Yap_LookupAtom("clause_reference"); SWI_Atoms[i++] = Yap_LookupAtom("clause_reference");
SWI_Atoms[i++] = Yap_LookupAtom("close"); SWI_Atoms[i++] = Yap_LookupAtom("close");
SWI_Atoms[i++] = Yap_LookupAtom("close_on_abort"); SWI_Atoms[i++] = Yap_LookupAtom("close_on_abort");
@ -109,9 +119,11 @@
SWI_Atoms[i++] = Yap_LookupAtom("context"); SWI_Atoms[i++] = Yap_LookupAtom("context");
SWI_Atoms[i++] = Yap_LookupAtom("context_module"); SWI_Atoms[i++] = Yap_LookupAtom("context_module");
SWI_Atoms[i++] = Yap_LookupAtom("continue"); SWI_Atoms[i++] = Yap_LookupAtom("continue");
SWI_Atoms[i++] = Yap_LookupAtom("copysign");
SWI_Atoms[i++] = Yap_LookupAtom("core"); SWI_Atoms[i++] = Yap_LookupAtom("core");
SWI_Atoms[i++] = Yap_LookupAtom("core_left"); SWI_Atoms[i++] = Yap_LookupAtom("core_left");
SWI_Atoms[i++] = Yap_LookupAtom("cos"); SWI_Atoms[i++] = Yap_LookupAtom("cos");
SWI_Atoms[i++] = Yap_LookupAtom("cosh");
SWI_Atoms[i++] = Yap_LookupAtom("cputime"); SWI_Atoms[i++] = Yap_LookupAtom("cputime");
SWI_Atoms[i++] = Yap_LookupAtom("create"); SWI_Atoms[i++] = Yap_LookupAtom("create");
SWI_Atoms[i++] = Yap_LookupAtom("csym"); SWI_Atoms[i++] = Yap_LookupAtom("csym");
@ -127,6 +139,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("cut_parent"); SWI_Atoms[i++] = Yap_LookupAtom("cut_parent");
SWI_Atoms[i++] = Yap_LookupAtom("cut"); SWI_Atoms[i++] = Yap_LookupAtom("cut");
SWI_Atoms[i++] = Yap_LookupAtom("cyclic_term"); SWI_Atoms[i++] = Yap_LookupAtom("cyclic_term");
SWI_Atoms[i++] = Yap_LookupAtom("cycles");
SWI_Atoms[i++] = Yap_LookupAtom("$and"); SWI_Atoms[i++] = Yap_LookupAtom("$and");
SWI_Atoms[i++] = Yap_LookupAtom("date"); SWI_Atoms[i++] = Yap_LookupAtom("date");
SWI_Atoms[i++] = Yap_LookupAtom("db_reference"); SWI_Atoms[i++] = Yap_LookupAtom("db_reference");
@ -137,8 +150,10 @@
SWI_Atoms[i++] = Yap_LookupAtom("$cut"); SWI_Atoms[i++] = Yap_LookupAtom("$cut");
SWI_Atoms[i++] = Yap_LookupAtom("dde_error"); SWI_Atoms[i++] = Yap_LookupAtom("dde_error");
SWI_Atoms[i++] = Yap_LookupAtom("dde_handle"); SWI_Atoms[i++] = Yap_LookupAtom("dde_handle");
SWI_Atoms[i++] = Yap_LookupAtom("deadline");
SWI_Atoms[i++] = Yap_LookupAtom("debug"); SWI_Atoms[i++] = Yap_LookupAtom("debug");
SWI_Atoms[i++] = Yap_LookupAtom("debug_on_error"); SWI_Atoms[i++] = Yap_LookupAtom("debug_on_error");
SWI_Atoms[i++] = Yap_LookupAtom("debug_topic");
SWI_Atoms[i++] = Yap_LookupAtom("debugger_print_options"); SWI_Atoms[i++] = Yap_LookupAtom("debugger_print_options");
SWI_Atoms[i++] = Yap_LookupAtom("debugger_show_context"); SWI_Atoms[i++] = Yap_LookupAtom("debugger_show_context");
SWI_Atoms[i++] = Yap_LookupAtom("debugging"); SWI_Atoms[i++] = Yap_LookupAtom("debugging");
@ -170,11 +185,13 @@
SWI_Atoms[i++] = Yap_LookupAtom("double_quotes"); SWI_Atoms[i++] = Yap_LookupAtom("double_quotes");
SWI_Atoms[i++] = Yap_LookupAtom("**"); SWI_Atoms[i++] = Yap_LookupAtom("**");
SWI_Atoms[i++] = Yap_LookupAtom("$profile_node"); SWI_Atoms[i++] = Yap_LookupAtom("$profile_node");
SWI_Atoms[i++] = Yap_LookupAtom("$query_loop");
SWI_Atoms[i++] = Yap_LookupAtom("$recover_and_rethrow"); SWI_Atoms[i++] = Yap_LookupAtom("$recover_and_rethrow");
SWI_Atoms[i++] = Yap_LookupAtom("$stream"); SWI_Atoms[i++] = Yap_LookupAtom("$stream");
SWI_Atoms[i++] = Yap_LookupAtom("$thread_init"); SWI_Atoms[i++] = Yap_LookupAtom("$thread_init");
SWI_Atoms[i++] = Yap_LookupAtom("$throw"); SWI_Atoms[i++] = Yap_LookupAtom("$throw");
SWI_Atoms[i++] = Yap_LookupAtom("$time"); SWI_Atoms[i++] = Yap_LookupAtom("$time");
SWI_Atoms[i++] = Yap_LookupAtom("$toplevel");
SWI_Atoms[i++] = Yap_LookupAtom("$VAR$"); SWI_Atoms[i++] = Yap_LookupAtom("$VAR$");
SWI_Atoms[i++] = Yap_LookupAtom("$wakeup"); SWI_Atoms[i++] = Yap_LookupAtom("$wakeup");
SWI_Atoms[i++] = Yap_LookupAtom("dynamic"); SWI_Atoms[i++] = Yap_LookupAtom("dynamic");
@ -268,9 +285,8 @@
SWI_Atoms[i++] = Yap_LookupAtom("hash"); SWI_Atoms[i++] = Yap_LookupAtom("hash");
SWI_Atoms[i++] = Yap_LookupAtom("hashed"); SWI_Atoms[i++] = Yap_LookupAtom("hashed");
SWI_Atoms[i++] = Yap_LookupAtom("^"); SWI_Atoms[i++] = Yap_LookupAtom("^");
SWI_Atoms[i++] = Yap_LookupAtom("heap");
SWI_Atoms[i++] = Yap_LookupAtom("heaplimit");
SWI_Atoms[i++] = Yap_LookupAtom("heapused"); SWI_Atoms[i++] = Yap_LookupAtom("heapused");
SWI_Atoms[i++] = Yap_LookupAtom("heap_gc");
SWI_Atoms[i++] = Yap_LookupAtom("help"); SWI_Atoms[i++] = Yap_LookupAtom("help");
SWI_Atoms[i++] = Yap_LookupAtom("hidden"); SWI_Atoms[i++] = Yap_LookupAtom("hidden");
SWI_Atoms[i++] = Yap_LookupAtom("hide_childs"); SWI_Atoms[i++] = Yap_LookupAtom("hide_childs");
@ -278,6 +294,8 @@
SWI_Atoms[i++] = Yap_LookupAtom("->"); SWI_Atoms[i++] = Yap_LookupAtom("->");
SWI_Atoms[i++] = Yap_LookupAtom("ignore"); SWI_Atoms[i++] = Yap_LookupAtom("ignore");
SWI_Atoms[i++] = Yap_LookupAtom("ignore_ops"); SWI_Atoms[i++] = Yap_LookupAtom("ignore_ops");
SWI_Atoms[i++] = Yap_LookupAtom("import_into");
SWI_Atoms[i++] = Yap_LookupAtom("import_type");
SWI_Atoms[i++] = Yap_LookupAtom("imported"); SWI_Atoms[i++] = Yap_LookupAtom("imported");
SWI_Atoms[i++] = Yap_LookupAtom("imported_procedure"); SWI_Atoms[i++] = Yap_LookupAtom("imported_procedure");
SWI_Atoms[i++] = Yap_LookupAtom("index"); SWI_Atoms[i++] = Yap_LookupAtom("index");
@ -312,9 +330,11 @@
SWI_Atoms[i++] = Yap_LookupAtom(">="); SWI_Atoms[i++] = Yap_LookupAtom(">=");
SWI_Atoms[i++] = Yap_LookupAtom("level"); SWI_Atoms[i++] = Yap_LookupAtom("level");
SWI_Atoms[i++] = Yap_LookupAtom("li"); SWI_Atoms[i++] = Yap_LookupAtom("li");
SWI_Atoms[i++] = Yap_LookupAtom("library");
SWI_Atoms[i++] = Yap_LookupAtom("limit"); SWI_Atoms[i++] = Yap_LookupAtom("limit");
SWI_Atoms[i++] = Yap_LookupAtom("line"); SWI_Atoms[i++] = Yap_LookupAtom("line");
SWI_Atoms[i++] = Yap_LookupAtom("line_count"); SWI_Atoms[i++] = Yap_LookupAtom("line_count");
SWI_Atoms[i++] = Yap_LookupAtom("line_position");
SWI_Atoms[i++] = Yap_LookupAtom("list"); SWI_Atoms[i++] = Yap_LookupAtom("list");
SWI_Atoms[i++] = Yap_LookupAtom("list_position"); SWI_Atoms[i++] = Yap_LookupAtom("list_position");
SWI_Atoms[i++] = Yap_LookupAtom("listing"); SWI_Atoms[i++] = Yap_LookupAtom("listing");
@ -329,6 +349,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("log"); SWI_Atoms[i++] = Yap_LookupAtom("log");
SWI_Atoms[i++] = Yap_LookupAtom("log10"); SWI_Atoms[i++] = Yap_LookupAtom("log10");
SWI_Atoms[i++] = Yap_LookupAtom("long"); SWI_Atoms[i++] = Yap_LookupAtom("long");
SWI_Atoms[i++] = Yap_LookupAtom("loose");
SWI_Atoms[i++] = Yap_LookupAtom("low"); SWI_Atoms[i++] = Yap_LookupAtom("low");
SWI_Atoms[i++] = Yap_LookupAtom("lower"); SWI_Atoms[i++] = Yap_LookupAtom("lower");
SWI_Atoms[i++] = Yap_LookupAtom("lsb"); SWI_Atoms[i++] = Yap_LookupAtom("lsb");
@ -342,6 +363,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("max_depth"); SWI_Atoms[i++] = Yap_LookupAtom("max_depth");
SWI_Atoms[i++] = Yap_LookupAtom("max_files"); SWI_Atoms[i++] = Yap_LookupAtom("max_files");
SWI_Atoms[i++] = Yap_LookupAtom("max_frame_size"); SWI_Atoms[i++] = Yap_LookupAtom("max_frame_size");
SWI_Atoms[i++] = Yap_LookupAtom("max_length");
SWI_Atoms[i++] = Yap_LookupAtom("max_path_length"); SWI_Atoms[i++] = Yap_LookupAtom("max_path_length");
SWI_Atoms[i++] = Yap_LookupAtom("max_size"); SWI_Atoms[i++] = Yap_LookupAtom("max_size");
SWI_Atoms[i++] = Yap_LookupAtom("max_variable_length"); SWI_Atoms[i++] = Yap_LookupAtom("max_variable_length");
@ -361,6 +383,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("mode"); SWI_Atoms[i++] = Yap_LookupAtom("mode");
SWI_Atoms[i++] = Yap_LookupAtom("modify"); SWI_Atoms[i++] = Yap_LookupAtom("modify");
SWI_Atoms[i++] = Yap_LookupAtom("module"); SWI_Atoms[i++] = Yap_LookupAtom("module");
SWI_Atoms[i++] = Yap_LookupAtom("module_class");
SWI_Atoms[i++] = Yap_LookupAtom("module_property"); SWI_Atoms[i++] = Yap_LookupAtom("module_property");
SWI_Atoms[i++] = Yap_LookupAtom("module_transparent"); SWI_Atoms[i++] = Yap_LookupAtom("module_transparent");
SWI_Atoms[i++] = Yap_LookupAtom("modules"); SWI_Atoms[i++] = Yap_LookupAtom("modules");
@ -391,6 +414,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("not_unique"); SWI_Atoms[i++] = Yap_LookupAtom("not_unique");
SWI_Atoms[i++] = Yap_LookupAtom("number"); SWI_Atoms[i++] = Yap_LookupAtom("number");
SWI_Atoms[i++] = Yap_LookupAtom("number_of_clauses"); SWI_Atoms[i++] = Yap_LookupAtom("number_of_clauses");
SWI_Atoms[i++] = Yap_LookupAtom("number_of_rules");
SWI_Atoms[i++] = Yap_LookupAtom("numbervar_option"); SWI_Atoms[i++] = Yap_LookupAtom("numbervar_option");
SWI_Atoms[i++] = Yap_LookupAtom("numbervars"); SWI_Atoms[i++] = Yap_LookupAtom("numbervars");
SWI_Atoms[i++] = Yap_LookupAtom("occurs_check"); SWI_Atoms[i++] = Yap_LookupAtom("occurs_check");
@ -405,6 +429,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("or"); SWI_Atoms[i++] = Yap_LookupAtom("or");
SWI_Atoms[i++] = Yap_LookupAtom("order"); SWI_Atoms[i++] = Yap_LookupAtom("order");
SWI_Atoms[i++] = Yap_LookupAtom("output"); SWI_Atoms[i++] = Yap_LookupAtom("output");
SWI_Atoms[i++] = Yap_LookupAtom("owner");
SWI_Atoms[i++] = Yap_LookupAtom("pair"); SWI_Atoms[i++] = Yap_LookupAtom("pair");
SWI_Atoms[i++] = Yap_LookupAtom("paren"); SWI_Atoms[i++] = Yap_LookupAtom("paren");
SWI_Atoms[i++] = Yap_LookupAtom("parent"); SWI_Atoms[i++] = Yap_LookupAtom("parent");
@ -423,6 +448,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("+"); SWI_Atoms[i++] = Yap_LookupAtom("+");
SWI_Atoms[i++] = Yap_LookupAtom("popcount"); SWI_Atoms[i++] = Yap_LookupAtom("popcount");
SWI_Atoms[i++] = Yap_LookupAtom("portray"); SWI_Atoms[i++] = Yap_LookupAtom("portray");
SWI_Atoms[i++] = Yap_LookupAtom("portray_goal");
SWI_Atoms[i++] = Yap_LookupAtom("position"); SWI_Atoms[i++] = Yap_LookupAtom("position");
SWI_Atoms[i++] = Yap_LookupAtom("posix"); SWI_Atoms[i++] = Yap_LookupAtom("posix");
SWI_Atoms[i++] = Yap_LookupAtom("powm"); SWI_Atoms[i++] = Yap_LookupAtom("powm");
@ -433,6 +459,8 @@
SWI_Atoms[i++] = Yap_LookupAtom("priority"); SWI_Atoms[i++] = Yap_LookupAtom("priority");
SWI_Atoms[i++] = Yap_LookupAtom("private_procedure"); SWI_Atoms[i++] = Yap_LookupAtom("private_procedure");
SWI_Atoms[i++] = Yap_LookupAtom("procedure"); SWI_Atoms[i++] = Yap_LookupAtom("procedure");
SWI_Atoms[i++] = Yap_LookupAtom("process_comment");
SWI_Atoms[i++] = Yap_LookupAtom("process_cputime");
SWI_Atoms[i++] = Yap_LookupAtom("profile_mode"); SWI_Atoms[i++] = Yap_LookupAtom("profile_mode");
SWI_Atoms[i++] = Yap_LookupAtom("profile_no_cpu_time"); SWI_Atoms[i++] = Yap_LookupAtom("profile_no_cpu_time");
SWI_Atoms[i++] = Yap_LookupAtom("profile_node"); SWI_Atoms[i++] = Yap_LookupAtom("profile_node");
@ -457,6 +485,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("quoted"); SWI_Atoms[i++] = Yap_LookupAtom("quoted");
SWI_Atoms[i++] = Yap_LookupAtom("radix"); SWI_Atoms[i++] = Yap_LookupAtom("radix");
SWI_Atoms[i++] = Yap_LookupAtom("random"); SWI_Atoms[i++] = Yap_LookupAtom("random");
SWI_Atoms[i++] = Yap_LookupAtom("random_float");
SWI_Atoms[i++] = Yap_LookupAtom("random_option"); SWI_Atoms[i++] = Yap_LookupAtom("random_option");
SWI_Atoms[i++] = Yap_LookupAtom("rational"); SWI_Atoms[i++] = Yap_LookupAtom("rational");
SWI_Atoms[i++] = Yap_LookupAtom("rationalize"); SWI_Atoms[i++] = Yap_LookupAtom("rationalize");
@ -472,6 +501,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("record_position"); SWI_Atoms[i++] = Yap_LookupAtom("record_position");
SWI_Atoms[i++] = Yap_LookupAtom("redefine"); SWI_Atoms[i++] = Yap_LookupAtom("redefine");
SWI_Atoms[i++] = Yap_LookupAtom("redo"); SWI_Atoms[i++] = Yap_LookupAtom("redo");
SWI_Atoms[i++] = Yap_LookupAtom("redo_in_skip");
SWI_Atoms[i++] = Yap_LookupAtom("references"); SWI_Atoms[i++] = Yap_LookupAtom("references");
SWI_Atoms[i++] = Yap_LookupAtom("rem"); SWI_Atoms[i++] = Yap_LookupAtom("rem");
SWI_Atoms[i++] = Yap_LookupAtom("rename"); SWI_Atoms[i++] = Yap_LookupAtom("rename");
@ -489,6 +519,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("runtime"); SWI_Atoms[i++] = Yap_LookupAtom("runtime");
SWI_Atoms[i++] = Yap_LookupAtom("save_class"); SWI_Atoms[i++] = Yap_LookupAtom("save_class");
SWI_Atoms[i++] = Yap_LookupAtom("save_option"); SWI_Atoms[i++] = Yap_LookupAtom("save_option");
SWI_Atoms[i++] = Yap_LookupAtom("see");
SWI_Atoms[i++] = Yap_LookupAtom("seed"); SWI_Atoms[i++] = Yap_LookupAtom("seed");
SWI_Atoms[i++] = Yap_LookupAtom("seek_method"); SWI_Atoms[i++] = Yap_LookupAtom("seek_method");
SWI_Atoms[i++] = Yap_LookupAtom("select"); SWI_Atoms[i++] = Yap_LookupAtom("select");
@ -501,15 +532,18 @@
SWI_Atoms[i++] = Yap_LookupAtom("shared_object"); SWI_Atoms[i++] = Yap_LookupAtom("shared_object");
SWI_Atoms[i++] = Yap_LookupAtom("shared_object_handle"); SWI_Atoms[i++] = Yap_LookupAtom("shared_object_handle");
SWI_Atoms[i++] = Yap_LookupAtom("shell"); SWI_Atoms[i++] = Yap_LookupAtom("shell");
SWI_Atoms[i++] = Yap_LookupAtom("shift_time");
SWI_Atoms[i++] = Yap_LookupAtom("sign"); SWI_Atoms[i++] = Yap_LookupAtom("sign");
SWI_Atoms[i++] = Yap_LookupAtom("signal"); SWI_Atoms[i++] = Yap_LookupAtom("signal");
SWI_Atoms[i++] = Yap_LookupAtom("signal_handler"); SWI_Atoms[i++] = Yap_LookupAtom("signal_handler");
SWI_Atoms[i++] = Yap_LookupAtom("silent"); SWI_Atoms[i++] = Yap_LookupAtom("silent");
SWI_Atoms[i++] = Yap_LookupAtom("sin"); SWI_Atoms[i++] = Yap_LookupAtom("sin");
SWI_Atoms[i++] = Yap_LookupAtom("singletons"); SWI_Atoms[i++] = Yap_LookupAtom("singletons");
SWI_Atoms[i++] = Yap_LookupAtom("sinh");
SWI_Atoms[i++] = Yap_LookupAtom("size"); SWI_Atoms[i++] = Yap_LookupAtom("size");
SWI_Atoms[i++] = Yap_LookupAtom("size_t"); SWI_Atoms[i++] = Yap_LookupAtom("size_t");
SWI_Atoms[i++] = Yap_LookupAtom("skip"); SWI_Atoms[i++] = Yap_LookupAtom("skip");
SWI_Atoms[i++] = Yap_LookupAtom("skipped");
SWI_Atoms[i++] = Yap_LookupAtom("<"); SWI_Atoms[i++] = Yap_LookupAtom("<");
SWI_Atoms[i++] = Yap_LookupAtom("=<"); SWI_Atoms[i++] = Yap_LookupAtom("=<");
SWI_Atoms[i++] = Yap_LookupAtom("*->"); SWI_Atoms[i++] = Yap_LookupAtom("*->");
@ -528,6 +562,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("*"); SWI_Atoms[i++] = Yap_LookupAtom("*");
SWI_Atoms[i++] = Yap_LookupAtom("start"); SWI_Atoms[i++] = Yap_LookupAtom("start");
SWI_Atoms[i++] = Yap_LookupAtom("stat"); SWI_Atoms[i++] = Yap_LookupAtom("stat");
SWI_Atoms[i++] = Yap_LookupAtom("state");
SWI_Atoms[i++] = Yap_LookupAtom("static_procedure"); SWI_Atoms[i++] = Yap_LookupAtom("static_procedure");
SWI_Atoms[i++] = Yap_LookupAtom("statistics"); SWI_Atoms[i++] = Yap_LookupAtom("statistics");
SWI_Atoms[i++] = Yap_LookupAtom("status"); SWI_Atoms[i++] = Yap_LookupAtom("status");
@ -538,9 +573,11 @@
SWI_Atoms[i++] = Yap_LookupAtom("stream_pair"); SWI_Atoms[i++] = Yap_LookupAtom("stream_pair");
SWI_Atoms[i++] = Yap_LookupAtom("$stream_position"); SWI_Atoms[i++] = Yap_LookupAtom("$stream_position");
SWI_Atoms[i++] = Yap_LookupAtom("stream_property"); SWI_Atoms[i++] = Yap_LookupAtom("stream_property");
SWI_Atoms[i++] = Yap_LookupAtom("stream_type_check");
SWI_Atoms[i++] = Yap_LookupAtom("=="); SWI_Atoms[i++] = Yap_LookupAtom("==");
SWI_Atoms[i++] = Yap_LookupAtom("string"); SWI_Atoms[i++] = Yap_LookupAtom("string");
SWI_Atoms[i++] = Yap_LookupAtom("string_position"); SWI_Atoms[i++] = Yap_LookupAtom("string_position");
SWI_Atoms[i++] = Yap_LookupAtom("strong");
SWI_Atoms[i++] = Yap_LookupAtom("subterm_positions"); SWI_Atoms[i++] = Yap_LookupAtom("subterm_positions");
SWI_Atoms[i++] = Yap_LookupAtom("suffix"); SWI_Atoms[i++] = Yap_LookupAtom("suffix");
SWI_Atoms[i++] = Yap_LookupAtom("syntax_error"); SWI_Atoms[i++] = Yap_LookupAtom("syntax_error");
@ -551,15 +588,19 @@
SWI_Atoms[i++] = Yap_LookupAtom("system_thread_id"); SWI_Atoms[i++] = Yap_LookupAtom("system_thread_id");
SWI_Atoms[i++] = Yap_LookupAtom("system_time"); SWI_Atoms[i++] = Yap_LookupAtom("system_time");
SWI_Atoms[i++] = Yap_LookupAtom("tan"); SWI_Atoms[i++] = Yap_LookupAtom("tan");
SWI_Atoms[i++] = Yap_LookupAtom("tanh");
SWI_Atoms[i++] = Yap_LookupAtom("temporary_files"); SWI_Atoms[i++] = Yap_LookupAtom("temporary_files");
SWI_Atoms[i++] = Yap_LookupAtom("term"); SWI_Atoms[i++] = Yap_LookupAtom("term");
SWI_Atoms[i++] = Yap_LookupAtom("term_expansion"); SWI_Atoms[i++] = Yap_LookupAtom("term_expansion");
SWI_Atoms[i++] = Yap_LookupAtom("term_position"); SWI_Atoms[i++] = Yap_LookupAtom("term_position");
SWI_Atoms[i++] = Yap_LookupAtom("terminal"); SWI_Atoms[i++] = Yap_LookupAtom("terminal");
SWI_Atoms[i++] = Yap_LookupAtom("terminal_capability"); SWI_Atoms[i++] = Yap_LookupAtom("terminal_capability");
SWI_Atoms[i++] = Yap_LookupAtom("test");
SWI_Atoms[i++] = Yap_LookupAtom("text"); SWI_Atoms[i++] = Yap_LookupAtom("text");
SWI_Atoms[i++] = Yap_LookupAtom("text_stream");
SWI_Atoms[i++] = Yap_LookupAtom("thread"); SWI_Atoms[i++] = Yap_LookupAtom("thread");
SWI_Atoms[i++] = Yap_LookupAtom("thread_cputime"); SWI_Atoms[i++] = Yap_LookupAtom("thread_cputime");
SWI_Atoms[i++] = Yap_LookupAtom("thread_get_message_option");
SWI_Atoms[i++] = Yap_LookupAtom("thread_initialization"); SWI_Atoms[i++] = Yap_LookupAtom("thread_initialization");
SWI_Atoms[i++] = Yap_LookupAtom("thread_local"); SWI_Atoms[i++] = Yap_LookupAtom("thread_local");
SWI_Atoms[i++] = Yap_LookupAtom("thread_local_procedure"); SWI_Atoms[i++] = Yap_LookupAtom("thread_local_procedure");
@ -637,6 +678,7 @@
SWI_Atoms[i++] = Yap_LookupAtom("wakeup"); SWI_Atoms[i++] = Yap_LookupAtom("wakeup");
SWI_Atoms[i++] = Yap_LookupAtom("walltime"); SWI_Atoms[i++] = Yap_LookupAtom("walltime");
SWI_Atoms[i++] = Yap_LookupAtom("warning"); SWI_Atoms[i++] = Yap_LookupAtom("warning");
SWI_Atoms[i++] = Yap_LookupAtom("weak");
SWI_Atoms[i++] = Yap_LookupAtom("wchar_t"); SWI_Atoms[i++] = Yap_LookupAtom("wchar_t");
SWI_Atoms[i++] = Yap_LookupAtom("when_condition"); SWI_Atoms[i++] = Yap_LookupAtom("when_condition");
SWI_Atoms[i++] = Yap_LookupAtom("white"); SWI_Atoms[i++] = Yap_LookupAtom("white");
@ -656,15 +698,18 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_abs),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_abs),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_access),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_access),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_acos),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_acos),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_acosh),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_alias),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_alias),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_and),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_and),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ar_equals),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ar_equals),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ar_not_equal),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ar_not_equal),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_asin),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_asin),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_asinh),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_assert),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_assert),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_asserta),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_asserta),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atan),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atan),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atan),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atan),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atanh),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atan2),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atan2),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atom),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_atom),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_att),3); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_att),3);
@ -686,6 +731,7 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ceiling),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ceiling),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_chars),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_chars),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_chars),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_chars),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_class),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_clause),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_clause),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_close_on_abort),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_close_on_abort),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_close_on_exec),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_close_on_exec),1);
@ -694,7 +740,9 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_colon),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_colon),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_comma),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_comma),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_context),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_context),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_copysign),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_cos),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_cos),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_cosh),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_cputime),0); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_cputime),0);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_curl),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_curl),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_cut_call),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_cut_call),1);
@ -762,7 +810,9 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ground),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ground),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_hat),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_hat),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ifthen),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_ifthen),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_import_into),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_input),0); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_input),0);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_input),3);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_integer),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_integer),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_interrupt),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_interrupt),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_io_error),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_io_error),2);
@ -792,6 +842,7 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_nonvar),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_nonvar),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_not_implemented),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_not_implemented),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_not_provable),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_not_provable),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_not_strict_equal),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_occurs_check),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_occurs_check),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_or),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_or),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_output),0); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_output),0);
@ -806,14 +857,17 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_powm),3); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_powm),3);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_print),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_print),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_print_message),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_print_message),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_priority),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_procedure),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_procedure),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_prove),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_prove),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_prove),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_prove),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_punct),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_punct),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_random),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_random),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_random_float),0);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_rational),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_rational),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_rationalize),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_rationalize),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_rdiv),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_rdiv),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_redo),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_rem),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_rem),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_reposition),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_reposition),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_representation_error),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_representation_error),1);
@ -831,6 +885,7 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_signal),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_signal),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_sin),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_sin),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_singletons),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_singletons),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_sinh),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_size),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_size),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_smaller),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_smaller),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_smaller_equal),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_smaller_equal),2);
@ -848,6 +903,7 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_syntax_error),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_syntax_error),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_syntax_error),3); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_syntax_error),3);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_tan),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_tan),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_tanh),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_term_expansion),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_term_expansion),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_term_position),5); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_term_position),5);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_timeout),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_timeout),1);
@ -868,3 +924,4 @@
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_warning),3); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_warning),3);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_xor),2); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_xor),2);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_xpceref),1); SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_xpceref),1);
SWI_Functors[j++] = Yap_MkFunctor(SWIAtomToAtom(ATOM_xpceref),2);

View File

@ -81,6 +81,15 @@ typedef struct {
int optimise; /* -O: optimised compilation */ int optimise; /* -O: optimised compilation */
} cmdline; } cmdline;
struct
{ char * CWDdir;
size_t CWDlen;
char * executable; /* Running executable */
#ifdef __WINDOWS__
char * module; /* argv[0] module passed */
#endif
} paths;
struct struct
{ ExtensionCell _ext_head; /* head of registered extensions */ { ExtensionCell _ext_head; /* head of registered extensions */
ExtensionCell _ext_tail; /* tail of this chain */ ExtensionCell _ext_tail; /* tail of this chain */
@ -163,6 +172,7 @@ typedef struct PL_local_data {
{ IOSTREAM *streams[6]; /* handles for standard streams */ { IOSTREAM *streams[6]; /* handles for standard streams */
struct input_context *input_stack; /* maintain input stream info */ struct input_context *input_stack; /* maintain input stream info */
struct output_context *output_stack; /* maintain output stream info */ struct output_context *output_stack; /* maintain output stream info */
st_check stream_type_check; /* Check bin/text streams? */
} IO; } IO;
struct struct
@ -192,6 +202,7 @@ typedef struct PL_local_data {
pl_features_t mask; /* Masked access to booleans */ pl_features_t mask; /* Masked access to booleans */
int write_attributes; /* how to write attvars? */ int write_attributes; /* how to write attvars? */
occurs_check_t occurs_check; /* Unify and occurs check */ occurs_check_t occurs_check; /* Unify and occurs check */
access_level_t access_level; /* Current access level */
} prolog_flag; } prolog_flag;
void * glob_info; /* pl-glob.c */ void * glob_info; /* pl-glob.c */
@ -236,6 +247,10 @@ typedef struct PL_local_data {
int _current_buffer_id; int _current_buffer_id;
} fli; } fli;
struct
{ fid_t numbervars_frame; /* Numbervars choice-point */
} var_names;
#ifdef O_GMP #ifdef O_GMP
struct struct
{ {
@ -253,35 +268,6 @@ extern PL_local_data_t lds;
#define exception_term (LD->exception.term) #define exception_term (LD->exception.term)
// THIS HAS TO BE ABSTRACTED
#define GLOBAL_LD (LOCAL_PL_local_data_p)
#if !defined(O_PLMT) && !defined(YAPOR)
#define LOCAL_LD (GLOBAL_LD)
#define LD (GLOBAL_LD)
#define ARG1_LD void
#define ARG_LD
#define GET_LD
#define PRED_LD
#define PASS_LD
#define PASS_LD1
#else
#define LOCAL_LD (__PL_ld)
#define LD LOCAL_LD
#define GET_LD CACHE_REGS PL_local_data_t *__PL_ld = GLOBAL_LD;
#define ARG1_LD PL_local_data_t *__PL_ld
#define ARG_LD , ARG1_LD
#define PASS_LD1 LD
#define PASS_LD , LD
#define PRED_LD GET_LD
#endif
#define Suser_input (LD->IO.streams[0]) #define Suser_input (LD->IO.streams[0])
#define Suser_output (LD->IO.streams[1]) #define Suser_output (LD->IO.streams[1])
#define Suser_error (LD->IO.streams[2]) #define Suser_error (LD->IO.streams[2])

View File

@ -36,9 +36,16 @@
#define O_PLMT 1 #define O_PLMT 1
#endif #endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#include "Yap.h" #include "Yap.h"
#include "YapHeap.h" #include "YapHeap.h"
#define PLVERSION YAP_VERSION
#define PLNAME "yap"
/* try not to pollute the SWI space */ /* try not to pollute the SWI space */
#ifdef P #ifdef P
#undef P #undef P
@ -225,6 +232,37 @@ users foreign language code.
*******************************/ *******************************/
#define WM_SIGNALLED (WM_USER+4201) /* how to select a good number!? */ #define WM_SIGNALLED (WM_USER+4201) /* how to select a good number!? */
#endif
// THIS HAS TO BE ABSTRACTED
#define GLOBAL_LD (LOCAL_PL_local_data_p)
#if !defined(O_PLMT) && !defined(YAPOR)
#define LOCAL_LD (GLOBAL_LD)
#define LD (GLOBAL_LD)
#define ARG1_LD void
#define ARG_LD
#define GET_LD
#define PRED_LD
#define PASS_LD
#define PASS_LD1
#define IGNORE_LD
#else
#define LOCAL_LD (__PL_ld)
#define LD LOCAL_LD
#define GET_LD CACHE_REGS struct PL_local_data *__PL_ld = GLOBAL_LD;
#define ARG1_LD struct PL_local_data *__PL_ld
#define ARG_LD , ARG1_LD
#define PASS_LD1 LD
#define PASS_LD , LD
#define PRED_LD GET_LD
#define IGNORE_LD (void)__PL_ld;
#endif #endif
/******************************** /********************************
@ -339,6 +377,7 @@ typedef struct
{ functor_t functor; /* Functor to use ($VAR/1) */ { functor_t functor; /* Functor to use ($VAR/1) */
av_action on_attvar; /* How to handle attvars */ av_action on_attvar; /* How to handle attvars */
int singletons; /* Write singletons as $VAR('_') */ int singletons; /* Write singletons as $VAR('_') */
int numbered_check; /* Check for already numbered */
} nv_options; } nv_options;
@ -437,9 +476,6 @@ typedef struct
#define FT_FROM_VALUE 0x0f /* Determine type from value */ #define FT_FROM_VALUE 0x0f /* Determine type from value */
#define FT_MASK 0x0f /* mask to get type */ #define FT_MASK 0x0f /* mask to get type */
#define FF_READONLY 0x10 /* feature is read-only */
#define FF_KEEP 0x20 /* keep value it already set */
#define PLFLAG_CHARESCAPE 0x000001 /* handle \ in atoms */ #define PLFLAG_CHARESCAPE 0x000001 /* handle \ in atoms */
#define PLFLAG_GC 0x000002 /* do GC */ #define PLFLAG_GC 0x000002 /* do GC */
#define PLFLAG_TRACE_GC 0x000004 /* verbose gc */ #define PLFLAG_TRACE_GC 0x000004 /* verbose gc */
@ -481,6 +517,36 @@ typedef struct exception_frame /* PL_throw exception environments */
jmp_buf exception_jmp_env; /* longjmp environment */ jmp_buf exception_jmp_env; /* longjmp environment */
} exception_frame; } exception_frame;
/*******************************
* STREAM I/O *
*******************************/
#define REDIR_MAGIC 0x23a9bef3
typedef struct redir_context
{ int magic; /* REDIR_MAGIC */
IOSTREAM *stream; /* temporary output */
int is_stream; /* redirect to stream */
int redirected; /* output is redirected */
term_t term; /* redirect target */
int out_format; /* output type */
int out_arity; /* 2 for difference-list versions */
size_t size; /* size of I/O buffer */
char *data; /* data written */
char buffer[1024]; /* fast temporary buffer */
} redir_context;
#include "pl-file.h"
typedef enum
{ ACCESS_LEVEL_USER = 0, /* Default user view */
ACCESS_LEVEL_SYSTEM /* Allow low-level access */
} access_level_t;
#define SYSTEM_MODE (LD->prolog_flag.access_level == ACCESS_LEVEL_SYSTEM)
#define PL_malloc_atomic malloc
/* vsc: global variables */ /* vsc: global variables */
#include "pl-global.h" #include "pl-global.h"
@ -514,6 +580,21 @@ it mean anything?
#define fail return FALSE #define fail return FALSE
#define TRY(goal) if ((goal) == FALSE) fail #define TRY(goal) if ((goal) == FALSE) fail
/* Flags on module. Most of these flags are copied to the read context
in pl-read.c.
*/
#define M_SYSTEM (0x0001) /* system module */
#define M_CHARESCAPE (0x0002) /* module */
#define DBLQ_CHARS (0x0004) /* "ab" --> ['a', 'b'] */
#define DBLQ_ATOM (0x0008) /* "ab" --> 'ab' */
#define DBLQ_STRING (0x0010) /* "ab" --> "ab" */
#define DBLQ_MASK (DBLQ_CHARS|DBLQ_ATOM|DBLQ_STRING)
#define UNKNOWN_FAIL (0x0020) /* module */
#define UNKNOWN_WARNING (0x0040) /* module */
#define UNKNOWN_ERROR (0x0080) /* module */
#define UNKNOWN_MASK (UNKNOWN_ERROR|UNKNOWN_WARNING|UNKNOWN_FAIL)
extern int fileerrors; extern int fileerrors;
@ -558,25 +639,6 @@ typedef struct wakeup_state
} wakeup_state; } wakeup_state;
/*******************************
* STREAM I/O *
*******************************/
#define REDIR_MAGIC 0x23a9bef3
typedef struct redir_context
{ int magic; /* REDIR_MAGIC */
IOSTREAM *stream; /* temporary output */
int is_stream; /* redirect to stream */
int redirected; /* output is redirected */
term_t term; /* redirect target */
int out_format; /* output type */
int out_arity; /* 2 for difference-list versions */
size_t size; /* size of I/O buffer */
char *data; /* data written */
char buffer[1024]; /* fast temporary buffer */
} redir_context;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Defining built-in predicates using the new interface Defining built-in predicates using the new interface
@ -651,6 +713,7 @@ typedef double real;
#endif #endif
#define PL_unify_time(A,B) PL_unify_int64(A,B)
extern int PL_unify_char(term_t chr, int c, int how); extern int PL_unify_char(term_t chr, int c, int how);
extern int PL_get_char(term_t chr, int *c, int eof); extern int PL_get_char(term_t chr, int *c, int eof);
extern void PL_cleanup_fork(void); extern void PL_cleanup_fork(void);
@ -660,6 +723,7 @@ extern int PL_unify_atomic(term_t t, PL_atomic_t a);
extern int _PL_unify_atomic(term_t t, PL_atomic_t a); extern int _PL_unify_atomic(term_t t, PL_atomic_t a);
extern int _PL_unify_string(term_t t, word w); extern int _PL_unify_string(term_t t, word w);
#define _PL_get_arg(X,Y,Z) PL_get_arg(X,Y,Z) #define _PL_get_arg(X,Y,Z) PL_get_arg(X,Y,Z)
extern IOSTREAM ** /* provide access to Suser_input, */ extern IOSTREAM ** /* provide access to Suser_input, */
@ -740,7 +804,19 @@ PL_EXPORT(int) PL_release_stream(IOSTREAM *s);
COMMON(atom_t) fileNameStream(IOSTREAM *s); COMMON(atom_t) fileNameStream(IOSTREAM *s);
COMMON(int) streamStatus(IOSTREAM *s); COMMON(int) streamStatus(IOSTREAM *s);
COMMON(int) getOutputStream(term_t t, IOSTREAM **s); #define getOutputStream(t, k, s) getOutputStream__LD(t, k, s PASS_LD)
#define getTextOutputStream(t, s) getTextOutputStream__LD(t, s PASS_LD)
#define getBinaryOutputStream(t, s) getBinaryOutputStream__LD(t, s PASS_LD)
#define getInputStream(t, k, s) getInputStream__LD(t, k, s PASS_LD)
#define getTextInputStream(t, s) getTextInputStream__LD(t, s PASS_LD)
#define getBinaryInputStream(t, s) getBinaryInputStream__LD(t, s PASS_LD)
COMMON(int) getTextOutputStream__LD(term_t t, IOSTREAM **s ARG_LD);
COMMON(int) getBinaryOutputStream__LD(term_t t, IOSTREAM **s ARG_LD);
COMMON(int) getTextInputStream__LD(term_t t, IOSTREAM **s ARG_LD);
COMMON(int) getBinaryInputStream__LD(term_t t, IOSTREAM **s ARG_LD);
COMMON(void) pushOutputContext(void); COMMON(void) pushOutputContext(void);
COMMON(void) popOutputContext(void); COMMON(void) popOutputContext(void);
COMMON(int) getSingleChar(IOSTREAM *s, int signals); COMMON(int) getSingleChar(IOSTREAM *s, int signals);
@ -754,6 +830,7 @@ COMMON(int) unicode_separator(pl_wchar_t c);
COMMON(word) pl_raw_read(term_t term); COMMON(word) pl_raw_read(term_t term);
COMMON(word) pl_raw_read2(term_t stream, term_t term); COMMON(word) pl_raw_read2(term_t stream, term_t term);
COMMON(access_level_t) setAccessLevel(access_level_t new_level);
/**** stuff from pl-error.c ****/ /**** stuff from pl-error.c ****/
extern void outOfCore(void); extern void outOfCore(void);
@ -795,7 +872,7 @@ extern size_t getenv3(const char *name, char *buf, size_t len);
extern int Setenv(char *name, char *value); extern int Setenv(char *name, char *value);
extern int Unsetenv(char *name); extern int Unsetenv(char *name);
extern int System(char *cmd); extern int System(char *cmd);
extern bool expandVars(const char *pattern, char *expanded, int maxlen); extern char *expandVars(const char *pattern, char *expanded, int maxlen);
/**** SWI stuff (emulated in pl-yap.c) ****/ /**** SWI stuff (emulated in pl-yap.c) ****/
extern int writeAtomToStream(IOSTREAM *so, atom_t at); extern int writeAtomToStream(IOSTREAM *so, atom_t at);
@ -819,6 +896,10 @@ COMMON(char) digitName(int n, int sm);
/**** stuff from pl-utf8.c ****/ /**** stuff from pl-utf8.c ****/
size_t utf8_strlen(const char *s, size_t len); size_t utf8_strlen(const char *s, size_t len);
/**** stuff from pl-version.c ****/
COMMON(void) setGITVersion(void);
/**** stuff from pl-write.c ****/ /**** stuff from pl-write.c ****/
COMMON(char *) varName(term_t var, char *buf); COMMON(char *) varName(term_t var, char *buf);
COMMON(int) writeUCSAtom(IOSTREAM *fd, atom_t atom, int flags); COMMON(int) writeUCSAtom(IOSTREAM *fd, atom_t atom, int flags);
@ -856,10 +937,12 @@ COMMON(Buffer) codes_or_chars_to_buffer(term_t l, unsigned int flags,
COMMON(bool) systemMode(bool accept); COMMON(bool) systemMode(bool accept);
COMMON(void) initPrologFlagTable(void); COMMON(void) cleanupPrologFlags(void);
COMMON(void) initPrologFlags(void); COMMON(void) initPrologFlags(void);
COMMON(int) raiseStackOverflow(int overflow); COMMON(int) raiseStackOverflow(int overflow);
COMMON(int) PL_qualify(term_t raw, term_t qualified);
static inline word static inline word
setBoolean(int *flag, term_t old, term_t new) setBoolean(int *flag, term_t old, term_t new)
{ if ( !PL_unify_bool_ex(old, *flag) || { if ( !PL_unify_bool_ex(old, *flag) ||
@ -869,7 +952,21 @@ setBoolean(int *flag, term_t old, term_t new)
succeed; succeed;
} }
COMMON(int) getInputStream__LD(term_t t, IOSTREAM **s ARG_LD); #define BEGIN_NUMBERVARS(save) \
{ fid_t _savedf; \
if ( save ) \
{ _savedf = LD->var_names.numbervars_frame; \
LD->var_names.numbervars_frame = PL_open_foreign_frame(); \
}
#define END_NUMBERVARS(save) \
if ( save ) \
{ PL_discard_foreign_frame(LD->var_names.numbervars_frame); \
LD->var_names.numbervars_frame = _savedf; \
} \
}
COMMON(int) PL_get_atom__LD(term_t t1, atom_t *a ARG_LD); COMMON(int) PL_get_atom__LD(term_t t1, atom_t *a ARG_LD);
COMMON(int) PL_get_atom_ex__LD(term_t t, atom_t *a ARG_LD); COMMON(int) PL_get_atom_ex__LD(term_t t, atom_t *a ARG_LD);
@ -884,6 +981,8 @@ COMMON(word) pl_get_prolog_flag(term_t key, term_t value);
COMMON(word) pl_prolog_flag5(term_t key, term_t value, word scope, word access, word type, control_t h); COMMON(word) pl_prolog_flag5(term_t key, term_t value, word scope, word access, word type, control_t h);
COMMON(foreign_t) pl_prolog_flag(term_t name, term_t value, control_t h); COMMON(foreign_t) pl_prolog_flag(term_t name, term_t value, control_t h);
COMMON(struct tm *) PL_localtime_r(const time_t *t, struct tm *r);
/* inlines that need ARG_LD */ /* inlines that need ARG_LD */
static inline intptr_t static inline intptr_t
skip_list(Word l, Word *tailp ARG_LD) { skip_list(Word l, Word *tailp ARG_LD) {
@ -901,7 +1000,14 @@ static inline void *allocHeap__LD(size_t n ARG_LD)
return YAP_AllocSpaceFromYap(n); return YAP_AllocSpaceFromYap(n);
} }
static inline void freeHeap__LD(void *mem, size_t n ARG_LD) static inline void *allocHeapOrHalt(size_t n)
{
void *ptr = YAP_AllocSpaceFromYap(n);
if (!ptr) Yap_exit(1);
return ptr;
}
static inline void freeHeap(void *mem, size_t n)
{ {
YAP_FreeSpaceFromYap(mem); YAP_FreeSpaceFromYap(mem);
} }

View File

@ -95,13 +95,14 @@ COMMON(bool) ChDir(const char *path);
COMMON(int) DeleteTemporaryFile(atom_t name); COMMON(int) DeleteTemporaryFile(atom_t name);
COMMON(int) IsAbsolutePath(const char *spec); COMMON(int) IsAbsolutePath(const char *spec);
COMMON(bool) sysError(const char *fm, ...);
/* TBD */ /* TBD */
extern word globalString(size_t size, char *s); extern word globalString(size_t size, char *s);
extern word globalWString(size_t size, wchar_t *s); extern word globalWString(size_t size, wchar_t *s);
#define allocHeap(n) allocHeap__LD(n PASS_LD) #define allocHeap(n) allocHeap__LD(n PASS_LD)
#define freeHeap(p, n) freeHeap__LD(p, n PASS_LD)
#define valHandle(r) valHandle__LD(r PASS_LD) #define valHandle(r) valHandle__LD(r PASS_LD)
@ -150,6 +151,7 @@ atomLength(Atom atom)
#define _PL_predicate(A,B,C,D) PL_predicate(A,B,C) #define _PL_predicate(A,B,C,D) PL_predicate(A,B,C)
#define predicateHasClauses(A) (YAP_NumberOfClausesForPredicate((YAP_PredEntryPtr)A) != 0) #define predicateHasClauses(A) (YAP_NumberOfClausesForPredicate((YAP_PredEntryPtr)A) != 0)
#define lookupModule(A) Yap_Module(MkAtomTerm(YAP_AtomFromSWIAtom(A))) #define lookupModule(A) Yap_Module(MkAtomTerm(YAP_AtomFromSWIAtom(A)))
#define charEscapeWriteOption(A) FALSE // VSC: to implement #define charEscapeWriteOption(A) FALSE // VSC: to implement
#define wordToTermRef(A) YAP_InitSlot(*(A)) #define wordToTermRef(A) YAP_InitSlot(*(A))
#define isTaggedInt(A) IsIntegerTerm(A) #define isTaggedInt(A) IsIntegerTerm(A)
@ -179,8 +181,6 @@ charCode(Term w)
return -1; return -1;
} }
#define getInputStream(t, s) getInputStream__LD(t, s PASS_LD)
#define PL_get_atom(t, a) PL_get_atom__LD(t, a PASS_LD) #define PL_get_atom(t, a) PL_get_atom__LD(t, a PASS_LD)
#define PL_get_atom_ex(t, a) PL_get_atom_ex__LD(t, a PASS_LD) #define PL_get_atom_ex(t, a) PL_get_atom_ex__LD(t, a PASS_LD)
#define PL_get_text(l, t, f) PL_get_text__LD(l, t, f PASS_LD) #define PL_get_text(l, t, f) PL_get_text__LD(l, t, f PASS_LD)
@ -227,5 +227,8 @@ unblockSignal(int sig)
} }
#endif #endif
#define suspendTrace(x)
atom_t ATOM_;
#endif /* PL_YAP_H */ #endif /* PL_YAP_H */

View File

@ -74,6 +74,7 @@
AtomDefault = AtomAdjust(AtomDefault); AtomDefault = AtomAdjust(AtomDefault);
AtomDevNull = AtomAdjust(AtomDevNull); AtomDevNull = AtomAdjust(AtomDevNull);
AtomDiff = AtomAdjust(AtomDiff); AtomDiff = AtomAdjust(AtomDiff);
AtomDollar = AtomAdjust(AtomDollar);
AtomDoLogUpdClause = AtomAdjust(AtomDoLogUpdClause); AtomDoLogUpdClause = AtomAdjust(AtomDoLogUpdClause);
AtomDoLogUpdClause0 = AtomAdjust(AtomDoLogUpdClause0); AtomDoLogUpdClause0 = AtomAdjust(AtomDoLogUpdClause0);
AtomDoLogUpdClauseErase = AtomAdjust(AtomDoLogUpdClauseErase); AtomDoLogUpdClauseErase = AtomAdjust(AtomDoLogUpdClauseErase);
@ -127,6 +128,7 @@
AtomGlobalSp = AtomAdjust(AtomGlobalSp); AtomGlobalSp = AtomAdjust(AtomGlobalSp);
AtomGlobalTrie = AtomAdjust(AtomGlobalTrie); AtomGlobalTrie = AtomAdjust(AtomGlobalTrie);
AtomGoalExpansion = AtomAdjust(AtomGoalExpansion); AtomGoalExpansion = AtomAdjust(AtomGoalExpansion);
AtomHat = AtomAdjust(AtomHat);
AtomHERE = AtomAdjust(AtomHERE); AtomHERE = AtomAdjust(AtomHERE);
AtomHandleThrow = AtomAdjust(AtomHandleThrow); AtomHandleThrow = AtomAdjust(AtomHandleThrow);
AtomHeap = AtomAdjust(AtomHeap); AtomHeap = AtomAdjust(AtomHeap);
@ -390,6 +392,7 @@
FunctorGoalExpansion2 = FuncAdjust(FunctorGoalExpansion2); FunctorGoalExpansion2 = FuncAdjust(FunctorGoalExpansion2);
FunctorGoalExpansion = FuncAdjust(FunctorGoalExpansion); FunctorGoalExpansion = FuncAdjust(FunctorGoalExpansion);
FunctorHandleThrow = FuncAdjust(FunctorHandleThrow); FunctorHandleThrow = FuncAdjust(FunctorHandleThrow);
FunctorHat = FuncAdjust(FunctorHat);
FunctorId = FuncAdjust(FunctorId); FunctorId = FuncAdjust(FunctorId);
FunctorIs = FuncAdjust(FunctorIs); FunctorIs = FuncAdjust(FunctorIs);
FunctorLastExecuteWithin = FuncAdjust(FunctorLastExecuteWithin); FunctorLastExecuteWithin = FuncAdjust(FunctorLastExecuteWithin);

View File

@ -447,6 +447,8 @@ restore_opcodes(yamop *pc, yamop *max USES_REGS)
case _lock_lu: case _lock_lu:
case _procceed: case _procceed:
case _retry_profiled: case _retry_profiled:
case _retry_udi:
case _try_udi:
pc->u.p.p = PtoPredAdjust(pc->u.p.p); pc->u.p.p = PtoPredAdjust(pc->u.p.p);
pc = NEXTOP(pc,p); pc = NEXTOP(pc,p);
break; break;

View File

@ -98,4 +98,5 @@ static void RestoreGlobal(void) {
#endif #endif
} }

View File

@ -1042,6 +1042,7 @@ RestoreYapRecords__( USES_REGS1 )
ptr->prev_rec = DBRecordAdjust(ptr->prev_rec); ptr->prev_rec = DBRecordAdjust(ptr->prev_rec);
ptr->dbrecord = DBTermAdjust(ptr->dbrecord); ptr->dbrecord = DBTermAdjust(ptr->dbrecord);
RestoreDBTerm(ptr->dbrecord, FALSE PASS_REGS); RestoreDBTerm(ptr->dbrecord, FALSE PASS_REGS);
ptr = ptr->next_rec;
} }
} }

View File

@ -243,4 +243,6 @@ static void RestoreWorker(int wid USES_REGS) {
} }

View File

@ -464,6 +464,8 @@
case _lock_lu: case _lock_lu:
case _procceed: case _procceed:
case _retry_profiled: case _retry_profiled:
case _retry_udi:
case _try_udi:
CHECK(save_PtoPred(stream, pc->u.p.p)); CHECK(save_PtoPred(stream, pc->u.p.p));
pc = NEXTOP(pc,p); pc = NEXTOP(pc,p);
break; break;

View File

@ -146,6 +146,8 @@
#define AtomDevNull Yap_heap_regs->AtomDevNull_ #define AtomDevNull Yap_heap_regs->AtomDevNull_
Atom AtomDiff_; Atom AtomDiff_;
#define AtomDiff Yap_heap_regs->AtomDiff_ #define AtomDiff Yap_heap_regs->AtomDiff_
Atom AtomDollar_;
#define AtomDollar Yap_heap_regs->AtomDollar_
Atom AtomDoLogUpdClause_; Atom AtomDoLogUpdClause_;
#define AtomDoLogUpdClause Yap_heap_regs->AtomDoLogUpdClause_ #define AtomDoLogUpdClause Yap_heap_regs->AtomDoLogUpdClause_
Atom AtomDoLogUpdClause0_; Atom AtomDoLogUpdClause0_;
@ -252,6 +254,8 @@
#define AtomGlobalTrie Yap_heap_regs->AtomGlobalTrie_ #define AtomGlobalTrie Yap_heap_regs->AtomGlobalTrie_
Atom AtomGoalExpansion_; Atom AtomGoalExpansion_;
#define AtomGoalExpansion Yap_heap_regs->AtomGoalExpansion_ #define AtomGoalExpansion Yap_heap_regs->AtomGoalExpansion_
Atom AtomHat_;
#define AtomHat Yap_heap_regs->AtomHat_
Atom AtomHERE_; Atom AtomHERE_;
#define AtomHERE Yap_heap_regs->AtomHERE_ #define AtomHERE Yap_heap_regs->AtomHERE_
Atom AtomHandleThrow_; Atom AtomHandleThrow_;
@ -778,6 +782,8 @@
#define FunctorGoalExpansion Yap_heap_regs->FunctorGoalExpansion_ #define FunctorGoalExpansion Yap_heap_regs->FunctorGoalExpansion_
Functor FunctorHandleThrow_; Functor FunctorHandleThrow_;
#define FunctorHandleThrow Yap_heap_regs->FunctorHandleThrow_ #define FunctorHandleThrow Yap_heap_regs->FunctorHandleThrow_
Functor FunctorHat_;
#define FunctorHat Yap_heap_regs->FunctorHat_
Functor FunctorId_; Functor FunctorId_;
#define FunctorId Yap_heap_regs->FunctorId_ #define FunctorId Yap_heap_regs->FunctorId_
Functor FunctorIs_; Functor FunctorIs_;

View File

@ -350,6 +350,8 @@
case _deallocate: case _deallocate:
case _enter_profiling: case _enter_profiling:
case _retry_profiled: case _retry_profiled:
case _retry_udi:
case _try_udi:
pc = NEXTOP(pc,p); pc = NEXTOP(pc,p);
break; break;
/* instructions type plxxs */ /* instructions type plxxs */

View File

@ -1,11 +1,10 @@
/* $Id: debug.pl,v 1.1 2008-02-12 17:03:53 vsc Exp $ /* Part of SWI-Prolog
Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl E-mail: J.Wielemaker@vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam Copyright (C): 1985-2012, University of Amsterdam
VU University Amsterdam
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
@ -19,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, if you link this library with other files, As a special exception, if you link this library with other files,
compiled with a Free Software compiler, to produce an executable, this compiled with a Free Software compiler, to produce an executable, this
@ -30,19 +29,29 @@
*/ */
:- module(prolog_debug, :- module(prolog_debug,
[ debug/3, % +Topic, +Format, +Args [ debug/3, % +Topic, +Format, :Args
debug/1, % +Topic debug/1, % +Topic
nodebug/1, % +Topic nodebug/1, % +Topic
debugging/1, % ?Topic debugging/1, % ?Topic
debugging/2, % ?Topic, ?Bool debugging/2, % ?Topic, ?Bool
list_debug_topics/0, list_debug_topics/0,
debug_message_context/1, % (+|-)What
assertion/1 % :Goal assertion/1 % :Goal
]). ]).
:- use_module(library(error)).
:- meta_predicate(assertion(:)). :- use_module(library(lists)).
:- set_prolog_flag(generate_debug_info, false). :- set_prolog_flag(generate_debug_info, false).
:- meta_predicate
assertion(0),
debug(+,+,:).
:- multifile prolog:assertion_failed/2.
:- dynamic prolog:assertion_failed/2.
/*:- use_module(library(prolog_stack)).*/ % We use the autoloader if needed
:- if(current_prolog_flag(dialect, yap)). :- if(current_prolog_flag(dialect, yap)).
:- use_module(library(hacks), [stack_dump/1]). :- use_module(library(hacks), [stack_dump/1]).
@ -53,10 +62,15 @@ backtrace(N) :-
:- endif. :- endif.
:- dynamic %:- set_prolog_flag(generate_debug_info, false).
debugging/2.
/** <module> Print debug messages :- dynamic
debugging/3, % Topic, Enabled, To
debug_context/1.
debug_context(thread).
/** <module> Print debug messages and test assertions
This library is a replacement for format/3 for printing debug messages. This library is a replacement for format/3 for printing debug messages.
Messages are assigned a _topic_. By dynamically enabling or disabling Messages are assigned a _topic_. By dynamically enabling or disabling
@ -64,7 +78,7 @@ topics the user can select desired messages. Debug statements are
removed when the code is compiled for optimization. removed when the code is compiled for optimization.
See manual for details. With XPCE, you can use the call below to start a See manual for details. With XPCE, you can use the call below to start a
graphical monitorring tool. graphical monitoring tool.
== ==
?- prolog_ide(debug_monitor). ?- prolog_ide(debug_monitor).
@ -80,11 +94,26 @@ program explicit, trapping the debugger if the condition does not hold.
%% debugging(-Topic) is nondet. %% debugging(-Topic) is nondet.
%% debugging(?Topic, ?Bool) is nondet. %% debugging(?Topic, ?Bool) is nondet.
% %
% Check whether we are debugging Topic or enumerate the topics we % Examine debug topics. The form debugging(+Topic) may be used to
% are debugging. % perform more complex debugging tasks. A typical usage skeleton
% is:
%
% ==
% ( debugging(mytopic)
% -> <perform debugging actions>
% ; true
% ),
% ...
% ==
%
% The other two calls are intended to examine existing and enabled
% debugging tokens and are typically not used in user programs.
debugging(Topic) :- debugging(Topic) :-
debugging(Topic, true). debugging(Topic, true, _To).
debugging(Topic, Bool) :-
debugging(Topic, Bool, _To).
%% debug(+Topic) is det. %% debug(+Topic) is det.
%% nodebug(+Topic) is det. %% nodebug(+Topic) is det.
@ -92,27 +121,51 @@ debugging(Topic) :-
% Add/remove a topic from being printed. nodebug(_) removes all % Add/remove a topic from being printed. nodebug(_) removes all
% topics. Gives a warning if the topic is not defined unless it is % topics. Gives a warning if the topic is not defined unless it is
% used from a directive. The latter allows placing debug topics at % used from a directive. The latter allows placing debug topics at
% the start a a (load-)file without warnings. % the start of a (load-)file without warnings.
%
% For debug/1, Topic can be a term Topic > Out, where Out is
% either a stream or stream-alias or a filename (atom). This
% redirects debug information on this topic to the given output.
debug(Topic) :- debug(Topic) :-
debug(Topic, true). debug(Topic, true).
nodebug(Topic) :- nodebug(Topic) :-
debug(Topic, false). debug(Topic, false).
debug(Topic, Val) :- debug(Spec, Val) :-
( ( retract(debugging(Topic, _)) debug_target(Spec, Topic, Out),
*-> assert(debugging(Topic, Val)), ( ( retract(debugging(Topic, Enabled0, To0))
*-> update_debug(Enabled0, To0, Val, Out, Enabled, To),
assert(debugging(Topic, Enabled, To)),
fail fail
; ( prolog_load_context(file, _) ; ( prolog_load_context(file, _)
-> true -> true
; print_message(warning, debug_no_topic(Topic)) ; print_message(warning, debug_no_topic(Topic))
), ),
assert(debugging(Topic, Val)) update_debug(false, [], Val, Out, Enabled, To),
assert(debugging(Topic, Enabled, To))
) )
-> true -> true
; true ; true
). ).
debug_target(Spec, Topic, To) :-
nonvar(Spec),
Spec = (Topic > To), !.
debug_target(Topic, Topic, -).
update_debug(_, To0, true, -, true, To) :- !,
ensure_output(To0, To).
update_debug(true, To0, true, Out, true, Output) :- !,
append(To0, [Out], Output).
update_debug(false, _, true, Out, true, [Out]) :- !.
update_debug(_, _, false, -, false, []) :- !.
update_debug(true, [Out], false, Out, false, []) :- !.
update_debug(true, To0, false, Out, true, Output) :- !,
delete(To0, Out, Output).
ensure_output([], [user_error]) :- !.
ensure_output(List, List).
%% debug_topic(+Topic) is det. %% debug_topic(+Topic) is det.
% %
@ -120,44 +173,108 @@ debug(Topic, Val) :-
% topics available for debugging. % topics available for debugging.
debug_topic(Topic) :- debug_topic(Topic) :-
( debugging(Registered, _), ( debugging(Registered, _, _),
Registered =@= Topic Registered =@= Topic
-> true -> true
; assert(debugging(Topic, false)) ; assert(debugging(Topic, false, []))
). ).
%% list_debug_topics is det. %% list_debug_topics is det.
% %
% List currently known debug topics and their setting. % List currently known debug topics and their setting.
list_debug_topics :- list_debug_topics :-
format(user_error, '~*t~40|~n', "-"), format(user_error, '~*t~45|~n', "-"),
format(user_error, '~w~t~30| ~w~n', ['Debug Topic', 'Activated']), format(user_error, '~w~t ~w~35| ~w~n',
format(user_error, '~*t~40|~n', "-"), ['Debug Topic', 'Activated', 'To']),
( debugging(Topic, Value), format(user_error, '~*t~45|~n', "-"),
format(user_error, '~w~t~30| ~w~n', [Topic, Value]), ( debugging(Topic, Value, To),
format(user_error, '~w~t ~w~35| ~w~n', [Topic, Value, To]),
fail fail
; true ; true
). ).
%% debug(+Topic, +Format, +Args) is det. %% debug_message_context(+What) is det.
% %
% As format/3 to user_error, but only does something if Topic % Specify additional context for debug messages. What is one of
% is activated through debug/1. % +Context or -Context, and Context is one of =thread=, =time= or
% time(Format), where Format is a format specification for
% format_time/3 (default is =|%T.%3f|=). Initially, debug/3 shows
% only thread information.
debug_message_context(+Topic) :- !,
valid_topic(Topic, Del, Add),
retractall(debug_context(Del)),
assert(debug_context(Add)).
debug_message_context(-Topic) :- !,
valid_topic(Topic, Del, _),
retractall(debug_context(Del)).
debug_message_context(Term) :-
type_error(debug_message_context, Term).
valid_topic(thread, thread, thread) :- !.
valid_topic(time, time(_), time('%T.%3f')) :- !.
valid_topic(time(Format), time(_), time(Format)) :- !.
valid_topic(X, _, _) :-
domain_error(debug_message_context, X).
%% debug(+Topic, +Format, :Args) is det.
%
% Format a message if debug topic is enabled. Similar to format/3
% to =user_error=, but only prints if Topic is activated through
% debug/1. Args is a meta-argument to deal with goal for the
% @-command. Output is first handed to the hook
% prolog:debug_print_hook/3. If this fails, Format+Args is
% translated to text using the message-translation (see
% print_message/2) for the term debug(Format, Args) and then
% printed to every matching destination (controlled by debug/1)
% using print_message_lines/3.
%
% The message is preceded by '% ' and terminated with a newline.
%
% @see format/3.
debug(Topic, Format, Args) :- debug(Topic, Format, Args) :-
debugging(Topic, true), !, debugging(Topic, true, To), !,
print_debug(Topic, Format, Args). print_debug(Topic, To, Format, Args).
debug(_, _, _). debug(_, _, _).
%% prolog:debug_print_hook(+Topic, +Format, +Args) is semidet.
%
% Hook called by debug/3. This hook is used by the graphical
% frontend that can be activated using prolog_ide/1:
%
% ==
% ?- prolog_ide(debug_monitor).
% ==
:- multifile :- multifile
prolog:debug_print_hook/3. prolog:debug_print_hook/3.
print_debug(Topic, Format, Args) :- print_debug(Topic, _To, Format, Args) :-
prolog:debug_print_hook(Topic, Format, Args), !. prolog:debug_print_hook(Topic, Format, Args), !.
print_debug(_, Format, Args) :- print_debug(_, [], _, _) :- !.
print_message(informational, debug(Format, Args)). print_debug(Topic, To, Format, Args) :-
phrase('$messages':translate_message(debug(Format, Args)), Lines),
( member(T, To),
debug_output(T, Stream),
print_message_lines(Stream, kind(debug(Topic)), Lines),
fail
; true
).
debug_output(user, user_error) :- !.
debug_output(Stream, Stream) :-
is_stream(Stream), !.
debug_output(File, Stream) :-
open(File, append, Stream,
[ close_on_abort(false),
alias(File),
buffer(line)
]).
/******************************* /*******************************
@ -165,27 +282,46 @@ print_debug(_, Format, Args) :-
*******************************/ *******************************/
%% assertion(:Goal) is det. %% assertion(:Goal) is det.
% %
% Acts similar to C assert() macro. It has no effect of Goal % Acts similar to C assert() macro. It has no effect if Goal
% succeeds. If Goal fails it prints a message, a stack-trace % succeeds. If Goal fails or throws an exception, the following
% and finally traps the debugger. % steps are taken:
%
% * call prolog:assertion_failed/2. If prolog:assertion_failed/2
% fails, then:
%
% - If this is an interactive toplevel thread, print a
% message, the stack-trace, and finally trap the debugger.
% - Otherwise, throw error(assertion_error(Reason, G),_) where
% Reason is one of =fail= or the exception raised.
assertion(G) :- assertion(G) :-
\+ \+ G, !. % avoid binding variables \+ \+ catch(G,
Error,
assertion_failed(Error, G)),
!.
assertion(G) :- assertion(G) :-
print_message(error, assumption_failed(G)), assertion_failed(fail, G),
assertion_failed. % prevent last call optimization.
assertion_failed(Reason, G) :-
prolog:assertion_failed(Reason, G), !.
assertion_failed(Reason, G) :-
print_message(error, assertion_failed(Reason, G)),
backtrace(10), backtrace(10),
trace, ( current_prolog_flag(break_level, _) % interactive thread
assertion_failed. -> trace
; throw(error(assertion_error(Reason, G), _))
).
assertion_failed. assertion_failed.
%% assume(:Goal) is det. %% assume(:Goal) is det.
% %
% Acts similar to C assert() macro. It has no effect of Goal % Acts similar to C assert() macro. It has no effect of Goal
% succeeds. If Goal fails it prints a message, a stack-trace % succeeds. If Goal fails it prints a message, a stack-trace
% and finally traps the debugger. % and finally traps the debugger.
% %
% @deprecated Use assertion/1 in new code. % @deprecated Use assertion/1 in new code.
/******************************* /*******************************
@ -193,34 +329,28 @@ assertion_failed.
*******************************/ *******************************/
:- multifile :- multifile
user:goal_expansion/2. system:goal_expansion/2.
user:goal_expansion(debug(Topic,_,_), true) :- system:goal_expansion(debug(Topic,_,_), true) :-
( current_prolog_flag(optimise, true) ( current_prolog_flag(optimise, true)
-> true -> true
; debug_topic(Topic), ; debug_topic(Topic),
fail fail
). ).
user:goal_expansion(debugging(Topic), fail) :- system:goal_expansion(debugging(Topic), fail) :-
( current_prolog_flag(optimise, true) ( current_prolog_flag(optimise, true)
-> true -> true
; debug_topic(Topic), ; debug_topic(Topic),
fail fail
). ).
user:goal_expansion(assertion(G), Goal) :- system:goal_expansion(assertion(_), Goal) :-
( current_prolog_flag(optimise, true) current_prolog_flag(optimise, true),
-> Goal = true Goal = true.
; expand_goal(G, G2), system:goal_expansion(assume(_), Goal) :-
Goal = assertion(G2)
).
user:goal_expansion(assume(G), Goal) :-
print_message(informational, print_message(informational,
compatibility(renamed(assume/1, assertion/1))), compatibility(renamed(assume/1, assertion/1))),
( current_prolog_flag(optimise, true) current_prolog_flag(optimise, true),
-> Goal = true Goal = true.
; expand_goal(G, G2),
Goal = assertion(G2)
).
/******************************* /*******************************
@ -230,13 +360,41 @@ user:goal_expansion(assume(G), Goal) :-
:- multifile :- multifile
prolog:message/3. prolog:message/3.
prolog:message(assumption_failed(G)) --> prolog:message(assertion_failed(_, G)) -->
[ 'Assertion failed: ~p'-[G] ]. [ 'Assertion failed: ~q'-[G] ].
prolog:message(debug(Fmt, Args)) --> prolog:message(debug(Fmt, Args)) -->
{ thread_self(Me) }, show_thread_context,
( { Me == main } show_time_context,
-> [ Fmt-Args ] [ Fmt-Args ].
; [ '[Thread ~w] '-[Me], Fmt-Args ]
).
prolog:message(debug_no_topic(Topic)) --> prolog:message(debug_no_topic(Topic)) -->
[ '~q: no matching debug topic (yet)'-[Topic] ]. [ '~q: no matching debug topic (yet)'-[Topic] ].
show_thread_context -->
{ debug_context(thread),
thread_self(Me) ,
Me \== main
},
[ '[Thread ~w] '-[Me] ].
show_thread_context -->
[].
show_time_context -->
{ debug_context(time(Format)),
get_time(Now),
format_time(string(S), Format, Now)
},
[ '[~w] '-[S] ].
show_time_context -->
[].
/*******************************
* HOOKS *
*******************************/
%% prolog:assertion_failed(+Reason, +Goal) is semidet.
%
% This hook is called if the Goal of assertion/1 fails. Reason is
% unified with either =fail= if Goal simply failed or an exception
% call otherwise. If this hook fails, the default behaviour is
% activated. If the hooks throws an exception it will be
% propagated into the caller of assertion/1.

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, if you link this library with other files, As a special exception, if you link this library with other files,
compiled with a Free Software compiler, to produce an executable, this compiled with a Free Software compiler, to produce an executable, this
@ -32,6 +32,7 @@
:- module((record), :- module((record),
[ (record)/1, % +Record [ (record)/1, % +Record
current_record/2, % ?Name, ?Term current_record/2, % ?Name, ?Term
current_record_predicate/2, % ?Record, :PI
op(1150, fx, record) op(1150, fx, record)
]). ]).
:- use_module(library(error)). :- use_module(library(error)).
@ -59,7 +60,8 @@ _directive_. Here is a simple example declaration and some calls.
*/ */
:- multifile :- multifile
error:has_type/2. error:has_type/2,
prolog:generated_predicate/1.
error:has_type(record(M:Name), X) :- error:has_type(record(M:Name), X) :-
current_record(Name, M, _, X, IsX), !, current_record(Name, M, _, X, IsX), !,
@ -77,6 +79,7 @@ error:has_type(record(M:Name), X) :-
% info the following predicates: % info the following predicates:
% %
% * <constructor>_<name>(Record, Value) % * <constructor>_<name>(Record, Value)
% * <constructor>_data(?Name, ?Record, ?Value)
% * default_<constructor>(-Record) % * default_<constructor>(-Record)
% * is_<constructor>(@Term) % * is_<constructor>(@Term)
% * make_<constructor>(+Fields, -Record) % * make_<constructor>(+Fields, -Record)
@ -120,12 +123,14 @@ compile_record(RecordDef) -->
defaults(Args, Defs, TypedArgs), defaults(Args, Defs, TypedArgs),
types(TypedArgs, Names, Types), types(TypedArgs, Names, Types),
atom_concat(default_, Constructor, DefName), atom_concat(default_, Constructor, DefName),
atom_concat(Constructor, '_data', DataName),
DefRecord =.. [Constructor|Defs], DefRecord =.. [Constructor|Defs],
DefClause =.. [DefName,DefRecord], DefClause =.. [DefName,DefRecord],
length(Names, Arity) length(Names, Arity)
}, },
[ DefClause ], [ DefClause ],
access_predicates(Names, 1, Arity, Constructor), access_predicates(Names, 1, Arity, Constructor),
data_predicate(Names, 1, Arity, Constructor, DataName),
set_predicates(Names, 1, Arity, Types, Constructor), set_predicates(Names, 1, Arity, Types, Constructor),
set_field_predicates(Names, 1, Arity, Types, Constructor), set_field_predicates(Names, 1, Arity, Types, Constructor),
make_predicate(Constructor), make_predicate(Constructor),
@ -133,7 +138,8 @@ compile_record(RecordDef) -->
current_clause(RecordDef). current_clause(RecordDef).
:- meta_predicate :- meta_predicate
current_record(:). current_record(?, :),
current_record_predicate(?, :).
:- multifile :- multifile
current_record/5. % Name, Module, Term, X, IsX current_record/5. % Name, Module, Term, X, IsX
@ -156,6 +162,56 @@ current_clause(RecordDef) -->
]. ].
%% current_record_predicate(?Record, ?PI) is nondet.
%
% True if PI is the predicate indicator for an access predicate to
% Record. This predicate is intended to support cross-referencer
% tools.
current_record_predicate(Record, M:PI) :-
( ground(PI)
-> Det = true
; true
),
current_record(Record, M:RecordDef),
( general_record_pred(Record, M:PI)
; RecordDef =.. [_|Args],
defaults(Args, _Defs, TypedArgs),
types(TypedArgs, Names, _Types),
member(Field, Names),
field_record_pred(Record, Field, M:PI)
),
( Det == true
-> !
; true
).
general_record_pred(Record, _:Name/1) :-
atom_concat(is_, Record, Name).
general_record_pred(Record, _:Name/1) :-
atom_concat(default_, Record, Name).
general_record_pred(Record, _:Name/A) :-
member(A, [2,3]),
atom_concat(make_, Record, Name).
general_record_pred(Record, _:Name/3) :-
atom_concat(Record, '_data', Name).
general_record_pred(Record, _:Name/A) :-
member(A, [3,4]),
atomic_list_concat([set_, Record, '_fields'], Name).
general_record_pred(Record, _:Name/3) :-
atomic_list_concat([set_, Record, '_field'], Name).
field_record_pred(Record, Field, _:Name/2) :-
atomic_list_concat([Record, '_', Field], Name).
field_record_pred(Record, Field, _:Name/A) :-
member(A, [2,3]),
atomic_list_concat([set_, Field, '_of_', Record], Name).
field_record_pred(Record, Field, _:Name/2) :-
atomic_list_concat([nb_set_, Field, '_of_', Record], Name).
prolog:generated_predicate(P) :-
current_record_predicate(_, P).
%% make_predicate(+Constructor)// is det. %% make_predicate(+Constructor)// is det.
% %
% Creates the make_<constructor>(+Fields, -Record) predicate. This % Creates the make_<constructor>(+Fields, -Record) predicate. This
@ -286,6 +342,22 @@ access_predicates([Name|NT], I, Arity, Constructor) -->
access_predicates(NT, I2, Arity, Constructor). access_predicates(NT, I2, Arity, Constructor).
%% data_predicate(+Names, +Idx0, +Arity, +Constructor, +DataName)// is det.
%
% Create the <constructor>_data(Name, Record, Value) predicate.
data_predicate([], _, _, _, _) -->
[].
data_predicate([Name|NT], I, Arity, Constructor, DataName) -->
{ functor(Record, Constructor, Arity),
arg(I, Record, Value),
Clause =.. [DataName, Name, Record, Value],
I2 is I + 1
},
[Clause],
data_predicate(NT, I2, Arity, Constructor, DataName).
%% set_predicates(+Names, +Idx0, +Arity, +Types, +Constructor)// is det. %% set_predicates(+Names, +Idx0, +Arity, +Types, +Constructor)// is det.
% %
% Create the clauses % Create the clauses

View File

@ -101,7 +101,7 @@ SONAMEFLAG=@SONAMEFLAG@
#4.1VPATH=@srcdir@:@srcdir@/OPTYap #4.1VPATH=@srcdir@:@srcdir@/OPTYap
CWD=$(PWD) CWD=$(PWD)
# #
VERSION=6.3.2 VERSION=6.3.4
MYDDAS_VERSION=MYDDAS-0.9.1 MYDDAS_VERSION=MYDDAS-0.9.1
# #
@ -135,14 +135,13 @@ IOLIB_HEADERS=$(srcdir)/os/pl-buffer.h \
$(srcdir)/os/dtoa.c \ $(srcdir)/os/dtoa.c \
$(srcdir)/H/pl-incl.h \ $(srcdir)/H/pl-incl.h \
$(srcdir)/H/pl-global.h \ $(srcdir)/H/pl-global.h \
$(srcdir)/os/pl-mswchar.h \
$(srcdir)/os/pl-option.h \ $(srcdir)/os/pl-option.h \
$(srcdir)/os/pl-os.h \ $(srcdir)/os/pl-os.h \
$(srcdir)/os/pl-privitf.h \ $(srcdir)/os/pl-privitf.h \
$(srcdir)/os/pl-table.h \ $(srcdir)/os/pl-table.h \
$(srcdir)/os/pl-text.h \ $(srcdir)/os/pl-text.h \
$(srcdir)/os/pl-utf8.h \ $(srcdir)/os/pl-utf8.h \
$(srcdir)/H/pl-yap.h @ENABLE_WINCONSOLE@ $(srcdir)/os/windows/dirent.h $(srcdir)/os/windows/utf8.h $(srcdir)/os/windows/utf8.c $(srcdir)/os/windows/uxnt.h $(srcdir)/os/windows/mswchar.h $(srcdir)/os/windows/popen.c $(srcdir)/H/pl-yap.h @ENABLE_WINCONSOLE@ $(srcdir)/os/windows/dirent.h $(srcdir)/os/windows/utf8.h $(srcdir)/os/windows/utf8.c $(srcdir)/os/windows/uxnt.h $(srcdir)/os/windows/popen.c
HEADERS = \ HEADERS = \
$(srcdir)/H/Atoms.h \ $(srcdir)/H/Atoms.h \
@ -224,6 +223,7 @@ IOLIB_SOURCES=$(srcdir)/os/pl-buffer.c $(srcdir)/os/pl-ctype.c \
$(srcdir)/os/pl-table.c \ $(srcdir)/os/pl-table.c \
$(srcdir)/os/pl-tai.c \ $(srcdir)/os/pl-tai.c \
$(srcdir)/os/pl-text.c \ $(srcdir)/os/pl-text.c \
$(srcdir)/os/pl-version.c \
$(srcdir)/os/pl-write.c \ $(srcdir)/os/pl-write.c \
$(srcdir)/C/pl-yap.c @ENABLE_WINCONSOLE@$(srcdir)/os/windows/uxnt.c $(srcdir)/C/pl-yap.c @ENABLE_WINCONSOLE@$(srcdir)/os/windows/uxnt.c
@ -350,7 +350,7 @@ IOLIB_OBJECTS=pl-buffer.o pl-codelist.o pl-ctype.o pl-dtoa.o pl-error.o \
pl-rl.o \ pl-rl.o \
pl-stream.o pl-string.o pl-table.o \ pl-stream.o pl-string.o pl-table.o \
pl-tai.o pl-text.o pl-utf8.o \ pl-tai.o pl-text.o pl-utf8.o \
pl-write.o \ pl-version.o pl-write.o \
pl-yap.o @ENABLE_WINCONSOLE@ uxnt.o pl-yap.o @ENABLE_WINCONSOLE@ uxnt.o
ENGINE_OBJECTS = \ ENGINE_OBJECTS = \
@ -649,6 +649,9 @@ pl-text.o: $(srcdir)/os/pl-text.c config.h
pl-utf8.o: $(srcdir)/os/pl-utf8.c config.h pl-utf8.o: $(srcdir)/os/pl-utf8.c config.h
$(CC) -c $(CFLAGS) -I$(srcdir)/include -I$(srcdir) -I$(srcdir)/os @EXTRA_INCLUDES_FOR_WIN32@ $(srcdir)/os/pl-utf8.c -o $@ $(CC) -c $(CFLAGS) -I$(srcdir)/include -I$(srcdir) -I$(srcdir)/os @EXTRA_INCLUDES_FOR_WIN32@ $(srcdir)/os/pl-utf8.c -o $@
pl-version.o: $(srcdir)/os/pl-version.c config.h
$(CC) -c $(CFLAGS) -I$(srcdir)/include -I$(srcdir) -I$(srcdir)/os @EXTRA_INCLUDES_FOR_WIN32@ $(srcdir)/os/pl-version.c -o $@
pl-write.o: $(srcdir)/os/pl-write.c config.h pl-write.o: $(srcdir)/os/pl-write.c config.h
$(CC) -c $(CFLAGS) -I$(srcdir)/include -I$(srcdir) -I$(srcdir)/os @EXTRA_INCLUDES_FOR_WIN32@ $(srcdir)/os/pl-write.c -o $@ $(CC) -c $(CFLAGS) -I$(srcdir)/include -I$(srcdir) -I$(srcdir)/os @EXTRA_INCLUDES_FOR_WIN32@ $(srcdir)/os/pl-write.c -o $@
@ -698,6 +701,7 @@ all: startup.yss
@INSTALL_DLLS@ (cd library/system; $(MAKE)) @INSTALL_DLLS@ (cd library/system; $(MAKE))
@INSTALL_DLLS@ (cd library/tries; $(MAKE)) @INSTALL_DLLS@ (cd library/tries; $(MAKE))
@ENABLE_CLIB@ @INSTALL_DLLS@ (cd packages/clib; $(MAKE)) @ENABLE_CLIB@ @INSTALL_DLLS@ (cd packages/clib; $(MAKE))
@ENABLE_CHR@ @INSTALL_DLLS@ (cd packages/chr; $(MAKE))
@ENABLE_HTTP@ @INSTALL_DLLS@ (cd packages/http; $(MAKE)) @ENABLE_HTTP@ @INSTALL_DLLS@ (cd packages/http; $(MAKE))
@ENABLE_PLDOC@ @INSTALL_DLLS@ (cd packages/pldoc; $(MAKE)) @ENABLE_PLDOC@ @INSTALL_DLLS@ (cd packages/pldoc; $(MAKE))
@ENABLE_PLUNIT@ @INSTALL_DLLS@ (cd packages/plunit; $(MAKE)) @ENABLE_PLUNIT@ @INSTALL_DLLS@ (cd packages/plunit; $(MAKE))
@ -921,6 +925,7 @@ clean: clean_docs
@ENABLE_REAL@ (cd packages/real; $(MAKE) clean) @ENABLE_REAL@ (cd packages/real; $(MAKE) clean)
@ENABLE_MINISAT@ (cd packages/swi-minisat2; $(MAKE) clean) @ENABLE_MINISAT@ (cd packages/swi-minisat2; $(MAKE) clean)
@ENABLE_CLPBN_BP@ (cd packages/CLPBN/horus; $(MAKE) clean) @ENABLE_CLPBN_BP@ (cd packages/CLPBN/horus; $(MAKE) clean)
@ENABLE_CHR@ @INSTALL_DLLS@ (cd packages/chr; $(MAKE) clean)
@ENABLE_ZLIB@ @INSTALL_DLLS@ (cd packages/zlib; $(MAKE) clean) @ENABLE_ZLIB@ @INSTALL_DLLS@ (cd packages/zlib; $(MAKE) clean)
@ENABLE_PRISM@ (cd packages/prism/src/c; $(MAKE) clean) @ENABLE_PRISM@ (cd packages/prism/src/c; $(MAKE) clean)
@ENABLE_PRISM@ (cd packages/prism/src/prolog; $(MAKE) clean) @ENABLE_PRISM@ (cd packages/prism/src/prolog; $(MAKE) clean)

View File

@ -52,6 +52,7 @@
#undef HAVE_ARPA_INET_H #undef HAVE_ARPA_INET_H
#undef HAVE_CTYPE_H #undef HAVE_CTYPE_H
#undef HAVE_CRYPT_H #undef HAVE_CRYPT_H
#undef HAVE_CRTDBG_H
#undef HAVE_CUDD_H #undef HAVE_CUDD_H
#undef HAVE_CUDDINT_H #undef HAVE_CUDDINT_H
#undef HAVE_CUDD_CUDD_H #undef HAVE_CUDD_CUDD_H
@ -87,6 +88,7 @@
#undef HAVE_READLINE_HISTORY_H #undef HAVE_READLINE_HISTORY_H
#undef HAVE_REGEX_H #undef HAVE_REGEX_H
#undef HAVE_RINTERFACE_H #undef HAVE_RINTERFACE_H
#undef HAVE_SHLOBJ_H
#undef HAVE_SIGINFO_H #undef HAVE_SIGINFO_H
#undef HAVE_SIGNAL_H #undef HAVE_SIGNAL_H
#undef HAVE_STDARG_H #undef HAVE_STDARG_H
@ -117,6 +119,8 @@
#undef HAVE_WCTYPE_H #undef HAVE_WCTYPE_H
#undef HAVE_WINSOCK_H #undef HAVE_WINSOCK_H
#undef HAVE_WINSOCK2_H #undef HAVE_WINSOCK2_H
#undef HAVE_WINSOCK2_H
#undef HAVE_LIBLOADERAPI_H
#if __MINGW32__ #if __MINGW32__
#define __WINDOWS__ 1 #define __WINDOWS__ 1
@ -184,6 +188,7 @@
#undef HAVE_FINITE #undef HAVE_FINITE
#undef HAVE_FPCLASS #undef HAVE_FPCLASS
#undef HAVE_FTIME #undef HAVE_FTIME
#undef HAVE_FTRUNCATE
#undef HAVE_GETCWD #undef HAVE_GETCWD
#undef HAVE_GETENV #undef HAVE_GETENV
#undef HAVE_GETEXECNAME #undef HAVE_GETEXECNAME

17
configure vendored
View File

@ -8038,7 +8038,6 @@ fi
fi fi
INSTALL_DLLS="#" INSTALL_DLLS="#"
EXTRA_OBJS="" EXTRA_OBJS=""
SHLIB_LD="#" SHLIB_LD="#"
@ -8387,6 +8386,7 @@ fi
fi fi
LDFLAGS="$LDFLAGS -L\$(abs_top_builddir) -Wl,-R,\$(LIBDIR)" LDFLAGS="$LDFLAGS -L\$(abs_top_builddir) -Wl,-R,\$(LIBDIR)"
DYNYAPLIB=libYap."$SO" DYNYAPLIB=libYap."$SO"
YAPLIB_LD=$SHLIB_LD
SONAMEFLAG="-Wl,--soname=$DYNYAPLIB" SONAMEFLAG="-Wl,--soname=$DYNYAPLIB"
EXTRA_LIBS_FOR_DLLS="$EXTRA_LIBS_FOR_DLLS -L\$(abs_top_builddir) -Wl,-R,\$(YAPLIBDIR)" EXTRA_LIBS_FOR_DLLS="$EXTRA_LIBS_FOR_DLLS -L\$(abs_top_builddir) -Wl,-R,\$(YAPLIBDIR)"
PRE_INSTALL_ENV="LD_LIBRARY_PATH=\$(abs_top_builddir)" PRE_INSTALL_ENV="LD_LIBRARY_PATH=\$(abs_top_builddir)"
@ -9026,7 +9026,7 @@ $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
fi fi
for ac_header in arpa/inet.h alloca.h crypt.h for ac_header in arpa/inet.h alloca.h crtdbg.h crypt.h
do : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -9091,7 +9091,7 @@ fi
done done
for ac_header in netdb.h netinet/in.h netinet/tcp.h pwd.h regex.h for ac_header in netdb.h netinet/in.h netinet/tcp.h pwd.h regex.h shlobj.h
do : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -9221,12 +9221,13 @@ fi
done done
for ac_header in mach-o/dyld.h for ac_header in mach-o/dyld.h LibLoaderAPI.h
do : do :
ac_fn_c_check_header_mongrel "$LINENO" "mach-o/dyld.h" "ac_cv_header_mach_o_dyld_h" "$ac_includes_default" as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
if test "x$ac_cv_header_mach_o_dyld_h" = xyes; then : ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
#define HAVE_MACH_O_DYLD_H 1 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF _ACEOF
fi fi
@ -10238,7 +10239,7 @@ _ACEOF
fi fi
done done
for ac_func in fesettrapenable fgetpos finite fpclass ftime getcwd getenv for ac_func in fesettrapenable fgetpos finite fpclass ftime ftruncate getcwd getenv
do : do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -1167,7 +1167,6 @@ else
AC_SYS_RESTARTABLE_SYSCALLS AC_SYS_RESTARTABLE_SYSCALLS
fi fi
dnl defaults dnl defaults
INSTALL_DLLS="#" INSTALL_DLLS="#"
EXTRA_OBJS="" EXTRA_OBJS=""
@ -1400,6 +1399,7 @@ dnl Linux has both elf and a.out, in this case we found elf
fi fi
LDFLAGS="$LDFLAGS -L\$(abs_top_builddir) -Wl,-R,\$(LIBDIR)" LDFLAGS="$LDFLAGS -L\$(abs_top_builddir) -Wl,-R,\$(LIBDIR)"
DYNYAPLIB=libYap."$SO" DYNYAPLIB=libYap."$SO"
YAPLIB_LD=$SHLIB_LD
SONAMEFLAG="-Wl,--soname=$DYNYAPLIB" SONAMEFLAG="-Wl,--soname=$DYNYAPLIB"
EXTRA_LIBS_FOR_DLLS="$EXTRA_LIBS_FOR_DLLS -L\$(abs_top_builddir) -Wl,-R,\$(YAPLIBDIR)" EXTRA_LIBS_FOR_DLLS="$EXTRA_LIBS_FOR_DLLS -L\$(abs_top_builddir) -Wl,-R,\$(YAPLIBDIR)"
PRE_INSTALL_ENV="LD_LIBRARY_PATH=\$(abs_top_builddir)" PRE_INSTALL_ENV="LD_LIBRARY_PATH=\$(abs_top_builddir)"
@ -1694,12 +1694,12 @@ AC_SUBST(PRE_INSTALL_ENV)
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_HEADER_SYS_WAIT AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(arpa/inet.h alloca.h crypt.h) AC_CHECK_HEADERS(arpa/inet.h alloca.h crtdbg.h crypt.h)
AC_CHECK_HEADERS(ctype.h direct.h dirent.h dlfcn.h) AC_CHECK_HEADERS(ctype.h direct.h dirent.h dlfcn.h)
AC_CHECK_HEADERS(errno.h execinfo.h fcntl.h fenv.h) AC_CHECK_HEADERS(errno.h execinfo.h fcntl.h fenv.h)
AC_CHECK_HEADERS(float.h fpu_control.h ieeefp.h io.h limits.h) AC_CHECK_HEADERS(float.h fpu_control.h ieeefp.h io.h limits.h)
AC_CHECK_HEADERS(locale.h malloc.h math.h memory.h) AC_CHECK_HEADERS(locale.h malloc.h math.h memory.h)
AC_CHECK_HEADERS(netdb.h netinet/in.h netinet/tcp.h pwd.h regex.h) AC_CHECK_HEADERS(netdb.h netinet/in.h netinet/tcp.h pwd.h regex.h shlobj.h)
AC_CHECK_HEADERS(siginfo.h signal.h stdarg.h stdint.h string.h stropts.h) AC_CHECK_HEADERS(siginfo.h signal.h stdarg.h stdint.h string.h stropts.h)
AC_CHECK_HEADERS(sys/conf.h sys/dir.h sys/file.h) AC_CHECK_HEADERS(sys/conf.h sys/dir.h sys/file.h)
AC_CHECK_HEADERS(sys/mman.h sys/ndir.h sys/param.h) AC_CHECK_HEADERS(sys/mman.h sys/ndir.h sys/param.h)
@ -1709,7 +1709,7 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h sys/types.h)
AC_CHECK_HEADERS(sys/ucontext.h sys/un.h sys/wait.h) AC_CHECK_HEADERS(sys/ucontext.h sys/un.h sys/wait.h)
AC_CHECK_HEADERS(time.h unistd.h utime.h wctype.h winsock.h winsock2.h) AC_CHECK_HEADERS(time.h unistd.h utime.h wctype.h winsock.h winsock2.h)
AC_CHECK_HEADERS(zlib.h zutil.h) AC_CHECK_HEADERS(zlib.h zutil.h)
AC_CHECK_HEADERS(mach-o/dyld.h) AC_CHECK_HEADERS(mach-o/dyld.h LibLoaderAPI.h)
if test "$yap_cv_gmp" != "no" if test "$yap_cv_gmp" != "no"
then then
AC_CHECK_HEADERS(gmp.h) AC_CHECK_HEADERS(gmp.h)
@ -2068,7 +2068,7 @@ AC_CHECK_FUNCS(_NSGetEnviron _chsize_s access acosh)
AC_CHECK_FUNCS(alloca asinh atanh chdir clock clock_gettime) AC_CHECK_FUNCS(alloca asinh atanh chdir clock clock_gettime)
AC_CHECK_FUNCS(ctime dlopen dup2) AC_CHECK_FUNCS(ctime dlopen dup2)
AC_CHECK_FUNCS(erf feclearexcept) AC_CHECK_FUNCS(erf feclearexcept)
AC_CHECK_FUNCS(fesettrapenable fgetpos finite fpclass ftime getcwd getenv) AC_CHECK_FUNCS(fesettrapenable fgetpos finite fpclass ftime ftruncate getcwd getenv)
AC_CHECK_FUNCS(getexecname) AC_CHECK_FUNCS(getexecname)
AC_CHECK_FUNCS(gethostbyname gethostent gethostid gethostname) AC_CHECK_FUNCS(gethostbyname gethostent gethostid gethostname)
AC_CHECK_FUNCS(gethrtime getpagesize) AC_CHECK_FUNCS(gethrtime getpagesize)

View File

@ -8,7 +8,7 @@
@c @setchapternewpage odd @c @setchapternewpage odd
@c %**end of header @c %**end of header
@set VERSION 6.3.2 @set VERSION 6.3.3
@set EDITION 4.2.9 @set EDITION 4.2.9
@set UPDATED Oct 2010 @set UPDATED Oct 2010
@ -1686,6 +1686,13 @@ supported encodings.
is @code{compact} clauses are compiled and no source code is stored; is @code{compact} clauses are compiled and no source code is stored;
if it is @code{source} clauses are compiled and source code is stored; if it is @code{source} clauses are compiled and source code is stored;
if it is @code{assert_all} clauses are asserted into the data-base. if it is @code{assert_all} clauses are asserted into the data-base.
@item comnsult(+@var{Mode})
This extension controls the type of file to load. If @var{Mode}
is @code{consult}, clauses are added to the data-base,
is @code{reconsult}, clauses are recompiled,
is @code{db}, these are facts that need to be added to the data-base,
is @code{exo}, these are facts with atoms and integers that need a very compact representation.
@end table @end table
@item ensure_loaded(@var{+F}) [ISO] @item ensure_loaded(@var{+F}) [ISO]
@ -1708,7 +1715,14 @@ if they have not been loaded before, does nothing otherwise.
@syindex load_db/1 @syindex load_db/1
@cnindex load_db/1 @cnindex load_db/1
@noindent @noindent
Load a database of facts with equal structure. Useful when wanting to Load a database of facts with equal structure.
@item exo_files(@var{+Files})
@findex exo_files/1
@syindex exo_files/1
@cnindex exo_files/1
@noindent
Load compactly a database of facts with equal structure. Useful when wanting to
read in a very compact way database tables. read in a very compact way database tables.
@item make @item make

View File

@ -127,7 +127,10 @@ typedef unsigned long uintptr_t;
#include <inttypes.h> /* more portable than stdint.h */ #include <inttypes.h> /* more portable than stdint.h */
#endif #endif
#ifndef PL_HAVE_TERM_T
#define PL_HAVE_TERM_T
typedef uintptr_t term_t; typedef uintptr_t term_t;
#endif
typedef void *module_t; typedef void *module_t;
typedef void *record_t; typedef void *record_t;
typedef uintptr_t atom_t; typedef uintptr_t atom_t;
@ -220,6 +223,15 @@ typedef void *PL_engine_t;
#define PL_CYCLIC_TERM (42) /* a cyclic list/term */ #define PL_CYCLIC_TERM (42) /* a cyclic list/term */
#define PL_NOT_A_LIST (43) /* Object is not a list */ #define PL_NOT_A_LIST (43) /* Object is not a list */
/* Or'ed flags for PL_set_prolog_flag() */
/* MUST fit in a short int! */
#define FF_READONLY 0x1000 /* Read-only prolog flag */
#define FF_KEEP 0x2000 /* keep prolog flag if already se
t */
#define FF_NOCREATE 0x4000 /* Fail if flag is non-existent */
#define FF_MASK 0xf000
#define CVT_ATOM 0x0001 #define CVT_ATOM 0x0001
#define CVT_STRING 0x0002 #define CVT_STRING 0x0002
#define CVT_LIST 0x0004 #define CVT_LIST 0x0004
@ -332,9 +344,6 @@ UNICODE file functions.
#ifdef SIO_MAGIC /* defined from <SWI-Stream.h> */ #ifdef SIO_MAGIC /* defined from <SWI-Stream.h> */
#define FF_NOCREATE 0x4000 /* Fail if flag is non-existent */
#define FF_MASK 0xf000
/******************************* /*******************************
* STREAM SUPPORT * * STREAM SUPPORT *
*******************************/ *******************************/
@ -373,6 +382,10 @@ PL_EXPORT(IOSTREAM *)*_PL_streams(void); /* base of streams */
PL_WRT_ATTVAR_WRITE | \ PL_WRT_ATTVAR_WRITE | \
PL_WRT_ATTVAR_PORTRAY) PL_WRT_ATTVAR_PORTRAY)
#define PL_WRT_BLOB_PORTRAY 0x400 /* Use portray to emit non-text blobs */ #define PL_WRT_BLOB_PORTRAY 0x400 /* Use portray to emit non-text blobs */
#define PL_WRT_NO_CYCLES 0x800 /* Never emit @(Template,Subst) */
#define PL_WRT_LIST 0x1000 /* Write [...], even with ignoreops */
#define PL_WRT_NEWLINE 0x2000 /* Add a newline */
#define PL_WRT_VARNAMES 0x4000 /* Internal: variable_names(List) */
PL_EXPORT(int) PL_write_term(IOSTREAM *s, PL_EXPORT(int) PL_write_term(IOSTREAM *s,
term_t term, term_t term,
@ -525,6 +538,7 @@ extern X_API int PL_is_string(term_t);
extern X_API int PL_is_variable(term_t); extern X_API int PL_is_variable(term_t);
extern X_API int PL_term_type(term_t); extern X_API int PL_term_type(term_t);
extern X_API int PL_is_inf(term_t); extern X_API int PL_is_inf(term_t);
extern X_API int PL_is_acyclic(term_t t);
/* end PL_is_* functions =============================*/ /* end PL_is_* functions =============================*/
extern X_API void PL_halt(int); extern X_API void PL_halt(int);
extern X_API int PL_initialise(int, char **); extern X_API int PL_initialise(int, char **);
@ -579,6 +593,7 @@ extern X_API int PL_erase_external(char *);
extern X_API int PL_action(int,...); extern X_API int PL_action(int,...);
extern X_API void PL_on_halt(void (*)(int, void *), void *); extern X_API void PL_on_halt(void (*)(int, void *), void *);
extern X_API void *PL_malloc(size_t); extern X_API void *PL_malloc(size_t);
extern X_API void *PL_malloc_uncollectable(size_t s);
extern X_API void *PL_realloc(void*,size_t); extern X_API void *PL_realloc(void*,size_t);
extern X_API void PL_free(void *); extern X_API void PL_free(void *);
extern X_API int PL_eval_expression_to_int64_ex(term_t t, int64_t *val); extern X_API int PL_eval_expression_to_int64_ex(term_t t, int64_t *val);
@ -618,7 +633,7 @@ extern char *PL_prompt_string(int fd);
PL_EXPORT(int) PL_get_file_name(term_t n, char **name, int flags); PL_EXPORT(int) PL_get_file_name(term_t n, char **name, int flags);
PL_EXPORT(int) PL_get_file_nameW(term_t n, wchar_t **name, int flags); PL_EXPORT(int) PL_get_file_nameW(term_t n, wchar_t **name, int flags);
PL_EXPORT(void) PL_changed_cwd(void); /* foreign code changed CWD */ PL_EXPORT(void) PL_changed_cwd(void); /* foreign code changed CWD */
PL_EXPORT(const char *) PL_cwd(void); PL_EXPORT(char *) PL_cwd(char *buf, size_t buflen);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: the functions in this section are not documented, as as yet not NOTE: the functions in this section are not documented, as as yet not
@ -784,8 +799,6 @@ PL_EXPORT(int) PL_unify_mpq(term_t t, mpq_t mpz);
#endif #endif
extern X_API const char *PL_cwd(void);
void swi_install(void); void swi_install(void);
X_API int PL_warning(const char *msg, ...); X_API int PL_warning(const char *msg, ...);

File diff suppressed because it is too large Load Diff

View File

@ -120,8 +120,14 @@ typedef enum {
#define YAP_WRITE_QUOTED 1 #define YAP_WRITE_QUOTED 1
#define YAP_WRITE_IGNORE_OPS 2 #define YAP_WRITE_IGNORE_OPS 2
#define YAP_WRITE_HANDLE_VARS 2 #define YAP_WRITE_HANDLE_VARS 4
#define YAP_WRITE_USE_PORTRAY 8 #define YAP_WRITE_USE_PORTRAY 8
#define YAP_WRITE_HANDLE_CYCLES 0x20
#define YAP_WRITE_BACKQUOTE_STRING 0x80
#define YAP_WRITE_ATTVAR_NONE 0x100
#define YAP_WRITE_ATTVAR_DOTS 0x200
#define YAP_WRITE_ATTVAR_PORTRAY 0x400
#define YAP_WRITE_BLOB_PORTRAY 0x800
#define YAP_CONSULT_MODE 0 #define YAP_CONSULT_MODE 0
#define YAP_RECONSULT_MODE 1 #define YAP_RECONSULT_MODE 1

View File

@ -20,6 +20,10 @@
#include <string.h> #include <string.h>
/* for freeBSD9.1 */
#define _WITH_DPRINTF
#include <stdio.h>
#include <SWI-Prolog.h> #include <SWI-Prolog.h>
#include "swi.h" #include "swi.h"

View File

@ -1738,6 +1738,12 @@ X_API int PL_is_ground(term_t t)
return Yap_IsGroundTerm(Yap_GetFromSlot(t PASS_REGS)); return Yap_IsGroundTerm(Yap_GetFromSlot(t PASS_REGS));
} }
X_API int PL_is_acyclic(term_t t)
{
CACHE_REGS
return Yap_IsAcyclicTerm(Yap_GetFromSlot(t PASS_REGS));
}
X_API int PL_is_callable(term_t t) X_API int PL_is_callable(term_t t)
{ {
CACHE_REGS CACHE_REGS
@ -2196,6 +2202,7 @@ PL_open_foreign_frame(void)
new->open = FALSE; new->open = FALSE;
new->cp = CP; new->cp = CP;
new->p = P; new->p = P;
new->flags = 0;
new->b = (CELL)(LCL0-(CELL*)B); new->b = (CELL)(LCL0-(CELL*)B);
new->slots = CurSlot; new->slots = CurSlot;
LOCAL_execution = new; LOCAL_execution = new;
@ -2226,6 +2233,8 @@ PL_close_foreign_frame(fid_t f)
CurSlot = env->slots; CurSlot = env->slots;
B = (choiceptr)(LCL0-env->b); B = (choiceptr)(LCL0-env->b);
ASP = (CELL *)(LCL0-CurSlot); ASP = (CELL *)(LCL0-CurSlot);
EX = NULL;
LOCAL_BallTerm = EX;
LOCAL_execution = env->old; LOCAL_execution = env->old;
free(env); free(env);
} }
@ -2274,6 +2283,8 @@ PL_discard_foreign_frame(fid_t f)
LOCAL_execution = env->old; LOCAL_execution = env->old;
ASP = LCL0-CurSlot; ASP = LCL0-CurSlot;
B = B->cp_b; B = B->cp_b;
EX = NULL;
LOCAL_BallTerm = EX;
free(env); free(env);
} }
@ -2285,9 +2296,22 @@ X_API qid_t PL_open_query(module_t ctx, int flags, predicate_t p, term_t t0)
Term t[2], m; Term t[2], m;
/* ignore flags and module for now */ /* ignore flags and module for now */
PL_open_foreign_frame(); if (!LOCAL_execution) {
open_query *new = (open_query *)malloc(sizeof(open_query));
if (!new) return 0;
new->old = LOCAL_execution;
new->g = TermNil;
new->open = FALSE;
new->cp = CP;
new->p = P;
new->b = (CELL)(LCL0-(CELL*)B);
new->slots = CurSlot;
new->flags = 0;
LOCAL_execution = new;
}
LOCAL_execution->open=1; LOCAL_execution->open=1;
LOCAL_execution->state=0; LOCAL_execution->state=0;
LOCAL_execution->flags = flags;
PredicateInfo((PredEntry *)p, &yname, &arity, &m); PredicateInfo((PredEntry *)p, &yname, &arity, &m);
t[0] = SWIModuleToModule(ctx); t[0] = SWIModuleToModule(ctx);
if (arity == 0) { if (arity == 0) {
@ -2346,9 +2370,15 @@ X_API void PL_cut_query(qid_t qi)
X_API void PL_close_query(qid_t qi) X_API void PL_close_query(qid_t qi)
{ {
CACHE_REGS
EX = NULL;
if (EX && !(qi->flags & (PL_Q_CATCH_EXCEPTION|PL_Q_PASS_EXCEPTION))) {
EX = NULL;
}
/* need to implement backtracking here */ /* need to implement backtracking here */
if (qi->open != 1 || qi->state == 0) if (qi->open != 1 || qi->state == 0) {
return; return;
}
YAP_PruneGoal(); YAP_PruneGoal();
YAP_RestartGoal(); YAP_RestartGoal();
qi->open = 0; qi->open = 0;
@ -2784,6 +2814,11 @@ PL_query(int query)
} }
} }
X_API void
PL_cleanup_fork(void)
{
}
X_API void (*PL_signal(int sig, void (*func)(int)))(int) X_API void (*PL_signal(int sig, void (*func)(int)))(int)
{ {
@ -2796,11 +2831,106 @@ X_API void PL_on_halt(void (*f)(int, void *), void *closure)
Yap_HaltRegisterHook((HaltHookFunc)f,closure); Yap_HaltRegisterHook((HaltHookFunc)f,closure);
} }
X_API char *PL_atom_generator(const char *prefix, int state) #define is_signalled() unlikely(LD && LD->signal.pending != 0)
#ifdef O_PLMT
#include <pthread.h>
static pthread_key_t atomgen_key;
#endif
typedef struct scan_atoms {
Int pos;
Atom atom;
} scan_atoms_t;
static inline int
str_prefix(const char *p0, char *s)
{ {
char *p = (char *)p0;
while (*p && *p == *s) { p++; s++; }
return p[0] == '\0';
}
static int
atom_generator(const char *prefix, char **hit, int state)
{
struct scan_atoms *index;
Atom catom;
Int i;
#ifdef O_PLMT
if ( !atomgen_key ) {
pthread_key_create(&atomgen_key, NULL);
state = FALSE;
}
#endif
if ( !state )
{ index = (struct scan_atoms *)malloc(sizeof(struct scan_atoms));
i = 0;
catom = NIL;
} else
{
#ifdef O_PLMT
index = (struct scan_atoms *)pthread_getspecific(atomgen_key);
#else
index = LOCAL_search_atoms;
#endif
catom = index->atom;
i = index->pos;
}
while (catom != NIL || i < AtomHashTableSize) {
// if ( is_signalled() ) /* Notably allow windows version */
// PL_handle_signals(); /* to break out on ^C */
AtomEntry *ap;
if (catom == NIL) {
/* move away from current hash table line */
READ_LOCK(HashChain[i].AERWLock);
catom = HashChain[i].Entry;
READ_UNLOCK(HashChain[i].AERWLock);
i++;
} else {
ap = RepAtom(catom);
READ_LOCK(ap->ARWLock);
if ( str_prefix(prefix, ap->StrOfAE) ) {
index->pos = i;
index->atom = ap->NextOfAE;
#ifdef O_PLMT
pthread_setspecific(atomgen_key,index);
#else
LOCAL_search_atoms = index;
#endif
*hit = ap->StrOfAE;
READ_UNLOCK(ap->ARWLock);
return TRUE;
}
catom = ap->NextOfAE;
READ_UNLOCK(ap->ARWLock);
}
}
#ifdef O_PLMT
pthread_setspecific(atomgen_key,NULL);
#else
LOCAL_search_atoms = NULL;
#endif
free(index);
return FALSE;
}
char *
PL_atom_generator(const char *prefix, int state)
{
char * hit = NULL;
if (atom_generator(prefix, &hit, state)) {
return hit;
}
return NULL; return NULL;
} }
X_API pl_wchar_t *PL_atom_generator_w(const pl_wchar_t *pref, pl_wchar_t *buffer, size_t buflen, int state) X_API pl_wchar_t *PL_atom_generator_w(const pl_wchar_t *pref, pl_wchar_t *buffer, size_t buflen, int state)
{ {
return NULL; return NULL;

View File

@ -49,6 +49,7 @@ typedef struct open_query_struct {
yamop *p, *cp; yamop *p, *cp;
Int slots, b; Int slots, b;
jmp_buf env; jmp_buf env;
int flags;
struct open_query_struct *old; struct open_query_struct *old;
} open_query; } open_query;

View File

@ -79,6 +79,7 @@ A Dec10 N "dec10"
A Default N "default" A Default N "default"
A DevNull N "/dev/null" A DevNull N "/dev/null"
A Diff N "\\=" A Diff N "\\="
A Dollar F "$"
A DoLogUpdClause F "$do_log_upd_clause" A DoLogUpdClause F "$do_log_upd_clause"
A DoLogUpdClause0 F "$do_log_upd_clause0" A DoLogUpdClause0 F "$do_log_upd_clause0"
A DoLogUpdClauseErase F "$do_log_upd_clause_erase" A DoLogUpdClauseErase F "$do_log_upd_clause_erase"
@ -132,6 +133,7 @@ A GetworkSeq F "$getwork_seq"
A GlobalSp N "global_sp" A GlobalSp N "global_sp"
A GlobalTrie N "global_trie" A GlobalTrie N "global_trie"
A GoalExpansion N "goal_expansion" A GoalExpansion N "goal_expansion"
A Hat N "^"
A HERE N "\n <====HERE====> \n" A HERE N "\n <====HERE====> \n"
A HandleThrow F "$handle_throw" A HandleThrow F "$handle_throw"
A Heap N "heap" A Heap N "heap"
@ -395,6 +397,7 @@ F GeneratePredInfo GeneratePredInfo 4
F GoalExpansion2 GoalExpansion 2 F GoalExpansion2 GoalExpansion 2
F GoalExpansion GoalExpansion 3 F GoalExpansion GoalExpansion 3
F HandleThrow HandleThrow 3 F HandleThrow HandleThrow 3
F Hat Hat 2
F Id Id 1 F Id Id 1
F Is Is 2 F Is Is 2
F LastExecuteWithin LastExecuteWithin 1 F LastExecuteWithin LastExecuteWithin 1

View File

@ -118,6 +118,8 @@ char pwd[YAP_FILENAME_MAX] void
//udi.c //udi.c
//struct udi_control_block RtreeCmd void //struct udi_control_block RtreeCmd void
char* RestoreFile void
END_GLOBAL_DATA END_GLOBAL_DATA

View File

@ -274,4 +274,7 @@ Functor FunctorVar =FunctorVar
// exo indexing // exo indexing
UInt ibnds[256] void UInt ibnds[256] void
// atom completion
struct scan_atoms* search_atoms void
END_WORKER_LOCAL END_WORKER_LOCAL

View File

@ -14,7 +14,9 @@ A abort "abort"
A aborted "$aborted" A aborted "$aborted"
A abs "abs" A abs "abs"
A access "access" A access "access"
A access_level "access_level"
A acos "acos" A acos "acos"
A acosh "acosh"
A acyclic_term "acyclic_term" A acyclic_term "acyclic_term"
A add_import "add_import" A add_import "add_import"
A address "address" A address "address"
@ -38,6 +40,7 @@ A argumentlimit "argumentlimit"
A as "as" A as "as"
A ascii "ascii" A ascii "ascii"
A asin "asin" A asin "asin"
A asinh "asinh"
A assert "assert" A assert "assert"
A asserta "asserta" A asserta "asserta"
A at "at" A at "at"
@ -49,6 +52,7 @@ A at_not_equals "\\=@="
A at_smaller "@<" A at_smaller "@<"
A at_smaller_eq "@=<" A at_smaller_eq "@=<"
A atan "atan" A atan "atan"
A atanh "atanh"
A atan2 "atan2" A atan2 "atan2"
A atom "atom" A atom "atom"
A atom_garbage_collection "atom_garbage_collection" A atom_garbage_collection "atom_garbage_collection"
@ -62,8 +66,10 @@ A backquoted_string "backquoted_string"
A backslash "\\" A backslash "\\"
A backtrace "backtrace" A backtrace "backtrace"
A bar "|" A bar "|"
A base "base"
A begin "begin" A begin "begin"
A binary "binary" A binary "binary"
A binary_stream "binary_stream"
A bind "bind" A bind "bind"
A bitor "\\/" A bitor "\\/"
A blobs "blobs" A blobs "blobs"
@ -73,6 +79,7 @@ A bool "bool"
A boolean "boolean" A boolean "boolean"
A brace_term_position "brace_term_position" A brace_term_position "brace_term_position"
A break "break" A break "break"
A break_level "break_level"
A btree "btree" A btree "btree"
A buffer "buffer" A buffer "buffer"
A buffer_size "buffer_size" A buffer_size "buffer_size"
@ -86,6 +93,7 @@ A callpred "$callpred"
A canceled "canceled" A canceled "canceled"
A case_sensitive_file_names "case_sensitive_file_names" A case_sensitive_file_names "case_sensitive_file_names"
A catch "catch" A catch "catch"
A category "category"
A ceil "ceil" A ceil "ceil"
A ceiling "ceiling" A ceiling "ceiling"
A char_type "char_type" A char_type "char_type"
@ -96,11 +104,13 @@ A chars "chars"
A chdir "chdir" A chdir "chdir"
A chmod "chmod" A chmod "chmod"
A choice "choice" A choice "choice"
A class "class"
A clause "clause" A clause "clause"
A clauses "clauses"
A clause_reference "clause_reference" A clause_reference "clause_reference"
A close "close" A close "close"
A close_on_abort "close_on_abort" A close_on_abort "close_on_abort"
A close_on_exec "close_on_exec" A close_on_exec "close_on_exec"
A close_option "close_option" A close_option "close_option"
A cm "cm" A cm "cm"
A cntrl "cntrl" A cntrl "cntrl"
@ -115,9 +125,11 @@ A compound "compound"
A context "context" A context "context"
A context_module "context_module" A context_module "context_module"
A continue "continue" A continue "continue"
A copysign "copysign"
A core "core" A core "core"
A core_left "core_left" A core_left "core_left"
A cos "cos" A cos "cos"
A cosh "cosh"
A cputime "cputime" A cputime "cputime"
A create "create" A create "create"
A csym "csym" A csym "csym"
@ -133,6 +145,7 @@ A cut_exit "cut_exit"
A cut_parent "cut_parent" A cut_parent "cut_parent"
A cutted "cut" A cutted "cut"
A cyclic_term "cyclic_term" A cyclic_term "cyclic_term"
A cycles "cycles"
A dand "$and" A dand "$and"
A date "date" A date "date"
A db_reference "db_reference" A db_reference "db_reference"
@ -143,8 +156,10 @@ A dcatch "$catch"
A dcut "$cut" A dcut "$cut"
A dde_error "dde_error" A dde_error "dde_error"
A dde_handle "dde_handle" A dde_handle "dde_handle"
A deadline "deadline"
A debug "debug" A debug "debug"
A debug_on_error "debug_on_error" A debug_on_error "debug_on_error"
A debug_topic "debug_topic"
A debugger_print_options "debugger_print_options" A debugger_print_options "debugger_print_options"
A debugger_show_context "debugger_show_context" A debugger_show_context "debugger_show_context"
A debugging "debugging" A debugging "debugging"
@ -176,11 +191,13 @@ A dots "dots"
A double_quotes "double_quotes" A double_quotes "double_quotes"
A doublestar "**" A doublestar "**"
A dprof_node "$profile_node" A dprof_node "$profile_node"
A dquery_loop "$query_loop"
A drecover_and_rethrow "$recover_and_rethrow" A drecover_and_rethrow "$recover_and_rethrow"
A dstream "$stream" A dstream "$stream"
A dthread_init "$thread_init" A dthread_init "$thread_init"
A dthrow "$throw" A dthrow "$throw"
A dtime "$time" A dtime "$time"
A dtoplevel "$toplevel"
A dvard "$VAR$" A dvard "$VAR$"
A dwakeup "$wakeup" A dwakeup "$wakeup"
A dynamic "dynamic" A dynamic "dynamic"
@ -274,9 +291,8 @@ A has_alternatives "has_alternatives"
A hash "hash" A hash "hash"
A hashed "hashed" A hashed "hashed"
A hat "^" A hat "^"
A heap "heap"
A heaplimit "heaplimit"
A heapused "heapused" A heapused "heapused"
A heap_gc "heap_gc"
A help "help" A help "help"
A hidden "hidden" A hidden "hidden"
A hide_childs "hide_childs" A hide_childs "hide_childs"
@ -284,6 +300,8 @@ A history_depth "history_depth"
A ifthen "->" A ifthen "->"
A ignore "ignore" A ignore "ignore"
A ignore_ops "ignore_ops" A ignore_ops "ignore_ops"
A import_into "import_into"
A import_type "import_type"
A imported "imported" A imported "imported"
A imported_procedure "imported_procedure" A imported_procedure "imported_procedure"
A index "index" A index "index"
@ -292,7 +310,7 @@ A inf "inf"
A inferences "inferences" A inferences "inferences"
A infinite "infinite" A infinite "infinite"
A informational "informational" A informational "informational"
A init_file "init_file" A init_file "init_file"
A initialization "initialization" A initialization "initialization"
A input "input" A input "input"
A inserted_char "inserted_char" A inserted_char "inserted_char"
@ -318,9 +336,11 @@ A larger ">"
A larger_equal ">=" A larger_equal ">="
A level "level" A level "level"
A li "li" A li "li"
A library "library"
A limit "limit" A limit "limit"
A line "line" A line "line"
A line_count "line_count" A line_count "line_count"
A line_position "line_position"
A list "list" A list "list"
A list_position "list_position" A list_position "list_position"
A listing "listing" A listing "listing"
@ -335,6 +355,7 @@ A locked "locked"
A log "log" A log "log"
A log10 "log10" A log10 "log10"
A long "long" A long "long"
A loose "loose"
A low "low" A low "low"
A lower "lower" A lower "lower"
A lsb "lsb" A lsb "lsb"
@ -348,6 +369,7 @@ A max_dde_handles "max_dde_handles"
A max_depth "max_depth" A max_depth "max_depth"
A max_files "max_files" A max_files "max_files"
A max_frame_size "max_frame_size" A max_frame_size "max_frame_size"
A max_length "max_length"
A max_path_length "max_path_length" A max_path_length "max_path_length"
A max_size "max_size" A max_size "max_size"
A max_variable_length "max_variable_length" A max_variable_length "max_variable_length"
@ -367,6 +389,7 @@ A mod "mod"
A mode "mode" A mode "mode"
A modify "modify" A modify "modify"
A module "module" A module "module"
A module_class "module_class"
A module_property "module_property" A module_property "module_property"
A module_transparent "module_transparent" A module_transparent "module_transparent"
A modules "modules" A modules "modules"
@ -393,15 +416,16 @@ A not_implemented "not_implemented"
A not_less_than_one "not_less_than_one" A not_less_than_one "not_less_than_one"
A not_less_than_zero "not_less_than_zero" A not_less_than_zero "not_less_than_zero"
A not_provable "\\+" A not_provable "\\+"
A not_strickt_equals "\\==" A not_strict_equal "\\=="
A not_unique "not_unique" A not_unique "not_unique"
A number "number" A number "number"
A number_of_clauses "number_of_clauses" A number_of_clauses "number_of_clauses"
A number_of_rules "number_of_rules"
A numbervar_option "numbervar_option" A numbervar_option "numbervar_option"
A numbervars "numbervars" A numbervars "numbervars"
A occurs_check "occurs_check" A occurs_check "occurs_check"
A octet "octet" A octet "octet"
A off "off" A off "off"
A on "on" A on "on"
A open "open" A open "open"
A operator "operator" A operator "operator"
@ -411,6 +435,7 @@ A optimise "optimise"
A or "or" A or "or"
A order "order" A order "order"
A output "output" A output "output"
A owner "owner"
A pair "pair" A pair "pair"
A paren "paren" A paren "paren"
A parent "parent" A parent "parent"
@ -429,6 +454,7 @@ A plain "plain"
A plus "+" A plus "+"
A popcount "popcount" A popcount "popcount"
A portray "portray" A portray "portray"
A portray_goal "portray_goal"
A position "position" A position "position"
A posix "posix" A posix "posix"
A powm "powm" A powm "powm"
@ -439,6 +465,8 @@ A print_message "print_message"
A priority "priority" A priority "priority"
A private_procedure "private_procedure" A private_procedure "private_procedure"
A procedure "procedure" A procedure "procedure"
A process_comment "process_comment"
A process_cputime "process_cputime"
A profile_mode "profile_mode" A profile_mode "profile_mode"
A profile_no_cpu_time "profile_no_cpu_time" A profile_no_cpu_time "profile_no_cpu_time"
A profile_node "profile_node" A profile_node "profile_node"
@ -463,6 +491,7 @@ A quote "quote"
A quoted "quoted" A quoted "quoted"
A radix "radix" A radix "radix"
A random "random" A random "random"
A random_float "random_float"
A random_option "random_option" A random_option "random_option"
A rational "rational" A rational "rational"
A rationalize "rationalize" A rationalize "rationalize"
@ -478,6 +507,7 @@ A record "record"
A record_position "record_position" A record_position "record_position"
A redefine "redefine" A redefine "redefine"
A redo "redo" A redo "redo"
A redo_in_skip "redo_in_skip"
A references "references" A references "references"
A rem "rem" A rem "rem"
A rename "rename" A rename "rename"
@ -495,6 +525,7 @@ A running "running"
A runtime "runtime" A runtime "runtime"
A save_class "save_class" A save_class "save_class"
A save_option "save_option" A save_option "save_option"
A see "see"
A seed "seed" A seed "seed"
A seek_method "seek_method" A seek_method "seek_method"
A select "select" A select "select"
@ -507,15 +538,18 @@ A shared "shared"
A shared_object "shared_object" A shared_object "shared_object"
A shared_object_handle "shared_object_handle" A shared_object_handle "shared_object_handle"
A shell "shell" A shell "shell"
A shift_time "shift_time"
A sign "sign" A sign "sign"
A signal "signal" A signal "signal"
A signal_handler "signal_handler" A signal_handler "signal_handler"
A silent "silent" A silent "silent"
A sin "sin" A sin "sin"
A singletons "singletons" A singletons "singletons"
A sinh "sinh"
A size "size" A size "size"
A size_t "size_t" A size_t "size_t"
A skip "skip" A skip "skip"
A skipped "skipped"
A smaller "<" A smaller "<"
A smaller_equal "=<" A smaller_equal "=<"
A softcut "*->" A softcut "*->"
@ -534,6 +568,7 @@ A standard "standard"
A star "*" A star "*"
A start "start" A start "start"
A stat "stat" A stat "stat"
A state "state"
A static_procedure "static_procedure" A static_procedure "static_procedure"
A statistics "statistics" A statistics "statistics"
A status "status" A status "status"
@ -544,9 +579,11 @@ A stream_or_alias "stream_or_alias"
A stream_pair "stream_pair" A stream_pair "stream_pair"
A stream_position "$stream_position" A stream_position "$stream_position"
A stream_property "stream_property" A stream_property "stream_property"
A stream_type_check "stream_type_check"
A strict_equal "==" A strict_equal "=="
A string "string" A string "string"
A string_position "string_position" A string_position "string_position"
A strong "strong"
A subterm_positions "subterm_positions" A subterm_positions "subterm_positions"
A suffix "suffix" A suffix "suffix"
A syntax_error "syntax_error" A syntax_error "syntax_error"
@ -554,18 +591,22 @@ A syntax_errors "syntax_errors"
A system "system" A system "system"
A system_error "system_error" A system_error "system_error"
A system_init_file "system_init_file" A system_init_file "system_init_file"
A system_thread_id "system_thread_id" A system_thread_id "system_thread_id"
A system_time "system_time" A system_time "system_time"
A tan "tan" A tan "tan"
A tanh "tanh"
A temporary_files "temporary_files" A temporary_files "temporary_files"
A term "term" A term "term"
A term_expansion "term_expansion" A term_expansion "term_expansion"
A term_position "term_position" A term_position "term_position"
A terminal "terminal" A terminal "terminal"
A terminal_capability "terminal_capability" A terminal_capability "terminal_capability"
A test "test"
A text "text" A text "text"
A text_stream "text_stream"
A thread "thread" A thread "thread"
A thread_cputime "thread_cputime" A thread_cputime "thread_cputime"
A thread_get_message_option "thread_get_message_option"
A thread_initialization "thread_initialization" A thread_initialization "thread_initialization"
A thread_local "thread_local" A thread_local "thread_local"
A thread_local_procedure "thread_local_procedure" A thread_local_procedure "thread_local_procedure"
@ -583,7 +624,7 @@ A timezone "timezone"
A to_lower "to_lower" A to_lower "to_lower"
A to_upper "to_upper" A to_upper "to_upper"
A top "top" A top "top"
A top_level "top_level" A top_level "top_level"
A toplevel "toplevel" A toplevel "toplevel"
A trace "trace" A trace "trace"
A trace_any "trace_any" A trace_any "trace_any"
@ -643,6 +684,7 @@ A wait "wait"
A wakeup "wakeup" A wakeup "wakeup"
A walltime "walltime" A walltime "walltime"
A warning "warning" A warning "warning"
A weak "weak"
A wchar_t "wchar_t" A wchar_t "wchar_t"
A when_condition "when_condition" A when_condition "when_condition"
A white "white" A white "white"
@ -663,15 +705,18 @@ A zero_divisor "zero_divisor"
F abs 1 F abs 1
F access 1 F access 1
F acos 1 F acos 1
F acosh 1
F alias 1 F alias 1
F and 2 F and 2
F ar_equals 2 F ar_equals 2
F ar_not_equal 2 F ar_not_equal 2
F asin 1 F asin 1
F asinh 1
F assert 1 F assert 1
F asserta 1 F asserta 1
F atan 1 F atan 1
F atan 2 F atan 2
F atanh 1
F atan2 2 F atan2 2
F atom 1 F atom 1
F att 3 F att 3
@ -693,15 +738,18 @@ F ceil 1
F ceiling 1 F ceiling 1
F chars 1 F chars 1
F chars 2 F chars 2
F class 1
F clause 1 F clause 1
F close_on_abort 1 F close_on_abort 1
F close_on_exec 1 F close_on_exec 1
F codes 1 F codes 1
F codes 2 F codes 2
F colon 2 F colon 2
F comma 2 F comma 2
F context 2 F context 2
F copysign 2
F cos 1 F cos 1
F cosh 1
F cputime 0 F cputime 0
F curl 1 F curl 1
F cut_call 1 F cut_call 1
@ -717,7 +765,7 @@ F debugging 1
F detached 1 F detached 1
F dexit 2 F dexit 2
F dforeign_registered 2 F dforeign_registered 2
F dgarbage_collect 1 F dgarbage_collect 1
F div 2 F div 2
F gdiv 2 F gdiv 2
F divide 2 F divide 2
@ -769,7 +817,9 @@ F goal_expansion 2
F ground 1 F ground 1
F hat 2 F hat 2
F ifthen 2 F ifthen 2
F import_into 1
F input 0 F input 0
F input 3
F integer 1 F integer 1
F interrupt 1 F interrupt 1
F io_error 2 F io_error 2
@ -799,6 +849,7 @@ F nlink 1
F nonvar 1 F nonvar 1
F not_implemented 2 F not_implemented 2
F not_provable 1 F not_provable 1
F not_strict_equal 2
F occurs_check 2 F occurs_check 2
F or 1 F or 1
F output 0 F output 0
@ -813,14 +864,17 @@ F position 1
F powm 3 F powm 3
F print 1 F print 1
F print_message 2 F print_message 2
F priority 1
F procedure 2 F procedure 2
F prove 1 F prove 1
F prove 2 F prove 2
F punct 2 F punct 2
F random 1 F random 1
F random_float 0
F rational 1 F rational 1
F rationalize 1 F rationalize 1
F rdiv 2 F rdiv 2
F redo 1
F rem 2 F rem 2
F reposition 1 F reposition 1
F representation_error 1 F representation_error 1
@ -838,6 +892,7 @@ F signal 1
F signal 2 F signal 2
F sin 1 F sin 1
F singletons 1 F singletons 1
F sinh 1
F size 1 F size 1
F smaller 2 F smaller 2
F smaller_equal 2 F smaller_equal 2
@ -855,6 +910,7 @@ F string_position 2
F syntax_error 1 F syntax_error 1
F syntax_error 3 F syntax_error 3
F tan 1 F tan 1
F tanh 1
F term_expansion 2 F term_expansion 2
F term_position 5 F term_position 5
F timeout 1 F timeout 1
@ -875,3 +931,4 @@ F wakeup 3
F warning 3 F warning 3
F xor 2 F xor 2
F xpceref 1 F xpceref 1
F xpceref 2

View File

@ -3,7 +3,7 @@
Name: yap Name: yap
Summary: Prolog Compiler Summary: Prolog Compiler
Version: 6.3.2 Version: 6.3.4
Packager: Vitor Santos Costa <vsc@dcc.fc.up.pt> Packager: Vitor Santos Costa <vsc@dcc.fc.up.pt>
Release: 1 Release: 1
Source: http://www.dcc.fc.up.pt/~vsc/Yap/%{name}-%{version}.tar.gz Source: http://www.dcc.fc.up.pt/~vsc/Yap/%{name}-%{version}.tar.gz

View File

@ -3,7 +3,7 @@
Name: yap Name: yap
Summary: Prolog Compiler Summary: Prolog Compiler
Version: 6.3.2 Version: 6.3.4
Packager: Vitor Santos Costa <vsc@dcc.fc.up.pt> Packager: Vitor Santos Costa <vsc@dcc.fc.up.pt>
Release: 1 Release: 1
Source: http://www.dcc.fc.up.pt/~vsc/Yap/%{name}-%{version}.tar.gz Source: http://www.dcc.fc.up.pt/~vsc/Yap/%{name}-%{version}.tar.gz

View File

@ -268,4 +268,4 @@ Function .onInstFailed
installer, please contact yap-users@sf.net" installer, please contact yap-users@sf.net"
FunctionEnd FunctionEnd
outfile "yap-6.3.2-installer.exe" outfile "yap-6.3.4-installer.exe"

View File

@ -265,4 +265,4 @@ Function .onInstFailed
installer, please contact yap-users@sf.net" installer, please contact yap-users@sf.net"
FunctionEnd FunctionEnd
outfile "yap64-6.3.2-installer.exe" outfile "yap64-6.3.4-installer.exe"

View File

@ -1,388 +1,395 @@
#ifndef _PL_STREAM_H #ifndef _PL_STREAM_H
#define _PL_STREAM_H #define _PL_STREAM_H
#ifndef _PL_EXPORT_DONE #ifndef _PL_EXPORT_DONE
#define _PL_EXPORT_DONE #define _PL_EXPORT_DONE
#if (defined(__WINDOWS__) || defined(__CYGWIN__)) && !defined(__LCC__) #if (defined(__WINDOWS__) || defined(__CYGWIN__)) && !defined(__LCC__)
#define HAVE_DECLSPEC #define HAVE_DECLSPEC
#endif #endif
#ifdef HAVE_DECLSPEC #ifdef HAVE_DECLSPEC
# ifdef PL_KERNEL # ifdef PL_KERNEL
#define PL_EXPORT(type) __declspec(dllexport) type #define PL_EXPORT(type) __declspec(dllexport) type
#define PL_EXPORT_DATA(type) __declspec(dllexport) type #define PL_EXPORT_DATA(type) __declspec(dllexport) type
#define install_t void #define install_t void
# else # else
# ifdef __BORLANDC__ # ifdef __BORLANDC__
#define PL_EXPORT(type) type _stdcall #define PL_EXPORT(type) type _stdcall
#define PL_EXPORT_DATA(type) extern type #define PL_EXPORT_DATA(type) extern type
# else # else
#define PL_EXPORT(type) extern type #define PL_EXPORT(type) extern type
#define PL_EXPORT_DATA(type) __declspec(dllimport) type #define PL_EXPORT_DATA(type) __declspec(dllimport) type
# endif # endif
#define install_t __declspec(dllexport) void #define install_t __declspec(dllexport) void
# endif # endif
#else /*HAVE_DECLSPEC*/ #else /*HAVE_DECLSPEC*/
#define PL_EXPORT(type) extern type #define PL_EXPORT(type) extern type
#define PL_EXPORT_DATA(type) extern type #define PL_EXPORT_DATA(type) extern type
#define install_t void #define install_t void
#endif /*HAVE_DECLSPEC*/ #endif /*HAVE_DECLSPEC*/
#endif /*_PL_EXPORT_DONE*/ #endif /*_PL_EXPORT_DONE*/
/* This appears to make the wide-character support compile and work /* This appears to make the wide-character support compile and work
on HPUX 11.23. There really should be a cleaner way ... on HPUX 11.23. There really should be a cleaner way ...
*/ */
#if defined(__hpux) #if defined(__hpux)
#include <sys/_mbstate_t.h> #include <sys/_mbstate_t.h>
#endif #endif
#if defined(_MSC_VER) && !defined(__WINDOWS__) #if defined(_MSC_VER) && !defined(__WINDOWS__)
#define __WINDOWS__ 1 #define __WINDOWS__ 1
#endif #endif
#include <stdarg.h> #include <stdarg.h>
#include <wchar.h> #include <wchar.h>
#include <stddef.h> #include <stddef.h>
#ifdef __WINDOWS__ #ifdef __WINDOWS__
#ifndef INT64_T_DEFINED #ifndef INT64_T_DEFINED
#define INT64_T_DEFINED 1 #define INT64_T_DEFINED 1
typedef __int64 int64_t; typedef __int64 int64_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
#if (_MSC_VER < 1300) && !defined(__MINGW32__) #if (_MSC_VER < 1300) && !defined(__MINGW32__)
typedef long intptr_t; typedef long intptr_t;
typedef unsigned long uintptr_t; typedef unsigned long uintptr_t;
typedef intptr_t ssize_t; /* signed version of size_t */ typedef intptr_t ssize_t; /* signed version of size_t */
#endif #endif
#endif #endif
#else #else
#include <unistd.h> #include <unistd.h>
#include <inttypes.h> /* more portable than stdint.h */ #include <inttypes.h> /* more portable than stdint.h */
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/******************************* #ifndef PL_HAVE_TERM_T
* CONSTANTS * #define PL_HAVE_TERM_T
*******************************/ typedef uintptr_t term_t;
#endif
#ifndef EOF /*******************************
#define EOF (-1) * CONSTANTS *
#endif *******************************/
#ifndef NULL #ifndef EOF
#define NULL ((void *)0) #define EOF (-1)
#endif #endif
#if defined(__WINDOWS__) && !defined(EWOULDBLOCK) #ifndef NULL
#define EWOULDBLOCK 1000 /* Needed for socket handling */ #define NULL ((void *)0)
#endif #endif
#define EPLEXCEPTION 1001 /* errno: pending Prolog exception */
#if defined(__WINDOWS__) && !defined(EWOULDBLOCK)
#define SIO_BUFSIZE (4096) /* buffering buffer-size */ #define EWOULDBLOCK 1000 /* Needed for socket handling */
#define SIO_LINESIZE (1024) /* Sgets() default buffer size */ #endif
#define SIO_MAGIC (7212676) /* magic number */ #define EPLEXCEPTION 1001 /* errno: pending Prolog exception */
#define SIO_CMAGIC (42) /* we are close (and thus illegal!) */
#define SIO_BUFSIZE (4096) /* buffering buffer-size */
typedef ssize_t (*Sread_function)(void *handle, char *buf, size_t bufsize); #define SIO_LINESIZE (1024) /* Sgets() default buffer size */
typedef ssize_t (*Swrite_function)(void *handle, char*buf, size_t bufsize); #define SIO_MAGIC (7212676) /* magic number */
typedef long (*Sseek_function)(void *handle, long pos, int whence); #define SIO_CMAGIC (42) /* we are close (and thus illegal!) */
typedef int64_t (*Sseek64_function)(void *handle, int64_t pos, int whence);
typedef int (*Sclose_function)(void *handle); typedef ssize_t (*Sread_function)(void *handle, char *buf, size_t bufsize);
typedef int (*Scontrol_function)(void *handle, int action, void *arg); typedef ssize_t (*Swrite_function)(void *handle, char*buf, size_t bufsize);
typedef long (*Sseek_function)(void *handle, long pos, int whence);
#include "pl-thread.h" typedef int64_t (*Sseek64_function)(void *handle, int64_t pos, int whence);
typedef int (*Sclose_function)(void *handle);
typedef struct io_functions typedef int (*Scontrol_function)(void *handle, int action, void *arg);
{ Sread_function read; /* fill the buffer */
Swrite_function write; /* empty the buffer */ #include "pl-thread.h"
Sseek_function seek; /* seek to position */
Sclose_function close; /* close stream */ typedef struct io_functions
Scontrol_function control; /* Info/control */ { Sread_function read; /* fill the buffer */
Sseek64_function seek64; /* seek to position (intptr_t files) */ Swrite_function write; /* empty the buffer */
} IOFUNCTIONS; Sseek_function seek; /* seek to position */
Sclose_function close; /* close stream */
typedef struct io_position Scontrol_function control; /* Info/control */
{ int64_t byteno; /* byte-position in file */ Sseek64_function seek64; /* seek to position (intptr_t files) */
int64_t charno; /* character position in file */ } IOFUNCTIONS;
int lineno; /* lineno in file */
int linepos; /* position in line */ typedef struct io_position
intptr_t reserved[2]; /* future extensions */ { int64_t byteno; /* byte-position in file */
} IOPOS; int64_t charno; /* character position in file */
int lineno; /* lineno in file */
/* NOTE: check with encoding_names */ int linepos; /* position in line */
/* in pl-file.c */ intptr_t reserved[2]; /* future extensions */
typedef enum } IOPOS;
{ ENC_UNKNOWN = 0, /* invalid/unknown */
ENC_OCTET, /* raw 8 bit input */ /* NOTE: check with encoding_names */
ENC_ASCII, /* US-ASCII (0..127) */ /* in pl-file.c */
ENC_ISO_LATIN_1, /* ISO Latin-1 (0..256) */ typedef enum
ENC_ANSI, /* default (multibyte) codepage */ { ENC_UNKNOWN = 0, /* invalid/unknown */
ENC_UTF8, ENC_OCTET, /* raw 8 bit input */
ENC_UNICODE_BE, /* big endian unicode file */ ENC_ASCII, /* US-ASCII (0..127) */
ENC_UNICODE_LE, /* little endian unicode file */ ENC_ISO_LATIN_1, /* ISO Latin-1 (0..256) */
ENC_WCHAR /* pl_wchar_t */ ENC_ANSI, /* default (multibyte) codepage */
} IOENC; ENC_UTF8,
ENC_UNICODE_BE, /* big endian unicode file */
#define SIO_NL_POSIX 0 /* newline as \n */ ENC_UNICODE_LE, /* little endian unicode file */
#define SIO_NL_DOS 1 /* newline as \r\n */ ENC_WCHAR /* pl_wchar_t */
#define SIO_NL_DETECT 3 /* detect processing mode */ } IOENC;
typedef struct io_stream #define SIO_NL_POSIX 0 /* newline as \n */
{ char *bufp; /* `here' */ #define SIO_NL_DOS 1 /* newline as \r\n */
char *limitp; /* read/write limit */ #define SIO_NL_DETECT 3 /* detect processing mode */
char *buffer; /* the buffer */
char *unbuffer; /* Sungetc buffer */ typedef struct io_stream
int lastc; /* last character written */ { char *bufp; /* `here' */
int magic; /* magic number SIO_MAGIC */ char *limitp; /* read/write limit */
int bufsize; /* size of the buffer */ char *buffer; /* the buffer */
int flags; /* Status flags */ char *unbuffer; /* Sungetc buffer */
IOPOS posbuf; /* location in file */ int lastc; /* last character written */
IOPOS * position; /* pointer to above */ int magic; /* magic number SIO_MAGIC */
void *handle; /* function's handle */ int bufsize; /* size of the buffer */
IOFUNCTIONS *functions; /* open/close/read/write/seek */ int flags; /* Status flags */
int locks; /* lock/unlock count */ IOPOS posbuf; /* location in file */
IOLOCK * mutex; /* stream mutex */ IOPOS * position; /* pointer to above */
/* SWI-Prolog 4.0.7 */ void *handle; /* function's handle */
void (*close_hook)(void* closure); IOFUNCTIONS *functions; /* open/close/read/write/seek */
void * closure; int locks; /* lock/unlock count */
/* SWI-Prolog 5.1.3 */ IOLOCK * mutex; /* stream mutex */
int timeout; /* timeout (milliseconds) */ /* SWI-Prolog 4.0.7 */
/* SWI-Prolog 5.4.4 */ void (*close_hook)(void* closure);
char * message; /* error/warning message */ void * closure;
IOENC encoding; /* character encoding used */ /* SWI-Prolog 5.1.3 */
struct io_stream * tee; /* copy data to this stream */ int timeout; /* timeout (milliseconds) */
mbstate_t * mbstate; /* ENC_ANSI decoding */ /* SWI-Prolog 5.4.4 */
struct io_stream * upstream; /* stream providing our input */ char * message; /* error/warning message */
struct io_stream * downstream; /* stream providing our output */ IOENC encoding; /* character encoding used */
unsigned newline : 2; /* Newline mode */ struct io_stream * tee; /* copy data to this stream */
unsigned erased : 1; /* Stream was erased */ mbstate_t * mbstate; /* ENC_ANSI decoding */
unsigned references : 4; /* Reference-count */ struct io_stream * upstream; /* stream providing our input */
int io_errno; /* Save errno value */ struct io_stream * downstream; /* stream providing our output */
void * exception; /* pending exception (record_t) */ unsigned newline : 2; /* Newline mode */
intptr_t reserved[2]; /* reserved for extension */ unsigned erased : 1; /* Stream was erased */
} IOSTREAM; unsigned references : 4; /* Reference-count */
int io_errno; /* Save errno value */
#define SmakeFlag(n) (1<<(n-1)) void * exception; /* pending exception (record_t) */
void * context; /* getStreamContext() */
#define SIO_FBUF SmakeFlag(1) /* full buffering */ intptr_t reserved[2]; /* reserved for extension */
#define SIO_LBUF SmakeFlag(2) /* line buffering */ } IOSTREAM;
#define SIO_NBUF SmakeFlag(3) /* no buffering */
#define SIO_FEOF SmakeFlag(4) /* end-of-file */ #define SmakeFlag(n) (1<<(n-1))
#define SIO_FERR SmakeFlag(5) /* error ocurred */
#define SIO_USERBUF SmakeFlag(6) /* buffer is from user */ #define SIO_FBUF SmakeFlag(1) /* full buffering */
#define SIO_INPUT SmakeFlag(7) /* input stream */ #define SIO_LBUF SmakeFlag(2) /* line buffering */
#define SIO_OUTPUT SmakeFlag(8) /* output stream */ #define SIO_NBUF SmakeFlag(3) /* no buffering */
#define SIO_NOLINENO SmakeFlag(9) /* line no. info is void */ #define SIO_FEOF SmakeFlag(4) /* end-of-file */
#define SIO_NOLINEPOS SmakeFlag(10) /* line pos is void */ #define SIO_FERR SmakeFlag(5) /* error ocurred */
#define SIO_STATIC SmakeFlag(11) /* Stream in static memory */ #define SIO_USERBUF SmakeFlag(6) /* buffer is from user */
#define SIO_RECORDPOS SmakeFlag(12) /* Maintain position */ #define SIO_INPUT SmakeFlag(7) /* input stream */
#define SIO_FILE SmakeFlag(13) /* Stream refers to an OS file */ #define SIO_OUTPUT SmakeFlag(8) /* output stream */
#define SIO_PIPE SmakeFlag(14) /* Stream refers to an OS pipe */ #define SIO_NOLINENO SmakeFlag(9) /* line no. info is void */
#define SIO_NOFEOF SmakeFlag(15) /* don't set SIO_FEOF flag */ #define SIO_NOLINEPOS SmakeFlag(10) /* line pos is void */
#define SIO_TEXT SmakeFlag(16) /* text-mode operation */ #define SIO_STATIC SmakeFlag(11) /* Stream in static memory */
#define SIO_FEOF2 SmakeFlag(17) /* attempt to read past eof */ #define SIO_RECORDPOS SmakeFlag(12) /* Maintain position */
#define SIO_FEOF2ERR SmakeFlag(18) /* Sfpasteof() */ #define SIO_FILE SmakeFlag(13) /* Stream refers to an OS file */
#define SIO_NOCLOSE SmakeFlag(19) /* Do not close on abort */ #define SIO_PIPE SmakeFlag(14) /* Stream refers to an OS pipe */
#define SIO_APPEND SmakeFlag(20) /* opened in append-mode */ #define SIO_NOFEOF SmakeFlag(15) /* don't set SIO_FEOF flag */
#define SIO_UPDATE SmakeFlag(21) /* opened in update-mode */ #define SIO_TEXT SmakeFlag(16) /* text-mode operation */
#define SIO_ISATTY SmakeFlag(22) /* Stream is a tty */ #define SIO_FEOF2 SmakeFlag(17) /* attempt to read past eof */
#define SIO_CLOSING SmakeFlag(23) /* We are closing the stream */ #define SIO_FEOF2ERR SmakeFlag(18) /* Sfpasteof() */
#define SIO_TIMEOUT SmakeFlag(24) /* We had a timeout */ #define SIO_NOCLOSE SmakeFlag(19) /* Do not close on abort */
#define SIO_NOMUTEX SmakeFlag(25) /* Do not allow multi-thread access */ #define SIO_APPEND SmakeFlag(20) /* opened in append-mode */
#define SIO_ADVLOCK SmakeFlag(26) /* File locked with advisory lock */ #define SIO_UPDATE SmakeFlag(21) /* opened in update-mode */
#define SIO_WARN SmakeFlag(27) /* Pending warning */ #define SIO_ISATTY SmakeFlag(22) /* Stream is a tty */
#define SIO_CLEARERR SmakeFlag(28) /* Clear error after reporting */ #define SIO_CLOSING SmakeFlag(23) /* We are closing the stream */
#define SIO_REPXML SmakeFlag(29) /* Bad char --> XML entity */ #define SIO_TIMEOUT SmakeFlag(24) /* We had a timeout */
#define SIO_REPPL SmakeFlag(30) /* Bad char --> Prolog \hex\ */ #define SIO_NOMUTEX SmakeFlag(25) /* Do not allow multi-thread access */
#define SIO_BOM SmakeFlag(31) /* BOM was detected/written */ #define SIO_ADVLOCK SmakeFlag(26) /* File locked with advisory lock */
#define SIO_WARN SmakeFlag(27) /* Pending warning */
#define SIO_SEEK_SET 0 /* From beginning of file. */ #define SIO_CLEARERR SmakeFlag(28) /* Clear error after reporting */
#define SIO_SEEK_CUR 1 /* From current position. */ #define SIO_REPXML SmakeFlag(29) /* Bad char --> XML entity */
#define SIO_SEEK_END 2 /* From end of file. */ #define SIO_REPPL SmakeFlag(30) /* Bad char --> Prolog \hex\ */
#define SIO_BOM SmakeFlag(31) /* BOM was detected/written */
PL_EXPORT(IOSTREAM *) S__getiob(void); /* get DLL's __iob[] address */
#define SIO_SEEK_SET 0 /* From beginning of file. */
PL_EXPORT_DATA(IOFUNCTIONS) Sfilefunctions; /* OS file functions */ #define SIO_SEEK_CUR 1 /* From current position. */
PL_EXPORT_DATA(int) Slinesize; /* Sgets() linesize */ #define SIO_SEEK_END 2 /* From end of file. */
#if (defined(__CYGWIN__) || defined(__MINGW32__)) && !defined(PL_KERNEL)
#define S__iob S__getiob() PL_EXPORT(IOSTREAM *) S__getiob(void); /* get DLL's __iob[] address */
#else
PL_EXPORT_DATA(IOSTREAM) S__iob[3]; /* Libs standard streams */ PL_EXPORT_DATA(IOFUNCTIONS) Sfilefunctions; /* OS file functions */
#endif PL_EXPORT_DATA(int) Slinesize; /* Sgets() linesize */
#if (defined(__CYGWIN__) || defined(__MINGW32__)) && !defined(PL_KERNEL)
#define Sinput (&S__iob[0]) /* Stream Sinput */ #define S__iob S__getiob()
#define Soutput (&S__iob[1]) /* Stream Soutput */ #else
#define Serror (&S__iob[2]) /* Stream Serror */ PL_EXPORT_DATA(IOSTREAM) S__iob[3]; /* Libs standard streams */
#endif
#define Sgetchar() Sgetc(Sinput)
#define Sputchar(c) Sputc((c), Soutput) #define Sinput (&S__iob[0]) /* Stream Sinput */
#define Soutput (&S__iob[1]) /* Stream Soutput */
#define S__checkpasteeof(s,c) \ #define Serror (&S__iob[2]) /* Stream Serror */
if ( (c)==-1 && (s)->flags & (SIO_FEOF|SIO_FERR) ) \
((s)->flags |= SIO_FEOF2) #define Sgetchar() Sgetc(Sinput)
#define S__updatefilepos_getc(s, c) \ #define Sputchar(c) Sputc((c), Soutput)
((s)->position ? S__fupdatefilepos_getc((s), (c)) \
: S__fcheckpasteeof((s), (c))) #define S__checkpasteeof(s,c) \
if ( (c)==-1 && (s)->flags & (SIO_FEOF|SIO_FERR) ) \
#define Snpgetc(s) ((s)->bufp < (s)->limitp ? (int)(*(s)->bufp++)&0xff \ ((s)->flags |= SIO_FEOF2)
: S__fillbuf(s)) #define S__updatefilepos_getc(s, c) \
#define Sgetc(s) S__updatefilepos_getc((s), Snpgetc(s)) ((s)->position ? S__fupdatefilepos_getc((s), (c)) \
: S__fcheckpasteeof((s), (c)))
PL_EXPORT(int) Speekcode(IOSTREAM *s);
#define Snpgetc(s) ((s)->bufp < (s)->limitp ? (int)(*(s)->bufp++)&0xff \
/* Control-operations */ : S__fillbuf(s))
#define SIO_GETSIZE (1) /* get size of underlying object */ #define Sgetc(s) S__updatefilepos_getc((s), Snpgetc(s))
#define SIO_GETFILENO (2) /* get underlying file (if any) */
#define SIO_SETENCODING (3) /* modify encoding of stream */ PL_EXPORT(int) Speekcode(IOSTREAM *s);
#define SIO_FLUSHOUTPUT (4) /* flush output */
#define SIO_LASTERROR (5) /* string holding last error */ /* Control-operations */
#ifdef __WINDOWS__ #define SIO_GETSIZE (1) /* get size of underlying object */
#define SIO_GETWINSOCK (6) /* get underlying SOCKET object */ #define SIO_GETFILENO (2) /* get underlying file (if any) */
#endif #define SIO_SETENCODING (3) /* modify encoding of stream */
#define SIO_FLUSHOUTPUT (4) /* flush output */
/* Sread_pending() */ #define SIO_LASTERROR (5) /* string holding last error */
#define SIO_RP_BLOCK 0x1 /* wait for new input */ #ifdef __WINDOWS__
#define SIO_GETWINSOCK (6) /* get underlying SOCKET object */
#if IOSTREAM_REPLACES_STDIO #endif
#undef FILE /* Sread_pending() */
#undef stdin #define SIO_RP_BLOCK 0x1 /* wait for new input */
#undef stdout
#undef stderr #if IOSTREAM_REPLACES_STDIO
#undef putc
#undef getc #undef FILE
#undef putchar #undef stdin
#undef getchar #undef stdout
#undef feof #undef stderr
#undef ferror #undef putc
#undef fileno #undef getc
#undef clearerr #undef putchar
#undef getchar
#define FILE IOSTREAM #undef feof
#define stdin Sinput #undef ferror
#define stdout Soutput #undef fileno
#define stderr Serror #undef clearerr
#define putc Sputc #define FILE IOSTREAM
#define getc Sgetc #define stdin Sinput
#define fputc Sputc #define stdout Soutput
#define fgetc Sgetc #define stderr Serror
#define getw Sgetw
#define putw Sputw #define putc Sputc
#define fread Sfread #define getc Sgetc
#define fwrite Sfwrite #define fputc Sputc
#define ungetc Sungetc #define fgetc Sgetc
#define putchar Sputchar #define getw Sgetw
#define getchar Sgetchar #define putw Sputw
#define feof Sfeof #define fread Sfread
#define ferror Sferror #define fwrite Sfwrite
#define clearerr Sclearerr #define ungetc Sungetc
#define fflush Sflush #define putchar Sputchar
#define fseek Sseek #define getchar Sgetchar
#define ftell Stell #define feof Sfeof
#define fclose Sclose #define ferror Sferror
#define fgets Sfgets #define clearerr Sclearerr
#define gets Sgets #define fflush Sflush
#define fputs Sfputs #define fseek Sseek
#define puts Sputs #define ftell Stell
#define fprintf Sfprintf #define fclose Sclose
#define printf Sprintf #define fgets Sfgets
#define vprintf Svprintf #define gets Sgets
#define vfprintf Svfprintf #define fputs Sfputs
#define sprintf Ssprintf #define puts Sputs
#define vsprintf Svsprintf #define fprintf Sfprintf
#define fopen Sopen_file #define printf Sprintf
#define fdopen Sfdopen #define vprintf Svprintf
#define fileno Sfileno #define vfprintf Svfprintf
#define popen Sopen_pipe #define sprintf Ssprintf
#define vsprintf Svsprintf
#endif /*IOSTREAM_REPLACES_STDIO*/ #define fopen Sopen_file
#define fdopen Sfdopen
/******************************* #define fileno Sfileno
* PROTOTYPES * #define popen Sopen_pipe
*******************************/
#endif /*IOSTREAM_REPLACES_STDIO*/
PL_EXPORT(void) SinitStreams(void);
PL_EXPORT(void) Scleanup(void); /*******************************
PL_EXPORT(void) Sreset(void); * PROTOTYPES *
PL_EXPORT(int) S__fupdatefilepos_getc(IOSTREAM *s, int c); *******************************/
PL_EXPORT(int) S__fcheckpasteeof(IOSTREAM *s, int c);
PL_EXPORT(int) S__fillbuf(IOSTREAM *s); PL_EXPORT(void) SinitStreams(void);
PL_EXPORT(int) Sunit_size(IOSTREAM *s); PL_EXPORT(void) Scleanup(void);
/* byte I/O */ PL_EXPORT(void) Sreset(void);
PL_EXPORT(int) Sputc(int c, IOSTREAM *s); PL_EXPORT(int) S__fupdatefilepos_getc(IOSTREAM *s, int c);
PL_EXPORT(int) Sfgetc(IOSTREAM *s); PL_EXPORT(int) S__fcheckpasteeof(IOSTREAM *s, int c);
PL_EXPORT(int) Sungetc(int c, IOSTREAM *s); PL_EXPORT(int) S__fillbuf(IOSTREAM *s);
/* multibyte I/O */ PL_EXPORT(int) Sunit_size(IOSTREAM *s);
PL_EXPORT(int) Scanrepresent(int c, IOSTREAM *s); /* byte I/O */
PL_EXPORT(int) Sputcode(int c, IOSTREAM *s); PL_EXPORT(int) Sputc(int c, IOSTREAM *s);
PL_EXPORT(int) Sgetcode(IOSTREAM *s); PL_EXPORT(int) Sfgetc(IOSTREAM *s);
PL_EXPORT(int) Sungetcode(int c, IOSTREAM *s); PL_EXPORT(int) Sungetc(int c, IOSTREAM *s);
/* word I/O */ /* multibyte I/O */
PL_EXPORT(int) Sputw(int w, IOSTREAM *s); PL_EXPORT(int) Scanrepresent(int c, IOSTREAM *s);
PL_EXPORT(int) Sgetw(IOSTREAM *s); PL_EXPORT(int) Sputcode(int c, IOSTREAM *s);
PL_EXPORT(size_t) Sfread(void *data, size_t size, size_t elems, PL_EXPORT(int) Sgetcode(IOSTREAM *s);
IOSTREAM *s); PL_EXPORT(int) Sungetcode(int c, IOSTREAM *s);
PL_EXPORT(size_t) Sfwrite(const void *data, size_t size, size_t elems, /* word I/O */
IOSTREAM *s); PL_EXPORT(int) Sputw(int w, IOSTREAM *s);
PL_EXPORT(int) Sfeof(IOSTREAM *s); PL_EXPORT(int) Sgetw(IOSTREAM *s);
PL_EXPORT(int) Sfpasteof(IOSTREAM *s); PL_EXPORT(size_t) Sfread(void *data, size_t size, size_t elems,
PL_EXPORT(int) Sferror(IOSTREAM *s); IOSTREAM *s);
PL_EXPORT(void) Sclearerr(IOSTREAM *s); PL_EXPORT(size_t) Sfwrite(const void *data, size_t size, size_t elems,
PL_EXPORT(void) Sseterr(IOSTREAM *s, int which, const char *message); IOSTREAM *s);
#ifdef _FLI_H_INCLUDED PL_EXPORT(int) Sfeof(IOSTREAM *s);
PL_EXPORT(void) Sset_exception(IOSTREAM *s, term_t ex); PL_EXPORT(int) Sfpasteof(IOSTREAM *s);
#else PL_EXPORT(int) Sferror(IOSTREAM *s);
PL_EXPORT(void) Sset_exception(IOSTREAM *s, intptr_t ex); PL_EXPORT(void) Sclearerr(IOSTREAM *s);
#endif PL_EXPORT(void) Sseterr(IOSTREAM *s, int which, const char *message);
PL_EXPORT(int) Ssetenc(IOSTREAM *s, IOENC new_enc, IOENC *old_enc); PL_EXPORT(void) Sset_exception(IOSTREAM *s, term_t ex);
PL_EXPORT(int) Sflush(IOSTREAM *s); PL_EXPORT(int) Ssetenc(IOSTREAM *s, IOENC new_enc, IOENC *old_enc);
PL_EXPORT(long) Ssize(IOSTREAM *s); PL_EXPORT(int) Sflush(IOSTREAM *s);
PL_EXPORT(int) Sseek(IOSTREAM *s, long pos, int whence); PL_EXPORT(int64_t) Ssize(IOSTREAM *s);
PL_EXPORT(long) Stell(IOSTREAM *s); PL_EXPORT(int) Sseek(IOSTREAM *s, long pos, int whence);
PL_EXPORT(int) Sclose(IOSTREAM *s); PL_EXPORT(long) Stell(IOSTREAM *s);
PL_EXPORT(char *) Sfgets(char *buf, int n, IOSTREAM *s); PL_EXPORT(int) Sclose(IOSTREAM *s);
PL_EXPORT(char *) Sgets(char *buf); PL_EXPORT(char *) Sfgets(char *buf, int n, IOSTREAM *s);
PL_EXPORT(ssize_t) Sread_pending(IOSTREAM *s, PL_EXPORT(char *) Sgets(char *buf);
char *buf, size_t limit, int flags); PL_EXPORT(ssize_t) Sread_pending(IOSTREAM *s,
PL_EXPORT(int) Sfputs(const char *q, IOSTREAM *s); char *buf, size_t limit, int flags);
PL_EXPORT(int) Sputs(const char *q); PL_EXPORT(int) Sfputs(const char *q, IOSTREAM *s);
PL_EXPORT(int) Sfprintf(IOSTREAM *s, const char *fm, ...); PL_EXPORT(int) Sputs(const char *q);
PL_EXPORT(int) Sprintf(const char *fm, ...); PL_EXPORT(int) Sfprintf(IOSTREAM *s, const char *fm, ...);
PL_EXPORT(int) Svprintf(const char *fm, va_list args); PL_EXPORT(int) Sprintf(const char *fm, ...);
PL_EXPORT(int) Svfprintf(IOSTREAM *s, const char *fm, va_list args); PL_EXPORT(int) Svprintf(const char *fm, va_list args);
PL_EXPORT(int) Ssprintf(char *buf, const char *fm, ...); PL_EXPORT(int) Svfprintf(IOSTREAM *s, const char *fm, va_list args);
PL_EXPORT(int) Svsprintf(char *buf, const char *fm, va_list args); PL_EXPORT(int) Ssprintf(char *buf, const char *fm, ...);
PL_EXPORT(int) Svdprintf(const char *fm, va_list args); PL_EXPORT(int) Svsprintf(char *buf, const char *fm, va_list args);
PL_EXPORT(int) Sdprintf(const char *fm, ...); PL_EXPORT(int) Svdprintf(const char *fm, va_list args);
PL_EXPORT(int) Slock(IOSTREAM *s); PL_EXPORT(int) Sdprintf(const char *fm, ...);
PL_EXPORT(int) StryLock(IOSTREAM *s); PL_EXPORT(int) Slock(IOSTREAM *s);
PL_EXPORT(int) Sunlock(IOSTREAM *s); PL_EXPORT(int) StryLock(IOSTREAM *s);
PL_EXPORT(IOSTREAM *) Snew(void *handle, int flags, IOFUNCTIONS *functions); PL_EXPORT(int) Sunlock(IOSTREAM *s);
PL_EXPORT(IOSTREAM *) Sopen_file(const char *path, const char *how); PL_EXPORT(IOSTREAM *) Snew(void *handle, int flags, IOFUNCTIONS *functions);
PL_EXPORT(IOSTREAM *) Sfdopen(int fd, const char *type); PL_EXPORT(IOSTREAM *) Sopen_file(const char *path, const char *how);
PL_EXPORT(int) Sfileno(IOSTREAM *s); PL_EXPORT(IOSTREAM *) Sfdopen(int fd, const char *type);
PL_EXPORT(IOSTREAM *) Sopen_pipe(const char *command, const char *type); PL_EXPORT(int) Sfileno(IOSTREAM *s);
PL_EXPORT(IOSTREAM *) Sopenmem(char **buffer, size_t *sizep, const char *mode); PL_EXPORT(IOSTREAM *) Sopen_pipe(const char *command, const char *type);
PL_EXPORT(IOSTREAM *) Sopen_string(IOSTREAM *s, char *buf, size_t sz, const char *m); PL_EXPORT(IOSTREAM *) Sopenmem(char **buffer, size_t *sizep, const char *mode);
PL_EXPORT(int) Sclosehook(void (*hook)(IOSTREAM *s)); PL_EXPORT(IOSTREAM *) Sopen_string(IOSTREAM *s, char *buf, size_t sz, const char *m);
PL_EXPORT(void) Sfree(void *ptr); PL_EXPORT(int) Sclosehook(void (*hook)(IOSTREAM *s));
PL_EXPORT(int) Sset_filter(IOSTREAM *parent, IOSTREAM *filter); PL_EXPORT(void) Sfree(void *ptr);
PL_EXPORT(void) Ssetbuffer(IOSTREAM *s, char *buf, size_t size); PL_EXPORT(int) Sset_filter(IOSTREAM *parent, IOSTREAM *filter);
PL_EXPORT(void) Ssetbuffer(IOSTREAM *s, char *buf, size_t size);
PL_EXPORT(int64_t) Stell64(IOSTREAM *s);
PL_EXPORT(int) Sseek64(IOSTREAM *s, int64_t pos, int whence); PL_EXPORT(int64_t) Stell64(IOSTREAM *s);
PL_EXPORT(int) Sseek64(IOSTREAM *s, int64_t pos, int whence);
PL_EXPORT(int) ScheckBOM(IOSTREAM *s);
PL_EXPORT(int) SwriteBOM(IOSTREAM *s); #ifdef __WINDOWS__
PL_EXPORT(ssize_t) Sread_user(void *handle, char *buf, size_t size); #if defined(_WINSOCKAPI_) || defined(NEEDS_SWINSOCK)
PL_EXPORT(SOCKET) Swinsock(IOSTREAM *s);
#ifdef __cplusplus #endif
} #endif
#endif
PL_EXPORT(int) ScheckBOM(IOSTREAM *s);
#endif /*_PL_STREAM_H*/ PL_EXPORT(int) SwriteBOM(IOSTREAM *s);
PL_EXPORT(ssize_t) Sread_user(void *handle, char *buf, size_t size);
#ifdef __cplusplus
}
#endif
#endif /*_PL_STREAM_H*/

View File

@ -28,6 +28,7 @@ int
growBuffer(Buffer b, size_t minfree) growBuffer(Buffer b, size_t minfree)
{ size_t osz = b->max - b->base, sz = osz; { size_t osz = b->max - b->base, sz = osz;
size_t top = b->top - b->base; size_t top = b->top - b->base;
char *new;
if ( b->max - b->top >= (int)minfree ) if ( b->max - b->top >= (int)minfree )
return TRUE; return TRUE;
@ -37,20 +38,17 @@ growBuffer(Buffer b, size_t minfree)
while( top + minfree > sz ) while( top + minfree > sz )
sz *= 2; sz *= 2;
if ( b->base != b->static_buffer ) if ( b->base == b->static_buffer )
{ b->base = realloc(b->base, sz); { if ( !(new = malloc(sz)) )
if ( !b->base )
return FALSE;
} else /* from static buffer */
{ char *new;
if ( !(new = malloc(sz)) )
return FALSE; return FALSE;
memcpy(new, b->static_buffer, osz); memcpy(new, b->static_buffer, osz);
b->base = new; } else
{ if ( !(new = realloc(b->base, sz)) )
return FALSE;
} }
b->base = new;
b->top = b->base + top; b->top = b->base + top;
b->max = b->base + sz; b->max = b->base + sz;
@ -62,7 +60,7 @@ growBuffer(Buffer b, size_t minfree)
* BUFFER RING * * BUFFER RING *
*******************************/ *******************************/
#define discardable_buffer (LD->fli._discardable_buffer) #define discardable_buffer (LD->fli._discardable_buffer)
#define buffer_ring (LD->fli._buffer_ring) #define buffer_ring (LD->fli._buffer_ring)
#define current_buffer_id (LD->fli._current_buffer_id) #define current_buffer_id (LD->fli._current_buffer_id)

View File

@ -49,7 +49,7 @@ int growBuffer(Buffer b, size_t minfree);
{ if ( !growBuffer((Buffer)b, sizeof(type)) ) \ { if ( !growBuffer((Buffer)b, sizeof(type)) ) \
outOfCore(); \ outOfCore(); \
} \ } \
*((type *)(b)->top) = obj; \ *((type *)(b)->top) = obj; \
(b)->top += sizeof(type); \ (b)->top += sizeof(type); \
} while(0) } while(0)
@ -68,6 +68,24 @@ int growBuffer(Buffer b, size_t minfree);
(b)->top = (char *)_d; \ (b)->top = (char *)_d; \
} while(0) } while(0)
#define allocFromBuffer(b, bytes) \
f__allocFromBuffer((Buffer)(b), (bytes))
static inline void*
f__allocFromBuffer(Buffer b, size_t bytes)
{ if ( b->top + bytes <= b->max ||
growBuffer(b, bytes) )
{ void *top = b->top;
b->top += bytes;
return top;
}
return NULL;
}
#define baseBuffer(b, type) ((type *) (b)->base) #define baseBuffer(b, type) ((type *) (b)->base)
#define topBuffer(b, type) ((type *) (b)->top) #define topBuffer(b, type) ((type *) (b)->top)
#define inBuffer(b, addr) ((char *) (addr) >= (b)->base && \ #define inBuffer(b, addr) ((char *) (addr) >= (b)->base && \
@ -83,6 +101,8 @@ int growBuffer(Buffer b, size_t minfree);
sizeof((b)->static_buffer)) sizeof((b)->static_buffer))
#define emptyBuffer(b) ((b)->top = (b)->base) #define emptyBuffer(b) ((b)->top = (b)->base)
#define isEmptyBuffer(b) ((b)->top == (b)->base) #define isEmptyBuffer(b) ((b)->top == (b)->base)
#define popBuffer(b,type) \
((b)->top -= sizeof(type), *(type*)(b)->top)
#define discardBuffer(b) \ #define discardBuffer(b) \
do \ do \
@ -99,6 +119,6 @@ int growBuffer(Buffer b, size_t minfree);
COMMON(Buffer) findBuffer(int flags); COMMON(Buffer) findBuffer(int flags);
COMMON(int) unfindBuffer(int flags); COMMON(int) unfindBuffer(int flags);
COMMON(char *) buffer_string(const char *s, int flags); COMMON(char *) buffer_string(const char *s, int flags);
#endif /*BUFFER_H_INCLUDED*/ #endif /*BUFFER_H_INCLUDED*/

View File

@ -89,15 +89,49 @@ get_trace_store(void)
} }
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
next_btrace_id() produces the id for the next backtrace and sets
bt->current to the subsequent id. Although bt is thread-local, it may be
called from a signal handler or (Windows) exception. We cannot use
locking because the mutex functions are not async signal safe. So, we
use atomic instructions if possible. Otherwise, we ensure consistency of
the datastructures, but we may overwrite an older stack trace.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static int
next_btrace_id(btrace *bt)
{ int current;
#ifdef COMPARE_AND_SWAP
int next;
do
{ current = bt->current;
next = current+1;
if ( next == SAVE_TRACES )
next = 0;
} while ( !COMPARE_AND_SWAP(&bt->current, current, next) );
#else
current = bt->current++ % SAVE_TRACES;
if ( bt->current >= SAVE_TRACES )
bt->current %= SAVE_TRACES;
#endif
return current;
}
void void
save_backtrace(const char *why) save_backtrace(const char *why)
{ btrace *bt = get_trace_store(); { btrace *bt = get_trace_store();
if ( bt ) if ( bt )
{ btrace_stack *s = &bt->dumps[bt->current]; { btrace_stack *s;
unw_cursor_t cursor; unw_context_t uc; unw_cursor_t cursor; unw_context_t uc;
int depth; int depth;
int current = next_btrace_id(bt);
s = &bt->dumps[current];
unw_getcontext(&uc); unw_getcontext(&uc);
unw_init_local(&cursor, &uc); unw_init_local(&cursor, &uc);
for(depth=0; unw_step(&cursor) > 0 && depth < MAX_DEPTH; depth++) for(depth=0; unw_step(&cursor) > 0 && depth < MAX_DEPTH; depth++)
@ -107,9 +141,6 @@ save_backtrace(const char *why)
} }
s->name = why; s->name = why;
s->depth = depth; s->depth = depth;
if ( ++bt->current == SAVE_TRACES )
bt->current = 0;
} }
} }
@ -228,6 +259,33 @@ get_trace_store(void)
} }
/* Copy of same function above. Relies on a different btrace structure.
Ideally, this should be shared :-(
*/
static int
next_btrace_id(btrace *bt)
{ int current;
#ifdef COMPARE_AND_SWAP
int next;
do
{ current = bt->current;
next = current+1;
if ( next == SAVE_TRACES )
next = 0;
} while ( !COMPARE_AND_SWAP(&bt->current, current, next) );
#else
current = bt->current++ % SAVE_TRACES;
if ( bt->current >= SAVE_TRACES )
bt->current %= SAVE_TRACES;
#endif
return current;
}
void void
save_backtrace(const char *why) save_backtrace(const char *why)
{ btrace *bt = get_trace_store(); { btrace *bt = get_trace_store();
@ -235,15 +293,14 @@ save_backtrace(const char *why)
if ( bt ) if ( bt )
{ void *array[100]; { void *array[100];
size_t frames; size_t frames;
int current = next_btrace_id(bt);
frames = backtrace(array, sizeof(array)/sizeof(void *)); frames = backtrace(array, sizeof(array)/sizeof(void *));
bt->sizes[bt->current] = frames; bt->sizes[current] = frames;
if ( bt->symbols[bt->current] ) if ( bt->symbols[current] )
free(bt->symbols[bt->current]); free(bt->symbols[current]);
bt->symbols[bt->current] = backtrace_symbols(array, frames); bt->symbols[current] = backtrace_symbols(array, frames);
bt->why[bt->current] = why; bt->why[current] = why;
if ( ++bt->current == SAVE_TRACES )
bt->current = 0;
} }
} }
@ -358,6 +415,9 @@ initBackTrace(void)
*/ */
#define MAX_MODULE_NAME_LENGTH 64 #define MAX_MODULE_NAME_LENGTH 64
#define LOCK() PL_LOCK(L_CSTACK)
#define UNLOCK() PL_UNLOCK(L_CSTACK)
typedef struct typedef struct
{ char name[MAX_FUNCTION_NAME_LENGTH]; /* function called */ { char name[MAX_FUNCTION_NAME_LENGTH]; /* function called */
DWORD64 offset; /* offset in function */ DWORD64 offset; /* offset in function */
@ -397,6 +457,32 @@ get_trace_store(void)
return LD->btrace_store; return LD->btrace_store;
} }
/* Copy of same function above. Relies on a different btrace structure.
Ideally, this should be shared :-(
*/
static int
next_btrace_id(btrace *bt)
{ int current;
#ifdef COMPARE_AND_SWAP
int next;
do
{ current = bt->current;
next = current+1;
if ( next == SAVE_TRACES )
next = 0;
} while ( !COMPARE_AND_SWAP(&bt->current, current, next) );
#else
current = bt->current++ % SAVE_TRACES;
if ( bt->current >= SAVE_TRACES )
bt->current %= SAVE_TRACES;
#endif
return current;
}
int backtrace(btrace_stack* trace, PEXCEPTION_POINTERS pExceptionInfo) int backtrace(btrace_stack* trace, PEXCEPTION_POINTERS pExceptionInfo)
{ STACKFRAME64 frame; { STACKFRAME64 frame;
CONTEXT context; CONTEXT context;
@ -406,7 +492,6 @@ int backtrace(btrace_stack* trace, PEXCEPTION_POINTERS pExceptionInfo)
char symbolScratch[sizeof(SYMBOL_INFO) + MAX_SYMBOL_LEN]; char symbolScratch[sizeof(SYMBOL_INFO) + MAX_SYMBOL_LEN];
SYMBOL_INFO* symbol = (SYMBOL_INFO*)&symbolScratch; SYMBOL_INFO* symbol = (SYMBOL_INFO*)&symbolScratch;
IMAGEHLP_MODULE64 moduleInfo; IMAGEHLP_MODULE64 moduleInfo;
EXCEPTION_POINTERS *pExp = NULL;
DWORD64 offset; DWORD64 offset;
DWORD imageType; DWORD imageType;
int skip = 0; int skip = 0;
@ -529,11 +614,12 @@ void
win_save_backtrace(const char *why, PEXCEPTION_POINTERS pExceptionInfo) win_save_backtrace(const char *why, PEXCEPTION_POINTERS pExceptionInfo)
{ btrace *bt = get_trace_store(); { btrace *bt = get_trace_store();
if ( bt ) if ( bt )
{ btrace_stack *s = &bt->dumps[bt->current]; { int current = next_btrace_id(bt);
btrace_stack *s = &bt->dumps[current];
LOCK();
s->depth = backtrace(s, pExceptionInfo); s->depth = backtrace(s, pExceptionInfo);
UNLOCK();
s->name = why; s->name = why;
if ( ++bt->current == SAVE_TRACES )
bt->current = 0;
} }
} }

View File

@ -471,7 +471,7 @@ init_tout(PL_chars_t *t, size_t len)
{ t->text.t = t->buf; { t->text.t = t->buf;
t->storage = PL_CHARS_LOCAL; t->storage = PL_CHARS_LOCAL;
} else } else
{ t->text.t = PL_malloc(len+1); { t->text.t = PL_malloc(len);
t->storage = PL_CHARS_MALLOC; t->storage = PL_CHARS_MALLOC;
} }
succeed; succeed;
@ -480,7 +480,7 @@ init_tout(PL_chars_t *t, size_t len)
{ t->text.w = (pl_wchar_t*)t->buf; { t->text.w = (pl_wchar_t*)t->buf;
t->storage = PL_CHARS_LOCAL; t->storage = PL_CHARS_LOCAL;
} else } else
{ t->text.w = PL_malloc((len+1)*sizeof(pl_wchar_t)); { t->text.w = PL_malloc(len*sizeof(pl_wchar_t));
t->storage = PL_CHARS_MALLOC; t->storage = PL_CHARS_MALLOC;
} }
succeed; succeed;

File diff suppressed because it is too large Load Diff

81
os/pl-file.h Normal file
View File

@ -0,0 +1,81 @@
/* $Id$
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: J.Wielemaker@uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2011, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PL_FILE_H_INCLUDED
#define PL_FILE_H_INCLUDED
typedef enum
{ ST_FALSE = -1, /* Do not check stream types */
ST_LOOSE = 0, /* Default: accept latin-1 for binary */
ST_TRUE = 1 /* Strict checking */
} st_check;
/* pl-file.c */
COMMON(void) initIO(void);
COMMON(void) dieIO(void);
COMMON(void) closeFiles(int all);
COMMON(int) openFileDescriptors(unsigned char *buf, int size);
COMMON(void) protocol(const char *s, size_t n);
COMMON(int) getTextInputStream__LD(term_t t, IOSTREAM **s ARG_LD);
COMMON(int) getBinaryInputStream__LD(term_t t, IOSTREAM **s ARG_LD);
COMMON(int) getTextOutputStream__LD(term_t t, IOSTREAM **s ARG_LD);
COMMON(int) getBinaryOutputStream__LD(term_t t, IOSTREAM **s ARG_LD);
COMMON(int) reportStreamError(IOSTREAM *s);
COMMON(int) streamStatus(IOSTREAM *s);
COMMON(atom_t) fileNameStream(IOSTREAM *s);
COMMON(int) getSingleChar(IOSTREAM *s, int signals);
COMMON(int) readLine(IOSTREAM *in, IOSTREAM *out, char *buffer);
COMMON(int) LockStream(void);
COMMON(int) UnlockStream(void);
COMMON(IOSTREAM *) PL_current_input(void);
COMMON(IOSTREAM *) PL_current_output(void);
COMMON(int) pl_see(term_t f);
COMMON(int) pl_seen(void);
COMMON(int) seeString(const char *s);
COMMON(int) seeingString(void);
COMMON(int) seenString(void);
COMMON(int) tellString(char **s, size_t *size, IOENC enc);
COMMON(int) toldString(void);
COMMON(void) prompt1(atom_t prompt);
COMMON(atom_t) PrologPrompt(void);
COMMON(int) streamNo(term_t spec, int mode);
COMMON(void) release_stream_handle(term_t spec);
COMMON(int) unifyTime(term_t t, time_t time);
#ifdef __WINDOWS__
COMMON(word) pl_make_fat_filemap(term_t dir);
#endif
COMMON(int) PL_unify_stream_or_alias(term_t t, IOSTREAM *s);
COMMON(void) pushOutputContext(void);
COMMON(void) popOutputContext(void);
COMMON(IOENC) atom_to_encoding(atom_t a);
COMMON(atom_t) encoding_to_atom(IOENC enc);
COMMON(int) setupOutputRedirect(term_t to,
redir_context *ctx,
int redir);
COMMON(int) closeOutputRedirect(redir_context *ctx);
COMMON(void) discardOutputRedirect(redir_context *ctx);
COMMON(int) push_input_context(atom_t type);
COMMON(int) pop_input_context(void);
#endif /*PL_FILE_H_INCLUDED*/

View File

@ -3,9 +3,10 @@
Part of SWI-Prolog Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: J.Wielemaker@uva.nl E-mail: J.Wielemaker@cs.vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2008, University of Amsterdam Copyright (C): 1985-2011, University of Amsterdam
VU University Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,7 +20,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "pl-incl.h" #include "pl-incl.h"
@ -44,26 +45,89 @@
General file operations and binding to Prolog General file operations and binding to Prolog
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef __WINDOWS__
static void
set_posix_error(int win_error)
{ int error = 0;
switch(win_error)
{ case ERROR_ACCESS_DENIED: error = EACCES; break;
case ERROR_FILE_NOT_FOUND: error = ENOENT; break;
case ERROR_SHARING_VIOLATION: error = EAGAIN; break;
case ERROR_ALREADY_EXISTS: error = EEXIST; break;
}
errno = error;
}
#endif /*__WINDOWS__*/
/******************************* /*******************************
* OS STUFF * * OS STUFF *
*******************************/ *******************************/
/** time_t LastModifiedFile(const char *file) /** int LastModifiedFile(const char *file, double *t)
Return the last modification time of file as a POSIX timestamp. Returns Return the last modification time of file as a POSIX timestamp. Returns
(time_t)-1 on failure. (time_t)-1 on failure.
Contains a 64-bit value representing the number of 100-nanosecond
intervals since January 1, 1601 (UTC).
*/ */
int
LastModifiedFile(const char *name, double *tp)
{
#ifdef __WINDOWS__
HANDLE hFile;
wchar_t wfile[MAXPATHLEN];
time_t #define nano * 0.000000001
LastModifiedFile(const char *file) #define ntick 100.0
{ char tmp[MAXPATHLEN]; #define SEC_TO_UNIX_EPOCH 11644473600.0
if ( !_xos_os_filenameW(name, wfile, MAXPATHLEN) )
return FALSE;
if ( (hFile=CreateFileW(wfile,
0,
FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL)) != INVALID_HANDLE_VALUE )
{ FILETIME wt;
int rc;
rc = GetFileTime(hFile, NULL, NULL, &wt);
CloseHandle(hFile);
if ( rc )
{ double t;
t = (double)wt.dwHighDateTime * (4294967296.0 * ntick nano);
t += (double)wt.dwLowDateTime * (ntick nano);
t -= SEC_TO_UNIX_EPOCH;
*tp = t;
return TRUE;
}
}
set_posix_error(GetLastError());
return FALSE;
#else
char tmp[MAXPATHLEN];
statstruct buf; statstruct buf;
if ( statfunc(OsPath(file, tmp), &buf) < 0 ) if ( statfunc(OsPath(name, tmp), &buf) < 0 )
return (time_t)-1; return FALSE;
return buf.st_mtime; *tp = (double)buf.st_mtime;
return TRUE;
#endif
} }
@ -349,13 +413,7 @@ MarkExecutable(const char *name)
int int
unifyTime(term_t t, time_t time) unifyTime(term_t t, time_t time)
{ { return PL_unify_time(t, time);
#if __YAP_PROLOG__
/* maintain compatibility with old Prolog systems, and avoid losing precision unnecessarily */
return PL_unify_int64(t, (int64_t)time);
#else
return PL_unify_float(t, (double)time);
#endif
} }
@ -433,9 +491,12 @@ get_file_name(term_t n, char **namep, char *tmp, int flags)
return PL_error(NULL, 0, "file name contains a 0-code", return PL_error(NULL, 0, "file name contains a 0-code",
ERR_DOMAIN, ATOM_file_name, n); ERR_DOMAIN, ATOM_file_name, n);
} }
if ( len+1 >= MAXPATHLEN )
return PL_error(NULL, 0, NULL, ERR_REPRESENTATION,
ATOM_max_path_length);
if ( truePrologFlag(PLFLAG_FILEVARS) ) if ( truePrologFlag(PLFLAG_FILEVARS) )
{ if ( !(name = ExpandOneFile(name, tmp)) ) { if ( !(name = expandVars(name, tmp, MAXPATHLEN)) )
return FALSE; return FALSE;
} }
@ -529,13 +590,13 @@ PRED_IMPL("time_file", 2, time_file, 0)
{ char *fn; { char *fn;
if ( PL_get_file_name(A1, &fn, 0) ) if ( PL_get_file_name(A1, &fn, 0) )
{ time_t time; { double time;
if ( (time = LastModifiedFile(fn)) == (time_t)-1 ) if ( LastModifiedFile(fn, &time) )
return PL_error(NULL, 0, NULL, ERR_FILE_OPERATION, return PL_unify_float(A2, time);
ATOM_time, ATOM_file, A1);
return unifyTime(A2, time); return PL_error(NULL, 0, NULL, ERR_FILE_OPERATION,
ATOM_time, ATOM_file, A1);
} }
return FALSE; return FALSE;
@ -544,7 +605,8 @@ PRED_IMPL("time_file", 2, time_file, 0)
static static
PRED_IMPL("size_file", 2, size_file, 0) PRED_IMPL("size_file", 2, size_file, 0)
{ char *n; { PRED_LD
char *n;
if ( PL_get_file_name(A1, &n, 0) ) if ( PL_get_file_name(A1, &n, 0) )
{ int64_t size; { int64_t size;
@ -680,7 +742,7 @@ static
PRED_IMPL("file_base_name", 2, file_base_name, 0) PRED_IMPL("file_base_name", 2, file_base_name, 0)
{ char *n; { char *n;
if ( !PL_get_chars_ex(A1, &n, CVT_ALL|REP_FN) ) if ( !PL_get_chars(A1, &n, CVT_ALL|REP_FN|CVT_EXCEPTION) )
return FALSE; return FALSE;
return PL_unify_chars(A2, PL_ATOM|REP_FN, -1, BaseName(n)); return PL_unify_chars(A2, PL_ATOM|REP_FN, -1, BaseName(n));
@ -692,7 +754,7 @@ PRED_IMPL("file_directory_name", 2, file_directory_name, 0)
{ char *n; { char *n;
char tmp[MAXPATHLEN]; char tmp[MAXPATHLEN];
if ( !PL_get_chars_ex(A1, &n, CVT_ALL|REP_FN) ) if ( !PL_get_chars(A1, &n, CVT_ALL|REP_FN|CVT_EXCEPTION) )
return FALSE; return FALSE;
return PL_unify_chars(A2, PL_ATOM|REP_FN, -1, DirName(n, tmp)); return PL_unify_chars(A2, PL_ATOM|REP_FN, -1, DirName(n, tmp));
@ -868,12 +930,13 @@ PRED_IMPL("$absolute_file_name", 2, absolute_file_name, 0)
static static
PRED_IMPL("working_directory", 2, working_directory, 0) PRED_IMPL("working_directory", 2, working_directory, 0)
{ PRED_LD { PRED_LD
char buf[MAXPATHLEN];
const char *wd; const char *wd;
term_t old = A1; term_t old = A1;
term_t new = A2; term_t new = A2;
if ( !(wd = PL_cwd()) ) if ( !(wd = PL_cwd(buf, sizeof(buf))) )
return FALSE; return FALSE;
if ( PL_unify_chars(old, PL_ATOM|REP_FN, -1, wd) ) if ( PL_unify_chars(old, PL_ATOM|REP_FN, -1, wd) )
@ -966,8 +1029,8 @@ PRED_IMPL("file_name_extension", 3, file_name_extension, 0)
PL_fail; PL_fail;
} }
if ( PL_get_chars_ex(base, &b, CVT_ALL|BUF_RING|REP_FN) && if ( PL_get_chars(base, &b, CVT_ALL|BUF_RING|REP_FN|CVT_EXCEPTION) &&
PL_get_chars_ex(ext, &e, CVT_ALL|REP_FN) ) PL_get_chars(ext, &e, CVT_ALL|REP_FN|CVT_EXCEPTION) )
{ char *s; { char *s;
if ( e[0] == '.' ) /* +Base, +Extension, -full */ if ( e[0] == '.' ) /* +Base, +Extension, -full */
@ -989,20 +1052,19 @@ PRED_IMPL("file_name_extension", 3, file_name_extension, 0)
static static
PRED_IMPL("prolog_to_os_filename", 2, prolog_to_os_filename, 0) PRED_IMPL("prolog_to_os_filename", 2, prolog_to_os_filename, 0)
{ { PRED_LD
term_t pl = A1; term_t pl = A1;
term_t os = A2; term_t os = A2;
#ifdef O_XOS #ifdef O_XOS
PRED_LD
wchar_t *wn; wchar_t *wn;
if ( !PL_is_variable(pl) ) if ( !PL_is_variable(pl) )
{ char *n; { char *n;
wchar_t buf[MAXPATHLEN]; wchar_t buf[MAXPATHLEN];
if ( PL_get_chars_ex(pl, &n, CVT_ALL|REP_UTF8) ) if ( PL_get_chars(pl, &n, CVT_ALL|REP_UTF8|CVT_EXCEPTION) )
{ if ( !_xos_os_filenameW(n, buf, MAXPATHLEN) ) { if ( !_xos_os_filenameW(n, buf, MAXPATHLEN) )
return name_too_long(); return name_too_long();

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef PL_FILES_H_INCLUDED #ifndef PL_FILES_H_INCLUDED
@ -31,11 +31,11 @@
#define ACCESS_WRITE 4 #define ACCESS_WRITE 4
COMMON(void) initFiles(void); COMMON(void) initFiles(void);
COMMON(time_t) LastModifiedFile(const char *f); COMMON(int) LastModifiedFile(const char *f, double *t);
COMMON(int) RemoveFile(const char *path); COMMON(int) RemoveFile(const char *path);
COMMON(int) AccessFile(const char *path, int mode); COMMON(int) AccessFile(const char *path, int mode);
COMMON(char *) DeRefLink(const char *link, char *buf); COMMON(char *) DeRefLink(const char *link, char *buf);
COMMON(int) ExistsFile(const char *path); COMMON(int) ExistsFile(const char *path);
COMMON(int) ExistsDirectory(const char *path); COMMON(int) ExistsDirectory(const char *path);
#endif /*PL_FILES_H_INCLUDED*/ #endif /*PL_FILES_H_INCLUDED*/

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -53,9 +53,9 @@ typedef struct
struct rubber rub[MAXRUBBER]; struct rubber rub[MAXRUBBER];
} format_state; } format_state;
#define BUFSIZE 1024 #define BUFSIZE 1024
#define DEFAULT (-1) #define DEFAULT (-1)
#define SHIFT { argc--; argv++; } #define SHIFT { argc--; argv++; }
#define NEED_ARG { if ( argc <= 0 ) \ #define NEED_ARG { if ( argc <= 0 ) \
{ FMT_ERROR("not enough arguments"); \ { FMT_ERROR("not enough arguments"); \
} \ } \
@ -189,7 +189,8 @@ outtext(format_state *state, PL_chars_t *txt)
#define format_predicates (GD->format.predicates) #define format_predicates (GD->format.predicates)
static int update_column(int, Char); static int update_column(int, Char);
static bool do_format(IOSTREAM *fd, PL_chars_t *fmt, int ac, term_t av); static bool do_format(IOSTREAM *fd, PL_chars_t *fmt,
int ac, term_t av, Module m);
static void distribute_rubber(struct rubber *, int, int); static void distribute_rubber(struct rubber *, int, int);
static int emit_rubber(format_state *state); static int emit_rubber(format_state *state);
@ -272,7 +273,7 @@ pl_current_format_predicate(term_t chr, term_t descr, control_t h)
static word static word
format_impl(IOSTREAM *out, term_t format, term_t Args) format_impl(IOSTREAM *out, term_t format, term_t Args, Module m)
{ GET_LD { GET_LD
term_t argv; term_t argv;
int argc = 0; int argc = 0;
@ -307,7 +308,7 @@ format_impl(IOSTREAM *out, term_t format, term_t Args)
break; break;
} }
rval = do_format(out, &fmt, argc, argv); rval = do_format(out, &fmt, argc, argv, m);
PL_free_text(&fmt); PL_free_text(&fmt);
if ( !endCritical ) if ( !endCritical )
return FALSE; return FALSE;
@ -318,31 +319,20 @@ format_impl(IOSTREAM *out, term_t format, term_t Args)
word word
pl_format3(term_t out, term_t format, term_t args) pl_format3(term_t out, term_t format, term_t args)
{ redir_context ctx; { GET_LD
redir_context ctx;
word rc; word rc;
#if __YAP_PROLOG__ Module m = NULL;
/* term_t list = PL_new_term_ref();
YAP allows the last argument to format to be of the form
module:[]
*/
YAP_Term mod;
#endif
if ( (rc=setupOutputRedirect(out, &ctx, FALSE)) ) { if ( !PL_strip_module(args, &m, list) )
#if __YAP_PROLOG__ return FALSE;
/* module processing */
{ if ( (rc=setupOutputRedirect(out, &ctx, FALSE)) )
args = Yap_fetch_module_for_format(args, &mod); { if ( (rc = format_impl(ctx.stream, format, list, m)) )
} rc = closeOutputRedirect(&ctx);
#endif else
{ if ( (rc = format_impl(ctx.stream, format, args)) )
rc = closeOutputRedirect(&ctx);
else
discardOutputRedirect(&ctx); discardOutputRedirect(&ctx);
}
#if __YAP_PROLOG__
YAP_SetCurrentModule(mod);
#endif
} }
return rc; return rc;
@ -374,7 +364,7 @@ get_chr_from_text(const PL_chars_t *t, int index)
********************************/ ********************************/
static bool static bool
do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv) do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv, Module m)
{ GET_LD { GET_LD
format_state state; /* complete state */ format_state state; /* complete state */
int tab_stop = 0; /* padded tab stop */ int tab_stop = 0; /* padded tab stop */
@ -443,7 +433,7 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
char buf[BUFSIZE]; char buf[BUFSIZE];
char *str = buf; char *str = buf;
size_t bufsize = BUFSIZE; size_t bufsize = BUFSIZE;
unsigned int i; int i;
PL_predicate_info(proc, NULL, &arity, NULL); PL_predicate_info(proc, NULL, &arity, NULL);
av = PL_new_term_refs(arity); av = PL_new_term_refs(arity);
@ -481,7 +471,9 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
if ( !PL_get_text(argv, &txt, CVT_ATOMIC) ) if ( !PL_get_text(argv, &txt, CVT_ATOMIC) )
FMT_ARG("a", argv); FMT_ARG("a", argv);
SHIFT; SHIFT;
outtext(&state, &txt); rc = outtext(&state, &txt);
if ( !rc )
goto out;
here++; here++;
break; break;
} }
@ -494,7 +486,9 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
SHIFT; SHIFT;
while(times-- > 0) while(times-- > 0)
{ outchr(&state, chr); { rc = outchr(&state, chr);
if ( !rc )
goto out;
} }
} else } else
FMT_ARG("c", argv); FMT_ARG("c", argv);
@ -508,7 +502,7 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
case 'G': /* shortest of 'f' and 'E' */ case 'G': /* shortest of 'f' and 'E' */
{ number n; { number n;
union { union {
tmp_buffer b; tmp_buffer b;
buffer b1; buffer b1;
} u; } u;
@ -525,8 +519,10 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
initBuffer(&u.b); initBuffer(&u.b);
formatFloat(c, arg, &n, &u.b1); formatFloat(c, arg, &n, &u.b1);
clearNumber(&n); clearNumber(&n);
outstring0(&state, baseBuffer(&u.b, char)); rc = outstring0(&state, baseBuffer(&u.b, char));
discardBuffer(&u.b); discardBuffer(&u.b);
if ( !rc )
goto out;
here++; here++;
break; break;
} }
@ -564,8 +560,10 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
formatNumber(FALSE, 0, arg, c == 'r', &i, (Buffer)&b); formatNumber(FALSE, 0, arg, c == 'r', &i, (Buffer)&b);
} }
clearNumber(&i); clearNumber(&i);
outstring0(&state, baseBuffer(&b, char)); rc = outstring0(&state, baseBuffer(&b, char));
discardBuffer(&b); discardBuffer(&b);
if ( !rc )
goto out;
here++; here++;
break; break;
} }
@ -576,8 +574,10 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
if ( !PL_get_text(argv, &txt, CVT_LIST|CVT_STRING) && if ( !PL_get_text(argv, &txt, CVT_LIST|CVT_STRING) &&
!PL_get_text(argv, &txt, CVT_ATOM) ) /* SICStus compat */ !PL_get_text(argv, &txt, CVT_ATOM) ) /* SICStus compat */
FMT_ARG("s", argv); FMT_ARG("s", argv);
outtext(&state, &txt); rc = outtext(&state, &txt);
SHIFT; SHIFT;
if ( !rc )
goto out;
here++; here++;
break; break;
} }
@ -610,8 +610,10 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
str = buf; str = buf;
tellString(&str, &bufsize, ENC_UTF8); tellString(&str, &bufsize, ENC_UTF8);
(*f)(argv); rc = (*f)(argv);
toldString(); toldString();
if ( !rc )
goto out;
oututf8(&state, str, bufsize); oututf8(&state, str, bufsize);
if ( str != buf ) if ( str != buf )
free(str); free(str);
@ -632,8 +634,10 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
str = buf; str = buf;
tellString(&str, &bufsize, ENC_UTF8); tellString(&str, &bufsize, ENC_UTF8);
(*f)(argv); rc = (*f)(argv);
toldString(); toldString();
if ( !rc )
goto out;
oututf8(&state, str, bufsize); oututf8(&state, str, bufsize);
if ( str != buf ) if ( str != buf )
free(str); free(str);
@ -704,7 +708,7 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
{ FMT_ERROR("not enough arguments"); { FMT_ERROR("not enough arguments");
} }
tellString(&str, &bufsize, ENC_UTF8); tellString(&str, &bufsize, ENC_UTF8);
rval = callProlog(NULL, argv, PL_Q_CATCH_EXCEPTION, &ex); rval = callProlog(m, argv, PL_Q_CATCH_EXCEPTION, &ex);
toldString(); toldString();
oututf8(&state, str, bufsize); oututf8(&state, str, bufsize);
if ( str != buf ) if ( str != buf )
@ -724,7 +728,9 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
break; break;
} }
case '~': /* ~ */ case '~': /* ~ */
{ outchr(&state, '~'); { rc = outchr(&state, '~');
if ( !rc )
goto out;
here++; here++;
break; break;
} }
@ -735,7 +741,10 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
if ( c == 'N' && state.column == 0 ) if ( c == 'N' && state.column == 0 )
arg--; arg--;
while( arg-- > 0 ) while( arg-- > 0 )
outchr(&state, '\n'); { rc = outchr(&state, '\n');
if ( !rc )
goto out;
}
here++; here++;
break; break;
} }
@ -790,7 +799,9 @@ do_format(IOSTREAM *fd, PL_chars_t *fmt, int argc, term_t argv)
break; /* the '~' switch */ break; /* the '~' switch */
} }
default: default:
{ outchr(&state, c); { rc = outchr(&state, c);
if ( !rc )
goto out;
here++; here++;
break; break;
} }
@ -1032,7 +1043,8 @@ formatFloat(int how, int arg, Number f, Buffer out)
while(written >= size) while(written >= size)
{ size = written+1; { size = written+1;
growBuffer(out, size); /* reserve for -.e<null> */ if ( !growBuffer(out, size) ) /* reserve for -.e<null> */
outOfCore();
written = gmp_snprintf(baseBuffer(out, char), size, tmp, mpf); written = gmp_snprintf(baseBuffer(out, char), size, tmp, mpf);
} }
mpf_clear(mpf); mpf_clear(mpf);
@ -1053,7 +1065,8 @@ formatFloat(int how, int arg, Number f, Buffer out)
while(written >= size) while(written >= size)
{ size = written+1; { size = written+1;
growBuffer(out, size); if ( !growBuffer(out, size) )
outOfCore();
written = snprintf(baseBuffer(out, char), size, tmp, f->value.f); written = snprintf(baseBuffer(out, char), size, tmp, f->value.f);
} }
out->top = out->base + written; out->top = out->base + written;

View File

@ -3,9 +3,10 @@
Part of SWI-Prolog Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl E-mail: J.Wielemaker@cs.vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam Copyright (C): 1985-2011, University of Amsterdam
VU University Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,7 +20,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "pl-incl.h" #include "pl-incl.h"
@ -29,9 +30,9 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifdef __WATCOMC__ #ifdef O_XOS
#include <direct.h> # include "windows/dirent.h"
#else /*__WATCOMC__*/ #else
#if HAVE_DIRENT_H #if HAVE_DIRENT_H
# include <dirent.h> # include <dirent.h>
#else #else
@ -46,7 +47,7 @@
# include <ndir.h> # include <ndir.h>
# endif # endif
#endif #endif
#endif /*__WATCOMC__*/ #endif /*O_XOS*/
#ifdef HAVE_SYS_STAT_H #ifdef HAVE_SYS_STAT_H
#include <sys/stat.h> #include <sys/stat.h>
@ -326,8 +327,8 @@ PRED_IMPL("wildcard_match", 2, wildcard_match, 0)
{ char *p, *s; { char *p, *s;
compiled_pattern buf; compiled_pattern buf;
if ( !PL_get_chars_ex(A1, &p, CVT_ALL) || if ( !PL_get_chars(A1, &p, CVT_ALL|CVT_EXCEPTION) ||
!PL_get_chars_ex(A2, &s, CVT_ALL) ) !PL_get_chars(A2, &s, CVT_ALL|CVT_EXCEPTION) )
fail; fail;
if ( compilePattern(p, &buf) ) if ( compilePattern(p, &buf) )
@ -423,6 +424,7 @@ expand(const char *pattern, GlobInfo info)
compiled_pattern cbuf; compiled_pattern cbuf;
char prefix[MAXPATHLEN]; /* before first pattern */ char prefix[MAXPATHLEN]; /* before first pattern */
char patbuf[MAXPATHLEN]; /* pattern buffer */ char patbuf[MAXPATHLEN]; /* pattern buffer */
size_t prefix_len;
int end, dot; int end, dot;
initBuffer(&info->files); initBuffer(&info->files);
@ -441,20 +443,25 @@ expand(const char *pattern, GlobInfo info)
switch( (c=*s++) ) switch( (c=*s++) )
{ case EOS: { case EOS:
if ( s > pat ) /* something left and expanded */ if ( s > pat ) /* something left and expanded */
{ un_escape(prefix, pat, s); { size_t prefix_len;
un_escape(prefix, pat, s);
prefix_len = strlen(prefix);
end = info->end; end = info->end;
for( ; info->start < end; info->start++ ) for( ; info->start < end; info->start++ )
{ char path[MAXPATHLEN]; { char path[MAXPATHLEN];
size_t plen; const char *entry = expand_entry(info, info->start);
size_t plen = strlen(entry);
strcpy(path, expand_entry(info, info->start)); if ( plen+prefix_len+2 <= MAXPATHLEN )
plen = strlen(path); { strcpy(path, entry);
if ( prefix[0] && plen > 0 && path[plen-1] != '/' ) if ( prefix[0] && plen > 0 && path[plen-1] != '/' )
path[plen++] = '/'; path[plen++] = '/';
strcpy(&path[plen], prefix); strcpy(&path[plen], prefix);
if ( end == 1 || AccessFile(path, ACCESS_EXIST) ) if ( end == 1 || AccessFile(path, ACCESS_EXIST) )
add_path(path, info); add_path(path, info);
}
} }
} }
succeed; succeed;
@ -489,8 +496,9 @@ expand(const char *pattern, GlobInfo info)
*/ */
un_escape(prefix, pat, head); un_escape(prefix, pat, head);
un_escape(patbuf, head, tail); un_escape(patbuf, head, tail);
prefix_len = strlen(prefix);
if ( !compilePattern(patbuf, &cbuf) ) /* syntax error */ if ( !compilePattern(patbuf, &cbuf) ) /* syntax error */
fail; fail;
dot = (patbuf[0] == '.'); /* do dots as well */ dot = (patbuf[0] == '.'); /* do dots as well */
@ -502,6 +510,10 @@ expand(const char *pattern, GlobInfo info)
char path[MAXPATHLEN]; char path[MAXPATHLEN];
char tmp[MAXPATHLEN]; char tmp[MAXPATHLEN];
const char *current = expand_entry(info, info->start); const char *current = expand_entry(info, info->start);
size_t clen = strlen(current);
if ( clen+prefix_len+1 > sizeof(path) )
continue;
strcpy(path, current); strcpy(path, current);
strcat(path, prefix); strcat(path, prefix);
@ -521,12 +533,11 @@ expand(const char *pattern, GlobInfo info)
matchPattern(e->d_name, &cbuf) ) matchPattern(e->d_name, &cbuf) )
{ char newp[MAXPATHLEN]; { char newp[MAXPATHLEN];
strcpy(newp, path); if ( plen+strlen(e->d_name)+1 < sizeof(newp) )
strcpy(&newp[plen], e->d_name); { strcpy(newp, path);
/* if ( !tail[0] || ExistsDirectory(newp) ) strcpy(&newp[plen], e->d_name);
Saves memory, but involves one more file-access
*/
add_path(newp, info); add_path(newp, info);
}
} }
} }
closedir(d); closedir(d);
@ -579,11 +590,11 @@ PRED_IMPL("expand_file_name", 2, expand_file_name, 0)
term_t head = PL_new_term_ref(); term_t head = PL_new_term_ref();
int i; int i;
if ( !PL_get_chars_ex(A1, &s, CVT_ALL|REP_FN) ) if ( !PL_get_chars(A1, &s, CVT_ALL|REP_FN|CVT_EXCEPTION) )
fail; fail;
if ( strlen(s) > sizeof(spec)-1 ) if ( strlen(s) > sizeof(spec)-1 )
return PL_error(NULL, 0, "File name too intptr_t", return PL_error(NULL, 0, NULL, ERR_REPRESENTATION,
ERR_DOMAIN, ATOM_pattern, A1); ATOM_max_path_length);
if ( !expandVars(s, spec, sizeof(spec)) ) if ( !expandVars(s, spec, sizeof(spec)) )
fail; fail;

View File

@ -1,39 +0,0 @@
/* $Id$
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: wielemak@science.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2005, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <wchar.h>
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
See pl-mswchar.cpp for the motivation for this nonsense. Used in
pl-fli.c and pl-text.c.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(__WINDOWS__) && !defined(__MINGW32__)
#define wcrtomb(s, wc, ps) ms_wcrtomb(s, wc, ps)
#define mbrtowc(pwc, s, n, ps) ms_mbrtowc(pwc, s, n, ps)
extern size_t ms_wcrtomb(char *s, wchar_t wc, mbstate_t *ps);
extern size_t ms_mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
#endif

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifdef __MINGW32__ #ifdef __MINGW32__
@ -27,8 +27,8 @@
#endif #endif
#ifdef __WINDOWS__ #ifdef __WINDOWS__
#define _WIN32_WINNT 0x0400 #define WINVER 0x0501
#if (_MSC_VER >= 1300) || defined(__MINGW32__) #if (_MSC_VER >= 1300) || __MINGW32__
#include <winsock2.h> /* Needed on VC8 */ #include <winsock2.h> /* Needed on VC8 */
#include <windows.h> #include <windows.h>
#else #else
@ -36,16 +36,40 @@
#include <winsock2.h> #include <winsock2.h>
#endif #endif
#ifdef __MINGW32__
#ifndef _WIN32_IE
#define _WIN32_IE 0x0400
#endif
/* FIXME: these are copied from SWI-Prolog.h. */
#define PL_MSG_EXCEPTION_RAISED -1
#define PL_MSG_IGNORED 0
#define PL_MSG_HANDLED 1
#endif
#include "pl-incl.h" #include "pl-incl.h"
#ifdef __YAP_PROLOG__
#include "pl-utf8.h" #include "pl-utf8.h"
//#include <crtdbg.h> #else
#include "os/pl-utf8.h"
#endif
#include <process.h> #include <process.h>
#ifdef __YAP_PROLOG__
#include "pl-ctype.h" #include "pl-ctype.h"
#else
#include "os/pl-ctype.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#ifdef __YAP_PROLOG__
#include "SWI-Stream.h" #include "SWI-Stream.h"
#else
#include "os/SWI-Stream.h"
#endif
#include <process.h> #include <process.h>
#include <winbase.h> #include <winbase.h>
#ifdef HAVE_CRTDBG_H
#include <crtdbg.h>
#endif
/******************************* /*******************************
@ -135,8 +159,8 @@ PlMessage(const char *fm, ...)
* WinAPI ERROR CODES * * WinAPI ERROR CODES *
*******************************/ *******************************/
char * const char *
WinError() WinError(void)
{ int id = GetLastError(); { int id = GetLastError();
char *msg; char *msg;
static WORD lang; static WORD lang;
@ -232,23 +256,21 @@ Pause(double t)
* SET FILE SIZE * * SET FILE SIZE *
*******************************/ *******************************/
#ifndef HAVE_FTRUNCATE
int int
ftruncate(int fileno, int64_t length) ftruncate(int fileno, int64_t length)
{ int e; { errno_t e;
#if HAVE__CHSIZE_S
/* not always available in mingw */
if ( (e=_chsize_s(fileno, length)) == 0 ) if ( (e=_chsize_s(fileno, length)) == 0 )
return 0; return 0;
#else
if ( (e=_chsize(fileno, (long)length)) == 0 )
return 0;
#endif
errno = e; errno = e;
return -1; return -1;
} }
#endif
/******************************* /*******************************
* QUERY CPU TIME * * QUERY CPU TIME *
@ -273,13 +295,14 @@ CpuTime(cputime_kind which)
case CPU_SYSTEM: case CPU_SYSTEM:
p = &kerneltime; p = &kerneltime;
break; break;
default:
assert(0);
return 0.0;
} }
t = (double)p->dwHighDateTime * (4294967296.0 * ntick nano); t = (double)p->dwHighDateTime * (4294967296.0 * ntick nano);
t += (double)p->dwLowDateTime * (ntick nano); t += (double)p->dwLowDateTime * (ntick nano);
} else /* '95, Windows 3.1/win32s */ } else /* '95, Windows 3.1/win32s */
{ extern intptr_t clock_wait_ticks; { t = 0.0;
t = (double) (clock() - clock_wait_ticks) / (double) CLOCKS_PER_SEC;
} }
return t; return t;
@ -287,7 +310,7 @@ CpuTime(cputime_kind which)
static int static int
CpuCount() CpuCount(void)
{ SYSTEM_INFO si; { SYSTEM_INFO si;
GetSystemInfo(&si); GetSystemInfo(&si);
@ -297,7 +320,7 @@ CpuCount()
void void
setOSPrologFlags() setOSPrologFlags(void)
{ PL_set_prolog_flag("cpu_count", PL_INTEGER, CpuCount()); { PL_set_prolog_flag("cpu_count", PL_INTEGER, CpuCount());
} }
@ -310,7 +333,7 @@ findExecutable(const char *module, char *exe)
if ( module ) if ( module )
{ if ( !(hmod = GetModuleHandle(module)) ) { if ( !(hmod = GetModuleHandle(module)) )
{ hmod = GetModuleHandle("libpl.dll"); { hmod = GetModuleHandle("libswipl.dll");
DEBUG(0, DEBUG(0,
Sdprintf("Warning: could not find module from \"%s\"\n" Sdprintf("Warning: could not find module from \"%s\"\n"
"Warning: Trying %s to find home\n", "Warning: Trying %s to find home\n",
@ -340,7 +363,7 @@ findExecutable(const char *module, char *exe)
typedef struct typedef struct
{ const char *name; { const char *name;
int id; UINT id;
} showtype; } showtype;
static int static int
@ -348,12 +371,12 @@ get_showCmd(term_t show, UINT *cmd)
{ char *s; { char *s;
showtype *st; showtype *st;
static showtype types[] = static showtype types[] =
{ { "hide", SW_HIDE }, { { "hide", SW_HIDE },
{ "maximize", SW_MAXIMIZE }, { "maximize", SW_MAXIMIZE },
{ "minimize", SW_MINIMIZE }, { "minimize", SW_MINIMIZE },
{ "restore", SW_RESTORE }, { "restore", SW_RESTORE },
{ "show", SW_SHOW }, { "show", SW_SHOW },
{ "showdefault", SW_SHOWDEFAULT }, { "showdefault", SW_SHOWDEFAULT },
{ "showmaximized", SW_SHOWMAXIMIZED }, { "showmaximized", SW_SHOWMAXIMIZED },
{ "showminimized", SW_SHOWMINIMIZED }, { "showminimized", SW_SHOWMINIMIZED },
{ "showminnoactive", SW_SHOWMINNOACTIVE }, { "showminnoactive", SW_SHOWMINNOACTIVE },
@ -361,8 +384,8 @@ get_showCmd(term_t show, UINT *cmd)
{ "shownoactive", SW_SHOWNOACTIVATE }, { "shownoactive", SW_SHOWNOACTIVATE },
{ "shownormal", SW_SHOWNORMAL }, { "shownormal", SW_SHOWNORMAL },
/* compatibility */ /* compatibility */
{ "normal", SW_SHOWNORMAL }, { "normal", SW_SHOWNORMAL },
{ "iconic", SW_MINIMIZE }, { "iconic", SW_MINIMIZE },
{ NULL, 0 }, { NULL, 0 },
}; };
@ -422,8 +445,9 @@ win_exec(size_t len, const wchar_t *cmd, UINT show)
} else } else
{ term_t tmp = PL_new_term_ref(); { term_t tmp = PL_new_term_ref();
PL_unify_wchars(tmp, PL_ATOM, len, cmd); return ( PL_unify_wchars(tmp, PL_ATOM, len, cmd) &&
return PL_error(NULL, 0, WinError(), ERR_SHELL_FAILED, tmp); PL_error(NULL, 0, WinError(), ERR_SHELL_FAILED, tmp)
);
} }
} }
@ -524,7 +548,7 @@ static const shell_error se_errors[] =
{ SE_ERR_DDETIMEOUT, "DDE request timed out" }, { SE_ERR_DDETIMEOUT, "DDE request timed out" },
{ SE_ERR_DLLNOTFOUND, "DLL not found" }, { SE_ERR_DLLNOTFOUND, "DLL not found" },
{ SE_ERR_FNF, "File not found (FNF)" }, { SE_ERR_FNF, "File not found (FNF)" },
{ SE_ERR_NOASSOC, "No association" }, { SE_ERR_NOASSOC, "No association" },
{ SE_ERR_OOM, "Not enough memory" }, { SE_ERR_OOM, "Not enough memory" },
{ SE_ERR_PNF, "Path not found (PNF)" }, { SE_ERR_PNF, "Path not found (PNF)" },
{ SE_ERR_SHARE, "Sharing violation" }, { SE_ERR_SHARE, "Sharing violation" },
@ -550,7 +574,7 @@ win_shell(term_t op, term_t file, term_t how)
{ const shell_error *se; { const shell_error *se;
for(se = se_errors; se->message; se++) for(se = se_errors; se->message; se++)
{ if ( se->eno == (int)instance ) { if ( se->eno == (int)(intptr_t)instance )
return PL_error(NULL, 0, se->message, ERR_SHELL_FAILED, file); return PL_error(NULL, 0, se->message, ERR_SHELL_FAILED, file);
} }
PL_error(NULL, 0, NULL, ERR_SHELL_FAILED, file); PL_error(NULL, 0, NULL, ERR_SHELL_FAILED, file);
@ -621,22 +645,113 @@ need. They are used by pl-load.c, which defines the actual Prolog
interface. interface.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static char *dlmsg; #ifdef HAVE_LIBLOADERAPI_H
#include <LibLoaderAPI.h>
#else
#ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
#define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100
#endif
#ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000
#endif
typedef void * DLL_DIRECTORY_COOKIE;
#endif
static const char *dlmsg;
static DLL_DIRECTORY_COOKIE WINAPI (*f_AddDllDirectoryW)(wchar_t* dir);
static BOOL WINAPI (*f_RemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
static DWORD
load_library_search_flags(void)
{ static int done = FALSE;
static DWORD flags = 0;
if ( !done )
{ HMODULE kernel = GetModuleHandle(TEXT("kernel32.dll"));
if ( (f_AddDllDirectoryW = (void*)GetProcAddress(kernel, "AddDllDirectory")) &&
(f_RemoveDllDirectory = (void*)GetProcAddress(kernel, "RemoveDllDirectory")) )
{ flags = ( LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR|
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
}
done = TRUE;
}
return flags;
}
static
PRED_IMPL("win_add_dll_directory", 2, win_add_dll_directory, 0)
{ PRED_LD
char *dirs;
if ( PL_get_file_name(A1, &dirs, REP_UTF8) )
{ size_t len = utf8_strlen(dirs, strlen(dirs));
wchar_t *dirw = alloca((len+10)*sizeof(wchar_t));
DLL_DIRECTORY_COOKIE cookie;
if ( _xos_os_filenameW(dirs, dirw, len+10) == NULL )
return PL_representation_error("file_name");
if ( load_library_search_flags() )
{ if ( (cookie = (*f_AddDllDirectoryW)(dirw)) )
return PL_unify_int64(A2, (int64_t)cookie);
return PL_error(NULL, 0, WinError(), ERR_SYSCALL, "AddDllDirectory()");
} else
return FALSE;
} else
return FALSE;
}
static
PRED_IMPL("win_remove_dll_directory", 1, win_remove_dll_directory, 0)
{ int64_t icookie;
if ( PL_get_int64_ex(A1, &icookie) )
{ if ( f_RemoveDllDirectory )
{ if ( (*f_RemoveDllDirectory)((DLL_DIRECTORY_COOKIE)icookie) )
return TRUE;
return PL_error(NULL, 0, WinError(), ERR_SYSCALL, "RemoveDllDirectory()");
} else
return FALSE;
} else
return FALSE;
}
static int
is_windows_abs_path(const wchar_t *path)
{ if ( path[1] == ':' && path[0] < 0x80 && iswalpha(path[0]) )
return TRUE; /* drive */
if ( path[0] == '\\' && path[1] == '\\' )
return TRUE; /* UNC */
return FALSE;
}
void * void *
dlopen(const char *file, int flags) /* file is in UTF-8 */ dlopen(const char *file, int flags) /* file is in UTF-8, POSIX path */
{ HINSTANCE h; { HINSTANCE h;
DWORD llflags = 0;
size_t len = utf8_strlen(file, strlen(file)); size_t len = utf8_strlen(file, strlen(file));
wchar_t *wfile = alloca((len+1)*sizeof(wchar_t)); wchar_t *wfile = alloca((len+10)*sizeof(wchar_t));
if ( !wfile ) if ( !wfile )
{ dlmsg = "No memory"; { dlmsg = "No memory";
return NULL; return NULL;
} }
utf8towcs(wfile, file); if ( _xos_os_filenameW(file, wfile, len+10) == NULL )
{ dlmsg = "Name too long";
return NULL;
}
if ( (h = LoadLibraryW(wfile)) ) if ( is_windows_abs_path(wfile) )
llflags |= load_library_search_flags();
if ( (h = LoadLibraryExW(wfile, NULL, llflags)) )
{ dlmsg = "No Error"; { dlmsg = "No Error";
return (void *)h; return (void *)h;
} }
@ -647,7 +762,7 @@ dlopen(const char *file, int flags) /* file is in UTF-8 */
const char * const char *
dlerror() dlerror(void)
{ return dlmsg; { return dlmsg;
} }
@ -676,11 +791,59 @@ dlclose(void *handle)
#endif /*EMULATE_DLOPEN*/ #endif /*EMULATE_DLOPEN*/
/*******************************
* SNPRINTF MADNESS *
*******************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MS-Windows _snprintf() may look like C99 snprintf(), but is is not quite
the same: on overflow, the buffer is *not* 0-terminated and the return
is negative (unspecified how negative). The code below works around
this, returning count on overflow. This is still not the same as the C99
version that returns the number of characters that would have been
written, but it seems to be enough for our purposes.
See http://www.di-mgt.com.au/cprog.html#snprintf
The above came from the provided link, but it is even worse (copied from
VS2005 docs):
- If len < count, then len characters are stored in buffer, a
null-terminator is appended, and len is returned.
- If len = count, then len characters are stored in buffer, no
null-terminator is appended, and len is returned.
- If len > count, then count characters are stored in buffer, no
null-terminator is appended, and a negative value is returned.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int
ms_snprintf(char *buffer, size_t count, const char *fmt, ...)
{ va_list ap;
int ret;
va_start(ap, fmt);
ret = _vsnprintf(buffer, count-1, fmt, ap);
va_end(ap);
if ( ret < 0 || ret == count )
{ ret = (int)count;
buffer[count-1] = '\0';
}
return ret;
}
/******************************* /*******************************
* FOLDERS * * FOLDERS *
*******************************/ *******************************/
#include <Shlobj.h> #ifdef HAVE_SHLOBJ_H
#include <shlobj.h>
#endif
typedef struct folderid typedef struct folderid
{ int csidl; { int csidl;
@ -727,7 +890,7 @@ static int
unify_csidl_path(term_t t, int csidl) unify_csidl_path(term_t t, int csidl)
{ wchar_t buf[MAX_PATH]; { wchar_t buf[MAX_PATH];
if ( SHGetFolderPathW(0, csidl, NULL, FALSE, buf) ) if ( SHGetSpecialFolderPathW(0, buf, csidl, FALSE) )
{ wchar_t *p; { wchar_t *p;
for(p=buf; *p; p++) for(p=buf; *p; p++)
@ -935,7 +1098,7 @@ setStacksFromKey(HKEY key)
void void
getDefaultsFromRegistry() getDefaultsFromRegistry(void)
{ HKEY key; { HKEY key;
if ( (key = reg_open_key(L"HKEY_LOCAL_MACHINE/Software/SWI/Prolog", FALSE)) ) if ( (key = reg_open_key(L"HKEY_LOCAL_MACHINE/Software/SWI/Prolog", FALSE)) )
@ -948,44 +1111,6 @@ getDefaultsFromRegistry()
} }
} }
static
PRED_IMPL("win_open_file_name", 3, win_open_file_name, 0)
{ GET_LD
OPENFILENAMEW ofn;
wchar_t szFileName[MAX_PATH];
void *x;
HWND hwnd;
wchar_t *yap_cwd;
if(!PL_get_pointer(A1, &x))
return FALSE;
if(!PL_get_wchars(A2, NULL, &yap_cwd, CVT_ATOM|CVT_EXCEPTION))
return FALSE;
hwnd = (HWND)x;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = L"Prolog Files (*.pl;*.yap)\0*.pl;*.yap\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.lpstrInitialDir = yap_cwd;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST
//| OFN_HIDEREADONLY
//|OFN_ALLOWMULTISELECT
;
ofn.lpstrDefExt = "pl";
if(GetOpenFileNameW(&ofn))
{
// Do something usefull with the filename stored in szFileName
return PL_unify_wchars(A3, PL_ATOM,
MAX_PATH-1, szFileName);
}
return TRUE;
}
/******************************* /*******************************
* PUBLISH PREDICATES * * PUBLISH PREDICATES *
*******************************/ *******************************/
@ -993,9 +1118,12 @@ PRED_IMPL("win_open_file_name", 3, win_open_file_name, 0)
BeginPredDefs(win) BeginPredDefs(win)
PRED_DEF("win_shell", 2, win_shell2, 0) PRED_DEF("win_shell", 2, win_shell2, 0)
PRED_DEF("win_shell", 3, win_shell3, 0) PRED_DEF("win_shell", 3, win_shell3, 0)
PRED_DEF("win_open_file_name", 3, win_open_file_name, 0)
PRED_DEF("win_registry_get_value", 3, win_registry_get_value, 0) PRED_DEF("win_registry_get_value", 3, win_registry_get_value, 0)
PRED_DEF("win_folder", 2, win_folder, PL_FA_NONDETERMINISTIC) PRED_DEF("win_folder", 2, win_folder, PL_FA_NONDETERMINISTIC)
#ifdef EMULATE_DLOPEN
PRED_DEF("win_add_dll_directory", 2, win_add_dll_directory, 0)
PRED_DEF("win_remove_dll_directory", 1, win_remove_dll_directory, 0)
#endif
EndPredDefs EndPredDefs
#endif /*__WINDOWS__*/ #endif /*__WINDOWS__*/

View File

@ -1,11 +1,10 @@
/* $Id$ /* Part of SWI-Prolog
Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: wielemak@science.uva.nl E-mail: J.Wielemaker@vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2007, University of Amsterdam Copyright (C): 1985-2013, University of Amsterdam
VU University Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/* Modified (M) 1993 Dave Sherratt */ /* Modified (M) 1993 Dave Sherratt */
@ -30,6 +29,17 @@
#include <os2.h> /* this has to appear before pl-incl.h */ #include <os2.h> /* this has to appear before pl-incl.h */
#endif #endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Solaris has asctime_r() with 3 arguments. Using _POSIX_PTHREAD_SEMANTICS
is supposed to give the POSIX standard one.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(__sun__) || defined(__sun)
#define _POSIX_PTHREAD_SEMANTICS 1
#endif
#define __MINGW_USE_VC2005_COMPAT /* Get Windows time_t as 64-bit */
#include "pl-incl.h" #include "pl-incl.h"
#include "pl-ctype.h" #include "pl-ctype.h"
#include "pl-utf8.h" #include "pl-utf8.h"
@ -96,27 +106,11 @@ static double initial_time;
static void initExpand(void); static void initExpand(void);
static void cleanupExpand(void); static void cleanupExpand(void);
static void initEnviron(void); static void initEnviron(void);
static char * Which(const char *program, char *fullname);
#ifndef DEFAULT_PATH #ifndef DEFAULT_PATH
#define DEFAULT_PATH "/bin:/usr/bin" #define DEFAULT_PATH "/bin:/usr/bin"
#endif #endif
/*******************************
* GLOBALS *
*******************************/
#ifdef HAVE_CLOCK
long clock_wait_ticks;
#endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
This module is a contraction of functions that used to be all over the
place. together with pl-os.h (included by pl-incl.h) this file
should define a basic layer around the OS, on which the rest of
SWI-Prolog is based.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/******************************** /********************************
* INITIALISATION * * INITIALISATION *
*********************************/ *********************************/
@ -145,20 +139,6 @@ initOs(void)
setPrologFlagMask(PLFLAG_FILE_CASE_PRESERVING); setPrologFlagMask(PLFLAG_FILE_CASE_PRESERVING);
#endif #endif
#ifdef HAVE_CLOCK
clock_wait_ticks = 0L;
#endif
#if OS2
{ DATETIME i;
DosGetDateTime((PDATETIME)&i);
initial_time = (i.hours * 3600.0)
+ (i.minutes * 60.0)
+ i.seconds
+ (i.hundredths / 100.0);
}
#endif /* OS2 */
DEBUG(1, Sdprintf("OS:done\n")); DEBUG(1, Sdprintf("OS:done\n"));
succeed; succeed;
@ -239,11 +219,26 @@ static char errmsg[64];
#endif /*_SC_CLK_TCK*/ #endif /*_SC_CLK_TCK*/
#endif /*HAVE_TIMES*/ #endif /*HAVE_TIMES*/
#ifdef HAVE_CLOCK_GETTIME
#define timespec_to_double(ts) \
((double)(ts).tv_sec + (double)(ts).tv_nsec/(double)1000000000.0)
#endif
double double
CpuTime(cputime_kind which) CpuTime(cputime_kind which)
{ {
#ifdef HAVE_TIMES #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
#define CPU_TIME_DONE
struct timespec ts;
(void)which;
if ( clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0 )
return timespec_to_double(ts);
return 0.0;
#endif
#if !defined(CPU_TIME_DONE) && defined(HAVE_TIMES)
#define CPU_TIME_DONE
struct tms t; struct tms t;
double used; double used;
static int MTOK_got_hz = FALSE; static int MTOK_got_hz = FALSE;
@ -268,39 +263,17 @@ CpuTime(cputime_kind which)
used = 0.0; /* happens when running under GDB */ used = 0.0; /* happens when running under GDB */
return used; return used;
#else #endif
#if OS2 && EMX #if !defined(CPU_TIME_DONE)
DATETIME i; (void)which;
DosGetDateTime((PDATETIME)&i);
return (((i.hours * 3600)
+ (i.minutes * 60)
+ i.seconds
+ (i.hundredths / 100.0)) - initial_time);
#else
#ifdef HAVE_CLOCK
return (double) (clock() - clock_wait_ticks) / (double) CLOCKS_PER_SEC;
#else
return 0.0; return 0.0;
#endif
#endif
#endif #endif
} }
#endif /*__WINDOWS__*/ #endif /*__WINDOWS__*/
void
PL_clock_wait_ticks(long waited)
{
#ifdef HAVE_CLOCK
clock_wait_ticks += waited;
#endif
}
double double
WallTime(void) WallTime(void)
@ -310,7 +283,7 @@ WallTime(void)
struct timespec tp; struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp); clock_gettime(CLOCK_REALTIME, &tp);
stime = (double)tp.tv_sec + (double)tp.tv_nsec/1000000000.0; stime = timespec_to_double(tp);
#else #else
#ifdef HAVE_GETTIMEOFDAY #ifdef HAVE_GETTIMEOFDAY
struct timeval tp; struct timeval tp;
@ -389,7 +362,7 @@ CpuCount()
#include <sys/sysctl.h> #include <sys/sysctl.h>
int int
CpuCount() CpuCount(void)
{ int count ; { int count ;
size_t size=sizeof(count) ; size_t size=sizeof(count) ;
@ -415,7 +388,7 @@ setOSPrologFlags(void)
{ int cpu_count = CpuCount(); { int cpu_count = CpuCount();
if ( cpu_count > 0 ) if ( cpu_count > 0 )
PL_set_prolog_flag("cpu_count", PL_INTEGER|FF_READONLY, cpu_count); PL_set_prolog_flag("cpu_count", PL_INTEGER, cpu_count);
} }
#endif #endif
@ -436,8 +409,7 @@ UsedMemory(void)
} }
#endif #endif
return (GD->statistics.heap + return (usedStack(global) +
usedStack(global) +
usedStack(local) + usedStack(local) +
usedStack(trail)); usedStack(trail));
} }
@ -448,8 +420,7 @@ FreeMemory(void)
{ {
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_DATA) #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_DATA)
uintptr_t used = UsedMemory(); uintptr_t used = UsedMemory();
struct rlimit limit;
struct rlimit limit;
if ( getrlimit(RLIMIT_DATA, &limit) == 0 ) if ( getrlimit(RLIMIT_DATA, &limit) == 0 )
return limit.rlim_cur - used; return limit.rlim_cur - used;
@ -470,7 +441,7 @@ FreeMemory(void)
some systems (__WINDOWS__) the seed of rand() is thread-local, while on some systems (__WINDOWS__) the seed of rand() is thread-local, while on
others it is global. We appear to have the choice between others it is global. We appear to have the choice between
# srand()/rand() # srand()/rand()
Differ in MT handling, often bad distribution Differ in MT handling, often bad distribution
# srandom()/random() # srandom()/random()
@ -522,16 +493,14 @@ _PL_Random(void)
} }
#ifdef HAVE_RANDOM #ifdef HAVE_RANDOM
#if SIZEOF_VOIDP == 4
{ uint64_t l = random(); { uint64_t l = random();
l ^= (uint64_t)random()<<32; l ^= (uint64_t)random()<<15;
l ^= (uint64_t)random()<<30;
l ^= (uint64_t)random()<<45;
return l; return l;
} }
#else
return random();
#endif
#else #else
{ uint64_t l = rand(); /* 0<n<2^15-1 */ { uint64_t l = rand(); /* 0<n<2^15-1 */
@ -845,19 +814,16 @@ struct canonical_dir
forwards char *canoniseDir(char *); forwards char *canoniseDir(char *);
#endif /*O_CANONISE_DIRS*/ #endif /*O_CANONISE_DIRS*/
#define CWDdir (LD->os._CWDdir) /* current directory */
#define CWDlen (LD->os._CWDlen) /* strlen(CWDdir) */
static void static void
initExpand(void) initExpand(void)
{ GET_LD {
#ifdef O_CANONISE_DIRS #ifdef O_CANONISE_DIRS
char *dir; char *dir;
char *cpaths; char *cpaths;
#endif #endif
CWDdir = NULL; GD->paths.CWDdir = NULL;
CWDlen = 0; GD->paths.CWDlen = 0;
#ifdef O_CANONISE_DIRS #ifdef O_CANONISE_DIRS
{ char envbuf[MAXPATHLEN]; { char envbuf[MAXPATHLEN];
@ -898,7 +864,15 @@ cleanupExpand(void)
canonical_dirlist = NULL; canonical_dirlist = NULL;
for( ; dn; dn = next ) for( ; dn; dn = next )
{ next = dn->next; { next = dn->next;
free(dn); if ( dn->canonical && dn->canonical != dn->name )
remove_string(dn->canonical);
remove_string(dn->name);
PL_free(dn);
}
if ( GD->paths.CWDdir )
{ remove_string(GD->paths.CWDdir);
GD->paths.CWDdir = NULL;
GD->paths.CWDlen = 0;
} }
} }
@ -925,7 +899,7 @@ registerParentDirs(const char *path)
} }
if ( statfunc(OsPath(dirname, tmp), &buf) == 0 ) if ( statfunc(OsPath(dirname, tmp), &buf) == 0 )
{ CanonicalDir dn = malloc(sizeof(*dn)); { CanonicalDir dn = PL_malloc(sizeof(*dn));
dn->name = store_string(dirname); dn->name = store_string(dirname);
dn->inode = buf.st_ino; dn->inode = buf.st_ino;
@ -980,7 +954,7 @@ verify_entry(CanonicalDir d)
remove_string(d->name); remove_string(d->name);
if ( d->canonical != d->name ) if ( d->canonical != d->name )
remove_string(d->canonical); remove_string(d->canonical);
free(d); PL_free(d);
} }
return FALSE; return FALSE;
@ -1008,12 +982,12 @@ canoniseDir(char *path)
} }
/* we need to use malloc() here */ /* we need to use malloc() here */
/* because allocHeap() only ensures */ /* because allocHeapOrHalt() only ensures */
/* alignment for `word', and inode_t */ /* alignment for `word', and inode_t */
/* is sometimes bigger! */ /* is sometimes bigger! */
if ( statfunc(OsPath(path, tmp), &buf) == 0 ) if ( statfunc(OsPath(path, tmp), &buf) == 0 )
{ CanonicalDir dn = malloc(sizeof(*dn)); { CanonicalDir dn = PL_malloc(sizeof(*dn));
char dirname[MAXPATHLEN]; char dirname[MAXPATHLEN];
char *e = path + strlen(path); char *e = path + strlen(path);
@ -1082,8 +1056,7 @@ cleanupExpand(void)
char * char *
canoniseFileName(char *path) canoniseFileName(char *path)
{ char *out = path, *in = path, *start = path; { char *out = path, *in = path, *start = path;
char *osave[100]; tmp_buffer saveb;
int osavep = 0;
#ifdef O_HASDRIVES /* C: */ #ifdef O_HASDRIVES /* C: */
if ( in[1] == ':' && isLetter(in[0]) ) if ( in[1] == ':' && isLetter(in[0]) )
@ -1092,8 +1065,8 @@ canoniseFileName(char *path)
out = start = in; out = start = in;
} }
#ifdef __MINGW32__ /* /c/ in MINGW is the same as c: */ #ifdef __MINGW32__ /* /c/ in MINGW is the same as c: */
if ( in[0] == '/' && isLetter(in[1]) && else if ( in[0] == '/' && isLetter(in[1]) &&
in[2] == '/' ) in[2] == '/' )
{ {
out[0] = in[1]; out[0] = in[1];
out[1] = ':'; out[1] = ':';
@ -1101,13 +1074,13 @@ canoniseFileName(char *path)
out = start = in; out = start = in;
} }
#endif #endif
#endif #endif
#ifdef O_HASSHARES /* //host/ */ #ifdef O_HASSHARES /* //host/ */
if ( in[0] == '/' && in[1] == '/' && isAlpha(in[2]) ) if ( in[0] == '/' && in[1] == '/' && isAlpha(in[2]) )
{ char *s; { char *s;
for(s = in+3; *s && (isAlpha(*s) || *s == '.'); s++) for(s = in+3; *s && (isAlpha(*s) || *s == '-' || *s == '.'); s++)
; ;
if ( *s == '/' ) if ( *s == '/' )
{ in = out = s+1; { in = out = s+1;
@ -1122,7 +1095,8 @@ canoniseFileName(char *path)
in += 2; in += 2;
if ( in[0] == '/' ) if ( in[0] == '/' )
*out++ = '/'; *out++ = '/';
osave[osavep++] = out; initBuffer(&saveb);
addBuffer(&saveb, out, char*);
while(*in) while(*in)
{ if (*in == '/') { if (*in == '/')
@ -1138,15 +1112,15 @@ canoniseFileName(char *path)
} }
if ( in[2] == EOS ) /* delete trailing /. */ if ( in[2] == EOS ) /* delete trailing /. */
{ *out = EOS; { *out = EOS;
return path; goto out;
} }
if ( in[2] == '.' && (in[3] == '/' || in[3] == EOS) ) if ( in[2] == '.' && (in[3] == '/' || in[3] == EOS) )
{ if ( osavep > 0 ) /* delete /foo/../ */ { if ( !isEmptyBuffer(&saveb) ) /* delete /foo/../ */
{ out = osave[--osavep]; { out = popBuffer(&saveb, char*);
in += 3; in += 3;
if ( in[0] == EOS && out > start+1 ) if ( in[0] == EOS && out > start+1 )
{ out[-1] = EOS; /* delete trailing / */ { out[-1] = EOS; /* delete trailing / */
return path; goto out;
} }
goto again; goto again;
} else if ( start[0] == '/' && out == start+1 ) } else if ( start[0] == '/' && out == start+1 )
@ -1160,12 +1134,15 @@ canoniseFileName(char *path)
in++; in++;
if ( out > path && out[-1] != '/' ) if ( out > path && out[-1] != '/' )
*out++ = '/'; *out++ = '/';
osave[osavep++] = out; addBuffer(&saveb, out, char*);
} else } else
*out++ = *in++; *out++ = *in++;
} }
*out++ = *in++; *out++ = *in++;
out:
discardBuffer(&saveb);
return path; return path;
} }
@ -1201,15 +1178,18 @@ canonisePath(char *path)
#ifdef O_CANONISE_DIRS #ifdef O_CANONISE_DIRS
{ char *e; { char *e;
char dirname[MAXPATHLEN]; char dirname[MAXPATHLEN];
size_t plen = strlen(path);
e = path + strlen(path) - 1; if ( plen > 0 )
for( ; *e != '/' && e > path; e-- ) { e = path + plen - 1;
; for( ; *e != '/' && e > path; e-- )
strncpy(dirname, path, e-path); ;
dirname[e-path] = EOS; strncpy(dirname, path, e-path);
canoniseDir(dirname); dirname[e-path] = EOS;
strcat(dirname, e); canoniseDir(dirname);
strcpy(path, dirname); strcat(dirname, e);
strcpy(path, dirname);
}
} }
#endif #endif
@ -1238,11 +1218,12 @@ takeWord(const char **string, char *wrd, int maxlen)
} }
bool char *
expandVars(const char *pattern, char *expanded, int maxlen) expandVars(const char *pattern, char *expanded, int maxlen)
{ GET_LD { GET_LD
int size = 0; int size = 0;
char wordbuf[MAXPATHLEN]; char wordbuf[MAXPATHLEN];
char *rc = expanded;
if ( *pattern == '~' ) if ( *pattern == '~' )
{ char *user; { char *user;
@ -1305,7 +1286,9 @@ expandVars(const char *pattern, char *expanded, int maxlen)
#endif #endif
size += (l = (int) strlen(value)); size += (l = (int) strlen(value));
if ( size+1 >= maxlen ) if ( size+1 >= maxlen )
return PL_error(NULL, 0, NULL, ERR_REPRESENTATION, ATOM_max_path_length); { PL_error(NULL, 0, NULL, ERR_REPRESENTATION, ATOM_max_path_length);
return NULL;
}
strcpy(expanded, value); strcpy(expanded, value);
expanded += l; expanded += l;
UNLOCK(); UNLOCK();
@ -1345,8 +1328,9 @@ expandVars(const char *pattern, char *expanded, int maxlen)
size += (l = (int)strlen(value)); size += (l = (int)strlen(value));
if ( size+1 >= maxlen ) if ( size+1 >= maxlen )
{ UNLOCK(); { UNLOCK();
return PL_error(NULL, 0, NULL, ERR_REPRESENTATION, PL_error(NULL, 0, NULL, ERR_REPRESENTATION,
ATOM_max_path_length); ATOM_max_path_length);
return NULL;
} }
strcpy(expanded, value); strcpy(expanded, value);
UNLOCK(); UNLOCK();
@ -1359,8 +1343,10 @@ expandVars(const char *pattern, char *expanded, int maxlen)
def: def:
size++; size++;
if ( size+1 >= maxlen ) if ( size+1 >= maxlen )
return PL_error(NULL, 0, NULL, ERR_REPRESENTATION, { PL_error(NULL, 0, NULL, ERR_REPRESENTATION,
ATOM_max_path_length); ATOM_max_path_length);
return NULL;
}
*expanded++ = c; *expanded++ = c;
continue; continue;
@ -1369,61 +1355,14 @@ expandVars(const char *pattern, char *expanded, int maxlen)
} }
if ( ++size >= maxlen ) if ( ++size >= maxlen )
return PL_error(NULL, 0, NULL, ERR_REPRESENTATION, { PL_error(NULL, 0, NULL, ERR_REPRESENTATION,
ATOM_max_path_length); ATOM_max_path_length);
return NULL;
}
*expanded = EOS; *expanded = EOS;
succeed; return rc;
}
static int
ExpandFile(const char *pattern, char **vector)
{ char expanded[MAXPATHLEN];
int matches = 0;
if ( !expandVars(pattern, expanded, sizeof(expanded)) )
return -1;
vector[matches++] = store_string(expanded);
return matches;
}
char *
ExpandOneFile(const char *spec, char *file)
{ GET_LD
char *vector[256];
int size;
switch( (size=ExpandFile(spec, vector)) )
{ case -1:
return NULL;
case 0:
{ term_t tmp = PL_new_term_ref();
PL_put_atom_chars(tmp, spec);
PL_error(NULL, 0, "no match", ERR_EXISTENCE, ATOM_file, tmp);
return NULL;
}
case 1:
strcpy(file, vector[0]);
remove_string(vector[0]);
return file;
default:
{ term_t tmp = PL_new_term_ref();
int n;
for(n=0; n<size; n++)
remove_string(vector[n]);
PL_put_atom_chars(tmp, spec);
PL_error(NULL, 0, "ambiguous", ERR_EXISTENCE, ATOM_file, tmp);
return NULL;
}
}
} }
@ -1507,7 +1446,7 @@ AbsoluteFile(const char *spec, char *path)
if ( !file ) if ( !file )
return (char *) NULL; return (char *) NULL;
if ( truePrologFlag(PLFLAG_FILEVARS) ) if ( truePrologFlag(PLFLAG_FILEVARS) )
{ if ( !(file = ExpandOneFile(buf, tmp)) ) { if ( !(file = expandVars(buf, tmp, sizeof(tmp))) )
return (char *) NULL; return (char *) NULL;
} }
@ -1530,17 +1469,17 @@ AbsoluteFile(const char *spec, char *path)
} }
#endif /*O_HASDRIVES*/ #endif /*O_HASDRIVES*/
if ( !PL_cwd() ) if ( !PL_cwd(path, MAXPATHLEN) )
return NULL; return NULL;
if ( (CWDlen + strlen(file) + 1) >= MAXPATHLEN ) if ( (GD->paths.CWDlen + strlen(file) + 1) >= MAXPATHLEN )
{ PL_error(NULL, 0, NULL, ERR_REPRESENTATION, ATOM_max_path_length); { PL_error(NULL, 0, NULL, ERR_REPRESENTATION, ATOM_max_path_length);
return (char *) NULL; return (char *) NULL;
} }
strcpy(path, CWDdir); strcpy(path, GD->paths.CWDdir);
if ( file[0] != EOS ) if ( file[0] != EOS )
strcpy(&path[CWDlen], file); strcpy(&path[GD->paths.CWDlen], file);
if ( strchr(file, '.') || strchr(file, '/') ) if ( strchr(file, '.') || strchr(file, '/') )
return canonisePath(path); return canonisePath(path);
else else
@ -1550,20 +1489,20 @@ AbsoluteFile(const char *spec, char *path)
void void
PL_changed_cwd(void) PL_changed_cwd(void)
{ GET_LD { LOCK();
if ( GD->paths.CWDdir )
if ( CWDdir ) remove_string(GD->paths.CWDdir);
remove_string(CWDdir); GD->paths.CWDdir = NULL;
CWDdir = NULL; GD->paths.CWDlen = 0;
CWDlen = 0; UNLOCK();
} }
const char * static char *
PL_cwd(void) cwd_unlocked(char *cwd, size_t cwdlen)
{ GET_LD { GET_LD
if ( CWDlen == 0 ) if ( GD->paths.CWDlen == 0 )
{ char buf[MAXPATHLEN]; { char buf[MAXPATHLEN];
char *rval; char *rval;
@ -1593,16 +1532,34 @@ to be implemented directly. What about other Unixes?
} }
canonisePath(buf); canonisePath(buf);
CWDlen = strlen(buf); GD->paths.CWDlen = strlen(buf);
buf[CWDlen++] = '/'; buf[GD->paths.CWDlen++] = '/';
buf[CWDlen] = EOS; buf[GD->paths.CWDlen] = EOS;
if ( CWDdir ) if ( GD->paths.CWDdir )
remove_string(CWDdir); remove_string(GD->paths.CWDdir);
CWDdir = store_string(buf); GD->paths.CWDdir = store_string(buf);
} }
return (const char *)CWDdir; if ( GD->paths.CWDlen < cwdlen )
{ memcpy(cwd, GD->paths.CWDdir, GD->paths.CWDlen+1);
return cwd;
} else
{ PL_error(NULL, 0, NULL, ERR_REPRESENTATION, ATOM_max_path_length);
return NULL;
}
}
char *
PL_cwd(char *cwd, size_t cwdlen)
{ char *rc;
LOCK();
rc = cwd_unlocked(cwd, cwdlen);
UNLOCK();
return rc;
} }
@ -1652,14 +1609,13 @@ DirName(const char *f, char *dir)
bool bool
ChDir(const char *path) ChDir(const char *path)
{ GET_LD { char ospath[MAXPATHLEN];
char ospath[MAXPATHLEN];
char tmp[MAXPATHLEN]; char tmp[MAXPATHLEN];
OsPath(path, ospath); OsPath(path, ospath);
if ( path[0] == EOS || streq(path, ".") || if ( path[0] == EOS || streq(path, ".") ||
(CWDdir && streq(path, CWDdir)) ) (GD->paths.CWDdir && streq(path, GD->paths.CWDdir)) )
succeed; succeed;
AbsoluteFile(path, tmp); AbsoluteFile(path, tmp);
@ -1672,10 +1628,12 @@ ChDir(const char *path)
{ tmp[len++] = '/'; { tmp[len++] = '/';
tmp[len] = EOS; tmp[len] = EOS;
} }
CWDlen = len; LOCK(); /* Lock with PL_changed_cwd() */
if ( CWDdir ) GD->paths.CWDlen = len; /* and PL_cwd() */
remove_string(CWDdir); if ( GD->paths.CWDdir )
CWDdir = store_string(tmp); remove_string(GD->paths.CWDdir);
GD->paths.CWDdir = store_string(tmp);
UNLOCK();
succeed; succeed;
} }
@ -1689,7 +1647,7 @@ ChDir(const char *path)
*********************************/ *********************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct tm *LocalTime(time_t time, struct tm *r) struct tm *PL_localtime_r(time_t time, struct tm *r)
Convert time in Unix internal form (seconds since Jan 1 1970) into a Convert time in Unix internal form (seconds since Jan 1 1970) into a
structure providing easier access to the time. structure providing easier access to the time.
@ -1713,17 +1671,52 @@ ChDir(const char *path)
time_t Time() time_t Time()
Return time in seconds after Jan 1 1970 (Unix' time notion). Return time in seconds after Jan 1 1970 (Unix' time notion).
Note: MinGW has localtime_r(), but it is not locked and thus not
thread-safe. MinGW does not have localtime_s(), but we test for it in
configure.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct tm * struct tm *
LocalTime(long *t, struct tm *r) PL_localtime_r(const time_t *t, struct tm *r)
{ {
#if defined(_REENTRANT) && defined(HAVE_LOCALTIME_R) #ifdef HAVE_LOCALTIME_R
return localtime_r(t, r); return localtime_r(t, r);
#else #else
*r = *localtime((const time_t *) t); #ifdef HAVE_LOCALTIME_S
return localtime_s(r, t) == EINVAL ? NULL : t;
#else
struct tm *rc;
LOCK();
if ( (rc = localtime(t)) )
*r = *rc;
else
r = NULL;
UNLOCK();
return r; return r;
#endif #endif
#endif
}
char *
PL_asctime_r(const struct tm *tm, char *buf)
{
#ifdef HAVE_ASCTIME_R
return asctime_r(tm, buf);
#else
char *rc;
LOCK();
if ( (rc = asctime(tm)) )
strcpy(buf, rc);
else
buf = NULL;
UNLOCK();
return buf;
#endif
} }
@ -1857,7 +1850,7 @@ PushTty(IOSTREAM *s, ttybuf *buf, int mode)
if ( !truePrologFlag(PLFLAG_TTY_CONTROL) ) if ( !truePrologFlag(PLFLAG_TTY_CONTROL) )
succeed; succeed;
buf->state = allocHeap(sizeof(tty_state)); buf->state = allocHeapOrHalt(sizeof(tty_state));
#ifdef HAVE_TCSETATTR #ifdef HAVE_TCSETATTR
if ( tcgetattr(fd, &TTY_STATE(buf)) ) /* save the old one */ if ( tcgetattr(fd, &TTY_STATE(buf)) ) /* save the old one */
@ -1915,9 +1908,7 @@ PushTty(IOSTREAM *s, ttybuf *buf, int mode)
bool bool
PopTty(IOSTREAM *s, ttybuf *buf, int do_free) PopTty(IOSTREAM *s, ttybuf *buf, int do_free)
{ GET_LD { ttymode = buf->mode;
ttymode = buf->mode;
if ( buf->state ) if ( buf->state )
{ int fd = Sfileno(s); { int fd = Sfileno(s);
@ -1963,7 +1954,7 @@ PushTty(IOSTREAM *s, ttybuf *buf, int mode)
if ( !truePrologFlag(PLFLAG_TTY_CONTROL) ) if ( !truePrologFlag(PLFLAG_TTY_CONTROL) )
succeed; succeed;
buf->state = allocHeap(sizeof(tty_state)); buf->state = allocHeapOrHalt(sizeof(tty_state));
if ( ioctl(fd, TIOCGETP, &TTY_STATE(buf)) ) /* save the old one */ if ( ioctl(fd, TIOCGETP, &TTY_STATE(buf)) ) /* save the old one */
fail; fail;
@ -2178,7 +2169,7 @@ growEnviron(char **e, int amount)
for(e1=e, filled=0; *e1; e1++, filled++) for(e1=e, filled=0; *e1; e1++, filled++)
; ;
size = ROUND(filled+10+amount, 32); size = ROUND(filled+10+amount, 32);
env = (char **)malloc(size * sizeof(char *)); env = (char **)PL_malloc(size * sizeof(char *));
for ( e1=e, e2=env; *e1; *e2++ = *e1++ ) for ( e1=e, e2=env; *e1; *e2++ = *e1++ )
; ;
*e2 = (char *) NULL; *e2 = (char *) NULL;
@ -2192,7 +2183,7 @@ growEnviron(char **e, int amount)
{ char **env, **e1, **e2; { char **env, **e1, **e2;
size += 32; size += 32;
env = (char **)realloc(e, size * sizeof(char *)); env = (char **)PL_realloc(e, size * sizeof(char *));
for ( e1=e, e2=env; *e1; *e2++ = *e1++ ) for ( e1=e, e2=env; *e1; *e2++ = *e1++ )
; ;
*e2 = (char *) NULL; *e2 = (char *) NULL;
@ -2224,9 +2215,9 @@ matchName(const char *e, const char *name)
static void static void
setEntry(char **e, char *name, char *value) setEntry(char **e, char *name, char *value)
{ int l = (int)strlen(name); { size_t l = strlen(name);
*e = (char *) malloc(l + strlen(value) + 2); *e = PL_malloc_atomic(l + strlen(value) + 2);
strcpy(*e, name); strcpy(*e, name);
e[0][l++] = '='; e[0][l++] = '=';
strcpy(&e[0][l], value); strcpy(&e[0][l], value);
@ -2292,7 +2283,7 @@ Unsetenv(char *name)
an alternative. an alternative.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(__unix__) #ifdef __unix__
#define SPECIFIC_SYSTEM 1 #define SPECIFIC_SYSTEM 1
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -2465,30 +2456,15 @@ char *command;
#endif #endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[candidate]
exec(+Cmd, [+In, +Out, +Error], -Pid)
The streams may be one of standard stream, std, null stream, null, or
pipe(S), where S is a pipe stream
Detach if none is std!
TBD: Sort out status. The above is SICStus 3. YAP uses `Status' for last
argument (strange). SICStus 4 appears to drop this altogether.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
char *Symbols(char *buf) char *findExecutable(char *buf)
Return the path name of the executable of SWI-Prolog. Return the path name of the executable of SWI-Prolog.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __WINDOWS__ /* Win32 version in pl-nt.c */ #ifndef __WINDOWS__ /* Win32 version in pl-nt.c */
static char * Which(const char *program, char *fullname);
char * char *
findExecutable(const char *av0, char *buffer) findExecutable(const char *av0, char *buffer)
@ -2500,7 +2476,7 @@ findExecutable(const char *av0, char *buffer)
return NULL; return NULL;
file = Which(buf, tmp); file = Which(buf, tmp);
#if __unix__ /* argv[0] can be an #! script! */ #if __unix__ /* argv[0] can be an #! script! */
if ( file ) if ( file )
{ int n, fd; { int n, fd;
char buf[MAXPATHLEN]; char buf[MAXPATHLEN];
@ -2532,14 +2508,8 @@ findExecutable(const char *av0, char *buffer)
return strcpy(buffer, file ? file : buf); return strcpy(buffer, file ? file : buf);
} }
#endif /*__WINDOWS__*/
#ifdef __unix__
#if defined(OS2) || defined(__DOS__) || defined(__WINDOWS__)
#define EXEC_EXTENSIONS { ".exe", ".com", ".bat", ".cmd", NULL }
#define PATHSEP ';'
#else
/* not Windows, must be a Linux-like thingy */
static char * static char *
okToExec(const char *s) okToExec(const char *s)
{ statstruct stbuff; { statstruct stbuff;
@ -2552,6 +2522,11 @@ okToExec(const char *s)
return (char *) NULL; return (char *) NULL;
} }
#define PATHSEP ':' #define PATHSEP ':'
#endif /* __unix__ */
#if defined(OS2) || defined(__DOS__) || defined(__WINDOWS__)
#define EXEC_EXTENSIONS { ".exe", ".com", ".bat", ".cmd", NULL }
#define PATHSEP ';'
#endif #endif
#ifdef EXEC_EXTENSIONS #ifdef EXEC_EXTENSIONS
@ -2636,6 +2611,7 @@ Which(const char *program, char *fullname)
return NULL; return NULL;
} }
#endif /*__WINDOWS__*/
/** int Pause(double time) /** int Pause(double time)

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "pl-incl.h" #include "pl-incl.h"
@ -173,7 +173,7 @@ unifyList(term_t term, list_ctx *ctx)
a = valTermRef(term); a = valTermRef(term);
deRef(a); deRef(a);
if ( !unify_ptrs(a, ctx->lp PASS_LD) ) if ( !unify_ptrs(a, ctx->lp, 0 PASS_LD) )
{ gTop = ctx->lp; { gTop = ctx->lp;
return FALSE; return FALSE;
} }
@ -191,13 +191,13 @@ unifyDiffList(term_t head, term_t tail, list_ctx *ctx)
a = valTermRef(head); a = valTermRef(head);
deRef(a); deRef(a);
if ( !unify_ptrs(a, ctx->lp PASS_LD) ) if ( !unify_ptrs(a, ctx->lp, 0 PASS_LD) )
{ gTop = ctx->lp; { gTop = ctx->lp;
return FALSE; return FALSE;
} }
a = valTermRef(tail); a = valTermRef(tail);
deRef(a); deRef(a);
if ( !unify_ptrs(a, ctx->gstore PASS_LD) ) if ( !unify_ptrs(a, ctx->gstore, 0 PASS_LD) )
{ gTop = ctx->lp; { gTop = ctx->lp;
return FALSE; return FALSE;
} }

View File

@ -1,11 +1,10 @@
/* $Id$ /* Part of SWI-Prolog
Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: J.wielemaker@uva.nl E-mail: J.wielemaker@vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2008, University of Amsterdam Copyright (C): 1985-2012, University of Amsterdam
VU University Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/*#define O_DEBUG 1*/ /*#define O_DEBUG 1*/
@ -76,10 +75,10 @@ too much.
static void setArgvPrologFlag(void); static void setArgvPrologFlag(void);
#endif #endif
static void setTZPrologFlag(void); static void setTZPrologFlag(void);
#ifndef __YAP_PROLOG__
static void setVersionPrologFlag(void); static void setVersionPrologFlag(void);
#endif
static atom_t lookupAtomFlag(atom_t key); static atom_t lookupAtomFlag(atom_t key);
static void initPrologFlagTable(void);
typedef struct _prolog_flag typedef struct _prolog_flag
{ short flags; /* Type | Flags */ { short flags; /* Type | Flags */
@ -138,7 +137,7 @@ setPrologFlag(const char *name, int flags, ...)
if ( flags & FF_KEEP ) if ( flags & FF_KEEP )
return; return;
} else } else
{ f = allocHeap(sizeof(*f)); { f = allocHeapOrHalt(sizeof(*f));
f->index = -1; f->index = -1;
f->flags = flags; f->flags = flags;
addHTable(GD->prolog_flag.table, (void *)an, f); addHTable(GD->prolog_flag.table, (void *)an, f);
@ -155,7 +154,8 @@ setPrologFlag(const char *name, int flags, ...)
val = (f->value.a == ATOM_true); val = (f->value.a == ATOM_true);
} else if ( !s ) /* 1st definition */ } else if ( !s ) /* 1st definition */
{ f->index = indexOfBoolMask(mask); { f->index = indexOfBoolMask(mask);
DEBUG(2, Sdprintf("Prolog flag %s at 0x%08lx\n", name, mask)); DEBUG(MSG_PROLOG_FLAG,
Sdprintf("Prolog flag %s at 0x%08lx\n", name, mask));
} }
f->value.a = (val ? ATOM_true : ATOM_false); f->value.a = (val ? ATOM_true : ATOM_false);
@ -211,12 +211,20 @@ setPrologFlag(const char *name, int flags, ...)
} }
static void
freePrologFlag(prolog_flag *f)
{ if ( (f->flags & FT_MASK) == FT_TERM )
PL_erase(f->value.t);
freeHeap(f, sizeof(*f));
}
#ifdef O_PLMT #ifdef O_PLMT
static void static void
copySymbolPrologFlagTable(Symbol s) copySymbolPrologFlagTable(Symbol s)
{ GET_LD { prolog_flag *f = s->value;
prolog_flag *f = s->value; prolog_flag *copy = allocHeapOrHalt(sizeof(*copy));
prolog_flag *copy = allocHeap(sizeof(*copy));
*copy = *f; *copy = *f;
if ( (f->flags & FT_MASK) == FT_TERM ) if ( (f->flags & FT_MASK) == FT_TERM )
@ -227,13 +235,7 @@ copySymbolPrologFlagTable(Symbol s)
static void static void
freeSymbolPrologFlagTable(Symbol s) freeSymbolPrologFlagTable(Symbol s)
{ GET_LD { freePrologFlag(s->value);
prolog_flag *f = s->value;
if ( (f->flags & FT_MASK) == FT_TERM )
PL_erase(f->value.t);
freeHeap(f, sizeof(*f));
} }
#endif #endif
@ -267,25 +269,34 @@ setDoubleQuotes(atom_t a, unsigned int *flagp)
static int static int
setUnknown(atom_t a, unsigned int *flagp) setUnknown(term_t value, atom_t a, Module m)
{ unsigned int flags; { unsigned int flags = m->flags & ~(UNKNOWN_MASK);
if ( a == ATOM_error ) if ( a == ATOM_error )
flags = UNKNOWN_ERROR; flags |= UNKNOWN_ERROR;
else if ( a == ATOM_warning ) else if ( a == ATOM_warning )
flags = UNKNOWN_WARNING; flags |= UNKNOWN_WARNING;
else if ( a == ATOM_fail ) else if ( a == ATOM_fail )
flags = UNKNOWN_FAIL; flags |= UNKNOWN_FAIL;
else else
{ GET_LD
term_t value = PL_new_term_ref();
PL_put_atom(value, a);
return PL_error(NULL, 0, NULL, ERR_DOMAIN, ATOM_unknown, value); return PL_error(NULL, 0, NULL, ERR_DOMAIN, ATOM_unknown, value);
if ( !(flags&UNKNOWN_ERROR) && (m == MODULE_user || m == MODULE_system) )
{ GET_LD
if ( m == MODULE_system && !SYSTEM_MODE )
{ term_t key = PL_new_term_ref();
PL_put_atom(key, ATOM_unknown);
return PL_error(NULL, 0, NULL, ERR_PERMISSION,
ATOM_modify, ATOM_flag, key);
}
if ( !SYSTEM_MODE )
printMessage(ATOM_warning, PL_CHARS, "unknown_in_module_user");
} }
*flagp &= ~(UNKNOWN_MASK); m->flags = flags;
*flagp |= flags;
succeed; succeed;
} }
@ -308,6 +319,21 @@ setWriteAttributes(atom_t a)
} }
static int
setAccessLevelFromAtom(atom_t a)
{ GET_LD
if ( getAccessLevelMask(a, &LD->prolog_flag.access_level) )
{ succeed;
} else
{ term_t value = PL_new_term_ref();
PL_put_atom(value, a);
return PL_error(NULL, 0, NULL, ERR_DOMAIN, ATOM_access_level, value);
}
}
static int static int
getOccursCheckMask(atom_t a, occurs_check_t *val) getOccursCheckMask(atom_t a, occurs_check_t *val)
{ if ( a == ATOM_false ) { if ( a == ATOM_false )
@ -357,6 +383,30 @@ setEncoding(atom_t a)
} }
static int
setStreamTypeCheck(atom_t a)
{ GET_LD
st_check check;
if ( a == ATOM_false )
check = ST_FALSE;
else if ( a == ATOM_loose )
check = ST_LOOSE;
else if ( a == ATOM_true )
check = ST_TRUE;
else
{ term_t value = PL_new_term_ref();
PL_put_atom(value, a);
return PL_error(NULL, 0, NULL, ERR_DOMAIN, ATOM_stream_type_check, value);
}
LD->IO.stream_type_check = check;
return TRUE;
}
static word static word
set_prolog_flag_unlocked(term_t key, term_t value, int flags) set_prolog_flag_unlocked(term_t key, term_t value, int flags)
{ GET_LD { GET_LD
@ -385,7 +435,7 @@ set_prolog_flag_unlocked(term_t key, term_t value, int flags)
#ifdef O_PLMT #ifdef O_PLMT
if ( GD->statistics.threads_created > 1 ) if ( GD->statistics.threads_created > 1 )
{ prolog_flag *f2 = allocHeap(sizeof(*f2)); { prolog_flag *f2 = allocHeapOrHalt(sizeof(*f2));
*f2 = *f; *f2 = *f;
if ( (f2->flags & FT_MASK) == FT_TERM ) if ( (f2->flags & FT_MASK) == FT_TERM )
@ -399,7 +449,8 @@ set_prolog_flag_unlocked(term_t key, term_t value, int flags)
} }
addHTable(LD->prolog_flag.table, (void *)k, f2); addHTable(LD->prolog_flag.table, (void *)k, f2);
DEBUG(1, Sdprintf("Localised Prolog flag %s\n", PL_atom_chars(k))); DEBUG(MSG_PROLOG_FLAG,
Sdprintf("Localised Prolog flag %s\n", PL_atom_chars(k)));
f = f2; f = f2;
} }
#endif #endif
@ -411,7 +462,7 @@ set_prolog_flag_unlocked(term_t key, term_t value, int flags)
anyway: anyway:
PL_register_atom(k); PL_register_atom(k);
f = allocHeap(sizeof(*f)); f = allocHeapOrHalt(sizeof(*f));
f->index = -1; f->index = -1;
switch( (flags & FT_MASK) ) switch( (flags & FT_MASK) )
@ -437,8 +488,9 @@ set_prolog_flag_unlocked(term_t key, term_t value, int flags)
goto wrong_type; goto wrong_type;
} }
if ( !(f->value.t = PL_record(value)) ) if ( !(f->value.t = PL_record(value)) )
goto wrong_type; { freeHeap(f, sizeof(*f));
f->value.t = PL_record(value); return FALSE;
}
} }
break; break;
} }
@ -483,7 +535,10 @@ set_prolog_flag_unlocked(term_t key, term_t value, int flags)
if ( (flags & FF_READONLY) ) if ( (flags & FF_READONLY) )
f->flags |= FF_READONLY; f->flags |= FF_READONLY;
addHTable(GD->prolog_flag.table, (void *)k, f); if ( !addHTable(GD->prolog_flag.table, (void *)k, f) )
{ freePrologFlag(f);
Sdprintf("OOPS; failed to set Prolog flag!?\n");
}
succeed; succeed;
} else } else
@ -516,9 +571,9 @@ set_prolog_flag_unlocked(term_t key, term_t value, int flags)
#ifndef __YAP_PROLOG__ #ifndef __YAP_PROLOG__
if ( k == ATOM_character_escapes ) if ( k == ATOM_character_escapes )
{ if ( val ) { if ( val )
set(m, CHARESCAPE); set(m, M_CHARESCAPE);
else else
clear(m, CHARESCAPE); clear(m, M_CHARESCAPE);
} else if ( k == ATOM_debug ) } else if ( k == ATOM_debug )
{ if ( val ) { if ( val )
{ debugmode(DBG_ALL, NULL); { debugmode(DBG_ALL, NULL);
@ -551,15 +606,19 @@ set_prolog_flag_unlocked(term_t key, term_t value, int flags)
if ( k == ATOM_double_quotes ) if ( k == ATOM_double_quotes )
{ rval = setDoubleQuotes(a, &m->flags); { rval = setDoubleQuotes(a, &m->flags);
} else if ( k == ATOM_unknown ) } else if ( k == ATOM_unknown )
{ rval = setUnknown(a, &m->flags); { rval = setUnknown(value, a, m);
} else if ( k == ATOM_write_attributes ) } else if ( k == ATOM_write_attributes )
{ rval = setWriteAttributes(a); { rval = setWriteAttributes(a);
} else if ( k == ATOM_occurs_check ) } else if ( k == ATOM_occurs_check )
{ rval = setOccursCheck(a); { rval = setOccursCheck(a);
} else } else if ( k == ATOM_access_level )
{ rval = setAccessLevelFromAtom(a);
} else
#endif #endif
if ( k == ATOM_encoding ) if ( k == ATOM_encoding )
{ rval = setEncoding(a); { rval = setEncoding(a);
} else if ( k == ATOM_stream_type_check )
{ rval = setStreamTypeCheck(a);
} }
if ( !rval ) if ( !rval )
fail; fail;
@ -705,7 +764,7 @@ unify_prolog_flag_value(Module m, atom_t key, prolog_flag *f, term_t val)
#ifndef __YAP_PROLOG__ #ifndef __YAP_PROLOG__
if ( key == ATOM_character_escapes ) if ( key == ATOM_character_escapes )
{ atom_t v = (true(m, CHARESCAPE) ? ATOM_true : ATOM_false); { atom_t v = (true(m, M_CHARESCAPE) ? ATOM_true : ATOM_false);
return PL_unify_atom(val, v); return PL_unify_atom(val, v);
} else if ( key == ATOM_double_quotes ) } else if ( key == ATOM_double_quotes )
@ -736,6 +795,7 @@ unify_prolog_flag_value(Module m, atom_t key, prolog_flag *f, term_t val)
break; break;
default: default:
assert(0); assert(0);
return FALSE;
} }
return PL_unify_atom(val, v); return PL_unify_atom(val, v);
@ -747,6 +807,14 @@ unify_prolog_flag_value(Module m, atom_t key, prolog_flag *f, term_t val)
{ return PL_unify_bool_ex(val, debugstatus.debugging); { return PL_unify_bool_ex(val, debugstatus.debugging);
} else if ( key == ATOM_debugger_show_context ) } else if ( key == ATOM_debugger_show_context )
{ return PL_unify_bool_ex(val, debugstatus.showContext); { return PL_unify_bool_ex(val, debugstatus.showContext);
} else if ( key == ATOM_break_level )
{ int bl = currentBreakLevel();
if ( bl >= 0 )
return PL_unify_integer(val, bl);
return FALSE;
} else if ( key == ATOM_access_level )
{ return PL_unify_atom(val, accessLevel());
} }
#endif /* YAP_PROLOG */ #endif /* YAP_PROLOG */
@ -861,7 +929,7 @@ pl_prolog_flag5(term_t key, term_t value,
fail; fail;
} else if ( PL_is_variable(key) ) } else if ( PL_is_variable(key) )
{ e = allocHeap(sizeof(*e)); { e = allocHeapOrHalt(sizeof(*e));
e->module = module; e->module = module;
@ -965,7 +1033,7 @@ pl_prolog_flag(term_t name, term_t value, control_t h)
#define SO_PATH "LD_LIBRARY_PATH" #define SO_PATH "LD_LIBRARY_PATH"
#endif #endif
void static void
initPrologFlagTable(void) initPrologFlagTable(void)
{ if ( !GD->prolog_flag.table ) { if ( !GD->prolog_flag.table )
{ {
@ -973,7 +1041,7 @@ initPrologFlagTable(void)
initPrologThreads(); /* may be called before PL_initialise() */ initPrologThreads(); /* may be called before PL_initialise() */
#endif #endif
GD->prolog_flag.table = newHTable(32); GD->prolog_flag.table = newHTable(64);
} }
} }
@ -983,7 +1051,7 @@ initPrologFlags(void)
{ GET_LD { GET_LD
#ifndef __YAP_PROLOG__ #ifndef __YAP_PROLOG__
setPrologFlag("iso", FT_BOOL, FALSE, PLFLAG_ISO); setPrologFlag("iso", FT_BOOL, FALSE, PLFLAG_ISO);
setPrologFlag("arch", FT_ATOM|FF_READONLY, ARCH); setPrologFlag("arch", FT_ATOM|FF_READONLY, PLARCH);
#if __WINDOWS__ #if __WINDOWS__
setPrologFlag("windows", FT_BOOL|FF_READONLY, TRUE, 0); setPrologFlag("windows", FT_BOOL|FF_READONLY, TRUE, 0);
#endif #endif
@ -996,12 +1064,17 @@ initPrologFlags(void)
#if defined(HAVE_GETPID) || defined(EMULATE_GETPID) #if defined(HAVE_GETPID) || defined(EMULATE_GETPID)
setPrologFlag("pid", FT_INTEGER|FF_READONLY, getpid()); setPrologFlag("pid", FT_INTEGER|FF_READONLY, getpid());
#endif #endif
setPrologFlag("optimise", FT_BOOL, GD->cmdline.optimise, PLFLAG_OPTIMISE);
setPrologFlag("generate_debug_info", FT_BOOL, setPrologFlag("generate_debug_info", FT_BOOL,
truePrologFlag(PLFLAG_DEBUGINFO), PLFLAG_DEBUGINFO); truePrologFlag(PLFLAG_DEBUGINFO), PLFLAG_DEBUGINFO);
setPrologFlag("last_call_optimisation", FT_BOOL, TRUE, PLFLAG_LASTCALL); setPrologFlag("last_call_optimisation", FT_BOOL, TRUE, PLFLAG_LASTCALL);
setPrologFlag("c_libs", FT_ATOM|FF_READONLY, C_LIBS); setPrologFlag("warn_override_implicit_import", FT_BOOL, TRUE,
setPrologFlag("c_cc", FT_ATOM|FF_READONLY, C_CC); PLFLAG_WARN_OVERRIDE_IMPLICIT_IMPORT);
setPrologFlag("c_ldflags", FT_ATOM|FF_READONLY, C_LDFLAGS); setPrologFlag("c_cc", FT_ATOM, C_CC);
setPrologFlag("c_libs", FT_ATOM, C_LIBS);
setPrologFlag("c_libplso", FT_ATOM, C_LIBPLSO);
setPrologFlag("c_ldflags", FT_ATOM, C_LDFLAGS);
setPrologFlag("c_cflags", FT_ATOM, C_CFLAGS);
#if defined(O_LARGEFILES) || SIZEOF_LONG == 8 #if defined(O_LARGEFILES) || SIZEOF_LONG == 8
setPrologFlag("large_files", FT_BOOL|FF_READONLY, TRUE, 0); setPrologFlag("large_files", FT_BOOL|FF_READONLY, TRUE, 0);
#endif #endif
@ -1041,6 +1114,7 @@ initPrologFlags(void)
setPrologFlag("debug_on_error", FT_BOOL, TRUE, PLFLAG_DEBUG_ON_ERROR); setPrologFlag("debug_on_error", FT_BOOL, TRUE, PLFLAG_DEBUG_ON_ERROR);
setPrologFlag("report_error", FT_BOOL, TRUE, PLFLAG_REPORT_ERROR); setPrologFlag("report_error", FT_BOOL, TRUE, PLFLAG_REPORT_ERROR);
#endif #endif
setPrologFlag("break_level", FT_INTEGER|FF_READONLY, 0, 0);
setPrologFlag("user_flags", FT_ATOM, "silent"); setPrologFlag("user_flags", FT_ATOM, "silent");
setPrologFlag("editor", FT_ATOM, "default"); setPrologFlag("editor", FT_ATOM, "default");
setPrologFlag("debugger_show_context", FT_BOOL, FALSE, 0); setPrologFlag("debugger_show_context", FT_BOOL, FALSE, 0);
@ -1065,28 +1139,39 @@ initPrologFlags(void)
setPrologFlag("integer_rounding_function", FT_ATOM|FF_READONLY, "toward_zero"); setPrologFlag("integer_rounding_function", FT_ATOM|FF_READONLY, "toward_zero");
setPrologFlag("max_arity", FT_ATOM|FF_READONLY, "unbounded"); setPrologFlag("max_arity", FT_ATOM|FF_READONLY, "unbounded");
setPrologFlag("answer_format", FT_ATOM, "~p"); setPrologFlag("answer_format", FT_ATOM, "~p");
setPrologFlag("colon_sets_calling_context", FT_BOOL, TRUE, 0);
setPrologFlag("character_escapes", FT_BOOL, TRUE, PLFLAG_CHARESCAPE); setPrologFlag("character_escapes", FT_BOOL, TRUE, PLFLAG_CHARESCAPE);
setPrologFlag("char_conversion", FT_BOOL, FALSE, PLFLAG_CHARCONVERSION); setPrologFlag("char_conversion", FT_BOOL, FALSE, PLFLAG_CHARCONVERSION);
setPrologFlag("backquoted_string", FT_BOOL, FALSE, PLFLAG_BACKQUOTED_STRING); setPrologFlag("backquoted_string", FT_BOOL, FALSE, PLFLAG_BACKQUOTED_STRING);
setPrologFlag("write_attributes", FT_ATOM, "ignore"); setPrologFlag("write_attributes", FT_ATOM, "ignore");
setPrologFlag("stream_type_check", FT_ATOM, "loose");
setPrologFlag("occurs_check", FT_ATOM, "false"); setPrologFlag("occurs_check", FT_ATOM, "false");
setPrologFlag("access_level", FT_ATOM, "user");
setPrologFlag("double_quotes", FT_ATOM, "codes"); setPrologFlag("double_quotes", FT_ATOM, "codes");
setPrologFlag("unknown", FT_ATOM, "error"); setPrologFlag("unknown", FT_ATOM, "error");
setPrologFlag("debug", FT_BOOL, FALSE, 0); setPrologFlag("debug", FT_BOOL, FALSE, 0);
setPrologFlag("verbose", FT_ATOM|FF_KEEP, GD->options.silent ? "silent" : "normal"); setPrologFlag("verbose", FT_ATOM|FF_KEEP, GD->options.silent ? "silent" : "normal");
setPrologFlag("verbose_load", FT_BOOL, TRUE, 0); setPrologFlag("verbose_load", FT_ATOM, "normal");
setPrologFlag("verbose_autoload", FT_BOOL, FALSE, 0); setPrologFlag("verbose_autoload", FT_BOOL, FALSE, 0);
setPrologFlag("verbose_file_search", FT_BOOL, FALSE, 0); setPrologFlag("verbose_file_search", FT_BOOL, FALSE, 0);
setPrologFlag("allow_variable_name_as_functor", FT_BOOL, FALSE, setPrologFlag("allow_variable_name_as_functor", FT_BOOL, FALSE,
ALLOW_VARNAME_FUNCTOR); ALLOW_VARNAME_FUNCTOR);
setPrologFlag("toplevel_var_size", FT_INTEGER, 1000); setPrologFlag("toplevel_var_size", FT_INTEGER, 1000);
setPrologFlag("toplevel_print_anon", FT_BOOL, TRUE, 0); setPrologFlag("toplevel_print_anon", FT_BOOL, TRUE, 0);
setPrologFlag("toplevel_prompt", FT_ATOM, "~m~d~l~! ?- ");
setPrologFlag("file_name_variables", FT_BOOL, FALSE, PLFLAG_FILEVARS);
setPrologFlag("fileerrors", FT_BOOL, TRUE, PLFLAG_FILEERRORS);
#ifdef __unix__ #ifdef __unix__
setPrologFlag("unix", FT_BOOL|FF_READONLY, TRUE, 0); setPrologFlag("unix", FT_BOOL|FF_READONLY, TRUE, 0);
#endif #endif
setPrologFlag("encoding", FT_ATOM, stringAtom(encoding_to_atom(LD->encoding)));
setPrologFlag("tty_control", FT_BOOL,
truePrologFlag(PLFLAG_TTY_CONTROL), PLFLAG_TTY_CONTROL);
setPrologFlag("signals", FT_BOOL|FF_READONLY, setPrologFlag("signals", FT_BOOL|FF_READONLY,
truePrologFlag(PLFLAG_SIGNALS), PLFLAG_SIGNALS); truePrologFlag(PLFLAG_SIGNALS), PLFLAG_SIGNALS);
setPrologFlag("readline", FT_BOOL/*|FF_READONLY*/, FALSE, 0);
#if defined(__WINDOWS__) && defined(_DEBUG) #if defined(__WINDOWS__) && defined(_DEBUG)
setPrologFlag("kernel_compile_mode", FT_ATOM|FF_READONLY, "debug"); setPrologFlag("kernel_compile_mode", FT_ATOM|FF_READONLY, "debug");
@ -1117,14 +1202,14 @@ initPrologFlags(void)
setTZPrologFlag(); setTZPrologFlag();
#ifndef __YAP_PROLOG__ #ifndef __YAP_PROLOG__
setOSPrologFlags(); setOSPrologFlags();
setVersionPrologFlag();
#endif /* YAP_PROLOG */ #endif /* YAP_PROLOG */
setVersionPrologFlag();
} }
#ifndef __YAP_PROLOG__ #ifndef __YAP_PROLOG__
static void static void
setArgvPrologFlag() setArgvPrologFlag(void)
{ GET_LD { GET_LD
fid_t fid = PL_open_foreign_frame(); fid_t fid = PL_open_foreign_frame();
term_t e = PL_new_term_ref(); term_t e = PL_new_term_ref();
@ -1148,14 +1233,12 @@ setArgvPrologFlag()
#endif #endif
static void static void
setTZPrologFlag() setTZPrologFlag(void)
{ tzset(); { tzset();
setPrologFlag("timezone", FT_INTEGER|FF_READONLY, timezone); setPrologFlag("timezone", FT_INTEGER|FF_READONLY, timezone);
} }
#ifndef __YAP_PROLOG__
static void static void
setVersionPrologFlag(void) setVersionPrologFlag(void)
{ GET_LD { GET_LD
@ -1166,7 +1249,7 @@ setVersionPrologFlag(void)
int patch = (PLVERSION%100); int patch = (PLVERSION%100);
if ( !PL_unify_term(t, if ( !PL_unify_term(t,
PL_FUNCTOR_CHARS, "swi", 4, PL_FUNCTOR_CHARS, PLNAME, 4,
PL_INT, major, PL_INT, major,
PL_INT, minor, PL_INT, minor,
PL_INT, patch, PL_INT, patch,
@ -1178,7 +1261,21 @@ setVersionPrologFlag(void)
setGITVersion(); setGITVersion();
} }
#endif /* YAP_PROLOG */
void
cleanupPrologFlags(void)
{ if ( GD->prolog_flag.table )
{ Table t = GD->prolog_flag.table;
GD->prolog_flag.table = NULL;
#ifdef O_PLMT
t->free_symbol = freeSymbolPrologFlagTable;
#endif
destroyHTable(t);
}
}
/******************************* /*******************************
* PUBLISH PREDICATES * * PUBLISH PREDICATES *
*******************************/ *******************************/

View File

@ -943,7 +943,7 @@ pl_raw_read2(term_t from, term_t term)
int chr; int chr;
PL_chars_t txt; PL_chars_t txt;
if ( !getInputStream(from, &in) ) if ( !getTextInputStream(from, &in) )
fail; fail;
init_read_data(&rd, in PASS_LD); init_read_data(&rd, in PASS_LD);

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -40,12 +40,14 @@ SWI-Prolog.h and SWI-Stream.h
#include "SWI-Stream.h" #include "SWI-Stream.h"
#include "SWI-Prolog.h" #include "SWI-Prolog.h"
#if defined(__WINDOWS__) && !defined(__YAP_PROLOG__) #ifdef __WINDOWS__
#ifndef __YAP_PROLOG__
#ifdef WIN64 #ifdef WIN64
#include "config/win64.h" #include "config/win64.h"
#else #else
#include "config/win32.h" #include "config/win32.h"
#endif #endif
#endif
#else #else
#include <config.h> #include <config.h>
#endif #endif
@ -102,7 +104,6 @@ extern void add_history(char *); /* should be in readline.h */
extern int rl_begin_undo_group(void); /* delete when conflict arrises! */ extern int rl_begin_undo_group(void); /* delete when conflict arrises! */
extern int rl_end_undo_group(void); extern int rl_end_undo_group(void);
extern Function *rl_event_hook; extern Function *rl_event_hook;
#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
#define rl_filename_completion_function filename_completion_function #define rl_filename_completion_function filename_completion_function
extern char *filename_completion_function(const char *, int); extern char *filename_completion_function(const char *, int);
@ -368,7 +369,6 @@ input_on_fd(int fd)
return select(fd+1, &rfds, NULL, NULL, &tv) != 0; return select(fd+1, &rfds, NULL, NULL, &tv) != 0;
} }
static int static int
event_hook(void) event_hook(void)
{ if ( Sinput->position ) { if ( Sinput->position )
@ -487,9 +487,8 @@ Sread_readline(void *handle, char *buf, size_t size)
rl_prep_terminal(FALSE); rl_prep_terminal(FALSE);
rl_readline_state = state; rl_readline_state = state;
rl_done = 0; rl_done = 0;
} else { } else
line = pl_readline(prompt); line = pl_readline(prompt);
}
in_readline--; in_readline--;
if ( my_prompt ) if ( my_prompt )
@ -515,31 +514,26 @@ Sread_readline(void *handle, char *buf, size_t size)
} }
} }
#ifdef HAVE_CLOCK
PL_clock_wait_ticks(clock() - oldclock);
#endif
return rval; return rval;
} }
static int static int
prolog_complete(int ignore, int key) prolog_complete(int ignore, int key)
{ { if ( rl_point > 0 && rl_line_buffer[rl_point-1] != ' ' )
if ( rl_point > 0 && rl_line_buffer[rl_point-1] != ' ' ) { rl_begin_undo_group();
{ rl_begin_undo_group(); rl_complete(ignore, key);
rl_complete(ignore, key); if ( rl_point > 0 && rl_line_buffer[rl_point-1] == ' ' )
if ( rl_point > 0 && rl_line_buffer[rl_point-1] == ' ' ) {
{
#ifdef HAVE_RL_INSERT_CLOSE /* actually version >= 1.2 */ #ifdef HAVE_RL_INSERT_CLOSE /* actually version >= 1.2 */
rl_delete_text(rl_point-1, rl_point); rl_delete_text(rl_point-1, rl_point);
rl_point -= 1; rl_point -= 1;
#else #else
rl_delete(-1, key); rl_delete(-1, key);
#endif #endif
} }
rl_end_undo_group(); rl_end_undo_group();
} else } else
rl_complete(ignore, key); rl_complete(ignore, key);
return 0; return 0;
@ -551,7 +545,12 @@ atom_generator(const char *prefix, int state)
{ char *s = PL_atom_generator(prefix, state); { char *s = PL_atom_generator(prefix, state);
if ( s ) if ( s )
return strcpy(PL_malloc(1 + strlen(s)), s); { char *copy = malloc(1 + strlen(s));
if ( copy ) /* else pretend no completion */
strcpy(copy, s);
s = copy;
}
return s; return s;
} }
@ -574,20 +573,26 @@ prolog_completion(const char *text, int start, int end)
#undef read /* UXNT redefinition */ #undef read /* UXNT redefinition */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
For some obscure reasons, notably libreadline 6 can show very bad
interactive behaviour. There is a timeout set to 100000 (0.1 sec). It
isn't particularly clear what this timeout is doing. I _think_ it should
be synchronized PL_dispatch_hook(), and set to 0 if this hook is
non-null.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
install_t install_t
PL_install_readline(void) PL_install_readline(void)
{ GET_LD { GET_LD
bool old; access_level_t alevel;
#ifndef __WINDOWS__ #ifndef __WINDOWS__
if ( !truePrologFlag(PLFLAG_TTY_CONTROL) || !isatty(0) ) if ( !truePrologFlag(PLFLAG_TTY_CONTROL) || !isatty(0) )
return; return;
#endif #endif
old = systemMode(TRUE); alevel = setAccessLevel(ACCESS_LEVEL_SYSTEM);
#if HAVE_DECL_RL_CATCH_SIGNALS
rl_catch_signals = 0; rl_catch_signals = 0;
#endif
rl_readline_name = "Prolog"; rl_readline_name = "Prolog";
rl_attempted_completion_function = prolog_completion; rl_attempted_completion_function = prolog_completion;
#ifdef __WINDOWS__ #ifdef __WINDOWS__
@ -599,6 +604,9 @@ PL_install_readline(void)
#if HAVE_RL_INSERT_CLOSE #if HAVE_RL_INSERT_CLOSE
rl_add_defun("insert-close", rl_insert_close, ')'); rl_add_defun("insert-close", rl_insert_close, ')');
#endif #endif
#if HAVE_RL_SET_KEYBOARD_INPUT_TIMEOUT /* see (*) */
rl_set_keyboard_input_timeout(20000);
#endif
GD->os.rl_functions = *Sinput->functions; /* structure copy */ GD->os.rl_functions = *Sinput->functions; /* structure copy */
GD->os.rl_functions.read = Sread_readline; /* read through readline */ GD->os.rl_functions.read = Sread_readline; /* read through readline */
@ -607,14 +615,17 @@ PL_install_readline(void)
Soutput->functions = &GD->os.rl_functions; Soutput->functions = &GD->os.rl_functions;
Serror->functions = &GD->os.rl_functions; Serror->functions = &GD->os.rl_functions;
PL_register_foreign("rl_read_init_file", 1, pl_rl_read_init_file, 0); #define PRED(name, arity, func, attr) \
PL_register_foreign("rl_add_history", 1, pl_rl_add_history, PL_FA_NOTRACE); PL_register_foreign_in_module("system", name, arity, func, attr)
PL_register_foreign("rl_write_history", 1, pl_rl_write_history, 0);
PL_register_foreign("rl_read_history", 1, pl_rl_read_history, 0); PRED("rl_read_init_file", 1, pl_rl_read_init_file, 0);
PRED("rl_add_history", 1, pl_rl_add_history, PL_FA_NOTRACE);
PRED("rl_write_history", 1, pl_rl_write_history, 0);
PRED("rl_read_history", 1, pl_rl_read_history, 0);
PL_set_prolog_flag("readline", PL_BOOL, TRUE); PL_set_prolog_flag("readline", PL_BOOL, TRUE);
PL_set_prolog_flag("tty_control", PL_BOOL, TRUE); PL_set_prolog_flag("tty_control", PL_BOOL, TRUE);
PL_license("gpl", "GNU Readline library"); PL_license("gpl", "GNU Readline library");
systemMode(old); setAccessLevel(alevel);
} }
#else /*HAVE_LIBREADLINE*/ #else /*HAVE_LIBREADLINE*/

528
os/pl-stream.c Normal file → Executable file
View File

@ -1,11 +1,10 @@
/* $Id$ /* Part of SWI-Prolog
Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: J.Wielemaker@uva.nl E-mail: J.Wielemaker@vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2009, University of Amsterdam Copyright (C): 1985-2012, University of Amsterdam
VU University Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,21 +18,24 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#if defined(__WINDOWS__)||defined(__WIN32) #if defined(__WINDOWS__)|| defined(__WIN32)
#include <windows/uxnt.h> #include "windows/uxnt.h"
#ifndef _YAP_NOT_INSTALLED_ #ifdef _YAP_NOT_INSTALLED_
#ifdef WIN64 #include <config.h>
#define MD "config/win64.h"
#else #else
#define MD "config/win32.h" #ifdef WIN64
#include "config/win64.h"
#else
#include "config/win32.h"
#endif #endif
#endif #endif
#include <winsock2.h> #include <winsock2.h>
#include "windows/mswchar.h"
#define CRLF_MAPPING 1 #define CRLF_MAPPING 1
#else
#include <config.h>
#endif #endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -48,12 +50,6 @@ recursive locks. If a stream handle might be known to another thread
locking is required. locking is required.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef MD
#include MD
#else
#include <config.h>
#endif
#if _FILE_OFFSET_BITS == 64 || defined(_LARGE_FILES) #if _FILE_OFFSET_BITS == 64 || defined(_LARGE_FILES)
#define O_LARGEFILES 1 /* use for conditional code in Prolog */ #define O_LARGEFILES 1 /* use for conditional code in Prolog */
#else #else
@ -62,8 +58,9 @@ locking is required.
#define PL_KERNEL 1 #define PL_KERNEL 1
#include <wchar.h> #include <wchar.h>
typedef wchar_t pl_wchar_t; #define NEEDS_SWINSOCK
#include "SWI-Stream.h" #include "SWI-Stream.h"
#include "SWI-Prolog.h"
#include "pl-utf8.h" #include "pl-utf8.h"
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
@ -104,7 +101,7 @@ typedef wchar_t pl_wchar_t;
#endif #endif
#define ROUND(p, n) ((((p) + (n) - 1) & ~((n) - 1))) #define ROUND(p, n) ((((p) + (n) - 1) & ~((n) - 1)))
#define UNDO_SIZE ROUND(MB_LEN_MAX, sizeof(wchar_t)) #define UNDO_SIZE ROUND(PL_MB_LEN_MAX, sizeof(wchar_t))
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
@ -127,7 +124,7 @@ static int S__seterror(IOSTREAM *s);
#ifdef O_PLMT #ifdef O_PLMT
#define SLOCK(s) if ( s->mutex ) recursiveMutexLock(s->mutex) #define SLOCK(s) if ( s->mutex ) recursiveMutexLock(s->mutex)
#define SUNLOCK(s) if ( s->mutex ) recursiveMutexUnlock(s->mutex) #define SUNLOCK(s) if ( s->mutex ) recursiveMutexUnlock(s->mutex)
static inline int inline int
STRYLOCK(IOSTREAM *s) STRYLOCK(IOSTREAM *s)
{ if ( s->mutex && { if ( s->mutex &&
recursiveMutexTryLock(s->mutex) == EBUSY ) recursiveMutexTryLock(s->mutex) == EBUSY )
@ -141,13 +138,9 @@ STRYLOCK(IOSTREAM *s)
#define STRYLOCK(s) (TRUE) #define STRYLOCK(s) (TRUE)
#endif #endif
typedef void *record_t;
typedef void *Module;
typedef intptr_t term_t;
typedef intptr_t atom_t;
#include "pl-error.h" #include "pl-error.h"
extern int fatalError(const char *fm, ...); extern int fatalError(const char *fm, ...);
extern int PL_handle_signals(void); extern int PL_handle_signals(void);
extern IOENC initEncoding(void); extern IOENC initEncoding(void);
extern int reportStreamError(IOSTREAM *s); extern int reportStreamError(IOSTREAM *s);
@ -368,6 +361,69 @@ Sunlock(IOSTREAM *s)
} }
/*******************************
* TIMEOUT *
*******************************/
#ifdef HAVE_SELECT
#ifndef __WINDOWS__
typedef int SOCKET;
#define INVALID_SOCKET -1
#define Swinsock(s) Sfileno(s)
#define NFDS(n) (n+1)
#else
#define NFDS(n) (0) /* 1st arg of select is ignored */
#endif
static int
S__wait(IOSTREAM *s)
{ SOCKET fd = Swinsock(s);
fd_set wait;
struct timeval time;
int rc;
if ( fd == INVALID_SOCKET )
{ errno = EPERM; /* no permission to select */
s->flags |= SIO_FERR;
return -1;
}
time.tv_sec = s->timeout / 1000;
time.tv_usec = (s->timeout % 1000) * 1000;
FD_ZERO(&wait);
FD_SET(fd, &wait);
for(;;)
{ if ( (s->flags & SIO_INPUT) )
rc = select(NFDS(fd), &wait, NULL, NULL, &time);
else
rc = select(NFDS(fd), NULL, &wait, NULL, &time);
if ( rc < 0 && errno == EINTR )
{ if ( PL_handle_signals() < 0 )
{ errno = EPLEXCEPTION;
return -1;
}
continue;
}
break;
}
if ( rc == 0 )
{ s->flags |= (SIO_TIMEOUT|SIO_FERR);
return -1;
}
return 0; /* ok, data available */
}
#endif /*HAVE_SELECT*/
/******************************* /*******************************
* FLUSH/FILL * * FLUSH/FILL *
*******************************/ *******************************/
@ -385,7 +441,18 @@ S__flushbuf(IOSTREAM *s)
while ( from < to ) while ( from < to )
{ size_t size = (size_t)(to - from); { size_t size = (size_t)(to - from);
ssize_t n = (*s->functions->write)(s->handle, from, size); ssize_t n;
#ifdef HAVE_SELECT
s->flags &= ~SIO_TIMEOUT;
if ( s->timeout >= 0 )
{ if ( (rc=S__wait(s)) < 0 )
goto partial;
}
#endif
n = (*s->functions->write)(s->handle, from, size);
if ( n > 0 ) /* wrote some */ if ( n > 0 ) /* wrote some */
{ from += n; { from += n;
@ -398,6 +465,9 @@ S__flushbuf(IOSTREAM *s)
} }
} }
#ifdef HAVE_SELECT
partial:
#endif
if ( to == from ) /* full flush */ if ( to == from ) /* full flush */
{ rc = s->bufp - s->buffer; { rc = s->bufp - s->buffer;
s->bufp = s->buffer; s->bufp = s->buffer;
@ -442,52 +512,6 @@ S__flushbufc(int c, IOSTREAM *s)
} }
static int
Swait_for_data(IOSTREAM *s)
{ int fd = Sfileno(s);
fd_set wait;
struct timeval time;
int rc;
if ( fd < 0 )
{ errno = EPERM; /* no permission to select */
s->flags |= SIO_FERR;
return -1;
}
time.tv_sec = s->timeout / 1000;
time.tv_usec = (s->timeout % 1000) * 1000;
FD_ZERO(&wait);
#ifdef __WINDOWS__
FD_SET((SOCKET)fd, &wait);
#else
FD_SET(fd, &wait);
#endif
for(;;)
{ rc = select(fd+1, &wait, NULL, NULL, &time);
if ( rc < 0 && errno == EINTR )
{ if ( PL_handle_signals() < 0 )
{ errno = EPLEXCEPTION;
return -1;
}
continue;
}
break;
}
if ( rc == 0 )
{ s->flags |= (SIO_TIMEOUT|SIO_FERR);
return -1;
}
return 0; /* ok, data available */
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
S__fillbuf() fills the read-buffer, returning the first character of it. S__fillbuf() fills the read-buffer, returning the first character of it.
It also realises the SWI-Prolog timeout facility. It also realises the SWI-Prolog timeout facility.
@ -497,8 +521,11 @@ int
S__fillbuf(IOSTREAM *s) S__fillbuf(IOSTREAM *s)
{ int c; { int c;
if ( s->flags & (SIO_FEOF|SIO_FERR) ) if ( s->flags & (SIO_FEOF|SIO_FERR) ) /* reading past eof */
{ s->flags |= SIO_FEOF2; /* reading past eof */ { if ( s->flags & SIO_FEOF2ERR )
s->flags |= (SIO_FEOF2|SIO_FERR);
else
s->flags |= SIO_FEOF2;
return -1; return -1;
} }
@ -508,7 +535,7 @@ S__fillbuf(IOSTREAM *s)
if ( s->timeout >= 0 && !s->downstream ) if ( s->timeout >= 0 && !s->downstream )
{ int rc; { int rc;
if ( (rc=Swait_for_data(s)) < 0 ) if ( (rc=S__wait(s)) < 0 )
return rc; return rc;
} }
#endif #endif
@ -517,7 +544,8 @@ S__fillbuf(IOSTREAM *s)
{ char chr; { char chr;
ssize_t n; ssize_t n;
if ( (n=(*s->functions->read)(s->handle, &chr, 1)) == 1 ) n = (*s->functions->read)(s->handle, &chr, 1);
if ( n == 1 )
{ c = char_to_int(chr); { c = char_to_int(chr);
return c; return c;
} else if ( n == 0 ) } else if ( n == 0 )
@ -548,7 +576,8 @@ S__fillbuf(IOSTREAM *s)
len = s->bufsize; len = s->bufsize;
} }
if ( (n=(*s->functions->read)(s->handle, s->limitp, len)) > 0 ) n = (*s->functions->read)(s->handle, s->limitp, len);
if ( n > 0 )
{ s->limitp += n; { s->limitp += n;
c = char_to_int(*s->bufp++); c = char_to_int(*s->bufp++);
return c; return c;
@ -777,7 +806,7 @@ put_code(int c, IOSTREAM *s)
} }
goto simple; goto simple;
case ENC_ANSI: case ENC_ANSI:
{ char b[MB_LEN_MAX]; { char b[PL_MB_LEN_MAX];
size_t n; size_t n;
if ( !s->mbstate ) if ( !s->mbstate )
@ -863,7 +892,10 @@ Sputcode(int c, IOSTREAM *s)
if ( s->tee && s->tee->magic == SIO_MAGIC ) if ( s->tee && s->tee->magic == SIO_MAGIC )
Sputcode(c, s->tee); Sputcode(c, s->tee);
if ( c == '\n' && (s->flags&SIO_TEXT) && s->newline == SIO_NL_DOS ) if ( c == '\n' &&
(s->flags&SIO_TEXT) &&
s->newline == SIO_NL_DOS &&
s->lastc != '\r' )
{ if ( put_code('\r', s) < 0 ) { if ( put_code('\r', s) < 0 )
return -1; return -1;
} }
@ -886,7 +918,7 @@ Scanrepresent(int c, IOSTREAM *s)
return -1; return -1;
case ENC_ANSI: case ENC_ANSI:
{ mbstate_t state; { mbstate_t state;
char b[MB_LEN_MAX]; char b[PL_MB_LEN_MAX];
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
if ( wcrtomb(b, (wchar_t)c, &state) != (size_t)-1 ) if ( wcrtomb(b, (wchar_t)c, &state) != (size_t)-1 )
@ -1072,14 +1104,15 @@ returns \n, but it returns the same for a single \n.
Often, we could keep track of bufp and reset this, but we must deal with Often, we could keep track of bufp and reset this, but we must deal with
the case where we fetch a new buffer. In this case, we must copy the few the case where we fetch a new buffer. In this case, we must copy the few
remaining bytes to the `unbuffer' area. remaining bytes to the `unbuffer' area. If SIO_USERBUF is set, we do not
have this spare buffer space. This is used for reading from strings,
which cannot fetch a new buffer anyway.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int int
Speekcode(IOSTREAM *s) Speekcode(IOSTREAM *s)
{ int c; { int c;
char *start; char *start;
IOPOS *psave = s->position;
size_t safe = (size_t)-1; size_t safe = (size_t)-1;
if ( !s->buffer ) if ( !s->buffer )
@ -1094,15 +1127,19 @@ Speekcode(IOSTREAM *s)
if ( (s->flags & SIO_FEOF) ) if ( (s->flags & SIO_FEOF) )
return -1; return -1;
if ( s->bufp + UNDO_SIZE > s->limitp ) if ( s->bufp + UNDO_SIZE > s->limitp && !(s->flags&SIO_USERBUF) )
{ safe = s->limitp - s->bufp; { safe = s->limitp - s->bufp;
memcpy(s->buffer-safe, s->bufp, safe); memcpy(s->buffer-safe, s->bufp, safe);
} }
start = s->bufp; start = s->bufp;
s->position = NULL; if ( s->position )
c = Sgetcode(s); { IOPOS psave = *s->position;
s->position = psave; c = Sgetcode(s);
*s->position = psave;
} else
{ c = Sgetcode(s);
}
if ( Sferror(s) ) if ( Sferror(s) )
return -1; return -1;
@ -1110,7 +1147,7 @@ Speekcode(IOSTREAM *s)
if ( s->bufp > start ) if ( s->bufp > start )
{ s->bufp = start; { s->bufp = start;
} else } else if ( c != -1 )
{ assert(safe != (size_t)-1); { assert(safe != (size_t)-1);
s->bufp = s->buffer-safe; s->bufp = s->buffer-safe;
} }
@ -1341,10 +1378,6 @@ Sfeof(IOSTREAM *s)
return -1; return -1;
} }
if ( s->downstream != NULL &&
Sfeof(s->downstream))
return TRUE;
if ( S__fillbuf(s) == -1 ) if ( S__fillbuf(s) == -1 )
return TRUE; return TRUE;
@ -1440,6 +1473,11 @@ Ssetenc(IOSTREAM *s, IOENC enc, IOENC *old)
} }
s->encoding = enc; s->encoding = enc;
if ( enc == ENC_OCTET )
s->flags &= ~SIO_TEXT;
else
s->flags |= SIO_TEXT;
return 0; return 0;
} }
@ -1490,23 +1528,23 @@ Sunit_size(IOSTREAM *s)
Return the size of the underlying data object. Should be optimized; Return the size of the underlying data object. Should be optimized;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
long int64_t
Ssize(IOSTREAM *s) Ssize(IOSTREAM *s)
{ if ( s->functions->control ) { if ( s->functions->control )
{ long size; { int64_t size;
if ( (*s->functions->control)(s->handle, SIO_GETSIZE, (void *)&size) == 0 ) if ( (*s->functions->control)(s->handle, SIO_GETSIZE, (void *)&size) == 0 )
return size; return size;
} }
if ( s->functions->seek ) if ( s->functions->seek )
{ long here = Stell(s); { int64_t here = Stell64(s);
long end; int64_t end;
if ( Sseek(s, 0, SIO_SEEK_END) == 0 ) if ( Sseek64(s, 0, SIO_SEEK_END) == 0 )
end = Stell(s); end = Stell64(s);
else else
end = -1; end = -1;
Sseek(s, here, SIO_SEEK_SET); Sseek64(s, here, SIO_SEEK_SET);
return end; return end;
} }
@ -1667,13 +1705,13 @@ unallocStream(IOSTREAM *s)
#ifdef O_PLMT #ifdef O_PLMT
if ( s->mutex ) if ( s->mutex )
{ recursiveMutexDelete(s->mutex); { recursiveMutexDelete(s->mutex);
free(s->mutex); PL_free(s->mutex);
s->mutex = NULL; s->mutex = NULL;
} }
#endif #endif
if ( !(s->flags & SIO_STATIC) ) if ( !(s->flags & SIO_STATIC) )
free(s); PL_free(s);
} }
@ -1711,7 +1749,7 @@ Sclose(IOSTREAM *s)
#ifdef __WINDOWS__ #ifdef __WINDOWS__
if ( (s->flags & SIO_ADVLOCK) ) if ( (s->flags & SIO_ADVLOCK) )
{ OVERLAPPED ov; { OVERLAPPED ov;
HANDLE h = (HANDLE)_get_osfhandle((int)s->handle); HANDLE h = (HANDLE)_get_osfhandle((int)((uintptr_t)s->handle));
memset(&ov, 0, sizeof(ov)); memset(&ov, 0, sizeof(ov));
UnlockFileEx(h, 0, 0, 0xffffffff, &ov); UnlockFileEx(h, 0, 0, 0xffffffff, &ov);
@ -1732,9 +1770,9 @@ Sclose(IOSTREAM *s)
if ( rval < 0 ) if ( rval < 0 )
reportStreamError(s); reportStreamError(s);
run_close_hooks(s); /* deletes Prolog registration */ run_close_hooks(s); /* deletes Prolog registration */
s->magic = SIO_CMAGIC;
SUNLOCK(s); SUNLOCK(s);
s->magic = SIO_CMAGIC;
if ( s->message ) if ( s->message )
free(s->message); free(s->message);
if ( s->references == 0 ) if ( s->references == 0 )
@ -1845,11 +1883,23 @@ Svprintf(const char *fm, va_list args)
} }
#define NEXTCHR(s, c) if ( utf8 ) \ #define NEXTCHR(s, c) \
{ (s) = utf8_get_char((s), &(c)); \ switch (enc) \
} else \ { case ENC_ANSI: \
{ c = *(s)++; c &= 0xff; \ c = *(s)++; c &= 0xff; \
} break; \
case ENC_UTF8: \
(s) = utf8_get_char((s), &(c)); \
break; \
case ENC_WCHAR: \
{ wchar_t *_w = (wchar_t*)(s); \
c = *_w++; \
(s) = (char*)_w; \
break; \
} \
default: \
break; \
}
#define OUTCHR(s, c) do { printed++; \ #define OUTCHR(s, c) do { printed++; \
if ( Sputcode((c), (s)) < 0 ) goto error; \ if ( Sputcode((c), (s)) < 0 ) goto error; \
@ -1911,7 +1961,7 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
char fbuf[100], *fs = fbuf, *fe = fbuf; char fbuf[100], *fs = fbuf, *fe = fbuf;
int islong = 0; int islong = 0;
int pad = ' '; int pad = ' ';
int utf8 = FALSE; IOENC enc = ENC_ANSI;
for(;;) for(;;)
{ switch(*fm) { switch(*fm)
@ -1952,13 +2002,19 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
{ islong++; /* 1: %ld */ { islong++; /* 1: %ld */
fm++; fm++;
} }
if ( *fm == 'l' ) switch ( *fm )
{ islong++; /* 2: %lld */ { case 'l':
fm++; islong++; /* 2: %lld */
} fm++;
if ( *fm == 'U' ) /* %Us: UTF-8 string */ break;
{ utf8 = TRUE; case 'U': /* %Us: UTF-8 string */
fm++; enc = ENC_UTF8;
fm++;
break;
case 'W': /* %Ws: wide string */
enc = ENC_WCHAR;
fm++;
break;
} }
switch(*fm) switch(*fm)
@ -1983,41 +2039,53 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
case 'u': case 'u':
case 'x': case 'x':
case 'X': case 'X':
{ intptr_t v = 0; /* make compiler silent */ { int vi = 0;
int64_t vl = 0; long vl = 0; /* make compiler silent */
int64_t vll = 0;
char fmbuf[8], *fp=fmbuf; char fmbuf[8], *fp=fmbuf;
switch( islong ) switch( islong )
{ case 0: { case 0:
v = va_arg(args, int); vi = va_arg(args, int);
break; break;
case 1: case 1:
v = va_arg(args, long); vl = va_arg(args, long);
break; break;
case 2: case 2:
vl = va_arg(args, int64_t); vll = va_arg(args, int64_t);
break; break;
default:
assert(0);
} }
*fp++ = '%'; *fp++ = '%';
if ( modified ) if ( modified )
*fp++ = '#'; *fp++ = '#';
*fp++ = 'l'; switch( islong )
if ( islong < 2 ) { case 0:
{ *fp++ = *fm; *fp++ = *fm;
*fp = '\0'; *fp = '\0';
SNPRINTF3(fmbuf, v); SNPRINTF3(fmbuf, vi);
} else break;
{ case 1:
*fp++ = 'l';
*fp++ = *fm;
*fp = '\0';
SNPRINTF3(fmbuf, vl);
break;
case 2:
#ifdef __WINDOWS__ #ifdef __WINDOWS__
strcat(fp-1, "I64"); /* Synchronise with INT64_FORMAT! */ *fp++ = 'I'; /* Synchronise with INT64_FORMAT! */
fp += strlen(fp); *fp++ = '6';
*fp++ = '4';
#else #else
*fp++ = 'l'; *fp++ = 'l';
*fp++ = 'l';
#endif #endif
*fp++ = *fm; *fp++ = *fm;
*fp = '\0'; *fp = '\0';
SNPRINTF3(fmbuf, vl); SNPRINTF3(fmbuf, vll);
break;
} }
break; break;
@ -2075,12 +2143,25 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
{ size_t w; { size_t w;
if ( fs == fbuf ) if ( fs == fbuf )
w = fe - fs; { w = fe - fs;
else } else
w = strlen(fs); { switch(enc)
{ case ENC_ANSI:
if ( utf8 ) w = strlen(fs);
w = utf8_strlen(fs, w); break;
case ENC_UTF8:
w = strlen(fs);
w = utf8_strlen(fs, w);
break;
case ENC_WCHAR:
w = wcslen((wchar_t*)fs);
break;
default:
assert(0);
w = 0; /* make compiler happy */
break;
}
}
if ( (ssize_t)w < arg1 ) if ( (ssize_t)w < arg1 )
{ w = arg1 - w; { w = arg1 - w;
@ -2609,7 +2690,7 @@ Scontrol_file(void *handle, int action, void *arg)
switch(action) switch(action)
{ case SIO_GETSIZE: { case SIO_GETSIZE:
{ intptr_t *rval = arg; { int64_t *rval = arg;
struct stat buf; struct stat buf;
if ( fstat(fd, &buf) == 0 ) if ( fstat(fd, &buf) == 0 )
@ -2621,6 +2702,11 @@ Scontrol_file(void *handle, int action, void *arg)
case SIO_SETENCODING: case SIO_SETENCODING:
case SIO_FLUSHOUTPUT: case SIO_FLUSHOUTPUT:
return 0; return 0;
case SIO_GETFILENO:
{ int *p = arg;
*p = fd;
return 0;
}
default: default:
return -1; return -1;
} }
@ -2662,13 +2748,20 @@ provide the socket-id through Sfileno, this code crashes on
tcp_open_socket(). As ttys and its detection is of no value on Windows tcp_open_socket(). As ttys and its detection is of no value on Windows
anyway, we skip this. Second, Windows doesn't have fork(), so FD_CLOEXEC anyway, we skip this. Second, Windows doesn't have fork(), so FD_CLOEXEC
is of no value. is of no value.
For now, we use PL_malloc_uncollectable(). In the end, this is really
one of the object-types we want to leave to GC.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FD_CLOEXEC /* This is not defined in MacOS */
#define FD_CLOEXEC 1
#endif
IOSTREAM * IOSTREAM *
Snew(void *handle, int flags, IOFUNCTIONS *functions) Snew(void *handle, int flags, IOFUNCTIONS *functions)
{ IOSTREAM *s; { IOSTREAM *s;
if ( !(s = malloc(sizeof(IOSTREAM))) ) if ( !(s = PL_malloc_uncollectable(sizeof(IOSTREAM))) )
{ errno = ENOMEM; { errno = ENOMEM;
return NULL; return NULL;
} }
@ -2680,7 +2773,11 @@ Snew(void *handle, int flags, IOFUNCTIONS *functions)
s->functions = functions; s->functions = functions;
s->timeout = -1; /* infinite */ s->timeout = -1; /* infinite */
s->posbuf.lineno = 1; s->posbuf.lineno = 1;
s->encoding = ENC_ISO_LATIN_1; if ( (flags&SIO_TEXT) )
{ s->encoding = initEncoding();
} else
{ s->encoding = ENC_OCTET;
}
#if CRLF_MAPPING #if CRLF_MAPPING
s->newline = SIO_NL_DOS; s->newline = SIO_NL_DOS;
#endif #endif
@ -2688,8 +2785,8 @@ Snew(void *handle, int flags, IOFUNCTIONS *functions)
s->position = &s->posbuf; s->position = &s->posbuf;
#ifdef O_PLMT #ifdef O_PLMT
if ( !(flags & SIO_NOMUTEX) ) if ( !(flags & SIO_NOMUTEX) )
{ if ( !(s->mutex = malloc(sizeof(recursiveMutex))) ) { if ( !(s->mutex = PL_malloc(sizeof(recursiveMutex))) )
{ free(s); { PL_free(s);
return NULL; return NULL;
} }
recursiveMutexInit(s->mutex); recursiveMutexInit(s->mutex);
@ -2701,7 +2798,7 @@ Snew(void *handle, int flags, IOFUNCTIONS *functions)
if ( (fd = Sfileno(s)) >= 0 ) if ( (fd = Sfileno(s)) >= 0 )
{ if ( isatty(fd) ) { if ( isatty(fd) )
s->flags |= SIO_ISATTY; s->flags |= SIO_ISATTY;
#if defined(F_SETFD) && defined(FD_CLOEXEC) #ifdef F_SETFD
fcntl(fd, F_SETFD, FD_CLOEXEC); fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif #endif
} }
@ -2804,13 +2901,23 @@ Sopen_file(const char *path, const char *how)
struct flock buf; struct flock buf;
memset(&buf, 0, sizeof(buf)); memset(&buf, 0, sizeof(buf));
buf.l_type = (lock == lread ? F_RDLCK : F_WRLCK); buf.l_whence = SEEK_SET;
buf.l_type = (lock == lread ? F_RDLCK : F_WRLCK);
if ( fcntl(fd, wait ? F_SETLKW : F_SETLK, &buf) < 0 ) while( fcntl(fd, wait ? F_SETLKW : F_SETLK, &buf) != 0 )
{ int save = errno; { if ( errno == EINTR )
close(fd); { if ( PL_handle_signals() < 0 )
errno = save; { close(fd);
return NULL; return NULL;
}
continue;
} else
{ int save = errno;
close(fd);
errno = save;
return NULL;
}
} }
#else /* we don't have locking */ #else /* we don't have locking */
#if __WINDOWS__ #if __WINDOWS__
@ -2891,12 +2998,10 @@ Sfileno(IOSTREAM *s)
if ( s->flags & SIO_FILE ) if ( s->flags & SIO_FILE )
{ intptr_t h = (intptr_t)s->handle; { intptr_t h = (intptr_t)s->handle;
n = (int)h; n = (int)h;
} else if ( s->flags & SIO_PIPE )
{ n = fileno((FILE *)s->handle);
} else if ( s->functions->control && } else if ( s->functions->control &&
(*s->functions->control)(s->handle, (*s->functions->control)(s->handle,
SIO_GETFILENO, SIO_GETFILENO,
(void *)&n) == 0 ) (void *)&n) == 0 )
{ ; { ;
} else } else
{ errno = EINVAL; { errno = EINVAL;
@ -2907,6 +3012,30 @@ Sfileno(IOSTREAM *s)
} }
#ifdef __WINDOWS__
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
On Windows, type SOCKET is an unsigned int and all values
[0..INVALID_SOCKET) are valid. It is also not allowed to run normal
file-functions on it or the application will crash. There seems to be no
way out except for introducing an extra function at this level :-(
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
SOCKET
Swinsock(IOSTREAM *s)
{ SOCKET n = INVALID_SOCKET;
if ( s->functions->control &&
(*s->functions->control)(s->handle,
SIO_GETWINSOCK,
(void *)&n) == 0 )
{ return n;
}
errno = EINVAL;
return INVALID_SOCKET;
}
#endif
/******************************* /*******************************
* PIPES * * PIPES *
*******************************/ *******************************/
@ -2915,13 +3044,9 @@ Sfileno(IOSTREAM *s)
#ifdef __WINDOWS__ #ifdef __WINDOWS__
#include "windows/popen.c" #include "windows/popen.c"
#ifdef popen
#undef popen #undef popen
#endif
#define popen(cmd, how) pt_popen(cmd, how)
#ifdef pclose
#undef pclose #undef pclose
#endif #define popen(cmd, how) pt_popen(cmd, how)
#define pclose(fd) pt_pclose(fd) #define pclose(fd) pt_pclose(fd)
#endif #endif
@ -2958,11 +3083,31 @@ Sclose_pipe(void *handle)
} }
static int
Scontrol_pipe(void *handle, int action, void *arg)
{ FILE *fp = handle;
switch(action)
{ case SIO_GETFILENO:
{ int *ap = arg;
*ap = fileno(fp);
return 0;
}
case SIO_FLUSHOUTPUT:
case SIO_SETENCODING:
return 0;
default:
return -1;
}
}
IOFUNCTIONS Spipefunctions = IOFUNCTIONS Spipefunctions =
{ Sread_pipe, { Sread_pipe,
Swrite_pipe, Swrite_pipe,
(Sseek_function)0, (Sseek_function)0,
Sclose_pipe Sclose_pipe,
Scontrol_pipe
}; };
@ -2983,9 +3128,9 @@ Sopen_pipe(const char *command, const char *type)
{ int flags; { int flags;
if ( *type == 'r' ) if ( *type == 'r' )
flags = SIO_PIPE|SIO_INPUT|SIO_FBUF; flags = SIO_INPUT|SIO_FBUF;
else else
flags = SIO_PIPE|SIO_OUTPUT|SIO_FBUF; flags = SIO_OUTPUT|SIO_FBUF;
return Snew((void *)fd, flags, &Spipefunctions); return Snew((void *)fd, flags, &Spipefunctions);
} }
@ -3229,12 +3374,20 @@ Sopenmem(char **buffer, size_t *sizep, const char *mode)
static ssize_t static ssize_t
Sread_string(void *handle, char *buf, size_t size) Sread_string(void *handle, char *buf, size_t size)
{ return 0; /* signal EOF */ { (void)handle;
(void)buf;
(void)size;
return 0; /* signal EOF */
} }
static ssize_t static ssize_t
Swrite_string(void *handle, char *buf, size_t size) Swrite_string(void *handle, char *buf, size_t size)
{ errno = ENOSPC; /* signal error */ { (void)handle;
(void)buf;
(void)size;
errno = ENOSPC; /* signal error */
return -1; return -1;
} }
@ -3267,7 +3420,7 @@ Sopen_string(IOSTREAM *s, char *buf, size_t size, const char *mode)
{ int flags = SIO_FBUF|SIO_USERBUF; { int flags = SIO_FBUF|SIO_USERBUF;
if ( !s ) if ( !s )
{ if ( !(s = malloc(sizeof(IOSTREAM))) ) { if ( !(s = PL_malloc_uncollectable(sizeof(IOSTREAM))) ) /* TBD: Use GC */
{ errno = ENOMEM; { errno = ENOMEM;
return NULL; return NULL;
} }
@ -3310,7 +3463,7 @@ Sopen_string(IOSTREAM *s, char *buf, size_t size, const char *mode)
#define STDIO(n, f) { NULL, NULL, NULL, NULL, \ #define STDIO(n, f) { NULL, NULL, NULL, NULL, \
EOF, SIO_MAGIC, 0, f, {0, 0, 0}, NULL, \ EOF, SIO_MAGIC, 0, f, {0, 0, 0}, NULL, \
((void *)(n)), &Sttyfunctions, \ (void *)(n), &Sttyfunctions, \
0, NULL, \ 0, NULL, \
(void (*)(void *))0, NULL, \ (void (*)(void *))0, NULL, \
-1, \ -1, \
@ -3321,7 +3474,7 @@ Sopen_string(IOSTREAM *s, char *buf, size_t size, const char *mode)
#define SIO_STDIO (SIO_FILE|SIO_STATIC|SIO_NOCLOSE|SIO_ISATTY|SIO_TEXT) #define SIO_STDIO (SIO_FILE|SIO_STATIC|SIO_NOCLOSE|SIO_ISATTY|SIO_TEXT)
#define STDIO_STREAMS \ #define STDIO_STREAMS \
STDIO(0, SIO_STDIO|SIO_LBUF|SIO_INPUT|SIO_NOFEOF), /* Sinput */ \ STDIO(0, SIO_STDIO|SIO_LBUF|SIO_INPUT|SIO_NOFEOF), /* Sinput */ \
STDIO(1, SIO_STDIO|SIO_LBUF|SIO_OUTPUT|SIO_REPPL), /* Soutput */ \ STDIO(1, SIO_STDIO|SIO_LBUF|SIO_OUTPUT|SIO_REPPL), /* Soutput */ \
STDIO(2, SIO_STDIO|SIO_NBUF|SIO_OUTPUT|SIO_REPPL) /* Serror */ STDIO(2, SIO_STDIO|SIO_NBUF|SIO_OUTPUT|SIO_REPPL) /* Serror */
@ -3335,31 +3488,33 @@ static const IOSTREAM S__iob0[] =
}; };
/* vsc: Scleanup should reset init done */ static int S__initialised = FALSE;
static int done;
void void
SinitStreams(void) SinitStreams(void)
{ { if ( !S__initialised )
if ( !done++ )
{ int i; { int i;
IOENC enc = initEncoding(); IOENC enc;
S__initialised = TRUE;
enc = initEncoding();
for(i=0; i<=2; i++) for(i=0; i<=2; i++)
{ if ( !isatty(i) ) { IOSTREAM *s = &S__iob[i];
{ S__iob[i].flags &= ~SIO_ISATTY;
S__iob[i].functions = &Sfilefunctions; /* Check for pipe? */ if ( !isatty(i) )
{ s->flags &= ~SIO_ISATTY;
s->functions = &Sfilefunctions; /* Check for pipe? */
} }
if ( S__iob[i].encoding == ENC_ISO_LATIN_1 ) if ( s->encoding == ENC_ISO_LATIN_1 )
S__iob[i].encoding = enc; s->encoding = enc;
#ifdef O_PLMT #ifdef O_PLMT
S__iob[i].mutex = malloc(sizeof(recursiveMutex)); s->mutex = PL_malloc(sizeof(recursiveMutex));
recursiveMutexInit(S__iob[i].mutex); recursiveMutexInit(s->mutex);
#endif #endif
#if CRLF_MAPPING #if CRLF_MAPPING
_setmode(i, O_BINARY); _setmode(i, O_BINARY);
S__iob[i].newline = SIO_NL_DOS; s->newline = SIO_NL_DOS;
#endif #endif
} }
@ -3371,7 +3526,7 @@ SinitStreams(void)
IOSTREAM * IOSTREAM *
S__getiob() S__getiob(void)
{ return S__iob; { return S__iob;
} }
@ -3461,11 +3616,12 @@ Scleanup(void)
S__iob[i].mutex = NULL; S__iob[i].mutex = NULL;
recursiveMutexDelete(m); recursiveMutexDelete(m);
free(m); PL_free(m);
} }
#endif #endif
*s = S__iob0[i]; /* re-initialise */ *s = S__iob0[i]; /* re-initialise */
} }
done = 0;
S__initialised = FALSE;
} }

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "pl-incl.h" #include "pl-incl.h"
@ -34,45 +34,10 @@ String operations that are needed for the shared IO library.
* ALLOCATION * * ALLOCATION *
*******************************/ *******************************/
#ifdef O_DEBUG
#define CHAR_INUSE 0x42
#define CHAR_FREED 0x41
char * char *
store_string(const char *s) store_string(const char *s)
{ if ( s ) { if ( s )
{ GET_LD { char *copy = (char *)allocHeapOrHalt(strlen(s)+1);
char *copy = (char *)allocHeap(strlen(s)+2);
*copy++ = CHAR_INUSE;
strcpy(copy, s);
return copy;
} else
{ return NULL;
}
}
void
remove_string(char *s)
{ if ( s )
{ GET_LD
assert(s[-1] == CHAR_INUSE);
s[-1] = CHAR_FREED;
freeHeap(s-1, strlen(s)+2);
}
}
#else /*O_DEBUG*/
char *
store_string(const char *s)
{ if ( s )
{ GET_LD
char *copy = (char *)allocHeap(strlen(s)+1);
strcpy(copy, s); strcpy(copy, s);
return copy; return copy;
@ -85,14 +50,9 @@ store_string(const char *s)
void void
remove_string(char *s) remove_string(char *s)
{ if ( s ) { if ( s )
{ GET_LD
freeHeap(s, strlen(s)+1); freeHeap(s, strlen(s)+1);
}
} }
#endif /*O_DEBUG*/
/******************************* /*******************************
* NUMBERS * * NUMBERS *
*******************************/ *******************************/
@ -239,13 +199,13 @@ int_mbscoll(const char *s1, const char *s2, int icase)
if ( l1 < 1024 && (w1 = alloca(sizeof(wchar_t)*(l1+1))) ) if ( l1 < 1024 && (w1 = alloca(sizeof(wchar_t)*(l1+1))) )
{ ml1 = FALSE; { ml1 = FALSE;
} else } else
{ w1 = PL_malloc(sizeof(wchar_t)*(l1+1)); { w1 = PL_malloc_atomic(sizeof(wchar_t)*(l1+1));
ml1 = TRUE; ml1 = TRUE;
} }
if ( l2 < 1024 && (w2 = alloca(sizeof(wchar_t)*(l2+1))) ) if ( l2 < 1024 && (w2 = alloca(sizeof(wchar_t)*(l2+1))) )
{ ml2 = FALSE; { ml2 = FALSE;
} else } else
{ w2 = PL_malloc(sizeof(wchar_t)*(l2+1)); { w2 = PL_malloc_atomic(sizeof(wchar_t)*(l2+1));
ml2 = TRUE; ml2 = TRUE;
} }

4
os/pl-string.h Normal file → Executable file
View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef PL_STRING_H_INCLUDED #ifndef PL_STRING_H_INCLUDED
@ -27,7 +27,7 @@
COMMON(char *) store_string(const char *s); COMMON(char *) store_string(const char *s);
COMMON(void) remove_string(char *s); COMMON(void) remove_string(char *s);
COMMON(char) digitName(int n, int smll); //COMMON(char) digitName(int n, int small);
COMMON(int) digitValue(int b, int c); COMMON(int) digitValue(int b, int c);
COMMON(bool) strprefix(const char *string, const char *prefix); COMMON(bool) strprefix(const char *string, const char *prefix);
COMMON(bool) strpostfix(const char *string, const char *postfix); COMMON(bool) strpostfix(const char *string, const char *postfix);

View File

@ -1,11 +1,10 @@
/* $Id$ /* Part of SWI-Prolog
Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl E-mail: J.Wielemaker@vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam Copyright (C): 1985-2012, University of Amsterdam
VU University Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/*#define O_DEBUG 1*/ /*#define O_DEBUG 1*/
@ -41,35 +40,35 @@ create, advance over and destroy enumerator objects. These objects are
used to enumerate the symbols of these tables, used primarily for the used to enumerate the symbols of these tables, used primarily for the
pl_current_* predicates. pl_current_* predicates.
The enumerators cause two things: (1) as intptr_t enumerators are The enumerators cause two things: (1) as long as enumerators are
associated, the table will not be rehashed and (2) if symbols are associated, the table will not be rehashed and (2) if symbols are
deleted that are referenced by an enumerator, the enumerator is deleted that are referenced by an enumerator, the enumerator is
automatically advanced to the next free symbol. This, in general, makes automatically advanced to the next free symbol. This, in general, makes
the enumeration of hash-tables safe. the enumeration of hash-tables safe.
TODO: abort should delete any pending enumerators. This should be TBD: Resizing hash-tables causes major headaches for concurrent access.
thread-local, as thread_exit/1 should do the same. We can avoid this by using a dynamic array for the list of hash-entries.
Ongoing work in the RDF store shows hash-tables that can handle
concurrent lock-free access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static void static Symbol *
allocHTableEntries(Table ht) allocHTableEntries(int buckets)
{ GET_LD { size_t bytes = buckets * sizeof(Symbol);
int n;
Symbol *p; Symbol *p;
ht->entries = allocHeap(ht->buckets * sizeof(Symbol)); p = allocHeapOrHalt(bytes);
memset(p, 0, bytes);
for(n=0, p = &ht->entries[0]; n < ht->buckets; n++, p++) return p;
*p = NULL;
} }
Table Table
newHTable(int buckets) newHTable(int buckets)
{ GET_LD { Table ht;
Table ht;
ht = allocHeap(sizeof(struct table)); ht = allocHeapOrHalt(sizeof(struct table));
ht->buckets = (buckets & ~TABLE_MASK); ht->buckets = (buckets & ~TABLE_MASK);
ht->size = 0; ht->size = 0;
ht->enumerators = NULL; ht->enumerators = NULL;
@ -79,25 +78,24 @@ newHTable(int buckets)
if ( (buckets & TABLE_UNLOCKED) ) if ( (buckets & TABLE_UNLOCKED) )
ht->mutex = NULL; ht->mutex = NULL;
else else
{ ht->mutex = allocHeap(sizeof(simpleMutex)); { ht->mutex = allocHeapOrHalt(sizeof(simpleMutex));
simpleMutexInit(ht->mutex); simpleMutexInit(ht->mutex);
} }
#endif #endif
allocHTableEntries(ht); ht->entries = allocHTableEntries(ht->buckets);
return ht; return ht;
} }
void void
destroyHTable(Table ht) destroyHTable(Table ht)
{ GET_LD {
#ifdef O_PLMT #ifdef O_PLMT
if ( ht->mutex ) if ( ht->mutex )
{ simpleMutexDelete(ht->mutex); { simpleMutexDelete(ht->mutex);
freeHeap(ht->mutex, sizeof(*ht->mutex)); freeHeap(ht->mutex, sizeof(*ht->mutex));
ht->mutex = NULL; ht->mutex = NULL;
} }
#endif #endif
@ -107,19 +105,19 @@ destroyHTable(Table ht)
} }
#if O_DEBUG || O_HASHSTAT #if O_DEBUG
#define HASHSTAT(c) c
static int lookups; static int lookups;
static int cmps; static int cmps;
void void
exitTables(int status, void *arg) exitTables(int status, void *arg)
{ Sdprintf("hashstat: Anonymous tables: %d lookups using %d compares\n", { (void)status;
(void)arg;
Sdprintf("hashstat: Anonymous tables: %d lookups using %d compares\n",
lookups, cmps); lookups, cmps);
} }
#else #endif
#define HASHSTAT(c)
#endif /*O_DEBUG*/
void void
@ -129,7 +127,7 @@ initTables(void)
if ( !done ) if ( !done )
{ done = TRUE; { done = TRUE;
HASHSTAT(PL_on_halt(exitTables, NULL)); DEBUG(MSG_HASH_STAT, PL_on_halt(exitTables, NULL));
} }
} }
@ -138,9 +136,9 @@ Symbol
lookupHTable(Table ht, void *name) lookupHTable(Table ht, void *name)
{ Symbol s = ht->entries[pointerHashValue(name, ht->buckets)]; { Symbol s = ht->entries[pointerHashValue(name, ht->buckets)];
HASHSTAT(lookups++); DEBUG(MSG_HASH_STAT, lookups++);
for( ; s; s = s->next) for( ; s; s = s->next)
{ HASHSTAT(cmps++); { DEBUG(MSG_HASH_STAT, cmps++);
if ( s->name == name ) if ( s->name == name )
return s; return s;
} }
@ -170,41 +168,79 @@ checkHTable(Table ht)
/* MT: Locked by calling addHTable() /* MT: Locked by calling addHTable()
*/ */
static void static Symbol
rehashHTable(Table ht) rehashHTable(Table ht, Symbol map)
{ GET_LD { Symbol *newentries, *oldentries;
Symbol *oldtab; int newbuckets, oldbuckets;
int oldbucks; int i;
int i; #ifdef O_PLMT
int safe_copy = (ht->mutex != NULL);
#else
int safe_copy = TRUE;
#endif
oldtab = ht->entries; newbuckets = ht->buckets*2;
oldbucks = ht->buckets; newentries = allocHTableEntries(newbuckets);
ht->buckets *= 2;
allocHTableEntries(ht);
DEBUG(1, Sdprintf("Rehashing table %p to %d entries\n", ht, ht->buckets)); DEBUG(MSG_HASH_STAT,
Sdprintf("Rehashing table %p to %d entries\n", ht, ht->buckets));
for(i=0; i<oldbucks; i++) for(i=0; i<ht->buckets; i++)
{ Symbol s, n; { Symbol s, n;
for(s=oldtab[i]; s; s = n) if ( safe_copy )
{ int v = (int)pointerHashValue(s->name, ht->buckets); { for(s=ht->entries[i]; s; s = n)
{ int v = (int)pointerHashValue(s->name, newbuckets);
Symbol s2 = allocHeapOrHalt(sizeof(*s2));
n = s->next; n = s->next;
s->next = ht->entries[v]; if ( s == map )
ht->entries[v] = s; map = s2;
*s2 = *s;
s2->next = newentries[v];
newentries[v] = s2;
}
} else
{ for(s=ht->entries[i]; s; s = n)
{ int v = (int)pointerHashValue(s->name, newbuckets);
n = s->next;
s->next = newentries[v];
newentries[v] = s;
}
} }
} }
freeHeap(oldtab, oldbucks * sizeof(Symbol)); oldentries = ht->entries;
DEBUG(0, checkHTable(ht)); oldbuckets = ht->buckets;
ht->entries = newentries;
ht->buckets = newbuckets;
if ( safe_copy )
{ /* Here we should be waiting until */
/* active lookup are finished */
for(i=0; i<oldbuckets; i++)
{ Symbol s, n;
for(s=oldentries[i]; s; s = n)
{ n = s->next;
s->next = NULL; /* that causes old readers to stop */
freeHeap(s, sizeof(*s));
}
}
}
freeHeap(oldentries, oldbuckets * sizeof(Symbol));
DEBUG(CHK_SECURE, checkHTable(ht));
return map;
} }
Symbol Symbol
addHTable(Table ht, void *name, void *value) addHTable(Table ht, void *name, void *value)
{ GET_LD { Symbol s;
Symbol s;
int v; int v;
LOCK_TABLE(ht); LOCK_TABLE(ht);
@ -213,7 +249,7 @@ addHTable(Table ht, void *name, void *value)
{ UNLOCK_TABLE(ht); { UNLOCK_TABLE(ht);
return NULL; return NULL;
} }
s = allocHeap(sizeof(struct symbol)); s = allocHeapOrHalt(sizeof(struct symbol));
s->name = name; s->name = name;
s->value = value; s->value = value;
s->next = ht->entries[v]; s->next = ht->entries[v];
@ -223,7 +259,7 @@ addHTable(Table ht, void *name, void *value)
ht, name, value, ht->size)); ht, name, value, ht->size));
if ( ht->buckets * 2 < ht->size && !ht->enumerators ) if ( ht->buckets * 2 < ht->size && !ht->enumerators )
rehashHTable(ht); s = rehashHTable(ht, s);
UNLOCK_TABLE(ht); UNLOCK_TABLE(ht);
DEBUG(1, checkHTable(ht)); DEBUG(1, checkHTable(ht));
@ -237,8 +273,7 @@ Note: s must be in the table!
void void
deleteSymbolHTable(Table ht, Symbol s) deleteSymbolHTable(Table ht, Symbol s)
{ GET_LD { int v;
int v;
Symbol *h; Symbol *h;
TableEnum e; TableEnum e;
@ -255,6 +290,9 @@ deleteSymbolHTable(Table ht, Symbol s)
{ if ( *h == s ) { if ( *h == s )
{ *h = (*h)->next; { *h = (*h)->next;
s->next = NULL; /* force crash */
s->name = NULL;
s->value = NULL;
freeHeap(s, sizeof(struct symbol)); freeHeap(s, sizeof(struct symbol));
ht->size--; ht->size--;
@ -268,8 +306,7 @@ deleteSymbolHTable(Table ht, Symbol s)
void void
clearHTable(Table ht) clearHTable(Table ht)
{ GET_LD { int n;
int n;
TableEnum e; TableEnum e;
LOCK_TABLE(ht); LOCK_TABLE(ht);
@ -309,24 +346,23 @@ Table copyHTable(Table org)
Table Table
copyHTable(Table org) copyHTable(Table org)
{ GET_LD { Table ht;
Table ht;
int n; int n;
ht = allocHeap(sizeof(struct table)); ht = allocHeapOrHalt(sizeof(struct table));
LOCK_TABLE(org); LOCK_TABLE(org);
*ht = *org; /* copy all attributes */ *ht = *org; /* copy all attributes */
#ifdef O_PLMT #ifdef O_PLMT
ht->mutex = NULL; ht->mutex = NULL;
#endif #endif
allocHTableEntries(ht); ht->entries = allocHTableEntries(ht->buckets);
for(n=0; n < ht->buckets; n++) for(n=0; n < ht->buckets; n++)
{ Symbol s, *q; { Symbol s, *q;
q = &ht->entries[n]; q = &ht->entries[n];
for(s = org->entries[n]; s; s = s->next) for(s = org->entries[n]; s; s = s->next)
{ Symbol s2 = allocHeap(sizeof(*s2)); { Symbol s2 = allocHeapOrHalt(sizeof(*s2));
*q = s2; *q = s2;
q = &s2->next; q = &s2->next;
@ -340,7 +376,7 @@ copyHTable(Table org)
} }
#ifdef O_PLMT #ifdef O_PLMT
if ( org->mutex ) if ( org->mutex )
{ ht->mutex = allocHeap(sizeof(simpleMutex)); { ht->mutex = allocHeapOrHalt(sizeof(simpleMutex));
simpleMutexInit(ht->mutex); simpleMutexInit(ht->mutex);
} }
#endif #endif
@ -356,8 +392,7 @@ copyHTable(Table org)
TableEnum TableEnum
newTableEnum(Table ht) newTableEnum(Table ht)
{ GET_LD { TableEnum e = allocHeapOrHalt(sizeof(struct table_enum));
TableEnum e = allocHeap(sizeof(struct table_enum));
Symbol n; Symbol n;
LOCK_TABLE(ht); LOCK_TABLE(ht);
@ -378,8 +413,7 @@ newTableEnum(Table ht)
void void
freeTableEnum(TableEnum e) freeTableEnum(TableEnum e)
{ GET_LD { TableEnum *ep;
TableEnum *ep;
Table ht; Table ht;
if ( !e ) if ( !e )

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef TABLE_H_INCLUDED #ifndef TABLE_H_INCLUDED
@ -27,7 +27,7 @@
typedef struct table * Table; /* (numeric) hash table */ typedef struct table * Table; /* (numeric) hash table */
typedef struct symbol * Symbol; /* symbol of hash table */ typedef struct symbol * Symbol; /* symbol of hash table */
typedef struct table_enum * TableEnum; /* Enumerate table entries */ typedef struct table_enum * TableEnum; /* Enumerate table entries */
struct table struct table
{ int buckets; /* size of hash table */ { int buckets; /* size of hash table */
@ -36,8 +36,8 @@ struct table
#ifdef O_PLMT #ifdef O_PLMT
simpleMutex *mutex; /* Mutex to guard table */ simpleMutex *mutex; /* Mutex to guard table */
#endif #endif
void (*copy_symbol)(Symbol s); void (*copy_symbol)(Symbol s);
void (*free_symbol)(Symbol s); void (*free_symbol)(Symbol s);
Symbol *entries; /* array of hash symbols */ Symbol *entries; /* array of hash symbols */
}; };
@ -54,17 +54,17 @@ struct table_enum
TableEnum next; /* More choice points */ TableEnum next; /* More choice points */
}; };
COMMON(void) initTables(void); COMMON(void) initTables(void);
COMMON(Table) newHTable(int size); COMMON(Table) newHTable(int size);
COMMON(void) destroyHTable(Table ht); COMMON(void) destroyHTable(Table ht);
COMMON(Symbol) lookupHTable(Table ht, void *name); COMMON(Symbol) lookupHTable(Table ht, void *name);
COMMON(Symbol) addHTable(Table ht, void *name, void *value); COMMON(Symbol) addHTable(Table ht, void *name, void *value);
COMMON(void) deleteSymbolHTable(Table ht, Symbol s); COMMON(void) deleteSymbolHTable(Table ht, Symbol s);
COMMON(void) clearHTable(Table ht); COMMON(void) clearHTable(Table ht);
COMMON(Table) copyHTable(Table org); COMMON(Table) copyHTable(Table org);
COMMON(TableEnum) newTableEnum(Table ht); COMMON(TableEnum) newTableEnum(Table ht);
COMMON(void) freeTableEnum(TableEnum e); COMMON(void) freeTableEnum(TableEnum e);
COMMON(Symbol) advanceTableEnum(TableEnum e); COMMON(Symbol) advanceTableEnum(TableEnum e);
#define TABLE_UNLOCKED 0x10000000L /* do not create mutex for table */ #define TABLE_UNLOCKED 0x10000000L /* do not create mutex for table */
#define TABLE_MASK 0xf0000000UL #define TABLE_MASK 0xf0000000UL

View File

@ -1,11 +1,9 @@
/* $Id$ /* Part of SWI-Prolog
Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: J.Wielemaker@cs.vu.nl E-mail: J.Wielemaker@cs.vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2010, University of Amsterdam Copyright (C): 1985-2012, University of Amsterdam
VU University Amsterdam VU University Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
@ -20,17 +18,10 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #define __MINGW_USE_VC2005_COMPAT /* Get Windows time_t as 64-bit */
Solaris has asctime_r() with 3 arguments. Using _POSIX_PTHREAD_SEMANTICS
is supposed to give the POSIX standard one.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(__sun__) || defined(__sun)
#define _POSIX_PTHREAD_SEMANTICS 1
#endif
#include <math.h> #include <math.h>
#include "pl-incl.h" #include "pl-incl.h"
@ -62,37 +53,6 @@ extern long timezone;
#endif #endif
#endif #endif
#if defined(__MINGW32__)
#include <stdlib.h>
#include <time.h>
#include <string.h>
#ifndef localtime_r
struct tm *localtime_r (const time_t *, struct tm *);
struct tm *
localtime_r (const time_t *timer, struct tm *result)
{
struct tm *local_result;
local_result = localtime (timer);
if (local_result == NULL || result == NULL)
return NULL;
memcpy (result, local_result, sizeof (result));
return result;
}
#endif
#ifndef asctime_r
#define asctime_r(_Tm, _Buf) ({ char *___tmp_tm = asctime((_Tm)); \
if (___tmp_tm) \
___tmp_tm = \
strcpy((_Buf),___tmp_tm);\
___tmp_tm; })
#endif
#endif
#define TAI_UTC_OFFSET LL(4611686018427387914) #define TAI_UTC_OFFSET LL(4611686018427387914)
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -102,6 +62,8 @@ struct ftm is a `floating' version of the system struct tm.
#define HAS_STAMP 0x0001 #define HAS_STAMP 0x0001
#define HAS_WYDAY 0x0002 #define HAS_WYDAY 0x0002
#define NO_UTC_OFFSET 0x7fffffff
typedef struct ftm typedef struct ftm
{ struct tm tm; /* System time structure */ { struct tm tm; /* System time structure */
double sec; /* float version of tm.tm_sec */ double sec; /* float version of tm.tm_sec */
@ -147,7 +109,7 @@ tz_offset(void)
{ time_t t = time(NULL); { time_t t = time(NULL);
struct tm tm; struct tm tm;
localtime_r(&t, &tm); PL_localtime_r(&t, &tm);
offset = -tm.tm_gmtoff; offset = -tm.tm_gmtoff;
if ( tm.tm_isdst > 0 ) if ( tm.tm_isdst > 0 )
@ -177,7 +139,7 @@ static atom_t
tz_name_as_atom(int dst) tz_name_as_atom(int dst)
{ static atom_t a[2]; { static atom_t a[2];
dst = (dst != 0); /* 0 or 1 */ dst = (dst > 0); /* 0 or 1 */
if ( !a[dst] ) if ( !a[dst] )
{ wchar_t wbuf[256]; { wchar_t wbuf[256];
@ -245,10 +207,12 @@ get_tz_arg(int i, term_t t, term_t a, atom_t *tz)
atom_t name; atom_t name;
_PL_get_arg(i, t, a); _PL_get_arg(i, t, a);
if ( !PL_get_atom_ex(a, &name) ) if ( !PL_is_variable(a) )
fail; { if ( !PL_get_atom_ex(a, &name) )
if ( name != ATOM_minus ) fail;
*tz = name; if ( name != ATOM_minus )
*tz = name;
}
succeed; succeed;
} }
@ -264,6 +228,21 @@ get_int_arg(int i, term_t t, term_t a, int *val)
} }
static int
get_voff_arg(int i, term_t t, term_t a, int *val)
{ GET_LD
_PL_get_arg(i, t, a);
if ( PL_is_variable(a) )
{ *val = NO_UTC_OFFSET;
return TRUE;
} else
{ return PL_get_integer_ex(a, val);
}
}
static int static int
get_float_arg(int i, term_t t, term_t a, double *val) get_float_arg(int i, term_t t, term_t a, double *val)
{ GET_LD { GET_LD
@ -275,7 +254,7 @@ get_float_arg(int i, term_t t, term_t a, double *val)
static int static int
get_bool_arg(int i, term_t t, term_t a, int *val) get_dst_arg(int i, term_t t, term_t a, int *val)
{ GET_LD { GET_LD
atom_t name; atom_t name;
@ -284,10 +263,16 @@ get_bool_arg(int i, term_t t, term_t a, int *val)
{ if ( name == ATOM_true ) { if ( name == ATOM_true )
{ *val = TRUE; { *val = TRUE;
return TRUE; return TRUE;
} else if ( name == ATOM_false || name == ATOM_minus ) } else if ( name == ATOM_false )
{ *val = FALSE; { *val = FALSE;
return TRUE; return TRUE;
} else if ( name == ATOM_minus )
{ *val = -1;
return TRUE;
} }
} else if ( PL_is_variable(a) )
{ *val = -2;
return TRUE;
} }
return PL_get_bool_ex(a, val); /* generate an error */ return PL_get_bool_ex(a, val); /* generate an error */
@ -297,23 +282,25 @@ get_bool_arg(int i, term_t t, term_t a, int *val)
static int static int
get_ftm(term_t t, ftm *ftm) get_ftm(term_t t, ftm *ftm)
{ GET_LD { GET_LD
term_t tmp = PL_new_term_ref();
int date9;
if ( PL_is_functor(t, FUNCTOR_date9) ) memset(ftm, 0, sizeof(*ftm));
{ term_t tmp = PL_new_term_ref();
memset(ftm, 0, sizeof(*ftm)); if ( (date9=PL_is_functor(t, FUNCTOR_date9)) )
{ if ( get_int_arg (1, t, tmp, &ftm->tm.tm_year) &&
if ( get_int_arg (1, t, tmp, &ftm->tm.tm_year) &&
get_int_arg (2, t, tmp, &ftm->tm.tm_mon) && get_int_arg (2, t, tmp, &ftm->tm.tm_mon) &&
get_int_arg (3, t, tmp, &ftm->tm.tm_mday) && get_int_arg (3, t, tmp, &ftm->tm.tm_mday) &&
get_int_arg (4, t, tmp, &ftm->tm.tm_hour) && get_int_arg (4, t, tmp, &ftm->tm.tm_hour) &&
get_int_arg (5, t, tmp, &ftm->tm.tm_min) && get_int_arg (5, t, tmp, &ftm->tm.tm_min) &&
get_float_arg(6, t, tmp, &ftm->sec) && get_float_arg(6, t, tmp, &ftm->sec) &&
get_int_arg (7, t, tmp, &ftm->utcoff) && get_voff_arg (7, t, tmp, &ftm->utcoff) &&
get_tz_arg (8, t, tmp, &ftm->tzname) && get_tz_arg (8, t, tmp, &ftm->tzname) &&
get_bool_arg (9, t, tmp, &ftm->isdst) ) get_dst_arg (9, t, tmp, &ftm->isdst) )
{ double fp, ip; { double fp, ip;
ftm->tm.tm_isdst = (ftm->isdst == -2 ? -1 : ftm->isdst);
fixup: fixup:
fp = modf(ftm->sec, &ip); fp = modf(ftm->sec, &ip);
if ( fp < 0.0 ) if ( fp < 0.0 )
@ -325,20 +312,62 @@ get_ftm(term_t t, ftm *ftm)
ftm->tm.tm_year -= 1900; /* 1900 based */ ftm->tm.tm_year -= 1900; /* 1900 based */
ftm->tm.tm_mon--; /* 0-based */ ftm->tm.tm_mon--; /* 0-based */
if ( ftm->utcoff == NO_UTC_OFFSET )
{ if ( ftm->tm.tm_isdst < 0 ) /* unknown DST */
{ int offset;
if ( mktime(&ftm->tm) == (time_t)-1 )
return PL_representation_error("dst");
ftm->flags |= HAS_WYDAY;
offset = tz_offset();
if ( ftm->tm.tm_isdst > 0 )
offset -= 3600;
ftm->utcoff = offset;
if ( date9 ) /* variable */
{ _PL_get_arg(7, t, tmp);
if ( !PL_unify_integer(tmp, ftm->utcoff) )
return FALSE;
} else
{ ftm->utcoff = offset;
}
}
if ( ftm->isdst == -2 )
{ ftm->isdst = ftm->tm.tm_isdst;
_PL_get_arg(9, t, tmp);
if ( ftm->isdst < 0 )
{ if ( !PL_unify_atom(tmp, ATOM_minus) )
return FALSE;
} else
{ if ( !PL_unify_bool(tmp, ftm->isdst) )
return FALSE;
}
}
if ( !ftm->tzname )
{ ftm->tzname = tz_name_as_atom(ftm->isdst);
_PL_get_arg(8, t, tmp);
if ( PL_is_variable(tmp) &&
!PL_unify_atom(tmp, ftm->tzname) )
return FALSE;
}
}
succeed; succeed;
} }
} else if ( PL_is_functor(t, FUNCTOR_date3) ) } else if ( PL_is_functor(t, FUNCTOR_date3) )
{ term_t tmp = PL_new_term_ref(); { if ( get_int_arg (1, t, tmp, &ftm->tm.tm_year) &&
memset(ftm, 0, sizeof(*ftm));
if ( get_int_arg (1, t, tmp, &ftm->tm.tm_year) &&
get_int_arg (2, t, tmp, &ftm->tm.tm_mon) && get_int_arg (2, t, tmp, &ftm->tm.tm_mon) &&
get_int_arg (3, t, tmp, &ftm->tm.tm_mday) ) get_int_arg (3, t, tmp, &ftm->tm.tm_mday) )
{ ftm->tm.tm_isdst = -1;
ftm->utcoff = NO_UTC_OFFSET;
goto fixup; goto fixup;
}
} }
fail; return PL_error(NULL, 0, NULL, ERR_TYPE, ATOM_time, t);
} }
@ -407,7 +436,7 @@ PRED_IMPL("stamp_date_time", 3, stamp_date_time, 0)
if ( (int64_t)unixt == ut64 ) if ( (int64_t)unixt == ut64 )
{ double ip; { double ip;
localtime_r(&unixt, &tm); PL_localtime_r(&unixt, &tm);
sec = (double)tm.tm_sec + modf(argsec, &ip); sec = (double)tm.tm_sec + modf(argsec, &ip);
ct.date.year = tm.tm_year+1900; ct.date.year = tm.tm_year+1900;
ct.date.month = tm.tm_mon+1; ct.date.month = tm.tm_mon+1;
@ -562,7 +591,7 @@ fmt_not_implemented(int c)
{ format_time(fd, f, ftm, posix); \ { format_time(fd, f, ftm, posix); \
} }
#define OUTCHR(fd, c) \ #define OUTCHR(fd, c) \
{ Sputcode(c, fd); \ { Sputcode(c, fd); \
} }
#define OUTSTR(str) \ #define OUTSTR(str) \
{ Sfputs(str, fd); \ { Sfputs(str, fd); \
@ -654,7 +683,6 @@ format_time(IOSTREAM *fd, const wchar_t *format, ftm *ftm, int posix)
case_b: case_b:
{ char fmt[3]; { char fmt[3];
char buf[256]; char buf[256];
size_t n;
fmt[0] = '%'; fmt[0] = '%';
fmt[1] = (char)c; fmt[1] = (char)c;
@ -662,7 +690,7 @@ format_time(IOSTREAM *fd, const wchar_t *format, ftm *ftm, int posix)
cal_ftm(ftm, HAS_STAMP|HAS_WYDAY); cal_ftm(ftm, HAS_STAMP|HAS_WYDAY);
/* conversion is not thread-safe under locale switch */ /* conversion is not thread-safe under locale switch */
n = strftime(buf, sizeof(buf), fmt, &ftm->tm); strftime(buf, sizeof(buf), fmt, &ftm->tm);
OUTSTRA(buf); OUTSTRA(buf);
break; break;
} }
@ -856,7 +884,7 @@ format_time(IOSTREAM *fd, const wchar_t *format, ftm *ftm, int posix)
{ char buf[26]; { char buf[26];
cal_ftm(ftm, HAS_WYDAY); cal_ftm(ftm, HAS_WYDAY);
asctime_r(&ftm->tm, buf); PL_asctime_r(&ftm->tm, buf);
buf[24] = EOS; buf[24] = EOS;
OUTSTRA(buf); OUTSTRA(buf);
} }
@ -920,7 +948,7 @@ pl_format_time(term_t out, term_t format, term_t time, int posix)
if ( (int64_t)unixt == ut64 ) if ( (int64_t)unixt == ut64 )
{ tb.utcoff = tz_offset(); { tb.utcoff = tz_offset();
localtime_r(&unixt, &tb.tm); PL_localtime_r(&unixt, &tb.tm);
tb.sec = (double)tb.tm.tm_sec + modf(tb.stamp, &ip); tb.sec = (double)tb.tm.tm_sec + modf(tb.stamp, &ip);
if ( tb.tm.tm_isdst > 0 ) if ( tb.tm.tm_isdst > 0 )
{ tb.utcoff -= 3600; { tb.utcoff -= 3600;
@ -942,7 +970,7 @@ pl_format_time(term_t out, term_t format, term_t time, int posix)
tb.utcoff = 0; tb.utcoff = 0;
} }
} else if ( !get_ftm(time, &tb) ) } else if ( !get_ftm(time, &tb) )
{ return PL_error(NULL, 0, NULL, ERR_TYPE, ATOM_time, time); { return FALSE;
} }
if ( !setupOutputRedirect(out, &ctx, FALSE) ) if ( !setupOutputRedirect(out, &ctx, FALSE) )

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "pl-incl.h" #include "pl-incl.h"
@ -28,9 +28,6 @@
#include "pl-codelist.h" #include "pl-codelist.h"
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#ifdef __WINDOWS__
#include "pl-mswchar.h" /* Terrible hack */
#endif
#if HAVE_LIMITS_H #if HAVE_LIMITS_H
#include <limits.h> /* solaris compatibility */ #include <limits.h> /* solaris compatibility */
#endif #endif
@ -121,12 +118,52 @@ PL_from_stack_text(PL_chars_t *text)
} }
#define INT64_DIGITS 20
static char *
ui64toa(uint64_t val, char *out)
{ char tmpBuf[INT64_DIGITS + 1];
char *ptrOrg = tmpBuf + INT64_DIGITS;
char *ptr = ptrOrg;
size_t nbDigs;
do
{ int rem = val % 10;
*--ptr = rem + '0';
val /= 10;
} while ( val );
nbDigs = ptrOrg - ptr;
memcpy(out, ptr, nbDigs);
out += nbDigs;
*out = '\0';
return out; /* points to the END */
};
static char *
i64toa(int64_t val, char *out)
{ if ( val < 0 )
{ *out++ = '-';
val = -val;
}
return ui64toa((uint64_t)val, out);
}
int int
PL_get_text__LD(term_t l, PL_chars_t *text, int flags ARG_LD) PL_get_text__LD(term_t l, PL_chars_t *text, int flags ARG_LD)
{ word w = valHandle(l); { word w = valHandle(l);
if ( (flags & CVT_ATOM) && isAtom(w) ) if ( (flags & CVT_ATOM) && isAtom(w) )
#if __YAP_PROLOG__
{ if ( !get_atom_text(atomFromTerm(w), text) ) { if ( !get_atom_text(atomFromTerm(w), text) )
#else
{ if ( !get_atom_text(w, text) )
#endif
goto maybe_write; goto maybe_write;
} else if ( (flags & CVT_STRING) && isString(w) ) } else if ( (flags & CVT_STRING) && isString(w) )
{ if ( !get_string_text(w, text PASS_LD) ) { if ( !get_string_text(w, text PASS_LD) )
@ -138,17 +175,20 @@ PL_get_text__LD(term_t l, PL_chars_t *text, int flags ARG_LD)
PL_get_number(l, &n); PL_get_number(l, &n);
switch(n.type) switch(n.type)
{ case V_INTEGER: { case V_INTEGER:
sprintf(text->buf, INT64_FORMAT, n.value.i); { char *ep = i64toa(n.value.i, text->buf);
text->text.t = text->buf; text->text.t = text->buf;
text->length = strlen(text->text.t); text->length = ep-text->text.t;
text->storage = PL_CHARS_LOCAL; text->storage = PL_CHARS_LOCAL;
break; break;
}
#ifdef O_GMP #ifdef O_GMP
case V_MPZ: case V_MPZ:
{ size_t sz = mpz_sizeinbase(n.value.mpz, 10) + 2; { size_t sz = mpz_sizeinbase(n.value.mpz, 10) + 2;
Buffer b = findBuffer(BUF_RING); Buffer b = findBuffer(BUF_RING);
growBuffer(b, sz); if ( !growBuffer(b, sz) )
outOfCore();
mpz_get_str(b->base, 10, n.value.mpz); mpz_get_str(b->base, 10, n.value.mpz);
b->top = b->base + strlen(b->base); b->top = b->base + strlen(b->base);
text->text.t = baseBuffer(b, char); text->text.t = baseBuffer(b, char);
@ -196,7 +236,7 @@ PL_get_text__LD(term_t l, PL_chars_t *text, int flags ARG_LD)
{ case CVT_partial: { case CVT_partial:
return PL_error(NULL, 0, NULL, ERR_INSTANTIATION); return PL_error(NULL, 0, NULL, ERR_INSTANTIATION);
case CVT_nolist: case CVT_nolist:
return PL_error(NULL, 0, NULL, ERR_TYPE, ATOM_list, l); goto error;
case CVT_nocode: case CVT_nocode:
case CVT_nochar: case CVT_nochar:
{ term_t culprit = PL_new_term_ref(); { term_t culprit = PL_new_term_ref();
@ -295,7 +335,9 @@ error:
if ( (flags & CVT_EXCEPTION) ) if ( (flags & CVT_EXCEPTION) )
{ atom_t expected; { atom_t expected;
if ( flags & CVT_LIST ) if ( (flags & CVT_LIST) && !(flags&(CVT_ATOM|CVT_NUMBER)) )
expected = ATOM_list; /* List and/or string object */
else if ( flags & CVT_LIST )
expected = ATOM_text; expected = ATOM_text;
else if ( flags & CVT_NUMBER ) else if ( flags & CVT_NUMBER )
expected = ATOM_atomic; expected = ATOM_atomic;
@ -353,7 +395,7 @@ PL_unify_text(term_t term, term_t tail, PL_chars_t *text, int type)
{ word w = textToString(text); { word w = textToString(text);
if ( w ) if ( w )
return _PL_unify_string(term, w); return _PL_unify_atomic(term, w);
else else
return FALSE; return FALSE;
} }
@ -473,6 +515,7 @@ PL_unify_text(term_t term, term_t tail, PL_chars_t *text, int type)
return FALSE; return FALSE;
} }
} }
return CLOSE_SEQ_STRING(p, p0, tail, term, l ); return CLOSE_SEQ_STRING(p, p0, tail, term, l );
} }
} }
@ -497,6 +540,18 @@ PL_unify_text_range(term_t term, PL_chars_t *text,
if ( offset > text->length || offset + len > text->length ) if ( offset > text->length || offset + len > text->length )
return FALSE; return FALSE;
if ( len == 1 && type == PL_ATOM )
{ GET_LD
int c;
if ( text->encoding == ENC_ISO_LATIN_1 )
c = text->text.t[offset]&0xff;
else
c = text->text.w[offset];
return PL_unify_atom(term, codeToAtom(c));
}
sub.length = len; sub.length = len;
sub.storage = PL_CHARS_HEAP; sub.storage = PL_CHARS_HEAP;
if ( text->encoding == ENC_ISO_LATIN_1 ) if ( text->encoding == ENC_ISO_LATIN_1 )
@ -659,7 +714,7 @@ represented.
static int static int
wctobuffer(wchar_t c, mbstate_t *mbs, Buffer buf) wctobuffer(wchar_t c, mbstate_t *mbs, Buffer buf)
{ char b[MB_LEN_MAX]; { char b[PL_MB_LEN_MAX];
size_t n; size_t n;
if ( (n=wcrtomb(b, c, mbs)) != (size_t)-1 ) if ( (n=wcrtomb(b, c, mbs)) != (size_t)-1 )

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef PL_TEXT_H_INCLUDED #ifndef PL_TEXT_H_INCLUDED

View File

@ -46,26 +46,43 @@ extern void freeSimpleMutex(counting_mutex *m);
extern counting_mutex _PL_mutexes[]; /* Prolog mutexes */ extern counting_mutex _PL_mutexes[]; /* Prolog mutexes */
#define L_MISC 0 #define L_MISC 0
#define L_ALLOC 1 #define L_ALLOC 1
#define L_ATOM 2 #define L_ATOM 2
#define L_FLAG 3 #define L_FLAG 3
#define L_FUNCTOR 4 #define L_FUNCTOR 4
#define L_RECORD 5 #define L_RECORD 5
#define L_THREAD 6 #define L_THREAD 6
#define L_PREDICATE 7 #define L_PREDICATE 7
#define L_MODULE 8 #define L_MODULE 8
#define L_TABLE 9 #define L_TABLE 9
#define L_BREAK 10 #define L_BREAK 10
#define L_FILE 11 #define L_FILE 11
#define L_PLFLAG 12 #define L_SEETELL 12
#define L_OP 13 #define L_PLFLAG 13
#define L_INIT 14 #define L_OP 14
#define L_TERM 15 #define L_INIT 15
#define L_GC 16 #define L_TERM 16
#define L_AGC 17 #define L_GC 17
#define L_FOREIGN 18 #define L_AGC 18
#define L_OS 19 #define L_STOPTHEWORLD 19
#define L_FOREIGN 20
#define L_OS 21
#ifdef __WINDOWS__
#define L_DDE 22
#define L_CSTACK 23
#endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The IF_MT(id, g) macro is used to bypass mutexes if threading is
disabled. We cannot do this for the L_THREAD mutex however as we need to
control when threads can be created.
We assume id == L_THREAD is optimized away if id is known at
compile-time
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define IF_MT(id, g) if ( id == L_THREAD || GD->thread.enabled ) g
#ifdef O_CONTENTION_STATISTICS #ifdef O_CONTENTION_STATISTICS
#define countingMutexLock(cm) \ #define countingMutexLock(cm) \

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <string.h> /* get size_t */ #include <string.h> /* get size_t */

View File

@ -19,13 +19,15 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef UTF8_H_INCLUDED #ifndef UTF8_H_INCLUDED
#define UTF8_H_INCLUDED #define UTF8_H_INCLUDED
#define PL_MB_LEN_MAX 16
#define UTF8_MALFORMED_REPLACEMENT 0xfffd #define UTF8_MALFORMED_REPLACEMENT 0xfffd
#define ISUTF8_MB(c) ((unsigned)(c) >= 0xc0 && (unsigned)(c) <= 0xfd) #define ISUTF8_MB(c) ((unsigned)(c) >= 0xc0 && (unsigned)(c) <= 0xfd)

View File

@ -5,7 +5,7 @@
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: wielemak@science.uva.nl E-mail: wielemak@science.uva.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2005, University of Amsterdam Copyright (C): 1985-2007, University of Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,20 +19,18 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <wchar.h> #include "pl-incl.h"
#ifdef USE_GIT_VERSION_H
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #include <version.h>
See pl-mswchar.cpp for the motivation for this nonsense. Used in
pl-fli.c and pl-text.c.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef __WINDOWS__
#define wcrtomb(s, wc, ps) ms_wcrtomb(s, wc, ps)
#define mbrtowc(pwc, s, n, ps) ms_mbrtowc(pwc, s, n, ps)
extern size_t ms_wcrtomb(char *s, wchar_t wc, mbstate_t *ps);
extern size_t ms_mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
#endif #endif
void
setGITVersion(void)
{
#ifdef GIT_VERSION
PL_set_prolog_flag("version_git", PL_ATOM|FF_READONLY, GIT_VERSION);
#endif
}

View File

@ -60,16 +60,19 @@ typedef struct
int max_depth; /* depth limit */ int max_depth; /* depth limit */
int depth; /* current depth */ int depth; /* current depth */
atom_t spacing; /* Where to insert spaces */ atom_t spacing; /* Where to insert spaces */
Term module; /* Module for operators */ Term module; /* Module for operators */
IOSTREAM *out; /* stream to write to */ IOSTREAM *out; /* stream to write to */
visited *visited; /* visited (attributed-) variables */ term_t portray_goal; /* call/2 activated portray hook */
term_t write_options; /* original write options */
term_t prec_opt; /* term in write options with prec */
} write_options; } write_options;
word word
pl_nl1(term_t stream) pl_nl1(term_t stream)
{ IOSTREAM *s; { GET_LD
IOSTREAM *s;
if ( getOutputStream(stream, &s) ) if ( getTextOutputStream(stream, &s) )
{ Sputcode('\n', s); { Sputcode('\n', s);
return streamStatus(s); return streamStatus(s);
} }
@ -165,6 +168,28 @@ format_float(double f, char *buf)
return buf; return buf;
} }
static int
bind_varnames(term_t varnames ARG_LD)
{
CACHE_REGS
Term t = Yap_GetFromSlot(varnames PASS_REGS);
while(!IsVarTerm(t) && IsPairTerm(t)) {
Term tl = HeadOfTerm(t);
Functor f;
Term tv, t2, t1;
if (!IsApplTerm(tl)) return FALSE;
if ((f = FunctorOfTerm(tl)) != FunctorEq)
return FALSE;
t1 = ArgOfTerm(1, tl);
t2 = ArgOfTerm(2, tl);
tv = Yap_MkApplTerm(LOCAL_FunctorVar, 1, &t1);
if (!Yap_unify(t2, tv))
return FALSE;
t = TailOfTerm(t);
}
return TRUE;
}
char * char *
varName(term_t t, char *name) varName(term_t t, char *name)
@ -183,7 +208,7 @@ varName(term_t t, char *name)
static bool static bool
writeTerm(term_t t, int prec, write_options *options) writeTopTerm(term_t t, int prec, write_options *options)
{ {
CACHE_REGS CACHE_REGS
UInt yap_flag = Use_SWI_Stream_f; UInt yap_flag = Use_SWI_Stream_f;
@ -194,6 +219,8 @@ writeTerm(term_t t, int prec, write_options *options)
yap_flag |= Quote_illegal_f; yap_flag |= Quote_illegal_f;
if (options->flags & PL_WRT_NUMBERVARS) if (options->flags & PL_WRT_NUMBERVARS)
yap_flag |= Handle_vars_f; yap_flag |= Handle_vars_f;
if (options->flags & PL_WRT_VARNAMES)
yap_flag |= Handle_vars_f;
if (options->flags & PL_WRT_IGNOREOPS) if (options->flags & PL_WRT_IGNOREOPS)
yap_flag |= Ignore_ops_f; yap_flag |= Ignore_ops_f;
if (flags & PL_WRT_PORTRAY) if (flags & PL_WRT_PORTRAY)
@ -221,21 +248,6 @@ writeAtomToStream(IOSTREAM *s, atom_t atom)
return 1; return 1;
} }
int
writeAttributeMask(atom_t a)
{ if ( a == ATOM_ignore )
{ return PL_WRT_ATTVAR_IGNORE;
} else if ( a == ATOM_dots )
{ return PL_WRT_ATTVAR_DOTS;
} else if ( a == ATOM_write )
{ return PL_WRT_ATTVAR_WRITE;
} else if ( a == ATOM_portray )
{ return PL_WRT_ATTVAR_PORTRAY;
} else
return 0;
}
static int static int
writeBlobMask(atom_t a) writeBlobMask(atom_t a)
{ if ( a == ATOM_default ) { if ( a == ATOM_default )
@ -247,23 +259,6 @@ writeBlobMask(atom_t a)
} }
static const opt_spec write_term_options[] =
{ { ATOM_quoted, OPT_BOOL },
{ ATOM_ignore_ops, OPT_BOOL },
{ ATOM_numbervars, OPT_BOOL },
{ ATOM_portray, OPT_BOOL },
{ ATOM_character_escapes, OPT_BOOL },
{ ATOM_max_depth, OPT_INT },
{ ATOM_module, OPT_ATOM },
{ ATOM_backquoted_string, OPT_BOOL },
{ ATOM_attributes, OPT_ATOM },
{ ATOM_priority, OPT_INT },
{ ATOM_partial, OPT_BOOL },
{ ATOM_spacing, OPT_ATOM },
{ ATOM_blobs, OPT_ATOM },
{ NULL_ATOM, 0 }
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PutOpenToken() inserts a space in the output stream if the last-written PutOpenToken() inserts a space in the output stream if the last-written
and given character require a space to ensure a token-break. and given character require a space to ensure a token-break.
@ -317,6 +312,84 @@ PutOpenToken(int c, IOSTREAM *s)
return TRUE; return TRUE;
} }
/*******************************
* TOPLEVEL *
*******************************/
int
writeAttributeMask(atom_t a)
{ if ( a == ATOM_ignore )
{ return PL_WRT_ATTVAR_IGNORE;
} else if ( a == ATOM_dots )
{ return PL_WRT_ATTVAR_DOTS;
} else if ( a == ATOM_write )
{ return PL_WRT_ATTVAR_WRITE;
} else if ( a == ATOM_portray )
{ return PL_WRT_ATTVAR_PORTRAY;
} else
return 0;
}
static const opt_spec write_term_options[] =
{ { ATOM_quoted, OPT_BOOL },
{ ATOM_ignore_ops, OPT_BOOL },
{ ATOM_numbervars, OPT_BOOL },
{ ATOM_portray, OPT_BOOL },
{ ATOM_portray_goal, OPT_TERM },
{ ATOM_character_escapes, OPT_BOOL },
{ ATOM_max_depth, OPT_INT },
{ ATOM_module, OPT_ATOM },
{ ATOM_backquoted_string, OPT_BOOL },
{ ATOM_attributes, OPT_ATOM },
{ ATOM_priority, OPT_INT },
{ ATOM_partial, OPT_BOOL },
{ ATOM_spacing, OPT_ATOM },
{ ATOM_blobs, OPT_ATOM },
{ ATOM_cycles, OPT_BOOL },
{ ATOM_variable_names, OPT_TERM },
{ NULL_ATOM, 0 }
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Call user:portray/1 if defined.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static int
put_write_options(term_t opts_in, write_options *options)
{ GET_LD
term_t newlist = PL_new_term_ref();
term_t precopt = PL_new_term_ref();
fid_t fid = PL_open_foreign_frame();
term_t head = PL_new_term_ref();
term_t tail = PL_copy_term_ref(opts_in);
term_t newhead = PL_new_term_ref();
term_t newtail = PL_copy_term_ref(newlist);
int rc = TRUE;
while(rc && PL_get_list(tail, head, tail))
{ if ( !PL_is_functor(head, FUNCTOR_priority1) )
rc = ( PL_unify_list(newtail, newhead, newtail) &&
PL_unify(newhead, head) );
}
if ( rc )
{ rc = ( PL_unify_list(newtail, head, newtail) &&
PL_unify_functor(head, FUNCTOR_priority1) &&
PL_get_arg(1, head, precopt) &&
PL_unify_nil(newtail) );
}
if ( rc )
{ options->write_options = newlist;
options->prec_opt = precopt;
}
PL_close_foreign_frame(fid);
return rc;
}
word word
pl_write_term3(term_t stream, term_t term, term_t opts) pl_write_term3(term_t stream, term_t term, term_t opts)
{ GET_LD { GET_LD
@ -324,6 +397,7 @@ pl_write_term3(term_t stream, term_t term, term_t opts)
bool ignore_ops = FALSE; bool ignore_ops = FALSE;
bool numbervars = -1; /* not set */ bool numbervars = -1; /* not set */
bool portray = FALSE; bool portray = FALSE;
term_t gportray = 0;
bool bqstring = truePrologFlag(PLFLAG_BACKQUOTED_STRING); bool bqstring = truePrologFlag(PLFLAG_BACKQUOTED_STRING);
bool charescape = -1; /* not set */ bool charescape = -1; /* not set */
atom_t mname = ATOM_user; atom_t mname = ATOM_user;
@ -331,7 +405,10 @@ pl_write_term3(term_t stream, term_t term, term_t opts)
atom_t blobs = ATOM_nil; atom_t blobs = ATOM_nil;
int priority = 1200; int priority = 1200;
bool partial = FALSE; bool partial = FALSE;
IOSTREAM *s; bool cycles = TRUE;
term_t varnames = 0;
int local_varnames;
IOSTREAM *s = NULL;
write_options options; write_options options;
int rc; int rc;
@ -339,10 +416,10 @@ pl_write_term3(term_t stream, term_t term, term_t opts)
options.spacing = ATOM_standard; options.spacing = ATOM_standard;
if ( !scan_options(opts, 0, ATOM_write_option, write_term_options, if ( !scan_options(opts, 0, ATOM_write_option, write_term_options,
&quoted, &ignore_ops, &numbervars, &portray, &quoted, &ignore_ops, &numbervars, &portray, &gportray,
&charescape, &options.max_depth, &mname, &charescape, &options.max_depth, &mname,
&bqstring, &attr, &priority, &partial, &options.spacing, &bqstring, &attr, &priority, &partial, &options.spacing,
&blobs) ) &blobs, &cycles, &varnames) )
fail; fail;
if ( attr == ATOM_nil ) if ( attr == ATOM_nil )
@ -381,14 +458,21 @@ pl_write_term3(term_t stream, term_t term, term_t opts)
} }
} }
if ( !getOutputStream(stream, &s) )
fail;
options.module = lookupModule(mname); options.module = lookupModule(mname);
if ( charescape == TRUE || if ( charescape == TRUE ||
// (charescape == -1 && true(options.module, CHARESCAPE)) ) (charescape == -1
charEscapeWriteOption(options)) #ifndef __YAP_PROLOG__
&& true(options.module, M_CHARESCAPE)
#endif
) )
options.flags |= PL_WRT_CHARESCAPES; options.flags |= PL_WRT_CHARESCAPES;
if ( gportray )
{ options.portray_goal = gportray;
if ( !put_write_options(opts, &options) ||
!PL_qualify(options.portray_goal, options.portray_goal) )
return FALSE;
portray = TRUE;
}
if ( numbervars == -1 ) if ( numbervars == -1 )
numbervars = (portray ? TRUE : FALSE); numbervars = (portray ? TRUE : FALSE);
@ -397,19 +481,35 @@ pl_write_term3(term_t stream, term_t term, term_t opts)
if ( numbervars ) options.flags |= PL_WRT_NUMBERVARS; if ( numbervars ) options.flags |= PL_WRT_NUMBERVARS;
if ( portray ) options.flags |= PL_WRT_PORTRAY; if ( portray ) options.flags |= PL_WRT_PORTRAY;
if ( bqstring ) options.flags |= PL_WRT_BACKQUOTED_STRING; if ( bqstring ) options.flags |= PL_WRT_BACKQUOTED_STRING;
if ( !cycles ) options.flags |= PL_WRT_NO_CYCLES;
local_varnames = (varnames && false(&options, PL_WRT_NUMBERVARS));
BEGIN_NUMBERVARS(local_varnames);
if ( varnames )
{ if ( (rc=bind_varnames(varnames PASS_LD)) )
options.flags |= PL_WRT_VARNAMES;
else
goto out;
}
if ( !(rc=getTextOutputStream(stream, &s)) )
goto out;
options.out = s; options.out = s;
if ( !partial ) if ( !partial )
PutOpenToken(EOF, s); /* reset this */ PutOpenToken(EOF, s); /* reset this */
if ( (options.flags & PL_WRT_QUOTED) && !(s->flags&SIO_REPPL) ) if ( (options.flags & PL_WRT_QUOTED) && !(s->flags&SIO_REPPL) )
{ s->flags |= SIO_REPPL; { s->flags |= SIO_REPPL;
rc = writeTerm(term, priority, &options); rc = writeTopTerm(term, priority, &options);
s->flags &= ~SIO_REPPL; s->flags &= ~SIO_REPPL;
} else } else
{ rc = writeTerm(term, priority, &options); { rc = writeTopTerm(term, priority, &options);
} }
return streamStatus(s) && rc; out:
END_NUMBERVARS(local_varnames);
return (!s || streamStatus(s)) && rc;
} }
@ -426,10 +526,10 @@ PL_write_term(IOSTREAM *s, term_t term, int precedence, int flags)
memset(&options, 0, sizeof(options)); memset(&options, 0, sizeof(options));
options.flags = flags; options.flags = flags;
options.out = s; options.out = s;
options.module = USER_MODULE; //MODULE_user; options.module = MODULE_user;
PutOpenToken(EOF, s); /* reset this */ PutOpenToken(EOF, s); /* reset this */
return writeTerm(term, precedence, &options); return writeTopTerm(term, precedence, &options);
} }
@ -438,22 +538,27 @@ do_write2(term_t stream, term_t term, int flags)
{ GET_LD { GET_LD
IOSTREAM *s; IOSTREAM *s;
if ( getOutputStream(stream, &s) ) if ( getTextOutputStream(stream, &s) )
{ write_options options; { write_options options;
int rc; int rc;
memset(&options, 0, sizeof(options)); memset(&options, 0, sizeof(options));
options.flags = flags; options.flags = flags;
options.out = s; options.out = s;
options.module = USER_MODULE; // MODULE_user; options.module = MODULE_user;
// if ( options.module && true(options.module, CHARESCAPE) ) if ( options.module
if (charEscapeWriteOption(options)) #ifndef __YAP_PROLOG__
&& true(options.module, M_CHARESCAPE)
#endif
)
options.flags |= PL_WRT_CHARESCAPES; options.flags |= PL_WRT_CHARESCAPES;
if ( truePrologFlag(PLFLAG_BACKQUOTED_STRING) ) if ( truePrologFlag(PLFLAG_BACKQUOTED_STRING) )
options.flags |= PL_WRT_BACKQUOTED_STRING; options.flags |= PL_WRT_BACKQUOTED_STRING;
PutOpenToken(EOF, s); /* reset this */ PutOpenToken(EOF, s); /* reset this */
rc = writeTerm(term, 1200, &options); rc = writeTopTerm(term, 1200, &options);
if ( rc && (flags&PL_WRT_NEWLINE) )
rc = Putc('\n', s);
return streamStatus(s) && rc; return streamStatus(s) && rc;
} }
@ -481,25 +586,22 @@ pl_print2(term_t stream, term_t term)
word word
pl_write_canonical2(term_t stream, term_t term) pl_write_canonical2(term_t stream, term_t term)
{ GET_LD { GET_LD
fid_t fid;
nv_options options; nv_options options;
word rc; word rc;
if ( !(fid = PL_open_foreign_frame()) ) BEGIN_NUMBERVARS(TRUE);
return FALSE;
options.functor = FUNCTOR_isovar1; options.functor = FUNCTOR_isovar1;
options.on_attvar = AV_SKIP; options.on_attvar = AV_SKIP;
options.singletons = TRUE; options.singletons = PL_is_acyclic(term);
#if __YAP_PROLOG__ options.numbered_check = FALSE;
LOCAL_FunctorVar = FunctorHiddenVar;
#endif rc = ( numberVars(term, &options, 0 PASS_LD) >= 0 &&
numberVars(term, &options, 0 PASS_LD); do_write2(stream, term,
rc = do_write2(stream, term, PL_WRT_QUOTED|PL_WRT_IGNOREOPS|PL_WRT_NUMBERVARS)
PL_WRT_QUOTED|PL_WRT_IGNOREOPS|PL_WRT_NUMBERVARS); );
#if __YAP_PROLOG__
LOCAL_FunctorVar = FunctorVar; END_NUMBERVARS(TRUE);
#endif
PL_discard_foreign_frame(fid);
return rc; return rc;
} }
@ -524,17 +626,13 @@ pl_write_canonical(term_t term)
{ return pl_write_canonical2(0, term); { return pl_write_canonical2(0, term);
} }
word /* for debugging purposes! */ word
pl_writeln(term_t term) pl_writeln(term_t term)
{ if ( PL_write_term(Serror, term, 1200, { return do_write2(0, term, PL_WRT_NUMBERVARS|PL_WRT_NEWLINE);
PL_WRT_QUOTED|PL_WRT_NUMBERVARS) &&
Sdprintf("\n") >= 0 )
succeed;
fail;
} }
/******************************* /*******************************
* PUBLISH PREDICATES * * PUBLISH PREDICATES *
*******************************/ *******************************/

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef _DIRENT_H_INCLUDED #ifndef _DIRENT_H_INCLUDED
@ -28,8 +28,8 @@
#include <io.h> #include <io.h>
#undef _export #undef _export
#if defined(_UXNT_KERNEL) && !defined(__LCC__) #if defined(_UXNT_KERNEL) && !defined(__MINGW32__)
#define _export __declspec(dllexport) #define _export _declspec(dllexport)
#else #else
#define _export extern #define _export extern
#endif #endif
@ -37,7 +37,7 @@
#define DIRENT_MAX 512 #define DIRENT_MAX 512
typedef struct dirent typedef struct dirent
{ void * data; /* actually WIN32_FIND_DATA * */ { void * data; /* actually WIN32_FIND_DATA * */
int first; int first;
void * handle; /* actually HANDLE */ void * handle; /* actually HANDLE */
/* dirent */ /* dirent */

View File

@ -297,9 +297,9 @@ pt_popen(const char *cmd, const char *mode)
} }
if ( pc->mode == 'r' ) if ( pc->mode == 'r' )
fptr = _fdopen(_open_osfhandle((long)pc->out[0],_O_BINARY),"r"); fptr = _fdopen(_open_osfhandle((intptr_t)pc->out[0],_O_BINARY),"r");
else else
fptr = _fdopen(_open_osfhandle((long)pc->in[1],_O_BINARY),"w"); fptr = _fdopen(_open_osfhandle((intptr_t)pc->in[1],_O_BINARY),"w");
finito: finito:
if ( fptr ) if ( fptr )

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "utf8.h" #include "utf8.h"
@ -31,7 +31,7 @@ UTF-8 Decoding, based on http://www.cl.cam.ac.uk/~mgk25/unicode.html
#define CONT(i) ISUTF8_CB(in[1]) #define CONT(i) ISUTF8_CB(in[1])
#define VAL(i, s) ((in[i]&0x3f) << s) #define VAL(i, s) ((in[i]&0x3f) << s)
char * static char *
_xos_utf8_get_char(const char *in, int *chr) _xos_utf8_get_char(const char *in, int *chr)
{ /* 2-byte, 0x80-0x7ff */ { /* 2-byte, 0x80-0x7ff */
if ( (in[0]&0xe0) == 0xc0 && CONT(1) ) if ( (in[0]&0xe0) == 0xc0 && CONT(1) )
@ -60,12 +60,12 @@ _xos_utf8_get_char(const char *in, int *chr)
} }
*chr = *in; *chr = *in;
return (char *)in+1; return (char *)in+1;
} }
char * static char *
_xos_utf8_put_char(char *out, int chr) _xos_utf8_put_char(char *out, int chr)
{ if ( chr < 0x80 ) { if ( chr < 0x80 )
{ *out++ = chr; { *out++ = chr;

View File

@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
@ -52,7 +52,7 @@
((chr) < 0x80 ? out[0]=(char)(chr), out+1 \ ((chr) < 0x80 ? out[0]=(char)(chr), out+1 \
: _xos_utf8_put_char(out, (chr))) : _xos_utf8_put_char(out, (chr)))
extern char *_xos_utf8_get_char(const char *in, int *chr); static char *_xos_utf8_get_char(const char *in, int *chr);
extern char *_xos_utf8_put_char(char *out, int chr); static char *_xos_utf8_put_char(char *out, int chr);
#endif /*UTF8_H_INCLUDED*/ #endif /*UTF8_H_INCLUDED*/

View File

@ -1,11 +1,10 @@
/* $Id$ /* Part of SWI-Prolog
Part of SWI-Prolog
Author: Jan Wielemaker Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl E-mail: J.Wielemaker@vu.nl
WWW: http://www.swi-prolog.org WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam Copyright (C): 1985-2012, University of Amsterdam
Vu University Amsterdam
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#define UNICODE 1 #define UNICODE 1
@ -52,11 +51,6 @@
#define FALSE 0 #define FALSE 0
#endif #endif
#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif
#ifdef __LCC__ #ifdef __LCC__
#define _close close #define _close close
#define _read read #define _read read
@ -72,6 +66,10 @@
#define XENOMAP 1 #define XENOMAP 1
#define XENOMEM 2 #define XENOMEM 2
#ifndef PATH_MAX
#define PATH_MAX 260
#endif
/******************************* /*******************************
* ERRNO * * ERRNO *
@ -146,6 +144,21 @@ utf8towcs(wchar_t *dest, const char *src, size_t len)
} }
static size_t
utf8_strlen(const char *s, size_t len)
{ const char *e = &s[len];
unsigned int l = 0;
while(s<e)
{ int chr;
s = utf8_get_char(s, &chr);
l++;
}
return l;
}
/******************************* /*******************************
@ -169,11 +182,11 @@ existsAndWriteableDir(const TCHAR *name)
char * char *
_xos_home() /* expansion of ~ */ _xos_home() /* expansion of ~ */
{ static char home[MAXPATHLEN]; { static char home[PATH_MAX];
static int done = FALSE; static int done = FALSE;
if ( !done ) if ( !done )
{ TCHAR h[MAXPATHLEN]; { TCHAR h[PATH_MAX];
/* Unix, set by user */ /* Unix, set by user */
if ( GetEnvironmentVariable(_T("HOME"), h, sizeof(h)) && if ( GetEnvironmentVariable(_T("HOME"), h, sizeof(h)) &&
@ -184,8 +197,8 @@ _xos_home() /* expansion of ~ */
{ _xos_canonical_filenameW(h, home, sizeof(home), 0); { _xos_canonical_filenameW(h, home, sizeof(home), 0);
} else } else
{ TCHAR d[100]; { TCHAR d[100];
TCHAR p[MAXPATHLEN]; TCHAR p[PATH_MAX];
TCHAR tmp[MAXPATHLEN]; TCHAR tmp[PATH_MAX];
int haved, havep; int haved, havep;
haved = GetEnvironmentVariable(_T("HOMEDRIVE"), d, sizeof(d)); haved = GetEnvironmentVariable(_T("HOMEDRIVE"), d, sizeof(d));
@ -245,7 +258,8 @@ _xos_os_filenameW(const char *cname, wchar_t *osname, size_t len)
q += 3; q += 3;
} }
if ( q[0] == '/' || q[0] == '\\' ) /* deal with //host/share */ if ( (q[0] == '/' || q[0] == '\\') &&
(q[1] == '/' || q[1] == '\\') ) /* deal with //host/share */
{ if ( s+1 >= e ) { if ( s+1 >= e )
{ errno = ENAMETOOLONG; { errno = ENAMETOOLONG;
return NULL; return NULL;
@ -600,7 +614,6 @@ _xos_fopen(const char *path, const char *mode)
} }
/******************************* /*******************************
* FILE MANIPULATIONS * * FILE MANIPULATIONS *
*******************************/ *******************************/
@ -608,11 +621,101 @@ _xos_fopen(const char *path, const char *mode)
int int
_xos_access(const char *path, int mode) _xos_access(const char *path, int mode)
{ TCHAR buf[PATH_MAX]; { TCHAR buf[PATH_MAX];
char sd_buf[512];
SECURITY_DESCRIPTOR *sd;
BOOL access_status;
DWORD desired_access = 0;
DWORD sd_size, granted_access;
HANDLE token = 0, imp_token = 0;
GENERIC_MAPPING generic_mapping;
PRIVILEGE_SET privelege_set;
DWORD priv_set_len = sizeof(PRIVILEGE_SET);
int retval = -1;
SECURITY_INFORMATION sec_info =
DACL_SECURITY_INFORMATION |
OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION;
if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) if ( !_xos_os_filenameW(path, buf, PATH_MAX) )
return -1; return -1;
return _waccess(buf, mode); if ( mode == F_OK )
return _waccess(buf, F_OK);
sd = (SECURITY_DESCRIPTOR*)&sd_buf;
if ( !GetFileSecurity(buf, sec_info, sd, sizeof(sd_buf), &sd_size) )
{ if ( GetLastError() == ERROR_INVALID_FUNCTION )
{ goto simple;
} else if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
{ errno = ENOENT;
return -1;
}
if ( !(sd = malloc(sd_size)) )
{ errno = ENOMEM;
return -1;
}
if ( !GetFileSecurity(buf, sec_info, sd, sd_size, &sd_size) )
goto simple;
}
if ( mode & W_OK )
{ if ( _waccess(buf, W_OK ) < 0 ) /* read-only bit set */
goto out;
}
if ( !OpenThreadToken(GetCurrentThread(),
TOKEN_DUPLICATE | TOKEN_READ,
TRUE,
&token) )
{ if ( GetLastError() != ERROR_NO_TOKEN )
goto simple;
if ( !OpenProcessToken(GetCurrentProcess(),
TOKEN_DUPLICATE | TOKEN_READ,
&token) )
goto simple;
}
if ( !DuplicateToken(token,
SecurityImpersonation,
&imp_token) )
goto simple;
if (mode & R_OK) desired_access |= GENERIC_READ;
if (mode & W_OK) desired_access |= GENERIC_WRITE;
if (mode & X_OK) desired_access |= GENERIC_EXECUTE;
generic_mapping.GenericRead = FILE_GENERIC_READ;
generic_mapping.GenericWrite = FILE_GENERIC_WRITE;
generic_mapping.GenericExecute = FILE_GENERIC_EXECUTE;
generic_mapping.GenericAll = FILE_ALL_ACCESS;
MapGenericMask(&desired_access, &generic_mapping);
if ( !AccessCheck(sd,
imp_token,
desired_access,
&generic_mapping,
&privelege_set,
&priv_set_len,
&granted_access,
&access_status) )
goto simple;
if ( access_status )
retval = 0;
out:
if ( sd && (char*)sd != sd_buf ) free(sd);
if (imp_token) CloseHandle(imp_token);
if (token) CloseHandle(token);
return retval;
simple:
retval = _waccess(buf, mode);
goto out;
} }
@ -858,6 +961,7 @@ _xos_getenv(const char *name, char *buf, size_t buflen)
size = GetEnvironmentVariable(nm, valp, size+1); size = GetEnvironmentVariable(nm, valp, size+1);
} }
size = wcslen(valp); /* return sometimes holds 0-bytes */
if ( wcstoutf8(buf, valp, buflen) ) if ( wcstoutf8(buf, valp, buflen) )
rc = strlen(buf); rc = strlen(buf);
else else
@ -876,16 +980,27 @@ _xos_getenv(const char *name, char *buf, size_t buflen)
int int
_xos_setenv(const char *name, char *value, int overwrite) _xos_setenv(const char *name, char *value, int overwrite)
{ TCHAR nm[PATH_MAX]; { TCHAR nm[PATH_MAX];
TCHAR val[PATH_MAX]; TCHAR buf[PATH_MAX];
TCHAR *val = buf;
int rc;
if ( !utf8towcs(nm, name, PATH_MAX) ) if ( !utf8towcs(nm, name, PATH_MAX) )
return -1; return -1;
if ( !overwrite && GetEnvironmentVariable(nm, NULL, 0) > 0 ) if ( !overwrite && GetEnvironmentVariable(nm, NULL, 0) > 0 )
return 0; return 0;
if ( !utf8towcs(val, value, PATH_MAX) ) if ( !utf8towcs(val, value, PATH_MAX) )
return -1; { size_t wlen = utf8_strlen(value, strlen(value)) + 1;
if ( SetEnvironmentVariable(nm, val) ) if ( (val = malloc(wlen*sizeof(TCHAR))) == NULL )
return -1;
utf8towcs(val, value, wlen);
}
rc = SetEnvironmentVariable(nm, val);
if ( val != buf )
free(val);
if ( rc )
return 0; return 0;
return -1; /* TBD: convert error */ return -1; /* TBD: convert error */

View File

@ -37,7 +37,7 @@ LIBDIR=@libdir@
YAPLIBDIR=@libdir@/Yap YAPLIBDIR=@libdir@/Yap
SHAREDIR=$(ROOTDIR)/share/Yap SHAREDIR=$(ROOTDIR)/share/Yap
abs_top_builddir=@abs_top_builddir@ abs_top_builddir=@abs_top_builddir@
PL=@INSTALL_ENV@ $(DESTDIR)$(BINDIR)/yap $(DESTDIR)$(YAPLIBDIR)/startup.yss PL=@PRE_INSTALL_ENV@ $(abs_top_builddir)/yap $(abs_top_builddir)/startup.yss
CC=@CC@ CC=@CC@
LD=@SHLIB_LD@ LD=@SHLIB_LD@

@ -1 +1 @@
Subproject commit 270146c1f4117ebb58d20c2f06e58d7d23cbc9ca Subproject commit 79a369f81a44a6cbf16d50351fbfbffc23f90f03

Some files were not shown because too many files have changed in this diff Show More