home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / asm / wasm / filt.asm < prev    next >
Assembly Source File  |  1988-03-07  |  15KB  |  469 lines

  1.  
  2.  Title 'Wolfware Sample Program', 'Text Filter'
  3.  
  4. ;******************************************************************************
  5. ; Text FILTer
  6. ; Copyright (c) 1988 Eric Tauck
  7. ; All rights reserved
  8. ;
  9. ; This program performs various text filter functions.  The files FILT1.ASM and
  10. ; FILE1.INC are required on the default drive/path for assembly.
  11. ;
  12. ; Usage:
  13. ;
  14. ;   FILT [options] < in_file > out_file
  15. ;
  16. ; Options:
  17. ;
  18. ;    x  = expand tabs to spaces           e  = erase all tab stops
  19. ;    c  = compress spaces to tabs         t# = set tab stop
  20. ;
  21. ;    S  = strip high bits                 m  = left margin
  22. ;    C  = strip control chars             d  = delete left margin
  23. ;    H  = strip high (>127) bytes         l# = truncate long lines
  24. ;    U  = all letters to upper-case       r  = remove trailing spaces
  25. ;    L  = all letters to lower-case       b# = byte to end input lines
  26. ;    A  = capitalize words                s  = save carriage returns
  27. ;
  28. ;    Z  = write ^Z to output              i# = input buffer size (20000)
  29. ;    z  = ignore ^Z in input              o# = output buffer size (20000)
  30.  
  31.         jmp     start
  32.  
  33. ;--- line definition
  34.  
  35. MAXLIN  EQU     600     ;maximum line length
  36. LeftMar DW      0       ;left margin
  37. LeftDel DW      0       ;left characters to delete
  38. Trunc   DW      0       ;truncate line length (truncate if non-zero)
  39.  
  40. ;--- input control block
  41.  
  42. InpBlk  LABEL   WORD
  43.         DW      0       ;status
  44.         DW      20000   ;buffer size
  45.         DW      ?
  46.         DW      ?
  47.         DW      0       ;standard input device
  48.         DW      ?
  49.  
  50. ;--- output control block
  51.  
  52. OutBlk  LABEL   WORD
  53.         DW      1       ;status
  54.         DW      20000   ;buffer size
  55.         DW      ?
  56.         DW      ?
  57.         DW      1       ;standard output device
  58.         DW      ?
  59.  
  60. ;--- special characters
  61.  
  62. TAB     EQU     9       ;tab character
  63. LF      EQU     10      ;line feed
  64. FF      EQU     12      ;form feed
  65. CR      EQU     13      ;carriage return
  66. EOF     EQU     26      ;carriage return
  67.  
  68. EOL     DB      LF      ;end of line character
  69.  
  70. ;--- character options
  71.  
  72. STR_LOB EQU     0001h   ;strip low (control) bytes
  73. STR_HIB EQU     0002h   ;strip high bytes
  74. STR_BIT EQU     0004h   ;strip high bits
  75. MAK_UPR EQU     0008h   ;make upper-case
  76. MAK_LWR EQU     0010h   ;make lower-case
  77. MAK_CAP EQU     0020h   ;capitalize
  78. REP_TAB EQU     0040h   ;replace tabs with spaces
  79. REP_SPC EQU     0080h   ;replace spaces with tabs
  80. SAV_CR  EQU     0100h   ;save CR's
  81. REM_SPC EQU     0200h   ;delete trailing spaces
  82. SKP_EOF EQU     0400h   ;skip input EOF
  83. SUP_EOF EQU     0800h   ;suppress output EOF
  84.  
  85. Options DW      0
  86.  
  87. ;--- input/output status
  88.  
  89. INP_EOL EQU     0001H   ;end of line
  90. INP_EOF EQU     0002H   ;end of file
  91. LAS_LET EQU     0004H   ;last byte was letter
  92. INP_ERR EQU     4000H   ;input error
  93. OUT_ERR EQU     8000H   ;output error
  94.  
  95. InpSta  DW      0
  96.  
  97. ;--- help message
  98.  
  99. Help    LABEL   BYTE
  100.   DB  13,10
  101.   DB  'Text Filter, Version 1.00',13,10
  102.   DB  'Copyright (c) 1988 Eric Tauck. All rights reserved',13,10
  103.   DB  13,10
  104.   DB  'Usage: FILT [options] < input_file > output_file',13,10
  105.   DB  13,10
  106.   DB  'Tab Replacement:                 Tab Assignment:',13,10
  107.   DB  '  x  = expand tabs to spaces       e  = erase all tab stops',13,10
  108.   DB  '  c  = compress spaces to tabs     t# = set tab stop',13,10
  109.   DB  'Character Replacement:           Line Format:',13,10
  110.   DB  '  S  = strip high bits             m  = add left margin',13,10
  111.   DB  '  C  = strip control chars         d  = delete left margin',13,10
  112.   DB  '  H  = strip high (>127) bytes     l# = truncate long lines',13,10
  113.   DB  '  U  = all letters to upper-case   r  = remove trailing spaces',13,10
  114.   DB  '  L  = all letters to lower-case   b# = byte to end input lines',13,10
  115.   DB  '  A  = capitalize words            s  = save carriage returns',13,10
  116.   DB  'End of File:                     I/O Buffer:',13,10
  117.   DB  '  z  = ignore ^Z in input          i# = input buffer size (20000)',13,10
  118.   DB  '  Z  = suppress ^Z in output       o# = output buffer size (20000)',13,10
  119.   DB  '$'
  120.  
  121. ;================================================
  122. ; External source code.
  123.  
  124.         include 'FILE1.INC'
  125.         include 'FILT1.ASM'
  126.  
  127. ;================================================
  128. ; Main program.
  129.  
  130. ;--- set up stack and reduce memory allocation
  131.  
  132. start   lea     bx, End         ;end of program
  133.         mov     sp, bx          ;set stack
  134.         mov     cl, 4
  135.         shr     bx, cl          ;adjust to paragraph
  136.         inc     bx              ;round up
  137.         mov     ah, 4ah         ;function
  138.         int     21h             ;execute
  139.  
  140. ;--- initialize
  141.  
  142.         mov     dx, MAXLIN      ;max margin spaces
  143.         lea     di, Margin      ;margin area
  144.         call    Spaces          ;store spaces
  145.         call    Tab_Reset       ;set default tab stops
  146.         call    Parse_Cmd       ;parse command line
  147.  
  148. ;--- input read buffer
  149.  
  150.         lea     bx, InpBlk      ;control block
  151.         call    File_Alloc      ;set up buffer
  152.         jc      main3
  153.  
  154. ;--- output write buffer
  155.  
  156.         lea     bx, OutBlk      ;control block
  157.         call    File_Alloc      ;set up buffer
  158.         jc      main3
  159.  
  160. ;--- process file
  161.  
  162.         call    Proc_Doc        ;process document
  163.  
  164.         test    InpSta, INP_ERR
  165.         jnz     main4
  166.         test    InpSta, OUT_ERR
  167.         jnz     main5
  168.  
  169. ;--- close input buffer
  170.  
  171.         lea     bx, InpBlk      ;control block
  172.         call    File_Free       ;close buffer
  173.  
  174. ;--- close output buffer
  175.  
  176.         lea     bx, OutBlk      ;control block
  177.         call    File_Flush      ;flush file first
  178.         jc      main5
  179.         call    File_Free       ;close buffer
  180.  
  181.         mov     ax, 4c00h
  182.         int     21h
  183.  
  184. ;--- not enough memory
  185.  
  186. main3   mov     al, 1
  187.         jmp     Error_Exit
  188.  
  189. ;--- error reading input file
  190.  
  191. main4   mov     al, 2
  192.         jmp     Error_Exit
  193.  
  194. ;--- error writing output file
  195.  
  196. main5   mov     al, 3
  197.         jmp     Error_Exit
  198.  
  199. ;================================================
  200. ; Parse command line.
  201.  
  202. Parse_Cmd PROC  NEAR
  203.         mov     si, 80h         ;command tail
  204.         lodsb                   ;get number of bytes
  205.         mov     bx, si
  206.         sub     ah, ah
  207.         add     bx, ax          ;BX points to end
  208.  
  209. parcmd1 cmp     bx, si          ;check if done
  210.         je      parcmd5
  211.  
  212.         lodsb                   ;get character
  213.         mov     mess1+16, al    ;put in message in case of error
  214.         lea     di, OptTab      ;start of table
  215.  
  216. parcmd2 cmp     BYTE [di], 0    ;check if end of table
  217.         je      parcmd6
  218.         cmp     al, [di]        ;check if option matches
  219.         je      parcmd3
  220.         add     di, 5           ;skip to next entry
  221.         jmps    parcmd2
  222.  
  223. ;--- found matching option
  224.  
  225. parcmd3 mov     ax, [di+1]      ;load command word
  226.         or      ax, ax          ;check if branch location
  227.         jnz     parcmd4
  228.         mov     ax, [di+3]      ;load option flag
  229.         xor     Options, ax     ;flip bits
  230.         jmp     parcmd1
  231.  
  232. parcmd4 call    ax              ;branch to special routine
  233.         jmp     parcmd1
  234.  
  235. ;--- finished
  236.  
  237. parcmd5 ret
  238.  
  239. ;--- bad option
  240.  
  241. parcmd6 mov     al, 0           ;error number
  242.         jmp     Error_Exit      ;branch to error routine
  243.         ENDP                    ;Parse_Cmd
  244.  
  245. ;------------------------------------------------
  246. ; Option table.
  247.  
  248. OptTab  LABEL   BYTE
  249.         DB      ' ', WORD 0, WORD 0             ;option delimiter
  250.         DB      ',', WORD 0, WORD 0             ;option delimiter
  251.         DB      '-', WORD 0, WORD 0             ;option delimiter
  252.         DB      '/', WORD 0, WORD 0             ;option delimiter
  253.         DB      'x', WORD 0, WORD REP_TAB       ;expand tabs
  254.         DB      'c', WORD 0, WORD REP_SPC       ;compress spaces with tabs
  255.         DB      'e', OFFSET setopt4, WORD 0     ;erase all tab stops
  256.         DB      't', OFFSET setopt5, WORD 0     ;set tab stop
  257.         DB      'S', WORD 0, WORD STR_BIT       ;strip high bits
  258.         DB      'C', WORD 0, WORD STR_LOB       ;strip control (<32) chars
  259.         DB      'H', WORD 0, WORD STR_HIB       ;strip high (>127) bytes
  260.         DB      'U', WORD 0, WORD MAK_UPR       ;all letters to upper-case
  261.         DB      'L', WORD 0, WORD MAK_LWR       ;all letters to lower-case
  262.         DB      'A', WORD 0, WORD MAK_CAP       ;capitalize words
  263.         DB      'm', OFFSET setopt7, WORD 0     ;left margin
  264.         DB      'd', OFFSET setopt8, WORD 0     ;delete left margin
  265.         DB      'l', OFFSET setopt6, WORD 0     ;truncate lines
  266.         DB      'r', WORD 0, WORD REM_SPC       ;remove trailing spaces
  267.         DB      'b', OFFSET setopt3, WORD 0     ;byte to end input lines
  268.         DB      's', WORD 0, WORD SAV_CR        ;save CR's
  269.         DB      'z', WORD 0, WORD SKP_EOF       ;ignore input EOF
  270.         DB      'Z', WORD 0, WORD SUP_EOF       ;suppress output EOF
  271.         DB      'i', OFFSET setopt1, WORD 0     ;input buffer size (20000)
  272.         DB      'o', OFFSET setopt2, WORD 0     ;output buffer size (20000)
  273.         DB      '?', OFFSET setopt9, WORD 0     ;display help
  274.         DB      'h', OFFSET setopt9, WORD 0     ;display help
  275.         DB      0
  276.  
  277. ;------------------------------------------------
  278. ; Special option setting routines.
  279.  
  280. ;--- set input buffer size
  281.  
  282. setopt1 PROC    NEAR
  283.         call    Cmd_Num         ;get size
  284.         mov     InpBlk+2, cx    ;save
  285.         ret
  286.         ENDP
  287.  
  288. ;--- set output buffer size
  289.  
  290. setopt2 PROC    NEAR
  291.         call    Cmd_Num         ;get size
  292.         mov     OutBlk+2, cx    ;save
  293.         ret
  294.         ENDP
  295.  
  296. ;--- byte to end lines
  297.  
  298. setopt3 PROC    NEAR
  299.         call    Cmd_Num         ;get byte
  300.         mov     EOL, cl         ;save
  301.         ret
  302.         ENDP
  303.  
  304. ;--- clear all tab stops
  305.  
  306. setopt4 PROC    NEAR
  307.         call    Tab_Clear       ;clear all stops
  308.         ret
  309.         ENDP
  310.  
  311. ;--- set a tab stop
  312.  
  313. setopt5 PROC    NEAR
  314.         call    Cmd_Num         ;get location
  315.         push    bx
  316.         mov     bx, cx
  317.         dec     bx              ;start numbering at 0
  318.         call    Tab_Set         ;set tab stop
  319.         pop     bx
  320.         ret
  321.         ENDP
  322.  
  323. ;--- truncate lines
  324.  
  325. setopt6 PROC    NEAR
  326.         call    Cmd_Num         ;get length
  327.         mov     Trunc, cx       ;save
  328.         ret
  329.         ENDP
  330.  
  331. ;--- left margin
  332.  
  333. setopt7 PROC    NEAR
  334.         call    Cmd_Num         ;get size
  335.         mov     LeftMar, cx     ;save
  336.         ret
  337.         ENDP
  338.  
  339. ;--- delete left margin
  340.  
  341. setopt8 PROC    NEAR
  342.         call    Cmd_Num         ;get bytes to delete
  343.         mov     LeftDel, cx     ;save
  344.         ret
  345.         ENDP
  346.  
  347. ;--- display help message
  348.  
  349. setopt9 PROC    NEAR
  350.         mov     ah, 9           ;display function
  351.         lea     dx, Help        ;load help location
  352.         int     21h             ;execute
  353.         mov     ax, 4c03h       ;exit function and error code
  354.         int     21h             ;execute
  355.         ENDP
  356.  
  357. ;------------------------------------------------
  358. ; Read a command line number. Number returned
  359. ; in CX.
  360.  
  361. Cmd_Num PROC    NEAR
  362.         sub     cx, cx
  363.  
  364. cmdnum1 cmp     bx, si          ;check if done
  365.         je      cmdnum2
  366.  
  367.         cmp     BYTE [si], '0'  ;check if below zero
  368.         jb      cmdnum2
  369.         cmp     BYTE [si], '9'  ;check if above nine
  370.         ja      cmdnum2
  371.  
  372.         mov     ax, 10          ;base ten
  373.         mul     ax, cx          ;multiply
  374.         jc      cmdnum3         ;jump if overflow
  375.         mov     cx, ax          ;back into total
  376.         lodsb                   ;load number
  377.         sub     al, '0'         ;convert to binary
  378.         sub     ah, ah
  379.         add     cx, ax          ;add to total
  380.         jmps    cmdnum1
  381.  
  382. ;--- finished
  383.  
  384. cmdnum2 ret
  385.  
  386. ;--- overflow
  387.  
  388. cmdnum3 mov     al, 0           ;error number
  389.         jmp     Error_Exit      ;branch to error routine
  390.         ENDP                    ;Cmd_Num
  391.  
  392. ;================================================
  393. ; Error routine.
  394. ;
  395. ; In: AL= local error number
  396.  
  397. Error_Exit      LABEL   NEAR
  398.  
  399. ;--- get error table entry
  400.  
  401.         sub     ah, ah
  402.         mov     bx, ax
  403.         shl     ax
  404.         add     bx, ax                  ;error number times three
  405.         lea     si, [ErrTbl + bx]       ;get location of error data
  406.  
  407.         lodsb                           ;load return code
  408.         push    ax
  409.  
  410. ;--- write message
  411.  
  412.         lodsw                           ;load offset of message
  413.         mov     si, ax
  414.         lodsb                           ;load length of message
  415.         sub     ah, ah
  416.         mov     cx, ax                  ;length in CX
  417.         mov     bx, 2                   ;error device
  418.         mov     dx, si                  ;offset in DX
  419.         mov     ah, 40h                 ;function
  420.         int     21h                     ;execute
  421.  
  422. ;--- exit
  423.  
  424.         pop     ax                      ;restore error code
  425.         mov     ah, 4ch                 ;exit function
  426.         int     21h                     ;execute
  427.  
  428. ;------------------------------------------------
  429. ; Messages and return codes.
  430.  
  431. ;--- messages
  432.  
  433. mess1   DB      37, 'Option error: "?", enter ? for help',13,10
  434. mess2   DB      21, 'Insufficient memory',13,10
  435. mess3   DB      12, 'Read error',13,10
  436. mess4   DB      13, 'Write error',13,10
  437.  
  438. ;--- error table
  439.  
  440. ErrTbl  LABEL   BYTE
  441.         DB      3, OFFSET mess1         ;option error           (0)
  442.         DB      4, OFFSET mess2         ;insufficient memory    (1)
  443.         DB      2, OFFSET mess3         ;input error            (2)
  444.         DB      1, OFFSET mess4         ;output error           (3)
  445.  
  446. ;================================================
  447. ; Uninitialized data.
  448.  
  449. InpBuf  LABEL   BYTE            ;input read location
  450.         ORG     +1
  451.  
  452. Margin  LABEL   BYTE            ;margin
  453.         ORG     +MAXLIN
  454. LinBuf  LABEL   BYTE            ;line buffer
  455.         ORG     +MAXLIN+2
  456.  
  457. TabTbl  LABEL   BYTE            ;tab table
  458.         ORG     +MAXLIN
  459. TabEndx LABEL   BYTE
  460. TabEnd  EQU     OFFSET TabEndx  ;end of tab table
  461.  
  462. SpcCnt  LABEL   WORD            ;space count (for compressing spaces)
  463.         ORG     +2
  464. TabOff  LABEL   WORD            ;tab offset (decrements tab column number)
  465.         ORG     +2
  466.  
  467.         ORG     +500
  468. End     LABEL   BYTE            ;end of code and data, top of stack
  469.