News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

scan file for lines above a given character count

Started by Rainstorm, April 21, 2008, 09:48:48 AM

Previous topic - Next topic

Rainstorm

Hi,
    This code is supposed to scan a txt file & report the line numbers & their sizes (amount of chars in a line) above the specified number. It stores the results in 2 buffers allocated using Heapalloc & reallocates more memory if needed.
I've assembled the file using the 'console Assemble & link' option in the masm32 editor.

Any comments suggestions or improvements would be appreciated.

thankyou.

    .const
        HEAP_CREATE_ENABLE_EXECUTE      equ     262144


    .data?


    .data
        pfname                      dd      0
        flen                        dd      0
        fpattern                    db      "text files",0,"*.txt",0,0
        total_characters_in_line    dd      0
        pfbuff                      dd      0
        line_char_limit             dd      0
        pline_char_limit            dd      0
        hInstance                   dd      0
       
        hHeap_line                  dd      0
        hHeap_linecharcount         dd      0
        p_linecount_buff            dd      0
        p_linecharcount_buff        dd      0

        ptop_linecount_buff         dd      0
        ptop_linecharcount_buff     dd      0
        linebuffer_usedbytes        dd      0
        charbuffer_usedbytes        dd      0
        linebuff_size               dd      0
        line_charcountbuff_size     dd      0
        total_matchinglines_found   dd      0       
        total_lines                 dd      0
        temp                        dd      0


; -----------------------------------------------------------------------


    .code

start:

    invoke GetModuleHandle, NULL      ; get the handle of this program
    mov hInstance, eax

    mov pfname,  OpenFileDlg(NULL,hInstance,"Select File",addr fpattern)
    cmp BYTE PTR [eax], 0
    je exit_

repeat_:   
    invoke read_disk_file,pfname,addr pfbuff, addr flen 
    cmp eax, 0
    je exit_

    print "returned file length - "
    print ustr$(flen),13,10

    mov total_lines, 0                      ; resets these variables
    mov total_matchinglines_found, 0


   ; ------- // Input the character limit // ---------

    mov pline_char_limit, input("enter the max character count of line ",58,32,32)
   
    mov line_char_limit, uval(pline_char_limit)
    print " ",13,10
    print "  character Limit - : "
    print ustr$(line_char_limit),13,10



       mov eax, pfbuff
       add eax, flen
       mov byte ptr [eax+1], 0


;     ------ //  Create the memory heap & Allocate Memory  // --------

    ; ----------------------------------
    ;  create buffer for line numbers
    ; ----------------------------------
   
      invoke HeapCreate, HEAP_CREATE_ENABLE_EXECUTE or HEAP_NO_SERIALIZE, 0, 0
        cmp eax, 0
        je heap_creation_error
        mov hHeap_line, eax                 ; handle to memory object

      invoke HeapAlloc, hHeap_line, HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY, 2048
        cmp eax, 0
        je heap_allocation_error
        mov p_linecount_buff, eax           ; pointer to allocated block
        mov ptop_linecount_buff, eax
       
      invoke HeapSize, hHeap_line, HEAP_NO_SERIALIZE, p_linecount_buff

        cmp eax, 4294967295                 ; tests if the size function succeeded
        je heap_size_error                  ; 4294967295 is -1 which is returned if it fails.
        mov linebuff_size, eax              ; store the size


    ; -----------------------------------------------------
    ;  create buffer for the character count of the lines
    ; -----------------------------------------------------

      invoke HeapCreate, HEAP_CREATE_ENABLE_EXECUTE or HEAP_NO_SERIALIZE, 0, 0
        cmp eax, 0
        je heap_creation_error
        mov hHeap_linecharcount, eax             ; handle to memory object

      invoke HeapAlloc, hHeap_linecharcount, HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY, 2048
        cmp eax, 0
        je heap_allocation_error
        mov p_linecharcount_buff, eax            ; pointer to allocated block
        mov ptop_linecharcount_buff, eax

      invoke HeapSize, hHeap_linecharcount, HEAP_NO_SERIALIZE, p_linecharcount_buff

        cmp eax, 4294967295
        je heap_size_error
        mov line_charcountbuff_size, eax
   

   ; --------------------------------------------------------------------------------


        mov esi, pfbuff                     ; move address of the file buffer into esi
        xor ecx, ecx
        xor ebx, ebx
        jmp count_characters
 
    pre_count:
         xor ecx, ecx                        ; reset count of chars in the line
         add esi, 1
       
    count_characters:
          cmp byte ptr [esi], 0
          je display_results       
          cmp byte ptr [esi], 10
          je newline
          inc esi                           ; pointer to file buffer
          add ecx, 1                        ; count of characters in the line
          jmp count_characters

    newline:
