aboutsummaryrefslogtreecommitdiff
path: root/renumbas.c
diff options
context:
space:
mode:
Diffstat (limited to 'renumbas.c')
-rw-r--r--renumbas.c141
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;
+}