Ungenutze Variablen

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Benutzeravatar
Josef Stockinger
UDF-Programmierer
UDF-Programmierer
Beiträge: 53
Registriert: So, 25. Sep 2005 18:06
Wohnort: Nähe Regensburg
Kontaktdaten:

Beitrag von Josef Stockinger »

Hallo Manfred,
Manfred hat geschrieben:Dein 2.Satz: was meinst Du damit? Das wäre nämlich meine eigentliche Frage gewesen.
das ist wahrscheinlich ein gemeinsames Problem:

Diese STATIC FUNC/PROCs werden meist von einer vorhandenen abgeleitet und vielleicht dann in der anderen STATIC FUNC/PROC etwas verändert. Wenn ich jetzt wieder sowas brauche und diese reinkopiere, erwische ich leicht die falsche oder das Verhalten wird wieder geändert. Am Schluß weiß ich nicht mehr, welche denn nun eigentlich die beste von allen ist.
Da wären wir dann wahrscheinlich bei den Klassen, die gerade an anderer Stelle aktuell angesprochen sind.
Das ist wohl der Punkt, wo auch ich bei CLASS-Code landen sollte. Aber dazu fehlen mir die Grundlagen.

Gruß
Josef
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Koverhage hat geschrieben:Hubert, das macht schon Sinn, OOP was ist das ? ;-)
Ich weiß jetzt nicht ob du den 2. Teilsatz mit dem ;) gemeint hast,
zur Sicherheit OOP = ObjektOrientierteProgrammierung.
Gruß
Hubert
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

Habe das Programm von Mark mal erweitert.
Es werden jetzt PROCEDURE, FUNCTION, PROC und FUNCT verarbeitet.
Static function oder Static Procedure werden mit einem | versehen.

So kann man unbenutzten Code aufspüren bzw. wenn Static Prozeduren bzw. Functionen und normale gleichen Namens existieren, prüfen was anders ist.

*
* Author Mark J Carew
* 25/10/04 05:18
* Examines
* 1. One prg
* grok myprog.prg
* 2. All Prgs
* grok
* 3. One xpj file's programs
* grok myproj.xpj
* 4. All Prgs in all Xpjs
* grok *.xpj
*
* Create a file - grok.dbf that contains the number of
* times a function that is in the above prg(s) is called
* If hitcount == 0 then the function is ceated but never called
*
#INCLUDE "common.ch"
#INCLUDE "directry.CH"
#INCLUDE "dbfdbe.CH"
#INCLUDE "fileio.CH"
#INCLUDE "deldbe.CH"

#define GROK_EXCEPTIONS ;
{"LAYOUT_AU","NAMETITLE","USEPREFIX_A1","ADDRLINEONE"}

#define CRLF chr( 13 ) + chr( 10 )
#define CR chr( 13 )
#define LF chr( 10 )

static aChs
static aProgsToCheck
static cFunction
static cPrg
static cCh
static cShortProg
static nAsteriskSlash
static nLineNo
static nSlashAsterisk
*
function main(cInPrg)
*
local aDirXpj
local aGrokExceptions
local aPrgs
local aThisXpj
local cEachException
local cString
local nHandleCfg
local nLen
local nPtr
local nTotalLines
*
nTotalLines := 0
*
aGrokExceptions := GROK_EXCEPTIONS
*
aProgsToCheck := {}
clear screen
*
loadCDxDbe()
*
ferase("grok.dbf")
ferase("grok.cdx")
*
dbcreate(;
"grok.dbf",;
{{"fnctn","C",45,0},;
{"hitCount","N",6,0},;
{"program","C",12,0},;
{"linenr","N",6,0},;
{"info","C",200,0}},;
"DBFCDX")
*
use grok alias grok new exclusive via "DBFCDX"
*
ordcreate("grok.cdx","fnctn","fnctn")
ordcreate("grok.cdx","program","program+fnctn")
ordcreate("grok.cdx","hitcount","str(hitcount,6,0)+fnctn+program")
*
dbcloseALL()
*
use grok alias grok new exclusive via "DBFCDX"
grok->(ordlistadd("grok.cdx"))
grok->(ordsetfocus("fnctn","grok.cdx"))
*
IF cInPrg == nil
aPrgs := directory("*.prg")
ELSE
*
cInPrg := upper(alltrim(cInPrg))
*
do case
case cInPrg == "*.XPJ"
*
aDirXpj := directory(cInPrg)
*
aThisXpj := {}
*
nLen := len(aDirXpj)
*
FOR nPtr := 1 TO nLen
*
xpjPrgsArray(aDirXpj[nPtr][1],aThisXpj)
*
NEXT
*
aPrgs := aThisXpj
*
case at(".XPJ",cInPrg) > 0
*
aThisXpj := {}
*
xpjPrgsArray(cInPrg,aThisXpj)
*
aPrgs := aThisXpj
*
otherwise
*
IF at(".PRG",cInPrg) > 0
*
// cInPrg += ".PRG"
*
ENDIF
*
aPrgs := {}
*
aadd(aPrgs,{cInPrg})
*
end case
*
ENDIF

