flex usage & input() function

This forum is for general developer support questions.
Post Reply
JosDuchIt
Posts: 291
Joined: Sun Jun 26, 2011 5:47 pm
Contact:

flex usage & input() function

Post by JosDuchIt »

I am trying to understand and modify the .flex file below (making it produce a directly usable cli command that generates files corresponding to the produced structures)

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! --------------- */
Belxjander
Posts: 314
Joined: Mon May 14, 2012 10:26 pm
Location: 日本千葉県松戸市 / Matsudo City, Chiba, Japan
Contact:

Re: flex usage & input() function

Post by Belxjander »

I get the idea it is part of what flex would produce...
JosDuchIt
Posts: 291
Joined: Sun Jun 26, 2011 5:47 pm
Contact:

Re: flex usage & input() function

Post by JosDuchIt »

I guess so, had hoped i didn't have to feed the source to flex for debugging it further.
Could i use an other function just for debugging sake?
User avatar
polluks
Posts: 55
Joined: Tue May 19, 2015 6:30 pm
Location: Germany
Contact:

Re: flex usage & input() function

Post by polluks »

for the record:

Code: Select all

# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)
Post Reply