Blame


1 a2728733 2021-07-18 op /*
2 34b4388f 2022-02-08 op * Copyright (c) 2022, 2021 Omar Polo <op@omarpolo.com>
3 a2728733 2021-07-18 op *
4 a2728733 2021-07-18 op * Permission to use, copy, modify, and distribute this software for any
5 a2728733 2021-07-18 op * purpose with or without fee is hereby granted, provided that the above
6 a2728733 2021-07-18 op * copyright notice and this permission notice appear in all copies.
7 a2728733 2021-07-18 op *
8 a2728733 2021-07-18 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 a2728733 2021-07-18 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 a2728733 2021-07-18 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 a2728733 2021-07-18 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 a2728733 2021-07-18 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 a2728733 2021-07-18 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 a2728733 2021-07-18 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 a2728733 2021-07-18 op */
16 a2728733 2021-07-18 op
17 a2728733 2021-07-18 op /*
18 a2728733 2021-07-18 op * pagebundler converts the given file into a valid C program that can
19 a2728733 2021-07-18 op * be compiled. The generated code provides a variable that holds the
20 ed84beb9 2021-07-18 op * content of the original file and a _len variable with the size.
21 a2728733 2021-07-18 op *
22 34b4388f 2022-02-08 op * Usage: pagebundler file > outfile
23 a2728733 2021-07-18 op */
24 a2728733 2021-07-18 op
25 f3f98c70 2022-02-08 op #include <ctype.h>
26 a2728733 2021-07-18 op #include <errno.h>
27 34b4388f 2022-02-08 op #include <limits.h>
28 de6548b9 2021-07-18 op #include <stdint.h>
29 a2728733 2021-07-18 op #include <stdio.h>
30 34b4388f 2022-02-08 op #include <stdlib.h>
31 a2728733 2021-07-18 op #include <string.h>
32 de6548b9 2021-07-18 op #include <unistd.h>
33 a2728733 2021-07-18 op
34 34b4388f 2022-02-08 op static void
35 34b4388f 2022-02-08 op setfname(const char *fname, char *buf, size_t siz)
36 34b4388f 2022-02-08 op {
37 34b4388f 2022-02-08 op const char *c, *d;
38 34b4388f 2022-02-08 op size_t len;
39 a2728733 2021-07-18 op
40 34b4388f 2022-02-08 op if ((c = strrchr(fname, '/')) != NULL)
41 34b4388f 2022-02-08 op c++;
42 34b4388f 2022-02-08 op else
43 34b4388f 2022-02-08 op c = fname;
44 34b4388f 2022-02-08 op
45 34b4388f 2022-02-08 op if ((d = strrchr(fname, '.')) == NULL || c > d)
46 34b4388f 2022-02-08 op d = strchr(fname, '\0');
47 34b4388f 2022-02-08 op
48 34b4388f 2022-02-08 op len = d - c;
49 34b4388f 2022-02-08 op if (len >= siz) {
50 34b4388f 2022-02-08 op fprintf(stderr, "file name too long: %s\n", fname);
51 34b4388f 2022-02-08 op exit(1);
52 34b4388f 2022-02-08 op }
53 34b4388f 2022-02-08 op
54 34b4388f 2022-02-08 op memcpy(buf, c, len);
55 34b4388f 2022-02-08 op buf[len] = '\0';
56 34b4388f 2022-02-08 op }
57 34b4388f 2022-02-08 op
58 f3f98c70 2022-02-08 op static int
59 f3f98c70 2022-02-08 op validc(int c)
60 f3f98c70 2022-02-08 op {
61 f3f98c70 2022-02-08 op return isprint(c) && c != '\\' && c != '\'' && c != '\n';
62 f3f98c70 2022-02-08 op }
63 f3f98c70 2022-02-08 op
64 a2728733 2021-07-18 op int
65 a2728733 2021-07-18 op main(int argc, char **argv)
66 a2728733 2021-07-18 op {
67 f3f98c70 2022-02-08 op size_t len, r, i, n;
68 34b4388f 2022-02-08 op int did;
69 14967caf 2022-02-08 op FILE *f;
70 afda2dda 2022-02-08 op uint8_t buf[BUFSIZ];
71 34b4388f 2022-02-08 op char varname[PATH_MAX];
72 a2728733 2021-07-18 op
73 34b4388f 2022-02-08 op if (argc != 2) {
74 34b4388f 2022-02-08 op fprintf(stderr, "usage: %s file\n", *argv);
75 a2728733 2021-07-18 op return 1;
76 a2728733 2021-07-18 op }
77 a2728733 2021-07-18 op
78 34b4388f 2022-02-08 op setfname(argv[1], varname, sizeof(varname));
79 34b4388f 2022-02-08 op
80 34b4388f 2022-02-08 op if ((f = fopen(argv[1], "r")) == NULL) {
81 a2728733 2021-07-18 op fprintf(stderr, "%s: can't open %s: %s",
82 34b4388f 2022-02-08 op argv[0], argv[1], strerror(errno));
83 ed84beb9 2021-07-18 op return 1;
84 a2728733 2021-07-18 op }
85 a2728733 2021-07-18 op
86 f3f98c70 2022-02-08 op printf("const uint8_t %s[] = {", varname);
87 a2728733 2021-07-18 op
88 2aeddf9c 2021-07-18 op did = 0;
89 a2728733 2021-07-18 op len = 0;
90 f3f98c70 2022-02-08 op n = 0;
91 95a8c791 2021-08-26 op for (;;) {
92 a2728733 2021-07-18 op r = fread(buf, 1, sizeof(buf), f);
93 a2728733 2021-07-18 op len += r;
94 a2728733 2021-07-18 op
95 2aeddf9c 2021-07-18 op if (r != 0)
96 2aeddf9c 2021-07-18 op did = 1;
97 2aeddf9c 2021-07-18 op
98 f3f98c70 2022-02-08 op for (i = 0; i < r; ++i, ++n) {
99 f3f98c70 2022-02-08 op if (n % 12 == 0)
100 f3f98c70 2022-02-08 op printf("\n\t");
101 f3f98c70 2022-02-08 op else
102 f3f98c70 2022-02-08 op printf(" ");
103 f3f98c70 2022-02-08 op
104 f3f98c70 2022-02-08 op if (validc(buf[i]))
105 f3f98c70 2022-02-08 op printf("'%c',", buf[i]);
106 f3f98c70 2022-02-08 op else if (buf[i] == '\n')
107 f3f98c70 2022-02-08 op printf("'\\n',");
108 f3f98c70 2022-02-08 op else
109 f3f98c70 2022-02-08 op printf("0x%x,", buf[i]);
110 a2728733 2021-07-18 op }
111 a2728733 2021-07-18 op printf("\n");
112 a2728733 2021-07-18 op
113 a2728733 2021-07-18 op if (r != sizeof(buf))
114 a2728733 2021-07-18 op break;
115 a2728733 2021-07-18 op }
116 a2728733 2021-07-18 op
117 2aeddf9c 2021-07-18 op if (!did) {
118 2aeddf9c 2021-07-18 op /*
119 2aeddf9c 2021-07-18 op * if nothing was emitted, add a NUL byte. This was
120 2aeddf9c 2021-07-18 op * still produce an exact copy of the file because
121 2aeddf9c 2021-07-18 op * `len' doesn't count this NUL byte. It prevents the
122 2aeddf9c 2021-07-18 op * "use of GNU empty initializer extension" warning
123 2aeddf9c 2021-07-18 op * when bundling pages/about_empty.gmi
124 2aeddf9c 2021-07-18 op */
125 2aeddf9c 2021-07-18 op printf("\t0x0\n");
126 2aeddf9c 2021-07-18 op }
127 2aeddf9c 2021-07-18 op
128 a2728733 2021-07-18 op printf("}; /* %s */\n", varname);
129 a2728733 2021-07-18 op
130 a2728733 2021-07-18 op printf("size_t %s_len = %zu;\n", varname, len);
131 a2728733 2021-07-18 op
132 a2728733 2021-07-18 op fclose(f);
133 a2728733 2021-07-18 op return 0;
134 a2728733 2021-07-18 op }