%%s 10/2/249 %%d D 1.3 14-Dec-82 15:34:20 sventek 3 2 %%c Updated form.fmt to reflect the addition of the multi-line prompt %%c capability. %%s 34/21/217 %%d D 1.2 20-Oct-82 16:56:56 sventek 2 1 %%c Modified form.w`form.r`guser to permit multi-line prompts if the %%c left-most bracketing character is immediately followed by a minus ('-') %%c as in <-long prompt>. Upon detection of a prompt of this form, the input %%c can only be terminated by typing a bare period ('.') on a line, as in the %%c editor. This fact is brought to the user's attention when the prompt is %%c displayed. %%s 0/0/0 %%d D 1.1 25-Mar-82 12:06:22 v1.1 1 0 %%c Version 1.1 is the Spring 1982 Distribution of the LBL/Hughes release %%c of the Software Tools Virtual Operating System software and documentation. %%T %%I 1 #-h- cform 276 asc 25-mar-82 07:56:56 v1.1 (sw-tools v1.1) ## cform common block for formletter tool # put on a file named 'cform' # Used only by form common /cform/ char1, char2 character char1 #character to indicate beginning of prompt; #init = LESS character char2 #character to terminate prompt; #init = GREATER %%D 2 #-h- form.r 3741 asc 25-mar-82 07:56:57 v1.1 (sw-tools v1.1) %%E 2 %%I 2 #-h- form.r 4282 asc 20-oct-82 16:54:42 sventek (joseph sventek) %%E 2 #-h- defns 328 asc 25-mar-82 07:56:43 v1.1 (sw-tools v1.1) define(MAXFILES,10) #number files allowed on command line define(MAXREPLY,5000) #maximum characters available in user's response ifdef(LARGE_ADDRESS_SPACE) define(MEM_SIZE,20000) elsedef define(MEM_SIZE,5000) # size of dynamic storage in words enddef define(ESCAPE,'-') define(Push_back,100) # size of push back buffer #-h- main 1037 asc 25-mar-82 07:56:44 v1.1 (sw-tools v1.1) ## form - replace all instances of '<...>' in file with input from user DRIVER(form) character line(MAXLINE) integer getarg, open integer i, nfiles character fnames(FILENAMESIZE, MAXFILES) include cform DS_DECL(Mem, MEM_SIZE) PB_DECL(Push_back) string usestr "usage: form [-c] [+c] file ..." data char1 /'<'/ data char2 /'>'/ call query(usestr) call tbinit(MEM_SIZE) # initialize tblook and tbinst block call pbinit(Push_back) # initialize push-back buffer nfiles = 0 for (i=1; getarg(i, line, MAXLINE) != EOF; i=i+1) { if (line(1) == '-' & line(2) != EOS) char1 = line(2) else if (line(1) == '+') char2 = line(2) else { nfiles = nfiles + 1 if (nfiles > MAXFILES) call error ("too many file names") call scopy(line, 1, fnames(1, nfiles), 1) } } for (i=1; i<=nfiles; i=i+1) #loop through all files { int = open(fnames(1,i), READ) if (int == ERR) call cant(fnames(1,i)) call forml(int) call close(int) } if (i == 1) #no input file call error (usestr) DRETURN end #-h- forml 612 asc 25-mar-82 07:56:45 v1.1 (sw-tools v1.1) ##forml - replace prompts with user input on file 'int' subroutine forml(int) integer int, tog integer ftok, guser, tblook character token(MAXLINE), defn(MAXREPLY) include cform tog = NO while (ftok(token, int, tog) != EOF) { if (tog == YES) #inside prompt { if (token(1) == char2) { tog = NO next } if (tblook(token, defn) == NO) { if (guser(token, defn) == EOF) break call tbinst(token, defn) } call putlin(defn, STDOUT) next } else if (token(1) == char1) { tog = YES next } call putlin(token, STDOUT) #output normal text } return end #-h- ftok 627 asc 25-mar-82 07:56:45 v1.1 (sw-tools v1.1) ## ftok - pick up token for form letter integer function ftok(token, int, prflag) character token(ARB) integer int, prflag character ngetch include cform for (i=1; i< MAXREPLY; i=i+1) { ftok = ngetch(token(i), int) if (ftok == EOF | (prflag == NO & ftok == '@n') | (i == 1 & ftok == char1) | (i == 1 & ftok == char2) ) break if (ftok == char1 | ftok == char2) #beginning of next token { call putbak(ftok) if (ftok == char2 & prflag == YES) token(i) = ' ' else i = i - 1 break } } if (i >=MAXREPLY) call error ("token too long.") token(i+1) = EOS return end %%D 2 #-h- guser 772 asc 25-mar-82 07:56:46 v1.1 (sw-tools v1.1) %%E 2 %%I 2 #-h- guser 1309 asc 20-oct-82 14:17:57 sventek (joseph sventek) %%E 2 ##guser - get form letter replacement text from user integer function guser(pstr, repl) %%D 2 character repl(ARB), pstr(ARB) integer getlin, prompt %%E 2 %%I 2 character repl(ARB), pstr(ARB), pbuf(MAXLINE), buf(MAXLINE) integer getlin, prompt, equal %%E 2 integer lth %%I 2 string extpmt "(terminate answer with a dot line)@n" string dotnln ".@n" %%E 2 %%D 2 lth = 0 %%E 2 %%I 2 lth = 1 repl(1) = EOS if (pstr(1) == ESCAPE) # have extended prompt call concat(pstr(2), extpmt, pbuf) else call strcpy(pstr, pbuf) %%E 2 repeat { %%D 2 if (lth == 0) i = prompt(pstr, repl(lth+1), STDIN) else %%E 2 %%I 2 if (lth == 1) %%E 2 %%D 2 i = getlin(repl(lth+1), STDIN) %%E 2 %%I 2 i = prompt(pbuf, buf, STDIN) else i = getlin(buf, STDIN) %%E 2 if (i == EOF) break %%D 2 lth = lth + i if (lth >= MAXREPLY) #oops--too long %%E 2 %%I 2 if ((pstr(1) == ESCAPE) & equal(buf, dotnln) == YES) break if (lth + i > MAXREPLY) #oops--too long %%E 2 { call remark ("truncating response") break } %%D 2 if (lth == 1) # (dpm 3-Nov-81) break if (repl(lth) == '@n' & repl(lth-1) != ESCAPE) break #no more lth = lth - 1 repl(lth) = '@n' #remove the escape #and continue %%E 2 %%I 2 call stcopy(buf, 1, repl, lth) if (pstr(1) != ESCAPE) # see if explicitly continued if (i == 1) # only a newline, so break break else if (buf(i-1) != ESCAPE) # not escape character break else # copy '@n' over ESCAPE { lth = lth - 2 call chcopy('@n', repl, lth) } %%E 2 } %%D 2 if (repl(lth) == '@n') #remove last '@n' %%E 2 %%I 2 if (repl(lth-1) == '@n') #remove last '@n' %%E 2 lth = lth - 1 %%D 2 repl(lth+1) = EOS %%E 2 %%I 2 repl(lth) = EOS %%E 2 if (i == EOF) guser = EOF else %%D 2 guser = lth %%E 2 %%I 2 guser = lth - 1 %%E 2 return end %%D 3 #-h- form.fmt 1420 asc 25-mar-82 07:56:59 v1.1 (sw-tools v1.1) %%E 3 %%I 3 #-h- form.fmt 1784 asc 14-dec-82 15:33:36 sventek (joseph sventek) %%E 3 .so ~bin/manhdr .hd Form (1) 1-Mar-79 produce form letter by prompting user for information .sy form [-c] [+c] file ... .ds Form reads input files and writes them to the standard output. Any time it encounters some characters surrounded by angle brackets ('<' and '>') it prints the string between the characters as a prompt to the user. It then reads from the standard input and replaces the bracketed string with what was read. Normally only one line of input is accepted from the standard input. However, a response can be continued on succeeding lines by terminating each line to be continued with a minus ('-'). %%D 3 %%E 3 %%I 3 Multi-line input will also be accepted if the left-most bracketing character of the prompt is immediately followed by a minus ('-') as in <-long prompt>. Upon detection of a prompt of this form, the input can only be terminated by typing a bare period ('.') on a line, as in the editor. This fact is brought to the user's attention when the prompt is displayed. %%E 3 The prompts inside the file may also span line boundaries if so desired. The user's answers to prompts are remembered, so duplicate prompts are replaced without repeating the prompt to the user. If the standard input is not a terminal, no prompts are issued. The '-c' flag may be used to reset the initial character signalling a prompt. The character 'c' then replaces the '<'. The '+c' flag may be used to reset the terminating character of a prompt. The character 'c' then replaces '>'. .fl Your terminal is opened at READ access. .sa The Unix form-letter tool .br .di If an input file cannot be opened, a message is printed and execution is terminated. A message is also printed if either the prompt or the response is too long for the tool's internal buffer. .au Debbie Scherrer .bu %%E 1