📄 main.c
字号:
#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 + -