fixes in modules

system support for WIN32 (first try).
small fixes.


git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@45 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2001-05-28 19:54:53 +00:00
parent 27e367f0a5
commit 82438c1d6f
23 changed files with 715 additions and 177 deletions

View File

@ -51,6 +51,14 @@ static char SccsId[] = "%W% %G%";
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_FCNTL_H
/* for O_BINARY and O_TEXT in WIN32 */
#include <fcntl.h>
#endif
#if HAVE_IO_H
/* Windows */
#include <io.h>
#endif
#if !HAVE_STRNCAT
#define strncat(X,Y,Z) strcat(X,Y)
#endif
@ -1676,9 +1684,14 @@ p_open_pipe_stream (void)
int sno;
int filedes[2];
if (pipe(filedes) != 0) {
return (PlIOError (SYSTEM_ERROR,TermNil, "open_pipe_stream/2 could not create pipe"));
}
#if _MSC_VER || defined(__MINGW32__)
if (_pipe(filedes, 256, O_TEXT) == -1)
#else
if (pipe(filedes) != 0)
#endif
{
return (PlIOError (SYSTEM_ERROR,TermNil, "open_pipe_stream/2 could not create pipe"));
}
for (sno = 0; sno < MaxStreams; ++sno)
if (Stream[sno].status & Free_Stream_f)
break;

View File

@ -39,6 +39,12 @@ static char SccsId[] = "@(#)save.c 1.3 3/15/90";
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
/********* hack for accesing several kinds of terms. Should be cleaned **/
@ -124,9 +130,7 @@ STATIC_PROTO(void NewFileInfo, (long, long));
extern int DefVol;
#endif
#if _MSC_VER
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_IO_H
#include <io.h>
#endif
@ -254,7 +258,7 @@ open_file(char *ss, int flag)
#else
#ifdef O_BINARY
#if _MSC_VER
if ((splfild = open(ss, flag | O_BINARY), _S_IREAD | _S_IWRITE) < 0)
if ((splfild = _open(ss, flag | O_BINARY), _S_IREAD | _S_IWRITE) < 0)
#else
if ((splfild = open(ss, flag | O_BINARY), 0755) < 0)
#endif

View File

@ -2012,6 +2012,20 @@ mk_argc_list(void)
Term t = TermNil;
while (i < yap_argc) {
char *arg = yap_args[i];
/* check for -L -- */
if (arg[0] == '-' && arg[1] == 'L') {
arg += 2;
while (*arg != '\0' && (*arg == ' ' || *arg == '\t'))
arg++;
if (*arg == '-' && arg[1] == '-' && arg[2] == '\0') {
/* we found the separator */
int j;
for (j = yap_argc-1; j > i+1; --j) {
t = MkPairTerm(MkAtomTerm(LookupAtom(yap_args[j])),t);
}
return(t);
}
}
if (arg[0] == '-' && arg[1] == '-' && arg[2] == '\0') {
/* we found the separator */
int j;
@ -2173,6 +2187,13 @@ p_set_yap_flags(void)
return(TRUE);
}
#ifndef YAPOR
static Int
p_default_sequential(void) {
return(TRUE);
}
#endif
#ifdef DEBUG
extern void DumpActiveGoals(void);
@ -2257,7 +2278,9 @@ InitCPreds(void)
InitCPred("unhide", 1, p_unhide, SafePredFlag|SyncPredFlag);
InitCPred("$hidden", 1, p_hidden, SafePredFlag|SyncPredFlag);
InitCPred("$has_yap_or", 0, p_has_yap_or, SafePredFlag|SyncPredFlag);
InitCPred("$has_tabling", 0, p_has_tabling, SafePredFlag|SyncPredFlag);
#ifndef YAPOR
InitCPred("$default_sequential", 1, p_default_sequential, SafePredFlag|SyncPredFlag);
#endif
#ifdef DEBUG
InitCPred("dump_active_goals", 0, p_dump_active_goals, SafePredFlag|SyncPredFlag);
#endif

View File

@ -36,6 +36,9 @@
#if HAVE_SYS_TIME_H && !HAVE_WINSOCK2_H && !_MSC_VER
#include <sys/time.h>
#endif
#if HAVE_IO_H
#include <io.h>
#endif
#if HAVE_WINSOCK2_H
#include <winsock2.h>
#ifdef HAVE_SYS_UN_H
@ -239,7 +242,7 @@ void init_socks(char *host, long interface_port)
crash("[ could not connect to interface]");
}
/* now reopen stdin stdout and stderr */
#if HAVE_DUP2
#if HAVE_DUP2 && !defined(__MINGW32__)
if(dup2(s,0)<0) {
YP_fprintf(YP_stderr,"could not dup2 stdin\n");
return;
@ -252,7 +255,7 @@ void init_socks(char *host, long interface_port)
YP_fprintf(YP_stderr,"could not dup2 stderr\n");
return;
}
#elif _MSC_VER
#elif _MSC_VER || defined(__MINGW32__)
if(_dup2(s,0)<0) {
YP_fprintf(YP_stderr,"could not dup2 stdin\n");
return;
@ -286,7 +289,11 @@ void init_socks(char *host, long interface_port)
yp_iob[2].flags = _YP_IO_SOCK | _YP_IO_WRITE;
#endif
YP_sockets_io = 1;
#if _MSC_VER || defined(__MINGW32__)
_close(s);
#else
close(s);
#endif
}
static Int
@ -436,7 +443,11 @@ p_socket(void)
out = InitSocketStream(fd, new_socket, af_inet);
else {
/* ok, we currently don't support these sockets */
#if _MSC_VER || defined(__MINGW32__)
_close(fd);
#else
close(fd);
#endif
return(FALSE);
}
return(unify(out,ARG4));

View File

