-
Notifications
You must be signed in to change notification settings - Fork 4
/
ufasta.cc
136 lines (118 loc) · 3.07 KB
/
ufasta.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <signal.h>
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <iostream>
typedef int (main_func_t)(int argc, char *argv[]);
main_func_t one_main;
main_func_t sizes_main;
main_func_t head_main;
main_func_t tail_main;
main_func_t rc_main;
main_func_t n50_main;
main_func_t extract_main;
main_func_t format_main;
main_func_t sort_main;
main_func_t dsort_main;
main_func_t rsort_main;
main_func_t split_main;
#ifdef HAVE_BOOST_REGEX
main_func_t hgrep_main;
main_func_t dgrep_main;
#endif
main_func_t sos;
main_func_t version;
struct cmd_func {
const char *cmd;
main_func_t *func;
};
cmd_func cmd_list[] = {
{"one", &one_main},
{"sizes", &sizes_main},
{"head", &head_main},
{"tail", &tail_main},
{"rc", &rc_main},
{"n50", &n50_main},
{"stats", &n50_main},
{"extract", &extract_main},
{"format", &format_main},
{"hsort", &sort_main},
{"sort", &sort_main},
{"dsort", &dsort_main},
{"rsort", &rsort_main},
#ifdef HAVE_BOOST_REGEX
{"hgrep", &hgrep_main},
{"dgrep", &dgrep_main},
#endif
{"split", &split_main},
/* help in all its form. Must be first non-command */
{"help", &sos},
{"-h", &sos},
{"-help", &sos},
{"--help", &sos},
{"-?", &sos},
{"--version", &version},
{"-V", &version},
{"", 0}
};
void __sos(std::ostream *os)
{
*os << "Usage: ufasta <cmd> [options] arg..." << std::endl <<
"Where <cmd> is one of: ";
bool comma = false;
for(cmd_func *ccmd = cmd_list; ccmd->func != sos; ccmd++) {
*os << (comma ? ", " : "") << ccmd->cmd;
comma = true;
}
*os << "." << std::endl;
*os << "Options:" << std::endl <<
" --version Display version" << std::endl <<
" --help Display this message" << std::endl;
}
int sos(int argc, char *argv[])
{
__sos(&std::cout);
return 0;
}
int version(int argc, char *argv[])
{
#ifdef PACKAGE_STRING
std::cout << PACKAGE_STRING << std::endl;
#else
std::cout << "0.0.0" << std::endl;
#endif
return 0;
}
void sigpipe_handler(int sig) {
_exit(EXIT_SUCCESS);
}
int main(int argc, char *argv[])
{
std::string error;
// Ignore SIGPIPE. It causes ufasta to fail if output is sent to a
// pipe, which is not very useful for us. Simply exit successfully.
{
struct sigaction sig;
memset(&sig, '\0', sizeof(sig));
sig.sa_handler = sigpipe_handler;
if(sigaction(SIGPIPE, &sig, nullptr) == -1)
perror("sigaction");
}
if(argc < 2) {
error = "Too few arguments";
} else {
for(cmd_func *ccmd = cmd_list; ccmd->func != 0; ccmd++) {
if(!strcmp(ccmd->cmd, argv[1]))
return ccmd->func(argc - 1, argv + 1);
}
error = "Unknown command '";
error += argv[1];
error += "'\n";
}
std::cerr << error << std::endl;
__sos(&std::cerr);
return EXIT_FAILURE;
}