; ; Program to examine the environment and give return codes for BATCH inquiry ; ; Gerald Lotto 01/24/85 ; ; Usage: ; ENVRPT [] ; is an environment variable with value ; (optional) ; ; Valid return codes are: ; ; 0 - is found to equal ; 1 - is found to not equal ; 3 - is not found ; 4 - Illegal arguments were given, i.e. ENVRPT (cr) ; ; Revised: ; DATE INIT REASON ; ; Title ENVRPT CSEG SEGMENT PARA 'CODE' NULL EQU 00H SPACE EQU 20H CR EQU 0DH LF EQU 0AH ENVSIZE EQU 800H ; This is maximum size ; for my (modified) DOS ORG 2CH ENVSEG LABEL WORD ; Segment of environment ORG 80H DOSCMD LABEL BYTE ; Command line from DOS ORG 100H ENVRPT PROC FAR ASSUME CS:CSEG,DS:NOTHING,ES:NOTHING JMP START VALUE DB 80H DUP(0) ; Internal work area for ; storing translation string START: MOV AX,CS MOV DS,AX ; Ensure that DS and ES are MOV ES,AX ; set up MOV SI,OFFSET DOSCMD + 1 ; Start of argument string MOV CX,0000 MOV CL,BYTE PTR DOSCMD ; Length of argument string CALL GETWORD ; Get first argument CMP BYTE PTR [DI],NULL ; Is it NULL? JZ ERROR ; Yes, exit with code 4 CALL UPCASE ; Upper case it in place CALL XLATE ; Get translation string ; from environment in VALUE CMP BYTE PTR CS:VALUE,NULL ; Is the translation NULL? JZ NOTFOUND ; Yes, exit with code 3 MOV DI,OFFSET DS:VALUE ; Locate translation string MOV AX,0200H ; DOS Print character PRINT: MOV DL,BYTE PTR [DI] ; Get next char to print INT 21H ; Print it, INC DI ; and move up one CMP BYTE PTR [DI],NULL ; Is it the end? JNZ PRINT ; No, go another round MOV DL,CR ; Yes, follow by a carriage INT 21H ; return MOV DL,LF ; and a line feed INT 21H ADD SI,CX ; Position at the end of arg2 MOV BYTE PTR [SI],NULL ; and put a NULL there INC CX ; Increase to count all chars STD ; Reverse direction REPZ CMPS BYTE PTR DS:[SI],ES:[DI] ; and compare the strings CLD ; Go forward again JNZ FALSEEXIT ; If the comparison failed, ; exit with code 1 TRUEEXIT: MOV AX,4C00H ; Otherwise exit with code 0 INT 21H FALSEEXIT: MOV AX,4C01H ; This is the exit for a INT 21H ; non-match NOTFOUND: MOV AX,4C03H ; This is the exit for not INT 21H ; finding the requested ; ENVIRONMENT variable ERROR: MOV AX,4C04H ; This is the exit for bad INT 21H ; arguments ENVRPT ENDP ; Procedure GETWORD ; ; Call with: ; SI - Pointer in an ASCII string (Possible leading spaces) ; CX - Length to end of string ; ; Returns with: ; DI - Pointer to first word now terminated with a null ; SI, CX - Now point to next word and have remaining string length ; ; Does not look back for data before SI ; AX, BX, CX zapped, all other regs preserved ; ; Thanks to Dan Tappan, this code was modified from OLDER.ASM ; GETWORD PROC CLD PUSH SI PUSH CX MOV BX,CX MOV AL,SPACE MOV BYTE PTR [BX+SI],AL ; Put a space at the end MOV DI,SI CMP CX,+00 ; Check length JLE GOTWORD ; Return if NULL REPZ SCASB ; Skip leading spaces CMP CX,+00 ; See if you ran out of string JG READWORD ; If not, go to it MOV DI,SI ; If so, back to the beginning JMP GOTWORD ; and return READWORD: DEC DI ; Back up to the first char NOT CX ; Count back from -1 PUSH DI ; Save the start REPNZ SCASB ; Find the next space DEC DI ; Back up to the end MOV SI,DI ; Save it, POP DI ; and restore the pointer ; to the start GOTWORD: MOV BYTE PTR [SI],00 ; Terminate word with a null INC SI ; Advance to next word POP CX ; Original length POP BX ; The original location SUB BX,SI ; - the current location ADD CX,BX ; + the overall length RET ; = the remaining length GETWORD ENDP ; Procedure UPCASE ; ; Call with: ; DI - Pointer in an ASCII string terminated by a space (or less) ; ; Returns with: ; String UPPERCASED in place ; ; AX zapped, all other regs preserved ; UPCASE PROC CLD PUSH SI MOV SI,DI NEXTBYTE: LODSB AND AL,07FH ; Strip hi bit CMP AL,SPACE ; Is this the end? JLE UPCASED ; Yes, we are done. CMP AL,'a' ; Skip if it is less JL NEXTBYTE ; then 'a' CMP AL,'z' ; or if it is greater JG NEXTBYTE ; then 'z' AND AL,0DFH ; Else, UPPERCASE it MOV BYTE PTR [SI-01],AL ; Replace it JMP NEXTBYTE ; and grab the next one UPCASED: POP SI RET UPCASE ENDP ; Procedure XLATE ; ; Call with: ; DI - Pointer to an UPPERCASED string, null terminated ; ; Returns with: ; Translation of string in an internal data area, terminated ; with a 00, '$' ; ; AX zapped, all other regs preserved ; XLATE PROC CLD PUSH DS PUSH SI PUSH DI PUSH CX MOV SI,DI MOV AX,WORD PTR ENVSEG ; From the PSP, DOS gives MOV ES,AX ; the segment and offset of MOV DI,00 ; a copy of the environment MOV CX,WORD PTR ENVSIZE ; Max size, see params up top LODS BYTE PTR DS:[SI] ; Get the first char of arg TESTMATCH: PUSH AX ; and save it CMP AL,BYTE PTR ES:[DI] ; Check against ENV string #1 JZ GOTMATCH ; Possible match FAILED: MOV AX,0000 ; No match, search ENVIRONMENT REPNZ SCAS BYTE PTR ES:[DI] ; for next NULL POP AX ; Restore first char of arg CMP CX,00 ; Have we run out of space? JZ TERMINATE ; Yes, stop looking CMP BYTE PTR ES:[DI],NULL ; Are we at environment end? JNZ TESTMATCH ; No, test next entry JMP TERMINATE ; Yes, stop looking GOTMATCH: INC DI ; Step to next char in ENV REPZ CMPS BYTE PTR DS:[SI],ES:[DI] ; Compare strings DEC SI ; Back up to last character DEC DI ; in arg and ENV strings CMP BYTE PTR DS:[SI],NULL ; Are we at the end of arg? JNZ FAILED ; No, try next ENV string ; ; Insert code to handle wildcards here ; CMP BYTE PTR ES:[DI],'=' ; End of the ENV string? JNZ FAILED ; No, try next ENV string POP AX ; We have a match, trash AX INC DI PUSH DI ; Save start of translation MOV CX,0FFFFH ; Count backwards from -1 MOV AX,0000 REPNZ SCAS BYTE PTR ES:[DI] ; up to the next NULL NOT CX DEC CX ; Adjust count to + number POP SI ; Start of translation string MOV AX,ES ; Swap seg regs around for MOV DS,AX ; MOVS with DS = ENVSEG MOV AX,CS ; and ES = CS MOV ES,AX MOV DI,OFFSET CS:VALUE ; Point to the internal data REPZ MOVS BYTE PTR ES:[DI],DS:[SI] ; area and copy translation TERMINATE: MOV BYTE PTR ES:[DI],NULL ; Terminate with a NULL POP CX POP DI POP SI POP DS RET XLATE ENDP CSEG ENDS END ENVRPT