;         add ecx, 1                        ; would count the 'LF' too
          add total_lines, 1                ; total line count
          mov total_characters_in_line, ecx
          cmp ecx, line_char_limit    ; cmp the total chars in the line with the requested limit
          jb pre_count
          add total_matchinglines_found, 1


comment * -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
          check to see if the memory buffer is full
          if so, reallocate more memory
          else add the character count & line number to the buffer
        -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - *


    ; ---- / check if there's enough space in the buffers / -----

          mov eax, ptop_linecount_buff
          sub eax, p_linecount_buff         ; subtract base addr from top addr
          mov linebuffer_usedbytes, eax
          mov edx, linebuff_size
          sub edx, 16                       ; check at 16 bytes ahead of time
          cmp edx, eax                      ; cmp no. of used bytes with the buffer size
          jbe reallocate_linecount_buff
          call store_linenumber


       check_line_charcount_buffer:

          mov eax, ptop_linecharcount_buff
          sub eax, p_linecharcount_buff
          mov charbuffer_usedbytes, eax
          mov edx, line_charcountbuff_size
          sub edx, 16                       ; reallocate 16 bytes ahead of time
          cmp edx, eax
          jbe reallocate_charcount_buff
          call store_line_charcount
          jmp pre_count

         

    ; ---- / add the line number & character count of the line to the buffers / -----


       store_linenumber:

          mov eax, total_lines                  ; the line number
          mov edx, ptop_linecount_buff
          mov [edx], eax                        ; move the count of chars into the buffer
          add ptop_linecount_buff, 4            ; track the top of the buffer

         ret

       store_line_charcount:
       
          mov ecx, total_characters_in_line
          mov edx, ptop_linecharcount_buff
          mov [edx], ecx                         ; move the line count in the buffer
          add ptop_linecharcount_buff, 4         ; track the top of the linecount buffer
         ret 


    ; ----------- //  Reallocate Memory  // ---------------


           
    reallocate_linecount_buff:

        add linebuff_size, 2048                ; supply this as the new reallocated mem size     

    invoke HeapReAlloc, hHeap_line,HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY,
                          p_linecount_buff, linebuff_size
        cmp eax, 0
        je heap_reallocation_error
        mov p_linecount_buff, eax              ; pointer to reallocated block


      invoke HeapSize, hHeap_line, HEAP_NO_SERIALIZE, p_linecount_buff
        cmp eax, 4294967295                    ; test if the size function succeeded
        je heap_size_error
        mov linebuff_size, eax   

        pushad
        print "* Reallocation took place - Memory size = "
        print ustr$(linebuff_size),13,10
        popad

        mov eax, linebuffer_usedbytes
        add eax, p_linecount_buff
        mov ptop_linecount_buff, eax
        call store_linenumber
        jmp check_line_charcount_buffer

  ; -------------------------------------------------

   reallocate_charcount_buff:   

        add line_charcountbuff_size, 2048   ; supply this as the new mem size
     
      invoke HeapReAlloc, hHeap_linecharcount,HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY,
                          p_linecharcount_buff, line_charcountbuff_size
        cmp eax, 0
        je heap_reallocation_error
        mov p_linecharcount_buff, eax       ; pointer to reallocated block


      invoke HeapSize, hHeap_linecharcount, HEAP_NO_SERIALIZE, p_linecharcount_buff

        cmp eax, 4294967295                 ; test if the size function succeeded
        je heap_size_error
        mov line_charcountbuff_size, eax    ; store the size

        mov eax, charbuffer_usedbytes       
        add eax, p_linecharcount_buff       ; bring the pointer in the new block..
        mov ptop_linecharcount_buff, eax    ; to where it was in the buffer before..
        call store_line_charcount           ; reallocation.
        jmp pre_count



  ;---------------------------------------------------------------------   
  ;                display the results
  ;         ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

        display_results:
          print "  Filename : "
          print pfname,13,10
          print "  Total Lines: "
          print ustr$(total_lines),13,10,13,10
          inkey
          print " ",13,10,
          print "Lines with a character count equal to or above "
          print ustr$(line_char_limit)
          print "  =  "
          print ustr$(total_matchinglines_found),13,10
          print "=============================================================",13,10

          mov edi, p_linecount_buff
          mov edx, ptop_linecount_buff     
          mov dword ptr [edx+1], 0            ; add a 0 at the top of the buffer

