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

  1. Newsgroups: comp.sources.misc
  2. From: tcamp@acpub.duke.edu (Ted A. Campbell)
  3. Subject:  v33i044:  bwbasic - Bywater BASIC interpreter version 1.10, Part08/11
  4. Message-ID: <1992Nov5.040659.19932@sparky.imd.sterling.com>
  5. X-Md4-Signature: 24b743d46a94e9bddfbfdebde1f46d89
  6. Date: Thu, 5 Nov 1992 04:06:59 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 44
  11. Archive-name: bwbasic/part08
  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_inp.c bwb_tbl.c
  19. # Wrapped by kent@sparky on Wed Nov  4 21:34:27 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 8 (of 11)."'
  23. if test -f 'bwb_inp.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'bwb_inp.c'\"
  25. else
  26.   echo shar: Extracting \"'bwb_inp.c'\" \(35414 characters\)
  27.   sed "s/^X//" >'bwb_inp.c' <<'END_OF_FILE'
  28. X/***************************************************************
  29. X
  30. X        bwb_inp.c       Input Routines
  31. X                        for Bywater BASIC Interpreter
  32. X
  33. X                        Commands:       DATA
  34. X                                        READ
  35. X                                        RESTORE
  36. X                                        INPUT
  37. X                                        LINE INPUT
  38. X
  39. X                        Copyright (c) 1992, Ted A. Campbell
  40. X
  41. X                        Bywater Software
  42. X                        P. O. Box 4023
  43. X                        Duke Station
  44. X                        Durham, NC  27706
  45. X
  46. X                        email: tcamp@acpub.duke.edu
  47. X
  48. X        Copyright and Permissions Information:
  49. X
  50. X        All U.S. and international copyrights are claimed by the
  51. X        author. The author grants permission to use this code
  52. X        and software based on it under the following conditions:
  53. X        (a) in general, the code and software based upon it may be
  54. X        used by individuals and by non-profit organizations; (b) it
  55. X        may also be utilized by governmental agencies in any country,
  56. X        with the exception of military agencies; (c) the code and/or
  57. X        software based upon it may not be sold for a profit without
  58. X        an explicit and specific permission from the author, except
  59. X        that a minimal fee may be charged for media on which it is
  60. X        copied, and for copying and handling; (d) the code must be
  61. X        distributed in the form in which it has been released by the
  62. X        author; and (e) the code and software based upon it may not
  63. X        be used for illegal activities.
  64. X
  65. X***************************************************************/
  66. X
  67. X#include <stdio.h>
  68. X#include <stdlib.h>
  69. X#include <ctype.h>
  70. X#include <string.h>
  71. X#include <math.h>
  72. X
  73. X#include "bwbasic.h"
  74. X#include "bwb_mes.h"
  75. X
  76. Xstruct bwb_line *data_line;
  77. Xint data_pos;
  78. X
  79. X/* Declarations of functions visible to this file only */
  80. X
  81. Xstatic struct bwb_line *bwb_xinp( struct bwb_line *l, FILE *f );
  82. Xstatic struct bwb_line *inp_str( struct bwb_line *l, char *buffer,
  83. X   char *var_list, int *position );
  84. Xstatic int inp_const( char *m_buffer, char *s_buffer, int *position );
  85. Xstatic int inp_assign( char *b, struct bwb_variable *v );
  86. Xstatic int inp_advws( FILE *f );
  87. Xstatic int inp_xgetc( FILE *f, int is_string );
  88. Xstatic int inp_eatcomma( FILE *f );
  89. Xstatic char_saved = FALSE;
  90. Xstatic cs;
  91. X
  92. X/***************************************************************
  93. X
  94. X        FUNCTION:       bwb_read()
  95. X
  96. X        DESCRIPTION:    This function implements the BASIC READ
  97. X                        statement.
  98. X
  99. X        SYNTAX:         READ variable[, variable...]
  100. X
  101. X***************************************************************/
  102. X
  103. Xstruct bwb_line *
  104. Xbwb_read( struct bwb_line *l )
  105. X   {
  106. X   int pos;
  107. X   register int n;
  108. X   int main_loop, adv_loop;
  109. X   struct bwb_variable *v;
  110. X   int n_params;                         /* number of parameters */
  111. X   int *pp;                              /* pointer to parameter values */
  112. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  113. X
  114. X   #if INTENSIVE_DEBUG
  115. X   sprintf( bwb_ebuf, "in bwb_read(): buffer <%s>",
  116. X      &( l->buffer[ l->position ]));
  117. X   bwb_debug( bwb_ebuf );
  118. X   #endif
  119. X
  120. X   /* Process each variable read from the READ statement */
  121. X
  122. X   main_loop = TRUE;
  123. X   while ( main_loop == TRUE )
  124. X      {
  125. X
  126. X      /* first check position in l->buffer and advance beyond whitespace */
  127. X
  128. X      adv_loop = TRUE;
  129. X      while( adv_loop == TRUE )
  130. X         {
  131. X
  132. X         #if INTENSIVE_DEBUG
  133. X         sprintf( bwb_ebuf, "in bwb_read() adv_loop char <%d> = <%c>",
  134. X            l->buffer[ l->position ], l->buffer[ l->position ] );
  135. X         bwb_debug( bwb_ebuf );
  136. X         #endif
  137. X
  138. X         switch ( l->buffer[ l->position ] )
  139. X            {
  140. X            case ',':                   /* comma delimiter */
  141. X            case ' ':                   /* whitespace */
  142. X            case '\t':
  143. X               ++l->position;
  144. X               break;
  145. X            case ':':                   /* end of line segment */
  146. X        case '\n':                  /* end of line */
  147. X            case '\r':
  148. X            case '\0':
  149. X               adv_loop = FALSE;        /* break out of advance loop */
  150. X               main_loop = FALSE;       /* break out of main loop */
  151. X               break;
  152. X            default:                    /* anything else */
  153. X               adv_loop = FALSE;        /* break out of advance loop */
  154. X               break;
  155. X            }
  156. X         }
  157. X
  158. X      #if INTENSIVE_DEBUG
  159. X      sprintf( bwb_ebuf, "in bwb_read(): end of adv_loop <%d> main_loop <%d>",
  160. X         adv_loop, main_loop );
  161. X      bwb_debug( bwb_ebuf );
  162. X      #endif
  163. X
  164. X      /* be sure main_loop id still valid after checking the line */
  165. X
  166. X      if ( main_loop == TRUE )
  167. X         {
  168. X
  169. X         /* Read a variable name */
  170. X
  171. X         bwb_getvarname( l->buffer, tbuf, &( l->position ) );
  172. X         inp_adv( l->buffer, &( l->position ) );
  173. X         v = var_find( tbuf );
  174. X
  175. X     #if INTENSIVE_DEBUG
  176. X     sprintf( bwb_ebuf, "in bwb_read(): line <%d> variable <%s>",
  177. X        l->number, v->name );
  178. X     bwb_debug( bwb_ebuf );
  179. X     sprintf( bwb_ebuf, "in bwb_read(): remaining line <%s>",
  180. X        &( l->buffer[ l->position ] ) );
  181. X     bwb_debug( bwb_ebuf );
  182. X     #endif
  183. X
  184. X         /* advance beyond whitespace or comma in data buffer */
  185. X
  186. X         inp_adv( data_line->buffer, &data_pos );
  187. X
  188. X         /* Advance to next line if end of buffer */
  189. X
  190. X         switch( data_line->buffer[ data_pos ] )
  191. X            {
  192. X            case '\0':                     /* end of buffer */
  193. X            case '\n':
  194. X            case '\r':
  195. X
  196. X               data_line = data_line->next;
  197. X
  198. X               /* advance farther to line with DATA statement if necessary */
  199. X
  200. X               pos = 0;
  201. X               line_start( data_line->buffer, &pos,
  202. X                  &( data_line->lnpos ),
  203. X                  &( data_line->lnum ),
  204. X                  &( data_line->cmdpos ),
  205. X                  &( data_line->cmdnum ),
  206. X                  &( data_line->startpos ) );
  207. X               data_pos = data_line->startpos;
  208. X
  209. X           #if INTENSIVE_DEBUG
  210. X               sprintf( bwb_ebuf, "in bwb_read(): current data line: <%s>",
  211. X                  data_line->buffer );
  212. X               bwb_debug( bwb_ebuf );
  213. X               #endif
  214. X
  215. X               break;
  216. X            }
  217. X
  218. X         while ( bwb_cmdtable[ data_line->cmdnum ].vector != bwb_data )
  219. X            {
  220. X
  221. X            if ( data_line == &bwb_end )
  222. X               {
  223. X               data_line = bwb_start.next;
  224. X               }
  225. X
  226. X            else
  227. X               {
  228. X               data_line = data_line->next;
  229. X               }
  230. X
  231. X            pos = 0;
  232. X            line_start( data_line->buffer, &pos,
  233. X               &( data_line->lnpos ),
  234. X               &( data_line->lnum ),
  235. X               &( data_line->cmdpos ),
  236. X               &( data_line->cmdnum ),
  237. X               &( data_line->startpos ) );
  238. X            data_pos = data_line->startpos;
  239. X
  240. X            #if INTENSIVE_DEBUG
  241. X            sprintf( bwb_ebuf, "in bwb_read(): advance to data line: <%s>",
  242. X               data_line->buffer );
  243. X            bwb_debug( bwb_ebuf );
  244. X            #endif
  245. X
  246. X            }
  247. X
  248. X         /* advance beyond whitespace in data buffer */
  249. X
  250. X         adv_loop = TRUE;
  251. X         while ( adv_loop == TRUE )
  252. X            {
  253. X            switch( data_line->buffer[ data_pos ] )
  254. X               {
  255. X               case '\0':                       /* end of buffer */
  256. X               case '\n':
  257. X               case '\r':
  258. X                  bwb_error( err_od );
  259. X                  l->next->position = 0;
  260. X                  return l->next;
  261. X               case ' ':                        /* whitespace */
  262. X               case '\t':
  263. X                  ++data_pos;
  264. X                  break;
  265. X               default:
  266. X                  adv_loop = FALSE;             /* carry on */
  267. X                  break;
  268. X               }
  269. X            }
  270. X
  271. X         /* now at last we have a variable in v that needs to be
  272. X            assigned data from the data_buffer at position data_pos.
  273. X            What remains to be done is to get one single bit of data,
  274. X            a string constant or numerical constant, into the small
  275. X            buffer */
  276. X
  277. X         inp_const( data_line->buffer, tbuf, &data_pos );
  278. X
  279. X     #if INTENSIVE_DEBUG
  280. X     sprintf( bwb_ebuf, "in bwb_read(): data constant is <%s>", tbuf );
  281. X     bwb_debug( bwb_ebuf );
  282. X     #endif
  283. X
  284. X         /* get parameters if the variable is dimensioned */
  285. X
  286. X     adv_ws( l->buffer, &( l->position ) );
  287. X     if ( l->buffer[ l->position ] == '(' )
  288. X        {
  289. X        #if INTENSIVE_DEBUG
  290. X        sprintf( bwb_ebuf, "in bwb_read(): variable <%s> is dimensioned",
  291. X           v->name );
  292. X        bwb_debug( bwb_ebuf );
  293. X        #endif
  294. X            dim_getparams( l->buffer, &( l->position ), &n_params, &pp );
  295. X            for ( n = 0; n < v->dimensions; ++n )
  296. X               {
  297. X               v->array_pos[ n ] = pp[ n ];
  298. X               }
  299. X        }
  300. X     #if INTENSIVE_DEBUG
  301. X     else
  302. X        {
  303. X        sprintf( bwb_ebuf, "in bwb_read(): variable <%s> is NOT dimensioned",
  304. X           v->name );
  305. X        bwb_debug( bwb_ebuf );
  306. X        sprintf( bwb_ebuf, "in bwb_read(): remaining line <%s>",
  307. X           &( l->buffer[ l->position ] ) );
  308. X        bwb_debug( bwb_ebuf );
  309. X        }
  310. X     #endif
  311. X
  312. X         /* finally assign the data to the variable */
  313. X
  314. X         inp_assign( tbuf, v );
  315. X
  316. X         }                              /* end of remainder of main loop */
  317. X
  318. X      }                                 /* end of main_loop */
  319. X
  320. X   #if INTENSIVE_DEBUG
  321. X   sprintf( bwb_ebuf, "in bwb_read(): exiting function, line <%s> ",
  322. X      &( l->buffer[ l->position ] ) );
  323. X   bwb_debug( bwb_ebuf );
  324. X   #endif
  325. X
  326. X   l->next->position = 0;
  327. X   return l->next;
  328. X
  329. X   }
  330. X
  331. X/***************************************************************
  332. X
  333. X        FUNCTION:       bwb_data()
  334. X
  335. X        DESCRIPTION:    This function implements the BASIC DATA
  336. X                        statement, although at the point at which
  337. X                        DATA statements are encountered, no
  338. X                        processing is done.  All actual processing
  339. X                        of DATA statements is accomplished by READ
  340. X                        (bwb_read()).
  341. X
  342. X        SYNTAX:         DATA constant[, constant]...
  343. X
  344. X
  345. X***************************************************************/
  346. X
  347. Xstruct bwb_line *
  348. Xbwb_data( struct bwb_line *l )
  349. X   {
  350. X   l->next->position = 0;
  351. X   return l->next;
  352. X   }
  353. X
  354. X/***************************************************************
  355. X
  356. X        FUNCTION:       bwb_restore()
  357. X
  358. X        DESCRIPTION:    This function implements the BASIC RESTORE
  359. X                        statement.
  360. X
  361. X        SYNTAX:         RESTORE [line number]
  362. X
  363. X***************************************************************/
  364. X
  365. Xstruct bwb_line *
  366. Xbwb_restore( struct bwb_line *l )
  367. X   {
  368. X   struct bwb_line *r;
  369. X   struct bwb_line *r_line;
  370. X   int n;
  371. X   int pos;
  372. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  373. X
  374. X   /* get the first element beyond the starting position */
  375. X
  376. X   adv_element( l->buffer, &( l->position ), tbuf );
  377. X
  378. X   /* if the line is not a numerical constant, then there is no
  379. X      argument; set the current line to the first in the program */
  380. X
  381. X   if ( is_numconst( tbuf ) != TRUE )
  382. X      {
  383. X      data_line = &bwb_start;
  384. X      data_pos = 0;
  385. X      #if INTENSIVE_DEBUG
  386. X      sprintf( bwb_ebuf, "in bwb_restore(): RESTORE w/ no argument " );
  387. X      bwb_debug( bwb_ebuf );
  388. X      #endif
  389. X      l->next->position = 0;
  390. X      return l->next;
  391. X      }
  392. X
  393. X   /* find the line */
  394. X
  395. X   n = atoi( tbuf );
  396. X
  397. X   #if INTENSIVE_DEBUG
  398. X   sprintf( bwb_ebuf, "in bwb_restore(): line for restore is <%d>", n );
  399. X   bwb_debug( bwb_ebuf );
  400. X   #endif
  401. X
  402. X   r_line = NULL;
  403. X   for ( r = bwb_start.next; r != &bwb_end; r = r->next )
  404. X      {
  405. X
  406. X      if ( r->number == n )
  407. X         {
  408. X         r_line = r;
  409. X         }
  410. X      }
  411. X
  412. X   if ( r_line == NULL )
  413. X      {
  414. X      #if PROG_ERRORS
  415. X      sprintf( bwb_ebuf, "at line %d: Can't find line number for RESTORE.",
  416. X         l->number );
  417. X      bwb_error( bwb_ebuf );
  418. X      #else
  419. X      sprintf( bwb_ebuf, err_lnnotfound, n );
  420. X      bwb_error( bwb_ebuf );
  421. X      #endif
  422. X      l->next->position = 0;
  423. X      return l->next;
  424. X      }
  425. X
  426. X   /* initialize variables for the line */
  427. X
  428. X   pos = 0;
  429. X   line_start( r_line->buffer, &pos,
  430. X      &( r_line->lnpos ),
  431. X      &( r_line->lnum ),
  432. X      &( r_line->cmdpos ),
  433. X      &( r_line->cmdnum ),
  434. X      &( r_line->startpos ) );
  435. X
  436. X   /* verify that line is a data statement */
  437. X
  438. X   if ( bwb_cmdtable[ r_line->cmdnum ].vector != bwb_data )
  439. X      {
  440. X      #if PROG_ERRORS
  441. X      sprintf( bwb_ebuf, "at line %d: Line %d is not a DATA statement.",
  442. X         l->number, r_line->number );
  443. X      bwb_error( bwb_ebuf );
  444. X      #else
  445. X      bwb_error( err_syntax );
  446. X      #endif
  447. X      l->next->position = 0;
  448. X      return l->next;
  449. X      }
  450. X
  451. X   /* reassign data_line */
  452. X
  453. X   data_line = r_line;
  454. X   data_pos = data_line->startpos;
  455. X
  456. X   l->next->position = 0;
  457. X   return l->next;
  458. X   }
  459. X
  460. X/***************************************************************
  461. X
  462. X        FUNCTION:       bwb_input()
  463. X
  464. X        DESCRIPTION:    This function implements the BASIC INPUT
  465. X                        statement.
  466. X
  467. X        SYNTAX:         INPUT [;][prompt$;]variable[$,variable]...
  468. X                        INPUT #n variable[$,variable]...
  469. X
  470. X***************************************************************/
  471. X
  472. Xstruct bwb_line *
  473. Xbwb_input( struct bwb_line *l )
  474. X   {
  475. X   FILE *fp;
  476. X   int pos;
  477. X   int req_devnumber;
  478. X   struct exp_ese *v;
  479. X   int is_prompt;
  480. X   int suppress_qm;
  481. X   static char tbuf[ MAXSTRINGSIZE + 1 ];
  482. X
  483. X   #if INTENSIVE_DEBUG
  484. X   sprintf( bwb_ebuf, "in bwb_input(): enter function" );
  485. X   bwb_debug( bwb_ebuf );
  486. X   #endif
  487. X
  488. X   /* advance beyond whitespace and check for the '#' sign */
  489. X
  490. X   adv_ws( l->buffer, &( l->position ) );
  491. X
  492. X   if ( l->buffer[ l->position ] == '#' )
  493. X      {
  494. X      ++( l->position );
  495. X      adv_element( l->buffer, &( l->position ), tbuf );
  496. X      pos = 0;
  497. X      v = bwb_exp( tbuf, FALSE, &pos );
  498. X      adv_ws( l->buffer, &( l->position ) );
  499. X      if ( l->buffer[ l->position ] == ',' )
  500. X         {
  501. X         ++( l->position );
  502. X         }
  503. X      else
  504. X         {
  505. X     #if PROG_ERRORS
  506. X         bwb_error( "in bwb_input(): no comma after #n" );
  507. X         #else
  508. X         bwb_error( err_syntax );
  509. X         #endif
  510. X         l->next->position = 0;
  511. X         return l->next;
  512. X         }
  513. X
  514. X      req_devnumber = exp_getival( v );
  515. X
  516. X      #if INTENSIVE_DEBUG
  517. X      sprintf( bwb_ebuf, "in bwb_input(): requested device number <%d>",
  518. X         req_devnumber );
  519. X      bwb_debug( bwb_ebuf );
  520. X      #endif
  521. X
  522. X      /* check the requested device number */
  523. X
  524. X      if ( ( req_devnumber < 0 ) || ( req_devnumber >= DEF_DEVICES ))
  525. X         {
  526. X         #if PROG_ERRORS
  527. X         bwb_error( "in bwb_input(): Requested device number is out if range." );
  528. X         #else
  529. X         bwb_error( err_devnum );
  530. X         #endif
  531. X         l->next->position = 0;
  532. X         return l->next;
  533. X         }
  534. X
  535. X      if ( ( dev_table[ req_devnumber ].mode == DEVMODE_CLOSED ) ||
  536. X         ( dev_table[ req_devnumber ].mode == DEVMODE_AVAILABLE ) )
  537. X         {
  538. X         #if PROG_ERRORS
  539. X         bwb_error( "in bwb_input(): Requested device number is not open." );
  540. X         #else
  541. X         bwb_error( err_devnum );
  542. X         #endif
  543. X
  544. X         l->next->position = 0;
  545. X         return l->next;
  546. X         }
  547. X
  548. X      if ( dev_table[ req_devnumber ].mode != DEVMODE_INPUT )
  549. X         {
  550. X         #if PROG_ERRORS
  551. X         bwb_error( "in bwb_input(): Requested device is not open for INPUT." );
  552. X         #else
  553. X         bwb_error( err_devnum );
  554. X         #endif
  555. X
  556. X         l->next->position = 0;
  557. X         return l->next;
  558. X         }
  559. X
  560. X      /* look up the requested device in the device table */
  561. X
  562. X      fp = dev_table[ req_devnumber ].cfp;
  563. X
  564. X      }
  565. X   else
  566. X      {
  567. X      fp = stdin;
  568. X      }
  569. X
  570. X   /* if input is not from stdin, then branch to bwb_xinp() */
  571. X
  572. X   if ( fp != stdin )
  573. X      {
  574. X      return bwb_xinp( l, fp );
  575. X      }
  576. X
  577. X   /* from this point we presume that input is from stdin */
  578. X
  579. X   /* check for a semicolon or a quotation mark, not in
  580. X      first position: this should indicate a prompt string */
  581. X
  582. X   suppress_qm = is_prompt = FALSE;
  583. X
  584. X   adv_ws( l->buffer, &( l->position ) );
  585. X
  586. X   switch( l->buffer[ l->position ] )
  587. X      {
  588. X      case '\"':
  589. X         is_prompt = TRUE;
  590. X         break;
  591. X
  592. X      case ';':
  593. X
  594. X         /* AGENDA: add code to suppress newline if a
  595. X            semicolon is used here; this may not be possible
  596. X            using ANSI C alone, since it has not functions for
  597. X            unechoed console input. */
  598. X
  599. X         is_prompt = TRUE;
  600. X         ++l->position;
  601. X         break;
  602. X
  603. X      case ',':
  604. X
  605. X         /* QUERY: why is this code here? the question mark should
  606. X            be suppressed if a comma <follows> the prompt string. */
  607. X
  608. X         #if INTENSIVE_DEBUG
  609. X         bwb_debug( "in bwb_input(): found initial comma" );
  610. X         #endif
  611. X         suppress_qm = TRUE;
  612. X         ++l->position;
  613. X         break;
  614. X      }
  615. X
  616. X   /* get prompt string and print it */
  617. X
  618. X   if ( is_prompt == TRUE )
  619. X      {
  620. X
  621. X      /* get string element */
  622. X
  623. X      inp_const( l->buffer, tbuf, &( l->position ) );
  624. X
  625. X      /* advance past semicolon to beginning of variable */
  626. X
  627. X      suppress_qm = inp_adv( l->buffer, &( l->position ) );
  628. X
  629. X      /* print the prompt string */
  630. X
  631. X      xprintf( stdout, tbuf );
  632. X      }                                      /* end condition: prompt string */
  633. X
  634. X   /* print out the question mark delimiter unless it has been
  635. X      suppressed */
  636. X
  637. X   if ( suppress_qm != TRUE )
  638. X      {
  639. X      xprintf( stdout, "? " );
  640. X      }
  641. X
  642. X   #if INTENSIVE_DEBUG
  643. X   sprintf( bwb_ebuf, "in bwb_input(): ready to get input line" );
  644. X   bwb_debug( bwb_ebuf );
  645. X   #endif
  646. X
  647. X   /* read a line into the input buffer */
  648. X
  649. X   fflush( stdin );
  650. X   fgets( tbuf, MAXSTRINGSIZE, stdin );
  651. X   bwb_stripcr( tbuf );
  652. X
  653. X   #if INTENSIVE_DEBUG
  654. X   sprintf( bwb_ebuf, "in bwb_input(): received line <%s>", tbuf );
  655. X   bwb_debug( bwb_ebuf );
  656. X   bwb_debug( "Press RETURN: " );
  657. X   getchar();
  658. X   #endif
  659. X
  660. X   /* reset print column to account for LF at end of fgets() */
  661. X
  662. X   * prn_getcol( stdout ) = 1;
  663. X
  664. X   return inp_str( l, tbuf, l->buffer, &( l->position ) );
  665. X
  666. X   }
  667. X
  668. X/***************************************************************
  669. X
  670. X        FUNCTION:       bwb_xinp()
  671. X
  672. X        DESCRIPTION:    This function does the bulk of processing
  673. X                        for INPUT #, and so is file independent.
  674. X
  675. X***************************************************************/
  676. X
  677. Xstruct bwb_line *
  678. Xbwb_xinp( struct bwb_line *l, FILE *f )
  679. X   {
  680. X   int loop;
  681. X   struct bwb_variable *v;
  682. X   char c;
  683. X   register int n;
  684. X   int pos;
  685. X   int *pp;
  686. X   int n_params;
  687. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  688. X
  689. X   #if INTENSIVE_DEBUG
  690. X   sprintf( bwb_ebuf, "in bwb_xinp(): buffer <%s>",
  691. X      &( l->buffer[ l->position ] ) );
  692. X   bwb_debug( bwb_ebuf );
  693. X   #endif
  694. X
  695. X   /* loop through elements required */
  696. X
  697. X   loop = TRUE;
  698. X   while ( loop == TRUE )
  699. X      {
  700. X      
  701. X      /* read a variable from the list */
  702. X
  703. X      bwb_getvarname( l->buffer, tbuf, &( l->position ) );
  704. X      v = var_find( tbuf );
  705. X
  706. X      #if INTENSIVE_DEBUG
  707. X      sprintf( bwb_ebuf, "in bwb_xinp(): found variable name <%s>",
  708. X         v->name );
  709. X      bwb_debug( bwb_ebuf );
  710. X      #endif
  711. X
  712. X      /* read subscripts */
  713. X
  714. X      adv_ws( l->buffer, &( l->position ) );
  715. X      if ( l->buffer[ l->position ] == ')' )
  716. X         {
  717. X         #if INTENSIVE_DEBUG
  718. X         sprintf( bwb_ebuf, "in bwb_xinp(): variable <%s> has dimensions",
  719. X            v->name );
  720. X         bwb_debug( bwb_ebuf );
  721. X         #endif
  722. X         dim_getparams( l->buffer, &( l->position ), &n_params, &pp );
  723. X         for ( n = 0; n < v->dimensions; ++n )
  724. X            {
  725. X            v->array_pos[ n ] = pp[ n ];
  726. X            }
  727. X         }
  728. X
  729. X      inp_advws( f );
  730. X
  731. X      /* perform type-specific input */
  732. X
  733. X      switch( v->type )
  734. X         {
  735. X         case STRING:
  736. X            if ( inp_xgetc( f, TRUE ) != '\"' )
  737. X               {
  738. X               #if PROG_ERRORS
  739. X               sprintf( bwb_ebuf, "in bwb_xinp(): expected quotation mark" );
  740. X               bwb_error( bwb_ebuf );
  741. X               #else
  742. X               bwb_error( err_mismatch );
  743. X               #endif
  744. X               }
  745. X            n = 0;
  746. X            while ( ( c = (char) inp_xgetc( f, TRUE )) != '\"' )
  747. X               {
  748. X               tbuf[ n ] = c;
  749. X               ++n;
  750. X               tbuf[ n ] = '\0';
  751. X               }
  752. X            str_ctob( var_findsval( v, v->array_pos ), tbuf );
  753. X            #if INTENSIVE_DEBUG
  754. X            sprintf( bwb_ebuf, "in bwb_xinp(): read STRING <%s>",
  755. X               tbuf );
  756. X            bwb_debug( bwb_ebuf );
  757. X            #endif
  758. X            inp_eatcomma( f );
  759. X            break;
  760. X         case INTEGER:
  761. X            n = 0;
  762. X            while ( ( c = (char) inp_xgetc( f, FALSE )) != ',' )
  763. X               {
  764. X               tbuf[ n ] = c;
  765. X               ++n;
  766. X               tbuf[ n ] = '\0';
  767. X               }
  768. X            #if INTENSIVE_DEBUG
  769. X            sprintf( bwb_ebuf, "in bwb_xinp(): read INTEGER <%s>",
  770. X               tbuf );
  771. X            bwb_debug( bwb_ebuf );
  772. X            #endif
  773. X            * var_findival( v, v->array_pos ) = atoi( tbuf );
  774. X            break;
  775. X         case DOUBLE:
  776. X            n = 0;
  777. X            while ( ( c = (char) inp_xgetc( f, FALSE )) != ',' )
  778. X               {
  779. X               tbuf[ n ] = c;
  780. X               ++n;
  781. X               tbuf[ n ] = '\0';
  782. X               }
  783. X            #if INTENSIVE_DEBUG
  784. X            sprintf( bwb_ebuf, "in bwb_xinp(): read DOUBLE <%s>",
  785. X               tbuf );
  786. X            bwb_debug( bwb_ebuf );
  787. X            #endif
  788. X            * var_finddval( v, v->array_pos ) = (double) atof( tbuf );
  789. X            break;
  790. X         default:            /* take SINGLE as default */
  791. X            n = 0;
  792. X            while ( ( c = (char) inp_xgetc( f, FALSE )) != ',' )
  793. X               {
  794. X               tbuf[ n ] = c;
  795. X               ++n;
  796. X               tbuf[ n ] = '\0';
  797. X               }
  798. X            #if INTENSIVE_DEBUG
  799. X            sprintf( bwb_ebuf, "in bwb_xinp(): read SINGLE <%s>",
  800. X               tbuf );
  801. X            bwb_debug( bwb_ebuf );
  802. X            #endif
  803. X            * var_findfval( v, v->array_pos ) = (float) atof( tbuf );
  804. X            break;
  805. X         }                /* end of switch for type-specific input */
  806. X
  807. X      /* check for comma */
  808. X
  809. X      adv_ws( l->buffer, &( l->position ) );
  810. X      if ( l->buffer[ l->position ] == ',' )
  811. X         {
  812. X         ++( l->position );
  813. X         }
  814. X      else
  815. X         {
  816. X         loop = FALSE;
  817. X         }
  818. X
  819. X      }
  820. X
  821. X   /* return */
  822. X
  823. X   return l;
  824. X
  825. X   }
  826. X
  827. X/***************************************************************
  828. X
  829. X        FUNCTION:       inp_advws()
  830. X
  831. X        DESCRIPTION:    
  832. X
  833. X***************************************************************/
  834. X
  835. Xint
  836. Xinp_advws( FILE *f )
  837. X   {
  838. X   register int c;
  839. X   int loop;
  840. X
  841. X   loop = TRUE;
  842. X   while ( loop == TRUE )
  843. X      {
  844. X      c = (char) inp_xgetc( f, TRUE );
  845. X
  846. X      switch( c )
  847. X         {
  848. X         case '\n':
  849. X         case '\r':
  850. X         case ' ':
  851. X         case '\t':
  852. X            break;
  853. X         default:
  854. X            char_saved = TRUE;
  855. X            cs = c;
  856. X            loop = FALSE;
  857. X            break;
  858. X         }
  859. X      }   
  860. X
  861. X   return TRUE;
  862. X   }
  863. X
  864. X/***************************************************************
  865. X
  866. X        FUNCTION:       inp_xgetc()
  867. X
  868. X        DESCRIPTION:    
  869. X
  870. X***************************************************************/
  871. X
  872. Xint
  873. Xinp_xgetc( FILE *f, int is_string )
  874. X   {
  875. X   register int c;
  876. X   static int prev_eof = FALSE;
  877. X
  878. X   if ( char_saved == TRUE )
  879. X      {
  880. X      char_saved = FALSE;
  881. X      return cs;
  882. X      }
  883. X
  884. X   if ( feof( f ) != 0 )
  885. X      {
  886. X      if ( prev_eof == TRUE )
  887. X         {
  888. X         bwb_error( err_od );
  889. X         }
  890. X      else
  891. X         {
  892. X     prev_eof = TRUE;
  893. X     return (int) ',';
  894. X     }
  895. X      }
  896. X
  897. X   prev_eof = FALSE;
  898. X
  899. X   c = fgetc( f );
  900. X
  901. X   if ( is_string == TRUE )
  902. X      {
  903. X      return c;
  904. X      }
  905. X      
  906. X   switch( c )
  907. X      {
  908. X      case ' ':
  909. X      case '\n':
  910. X      case ',':
  911. X      case '\r':
  912. X         return ',';
  913. X      }
  914. X
  915. X   return c;
  916. X
  917. X   }
  918. X
  919. X/***************************************************************
  920. X
  921. X        FUNCTION:       inp_eatcomma()
  922. X
  923. X        DESCRIPTION:    
  924. X
  925. X***************************************************************/
  926. X
  927. Xint
  928. Xinp_eatcomma( FILE *f )
  929. X   {
  930. X   char c;
  931. X
  932. X   while ( ( c = (char) inp_xgetc( f, TRUE ) ) == ',' )
  933. X      {
  934. X      }
  935. X      
  936. X   char_saved = TRUE;
  937. X   cs = c;
  938. X      
  939. X   return TRUE;
  940. X   }
  941. X
  942. X/***************************************************************
  943. X
  944. X        FUNCTION:       inp_str()
  945. X
  946. X        DESCRIPTION:    This function does INPUT processing
  947. X                        from a determined string of input
  948. X                        data and a determined variable list
  949. X                        (both in memory).  This presupposes
  950. X            that input has been taken from stdin,
  951. X            not from a disk file or device.
  952. X
  953. X***************************************************************/
  954. X
  955. Xstruct bwb_line *
  956. Xinp_str( struct bwb_line *l, char *input_buffer, char *var_list, int *vl_position )
  957. X   {
  958. X   int i;
  959. X   register int n;
  960. X   struct bwb_variable *v;
  961. X   int loop;
  962. X   int *pp;
  963. X   int n_params;
  964. X   char ttbuf[ MAXSTRINGSIZE + 1 ];        /* build element */
  965. X   char varname[ MAXSTRINGSIZE + 1 ];        /* build element */
  966. X
  967. X   #if INTENSIVE_DEBUG
  968. X   sprintf( bwb_ebuf, "in inp_str(): received line <%s>",
  969. X      l->buffer );
  970. X   bwb_debug( bwb_ebuf );
  971. X   sprintf( bwb_ebuf, "in inp_str(): received variable list <%s>.",
  972. X      &( var_list[ *vl_position ] ) );
  973. X   bwb_debug( bwb_ebuf );
  974. X   sprintf( bwb_ebuf, "in inp_str(): received input buffer  <%s>.",
  975. X      input_buffer );
  976. X   bwb_debug( bwb_ebuf );
  977. X   #endif
  978. X
  979. X   /* Read elements, and assign them to variables */
  980. X
  981. X   i = 0;
  982. X   loop = TRUE;
  983. X   while ( loop == TRUE )
  984. X      {
  985. X
  986. X      /* get a variable name from the list */
  987. X
  988. X      bwb_getvarname( var_list, varname, vl_position );    /* get name */
  989. X      v = var_find( varname );
  990. X
  991. X      #if INTENSIVE_DEBUG
  992. X      sprintf( bwb_ebuf, "in inp_str(): found variable buffer <%s> name <%s>",
  993. X         varname, v->name );
  994. X      bwb_debug( bwb_ebuf );
  995. X      #endif
  996. X
  997. X      /* read subscripts if appropriate */
  998. X
  999. X      adv_ws( var_list, vl_position );
  1000. X      if ( var_list[ *vl_position ] == ')' )
  1001. X         {
  1002. X     #if INTENSIVE_DEBUG
  1003. X     sprintf( bwb_ebuf, "in inp_str(): variable <%s> has dimensions",
  1004. X        v->name );
  1005. X     bwb_debug( bwb_ebuf );
  1006. X     #endif
  1007. X         dim_getparams( var_list, vl_position, &n_params, &pp );
  1008. X         for ( n = 0; n < v->dimensions; ++n )
  1009. X            {
  1010. X            v->array_pos[ n ] = pp[ n ];
  1011. X            }
  1012. X         }
  1013. X
  1014. X      /* build string from input buffer in ttbuf */
  1015. X
  1016. X      n = 0;
  1017. X      ttbuf[ 0 ] = '\0';
  1018. X      while ( ( input_buffer[ i ] != ',' )
  1019. X         &&   ( input_buffer[ i ] != '\0' ))
  1020. X         {
  1021. X         ttbuf[ n ] = input_buffer[ i ];
  1022. X         ++n;
  1023. X         ++i;
  1024. X         ttbuf[ n ] = '\0';
  1025. X         }
  1026. X
  1027. X      #if INTENSIVE_DEBUG
  1028. X      sprintf( bwb_ebuf, "in inp_str(): string for input <%s>",
  1029. X         ttbuf );
  1030. X      bwb_debug( bwb_ebuf );
  1031. X      #endif
  1032. X
  1033. X      /* perform type-specific input */
  1034. X
  1035. X      inp_assign( ttbuf, v );
  1036. X
  1037. X      /* check for commas in variable list and input list and advance */
  1038. X
  1039. X      adv_ws( var_list, vl_position );
  1040. X      switch( var_list[ *vl_position ] )
  1041. X     {
  1042. X     case '\n':
  1043. X     case '\r':
  1044. X     case '\0':
  1045. X     case ':':
  1046. X        loop = FALSE;
  1047. X        break;
  1048. X     case ',':
  1049. X        ++( *vl_position );
  1050. X        break;
  1051. X         }
  1052. X      adv_ws( var_list, vl_position );
  1053. X
  1054. X      adv_ws( input_buffer, &i );
  1055. X      switch ( input_buffer[ i ] )
  1056. X     {
  1057. X     case '\n':
  1058. X     case '\r':
  1059. X     case '\0':
  1060. X     case ':':
  1061. X        loop = FALSE;
  1062. X        break;
  1063. X     case ',':
  1064. X        ++i;
  1065. X        break;
  1066. X     }
  1067. X      adv_ws( input_buffer, &i );
  1068. X
  1069. X      }
  1070. X
  1071. X   #if INTENSIVE_DEBUG
  1072. X   sprintf( bwb_ebuf, "in inp_str(): exit, line buffer <%s>",
  1073. X      &( l->buffer[ l->position ] ) );
  1074. X   bwb_debug( bwb_ebuf );
  1075. X   #endif
  1076. X
  1077. X   /* return */
  1078. X
  1079. X   l->next->position = 0;
  1080. X   return l->next;
  1081. X
  1082. X   }
  1083. X
  1084. X/***************************************************************
  1085. X
  1086. X        FUNCTION:       inp_assign()
  1087. X
  1088. X        DESCRIPTION:    This function assigns the value of a
  1089. X                        numerical or string constant to a
  1090. X                        variable.
  1091. X
  1092. X
  1093. X***************************************************************/
  1094. X
  1095. Xint
  1096. Xinp_assign( char *b, struct bwb_variable *v )
  1097. X   {
  1098. X
  1099. X   switch( v->type )
  1100. X      {
  1101. X      case STRING:
  1102. X         str_ctob( var_findsval( v, v->array_pos ), b );
  1103. X         break;
  1104. X
  1105. X      case DOUBLE:
  1106. X         if ( strlen( b ) == 0 )
  1107. X            {
  1108. X            *( var_finddval( v, v->array_pos )) = (double) 0.0;
  1109. X            }
  1110. X         else
  1111. X            {
  1112. X            *( var_finddval( v, v->array_pos )) = (double) atof( b );
  1113. X            }
  1114. X         break;
  1115. X
  1116. X      case SINGLE:
  1117. X         if ( strlen( b ) == 0 )
  1118. X            {
  1119. X            *( var_findfval( v, v->array_pos )) = (float) 0.0;
  1120. X            }
  1121. X         else
  1122. X            {
  1123. X            *( var_findfval( v, v->array_pos )) = (float) atof( b );
  1124. X            }
  1125. X         break;
  1126. X
  1127. X      case INTEGER:
  1128. X         if ( strlen( b ) == 0 )
  1129. X            {
  1130. X            *( var_findival( v, v->array_pos )) = 0;
  1131. X            }
  1132. X         else
  1133. X            {
  1134. X            *( var_findival( v, v->array_pos )) = atoi( b );
  1135. X            }
  1136. X         break;
  1137. X
  1138. X      default:
  1139. X         #if PROG_ERRORS
  1140. X         sprintf( bwb_ebuf, "in inp_assign(): variable <%s> of unknown type",
  1141. X            v->name );
  1142. X         bwb_error( bwb_ebuf );
  1143. X         #else
  1144. X         bwb_error( err_mismatch );
  1145. X         #endif
  1146. X         return FALSE;
  1147. X
  1148. X      }
  1149. X
  1150. X   return FALSE;
  1151. X
  1152. X   }
  1153. X
  1154. X/***************************************************************
  1155. X
  1156. X        FUNCTION:       inp_adv()
  1157. X
  1158. X        DESCRIPTION:    This function advances the string pointer
  1159. X                        past whitespace and the item delimiter
  1160. X                        (comma).
  1161. X
  1162. X***************************************************************/
  1163. X
  1164. Xint
  1165. Xinp_adv( char *b, int *c )
  1166. X   {
  1167. X   int rval;
  1168. X
  1169. X   rval = FALSE;
  1170. X
  1171. X   while( TRUE )
  1172. X      {
  1173. X      switch( b[ *c ] )
  1174. X         {
  1175. X         case ' ':              /* whitespace */
  1176. X         case '\t':
  1177. X         case ';':              /* semicolon, end of prompt string */
  1178. X            ++*c;
  1179. X            break;
  1180. X         case ',':              /* comma, variable delimiter */
  1181. X            rval = TRUE;
  1182. X            ++*c;
  1183. X            break;
  1184. X         case '\0':        /* end of line */
  1185. X         case ':':         /* end of line segment */
  1186. X            rval = TRUE;
  1187. X            return rval;
  1188. X         default:
  1189. X            return rval;
  1190. X         }
  1191. X      }
  1192. X   }
  1193. X
  1194. X/***************************************************************
  1195. X
  1196. X        FUNCTION:       inp_const()
  1197. X
  1198. X        DESCRIPTION:    This function reads a numerical or string
  1199. X                        constant from <m_buffer> into <s_buffer>,
  1200. X                        incrementing <position> appropriately.
  1201. X
  1202. X***************************************************************/
  1203. X
  1204. Xint
  1205. Xinp_const( char *m_buffer, char *s_buffer, int *position )
  1206. X   {
  1207. X   int string;
  1208. X   int s_pos;
  1209. X   int loop;
  1210. X
  1211. X   #if INTENSIVE_DEBUG
  1212. X   sprintf( bwb_ebuf, "in inp_const(): received argument <%s>.",
  1213. X      &( m_buffer[ *position ] ) );
  1214. X   bwb_debug( bwb_ebuf );
  1215. X   #endif
  1216. X
  1217. X   string = FALSE;
  1218. X
  1219. X   /* first detect string constant */
  1220. X
  1221. X   if ( m_buffer[ *position ] == '\"' )
  1222. X      {
  1223. X      string = TRUE;
  1224. X      ++( *position );
  1225. X      }
  1226. X   else
  1227. X      {
  1228. X      string = FALSE;
  1229. X      }
  1230. X
  1231. X   /* build the constant string */
  1232. X
  1233. X   s_buffer[ 0 ] = '\0';
  1234. X   s_pos = 0;
  1235. X   loop = TRUE;
  1236. X
  1237. X   while ( loop == TRUE )
  1238. X      {
  1239. X
  1240. X      switch ( m_buffer[ *position ] )
  1241. X         {
  1242. X         case '\0':                     /* end of string */
  1243. X         case '\n':
  1244. X         case '\r':
  1245. X            return TRUE;
  1246. X         case ' ':                      /* whitespace */
  1247. X         case '\t':
  1248. X         case ',':                      /* or end of argument */
  1249. X            if ( string == FALSE )
  1250. X               {
  1251. X               return TRUE;
  1252. X               }
  1253. X            else
  1254. X               {
  1255. X               s_buffer[ s_pos ] = m_buffer[ *position ];
  1256. X               ++( *position );
  1257. X               ++s_buffer;
  1258. X               s_buffer[ s_pos ] = '\0';
  1259. X               }
  1260. X            break;
  1261. X         case '\"':
  1262. X            if ( string == TRUE )
  1263. X               {
  1264. X               ++( *position );                 /* advance beyond quotation mark */
  1265. X               inp_adv( m_buffer, position );
  1266. X               return TRUE;
  1267. X               }
  1268. X            else
  1269. X               {
  1270. X               #if PROG_ERRORS
  1271. X               sprintf( bwb_ebuf, "Unexpected character in numerical constant." );
  1272. X               bwb_error( bwb_ebuf );
  1273. X               #else
  1274. X               bwb_error( err_syntax );
  1275. X               #endif
  1276. X               return FALSE;
  1277. X               }
  1278. X         default:
  1279. X            s_buffer[ s_pos ] = m_buffer[ *position ];
  1280. X            ++( *position );
  1281. X            ++s_buffer;
  1282. X            s_buffer[ s_pos ] = '\0';
  1283. X            break;
  1284. X         }
  1285. X
  1286. X      }
  1287. X
  1288. X   return NULL;
  1289. X
  1290. X   }
  1291. X
  1292. X/***************************************************************
  1293. X
  1294. X        FUNCTION:       bwb_line()
  1295. X
  1296. X        DESCRIPTION:    This function implements the BASIC LINE
  1297. X                        INPUT statement.
  1298. X
  1299. X        SYNTAX:         LINE INPUT
  1300. X
  1301. X***************************************************************/
  1302. X
  1303. Xstruct bwb_line *
  1304. Xbwb_line( struct bwb_line *l )
  1305. X   {
  1306. X   int dev_no;
  1307. X   struct bwb_variable *v;
  1308. X   FILE *inp_device;
  1309. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1310. X
  1311. X   /* assign default values */
  1312. X
  1313. X   inp_device = stdin;
  1314. X   l->next->position = 0;
  1315. X
  1316. X   /* advance to first element (INPUT statement) */
  1317. X
  1318. X   adv_element( l->buffer, &( l->position ), tbuf );
  1319. X   bwb_strtoupper( tbuf );
  1320. X   if ( strcmp( tbuf, "INPUT" ) != 0 )
  1321. X      {
  1322. X      bwb_error( err_syntax );
  1323. X      return l->next;
  1324. X      }
  1325. X   adv_ws( l->buffer, &( l->position ) );
  1326. X
  1327. X   /* check for semicolon in first position */
  1328. X
  1329. X   if ( l->buffer[ l->position ] == ';' )
  1330. X      {
  1331. X      ++l->position;
  1332. X      adv_ws( l->buffer, &( l->position ) );
  1333. X      }
  1334. X
  1335. X   /* else check for # for file number in first position */
  1336. X
  1337. X   else if ( l->buffer[ l->position ] == '#' )
  1338. X      {
  1339. X      ++l->position;
  1340. X      adv_element( l->buffer, &( l->position ), tbuf );
  1341. X      adv_ws( l->buffer, &( l->position ));
  1342. X      dev_no = atoi( tbuf );
  1343. X
  1344. X      #if INTENSIVE_DEBUG
  1345. X      sprintf( bwb_ebuf, "in bwb_line(): file number requested <%d>", dev_no );
  1346. X      bwb_debug( bwb_ebuf );
  1347. X      #endif
  1348. X
  1349. X      if ( dev_table[ dev_no ].cfp == NULL )
  1350. X         {
  1351. X         bwb_error( err_dev );
  1352. X         return l->next;
  1353. X         }
  1354. X      else
  1355. X         {
  1356. X         inp_device = dev_table[ dev_no ].cfp;
  1357. X         }
  1358. X      }
  1359. X
  1360. X   /* check for comma */
  1361. X
  1362. X   if ( l->buffer[ l->position ] == ',' )
  1363. X      {
  1364. X      ++( l->position );
  1365. X      adv_ws( l->buffer, &( l->position ));
  1366. X      }
  1367. X
  1368. X   /* check for quotation mark indicating prompt */
  1369. X
  1370. X   if ( l->buffer[ l->position ] == '\"' )
  1371. X      {
  1372. X      inp_const( l->buffer, tbuf, &( l->position ) );
  1373. X      xprintf( stdout, tbuf );
  1374. X      }
  1375. X
  1376. X   /* read the variable for assignment */
  1377. X
  1378. X   #if INTENSIVE_DEBUG
  1379. X   sprintf( bwb_ebuf, "in bwb_line(): tbuf <%s>", 
  1380. X      tbuf );
  1381. X   bwb_debug( bwb_ebuf );
  1382. X   sprintf( bwb_ebuf, "in bwb_line(): line buffer <%s>", 
  1383. X      &( l->buffer[ l->position ] ) );
  1384. X   bwb_debug( bwb_ebuf );
  1385. X   #endif
  1386. X
  1387. X   adv_element( l->buffer, &( l->position ), tbuf );
  1388. X
  1389. X   #if INTENSIVE_DEBUG
  1390. X   sprintf( bwb_ebuf, "in bwb_line(): variable buffer <%s>", tbuf );
  1391. X   bwb_debug( bwb_ebuf );
  1392. X   #endif
  1393. X   v = var_find( tbuf );
  1394. X   if ( v->type != STRING )
  1395. X      {
  1396. X      #if PROG_ERRORS
  1397. X      bwb_error( "in bwb_line(): String variable required" );
  1398. X      #else
  1399. X      bwb_error( err_syntax );
  1400. X      #endif
  1401. X      return l->next;
  1402. X      }
  1403. X
  1404. X   #if INTENSIVE_DEBUG
  1405. X   sprintf( bwb_ebuf, "in bwb_line(): variable for assignment <%s>", v->name );
  1406. X   bwb_debug( bwb_ebuf );
  1407. X   #endif
  1408. X
  1409. X   /* read a line of text into the bufffer */
  1410. X
  1411. X   fgets( tbuf, MAXSTRINGSIZE, inp_device );
  1412. X   bwb_stripcr( tbuf );
  1413. X   str_ctob( var_findsval( v, v->array_pos ), tbuf );
  1414. X
  1415. X   /* end: return next line */
  1416. X
  1417. X   return l->next;
  1418. X   }
  1419. X
  1420. END_OF_FILE
  1421.   if test 35414 -ne `wc -c <'bwb_inp.c'`; then
  1422.     echo shar: \"'bwb_inp.c'\" unpacked with wrong size!
  1423.   fi
  1424.   # end of 'bwb_inp.c'
  1425. fi
  1426. if test -f 'bwb_tbl.c' -a "${1}" != "-c" ; then 
  1427.   echo shar: Will not clobber existing file \"'bwb_tbl.c'\"
  1428. else
  1429.   echo shar: Extracting \"'bwb_tbl.c'\" \(6014 characters\)
  1430.   sed "s/^X//" >'bwb_tbl.c' <<'END_OF_FILE'
  1431. X/***************************************************************
  1432. X
  1433. X        bwb_tbl.c       Command Table
  1434. X                        for Bywater BASIC Interpreter
  1435. X
  1436. X                        Copyright (c) 1992, Ted A. Campbell
  1437. X
  1438. X                        Bywater Software
  1439. X                        P. O. Box 4023
  1440. X                        Duke Station
  1441. X                        Durham, NC  27706
  1442. X
  1443. X                        email: tcamp@acpub.duke.edu
  1444. X
  1445. X        Copyright and Permissions Information:
  1446. X
  1447. X        All U.S. and international copyrights are claimed by the
  1448. X        author. The author grants permission to use this code
  1449. X        and software based on it under the following conditions:
  1450. X        (a) in general, the code and software based upon it may be
  1451. X        used by individuals and by non-profit organizations; (b) it
  1452. X        may also be utilized by governmental agencies in any country,
  1453. X        with the exception of military agencies; (c) the code and/or
  1454. X        software based upon it may not be sold for a profit without
  1455. X        an explicit and specific permission from the author, except
  1456. X        that a minimal fee may be charged for media on which it is
  1457. X        copied, and for copying and handling; (d) the code must be
  1458. X        distributed in the form in which it has been released by the
  1459. X        author; and (e) the code and software based upon it may not
  1460. X        be used for illegal activities.
  1461. X
  1462. X***************************************************************/
  1463. X
  1464. X#include <stdio.h>
  1465. X#include <stdlib.h>
  1466. X
  1467. X#include "bwbasic.h"
  1468. X#include "bwb_mes.h"
  1469. X
  1470. Xint err_line = 0;            /* line in which error occurred */
  1471. Xint err_number = 0;            /* number of last error */
  1472. X
  1473. X/***************************************************************
  1474. X
  1475. X        Command Table for Bywater BASIC
  1476. X
  1477. X***************************************************************/
  1478. X
  1479. Xstruct bwb_command bwb_cmdtable[ COMMANDS ] =
  1480. X   {
  1481. X
  1482. X      #if PERMANENT_DEBUG
  1483. X      { "VARS",         bwb_vars,        2 },
  1484. X      { "CMDS",         bwb_cmds,        2 },
  1485. X      { "FNCS",         bwb_fncs,        2 },
  1486. X      #endif
  1487. X
  1488. X      #if DIRECTORY_CMDS
  1489. X      { "CHDIR",        bwb_chdir,       2 },
  1490. X      { "MKDIR",        bwb_mkdir,       2 },
  1491. X      { "RMDIR",        bwb_rmdir,       2 },
  1492. X      #endif
  1493. X
  1494. X      { "SYSTEM",       bwb_system,      2 },
  1495. X      { "REM",          bwb_rem,         2 },
  1496. X      { "LET",          bwb_let,         2 },
  1497. X      { "LIST",         bwb_list,        2 },
  1498. X      { "LOAD",         bwb_load,        2 },
  1499. X      { "MERGE",        bwb_merge,       2 },
  1500. X      { "CHAIN",        bwb_chain,       2 },
  1501. X      { "COMMON",       bwb_common,      2 },
  1502. X      { "RUN",          bwb_run,         2 },
  1503. X      { "PRINT",        bwb_print,       2 },
  1504. X      { "SAVE",         bwb_save,        2 },
  1505. X      { "INPUT",        bwb_input,       2 },
  1506. X      { "GOTO",         bwb_goto,        2 },
  1507. X      { "GOSUB",        bwb_gosub,       2 },
  1508. X      { "RETURN",       bwb_return,      2 },
  1509. X      { "ERROR",        bwb_lerror,      2 },
  1510. X      { "ON",           bwb_on,          2 },
  1511. X      { "IF",           bwb_if,          2 },
  1512. X      { "WHILE",        bwb_while,       2 },
  1513. X      { "WEND",         bwb_wend,        2 },
  1514. X      { "WRITE",        bwb_write,       2 },
  1515. X      { "WIDTH",        bwb_width,       2 },
  1516. X      { "TRON",         bwb_tron,        2 },
  1517. X      { "TROFF",        bwb_troff,       2 },
  1518. X      { "END",          bwb_xend,        2 },
  1519. X      { "NEW",          bwb_new,         2 },
  1520. X      { "DELETE",       bwb_delete,      2 },
  1521. X      { "FOR",          bwb_for,         2 },
  1522. X      { "NEXT",         bwb_next,        2 },
  1523. X      { "RANDOMIZE",    bwb_randomize,   2 },
  1524. X      { "STOP",         bwb_stop,        2 },
  1525. X      { "DATA",         bwb_data,        2 },
  1526. X      { "READ",         bwb_read,        2 },
  1527. X      { "RESTORE",      bwb_restore,     2 },
  1528. X      { "DIM",          bwb_dim,         2 },
  1529. X      { "OPTION",       bwb_option,      2 },
  1530. X      { "OPEN",         bwb_open,        2 },
  1531. X      { "CLOSE",        bwb_close,       2 },
  1532. X      { "GET",          bwb_get,         2 },
  1533. X      { "PUT",          bwb_put,         2 },
  1534. X      { "KILL",         bwb_kill,        2 },
  1535. X      { "NAME",         bwb_name,        2 },
  1536. X      { "LSET",         bwb_lset,        2 },
  1537. X      { "RSET",         bwb_rset,        2 },
  1538. X      { "FIELD",        bwb_field,       2 },
  1539. X      { "LINE",         bwb_line,        2 },
  1540. X      { "DEFDBL",       bwb_ddbl,        2 },
  1541. X      { "DEFINT",       bwb_dint,        2 },
  1542. X      { "DEFSNG",       bwb_dsng,        2 },
  1543. X      { "DEFSTR",       bwb_dstr,        2 },
  1544. X      { "DEF",          bwb_deffn,       2 },
  1545. X      { "CLEAR",        bwb_clear,       2 },
  1546. X      { "ERASE",        bwb_erase,       2 },
  1547. X      { "ENVIRON",      bwb_environ,     2 },
  1548. X      { "SWAP",         bwb_swap,        2 }
  1549. X   };
  1550. X
  1551. X/* Error messages used more than once */
  1552. X
  1553. Xchar err_openfile[] =   ERR_OPENFILE;
  1554. Xchar err_getmem[] =     ERR_GETMEM;
  1555. Xchar err_noln[] =       ERR_NOLN;
  1556. Xchar err_nofn[] =       ERR_NOFN;
  1557. Xchar err_lnnotfound[] = ERR_LNNOTFOUND;
  1558. Xchar err_incomplete[] = ERR_INCOMPLETE;
  1559. Xchar err_valoorange[] = ERR_VALOORANGE;
  1560. Xchar err_syntax[] =     ERR_SYNTAX;
  1561. Xchar err_devnum[] =     ERR_DEVNUM;
  1562. Xchar err_dev[] =        ERR_DEV;
  1563. Xchar err_opsys[] =    ERR_OPSYS;
  1564. Xchar err_argstr[] =     ERR_ARGSTR;
  1565. Xchar err_defchar[] =     ERR_DEFCHAR;
  1566. Xchar err_mismatch[] =    ERR_MISMATCH;
  1567. Xchar err_dimnotarray[] =ERR_DIMNOTARRAY;
  1568. Xchar err_od[] =         ERR_OD;
  1569. Xchar err_overflow[] =   ERR_OVERFLOW;
  1570. Xchar err_nf[] =         ERR_NF;
  1571. Xchar err_uf[] =         ERR_UF;
  1572. Xchar err_dbz[] =        ERR_DBZ;
  1573. Xchar err_redim[] =      ERR_REDIM;
  1574. Xchar err_obdim[] =      ERR_OBDIM;
  1575. Xchar err_uc[] =     ERR_UC;
  1576. X
  1577. X/* error table */
  1578. X
  1579. Xchar *err_table[ N_ERRORS ] = 
  1580. X   {
  1581. X   err_openfile,
  1582. X   err_getmem,
  1583. X   err_noln,
  1584. X   err_nofn,
  1585. X   err_lnnotfound,
  1586. X   err_incomplete,
  1587. X   err_valoorange,
  1588. X   err_syntax,
  1589. X   err_devnum,
  1590. X   err_dev,
  1591. X   err_opsys,
  1592. X   err_argstr,
  1593. X   err_defchar,
  1594. X   err_mismatch,
  1595. X   err_dimnotarray,
  1596. X   err_od,
  1597. X   err_overflow,
  1598. X   err_nf,
  1599. X   err_uf,
  1600. X   err_dbz,
  1601. X   err_redim,
  1602. X   err_obdim,
  1603. X   err_uc 
  1604. X   };
  1605. X
  1606. END_OF_FILE
  1607.   if test 6014 -ne `wc -c <'bwb_tbl.c'`; then
  1608.     echo shar: \"'bwb_tbl.c'\" unpacked with wrong size!
  1609.   fi
  1610.   # end of 'bwb_tbl.c'
  1611. fi
  1612. echo shar: End of archive 8 \(of 11\).
  1613. cp /dev/null ark8isdone
  1614. MISSING=""
  1615. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1616.     if test ! -f ark${I}isdone ; then
  1617.     MISSING="${MISSING} ${I}"
  1618.     fi
  1619. done
  1620. if test "${MISSING}" = "" ; then
  1621.     echo You have unpacked all 11 archives.
  1622.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1623. else
  1624.     echo You still must unpack the following archives:
  1625.     echo "        " ${MISSING}
  1626. fi
  1627. exit 0
  1628. exit 0 # Just in case...
  1629.