forked from mthom/scryer-prolog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathos.pl
112 lines (93 loc) · 2.92 KB
/
os.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Predicates for reasoning about the operating system (OS) environment.
Written July 2020 by Markus Triska ([email protected]).
Lists of characters are used throughout to represent keys and values.
Example:
?- getenv("LANG", Ls).
Ls = "en_US.UTF-8".
Public domain code.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/** Predicates for reasoning about the operating system (OS) environment.
This includes predicates about environment variables, calls to shell and
finding out the PID of the running system.
*/
:- module(os, [getenv/2,
setenv/2,
unsetenv/1,
shell/1,
shell/2,
pid/1]).
:- use_module(library(error)).
:- use_module(library(charsio)).
:- use_module(library(lists)).
:- use_module(library(si)).
%% getenv(+Key, -Value).
%
% True iff Value contains the value of the environment variable Key.
% Example:
%
% ```
% ?- getenv("LANG", Ls).
% Ls = "en_US.UTF-8".
% ```
getenv(Key, Value) :-
must_be_env_var(Key),
'$getenv'(Key, Value).
%% setenv(+Key, +Value).
%
% Sets the environment variable Key to Value
setenv(Key, Value) :-
must_be_env_var(Key),
must_be_chars(Value),
'$setenv'(Key, Value).
%% unsetenv(+Key).
%
% Unsets the environment variable Key
unsetenv(Key) :-
must_be_env_var(Key),
'$unsetenv'(Key).
%% shell(+Command)
%
% Equivalent to `shell(Command, 0)`.
shell(Command) :- shell(Command, 0).
%% shell(+Command, -Status).
%
% True iff executes Command in a shell of the operating system and the exit code is Status.
% Keep in mind the shell syntax is dependant on the operating system, so it should be
% used very carefully.
%
% Example (using Linux and fish shell):
%
% ```
% ?- shell("echo $SHELL", Status).
% /bin/fish
% Status = 0.
% ```
shell(Command, Status) :-
must_be_chars(Command),
can_be(integer, Status),
'$shell'(Command, Status).
%% pid(-PID).
%
% True iff PID is the process identification number of current Scryer Prolog instance.
pid(PID) :-
can_be(integer, PID),
'$pid'(PID).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
For now, we only support a restricted subset of variable names.
The reason is that Rust may panic if a key is empty, contains an
ASCII equals sign '=' or the NUL character '\0', or when the value
contains the NUL character.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
must_be_env_var(Cs) :-
must_be_chars(Cs),
Cs = [_|_],
( maplist(permitted, Cs) -> true
; domain_error(env_var, Cs, os)
).
permitted(C) :- char_type(C, alnum).
permitted(C) :- char_type(C, ascii_punctuation).
permitted('_').
must_be_chars(Cs) :-
must_be(list, Cs),
maplist(must_be(character), Cs).