EnableExplicit generator?

Everything else that doesn't fall into one of the other PB categories.
BarryG
Addict
Addict
Posts: 2272
Joined: Thu Apr 18, 2019 8:17 am

EnableExplicit generator?

Post by BarryG »

So I've never used EnableExplicit before, but I was thinking today: my source code has now grown far too large to suddenly add it, as I'd have to manually go through 1.6 MB of source code (55880 lines) to add definitions to every single variable that my app uses.

This is obviously way too hard and too much manual work for such a large source, so has anyone ever coded an EnableExplicit generator to do this automatically to a given source file?
User avatar
STARGÅTE
Addict
Addict
Posts: 1761
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: EnableExplicit generator?

Post by STARGÅTE »

What should this generator do?
What is the problem, to add EnableExplicit at the beginning of the file?

When you mean a generator, which automatically define all undefined variables, then the sense of using EnableExplicit is obsolete. EnableExplicit can be used to find spelling bugs like:

Code: Select all

Procedure MyProcedure(ParameterWithASpellingBug.i)
	ProcedureReturn ParameterWitnASpellingBug * 20
EndProcedure

Debug MyProcedure(10)
With such a generator you end up with this, without showing you the spelling issue:

Code: Select all

EnableExplicit

Procedure MyProcedure(ParameterWithASpellingBug.i)
	Protected ParameterWitnASpellingBug.i
	ProcedureReturn ParameterWitnASpellingBug * 20
EndProcedure

Debug MyProcedure(10)
BarryG wrote: Sun Jul 31, 2022 12:56 am my source code has now grown far too large to suddenly add it, as I'd have to manually go through 1.6 MB of source code (55880 lines) to add definitions to every single variable that my app uses.
If you haven't used explicite definitions until now, why do you care about EnableExplicit now?
PB 5.73 ― Win 10, 20H2 ― Ryzen 9 3900X ― Radeon RX 5600 XT ITX ― Vivaldi 5.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
BarryG
Addict
Addict
Posts: 2272
Joined: Thu Apr 18, 2019 8:17 am

Re: EnableExplicit generator?

Post by BarryG »

Yes, I meant a generator, which automatically define all undefined variables. And no, it won't make EnableExplicit obsolete because all my variables are valid at the the time the generator would be used, so there's no situation of typos becoming valid generated names.

The idea is to make all variables explicit at the time the generator is done, so that future variable names can be defensively coded thereafter. The generator isn't something that you'd run every day on the same source, but only once, to clean it up.
User avatar
STARGÅTE
Addict
Addict
Posts: 1761
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: EnableExplicit generator?

Post by STARGÅTE »

BarryG wrote: Sun Jul 31, 2022 10:13 am And no, it won't make EnableExplicit obsolete because all my variables are valid at the the time the generator would be used, so there's no situation of typos becoming valid generated names.
Why you are sure that all your variable names are "valid" if you havn't used EnableExplicit at the moment?
Wrong definitions or spelling issue do not always and up in syntax errors or calculation issues.

Whatever, my answers/question are slightly off-topic.
So, I havn't such a generator. There are some generators for creating procedure declarations at one shot, but I don't know if they also create Protected or Define keywords.
PB 5.73 ― Win 10, 20H2 ― Ryzen 9 3900X ― Radeon RX 5600 XT ITX ― Vivaldi 5.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
BarryG
Addict
Addict
Posts: 2272
Joined: Thu Apr 18, 2019 8:17 am

Re: EnableExplicit generator?

Post by BarryG »

STARGÅTE wrote: Sun Jul 31, 2022 11:16 amWhy you are sure that all your variable names are "valid" if you havn't used EnableExplicit at the moment?
Image
User avatar
Oso
User
User
Posts: 66
Joined: Wed Jul 20, 2022 10:09 am

Re: EnableExplicit generator?

Post by Oso »

