/* dirty.c  MR Jun 2001
   Generate a calling tree from a C source file that has already
   been filtered through 'clscanc2.sh' (which uses a lexer generated
   from "csimple2.l").
*/

#include <stdio.h>
#include <string.h>

typedef int _bool;

int main( int argc, char ** argv )
	{
	char buf[256];
	char k;
	char bufpr[256];
	char kpr;
	char save1[256];
	int roundbrlevel = 0;
	int curlybrlevel = 0;
	int alert1 = 0;

	_bool _d = ( argc > 1 ); //"Debug"

	strcpy( buf, "" );
	k = 0x00;

	while ( kpr = k, 
	   strcpy( bufpr, buf+1 ),
	   fscanf( stdin, " %s", buf ) == 1 )
		{
		if(_d) { printf( "\tc%d r%d [%s]\n", 
		           curlybrlevel, roundbrlevel, buf ); }

		k = buf[0];

		if ( kpr == 'I' && k == '(' )
			{
			if ( curlybrlevel > 0 )
				{ /* Function call inside a function
				     definition body */
				printf( "c %s %s\n", 
				   save1, bufpr );
				}
			else
				{ /* Possible start of fnc decl/def */
				strcpy( save1, bufpr );
				alert1 = 1;
				if(_d) { printf( "\tsave1:=[%s]\n", save1 ); }
				}
			}
		else if ( roundbrlevel == 0 && alert1 &&
		   curlybrlevel == 0 && kpr == ')' && k == '{' )
			{ /* Function definition, now at opening '{' */
			printf( "{ %s\n", save1 );
			}
		else if ( roundbrlevel == 0 && alert1 &&
		   curlybrlevel == 0 && kpr == ')' && k == ';' )
			{ /* Function declaration */
			printf( "d %s\n", save1 );
			alert1 = 0;
			}
		else if ( alert1 && k == '}' && curlybrlevel == 1 )
			{ /* Function definition, now at closing '}' */
			printf( "} %s\n", save1 );
			alert1 = 0;
			}


		if ( k == '(' ) { roundbrlevel++; }
		if ( k == ')' ) { roundbrlevel--; }
		if ( k == '{' ) { curlybrlevel++; }
		if ( k == '}' ) { curlybrlevel--; }

		if ( roundbrlevel < 0 )
			{
			fprintf( stderr, "dirty2 ERROR: roundbrlevel < 0\n" );
			return -1;
			}
		if ( curlybrlevel < 0 )
			{
			fprintf( stderr, "dirty2 ERROR: curlybrlevel < 0\n" );
			return -1;
			}

		}

	return 0;
	}
