X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/f2f75f25ecc377fb95877449aa12314ee1385a1f..df005d9975b81f8e310761ebed0afbabd40acfe3:/src/cdecl99.c diff --git a/src/cdecl99.c b/src/cdecl99.c index 2a522d4..1da195e 100644 --- a/src/cdecl99.c +++ b/src/cdecl99.c @@ -1,6 +1,6 @@ /* * Command line utility for making sense of C declarations. - * Copyright © 2011-2012, 2020-2021 Nick Bowler + * Copyright © 2011-2012, 2020-2023 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,18 +25,21 @@ #include #include #include +#include #include #include #include -#include #include #include #include "cdecl99.h" #include "cdecl.h" +#include "help.h" +#include "copysym.h" static const char *progname = "cdecl99"; +static bool interactive = true; #include "options.h" static const char sopts[] = SOPT_STRING; @@ -45,24 +48,30 @@ static const struct option lopts[] = { {0} }; -static void print_version(void) +void print_error(const char *fmt, ...) { - const char *copysign = "(C)"; - void *convsign = NULL; + va_list(ap); - if (ENABLE_NLS) { - convsign = str_iconv("\xc2\xa9", "UTF-8", locale_charset()); - if (convsign) - copysign = convsign; - } + if (!interactive) + fprintf(stderr, "%s: ", progname); + fprintf(stderr, "%s", _("error: ")); + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + fprintf(stderr, "\n"); +} + +static void print_version(void) +{ + const char *copysign = copyright_symbol(locale_charset()); puts(PACKAGE_STRING); - printf("Copyright %s 2021 Nick Bowler.\n", copysign); + printf("Copyright %s 2023 Nick Bowler.\n", copysign); puts("License GPLv3+: GNU GPL version 3 or any later version."); puts("This is free software: you are free to change and redistribute it."); puts("There is NO WARRANTY, to the extent permitted by law."); - - free(convsign); } static void print_usage(FILE *f) @@ -73,65 +82,6 @@ static void print_usage(FILE *f) progname); } -static int -print_optstring(const struct option *opt, const struct lopt_help *help) -{ - char optstring[100]; - int w; - - if (!ENABLE_NLS) - goto no_translate; - - if (opt->has_arg) { - w = snprintf(optstring, sizeof optstring, - _(" -%c, --%s=%s"), opt->val, opt->name, - pgettext_expr(opt->name, help->arg)); - } else { - w = snprintf(optstring, sizeof optstring, - _(" -%c, --%s"), opt->val, opt->name); - } - - if (w < 0) - goto no_translate; - - w = mbsnwidth(optstring, w, 0); - printf("%s", optstring); - goto out; - -no_translate: - if (opt->has_arg) { - w = printf(" -%c, --%s=%s", opt->val, opt->name, help->arg); - } else { - w = printf(" -%c, --%s", opt->val, opt->name); - } -out: - if (w < 0 || w > 18) { - putchar('\n'); - return 0; - } - - return w; -} - -/* - * Print a string, with each line indented by i spaces. The first line - * will be indented by w fewer spaces (to account for the cursor being in - * some other column). - */ -void print_block(const char *s, int i, int w) -{ - for (; *s; w = 0) { - const char *nl = strchr(s, '\n'); - int n = (nl ? nl-s : -1); - - printf("%*s%.*s\n", i-w, "", n, s); - if (!nl) - break; - - s = nl+1; - } -} - static void print_help(void) { const struct option *opt; @@ -145,17 +95,11 @@ static void print_help(void) puts(_("Options:")); for (opt = lopts; opt->name; opt++) { struct lopt_help help; - int w; if (!lopt_get_help(opt, &help)) continue; - w = print_optstring(opt, &help); - - if (ENABLE_NLS) - help.desc = pgettext_expr(opt->name, help.desc); - - print_block(help.desc, 20, w); + help_print_option(opt, help.arg, help.desc, 20); } putchar('\n'); @@ -169,14 +113,9 @@ static void print_help(void) printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT); } -static bool is_blank_line(const char *line) +static int is_blank_line(const char *line) { - for (size_t i = 0; line[i]; i++) { - if (!isblank((unsigned char)line[i])) - return false; - } - - return true; + return !line[strspn(line, " \t")]; } static int repl(void) @@ -195,16 +134,13 @@ static int repl(void) return 0; } -static int repl_cmdline(int argc, char **argv) +static int repl_cmdline(unsigned count, char **commands) { - int opt, rc, ret = 0; - - optind = 1; - while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { - if (opt != 'e') - continue; + int ret = 0; + unsigned i; - rc = run_command(optarg, false); + for (i = 0; i < count; i++) { + int rc = run_command(commands[i], false); if (rc < 0) ret = -1; else if (rc > 0) @@ -236,8 +172,7 @@ static int repl_noninteractive(void) free(line); if (ferror(stdin)) { - errno = saved_errno; - perror("read error"); + print_error("%s", strerror(saved_errno)); return -1; } @@ -257,8 +192,9 @@ static void init_i18n(void) int main(int argc, char **argv) { - bool show_intro = true, interactive = true, execute = false; + bool show_intro = true; const char *filename = NULL; + unsigned execute = 0; int i, opt, rc; if (argc > 0) @@ -281,7 +217,7 @@ int main(int argc, char **argv) filename = optarg; break; case 'e': - execute = true; + argv[execute++] = optarg; break; case 'V': print_version(); @@ -296,8 +232,8 @@ int main(int argc, char **argv) } if (optind < argc) { - fprintf(stderr, _("%s: excess command-line arguments:"), - progname); + fprintf(stderr, "%s: ", progname); + fprintf(stderr, _("excess command-line arguments:")); for (i = optind; i < argc; i++) { fprintf(stderr, " %s", argv[i]); } @@ -317,7 +253,8 @@ int main(int argc, char **argv) /* --execute supersedes --filename */ if (filename && !execute) { if (!freopen(filename, "r", stdin)) { - perror(filename); + print_error("failed to open %s: %s", filename, + strerror(errno)); return EXIT_FAILURE; } } @@ -325,7 +262,7 @@ int main(int argc, char **argv) if (interactive) rc = repl(); else if (execute) - rc = repl_cmdline(argc, argv); + rc = repl_cmdline(execute, argv); else rc = repl_noninteractive();