5 * (C)opyleft STDyearDTS- Øyvind A. Holm <sunny@sunbase.org>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "STDexecDTS.h"
31 * msg() - Print a message prefixed with "[progname]: " to stderr if the
32 * current verbose level is equal or higher than the first argument. The rest
33 * of the arguments are delivered to vfprintf().
34 * Returns the number of characters written.
37 int msg(const VerboseLevel verbose
, const char *format
, ...)
42 assert(strlen(format
));
44 if (opt
.verbose
>= verbose
) {
48 retval
= fprintf(stderr
, "%s: ", progname
);
49 retval
+= vfprintf(stderr
, format
, ap
);
50 retval
+= fprintf(stderr
, "\n");
58 * std_strerror() - Replacement for `strerror()` that returns a predictable
59 * error message on every platform so the tests work everywhere.
62 static const char *std_strerror(const int errnum
)
66 return "Permission denied";
69 * Should never happen. If this line is executed, an `errno`
70 * value is missing from `std_strerror()`, and tests may fail
73 return strerror(errnum
);
78 * myerror() - Print an error message to stderr using this format:
82 * where `a` is the name of the program (the value of `progname`), `b` is the
83 * output from the printf-like string and optional arguments, and `c` is the
84 * error message from `errno`. If `errno` indicates no error, the ": c" part is
85 * not printed. Returns the number of characters written.
88 int myerror(const char *format
, ...)
92 const int orig_errno
= errno
;
95 assert(strlen(format
));
97 retval
= fprintf(stderr
, "%s: ", progname
);
99 retval
+= vfprintf(stderr
, format
, ap
);
102 retval
+= fprintf(stderr
, ": %s", std_strerror(orig_errno
));
103 retval
+= fprintf(stderr
, "\n");
109 * print_license() - Display the program license. Returns `EXIT_SUCCESS`.
112 static int print_license(void)
114 puts("(C)opyleft STDyearDTS- Øyvind A. Holm <sunny@sunbase.org>");
116 puts("This program is free software; you can redistribute it"
117 " and/or modify it \n"
118 "under the terms of the GNU General Public License as"
119 " published by the \n"
120 "Free Software Foundation; either version 2 of the License,"
122 "option) any later version.");
124 puts("This program is distributed in the hope that it will be"
126 "WITHOUT ANY WARRANTY; without even the implied warranty of \n"
127 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
128 puts("See the GNU General Public License for more details.");
130 puts("You should have received a copy of"
131 " the GNU General Public License along \n"
132 "with this program. If not, see <http://www.gnu.org/licenses/>.");
138 * print_version() - Print version information on stdout. If `-q` is used, only
139 * the version number is printed. Returns `EXIT_SUCCESS`.
142 static int print_version(void)
144 if (opt
.verbose
<= VERBOSE_QUIET
) {
148 printf("%s %s (%s)\n", progname
, EXEC_VERSION
, EXEC_DATE
);
150 printf("has GCOV\n");
153 printf("has NDEBUG\n");
156 printf("has PROF\n");
159 printf("has UNUSED\n");
166 * usage() - Prints a help screen. Returns `retval`.
169 static int usage(const int retval
)
171 if (retval
!= EXIT_SUCCESS
) {
172 myerror("Type \"%s --help\" for help screen."
173 " Returning with value %d.", progname
, retval
);
177 if (opt
.verbose
>= 1) {
181 printf("Usage: %s [options]\n", progname
);
183 printf("Options:\n");
185 printf(" -h, --help\n"
186 " Show this help.\n");
187 printf(" --license\n"
188 " Print the software license.\n");
189 printf(" -q, --quiet\n"
190 " Be more quiet. Can be repeated to increase silence.\n");
191 printf(" -v, --verbose\n"
192 " Increase level of verbosity. Can be repeated.\n");
193 printf(" --selftest\n"
194 " Run the built-in test suite.\n");
195 printf(" --version\n"
196 " Print version information.\n");
203 * choose_opt_action() - Decide what to do when option `c` is found. Read
204 * definitions for long options from `opts`.
205 * Returns 0 if ok, or 1 if `c` is unknown or anything fails.
208 static int choose_opt_action(const int c
, const struct option
*opts
)
216 if (!strcmp(opts
->name
, "license"))
218 else if (!strcmp(opts
->name
, "selftest"))
220 else if (!strcmp(opts
->name
, "version"))
234 "%s(): getopt_long() returned character code %d",
244 * parse_options() - Parse command line options.
245 * Returns 0 if succesful, or 1 if an error occurs.
248 static int parse_options(const int argc
, char * const argv
[])
256 opt
.selftest
= false;
262 int option_index
= 0;
263 static const struct option long_options
[] = {
264 {"help", no_argument
, NULL
, 'h'},
265 {"license", no_argument
, NULL
, 0},
266 {"quiet", no_argument
, NULL
, 'q'},
267 {"selftest", no_argument
, NULL
, 0},
268 {"verbose", no_argument
, NULL
, 'v'},
269 {"version", no_argument
, NULL
, 0},
273 c
= getopt_long(argc
, argv
,
277 , long_options
, &option_index
);
280 retval
= choose_opt_action(c
, &long_options
[option_index
]);
290 int main(int argc
, char *argv
[])
292 int retval
= EXIT_SUCCESS
;
297 if (parse_options(argc
, argv
)) {
298 myerror("Option error");
299 return usage(EXIT_FAILURE
);
302 msg(VERBOSE_DEBUG
, "%s(): Using verbose level %d",
303 __func__
, opt
.verbose
);
304 msg(VERBOSE_DEBUG
, "%s(): argc = %d, optind = %d",
305 __func__
, argc
, optind
);
308 return usage(EXIT_SUCCESS
);
312 return print_version();
314 return print_license();
319 for (t
= optind
; t
< argc
; t
++) {
320 msg(VERBOSE_DEBUG
, "%s(): Non-option arg %d: %s",
321 __func__
, t
, argv
[t
]);
325 msg(VERBOSE_DEBUG
, "Returning from %s() with value %d",
330 /* vim: set ts=8 sw=8 sts=8 noet fo+=w tw=79 fenc=UTF-8 : */