⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Coware的LISA指令集描述语言开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "main.h"


/*
	GLOBALS
*/

FILE *inpstream;				// input stream file descriptor
FILE *outstream;				// output stream file descriptor
char  line[INP_MAX_CHAR+1];		// input readed line
int   line_index;				// current char for readed line
int   line_count;				// current line number
char *script;					// script block buffer
int   script_index;				// current char for stored script block
lisa_environment *global_env;	// ptr to global environment structure

struct lisa_database database;		// this is THE database structure
char *xmldbfile = "config.xml";	// name of the database xml file





/*
	main entry
*/
int main( int argc, char *argv[] )
{
	char ch;
	lisa_node *n, *tmp;	// ptr to a single node
	lisa_node *tree;		// ptr to APT
	int file_name;

	if ( argc == 1 )
	{
		// If no arguments we call the Usage routine and exit
		// Usage( APP_NAME );
		// return 1;
	}

	// NOTE: (2002-07-03 Gabriele Budelacci)
	// The global environment is created in HandleOption procedure...

	// handle the program options
	file_name = HandleOptions( argc, argv );

	if ( file_name == 0 )
	{
		inpstream = stdin;
		outstream = stdout;
		// comment the follow lines in debug versions...
		fprintf( stderr, "%s: No input files\n", APP_NAME );
		exit( 1 );
	}
	else
	{
		char *extension = NULL;

		inpstream = fopen( argv[ file_name ], "r" );
		// using line[] buffer for managing output stream name...
		strncpy( line, argv[ file_name ], INP_MAX_CHAR );
		// find the extension
		extension = strrchr( line, '.' );
		if ( ! extension )
		{
			// no extension founded, placing at the end of input file name
			extension = line + strlen( line );
		}
		switch ( global_env->language )
		{
			case LISA_LANG_PHP:
			{
				strncpy( extension, ".php", 8 );
				outstream = fopen( line, "w" );
				break;
			}
			case LISA_LANG_NONE:
			{
				outstream = stdout;
				break;
			}
		}
	}

	// handling error on streams...
	if ( ! inpstream )
	{
		fprintf( stderr, "Unable to open file: %s\n", argv[ file_name ] );
		exit( 0 );
	}
	if ( ! outstream )
	{
		fprintf( stderr, "Unable to open file: %s\n", argv[ file_name ] );
		exit( 0 );
	}

	line[0] = '\0';		// empty readed line
	line_index = 0;		// current char for readed line
	line_count = 1;		// current line number
	// this string is reserved for script blocks...
	script = (char*) malloc( SCRIPT_MAX_CHAR );
	// NOTE: (2002-06-25 Gabriele Budelacci)
	//	"script" is allocated dinamically, so if you need
	//	more space, you can specify it via a compiler option.
	script_index = 0;	// current char for stored script block

	// inp = fopen( argv[ file_name ], "r" );

	// processing database xml comfiguration file...
	processXMLDatabase( &database, xmldbfile );

	switch ( global_env->language )
	{
		case LISA_LANG_PHP:
		{
			// create the database driver only if module generation is disabled...
			if ( global_env->module == LISA_MODULE_OFF )
			{
				switch ( database.type )
				{
					case LISA_DBTYPE_MYSQL:
					{
						writeMySQLdriver( database.host, database.name, database.username, database.password );
						break;
					}
					case LISA_DBTYPE_ODBC:
					{
						writeODBCdriver( database.dsn, database.username, database.password );
						break;
					}
				}
			}

			// write headers only if module generation is disabled...
			if ( global_env->module == LISA_MODULE_OFF )
			{
				fprintf( outstream, "<?\n" );
				fprintf( outstream, "session_start();\n" );
				fprintf( outstream, "session_register( \"SESSION\" );\n" );
				fprintf( outstream, "if ( ! isset( $SESSION ) )\n" );
				fprintf( outstream, "{\n" );
				fprintf( outstream, "\t$SESSION['_l_s_i_'] = 0;\n" );
				fprintf( outstream, "}\n" );
				fprintf( outstream, "mt_srand ((double) microtime() * 1000000);\n" );
				fprintf( outstream, "require( 'std.php' );\n" );
				if ( database.valid )
				{
					fprintf( outstream, "$_link_ = 0;\n" );
					fprintf( outstream, "$_array_ = array();\n" );
					fprintf( outstream, "require( 'dbsupport.php' );\n" );
					fprintf( outstream, "_database_();\n" );
				}
				fprintf( outstream, "?>\n" );
			}
			break;
		}
	}

	while ( 1 )
	{
		// processing HTML code...
//debug( "processing HTML code..." );
		ch = processHTML();

		switch ( ch )
		{
			// EOF reached if ch==0...
			case 0:
			{
				switch ( global_env->language )
				{
					case LISA_LANG_PHP:
					{
						// write headers only if module generation is disabled...
						if ( global_env->module == LISA_MODULE_OFF )
						{
							if ( database.valid )
							{
								fprintf( outstream, "<?\n" );
								fprintf( outstream, "_close_();\n" );
								fprintf( outstream, "?>\n" );
							}
						}
						break;
					}
				}
				exit( 0 );
			}

			// Script block...
			case '%':
				// get the whole script block...
//debug( "get the whole script block..." );
				getScript();
				// APT is empty initially
				tree = createNode();
				tmp = tree;
				// initialize the parser
				initParser();
				// read the first node
				n = lex( LISA_SCOPE_EXPRESSION | LISA_SCOPE_STATEMENT | LISA_SCOPE_EMPTY );
				// if it's a TAG type node, then break...
				if ( n->type != LISA_TYPE_TAGKEYWORD )
				{
					// read the other nodes...
					while ( ! emptyNode( n ) )
					{
						tmp->next = n;
						tmp = n;
						n = lex( LISA_SCOPE_EXPRESSION | LISA_SCOPE_STATEMENT | LISA_SCOPE_EMPTY );
					}
				}
				else
				{
					if ( n->next == 0 )
						n->next = createNode();
				}
				tmp->next = n;
				// NOTE: (2002-07-06 Gabriele Budelacci)
				//	Others statements in the same block of a TAG keyword
				//	are discarged, an this isn't a good idea!!!

				tmp = tree->next;
				if ( ! emptyNode( tmp ) )
				{
					startScript();

					// evaluating...
					while ( ! emptyNode( tmp ) )
					{
						eval( tmp, global_env );
						tmp = tmp->next;
					}

					stopScript();
				}

				// destroying APT...
				destroyNodeR( tree );

				break;

			// Expression value...
			case '=':
				// get the whole script block...
				getScript();
				// APT is empty initially
				tree = createNode();
				// initialize the parser
				initParser();
				// read the first node
				n = lex( LISA_SCOPE_CONDITION | LISA_SCOPE_STATEMENT | LISA_SCOPE_EMPTY );

				// NOTE: (2002-07-02 Gabriele Budelacci)
				//	I must create a dummy node for condition evaluation.
				tree->next = createNode();
				tree->next->type = LISA_TYPE_CONDITION;
				tree->next->args = n;

				// check if another node
				n = lex( LISA_SCOPE_EXPRESSION | LISA_SCOPE_SEMICOLON | LISA_SCOPE_EMPTY );
				if ( ! emptyNode( n ) )
					error( "no more than one expressions allowed" );
				tree->next->next = n;

				tmp = tree->next;
				if ( ! emptyNode( tmp ) )
				{
					startExpression();

					// evaluating...
					eval( tmp, global_env );

					stopScript();
				}

				// destroying APT...
				destroyNodeR( tree );

				break;

			// Unimplemented code...
			default:
				error( "INTERNAL ERROR:\n\tUnimplemented block type" );
		}
	}

	// closing input stream...
	fclose( inpstream );
	// closing output stream...
	fclose( outstream );

	exit( 0 );
	return 0;
}//main





