home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MURUTIL4.ZIP / TRIM.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-11-22  |  8.1 KB  |  278 lines

  1.     PAGE    57,132
  2.     TITLE    TRIM -- File Trimming Filter Routine.
  3.     NAME    TRIM
  4. ;
  5. ;    Usage:  TRIM <INPUT.FIL >OUTPUT.FIL
  6. ;
  7. ;    This is a filter routine which copies the input file  to  the
  8. ;    output file while filtering out the FFH byte and all  control
  9. ;    bytes except for tabs.   Each carriage-return is followed  by
  10. ;    a line-feed code.  Trailing blanks are deleted.  An all-blank
  11. ;    line is written simply as a CR/LF combination.
  12. ;
  13. ;    Ground rules:
  14. ;            (1)  All routines must  preserve  any  needed
  15. ;            registers before calling other routines.
  16. ;
  17. ;            (2)  Registers SI and DI index the input  and
  18. ;            the output buffers, respectively.
  19. ;
  20. ;    Program by Harry M. Murphy,  4 March 1987.
  21. ;
  22. ;                               NOTICE
  23. ;
  24. ;       Copyright 1987, Harry M. Murphy.
  25. ;
  26. ;       A general license is hereby  granted  for  non-commercial
  27. ;       use,  copying and free exchange of this  program  without
  28. ;       payment of any royalties,  provided that  this  copyright
  29. ;       notice is not altered nor deleted.   All other rights are
  30. ;       reserved.   This program is supplied as-is and the author
  31. ;       hereby disclaims all warranties,  expressed  or  implied,
  32. ;       including any and all warranties of  merchantability  and
  33. ;       any and all warranties of suitability  for  any  purpose.
  34. ;       Use of this program in  any  way  whatsoever  constitutes
  35. ;       acceptance of the terms of this license.
  36. ;
  37. ;       Harry M. Murphy, Consultant
  38. ;       3912 Hilton Avenue, NE
  39. ;       Albuquerque, NM  87110
  40. ;
  41. ;
  42. BEL    EQU    07H        ;Bell (beep) code.
  43. BUFLEN    EQU    1000H        ;Length of the I/O buffers.
  44. CTLZ    EQU    1AH        ;Control-Z (ASCII SUB) code.
  45. CR    EQU    0DH        ;Carriage Return code.
  46. DOS    EQU    21H        ;DOS interrupt code.
  47. HT    EQU    09H        ;Tab code.
  48. LF    EQU    0AH        ;Line Feed code.
  49. LINLEN    EQU    100H        ;Line length.
  50. STDIN    EQU    0        ;Standard input file handle.
  51. STDOUT    EQU    1        ;Standard output file handle.
  52. ;
  53. ;
  54. TRIM SEGMENT 'CODE'
  55.     ORG    100H        ;This is a "COM" routine.
  56.     ASSUME    CS:TRIM,DS:TRIM
  57. ;
  58. MAIN    PROC    NEAR        ;TRIM starts here.
  59.     XOR    AX,AX        ;Zero AX and
  60.     MOV    EOF,AX        ;  clear end-of-file flag,
  61.     MOV    LINP,AX        ;    clear input buffer length,
  62.     MOV    LLIN,AX        ;      clear line length,
  63.     MOV    SI,AX        ;        clear input index and
  64.     MOV    DI,AX        ;          clear output index.
  65. ;
  66. MAIN1:    CALL    GETLIN        ;Get a line
  67.     CMP    EOF,0        ;  and skip
  68.     JNE    MAIN2        ;    if end-of file.
  69. ;
  70.     CALL    PUTLIN        ;Else, output the line and
  71.     JMP    MAIN1        ;  loop for another.
  72. ;
  73. MAIN2:    CMP    LLIN,0        ;If the line length is
  74.     JE    MAIN3        ;  zero, then skip to flush.
  75. ;
  76.     CALL    PUTLIN        ;Else, output the last line.
  77. ;
  78. MAIN3:    CALL    FLUSH        ;Flush the output buffer and
  79.     MOV    AX,4C00H    ;  exit with
  80.     INT    DOS        ;    ERRORLEVEL = 0.
  81. MAIN    ENDP
  82. ;
  83. ;
  84. ABORT    PROC    NEAR        ;Abort routine.  Jump to this routine
  85. ;                ;with DX containing the offset of  an
  86. ;                ;ASCIIZ error message.
  87. ;        
  88.     MOV    AH,0EH        ;Prepare for BIOS output text in
  89.     XOR    BX,BX        ;  teletype mode interrupt.
  90.     MOV    SI,DX        ;Copy ASCIIZ pointer to SI and
  91.     CLD            ;  clear direction flag.
  92. ;
  93. ABRT1:    LODSB            ;Get next byte of the message,
  94.     OR    AL,AL        ;  skip to
  95.     JZ    ABRT2        ;    exit on zero.
  96. ;
  97.     INT    10H        ;Else, display the byte and
  98.     JMP    ABRT1        ;  loop for next byte.
  99. ;
  100. ABRT2:    MOV    AX,4C07H    ;Exit with
  101.     INT    DOS        ;  ERRORLEVEL = 7.
  102. ABORT    ENDP
  103. ;
  104. ;
  105. FLUSH    PROC    NEAR        ;Subroutine to flush the output buffer.
  106. ;
  107.     MOV    AL,CTLZ        ;Output a final
  108.     CALL    PUTCH        ;  Control-Z.
  109.     OR    DI,DI        ;If the output buffer is empty,
  110.     JZ    FLUSH2        ;  skip to return.
  111. ;
  112.     MOV    AH,40H        ;Else
  113.     MOV    BX,STDOUT    ;  call DOS
  114.     MOV    CX,DI        ;    to flush
  115.     MOV    DX,OFFSET OUTPUT ;     the output
  116.     INT    DOS        ;        buffer.
  117.     JNC    FLUSH1        ;If no carry, OK.
  118. ;
  119.     MOV    DX,OFFSET WRMSG    ;Else, point to write-error message
  120.     JMP    ABORT        ;  and abort.
  121. ;
  122. FLUSH1:    INC    AX        ;If we wrote all the bytes, or all the
  123.     CMP    AX,DI        ;  bytes except for the CTLZ,
  124.     JAE    FLUSH2        ;    then OK.
  125. ;
  126.     MOV    DX,OFFSET WFMSG    ;Else, point to "full" message
  127.     JMP    ABORT        ;  and abort.
  128. ;
  129. FLUSH2:    XOR    DI,DI        ;Clear the output index and
  130.     RET            ;  return.
  131. FLUSH    ENDP
  132. ;
  133. ;
  134. GETCH    PROC    NEAR        ;Subroutine to get the next  input  byte
  135. ;                ;in AL.  If end-of-file, EOF is returned
  136. ;                ;set to -1, else it's set to 0.
  137. ;
  138.     CMP    SI,LINP        ;If we haven't read the last byte from
  139.     JNE    GETCH2        ;  the input buffer, skip to GETCH2.
  140. ;
  141.     MOV    EOF,0        ;Else, clear the end-of-file flag and
  142.     MOV    AH,3FH        ;  call DOS
  143.     MOV    BX,STDIN    ;    to read
  144.     MOV    CX,BUFLEN    ;      into the
  145.     MOV    DX,OFFSET INPUT    ;        input
  146.     INT    DOS        ;          buffer.
  147.     JNC    GETCH1        ;If no carry, OK.
  148. ;
  149.     MOV    DX,OFFSET RDMSG    ;Else, point to read-error message
  150.     JMP    ABORT        ;  and abort.
  151. ;
  152. GETCH1:    XOR    SI,SI        ;Clear the input index and
  153.     MOV    LINP,AX        ;  copy number of bytes read to LINP.
  154.     OR    AX,AX        ;If the number of bytes
  155.     JNZ    GETCH2        ;  is non-zero, OK.
  156. ;
  157.     DEC    EOF        ;Else, set the end-of-file flag.
  158. ;
  159. GETCH2:    MOV    AL,BYTE PTR INPUT[SI] ;Get byte in AL,
  160.     INC    SI        ;  increment input index and
  161.     RET            ;    return.
  162. GETCH    ENDP
  163. ;
  164. ;
  165. GETLIN    PROC    NEAR        ;Subroutine to get and filter an input
  166. ;                ;line.   If end-of-file,  then EOF is
  167. ;                ;returned set to -1, else it's set to 0.
  168. ;
  169.     MOV    LLIN,0        ;Start:  clear the line length.
  170. ;
  171. GETLN1:    CALL    GETCH        ;Get an input byte in AL,
  172.     CMP    EOF,0        ;  check for end-of-file and
  173.     JNE    GETLN5        ;    skip to return if EOF.
  174. ;
  175.     CMP    AL,0FFH        ;Reject
  176.     JE    GETLN1        ;  FFH bytes.
  177. ;
  178.     CMP    AL,' '        ;Else, accept all bytes equal to, or
  179.     JAE    GETLN2        ;  above, a blank code.
  180. ;
  181.     CMP    AL,HT        ;Else, accept horizontal-tab
  182.     JE    GETLN2        ;  bytes.
  183. ;
  184.     CMP    AL,CR        ;Else, skip to GETLN3 if it's a
  185.     JE    GETLN3        ;  carriage-return code.
  186. ;
  187.     JMP    GETLN1        ;Else, reject this byte.
  188. ;
  189. GETLN2:    MOV    BX,LLIN        ;Get current line length in BX,
  190.     MOV    BYTE PTR LINE[BX],AL ;copy the byte to the line,
  191.     INC    BX        ;    increment the line length and
  192.     MOV    LLIN,BX        ;      re-store in LLIN.
  193.     CMP    BX,LINLEN    ;If the line isn't full,
  194.     JNE    GETLN1        ;  loop for another byte.
  195. ;
  196. GETLN3:    MOV    BX,LLIN        ;Get the line length in BX and
  197.     OR    BX,BX        ;  if it's zero,
  198.     JZ    GETLN5        ;    skip to return.
  199. ;
  200. GETLN4:    CMP    BYTE PTR LINE[BX-1],' ' ;Else, if the last byte isn't
  201.     JNE    GETLN5        ;  a blank, skip to return.
  202. ;
  203.     DEC    BX        ;Else, decrement the line count in BX
  204.     MOV    LLIN,BX        ;  and LLIN and
  205.     JNZ    GETLN4        ;    loop if BX isn't zero.
  206. ;
  207. GETLN5:    RET            ;Return with the line length in LLIN.
  208. GETLIN    ENDP
  209. ;
  210. ;
  211. PUTCH    PROC    NEAR        ;Subroutine to output the byte in AL.
  212. ;
  213.     MOV    BYTE PTR OUTPUT[DI],AL ;Copy AL to the output buffer,
  214.     INC    DI        ;  and increment the buffer index.
  215.     CMP    DI,BUFLEN    ;If the buffer isn't full,
  216.     JB    PUTCH2        ;  skip to return.
  217. ;
  218.     MOV    AH,40H        ;Else,
  219.     MOV    BX,STDOUT    ;  call DOS to
  220.     MOV    CX,BUFLEN    ;    write the
  221.     MOV    DX,OFFSET OUTPUT ;     output
  222.     INT    DOS        ;        buffer.
  223.     JNC    PUTCH1        ;If no carry, OK.
  224. ;
  225.     MOV    DX,OFFSET WRMSG    ;Else, point to write-error message
  226.     JMP    ABORT        ;  and abort.
  227. ;
  228. PUTCH1:    XOR    DI,DI        ;Clear the output index and
  229.     CMP    AX,BUFLEN    ;  check if all bytes were written.
  230.     JE    PUTCH2        ;    If so, skip to return.
  231. ;
  232.     MOV    DX,OFFSET WFMSG    ;Else, point to "full" message
  233.     JMP    ABORT        ;  and abort.
  234. ;
  235. PUTCH2:    RET            ;Return.
  236. PUTCH    ENDP
  237. ;
  238. ;
  239. PUTLIN    PROC    NEAR        ;Subroutine to output the line in LINE
  240. ;                ;whose length is LLIN.
  241. ;
  242.     MOV    CX,LLIN        ;Get line length in CX and
  243.     OR    CX,CX        ;  if it's zero,
  244.     JZ    PUTLN2        ;    skip to output CR/LF.
  245. ;
  246.     XOR    BX,BX        ;Else clear BX as a line index.
  247. ;
  248. PUTLN1:    MOV    AL,BYTE PTR LINE[BX] ;Get the next byte from LINE in AL
  249.     INC    BX        ;  increment the line index,
  250.     PUSH    BX        ;    save the line index
  251.     PUSH    CX        ;      save the byte count and
  252.     CALL    PUTCH        ;        call PUTCH to output it.
  253.     POP    CX        ;Restore the byte count,
  254.     POP    BX        ;  restore the line index and
  255.     LOOP    PUTLN1        ;    loop to output the next byte.
  256. ;
  257. PUTLN2:    MOV    AL,CR        ;Output a trailing
  258.     CALL    PUTCH        ;  carriage-return and
  259.     MOV    AL,LF        ;    a trailing
  260.     CALL    PUTCH        ;      line-feed and
  261.     RET            ;         return.
  262. PUTLIN    ENDP
  263. ;
  264. ;
  265. RDMSG    DB    CR,LF,'Read error!',CR,LF,BEL,0
  266. WRMSG    DB    CR,LF,'Write error!',CR,LF,BEL,0
  267. WFMSG    DB    CR,LF,'Disk full error!',CR,LF,BEL,0
  268.     EVEN
  269. EOF    DW    0        ;End-of-File flag.
  270. LINP    DW    0        ;Input buffer byte count.
  271. LLIN    DW    0        ;Line length.
  272. ;
  273. LINE    LABEL    BYTE        ;Start of LINE buffer.
  274. INPUT    EQU    LINE+LINLEN    ;Start of INPUT buffer.
  275. OUTPUT    EQU    INPUT+BUFLEN    ;Start of OUTPUT buffer.
  276. TRIM    ENDS
  277.     END    MAIN
  278.