]> git.draconx.ca Git - upkg.git/blob - test/decodeindex.c
Improve GOB rebuild rules for VPATH builds.
[upkg.git] / test / decodeindex.c
1 /*
2  * Tool for decoding compact index values for testing.
3  * Copyright © 2012 Nick Bowler
4  *
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.
9  *
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.
14  *
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/>.
17  */
18
19 #include <config.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <getopt.h>
23
24 #include <upkg.h>
25 #include "common.h"
26
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 }
34 };
35
36 static void print_usage(FILE *f)
37 {
38         fprintf(f, "Usage: %s [options] index [index ...]\n", progname);
39 }
40
41 static void print_version(void)
42 {
43         printf("%s (%s) %s\n", PROGNAME, PACKAGE_NAME, PACKAGE_VERSION);
44         puts("Copyright (C) 2012 Nick Bowler.");
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.");
48 }
49
50 static void print_bytes(FILE *f, int indent, void *buf, size_t n)
51 {
52         fprintf(f, "%*s", indent, "");
53
54         if (n == 0) {
55                 printf("(empty)\n");
56                 return;
57         }
58
59         for (size_t i = 0; i < n; i++)
60                 fprintf(f, "%*s%.2hhx", i != 0, "", ((unsigned char *)buf)[i]);
61         putc('\n', f);
62 }
63
64 static int print_index(const char *hex)
65 {
66         unsigned char buf[32];
67         long index = 0;
68         size_t n, rc;
69         int ret = -1;
70
71         n = test_decode_hex(hex, buf, sizeof buf);
72         if (n == -1) {
73                 fprintf(stderr, "%s: invalid hex sequence: %s\n",
74                                 progname, hex);
75                 goto out;
76         } else if (n > sizeof buf) {
77                 fprintf(stderr, "%s: hex sequence too long: %s\n",
78                                 progname, hex);
79                 goto out;
80         }
81                 
82         rc = upkg_decode_index(&index, buf, n);
83         if (rc == 0) {
84                 fprintf(stderr, "%s: invalid index encoding:\n", progname);
85                 print_bytes(stderr, 4, buf, n);
86                 goto out;
87         } else if (rc < n) {
88                 fprintf(stderr, "%s: trailing bytes in argument:\n", progname);
89                 print_bytes(stderr, 4, buf+rc, n-rc);
90                 /* Non-fatal */
91         }
92
93         ret = 0;
94 out:
95         printf("%ld\n", index);
96         return ret;
97 }
98
99 int main(int argc, char **argv)
100 {
101         int opt, ret = EXIT_SUCCESS;
102
103         if (argc > 0)
104                 progname = argv[0];
105
106         while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
107                 switch (opt) {
108                 case 'V':
109                         print_version();
110                         return EXIT_SUCCESS;
111                 case 'H':
112                         print_usage(stdout);
113                         return EXIT_SUCCESS;
114                 default:
115                         print_usage(stderr);
116                         return EXIT_FAILURE;
117                 }
118         }
119
120         if (!argv[optind]) {
121                 print_usage(stderr);
122                 return EXIT_FAILURE;
123         }
124
125         for (int i = optind; i < argc; i++) {
126                 if (print_index(argv[i]) != 0) {
127                         ret = EXIT_FAILURE;
128                 }
129         }
130
131         return ret;
132 }