// HandleOptions:
//	returns the index of the first argument that is not an option; i.e.
//	does not start with a dash or a slash.
int HandleOptions( int argc,char *argv[] )
{
	int i, firstnonoption = 0;
	int language, module;

	// NOTE: (2002-06-27 Gabriele Budelacci)
	// I use PHP language for debugging. The language selection
	// must be performed via a --option to the compiler...
	language = LISA_LANG_NONE;
	// by default, module generation is disabled:
	module = LISA_MODULE_OFF;

	for ( i=1 ; i<argc ; i++ )
	{
		if ( argv[i][0] == '/' || argv[i][0] == '-')
		{
			switch ( argv[i][1] )
			{
				// An argument -? means help is requested
				case '?':
					Usage( APP_NAME );
					break;
				case 'h':
				case 'H':
					if ( !strcmp( argv[i]+1, "help" ) )
					{
						Usage( APP_NAME );
						return 0;
					}
					/* If the option -h means anything else
					   in your application add code here
					   Note: this falls through to the default
					   to print an "unknow option" message
					*/
					return 0;
					break;
				case 'm':
					module = LISA_MODULE_ON;
					break;
				case 'p':
					language = LISA_LANG_PHP;
					break;
				case '-':
					if ( !strcmp( argv[i]+2, "help" ) )
					{
						Usage( APP_NAME );
						exit( 0 );
					}
					if ( !strcmp( argv[i]+2, "module" ) )
					{
						module = LISA_MODULE_ON;
						break;
					}
					if ( !strcmp( argv[i]+2, "php" ) )
					{
						language = LISA_LANG_PHP;
						break;
					}
					if ( !strcmp( argv[i]+2, "version" ) )
					{
						Version();
						exit( 0 );
						break;
					}
					/* If the option -h means anything else
					   in your application add code here
					   Note: this falls through to the default
					   to print an "unknow option" message
					*/
					break;
				// add your option switches here
				default:
					fprintf( stderr, "unknown option %s\n", argv[i] );
					break;
			}
		}
		else
		{
			firstnonoption = i;
			break;
		}
	}

	// creating the global environment correctly
	global_env = createEnvironment( language );
	global_env->module = module;

	return firstnonoption;

}//HandleOptions





