diff --git a/C/iopreds.c b/C/iopreds.c
index 3f4d4e549..e4329cbfc 100644
--- a/C/iopreds.c
+++ b/C/iopreds.c
@@ -2239,17 +2239,17 @@ p_open (void)
Yap_Error(DOMAIN_ERROR_IO_MODE, t2, "open/3");
return(FALSE);
}
- if (!Yap_TrueFileName (RepAtom (AtomOfTerm (file_name))->StrOfAE, Yap_FileNameBuf, FALSE))
- return (PlIOError (EXISTENCE_ERROR_SOURCE_SINK,file_name,"open/3"));
- sno = GetFreeStreamD();
- if (sno < 0)
- return (PlIOError (SYSTEM_ERROR,TermNil, "new stream not available for open/3"));
- st = &Stream[sno];
/* can never happen */
topts = Deref(ARG4);
if (IsVarTerm(topts) || !IsIntegerTerm(topts))
return(FALSE);
opts = IntegerOfTerm(topts);
+ if (!strncpy(Yap_FileNameBuf, RepAtom (AtomOfTerm (file_name))->StrOfAE, YAP_FILENAME_MAX))
+ return (PlIOError (SYSTEM_ERROR,file_name,"file name is too long in open/3"));
+ sno = GetFreeStreamD();
+ if (sno < 0)
+ return (PlIOError (SYSTEM_ERROR,TermNil, "new stream not available for open/3"));
+ st = &Stream[sno];
/* can never happen */
tenc = Deref(ARG5);
if (IsVarTerm(tenc) || !IsIntegerTerm(tenc))
@@ -4309,7 +4309,7 @@ p_get (void)
static Int
p_get0 (void)
-{ /* '$get0'(Stream,-N) */
+{ /* get0(Stream,-N) */
int sno = CheckStream (ARG1, Input_Stream_f, "get0/2");
Int status;
Int out;
@@ -6014,8 +6014,8 @@ Yap_InitIOPreds(void)
Yap_InitCPred ("$close", 1, p_close, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("flush_output", 1, p_flush, SafePredFlag|SyncPredFlag);
Yap_InitCPred ("$flush_all_streams", 0, p_flush_all_streams, SafePredFlag|SyncPredFlag|HiddenPredFlag);
- Yap_InitCPred ("$get", 2, p_get, SafePredFlag|SyncPredFlag|HiddenPredFlag);
- Yap_InitCPred ("$get0", 2, p_get0, SafePredFlag|SyncPredFlag|HiddenPredFlag);
+ Yap_InitCPred ("get", 2, p_get, SafePredFlag|SyncPredFlag|HiddenPredFlag);
+ Yap_InitCPred ("get0", 2, p_get0, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$get0_line_codes", 2, p_get0_line_codes, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$get_byte", 2, p_get_byte, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$access", 1, p_access, SafePredFlag|SyncPredFlag|HiddenPredFlag);
diff --git a/C/sysbits.c b/C/sysbits.c
index 9c2aeab2d..a15dcd27b 100644
--- a/C/sysbits.c
+++ b/C/sysbits.c
@@ -1589,13 +1589,14 @@ Yap_volume_header(char *file)
return volume_header(file);
}
+/******
+ TODO: rewrite to use wordexp
+ ****/
static int
TrueFileName (char *source, char *root, char *result, int in_lib)
{
- register int ch;
- register char *res0 = result, *work;
- char ares1[YAP_FILENAME_MAX], *res1 = ares1;
- char *var_name;
+ char *res0 = result, *work;
+ char ares1[YAP_FILENAME_MAX];
result[0] = '\0';
#if defined(__MINGW32__) || _MSC_VER
@@ -1610,149 +1611,137 @@ TrueFileName (char *source, char *root, char *result, int in_lib)
}
#endif
/* step 1: eating home information */
- if (source[0] == '~')
- {
- if (dir_separator(source[1]) || source[1] == '\0')
- {
- char *s;
- source++;
+ if (source[0] == '~') {
+ if (dir_separator(source[1]) || source[1] == '\0')
+ {
+ char *s;
+ source++;
#if defined(_WIN32)
- s = getenv("HOMEDRIVE");
- if (s != NULL)
- strncpy (result, getenv ("HOMEDRIVE"), YAP_FILENAME_MAX);
- s = getenv("HOMEPATH");
- if (s != NULL)
- strncpy (result, s, YAP_FILENAME_MAX);
+ s = getenv("HOMEDRIVE");
+ if (s != NULL)
+ strncpy (result, getenv ("HOMEDRIVE"), YAP_FILENAME_MAX);
+ s = getenv("HOMEPATH");
+ if (s != NULL)
+ strncpy (result, s, YAP_FILENAME_MAX);
#else
- s = getenv ("HOME");
- if (s != NULL)
- strncpy (result, s, YAP_FILENAME_MAX);
+ s = getenv ("HOME");
+ if (s != NULL)
+ strncpy (result, s, YAP_FILENAME_MAX);
#endif
- }
+ } else {
#if HAVE_GETPWNAM
- else
- {
- struct passwd *user_passwd;
+ struct passwd *user_passwd;
- source++;
- while (!dir_separator((*res0 = *source)) && *res0 != '\0')
- res0++, source++;
- *res0++ = '\0';
- if ((user_passwd = getpwnam (result)) == NULL)
- {
- return(FALSE);
- }
- strncpy (result, user_passwd->pw_dir, YAP_FILENAME_MAX);
- }
+ source++;
+ while (!dir_separator((*res0 = *source)) && *res0 != '\0')
+ res0++, source++;
+ *res0++ = '\0';
+ if ((user_passwd = getpwnam (result)) == NULL) {
+ return FALSE;
+ }
+ strncpy (result, user_passwd->pw_dir, YAP_FILENAME_MAX);
+#else
+ return FALSE;
#endif
- strncat (result, source, YAP_FILENAME_MAX);
}
- else
+ strncat (result, source, YAP_FILENAME_MAX);
+ } else if (source[0] == '$') {
+ /* follow SICStus expansion rules */
+ int ch;
+ char *s;
+ char *res0 = source+1;
+
+ while ((ch = *res0) && is_valid_env_char (ch)) {
+ res0++;
+ }
+ *res0 = '\0';
+ if (!(s = (char *) getenv (source+1))) {
+ return FALSE;
+ }
+ *res0 = ch;
+ strncpy (result, s, YAP_FILENAME_MAX);
+ strncat (result, res0, YAP_FILENAME_MAX);
+ } else {
strncpy (result, source, YAP_FILENAME_MAX);
- /* step 2: handling environment variables in file names */
- strncpy (ares1, result, YAP_FILENAME_MAX);
- res0 = result;
- while ((ch = *res1++)!=0)
- {
- if (ch == '\\' && !dir_separator('\\'))
- {
- ch = *res1++;
- if (ch == '\0')
- {
- *res0 = '\0';
- break;
- }
- else
- *res0++ = ch;
- }
- if (ch != '$')
- *res0++ = ch;
- else
- {
- char env_var[256], *sptr = env_var;
- while (((ch = *res1)!=0) && is_valid_env_char (ch))
- {
- res1++;
- *sptr++ = ch;
- }
- *sptr = '\0';
- if ((var_name = (char *) getenv (env_var)) == NULL)
- {
- return(FALSE);
- }
- else
- while ((*res0 = *var_name++)!=0)
- res0++;
- }
+ }
+#if defined(_WIN32)
+ res1 = result;
+ /* step 2 WINDOWS: replacing \ by / */
+ while ((ch = *res1++)) {
+ if (ch == '\\' && dir_separator('\\')) {
+ res1[-1] = '/';
}
- *res0 = '\0';
+ }
+#endif
/* step 3: get the full file name */
if (!dir_separator(result[0]) && !volume_header(result)) {
- if (root) {
- strncpy(ares1, root, YAP_FILENAME_MAX);
-#if _MSC_VER || defined(__MINGW32__)
- strncat (ares1, "\\", YAP_FILENAME_MAX);
-#else
- strncat (ares1, "/", YAP_FILENAME_MAX);
-#endif
- strncat (ares1, result, YAP_FILENAME_MAX);
- } else {
#if __simplescalar__
- /* does not implement getcwd */
- strncpy(ares1,yap_pwd,YAP_FILENAME_MAX);
+ /* does not implement getcwd */
+ strncpy(ares1,yap_pwd,YAP_FILENAME_MAX);
#elif HAVE_GETCWD
- if (getcwd (ares1, YAP_FILENAME_MAX) == NULL)
- return FALSE;
+ if (getcwd (ares1, YAP_FILENAME_MAX) == NULL)
+ return FALSE;
#else
- if (getwd (ares1) == NULL)
- return FALSE;
+ if (getwd (ares1) == NULL)
+ return FALSE;
#endif
+#if _MSC_VER || defined(__MINGW32__)
+ strncat (ares1, "\\", YAP_FILENAME_MAX);
+#else
+ strncat (ares1, "/", YAP_FILENAME_MAX);
+#endif
+ if (root) {
+ if (!dir_separator(root[0]) && !volume_header(root)) {
+ strncat(ares1, root, YAP_FILENAME_MAX);
+ } else {
+ strncpy(ares1, root, YAP_FILENAME_MAX);
+ }
#if _MSC_VER || defined(__MINGW32__)
strncat (ares1, "\\", YAP_FILENAME_MAX);
#else
strncat (ares1, "/", YAP_FILENAME_MAX);
#endif
- strncat (ares1, result, YAP_FILENAME_MAX);
- if (in_lib) {
- int tmpf;
- if ((tmpf = open(ares1, O_RDONLY)) < 0) {
- /* not in current directory, let us try the library */
- if (Yap_LibDir != NULL) {
- strncpy(Yap_FileNameBuf, Yap_LibDir, YAP_FILENAME_MAX);
+ }
+ strncat (ares1, result, YAP_FILENAME_MAX);
+ if (in_lib) {
+ int tmpf;
+ if ((tmpf = open(ares1, O_RDONLY)) < 0) {
+ /* not in current directory, let us try the library */
+ if (Yap_LibDir != NULL) {
+ strncpy(Yap_FileNameBuf, Yap_LibDir, YAP_FILENAME_MAX);
#if HAVE_GETENV
- } else {
- char *yap_env = getenv("YAPLIBDIR");
- if (yap_env != NULL) {
- strncpy(ares1, yap_env, YAP_FILENAME_MAX);
-#endif
- } else {
-#if _MSC_VER || defined(__MINGW32__)
- if (libdir)
- strncpy(ares1, libdir, YAP_FILENAME_MAX);
- else
-#endif
- strncpy(ares1, LIB_DIR, YAP_FILENAME_MAX);
- }
-#if HAVE_GETENV
- }
-#endif
-#if _MSC_VER || defined(__MINGW32__)
- strncat(ares1,"\\", YAP_FILENAME_MAX);
-#else
- strncat(ares1,"/", YAP_FILENAME_MAX);
-#endif
- strncat(ares1,result, YAP_FILENAME_MAX);
- if ((tmpf = open(ares1, O_RDONLY)) >= 0) {
- close(tmpf);
- strncpy (result, ares1, YAP_FILENAME_MAX);
- }
} else {
- strncpy (result, ares1, YAP_FILENAME_MAX);
+ char *yap_env = getenv("YAPLIBDIR");
+ if (yap_env != NULL) {
+ strncpy(ares1, yap_env, YAP_FILENAME_MAX);
+#endif
+ } else {
+#if _MSC_VER || defined(__MINGW32__)
+ if (libdir)
+ strncpy(ares1, libdir, YAP_FILENAME_MAX);
+ else
+#endif
+ strncpy(ares1, LIB_DIR, YAP_FILENAME_MAX);
+ }
+#if HAVE_GETENV
+ }
+#endif
+#if _MSC_VER || defined(__MINGW32__)
+ strncat(ares1,"\\", YAP_FILENAME_MAX);
+#else
+ strncat(ares1,"/", YAP_FILENAME_MAX);
+#endif
+ strncat(ares1,result, YAP_FILENAME_MAX);
+ if ((tmpf = open(ares1, O_RDONLY)) >= 0) {
close(tmpf);
+ strncpy (result, ares1, YAP_FILENAME_MAX);
}
} else {
strncpy (result, ares1, YAP_FILENAME_MAX);
+ close(tmpf);
}
+ } else {
+ strncpy (result, ares1, YAP_FILENAME_MAX);
}
}
/* step 4: simplifying the file name */
diff --git a/H/iopreds.h b/H/iopreds.h
index e646b8a10..a31a1f36e 100644
--- a/H/iopreds.h
+++ b/H/iopreds.h
@@ -126,6 +126,8 @@ StreamDesc;
#define RepError_Prolog_f 0x400000
#define RepError_Xml_f 0x800000
+#define EXPAND_FILENAME 0x000080
+
#define StdInStream 0
#define StdOutStream 1
#define StdErrStream 2
diff --git a/changes-5.1.html b/changes-5.1.html
index 609b6a380..9bf10aca2 100644
--- a/changes-5.1.html
+++ b/changes-5.1.html
@@ -17,7 +17,10 @@ xb
Yap-5.1.3:
-- FIXED: [ ] should be processed by parser, not by scanner (obs
+
- FIXED: true_file_name/3 was totally broken (obs from Nicos Agelopoulos).
+- FIXED: Environment variables should only be seen at the beginning
+ of the file (obs from Samir Genaim.)
+- FIXED: [ ] should be processed by parser, not by scanner (obs
from Samir Genaim).
- NEW: file_base_name/2.
- FIXED: in console, count input characters as being output, as they
diff --git a/docs/yap.tex b/docs/yap.tex
index 3011d3877..c654712ef 100644
--- a/docs/yap.tex
+++ b/docs/yap.tex
@@ -4047,6 +4047,16 @@ escape code or @code{xml} (write @code{...;} XML character entity).
The initial mode is @code{prolog} for the user streams and
@code{error} for all other streams. See also @ref{Encoding}.
+@item expand_filename(+@var{Mode})
+If @var{Mode} is @code{true} then do filename expansion, then ask Prolog
+to do file name expansion before actually trying to opening the file:
+this includes processing @code{~} characters and processing @code{$}
+environment variables at the beginning of the file. Otherwise, just try
+to open the file using the given name.
+
+The default behavior is given by the Prolog flag
+@code{open_expands_filename}.
+
@end table
@item close(+@var{S}) [ISO]
@@ -7616,6 +7626,13 @@ blackboard when the key is an integer.
Read or set the size of the hash table that is used for looking up the
internal data-base when the key is an integer.
+@item open_expands_filename
+@findex open_expands_filename (yap_flag/2 option)
+@*
+If @code{true} the @code{open/3} builtin performs filename-expansion
+before opening a file (SICStus Prolog like). If @code{false} it does not
+(SWI-Prolog like).
+
@item profiling
@findex profiling (yap_flag/2 option)
@*
diff --git a/library/lists.yap b/library/lists.yap
index 15c12d07e..96dff22e3 100644
--- a/library/lists.yap
+++ b/library/lists.yap
@@ -95,25 +95,6 @@ last([], Last, Last).
last([H|List], _, Last) :-
last(List, H, Last).
-% member(?Element, ?Set)
-% is true when Set is a list, and Element occurs in it. It may be used
-% to test for an element or to enumerate all the elements by backtracking.
-% Indeed, it may be used to generate the Set!
-
-member(Element, [Element|_]).
-member(Element, [_|Rest]) :-
- member(Element, Rest).
-
-
-% memberchk(+Element, +Set)
-% means the same thing, but may only be used to test whether a known
-% Element occurs in a known Set. In return for this limited use, it
-% is more efficient when it is applicable.
-
-memberchk(Element, [Element|_]) :- !.
-memberchk(Element, [_|Rest]) :-
- memberchk(Element, Rest).
-
% nextto(X, Y, List)
% is true when X and Y appear side-by-side in List. It could be written as
% nextto(X, Y, List) :- append(_, [X,Y,_], List).
diff --git a/library/swi.yap b/library/swi.yap
index b6803ac60..d1894643f 100644
--- a/library/swi.yap
+++ b/library/swi.yap
@@ -5,6 +5,8 @@
:- yap_flag(unknown,error).
+:- yap_flag(open_expands_filename,false).
+
% redefines stuff in prolog module.
:- module(swi, []).
diff --git a/pl/boot.yap b/pl/boot.yap
index 8bfcdd88f..a27d842ff 100644
--- a/pl/boot.yap
+++ b/pl/boot.yap
@@ -65,6 +65,7 @@ true :- true.
prompt(' ?- '),
nb_setval('$break',0),
% '$set_read_error_handler'(error), let the user do that
+ nb_setval('$open_expands_filename',true),
nb_setval('$debug',off),
nb_setval('$trace',off),
b_setval('$spy_glist',[]),
@@ -532,7 +533,7 @@ true :- true.
'$another' :-
format(user_error,' ? ',[]),
- '$get0'(user_input,C),
+ get0(user_input,C),
( C== 0'; -> '$skip'(user_input,10), %'
'$add_nl_outside_console',
fail
diff --git a/pl/directives.yap b/pl/directives.yap
index f752228bf..461477b06 100644
--- a/pl/directives.yap
+++ b/pl/directives.yap
@@ -436,13 +436,13 @@ yap_flag(float_min_exponent,X) :-
yap_flag(float_epsilon,X) :-
'$do_error'(domain_error(flag_value,float_min_exponent+X),yap_flag(float_min_exponent,X)).
-yap_flag(float_max_exponent,X) :-
+yap_flag(float_max_exponent,X) :-
var(X), !,
?????
-yap_flag(float_max_exponent,X) :-
+yap_flag(float_max_exponent,X) :-
integer(X), X > 0, !,
'$do_error'(permission_error(modify,flag,float_max_exponent),yap_flag(float_max_exponent,X)).
-yap_flag(float_max_exponent,X) :-
+yap_flag(float_max_exponent,X) :-
'$do_error'(domain_error(flag_value,float_max_exponent+X),yap_flag(float_max_exponent,X)).
*/
@@ -580,6 +580,12 @@ yap_flag(chr_toplevel_show_store,X) :-
yap_flag(chr_toplevel_show_store,X) :-
'$do_error'(domain_error(flag_value,chr_toplevel_show_store+X),yap_flag(chr_toplevel_show_store,X)).
+yap_flag(open_expands_filename,Expand) :-
+ var(Expand), !,
+ '$default_expand'(Expand).
+yap_flag(open_expands_filename,Expand) :-
+ '$set_default_expand'(Expand).
+
yap_flag(single_var_warnings,X) :-
var(X), !,
('$syntax_check_mode'(on,_), '$syntax_check_single_var'(on,_) ->
@@ -810,6 +816,10 @@ yap_flag(dialect,yap).
% V = fast ;
V = fileerrors ;
V = float_format ;
+% V = float_mantissa_digits ;
+% V = float_epsilon ;
+% V = float_min_exponent ;
+% V = float_max_exponent ;
V = gc ;
V = gc_margin ;
V = gc_trace ;
@@ -828,11 +838,8 @@ yap_flag(dialect,yap).
V = max_threads ;
V = min_integer ;
V = min_tagged_integer ;
-% V = float_mantissa_digits ;
-% V = float_epsilon ;
-% V = float_min_exponent ;
-% V = float_max_exponent ;
V = n_of_integer_keys_in_db ;
+ V = open_expands_filename ;
V = profiling ;
V = redefine_warnings ;
V = shared_object_search_path ;
diff --git a/pl/modules.yap b/pl/modules.yap
index 432e10e0d..393b19e62 100644
--- a/pl/modules.yap
+++ b/pl/modules.yap
@@ -134,7 +134,7 @@ module(N) :-
'$use_preds'(P,Publics,Mod,M),
'$use_preds'(Ps,Publics,Mod,M).
'$use_preds'(N/K,Publics,M,Mod) :-
- ( '$member'(N/K,Publics) -> true ;
+ ( lists:memberchk(N/K,Publics) -> true ;
print_message(warning,import(N/K,Mod,M,private))
),
'$do_import'(N, K, M, Mod).
@@ -469,8 +469,23 @@ current_module(Mod,TFN) :-
source_module(Mod) :-
'$current_module'(Mod).
-'$member'(X,[X|_]) :- !.
-'$member'(X,[_|L]) :- '$member'(X,L).
+% member(?Element, ?Set)
+% is true when Set is a list, and Element occurs in it. It may be used
+% to test for an element or to enumerate all the elements by backtracking.
+% Indeed, it may be used to generate the Set!
+
+lists:memberchk(X,[X|_]) :- !.
+lists:memberchk(X,[_|L]) :-
+ lists:memberchk(X,L).
+
+% memberchk(+Element, +Set)
+% means the same thing, but may only be used to test whether a known
+% Element occurs in a known Set. In return for this limited use, it
+% is more efficient when it is applicable.
+
+lists:member(X,[X|_]) :- !.
+lists:member(X,[_|L]) :-
+ lists:member(X,L).
% comma has its own problems.
@@ -639,20 +654,20 @@ abolish_module(_).
'$clean_conversion'([], _, [], [], _).
'$clean_conversion'([P1|Ps], List, [P1-P1|Tab], [P1|MyExports], Goal) :-
- '$member'(P1, List), !,
+ lists:memberchk(P1, List), !,
'$clean_conversion'(Ps, List, Tab, MyExports, Goal).
'$clean_conversion'([(N1/A1 as N2)|Ps], List, [N1/A1-N2/A1|Tab], [N2/A1|MyExports], Goal) :-
- '$member'(N1/A1, List), !,
+ lists:memberchk(N1/A1, List), !,
'$clean_conversion'(Ps, List, Tab, MyExports, Goal).
'$clean_conversion'([P|_], _, _, _, Goal) :-
'$do_error'(domain_error(module_reexport_predicates,P), Goal).
'$neg_conversion'([], _, [], [], _).
'$neg_conversion'([P1|Ps], List, Tab, MyExports, Goal) :-
- '$member'(P1, List), !,
+ lists:memberchk(P1, List), !,
'$neg_conversion'(Ps, List, Tab, MyExports, Goal).
'$neg_conversion'([N1/A1|Ps], List, [N1/A1-N2/A1|Tab], [N2/A1|MyExports], Goal) :-
- '$member'(N1/A1 as N2, List), !,
+ lists:memberchk(N1/A1 as N2, List), !,
'$neg_conversion'(Ps, List, Tab, MyExports, Goal).
'$neg_conversion'([P|Ps], List, [P-P|Tab], [P|MyExports], Goal) :-
'$neg_conversion'(Ps, List, Tab, MyExports, Goal).
diff --git a/pl/preds.yap b/pl/preds.yap
index 7b40c1aa8..87a97674e 100644
--- a/pl/preds.yap
+++ b/pl/preds.yap
@@ -852,7 +852,7 @@ predicate_property(Pred,Prop) :-
'$predicate_property'(P,M,M,exported) :-
functor(P,N,A),
recorded('$module','$module'(_TFN,M,Publics),_),
- '$member'(N/A,Publics), !. /* defined in modules.yap */
+ lists:memberchk(N/A,Publics), !.
'$predicate_property'(P,Mod,_,number_of_clauses(NCl)) :-
'$number_of_clauses'(P,Mod,NCl).
diff --git a/pl/yio.yap b/pl/yio.yap
index bcf42528f..95ebb170d 100644
--- a/pl/yio.yap
+++ b/pl/yio.yap
@@ -23,8 +23,10 @@ open(Source,M,T) :- var(M), !,
'$do_error'(instantiation_error,open(Source,M,T)).
open(Source,M,T) :- nonvar(T), !,
'$do_error'(type_error(variable,T),open(Source,M,T)).
-open(File,Mode,Stream) :-
+open(File0,Mode,Stream) :-
'$default_encoding'(Encoding),
+ '$default_expand'(Expansion),
+ '$expand_filename'(Expansion, File0, File),
'$open'(File,Mode,Stream,16,Encoding).
/* meaning of flags for '$write' is
@@ -59,11 +61,16 @@ close(S,Opts) :-
open(F,T,S,Opts) :-
'$check_io_opts'(Opts,open(F,T,S,Opts)),
- '$process_open_opts'(Opts, 0, N, Aliases, E, BOM),
- '$open2'(F,T,S,N,E),
+ '$process_open_opts'(Opts, 0, N, Aliases, E, BOM, Expand),
+ '$expand_filename'(Expand, F, NF),
+ '$open2'(NF, T, S, N, E),
'$process_bom'(S, BOM),
'$process_open_aliases'(Aliases,S).
+'$expand_filename'(false, F, F) :- !.
+'$expand_filename'(true, F, NF) :-
+ system:true_file_name(F, NF).
+
'$open2'(Source,M,T,N,_) :- var(Source), !,
'$do_error'(instantiation_error,open(Source,M,T,N)).
'$open2'(Source,M,T,N,_) :- var(M), !,
@@ -83,26 +90,30 @@ open(F,T,S,Opts) :-
'$add_alias_to_stream'(Alias, S),
'$process_open_aliases'(Aliases,S).
-'$process_open_opts'([], N, N, [], DefaultEncoding, []) :-
- '$default_encoding'(DefaultEncoding).
-'$process_open_opts'([type(T)|L], N0, N, Aliases, Encoding, BOM) :-
+'$process_open_opts'([], N, N, [], DefaultEncoding, [], DefaultExpand) :-
+ '$default_encoding'(DefaultEncoding),
+ '$default_expand'(DefaultExpand).
+'$process_open_opts'([type(T)|L], N0, N, Aliases, Encoding, BOM, DefaultExpand) :-
'$value_open_opt'(T,type,I1,I2),
N1 is I1\/N0,
N2 is I2/\N1,
- '$process_open_opts'(L,N2,N, Aliases, Encoding, BOM).
-'$process_open_opts'([reposition(T)|L], N0, N, Aliases, Encoding, BOM) :-
+ '$process_open_opts'(L,N2,N, Aliases, Encoding, BOM, DefaultExpand).
+'$process_open_opts'([expand_filename(T)|L], N0, N, Aliases, Encoding, BOM, Expand) :-
+ '$valid_expand'(T, Expand),
+ '$process_open_opts'(L,N2,N, Aliases, Encoding, BOM, _).
+'$process_open_opts'([reposition(T)|L], N0, N, Aliases, Encoding, BOM, DefaultExpand) :-
'$value_open_opt'(T,reposition,I1,I2),
N1 is I1\/N0,
N2 is I2/\N1,
- '$process_open_opts'(L,N2,N, Aliases, Encoding, BOM).
-'$process_open_opts'([encoding(Enc)|L], N0, N, Aliases, EncCode, BOM) :-
+ '$process_open_opts'(L,N2,N, Aliases, Encoding, BOM, DefaultExpand).
+'$process_open_opts'([encoding(Enc)|L], N0, N, Aliases, EncCode, BOM, DefaultExpand) :-
'$valid_encoding'(Enc, EncCode),
- '$process_open_opts'(L, N0, N, Aliases, _, BOM).
-'$process_open_opts'([representation_errors(Mode)|L], N0, N, Aliases, EncCode, BOM) :-
+ '$process_open_opts'(L, N0, N, Aliases, _, BOM, DefaultExpand).
+'$process_open_opts'([representation_errors(Mode)|L], N0, N, Aliases, EncCode, BOM, DefaultExpand) :-
'$valid_reperrorhandler'(Mode, Flag),
NI is N0 \/ Flag,
- '$process_open_opts'(L, NI, N, Aliases, EncCode, BOM).
-'$process_open_opts'([bom(BOM)|L], N0, N, Aliases, EncCode, BOM) :-
+ '$process_open_opts'(L, NI, N, Aliases, EncCode, BOM, DefaultExpand).
+'$process_open_opts'([bom(BOM)|L], N0, N, Aliases, EncCode, BOM, DefaultExpand) :-
(
var(BOM)
->
@@ -111,14 +122,14 @@ open(F,T,S,Opts) :-
'$valid_bom'(BOM, Flag),
NI is N0 \/ Flag
),
- '$process_open_opts'(L, NI, N, Aliases, EncCode, _).
-'$process_open_opts'([eof_action(T)|L], N0, N, Aliases, Encoding, BOM) :-
+ '$process_open_opts'(L, NI, N, Aliases, EncCode, _, DefaultExpand).
+'$process_open_opts'([eof_action(T)|L], N0, N, Aliases, Encoding, BOM, DefaultExpand) :-
'$value_open_opt'(T,eof_action,I1,I2),
N1 is I1\/N0,
N2 is I2/\N1,
- '$process_open_opts'(L,N2,N, Aliases, Encoding, BOM).
-'$process_open_opts'([alias(Alias)|L], N0, N, [Alias|Aliases], Encoding, BOM) :-
- '$process_open_opts'(L,N0,N, Aliases, Encoding, BOM).
+ '$process_open_opts'(L,N2,N, Aliases, Encoding, BOM, DefaultExpand).
+'$process_open_opts'([alias(Alias)|L], N0, N, [Alias|Aliases], Encoding, BOM, DefaultExpand) :-
+ '$process_open_opts'(L,N0,N, Aliases, Encoding, BOM, DefaultExpand).
'$value_open_opt'(text,_,1,X) :- X is 128-2. % default
@@ -140,6 +151,9 @@ open(F,T,S,Opts) :-
'$valid_reperrorhandler'(prolog, 512).
'$valid_reperrorhandler'(xml, 1024).
+'$valid_expand'(true, true),
+'$valid_expand'(false, false),
+
/* check whether a list of options is valid */
'$check_io_opts'(V,G) :- var(V), !,
'$do_error'(instantiation_error,G).
@@ -587,7 +601,7 @@ print(_,_).
/* character I/O */
-get(N) :- current_input(S), '$get'(S,N).
+get(N) :- current_input(S), get(S,N).
get_byte(V) :-
\+ var(V), (\+ integer(V) ; V < -1 ; V > 256), !,
@@ -621,7 +635,7 @@ get_char(V) :-
'$do_error'(type_error(in_character,V),get_char(V)).
get_char(V) :-
current_input(S),
- '$get0'(S,I),
+ get0(S,I),
( I = -1 -> V = end_of_file ; atom_codes(V,[I])).
get_char(S,V) :-
@@ -629,7 +643,7 @@ get_char(S,V) :-
( atom(V) -> atom_codes(V,[_,_|_]), V \= end_of_file ; true ), !,
'$do_error'(type_error(in_character,V),get_char(S,V)).
get_char(S,V) :-
- '$get0'(S,I),
+ get0(S,I),
( I = -1 -> V = end_of_file ; atom_codes(V,[I])).
peek_char(V) :-
@@ -653,14 +667,14 @@ get_code(S,V) :-
\+ var(V), (\+ integer(V)), !,
'$do_error'(type_error(in_character_code,V),get_code(S,V)).
get_code(S,V) :-
- '$get0'(S,V).
+ get0(S,V).
get_code(V) :-
\+ var(V), (\+ integer(V)), !,
'$do_error'(type_error(in_character_code,V),get_code(V)).
get_code(V) :-
current_input(S),
- '$get0'(S,V).
+ get0(S,V).
peek_code(S,V) :-
\+ var(V), (\+ integer(V)), !,
@@ -732,11 +746,7 @@ put_code(S,V) :-
-get(Stream,N) :- '$get'(Stream,N).
-
-get0(N) :- current_input(S), '$get0'(S,N).
-
-get0(Stream,N) :- '$get0'(Stream,N).
+get0(N) :- current_input(S), get0(S,N).
put(N) :- current_output(S), N1 is N, '$put'(S,N1).
@@ -759,9 +769,9 @@ tab(_).
tab(Stream,N) :- '$tab'(Stream,N), fail.
tab(_,_).
-ttyget(N) :- '$get'(user_input,N).
+ttyget(N) :- get(user_input,N).
-ttyget0(N) :- '$get0'(user_input,N).
+ttyget0(N) :- get0(user_input,N).
ttyskip(N) :- N1 is N, '$skip'(user_input,N1).
@@ -1070,3 +1080,12 @@ stream_position_data(line_position, '$stream_position'(_,_,Data,_,_), Data).
%stream_position_data(char_count, '$stream_position'(Data,_,_,_,_), Data).
stream_position_data(byte_count, '$stream_position'(Data,_,_,_,_), Data).
+'$default_expand'(Expand) :-
+ nb_getval('$open_expands_filename',Expand).
+
+'$set_default_expand'(true) :- !,
+ nb_setval('$open_expands_filename',true).
+'$set_default_expand'(false) :- !,
+ nb_setval('$open_expands_filename',false).
+'$set_default_expand'(V) :- !,
+ '$do_error'(domain_error(flag_value,V),yap_flag(open_expands_file_name,X)).