|
- /*-------------------------------------------------------------------*/
- /* 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 <stdlib.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];
-
- int 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 + 64];
- FILE *fdin;
- FILE *fdout;
- int skip, bp, temp, getout, disp_msg;
-
- f = 1;
-
- printf("Version 12/13/2019\n");
-
- if (argc > 1) strcpy(pstr, argv[1]);
- else
- {
- printf("Program in file? ");
- fgets(pstr,MAX_LINE_LENGTH, stdin);
- if (strchr(pstr, '\n') != NULL)
- {
- pstr[strlen(pstr)-1] = '\0';
- }
-
- }
- 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 temporary file editfl for output\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? N or n cancels:");
- fgets(pstr,MAX_LINE_LENGTH,stdin);
- v1 = 0;
- if (strcmp(midstr2(pstr, 1, 1), "N") == 0) v1 = 1;
- if (strcmp(midstr2(pstr, 1, 1), "n") == 0) v1 = 1;
-
- if (v1 == 1) {
- printf("Operation cancelled\n");
- exit(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__) && !defined(MSDOS)
- tempstr[strlen(tempstr)] = '\0';
- sprintf(tempstr, "cp editfl %s", f9str);
- system(tempstr);
- #endif
- #if defined(MSDOS)
- tempstr[strlen(tempstr)] = '\0';
- sprintf(tempstr, "copy editfl %s", 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)
- {
- rstr[strlen(rstr)] = '\0';
- sprintf(rstr, "%d", sidx[m][1]);
- x = 0;
- return;
- }
-
- if (m == f5 || m == l5)
- {
- x = 1;
- return;
- }
-
- if (sidx[m][0] < n)
- f5 = m;
- else
- l5 = m;
- }
- }
|