// Usage:
//	Display 'usage' string information.
void Usage( char *programName )
{
	fprintf( stderr, "\nusage: %s [options] filename\n\n", APP_NAME );
	fprintf( stderr, "Recognized options are:\n" );
	fprintf( stderr, "\n" );
	fprintf( stderr, "\t--asp, -a\tSet ASP target language (unimplemented yet)\n" );
	fprintf( stderr, "\t--jsp, -j\tSet JSP target language (unimplemented yet)\n" );
	fprintf( stderr, "\t--php, -p\tSet PHP target language\n" );
	fprintf( stderr, "\n" );
	fprintf( stderr, "\t--module, -m\tGenerate a module\n" );
	fprintf( stderr, "\n" );
	fprintf( stderr, "\t--help, -h\tShow this message\n" );
	fprintf( stderr, "\t--version\tShow version information\n" );
	fprintf( stderr, "\n" );
	fprintf( stderr, "%s v%s, %s\n", APP_NAME, APP_VERSION, APP_DATE );
	fprintf( stderr, "Copyright (c)2002 Gabriele Budelacci\n" );
	fprintf( stderr, "See COPYING file for license\n" );
	/* Modify here to add your usage message when the program is
	 * called without arguments */
}//Usage





// Version:
//	Display 'version' information.
void Version( void )
{
	fprintf( stderr, "%s v%s, %s\n", APP_NAME, APP_VERSION, APP_DATE );
}//Version





// appendNode:
//	Append a node to the specified list.
void appendNode( lisa_node *node, lisa_node *list )
{
	struct lisa_node *tmp;

	if ( list )
	{
		tmp = list;
		// scan for end of list...
		while ( tmp->next )
			tmp = tmp->next;
		// appending the node...
		tmp->next = node;
	}
}//appendNode





// createEnvironment:
//	Create an environment structure.
lisa_environment *createEnvironment( int language )
{
	lisa_environment *env = malloc( sizeof( lisa_environment ) );
	if ( env )
	{
		env->global     = env;
		env->parent     = env;
		env->language   = language;
		env->module     = LISA_MODULE_OFF;
		env->globals    = createNode();
		env->parameters = createNode();
		env->declared   = createNode();
		env->loops      = createNode();
	}
	return env;
}//createEnvironment





// childEnvironment:
//	Clone an environment for a child script block.
lisa_environment *childEnvironment( lisa_environment *env )
{
	struct lisa_environment *e = NULL;
	struct lisa_node        *n = NULL;

	if ( env )
	{
		// creating the new environment...
		e = createEnvironment( LISA_LANG_NONE );
		// ...and filling with existing data...
		memcpy( e, env, sizeof( lisa_environment ) );
		e->globals    = cloneNode( env->globals );
		e->parameters = cloneNode( env->parameters );
		e->declared   = cloneNode( env->declared );
		e->loops      = cloneNode( env->loops );
		// making global variables unchangeable...
		n = e->declared->next;	// skip initial empty node
		while ( n )
		{
			if ( findNodeByElement( n->element, e->globals ) )
			{
				if ( n->type > 0 ) n->type = -n->type;
			}
			else
			{
				if ( n->type < 0 ) n->type = -n->type;
			}
			n = n->next;
		}
		// ...last, setting the parent environment...
		e->parent  = env;
	}
	return e;
}//childEnvironment




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -