blob: 240f66bdaddc6af03e8632f799f3a0c3ba7fb741 [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
23#include <stdio.h>
Gavin Howard207053c2018-02-20 11:12:43 -070024#include <stdlib.h>
25#include <string.h>
26
27#include <libgen.h>
Gavin Howardf8333992018-02-19 13:55:25 -070028
Gavin Howard3f68df72018-03-22 20:30:27 -060029const char *bc_gen_usage = "usage: gen bc_script output [header]\n";
Gavin Howardfe2351d2018-02-19 14:10:15 -070030
31#define INVALID_PARAMS (1)
Gavin Howard207053c2018-02-20 11:12:43 -070032#define MALLOC_FAIL (2)
33#define INVALID_INPUT_FILE (3)
34#define INVALID_OUTPUT_FILE (4)
Gavin Howard1ba6bee2018-03-08 11:52:45 -070035#define INVALID_HEADER_FILE (5)
36#define IO_ERR (6)
Gavin Howardf8333992018-02-19 13:55:25 -070037
Gavin Howard7edf8292018-03-09 02:07:59 -070038#define MAX_WIDTH (74)
39
Gavin Howard8d1f1db2018-02-23 11:29:41 -070040int main(int argc, char *argv[]) {
Gavin Howardf8333992018-02-19 13:55:25 -070041
Gavin Howard1ba6bee2018-03-08 11:52:45 -070042 FILE *in;
43 FILE *out;
44 FILE *header;
45 char *header_name;
46 char *header_buf;
Gavin Howardf8333992018-02-19 13:55:25 -070047 int c;
48 int count;
Gavin Howard1ba6bee2018-03-08 11:52:45 -070049 char *buffer;
50 size_t len, read;
Gavin Howard8d1f1db2018-02-23 11:29:41 -070051 char *buf;
52 char *base;
Gavin Howardd571acf2018-02-20 17:13:07 -070053 int err;
Gavin Howard7edf8292018-03-09 02:07:59 -070054 int slashes;
Gavin Howardd571acf2018-02-20 17:13:07 -070055
56 err = 0;
Gavin Howardf8333992018-02-19 13:55:25 -070057
Gavin Howard1ba6bee2018-03-08 11:52:45 -070058 if (argc < 3) {
Gavin Howardd8a2b502018-02-24 13:26:48 -070059 printf("%s", bc_gen_usage);
Gavin Howardfe2351d2018-02-19 14:10:15 -070060 return INVALID_PARAMS;
Gavin Howardf8333992018-02-19 13:55:25 -070061 }
62
Gavin Howard207053c2018-02-20 11:12:43 -070063 buf = malloc(strlen(argv[1]) + 1);
64
65 if (!buf) return MALLOC_FAIL;
66
67 strcpy(buf, argv[1]);
68
69 base = basename(buf);
70
Gavin Howardf8333992018-02-19 13:55:25 -070071 in = fopen(argv[1], "r");
72
Gavin Howardd571acf2018-02-20 17:13:07 -070073 if (!in) {
74 err = INVALID_INPUT_FILE;
75 goto in_err;
76 }
Gavin Howardf8333992018-02-19 13:55:25 -070077
78 out = fopen(argv[2], "w");
79
Gavin Howardd571acf2018-02-20 17:13:07 -070080 if (!out) {
81 err = INVALID_OUTPUT_FILE;
82 goto out_err;
83 }
Gavin Howardf8333992018-02-19 13:55:25 -070084
Gavin Howard1ba6bee2018-03-08 11:52:45 -070085 if (argc >= 4) header_name = argv[3];
Gavin Howard6a11d792018-03-24 06:47:28 -060086 else header_name = "lib/header.c";
Gavin Howard1ba6bee2018-03-08 11:52:45 -070087
88 header = fopen(header_name, "r");
89
90 if (!header) {
91 err = INVALID_HEADER_FILE;
92 goto header_err;
93 }
94
95 fseek(header, 0, SEEK_END);
96 len = ftell(header);
97 fseek(header, 0, SEEK_SET);
98
99 buffer = malloc(len + 1);
100
101 if (!buffer) {
102 err = MALLOC_FAIL;
103 goto buffer_err;
104 }
105
106 read = fread(buffer, 1, len, header);
107
108 if (read != len) {
109 err = IO_ERR;
110 goto header_buf_err;
111 }
112
113 buffer[len] = '\0';
114
115 header_buf = malloc(len + strlen(base) + 1);
116
117 if (!header_buf) {
118 err= MALLOC_FAIL;
119 goto header_buf_err;
120 }
121
122 if (sprintf(header_buf, buffer, base) < 0) {
123 err = IO_ERR;
124 goto error;
125 }
126
Gavin Howardf8333992018-02-19 13:55:25 -0700127 count = 0;
128
Gavin Howard1ba6bee2018-03-08 11:52:45 -0700129 if (fputs(header_buf, out) == EOF) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700130 err = IO_ERR;
131 goto error;
132 }
Gavin Howard207053c2018-02-20 11:12:43 -0700133
Gavin Howard8d1f1db2018-02-23 11:29:41 -0700134 if (fprintf(out, "const char *bc_lib_name = \"%s\";\n\n", base) < 0) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700135 err = IO_ERR;
136 goto error;
137 }
Gavin Howardfe2351d2018-02-19 14:10:15 -0700138
Gavin Howardeb9a8222018-03-13 09:25:56 -0600139 if (fprintf(out, "const char bc_lib[] = {\n") < 0) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700140 err = IO_ERR;
141 goto error;
142 }
Gavin Howardf8333992018-02-19 13:55:25 -0700143
Gavin Howard7edf8292018-03-09 02:07:59 -0700144 slashes = 0;
145
146 while (slashes < 2 && (c = fgetc(in)) >= 0) {
147 if (slashes == 1 && c == '/' && fgetc(in) == '\n') ++slashes;
148 if (!slashes && c == '/' && fgetc(in) == '*') ++slashes;
149 }
150
151 if (c < 0) {
152 err = INVALID_INPUT_FILE;
153 goto error;
154 }
155
Gavin Howardf8333992018-02-19 13:55:25 -0700156 while ((c = fgetc(in)) >= 0) {
157
Gavin Howardfe2351d2018-02-19 14:10:15 -0700158 int val;
Gavin Howardf8333992018-02-19 13:55:25 -0700159
Gavin Howardfe2351d2018-02-19 14:10:15 -0700160 if (!count) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700161 if (fprintf(out, " ") < 0) {
162 err = IO_ERR;
163 goto error;
164 }
Gavin Howardfe2351d2018-02-19 14:10:15 -0700165 }
166
167 val = fprintf(out, "%d,", c);
168
Gavin Howardd571acf2018-02-20 17:13:07 -0700169 if (val < 0) {
170 err = IO_ERR;
171 goto error;
172 }
Gavin Howardfe2351d2018-02-19 14:10:15 -0700173
174 count += val;
Gavin Howardf8333992018-02-19 13:55:25 -0700175
Gavin Howard7edf8292018-03-09 02:07:59 -0700176 if (count > MAX_WIDTH) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700177
Gavin Howardf8333992018-02-19 13:55:25 -0700178 count = 0;
Gavin Howardd571acf2018-02-20 17:13:07 -0700179
180 if (fputc('\n', out) == EOF) {
181 err = IO_ERR;
182 goto error;
183 }
Gavin Howardf8333992018-02-19 13:55:25 -0700184 }
185 }
186
Gavin Howard8bdbb1f2018-02-20 16:17:16 -0700187 if (!count) {
Gavin Howard7edf8292018-03-09 02:07:59 -0700188 if (fputc(' ', out) == EOF || fputc(' ', out) == EOF) {
Gavin Howardd571acf2018-02-20 17:13:07 -0700189 err = IO_ERR;
190 goto error;
191 }
Gavin Howardfe2351d2018-02-19 14:10:15 -0700192 }
Gavin Howardd571acf2018-02-20 17:13:07 -0700193 if (fprintf(out, "0\n};\n") < 0) {
194 err = IO_ERR;
195 goto error;
196 }
Gavin Howardf8333992018-02-19 13:55:25 -0700197
Gavin Howardd571acf2018-02-20 17:13:07 -0700198error:
199
Gavin Howard1ba6bee2018-03-08 11:52:45 -0700200 free(header_buf);
201
202header_buf_err:
203
204 free(buffer);
205
206buffer_err:
207
208 fclose(header);
209
210header_err:
211
Gavin Howardf8333992018-02-19 13:55:25 -0700212 fclose(out);
213
Gavin Howardd571acf2018-02-20 17:13:07 -0700214out_err:
215
216 fclose(in);
217
218in_err:
219
220 free(buf);
221
222 return err;
Gavin Howardf8333992018-02-19 13:55:25 -0700223}