diff --git a/include/VFS.h b/include/VFS.h new file mode 100644 index 000000000..4ffa601e6 --- /dev/null +++ b/include/VFS.h @@ -0,0 +1,133 @@ +/************************************************************************* + * * + * YAP Prolog * + * * + * Yap Prolog was developed at NCCUP - Universidade do Porto * + * * + * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * + * * + ************************************************************************** + * * + * File: VFS.h * + * Last rev: 5/2/88 * + * mods: * + * comments: Virtual File System Access for YAP * + * * + *************************************************************************/ +#ifndef VFS_H +#define VFS_H 1 +#include +#if HAVE_SYS_STAT_H +#include +#endif + +#ifdef _WIN32 +#include +typedef uintptr_t uid_t; +typedef uintptr_t gid_t; +#endif + +typedef struct { + dev_t st_dev; /* ID of device containing file */ + mode_t st_mode; /* Mode of file (see below) */ + uid_t st_uid; /* User ID of the file */ + gid_t st_gid; /* Group ID of the file */ + struct timespec st_atimespec; /* time of last access */ + struct timespec st_mtimespec; /* time of last data modification */ + struct timespec st_ctimespec; /* time of last status change */ + struct timespec st_birthtimespec; /* time of file creation(birth) */ +#if __ANDROID__ + off64_t st_size; /* file size, in bytes */ +#else + off_t st_size; /* file size, in bytes */ +#endif +} vfs_stat; + +typedef enum vfs_flags { + VFS_CAN_WRITE = 0x1, /// we can write to files in this space + VFS_CAN_EXEC = 0x2, /// we can execute files in this space + VFS_CAN_SEEK = 0x4, /// we can seek within files in this space + VFS_HAS_PREFIX = 0x8, /// has a prefix that identifies a file in this space + VFS_HAS_SUFFIX = 0x10, /// has a suffix that describes the file. + VFS_HAS_FUNCTION = 0x10, /// has a suffix that describes the file. +} vfs_flags_t; + +typedef union { + struct vfs *vfs; + uintptr_t cell; + size_t sz; + void *pt; + uintptr_t scalar; +#if __ANDROID__ + AAssetManager *mgr; + AAsset *asset; +#endif +} cell_size_t; + +typedef struct vfs { + const char *name; /// A text that explains the file system + uintptr_t vflags; /// the main flags describing the operation of the Fs. + /// a way to identify a file in this VFS: two special cases, prefix and suffix + const char *prefix; + const char *suffix; + bool (*id)(struct vfs *me, const char *s); + /** operations */ + bool (*open)(struct vfs *me, struct stream_desc *st, const char *s, + const char *io_mode); + ; /// open an object + /// in this space, usual w,r,a,b flags plus B (store in a buffer) + bool (*close)(struct stream_desc *stream); /// close the object + int (*get_char)(struct stream_desc *stream); /// get an octet to the stream + int (*putc)(int ch, + struct stream_desc *stream); /// output an octet to the stream + int64_t (*seek)(struct stream_desc *stream, int64_t offset, + int whence); /// jump around the stream + void *(*opendir)(struct vfs *me, + const char *s); /// open a directory object, if one exists + const char *(*nextdir)( + void *d); /// walk to the next entry in a directory object + void (*closedir)(void *d); + ; /// close access a directory object + bool (*stat)(struct vfs *me, const char *s, + vfs_stat *); /// obtain size, age, permissions of a file. + bool (*isdir)(struct vfs *me, const char *s); /// verify whether is directory. + bool (*exists)(struct vfs *me, + const char *s); /// verify whether a file exists. + bool (*chdir)(struct vfs *me, + const char *s); /// set working directory (may be virtual). + encoding_t enc; /// how the file is encoded. + YAP_Term (*parsers)(void *stream); // a set of parsers that can read the + // stream and generate a YAP_Term + int (*writers)(int ch, void *stream); + ; /// convert a YAP_Term into this space + const char *virtual_cwd; + /** VFS dep + endent area */ + cell_size_t priv[4]; + struct vfs *next; +} VFS_t; + +extern VFS_t *GLOBAL_VFS; + +static inline VFS_t *vfs_owner(const char *fname) { + return NULL; + VFS_t *me = GLOBAL_VFS; + int d; + size_t sz0 = strlen(fname); + + while (me) { + if (me->vflags & VFS_HAS_PREFIX && strstr(fname, me->prefix)) + return me; + size_t sz = strlen(me->suffix); + if (me->vflags & VFS_HAS_SUFFIX && (d = (sz0 - sz)) >= 0 && + strcmp(fname + d, me->suffix) == 0) + return me; + if (me->vflags & VFS_HAS_FUNCTION && (me->id(me, fname))) { + return me; + } + me = me->next; + } + return NULL; +} + +#endif diff --git a/include/YAPStreams.h b/include/YAPStreams.h new file mode 100644 index 000000000..9f792a278 --- /dev/null +++ b/include/YAPStreams.h @@ -0,0 +1,248 @@ +/************************************************************************** + * * + * File: iopreds.h * + * Last rev: 5/2/88 * + * mods: * + * comments: Input/Output C implemented predicates * + * * + *************************************************************************/ +#ifdef SCCS +static char SccsId[] = "%W% %G%"; +#endif + +#ifndef YAPSTREAMS_H +#define YAPSTREAMS_H 1 + +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_SOCKET_H +#include +#endif + +#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 + +#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, + * + */ + +#if defined(_MSC_VER) || defined(__MINGW32__) + +#include + +#endif + +#include + +/************ 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 { + YAP_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 */ + YAP_Term position; /* Line, line pos, char and byte */ + void *posp; /* position pointer */ + size_t posi; /* position number */ + + YAP_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 */ + + YAP_Atom on_error; /* Handling of syntax errors */ + int has_exception; /* exception is raised */ + + YAP_Term exception; /* raised exception */ + YAP_Term variables; /* report variables */ + YAP_Term singles; /* Report singleton variables */ + YAP_Term varnames; /* Report variables+names */ + int strictness; /* Strictness level */ + +#ifdef O_QUASIQUOTATIONS + YAP_Term quasi_quotations; /* User option quasi_quotations(QQ) */ + YAP_Term qq; /* Quasi quoted list */ + YAP_Term qq_tail; /* Tail of the quoted stuff */ +#endif + + YAP_Term comments; /* Report comments */ + +} read_data, *ReadData; + +#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 */ + size_t max_size; /* maximum buffer size (may be changed dynamically) */ + size_t + + pos; /* cursor */ + volatile void *error_handler; +} memHandle; + +#if HAVE_SOCKET +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; + +#endif + +#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_f 0x2000 +#define Fullstop_f 0x4000 +#define New_Line_f 0x8000 + +typedef struct stream_desc { + YAP_Atom name; + YAP_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; + + int64_t 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. */ + struct vfs *vfs; /** stream belongs to a space */ + void *vfs_handle; /** direct handle to stream in that space. */ + 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; + +#endif diff --git a/include/YapInterface.h b/include/YapInterface.h index e24d9986e..86fa96f4c 100755 --- a/include/YapInterface.h +++ b/include/YapInterface.h @@ -84,25 +84,38 @@ __BEGIN_DECLS #ifndef Int_FORMAT -#if HAVE_INTTYPES_H - -#include - +#ifdef PRIdPTR #define Int_FORMAT "%" PRIdPTR -#define Int_ANYFORMAT "%" PRIiPTR -#define UInt_FORMAT "%" PRIuPTR - #elif _WIN64 #define Int_FORMAT "%I64d" -#define Int_ANYFORMAT "%I64i" -#define UInt_FORMAT "%I64u" +#elif _WIN32 +#define Int_FORMAT "%I32d" #else #define Int_FORMAT "%ld" +#endif + +#ifdef PRIiPTR +#define Int_ANYFORMAT "%" PRIiPTR +#elif _WIN64 +#define Int_ANYFORMAT "%I64i" +#elif _WIN32 +#define Int_ANYFORMAT "%I32i" +#else #define Int_ANYFORMAT "%li" +#endif + +#ifdef PRIuPTR +#define UInt_FORMAT "%" PRIuPTR +#elif _WIN64 +#define UInt_FORMAT "%I64ud" +#elif _WIN32 +#define UInt_FORMAT "%I32ud" +#else #define UInt_FORMAT "%lu" #endif -#endif /* portable form of formatted output for Prolog terms */ +/* portable form of formatted output for Prolog terms */ +#endif /** @@ -1920,10 +1933,11 @@ extern X_API int YAP_AssertTuples(YAP_PredEntryPtr pred, const YAP_Term *ts, size_t offset, size_t sz); /* int YAP_Init(YAP_init_args *) */ -extern X_API YAP_Int YAP_Init(YAP_init_args *); +extern X_API YAP_file_type_t YAP_Init(YAP_init_args *); /* int YAP_FastInit(const char *) */ -extern X_API YAP_Int YAP_FastInit(char saved_state[]); +extern X_API YAP_file_type_t YAP_FastInit(char saved_state[], int argc, + char *argv[]); #ifndef _PL_STREAM_H // if we don't know what a stream is, just don't assume nothing about the @@ -2181,6 +2195,8 @@ extern X_API YAP_CELL *YAP_HeapStoreOpaqueTerm(YAP_Term t); extern X_API int YAP_Argv(char ***); +extern X_API bool YAP_DelayInit(YAP_ModInit_t f, const char s[]); + extern X_API YAP_tag_t YAP_TagOfTerm(YAP_Term); extern X_API size_t YAP_ExportTerm(YAP_Term, char *, size_t); @@ -2213,7 +2229,7 @@ extern X_API int YAP_RequiresExtraStack(size_t); * -P only in development versions */ extern X_API YAP_file_type_t YAP_parse_yap_arguments(int argc, char *argv[], - YAP_init_args *iap); + YAP_init_args *iap); extern X_API YAP_Int YAP_AtomToInt(YAP_Atom At); diff --git a/os/stream.h b/os/stream.h new file mode 100644 index 000000000..8d7ca1494 --- /dev/null +++ b/os/stream.h @@ -0,0 +1,87 @@ +/************************************************************************** + * * + * File: stream.h * + * Last rev: 5/2/88 * + * mods: * + * comments: Stream core routunes * + * * + *************************************************************************/ +#ifdef SCCS +static char SccsId[] = "%W% %G%"; +#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. */ + struct vfs *vfs; /** stream belongs to a space */ + void *vfs_handle; /** direct handle to stream in that space. */ + 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; diff --git a/os/streams.c b/os/streams.c index a1408adc2..775511f62 100644 --- a/os/streams.c +++ b/os/streams.c @@ -29,11 +29,11 @@ static char SccsId[] = "%W% %G%"; /* for O_BINARY and O_TEXT in WIN32 */ #include #endif -#include "Yatom.h" #include "YapHeap.h" -#include "yapio.h" -#include "eval.h" #include "YapText.h" +#include "Yatom.h" +#include "eval.h" +#include "yapio.h" #include #if HAVE_STDARG_H #include @@ -222,7 +222,7 @@ static Int has_bom(int sno, Term t2 USES_REGS) { /* '$set_output'(+Stream,-ErrorMessage) */ bool rc = GLOBAL_Stream[sno].status & HAS_BOM_f; if (!IsVarTerm(t2) && !booleanFlag(t2)) { - // Yap_Error( DOMAIN_ERROR_BOOLEAN, t2, " stream_property/2"); + // Yap_Error( DOMAIN_ERROR_BOOLEAN, t2, " stream_property/2"); return false; } if (rc) { @@ -247,20 +247,20 @@ has_reposition(int sno, } } -char *Yap_guessFileName(FILE* file, int sno, char *nameb, size_t max) { - if (!nameb) { - nameb = malloc(max(256, max)); - } - if (!file) { - strcpy(nameb, "memory buffer"); - return nameb; - } - int f = fileno(file); - if (f < 0) { - strcpy(nameb, "???"); - return nameb; - } - +char *Yap_guessFileName(FILE *file, int sno, char *nameb, size_t max) { + if (!nameb) { + nameb = malloc(max(256, max)); + } + if (!file) { + strcpy(nameb, "memory buffer"); + return nameb; + } + int f = fileno(file); + if (f < 0) { + strcpy(nameb, "???"); + return nameb; + } + #if __linux__ char path[256]; if (snprintf(path, 255, "/proc/self/fd/%d", f) && readlink(path, nameb, max)) @@ -270,14 +270,14 @@ char *Yap_guessFileName(FILE* file, int sno, char *nameb, size_t max) { return nameb; } #else - TCHAR path[MAX_PATH+1]; + TCHAR path[MAX_PATH + 1]; if (!GetFullPathName(path, MAX_PATH, path, NULL)) - return NULL; + return NULL; else { int i; - char *ptr = nameb; + unsigned char *ptr = nameb; for (i = 0; i < strlen(path); i++) - ptr += put_utf8(ptr, path[i]); + ptr += put_utf8(ptr, path[i]); *ptr = '\0'; return nameb; } @@ -472,8 +472,8 @@ eof_action(int sno, } #define STREAM_PROPERTY_DEFS() \ - PAR("alias", filler, STREAM_PROPERTY_ALIAS), \ - PAR("bom", filler, STREAM_PROPERTY_BOM), \ + PAR("alias", filler, STREAM_PROPERTY_ALIAS) \ + , PAR("bom", filler, STREAM_PROPERTY_BOM), \ PAR("close_on_abort", filler, STREAM_PROPERTY_CLOSE_ON_ABORT), \ PAR("encoding", filler, STREAM_PROPERTY_ENCODING), \ PAR("end_of_stream", filler, STREAM_PROPERTY_END_OF_STREAM), \ @@ -639,8 +639,7 @@ static Int cont_stream_property(USES_REGS1) { /* current_stream */ if (IsAtomTerm(args[STREAM_PROPERTY_ALIAS].tvalue)) { // one solution only i = Yap_CheckAlias(AtomOfTerm(args[STREAM_PROPERTY_ALIAS].tvalue)); - free(args) - UNLOCK(GLOBAL_Stream[i].streamlock); + free(args) UNLOCK(GLOBAL_Stream[i].streamlock); if (i < 0 || !Yap_unify(ARG1, Yap_MkStream(i))) { cut_fail(); } @@ -649,7 +648,7 @@ static Int cont_stream_property(USES_REGS1) { /* current_stream */ LOCK(GLOBAL_Stream[i].streamlock); rc = do_stream_property(i, args PASS_REGS); UNLOCK(GLOBAL_Stream[i].streamlock); - if (IsVarTerm(t1)) { + if (IsVarTerm(t1)) { if (rc) rc = Yap_unify(ARG1, Yap_MkStream(i)); if (p == STREAM_PROPERTY_END) { @@ -671,7 +670,7 @@ static Int cont_stream_property(USES_REGS1) { /* current_stream */ // done det = (p == STREAM_PROPERTY_END); } - free( args ); + free(args); if (rc) { if (det) cut_succeed(); @@ -722,11 +721,11 @@ static Int stream_property(USES_REGS1) { /* Init current_stream */ } if (do_stream_property(i, args PASS_REGS)) { UNLOCK(GLOBAL_Stream[i].streamlock); - free( args ); + free(args); cut_succeed(); } else { UNLOCK(GLOBAL_Stream[i].streamlock); - free( args ); + free(args); cut_fail(); } } else { @@ -735,8 +734,8 @@ static Int stream_property(USES_REGS1) { /* Init current_stream */ } #define SET_STREAM_DEFS() \ - PAR("alias", isatom, SET_STREAM_ALIAS), \ - PAR("buffer", booleanFlag, SET_STREAM_BUFFER), \ + PAR("alias", isatom, SET_STREAM_ALIAS) \ + , PAR("buffer", booleanFlag, SET_STREAM_BUFFER), \ PAR("buffer_size", nat, SET_STREAM_BUFFER_SIZE), \ PAR("close_on_abort", booleanFlag, SET_STREAM_CLOSE_ON_ABORT), \ PAR("encoding", isatom, SET_STREAM_ENCODING), \ @@ -894,7 +893,7 @@ void Yap_CloseStreams(int loud) { for (sno = 3; sno < MaxStreams; ++sno) { if (GLOBAL_Stream[sno].status & Free_Stream_f) continue; - CloseStream( sno ); + CloseStream(sno); } } @@ -1019,7 +1018,7 @@ static Int set_output(USES_REGS1) { /* '$show_stream_position'(+Stream,Pos) */ static Int p_user_file_name(USES_REGS1) { Term tout; int sno = - Yap_CheckStream(ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, + Yap_CheckStream(ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, "user_file_name/2"); if (sno < 0) return (FALSE); @@ -1405,7 +1404,7 @@ FILE *Yap_FileDescriptorFromStream(Term t) { void Yap_InitBackIO ( - + void) { Yap_InitCPredBack("stream_property", 2, 2, stream_property, diff --git a/os/sysbits.c b/os/sysbits.c index 06ab9ef42..5ea175596 100644 --- a/os/sysbits.c +++ b/os/sysbits.c @@ -34,6 +34,14 @@ 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); @@ -51,7 +59,6 @@ static const char *expandVars(const char *spec, char *u); void exit(int); - #ifdef _WIN32 void Yap_WinError(char *yap_error) { char msg[256]; @@ -66,97 +73,14 @@ 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 +102,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 +262,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 +346,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; + VFS_t *v; + if ((v = vfs_owner(path))) { + return v->chdir(v, path); } - 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; - } - return false; - } else { - GLOBAL_AssetsWD = NULL; - } -#endif #if _WIN32 rc = true; if (qpath != NULL && qpath[0] && @@ -449,7 +359,8 @@ static bool ChDir(const char *path) { #else rc = (chdir(qpath) == 0); #endif - if (qpath != qp && qpath != LOCAL_FileNameBuf && qpath != LOCAL_FileNameBuf2) + if (qpath != qp && qpath != path && qpath != LOCAL_FileNameBuf && + qpath != LOCAL_FileNameBuf2) free((char *)qpath); return rc; } @@ -579,12 +490,11 @@ 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]; { WIN32_FIND_DATA find; HANDLE hFind; @@ -622,6 +532,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 +635,7 @@ static Term return tf; #else // just use basic - return MkPairTerm(MkAtomTerm(Yap_LookupAtom(espec)), TermNil); + return MkPairTerm(MkAtomTerm(Yap_LookupAtom(spec)), TermNil); #endif } @@ -809,15 +721,13 @@ static Term do_expand_file_name(Term t1, Term opts USES_REGS) { return TermNil; } #if _WIN32 - { - char *rc; - char cmd2[YAP_FILENAME_MAX + 1]; + char *rc; + char cmd2[YAP_FILENAME_MAX + 1]; - if ((rc = unix2win(spec, cmd2, YAP_FILENAME_MAX)) == NULL) { - return false; - } - spec = rc; + if ((rc = unix2win(spec, cmd2, YAP_FILENAME_MAX)) == NULL) { + return false; } + spec = rc; #endif args = Yap_ArgListToVector(opts, expand_filename_defs, EXPAND_FILENAME_END); @@ -1143,7 +1053,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 +1136,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 +1166,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 @@ -1260,25 +1179,33 @@ 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]; + + char *save_buffer = NULL; const char *root, *source = isource; int rc = FAIL_RESTORE; 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 __android_log_print(ANDROID_LOG_ERROR, __FUNCTION__, - // "try=%d %s %s", try, isource, iroot) ; } + // { 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,10 +1221,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 { + save_buffer = getFileNameBuffer(); strncpy(save_buffer, root, YAP_FILENAME_MAX); strncat(save_buffer, "/pl", YAP_FILENAME_MAX); } @@ -1343,12 +1272,22 @@ const char *Yap_findFile(const char *isource, const char *idef, if (pt) { if (ftype == YAP_BOOT_PL) { - root = "../../share/Yap/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 +1305,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 +1317,15 @@ const char *Yap_findFile(const char *isource, const char *idef, // "root= %s %s ", root, source) ; } const char *work = PlExpandVars(source, root, result); + 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 +1695,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..eb295cf57 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,31 +99,33 @@ 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); -extern X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp, +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_write_stream(encoding_t enc, memBufSource src); -Term Yap_ReadFromAtom(Atom a, Term opts); -FILE *Yap_GetInputStream(Term t, const char *m); -FILE *Yap_GetOutputStream(Term t, const char *m); -char *Yap_guessFileName(FILE *f, int sno, char *nameb, size_t max); -void Yap_plwrite(Term t, struct stream_desc *mywrite, int max_depth, int flags, +extern Term Yap_StringToNumberTerm(const char *s, encoding_t *encp); +extern int Yap_FormatFloat(Float f, char **s, size_t sz); +extern int Yap_open_buf_read_stream(const char *buf, size_t nchars, encoding_t *encp, + memBufSource src); +extern bool Yap_set_stream_to_buf(struct stream_desc *st, const char *buf, + size_t nchars); +extern int Yap_open_buf_write_stream(encoding_t enc, memBufSource src); +extern Term Yap_AtomToTerm(Atom a, Term opts); +extern FILE *Yap_GetInputStream(Term t, const char *m); +extern FILE *Yap_GetOutputStream(Term t, const char *m); +extern char *Yap_guessFileName(FILE *f, int sno, char *nameb, size_t max); +extern void Yap_plwrite(Term t, struct stream_desc *mywrite, int max_depth, int flags, int priority); -int Yap_CheckSocketStream(Term stream, const char *error); -void Yap_init_socks(char *host, long interface_port); +extern int Yap_CheckSocketStream(Term stream, const char *error); +extern void Yap_init_socks(char *host, long interface_port); -uint64_t HashFunction(const unsigned char *); -uint64_t WideHashFunction(wchar_t *); +extern uint64_t HashFunction(const unsigned char *); +extern uint64_t WideHashFunction(wchar_t *); INLINE_ONLY inline EXTERN Term MkCharTerm(Int c); @@ -161,6 +146,7 @@ INLINE_ONLY inline EXTERN Term MkCharTerm(Int c) { } /// UT when yap started -uint64_t Yap_StartOfWTimes; +extern uint64_t Yap_StartOfWTimes; + #endif