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;
}
Beispiel #2
0
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();
}
Beispiel #4
0
void initFlash(void) {
	initLogging(&logger, "Flash memory");

	addConsoleAction("readconfig", readFromFlash);
	addConsoleAction("writeconfig", writeToFlash);
	addConsoleAction("resetconfig", doResetConfiguration);
}
Beispiel #5
0
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;
}
Beispiel #7
0
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();
}
Beispiel #8
0
int main(int argc, const char **argv) {
	initLogging();
	Ea3dPlatform myPlatform(640, 480);
	myPlatform.initPlatform();
	myPlatform.render();
	exit(EXIT_SUCCESS);
}
Beispiel #9
0
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);
}
Beispiel #10
0
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);
}
Beispiel #11
0
void initConsoleLogic() {
#if EFI_PROD_CODE || EFI_SIMULATOR
	initLogging(&logging, "rfi console");
#endif /* EFI_PROD_CODE */
	resetConsoleActions();
	addConsoleAction("help", helpCommand);
	addConsoleActionI("echo", echo);
}
Beispiel #12
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
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);
}
Beispiel #17
0
int main(){
	initLogging("f**k.txt");
	startLogging();
	printf("hello\n");
	endLogging();

	printTimeLog("main");

	cleanLogging();
	return 0;
}
Beispiel #18
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;
}
Beispiel #19
0
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__);
}
Beispiel #20
0
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");
}
Beispiel #21
0
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 */
}
Beispiel #22
0
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
}
Beispiel #23
0
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);
}
Beispiel #24
0
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;
}
Beispiel #25
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);
}
Beispiel #26
0
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();
}
Beispiel #27
0
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);
}
Beispiel #28
0
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);
}
Beispiel #29
0
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);
}
Beispiel #30
0
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;
}