-
Notifications
You must be signed in to change notification settings - Fork 12
/
juxt.c
97 lines (89 loc) · 2.82 KB
/
juxt.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* Decompress a brotli stream using yeast, and compare to the associated
original file. The brotli stream is expected to have an extension, i.e. a
period and characters that follow the period, and that same name with no
extension is the associated original file. This compares the decompressed
bytes as they are generated, and so catches and reports the error as soon as
possible. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "load.h"
#include "yeast.h"
/* Load the file at path into memory, allocating new memory if *dat is NULL, or
reusing the allocation at *dat of size *size. The length of the read data
is returned in *len. load_file() returns zero on success, non-zero on
failure. */
static int load_file(char *path, void **dat, size_t *size, size_t *len)
{
int ret = 0;
FILE *in = fopen(path, "rb");
if (in == NULL)
ret = -1;
else {
ret = load(in, 0, dat, size, len);
fclose(in);
}
if (ret)
fprintf(stderr, "could not load %s\n", path);
return ret;
}
/* Strip the extension off of a name in place. Return 0 on success or -1 if
the name does not have a period in the name or after the final slash. If
cut is 0, then the extension is not stripped -- only the status is returned
in order to see if a later strip() will succeed. */
static int strip(char *path, int cut)
{
char *dot;
dot = strrchr(path, '.');
if (dot == NULL || strchr(dot + 1, '/') != NULL)
return -1;
if (cut)
*dot = 0;
return 0;
}
/* Decompress and check all of the compressed files on the command line. */
int main(int argc, char **argv)
{
int ret;
void *compressed = NULL;
void *uncompressed = NULL;
size_t csize, clen, usize, ulen;
#ifdef DEBUG
/* process verbosity option */
if (argc > 1 && argv[1][0] == '-') {
char *opt;
--argc;
opt = *++argv;
while (*++opt) {
if (*opt == 'v')
yeast_verbosity++;
else {
fprintf(stderr, "juxt: invalid option %s\n", opt);
return 1;
}
}
}
#endif
/* test each name in the command line remaining */
while (++argv, --argc) {
if (strip(*argv, 0)) {
fprintf(stderr, "%s has no extension\n", *argv);
continue;
}
if (load_file(*argv, &compressed, &csize, &clen))
continue;
strip(*argv, 1);
if (load_file(*argv, &uncompressed, &usize, &ulen))
continue;
fprintf(stderr, "%s:\n", *argv);
ret = yeast(&uncompressed, &ulen, compressed, &clen, 1);
if (ret)
fprintf(stderr, "yeast() returned %d\n", ret);
if (argc > 1)
putchar('\n');
}
free(uncompressed);
free(compressed);
return 0;
}