2025-04-27 07:49:33 -04:00

303 lines
8.4 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

page 60,132;
title EDLPARSE for EDLIN
;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1991
; * All Rights Reserved.
; */
;******************* START OF SPECIFICATIONS *****************************
;
; MODULE NAME: EDLPARSE.SAL
;
; DESCRIPTIVE NAME: PARSES THE EXTERNAL COMMAND LINE FOR EDLIN
;
; FUNCTION: THIS ROUTINE PROVIDES PARSING CAPABILITIES FOR THE
; EXTERNAL COMMAND LINE OF EDLIN. IT PARSES FOR THE PRESENCE
; OF A REQUIRED FILESPEC AND AN OPTIONAL SWITCH (/B).
;
; ENTRY POINT: PARSER_COMMAND
;
; INPUT: DOS COMMAND LINE
;
; EXIT NORMAL: AX = 0FFH - VALID SWITCH AND FILESPEC SPECIFIED
;
; EXIT ERROR: AX NOT= 0FFH - INVALID SWITCH OR NO FILESPEC SPECIFIED
;
; INTERNAL REFERENCES
;
; ROUTINE: PARSER_COMMAND - THIS ROUTINE PARSES FOR THE PRESENCE
; OF THE /B SWITCH AND A FILESPEC. THE
; FILEPSEC IS REQUIRED, WHILE THE SWITCH
; IS OPTIONAL.
;
; EXTERNAL REFERENCES:
;
; ROUTINE: PARSE.ASM - THIS IS THE PARSER CODE.
;
; NOTES: THIS MODULE IS TO BE PREPPED BY SALUT WITH THE "PR" OPTIONS.
; LINK EDLIN+EDLCMD1+EDLCMD2+EDLMES+EDLPARSE
;
; REVISION HISTORY:
;
; AN000 VERSION 4.00 - IMPLEMENTS THE SYSTEM PARSER (SYSPARSE)
;
; COPYRIGHT: "THE IBM PERSONAL COMPUTER EDLIN UTILITY"
; "VERSION 4.00 (C) COPYRIGHT 1988"
; "LICENSED MATERIAL - PROPERTY OF Microsoft"
;
;
;******************** END OF SPECIFICATIONS ******************************
;======================= equates for edlparse ============================
parse_ok equ 0 ;an000;good parse return
parse_command equ 081h ;an000;offset of command line
nul equ 0 ;an000;nul
fs_flag equ 05h ;an000;filespec found
sw_flag equ 03h ;an000;switch found
true equ 0ffffh ;an000;true
false equ 00h ;an000;false
too_many equ 01h ;an000;too many parms
;======================= end equates =====================================
CODE SEGMENT PUBLIC BYTE
CODE ENDS
CONST SEGMENT PUBLIC BYTE
CONST ENDS
cstack segment stack
cstack ends
DATA SEGMENT PUBLIC BYTE
extrn path_name:byte
extrn org_ds:word ;an000; dms;
public parse_switch_b ;an000;parse switch result
public parse_switch_? ; parse switch result
public filespec ;an000;actual filespec
;======================= input parameters control blocks =================
; these control blocks are used by sysparse and must be pointed to by
; es:di on invocation.
public parms ;an000;share parms
parms label byte ;an000;parms control block
dw dg:parmsx ;an000;point to parms structure
db 00h ;an000;no additional delims.
parmsx label byte ;an000;parameter types
db 1,1 ;an000;must have filespec
dw dg:fs_pos ;an000;filespec control block
db 2 ;an000;max. number of switches
dw dg:sw_b ;an000;/b switch control block
dw dg:sw_? ;an000;/? switch control block
db 00h ;an000;no keywords
;======================= filespec positional tables ======================
fs_pos label byte ;an000;filespec positional
dw 0200h ;an000;filespec/not optional
dw 0001h ;an000;cap
dw dg:filespec_res ;an000;filespec result table
dw dg:noval ;an000;value list/none
db 0 ;an000;no keyword/switch syns.
filespec_res label byte ;an000;filespec result table
parse_fs_res db ? ;an000;must be filespec (05)
parse_fs_tag db ? ;an000;item tag
parse_fs_syn dw ? ;an000;synonym pointer
parse_fs_off dw ? ;an000;offset to filespec
parse_fs_seg dw ? ;an000;segment of filespec
;======================= switch tables /b ================================
sw_b label byte ;an000;/b switch
dw 0000h ;an000;no match flags
dw 0000h ;an000;no cap
dw dg:switch_res ;an000;result buffer
dw dg:noval ;an000;value list/none
db 1 ;an000;1 switch
sw_b_switch db "/B",0 ;an000;/B means ignore CTL-Z
sw_? label byte ;an000;/b switch
dw 0000h ;an000;no match flags
dw 0000h ;an000;no cap
dw dg:switch_res ;an000;result buffer
dw dg:noval ;an000;value list/none
db 1 ;an000;1 switch
sw_?_switch db "/?",0 ;an000;/B means ignore CTL-Z
PUBLIC sw_?_switch
switch_res label byte ;an000;switch result table
parse_sw_res db ? ;an000;must be string (03)
parse_sw_tag db ? ;an000;item tag
parse_sw_syn dw ? ;an000;synonym pointer
parse_sw_ptr dd ? ;an000;pointer to result
noval label byte ;an000;value table
db 0 ;an000;no values
;======================= end input parameter control blocks ==============
filespec db 128 dup (0) ;an000;holds filespec
parse_switch_b db false ;an000;hold boolean result
; of /b parse
parse_switch_? db false ; true if /? found
parse_sw_b db "/B" ;an000;comparison switch
DATA ENDS
DG GROUP CODE,CONST,cstack,DATA
code segment public byte ;an000;code segment
assume cs:dg,ds:dg,es:dg,ss:CStack ;an000;
public parser_command ;an000;share this routine
;======================= begin main routine ==============================
.xlist
include version.inc ; parse.asm include psdata.inc which needs defs from here
include parse.asm ;an000;parser
.list
parser_command proc near ;an000;parse routine
push es ;an000;save registers
push ds ;an000;
push di ;an000;
push si ;an000;
mov dg:parse_switch_b,false ;an000;init. to false
xor cx,cx ;an000;set cx to 0
xor dx,dx ;an000;set dx to 0
mov di,offset dg:parms ;an000;point to parms
mov si,parse_command ;an000;point to ds:81h
mov ds,dg:org_ds ;an000;get ds at entry
assume ds:nothing ;an000;
parse_continue: ;an000;loop return point
call sysparse ;an000;invoke parser
cmp ax,parse_ok ;an000;is it a good parse
jne parse_end ;an000;continue on good parse
push si
mov si,dx
cmp byte ptr es:[si],fs_flag ;an000;do we have a filespec
; $if e ;an000;yes we do
JNE $$IF1
call build_fs ;an000;save filespec
; $else ;an000;
JMP SHORT $$EN1
$$IF1:
; A switch was found.
; See which one it was.
call val_sw ;an000;see which switch
; $endif ;an000;
$$EN1:
pop si
jmp parse_continue ;an000;continue parsing
parse_end: ;an000;end parse routine
pop si ;an000;restore registers
pop di ;an000; for return to caller
pop ds ;an000;
assume ds:dg ;an000;
pop es ;an000;
ret ;an000;return to caller
parser_command endp ;an000;end parser_command
;======================= subroutine area =================================
;=========================================================================
; build_fs: This routine saves the filespec for use by the calling program.
;=========================================================================
build_fs proc near ;an000;save filespec
push ax ;an000;save affected regs.
push di ;an000;
push si ;an000;
push ds ;an000;
push es ;an000;
mov di,offset dg:filespec ;an000;point to filespec buffer
lds si,dword ptr es:parse_fs_off ;an000;get offset
build_cont: ;an000;continue routine
lodsb ;an000;mov ds:si to al
cmp al,nul ;an000;is it end of filespec
; $if nz ;an000;if not
JZ $$IF7
stosb ;an000;move byte to filespec
jmp build_cont ;an000;continue buffer fill
; $endif ;an000;
$$IF7:
stosb ;an000;save nul
pop es ;an000;restore regs
pop ds ;an000;
pop si ;an000;
pop di ;an000;
pop ax ;an000;
ret ;an000;return to caller
build_fs endp ;an000;end proc
;=========================================================================
; val_sw : determines which switch we have.
;=========================================================================
val_sw proc near ;an000;switch determination
; Check for /B
cmp es:[parse_sw_syn], offset es:sw_b_switch
jne ValSwitchBDone
cmp es:[parse_switch_b], true ; see if already given
jne ValSwitchBOkay ; jump if not
mov ax, too_many ; set error level
jmp parse_end ; and exit parser
ValSwitchBOkay:
mov es:[parse_switch_b], true ; set the flag on
jmp short ValSwitchExit ; and done
ValSwitchBDone:
; Check for /?
cmp es:[parse_sw_syn], offset es:sw_?_switch
jne ValSwitch?Done
mov es:[parse_switch_?], true ; set the flag on
jmp short ValSwitchExit ; and done
ValSwitch?Done:
ValSwitchExit:
ret ;an000;return to caller
val_sw endp ;an000;end proc
code ends ;an000;end segment
end ;an000;