Pol  Revision:b38175a
runecl/runecl.cpp
Go to the documentation of this file.
00001 /*
00002 History
00003 =======
00004 
00005 Notes
00006 =======
00007 
00008 */
00009 
00010 #include "../clib/clib.h"
00011 #include "../clib/logfacility.h"
00012 
00013 #include "../bscript/config.h"
00014 #include "../bscript/eprog.h"
00015 #include "../bscript/escriptv.h"
00016 #include "../bscript/filefmt.h"
00017 #include "../bscript/tokens.h"
00018 #include "../bscript/symcont.h"
00019 #include "../bscript/token.h"
00020 #include "../bscript/execmodl.h"
00021 #include "../bscript/executor.h"
00022 
00023 #include "../pol/sqlscrobj.h"
00024 #include "../clib/cmdargs.h"
00025 #include "../clib/cfgelem.h"
00026 
00027 #include "../pol/module/basicmod.h"
00028 #include "../pol/module/basiciomod.h"
00029 #include "../pol/module/mathmod.h"
00030 #include "../pol/module/sqlmod.h"
00031 #include "../pol/module/utilmod.h"
00032 #include "../pol/module/filemod.h"
00033 #include "../pol/module/cfgmod.h"
00034 #include "../pol/module/datastore.h"
00035 
00036 #include "../pol/polcfg.h"
00037 
00038 #include "../clib/timer.h"
00039 
00040 #include <cstring>
00041 #include <cstdio>
00042 #include <ctime>
00043 
00044 #include <iostream>
00045 #include <iomanip>
00046 
00047 #ifdef _MSC_VER
00048 #pragma warning(disable:4996) // disable deprecation warning strcpy 
00049 #endif
00050 
00051 
00052 namespace Pol {
00053   namespace Bscript {
00054     void display_bobjectimp_instances();
00055   }
00056   namespace Runecl {
00057     using namespace Bscript;
00058     using namespace Module;
00059 #if REFPTR_DEBUG
00060     unsigned int ref_counted::_ctor_calls;
00061 #endif
00062 
00063     int quiet = 0;
00064     int debug = 0;
00065     bool profile = false;
00066     void usage( void )
00067     {
00068       ERROR_PRINT << "  Usage:\n"
00069         << "    " << "RUNECL [options] filespec [filespec ...]\n"
00070         << "        Options:\n"
00071         << "            -q    Quiet\n"
00072         << "            -d    Debug output\n"
00073         << "            -p    Profile\n";
00074     }
00075 
00076     void DumpCaseJmp( std::ostream& os, const Token& token, EScriptProgram* /*prog*/ )
00077     {
00078       const unsigned char* dataptr = token.dataptr;
00079       for ( ;; )
00080       {
00081         unsigned short offset = *(const unsigned short*)dataptr;
00082         dataptr += 2;
00083         unsigned char type = *dataptr;
00084         dataptr += 1;
00085         if ( type == CASE_TYPE_LONG )
00086         {
00087           unsigned int lval = *(const unsigned int*)dataptr;
00088           dataptr += 4;
00089           os << "\t" << lval << ": @" << offset << std::endl;
00090         }
00091         else if ( type == CASE_TYPE_DEFAULT )
00092         {
00093             os << "\tdefault: @" << offset << std::endl;
00094           break;
00095         }
00096         else
00097         { // type is the length of the string, otherwise
00098             os << "\t\"" << std::string((const char*)dataptr, type) << "\": @" << offset << std::endl;
00099           dataptr += type;
00100         }
00101       }
00102     }
00103 
00104     Bscript::BObjectImp::BObjectType ot = Bscript::BObjectImp::OTLong;
00105     BApplicObjType aot;
00106     int x;
00107 
00108     void foo( BApplicObjType* laot, Bscript::BObjectImp::BObjectType lot )
00109     {
00110       if ( laot == &aot )
00111       {
00112         x = 5;
00113       }
00114 
00115       if ( lot == Bscript::BObjectImp::OTLong )
00116       {
00117         x = 6;
00118       }
00119     }
00120 
00121     void DumpScript( const char *path )
00122     {
00123         std::string fname(path);
00124       if ( fname.size() >= 4 )
00125         fname.replace( fname.size() - 4, 4, ".ecl" );
00126 
00127       Executor E;
00128       E.setViewMode( true );
00129       E.addModule( new BasicExecutorModule( E ) );
00130       E.addModule( new BasicIoExecutorModule( E ) );
00131       E.addModule( new MathExecutorModule( E ) );
00132       //E.addModule( new SQLExecutorModule( E ) );
00133       E.addModule( new UtilExecutorModule( E ) );
00134       E.addModule( new FileAccessExecutorModule( E ) );
00135       E.addModule( new ConfigFileExecutorModule( E ) );
00136       E.addModule( new DataFileExecutorModule( E ) );
00137 
00138       ref_ptr<EScriptProgram> program( new EScriptProgram );
00139       program->read( fname.c_str() );
00140       E.setProgram( program.get() );
00141 
00142       std::ostringstream os;
00143       program->dump( os );
00144       INFO_PRINT << os.str();
00145 
00146       /* return;
00147 
00148           Token token;
00149           unsigned PC;
00150           for( PC = 0; PC < E.nLines; PC++ )
00151           {
00152           if (E.getToken(token, PC))
00153           {
00154           return;
00155           }
00156           else
00157           {
00158           cout << PC << ": " << token;
00159           if (debug) cout << " (" << token.id << "," << token.type << ")";
00160           cout << endl;
00161           if (token.id == INS_CASEJMP)
00162           {
00163           DumpCaseJmp( cout, token, program.get() );
00164           }
00165           }
00166           }
00167           */
00168     }
00169 
00170     
00171     int exec_script( const char *path )
00172     {
00173       std::string fname(path);
00174       // TODO: autoconvert to .ecl ?
00175       bool exres;
00176       double seconds;
00177       size_t memory_used;
00178       clock_t clocks;
00179 #ifdef _WIN32
00180       FILETIME dummy;
00181       FILETIME kernelStart, userStart;
00182       FILETIME kernelEnd, userEnd;
00183 #endif
00184 
00185       {
00186         Executor E;
00187         E.addModule( new BasicExecutorModule( E ) );
00188         E.addModule( new BasicIoExecutorModule( E ) );
00189         E.addModule( new MathExecutorModule( E ) );
00190         //E.addModule( new SQLExecutorModule( E ) );
00191         E.addModule( new UtilExecutorModule( E ) );
00192         E.addModule( new FileAccessExecutorModule( E ) );
00193         E.addModule( new ConfigFileExecutorModule( E ) );
00194         E.addModule( new DataFileExecutorModule( E ) );
00195 
00196         ref_ptr<EScriptProgram> program( new EScriptProgram );
00197         if ( program->read( fname.c_str() ) )
00198         {
00199           ERROR_PRINT << "Error reading " << fname << "\n";
00200           return 1;
00201         }
00202         E.setProgram( program.get() );
00203 
00204         E.setDebugLevel( debug ? Executor::INSTRUCTIONS : Executor::NONE );
00205         clock_t start = clock();
00206 #ifdef _WIN32
00207         GetThreadTimes( GetCurrentThread(), &dummy, &dummy, &kernelStart, &userStart );
00208 #endif
00209 
00210         exres = E.exec();
00211       
00212 #ifdef _WIN32
00213         GetThreadTimes( GetCurrentThread(), &dummy, &dummy, &kernelEnd, &userEnd );
00214 #endif
00215         clocks = clock() - start;
00216         seconds = static_cast<double>( clocks ) / CLOCKS_PER_SEC;
00217 
00218         memory_used = E.sizeEstimate();
00219       }
00220 
00221       if ( profile )
00222       {
00223         fmt::Writer tmp;
00224         tmp << "Profiling information: \n"
00225           << "\tEObjectImp constructions: " << eobject_imp_constructions << "\n";
00226         if ( eobject_imp_count )
00227           tmp << "\tRemaining BObjectImps: " << eobject_imp_count << "\n";
00228         tmp << "\tInstruction cycles: " << escript_instr_cycles << "\n"
00229           << "\tInnerExec calls: " << escript_execinstr_calls << "\n"
00230           << "\tClocks: " << clocks << " (" << seconds << " seconds)" << "\n"
00231 #ifdef _WIN32
00232           << "\tKernel Time: " << ( *(__int64*)&kernelEnd ) - ( *(__int64*)&kernelStart ) << "\n"
00233           << "\tUser Time:   " << ( *(__int64*)&userEnd ) - ( *(__int64*)&userStart ) << "\n"
00234 #endif
00235           << "\tSpace used: " << memory_used << "\n\n"
00236 
00237           << "\tCycles Per Second: " << escript_instr_cycles / seconds << "\n"
00238           << "\tCycles Per Minute: " << 60.0 * escript_instr_cycles / seconds << "\n"
00239           << "\tCycles Per Hour:   " << 3600.0 * escript_instr_cycles / seconds << "\n";
00240 #if BOBJECTIMP_DEBUG
00241         display_bobjectimp_instances();
00242 #endif
00243 #ifdef ESCRIPT_PROFILE
00244         tmp << "FuncName,Count,Min,Max,Sum,Avarage\n";
00245         for (escript_profile_map::iterator itr=EscriptProfileMap.begin();itr!=EscriptProfileMap.end();++itr)
00246         {
00247           tmp << itr->first << "," << itr->second.count << "," << itr->second.min << "," << itr->second.max << "," << itr->second.sum << "," 
00248             << (itr->second.sum / itr->second.count) << "\n";
00249         }
00250 #endif
00251         INFO_PRINT << tmp.str();
00252       }
00253       return exres ? 0 : 1;
00254     }
00255 
00256     int run( int argc, char **argv )
00257     {
00258       for ( int i = 1; i < argc; i++ )
00259       {
00260         switch ( argv[i][0] )
00261         {
00262           case '/': case '-':
00263             switch ( argv[i][1] )
00264             {
00265               case 'a': case 'A':
00266               case 'd': case 'D':
00267               case 'v': case 'V':
00268               case 'q': case 'Q':
00269               case 'p': case 'P':
00270                 break;
00271               default:
00272                 ERROR_PRINT << "Unknown option: " << argv[i] << "\n";
00273                 usage();
00274                 return 1;
00275             }
00276             break;
00277           default:
00278             return exec_script( argv[i] );
00279         }
00280       }
00281       return 0;
00282     }
00283   }
00284   int xmain( int argc, char *argv[] )
00285   {
00286     Clib::StoreCmdArgs( argc, argv );
00287 
00288     int progver = 1;
00289 
00290     Runecl::escript_config.max_call_depth = 100;
00291     Runecl::quiet = Clib::FindArg( "q" ) ? 1 : 0;
00292     Runecl::debug = Clib::FindArg( "d" ) ? 1 : 0;
00293     Runecl::profile = Clib::FindArg( "p" ) ? 1 : 0;
00294     Clib::passert_disabled = Clib::FindArg( "a" ) ? false : true;
00295 
00296     if ( !Runecl::quiet )
00297     {
00298       // vX.YY
00299       double vernum = (double)progver + (double)( ESCRIPT_FILE_VER_CURRENT / 100.0f );
00300       ERROR_PRINT << "EScript Executor v" << vernum << "\n"
00301       << "Copyright (C) 1993-2015 Eric N. Swanson\n\n";
00302     }
00303 
00304     if ( argc == 1 )
00305     {
00306       Runecl::usage( );
00307       return 1;
00308     }
00309 
00310     const char *todump = Clib::FindArg( "v" );
00311     if ( todump )
00312     {
00313       Runecl::DumpScript( todump );
00314       return 0;
00315     }
00316 
00317     return Runecl::run( argc, argv );
00318   }
00319 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines