diff options
Diffstat (limited to 'renumbas.c')
-rw-r--r-- | renumbas.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/renumbas.c b/renumbas.c new file mode 100644 index 0000000..6f4f51e --- /dev/null +++ b/renumbas.c @@ -0,0 +1,141 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <time.h> + +#include "bas.h" +#include "bcdfp.h" +#include "linetab.h" + +unsigned short startlineno = 10; +unsigned short increment = 10; +unsigned short limit = 0; +unsigned short newno; +int backwards = 0; + +void print_help(void) { + printf("Usage: %s [-v] [-s start-lineno] [-i increment] [-f first-lineno] <inputfile> <outputfile>\n", self); + printf(" -v: Verbose.\n"); + printf(" -s <num>: Starting line number (default: 10).\n"); + printf(" -i <num>: Increment (default: 10).\n"); + printf(" -f <num>: Don't renumber lines less than <num> (default: 0).\n"); + printf(" -b: Number backwards (creates invalid program).\n"); +} + +unsigned short getlineno(char opt, const char *arg) { + int lineno; + char *e; + + lineno = (int)strtol(arg, &e, 10); + + if(*e) { + fprintf(stderr, "%s: Invalid line number for -%c option: %s is not a number.\n", + self, opt, arg); + exit(1); + } + + if(lineno < 0 || lineno > 32767) { + fprintf(stderr, "%s: Invalid line number for -%c option: %d > 32767.\n", + self, opt, lineno); + exit(1); + } + + return ((unsigned short)lineno); +} + +void parse_args(int argc, char **argv) { + int opt; + + while( (opt = getopt(argc, argv, "vbs:i:f:")) != -1) { + switch(opt) { + case 'v': verbose = 1; break; + case 'b': backwards = 1; break; + case 's': startlineno = getlineno(opt, optarg); break; + case 'i': increment = getlineno(opt, optarg); break; + case 'f': limit = getlineno(opt, optarg); break; + default: + print_help(); + exit(1); + } + } + + if(optind >= argc) + die("No input file given (use - for stdin)."); + else + open_input(argv[optind]); + + if(++optind >= argc) + die("No output file given (use - for stdout)."); + else + output_filename = argv[optind]; +} + +CALLBACK(renumber_line) { + int i; + unsigned char fpnewno[6]; + + if(lineno < limit || lineno == 32768) return; + if(newno >= 32768) { + fprintf(stderr, "%s: Fatal: New line number %d would be >32767.\n", self, newno); + exit(1); + } + + if(verbose) + fprintf(stderr, "Renumbering line %d as %d (%d refs).\n", lineno, newno, refcounts[lineno]); + + int2fp(newno, fpnewno); + for(i = 0; i < refcounts[lineno]; i++) + memmove(program + linerefs[lineno][i].pos, fpnewno, 6); + setword(pos, newno); + + if(backwards) { + if(newno < increment) { + fprintf(stderr, "%s: Fatal: New line number %d would be <0.\n", self, newno); + exit(1); + } else { + newno -= increment; + } + } else { + newno += increment; + } +} + +void check_refs(void) { + int i, j; + + for(i = 0; i < 32768; i++) { + if(refcounts[i] && !lines_exist[i]) { + for(j = 0; j < refcounts[i]; j++) { + fprintf(stderr, "%s: Warning: Line %d references nonexistent line %d.\n", + self, linerefs[i][j].lineno, i); + } + } + } +} + +void renumber(void) { + check_refs(); + newno = startlineno; + on_start_line = renumber_line; + walk_all_code(); +} + +int main(int argc, char **argv) { + set_self(*argv); + parse_general_args(argc, argv, print_help); + parse_args(argc, argv); + + readfile(); + parse_header(); + + build_ref_table(); + renumber(); + free_ref_table(); + + open_output(output_filename); + writefile(); + + return 0; +} |