2 * 2ooM: The Master of Orion II Reverse Engineering Project
3 * Helper functions for liblbx command-line applications.
4 * Copyright © 2013 Nick Bowler
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 static const char *progname, *argv0;
34 void tool_init(const char *name, int argc, char **argv)
37 argv0 = argv[0] ? argv[0] : progname;
40 void tool_version(void)
42 assert(argv0 != NULL);
43 printf("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
44 printf("Copyright (C) 2013 Nick Bowler.\n");
45 puts("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.");
46 puts("This is free software: you are free to change and redistribute it.");
47 puts("There is NO WARRANTY, to the extent permitted by law.");
50 const char *tool_invocation(void)
52 assert(argv0 != NULL);
56 /* Saturating addition. */
57 static size_t add_size(size_t a, size_t b)
59 if (a >= SIZE_MAX - b)
64 static int vfmsg_internal(FILE *f, int err, const char *fmt, va_list ap)
66 size_t invokelen, fmtlen, errlen, totlen;
67 char *newfmt, *errmsg;
70 invokelen = strlen(tool_invocation());
71 fmtlen = fmt ? strlen(fmt) : 0;
72 errlen = err > 0 ? strlen(errmsg = strerror(err)) : 0;
74 totlen = add_size(invokelen, sizeof "\n");
76 totlen = add_size(totlen, strlen(": "));
77 totlen = add_size(totlen, fmtlen);
80 totlen = add_size(totlen, strlen(": "));
81 totlen = add_size(totlen, errlen);
84 if (totlen == SIZE_MAX || totlen > INT_MAX)
87 newfmt = malloc(totlen);
92 rc = sprintf(newfmt, "%s: %s: %s\n", argv0, fmt, errmsg);
94 rc = sprintf(newfmt, "%s: %s\n", argv0, errmsg);
96 rc = sprintf(newfmt, "%s: %s\n", argv0, fmt);
98 rc = sprintf(newfmt, "%s\n", argv0);
104 rc = vfprintf(f, newfmt, ap);
110 int tool_vmsg(const char *fmt, va_list ap)
112 return vfmsg_internal(stdout, -1, fmt, ap);
115 int tool_verr(int err, const char *fmt, va_list ap)
117 return vfmsg_internal(stderr, err == 0 ? errno : err, fmt, ap);
120 int tool_msg(const char *fmt, ...)
126 rc = tool_vmsg(fmt, ap);
132 int tool_err(int err, const char *fmt, ...)
138 rc = tool_verr(err, fmt, ap);