Blender V4.3
datatoc.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <algorithm>
10#include <cstdio>
11#include <cstdlib>
12#include <cstring>
13
14// #define VERBOSE
15
16#define STRPREFIX(a, b) (strncmp((a), (b), strlen(b)) == 0)
17
18static char *arg_basename(char *string)
19{
20 char *lfslash, *lbslash;
21
22 lfslash = strrchr(string, '/');
23 lbslash = strrchr(string, '\\');
24 if (lbslash) {
25 lbslash++;
26 }
27 if (lfslash) {
28 lfslash++;
29 }
30
31 return std::max({string, lfslash, lbslash});
32}
33
43static int strip_leading_c_comment(FILE *fpin, int size, int *r_newlines)
44{
45 *r_newlines = 0;
46 if (size < 4) {
47 return 0;
48 }
49
50 enum {
51 IS_SPACE = 1,
52 IS_COMMENT = 2,
53 IS_COMMENT_MAYBE_BEG = 3,
54 IS_COMMENT_MAYBE_END = 4,
55 } context = IS_SPACE;
56
57 /* Last known valid offset. */
58 int offset_checkpoint = 0;
59 int newlines_checkpoint = 0;
60
61 int offset = 0;
62 int newlines = 0;
63
64 while (offset < size) {
65 const char c_curr = getc(fpin);
66 offset += 1;
67
68 if (context == IS_SPACE) {
69 if (c_curr == ' ' || c_curr == '\t' || c_curr == '\n') {
70 /* Pass. */
71 }
72 else if (c_curr == '/') {
73 context = IS_COMMENT_MAYBE_BEG;
74 }
75 else {
76 /* Non-space and non-comment, exit. */
77 break;
78 }
79 }
80 else if (context == IS_COMMENT) {
81 if (c_curr == '*') {
82 context = IS_COMMENT_MAYBE_END;
83 }
84 }
85 else if (context == IS_COMMENT_MAYBE_BEG) {
86 if (c_curr == '*') {
87 context = IS_COMMENT;
88 }
89 else {
90 /* Non-comment text, exit. */
91 break;
92 }
93 }
94 else if (context == IS_COMMENT_MAYBE_END) {
95 if (c_curr == '/') {
96 context = IS_SPACE;
97 }
98 else if (c_curr == '*') {
99 /* Pass. */
100 }
101 else {
102 context = IS_COMMENT;
103 }
104 }
105
106 if (c_curr == '\n') {
107 newlines += 1;
108 }
109
110 if (context == IS_SPACE) {
111 offset_checkpoint = offset;
112 newlines_checkpoint = newlines;
113 }
114 }
115
116 if (offset != offset_checkpoint) {
117 fseek(fpin, offset_checkpoint, SEEK_SET);
118 }
119 *r_newlines = newlines_checkpoint;
120 return offset_checkpoint;
121}
122
123int main(int argc, char **argv)
124{
125 FILE *fpin, *fpout;
126 long size;
127 int i;
128 int argv_len;
129
130 bool strip_leading_c_comments_test = false;
131 int leading_newlines = 0;
132
133 if (argc < 2) {
134 printf(
135 "Usage: "
136 "datatoc <data_file_from> <data_file_to> [--options=strip_leading_c_comments]\n");
137 exit(1);
138 }
139
140 if (argc > 3) {
141 const char *arg_extra = argv[3];
142 const char *arg_transform = "--options=";
143 if (STRPREFIX(arg_extra, arg_transform)) {
144 /* We may want to have other options in the future. */
145 const char *options = arg_extra + strlen(arg_transform);
146 if (strcmp(options, "strip_leading_c_comments") == 0) {
147 strip_leading_c_comments_test = true;
148 }
149 else {
150 printf("Unknown --options=<%s>\n", options);
151 exit(1);
152 }
153 }
154 else {
155 printf("Unknown argument <%s>, expected --options=[...] or none.\n", arg_extra);
156 exit(1);
157 }
158 }
159
160 fpin = fopen(argv[1], "rb");
161 if (!fpin) {
162 printf("Unable to open input <%s>\n", argv[1]);
163 exit(1);
164 }
165
166 argv[1] = arg_basename(argv[1]);
167
168 fseek(fpin, 0L, SEEK_END);
169 size = ftell(fpin);
170 fseek(fpin, 0L, SEEK_SET);
171
172 if (strip_leading_c_comments_test) {
173 const int size_offset = strip_leading_c_comment(fpin, size, &leading_newlines);
174 size -= size_offset; /* The comment is skipped, */
175 }
176
177 if (argv[1][0] == '.') {
178 argv[1]++;
179 }
180
181#ifdef VERBOSE
182 printf("Making C file <%s>\n", argv[2]);
183#endif
184
185 argv_len = int(strlen(argv[1]));
186 for (i = 0; i < argv_len; i++) {
187 if (argv[1][i] == '.') {
188 argv[1][i] = '_';
189 }
190 }
191
192 fpout = fopen(argv[2], "w");
193 if (!fpout) {
194 fprintf(stderr, "Unable to open output <%s>\n", argv[2]);
195 exit(1);
196 }
197
198 fprintf(fpout, "/* DataToC output of file <%s> */\n\n", argv[1]);
199
200 /* Quiet 'missing-variable-declarations' warning. */
201 fprintf(fpout, "extern const int datatoc_%s_size;\n", argv[1]);
202 fprintf(fpout, "extern const char datatoc_%s[];\n\n", argv[1]);
203
204 fprintf(fpout, "const int datatoc_%s_size = %d;\n", argv[1], int(leading_newlines + size));
205 fprintf(fpout, "const char datatoc_%s[] = {\n", argv[1]);
206
207 if (leading_newlines) {
208 while (leading_newlines--) {
209 if (leading_newlines % 32 == 31) {
210 fprintf(fpout, "\n");
211 }
212 fprintf(fpout, "%3d,", '\n');
213 }
214 fprintf(fpout, "\n");
215 }
216
217 while (size--) {
218 /* Even though this file is generated and doesn't need new-lines,
219 * these files may be loaded by developers when looking up symbols.
220 * Avoid a very long single line that may lock-up some editors. */
221 if (size % 32 == 31) {
222 fprintf(fpout, "\n");
223 }
224
225 // fprintf(fpout, "\\x%02x", getc(fpin));
226 fprintf(fpout, "%3d,", getc(fpin));
227 }
228
229 /* Trailing nullptr terminator, this isn't needed in some cases and
230 * won't be taken into account by the size variable, but its useful when dealing with
231 * nullptr terminated string data */
232 fprintf(fpout, "0\n};\n\n");
233
234 fclose(fpin);
235 fclose(fpout);
236 return 0;
237}
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define printf
CCL_NAMESPACE_BEGIN struct Options options
#define STRPREFIX(a, b)
Definition datatoc.cc:16
static int strip_leading_c_comment(FILE *fpin, int size, int *r_newlines)
Definition datatoc.cc:43
static char * arg_basename(char *string)
Definition datatoc.cc:18
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
#define L
int main()