home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / bwbasic / part09 < prev    next >
Encoding:
Text File  |  1992-11-03  |  37.6 KB  |  1,608 lines

  1. Newsgroups: comp.sources.misc
  2. From: tcamp@acpub.duke.edu (Ted A. Campbell)
  3. Subject:  v33i045:  bwbasic - Bywater BASIC interpreter version 1.10, Part09/11
  4. Message-ID: <1992Nov5.040809.20194@sparky.imd.sterling.com>
  5. X-Md4-Signature: c2855db5f8ffff4b47cc48b8dcefa9e2
  6. Date: Thu, 5 Nov 1992 04:08:09 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: tcamp@acpub.duke.edu (Ted A. Campbell)
  10. Posting-number: Volume 33, Issue 45
  11. Archive-name: bwbasic/part09
  12. Environment: ANSI-C
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  bwb_cmd.c
  19. # Wrapped by kent@sparky on Wed Nov  4 21:34:28 1992
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 9 (of 11)."'
  23. if test -f 'bwb_cmd.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'bwb_cmd.c'\"
  25. else
  26.   echo shar: Extracting \"'bwb_cmd.c'\" \(35201 characters\)
  27.   sed "s/^X//" >'bwb_cmd.c' <<'END_OF_FILE'
  28. X/***************************************************************
  29. X
  30. X        bwb_cmd.c       Miscellaneous Commands
  31. X                        for Bywater BASIC Interpreter
  32. X
  33. X                        Commands:       RUN
  34. X                                        LET
  35. X                                        LOAD
  36. X                                        MERGE
  37. X                                        CHAIN
  38. X                                        NEW
  39. X                                        RENUM
  40. X                                        SAVE
  41. X                                        LIST
  42. X                                        GOTO
  43. X                                        GOSUB
  44. X                                        RETURN
  45. X                                        ON
  46. X                                        STOP
  47. X                                        END
  48. X                                        SYSTEM
  49. X                                        TRON
  50. X                                        TROFF
  51. X                                        DELETE
  52. X                                        RANDOMIZE
  53. X                    ENVIRON
  54. X                                        CMDS            (*debugging)
  55. X
  56. X                        Copyright (c) 1992, Ted A. Campbell
  57. X
  58. X                        Bywater Software
  59. X                        P. O. Box 4023
  60. X                        Duke Station
  61. X                        Durham, NC  27706
  62. X
  63. X                        email: tcamp@acpub.duke.edu
  64. X
  65. X        Copyright and Permissions Information:
  66. X
  67. X        All U.S. and international copyrights are claimed by the
  68. X        author. The author grants permission to use this code
  69. X        and software based on it under the following conditions:
  70. X        (a) in general, the code and software based upon it may be
  71. X        used by individuals and by non-profit organizations; (b) it
  72. X        may also be utilized by governmental agencies in any country,
  73. X        with the exception of military agencies; (c) the code and/or
  74. X        software based upon it may not be sold for a profit without
  75. X        an explicit and specific permission from the author, except
  76. X        that a minimal fee may be charged for media on which it is
  77. X        copied, and for copying and handling; (d) the code must be
  78. X        distributed in the form in which it has been released by the
  79. X        author; and (e) the code and software based upon it may not
  80. X        be used for illegal activities.
  81. X
  82. X***************************************************************/
  83. X
  84. X#include <stdio.h>
  85. X#include <stdlib.h>
  86. X#include <math.h>
  87. X#include <string.h>
  88. X
  89. X#include "bwbasic.h"
  90. X#include "bwb_mes.h"
  91. X
  92. Xstruct gsse *bwb_gss;            /* GOSUB stack */
  93. Xint bwb_gssc = 0;            /* GOSUB stack counter */
  94. Xint err_gosubn = 0;            /* line number for error GOSUB */
  95. X
  96. Xextern struct bwb_line *bwb_xnew( struct bwb_line *l );
  97. Xextern struct bwb_line *bwb_onerror( struct bwb_line *l );
  98. X
  99. X/***************************************************************
  100. X
  101. X        FUNCTION:       bwb_null()
  102. X
  103. X        DESCRIPTION:
  104. X
  105. X***************************************************************/
  106. X
  107. Xstruct bwb_line *
  108. Xbwb_null( struct bwb_line *l )
  109. X   {
  110. X   #if  INTENSIVE_DEBUG
  111. X   sprintf( bwb_ebuf, "in bwb_null(): NULL function: argc = %d", l->argc );
  112. X   bwb_debug( bwb_ebuf );
  113. X   #endif
  114. X   l->next->position = 0;
  115. X   return l->next;
  116. X   }
  117. X
  118. X/***************************************************************
  119. X
  120. X    FUNCTION:       bwb_rem()
  121. X
  122. X        DESCRIPTION:
  123. X
  124. X***************************************************************/
  125. X
  126. Xstruct bwb_line *
  127. Xbwb_rem( struct bwb_line *l )
  128. X   {
  129. X   #if INTENSIVE_DEBUG
  130. X   sprintf( bwb_ebuf, "in bwb_rem(): REM command" );
  131. X   bwb_debug( bwb_ebuf );
  132. X   #endif
  133. X
  134. X   l->position = strlen( l->buffer ) - 1;
  135. X
  136. X   l->next->position = 0;
  137. X   return l->next;
  138. X   }
  139. X
  140. X/***************************************************************
  141. X
  142. X        FUNCTION:       bwb_run()
  143. X
  144. X        DESCRIPTION:
  145. X
  146. X***************************************************************/
  147. X
  148. Xstruct bwb_line *
  149. Xbwb_run( struct bwb_line *l )
  150. X   {
  151. X   struct bwb_line *current, *x;
  152. X   int go_lnumber;                /* line number to go to */
  153. X   register int n;                /* counter */
  154. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  155. X   struct exp_ese *e;
  156. X   FILE *input;
  157. X
  158. X   #if INTENSIVE_DEBUG
  159. X   sprintf( bwb_ebuf, "in bwb_run(): entered function. buffer <%s> pos <%d>",
  160. X      l->buffer, l->position );
  161. X   bwb_debug( bwb_ebuf );
  162. X   #endif
  163. X
  164. X   /* see if there is an element */
  165. X
  166. X   current = NULL;
  167. X   adv_ws( l->buffer, &( l->position ) );
  168. X   #if INTENSIVE_DEBUG
  169. X   sprintf( bwb_ebuf, "in bwb_run(): check buffer <%s> pos <%d> char <0x%x>",
  170. X      l->buffer, l->position, l->buffer[ l->position ] );
  171. X   bwb_debug( bwb_ebuf );
  172. X   #endif
  173. X   switch ( l->buffer[ l->position ] )
  174. X      {
  175. X      case '\0':
  176. X      case '\n':
  177. X      case '\r':
  178. X      case ':':
  179. X         #if INTENSIVE_DEBUG
  180. X         sprintf( bwb_ebuf, "in bwb_run(): no argument; begin at start.next" );
  181. X         bwb_debug( bwb_ebuf );
  182. X         #endif
  183. X         current = bwb_start.next;
  184. X         e = NULL;
  185. X         break;
  186. X      default:
  187. X         e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  188. X         break;
  189. X      }
  190. X
  191. X   /* check its type: if it is a string, open the file and execute it */
  192. X
  193. X   if (( e != NULL ) && ( e->type == STRING ))
  194. X      {
  195. X      bwb_new( l );                /* clear memory */
  196. X      str_btoc( tbuf, exp_getsval( e ) );    /* get string in tbuf */
  197. X      if ( ( input = fopen( tbuf, "r" )) == NULL )    /* open file */
  198. X         {
  199. X         sprintf( bwb_ebuf, err_openfile, tbuf );
  200. X         bwb_error( bwb_ebuf );
  201. X         }
  202. X      bwb_fload( input );        /* load program */
  203. X      bwb_run( &bwb_start );        /* and call bwb_run() recursively */
  204. X      }
  205. X
  206. X   /* else if it is a line number, execute the progrm in memory
  207. X      at that line number */
  208. X   else
  209. X      {
  210. X
  211. X      if ( current == NULL )
  212. X         {
  213. X
  214. X         if ( e != NULL )
  215. X            {
  216. X            go_lnumber = exp_getival( e );
  217. X            }
  218. X
  219. X         #if INTENSIVE_DEBUG
  220. X         sprintf( bwb_ebuf, "in bwb_run(): element detected <%s>, lnumber <%d>",
  221. X            tbuf, go_lnumber );
  222. X         bwb_debug( bwb_ebuf );
  223. X         #endif
  224. X
  225. X         for ( x = bwb_start.next; x != &bwb_end; x = x->next )
  226. X            {
  227. X            if ( x->number == go_lnumber )
  228. X               {
  229. X               current = x;
  230. X               }
  231. X            }
  232. X         }
  233. X
  234. X      if ( current == NULL )
  235. X         {
  236. X         sprintf( bwb_ebuf, err_lnnotfound, go_lnumber );
  237. X         bwb_error( bwb_ebuf );
  238. X         return &bwb_end;
  239. X         }
  240. X
  241. X      #if INTENSIVE_DEBUG
  242. X      sprintf( bwb_ebuf, "in bwb_run(): ready to call do-while loop at line %d",
  243. X         current->number );
  244. X      bwb_debug( bwb_ebuf );
  245. X      #endif
  246. X
  247. X      current->position = 0;
  248. X
  249. X      while ( current != &bwb_end )
  250. X         {
  251. X         current = bwb_xline( current );
  252. X         }
  253. X
  254. X      }
  255. X
  256. X   #if INTENSIVE_DEBUG
  257. X   sprintf( bwb_ebuf, "in bwb_run(): function complete." );
  258. X   bwb_debug( bwb_ebuf );
  259. X   #endif
  260. X
  261. X   return &bwb_end;
  262. X
  263. X   }
  264. X
  265. X/***************************************************************
  266. X
  267. X        FUNCTION:       bwb_let()
  268. X
  269. X        DESCRIPTION:
  270. X
  271. X***************************************************************/
  272. X
  273. Xstruct bwb_line *
  274. Xbwb_let( struct bwb_line *l )
  275. X   {
  276. X
  277. X   #if INTENSIVE_DEBUG
  278. X   sprintf( bwb_ebuf, "in bwb_let(): pos <%d> line <%s>",
  279. X      l->position, l->buffer );
  280. X   bwb_debug( bwb_ebuf );
  281. X   #endif
  282. X
  283. X   /* Call the expression interpreter to evaluate the assignment */
  284. X
  285. X   bwb_exp( l->buffer, TRUE, &( l->position ) );
  286. X
  287. X   l->next->position = 0;
  288. X   return l->next;
  289. X
  290. X   }
  291. X
  292. X/***************************************************************
  293. X
  294. X        FUNCTION:       bwb_chain()
  295. X
  296. X        DESCRIPTION:    This C function implements the BASIC
  297. X            CHAIN command.
  298. X
  299. X***************************************************************/
  300. X
  301. Xstruct bwb_line *
  302. Xbwb_chain( struct bwb_line *l )
  303. X   {
  304. X   struct bwb_line *current;
  305. X
  306. X   /* deallocate all variables except common ones */
  307. X
  308. X   var_delcvars();
  309. X
  310. X   /* remove old program from memory */
  311. X
  312. X   bwb_xnew( l );
  313. X
  314. X   /* call xload function to load new program in memory */
  315. X
  316. X   bwb_xload( l );
  317. X
  318. X   /* process other arguments */
  319. X
  320. X   /*** TEMP -- WORKPOINT ***/
  321. X
  322. X   /* run the newly loaded program */
  323. X
  324. X   current = bwb_start.next;
  325. X
  326. X   current->position = 0;
  327. X
  328. X   while ( current != &bwb_end )
  329. X      {
  330. X      current = bwb_xline( current );
  331. X      }
  332. X
  333. X   /* return */
  334. X
  335. X   return &bwb_end;
  336. X
  337. X   }
  338. X
  339. X/***************************************************************
  340. X
  341. X        FUNCTION:       bwb_merge()
  342. X
  343. X        DESCRIPTION:    This C function implements the BASIC
  344. X            MERGE command.
  345. X
  346. X***************************************************************/
  347. X
  348. Xstruct bwb_line *
  349. Xbwb_merge( struct bwb_line *l )
  350. X   {
  351. X
  352. X   /* call xload function to merge program in memory */
  353. X
  354. X   bwb_xload( l );
  355. X
  356. X   return l;
  357. X
  358. X   }
  359. X
  360. X/***************************************************************
  361. X
  362. X        FUNCTION:       bwb_load()
  363. X
  364. X        DESCRIPTION:    This C function implements the BASIC
  365. X            LOAD command.
  366. X
  367. X***************************************************************/
  368. X
  369. Xstruct bwb_line *
  370. Xbwb_load( struct bwb_line *l )
  371. X   {
  372. X
  373. X   /* clear current contents */
  374. X
  375. X   bwb_new( l );
  376. X
  377. X   /* call xload function to load program in memory */
  378. X
  379. X   bwb_xload( l );
  380. X
  381. X   return l;
  382. X
  383. X   }
  384. X
  385. X/***************************************************************
  386. X
  387. X        FUNCTION:       bwb_xload()
  388. X
  389. X        DESCRIPTION:    This C function implements the BASIC
  390. X            LOAD command.
  391. X
  392. X***************************************************************/
  393. X
  394. Xstruct bwb_line *
  395. Xbwb_xload( struct bwb_line *l )
  396. X   {
  397. X   FILE *loadfile;
  398. X   char filename[ MAXARGSIZE ];
  399. X
  400. X   /* Get an argument for filename */
  401. X
  402. X   adv_ws( l->buffer, &( l->position ) );
  403. X   switch( l->buffer[ l->position ] )
  404. X      {
  405. X      case '\0':
  406. X      case '\n':
  407. X      case '\r':
  408. X      case ':':
  409. X         bwb_error( err_nofn );
  410. X         l->next->position = 0;
  411. X         return l->next;
  412. X      default:
  413. X         break;
  414. X      }
  415. X
  416. X   bwb_const( l->buffer, filename, &( l->position ) );
  417. X   if ( ( loadfile = fopen( filename, "r" )) == NULL )
  418. X      {
  419. X      sprintf( bwb_ebuf, err_openfile, filename );
  420. X      bwb_error( bwb_ebuf );
  421. X      l->next->position = 0;
  422. X      return l->next;
  423. X      }
  424. X
  425. X   bwb_fload( loadfile );
  426. X
  427. X   l->next->position = 0;
  428. X   return l->next;
  429. X   }
  430. X
  431. X/***************************************************************
  432. X
  433. X        FUNCTION:       bwb_new()
  434. X
  435. X        DESCRIPTION:    This C function implements the BASIC
  436. X            NEW command.
  437. X
  438. X***************************************************************/
  439. X
  440. Xstruct bwb_line *
  441. Xbwb_new( struct bwb_line *l )
  442. X   {
  443. X
  444. X   /* clear program in memory */
  445. X
  446. X   bwb_xnew( l );
  447. X
  448. X   /* clear all variables */
  449. X
  450. X   bwb_clear( l );
  451. X
  452. X   return l->next;
  453. X   }
  454. X
  455. X/***************************************************************
  456. X
  457. X        FUNCTION:       bwb_xnew()
  458. X
  459. X        DESCRIPTION:    Clears the program in memory, but does not
  460. X            deallocate all variables.
  461. X
  462. X***************************************************************/
  463. X
  464. Xstruct bwb_line *
  465. Xbwb_xnew( struct bwb_line *l )
  466. X   {
  467. X   struct bwb_line *current, *previous;
  468. X   int wait;
  469. X
  470. X   wait = TRUE;
  471. X   for ( current = bwb_start.next; current != &bwb_end; current = current->next )
  472. X      {
  473. X      if ( wait != TRUE )
  474. X         {
  475. X         free( previous );
  476. X         }
  477. X      wait = FALSE;
  478. X      previous = current;
  479. X      }
  480. X
  481. X   bwb_start.next = &bwb_end;
  482. X
  483. X   l->next->position = 0;
  484. X
  485. X   return l->next;
  486. X   }
  487. X
  488. X/***************************************************************
  489. X
  490. X        FUNCTION:       bwb_renum()
  491. X
  492. X        DESCRIPTION:
  493. X
  494. X***************************************************************/
  495. X
  496. X#ifdef ALLOW_RENUM
  497. Xstruct bwb_line *
  498. Xbwb_renum( struct bwb_line *l )
  499. X   {
  500. X   struct bwb_line *current, *x;
  501. X   register int c, o;
  502. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  503. X
  504. X   /* set c to initial number */
  505. X
  506. X   c = 10;
  507. X
  508. X   /* set all reset flags to FALSE */
  509. X
  510. X   for ( x = bwb_start.next; x != &bwb_end; x = x->next )
  511. X      {
  512. X      x->reset = FALSE;
  513. X      }
  514. X
  515. X   /* cycle through each line */
  516. X
  517. X   for ( current = bwb_start.next; current != &bwb_end; current = current->next )
  518. X      {
  519. X      o = current->number;
  520. X      current->number = c;
  521. X
  522. X      /* run back through and change any GOTO statements
  523. X         or GOSUB statements depending on this line */
  524. X
  525. X      for ( x = bwb_start.next; x != &bwb_end; x = x->next )
  526. X         {
  527. X
  528. X         if ( ( x->vector == bwb_goto ) || ( x->vector == bwb_gosub ))
  529. X            {
  530. X            if ( atoi( x->argv[ 0 ] ) == o )
  531. X               {
  532. X
  533. X               if ( x->reset == FALSE )
  534. X                  {
  535. X
  536. X                  #if INTENSIVE_DEBUG
  537. X                  sprintf( bwb_ebuf,
  538. X                     "in bwb_renum(): renumbering line %d, new argument is %d",
  539. X                     x->number, c );
  540. X                  bwb_debug( bwb_ebuf );
  541. X                  #endif
  542. X
  543. X                  free( x->argv[ 0 ] );
  544. X                  sprintf( tbuf, "%d", c );
  545. X                  if ( ( x->argv[ 0 ] = calloc( 1, strlen( tbuf ) + 1 )) == NULL )
  546. X                     {
  547. X                     bwb_error( err_getmem );
  548. X                     l->next->position = 0;
  549. X                     return l->next;
  550. X                     }
  551. X                  strcpy( x->argv[ 0 ], tbuf );
  552. X                  x->reset = TRUE;
  553. X                  }
  554. X               }
  555. X            }
  556. X
  557. X         }
  558. X
  559. X      c += 10;
  560. X      }
  561. X
  562. X   l->next->position = 0;
  563. X   return l->next;
  564. X   }
  565. X#endif
  566. X
  567. X/***************************************************************
  568. X
  569. X        FUNCTION:       bwb_save()
  570. X
  571. X        DESCRIPTION:
  572. X
  573. X***************************************************************/
  574. X
  575. Xstruct bwb_line *
  576. Xbwb_save( struct bwb_line *l )
  577. X   {
  578. X   FILE *outfile;
  579. X   static char filename[ MAXARGSIZE ];
  580. X
  581. X   #if INTENSIVE_DEBUG
  582. X   sprintf( bwb_ebuf, "in bwb_save(): entered function." );
  583. X   bwb_debug( bwb_ebuf );
  584. X   #endif
  585. X
  586. X   /* Get an argument for filename */
  587. X
  588. X   adv_ws( l->buffer, &( l->position ) );
  589. X   switch( l->buffer[ l->position ] )
  590. X      {
  591. X      case '\0':
  592. X      case '\n':
  593. X      case '\r':
  594. X      case ':':
  595. X         bwb_error( err_nofn );
  596. X         l->next->position = 0;
  597. X         return l->next;
  598. X      default:
  599. X         break;
  600. X      }
  601. X
  602. X   bwb_const( l->buffer, filename, &( l->position ) );
  603. X   if ( ( outfile = fopen( filename, "w" )) == NULL )
  604. X      {
  605. X      sprintf( bwb_ebuf, err_openfile, filename );
  606. X      bwb_error( bwb_ebuf );
  607. X      l->next->position = 0;
  608. X      return l->next;
  609. X      }
  610. X
  611. X   bwb_xlist( l, outfile );
  612. X   fclose( outfile );
  613. X
  614. X   l->next->position = 0;
  615. X   return l->next;
  616. X
  617. X   }
  618. X
  619. X/***************************************************************
  620. X
  621. X        FUNCTION:       bwb_list()
  622. X
  623. X        DESCRIPTION:
  624. X
  625. X***************************************************************/
  626. X
  627. Xstruct bwb_line *
  628. Xbwb_list( struct bwb_line *l )
  629. X   {
  630. X   bwb_xlist( l, stdout );
  631. X   l->next->position = 0;
  632. X   return l->next;
  633. X   }
  634. X
  635. X/***************************************************************
  636. X
  637. X        FUNCTION:       bwb_xlist()
  638. X
  639. X        DESCRIPTION:
  640. X
  641. X***************************************************************/
  642. X
  643. Xstruct bwb_line *
  644. Xbwb_xlist( struct bwb_line *l, FILE *file )
  645. X   {
  646. X   struct bwb_line *start, *end, *current;
  647. X   register int n;
  648. X   static int s, e;
  649. X   int f, r;
  650. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  651. X
  652. X   start = bwb_start.next;
  653. X   end = &bwb_end;
  654. X
  655. X   r = bwb_numseq( &( l->buffer[ l->position ] ), &s, &e );
  656. X
  657. X   if (( r == FALSE ) || ( s == 0 ))
  658. X      {
  659. X      s = bwb_start.next->number;
  660. X      }
  661. X
  662. X   if ( e == 0 )
  663. X      {
  664. X      e = s;
  665. X      }
  666. X
  667. X   if ( r == FALSE )
  668. X      {
  669. X      for ( current = bwb_start.next; current != &bwb_end; current = current->next )
  670. X         {
  671. X         if ( current->next == &bwb_end )
  672. X            {
  673. X            e = current->number;
  674. X            }
  675. X         }
  676. X      }
  677. X
  678. X   #if INTENSIVE_DEBUG
  679. X   sprintf( bwb_ebuf, "in bwb_list(): LBUFFER sequence is %d-%d", s, e );
  680. X   bwb_debug( bwb_ebuf );
  681. X   #endif
  682. X
  683. X   /* Now try to find the actual lines in memory */
  684. X
  685. X   f = FALSE;
  686. X
  687. X   for ( current = bwb_start.next; current != &bwb_end; current = current->next )
  688. X      {
  689. X      if ( current != l )
  690. X         {
  691. X         current->position = 0;
  692. X         adv_element( current->buffer, &( current->position ), tbuf );
  693. X         if ( atoi( tbuf ) == s )
  694. X            {
  695. X            f = TRUE;
  696. X        start = current;
  697. X
  698. X            #if INTENSIVE_DEBUG
  699. X            sprintf( bwb_ebuf, "in bwb_list(): start line number is <%d>",
  700. X               s );
  701. X            bwb_debug( bwb_ebuf );
  702. X            #endif
  703. X
  704. X            }
  705. X         }
  706. X      }
  707. X
  708. X   /* check and see if a line number was found */
  709. X
  710. X   if ( f == FALSE )
  711. X      {
  712. X      sprintf( bwb_ebuf, err_lnnotfound, s );
  713. X      bwb_error( bwb_ebuf );
  714. X      l->next->position = 0;
  715. X      return l->next;
  716. X      }
  717. X
  718. X   if ( e > s )
  719. X      {
  720. X      for ( current = bwb_start.next; current != &bwb_end; current = current->next )
  721. X         {
  722. X         if ( current != l )
  723. X            {
  724. X            current->position = 0;
  725. X            adv_element( current->buffer, &( current->position ), tbuf );
  726. X            if ( atoi( tbuf ) == e )
  727. X               {
  728. X               #if INTENSIVE_DEBUG
  729. X               sprintf( bwb_ebuf, "in bwb_list(): end line number is <%d>",
  730. X                  e );
  731. X               bwb_debug( bwb_ebuf );
  732. X               #endif
  733. X
  734. X               end = current->next;
  735. X               }
  736. X            }
  737. X         }
  738. X      }
  739. X   else
  740. X      {
  741. X      end = start;
  742. X      }
  743. X
  744. X   /* previous should now be set to the line previous to the
  745. X      first in the omission list */
  746. X
  747. X   /* now go through and list appropriate lines */
  748. X
  749. X   if ( start == end )
  750. X      {
  751. X      fprintf( file, "%s\n", start->buffer );
  752. X      }
  753. X   else
  754. X      {
  755. X      current = start;
  756. X      while ( current != end )
  757. X         {
  758. X         fprintf( file, "%s\n", current->buffer );
  759. X         current = current->next;
  760. X         }
  761. X      }
  762. X
  763. X   l->next->position = 0;
  764. X   return l->next;
  765. X
  766. X   }
  767. X
  768. X/***************************************************************
  769. X
  770. X        FUNCTION:       bwb_goto
  771. X
  772. X        DESCRIPTION:
  773. X
  774. X***************************************************************/
  775. X
  776. Xstruct bwb_line *
  777. Xbwb_goto( struct bwb_line *l )
  778. X   {
  779. X   struct bwb_line *x;
  780. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  781. X
  782. X   /* Check for argument */
  783. X
  784. X   adv_ws( l->buffer, &( l->position ) );
  785. X   switch( l->buffer[ l->position ] )
  786. X      {
  787. X      case '\0':
  788. X      case '\n':
  789. X      case '\r':
  790. X      case ':':
  791. X         bwb_error( err_noln );
  792. X         l->next->position = 0;
  793. X         return l->next;
  794. X      default:
  795. X         break;
  796. X      }
  797. X
  798. X   adv_element( l->buffer, &( l->position ), tbuf );
  799. X
  800. X   for ( x = &bwb_start; x != &bwb_end; x = x->next )
  801. X      {
  802. X      if ( x->number == atoi( tbuf ) )
  803. X         {
  804. X         x->position = 0;
  805. X         return x;
  806. X         }
  807. X      }
  808. X
  809. X   sprintf( bwb_ebuf, err_lnnotfound, atoi( tbuf ) );
  810. X   bwb_error( bwb_ebuf );
  811. X
  812. X   l->next->position = 0;
  813. X   return l->next;
  814. X   }
  815. X
  816. X/***************************************************************
  817. X
  818. X        FUNCTION:       bwb_gosub()
  819. X
  820. X    DESCRIPTION:    This function implements the BASIC GOSUB
  821. X            command.
  822. X
  823. X***************************************************************/
  824. X
  825. Xstruct bwb_line *
  826. Xbwb_gosub( struct bwb_line *l )
  827. X   {
  828. X   struct bwb_line *x, *nl;
  829. X   int save_pos;
  830. X   register int c;
  831. X   char atbuf[ MAXSTRINGSIZE + 1 ];
  832. X   char btbuf[ MAXSTRINGSIZE + 1 ];
  833. X
  834. X   /* Check for argument */
  835. X
  836. X   adv_ws( l->buffer, &( l->position ) );
  837. X   switch( l->buffer[ l->position ] )
  838. X      {
  839. X      case '\0':
  840. X      case '\n':
  841. X      case '\r':
  842. X      case ':':
  843. X         sprintf( bwb_ebuf, err_noln );
  844. X         bwb_error( bwb_ebuf );
  845. X         l->next->position = 0;
  846. X         return l->next;
  847. X      default:
  848. X         break;
  849. X      }
  850. X
  851. X   /* get the target line number in tbuf */
  852. X
  853. X   adv_element( l->buffer, &( l->position ), atbuf );
  854. X
  855. X   for ( x = &bwb_start; x != &bwb_end; x = x->next )
  856. X      {
  857. X
  858. X      if ( x != l )
  859. X         {
  860. X         x->position = 0;
  861. X         }
  862. X
  863. X      /* try to get line number in tbuf */
  864. X
  865. X      adv_element( x->buffer, &( x->position ), btbuf );
  866. X
  867. X      if ( is_numconst( btbuf ) == TRUE )
  868. X         {
  869. X         if ( atoi( btbuf ) == atoi( atbuf ) )
  870. X            {
  871. X        save_pos = l->position;
  872. X
  873. X        #if  INTENSIVE_DEBUG
  874. X        sprintf( bwb_ebuf, "in bwb_gosub() at line <%d> gssc <%d>\n",
  875. X               l->number, bwb_gssc );
  876. X            bwb_debug( bwb_ebuf );
  877. X            bwb_debug( "Press RETURN: " );
  878. X            getchar();
  879. X            #endif
  880. X
  881. X            /* increment the GOSUB stack counter */
  882. X
  883. X            ++bwb_gssc;
  884. X
  885. X            x->cmdnum = -1;
  886. X            x->marked = FALSE;
  887. X            x->position = 0;
  888. X
  889. X            do
  890. X               {
  891. X               bwb_gss[ bwb_gssc ].position = 0;
  892. X
  893. X           /* execute the line */
  894. X
  895. X           nl = bwb_xline( x );
  896. X
  897. X           /* check for RETURN in the line */
  898. X
  899. X           if ( x->cmdnum == getcmdnum( "RETURN" ) )
  900. X          {
  901. X          l->position = save_pos;
  902. X          #if  INTENSIVE_DEBUG
  903. X          sprintf( bwb_ebuf, "in bwb_gosub(): return to line <%d>, position <%d>, gssc <%d>",
  904. X             l->number, l->position, bwb_gssc );
  905. X          bwb_debug( bwb_ebuf );
  906. X          #endif
  907. X          l->next->position = 0;
  908. X          return l->next;     /* but why shouldn't we continue processing */
  909. X          }            /* this line? */
  910. X                    /* answer: bwb_xline() will continue */
  911. X           x = nl;
  912. X
  913. X           }
  914. X
  915. X        while ( TRUE );
  916. X
  917. X            }
  918. X         }
  919. X      }
  920. X
  921. X   sprintf( bwb_ebuf, err_lnnotfound, atoi( atbuf ) );
  922. X   bwb_error( bwb_ebuf );
  923. X
  924. X   l->next->position = 0;
  925. X   return l->next;
  926. X
  927. X   }
  928. X
  929. X/***************************************************************
  930. X
  931. X        FUNCTION:       bwb_return()
  932. X
  933. X    DESCRIPTION:    This function implements the BASIC RETURN
  934. X            command.
  935. X
  936. X***************************************************************/
  937. X
  938. Xstruct bwb_line *
  939. Xbwb_return( struct bwb_line *l )
  940. X   {
  941. X
  942. X   #if  INTENSIVE_DEBUG
  943. X   sprintf( bwb_ebuf, "in bwb_return() at line <%d> bwb_gssc <%d>, cmdnum <%d>",
  944. X      l->number, bwb_gssc, l->cmdnum );
  945. X   bwb_debug( bwb_ebuf );
  946. X   #endif
  947. X
  948. X   if ( bwb_gssc < 1 )
  949. X      {
  950. X      #if PROG_ERRORS
  951. X      sprintf( bwb_ebuf, "in bwb_return(): bwb_gssc <%d>", bwb_gssc );
  952. X      #else
  953. X      sprintf( bwb_ebuf, ERR_RETNOGOSUB );
  954. X      #endif
  955. X      bwb_error( bwb_ebuf );
  956. X      l->next->position = 0;
  957. X      return l->next;
  958. X      }
  959. X
  960. X   --bwb_gssc;
  961. X
  962. X   #if  INTENSIVE_DEBUG
  963. X   sprintf( bwb_ebuf, "in bwb_return() at line <%d>: gss level <%d>",
  964. X      l->number, bwb_gssc );
  965. X   bwb_debug( bwb_ebuf );
  966. X   #endif
  967. X
  968. X   l->cmdnum = getcmdnum( "RETURN" );
  969. X   l->marked = FALSE;
  970. X
  971. X   l->next->position = 0;
  972. X   return l->next;
  973. X
  974. X   }
  975. X
  976. X/***************************************************************
  977. X
  978. X        FUNCTION:       bwb_on
  979. X
  980. X        DESCRIPTION:    This function implements the BASIC ON...
  981. X                        GOTO or ON...GOSUB statements.
  982. X
  983. X***************************************************************/
  984. X
  985. Xstruct bwb_line *
  986. Xbwb_on( struct bwb_line *l )
  987. X   {
  988. X   struct bwb_line *x;
  989. X   char varname[ MAXVARNAMESIZE + 1 ];
  990. X   static int p;
  991. X   struct exp_ese *rvar;
  992. X   int v;
  993. X   int loop;
  994. X   int num_lines;
  995. X   int command;
  996. X   int lines[ MAX_GOLINES ];
  997. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  998. X   char sbuf[ 7 ];
  999. X
  1000. X   /* Check for argument */
  1001. X
  1002. X   adv_ws( l->buffer, &( l->position ) );
  1003. X
  1004. X   switch( l->buffer[ l->position ] )
  1005. X      {
  1006. X      case '\0':
  1007. X      case '\n':
  1008. X      case '\r':
  1009. X      case ':':
  1010. X         sprintf( bwb_ebuf, err_incomplete );
  1011. X         bwb_error( bwb_ebuf );
  1012. X         l->next->position = 0;
  1013. X         return l->next;
  1014. X      default:
  1015. X         break;
  1016. X      }
  1017. X
  1018. X   /* get the variable name or numerical constant */
  1019. X
  1020. X   adv_element( l->buffer, &( l->position ), varname );
  1021. X
  1022. X   /* check for ON ERROR statement */
  1023. X
  1024. X   strncpy( sbuf, varname, 6 );
  1025. X   bwb_strtoupper( sbuf );
  1026. X   if ( strcmp( sbuf, "ERROR" ) == 0 )
  1027. X      {
  1028. X      #if INTENSIVE_DEBUG
  1029. X      sprintf( bwb_ebuf, "in bwb_on(): detected ON ERROR" );
  1030. X      bwb_debug( bwb_ebuf );
  1031. X      #endif
  1032. X      return bwb_onerror( l );
  1033. X      }
  1034. X
  1035. X   /* evaluate the variable name or constant */
  1036. X
  1037. X   p = 0;
  1038. X   rvar = bwb_exp( varname, FALSE, &p );
  1039. X   v = exp_getival( rvar );
  1040. X
  1041. X   #if INTENSIVE_DEBUG
  1042. X   sprintf( bwb_ebuf, "in bwb_on(): value is <%d>", v );
  1043. X   bwb_debug( bwb_ebuf );
  1044. X   #endif
  1045. X
  1046. X   /* Get GOTO or GOSUB statements */
  1047. X
  1048. X   adv_element( l->buffer, &( l->position ), tbuf );
  1049. X   bwb_strtoupper( tbuf );
  1050. X   if ( strncmp( tbuf, "GOTO", (size_t) 4 ) == 0 )
  1051. X      {
  1052. X      command = getcmdnum( "GOTO" );
  1053. X      }
  1054. X   else if ( strncmp( tbuf, "GOSUB", (size_t) 5 ) == 0 )
  1055. X      {
  1056. X      command = getcmdnum( "GOSUB" );
  1057. X      }
  1058. X   else
  1059. X      {
  1060. X      sprintf( bwb_ebuf, ERR_ONNOGOTO );
  1061. X      bwb_error( bwb_ebuf );
  1062. X      l->next->position = 0;
  1063. X      return l->next;
  1064. X      }
  1065. X
  1066. X   num_lines = 0;
  1067. X
  1068. X   loop = TRUE;
  1069. X   while( loop == TRUE )
  1070. X      {
  1071. X
  1072. X      /* read a line number */
  1073. X
  1074. X      inp_adv( l->buffer, &( l->position ) );
  1075. X      adv_element( l->buffer, &( l->position ), tbuf );
  1076. X
  1077. X      lines[ num_lines ] = atoi( tbuf );
  1078. X
  1079. X      ++num_lines;
  1080. X
  1081. X      if ( num_lines >= MAX_GOLINES )
  1082. X         {
  1083. X         loop = FALSE;
  1084. X         }
  1085. X
  1086. X      /* check for end of line */
  1087. X
  1088. X      adv_ws( l->buffer, &( l->position ) );
  1089. X      switch( l->buffer[ l->position ] )
  1090. X         {
  1091. X         case '\0':
  1092. X         case '\n':
  1093. X         case '\r':
  1094. X         case ':':
  1095. X            loop = FALSE;
  1096. X            break;
  1097. X         }
  1098. X
  1099. X      }
  1100. X
  1101. X   /* Be sure value is in range */
  1102. X
  1103. X   if ( ( v < 1 ) || ( v > num_lines ))
  1104. X      {
  1105. X      sprintf( bwb_ebuf, err_valoorange );
  1106. X      bwb_error( bwb_ebuf );
  1107. X      l->next->position = 0;
  1108. X      return l->next;
  1109. X      }
  1110. X
  1111. X   if ( command == getcmdnum( "GOTO" ))
  1112. X      {
  1113. X      sprintf( tbuf, "GOTO %d", lines[ v - 1 ] );
  1114. X      return cnd_xpline( l, tbuf );
  1115. X      }
  1116. X   else if ( command == getcmdnum( "GOSUB" ))
  1117. X      {
  1118. X      sprintf( tbuf, "GOSUB %d", lines[ v - 1 ] );
  1119. X      return cnd_xpline( l, tbuf );
  1120. X      }
  1121. X   else
  1122. X      {
  1123. X      #if PROG_ERRORS
  1124. X      sprintf( bwb_ebuf, "in bwb_on(): invalid value for command." );
  1125. X      bwb_error( bwb_ebuf );
  1126. X      #else
  1127. X      bwb_error( err_syntax );
  1128. X      #endif
  1129. X      l->next->position = 0;
  1130. X      return l->next;
  1131. X      }
  1132. X
  1133. X   }
  1134. X
  1135. X/***************************************************************
  1136. X
  1137. X        FUNCTION:       bwb_onerror()
  1138. X
  1139. X        DESCRIPTION:    This C function implements the BASIC
  1140. X                ON ERROR GOSUB command.
  1141. X
  1142. X***************************************************************/
  1143. X
  1144. Xstruct bwb_line *
  1145. Xbwb_onerror( struct bwb_line *l )
  1146. X   {
  1147. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1148. X
  1149. X   #if INTENSIVE_DEBUG
  1150. X   sprintf( bwb_ebuf, "in bwb_onerror(): entered function" );
  1151. X   bwb_debug( bwb_ebuf );
  1152. X   #endif
  1153. X
  1154. X   /* get the GOSUB STATEMENT */
  1155. X
  1156. X   adv_element( l->buffer, &( l->position ), tbuf );
  1157. X
  1158. X   /* check for GOSUB statement */
  1159. X
  1160. X   bwb_strtoupper( tbuf );
  1161. X   if ( strcmp( tbuf, "GOSUB" ) != 0 )
  1162. X      {
  1163. X      #if PROG_ERRORS
  1164. X      sprintf( bwb_ebuf, "in bwb_onerror(): GOSUB statement missing" );
  1165. X      bwb_error( bwb_ebuf );
  1166. X      #else
  1167. X      bwb_error( err_syntax );
  1168. X      #endif
  1169. X      return l;
  1170. X      }
  1171. X
  1172. X   /* get the GOSUB line number */
  1173. X
  1174. X   adv_element( l->buffer, &( l->position ), tbuf );
  1175. X   err_gosubn = atoi( tbuf );
  1176. X
  1177. X   return l;
  1178. X   }
  1179. X
  1180. X/***************************************************************
  1181. X
  1182. X        FUNCTION:       bwb_stop()
  1183. X
  1184. X        DESCRIPTION:
  1185. X
  1186. X***************************************************************/
  1187. X
  1188. Xstruct bwb_line *
  1189. Xbwb_stop( struct bwb_line *l )
  1190. X   {
  1191. X   return bwb_xend( l );
  1192. X   }
  1193. X
  1194. X/***************************************************************
  1195. X
  1196. X        FUNCTION:       bwb_xend()
  1197. X
  1198. X        DESCRIPTION:
  1199. X
  1200. X***************************************************************/
  1201. X
  1202. Xstruct bwb_line *
  1203. Xbwb_xend( struct bwb_line *l )
  1204. X   {
  1205. X
  1206. X   #if INTENSIVE_DEBUG
  1207. X   sprintf( bwb_ebuf, "in bwb_xend(): entered funtion" );
  1208. X   bwb_debug( bwb_ebuf );
  1209. X   #endif
  1210. X
  1211. X   break_handler();
  1212. X
  1213. X   return &bwb_end;
  1214. X   }
  1215. X
  1216. X/***************************************************************
  1217. X
  1218. X        FUNCTION:       bwb_system()
  1219. X
  1220. X        DESCRIPTION:
  1221. X
  1222. X
  1223. X***************************************************************/
  1224. X
  1225. Xstruct bwb_line *
  1226. Xbwb_system( struct bwb_line *l )
  1227. X   {
  1228. X   fprintf( stdout, "\n" );
  1229. X
  1230. X   #if INTENSIVE_DEBUG
  1231. X   bwb_debug( "in bwb_system(): ready to exit" );
  1232. X   #endif
  1233. X
  1234. X   exit( 0 );
  1235. X   return &bwb_end;                 /* to make LINT happy */
  1236. X   }
  1237. X
  1238. X/***************************************************************
  1239. X
  1240. X        FUNCTION:       bwb_tron()
  1241. X
  1242. X        DESCRIPTION:
  1243. X
  1244. X***************************************************************/
  1245. X
  1246. Xstruct bwb_line *
  1247. Xbwb_tron( struct bwb_line *l )
  1248. X   {
  1249. X   bwb_trace = TRUE;
  1250. X   fprintf( stdout, "Trace is ON\n" );
  1251. X   l->next->position = 0;
  1252. X   return l->next;
  1253. X   }
  1254. X
  1255. X/***************************************************************
  1256. X
  1257. X        FUNCTION:       bwb_troff()
  1258. X
  1259. X        DESCRIPTION:
  1260. X
  1261. X***************************************************************/
  1262. X
  1263. Xstruct bwb_line *
  1264. Xbwb_troff( struct bwb_line *l )
  1265. X   {
  1266. X   bwb_trace = FALSE;
  1267. X   fprintf( stdout, "Trace is OFF\n" );
  1268. X   l->next->position = 0;
  1269. X   return l->next;
  1270. X   }
  1271. X
  1272. X/***************************************************************
  1273. X
  1274. X
  1275. X        FUNCTION:       bwb_delete()
  1276. X
  1277. X        DESCRIPTION:
  1278. X
  1279. X***************************************************************/
  1280. X
  1281. Xstruct bwb_line *
  1282. X
  1283. Xbwb_delete( struct bwb_line *l )
  1284. X   {
  1285. X   struct bwb_line *start, *end, *current, *previous, *p;
  1286. X   register int n;
  1287. X   static int s, e;
  1288. X   int f;
  1289. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1290. X
  1291. X   previous = &bwb_start;
  1292. X   start = bwb_start.next;
  1293. X   end = &bwb_end;
  1294. X
  1295. X   bwb_numseq( &( l->buffer[ l->position ] ), &s, &e );
  1296. X
  1297. X   #if INTENSIVE_DEBUG
  1298. X   sprintf( bwb_ebuf, "in bwb_delete(): LBUFFER sequence is %d-%d", s, e );
  1299. X   bwb_debug( bwb_ebuf );
  1300. X   #endif
  1301. X
  1302. X   /* Now try to find the actual lines in memory */
  1303. X
  1304. X   previous = p = &bwb_start;
  1305. X   f = FALSE;
  1306. X
  1307. X   for ( current = bwb_start.next; current != &bwb_end; current = current->next )
  1308. X      {
  1309. X      if ( current != l )
  1310. X         {
  1311. X         current->position = 0;
  1312. X         adv_element( current->buffer, &( current->position ), tbuf );
  1313. X         if ( atoi( tbuf ) == s )
  1314. X            {
  1315. X            f = TRUE;
  1316. X            previous = p;
  1317. X            start = current;
  1318. X
  1319. X            #if INTENSIVE_DEBUG
  1320. X            sprintf( bwb_ebuf, "in bwb_delete(): start line number is <%d>",
  1321. X               s );
  1322. X            bwb_debug( bwb_ebuf );
  1323. X            #endif
  1324. X
  1325. X            }
  1326. X         }
  1327. X      p = current;
  1328. X      }
  1329. X
  1330. X   /* check and see if a line number was found */
  1331. X
  1332. X   if ( f == FALSE )
  1333. X      {
  1334. X      sprintf( bwb_ebuf, err_lnnotfound, s );
  1335. X      bwb_error( bwb_ebuf );
  1336. X      l->next->position = 0;
  1337. X      return l->next;
  1338. X      }
  1339. X
  1340. X   if ( e > s )
  1341. X      {
  1342. X      for ( current = bwb_start.next; current != &bwb_end; current = current->next )
  1343. X         {
  1344. X         if ( current != l )
  1345. X            {
  1346. X            current->position = 0;
  1347. X            adv_element( current->buffer, &( current->position ), tbuf );
  1348. X            if ( atoi( tbuf ) == e )
  1349. X               {
  1350. X               #if INTENSIVE_DEBUG
  1351. X               sprintf( bwb_ebuf, "in bwb_delete(): end line number is <%d>",
  1352. X                  e );
  1353. X               bwb_debug( bwb_ebuf );
  1354. X               #endif
  1355. X
  1356. X               end = current->next;
  1357. X               }
  1358. X            }
  1359. X         }
  1360. X      }
  1361. X   else
  1362. X      {
  1363. X      end = start;
  1364. X      }
  1365. X
  1366. X   /* previous should now be set to the line previous to the
  1367. X      first in the omission list */
  1368. X
  1369. X   /* now go through and delete appropriate lines */
  1370. X
  1371. X   current = start;
  1372. X   while ( current != end )
  1373. X      {
  1374. X
  1375. X      #if INTENSIVE_DEBUG
  1376. X      sprintf( bwb_ebuf, "in bwb_delete(): deleting line %d",
  1377. X         current->number );
  1378. X      bwb_debug( bwb_ebuf );
  1379. X      #endif
  1380. X
  1381. X      /* free line memory */
  1382. X
  1383. X      bwb_freeline( current );
  1384. X
  1385. X      /* recycle */
  1386. X
  1387. X      current = current->next;
  1388. X      }
  1389. X
  1390. X   /* reset link */
  1391. X
  1392. X   previous->next = current;
  1393. X
  1394. X   l->next->position = 0;
  1395. X   return l->next;
  1396. X   }
  1397. X
  1398. X/***************************************************************
  1399. X
  1400. X        FUNCTION:       bwb_randomize()
  1401. X
  1402. X        DESCRIPTION:
  1403. X
  1404. X***************************************************************/
  1405. X
  1406. Xstruct bwb_line *
  1407. Xbwb_randomize( struct bwb_line *l )
  1408. X   {
  1409. X   register unsigned n;
  1410. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1411. X
  1412. X   /* Check for argument */
  1413. X
  1414. X   adv_ws( l->buffer, &( l->position ) );
  1415. X   switch( l->buffer[ l->position ] )
  1416. X      {
  1417. X      case '\0':
  1418. X      case '\n':
  1419. X      case '\r':
  1420. X      case ':':
  1421. X         n = (unsigned) 1;
  1422. X         break;
  1423. X      default:
  1424. X         n = (unsigned) 0;
  1425. X         break;
  1426. X      }
  1427. X
  1428. X   /* get the argument in tbuf */
  1429. X
  1430. X   if ( n == (unsigned) 0 )
  1431. X      {
  1432. X      adv_element( l->buffer, &( l->position ), tbuf );
  1433. X      n = (unsigned) atoi( tbuf );
  1434. X      }
  1435. X
  1436. X   #if INTENSIVE_DEBUG
  1437. X   sprintf( bwb_ebuf, "in bwb_randomize(): argument is <%d>", n );
  1438. X   bwb_debug( bwb_ebuf );
  1439. X   #endif
  1440. X
  1441. X   srand( n );
  1442. X
  1443. X   l->next->position = 0;
  1444. X   return l->next;
  1445. X   }
  1446. X
  1447. X
  1448. X/***************************************************************
  1449. X
  1450. X        FUNCTION:       bwb_environ()
  1451. X
  1452. X        DESCRIPTION:    This C function implements the BASIC
  1453. X            ENVIRON command.  
  1454. X
  1455. X***************************************************************/
  1456. X
  1457. Xstruct bwb_line *
  1458. Xbwb_environ( struct bwb_line *l )
  1459. X   {
  1460. X   static char tbuf[ MAXSTRINGSIZE + 1 ];
  1461. X   char tmp[ MAXSTRINGSIZE + 1 ];
  1462. X   register int h, i;
  1463. X   int pos;
  1464. X   struct exp_ese *e;
  1465. X
  1466. X   /* find the equals sign */
  1467. X
  1468. X   for ( i = 0; ( l->buffer[ l->position ] != '=' ) && ( l->buffer[ l->position ] != '\0' ); ++i )
  1469. X      {
  1470. X      tbuf[ i ] = l->buffer[ l->position ];
  1471. X      tbuf[ i + 1 ] = '\0';
  1472. X      ++( l->position );
  1473. X      }
  1474. X
  1475. X   #if INTENSIVE_DEBUG
  1476. X   sprintf( bwb_ebuf, "in bwb_environ(): variable string is <%s>", tbuf );
  1477. X   bwb_debug( bwb_ebuf );
  1478. X   #endif
  1479. X
  1480. X   /* get the value string to be assigned */
  1481. X
  1482. X   pos = 0;
  1483. X   e = bwb_exp( tbuf, FALSE, &pos );
  1484. X   str_btoc( tbuf, exp_getsval( e ) );
  1485. X
  1486. X   #if INTENSIVE_DEBUG
  1487. X   sprintf( bwb_ebuf, "in bwb_environ(): variable string resolves to <%s>", tbuf );
  1488. X   bwb_debug( bwb_ebuf );
  1489. X   #endif
  1490. X
  1491. X   /* find the equals sign */
  1492. X
  1493. X   adv_ws( l->buffer, &( l->position ) );
  1494. X   if ( l->buffer[ l->position ] != '=' )
  1495. X      {
  1496. X      #if PROG_ERRORS
  1497. X      sprintf( bwb_ebuf, "in bwb_environ(): failed to find equal sign" );
  1498. X      bwb_error( bwb_ebuf );
  1499. X      #else
  1500. X      bwb_error( err_syntax );
  1501. X      #endif
  1502. X      return l;
  1503. X      }
  1504. X   ++( l->position );
  1505. X
  1506. X   /* get the value string to be assigned */
  1507. X
  1508. X   e = bwb_exp( l->buffer, FALSE, &( l->position ));
  1509. X   str_btoc( tmp, exp_getsval( e ) );
  1510. X
  1511. X   #if INTENSIVE_DEBUG
  1512. X   sprintf( bwb_ebuf, "in bwb_environ(): value string resolves to <%s>", tmp );
  1513. X   bwb_debug( bwb_ebuf );
  1514. X   #endif
  1515. X
  1516. X   /* construct string */
  1517. X
  1518. X   strcat( tbuf, "=" );
  1519. X   strcat( tbuf, tmp );
  1520. X
  1521. X   #if INTENSIVE_DEBUG
  1522. X   sprintf( bwb_ebuf, "in bwb_environ(): assignment string is <%s>", tbuf );
  1523. X   bwb_debug( bwb_ebuf );
  1524. X   #endif
  1525. X
  1526. X   /* now assign value to variable */
  1527. X
  1528. X   if ( putenv( tbuf ) == -1 )
  1529. X      {
  1530. X      bwb_error( err_opsys );
  1531. X      return l;
  1532. X      }
  1533. X
  1534. X   /* return */ 
  1535. X
  1536. X   return l;
  1537. X
  1538. X   }
  1539. X
  1540. X/***************************************************************
  1541. X
  1542. X        FUNCTION:       bwb_cmds()
  1543. X
  1544. X        DESCRIPTION:
  1545. X
  1546. X***************************************************************/
  1547. X
  1548. X#if PERMANENT_DEBUG
  1549. Xstruct bwb_line *
  1550. Xbwb_cmds( struct bwb_line *l )
  1551. X   {
  1552. X   register int n;
  1553. X
  1554. X   fprintf( stdout, "BWBASIC COMMANDS AVAILABLE: \n" );
  1555. X
  1556. X   /* run through the command table and print comand names */
  1557. X
  1558. X   for ( n = 0; n < COMMANDS; ++n )
  1559. X      {
  1560. X      fprintf( stdout, "%s \n", bwb_cmdtable[ n ].name );
  1561. X      }
  1562. X
  1563. X   l->next->position = 0;
  1564. X   return l->next;
  1565. X   }
  1566. X#endif
  1567. X
  1568. Xint
  1569. Xgetcmdnum( char *cmdstr )
  1570. X   {
  1571. X   register int c;
  1572. X
  1573. X   for ( c = 0; c < COMMANDS; ++c )
  1574. X      {
  1575. X      if ( strcmp( bwb_cmdtable[ c ].name, cmdstr ) == 0 )
  1576. X         {
  1577. X         return c;
  1578. X         }
  1579. X      }
  1580. X
  1581. X   return -1;
  1582. X
  1583. X   }
  1584. END_OF_FILE
  1585.   if test 35201 -ne `wc -c <'bwb_cmd.c'`; then
  1586.     echo shar: \"'bwb_cmd.c'\" unpacked with wrong size!
  1587.   fi
  1588.   # end of 'bwb_cmd.c'
  1589. fi
  1590. echo shar: End of archive 9 \(of 11\).
  1591. cp /dev/null ark9isdone
  1592. MISSING=""
  1593. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1594.     if test ! -f ark${I}isdone ; then
  1595.     MISSING="${MISSING} ${I}"
  1596.     fi
  1597. done
  1598. if test "${MISSING}" = "" ; then
  1599.     echo You have unpacked all 11 archives.
  1600.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1601. else
  1602.     echo You still must unpack the following archives:
  1603.     echo "        " ${MISSING}
  1604. fi
  1605. exit 0
  1606. exit 0 # Just in case...
  1607.