android and encoding

This commit is contained in:
Vitor Santos Costa 2016-07-31 10:28:05 -05:00
parent 91120de170
commit 8d19f397d4
5 changed files with 335 additions and 264 deletions

249
os/assets.c Normal file
View File

@ -0,0 +1,249 @@
/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: assets.c *
* Last rev: 5/2/88 *
* mods: *
* comments: Asset Support in ANDROID *
* *
*************************************************************************/
#ifdef SCCSA
static char SccsId[] = "%W% %G%";
#endif
/**
* @file assets.c
* @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
* @date Thu Nov 19 10:53:20 2015
*
* @brief File Aliases
*
*
*/
#include <stdbool.h>
#include "sysbits.h"
// for native asset manager
#include <sys/types.h>
#if __ANDROID__
static AAssetManager * getMgr(struct vfs *me)
{
return me->priv[0].mgr;
}
void
Java_pt_up_yap_app_YAPDroid_load(JNIEnv *env,
jobject assetManager) {
AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);
if (mgr == NULL) {
return;
}
VFS_t *me = GLOBAL_VFS;
while ( strcmp(me->name, "/assets") == 0)
me = me->next;
me->priv[0].mgr = mgr;
}
static bool
open_asset(struct vfs *me, struct stream_desc *st, const char *fname, const char
*io_mode)
{
AAssetManager *mgr;
int mode;
const void *buf;
if (strstr(fname,"/assets") == fname) {
// we're in
mgr = getMgr(me);
if (mgr == NULL) {
return PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, TermNil,
"asset manager",
fname);
}
if (strchr(io_mode, 'w') || strchr(io_mode, 'a')) {
return PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, TermNil,
"%s: no writing but flags are %s",
fname, io_mode);
}
if (strchr(io_mode, 'B'))
mode = AASSET_MODE_BUFFER;
else
{
mode = AASSET_MODE_UNKNOWN;
}
AAsset *a = AAssetManager_open(mgr , fname, mode);
// try not to use it as an asset
off64_t sz = AAsset_getLength64(a), sz0 = 0;
int fd;
if ((fd = AAsset_openFileDescriptor64(a, &sz0, &sz)) >= 0) {
// can use it as red-only file
st->file = fdopen( fd, "r");
st->vfs = me;
st->vfs_handle = a;
return true;
} else if ((buf = AAsset_getBuffer(a)) ) {
// copy to memory
bool rc = Yap_set_stream_to_buf(st, buf, sz);
AAsset_close(a);
return rc;
}
// should be done, but if not
st->vfs_handle = a;
st->vfs = me;
return true;
}
if (me->next) {
return me->next->open(me->next, st, fname, io_mode);
}
return NULL;
}
static bool
close_asset(struct stream_desc *st)
{
AAsset_close(st->vfs_handle);
return true;
}
static int64_t seek64(struct stream_desc *st, int64_t offset, int whence)
{
return AAsset_seek64(st->vfs_handle, offset, whence);
}
static int getc_asset(struct stream_desc *st)
{
int ch;
if ( AAsset_read (st->vfs_handle, &ch, 1) )
return ch;
return -1;
}
static void *opendir_a(struct vfs *me, const char *dirName)
{
return (void *)AAssetManager_openDir (getMgr(me), dirName);
}
static const char *readdir_a(void *dirHandle)
{
return AAssetDir_getNextFileName ((AAssetDir *)dirHandle);
}
static bool closedir_a(void *dirHandle)
{
AAssetDir_close ((AAssetDir *)dirHandle);
return true;
}
static bool stat_a(struct vfs *me, const char *fname, vfs_stat *out)
{
struct stat64 bf;
if (stat64( "/assets", &bf)) {
out->st_dev = bf.st_dev;
out->st_uid = bf.st_uid;
out->st_gid = bf.st_gid;
memcpy(&out->st_atimespec, (const void *)&out->st_atimespec, sizeof(struct timespec));
memcpy(&out->st_mtimespec,(const void *) &out->st_mtimespec, sizeof(struct timespec));
memcpy(&out->st_ctimespec, (const void *)&out->st_ctimespec, sizeof(struct timespec));
memcpy(&out->st_birthtimespec, (const void *)&out->st_birthtimespec, sizeof(struct timespec));
}
AAssetManager *mgr = getMgr(me);
AAsset *a = AAssetManager_open(mgr , fname, AASSET_MODE_UNKNOWN);
// try not to use it as an asset
out->st_size = AAsset_getLength64(a);
AAsset_close(a);
return true;
}
static
bool is_dir_a(struct vfs *me, const char *dirName)
{
bool rc;
// try not to use it as an asset
AAssetDir *d = AAssetManager_openDir (getMgr(me), dirName);
if (d == NULL)
return false;
rc = (AAssetDir_getNextFileName(d) != NULL);
AAssetDir_close(d);
return rc;
}
static
bool exists_a(struct vfs *me, const char *dirName)
{
// try not to use it as an asset
AAsset *d = AAssetManager_open (getMgr(me), dirName, AASSET_MODE_UNKNOWN);
if (d == NULL)
return false;
AAsset_close(d);
return true;
}
static bool set_cwd (struct vfs *me, const char *dirName) {
chdir("/assets");
if (me->virtual_cwd)
free(me->virtual_cwd);
me->virtual_cwd = malloc( sizeof(dirName) + 1 );
return me!= NULL;
}
#endif
/* create a new alias arg for stream sno */
VFS_t *
Yap_InitAssetManager(void)
{
#if __ANDROID__
VFS_t *me;
/* init standard VFS */
me = (VFS_t *)Yap_AllocCodeSpace(sizeof(struct vfs));
me->name = "/assets";
me->vflags = VFS_CAN_EXEC|VFS_CAN_SEEK|VFS_HAS_PREFIX; /// the main flags describing the operation of the Fs.
me->prefix = "/assets";
/** operations */
me->open = open_asset; /// open an object in this space
me->close= close_asset; /// close the object
me->get_char = getc_asset; /// get an octet to the stream
me->putc = NULL; /// output an octet to the stream
me->seek = seek64; /// jump around the stream
me->opendir = opendir_a; /// open a directory object, if one exists
me->nextdir = readdir_a; /// open a directory object, if one exists
me->closedir = closedir_a; /// close access a directory object
me->stat = stat_a; /// obtain size, age, permissions of a file.
me->isdir = is_dir_a; /// obtain size, age, permissions of a file.
me->exists = exists_a; /// obtain size, age, permissions of a file.
me->chdir = set_cwd; /// chnage working directory.
me->enc = ENC_ISO_UTF8; /// how the file is encoded.
me->parsers = NULL; /// a set of parsers that can read the stream and generate a term
me->writers = NULL;
LOCK(BGL);
me-> next = GLOBAL_VFS;
GLOBAL_VFS = me;
return me;
UNLOCK(BGL);
return me;
#else
return NULL;
#endif
}

