home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 21 / CD_ASCQ_21_040595.iso / dos / prg / c / freedos3 / source / comp_pv2 / comp.a86 next >
Encoding:
Text File  |  1990-01-22  |  11.0 KB  |  626 lines

  1. ;    COMP    Replacement for the messy-dos command of the same name.
  2.  
  3. ;    Usage:    comp [/#] file1 [file2]
  4. ;        where file1 and file2 may be directories or may contain
  5. ;        wildcards (but not both).  The default for file2 is the current
  6. ;        directory on the current disk.  The switch gives the maximum
  7. ;        number of errors to report per file.  Default is 65535 if file1
  8. ;        refers to a single file, 10 otherwise.
  9. ;        The '/' in the switch refers to the switch character.
  10.  
  11. ;    Author:  Paul Vojta
  12.  
  13. stdout    equ    1
  14. stderr    equ    2
  15.  
  16. CR    equ    13
  17. LF    equ    10
  18. TAB    equ    9
  19.  
  20. fn1    equ    word [5ch]    ;filename portion of string 1
  21. str2    equ    word [5eh]    ;string 2
  22. fn2    equ    word [60h]
  23. pat2    equ    62h        ;pattern for filling in wild cards in filename 2
  24. str1    equ    70h
  25.  
  26. attr    equ    21        ;byte in area43 (see below)
  27. flname    equ    30        ;ditto
  28.  
  29. ;    Begin.  Set disk transfer address and slash.
  30.  
  31.     mov    dx,offset area43
  32.     mov    ah,1ah
  33.     int    21h
  34.     mov    ax,3700h
  35.     int    21h
  36.     cmp    dl,'/'
  37.     jne    f1
  38.     mov    byte slash,'\'
  39. f1:    cld
  40.  
  41. ;    Compute buffer size.
  42.  
  43.     mov    ax,sp
  44.     sub    ax,offset buf+100h
  45.     shr    ax,1
  46.     mov    al,0
  47.     mov    word buflen,ax
  48.  
  49. ;    Handle switches
  50.  
  51.     mov    di,81h
  52.     mov    ch,0
  53.     mov    cl,[di-1]
  54.  
  55. f2:    jcxz    f8        ;if end of string
  56.     mov    al,dl        ;switch character
  57.     repnz    scasb
  58.     jne    f8        ;if done searching
  59.     cmp    al,'/'
  60.     je    f3        ;if slash, don't require preceding white space
  61.     mov    al,[di-2]
  62.     cmp    al,' '
  63.     je    f3        ;if space
  64.     cmp    al,TAB
  65.     jne    f2        ;if not tab
  66.  
  67. ;    Interpret switch (must be numeric argument)
  68.  
  69. f3:    xor    bx,bx        ;value of the argument
  70.     push    cx
  71.     mov    cx,10
  72.     mov    si,di
  73. f4:    mov    byte [si-1],' '
  74.     lodsb
  75.     sub    al,'0'
  76.     cmp    al,9    
  77.     ja    f5        ;if not digit
  78.     xchg    ax,bx
  79.     mul    cx
  80.     mov    bh,0
  81.     add    bx,ax
  82.     jmp    f4        ;loop back for more
  83.  
  84. f5:    mov    maxerrs,bx    ;save argument
  85.     pop    cx
  86.     cmp    al,' '-'0'
  87.     je    f2        ;if ended with space
  88.     cmp    al,TAB-'0'
  89.     je    f2        ;if ended with tab
  90.     cmp    al,CR-'0'
  91.     je    f2        ;if ended with CR
  92.     mov    dx,offset msg1    ;illegal switch
  93.     jmp    short f7    ;error quit
  94. f6:    mov    dx,offset msg2    ;insufficient parameters
  95. f7:    jmp    errend
  96.  
  97. ;    Start scanning parameters.
  98.  
  99. f8:    mov    si,81h
  100. f9:    lodsb            ;skip spaces
  101.     cmp    al,' '
  102.     je    f9        ;if space
  103.     cmp    al,TAB
  104.     je    f9        ;if tab
  105.     dec    si        ;get first parameter
  106.     mov    di,str1
  107.     call    getparm
  108.     jz    f6        ;if no parameter present
  109.     pushf
  110.     push    area43+attr
  111.     mov    fn1,bx        ;beginning of file name 1
  112.     lea    di,[bx+14]
  113.     mov    str2,di        ;start of second string
  114.     call    getparm
  115.     mov    fn2,bx
  116.     mov    si,bx        ;set up pat2
  117.     mov    di,pat2
  118.     mov    cx,7
  119.     rep    movsw
  120.     pop    area43+attr
  121.     popf
  122.     jns    f11        ;if wild cards
  123.     cmp    word maxerrs,0
  124.     jnz    f10        ;if maxerrs given
  125.     mov    word maxerrs,-1    ;default = -1
  126.     mov    byte hyph,0    ;don't print hyphens
  127. f10:    call    doit
  128.     jmp    short quit
  129.  
  130. ;    Compare multiple files.
  131.  
  132. f11:    cmp    word maxerrs,0
  133.     jnz    f12        ;if maxerrs given
  134.     mov    word maxerrs,10    ;default = 10
  135. f12:    mov    dx,str1
  136.     mov    cx,1
  137.     mov    ah,4eh        ;find first file
  138.     int    21h
  139.     jc    f14        ;if not found
  140.     mov    word okmsg,offset crlf
  141.  
  142. f13:    mov    si,offset area43+flname
  143.     mov    di,fn1
  144.     mov    cx,7
  145.     rep    movsw
  146.     mov    dx,str1
  147.     call    print
  148.     call    doit
  149.     mov    ah,4fh        ;find next file
  150.     int    21h
  151.     jnc    f13
  152.  
  153. quit:    mov    ax,4c00h
  154.     int    21h
  155.  
  156. f14:    mov    dx,offset msg3    ;file not found
  157.     jmp    errend
  158.  
  159. ;    GETPARM    Get next parameter.  Upon entry, si points to the next character
  160. ;        in the command string and di points where to put it.  On exit,
  161. ;        si points to the next+1 character in the command line, di points
  162. ;        to the end of the parameter, and bx points to the beginning of
  163. ;        the filename part of the string.  AH=0 if no parameter, 1 if
  164. ;        wild cards are present, and 80h if it is a file.  Flags are set
  165. ;        according to AH.
  166.  
  167. getparm:mov    str2,di
  168.  
  169. gp0:    lodsb        ;skip separators
  170.     cmp    al,' '
  171.     je    getparm
  172.     cmp    al,TAB
  173.     je    getparm
  174.     cmp    al,CR
  175.     mov    ah,0
  176.     je    gp8        ;if C/R
  177.  
  178. gp1:    stosb        ;copy until separator
  179.     lodsb
  180.     cmp    al,' '        ;check for separator
  181.     je    gp2
  182.     cmp    al,TAB
  183.     je    gp2
  184.     cmp    al,CR
  185.     jne    gp1
  186.     dec    si
  187.  
  188. ;    Process the parameter.
  189.  
  190. gp2:    mov    byte [di],0
  191.     mov    bx,di
  192.     mov    ah,81h        ;scan for start of file name
  193.  
  194. gp3:    dec    bx
  195.     cmp    bx,str2
  196.     jl    gp5        ;if past beginning
  197.     mov    al,[bx]
  198.     cmp    al,slash
  199.     je    gp6        ;if '\' or '/'
  200.     cmp    al,'?'        ;check for wild cards
  201.     je    gp4
  202.     cmp    al,'*'
  203.     jne    gp3
  204. gp4:    and    ah,7fh        ;clear no-wild bit
  205.     jmp    gp3
  206.  
  207. gp5:    cmp    byte [bx+2],':'    ;no dir. given; remove drive letter
  208.     jne    gp6
  209.     inc    bx
  210.     inc    bx
  211.  
  212. gp6:    inc    bx
  213.     or    ah,ah
  214.     jns    gp9        ;if wild cards
  215.     cmp    bx,di
  216.     mov    ah,1
  217.     je    gp8        ;if no file name
  218.     mov    ax,4300h    ;see if directory
  219.     mov    dx,str2
  220.     int    21h
  221.     mov    ah,80h
  222.     jc    gp9        ;if not found
  223.     test    cl,10h        ;test attribute for directory
  224.     jz    gp9        ;if file
  225.  
  226. ;    It's a directory.
  227.  
  228.     mov    al,slash
  229.     stosb
  230.     mov    ah,1
  231.  
  232. gp8:    push    ax
  233.     mov    bx,di        ;add "*.*"
  234.     mov    ax,'.*'
  235.     stosw
  236.     stosb
  237.     mov    byte [di],0
  238.     pop    ax
  239.  
  240. ;    Return.
  241.  
  242. gp9:    or    ah,ah        ;set flags
  243.     ret
  244.  
  245. ;    DOIT    Do it.  Str1, str2, and pat2 are assumed to be set up.
  246.  
  247. doit:    mov    si,pat2
  248.     mov    bx,fn1
  249.     mov    di,fn2
  250.     mov    cx,8
  251.     call    dopart        ;translate wild cards for main part of file name
  252.     dec    si
  253. d1:    lodsb            ;skip to file extension
  254.     or    al,al
  255.     jz    d3        ;if end of file
  256.     cmp    al,'.'
  257.     jne    d1
  258.     stosb            ;store '.'
  259. d2:    mov    al,byte [bx]    ;skip to extension in first file name
  260.     cmp    al,0
  261.     jz    d2a
  262.     inc    bx
  263.     cmp    al,'.'
  264.     jne    d2
  265. d2a:    mov    cl,3        ;translate wild cards for file extension
  266.     call    dopart
  267.  
  268. ;    Set up files.
  269.  
  270. d3:    mov    byte [di],0    ;store terminating zero
  271.     mov    dx,str1        ;open file
  272.     mov    ax,3d00h
  273.     int    21h
  274.     if c    jmp    err    ;if error
  275.     mov    si,ax
  276.     mov    ax,3d00h    ;open file
  277.     mov    dx,str2
  278.     int    21h
  279.     jnc    d3a        ;if no error
  280.     cmp    ax,2
  281.     if ne    jmp    err1    ;if not file-not-found
  282.     call    hyphens
  283.     mov    dx,offset fil
  284.     call    print
  285.     mov    dx,str2
  286.     call    print
  287.     mov    dx,offset msg3+4;' not found.'
  288.     call    print
  289.     mov    ah,3eh        ;close other file
  290.     mov    bx,si
  291.     int    21h
  292.     if c    jmp    err
  293.     ret
  294.  
  295. d3a:    mov    bx,ax
  296.     mov    word bufno,0
  297.     mov    word errcnt,0
  298.  
  299. ;    Loop for comparing.  si, bx = file handles.
  300.  
  301. d4:    mov    cx,buflen    ;read from file 1
  302.     mov    dx,offset buf
  303.     xchg    bx,si
  304.     mov    ah,3fh
  305.     int    21h
  306.     if c    jmp    err    ;if error
  307.     mov    word len1,ax
  308.     push    bx
  309.     mov    bx,si
  310.     mov    si,dx
  311.     add    dx,cx        ;read from file 2
  312.     mov    ah,3fh
  313.     int    21h
  314.     if c    jmp    err
  315.     mov    word len2,ax
  316.     push    bx
  317.     mov    di,dx
  318.     cmp    ax,len1
  319.     jle    d4z        ;find minimum length
  320.     mov    ax,len1
  321. d4z:    cmp    ax,buflen    ;whether this is the last
  322.     pushf
  323.  
  324. ;    Begin loop over mini-buffers
  325.  
  326. d5:    mov    cx,256
  327.     cmp    ax,cx
  328.     jae    d5a
  329.     mov    cx,ax
  330. d5a:    sub    ax,cx
  331.     push    ax
  332.  
  333. ;    Do comparison.
  334.  
  335. d6:    repz    cmpsb
  336.     je    d11        ;if buffers equal
  337.  
  338. ;    Print error message.
  339.  
  340.     push    cx
  341.     push    di
  342.     cmp    word errcnt,0
  343.     jne    d7        ;if not the first error
  344.     mov    dx,offset hdr    ;print header
  345.     call    print
  346. d7:    inc    word errcnt
  347.     mov    di,offset lyne
  348.     mov    dx,di
  349.     mov    ax,bufno
  350.     cmp    ah,0
  351.     je    d8        ;if not a huge file
  352.     push    ax
  353.     mov    al,ah
  354.     call    hex
  355.     stosw
  356.     pop    ax
  357. d8:    call    hex
  358.     stosw
  359.     mov    ax,si
  360.     sub    ax,offset buf+1
  361.     call    hex
  362.     stosw
  363.     pop    bx        ;old di
  364.     mov    al,[si-1]    ;convert data bytes to hex
  365.     mov    di,offset lyne+6
  366.     call    dumpbyte
  367.     mov    al,[bx-1]
  368.     call    dumpbyte
  369.  
  370. ;    Trim spaces from input line.
  371.  
  372. d9:    dec    di
  373.     cmp    byte [di],' '
  374.     je    d9        ;if space
  375.     inc    di
  376.     mov    ax,CR+256*LF
  377.     stosw
  378.     mov    al,0
  379.     stosb
  380.     mov    di,bx
  381.     call    print        ;print the line
  382.     pop    cx
  383.     mov    ax,errcnt
  384.     cmp    ax,maxerrs
  385.     jb    d10        ;if within limits
  386.     mov    dx,offset atleast
  387.     call    print
  388.     pop    ax
  389.     popf
  390.     pop    bx
  391.     pop    si
  392.     jmp    short d14
  393.  
  394. d10:    or    cx,cx
  395.     jnz    d6        ;if more comparisons to do
  396.  
  397. d11:    inc    word bufno    ;end mini-buffer
  398.     pop    ax
  399.     or    ax,ax
  400.     if nz    jmp    d5        ;if more in this buffer
  401.     popf
  402.     pop    bx        ;get file handles
  403.     pop    si
  404.     if e    jmp    d4        ;if not eof yet
  405.     mov    ax,len2
  406.     sub    ax,len1
  407.     mov    cl,'2'
  408.     jg    d12        ;if excess bytes on file 2
  409.     je    d14        ;if exact match
  410.     dec    cx
  411.     xchg    bx,si
  412.     neg    ax
  413.  
  414. ;    Excess bytes on some file.
  415.  
  416. d12:    mov    byte xs+26,cl
  417.     mov    len1,ax
  418.     mov    cx,buflen
  419.     mov    dx,offset buf
  420.  
  421. d13:    mov    ah,3fh        ;read excess bytes
  422.     int    21h
  423.     jc    err
  424.     add    len1,ax
  425.     cmp    ax,cx
  426.     je    d13        ;if more to go
  427.  
  428.     mov    al,len1+1    ;form and print excess-bytes message
  429.     call    hex
  430.     mov    xs,ax
  431.     mov    al,len1
  432.     call    hex
  433.     mov    xs+2,ax
  434.     push    bx
  435.     mov    dx,offset xs
  436.     call    print
  437.     pop    bx
  438.     inc    word errcnt
  439.     
  440. ;    Close files and print error count.
  441.  
  442. d14:    mov    ah,3eh        ;close file
  443.     int    21h
  444.     jc    err
  445.     mov    ah,3eh
  446.     xchg    bx,si
  447.     int    21h
  448.     jc    err
  449.  
  450.     mov    dx,okmsg    ;get OK-message address
  451.     mov    ax,errcnt
  452.     or    ax,ax
  453.     jz    d17        ;if no errors
  454.     mov    bx,10
  455.     xor    cx,cx
  456.  
  457. d15:    xor    dx,dx        ;convert to decimal
  458.     div    bx
  459.     add    dl,'0'
  460.     push    dx
  461.     inc    cx
  462.     or    ax,ax
  463.     jnz    d15        ;if more digits
  464.     mov    ah,2
  465.  
  466. d16:    pop    dx        ;print the number
  467.     int    21h
  468.     loop    d16
  469.     mov    dx,offset nerrs
  470.  
  471. ;    Common ending routine.
  472.  
  473. d17:    jmp    short print    ;call print and return
  474.  
  475. ;    Process errors.
  476.  
  477. err1:    cmp    ax,5
  478.     jne    err        ;if not invalid path
  479.     call    hyphens
  480.     mov    dx,offset msg4
  481.     jmp    short errend
  482.  
  483. err:    mov    dx,offset msg3    ;file not found
  484.     cmp    ax,2
  485.     je    errend        ;if file not found
  486.     call    hyphens
  487.     mov    dx,offset msg5    ;I/O error
  488. ;    jmp    short errend    ;(control falls through)
  489.  
  490. ;    Ending stuff.
  491.  
  492. errend:    mov    bx,stderr
  493.     call    print0
  494.     mov    ax,4c01h
  495.     int    21h
  496.  
  497. ;    HYPHENS    Print hyphens (but only if this is a multiple comp).
  498. ;    PRINT    Print the line at (DX).  Destroys AX,CX.
  499. ;    PRINT0    Same as above, but also requires BX = output handle.
  500.  
  501. hyphens:mov    dx,offset hyph
  502. print:    mov    bx,stdout
  503. print0:    push    di
  504.     mov    di,dx
  505.     mov    cx,-1
  506.     mov    al,0        ;find length
  507.     repnz    scasb
  508.     not    cx
  509.     dec    cx
  510.     mov    ah,40h
  511.     int    21h
  512.     pop    di
  513.     ret
  514.  
  515. ;    DOPART    Copy string from [si] to [di], changing wild cards to those
  516. ;        present in [bx].  This copies up to CX characters.
  517.  
  518. dopart:    lodsb
  519.     cmp    al,'.'
  520.     je    dp5        ;if end of this part
  521.     cmp    al,0
  522.     je    dp5        ;if end
  523.     cmp    al,'*'
  524.     jne    dp1
  525.     dec    si
  526.     mov    al,'?'
  527. dp1:    cmp    al,'?'
  528.     jne    dp2        ;if not wild card
  529.     mov    al,[bx]
  530.     cmp    al,'.'
  531.     je    dp3
  532.     cmp    al,0
  533.     je    dp3
  534. dp2:    stosb
  535. dp3:    cmp    byte [bx],'.'    ;advance [bx], but not past '.' or end of string
  536.     je    dp4
  537.     cmp    byte [bx],0
  538.     je    dp4
  539.     inc    bx
  540. dp4:    loop    dopart
  541.     inc    si
  542. dp5:    ret
  543.  
  544. ;    DUMPBYTE Print a byte in hexadecimal and then as a character.
  545.  
  546. dumpbyte:push    ax
  547.     mov    ax,'  '
  548.     stosw
  549.     pop    ax
  550.     push    ax
  551.     call    hex
  552.     stosw
  553.     mov    al,' '
  554.     stosb
  555.     pop    ax
  556.     cmp    al,0
  557.     je    db2        ;if null character
  558.     cmp    al,' '
  559.     jb    db1        ;if control character
  560.     cmp    al,127
  561.     ja    db2        ;if not a character
  562.     mov    ah,al
  563.     mov    al,''''        ;save normal character
  564.     stosw
  565.     stosb
  566.     ret
  567.  
  568. db1:    add    al,'A'-1    ;control character
  569.     mov    ah,al
  570.     mov    al,'^'
  571.     jmp    db3
  572.  
  573. db2:    mov    ax,'  '        ;just put spaces
  574. db3:    stosw
  575.     mov    al,' '
  576.     stosb
  577.     ret
  578.  
  579. ;    HEX    Convert a byte to hexadecimal.  Destroys (CL).
  580.  
  581. hex:    mov    ah,0
  582.     mov    cl,4
  583.     shl    ax,cl
  584.     shr    al,cl
  585.     add    al,90h        ;these four instructions change to ascii hex
  586.     daa
  587.     adc    al,40h
  588.     daa
  589.     xchg    al,ah
  590.     add    al,90h
  591.     daa
  592.     adc    al,40h
  593.     daa
  594.     ret
  595.  
  596. slash    db    '/'
  597. msg1    db    'Illegal switch.',CR,LF,0
  598. msg2    db    'Insufficient parameters.',CR,LF,0
  599. msg3    db    'File not found.',CR,LF,0
  600. msg4    db    'Access denied.',CR,LF,0
  601. msg5    db    'I/O error.',CR,LF,0
  602. fil    db    'File ',0
  603. hyph    db    '--',0
  604. hdr    db    CR,LF,'Byte    File 1  File 2',CR,LF,0
  605. lyne    db    'xxxx    aa      bb "x"',CR,LF,0
  606. xs    db    'nnnn excess bytes on file x.',CR,LF,0
  607. nerrs    db    ' error(s).',CR,LF,0
  608. ok    db    'Files compare OK.'    ;(continues...)
  609. crlf    db    CR,LF,0
  610. atleast    db    'At least ',0
  611.  
  612. okmsg    dw    ok
  613. maxerrs    dw    0
  614.  
  615. end1:
  616.  
  617. area43    equ    end1
  618. errcnt    equ    word end1+43
  619. bufno    equ    word end1+45
  620. len1    equ    word end1+47
  621. len2    equ    word end1+49
  622. buflen    equ    word end1+51
  623. buf    equ    end1+53
  624.  
  625.     end
  626.