This commit is contained in:
vscosta 2016-04-17 17:09:10 -07:00
parent 76f4868ff6
commit c1b8d140db
11 changed files with 209 additions and 215 deletions

View File

@ -251,7 +251,7 @@ X_API YAP_Bool YAP_IsAtomTerm(Term t) { return (IsAtomTerm(t)); }
X_API YAP_Bool YAP_IsPairTerm(Term t) { return (IsPairTerm(t)); } X_API YAP_Bool YAP_IsPairTerm(Term t) { return (IsPairTerm(t)); }
X_API YAP_Bool YAP_IsApplTerm(Term t) { X_API YAP_Bool YAP_IsApplTerm(Term t) {
return (IsApplTerm(t) && !IsExtensionFunctor(FunctorOfTerm(t))); return IsApplTerm(t) && !IsExtensionFunctor(FunctorOfTerm(t));
} }
X_API YAP_Bool YAP_IsCompoundTerm(Term t) { X_API YAP_Bool YAP_IsCompoundTerm(Term t) {
@ -1901,8 +1901,8 @@ X_API Int YAP_RunGoalOnce(Term t) {
X_API bool YAP_RestartGoal(void) { X_API bool YAP_RestartGoal(void) {
CACHE_REGS CACHE_REGS
bool out;
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
bool out;
if (LOCAL_AllowRestart) { if (LOCAL_AllowRestart) {
P = (yamop *)FAILCODE; P = (yamop *)FAILCODE;
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
@ -2009,7 +2009,7 @@ X_API void YAP_ClearExceptions(void) {
X_API int YAP_InitConsult(int mode, const char *filename, int *osnop) { X_API int YAP_InitConsult(int mode, const char *filename, int *osnop) {
CACHE_REGS CACHE_REGS
FILE *f; FILE *f;
int sno; int sno;
char full[FILENAME_MAX] BACKUP_MACHINE_REGS(); char full[FILENAME_MAX] BACKUP_MACHINE_REGS();
@ -2241,21 +2241,37 @@ static void do_bootfile(char *bootfilename USES_REGS) {
#endif #endif
} }
static void construct_init_file(char *boot_file, char *BootFile) { /* trust YAPSHAREDIR over YAP_PL_SRCDIR, and notice that the code is
/* trust YAPSHAREDIR over YAP_PL_SRCDIR, and notice that the code is /
* dependent. */ * dependent. */
static bool construct_init_file(char *boot_file, char *BootFile)
{
#if HAVE_GETENV #if HAVE_GETENV
if (getenv("YAPSHAREDIR")) { if (getenv("YAPSHAREDIR")) {
strncpy(boot_file, getenv("YAPSHAREDIR"), 256); strncpy(boot_file, getenv("YAPSHAREDIR"), 256);
strncat(boot_file, "/pl/", 255); strncat(boot_file, "/pl/", 255);
} else { if (Yap_Exists( boot_file ) ) {
#endif return true;
strncpy(boot_file, YAP_PL_SRCDIR, 256); }
strncat(boot_file, "/", 255);
#if HAVE_GETENV
} }
#endif #endif
#if __ANDROID__
strncpy(boot_file, "/assets/share/pl/", 256);
if (Yap_Exists( boot_file ) ) {
return true;
}
#endif
strncpy(boot_file, YAP_SHAREDIR "/pl/" , 256);
strncat(boot_file, BootFile, 255); strncat(boot_file, BootFile, 255);
if (Yap_Exists( boot_file ) ) {
return true;
}
strncpy(boot_file, YAP_PL_SRCDIR "/", 256);
strncat(boot_file, BootFile, 255);
if (Yap_Exists( boot_file ) ) {
return true;
}
return false;
} }
/* this routine is supposed to be called from an external program /* this routine is supposed to be called from an external program
@ -2353,25 +2369,22 @@ Int YAP_Init(YAP_init_args *yap_init) {
Yap_ExecutionMode = yap_init->ExecutionMode; Yap_ExecutionMode = yap_init->ExecutionMode;
if (do_bootstrap) { if (do_bootstrap) {
restore_result = YAP_BOOT_FROM_PROLOG; restore_result = YAP_BOOT_FROM_PROLOG;
} else if (BOOT_FROM_SAVED_STATE) { } else { // try always to boot from the saved state.
restore_result = Yap_Restore(yap_init->SavedState, yap_init->YapLibDir); if (restore_result != YAP_BOOT_FROM_PROLOG) {
if (restore_result == FAIL_RESTORE) {
yap_init->ErrorNo = LOCAL_Error_TYPE;
yap_init->ErrorCause = LOCAL_ErrorMessage;
/* shouldn't RECOVER_MACHINE_REGS(); be here ??? */
return YAP_BOOT_ERROR;
}
} else {
restore_result = YAP_BOOT_FROM_PROLOG;
}
if (BOOT_FROM_SAVED_STATE && !do_bootstrap) {
if (!Yap_SavedInfo(yap_init->SavedState, yap_init->YapLibDir, &Trail, if (!Yap_SavedInfo(yap_init->SavedState, yap_init->YapLibDir, &Trail,
&Stack, &Heap)) { &Stack, &Heap)) {
restore_result = YAP_BOOT_FROM_PROLOG;
yap_init->ErrorNo = LOCAL_Error_TYPE; yap_init->ErrorNo = LOCAL_Error_TYPE;
yap_init->ErrorCause = LOCAL_ErrorMessage; yap_init->ErrorCause = LOCAL_ErrorMessage;
return YAP_BOOT_ERROR; return YAP_BOOT_ERROR;
} }
} }
restore_result = Yap_Restore(yap_init->SavedState, yap_init->YapLibDir);
if (restore_result == FAIL_RESTORE) {
restore_result = YAP_BOOT_FROM_PROLOG;
}
}
GLOBAL_FAST_BOOT_FLAG = yap_init->FastBoot; GLOBAL_FAST_BOOT_FLAG = yap_init->FastBoot;
#if defined(YAPOR) || defined(TABLING) #if defined(YAPOR) || defined(TABLING)
Yap_init_root_frames(); Yap_init_root_frames();
@ -2444,17 +2457,8 @@ Int YAP_Init(YAP_init_args *yap_init) {
if (yap_init->QuietMode) { if (yap_init->QuietMode) {
setVerbosity(TermSilent); setVerbosity(TermSilent);
} }
if (BOOT_FROM_SAVED_STATE && !do_bootstrap) { if (restore_result == DO_EVERYTHING ||
if (restore_result == FAIL_RESTORE) { restore_result == DO_ONLY_CODE) {
yap_init->ErrorNo = LOCAL_Error_TYPE;
yap_init->ErrorCause = LOCAL_ErrorMessage;
return YAP_BOOT_ERROR;
}
if (Atts && Atts * 1024 > 2048 * sizeof(CELL))
Yap_AttsSize = Atts * 1024;
else {
Yap_AttsSize = 2048 * sizeof(CELL);
}
LOCAL_PrologMode &= ~BootMode; LOCAL_PrologMode &= ~BootMode;
if (restore_result == DO_ONLY_CODE) { if (restore_result == DO_ONLY_CODE) {
/* first, initialize the saved state */ /* first, initialize the saved state */
@ -2465,38 +2469,37 @@ Int YAP_Init(YAP_init_args *yap_init) {
CurrentModule = LOCAL_SourceModule = USER_MODULE; CurrentModule = LOCAL_SourceModule = USER_MODULE;
return YAP_BOOT_FROM_SAVED_STACKS; return YAP_BOOT_FROM_SAVED_STACKS;
} }
} else {
/* read the bootfile */
if (!do_bootstrap) {
construct_init_file(boot_file, BootFile);
yap_init->YapPrologBootFile = boot_file;
}
do_bootfile(yap_init->YapPrologBootFile ? yap_init->YapPrologBootFile
: BootFile PASS_REGS);
/* initialize the top-level */
if (!do_bootstrap) {
char init_file[256];
Atom atfile;
Functor fgoal;
YAP_Term goal, as[2];
construct_init_file(init_file, InitFile);
/* consult init file */
atfile = Yap_LookupAtom(init_file);
as[0] = MkAtomTerm(atfile);
fgoal = Yap_MkFunctor(Yap_FullLookupAtom("$silent_bootstrap"), 1);
goal = Yap_MkApplTerm(fgoal, 1, as);
/* launch consult */
YAP_RunGoalOnce(goal);
/* set default module to user */
as[0] = MkAtomTerm(AtomUser);
fgoal = Yap_MkFunctor(Yap_LookupAtom("module"), 1);
goal = Yap_MkApplTerm(fgoal, 1, as);
YAP_RunGoalOnce(goal);
}
Yap_PutValue(Yap_FullLookupAtom("$live"),
MkAtomTerm(Yap_FullLookupAtom("$true")));
} }
/* read the bootfile */
if (!do_bootstrap) {
construct_init_file(boot_file, BootFile);
yap_init->YapPrologBootFile = boot_file;
}
do_bootfile(yap_init->YapPrologBootFile ? yap_init->YapPrologBootFile
: BootFile PASS_REGS);
/* initialize the top-level */
if (!do_bootstrap) {
char init_file[256];
Atom atfile;
Functor fgoal;
YAP_Term goal, as[2];
if (!construct_init_file(init_file, InitFile))
Yap_exit(1);
/* consult init file */
atfile = Yap_LookupAtom(init_file);
as[0] = MkAtomTerm(atfile);
fgoal = Yap_MkFunctor(Yap_FullLookupAtom("$silent_bootstrap"), 1);
goal = Yap_MkApplTerm(fgoal, 1, as);
/* launch consult */
YAP_RunGoalOnce(goal);
/* set default module to user */
as[0] = MkAtomTerm(AtomUser);
fgoal = Yap_MkFunctor(Yap_LookupAtom("module"), 1);
goal = Yap_MkApplTerm(fgoal, 1, as);
YAP_RunGoalOnce(goal);
}
Yap_PutValue(Yap_FullLookupAtom("$live"),
MkAtomTerm(Yap_FullLookupAtom("$true")));
return YAP_BOOT_FROM_PROLOG; return YAP_BOOT_FROM_PROLOG;
} }
@ -2513,7 +2516,7 @@ Int Yap_InitDefaults(YAP_init_args *init_args, char saved_state[]) {
init_args->MaxTrailSize = 0; init_args->MaxTrailSize = 0;
init_args->YapLibDir = NULL; init_args->YapLibDir = NULL;
#if __ANDROID__ #if __ANDROID__
init_args->YapPrologBootFile = "pl/boot.yap"; init_args->YapPrologBootFile = "boot.yap";
init_args->YapPrologInitGoal = "bootstrap"; init_args->YapPrologInitGoal = "bootstrap";
#else #else
init_args->YapPrologBootFile = NULL; init_args->YapPrologBootFile = NULL;

View File

@ -586,7 +586,7 @@ static void initFlag(flag_info *f, int fnum, bool global) {
static bool executable(Term inp) { static bool executable(Term inp) {
CACHE_REGS CACHE_REGS
if (GLOBAL_argv && GLOBAL_argv[0]) { if (GLOBAL_argv && GLOBAL_argv[0]) {
if (!Yap_AbsoluteFileInBuffer(GLOBAL_argv[0], LOCAL_FileNameBuf, YAP_FILENAME_MAX - 1,true)) if (!Yap_AbsoluteFile(GLOBAL_argv[0], LOCAL_FileNameBuf,true))
return false; return false;
} else } else
strncpy(LOCAL_FileNameBuf, Yap_FindExecutable(), YAP_FILENAME_MAX - 1); strncpy(LOCAL_FileNameBuf, Yap_FindExecutable(), YAP_FILENAME_MAX - 1);

View File

@ -413,7 +413,11 @@ static void InitDebug(void) {
if (Yap_output_msg) { if (Yap_output_msg) {
char ch; char ch;
#if HAVE_ISATTY #if _WIN32
if (!_isatty( _fileno( stdin ) )) {
return;
}
#elif HAVE_ISATTY
if (!isatty(0)) { if (!isatty(0)) {
return; return;
} }
@ -423,9 +427,11 @@ static void InitDebug(void) {
fprintf(stderr, "a getch\t\tb token\t\tc Lookup\td LookupVar\ti Index\n"); fprintf(stderr, "a getch\t\tb token\t\tc Lookup\td LookupVar\ti Index\n");
fprintf(stderr, "e SetOp\t\tf compile\tg icode\t\th boot\t\tl log\n"); fprintf(stderr, "e SetOp\t\tf compile\tg icode\t\th boot\t\tl log\n");
fprintf(stderr, "m Machine\t p parser\n"); fprintf(stderr, "m Machine\t p parser\n");
while ((ch = putchar(getchar())) != '\n') while ((ch = putchar(getchar())) != '\n' && ch != '\r') {
if (ch >= 'a' && ch <= 'z') if (ch >= 'a' && ch <= 'z')
GLOBAL_Option[ch - 'a' + 1] = 1; GLOBAL_Option[ch - 'a' + 1] = 1;
GLOBAL_Option[ch - 'a' + 1] = 1;
}
if (GLOBAL_Option['l' - 96]) { if (GLOBAL_Option['l' - 96]) {
GLOBAL_logfile = fopen(LOGFILE, "w"); GLOBAL_logfile = fopen(LOGFILE, "w");
if (GLOBAL_logfile == NULL) { if (GLOBAL_logfile == NULL) {

View File

@ -15,9 +15,9 @@ set (CXX_SOURCES
) )
if (YAP_SINGLE_FILE) if (YAP_SINGLE_FILE OR WIN32)
add_library (Yap++ OBJECT ${CXX_SOURCES} ) add_library (Yap++ OBJECT ${CXX_SOURCES} )
else(YAP_SINGLE_FILE) else(YAP_SINGLE_FILE OR WIN32)
add_library (Yap++ SHARED ${CXX_SOURCES} ) add_library (Yap++ SHARED ${CXX_SOURCES} )
target_link_libraries(Yap++ ${CMAKE_DL_LIBS} libYap) target_link_libraries(Yap++ ${CMAKE_DL_LIBS} libYap)
@ -26,7 +26,7 @@ install(TARGETS Yap++
LIBRARY DESTINATION ${libdir} LIBRARY DESTINATION ${libdir}
ARCHIVE DESTINATION ${libdir} ARCHIVE DESTINATION ${libdir}
) )
endif(YAP_SINGLE_FILE) endif(YAP_SINGLE_FILE OR WIN32)
include_directories (H include ${CMAKE_BINARY_DIR} ${GMP_INCLUDE_DIR}) include_directories (H include ${CMAKE_BINARY_DIR} ${GMP_INCLUDE_DIR})

View File

@ -1,6 +1,3 @@
#ifndef __unix__
#define X_API
#endif
#ifndef YAPT_HH #ifndef YAPT_HH
#define YAPT_HH 1 #define YAPT_HH 1

View File

@ -1904,7 +1904,7 @@ significant byte first (like Motorola and SPARC, unlike Intel). */
#endif #endif
#ifndef YAP_PL_SRCDIR #ifndef YAP_PL_SRCDIR
#define YAP_PL_SRCDIR "${PROJECT_SOURCE_DIR}/pl}" #define YAP_PL_SRCDIR "${PROJECT_SOURCE_DIR}/pl"
#endif #endif
#ifndef YAP_SHAREDIR #ifndef YAP_SHAREDIR

View File

@ -95,13 +95,18 @@ void Yap_ConsoleOps(StreamDesc *s) {
/* static */ /* static */
static int ConsolePutc(int sno, int ch) { static int ConsolePutc(int sno, int ch) {
StreamDesc *s = &GLOBAL_Stream[sno]; StreamDesc *s = &GLOBAL_Stream[sno];
#if MAC || _MSC_VER || defined(__MINGW32__)
if (ch == 10) { if (ch == 10) {
#if MAC || _WIN32
fputs("\n", s->file);
#else
putc('\n', s->file); putc('\n', s->file);
#endif
LOCAL_newline = true; LOCAL_newline = true;
} else } else
#endif
putc(ch, s->file); putc(ch, s->file);
#if MAC || _WIN32
fflush( NULL );
#endif
console_count_output_char(ch, s); console_count_output_char(ch, s);
return ((int)ch); return ((int)ch);
} }
@ -133,6 +138,7 @@ restart:
#endif #endif
LOCAL_PrologMode |= ConsoleGetcMode; LOCAL_PrologMode |= ConsoleGetcMode;
ch = fgetc(s->file); ch = fgetc(s->file);
printf("got %d\n", ch);
#if HAVE_SIGINTERRUPT #if HAVE_SIGINTERRUPT
siginterrupt(SIGINT, FALSE); siginterrupt(SIGINT, FALSE);
#endif #endif

View File

@ -270,10 +270,14 @@ static Int time_file(USES_REGS1) {
HANDLE hdl; HANDLE hdl;
Term rc; Term rc;
if ((hdl = CreateFile(n, 0, 0, NULL, OPEN_EXISTING, 0, 0)) == 0) if ((hdl = CreateFile(n, 0, 0, NULL, OPEN_EXISTING, 0, 0)) == 0) {
Yap_WinError("in time_file");
return false; return false;
if (GetFileTime(hdl, NULL, NULL, &ft)) }
if (GetFileTime(hdl, NULL, NULL, &ft) == 0) {
Yap_WinError("in time_file");
return false; return false;
}
// Convert the last-write time to local time. // Convert the last-write time to local time.
// FileTimeToSystemTime(&ftWrite, &stUTC); // FileTimeToSystemTime(&ftWrite, &stUTC);
// SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); // SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
@ -548,9 +552,11 @@ static Int file_directory_name(USES_REGS1) { /* file_directory_name(Stream,N) */
#else #else
char s[YAP_FILENAME_MAX + 1]; char s[YAP_FILENAME_MAX + 1];
Int i = strlen(c); Int i = strlen(c);
while (i && !Yap_dir_separator((int)c[--i])) strncpy(s, c, YAP_FILENAME_MAX);
; while (--i) {
strncpy(s, c, i); if (Yap_dir_separator((int)c[i]))
break;
}
s[i] = '\0'; s[i] = '\0';
#endif #endif
return Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(s))); return Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(s)));

View File

@ -451,4 +451,7 @@ extern FILE *Yap_stdout;
extern FILE *Yap_stderr; extern FILE *Yap_stderr;
char *Yap_MemExportStreamPtr(int sno); char *Yap_MemExportStreamPtr(int sno);
bool Yap_Exists(const char *f);
#endif #endif

View File

@ -133,7 +133,7 @@ int Yap_open_buf_read_stream(const char *nbuf, size_t nchars, encoding_t *encp,
st->file = f = fmemopen((void *)nbuf, nchars, "r"); st->file = f = fmemopen((void *)nbuf, nchars, "r");
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f; flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
#else #else
sT->file = f = NULL; st->file = f = NULL;
flags = Input_Stream_f | InMemory_Stream_f; flags = Input_Stream_f | InMemory_Stream_f;
#endif #endif
Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead); Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead);

View File

@ -183,16 +183,16 @@ static bool is_directory(const char *FileName) {
#endif #endif
} }
/// has_access just calls access bool Yap_Exists(const char *f) {
/// it uses F_OK, R_OK and friend #if _WIN32
static bool has_access(const char *FileName, int mode) { if (_access(f, 0) == 0)
#ifdef __ANDROID__ return true;
if (Yap_isAsset(FileName)) { if (errno == EINVAL) {
return Yap_AccessAsset(FileName, mode); Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "bad flags to access");
} }
#endif return false;
#if HAVE_ACCESS #elif HAVE_ACCESS
if (access(FileName, mode) == 0) if (access(FileName, F_OK) == 0)
return true; return true;
if (errno == EINVAL) { if (errno == EINVAL) {
Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "bad flags to access"); Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "bad flags to access");
@ -205,14 +205,6 @@ static bool has_access(const char *FileName, int mode) {
#endif #endif
} }
static bool exists(const char *f) {
#if _MSC_VER
return has_access(f, 00);
#else
return has_access(f, F_OK);
#endif
}
static int dir_separator(int ch) { static int dir_separator(int ch) {
#ifdef MAC #ifdef MAC
return (ch == ':'); return (ch == ':');
@ -358,7 +350,7 @@ static const char *PlExpandVars(const char *source, const char *root,
return result; return result;
} }
#if _WIN32 || defined(__MINGW32__) #if _WIN32
// straightforward conversion from Unix style to WIN style // straightforward conversion from Unix style to WIN style
// check cygwin path.cc for possible improvements // check cygwin path.cc for possible improvements
static char *unix2win(const char *source, char *target, int max) { static char *unix2win(const char *source, char *target, int max) {
@ -454,9 +446,11 @@ static bool ChDir(const char *path) {
GLOBAL_AssetsWD = NULL; GLOBAL_AssetsWD = NULL;
} }
#endif #endif
#if _WIN32 || defined(__MINGW32__) #if _WIN32
rc = true;
if ((rc = (SetCurrentDirectory(qpath) != 0)) == 0) { if (qpath != NULL &&
qpath[0] &&
(rc = (SetCurrentDirectory(qpath) != 0)) == 0) {
Yap_WinError("SetCurrentDirectory failed"); Yap_WinError("SetCurrentDirectory failed");
} }
#else #else
@ -466,44 +460,15 @@ static bool ChDir(const char *path) {
free((char *)qpath); free((char *)qpath);
return rc; return rc;
} }
#if _WIN32 || defined(__MINGW32__)
char *BaseName(const char *X) {
char *qpath = unix2win(X, NULL, YAP_FILENAME_MAX);
char base[YAP_FILENAME_MAX], ext[YAP_FILENAME_MAX];
_splitpath(qpath, NULL, NULL, base, ext);
strcpy(qpath, base);
strcat(qpath, ext);
return qpath;
}
const char *DirName(const char *X) {
char dir[YAP_FILENAME_MAX];
char drive[YAP_FILENAME_MAX];
char *o = unix2win(X, NULL, YAP_FILENAME_MAX);
int err;
if (!o)
return NULL;
if ((err = _splitpath_s(o, drive, YAP_FILENAME_MAX - 1, dir,
YAP_FILENAME_MAX - 1, NULL, 0, NULL, 0)) != 0) {
FileError(SYSTEM_ERROR_OPERATING_SYSTEM, TermNil,
"could not perform _splitpath %s: %s", X, strerror(errno));
return NULL;
}
strncpy(o, drive, YAP_FILENAME_MAX - 1);
strncat(o, dir, YAP_FILENAME_MAX - 1);
return o;
}
#endif
static const char *myrealpath(const char *path, char *out) { static const char *myrealpath(const char *path, char *out) {
if (!out) if (!out)
out = LOCAL_FileNameBuf; out = LOCAL_FileNameBuf;
#if _WIN32 || defined(__MINGW32__) #if _WIN32
DWORD retval = 0; DWORD retval = 0;
// notice that the file does not need to exist // notice that the file does not need to exist
retval = GetFullPathName(path, YAP_FILENAME_MAX, out, NULL); retval = GetFullPathName(path, YAP_FILENAME_MAX, out, NULL);
if (retval == 0) { if (retval == 0) {
Yap_WinError("Generating a full path name for a file"); Yap_WinError("Generating a full path name for a file");
return NULL; return NULL;
@ -583,101 +548,80 @@ static const char *expandVars(const char *spec, char *u) {
* @return tmp, or NULL, in malloced memory * @return tmp, or NULL, in malloced memory
*/ */
const char *Yap_AbsoluteFile(const char *spec, char *rc0, bool ok) { const char *Yap_AbsoluteFile(const char *spec, char *rc0, bool ok) {
const char *p;
const char *rc; const char *rc;
if (!ok) { const char *spec1;
if (!rc0) const char *spec2;
rc0 = malloc(strlen(spec)+1); char rc1[YAP_FILENAME_MAX+1];
return strcpy(rc0, spec);
} /// spec gothe original spec;
rc = PlExpandVars(spec, NULL, rc0); /// rc0 may be an outout buffer
if (!rc) /// rc1 the internal buffer
rc = spec; ///
if ((p = myrealpath(rc, rc0))) { /// PlExpandVars
if (rc != rc0 && rc != spec && rc != p)
freeBuffer(rc);
return p; #if _WIN32
} else { char rc2[YAP_FILENAME_MAX];
if (rc != rc0 && rc != spec) if (( rc = unix2win(spec, rc2, YAP_FILENAME_MAX)) == NULL) {
freeBuffer(rc);
return NULL; return NULL;
} }
} spec1 = rc;
#else
/** spec1 = spec;
* generate absolute path and stores path in an user given buffer. If #endif
* NULL, uses a temporary buffer that must be quickly released. /// spec gothe original spec;
* /// rc1 the internal buffer
* if ok first expand variable names and do globbing
*
* @param[in] spec the file path, including `~` and `$`.
* @param[in] ok where to process `~` and `$`.
*
* @return tmp, or NULL, in malloced memory
*/
const char *Yap_AbsoluteFileInBuffer(const char *spec, char *out, size_t sz,
bool ok) {
CACHE_REGS
const char *p;
const char *rc;
if (ok) { if (ok) {
rc = expandVars(spec, LOCAL_FileNameBuf); const char *q = PlExpandVars(spec1, NULL, rc1);
if (!rc) if (!q)
return spec; spec2 = spec1;
else
spec2 = q;
} else { } else {
rc = spec; spec2 = spec1;
} }
rc = myrealpath(spec2, rc0);
if ((p = myrealpath(rc, NULL))) { return rc;
if (!out) {
out = LOCAL_FileNameBuf;
sz = YAP_FILENAME_MAX - 1;
}
if (p != out) {
strncpy(out, p, sz);
freeBuffer(p);
return out;
} else {
return NULL;
}
}
return NULL;
} }
static Term static Term
/* Expand the string for the program to run. */ /* Expand the string for the program to run. */
do_glob(const char *spec, bool glob_vs_wordexp) { do_glob(const char *spec, bool glob_vs_wordexp) {
CACHE_REGS CACHE_REGS
char u[YAP_FILENAME_MAX + 1]; char u[YAP_FILENAME_MAX + 1];
char *espec = u; const char *espec = u;
if (spec == NULL) { if (spec == NULL) {
return TermNil; return TermNil;
} }
#if _WIN32 || defined(__MINGW32__) #if _WIN32
{ {
WIN32_FIND_DATA find; WIN32_FIND_DATA find;
HANDLE hFind; HANDLE hFind;
CELL *dest; CELL *dest;
Term tf; Term tf;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath( spec, drive, dir, fname, ext );
_makepath( u, drive, dir, fname, ext );
// first pass, remove Unix style stuff // first pass, remove Unix style stuff
if (unix2win(espec, u, YAP_FILENAME_MAX) == NULL) hFind = FindFirstFile(u, &find);
return TermNil;
espec = (const char *)u;
hFind = FindFirstFile(espec, &find);
if (hFind == INVALID_HANDLE_VALUE) { if (hFind == INVALID_HANDLE_VALUE) {
return TermNil; return TermNil;
} else { } else {
tf = AbsPair(HR); tf = AbsPair(HR);
HR[0] = MkAtomTerm(Yap_LookupAtom(find.cFileName)); _makepath( u, drive, dir, find.cFileName, NULL );
HR[0] = MkAtomTerm(Yap_LookupAtom(u));
HR[1] = TermNil; HR[1] = TermNil;
dest = HR + 1; dest = HR + 1;
HR += 2; HR += 2;
while (FindNextFile(hFind, &find)) { while (FindNextFile(hFind, &find)) {
*dest = AbsPair(HR); *dest = AbsPair(HR);
HR[0] = MkAtomTerm(Yap_LookupAtom(find.cFileName)); _makepath( u, drive, dir, find.cFileName, NULL );
HR[0] = MkAtomTerm(Yap_LookupAtom(u));
HR[1] = TermNil; HR[1] = TermNil;
dest = HR + 1; dest = HR + 1;
HR += 2; HR += 2;
@ -687,7 +631,7 @@ static Term
return tf; return tf;
} }
#elif HAVE_WORDEXP || HAVE_GLOB #elif HAVE_WORDEXP || HAVE_GLOB
strncpy(espec, spec, sizeof(u)); strncpy(u, spec, sizeof(u));
/* Expand the string for the program to run. */ /* Expand the string for the program to run. */
size_t pathcount; size_t pathcount;
#if HAVE_GLOB #if HAVE_GLOB
@ -807,7 +751,8 @@ static Term
*/ */
static Int real_path(USES_REGS1) { static Int real_path(USES_REGS1) {
Term t1 = Deref(ARG1); Term t1 = Deref(ARG1);
const char *cmd; const char *cmd, *rc0;
char *rc;
if (IsAtomTerm(t1)) { if (IsAtomTerm(t1)) {
cmd = RepAtom(AtomOfTerm(t1))->StrOfAE; cmd = RepAtom(AtomOfTerm(t1))->StrOfAE;
@ -816,14 +761,20 @@ static Int real_path(USES_REGS1) {
} else { } else {
return false; return false;
} }
const char *rc = myrealpath(cmd, NULL); #if _WIN32
if (!rc) { char cmd2[YAP_FILENAME_MAX+1];
PlIOError(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, strerror(errno));
if (( rc = unix2win(cmd, cmd2, YAP_FILENAME_MAX)) == NULL) {
return false; return false;
} }
bool r = Yap_unify(MkAtomTerm(Yap_LookupAtom(rc)), ARG2); cmd = rc;
freeBuffer((char *)rc); #endif
return r;
rc0 = myrealpath(cmd, NULL);
if (!rc0) {
PlIOError(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, NULL);
}
return Yap_unify(MkAtomTerm(Yap_LookupAtom(rc0)), ARG2);
} }
#define EXPAND_FILENAME_DEFS() \ #define EXPAND_FILENAME_DEFS() \
@ -864,6 +815,18 @@ static Term do_expand_file_name(Term t1, Term opts USES_REGS) {
Yap_Error(TYPE_ERROR_ATOM, t1, NULL); Yap_Error(TYPE_ERROR_ATOM, t1, NULL);
return TermNil; return TermNil;
} }
#if _WIN32
{
char *rc;
char cmd2[YAP_FILENAME_MAX+1];
if (( rc = unix2win(spec, cmd2, YAP_FILENAME_MAX)) == NULL) {
return false;
}
spec = rc;
}
#endif
args = Yap_ArgListToVector(opts, expand_filename_defs, EXPAND_FILENAME_END); args = Yap_ArgListToVector(opts, expand_filename_defs, EXPAND_FILENAME_END);
if (args == NULL) { if (args == NULL) {
return TermNil; return TermNil;
@ -903,7 +866,10 @@ static Term do_expand_file_name(Term t1, Term opts USES_REGS) {
} }
if (!use_system_expansion) { if (!use_system_expansion) {
return MkPairTerm(MkAtomTerm(Yap_LookupAtom(expandVars(spec, NULL))), const char *o = expandVars(spec, NULL);
if (!o)
return false;
return MkPairTerm(MkAtomTerm(Yap_LookupAtom(o)),
TermNil); TermNil);
} }
tf = do_glob(spec, true); tf = do_glob(spec, true);
@ -1251,6 +1217,7 @@ const char *Yap_getcwd(const char *cwd, size_t cwdlen) {
static Int working_directory(USES_REGS1) { static Int working_directory(USES_REGS1) {
char dir[YAP_FILENAME_MAX + 1]; char dir[YAP_FILENAME_MAX + 1];
Term t1 = Deref(ARG1), t2; Term t1 = Deref(ARG1), t2;
if (!IsVarTerm(t1) && !IsAtomTerm(t1)) { if (!IsVarTerm(t1) && !IsAtomTerm(t1)) {
Yap_Error(TYPE_ERROR_ATOM, t1, "working_directory"); Yap_Error(TYPE_ERROR_ATOM, t1, "working_directory");
} }
@ -1264,8 +1231,9 @@ static Int working_directory(USES_REGS1) {
if (!IsAtomTerm(t2)) { if (!IsAtomTerm(t2)) {
Yap_Error(TYPE_ERROR_ATOM, t2, "working_directory"); Yap_Error(TYPE_ERROR_ATOM, t2, "working_directory");
} }
ChDir(RepAtom(AtomOfTerm(t2))->StrOfAE); if (t2 == TermEmptyAtom || t2 == TermDot)
return true; return true;
return ChDir(RepAtom(AtomOfTerm(t2))->StrOfAE);
} }
/** Yap_findFile(): tries to locate a file, no expansion should be performed/ /** Yap_findFile(): tries to locate a file, no expansion should be performed/
@ -1389,7 +1357,7 @@ const char *Yap_findFile(const char *isource, const char *idef,
// expand names in case you have // expand names in case you have
// to add a prefix // to add a prefix
if (!access || exists(work)) if (!access || Yap_Exists(work))
return work; // done return work; // done
} }
return NULL; return NULL;
@ -1401,18 +1369,23 @@ const char *Yap_locateFile(const char *source, char *result, bool in_lib) {
static Int true_file_name(USES_REGS1) { static Int true_file_name(USES_REGS1) {
Term t = Deref(ARG1); Term t = Deref(ARG1);
const char *s;
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
Yap_Error(INSTANTIATION_ERROR, t, "argument to true_file_name unbound"); Yap_Error(INSTANTIATION_ERROR, t, "argument to true_file_name unbound");
return FALSE; return FALSE;
} }
if (!IsAtomTerm(t)) { if (IsAtomTerm(t)) {
s = RepAtom(AtomOfTerm(t))->StrOfAE;
} else if (IsStringTerm(t)) {
s = StringOfTerm(t);
} else {
Yap_Error(TYPE_ERROR_ATOM, t, "argument to true_file_name"); Yap_Error(TYPE_ERROR_ATOM, t, "argument to true_file_name");
return FALSE; return FALSE;
} }
if (!Yap_AbsoluteFileInBuffer(RepAtom(AtomOfTerm(t))->StrOfAE, if (!Yap_AbsoluteFile(s,
LOCAL_FileNameBuf, YAP_FILENAME_MAX - 1, true)) LOCAL_FileNameBuf, true))
return FALSE; return true;
return Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf))); return Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf)));
} }