summaryrefslogtreecommitdiffstats
path: root/src/ParserCmdline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ParserCmdline.cpp')
-rw-r--r--src/ParserCmdline.cpp771
1 files changed, 0 insertions, 771 deletions
diff --git a/src/ParserCmdline.cpp b/src/ParserCmdline.cpp
deleted file mode 100644
index 8ce6f7a..0000000
--- a/src/ParserCmdline.cpp
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011, 2012 Her Majesty the Queen in Right of Canada (Communications
- Research Center Canada)
-
- Includes modifications
- 2012, Matthias P. Braendli, matthias.braendli@mpb.li
-
- The command-line parser reads the parameters given on the command
- line, and builds an ensemble.
- */
-/*
- This file is part of ODR-DabMux.
-
- ODR-DabMux is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- ODR-DabMux is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "ParserCmdline.h"
-
-#if ENABLE_CMDLINE_OPTIONS
-
-#include <vector>
-#include <stdint.h>
-#include <cstring>
-#include "dabOutput/dabOutput.h"
-#include "dabInput.h"
-#include "utils.h"
-#include "dabInputFile.h"
-#include "dabInputFifo.h"
-#include "dabInputMpegFile.h"
-#include "dabInputMpegFifo.h"
-#include "dabInputDabplusFile.h"
-#include "dabInputDabplusFifo.h"
-#include "dabInputPacketFile.h"
-#include "dabInputEnhancedPacketFile.h"
-#include "dabInputEnhancedFifo.h"
-#include "dabInputUdp.h"
-#include "dabInputBridgeUdp.h"
-#include "dabInputSlip.h"
-#include "dabInputTest.h"
-#include "dabInputPrbs.h"
-#include "dabInputRawFile.h"
-#include "dabInputRawFifo.h"
-#include "dabInputDmbFile.h"
-#include "dabInputDmbUdp.h"
-#include "DabMux.h"
-
-
-#ifdef _WIN32
-# pragma warning ( disable : 4103 )
-# include "Eti.h"
-# pragma warning ( default : 4103 )
-#else
-# include "Eti.h"
-#endif
-
-
-#ifdef _WIN32
-# include <time.h>
-# include <process.h>
-# include <io.h>
-# include <conio.h>
-# include <winsock2.h> // For types...
-typedef u_char uint8_t;
-typedef WORD uint16_t;
-typedef DWORD32 uint32_t;
-
-# ifndef __MINGW32__
-# include "xgetopt.h"
-# endif
-# define read _read
-# define snprintf _snprintf
-# define sleep(a) Sleep((a) * 1000)
-#else
-# include <unistd.h>
-# include <sys/time.h>
-# include <sys/wait.h>
-# include <sys/ioctl.h>
-# include <sys/times.h>
-#endif
-
-using namespace std;
-
-bool parse_cmdline(char **argv,
- int argc,
- vector<dabOutput*> &outputs,
- dabEnsemble* ensemble,
- bool* enableTist,
- unsigned* FICL,
- bool* factumAnalyzer,
- unsigned long* limit
- )
-{
- vector<dabOutput*>::iterator output;
- vector<DabSubchannel*>::iterator subchannel = ensemble->subchannels.end();
- vector<DabComponent*>::iterator component = ensemble->components.end();
- vector<DabService*>::iterator service = ensemble->services.end();
- dabProtection* protection = NULL;
-
- // Yes, this is ugly, but it suppresses warnings
- dabInputOperations operations = {
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
- // Default ensemble parameters:
- ensemble->lto = 0;
- ensemble->lto_auto = true; // Transmit local time by default
- ensemble->mode = 1; // Default TM=1
-
- // Parse command line
- int scids_temp = 0;
-
- const char* error_at = "";
- int success;
-
- char* progName = strrchr(argv[0], '/');
- if (progName == NULL) {
- progName = argv[0];
- } else {
- ++progName;
- }
-
- while (1) {
- int c = getopt(argc, argv,
- "A:B:CD:E:F:L:M:O:P:STVa:b:c:de:f:g:hi:kl:m:n:op:rst:y:z");
- if (c == -1) {
- break;
- }
- switch (c) {
- case 'O':
- char* proto;
-
- proto = strstr(optarg, "://");
- if (proto == NULL) {
- etiLog.log(error,
- "No protocol defined for output\n");
- goto EXIT;
- } else {
- *proto = 0; // terminate optarg
- outputs.push_back(new dabOutput(optarg, proto + 3));
- output = outputs.end() - 1;
- }
-
- subchannel = ensemble->subchannels.end();
- protection = NULL;
- component = ensemble->components.end();
- service = ensemble->services.end();
- break;
- case 'S':
- ensemble->services.push_back(new DabService("?"));
-
- subchannel = ensemble->subchannels.end();
- protection = NULL;
- component = ensemble->components.end();
- service = ensemble->services.end() - 1;
- output = outputs.end();
-
- (*service)->label.setLabel("Service", "Serv");
- (*service)->id = DEFAULT_SERVICE_ID + ensemble->services.size();
- (*service)->pty = 0;
- (*service)->language = 0;
- scids_temp = 0;
-
- break;
- case 'C':
- if (service == ensemble->services.end()) {
- etiLog.log(error, "You must define a service"
- " before using option -%c\n", c);
- printUsage(progName);
- goto EXIT;
- }
-
- ensemble->components.push_back(new DabComponent("?"));
-
- component = ensemble->components.end() - 1;
- subchannel = ensemble->subchannels.end();
- protection = NULL;
- output = outputs.end();
-
- (*component)->label.setLabel("Component", "Comp");
- (*component)->serviceId = (*service)->id;
- (*component)->subchId = (*(ensemble->subchannels.end() - 1))->id;
- (*component)->SCIdS = scids_temp++;
- break;
- case 'A':
- case 'B':
- case 'D':
- case 'E':
- case 'F':
- case 'M':
- case 'P':
- case 'T':
- if (optarg == NULL && c != 'T') {
- etiLog.log(error,
- "Missing parameter for option -%c\n", c);
- printUsage(progName);
- goto EXIT;
- }
-
- ensemble->subchannels.push_back(new DabSubchannel);
-
- subchannel = ensemble->subchannels.end() - 1;
- protection = &(*subchannel)->protection;
- component = ensemble->components.end();
- service = ensemble->services.end();
- output = outputs.end();
-
- if (c != 'T') {
- (*subchannel)->inputName = optarg;
- } else {
- (*subchannel)->inputName = NULL;
- }
- if (0) {
-#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG)
- } else if (c == 'A') {
- (*subchannel)->inputProto = "file";
- (*subchannel)->type = Audio;
- (*subchannel)->bitrate = 0;
- operations = dabInputMpegFileOperations;
-#endif // defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG)
-#if defined(HAVE_FORMAT_DABPLUS)
- } else if (c == 'F') {
- (*subchannel)->type = Audio;
- (*subchannel)->bitrate = 32;
-
- char* proto;
-
- proto = strstr(optarg, "://");
- if (proto == NULL) {
- (*subchannel)->inputProto = "file";
- } else {
- (*subchannel)->inputProto = optarg;
- (*subchannel)->inputName = proto + 3;
- *proto = 0;
- }
-
- if (0) {
-#if defined(HAVE_INPUT_FILE)
- } else if (strcmp((*subchannel)->inputProto, "file") == 0) {
- operations = dabInputDabplusFileOperations;
-#endif // defined(HAVE_INPUT_FILE)
- } else {
- etiLog.log(error,
- "Invalid protocol for DAB+ input (%s)\n",
- (*subchannel)->inputProto);
- printUsage(progName);
- goto EXIT;
- }
-#endif // defined(HAVE_FORMAT_DABPLUS)
- } else if (c == 'B') {
- char* proto;
-
- proto = strstr(optarg, "://");
- if (proto == NULL) {
- (*subchannel)->inputProto = "udp";
- } else {
- (*subchannel)->inputProto = optarg;
- (*subchannel)->inputName = proto + 3;
- *proto = 0;
- }
- if (0) {
-#if defined(HAVE_FORMAT_BRIDGE)
-#if defined(HAVE_INPUT_UDP)
- } else if (strcmp((*subchannel)->inputProto, "udp") == 0) {
- operations = dabInputBridgeUdpOperations;
-#endif // defined(HAVE_INPUT_UDP)
-#endif // defined(HAVE_FORMAT_BRIDGE)
- }
- } else if (c == 'D') {
- char* proto;
-
- proto = strstr(optarg, "://");
- if (proto == NULL) {
- (*subchannel)->inputProto = "udp";
- } else {
- (*subchannel)->inputProto = optarg;
- (*subchannel)->inputName = proto + 3;
- *proto = 0;
- }
- if (0) {
-#if defined(HAVE_INPUT_UDP)
- } else if (strcmp((*subchannel)->inputProto, "udp") == 0) {
- operations = dabInputUdpOperations;
-#endif
-#if defined(HAVE_INPUT_PRBS) && defined(HAVE_FORMAT_RAW)
- } else if (strcmp((*subchannel)->inputProto, "prbs") == 0) {
- operations = dabInputPrbsOperations;
-#endif
-#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW)
- } else if (strcmp((*subchannel)->inputProto, "file") == 0) {
- operations = dabInputRawFileOperations;
-#endif
- } else if (strcmp((*subchannel)->inputProto, "fifo") == 0) {
- operations = dabInputRawFifoOperations;
- } else {
- etiLog.log(error,
- "Invalid protocol for data input (%s)\n",
- (*subchannel)->inputProto);
- printUsage(progName);
- goto EXIT;
- }
-
- (*subchannel)->type = DataDmb;
- (*subchannel)->bitrate = DEFAULT_DATA_BITRATE;
-#if defined(HAVE_INPUT_TEST) && defined(HAVE_FORMAT_RAW)
- } else if (c == 'T') {
- (*subchannel)->inputProto = "test";
- (*subchannel)->type = DataDmb;
- (*subchannel)->bitrate = DEFAULT_DATA_BITRATE;
- operations = dabInputTestOperations;
-#endif // defined(HAVE_INPUT_TEST)) && defined(HAVE_FORMAT_RAW)
-#ifdef HAVE_FORMAT_PACKET
- } else if (c == 'P') {
- (*subchannel)->inputProto = "file";
- (*subchannel)->type = Packet;
- (*subchannel)->bitrate = DEFAULT_PACKET_BITRATE;
-#ifdef HAVE_INPUT_FILE
- operations = dabInputPacketFileOperations;
-#elif defined(HAVE_INPUT_FIFO)
- operations = dabInputFifoOperations;
-#else
-# pragma error("Must defined at least one packet input")
-#endif // defined(HAVE_INPUT_FILE)
-#ifdef HAVE_FORMAT_EPM
- } else if (c == 'E') {
- (*subchannel)->inputProto = "file";
- (*subchannel)->type = Packet;
- (*subchannel)->bitrate = DEFAULT_PACKET_BITRATE;
- operations = dabInputEnhancedPacketFileOperations;
-#endif // defined(HAVE_FORMAT_EPM)
-#endif // defined(HAVE_FORMAT_PACKET)
-#ifdef HAVE_FORMAT_DMB
- } else if (c == 'M') {
- char* proto;
-
- proto = strstr(optarg, "://");
- if (proto == NULL) {
- (*subchannel)->inputProto = "udp";
- } else {
- (*subchannel)->inputProto = optarg;
- (*subchannel)->inputName = proto + 3;
- *proto = 0;
- }
- if (strcmp((*subchannel)->inputProto, "udp") == 0) {
- operations = dabInputDmbUdpOperations;
- } else if (strcmp((*subchannel)->inputProto, "file") == 0) {
- operations = dabInputDmbFileOperations;
- } else {
- etiLog.log(error,
- "Invalid protocol for DMB input (%s)\n",
- (*subchannel)->inputProto);
- printUsage(progName);
- goto EXIT;
- }
-
- (*subchannel)->type = DataDmb;
- (*subchannel)->bitrate = DEFAULT_DATA_BITRATE;
-#endif
- } else {
- etiLog.log(error,
- "Service '%c' not yet coded!\n", c);
- goto EXIT;
- }
- (*subchannel)->input = new DabInputCompatible(operations);
-
- for (int i = 0; i < 64; ++i) { // Find first free subchannel
- subchannel = getSubchannel(ensemble->subchannels, i);
- if (subchannel == ensemble->subchannels.end()) {
- subchannel = ensemble->subchannels.end() - 1;
- (*subchannel)->id = i;
- break;
- }
- }
- (*subchannel)->startAddress = 0;
-
- if (c == 'A') {
- protection->form = UEP;
- protection->level = 2;
- protection->uep.tableIndex = 0;
- } else {
- protection->form = EEP;
- protection->level = 2;
- protection->eep.profile = EEP_A;
- }
- break;
- case 'L':
- if (optarg == NULL) {
- etiLog.log(error,
- "Missing parameter for option -L\n");
- printUsage(progName);
- goto EXIT;
- }
- if (service == ensemble->services.end()) {
- ensemble->label.setLabel(optarg);
- } else if (component != ensemble->components.end()) {
- (*component)->label.setLabel(optarg);
- } else { // Service
- (*service)->label.setLabel(optarg);
- }
- break;
- case 'V':
- goto EXIT;
- case 'l':
- if (optarg == NULL) {
- etiLog.log(error,
- "Missing parameter for option -l\n");
- printUsage(progName);
- goto EXIT;
- }
-
- if (service == ensemble->services.end()) {
- success = ensemble->label.setLabel(ensemble->label.text(), optarg);
- error_at = "Ensemble";
- }
- else if (component != ensemble->components.end()) {
- success = (*component)->label.setLabel(ensemble->label.text(), optarg);
- error_at = "Component";
- }
- else {
- success = (*service)->label.setLabel(ensemble->label.text(), optarg);
- error_at = "Service";
- }
-
- switch (success)
- {
- case 0:
- break;
- case -1:
- etiLog.level(error) << error_at << " short label " <<
- optarg << " is not subset of label '" <<
- ensemble->label.text() << "'";
- goto EXIT;
- case -2:
- etiLog.level(error) << error_at << " short label " <<
- optarg << " is too long (max 8 characters)";
- goto EXIT;
- case -3:
- etiLog.level(error) << error_at << " label " <<
- ensemble->label.text() << " is too long (max 16 characters)";
- goto EXIT;
- default:
- etiLog.level(error) << error_at << " short label definition: program error !";
- abort();
- }
- break;
- case 'i':
- if (optarg == NULL) {
- etiLog.log(error,
- "Missing parameter for option -i\n");
- printUsage(progName);
- goto EXIT;
- }
- if (component != ensemble->components.end()) {
- (*component)->subchId = strtoul(optarg, NULL, 0);
- } else if (subchannel != ensemble->subchannels.end()) {
- (*subchannel)->id = strtoul(optarg, NULL, 0);
- } else if (service != ensemble->services.end()) {
- (*service)->id = strtoul(optarg, NULL, 0);
- if ((*service)->id == 0) {
- etiLog.log(error,
- "Service id 0 is invalid\n");
- goto EXIT;
- }
- } else {
- ensemble->id = strtoul(optarg, NULL, 0);
- }
- break;
- case 'b':
- if (optarg == NULL) {
- etiLog.log(error,
- "Missing parameter for option -b\n");
- printUsage(progName);
- goto EXIT;
- }
- if (subchannel == ensemble->subchannels.end()) {
- etiLog.log(error,
- "You must define a subchannel first!\n");
- printUsage(progName);
- goto EXIT;
- }
- (*subchannel)->bitrate = strtoul(optarg, NULL, 0);
- if (((*subchannel)->bitrate & 0x7) != 0) {
- (*subchannel)->bitrate += 8;
- (*subchannel)->bitrate &= ~0x7;
- etiLog.log(warn,
- "bitrate must be multiple of 8 -> ceiling to %i\n",
- (*subchannel)->bitrate);
- }
- break;
- case 'c':
- if (optarg == NULL) {
- etiLog.log(error,
- "Missing parameter for option -c\n");
- printUsage(progName);
- goto EXIT;
- }
- ensemble->ecc = strtoul(optarg, NULL, 0);
- break;
-#if defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE)
- case 'k':
- if (subchannel == ensemble->subchannels.end()) {
- etiLog.log(error,
- "You must define a subchannel first!\n");
- printUsage(progName);
- goto EXIT;
- }
- switch ((*subchannel)->type) {
-#ifdef HAVE_FORMAT_PACKET
- case Packet:
- if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputPacketFileOperations) {
- operations = dabInputFifoOperations;
-#ifdef HAVE_FORMAT_EPM
- } else if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputEnhancedPacketFileOperations) {
- operations = dabInputEnhancedFifoOperations;
-#endif // defined(HAVE_FORMAT_EPM)
- } else {
- etiLog.log(error,
- "Error, wrong packet subchannel operations!\n");
- goto EXIT;
- }
- delete (*subchannel)->input;
- (*subchannel)->input = new DabInputCompatible(operations);
- (*subchannel)->inputProto = "fifo";
- break;
-#endif // defined(HAVE_FORMAT_PACKET)
-#ifdef HAVE_FORMAT_MPEG
- case Audio:
- if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputMpegFileOperations) {
- operations = dabInputMpegFifoOperations;
- } else if (((DabInputCompatible*)(*subchannel)->input)->getOpts() ==
- dabInputDabplusFileOperations) {
- operations = dabInputDabplusFifoOperations;
- } else {
- etiLog.log(error,
- "Error, wrong audio subchannel operations!\n");
- goto EXIT;
- }
- delete (*subchannel)->input;
- (*subchannel)->input = new DabInputCompatible(operations);
- (*subchannel)->inputProto = "fifo";
- break;
-#endif // defined(HAVE_FORMAT_MPEG)
- default:
- etiLog.log(error,
- "sorry, non-blocking input file is "
- "only valid with audio or packet services\n");
- goto EXIT;
- }
- break;
-#endif // defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE)
- case 'p':
- int level;
- if (optarg == NULL) {
- etiLog.log(error,
- "Missing parameter for option -p\n");
- printUsage(progName);
- goto EXIT;
- }
- if (subchannel == ensemble->subchannels.end()) {
- etiLog.log(error,
- "You must define a subchannel first!\n");
- printUsage(progName);
- goto EXIT;
- }
- level = strtoul(optarg, NULL, 0) - 1;
- if (protection->form == UEP) {
- if ((level < 0) || (level > 4)) {
- etiLog.log(error,
- "UEP protection level must be between "
- "1 to 5 inclusively (current = %i)\n", level);
- goto EXIT;
- }
- }
- else if (protection->form == EEP) {
- if ((level < 0) || (level > 3)) {
- etiLog.log(error,
- "EEP protection level must be between "
- "1 to 4 inclusively (current = %i)\n", level);
- goto EXIT;
- }
- }
- protection->level = level;
- break;
- case 'm':
- if (optarg) {
- ensemble->mode = strtoul(optarg, NULL, 0);
- if ((ensemble->mode < 1) || (ensemble->mode > 4)) {
- etiLog.log(error,
- "Mode must be between 1-4\n");
- goto EXIT;
- }
- if (ensemble->mode == 4)
- ensemble->mode = 0;
- if (ensemble->mode == 3) {
- *FICL = 32;
- } else {
- *FICL = 24;
- }
- } else {
- etiLog.log(error,
- "Missing parameter for option -m\n");
- printUsage(progName);
- goto EXIT;
- }
- break;
- case 'n':
- if (optarg) {
- *limit = strtoul(optarg, NULL, 0);
- } else {
- etiLog.log(error,
- "Missing parameter for option -n\n");
- printUsage(progName);
- goto EXIT;
- }
- break;
- case 'o':
- etiLog.register_backend(new LogToSyslog()); // TODO don't leak the LogToSyslog backend
- break;
- case 't':
- if (optarg == NULL) {
- etiLog.log(error,
- "Missing parameter for option -t\n");
- printUsage(progName);
- goto EXIT;
- }
- if (component == ensemble->components.end()) {
- etiLog.log(error,
- "You must define a component before setting "
- "service type!\n");
- printUsage(progName);
- goto EXIT;
- }
- (*component)->type = strtoul(optarg, NULL, 0);
- break;
- case 'a':
- if (component == ensemble->components.end()) {
- etiLog.log(error,
- "You must define a component before setting "
- "packet address!\n");
- printUsage(progName);
- goto EXIT;
- }
- if (!(*component)->isPacketComponent(ensemble->subchannels)) {
- etiLog.log(error, "address\n");
- printUsage(progName);
- goto EXIT;
- }
- (*component)->packet.address = strtoul(optarg, NULL, 0);
- break;
- case 'd':
- if (component == ensemble->components.end()) {
- etiLog.log(error,
- "You must define a component before setting "
- "datagroup!\n");
- printUsage(progName);
- goto EXIT;
- }
- if (!(*component)->isPacketComponent(ensemble->subchannels)) {
- etiLog.log(error, "datagroup\n");
- printUsage(progName);
- goto EXIT;
- }
- (*component)->packet.datagroup = true;
- break;
- case 'f':
- if (component == ensemble->components.end()) {
- etiLog.log(error,
- "You must define a component first!\n");
- printUsage(progName);
- goto EXIT;
- }
- if (!(*component)->isPacketComponent(ensemble->subchannels)) {
- etiLog.log(error, "application type\n");
- printUsage(progName);
- goto EXIT;
- }
- (*component)->packet.appType = strtoul(optarg, NULL, 0);
- break;
- case 'g':
- if (service == ensemble->services.end()) {
- etiLog.log(error, "You must define a service"
- " before using option -%c\n", c);
- printUsage(progName);
- goto EXIT;
- }
- (*service)->language = strtoul(optarg, NULL, 0);
- break;
- case 's':
- {
- /*
- struct timeval tv;
- gettimeofday(&tv, NULL);
- unsigned _8ms = (tv.tv_usec / 1000) / 8;
- unsigned _1ms = (tv.tv_usec - (_8ms * 8000)) / 1000;
- unsigned _4us = 20;
- unsigned _488ns = 0;
- unsigned _61ns = 0;
- timestamp = (((((((_8ms << 3) | _1ms) << 8) | _4us) << 3) | _488ns) << 8) | _61ns;
- */
- *enableTist = true;
- }
- break;
- case 'y':
- if (service == ensemble->services.end()) {
- etiLog.log(error, "You must define a service"
- " before using option -%c\n", c);
- printUsage(progName);
- goto EXIT;
- }
- (*service)->pty = strtoul(optarg, NULL, 0);
- break;
- case 'z':
- *factumAnalyzer = true;
- break;
- case 'r':
- etiLog.log(info,
- "Enabling throttled output using simul, one frame every 24ms\n");
- outputs.push_back(new dabOutput("simul", "simul"));
- output = outputs.end() - 1;
-
- subchannel = ensemble->subchannels.end();
- protection = NULL;
- component = ensemble->components.end();
- service = ensemble->services.end();
- break;
- case '?':
- case 'h':
- printUsage(progName, stdout);
- goto EXIT;
- default:
- etiLog.log(error, "Option '%c' not coded yet\n", c);
- goto EXIT;
- }
- }
- if (optind < argc) {
- etiLog.log(error, "Too much parameters:");
- while (optind < argc) {
- etiLog.log(error, " %s", argv[optind++]);
- }
- etiLog.log(error, "\n");
- printUsage(progName);
- goto EXIT;
- }
-
- return true;
-EXIT:
- return false;
-}
-
-#endif // ENABLE_CMDLINE_OPTIONS
-