;    --//  display the line numbers //
           
        display_results1:
          mov ebx, dword ptr [edi]
          print ustr$(ebx)
          print ", "
          add edi, 4
          cmp dword ptr [edi], 0
          jne display_results1

          print " ",13,10,
          print "=============================================================",13,10
          print " ",13,10,
      inkey
      print " ",13,10,13,10
      print "lines with corresponding character counts equal \
             to or above the requested limit",13,10

      print "==========================================================================",13,10

          mov edi, p_linecount_buff
          mov edx, ptop_linecount_buff     ; add a 0 at the top of the buffer
          mov dword ptr [edx+1], 0

          mov esi, p_linecharcount_buff
          mov edx, ptop_linecharcount_buff
          mov dword ptr [edx+1], 0

comment * -------------------------------------------------------   
            Display the line numbers with the corresponding char
            counts of the lines
          ------------------------------------------------------- *   

        display_results2:
          mov ebx, [edi]
          print ustr$(ebx)
          print " -  "
          mov ebx, [esi]
          print ustr$(ebx),13,10
          add edi, 4
          add esi, 4
          cmp dword ptr [edi], 0
          jne display_results2
         
      print " ",13,10,
      print "=============================================",13,10

      print "finished",13,10,13,10
      jmp free_memory


   ; ----------- //  Errors  //------------------------------------------

    heap_creation_error:
         print "memory error: memory heap couldn't be created",10,13
         jmp exit_

    heap_allocation_error:
         print "memory error: memory couldn't be allocated",10,13
         jmp exit_
         
    heap_reallocation_error:
         print "memory error: memory couldn't be reallocated",10,13
         jmp free_memory
         
    heap_size_error:
         print "memory error: heap size error",10,13
         jmp exit_

   ; ---------------------------------------------------------------------

    free_memory:

        free pfbuff
        free pfname
       
        invoke HeapFree, hHeap_line, HEAP_NO_SERIALIZE, p_linecount_buff
            cmp eax, 0
            jne @F
        print "HeapFree error !",13,10

      @@:
        invoke HeapFree, hHeap_linecharcount,HEAP_NO_SERIALIZE,p_linecharcount_buff
            cmp eax, 0
            jne @F
        print "HeapFree error !",13,10
            jmp exit_

      @@:
        print "Memory successfully freed...",13,10,13,10


   ; =====×= Choice for the code to loo back to the beginning or exit ===×====

    exit_:
         
         print "press C to continue with the same file, 'N' for New & any other key to exit...",13,10,"----------x---\
                -----------------x-----------------------------------------",13,10,13,10

         getkey
         cmp eax, 99        ; c
         je repeat_
         cmp eax, 67        ; C
         je repeat_
         cmp eax, "N"
         je start
         cmp eax, "n"
         je start
         
         exit


end start

[attachment deleted by admin]

kermit

Hi,

nice work, but i getc4.asm(365) : error A2006: undefined symbol : @@
c4.asm(371) : error A2006: undefined symbol : @@

when i compile it. seems the print macro doesn't work with the @@ markers.
Am i using wrong/old include files or is there another workaround ?

( I have noticed this behaviour already before)

oliver

Rainstorm

hi kermit .. thx

it assembles & runs proper for me..(am using ver 9)

these are the include files in that file     .586                                ; create 32 bit code
    .model flat, stdcall                ; 32 bit memory model
    option casemap :none                ; case sensitive
 
    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\macros\macros.asm
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\Comctl32.inc
    include \masm32\include\comdlg32.inc
    include \masm32\include\shell32.inc
    include \masm32\include\oleaut32.inc
    include \masm32\include\msvcrt.inc

    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\Comctl32.lib
    includelib \masm32\lib\comdlg32.lib
    includelib \masm32\lib\shell32.lib
    includelib \masm32\lib\oleaut32.lib
    includelib \masm32\lib\msvcrt.lib

kermit

ok, i found the error, i was compiling with the /Zi option (add symbolic debug info),

when i drop that option it compiles without errors, its working now  :U

Rainstorm

glad it worked...i'll keep that in mind  :thumbu