-
Notifications
You must be signed in to change notification settings - Fork 0
/
StartupSession.aplf
248 lines (232 loc) · 10.7 KB
/
StartupSession.aplf
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
{ok}←StartupSession
⍝ This is a boot-strapping function run when APL starts.
⍝ It loads Link and uses that to load other Dyalog and/or user-specified things into ⎕SE and calls their Run functions.
⍝ Then it optionally uses Link to load a directory structure of text files into #.
⍝ Please do not rely on any other current behaviour of this function, as it may change without warning.
⍝ For more information about...
⍝ ∘ Session Initialisation: https://help.dyalog.com/latest/#UserGuide/The%20APL%20Environment/Session%20Initialisation.htm
⍝ ∘ Linking into #: https://help.dyalog.com/latest/#UserGuide/Installation%20and%20Configuration/Configuration%20Parameters/Load.htm
⍝ ∘ Link: https://dyalog.github.io/link/latest
;⎕IO;⎕ML ⍝ sysvars
;Env;Dir;Path;NoSlash;AutoStatus;Cut;FullMsg;NJoin ⍝ fns
;win;dirs;dir;root;subdir;files;paths;path;roots;os;ver;envVars;defaults;as;oldlinks;new;z;fulldir;dskl;type;osSep ⍝ vars
;exe;parent;load;msg;dl;ref;fullns;runs;run;preFiles;pre;opts;dsx;dld;su;ns;fn;dyalog;loadSALT;home;salt;ds
⎕IO←⎕ML←1
Env←{2 ⎕NQ #'GetEnvironment'⍵}
:If '1'∊Env'DYALOGSTARTUPSTOP'
(1+⊃⎕LC)⎕STOP⊃⎕SI
:EndIf
:Trap '1'∊Env'DYALOGSTARTUPDEBUG' ⍝ If DYALOGSTARTUPDEBUG, only trap WS FULL
AutoStatus←2036⌶
NoSlash←{⍵↓⍨-'/\'∊⍨⊃⌽⍵} ⍝ remove trailing (back)slash
Cut←≠⊆⊢
FullMsg←{⍵.(OSError{⍵,2⌽(×≢⊃⍬⍴2⌽⍺,⊂'')/'") ("',⊃⍬⍴2⌽⊆⍺}Message{⍵,⍺,⍨': '/⍨×≢⍺}⊃⍬⍴DM,⊂'')}
Path←{
default←defaults,¨⊂⍺
append←osSep=⊃⍵
empty←0=≢⍵
user←osSep Cut ⍵
user,⍨default/⍨append∨empty
}
Dir←{ ⍝ ⍺=1:dirs; ⍺=2:files
pats←⍺⊃(,⊂'/*')('/*.dyalog' '/*.apl?')
pats,¨⍨←⊂NoSlash ⍵
~∨/⎕NEXISTS ⎕OPT 1⊢pats:0⍴⊂''
(names types)←⊃,¨/0 1 ⎕NINFO ⎕OPT 1⊢pats
{(⊂⍋⍵)⌷⍵}names/⍨types=⍺
}
NJoin←{
tail←⍺↑⍨-1⌊≢⍺
⍵,⍨⍺,'/'↓⍨∧/tail∊'/',win/'\:'
}
:Section __Read_Environment
(os ver type exe)←# ⎕WG'APLVersion'
win←'Windows'≡7↑os
osSep←':;'⊃⍨1+win
dyalog←NoSlash Env'DYALOG'
:If 0∊⍴salt←NoSlash Env'SALT'
⍝ If it isn't it should be found here:
salt←(NoSlash(¯3×'bin'≡¯3↑dyalog)↓dyalog),'/SALT'
:EndIf
salt,←'/core/SALTUtils.dyalog'
loadSALT←~'1'∊Env'DYALOGSTARTUPNOSALT'
home←NoSlash Env'HOME'
envVars←Env¨'DYALOGSTARTUPSE' 'DYALOGSTARTUPWS'
⍝ Exit code 1 means startup fail due to missing or invalid resource
:If 0=≢dl←Env'DYALOGLINK'
dl←dyalog
:ElseIf ~⎕NEXISTS dl
⍞←'Cannot read DYALOGLINK ("',dl,'"). Press Enter.'
⎕DL 5 ⋄ ⎕OFF 1
:EndIf
:If 0=≢ds←⊃⎕NPARTS Env'DYALOGSTARTUP'
ds←dyalog
:EndIf
:If ~(⊂dskl←Env'DYALOGSTARTUPKEEPLINK')∊,¨'' '0' '1'
⍞←'Configuration parameter DYALOGSTARTUPKEEPLINK is "',dskl,'" but must be "0" or "1". Press Enter.'
⎕DL 5 ⋄ ⎕OFF 1
:Else
dskl∊⍨←'1'
:EndIf
dsx←Env'DYALOGSTARTUP_X'
load←NoSlash Env'LOAD'
:EndSection
:Section a_Populate_Session_Object from $DYALOG/StartupSession/*/*.apl?
:If ~dskl ⍝ forget links?
{}5178⌶⊃⎕SI ⍝ forget self
:EndIf
:For pre dir :InEach ('Link' 'Dyalog')(dl ds)
dir←∊1 ⎕NPARTS dir,'/StartupSession/',pre
ref←⍎ns←⍬ ⎕NS⍨'⎕SE.',pre
preFiles←⊃⎕NINFO⍠1⊢dir,'/*.apl?'
:If dskl
{2 ref.⎕FIX'file://',⍵}¨preFiles
opts←⎕SE.Link.U.DefaultOpts ⍬
'opts'⎕NS'dir' 'ns'
opts.restored←0
opts.flagged←⍬
opts.singlefile←0
opts.⎕DF 1⌽'][',⎕SE.Link.U.LinkDisplay opts
:If 0=⎕NC'⎕SE.Link.Links'
⎕SE.Link.Links←⍬
:EndIf
⎕SE.Link.(U.SetLinks Links,{0::⍬ ⋄ Watcher.Watch ⍵})opts ⍝ Watcher might fail
:Else
{2 ref.⎕FIX⊃⎕NGET⍠'ContentType' 'APLCode'⊢⍵ 1}¨preFiles
:EndIf
:EndFor
:If 0∊≢¨envVars
defaults←{
verSpec←{
⍵:NoSlash 2⊃4070⌶⍬ ⍝ win only: version specific folder in user docs folder
num←∊2↑'.'Cut ver
uc←'UC'/⍨80 82=⎕DR'' ⍝ unicode/classic
bits←¯2↑'32',{⍵↓⍨⍵⍳'-'}os
home,'/dyalog.',num,uc,bits,'.files'
}⍵
user←⊃⎕NPARTS verSpec ⍝ /../
verAgno←user,'dyalog.files' 'Dyalog APL Files'⊃⍨1+⍵
∊¨1 ⎕NPARTS dyalog verAgno verSpec ⍝ normalise
}win
:EndIf
paths←1⍴'/StartupSession/' '/StartupWorkspace/'Path¨envVars ⍝ "1⍴" disables ws
roots←1⍴⎕SE # ⍝ "1⍴" disables #
⍝ ↓ if envVar set, then we don't know what's what
(⍎'⎕SE.Dyalog.StartupSession'⎕NS ⍬).(Dyalog VerAgno VerSpec AllPaths)←(0 0 0⊣⍣((×⍤≢∧osSep≠⊃)⊃envVars)⊢3↑⊃paths),⍬⍴paths
as←AutoStatus 0
run←0⍴⊂''
:For path root :InEach paths roots
:For dir :In path
⍝ files←2 Dir dir ⍝ disabled non-dir items in root
⍝ {}root FixEach files ⍝ disabled non-dir items in root
dirs←1 Dir dir
:For subdir :In 2⊃¨⎕NPARTS dirs
:Select fullns←root,⍥⍕'.',subdir
:CaseList '⎕SE.Link' '⎕SE.Dyalog' ⍝ already loaded
:Else
⎕EX fullns
fulldir←dir NJoin subdir
opts←⎕SE.Link.U.DefaultOpts ⍬
opts.codeExtensions~←'apl' 'mipage'
:If dskl ⍝ proper link or just import?
:Trap 0
{}opts ⎕SE.Link.Create fullns fulldir
run,←⊂fullns fulldir
:Else
⍞←('Could not link "',fulldir,'" with ',fullns,': ',FullMsg ⎕DMX),⎕UCS 13
:EndTrap
:Else
:Trap 0
opts.overwrite←1
{}opts ⎕SE.Link.Import fullns fulldir
run,←⊂fullns fulldir
:Else
⍞←('Could not import "',fulldir,'" to ',fullns,': ',FullMsg ⎕DMX),⎕UCS 13
:EndTrap
:EndIf
:EndSelect
:EndFor
:EndFor
:EndFor
:EndSection
:Section b_Boot_SALT
:Trap 0
:If loadSALT
⍝ Define the (SALTUtils) namespace locally
su←0 ⎕FIX'file://',salt
su.BootSALT ⍝ finally, call the bootstrap fn
:EndIf
:Else
⍞←'SALT initialization failed: ',(⎕DMX.DM[2 3],⍨⊂FullMsg ⎕DMX),¨⎕UCS 13
:EndTrap
:If 3=⎕NC'⎕SE.Link.SECreate'
{}⎕SE.Link.SECreate
:Else
{}⎕SE.Link.U.GetLinks ⍝ In case the session was saved with links and there is no Link.SECreate
:EndIf
:EndSection
:Section c_Call_Run_From_Dirs
:If ~(⊂dsx)∊,¨'' '0' '1'
⍞←'Configuration parameter DYALOGSTARTUP_X is "',dskl,'" but must be "0" or "1". Press Enter.'
{}⍞ ⋄ ⎕OFF 1
:Else
dsx∊⍨←'1'
:EndIf
:If ~dsx
run/⍨←3=40 ⎕ATX(⊃,'.Run'⍨)¨run ⍝ which ns.Run functions exist?
:For ns dir :In run
:Trap 0
:If 0≠11 ⎕ATX fn←ns,'.Run'
(⍎fn),⊂dir
:Else
⍎fn
:EndIf
:Else
⎕←'Calling ',fn,' caused a ',FullMsg ⎕DMX
:EndTrap
:EndFor
:EndIf
:EndSection
:Section d_Link_Hash_And_Set_Latent_Expression
msg←' ─ LOAD ignored!'
:If 0≠≢load ⍝ LOAD allows linking/importing one dir into # at startup
:AndIf ⎕NEXISTS load
:AndIf 1=1 ⎕NINFO load ⍝ handle if dir (file is handled by interpreter)
:If 0≠⎕NC'⎕SE.Link'
:Select exe
:CaseList 'Development' 'DLL'
:Trap 0
⍞←⎕SE.Link.Create # load
:Else
⍞←'Could not link "',load,'" with #: ',FullMsg ⎕DMX
:EndTrap
:CaseList 'Runtime' 'DLLRT'
:Trap 0
⍞←⎕SE.Link.Import # load
:Else
⍞←'Could not import "',load,'" to #: ',FullMsg ⎕DMX
:EndTrap
:Else
⍞←'Could not determine if interpreter (',exe,') is Development or Runtime version',msg
:EndSelect
:Else
:Select exe
:CaseList 'Development' 'DLL'
⍞←'Could not link "',load,'" with # because ⎕SE.Link does not exist',msg
:CaseList 'Runtime' 'DLLRT'
⍞←'Could not import "',load,'" to # because ⎕SE.Link does not exist',msg
:Else
⍞←'Could not bring in "',load,'" to # because ⎕SE.Link does not exist',msg
:EndSelect
:EndIf
⍞←⎕UCS 13
2060⌶'#.Run',(0≠1 2⊃⎕AT'#.Run')/',⊂''',(load/⍨1+''''=load),'''' ⍝ make interpreter ⎕LX-style run before 6-space prompt (undocumented)
:EndIf
:EndSection
{}AutoStatus as
⎕SE.SALTUtils.USetup'init' 0
{}⎕SE.UCMD'box' ⍝ initialise output space so toolbar button works
ok←1
:Else
ok←0
:EndTrap