%{
/*---------McGill-Computer-Vision-and-Robotics-Laboratory--C-Module---------
 *		
 * NAME:	fxref
 *
 * USAGE:	fxref files ...  > output_stream
 *
 * DESCRIPTION: A program which takes a C source and produces a listing of all
 *		defined functions (or macros), and the functions (or macros)
 *		which they in turn reference.
 *
 *		The source is taken from either files given in the command
 *		line, or off the standard input, and the listing 
 *		is put onto the standard output.
 *
 *		The output is a series of entries of the form:
 *		
 *			function	: filename
 *			  call1
 *			  call2
 *			  call3
 *
 *		where 'function' is the beast defined, 'filename' is the file
 *		where it is defined, and 'call1' through 'call3' are functions
 *		which it referenced.
 *
 * FILES:	fxref.lex, the specification for the lexical scanner;
 *		fxref.c, the source for the subroutines
 *		Lex fxref.lex and compile lex.yy.c; it #includes fxref.c.
 *
 * AUTHOR:	Mike Parker, with emotional support from John lloyd
 *
 *-------------McGill-Computer-Vision-and-Robotics-Laboratory--------------*/
#include <ctype.h>
static int brace_level;
static int commenting;
static int quoting;
static int insideDefine = 0;
static int lineNo = 1;
static int debug = 0;
char *index();
%}
%start NORM DEFINE QUOTING COMMENTING
ident	[a-zA-Z$_][a-zA-Z$_0-9]*
w	[ \t\n]*
ww	[ \t\n]+
%%
<NORM,DEFINE>{ident}/{w}"("{w}")"{w}(";"|",") { if (brace_level > 0)
				    { is_called(yytext);
				    }
				 }
<NORM,DEFINE>E[A-Z][A-Za-z]*	{ if (brace_level > 0)
				   { errorUsed(yytext);
				   }
				}
<NORM,DEFINE>{ident}/{w}"("		{ if (brace_level == 0)
			   { is_defined(yytext,1);
			   }
			  else
			   { is_called(yytext);
			   }
			}
<NORM>^#{w}define{ww}{ident}/{ww} { char *cp;
			      cp = index(yytext,'d') + 6;
			      while (isspace(*++cp)) ;
			      is_sharp_defined(cp,0);
			      BEGIN DEFINE;
			      if (debug) printf ("begin DEFINE\n");
			      insideDefine = 1;
			      brace_level ++;
			    }
<NORM>^#{w}define{ww}{ident}/"("  { char *cp;
			      cp = index(yytext,'d') + 6;
			      while (isspace(*++cp)) ;
			      is_sharp_defined(cp,1);
			      BEGIN DEFINE;
			      if (debug) printf ("begin DEFINE\n");
			      insideDefine = 1;
			      brace_level ++;
			    }
<DEFINE>"\\\n"		{ lineNo++;
			  if (debug) printf ("line %d\n", lineNo);
			}
<DEFINE>"\n"		{ brace_level --;
			  end_sharp_define();
			  if (debug) printf ("BEGIN NORM\n");
			  BEGIN NORM;
			  insideDefine = 0;
			  lineNo++;
			  if (debug) printf ("line %d\n", lineNo);
			}
<NORM>"{"		{ brace_level ++;
			}
<NORM>"}"		{ brace_level --;
			}
<NORM,DEFINE>"/*"	{ BEGIN COMMENTING;
			  if (debug) printf ("BEGIN COMMENTING\n");
			}
<COMMENTING>"*/"	{ if (insideDefine)
			   { BEGIN DEFINE;
			     if (debug) printf ("BEGIN DEFINE\n");
			   }
			  else
			   { BEGIN NORM;
			     if (debug) printf ("BEGIN NORM\n");
			   }
			}
<NORM,DEFINE>'([^']|\\')*' { if (debug) printf ("Quote: %s\n", yytext);
			}
<NORM,DEFINE>\"		{ BEGIN QUOTING;
			  if (debug) printf ("BEGIN QUOTING\n");
			}
<QUOTING>\\\"		;
<QUOTING>\"		{ if (insideDefine)
			   { BEGIN DEFINE;
			     if (debug) printf ("BEGIN DEFINE\n");
			   }
			  else
			   { BEGIN NORM;
			     if (debug) printf ("BEGIN NORM\n");
			   }
			}
.			;
"\n"			{ lineNo++;
			  if (debug) printf ("line %d\n", lineNo);
			}
%%
#include "fxref.c"
