blob: 5d44825dacff2bf9e14698fb65f98c7fcc0c82de [file] [log] [blame]
Gavin Howardf8333992018-02-19 13:55:25 -07001/*
Gavin Howardb5904bf2018-02-20 13:28:18 -07002 * *****************************************************************************
Gavin Howardf8333992018-02-19 13:55:25 -07003 *
Gavin Howardb5904bf2018-02-20 13:28:18 -07004 * Copyright 2018 Gavin D. Howard
Gavin Howardf8333992018-02-19 13:55:25 -07005 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 *
Gavin Howardb5904bf2018-02-20 13:28:18 -070017 * *****************************************************************************
Gavin Howardf8333992018-02-19 13:55:25 -070018 *
19 * Generates a const array from a bc script.
20 *
21 */
22
Gavin Howardbe3a3422018-09-07 13:29:10 -060023#include <stdbool.h>
Gavin Howardf8333992018-02-19 13:55:25 -070024#include <stdio.h>
Gavin Howard207053c2018-02-20 11:12:43 -070025#include <stdlib.h>
26#include <string.h>
27
Gavin Howardbe3a3422018-09-07 13:29:10 -060028#include <errno.h>
29
Gavin Howard207053c2018-02-20 11:12:43 -070030#include <libgen.h>
Gavin Howardf8333992018-02-19 13:55:25 -070031
Gavin Howardbe3a3422018-09-07 13:29:10 -060032static const char* const bc_gen_header =
Gavin Howardb52a8792018-09-07 13:37:41 -060033 "// Copyright 2018 Gavin D. Howard. Under a 0-clause BSD license.\n"
Gavin Howardbe3a3422018-09-07 13:29:10 -060034 "// *** AUTOMATICALLY GENERATED FROM %s. DO NOT MODIFY. ***\n";
35
36static const char* const bc_gen_label = "const char *%s = \"%s\";\n\n";
37static const char* const bc_gen_name = "const char %s[] = {\n";
Gavin Howardfe2351d2018-02-19 14:10:15 -070038
39#define INVALID_PARAMS (1)
Gavin Howard207053c2018-02-20 11:12:43 -070040#define MALLOC_FAIL (2)
41#define INVALID_INPUT_FILE (3)
42#define INVALID_OUTPUT_FILE (4)
Gavin Howard1ba6bee2018-03-08 11:52:45 -070043#define INVALID_HEADER_FILE (5)
44#define IO_ERR (6)
Gavin Howardf8333992018-02-19 13:55:25 -070045
Gavin Howard7edf8292018-03-09 02:07:59 -070046#define MAX_WIDTH (74)
47
Gavin Howard8d1f1db2018-02-23 11:29:41 -070048int main(int argc, char *argv[]) {
Gavin Howardf8333992018-02-19 13:55:25 -070049
Gavin Howardbe3a3422018-09-07 13:29:10 -060050 FILE *in, *out;
Gavin Howardb52a8792018-09-07 13:37:41 -060051 char *label, *name;
Gavin Howardbe3a3422018-09-07 13:29:10 -060052 int c, count, err, slashes;
53 bool has_label;
Gavin Howardd571acf2018-02-20 17:13:07 -070054
55 err = 0;
Gavin Howardf8333992018-02-19 13:55:25 -070056
Gavin Howardbe3a3422018-09-07 13:29:10 -060057 if (argc < 4) {
Gavin Howard96d97932018-09-13 14:16:56 -060058 printf("usage: gen input output name [label]\n");
Gavin Howardfe2351d2018-02-19 14:10:15 -070059 return INVALID_PARAMS;
Gavin Howardf8333992018-02-19 13:55:25 -070060 }
61
Gavin Howardbe3a3422018-09-07 13:29:10 -060062 name = argv[3];
63
64 has_label = argc > 4;
65 label = has_label ? argv[4] : "";
66
Gavin Howardf8333992018-02-19 13:55:25 -070067 in = fopen(argv[1], "r");
68
Gavin Howardb52a8792018-09-07 13:37:41 -060069 if (!in) return INVALID_INPUT_FILE;
Gavin Howardf8333992018-02-19 13:55:25 -070070
71 out = fopen(argv[2], "w");
72
Gavin Howardd571acf2018-02-20 17:13:07 -070073 if (!out) {
74 err = INVALID_OUTPUT_FILE;
75 goto out_err;
76 }
Gavin Howardf8333992018-02-19 13:55:25 -070077
Gavin Howardb52a8792018-09-07 13:37:41 -060078 if (fprintf(out, bc_gen_header, argv[1]) < 0) {
Gavin Howard1ba6bee2018-03-08 11:52:45 -070079 err = IO_ERR;
80 goto error;
81 }
82
Gavin Howardb52a8792018-09-07 13:37:41 -060083 if (has_label && fprintf(out, bc_gen_label, label, argv[1]) < 0) {
Gavin Howardd571acf2018-02-20 17:13:07 -070084 err = IO_ERR;
85 goto error;
86 }
Gavin Howardfe2351d2018-02-19 14:10:15 -070087
Gavin Howardbe3a3422018-09-07 13:29:10 -060088 if (fprintf(out, bc_gen_name, name) < 0) {
Gavin Howardd571acf2018-02-20 17:13:07 -070089 err = IO_ERR;
90 goto error;
91 }
Gavin Howardf8333992018-02-19 13:55:25 -070092
Gavin Howard70610172018-09-05 20:30:08 -060093 c = count = slashes = 0;
Gavin Howard7edf8292018-03-09 02:07:59 -070094
95 while (slashes < 2 && (c = fgetc(in)) >= 0) {
96 if (slashes == 1 && c == '/' && fgetc(in) == '\n') ++slashes;
97 if (!slashes && c == '/' && fgetc(in) == '*') ++slashes;
98 }
99
100 if (c < 0) {
101 err = INVALID_INPUT_FILE;
102 goto error;
103 }
104
Gavin Howarddb28f432018-09-25 15:55:35 -0600105 c = fgetc(in);
106
107 if (c == '\n') c = fgetc(in);
108
109 while (c >= 0) {
Gavin Howardf8333992018-02-19 13:55:25 -0700110
Gavin Howardfe2351d2018-02-19 14:10:15 -0700111 int val;
Gavin Howardf8333992018-02-19 13:55:25 -0700112
Gavin Howardfe2351d2018-02-19 14:10:15 -0700113 if (!count) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700114 if (fprintf(out, " ") < 0) {
115 err = IO_ERR;
116 goto error;
117 }
Gavin Howardfe2351d2018-02-19 14:10:15 -0700118 }
119
120 val = fprintf(out, "%d,", c);
121
Gavin Howardd571acf2018-02-20 17:13:07 -0700122 if (val < 0) {
123 err = IO_ERR;
124 goto error;
125 }
Gavin Howardfe2351d2018-02-19 14:10:15 -0700126
127 count += val;
Gavin Howardf8333992018-02-19 13:55:25 -0700128
Gavin Howard7edf8292018-03-09 02:07:59 -0700129 if (count > MAX_WIDTH) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700130
Gavin Howardf8333992018-02-19 13:55:25 -0700131 count = 0;
Gavin Howardd571acf2018-02-20 17:13:07 -0700132
133 if (fputc('\n', out) == EOF) {
134 err = IO_ERR;
135 goto error;
136 }
Gavin Howardf8333992018-02-19 13:55:25 -0700137 }
Gavin Howarddb28f432018-09-25 15:55:35 -0600138
139 c = fgetc(in);
Gavin Howardf8333992018-02-19 13:55:25 -0700140 }
141
Gavin Howard8bdbb1f2018-02-20 16:17:16 -0700142 if (!count) {
Gavin Howard7edf8292018-03-09 02:07:59 -0700143 if (fputc(' ', out) == EOF || fputc(' ', out) == EOF) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700144 err = IO_ERR;
145 goto error;
146 }
Gavin Howardfe2351d2018-02-19 14:10:15 -0700147 }
Gavin Howardd571acf2018-02-20 17:13:07 -0700148 if (fprintf(out, "0\n};\n") < 0) {
149 err = IO_ERR;
150 goto error;
151 }
Gavin Howardf8333992018-02-19 13:55:25 -0700152
Gavin Howardd571acf2018-02-20 17:13:07 -0700153error:
154
Gavin Howardf8333992018-02-19 13:55:25 -0700155 fclose(out);
156
Gavin Howardd571acf2018-02-20 17:13:07 -0700157out_err:
158
159 fclose(in);
160
Gavin Howardd571acf2018-02-20 17:13:07 -0700161 return err;
Gavin Howardf8333992018-02-19 13:55:25 -0700162}