diff options
Diffstat (limited to 'renum.c')
-rw-r--r-- | renum.c | 580 |
1 files changed, 580 insertions, 0 deletions
@@ -0,0 +1,580 @@ +/*-------------------------------------------------------------------*/ +/* renum.c -- Renumbers a BASIC program in an ASCII file. */ +/* Originally written in HP 2000 BASIC by David Lance Robinson, 1977 */ +/* Adapted to MS BASIC and translated to C 4/1995 by Jon B. Volkoff */ +/* (eidetics@cerf.net) */ +/*-------------------------------------------------------------------*/ + +#include <stdio.h> +#include <string.h> + +#define MAX_LINE_LENGTH 255 +#define MAX_LINE_COUNT 1500 + +int instr(); +char *midstr1(); +char *midstr2(); +void binary_search(void); + +int f2, l2, n, x; +int sidx[MAX_LINE_COUNT][2]; +char rstr[MAX_LINE_LENGTH]; + +main(argc, argv) + int argc; + char *argv[]; +{ + int f, d, s, p, s1, t, l, g; + int c, f1, c1, i, f8, r, l1, l3; + int v1, f6, l6, b, f9, x9, b1, p8, p9, a, d9; + char pstr[MAX_LINE_LENGTH]; + char sstr[MAX_LINE_LENGTH]; + char f9str[MAX_LINE_LENGTH]; + char s9str[MAX_LINE_LENGTH]; + char tempstr[MAX_LINE_LENGTH]; + FILE *fdin; + FILE *fdout; + int skip, bp, temp, getout, disp_msg; + + f = 1; + + if (argc > 1) strcpy(pstr, argv[1]); + else + { + printf("Program in file? "); + fgets(pstr,MAX_LINE_LENGTH, stdin); + } + if (strlen(pstr) == 0) strcpy(pstr, "0.doc"); + + fdin = fopen(pstr, "r"); + if (fdin == NULL) + { + printf("Unable to open input file\n"); + exit(1); + } + strcpy(f9str, pstr); + +#if defined(__MVS__) || defined(__CMS__) + strcpy(pstr, "dd:editfl"); +#else + strcpy(pstr, "editfl"); +#endif + fdout = fopen(pstr, "w"); + if (fdout == NULL) + { + printf("Unable to open editfl output file\n"); + exit(1); + } + + /* Main program begins here */ + s = 0; l2 = 0; d = 0; + f2 = 10000; + printf ("PLEASE WAIT A FEW SECONDS!\n"); + while (fgets(pstr, MAX_LINE_LENGTH, fdin) != NULL) + { + pstr[strlen(pstr) - 1] = '\0'; + p = instr(pstr, " "); + if (p != 0 && p <= 5) + { + n = atoi(midstr2(pstr, 1, p)); + if (n != 0) + { + s++; + if( s < MAX_LINE_COUNT ) + { + /* OK */ + } + else + { + printf("Too many lines\n"); + exit(1); + } + sidx[s][0] = n; + s1 = s; + while (s1 >= 2) + { + s1--; + if (sidx[s1][0] < sidx[s1 + 1][0]) break; + if (sidx[s1][0] == sidx[s1 + 1][0]) + { + printf("ERROR !!! MORE THAN ONE STATEMENT FOR A "); + printf("STATEMENT NUMBER\n"); + exit(1); + } + + t = sidx[s1][0]; + sidx[s1][0] = sidx[s1 + 1][0]; + sidx[s1 + 1][0] = t; + } + } + } + } + fclose(fdin); + + strcpy(pstr, ""); + + if (s == 0) + { + printf("NO PROGRAM IS IN THE FILE!\n"); + exit(1); + } + + for (l = 1; l <= s; l++) + sidx[l][1] = sidx[l][0]; + g = 1; + disp_msg = 1; + + /*------------------------------------------------------------------------*/ + /* Find out how and what to renumber (using HP BASIC renumber parameters) */ + /* MS BASIC renumber is: RENUM (newnum) (,(oldnum) (,increment)) */ + /*------------------------------------------------------------------------*/ + + while(1) + { + if (disp_msg == 1) + { + printf("RENUMBER (-starting number (,interval (,first statement "); + printf("(,last))))\n"); + disp_msg = 0; + } + + skip = 0; + bp = 0; + printf("RENUMBER-"); + fgets(pstr,MAX_LINE_LENGTH,stdin); + p = strlen(pstr); + + if (g == 0) + { + if (strlen(pstr) == 0) break; + if (p == 0) skip = 1; + else + { + t = atoi(midstr2(pstr, 1, 1)); + if (t == 0) break; + } + } + + if (strlen(pstr) == 0) skip = 1; + + if (skip == 0) + { + c = instr(pstr, ","); + temp = 0; if (c != 0) temp = -1; + f1 = atoi(midstr2(pstr, 1, p + temp*(p - c + 1))); + if (f1 == 0) bp = 1; + if (c == 0) skip = 2; + } + + if (skip == 0 && bp == 0) + { + c1 = instr(midstr1(pstr, c + 1), ",") + c; + temp = 0; if (c1 != c) temp = -1; + i = atoi(midstr2(pstr, c + 1, p + temp*(p - c1 + 1) - c)); + if (i == 0) bp = 1; + if (c1 == c) skip = 3; + } + + if (skip == 0 && bp == 0) + { + c = instr(midstr1(pstr, c1 + 1), ",") + c1; + temp = 0; if (c != c1) temp = -1; + f8 = atoi(midstr2(pstr, c1 + 1, p + temp*(p - c + 1) - c1)); + if (f8 == 0) bp = 1; + if (c == c1) skip = 4; + } + + if (skip == 0 && bp == 0) + { + l = atoi(midstr1(pstr, c + 1)); + if (l == 0) bp = 1; + } + + if (bp == 0) switch (skip) + { + case 1: + f1 = 10; + i = 10; + f8 = 1; + l = 99999; + break; + + case 2: + i = 10; + f8 = 1; + l = 99999; + break; + + case 3: + f8 = 1; + l = 99999; + break; + + case 4: + l = 99999; + break; + } + + if (f1 < 1 || i == 0 || f8 < 1 || l < 1) bp = 1; + + if (f1 > 99999 || i > 99999 || f8 > 99999 || l > 99999 || f8 > l) + bp = 1; + + c = 0; + for (r = 1; r <= s; r++) + if (sidx[r][0] >= f8 && sidx[r][0] <= l) c = c + 1; + if (c == 0) + { + printf("There is nothing to renumber !!\n"); + disp_msg = 1; + } + + /*------------------------------------*/ + /* Make list of new statement numbers */ + /*------------------------------------*/ + + l1 = f1 + (c - 1)*i; + if (l1 < 1 || l1 > 99999) bp = 1; + + x = 0; c = 0; + if (bp == 0 && disp_msg == 0) for (r = 1; r <= s; r++) + { + if (sidx[r][0] < f8 || sidx[r][0] > l) + if (sidx[r][1] >= f1 && sidx[r][1] <= l1) + { + printf("SEQUENCE NUMBER OVERLAP\n"); + exit(1); + } + else {} + else + { + if (sidx[r][0] != f1 + c*i) + { + if (x == 0) + { + if (r < f2) f2 = r; + x = 1; + } + + if (r > l2) l2 = r; + } + + sidx[r][1] = f1 + c*i; + c++; + l3 = r; + } + } + + if (bp == 0 && disp_msg == 0) g = 0; + + if (bp == 1) printf("BAD PARAMETER\n"); + } + + /*-------------------*/ + /* Start renumbering */ + /*-------------------*/ + + if (l2 == 0) + { + printf("NOTHING RENUMBERED!\n"); + exit(1); + } + + printf("RENUMBERING\n"); +/* for (r = 1; r <= s; r ++) + printf("%d -> %d\n", sidx[r][0], sidx[r][1]); */ + + printf("VERIFY? "); + fgets(pstr,MAX_LINE_LENGTH,stdin); + v1 = 0; + if (strcmp(midstr2(pstr, 1, 1), "N") == 0) v1 = 1; + + fdin = fopen(f9str, "r"); + if (fdin == NULL) + { + printf("Unable to open input file\n"); + exit(1); + } + + f6 = sidx[f2][0]; + l6 = sidx[l2][0]; + + while (fgets(pstr, MAX_LINE_LENGTH, fdin) != NULL) + { + pstr[strlen(pstr) - 1] = '\0'; + b = instr(pstr, " "); + if (b != 0) + { + n = atoi(midstr2(pstr, 1, b)); + if (n != 0) + { + if (n >= f6 && n <= l6) + { + binary_search(); + if (x == 0) + { + strcat(rstr, midstr1(pstr, b)); + strcpy(pstr, rstr); + b = instr(pstr, " "); + } + } + b++; + + /*-------------------------------------------------------------*/ + /* There are differences, of course, between processing for HP */ + /* BASIC and MS BASIC. */ + /* */ + /* CONVERT, PRINT USING, and MAT PRINT USING changes are not */ + /* applicable in MS BASIC. */ + /* */ + /* Had to also add capability for multiple statements here. */ + /*-------------------------------------------------------------*/ + + while(1) + { + if (strcmp(midstr2(pstr, b, 3), "REM") == 0 || + strcmp(midstr2(pstr, b, 1), "'") == 0) break; + + f9 = 0; + skip = 0; + for (x9 = b; x9 <= strlen(pstr); x9++) + { + if ((char)(*midstr2(pstr, x9, 1)) == 34) + { + if (f9 == 0) + f9 = 1; + else + f9 = 0; + } + else if (strcmp(midstr2(pstr, x9, 1), ":") == 0 && + f9 == 0) + { + b1 = x9 - 1; + skip = 1; + break; + } + } + if (skip == 0) b1 = strlen(pstr); + + t = instr("GOSGOTIF ON RESRET", midstr2(pstr, b, 3)); + + temp = (t + 5)/3; + if (temp != 1) + { + if (temp == 2 || temp == 3 || temp == 4 || temp == 6 || + temp == 7) + { + /*-------------------------------------------------*/ + /* Change GOSUB, GOTO, IF, RESTORE, RESUME, RETURN */ + /* routine. */ + /* Go word by word through the statement. */ + /*-------------------------------------------------*/ + getout = 0; + p8 = b; + strcpy(s9str, " "); + } + else if (temp == 5) + { + /*---------------------------------------------------*/ + /* Change ON event/expression GOSUB/GOTO routine. */ + /* Find starting point appropriate to this statement */ + /* type. */ + /*---------------------------------------------------*/ + getout = 1; + for (x9 = b1; x9 >= b; x9--) + { + if (strcmp(midstr2(pstr, x9, 1), " ") == 0) + { + p8 = x9 + 1; + getout = 0; + break; + } + } + + if (getout == 0) strcpy(s9str, ","); + } + + /* Start looping here */ + if (getout == 0) while(1) + { + f9 = 0; + skip = 0; + for (x9 = p8; x9 <= b1; x9++) + { + if ((char)(*midstr2(pstr, x9, 1)) == 34) + { + if (f9 == 0) + f9 = 1; + else + f9 = 0; + } + else if (strcmp(midstr2(pstr, x9, 1), s9str) == 0 && + f9 == 0) + { + p9 = x9 - 1; + skip = 1; + break; + } + } + if (skip == 0) p9 = b1; + + skip = 0; + for (x9 = p8; x9 <= p9; x9++) + { + a = (char)(*midstr2(pstr, x9, 1)); + if (a < 48 || a > 57) + { + skip = 1; + break; + } + } + + if (skip == 0) + { + /*---------------------*/ + /* Found a line number */ + /*---------------------*/ + n = atoi(midstr2(pstr, p8, p9 - p8 + 1)); + if (n != 0) + { + if (n >= f6 && n <= l6) + { + binary_search(); + if (x == 0) + { + if (p9 == strlen(pstr)) + { + strcpy(tempstr, midstr2(pstr, 1, p8 - 1)); + strcat(tempstr, rstr); + strcpy(pstr, tempstr); + } + else + { + strcpy(tempstr, midstr2(pstr, 1, p8 - 1)); + strcat(tempstr, rstr); + strcat(tempstr, midstr1(pstr, p9 + 1)); + strcpy(pstr, tempstr); + } + + /*-----------------------------------*/ + /* Adjust indices to account for new */ + /* substring length, if any. */ + /*-----------------------------------*/ + d9 = strlen(rstr) - (p9 - p8 + 1); + p9 = p9 + d9; + b1 = b1 + d9; + } + } + } + } + + p8 = p9 + 2; + if (p8 > b1) break; + } + } + + /*--------------------------------------------------*/ + /* No more words to process in the statement, go to */ + /* next statement. */ + /*--------------------------------------------------*/ + if (b1 == strlen(pstr)) break; + b = b1 + 2; + } + } + } + + fprintf(fdout, "%s\n", pstr); + if (v1 == 0) printf("%s\n", pstr); + } + + fclose(fdin); + fclose(fdout); +#if !defined(__MVS__) && !defined(__CMS__) + sprintf(tempstr, "mv editfl %s\0", f9str); + system(tempstr); +#endif + return (0); +} + + +int instr(astr, bstr) + char *astr, *bstr; +{ + char *p; + int q; + + p = strstr(astr, bstr); + if (p == NULL) + { + q = 0; + } + else + { + q = (p - astr) + 1; + } + return q; +} + + +char *midstr1(astr, start) + char *astr; + int start; +{ + static char tempstr[MAX_LINE_LENGTH]; + char *startptr; + + strcpy(tempstr, astr); + startptr = (char *)((long)(tempstr) + start - 1); + + return startptr; +} + + +char *midstr2(astr, start, len) + char *astr; + int start, len; +{ + static char tempstr[MAX_LINE_LENGTH]; + char *startptr, *endptr; + + strcpy(tempstr, astr); + startptr = (char *)((long)(tempstr) + start - 1); + endptr = (char *)((long)(tempstr) + start + len - 1); + strcpy(endptr, "\0"); + + return startptr; +} + + +void binary_search(void) +{ + int f5, l5; + + f5 = f2; + l5 = l2 + 1; + + while(1) + { + int m; + + m = (f5 + l5)/2; + + if (sidx[m][0] == n) + { + sprintf(rstr, "%d\0", sidx[m][1]); + x = 0; + return; + } + + if (m == f5 || m == l5) + { + x = 1; + return; + } + + if (sidx[m][0] < n) + f5 = m; + else + l5 = m; + } +} |