int main(int argc, char* argv[]) { initLogging("OptionPricingTest.log"); /** Ask for a simple option pricings a few times */ int t = 2; double strike = 0.01; double sigma = 0.02; double timestep = 0.05; int numTimeStep = (int)(10/0.05); int numMaturity = 200; int paraNode = 50; int numPathGroup = 20; double T = 10; bool status = true; for (int k = 0; k < t; k++) { double res; optionPricing(strike, sigma, timestep, numMaturity, paraNode, numPathGroup, T, &res); printf("res = %d\n", res); } return status ? 0 : 1; }
void initInjectorCentral(void) { initLogging(&logger, "InjectorCentral"); chThdCreateStatic(benchThreadStack, sizeof(benchThreadStack), NORMALPRIO, (tfunc_t) benchThread, NULL); for (int i = 0; i < engineConfiguration->cylindersCount; i++) { is_injector_enabled[i] = true; } // todo: should we move this code closer to the injection logic? for (int i = 0; i < engineConfiguration->cylindersCount; i++) { io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + i); outputPinRegisterExt2(getPinName(pin), pin, boardConfiguration->injectionPins[i], &boardConfiguration->injectionPinMode); } printStatus(); addConsoleActionII("injector", setInjectorEnabled); addConsoleActionII("fuelpumpbench", &fuelpumpbench); addConsoleActionSSS("fuelbench", &fuelbench); addConsoleActionSSS("sparkbench", &sparkbench); addConsoleActionSSSSS("fuelbench2", &fuelbench2); addConsoleActionSSSSS("sparkbench2", &sparkbench2); }
int main(int argc, char* argv[]) { std::srand (unsigned(std::time(0))); initLogging(); Model* model = new Model; Controller* controller = new Controller(model); std::vector<std::string> armyFiles; armyFiles.push_back("moloch.json"); armyFiles.push_back("outpost.json"); TokenLoader::getInstance() -> loadArmies(armyFiles, controller); controller -> initializeNewPlayer(MOLOCH); controller -> initializeNewPlayer(OUTPOST); QApplication app(argc, argv); mainWindowInit(&app, controller); std::vector<Token*> tokens = model -> getCurrentPlayer() -> hiddenTokens; for (unsigned i=0; i<tokens.size(); ++i) { qDebug() << tokens.at(i) -> getName().c_str(); } return app.exec(); }
void initFlash(void) { initLogging(&logger, "Flash memory"); addConsoleAction("readconfig", readFromFlash); addConsoleAction("writeconfig", writeToFlash); addConsoleAction("resetconfig", doResetConfiguration); }
void startTunerStudioConnectivity(void) { initLogging(&logger, "tuner studio"); if (sizeof(engine_configuration_s) != getTunerStudioPageSize(0)) firmwareError("TS page size mismatch: %d/%d", sizeof(engine_configuration_s), getTunerStudioPageSize(0)); if (sizeof(TunerStudioOutputChannels) != TS_OUTPUT_SIZE) firmwareError("TS outputs size mismatch: %d/%d", sizeof(TunerStudioOutputChannels), TS_OUTPUT_SIZE); memset(&tsState, 0, sizeof(tsState)); #if EFI_PROD_CODE if (isSerialOverUart()) { print("TunerStudio over USB serial"); usb_serial_start(); } else { print("TunerStudio over USART"); mySetPadMode("tunerstudio rx", TS_SERIAL_RX_PORT, TS_SERIAL_RX_PIN, PAL_MODE_ALTERNATE(TS_SERIAL_AF)); mySetPadMode("tunerstudio tx", TS_SERIAL_TX_PORT, TS_SERIAL_TX_PIN, PAL_MODE_ALTERNATE(TS_SERIAL_AF)); sdStart(TS_SERIAL_UART_DEVICE, &tsSerialConfig); } #endif /* EFI_PROD_CODE */ syncTunerStudioCopy(); addConsoleAction("tsinfo", printStats); chThdCreateStatic(TS_WORKING_AREA, sizeof(TS_WORKING_AREA), NORMALPRIO, tsThreadEntryPoint, NULL); }
// Software Initialization: // input parameter: // void : nothing // return type: // int : return SUCCESS, init Software int init(void) { int level; double actual, desired; char sensorTempData[5]; initLogging("temp_log"); initCSVFile("temp_csv"); initConfigFile("temp_config"); logging(INFO, "\nStarting CliConWARE Software...."); // Printing current hour: printf(" -- Current hour : %d:%02d\n", getHour(), getMin()); // Printing actual temperature: readData("/dev/temp_sensor", sensorTempData); actual = (double) atof(sensorTempData)/ 1000; printf(" -- Actual temperature : %.2f°C\n", actual); // Printing desired temperature: desired = getDesired("temp_config"); printf(" -- Desired temperature : %.2f°C\n", desired); // Printing current knob level: level = map(actual); printf(" -- Current knob level : %d\n", level); logging(INFO, "The Software will start in 3 seconds.....\n"); sleep(3); return SUCCESS; }
void initProgram(int argc, char ** argv, char ** envp) { cfg.argc = argc; cfg.argv = argv; cfg.envp = envp; cfg.help = 0; cfg.debug = 0; cfg.daemon = 0; cfg.version = 0; cfg.syslog = 0; cfg.port = 0; cfg.passkey = NULL; initOptions(); printDebug(); printHelp(); printVersion(); signal(SIGINT, mySignal); daemonize(); initLogging(); initServer(); }
int main(int argc, const char **argv) { initLogging(); Ea3dPlatform myPlatform(640, 480); myPlatform.initPlatform(); myPlatform.render(); exit(EXIT_SUCCESS); }
void initHip9011(void) { initLogging(&logger, "HIP driver"); print("Starting HIP9011/TPIC8101 driver\r\n"); spiStart(driver, &spicfg); chThdCreateStatic(htThreadStack, sizeof(htThreadStack), NORMALPRIO, (tfunc_t) ivThread, NULL); }
void initIgnitionCentral(void) { initLogging(&logger, "IgnitionCentral"); outputPinRegisterExt2("sparkout1", SPARKOUT_1_OUTPUT, boardConfiguration->ignitionPins[0], &boardConfiguration->ignitionPinMode); outputPinRegisterExt2("sparkout2", SPARKOUT_2_OUTPUT, boardConfiguration->ignitionPins[1], &boardConfiguration->ignitionPinMode); outputPinRegisterExt2("sparkout3", SPARKOUT_3_OUTPUT, boardConfiguration->ignitionPins[2], &boardConfiguration->ignitionPinMode); outputPinRegisterExt2("sparkout4", SPARKOUT_4_OUTPUT, boardConfiguration->ignitionPins[3], &boardConfiguration->ignitionPinMode); }
void initConsoleLogic() { #if EFI_PROD_CODE || EFI_SIMULATOR initLogging(&logging, "rfi console"); #endif /* EFI_PROD_CODE */ resetConsoleActions(); addConsoleAction("help", helpCommand); addConsoleActionI("echo", echo); }
PADsetLogDir(const char *dir) { // Get the path to the log directory. s_strLogPath = (dir == NULL) ? "logs/" : dir; // Reload the log file after updated the path CloseLogging(); initLogging(); }
visualiser::Visualiser::Visualiser(const visualiser::VisualiserConfig &config) : _config(config), _renderer(std::make_unique<rendering::Renderer>(config.resX, config.resY, config.fullscreen)) { initLogging(config.debugMessages); loadShowFile(config.showFilePath); if (config.realLighting) _renderer->setLightingMode(rendering::Renderer::REALISTIC_LIGHTING); }
// Software Initialization: // input parameter: // void : nothing // return type: // int : return SUCCESS int init(void) { // TODO: MESSY int command; double actual; char sensorTempData[5]; initLogging("G44/log"); initCSVFile(); initConfigFile(); if (extern_argc != 2) { logging(WARN, "Error running software!, Mismatch number of argument!!!"); logging(WARN, "E.g run as follow: ./climateControlSoftware 22.5"); logging(WARN, "Terminating program.........."); logging(ERROR, "Terminating program..........Done"); } logging(INFO, "Initializing Climate Control Software...."); sleep(1); logging(INFO, "Initializing Climate Control Software....Done"); sleep(1); logging(INFO, "Checking sensor device file...."); sleep(1); logging(INFO, "Openning /dev/temp_sensor...."); FILE* file = openFile("/dev/temp_sensor", "r"); readData("/dev/temp_sensor", sensorTempData); actual = (double) atof(sensorTempData)/ 1000; sleep(1); //logging(INFO, "Initializing Climate Control Software....Done"); printf("Current sensor data is.... %.2f°C\n", actual); sleep(1); fclose(file); logging(INFO, "Checking sensor device file....Done"); sleep(1); logging(INFO, "Checking knob device file...."); sleep(1); logging(INFO, "Openning /dev/temp_knob...."); file = openFile("/dev/temp_knob", "r"); command = map(actual); sleep(1); //logging(INFO, "Initializing Climate Control Software....Done"); printf("Current knob level is.... %d\n", command); sleep(1); fclose(file); logging(INFO, "Checking knob device file....Done"); sleep(1); logging(INFO, "The PID Controller will start in 5 seconds....."); sleep(5); logging(INFO, "The PID Controller will start in 5 seconds.....Done"); return SUCCESS; }
int main(int argc, char **argv) { LogLevel logLevel = LogLevel::Error; Path file; for (int i=1; i<argc; ++i) { if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) { ++logLevel; } else { file = argv[i]; } } setenv("LIBCLANG_NOTHREADS", "1", 0); signal(SIGSEGV, sigHandler); signal(SIGABRT, sigHandler); signal(SIGBUS, sigHandler); Flags<LogMode> logType = LogStderr; std::shared_ptr<SyslogCloser> closer; if (ClangIndexer::serverOpts() & Server::RPLogToSyslog) { logType |= LogSyslog; closer.reset(new SyslogCloser); } initLogging(argv[0], logType, logLevel); (void)closer; RTags::initMessages(); std::shared_ptr<EventLoop> eventLoop(new EventLoop); eventLoop->init(EventLoop::MainEventLoop); String data; if (!file.isEmpty()) { data = file.readAll(); } else { uint32_t size; if (!fread(&size, sizeof(size), 1, stdin)) { error() << "Failed to read from stdin"; return 1; } data.resize(size); if (!fread(&data[0], size, 1, stdin)) { error() << "Failed to read from stdin"; return 2; } // FILE *f = fopen("/tmp/data", "w"); // fwrite(data.constData(), data.size(), 1, f); // fclose(f); } ClangIndexer indexer; if (!indexer.exec(data)) { error() << "ClangIndexer error"; return 3; } return 0; }
void initFakeBoard(void) { initLogging(&logger, "simulator board"); addConsoleActionF("set_mock_clt_voltage", setCltVoltage); addConsoleActionF("set_mock_iat_voltage", setIatVoltage); addConsoleActionF("set_mock_maf_voltage", setMafVoltage); addConsoleActionF("set_mock_afr_voltage", setAfrVoltage); addConsoleActionF("set_mock_tps_voltage", setTpsVoltage); addConsoleActionF("set_mock_map_voltage", setMapVoltage); }
int main(){ initLogging("f**k.txt"); startLogging(); printf("hello\n"); endLogging(); printTimeLog("main"); cleanLogging(); return 0; }
int main(int argc, char *argv[]) { QApplication app(argc, argv); QCoreApplication::setApplicationName("2D-model"); QCoreApplication::setApplicationVersion("1.0"); setDefaultLocale(); QCommandLineParser parser; parser.setApplicationDescription(description); parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument("qrs-file", QObject::tr("Save file to be interpreted.")); QCommandLineOption backgroundOption({"b", "background"}, QObject::tr("Run emulation in background.")); QCommandLineOption platformOption("platform" , QObject::tr("Use this option set to \"minimal\" to disable connection to X server"), "minimal"); QCommandLineOption reportOption("report", QObject::tr("A path to file where checker results will be written (JSON)") , "path-to-report", "report.json"); QCommandLineOption trajectoryOption("trajectory", QObject::tr("A path to file where robot`s trajectory will be"\ " written. The writing will not be performed not immediately, each trajectory point will be written"\ " just when obtained by checker, so FIFOs are recommended to be targets for this option.") , "path-to-trajectory", "trajectory.fifo"); parser.addOption(backgroundOption); parser.addOption(platformOption); parser.addOption(reportOption); parser.addOption(trajectoryOption); qsrand(time(0)); initLogging(); QLOG_INFO() << "------------------- APPLICATION STARTED --------------------"; QLOG_INFO() << "Running on" << qReal::PlatformInfo::prettyOsVersion(); QLOG_INFO() << "Arguments:" << app.arguments(); QLOG_INFO() << "Setting default locale to" << QLocale().name(); parser.process(app); const QStringList positionalArgs = parser.positionalArguments(); if (positionalArgs.size() != 1) { parser.showHelp(); } const QString qrsFile = positionalArgs.first(); const bool backgroundMode = parser.isSet(backgroundOption); const QString report = parser.isSet(reportOption) ? parser.value(reportOption) : QString(); const QString trajectory = parser.isSet(trajectoryOption) ? parser.value(trajectoryOption) : QString(); twoDModel::Runner runner(report, trajectory); if (!runner.interpret(qrsFile, backgroundMode)) { return 2; } const int exitCode = app.exec(); QLOG_INFO() << "------------------- APPLICATION FINISHED -------------------"; return exitCode; }
void lcd_HD44780_init(void) { initLogging(&logger, "HD44780 driver"); addConsoleAction("lcdinfo", lcdInfo); if (engineConfiguration->displayMode == DM_HD44780) { mySetPadMode("lcd RS", HD44780_PORT_RS, HD44780_PIN_RS, PAL_MODE_OUTPUT_PUSHPULL); mySetPadMode("lcd E", HD44780_PORT_E, HD44780_PIN_E, PAL_MODE_OUTPUT_PUSHPULL); mySetPadMode("lcd DB4", HD44780_PORT_DB4, HD44780_PIN_DB4, PAL_MODE_OUTPUT_PUSHPULL); mySetPadMode("lcd DB6", HD44780_PORT_DB5, HD44780_PIN_DB5, PAL_MODE_OUTPUT_PUSHPULL); mySetPadMode("lcd DB7", HD44780_PORT_DB6, HD44780_PIN_DB6, PAL_MODE_OUTPUT_PUSHPULL); mySetPadMode("lcd DB8", HD44780_PORT_DB7, HD44780_PIN_DB7, PAL_MODE_OUTPUT_PUSHPULL); palWritePad(HD44780_PORT_RS, HD44780_PIN_RS, 0); palWritePad(HD44780_PORT_E, HD44780_PIN_E, 0); palWritePad(HD44780_PORT_DB4, HD44780_PIN_DB4, 0); palWritePad(HD44780_PORT_DB5, HD44780_PIN_DB5, 0); palWritePad(HD44780_PORT_DB6, HD44780_PIN_DB6, 0); palWritePad(HD44780_PORT_DB7, HD44780_PIN_DB7, 0); } // LCD needs some time to wake up chThdSleepMilliseconds(50); lcd_HD44780_write(LCD_2X16_RESET); chThdSleepMilliseconds(1); lcd_HD44780_write(0x30); lcd_HD44780_write(LCD_2X16_4_BIT_BUS); // 4 bit, 2 line chThdSleepMicroseconds(40); lcd_HD44780_write(LCD_2X16_4_BIT_BUS); // 4 bit, 2 line lcd_HD44780_write(0x80); chThdSleepMicroseconds(40); lcd_HD44780_write(0x00); // display and cursor control lcd_HD44780_write(0xC0); chThdSleepMicroseconds(40); lcd_HD44780_write(0x00); // display clear lcd_HD44780_write(0x01); chThdSleepMilliseconds(2); lcd_HD44780_write(0x00); // entry mode set lcd_HD44780_write(0x60); lcd_HD44780_set_position(0, 0); lcd_HD44780_print_string("rusefi here\n"); lcd_HD44780_print_string(__DATE__); }
void initRpmCalculator(void) { initLogging(&logger, "rpm calc"); strcpy(shaft_signal_msg_index, "_"); rpmState.rpm = 0; // we need this initial to have not_running at first invocation rpmState.lastRpmEventTime = (time_t)-10 * CH_FREQUENCY; registerShaftPositionListener(&shaftPositionCallback, "rpm reporter"); registerShaftPositionListener(&tdcMarkCallback, "chart TDC mark"); }
void initTriggerCentral(Engine *engine) { strcpy((char*) shaft_signal_msg_index, "x_"); #if EFI_WAVE_CHART initWaveChart(&waveChart); #endif /* EFI_WAVE_CHART */ #if EFI_PROD_CODE || EFI_SIMULATOR initLogging(&logger, "ShaftPosition"); addConsoleActionP("triggerinfo", (VoidPtr) triggerInfo, engine); addConsoleActionP("triggershapeinfo", (VoidPtr) triggerShapeInfo, engine); #endif #if EFI_HISTOGRAMS initHistogram(&triggerCallback, "all callbacks"); #endif /* EFI_HISTOGRAMS */ }
void initWaveAnalyzer(void) { #if EFI_WAVE_ANALYZER || defined(__DOXYGEN__) initLogging(&logger, "wave"); initWave(WA_CHANNEL_1, 0); initWave(WA_CHANNEL_2, 1); addTriggerEventListener(&waTriggerEventListener, "wave analyzer", (void*) NULL); addConsoleActionII("set_logic_input_mode", setWaveModeSilent); chThdCreateStatic(waThreadStack, sizeof(waThreadStack), NORMALPRIO, waThread, (void*) NULL); #else print("wave disabled\r\n"); #endif }
void initializeConsole() { initIntermediateLoggingBuffer(); initConsoleLogic(); startChibiosConsole(&handleConsoleLine); initLogging(&logger, "console"); sayHello(); addConsoleAction("hello", sayHello); #if EFI_HAS_RESET addConsoleAction("reset", scheduleReset); #endif addConsoleAction("fatal", myfatal); addConsoleAction("threadsinfo", cmd_threads); }
PADinit(u32 flags) { initLogging(); LoadConfig(); key_status = new KeyStatus(); Pad::reset_all(); query.reset(); for (int port = 0; port < 2; port++) slots[port] = 0; return 0; }
void initElectronicThrottle(void) { initLogging(&logger, "Electronic Throttle"); engineConfiguration->tpsMin = 140; engineConfiguration->tpsMax = 898; // these two lines are controlling direction // outputPinRegister("etb1", ELECTRONIC_THROTTLE_CONTROL_1, ETB_CONTROL_LINE_1_PORT, ETB_CONTROL_LINE_1_PIN); // outputPinRegister("etb2", ELECTRONIC_THROTTLE_CONTROL_2, ETB_CONTROL_LINE_2_PORT, ETB_CONTROL_LINE_2_PIN); // this line used for PWM startSimplePwmExt(&etbPwm, "etb", boardConfiguration->electronicThrottlePin1, ELECTRONIC_THROTTLE_CONTROL_1, 500, 0.80); addConsoleActionI("e", setThrottleConsole); chThdCreateStatic(etbTreadStack, sizeof(etbTreadStack), NORMALPRIO, (tfunc_t) etbThread, NULL); }
NLogger::NLogger(std::string logFile, std::string moduleName, LogFilterListenType type) { std::function<void(SeverityLevel)> callback = std::bind( &NLogger::changeLogFilter, this, std::placeholders::_1); switch (type) { case LogFilterListenType::LOG_FILTER_NETWORK: logListener = std::make_shared<NetworkListener>(moduleName, callback); break; case LogFilterListenType::LOG_FILTER_STANDALONE: logListener = std::make_shared<StandAloneListener>(moduleName, callback); break; default: logListener = std::make_shared<StandAloneListener>(moduleName, callback); break; } initLogging(); }
void startIdleThread() { initLogging(&logger, "Idle Valve Control"); startSimplePwm(&idleValve, "Idle Valve", boardConfiguration->idleValvePin, 0.5, IDLE_AIR_CONTROL_VALVE_PWM_FREQUENCY, IDLE_VALVE ); idleInit(&idle); scheduleMsg(&logger, "initial idle %d", idle.value); chThdCreateStatic(ivThreadStack, sizeof(ivThreadStack), NORMALPRIO, (tfunc_t)ivThread, NULL); // this is idle switch INPUT - sometimes there is a switch on the throttle pedal // this switch is not used yet mySetPadMode("idle switch", getHwPort(boardConfiguration->idleSwitchPin), getHwPin(boardConfiguration->idleSwitchPin), PAL_MODE_INPUT); addConsoleActionI("set_idle_rpm", setIdleRpmAction); addConsoleActionI("set_idle_pwm", setIdleValvePwm); addConsoleActionI("set_idle_enabled", setIdleControlEnabled); }
void initPwmTester(void) { initLogging(&logger, "pwm test"); addConsoleActionI("pwmtest", startPwmTest); startPwmTest(1000); /** * injector channels #4-#8 are used for individual squirt test */ // todo: yet, it's some horrible code duplication outSignals[0].output = &enginePins.injectors[4]; outSignals[1].output = &enginePins.injectors[5]; outSignals[2].output = &enginePins.injectors[6]; outSignals[3].output = &enginePins.injectors[7]; outSignals[4].output = &enginePins.injectors[8]; outSignals[5].output = &enginePins.injectors[9]; outSignals[6].output = &enginePins.injectors[10]; outSignals[7].output = &enginePins.injectors[11]; /** * this would schedule a callback in 2ms from now */ scheduleTask("test", &ioTest, MS2US(2), testCallback, NULL); }
void initWaveChart(WaveChart *chart) { initLogging(&logger, "wave info"); if (!isChartActive) { printMsg(&logger, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! chart disabled"); } printStatus(); initLoggingExt(&chart->logging, "wave chart", WAVE_LOGGING_BUFFER, sizeof(WAVE_LOGGING_BUFFER)); chart->isInitialized = TRUE; #if DEBUG_WAVE initLoggingExt(&debugLogging, "wave chart debug", &debugLogging.DEFAULT_BUFFER, sizeof(debugLogging.DEFAULT_BUFFER)); #endif #if EFI_HISTOGRAMS initHistogram(&waveChartHisto, "wave chart"); #endif /* EFI_HISTOGRAMS */ resetWaveChart(chart); addConsoleActionI("chartsize", setChartSize); addConsoleActionI("chart", setChartActive); }
int main(int argc, char** argv) { RemoveCrashDump removeCrashDump; #ifdef OS_Darwin struct rlimit rlp; if (getrlimit(RLIMIT_NOFILE, &rlp) == 0) { if (rlp.rlim_cur < 1000) { rlp.rlim_cur = 1000; setrlimit(RLIMIT_NOFILE, &rlp); } } #endif Rct::findExecutablePath(*argv); bool daemon = false; Server::Options serverOpts; const char * runtimeDir = getenv("XDG_RUNTIME_DIR"); if (runtimeDir == NULL) { serverOpts.socketFile = String::format<128>("%s.rdm", Path::home().constData()); } else { serverOpts.socketFile = String::format<1024>("%s/rdm.socket", runtimeDir); } serverOpts.jobCount = std::max(2, ThreadPool::idealThreadCount()); serverOpts.headerErrorJobCount = -1; serverOpts.rpVisitFileTimeout = DEFAULT_RP_VISITFILE_TIMEOUT; serverOpts.rpIndexDataMessageTimeout = DEFAULT_RP_INDEXER_MESSAGE_TIMEOUT; serverOpts.rpConnectTimeout = DEFAULT_RP_CONNECT_TIMEOUT; serverOpts.rpConnectAttempts = DEFAULT_RP_CONNECT_ATTEMPTS; serverOpts.maxFileMapScopeCacheSize = DEFAULT_RDM_MAX_FILE_MAP_CACHE_SIZE; serverOpts.errorLimit = DEFAULT_ERROR_LIMIT; serverOpts.rpNiceValue = INT_MIN; serverOpts.options = Server::Wall|Server::SpellChecking; serverOpts.maxCrashCount = DEFAULT_MAX_CRASH_COUNT; serverOpts.completionCacheSize = DEFAULT_COMPLETION_CACHE_SIZE; serverOpts.maxIncludeCompletionDepth = DEFAULT_MAX_INCLUDE_COMPLETION_DEPTH; serverOpts.rp = defaultRP(); strcpy(crashDumpFilePath, "crash.dump"); #ifdef FILEMANAGER_OPT_IN serverOpts.options |= Server::NoFileManagerWatch; #endif // #ifndef NDEBUG // serverOpts.options |= Server::SuspendRPOnCrash; // #endif serverOpts.dataDir = String::format<128>("%s.rtags", Path::home().constData()); if (!serverOpts.dataDir.exists()) { const char * dataDir = getenv("XDG_CACHE_HOME"); serverOpts.dataDir = dataDir ? dataDir : Path::home() + ".cache"; serverOpts.dataDir += "/rtags/"; serverOpts.dataDir.mkdir(Path::Recursive); } Path logFile; Flags<LogFlag> logFlags = DontRotate|LogStderr; LogLevel logLevel(LogLevel::Error); LogLevel logFileLogLevel(LogLevel::Error); bool sigHandler = true; assert(Path::home().endsWith('/')); int inactivityTimeout = 0; const std::initializer_list<CommandLineParser::Option<OptionType> > opts = { { None, 0, 0, CommandLineParser::NoValue, "Options:" }, { Help, "help", 'h', CommandLineParser::NoValue, "Display this page." }, { Version, "version", 0, CommandLineParser::NoValue, "Display version." }, { IncludePath, "include-path", 'I', CommandLineParser::Required, "Add additional include path to clang." }, { Isystem, "isystem", 's', CommandLineParser::Required, "Add additional system include path to clang." }, { Define, "define", 'D', CommandLineParser::Required, "Add additional define directive to clang." }, { DefaultArgument, "default-argument", 0, CommandLineParser::Required, "Add additional argument to clang." }, { LogFile, "log-file", 'L', CommandLineParser::Required, "Log to this file." }, { CrashDumpFile, "crash-dump-file", 0, CommandLineParser::Required, "File to dump crash log to (default is <datadir>/crash.dump)." }, { SetEnv, "setenv", 'e', CommandLineParser::Required, "Set this environment variable (--setenv \"foobar=1\")." }, { NoWall, "no-Wall", 'W', CommandLineParser::NoValue, "Don't use -Wall." }, { Weverything, "Weverything", 'u', CommandLineParser::NoValue, "Use -Weverything." }, { Verbose, "verbose", 'v', CommandLineParser::NoValue, "Change verbosity, multiple -v's are allowed." }, { JobCount, "job-count", 'j', CommandLineParser::Required, String::format("Spawn this many concurrent processes for indexing (default %d).", std::max(2, ThreadPool::idealThreadCount())) }, { HeaderErrorJobCount, "header-error-job-count", 'H', CommandLineParser::Required, "Allow this many concurrent header error jobs (default std::max(1, --job-count / 2))." }, { Test, "test", 't', CommandLineParser::Required, "Run this test." }, { TestTimeout, "test-timeout", 'z', CommandLineParser::Required, "Timeout for test to complete." }, { CleanSlate, "clean-slate", 'C', CommandLineParser::NoValue, "Clear out all data." }, { DisableSigHandler, "disable-sighandler", 'x', CommandLineParser::NoValue, "Disable signal handler to dump stack for crashes." }, { Silent, "silent", 'S', CommandLineParser::NoValue, "No logging to stdout/stderr." }, { ExcludeFilter, "exclude-filter", 'X', CommandLineParser::Required, "Files to exclude from rdm, default \"" DEFAULT_EXCLUDEFILTER "\"." }, { SocketFile, "socket-file", 'n', CommandLineParser::Required, "Use this file for the server socket (default ~/.rdm)." }, { DataDir, "data-dir", 'd', CommandLineParser::Required, "Use this directory to store persistent data (default $XDG_CACHE_HOME/rtags otherwise ~/.cache/rtags)." }, { IgnorePrintfFixits, "ignore-printf-fixits", 'F', CommandLineParser::NoValue, "Disregard any clang fixit that looks like it's trying to fix format for printf and friends." }, { ErrorLimit, "error-limit", 'f', CommandLineParser::Required, "Set error limit to argument (-ferror-limit={arg} (default " STR(DEFAULT_ERROR_LIMIT) ")." }, { BlockArgument, "block-argument", 'G', CommandLineParser::Required, "Block this argument from being passed to clang. E.g. rdm --block-argument -fno-inline" }, { NoSpellChecking, "no-spell-checking", 'l', CommandLineParser::NoValue, "Don't pass -fspell-checking." }, { LargeByValueCopy, "large-by-value-copy", 'r', CommandLineParser::Required, "Use -Wlarge-by-value-copy=[arg] when invoking clang." }, { AllowMultipleSources, "allow-multiple-sources", 'm', CommandLineParser::NoValue, "Don't merge source files added with -c." }, { NoStartupProject, "no-startup-project", 'o', CommandLineParser::NoValue, "Don't restore the last current project on startup." }, { NoNoUnknownWarningsOption, "no-no-unknown-warnings-option", 'Y', CommandLineParser::NoValue, "Don't pass -Wno-unknown-warning-option." }, { IgnoreCompiler, "ignore-compiler", 'b', CommandLineParser::Required, "Ignore this compiler." }, { CompilerWrappers, "compiler-wrappers", 0, CommandLineParser::Required, "Consider these filenames compiler wrappers (split on ;), default " DEFAULT_COMPILER_WRAPPERS "\"." }, { WatchSystemPaths, "watch-system-paths", 'w', CommandLineParser::NoValue, "Watch system paths for changes." }, { RpVisitFileTimeout, "rp-visit-file-timeout", 'Z', CommandLineParser::Required, "Timeout for rp visitfile commands in ms (0 means no timeout) (default " STR(DEFAULT_RP_VISITFILE_TIMEOUT) ")." }, { RpIndexerMessageTimeout, "rp-indexer-message-timeout", 'T', CommandLineParser::Required, "Timeout for rp indexer-message in ms (0 means no timeout) (default " STR(DEFAULT_RP_INDEXER_MESSAGE_TIMEOUT) ")." }, { RpConnectTimeout, "rp-connect-timeout", 'O', CommandLineParser::Required, "Timeout for connection from rp to rdm in ms (0 means no timeout) (default " STR(DEFAULT_RP_CONNECT_TIMEOUT) ")." }, { RpConnectAttempts, "rp-connect-attempts", 0, CommandLineParser::Required, "Number of times rp attempts to connect to rdm before giving up. (default " STR(DEFAULT_RP_CONNECT_ATTEMPTS) ")." }, { RpNiceValue, "rp-nice-value", 'a', CommandLineParser::Required, "Nice value to use for rp (nice(2)) (default is no nicing)." }, { SuspendRpOnCrash, "suspend-rp-on-crash", 'q', CommandLineParser::NoValue, "Suspend rp in SIGSEGV handler (default " DEFAULT_SUSPEND_RP ")." }, { RpLogToSyslog, "rp-log-to-syslog", 0, CommandLineParser::NoValue, "Make rp log to syslog." }, { StartSuspended, "start-suspended", 'Q', CommandLineParser::NoValue, "Start out suspended (no reindexing enabled)." }, { SeparateDebugAndRelease, "separate-debug-and-release", 'E', CommandLineParser::NoValue, "Normally rdm doesn't consider release and debug as different builds. Pass this if you want it to." }, { Separate32BitAnd64Bit, "separate-32-bit-and-64-bit", 0, CommandLineParser::NoValue, "Normally rdm doesn't consider -m32 and -m64 as different builds. Pass this if you want it to." }, { SourceIgnoreIncludePathDifferencesInUsr, "ignore-include-path-differences-in-usr", 0, CommandLineParser::NoValue, "Don't consider sources that only differ in includepaths within /usr (not including /usr/home/) as different builds." }, { MaxCrashCount, "max-crash-count", 'K', CommandLineParser::Required, "Max number of crashes before giving up a sourcefile (default " STR(DEFAULT_MAX_CRASH_COUNT) ")." }, { CompletionCacheSize, "completion-cache-size", 'i', CommandLineParser::Required, "Number of translation units to cache (default " STR(DEFAULT_COMPLETION_CACHE_SIZE) ")." }, { CompletionNoFilter, "completion-no-filter", 0, CommandLineParser::NoValue, "Don't filter private members and destructors from completions." }, { CompletionLogs, "completion-logs", 0, CommandLineParser::NoValue, "Log more info about completions." }, { MaxIncludeCompletionDepth, "max-include-completion-depth", 0, CommandLineParser::Required, "Max recursion depth for header completion (default " STR(DEFAULT_MAX_INCLUDE_COMPLETION_DEPTH) ")." }, { AllowWpedantic, "allow-Wpedantic", 'P', CommandLineParser::NoValue, "Don't strip out -Wpedantic. This can cause problems in certain projects." }, { AllowWErrorAndWFatalErrors, "allow-Werror", 0, CommandLineParser::NoValue, "Don't strip out -Werror and -Wfatal-errors. By default these are stripped out. " }, { EnableCompilerManager, "enable-compiler-manager", 'R', CommandLineParser::NoValue, "Query compilers for their actual include paths instead of letting clang use its own." }, { EnableNDEBUG, "enable-NDEBUG", 'g', CommandLineParser::NoValue, "Don't remove -DNDEBUG from compile lines." }, { Progress, "progress", 'p', CommandLineParser::NoValue, "Report compilation progress in diagnostics output." }, { MaxFileMapCacheSize, "max-file-map-cache-size", 'y', CommandLineParser::Required, "Max files to cache per query (Should not exceed maximum number of open file descriptors allowed per process) (default " STR(DEFAULT_RDM_MAX_FILE_MAP_CACHE_SIZE) ")." }, #ifdef FILEMANAGER_OPT_IN { FileManagerWatch, "filemanager-watch", 'M', CommandLineParser::NoValue, "Use a file system watcher for filemanager." }, #else { NoFileManagerWatch, "no-filemanager-watch", 'M', CommandLineParser::NoValue, "Don't use a file system watcher for filemanager." }, #endif { NoFileManager, "no-filemanager", 0, CommandLineParser::NoValue, "Don't scan project directory for files. (rc -P won't work)." }, { NoFileLock, "no-file-lock", 0, CommandLineParser::NoValue, "Disable file locking. Not entirely safe but might improve performance on certain systems." }, { PchEnabled, "pch-enabled", 0, CommandLineParser::NoValue, "Enable PCH (experimental)." }, { NoFilesystemWatcher, "no-filesystem-watcher", 'B', CommandLineParser::NoValue, "Disable file system watching altogether. Reindexing has to be triggered manually." }, { ArgTransform, "arg-transform", 'V', CommandLineParser::Required, "Use arg to transform arguments. [arg] should be executable with (execv(3))." }, { NoComments, "no-comments", 0, CommandLineParser::NoValue, "Don't parse/store doxygen comments." }, #ifdef RTAGS_HAS_LAUNCHD { Launchd, "launchd", 0, CommandLineParser::NoValue, "Run as a launchd job (use launchd API to retrieve socket opened by launchd on rdm's behalf)." }, #endif { InactivityTimeout, "inactivity-timeout", 0, CommandLineParser::Required, "Time in seconds after which rdm will quit if there's been no activity (N.B., once rdm has quit, something will need to re-run it!)." }, { Daemon, "daemon", 0, CommandLineParser::NoValue, "Run as daemon (detach from terminal)." }, { LogFileLogLevel, "log-file-log-level", 0, CommandLineParser::Required, "Log level for log file (default is error), options are: error, warning, debug or verbose-debug." }, { WatchSourcesOnly, "watch-sources-only", 0, CommandLineParser::NoValue, "Only watch source files (not dependencies)." }, { DebugLocations, "debug-locations", 0, CommandLineParser::NoValue, "Set debug locations." }, { ValidateFileMaps, "validate-file-maps", 0, CommandLineParser::NoValue, "Spend some time validating project data on startup." }, { TcpPort, "tcp-port", 0, CommandLineParser::Required, "Listen on this tcp socket (default none)." }, { RpPath, "rp-path", 0, CommandLineParser::Required, String::format<256>("Path to rp (default %s).", defaultRP().constData()) }, { LogTimestamp, "log-timestamp", 0, CommandLineParser::NoValue, "Add timestamp to logs." }, { LogFlushOption, "log-flush", 0, CommandLineParser::NoValue, "Flush stderr/stdout after each log." }, { SandboxRoot, "sandbox-root", 0, CommandLineParser::Required, "Create index using relative paths by stripping dir (enables copying of tag index db files without need to reindex)." }, { PollTimer, "poll-timer", 0, CommandLineParser::Required, "Poll the database of the current project every <arg> seconds. " }, { NoRealPath, "no-realpath", 0, CommandLineParser::NoValue, "Don't use realpath(3) for files" }, { Noop, "config", 'c', CommandLineParser::Required, "Use this file (instead of ~/.rdmrc)." }, { Noop, "no-rc", 'N', CommandLineParser::NoValue, "Don't load any rc files." } }; std::function<CommandLineParser::ParseStatus(OptionType type, String &&value, size_t &idx, const List<String> &args)> cb; cb = [&](OptionType type, String &&value, size_t &, const List<String> &) -> CommandLineParser::ParseStatus { switch (type) { case None: case Noop: break; case Help: { CommandLineParser::help(stdout, Rct::executablePath().fileName(), opts); return { String(), CommandLineParser::Parse_Ok }; } case Version: { fprintf(stdout, "%s\n", RTags::versionString().constData()); return { String(), CommandLineParser::Parse_Ok }; } case IncludePath: { serverOpts.includePaths.append(Source::Include(Source::Include::Type_Include, Path::resolved(value))); break; } case Isystem: { serverOpts.includePaths.append(Source::Include(Source::Include::Type_System, Path::resolved(value))); break; } case Define: { const size_t eq = value.indexOf('='); Source::Define def; if (eq == String::npos) { def.define = std::move(value); } else { def.define = value.left(eq); def.value = value.mid(eq + 1); } serverOpts.defines.append(def); break; } case DefaultArgument: { serverOpts.defaultArguments.append(std::move(value)); break; } case LogFile: { logFile = std::move(value); logFile.resolve(); logLevel = LogLevel::None; break; } case CrashDumpFile: { strncpy(crashDumpFilePath, value.constData(), sizeof(crashDumpFilePath) - 1); break; } case SetEnv: { putenv(&value[0]); break; } case NoWall: { serverOpts.options &= ~Server::Wall; break; } case Weverything: { serverOpts.options |= Server::Weverything; break; } case Verbose: { if (logLevel != LogLevel::None) ++logLevel; break; } case JobCount: { bool ok; serverOpts.jobCount = String(value).toULong(&ok); if (!ok) { return { String::format<1024>("Can't parse argument to -j %s. -j must be a positive integer.\n", value.constData()), CommandLineParser::Parse_Error }; } break; } case HeaderErrorJobCount: { bool ok; serverOpts.headerErrorJobCount = String(value).toULong(&ok); if (!ok) { return { String::format<1024>("Can't parse argument to -H %s. -H must be a positive integer.", value.constData()), CommandLineParser::Parse_Error }; } break; } case Test: { Path test(value); if (!test.resolve() || !test.isFile()) { return { String::format<1024>("%s doesn't seem to be a file", value.constData()), CommandLineParser::Parse_Error }; } serverOpts.tests += test; break; } case TestTimeout: { serverOpts.testTimeout = atoi(value.constData()); if (serverOpts.testTimeout <= 0) { return { String::format<1024>("Invalid argument to -z %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case PollTimer: { serverOpts.pollTimer = atoi(value.constData()); if (serverOpts.pollTimer < 0) { return { String::format<1024>("Invalid argument to --poll-timer %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case CleanSlate: { serverOpts.options |= Server::ClearProjects; break; } case DisableSigHandler: { sigHandler = false; break; } case Silent: { logLevel = LogLevel::None; break; } case ExcludeFilter: { serverOpts.excludeFilters += String(value).split(';'); break; } case SocketFile: { serverOpts.socketFile = std::move(value); serverOpts.socketFile.resolve(); break; } case DataDir: { serverOpts.dataDir = String::format<128>("%s", Path::resolved(value).constData()); break; } case IgnorePrintfFixits: { serverOpts.options |= Server::IgnorePrintfFixits; break; } case ErrorLimit: { bool ok; serverOpts.errorLimit = String(value).toULong(&ok); if (!ok) { return { String::format<1024>("Can't parse argument to --error-limit %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case BlockArgument: { serverOpts.blockedArguments << value; break; } case NoSpellChecking: { serverOpts.options &= ~Server::SpellChecking; break; } case LargeByValueCopy: { int large = atoi(value.constData()); if (large <= 0) { return { String::format<1024>("Can't parse argument to -r %s", value.constData()), CommandLineParser::Parse_Error }; } serverOpts.defaultArguments.append("-Wlarge-by-value-copy=" + String(value)); // ### not quite working break; } case AllowMultipleSources: { serverOpts.options |= Server::AllowMultipleSources; break; } case NoStartupProject: { serverOpts.options |= Server::NoStartupCurrentProject; break; } case NoNoUnknownWarningsOption: { serverOpts.options |= Server::NoNoUnknownWarningsOption; break; } case IgnoreCompiler: { serverOpts.ignoredCompilers.insert(Path::resolved(value)); break; } case CompilerWrappers: { serverOpts.compilerWrappers = String(value).split(";", String::SkipEmpty).toSet(); break; } case WatchSystemPaths: { serverOpts.options |= Server::WatchSystemPaths; break; } case RpVisitFileTimeout: { serverOpts.rpVisitFileTimeout = atoi(value.constData()); if (serverOpts.rpVisitFileTimeout < 0) { return { String::format<1024>("Invalid argument to -Z %s", value.constData()), CommandLineParser::Parse_Error }; } if (!serverOpts.rpVisitFileTimeout) serverOpts.rpVisitFileTimeout = -1; break; } case RpIndexerMessageTimeout: { serverOpts.rpIndexDataMessageTimeout = atoi(value.constData()); if (serverOpts.rpIndexDataMessageTimeout <= 0) { return { String::format<1024>("Can't parse argument to -T %s.", value.constData()), CommandLineParser::Parse_Error }; } break; } case RpConnectTimeout: { serverOpts.rpConnectTimeout = atoi(value.constData()); if (serverOpts.rpConnectTimeout < 0) { return { String::format<1024>("Invalid argument to -O %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case RpConnectAttempts: { serverOpts.rpConnectAttempts = atoi(value.constData()); if (serverOpts.rpConnectAttempts <= 0) { return { String::format<1024>("Invalid argument to --rp-connect-attempts %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case RpNiceValue: { bool ok; serverOpts.rpNiceValue = value.toLong(&ok); if (!ok) { return { String::format<1024>("Can't parse argument to -a %s.", value.constData()), CommandLineParser::Parse_Error }; } break; } case SuspendRpOnCrash: { serverOpts.options |= Server::SuspendRPOnCrash; break; } case RpLogToSyslog: { serverOpts.options |= Server::RPLogToSyslog; break; } case StartSuspended: { serverOpts.options |= Server::StartSuspended; break; } case SeparateDebugAndRelease: { serverOpts.options |= Server::SeparateDebugAndRelease; break; } case Separate32BitAnd64Bit: { serverOpts.options |= Server::Separate32BitAnd64Bit; break; } case SourceIgnoreIncludePathDifferencesInUsr: { serverOpts.options |= Server::SourceIgnoreIncludePathDifferencesInUsr; break; } case MaxCrashCount: { serverOpts.maxCrashCount = atoi(value.constData()); if (serverOpts.maxCrashCount <= 0) { return { String::format<1024>("Invalid argument to -K %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case CompletionCacheSize: { serverOpts.completionCacheSize = atoi(value.constData()); if (serverOpts.completionCacheSize <= 0) { return { String::format<1024>("Invalid argument to -i %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case CompletionNoFilter: { serverOpts.options |= Server::CompletionsNoFilter; break; } case CompletionLogs: { serverOpts.options |= Server::CompletionLogs; break; } case MaxIncludeCompletionDepth: { serverOpts.maxIncludeCompletionDepth = strtoul(value.constData(), 0, 10); break; } case AllowWpedantic: { serverOpts.options |= Server::AllowPedantic; break; } case AllowWErrorAndWFatalErrors: { serverOpts.options |= Server::AllowWErrorAndWFatalErrors; break; } case EnableCompilerManager: { serverOpts.options |= Server::EnableCompilerManager; break; } case EnableNDEBUG: { serverOpts.options |= Server::EnableNDEBUG; break; } case Progress: { serverOpts.options |= Server::Progress; break; } case MaxFileMapCacheSize: { serverOpts.maxFileMapScopeCacheSize = atoi(value.constData()); if (serverOpts.maxFileMapScopeCacheSize <= 0) { return { String::format<1024>("Invalid argument to -y %s", value.constData()), CommandLineParser::Parse_Error }; } break; } #ifdef FILEMANAGER_OPT_IN case FileManagerWatch: { serverOpts.options &= ~Server::NoFileManagerWatch; break; } #else case NoFileManagerWatch: { serverOpts.options |= Server::NoFileManagerWatch; break; } #endif case NoFileManager: { serverOpts.options |= Server::NoFileManager; break; } case NoFileLock: { serverOpts.options |= Server::NoFileLock; break; } case PchEnabled: { serverOpts.options |= Server::PCHEnabled; break; } case NoFilesystemWatcher: { serverOpts.options |= Server::NoFileSystemWatch; break; } case ArgTransform: { serverOpts.argTransform = Process::findCommand(value); if (!value.isEmpty() && serverOpts.argTransform.isEmpty()) { return { String::format<1024>("Invalid argument to -V. Can't resolve %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case NoComments: { serverOpts.options |= Server::NoComments; break; } #ifdef RTAGS_HAS_LAUNCHD case Launchd: { serverOpts.options |= Server::Launchd; break; } #endif case InactivityTimeout: { inactivityTimeout = atoi(value.constData()); // seconds. if (inactivityTimeout <= 0) { return { String::format<1024>("Invalid argument to --inactivity-timeout %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case Daemon: { daemon = true; logLevel = LogLevel::None; break; } case LogFileLogLevel: { if (!strcasecmp(value.constData(), "verbose-debug")) { logFileLogLevel = LogLevel::VerboseDebug; } else if (!strcasecmp(value.constData(), "debug")) { logFileLogLevel = LogLevel::Debug; } else if (!strcasecmp(value.constData(), "warning")) { logFileLogLevel = LogLevel::Warning; } else if (!strcasecmp(value.constData(), "error")) { logFileLogLevel = LogLevel::Error; } else { return { String::format<1024>("Unknown log level: %s options are error, warning, debug or verbose-debug", value.constData()), CommandLineParser::Parse_Error }; } break; } case WatchSourcesOnly: { serverOpts.options |= Server::WatchSourcesOnly; break; } case DebugLocations: { if (value == "clear" || value == "none") { serverOpts.debugLocations.clear(); } else { serverOpts.debugLocations << value; } break; } case ValidateFileMaps: { serverOpts.options |= Server::ValidateFileMaps; break; } case TcpPort: { serverOpts.tcpPort = atoi(value.constData()); if (!serverOpts.tcpPort) { return { String::format<1024>("Invalid port %s for --tcp-port", value.constData()), CommandLineParser::Parse_Error }; } break; } case RpPath: { serverOpts.rp = std::move(value); if (serverOpts.rp.isFile()) { serverOpts.rp.resolve(); } else { return { String::format<1024>("%s is not a file", value.constData()), CommandLineParser::Parse_Error }; } break; } case LogTimestamp: { logFlags |= LogTimeStamp; break; } case LogFlushOption: { logFlags |= LogFlush; break; } case SandboxRoot: { serverOpts.sandboxRoot = std::move(value); if (!serverOpts.sandboxRoot.endsWith('/')) serverOpts.sandboxRoot += '/'; if (!serverOpts.sandboxRoot.resolve() || !serverOpts.sandboxRoot.isDir()) { return { String::format<1024>("%s is not a valid directory for sandbox-root", serverOpts.sandboxRoot.constData()), CommandLineParser::Parse_Error }; } break; } case NoRealPath: { Path::setRealPathEnabled(false); serverOpts.options |= Server::NoRealPath; break; } } return { String(), CommandLineParser::Parse_Exec }; }; const std::initializer_list<CommandLineParser::Option<CommandLineParser::ConfigOptionType> > configOpts = { { CommandLineParser::Config, "config", 'c', CommandLineParser::Required, "Use this file (instead of ~/.rdmrc)." }, { CommandLineParser::NoRc, "no-rc", 'N', CommandLineParser::NoValue, "Don't load any rc files." } }; const CommandLineParser::ParseStatus status = CommandLineParser::parse<OptionType>(argc, argv, opts, NullFlags, cb, "rdm", configOpts); switch (status.status) { case CommandLineParser::Parse_Error: fprintf(stderr, "%s\n", status.error.constData()); return 1; case CommandLineParser::Parse_Ok: return 0; case CommandLineParser::Parse_Exec: break; } if (daemon) { switch (fork()) { case -1: fprintf(stderr, "Failed to fork (%d) %s\n", errno, strerror(errno)); return 1; case 0: setsid(); switch (fork()) { case -1: fprintf(stderr, "Failed to fork (%d) %s\n", errno, strerror(errno)); return 1; case 0: break; default: return 0; } break; default: return 0; } } if (serverOpts.excludeFilters.isEmpty()) serverOpts.excludeFilters = String(DEFAULT_EXCLUDEFILTER).split(';'); if (serverOpts.compilerWrappers.isEmpty()) serverOpts.compilerWrappers = String(DEFAULT_COMPILER_WRAPPERS).split(';').toSet(); if (!serverOpts.headerErrorJobCount) { serverOpts.headerErrorJobCount = std::max<size_t>(1, serverOpts.jobCount / 2); } else { serverOpts.headerErrorJobCount = std::min(serverOpts.headerErrorJobCount, serverOpts.jobCount); } if (sigHandler) { signal(SIGSEGV, signalHandler); signal(SIGBUS, signalHandler); signal(SIGILL, signalHandler); signal(SIGABRT, signalHandler); } if (!initLogging(argv[0], logFlags, logLevel, logFile, logFileLogLevel)) { fprintf(stderr, "Can't initialize logging with %d %s %s\n", logLevel.toInt(), logFile.constData(), logFlags.toString().constData()); return 1; } #ifdef RTAGS_HAS_LAUNCHD if (serverOpts.options & Server::Launchd) { // Clamp inactivity timeout. launchd starts to worry if the // process runs for less than 10 seconds. static const int MIN_INACTIVITY_TIMEOUT = 15; // includes // fudge factor. if (inactivityTimeout < MIN_INACTIVITY_TIMEOUT) { inactivityTimeout = MIN_INACTIVITY_TIMEOUT; fprintf(stderr, "launchd mode - clamped inactivity timeout to %d to avoid launchd warnings.\n", inactivityTimeout); } } #endif EventLoop::SharedPtr loop(new EventLoop); loop->init(EventLoop::MainEventLoop|EventLoop::EnableSigIntHandler|EventLoop::EnableSigTermHandler); auto server = std::make_shared<Server>(); if (!serverOpts.tests.isEmpty()) { char buf[1024]; Path path; while (true) { strcpy(buf, "/tmp/rtags-test-XXXXXX"); if (!mkdtemp(buf)) { fprintf(stderr, "Failed to mkdtemp (%d)\n", errno); return 1; } path = buf; path.resolve(); break; } serverOpts.dataDir = path; strcpy(buf, "/tmp/rtags-sock-XXXXXX"); const int fd = mkstemp(buf); if (fd == -1) { fprintf(stderr, "Failed to mkstemp (%d)\n", errno); return 1; } close(fd); serverOpts.socketFile = buf; serverOpts.socketFile.resolve(); } serverOpts.dataDir = serverOpts.dataDir.ensureTrailingSlash(); #ifdef HAVE_BACKTRACE if (strlen(crashDumpFilePath)) { if (crashDumpFilePath[0] != '/') { const String f = crashDumpFilePath; snprintf(crashDumpFilePath, sizeof(crashDumpFilePath), "%s%s", serverOpts.dataDir.constData(), f.constData()); } snprintf(crashDumpTempFilePath, sizeof(crashDumpTempFilePath), "%s.tmp", crashDumpFilePath); Path::mkdir(serverOpts.dataDir); crashDumpFile = fopen(crashDumpTempFilePath, "w"); if (!crashDumpFile) { fprintf(stderr, "Couldn't open temp file %s for write (%d)\n", crashDumpTempFilePath, errno); } } #endif if (!server->init(serverOpts)) { cleanupLogging(); return 1; } if (!serverOpts.tests.isEmpty()) { return server->runTests() ? 0 : 1; } loop->setInactivityTimeout(inactivityTimeout * 1000); loop->exec(); const int ret = server->exitCode(); server.reset(); cleanupLogging(); return ret; }