sseg segment stack
db 128 dup (0)
sseg ends
dseg segment para public 'global'
extrn parambuf:byte
extrn paramnr:word
configpath db 'config.txt',0 ; file name to be open
dseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,ss:sseg
public rdconfig,chksynx
extrn panic:near
rdconfig proc near
push ds ; save caller's segment
push es
push bp ; make stack frame
mov bp,sp
mov ax,3d00h ; read only open file
mov dx,offset configpath
int 21h
jnc suc
; don't clear carry if error detected
mov sp,bp
pop bp ; restore stack frame
pop es
pop ds
ret ; leave error code in ax
suc:
mov bx,ax ;we will read the config file
xor ax,ax
mov ah,3fh
mov dx,offset parambuf
mov cx,1024
int 21h
jnc suc1
mov sp,bp
pop bp
pop es
pop ds
ret
suc1:
mov [paramnr],ax ; indicate how many byte we read from config file
clc ; guaratee no error
; the file handler is already set properly
mov ah,3eh
int 21h ; close config file
; we don't care if this operating is successful
mov sp,bp
pop bp
pop es
pop ds
ret
rdconfig endp
chksynx proc near
push ds
push es
push bp
mov bp,sp
sub sp,10
; stack arranges like this:
; [bp-2]: the first '/' relative position
; [bp-4]: the first '$' relative position
; [bp-6]: the rest count left after each '/' matched
; [bp-8]: the rest count left after each '$' matched
; [bp-10]: the search time counter
; try to find the '#', if '#' not present in our parameter
; buf, we will refuse to continue operating and panic, also
; we will check the '/','$', we guarantee the each '$' is
; behind the each '/', if not, we can't continue operating
; and panic syntax error, '/','$' not in group
cmp word ptr [paramnr],0 ; configuration file can't be NULL
jne cnext1
mov ax,105
push ax
call panic
cnext1:
cld ; clear direction
mov di,offset parambuf
mov cx,[paramnr]
mov al,35 ; '#'
repnz scasb ; find first '#' char
jz found
mov ax,100 ; get appropriate error code
push ax
call panic
found:
; '#' presents, it's time to check the relation
; between '/' & '$'
; we will initialize the rest count and relative
; position for '/' & '$', and create a loop to
; check if each '$' is behind each '/'
mov di,offset parambuf
mov [bp-2],di ; '/' position initialize
mov [bp-4],di ; '$' position initialize
mov cx,[paramnr]
mov [bp-6],cx ; '/' count initialize
mov [bp-8],cx ; '$' count initialize
mov word ptr [bp-10],0 ; it is the first time
cw1loop: ; check loop start here
cld
mov di,[bp-4]
mov cx,[bp-8]
mov al,36 ; '$'
repnz scasb ; find relative first '$' char
jz cnext2
cmp word ptr [bp-10],0 ; is it the first time ?
jz bad1
; if we can't find '$' again, we will
; guarantee no '/' after that
cld
mov di,[bp-2]
mov cx,[bp-6]
mov al,47 ; '/'
repnz scasb
jnz match ; check if in group
mov ax,108
push ax
call panic
match:
jmp cnext6
bad1:
mov ax,106
push ax
call panic
cnext2:
mov [bp-4],di ; set next start of '$'
mov [bp-8],cx ; parameter count left of '$'
cld
mov di,[bp-2]
mov cx,[bp-6]
mov al,47 ; at least one '/' present
repnz scasb
jz cnext34
mov ax,107
push ax
call panic
cnext34:
; we guarantee at least one '$', one '/' present
; also '$' should behind '/'
cld
mov di,[bp-2]
mov cx,[bp-6]
mov al,47 ; '/'
repnz scasb ; find the most close to '$' of '/' char
jz cnext3
; test if next '$' can be found, if so
; too bad
cld
mov di,[bp-4]
mov cx,[bp-8]
mov al,36 ; '$'
repnz scasb
jnz toobad
; it seems the end of config file
; it is not necessary to go on
jmp cnext6
toobad:
mov ax,108
push ax
call panic
cnext3:
; we will check each path if they are all in group
; first verify the previous '/' is most close to
; '$', if so, restore the search position of '/'
; to previous state
; be more careful, di is now one
; more than that position
dec di
mov si,[bp-4]
dec si
cmp di,si ; if exceed the position of '$'
jb cnext32
jmp cnext33
; not updata the current position of '/'
; in effect is to restore the position
; to the close previous
cnext32:
; remember to restore the di
inc di
mov [bp-2],di ; set next start of '/'
mov [bp-6],cx ; parameter count left of '/'
jmp cnext34 ; get more close to '$'
cnext33:
; if all the counts reach zero, it indicates
; that the whole syntax check complete without
; any error detected, we will move back. if not
; then cmp the relative position between '$' & '/'
; if '$' > '/', something is wrong with the config
; file, it is likely we can't continue again
cmp word ptr [bp-8],0
jne cnext4
; the '/' can't be found again
cld
mov di,[bp-2]
mov cx,[bp-6]
mov al,47 ; '/'
repnz scasb
jnz cnext35
mov ax,108
push ax
call panic
cnext35:
jmp cnext6
cnext4:
inc word ptr [bp-10]
jmp cw1loop ; verify next path
cnext5:
mov ax,108
push ax
call panic
cnext6:
mov sp,bp
pop bp
pop es
pop ds
ret
chksynx endp
cseg ends
end