View File

@ -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,32 +664,29 @@ 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;
Term t2;
Term t1;
Int tabs, i;
if (IsVarTerm(t2 = Deref(ARG2))) {
Yap_Error(INSTANTIATION_ERROR, t2, "put_char/1");
if (IsVarTerm(t1 = Deref(ARG1))) {
Yap_Error(INSTANTIATION_ERROR, t1, "first argument");
return FALSE;
} else if (!IsIntegerTerm(t2)) {
Yap_Error(TYPE_ERROR_INTEGER, t2, "put_char/1");
} else if (!IsIntegerTerm(t1)) {
Yap_Error(TYPE_ERROR_INTEGER, t1, "first argument");
return FALSE;
} else if ((tabs = IntegerOfTerm(t2)) < 0) {
Yap_Error(DOMAIN_ERROR_OUT_OF_RANGE, t2, "tab/1");
} else if ((tabs = IntegerOfTerm(t1)) < 0) {
Yap_Error(DOMAIN_ERROR_OUT_OF_RANGE, t1, "first argument");
return FALSE;
}
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);
}

View File

@ -79,7 +79,7 @@ static char SccsId[] = "%W% %G%";
static Int p_change_type_of_char(USES_REGS1);
Term Yap_StringToNumberTerm(char *s, encoding_t *encp) {
Term Yap_StringToNumberTerm(const char *s, encoding_t *encp) {
CACHE_REGS
int sno;
Term t;

View File

@ -98,8 +98,8 @@ static char SccsId[] = "%W% %G%";
#endif
#endif
#include "iopreds.h"
#define GETW get_wchar_from_FILE
//#define GETW get_wchar_from_FILE
//#endif
#define GETC() fgetwc(st->file)
#include "getw.h"
@ -262,10 +262,7 @@ void Yap_DefaultStreamOps(StreamDesc *st) {
}
#ifndef _WIN32
else if (st->file != NULL && 0 && !(st->status & InMemory_Stream_f)) {
if (st->encoding == Yap_SystemEncoding()) {
st->stream_wgetc = get_wchar_from_file;
} else
st->stream_wgetc = get_wchar_from_FILE;
st->stream_wgetc = get_wchar_from_file;
}
#endif
if (GLOBAL_CharConversionTable != NULL)
@ -353,6 +350,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;
@ -639,7 +643,8 @@ int post_process_weof(StreamDesc *s) {
}
/**
* caled after EOF found a peek, it just calls console_post_process to conclude
* caled after EOF found a peek, it just calls console_post_process to
*conclude
*the job.
*
* @param sno
@ -655,7 +660,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,9 +1298,8 @@ 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) {

View File

@ -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 <stdlib.h>
/*
* This file defines main data-structure for stream management,
*
*/
extern size_t Yap_page_size;
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <windows.h>
@ -37,6 +22,19 @@ extern size_t Yap_page_size;
#include <wchar.h>
#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 +43,31 @@ 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,198 +79,13 @@ 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;
extern Term Yap_read_term(int inp_stream, Term opts, int nargs);
extern Term Yap_Parse(UInt prio, encoding_t enc, Term cmod);
#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);
void init_read_data(ReadData _PL_rd, struct stream_desc *s);
extern void init_read_data(ReadData _PL_rd, struct stream_desc *s);
typedef int (*GetsFunc)(int, UInt, char *);
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#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);
@ -285,28 +96,29 @@ static inline Int GetCurInpPos(StreamDesc *inp_stream) {
#define PlIOError(type, culprit, ...) \
PlIOError__(__FILE__, __FUNCTION__, __LINE__, type, culprit, __VA_ARGS__)
Int PlIOError__(const char *, const char *, int, yap_error_number, Term, ...);
extern Int PlIOError__(const char *, const char *, int, yap_error_number, Term, ...);
int GetFreeStreamD(void);
Term Yap_MkStream(int n);
extern int GetFreeStreamD(void);
extern Term Yap_MkStream(int n);
bool Yap_PrintWarning(Term twarning);
extern bool Yap_PrintWarning(Term twarning);
void Yap_plwrite(Term, struct stream_desc *, int, int, int);
void Yap_WriteAtom(struct stream_desc *s, Atom atom);
extern void Yap_plwrite(Term, struct stream_desc *, int, int, int);
extern void Yap_WriteAtom(struct stream_desc *s, Atom atom);
extern bool Yap_WriteTerm( int output_stream, Term t, Term opts USES_REGS);
Term Yap_scan_num(struct stream_desc *);
extern Term Yap_scan_num(struct stream_desc *);
void Yap_DefaultStreamOps(StreamDesc *st);
void Yap_PipeOps(StreamDesc *st);
void Yap_MemOps(StreamDesc *st);
bool Yap_CloseMemoryStream(int sno);
void Yap_ConsolePipeOps(StreamDesc *st);
void Yap_SocketOps(StreamDesc *st);
void Yap_ConsoleSocketOps(StreamDesc *st);
bool Yap_ReadlineOps(StreamDesc *st);
int Yap_OpenBufWriteStream(USES_REGS1);
void Yap_ConsoleOps(StreamDesc *s);
extern void Yap_DefaultStreamOps(StreamDesc *st);
extern void Yap_PipeOps(StreamDesc *st);
extern void Yap_MemOps(StreamDesc *st);
extern bool Yap_CloseMemoryStream(int sno);
extern void Yap_ConsolePipeOps(StreamDesc *st);
extern void Yap_SocketOps(StreamDesc *st);
extern void Yap_ConsoleSocketOps(StreamDesc *st);
extern bool Yap_ReadlineOps(StreamDesc *st);
extern int Yap_OpenBufWriteStream(USES_REGS1);
extern void Yap_ConsoleOps(StreamDesc *s);
void Yap_InitRandomPreds(void);
void Yap_InitSignalPreds(void);
@ -332,9 +144,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);
@ -465,4 +278,8 @@ static inline void freeBuffer(const void *ptr) {
free((void *)ptr);
}
/** VFS handling */
VFS_t *Yap_InitAssetManager(void);
#endif