Mercurial > sci
comparison extern/bcc/bcc.c @ 0:f1de39079243
misc: initial import
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 07 Jun 2021 09:41:37 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f1de39079243 |
---|---|
1 /* | |
2 * bcc.c -- binary to C/C++ arrays converter | |
3 * | |
4 * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr> | |
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 <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <stdnoreturn.h> | |
24 #include <string.h> | |
25 #include <unistd.h> | |
26 | |
27 static const char *charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; | |
28 static char findentchar = '\t'; | |
29 static int findent = 1, fconst, fnull, fstatic; | |
30 | |
31 noreturn static void | |
32 usage(void) | |
33 { | |
34 fprintf(stderr, "usage: bcc [-0cs] [-I tab-indent] [-i space-indent] input variable\n"); | |
35 exit(1); | |
36 } | |
37 | |
38 noreturn static void | |
39 die(const char *fmt, ...) | |
40 { | |
41 va_list ap; | |
42 | |
43 va_start(ap, fmt); | |
44 fputs("abort: ", stderr); | |
45 vfprintf(stderr, fmt, ap); | |
46 va_end(ap); | |
47 exit(1); | |
48 } | |
49 | |
50 static char * | |
51 mangle(char *variable) | |
52 { | |
53 char *p; | |
54 size_t pos; | |
55 | |
56 /* Remove extension. */ | |
57 if ((p = strrchr(variable, '.'))) | |
58 *p = '\0'; | |
59 | |
60 /* Remove disallowed characters. */ | |
61 while ((pos = strspn(variable, charset)) != strlen(variable)) | |
62 variable[pos] = '_'; | |
63 | |
64 return variable; | |
65 } | |
66 | |
67 static void | |
68 indent(void) | |
69 { | |
70 for (int i = 0; i < findent; ++i) | |
71 putchar(findentchar); | |
72 } | |
73 | |
74 static void | |
75 put(int ch) | |
76 { | |
77 printf("0x%02hhx", (unsigned char)ch); | |
78 } | |
79 | |
80 static void | |
81 process(const char *input, const char *variable) | |
82 { | |
83 FILE *fp; | |
84 int ch, col = 0; | |
85 | |
86 if (strcmp(input, "-") == 0) | |
87 fp = stdin; | |
88 else if (!(fp = fopen(input, "rb"))) | |
89 die("%s: %s\n", input, strerror(errno)); | |
90 | |
91 if (fstatic) | |
92 printf("static "); | |
93 if (fconst) | |
94 printf("const "); | |
95 | |
96 printf("unsigned char %s[] = {\n", variable); | |
97 | |
98 for (ch = fgetc(fp); ch != EOF; ) { | |
99 if (col == 0) | |
100 indent(); | |
101 | |
102 put(ch); | |
103 | |
104 if ((ch = fgetc(fp)) != EOF || fnull) | |
105 printf(",%s", col < 3 ? " " : ""); | |
106 | |
107 if (++col == 4) { | |
108 col = 0; | |
109 putchar('\n'); | |
110 } | |
111 | |
112 /* Add final '\0' if required. */ | |
113 if (ch == EOF && fnull) { | |
114 if (col++ == 0) | |
115 indent(); | |
116 | |
117 put(0); | |
118 } | |
119 } | |
120 | |
121 if (col != 0) | |
122 printf("\n"); | |
123 | |
124 puts("};"); | |
125 fclose(fp); | |
126 } | |
127 | |
128 int | |
129 main(int argc, char **argv) | |
130 { | |
131 int ch; | |
132 | |
133 while ((ch = getopt(argc, argv, "0cI:i:s")) != -1) { | |
134 switch (ch) { | |
135 case '0': | |
136 fnull = 1; | |
137 break; | |
138 case 'c': | |
139 fconst = 1; | |
140 break; | |
141 case 'I': | |
142 findentchar = '\t'; | |
143 findent = atoi(optarg); | |
144 break; | |
145 case 'i': | |
146 findentchar = ' '; | |
147 findent = atoi(optarg); | |
148 break; | |
149 case 's': | |
150 fstatic = 1; | |
151 break; | |
152 default: | |
153 break; | |
154 } | |
155 } | |
156 | |
157 argc -= optind; | |
158 argv += optind; | |
159 | |
160 if (argc < 2) | |
161 usage(); | |
162 | |
163 process(argv[0], mangle(argv[1])); | |
164 } |