DOCUMENTATION FOR //IF.COM AND //SKIP.COM 82/06/10 Reformatted 85/10/20 Modifications 86/10/16 by C.B. Falconer (versions 2.1) The $$$.SUB file is expected to be found on drive A, user 0. JOB 1.5 and CCP+ 2.1 place/use it from there. For use on other than user area 0 you should be running CCP+ and do any cancellation of jobs with: era a0:$$$$$$.sub (CCP+ will parse this) (the double $'s represent $ to JOB/SUBMIT) Modifications 85/10/20 by C.B. Falconer (versions set to 2.0 from 1.0) //IF will function with systems that do not upshift command lines (e.g. CCPLUS with the UP$ command executed). //SKIP considers the ";" as an eol marker, so that commands can have trailing comment areas, e.g: "//skip 3; this is a comment" ------------------------------------------------------------------ //IF is a program to test various conditions from within a CP/M SUBMIT file and then either skip the next line in the submit file, or execute it normally, depending on the results of the tests. //IF can test for the presence or absence of one or more files, test a file for emptiness, compare two filespecs for equality, test Submit parameters for expected syntax, test the default drive, and more. When combined with the //SKIP program the power of //IF can be expanded to conditionally execute entire blocks of lines within the Submit file. IF...THEN...ELSE structures can be easily implemented within Submit files depending upon the parameters supplied, or the status of files on the disks when the jobstream is submitted. THE //IF COMMAND: Syntax: (Square brackets indicate optional parameters) //IF [parm1 [parm2]] [:options] where: is a standard CP/M file reference either entered literally, or supplied by Submit parameter substitution. The syntax is the normal D:FILENAME.EXT form. If either Filename or Extension are not entered they default to blanks. If the Drive is not entered, the current drive is assumed. If the name or extension contain question mark (?) or asterisk (*) characters, the file reference is said to be ambiguous. Otherwise it is unambiguous. is an optional second filespec used by some of the options described below. The defaults are the same as for parm1. is a string of single-character options with no intervening or trailing blanks. The option list must be separated from the preceding parameters by at least one blank, and must always begin with a colon (:) to identify it as the option list, and prevent it from being confused with parm1 or parm2 if one or both are omitted. The entire option list may also be omitted, in which case the identifying colon should not be entered. The ordering of the options within the list is not significant. The option list is really a set of tests to be performed upon the first parameter, parm1. (Parm1 is assumed to be the name of a file, but may in fact be any text at all, as long as it conforms to the syntax for a valid file reference.) If the tests are passed, the //IF command does nothing at all, and the next line in the submit file is processed normally. If however, any of the specified option tests fails, the //IF command modifies the submit control file (A:$$$.SUB) to skip over the next command in the file. Command processing then continues with the line after the one which was skipped, if any. If two mutually exclusive options are included in the option list, the following line will never be executed. Explanation of option characters: A Ambiguous: True if parm1 is an ambiguous file reference. False otherwise. The A option does not test to see if a file or files exists. For example the parameter *.ASM will pass the A test regardless of whether there are any .ASM files on the disk. U Unambiguous: True if parm1 is an unambiguous file reference. False otherwise. P Present: True if at least one file exists which matches the specification given in parm1. Parm1 may be ambiguous (unless of course the U option appears in the list) M Missing: True if there exists no file which matches the specifi cation given in parm1. Parm1 may be ambiguous. C Contents: True if the file referenced by parm1 exists and con tains at least one record (sector). If Parm1 is ambiguous the test fails. E Empty: True if the file referenced by parm1 exists in the direc tory but contains no data. If Parm1 is ambiguous the test fails. D Drive substitution: This option is not really a test, and cannot fail as such. It causes whatever drive has been entered in parm2 to be moved into parm1 before any testing is done on parm1. For example if parm1 were A:TEST.FIL and parm2 were B: all the re maining options would treat parm1 as if it had been B:TEST.FIL. If parm2 is blank, or does not contain a drive spec, parm1 is modified to remove any explicit drive spec. Parm1 then refers to the default drive. Note again that the order of the options makes no difference to the program. The D option is always performed before any other tests, even if it occurs at the end of the option list. The following three options are matching tests. They match portions of parm1 against the corresponding portions of parm2. 0 Matches the drivespec portions of parm1 and parm2. Tests true if the same drive is referred to by both. Note that if one of the drives is explicit and the other is defaulted, the test will pass or not depending upon whether the explicit drive is in fact the current default drive. If both parm1 and parm2 are missing, this test will pass, since both parameters refer by default to the current drive. 1 Matches the filename portion of parm1 and parm2. Tests true if the filenames match or are both missing. If either or both of the filenames are ambiguous, the ambiguous characters are considered to match the corresponding portion of the other name. For example if parm2 is * this test will always pass. Note that only the first 8 characters of the names are tested. 2 Matches the extension (filetype) portion of parm1 and parm2. Same as option 1 except that only the three characters after the period of each parameter are tested. No option list: If the option list is omitted entirely, the //IF command merely tests to see if anything was entered following the word //IF on the command line. If the remainder of the line (after Submit parameter substitution) is blank, the test fails. If any non-blank character appears on the line, the test passes. For example the line //IF $1 tests to see if parameter number $1 was defined on the Submit command line. If it was not, the line after substitution becomes just "//IF ", and the test fails. Error Messages: The following error messages indicate fatal errors in processing. The remainder of the submit file is not processed, and control returns to the console. Option "X" not valid....CANCELED A character appears in the option list which is not one of those defined above. Error accessing .SUB file....CANCELED The file A:$$$.SUB could not be found, or could not be closed, by the //IF program. This error can also occur if //IF is run from the console rather than within a submit file, or if //IF is the last line in a submit file; i.e. there is no next line to skip when a test fails. THE //SKIP COMMAND: The skip command is used to unconditionally skip over any number of lines within a Submit file. Normally it is used as the line immediately following an //IF command. In this way the testing capabilities of //IF can be extended to apply to more than one line of the file. //SKIP can also be used to implement IF...THEN...ELSE structures within Submit files. Syntax: (Square brackets indicate optional parameter.) //SKIP [number] where: is a decimal integer in the range 0-127 which indicates the number of lines in the submit file to be skipped. If omitted, the number 1 is assumed. The number must be separated from the //SKIP command by at least one space, and may not have any trailing spaces. //Skip operates by evaluating the argument and, if it is greater than zero, modifying the file A:$$$.SUB to cause the system to ignore the indicated number of lines. If the argument is 0, //SKIP does nothing at all. Error Messages: The following error messages indicate fatal errors in processing. The remainder of the submit file is not processed, and control returns to the console. Error accessing .SUB file....CANCELED The file A:$$$.SUB could not be found, or could not be closed, by the //SKIP program. This error can also occur if //SKIP is typed directly from the console rather than within a submit file. //SKIP argument not numeric....CANCELLED The parameter contains characters other than 0 to 9. //SKIP argument exceeds file size....CANCELLED An attempt was made to skip over more lines than there are remaining in the A:$$$.SUB file. USAGE EXAMPLES: Example 1: The following Submit file will assemble and load a source file. The file name is indicated as the first parameter. If the second parameter is EDIT, the file will first be edited. Some error checking is done. Note the use of lines beginning with a semicolon to supply messages to the operator. CP/M treats such lines as comments. The line numbers are for reference purposes, and are not part of the file. [1] //IF $1 :U2 [2] //SKIP 2 [3] ;PARAMETER 1 NOT VALID [4] ERA A:$$$$$$.SUB (use A0:$$$$$$.SUB with CCP+) [5] //IF EDIT $2 :U012 [6] ED $1.ASM [7] //IF $1.ASM :C [8] ASM $1 [9] //IF $1.HEX :C [10] LOAD $1 Notes: Line 1: Tests that parameter 1 is unambiguous and has a filetype of all blanks. Parameter 2 is missing, and is treated as blanks for the comparison. Line 2: If the test is passed, lines 3 and 4 are skipped. Line 3: The operator is informed of an error condition Line 4: The submit file is aborted by erasing A:$$$.SUB. Since $ is a special character to SUBMIT, each one must be represented by two in the source file. Line 5: The second parameter is tested to see if it is equal to the word "EDIT". The 0 and 2 options are extra insurance that the drive and filetype are blank. Line 6: If the test is passed the file is edited with a filetype of Line 7: The file is tested to see if it contains data. This helps insure that the editor terminated normally. Line 8: If the test is passed, the file is assembled. Line 9: The .HEX file is tested for contents to help insure that the assembler terminated normally. Line 10: If the .HEX file is present, the file is LOADed to produce a Example 2: The following is a skeleton example of how //IF and //SKIP can be used to form an IF....THEN....ELSE structure. <--------------------------------------> <--------- prior submit lines ---------> <-------------------------------------->//IF : //SKIP m <--------------------------------------> <---- m-1 lines to be executed---------> <---- if test is FALSE ----------------> <--------------------------------------> //SKIP n <--------------------------------------> <---- n lines to be executed ----------> <---- if test is TRUE------------------> <--------------------------------------> <---- remainder of submit file to -----> <---- be executed unconditionally -----> <--------------------------------------> Notes: The //IF condition tests whatever combination of options is desired. If the conditions are not met, the //SKIP immediately below is not ex ecuted. Instead, control passes through to the lines to be executed if the test is false, in effect the ELSE section. The last line of the ELSE section is another //SKIP which skips past the THEN section (those lines to be executed if the test is true) and executes the remainder of the file. If the //IF test is true, the first //SKIP statement skips over the ELSE section. The value m is chosen so that the last line skipped over is the second //SKIP statement. It takes some time to get used to seeing a structure where the ELSE comes between the IF and the THEN, but the struc ture is no less valid for being slightly unorthodox. PROGRAM NOTES: The program is written for the 8080 processor and should execute properly on 8080, 8085, and Z-80 processors. It has been tested under CP/M80 version 2.2, but should operate properly with 2.1, 2.0 and 1.4 also. There is a minor difference in the operation of the C option depending on the version used. If the operating system identifies itself as version 2.0 or above (as determined by a call to Function 12) the C option will use Function 35, "Compute File Size" in order to determine if the file contains any records. If the version test shows that the operating system is pre- version-2, the C option test merely tries to read the first record of the file. The only time this would make a difference is on a Random file which happens to have no records in the first extent. The sequential read would fail, but the Compute File Size function would properly report the exist ence of records in the file. While sequential files will test correctly on any version, files which have been created randomly should not be tested for contents on CP/M 1.4 or earlier. I would appreciate being informed of any bugs found in either program, or suggestions for expansion or improvement. Gary P. Novosielski, 21 W. Pierrepont Avenue, Rutherford, NJ 07070