Trailing-Edge
-
PDP-10 Archives
-
decuslib20-03
-
decus/20-0078/libsim/form.sim
There are 4 other files named form.sim in the archive. Click here to see a list.
OPTIONS(/e/l);
EXTERNAL CHARACTER PROCEDURE fetchar, getch;
EXTERNAL INTEGER PROCEDURE trmop, gettab, checkreal, checkint;
EXTERNAL PROCEDURE depchar, echo, abort, outchr, forceout, outstring;
EXTERNAL TEXT PROCEDURE frontstrip, upcase, storbokstav, tmpin, scanto;
EXTERNAL BOOLEAN PROCEDURE tmpout, meny;
EXTERNAL CLASS vista, termty;
vista CLASS form;
NOT HIDDEN PROTECTED myinimage, show_page, ask_page, field,
intfield, realfield, choicefield, alphafield, first_field,
stopasking;
NOT HIDDEN height, echon, echoff, terminaltype,
resume_display, cancel_display, start_blink, stop_blink,
cause_real_time_delay, get_char_from_screen,
synchronize, restore_the_whole_screen,
home_the_cursor, set_char_on_screen,
outchar, blank_line, outimage, outtext, make_blank,
outfix, outreal, outint,
restore_one_char,
insingle, inimage, inint, inreal,
inword, inyes, move_the_cursor_to, blank_the_screen,
stopblink, startblink,
horizontalpos, verticalpos,
up, down, left, right, altmode,
carriagereturn, linefeed, home, fill,
null, tab, formfeed, verttab,
controlchar, screen, echoenabled;
BEGIN
REF (field) last_field, first_field, main_field,
temp_field;
BOOLEAN error_is_blinking, got_movechar, stopask,
last_is_controlchar;
INTEGER errmesslength, i, line, order, cover_length;
CHARACTER c, movechar; TEXT temp_answer;
PROCEDURE stopasking; stopask:= TRUE;
PROCEDURE myinimage(length, stopchar);
INTEGER length; CHARACTER stopchar;
BEGIN
BOOLEAN nostopchar; INTEGER count, firstpos;
firstpos:= horizontalpos;
sysin.image:= NOTEXT;
sysin.image.setpos(1);
WHILE TRUE DO
BEGIN
IF count > length THEN GOTO out;
c:= insingle(TRUE);
IF NOT nostopchar THEN
nostopchar:= stopchar NE c ELSE IF c = stopchar THEN
GOTO out;
IF NOT controlchar AND c NE fill THEN
BEGIN
sysin.image.putchar(c); count:= count+1;
last_is_controlchar:= FALSE;
IF c = '?' AND count = 1 THEN GOTO outfast;
END ELSE
BEGIN
IF c =
carriagereturn THEN
BEGIN insingle(TRUE);
GOTO outfast;
END;
last_is_controlchar:= TRUE;
BEGIN
IF c NE fill THEN GOTO out;
last_is_controlchar:= FALSE;
IF horizontalpos < firstpos THEN
move_the_cursor_to(firstpos,verticalpos);
IF sysin.pos > 1 THEN
BEGIN
IF echoenabled THEN
BEGIN
IF count <= 0 THEN outchar(' ');
END ELSE
BEGIN
sysin.setpos(sysin.pos-1);
sysin.image.putchar(' ');
sysin.setpos(sysin.pos-1);
END;
END;
END;
END;
END;
out: IF c NE tab THEN
sysin.image.putchar(c);
outfast: sysin.image.setpos(1);
END;
PROCEDURE show_page;
BEGIN
FOR temp_field:- first_field,
temp_field.next WHILE temp_field =/= NONE DO
INSPECT temp_field DO
BEGIN
putheader; answer:- NOTEXT;
END;
END;
PROCEDURE ask_page;
BEGIN
loop: IF stopask THEN stopask:= FALSE ELSE
FOR temp_field:- first_field,
temp_field.next WHILE temp_field =/= NONE DO
IF temp_field.answer = NOTEXT THEN
BEGIN
resume(temp_field);
GOTO loop;
END;
sysout.breakoutimage;
END;
CLASS field(h,v,header,length,stopchar, helptext);
VALUE header, helptext;
INTEGER h, v, length; CHARACTER stopchar;
TEXT header, helptext;
VIRTUAL: PROCEDURE help;
BEGIN
TEXT answer; INTEGER orderinline;
REF(field) next;
PROCEDURE help;
BEGIN
IF helptext == NOTEXT THEN helptext:-
copy("There is no HELP available here");
blank_line(18);
move_the_cursor_to(0,18); outtext(helptext); breakoutimage;
error_is_blinking:= TRUE;
END;
PROCEDURE error(errmess); VALUE errmess; TEXT errmess;
BEGIN
move_the_cursor_to(0,18); start_blink;
outtext("->"); stop_blink;
outtext(errmess);
error_is_blinking:= TRUE;
errmesslength:= errmess.length;
GOTO get_answer;
END;
PROCEDURE putheader;
IF header =/= NOTEXT THEN
BEGIN
move_the_cursor_to(h,v); outtext(header);
END;
PROCEDURE screen_answer(answer);
TEXT answer;
COMMENT will put answer onto screen,
covering cover_length chars;
BEGIN
move_the_cursor_to(h+header.length+1,v);
outtext(answer);
make_blank(length-answer.length);
END;
PROCEDURE change_answer(new_answer);
VALUE new_answer; TEXT new_answer;
BEGIN
i:= answer.length;
answer:- new_answer;
screen_answer(answer);
END;
IF last_field =/= NONE THEN last_field.next:- THIS
field;
last_field:- THIS field;
IF first_field == NONE THEN first_field:- THIS field;
IF line NE v THEN
BEGIN
line:= v; order:= orderinline:= 1;
END ELSE
BEGIN orderinline:= order:= order+1;
END;
detach;
get_answer:
move_the_cursor_to(h+header.length+1,v);
IF echoenabled THEN inimage ELSE
myinimage(length,stopchar);
temp_answer:- copy(frontstrip(sysin.image.strip));
IF temp_answer = "?" THEN
BEGIN help; GOTO get_answer;
END;
IF sysin.image.sub(1,1) = " " AND temp_answer =/= NOTEXT
THEN screen_answer(temp_answer);
movechar:= IF temp_answer == NOTEXT THEN ' ' ELSE
temp_answer.sub(temp_answer.length,1).getchar;
got_movechar:= IF last_is_controlchar THEN
movechar = left OR movechar = right
OR movechar = up OR movechar = down
OR movechar = home ELSE FALSE;
IF error_is_blinking THEN
BEGIN
blank_line(18); error_is_blinking:= FALSE;
IF answer.length > temp_answer.length THEN
BEGIN
move_the_cursor_to(h+header.length+1
+temp_answer.length-
(IF got_movechar THEN 1 ELSE 0),v);
cover_length:= answer.length-temp_answer.length
+(IF got_movechar THEN 1 ELSE 0);
FOR i:= 1 STEP 1 UNTIL cover_length DO outchar(' ');
END;
answer:- NOTEXT;
END;
IF answer.length > temp_answer.length AND
NOT (NOT echoenabled AND got_movechar
AND temp_answer.length = 1) THEN
BEGIN
move_the_cursor_to(h+header.length+1+temp_answer.
length, v);
cover_length:= answer.length;
FOR i:= temp_answer.length+1 STEP 1 UNTIL
cover_length DO outchar(' ');
END;
IF (IF temp_answer == NOTEXT THEN FALSE
ELSE temp_answer.sub(1,1) = "^") THEN
BEGIN
TEXT searched; REF(field) test_field;
screen_answer(answer);
searched:- temp_answer.sub(2,temp_answer.length-1);
test_field:- first_field;
WHILE test_field =/= NONE DO
BEGIN
IF test_field.header.length >= searched.length
THEN
BEGIN
IF test_field.header.sub(1,
searched.length) = searched THEN
BEGIN
IF test_field =/= THIS field THEN
BEGIN
IF main_field == NONE THEN main_field:-
THIS field;
resume(test_field);
END;
GOTO get_answer;
END;
END;
test_field:- test_field.next;
END;
error("No such header.");
END;
IF NOT echoenabled THEN
BEGIN
IF got_movechar THEN
BEGIN
INTEGER goalline, goalorder;
BOOLEAN modified_goal;
REF (field) test_field, back_field;
IF movechar = home THEN
BEGIN goalline:= 0; goalorder:= 1;
END ELSE IF movechar = left THEN
BEGIN goalline:= v; goalorder:= orderinline-1;
IF goalorder < 1 THEN goalorder:= 1;
END ELSE IF movechar = right THEN
BEGIN goalline:= v; goalorder:= orderinline+1;
END ELSE IF movechar = up THEN
BEGIN goalline:= v-1; goalorder:= orderinline;
END ELSE IF movechar = down THEN
BEGIN goalline:= v+1; goalorder:= orderinline;
END;
test_field:- first_field;
WHILE test_field =/= NONE DO
BEGIN
tryagain: IF test_field.v = goalline AND
test_field.orderinline =
goalorder THEN GOTO found;
IF test_field.v > goalline THEN
BEGIN
IF back_field =/= NONE THEN
BEGIN
IF movechar = up AND NOT modified_goal THEN
BEGIN
modified_goal:= TRUE;
goalline:= back_field.v;
test_field:-first_field;
GOTO tryagain;
END ELSE IF movechar = down THEN
BEGIN
IF test_field.v-back_field.v>1 THEN
goalline:=
goalline+test_field.v-back_field.v-1;
GOTO tryagain;
END;
END;
GOTO backfound;
END;
back_field:- test_field;
test_field:- test_field.next;
END;
IF movechar = down AND NOT modified_goal THEN
BEGIN
modified_goal:= TRUE;
goalline:= goalline-1;
test_field:- first_field;
GOTO tryagain;
END;
backfound: IF back_field =/= NONE
THEN test_field:- back_field;
found: IF test_field =/= THIS field THEN
BEGIN
IF main_field == NONE THEN main_field:-
THIS field;
resume(test_field);
END;
GOTO get_answer;
END;
END;
answer:- temp_answer;
INNER; IF main_field == NONE THEN detach ELSE
BEGIN temp_field:- main_field; main_field:- NONE;
IF temp_field =/= THIS field AND
temp_field.answer == NOTEXT THEN
resume(temp_field) ELSE detach;
END;
GOTO get_answer;
END of field;
field CLASS intfield(min,max,rangerror);
VALUE rangerror; INTEGER min, max; TEXT rangerror;
BEGIN
INTEGER intvalue;
answer.setpos(1);
IF checkint(answer) >= 1 AND NOT answer.more THEN
BEGIN
answer.setpos(1); intvalue:= answer.getint;
IF intvalue < min OR intvalue > max THEN
error(rangerror);
END ELSE error("Integer input was expected.");
END;
field CLASS realfield(min,max,rangerror);
VALUE rangerror; REAL min, max; TEXT rangerror;
BEGIN
REAL realvalue;
answer.setpos(1);
IF checkreal(answer) >= 1 AND NOT answer.more THEN
BEGIN
answer.setpos(1); realvalue:= answer.getreal;
IF realvalue < min OR realvalue > max THEN
error(rangerror);
END ELSE error("Integer input was expected.");
END;
field CLASS choicefield(nonemessage);
VALUE nonemessage; TEXT nonemessage;
BEGIN
CLASS choice(choicetext);
VALUE choicetext; TEXT choicetext;
BEGIN
REF (choice) nextchoice;
upcase(choicetext);
IF lastchoice =/= NONE THEN
lastchoice.nextchoice:- THIS choice ELSE
firstchoice:- THIS choice;
lastchoice:- THIS choice;
END;
REF (choice) firstchoice, lastchoice, tempchoice;
REF (choice) foundchoice;
foundchoice:- NONE;
upcase(answer);
IF answer =/= NOTEXT THEN
BEGIN
tempchoice:- firstchoice;
WHILE tempchoice =/= NONE DO
BEGIN
INSPECT tempchoice DO
IF answer.length <= choicetext.length THEN
BEGIN
IF choicetext.sub(1,answer.length) = answer THEN
BEGIN
IF answer.length EQ choicetext.length THEN
GOTO good;
IF foundchoice =/= NONE THEN
BEGIN
error("Ambiguous entry, give more characters.");
GOTO good;
END;
foundchoice:- tempchoice;
END;
END;
tempchoice:- tempchoice.nextchoice;
END;
END;
IF foundchoice == NONE THEN error(nonemessage)
ELSE change_answer(foundchoice.choicetext);
good:
END of choicefield;
field CLASS alphafield;
BEGIN
answer.setpos(1);
WHILE answer.more DO
BEGIN
c:= answer.getchar;
IF NOT letter(c) AND c NE ' ' THEN
error("Only letters accepted in answer.");
END;
END of alphafield;
line:= -1;
END of form;