Mercurial > molko
annotate src/tools/bcc/main.c @ 320:8f9937403749
misc: improve loading of data
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 01 Oct 2021 20:30:00 +0200 |
parents | tools/bcc/main.c@3bfaaf5342a9 |
children | 7d7991f97acf |
rev | line source |
---|---|
223 | 1 /* |
2 * main.c -- binary to C/C++ arrays converter | |
3 * | |
314 | 4 * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> |
223 | 5 * |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #include <errno.h> | |
20 #include <stdarg.h> | |
21 #include <stdbool.h> | |
22 #include <stdio.h> | |
23 #include <stdlib.h> | |
24 #include <stdnoreturn.h> | |
25 #include <string.h> | |
26 #include <unistd.h> | |
27 | |
315
3bfaaf5342a9
cmake: add support for Visual Studio 2019
David Demelier <markand@malikania.fr>
parents:
314
diff
changeset
|
28 #include <port/port.h> |
3bfaaf5342a9
cmake: add support for Visual Studio 2019
David Demelier <markand@malikania.fr>
parents:
314
diff
changeset
|
29 |
223 | 30 static const char *charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; |
31 static char findentchar = '\t'; | |
32 static int findent = 1; | |
33 static bool fconst; | |
34 static bool fnull; | |
35 static bool fstatic; | |
36 static bool funsigned; | |
37 | |
38 noreturn static void | |
39 usage(void) | |
40 { | |
41 fprintf(stderr, "usage: bcc [-0csu] [-I tab-indent] [-i space-indent] input variable\n"); | |
42 exit(1); | |
43 } | |
44 | |
45 noreturn static void | |
46 die(const char *fmt, ...) | |
47 { | |
48 va_list ap; | |
49 | |
50 va_start(ap, fmt); | |
51 fputs("abort: ", stderr); | |
52 vfprintf(stderr, fmt, ap); | |
53 va_end(ap); | |
54 exit(1); | |
55 } | |
56 | |
57 static char * | |
58 mangle(char *variable) | |
59 { | |
60 char *p; | |
61 size_t pos; | |
62 | |
63 /* Remove extension. */ | |
64 if ((p = strrchr(variable, '.'))) | |
65 *p = '\0'; | |
66 | |
67 /* Remove disallowed characters. */ | |
68 while ((pos = strspn(variable, charset)) != strlen(variable)) | |
69 variable[pos] = '_'; | |
70 | |
71 return variable; | |
72 } | |
73 | |
74 static void | |
75 indent(void) | |
76 { | |
77 for (int i = 0; i < findent; ++i) | |
78 putchar(findentchar); | |
79 } | |
80 | |
81 static void | |
82 put(int ch) | |
83 { | |
84 if (funsigned) | |
85 printf("0x%02hhx", (unsigned char)ch); | |
86 else | |
87 printf("%hhd", (signed char)ch); | |
88 } | |
89 | |
90 static void | |
91 process(const char *input, const char *variable) | |
92 { | |
93 FILE *fp; | |
94 int ch, col = 0; | |
95 | |
96 if (strcmp(input, "-") == 0) | |
97 fp = stdin; | |
98 else if (!(fp = fopen(input, "rb"))) | |
99 die("%s: %s\n", input, strerror(errno)); | |
100 | |
101 if (fstatic) | |
102 printf("static "); | |
103 if (fconst) | |
104 printf("const "); | |
105 | |
106 printf(funsigned ? "unsigned " : "signed "); | |
107 printf("char %s[] = {\n", variable); | |
108 | |
109 for (ch = fgetc(fp); ch != EOF; ) { | |
110 if (col == 0) | |
111 indent(); | |
112 | |
113 put(ch); | |
114 | |
115 if ((ch = fgetc(fp)) != EOF || fnull) | |
116 printf(",%s", col < 3 ? " " : ""); | |
117 | |
118 if (++col == 4) { | |
119 col = 0; | |
120 putchar('\n'); | |
121 } | |
122 | |
123 /* Add final '\0' if required. */ | |
124 if (ch == EOF && fnull) { | |
125 if (col++ == 0) | |
126 indent(); | |
127 | |
128 put(0); | |
129 } | |
130 } | |
131 | |
132 if (col != 0) | |
133 printf("\n"); | |
134 | |
135 puts("};"); | |
136 fclose(fp); | |
137 } | |
138 | |
139 int | |
140 main(int argc, char **argv) | |
141 { | |
142 int ch; | |
143 | |
144 while ((ch = getopt(argc, argv, "0cI:i:su")) != -1) { | |
145 switch (ch) { | |
146 case '0': | |
147 fnull = true; | |
148 break; | |
149 case 'c': | |
150 fconst = true; | |
151 break; | |
152 case 'I': | |
153 findentchar = '\t'; | |
154 findent = atoi(optarg); | |
155 break; | |
156 case 'i': | |
157 findentchar = ' '; | |
158 findent = atoi(optarg); | |
159 break; | |
160 case 's': | |
161 fstatic = true; | |
162 break; | |
163 case 'u': | |
164 funsigned = true; | |
165 break; | |
166 default: | |
167 break; | |
168 } | |
169 } | |
170 | |
171 argc -= optind; | |
172 argv += optind; | |
173 | |
174 if (argc < 2) | |
175 usage(); | |
176 | |
177 process(argv[0], mangle(argv[1])); | |
178 } |