xref: /freebsd/stand/forth/menusets.4th (revision ca987d4641cdcd7f27e153db17c5bf064934faf5)
1*ca987d46SWarner Losh\ Copyright (c) 2012 Devin Teske <dteske@FreeBSD.org>
2*ca987d46SWarner Losh\ All rights reserved.
3*ca987d46SWarner Losh\
4*ca987d46SWarner Losh\ Redistribution and use in source and binary forms, with or without
5*ca987d46SWarner Losh\ modification, are permitted provided that the following conditions
6*ca987d46SWarner Losh\ are met:
7*ca987d46SWarner Losh\ 1. Redistributions of source code must retain the above copyright
8*ca987d46SWarner Losh\    notice, this list of conditions and the following disclaimer.
9*ca987d46SWarner Losh\ 2. Redistributions in binary form must reproduce the above copyright
10*ca987d46SWarner Losh\    notice, this list of conditions and the following disclaimer in the
11*ca987d46SWarner Losh\    documentation and/or other materials provided with the distribution.
12*ca987d46SWarner Losh\
13*ca987d46SWarner Losh\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14*ca987d46SWarner Losh\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15*ca987d46SWarner Losh\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16*ca987d46SWarner Losh\ ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17*ca987d46SWarner Losh\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18*ca987d46SWarner Losh\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19*ca987d46SWarner Losh\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20*ca987d46SWarner Losh\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21*ca987d46SWarner Losh\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22*ca987d46SWarner Losh\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23*ca987d46SWarner Losh\ SUCH DAMAGE.
24*ca987d46SWarner Losh\
25*ca987d46SWarner Losh\ $FreeBSD$
26*ca987d46SWarner Losh
27*ca987d46SWarner Loshmarker task-menusets.4th
28*ca987d46SWarner Losh
29*ca987d46SWarner Loshvocabulary menusets-infrastructure
30*ca987d46SWarner Loshonly forth also menusets-infrastructure definitions
31*ca987d46SWarner Losh
32*ca987d46SWarner Loshvariable menuset_use_name
33*ca987d46SWarner Losh
34*ca987d46SWarner Loshcreate menuset_affixbuf	255 allot
35*ca987d46SWarner Loshcreate menuset_x        1   allot
36*ca987d46SWarner Loshcreate menuset_y        1   allot
37*ca987d46SWarner Losh
38*ca987d46SWarner Losh: menuset-loadvar ( -- )
39*ca987d46SWarner Losh
40*ca987d46SWarner Losh	\ menuset_use_name is true or false
41*ca987d46SWarner Losh	\ $type should be set to one of:
42*ca987d46SWarner Losh	\ 	menu toggled ansi
43*ca987d46SWarner Losh	\ $var should be set to one of:
44*ca987d46SWarner Losh	\ 	caption command keycode text ...
45*ca987d46SWarner Losh	\ $affix is either prefix (menuset_use_name is true)
46*ca987d46SWarner Losh	\               or infix (menuset_use_name is false)
47*ca987d46SWarner Losh
48*ca987d46SWarner Losh	s" set cmdbuf='set ${type}_${var}=\$'" evaluate
49*ca987d46SWarner Losh	s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length
50*ca987d46SWarner Losh	menuset_use_name @ true = if
51*ca987d46SWarner Losh		s" set cmdbuf=${cmdbuf}${affix}${type}_${var}"
52*ca987d46SWarner Losh		( u1 -- u1 c-addr2 u2 )
53*ca987d46SWarner Losh	else
54*ca987d46SWarner Losh		s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}"
55*ca987d46SWarner Losh		( u1 -- u1 c-addr2 u2 )
56*ca987d46SWarner Losh	then
57*ca987d46SWarner Losh	evaluate ( u1 c-addr2 u2 -- u1 )
58*ca987d46SWarner Losh	s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 )
59*ca987d46SWarner Losh	rot 2 pick 2 pick over + -rot + tuck -
60*ca987d46SWarner Losh		( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 )
61*ca987d46SWarner Losh		\ Generate a string representing rvalue inheritance var
62*ca987d46SWarner Losh	getenv dup -1 = if
63*ca987d46SWarner Losh		( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 )
64*ca987d46SWarner Losh		\ NOT set -- clean up the stack
65*ca987d46SWarner Losh		drop ( c-addr2 u2 -1 -- c-addr2 u2 )
66*ca987d46SWarner Losh		2drop ( c-addr2 u2 -- )
67*ca987d46SWarner Losh	else
68*ca987d46SWarner Losh		( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 )
69*ca987d46SWarner Losh		\ SET -- execute cmdbuf (c-addr2/u2) to inherit value
70*ca987d46SWarner Losh		2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 )
71*ca987d46SWarner Losh		evaluate ( c-addr2 u2 -- )
72*ca987d46SWarner Losh	then
73*ca987d46SWarner Losh
74*ca987d46SWarner Losh	s" cmdbuf" unsetenv
75*ca987d46SWarner Losh;
76*ca987d46SWarner Losh
77*ca987d46SWarner Losh: menuset-unloadvar ( -- )
78*ca987d46SWarner Losh
79*ca987d46SWarner Losh	\ menuset_use_name is true or false
80*ca987d46SWarner Losh	\ $type should be set to one of:
81*ca987d46SWarner Losh	\ 	menu toggled ansi
82*ca987d46SWarner Losh	\ $var should be set to one of:
83*ca987d46SWarner Losh	\ 	caption command keycode text ...
84*ca987d46SWarner Losh	\ $affix is either prefix (menuset_use_name is true)
85*ca987d46SWarner Losh	\               or infix (menuset_use_name is false)
86*ca987d46SWarner Losh
87*ca987d46SWarner Losh	menuset_use_name @ true = if
88*ca987d46SWarner Losh		s" set buf=${affix}${type}_${var}"
89*ca987d46SWarner Losh	else
90*ca987d46SWarner Losh		s" set buf=${type}set${affix}_${var}"
91*ca987d46SWarner Losh	then
92*ca987d46SWarner Losh	evaluate
93*ca987d46SWarner Losh	s" buf" getenv unsetenv
94*ca987d46SWarner Losh	s" buf" unsetenv
95*ca987d46SWarner Losh;
96*ca987d46SWarner Losh
97*ca987d46SWarner Losh: menuset-loadmenuvar ( -- )
98*ca987d46SWarner Losh	s" set type=menu" evaluate
99*ca987d46SWarner Losh	menuset-loadvar
100*ca987d46SWarner Losh;
101*ca987d46SWarner Losh
102*ca987d46SWarner Losh: menuset-unloadmenuvar ( -- )
103*ca987d46SWarner Losh	s" set type=menu" evaluate
104*ca987d46SWarner Losh	menuset-unloadvar
105*ca987d46SWarner Losh;
106*ca987d46SWarner Losh
107*ca987d46SWarner Losh: menuset-loadxvar ( -- )
108*ca987d46SWarner Losh
109*ca987d46SWarner Losh	\ menuset_use_name is true or false
110*ca987d46SWarner Losh	\ $type should be set to one of:
111*ca987d46SWarner Losh	\ 	menu toggled ansi
112*ca987d46SWarner Losh	\ $var should be set to one of:
113*ca987d46SWarner Losh	\ 	caption command keycode text ...
114*ca987d46SWarner Losh	\ $x is "1" through "8"
115*ca987d46SWarner Losh	\ $affix is either prefix (menuset_use_name is true)
116*ca987d46SWarner Losh	\               or infix (menuset_use_name is false)
117*ca987d46SWarner Losh
118*ca987d46SWarner Losh	s" set cmdbuf='set ${type}_${var}[${x}]=\$'" evaluate
119*ca987d46SWarner Losh	s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length
120*ca987d46SWarner Losh	menuset_use_name @ true = if
121*ca987d46SWarner Losh		s" set cmdbuf=${cmdbuf}${affix}${type}_${var}[${x}]"
122*ca987d46SWarner Losh		( u1 -- u1 c-addr2 u2 )
123*ca987d46SWarner Losh	else
124*ca987d46SWarner Losh		s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}[${x}]"
125*ca987d46SWarner Losh		( u1 -- u1 c-addr2 u2 )
126*ca987d46SWarner Losh	then
127*ca987d46SWarner Losh	evaluate ( u1 c-addr2 u2 -- u1 )
128*ca987d46SWarner Losh	s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 )
129*ca987d46SWarner Losh	rot 2 pick 2 pick over + -rot + tuck -
130*ca987d46SWarner Losh		( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 )
131*ca987d46SWarner Losh		\ Generate a string representing rvalue inheritance var
132*ca987d46SWarner Losh	getenv dup -1 = if
133*ca987d46SWarner Losh		( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 )
134*ca987d46SWarner Losh		\ NOT set -- clean up the stack
135*ca987d46SWarner Losh		drop ( c-addr2 u2 -1 -- c-addr2 u2 )
136*ca987d46SWarner Losh		2drop ( c-addr2 u2 -- )
137*ca987d46SWarner Losh	else
138*ca987d46SWarner Losh		( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 )
139*ca987d46SWarner Losh		\ SET -- execute cmdbuf (c-addr2/u2) to inherit value
140*ca987d46SWarner Losh		2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 )
141*ca987d46SWarner Losh		evaluate ( c-addr2 u2 -- )
142*ca987d46SWarner Losh	then
143*ca987d46SWarner Losh
144*ca987d46SWarner Losh	s" cmdbuf" unsetenv
145*ca987d46SWarner Losh;
146*ca987d46SWarner Losh
147*ca987d46SWarner Losh: menuset-unloadxvar ( -- )
148*ca987d46SWarner Losh
149*ca987d46SWarner Losh	\ menuset_use_name is true or false
150*ca987d46SWarner Losh	\ $type should be set to one of:
151*ca987d46SWarner Losh	\ 	menu toggled ansi
152*ca987d46SWarner Losh	\ $var should be set to one of:
153*ca987d46SWarner Losh	\ 	caption command keycode text ...
154*ca987d46SWarner Losh	\ $x is "1" through "8"
155*ca987d46SWarner Losh	\ $affix is either prefix (menuset_use_name is true)
156*ca987d46SWarner Losh	\               or infix (menuset_use_name is false)
157*ca987d46SWarner Losh
158*ca987d46SWarner Losh	menuset_use_name @ true = if
159*ca987d46SWarner Losh		s" set buf=${affix}${type}_${var}[${x}]"
160*ca987d46SWarner Losh	else
161*ca987d46SWarner Losh		s" set buf=${type}set${affix}_${var}[${x}]"
162*ca987d46SWarner Losh	then
163*ca987d46SWarner Losh	evaluate
164*ca987d46SWarner Losh	s" buf" getenv unsetenv
165*ca987d46SWarner Losh	s" buf" unsetenv
166*ca987d46SWarner Losh;
167*ca987d46SWarner Losh
168*ca987d46SWarner Losh: menuset-loadansixvar ( -- )
169*ca987d46SWarner Losh	s" set type=ansi" evaluate
170*ca987d46SWarner Losh	menuset-loadxvar
171*ca987d46SWarner Losh;
172*ca987d46SWarner Losh
173*ca987d46SWarner Losh: menuset-unloadansixvar ( -- )
174*ca987d46SWarner Losh	s" set type=ansi" evaluate
175*ca987d46SWarner Losh	menuset-unloadxvar
176*ca987d46SWarner Losh;
177*ca987d46SWarner Losh
178*ca987d46SWarner Losh: menuset-loadmenuxvar ( -- )
179*ca987d46SWarner Losh	s" set type=menu" evaluate
180*ca987d46SWarner Losh	menuset-loadxvar
181*ca987d46SWarner Losh;
182*ca987d46SWarner Losh
183*ca987d46SWarner Losh: menuset-unloadmenuxvar ( -- )
184*ca987d46SWarner Losh	s" set type=menu" evaluate
185*ca987d46SWarner Losh	menuset-unloadxvar
186*ca987d46SWarner Losh;
187*ca987d46SWarner Losh
188*ca987d46SWarner Losh: menuset-loadtoggledxvar ( -- )
189*ca987d46SWarner Losh	s" set type=toggled" evaluate
190*ca987d46SWarner Losh	menuset-loadxvar
191*ca987d46SWarner Losh;
192*ca987d46SWarner Losh
193*ca987d46SWarner Losh: menuset-unloadtoggledxvar ( -- )
194*ca987d46SWarner Losh	s" set type=toggled" evaluate
195*ca987d46SWarner Losh	menuset-unloadxvar
196*ca987d46SWarner Losh;
197*ca987d46SWarner Losh
198*ca987d46SWarner Losh: menuset-loadxyvar ( -- )
199*ca987d46SWarner Losh
200*ca987d46SWarner Losh	\ menuset_use_name is true or false
201*ca987d46SWarner Losh	\ $type should be set to one of:
202*ca987d46SWarner Losh	\ 	menu toggled ansi
203*ca987d46SWarner Losh	\ $var should be set to one of:
204*ca987d46SWarner Losh	\ 	caption command keycode text ...
205*ca987d46SWarner Losh	\ $x is "1" through "8"
206*ca987d46SWarner Losh	\ $y is "0" through "9"
207*ca987d46SWarner Losh	\ $affix is either prefix (menuset_use_name is true)
208*ca987d46SWarner Losh	\               or infix (menuset_use_name is false)
209*ca987d46SWarner Losh
210*ca987d46SWarner Losh	s" set cmdbuf='set ${type}_${var}[${x}][${y}]=\$'" evaluate
211*ca987d46SWarner Losh	s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length
212*ca987d46SWarner Losh	menuset_use_name @ true = if
213*ca987d46SWarner Losh		s" set cmdbuf=${cmdbuf}${affix}${type}_${var}[${x}][${y}]"
214*ca987d46SWarner Losh		( u1 -- u1 c-addr2 u2 )
215*ca987d46SWarner Losh	else
216*ca987d46SWarner Losh		s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}[${x}][${y}]"
217*ca987d46SWarner Losh		( u1 -- u1 c-addr2 u2 )
218*ca987d46SWarner Losh	then
219*ca987d46SWarner Losh	evaluate ( u1 c-addr2 u2 -- u1 )
220*ca987d46SWarner Losh	s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 )
221*ca987d46SWarner Losh	rot 2 pick 2 pick over + -rot + tuck -
222*ca987d46SWarner Losh		( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 )
223*ca987d46SWarner Losh		\ Generate a string representing rvalue inheritance var
224*ca987d46SWarner Losh	getenv dup -1 = if
225*ca987d46SWarner Losh		( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 )
226*ca987d46SWarner Losh		\ NOT set -- clean up the stack
227*ca987d46SWarner Losh		drop ( c-addr2 u2 -1 -- c-addr2 u2 )
228*ca987d46SWarner Losh		2drop ( c-addr2 u2 -- )
229*ca987d46SWarner Losh	else
230*ca987d46SWarner Losh		( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 )
231*ca987d46SWarner Losh		\ SET -- execute cmdbuf (c-addr2/u2) to inherit value
232*ca987d46SWarner Losh		2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 )
233*ca987d46SWarner Losh		evaluate ( c-addr2 u2 -- )
234*ca987d46SWarner Losh	then
235*ca987d46SWarner Losh
236*ca987d46SWarner Losh	s" cmdbuf" unsetenv
237*ca987d46SWarner Losh;
238*ca987d46SWarner Losh
239*ca987d46SWarner Losh: menuset-unloadxyvar ( -- )
240*ca987d46SWarner Losh
241*ca987d46SWarner Losh	\ menuset_use_name is true or false
242*ca987d46SWarner Losh	\ $type should be set to one of:
243*ca987d46SWarner Losh	\ 	menu toggled ansi
244*ca987d46SWarner Losh	\ $var should be set to one of:
245*ca987d46SWarner Losh	\ 	caption command keycode text ...
246*ca987d46SWarner Losh	\ $x is "1" through "8"
247*ca987d46SWarner Losh	\ $y is "0" through "9"
248*ca987d46SWarner Losh	\ $affix is either prefix (menuset_use_name is true)
249*ca987d46SWarner Losh	\               or infix (menuset_use_name is false)
250*ca987d46SWarner Losh
251*ca987d46SWarner Losh	menuset_use_name @ true = if
252*ca987d46SWarner Losh		s" set buf=${affix}${type}_${var}[${x}][${y}]"
253*ca987d46SWarner Losh	else
254*ca987d46SWarner Losh		s" set buf=${type}set${affix}_${var}[${x}][${y}]"
255*ca987d46SWarner Losh	then
256*ca987d46SWarner Losh	evaluate
257*ca987d46SWarner Losh	s" buf" getenv unsetenv
258*ca987d46SWarner Losh	s" buf" unsetenv
259*ca987d46SWarner Losh;
260*ca987d46SWarner Losh
261*ca987d46SWarner Losh: menuset-loadansixyvar ( -- )
262*ca987d46SWarner Losh	s" set type=ansi" evaluate
263*ca987d46SWarner Losh	menuset-loadxyvar
264*ca987d46SWarner Losh;
265*ca987d46SWarner Losh
266*ca987d46SWarner Losh: menuset-unloadansixyvar ( -- )
267*ca987d46SWarner Losh	s" set type=ansi" evaluate
268*ca987d46SWarner Losh	menuset-unloadxyvar
269*ca987d46SWarner Losh;
270*ca987d46SWarner Losh
271*ca987d46SWarner Losh: menuset-loadmenuxyvar ( -- )
272*ca987d46SWarner Losh	s" set type=menu" evaluate
273*ca987d46SWarner Losh	menuset-loadxyvar
274*ca987d46SWarner Losh;
275*ca987d46SWarner Losh
276*ca987d46SWarner Losh: menuset-unloadmenuxyvar ( -- )
277*ca987d46SWarner Losh	s" set type=menu" evaluate
278*ca987d46SWarner Losh	menuset-unloadxyvar
279*ca987d46SWarner Losh;
280*ca987d46SWarner Losh
281*ca987d46SWarner Losh: menuset-setnum-namevar ( N -- C-Addr/U )
282*ca987d46SWarner Losh
283*ca987d46SWarner Losh	s" menuset_nameNNNNN" ( n -- n c-addr1 u1 )	\ variable basename
284*ca987d46SWarner Losh	drop 12 ( n c-addr1 u1 -- n c-addr1 12 )	\ remove "NNNNN"
285*ca987d46SWarner Losh	rot     ( n c-addr1 12 -- c-addr1 12 n )	\ move number on top
286*ca987d46SWarner Losh
287*ca987d46SWarner Losh	\ convert to string
288*ca987d46SWarner Losh	s>d <# #s #> ( c-addr1 12 n -- c-addr1 12 c-addr2 u2 )
289*ca987d46SWarner Losh
290*ca987d46SWarner Losh	\ Combine strings
291*ca987d46SWarner Losh	begin ( using u2 in c-addr2/u2 pair as countdown to zero )
292*ca987d46SWarner Losh		over	( c-addr1 u1 c-addr2 u2 -- continued below )
293*ca987d46SWarner Losh			( c-addr1 u1 c-addr2 u2 c-addr2 ) \ copy src-addr
294*ca987d46SWarner Losh		c@	( c-addr1 u1 c-addr2 u2 c-addr2 -- continued below )
295*ca987d46SWarner Losh			( c-addr1 u1 c-addr2 u2 c ) \ get next src-addr byte
296*ca987d46SWarner Losh		4 pick 4 pick
297*ca987d46SWarner Losh			( c-addr1 u1 c-addr2 u2 c -- continued below )
298*ca987d46SWarner Losh			( c-addr1 u1 c-addr2 u2 c c-addr1 u1 )
299*ca987d46SWarner Losh			\ get destination c-addr1/u1 pair
300*ca987d46SWarner Losh		+	( c-addr1 u1 c-addr2 u2 c c-addr1 u1 -- cont. below )
301*ca987d46SWarner Losh			( c-addr1 u1 c-addr2 u2 c c-addr3 )
302*ca987d46SWarner Losh			\ combine dest-c-addr to get dest-addr for byte
303*ca987d46SWarner Losh		c!	( c-addr1 u1 c-addr2 u2 c c-addr3 -- continued below )
304*ca987d46SWarner Losh			( c-addr1 u1 c-addr2 u2 )
305*ca987d46SWarner Losh			\ store the current src-addr byte into dest-addr
306*ca987d46SWarner Losh
307*ca987d46SWarner Losh		2swap 1+ 2swap	\ increment u1 in destination c-addr1/u1 pair
308*ca987d46SWarner Losh		swap 1+ swap	\ increment c-addr2 in source c-addr2/u2 pair
309*ca987d46SWarner Losh		1-		\ decrement u2 in the source c-addr2/u2 pair
310*ca987d46SWarner Losh
311*ca987d46SWarner Losh		dup 0= \ time to break?
312*ca987d46SWarner Losh	until
313*ca987d46SWarner Losh
314*ca987d46SWarner Losh	2drop	( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 )
315*ca987d46SWarner Losh		\ drop temporary number-format conversion c-addr2/u2
316*ca987d46SWarner Losh;
317*ca987d46SWarner Losh
318*ca987d46SWarner Losh: menuset-checksetnum ( N -- )
319*ca987d46SWarner Losh
320*ca987d46SWarner Losh	\
321*ca987d46SWarner Losh	\ adjust input to be both positive and no-higher than 65535
322*ca987d46SWarner Losh	\
323*ca987d46SWarner Losh	abs dup 65535 > if drop 65535 then ( n -- n )
324*ca987d46SWarner Losh
325*ca987d46SWarner Losh	\
326*ca987d46SWarner Losh	\ The next few blocks will determine if we should use the default
327*ca987d46SWarner Losh	\ methodology (referencing the original numeric stack-input), or if-
328*ca987d46SWarner Losh	\ instead $menuset_name{N} has been defined wherein we would then
329*ca987d46SWarner Losh	\ use the value thereof as the prefix to every menu variable.
330*ca987d46SWarner Losh	\
331*ca987d46SWarner Losh
332*ca987d46SWarner Losh	false menuset_use_name ! \ assume name is not set
333*ca987d46SWarner Losh
334*ca987d46SWarner Losh	menuset-setnum-namevar
335*ca987d46SWarner Losh	\
336*ca987d46SWarner Losh	\ We now have a string that is the assembled variable name to check
337*ca987d46SWarner Losh	\ for... $menuset_name{N}. Let's check for it.
338*ca987d46SWarner Losh	\
339*ca987d46SWarner Losh	2dup ( c-addr1 u1 -- c-addr1 u1 c-addr1 u1 ) \ save a copy
340*ca987d46SWarner Losh	getenv dup -1 <> if ( c-addr1 u1 c-addr1 u1 -- c-addr1 u1 c-addr2 u2 )
341*ca987d46SWarner Losh		\ The variable is set. Let's clean up the stack leaving only
342*ca987d46SWarner Losh		\ its value for later use.
343*ca987d46SWarner Losh
344*ca987d46SWarner Losh		true menuset_use_name !
345*ca987d46SWarner Losh		2swap 2drop	( c-addr1 u1 c-addr2 u2 -- c-addr2 u2 )
346*ca987d46SWarner Losh				\ drop assembled variable name, leave the value
347*ca987d46SWarner Losh	else ( c-addr1 u1 c-addr1 u1 -- c-addr1 u1 -1 ) \ no such variable
348*ca987d46SWarner Losh		\ The variable is not set. Let's clean up the stack leaving the
349*ca987d46SWarner Losh		\ string [portion] representing the original numeric input.
350*ca987d46SWarner Losh
351*ca987d46SWarner Losh		drop ( c-addr1 u1 -1 -- c-addr1 u1 ) \ drop -1 result
352*ca987d46SWarner Losh		12 - swap 12 + swap ( c-addr1 u1 -- c-addr2 u2 )
353*ca987d46SWarner Losh			\ truncate to original numeric stack-input
354*ca987d46SWarner Losh	then
355*ca987d46SWarner Losh
356*ca987d46SWarner Losh	\
357*ca987d46SWarner Losh	\ Now, depending on whether $menuset_name{N} has been set, we have
358*ca987d46SWarner Losh	\ either the value thereof to be used as a prefix to all menu_*
359*ca987d46SWarner Losh	\ variables or we have a string representing the numeric stack-input
360*ca987d46SWarner Losh	\ to be used as a "set{N}" infix to the same menu_* variables.
361*ca987d46SWarner Losh	\
362*ca987d46SWarner Losh	\ For example, if the stack-input is 1 and menuset_name1 is NOT set
363*ca987d46SWarner Losh	\ the following variables will be referenced:
364*ca987d46SWarner Losh	\ 	ansiset1_caption[x]		-> ansi_caption[x]
365*ca987d46SWarner Losh	\ 	ansiset1_caption[x][y]		-> ansi_caption[x][y]
366*ca987d46SWarner Losh	\ 	menuset1_acpi			-> menu_acpi
367*ca987d46SWarner Losh	\ 	menuset1_caption[x]		-> menu_caption[x]
368*ca987d46SWarner Losh	\ 	menuset1_caption[x][y]		-> menu_caption[x][y]
369*ca987d46SWarner Losh	\ 	menuset1_command[x]		-> menu_command[x]
370*ca987d46SWarner Losh	\ 	menuset1_init			-> ``evaluated''
371*ca987d46SWarner Losh	\ 	menuset1_init[x]		-> menu_init[x]
372*ca987d46SWarner Losh	\ 	menuset1_kernel			-> menu_kernel
373*ca987d46SWarner Losh	\ 	menuset1_keycode[x]		-> menu_keycode[x]
374*ca987d46SWarner Losh	\ 	menuset1_options		-> menu_options
375*ca987d46SWarner Losh	\ 	menuset1_optionstext		-> menu_optionstext
376*ca987d46SWarner Losh	\ 	menuset1_reboot			-> menu_reboot
377*ca987d46SWarner Losh	\ 	toggledset1_ansi[x]		-> toggled_ansi[x]
378*ca987d46SWarner Losh	\ 	toggledset1_text[x]		-> toggled_text[x]
379*ca987d46SWarner Losh	\ otherwise, the following variables are referenced (where {name}
380*ca987d46SWarner Losh	\ represents the value of $menuset_name1 (given 1 as stack-input):
381*ca987d46SWarner Losh	\ 	{name}ansi_caption[x]		-> ansi_caption[x]
382*ca987d46SWarner Losh	\ 	{name}ansi_caption[x][y]	-> ansi_caption[x][y]
383*ca987d46SWarner Losh	\ 	{name}menu_acpi			-> menu_acpi
384*ca987d46SWarner Losh	\ 	{name}menu_caption[x]		-> menu_caption[x]
385*ca987d46SWarner Losh	\ 	{name}menu_caption[x][y]	-> menu_caption[x][y]
386*ca987d46SWarner Losh	\ 	{name}menu_command[x]		-> menu_command[x]
387*ca987d46SWarner Losh	\ 	{name}menu_init			-> ``evaluated''
388*ca987d46SWarner Losh	\ 	{name}menu_init[x]		-> menu_init[x]
389*ca987d46SWarner Losh	\ 	{name}menu_kernel		-> menu_kernel
390*ca987d46SWarner Losh	\ 	{name}menu_keycode[x]		-> menu_keycode[x]
391*ca987d46SWarner Losh	\ 	{name}menu_options		-> menu_options
392*ca987d46SWarner Losh	\ 	{name}menu_optionstext		-> menu_optionstext
393*ca987d46SWarner Losh	\ 	{name}menu_reboot		-> menu_reboot
394*ca987d46SWarner Losh	\ 	{name}toggled_ansi[x]		-> toggled_ansi[x]
395*ca987d46SWarner Losh	\ 	{name}toggled_text[x]		-> toggled_text[x]
396*ca987d46SWarner Losh	\
397*ca987d46SWarner Losh	\ Note that menuset{N}_init and {name}menu_init are the initializers
398*ca987d46SWarner Losh	\ for the entire menu (for wholly dynamic menus) opposed to the per-
399*ca987d46SWarner Losh	\ menuitem initializers (with [x] afterward). The whole-menu init
400*ca987d46SWarner Losh	\ routine is evaluated and not passed down to $menu_init (which
401*ca987d46SWarner Losh	\ would result in double evaluation). By doing this, the initializer
402*ca987d46SWarner Losh	\ can initialize the menuset before we transfer it to active-duty.
403*ca987d46SWarner Losh	\
404*ca987d46SWarner Losh
405*ca987d46SWarner Losh	\
406*ca987d46SWarner Losh	\ Copy our affixation (prefix or infix depending on menuset_use_name)
407*ca987d46SWarner Losh	\ to our buffer so that we can safely use the s-quote (s") buf again.
408*ca987d46SWarner Losh	\
409*ca987d46SWarner Losh	menuset_affixbuf 0 2swap ( c-addr2 u2 -- c-addr1 0 c-addr2 u2 )
410*ca987d46SWarner Losh	begin ( using u2 in c-addr2/u2 pair as countdown to zero )
411*ca987d46SWarner Losh		over ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 c-addr2 u2 c-addr2 )
412*ca987d46SWarner Losh		c@   ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 c-addr2 u2 c )
413*ca987d46SWarner Losh		4 pick 4 pick
414*ca987d46SWarner Losh		     ( c-addr1 u1 c-addr2 u2 c -- continued below )
415*ca987d46SWarner Losh		     ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 )
416*ca987d46SWarner Losh		+    ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 -- continued below )
417*ca987d46SWarner Losh		     ( c-addr1 u1 c-addr2 u2 c c-addr3 )
418*ca987d46SWarner Losh		c!   ( c-addr1 u1 c-addr2 u2 c c-addr3 -- continued below )
419*ca987d46SWarner Losh		     ( c-addr1 u1 c-addr2 u2 )
420*ca987d46SWarner Losh		2swap 1+ 2swap	\ increment affixbuf byte position/count
421*ca987d46SWarner Losh		swap 1+ swap	\ increment strbuf pointer (source c-addr2)
422*ca987d46SWarner Losh		1-		\ decrement strbuf byte count (source u2)
423*ca987d46SWarner Losh		dup 0=          \ time to break?
424*ca987d46SWarner Losh	until
425*ca987d46SWarner Losh	2drop ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 ) \ drop strbuf c-addr2/u2
426*ca987d46SWarner Losh
427*ca987d46SWarner Losh	\
428*ca987d46SWarner Losh	\ Create a variable for referencing our affix data (prefix or infix
429*ca987d46SWarner Losh	\ depending on menuset_use_name as described above). This variable will
430*ca987d46SWarner Losh	\ be temporary and only used to simplify cmdbuf assembly.
431*ca987d46SWarner Losh	\
432*ca987d46SWarner Losh	s" affix" setenv ( c-addr1 u1 -- )
433*ca987d46SWarner Losh;
434*ca987d46SWarner Losh
435*ca987d46SWarner Losh: menuset-cleanup ( -- )
436*ca987d46SWarner Losh	s" type"  unsetenv
437*ca987d46SWarner Losh	s" var"   unsetenv
438*ca987d46SWarner Losh	s" x"     unsetenv
439*ca987d46SWarner Losh	s" y"     unsetenv
440*ca987d46SWarner Losh	s" affix" unsetenv
441*ca987d46SWarner Losh;
442*ca987d46SWarner Losh
443*ca987d46SWarner Loshonly forth definitions also menusets-infrastructure
444*ca987d46SWarner Losh
445*ca987d46SWarner Losh: menuset-loadsetnum ( N -- )
446*ca987d46SWarner Losh
447*ca987d46SWarner Losh	menuset-checksetnum ( n -- )
448*ca987d46SWarner Losh
449*ca987d46SWarner Losh	\
450*ca987d46SWarner Losh	\ From here out, we use temporary environment variables to make
451*ca987d46SWarner Losh	\ dealing with variable-length strings easier.
452*ca987d46SWarner Losh	\
453*ca987d46SWarner Losh	\ menuset_use_name is true or false
454*ca987d46SWarner Losh	\ $affix should be used appropriately w/respect to menuset_use_name
455*ca987d46SWarner Losh	\
456*ca987d46SWarner Losh
457*ca987d46SWarner Losh	\ ... menu_init ...
458*ca987d46SWarner Losh	s" set var=init" evaluate
459*ca987d46SWarner Losh	menuset-loadmenuvar
460*ca987d46SWarner Losh
461*ca987d46SWarner Losh	\ If menu_init was set by the above, evaluate it here-and-now
462*ca987d46SWarner Losh	\ so that the remaining variables are influenced by its actions
463*ca987d46SWarner Losh	s" menu_init" 2dup getenv dup -1 <> if
464*ca987d46SWarner Losh		2swap unsetenv \ don't want later menu-create to re-call this
465*ca987d46SWarner Losh		evaluate
466*ca987d46SWarner Losh	else
467*ca987d46SWarner Losh		drop 2drop ( n c-addr u -1 -- n )
468*ca987d46SWarner Losh	then
469*ca987d46SWarner Losh
470*ca987d46SWarner Losh	[char] 1 ( -- x ) \ Loop range ASCII '1' (49) to '8' (56)
471*ca987d46SWarner Losh	begin
472*ca987d46SWarner Losh		dup menuset_x tuck c! 1 s" x" setenv \ set loop iterator and $x
473*ca987d46SWarner Losh
474*ca987d46SWarner Losh		s" set var=caption" evaluate
475*ca987d46SWarner Losh
476*ca987d46SWarner Losh		\ ... menu_caption[x] ...
477*ca987d46SWarner Losh		menuset-loadmenuxvar
478*ca987d46SWarner Losh
479*ca987d46SWarner Losh		\ ... ansi_caption[x] ...
480*ca987d46SWarner Losh		menuset-loadansixvar
481*ca987d46SWarner Losh
482*ca987d46SWarner Losh		[char] 0 ( x -- x y ) \ Inner Loop ASCII '1' (48) to '9' (57)
483*ca987d46SWarner Losh		begin
484*ca987d46SWarner Losh			dup menuset_y tuck c! 1 s" y" setenv
485*ca987d46SWarner Losh				\ set inner loop iterator and $y
486*ca987d46SWarner Losh
487*ca987d46SWarner Losh			\ ... menu_caption[x][y] ...
488*ca987d46SWarner Losh			menuset-loadmenuxyvar
489*ca987d46SWarner Losh
490*ca987d46SWarner Losh			\ ... ansi_caption[x][y] ...
491*ca987d46SWarner Losh			menuset-loadansixyvar
492*ca987d46SWarner Losh
493*ca987d46SWarner Losh			1+ dup 57 > ( x y -- y' 0|-1 ) \ increment and test
494*ca987d46SWarner Losh		until
495*ca987d46SWarner Losh		drop ( x y -- x )
496*ca987d46SWarner Losh
497*ca987d46SWarner Losh		\ ... menu_command[x] ...
498*ca987d46SWarner Losh		s" set var=command" evaluate
499*ca987d46SWarner Losh		menuset-loadmenuxvar
500*ca987d46SWarner Losh
501*ca987d46SWarner Losh		\ ... menu_init[x] ...
502*ca987d46SWarner Losh		s" set var=init" evaluate
503*ca987d46SWarner Losh		menuset-loadmenuxvar
504*ca987d46SWarner Losh
505*ca987d46SWarner Losh		\ ... menu_keycode[x] ...
506*ca987d46SWarner Losh		s" set var=keycode" evaluate
507*ca987d46SWarner Losh		menuset-loadmenuxvar
508*ca987d46SWarner Losh
509*ca987d46SWarner Losh		\ ... toggled_text[x] ...
510*ca987d46SWarner Losh		s" set var=text" evaluate
511*ca987d46SWarner Losh		menuset-loadtoggledxvar
512*ca987d46SWarner Losh
513*ca987d46SWarner Losh		\ ... toggled_ansi[x] ...
514*ca987d46SWarner Losh		s" set var=ansi" evaluate
515*ca987d46SWarner Losh		menuset-loadtoggledxvar
516*ca987d46SWarner Losh
517*ca987d46SWarner Losh		1+ dup 56 > ( x -- x' 0|-1 ) \ increment iterator
518*ca987d46SWarner Losh		                             \ continue if less than 57
519*ca987d46SWarner Losh	until
520*ca987d46SWarner Losh	drop ( x -- ) \ loop iterator
521*ca987d46SWarner Losh
522*ca987d46SWarner Losh	\ ... menu_reboot ...
523*ca987d46SWarner Losh	s" set var=reboot" evaluate
524*ca987d46SWarner Losh	menuset-loadmenuvar
525*ca987d46SWarner Losh
526*ca987d46SWarner Losh	\ ... menu_acpi ...
527*ca987d46SWarner Losh	s" set var=acpi" evaluate
528*ca987d46SWarner Losh	menuset-loadmenuvar
529*ca987d46SWarner Losh
530*ca987d46SWarner Losh	\ ... menu_kernel ...
531*ca987d46SWarner Losh	s" set var=kernel" evaluate
532*ca987d46SWarner Losh	menuset-loadmenuvar
533*ca987d46SWarner Losh
534*ca987d46SWarner Losh	\ ... menu_options ...
535*ca987d46SWarner Losh	s" set var=options" evaluate
536*ca987d46SWarner Losh	menuset-loadmenuvar
537*ca987d46SWarner Losh
538*ca987d46SWarner Losh	\ ... menu_optionstext ...
539*ca987d46SWarner Losh	s" set var=optionstext" evaluate
540*ca987d46SWarner Losh	menuset-loadmenuvar
541*ca987d46SWarner Losh
542*ca987d46SWarner Losh	menuset-cleanup
543*ca987d46SWarner Losh;
544*ca987d46SWarner Losh
545*ca987d46SWarner Losh: menusets-unset ( -- )
546*ca987d46SWarner Losh
547*ca987d46SWarner Losh	s" menuset_initial" unsetenv
548*ca987d46SWarner Losh
549*ca987d46SWarner Losh	1 begin
550*ca987d46SWarner Losh		dup menuset-checksetnum ( n n -- n )
551*ca987d46SWarner Losh
552*ca987d46SWarner Losh		dup menuset-setnum-namevar ( n n -- n )
553*ca987d46SWarner Losh		unsetenv
554*ca987d46SWarner Losh
555*ca987d46SWarner Losh		\ If the current menuset does not populate the first menuitem,
556*ca987d46SWarner Losh		\ we stop completely.
557*ca987d46SWarner Losh
558*ca987d46SWarner Losh		menuset_use_name @ true = if
559*ca987d46SWarner Losh			s" set buf=${affix}menu_caption[1]"
560*ca987d46SWarner Losh		else
561*ca987d46SWarner Losh			s" set buf=menuset${affix}_caption[1]"
562*ca987d46SWarner Losh		then
563*ca987d46SWarner Losh		evaluate s" buf" getenv getenv -1 = if
564*ca987d46SWarner Losh			drop ( n -- )
565*ca987d46SWarner Losh			s" buf" unsetenv
566*ca987d46SWarner Losh			menuset-cleanup
567*ca987d46SWarner Losh			exit
568*ca987d46SWarner Losh		else
569*ca987d46SWarner Losh			drop ( n c-addr2 -- n ) \ unused
570*ca987d46SWarner Losh		then
571*ca987d46SWarner Losh
572*ca987d46SWarner Losh		[char] 1 ( n -- n x ) \ Loop range ASCII '1' (49) to '8' (56)
573*ca987d46SWarner Losh		begin
574*ca987d46SWarner Losh			dup menuset_x tuck c! 1 s" x" setenv \ set $x to x
575*ca987d46SWarner Losh
576*ca987d46SWarner Losh			s" set var=caption" evaluate
577*ca987d46SWarner Losh			menuset-unloadmenuxvar
578*ca987d46SWarner Losh			menuset-unloadmenuxvar
579*ca987d46SWarner Losh			menuset-unloadansixvar
580*ca987d46SWarner Losh			[char] 0 ( n x -- n x y ) \ Inner loop '0' to '9'
581*ca987d46SWarner Losh			begin
582*ca987d46SWarner Losh				dup menuset_y tuck c! 1 s" y" setenv
583*ca987d46SWarner Losh					\ sets $y to y
584*ca987d46SWarner Losh				menuset-unloadmenuxyvar
585*ca987d46SWarner Losh				menuset-unloadansixyvar
586*ca987d46SWarner Losh				1+ dup 57 > ( n x y -- n x y' 0|-1 )
587*ca987d46SWarner Losh			until
588*ca987d46SWarner Losh			drop ( n x y -- n x )
589*ca987d46SWarner Losh			s" set var=command" evaluate menuset-unloadmenuxvar
590*ca987d46SWarner Losh			s" set var=init"    evaluate menuset-unloadmenuxvar
591*ca987d46SWarner Losh			s" set var=keycode" evaluate menuset-unloadmenuxvar
592*ca987d46SWarner Losh			s" set var=text"    evaluate menuset-unloadtoggledxvar
593*ca987d46SWarner Losh			s" set var=ansi"    evaluate menuset-unloadtoggledxvar
594*ca987d46SWarner Losh
595*ca987d46SWarner Losh			1+ dup 56 > ( x -- x' 0|-1 ) \ increment and test
596*ca987d46SWarner Losh		until
597*ca987d46SWarner Losh		drop ( n x -- n ) \ loop iterator
598*ca987d46SWarner Losh
599*ca987d46SWarner Losh		s" set var=acpi"        evaluate menuset-unloadmenuvar
600*ca987d46SWarner Losh		s" set var=init"        evaluate menuset-unloadmenuvar
601*ca987d46SWarner Losh		s" set var=kernel"      evaluate menuset-unloadmenuvar
602*ca987d46SWarner Losh		s" set var=options"     evaluate menuset-unloadmenuvar
603*ca987d46SWarner Losh		s" set var=optionstext" evaluate menuset-unloadmenuvar
604*ca987d46SWarner Losh		s" set var=reboot"      evaluate menuset-unloadmenuvar
605*ca987d46SWarner Losh
606*ca987d46SWarner Losh		1+ dup 65535 > ( n -- n' 0|-1 ) \ increment and test
607*ca987d46SWarner Losh	until
608*ca987d46SWarner Losh	drop ( n' -- ) \ loop iterator
609*ca987d46SWarner Losh
610*ca987d46SWarner Losh	s" buf" unsetenv
611*ca987d46SWarner Losh	menuset-cleanup
612*ca987d46SWarner Losh;
613*ca987d46SWarner Losh
614*ca987d46SWarner Loshonly forth definitions
615*ca987d46SWarner Losh
616*ca987d46SWarner Losh: menuset-loadinitial ( -- )
617*ca987d46SWarner Losh	s" menuset_initial" getenv dup -1 <> if
618*ca987d46SWarner Losh		?number 0<> if
619*ca987d46SWarner Losh			menuset-loadsetnum
620*ca987d46SWarner Losh		then
621*ca987d46SWarner Losh	else
622*ca987d46SWarner Losh		drop \ cruft
623*ca987d46SWarner Losh	then
624*ca987d46SWarner Losh;
625