@ -68,11 +68,11 @@ static int p_debug_prolog(void);
** -------------------------- */
void init_optyap_preds(void) {
InitCPred("$default_sequential", 1, p_default_sequential, SafePredFlag);
#ifdef YAPOR
InitCPred("$yapor_on", 0, yapor_on, SafePredFlag);
InitCPred("$start_yapor", 0, start_yapor, SafePredFlag);
InitCPred("$sequential", 1, p_sequential, SafePredFlag);
InitCPred("$default_sequential", 1, p_default_sequential, SafePredFlag);
InitCPred("execution_mode", 1, p_execution_mode, SafePredFlag);
InitCPred("performance", 1, p_performance, SafePredFlag);
InitCPred("$parallel_new_answer", 1, p_parallel_new_answer, SafePredFlag);

4
TO_DO
View File

@ -1,5 +1,5 @@
BEFORE 4.4:
- weird going ons with prompt
- weird going ons with prompt and readline
- mixed constraints and delays.
- write infinite terms
- constraints in DB.
@ -13,6 +13,7 @@ BEFORE 4.4:
- library(system) for WIN32
- document system(library)
- document new interface functions.
- remove pl/nfr.yap and misc/yap.spec from CVS.
TO CHECK:
- bad register allocation for a(X,Y) :- X is Y+2.3 ?
@ -70,3 +71,4 @@ DONE:
- initial port to OS_X
- listing (Steve Moyle).
- logtalk.
- fix bugs from Nicos.

View File

@ -16,19 +16,38 @@
<h2>Yap-4.3.19:</h2>
<ul>
<li> NEW: library(system), only for Unix system right now..
<li> FIXED: allow current_stream/3 to work with third argument known.
<li> FIXED: make yap modules more compatible with SICStus Prolog</li>
<li> NEW: portray_clause/2 (request from Nicos Angelopoulos)</li>
<li> FIXED: document absolute_file_name/2</li>
<li> FIXED: absolute_file_name/2 should return absolute path,
never user name! (bug report from Nicos Angelopoulos)</li>
<li> FIXED: in a:-b:call(X) X belongs to the module b (bug
report from Nicos Angelopoulos)</li>
<li> FIXED: make consult/1 and friends meta-predicates (bug
report from Nicos Angelopoulos)</li>
<li> FIXED: allow [M:F] and friends (bug report from
Nicos Angelopoulos)</li>
<li> FIXED: ensure_loaded/1 can be used as a goal (bug report
from Nicos Angelopoulos)</li>
<li> FIXED: abolish(VAR) should abolish all predicates in
current module (bug report from Nicos Angelopoulos).</li>
<li> NEW: library(system), only for Unix system right now.</li>
<li> FIXED: allow current_stream/3 to work with third argument
known.</li>
<li> FIXED: always leave enough space so that the hybrid garbage
collection may work.
<li> FIXED: add_to_path should not leave choice-points.
collection may work.</li>
<li> FIXED: add_to_path should not leave choice-points.</li>
<li> FIXED: don't initialise first occurrences in branches for
func outputs.
<li> FIXED: handle void variables in body.
func outputs.</li>
<li> FIXED: handle void variables in body.</li>
<li> NEW: externd C-interface with StreamToFileNo,
BufferToString, and BufferToAtomList.
<li> NEW: support pipes with open_pipe_stream/2.
<li>FIXED: <code>functor/3</code> was generating too many deallocates at the end of a clause.</li>
<li>FIXED: <code>call_residue/2</code> should not allow constraints to escape (use <code>copy_term_no_variables/2</code> to avoid this).</li>
BufferToString, and BufferToAtomList.</li>
<li> NEW: support pipes with open_pipe_stream/2.</li>
<li>FIXED: <code>functor/3</code> was generating too many
deallocates at the end of a clause.</li>
<li>FIXED: <code>call_residue/2</code> should not allow
constraints to escape (use
<code>copy_term_no_variables/2</code> to avoid this).</li>
<li>SPEEDUP: optimise away <code>true/0</code> at the end of a clause.</li>
<li>FIXED: do not short circuit trail entries.</li>
<li>FIXED: Patches for memory allocation in Apple's OS/X.</li>
@ -39,8 +58,10 @@
<li>FIXED: force line buffering for text stream.</li>
<li>FIXED: force no buffering for <code>user_error</code>.</li>
<li>FIXED: flush all streams before writing answer.</li>
<li>FIXED: <code>YP_std*</code> are now streams, so that <code>yap_flag(user_*)</code> will change them too.</li>
<li>FIXED: <code>nth/3</code> and <code>nth0/3</code> would leave one extra choice-point.</li>
<li>FIXED: <code>YP_std*</code> are now streams, so that
<code>yap_flag(user_*)</code> will change them too.</li>
<li>FIXED: <code>nth/3</code> and <code>nth0/3</code> would
leave one extra choice-point.</li>
<li>FIXED: use <code>Contents</code> instead of <code>Uses</code> to determine live variables.</li>
<li>FIXED: <code>cputime</code> was actually <code>walltime</code> in WIN32, ugh (report from Steve Moyle).</li>
<li>FIXED: regexp library would not compile on recent versions of cygwin.</li>

View File

@ -33,6 +33,7 @@
#undef HAVE_FPU_CONTROL_H
#undef HAVE_GMP_H
#undef HAVE_IEEEFP_H
#undef HAVE_IO_H
#undef HAVE_LIMITS_H
#undef HAVE_MEMORY_H
#undef HAVE_NETDB_H

2
configure vendored
View File

@ -2461,7 +2461,7 @@ else
fi
done
for ac_hdr in sys/select.h direct.h dirent.h signal.h
for ac_hdr in sys/select.h direct.h dirent.h signal.h io.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6

View File

@ -395,7 +395,7 @@ AC_CHECK_HEADERS(sys/param.h errno.h netdb.h netinet/in.h arpa/inet.h)
AC_CHECK_HEADERS(string.h memory.h sys/mman.h sys/stat.h stdarg.h ctype.h)
AC_CHECK_HEADERS(sys/resource.h limits.h siginfo.h time.h fenv.h)
AC_CHECK_HEADERS(fpu_control.h sys/shm.h regex.h winsock.h winsock2.h)
AC_CHECK_HEADERS(sys/select.h direct.h dirent.h signal.h)
AC_CHECK_HEADERS(sys/select.h direct.h dirent.h signal.h io.h)
if test "$yap_cv_gmp" != "no"
then
AC_CHECK_HEADERS(gmp.h)

View File

@ -327,8 +327,25 @@ parse_yap_arguments(int argc, char *argv[], yap_init_args *init_args)
output_msg = TRUE;
break;
#endif
case 'l':
case 'L':
p++;
while (*p != '\0' && (*p == ' ' || *p == '\t'))
p++;
/* skip zeroth argument */
argc--;
if (argc == 0) {
fprintf(stderr," [ YAP unrecoverable error: missing file name with option 'l' ]\n");
exit(1);
}
argv++;
if (p[0] == '-' && p[1] == '-'&& p[2] == '\0') {
/* we're done here */
argc = 1;
}
init_args->YapPrologBootFile = *argv;
init_args->HaltAfterConsult = TRUE;
break;
case 'l':
if ((*argv)[0] == '\0')
init_args->YapPrologBootFile = *argv;
else {
@ -340,8 +357,6 @@ parse_yap_arguments(int argc, char *argv[], yap_init_args *init_args)
argv++;
init_args->YapPrologBootFile = *argv;
}
if (p[0] == 'L')
init_args->HaltAfterConsult = TRUE;
break;
case '-':
/* skip remaining arguments */

View File

@ -885,7 +885,7 @@ Unix-like environments. A simple example is shown next:
@example
@cartouche
#!/usr/local/bin/yap -L $0 "$@"
#!/usr/local/bin/yap -L
#
# Hello World script file using Yap
#
@ -898,16 +898,16 @@ Unix-like environments. A simple example is shown next:
The @code{#!} characters specify that the script should call the binary
file Yap. Notice that many systems will require the complete path to the
Yap binary. The @code{-L} flag indicates that YAP should consult the
file "$0" at booting and then halt. The remaining arguments are then
passed to YAP. Note that YAP will skip the first lines if they start
with @code{#} (the comment sign for Unix's shell). YAP will consult the
file and execute any commands.
current file when booting and then halt. The remaining arguments are
then passed to YAP. Note that YAP will skip the first lines if they
start with @code{#} (the comment sign for Unix's shell). YAP will
consult the file and execute any commands.
A slightly more sophisticated example is:
@example
@cartouche
#!/usr/bin/yap -L $0 "$@"
#!/usr/bin/yap -L
#
# Hello World script file using Yap
#
@ -923,6 +923,58 @@ The @code{initialization} directive tells Yap to execute the goal main
after consulting the file. Source code is thus compiled and @code{main}
executed at the end.
By default, arguments to a script are considered arguments to YAP. As an
example, consider the following script @code{dump_args}:
@example
@cartouche
#!/usr/bin/yap -L
main( [] ).
main( [H|T] ) :-
write( H ), nl,
main( T ).
:- unix( argv(AllArgs) ), main( AllArgs ).
@end cartouche
@end example
If you this run this script with the arguments:
@example
./dump_args -s 10000
@end example
@noindent
the script will start an YAP process with stack size @code{10MB}, and
the list of arguments to the process will be empty.
Often one wants to run the script as any other program, and for this it
is convenient to ignore arguments to YAP. This is possible by using
@code{L --} as in the next version of @code{dump_args}:
@example
@cartouche
#!/usr/bin/yap -L --
main( [] ).
main( [H|T] ) :-
write( H ), nl,
main( T ).
:- unix( argv(AllArgs) ), main( AllArgs ).
@end cartouche
@end example
The @code{--} indicates the next arguments are not for YAP. Instead,
they must be sent directly to the @code{argv} builtin. Hence, running
@example
./dump_args test
@end example
@noindent
will write @code{test} on the standard output.
@node Syntax, Loading Programs, Run, Top
@chapter Syntax
@ -1547,6 +1599,13 @@ directories are the places where files specified in the form
@code{consult/1}, @code{reconsult/1}, @code{use_module/1} or
@code{ensure_loaded/1}.
@item prolog_file_name(+@var{Name},-@var{FullPath})
@findex prolog_file_name/2
@syindex prolog_file_name/1
@cnindex prolog_file_name/2
Unify @var{FullPath} with the absolute path YAP would use to consult
file @var{Name}.
@item public @var{P} [ISO]
@findex public/1 (directive)
@snindex public/1 (directive)
@ -4510,11 +4569,13 @@ support may go away in future versions.
@findex abolish/1
@saindex abolish/1
@caindex abolish/1
Deletes the predicate given by @var{PredSpec} from the database. The
Deletes the predicate given by @var{PredSpec} from the database. If
@var{PredSpec} is an unbound variable, delete all predicates for the
current module. The
specification must include the name and arity, and it may include module
information. Under @t{iso} language mode this builtin will only abolish
dynamic procedures. Under other modes it will abolish any procedures, as
long as they are not currently in use.
long as they are not currently in use.
@item abolish(+@var{P},+@var{N})
@findex abolish/2
@ -4609,7 +4670,13 @@ Lists predicate @var{P} if its source code is available.
@findex portray_clause/1
@syindex portray_clause/1
@cnindex portray_clause/1
Write clause @var{C} as if written by listing.
Write clause @var{C} as if written by @code{listing/0}.
@item portray_clause(+@var{S},+@var{C})
@findex portray_clause/2
@syindex portray_clause/2
@cnindex portray_clause/2
Write clause @var{C} on stream @var{S} as if written by @code{listing/0}.
@item current_atom(@var{A})
@findex current_atom/1
@ -7233,6 +7300,159 @@ YAP does not currently support opening a @code{charsio} stream in
@section Calling The Operating System from YAP
@cindex Operating System Utilities
Yap now provides a library of system utilities compatible with the
SICStus Prolog system library. This library extends and to some point
replaces the functionality of Operating System access routines. The
library includes Unix/Linux and Win32 @code{C} code. They
are available through the @code{use_module(library(system))} command.
@table @code
@item datime(datime(-@var{Year}, -@var{Month}, -@var{DayOfTheMonth},
-@var{Hour}, -@var{Minute}, -@var{Second})
@findex datime/1
@syindex datime/1
@cnindex datime/1
The @code{datime/1} procedure returns the current date and time, with
information on @var{Year}, @var{Month}, @var{DayOfTheMonth},
@var{Hour}, @var{Minute}, and @var{Second}. The @var{Hour} is returned
on local time. This function uses the WIN32
@code{GetLocalTime} function or the Unix @code{localtime} function.
@example
?- datime(X).
X = datime(2001,5,28,15,29,46) ?
@end example
@item delete_file(+@var{File})
@findex delete_file/1
@syindex delete_file/1
@cnindex delete_file/1
The @code{delete_file/1} procedure removes file @var{File}. If
@var{File} is a directory, remove the directory @emph{and all its
subdirectories}.
@example
?- delete_file(x).
@end example
@item delete_file(+@var{File},+@var{Opts})
@findex delete_file/2
@syindex delete_file/2
@cnindex delete_file/2
The @code{delete_file/2} procedure removes file @var{File} according to
options @var{Opts}. These options are @code{directory} if one should
remove directories, @code{recursive} if one should remove directories
recursively, and @code{ignore} if errors are not to be reported.
This example is equivalent to using the @code{delete_file/1} predicate:
@example
?- delete_file(x, [recursive]).
@end example
@item directory_files(+@var{Dir},+@var{List})
@findex directory_files/2
@syindex directory_files/2
@cnindex directory_files/2
Given a directory @var{Dir}, @code{directory_files/2} procedures a
listing of all files and directories in the directory:
@example
?- directory_files('.',L), writeq(L).
['Makefile.~1~','sys.so','Makefile','sys.o',x,..,'.']
@end example
The predicates uses the @code{dirent} family of routines in Unix
environments, and @code{findfirst} in WIN32.
@item file_exists(+@var{File})
@findex file_exists/1
@syindex file_exists/1
@cnindex file_exists/1
The atom @var{File} corresponds to an existing file.
@item file_exists(+@var{File},+@var{Permissions})
@findex file_exists/2
@syindex file_exists/2
@cnindex file_exists/2
The atom @var{File} corresponds to an existing file with permissions
compatible with @var{Permissions}. YAP currently only accepts for
permissions to be described as a number. The actual meaning of this
number is Operating System dependent.
@item file_property(+@var{File},?@var{Property})
@findex file_property/2
@syindex file_property/2
@cnindex file_property/2
The atom @var{File} corresponds to an existing file, and @var{Property}
will be unified with a property of this file. The poperties are of the
form @code{type(@var{Type))}, which gives whether the file is a regular
file, a directory, a fifo file, or of unknown type;
@code{size(@var{Size))}, with gives the size for a file, and
@code{mod_time(@var{Time))}, which gives the last time a file was
modified according to some Operating System dependent
timestamp. Properties can be obtained through backtracking:
@example
?- file_property('Makefile',P).
P = type(regular) ? ;
P = size(2375) ? ;
P = mod_time(990826911) ? ;
no
@end example
@item make_directory(+@var{Dir})
@findex make_directory/2
@syindex make_directory/2
@cnindex make_directory/2
Create a directory @var{Dir}. The name of the directory must be an atom.
@item rename_file(+@var{OldFile},+@var{NewFile})
@findex rename_file/2
@syindex rename_file/2
@cnindex rename_file/2
Create file @var{OldFile} to @var{NewFile}. This predicate uses the
@code{C} builtin function @code{rename}.
@item environ(?@var{EnvVar},+@var{EnvValue})
@findex environ/2
@syindex environ/2
@cnindex environ/2
Unify environment variable @var{EnvVar} with its value @var{EnvValue},
if there is one. This predicate is backtrackable in Unix systems, but
not currently in Win32 configurations.
@example
?- environ('HOME',X).
X = 'C:\\cygwin\\home\\administrator' ?
@end example
@item
exec(+@var{Command},[+@var{InputStream},+@var{OutputStream},,+@var{ErrorStream},
-@var{Status})
@findex exec/3
@syindex exec/3
@cnindex exec/3
Execute command @var{Command} with its streams connected to
@var{InputStream}, @var{OutputStream}, and @var{ErrorStream}. The result
for the command is returned in @var{Status}.
@item working_directory(-@var{CurDir},?@var{NextDir})
@findex working_directory/2
@syindex working_directory/2
@cnindex working_directory/2
Fetch the current directory at @var{CurDir}. If @var{NextDir} is bound
to an atom, make its value the current working directory.
@end table
@node Terms, Timeout, System, Library
@section Utilities On Terms
@cindex utilities on terms
@ -12520,7 +12740,8 @@ compatible built-in.
implemented in YAP (note that this is only a partial list):
@code{call_cleanup/1}, @code{file_search_path/2},
@code{stream_interrupt/3}, @code{reinitialize/0}, @code{help/0},
@code{help/1}, @code{module/3}, @code{trimcore/0}.
@code{help/1}, @code{trimcore/0}, @code{load_files/1},
@code{load_files/2}, and @code{require/1}.
The previous list is incomplete. We also cannot guarantee full
compatibility for other built-ins (although we will try to address any

View File

@ -275,12 +275,48 @@ check_mode(write,1, _) :- !.
check_mode(Mode, G) :-
throw(domain_error(io_mode,Mode),G).
shell :-
G = shell,
get_shell(Shell),
atom_codes(FullCommand, Shell),
exec_command(FullCommand, '$stream'(0),'$stream'(0), '$stream'(1), PID, Error),
handle_system_error(Error, off, G),
wait(PID, _Status, Error),
handle_system_error(Error, off, G).
shell(Command) :-
G = shell(Command),
check_command(Command, G),
get_shell(Shell),
atom_codes(Command, SC),
append(Shell, SC, ShellCommand),
atom_codes(FullCommand, ShellCommand),
exec_command(FullCommand, '$stream'(0),'$stream'(0), '$stream'(1), PID, Error),
handle_system_error(Error, off, G),
wait(PID, _Status, Error),
handle_system_error(Error, off, G).
shell(Command, Status) :-
G = shell(Command, Status),
check_command(Command, G),
do_shell(Status, Error),
( var(Error) -> Status = 0 ; Status = Error).
get_shell(Shell),
atom_codes(Command, SC),
append(Shell, SC, ShellCommand),
atom_codes(FullCommand, ShellCommand),
exec_command(FullCommand, '$stream'(0),'$stream'(0), '$stream'(1), PID, Error),
handle_system_error(Error, off, G),
wait(PID, Status,Error),
handle_system_error(Error, off, G).
get_shell(Shell) :-
getenv('SHELL', Shell0), !,
atom_codes(Shell0, Codes),
append(Codes," -c ", Shell).
get_shell(COMSPEC) :-
getenv('COMPSEC', Shell),
atom_codes(Shell0, Codes),
append(Codes," /c ", Shell).
system(Command, Status) :-
G = system(Command, Status),
check_command(Command, G),

View File

@ -64,7 +64,7 @@ sys.so: sys.o
#
DLLTOOL=dlltool
DLLNAME=sys.dll
DLL_LIBS=-lcrtdll -L../.. -lWYap
DLL_LIBS=-L /usr/lib/mingw -lmoldname -lcrtdll -lkernel32 -L../.. -lWYap
BASE_FILE=sys.base
EXP_FILE=sys.exp
DEF_FILE=$(srcdir)/sys.def

View File

@ -54,7 +54,13 @@
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
#if HAVE_DIRECT_H
#include <direct.h>
#endif
#if defined(__MINGW32__) || _MSC_VER
#include <windows.h>
#include <process.h>
#endif
#ifdef __MINGW32__
#ifdef HAVE_ENVIRON
#undef HAVE_ENVIRON
@ -68,7 +74,16 @@ static int
datime(void)
{
Term tf, out[6];
#ifdef HAVE_TIME
#if defined(__MINGW32__) || _MSC_VER
SYSTEMTIME stime;
GetLocalTime(&stime);
out[0] = MkIntTerm(stime.wYear);
out[1] = MkIntTerm(stime.wMonth);
out[2] = MkIntTerm(stime.wDay);
out[3] = MkIntTerm(stime.wHour);
out[4] = MkIntTerm(stime.wMinute);
out[5] = MkIntTerm(stime.wSecond);
#elif HAVE_TIME
time_t tp;
if ((tp = time(NULL)) == -1) {
@ -106,6 +121,32 @@ list_directory(void)
Term tf = MkAtomTerm(LookupAtom("[]"));
char *buf = AtomName(AtomOfTerm(ARG1));
#if defined(__MINGW32__) || _MSC_VER
struct _finddata_t c_file;
char bs[BUF_SIZE];
long hFile;
bs[0] = '\0';
#if HAVE_STRNCPY
strncpy(bs, buf, BUF_SIZE);
#else
strcpy(bs, buf);
#endif
#if HAVE_STRNCAT
strncat(bs, "/*", BUF_SIZE);
#else
strncat(bs, "/*");
#endif
if ((hFile = _findfirst(bs, &c_file)) == -1L) {
return(unify(ARG2,tf));
}
tf = MkPairTerm(MkAtomTerm(LookupAtom(c_file.name)), tf);
while (_findnext( hFile, &c_file) == 0) {
Term ti = MkAtomTerm(LookupAtom(c_file.name));
tf = MkPairTerm(ti, tf);
}
_findclose( hFile );
#else
#if HAVE_OPENDIR
{
DIR *de;
@ -121,6 +162,7 @@ list_directory(void)
closedir(de);
}
#endif /* HAVE_OPENDIR */
#endif
return(unify(ARG2, tf));
}
@ -128,10 +170,15 @@ static int
p_unlink(void)
{
char *fd = AtomName(AtomOfTerm(ARG1));
if (unlink(fd) == -1) {
/* return an error number */
return(unify(ARG2, MkIntTerm(errno)));
}
#if defined(__MINGW32__) || _MSC_VER
if (_unlink(fd) == -1)
#else
if (unlink(fd) == -1)
#endif
{
/* return an error number */
return(unify(ARG2, MkIntTerm(errno)));
}
return(TRUE);
}
@ -139,7 +186,11 @@ static int
p_mkdir(void)
{
char *fd = AtomName(AtomOfTerm(ARG1));
#if defined(__MINGW32__) || _MSC_VER
if (_mkdir(fd) == -1) {
#else
if (mkdir(fd, 0777) == -1) {
#endif
/* return an error number */
return(unify(ARG2, MkIntTerm(errno)));
}
@ -150,7 +201,11 @@ static int
p_rmdir(void)
{
char *fd = AtomName(AtomOfTerm(ARG1));
#if defined(__MINGW32__) || _MSC_VER
if (_rmdir(fd) == -1) {
#else
if (rmdir(fd) == -1) {
#endif
/* return an error number */
return(unify(ARG2, MkIntTerm(errno)));
}
@ -181,7 +236,7 @@ static int
file_property(void)
{
char *fd;
#if HAVE_LSTAT
#if HAVE_LSTAT
struct stat buf;
fd = AtomName(AtomOfTerm(ARG1));
@ -189,9 +244,9 @@ file_property(void)
/* return an error number */
return(unify(ARG6, MkIntTerm(errno)));
}
if (S_ISREG(buf.st_mode))
if (buf.st_mode & _S_IFREG)
unify(ARG2, MkAtomTerm(LookupAtom("regular")));
else if (S_ISDIR(buf.st_mode))
else if (buf.st_mode & _S_IFDIR)
unify(ARG2, MkAtomTerm(LookupAtom("directory")));
else if (S_ISFIFO(buf.st_mode))
unify(ARG2, MkAtomTerm(LookupAtom("fifo")));
@ -201,10 +256,25 @@ file_property(void)
unify(ARG2, MkAtomTerm(LookupAtom("socket")));
else
unify(ARG2, MkAtomTerm(LookupAtom("unknown")));
#elif defined(__MINGW32__) || _MSC_VER
/* for some weird reason _stat did not work with mingw32 */
struct stat buf;
fd = AtomName(AtomOfTerm(ARG1));
if (stat(fd, &buf) != 0) {
/* return an error number */
return(unify(ARG6, MkIntTerm(errno)));
}
if (buf.st_mode & S_IFREG)
unify(ARG2, MkAtomTerm(LookupAtom("regular")));
else if (buf.st_mode & S_IFDIR)
unify(ARG2, MkAtomTerm(LookupAtom("directory")));
else
unify(ARG2, MkAtomTerm(LookupAtom("unknown")));
#endif
unify(ARG3, MkIntTerm(buf.st_size));
unify(ARG4, MkIntTerm(buf.st_mtime));
unify(ARG5, MkIntTerm(buf.st_mode));
#endif
return(TRUE);
}
@ -221,7 +291,11 @@ p_mktemp(void)
#else
strcpy(tmp, s);
#endif
#if defined(__MINGW32__) || _MSC_VER
if ((s = _mktemp(tmp)) == NULL) {
#else
if ((s = mktemp(tmp)) == NULL) {
#endif
/* return an error number */
return(unify(ARG3, MkIntTerm(errno)));
}
@ -247,12 +321,20 @@ static int
p_environ(void)
{
#if HAVE_ENVIRON
#if defined(__MINGW32__) || _MSC_VER
extern char **_environ;
#else
extern char **environ;
#endif
Term t1 = ARG1;
Int i;
i = IntOfTerm(t1);
#if defined(__MINGW32__) || _MSC_VER
if (_environ[i] == NULL)
#else
if (environ[i] == NULL)
#endif
return(FALSE);
else {
Term t = BufferToString(environ[i]);
@ -264,6 +346,37 @@ p_environ(void)
#endif
}
#if defined(__MINGW32__) || _MSC_VER
static int
get_handle(Term ti, int fd, Term tzero)
{
if (ti == tzero) {
int new_fd = _dup(fd);
_close(fd);
return(new_fd);
} else {
int sd = YapStreamToFileNo(ti), new_fd;
if (sd == fd)
return(-1);
new_fd = _dup(fd);
_close(fd);
_dup2(sd, fd);
return(new_fd);
}
}
static void
restore_descriptor(int fd0, int fd, Term t, Term tzero)
{
if (fd != -1) {
if (t != tzero) {
_close(fd0);
}
_dup2(fd, fd0);
}
}
#endif
/* execute a command as a detached process */
static int
execute_command(void)
@ -272,6 +385,46 @@ execute_command(void)
Term tzero = MkIntTerm(0);
int res;
int inpf, outf, errf;
#if defined(__MINGW32__) || _MSC_VER
DWORD CreationFlags = 0;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
inpf = get_handle(ti, 0, tzero);
outf = get_handle(to, 1, tzero);
errf = get_handle(te, 2, tzero);
if (inpf != -1 || outf != -1 || errf != -1) {
/* we are keeping the curent streams */
CreationFlags = DETACHED_PROCESS;
}
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL; /* inherit */
StartupInfo.lpTitle = NULL; /* we do not create a new console window */
StartupInfo.dwFlags = STARTF_USESTDHANDLES;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = NULL;
StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
/* got stdin, stdout and error as I like it */
if (CreateProcess(NULL,
AtomName(AtomOfTerm(ARG1)),
NULL,
NULL,
TRUE,
CreationFlags,
NULL,
NULL,
&StartupInfo,
&ProcessInformation) == FALSE) {
return(unify(ARG6, MkIntTerm(GetLastError())));
}
restore_descriptor(0, inpf, ti, tzero);
restore_descriptor(1, outf, to, tzero);
restore_descriptor(2, errf, te, tzero);
res = ProcessInformation.dwProcessId;
return(unify(ARG5,MkIntTerm(res)));
#else /* UNIX CODE */
/* process input first */
if (ti == tzero) {
inpf = open("/dev/null", O_RDONLY);
@ -341,50 +494,7 @@ execute_command(void)
close(errf);
return(unify(ARG5,MkIntTerm(res)));
}
}
/* execute a command as a detached process */
static int
shell(void)
{
char *command = AtomName(AtomOfTerm(ARG1));
int pid;
/* we are now ready to fork */
if ((pid = fork()) < 0) {
/* return an error number */
return(unify(ARG2, MkIntTerm(errno)));
} else if (pid == 0) {
char *argv[4];
char *shell;
/* child */
/* close current streams, but not std streams */
YapCloseAllOpenStreams();
#if HAVE_GETENV
shell = getenv ("SHELL");
if (shell == NULL)
shell = "/bin/sh";
#endif
argv[0] = shell;
argv[1] = "-c";
argv[2] = command;
argv[3] = NULL;
execv("/bin/sh", argv);
exit(127);
/* we have the streams where we want them, just want to execute now */
} else {
do {
int status;
/* check for interruptions */
if (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR)
return -1;
return(unify(ARG2, MkIntTerm(errno)));
} else
return(TRUE);
} while(TRUE);
}
#endif /* UNIX code */
}
/* execute a command as a detached process */
@ -403,6 +513,21 @@ static int
p_wait(void)
{
Int pid = IntOfTerm(ARG1);
#if defined(__MINGW32__) || _MSC_VER
HANDLE proc = OpenProcess(STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, FALSE, pid);
DWORD ExitCode;
if (proc == NULL) {
return(unify(ARG3, MkIntTerm(GetLastError())));
}
if (WaitForSingleObject(proc, INFINITE) == WAIT_FAILED) {
return(unify(ARG3, MkIntTerm(GetLastError())));
}
if (GetExitCodeProcess(proc, &ExitCode) == 0) {
return(unify(ARG3, MkIntTerm(GetLastError())));
}
CloseHandle(proc);
return(unify(ARG2, MkIntTerm(ExitCode)));
#else
do {
int status;
@ -415,6 +540,7 @@ p_wait(void)
return(unify(ARG2, MkIntTerm(status)));
}
} while(TRUE);
#endif
}
/* execute a command as a detached process */
@ -428,10 +554,18 @@ p_popen(void)
int flags;
#if HAVE_POPEN
#if defined(__MINGW32__) || _MSC_VER
/* This will only work for console applications. FIX */
if (mode == 0)
pfd = _popen(command, "r");
else
pfd = _popen(command, "w");
#else
if (mode == 0)
pfd = popen(command, "r");
else
pfd = popen(command, "w");
#endif
if (pfd == NULL) {
return(unify(ARG4, MkIntTerm(errno)));
}
@ -461,6 +595,11 @@ p_sleep(void)
else
usecs = tfl*1000;
}
#if defined(__MINGW32__) || _MSC_VER
if (secs) usecs = secs*1000;
Sleep(usecs);
out = 0;
#else
#if HAVE_USLEEP
if (usecs > 0) {
usleep(usecs);
@ -472,6 +611,7 @@ p_sleep(void)
out = sleep(secs);
}
#endif
#endif /* defined(__MINGW32__) || _MSC_VER */
return(unify(ARG2, MkIntTerm(out)));
}
@ -480,13 +620,21 @@ p_sleep(void)
static int
host_name(void)
{
char name[256];
#if defined(__MINGW32__) || _MSC_VER
char name[MAX_COMPUTERNAME_LENGTH+1];
DWORD nSize = MAX_COMPUTERNAME_LENGTH+1;
if (GetComputerName(name, &nSize) == 0) {
return(unify(ARG2, MkIntTerm(GetLastError())));
}
#else
#if HAVE_GETHOSTNAME
char name[256];
if (gethostname(name, 256) == -1) {
/* return an error number */
return(unify(ARG2, MkIntTerm(errno)));
}
#endif
#endif /* defined(__MINGW32__) || _MSC_VER */
return(unify(ARG1, MkAtomTerm(LookupAtom(name))));
}
@ -495,26 +643,42 @@ host_id(void)
{
#if HAVE_GETHOSTID
return(unify(ARG1, MkIntTerm(gethostid())));
#else
return(unify(ARG1, MkIntTerm(0)));
#endif
}
static int
pid(void)
{
#if defined(__MINGW32__) || _MSC_VER
return(unify(ARG1, MkIntTerm(_getpid())));
#else
return(unify(ARG1, MkIntTerm(getpid())));
#endif
}
static int
p_kill(void)
{
#if HAVE_KILL
#if defined(__MINGW32__) || _MSC_VER
/* Windows does not support cross-process signals, so we shall do the
SICStus thing and assume that a signal to a process will
always kill it */
HANDLE proc = OpenProcess(STANDARD_RIGHTS_REQUIRED|PROCESS_TERMINATE, FALSE, IntOfTerm(ARG1));
if (proc == NULL) {
return(unify(ARG3, MkIntTerm(GetLastError())));
}
if (TerminateProcess(proc, -1) == 0) {
return(unify(ARG3, MkIntTerm(GetLastError())));
}
CloseHandle(proc);
#else
if (kill(IntOfTerm(ARG1), IntOfTerm(ARG2)) < 0) {
/* return an error number */
return(unify(ARG2, MkIntTerm(errno)));
return(unify(ARG3, MkIntTerm(errno)));
}
#else
oops
#endif
#endif /* defined(__MINGW32__) || _MSC_VER */
return(TRUE);
}
@ -542,7 +706,6 @@ init_sys(void)
UserCPredicate("dir_separator", dir_separator, 1);
UserCPredicate("p_environ", p_environ, 2);
UserCPredicate("exec_command", execute_command, 6);
UserCPredicate("do_shell", shell, 2);
UserCPredicate("do_system", do_system, 2);
UserCPredicate("popen", p_popen, 4);
UserCPredicate("wait", p_wait, 3);
@ -561,9 +724,9 @@ init_sys(void)
#include <windows.h>
int WINAPI PROTO(win_system, (HANDLE, DWORD, LPVOID));
int WINAPI PROTO(win_sys, (HANDLE, DWORD, LPVOID));
int WINAPI win_system(HANDLE hinst, DWORD reason, LPVOID reserved)
int WINAPI win_sys(HANDLE hinst, DWORD reason, LPVOID reserved)
{
switch (reason)
{
@ -576,6 +739,6 @@ int WINAPI win_system(HANDLE hinst, DWORD reason, LPVOID reserved)
case DLL_THREAD_DETACH:
break;
}
p return 1;
return 1;
}
#endif

View File

@ -866,6 +866,8 @@ break :- '$get_value'('$break',BL), NBL is BL+1,
;
throw(error(permission_error(input,stream,Y),consult(X)))
).
'$consult'(M:X) :-
'$mod_switch'(M,'$consult'(X)).
'$consult'(library(X)) :- !,
'$find_in_path'(library(X),Y),
( open(Y,'$csult',Stream), !,

View File

@ -15,6 +15,9 @@
* *
*************************************************************************/
ensure_loaded(V) :-
'$ensure_loaded'(V).
'$ensure_loaded'(V) :- var(V), !,
throw(error(instantiation_error,ensure_loaded(V))).
'$ensure_loaded'([]) :- !.
@ -40,6 +43,8 @@
throw(error(permission_error(input,stream,X),ensure_loaded(X)))
).
'$ensure_loaded'(M:X) :-
'$mod_switch'(M,'$ensure_loaded'(X)).
'$ensure_loaded'(library(X)) :- !,
'$find_in_path'(library(X),Y),
( open(Y,'$csult',Stream), !,
@ -100,6 +105,8 @@ reconsult(Fs) :-
;
throw(error(permission_error(input,stream,X),reconsult(X)))
).
'$reconsult'(M:X) :-
'$mod_switch'(M,'$reconsult'(X)).
'$reconsult'(library(X)) :- !,
'$find_in_path'(library(X),Y),
( open(Y,'$csult',Stream), !,

View File

@ -54,6 +54,12 @@ listing(_).
'$write_clause'(Pred,Body),
fail.
portray_clause(Stream, Clause) :-
current_output(OldStream),
set_output(Stream),
portray_clause(Clause),
set_output(OldStream).
portray_clause((Pred:-Body)) :- !,
'$beautify_vars'((Pred:-Body)),
'$write_clause'(Pred,Body).

View File

@ -249,7 +249,6 @@ $check_import(_,_,_,_).
;
true
).
'$abolish_module_data'(M) :-
@ -267,12 +266,12 @@ $check_import(_,_,_,_).
'$prepare_body_with_correct_modules'(B, M, B0),
'$module_u_vars'(H,UVars), % collect head variables in
% expanded positions
'$module_expansion'(B0,B1,BO,M,UVars). % expand body
'$module_expansion'(B0,B1,BO,M,M,M,UVars). % expand body
'$module_expansion'((H:-B),(H:-B1),(H:-BO)) :-
'$module_u_vars'(H,UVars), % collect head variables in
% expanded positions
'$current_module'(M),
'$module_expansion'(B,B1,BO,M,UVars). % expand body
'$module_expansion'(B,B1,BO,M,M,M,UVars). % expand body
% $trace_module((H:-B),(H:-B1)).
% expand module names in a body
@ -295,15 +294,15 @@ $check_import(_,_,_,_).
'$prepare_body_with_correct_modules'(G,M,M:G).
$trace_module(X) :-
'$trace_module'(X) :-
telling(F),
tell('P0:debug'),
write(X),nl,
tell(F), fail.
$trace_module(X).
'$trace_module'(X).
$trace_module(X,Y) :- X==Y, !.
$trace_module(X,Y) :-
'$trace_module'(X,Y) :- X==Y, !.
'$trace_module'(X,Y) :-
telling(F),
tell('~/.dbg.modules'),
write('***************'), nl,
@ -330,72 +329,60 @@ $trace_module(X,Y).
'$execute0'(G).
'$complete_goal_expansion'(G, M, _, G1, G2, HVars) :-
'$pred_goal_expansion_on',
user:goal_expansion(G,M,GI), !,
'$prepare_body_with_correct_modules'(GI, M, GF),
'$module_expansion'(GF,G1,G2,M,HVars).
'$complete_goal_expansion'(G, _, _, G, GF, _) :-
'$system_predicate'(G), !,
'$c_built_in'(G,GF).
'$complete_goal_expansion'(G, Mod, Mod, G, G, _) :- '$current_module'(Mod), !.
'$complete_goal_expansion'(G, GMod, _, GMod:G, GMod:G, _).
% expand module names in a body
'$module_expansion'(V,call(M:V),call(M:V),M,HVars) :- var(V), !.
'$module_expansion'((A,B),(A1,B1),(AO,BO),M,HVars) :- !,
'$module_expansion'(A,A1,AO,M,HVars),
'$module_expansion'(B,B1,BO,M,HVars).
'$module_expansion'((A;B),(A1;B1),(AO;BO),M,HVars) :- !,
'$module_expansion'(A,A1,AO,M,HVars),
'$module_expansion'(B,B1,BO,M,HVars).
'$module_expansion'((A->B),(A1->B1),(AO->BO),M,HVars) :- !,
'$module_expansion'(A,A1,AO,M,HVars),
'$module_expansion'(B,B1,BO,M,HVars).
'$module_expansion'(true,true,true,_,_) :- !.
'$module_expansion'(fail,fail,fail,_,_) :- !.
'$module_expansion'(false,false,false,_,_) :- !.
% args are:
% goals to expand
% code to pass to compiler
% code to pass to listing
% current module for looking up preds
% current module for fixing up meta-call arguments
% current module for predicate
% head variables.
'$module_expansion'(V,call(MM:V),call(MM:V),M,MM,TM,HVars) :- var(V), !.
'$module_expansion'((A,B),(A1,B1),(AO,BO),M,MM,TM,HVars) :- !,
'$module_expansion'(A,A1,AO,M,MM,TM,HVars),
'$module_expansion'(B,B1,BO,M,MM,TM,HVars).
'$module_expansion'((A;B),(A1;B1),(AO;BO),M,MM,TM,HVars) :- !,
'$module_expansion'(A,A1,AO,M,MM,TM,HVars),
'$module_expansion'(B,B1,BO,M,MM,TM,HVars).
'$module_expansion'((A->B),(A1->B1),(AO->BO),M,MM,TM,HVars) :- !,
'$module_expansion'(A,A1,AO,M,MM,TM,HVars),
'$module_expansion'(B,B1,BO,M,MM,TM,HVars).
'$module_expansion'(true,true,true,_,_,_,_) :- !.
'$module_expansion'(fail,fail,fail,_,_,_,_) :- !.
'$module_expansion'(false,false,false,_,_,_,_) :- !.
% if I don't know what the module is, I cannot do anything to the goal,
% so I just put a call for later on.
'$module_expansion'(M:G,call(M:G),call(M:G),_,HVars) :- var(M), !.
'$module_expansion'(M:(M1:G),G1,GO,M0,HVars) :- !,
'$module_expansion'(M1:G,G1,GO,M0,HVars).
'$module_expansion'(M:G,G1,GO,Mod,HVars) :- !,
'$module_expansion'(M:G,call(M:G),call(M:G),_,_,_,HVars) :- var(M), !.
% if M1 is given explicitly process G within M1's context.
'$module_expansion'(M:G,G1,GO,Mod,MM,TM,HVars) :- !,
% is this imported from some other module M1?
( '$imported_pred'(G, M, M1) ->
% continue recursively...
'$module_expansion'(M1:G,G1,GO,Mod,HVars)
'$module_expansion'(G,G1,GO,M1,M,TM,HVars)
;
(
'$meta_expansion_of_subgoal'(G, M, Mod, NG, HVars, NM)
'$meta_expansion'(M, M, G, NG, HVars)
;
G = NG, M = NM
G = NG
),
'$complete_goal_expansion'(NG, NM, Mod, G1, GO, HVars)
'$complete_goal_expansion'(NG, M, M, TM, G1, GO, HVars)
).
%
% next, check if this is something imported.
%
'$module_expansion'(G, G1, GO, CurMod, HVars) :-
'$module_expansion'(G, G1, GO, CurMod, MM, TM, HVars) :-
% is this imported from some other module M1?
( '$imported_pred'(G, CurMod, M1) ->
% continue recursively...
'$module_expansion'(M1:G,G1,GO,CurMod,HVars)
'$module_expansion'(G, G1, GO, M1, MM, TM, HVars)
;
( '$meta_expansion_of_subgoal'(G, CurMod, CurMod, GI, HVars, GoalModule)
( '$meta_expansion'(CurMod, MM, G, GI, HVars)
;
GI = G, GoalModule = CurMod
GI = G
),
'$complete_goal_expansion'(GI, GoalModule, CurMod, G1, GO, HVars)
'$complete_goal_expansion'(GI, CurMod, MM, TM, G1, GO, HVars)
).
'$meta_expansion_of_subgoal'(G, GMod, CurMod, GF, HVars, ImportedMod) :-
functor(G,F,N),
'$recorded'('$import','$import'(ImportedMod,GMod,F,N),_), !,
'$meta_expansion'(ImportedMod, CurMod, G, GF, HVars).
'$meta_expansion_of_subgoal'(G, GMod, CurMod, NG, HVars, GMod) :-
'$meta_expansion'(GMod, CurMod, G, NG, HVars).
'$imported_pred'(G, ImportingMod, ExportingMod) :-
'$undefined'(ImportingMod:G),
@ -403,27 +390,40 @@ $trace_module(X,Y).
'$recorded'('$import','$import'(ExportingMod,ImportingMod,F,N),_),
ExportingMod \= ImportingMod.
% args are:
% goal to expand
% current module for looking up pred
% current module from top-level clause
% goal to pass to compiler
% goal to pass to listing
% head variables.
'$complete_goal_expansion'(G, M, CM, TM, G1, G2, HVars) :-
'$pred_goal_expansion_on',
user:goal_expansion(G,M,GI), !,
'$module_expansion'(GI,G1,G2,M,CM,TM,HVars).
'$complete_goal_expansion'(G, _, _, _, G, GF, _) :-
'$system_predicate'(G), !,
'$c_built_in'(G,GF).
'$complete_goal_expansion'(G, Mod, _, Mod, G, G, _) :- !.
'$complete_goal_expansion'(G, GMod, _, _, GMod:G, GMod:G, _).
% meta_predicate declaration
% records $meta_predicate(SourceModule,Functor,Arity,Declaration)
% directive now meta_predicate Ps :- $meta_predicate(Ps).
'$meta_predicate'((P,Ps)) :- !,
$meta_predicate(P),
$meta_predicate(Ps).
'$meta_predicate'(P),
'$meta_predicate'(Ps).
'$meta_predicate'(P) :-
functor(P,F,N),
'$current_module'(M1),
( M1 = prolog -> M = _ ; M1 = M),
% ( '$recorded'($meta_predicate,$meta_predicate(M,F,N,_),R), erase(R), fail;
% true
% ),
% recorda('$meta_predicate','$meta_predicate'(M,F,N,P),_),
( retractall('$meta_predicate'(F,M,N,_)), fail ; true),
asserta($meta_predicate(F,M,N,P)),
asserta('$meta_predicate'(F,M,N,P)),
'$flags'(P, Fl, Fl),
NFlags is Fl \/ 0x200000,
'$flags'(P, Fl, NFlags).
'$flags'(P, Fl, NFlags).
% return list of vars in expanded positions on the head of a clause.
%
@ -432,8 +432,8 @@ $trace_module(X,Y).
'$module_u_vars'(H,UVars) :-
functor(H,F,N),
'$current_module'(M),
% '$recorded'($meta_predicate,$meta_predicate(M,F,N,D),_), !,
$meta_predicate(F,M,N,D), !,
% '$recorded'('$meta_predicate','$meta_predicate'(M,F,N,D),_), !,
'$meta_predicate'(F,M,N,D), !,
'$module_u_vars'(N,D,H,UVars).
'$module_u_vars'(H,[]).
@ -490,15 +490,15 @@ current_module(Mod,TFN) :-
source_module(Mod) :-
'$current_module'(Mod).
$member(X,[X|_]) :- !.
$member(X,[_|L]) :- $member(X,L).
'$member'(X,[X|_]) :- !.
'$member'(X,[_|L]) :- '$member'(X,L).
%
% this declaration should only be here, as meta_predicates should belong
% to the user module, not to the prolog module
:- meta_predicate
% [:,:],
abolish(:),
abolish(:,+),
all(?,:,?),
@ -512,8 +512,11 @@ $member(X,[_|L]) :- $member(X,L).
call(:),
clause(:,?),
clause(:,?,?),
compile(:),
consult(:),
current_predicate(:),
current_predicate(?,:),
ensure_loaded(:),
findall(?,:,?),
findall(?,:,?,?),
if(:,:,:),
@ -524,6 +527,7 @@ $member(X,[_|L]) :- $member(X,L).
retract(:),
retract(:,?),
retractall(:),
reconsult(:),
setof(?,:,?),
spy(:),
^(+,:),

View File

@ -324,8 +324,8 @@ abolish(X) :-
abolish(X) :-
'$old_abolish'(X).
'$new_abolish'(V) :-
'$check_error_in_predicate_indicator'(V, abolish(V)), !.
'$new_abolish'(V) :- var(V), !,
'$abolish_all'.
'$new_abolish'(M:PS) :- !,
'$mod_switch'(M,'$new_abolish'(PS)).
'$new_abolish'(Na/Ar) :-
@ -339,6 +339,12 @@ abolish(X) :-
'$current_module'(M),
throw(error(permission_error(modify,static_procedure,Na/Ar),abolish(M:Na/Ar))).
'$abolish_all' :-
current_predicate(_,P),
functor(P, Na, Ar),
'$new_abolish'(Na, Ar),
fail.
'$abolish_all'.
'$check_error_in_predicate_indicator'(V, Msg) :-
var(V), !,
@ -377,7 +383,7 @@ abolish(X) :-
throw(error(type_error(atom,Na), Msg)).
'$old_abolish'(V) :-
'$check_error_in_predicate_indicator'(V, abolish(V)).
'$abolish_all'.
'$old_abolish'(M:N) :- !,
'$mod_switch'(M,'$old_abolish'(N)).
'$old_abolish'([]) :- !.

View File

@ -850,7 +850,9 @@ user_defined_directive(Dir,Action) :-
'$fast_do'(M:G) :- '$mod_switch'(M,G).
'$fast_do'('$spycalls'(G,Res)) :- '$spycalls'(G,Res).
'$fast_do'('$profile_data'(P, Parm, Data)) :- '$profile_data'(P, Parm, Data).
'$fast_do'('$ensure_loaded'(F)) :- '$ensure_loaded'(F).
'$fast_do'('$consult'(F)) :- '$consult'(F).
'$fast_do'('$reconsult'(F)) :- '$reconsult'(F).
'$set_toplevel_hook'(_) :-
'$recorded'('$toplevel_hooks',_,R),

View File

@ -22,7 +22,8 @@
% * -------- YAPOR -------- *
% ***************************
default_sequential(X) :- '$default_sequential'(X), !.
default_sequential(X) :-
'$default_sequential'(X), !.
default_sequential(_).
'$sequential' :-

View File

@ -833,7 +833,7 @@ absolute_file_name(RelFile,AbsFile) :-
'$get_value'(fileerrors,V),
'$set_value'(fileerrors,0),
( open(F,Mode,S), !,
'$user_file_name'(S, AbsFile),
'$file_name'(S, AbsFile),
close(S), '$set_value'(fileerrors,V);
'$set_value'(fileerrors,V), fail).