//---------------------------------------------------------------------------- // ArgumentHandler::parse implementation //---------------------------------------------------------------------------- int32_t ArgumentHandler::parse(int argc, _TCHAR* argv[] ) { assert( argv ); if( !m_bInitialized ) return 0; int32_t iArgsparsed = 1; //0: executable name wstring* pstrArg; wstring strNull( L"" ); while( iArgsparsed < argc ) { pstrArg = new wstring( (const wchar_t*)argv[ iArgsparsed ], wcslen( (const wchar_t*)argv[ iArgsparsed ] ) ); std::transform( pstrArg->begin(), pstrArg->end(), pstrArg->begin(), (int(*)(int))std::tolower ); if( *pstrArg->begin() == '-' ) //|| *pstrArg->begin() == '/' ) //Now only '-' is allowed as option switc { //parse options //*pstrArg->begin() = '-'; //Replace '/' map< wstring, OPTIONCALLBACK*>::iterator it; it = m_mapOptions.find( *pstrArg ); if( it != m_mapOptions.end() && it->second != NULL ) { iArgsparsed += it->second( argc - iArgsparsed, argv + iArgsparsed ); } else { if( m_pError ) { m_pError->report( ERROR_INVALIDOPTIONSWITCH, 0, 0, strNull, strNull, *pstrArg ); } iArgsparsed ++; } } else { delete pstrArg; break; } delete pstrArg; } return iArgsparsed; }
static void test_CarlaUtils() { // ---------------------------------------------------------------------------------------------------------------- // misc functions { bool2str(false); bool2str(true); pass(); char strBuf[2]; nullStrBuf(strBuf); char* const strBuf2(strBuf+1); nullStrBuf(strBuf2); } // ---------------------------------------------------------------------------------------------------------------- // string print functions { carla_debug("DEBUG"); carla_stdout("STDOUT %s", bool2str(true)); carla_stderr("STDERR %s", bool2str(false)); carla_stderr2("STDERR2 " P_UINT64, 0xffffffff); // 4294967295 } // ---------------------------------------------------------------------------------------------------------------- // carla_*sleep { carla_sleep(1); carla_msleep(1); } // ---------------------------------------------------------------------------------------------------------------- // carla_setenv { carla_setenv("THIS", "THAT"); assert(std::strcmp(std::getenv("THIS"), "THAT") == 0); carla_unsetenv("THIS"); assert(std::getenv("THIS") == nullptr); } // ---------------------------------------------------------------------------------------------------------------- // carla_strdup { // with variables const char* const str1(carla_strdup("stringN")); const char* const strF(carla_strdup_free(strdup("stringF"))); const char* const str2(carla_strdup_safe("stringS")); delete[] str1; delete[] str2; delete[] strF; // without variables delete[] carla_strdup("string_normal"); delete[] carla_strdup_free(strdup("string_free")); delete[] carla_strdup_safe("string_safe"); } { // common use case in Carla code struct TestStruct { const char* strNull; const char* strNormal; const char* strFree; const char* strSafe; TestStruct() : strNull(nullptr), strNormal(carla_strdup("strNormal")), strFree(carla_strdup_free(strdup("strFree"))), strSafe(carla_strdup_safe("strSafe")) {} ~TestStruct() noexcept { if (strNull != nullptr) { delete[] strNull; strNull = nullptr; } if (strNormal != nullptr) { delete[] strNormal; strNormal = nullptr; } if (strFree != nullptr) { delete[] strFree; strFree = nullptr; } if (strSafe != nullptr) { delete[] strSafe; strSafe = nullptr; } } CARLA_DECLARE_NON_COPY_STRUCT(TestStruct) }; TestStruct a, b, c; } // ---------------------------------------------------------------------------------------------------------------- // memory functions { int a1[] = { 4, 3, 2, 1 }; int a2[] = { 4, 3, 2, 1 }; int b1[] = { 1, 2, 3, 4 }; int b2[] = { 1, 2, 3, 4 }; carla_add(a1, b1, 4); assert(a1[0] == 5); assert(a1[1] == 5); assert(a1[2] == 5); assert(a1[3] == 5); carla_add(b1, a2, 4); assert(b1[0] == 5); assert(b1[1] == 5); assert(b1[2] == 5); assert(b1[3] == 5); assert(a1[0] == b1[0]); assert(a1[1] == b1[1]); assert(a1[2] == b1[2]); assert(a1[3] == b1[3]); carla_copy(a1, b2, 4); assert(a1[0] != b1[0]); assert(a1[1] != b1[1]); assert(a1[2] != b1[2]); assert(a1[3] != b1[3]); assert(a1[0] == b2[0]); assert(a1[1] == b2[1]); assert(a1[2] == b2[2]); assert(a1[3] == b2[3]); carla_copy(a1, b1, 4); assert(a1[0] == b1[0]); assert(a1[1] == b1[1]); assert(a1[2] == b1[2]); assert(a1[3] == b1[3]); carla_copy(a1, b2, 2); assert(a1[0] != b1[0]); assert(a1[1] != b1[1]); assert(a1[2] == b1[2]); assert(a1[3] == b1[3]); carla_copy(a1+2, b2+2, 2); assert(a1[0] != b1[0]); assert(a1[1] != b1[1]); assert(a1[2] != b1[2]); assert(a1[3] != b1[3]); carla_copy(a1, b1, 2); assert(a1[0] == b1[0]); assert(a1[1] == b1[1]); assert(a1[2] != b1[2]); assert(a1[3] != b1[3]); carla_copy(a1+2, b1+2, 2); assert(a1[0] == b1[0]); assert(a1[1] == b1[1]); assert(a1[2] == b1[2]); assert(a1[3] == b1[3]); carla_fill(a1, 0, 4); assert(a1[0] == 0); assert(a1[1] == 0); assert(a1[2] == 0); assert(a1[3] == 0); carla_fill(a1, -11, 4); assert(a1[0] == -11); assert(a1[1] == -11); assert(a1[2] == -11); assert(a1[3] == -11); carla_fill(a1, 1791, 2); assert(a1[0] == 1791); assert(a1[1] == 1791); assert(a1[2] == -11); assert(a1[3] == -11); carla_fill(a1+2, 1791, 2); assert(a1[0] == 1791); assert(a1[1] == 1791); assert(a1[2] == 1791); assert(a1[3] == 1791); int16_t d = 1527, e = 0; carla_add(&d, &d, 1); assert(d == 1527*2); carla_add(&d, &d, 1); assert(d == 1527*4); carla_add(&d, &e, 1); assert(d == 1527*4); assert(e == 0); carla_add(&e, &d, 1); assert(d == e); carla_add(&e, &d, 1); assert(e == d*2); d = -e; carla_add(&d, &e, 1); assert(d == 0); } { bool x; const bool f = false, t = true; carla_copy(&x, &t, 1); assert(x); carla_copy(&x, &f, 1); assert(! x); carla_fill(&x, true, 1); assert(x); carla_fill(&x, false, 1); assert(! x); } { uint8_t a[] = { 3, 2, 1, 0 }; carla_zeroBytes(a, 1); assert(a[0] == 0); assert(a[1] == 2); assert(a[2] == 1); assert(a[3] == 0); carla_zeroBytes(a+1, 2); assert(a[0] == 0); assert(a[1] == 0); assert(a[2] == 0); assert(a[3] == 0); } { char a[501]; for (int i=500; --i>=0;) a[i] = 'a'; carla_zeroChars(a, 501); for (int i=501; --i>=0;) assert(a[i] == '\0'); for (int i=500; --i>=0;) a[i] = 'a'; assert(std::strlen(a) == 500); carla_fill(a+200, '\0', 1); assert(std::strlen(a) == 200); } { void* a[33]; carla_zeroPointers(a, 33); for (int i=33; --i>=0;) assert(a[i] == nullptr); } { struct Thing { char c; int i; int64_t h; bool operator==(const Thing& t) const noexcept { return (t.c == c && t.i == i && t.h == h); } bool operator!=(const Thing& t) const noexcept { return !operator==(t); } }; Thing a, b, c; a.c = 0; a.i = 0; a.h = 0; b.c = 64; b.i = 64; b.h = 64; c = a; carla_copyStruct(a, b); assert(a == b); carla_zeroStruct(a); assert(a == c); carla_copyStruct(c, b); assert(a != c); // make it non-zero a.c = 1; Thing d[3]; carla_zeroStructs(d, 3); assert(d[0] != a); assert(d[1] != b); assert(d[2] != c); carla_copyStructs(d, &a, 1); assert(d[0] == a); assert(d[1] != b); assert(d[2] != c); carla_copyStructs(&c, d+2, 1); assert(d[0] == a); assert(d[1] != b); assert(d[2] == c); } }
int _tmain(int argc, _TCHAR* argv[]) #endif { int32_t iRet = RETVALUE_SUCCESS; #ifdef __APPLE__ _TCHAR** argv = convertArguments( argc, argvOriginal ); #endif //Initialize argument handler ArgumentHandler argumenthandler( ARRAYSIZE( options ), options ); //Initialize a parser interface cri::CParser* parser = new cri::CParser; //Initialize error handler cri::CErrorPool *error = new cri::CErrorPool; error->setErrorTable( cri::g_ErrorTable_English, sizeof( cri::g_ErrorTable_English ) / sizeof( cri::g_ErrorTable_English[ 0 ] ) ); //parse args argumenthandler.setErrorHandler( error ); int32_t iArgOffset = argumenthandler.parse( argc, argv ); //Set error output configuration error->suppressErrorLine( g_bsuppressErrorLine ); if( !g_bSuppressBanner ) { CRISCRIPT_VERSIONS ver = parser->getVersions(); cout << "CriScript compiler and linker ver."; cout << ver.major << "."; cout << ver.minor << "."; cout << ver.revision << "."; cout << ver.build << "\n"; cout << "CRI Middleware inc. 2008" << endl; } if( argc <= iArgOffset ) { if( error->hasError() ) error->dumpError(); delete( error ); //Output help info cout << endl; cout << "cscl.exe [options] source" << endl; cout << "Option switch:" << endl; for( int32_t i = 0; i < ARRAYSIZE( options ); ++ i ) { wcout << options[ i ].strOption << " : " << options[ i ].strDescription << endl; } delete( parser ); #ifdef __APPLE__ deleteArguments( argc, argv ); #endif return RETVALUE_SUCCESS; } //Open the target file #ifdef __APPLE__ ifstream fin ( argvOriginal[ iArgOffset ], ios::in | ios::binary ); #else ifstream fin ( argv[ iArgOffset ], ios::in | ios::binary ); #endif if( !fin ) { wstring strArg1( argv[ iArgOffset ] ); wstring strNull( L"" ); error->report( ERROR_FILENOTFOUND, 0, 0, strArg1, strNull, strArg1 ); error->dumpError(); delete( error ); delete( parser ); #ifdef __APPLE__ deleteArguments( argc, argv ); #endif return RETVALUE_TOOL_ERROR; } //Check file endianness; //Note that wchar_t is 4 byte in OSX. uint16_t c; fin.read( (char*)&c, sizeof( uint16_t ) ); bool bSourceEndiannness = false; switch( c ) { case 0xfeff: //Little endian break; case 0xfffe: //Big endian bSourceEndiannness = true; break; default: { wstring strArg1( argv[ iArgOffset ] ); wstring strNull( L"" ); error->report( ERROR_INVALIDFILEENCODING, 0, 0, strArg1, strNull, strArg1 ); error->dumpError(); delete( error ); } delete( parser ); #ifdef __APPLE__ deleteArguments( argc, argv ); #endif return RETVALUE_TOOL_ERROR; } //Initialize the lexer cri::CFileStreamLexer *lex = new cri::CFileStreamLexer; //test lex->init(); lex->setEndianness( bSourceEndiannness ); //Initialize the codegen cri::CCilCodeGen *codegen = new cri::CCilCodeGen; //Initialize the parser engine parser->init( lex, codegen, error ); //Set filestream to the lexer lex->setStream( &fin, &wstring( argv[ iArgOffset ] ) ); #ifdef DEBUG_PARSING //debug cri::yydebug = 1; #endif if( !g_bPerformLinkage ) { iRet = Compile( parser, fin ); g_bPerformExecution = false; } else { iRet = CompileAndLink( parser, fin ); } if( error->hasError() ) { error->dumpError(); cout << "Compile failed." << endl; iRet = RETVALUE_COMPILE_ERROR; } else { if( error->hasInformation() ) { iRet = RETVALUE_COMPILE_WARNING; cout << "Compile succeeded but with some warnings" << endl; } else { iRet = RETVALUE_SUCCESS; cout << "Compile succeeded." << endl; } error->dumpError(); } if( g_bPerformExecution && iRet != RETVALUE_COMPILE_ERROR ) { cri::CCilVm *vm = new cri::CCilVm; cri::CCilDebugger *debugger = new cri::CCilDebugger; vm->setILPool( &*parser->getILPool().begin(), parser->getILPool().size() ); //Note: //setSymbolInformation need to be invoked before SetMetaData() for now vm->setSymbolInformation( parser->getSymbolInformation() ); vm->setMetaData( parser->getMetaData() ); cout << "-----------------------------------------------------------------\n"; cri::CCilDisasm * disasm = new cri::CCilDisasm; disasm->setILStream( &*parser->getILPool().begin(), parser->getILPool().size() ); disasm->setSymbolInformation( parser->getSymbolInformation() ); disasm->setMetaData( parser->getMetaData() ); disasm->dumpDisasm(); cout << "-----------------------------------------------------------------\n"; iRet = vm->execute(); iRet = vm->getExitCode(); debugger->attach( vm ); debugger->setSymbolInformation( parser->getSymbolInformation() ); debugger->setMetaData( parser->getMetaData() ); debugger->debugDumpStats(); debugger->debugDumpStaticFields( 0 ); //dump all fields debugger->debugDumpObjects( 0 ); //dump all objects delete( disasm ); delete( debugger ); delete( vm ); } delete( lex ); delete( error ); delete( codegen ); delete( parser ); #ifdef __APPLE__ deleteArguments( argc, argv ); #endif return iRet; }