     1                                  ;	SCCSID = @(#)parse.asm	1.2 85/07/23
     2                                  ;TITLE PARSE - Parsing system calls for MS-DOS
     3                                  ;NAME  PARSE
     4                                  ;
     5                                  ; System calls for parsing command lines
     6                                  ;
     7                                  ;   $PARSE_FILE_DESCRIPTOR
     8                                  ;
     9                                  ;   Modification history:
    10                                  ;
    11                                  ;       Created: ARR 30 March 1983
    12                                  ;               EE PathParse 10 Sept 1983
    13                                  ;
    14                                  
    15                                  [list -]
    15          ******************       warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi]
    14                              <4> [list -]
    14                              <3> [list -]
     3                              <2> 
     4                              <2> addsection DOSSTART, align=16 PUBLIC class=DOSSTART
     5                              <2> ; (no prior section) ; DOSSTART		ENDS
     6                              <2> 
     7                              <2> addsection DOSSTARTJUMP, align=1 PUBLIC class=START
     8                              <2> ; (no prior section) ; DOSSTARTJUMP		ENDS
     9                              <2> 
    10                              <2> addsection CONSTANTS, align=2 PUBLIC class=CONST
    11                              <2> ; (no prior section) ; CONSTANTS	ENDS
    12                              <2> 
    13                              <2> addsection DATA, align=2 PUBLIC class=DATA
    14                              <2> ; (no prior section) ; DATA		ENDS
    15                              <2> 
    16                              <2> addsection TABLE, align=2 PUBLIC class=TABLE
    17                              <2> ; (no prior section) ; TABLE		ENDS
    18                              <2> 
    19                              <2> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE
    20                              <2> ; (no prior section) ; DOSDATATABLE		ENDS
    21                              <2> 
    22                              <2> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE
    23                              <2> ; (no prior section) ; DOSDATACODE		ENDS
    24                              <2> 
    25                              <2> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA
    26                              <2> 
    27                              <2> addsection LAST, align=16 PUBLIC class=LAST
    28                              <2> ; (no prior section) ; LAST		ENDS
    29                              <2> 
    30                              <2> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST
     8                              <1> 
     9                              <1> %include "dcodeseg.nas"
     1                              <2> 
     2                              <2> %ifndef DCODESEGNAS
     3                              <2> %assign DCODESEGNAS 1
     4                              <2> 
     5                              <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE
     6                              <2> ; (no prior section) ; DOSCODETABLE		ENDS
     7                              <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE
     8                              <2> ; (no prior section) ; DOSCODECODE		ENDS
     9                              <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE
    10                              <2> section BIOCODE	align=2 PUBLIC class=DOSCODE
    11                              <2> 
    12                              <2> %ifnidni DOSENTRYGROUP, DOSCODEGROUP
    13                              <2>  group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE
    14                              <2> %endif
    15                              <2> 
    16                              <2> %endif
    10                              <1> 
    11                              <1> section LAST
    12                              <1> ; (no prior section) ; LAST		ENDS
    20                                  
    21                                  [list +]
    22                                  section DOSCODECODE
    23                                  [list -]
    23          ******************       warning: out: ... for DOS Version 4.00 ... [-w+user]
    23          ******************       warning: out: BPB.INC... [-w+user]
    23          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    23          ******************       warning: out: DEVSYM.INC... [-w+user]
    30                                  
    31                                  BOGUS equ FALSE
    32                                  ;.lall
    33                                  	I_Need  chSwitch,BYTE
    34                                  
    35                                   assume nocheck, ss:DOSGROUP
    36                                  
    37                                  BREAK <$Parse_File_Descriptor -- Parse an arbitrary string into an FCB>
    38                                  
    39                                  ; Inputs:
    40                                  ;       DS:SI Points to a command line
    41                                  ;       ES:DI Points to an empty FCB
    42                                  ;       Bit 0 of AL = 1 At most one leading separator scanned off
    43                                  ;                   = 0 Parse stops if separator encountered
    44                                  ;       Bit 1 of AL = 1 If drive field blank in command line - leave FCB
    45                                  ;                   = 0  "    "    "     "         "      "  - put 0 in FCB
    46                                  ;       Bit 2 of AL = 1 If filename field blank - leave FCB
    47                                  ;                   = 0  "       "      "       - put blanks in FCB
    48                                  ;       Bit 3 of AL = 1 If extension field blank - leave FCB
    49                                  ;                   = 0  "       "      "        - put blanks in FCB
    50                                  ; Function:
    51                                  ;       Parse command line into FCB
    52                                  ; Returns:
    53                                  ;       AL = 1 if '*' or '?' in filename or extension, 0 otherwise
    54                                  ;       DS:SI points to first character after filename
    55                                  
    56                                  	procedure   D_PARSE_FILE_DESCRIPTOR,NEAR
    56          ******************       warning: proc D_PARSE_FILE_DESCRIPTOR... [-w+user]
    57                                  ASSUME  DS:NOTHING,ES:NOTHING
    58                                  
    59 00000000 E8(0000)                	invoke  MAKEFCB
    60 00000003 56                      	PUSH    SI
    61 00000004 E8(0000)                	invoke  get_user_stack
    62 00000007 8F4408                  	POP     word [SI + user_SI]
    63 0000000A C3                      	return
    64                                  EndProc D_PARSE_FILE_DESCRIPTOR
    65                                  
    66                                  
    67                                  %IF BOGUS
    68                                  BREAK <$PathParse - Parse a string>
    69                                  
    70                                  ;------------------------------------------------------------------------------
    71                                  ;
    72                                  ; Parse is a string parser.  It copies the next token into a buffer, updates
    73                                  ; the string pointer, and builds a flag word which describes the token.
    74                                  ;
    75                                  ; ENTRY
    76                                  ;       DS:SI - Points to the beginning of the string to be parsed
    77                                  ;       ES:DI - Points to the buffer which will hold the new token
    78                                  ;
    79                                  ; EXIT
    80                                  ;       AX - Flag word
    81                                  ;       DS:SI - String pointer updated to point past the token just found
    82                                  ;       All other registers are unchanged.
    83                                  ;
    84                                  ; All of the isXXXX procedures called by the main routine test a character
    85                                  ; to see if it is of a particular type.  If it is, they store the character
    86                                  ; and return with the ZF set.
    87                                  ;
    88                                  ; CALLS
    89                                  ;       isswit issep ispchr ispsep isinval isdot ischrnull dirdot pasep
    90                                  ;
    91                                  ;
    92                                  ; INTERNAL REGISTER USAGE
    93                                  ;       AH - FF/00  to indicate whether a path token can terminated with a
    94                                  ;            slash or not.
    95                                  ;       AL - Used with lodsb/stosb to transfer and test chars from DS:SI
    96                                  ;       BX - Holds flag word
    97                                  ;       CX - Used with loop/rep and as a work var
    98                                  ;       DX - Used to test the length of names and extensions
    99                                  ;
   100                                  ; EFFECTS
   101                                  ;       The memory pointed to by DI has the next token copied into it.
   102                                  ;
   103                                  ; WARNINGS
   104                                  ;       It is the caller's responsibility to make sure DS:SI does not point
   105                                  ;       to a null string.  If it does, SI is incremented, a null byte is
   106                                  ;       stored at ES:DI, and the routine returns.
   107                                  ;
   108                                  ;------------------------------------------------------------------------------
   109                                  ParseClassMask          equ     1110000000000000b       ; Token class mask
   110                                  ParseSwitch             equ     1000000000000000b       ; Switch class
   111                                  ParseSeparators         equ     0100000000000000b       ; Separator class
   112                                  ParsePathName           equ     0010000000000000b       ; Path class
   113                                  ParsePathNameData       equ     0000000000001111b       ; Path token data mask
   114                                  ParsePathSynErr         equ     0000000000000001b       ; Path has syntax error
   115                                  ParsePathWild           equ     0000000000000010b       ; Path has wildcards
   116                                  ParsePathSeparators     equ     0000000000000100b       ; Path has pseparators
   117                                  ParseInvalidDrive       equ     0000000000001000b       ; Path has invald drive
   118                                  
   119                                  
   120                                  ; Sepchars is a string containing all of the token separator characters
   121                                  ; and is used to test for separators.
   122                                  
   123                                  section DOSCODETABLE
   124                                  Public PRS001S,PRS001E
   125                                  PRS001S label byte
   126                                  sepchrs db      9,10,13,' ','+',',',';','='     ; tab cr lf sp + , ; =
   127                                  seplen  equ     $-sepchrs
   128                                  PRS001E label byte
   129                                  section DOSCODECODE	; DOSCODETABLE   ends
   130                                  
   131                                  Procedure D_PathParse,NEAR
   132                                  	assume  ds:nothing,es:nothing
   133                                  	xor     ah,ah           ; initialize registers and flags
   134                                  	xor     bx,bx
   135                                  	cld
   136                                  	lodsb                   ; used the first byte of the token to
   137                                  	call    isswit          ; determine its type and call the routine to
   138                                  	je      switch          ; parse it
   139                                  	call    issep
   140                                  	je      separ
   141                                  	call    ispchr
   142                                  	je      path
   143                                  	call    ispsep
   144                                  	je      path
   145                                  	call    isdot
   146                                  	je      path
   147                                  	call    isinval
   148                                  	je      inval
   149                                  	stosb
   150                                  	jmp     done
   151                                  
   152                                  inval:  or      bx,ParsePathName        ; an invalid character/path token
   153                                  	or      bx,ParsePathSynErr      ; was found, set the appropriate
   154                                  	call    issep                   ; flag bits and parse the rest of
   155                                  	jne     icont                   ; the token
   156                                  	dec     di
   157                                  icont:  dec     si
   158                                  	jmp     ptosep
   159                                  
   160                                  switch: mov     bx,ParseSwitch          ; found a switch, set flag and parse
   161                                  	jmp     ptosep                  ; the rest of it
   162                                  
   163                                  separ:  mov     bx,ParseSeparators      ; found separator, set flag and parse
   164                                  seloop: lodsb                           ; everything up to the next non
   165                                  	call    issep                   ; separator character
   166                                  	je      seloop
   167                                  	jmp     bksi
   168                                  
   169                                  path:   or      bx,ParsePathName        ; found path, set flag
   170                                  	mov     cx,8                    ; set up to parse a file name
   171                                  	mov     dx,8
   172                                  	call    pasep                   ; if the token began with a path
   173                                  	jne     pcont1                  ; separator or . call rcont which
   174                                  	not     ah                      ; handles checksfor . and ..
   175                                  	jmp     rcont
   176                                  pcont1: cmp     al,'.'
   177                                  	jne     pcont2
   178                                  	dec     si
   179                                  	dec     di
   180                                  	jmp     rcont
   181                                  pcont2: cmp     al,'A'                  ; if token may start with a drive
   182                                  	jge     .drive                   ; designator, go to drive. otherwise
   183                                  	jmp     parse_name1             ; parse a file name.
   184                                  
   185                                  .drive:  cmp     byte ptr [si],':'       ; if there is a drive designator, parse
   186                                  	jne     parse_name1             ; and verify it. otherwise parse a file
   187                                  	not     ah                      ; name.
   188                                  	cmp     al, 'a'			; CDS limit
   189                                  	jb      dcont1
   190                                  	sub     al, 20h
   191                                  dcont1: sub     al,'@'
   192                                  	invoke  GetthisDrv
   193                                  	lodsb
   194                                  	stosb
   195                                  	jc      dcont2
   196                                  	jmp     dcont3
   197                                  dcont2: or      bx,ParseInvalidDrive
   198                                  dcont3: dec     cx
   199                                  	lodsb
   200                                  	call    ispsep
   201                                  	je      rcont
   202                                  	dec     si
   203                                  
   204                                  repeat: mov     al,byte ptr [si-2]      ; repeat and rcont test for //, \\, .,
   205                                  	call    pasep                   ; and .. and repeatedly calls name
   206                                  	jne     rcont                   ; and ext until a path token has
   207                                  	inc     si                      ; been completely parsed.
   208                                  	jmp     inval
   209                                  rcont:  call    dirdot
   210                                  	je      done
   211                                  	jc      inval
   212                                  	mov     cx,8
   213                                  	mov     dx,8
   214                                  	jmp     name
   215                                  
   216                                  parse_name1:
   217                                  	dec     cx
   218                                  name:   lodsb                           ; parse and verify a file name
   219                                  	call    ispchr
   220                                  	jne     ncheck
   221                                  	xor     ah,ah
   222                                  nloop:  loop    name
   223                                  	lodsb
   224                                  
   225                                  ncheck: cmp     ah,0
   226                                  	jne     ncont
   227                                  	cmp     cx,dx
   228                                  	jne     ncont
   229                                  	jmp     inval
   230                                  ncont:  call    isdot
   231                                  	je      ext
   232                                  	jmp     dcheck
   233                                  
   234                                  ext:    mov     cx,3                    ; parse and verify a file extension
   235                                  	mov     dx,3
   236                                  extl:   lodsb
   237                                  	call    ispchr
   238                                  	jne     echeck
   239                                  eloop:  loop    extl
   240                                  	lodsb
   241                                  
   242                                  echeck: cmp     cx,dx
   243                                  	jne     dcheck
   244                                  	jmp     inval
   245                                  
   246                                  dcheck: call    ispsep                  ; do the checks need to make sure
   247                                  	je      repeat                  ; a file name or extension ended
   248                                  	call    issep                   ; correctly and checks to see if
   249                                  	je      bkboth                  ; we're done
   250                                  	call    ischrnull
   251                                  	je      done
   252                                  	jmp     inval
   253                                  
   254                                  ptosep: lodsb                           ; parse everything to the next separator
   255                                  	call    issep
   256                                  	je      bkboth
   257                                  	call    ischrnull
   258                                  	je      done
   259                                  	call    isinval
   260                                  	jne     ptcont
   261                                  	or      bx,ParsePathSynErr
   262                                  ptcont: stosb
   263                                  	jmp     ptosep
   264                                  
   265                                  bkboth: dec     di                      ; clean up when the end of the token
   266                                  bksi:   dec     si                      ; is found, stick a terminating null
   267                                  done:   xor     al,al                   ; byte at the end of buf, and exit
   268                                  	stosb
   269                                  	push    si
   270                                  	invoke  Get_user_stack
   271                                  	mov     [si + user_AX],bx
   272                                  	pop     word [si + user_SI]
   273                                  	Transfer sys_ret_ok
   274                                  
   275                                  Endproc D_PathParse
   276                                  
   277                                  ; Is current character the beginning of a switch?
   278                                  
   279                                  isswit  proc    near
   280                                  	cmp     al,[ss:chSwitch]
   281                                  	jne     swret
   282                                  	stosb
   283                                  swret:  ret
   284                                  isswit  endp
   285                                  
   286                                  
   287                                  ; Is the current character a separator?
   288                                  
   289                                  issep   proc    near
   290                                  	push    cx
   291                                  	push    di
   292                                  	push    es
   293                                  	 push cs
   294                                  	 pop es
   295                                  	mov     cx,seplen
   296                                  dosgroup equ DOSGROUP	; NASM port equate
   297                                  	mov     di,offset sepchrs
   298                                  	repne   scasb
   299                                  	pop     es
   300                                  	pop     di
   301                                  	jne     sepret
   302                                  sepyes: stosb
   303                                  sepret: pop     cx
   304                                  	ret
   305                                  issep   endp
   306                                  
   307                                  
   308                                  ; Is the current character a path character?  If it is a wildcard char too,
   309                                  ;  set that flag.
   310                                  
   311                                  ispchr  proc    near
   312                                  	cmp     al,'!'
   313                                  	je      pcyes
   314                                  	cmp     al,'#'
   315                                  	jl      pcret
   316                                  	cmp     al,'*'
   317                                  	je      pcwild
   318                                  	jl      pcyes
   319                                  	cmp     al,'-'
   320                                  	je      pcyes
   321                                  	cmp     al,'0'
   322                                  	jl      pcret
   323                                  	cmp     al,'9'
   324                                  	jle     pcyes
   325                                  	cmp     al,'?'
   326                                  	je      pcwild
   327                                  	jl      pcret
   328                                  	cmp     al,'Z'
   329                                  	jle     pcyes
   330                                  	cmp     al,'^'
   331                                  	jl      pcret
   332                                  	cmp     al,'{'
   333                                  	jle     pcyes
   334                                  	cmp     al,'}'
   335                                  	je      pcyes
   336                                  	cmp     al,'~'
   337                                  	je      pcyes
   338                                  	jmp     pcret
   339                                  pcwild: or      bx,ParsePathWild
   340                                  pcyes:  stosb
   341                                  	cmp     al,al
   342                                  pcret:  ret
   343                                  ispchr  endp
   344                                  
   345                                  
   346                                  ; Is the current character a path separator?  If so, set that flag after
   347                                  ; storing the byte.
   348                                  
   349                                  ispsep  proc    near
   350                                  	call    pasep
   351                                  	jne     psret
   352                                  	stosb
   353                                  	or      bx,ParsePathSeparators
   354                                  	cmp     al,al
   355                                  psret:  ret
   356                                  ispsep  endp
   357                                  
   358                                  
   359                                  ; Set ZF if the character in AL is a path separator.
   360                                  
   361                                  pasep   proc    near
   362                                  	cmp     byte [ss:chSwitch],'/'
   363                                  	je      bkslash
   364                                  	cmp     al,'/'
   365                                  	retz
   366                                  bkslash:cmp     al,'\'
   367                                  	ret
   368                                  pasep   endp
   369                                  
   370                                  
   371                                  ; Is the current character invalid?
   372                                  
   373                                  isinval proc    near
   374                                  	cmp     al,1
   375                                  	jl      inret
   376                                  	cmp     al,8
   377                                  	jle     inyes
   378                                  	cmp     al,11
   379                                  	jl      inret
   380                                  	cmp     al,13
   381                                  	jne     incont
   382                                  	cmp     al,0
   383                                  	ret
   384                                  incont: cmp     al,31
   385                                  	jle     inyes
   386                                  	cmp     al,'['
   387                                  	je      inyes
   388                                  	cmp     al,']'
   389                                  	je      inyes
   390                                  	ret
   391                                  inyes:  cmp     al,al
   392                                  inret:  ret
   393                                  isinval endp
   394                                  
   395                                  
   396                                  ; Is the current character a dot?
   397                                  
   398                                  isdot   proc    near
   399                                  	cmp     al,'.'
   400                                  	jne     dotret
   401                                  	stosb
   402                                  dotret: ret
   403                                  isdot   endp
   404                                  
   405                                  
   406                                  ; Is the current character null?  If so, update SI for exiting.
   407                                  
   408                                  ischrnull  proc    near
   409                                  	cmp     al,0
   410                                  	jne     nulret
   411                                  	dec     si
   412                                  	cmp     al,al
   413                                  nulret: ret
   414                                  ischrnull  endp
   415                                  
   416                                  
   417                                  ; Check for . and ..  Before returning, CF and ZF are set to indicate whether
   418                                  ; the token is invalid (found . or .. followed by an invalid char - CF on),
   419                                  ; we're done (found . or .. followed by null or a separator - ZF on), or the
   420                                  ; token continues (. and .. not found or found and followed by a path
   421                                  ; separator - both flags off).
   422                                  
   423                                  dirdot  proc    near
   424                                  	cmp     byte ptr [si], '.'
   425                                  	jne     diretc
   426                                  	lodsb
   427                                  	stosb
   428                                  	cmp     byte ptr [si],'.'
   429                                  	jne     dicont
   430                                  	lodsb
   431                                  	stosb
   432                                  dicont: lodsb
   433                                  	call    ispsep
   434                                  	je      diretc
   435                                  	call    issep
   436                                  	je      dibk
   437                                  	call    ischrnull
   438                                  	je      diretd
   439                                  direti: stc                             ; Invalid return
   440                                  	ret
   441                                  dibk:   dec     si
   442                                  	dec     di
   443                                  diretd: cmp     al,al                   ; Done return
   444                                  	ret
   445                                  diretc: cmp     ah,1                    ; Continue return
   446                                  	clc
   447                                  	ret
   448                                  dirdot  endp
   449                                  %ENDIF
   450                                  
   451                                      END
