Mercurial > bcc
annotate bcc.c @ 32:d41fa28014a4 default tip @
misc: update copyright years
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 04 Jan 2024 10:17:16 +0100 |
parents | b314ce316e65 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * bcc.c -- binary to C/C++ arrays converter | |
3 * | |
32
d41fa28014a4
misc: update copyright years
David Demelier <markand@malikania.fr>
parents:
31
diff
changeset
|
4 * Copyright (c) 2020-2024 David Demelier <markand@malikania.fr> |
0 | 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 <string.h> | |
20
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
24 |
31 | 25 #if defined(__OpenBSD__) |
26 # include <unistd.h> | |
27 #endif | |
28 | |
20
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
29 #include "arg.h" |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
30 |
0 | 31 static const char *charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; |
27 | 32 static const char *ftype = "unsigned char"; |
0 | 33 static char findentchar = '\t'; |
7
43056d03d89a
bcc: remove usage of bool
David Demelier <markand@malikania.fr>
parents:
4
diff
changeset
|
34 static int findent = 1, fconst, fnull, fstatic; |
0 | 35 |
14
f81ab4107433
misc: noreturn is deprecated
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
36 static void |
0 | 37 usage(void) |
38 { | |
27 | 39 fprintf(stderr, "usage: bcc [-0cs] [-I tab-num] [-i space-num] [-t type] input variable\n"); |
0 | 40 exit(1); |
41 } | |
42 | |
14
f81ab4107433
misc: noreturn is deprecated
David Demelier <markand@malikania.fr>
parents:
13
diff
changeset
|
43 static void |
0 | 44 die(const char *fmt, ...) |
45 { | |
46 va_list ap; | |
47 | |
48 va_start(ap, fmt); | |
49 fputs("abort: ", stderr); | |
50 vfprintf(stderr, fmt, ap); | |
51 va_end(ap); | |
52 exit(1); | |
53 } | |
54 | |
55 static char * | |
56 mangle(char *variable) | |
57 { | |
58 char *p; | |
59 size_t pos; | |
60 | |
61 /* Remove extension. */ | |
62 if ((p = strrchr(variable, '.'))) | |
63 *p = '\0'; | |
64 | |
65 /* Remove disallowed characters. */ | |
66 while ((pos = strspn(variable, charset)) != strlen(variable)) | |
67 variable[pos] = '_'; | |
68 | |
69 return variable; | |
70 } | |
71 | |
72 static void | |
73 indent(void) | |
74 { | |
75 for (int i = 0; i < findent; ++i) | |
76 putchar(findentchar); | |
77 } | |
78 | |
79 static void | |
80 put(int ch) | |
81 { | |
3
b91e030a2040
bcc: generates only unsigned arrays
David Demelier <markand@malikania.fr>
parents:
0
diff
changeset
|
82 printf("0x%02hhx", (unsigned char)ch); |
0 | 83 } |
84 | |
85 static void | |
86 process(const char *input, const char *variable) | |
87 { | |
88 FILE *fp; | |
89 int ch, col = 0; | |
90 | |
91 if (strcmp(input, "-") == 0) | |
92 fp = stdin; | |
93 else if (!(fp = fopen(input, "rb"))) | |
94 die("%s: %s\n", input, strerror(errno)); | |
95 | |
96 if (fstatic) | |
97 printf("static "); | |
98 if (fconst) | |
99 printf("const "); | |
100 | |
27 | 101 printf("%s %s[] = {\n", ftype, variable); |
0 | 102 |
103 for (ch = fgetc(fp); ch != EOF; ) { | |
104 if (col == 0) | |
105 indent(); | |
106 | |
107 put(ch); | |
108 | |
109 if ((ch = fgetc(fp)) != EOF || fnull) | |
110 printf(",%s", col < 3 ? " " : ""); | |
111 | |
112 if (++col == 4) { | |
113 col = 0; | |
114 putchar('\n'); | |
115 } | |
116 | |
117 /* Add final '\0' if required. */ | |
118 if (ch == EOF && fnull) { | |
119 if (col++ == 0) | |
120 indent(); | |
121 | |
122 put(0); | |
123 } | |
124 } | |
125 | |
126 if (col != 0) | |
127 printf("\n"); | |
128 | |
129 puts("};"); | |
130 fclose(fp); | |
131 } | |
132 | |
133 int | |
20
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
134 main(int argc, char *argv[]) |
0 | 135 { |
15
9dd58c5e7d65
bcc: add pledge support
David Demelier <markand@malikania.fr>
parents:
14
diff
changeset
|
136 #if defined(__OpenBSD__) |
9dd58c5e7d65
bcc: add pledge support
David Demelier <markand@malikania.fr>
parents:
14
diff
changeset
|
137 if (pledge("rpath stdio", NULL) < 0) |
9dd58c5e7d65
bcc: add pledge support
David Demelier <markand@malikania.fr>
parents:
14
diff
changeset
|
138 die("abort: %s\n", strerror(errno)); |
9dd58c5e7d65
bcc: add pledge support
David Demelier <markand@malikania.fr>
parents:
14
diff
changeset
|
139 #endif |
9dd58c5e7d65
bcc: add pledge support
David Demelier <markand@malikania.fr>
parents:
14
diff
changeset
|
140 |
20
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
141 ARGBEGIN { |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
142 case '0': |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
143 fnull = 1; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
144 break; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
145 case 'c': |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
146 fconst = 1; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
147 break; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
148 case 'I': |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
149 findentchar = '\t'; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
150 findent = atoi(EARGF(usage())); |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
151 break; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
152 case 'i': |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
153 findentchar = ' '; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
154 findent = atoi(EARGF(usage())); |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
155 break; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
156 case 's': |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
157 fstatic = 1; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
158 break; |
27 | 159 case 't': |
160 ftype = EARGF(usage()); | |
161 break; | |
20
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
162 default: |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
163 usage(); |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
164 break; |
9c10473a0e66
misc: remove getopt for more portability
David Demelier <markand@malikania.fr>
parents:
15
diff
changeset
|
165 } ARGEND |
0 | 166 |
167 if (argc < 2) | |
168 usage(); | |
169 | |
170 process(argv[0], mangle(argv[1])); | |
171 } |