From e90d6413c1d6b5f8dab658488addf89d946489fe Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Thu, 31 Aug 2017 19:04:42 -0700 Subject: [PATCH] first version --- radius.rb | 243 +++++++++++++++++++++++++++++++++++++++++++++++++++++ readme.txt | 24 ++++++ 2 files changed, 267 insertions(+) create mode 100644 radius.rb create mode 100644 readme.txt diff --git a/radius.rb b/radius.rb new file mode 100644 index 0000000..b65b5b4 --- /dev/null +++ b/radius.rb @@ -0,0 +1,243 @@ +####################################################################### +# RADIUS # +# Really, Another Developer Indentation Utility Software? # +# (c) 2017 Dagen Brock # +# # +# Hats off to people who make real dev tools like: # +# https://www.brutaldeluxe.fr/products/crossdevtools/cadius/ # +####################################################################### + +# params/defaults +mnemonic_col_x = 18 +operand_col_x = 24 +comment_col_x = 48 +min_space = 1 +bump_space = 2 +indent_semi = true +indent_ast = false +std_out = false + +def print_help() + puts "\nradius.rb [-h] [-c0 nn] [-c1 nn] [-c2 nn] filename.\n " + puts " -h : help" + puts " -c0 : column 0 indent (start of opcode column)" + puts " -c1 : column 1 indent (start of operand column)" + puts " -c2 : column 2 indent (start of comment column)" + puts " -s : redirect to standard out only (default overwrites source file)" + puts "\n\n" +end + +# must at least have filename +if ARGV.length == 0 + print_help() + exit +end + + +# load file +infile = false +skip_parm = false +for i in 0..ARGV.length-1 + if skip_parm + skip_parm = false + next + end + + arg = ARGV[i] + if arg[0] == "-" + case arg + when "-h" + print_help() + exit + when "-s" + std_out = true + when "-c0" + mnemonic_col_x = ARGV[i+1].to_i + skip_parm = true + when "-c1" + operand_col_x = ARGV[i+1].to_i + skip_parm = true + when "-c2" + comment_col_x = ARGV[i+1].to_i + skip_parm = true + end + + else + if infile == false + infile = arg + end + end + +end + +#puts "opening #{infile}" +file = File.open(infile, "rb") +source_contents = file.read +file.close unless file.nil? + +# begin line-by-line processing +output_buf = "" +source_contents.each_line do |line| + # state machine - resets each line + in_quote = false + in_comment = false + label_done = false + in_label = false + opcode_done = false + in_opcode = false + operand_done = false + in_operand = false + chars_started = false + quote_char = false + x=0 + + buf = "" # line buffer, starts empty each line and is appended to output_buf + + # begin char-by-char processing + line.each_char.with_index(0) do |c, i| + + # starts with whitespace? do an indent + if i == 0 && c.strip.empty? + buf << " "*mnemonic_col_x # optimize? + x+=mnemonic_col_x + label_done = true + next # SHORT CIRCUIT + end + + # are we in a comment? just print the char + if in_comment + # don't print embedded newline :P + if !c.include?("\n") + buf << c + x+=1 + end + next # SHORT CIRCUIT + end + + # are we in a quote? print, but also look for matching end quote + if in_quote + ##print c + buf << c + x+=1 + if c == quote_char # second quotes + in_quote = false + end + next # SHORT CIRCUIT + end + + # not already in comment or quote + if c.strip.empty? + #ignore + if in_label + in_label = false + label_done = true + # do we need to bump out space + if x > mnemonic_col_x-min_space + buf << " "*min_space # optimize? + x+=min_space + else + buf << " "*(mnemonic_col_x-x) # optimize ? + x+=mnemonic_col_x-x + end + elsif in_opcode + in_opcode = false + opcode_done = true + # do we need to bump out space + if x > operand_col_x-min_space + buf << " "*min_space + x+=min_space + else + buf << " "*(operand_col_x-x) + x+=operand_col_x-x + end + elsif in_operand + in_operand = false + operand_done = true + # do we need to bump out space + if x > comment_col_x-min_space + buf << " "*min_space + x+=min_space + else + buf << " "*(comment_col_x-x) + x+=comment_col_x-x + end + end + + + next + else + chars_started = true + # see if we are starting a quote + if c == '"' || c == "'" + quote_char = c + in_quote = true + buf << c + # see if we are starting a line with a comment + elsif (c == ';' || c == '*') && i == 0 + in_comment = true + buf << c + x+=1 + # found a semi-colon not in an operand (macro!danger) + # (and not in quote or comment) + elsif c == ';' && !in_operand + in_comment = true + buf << " "*(comment_col_x-x) + x+=comment_col_x-x + buf << c + x+=1 + # found asterisk preceded only by whitespace + elsif c == '*' && line[0..i-1].strip.empty? + in_comment = true + buf << c + x+=1 + # real label! + elsif i == 0 + buf << "" + in_label = true + buf << c + x+=1 + # already in label? + elsif in_label + buf << c + x+=1 + # real opcode! + elsif label_done && !opcode_done + in_opcode = true + buf << c + x+=1 + # already in opcode + elsif in_opcode + buf << c + x+=1 + # real operand! + elsif opcode_done && !operand_done + in_operand = true + buf << c + x+=1 + # already in operand + elsif in_operand + buf << c + x+=1 + end + end + end + + # move line to buffer, stripping trailing spaces + output_buf << buf.rstrip << "\n" +end + +# see if output matches input as far as characters +is_error = output_buf.gsub(/\s+/, "") != source_contents.gsub(/\s+/, "") +if is_error + #puts output_buf.gsub(/\s+/, "") + #puts source_contents.gsub(/\s+/, "") + puts "FAILED TO SAFELY INDENT. Aborting... " + puts "** We're really sorry about this. But we didn't want to take a chance corrupting your file." + exit +end + +if std_out + puts output_buf +else + File.open(infile, 'w') { |file| file.write(output_buf) } +end diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..8527cfe --- /dev/null +++ b/readme.txt @@ -0,0 +1,24 @@ +# RADIUS + +### Really, Another Developer Indentation Utility Software? + +Basic useful feature list: + + * Indents Assembly source files + * Supports the idea of set columns that get pushed or bumped to the right + * Balances consistency with sanity for spacing rule + +This is a really quickly thrown together indenter for Merlin32 assembly files (but really all Merlin files and many other formats of 6502 code). I currently use CADIUS, a really much more impressive tool that supports indentation as one feature, but it doesn't let me set my own column widths so I've decided to make my own software to address this. + +Currently, the options allow you to set a column 0, 1 and 2. Those represent the Opcode, Operand and Comment columns respectively. + +## Usage +``` +radius.rb [-h] [-c0 nn] [-c1 nn] [-c2 nn] filename. + + -h : help + -c0 : column 0 indent (start of opcode column) + -c1 : column 1 indent (start of operand column) + -c2 : column 2 indent (start of comment column) + -s : redirect to standard out only (default overwrites source file) +```