diff --git a/C/c_interface.c b/C/c_interface.c index aafa2b0f6..8a01cc8e3 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -2122,7 +2122,7 @@ X_API int YAP_InitConsult(int mode, const char *fname, char *full, int *osnop) { } } bool consulted = (mode == YAP_CONSULT_MODE); - sno = Yap_OpenStream(fl, "r", MkAtomTerm(Yap_LookupAtom(fl))); + sno = Yap_OpenStream(fl, "r", MkAtomTerm(Yap_LookupAtom(fl)), LOCAL_encoding); if (sno < 0) return sno; if (!Yap_ChDir(dirname((char *)fl))) return -1; diff --git a/C/dbase.c b/C/dbase.c index b776ed244..b94ce8954 100644 --- a/C/dbase.c +++ b/C/dbase.c @@ -4913,11 +4913,15 @@ static Int cont_current_key_integer(USES_REGS1) { Term Yap_FetchTermFromDB(void *ref) { CACHE_REGS + if (ref == NULL) + return 0; return GetDBTerm(ref, FALSE PASS_REGS); } Term Yap_FetchClauseTermFromDB(void *ref) { CACHE_REGS + if (ref == NULL) + return 0; return GetDBTerm(ref, TRUE PASS_REGS); } diff --git a/C/yap-args.c b/C/yap-args.c index 3176b95c2..8e5832bcf 100755 --- a/C/yap-args.c +++ b/C/yap-args.c @@ -149,7 +149,10 @@ const char *Yap_BINDIR, *Yap_ROOTDIR, *Yap_SHAREDIR, *Yap_LIBDIR, *Yap_DLLDIR, *Yap_PLDIR, *Yap_BOOTSTRAP, *Yap_COMMONSDIR, *Yap_STARTUP, *Yap_INPUT_STARTUP, *Yap_OUTPUT_STARTUP, *Yap_BOOTFILE, *Yap_INCLUDEDIR; -/* do initial boot by consulting the file boot.yap */ +/** + * consult loop in C: used to boot the system, butt supports goal execution and recursive consulting. + * + * */ static void consult(const char *b_file USES_REGS) { Term t; int c_stream, osno, oactive; @@ -157,7 +160,7 @@ static void consult(const char *b_file USES_REGS) { Functor functor_command1 = Yap_MkFunctor(Yap_LookupAtom(":-"), 1); Functor functor_compile2 = Yap_MkFunctor(Yap_LookupAtom("c_compile"), 1); - /* consult boot.pl */ + /* consult in C */ int lvl = push_text_stack(); char *full = Malloc(YAP_FILENAME_MAX + 1); full[0] = '\0'; diff --git a/CXX/CMakeLists.txt b/CXX/CMakeLists.txt index d29e8b7ec..168e84cef 100644 --- a/CXX/CMakeLists.txt +++ b/CXX/CMakeLists.txt @@ -5,7 +5,7 @@ set(SO_MINOR 0) set(SO_PATCH 0) set (CXX_SOURCES - yapi.cpp + yapi.cpp ) list(APPEND LIBYAP_SOURCES ${CXX_SOURCES} PARENT_SCOPE) @@ -15,7 +15,7 @@ if ( WIN32 OR ANDROID) set_property( DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "_YAP_NOT_INSTALLED_=1;HAVE_CONFIG_H=1;_GNU_SOURCE;YAP_KERNEL=1" ) else() add_lib(YAP++ ${CXX_SOURCES} ) - target_link_libraries(YAP++ ${CMAKE_DL_LIBS} libYap) + target_link_libraries(YAP++ ${CMAKE_DL_LIBS} Py4YAP libYap) MY_install(TARGETS YAP++ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 39ca33f3c..f8a08e8ca 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -10,6 +10,10 @@ extern "C" { #include "android/log.h" #endif +#if 1 +#include "Python.h" +#endif + #include "YapInterface.h" #include "YapBlobs.h" #include "iopreds.h" @@ -238,7 +242,6 @@ Term &YAPTerm::operator[](arity_t i) { else if (i == 1) tf = TailOfTerm(t0); RECOVER_MACHINE_REGS(); - tf = RepPair(tf)[i]; } else { Yap_Error(TYPE_ERROR_COMPOUND, t0, ""); } @@ -252,6 +255,7 @@ Term &YAPListTerm::operator[](arity_t i) { Term tf = 0; while (IsPairTerm(t0)) { if (i == 0) { + tf = HeadOfTerm(t0); break; } else { @@ -436,7 +440,10 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { //q.e = new YAPError(); } // don't forget, on success these bindings will still be there); + PyThreadState *tstate; +Py_BEGIN_ALLOW_THREADS result = YAP_LeaveGoal(false, &q); + Py_END_ALLOW_THREADS Yap_CloseHandles(q.CurSlot); LOCAL_RestartEnv = oj; RECOVER_MACHINE_REGS(); @@ -453,6 +460,9 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { bool YAPEngine::mgoal(Term t, Term tmod) { sigjmp_buf buf, *oldp = LOCAL_RestartEnv; + PyThreadState *_save; + + _save = PyEval_SaveThread(); try { CACHE_REGS BACKUP_MACHINE_REGS(); @@ -479,15 +489,16 @@ bool YAPEngine::mgoal(Term t, Term tmod) { // allow Prolog style exception handling LOCAL_RestartEnv = &buf; if (sigsetjmp(*LOCAL_RestartEnv, false)) { - std::cerr << "Restart\n"; + PyEval_RestoreThread(_save); + std::cerr << "Restart\n"; //throw new YAPError(); } // don't forget, on success these guys may create slots __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); - result = (bool)YAP_EnterGoal(ap, nullptr, &q); { YAP_LeaveGoal(false, &q); + PyEval_RestoreThread(_save); LOCAL_RestartEnv = oldp; RECOVER_MACHINE_REGS(); return result; @@ -495,7 +506,8 @@ bool YAPEngine::mgoal(Term t, Term tmod) { } catch (YAPError e) { YAP_LeaveGoal(false, &q); Yap_CloseHandles(q.CurSlot); - LOCAL_RestartEnv = oldp; + PyEval_RestoreThread(_save); + LOCAL_RestartEnv = oldp; return 0; //throw e; } @@ -745,8 +757,8 @@ PredEntry *YAPEngine::rewriteUndefEngineQuery(PredEntry *a, Term &tgoal, ARG1 = tgoal = Yap_MkApplTerm(FunctorModule, 2, ts); //goal = YAPTerm(Yap_MkApplTerm(FunctorMetaCall, 1, &ARG1)); return PredCall; - - + + // return YAPApplTerm(FunctorUndefinedQuery, ts); } diff --git a/cmake/anaconda.cmake b/cmake/anaconda.cmake new file mode 100644 index 000000000..4c2693122 --- /dev/null +++ b/cmake/anaconda.cmake @@ -0,0 +1,73 @@ + set (PYTHONLIBS_FOUND YES CACHE BOOL "MINGW/MSYS2" FORCE ) + set (PYTHON_LIBRARY $ENV{PREFIX}/lib/libpython$ENV{PY_VER}m.$ENV{SHLIB_EXT} CACHE FILEPATH "MINGW/MSYS2" FORCE ) + set (PYTHON_LIBRARIES ${PYTHON_LIBRARY} CACHE FILEPATH "MINGW/MSYS2" FORCE ) + set (PYTHON_INCLUDE_PATH $ENV{PREFIX}/include/python$ENV{PY_VER}m CACHE PATH "MINGW/MSYS2" FORCE ) + set (PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH} CACHE PATH "MINGW/MSYS2" FORCE ) + set (PYTHON_EXECUTABLE $ENV{PREFIX}/bin/python CACHE FILEPATH "MINGW/MSYS2" FORCE ) + set (PYTHONLIBS_VERSION_STRING $ENV{PY_VER} CACHE STRING "MINGW/MSYS2" FORCE ) + + + # # try to extract R from readline to avoid collision + set(READLINE_INCLUDE_DIR $ENV{PREFIX}/include CACHE PATH "readline" FORCE) + + + # Apple readline does not support readline hooks + # So we look for another one by default + set(READLINE_readline_LIBRARY $ENV{PREFIX}/lib/libreadline.$ENV{SHLIB_EXT} CACHE PATH "readline") + + # Sometimes readline really needs ncurses + set(READLINE_ncurses_LIBRARY $ENV{PREFIX}/lib/libncurses.$ENV{SHLIB_EXT} CACHE PATH "readline") + + set(READLINE_ncursesw_LIBRARY $ENV{PREFIX}/lib/libncursesw.$ENV{SHLIB_EXT} CACHE PATH "readline") + + # Sometimes ncurses really needs terminfo + set(READLINE_tinfo_LIBRARY $ENV{PREFIX}/lib/libntinfo.$ENV{SHLIB_EXT} CACHE PATH "readline") + + set(READLINE_tinfow_LIBRARY $ENV{PREFIX}/lib/libntinfow.$ENV{SHLIB_EXT} CACHE PATH "readline") + + SET( READLINE_FOUND "YES" CACHE BOOL "Readline ACCESS.") + + + # Apple readline does not support readline hooks + # So we look for another one by default + if ( READLINE_readline_LIBRARY) + set (HAVE_LIBREADLINE YES CACHE BOOL "ibReadline ACCESS") + endif() + + IF(READLINE_readline_LIBRARY) + set(HAVE_LIBREADLINE CACHE YES BOOL "Readline works." ) + SET( READLINE_LIBRARIES + ${READLINE_readline_LIBRARY} + ) + + # some readline libraries depend on ncurses + IF(READLINE_ncurses_LIBRARY) + list(APPEND READLINE_LIBRARIES ${READLINE_ncurses_LIBRARY}) + endif () + + # some readline libraries depend on ncurses + IF(READLINE_ncursesw_LIBRARY) + list(APPEND READLINE_LIBRARIES ${READLINE_ncursesw_LIBRARY}) + endif () + + # some readline libraries depend on tinfo + IF(READLINE_tinfo_LIBRARY) + list(APPEND READLINE_LIBRARIES ${READLINE_tinfo_LIBRARY}) + endif () + + + # some readline libraries depend on tinfo + IF(READLINE_tinfow_LIBRARY) + list(APPEND READLINE_LIBRARIES ${READLINE_tinfow_LIBRARY}) + endif () + + IF(READLINE_INCLUDE_DIR) + SET( READLINE_FOUND "YES" CACHE BOOL "Readline ACCESS.") + ENDIF(READLINE_INCLUDE_DIR) + ENDIF(READLINE_readline_LIBRARY) + + + set (GMP_INCLUDE_DIRS $ENV{PREFIX}/include) + set (GMP_LIBRARIES $ENV{PREFIX}/lib/libgmp.${SHLIB_EXT}) + set (GMP_FOUND ON) + set (GMP_LIBRARIES_DIR $ENV{PREFIX}/lib) \ No newline at end of file diff --git a/include/SWI-Prolog.h b/include/SWI-Prolog.h index a66e3e727..fe8ddcb19 100755 --- a/include/SWI-Prolog.h +++ b/include/SWI-Prolog.h @@ -44,7 +44,6 @@ extern "C" { #include #else #include -#include #endif #endif #include diff --git a/include/VFS.h b/include/VFS.h index 5dd389534..8b9c8c24e 100644 --- a/include/VFS.h +++ b/include/VFS.h @@ -79,8 +79,9 @@ typedef struct vfs { const char *suffix; bool (*chDir)(struct vfs *me, const char *s); /** operations */ - void *(*open)(struct vfs *, int sno, const char *fname, - const char *io_mode); /// open an object + void *(*open)(struct vfs *, const char *fname, + const char *io_mode, + int sno); /// open an object /// in this space, usual w,r,a,b flags plus B (store in a buffer) bool (*close)(int sno); /// close the object int (*get_char)(int sno); /// get an octet from the stream diff --git a/library/lammpi/CMakeLists.txt b/library/lammpi/CMakeLists.txt index fcb67ba15..88b59f7a5 100644 --- a/library/lammpi/CMakeLists.txt +++ b/library/lammpi/CMakeLists.txt @@ -1,10 +1,11 @@ -set (MPI_SOURCES +set (MPI_YAP_SOURCES hash.c prologterms2c.c yap_mpi.c) macro_optional_find_package(MPI ON) - -if (MPI_C_FOUND) + + if (MPI_FOUND) + if (MPI_C_FOUND) # === Variables === # # This module will set the following variables per language in your @@ -67,7 +68,7 @@ if (MPI_C_FOUND) # pass to the MPI program. # - add_lib (yap_mpi ${MPI_SOURCES}) + add_executable (yap_mpi ${MPI_YAP_SOURCES} Yaplib ../../console/yap.c) target_link_libraries(yap_mpi libYap ${MPI_C_LIBRARIES}) @@ -76,11 +77,11 @@ if (MPI_C_FOUND) include_directories (${MPI_C_INCLUDE_PATH}) add_definitions (-DHAVE_MPI_H=1) + target_compile_definitions(yap_mpi ${MPI_C_COMPILE_FLAGS}) install(TARGETS yap_mpi - LIBRARY DESTINATION ${YAP_INSTALL_DLLDIR} - RUNTIME DESTINATION ${YAP_INSTALL_DLLDIR} - ARCHIVE DESTINATION ${YAP_INSTALL_DLLDIR} + RUNTIME DESTINATION ${YAP_INSTALL_BDIR} ) -endif (MPI_C_FOUND) + endif (MPI_C_FOUND) +endif (MPI_FOUND) diff --git a/os/fmem.c b/os/fmem.c index 1d1b46f61..fa5e29cef 100644 --- a/os/fmem.c +++ b/os/fmem.c @@ -152,7 +152,7 @@ int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp, // like any file stream. f = st->file = fmemopen((void *)buf, nchars, "r"); flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f; - Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead, NULL); + Yap_initStream(sno, f, "memStream", "r", buf, encoding, flags, NULL); // like any file stream. Yap_DefaultStreamOps(st); UNLOCK(st->streamlock); diff --git a/os/iopreds.c b/os/iopreds.c index 6ff25467b..c5e69f6f1 100644 --- a/os/iopreds.c +++ b/os/iopreds.c @@ -406,16 +406,8 @@ static void InitStdStream(int sno, SMALLUNSGN flags, FILE *file, VFS_t *vfsp) { s->buf.on = false; s->encoding = ENC_ISO_UTF8; INIT_LOCK(s->streamlock); - if (vfsp != NULL) { - s->u.private_data = vfsp->open(vfsp, sno, vfsp->name, - (sno == StdInStream ? "read" : "write")); - if (s->u.private_data == NULL) { - (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, MkIntTerm(sno), "%s", - vfsp->name)); - return; - } - } else { - unix_upd_stream_info(s); + if (vfsp == NULL) { + unix_upd_stream_info(s); } /* Getting streams to prompt is a mess because we need for cooperation between readers and writers to the stream :-( @@ -1133,11 +1125,23 @@ static void check_bom(int sno, StreamDesc *st) { } } -bool Yap_initStream(int sno, FILE *fd, const char *name, Term file_name, - encoding_t encoding, stream_flags_t flags, Atom open_mode, - void *vfs) { +bool Yap_initStream(int sno, FILE *fd, const char *name, const char *io_mode, Term file_name, encoding_t encoding, + stream_flags_t flags, void *vfs) { StreamDesc *st = &GLOBAL_Stream[sno]; - st->status = flags; + if (io_mode == NULL) + Yap_Error(PERMISSION_ERROR_NEW_ALIAS_FOR_STREAM, MkIntegerTerm(sno), "File opened with NULL Permissions"); + if (strchr(io_mode, 'a')) { + st->status = Append_Stream_f|Output_Stream_f|flags; + } else + if (strchr(io_mode, 'w')) { + st->status = Output_Stream_f | flags; + } + if (strchr(io_mode, 'r')) { + st->status = Input_Stream_f|flags; + } + if (strchr(io_mode, 'b')) { + st->status = Binary_Stream_f|flags; + } st->vfs = vfs; st->buf.on = false; @@ -1150,12 +1154,13 @@ bool Yap_initStream(int sno, FILE *fd, const char *name, Term file_name, } if (name == NULL) { - char buf[YAP_FILENAME_MAX + 1]; - memset(buf, 0, YAP_FILENAME_MAX + 1); - name = Yap_guessFileName(fd, sno, buf, YAP_FILENAME_MAX); - if (name) - st->name = Yap_LookupAtom(name); + char buf[YAP_FILENAME_MAX + 1]; + memset(buf, 0, YAP_FILENAME_MAX + 1); + name = Yap_guessFileName(fd, sno, buf, YAP_FILENAME_MAX); } + if (!name) + Yap_Error(SYSTEM_ERROR_INTERNAL,file_name,"Yap_guessFileName failed: opening a file without a name"); + st->name = Yap_LookupAtom(name); st->user_name = file_name; st->file = fd; st->linepos = 0; @@ -1221,7 +1226,7 @@ static const param_t open_defs[] = {OPEN_DEFS()}; static Int do_open(Term file_name, Term t2, - Term tlist USES_REGS) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */ + Term tlist USES_REGS) { Atom open_mode; int sno; StreamDesc *st; @@ -1232,6 +1237,7 @@ do_open(Term file_name, Term t2, encoding_t encoding; Term tenc; char io_mode[8]; + // original file name if (IsVarTerm(file_name)) { Yap_Error(INSTANTIATION_ERROR, file_name, "open/3"); @@ -1287,6 +1293,7 @@ do_open(Term file_name, Term t2, ? args[OPEN_EXPAND_FILENAME].tvalue == TermTrue : false) || trueGlobalPrologFlag(OPEN_EXPANDS_FILENAME_FLAG); + // expand file name? int lvl = push_text_stack(); const char *fname = Yap_AbsoluteFile(fname0, ok); @@ -1298,9 +1305,18 @@ do_open(Term file_name, Term t2, // Skip scripts that start with !#/.. or similar pop_text_stack(lvl); - bool script = - (args[OPEN_SCRIPT].used ? args[OPEN_SCRIPT].tvalue == TermTrue : false); - // binary type + + if (open_mode == AtomRead) { + strncpy(io_mode, "r", 8); + } else if (open_mode == AtomWrite) { + strncpy(io_mode, "w", 8); + } else if (open_mode == AtomAppend) { + strncpy(io_mode, "a", 8); + } else { + pop_text_stack(lvl); + return false; + } + // binary type if (args[OPEN_TYPE].used) { Term t = args[OPEN_TYPE].tvalue; bool bin = (t == TermBinary); @@ -1323,39 +1339,37 @@ do_open(Term file_name, Term t2, "type is ~a, must be one of binary or text", t); } } - // BOM mess - if (encoding == ENC_UTF16_BE || encoding == ENC_UTF16_LE || - encoding == ENC_UCS2_BE || encoding == ENC_UCS2_LE || - encoding == ENC_ISO_UTF32_BE || encoding == ENC_ISO_UTF32_LE) { - needs_bom = true; - } - if (args[OPEN_BOM].used) { - if (args[OPEN_BOM].tvalue == TermTrue) { - avoid_bom = false; - needs_bom = true; - } else if (args[OPEN_BOM].tvalue == TermFalse) { - avoid_bom = true; - needs_bom = false; - } - } - if (open_mode == AtomRead) { - strncpy(io_mode, "r", 8); - } else if (open_mode == AtomWrite) { - strncpy(io_mode, "w", 8); - } else if (open_mode == AtomAppend) { - strncpy(io_mode, "a", 8); - } else { - pop_text_stack(lvl); - return false; - } - if ((sno = Yap_OpenStream(fname, io_mode, file_name)) < 0) { + if ((sno = Yap_OpenStream(fname, io_mode, file_name, encoding)) < 0) + { pop_text_stack(lvl); return false; } st = &GLOBAL_Stream[sno]; - st->user_name = file_name; // user requested encoding? + // BOM mess + if (encoding == ENC_UTF16_BE || encoding == ENC_UTF16_LE || + encoding == ENC_UCS2_BE || encoding == ENC_UCS2_LE || + encoding == ENC_ISO_UTF32_BE || encoding == ENC_ISO_UTF32_LE) + { + needs_bom = true; + } + if (args[OPEN_BOM].used) + { + if (args[OPEN_BOM].tvalue == TermTrue) + { + avoid_bom = false; + needs_bom = true; + } + else if (args[OPEN_BOM].tvalue == TermFalse) + { + avoid_bom = true; + needs_bom = false; + } + } + bool script = + (args[OPEN_SCRIPT].used ? args[OPEN_SCRIPT].tvalue == TermTrue : false); + if (args[OPEN_ALIAS].used) { Atom al = AtomOfTerm(args[OPEN_ALIAS].tvalue); if (!Yap_AddAlias(al, sno)) { @@ -1363,7 +1377,6 @@ do_open(Term file_name, Term t2, return false; } } - st->name = Yap_LookupAtom(fname); if (st - GLOBAL_Stream < 3) { flags |= RepError_Prolog_f; } @@ -1557,14 +1570,13 @@ static Int p_open_null_stream(USES_REGS1) { return (Yap_unify(ARG1, t)); } -int Yap_OpenStream(const char *fname, const char *io_mode, Term user_name) { +int Yap_OpenStream(const char *fname, const char* io_mode, Term user_name, encoding_t enc) { CACHE_REGS int sno; StreamDesc *st; - Atom at; - struct vfs *vfsp; - FILE *fd; - int flags; + struct vfs *vfsp = NULL; + FILE *fd = NULL; + int flags; sno = GetFreeStreamD(); if (sno < 0) { @@ -1573,20 +1585,20 @@ int Yap_OpenStream(const char *fname, const char *io_mode, Term user_name) { return -1; } st = GLOBAL_Stream + sno; - // read, write, append - st->file = NULL; - st->status = 0; - // fname = Yap_VF(fname); + // fname = Yap_VF(fname); + flags = 0; if ((vfsp = vfs_owner(fname)) != NULL) { - if (!vfsp->open(vfsp, sno, fname, "r")) { + if (!vfsp->open(vfsp, fname, io_mode, sno)) { UNLOCK(st->streamlock); PlIOError(EXISTENCE_ERROR_SOURCE_SINK, MkAtomTerm(Yap_LookupAtom(fname)), "%s", fname); + /* extract BACK info passed through the stream descriptor */ return -1; } - vfsp = GLOBAL_Stream[sno].vfs; + // read, write, append + user_name = st->user_name; } else { - fd = st->file = fopen(fname, io_mode); + fd = fopen(fname, io_mode); if (fd == NULL) { if (!strchr(io_mode, 'b') && binary_file(fname)) { UNLOCK(st->streamlock); @@ -1603,25 +1615,7 @@ int Yap_OpenStream(const char *fname, const char *io_mode, Term user_name) { return -1; } } - flags = st->status; - if (strchr(io_mode, 'w')) { - if (strchr(io_mode, 'a')) { - at = AtomAppend; - flags |= Append_Stream_f | Output_Stream_f; - } else { - at = AtomWrite; - flags |= Output_Stream_f; - } - } - if (strchr(io_mode, 'r')) { - at = AtomRead; - flags |= Input_Stream_f; - } - if (strchr(io_mode, 'b')) { - flags |= Binary_Stream_f; - } - Yap_initStream(sno, st->file, fname, user_name, LOCAL_encoding, flags, at, - vfsp); + Yap_initStream(sno, fd, fname, io_mode, user_name, LOCAL_encoding, flags, vfsp); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exists %s <%d>", fname, sno); return sno; @@ -1631,7 +1625,7 @@ int Yap_FileStream(FILE *fd, char *name, Term file_name, int flags, VFS_t *vfsp) { CACHE_REGS int sno; - Atom at; + const char *mode; sno = GetFreeStreamD(); if (sno < 0) @@ -1639,12 +1633,13 @@ int Yap_FileStream(FILE *fd, char *name, Term file_name, int flags, "new stream not available for opening")); if (flags & Output_Stream_f) { if (flags & Append_Stream_f) - at = AtomAppend; + mode = "a"; else - at = AtomWrite; - } else - at = AtomRead; - Yap_initStream(sno, fd, name, file_name, LOCAL_encoding, flags, at, vfsp); + mode = "w"; + } else { + mode = "r"; + } + Yap_initStream(sno, fd, name, mode, file_name, LOCAL_encoding, flags, vfsp); return sno; } diff --git a/os/iopreds.h b/os/iopreds.h index e0b118251..e4eb1d476 100644 --- a/os/iopreds.h +++ b/os/iopreds.h @@ -31,9 +31,8 @@ INLINE_ONLY EXTERN inline bool IsStreamTerm(Term t) { (IsApplTerm(t) && (FunctorOfTerm(t) == FunctorStream))); } -extern bool Yap_initStream(int sno, FILE *fd, const char *name, Term file_name, - encoding_t encoding, stream_flags_t flags, - Atom open_mode, void *vfs); +extern bool Yap_initStream(int sno, FILE *fd, const char *name, const char *io_mode, Term file_name, encoding_t encoding, + stream_flags_t flags, void *vfs); #define Yap_CheckStream(arg, kind, msg) \ Yap_CheckStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg) diff --git a/os/mem.c b/os/mem.c index 322b6a270..066874601 100644 --- a/os/mem.c +++ b/os/mem.c @@ -193,7 +193,7 @@ bool Yap_set_stream_to_buf(StreamDesc *st, const char *buf, st->file = f = NULL; flags = Input_Stream_f | InMemory_Stream_f; st->vfs = NULL; - Yap_initStream(st - GLOBAL_Stream, f, NULL, TermNil, LOCAL_encoding, flags, + Yap_initStream(st - GLOBAL_Stream, f, "r", TermNil, LOCAL_encoding, flags, AtomRead, NULL); // like any file stream. /* currently these streams are not seekable */ @@ -228,7 +228,7 @@ int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp, st->file = f = NULL; flags = Input_Stream_f | InMemory_Stream_f; st->vfs = NULL; - Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead, NULL); + Yap_initStream(sno, f, ""wa", TermNil, encoding, flags, AtomRead, NULL); // like any file stream. /* currently these streams are not seekable */ st->status = Input_Stream_f | InMemory_Stream_f; diff --git a/os/sig.c b/os/sig.c index 99ceae5f1..efd2ee8e1 100644 --- a/os/sig.c +++ b/os/sig.c @@ -860,5 +860,6 @@ void Yap_InitSignalPreds(void) { Yap_InitCPred("virtual_alarm", 4, virtual_alarm, SafePredFlag | SyncPredFlag); Yap_InitCPred("enable_interrupts", 0, enable_interrupts, SafePredFlag); Yap_InitCPred("disable_interrupts", 0, disable_interrupts, SafePredFlag); + my_signal_info(SIGSEGV, HandleSIGSEGV); CurrentModule = cm; } diff --git a/os/streams.c b/os/streams.c index 27dfcc81a..d3ff1f91d 100644 --- a/os/streams.c +++ b/os/streams.c @@ -445,19 +445,19 @@ found_eof(int sno, static bool stream_mode(int sno, - Term t2 USES_REGS) { /* '$set_output'(+Stream,-ErrorMessage) */ - stream_flags_t flags = GLOBAL_Stream[sno].status & - (Input_Stream_f | Output_Stream_f | Append_Stream_f); + Term t2 USES_REGS) { + /* '$set_output'(+Stream,-ErrorMessage) */ + stream_flags_t flags = GLOBAL_Stream[sno].status; if (!IsVarTerm(t2) && !(isatom(t2))) { - return FALSE; + return false; } if (flags & Input_Stream_f) return Yap_unify(t2, TermRead); - if (flags & Output_Stream_f) - return Yap_unify(t2, TermWrite); if (flags & Append_Stream_f) - return Yap_unify(t2, TermAppend); - return false; + return Yap_unify(t2, TermWrite); + if (flags & Output_Stream_f) + return Yap_unify(t2, TermWrite); + return false; } static bool diff --git a/os/yapio.h b/os/yapio.h index 3bc389397..656f65c4b 100644 --- a/os/yapio.h +++ b/os/yapio.h @@ -86,7 +86,7 @@ extern int Yap_PlGetWchar(void); extern int Yap_PlFGetchar(void); extern int Yap_GetCharForSIGINT(void); extern Int Yap_StreamToFileNo(Term); -extern int Yap_OpenStream(const char*, const char*, Term); +extern int Yap_OpenStream(const char *fname, const char* io_mode, Term user_name, encoding_t enc); extern int Yap_FileStream(FILE*, char *, Term, int, VFS_t *); extern char *Yap_TermToBuffer(Term t, encoding_t encoding, int flags); extern char *Yap_HandleToString(yhandle_t l, size_t sz, size_t *length, diff --git a/os/yio.yap b/os/yio.yap index bd1e1a037..b37757a95 100644 --- a/os/yio.yap +++ b/os/yio.yap @@ -350,7 +350,6 @@ with _S_. */ current_stream(File, Mode, Stream) :- - stream_property(Stream, mode(Mode)), '$stream_name'(Stream, File). diff --git a/packages/python/pl2pl.c b/packages/python/pl2pl.c index 82acbfda7..b9661f772 100644 --- a/packages/python/pl2pl.c +++ b/packages/python/pl2pl.c @@ -119,17 +119,17 @@ static foreign_t prolog_list_to_python_list(term_t plist, term_t pyt, term_t tle term_t targ = PL_new_term_ref(); if (PL_skip_list(plist, targ, &sz) <0 || ! PL_get_nil(targ)) { - pyErrorAndReturn( false, false); + pyErrorAndReturn( false); } if (!PyList_Check(pyl)) { - pyErrorAndReturn( false, false); + pyErrorAndReturn( false); } if (sz > PyList_GET_SIZE(pyl)) - pyErrorAndReturn( false, false); + pyErrorAndReturn( false); for (i=0; i < sz; i++) { if (!PL_get_list(plist, targ, plist)) { - pyErrorAndReturn( false, false); + pyErrorAndReturn( false); } PyObject *t = term_to_python(targ, true, NULL, true); PyList_SET_ITEM(pyl, i, t); @@ -139,7 +139,7 @@ static foreign_t prolog_list_to_python_list(term_t plist, term_t pyt, term_t tle } else { python_assign(tlen, PyLong_FromUnsignedLong(sz), NULL); } - pyErrorAndReturn( true, false); + pyErrorAndReturn( true); } install_t install_pl2pl(void) { diff --git a/packages/python/py2pl.c b/packages/python/py2pl.c index a52a5edeb..5af802c76 100644 --- a/packages/python/py2pl.c +++ b/packages/python/py2pl.c @@ -207,6 +207,7 @@ foreign_t python_to_term(PyObject *pVal, term_t t) { } X_API YAP_Term pythonToYAP(PyObject *pVal) { + term_t t = PL_new_term_ref(); if (pVal == NULL || !python_to_term(pVal, t)) { PL_reset_term_refs(t); diff --git a/packages/python/py4yap.h b/packages/python/py4yap.h index aaaa5d2fe..0c799427e 100644 --- a/packages/python/py4yap.h +++ b/packages/python/py4yap.h @@ -168,14 +168,12 @@ extern void pyErrorHandler__(int line, const char *file, const char *code); } \ } -#define pyErrorAndReturn(x, y) \ +#define pyErrorAndReturn(x) \ { \ if (PyErr_Occurred()) { \ pyErrorHandler__(__LINE__, __FILE__, __FUNCTION__); \ - return (x); \ - } else { \ - return (x); \ } \ + return (x); \ } // #define pyErrorAndReturn( x, y ) return x diff --git a/packages/python/pyio.c b/packages/python/pyio.c index 0c645922d..4fdc5586f 100644 --- a/packages/python/pyio.c +++ b/packages/python/pyio.c @@ -43,7 +43,7 @@ static int py_put(int sno, int ch) } VFS_t pystream; - static void *py_open(VFS_t *me, int sno, const char *name, const char *io_mode) { + static void *py_open(VFS_t *me, const char *name, const char *io_mode, int sno) { #if HAVE_STRCASESTR if (strcasestr(name, "/python/") == name) name += strlen("/python/"); @@ -51,29 +51,28 @@ VFS_t pystream; if (strstr(name, "/python/") == name) name += strlen("/python/"); #endif + PyObject *pystream = string_to_python(name, true, NULL); + if (pystream == NULL || pystream == Py_None) { + return NULL; + } StreamDesc *st = YAP_RepStreamFromId(sno); - if (strcmp(name,"sys.output") == 0) { + st->name = YAP_LookupAtom(name); + if (0&&strcmp(name,"sys.stdout") == 0) { st->user_name = TermOutStream; - } else if(strcmp(name,"sys.error") == 0) { + } else if(0&&strcmp(name,"sys.stderr") == 0) { st->user_name = TermErrStream; } else { - // we assume object is already open, so there is no need to open it. - PyObject *pystream = string_to_python(name, true, NULL); - if (pystream == Py_None) { - return NULL; - } else { - st->u.private_data = pystream; - st->vfs = me; - st->name = YAP_LookupAtom(name); - st->user_name = YAP_MkAtomTerm(st->name); - } + st->user_name = YAP_MkAtomTerm(st->name); } + // we assume object is already open, so there is no need to open it. + st->u.private_data = pystream; + st->vfs = me; return st; } static bool py_close(int sno) { - StreamDesc *st = YAP_RepStreamFromId(sno); - Py_DECREF(st->u.private_data); + StreamDesc *st = YAP_RepStreamFromId(sno); + Py_XDECREF(st->u.private_data); return true; } @@ -153,7 +152,7 @@ return PyLong_AsLong(pyr); static void py_flush(int sno) { StreamDesc *s = YAP_GetStreamFromId(sno); - YAP_Term tg = python_acquire_GIL(); + PyGILState_STATE tg = python_acquire_GIL(); PyObject *flush = PyObject_GetAttrString(s->u.private_data, "flush"); PyObject_CallFunction(flush, NULL); python_release_GIL(tg); diff --git a/packages/python/pypreds.c b/packages/python/pypreds.c index c95896c2d..d3c15276f 100644 --- a/packages/python/pypreds.c +++ b/packages/python/pypreds.c @@ -14,10 +14,10 @@ static foreign_t python_len(term_t tobj, term_t tf) { o = term_to_python(tobj, true, NULL, true); if (o == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } len = PyObject_Length(o); - pyErrorAndReturn(PL_unify_int64(tf, len), false); + pyErrorAndReturn(PL_unify_int64(tf), false); } static foreign_t python_dir(term_t tobj, term_t tf) { @@ -26,13 +26,13 @@ static foreign_t python_dir(term_t tobj, term_t tf) { o = term_to_python(tobj, true, NULL, true); if (o == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } dir = PyObject_Dir(o); { foreign_t rc = address_to_term(dir, tf); ; - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } } @@ -43,14 +43,14 @@ static foreign_t python_index(term_t tobj, term_t tindex, term_t val) { o = term_to_python(tobj, true, NULL, true); if (o == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } if (!PySequence_Check(o)) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } i = term_to_python(tindex, true, NULL, true); if (i == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } #if PY_MAJOR_VERSION < 3 f = PyObject_CallMethodObjArgs(o, PyString_FromString("getitem"), i); @@ -60,7 +60,7 @@ static foreign_t python_index(term_t tobj, term_t tindex, term_t val) { { foreign_t rc = address_to_term(f, val); ; - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } } @@ -72,13 +72,13 @@ static foreign_t python_is(term_t tobj, term_t tf) { o = term_to_python(tobj, true, NULL, true); if (!o) { python_release_GIL(lim); - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } foreign_t rc = python_to_term(o, tf); if (rc) PyErr_Clear(); python_release_GIL(lim); - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } static foreign_t python_proc(term_t tobj) { @@ -89,7 +89,7 @@ static foreign_t python_proc(term_t tobj) { o = term_to_python(tobj, true, NULL, true); python_release_GIL(lim); bool rc = o != NULL; - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } static foreign_t python_slice(term_t parent, term_t indx, term_t tobj) { @@ -104,10 +104,10 @@ static foreign_t python_slice(term_t parent, term_t indx, term_t tobj) { p = term_to_python(parent, true, NULL, true); // Exp if (!pI || !p) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } else if ((pF = PySequence_GetSlice(p, 0, 0)) == NULL) { PyErr_Print(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } Py_DecRef(pI); Py_DecRef(p); @@ -115,7 +115,7 @@ static foreign_t python_slice(term_t parent, term_t indx, term_t tobj) { { foreign_t rc; rc = address_to_term(pF, tobj); - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } } @@ -132,14 +132,14 @@ static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, pF = term_to_python(tin, true, NULL, true); PyErr_Clear(); if (pF == NULL) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } if (PL_is_atom(targs)) { pArgs = NULL; } else { if (!PL_get_name_arity(targs, &aname, &arity)) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } if (arity == 1 && PL_get_arg(1, targs, targ) && PL_is_variable(targ)) { /* ignore (_) */ @@ -150,16 +150,16 @@ static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, DebugPrintf("Tuple %p\n", pArgs); if (!pArgs) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } for (i = 0; i < arity; i++) { PyObject *pArg; if (!PL_get_arg(i + 1, targs, targ)) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } pArg = term_to_python(targ, true, NULL, true); if (pArg == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } /* pArg reference stolen here: */ PyTuple_SetItem(pArgs, i, pArg); @@ -188,16 +188,16 @@ static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, } } else { PyErr_Print(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } if (pArgs) Py_DECREF(pArgs); Py_DECREF(pF); if (pValue == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } out = address_to_term(pValue, tf); - pyErrorAndReturn(out, false); + pyErrorAndReturn(out); } static foreign_t assign_python(term_t exp, term_t name) { @@ -206,11 +206,11 @@ static foreign_t assign_python(term_t exp, term_t name) { if (e == NULL) { python_release_GIL(stackp); - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } bool b = python_assign(name, e, NULL); python_release_GIL(stackp); - pyErrorAndReturn(b, false); + pyErrorAndReturn(b); } static foreign_t python_builtin_eval(term_t caller, term_t dict, term_t out) { @@ -224,27 +224,27 @@ static foreign_t python_builtin_eval(term_t caller, term_t dict, term_t out) { if ((env = py_Builtin) == NULL) { // no point in even trying - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } if (PL_get_name_arity(caller, &name, &arity)) { if (!(s = PL_atom_chars(name))) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } if ((pI = PyObject_GetAttrString(env, s)) == NULL) { PyErr_Print(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } Py_INCREF(pI); } else { // Prolog should make sure this never happens. - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } pArgs = PyTuple_New(arity); DebugPrintf("Tuple %p\n", pArgs); for (i = 0; i < arity; i++) { PyObject *pArg; if (!PL_get_arg(i + 1, caller, targ)) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } /* ignore (_) */ if (i == 0 && PL_is_variable(targ)) { @@ -252,13 +252,13 @@ static foreign_t python_builtin_eval(term_t caller, term_t dict, term_t out) { } else { pArg = term_to_python(targ, true, NULL, true); if (pArg == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } } /* pArg reference stolen here: */ if (PyTuple_SetItem(pArgs, i, pArg)) { PyErr_Print(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } } pOut = PyObject_CallObject(pI, pArgs); @@ -266,12 +266,12 @@ static foreign_t python_builtin_eval(term_t caller, term_t dict, term_t out) { Py_DECREF(pI); if (pOut == NULL) { PyErr_Print(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } { foreign_t rc = address_to_term(pOut, out); ; - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } } @@ -284,37 +284,37 @@ static foreign_t python_access(term_t obj, term_t f, term_t out) { term_t targ = PL_new_term_ref(); if (o == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } if (PL_is_atom(f)) { if (!PL_get_atom_chars(f, &s)) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } if ((pValue = PyObject_GetAttrString(o, s)) == NULL) { PyErr_Print(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } Py_INCREF(pValue); - { pyErrorAndReturn(python_to_term(pValue, out), false); } + { pyErrorAndReturn(python_to_term(pValue), false); } } if (!PL_get_name_arity(f, &name, &arity)) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } s = PL_atom_chars(name); if (!s) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } if ((pF = PyObject_GetAttrString(o, s)) == NULL) { - DebugPrintf("Function %p\n", pArgs); + DebugPrintf("Function %p\n", o); PyErr_Print(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } pArgs = PyTuple_New(arity); DebugPrintf("Tuple %p\n", pArgs); for (i = 0; i < arity; i++) { PyObject *pArg; if (!PL_get_arg(i + 1, f, targ)) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } /* ignore (_) */ if (i == 0 && PL_is_variable(targ)) { @@ -322,7 +322,7 @@ static foreign_t python_access(term_t obj, term_t f, term_t out) { } pArg = term_to_python(targ, true, NULL, true); if (pArg == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } /* pArg reference stolen here: */ PyTuple_SetItem(pArgs, i, pArg); @@ -331,9 +331,9 @@ static foreign_t python_access(term_t obj, term_t f, term_t out) { Py_DECREF(pArgs); Py_DECREF(pF); if (pValue == NULL) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } - { pyErrorAndReturn(python_to_term(pValue, out), false); } + { pyErrorAndReturn(python_to_term(pValue), false); } } static foreign_t python_field(term_t parent, term_t att, term_t tobj) { @@ -343,7 +343,7 @@ static foreign_t python_field(term_t parent, term_t att, term_t tobj) { int arity; if (!PL_get_name_arity(att, &name, &arity)) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } else { PyObject *p; @@ -352,29 +352,29 @@ static foreign_t python_field(term_t parent, term_t att, term_t tobj) { p = term_to_python(parent, true, NULL, true); // Exp if (!PL_get_name_arity(att, &name, &arity)) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } s = PL_atom_chars(name); if (arity == 1 && !strcmp(s, "()")) { if (!PL_get_arg(1, att, att)) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } if (!PL_get_name_arity(att, &name, &arity)) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } s = PL_atom_chars(name); } if (!s || !p) { - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } else if ((pF = PyObject_GetAttrString(p, s)) == NULL) { PyErr_Clear(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } } { foreign_t rc; rc = address_to_term(pF, tobj); - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } } @@ -383,7 +383,7 @@ static foreign_t python_main_module(term_t mod) { foreign_t rc; PyErr_Clear(); rc = address_to_term(py_Main, mod); - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } } @@ -392,7 +392,7 @@ static foreign_t python_function(term_t tobj) { PyObject *obj = term_to_python(tobj, true, NULL, true); foreign_t rc = PyFunction_Check(obj); - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } foreign_t python_builtin(term_t out) { @@ -400,7 +400,7 @@ foreign_t python_builtin(term_t out) { foreign_t rc; PyErr_Clear(); rc = address_to_term(py_Builtin, out); - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } } @@ -417,15 +417,15 @@ static foreign_t python_run_file(term_t file) { #else FILE *f = fopen(s, "r"); if (f == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } PyRun_SimpleFileEx(f, s, 1); #endif { - { pyErrorAndReturn(true, false); } + { pyErrorAndReturn(true); } } } - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } extern PyThreadState *YAP_save; @@ -442,7 +442,7 @@ static foreign_t python_run_command(term_t cmd) { PyRun_SimpleString(s); rc = true; } - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } static foreign_t python_run_script(term_t cmd, term_t fun) { @@ -483,7 +483,7 @@ static foreign_t python_run_script(term_t cmd, term_t fun) { Py_DECREF(pModule); PyErr_Print(); fprintf(stderr, "Call failed\n"); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } } else { pyErrorHandler(); @@ -495,11 +495,11 @@ static foreign_t python_run_script(term_t cmd, term_t fun) { Py_DECREF(pModule); } else { PyErr_Print(); - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } - { pyErrorAndReturn(true, false); } + { pyErrorAndReturn(true); } } - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } static foreign_t python_export(term_t t, term_t pl) { @@ -510,16 +510,16 @@ static foreign_t python_export(term_t t, term_t pl) { term_t targ = PL_new_term_ref(); if (!PL_get_arg(1, t, targ)) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } if (!PL_get_pointer(targ, &ptr)) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } Py_INCREF((PyObject *)ptr); - /* pyErrorAndReturn( __main__, false) */ + /* pyErrorAndReturn( __main__) */ rc = python_to_term((PyObject *)ptr, pl); } - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } /** @@ -546,7 +546,7 @@ static int python_import(term_t mname, term_t mod) { if (!PL_get_arg(1, mname, arg) || !PL_get_atom_chars(arg, &sa) || !PL_get_arg(2, mname, mname)) { python_release_GIL(t0); - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } PL_get_atom_chars(arg, &sa); strcpy(s, sa); @@ -556,7 +556,7 @@ static int python_import(term_t mname, term_t mod) { } else if (!PL_get_nchars(mname, &len, &s, CVT_ATOM | CVT_EXCEPTION | REP_UTF8)) { python_release_GIL(t0); - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } else { break; } @@ -568,7 +568,7 @@ static int python_import(term_t mname, term_t mod) { #endif python_release_GIL(t0); if (pName == NULL) { - pyErrorAndReturn(false, false); + pyErrorAndReturn(false); } PyObject *pModule = PyImport_Import(pName); @@ -580,11 +580,11 @@ static int python_import(term_t mname, term_t mod) { PyErr_Print(); PyErr_Clear(); #endif - { pyErrorAndReturn(false, false); } + { pyErrorAndReturn(false); } } { foreign_t rc = address_to_term(pModule, mod); - pyErrorAndReturn(rc, false); + pyErrorAndReturn(rc); } } @@ -593,8 +593,8 @@ static foreign_t python_to_rhs(term_t inp, term_t t) { PyErr_Clear(); pVal = term_to_python(inp, true, NULL, true); if (pVal == NULL) - pyErrorAndReturn(false, false); - pyErrorAndReturn(address_to_term(pVal, t), false); + pyErrorAndReturn(false); + pyErrorAndReturn(address_to_term(pVal), false); } // static PyThreadState *_saveP = NULL; @@ -605,7 +605,7 @@ static YAP_Int p_python_ensure(term_t ptr) { PyGILState_STATE _tState = PyGILState_Ensure(); - pyErrorAndReturn( PL_unify_int64(ptr, _tState), false); + pyErrorAndReturn( PL_unify_int64(ptr), false); } static YAP_Int @@ -615,7 +615,7 @@ static YAP_Int PyGILState_STATE _tState; PL_get_int64( ptr, &_tState); PyGILState_Release( _tState ); - pyErrorAndReturn( true, false); + pyErrorAndReturn( true); } */ @@ -628,40 +628,50 @@ static YAP_Int p_python_threaded(void) { // PyEval_ReleaseThread(tstate); // _threaded = true; // _locked = 0; - pyErrorAndReturn(true, false); + pyErrorAndReturn(true); } +static PyGILState_STATE gstates[64]; +static int gstatei = 0; term_t python_acquire_GIL(void) { static PyGILState_STATE gstate; term_t curSlot = PL_new_term_ref(); - if (!_threaded) - pyErrorAndReturn(curSlot, false); // extern int Yap_do_low_level_trace; // Yap_do_low_level_trace = 1; - // f[rintf( stderr, "++%d\n", ++_locked); + // fprintf( stderr, "++%d\n", ++_locked); // if (_locked > 0) { _locked++ ; } // else - gstate = PyGILState_Ensure(); - fprintf(stderr, "+%d\n", (int)gstate); - PL_put_integer(curSlot, gstate); - pyErrorAndReturn(curSlot, false); + if (_threaded) { + gstates[gstatei] = PyGILState_Ensure(); + } + fprintf(stderr, "+%d\n", (int)gstatei); + PL_put_integer(curSlot, gstatei++); + return curSlot; } bool python_release_GIL(term_t curBlock) { PyGILState_STATE gstate; + int gstateix; - if (_threaded) { - PL_get_integer(curBlock, &gstate); - PyGILState_Release(gstate); - fprintf(stderr, "-%d\n", (int)gstate); + PL_get_integer(curBlock, &gstateix); + PL_reset_term_refs(curBlock); + if (gstatei != gstateix) { + if (gstateix > gstatei) { + fprintf(stderr, "gstateix(%d) > gstatei(%d)\n", gstateix, gstatei); + return false; + } else { + fprintf(stderr, "gstateix(%d) < gstatei(%d)\n", gstateix, gstatei); + return false; + } + } + if (_threaded) { + PyGILState_Release(gstates[gstatei--]); } - PL_reset_term_refs(curBlock); - pyErrorAndReturn(true, false); + pyErrorAndReturn(true); } -//: prolog: release python - +/ install_t install_pypreds(void) { PL_register_foreign("python_builtin_eval", 3, python_builtin_eval, 0); PL_register_foreign("python_builtin", 1, python_builtin, 0); diff --git a/packages/python/swig/yap4py/yapi.py b/packages/python/swig/yap4py/yapi.py index 6542105f8..25d4853da 100644 --- a/packages/python/swig/yap4py/yapi.py +++ b/packages/python/swig/yap4py/yapi.py @@ -1,12 +1,21 @@ - -import os.path -import sys -import keyword -# debugging support. -# import pdb -from collections import namedtuple import readline -from .yap import * +from yap4py.yap import YAPEngine, YAPEngineArgs, YAPPredicate, YAPQuery, YAPPrologPredicate, YAPVarTerm +from os.path import join, dirname +from collections import namedtuple +import sys + +yap_lib_path = dirname(__file__) + +compile = namedtuple('compile', 'file') +bindvars = namedtuple('bindvars', 'list') +library = namedtuple('library', 'list') +v0 = namedtuple('v', 'slot') +yap_query = namedtuple('yap_query', 'query owner') +jupyter_query = namedtuple('jupyter_query', 'vars dict') +python_query = namedtuple('python_query', 'vars dict') +yapi_query = namedtuple('yapi_query', 'vars dict') +show_answer = namedtuple('show_answer', 'vars dict') +set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value') class Engine( YAPEngine ): @@ -16,10 +25,10 @@ class Engine( YAPEngine ): if not args: args = EngineArgs(**kwargs) if self_contained: - yap_lib_path = os.path.dirname(__file__) - args.setYapShareDir(os.path.join(yap_lib_path, "prolog")) + yap_lib_path = dirname(__file__) + args.setYapShareDir(join(yap_lib_path, "prolog")) args.setYapPLDIR(yap_lib_path) - args.setSavedState(os.path.join(yap_lib_path, "startup.yss")) + args.setSavedState(join(yap_lib_path, "startup.yss")) YAPEngine.__init__(self, args) self.goal(set_prolog_flag('verbose', 'silent')) self.goal(compile(library('yapi'))) @@ -31,9 +40,6 @@ class Engine( YAPEngine ): else: self.goal(g) - def f(self, g): - self.E.fun(g) - class EngineArgs( YAPEngineArgs ): """ Interface to Engine Options class""" @@ -47,112 +53,79 @@ class Predicate( YAPPredicate ): def __init__(self, t, module=None): super().__init__(t) -class IQuery(YAPQuery): +class Query: """Goal is a predicate instantiated under a specific environment """ def __init__(self, engine, g): - self = engine.query(g) - self.port = "call" - self.bindings = None + self.q = engine.query(g) + if self.q: + self.port = "call" + self.bindings = None + self.engine = engine + self.answer = {} def __iter__(self): - return PrologTableIter( self ) - -class PrologTableIter: - - def __init__(self, q): - try: - self.q = q - except: - print('Error') - - def __iter__(self): - # Iterators are iterables too. - # - # Adding this functions to make them so. return self def __next__(self): + print(self) if not self.q: raise StopIteration() if self.q.next(): - rc = self.q.bindings - if self.q.port == "exit": - self.q.close() + rc = self.answer + if self.port == "exit": + self.close() return rc else: - if self.q: + if self: self.close() raise StopIteration() - def close(self): + def close( self ): self.q.close() self.q = None -f2p = {"fails":{}} -for i in range(16): - f2p[i] ={} - - - -global engine, handler - -yap_lib_path = os.path.dirname(__file__) - -compile = namedtuple('compile', 'file') -bindvars = namedtuple('bindvars', 'list') -library = namedtuple('library', 'list') -v = namedtuple( 'v', 'slot') -yap_query = namedtuple( 'yap_query', 'query owner') -jupyter_query = namedtuple( 'jupyter_query', 'vars dict') -python_query = namedtuple( 'python_query', 'vars dict') -yapi_query = namedtuple( 'yapi_query', 'vars dict') -show_answer = namedtuple( 'show_answer', 'vars dict') -set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value') - - -def named( name, arity): +def name( name, arity): try: - if arity > 0 and name.isidentifier() and not keyword.iskeyword(name): + if arity > 0 and name.isidentifier(): # and not keyword.iskeyword(name): s = [] for i in range(arity): s += ["A" + str(i)] - f2p[arity][name] = namedtuple(name, s) + return namedtuple(name, s) except: - f2p[fails][name] = True + return None class PrologPredicate( YAPPrologPredicate ): """ Interface to Prolog Predicate""" -class v(YAPVarTerm): +class v(YAPVarTerm,v0): def __init__(self): - super().__init__() + YAPVarTerm.__init__() def binding(self): return self.term() -def numbervars( q ): - Dict = {} - if True: - engine.goal(show_answer( q.namedVars(), Dict)) - return Dict - rc = q.namedVarsVector() - q.r = q.goal().numbervars() - o = [] - for i in rc: - if len(i) == 2: - do = str(i[0]) + " = " + str( i[1] ) + "\n" - o += do - else: - do = str(i[0]) + " = " + str( i[1] ) + "\n" - o += do - return o class YAPShell: + def numbervars( self ): + Dict = {} + self.engine.goal(show_answer( self, Dict)) + return Dict + # rc = self.q.namedVarsVector() + # self.q.r = self.q.goal().numbervars() + # o = [] + # for i in rc: + # if len(i) == 2: + # do = str(i[0]) + " = " + str( i[1] ) + "\n" + # o += do + # else: + # do = str(i[0]) + " = " + str( i[1] ) + "\n" + # o += do + # return o - - def query_prolog(self, engine, query): + def query_prolog(self, query): #import pdb; pdb.set_trace() # # construct a query from a one-line string @@ -172,12 +145,12 @@ class YAPShell: # print( "Error: Variable Name matches a Python Symbol") # return do_ask = True - self.e = engine + engine = self.engine bindings = [] g = python_query(self, query) if not self.q: - self.it = IQuery( engine, g ) - for bind in self.it: + self.q = Query( engine, g ) + for bind in self.q: bindings += [bind] if do_ask: print(bindings) @@ -214,7 +187,7 @@ class YAPShell: if not s: loop = False else: - self.query_prolog(engine, s) + self.query_prolog(s) except SyntaxError as err: print("Syntax Error error: {0}".format(err)) except EOFError: @@ -233,13 +206,13 @@ class YAPShell: # engine = yap.YAPEngine(yap.YAPParams()); # def __init__(self, engine, **kwargs): - self.live(engine) + self.engine = engine + self.live(engine) def main(): engine = Engine() - handler = numbervars YAPShell(engine) if __name__ == "__main__": diff --git a/packages/python/yap_kernel/yap_ipython/core/interactiveshell.py b/packages/python/yap_kernel/yap_ipython/core/interactiveshell.py index a0231ebd5..bcf280720 100644 --- a/packages/python/yap_kernel/yap_ipython/core/interactiveshell.py +++ b/packages/python/yap_kernel/yap_ipython/core/interactiveshell.py @@ -2664,9 +2664,22 @@ class InteractiveShell(SingletonConfigurable): print("go") result = None try: - result = self._yrun_cell( - raw_cell, store_history, silent, shell_futures) + import trace + tracer = trace.Trace( + #ignoredirs=[sys.prefix, sys.exec_prefix], + trace=1, + count=0) + + # run the new command using the given tracer + # + result =tracer.runfunc(self._yrun_cell, + raw_cell, store_history, + silent, shell_futures) + + # result = self._yrun_cell( + # raw_cell, store_history, silent, shell_futures) finally: + print("ugh", self.events) self.events.trigger('post_execute') if not silent: self.events.trigger('post_run_cell', result) diff --git a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap index bcd6a9040..bf26c388d 100644 --- a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap +++ b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap @@ -62,9 +62,11 @@ blankc('\t'). streams(false) :- -% close( user_input), - close( user_error ), - close( user_output ). + flush_output, + forall( + stream_property( S, mode(_) ), + close(S) + ). streams(true) :- % open('/python/input', read, _Input, [alias(user_input),bom(false)]), open('/python/sys.stdout', append, _Output, [alias(user_output)]), diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index 5f07d0c76..73f78d015 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -39,6 +39,7 @@ completions = namedtuple('completions', 'txt self' ) errors = namedtuple('errors', 'self text' ) streams = namedtuple('streams', ' text' ) +global engine class YAPInputSplitter(InputSplitter): """An input splitter that recognizes all of iyap's special syntax.""" @@ -106,11 +107,10 @@ class YAPInputSplitter(InputSplitter): def validQuery(self, text, engine, shell, line=None): """Return whether a legal query """ - if text == shell.os: + if shell and text == shell.os: return True if not line: line = text.rstrip() - (line, _, _, _)=self.shell.clean_end(line) self.errors = [] engine.mgoal(errors(self, line),"user") return self.errors != [] @@ -181,7 +181,7 @@ class YAPInputSplitter(InputSplitter): if self.transformer_accumulating: return True else: - return self.validQuery(self.source, self.yapeng, self) + return self.validQuery(self.source, engine, self.shell) def transform_cell(self, cell): """Process and translate a cell of input. @@ -509,6 +509,8 @@ class YAPRun: def __init__(self, shell): self.shell = shell self.yapeng = Engine() + global engine + engine = self.yapeng self.yapeng.goal(use_module(library("jupyter"))) self.query = None self.os = None @@ -542,6 +544,7 @@ class YAPRun: pg = jupyter_query( self, program, query) self.query = self.yapeng.query( pg) self.query.port = "call" + self.query.answer = {} else: self.query.port = "retry" self.os = s diff --git a/packages/swig/android/streamer.cpp b/packages/swig/android/streamer.cpp index ce99d8773..514d1d5f0 100644 --- a/packages/swig/android/streamer.cpp +++ b/packages/swig/android/streamer.cpp @@ -36,7 +36,7 @@ void Java_pt_up_yap_streamerJNI_swig_1module_1init__(void) { static std::string buff0; static void * -and_open(struct vfs *me, int sno, const char *name, const char *io_mode) { +and_open(struct vfs *me, const char *name, const char *io_mode, int sno) { // we assume object is already open, so there is no need to open it. GLOBAL_Stream[sno].vfs_handle = streamerInstance; GLOBAL_Stream[sno].vfs = me; diff --git a/pl/absf.yap b/pl/absf.yap index f8ae4311b..eab63a0fe 100755 --- a/pl/absf.yap +++ b/pl/absf.yap @@ -226,7 +226,7 @@ absolute_file_name(File0,File) :- '$find_in_path'(user_output,_,user_ouput, _, _) :- !. '$find_in_path'(user_error,_,user_error, _, _) :- !. '$find_in_path'(Name, Opts, File, _, First) :- -% ( atom(Name) -> true ; start_low_level_trace ), + % ( atom(Name) -> true ; start_low_level_trace ), get_abs_file_parameter( file_type, Opts, Type ), get_abs_file_parameter( access, Opts, Access ), get_abs_file_parameter( expand, Opts, Expand ), diff --git a/pl/boot.yap b/pl/boot.yap index 94d4b7fbc..d386872e3 100644 --- a/pl/boot.yap +++ b/pl/boot.yap @@ -250,9 +250,12 @@ initialize_prolog :- :- c_compile( 'preds.yap' ). :- c_compile( 'modules.yap' ). :- c_compile( 'grammar.yap' ). + +:- start_low_level_trace. + :- ['absf.yap']. -%:- start_low_level_trace. +:- stop_low_level_trace. :- use_module('error.yap'). @@ -305,6 +308,8 @@ initialize_prolog :- :- ['protect.yap']. +:- stop_low_level_trace. + version(yap,[6,3]). :- op(1150,fx,(mode)). @@ -444,7 +449,7 @@ modules defining clauses for it too. Dynamic predicate, normally not defined. Called by the Prolog system on run-time exceptions that can be repaired `just-in-time`. The values for _Exception_ are described below. See also catch/3 and throw/1. -If this hook predicate succeeds it must instantiate the _Action_ argument to the atom `fail` to make the operation fail silently, `retry` to tell Prolog to retry the operation or `error` to make the system generate an exception. The action `retry` only makes sense if this hook modified the environment such that the operation can now succeed without error. +If this hook preodicate succeeds it must instantiate the _Action_ argument to the atom `fail` to make the operation fail silently, `retry` to tell Prolog to retry the operation or `error` to make the system generate an exception. The action `retry` only makes sense if this hook modified the environment such that the operation can now succeed without error. + `undefined_predicate` _Context_ is instantiated to a predicate-indicator ( _Module:Name/Arity_). If the predicate fails Prolog will generate an existence_error exception. The hook is intended to implement alternatives to the SWI built-in autoloader, such as autoloading code from a database. Do not use this hook to suppress existence errors on predicates. See also `unknown`. diff --git a/regression/modules/goal_expansion_tests.yap b/regression/modules/goal_expansion_tests.yap index 02ac2e6f1..86a00c8b9 100644 --- a/regression/modules/goal_expansion_tests.yap +++ b/regression/modules/goal_expansion_tests.yap @@ -1,4 +1,4 @@ - + :- use_module(library(lists)). @@ -13,4 +13,3 @@ given user:goal_expansion(a(X,Y), m, Y is X*X )) test m:a(3,X) returns X =@= 9 given user:goal_expansion(a(X,Y), m, Y is X*X ), user:goal_expansion(a(X), X is 3*5) -