ZCPR33 PROGRAMMING NOTES ======================== Note Number: 003 Author: Jay Sage Date: June 6, 1987 The ZCPR33 File Name Parser There are two special aspects to the file name parser in ZCPR33. First of all, the command processor provides three standard entry points, similar to those provided by the BIOS, so that external programs can make use of the parsing code inside the command processor. Secondly, the result of the parsing is designed to provide much more information, such as whether or not a directory was specified explicitly and, if so, whether or not the directory was a valid one. Let's take up these two features one at a time. Note that routines are (or will be) provided in Z33LIB to perform these functions easily. The Parser Entry Points ----------------------- The beginning of the command processor has the following structure: offset code ------ ---- 0H JP actual code 3H JR actual code 5H DB version byte 6H DS ten configuration information bytes 10H LD HL,token pointer 13H JP PARSETAIL 16H JP SCANNER 19H command dispatch table The routine whose entry point is at offset 16H parses a single file specification string pointed to by HL into a file control block pointed to by DE. Two important precautions must be observed. First, the string at HL must have the form of a command token, that is, it must have a termination character. The termination characters that are recognized are a semicolon, and equal sign, a space, or any control character. Note that a comma is not included in this list, so that compound tokens such as "FN1.FT,FN2.FT" will be treated as a single token, and the second file name and type will be skipped over. Individual fields in a file specification are terminated by any of the following characters: space, equal sign, underscore, semicolon, greater than or less than sign, comma, or null. A second colon or period will also terminate the field. However, once all the required fields have been identified, the code skips over characters until it finds the token delimiter from the smaller set of characters described earlier. Thus this routine does not function exactly like the routine ZFNAME in Z3LIB. Contrary to the statement in "ZCPR3, The Libraries," ZFNAME does not behave identically to the ZCPR30 parser either. The second precaution is the more unusual one. The file control block pointed to by DE must have been initialized more extensively than is usual. Generally, the fields occupied by the file name and file type do not have to be initialized. For this routine, however, the 11 filename characters must all be set to spaces before the routine is called. The routine whose entry point is at offset 13H parses a pair of file specifications pointed to by HL into the two system default file control blocks (at 5CH and 6CH). The file control blocks are initialized by the routine, and no user-provided initialization of any sort is required. After this routine has run, the address of the beginning of the second of the two file specifications is set into the word at offset 11H so that it will be loaded into the HL register automatically when the entry point at offset 10H is used. The entry point at offset 10H is provided in case an external program wants to continue parsing the line that the command processor parsed. This would be useful, for example, for an RCP version of SAVE or JUMP. Note that these routines can be used only when the command processor has not been overwritten by an application program. When this is the case, these routines offer two advantages. First, they save code. Secondly, they automatically parse the file specifications in the exact same way that the command processor does (naturally!). This means that the same configuration options will apply, such as recognizing DU and/or DIR forms and in the correct order, checking passwords, omitting password checking when the wheel byte is set, allowing the DU form only when the ENV DUOK flag is set, etc. Structure of File Control Blocks Built -------------------------------------- The file control blocks constructed by the ZCPR33 parser differ in several critical ways from those produced by the ZCPR30 command processor. In all cases, the purpose is to provide more information. In its internal operation, the command processor constructs three file control blocks. The external file control block contains a parsed version of the command expression (the first token on the command line, token zero). The first two tokens in the command tail are parsed into the two system default file control blocks. Let's treat the two system default file control blocks first. These two FCBs are initialized so that all fields contain zeros except as noted here. the drive byte: This byte is set to zero if no drive is specified explicitly, that is, if there is no 'DU:', 'DIR:', or ':' (alone) prefix. If a directory is specified, then a drive number in the range 1..16 designated by that directory is stored in the drive byte. A colon alone designates the currently logged directory. If the designated directory is invalid for any reason, the currently logged drive is used (an error flag, described below, is also set). A designated directory is invalid if (1) it is a 'DU:' expression with a drive or user number that is outside the allowed range, (2) it is a 'DIR:' expression with a name that is not defined in the named directory register (NDR), or (3) it is a 'DIR:' form designating a password- protected directory and the user did not enter the correct password when asked for it. the file name and type fields: These fields are filled in with the first 8 characters of the string before a period and the first three characters of the string after a period, respectively. If fewer than 8 and 3 characters, respectively, are present, the name or type is padded out with space characters. If no name or no type is included in the file specification, then the corresponding field is filled entirely with blanks. If more than 8 or 3 characters, respectively, are present, the excess characters are ignored. user number byte: The user number byte at offset 13 decimal (0DH) contains the user number for the file specification. If no user number is given explicitly (using either the forms 'DU:' or 'U:' or by a named directory specification), then this byte contains the currently logged in user number. There is no way to tell whether or not a user number was given explicitly (thus the expression 'A:' cannot be distinguished from the expression 'A3:' where the current user area is 3). This is a defect in the basic design of ZCPR3 file control blocks and cannot be changed at this point. To overcome this limitation, a program would have to scan the original file specification itself using its own code. record count byte: The record count byte at offset 0FH in the FCB normally contains a zero byte. If the directory specified was not valid (for the reasons listed above), a non-zero value is placed in the record count byte. Programs can use this information to distinguish between an FCB specifying the current directory because that is the directory actually specified and an FCB that does so because the specified directory was invalid. In a future release of the ZCPR3 command processor, it might be possible to use individual bits in the record count byte to indicate complete information about the parse, including whether or not a user number was specified explicitly. The External Command File Control Block --------------------------------------- The requested command is parsed into the external command file control block in exactly the way described above. However, since this FCB is used by the command processor before a user program sees it, there are some changes. First of all, the drive byte is always set to zero during the search for a transient program, and it was already zero for any RCP- and CPR- resident commands. Consequently, it is not normally possible to get any information about the kind of command from this byte. However, the drive and user number where the command was actually found during loading is put into the FCB. The user value is in its normal place at offset 13 (0DH). The drive value, in the range 1..16, is kept in the next byte (this way the two values can be loaded into BC as a word for use by SYSLIB routines like LOGUD). If the drive value is 0, then no search was performed for a transient command; in other words, the command was a resident command. There is one exception to the above description. That concerns the FCP commands, which I carefully did not mention. The command processor scans the FCP for ALL commands, whether or not they have a directory prefix. Since commands processed by the FCP have not been subjected to the command processor loader, the external command FCB is still intact from the original parse. Consequently, the drive byte can be used to determine whether or not a directory prefix was included with the command. This technique is used to advantage in Z33FCP. If the invocation of IF, OR, or AND had a directory specification (including a lone colon), then the FCP module immediately loads the transient flow processor IF.COM, without first checking to see if the requested option is supported in the resident code. Thus a leading colon can force the more powerful transient flow processor to be run, and the code required to detect this request in the FCP module is minimal.