nLen := len(aPrgs)
*
FOR nPtr := 1 TO nLen
*
cPrg := upper(alltrim(aPrgs[nPtr][1]))
*
IF cPrg == "GROK.PRG"
LOOP
ENDIF
*
* select programs
*
aadd(aProgsToCheck,cPrg)
*
nLineNo := 0
*
nSlashAsterisk := 0
*
nHandleCfg := mcTxtOpen(cPrg)
*
if nHandleCfg > 0
*
DO WHILE TRUE
*
cString := mcTxtLine(nHandleCfg)
if len(cString) < 1
exit
endif
*
cString := strtran(cString,chr(09),space(4))
*
nTotalLines ++
*
processPrg(cString)
*
ENDDO
*
mcTxtCLOSE(nHandleCfg)
*
endif
*
next
*
updateHitCount()
updateChCount()
*
nLen := len(aGrokExceptions)
*
FOR nPtr := 1 TO nLen
*
cEachException := aGrokExceptions[nPtr]
*
IF grok->(dbseek(padr(cEachException,45)))
*
grok->hitcount := 99999
*
ENDIF
*
NEXT
*
dbcloseall()
?
? 'total lines read ', nTotalLines
?
WAIT
*
return nil
*
*
*
function xpjPrgsArray(cXpjName,aThisXpj)
*
local nScan
local cXpjString
local nHandle
*
nHandle := fOpen(cXpjName,FO_READ)
*
IF nHandle <> -1
*
* what are the prgs in this xpj
*
do while TRUE
*
cXpjString := mcTxtLine(nHandle)
if len(cXpjString) < 1
exit
endif
*
cXpjString := upper(alltrim(cXpjString))
*
IF at(".PRG",cXpjString) > 0
*
IF AT("/" + "/",cXpjString) == 0
*
IF empty(aThisXpj)
*
aadd(aThisXpj,{cXpjString})
*
? cXpjString
*
else
*
nScan := ;
aScan(aThisXpj,{|e|e[1]==cXpjString })
*
IF nScan == 0
*
aadd(aThisXpj,{cXpjString})
*
? cXpjString
*
ENDIF
*
ENDIF
*
ENDIF
*
ENDIF
*
enddo
*
mcTxtClose(nHandle)
*
ENDIF
*
return aThisXpj
*
*
*
function processPrg(cString)
*
local cFirstTwo
local cFunct
local cUpper
local cUpperString
local nFunctionCol
local cEOL := CHR(13) + CHR(10)
*

