Skip to content

Commit

Permalink
added guard for unrecognized opts
Browse files Browse the repository at this point in the history
  • Loading branch information
gf777 committed Oct 9, 2024
1 parent fea9524 commit 1537817
Showing 1 changed file with 39 additions and 120 deletions.
159 changes: 39 additions & 120 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,9 @@ int main(int argc, char **argv) {
bool isPipe = false; // to check if input is from pipe

if (argc == 1) { // gfastats with no arguments

printf("gfastats input.[fasta|fastq|gfa][.gz] [expected genome size] [header[:start-end]]\n-h for additional help.\n");
exit(0);

exit(EXIT_SUCCESS);
}

static struct option long_options[] = { // struct mapping long options
{"input-sequence", required_argument, 0, 'f'},

Expand Down Expand Up @@ -81,28 +78,26 @@ int main(int argc, char **argv) {
while (1) { // loop through argv

int option_index = 0;

int curind = optind;
c = getopt_long(argc, argv, "-:a:b:e:f:i:j:k:o:s:tvh",
long_options, &option_index);

if (optind < argc && !isPipe) { // if pipe wasn't assigned already

if (optind < argc && !isPipe) // if pipe wasn't assigned already
isPipe = isDash(argv[optind]) ? true : false; // check if the argument to the option is a '-' and set it as pipe input

}

if (optarg != nullptr && !isPipe) { // case where pipe input is given as positional argument (input sequence file)

if (optarg != nullptr && !isPipe) // case where pipe input is given as positional argument (input sequence file)
isPipe = isDash(optarg) ? true : false;

}

if (c == -1) { // exit the loop if run out of options
if (c == -1) // exit the loop if run out of options
break;

}

switch (c) {
case '?':
if (optopt)
printf("Unrecognized short option (%c).\n", optopt);
else
printf("Unrecognized long option (%s).\n", argv[curind]);
exit(EXIT_FAILURE);
case ':': // handle options without arguments
switch (optopt) { // the command line option last matched
case 'b':
Expand All @@ -128,17 +123,12 @@ int main(int argc, char **argv) {
default: // handle positional arguments
if (pos_op == 1) { // only one positional argument given

if (isPipe && userInput.pipeType == 'n') { // check whether input is from pipe and that pipe input was not already set

if (isPipe && userInput.pipeType == 'n') // check whether input is from pipe and that pipe input was not already set
userInput.pipeType = 'f'; // pipe input is a sequence

}else{ // input is a regular file

else{ // input is a regular file
ifFileExists(optarg);
userInput.inSequence = optarg;

}

pos_op++;

}else if (pos_op == 2 || pos_op == 3) { // if >1 positional argument, check what additional positional arguments are present
Expand All @@ -154,164 +144,115 @@ int main(int argc, char **argv) {
pos_op++;

}

}else{
printf("Error: too many positional arguments (%s).\n",optarg);
exit(EXIT_FAILURE);
}
else{printf("Error: too many positional arguments (%s).\n",optarg);exit(1);}

break;

case 0: // case for long options without short options

if (strcmp(long_options[option_index].name,"discover-terminal-overlaps") == 0) {

if (optarg == NULL && optind < argc
&& argv[optind][0] != '-')
{
if (optarg == NULL && optind < argc && argv[optind][0] != '-')
optarg = argv[optind++];
}

if (optarg != NULL) {

if (optarg != NULL)
userInput.terminalOvlLen = atoi(optarg);

}else {

else
userInput.terminalOvlLen = 1000;

}

}

if (strcmp(long_options[option_index].name,"line-length") == 0)
userInput.splitLength = atoi(optarg);

if (strcmp(long_options[option_index].name,"sort") == 0) {

std::vector<std::string> options {"none", "ascending", "descending", "largest", "smallest"};

if (std::find(options.begin(), options.end(), optarg) != options.end() || ifFileExists(optarg)){

if (std::find(options.begin(), options.end(), optarg) != options.end() || ifFileExists(optarg))
userInput.sortType = optarg;

}else{printf("Error: unrecognized sorting option (%s).\n", optarg); exit(1);}

else{
printf("Error: unrecognized sorting option (%s).\n", optarg);
exit(1);
}
}

if(strcmp(long_options[option_index].name,"homopolymer-compress") == 0) {
userInput.hc_cutoff = atoi(optarg);
userInput.stats_flag = 1;
}

if (strcmp(long_options[option_index].name,"locale") == 0) {

setlocale(LC_ALL, optarg);
std::cout.imbue(std::locale(optarg));
std::locale::global(std::locale(optarg));
userInput.stats_flag = 1;

}

break;

case 'a': // agp to paths

if (isPipe && userInput.pipeType == 'n') { // check whether input is from pipe and that pipe input was not already set

if (isPipe && userInput.pipeType == 'n') // check whether input is from pipe and that pipe input was not already set
userInput.pipeType = 'a'; // pipe input is agp

}else{ // input is a regular file

else{ // input is a regular file
ifFileExists(optarg);
userInput.inAgp = optarg;

}

userInput.stats_flag = 1;
break;

case 'b': // output bed type (agp, contig, gaps)
bedOutType = *optarg;
userInput.outCoord_flag = 1;
break;

case 'e': // bed exclude

if (isPipe && userInput.pipeType == 'n') { // check whether input is from pipe and that pipe input was not already set

if (isPipe && userInput.pipeType == 'n') // check whether input is from pipe and that pipe input was not already set
userInput.pipeType = 'e'; // pipe input is an exclude bed

}else{ // input is a regular file

else{ // input is a regular file
ifFileExists(optarg);
userInput.inBedExclude = optarg;

}

userInput.stats_flag = 1;
break;

case 'f': // input sequence

if (isPipe && userInput.pipeType == 'n') { // check whether input is from pipe and that pipe input was not already set

if (isPipe && userInput.pipeType == 'n') // check whether input is from pipe and that pipe input was not already set
userInput.pipeType = 'f'; // pipe input is a sequence

}else{ // input is a regular file
else{ // input is a regular file

ifFileExists(optarg);
userInput.inSequence = optarg;
userInput.stats_flag = 1;

}

break;

case 'i': // bed include

if (isPipe && userInput.pipeType == 'n') { // check whether input is from pipe and that pipe input was not already set

if (isPipe && userInput.pipeType == 'n') // check whether input is from pipe and that pipe input was not already set
userInput.pipeType = 'i'; // pipe input is an include bed

}else{ // input is a regular file

else{ // input is a regular file
ifFileExists(optarg);
userInput.inBedInclude = optarg;

}

userInput.stats_flag = 1;
break;

case 'j': // max threads
maxThreads = atoi(optarg);
userInput.stats_flag = 1;
break;

case 'k': // the swiss army knife

if (isPipe && userInput.pipeType == 'n') { // check whether input is from pipe and that pipe input was not already set

if (isPipe && userInput.pipeType == 'n') // check whether input is from pipe and that pipe input was not already set
userInput.pipeType = 'k'; // pipe input is a set of instructions for the swiss army knife

}else{ // input is a regular file

else{ // input is a regular file
ifFileExists(optarg);
userInput.inSak = optarg;

}

userInput.stats_flag = 1;
break;

case 'o': // handle output (file or stdout)

userInput.outFile_flag = 1;

if (isPipe && userInput.pipeType == 'n') { // check whether input is from pipe and that pipe input was not already set

if (isPipe && userInput.pipeType == 'n') // check whether input is from pipe and that pipe input was not already set
userInput.pipeType = 'r'; // pipe input is a sequence

}else{ // outputs are regular files
else{ // outputs are regular files

optind--;

Expand All @@ -329,31 +270,22 @@ int main(int argc, char **argv) {
file.erase(0, 2); // handle file name attached to option

userInput.outFiles.push_back(file);

++i;

}

userInput.stats_flag = 1;

}

break;

case 's': // output size of features
bedOutType = *optarg;
userInput.outSize_flag = 1;
break;

case 't': // tabular output
tabular_flag = 1;
break;

case 'v': // software version
printf("gfastats v%s\n", version.c_str());
printf("Giulio Formenti [email protected]\n");
exit(0);

exit(EXIT_SUCCESS);
case 'h': // help
printf("gfastats input.[fasta|fastq|gfa][.gz] [expected genome size] [header[:start-end]]\n");
printf("genome size: estimated genome size for NG* statistics (optional).\n");
Expand Down Expand Up @@ -386,31 +318,26 @@ int main(int argc, char **argv) {
printf("\t--verbose verbose output.\n");
printf("\t--locale set a different locale, for instance to use , for thousand separators use en_US.UTF-8.\n");
printf("\nAll input files can be piped from stdin using '-'.\n");
exit(0);
exit(EXIT_SUCCESS);
}

if (argc == 2 || // handle various cases in which the output should include summary stats
(argc == 3 && pos_op == 2) ||
(argc == 4 && pos_op == 3) ||
userInput.nstarReport_flag ||
userInput.discoverPaths_flag) {

userInput.stats_flag = 1; // default mode 'stats'

}

}

lg.verbose("Input variables assigned");

if (userInput.cmd_flag) { // print command line
for (unsigned short int arg_counter = 0; arg_counter < argc; arg_counter++) {
printf("%s ", argv[arg_counter]);
}
printf("\n");

}

Input in;

in.load(userInput); // load user input
Expand All @@ -429,33 +356,25 @@ int main(int argc, char **argv) {
userInput.stats_flag = 0;
report.segmentReport(inSequences, userInput.outSequence_flag);
}

if (userInput.pathReport_flag) { // report results for each sequence
userInput.stats_flag = 0;
report.pathReport(inSequences);
}

if (userInput.outFile_flag) { // output sequences to file or stdout
userInput.stats_flag = 0;
for (std::string file : userInput.outFiles)
report.writeToStream(inSequences, file, userInput);
}

if (userInput.outCoord_flag || userInput.outSize_flag) { // output coordinates
userInput.stats_flag = 0;
report.outCoord(inSequences, bedOutType, userInput.outSize_flag);
}

if (userInput.stats_flag) { // output summary statistics
report.reportStats(inSequences, gSize, userInput.outBubbles_flag);
}

if (userInput.nstarReport_flag) { // output full N/L* statistics
report.nstarReport(inSequences, gSize);
}

lg.verbose("Generated output");

exit(EXIT_SUCCESS);

}

0 comments on commit 1537817

Please sign in to comment.