BarryG wrote: Sun Jul 31, 2022 10:13 am Yes, I meant a generator, which automatically define all undefined variables. And no, it won't make EnableExplicit obsolete because all my variables are valid at the the time the generator would be used, so there's no situation of typos becoming valid generated names.
I often write code to modify my source code, in cases where I need to make the same change to multiple programmes, but that's not in PB, it's in PICK DataBasic (which I've been using practically my entire life ;-) ), but I fully understand your motivation in wanting to do this. It can save an enormous amount of time. There's no easy way, in my view, because your automatic routine is going to need to identify variable names within all the various lines of code and make a list of them. It's then going to need to make a determination regarding the variable type and then generate some form of output for you, either in the form of a list of all the variable names that it has found, which presumably aren't already defined, or alternatively add them automatically into the top of the code itself.

If it's any help though, I noticed (as a very new user of PureBasic) that if you add EnableExplicit to a routine in which it wasn't already set, that the compiler will throw an error anyway, until you define each variable. So it's not as bad as having a routine that compiles successfully but fails under certain conditions when it is executed.

I would say that if your code is mature and is well written, despite not having EnableExplicit, there isn't a strong argument for changing what already works well. I guess it's more of a personal desire to improve it, but it doesn't seem worthwhile. I suppose one way of doing it, is that whenever you work on an existing routine, improve it at that point and work through the system in that way. Just my thoughts anyway.
#NULL
Addict
Addict
Posts: 1424
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: EnableExplicit generator?

Post by #NULL »

In case you don't know: There is DisableExplicit as well. So you can convert only part of your code at times. Or you start at the bottom of your files, moving EnableExplicit up in chunks to convert new parts.
User avatar
Oso
User
User
Posts: 66
Joined: Wed Jul 20, 2022 10:09 am

Re: EnableExplicit generator?

Post by Oso »

I have written a source code analyser which may help @BarryG 's requirement, the purpose being to look through the code and pick out all the variable names used. It builds these into a sorted list, then outputs them at the end. It would be easy to modify this to write "Define" statements for each variable. This is the first programme I've written with PureBasic and consequently my knowledge of the language is very limited. It's likely that it doesn't cover all relevant statements that assign values to variables. Nevertheless, it looks for the following:

Code: Select all

variable = 'x'
For variable = 'x' to 'y'
It properly ignores:

Code: Select all

Define variable = 'x'
#constant = 'x'
If variable = 'x'
The code is fully commented, which should make it easier for others to add missing PureBasic statements that might be responsible for assigning values to variables, that I'm unfamiliar with.

Code: Select all

OpenConsole()
EnableExplicit

#ENABLE_EXPLICIT = "EnableExplicit"

Define filename.s           ; File path of source code file to process
Define text.s               ; Input text line read from file
Define recno                ; Input record counter to show serial no. of source line
Define length               ; Input line length, before removing multiple spaces
Define newstring.s          ; Input line cleaned up, by remocing multiple unwanted spaces
Define varname.s            ; Extracted variable name from the source line
Define stpos                ; Input line character count
Define lastchr.s            ; Previous character processed from input line, to detected multiple spaces
Define chr.s                ; Input character read one-by-one
Define expfound             ; Flag to indicate "EnableExplicit" was found in the source item
Define pos                  ; Character position when searching for specific symbols in input line
Define duped                ; Flag to indicate that variable is already in the output list
Define outcount             ; Output variable counter

NewList varlist.s()         ; List for building each variable name found
NewList vardupe.s()         ; List for de-duping the varlist.s list

Print ("Please enter the file path of the source file you want to process (or press Enter for default) : ")
filename.s = Input()
If filename.s = ""
  filename.s="C:\test\source_util.pb"
EndIf

If ReadFile(1,filename.s)
  While Not(Eof(1))
    text.s = ReadString(1)                                  ; Read the input line
    
    ; \\\
    ; \\\  Remove trailing semi-colons from input lines, retaining only the code which precedes it
    ; \\\
    pos=FindString(text.s, ";")                             ; Locate semi-colon (marker for comments, which can trail on end of code)
    If pos;                                                 ; Found a semi-colon
      text.s=Left(text.s,pos-1)                             ; Retain all text up to the semi-colon, discard everything from semi-colon onwards
    EndIf
    
    ; \\\
    ; \\\  Determine line length and reset working variables
    ; \\\
    length=Len(text.s)    
    newstring.s = ""
    lastchr.s=" "
    
    ; \\\
    ; \\\  Process the input line and look for repeating spaces, removing the unwanted spaces to maintain consistency.  Write the cleaned-up line
    ; \\\  to the new variable newstring.s
    ; \\\
    For stpos=1 To length                                   ; Go through each character in the input line
      chr.s=Mid(text.s,stpos,1)                             ; Extract each character in turn
      If (chr.s <> " " Or lastchr.s <> " ")                 ; If character is not a space, or the previous character was not a space, include it
        newstring.s=newstring.s+chr.s                       ; Include the character in the 'newstring.s' output
      EndIf
      lastchr.s=chr.s                                       ; Save this character for the next iteration in the loop
    Next stpos

    recno=recno+1                                           ; Increment the record counter, if only to provide the user with a running count of lines
    Debug Str(recno)+" : "+newstring.s                      ; Show the user the newly amended line (i.e. the line with unwanted spacing removed)
    
    If CountString(newstring.s, #ENABLE_EXPLICIT)           ; If we encounter EnableExplicit, set to flag to indicate as such
      expfound=#True                                        ; and the user can therefore choose to ignore those source files which already contain it
    EndIf
      
    If Left(newstring.s,3) <> "If " And Left(newstring.s,1) <> "#"      ; Ignore 'If' statements and constants, since we're not interested in those vars.
                                                                        ; but other commands can be added to this list, as necessary
      
      If Left(newstring.s,4) = "For "                                   ; Special case for 'For' statement, since the variable follows the statement
        newstring.s=Mid(newstring.s,5)                                  ; In this case, remove 'For' since we don't want this to form part of var. name
      EndIf
      
      If Left(newstring.s,7) <> "Define "                               ; Special case for 'Define' with equate of an initialised value, since these
                                                                        ; presumably fulfil our requirement of being defined, hence we
                                                                        ; don't need to know about these
        
        pos=FindString(newstring.s, "=")                    ; Look for '=' assignment in the line, so we can determine the variable name preceding it
        If pos>1                                            ; If we find an '=' symbol, process the line
         If Mid(newstring.s,pos-1,1)=" "                    ; If the previous character before the '=' symbol is a space, adjust our pointer to ignore it
           pos=pos-1                                        ; because we don't want the space in the variable name
         EndIf

         varname.s=Left(newstring.s,pos-1)                  ; Extract the variable name preceding the '=' symbol
         Debug " "
         Debug varname.s+" IS A VARIABLE"                   ; Show the user the extracted variable name, so this can be checked in the source if req'd.
         Debug " "
         
         AddElement(varlist.s())                            ; Create a new list entry in varlist.s()
         varlist.s() = varname.s                            ; Store the extracted variable name in list varlist.s()
        EndIf
      EndIf
        
    EndIf
  Wend
Else
  Debug "Cannot open the file specified"
  End
EndIf

Debug " "
If expfound
   Debug "This source code file already contains "+ #ENABLE_EXPLICIT
Else
   Debug "This source code file DOES NOT contain "+ #ENABLE_EXPLICIT
EndIf
 
; \\\
; \\\  Now we have our list of variable names found in varlist.s(), go through each of them and de-dupe them against a new list vardupe.s(), so we
; \\\  end up with the list of unique variable names
; \\\ 
ResetList(varlist.s())                                      ; Reset the varlist.s() point to the beginning of the list
While NextElement(varlist.s())                              ; Go through each list element
  duped=#False
  ResetList(vardupe.s())                                    ; Reset the de-duped output list vardupe.s() so we can check every entry in there
  While NextElement(vardupe.s())                            ; Go through the output de-duped list
    If vardupe.s() = varlist.s()                            ; Check if the input list element varlist.s() already exists in the de-duped list
      duped=#True                                           ; It's already there, so we don't need to store it again
    EndIf
  Wend
  If Not(duped)                                             ; Is it a duplication?
    AddElement(vardupe.s())                                 ; Not a duplication, so we create a new element in vardupe.s()
    vardupe.s() = varlist.s()                               ; Store the variable in the de-duped list vardupe.s()
  EndIf    
Wend

; \\\
; \\\  Sort the de-duped output list in alphabetical sequence
; \\\ 
SortList(vardupe(),#PB_Sort_Ascending)
  
Debug "These are the variables found : "

; \\\
; \\\  Show the complete list to the user
; \\\ 
ResetList(vardupe.s())
While NextElement(vardupe.s())
  outcount=outcount+1
  Debug Str(outcount)+" : "+vardupe.s()
Wend
Last edited by Oso on Sun Jul 31, 2022 7:44 pm, edited 1 time in total.
User avatar
Oso
User
User
Posts: 66
Joined: Wed Jul 20, 2022 10:09 am

Re: EnableExplicit generator?

Post by Oso »

Incidentally, a good 'first test' of this is to run the routine on its own source code file. Without wishing to include the full result, the tail-end of the output will be as follows...

Code: Select all

135 : 
136 : 
137 : ResetList(vardupe.s())
138 : While NextElement(vardupe.s())
139 : outcount=outcount+1
 
outcount IS A VARIABLE
 
140 : Debug Str(outcount)+" : "+vardupe.s()
141 : Wend
 
This source code file already contains EnableExplicit
These are the variables found : 
1 : chr.s
2 : duped
3 : expfound
4 : filename.s
5 : lastchr.s
6 : length
7 : newstring.s
8 : outcount
9 : pos
10 : recno
11 : stpos
12 : text.s
13 : vardupe.s()
14 : varlist.s()
15 : varname.s
BarryG
Addict
Addict
Posts: 2272
Joined: Thu Apr 18, 2019 8:17 am

Re: EnableExplicit generator?

Post by BarryG »

Thanks Oso! That's the type of practical help I was looking for. I'll try it soon.
User avatar
Oso
User
User
Posts: 66
Joined: Wed Jul 20, 2022 10:09 am

Re: EnableExplicit generator?

Post by Oso »

BarryG wrote: Sun Jul 31, 2022 9:57 pm Thanks Oso! That's the type of practical help I was looking for. I'll try it soon.
We might need to refine it further, because it's designed for the code as I would write it. PB is still a bit of an unknown science to me!
TassyJim
Enthusiast
Enthusiast
Posts: 122
Joined: Sun Jun 16, 2013 6:27 am
Location: Tasmania (Australia)

Re: EnableExplicit generator?

Post by TassyJim »

I wrote a variable report for another much simpler Basic as part of an IDE. It was also written in something other than PureBasic.

It would not transfer easily to testing PureBasic but one of my early "gotchas" was handling quoted text in the code.

Code: Select all

 pos=FindString(text.s, ";")                             ; Locate semi-colon (marker for comments, which can trail on end of code)
    If pos;                                                 ; Found a semi-colon
      text.s=Left(text.s,pos-1)                             ; Retain all text up to the semi-colon, discard everything from semi-colon onwards
    EndIf
The above section of Oso's code will stop at any ; that is in quotes. Any strings in quotes should be stepped over when scanning the line.

My flow was
Scan the file and make a list of all procedures.
Scan again and find each 'word' and test to see if it a procedure form the earlier list or a language keyword.
If it's not in either list, assume that it is a variable.
Check to see if it has been found already.

You will have to handle within procedures as individual entities.
You will also have to include any Includes in the scan for procedures

I couldn't live without enableexplicit.
My left hand doesn't do what I tell it to do any longer, so lots of spelling errors.

Jim
User avatar
Oso
User
User
Posts: 66
Joined: Wed Jul 20, 2022 10:09 am

Re: EnableExplicit generator?

Post by Oso »

TassyJim wrote: Mon Aug 01, 2022 3:47 am

Code: Select all

 pos=FindString(text.s, ";")                             ; Locate semi-colon (marker for comments, which can trail on end of code)
    If pos;                                                 ; Found a semi-colon
      text.s=Left(text.s,pos-1)                             ; Retain all text up to the semi-colon, discard everything from semi-colon onwards
    EndIf
The above section of Oso's code will stop at any ; that is in quotes. Any strings in quotes should be stepped over when scanning the line.
These things are easy to do, but I think there's limited value in attempting to take this to the n'th degree, since trying to do so makes it just as sophisticated as the compiler's own parser. In fact many compilers provide the option to do this anyway - it's usually known as the 'symbol table'

I have added those you mention anyway and the complete code is below...

1. Contents of double-quote pairs are removed, so reserved words or special characters within quotes are ignored
2. Procedure names are included within the table of variable names, thus when the variable names are sorted, they appear in order of parent procedure and the individual procedure can be identified

Code: Select all

OpenConsole()
EnableExplicit

#ENABLE_EXPLICIT = "EnableExplicit"
#CHR34 = Chr(34)

Define filename.s           ; File path of source code file to process
Define text.s               ; Input text line read from file
Define recno                ; Input record counter to show serial no. of source line
Define length               ; Input line length, before removing multiple spaces
Define newstring.s          ; Input line cleaned up, by remocing multiple unwanted spaces
Define varname.s            ; Extracted variable name from the source line
Define stpos                ; Input line character count
Define lastchr.s            ; Previous character processed from input line, to detected multiple spaces
Define chr.s                ; Input character read one-by-one
Define expfound             ; Flag to indicate "EnableExplicit" was found in the source item
Define pos                  ; Character position when searching for specific symbols in input line
Define duped                ; Flag to indicate that variable is already in the output list
Define outcount             ; Output variable counter
Define lastproc.s           ; Last procedure name
Define quotemark            ; Quote mark toggle flag

NewList varlist.s()         ; List for building each variable name found
NewList vardupe.s()         ; List for de-duping the varlist.s list

Print ("Please enter the file path of the source file you want to process (or press Enter for default) : ")
filename.s = Input()
If filename.s = ""
  filename.s="C:\test\source_util.pb"
EndIf

If ReadFile(1,filename.s)
  While Not(Eof(1))
    text.s = ReadString(1)                                  ; Read the input line
    
    ; \\\
    ; \\\  Determine line length and reset working variables
    ; \\\
    length=Len(text.s)    
    newstring.s = ""
    lastchr.s=" "
    
    ; \\\
    ; \\\  Process the input line and look for repeating spaces, removing the unwanted spaces to maintain consistency.  Write the cleaned-up line
    ; \\\  to the new variable newstring.s
    ; \\\
    For stpos=1 To length                                   ; Go through each character in the input line
      chr.s=Mid(text.s,stpos,1)                             ; Extract each character in turn
      If (chr.s <> " " Or lastchr.s <> " ")                 ; If character is not a space, or the previous character was not a space, include it
        newstring.s=newstring.s+chr.s                       ; Include the character in the 'newstring.s' output
      EndIf
      lastchr.s=chr.s                                       ; Save this character for the next iteration in the loop
    Next stpos
    
    ; \\\
    ; \\\  Remove text between double quotes to eliminate problems in the event that reserved words or characters processed by this routine happen to
    ; \\\  be within double quotes
    ; \\\
    
    quotemark=#False;                                       ; Reset quote mark 'active' flag
    length=Len(newstring.s)                                 ; Length of processed line
    For stpos=1 To length                                   ; Go through each character in the resulting processed line
      chr.s=Mid(newstring.s,stpos,1)                        ; Extract each character in turn
      If chr.s = #CHR34                                     ; Look for double quote mark
        If quotemark=#True                                  ; We're already inside a quote pair, so turn off the quote flag, since we've reached
          quotemark=#False                                  ; the end of the pair
        Else
          quotemark=#True                                   ; First of the quote pair so turn on the flag
        EndIf
      EndIf
      If quotemark=#True And chr.s <> #CHR34                ; If we're inside a quote pair and this is not the actual quote, then change to a space
        newstring.s=Left(newstring.s,stpos-1) + " " + Mid(newstring.s,stpos+1)
      EndIf
    Next stpos
    
    ; \\\
    ; \\\  Remove trailing semi-colons from input lines, retaining only the code which precedes it
    ; \\\
    pos=FindString(newstring.s, ";")                        ; Locate semi-colon (marker for comments, which can trail on end of code)
    If pos;                                                 ; Found a semi-colon
      newstring.s=Left(newstring.s,pos-1)                   ; Retain all text up to the semi-colon, discard everything from semi-colon onwards
    EndIf
    
    recno=recno+1                                           ; Increment the record counter, if only to provide the user with a running count of lines
    Debug Str(recno)+" : "+newstring.s                      ; Show the user the newly amended line (i.e. the line with unwanted spacing removed)
    
    If CountString(newstring.s, #ENABLE_EXPLICIT)           ; If we encounter EnableExplicit, set the flag to indicate as such
      expfound=#True                                        ; and the user can therefore choose to ignore those source files in which EnableExplicit
    EndIf                                                   ; already appears
    
    If Left(newstring.s,10)="Procedure "                    ; If we meet a Procedure section, record the name so we can associate variables with it
      lastproc.s=Mid(newstring.s,11);                       ; Extract the procedure name
      pos=FindString(lastproc.s, "(")                       ; Find the opening parenthesis so we know where the name ends
      If pos
        lastproc.s=Left(lastproc.s,pos-1)                   ; Extract the procedure name, up to the character before opening parenthesis
      EndIf
    EndIf
    
    If Left(newstring.s,12)="EndProcedure"                  ; For EndProcedure, drop the last procedure name, so that any further variables are
      lastproc.s=""                                         ; associated without a procedure name (the main programme), until we subsequently find
    EndIf                                                   ; another procedure
      
    If Left(newstring.s,3) <> "If " And Left(newstring.s,1) <> "#"      ; Ignore 'If' statements and constants, since we're not interested in those vars.
                                                                        ; but other commands can be added to this list, as necessary
      
      If Left(newstring.s,4) = "For "                                   ; Special case for 'For' statement, since the variable follows the statement
        newstring.s=Mid(newstring.s,5)                                  ; In this case, remove 'For' since we don't want this to form part of var. name
      EndIf
      
      If Left(newstring.s,6) <> "Define"                                ; Special case for 'Define' with equate of an initialised value, since these
                                                                        ; presumably fulfil our requirement of being defined, hence we
                                                                        ; don't need to know about these
        
        pos=FindString(newstring.s, "=")                    ; Look for '=' assignment in the line, so we can determine the variable name preceding it
        If pos>1                                            ; If we find an '=' symbol, process the line
         If Mid(newstring.s,pos-1,1)=" "                    ; If the previous character before the '=' symbol is a space, adjust our pointer to ignore it
           pos=pos-1                                        ; because we don't want the space in the variable name
         EndIf

         varname.s=Left(newstring.s,pos-1)                      ; Extract the variable name preceding the '=' symbol
         Debug " "
         If lastproc.s <> ""                                    ; Show the user the extracted variable name, so this can be checked in the source if
           Debug lastproc.s + "/" + varname.s+" IS A VARIABLE"  ; req'd. also add the procedure name, so we can see the name of the procedure with which
         Else                                                   ; the variable is associated
           Debug varname.s+" IS A VARIABLE"
         EndIf
         Debug " ";                                         
         
         AddElement(varlist.s())                            ; Create a new list entry in varlist.s()
         If lastproc.s <> ""
           varname.s=lastproc.s + " / " + varname.s         ; Prefix with procedure name
         EndIf
         varlist.s() = varname.s                            ; Store the extracted variable name in list varlist.s()
        EndIf
      EndIf
        
    EndIf
  Wend
Else
  Debug "Cannot open the file specified"
  End
EndIf

Debug " "
If expfound
   Debug "This source code file already contains "+ #ENABLE_EXPLICIT
Else
   Debug "This source code file DOES NOT contain "+ #ENABLE_EXPLICIT
EndIf
 
; \\\
; \\\  Now we have our list of variable names found in varlist.s(), go through each of them and de-dupe them against a new list vardupe.s(), so we
; \\\  end up with the list of unique variable names
; \\\ 
ResetList(varlist.s())                                      ; Reset the varlist.s() point to the beginning of the list
While NextElement(varlist.s())                              ; Go through each list element
  duped=#False
  ResetList(vardupe.s())                                    ; Reset the de-duped output list vardupe.s() so we can check every entry in there
  While NextElement(vardupe.s())                            ; Go through the output de-duped list
    If vardupe.s() = varlist.s()                            ; Check if the input list element varlist.s() already exists in the de-duped list
      duped=#True                                           ; It's already there, so we don't need to store it again
    EndIf
  Wend
  If Not(duped)                                             ; Is it a duplication?
    AddElement(vardupe.s())                                 ; Not a duplication, so we create a new element in vardupe.s()
    vardupe.s() = varlist.s()                               ; Store the variable in the de-duped list vardupe.s()
  EndIf    
Wend

; \\\
; \\\  Sort the de-duped output list in alphabetical sequence
; \\\ 
SortList(vardupe(),#PB_Sort_Ascending)
  
Debug "These are the variables found : "

; \\\
; \\\  Show the complete list to the user
; \\\ 
ResetList(vardupe.s())                                      ; Start at the beginning of the de-duplicated list
While NextElement(vardupe.s())
  outcount=outcount+1
  Debug Str(outcount)+" : "+vardupe.s()                     ; Output the numeric counter and the variable name (note that variable names can be
Wend                                                        ; prefixed with the procedure name (if found) followed by a '/'
User avatar
Oso
User
User
Posts: 66
Joined: Wed Jul 20, 2022 10:09 am

Re: EnableExplicit generator?

Post by Oso »

Just to give an example of what to expect. Someone else's code I'm looking at gives this output and we can see how it has identified a set of variables associated with the procedure 'OpenImage', whereas the other two (x and y) are in the main body.

Code: Select all

41 : Procedure OpenImage()
42 : Define.s filePath$
43 : filePath$=OpenFileRequester("                    ",
 
OpenImage/filePath$ IS A VARIABLE
 
59 : imageWidth = ImageWidth(#Image_Copy)
 
OpenImage/imageWidth IS A VARIABLE
 
60 : imageHeight = ImageHeight(#Image_Copy)
 
OpenImage/imageHeight IS A VARIABLE
 
This source code file already contains EnableExplicit
These are the variables found : 
1 : OpenImage / filePath$
2 : OpenImage / imageHeight
3 : OpenImage / imageWidth
4 : x
5 : y
User avatar
blueb
Addict
Addict
Posts: 963
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: EnableExplicit generator?

Post by blueb »

BarryG wrote: Sun Jul 31, 2022 12:56 am So I've never used EnableExplicit before, but I was thinking today: my source code has now grown far too large to suddenly add it, as I'd have to manually go through 1.6 MB of source code (55880 lines) to add definitions to every single variable that my app uses.

This is obviously way too hard and too much manual work for such a large source, so has anyone ever coded an EnableExplicit generator to do this automatically to a given source file?
BarryG
SnifftheGlove wrote something a few years ago that might assist you...
https://www.purebasic.fr/english/viewto ... 41#p517741
- It was too lonely at the top.

Current Machine: Win 10 Pro 64-bit, AMD Ryzen 9 5900X, 64 gigs ram, Geforce GTX 1660 Ti w/6 gigs ram
Post Reply