2 * Tool for decoding compact index values for testing.
3 * Copyright © 2012 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 <http://www.gnu.org/licenses/>.
27 #define PROGNAME "decodeindex"
28 static const char *progname = PROGNAME;
29 static const unsigned char sopts[] = "VH";
30 static const struct option lopts[] = {
31 { "version", 0, NULL, 'V' },
32 { "help", 0, NULL, 'H' },
37 * Decode a hexadecimal string into a sequence of bytes. If there are an
38 * odd number of nibbles, treat the first character as the least significant
39 * nibble of the first byte. The result is written to the buffer specified by
40 * buf. At most n bytes are written to the buffer.
42 * Returns the number of bytes that would be written provided that n was large
43 * enough, or (size_t)-1 if the input is not valid.
45 static size_t decode_hex(const char *hex, unsigned char *buf, size_t n)
47 size_t len, count = 0;
50 for (len = 0; hex[len]; len++) {
51 if (!isxdigit(hex[len]))
60 case 0: tmp[0] = *hex++; len--;
61 case 1: tmp[1] = *hex++; len--;
64 buf[count] = strtoul(tmp, NULL, 16);
72 static void print_usage(FILE *f)
74 fprintf(f, "Usage: %s [options] index [index ...]\n", progname);
77 static void print_version(void)
79 printf("%s (%s) %s\n", PROGNAME, PACKAGE_NAME, PACKAGE_VERSION);
80 puts("Copyright (C) 2012 Nick Bowler.");
81 puts("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.");
82 puts("This is free software: you are free to change and redistribute it.");
83 puts("There is NO WARRANTY, to the extent permitted by law.");
86 static void print_bytes(FILE *f, int indent, void *buf, size_t n)
88 fprintf(f, "%*s", indent, "");
89 for (size_t i = 0; i < n; i++)
90 fprintf(f, "%*s%.2hhx", i != 0, "", ((unsigned char *)buf)[i]);
94 static int print_index(const char *hex)
96 unsigned char buf[32];
101 n = decode_hex(hex, buf, sizeof buf);
103 fprintf(stderr, "%s: invalid hex sequence: %s\n",
107 fprintf(stderr, "%s: empty argument\n", progname);
109 } else if (n > sizeof buf) {
110 fprintf(stderr, "%s: hex sequence too long: %s\n",
115 rc = upkg_decode_index(&index, buf, n);
117 fprintf(stderr, "%s: invalid index encoding:\n", progname);
118 print_bytes(stderr, 4, buf, n);
121 fprintf(stderr, "%s: trailing bytes in argument:\n", progname);
122 print_bytes(stderr, 4, buf+rc, n-rc);
128 printf("%ld\n", index);
132 int main(int argc, char **argv)
134 int opt, ret = EXIT_SUCCESS;
139 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
158 for (int i = optind; i < argc; i++) {
159 if (print_index(argv[i]) != 0) {