bool TestCppBase::TestCollectionHdf() { IniSetting::Map ini = IniSetting::Map::object; Hdf hdf; hdf.fromString( " Server {\n" " AllowedDirectories.* = /var/www\n" " AllowedDirectories.* = /usr/bin\n" " HighPriorityEndPoints.* = /end\n" " HighPriorityEndPoints.* = /point\n" " HighPriorityEndPoints.* = /power\n" " }\n" ); RuntimeOption::AllowedDirectories.clear(); Config::Bind(RuntimeOption::AllowedDirectories, ini, hdf, "Server.AllowedDirectories"); VERIFY(RuntimeOption::AllowedDirectories.size() == 2); std::vector<std::string> ad = Config::GetVector(ini, hdf, "Server.AllowedDirectories", RuntimeOption::AllowedDirectories); VERIFY(RuntimeOption::AllowedDirectories.size() == 2); VERIFY(ad.size() == 2); Config::Bind(RuntimeOption::ServerHighPriorityEndPoints, ini, hdf, "Server.HighPriorityEndPoints"); VERIFY(RuntimeOption::ServerHighPriorityEndPoints.size() == 3); return Count(true); }
bool TestCppBase::TestSatelliteServer() { IniSetting::Map ini = IniSetting::Map::object; Hdf hdf; hdf.fromString( "Satellites {\n" " rpc {\n" " Type = RPCServer\n" " Port = 9999\n" " RequestInitDocument = my/rpc/rpc.php\n" " RequestInitFunction = init_me\n" " Password = abcd0987\n" " Passwords {\n" " * = abcd0987\n" " }\n" " }\n" " ips {\n" " Type = InternalPageServer\n" " BlockMainServer = false\n" " }\n" "}\n" ); std::vector<std::shared_ptr<SatelliteServerInfo>> infos; RuntimeOption::ReadSatelliteInfo(ini, hdf, infos, RuntimeOption::XboxPassword, RuntimeOption::XboxPasswords); for (auto& info_ptr : infos) { auto info = info_ptr.get(); auto name = info->getName(); if (name == "rpc") { VERIFY(info->getType() == SatelliteServer::Type::KindOfRPCServer); VERIFY(info->getPort() == 9999); VERIFY(info->getThreadCount() == 5); VERIFY(info->getTimeoutSeconds() == std::chrono::seconds(RuntimeOption::RequestTimeoutSeconds)); VERIFY(info->getURLs().size() == 0); VERIFY(info->getMaxRequest() == 500); VERIFY(info->getMaxDuration() == 120); VERIFY(info->getReqInitFunc() == "init_me"); VERIFY(info->getReqInitDoc() == "my/rpc/rpc.php"); VERIFY(info->getPassword() == "abcd0987"); VERIFY(info->getPasswords().size() == 1); VERIFY(info->getPasswords().find("abcd0987") != info->getPasswords().end()); VERIFY(info->alwaysReset() == false); VERIFY(RuntimeOption::XboxPassword == "abcd0987"); } else if (name == "ips") { VERIFY(info->getType() == SatelliteServer::Type::KindOfInternalPageServer); VERIFY(info->getURLs().size() == 0); } } return Count(true); }
bool TestUtil::TestHDF() { // This was causing a crash { Hdf doc, node; node = doc["Node"]; } { Hdf doc; doc.fromString( "node.* {\n" " name = value\n" "}"); VS(doc["node"][0]["name"].getString(), "value"); } return Count(true); }
bool TestUtil::TestHDF() { // This was causing a crash { Hdf doc, node; node = doc["Node"]; } { IniSetting::Map ini = IniSetting::Map::object; Hdf doc; doc.fromString( "node.* {\n" " name = value\n" "}"); VS(Config::GetString(ini, doc, "node.0.name"), "value"); } return Count(true); }
void Config::ParseHdfString(const std::string hdfStr, Hdf &hdf) { hdf.fromString(hdfStr.c_str()); }
void RuntimeOption::Load(Hdf &config, StringVec *overwrites /* = NULL */) { // Machine metrics string hostname, tier, cpu; { Hdf machine = config["Machine"]; hostname = machine["name"].getString(); if (hostname.empty()) { hostname = Process::GetHostName(); } tier = machine["tier"].getString(); cpu = machine["cpu"].getString(); if (cpu.empty()) { cpu = Process::GetCPUModel(); } } // Tier overwrites { Hdf tiers = config["Tiers"]; for (Hdf hdf = tiers.firstChild(); hdf.exists(); hdf = hdf.next()) { if (matchHdfPattern(hostname, hdf["machine"]) && matchHdfPattern(tier, hdf["tier"]) && matchHdfPattern(cpu, hdf["cpu"])) { Tier = hdf.getName(); config.copy(hdf["overwrite"]); // no break here, so we can continue to match more overwrites } hdf["overwrite"].setVisited(); // avoid lint complaining } } // More overwrites if (overwrites) { for (unsigned int i = 0; i < overwrites->size(); i++) { config.fromString(overwrites->at(i).c_str()); } } PidFile = config["PidFile"].getString("www.pid"); { Hdf logger = config["Log"]; if (logger["Level"] == "None") { Logger::LogLevel = Logger::LogNone; } else if (logger["Level"] == "Error") { Logger::LogLevel = Logger::LogError; } else if (logger["Level"] == "Warning") { Logger::LogLevel = Logger::LogWarning; } else if (logger["Level"] == "Info") { Logger::LogLevel = Logger::LogInfo; } else if (logger["Level"] == "Verbose") { Logger::LogLevel = Logger::LogVerbose; } Logger::LogHeader = logger["Header"].getBool(); bool logInjectedStackTrace = logger["InjectedStackTrace"].getBool(); if (logInjectedStackTrace) { Logger::SetTheLogger(new ExtendedLogger()); ExtendedLogger::EnabledByDefault = true; } Logger::LogNativeStackTrace = logger["NativeStackTrace"].getBool(true); Logger::MaxMessagesPerRequest = logger["MaxMessagesPerRequest"].getInt32(-1); Logger::UseLogFile = logger["UseLogFile"].getBool(true); Logger::UseCronolog = logger["UseCronolog"].getBool(false); if (Logger::UseLogFile) { LogFile = logger["File"].getString(); LogFileSymLink = logger["SymLink"].getString(); } Logger::DropCacheChunkSize = logger["DropCacheChunkSize"].getInt32(1 << 20); AlwaysEscapeLog = logger["AlwaysEscapeLog"].getBool(false); Hdf aggregator = logger["Aggregator"]; Logger::UseLogAggregator = aggregator.getBool(); LogAggregatorFile = aggregator["File"].getString(); LogAggregatorDatabase = aggregator["Database"].getString(); LogAggregatorSleepSeconds = aggregator["SleepSeconds"].getInt16(10); AlwaysLogUnhandledExceptions = logger["AlwaysLogUnhandledExceptions"].getBool(true); NoSilencer = logger["NoSilencer"].getBool(); EnableApplicationLog = logger["ApplicationLog"].getBool(true); RuntimeErrorReportingLevel = logger["RuntimeErrorReportingLevel"].getInt32(ErrorConstants::HPHP_ALL); AccessLogDefaultFormat = logger["AccessLogDefaultFormat"]. getString("%h %l %u %t \"%r\" %>s %b"); { Hdf access = logger["Access"]; for (Hdf hdf = access.firstChild(); hdf.exists(); hdf = hdf.next()) { string fname = hdf["File"].getString(); if (fname.empty()) { continue; } string symLink = hdf["SymLink"].getString(); AccessLogs. push_back(AccessLogFileData(fname, symLink, hdf["Format"]. getString(AccessLogDefaultFormat))); } } AdminLogFormat = logger["AdminLog.Format"].getString("%h %t %s %U"); AdminLogFile = logger["AdminLog.File"].getString(); AdminLogSymLink = logger["AdminLog.SymLink"].getString(); } { Hdf error = config["ErrorHandling"]; /* Remove this, once its removed from production configs */ (void)error["NoInfiniteLoopDetection"].getBool(); MaxSerializedStringSize = error["MaxSerializedStringSize"].getInt32(64 * 1024 * 1024); CallUserHandlerOnFatals = error["CallUserHandlerOnFatals"].getBool(true); MaxLoopCount = error["MaxLoopCount"].getInt32(0); NoInfiniteRecursionDetection = error["NoInfiniteRecursionDetection"].getBool(); ThrowBadTypeExceptions = error["ThrowBadTypeExceptions"].getBool(); ThrowTooManyArguments = error["ThrowTooManyArguments"].getBool(); WarnTooManyArguments = error["WarnTooManyArguments"].getBool(); ThrowMissingArguments = error["ThrowMissingArguments"].getBool(); ThrowInvalidArguments = error["ThrowInvalidArguments"].getBool(); EnableHipHopErrors = error["EnableHipHopErrors"].getBool(true); AssertActive = error["AssertActive"].getBool(); AssertWarning = error["AssertWarning"].getBool(); NoticeFrequency = error["NoticeFrequency"].getInt32(1); WarningFrequency = error["WarningFrequency"].getInt32(1); } { Hdf rlimit = config["ResourceLimit"]; setResourceLimit(RLIMIT_CORE, rlimit, "CoreFileSize"); setResourceLimit(RLIMIT_NOFILE, rlimit, "MaxSocket"); setResourceLimit(RLIMIT_DATA, rlimit, "RSS"); MaxRSS = rlimit["MaxRSS"].getInt64(0); SocketDefaultTimeout = rlimit["SocketDefaultTimeout"].getInt16(5); MaxRSSPollingCycle = rlimit["MaxRSSPollingCycle"].getInt64(0); DropCacheCycle = rlimit["DropCacheCycle"].getInt64(0); MaxSQLRowCount = rlimit["MaxSQLRowCount"].getInt64(0); MaxMemcacheKeyCount = rlimit["MaxMemcacheKeyCount"].getInt64(0); SerializationSizeLimit = rlimit["SerializationSizeLimit"].getInt64(0); StringOffsetLimit = rlimit["StringOffsetLimit"].getInt64(10 * 1024 * 1024); } { Hdf server = config["Server"]; Host = server["Host"].getString(); DefaultServerNameSuffix = server["DefaultServerNameSuffix"].getString(); ServerIP = server["IP"].getString("0.0.0.0"); ServerPrimaryIP = Util::GetPrimaryIP(); ServerPort = server["Port"].getInt16(80); ServerBacklog = server["Backlog"].getInt16(128); ServerConnectionLimit = server["ConnectionLimit"].getInt16(0); ServerThreadCount = server["ThreadCount"].getInt32(50); ServerThreadRoundRobin = server["ThreadRoundRobin"].getBool(); ServerThreadDropCacheTimeoutSeconds = server["ThreadDropCacheTimeoutSeconds"].getInt32(0); ServerThreadJobLIFO = server["ThreadJobLIFO"].getBool(); RequestTimeoutSeconds = server["RequestTimeoutSeconds"].getInt32(0); RequestMemoryMaxBytes = server["RequestMemoryMaxBytes"].getInt64(-1); ResponseQueueCount = server["ResponseQueueCount"].getInt32(0); if (ResponseQueueCount <= 0) { ResponseQueueCount = ServerThreadCount / 10; if (ResponseQueueCount <= 0) ResponseQueueCount = 1; } ServerGracefulShutdownWait = server["GracefulShutdownWait"].getInt16(0); ServerHarshShutdown = server["HarshShutdown"].getBool(true); ServerEvilShutdown = server["EvilShutdown"].getBool(true); ServerDanglingWait = server["DanglingWait"].getInt16(0); if (ServerGracefulShutdownWait < ServerDanglingWait) { ServerGracefulShutdownWait = ServerDanglingWait; } GzipCompressionLevel = server["GzipCompressionLevel"].getInt16(3); ForceCompressionURL = server["ForceCompression"]["URL"].getString(); ForceCompressionCookie = server["ForceCompression"]["Cookie"].getString(); ForceCompressionParam = server["ForceCompression"]["Param"].getString(); EnableMagicQuotesGpc = server["EnableMagicQuotesGpc"].getBool(); EnableKeepAlive = server["EnableKeepAlive"].getBool(true); ExposeHPHP = server["ExposeHPHP"].getBool(true); ExposeXFBServer = server["ExposeXFBServer"].getBool(); ConnectionTimeoutSeconds = server["ConnectionTimeoutSeconds"].getInt16(-1); EnableOutputBuffering = server["EnableOutputBuffering"].getBool(); OutputHandler = server["OutputHandler"].getString(); ImplicitFlush = server["ImplicitFlush"].getBool(); EnableEarlyFlush = server["EnableEarlyFlush"].getBool(true); ForceChunkedEncoding = server["ForceChunkedEncoding"].getBool(); MaxPostSize = (server["MaxPostSize"].getInt32(100)) * (1LL << 20); AlwaysPopulateRawPostData = server["AlwaysPopulateRawPostData"].getBool(); LibEventSyncSend = server["LibEventSyncSend"].getBool(true); TakeoverFilename = server["TakeoverFilename"].getString(); ExpiresActive = server["ExpiresActive"].getBool(true); ExpiresDefault = server["ExpiresDefault"].getInt32(2592000); if (ExpiresDefault < 0) ExpiresDefault = 2592000; DefaultCharsetName = server["DefaultCharsetName"].getString("utf-8"); RequestBodyReadLimit = server["RequestBodyReadLimit"].getInt32(-1); EnableSSL = server["EnableSSL"].getBool(); SSLPort = server["SSLPort"].getInt16(443); SSLCertificateFile = server["SSLCertificateFile"].getString(); SSLCertificateKeyFile = server["SSLCertificateKeyFile"].getString(); SourceRoot = Util::normalizeDir(server["SourceRoot"].getString()); if (!SourceRoot.empty()) { // Guaranteed empty on empty load so avoid setting FileCache::SourceRoot // since it may not be initialized FileCache::SourceRoot = SourceRoot; } server["IncludeSearchPaths"].get(IncludeSearchPaths); for (unsigned int i = 0; i < IncludeSearchPaths.size(); i++) { IncludeSearchPaths[i] = Util::normalizeDir(IncludeSearchPaths[i]); } IncludeSearchPaths.insert(IncludeSearchPaths.begin(), "./"); FileCache = server["FileCache"].getString(); DefaultDocument = server["DefaultDocument"].getString(); ErrorDocument404 = server["ErrorDocument404"].getString(); normalizePath(ErrorDocument404); ErrorDocument500 = server["ErrorDocument500"].getString(); normalizePath(ErrorDocument500); FatalErrorMessage = server["FatalErrorMessage"].getString(); FontPath = Util::normalizeDir(server["FontPath"].getString()); EnableStaticContentCache = server["EnableStaticContentCache"].getBool(true); EnableStaticContentFromDisk = server["EnableStaticContentFromDisk"].getBool(true); EnableOnDemandUncompress = server["EnableOnDemandUncompress"].getBool(true); EnableStaticContentMMap = server["EnableStaticContentMMap"].getBool(true); if (EnableStaticContentMMap) { EnableOnDemandUncompress = true; } RTTIDirectory = Util::normalizeDir(server["RTTIDirectory"].getString("/tmp/")); EnableCliRTTI = server["EnableCliRTTI"].getBool(); Utf8izeReplace = server["Utf8izeReplace"].getBool(true); StartupDocument = server["StartupDocument"].getString(); normalizePath(StartupDocument); WarmupDocument = server["WarmupDocument"].getString(); RequestInitFunction = server["RequestInitFunction"].getString(); RequestInitDocument = server["RequestInitDocument"].getString(); server["ThreadDocuments"].get(ThreadDocuments); for (unsigned int i = 0; i < ThreadDocuments.size(); i++) { normalizePath(ThreadDocuments[i]); } server["ThreadLoopDocuments"].get(ThreadLoopDocuments); for (unsigned int i = 0; i < ThreadLoopDocuments.size(); i++) { normalizePath(ThreadLoopDocuments[i]); } SafeFileAccess = server["SafeFileAccess"].getBool(); server["AllowedDirectories"].get(AllowedDirectories); for (unsigned int i = 0; i < AllowedDirectories.size(); i++) { string &directory = AllowedDirectories[i]; char resolved_path[PATH_MAX]; if (realpath(directory.c_str(), resolved_path) && directory != resolved_path) { RuntimeOption::AllowedDirectories.push_back(resolved_path); } } server["AllowedFiles"].get(AllowedFiles); server["ForbiddenFileExtensions"].get(ForbiddenFileExtensions); EnableMemoryManager = server["EnableMemoryManager"].getBool(true); CheckMemory = server["CheckMemory"].getBool(); UseHphpArray = server["UseHphpArray"].getBool(false); UseSmallArray = server["UseSmallArray"].getBool(false); UseDirectCopy = server["UseDirectCopy"].getBool(false); AlwaysUseRelativePath = server["AlwaysUseRelativePath"].getBool(false); Hdf apc = server["APC"]; EnableApc = apc["EnableApc"].getBool(true); EnableConstLoad = apc["EnableConstLoad"].getBool(false); ForceConstLoadToAPC = apc["ForceConstLoadToAPC"].getBool(true); ApcPrimeLibrary = apc["PrimeLibrary"].getString(); ApcLoadThread = apc["LoadThread"].getInt16(2); apc["CompletionKeys"].get(ApcCompletionKeys); string apcTableType = apc["TableType"].getString("concurrent"); if (strcasecmp(apcTableType.c_str(), "hash") == 0) { ApcTableType = ApcHashTable; } else if (strcasecmp(apcTableType.c_str(), "concurrent") == 0) { ApcTableType = ApcConcurrentTable; } else { throw InvalidArgumentException("apc table type", "Invalid table type"); } string apcLockType = apc["LockType"].getString("readwritelock"); if (strcasecmp(apcLockType.c_str(), "readwritelock") == 0) { ApcTableLockType = ApcReadWriteLock; } else if (strcasecmp(apcLockType.c_str(), "mutex") == 0) { ApcTableLockType = ApcMutex; } else { throw InvalidArgumentException("apc lock type", "Invalid lock type"); } ApcExpireOnSets = apc["ExpireOnSets"].getBool(); ApcPurgeFrequency = apc["PurgeFrequency"].getInt32(4096); ApcAllowObj = apc["AllowObject"].getBool(); ApcKeyMaturityThreshold = apc["KeyMaturityThreshold"].getInt32(20); ApcMaximumCapacity = apc["MaximumCapacity"].getInt64(0); ApcKeyFrequencyUpdatePeriod = apc["KeyFrequencyUpdatePeriod"]. getInt32(1000); Hdf dns = server["DnsCache"]; EnableDnsCache = dns["Enable"].getBool(); DnsCacheTTL = dns["TTL"].getInt32(600); // 10 minutes DnsCacheKeyMaturityThreshold = dns["KeyMaturityThreshold"].getInt32(20); DnsCacheMaximumCapacity = dns["MaximumCapacity"].getInt64(0); DnsCacheKeyFrequencyUpdatePeriod = dns["KeyFrequencyUpdatePeriod"]. getInt32(1000); Hdf upload = server["Upload"]; UploadMaxFileSize = (upload["UploadMaxFileSize"].getInt32(100)) * (1LL << 20); UploadTmpDir = upload["UploadTmpDir"].getString("/tmp"); RuntimeOption::AllowedDirectories.push_back(UploadTmpDir); EnableFileUploads = upload["EnableFileUploads"].getBool(true); EnableUploadProgress = upload["EnableUploadProgress"].getBool(); Rfc1867Freq = upload["Rfc1867Freq"].getInt32(256 * 1024); if (Rfc1867Freq < 0) Rfc1867Freq = 256 * 1024; Rfc1867Prefix = upload["Rfc1867Prefix"].getString("vupload_"); Rfc1867Name = upload["Rfc1867Name"].getString("video_ptoken"); ImageMemoryMaxBytes = server["ImageMemoryMaxBytes"].getInt64(0); if (ImageMemoryMaxBytes == 0) { ImageMemoryMaxBytes = UploadMaxFileSize * 2; } SharedStores::Create(); LightProcessFilePrefix = server["LightProcessFilePrefix"].getString("./lightprocess"); LightProcessCount = server["LightProcessCount"].getInt32(0); InjectedStackTrace = server["InjectedStackTrace"].getBool(true); InjectedStackTraceLimit = server["InjectedStackTraceLimit"].getInt32(-1); ForceServerNameToHeader = server["ForceServerNameToHeader"].getBool(); ServerUser = server["User"].getString(""); } { Hdf hosts = config["VirtualHost"]; if (hosts.exists()) { for (Hdf hdf = hosts.firstChild(); hdf.exists(); hdf = hdf.next()) { if (hdf.getName() == "default") { VirtualHost::GetDefault().init(hdf); } else { VirtualHostPtr host(new VirtualHost(hdf)); VirtualHosts.push_back(host); } } for (unsigned int i = 0; i < VirtualHosts.size(); i++) { if (!VirtualHosts[i]->valid()) { throw InvalidArgumentException("virtual host", "missing prefix or pattern"); } } } } { Hdf ipblocks = config["IpBlockMap"]; IpBlocks = IpBlockMapPtr(new IpBlockMap(ipblocks)); } { Hdf satellites = config["Satellites"]; if (satellites.exists()) { for (Hdf hdf = satellites.firstChild(); hdf.exists(); hdf = hdf.next()) { SatelliteServerInfoPtr satellite(new SatelliteServerInfo(hdf)); SatelliteServerInfos.push_back(satellite); if (satellite->getType() == SatelliteServer::KindOfRPCServer) { XboxPassword = satellite->getPassword(); } } } } { Hdf xbox = config["Xbox"]; XboxServerThreadCount = xbox["ServerInfo.ThreadCount"].getInt32(0); XboxServerPort = xbox["ServerInfo.Port"].getInt32(0); XboxDefaultLocalTimeoutMilliSeconds = xbox["DefaultLocalTimeoutMilliSeconds"].getInt32(500); XboxDefaultRemoteTimeoutSeconds = xbox["DefaultRemoteTimeoutSeconds"].getInt32(5); XboxServerInfoMaxRequest = xbox["ServerInfo.MaxRequest"].getInt32(500); XboxServerInfoDuration = xbox["ServerInfo.MaxDuration"].getInt32(120); XboxServerInfoWarmupDoc = xbox["ServerInfo.WarmupDocument"].get(""); XboxServerInfoReqInitFunc = xbox["ServerInfo.RequestInitFunction"].get(""); XboxServerInfoReqInitDoc = xbox["ServerInfo.RequestInitDocument"].get(""); XboxProcessMessageFunc = xbox["ProcessMessageFunc"].get("xbox_process_message"); } { Hdf pagelet = config["PageletServer"]; PageletServerThreadCount = pagelet["ThreadCount"].getInt32(0); PageletServerThreadRoundRobin = pagelet["ThreadRoundRobin"].getBool(); PageletServerThreadDropCacheTimeoutSeconds = pagelet["ThreadDropCacheTimeoutSeconds"].getInt32(0); } { FiberCount = config["Fiber.ThreadCount"].getInt32(Process::GetCPUCount()); } { Hdf content = config["StaticFile"]; content["Extensions"].get(StaticFileExtensions); content["Generators"].get(StaticFileGenerators); Hdf matches = content["FilesMatch"]; if (matches.exists()) { for (Hdf hdf = matches.firstChild(); hdf.exists(); hdf = hdf.next()) { FilesMatches.push_back(FilesMatchPtr(new FilesMatch(hdf))); } } } { Hdf admin = config["AdminServer"]; AdminServerPort = admin["Port"].getInt16(8088); AdminThreadCount = admin["ThreadCount"].getInt32(1); AdminPassword = admin["Password"].getString(); } { Hdf proxy = config["Proxy"]; ProxyOrigin = proxy["Origin"].getString(); ProxyRetry = proxy["Retry"].getInt16(3); UseServeURLs = proxy["ServeURLs"].getBool(); proxy["ServeURLs"].get(ServeURLs); UseProxyURLs = proxy["ProxyURLs"].getBool(); ProxyPercentage = proxy["Percentage"].getByte(0); proxy["ProxyURLs"].get(ProxyURLs); proxy["ProxyPatterns"].get(ProxyPatterns); } { Hdf mysql = config["MySQL"]; MySQLReadOnly = mysql["ReadOnly"].getBool(); MySQLLocalize = mysql["Localize"].getBool(); MySQLConnectTimeout = mysql["ConnectTimeout"].getInt32(1000); MySQLReadTimeout = mysql["ReadTimeout"].getInt32(1000); MySQLWaitTimeout = mysql["WaitTimeout"].getInt32(-1); MySQLSlowQueryThreshold = mysql["SlowQueryThreshold"].getInt32(1000); MySQLKillOnTimeout = mysql["KillOnTimeout"].getBool(); } { Hdf http = config["Http"]; HttpDefaultTimeout = http["DefaultTimeout"].getInt32(30); HttpSlowQueryThreshold = http["SlowQueryThreshold"].getInt32(5000); } { Hdf debug = config["Debug"]; NativeStackTrace = debug["NativeStackTrace"].getBool(); StackTrace::Enabled = NativeStackTrace; TranslateLeakStackTrace = debug["TranslateLeakStackTrace"].getBool(); FullBacktrace = debug["FullBacktrace"].getBool(); ServerStackTrace = debug["ServerStackTrace"].getBool(); ServerErrorMessage = debug["ServerErrorMessage"].getBool(); TranslateSource = debug["TranslateSource"].getBool(); RecordInput = debug["RecordInput"].getBool(); ClearInputOnSuccess = debug["ClearInputOnSuccess"].getBool(true); ProfilerOutputDir = debug["ProfilerOutputDir"].getString("/tmp"); CoreDumpEmail = debug["CoreDumpEmail"].getString(); if (!CoreDumpEmail.empty()) { StackTrace::ReportEmail = CoreDumpEmail; } CoreDumpReport = debug["CoreDumpReport"].getBool(true); if (CoreDumpReport) { StackTrace::InstallReportOnErrors(); } std::string reportDirectory = debug["CoreDumpReportDirectory"].getString(); if (!reportDirectory.empty()) { StackTraceBase::ReportDirectory = reportDirectory; } LocalMemcache = debug["LocalMemcache"].getBool(); MemcacheReadOnly = debug["MemcacheReadOnly"].getBool(); { Hdf simpleCounter = debug["SimpleCounter"]; SimpleCounter::SampleStackCount = simpleCounter["SampleStackCount"].getInt32(0); SimpleCounter::SampleStackDepth = simpleCounter["SampleStackDepth"].getInt32(5); } } { Hdf stats = config["Stats"]; EnableStats = stats.getBool(); // main switch EnableWebStats = stats["Web"].getBool(); EnableMemoryStats = stats["Memory"].getBool(); EnableMallocStats = stats["Malloc"].getBool(); EnableAPCStats = stats["APC"].getBool(); EnableAPCKeyStats = stats["APCKey"].getBool(); EnableMemcacheStats = stats["Memcache"].getBool(); EnableMemcacheKeyStats = stats["MemcacheKey"].getBool(); EnableSQLStats = stats["SQL"].getBool(); EnableSQLTableStats = stats["SQLTable"].getBool(); EnableNetworkIOStatus = stats["NetworkIO"].getBool(); if (EnableStats && EnableMallocStats) { LeakDetectable::EnableMallocStats(true); } StatsXSL = stats["XSL"].getString(); StatsXSLProxy = stats["XSLProxy"].getString(); StatsSlotDuration = stats["SlotDuration"].getInt32(10 * 60); // 10 minutes StatsMaxSlot = stats["MaxSlot"].getInt32(12 * 6); // 12 hours { Hdf apcSize = stats["APCSize"]; EnableAPCSizeStats = apcSize["Enable"].getBool(); EnableAPCSizeGroup = apcSize["Group"].getBool(); apcSize["SpecialPrefix"].get(APCSizeSpecialPrefix); for (unsigned int i = 0; i < APCSizeSpecialPrefix.size(); i++) { string &prefix = APCSizeSpecialPrefix[i]; string prefixReplace = prefix + "{A}"; APCSizePrefixReplace.push_back(prefixReplace); } apcSize["SpecialMiddle"].get(APCSizeSpecialMiddle); for (unsigned int i = 0; i < APCSizeSpecialMiddle.size(); i++) { string &middle = APCSizeSpecialMiddle[i]; string middleReplace = "{A}" + middle + "{A}"; APCSizeMiddleReplace.push_back(middleReplace); } apcSize["SkipPrefix"].get(APCSizeSkipPrefix); EnableAPCSizeDetail = apcSize["Individual"].getBool(); EnableAPCFetchStats = apcSize["FetchStats"].getBool(); if (EnableAPCFetchStats) EnableAPCSizeDetail = true; if (EnableAPCSizeDetail) EnableAPCSizeGroup = true; APCSizeCountPrime = apcSize["CountPrime"].getBool(); } EnableHotProfiler = stats["EnableHotProfiler"].getBool(true); ProfilerTraceBuffer = stats["ProfilerTraceBuffer"].getInt32(2000000); ProfilerTraceExpansion = stats["ProfilerTraceExpansion"].getDouble(1.2); ProfilerMaxTraceBuffer = stats["ProfilerMaxTraceBuffer"].getInt32(0); } { config["ServerVariables"].get(ServerVariables); config["EnvVariables"].get(EnvVariables); } { Hdf eval = config["Eval"]; EnableHipHopSyntax = eval["EnableHipHopSyntax"].getBool(); EnableHipHopExperimentalSyntax = eval["EnableHipHopExperimentalSyntax"].getBool(); EnableShortTags= eval["EnableShortTags"].getBool(true); if (EnableShortTags) ScannerType |= Scanner::AllowShortTags; else ScannerType &= ~Scanner::AllowShortTags; EnableAspTags = eval["EnableAspTags"].getBool(); if (EnableAspTags) ScannerType |= Scanner::AllowAspTags; else ScannerType &= ~Scanner::AllowAspTags; EnableXHP = eval["EnableXHP"].getBool(true); EnableObjDestructCall = eval["EnableObjDestructCall"].getBool(false); CheckSymLink = eval["CheckSymLink"].getBool(false); NativeXHP = eval["NativeXHP"].getBool(true); if (EnableXHP && !NativeXHP) ScannerType |= Scanner::PreprocessXHP; else ScannerType &= ~Scanner::PreprocessXHP; EnableStrict = eval["EnableStrict"].getBool(); StrictLevel = eval["StrictLevel"].getInt32(1); // StrictBasic StrictFatal = eval["StrictFatal"].getBool(); RecordCodeCoverage = eval["RecordCodeCoverage"].getBool(); CodeCoverageOutputFile = eval["CodeCoverageOutputFile"].getString(); { Hdf debugger = eval["Debugger"]; EnableDebugger = debugger["EnableDebugger"].getBool(); EnableDebuggerServer = debugger["EnableDebuggerServer"].getBool(); DebuggerServerPort = debugger["Port"].getInt16(8089); DebuggerStartupDocument = debugger["StartupDocument"].getString(); DebuggerDefaultSandboxPath = debugger["DefaultSandboxPath"].getString(); DebuggerDefaultRpcPort = debugger["RPC.DefaultPort"].getInt16(8083); DebuggerDefaultRpcAuth = debugger["RPC.DefaultAuth"].getString(); DebuggerRpcHostDomain = debugger["RPC.HostDomain"].getString(); DebuggerDefaultRpcTimeout = debugger["RPC.DefaultTimeout"].getInt32(30); } } { Hdf sandbox = config["Sandbox"]; SandboxMode = sandbox["SandboxMode"].getBool(); SandboxPattern = Util::format_pattern (sandbox["Pattern"].getString(), true); SandboxHome = sandbox["Home"].getString(); SandboxFallback = sandbox["Fallback"].getString(); SandboxConfFile = sandbox["ConfFile"].getString(); SandboxFromCommonRoot = sandbox["FromCommonRoot"].getBool(); SandboxDirectoriesRoot = sandbox["DirectoriesRoot"].getString(); SandboxLogsRoot = sandbox["LogsRoot"].getString(); sandbox["ServerVariables"].get(SandboxServerVariables); } { Hdf mail = config["Mail"]; SendmailPath = mail["SendmailPath"].getString("sendmail -t -i"); MailForceExtraParameters = mail["ForceExtraParameters"].getString(); } { Hdf preg = config["Preg"]; PregBacktraceLimit = preg["BacktraceLimit"].getInt32(100000); PregRecursionLimit = preg["RecursionLimit"].getInt32(100000); } Extension::LoadModules(config); }
bool TestCppBase::TestIpBlockMap() { struct in6_addr addr; int bits; VERIFY(IpBlockMap::ReadIPv6Address("204.15.21.0/22", &addr, bits)); VS(bits, 118); VS(in6addrWord(addr, 0), 0x00000000L); VS(in6addrWord(addr, 1), 0x00000000L); VS(in6addrWord(addr, 2), 0x0000FFFFL); VS(in6addrWord(addr, 3), 0xCC0F1500L); VERIFY(IpBlockMap::ReadIPv6Address("127.0.0.1", &addr, bits)); VS(bits, 128); VS(in6addrWord(addr, 0), 0x00000000L); VS(in6addrWord(addr, 1), 0x00000000L); VS(in6addrWord(addr, 2), 0x0000FFFFL); VS(in6addrWord(addr, 3), 0x7F000001L); VERIFY(IpBlockMap::ReadIPv6Address( "1111:2222:3333:4444:5555:6666:789a:bcde", &addr, bits)); VS(bits, 128); VS(in6addrWord(addr, 0), 0x11112222L); VS(in6addrWord(addr, 1), 0x33334444L); VS(in6addrWord(addr, 2), 0x55556666L); VS(in6addrWord(addr, 3), 0x789abcdeL); VERIFY(IpBlockMap::ReadIPv6Address( "1111:2222:3333:4444:5555:6666:789a:bcde/68", &addr, bits)); VS(bits, 68); VS(in6addrWord(addr, 0), 0x11112222L); VS(in6addrWord(addr, 1), 0x33334444L); VS(in6addrWord(addr, 2), 0x55556666L); VS(in6addrWord(addr, 3), 0x789abcdeL); IpBlockMap::BinaryPrefixTrie root(true); unsigned char value[16]; // Default value with no additional nodes memset(value, 0, 16); VERIFY(root.isAllowed(value, 1)); value[0] = 0x80; VERIFY(root.isAllowed(value)); // Inheritance of parent allow value through multiple levels of new nodes IpBlockMap::BinaryPrefixTrie::InsertNewPrefix(&root, value, 1, false); value[0] = 0xf0; IpBlockMap::BinaryPrefixTrie::InsertNewPrefix(&root, value, 4, true); VERIFY(root.isAllowed(value)); value[0] = 0xe0; VERIFY(!root.isAllowed(value)); value[0] = 0xc0; VERIFY(!root.isAllowed(value)); value[0] = 0x80; VERIFY(!root.isAllowed(value)); value[0] = 0; VERIFY(root.isAllowed(value)); // > 1 byte in address value[2] = 0xff; IpBlockMap::BinaryPrefixTrie::InsertNewPrefix(&root, value, 24, false); VERIFY(!root.isAllowed(value)); value[3] = 0xff; VERIFY(!root.isAllowed(value)); value[2] = 0xfe; VERIFY(root.isAllowed(value)); // Exact address match value[2] = 0xff; value[15] = 1; IpBlockMap::BinaryPrefixTrie::InsertNewPrefix(&root, value, 128, true); VERIFY(root.isAllowed(value)); Hdf hdf; hdf.fromString( " 0 {\n" " Location = /test\n" " AllowFirst = true\n" " Ip {\n" " Allow {\n" " * = 127.0.0.1\n" " }\n" " Deny {\n" " * = 8.32.0.0/24\n" " * = aaaa:bbbb:cccc:dddd:eeee:ffff:1111::/80\n" " }\n" " }\n" " }\n" ); IpBlockMap ibm(hdf); VERIFY(!ibm.isBlocking("test/blah.php", "127.0.0.1")); VERIFY(ibm.isBlocking("test/blah.php", "8.32.0.104")); VERIFY(ibm.isBlocking("test/blah.php", "aaaa:bbbb:cccc:dddd:eeee:9999:8888:7777")); VERIFY(!ibm.isBlocking("test/blah.php", "aaaa:bbbb:cccc:dddd:eee3:4444:3333:2222")); return Count(true); }
void Config::ParseHdfString(const std::string hdfStr, Hdf &hdf, IniSetting::Map &ini) { hdf.fromString(hdfStr.c_str()); }
bool TestCppBase::TestVirtualHost() { IniSetting::Map ini = IniSetting::Map::object; Hdf hdf; hdf.fromString( " Server {\n" " AllowedDirectories.* = /var/www\n" " AllowedDirectories.* = /usr/bin\n" " }\n" " VirtualHost {\n" " flibtest {\n" " Prefix = flibtest.\n" " PathTranslation = flib/_bin\n" " ServerName = flibtest.facebook.com\n" " }\n" " upload {\n" " Prefix = upload.\n" " ServerVariables {\n" " TFBENV = 8{\n" " }\n" " overwrite {\n" " Server {\n" " AllowedDirectories.* = /var/www\n" " AllowedDirectories.* = /mnt\n" " AllowedDirectories.* = /tmp\n" " AllowedDirectories.* = /var/tmp/tao\n" " }\n" " MaxPostSize = 100MB\n" " UploadMaxFileSize = 100MB\n" " RequestTimeoutSeconds = 120\n" " }\n" " PathTranslation = html\n" " }\n" " default {\n" " LogFilters {\n" " * {\n" " url = /method/searchme\n" " params {\n" " * = q\n" " * = s\n" " * = atoken\n" " * = otoken\n" " }\n" " value = REMOVED\n" " }\n" " }\n" " RewriteRules {\n" " common {\n" " pattern = /html/common/\n" " to = http://3v4l.org\n" " qsa = true\n" " redirect = 301\n" " }\n" " }\n" " PathTranslation = htm\n" " }\n" " }\n" ); // reset RuntimeOption::AllowedDirectories to empty because if the INI // version of this test is run at the same time, we don't want to append // the same directories to it. We want to start fresh. RuntimeOption::AllowedDirectories.clear(); std::vector<VirtualHost> hosts; RuntimeOption::AllowedDirectories = Config::GetVector(ini, hdf, "Server.AllowedDirectories"); auto cb = [&] (const IniSetting::Map &ini_cb, const Hdf &hdf_cb, const std::string &host) { if (VirtualHost::IsDefault(ini_cb, hdf_cb, host)) { VirtualHost::GetDefault().init(ini_cb, hdf_cb, host); VirtualHost::GetDefault(). addAllowedDirectories(RuntimeOption::AllowedDirectories); } else { auto vh = VirtualHost(ini_cb, hdf_cb, host); // These will be added // " AllowedDirectories.* = /var/www\n" // " AllowedDirectories.* = /usr/bin\n" vh.addAllowedDirectories(RuntimeOption::AllowedDirectories); hosts.push_back(vh); } }; Config::Iterate(cb, ini, hdf, "VirtualHost"); for (auto& host : hosts) { VirtualHost::SetCurrent(&host); auto name = host.getName(); if (name == "flibtest") { VERIFY(host.getPathTranslation() == "flib/_bin/"); // the / is added VERIFY(host.getDocumentRoot() == RuntimeOption::SourceRoot + "flib/_bin"); VERIFY(host.getServerVars().size() == 0); VERIFY(VirtualHost::GetAllowedDirectories().size() == 2); VERIFY(host.valid() == true); VERIFY(host.hasLogFilter() == false); } else if (name == "upload") { VERIFY(host.getPathTranslation() == "html/"); // the / is added VERIFY(host.getDocumentRoot() == RuntimeOption::SourceRoot + "html"); // SortALlowedDirectories might add something and remove // duplicates. In this case, /var/releases/continuous_www_scripts4 // was added and the duplicate /var/www was removed.s VERIFY(VirtualHost::GetAllowedDirectories().size() == 6); VERIFY(host.valid() == true); VERIFY(host.hasLogFilter() == false); VERIFY(VirtualHost::GetMaxPostSize() == 104857600); } } VERIFY(VirtualHost::GetDefault().getPathTranslation() == "htm/"); VERIFY(VirtualHost::GetDefault().hasLogFilter() == true); String rw("/html/common/"); String h("default"); bool q = false; int rd = 0; VirtualHost::GetDefault().rewriteURL(h, rw, q, rd); VERIFY(rw.toCppString() == "http://3v4l.org"); VERIFY(rd == 301); return Count(true); }
int prepareOptions(ProgramOptions &po, int argc, char **argv) { options_description desc("HipHop Compiler for PHP Usage:\n\n" "\thphp <options> <inputs>\n\n" "Options"); desc.add_options() ("help", "display this message") ("version", "display version number") ("target,t", value<string>(&po.target)->default_value("run"), "lint | " "analyze | " "php | " "cpp | " "sep-ext-cpp | " "filecache | " "run (default)") ("format,f", value<string>(&po.format), "lint: (none); \n" "analyze: (none); \n" "php: trimmed (default) | inlined | pickled | typeinfo |" " <any combination of them by any separator>; \n" "cpp: cluster (default) | file | sys | exe | lib; \n" "run: cluster (default) | file") ("cluster-count", value<int>(&po.clusterCount)->default_value(0), "Cluster by file sizes and output roughly these many number of files. " "Use 0 for no clustering.") ("input-dir", value<string>(&po.inputDir), "input directory") ("program", value<string>(&po.program)->default_value("program"), "final program name to use") ("args", value<string>(&po.programArgs), "program arguments") ("inputs,i", value<vector<string> >(&po.inputs), "input file names") ("input-list", value<string>(&po.inputList), "file containing list of file names, one per line") ("include-path", value<vector<string> >(&Option::IncludeSearchPaths)->composing(), "a list of include paths to search for files being included in includes " "or requires but cannot be found assuming relative paths") ("module", value<vector<string> >(&po.modules)->composing(), "directories containing all input files") ("exclude-dir", value<vector<string> >(&po.excludeDirs)->composing(), "directories to exclude from the input") ("fmodule", value<vector<string> >(&po.fmodules)->composing(), "same with module, except no exclusion checking is performed, so these " "modules are forced to be included") ("ffile", value<vector<string> >(&po.ffiles)->composing(), "extra PHP files forced to include without exclusion checking") ("exclude-file", value<vector<string> >(&po.excludeFiles)->composing(), "files to exclude from the input, even if parse-on-demand finds it") ("exclude-pattern", value<vector<string> >(&po.excludePatterns)->composing(), "regex (in 'find' command's regex command line option format) of files " "or directories to exclude from the input, even if parse-on-demand finds " "it") ("exclude-static-pattern", value<vector<string> >(&po.excludeStaticPatterns)->composing(), "regex (in 'find' command's regex command line option format) of files " "or directories to exclude from static content cache") ("exclude-static-dir", value<vector<string> >(&po.excludeStaticDirs)->composing(), "directories to exclude from static content cache") ("exclude-static-file", value<vector<string> >(&po.excludeStaticFiles)->composing(), "files to exclude from static content cache") ("cfile", value<vector<string> >(&po.cfiles)->composing(), "extra static files forced to include without exclusion checking") ("cmodule", value<vector<string> >(&po.cmodules)->composing(), "extra directories for static files without exclusion checking") ("parse-on-demand", value<bool>(&po.parseOnDemand)->default_value(true), "whether to parse files that are not specified from command line") ("branch", value<string>(&po.branch), "SVN branch") ("revision", value<int>(&po.revision), "SVN revision") ("output-dir,o", value<string>(&po.outputDir), "output directory") ("output-file", value<string>(&po.outputFile), "output file") ("sync-dir", value<string>(&po.syncDir), "Files will be created in this directory first, then sync with output " "directory without overwriting identical files. Great for incremental " "compilation and build.") ("optimize-level", value<int>(&po.optimizeLevel)->default_value(1), "optimization level") ("gen-stats", value<bool>(&po.genStats)->default_value(false), "whether to generate code errors") ("keep-tempdir,k", value<bool>(&po.keepTempDir)->default_value(false), "whether to keep the temporary directory") ("db-stats", value<string>(&po.dbStats), "database connection string to save code errors: " "<username>:<password>@<host>:<port>/<db>") ("no-type-inference", value<bool>(&po.noTypeInference)->default_value(false), "turn off type inference for C++ code generation") ("no-min-include", value<bool>(&po.noMinInclude)->default_value(false), "turn off minimium include analysis when target is \"analyze\"") ("no-meta-info", value<bool>(&po.noMetaInfo)->default_value(false), "do not generate class map, function jump table and macros " "when generating code; good for demo purposes") ("config,c", value<vector<string> >(&po.config)->composing(), "config file name") ("config-dir", value<string>(&po.configDir), "root directory configuration is based on (for example, " "excluded directories may be relative path in configuration.") ("config-value,v", value<vector<string> >(&po.confStrings)->composing(), "individual configuration string in a format of name=value, where " "name can be any valid configuration for a config file") ("log,l", value<int>(&po.logLevel)->default_value(-1), "-1: (default); 0: no logging; 1: errors only; 2: warnings and errors; " "3: informational as well; 4: really verbose.") ("force", value<bool>(&po.force)->default_value(true), "force to ignore code generation errors and continue compilations") ("file-cache", value<string>(&po.filecache), "if specified, generate a static file cache with this file name") ("rtti-directory", value<string>(&po.rttiDirectory)->default_value(""), "the directory of rtti profiling data") ("java-root", value<string>(&po.javaRoot)->default_value("php"), "the root package of generated Java FFI classes") ("generate-ffi", value<bool>(&po.generateFFI)->default_value(false), "generate ffi stubs") ("dump", value<bool>(&po.dump)->default_value(false), "dump the program graph") ("coredump", value<bool>(&po.coredump)->default_value(false), "turn on coredump") ("nofork", value<bool>(&po.nofork)->default_value(false), "forking is needed for large compilation to release memory before g++" "compilation. turning off forking can help gdb debugging.") ("fl-annotate", value<bool>(&po.fl_annotate)->default_value(false), "Annote emitted source with compiler file-line info") ("opts", value<string>(&po.optimizations)->default_value("none"), "Set optimizations to enable/disable") ("ppp", value<string>(&po.ppp)->default_value(""), "Preprocessed partition configuration. To speed up distcc compilation, " "bin/ppp.php can pre-compute better partition between different .cpp " "files according to preprocessed file sizes, instead of original file " "sizes (default). Run bin/ppp.php to generate an HDF configuration file " "to specify here.") ; positional_options_description p; p.add("inputs", -1); variables_map vm; try { store(command_line_parser(argc, argv).options(desc).positional(p).run(), vm); notify(vm); } catch (unknown_option e) { cerr << "Error in command line: " << e.what() << "\n\n"; cout << desc << "\n"; return -1; } if (argc <= 1 || vm.count("help")) { cout << desc << "\n"; return 1; } if (vm.count("version")) { #ifdef HPHP_VERSION #undefine HPHP_VERSION #endif #define HPHP_VERSION(v) cout << "HipHop Compiler v" #v << "\n"; #include "../version" return 1; } // log level if (po.logLevel != -1) { Logger::LogLevel = (Logger::LogLevelType)po.logLevel; } else if (po.target == "run") { Logger::LogLevel = Logger::LogNone; } else { Logger::LogLevel = Logger::LogInfo; } // config and system Option::GenerateCPPMain = true; if (po.noMetaInfo) { Option::GenerateCPPMetaInfo = false; Option::GenerateCPPMacros = false; } Option::FlAnnotate = po.fl_annotate; Hdf config; for (vector<string>::const_iterator it = po.config.begin(); it != po.config.end(); ++it) { config.append(*it); } for (unsigned int i = 0; i < po.confStrings.size(); i++) { config.fromString(po.confStrings[i].c_str()); } Option::Load(config); vector<string> badnodes; config.lint(badnodes); for (unsigned int i = 0; i < badnodes.size(); i++) { Logger::Error("Possible bad config node: %s", badnodes[i].c_str()); } if (po.inputDir.empty()) { po.inputDir = '.'; } po.inputDir = Util::normalizeDir(po.inputDir); if (po.configDir.empty()) { po.configDir = po.inputDir; } po.configDir = Util::normalizeDir(po.configDir); Option::RootDirectory = po.configDir; for (unsigned int i = 0; i < po.excludeDirs.size(); i++) { Option::PackageExcludeDirs.insert (Util::normalizeDir(po.excludeDirs[i])); } for (unsigned int i = 0; i < po.excludeFiles.size(); i++) { Option::PackageExcludeFiles.insert(po.excludeFiles[i]); } for (unsigned int i = 0; i < po.excludePatterns.size(); i++) { Option::PackageExcludePatterns.insert (Util::format_pattern(po.excludePatterns[i], true)); } for (unsigned int i = 0; i < po.excludeStaticDirs.size(); i++) { Option::PackageExcludeStaticDirs.insert (Util::normalizeDir(po.excludeStaticDirs[i])); } for (unsigned int i = 0; i < po.excludeStaticFiles.size(); i++) { Option::PackageExcludeStaticFiles.insert(po.excludeStaticFiles[i]); } for (unsigned int i = 0; i < po.excludeStaticPatterns.size(); i++) { Option::PackageExcludeStaticPatterns.insert (Util::format_pattern(po.excludeStaticPatterns[i], true)); } if (po.target == "cpp" && po.format == "sys") { BuiltinSymbols::NoSuperGlobals = true; // so to generate super globals Option::AnalyzePerfectVirtuals = false; } Option::SystemGen = (po.target == "cpp" && po.format == "sys") ; Option::ProgramName = po.program; Option::PreprocessedPartitionConfig = po.ppp; if (po.target == "cpp") { if (po.format.empty()) po.format = "cluster"; } else if (po.target == "php") { if (po.format.empty()) po.format = "trimmed"; } else if (po.target == "run") { if (po.format.empty()) po.format = "cluster"; } if (po.optimizeLevel > 0) { Option::PreOptimization = true; Option::PostOptimization = true; } if (po.generateFFI) { Option::GenerateFFI = true; Option::JavaFFIRootPackage = po.javaRoot; } return 0; }