This commit is contained in:
Vitor Santos Costa 2018-02-14 00:13:13 +00:00
parent 37f7eb3cf3
commit fe496e840d
25 changed files with 462 additions and 241 deletions

View File

@ -2108,31 +2108,23 @@ X_API int YAP_InitConsult(int mode, const char *fname, char *full, int *osnop) {
const char *fl = NULL; const char *fl = NULL;
int lvl = push_text_stack(); int lvl = push_text_stack();
if (mode == YAP_BOOT_MODE) { if (mode == YAP_BOOT_MODE) {
mode = YAP_CONSULT_MODE; mode = YAP_CONSULT_MODE; }
}
char *bfp = Malloc(YAP_FILENAME_MAX + 1);
bfp[0] = '\0';
if (fname == NULL || fname[0] == '\0') { if (fname == NULL || fname[0] == '\0') {
fname = Yap_BOOTFILE; fl = Yap_BOOTFILE;
} }
if (fname) { if (fname) {
fl = Yap_AbsoluteFile(fname, bfp, true); fl = Yap_AbsoluteFile(fname, true);
if (!fl || !fl[0]) { if (!fl || !fl[0]) {
pop_text_stack(lvl); pop_text_stack(lvl);
return -1; return -1;
} }
} }
bool consulted = (mode == YAP_CONSULT_MODE); bool consulted = (mode == YAP_CONSULT_MODE);
sno = Yap_OpenStream(fl, "r", MkAtomTerm(Yap_LookupAtom(bfp))); sno = Yap_OpenStream(fl, "r", MkAtomTerm(Yap_LookupAtom(fl)));
if (!Yap_ChDir(dirname((char *)fl))) return -1; if (sno < 0)
Yap_init_consult(consulted, bfp);
*osnop = Yap_CheckAlias(AtomLoopStream);
if (!Yap_AddAlias(AtomLoopStream, sno)) {
Yap_CloseStream(sno);
pop_text_stack(lvl);
sno = -1;
return sno; return sno;
} if (!Yap_ChDir(dirname((char *)fl))) return -1;
Yap_init_consult(consulted, fl);
GLOBAL_Stream[sno].name = Yap_LookupAtom(fl); GLOBAL_Stream[sno].name = Yap_LookupAtom(fl);
GLOBAL_Stream[sno].user_name = MkAtomTerm(Yap_LookupAtom(fname)); GLOBAL_Stream[sno].user_name = MkAtomTerm(Yap_LookupAtom(fname));
GLOBAL_Stream[sno].encoding = LOCAL_encoding; GLOBAL_Stream[sno].encoding = LOCAL_encoding;
@ -2167,7 +2159,8 @@ X_API void YAP_EndConsult(int sno, int *osnop, const char *full) {
if (osnop >= 0) if (osnop >= 0)
Yap_AddAlias(AtomLoopStream, *osnop); Yap_AddAlias(AtomLoopStream, *osnop);
Yap_end_consult(); Yap_end_consult();
__android_log_print(ANDROID_LOG_INFO, "YAPDroid ", " closing %s(%d), %d", full, *osnop, sno);
// LOCAL_CurSlot);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
} }

View File

