Announcement

Collapse
No announcement yet.

Prog to find un-used.. part 2

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Prog to find un-used.. part 2

    Continued - original thread is becoming long, I start a new one...

    Okay, did some tweaking of the code and wrote an "AdjustString" routine
    that takes care of multiple spaces and tabs, plus cuts string at uncomment
    and valid underscore characters. Also added a faster UCASE routine that can
    handle extended ASCII, since we over here may have used such characters in
    a variable/routine name. PB's UCASE does not handle extended ASCII table.
    Own test shows better speed and all seems to work like it should.

    For best speed, one should grab entire file into a string and extract each
    line via pointer or INSTR loop, but this is fast enough for most needs so
    I don't care to do that. Reading and processing line by line has other
    advantages, like being leaner to memory, so..

    BTW, I also changed some IF/THEN to become ELSEIF, because if a line starts with
    "FUNCTION =", there's no point in checking it once more for "FUNCTION=", etc.

    The following three together replaces single "Process" routine in previous code.
    Code:
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' asmUCASE routine, alters given string directly - very fast..
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    SUB asmUCASE(a$)
      IF LEN(a$) = 0 THEN EXIT SUB
      #REGISTER NONE
     
      ! mov eax, a$            ; eax = pointer to string handle
      ! mov eax, [eax]         ; eax = pointer to string data
      ! mov ecx, [eax-4]       ; move length of string into ecx
     
      BgnUpLoop:
         ! mov dl, [eax]       ; move current char into dl
         ! cmp dl, 97          ; compare against value 97 (a)
         ! jb NoDnChar         ; if dl < 97 it is in 0-97 range, do nothing - get next
         ! cmp dl, 123         ; compare against value 123
         ! jb MakeUpper        ; if dl < 123 it is in 97-122 range, make Upper case and get next
         ! cmp dl, 224         ; compare against value 224 (à) - extended ANSI characters
         ! jb NoDnChar         ; if dl < 224 it is in 123-223 range, do nothing - get next
         ! cmp dl, 247         ; compare against value 247 (à)
         ! jb MakeUpper        ; if dl < 247 it is in 224-246 range, make Upper case and get next
         ! je NoDnChar         ; else dl = 247 (÷), do nothing - get next
         ! cmp dl, 255         ; compare against value 255 (ÿ)
         ! jb MakeUpper        ; if dl < 255 it is in 248-254 range, make Upper case and get next
         ! jmp NoDnChar        ; else dl = 255, do nothing - get next
     
      MakeUpper:
         ! sub dl, 32          ; make uppercase subtracting 32 from dl's value
         ! mov [eax], dl       ; write changed char back into a$
     
      NoDnChar:
         ! inc eax             ; get next character
         ! dec ecx             ; decrease ecx (length) counter
         ! jnz bgnUpLoop       ; iterate if not zero
     
    END SUB
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
    ' AdjustString removes multiple spaces, replaces eventual tab with space
    ' and cuts the string if a valid underscore or uncomment character is found
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
    SUB AdjustString(tStr AS STRING)
     
      tStr = TRIM$(tStr, ANY CHR$(32,0))  'trim string
      IF LEN(tStr) = 0 THEN EXIT SUB      'if string is empty, exit
      CALL asmUCASE(tStr)                 'and make UCASE for comparisons
     
    '  tStr = UCASE$(TRIM$(tStr, ANY CHR$(32,0)))  'trim string and make UCASE for comparisons
     
      DO WHILE INSTR(tStr, "  ")                  'replace multiple spaces with single space
         REPLACE "        " WITH " " IN tStr      'do several replacements with decreasing
         REPLACE "      " WITH " " IN tStr        'space length for much faster action
         REPLACE "    " WITH " " IN tStr
         REPLACE "  " WITH " " IN tStr
      LOOP
     
      LOCAL ci AS LONG, StrFlag AS LONG, Letter AS BYTE PTR
     
      Letter = STRPTR(tStr)                  'pointer to original string's start
      FOR ci = 1 TO LEN(tStr)                'loop through string
         SELECT CASE @Letter
            CASE 9                           'replace eventual tab with a space
               @Letter = 32
     
            CASE 34                          'string quote, "
               IF StrFlag = 0 THEN           'if not set
                  StrFlag = 1                'we have start of a text string
               ELSE
                  StrFlag = 0                'else, if already set, we have end of a text string
               END IF
     
            CASE 39                          'uncomment character, '
               IF StrFlag = 0 THEN           'if not within quotes
                  tStr = LEFT$(tStr, ci - 1) 'remove uncommented part
                  EXIT SUB                   'and exit
               END IF
     
            CASE 95                                       'underscore, _
               IF StrFlag = 0 THEN                        'if not within quotes
                  IF ci = 1 OR PEEK(Letter - 1) = 32 THEN 'if pos 1 or previous char is space
                     tStr = LEFT$(tStr, ci)               'use up to here as result, incl. underscore
                     EXIT SUB                             'valid underscore breaks line, so exit
                  END IF
               END IF
          END SELECT
     
          INCR Letter                       'on to next char
       NEXT
     
    END SUB
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
    SUB Process ' Process Source File SF
        LOCAL a$, Dupe&
     
        REDIM Vars(1:1)  AS GLOBAL InfoStruct ' Clear all variable arrays (They should be empty anyway)
        REDIM lVars(1:1) AS GLOBAL InfoStruct
        REDIM gVars(1:1) AS GLOBAL InfoStruct
        REDIM Incl(1:1)  AS GLOBAL InfoStruct
     
        iFuncts   = 0
        iSubs     = 0
        iIncl     = 0
        ilVars    = 0
        igVars    = 0
        iIncl     = 0
        In_Type   = 0
        If_Zero   = 0
        InWhich   = ""
        InProc    = 0                  ' We're not in a Proc
        TimesThru = 1                  ' First Pass
        zWorkPtr  = VARPTR(zWork)      ' Point to zWork
        hFile     = FREEFILE           ' Get a Free Handle
     
        Seperate Files(1), FilePathStr, FileNameStr ' Extract Path and Name
        CHDIR FilePathStr
     
        IF RIGHT$(UCASE$(FileNameStr), 4) <> ".BAS" THEN
            MSGBOX "Source File MUST be a PowerBASIC file with the .BAS extension.",,"Error"
            EXIT SUB
        END IF
     
        OPEN FilePathStr + FileNameStr FOR INPUT AS hFile LEN = 16384
        IF ERR THEN EXIT SUB
     
        IF LOF(hFile) < 1 THEN
            CONTROL SET TEXT hDlg, 114,  FileNameStr + " is empty!"
            CLOSE hFile
            EXIT SUB
        ELSE
           CONTROL SET TEXT hDlg, 114,  "Pre-processing File " & FileNameStr
        END IF
     
        CurrFile = FileNameStr                  ' Set Current File
        CurrLine = 0                            ' Set Current Line
     
        DO WHILE Done = 0
     
          IF EOF(hFile) THEN                    ' reached the end of the first file
             IF iIncl THEN                      ' Find Next File to Process
                CLOSE hFile
                sWork = Incl(1).zName           ' Get File Name
                OPEN sWork FOR INPUT AS hFile LEN = 16384  ' Open it
                ARRAY DELETE Incl(1)            ' Remove it from array
                DECR iIncl                      ' Lower the count
                IF iIncl THEN                   ' Resize the Array
                   REDIM PRESERVE Incl(1:iIncl) AS GLOBAL InfoStruct
                ELSE
                   REDIM Incl(1:1) AS GLOBAL InfoStruct
                END IF
                CurrFile = sWork
                CurrLine = 0
                IF TimesThru = 1 THEN
                   CONTROL SET TEXT hDlg, 114,  "Pre-processing File " & CurrFile
                ELSE
                   CONTROL SET TEXT hDlg, 114,  "Processing File " & CurrFile
                END IF
     
             ELSE
                IF TimesThru = 1 THEN
                   TimesThru = 2 ' Now check variables in PASS 2
                   CLOSE hFile
                   OPEN FilePathStr+FileNameStr FOR INPUT AS hFile LEN = 16384
                   CurrFile = FileNameStr
                   CurrLine = 0
                   REDIM Vars(1:1)  AS GLOBAL InfoStruct ' Clear all variable arrays (They should be empty anyway)
                   iVars = 0
                   REDIM lVars(1:1) AS GLOBAL InfoStruct
                   ilVars = 0
                   REDIM gVars(1:1) AS GLOBAL InfoStruct
                   igVars = 0
                   REDIM Incl(1:1)  AS GLOBAL InfoStruct
                   iIncl = 0
                   CONTROL SET TEXT hDlg, 114,  "Processing File " & CurrFile
                ELSE
                   EXIT LOOP ' If we have gone thru twice then exit otherwise do it again.
                END IF
             END IF
          END IF
     
          IF Done THEN EXIT LOOP  ' Abort if Quit Hit
     
          LINE INPUT# hFile, LineStr                     ' Get Line from file
     
          INCR CurrLine                                        ' Increment line # count
          IF LEN(LineStr) = 0 THEN ITERATE                     ' Nothing there, get next line!
          CALL AdjustString(LineStr)                           ' remove multiple spaces, etc
          IF LEN(LineStr) = 0 THEN ITERATE                     ' Nothing there, get next line!
     
          Do
             If Right$(LineStr,1) = "_" Then                   ' Continued on Next Line Get it Now
                LineStr = Left$(LineStr, Len(LineStr) -1)      ' get rid of the underscore, _
                Line Input# hFile, sTemp                       ' read the next line
                CALL AdjustString(sTemp)                       ' remove multiple spaces, etc
                IF LEN(sTemp) = 0 THEN ITERATE                 ' Nothing there, get next line!
                LineStr = LineStr & " " & sTemp                ' else append it to LineStr
                Incr CurrLine                                  ' Increment CurrLine
             Else
                Exit Loop
             End If
          Loop
     
          IF LEFT$(LineStr, 8) = "DECLARE " THEN
             ITERATE ' Don't Care
          ELSEIF LEFT$(LineStr, 5) = "TYPE " THEN
             In_Type = 1 : ITERATE     ' Struct
          ELSEIF LEFT$(LineStr, 8) = "END TYPE" THEN
             In_Type = 0 : ITERATE ' End Struct
          ELSEIF LEFT$(LineStr, 4) = "REM " THEN
             ITERATE     ' Comment
          END IF
     
          'IF In_Type THEN   ' Still Processing a TYPE Sturcture so ignore this line
     
          ' Handle #IF 0 Comment Blocks
          ' ===================================================
          a$ = LineStr
     
          IF LEFT$(a$,1) = "$" THEN MID$(a$,1,1) = "#"
     
          IF LEFT$(a$, 5) = "#IF 0" THEN
              INCR If_Zero
              ITERATE
          ELSEIF LEFT$(a$, 5) = "#ELSE" OR LEFT$(a$, 6) = "#ENDIF" THEN
             IF If_Zero THEN DECR If_Zero
             ITERATE
          END IF
     
          IF If_Zero THEN ITERATE     ' In Block Get another line
     
          ' End #IF 0 Comment Handling
          ' ===================================================
     
          IF LEFT$(a$, 8) = "#INCLUDE" THEN ' Find other files included
             sWork = PARSE$(LineStr, ANY CHR$(34), 2) ' get filename
             IF LEN(DIR$(sWork)) THEN   ' Get Only ones we can find!
                INCR iIncl
                REDIM PRESERVE Incl(1:iIncl) AS GLOBAL InfoStruct
                Incl(iIncl).zName = sWork
             END IF
             ITERATE
          END IF
     
          IF LEFT$(LineStr, 12) = "END FUNCTION" OR _
             LEFT$(LineStr, 7) = "END SUB" THEN ' Clear local Vars()and save any unused ones to lVars()
             InProc = 0
             IF iVars THEN
                j = ilVars
                FOR i = 1 TO iVars
                    IF Vars(i).IsUsed = 0 THEN
                       INCR j
                       REDIM PRESERVE lVars(1:j) AS GLOBAL InfoStruct
                       lVars(j).zName = Vars(i).zName
                       lVars(j).IsUsed = Vars(i).IsUsed
                       lVars(j).InFile = Vars(i).InFile
                       lVars(j).LineNum = Vars(i).LineNum
                       lVars(j).InProc = Vars(i).InProc
                    END IF
                NEXT i
                ilVars = j
                iVars = 0
                REDIM Vars(1:1) AS GLOBAL InfoStruct
             END IF
     
          ELSEIF LEFT$(LineStr, 10) = "FUNCTION =" THEN
             LineStr = MID$(LineStr,11)
     
          ELSEIF LEFT$(LineStr,  9) = "FUNCTION=" THEN
             LineStr = MID$(LineStr,10)
     
          ELSEIF LEFT$(LineStr, 9) = "FUNCTION " THEN ' Entering Proceedure
             InProc = 1
             IF TimesThru = 2 THEN ITERATE ' Second Pass so do no more
     
             sWork = MID$(LineStr,9)
             sWork = TRIM$(sWork)          ' Remove Leading Space
             sTemp = EXTRACT$(sWork, ANY " (")  ' Get Only Function Name
     
             SELECT CASE sTemp
                CASE "PBMAIN", "WINMAIN", "LIBMAIN", "PBLIBMAIN", "DLLMAIN"
                   InWhich = sTemp : ITERATE
             END SELECT
     
             IF sTemp <> "=" THEN
                INCR iFuncts
                REDIM PRESERVE Functs(1:iFuncts) AS GLOBAL InfoStruct
                Functs(iFuncts).zName = sTemp
                Functs(iFuncts).InFile = CurrFile
                Functs(iFuncts).LineNum = CurrLine
     
                IF INSTR(LineStr, "EXPORT") THEN Functs(iFuncts).Exported = %TRUE
     
                InWhich = sTemp
                ITERATE
             END IF
     
          ELSEIF LEFT$(LineStr, 18) = "CALLBACK FUNCTION " THEN
             InProc = 1
             IF TimesThru = 2 THEN ITERATE
             sWork = MID$(LineStr,18)
             sWork = TRIM$(sWork)          ' Remove Leading Space
             sWork = EXTRACT$(sWork, ANY " (")  ' Get Only Sub Name
     
             INCR iFuncts
             REDIM PRESERVE Functs(1:iFuncts) AS GLOBAL InfoStruct
             Functs(iFuncts).zName = sWork
             Functs(iFuncts).InFile = CurrFile
             Functs(iFuncts).LineNum = CurrLine
     
             IF INSTR(LineStr, "EXPORT") THEN Functs(iFuncts).Exported = %TRUE
     
             InWhich = sWork
             ITERATE
     
          ELSEIF LEFT$(LineStr, 4) = "SUB " THEN
             InProc = 1
             IF TimesThru = 2 THEN ITERATE
             sWork = MID$(LineStr,4)
             sWork = TRIM$(sWork)               ' Remove white Space
             sWork = EXTRACT$(sWork, ANY " (")  ' Get Only Sub Name
     
             INCR iSubs
             REDIM PRESERVE Subs(1:iSubs) AS GLOBAL InfoStruct
             Subs(iSubs).zName = sWork
             Subs(iSubs).InFile = CurrFile
             Subs(iSubs).LineNum = CurrLine
     
             IF INSTR(LineStr, "EXPORT") THEN Subs(iSubs).Exported = %TRUE
     
             InWhich = sWork
             ITERATE
          END IF
     
          IF TimesThru = 1 THEN ITERATE               ' We only want Subs & Functs on the first pass
     
          IF LEFT$(LineStr, 4) = "DIM " THEN          ' Local Variable Processing
             FoundIt = 4
          ELSEIF LEFT$(LineStr, 7) = "STATIC " THEN   ' Static Variable Processing
             FoundIt = 7
          ELSEIF LEFT$(LineStr, 6) = "LOCAL " THEN    ' Local Variable Processing
             FoundIt = 6
          ELSE
             FoundIt = 0
          END IF
     
          IF FoundIt THEN
             IF InProc = 0 THEN ITERATE
             sWork = MID$(LineStr, FoundIt)
             sWork = EXTRACT$(sWork,"REM")
             sWork = EXTRACT$(sWork,"'")
             FOR i = 1 TO PARSECOUNT(sWork,",")
                 sTemp = PARSE$(sWork,",",i)
                 sTemp = TRIM$(sTemp)
                 sTemp = EXTRACT$(sTemp, ANY " (")  'Chop off AS LONG etc.
                 sTemp = RTRIM$(sTemp, ANY " &%@!#$?")
                 sTemp = sTemp + CHR$(0)
     
                 ' remove strings that are additional dimensions of variables
                 IF TALLY(sTemp, "(") <> TALLY(sTemp, ")") THEN ITERATE FOR
                 IF INSTR(sTemp, ":") THEN ITERATE FOR
     
                 ARRAY SCAN Vars(), FROM 1 TO LEN(TRIM$(UCASE$(sTemp))), = TRIM$(UCASE$(sTemp)), TO Dupe&
                 IF Dupe& THEN ITERATE FOR
     
                 INCR iVars
                 REDIM PRESERVE Vars(1:iVars) AS GLOBAL InfoStruct
                 Vars(iVars).zName = sTemp
                 Vars(iVars).InFile = CurrFile
                 Vars(iVars).LineNum = CurrLine
                 Vars(iVars).InProc = InWhich
             NEXT i
             ITERATE
          END IF
     
          IF LEFT$(LineStr, 7) = "GLOBAL " THEN ' Global Variable Processing
             IF InProc = 1 THEN ITERATE
             sWork = MID$(LineStr,7)
             sWork = EXTRACT$(sWork,"REM")
             sWork = EXTRACT$(sWork,"'")
             FOR i = 1 TO PARSECOUNT(sWork,",")
                 sTemp = PARSE$(sWork,",",i)
                 sTemp = TRIM$(sTemp)
                 sTemp = EXTRACT$(sTemp, ANY " (")  'Chop off AS LONG etc.
                 sTemp = RTRIM$(sTemp, ANY " &%@!#$?")
                 sTemp = sTemp + CHR$(0)
     
                 ' remove strings that are additional dimensions of variables
                 IF TALLY(sTemp, "(") <> TALLY(sTemp, ")") THEN ITERATE FOR
                 IF INSTR(sTemp, ":") THEN ITERATE FOR
     
                 ARRAY SCAN Vars(), FROM 1 TO LEN(TRIM$(UCASE$(sTemp))), = TRIM$(UCASE$(sTemp)), TO Dupe&
                 IF Dupe& THEN ITERATE FOR
     
                 INCR igVars
                 REDIM PRESERVE gVars(1:igVars) AS GLOBAL InfoStruct
                 gVars(igVars).zName = sTemp
                 gVars(igVars).InFile = CurrFile
                 gVars(igVars).LineNum = CurrLine
             NEXT i
             ITERATE
          END IF
     
          ' Ok, it's a regular line of Code... Process it
          IF InProc = 0 THEN ITERATE  ' Make Sure we are in a SUB for FUNCT
     
          sTemp = "" ' Step 1, Remove Quoted Strings
          zWork = LineStr
          DblQuote = 0
          FOR i = 0 TO LEN(zWork)-1
              IF @zWorkPtr[i] = 34 THEN ' Quote Mark
                 IF DblQuote THEN
                    DblQuote = 0
                 ELSE
                    DblQuote = 1
                 END IF
              ELSEIF DblQuote = 0 THEN  ' Outside of Quotes
                 sTemp = sTemp + CHR$(@zWorkPtr[i])
              END IF
          NEXT i
     
          i = INSTR(sTemp, CHR$(39)) ' Step 2, Remove Comments
          IF i THEN sTemp = LEFT$(sTemp,i-1)
          sTemp = EXTRACT$(sTemp, CHR$(39))
          sTemp = EXTRACT$(sTemp,"REM")
          sWork = sTemp
     
          FOR i = 1 TO PARSECOUNT(sWork, ANY ".()[],=+-*/\: ") ' Step 3, Separate all keywords and varaible/sub/func names
              sTemp = PARSE$(sWork, ANY ".()[],=+-*/\: ",i)
              sTemp = TRIM$(sTemp)
     
              IF VAL(sTemp) > 0 OR LEN(sTemp) = 0 THEN ITERATE ' Skip Numbers and zero length strings
     
              sTemp = LTRIM$(sTemp, "@")
              sTemp = EXTRACT$(sTemp, ANY " &%@!#$?")
     
              ' remove strings that are additional dimensions of variables
              IF TALLY(sTemp, "(") <> TALLY(sTemp, ")") THEN ITERATE FOR
              IF INSTR(sTemp, ":") THEN ITERATE FOR
     
              sTemp = sTemp + CHR$(0)
     
              FoundIt = 0 ' Check Local Variable's First
              IF iVars THEN
                  ARRAY SCAN Vars(), FROM 1 TO LEN(TRIM$(UCASE$(sTemp))), = TRIM$(UCASE$(sTemp)), TO FoundIt
                  IF FoundIt THEN
                      INCR Vars(FoundIt).IsUsed
                      ITERATE FOR
                  END IF
              END IF
     
              IF igVars THEN ' Next check Global Variables
                  ARRAY SCAN gVars(), FROM 1 TO LEN(TRIM$(UCASE$(sTemp))), = TRIM$(UCASE$(sTemp)), TO FoundIt
                  IF FoundIt THEN
                      INCR gVars(FoundIt).IsUsed
                      ITERATE FOR
                  END IF
              END IF
     
              IF iSubs THEN  ' Check Sub Names Next
                  ARRAY SCAN Subs(), FROM 1 TO LEN(TRIM$(UCASE$(sTemp))), = TRIM$(UCASE$(sTemp)), TO FoundIt
                  IF FoundIt THEN
                      INCR Subs(FoundIt).IsUsed
                      ITERATE FOR
                  END IF
              END IF
     
              IF iFuncts THEN ' Last Check Function Names
                  ARRAY SCAN Functs(), FROM 1 TO LEN(TRIM$(UCASE$(sTemp))), = TRIM$(UCASE$(sTemp)), TO FoundIt
                  IF FoundIt THEN
                      INCR Functs(FoundIt).IsUsed
                      ITERATE FOR
                  END IF
              END IF
     
          NEXT i
       LOOP
       CLOSE hFile
       CONTROL SET TEXT hDlg, 114, "Finished"
    END SUB

    ------------------

  • #2
    Borje,

    I have a function that will be useful in speeding up your code,
    I wrote it a while ago to parse large files that needed repeat
    sequences of spaces removed.
    Code:
      '##########################################################################
      
      FUNCTION RemoveSpaces(ByVal src as LONG, _
                            ByVal dst as LONG, _
                            ByVal ln as LONG) as LONG
      
        ' -----------------------------------------
        ' removes sequences of spaces and replaces
        ' them with a single character.
        ' -----------------------------------------
      
          #REGISTER NONE
      
          ! mov ecx, ln
          ! mov esi, src
          ! mov edi, dst
          ! add ecx, esi
        ' ---------------------------------------------
        rsSt:
          ! mov al, [esi]     ; read byte
          ! inc esi
          ! cmp al, 32        ; search byte
          ! jne rsNxt
        ' ---------------------------------------------
          ! mov al, 32        ; <<<< This is the replacement char
          ! mov [edi], al
          ! inc edi           ; write replacement
        ' ---------------------------------------------
        rsSl:
          ! mov al, [esi]     ; read next byte
          ! inc esi
          ! cmp esi, ecx
          ! je rsOut          ; exit on length match
          ! cmp al, 32
          ! je rsSl           ; loop if next byte is space
          ! mov [edi], al     ; write it if its not
          ! inc edi
          ! jmp rsSt          ; exit to start of main loop
        ' ---------------------------------------------
        rsNxt:
          ! mov [edi], al
          ! inc edi
          ! cmp esi, ecx      ; check byte count
          ! jne rsSt          ; if not matching, return to rsSt
        ' ---------------------------------------------
        rsOut:
      
          ! sub edi, dst      ; get byte write count
      
          ! mov FUNCTION, edi
      
      END FUNCTION
      
      '##########################################################################
    Regards,

    [email protected]

    ------------------


    [This message has been edited by Steve Hutchesson (edited July 22, 2001).]
    hutch at movsd dot com
    The MASM Forum

    www.masm32.com

    Comment


    • #3
      Note: For those that want to parse out DOS code, please remove the following lines from the Process() function:

      Code:
      ' Ok, it's a regular line of Code... Process it      
      IF InProc = 0 THEN ITERATE  ' Make Sure we are in a SUB or FUNCT
      Has anyone added in that Registry code from the orig thread yet? (I just don't have time).

      I'd be happy to see someone (else!) put these latest block together, and post it here.



      ------------------
      Lance
      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      Lance
      mailto:[email protected]

      Comment


      • #4
        I made a couple changes to Process() which sped things up nicely on my machine.
        I changed this code:
        Code:
         
        If Left$(LineStr, 8) = "DECLARE " Then
           Iterate ' Don't Care
        ElseIf Left$(LineStr, 5) = "TYPE " Then
           In_Type = 1 : Iterate     ' Struct
        ElseIf Left$(LineStr, 8) = "END TYPE" Then
           In_Type = 0 : Iterate ' End Struct
        ElseIf Left$(LineStr, 4) = "REM " Then
           Iterate     ' Comment
        End If
         
        ...to this code:
        'rlp - 07/22/2001
        Select Case Asc(LineStr)
          Case 68 'D
              If Mid$(LineStr, 2, 7) = "ECLARE " Then
                  Iterate ' Don't Care
              End If
          Case 84 'T
              If Mid$(LineStr, 2, 4) = "YPE " Then
                  In_Type = 1 : Iterate     ' Struct
              End If
          Case 69 'E
              If Mid$(LineStr, 2, 7) = "ND TYPE" Then
                  In_Type = 0 : Iterate ' End Struct
              End If
          Case 82 'R
              If Mid$(LineStr, 2, 3) = "EM " Then
                  In_Type = 0 : Iterate ' End Struct
              End If
        End Select
         
        That decreased my process time by about 50ms.
         
        Next, I changed  this line:
        If Left$(a$,1) = "$" Then Mid$(a$,1,1) = "#"
        ...to this line:
        If Asc(a$) = 36& Then Poke StrPtr(a$), 35
         
        That decreased my process time by another 100ms.
         
        My total time went from an average of 790ms to 630ms or about a 20% decrease in processing time.

        Comment


        • #5
          Good tips, folks!

          However, I'm personally more interested in functionality rather than saving 200mS!


          ------------------
          Lance
          PowerBASIC Support
          mailto:[email protected][email protected]</A>
          Lance
          mailto:[email protected]

          Comment


          • #6
            Functionality with speed - PB keywords..

            I did some tests with include file folder and realize more needs to be
            done, but following grabs eventual custom include files in winapi folder
            and ignores some of the "default" ones. (not sure here - interesting result
            when including win32api.inc - to see what un-used custom functions there that
            are compiled into code, but means a lot more work and not really useful.)

            BTW, Steve - as always, interesting piece of code, thanks a lot. Have not
            implemented it yet, but will try to find time to do it soon.

            Following works quite well for me, though. First a custom function
            for grabbing include file folder, then a few snippets that needs to
            be pasted into existing code:
            Code:
            '************************************************************************
            ' Get PB/DLL 6 compiler's include dir (winapi folder)
            '************************************************************************
            FUNCTION GetIncludeDir AS STRING
              LOCAL lRet   AS LONG, hKey AS LONG
              LOCAL Buffer AS ASCIIZ * %MAX_PATH, SubKey AS string
              Buffer = "Software\PowerBasic\PB/DLL\6.00\Compiler"
              SubKey = "Include"
             
              IF RegOpenKeyEx(%HKEY_CURRENT_USER, Buffer, 0, _
                              %KEY_QUERY_VALUE, hKey) = %ERROR_SUCCESS THEN
             
                 lRet = RegQueryValueEx(hKey, BYVAL STRPTR(SubKey), _
                        BYVAL 0&, BYVAL 0&, Buffer, SIZEOF(Buffer))
             
                 IF LEN(Buffer) THEN FUNCTION = TRIM$(Buffer)
                 IF hKey THEN RegCloseKey hKey
              END IF
            END FUNCTION
            
            '---------------------------------------------------
            ' in declares
            '---------------------------------------------------
            GLOBAL sIncDir AS STRING
             
            '---------------------------------------------------
            ' in PBMAIN
            '---------------------------------------------------
              sIncDir = GetIncludeDir
              IF LEN(sIncDir) AND LEN(DIR$(sIncDir)) THEN
                 IF RIGHT$(sIncDir, 1) <> "\" THEN sIncDir = sIncDir + "\"
              END IF
             
            
            '---------------------------------------------------
            'in Process, the IF/END IF -part that handles #INCLUDE
            '---------------------------------------------------
                  IF LEFT$(a$, 8) = "#INCLUDE" THEN             'Find included files (DOS 8.3 rules apply)
                     sWork = PARSE$(LineStr, ANY CHR$(34), 2)   'get filename
             
                     SELECT CASE UCASE$(sWork)                  'ignore these
                        CASE "WIN32API.INC", "COMDLG32.INC", "COMMCTRL.INC", "COMBO32.INC", _
                                "DDT.INC", "DPMI.INC", "LZEXPAND.INC", "MDI32.INC", _
                                "MMSYSTEM.INC", "RICHEDIT.INC", "WSOCK32.INC", "TOOLHLP.INC", "VBAPI.INC", _
                                "CTL3D.INC", "VER.INC", "WINAPI.INC", "WINSOCK.INC", "COMMDLG.INC"
                           ITERATE
                     END SELECT
             
                     IF INSTR(-1, sWork, ".") = 0 THEN          'if no file extension is given,
                        sWork = sWork + ".BAS"                  'compiler assumes .BAS file
                     END IF
                      
                     'if no path is given, compiler will first look in include dir, so we better start there
                     IF INSTR(sWork, "\") = 0 THEN                          'no path given
                        IF LEN(sIncDir) AND LEN(DIR$(sIncDir + sWork)) THEN 'if it's there
                           sWork = sIncDir + sWork                          'use it
                        END IF
                     END IF
             
                     IF LEN(DIR$(sWork)) THEN   'if we can find it..
                        INCR iIncl
                        REDIM PRESERVE Incl(1:iIncl) AS GLOBAL InfoStruct
                        Incl(iIncl).zName = sWork
                     END IF
                     ITERATE
                  END IF

            ------------------

            Comment


            • #7
              What a great job you guys are doing... but it's not helping my application.

              I have defined all of my equates, globals, and declares in an include file,
              which I call from my main program with an #INCLUDE statement. Checkit scanned
              my include file and marked all of my globals as unused, even though they are
              used in the main file.

              Also, subs and functions which used foward calls in the main file, were marked
              as unused. The declares in my include file should allow forward calls.

              I'm trying to decipher the developed code, but you guys are way ahead of me.

              ------------------

              Comment


              • #8
                I see the same thing occuring with my "variable" include file, Charles. Perhaps all include files need to be imported into one temp file for processing while preserving the include file boundaries for reporting purposes?

                Comment


                • #9
                  Yes, Ron

                  I inserted my include file directly into my main file to make one large
                  file, and that did solve the unused globals problem, except for one
                  disturbing instance where it reported a global variable as named 'H',
                  when in reality, it is named 'HREMINDFORM'. I have no idea what happened
                  there.

                  What I thought was a forward referencing problem is evidently something else.
                  A few subs and functions are reported as unused, but in reality are used.

                  And I noticed yet another problem. A globally declared array is dimensioned
                  in an initializing subroutine, but isn't used there. However, it is used
                  frequently elsewhere, and it was reported as an unused local variable.




                  ------------------

                  Comment


                  • #10
                    Borje,
                    Good work!

                    Whydya put the INCLUDE function call in PBMain? just curious?

                    I put it in Process right here ..

                    Code:
                        IF LOF(hFile) < 1 THEN 
                            CONTROL SET TEXT hDlg, 114,  FileNameStr+" is empty"
                            CLOSE hFile
                            EXIT SUB
                        END IF
                    
                    
                        IncPathStr = GetIncludeDir ' Find PBDLL 6.0 Include Folder
                        IF LEN(IncPathStr) AND LEN(DIR$(IncPathStr)) THEN IF RIGHT$(IncPathStr, 1) <> "\" THEN IncPathStr = IncPathStr + "\"
                    
                    
                        CurrFile = FileNameStr                   ' Set Current File
                        CurrLine = 0                             ' Set Current Line
                    I agree with Lance. Im not at all concerned with speed, I just want it to
                    do everything I want.
                    Right now its easy to read for greenhorns like me

                    Steve,
                    For those of us that are assembler challenged ...

                    FUNCTION RemoveSpaces(ByVal src as LONG, _
                    ByVal dst as LONG, _
                    ByVal ln as LONG) as LONG

                    src = the string to process
                    dst = the destination string for the processed source string
                    ln = ???
                    FUNCTION return = number of bytes in the destination string?

                    Are all these strings declared as regular strings?

                    Also PBmain and the callback can be reduced ...
                    And i did some work on the formatting of the report so its
                    consistant

                    Just replace from the beggining of the SUB Save Results to the end with:

                    Code:
                    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
                    FUNCTION Pad ( BYVAL PadStr AS STRING ) AS STRING
                        LOCAL PadLen AS LONG
                        PadLen   = 40 ' adjust to taste
                        FUNCTION = "  " + LEFT$(PadStr + SPACE$(PadLen), PadLen)
                    END FUNCTION
                    
                    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
                    SUB SaveResults ' Now Prepare a Report of what we've found out!
                       LOCAL i AS LONG, sWork AS STRING, hFile AS LONG
                    
                       DestFile = PARSE$(FileNameStr, ANY ".", 1)+"LOG.txt"
                       OPEN FilePathStr+DestFile FOR OUTPUT AS hFile
                    
                       sWork = STRING$(80,"*")
                       PRINT# hFile, sWork
                       PRINT# hFile, "Report for: " + FileNameStr
                       PRINT# hFile, "  Compiled: " + DATE$
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                       PRINT# hFile, "++++[ UN-USED FUNCTIONS ] +++++"
                       PRINT# hFile, ""
                       IF iFuncts THEN
                          FOR i = 1 TO iFuncts
                              IF Functs(i).IsUsed = 0 THEN
                                  IF ISFALSE Functs(i).Exported THEN
                                      PRINT# hFile, Pad(Functs(i).zName)+"["+Functs(i).InFile+":"+FORMAT$(Functs(i).LineNum)+"]"
                                  END IF
                              END IF
                          NEXT i
                       END IF
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                    
                       PRINT# hFile, "++++[ UN-USED SUBS ] +++++"
                       PRINT# hFile, ""
                       IF iSubs THEN
                          FOR i = 1 TO iSubs
                              IF Subs(i).IsUsed = 0 THEN
                                  IF ISFALSE Subs(i).Exported THEN
                                      PRINT# hFile, Pad(Subs(i).zName)+"["+Subs(i).InFile+":"+FORMAT$(Subs(i).LineNum)+"]"
                                  END IF
                              END IF
                          NEXT i
                       END IF
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                    
                       PRINT# hFile, "++++[ UN-USED GLOBAL VARIABLES ] +++++"
                       PRINT# hFile, ""
                       IF igVars THEN
                          FOR i = 1 TO igVars
                              IF gVars(i).IsUsed = 0 THEN PRINT# hFile, Pad(gVars(i).zName)+"["+gVars(i).InFile+":"+FORMAT$(gVars(i).LineNum)+"]"
                          NEXT i
                       END IF
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                    
                       PRINT# hFile, "++++[ UN-USED LOCAL VARIABLES ] +++++"
                       PRINT# hFile, ""
                       IF ilVars THEN
                          FOR i = 1 TO ilVars
                              IF lVars(i).IsUsed = 0 THEN PRINT# hFile, Pad(lVars(i).zName)+"["+lVars(i).InFile+":"+FORMAT$(lVars(i).LineNum)+"]"
                          NEXT i
                       END IF
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                    
                       PRINT# hFile, "++++[ INCLUDES REFERENCE COUNT ] +++++"
                       PRINT# hFile, ""
                       IF iIncl > 0 THEN
                          FOR i = 1 TO iIncl
                              IF ISTRUE Incl(i).Exported THEN
                                PRINT# hFile, Pad(Incl(i).zName + " <export> ") + TRIM$(STR$(Incl(i).IsUsed))
                              ELSE
                                PRINT# hFile, Pad(Incl(i).zName) + TRIM$(STR$(Incl(i).IsUsed))
                              END IF
                          NEXT I
                       ELSE
                         PRINT# hFile, "  <None>"
                       END IF
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                    
                       PRINT# hFile, "++++[ FUNCTIONS REFERENCE COUNT ] +++++"
                       PRINT# hFile, ""
                       IF iFuncts > 0 THEN
                          FOR i = 1 TO iFuncts
                              IF ISTRUE Functs(i).Exported THEN
                                PRINT# hFile, Pad(Functs(i).zName + " <export> ") + TRIM$(STR$(Functs(i).IsUsed))
                              ELSE
                                PRINT# hFile, Pad(Functs(i).zName) + TRIM$(STR$(Functs(i).IsUsed))
                              END IF
                          NEXT I
                       ELSE
                         PRINT# hFile, "  <None>"
                       END IF
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                    
                       IF iSubs > 0 THEN
                       PRINT# hFile, "++++[ SUBS REFERENCE COUNT ] +++++"
                       PRINT# hFile, ""
                            FOR i = 1 TO iSubs    
                              IF ISTRUE Subs(i).Exported THEN
                                PRINT# hFile, Pad(Subs(i).zName + " <export> ") + TRIM$(STR$(Subs(i).IsUsed))
                              ELSE
                                PRINT# hFile, Pad(Subs(i).zName) + TRIM$(STR$(Subs(i).IsUsed))
                              END IF
                          NEXT I
                       ELSE
                         PRINT# hFile, "  <None>"
                       END IF
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                    
                       IF igVars > 0 THEN
                       PRINT# hFile, "++++[ GLOBAL VARIABLES REFERENCE COUNT ] +++++"
                       PRINT# hFile, ""
                          FOR i = 1 TO igVars
                              IF ISTRUE gVars(i).Exported THEN
                                PRINT# hFile, Pad(gVars(i).zName + " <export> ") + TRIM$(STR$(gVars(i).IsUsed))
                              ELSE
                                PRINT# hFile, Pad(gVars(i).zName) + TRIM$(STR$(gVars(i).IsUsed))
                              END IF
                          NEXT I
                       ELSE
                         PRINT# hFile, "  <None>"
                       END IF
                       PRINT# hFile, ""
                       PRINT# hFile, sWork
                    
                       CLOSE hFile
                    
                       SHELLEXECUTE 0, "open", FilePathStr+DestFile, BYVAL 0, BYVAL 0, %SW_SHOWNORMAL ' launch log file
                    END SUB  
                    
                    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
                    CALLBACK FUNCTION MainCB() AS LONG
                        SELECT CASE CBMSG
                            CASE %WM_INITDIALOG 
                                DIM Files(1), Folders(1) ' Starting condition 
                                IF LEN(COMMAND$) THEN
                                    CALL GetCommandFiles(COMMAND$, Files(), Folders()) ' Retrieve the contents of the Command String    
                                    LOCAL sTimer AS LONG 
                                    sTimer = SETTIMER(CBHNDL, 1, 200, %NULL) ' wait for window to draw
                                ELSE
                                    CONTROL SET TEXT hDlg, 114, "DRAG and DROP here"
                                END IF
                    
                            CASE %WM_TIMER
                                KILLTIMER  CBHNDL, 1
                                CALL Process 
                                CALL SaveResults
                                DIALOG END hDlg '  QUIT 
                    
                            CASE %WM_DROPFILES
                                REDIM Files(0) ' Reset Array
                                CALL GetDroppedFiles(CBWPARAM, Files(), Folders()) ' Retrieve the Dropped filenames                    
                                CALL Process 
                                CALL SaveResults
                                DIALOG END hDlg '  QUIT 
                    
                        END SELECT
                    END FUNCTION
                    
                    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
                    FUNCTION PBMAIN
                            Wdth = 140 : Hght = 48 
                            DIALOG NEW            hDlg,       "  Un-Used Vars/Funcs/Subs",   330,      60, Wdth, Hght, %WS_SYSMENU OR %WS_CAPTION TO hDlg
                            SETWINDOWPOS          hDlg,                     %HWND_TOPMOST,     0,       0,    0,    0, %SWP_NOMOVE OR %SWP_NOSIZE   
                            CONTROL ADD LABEL,    hDlg, 114,                           "",     0, Hght-30, Wdth,   12, %SS_CENTER	
                            DRAGACCEPTFILES       hDlg, %True 
                            DIALOG SHOW MODAL     hDlg  CALL MainCB
                    END FUNCTION
                    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'

                    ------------------
                    Kind Regards
                    Mike

                    [This message has been edited by Mike Trader (edited July 22, 2001).]

                    Comment


                    • #11
                      Yes, I have just tested and seen these problems too. It works quite
                      well on "normal" projects, but as soon as one has done something more
                      advanced, it fails. When I look the code, I realize many things needs
                      to be done in another way. Need to do recursive parsing of all files,
                      to get all nested includes before actual parsing takes place.

                      Theoretically speaking, not that hard. Many hours of work in reality,
                      though - without pay. Think I'll go fishing instead..

                      (actually started re-writing, just for fun. Have the recursive parsing
                      for all files and the extraction of all subs/functions ready. The rest
                      won't be ready for a while yet though - right now other, more important
                      things needs my attention..

                      ------------------
                      Mike, reason for PBMAIN - only need to look for the include path once,
                      so I do it at start. But of course, also possible to do it in other
                      place and use local storage. But then same thing will be done, with
                      same result, each time a project is processed..

                      Steve's asm code uses STRPTR and ln is LEN of source. Haven't tested
                      it yet, but should be possible to call it like (I think):
                      RemoveSpaces STRPTR(LineStr), STRPTR(LineStr), LEN(LineStr)


                      [This message has been edited by Borje Hagsten (edited July 22, 2001).]

                      Comment


                      • #12
                        Hey guys, looks like you've all been busy adding on to the code. Has anyone
                        put it all together yet into a single file? Also, to keep the checking alive
                        in the Includes wouldn't be all that hard. The varaibles all get
                        reset when the next file is loaded, so all you would have to do is keep the info
                        from the last batch and treat it all as one big file. Should be pretty
                        easy to get it to do that since it processes line-by-line anyway. If someone
                        has pasted all of these parts together into a single file could they post
                        it or email it to me? I was thinking about adding an INI file where the user
                        could define directories to search for INCLUDE files. Reading it from the
                        registry entries from PB would be okay, but then you would have to determine
                        what version and what compiler the user is running. Let me know what
                        you all think...


                        Scott



                        ------------------
                        Scott Slater
                        Summit Computer Networks, Inc.
                        www.summitcn.com

                        Comment


                        • #13
                          Source of 1 bug: Change "REM" to "REM ", 2 or 3 occurances.

                          ------------------

                          Comment


                          • #14
                            Another bug: 'fcnName' reported as unused function when in reality,
                            it was used in 'CODEPTR(fcnName)'

                            ------------------

                            Comment


                            • #15
                              My latest version should fix many of the problems with mis-identifying variable names... when I get back to my DEV PC, I'll post my latest code.

                              ------------------
                              Lance
                              PowerBASIC Support
                              mailto:[email protected][email protected]</A>
                              Lance
                              mailto:[email protected]

                              Comment


                              • #16
                                Steve, I've not had time to investigate it, but your ASM (RemoveSpaces) code gives strange results in this app! Does it remove all spaces, or just fix it when there are two or more spaces?

                                To check it out, please see my following posting and change the %STEVE equate to use your code instead of the REPLACE-based code.


                                ------------------
                                Lance
                                PowerBASIC Support
                                mailto:[email protected][email protected]</A>
                                Lance
                                mailto:[email protected]

                                Comment


                                • #17
                                  [quote]Originally posted by Ron Pierce:
                                  I changed this code:
                                  Code:
                                   
                                     ElseIf Left$(LineStr, 4) = "REM " Then
                                       Iterate     ' Comment
                                     End If
                                   
                                  ...to this code:
                                   
                                    Case 82 'R
                                        If Mid$(LineStr, 2, 3) = "EM " Then
                                            In_Type = 0 : Iterate ' End Struct
                                        End If
                                  </font>
                                  Ummm, you may want to reconsider that particular translation, Ron.

                                  ------------------
                                  Lance
                                  PowerBASIC Support
                                  mailto:[email protected][email protected]</A>
                                  Lance
                                  mailto:[email protected]

                                  Comment


                                  • #18
                                    The problem with this code is that it fails to find all occurrences
                                    if globals have been placed in include files. First all files must be
                                    gathered via recursive search for includes. The all gathered files
                                    must be searched for global declarations, plus subs and functions.
                                    Gathering and scanning for locals can be done at this point. Then
                                    it's time to start looking for redundant globals in each file.

                                    Like I said in the beginning - building a decent parser always ends
                                    up with an extreme amount of work. Not easy to create a program that
                                    can read and understand text. I'm now in the process of rewriting all
                                    code. Can only do a little per day, so it'll be a long-term project..


                                    ------------------

                                    Comment


                                    • #19
                                      I fixed the DIM(40,1) as well as a few other errors that occured when
                                      vars were DIM'ed with multiple dimmensions. Replace the original DIM
                                      handler with this one.


                                      Code:
                                            ' Local Variable Processing
                                            If Left$(sWork, 4) = "DIM " Then
                                               If InProc = 0 Then Iterate
                                               sWork = Mid$(sWork,4)
                                               sWork = Extract$(sWork,"REM")
                                               sWork = Extract$(sWork,"'")
                                               ' Strip out all () and everything in them.
                                               zWork = sWork
                                               sTemp = ""
                                               InPars = 0
                                               For i = 0 To Len(zWork)-1
                                                   If @pWork[i] = 40 Then
                                                      Incr InPars  ' "(" found, icrease depth by 1
                                                   ElseIf @pWork[i] = 41 Then
                                                      If InPars Then
                                                         Decr InPars  ' ")" found, decrease depth by 1
                                                      End If
                                                   ElseIf InPars = 0 Then  ' Not Inside of () so
                                                      sTemp = sTemp & Chr$(@pWork[i]) ' Save the Char
                                                   End If
                                               Next i
                                               sWork = sTemp
                                               For i = 1 To ParseCount(sWork,",")
                                                   sTemp = Parse$(sWork,",",i)
                                                   sTemp = Trim$(sTemp)
                                                   sTemp = Extract$(sTemp, Any " ")  'Chop off AS LONG etc.
                                                   CurrPos = Instr(sTemp, Any "&%@!#$?")
                                                   If CurrPos > 1 Then
                                                      sTemp = Left$(sTemp, CurrPos-1)
                                                   End If
                                                   Incr iVars
                                                   ReDim Preserve Vars(1:iVars) As InfoStruct
                                                   Vars(iVars).zName = sTemp
                                                   Vars(iVars).InFile = CurrFile
                                                   Vars(iVars).LineNum = CurrLine
                                                   Vars(iVars).InProc = InWhich
                                               Next i
                                               Iterate
                                            End If
                                      Scott


                                      ------------------
                                      Scott Slater
                                      Summit Computer Networks, Inc.
                                      www.summitcn.com

                                      Comment


                                      • #20
                                        Originally posted by Borje Hagsten:
                                        sIncDir = GetIncludeDir
                                        IF LEN(sIncDir) AND LEN(DIR$(sIncDir)) THEN
                                        IF RIGHT$(sIncDir, 1) <> "\" THEN sIncDir = sIncDir + "\"
                                        END IF
                                        Borje, the DIR statement above needs the ",16" attribute code parameter added.

                                        Yes, there are a couple of limitations with the current code. Likewise, I can only spent a little time per day.

                                        I've added a few new features and fixed still more problems, but I've not got to the point where I can post "working" code.

                                        Stay tuned...!



                                        ------------------
                                        Lance
                                        PowerBASIC Support
                                        mailto:[email protected][email protected]</A>
                                        Lance
                                        mailto:[email protected]

                                        Comment

                                        Working...
                                        X