ChipMaster's bwBASIC This also includes history going back to v2.10. *WARN* some binary files might have been corrupted by CRLF.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

609 lines
16 KiB

  1. /*-------------------------------------------------------------------*/
  2. /* renum.c -- Renumbers a BASIC program in an ASCII file. */
  3. /* Originally written in HP 2000 BASIC by David Lance Robinson, 1977 */
  4. /* Adapted to MS BASIC and translated to C 4/1995 by Jon B. Volkoff */
  5. /* (eidetics@cerf.net) */
  6. /*-------------------------------------------------------------------*/
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #define MAX_LINE_LENGTH 255
  11. #define MAX_LINE_COUNT 1500
  12. int instr();
  13. char *midstr1();
  14. char *midstr2();
  15. void binary_search(void);
  16. int f2, l2, n, x;
  17. int sidx[MAX_LINE_COUNT][2];
  18. char rstr[MAX_LINE_LENGTH];
  19. int main(argc, argv)
  20. int argc;
  21. char *argv[];
  22. {
  23. int f, d, s, p, s1, t, l, g;
  24. int c, f1, c1, i, f8, r, l1, l3;
  25. int v1, f6, l6, b, f9, x9, b1, p8, p9, a, d9;
  26. char pstr[MAX_LINE_LENGTH];
  27. char sstr[MAX_LINE_LENGTH];
  28. char f9str[MAX_LINE_LENGTH];
  29. char s9str[MAX_LINE_LENGTH];
  30. char tempstr[MAX_LINE_LENGTH + 64];
  31. FILE *fdin;
  32. FILE *fdout;
  33. int skip, bp, temp, getout, disp_msg;
  34. f = 1;
  35. printf("Version 12/13/2019\n");
  36. if (argc > 1) strcpy(pstr, argv[1]);
  37. else
  38. {
  39. printf("Program in file? ");
  40. fgets(pstr,MAX_LINE_LENGTH, stdin);
  41. if (strchr(pstr, '\n') != NULL)
  42. {
  43. pstr[strlen(pstr)-1] = '\0';
  44. }
  45. }
  46. if (strlen(pstr) == 0) strcpy(pstr, "0.doc");
  47. fdin = fopen(pstr, "r");
  48. if (fdin == NULL)
  49. {
  50. printf("Unable to open input file\n");
  51. exit(1);
  52. }
  53. strcpy(f9str, pstr);
  54. #if defined(__MVS__) || defined(__CMS__)
  55. strcpy(pstr, "dd:editfl");
  56. #else
  57. strcpy(pstr, "editfl");
  58. #endif
  59. fdout = fopen(pstr, "w");
  60. if (fdout == NULL)
  61. {
  62. printf("Unable to open temporary file editfl for output\n");
  63. exit(1);
  64. }
  65. /* Main program begins here */
  66. s = 0; l2 = 0; d = 0;
  67. f2 = 10000;
  68. printf ("PLEASE WAIT A FEW SECONDS!\n");
  69. while (fgets(pstr, MAX_LINE_LENGTH, fdin) != NULL)
  70. {
  71. pstr[strlen(pstr) - 1] = '\0';
  72. p = instr(pstr, " ");
  73. if (p != 0 && p <= 5)
  74. {
  75. n = atoi(midstr2(pstr, 1, p));
  76. if (n != 0)
  77. {
  78. s++;
  79. if( s < MAX_LINE_COUNT )
  80. {
  81. /* OK */
  82. }
  83. else
  84. {
  85. printf("Too many lines\n");
  86. exit(1);
  87. }
  88. sidx[s][0] = n;
  89. s1 = s;
  90. while (s1 >= 2)
  91. {
  92. s1--;
  93. if (sidx[s1][0] < sidx[s1 + 1][0]) break;
  94. if (sidx[s1][0] == sidx[s1 + 1][0])
  95. {
  96. printf("ERROR !!! MORE THAN ONE STATEMENT FOR A ");
  97. printf("STATEMENT NUMBER\n");
  98. exit(1);
  99. }
  100. t = sidx[s1][0];
  101. sidx[s1][0] = sidx[s1 + 1][0];
  102. sidx[s1 + 1][0] = t;
  103. }
  104. }
  105. }
  106. }
  107. fclose(fdin);
  108. strcpy(pstr, "");
  109. if (s == 0)
  110. {
  111. printf("NO PROGRAM IS IN THE FILE!\n");
  112. exit(1);
  113. }
  114. for (l = 1; l <= s; l++)
  115. sidx[l][1] = sidx[l][0];
  116. g = 1;
  117. disp_msg = 1;
  118. /*------------------------------------------------------------------------*/
  119. /* Find out how and what to renumber (using HP BASIC renumber parameters) */
  120. /* MS BASIC renumber is: RENUM (newnum) (,(oldnum) (,increment)) */
  121. /*------------------------------------------------------------------------*/
  122. while(1)
  123. {
  124. if (disp_msg == 1)
  125. {
  126. printf("RENUMBER (-starting number (,interval (,first statement ");
  127. printf("(,last))))\n");
  128. disp_msg = 0;
  129. }
  130. skip = 0;
  131. bp = 0;
  132. printf("RENUMBER-");
  133. fgets(pstr,MAX_LINE_LENGTH,stdin);
  134. p = strlen(pstr);
  135. if (g == 0)
  136. {
  137. if (strlen(pstr) == 0) break;
  138. if (p == 0) skip = 1;
  139. else
  140. {
  141. t = atoi(midstr2(pstr, 1, 1));
  142. if (t == 0) break;
  143. }
  144. }
  145. if (strlen(pstr) == 0) skip = 1;
  146. if (skip == 0)
  147. {
  148. c = instr(pstr, ",");
  149. temp = 0; if (c != 0) temp = -1;
  150. f1 = atoi(midstr2(pstr, 1, p + temp*(p - c + 1)));
  151. if (f1 == 0) bp = 1;
  152. if (c == 0) skip = 2;
  153. }
  154. if (skip == 0 && bp == 0)
  155. {
  156. c1 = instr(midstr1(pstr, c + 1), ",") + c;
  157. temp = 0; if (c1 != c) temp = -1;
  158. i = atoi(midstr2(pstr, c + 1, p + temp*(p - c1 + 1) - c));
  159. if (i == 0) bp = 1;
  160. if (c1 == c) skip = 3;
  161. }
  162. if (skip == 0 && bp == 0)
  163. {
  164. c = instr(midstr1(pstr, c1 + 1), ",") + c1;
  165. temp = 0; if (c != c1) temp = -1;
  166. f8 = atoi(midstr2(pstr, c1 + 1, p + temp*(p - c + 1) - c1));
  167. if (f8 == 0) bp = 1;
  168. if (c == c1) skip = 4;
  169. }
  170. if (skip == 0 && bp == 0)
  171. {
  172. l = atoi(midstr1(pstr, c + 1));
  173. if (l == 0) bp = 1;
  174. }
  175. if (bp == 0) switch (skip)
  176. {
  177. case 1:
  178. f1 = 10;
  179. i = 10;
  180. f8 = 1;
  181. l = 99999;
  182. break;
  183. case 2:
  184. i = 10;
  185. f8 = 1;
  186. l = 99999;
  187. break;
  188. case 3:
  189. f8 = 1;
  190. l = 99999;
  191. break;
  192. case 4:
  193. l = 99999;
  194. break;
  195. }
  196. if (f1 < 1 || i == 0 || f8 < 1 || l < 1) bp = 1;
  197. if (f1 > 99999 || i > 99999 || f8 > 99999 || l > 99999 || f8 > l)
  198. bp = 1;
  199. c = 0;
  200. for (r = 1; r <= s; r++)
  201. if (sidx[r][0] >= f8 && sidx[r][0] <= l) c = c + 1;
  202. if (c == 0)
  203. {
  204. printf("There is nothing to renumber !!\n");
  205. disp_msg = 1;
  206. }
  207. /*------------------------------------*/
  208. /* Make list of new statement numbers */
  209. /*------------------------------------*/
  210. l1 = f1 + (c - 1)*i;
  211. if (l1 < 1 || l1 > 99999) bp = 1;
  212. x = 0; c = 0;
  213. if (bp == 0 && disp_msg == 0) for (r = 1; r <= s; r++)
  214. {
  215. if (sidx[r][0] < f8 || sidx[r][0] > l)
  216. if (sidx[r][1] >= f1 && sidx[r][1] <= l1)
  217. {
  218. printf("SEQUENCE NUMBER OVERLAP\n");
  219. exit(1);
  220. }
  221. else {}
  222. else
  223. {
  224. if (sidx[r][0] != f1 + c*i)
  225. {
  226. if (x == 0)
  227. {
  228. if (r < f2) f2 = r;
  229. x = 1;
  230. }
  231. if (r > l2) l2 = r;
  232. }
  233. sidx[r][1] = f1 + c*i;
  234. c++;
  235. l3 = r;
  236. }
  237. }
  238. if (bp == 0 && disp_msg == 0) g = 0;
  239. if (bp == 1) printf("BAD PARAMETER\n");
  240. }
  241. /*-------------------*/
  242. /* Start renumbering */
  243. /*-------------------*/
  244. if (l2 == 0)
  245. {
  246. printf("NOTHING RENUMBERED!\n");
  247. exit(1);
  248. }
  249. printf("RENUMBERING\n");
  250. /*
  251. for (r = 1; r <= s; r ++)
  252. printf("%d -> %d\n", sidx[r][0], sidx[r][1]);
  253. */
  254. printf("VERIFY? N or n cancels:");
  255. fgets(pstr,MAX_LINE_LENGTH,stdin);
  256. v1 = 0;
  257. if (strcmp(midstr2(pstr, 1, 1), "N") == 0) v1 = 1;
  258. if (strcmp(midstr2(pstr, 1, 1), "n") == 0) v1 = 1;
  259. if (v1 == 1) {
  260. printf("Operation cancelled\n");
  261. exit(1);
  262. }
  263. fdin = fopen(f9str, "r");
  264. if (fdin == NULL)
  265. {
  266. printf("Unable to open input file\n");
  267. exit(1);
  268. }
  269. f6 = sidx[f2][0];
  270. l6 = sidx[l2][0];
  271. while (fgets(pstr, MAX_LINE_LENGTH, fdin) != NULL)
  272. {
  273. pstr[strlen(pstr) - 1] = '\0';
  274. b = instr(pstr, " ");
  275. if (b != 0)
  276. {
  277. n = atoi(midstr2(pstr, 1, b));
  278. if (n != 0)
  279. {
  280. if (n >= f6 && n <= l6)
  281. {
  282. binary_search();
  283. if (x == 0)
  284. {
  285. strcat(rstr, midstr1(pstr, b));
  286. strcpy(pstr, rstr);
  287. b = instr(pstr, " ");
  288. }
  289. }
  290. b++;
  291. /*-------------------------------------------------------------*/
  292. /* There are differences, of course, between processing for HP */
  293. /* BASIC and MS BASIC. */
  294. /* */
  295. /* CONVERT, PRINT USING, and MAT PRINT USING changes are not */
  296. /* applicable in MS BASIC. */
  297. /* */
  298. /* Had to also add capability for multiple statements here. */
  299. /*-------------------------------------------------------------*/
  300. while(1)
  301. {
  302. if (strcmp(midstr2(pstr, b, 3), "REM") == 0 ||
  303. strcmp(midstr2(pstr, b, 1), "'") == 0) break;
  304. f9 = 0;
  305. skip = 0;
  306. for (x9 = b; x9 <= strlen(pstr); x9++)
  307. {
  308. if ((char)(*midstr2(pstr, x9, 1)) == 34)
  309. {
  310. if (f9 == 0)
  311. f9 = 1;
  312. else
  313. f9 = 0;
  314. }
  315. else if (strcmp(midstr2(pstr, x9, 1), ":") == 0 &&
  316. f9 == 0)
  317. {
  318. b1 = x9 - 1;
  319. skip = 1;
  320. break;
  321. }
  322. }
  323. if (skip == 0) b1 = strlen(pstr);
  324. t = instr("GOSGOTIF ON RESRET", midstr2(pstr, b, 3));
  325. temp = (t + 5)/3;
  326. if (temp != 1)
  327. {
  328. if (temp == 2 || temp == 3 || temp == 4 || temp == 6 ||
  329. temp == 7)
  330. {
  331. /*-------------------------------------------------*/
  332. /* Change GOSUB, GOTO, IF, RESTORE, RESUME, RETURN */
  333. /* routine. */
  334. /* Go word by word through the statement. */
  335. /*-------------------------------------------------*/
  336. getout = 0;
  337. p8 = b;
  338. strcpy(s9str, " ");
  339. }
  340. else if (temp == 5)
  341. {
  342. /*---------------------------------------------------*/
  343. /* Change ON event/expression GOSUB/GOTO routine. */
  344. /* Find starting point appropriate to this statement */
  345. /* type. */
  346. /*---------------------------------------------------*/
  347. getout = 1;
  348. for (x9 = b1; x9 >= b; x9--)
  349. {
  350. if (strcmp(midstr2(pstr, x9, 1), " ") == 0)
  351. {
  352. p8 = x9 + 1;
  353. getout = 0;
  354. break;
  355. }
  356. }
  357. if (getout == 0) strcpy(s9str, ",");
  358. }
  359. /* Start looping here */
  360. if (getout == 0) while(1)
  361. {
  362. f9 = 0;
  363. skip = 0;
  364. for (x9 = p8; x9 <= b1; x9++)
  365. {
  366. if ((char)(*midstr2(pstr, x9, 1)) == 34)
  367. {
  368. if (f9 == 0)
  369. f9 = 1;
  370. else
  371. f9 = 0;
  372. }
  373. else if (strcmp(midstr2(pstr, x9, 1), s9str) == 0 &&
  374. f9 == 0)
  375. {
  376. p9 = x9 - 1;
  377. skip = 1;
  378. break;
  379. }
  380. }
  381. if (skip == 0) p9 = b1;
  382. skip = 0;
  383. for (x9 = p8; x9 <= p9; x9++)
  384. {
  385. a = (char)(*midstr2(pstr, x9, 1));
  386. if (a < 48 || a > 57)
  387. {
  388. skip = 1;
  389. break;
  390. }
  391. }
  392. if (skip == 0)
  393. {
  394. /*---------------------*/
  395. /* Found a line number */
  396. /*---------------------*/
  397. n = atoi(midstr2(pstr, p8, p9 - p8 + 1));
  398. if (n != 0)
  399. {
  400. if (n >= f6 && n <= l6)
  401. {
  402. binary_search();
  403. if (x == 0)
  404. {
  405. if (p9 == strlen(pstr))
  406. {
  407. strcpy(tempstr, midstr2(pstr, 1, p8 - 1));
  408. strcat(tempstr, rstr);
  409. strcpy(pstr, tempstr);
  410. }
  411. else
  412. {
  413. strcpy(tempstr, midstr2(pstr, 1, p8 - 1));
  414. strcat(tempstr, rstr);
  415. strcat(tempstr, midstr1(pstr, p9 + 1));
  416. strcpy(pstr, tempstr);
  417. }
  418. /*-----------------------------------*/
  419. /* Adjust indices to account for new */
  420. /* substring length, if any. */
  421. /*-----------------------------------*/
  422. d9 = strlen(rstr) - (p9 - p8 + 1);
  423. p9 = p9 + d9;
  424. b1 = b1 + d9;
  425. }
  426. }
  427. }
  428. }
  429. p8 = p9 + 2;
  430. if (p8 > b1) break;
  431. }
  432. }
  433. /*--------------------------------------------------*/
  434. /* No more words to process in the statement, go to */
  435. /* next statement. */
  436. /*--------------------------------------------------*/
  437. if (b1 == strlen(pstr)) break;
  438. b = b1 + 2;
  439. }
  440. }
  441. }
  442. fprintf(fdout, "%s\n", pstr);
  443. if (v1 == 0) printf("%s\n", pstr);
  444. }
  445. fclose(fdin);
  446. fclose(fdout);
  447. #if !defined(__MVS__) && !defined(__CMS__) && !defined(MSDOS)
  448. tempstr[strlen(tempstr)] = '\0';
  449. sprintf(tempstr, "cp editfl %s", f9str);
  450. system(tempstr);
  451. #endif
  452. #if defined(MSDOS)
  453. tempstr[strlen(tempstr)] = '\0';
  454. sprintf(tempstr, "copy editfl %s", f9str);
  455. system(tempstr);
  456. #endif
  457. return (0);
  458. }
  459. int instr(astr, bstr)
  460. char *astr, *bstr;
  461. {
  462. char *p;
  463. int q;
  464. p = strstr(astr, bstr);
  465. if (p == NULL)
  466. {
  467. q = 0;
  468. }
  469. else
  470. {
  471. q = (p - astr) + 1;
  472. }
  473. return q;
  474. }
  475. char *midstr1(astr, start)
  476. char *astr;
  477. int start;
  478. {
  479. static char tempstr[MAX_LINE_LENGTH];
  480. char *startptr;
  481. strcpy(tempstr, astr);
  482. startptr = (char *)((long)(tempstr) + start - 1);
  483. return startptr;
  484. }
  485. char *midstr2(astr, start, len)
  486. char *astr;
  487. int start, len;
  488. {
  489. static char tempstr[MAX_LINE_LENGTH];
  490. char *startptr, *endptr;
  491. strcpy(tempstr, astr);
  492. startptr = (char *)((long)(tempstr) + start - 1);
  493. endptr = (char *)((long)(tempstr) + start + len - 1);
  494. strcpy(endptr, "\0");
  495. return startptr;
  496. }
  497. void binary_search(void)
  498. {
  499. int f5, l5;
  500. f5 = f2;
  501. l5 = l2 + 1;
  502. while(1)
  503. {
  504. int m;
  505. m = (f5 + l5)/2;
  506. if (sidx[m][0] == n)
  507. {
  508. rstr[strlen(rstr)] = '\0';
  509. sprintf(rstr, "%d", sidx[m][1]);
  510. x = 0;
  511. return;
  512. }
  513. if (m == f5 || m == l5)
  514. {
  515. x = 1;
  516. return;
  517. }
  518. if (sidx[m][0] < n)
  519. f5 = m;
  520. else
  521. l5 = m;
  522. }
  523. }