home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / cpmug / cpmug081.ark / SUPERSUB.DOC < prev    next >
Encoding:
Text File  |  1984-04-29  |  14.2 KB  |  337 lines

  1.             SUPERSUB
  2.  
  3.          A replacement for the CP/M SUBMIT utility
  4.  
  5.                         Ron Fowler
  6.                         Nov. 16, 1981
  7.                         Westland, Michigan
  8.  
  9.  
  10.  
  11.  
  12.      One of the most useful programs provided with CP/M is the 
  13. SUBMIT utility, which allows system commands to be read from a 
  14. disk file for automatic processing.  Its command-line 
  15. substitution facility provides a convenient means of developing 
  16. "prototype" command files, with actual parameter substitution 
  17. performed when the command file is invoked.
  18.      There are, however, some shortcomings associated with 
  19. SUBMIT that recur frequently.  Frequently enough to inspire me 
  20. to write my own batch processor, SUPERSUB, that completely 
  21. replaces, and is fully compatible with, the standard SUBMIT 
  22. utility.
  23.  
  24. PROBLEMS WITH SUBMIT
  25.  
  26.      SUBMIT will produce a "garbaged" output file whenever it 
  27. encounters an empty line in the input file.  This is a real 
  28. handicap when attempting to pass command lines to PIP.COM, for 
  29. example, using XSUB (the CP/M2 utility that extends the SUBMIT 
  30. capability to transient programs), since the only way to exit 
  31. PIP is to enter an empty command line (you can enter a control-
  32. "C" as the first character of the line, but this is a "real-
  33. time" function, and cannot be done within a SUBMIT file). 
  34. SUPERSUB generates the necessary zero-length line in the output 
  35. file.
  36.       Another SUBMIT drawback is the constant need to enter an 
  37. editor and create a command file, even for the simplest of 
  38. jobs.  This added step discourages the use of SUBMIT for very 
  39. simple "command stacking" applications. With this in mind, I 
  40. gave SUPERSUB the ability to interactively accept command lines 
  41. from the console.  An additional option allows the entire job 
  42. to be specified on the SUPERSUB command line.
  43.  
  44. COMMAND FILE NESTING
  45.  
  46.      I felt that a nesting capability would be a significant 
  47. feature to add to SUPERSUB.  For example, it would be useful to 
  48. create a submit file called COMPILE.SUB, to facilitate the 
  49. program compilation process, and "clean up" any leftover files.  
  50. COMPILE.SUB might look like this:
  51.  
  52.     BASCOM =$1      ;COMPILE PROGRAM SPECIFIED IN CMD LINE
  53.     L80 $1,$1/N/E      ;LINK THE PROGRAM
  54.     PIP B:=$1.COM      ;MOVE THE OBJECT FILE TO THE B DRIVE
  55.     ERA $1.REL      ;DELETE THE .REL FILE
  56.     ERA $1.COM      ;  AND THE OBJECT FILE
  57.  
  58.      Now let's say I want to compile several programs at once 
  59. (a common situation in applications programming).  Under 
  60. SUBMIT, I would have to type in a SUBMIT invocation for each 
  61. program:
  62.  
  63.    A>SUBMIT COMPILE LEDGER    [COMPILE.SUB executes, operator waits
  64.                  for it to complete, then types:]
  65.    A>SUBMIT COMPILE PAYABLES  [more waiting for COMPILE.SUB, then:]
  66.    A>SUBMIT COMPILE RECVBLES  [and the job is finally done.]
  67.  
  68.      Using SUPERSUB, I can create a file (CMPILALL.SUB) 
  69. containing the commands
  70.  
  71.    SUBMIT COMPILE LEDGER
  72.    SUBMIT COMPILE PAYABLES
  73.    SUBMIT COMPILE RECVBLES
  74.  
  75. and execute the whole thing with the single command line
  76.  
  77.    A>SSUB CMPILALL
  78.  
  79. (Note that I've abbreviated SUPERSUB to SSUB on all my disks; 
  80. SUPERSUB as a name is a bit grandiose anyway).  I can also save 
  81. the trouble of creating CMPILALL.SUB (especially if I want to 
  82. do this only once) and enter the single command line
  83.  
  84.    A>SSUB /COMPILE LEDGER;SSUB COMPILE PAYABLES;SSUB COMPILE RECVBLES
  85.  
  86. or, if the individual command lines to be executed are a bit 
  87. long, I can specify the Interactive mode by entering only a 
  88. slash ("/") on the command line (after the SUPERSUB 
  89. invocation).  SUPERSUB will then prompt for each command line 
  90. with an asterisk.  To continue the previous example,
  91.  
  92.    A>SSUB /
  93.    *COMPILE LEDGER
  94.    *SSUB COMPILE PAYABLES
  95.    *SSUB COMPILE RECVBLES
  96.    *                       [empty line here terminates]
  97.  
  98. ON-LINE HELP FUNCTION
  99.  
  100.      I believe all programs of any complexity should be "self-
  101. instructive" by providing the user a means of typing out, on 
  102. the terminal, the major modes of operation, and any necessary 
  103. command line syntax.  Further, the command line used to invoke 
  104. this "help summary" should be the simplest possible form not 
  105. otherwise used by the program.  In the case of SUPERSUB, this 
  106. is a command line with no arguments at all:
  107.  
  108.    A>SSUB
  109.  
  110. SUBMIT.COM COMPATIBILITY
  111.  
  112.      SUPERSUB is fully compatible with CP/M's SUBMIT utility, 
  113. including command parameter substitution and control-character 
  114. translation:
  115.  
  116.    1) Parameters within the "prototype" file, of the form $1, 
  117.       $2, etc., are substituted from the command line on a one-
  118.       for-one basis.  Parameters are passed through to any 
  119.       nested files.  Two successive dollar-sign characters 
  120.       ("$$") may be used to introduce a single "$" into the 
  121.       output file.
  122.  
  123.    2) An up-arrow symbol ("^") may precede an alphabetic 
  124.       character to insert the associated control-character into 
  125.       the output file.
  126.  
  127. DETAILED INSTRUCTIONS
  128.  
  129.      In addition to the normal SUBMIT mode of operation and 
  130. associated command line usage, SUPERSUB provides two additional 
  131. modes of input: Interactive and Summary.
  132.  
  133.  
  134. SUMMARY MODE
  135.  
  136. Summary mode allows the entire SUBMIT job to be specified in 
  137. the CP/M command line.  This mode is enabled by using the slash 
  138. ("/")character as the first character of the command line. The 
  139. individual submit lines must be seperated with a semicolon. For 
  140. example,
  141.  
  142.      A>SSUB / CRCK *.* F;CRCK B:*.* F;COMPARE CRCKFILE.CRC B:
  143.          ^
  144.          |
  145.           ----> (this space is optional)
  146.  
  147. will create a file of CRC's of all files on A:, then create a 
  148. similar file on B:, then compare the two.  (CRCK, by Keith 
  149. Petersen, and COMPARE, by Ward Christensen, are available from 
  150. the CP/M Users Group).
  151.  
  152. INTERACTIVE MODE
  153.  
  154. You may enter the interactive entry mode by typing 
  155. "SUPERSUB /<CR>" (ie, "SUPERSUB /" with no arguments).  
  156. Supersub will prompt for input with an asterisk, and you may 
  157. then enter SUBMIT lines from the keyboard.  Multiple commands 
  158. may be entered on a line by separating them with semicolons.  
  159. An empty line terminates the input.  Example:
  160.  
  161. A>SUPERSUB /
  162. *CRCK *.* F
  163. *CRCK B:*.* F
  164. *COMPARE CRCKFILE.CRC B:
  165. *                <empty line here>
  166. A>CRCK *.* F            <submit file begins execution>
  167.  
  168. has the same effect as the above SUMMARY mode example.
  169.  
  170. HELP FUNCTION
  171.  
  172. Typing SUPERSUB with no arguments will print the built-in help 
  173. file.
  174.  
  175.  
  176.  
  177.  
  178.  
  179. NOTES
  180.  
  181. 1) Nested SUBMIT runs are only usable up to a maximum of 128 
  182.    nested commands at any one time.  This is a limitation of 
  183.    the CP/M Console Command Processor.
  184.  
  185. 2) If you change the drive specification for the output file, 
  186.    you may want to do the same thing with XSUB (Digital 
  187.    Research's function nine extender).  Within XSUB, find the 
  188.    submit File Control Block (search for "$$$     SUB" within 
  189.    XSUB.COM)  and change the first FCB byte (ie, the byte 
  190.    before the first "$") to:
  191.         0 - to use default drive
  192.         1 - to use drive A:
  193.         2 - to use drive B:
  194.    etc.
  195.  
  196. 3) In SUMMARY and INTERACTIVE modes, passed parameters have no 
  197.    meaning.  When these modes are used, the parameter flag, 
  198.    "$", will be passed through literally to the output file.
  199.  
  200. 4) Zero-length output lines may be created in SUMMARY and 
  201.    INTERACTIVE modes by using two consecutive semicolons.  This 
  202.    is, in effect, a blank logical line.
  203.  
  204. 5) Interactive mode may be aborted by typing control-C as the 
  205.    first character of a line.  Also, all normal CP/M editing 
  206.    characters are available in this mode.
  207.  
  208. HOW IT WORKS
  209.  
  210.      Those who have been following Ward Christensen's series of 
  211. tutorials on CP/M know that the output file ($$$.SUB) consists 
  212. of lines from the input file written in reverse order, one line 
  213. per CP/M record.  To fully understand how this file is built, 
  214. refer to the assembly listing while reading the following 
  215. program description.
  216.  
  217.      SUPERSUB can be divided into three distinct sections: 
  218. initialization, input file read, and output file write 
  219. ($$$.SUB).  Each will be discussed, along with any called 
  220. subroutines.
  221.  
  222. PROGRAM INITIALIZATION
  223.  
  224.      Initialization begins with a check for a HELP request (an 
  225. empty command line), which suppresses the sign-on message, and 
  226. branches directly to the HELP print routine.
  227.      If there is no help request, then the sign-on message is 
  228. printed and the routine INITVAR is called. INITVAR zeroes the 
  229. working variable area and initializes to empty the table which 
  230. will later hold the address of each command-line parameter.
  231.      Next, the routine GETPAR is called.  GETPAR parses the 
  232. input command line, setting up the variables OPTION and CLFLAG 
  233. (which will be used later to determine the input mode), and 
  234. calls the routine PUTPAR as each command-line parameter is 
  235. encountered.  PUTPAR stores each parameter (prefixed by its 
  236. length) into free memory, advances the free memory pointer, and 
  237. stores a pointer to the parameter into TABLE.  This pointer 
  238. will later be used to locate the parameter when user parameter 
  239. substitution is done.
  240.      Finally, the input file control block is prepared for use 
  241. by the routine SETUP.  SETUP insures that the input name 
  242. specified is of type "SUB".  If the type field is left blank, 
  243. SETUP moves the correct type into place.
  244.  
  245. READING THE INPUT FILE
  246.  
  247.      The RDFILE routine has the responsibility of reading in 
  248. the user's text file.  RDFILE reads each line sequentially into 
  249. memory, prefixed by a link word that contains the absolute 
  250. memory address of the previous line (the first line has a link 
  251. value of zero) followed by a length byte, then the line itself 
  252. (stripped of carriage-return/line feed characters).  No 
  253. parameter substitution is done during the file read.
  254.      RDFILE increases the value of LINNUM with each line read.  
  255. This variable is used by the error handlers to provide line 
  256. number reporting when an error is encountered.
  257.      RDFILE gets its input character-by-character by calling 
  258. GNB, the character "GET" routine.  This is the level at which 
  259. the command-line option flags OPTION and CLFLAG must be used to 
  260. determine the source of characters.  If the OPTION variable is 
  261. an ascii slash ("/"), then the character is retrieved from the 
  262. GNBKBD routine.  Otherwise control passes to GNB1, which 
  263. handles disk file character input.  GNB1 uses the IBP byte to 
  264. form a pointer into TBUF, the disk buffer.  If IBP is pointing 
  265. past the buffer end, the FILL routine is called to refill TBUF.  
  266. IBP is then incremented, and the character is returned in the 
  267. accumulator.
  268.      The GNBKBD routine is used when the input source is NOT a 
  269. disk file.  At this point, there are two possible sources of 
  270. input: the original command line (Summary mode) and the console 
  271. (Interactive mode).  The flag CLFLAG is used to decide which 
  272. source to use.  If CLFLAG is non-zero, then the Summary mode is 
  273. active, and characters are read from the original command line 
  274. (passed by CP/M in TBUF).  A CLFLAG of zero indicates 
  275. Interactive mode, and characters are read from the keyboard 
  276. buffer CLBUF (which is filled using CP/M function #10 whenever 
  277. it is found empty by GNBKBD).
  278.      The code at label GNBCL is common to both modes, and 
  279. substitutes an end-of-line character for a semicolon, to allow 
  280. multiple logical lines on a physical line.
  281.      The end of file condition is returned by GNB as a 1AH in 
  282. the accumulator.  This value is normally returned only from a 
  283. disk file, so special logic in GNBKBD must detect the end 
  284. condition.  This logic returns EOF at the end of the input 
  285. command line (in Summary mode) or upon entry of an empty line 
  286. (in Interactive mode).
  287.  
  288. WRITING THE OUTPUT FILE
  289.  
  290.      You may have wondered why the input file was read in with 
  291. link pointers and length bytes added.  That's because CP/M's 
  292. CCP (and XSUB utility) read the temporary submit file BACKWARD, 
  293. one line packed into each disk record.  This allows CP/M to use 
  294. the record count and next record fields of the directory entry 
  295. as file pointers.  This also means that SUPERSUB must write out 
  296. the last line first, followed by the next-to-last line, etc., 
  297. with the first line of the input file being at the END of the 
  298. output file.  The linked list provides a simple means of 
  299. traversing the lines in reverse order.
  300.      The subroutine WRSUB writes the output file, and is the 
  301. last routine called by the mainline code.  WRSUB first scans 
  302. backward from the end of the input file, looking for the last 
  303. line in the file that is not empty.  If one is found (an error 
  304. message is issued if one is not), control passes to the WRLOP 
  305. loop, which calls PUTLIN to move the line to the output buffer, 
  306. decrements the line number for possible error reporting 
  307. (remember, we're working BACKWARD now), and scans back to the 
  308. previous line to repeat the process.  If there is no previous 
  309. line (indicated by a link pointer with zero value), then the 
  310. file is closed, and a warm-boot to CP/M is executed, causing 
  311. the batch job to begin.
  312.      The PUTLIN routine moves characters one-by-one from the 
  313. input line stored in memory to the output buffer at TBUF.  This 
  314. is the point where parameter substitution and control-character 
  315. translation take place (unless Summary or Interactive modes are 
  316. active, which have no reason to do substitutions).  Buffer 
  317. pointers and counters are set up for the GETCHR and PUTCHR 
  318. routines, after which characters are received one-at-a-time by 
  319. calling GETCHR.
  320.      Each character is checked to see if it is either of the 
  321. option characters, "$" or "^".  In the case of the "$" 
  322. character, LKAHEAD is called to determine if the "$" is present 
  323. twice successively, which is interpreted as a single "$" to 
  324. move from input file to output file.  If there is no second "$" 
  325. character, the next character is considered to be the parameter 
  326. number (as in "$1", "$2", etc.).  The code at label SUBS 
  327. collects the parameter number from the input stream (which may 
  328. be more than one digit, if the conditional NPAR is greater than 
  329. ten) and uses it to index into the parameter address table.  
  330. The parameter, prefixed by its length, is then moved from the 
  331. parameter storage area into the output buffer.
  332.      After each line is moved into the output buffer, the 
  333. subroutine FLUSH writes the buffer to the disk.
  334.      When WRSUB has written the last record to the output file, 
  335. control returns to the mainline routine, which warm-boots CP/M 
  336. and begins execution of the new file.
  337.