When i try to compile and debug my modified version as a .c source i do strip out the specific flex definitions and rules
Some rule triggered functions make use of the input() function as in
while (((ch = input()) != '\n') && (ch != EOF))
I get an undefined error.
Is this a function generated by flex ? I can't find it in C libraries or in the SDK
Hidden Text - Click to Show :
/****h* CProfiler/CPCallScan.flex [2.0] ****************************
*
* NAME
* CPCallScan.flex
*
* DESCRIPTION
* Scan through all the files named in the ListFileName & add
* every function call inside defined functions to the internal
* Module structures.
*
* HISTORY
* 09-Dec-2004 - Added AmigaOS4 & gcc support.
*
* 05-Mar-2000 - Changed the main() to CallScan().
*
* 01-Mar-2000 - Added argv[1] as the output name.
********************************************************************
*
*/
/* ----------------------- Definitions Section: -------------------- */
%option noyywrap
%START CURLY NORM
WHT ([ \t]*)
INT ([1-9][0-9]*)
OCTAL ([0-7][0-7][0-7])
HEX ([0x][0-9A-Fa-f]*)
FLT ({INT}\.{INT})
NUMBER ({INT}|{OCTAL}|{HEX}|{FLT})
SEMI ";"
COMMA ","
AMP "&"
PTR "*"
OP ([\+\-/])*
NL \n
LBRACK \[
RBRACK \]
LPAREN \(
RPAREN \)
LBRCE \{
RBRCE \}
CPLUSCMT "//"
SQUOTE \047
DQUOTE \042
BKQUOTE (\134{DQUOTE})
STR ({DQUOTE}([^"\n]|{BKQUOTE})*{DQUOTE})
STRTCMT "/*"
CHRQUOTE ({SQUOTE}.{SQUOTE}|{SQUOTE}\134.{SQUOTE})
WLF ([ \t\n\f\r]*)
TYPEDEF "typedef"
IDENT ([_a-zA-Z][_a-zA-Z0-9]*)
PREPROC ("#"{IDENT})
NAME ({PTR}*{IDENT})
ARRAY ({LBRACK}[0-9+-/*]*{RBRACK})
DECL ([,]|{WLF}|{NAME}|{ARRAY})
FUNCPTR ({LPAREN}{NAME}*{RPAREN}{LPAREN}{DECL}*{RPAREN})
DECLST ({DECL}|{FUNCPTR})*
SPTR "->"
MISC ({OP}|{NL}|{AMP}{IDENT}|{AMP}{IDENT}{ARRAY}|{SPTR}|\.)
PARM ({NAME}|{WHT}|{STR}|{CHRQUOTE}|{ARRAY}|{NUMBER}|{MISC})
PARMLST ({PARM}|{COMMA})*
INFNC ({IDENT}{LPAREN}{PARMLST}{RPAREN})
F3STRT ([ \t]*{LPAREN}{DECLST}{RPAREN}[\n]*{LBRCE})
FNCCALL ({LPAREN}{PARMLST}|{INFNC}{RPAREN})
%{
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <AmigaDOSErrs.h>
#ifdef __amigaos4__
# define __USE_INLINE__
# include <proto/exec.h>
# include <proto/dos.h>
# include <proto/locale.h>
IMPORT struct Library *SysBase;
IMPORT struct Library *DOSBase;
IMPORT struct Library *LocaleBase;
IMPORT struct ExecIFace *IExec;
IMPORT struct DOSIFace *IDOS;
IMPORT struct LocaleIFace *ILocale;
#endif
#include "CPStructs.h"
#include "CPheader.h"
#include "CPGM:GlobalObjects/CommonFuncs.h"
#define CATCOMP_ARRAY 1
#include "CProfilerLocale.h"
#include "CProfilerProtos.h"
IMPORT struct Catalog *catalog;
// --------------------------------------------------------------------
IMPORT struct sfuncs SFuncs[ MAXFNCTS ];
IMPORT struct Module Modules[ MAXMODULES ];
IMPORT UBYTE *ErrMsg;
// --------------------------------------------------------------------
PRIVATE struct Module *CurrentModule = &Modules[0];
PRIVATE struct Function *CurrentFuncDefn = NULL;
PRIVATE FILE *InputFP = NULL; // stdin;
PRIVATE char CurrentModuleName[ BUFF_SIZE ];
PRIVATE int curly = 0;
PRIVATE int CurrentMIndex = 0;
PRIVATE void AddCalledFunc( char *ttext );
PRIVATE void SetCurrentFunc( char *ttext );
PRIVATE void DiscardComment( void );
PRIVATE void DiscardCPlusComment( void );
PRIVATE void DiscardPreProc( void );
PRIVATE void DiscardTypeDef( void );
#ifdef __SASC
# define MEMF_FLAGS MEMF_CLEAR | MEMF_ANY
#else
# define MEMF_FLAGS MEMF_CLEAR | MEMF_SHARED
#endif
%}
/* -------------------------- Rules Section: ------------------------ */
%%
{CHRQUOTE} ;
{STR} ;
{PREPROC} { DiscardPreProc(); }
{TYPEDEF} { DiscardTypeDef(); }
<CURLY>\{ {if (yytext[-1] != '\'')
curly++;
}
<CURLY>\} {if (yytext[-1] != '\'')
{
if (--curly == 0)
{
BEGIN 0;
BEGIN NORM;
}
}
}
{INFNC} {if (curly > 0)
AddCalledFunc( yytext );
}
<CURLY>{IDENT}/{FNCCALL} {if (curly > 0)
AddCalledFunc( yytext );
}
<NORM>{NAME}/{F3STRT} {SetCurrentFunc( yytext );
curly = 0;
BEGIN 0;
BEGIN CURLY;
}
{CPLUSCMT} { DiscardCPlusComment(); }
{STRTCMT} { DiscardComment(); }
{NL} ;
. ;
%%
/* -------------------------- User Code Section: -------------------- */
PRIVATE void DiscardPreProc( void )
{
int ch = 0, prev = 0;
for ( ; ; )
{
SlurpMore:
while (((ch = input()) != '\n') && (ch != EOF))
prev = ch;
if (ch == '\n')
{
if (prev == '\\')
goto SlurpMore;
break;
}
if (ch == EOF)
{
fprintf( stderr, CMsg( MSG_FOUND_EOF_PREPROC, MSG_FOUND_EOF_PREPROC_STR ) );
break;
}
}
return;
}
PRIVATE void DiscardTypeDef( void )
{
int ch = 0;
for ( ; ; )
{
while (((ch = input()) != '\n') && (ch != EOF))
;
if (ch == '\n')
{
break; // Only valid exit point for the 'for ( ; ; )'.
}
if (ch == EOF)
{
fprintf( stderr, CMsg( MSG_FOUND_EOF_TYPEDEF, MSG_FOUND_EOF_TYPEDEF_STR ) );
break;
}
}
return;
}
PRIVATE void DiscardCPlusComment( void )
{
int ch = 0;
for ( ; ; )
{
while (((ch = input()) != '\n') && (ch != EOF))
;
if (ch == '\n')
{
break; // Only valid exit point for the 'for ( ; ; )'.
}
if (ch == EOF)
{
fprintf( stderr, CMsg( MSG_FOUND_EOF_COMMENT, MSG_FOUND_EOF_COMMENT_STR ) );
break;
}
}
return;
}
PRIVATE void DiscardComment( void )
{
int ch = 0;
for ( ; ; )
{
while (((ch = input()) != '*') && (ch != EOF))
;
if (ch == '*')
{
while ((ch = input()) == '*')
;
if (ch == '/')
{
break; // Only valid exit point for the 'for ( ; ; )'.
}
}
if (ch == EOF)
{
fprintf( stderr, CMsg( MSG_FOUND_EOF_COMMENT, MSG_FOUND_EOF_COMMENT_STR ) );
break;
}
}
return;
}
/* These are keywords that can be followed by parentheses & can be
** mistaken for function names:
*/
PRIVATE char *keywords[] = {
"while", "if", "for",
"sizeof", "switch", "return", NULL
};
PRIVATE BOOL CheckKeywords( char *name )
{
int i = 0;
while (keywords) // != NULL)
{
if (StringComp( keywords, name ) == 0)
{
return( TRUE );
}
i++;
}
return( FALSE );
}
PRIVATE char FilteredName[ BUFF_SIZE ] = { 0, };
PRIVATE char *FilterStars( char *text )
{
int i, j, len = StringLength( text );
// Filter off any '*' pointer stuff:
for (i = 0, j = 0; i < len; i++)
{
if (*(text + i) != '*')
{
FilteredName[j] = *(text + i);
j++;
}
}
FilteredName[j] = '\0'; // Terminate with a nil.
return( &FilteredName[0] );
}
PRIVATE int FindLastFuncEntry( struct sfuncs *FArray )
{
int i = 0;
while (i < MAXFNCTS)
{
if ( !FArray.Name) // == NULL)
break;
i++;
}
if (i == MAXFNCTS)
{
fprintf( stderr, CMsg( MSG_FMT_ARRAY_OVERFLOW, MSG_FMT_ARRAY_OVERFLOW_STR ), MAXFNCTS );
return( 0 );
}
return( i );
}
PRIVATE void IncrementUsedCount( char *funcname, struct Function *flist )
{
struct Function *found = FindFunction( funcname, flist );
if (found) // != NULL)
found->used++;
return;
}
PRIVATE BOOL ChkFuncList( char *functionname, struct Function *flist )
{
BOOL rval = FALSE;
if (!flist) // == NULL)
rval = FALSE;
else if (FindFunction( functionname, flist )) // != NULL)
rval = TRUE;
else
rval = FALSE;
return( rval );
}
PRIVATE char temp[ BUFF_SIZE ] = { 0, };
#define LEFTPAREN "("
PRIVATE void StripOffGarbage( char *token )
{
int i = 0;
if (strpbrk( token, LEFTPAREN )) // != NULL)
{
while ((*(token + i) != '(') && (i < BUFF_SIZE))
temp = *(token + i++);
temp = '\0';
StringCopy( token, temp );
}
return;
}
PRIVATE void AddCalledFunc( char *ttext )
{
IMPORT struct sfuncs *FindFuncEntry( char *fname );
struct Function *newfp = NULL, *fp = NULL, *prev = NULL;
struct sfuncs *sfptr = NULL;
char *name = NULL, outFName[512] = { 0, };
int fidx = 0;
// Strip off any garbage after the identifier (if any):
StripOffGarbage( ttext );
if (CheckKeywords( ttext ) == TRUE)
{
return;
}
StringCopy( &outFName[0], FilterStars( ttext ) );
sfptr = FindFuncEntry( outFName );
fidx = FindLastFuncEntry( &SFuncs[0] );
if (ChkFuncList( outFName, CurrentModule->deffncs ) == TRUE)
{
// Function already in the Defined function list.
IncrementUsedCount( outFName, CurrentModule->deffncs );
}
else if (CurrentModule->deffncs->calls
&& (ChkFuncList( outFName, CurrentModule->deffncs->calls ) == TRUE))
{
// Function already in the function list:
IncrementUsedCount( outFName, CurrentModule->deffncs->calls );
}
/* We still have to add outFName to the CurrentFuncDefn even if
** it's part of the CurrentModule->deffncs:
*/
if (CurrentFuncDefn->calls && (ChkFuncList( outFName, CurrentFuncDefn->calls ) == TRUE))
{
// Function already in the function list, increment & return:
IncrementUsedCount( outFName, CurrentFuncDefn->calls );
}
else
{
// New function call space needed:
if ( !CurrentFuncDefn->calls) // == NULL)
{
newfp = (struct Function *) AllocVec( sizeof( struct Function ), MEMF_FLAGS );
if ( !newfp ) // == NULL)
{
DisplayAarrgghh( CMsg( MSG_NO_MEMORY, MSG_NO_MEMORY_STR ),
CMsg( MSG_SYSTEM_PROBLEM, MSG_SYSTEM_PROBLEM_STR )
);
return;
}
CurrentFuncDefn->calls = newfp; // First time in the list.
fp = newfp;
}
else
{
fp = prev = CurrentFuncDefn->calls;
while (fp) // != NULL)
{
prev = fp;
fp = fp->next;
}
newfp = (struct Function *) AllocVec( sizeof( struct Function ), MEMF_FLAGS );
if (!newfp) // == NULL)
{
DisplayAarrgghh( CMsg( MSG_NO_MEMORY, MSG_NO_MEMORY_STR ),
CMsg( MSG_SYSTEM_PROBLEM, MSG_SYSTEM_PROBLEM_STR )
);
return;
}
prev->next = newfp;
fp = newfp;
}
name = (char *) AllocVec( StringLength( outFName ) + 1, MEMF_FLAGS );
if (!name) // == NULL)
{
prev->next = NULL;
FreeVec( newfp );
DisplayAarrgghh( CMsg( MSG_NO_MEMORY, MSG_NO_MEMORY_STR ),
CMsg( MSG_SYSTEM_PROBLEM, MSG_SYSTEM_PROBLEM_STR )
);
return;
}
StringCopy( name, outFName );
fp->name = name;
fp->used++;
if (!sfptr) // == NULL) // Usually sfptr is NULL:
{
SFuncs[fidx].Name = fp->name;
SFuncs[fidx].Used = 0; // fp->used;
SFuncs[fidx].Parent = CurrentFuncDefn;
SFuncs[fidx].ModuleName = CurrentModule->name;
}
else
{
// ModuleName already taken care of in ReadInDefinedFuncs():
if (!sfptr->ModuleName) // == NULL)
sfptr->ModuleName = CurrentModule->name;
sfptr->Name = fp->name;
sfptr->Used = 0; // += fp->used;
sfptr->Parent = CurrentFuncDefn;
}
}
# ifdef DEBUG
fprintf( stderr, " CALL: %s()\n", outFName );
# endif
return;
}
PRIVATE int FindCurrentModule( char *ModuleName )
{
int i = 0;
while (i < MAXMODULES)
{
if (Modules.name) // != NULL)
{
if (StringComp( Modules.name, ModuleName ) == 0)
break;
}
i++;
}
return( i );
}
PRIVATE void SetCurrentFunc( char *ttext )
{
struct Function *fptr = NULL;
struct sfuncs *sfptr = NULL;
char outFName[ BUFF_SIZE ] = { 0, };
int i = 0, fidx = 0;
if (CheckKeywords( ttext ) == TRUE)
{
return; // A little whitespace would eliminate this.
}
StringCopy( &outFName[0], FilterStars( ttext ) );
sfptr = FindFuncEntry( outFName );
fidx = FindLastFuncEntry( &SFuncs[0] );
/* AddFunction() (Called in ReadInDefinedFuncs()), has allocated
** all defined functions, so FindFunction() should NEVER fail:
*/
if (!(fptr = FindFunction( outFName, CurrentModule->deffncs ))) // == NULL)
{
// Function isn't in the CurrentModule, search for it:
for (i = 0; i < MAXMODULES; i++)
{
if ((fptr = FindFunction( outFName, Modules.deffncs ))) // != NULL)
{
goto GotFuncPtr;
}
}
// This Should NEVER be called:
fprintf( stderr, CMsg( MSG_FMT_IMPOSSIBLE_COND, MSG_FMT_IMPOSSIBLE_COND_STR ),
outFName, CurrentModule->name
);
return;
}
GotFuncPtr:
fptr->used++; // used counter should NEVER move beyond one in here.
CurrentFuncDefn = fptr;
if (sfptr) // != NULL) // Usually sfptr is NOT NULL here:
{
// sfptr->Used = fptr->used;
// ModuleName already taken care of in ReadInDefinedFuncs():
if (!sfptr->ModuleName) // == NULL)
sfptr->ModuleName = CurrentModule->name;
}
else
{
SFuncs[fidx].Name = fptr->name;
SFuncs[fidx].Used = 0; // fptr->used;
SFuncs[fidx].Parent = NULL;
SFuncs[fidx].ModuleName = CurrentModule->name;
}
# ifdef DEBUG
fprintf( stderr, "\n%s() // %s\n{\n", fptr->name, CurrentModule->name );
# endif
return;
}
/****h* CProfiler/CallScan() ******************************************
*
* NAME
* CallScan()
*
* DESCRIPTION
* Scan through all the files named in the ListFileName & add
* every function call inside defined functions to the internal
* Module structures.
***********************************************************************
*
*/
PUBLIC int CallScan( char *ListFileName )
{
IMPORT FILE *yyin;
FILE *ListFP = NULL;
char ModuleName[ BUFF_SIZE ] = { 0, }, *MName = &ModuleName[0], *chk = NULL;
BOOL closeListfile = FALSE;
int rval = RETURN_OK, i = 0;
// -----------------------------------------------------------------
// InputFP = stdin;
if (!(ListFP = OpenFile( ListFileName, "r" ))) // == NULL)
{
rval = IoErr();
fprintf( stderr, CMsg( MSG_FMT_NO_READ_FILEOPEN, MSG_FMT_NO_READ_FILEOPEN_STR ),
ListFileName
);
goto ExitCallScan;
}
closeListfile = TRUE;
// Read in the first Module Name to Scan:
if (!(chk = FGetS( MName, BUFF_SIZE, ListFP ))) // == NULL)
{
fprintf( stderr, CMsg( MSG_EMPTY_FILE_FOUND, MSG_EMPTY_FILE_FOUND_STR ),
ListFileName
);
rval = RETURN_ERROR;
goto ExitCallScan;
}
// The main processing-of-the-Modules loop:
i = 0; // Starting index = 0 for Modules[].
while (chk && ModuleName && (strlen( ModuleName ) > 0)
&& (i < MAXMODULES))
{
if (!(InputFP = OpenFile( MName, "r" ))) // == NULL)
{
rval = IoErr();
fprintf( stderr, CMsg( MSG_FMT_NO_READ_FILEOPEN, MSG_FMT_NO_READ_FILEOPEN_STR ),
MName
);
goto ExitCallScan;
}
// Module structures have already been setup:
MName = strlwr( &ModuleName[0] ); // From Cp.c file
i = FindCurrentModule( MName );
CurrentModule = &Modules;
CurrentMIndex = i;
CurrentFuncDefn = CurrentModule->deffncs;
# ifdef DEBUG
fprintf( stderr, CMsg( MSG_FMT_PROC_MOD_FUNCS, MSG_FMT_PROC_MOD_FUNCS_STR ), MName );
# endif
sprintf( ErrMsg, CMsg( MSG_FMT_PROC_MOD_FUNCS, MSG_FMT_PROC_MOD_FUNCS_STR ), MName );
ShowStatus( ErrMsg );
StringCopy( CurrentModuleName, MName );
yyin = InputFP;
BEGIN NORM;
yylex(); // Find those function calls!
if (InputFP && InputFP != stdin)
{
fclose( InputFP );
InputFP = NULL;
}
chk = FGetS( MName, BUFF_SIZE, ListFP );
}
// All done, Close the file(s) & exit:
ExitCallScan:
if (closeListfile == TRUE)
fclose( ListFP );
return( rval );
}
/* ---------------- END of CPCallScan.flex file! --------------- */
*
* NAME
* CPCallScan.flex
*
* DESCRIPTION
* Scan through all the files named in the ListFileName & add
* every function call inside defined functions to the internal
* Module structures.
*
* HISTORY
* 09-Dec-2004 - Added AmigaOS4 & gcc support.
*
* 05-Mar-2000 - Changed the main() to CallScan().
*
* 01-Mar-2000 - Added argv[1] as the output name.
********************************************************************
*
*/
/* ----------------------- Definitions Section: -------------------- */
%option noyywrap
%START CURLY NORM
WHT ([ \t]*)
INT ([1-9][0-9]*)
OCTAL ([0-7][0-7][0-7])
HEX ([0x][0-9A-Fa-f]*)
FLT ({INT}\.{INT})
NUMBER ({INT}|{OCTAL}|{HEX}|{FLT})
SEMI ";"
COMMA ","
AMP "&"
PTR "*"
OP ([\+\-/])*
NL \n
LBRACK \[
RBRACK \]
LPAREN \(
RPAREN \)
LBRCE \{
RBRCE \}
CPLUSCMT "//"
SQUOTE \047
DQUOTE \042
BKQUOTE (\134{DQUOTE})
STR ({DQUOTE}([^"\n]|{BKQUOTE})*{DQUOTE})
STRTCMT "/*"
CHRQUOTE ({SQUOTE}.{SQUOTE}|{SQUOTE}\134.{SQUOTE})
WLF ([ \t\n\f\r]*)
TYPEDEF "typedef"
IDENT ([_a-zA-Z][_a-zA-Z0-9]*)
PREPROC ("#"{IDENT})
NAME ({PTR}*{IDENT})
ARRAY ({LBRACK}[0-9+-/*]*{RBRACK})
DECL ([,]|{WLF}|{NAME}|{ARRAY})
FUNCPTR ({LPAREN}{NAME}*{RPAREN}{LPAREN}{DECL}*{RPAREN})
DECLST ({DECL}|{FUNCPTR})*
SPTR "->"
MISC ({OP}|{NL}|{AMP}{IDENT}|{AMP}{IDENT}{ARRAY}|{SPTR}|\.)
PARM ({NAME}|{WHT}|{STR}|{CHRQUOTE}|{ARRAY}|{NUMBER}|{MISC})
PARMLST ({PARM}|{COMMA})*
INFNC ({IDENT}{LPAREN}{PARMLST}{RPAREN})
F3STRT ([ \t]*{LPAREN}{DECLST}{RPAREN}[\n]*{LBRCE})
FNCCALL ({LPAREN}{PARMLST}|{INFNC}{RPAREN})
%{
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <AmigaDOSErrs.h>
#ifdef __amigaos4__
# define __USE_INLINE__
# include <proto/exec.h>
# include <proto/dos.h>
# include <proto/locale.h>
IMPORT struct Library *SysBase;
IMPORT struct Library *DOSBase;
IMPORT struct Library *LocaleBase;
IMPORT struct ExecIFace *IExec;
IMPORT struct DOSIFace *IDOS;
IMPORT struct LocaleIFace *ILocale;
#endif
#include "CPStructs.h"
#include "CPheader.h"
#include "CPGM:GlobalObjects/CommonFuncs.h"
#define CATCOMP_ARRAY 1
#include "CProfilerLocale.h"
#include "CProfilerProtos.h"
IMPORT struct Catalog *catalog;
// --------------------------------------------------------------------
IMPORT struct sfuncs SFuncs[ MAXFNCTS ];
IMPORT struct Module Modules[ MAXMODULES ];
IMPORT UBYTE *ErrMsg;
// --------------------------------------------------------------------
PRIVATE struct Module *CurrentModule = &Modules[0];
PRIVATE struct Function *CurrentFuncDefn = NULL;
PRIVATE FILE *InputFP = NULL; // stdin;
PRIVATE char CurrentModuleName[ BUFF_SIZE ];
PRIVATE int curly = 0;
PRIVATE int CurrentMIndex = 0;
PRIVATE void AddCalledFunc( char *ttext );
PRIVATE void SetCurrentFunc( char *ttext );
PRIVATE void DiscardComment( void );
PRIVATE void DiscardCPlusComment( void );
PRIVATE void DiscardPreProc( void );
PRIVATE void DiscardTypeDef( void );
#ifdef __SASC
# define MEMF_FLAGS MEMF_CLEAR | MEMF_ANY
#else
# define MEMF_FLAGS MEMF_CLEAR | MEMF_SHARED
#endif
%}
/* -------------------------- Rules Section: ------------------------ */
%%
{CHRQUOTE} ;
{STR} ;
{PREPROC} { DiscardPreProc(); }
{TYPEDEF} { DiscardTypeDef(); }
<CURLY>\{ {if (yytext[-1] != '\'')
curly++;
}
<CURLY>\} {if (yytext[-1] != '\'')
{
if (--curly == 0)
{
BEGIN 0;
BEGIN NORM;
}
}
}
{INFNC} {if (curly > 0)
AddCalledFunc( yytext );
}
<CURLY>{IDENT}/{FNCCALL} {if (curly > 0)
AddCalledFunc( yytext );
}
<NORM>{NAME}/{F3STRT} {SetCurrentFunc( yytext );
curly = 0;
BEGIN 0;
BEGIN CURLY;
}
{CPLUSCMT} { DiscardCPlusComment(); }
{STRTCMT} { DiscardComment(); }
{NL} ;
. ;
%%
/* -------------------------- User Code Section: -------------------- */
PRIVATE void DiscardPreProc( void )
{
int ch = 0, prev = 0;
for ( ; ; )
{
SlurpMore:
while (((ch = input()) != '\n') && (ch != EOF))
prev = ch;
if (ch == '\n')
{
if (prev == '\\')
goto SlurpMore;
break;
}
if (ch == EOF)
{
fprintf( stderr, CMsg( MSG_FOUND_EOF_PREPROC, MSG_FOUND_EOF_PREPROC_STR ) );
break;
}
}
return;
}
PRIVATE void DiscardTypeDef( void )
{
int ch = 0;
for ( ; ; )
{
while (((ch = input()) != '\n') && (ch != EOF))
;
if (ch == '\n')
{
break; // Only valid exit point for the 'for ( ; ; )'.
}
if (ch == EOF)
{
fprintf( stderr, CMsg( MSG_FOUND_EOF_TYPEDEF, MSG_FOUND_EOF_TYPEDEF_STR ) );
break;
}
}
return;
}
PRIVATE void DiscardCPlusComment( void )
{
int ch = 0;
for ( ; ; )
{
while (((ch = input()) != '\n') && (ch != EOF))
;
if (ch == '\n')
{
break; // Only valid exit point for the 'for ( ; ; )'.
}
if (ch == EOF)
{
fprintf( stderr, CMsg( MSG_FOUND_EOF_COMMENT, MSG_FOUND_EOF_COMMENT_STR ) );
break;
}
}
return;
}
PRIVATE void DiscardComment( void )
{
int ch = 0;
for ( ; ; )
{
while (((ch = input()) != '*') && (ch != EOF))
;
if (ch == '*')
{
while ((ch = input()) == '*')
;
if (ch == '/')
{
break; // Only valid exit point for the 'for ( ; ; )'.
}
}
if (ch == EOF)
{
fprintf( stderr, CMsg( MSG_FOUND_EOF_COMMENT, MSG_FOUND_EOF_COMMENT_STR ) );
break;
}
}
return;
}
/* These are keywords that can be followed by parentheses & can be
** mistaken for function names:
*/
PRIVATE char *keywords[] = {
"while", "if", "for",
"sizeof", "switch", "return", NULL
};
PRIVATE BOOL CheckKeywords( char *name )
{
int i = 0;
while (keywords) // != NULL)
{
if (StringComp( keywords, name ) == 0)
{
return( TRUE );
}
i++;
}
return( FALSE );
}
PRIVATE char FilteredName[ BUFF_SIZE ] = { 0, };
PRIVATE char *FilterStars( char *text )
{
int i, j, len = StringLength( text );
// Filter off any '*' pointer stuff:
for (i = 0, j = 0; i < len; i++)
{
if (*(text + i) != '*')
{
FilteredName[j] = *(text + i);
j++;
}
}
FilteredName[j] = '\0'; // Terminate with a nil.
return( &FilteredName[0] );
}
PRIVATE int FindLastFuncEntry( struct sfuncs *FArray )
{
int i = 0;
while (i < MAXFNCTS)
{
if ( !FArray.Name) // == NULL)
break;
i++;
}
if (i == MAXFNCTS)
{
fprintf( stderr, CMsg( MSG_FMT_ARRAY_OVERFLOW, MSG_FMT_ARRAY_OVERFLOW_STR ), MAXFNCTS );
return( 0 );
}
return( i );
}
PRIVATE void IncrementUsedCount( char *funcname, struct Function *flist )
{
struct Function *found = FindFunction( funcname, flist );
if (found) // != NULL)
found->used++;
return;
}
PRIVATE BOOL ChkFuncList( char *functionname, struct Function *flist )
{
BOOL rval = FALSE;
if (!flist) // == NULL)
rval = FALSE;
else if (FindFunction( functionname, flist )) // != NULL)
rval = TRUE;
else
rval = FALSE;
return( rval );
}
PRIVATE char temp[ BUFF_SIZE ] = { 0, };
#define LEFTPAREN "("
PRIVATE void StripOffGarbage( char *token )
{
int i = 0;
if (strpbrk( token, LEFTPAREN )) // != NULL)
{
while ((*(token + i) != '(') && (i < BUFF_SIZE))
temp = *(token + i++);
temp = '\0';
StringCopy( token, temp );
}
return;
}
PRIVATE void AddCalledFunc( char *ttext )
{
IMPORT struct sfuncs *FindFuncEntry( char *fname );
struct Function *newfp = NULL, *fp = NULL, *prev = NULL;
struct sfuncs *sfptr = NULL;
char *name = NULL, outFName[512] = { 0, };
int fidx = 0;
// Strip off any garbage after the identifier (if any):
StripOffGarbage( ttext );
if (CheckKeywords( ttext ) == TRUE)
{
return;
}
StringCopy( &outFName[0], FilterStars( ttext ) );
sfptr = FindFuncEntry( outFName );
fidx = FindLastFuncEntry( &SFuncs[0] );
if (ChkFuncList( outFName, CurrentModule->deffncs ) == TRUE)
{
// Function already in the Defined function list.
IncrementUsedCount( outFName, CurrentModule->deffncs );
}
else if (CurrentModule->deffncs->calls
&& (ChkFuncList( outFName, CurrentModule->deffncs->calls ) == TRUE))
{
// Function already in the function list:
IncrementUsedCount( outFName, CurrentModule->deffncs->calls );
}
/* We still have to add outFName to the CurrentFuncDefn even if
** it's part of the CurrentModule->deffncs:
*/
if (CurrentFuncDefn->calls && (ChkFuncList( outFName, CurrentFuncDefn->calls ) == TRUE))
{
// Function already in the function list, increment & return:
IncrementUsedCount( outFName, CurrentFuncDefn->calls );
}
else
{
// New function call space needed:
if ( !CurrentFuncDefn->calls) // == NULL)
{
newfp = (struct Function *) AllocVec( sizeof( struct Function ), MEMF_FLAGS );
if ( !newfp ) // == NULL)
{
DisplayAarrgghh( CMsg( MSG_NO_MEMORY, MSG_NO_MEMORY_STR ),
CMsg( MSG_SYSTEM_PROBLEM, MSG_SYSTEM_PROBLEM_STR )
);
return;
}
CurrentFuncDefn->calls = newfp; // First time in the list.
fp = newfp;
}
else
{
fp = prev = CurrentFuncDefn->calls;
while (fp) // != NULL)
{
prev = fp;
fp = fp->next;
}
newfp = (struct Function *) AllocVec( sizeof( struct Function ), MEMF_FLAGS );
if (!newfp) // == NULL)
{
DisplayAarrgghh( CMsg( MSG_NO_MEMORY, MSG_NO_MEMORY_STR ),
CMsg( MSG_SYSTEM_PROBLEM, MSG_SYSTEM_PROBLEM_STR )
);
return;
}
prev->next = newfp;
fp = newfp;
}
name = (char *) AllocVec( StringLength( outFName ) + 1, MEMF_FLAGS );
if (!name) // == NULL)
{
prev->next = NULL;
FreeVec( newfp );
DisplayAarrgghh( CMsg( MSG_NO_MEMORY, MSG_NO_MEMORY_STR ),
CMsg( MSG_SYSTEM_PROBLEM, MSG_SYSTEM_PROBLEM_STR )
);
return;
}
StringCopy( name, outFName );
fp->name = name;
fp->used++;
if (!sfptr) // == NULL) // Usually sfptr is NULL:
{
SFuncs[fidx].Name = fp->name;
SFuncs[fidx].Used = 0; // fp->used;
SFuncs[fidx].Parent = CurrentFuncDefn;
SFuncs[fidx].ModuleName = CurrentModule->name;
}
else
{
// ModuleName already taken care of in ReadInDefinedFuncs():
if (!sfptr->ModuleName) // == NULL)
sfptr->ModuleName = CurrentModule->name;
sfptr->Name = fp->name;
sfptr->Used = 0; // += fp->used;
sfptr->Parent = CurrentFuncDefn;
}
}
# ifdef DEBUG
fprintf( stderr, " CALL: %s()\n", outFName );
# endif
return;
}
PRIVATE int FindCurrentModule( char *ModuleName )
{
int i = 0;
while (i < MAXMODULES)
{
if (Modules.name) // != NULL)
{
if (StringComp( Modules.name, ModuleName ) == 0)
break;
}
i++;
}
return( i );
}
PRIVATE void SetCurrentFunc( char *ttext )
{
struct Function *fptr = NULL;
struct sfuncs *sfptr = NULL;
char outFName[ BUFF_SIZE ] = { 0, };
int i = 0, fidx = 0;
if (CheckKeywords( ttext ) == TRUE)
{
return; // A little whitespace would eliminate this.
}
StringCopy( &outFName[0], FilterStars( ttext ) );
sfptr = FindFuncEntry( outFName );
fidx = FindLastFuncEntry( &SFuncs[0] );
/* AddFunction() (Called in ReadInDefinedFuncs()), has allocated
** all defined functions, so FindFunction() should NEVER fail:
*/
if (!(fptr = FindFunction( outFName, CurrentModule->deffncs ))) // == NULL)
{
// Function isn't in the CurrentModule, search for it:
for (i = 0; i < MAXMODULES; i++)
{
if ((fptr = FindFunction( outFName, Modules.deffncs ))) // != NULL)
{
goto GotFuncPtr;
}
}
// This Should NEVER be called:
fprintf( stderr, CMsg( MSG_FMT_IMPOSSIBLE_COND, MSG_FMT_IMPOSSIBLE_COND_STR ),
outFName, CurrentModule->name
);
return;
}
GotFuncPtr:
fptr->used++; // used counter should NEVER move beyond one in here.
CurrentFuncDefn = fptr;
if (sfptr) // != NULL) // Usually sfptr is NOT NULL here:
{
// sfptr->Used = fptr->used;
// ModuleName already taken care of in ReadInDefinedFuncs():
if (!sfptr->ModuleName) // == NULL)
sfptr->ModuleName = CurrentModule->name;
}
else
{
SFuncs[fidx].Name = fptr->name;
SFuncs[fidx].Used = 0; // fptr->used;
SFuncs[fidx].Parent = NULL;
SFuncs[fidx].ModuleName = CurrentModule->name;
}
# ifdef DEBUG
fprintf( stderr, "\n%s() // %s\n{\n", fptr->name, CurrentModule->name );
# endif
return;
}
/****h* CProfiler/CallScan() ******************************************
*
* NAME
* CallScan()
*
* DESCRIPTION
* Scan through all the files named in the ListFileName & add
* every function call inside defined functions to the internal
* Module structures.
***********************************************************************
*
*/
PUBLIC int CallScan( char *ListFileName )
{
IMPORT FILE *yyin;
FILE *ListFP = NULL;
char ModuleName[ BUFF_SIZE ] = { 0, }, *MName = &ModuleName[0], *chk = NULL;
BOOL closeListfile = FALSE;
int rval = RETURN_OK, i = 0;
// -----------------------------------------------------------------
// InputFP = stdin;
if (!(ListFP = OpenFile( ListFileName, "r" ))) // == NULL)
{
rval = IoErr();
fprintf( stderr, CMsg( MSG_FMT_NO_READ_FILEOPEN, MSG_FMT_NO_READ_FILEOPEN_STR ),
ListFileName
);
goto ExitCallScan;
}
closeListfile = TRUE;
// Read in the first Module Name to Scan:
if (!(chk = FGetS( MName, BUFF_SIZE, ListFP ))) // == NULL)
{
fprintf( stderr, CMsg( MSG_EMPTY_FILE_FOUND, MSG_EMPTY_FILE_FOUND_STR ),
ListFileName
);
rval = RETURN_ERROR;
goto ExitCallScan;
}
// The main processing-of-the-Modules loop:
i = 0; // Starting index = 0 for Modules[].
while (chk && ModuleName && (strlen( ModuleName ) > 0)
&& (i < MAXMODULES))
{
if (!(InputFP = OpenFile( MName, "r" ))) // == NULL)
{
rval = IoErr();
fprintf( stderr, CMsg( MSG_FMT_NO_READ_FILEOPEN, MSG_FMT_NO_READ_FILEOPEN_STR ),
MName
);
goto ExitCallScan;
}
// Module structures have already been setup:
MName = strlwr( &ModuleName[0] ); // From Cp.c file
i = FindCurrentModule( MName );
CurrentModule = &Modules;
CurrentMIndex = i;
CurrentFuncDefn = CurrentModule->deffncs;
# ifdef DEBUG
fprintf( stderr, CMsg( MSG_FMT_PROC_MOD_FUNCS, MSG_FMT_PROC_MOD_FUNCS_STR ), MName );
# endif
sprintf( ErrMsg, CMsg( MSG_FMT_PROC_MOD_FUNCS, MSG_FMT_PROC_MOD_FUNCS_STR ), MName );
ShowStatus( ErrMsg );
StringCopy( CurrentModuleName, MName );
yyin = InputFP;
BEGIN NORM;
yylex(); // Find those function calls!
if (InputFP && InputFP != stdin)
{
fclose( InputFP );
InputFP = NULL;
}
chk = FGetS( MName, BUFF_SIZE, ListFP );
}
// All done, Close the file(s) & exit:
ExitCallScan:
if (closeListfile == TRUE)
fclose( ListFP );
return( rval );
}
/* ---------------- END of CPCallScan.flex file! --------------- */