Stop using gnulib's flexmember module.
[upkg.git] / test / decodeindex.c
blob1d4643beeba5357b8c6acabc6caae2d382d58744
1 /*
2 * Tool for decoding compact index values for testing.
3 * Copyright © 2012, 2022 Nick Bowler
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 #include <config.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <getopt.h>
24 #include <upkg.h>
25 #include "common.h"
27 #define PROGNAME "decodeindex"
28 static const char *progname = PROGNAME;
29 static const char sopts[] = "VH";
30 static const struct option lopts[] = {
31 { "version", 0, NULL, 'V' },
32 { "help", 0, NULL, 'H' },
33 { 0 }
36 static void print_usage(FILE *f)
38 fprintf(f, "Usage: %s [options] index [index ...]\n", progname);
41 static void print_help(void)
43 print_usage(stdout);
44 test_print_options(lopts);
47 static void print_bytes(FILE *f, int indent, void *buf, size_t n)
49 fprintf(f, "%*s", indent, "");
51 if (n == 0) {
52 fprintf(f, "(empty)\n");
53 return;
56 for (size_t i = 0; i < n; i++)
57 fprintf(f, "%*s%.2hhx", i != 0, "", ((unsigned char *)buf)[i]);
58 putc('\n', f);
61 static int print_index(const char *hex)
63 unsigned char buf[32];
64 long index = 0;
65 size_t n, rc;
66 int ret = -1;
68 n = test_decode_hex(hex, buf, sizeof buf);
69 if (n == -1) {
70 fprintf(stderr, "%s: invalid hex sequence: %s\n",
71 progname, hex);
72 goto out;
73 } else if (n > sizeof buf) {
74 fprintf(stderr, "%s: hex sequence too long: %s\n",
75 progname, hex);
76 goto out;
79 rc = upkg_decode_index(&index, buf, n);
80 if (rc == 0) {
81 fprintf(stderr, "%s: invalid index encoding:\n", progname);
82 print_bytes(stderr, 4, buf, n);
83 goto out;
84 } else if (rc < n) {
85 fprintf(stderr, "%s: trailing bytes in argument:\n", progname);
86 print_bytes(stderr, 4, buf+rc, n-rc);
87 /* Non-fatal */
90 ret = 0;
91 out:
92 printf("%ld\n", index);
93 return ret;
96 int main(int argc, char **argv)
98 int opt, ret = EXIT_SUCCESS;
100 if (argc > 0)
101 progname = argv[0];
103 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
104 switch (opt) {
105 case 'V':
106 test_print_version(PROGNAME);
107 return EXIT_SUCCESS;
108 case 'H':
109 print_help();
110 return EXIT_SUCCESS;
111 default:
112 print_usage(stderr);
113 return EXIT_FAILURE;
117 if (!argv[optind]) {
118 print_usage(stderr);
119 return EXIT_FAILURE;
122 for (int i = optind; i < argc; i++) {
123 if (print_index(argv[i]) != 0) {
124 ret = EXIT_FAILURE;
128 return ret;