From 4b33d5d87b6119ac5f30fa752b9ff0d204dd264f Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 17 Jun 2016 17:13:17 +0100 Subject: [PATCH] bug fixes + Android --- os/CMakeLists.txt | 12 ++- os/charsio.c | 12 ++- os/iopreds.c | 13 ++- os/iopreds.h | 263 ++++++++-------------------------------------- os/readline.c | 22 ++-- os/readterm.c | 18 +++- os/sysbits.c | 224 ++++++++++++++++----------------------- os/yapio.h | 27 ++--- 8 files changed, 188 insertions(+), 403 deletions(-) diff --git a/os/CMakeLists.txt b/os/CMakeLists.txt index 4a33ab1ac..16685e1c2 100644 --- a/os/CMakeLists.txt +++ b/os/CMakeLists.txt @@ -1,6 +1,7 @@ set (YAPOS_SOURCES alias.c + assets.c charsio.c chartypes.c console.c @@ -31,8 +32,13 @@ set (YAPOS_HEADERS fmemopen.h yapio.h sysbits.h + VFS.h ) +set (YAPOS_PL_SOURCES + edio.yap + chartypes.yap +) include_directories (../H ../include ../OPTYap . ${GMP_INCLUDE_DIR} ${PROJECT_BINARY_DIR}) @@ -87,7 +93,7 @@ endif (READLINE) set (POSITION_INDEPENDENT_CODE TRUE) -add_library (libYAPOs OBJECT +add_library (libYAPOs OBJECT ${YAPOS_SOURCES} ) @@ -108,3 +114,7 @@ configure_file ("${PROJECT_SOURCE_DIR}/os/YapIOConfig.h.cmake" #set( CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${GMP_LIBRARIES} ) + +install (FILES ${YAPOS_PL_SOURCES} + DESTINATION ${libpl}/os + ) diff --git a/os/charsio.c b/os/charsio.c index 7b640ce1e..9c24e673a 100644 --- a/os/charsio.c +++ b/os/charsio.c @@ -111,6 +111,11 @@ Int Yap_peek(int sno) { } return ch; } +#endif +#if !MAY_READ + if (s->status & InMemory_Stream_f ) { + return Yap_MemPeekc( sno ); + } #endif /* buffer the character */ if (s->encoding == Yap_SystemEncoding() && 0) { @@ -659,12 +664,9 @@ static Int put_char(USES_REGS1) { /* '$put'(Stream,N) */ return (TRUE); } -/** @pred tab_1(+ _N_) - +/** @pred tab(+ _N_) Outputs _N_ spaces to the current output stream. - - */ static Int tab_1(USES_REGS1) { /* nl */ int sno = LOCAL_c_output_stream; @@ -684,7 +686,7 @@ static Int tab_1(USES_REGS1) { /* nl */ LOCK(GLOBAL_Stream[sno].streamlock); if (GLOBAL_Stream[sno].status & Binary_Stream_f) { UNLOCK(GLOBAL_Stream[sno].streamlock); - Yap_Error(PERMISSION_ERROR_OUTPUT_TEXT_STREAM, ARG1, "nl/0"); + Yap_Error(PERMISSION_ERROR_OUTPUT_TEXT_STREAM, ARG1, "user_output"); return (FALSE); } diff --git a/os/iopreds.c b/os/iopreds.c index c719a60ac..87c7541f0 100644 --- a/os/iopreds.c +++ b/os/iopreds.c @@ -353,6 +353,13 @@ static void InitStdStreams(void) { GLOBAL_Stream[StdInStream].name = Yap_LookupAtom("user_input"); GLOBAL_Stream[StdOutStream].name = Yap_LookupAtom("user_output"); GLOBAL_Stream[StdErrStream].name = Yap_LookupAtom("user_error"); +#if USE_READLINE + if (GLOBAL_Stream[StdInStream].status & Tty_Stream_f && + GLOBAL_Stream[StdOutStream].status & Tty_Stream_f && + GLOBAL_Stream[StdErrStream].status & Tty_Stream_f) { + Yap_InitReadline( TermTrue ); + } +#endif LOCAL_c_input_stream = StdInStream; LOCAL_c_output_stream = StdOutStream; LOCAL_c_error_stream = StdErrStream; @@ -655,7 +662,6 @@ int EOFWPeek(int sno) { return EOFWGetc(sno); } post_process_read_char, something to think about */ int PlGetc(int sno) { StreamDesc *s = &GLOBAL_Stream[sno]; - return fgetc(s->file); } @@ -1294,12 +1300,11 @@ do_open(Term file_name, Term t2, Yap_SetTextFile(RepAtom(AtomOfTerm(file_name))->StrOfAE); } #endif + // __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s", fname); flags &= ~(Free_Stream_f); if (!Yap_initStream(sno, fd, fname, file_name, encoding, flags, open_mode)) return false; - if (!Yap_initStream(sno, fd, fname, file_name, encoding, flags, open_mode)) - return false; - if (open_mode == AtomWrite) { + if (open_mode == AtomWrite) { if (needs_bom && !write_bom(sno, st)) return false; } else if (open_mode == AtomRead && !avoid_bom) { diff --git a/os/iopreds.h b/os/iopreds.h index 893ab69d0..96f1a4fc9 100644 --- a/os/iopreds.h +++ b/os/iopreds.h @@ -6,29 +6,14 @@ * comments: Input/Output C implemented predicates * * * *************************************************************************/ -#ifdef SCCS -static char SccsId[] = "%W% %G%"; -#endif #ifndef IOPREDS_H #define IOPREDS_H 1 -#if _WIN32 -#define USE_SOCKET 1 -#define HAVE_SOCKET 1 -#endif - #include "Atoms.h" #include "Yap.h" #include -/* - * This file defines main data-structure for stream management, - * - */ - -extern size_t Yap_page_size; - #if defined(_MSC_VER) || defined(__MINGW32__) #include @@ -37,6 +22,20 @@ extern size_t Yap_page_size; #include +#include "YapStreams.h" + + +static inline bool IsStreamTerm(Term t) { + return !IsVarTerm(t) && + (IsAtomTerm(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); + +# #define Yap_CheckStream(arg, kind, msg) \ Yap_CheckStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg) extern int Yap_CheckStream__(const char *, const char *, int, Term, int, @@ -45,33 +44,32 @@ extern int Yap_CheckStream__(const char *, const char *, int, Term, int, Yap_CheckTextStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg) extern int Yap_CheckTextStream__(const char *, const char *, int, Term, int, const char *); -#define Yap_CheckBinaryStream(arg, kind, msg) \ + +#define Yap_CheckBinaryStream(arg, kind, msg) \ Yap_CheckBinaryStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg) extern int Yap_CheckBinaryStream__(const char *, const char *, int, Term, int, - const char *); + const char *); -extern bool Yap_initStream(int sno, FILE *fd, const char *name, Term file_name, - encoding_t encoding, stream_flags_t flags, - Atom open_mode); +static inline StreamDesc *Yap_GetStreamHandle( Term t) { + int sno = Yap_CheckStream(t, 0, "stream search"); + if (sno < 0) + return NULL; + return GLOBAL_Stream + sno; +} + + +#include "VFS.h" + +/* + * This file defines main data-structure for stream management, + * + */ + +extern size_t Yap_page_size; #if HAVE_SOCKET extern int Yap_sockets_io; -/****************** defines for sockets *********************************/ - -typedef enum { /* in YAP, sockets may be in one of 4 possible status */ - new_socket, - server_socket, - client_socket, - server_session_socket, - closed_socket -} socket_info; - -typedef enum { /* we accept two domains for the moment, IPV6 may follow */ - af_inet, /* IPV4 */ - af_unix /* or AF_FILE */ -} socket_domain; - extern Term Yap_InitSocketStream(int, socket_info, socket_domain); extern int Yap_CheckSocketStream(Term, const char *); extern socket_domain Yap_GetSocketDomain(int); @@ -83,78 +81,6 @@ Int Yap_CloseSocket(int, socket_info, socket_domain); #endif /* USE_SOCKET */ -/************ SWI compatible support for unicode representations ************/ -typedef struct yap_io_position { - int64_t byteno; /* byte-position in file */ - int64_t charno; /* character position in file */ - long int lineno; /* lineno in file */ - long int linepos; /* position in line */ - intptr_t reserved[2]; /* future extensions */ -} yapIOPOS; - -#ifndef _PL_STREAM_H -typedef struct { - Atom file; /* current source file */ - yapIOPOS position; /* Line, line pos, char and byte */ -} yapSourceLocation; -#endif - -#define RD_MAGIC 0xefebe128 - -typedef struct vlist_struct_t { - struct VARSTRUCT *ve; - struct vlist_struct_t *next; -} vlist_t; - -typedef struct qq_struct_t { - unsigned char *text; - yapIOPOS start, mid, end; - vlist_t *vlist; - struct qq_struct_t *next; -} qq_t; - -typedef struct read_data_t { - unsigned char *here; /* current character */ - unsigned char *base; /* base of clause */ - unsigned char *end; /* end of the clause */ - unsigned char *token_start; /* start of most recent read token */ - - int magic; /* RD_MAGIC */ - struct stream_desc *stream; - FILE *f; /* file. of known */ - Term position; /* Line, line pos, char and byte */ - void *posp; /* position pointer */ - size_t posi; /* position number */ - - Term subtpos; /* Report Subterm positions */ - bool cycles; /* Re-establish cycles */ - yapSourceLocation start_of_term; /* Position of start of term */ - struct mod_entry *module; /* Current source module */ - unsigned int flags; /* Module syntax flags */ - int styleCheck; /* style-checking mask */ - bool backquoted_string; /* Read `hello` as string */ - - int *char_conversion_table; /* active conversion table */ - - Atom on_error; /* Handling of syntax errors */ - int has_exception; /* exception is raised */ - - Term exception; /* raised exception */ - Term variables; /* report variables */ - Term singles; /* Report singleton variables */ - Term varnames; /* Report variables+names */ - int strictness; /* Strictness level */ - -#ifdef O_QUASIQUOTATIONS - Term quasi_quotations; /* User option quasi_quotations(QQ) */ - Term qq; /* Quasi quoted list */ - Term qq_tail; /* Tail of the quoted stuff */ -#endif - - Term comments; /* Report comments */ - -} read_data, *ReadData; - Term Yap_read_term(int inp_stream, Term opts, int nargs); Term Yap_Parse(UInt prio, encoding_t enc, Term cmod); @@ -162,118 +88,6 @@ void init_read_data(ReadData _PL_rd, struct stream_desc *s); typedef int (*GetsFunc)(int, UInt, char *); -#if HAVE_SYS_TYPES_H -#include -#endif -#if HAVE_SYS_SOCKET_H -#include -#endif - -#if __APPLE__ -#include "fmemopen.h" -#define HAVE_FMEMOPEN 1 -#define HAVE_OPEN_MEMSTREAM 1 -FILE *open_memstream(char **buf, size_t *len); -#endif - -#if __ANDROID__ -#undef HAVE_FMEMOPEN -#undef HAVE_OPEN_MEMSTREAM -#endif - -#if HAVE_FMEMOPEN -#define MAY_READ 1 -#endif - -#if HAVE_OPEN_MEMSTREAM -#define MAY_READ 1 -#define MAY_WRITE 1 -#endif - -#if _WIN32 -#undef MAY_WRITE -#undef MAY_READ -#endif - -typedef struct mem_desc { - char *buf; /* where the file is being read from/written to */ - int src; /* where the space comes from, 0 code space, 1 malloc */ - Int max_size; /* maximum buffer size (may be changed dynamically) */ - UInt pos; /* cursor */ - volatile void *error_handler; -} memHandle; - -typedef struct stream_desc { - Atom name; - Term user_name; - FILE *file; - // useful in memory streams - char *nbuf; - size_t nsize; - union { - struct { -#define PLGETC_BUF_SIZE 4096 - unsigned char *buf, *ptr; - int left; - } file; - memHandle mem_string; - struct { - int fd; - } pipe; -#if HAVE_SOCKET - struct { - socket_domain domain; - socket_info flags; - int fd; - } socket; -#endif - struct { - const unsigned char *buf, *ptr; - } irl; - } u; - Int charcount, linecount, linepos; - stream_flags_t status; -#if defined(YAPOR) || defined(THREADS) - lockvar streamlock; /* protect stream access */ -#endif - int (*stream_putc)( - int, int); /** function the stream uses for writing a single octet */ - int (*stream_wputc)( - int, wchar_t); /** function the stream uses for writing a character */ - int (*stream_getc)(int); /** function the stream uses for reading an octet. */ - int (*stream_wgetc)( - int); /** function the stream uses for reading a character. */ - - int (*stream_wgetc_for_read)( - int); /* function the stream uses for parser. It may be different - from above if the ISO character conversion is on */ - encoding_t encoding; /** current encoding for stream */ -} StreamDesc; - -static inline bool IsStreamTerm(Term t) { - return !IsVarTerm(t) && - (IsAtomTerm(t) || - (IsApplTerm(t) && (FunctorOfTerm(t) == FunctorStream))); -} - -static inline StreamDesc *Yap_GetStreamHandle(Term t) { - int sno = Yap_CheckStream(t, 0, "stream search"); - if (sno < 0) - return NULL; - return GLOBAL_Stream + sno; -} - -#define YAP_ERROR NIL - -#define MaxStreams 64 - -#define EXPAND_FILENAME 0x000080 - -#define StdInStream 0 -#define StdOutStream 1 -#define StdErrStream 2 - -#define ALIASES_BLOCK_SIZE 8 void Yap_InitStdStreams(void); Term Yap_StreamPosition(int); @@ -332,9 +146,10 @@ void Yap_socketStream(StreamDesc *s); void Yap_ReadlineFlush(int sno); Int Yap_ReadlinePeekChar(int sno); int Yap_ReadlineForSIGINT(void); -bool Yap_ReadlinePrompt(StreamDesc *s); +bool Yap_DoPrompt(StreamDesc *s); Int Yap_peek(int sno); +int Yap_MemPeekc(int sno); Term Yap_syntax_error(TokEntry *tokptr, int sno); @@ -345,6 +160,7 @@ int post_process_weof(StreamDesc *); bool is_same_tty(FILE *f1, FILE *f2); + int ISOWGetc(int sno); int GetUTF8(int sno); Term read_line(int sno); @@ -401,6 +217,7 @@ inline static Term StreamName(int i) { return (GLOBAL_Stream[i].user_name); } inline static Atom StreamFullName(int i) { return (GLOBAL_Stream[i].name); } + inline static void console_count_output_char(int ch, StreamDesc *s) { CACHE_REGS if (ch == '\n') { @@ -428,6 +245,8 @@ inline static void console_count_output_char(int ch, StreamDesc *s) { } } + + inline static Term StreamPosition(int sno) { CACHE_REGS Term sargs[5]; @@ -465,4 +284,8 @@ static inline void freeBuffer(const void *ptr) { free((void *)ptr); } +/** VFS handling */ + +VFS_t *Yap_InitAssetManager(void); + #endif diff --git a/os/readline.c b/os/readline.c index dd194d252..d1236fd19 100644 --- a/os/readline.c +++ b/os/readline.c @@ -251,16 +251,6 @@ void Yap_ReadlineFlush(int sno) { } } -bool Yap_ReadlinePrompt(StreamDesc *s) { - if (s->status & Tty_Stream_f) { - s->stream_getc = ReadlineGetc; - if (GLOBAL_Stream[0].status & Tty_Stream_f && - s->name == GLOBAL_Stream[0].name) - return true; - } - return false; -} - bool Yap_ReadlineOps(StreamDesc *s) { if (s->status & Tty_Stream_f) { if (GLOBAL_Stream[0].status & (Input_Stream_f|Tty_Stream_f) && @@ -295,8 +285,11 @@ bool Yap_InitReadline(Term enable) { // don't call readline within emacs if (!(GLOBAL_Stream[StdInStream].status & Tty_Stream_f) || getenv("INSIDE_EMACS") || - enable != TermTrue) - return false; + enable != TermTrue) { + if (GLOBAL_Flags) + setBooleanGlobalPrologFlag(READLINE_FLAG, false); + return false; + } GLOBAL_Stream[StdInStream].u.irl.buf = NULL; GLOBAL_Stream[StdInStream].u.irl.ptr = NULL; GLOBAL_Stream[StdInStream].status |= Readline_Stream_f; @@ -322,6 +315,8 @@ bool Yap_InitReadline(Term enable) { #endif // does not work // rl_prep_terminal(1); + if (GLOBAL_Flags) + setBooleanGlobalPrologFlag(READLINE_FLAG, true); return Yap_ReadlineOps(GLOBAL_Stream + StdInStream); } @@ -333,8 +328,9 @@ static bool getLine(int inp) { /* window of vulnerability opened */ LOCAL_PrologMode |= ConsoleGetcMode; - if (LOCAL_newline) { // no output so far + if (Yap_DoPrompt(s)) { // no output so far myrl_line = (unsigned char *)readline(LOCAL_Prompt); + s->stream_getc = ReadlineGetc; } else { myrl_line = (unsigned char *)readline(NULL); } diff --git a/os/readterm.c b/os/readterm.c index 3eb87886b..cfe3f4fc9 100644 --- a/os/readterm.c +++ b/os/readterm.c @@ -904,7 +904,7 @@ static parser_state_t parse(REnv *re, FEnv *fe, int inp_stream) { * * @arg inp_stream: where we read from * @arg: opts, a list with options - * @arg: if call∫ed from read_term, arity + * @arg: if called from read_term, arity * called from read_clause, -arity * * @return the term or 0 in case of error. @@ -978,7 +978,7 @@ static Int static Int read_term( USES_REGS1) { /* '$read2'(+Flag,?Term,?Module,?Vars,-Pos,-Err,+Stream) */ int inp_stream; - Int out; + Term out; /* needs to change LOCAL_output_stream for write */ @@ -1089,7 +1089,7 @@ static Int read_clause2(USES_REGS1) { rc = Yap_read_term(LOCAL_c_input_stream, Deref(ARG2), -2); Term tf = Yap_GetFromSlot(h); Yap_RecoverSlots(1, h); - return rc && Yap_unify(tf, rc); + return rc && Yap_unify(tf, rc); } /** @@ -1116,7 +1116,7 @@ static Int read_clause2(USES_REGS1) { static Int read_clause( USES_REGS1) { /* '$read2'(+Flag,?Term,?Module,?Vars,-Pos,-Err,+Stream) */ int inp_stream; - Int out; + Term out; Term t3 = Deref(ARG3); yhandle_t h = Yap_InitSlot(ARG2); /* needs to change LOCAL_output_stream for write */ @@ -1124,6 +1124,16 @@ static Int read_clause( if (inp_stream < 0) return false; out = Yap_read_term(inp_stream, t3, -3); +#if COMMENTED + if (LOCAL_SourceFileLineno==707) { + char *s; size_t length; + + s= Yap_TermToString(out, &length, LOCAL_encoding, 0); + __android_log_print(ANDROID_LOG_INFO, "YAPDroid ", "at %d %s",LOCAL_SourceFileLineno, + s); + Yap_do_low_level_trace=1; + } +#endif UNLOCK(GLOBAL_Stream[inp_stream].streamlock); Term tf = Yap_GetFromSlot(h); Yap_RecoverSlots(1, h); diff --git a/os/sysbits.c b/os/sysbits.c index 06ab9ef42..3a6d9c5ae 100644 --- a/os/sysbits.c +++ b/os/sysbits.c @@ -34,6 +34,17 @@ static void FileError(yap_error_number type, Term where, const char *format, } } +/// Allocate a temporary buffer +static char *getFileNameBuffer(void) { + + return Yap_AllocAtomSpace( YAP_FILENAME_MAX ); +} + +static void freeFileNameBuffer(char *s) +{ + Yap_FreeCodeSpace(s); +} + static Int p_sh(USES_REGS1); static Int p_shell(USES_REGS1); static Int p_system(USES_REGS1); @@ -66,97 +77,16 @@ void Yap_WinError(char *yap_error) { #define is_valid_env_char(C) \ (((C) >= 'a' && (C) <= 'z') || ((C) >= 'A' && (C) <= 'Z') || (C) == '_') -#if __ANDROID__ -AAssetManager *Yap_assetManager; - -void *Yap_openAssetFile(const char *path) { - const char *p = path + 8; - AAsset *asset = AAssetManager_open(Yap_assetManager, p, AASSET_MODE_UNKNOWN); - return asset; -} - -bool Yap_isAsset(const char *path) { - if (Yap_assetManager == NULL) - return false; - return path[0] == '/' && path[1] == 'a' && path[2] == 's' && path[3] == 's' && - path[4] == 'e' && path[5] == 't' && path[6] == 's' && - (path[7] == '/' || path[7] == '\0'); -} - -bool Yap_AccessAsset(const char *name, int mode) { - AAssetManager *mgr = Yap_assetManager; - const char *bufp = name + 7; - - if (bufp[0] == '/') - bufp++; - if ((mode & W_OK) == W_OK) { - return false; - } - // directory works if file exists - AAssetDir *assetDir = AAssetManager_openDir(mgr, bufp); - if (assetDir) { - AAssetDir_close(assetDir); - return true; - } - return false; -} - -bool Yap_AssetIsFile(const char *name) { - AAssetManager *mgr = Yap_assetManager; - const char *bufp = name + 7; - if (bufp[0] == '/') - bufp++; - // check if file is a directory. - AAsset *asset = AAssetManager_open(mgr, bufp, AASSET_MODE_UNKNOWN); - if (!asset) - return false; - AAsset_close(asset); - return true; -} - -bool Yap_AssetIsDir(const char *name) { - AAssetManager *mgr = Yap_assetManager; - const char *bufp = name + 7; - if (bufp[0] == '/') - bufp++; - // check if file is a directory. - AAssetDir *assetDir = AAssetManager_openDir(mgr, bufp); - if (!assetDir) { - return false; - } - AAssetDir_close(assetDir); - AAsset *asset = AAssetManager_open(mgr, bufp, AASSET_MODE_UNKNOWN); - if (!asset) - return true; - AAsset_close(asset); - return false; -} - -int64_t Yap_AssetSize(const char *name) { - AAssetManager *mgr = Yap_assetManager; - const char *bufp = name + 7; - if (bufp[0] == '/') - bufp++; - AAsset *asset = AAssetManager_open(mgr, bufp, AASSET_MODE_UNKNOWN); - if (!asset) - return -1; - off64_t len = AAsset_getLength64(asset); - AAsset_close(asset); - return len; -} -#endif /// is_directory: verifies whether an expanded file name /// points at a readable directory static bool is_directory(const char *FileName) { -#ifdef __ANDROID__ - if (Yap_isAsset(FileName)) { - return Yap_AssetIsDir(FileName); + + VFS_t *vfs; + if ((vfs = vfs_owner( FileName ))) { + return vfs->isdir( vfs, FileName ); } - -#endif - #ifdef __WINDOWS__ DWORD dwAtts = GetFileAttributes(FileName); if (dwAtts == INVALID_FILE_ATTRIBUTES) @@ -178,6 +108,11 @@ static bool is_directory(const char *FileName) { } bool Yap_Exists(const char *f) { + VFS_t *vfs; + + if ((vfs = vfs_owner( f ))) { + return vfs->exists( vfs, f ); + } #if _WIN32 if (_access(f, 0) == 0) return true; @@ -333,9 +268,10 @@ static const char *PlExpandVars(const char *source, const char *root, "path too long"); return NULL; } - if (root) { + if (root && !Yap_IsAbsolutePath(source)) { strncpy(result, root, YAP_FILENAME_MAX); - strncat(result, "/", YAP_FILENAME_MAX); + if (root[strlen(root)-1] != '/') + strncat(result, "/", YAP_FILENAME_MAX); strncat(result, source, YAP_FILENAME_MAX); } else { strncpy(result, source, strlen(src) + 1); @@ -416,30 +352,10 @@ static bool ChDir(const char *path) { char qp[FILENAME_MAX + 1]; const char *qpath = Yap_AbsoluteFile(path, qp, true); -#ifdef __ANDROID__ - if (GLOBAL_AssetsWD) { - freeBuffer(GLOBAL_AssetsWD); - GLOBAL_AssetsWD = NULL; - } - if (Yap_isAsset(qpath)) { - AAssetManager *mgr = Yap_assetManager; - - const char *ptr = qpath + 8; - AAssetDir *d; - if (ptr[0] == '/') - ptr++; - d = AAssetManager_openDir(mgr, ptr); - if (d) { - GLOBAL_AssetsWD = malloc(strlen(qpath) + 1); - strcpy(GLOBAL_AssetsWD, qpath); - AAssetDir_close(d); - return true; +VFS_t *v; + if ((v = vfs_owner( path ))) { + return v->chdir(v, path); } - return false; - } else { - GLOBAL_AssetsWD = NULL; - } -#endif #if _WIN32 rc = true; if (qpath != NULL && qpath[0] && @@ -579,12 +495,12 @@ static Term /* Expand the string for the program to run. */ do_glob(const char *spec, bool glob_vs_wordexp) { CACHE_REGS - char u[YAP_FILENAME_MAX + 1]; - const char *espec = u; if (spec == NULL) { return TermNil; } #if _WIN32 + char u[YAP_FILENAME_MAX + 1]; + const char *espec = u; { WIN32_FIND_DATA find; HANDLE hFind; @@ -622,6 +538,8 @@ static Term return tf; } #elif HAVE_WORDEXP || HAVE_GLOB + char u[YAP_FILENAME_MAX + 1]; + const char *espec = u; strncpy(u, spec, sizeof(u)); /* Expand the string for the program to run. */ size_t pathcount; @@ -723,7 +641,7 @@ static Term return tf; #else // just use basic - return MkPairTerm(MkAtomTerm(Yap_LookupAtom(espec)), TermNil); + return MkPairTerm(MkAtomTerm(Yap_LookupAtom(spec)), TermNil); #endif } @@ -1143,7 +1061,21 @@ static Int libraries_directories(USES_REGS1) { } static Int system_library(USES_REGS1) { +#if __ANDROID__ + static Term dir = 0; + Term t; + if (IsVarTerm(t=Deref(ARG1))) { + if (dir == 0) + return false; + return Yap_unify(dir, ARG1); + } + if (!IsAtomTerm(t)) + return false; + dir = t; + return true; +#else return initSysPath(ARG1, MkVarTerm(), false, true); +#endif } static Int commons_library(USES_REGS1) { @@ -1212,11 +1144,6 @@ const char *Yap_getcwd(const char *cwd, size_t cwdlen) { return NULL; } return (char *)cwd; -#elif __ANDROID__ - if (GLOBAL_AssetsWD) { - return strncpy((char *)cwd, (const char *)GLOBAL_AssetsWD, cwdlen); - } - #endif return getcwd((char *)cwd, cwdlen); } @@ -1247,7 +1174,7 @@ static Int working_directory(USES_REGS1) { * * * @param isource the proper file - * @param idef the default name fo rthe file, ie, startup.yss + * @param idef the default name fothe file, ie, startup.yss * @param root the prefix * @param result the output * @param access verify whether the file has access permission @@ -1259,26 +1186,35 @@ static Int working_directory(USES_REGS1) { */ const char *Yap_findFile(const char *isource, const char *idef, const char *iroot, char *result, bool access, - YAP_file_type_t ftype, bool expand_root, bool in_lib) { - char save_buffer[YAP_FILENAME_MAX + 1]; +YAP_file_type_t ftype, bool expand_root, bool in_lib) { + + + + char *save_buffer = NULL; const char *root, *source = isource; int rc = FAIL_RESTORE; - int try - = 0; - - while (rc == FAIL_RESTORE) { - bool done = false; - // { CACHE_REGS __android_log_print(ANDROID_LOG_ERROR, __FUNCTION__, + int try = 0; + bool abspath = false; +//__android_log_print(ANDROID_LOG_ERROR, "YAPDroid " __FUNCTION__, // "try=%d %s %s", try, isource, iroot) ; } + while (rc == FAIL_RESTORE) { + // means we failed this iteration + bool done = false; + // { CACHE_REGS switch (try ++) { case 0: // path or file name is given; root = iroot; - if (!root && ftype == YAP_BOOT_PL) { - root = YAP_PL_SRCDIR; - } if (idef || isource) { source = (isource ? isource : idef); } + if (source) { + if (source[0] == '/') { + abspath = true; + } + } + if (!abspath && !root && ftype == YAP_BOOT_PL) { + root = YAP_PL_SRCDIR; + } break; case 1: // library directory is given in command line if (in_lib && ftype == YAP_SAVED_STATE) { @@ -1294,11 +1230,12 @@ const char *Yap_findFile(const char *isource, const char *idef, if (ftype == YAP_SAVED_STATE || ftype == YAP_OBJ) { root = getenv("YAPLIBDIR"); } else if (ftype == YAP_BOOT_PL) { - root = getenv("YAPSHAREDIR"); + root = getenv("YAPSHAREDIR" "/pl"); if (root == NULL) { continue; } else { - strncpy(save_buffer, root, YAP_FILENAME_MAX); + save_buffer = getFileNameBuffer(); + strncpy(save_buffer, root, YAP_FILENAME_MAX); strncat(save_buffer, "/pl", YAP_FILENAME_MAX); } } @@ -1343,12 +1280,22 @@ const char *Yap_findFile(const char *isource, const char *idef, if (pt) { if (ftype == YAP_BOOT_PL) { +#if __ANDROID__ + root = "../../../files/Yap/pl"; +#else root = "../../share/Yap/pl"; + #endif } else { root = (ftype == YAP_SAVED_STATE || ftype == YAP_OBJ ? "../../lib/Yap" : "../../share/Yap"); } + if (root == iroot) { + done = true; + continue; + } + if (!save_buffer) + save_buffer = getFileNameBuffer(); if (Yap_findFile(source, NULL, root, save_buffer, access, ftype, expand_root, in_lib)) root = save_buffer; @@ -1366,6 +1313,9 @@ const char *Yap_findFile(const char *isource, const char *idef, root = NULL; break; default: + if (save_buffer) + freeFileNameBuffer(save_buffer); + return false; } @@ -1375,11 +1325,15 @@ const char *Yap_findFile(const char *isource, const char *idef, // "root= %s %s ", root, source) ; } const char *work = PlExpandVars(source, root, result); - // expand names in case you have + if (save_buffer) + freeFileNameBuffer(save_buffer); + + // expand names in case you have // to add a prefix if (!access || Yap_Exists(work)) { return work; // done - } + } else if (abspath) + return NULL; } return NULL; } @@ -1749,7 +1703,7 @@ static Int p_getenv(USES_REGS1) { static Int p_putenv(USES_REGS1) { #if HAVE_PUTENV Term t1 = Deref(ARG1), t2 = Deref(ARG2); - char *s, *s2, *p0, *p; + char *s = "", *s2 = "", *p0, *p; if (IsVarTerm(t1)) { Yap_Error(INSTANTIATION_ERROR, t1, "first arg to putenv/2"); diff --git a/os/yapio.h b/os/yapio.h index da408a24d..de1d2cf5b 100644 --- a/os/yapio.h +++ b/os/yapio.h @@ -89,23 +89,6 @@ Term Yap_WStringToList(wchar_t *); Term Yap_WStringToListOfAtoms(wchar_t *); Atom Yap_LookupWideAtom(const wchar_t *); -#define Quote_illegal_f 0x01 -#define Ignore_ops_f 0x02 -#define Handle_vars_f 0x04 -#define Use_portray_f 0x08 -#define To_heap_f 0x10 -#define Unfold_cyclics_f 0x20 -#define Use_SWI_Stream_f 0x40 -#define BackQuote_String_f 0x80 -#define AttVar_None_f 0x100 -#define AttVar_Dots_f 0x200 -#define AttVar_Portray_f 0x400 -#define Blob_Portray_f 0x800 -#define No_Escapes_f 0x1000 -#define No_Brace_Terms_f 0x2000 -#define Fullstop_f 0x4000 -#define New_Line_f 0x8000 - /* grow.c */ int Yap_growheap_in_parser(tr_fr_ptr *, TokEntry **, VarEntry **); int Yap_growstack_in_parser(tr_fr_ptr *, TokEntry **, VarEntry **); @@ -116,9 +99,8 @@ Atom Yap_TemporaryFile(const char *prefix, int *fd); const char *Yap_AbsoluteFile(const char *spec, char *obuf, bool expand); typedef enum mem_buf_source { - MEM_BUF_CODE = 1, - MEM_BUF_MALLOC = 2, - MEM_BUF_USER = 4 + MEM_BUF_MALLOC = 1, + MEM_BUF_USER = 2 } memBufSource; char *Yap_MemStreamBuf(int sno); @@ -127,7 +109,10 @@ extern X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp, int prio, Term *bindings_p); extern Term Yap_StringToNumberTerm(char *s, encoding_t *encp); int Yap_FormatFloat(Float f, char **s, size_t sz); -int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp, memBufSource src); +int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp, + memBufSource src); +bool Yap_set_stream_to_buf(struct stream_desc *st, const char *buf, + size_t nchars); int Yap_open_buf_write_stream(encoding_t enc, memBufSource src); Term Yap_ReadFromAtom(Atom a, Term opts); FILE *Yap_GetInputStream(Term t, const char *m);