std.c: Don't use `EXIT_SUCCESS`/`EXIT_FAILURE` as function return values
[sunny256-utils.git] / Lib / std / c / src / std.c
blob272a7ec605f8992b36be82676b1103312130ca5d
1 /*
2 * STDfilenameDTS
3 * File ID: STDuuidDTS
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)
10 * any later version.
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
15 * more details.
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"
24 * Global variables
27 const char *progname;
28 struct Options opt;
31 * msg() - Print a message prefixed with "[progname]: " to stddebug 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 int verbose, const char *format, ...)
39 int retval = 0;
41 assert(format);
42 assert(strlen(format));
44 if (opt.verbose >= verbose) {
45 va_list ap;
47 va_start(ap, format);
48 retval = fprintf(stddebug, "%s: ", progname);
49 retval += vfprintf(stddebug, format, ap);
50 retval += fprintf(stddebug, "\n");
51 va_end(ap);
54 return retval;
58 * myerror() - Print an error message to stderr using this format:
59 * a: b: c
60 * where a is the name of the program (progname), b is the output from the
61 * printf-like string and optional arguments, and c is the error message from
62 * errno. Returns the number of characters written.
65 int myerror(const char *format, ...)
67 va_list ap;
68 int retval = 0;
69 const int orig_errno = errno;
71 assert(format);
72 assert(strlen(format));
74 retval = fprintf(stderr, "%s: ", progname);
75 va_start(ap, format);
76 retval += vfprintf(stderr, format, ap);
77 va_end(ap);
78 if (orig_errno)
79 retval += fprintf(stderr, ": %s", strerror(orig_errno));
80 retval += fprintf(stderr, "\n");
82 return retval;
86 * print_license() - Display the program license. Returns EXIT_SUCCESS.
89 static int print_license(void)
91 puts("(C)opyleft STDyearDTS- Øyvind A. Holm <sunny@sunbase.org>");
92 puts("");
93 puts("This program is free software; you can redistribute it"
94 " and/or modify it \n"
95 "under the terms of the GNU General Public License as"
96 " published by the \n"
97 "Free Software Foundation; either version 2 of the License,"
98 " or (at your \n"
99 "option) any later version.");
100 puts("");
101 puts("This program is distributed in the hope that it will be"
102 " useful, but \n"
103 "WITHOUT ANY WARRANTY; without even the implied warranty of \n"
104 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
105 puts("See the GNU General Public License for more details.");
106 puts("");
107 puts("You should have received a copy of"
108 " the GNU General Public License along \n"
109 "with this program. If not, see <http://www.gnu.org/licenses/>.");
111 return EXIT_SUCCESS;
115 * print_version() - Print version information on stdout. Returns EXIT_SUCCESS.
118 static int print_version(void)
120 if (opt.verbose < 0) {
121 puts(EXEC_VERSION);
122 return EXIT_SUCCESS;
124 printf("%s %s (%s)\n", progname, EXEC_VERSION, EXEC_DATE);
125 #ifdef GCOV
126 printf("has GCOV\n");
127 #endif
128 #ifdef NDEBUG
129 printf("has NDEBUG\n");
130 #endif
131 #ifdef PROF
132 printf("has PROF\n");
133 #endif
134 #ifdef UNUSED
135 printf("has UNUSED\n");
136 #endif
138 return EXIT_SUCCESS;
142 * usage() - Prints a help screen. Returns retval.
145 static int usage(const int retval)
147 if (retval != EXIT_SUCCESS) {
148 fprintf(stderr, "Type \"%s --help\" for help screen."
149 " Returning with value %d.\n",
150 progname, retval);
151 return retval;
153 puts("");
154 if (opt.verbose >= 1) {
155 print_version();
156 puts("");
158 printf("Usage: %s [options]\n", progname);
159 printf("\n");
160 printf("Options:\n");
161 printf("\n");
162 printf(" -h, --help\n"
163 " Show this help.\n");
164 printf(" --license\n"
165 " Print the software license.\n");
166 printf(" -q, --quiet\n"
167 " Be more quiet. Can be repeated to increase silence.\n");
168 printf(" -v, --verbose\n"
169 " Increase level of verbosity. Can be repeated.\n");
170 printf(" --selftest\n"
171 " Run the built-in test suite.\n");
172 printf(" --version\n"
173 " Print version information.\n");
174 printf("\n");
176 return retval;
180 * choose_opt_action() - Decide what to do when option `c` is found. Read
181 * definitions for long options from `opts`.
182 * Returns 0 if ok, or 1 if `c` is unknown or anything fails.
185 static int choose_opt_action(const int c, const struct option *opts)
187 int retval = 0;
189 assert(opts);
191 switch (c) {
192 case 0:
193 if (!strcmp(opts->name, "license"))
194 opt.license = true;
195 else if (!strcmp(opts->name, "selftest"))
196 opt.selftest = true;
197 else if (!strcmp(opts->name, "version"))
198 opt.version = true;
199 break;
200 case 'h':
201 opt.help = true;
202 break;
203 case 'q':
204 opt.verbose--;
205 break;
206 case 'v':
207 opt.verbose++;
208 break;
209 default:
210 msg(4, "%s(): getopt_long() returned character code %d",
211 __func__, c);
212 retval = 1;
213 break;
216 return retval;
220 * parse_options() - Parse command line options.
221 * Returns 0 if succesful, or 1 if an error occurs.
224 static int parse_options(const int argc, char * const argv[])
226 int retval = 0;
228 assert(argv);
230 opt.help = false;
231 opt.license = false;
232 opt.selftest = false;
233 opt.verbose = 0;
234 opt.version = false;
236 while (!retval) {
237 int c;
238 int option_index = 0;
239 static const struct option long_options[] = {
240 {"help", no_argument, NULL, 'h'},
241 {"license", no_argument, NULL, 0},
242 {"quiet", no_argument, NULL, 'q'},
243 {"selftest", no_argument, NULL, 0},
244 {"verbose", no_argument, NULL, 'v'},
245 {"version", no_argument, NULL, 0},
246 {0, 0, 0, 0}
249 c = getopt_long(argc, argv,
250 "h" /* --help */
251 "q" /* --quiet */
252 "v" /* --verbose */
253 , long_options, &option_index);
254 if (c == -1)
255 break;
256 retval = choose_opt_action(c, &long_options[option_index]);
259 return retval;
263 * main()
266 int main(int argc, char *argv[])
268 int retval = EXIT_SUCCESS;
270 progname = argv[0];
271 errno = 0;
273 if (parse_options(argc, argv)) {
274 myerror("Option error");
275 return usage(EXIT_FAILURE);
278 msg(4, "%s(): Using verbose level %d", __func__, opt.verbose);
279 msg(4, "%s(): argc = %d, optind = %d", __func__, argc, optind);
281 if (opt.help)
282 return usage(EXIT_SUCCESS);
283 if (opt.selftest)
284 return selftest();
285 if (opt.version)
286 return print_version();
287 if (opt.license)
288 return print_license();
290 if (optind < argc) {
291 int t;
293 for (t = optind; t < argc; t++) {
294 msg(4, "%s(): Non-option arg %d: %s",
295 __func__, t, argv[t]);
299 msg(4, "Returning from %s() with value %d", __func__, retval);
300 return retval;
303 /* vim: set ts=8 sw=8 sts=8 noet fo+=w tw=79 fenc=UTF-8 : */