home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / ASM / ALIB40.ZIP / ALIB4B.ZIP / SCAN.ASM < prev    next >
Encoding:
Assembly Source File  |  1997-12-20  |  12.9 KB  |  578 lines

  1. ;*****************************   SCAN.ASM  **********************************
  2. PAGE  70,132
  3. comment 
  4.                                 SCAN
  5.                              -------------
  6.  
  7.      Purpose:
  8.      --------
  9.  
  10.      Scan disk for string.
  11.  
  12.      Using newscan
  13.      ----------
  14.      SCAN <files/path> <pattern>
  15.  
  16.      SCAN starts searching from the current directory and checks each
  17.      each file which matches the <files/path> specification for the
  18.      <pattern>
  19.  
  20.      Example:  To scan all .ASM files in the current directory
  21.                for include files:
  22.  
  23.                      SCAN *.asm include
  24.  
  25.                To scan all the files in the current and its subdirectories
  26.                for include files:
  27.  
  28.                      SCAN *.* include             
  29.  
  30.      The <files/path> parameter applies to both files and subdirectories.
  31.      Thus, if you type "SCAN X*.* include" it will look in the current
  32.      directory and all subdirectories which begin with "X" for files
  33.      which begin with "X"
  34.      
  35.      Compiling
  36.      ---------
  37.  
  38.      The commands needed to build newscan.EXE using MASM are:
  39.         masm newscan;
  40.         link newscan,newscan,,alib.lib;
  41. 
  42.      
  43.     include    mac.inc
  44.     include    common.inc
  45. ;-----------------------------------------------------------------------------
  46.     extrn    library_setup:far
  47.     extrn    library_terminate:far    
  48.     extrn    dos_mem_allocate:far
  49.     extrn    dos_mem_release:far
  50. ;;    extrn    walk_path:far
  51.     extrn    scan_block_fopen:far
  52.     extrn    scan_block_fast:far
  53.     extrn    scan_block_fclose:far
  54.     extrn    parse_first:far
  55.     extrn    parse_next:far
  56.     extrn    stdout_string:far
  57.     extrn    stdout_crlf:far
  58.     extrn    stdout_spaces:far
  59.     extrn    stdout_char:far
  60.     extrn    is_text:far
  61.     extrn    is_stdout_console:far
  62.     extrn    key_read:far
  63. ;------------------------------------------------------------------------------
  64. code        segment byte
  65.         assume    cs:code, ds:code
  66. ;-----------------------------------------------------------------------------
  67. ;
  68.  
  69. data_area    struc
  70. file_mask    db    33 dup (?)
  71. compare_string    db    40 dup (?)
  72. match_posn    dw    ?        ;split buffer match handling
  73.  
  74. fname_off    dw    ?
  75. fname_seg    dw    ?
  76. file_handle    dw    ?
  77.  
  78. ;buffer_size    equ    512 * 125
  79. buffer_size    equ    512 * 100
  80. buffer        db    buffer_size dup (?)
  81. last_read_amount dw    ?
  82.  
  83. match_line    db    76 dup (?)
  84. open_flag    db    ?            ;set to one if new file opened
  85.  
  86. stdout_flag    db    ?            ;0=redirected 2=console
  87.  
  88.         dw    300 dup (?)        ;stack
  89. stack_        dw    ?
  90. data_area    ends
  91.  
  92. pspseg        dw    0
  93. data_seg    dw    0
  94. ;-----------------------------------------------------------------------------
  95. start:
  96.     cli
  97.     mov    cs:pspseg,es    ;save PSP segment
  98.     mov    ax,cs        ;get CODE segment
  99.     mov    ss,ax
  100.     mov    ds,ax
  101.     mov    es,ax
  102.     mov    sp,offset stack_
  103.     sti
  104.     
  105. ; next, release memory beyond the end of the program
  106. ; The  definition for ZSEG marks the
  107. ; end of the program's code, data and stack area.
  108. ; When linking be sure ZSEG is at the end of the program.
  109.  
  110.     mov    ax,zseg
  111.  
  112.     mov    bx,cs:pspseg        ;
  113.     mov    es,bx
  114.     sub    bx,ax
  115.     neg    bx            ; size of program in paragraphs
  116.     mov    ah,4Ah            ; resize memory block
  117.     int    21h
  118.  
  119.     mov    ax,cs
  120.     mov    es,ax
  121. ;
  122. ; check if enough memory free to run program
  123. ;
  124.     mov    ax,pspseg        ;pass psp segment to setup
  125.     mov    bx,8            ;number of floating point variables
  126.     call    library_setup
  127.     cmp    ax,128
  128.     jae    got_enough_mem        ;jmp if 128k of memory avail
  129. ;;    mov    al,7
  130. ;;    mov    ah,fatal_return
  131. ;;    call    lib_error_handler
  132.     jmp    exitx
  133.     
  134. got_enough_mem:
  135.     mov    ax,size data_area
  136.     mov    dx,0
  137.     call    dos_mem_allocate
  138.     mov    cs:data_seg,es
  139.     push    es
  140.     pop    ds
  141. ;
  142. ; clear data area
  143. ;
  144.     cld
  145.     mov    al,0
  146.     mov    cx,size data_area
  147.     mov    di,0
  148.     rep    stosb
  149.  
  150.     mov    di,offset file_mask
  151.     call    parse_first
  152. ;
  153. ; add error checks here and help display
  154. ;
  155.     mov    di,offset compare_string
  156.     mov    ds,cs:pspseg
  157.     mov    si,82h            ;compute the parse next postion
  158.     add    si,cx
  159.     mov    cx,0
  160.     lodsb
  161.     cmp    al,' '
  162.     jne    end_parse
  163.  
  164. parse_loop:
  165.     lodsb
  166.     cmp    al,0dh
  167.     je    end_parse
  168.     inc    cx
  169.     stosb
  170.     jmp    parse_loop        
  171.  
  172. end_parse:
  173.     mov    al,0
  174.     stosb
  175.     mov    ds,cs:data_seg        ;restore ds
  176. ;    call    parse_next
  177.  
  178.     call    is_stdout_console
  179.     mov    [ds:stdout_flag],al
  180.  
  181.     mov    si,offset compare_string
  182.     mov    dl,20h            ;match either case
  183.     call    scan_block_fopen
  184.                 
  185.     mov    si,offset file_mask
  186.     mov    ax,offset our_process
  187.     mov    cx,10h            ;walk directories also
  188.     call    FAR PTR walk_path
  189.  
  190.     call    scan_block_fclose
  191.     
  192. ; normal program exit
  193.  
  194. exitx:    mov    es,cs:data_seg
  195.     call    dos_mem_release
  196.     mov    ax,1
  197.     call    library_terminate
  198.     mov    ax,4C00h
  199.     int    21h
  200.  
  201. ;----------------------------------------------------------------------
  202. ; our_process - process each file found by walk_path
  203. ;  inputs:  es:di point at fully quailified filename including drive.
  204. ;                 Also, the path is set to same location as file.
  205. ;
  206. our_process    proc    far
  207.     push    es
  208.     pop    ds
  209.     mov    dx,di
  210.     add    dx,2        ;move past drive
  211.     mov    ax,3d00h    ;open file for read-only
  212.     int    21h
  213.     mov    ds,[cs:data_seg]
  214.     mov    [ds:open_flag],1 ;signal we opened a new file
  215.     mov    [ds:fname_off],di
  216.     mov    [ds:fname_seg],es
  217.     mov    es,[cs:data_seg]
  218.     mov    [ds:file_handle],ax
  219.     mov    di,offset compare_string
  220. ;
  221. ; read the file
  222. ;
  223. rd_lp:    mov    [ds:match_posn],di
  224.     mov    bx,[ds:file_handle]
  225.     mov    cx,buffer_size
  226.     mov    dx,offset buffer
  227.     mov    ah,3fh
  228.     int    21h
  229.     jc    exit_and_close
  230.     cmp    ax,0
  231.     je    exit_and_close
  232.     mov    [ds:last_read_amount],ax
  233. ;
  234. ; search the buffer for string
  235. ;
  236.     mov    cx,ax            ;length of buffer
  237.     mov    si,offset buffer
  238. mt_lp:    call    scan_block_fast
  239.     cmp    ax,0
  240.     jne    no_match
  241. ;
  242. ; we have found a match.  ds:si points at match end
  243. ;
  244.     cmp    [ds:open_flag],1
  245.     jne    show_match        ;jmp if file name already displayed
  246.     mov    [ds:open_flag],0
  247.  
  248.     apush    si,di,ds    
  249.     call    linefeed
  250.     lds    si,dword ptr [ds:fname_off]    ;display the file name
  251.     call    stdout_string
  252.     call    linefeed
  253.     apop    ds,di,si
  254. show_match:
  255.     call    display_match
  256.     jcxz    rd_lp
  257.     jmp    mt_lp    
  258.  
  259. ;
  260. ; no match was found, check for partial match,
  261. ;
  262. no_match:
  263.  
  264. ;
  265. ; check if more data in file
  266. ;
  267.     cmp    [ds:last_read_amount],buffer_size
  268.     je    rd_lp                ;jmp if more data in file
  269. ;
  270. ; close the file and exit
  271. ;
  272. exit_and_close:
  273.     mov    bx,[ds:file_handle]
  274.     mov    ah,3eh
  275.     int    21h    
  276.     retf
  277. our_process    endp    
  278. ;-----------------------------------------------------------------------------
  279. ; display match line
  280. ;   inputs:  ds:si point at match
  281. ;               cx = amount of data remaining in buffer
  282. ;   output:  match_line has line with match text, and it is sent to stdout
  283. ;
  284. display_match    proc    near
  285.     apush    cx,dx,si,di,bp
  286.     push    ds
  287.     pop    es
  288.     mov    ah,4
  289.     call    stdout_spaces
  290. ;
  291. ; register use: si=left end  di=right end  bp=amount collected
  292. ;    
  293.     mov    bp,0            ;init amount of data collected
  294.     mov    di,si            ;init right end
  295.     mov    ah,0            ;set mode for IS_TEXT
  296. ;
  297. ; go left and collect data
  298. ;
  299. left_lp:cmp    si,offset buffer
  300.     je    got_left        ;jmp if can't go left
  301.     mov    al,ds:[si-1]
  302.     call    is_text
  303.     jc    got_left        ;jmp if not text
  304.     inc    bp            ;bump amount collected
  305.     dec    si            ;move ptr to new char posn
  306.     cmp    bp,75
  307.     jb    left_lp            ;jmp if not at limit yet
  308. ;
  309. ; now  scan right
  310. ;
  311. got_left:
  312.     jcxz    got_right        ;jmp if no data in buffer
  313.     mov    al,ds:[di]        ;get next char
  314.     call    is_text
  315.     jc    got_right
  316.     inc    bp
  317.     inc    di
  318.     dec    cx
  319.     jcxz    got_right
  320.     cmp    bp,75
  321.     jb    got_left
  322. got_right:
  323.     mov    cx,bp            ;amount of data collected
  324.     mov    di,offset match_line
  325.     cld
  326. ;
  327. ; move data to local buffer
  328. ;
  329. mv_lp:    lodsb
  330.     cmp    al,9                ;check for tab
  331.     jne    moveon
  332.     mov    al,' '
  333. moveon:    stosb
  334.     loop    mv_lp
  335.     mov    byte ptr [di],0            ;put zero at end
  336.     mov    si,offset match_line
  337.     call    stdout_string
  338.     call    linefeed
  339.  
  340.     apop    bp,di,si,dx,cx
  341.     ret
  342. display_match    endp
  343. ;-------------------------------------------------------------------------
  344. ; linefeed - move to next display line, count line
  345. ;  inputs: none
  346. ;
  347. line_counter    db    0
  348. pause_msg    db    '(ESC=abort, any other key to continue)',0
  349.  
  350. linefeed:
  351.     apush    ax,si,ds
  352.     mov    ax,cs
  353.     mov    ds,ax
  354.     
  355.     call    stdout_crlf
  356.     mov    al,cs:line_counter
  357.     inc    al
  358.     cmp    al,23
  359.     jb    lf_exit
  360.     cmp    es:stdout_flag,0
  361.     je    lf_exit1        ;jmp if console redirected
  362.     mov    si,offset pause_msg
  363.     call    stdout_string
  364.     call    key_read
  365.     cmp    ax,3
  366.     je    abort
  367.     cmp    ax,1bh
  368.     je    abort
  369.     mov    al,0dh
  370.     call    stdout_char
  371.     mov    ah,40
  372.     call    stdout_spaces
  373.     mov    al,0dh
  374.     call    stdout_char
  375. lf_exit1:
  376.     mov    al,0    
  377. lf_exit:
  378.     mov    cs:line_counter,al
  379.     apop    ds,si,ax
  380.     ret
  381.  
  382. abort:    jmp    exitx            ;!! beware this exits program    
  383. code        ends
  384.  
  385.     page    66,132
  386. ;******************************** DISKE.ASM  *********************************
  387.  
  388.         public    walk_path
  389.  
  390. LIBSEG           segment byte public "LIB"
  391.         assume cs:LIBSEG , ds:nothing
  392.  
  393. ;----------------------------------------------------------------------------
  394. .xlist
  395.     include  mac.inc
  396.     extrn    expand_filename:far
  397. .list
  398. ;----------------------------------------------------------------------------
  399. LocalAlloc    equ    2ch        ;size of DTA for stack allocation
  400.  
  401. filename    db    128 dup (0)
  402. UpOneLevel    db    "..",0
  403. FileMask    db    13 dup (0)
  404. process        label    dword
  405. process_offset    dw    0
  406. process_seg    dw    0
  407.  
  408. comment 
  409. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(  DISK   )
  410. ;walk_path - compress data block
  411. ;
  412. ; inputs:  ds:si = pointer to asciiz file mask
  413. ;          ax    = pointer to processing for each file match.
  414. ;                  This must be a FAR routine with same CS as calling
  415. ;                  program.
  416. ;          cx    = file attributes to match.
  417. ;                  0000 - match normal data files
  418. ;                  0001 - find read only files
  419. ;                  0002 - find hidden files
  420. ;                  0004 - find system files and directories
  421. ;                  0008 - find volume labels
  422. ;                  0010 - walk subdirectories also
  423. ;
  424. ;                  note: attributes may be combined in some cases.
  425. ;
  426. ; output:  The feed proceedure is called with:  es:di = ptr to file found.
  427. ;          The file name found is fully quailfied and includes drive.
  428. ;          The current directory is where the match file was found.
  429. ;
  430. ;          After all files are processed walk_path exits with all regiseters
  431. ;          restored.
  432. ;
  433. ; note:  The path walk starts with the current directory and includes each
  434. ;        subdirectory found.
  435. ;* * * * * * * * * * * * * *
  436. 
  437. walk_path         proc     far
  438.     apush    ax,bx,cx,dx,si,di,bp,ds,es
  439.     mov    bp,sp
  440.     mov    cs:process_offset,ax
  441.     mov    ax,word ptr [bp+20]        ;get callers cs
  442.     mov    cs:process_seg,ax
  443. ;
  444. ; copy file mask from ds:si to cs:FileMask
  445. ;
  446.     cld
  447.     push    cs
  448.     pop    es
  449.     mov    di,offset FileMask
  450. wp_lp1:
  451.     lodsb
  452.     stosb
  453.     test    al,al
  454.     jnz    wp_lp1
  455.     push    cs
  456.     pop    ds
  457.     call    recursive_walk
  458.     apop    es,ds,bp,di,si,dx,cx,bx,ax
  459.         retf
  460. walk_path         endp
  461. ;
  462. ;--------------------------------------------------------------------------
  463. ; recursive_walk - walk till out of files/directories.
  464. ;  inputs:  ds,es = our code/data segment
  465. ;           FileMask =  match mask in asciiz form.
  466. ;           Process  =  far ptr to processing routine           
  467. ;
  468. recursive_walk:
  469.     push    bp
  470.         mov     ah,2Fh                  ;Get DTA address
  471.         int     21h
  472.         push    bx                      ;Save it on the stack
  473.         push    es
  474.         sub     sp,LocalAlloc           ;Allocate stack space
  475.         mov     bp,sp                   ;Stack pointer in BP
  476.         push    ss
  477.         pop    ds
  478.         mov     ah,1Ah                  ;Change DTA to location
  479.         mov     dx,bp                   ;on the stack
  480.         int     21h
  481. ;
  482.     mov    ah,4eh            ;DOS function (find first)    
  483. rs_loop:                ;mov cx,10h ;attribute = files & dir's
  484.     mov    dx,offset FileMask
  485.     push    cs
  486.     pop    ds
  487.     int    21h
  488.     jc    exit            ;jmp if end of this dir
  489.     cmp    byte ptr [bp+1eh],'.'    ;check if directory header
  490.     je    tail            ;jmp if header file
  491.     test    byte ptr [bp+15h],10h    ;check if directory entry
  492.     jz    file_fnd        ;jmp if not dir, and is file
  493. ;
  494. ; we have encountered a directory, switch to it and look for files
  495. ;
  496.     mov    ah,3bh
  497.     mov    dx,bp
  498.     add    dx,30
  499.     push    ss
  500.     pop    ds    
  501.     int    21h    
  502.  
  503.     push    bp
  504.     call    recursive_walk
  505.     pop    bp
  506. ;
  507. ; we are back from directory processing, restore origional dir.
  508. ;
  509.     mov    ah,3bh
  510.     mov    dx,offset UpOneLevel
  511.     push    cs
  512.     pop    ds
  513.     int    21h
  514.     jmp    tail
  515. ;
  516. ; we have found a file the caller wants to process
  517. ;
  518. file_fnd:
  519.     mov    si,bp
  520.     add    si,30
  521.     push    ss
  522.     pop    ds
  523.  
  524.     push    cs
  525.     pop    es    
  526.     mov    di,offset filename
  527. move_it:
  528.     lodsb
  529.     stosb
  530.     cmp    al,0
  531.     jne    move_it
  532.  
  533.     mov    si,offset filename
  534.     push    es
  535.     pop    ds
  536.     call    expand_filename
  537.     mov    di,si
  538.  
  539.     call    process
  540.  
  541. tail:    mov    ah,4fh
  542.     jmp    rs_loop    
  543. ;
  544. ; restore origional DTA from stack.
  545. ;
  546. exit:    add    sp,LocalAlloc    ;deallocate stack space
  547.     
  548.     mov    bx,ds
  549.     mov    ah,1ah        ;restore previous DTA
  550.     pop    ds
  551.     pop    dx
  552.     int    21h
  553.     mov    ds,bx
  554.     pop    bp
  555.     ret
  556.     
  557.     
  558. LIBSEG    ENDS
  559. ;;    end    
  560. ;-------------------------------------------------------------------------
  561. ;
  562. ; This segment definition is needed so linker will put the LIBSEG here
  563. ; before the ZSEG.  We want ZSEG to be last so memory allocation will
  564. ; work correctly.
  565. ;
  566. LIBSEG           segment byte public 'LIB'
  567.     assume    cs:LIBSEG
  568. LIBSEG    ENDS
  569.  
  570. ;-------------------------------------------------------------------------
  571. ; zseg must be at the end of the program for memory allocation from
  572. ; DOS.
  573. ;
  574. zseg    segment    para public 'ZZ'
  575. zseg    ends
  576.  
  577.         end    start
  578.