-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgild.ldpl
398 lines (344 loc) · 10.7 KB
/
gild.ldpl
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
##
# GILD: Gopher in LDPL
include "ldpl_socket/ldpl_socket.ldpl"
include "compat43.ldpl"
extension "gild.cpp"
DATA:
# externals defined in gild.cpp
window.rows is external number
window.cols is external number
gopher.url is text
gopher.host is text
gopher.port is number
gopher.selector is text
gopher.response is text
gopher.socket is number
# page navigation
gopher.links is text map
gopher.history is text map
gopher.hp is number # history pointer
gopher.parse-link-input is text
gopher.overflow is number
gopher.link-num is number
gopher.type is text
gopher.status is text
# arg
argc is number
# generic locals
index is number
input is text
lines is number
line is text
char is text
i is number
len is number
buf is text
out is text
tabs is number
parts is text list
# dictionaries
colormap is text map
linktypes is number map
help-cmd is number map
# cache
cache is text map
cache.key is text
PROCEDURE:
store "\e[32m" in colormap:"0" # file
store "\e[34m" in colormap:"1" # dir
store "\e[33m" in colormap:"i" # info
store "\e[31m" in colormap:"3" # err
store "\e[37m" in colormap:"7" # search
store "\e[36m" in colormap:"h" # html
store "\e[37m" in colormap:0 # nada
store "\e[35m" in colormap:"L" # link
store 1 in linktypes:"0" # file
store 1 in linktypes:"1" # dir
store 1 in linktypes:"7" # search
store 1 in help-cmd:"h"
store 1 in help-cmd:"help"
store 1 in help-cmd:"?"
store 1 in help-cmd:"#"
store "1" in gopher.type
# gets gopher response
sub-procedure gopher-get
LOCAL DATA:
res is text
PROCEDURE:
in cache.key join gopher.host ":" gopher.port gopher.selector
store cache:cache.key in gopher.response
if gopher.response is not equal to "" then
return
end if
store "" in gopher.response
join gopher.selector and crlf in gopher.selector
socket connect to gopher.host at gopher.port in gopher.socket
call gopher-check-for-errors
socket send gopher.selector to gopher.socket
call gopher-check-for-errors
socket read from gopher.socket in res
call gopher-check-for-errors
while res is not equal to "" do
in gopher.response join gopher.response res
socket read from gopher.socket in res
call gopher-check-for-errors
repeat
store gopher.response in cache:cache.key
end sub-procedure
# prints the content of gopher.response to the screen
sub-procedure gopher-print
display "\e[2J\e[H" # clear screen
store 0 in index
store "" in char
store "" in line
store "" in buf
store "" in out
store 0 in lines
store gopher.overflow in index
# regular file
if gopher.type is equal to "0" then
get char or empty at index from gopher.response in char
while char is not equal to "" do
if lines is greater than window.rows then
store index in gopher.overflow
break
end if
if char is equal to "\n" then
add 1 and lines in lines
end if
in out join out char
add 1 and index in index
get char or empty at index from gopher.response in char
repeat
display out crlf
return
end if
get char or empty at index from gopher.response in char
while char is not equal to "" do
if lines is greater than or equal to window.rows then
store index in gopher.overflow
break
end if
if char is equal to "\r" then
add 1 and index in index
get char or empty at index from gopher.response in char
end if
if char is equal to "\n" then
add 1 and lines in lines
get char or empty at 0 from line in char
if linktypes:char is equal to 1 then
in out join out colormap:"L" " "
add 1 and gopher.link-num in gopher.link-num
if gopher.link-num is less than 10 then
in out join out " " gopher.link-num
else
in out join out gopher.link-num
end if
in out join out ". "
store line in gopher.links:gopher.link-num
else
in out join out " "
end if
store colormap:char in char
if char is equal to "" then
store colormap:0 in char
end if
in out join out char
store 1 in i
get length of line in len
store "" in buf
while i is less than len do
get char or empty at i from line in char
if char is equal to "\t" then
break
end if
join buf and char in buf
add 1 and i in i
repeat
in out join out buf crlf
store "" in line
else
join line and char in line
end if
add 1 and index in index
get char or empty at index from gopher.response in char
repeat
display out
end sub-procedure
# parses a single line from a gopher.response into the gopher.host
# gopher.port and gopher.selector variables.
# also adds the parsed link to the history.
sub-procedure gopher-parse-link
store 1 in i
store 0 in tabs
store "" in buf
get length of gopher.parse-link-input in len
if gopher.parse-link-input is not equal to gopher.history:gopher.hp then
add 1 and gopher.hp in gopher.hp
store gopher.parse-link-input in gopher.history:gopher.hp
end if
get char or empty at 0 from gopher.parse-link-input in gopher.type
while i is less than len do
get char or empty at i from gopher.parse-link-input in char
add 1 and i in i
if char is equal to "\t" then
add 1 and tabs in tabs
if tabs is equal to 2 then
store buf in gopher.selector
end if
if tabs is equal to 3 then
store buf in gopher.host
end if
store "" in buf
else
join buf and char in buf
end if
repeat
store buf in gopher.port
end sub-procedure
# prompts the user for navigation.
# uses gopher.links and gopher.history for navigation
sub-procedure gopher-prompt
display "\e[36;1m[\e[37m"
if gopher.status is equal to "" then
if gopher.link-num is greater than 0 then
display "# to open, "
end if
if gopher.hp is greater than 1 then
display "0 to go back, "
end if
if lines is greater than or equal to window.rows then
display "SPACE for more, - to go up, "
else if gopher.overflow is greater than 0 then
display "- to go up, "
end if
display "Ctrl-C to quit"
else
display "\e[31m"
display gopher.status
store "" in gopher.status
end if
display "\e[36m]: \e[0m"
accept input
if input is equal to "q" then # quit
exit
end if
if help-cmd:input is equal to 1 then # explain
store "Navigate using the numbers next to links" in gopher.status
end if
if input is equal to "0" then # back in history
store 0 in gopher.link-num
store 0 in gopher.overflow
if gopher.hp is less than or equal to 1 then
return
end if
subtract 1 from gopher.hp in gopher.hp
store gopher.history:gopher.hp in gopher.parse-link-input
call sub-procedure gopher-parse-link
return
end if
if input is equal to "-" then # pageup
end if
if input is equal to " " then # pagedown
if lines is greater than or equal to window.rows then
return
end if
end if
store 0 in gopher.link-num
store 0 in gopher.overflow
store input in i # convert to number
if i is greater than 0 then
store gopher.links:i in gopher.parse-link-input
call sub-procedure gopher-parse-link
end if
# search prompt
store input in i # convert to number
get char or empty at 0 from gopher.links:i in char
if char is equal to "7" then
display "Search: "
accept input
in gopher.selector join gopher.selector "\t" input
end if
end sub-procedure
# prints error and exits, if one occurred
sub-procedure gopher-check-for-errors
if ErrorCode is less than 0 then
display "ERR: " ErrorText crlf
exit
end if
end sub
# remove leading /1/ or /0/ from gopher selector. we don't support it.
sub-procedure gopher-clean-selector
substring gopher.selector from 0 length 2 in buf
get length of gopher.selector in len
if buf is equal to "/1" or buf is equal to "/0" then
substring gopher.selector from 2 length len in gopher.selector
end if
end sub
# splits gopher.url into gopher.host, gopher.port, gopher.selector
sub-procedure gopher-split-url-into-parts
# strip leading "gopher://" from URLs
substring gopher.url from 0 length 9 in buf
if buf is equal to "gopher://" then
get length of gopher.url in len
substring gopher.url from 9 length len in gopher.url
end if
get index of "/" from gopher.url in i
if i is greater than -1 then
get length of gopher.url in len
substring gopher.url from 0 length i in gopher.host
substring gopher.url from i length len in gopher.selector
else
store gopher.url in gopher.host
end if
get index of ":" from gopher.host in i
if i is greater than -1 then
split gopher.host by ":" in parts
store parts:0 in gopher.host
store parts:1 in gopher.port
else
store 70 in gopher.port
end if
end sub-procedure
sub-procedure print-usage
display "Usage: gild [gopher-url]" crlf
exit
end sub-procedure
# MAIN:
get length of argv in argc
if argc is equal to 0 then
call print-usage
end if
if argc is greater than 0 and argv:0 is equal to "-h" then
call print-usage
end if
if argc is greater than 0 and argv:0 is equal to "--help" then
call print-usage
end if
if argc is equal to 1 then
store argv:0 in gopher.url
call gopher-split-url-into-parts
else if argc is greater than 0 then
store argv:0 in gopher.host
end if
if argc is greater than 1 then
store argv:1 in gopher.port
end if
if argc is greater than 2 then
store argv:2 in gopher.selector
end if
if gopher.port is equal to 0 then
store 70 in gopher.port
end if
# strip leading /1 or /0 from selector. we don't support it yet.
call gopher-clean-selector
# store initial site in history
add 1 and gopher.hp in gopher.hp
in gopher.history:gopher.hp join "1null\t" gopher.selector "\t" gopher.host "\t" gopher.port
# run loop
call external gopher-init
while 1 is greater than 0 do
call sub-procedure gopher-get
call sub-procedure gopher-print
call sub-procedure gopher-prompt
repeat