Mercurial > hg > dmlib
comparison tools/data2inc.c @ 2421:1361e3883dd8
Make things more flexible.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 16 Jan 2020 14:08:48 +0200 |
parents | bc05bcfc4598 |
children | f07e3e66ca58 |
comparison
equal
deleted
inserted
replaced
2420:621d071530ce | 2421:1361e3883dd8 |
---|---|
24 char *desc; | 24 char *desc; |
25 char *fexts[SET_MAX_FEXTS]; | 25 char *fexts[SET_MAX_FEXTS]; |
26 | 26 |
27 char *defDataType; | 27 char *defDataType; |
28 | 28 |
29 int (*writeHeader) (FILE *fh, const char *name); | 29 int (*initContext) (void **pctx); |
30 int (*writeDecl) (FILE *fh, const size_t len, const char *name); | 30 int (*closeContext) (void *pctx); |
31 int (*writeData) (FILE *fh, const Uint8 *buf, const size_t len); | 31 |
32 int (*writeFooter) (FILE *fh, const size_t len, const char *name); | 32 int (*writeHeader) (FILE *fh, void *ctx, const char *name); |
33 int (*writeDecl) (FILE *fh, void *ctx, const size_t len, const char *name); | |
34 int (*writeData) (FILE *fh, void *ctx, const Uint8 *buf, const size_t len); | |
35 int (*writeFooter) (FILE *fh, void *ctx, const size_t len, const char *name); | |
33 } DMOutputFormat; | 36 } DMOutputFormat; |
34 | 37 |
35 | 38 |
36 // | 39 // |
37 // Options | 40 // Options |
202 | 205 |
203 return TRUE; | 206 return TRUE; |
204 } | 207 } |
205 | 208 |
206 | 209 |
210 static void dmPrintIndentation(FILE *fh) | |
211 { | |
212 if (optIndentation < 0) | |
213 { | |
214 for (int i = 0; i < -optIndentation; i++) | |
215 fputs("\t", fh); | |
216 } | |
217 else | |
218 if (optIndentation > 0) | |
219 { | |
220 for (int i = 0; i < optIndentation; i++) | |
221 fputs(" ", fh); | |
222 } | |
223 } | |
224 | |
225 | |
226 static int dmHandleError(const int res) | |
227 { | |
228 return res >= 0 ? DMERR_OK : dmGetErrno(); | |
229 } | |
230 | |
231 | |
207 /* Assembler include data output functions | 232 /* Assembler include data output functions |
208 */ | 233 */ |
209 int writeHeader_ASM(FILE *fh, const char *name) | 234 int writeHeader_ASM(FILE *fh, void *ctx, const char *name) |
210 { | 235 { |
211 int res = 0; | 236 int res = 0; |
237 (void) ctx; | |
212 | 238 |
213 if (name) | 239 if (name) |
214 res = fprintf(fh, "; '%s'", name); | 240 res = fprintf(fh, "; '%s'", name); |
215 else | 241 else |
216 res = fprintf(fh, "; Generated"); | 242 res = fprintf(fh, "; Generated"); |
217 | 243 |
218 if (res >= 0) | 244 if (res >= 0) |
219 res = fprintf(fh, " by %s v%s\n", | 245 res = fprintf(fh, " by %s v%s\n", |
220 dmProgName, dmProgVersion); | 246 dmProgName, dmProgVersion); |
221 | 247 |
222 return res >= 0 ? DMERR_OK : dmGetErrno(); | 248 return dmHandleError(res); |
223 } | 249 } |
224 | 250 |
225 | 251 |
226 int writeDecl_ASM(FILE *fh, const size_t len, const char *name) | 252 int writeDecl_ASM(FILE *fh, void *ctx, const size_t len, const char *name) |
227 { | 253 { |
228 int res = 0; | 254 int res = 0; |
255 (void) ctx; | |
229 | 256 |
230 if (optExtraData) | 257 if (optExtraData) |
231 res = fprintf(fh, "%s_size = %" DM_PRIu_SIZE_T "\n", name, len); | 258 res = fprintf(fh, "%s_size = %" DM_PRIu_SIZE_T "\n", name, len); |
232 | 259 |
233 if (res >= 0) | 260 if (res >= 0) |
234 res = fprintf(fh, "%s:\n", name); | 261 res = fprintf(fh, "%s:\n", name); |
235 | 262 |
236 return res >= 0 ? DMERR_OK : dmGetErrno(); | 263 return dmHandleError(res); |
237 } | 264 } |
238 | 265 |
239 | 266 |
240 int writeData_ASM(FILE *fh, const Uint8 * buf, const size_t len) | 267 int writeData_ASM(FILE *fh, void *ctx, const Uint8 * buf, const size_t len) |
241 { | 268 { |
242 int res = fprintf(fh, "%s ", optDataType); | 269 int res; |
270 (void) ctx; | |
271 | |
272 dmPrintIndentation(fh); | |
273 res = fprintf(fh, "%s ", optDataType); | |
243 | 274 |
244 for (size_t i = 0; res >= 0 && i < len; i++) | 275 for (size_t i = 0; res >= 0 && i < len; i++) |
245 { | 276 { |
246 if (optFormatting) | 277 if (optFormatting) |
247 { | 278 { |
260 | 291 |
261 if (res >= 0 && i + 1 < len) | 292 if (res >= 0 && i + 1 < len) |
262 res = fprintf(fh, optFormatting ? ", " : ","); | 293 res = fprintf(fh, optFormatting ? ", " : ","); |
263 } | 294 } |
264 | 295 |
265 return res >= 0 ? DMERR_OK : dmGetErrno(); | 296 if (res >= 0) |
266 } | 297 res = fprintf(fh, "\n"); |
267 | 298 |
268 | 299 return dmHandleError(res); |
269 int writeFooter_ASM(FILE *fh, const size_t len, const char *name) | 300 } |
301 | |
302 | |
303 int writeFooter_ASM(FILE *fh, void *ctx, const size_t len, const char *name) | |
270 { | 304 { |
271 int res; | 305 int res; |
272 (void) len; | 306 (void) len; |
307 (void) ctx; | |
273 | 308 |
274 if (optExtraData) | 309 if (optExtraData) |
275 res = fprintf(fh, "%s_end: \n", name); | 310 res = fprintf(fh, "%s_end: \n", name); |
276 else | 311 else |
277 res = fprintf(fh, "\n"); | 312 res = fprintf(fh, "\n"); |
278 | 313 |
279 return res >= 0 ? DMERR_OK : dmGetErrno(); | 314 return dmHandleError(res); |
280 } | 315 } |
281 | 316 |
282 | 317 |
283 /* ANSI-C include data output functions | 318 /* ANSI-C include data output functions |
284 */ | 319 */ |
285 int writeHeader_C(FILE *fh, const char *name) | 320 int writeHeader_C(FILE *fh, void *ctx, const char *name) |
286 { | 321 { |
287 int res; | 322 int res; |
323 (void) ctx; | |
288 | 324 |
289 if (name) | 325 if (name) |
290 res = fprintf(fh, "/* '%s' generated", name); | 326 res = fprintf(fh, "/* '%s' generated", name); |
291 else | 327 else |
292 res = fprintf(fh, "/* Generated"); | 328 res = fprintf(fh, "/* Generated"); |
293 | 329 |
294 if (res >= 0) | 330 if (res >= 0) |
295 res = fprintf(fh, " by %s v%s\n" " */\n", | 331 res = fprintf(fh, " by %s v%s\n" " */\n", |
296 dmProgName, dmProgVersion); | 332 dmProgName, dmProgVersion); |
297 | 333 |
298 return res >= 0 ? DMERR_OK : dmGetErrno(); | 334 return dmHandleError(res); |
299 } | 335 } |
300 | 336 |
301 | 337 |
302 int writeDecl_C(FILE *fh, const size_t len, const char *name) | 338 int writeDecl_C(FILE *fh, void *ctx, const size_t len, const char *name) |
303 { | 339 { |
304 int res; | 340 int res; |
341 (void) ctx; | |
305 | 342 |
306 res = fprintf(fh, "%s %s[%" DM_PRIu_SIZE_T "] = {\n", | 343 res = fprintf(fh, "%s %s[%" DM_PRIu_SIZE_T "] = {\n", |
307 optDataType, name, len); | 344 optDataType, name, len); |
308 | 345 |
309 if (res >= 0) | 346 if (res >= 0) |
310 res = printf("extern %s %s[%" DM_PRIu_SIZE_T "];\n", | 347 res = printf("extern %s %s[%" DM_PRIu_SIZE_T "];\n", |
311 optDataType, name, len); | 348 optDataType, name, len); |
312 | 349 |
313 return res >= 0 ? DMERR_OK : dmGetErrno(); | 350 return dmHandleError(res); |
314 } | 351 } |
315 | 352 |
316 | 353 |
317 int writeData_C(FILE *fh, const Uint8 *buf, const size_t len) | 354 int writeData_C(FILE *fh, void *ctx, const Uint8 *buf, const size_t len) |
318 { | 355 { |
319 int res = 0; | 356 int res = 0; |
357 (void) ctx; | |
358 | |
359 dmPrintIndentation(fh); | |
320 | 360 |
321 for (size_t i = 0; res >= 0 && i < len; i++) | 361 for (size_t i = 0; res >= 0 && i < len; i++) |
322 { | 362 { |
323 if (optFormatting) | 363 if (optFormatting) |
324 { | 364 { |
337 | 377 |
338 if (res >= 0) | 378 if (res >= 0) |
339 res = fprintf(fh, optFormatting ? ", " : ","); | 379 res = fprintf(fh, optFormatting ? ", " : ","); |
340 } | 380 } |
341 | 381 |
342 return res >= 0 ? DMERR_OK : dmGetErrno(); | 382 if (res >= 0) |
343 } | 383 res = fprintf(fh, "\n"); |
344 | 384 |
345 | 385 return dmHandleError(res); |
346 int writeFooter_C(FILE *fh, const size_t len, const char *name) | 386 } |
387 | |
388 | |
389 int writeFooter_C(FILE *fh, void *ctx, const size_t len, const char *name) | |
347 { | 390 { |
348 int res; | 391 int res; |
349 (void) len; | 392 (void) len; |
350 (void) name; | 393 (void) name; |
394 (void) ctx; | |
351 | 395 |
352 res = fprintf(fh, "};\n"); | 396 res = fprintf(fh, "};\n"); |
353 return res >= 0 ? DMERR_OK : dmGetErrno(); | 397 return dmHandleError(res); |
354 } | 398 } |
355 | 399 |
356 | 400 |
357 /* | 401 /* |
358 * List of formats | 402 * List of formats |
362 { | 406 { |
363 "asm", | 407 "asm", |
364 "XA65 compatible assembler", | 408 "XA65 compatible assembler", |
365 { "s", "asm", NULL }, | 409 { "s", "asm", NULL }, |
366 ".byte", | 410 ".byte", |
411 | |
412 NULL, | |
413 NULL, | |
367 | 414 |
368 writeHeader_ASM, | 415 writeHeader_ASM, |
369 writeDecl_ASM, | 416 writeDecl_ASM, |
370 writeData_ASM, | 417 writeData_ASM, |
371 writeFooter_ASM, | 418 writeFooter_ASM, |
373 | 420 |
374 { | 421 { |
375 "c", | 422 "c", |
376 "ANSI C array", | 423 "ANSI C array", |
377 { "c", "h", "cc", "cpp", "hpp", "c++", NULL }, | 424 { "c", "h", "cc", "cpp", "hpp", "c++", NULL }, |
378 | |
379 "unsigned char", | 425 "unsigned char", |
426 | |
427 NULL, | |
428 NULL, | |
380 | 429 |
381 writeHeader_C, | 430 writeHeader_C, |
382 writeDecl_C, | 431 writeDecl_C, |
383 writeData_C, | 432 writeData_C, |
384 writeFooter_C, | 433 writeFooter_C, |
422 | 471 |
423 int main(int argc, char *argv[]) | 472 int main(int argc, char *argv[]) |
424 { | 473 { |
425 FILE *inFile = NULL, *outFile = NULL; | 474 FILE *inFile = NULL, *outFile = NULL; |
426 Uint8 *dataBuf = NULL; | 475 Uint8 *dataBuf = NULL; |
476 void *ctx = NULL; | |
427 size_t dataSize; | 477 size_t dataSize; |
428 off_t totalSize; | 478 off_t totalSize; |
429 int res; | 479 int res; |
430 | 480 |
431 // Initialize | 481 // Initialize |
494 } | 544 } |
495 | 545 |
496 // Get sourcefile size | 546 // Get sourcefile size |
497 totalSize = dmGetFileSize(inFile); | 547 totalSize = dmGetFileSize(inFile); |
498 | 548 |
549 // Call context init | |
550 if (setFormat->initContext != NULL && | |
551 (res = setFormat->initContext(&ctx)) != DMERR_OK) | |
552 { | |
553 dmErrorMsg("Error initializing format %s (%s) context: %s\n", | |
554 setFormat->name, setFormat->desc, | |
555 dmErrorStr(res)); | |
556 goto exit; | |
557 } | |
558 | |
499 // Output header | 559 // Output header |
500 if (!optQuiet && | 560 if (!optQuiet && |
501 (res = setFormat->writeHeader(outFile, optOutFilename)) != DMERR_OK) | 561 (res = setFormat->writeHeader(outFile, ctx, optOutFilename)) != DMERR_OK) |
502 { | 562 { |
503 dmErrorMsg("Error writing output header: %s\n", | 563 dmErrorMsg("Error writing output header: %s\n", |
504 dmErrorStr(res)); | 564 dmErrorStr(res)); |
505 goto exit; | 565 goto exit; |
506 } | 566 } |
507 | 567 |
508 if (optAddLine) | 568 if (optAddLine) |
509 fprintf(outFile, "%s\n", optAddLine); | 569 fprintf(outFile, "%s\n", optAddLine); |
510 | 570 |
511 // Output declaration | 571 // Output declaration |
512 setFormat->writeDecl(outFile, totalSize, optObjName); | 572 if (setFormat->writeDecl != NULL && |
573 (res = setFormat->writeDecl(outFile, ctx, totalSize, optObjName)) != DMERR_OK) | |
574 { | |
575 dmErrorMsg("Error writing output declaration: %s\n", | |
576 dmErrorStr(res)); | |
577 goto exit; | |
578 } | |
513 | 579 |
514 // Output data | 580 // Output data |
515 while (!feof(inFile)) | 581 while (!feof(inFile)) |
516 { | 582 { |
517 res = fread(dataBuf, 1, dataSize, inFile); | 583 res = fread(dataBuf, 1, dataSize, inFile); |
518 if (res > 0) | 584 if (res > 0 && |
519 { | 585 (res = setFormat->writeData(outFile, ctx, dataBuf, res)) != DMERR_OK) |
520 if (optIndentation < 0) | 586 { |
521 { | 587 dmErrorMsg("Error writing output data: %s\n", |
522 for (int i = 0; i < -optIndentation; i++) | 588 dmErrorStr(res)); |
523 fputs("\t", outFile); | 589 goto exit; |
524 } | |
525 else | |
526 if (optIndentation > 0) | |
527 { | |
528 for (int i = 0; i < optIndentation; i++) | |
529 fputs(" ", outFile); | |
530 } | |
531 | |
532 if ((res = setFormat->writeData(outFile, dataBuf, res)) != DMERR_OK) | |
533 { | |
534 dmErrorMsg("Error writing output data: %s\n", | |
535 dmErrorStr(res)); | |
536 goto exit; | |
537 } | |
538 | |
539 fprintf(outFile, "\n"); | |
540 } | 590 } |
541 } | 591 } |
542 | 592 |
543 // Output footer | 593 // Output footer |
544 if ((res = setFormat->writeFooter(outFile, totalSize, optObjName)) != DMERR_OK) | 594 if (setFormat->writeFooter != NULL && |
595 (res = setFormat->writeFooter(outFile, ctx, totalSize, optObjName)) != DMERR_OK) | |
545 { | 596 { |
546 dmErrorMsg("Error writing output footer: %s\n", | 597 dmErrorMsg("Error writing output footer: %s\n", |
547 dmErrorStr(res)); | 598 dmErrorStr(res)); |
548 goto exit; | 599 goto exit; |
549 } | 600 } |
556 if (outFile != NULL) | 607 if (outFile != NULL) |
557 fclose(outFile); | 608 fclose(outFile); |
558 | 609 |
559 dmFree(dataBuf); | 610 dmFree(dataBuf); |
560 | 611 |
612 if (setFormat != NULL && | |
613 setFormat->closeContext != NULL && | |
614 (res = setFormat->closeContext(ctx)) != DMERR_OK) | |
615 { | |
616 dmErrorMsg("Error closing format %s (%s) context: %s\n", | |
617 setFormat->name, setFormat->desc, | |
618 dmErrorStr(res)); | |
619 } | |
620 | |
561 return 0; | 621 return 0; |
562 } | 622 } |