Indents nested preprocessor. Allows label in its own line. Tries to preserve horizontal position of comments.

This commit is contained in:
nanochess 2017-11-06 13:28:48 -06:00
parent f6ab2c4942
commit 7de1c549a0
3 changed files with 235 additions and 20 deletions

22
LICENSE Normal file
View 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
View File

@ -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.

View File

@ -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, &current_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, &current_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, &current_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, &current_column, request, 0);
p2 = p1;
while (*p2)