cUpper := upper(strtran(cString,cEOL,""))
*
cUpperString := alltrim(cUpper)
*
cFirstTwo := left(cUpperString,2)
*
nLineNo ++
*
if cUpperString == "*" .OR. ;
cFirstTwo == "/" + "/"
*
else
*
nFunctionCol := at("FUNC",cUpperString)
if nFunctionCol < 1
nFunctionCol := at("PROC",cUpperString)
endif
*
if nSlashAsterisk == 0
*
nSlashAsterisk := at('/*',cUpperString)
*
endif
*
* time to turn off slash asterisk
*
if nSlashAsterisk > 0
*
nAsteriskSlash := at('*/',cUpperString)
*
if nAsteriskSlash > 0
*
nSlashAsterisk := 0
nAsteriskSlash := 0
*
endif
*
endif
*
* if commenting is off
*
IF nSlashAsterisk == 0
*
do case
case nFunctionCol == 1 .or. nFunctionCol == 8
*
cFunction := cUpperString
*
if at("(",cFunction) > 0
cFunct := substr(cFunction,1,at("(",cFunction)-1)
elseif at("//",cFunction) > 0
cFunct := substr(cFunction,1,at("//",cFunction)-1)
else
cFunct := cFunction
endif
cFunct := strtran(cFunct,"STATIC","")
cFunct := strtran(cFunct,"FUNCTION","")
cFunct := strtran(cFunct,"PROCEDURE","")
cFunct := strtran(cFunct,"FUNC","")
cFunct := strtran(cFunct,"PROC","")
cFunct := ltrim(cFunct)
if substr(cFunct,1,1) == "*"
return nil
endif
if nFunctionCol == 8
cFunct := "|"+padr(cFunct,44)
else
cFunct := padr(cFunct,45)
endif
*
IF grok->(dbseek(cFunct))
*
? '* ---------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
? 'Function/Procedure Occurrs Twice',alltrim(cFunct)
? '* ---------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
*
else
*
? 'Added Function/Procedure ',cPrg,alltrim(cFunct)
*
grok->(dbappend())
grok->fnctn := cFunct
grok->program := cPrg
grok->linenr := nLineNo
*
ENDIF
*
nSlashAsterisk := 0
nAsteriskSlash := 0
*
end case
*
ENDIF
*
endif
*
return nil
*
*
*
function updateHitCount()
*
local cString
local cUpperString
local nFunctionCol
local nHandleCfg
local nLen
local nPtr
local nReturnCol
*
nLen := len(aProgsToCheck)
*
? "Look at for Hit Count ?"
*
FOR nPtr := 1 TO nLen
*
cPrg := aProgsToCheck[nPtr]
cShortProg := strtran(cPrg,".PRG","")
*
? "Looking at",cPrg
*
nHandleCfg := mcTxtOpen(cPrg)
*
if nHandleCfg > 0
*
DO WHILE TRUE
*
cString := mcTxtLine(nHandleCfg)
if len(cString) < 1
exit
endif
if empty(cString)
loop
endif
*
cString := strtran(cString,chr(09),space(4))
cUpperString := upper(alltrim(cString))
*
if cUpperString == "*"
else
*
* look for slash Asterisk
*
if nSlashAsterisk == 0
nSlashAsterisk := at("/*",cUpperString)
ENDIF
*
* time to turn off slash asterisk
*
if nSlashAsterisk > 0
*
nAsteriskSlash := at("*/",cUpperString)
*
if nAsteriskSlash > 0
*
nSlashAsterisk := 0
nAsteriskSlash := 0
*
endif
*
endif
*
* if commenting is off
*
IF nSlashAsterisk == 0
*
* assumes that only one function is found per line
* we are realy looking for no hits
*
nFunctionCol := at("FUNC",cUpperString)
if nFunctionCol < 1
nFunctionCol := at("PROC",cUpperString)
endif
nReturnCol := at("RETURN",cUpperString)
*
do case
case nFunctionCol == 1
case nFunctionCol == 8
case nReturnCol == 1
*
otherwise
*
* looking for functions only
*
IF at("(",cUpperString) > 0
*
lookForHits(cUpperString)
*
ENDIF
*
end case
*
endif
*
endif
*
ENDDO
*
mcTxtCLOSE(nHandleCfg)
*
endif
*
NEXT
*
return nil
*
*
*
function lookForHits(cString)
*
grok->(dbgotop())
*
do while TRUE
*
IF grok->(eof())
exit
ENDIF
*
cFunction := alltrim(grok->fnctn) + "("
*
IF at(cFunction,cString) > 0
*
grok->hitcount ++
*
IF at(cShortProg,grok->info) == 0
*
grok->info := ;
alltrim(grok->info) + ;
cShortProg + ;
"|"
*
ENDIF
*
ENDIF
*
grok->(dbskip())
*
enddo
*
return nil

function updateChCount()
*
local cString
local nHandleCfg
local nLen
local nPtr
local cUpperString
*
aChs := directory("*.ch")
*
nLen := len(aChs)
*
FOR nPtr := 1 TO nLen
*
cCh := upper(alltrim(aChs[nPtr][1]))
*
? "Looking at",cCh
*
nHandleCfg := mcTxtOpen(cCh)
*
if nHandleCfg > 0
*
DO WHILE TRUE
*
cString := mcTxtLine(nHandleCfg)
if len(cString) < 1
exit
endif
if empty(cString)
loop
endif
*
cString := strtran(cString,chr(09),space(4))
cUpperString := upper(alltrim(cString))
*
* looking for functions only
*
IF at("(",cUpperString) > 0
*
lookForChHits(cUpperString)
*
endif
*
ENDDO
*
mcTxtCLOSE(nHandleCfg)
*
endif
*
NEXT
*
return nil

function lookForChHits(cString)
*
grok->(dbgotop())
*
do while TRUE
*
IF grok->(eof())
exit
ENDIF
*
cFunction := alltrim(grok->fnctn) + "("
*
IF at(cFunction,cString) > 0
*
grok->hitcount ++
*
IF at(cCh,grok->info) == 0
grok->info := ;
alltrim(grok->info) + ;
cCh + "|"
ENDIF
*
ENDIF
*
grok->(dbskip())
*
enddo
*
return nil

function loadCDxDbe()
*
IF ! DbeLoad( "CDXDBE",.T.)
msgBox( "Database-Engine CDXDBE not loaded" ,"Message Box" )
ENDIF

IF ! DbeBuild( "DBFCDX", "DBFDBE", "CDXDBE" )
msgBox( "DBFCDX Database-Engine;Could not build engine" , "Message Box" )
ENDIF
*
dbeSetDefault("DELDBE")
*
dbeinfo(COMPONENT_DATA, DELDBE_MODE, DELDBE_SINGLEFIELD)
dbeinfo(COMPONENT_DATA, DELDBE_DELIMITER_TOKEN, CHR(0))
*
return nil



