303 lines
8.4 KiB
NASM
303 lines
8.4 KiB
NASM
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;
|
||
|