mirror of
https://github.com/nanochess/pretty6502.git
synced 2024-12-09 20:49:22 +00:00
Indents nested preprocessor. Allows label in its own line. Tries to preserve horizontal position of comments.
This commit is contained in:
parent
f6ab2c4942
commit
7de1c549a0
22
LICENSE
Normal file
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
Copyright (c) 2017 Oscar Toledo G. http://nanochess.org/
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
5
README
5
README
@ -13,6 +13,8 @@ Arguments:
|
||||
label: mnemonic operand comment
|
||||
-s1 Code in three columns
|
||||
label: mnemonic+operand comment
|
||||
-p0 Processor unknown.
|
||||
-p1 Processor 6502 + DASM syntax (default)
|
||||
-m8 Start of mnemonic column (default)
|
||||
-o16 Start of operand column (default)
|
||||
-c32 Start of comment column (default)
|
||||
@ -21,6 +23,9 @@ Arguments:
|
||||
-a0 Align comments to nearest column
|
||||
-a1 Comments at line start are aligned
|
||||
to mnemonic (default)
|
||||
-n4 Nesting spacing (can be any number
|
||||
of spaces or multiple of tab size)
|
||||
-l Put labels in its own line
|
||||
|
||||
Assumes all your labels are at start of line and there is space
|
||||
before mnemonic.
|
||||
|
228
pretty6502.c
228
pretty6502.c
@ -6,6 +6,7 @@
|
||||
** © Copyright 2017 Oscar Toledo G.
|
||||
**
|
||||
** Creation date: Nov/03/2017.
|
||||
** Revision date: Nov/06/2017. Processor selection. Indents nested IF/ENDIF. Tries to preserve vertical structure of comments. Allows label in its own line.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -13,9 +14,113 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define VERSION "v0.1"
|
||||
#define VERSION "v0.2"
|
||||
int tabs;
|
||||
|
||||
/*
|
||||
** 6502 mnemonics
|
||||
*/
|
||||
char *mnemonics_6502[] = {
|
||||
"adc", "anc", "and", "ane", "arr", "asl", "asr", "bcc",
|
||||
"bcs", "beq", "bit", "bmi", "bne", "bpl", "brk", "bvc",
|
||||
"bvs", "clc", "cld", "cli", "clv", "cmp", "cpx", "cpy",
|
||||
"dcp", "dec", "dex", "dey", "eor", "inc", "inx", "iny",
|
||||
"isb", "jmp", "jsr", "las", "lax", "lda", "ldx", "ldy",
|
||||
"lsr", "lxa", "nop", "ora", "pha", "php", "pla", "plp",
|
||||
"rla", "rol", "ror", "rra", "rti", "rts", "sax", "sbc",
|
||||
"sbx", "sec", "sed", "sei", "sha", "shs", "shx", "shy",
|
||||
"slo", "sre", "sta", "stx", "sty", "tax", "tay", "tsx",
|
||||
"txa", "txs", "tya", NULL,
|
||||
};
|
||||
|
||||
#define DONT_RELOCATE_LABEL 0x01
|
||||
#define LEVEL_IN 0x02
|
||||
#define LEVEL_OUT 0x04
|
||||
#define LEVEL_MINUS 0x08
|
||||
|
||||
/*
|
||||
** DASM directives
|
||||
*/
|
||||
struct {
|
||||
char *directive;
|
||||
int flags;
|
||||
} directives_dasm[] = {
|
||||
"=", DONT_RELOCATE_LABEL,
|
||||
"align", 0,
|
||||
"byte", 0,
|
||||
"dc", 0,
|
||||
"ds", 0,
|
||||
"dv", 0,
|
||||
"echo", 0,
|
||||
"eif", LEVEL_OUT,
|
||||
"else", LEVEL_MINUS,
|
||||
"end", 0,
|
||||
"endif", LEVEL_OUT,
|
||||
"endm", LEVEL_OUT,
|
||||
"eqm", DONT_RELOCATE_LABEL,
|
||||
"equ", DONT_RELOCATE_LABEL,
|
||||
"err", 0,
|
||||
"hex", 0,
|
||||
"if", LEVEL_IN,
|
||||
"ifconst", LEVEL_IN,
|
||||
"ifnconst", LEVEL_IN,
|
||||
"incbin", 0,
|
||||
"incdir", 0,
|
||||
"include", 0,
|
||||
"list", 0,
|
||||
"long", 0,
|
||||
"mac", LEVEL_IN,
|
||||
"mexit", 0,
|
||||
"org", 0,
|
||||
"processor", 0,
|
||||
"rend", 0,
|
||||
"repeat", LEVEL_IN,
|
||||
"repend", LEVEL_OUT,
|
||||
"rorg", 0,
|
||||
"seg", 0,
|
||||
"set", DONT_RELOCATE_LABEL,
|
||||
"subroutine", DONT_RELOCATE_LABEL,
|
||||
"trace", 0,
|
||||
"word", 0,
|
||||
NULL, 0,
|
||||
};
|
||||
|
||||
/*
|
||||
** Comparison without case
|
||||
*/
|
||||
int memcmpcase(char *p1, char *p2, int size)
|
||||
{
|
||||
while (size--) {
|
||||
if (tolower(*p1) != tolower(*p2))
|
||||
return 1;
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check for opcode or directive
|
||||
*/
|
||||
int check_opcode(char *p1, char *p2)
|
||||
{
|
||||
int c;
|
||||
int length;
|
||||
|
||||
for (c = 0; directives_dasm[c].directive != NULL; c++) {
|
||||
length = strlen(directives_dasm[c].directive);
|
||||
if ((*p1 == '.' && length == p2 - p1 - 1 && memcmpcase(p1 + 1, directives_dasm[c].directive, p2 - p1 - 1) == 0) || (length == p2 - p1 && memcmpcase(p1, directives_dasm[c].directive, p2 - p1) == 0)) {
|
||||
return c + 1;
|
||||
}
|
||||
}
|
||||
for (c = 0; mnemonics_6502[c] != NULL; c++) {
|
||||
length = strlen(mnemonics_6502[c]);
|
||||
if (length == p2 - p1 && memcmpcase(p1, mnemonics_6502[c], p2 - p1) == 0)
|
||||
return -(c + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Request space in line
|
||||
*/
|
||||
@ -55,10 +160,13 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
int style;
|
||||
int processor;
|
||||
int start_mnemonic;
|
||||
int start_operand;
|
||||
int start_comment;
|
||||
int align_comment;
|
||||
int nesting_space;
|
||||
int labels_own_line;
|
||||
FILE *input;
|
||||
FILE *output;
|
||||
int allocation;
|
||||
@ -68,6 +176,10 @@ int main(int argc, char *argv[])
|
||||
char *p2;
|
||||
int current_column;
|
||||
int request;
|
||||
int current_level;
|
||||
int prev_comment_original_location;
|
||||
int prev_comment_final_location;
|
||||
int flags;
|
||||
|
||||
/*
|
||||
** Show usage if less than 3 arguments (program name counts as one)
|
||||
@ -87,6 +199,8 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, " label: mnemonic operand comment\n");
|
||||
fprintf(stderr, " -s1 Code in three columns\n");
|
||||
fprintf(stderr, " label: mnemonic+operand comment\n");
|
||||
fprintf(stderr, " -p0 Processor unknown\n");
|
||||
fprintf(stderr, " -p1 Processor 6502 + DASM syntax (default)\n");
|
||||
fprintf(stderr, " -m8 Start of mnemonic column (default)\n");
|
||||
fprintf(stderr, " -o16 Start of operand column (default)\n");
|
||||
fprintf(stderr, " -c32 Start of comment column (default)\n");
|
||||
@ -95,6 +209,9 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, " -a0 Align comments to nearest column\n");
|
||||
fprintf(stderr, " -a1 Comments at line start are aligned\n");
|
||||
fprintf(stderr, " to mnemonic (default)\n");
|
||||
fprintf(stderr, " -n4 Nesting spacing (can be any number\n");
|
||||
fprintf(stderr, " of spaces or multiple of tab size)\n");
|
||||
fprintf(stderr, " -l Puts labels in its own line\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Assumes all your labels are at start of line and there is space\n");
|
||||
fprintf(stderr, "before mnemonic.\n");
|
||||
@ -108,11 +225,14 @@ int main(int argc, char *argv[])
|
||||
** Default settings
|
||||
*/
|
||||
style = 0;
|
||||
processor = 1;
|
||||
start_mnemonic = 8;
|
||||
start_operand = 16;
|
||||
start_comment = 32;
|
||||
tabs = 0;
|
||||
align_comment = 1;
|
||||
nesting_space = 4;
|
||||
labels_own_line = 0;
|
||||
|
||||
/*
|
||||
** Process arguments
|
||||
@ -131,6 +251,13 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'p': /* Processor */
|
||||
processor = atoi(&argv[c][2]);
|
||||
if (processor < 0 || processor > 1) {
|
||||
fprintf(stderr, "Bad processor code: %d\n", processor);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'm': /* Mnemonic start */
|
||||
start_mnemonic = atoi(&argv[c][2]);
|
||||
break;
|
||||
@ -150,6 +277,12 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'n': /* Nesting space */
|
||||
nesting_space = atoi(&argv[c][2]);
|
||||
break;
|
||||
case 'l': /* Labels in own line */
|
||||
labels_own_line = 1;
|
||||
break;
|
||||
default: /* Other */
|
||||
fprintf(stderr, "Unknown argument: %c\n", argv[c][1]);
|
||||
exit(1);
|
||||
@ -189,6 +322,10 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, "Operand error: -m%d isn't a multiple of %d\n", start_comment, tabs);
|
||||
exit(1);
|
||||
}
|
||||
if (nesting_space % tabs) {
|
||||
fprintf(stderr, "Operand error: -n%d isn't a multiple of %d\n", nesting_space, tabs);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -250,29 +387,62 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, "Unable to open output file: %s\n", argv[c]);
|
||||
exit(1);
|
||||
}
|
||||
prev_comment_original_location = 0;
|
||||
prev_comment_final_location = 0;
|
||||
current_level = 0;
|
||||
p = data;
|
||||
while (p < data + allocation) {
|
||||
current_column = 0;
|
||||
p1 = p;
|
||||
if (*p1 && !isspace(*p1) && *p1 != ';') { /* Label */
|
||||
while (*p1 && !isspace(*p1) && *p1 != ';')
|
||||
p1++;
|
||||
fwrite(p, sizeof(char), p1 - p, output);
|
||||
current_column = p1 - p;
|
||||
p2 = p1;
|
||||
while (*p2 && !isspace(*p2) && *p2 != ';')
|
||||
p2++;
|
||||
if (p2 - p1) { /* Label */
|
||||
fwrite(p1, sizeof(char), p2 - p1, output);
|
||||
current_column = p2 - p1;
|
||||
p1 = p2;
|
||||
} else {
|
||||
current_column = 0;
|
||||
}
|
||||
while (*p1 && isspace(*p1))
|
||||
p1++;
|
||||
flags = 0;
|
||||
if (*p1 && *p1 != ';') { /* Mnemonic */
|
||||
if (*p1 == '=')
|
||||
request = start_operand;
|
||||
else
|
||||
request = start_mnemonic;
|
||||
request_space(output, ¤t_column, request, 1);
|
||||
p2 = p1;
|
||||
while (*p2 && !isspace(*p2))
|
||||
while (*p2 && !isspace(*p2) && *p2 != ';')
|
||||
p2++;
|
||||
if (processor == 1) {
|
||||
c = check_opcode(p1, p2);
|
||||
if (c == 0) {
|
||||
request = start_mnemonic;
|
||||
} else if (c < 0) {
|
||||
request = start_mnemonic;
|
||||
} else {
|
||||
flags = directives_dasm[c - 1].flags;
|
||||
if (flags & DONT_RELOCATE_LABEL)
|
||||
request = start_operand;
|
||||
else
|
||||
request = start_mnemonic;
|
||||
}
|
||||
} else {
|
||||
request = start_mnemonic;
|
||||
}
|
||||
|
||||
/*
|
||||
** Move label to own line
|
||||
*/
|
||||
if (current_column != 0 && labels_own_line != 0 && (flags & DONT_RELOCATE_LABEL) == 0) {
|
||||
fputc('\n', output);
|
||||
current_column = 0;
|
||||
}
|
||||
if (flags & LEVEL_OUT) {
|
||||
if (current_level > 0)
|
||||
current_level--;
|
||||
}
|
||||
request += current_level * nesting_space;
|
||||
if (flags & LEVEL_MINUS)
|
||||
request -= nesting_space;
|
||||
request_space(output, ¤t_column, request, 1);
|
||||
fwrite(p1, sizeof(char), p2 - p1, output);
|
||||
current_column += p2 - p1;
|
||||
p1 = p2;
|
||||
@ -280,6 +450,7 @@ int main(int argc, char *argv[])
|
||||
p1++;
|
||||
if (*p1 && *p1 != ';') { /* Operand */
|
||||
request = start_operand;
|
||||
request += current_level * nesting_space;
|
||||
request_space(output, ¤t_column, request, 1);
|
||||
p2 = p1;
|
||||
while (*p2 && *p2 != ';') {
|
||||
@ -305,16 +476,33 @@ int main(int argc, char *argv[])
|
||||
while (*p1 && isspace(*p1))
|
||||
p1++;
|
||||
}
|
||||
if (flags & LEVEL_IN) {
|
||||
current_level++;
|
||||
}
|
||||
}
|
||||
if (*p1 == ';') { /* Comment */
|
||||
if (current_column == 0)
|
||||
request = 0;
|
||||
else if (current_column < start_mnemonic)
|
||||
request = start_mnemonic;
|
||||
else
|
||||
request = start_comment;
|
||||
if (current_column == 0 && align_comment == 1)
|
||||
request = start_mnemonic;
|
||||
|
||||
/*
|
||||
** Try to keep comments horizontally aligned (only works
|
||||
** if spaces were used in source file)
|
||||
*/
|
||||
p2 = p1;
|
||||
while (p2 - 1 >= p && isspace(*(p2 - 1)))
|
||||
p2--;
|
||||
if (p2 == p && p1 - p == prev_comment_original_location) {
|
||||
request = prev_comment_final_location;
|
||||
} else {
|
||||
prev_comment_original_location = p1 - p;
|
||||
if (current_column == 0)
|
||||
request = 0;
|
||||
else if (current_column < start_mnemonic)
|
||||
request = start_mnemonic;
|
||||
else
|
||||
request = start_comment;
|
||||
if (current_column == 0 && align_comment == 1)
|
||||
request = start_mnemonic;
|
||||
prev_comment_final_location = request;
|
||||
}
|
||||
request_space(output, ¤t_column, request, 0);
|
||||
p2 = p1;
|
||||
while (*p2)
|
||||
|
Loading…
Reference in New Issue
Block a user