home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 December / simtel1292_SIMTEL_1292_Walnut_Creek.iso / msdos / txtutl / toadtrim.arc / TOADTRIM.ASM next >
Assembly Source File  |  1990-01-19  |  6KB  |  215 lines

  1. Comment ~
  2. Date: Thu, 18 Jan 1990  21:14 MST
  3. From: Keith Petersen <w8sdz@WSMR-SIMTEL20.ARMY.MIL>
  4. To: kirsch@arsocomvax.socom.mil
  5. Subject: TOADTRIM
  6.  
  7. David, time for another Toad Hall program: TOADTRIM.  Trims trailing
  8. spaces from each line in a text file.  Seems to me this is far better
  9. done in MASM than C or Pascal.
  10.  
  11. --Keith
  12.  
  13. Comment    ends    ~
  14.  
  15. TITLE    TOADTRIM    [900119]
  16.  
  17. ;Yeah, we can do that ...
  18. ;David Kirschbaum
  19. ;Toad Hall
  20. ;kirsch@arsocomvax.socom.mil
  21.  
  22.  
  23. CR    EQU    0DH
  24. LF    EQU    0AH
  25.  
  26. BUFFSIZ    equ    (0E800H SHR 1)    ;input buffer gets a little less than half
  27.                 ;of remaining 64Kb code space.
  28.                 ;It may run up to 1/2, however, as we read
  29.                 ;in up to EOL.
  30.                 ;Output buffer lies beyond input buffer.
  31.                 ;Hopefully it won't hit our stack!
  32.                 ;(Not making any tests for that right now!
  33.                 ; Sooooo baaaad!)
  34.  
  35. CSEG    SEGMENT PUBLIC PARA 'CODE'
  36.     ASSUME    CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
  37.  
  38.     org    80H+126            ;end of PSP cmdline
  39.  
  40. outstart label    word            ;let's use it for a variable
  41.  
  42.     ORG    100H
  43.  
  44. ToadTrim    proc    near
  45.  
  46. handle    label    word            ;var on top of this call (used once)
  47.     call    StartUp            ;Startup code down in buffer space
  48.  
  49.  
  50. BuffLup:
  51.     mov    dx,INBUFF        ;input buffer base
  52.     mov    cx,BUFFSIZ        ;read a buffer full
  53.     mov    bx,handle        ;input file handle
  54.     mov    ah,3FH            ;read from file/device
  55.     int    21H
  56.     jb    Terminate        ;read failed, die
  57.     or    ax,ax            ;anything read?
  58.     jz    Terminate        ;nope, terminate
  59.  
  60.     mov    si,dx            ;remember input buffer start
  61.  
  62.     mov    di,dx            ;input buffer start
  63.     add    di,ax            ;plus nr chars read
  64. ;DI => last input buffer char + 1
  65.  
  66.     cmp    ax,cx            ;read all we asked for?
  67.     jz    Got_EOL            ;yep, that's all of it.
  68.  
  69. ;We want to be sure our buffer ends with an EOL.
  70.  
  71. Find_Eol:
  72.     cmp    byte ptr [di-1],CR    ;is last char a CR
  73.     jz    Got_EOL            ;yep
  74.  
  75. ;We have to read in one byte at a time until we get that EOL.
  76. ;There's enough extra space in the input buffer for this
  77. ;(so long as we're talking about reasonable lines here!).
  78.  
  79.     mov    cx,1            ;one char
  80.     mov    dx,di            ;place to read next char
  81.     mov    ah,3FH            ;read from file/device
  82.     int    21H            ;(BX is still handle)
  83.     jb    Terminate        ;read failed, die
  84.     or    ax,ax            ;anything read?
  85.     jz    Got_Eol            ;nope, must be EOF
  86.      stosb                ;yep, stuff char, bump DI
  87.      jmp    short Find_Eol        ;loop back to retest for CR EOL
  88.  
  89. ;Input buffer either ends with CR EOL, or we've hit EOF.
  90. ;SI => input buffer start
  91. ;DI => last input buffer char + 1
  92. ;
  93. Got_Eol:
  94.     mov    cx,di            ; -> last char+1
  95.     sub    cx,si            ;minus buffer base = input char count
  96.     jcxz    Terminate        ;all done
  97.  
  98. ;DI => output buffer start (beyond input buffer, ne?)
  99.     mov    outstart,di        ;so remember output starting ofs
  100.     xor    bx,bx            ;init space counter
  101.  
  102. CharLup:
  103.     lodsb                ;snarf input buffer char
  104.     cmp    al,20H            ;space?
  105.     jnz    Not_Space        ;nope
  106.      inc    bx            ;yep, bump space counter
  107.      jmp    short Skip_Others    ;skip other tests
  108.  
  109. Not_Space:
  110.     cmp    al,CR            ;hit CR?
  111.     jz    Dump_Spaces        ;yep, dump all those spaces
  112.  
  113. ;Normal char, so we gotta put back the spaces we've been counting
  114.     or    bx,bx            ;skipped any spaces?
  115.     jz    Skip_Spaces        ;nope, nothing to do
  116.  
  117.     xchg    cx,bx            ;CX = nr spaces we skipped
  118.                     ;BX = old CX input char counter saved
  119.     mov    ah,al            ;save this non-space char
  120.     mov    al,20H            ;a space
  121.     rep    stosb            ;stuff back skipped spaces
  122.     mov    al,ah            ;replace non-space char
  123.     xchg    cx,bx            ;CX = saved input char counter
  124.                     ;BX = 0 (reinit space counter)
  125. Dump_Spaces:
  126.     xor    bx,bx            ;reinit space counter at a CR
  127. Skip_Spaces:
  128.     stosb                ;stuff the normal char
  129.  
  130. Skip_Others:
  131.     
  132.     loop    CharLup            ;for entire input buffer
  133. ;DI -> last output buffer char +1
  134.  
  135.     mov    dx,outstart        ;output buffer starting ofs
  136.     mov    cx,di            ;buffer starting ofs
  137.     sub    cx,dx            ; minus last char ofs +1 = char count
  138.     mov    bx,1            ;StdOut
  139.     mov    ah,40H            ;write to file/device
  140.     int    21H
  141.     jmp    SHORT    BuffLup        ;back to read another buffer-full
  142.  
  143. Terminate:
  144.     mov    ah,4CH            ;terminate (AL = any error,or 0)
  145.     int    21H            ;Let DOS close the output file
  146.  
  147. ToadTrim    endp
  148.  
  149. ;Make this even without MASM's "even" instruction
  150. INBUFF    equ    ( ( ($ - CSEG) +1) SHL 1) SHR 1
  151.  
  152. Startup    proc    near
  153.  
  154.     mov    si,80H            ;PSP cmdline length byte
  155.     xor    ax,ax            ;handy 0
  156.     mov    handle,ax        ;init handle to StdIn
  157.     lodsb                ;snarf cmdline length
  158.  
  159. ;When he's using redirection
  160. ;StdIn alone ("<") produces a command line length of 1 (space, CR)
  161. ;StdOut alone (">" : same result.
  162. ;StdIn and StdOut ("<wherever >wherever") produces a command line
  163. ;length of 2 (space, space, CR).
  164. ;A question mark alone would produce a command line length of 2
  165. ;(space, "?", CR).
  166.  
  167.     or    ax,ax            ;no cmdline?
  168.     jz    Usage            ; nope, give him help
  169.  
  170.     cmp    al,2            ;2 or less?
  171.     ja    Got_InFile        ;nope, there's a filename
  172.     jb    Started            ; 1 = he's using StdIn or StdOut alone
  173.                     ; No filenames to process, return
  174.  
  175. ;Ok, cmdline length is 2.
  176. ;Let's see if he's using StdIn and StdOut,
  177. ;or if he's asked for help (e.g., "TOADTRIM ?")
  178.  
  179.     cmp    word ptr [si],'? '    ;That's what help looks like
  180.     jz    Usage            ;It's help, all right
  181.     ret                ;He's using StdIn and StdOut
  182.                     ;No filenames to process, return
  183. Got_InFile:
  184. ;SI = 81H
  185.     add    si,ax            ;SI -> CR at filename end
  186.     mov    [si],ah            ;AsciiZ cmdline filename
  187.  
  188.     mov    dx,82H            ;cmdline first char
  189.     mov    ax,3D00H        ;open file, read-only
  190.     int    21H
  191.     jb    Terminate        ;open failed, die
  192.  
  193.     mov    handle,ax        ;save real file handle
  194. Started:
  195.     ret
  196.  
  197. Usage:
  198.     mov    dx,offset usage$
  199.     mov    ah,9            ;display msg
  200.     int    21H
  201.     mov    ax,4C00H        ;terminate, errorlevel 0
  202.     int    21H
  203.  
  204. Startup    endp
  205.  
  206. usage$    db 'TOADTRIM Trims trailing spaces from a (hopefully) text file,',CR,LF
  207.     db '    sends trimmed result to Std Out.',CR,LF,CR,LF
  208.     db 'Usage:',CR,LF
  209.     db '    TOADTRIM filename.txt [>out device or filename]',CR,LF,CR,LF
  210.     db '    Works with Std In also:',CR,LF
  211.     db '    TOADTRIM <filename.txt [>output device or filename]',CR,LF,'$'
  212.  
  213. CSEG    ENDS
  214.     END    ToadTrim
  215.