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