Skip to content

Commit 613fb3a

Browse files
committed
Rework output (WIP)
1 parent 07b9f90 commit 613fb3a

5 files changed

Lines changed: 182 additions & 55 deletions

File tree

cli/etripator.c

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -262,49 +262,76 @@ static bool code_extract(FILE *out, SectionArray *arr, int index, MemoryMap *map
262262
return true;
263263
}
264264

265-
static void print_header(FILE *out, Section *current, Section *previous) {
265+
static bool print_header(Output *output, Section *current, Section *previous) {
266+
bool ret = false;
266267
if(previous && ((previous->logical + previous->size) == current->logical)) {
267268
// ...
268269
} else if((current->type != SECTION_TYPE_DATA) || (current->data.type != DATA_TYPE_BINARY)) {
269-
/* Print header */
270-
fprintf(out, "\t.%s\n"
271-
"\t.bank $%03x\n"
272-
"\t.org $%04x\n",
273-
(current->type == SECTION_TYPE_CODE) ? "code" : "data", current->page, current->logical);
270+
const char *str = (current->type == SECTION_TYPE_CODE) ? ".code" : ".data";
271+
if(output_fill_n(output, ' ', 4U) != true) {
272+
// ...
273+
} else if(output_string(output, str) != true) {
274+
// ...
275+
} else if(output_newline(output) != true) {
276+
// ...
277+
} else if(output_fill_n(output, ' ', 4U) != true) {
278+
// ...
279+
} else if(output_string(output, ".bank ") != true) {
280+
// ...
281+
} else if(output_8h(output, current->page) != true) {
282+
// ...
283+
} else if(output_newline(output) != true) {
284+
// ...
285+
} else if(output_fill_n(output, ' ', 4U) != true) {
286+
// ...
287+
} else if(output_string(output, ".org ") != true) {
288+
// ...
289+
} else if(output_16h(output, current->offset) != true) {
290+
// ...
291+
} else if(output_newline(output) != true) {
292+
// ...
293+
} else {
294+
ret = true;
295+
}
274296
}
297+
return ret;
275298
}
276299

277-
static bool disassemble(SectionArray *arr, MemoryMap *map, LabelRepository *labels, CommentRepository *comments, CommandLineOptions *options) {
300+
static bool disassemble(OutputRegistry *registry, SectionArray *arr, MemoryMap *map, LabelRepository *labels, CommentRepository *comments, CommandLineOptions *options) {
278301
bool ret = true;
279302
Section *previous = NULL;
280303
Section *current = NULL;
281304
for (int i = 0; ret && (i < arr->count); ++i, previous=current) {
282-
current = &arr->data[i];
283-
FILE *out = fopen(current->output, "ab");
284-
if (out == NULL) {
285-
ERROR_MSG("Can't open %s : %s", current->output, strerror(errno));
286-
} else {
287-
if (options->cdrom && (current->offset != ((current->page << 13) | (current->logical & 0x1fff)))) {
288-
size_t offset = current->offset;
289-
/* Copy CDROM data */
290-
if (!cd_load(options->rom_filename, current->offset, current->size, options->sector_size, current->page, current->logical, map)) {
291-
ERROR_MSG("Failed to load CD data (section %d)", i);
292-
} else {
293-
ret = false;
294-
}
305+
Output *output = NULL;
306+
if (options->cdrom && (current->offset != ((current->page << 13) | (current->logical & 0x1fff)))) {
307+
size_t offset = current->offset;
308+
// Copy CDROM data
309+
if (!cd_load(options->rom_filename, current->offset, current->size, options->sector_size, current->page, current->logical, map)) {
310+
ERROR_MSG("Failed to load CD data (section %d)", i);
311+
} else {
312+
ret = false;
295313
}
314+
}
296315

297-
if(ret) {
298-
print_header(out, current, previous);
316+
if(ret) {
317+
ret = false;
318+
current = &arr->data[i];
319+
if(output_find(registry, current->output, &output) != true) {
320+
ERROR_MSG("No output registered for %s", current->output);
321+
} else if(output_begin(output) != true) {
322+
ERROR_MSG("Unable to open %s : %s", current->output, strerror(errno));
323+
} else {
299324
memory_map_mpr(map, current->mpr);
300-
301-
if (current->type == SECTION_TYPE_CODE) {
302-
ret = code_extract(out, arr, i, map, labels, comments, options->address);
325+
if(print_header(output, current, previous) != true) {
326+
// ...
327+
} else if (current->type == SECTION_TYPE_CODE) {
328+
// [todo] ret = code_extract(out, arr, i, map, labels, comments, options->address);
329+
ret = true;
303330
} else {
304-
ret = data_extract(out, current, map, labels, comments, options->address);
331+
ret = data_extract(output, current, map, labels, comments, options->address);
305332
}
333+
output_end(output);
306334
}
307-
fclose(out);
308335
}
309336
}
310337
return ret;
@@ -371,7 +398,7 @@ int main(int argc, char **argv) {
371398
// ...
372399
} else {
373400
ret = EXIT_SUCCESS;
374-
if(!disassemble(&section_arr, &map, &labels, &comments, &options)) {
401+
if(!disassemble(&output, &section_arr, &map, &labels, &comments, &options)) {
375402
ret = EXIT_FAILURE;
376403
}
377404
if (label_output(&labels, &options)) {

decode.c

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -157,25 +157,26 @@ bool label_extract(LabelRepository *labels, MemoryMap *map, Section *section) {
157157
return ret;
158158
}
159159

160-
static int data_extract_binary(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository) {
160+
static bool data_extract_binary(Output *output, Section *section, MemoryMap *map, LabelRepository *repository) {
161161
uint16_t logical;
162162
int32_t i;
163-
for (i = 0, logical = section->logical; i < section->size; i++, logical++) {
163+
bool ret = true;
164+
for (i = 0, logical = section->logical; ret && (i < section->size); i++, logical++) {
164165
uint8_t data = memory_map_read(map, logical);
165-
fwrite(&data, 1, 1, out);
166+
ret = output_raw(output, data);
166167
}
167-
return 1;
168+
return ret;
168169
}
169170

170-
static int data_extract_hex(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository,
171+
static int data_extract_hex(Output *output, Section *section, MemoryMap *map, LabelRepository *repository,
171172
CommentRepository *comments, int extra_infos) {
172173
const int32_t element_size = section->data.element_size;
173174
const int32_t elements_per_line = section->data.elements_per_line;
174175

175176
int32_t i, j;
176177
uint16_t logical;
177178

178-
size_t line_offset = ftell(out);
179+
//size_t line_offset = ftell(out);
179180
uint8_t line_page = section->page;
180181
uint16_t line_logical = section->logical;
181182

@@ -186,37 +187,51 @@ static int data_extract_hex(FILE *out, Section *section, MemoryMap *map, LabelRe
186187
uint8_t data[2] = {0};
187188
int32_t top = 0;
188189

190+
bool ret = false;
191+
189192
for (i = 0, j = 0, logical = section->logical; i < section->size; i++, logical++) {
190193
uint8_t page = memory_map_page(map, logical);
191194
Label label = {0};
192195
bool has_label = label_repository_find(repository, logical, page, &label);
193196
if (has_label) {
194197
// flush any bytes left in the buffer.
195198
if (top && (top < element_size)) {
196-
fprintf(out, "\n%s.db $%02x", g_spacing, data[0]);
199+
ret = output_newline(output);
200+
ret = output_fill_n(output, ' ', 4U);
201+
ret = output_string(output, ".db");
202+
ret = output_char(output, ' ');
203+
ret = output_8h(output, data[0]);
204+
197205
for (int32_t l = 1; l < top; l++) { // useless as top is always equal to 1
198-
fprintf(out, ",$%02x", data[l]);
206+
ret = output_char(output, ',');
207+
ret = output_8h(output, data[l]);
199208
}
200209
top = 0;
201210
}
202211
if (i) {
203-
fputc('\n', out);
212+
ret = output_newline(output);
204213
}
205-
print_label(out, &label);
214+
ret = output_label(output, &label);
206215
j = 0;
207216
}
208217

209218
Comment dummy;
210219
if (comment_repository_find(comments, logical, page, &dummy)) {
211220
if (has_comment) {
212221
if (top && (top < element_size)) {
213-
fprintf(out, "\n%s.db $%02x", g_spacing, data[0]);
222+
ret = output_newline(output);
223+
ret = output_fill_n(output, ' ', 4U);
224+
ret = output_string(output, ".db");
225+
ret = output_char(output, ' ');
226+
ret = output_8h(output, data[0]);
227+
214228
for (int32_t l = 1; l < top; l++) { // useless as top is always equal to 1
215-
fprintf(out, ",$%02x", data[l]);
229+
ret = output_char(output, ',');
230+
ret = output_8h(output, data[l]);
216231
}
217232
top = 0;
218233
}
219-
print_inline_comment(out, (int)(ftell(out) - line_offset), comment.text);
234+
ret = output_inline_comment(output, comment.text);
220235
}
221236
comment = dummy;
222237
has_comment = true;
@@ -228,15 +243,16 @@ static int data_extract_hex(FILE *out, Section *section, MemoryMap *map, LabelRe
228243
if (top >= element_size) {
229244
char sep;
230245
if (j == 0) {
231-
fputc('\n', out);
246+
ret = output_newline(output);
232247

233-
line_offset = ftell(out);
234248
line_logical = logical - top + 1;
235249
line_page = page;
236250

237251
const char *data_decl = (top > 1) ? ".dw" : ".db";
238252

239-
fprintf(out, "%s%s", g_spacing, data_decl);
253+
ret = output_fill_n(output, ' ', 4U);
254+
ret = output_string(output, data_decl);
255+
240256
sep = ' ';
241257
} else {
242258
sep = ',';
@@ -280,7 +296,7 @@ static int data_extract_hex(FILE *out, Section *section, MemoryMap *map, LabelRe
280296
}
281297
}
282298
fputc('\n', out);
283-
return 1;
299+
return ret;
284300
}
285301

286302
static int data_extract_string(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository,
@@ -305,7 +321,7 @@ static int data_extract_string(FILE *out, Section *section, MemoryMap *map, Labe
305321
Label label = {0};
306322
bool has_label = label_repository_find(repository, logical, page, &label);
307323
if (has_label) {
308-
if (c) { // close string if neededs
324+
if (c) { // close string if needed
309325
fputc('"', out);
310326
c = 0;
311327
}
@@ -319,7 +335,7 @@ static int data_extract_string(FILE *out, Section *section, MemoryMap *map, Labe
319335
Comment dummy = {0};
320336
if (comment_repository_find(comments, logical, page, &dummy)) {
321337
if (j) {
322-
if (c) { // close string if neededs
338+
if (c) { // close string if needed
323339
fputc('"', out);
324340
c = 0;
325341
}
@@ -335,7 +351,7 @@ static int data_extract_string(FILE *out, Section *section, MemoryMap *map, Labe
335351
// display directives
336352
if (j == 0) {
337353
fputc('\n', out);
338-
line_offset = ftell(out); // record star of line
354+
line_offset = ftell(out); // record start of line
339355
line_logical = logical;
340356
line_page = page;
341357
fprintf(out, "%s.db ", g_spacing);
@@ -501,17 +517,17 @@ static int data_extract_jump_table(FILE *out, Section *section, MemoryMap *map,
501517
}
502518

503519
/* Process data section. The result will be output has a binary file or an asm file containing hex values or strings. */
504-
bool data_extract(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository,
520+
bool data_extract(Output *output, Section *section, MemoryMap *map, LabelRepository *repository,
505521
CommentRepository *comments, int extra_infos) {
506522
switch (section->data.type) {
507523
case DATA_TYPE_BINARY:
508-
return data_extract_binary(out, section, map, repository);
524+
return data_extract_binary(output, section, map, repository);
509525
case DATA_TYPE_HEX:
510-
return data_extract_hex(out, section, map, repository, comments, extra_infos);
526+
return data_extract_hex(output, section, map, repository, comments, extra_infos);
511527
case DATA_TYPE_STRING:
512-
return data_extract_string(out, section, map, repository, comments, extra_infos);
528+
return true; // [todo] data_extract_string(out, section, map, repository, comments, extra_infos);
513529
case DATA_TYPE_JUMP_TABLE:
514-
return data_extract_jump_table(out, section, map, repository, comments, extra_infos);
530+
return true; // [todo] data_extract_jump_table(out, section, map, repository, comments, extra_infos);
515531
default:
516532
return false;
517533
}

decode.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@
5454
bool label_extract(LabelRepository *labels, MemoryMap *map, Section *section);
5555

5656
/// Process data section. The result will be output has a binary file or an asm file containing hex values or strings.
57-
/// \param [out] out File output.
57+
/// \param [out] output File output.
5858
/// \param [in] section Current section.
5959
/// \param [in] map Memory map.
6060
/// \param [in] repository Label repository.
6161
/// \param [in] comments Comments repository.
6262
/// \param [in] extra_infos Display extra informations as comments (if none set).
6363
/// \return true upon success.
6464
/// \return false if an error occured.
65-
bool data_extract(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository, CommentRepository *comments, int extra_infos);
65+
bool data_extract(Output *output, Section *section, MemoryMap *map, LabelRepository *repository, CommentRepository *comments, int extra_infos);
6666

6767
/// Process code section.
6868
/// \param [out] out File output.

output.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ void output_end(Output *output) {
153153

154154
// Write single char
155155
bool output_char(Output *output, char c) {
156+
assert(output != NULL);
156157
bool ret = false;
157158
if(fputc(c, output->stream) == EOF) {
158159
ERROR_MSG("failed to print '%c' to %s: %s", c, output->filename, strerror(errno));
@@ -347,3 +348,62 @@ bool output_label(Output *output, Label *label) {
347348

348349
return ret;
349350
}
351+
352+
// Print a single byte in hexadecimal format
353+
bool output_8h(Output *output, uint8_t data) {
354+
bool ret = false;
355+
if(output_char(output, '$') != true) {
356+
// ...
357+
} else {
358+
ret = output_byte(output, data);
359+
}
360+
return ret;
361+
}
362+
363+
// Print a 16 bits value in hexadecimal format
364+
bool output_16h(Output *output, uint16_t data) {
365+
bool ret = false;
366+
if(output_char(output, '$') != true) {
367+
// ...
368+
} else {
369+
ret = output_word(output, data);
370+
}
371+
return ret;
372+
}
373+
374+
// Write a raw byte to the output stream
375+
bool output_raw(Output *output, uint8_t data) {
376+
bool ret = false;
377+
if(fwrite(&data, 1, 1, output->stream) != 1) {
378+
ERROR_MSG("failed to write 0x%02x to %s: %s", data, output->filename, strerror(errno));
379+
} else {
380+
output->column++;
381+
ret = true;
382+
}
383+
return ret;
384+
}
385+
386+
// [todo]
387+
bool output_fmt(Output *output, const char *format, ...) {
388+
bool ret = true;
389+
char *buffer = NULL;
390+
391+
va_list args;
392+
va_start(args, format);
393+
int n = vasprintf(&buffer, format, args);
394+
va_end(args);
395+
396+
if(n > 0) {
397+
for(size_t i=0; ret && (i<n) && (buffer[i] != '\0'); i++) {
398+
if(buffer[i] == '\n') {
399+
ret = output_newline(output);
400+
} else {
401+
ret = output_char(output, buffer[i]);
402+
}
403+
}
404+
} else {
405+
ret = false;
406+
}
407+
free(buffer);
408+
return ret;
409+
}

0 commit comments

Comments
 (0)