/***
*
* FReadLn( <nHandle>, [<nLines>], [<nLineLength>], [<cDelim>] ) --> cLines
*
* Read one or more lines from a text file
*
* NOTES:
* Line length includes delimiter, so max line read is
* (nLineLength - LEN( cDelim ))
*
* Return value includes delimiters, if delimiter was read
*
* nLines defaults to 1, nLineLength to 80 and cDelim to CRLF
*
* FERROR() must be checked to see if FReadLn() was successful
*
* FReadLn() returns "" when EOF is reached
*
*/
STATIC FUNCTION mcTxtLine( nHandle, nLines, nLineLength, cDelim )

LOCAL nCurPos // Current position in file
LOCAL nFileSize // The size of the file
LOCAL nChrsToRead // Number of character to read
LOCAL nChrsRead // Number of characters actually read
LOCAL cBuffer // File read buffer
LOCAL cLines // Return value, the lines read
LOCAL nCount // Counts number of lines read
LOCAL nEOLPos // Position of EOL in cBuffer

DEFAULT nLines TO 1
DEFAULT nLineLength TO 132
DEFAULT cDelim TO ( CHR(13) + CHR(10) )

nCurPos := FilePos( nHandle )
nFileSize := FileSize( nHandle )

// Make sure no attempt is made to read past EOF
nChrsToRead := MIN( nLineLength, nFileSize - nCurPos )

cLines := ''
nCount := 1
DO WHILE (( nCount <= nLines ) .AND. ( nChrsToRead != 0 ))

cBuffer := SPACE( nChrsToRead )
nChrsRead := FREAD( nHandle, @cBuffer, nChrsToRead )

// Check for error condition
IF !(nChrsRead == nChrsToRead)
// Error!
// In order to stay conceptually compatible with the other
// low-level file functions, force the user to check FERROR()
// (which was set by the FREAD() above) to discover this fact
//
nChrsToRead := 0
ENDIF

nEOLPos := AT( cDelim, cBuffer )

// Update buffer and current file position
IF ( nEOLPos == 0 )
cLines += LEFT( cBuffer, nChrsRead )
nCurPos += nChrsRead
ELSE
cLines += LEFT( cBuffer, ( nEOLPos + LEN( cDelim ) ) - 1 )
nCurPos += ( nEOLPos + LEN( cDelim ) ) - 1
FSEEK( nHandle, nCurPos, FS_SET )
ENDIF

// Make sure we don't try to read past EOF
IF (( nFileSize - nCurPos ) < nLineLength )
nChrsToRead := ( nFileSize - nCurPos )
ENDIF

nCount++

ENDDO

RETURN ( cLines )

/***
*
* FilePos( <nHandle> ) --> nPos
*
* Report the current position of the file pointer in a binary file
*
*/
STATIC FUNCTION FilePos( nHandle )
RETURN ( FSEEK( nHandle, 0, FS_RELATIVE ) )



/***
*
* FileSize( <nHandle> ) --> nBytes
*
* Return the size of a binary file
*
*/
STATIC FUNCTION FileSize( nHandle )

LOCAL nCurrent
LOCAL nLength

// Get file position
nCurrent := FilePos( nHandle )

// Get file length
nLength := FSEEK( nHandle, 0, FS_END )

// Reset file position
FSEEK( nHandle, nCurrent )

RETURN ( nLength )


STATIC FUNCTION mcTxtOpen(cFilename)
return FOpen( cFilename , FO_READ )

STATIC FUNCTION mcTxtClose(nHandle)
FClose( nHandle )
return FError()
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Hallo, Klaus.

Wenn Du Code in die Code-Tags (Button "Code" über dem Editierfeld für Nachrichten) einbindest, wird er besser lesbar:

Code: Alles auswählen

FOR i := 1 TO n
? i
NEXT
Nur der Vollständigkeit halber: Symbolinfo(DEFINE) liefert Arrays, die - je nach DEFINE - alle PRIVATES, PUBLICS, auf Wunsch aber auch alle Funktionen/Prozeduren, Klassendeklarationen usw. auflistet.

Code: Alles auswählen

Symbolinfo(MEMVAR_PUBLIC) // alle Publics
Symbolinfo(MEMVAR_PRIVATE) // alle Privates
Symbolinfo(SYMBOL_FUNCTION) // alle Funktionen und Procs. usw.
Privates können auch durch Nutzung des Makro-Operators entstehen, zum Beispiel so:

Code: Alles auswählen

FOR i := 1 TO 10
  cTest := Ltrim(Str(i,2,0))
  cMyVar&cTest := i
NEXT
Im Anschluß existieren u.a. 10 PRIVATE-Variablen namens cMyVar1 bis cMyVar10. Die kann kein Compilerschalter finden.
Herzlich,
Tom
Antworten