@ -51,6 +51,57 @@ static Int p_dif( USES_REGS1 );
static Int p_eq( USES_REGS1 ); static Int p_eq( USES_REGS1 );
static Int p_arg( USES_REGS1 ); static Int p_arg( USES_REGS1 );
static Int p_functor( USES_REGS1 ); static Int p_functor( USES_REGS1 );
static Int p_fail( USES_REGS1 );
static Int p_true( USES_REGS1 );
/** @pred fail is iso
Always fails. Defined as if by:
~~~~~
fail :- 2=1.
~~~~~
*/
/** @pred false is iso
The same as fail. Defined as if by:
~~~~~
false :- 2=1.
~~~~~
*/
static Int p_fail( USES_REGS1 )
{
return false;
}
/** @pred true is iso
Succeed.
Succeeds once. Defined as if by:
~~~~~
true :- true.
~~~~~
*/
/** @pred otherwise is iso
Succeed.
Succeeds once. Defined as if by:
~~~~~
otherwise.
~~~~~
*/
static Int p_true( USES_REGS1 )
{
return true;
}
/** @pred atom( _T_) is iso /** @pred atom( _T_) is iso
@ -1150,6 +1201,10 @@ cont_genarg( USES_REGS1 )
CurrentModule = ARG_MODULE; CurrentModule = ARG_MODULE;
Yap_InitCPredBack("genarg", 3, 3, genarg, cont_genarg,SafePredFlag); Yap_InitCPredBack("genarg", 3, 3, genarg, cont_genarg,SafePredFlag);
CurrentModule = cm; CurrentModule = cm;
} Yap_InitCPred("true", 0, p_true, SafePredFlag);
Yap_InitCPred("otherwise", 0, p_true, SafePredFlag);
Yap_InitCPred("false", 0, p_fail, SafePredFlag);
Yap_InitCPred("fail", 0, p_fail, SafePredFlag);
}

View File

@ -1319,7 +1319,7 @@ static int commit_to_saved_state(const char *s, CELL *Astate, CELL *ATrail,
LOCAL_PrologMode = BootMode; LOCAL_PrologMode = BootMode;
if (Yap_HeapBase) { if (Yap_HeapBase) {
if (falseGlobalPrologFlag(HALT_AFTER_CONSULT_FLAG) && !silentMode()) { if (falseGlobalPrologFlag(HALT_AFTER_CONSULT_FLAG) && !silentMode()) {
Yap_AbsoluteFile(s, tmp, true); strcpy(tmp, Yap_AbsoluteFile(s, true));
fprintf(stderr, "%% Restoring file %s\n", tmp); fprintf(stderr, "%% Restoring file %s\n", tmp);
} }
Yap_CloseStreams(TRUE); Yap_CloseStreams(TRUE);

View File

@ -539,7 +539,8 @@ static inline int getchr(struct stream_desc *inp) {
* **********************************\n", AtomName(inp->name)); */ * **********************************\n", AtomName(inp->name)); */
/* inp0 = inp; */ /* inp0 = inp; */
/* } */ /* } */
int ch = inp->stream_wgetc_for_read(inp - GLOBAL_Stream); int sno = inp - GLOBAL_Stream;
int ch = inp->stream_wgetc_for_read(sno);
// fprintf(stderr,"%c", ch); // fprintf(stderr,"%c", ch);
return ch; return ch;
} }
@ -1334,7 +1335,6 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
LOCAL_AnonVarTable = NULL; LOCAL_AnonVarTable = NULL;
l = NULL; l = NULL;
p = NULL; /* Just to make lint happy */ p = NULL; /* Just to make lint happy */
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "i %d", st - GLOBAL_Stream);
ch = getchr(st); ch = getchr(st);
while (chtype(ch) == BS) { while (chtype(ch) == BS) {
ch = getchr(st); ch = getchr(st);

View File

@ -1349,13 +1349,17 @@ static Int p_statistics_lu_db_size(USES_REGS1) {
} }
static Int p_executable(USES_REGS1) { static Int p_executable(USES_REGS1) {
char tmp[YAP_FILENAME_MAX+1]; int lvl = push_text_stack();
if (GLOBAL_argv && GLOBAL_argv[0]) const char *tmp =
Yap_AbsoluteFile(GLOBAL_argv[0], tmp, true);
else
strncpy(tmp, Yap_FindExecutable(), YAP_FILENAME_MAX);
return Yap_unify(MkAtomTerm(Yap_LookupAtom(tmp)), ARG1); Yap_AbsoluteFile(GLOBAL_argv[0], true);
if (!tmp || tmp[0] == '\0' ) {
tmp = Malloc(YAP_FILENAME_MAX + 1);
strncpy((char *)tmp, Yap_FindExecutable(), YAP_FILENAME_MAX);
}
Atom at = Yap_LookupAtom(tmp);
pop_text_stack(lvl);
return Yap_unify(MkAtomTerm(at), ARG1);
} }
static Int p_system_mode(USES_REGS1) { static Int p_system_mode(USES_REGS1) {

View File

@ -20,6 +20,7 @@
#include "YapHeap.h" #include "YapHeap.h"
#include "YapInterface.h" #include "YapInterface.h"
#include "YapStreams.h" #include "YapStreams.h"
#include "iopreds.h"
#include "config.h" #include "config.h"
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -161,34 +162,42 @@ const char *Yap_BINDIR, *Yap_ROOTDIR, *Yap_SHAREDIR, *Yap_LIBDIR, *Yap_DLLDIR,
/* do initial boot by consulting the file boot.yap */ /* do initial boot by consulting the file boot.yap */
static void consult(const char *b_file USES_REGS) { static void consult(const char *b_file USES_REGS) {
Term t; Term t;
int boot_stream, osno; int c_stream, osno, oactive;
Functor functor_query = Yap_MkFunctor(Yap_LookupAtom("?-"), 1); Functor functor_query = Yap_MkFunctor(Yap_LookupAtom("?-"), 1);
Functor functor_command1 = Yap_MkFunctor(Yap_LookupAtom(":-"), 1); Functor functor_command1 = Yap_MkFunctor(Yap_LookupAtom(":-"), 1);
Functor functor_compile2 = Yap_MkFunctor(Yap_LookupAtom("c_compile"), 1); Functor functor_compile2 = Yap_MkFunctor(Yap_LookupAtom("c_compile"), 1);
/* consult boot.pl */ /* consult boot.pl */
char *full = malloc(YAP_FILENAME_MAX + 1); int lvl = push_text_stack();
char *full = Malloc(YAP_FILENAME_MAX + 1);
full[0] = '\0'; full[0] = '\0';
/* the consult mode does not matter here, really */ /* the consult mode does not matter here, really */
boot_stream = YAP_InitConsult(YAP_BOOT_MODE, b_file, full, &osno); if ((osno = Yap_CheckAlias(AtomLoopStream)) < 0)
if (boot_stream < 0) { osno = 0;
c_stream = YAP_InitConsult(YAP_BOOT_MODE, b_file, full, &oactive);
if (c_stream < 0) {
pop_text_stack(lvl);
fprintf(stderr, "[ FATAL ERROR: could not open stream %s ]\n", b_file); fprintf(stderr, "[ FATAL ERROR: could not open stream %s ]\n", b_file);
exit(1); exit(1);
} }
if (!Yap_AddAlias(AtomLoopStream, c_stream)) {
pop_text_stack(lvl);
return;
}
do { do {
CACHE_REGS CACHE_REGS
YAP_Reset(YAP_FULL_RESET, false); YAP_Reset(YAP_FULL_RESET, false);
Yap_StartSlots(); Yap_StartSlots();
Term vs = YAP_MkVarTerm(), pos = MkVarTerm(); Term vs = YAP_MkVarTerm(), pos = MkVarTerm();
t = YAP_ReadClauseFromStream(boot_stream, vs, pos); t = YAP_ReadClauseFromStream(c_stream, vs, pos);
// Yap_GetNèwSlot(t); // Yap_GetNèwSlot(t);
if (t == 0) { if (t == 0) {
fprintf(stderr, "[ SYNTAX ERROR: while parsing stream %s at line %ld ]\n", fprintf(stderr, "[ SYNTAX ERROR: while parsing stream %s at line %ld ]\n",
b_file, GLOBAL_Stream[boot_stream].linecount); b_file, GLOBAL_Stream[c_stream].linecount);
} else if (IsVarTerm(t) || t == TermNil) { } else if (IsVarTerm(t) || t == TermNil) {
fprintf(stderr, "[ line %d: term cannot be compiled ]", fprintf(stderr, "[ line %d: term cannot be compiled ]",
GLOBAL_Stream[boot_stream].linecount); GLOBAL_Stream[c_stream].linecount);
} else if (IsApplTerm(t) && (FunctorOfTerm(t) == functor_query || } else if (IsApplTerm(t) && (FunctorOfTerm(t) == functor_query ||
FunctorOfTerm(t) == functor_command1)) { FunctorOfTerm(t) == functor_command1)) {
t = ArgOfTerm(1, t); t = ArgOfTerm(1, t);
@ -206,13 +215,8 @@ static void consult(const char *b_file USES_REGS) {
} }
} while (t != TermEof); } while (t != TermEof);
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
YAP_EndConsult(c_stream, &osno, full);
YAP_EndConsult(boot_stream, &osno, full); pop_text_stack(lvl);
free(full);
#if DEBUG
if (Yap_output_msg)
fprintf(stderr, "Boot loaded\n");
#endif
} }
/** @brief A simple language for detecting where YAP stuff can be found /** @brief A simple language for detecting where YAP stuff can be found
@ -241,6 +245,19 @@ typedef struct config {
const char **bootpl; const char **bootpl;
} config_t; } config_t;
#if __ANDROID__
const char *gd_root[] = {"@RootDir", "/assets"};
const char *gd_lib[] = {"@LibDir", "[lib]", "(root)/lib/" "x86"};
const char *gd_share[] = {"@ShareDir", "(root)"};
const char *gd_include[] = {"@IncludeDir", "[include]", "(root)/include"};
const char *gd_dll[] = {"@DLLDir", "(lib)"};
const char *gd_pl[] = {"@PlDir", "(share)/Yap", "@BootPlDir/../library"};
const char *gd_commons[] = {"@CommonsDir", "(share)/PrologCommons"};
const char *gd_ss[] = {"(dll)"};
const char *gd_oss[] = {"."};
const char *gd_bootpldir[] = {"@BootPlDir", "@PrologBootFile/..", "(pl)/pl"};
const char *gd_bootpl[] = {"(bootpldir)" };
#else
const char *gd_root[] = {"@RootDir", "[root]", "(execdir)/.."}; const char *gd_root[] = {"@RootDir", "[root]", "(execdir)/.."};
const char *gd_lib[] = {"@LibDir", "[lib]", "(root)/lib"}; const char *gd_lib[] = {"@LibDir", "[lib]", "(root)/lib"};
const char *gd_share[] = {"@ShareDir", "[share]", "(root)/share"}; const char *gd_share[] = {"@ShareDir", "[share]", "(root)/share"};
@ -252,8 +269,9 @@ const char *gd_ss[] = {"(dll)"};
const char *gd_oss[] = {"."}; const char *gd_oss[] = {"."};
const char *gd_bootpldir[] = {"@BootPlDir", "@PrologBootFile/..", "(pl)/pl"}; const char *gd_bootpldir[] = {"@BootPlDir", "@PrologBootFile/..", "(pl)/pl"};
const char *gd_bootpl[] = {"@PrologBootFile", "(bootpldir)/setup.yap"}; const char *gd_bootpl[] = {"@PrologBootFile", "(bootpldir)/setup.yap"};
#endif
static config_t *gnu(config_t *i) { static config_t *cfg(config_t *i) {
i->root = gd_root; i->root = gd_root;
i->lib = gd_lib; i->lib = gd_lib;
i->share = gd_share; i->share = gd_share;
@ -272,10 +290,11 @@ static config_t *gnu(config_t *i) {
/** /**
* Search * Search
*/ */
char *location(YAP_init_args *iap, const char *inp, char *out) { char *location(YAP_init_args *iap, const char *inp) {
if (inp == NULL || inp[0] == '\0') { if (inp == NULL || inp[0] == '\0') {
return NULL; return NULL;
} }
char * out = Malloc(FILENAME_MAX+1);
out[0] = '\0'; out[0] = '\0';
if (inp[0] == '(') { if (inp[0] == '(') {
if (strstr(inp + 1, "root") == inp + 1 && Yap_ROOTDIR && if (strstr(inp + 1, "root") == inp + 1 && Yap_ROOTDIR &&
@ -311,8 +330,7 @@ char *location(YAP_init_args *iap, const char *inp, char *out) {
strcpy(out, Yap_BOOTFILE); strcpy(out, Yap_BOOTFILE);
strcat(out, inp + strlen("(bootpl)")); strcat(out, inp + strlen("(bootpl)"));
} else if (strstr(inp + 1, "execdir") == inp + 1) { } else if (strstr(inp + 1, "execdir") == inp + 1) {
char *buf = Malloc(YAP_FILENAME_MAX + 1); const char *ex = Yap_AbsoluteFile(Yap_FindExecutable(), true);
const char *ex = Yap_AbsoluteFile(Yap_FindExecutable(), buf, true);
if (ex != NULL) { if (ex != NULL) {
strcpy(out, dirname((char *)ex)); strcpy(out, dirname((char *)ex));
strcat(out, "/"); strcat(out, "/");
@ -447,19 +465,16 @@ static const char *find_directory(YAP_init_args *iap, const char *paths[],
} }
int i = 0; int i = 0;
while ((inp = paths[i++]) != NULL) { while ((inp = paths[i++]) != NULL) {
out[0] = '\0'; char *o = location(iap, inp);
const char *o = location(iap, inp, out); if (filename && o) {
char qp[FILENAME_MAX + 1];
if (o && o[0] && (o = Yap_AbsoluteFile(o, qp, false)) &&
Yap_isDirectory(o)) {
if (filename) {
strcat(o, "/"); strcat(o, "/");
strcat(o, filename); strcat(o, filename);
} if (o =(const char *) Yap_AbsoluteFile(o, false)) {
o = pop_output_text_stack(lvl, o); o = pop_output_text_stack(lvl, o);
return o; return o;
} }
} }
}
pop_text_stack(lvl); pop_text_stack(lvl);
return NULL; return NULL;
} }
@ -467,7 +482,7 @@ static const char *find_directory(YAP_init_args *iap, const char *paths[],
static void Yap_set_locations(YAP_init_args *iap) { static void Yap_set_locations(YAP_init_args *iap) {
config_t t, *template; config_t t, *template;
template = gnu(&t); template = cfg(&t);
Yap_ROOTDIR = find_directory(iap, template->root, NULL); Yap_ROOTDIR = find_directory(iap, template->root, NULL);
Yap_LIBDIR = find_directory(iap, template->lib, NULL); Yap_LIBDIR = find_directory(iap, template->lib, NULL);
// Yap_BINDIR = find_directory(iap, template->bin, NULL); // Yap_BINDIR = find_directory(iap, template->bin, NULL);
@ -475,7 +490,9 @@ static void Yap_set_locations(YAP_init_args *iap) {
Yap_DLLDIR = find_directory(iap, template->dll, NULL); Yap_DLLDIR = find_directory(iap, template->dll, NULL);
Yap_PLDIR = find_directory(iap, template->pl, NULL); Yap_PLDIR = find_directory(iap, template->pl, NULL);
Yap_BOOTPLDIR = find_directory(iap, template->bootpldir, NULL); Yap_BOOTPLDIR = find_directory(iap, template->bootpldir, NULL);
Yap_BOOTFILE = find_directory(iap, template->bootpldir, "setup.yap"); if (iap->PrologBootFile == NULL)
iap->PrologBootFile = "boot.yap";
Yap_BOOTFILE = find_directory(iap, template->bootpldir,iap->PrologBootFile );
Yap_COMMONSDIR = find_directory(iap, template->commons, NULL); Yap_COMMONSDIR = find_directory(iap, template->commons, NULL);
if (iap->SavedState == NULL) if (iap->SavedState == NULL)
iap->SavedState = "startup.yss"; iap->SavedState = "startup.yss";
@ -483,9 +500,6 @@ static void Yap_set_locations(YAP_init_args *iap) {
if (iap->OutputSavedState == NULL) if (iap->OutputSavedState == NULL)
iap->OutputSavedState = "startup.yss"; iap->OutputSavedState = "startup.yss";
Yap_OUTPUT_STARTUP = find_directory(iap, template->ss, iap->OutputSavedState); Yap_OUTPUT_STARTUP = find_directory(iap, template->ss, iap->OutputSavedState);
if (iap->PrologBootFile == NULL)
iap->PrologBootFile = "boot.yap";
Yap_BOOTFILE = find_directory(iap, template->bootpldir, iap->PrologBootFile);
if (Yap_ROOTDIR) if (Yap_ROOTDIR)
setAtomicGlobalPrologFlag(HOME_FLAG, setAtomicGlobalPrologFlag(HOME_FLAG,
MkAtomTerm(Yap_LookupAtom(Yap_ROOTDIR))); MkAtomTerm(Yap_LookupAtom(Yap_ROOTDIR)));
@ -637,9 +651,9 @@ X_API YAP_file_type_t YAP_parse_yap_arguments(int argc, char *argv[],
case 'B': case 'B':
iap->boot_file_type = YAP_BOOT_PL; iap->boot_file_type = YAP_BOOT_PL;
if (p[1]) if (p[1])
iap->BootPlDir = p + 1; iap->PrologBootFile = p + 1;
else if (argv[1] && *argv[1] != '-') { else if (argv[1] && *argv[1] != '-') {
iap->BootPlDir = *++argv; iap->PrologBootFile = *++argv;
argc--; argc--;
} }
iap->install = true; iap->install = true;
@ -1160,6 +1174,7 @@ X_API YAP_file_type_t YAP_Init(YAP_init_args *yap_init) {
/* tell the system who should cope with interrupts */ /* tell the system who should cope with interrupts */
Yap_ExecutionMode = yap_init->ExecutionMode; Yap_ExecutionMode = yap_init->ExecutionMode;
Yap_set_locations(yap_init); Yap_set_locations(yap_init);
if (!do_bootstrap && Yap_STARTUP && yap_init->boot_file_type != YAP_BOOT_PL && if (!do_bootstrap && Yap_STARTUP && yap_init->boot_file_type != YAP_BOOT_PL &&
Yap_SavedInfo(Yap_STARTUP, &minfo.Trail, &minfo.Stack, &minfo.Heap) && Yap_SavedInfo(Yap_STARTUP, &minfo.Trail, &minfo.Stack, &minfo.Heap) &&
Yap_Restore(Yap_STARTUP)) { Yap_Restore(Yap_STARTUP)) {
@ -1179,6 +1194,7 @@ X_API YAP_file_type_t YAP_Init(YAP_init_args *yap_init) {
Term t = MkAtomTerm(Yap_LookupAtom(Yap_OUTPUT_STARTUP)); Term t = MkAtomTerm(Yap_LookupAtom(Yap_OUTPUT_STARTUP));
Term g = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("qsave_program"), 1), Term g = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("qsave_program"), 1),
1, &t); 1, &t);
YAP_RunGoalOnce(g); YAP_RunGoalOnce(g);
} }
setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG, setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG,

View File

@ -568,7 +568,7 @@ List(APPEND YLIBS $<TARGET_OBJECTS:libswi>)
if (WIN32 OR ANDROID) if (WIN32 OR ANDROID)
List(APPEND YLIBS $<TARGET_OBJECTS:Yapsqlite3>) List(APPEND YLIBS $<TARGET_OBJECTS:Yapsqlite3>)
List(APPEND YLIBS $<TARGET_OBJECTS:YAP++>) List(APPEND YLIBS $<TARGET_OBJECTS:YAP++>)
if (WITH_PYTHON) if (WIN32 AND WITH_PYTHON)
List(APPEND YLIBS $<TARGET_OBJECTS:Py4YAP>) List(APPEND YLIBS $<TARGET_OBJECTS:Py4YAP>)
endif () endif ()
endif () endif ()

View File

@ -9,13 +9,13 @@ set (CXX_SOURCES
) )
list(APPEND LIBYAP_SOURCES ${CXX_SOURCES} PARENT_SCOPE) list(APPEND LIBYAP_SOURCES ${CXX_SOURCES} PARENT_SCOPE)
if ( WIN32) if ( WIN32 OR ANDROID)
add_component (YAP++ ${CXX_SOURCES} ) add_component (YAP++ ${CXX_SOURCES} )
set_property( DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "_YAP_NOT_INSTALLED_=1;HAVE_CONFIG_H=1;_GNU_SOURCE;YAP_KERNEL=1" ) set_property( DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "_YAP_NOT_INSTALLED_=1;HAVE_CONFIG_H=1;_GNU_SOURCE;YAP_KERNEL=1" )
else() else()
add_lib(YAP++ ${CXX_SOURCES} ) add_lib(YAP++ ${CXX_SOURCES} )
MY_target_link_libraries(YAP++ ${CMAKE_DL_LIBS} libYap) target_link_libraries(YAP++ ${CMAKE_DL_LIBS} libYap)
MY_install(TARGETS YAP++ MY_install(TARGETS YAP++
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}

View File

@ -12,6 +12,7 @@ extern "C" {
#include "YapInterface.h" #include "YapInterface.h"
#include "blobs.h" #include "blobs.h"
#include "iopreds.h"
X_API char *Yap_TermToBuffer(Term t, encoding_t encodingp, int flags); X_API char *Yap_TermToBuffer(Term t, encoding_t encodingp, int flags);
@ -843,8 +844,8 @@ void Yap_displayWithJava(int c) {
#endif #endif
void YAPEngine::doInit(YAP_file_type_t BootMode) { void YAPEngine::doInit(YAP_file_type_t BootMode, YAPEngineArgs *engineArgs) {
if ((BootMode = YAP_Init(engine_args)) == YAP_FOUND_BOOT_ERROR) { if ((BootMode = YAP_Init(engineArgs)) == YAP_FOUND_BOOT_ERROR) {
return; return;
throw YAPError(); throw YAPError();
} }
@ -874,7 +875,7 @@ YAPEngine::YAPEngine(int argc, char *argv[],
// if (cb) // if (cb)
// setYAPCallback(cb); // setYAPCallback(cb);
doInit(BootMode); doInit(BootMode, engine_args);
} }
YAPPredicate::YAPPredicate(YAPAtom at) { YAPPredicate::YAPPredicate(YAPAtom at) {

View File

@ -188,7 +188,7 @@ public:
/// @brief Setup all arguments to a new engine /// @brief Setup all arguments to a new engine
struct X_API YAPEngineArgs : YAP_init_args { struct X_API YAPEngineArgs : YAP_init_args {
public: public:
YAPEngineArgs() : yap_boot_params() { YAPEngineArgs() {
const std::string *s = new std::string("startup.yss"); const std::string *s = new std::string("startup.yss");
Embedded = true; Embedded = true;
Yap_InitDefaults(this, (char *)s->c_str(), 0, nullptr); Yap_InitDefaults(this, (char *)s->c_str(), 0, nullptr);
@ -294,7 +294,7 @@ private:
YAPEngineArgs *engine_args; YAPEngineArgs *engine_args;
YAPCallback *_callback; YAPCallback *_callback;
YAPError yerror; YAPError yerror;
void doInit(YAP_file_type_t BootMode); void doInit(YAP_file_type_t BootMode, YAPEngineArgs *cargs);
YAP_dogoalinfo q; YAP_dogoalinfo q;
PredEntry *rewriteUndefEngineQuery(PredEntry *ap, Term t, Term tmod); PredEntry *rewriteUndefEngineQuery(PredEntry *ap, Term t, Term tmod);
@ -303,7 +303,7 @@ public:
YAPEngine(YAPEngineArgs *cargs) { YAPEngine(YAPEngineArgs *cargs) {
engine_args = cargs; engine_args = cargs;
// doInit(cargs->boot_file_type); // doInit(cargs->boot_file_type);
doInit(YAP_QLY); doInit(YAP_QLY, cargs);
}; /// construct a new engine, including aaccess to callbacks }; /// construct a new engine, including aaccess to callbacks
/// construct a new engine using argc/argv list of arguments /// construct a new engine using argc/argv list of arguments
YAPEngine(int argc, char *argv[], YAPEngine(int argc, char *argv[],

View File

@ -450,7 +450,7 @@ extern int Yap_output_msg;
#include <android/log.h> #include <android/log.h>
#include <jni.h> #include <jni.h>
extern AAssetManager *Yap_assetManager; extern AAssetManager *Yap_assetManager(void);
extern void *Yap_openAssetFile(const char *path); extern void *Yap_openAssetFile(const char *path);
extern bool Yap_isAsset(const char *path); extern bool Yap_isAsset(const char *path);

View File

@ -295,7 +295,6 @@ extern int Yap_eq(Term, Term);
/* iopreds.c */ /* iopreds.c */
extern bool Yap_IsAbsolutePath(const char *p, bool); extern bool Yap_IsAbsolutePath(const char *p, bool);
extern Atom Yap_TemporaryFile(const char *prefix, int *fd); extern Atom Yap_TemporaryFile(const char *prefix, int *fd);
extern const char *Yap_AbsoluteFile(const char *spec, char *obuf, bool expand);
extern void Yap_InitPlIO( struct yap_boot_params *ts ); extern void Yap_InitPlIO( struct yap_boot_params *ts );
extern void Yap_InitBackIO(void); extern void Yap_InitBackIO(void);
extern void Yap_InitIOPreds(void); extern void Yap_InitIOPreds(void);
@ -413,9 +412,9 @@ extern int Yap_signal_index(const char *);
#ifdef MAC #ifdef MAC
extern void Yap_SetTextFile(char *); extern void Yap_SetTextFile(char *);
#endif #endif
extern const char *Yap_AbsoluteFile(const char *spec, bool expand);
#if __ANDROID__ #if __ANDROID__
#include <android/asset_manager.h> #include <android/asset_manager.h>
extern AAssetManager *Yap_assetManager;
extern void *Yap_openAssetFile(const char *path); extern void *Yap_openAssetFile(const char *path);
extern bool Yap_isAsset(const char *path); extern bool Yap_isAsset(const char *path);
@ -433,7 +432,6 @@ extern char *Yap_RegistryGetString(char *);
extern void Yap_WinError(char *); extern void Yap_WinError(char *);
#endif #endif
extern const char *Yap_AbsoluteFile(const char *spec, char *obuf, bool ok);
extern const char *Yap_AbsoluteFileInBuffer(const char *spec, char *outp, size_t sz, extern const char *Yap_AbsoluteFileInBuffer(const char *spec, char *outp, size_t sz,
bool ok); bool ok);
extern bool Yap_ChDir(const char *path); extern bool Yap_ChDir(const char *path);

View File

@ -128,10 +128,7 @@ static inline VFS_t *vfs_owner(const char *fname) {
while (me) { while (me) {
bool p = true; bool p = true;
if ((me->vflags & VFS_HAS_PREFIX) && p) { if ((me->vflags & VFS_HAS_PREFIX) && p) {
const char *r = fname, *s = me->prefix; if (strstr(fname,me->prefix)==fname)
while (*s && p)
p = *s++ == *r++;
if (p && r > fname + 1)
return me; return me;
} }
if (me->vflags & VFS_HAS_SUFFIX && (sz = strlen(me->suffix)) && if (me->vflags & VFS_HAS_SUFFIX && (sz = strlen(me->suffix)) &&

View File

@ -36,43 +36,71 @@ static char SccsId[] = "%W% %G%";
#if __ANDROID__ #if __ANDROID__
#include <jni.h>
#include <android/asset_manager.h> #include <android/asset_manager.h>
#include <android/native_activity.h> #include <android/native_activity.h>
AAssetManager *Yap_assetManager; jobject *Yap_aref;
JNIEnv *Yap_env;
AAssetManager *Yap_assetManager(void)
{
return AAssetManager_fromJava(Yap_env, Yap_aref);
}
jboolean jboolean
Java_pt_up_yap_app_YAPDroid_setAssetManager(JNIEnv *env, jclass clazz, jobject assetManager) { Java_pt_up_yap_app_YAPDroid_setAssetManager(JNIEnv *env, jclass clazz, jobject assetManager) {
Yap_assetManager = AAssetManager_fromJava(env, assetManager); Yap_aref = (*env)->NewGlobalRef(env,assetManager);
Yap_env = env;
return true; return true;
} }
static void * static void *
open_asset__(VFS_t *me, int sno, const char *fname, const char *io_mode) { open_asset(VFS_t *me, int sno, const char *fname, const char *io_mode) {
int mode; int mode;
const void *buf; const void *buf;
AAsset *am = NULL;
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s <%s>", fname, io_mode);
if (strchr(io_mode, 'B')) if (strchr(io_mode, 'B'))
mode = AASSET_MODE_BUFFER; mode = AASSET_MODE_BUFFER;
else { else {
mode = AASSET_MODE_UNKNOWN; mode = AASSET_MODE_UNKNOWN;
} }
fname += strlen(me->prefix) + 1; GLOBAL_Stream[sno].name = Yap_LookupAtom(fname);
AAsset *a = AAssetManager_open(Yap_assetManager, fname, mode); fname += strlen(me->prefix)+1;
if (!a) // strcpy(dir, fname);
// AAssetDir *dp = AAssetManager_openDir( Yap_assetManager(), dirname(dir) );
// strcpy(dir, fname);
// char *d = basename(dir);
am = AAssetManager_open(Yap_assetManager(), fname, mode);
// while (dp) {
// char *f = AAssetDir_getNextFileName(dp);
// __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s <%s>", f, d);
// if (f && strcasecmp(d,f) == 0) {
//
// }
// }
if (!am)
return NULL; return NULL;
// try not to use it as an asset // try not to use it as an asset
off64_t sz = AAsset_getLength64(a), sz0 = 0; off64_t sz = AAsset_getLength64(am), sz0 = 0;
int fd; int fd;
StreamDesc *st = GLOBAL_Stream + sno; StreamDesc *st = GLOBAL_Stream + sno;
if ((buf = AAsset_getBuffer(a))) { if ((buf = AAsset_getBuffer(am))) {
// copy to memory // copy to memory
bool rc = Yap_set_stream_to_buf(st, buf, sz); char *bf = malloc(sz);
if (rc) AAsset_close(a); memcpy(bf, buf, sz);
bool rc = Yap_set_stream_to_buf(st, bf, sz);
if (rc) AAsset_close(am);
st->vfs = NULL; st->vfs = NULL;
st->vfs_handle = NULL; st->vfs_handle = NULL;
st->status = InMemory_Stream_f|Seekable_Stream_f|Input_Stream_f; st->status = InMemory_Stream_f|Seekable_Stream_f|Input_Stream_f;
return st; return st;
} else if ((fd = AAsset_openFileDescriptor64(a, &sz0, &sz)) >= 0) { } else if ((fd = AAsset_openFileDescriptor64(am, &sz0, &sz)) >= 0) {
// can use it as read-only file // can use it as read-only file
st->file = fdopen(fd, "r"); st->file = fdopen(fd, "r");
st->vfs = NULL; st->vfs = NULL;
@ -81,10 +109,10 @@ open_asset__(VFS_t *me, int sno, const char *fname, const char *io_mode) {
return st; return st;
} else { } else {
// should be done, but if not // should be done, but if not
GLOBAL_Stream[sno].vfs_handle = a; GLOBAL_Stream[sno].vfs_handle = am;
st->vfs = me; st->vfs = me;
st->status = Input_Stream_f; st->status = Input_Stream_f;
return a; return am;
} }
} }
@ -108,7 +136,7 @@ static int getc_asset(int sno) {
static void *opendir_a(VFS_t *me, const char *dirName) { static void *opendir_a(VFS_t *me, const char *dirName) {
dirName += strlen(me->prefix) + 1; dirName += strlen(me->prefix) + 1;
return (void *) AAssetManager_openDir(Yap_assetManager, dirName); return (void *) AAssetManager_openDir(Yap_assetManager(), dirName);
} }
static const char *readdir_a(void *dirHandle) { static const char *readdir_a(void *dirHandle) {
@ -135,7 +163,7 @@ static bool stat_a(VFS_t *me, const char *fname, vfs_stat *out) {
memcpy(&out->st_birthtimespec, (const void *) &out->st_birthtimespec, memcpy(&out->st_birthtimespec, (const void *) &out->st_birthtimespec,
sizeof(struct timespec)); sizeof(struct timespec));
} }
AAsset *a = AAssetManager_open(Yap_assetManager, fname, AASSET_MODE_UNKNOWN); AAsset *a = AAssetManager_open(Yap_assetManager(), fname, AASSET_MODE_UNKNOWN);
// try not to use it as an asset // try not to use it as an asset
out->st_size = AAsset_getLength64(a); out->st_size = AAsset_getLength64(a);
AAsset_close(a); AAsset_close(a);
@ -145,23 +173,24 @@ static bool stat_a(VFS_t *me, const char *fname, vfs_stat *out) {
static static
bool is_dir_a(VFS_t *me, const char *dirName) { bool is_dir_a(VFS_t *me, const char *dirName) {
bool rc; dirName += strlen(me->prefix);
dirName += strlen(me->prefix) + 1; if (dirName[0] == '\0')
dirName = "/";
// try not to use it as an asset // try not to use it as an asset
AAssetDir *d = AAssetManager_openDir(Yap_assetManager, dirName); AAssetDir *d = AAssetManager_openDir(Yap_assetManager(), dirName);
if (d == NULL) if (d == NULL)
return false; return false;
rc = (AAssetDir_getNextFileName(d) != NULL); (AAssetDir_close(d));
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "isdir %s <%p>", dirName, d); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "isdir %s <%p>", dirName, d);
AAssetDir_close(d);
return rc; return true;
} }
static static
bool exists_a(VFS_t *me, const char *dirName) { bool exists_a(VFS_t *me, const char *dirName) {
dirName += strlen(me->prefix) + 1; dirName += strlen(me->prefix) + 1;
// try not to use it as an asset // try not to use it as an asset
AAsset *d = AAssetManager_open(Yap_assetManager, dirName, AASSET_MODE_UNKNOWN); AAsset *d = AAssetManager_open(Yap_assetManager(), dirName, AASSET_MODE_UNKNOWN);
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exists %s <%p>", dirName, d); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exists %s <%p>", dirName, d);
if (d == NULL) if (d == NULL)
return false; return false;
@ -170,16 +199,15 @@ bool exists_a(VFS_t *me, const char *dirName) {
} }
extern char virtual_cwd[YAP_FILENAME_MAX + 1]; char virtual_cwd[YAP_FILENAME_MAX + 1];
static bool set_cwd(VFS_t *me, const char *dirName) { static bool set_cwd(VFS_t *me, const char *dirName) {
chdir("/assets"); chdir("/assets");
strcpy(virtual_cwd, dirName); strcpy(virtual_cwd, dirName);
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", __android_log_print(ANDROID_LOG_INFO, "YAPDroid",
"chdir %s", virtual_cwd); "chdir %s", virtual_cwd);
Yap_do_low_level_trace=1; return true;
return true;
} }
#endif #endif
@ -198,7 +226,7 @@ Yap_InitAssetManager(void) {
VFS_HAS_PREFIX; /// the main flags describing the operation of the Fs. VFS_HAS_PREFIX; /// the main flags describing the operation of the Fs.
me->prefix = "/assets"; me->prefix = "/assets";
/** operations */ /** operations */
me->open = open_asset__; /// open an object in this space me->open = open_asset; /// open an object in this space
me->close = close_asset; /// close the object me->close = close_asset; /// close the object
me->get_char = getc_asset; /// get an octet to the stream me->get_char = getc_asset; /// get an octet to the stream
me->put_char = NULL; /// output an octet to the stream me->put_char = NULL; /// output an octet to the stream

View File

@ -163,6 +163,15 @@ static Int access_path(USES_REGS1) {
Yap_Error(TYPE_ERROR_ATOM, tname, "access"); Yap_Error(TYPE_ERROR_ATOM, tname, "access");
return false; return false;
} else { } else {
VFS_t *vfs;
char *s = RepAtom(AtomOfTerm(tname))->StrOfAE;
if (!s) return false;
if ((vfs = vfs_owner(s))) {
vfs_stat st;
bool rc = vfs->stat(vfs, s, &st);
UNLOCK(GLOBAL_Stream[sno].streamlock);
return rc;
}
#if HAVE_STAT #if HAVE_STAT
struct SYSTEM_STAT ss; struct SYSTEM_STAT ss;
char *file_name; char *file_name;
@ -190,6 +199,15 @@ static Int exists_file(USES_REGS1) {
Yap_Error(TYPE_ERROR_ATOM, tname, "access"); Yap_Error(TYPE_ERROR_ATOM, tname, "access");
return FALSE; return FALSE;
} else { } else {
VFS_t *vfs;
char *s = RepAtom(AtomOfTerm(tname))->StrOfAE;
if (!s) return false;
if ((vfs = vfs_owner(s))) {
vfs_stat st;
bool rc = vfs->stat(vfs, s, &st);
UNLOCK(GLOBAL_Stream[sno].streamlock);
return rc;
}
#if HAVE_STAT #if HAVE_STAT
struct SYSTEM_STAT ss; struct SYSTEM_STAT ss;
@ -249,6 +267,12 @@ static Int time_file(USES_REGS1) {
return FALSE; return FALSE;
} else { } else {
const char *n = RepAtom(AtomOfTerm(tname))->StrOfAE; const char *n = RepAtom(AtomOfTerm(tname))->StrOfAE;
VFS_t *vfs;
if ((vfs = vfs_owner(n))) {
vfs_stat s;
vfs->stat(vfs, n, &s);
return Yap_unify(ARG2, MkIntegerTerm(s.st_mtimespec.tv_sec));
}
#if __WIN32 #if __WIN32
FILETIME ft; FILETIME ft;
HANDLE hdl; HANDLE hdl;
@ -304,6 +328,15 @@ static Int file_size(USES_REGS1) {
"file_size/2"); "file_size/2");
if (sno < 0) if (sno < 0)
return (FALSE); return (FALSE);
VFS_t *vfs;
char *s = RepAtom(GLOBAL_Stream[sno].name)->StrOfAE;
if (!s) return false;
if ((vfs = vfs_owner(s))) {
vfs_stat st;
vfs->stat(vfs, s, &st);
UNLOCK(GLOBAL_Stream[sno].streamlock);
return Yap_unify_constant(ARG2, MkIntegerTerm(st.st_size));
}
if (GLOBAL_Stream[sno].status & Seekable_Stream_f && if (GLOBAL_Stream[sno].status & Seekable_Stream_f &&
!(GLOBAL_Stream[sno].status & !(GLOBAL_Stream[sno].status &
(InMemory_Stream_f | Socket_Stream_f | Pipe_Stream_f))) { (InMemory_Stream_f | Socket_Stream_f | Pipe_Stream_f))) {
@ -457,6 +490,22 @@ static Int exists_directory(USES_REGS1) {
Yap_Error(TYPE_ERROR_ATOM, tname, "exists_directory/1"); Yap_Error(TYPE_ERROR_ATOM, tname, "exists_directory/1");
return FALSE; return FALSE;
} else { } else {
VFS_t *vfs;
char *s = Yap_VF(RepAtom(AtomOfTerm(tname))->StrOfAE);
if (!s) return false;
if ((vfs = vfs_owner(s))) {
bool rc = true;
void *o;
if ((o=vfs->opendir(vfs, s))) {
rc = true;
vfs->closedir(o);
} else {
rc = false;
}
UNLOCK(GLOBAL_Stream[sno].streamlock);
return rc;
}
#if HAVE_STAT #if HAVE_STAT
struct SYSTEM_STAT ss; struct SYSTEM_STAT ss;

View File

@ -1217,8 +1217,7 @@ do_open(Term file_name, Term t2,
int sno; int sno;
StreamDesc *st; StreamDesc *st;
bool avoid_bom = false, needs_bom = false; bool avoid_bom = false, needs_bom = false;
const char *fname; const char *fname0;
char fbuf[FILENAME_MAX];
stream_flags_t flags; stream_flags_t flags;
const char *s_encoding; const char *s_encoding;
encoding_t encoding; encoding_t encoding;
@ -1231,13 +1230,13 @@ do_open(Term file_name, Term t2,
} }
if (!IsAtomTerm(file_name)) { if (!IsAtomTerm(file_name)) {
if (IsStringTerm(file_name)) { if (IsStringTerm(file_name)) {
fname = (char *)StringOfTerm(file_name); fname0 = (char *)StringOfTerm(file_name);
} else { } else {
Yap_Error(DOMAIN_ERROR_SOURCE_SINK, file_name, "open/3"); Yap_Error(DOMAIN_ERROR_SOURCE_SINK, file_name, "open/3");
return FALSE; return FALSE;
} }
} else { } else {
fname = RepAtom(AtomOfTerm(file_name))->StrOfAE; fname0 = RepAtom(AtomOfTerm(file_name))->StrOfAE;
} }
// open mode // open mode
if (IsVarTerm(t2)) { if (IsVarTerm(t2)) {
@ -1280,13 +1279,16 @@ do_open(Term file_name, Term t2,
: false) || : false) ||
trueGlobalPrologFlag(OPEN_EXPANDS_FILENAME_FLAG); trueGlobalPrologFlag(OPEN_EXPANDS_FILENAME_FLAG);
// expand file name? // expand file name?
fname = Yap_AbsoluteFile(fname, fbuf, ok); int lvl = push_text_stack();
const char *fname = Yap_AbsoluteFile(fname0, ok);
if (!fname) { if (!fname) {
pop_text_stack(lvl);
PlIOError(EXISTENCE_ERROR_SOURCE_SINK, ARG1, NULL); PlIOError(EXISTENCE_ERROR_SOURCE_SINK, ARG1, NULL);
} }
// Skip scripts that start with !#/.. or similar // Skip scripts that start with !#/.. or similar
pop_text_stack(lvl);
bool script = bool script =
(args[OPEN_SCRIPT].used ? args[OPEN_SCRIPT].tvalue == TermTrue : false); (args[OPEN_SCRIPT].used ? args[OPEN_SCRIPT].tvalue == TermTrue : false);
// binary type // binary type
@ -1307,6 +1309,7 @@ do_open(Term file_name, Term t2,
#endif #endif
/* note that this matters for UNICODE style conversions */ /* note that this matters for UNICODE style conversions */
} else { } else {
pop_text_stack(lvl);
Yap_Error(DOMAIN_ERROR_STREAM, tlist, Yap_Error(DOMAIN_ERROR_STREAM, tlist,
"type is ~a, must be one of binary or text", t); "type is ~a, must be one of binary or text", t);
} }
@ -1333,10 +1336,11 @@ do_open(Term file_name, Term t2,
} else if (open_mode == AtomAppend) { } else if (open_mode == AtomAppend) {
strncpy(io_mode, "a", 8); strncpy(io_mode, "a", 8);
} else { } else {
Yap_Error(DOMAIN_ERROR_IO_MODE, MkAtomTerm(open_mode), "open/3"); pop_text_stack(lvl);
return false; return false;
} }
if ((sno = Yap_OpenStream(fname, io_mode, file_name)) < 0) { if ((sno = Yap_OpenStream(fname, io_mode, file_name)) < 0) {
pop_text_stack(lvl);
return false; return false;
} }
st = &GLOBAL_Stream[sno]; st = &GLOBAL_Stream[sno];
@ -1369,10 +1373,10 @@ do_open(Term file_name, Term t2,
st->encoding = enc_id(s_encoding, st->encoding); st->encoding = enc_id(s_encoding, st->encoding);
else else
st->encoding = encoding; st->encoding = encoding;
if (script) if (script) {
open_header(sno, open_mode); open_header(sno, open_mode);
if (fname != fbuf) }
freeBuffer(fname); pop_text_stack(lvl);
free(args); free(args);
UNLOCK(st->streamlock); UNLOCK(st->streamlock);
@ -1497,11 +1501,16 @@ static Int p_file_expansion(USES_REGS1) { /* '$file_expansion'(+File,-Name) */
PlIOError(INSTANTIATION_ERROR, file_name, "absolute_file_name/3"); PlIOError(INSTANTIATION_ERROR, file_name, "absolute_file_name/3");
return (FALSE); return (FALSE);
} }
char tmp[YAP_FILENAME_MAX + 1]; int lvl = push_text_stack();
if (!Yap_AbsoluteFile(RepAtom(AtomOfTerm(file_name))->StrOfAE, tmp, false)) const char *tmp;
if ((tmp=Yap_AbsoluteFile(RepAtom(AtomOfTerm(file_name))->StrOfAE, false)) == NULL) {
pop_text_stack(lvl);
return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, file_name, return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, file_name,
"absolute_file_name/3")); "absolute_file_name/3"));
return (Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(tmp)))); }
bool rc = (Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(tmp))));
pop_text_stack(lvl);
return rc;
} }
static Int p_open_null_stream(USES_REGS1) { static Int p_open_null_stream(USES_REGS1) {
@ -1558,12 +1567,13 @@ int Yap_OpenStream(const char *fname, const char *io_mode, Term user_name) {
st->status = 0; st->status = 0;
fname = Yap_VF(fname); fname = Yap_VF(fname);
if ((vfsp = vfs_owner(fname)) != NULL) { if ((vfsp = vfs_owner(fname)) != NULL) {
if (!vfsp->open(vfsp, sno, fname, io_mode)) { if (!vfsp->open(vfsp, sno, fname, "r")) {
UNLOCK(st->streamlock); UNLOCK(st->streamlock);
PlIOError(EXISTENCE_ERROR_SOURCE_SINK, MkAtomTerm(Yap_LookupAtom(fname)), PlIOError(EXISTENCE_ERROR_SOURCE_SINK, MkAtomTerm(Yap_LookupAtom(fname)),
"%s", fname); "%s", fname);
return -1; return -1;
} }
vfsp = GLOBAL_Stream[sno].vfs;
} else { } else {
fd = st->file = fopen(fname, io_mode); fd = st->file = fopen(fname, io_mode);
if (fd == NULL) { if (fd == NULL) {

View File

@ -296,7 +296,7 @@ bool Yap_InitReadline(Term enable) {
#endif #endif
// rl_outstream = stderr; // rl_outstream = stderr;
using_history(); using_history();
const char *s = Yap_AbsoluteFile("~/.YAP.history", NULL, true); const char *s = Yap_AbsoluteFile("~/.YAP.history", true);
history_file = s; history_file = s;
if (read_history(s) != 0) { if (read_history(s) != 0) {
FILE *f = fopen(s, "a"); FILE *f = fopen(s, "a");

View File

@ -161,13 +161,11 @@ bool Yap_IsAbsolutePath(const char *p0, bool expand) {
// this is necessary because // this is necessary because
// support for ~expansion at the beginning // support for ~expansion at the beginning
// systems like Android do not do this. // systems like Android do not do this.
static const char *PlExpandVars(const char *source, const char *root, static const char *PlExpandVars(const char *source, const char *root) {
char *result) {
CACHE_REGS CACHE_REGS
int lvl = push_text_stack(); int lvl = push_text_stack();
const char *src = source; const char *src = source;
if (!result) char * result = Malloc(YAP_FILENAME_MAX + 1);
result = Malloc(YAP_FILENAME_MAX + 1);
if (strlen(source) >= YAP_FILENAME_MAX) { if (strlen(source) >= YAP_FILENAME_MAX) {
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, TermNil, Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, TermNil,
@ -346,13 +344,15 @@ char virtual_cwd[YAP_FILENAME_MAX + 1];
bool Yap_ChDir(const char *path) { bool Yap_ChDir(const char *path) {
bool rc = false; bool rc = false;
char qp[FILENAME_MAX + 1]; int lvl = push_text_stack();
const char *qpath = Yap_AbsoluteFile(path, qp, true);
VFS_t *v; VFS_t *v;
if ((v = vfs_owner(path))) { if ((v = vfs_owner(path))) {
return v->chdir(v, path); rc = v->chdir(v, path);
pop_text_stack(lvl);
return rc;
} }
const char *qpath = Yap_AbsoluteFile(path, true);
#if _WIN32 #if _WIN32
rc = true; rc = true;
if (qpath != NULL && qpath[0] && if (qpath != NULL && qpath[0] &&
@ -362,47 +362,125 @@ bool Yap_ChDir(const char *path) {
#else #else
rc = (chdir(qpath) == 0); rc = (chdir(qpath) == 0);
#endif #endif
if (qpath != qp && qpath != path && qpath != LOCAL_FileNameBuf && pop_text_stack(lvl);
qpath != LOCAL_FileNameBuf2)
free((char *)qpath);
return rc; return rc;
} }
static const char *myrealpath(const char *path, char *out) { static char * close_path(char *b0,char *o0, char *o ){
if (b0[0] == '\0') {
return o;
} else if (!strcmp(b0, "..")) {
while (o-- > o0) {
if (dir_separator(*o)) {
break;
}
}
} else if (strcmp(b0, ".") != 0) {
*o++ = '/';
strcpy(o, b0);
o += strlen(b0);
}
return o;
}
static char * clean_path(const char *path)
{
const char *p, *p0;
int lvl = push_text_stack(); int lvl = push_text_stack();
__android_log_print(ANDROID_LOG_INFO, "YAPDroid ", " looking at %s", path) ;
char *o0 = Malloc(FILENAME_MAX+1),*o = o0;
int ch;
char *b0 = Malloc(FILENAME_MAX+1), *b = b0;
p = p0 = path;
while((ch = *p++)) {
if (dir_separator(ch)) {
if (b==b0) {
o = o0;
} else {
b[0] = '\0';
o = close_path(b0, o0, o);
b = b0;
}
} else {
*b++ = ch;
}
}
if (!dir_separator(p[-1])) {
b[0] = '\0';
o = close_path(b0, o0, o);
}
if (o == o0)
*o++ = '/';
*o = '\0';
__android_log_print(ANDROID_LOG_INFO, "YAPDroid ", " %s at %s, %p-%p", p0, o0, o, o0) ;
return pop_output_text_stack(lvl,o0);
}
static const char *myrealpath(const char *path USES_REGS) {
int lvl = push_text_stack();
VFS_t *v;
char *out, *o;
if (Yap_IsAbsolutePath(path,true)) {
o = clean_path(path);
if ((v = vfs_owner(o))
) {
return pop_output_text_stack(lvl, o);
}
} else {
out = Malloc(FILENAME_MAX+1);
Yap_getcwd(out, FILENAME_MAX);
strcat(out, "/");
strcat(out, path);
o = clean_path(out);
if ((v = vfs_owner(o))) {
return pop_output_text_stack(lvl, o);
}
}
#if _WIN32 #if _WIN32
DWORD retval = 0; DWORD retval = 0;
// notice that the file does not need to exist // notice that the file does not need to exist
retval = GetFullPathName(path, YAP_FILENAME_MAX, out, NULL); retval = GetFullPathName(path, YAP_FILENAME_MAX, o, NULL);
pop_text_stack(lvl);
if (retval == 0) { if (retval == 0) {
pop_text_stack(lvl);
Yap_WinError("Generating a full path name for a file"); Yap_WinError("Generating a full path name for a file");
return NULL; return NULL;
} }
return out; return pop_output_text_stack(lvl, o);
#elif HAVE_REALPATH #elif HAVE_REALPATH
{ {
char *rc = realpath(path, NULL); char *rc = realpath(path, o);
if (rc) { if (rc) {
pop_text_stack(lvl); rc = pop_output_text_stack(lvl, rc);
return rc;
} }
// rc = NULL; // rc = NULL;
if (errno == ENOENT || errno == EACCES) { if (errno == ENOENT || errno == EACCES) {
char *base = Malloc(YAP_FILENAME_MAX + 1); char *base = Malloc(FILENAME_MAX + 1);
strncpy(base, path, YAP_FILENAME_MAX); strncpy(base, path, FILENAME_MAX);
rc = realpath(dirname(base), out); char *p = base+strlen(base);
while (p>base && !dir_separator(*--p));
if (p == base) p[1] = '\0';
else p[0] = '\0';
char *tmp = Malloc(FILENAME_MAX + 1);
rc = realpath(base, tmp);
if (rc) { if (rc) {
// base may haave been destroyed // base may have been destroyed
const char *b = basename((char *)path); char *b = base+strlen(base);
while (b>base && !dir_separator(*--b));
if (b[0] && !dir_separator(b[0])) b++;
size_t e = strlen(rc); size_t e = strlen(rc);
size_t bs = strlen(b); size_t bs = strlen(b);
if (rc != out && rc != base) { if (rc != out && rc != base) {
rc = realloc(rc, e + bs + 2); rc = Realloc(rc, e + bs + 2);
} }
#if _WIN32 #if _WIN32
if (rc[e - 1] != '\\' && rc[e - 1] != '/') { if (rc[e - 1] != '\\' && rc[e - 1] != '/') {
@ -422,10 +500,8 @@ static const char *myrealpath(const char *path, char *out) {
} }
} }
#endif #endif
out = malloc(strlen(path) + 1);
strcpy(out, path);
pop_text_stack(lvl); pop_text_stack(lvl);
return out; return path;
} }
static const char *expandVars(const char *spec, char *u) { static const char *expandVars(const char *spec, char *u) {
@ -456,11 +532,11 @@ static const char *expandVars(const char *spec, char *u) {
* *
* @return tmp, or NULL, in malloced memory * @return tmp, or NULL, in malloced memory
*/ */
const char *Yap_AbsoluteFile(const char *spec, char *rc0, bool ok) { const char *Yap_AbsoluteFile(const char *spec, bool ok) {
const char *rc; const char *rc;
const char *spec1; const char *spec1;
const char *spec2; const char *spec2;
char rc1[YAP_FILENAME_MAX + 1]; int lvl = push_text_stack();
/// spec gothe original spec; /// spec gothe original spec;
/// rc0 may be an outout buffer /// rc0 may be an outout buffer
@ -480,7 +556,7 @@ const char *Yap_AbsoluteFile(const char *spec, char *rc0, bool ok) {
/// spec gothe original spec; /// spec gothe original spec;
/// rc1 the internal buffer /// rc1 the internal buffer
if (ok) { if (ok) {
const char *q = PlExpandVars(spec1, NULL, rc1); const char *q = PlExpandVars(spec1, NULL);
if (!q) if (!q)
spec2 = spec1; spec2 = spec1;
else else
@ -488,8 +564,8 @@ const char *Yap_AbsoluteFile(const char *spec, char *rc0, bool ok) {
} else { } else {
spec2 = spec1; spec2 = spec1;
} }
rc = myrealpath(spec2, rc0); rc = myrealpath(spec2 PASS_REGS);
return rc; return pop_output_text_stack(lvl,rc);
} }
static Term static Term
@ -678,13 +754,14 @@ static Int real_path(USES_REGS1) {
} }
cmd = rc; cmd = rc;
#endif #endif
int lvl = push_text_stack();
rc0 = myrealpath(cmd, NULL); rc0 = myrealpath(cmd PASS_REGS);
if (!rc0) { if (!rc0) {
PlIOError(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, NULL); PlIOError(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, NULL);
} }
bool out = Yap_unify(MkAtomTerm(Yap_LookupAtom(rc0)), ARG2); bool out = Yap_unify(MkAtomTerm(Yap_LookupAtom(rc0)), ARG2);
freeBuffer(rc0); pop_output_text_stack(lvl,rc0);
return out; return out;
} }
@ -859,7 +936,7 @@ static Int absolute_file_system_path(USES_REGS1) {
pop_text_stack(l); pop_text_stack(l);
return false; return false;
} }
if (!(fp = Yap_AbsoluteFile(text, NULL, true))) { if (!(fp = Yap_AbsoluteFile(text, true))) {
pop_text_stack(l); pop_text_stack(l);
return false; return false;
} }
@ -1098,10 +1175,11 @@ static Int true_file_name(USES_REGS1) {
Yap_Error(TYPE_ERROR_ATOM, t, "argument to true_file_name"); Yap_Error(TYPE_ERROR_ATOM, t, "argument to true_file_name");
return FALSE; return FALSE;
} }
if (!(s = Yap_AbsoluteFile(s, LOCAL_FileNameBuf, true))) int l = push_text_stack();
if (!(s = Yap_AbsoluteFile(s, true)))
return false; return false;
bool rc = Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(s))); bool rc = Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(s)));
freeBuffer(s); pop_text_stack(l);
return rc; return rc;
} }
@ -1119,7 +1197,7 @@ static Int p_expand_file_name(USES_REGS1) {
pop_text_stack(l); pop_text_stack(l);
return false; return false;
} }
if (!(text2 = PlExpandVars(text, NULL, NULL))) { if (!(text2 = PlExpandVars(text, NULL))) {
pop_text_stack(l); pop_text_stack(l);
return false; return false;
} }
@ -1146,10 +1224,13 @@ static Int true_file_name3(USES_REGS1) {
} }
// root = RepAtom(AtomOfTerm(t2))->StrOfAE; // root = RepAtom(AtomOfTerm(t2))->StrOfAE;
} }
char tmp[YAP_FILENAME_MAX + 1]; int lvl = push_text_stack();
if (!Yap_AbsoluteFile(RepAtom(AtomOfTerm(t))->StrOfAE, tmp, true)) const char *tmp = Yap_AbsoluteFile(RepAtom(AtomOfTerm(t))->StrOfAE, true);
return FALSE; Atom at = NULL;
return Yap_unify(ARG3, MkAtomTerm(Yap_LookupAtom(tmp))); bool rc = (tmp != NULL &&
(at = Yap_LookupAtom(tmp)) != NULL);
pop_text_stack(lvl);
return rc && Yap_unify(ARG3, MkAtomTerm(at));
} }
/* Executes $SHELL under Prolog */ /* Executes $SHELL under Prolog */

View File

@ -52,7 +52,7 @@ if (ANDROID)
endif (ANDROID) endif (ANDROID)
add_library( Yapsqlite3 SHARED add_library( Yapsqlite3 OBJECT
${YAPSQLITE3_SOURCES} ) ${YAPSQLITE3_SOURCES} )
set_target_properties(Yapsqlite3 set_target_properties(Yapsqlite3
@ -62,15 +62,13 @@ set_target_properties(Yapsqlite3
POSITION_INDEPENDENT_CODE TRUE POSITION_INDEPENDENT_CODE TRUE
) )
target_link_libraries(Yapsqlite3 libYap) #target_link_libraries(Yapsqlite3 libYap)
if (ANDROID) # target_link_libraries(Yapsqlite3 android log)
target_link_libraries(Yapsqlite3 android log)
endif ()
install(TARGETS Yapsqlite3 #install(TARGETS Yapsqlite3
RUNTIME DESTINATION ${YAP_INSTALL_DLLDIR} # RUNTIME DESTINATION ${YAP_INSTALL_DLLDIR}
ARCHIVE DESTINATION ${YAP_INSTALL_DLLDIR} # ARCHIVE DESTINATION ${YAP_INSTALL_DLLDIR}
LIBRARY DESTINATION ${YAP_INSTALL_DLLDIR} # LIBRARY DESTINATION ${YAP_INSTALL_DLLDIR}
) # )

View File

@ -18,16 +18,19 @@ FILE( MAKE_DIRECTORY ${YAP_APP_DIR}/src/generated/assets)
set (GMP_LIBRARIES ${GMP_ROOT}/libgmp.so) set (GMP_LIBRARIES ${GMP_ROOT}/libgmp.so)
add_custom_command (OUTPUT yap_swig.cpp add_custom_target (pllib ALL
COMMAND ${CMAKE_COMMAND} -E make_directory ${pllib} COMMAND ${CMAKE_COMMAND} -E make_directory ${pllib}
COMMAND ${CMAKE_COMMAND} -E make_directory ${pllib}/pl
COMMAND ${CMAKE_COMMAND} -E make_directory ${pllib}/os
COMMAND ${CMAKE_COMMAND} -E copy ${pl_library} ${pllib} COMMAND ${CMAKE_COMMAND} -E copy ${pl_library} ${pllib}
)
add_custom_target (pllibpl ALL
COMMAND ${CMAKE_COMMAND} -E make_directory ${pllib}/pl
COMMAND ${CMAKE_COMMAND} -E copy ${pl_boot_library} ${pllib}/pl COMMAND ${CMAKE_COMMAND} -E copy ${pl_boot_library} ${pllib}/pl
)
add_custom_target (pllibos ALL
COMMAND ${CMAKE_COMMAND} -E make_directory ${pllib}/os
COMMAND ${CMAKE_COMMAND} -E copy ${pl_os_library} ${pllib}/os COMMAND ${CMAKE_COMMAND} -E copy ${pl_os_library} ${pllib}/os
COMMAND ${SWIG_EXECUTABLE} -c++ -java -package ${SWIG_MODULE_NAME} -outdir ${CMAKE_SWIG_OUTDIR} -outcurrentdir -addextern -I${CMAKE_SOURCE_DIR}/CXX -I${CMAKE_SOURCE_DIR}/include -I${CMAKE_SOURCE_DIR}/H -I${CMAKE_SOURCE_DIR}/os -I${CMAKE_SOURCE_DIR}/OPTYap -I${CMAKE_BINARY_DIR} -I${GMP_INCLUDE_DIRS} -DX_API="" -o yap_swig.cpp ${SWIG_SOURCES}
DEPENDS ${SWIG_SOURCES} YAP++
) )
add_custom_command (OUTPUT swig_streamer.cpp add_custom_command (OUTPUT swig_streamer.cpp
@ -35,6 +38,15 @@ FILE( MAKE_DIRECTORY ${YAP_APP_DIR}/src/generated/assets)
DEPENDS streamer.i DEPENDS streamer.i
) )
add_custom_command (OUTPUT yap_swig.cpp
COMMAND ${CMAKE_COMMAND} -E make_directory ${pllib}/pl
COMMAND ${CMAKE_COMMAND} -E make_directory ${pllib}/os
COMMAND ${SWIG_EXECUTABLE} -c++ -java -package ${SWIG_MODULE_NAME} -outdir ${CMAKE_SWIG_OUTDIR} -outcurrentdir -addextern -I${CMAKE_SOURCE_DIR}/CXX -I${CMAKE_SOURCE_DIR}/include -I${CMAKE_SOURCE_DIR}/H -I${CMAKE_SOURCE_DIR}/os -I${CMAKE_SOURCE_DIR}/OPTYap -I${CMAKE_BINARY_DIR} -I${GMP_INCLUDE_DIRS} -DX_API="" -o yap_swig.cpp ${SWIG_SOURCES}
DEPENDS pllibos ${SWIG_SOURCES} YAP++ ${pl_boot_library}
)
# GMP_FOUND - true if GMP/MPIR was found # GMP_FOUND - true if GMP/MPIR was found
# GMP_INCLUDE_DIRS - include search path # GMP_INCLUDE_DIRS - include search path
@ -51,7 +63,7 @@ FILE( MAKE_DIRECTORY ${YAP_APP_DIR}/src/generated/assets)
target_link_libraries(YAPJava ${GMP_LIBRARIES} ) target_link_libraries(YAPJava ${GMP_LIBRARIES} )
target_link_libraries( YAPJava YAP++ libYap android log) target_link_libraries( YAPJava libYap android log)
if (FALSE) if (FALSE)

View File

@ -41,6 +41,7 @@ and_open(struct vfs *me, int sno, const char *name, const char *io_mode) {
GLOBAL_Stream[sno].vfs_handle = streamerInstance; GLOBAL_Stream[sno].vfs_handle = streamerInstance;
GLOBAL_Stream[sno].vfs = me; GLOBAL_Stream[sno].vfs = me;
GLOBAL_Stream[sno].status = Append_Stream_f | Output_Stream_f; GLOBAL_Stream[sno].status = Append_Stream_f | Output_Stream_f;
GLOBAL_Stream[sno].name = Yap_LookupAtom(name);
buff0.clear(); buff0.clear();
return streamerInstance; return streamerInstance;
} }

View File

@ -51,6 +51,7 @@ set(PL_BOOT_SOURCES
swi.yap swi.yap
tabling.yap tabling.yap
threads.yap threads.yap
top.yap
udi.yap udi.yap
undefined.yap undefined.yap
utils.yap utils.yap
@ -64,7 +65,7 @@ if (ANDROID)
DEPENDS ${PL_BOOT_SOURCES} DEPENDS ${PL_BOOT_SOURCES}
) )
file (INSTALL ${PL_BOOT_SOURCES} DESTINATION ${libpl}/pl) file (INSTALL ${PL_BOOT_SOURCES} DESTINATION ${libpl}/pl)
elif(CMAKE_CROSSCOMPILING) elseif(CMAKE_CROSSCOMPILING)
add_custom_target(STARTUP ALL SOURCES add_custom_target(STARTUP ALL SOURCES
DEPENDS ${PL_BOOT_SOURCES} DEPENDS ${PL_BOOT_SOURCES}
) )
@ -73,7 +74,7 @@ else ()
DEPENDS ${CMAKE_TOP_BINARY_DIR}/${YAP_STARTUP} DEPENDS ${CMAKE_TOP_BINARY_DIR}/${YAP_STARTUP}
) )
add_custom_command(OUTPUT ${CMAKE_TOP_BINARY_DIR}/${YAP_STARTUP} add_custom_command(OUTPUT ${CMAKE_TOP_BINARY_DIR}/${YAP_STARTUP}
COMMAND yap-bin -B${CMAKE_SOURCE_DIR}/pl --output-saved-state=${CMAKE_TOP_BINARY_DIR}/${YAP_STARTUP} COMMAND yap-bin -B${CMAKE_SOURCE_DIR}/pl/boot.yap --output-saved-state=${CMAKE_TOP_BINARY_DIR}/${YAP_STARTUP}
VERBATIM VERBATIM
DEPENDS ${PL_BOOT_SOURCES} yap-bin DEPENDS ${PL_BOOT_SOURCES} yap-bin
) )

View File

@ -161,6 +161,7 @@ print_message(L,E) :-
:- use_system_module( '$_boot', ['$cut_by'/1]). :- use_system_module( '$_boot', ['$cut_by'/1]).
%:- start_low_level_trace. %:- start_low_level_trace.
% This is the YAP init file % This is the YAP init file
@ -291,6 +292,7 @@ initialize_prolog :-
'qly.yap', 'qly.yap',
'spy.yap', 'spy.yap',
'udi.yap']. 'udi.yap'].
:- stop_low_level_trace.
:- meta_predicate(log_event(+,:)). :- meta_predicate(log_event(+,:)).

View File

@ -240,31 +240,6 @@ not(G) :- \+ '$execute'(G).
/** @pred fail is iso
Always fails.
*/
fail :- fail.
/** @pred false is iso
The same as fail.
*/
false :- fail.
/** @pred true is iso
Succeed.
Succeeds once.
*/
true :- true.
/** @pred otherwise is iso
Succeed.
Succeeds once.
*/
otherwise.
/** @pred repeat is iso /** @pred repeat is iso
Succeeds repeatedly. Succeeds repeatedly.

View File

@ -424,7 +424,7 @@ load_files(Files,Opts) :-
). ).
'$lf'([F|Fs], Mod, Call, TOpts) :- !, '$lf'([F|Fs], Mod, Call, TOpts) :- !,
% clean up after each consult % clean up after each consult
( '$lf'(F,Mod,Call, TOpts), fail ; ( '$lf'(F,Mod,Call, TOpts), fail;
'$lf'(Fs, Mod, Call, TOpts), fail; '$lf'(Fs, Mod, Call, TOpts), fail;
true true
). ).