/*-------------------------------------------------------------------*/ /* 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 #include #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; } }