home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume40 / bwbasic / part05 < prev    next >
Encoding:
Text File  |  1993-10-29  |  70.7 KB  |  3,033 lines

  1. Newsgroups: comp.sources.misc
  2. From: tcamp@delphi.com (Ted A. Campbell)
  3. Subject: v40i056:  bwbasic - Bywater BASIC interpreter version 2.10, Part05/15
  4. Message-ID: <1993Oct29.162526.3621@sparky.sterling.com>
  5. X-Md4-Signature: 566d0d46e45811cba897caa8e83a7cd1
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 29 Oct 1993 16:25:26 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: tcamp@delphi.com (Ted A. Campbell)
  12. Posting-number: Volume 40, Issue 56
  13. Archive-name: bwbasic/part05
  14. Environment: UNIX, DOS
  15. Supersedes: bwbasic: Volume 33, Issue 37-47
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  bwbasic-2.10/bwb_var.c bwbasic-2.10/bwbtest/writeinp.bas
  22. #   bwbasic-2.10/bwx_iqc.c
  23. # Wrapped by kent@sparky on Thu Oct 21 10:47:49 1993
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 5 (of 15)."'
  27. if test -f 'bwbasic-2.10/bwb_var.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwb_var.c'\"
  29. else
  30.   echo shar: Extracting \"'bwbasic-2.10/bwb_var.c'\" \(50907 characters\)
  31.   sed "s/^X//" >'bwbasic-2.10/bwb_var.c' <<'END_OF_FILE'
  32. X/***************************************************************
  33. X
  34. X        bwb_var.c       Variable-Handling Routines
  35. X                        for Bywater BASIC Interpreter
  36. X
  37. X                        Commands:    DIM
  38. X                                        COMMON
  39. X                                        ERASE
  40. X                                        SWAP
  41. X                    CLEAR
  42. X
  43. X                        Copyright (c) 1993, Ted A. Campbell
  44. X                        Bywater Software
  45. X
  46. X                        email: tcamp@delphi.com
  47. X
  48. X        Copyright and Permissions Information:
  49. X
  50. X        All U.S. and international rights are claimed by the author,
  51. X        Ted A. Campbell.
  52. X
  53. X    This software is released under the terms of the GNU General
  54. X    Public License (GPL), which is distributed with this software
  55. X    in the file "COPYING".  The GPL specifies the terms under
  56. X    which users may copy and use the software in this distribution.
  57. X
  58. X    A separate license is available for commercial distribution,
  59. X    for information on which you should contact the author.
  60. X
  61. X***************************************************************/
  62. X
  63. X#include <stdio.h>
  64. X#include <ctype.h>
  65. X#include <math.h>
  66. X
  67. X#include "bwbasic.h"
  68. X#include "bwb_mes.h"
  69. X
  70. Xint dim_base = 0;                            /* set by OPTION BASE */
  71. Xstatic int dimmed = FALSE;                      /* has DIM been called? */
  72. Xstatic int first, last;                /* first, last for DEFxxx commands */
  73. X
  74. X/* Prototypes for functions visible to this file only */
  75. X
  76. X#if ANSI_C
  77. Xstatic int dim_check( struct bwb_variable *v, int *pp );
  78. Xstatic int var_defx( struct bwb_line *l, int type );
  79. Xstatic int var_letseq( char *buffer, int *position, int *start, int *end );
  80. Xstatic size_t dim_unit( struct bwb_variable *v, int *pp );
  81. X#else
  82. Xstatic int dim_check();
  83. Xstatic int var_defx();
  84. Xstatic int var_letseq();
  85. Xstatic size_t dim_unit();
  86. X#endif
  87. X
  88. X/***************************************************************
  89. X
  90. X        FUNCTION:       var_init()
  91. X
  92. X        DESCRIPTION:    This function initializes the internal
  93. X            linked list of variables.
  94. X
  95. X***************************************************************/
  96. X
  97. X#if ANSI_C
  98. Xint
  99. Xvar_init( int task )
  100. X#else
  101. Xint
  102. Xvar_init( task )
  103. X   int task;
  104. X#endif
  105. X   {
  106. X   LOCALTASK var_start.next = &(LOCALTASK var_end);
  107. X   strcpy( LOCALTASK var_start.name, "<START>" );
  108. X   strcpy( LOCALTASK var_end.name, "<END>" );
  109. X   return TRUE;
  110. X   }
  111. X
  112. X#if COMMON_CMDS
  113. X
  114. X/***************************************************************
  115. X
  116. X        FUNCTION:       bwb_common()
  117. X
  118. X        DESCRIPTION:    This C function implements the BASIC
  119. X                COMMON command.
  120. X
  121. X    SYNTAX:        COMMON variable [, variable...]
  122. X
  123. X***************************************************************/
  124. X
  125. X#if ANSI_C
  126. Xstruct bwb_line *
  127. Xbwb_common( struct bwb_line *l )
  128. X#else
  129. Xstruct bwb_line *
  130. Xbwb_common( l )
  131. X   struct bwb_line *l;
  132. X#endif
  133. X   {
  134. X   register int loop;
  135. X   struct bwb_variable *v;
  136. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  137. X
  138. X   /* loop while arguments are available */
  139. X
  140. X   loop = TRUE;
  141. X   while ( loop == TRUE )
  142. X      {
  143. X
  144. X      /* get variable name and find variable */
  145. X
  146. X      bwb_getvarname( l->buffer, tbuf, &( l->position ) );
  147. X
  148. X      if ( ( v = var_find( tbuf ) ) == NULL )
  149. X         {
  150. X         bwb_error( err_syntax );
  151. X         return bwb_zline( l );
  152. X         }
  153. X
  154. X      v->common = TRUE;                /* set common flag to true */
  155. X
  156. X      /* check for comma */
  157. X
  158. X      adv_ws( l->buffer, &( l->position ) );
  159. X      if ( l->buffer[ l->position ] != ',' )
  160. X         {
  161. X         return bwb_zline( l );                /* no comma; leave */
  162. X         }
  163. X      ++( l->position );
  164. X      adv_ws( l->buffer, &( l->position ) );
  165. X
  166. X      }
  167. X
  168. X   return bwb_zline( l );
  169. X
  170. X   }
  171. X
  172. X/***********************************************************
  173. X
  174. X        FUNCTION:    bwb_erase()
  175. X
  176. X    DESCRIPTION:    This C function implements the BASIC
  177. X            ERASE command.
  178. X
  179. X    SYNTAX:        ERASE variable[, variable]...
  180. X
  181. X***********************************************************/
  182. X
  183. X#if ANSI_C
  184. Xstruct bwb_line *
  185. Xbwb_erase( struct bwb_line *l )
  186. X#else
  187. Xstruct bwb_line *
  188. Xbwb_erase( l )
  189. X   struct bwb_line *l;
  190. X#endif
  191. X   {
  192. X   register int loop;
  193. X   struct bwb_variable *v;
  194. X   struct bwb_variable *p;        /* previous variable in linked list */
  195. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  196. X
  197. X   /* loop while arguments are available */
  198. X
  199. X   loop = TRUE;
  200. X   while ( loop == TRUE )
  201. X      {
  202. X
  203. X      /* get variable name and find variable */
  204. X
  205. X      bwb_getvarname( l->buffer, tbuf, &( l->position ) );
  206. X
  207. X      if ( ( v = var_find( tbuf ) ) == NULL )
  208. X         {
  209. X         bwb_error( err_syntax );
  210. X         return bwb_zline( l );
  211. X         }
  212. X
  213. X      /* be sure the variable is dimensioned */
  214. X
  215. X      if (( v->dimensions < 1 ) || ( v->array_sizes[ 0 ] < 1 ))
  216. X     {
  217. X     bwb_error( err_dimnotarray );
  218. X     return bwb_zline( l );
  219. X         }
  220. X
  221. X      /* find previous variable in chain */
  222. X
  223. X      for ( p = &CURTASK var_start; p->next != v; p = p->next )
  224. X         {
  225. X         ;
  226. X         }
  227. X
  228. X      /* reassign linkage */
  229. X
  230. X      p->next = v->next;
  231. X
  232. X      /* deallocate memory */
  233. X
  234. X      free( v->array_sizes );
  235. X      free( v->array_pos );
  236. X      if ( v->type == NUMBER )
  237. X     {
  238. X     free( v->memnum );
  239. X     }
  240. X      else
  241. X     {
  242. X     free( v->memstr );
  243. X     }
  244. X      free( v );
  245. X
  246. X      /* check for comma */
  247. X
  248. X      adv_ws( l->buffer, &( l->position ) );
  249. X      if ( l->buffer[ l->position ] != ',' )
  250. X         {
  251. X         return bwb_zline( l );                /* no comma; leave */
  252. X         }
  253. X      ++( l->position );
  254. X      adv_ws( l->buffer, &( l->position ) );
  255. X
  256. X      }
  257. X
  258. X   return bwb_zline( l );
  259. X
  260. X   }
  261. X
  262. X/***********************************************************
  263. X
  264. X        FUNCTION:    bwb_swap()
  265. X
  266. X    DESCRIPTION:    This C function implements the BASIC
  267. X            SWAP command.
  268. X
  269. X    SYNTAX:        SWAP variable, variable
  270. X
  271. X***********************************************************/
  272. X
  273. X#if ANSI_C
  274. Xstruct bwb_line *
  275. Xbwb_swap( struct bwb_line *l )
  276. X#else
  277. Xstruct bwb_line *
  278. Xbwb_swap( l )
  279. X   struct bwb_line *l;
  280. X#endif
  281. X   {
  282. X   struct bwb_variable tmp;                     /* temp holder */
  283. X   struct bwb_variable *lhs, *rhs;        /* left and right- hand side of swap statement */
  284. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  285. X
  286. X#if INTENSIVE_DEBUG
  287. X   sprintf( bwb_ebuf, "in bwb_swap(): buffer is <%s>",
  288. X      &( l->buffer[ l->position ] ) );
  289. X   bwb_debug( bwb_ebuf );
  290. X#endif
  291. X
  292. X   /* get left variable name and find variable */
  293. X
  294. X   bwb_getvarname( l->buffer, tbuf, &( l->position ) );
  295. X
  296. X#if INTENSIVE_DEBUG
  297. X   sprintf( bwb_ebuf, "in bwb_swap(): tbuf is <%s>", tbuf );
  298. X   bwb_debug( bwb_ebuf );
  299. X#endif
  300. X
  301. X   if ( ( lhs = var_find( tbuf ) ) == NULL )
  302. X      {
  303. X      bwb_error( err_syntax );
  304. X      return bwb_zline( l );
  305. X      }
  306. X
  307. X#if INTENSIVE_DEBUG
  308. X   sprintf( bwb_ebuf, "in bwb_swap(): lhs variable <%s> found",
  309. X      lhs->name );
  310. X   bwb_debug( bwb_ebuf );
  311. X#endif
  312. X
  313. X   /* check for comma */
  314. X
  315. X   adv_ws( l->buffer, &( l->position ) );
  316. X   if ( l->buffer[ l->position ] != ',' )
  317. X      {
  318. X      bwb_error( err_syntax );
  319. X      return bwb_zline( l );
  320. X      }
  321. X   ++( l->position );
  322. X   adv_ws( l->buffer, &( l->position ) );
  323. X
  324. X   /* get right variable name */
  325. X
  326. X#if INTENSIVE_DEBUG
  327. X   sprintf( bwb_ebuf, "in bwb_swap(): buffer is now <%s>",
  328. X      &( l->buffer[ l->position ] ) );
  329. X   bwb_debug( bwb_ebuf );
  330. X#endif
  331. X
  332. X   bwb_getvarname( l->buffer, tbuf, &( l->position ) );
  333. X
  334. X#if INTENSIVE_DEBUG
  335. X   sprintf( bwb_ebuf, "in bwb_swap(): tbuf is <%s>", tbuf );
  336. X   bwb_debug( bwb_ebuf );
  337. X#endif
  338. X
  339. X   if ( ( rhs = var_find( tbuf ) ) == NULL )
  340. X      {
  341. X      bwb_error( err_syntax );
  342. X      return bwb_zline( l );
  343. X      }
  344. X
  345. X   /* check to be sure that both variables are of the same type */
  346. X
  347. X   if ( rhs->type != lhs->type )
  348. X      {
  349. X      bwb_error( err_mismatch );
  350. X      return bwb_zline( l );
  351. X      }
  352. X
  353. X   /* copy lhs to temp, rhs to lhs, then temp to rhs */
  354. X
  355. X   if ( lhs->type == NUMBER )
  356. X      {
  357. X      tmp.memnum = lhs->memnum;
  358. X      }
  359. X   else
  360. X      {
  361. X      tmp.memstr = lhs->memstr;
  362. X      }
  363. X   tmp.array_sizes = lhs->array_sizes;
  364. X   tmp.array_units = lhs->array_units;
  365. X   tmp.array_pos = lhs->array_pos;
  366. X   tmp.dimensions = lhs->dimensions;
  367. X
  368. X   if ( lhs->type == NUMBER )
  369. X      {
  370. X      lhs->memnum = rhs->memnum;
  371. X      }
  372. X   else
  373. X      {
  374. X      lhs->memstr = rhs->memstr;
  375. X      }
  376. X   lhs->array_sizes = rhs->array_sizes;
  377. X   lhs->array_units = rhs->array_units;
  378. X   lhs->array_pos = rhs->array_pos;
  379. X   lhs->dimensions = rhs->dimensions;
  380. X
  381. X   if ( lhs->type = NUMBER )
  382. X      {
  383. X      rhs->memnum = tmp.memnum;
  384. X      }
  385. X   else
  386. X      {
  387. X      rhs->memstr = tmp.memstr;
  388. X      }
  389. X   rhs->array_sizes = tmp.array_sizes;
  390. X   rhs->array_units = tmp.array_units;
  391. X   rhs->array_pos = tmp.array_pos;
  392. X   rhs->dimensions = tmp.dimensions;
  393. X
  394. X   /* return */
  395. X
  396. X   return bwb_zline( l );
  397. X
  398. X   }
  399. X
  400. X#endif                /* COMMON_CMDS */
  401. X
  402. X/***********************************************************
  403. X
  404. X        FUNCTION:    bwb_clear()
  405. X
  406. X    DESCRIPTION:    This C function implements the BASIC
  407. X            CLEAR command.
  408. X
  409. X    SYNTAX:        CLEAR
  410. X
  411. X***********************************************************/
  412. X
  413. X#if ANSI_C
  414. Xstruct bwb_line *
  415. Xbwb_clear( struct bwb_line *l )
  416. X#else
  417. Xstruct bwb_line *
  418. Xbwb_clear( l )
  419. X   struct bwb_line *l;
  420. X#endif
  421. X   {
  422. X   struct bwb_variable *v;
  423. X   register int n;
  424. X   bstring *sp;
  425. X   bnumber *np;
  426. X
  427. X   for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next )
  428. X      {
  429. X      if ( v->preset != TRUE )
  430. X         {
  431. X         switch( v->type )
  432. X            {
  433. X            case NUMBER:
  434. X           np = v->memnum;
  435. X           for ( n = 0; n < (int) v->array_units; ++n )
  436. X          {
  437. X          np[ n ] = (bnumber) 0.0;
  438. X          }
  439. X           break;
  440. X        case STRING:
  441. X           sp = v->memstr;
  442. X               for ( n = 0; n < (int) v->array_units; ++n )
  443. X                  {
  444. X          if ( sp[ n ].sbuffer != NULL )
  445. X             {
  446. X             free( sp[ n ].sbuffer );
  447. X             sp[ n ].sbuffer = NULL;
  448. X                     }
  449. X                  sp[ n ].rab = FALSE;
  450. X                  sp[ n ].length = 0;
  451. X                  }
  452. X               break;
  453. X            }
  454. X         }
  455. X      }
  456. X
  457. X   return bwb_zline( l );
  458. X
  459. X   }
  460. X
  461. X/***********************************************************
  462. X
  463. X    FUNCTION:       var_delcvars()
  464. X
  465. X    DESCRIPTION:    This function deletes all variables
  466. X            in memory except those previously marked
  467. X            as common.
  468. X
  469. X***********************************************************/
  470. X
  471. X#if ANSI_C
  472. Xint
  473. Xvar_delcvars( void )
  474. X#else
  475. Xint
  476. Xvar_delcvars()
  477. X#endif
  478. X   {
  479. X   struct bwb_variable *v;
  480. X   struct bwb_variable *p;        /* previous variable */
  481. X
  482. X   p = &CURTASK var_start;
  483. X   for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next )
  484. X      {
  485. X
  486. X      if ( v->common != TRUE )
  487. X         {
  488. X
  489. X         /* if the variable is dimensioned, release allocated memory */
  490. X
  491. X         if ( v->dimensions > 0 )
  492. X            {
  493. X
  494. X            /* deallocate memory */
  495. X
  496. X            free( v->array_sizes );
  497. X            free( v->array_pos );
  498. X        if ( v->type == NUMBER )
  499. X           {
  500. X           free( v->memnum );
  501. X           }
  502. X        else
  503. X           {
  504. X           free( v->memstr );
  505. X           }
  506. X            }
  507. X
  508. X         /* reassign linkage */
  509. X
  510. X         p->next = v->next;
  511. X
  512. X         /* deallocate the variable itself */
  513. X
  514. X         free( v );
  515. X
  516. X         }
  517. X
  518. X      /* else reset previous variable */
  519. X
  520. X      else
  521. X         {
  522. X         p = v;
  523. X         }
  524. X
  525. X      }
  526. X
  527. X   return TRUE;
  528. X
  529. X   }
  530. X
  531. X#if MS_CMDS
  532. X
  533. X/***********************************************************
  534. X
  535. X        FUNCTION:    bwb_ddbl()
  536. X
  537. X    DESCRIPTION:    This function implements the BASIC
  538. X            DEFDBL command.
  539. X
  540. X    SYNTAX:        DEFDBL letter[-letter](, letter[-letter])...
  541. X
  542. X***********************************************************/
  543. X
  544. X#if ANSI_C
  545. Xstruct bwb_line *
  546. Xbwb_ddbl( struct bwb_line *l )
  547. X#else
  548. Xstruct bwb_line *
  549. Xbwb_ddbl( l )
  550. X   struct bwb_line *l;
  551. X#endif
  552. X   {
  553. X
  554. X   /* call generalized DEF handler with DOUBLE set */
  555. X
  556. X   var_defx( l, NUMBER );
  557. X
  558. X   return bwb_zline( l );
  559. X
  560. X   }
  561. X
  562. X/***********************************************************
  563. X
  564. X        FUNCTION:    bwb_dint()
  565. X
  566. X    DESCRIPTION:    This function implements the BASIC
  567. X            DEFINT command.
  568. X
  569. X    SYNTAX:        DEFINT letter[-letter](, letter[-letter])...
  570. X
  571. X***********************************************************/
  572. X
  573. X#if ANSI_C
  574. Xstruct bwb_line *
  575. Xbwb_dint( struct bwb_line *l )
  576. X#else
  577. Xstruct bwb_line *
  578. Xbwb_dint( l )
  579. X   struct bwb_line *l;
  580. X#endif
  581. X   {
  582. X
  583. X   /* call generalized DEF handler with INTEGER set */
  584. X
  585. X   var_defx( l, NUMBER );
  586. X
  587. X   return bwb_zline( l );
  588. X
  589. X   }
  590. X
  591. X/***********************************************************
  592. X
  593. X        FUNCTION:    bwb_dsng()
  594. X
  595. X    DESCRIPTION:    This function implements the BASIC
  596. X            DEFSNG command.
  597. X
  598. X    SYNTAX:        DEFSNG letter[-letter](, letter[-letter])...
  599. X
  600. X***********************************************************/
  601. X
  602. X#if ANSI_C
  603. Xstruct bwb_line *
  604. Xbwb_dsng( struct bwb_line *l )
  605. X#else
  606. Xstruct bwb_line *
  607. Xbwb_dsng( l )
  608. X   struct bwb_line *l;
  609. X#endif
  610. X   {
  611. X
  612. X   /* call generalized DEF handler with SINGLE set */
  613. X
  614. X   var_defx( l, NUMBER );
  615. X
  616. X   return bwb_zline( l );
  617. X
  618. X   }
  619. X
  620. X/***********************************************************
  621. X
  622. X        FUNCTION:    bwb_dstr()
  623. X
  624. X    DESCRIPTION:    This function implements the BASIC
  625. X            DEFSTR command.
  626. X
  627. X    SYNTAX:        DEFSTR letter[-letter](, letter[-letter])...
  628. X
  629. X***********************************************************/
  630. X
  631. X#if ANSI_C
  632. Xstruct bwb_line *
  633. Xbwb_dstr( struct bwb_line *l )
  634. X#else
  635. Xstruct bwb_line *
  636. Xbwb_dstr( l )
  637. X   struct bwb_line *l;
  638. X#endif
  639. X   {
  640. X
  641. X   /* call generalized DEF handler with STRING set */
  642. X
  643. X   var_defx( l, STRING );
  644. X
  645. X   return bwb_zline( l );
  646. X
  647. X   }
  648. X
  649. X/***********************************************************
  650. X
  651. X        Function:    var_defx()
  652. X
  653. X    DESCRIPTION:    This function is a generalized DEFxxx handler.
  654. X
  655. X***********************************************************/
  656. X
  657. X#if ANSI_C
  658. Xstatic int
  659. Xvar_defx( struct bwb_line *l, int type )
  660. X#else
  661. Xstatic int
  662. Xvar_defx( l, type )
  663. X   struct bwb_line *l;
  664. X   int type;
  665. X#endif
  666. X   {
  667. X   int loop;
  668. X   register int c;
  669. X   static char vname[ 2 ];
  670. X   struct bwb_variable *v;
  671. X
  672. X   /* loop while there are variable names to process */
  673. X
  674. X   loop = TRUE;
  675. X   while ( loop == TRUE )
  676. X      {
  677. X
  678. X      /* check for end of line or line segment */
  679. X
  680. X      adv_ws( l->buffer, &( l->position ) );
  681. X      switch( l->buffer[ l->position ] )
  682. X         {
  683. X         case '\n':
  684. X         case '\r':
  685. X         case '\0':
  686. X         case ':':
  687. X            return FALSE;
  688. X         }
  689. X
  690. X      /* find a sequence of letters for variables */
  691. X
  692. X      if ( var_letseq( l->buffer, &( l->position ), &first, &last ) == FALSE )
  693. X         {
  694. X         return FALSE;
  695. X         }
  696. X
  697. X      /* loop through the list getting variables */
  698. X
  699. X      for ( c = first; c <= last; ++c )
  700. X         {
  701. X         vname[ 0 ] = (char) c;
  702. X         vname[ 1 ] = '\0';
  703. X
  704. X#if INTENSIVE_DEBUG
  705. X         sprintf( bwb_ebuf, "in var_defx(): calling var_find() for <%s>",
  706. X            vname );
  707. X         bwb_debug( bwb_ebuf );
  708. X#endif
  709. X
  710. X         v = var_find( vname );
  711. X
  712. X         /* but var_find() assigns on the basis of name endings
  713. X            (so all in this case should be SINGLEs), so we must
  714. X            force the type of the variable */
  715. X
  716. X         var_make( v, type );
  717. X
  718. X         }
  719. X
  720. X      }
  721. X
  722. X   return TRUE;
  723. X
  724. X   }
  725. X
  726. X#endif                /* MS_CMDS */
  727. X
  728. X/***********************************************************
  729. X
  730. X        Function:    var_letseq()
  731. X
  732. X    DESCRIPTION:    This function finds a sequence of letters
  733. X            for a DEFxxx command.
  734. X
  735. X***********************************************************/
  736. X
  737. X#if ANSI_C
  738. Xstatic int
  739. Xvar_letseq( char *buffer, int *position, int *start, int *end )
  740. X#else
  741. Xstatic int
  742. Xvar_letseq( buffer, position, start, end )
  743. X   char *buffer;
  744. X   int *position;
  745. X   int *start;
  746. X   int *end;
  747. X#endif
  748. X   {
  749. X
  750. X#if INTENSIVE_DEBUG
  751. X   sprintf( bwb_ebuf, "in var_letseq(): buffer <%s>", &( buffer[ *position ] ));
  752. X   bwb_debug( bwb_ebuf );
  753. X#endif
  754. X
  755. X   /* advance beyond whitespace */
  756. X
  757. X   adv_ws( buffer, position );
  758. X
  759. X   /* check for end of line */
  760. X
  761. X   switch( buffer[ *position ] )
  762. X      {
  763. X      case '\0':
  764. X      case '\n':
  765. X      case '\r':
  766. X      case ':':
  767. X         return TRUE;
  768. X      }
  769. X
  770. X   /* character at this position must be a letter */
  771. X
  772. X   if ( isalpha( buffer[ *position ] ) == 0 )
  773. X      {
  774. X      bwb_error( err_defchar );
  775. X      return FALSE;
  776. X      }
  777. X
  778. X   *end = *start = buffer[ *position ];
  779. X
  780. X   /* advance beyond character and whitespace */
  781. X
  782. X   ++( *position );
  783. X   adv_ws( buffer, position );
  784. X
  785. X   /* check for hyphen, indicating sequence of more than one letter */
  786. X
  787. X   if ( buffer[ *position ] == '-' )
  788. X      {
  789. X
  790. X      ++( *position );
  791. X
  792. X      /* advance beyond whitespace */
  793. X
  794. X      adv_ws( buffer, position );
  795. X
  796. X      /* character at this position must be a letter */
  797. X
  798. X      if ( isalpha( buffer[ *position ] ) == 0 )
  799. X         {
  800. X         *end = *start;
  801. X         }
  802. X      else
  803. X         {
  804. X         *end = buffer[ *position ];
  805. X         ++( *position );
  806. X         }
  807. X
  808. X      }
  809. X
  810. X   /* advance beyond comma if present */
  811. X
  812. X   if ( buffer[ *position ] == ',' )
  813. X      {
  814. X      ++( *position );
  815. X      }
  816. X
  817. X   return TRUE;
  818. X   }
  819. X
  820. X/***********************************************************
  821. X
  822. X    FUNCTION:       bwb_const()
  823. X
  824. X    DESCRIPTION:    This function takes the string in lb
  825. X            (the large buffer), finds a string constant
  826. X            (beginning and ending with quotation marks),
  827. X            and returns it in sb (the small buffer),
  828. X            appropriately incrementing the integer
  829. X            pointed to by n. The string in lb should NOT
  830. X            include the initial quotation mark.
  831. X
  832. X***********************************************************/
  833. X
  834. X#if ANSI_C
  835. Xint
  836. Xbwb_const( char *lb, char *sb, int *n )
  837. X#else
  838. Xint
  839. Xbwb_const( lb, sb, n )
  840. X   char *lb;
  841. X   char *sb;
  842. X   int *n;
  843. X#endif
  844. X   {
  845. X   register int s;
  846. X
  847. X   ++*n;                        /* advance past quotation mark */
  848. X   s = 0;
  849. X
  850. X   while ( TRUE )
  851. X      {
  852. X      switch ( lb[ *n ] )
  853. X         {
  854. X         case '\"':
  855. X            sb[ s ] = 0;
  856. X            ++*n;               /* advance past ending quotation mark */
  857. X            return TRUE;
  858. X         case '\n':
  859. X         case '\r':
  860. X         case 0:
  861. X            sb[ s ] = 0;
  862. X            return TRUE;
  863. X         default:
  864. X            sb[ s ] = lb[ *n ];
  865. X            break;
  866. X         }
  867. X
  868. X      ++*n;                     /* advance to next character in large buffer */
  869. X      ++s;                      /* advance to next position in small buffer */
  870. X      sb[ s ] = 0;              /* terminate with 0 */
  871. X      }
  872. X
  873. X   }
  874. X
  875. X/***********************************************************
  876. X
  877. X    FUNCTION:       bwb_getvarname()
  878. X
  879. X    DESCRIPTION:    This function takes the string in lb
  880. X            (the large buffer), finds a variable name,
  881. X            and returns it in sb (the small buffer),
  882. X            appropriately incrementing the integer
  883. X            pointed to by n.
  884. X
  885. X***********************************************************/
  886. X
  887. X#if ANSI_C
  888. Xint
  889. Xbwb_getvarname( char *lb, char *sb, int *n )
  890. X#else
  891. Xint
  892. Xbwb_getvarname( lb, sb, n )
  893. X   char *lb;
  894. X   char *sb;
  895. X   int *n;
  896. X#endif
  897. X   {
  898. X   register int s;
  899. X
  900. X   s = 0;
  901. X
  902. X   /* advance beyond whitespace */
  903. X
  904. X   adv_ws( lb, n );
  905. X
  906. X   while ( TRUE )
  907. X      {
  908. X      switch ( lb[ *n ] )
  909. X         {
  910. X         case ' ':              /* whitespace */
  911. X         case '\t':
  912. X         case '\n':             /* end of string */
  913. X         case '\r':
  914. X         case 0:
  915. X         case ':':              /* end of expression */
  916. X         case ',':
  917. X         case ';':
  918. X         case '(':              /* beginning of parameter list for dimensioned array */
  919. X         case '+':              /* add variables */
  920. X            sb[ s ] = 0;
  921. X            return TRUE;
  922. X         default:
  923. X            sb[ s ] = lb[ *n ];
  924. X            break;
  925. X         }
  926. X
  927. X      ++*n;                     /* advance to next character in large buffer */
  928. X      ++s;                      /* advance to next position in small buffer */
  929. X      sb[ s ] = 0;              /* terminate with 0 */
  930. X
  931. X#if INTENSIVE_DEBUG
  932. X      sprintf( bwb_ebuf, "in bwb_getvarname(): found <%s>", sb );
  933. X      bwb_debug( bwb_ebuf );
  934. X#endif
  935. X      }
  936. X
  937. X   }
  938. X
  939. X/***************************************************************
  940. X
  941. X        FUNCTION:       var_find()
  942. X
  943. X    DESCRIPTION:    This C function attempts to find a variable
  944. X            name matching the argument in buffer. If
  945. X            it fails to find a matching name, it
  946. X            sets up a new variable with that name.
  947. X
  948. X***************************************************************/
  949. X
  950. X#if ANSI_C
  951. Xstruct bwb_variable *
  952. Xvar_find( char *buffer )
  953. X#else
  954. Xstruct bwb_variable *
  955. Xvar_find( buffer )
  956. X   char *buffer;
  957. X#endif
  958. X   {
  959. X   struct bwb_variable *v;
  960. X
  961. X#if INTENSIVE_DEBUG
  962. X   sprintf( bwb_ebuf, "in var_find(): received <%s>", buffer );
  963. X   bwb_debug( bwb_ebuf );
  964. X#endif
  965. X
  966. X   /* check for a local variable at this EXEC level */
  967. X
  968. X   v = var_islocal( buffer );
  969. X   if ( v != NULL )
  970. X      {
  971. X      return v;
  972. X      }
  973. X
  974. X   /* now run through the global variable list and try to find a match */
  975. X
  976. X   for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next )
  977. X      {
  978. X
  979. X      if ( strcmp( v->name, buffer ) == 0 )
  980. X         {
  981. X         switch( v->type )
  982. X            {
  983. X            case STRING:
  984. X            case NUMBER:
  985. X               break;
  986. X            default:
  987. X#if PROG_ERRORS
  988. X               sprintf( bwb_ebuf, "in var_find(): inappropriate precision for variable <%s>",
  989. X                  v->name );
  990. X               bwb_error( bwb_ebuf );
  991. X#endif
  992. X               break;
  993. X            }
  994. X#if INTENSIVE_DEBUG
  995. X         sprintf( bwb_ebuf, "in var_find(): found global variable <%s>", v->name );
  996. X         bwb_debug( bwb_ebuf );
  997. X#endif
  998. X
  999. X         return v;
  1000. X         }
  1001. X
  1002. X      }
  1003. X
  1004. X   /* presume this is a new variable, so initialize it... */
  1005. X   /* check for NULL variable name */
  1006. X
  1007. X   if ( strlen( buffer ) == 0 )
  1008. X      {
  1009. X#if PROG_ERRORS
  1010. X      sprintf( bwb_ebuf, "in var_find(): NULL variable name received\n" );
  1011. X      bwb_error( bwb_ebuf );
  1012. X#else
  1013. X      bwb_error( err_syntax );
  1014. X#endif
  1015. X      return NULL;
  1016. X      }
  1017. X
  1018. X   /* initialize new variable */
  1019. X
  1020. X   v = var_new( buffer );
  1021. X
  1022. X   /* set place at beginning of variable chain */
  1023. X
  1024. X   v->next = CURTASK var_start.next;
  1025. X   CURTASK var_start.next = v;
  1026. X
  1027. X   /* normally not a preset */
  1028. X
  1029. X   v->preset = FALSE;
  1030. X
  1031. X#if INTENSIVE_DEBUG
  1032. X   sprintf( bwb_ebuf, "in var_find(): initialized new variable <%s> type <%c>, dim <%d>",
  1033. X      v->name, v->type, v->dimensions );
  1034. X   bwb_debug( bwb_ebuf );
  1035. X   getchar();
  1036. X#endif
  1037. X
  1038. X   return v;
  1039. X
  1040. X   }
  1041. X
  1042. X/***************************************************************
  1043. X
  1044. X        FUNCTION:       var_new()
  1045. X
  1046. X    DESCRIPTION:    This function assigns memory for a new variable.
  1047. X
  1048. X***************************************************************/
  1049. X
  1050. X#if ANSI_C
  1051. Xstruct bwb_variable *
  1052. Xvar_new( char *name )
  1053. X#else
  1054. Xstruct bwb_variable *
  1055. Xvar_new( name )
  1056. X   char *name;
  1057. X#endif
  1058. X   {
  1059. X   struct bwb_variable *v;
  1060. X
  1061. X   /* get memory for new variable */
  1062. X
  1063. X   if ( ( v = (struct bwb_variable *) calloc( 1, sizeof( struct bwb_variable ) ))
  1064. X      == NULL )
  1065. X      {
  1066. X      bwb_error( err_getmem );
  1067. X      return NULL;
  1068. X      }
  1069. X
  1070. X   /* copy the name into the appropriate structure */
  1071. X
  1072. X   strcpy( v->name, name );
  1073. X
  1074. X   /* set memory in the new variable */
  1075. X
  1076. X   var_make( v, (int) v->name[ strlen( v->name ) - 1 ] );
  1077. X
  1078. X   /* and return */
  1079. X
  1080. X   return v;
  1081. X
  1082. X   }
  1083. X
  1084. X/***************************************************************
  1085. X
  1086. X        FUNCTION:       bwb_isvar()
  1087. X
  1088. X    DESCRIPTION:    This function determines if the string
  1089. X            in 'buffer' is the name of a previously-
  1090. X            existing variable.
  1091. X
  1092. X***************************************************************/
  1093. X
  1094. X#if ANSI_C
  1095. Xint
  1096. Xbwb_isvar( char *buffer )
  1097. X#else
  1098. Xint
  1099. Xbwb_isvar( buffer )
  1100. X   char *buffer;
  1101. X#endif
  1102. X   {
  1103. X   struct bwb_variable *v;
  1104. X
  1105. X   /* run through the variable list and try to find a match */
  1106. X
  1107. X   for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next )
  1108. X      {
  1109. X
  1110. X      if ( strcmp( v->name, buffer ) == 0 )
  1111. X         {
  1112. X         return TRUE;
  1113. X         }
  1114. X
  1115. X      }
  1116. X
  1117. X   /* search failed */
  1118. X
  1119. X   return FALSE;
  1120. X
  1121. X   }
  1122. X
  1123. X/***************************************************************
  1124. X
  1125. X    FUNCTION:       var_getnval()
  1126. X
  1127. X    DESCRIPTION:    This function returns the current value of
  1128. X            the variable argument as a number.
  1129. X
  1130. X***************************************************************/
  1131. X
  1132. X#if ANSI_C
  1133. Xbnumber
  1134. Xvar_getnval( struct bwb_variable *nvar )
  1135. X#else
  1136. Xbnumber
  1137. Xvar_getnval( nvar )
  1138. X   struct bwb_variable *nvar;
  1139. X#endif
  1140. X   {
  1141. X
  1142. X   switch( nvar->type )
  1143. X      {
  1144. X      case NUMBER:
  1145. X         return *( var_findnval( nvar, nvar->array_pos ) );
  1146. X      }
  1147. X
  1148. X#if PROG_ERRORS
  1149. X   sprintf( bwb_ebuf, "in var_getnval(): type is <%d>=<%c>.",
  1150. X      nvar->type, nvar->type );
  1151. X   bwb_error( bwb_ebuf );
  1152. X#else
  1153. X   bwb_error( err_mismatch );
  1154. X#endif
  1155. X
  1156. X
  1157. X   return (bnumber) 0.0;
  1158. X
  1159. X   }
  1160. X
  1161. X/***************************************************************
  1162. X
  1163. X    FUNCTION:       var_getsval()
  1164. X
  1165. X    DESCRIPTION:    This function returns the current value of
  1166. X            the variable argument as a pointer to a BASIC
  1167. X            string structure.
  1168. X
  1169. X***************************************************************/
  1170. X
  1171. X#if ANSI_C
  1172. Xbstring *
  1173. Xvar_getsval( struct bwb_variable *nvar )
  1174. X#else
  1175. Xbstring *
  1176. Xvar_getsval( nvar )
  1177. X   struct bwb_variable *nvar;
  1178. X#endif
  1179. X   {
  1180. X   static bstring b;
  1181. X
  1182. X   b.rab = FALSE;
  1183. X
  1184. X   switch( nvar->type )
  1185. X      {
  1186. X      case STRING:
  1187. X     return var_findsval( nvar, nvar->array_pos );
  1188. X      case NUMBER:
  1189. X     sprintf( bwb_ebuf, "%*f ", prn_precision( nvar ),
  1190. X        *( var_findnval( nvar, nvar->array_pos ) ) );
  1191. X     str_ctob( &b, bwb_ebuf );
  1192. X     return &b;
  1193. X      default:
  1194. X#if PROG_ERRORS
  1195. X     sprintf( bwb_ebuf, "in var_getsval(): type is <%d>=<%c>.",
  1196. X        nvar->type, nvar->type );
  1197. X     bwb_error( bwb_ebuf );
  1198. X#else
  1199. X     bwb_error( err_mismatch );
  1200. X#endif
  1201. X     return NULL;
  1202. X      }
  1203. X
  1204. X   }
  1205. X
  1206. X/***************************************************************
  1207. X
  1208. X    FUNCTION:    bwb_dim()
  1209. X
  1210. X    DESCRIPTION:    This function implements the BASIC DIM
  1211. X            statement, allocating memory for a
  1212. X            dimensioned array of variables.
  1213. X
  1214. X    SYNTAX:        DIM variable(elements...)[variable(elements...)]...
  1215. X
  1216. X***************************************************************/
  1217. X
  1218. X#if ANSI_C
  1219. Xstruct bwb_line *
  1220. Xbwb_dim( struct bwb_line *l )
  1221. X#else
  1222. Xstruct bwb_line *
  1223. Xbwb_dim( l )
  1224. X   struct bwb_line *l;
  1225. X#endif
  1226. X   {
  1227. X   register int n;
  1228. X   static int n_params;                         /* number of parameters */
  1229. X   static int *pp;                              /* pointer to parameter values */
  1230. X   struct bwb_variable *newvar;
  1231. X   bnumber *np;
  1232. X   int loop;
  1233. X   int old_name, old_dimensions;
  1234. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1235. X
  1236. X#if INTENSIVE_DEBUG
  1237. X   sprintf( bwb_ebuf, "in bwb_dim(): entered function." );
  1238. X   bwb_debug( bwb_ebuf );
  1239. X#endif
  1240. X
  1241. X   loop = TRUE;
  1242. X   while ( loop == TRUE )
  1243. X      {
  1244. X
  1245. X      old_name = FALSE;
  1246. X
  1247. X      /* Get variable name */
  1248. X
  1249. X      adv_ws( l->buffer, &( l->position ) );
  1250. X      bwb_getvarname( l->buffer, tbuf, &( l->position ) );
  1251. X
  1252. X      /* check for previously used variable name */
  1253. X
  1254. X      if ( bwb_isvar( tbuf ) == TRUE )
  1255. X         {
  1256. X#if INTENSIVE_DEBUG
  1257. X         sprintf( bwb_ebuf, "in bwb_dim(): variable name is already used.",
  1258. X            l->number );
  1259. X         bwb_debug( bwb_ebuf );
  1260. X#endif
  1261. X         old_name = TRUE;
  1262. X         }
  1263. X
  1264. X      /* get the new variable */
  1265. X
  1266. X      newvar = var_find( tbuf );
  1267. X
  1268. X#if INTENSIVE_DEBUG
  1269. X      sprintf( bwb_ebuf, "in bwb_dim(): new variable name is <%s>.",
  1270. X         newvar->name );
  1271. X      bwb_debug( bwb_ebuf );
  1272. X#endif
  1273. X
  1274. X      /* note that DIM has been called */
  1275. X
  1276. X      dimmed = TRUE;
  1277. X
  1278. X      /* read parameters */
  1279. X
  1280. X      old_dimensions = newvar->dimensions;
  1281. X      dim_getparams( l->buffer, &( l->position ), &n_params, &pp );
  1282. X      newvar->dimensions = n_params;
  1283. X
  1284. X      /* Check parameters for an old variable name */
  1285. X
  1286. X      if ( old_name == TRUE )
  1287. X         {
  1288. X
  1289. X         /* check to be sure the number of dimensions is the same */
  1290. X
  1291. X         if ( newvar->dimensions != old_dimensions )
  1292. X            {
  1293. X#if PROG_ERRORS
  1294. X            sprintf( bwb_ebuf, "in bwb_dim(): variable <%s> cannot be re-dimensioned",
  1295. X               newvar->name );
  1296. X            bwb_error( bwb_ebuf );
  1297. X#else
  1298. X            bwb_error( err_redim );
  1299. X#endif
  1300. X            }
  1301. X
  1302. X         /* check to be sure sizes for the old variable are the same */
  1303. X
  1304. X         for ( n = 0; n < newvar->dimensions; ++n )
  1305. X            {
  1306. X#if INTENSIVE_DEBUG
  1307. X            sprintf( bwb_ebuf, "in bwb_dim(): old var <%s> parameter <%d> size <%d>.",
  1308. X               newvar->name, n, pp[ n ] );
  1309. X            bwb_debug( bwb_ebuf );
  1310. X#endif
  1311. X            if ( ( pp[ n ] + ( 1 - dim_base )) != newvar->array_sizes[ n ] )
  1312. X               {
  1313. X#if PROG_ERRORS
  1314. X               sprintf( bwb_ebuf, "in bwb_dim(): variable <%s> parameter <%d> cannot be resized",
  1315. X                  newvar->name, n );
  1316. X               bwb_error( bwb_ebuf );
  1317. X#else
  1318. X               bwb_error( err_redim );
  1319. X#endif
  1320. X               }
  1321. X            }
  1322. X
  1323. X         }         /* end of conditional for old variable */
  1324. X
  1325. X
  1326. X      /* a new variable */
  1327. X
  1328. X      else
  1329. X         {
  1330. X
  1331. X         /* assign memory for parameters */
  1332. X
  1333. X         if ( ( newvar->array_sizes = (int *) calloc( n_params, sizeof( int )  )) == NULL )
  1334. X            {
  1335. X#if PROG_ERRORS
  1336. X            sprintf( bwb_ebuf, "in line %d: Failed to find memory for array_sizes for <%s>",
  1337. X               l->number, newvar->name );
  1338. X            bwb_error( bwb_ebuf );
  1339. X#else
  1340. X            bwb_error( err_getmem );
  1341. X#endif
  1342. X            return bwb_zline( l );
  1343. X            }
  1344. X
  1345. X         for ( n = 0; n < newvar->dimensions; ++n )
  1346. X            {
  1347. X            newvar->array_sizes[ n ] = pp[ n ] + ( 1 - dim_base );
  1348. X#if INTENSIVE_DEBUG
  1349. X            sprintf( bwb_ebuf, "in bwb_dim(): array_sizes dim <%d> value <%d>",
  1350. X               n, newvar->array_sizes[ n ] );
  1351. X            bwb_debug( bwb_ebuf );
  1352. X#endif
  1353. X            }
  1354. X
  1355. X         /* assign memory for current position */
  1356. X
  1357. X         if ( ( newvar->array_pos = (int *) calloc( n_params, sizeof( int ) )) == NULL )
  1358. X            {
  1359. X#if PROG_ERRORS
  1360. X            sprintf( bwb_ebuf, "in line %d: Failed to find memory for array_pos for <%s>",
  1361. X               l->number, newvar->name );
  1362. X            bwb_error( bwb_ebuf );
  1363. X#else
  1364. X            bwb_error( err_getmem );
  1365. X#endif
  1366. X            return bwb_zline( l );
  1367. X            }
  1368. X
  1369. X         for ( n = 0; n < newvar->dimensions; ++n )
  1370. X            {
  1371. X            newvar->array_pos[ n ] = dim_base;
  1372. X            }
  1373. X
  1374. X         /* calculate the array size */
  1375. X
  1376. X     newvar->array_units = (size_t) MAXINTSIZE;    /* avoid error in dim_unit() */
  1377. X     newvar->array_units = dim_unit( newvar, pp ) + 1;
  1378. X
  1379. X#if INTENSIVE_DEBUG
  1380. X         sprintf( bwb_ebuf, "in bwb_dim(): array memory requires <%ld> units",
  1381. X            (long) newvar->array_units );
  1382. X         bwb_debug( bwb_ebuf );
  1383. X#endif
  1384. X
  1385. X         /* assign array memory */
  1386. X
  1387. X         switch( newvar->type )
  1388. X            {
  1389. X            case STRING:
  1390. X#if INTENSIVE_DEBUG
  1391. X               sprintf( bwb_ebuf, "in bwb_dim(): 1 STRING requires <%ld> bytes",
  1392. X                  (long) sizeof( bstring ));
  1393. X               bwb_debug( bwb_ebuf );
  1394. X               sprintf( bwb_ebuf, "in bwb_dim(): STRING array memory requires <%ld> bytes",
  1395. X              (long) ( newvar->array_units + 1 ) * sizeof( bstring ));
  1396. X               bwb_debug( bwb_ebuf );
  1397. X#endif
  1398. X           if ( ( newvar->memnum = calloc( newvar->array_units, sizeof( bstring) )) == NULL )
  1399. X          {
  1400. X#if PROG_ERRORS
  1401. X                  sprintf( bwb_ebuf, "in line %d: Failed to find memory for array <%s>",
  1402. X                     l->number, newvar->name );
  1403. X                  bwb_error( bwb_ebuf );
  1404. X#else
  1405. X                  bwb_error( err_getmem );
  1406. X#endif
  1407. X                  return bwb_zline( l );
  1408. X                  }
  1409. X               break;
  1410. X            case NUMBER:
  1411. X#if INTENSIVE_DEBUG
  1412. X               sprintf( bwb_ebuf, "in bwb_dim(): 1 DOUBLE requires <%ld> bytes",
  1413. X                  (long) sizeof( double ));
  1414. X               bwb_debug( bwb_ebuf );
  1415. X               sprintf( bwb_ebuf, "in bwb_dim(): DOUBLE array memory requires <%ld> bytes",
  1416. X              (long) ( newvar->array_units + 1 ) * sizeof( double ));
  1417. X               bwb_debug( bwb_ebuf );
  1418. X#endif
  1419. X               if ( ( np = (bnumber *)
  1420. X                  calloc( newvar->array_units, sizeof( bnumber ) )) == NULL )
  1421. X                  {
  1422. X#if PROG_ERRORS
  1423. X                  sprintf( bwb_ebuf, "in line %d: Failed to find memory for array <%s>",
  1424. X                  l->number, newvar->name );
  1425. X                  bwb_error( bwb_ebuf );
  1426. X#else
  1427. X                  bwb_error( err_getmem );
  1428. X#endif
  1429. X                  return bwb_zline( l );
  1430. X                  }
  1431. X           newvar->memnum = np;
  1432. X           break;
  1433. X        default:
  1434. X#if PROG_ERRORS
  1435. X               sprintf( bwb_ebuf, "in line %d: New variable has unrecognized type.",
  1436. X                  l->number );
  1437. X               bwb_error( bwb_ebuf );
  1438. X#else
  1439. X               bwb_error( err_syntax );
  1440. X#endif
  1441. X               return bwb_zline( l );
  1442. X            }
  1443. X
  1444. X         }            /* end of conditional for new variable */
  1445. X
  1446. X      /* now check for end of string */
  1447. X
  1448. X      if ( l->buffer[ l->position ] == ')' )
  1449. X         {
  1450. X         ++( l->position );
  1451. X         }
  1452. X      adv_ws( l->buffer, &( l->position ));
  1453. X      switch( l->buffer[ l->position ] )
  1454. X         {
  1455. X         case '\n':            /* end of line */
  1456. X         case '\r':
  1457. X         case ':':            /* end of line segment */
  1458. X         case '\0':            /* end of string */
  1459. X            loop = FALSE;
  1460. X            break;
  1461. X         case ',':
  1462. X            ++( l->position );
  1463. X            adv_ws( l->buffer, &( l->position ) );
  1464. X            loop = TRUE;
  1465. X            break;
  1466. X         default:
  1467. X#if PROG_ERRORS
  1468. X            sprintf( bwb_ebuf, "in bwb_dim(): unexpected end of string, buf <%s>",
  1469. X               &( l->buffer[ l->position ] ) );
  1470. X            bwb_error( bwb_ebuf );
  1471. X#else
  1472. X            bwb_error( err_syntax );
  1473. X#endif
  1474. X            loop = FALSE;
  1475. X            break;
  1476. X         }
  1477. X
  1478. X      }                /* end of loop through variables */
  1479. X
  1480. X   /* return */
  1481. X
  1482. X   return bwb_zline( l );
  1483. X
  1484. X   }
  1485. X
  1486. X/***************************************************************
  1487. X
  1488. X        FUNCTION:       dim_unit()
  1489. X
  1490. X        DESCRIPTION:    This function calculates the unit
  1491. X                position for an array.
  1492. X
  1493. X***************************************************************/
  1494. X
  1495. X#if ANSI_C
  1496. Xstatic size_t
  1497. Xdim_unit( struct bwb_variable *v, int *pp )
  1498. X#else
  1499. Xstatic size_t
  1500. Xdim_unit( v, pp )
  1501. X   struct bwb_variable *v;
  1502. X   int *pp;
  1503. X#endif
  1504. X   {
  1505. X   size_t r;
  1506. X   size_t b;
  1507. X   register int n;
  1508. X
  1509. X   /* Calculate and return the address of the dimensioned array */
  1510. X
  1511. X   b = 1;
  1512. X   r = 0;
  1513. X   for ( n = 0; n < v->dimensions; ++n )
  1514. X      {
  1515. X      r += b * ( pp[ n ] - dim_base );
  1516. X      b *= v->array_sizes[ n ];
  1517. X      }
  1518. X
  1519. X#if INTENSIVE_DEBUG
  1520. X   for ( n = 0; n < v->dimensions; ++n )
  1521. X      {
  1522. X      sprintf( bwb_ebuf,
  1523. X         "in dim_unit(): variable <%s> pos <%d> val <%d>.",
  1524. X         v->name, n, pp[ n ] );
  1525. X      bwb_debug( bwb_ebuf );
  1526. X      }
  1527. X   sprintf( bwb_ebuf, "in dim_unit(): return unit: <%ld>", (long) r );
  1528. X   bwb_debug( bwb_ebuf );
  1529. X#endif
  1530. X
  1531. X   if ( r > v->array_units )
  1532. X      {
  1533. X#if PROG_ERRORS
  1534. X      sprintf( bwb_ebuf, "in dim_unit(): unit value <%ld> exceeds array units <%ld>",
  1535. X         r, v->array_units );
  1536. X      bwb_error( bwb_ebuf );
  1537. X#else
  1538. X      bwb_error( err_valoorange );
  1539. X#endif
  1540. X      return 0;
  1541. X      }
  1542. X
  1543. X   return r;
  1544. X
  1545. X   }
  1546. X
  1547. X/***************************************************************
  1548. X
  1549. X        FUNCTION:       dim_getparams()
  1550. X
  1551. X    DESCRIPTION:    This function reads a string in <buffer>
  1552. X                        beginning at position <pos> and finds a
  1553. X                        list of parameters surrounded by paren-
  1554. X                        theses, returning in <n_params> the number
  1555. X                        of parameters found, and returning in
  1556. X                        <pp> an array of n_params integers giving
  1557. X                        the sizes for each dimension of the array.
  1558. X
  1559. X***************************************************************/
  1560. X
  1561. X#if ANSI_C
  1562. Xint
  1563. Xdim_getparams( char *buffer, int *pos, int *n_params, int **pp )
  1564. X#else
  1565. Xint
  1566. Xdim_getparams( buffer, pos, n_params, pp )
  1567. X   char *buffer;
  1568. X   int *pos;
  1569. X   int *n_params;
  1570. X   int **pp;
  1571. X#endif
  1572. X   {
  1573. X   int loop;
  1574. X   static int params[ MAX_DIMS ];
  1575. X   int x_pos, s_pos;
  1576. X   struct exp_ese *e;
  1577. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1578. X
  1579. X   /* set initial values */
  1580. X
  1581. X   *n_params = 0;
  1582. X#if OLDSTUFF
  1583. X   paren_found = FALSE;
  1584. X#endif
  1585. X
  1586. X   /* advance and check for undimensioned variable */
  1587. X
  1588. X   adv_ws( buffer, pos );
  1589. X   if ( buffer[ *pos ] != '(' )
  1590. X      {
  1591. X      *n_params = 1;
  1592. X      params[ 0 ] = dim_base;
  1593. X      *pp = params;
  1594. X      return TRUE;
  1595. X      }
  1596. X   else
  1597. X      {
  1598. X      ++(*pos);
  1599. X      }
  1600. X
  1601. X   /* Variable has DIMensions: Find each parameter */
  1602. X
  1603. X   s_pos = 0;
  1604. X   tbuf[ 0 ] = '\0';
  1605. X   loop = TRUE;
  1606. X   while( loop == TRUE )
  1607. X      {
  1608. X      switch( buffer[ *pos ] )
  1609. X         {
  1610. X         case ')':                      /* end of parameter list */
  1611. X            x_pos = 0;
  1612. X            if ( tbuf[ 0 ] == '\0' )
  1613. X               {
  1614. X               params[ *n_params ] = DEF_SUBSCRIPT;
  1615. X               }
  1616. X            else
  1617. X               {
  1618. X#if INTENSIVE_DEBUG
  1619. X               sprintf( bwb_ebuf, "in dim_getparams(): call bwb_exp() for last element" );
  1620. X               bwb_debug( bwb_ebuf );
  1621. X#endif
  1622. X               e = bwb_exp( tbuf, FALSE, &x_pos );
  1623. X#if INTENSIVE_DEBUG
  1624. X               sprintf( bwb_ebuf, "in dim_getparams(): return from bwb_exp() for last element" );
  1625. X               bwb_debug( bwb_ebuf );
  1626. X#endif
  1627. X               params[ *n_params ] = (int) exp_getnval( e );
  1628. X               }
  1629. X            ++(*n_params);
  1630. X            loop = FALSE;
  1631. X            ++( *pos );
  1632. X            break;
  1633. X
  1634. X         case ',':                      /* end of a parameter */
  1635. X            x_pos = 0;
  1636. X            if ( tbuf[ 0 ] == '\0' )
  1637. X               {
  1638. X               params[ *n_params ] = DEF_SUBSCRIPT;
  1639. X               }
  1640. X            else
  1641. X               {
  1642. X#if INTENSIVE_DEBUG
  1643. X               sprintf( bwb_ebuf, "in dim_getparams(): call bwb_exp() for element (not last)" );
  1644. X               bwb_debug( bwb_ebuf );
  1645. X#endif
  1646. X               e = bwb_exp( tbuf, FALSE, &x_pos );
  1647. X               params[ *n_params ] = (int) exp_getnval( e );
  1648. X               }
  1649. X            ++(*n_params);
  1650. X            tbuf[ 0 ] = '\0';
  1651. X            ++(*pos);
  1652. X            s_pos = 0;
  1653. X            break;
  1654. X
  1655. X         case ' ':                      /* whitespace -- skip */
  1656. X         case '\t':
  1657. X            ++(*pos);
  1658. X            break;
  1659. X
  1660. X         default:
  1661. X            tbuf[ s_pos ] = buffer[ *pos ];
  1662. X            ++(*pos);
  1663. X            ++s_pos;
  1664. X            tbuf[ s_pos ] = '\0';
  1665. X            break;
  1666. X         }
  1667. X      }
  1668. X
  1669. X#if INTENSIVE_DEBUG
  1670. X   for ( n = 0; n < *n_params; ++n )
  1671. X      {
  1672. X      sprintf( bwb_ebuf, "in dim_getparams(): Parameter <%d>: <%d>",
  1673. X         n, params[ n ] );
  1674. X      bwb_debug( bwb_ebuf );
  1675. X      }
  1676. X#endif
  1677. X
  1678. X   /* return params stack */
  1679. X
  1680. X   *pp = params;
  1681. X
  1682. X   return TRUE;
  1683. X
  1684. X   }
  1685. X
  1686. X/***************************************************************
  1687. X
  1688. X        FUNCTION:       bwb_option()
  1689. X
  1690. X        DESCRIPTION:    This function implements the BASIC OPTION
  1691. X                        BASE statement, designating the base (1 or
  1692. X                        0) for addressing DIM arrays.
  1693. X
  1694. X    SYNTAX:        OPTION BASE number
  1695. X
  1696. X***************************************************************/
  1697. X
  1698. X#if ANSI_C
  1699. Xstruct bwb_line *
  1700. Xbwb_option( struct bwb_line *l )
  1701. X#else
  1702. Xstruct bwb_line *
  1703. Xbwb_option( l )
  1704. X   struct bwb_line *l;
  1705. X#endif
  1706. X   {
  1707. X   register int n;
  1708. X   int newval;
  1709. X   struct exp_ese *e;
  1710. X   struct bwb_variable *current;
  1711. X   char tbuf[ MAXSTRINGSIZE ];
  1712. X
  1713. X#if INTENSIVE_DEBUG
  1714. X   sprintf( bwb_ebuf, "in bwb_option(): entered function." );
  1715. X   bwb_debug( bwb_ebuf );
  1716. X#endif
  1717. X
  1718. X   /* If DIM has already been called, do not allow OPTION BASE */
  1719. X
  1720. X   if ( dimmed != FALSE )
  1721. X      {
  1722. X#if PROG_ERRORS
  1723. X      sprintf( bwb_ebuf, "at line %d: OPTION BASE must be called before DIM.",
  1724. X         l->number );
  1725. X      bwb_error( bwb_ebuf );
  1726. X#else
  1727. X      bwb_error( err_obdim );
  1728. X#endif
  1729. X      return bwb_zline( l );
  1730. X      }
  1731. X
  1732. X   /* capitalize first element in tbuf */
  1733. X
  1734. X   adv_element( l->buffer, &( l->position ), tbuf );
  1735. X   for ( n = 0; tbuf[ n ] != '\0'; ++n )
  1736. X      {
  1737. X      if ( islower( tbuf[ n ] ) != FALSE )
  1738. X         {
  1739. X         tbuf[ n ] = (char) toupper( tbuf[ n ] );
  1740. X         }
  1741. X      }
  1742. X
  1743. X   /* check for BASE statement */
  1744. X
  1745. X   if ( strncmp( tbuf, "BASE", (size_t) 4 ) != 0 )
  1746. X      {
  1747. X#if PROG_ERRORS
  1748. X      sprintf( bwb_ebuf, "at line %d: Unknown statement <%s> following OPTION.",
  1749. X         l->number, tbuf );
  1750. X      bwb_error( bwb_ebuf );
  1751. X#else
  1752. X      bwb_error( err_syntax );
  1753. X#endif
  1754. X      return bwb_zline( l );
  1755. X      }
  1756. X
  1757. X   /* Get new value from argument. */
  1758. X
  1759. X   adv_ws( l->buffer, &( l->position ) );
  1760. X   e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  1761. X   newval = (int) exp_getnval( e );
  1762. X
  1763. X   /* Test the new value. */
  1764. X
  1765. X#if INTENSIVE_DEBUG
  1766. X   sprintf( bwb_ebuf, "in bwb_option(): New value received is <%d>.", newval );
  1767. X   bwb_debug( bwb_ebuf );
  1768. X#endif
  1769. X
  1770. X   if ( ( newval < 0 ) || ( newval > 1 ) )
  1771. X      {
  1772. X#if PROG_ERRORS
  1773. X      sprintf( bwb_ebuf, "at line %d: value for OPTION BASE must be 1 or 0.",
  1774. X         l->number );
  1775. X      bwb_error( bwb_ebuf );
  1776. X#else
  1777. X      bwb_error( err_valoorange );
  1778. X#endif
  1779. X      return bwb_zline( l );
  1780. X      }
  1781. X
  1782. X   /* Set the new value. */
  1783. X
  1784. X   dim_base = newval;
  1785. X
  1786. X   /* run through the variable list and change any positions that had
  1787. X      set 0 before OPTION BASE was run */
  1788. X
  1789. X   for ( current = CURTASK var_start.next; current != &CURTASK var_end; current = current->next )
  1790. X      {
  1791. X      current->array_pos[ 0 ] = dim_base;
  1792. X      }
  1793. X
  1794. X   /* Return. */
  1795. X
  1796. X   return bwb_zline( l );
  1797. X
  1798. X   }
  1799. X
  1800. X/***************************************************************
  1801. X
  1802. X        FUNCTION:       var_findnval()
  1803. X
  1804. X        DESCRIPTION:    This function returns the address of
  1805. X                        the number for the variable <v>.  If
  1806. X                        <v> is a dimensioned array, the address
  1807. X                        returned is for the double at the
  1808. X                        position indicated by the integer array
  1809. X                        <pp>.
  1810. X
  1811. X***************************************************************/
  1812. X
  1813. X
  1814. X#if ANSI_C
  1815. Xbnumber *
  1816. Xvar_findnval( struct bwb_variable *v, int *pp )
  1817. X#else
  1818. Xbnumber *
  1819. Xvar_findnval( v, pp )
  1820. X   struct bwb_variable *v;
  1821. X   int *pp;
  1822. X#endif
  1823. X   {
  1824. X   size_t offset;
  1825. X   bnumber *p;
  1826. X
  1827. X   /* Check for appropriate type */
  1828. X
  1829. X   if ( v->type != NUMBER )
  1830. X      {
  1831. X#if PROG_ERRORS
  1832. X      sprintf ( bwb_ebuf, "in var_findnval(): Variable <%s> is not a number.",
  1833. X         v->name );
  1834. X      bwb_error( bwb_ebuf );
  1835. X#else
  1836. X      bwb_error( err_mismatch );
  1837. X#endif
  1838. X      return NULL;
  1839. X      }
  1840. X
  1841. X   /* Check subscripts */
  1842. X
  1843. X   if ( dim_check( v, pp ) == FALSE )
  1844. X      {
  1845. X      return NULL;
  1846. X      }
  1847. X
  1848. X   /* Calculate and return the address of the dimensioned array */
  1849. X
  1850. X   offset = dim_unit( v, pp );
  1851. X
  1852. X#if INTENSIVE_DEBUG
  1853. X   for ( n = 0; n < v->dimensions; ++n )
  1854. X      {
  1855. X      sprintf( bwb_ebuf,
  1856. X         "in var_findnval(): dimensioned variable pos <%d> <%d>.",
  1857. X         n, pp[ n ] );
  1858. X      bwb_debug( bwb_ebuf );
  1859. X      }
  1860. X#endif
  1861. X
  1862. X   p = v->memnum;
  1863. X   return (p + offset);
  1864. X
  1865. X   }
  1866. X
  1867. X/***************************************************************
  1868. X
  1869. X        FUNCTION:       var_findsval()
  1870. X
  1871. X        DESCRIPTION:    This function returns the address of
  1872. X                        the string for the variable <v>.  If
  1873. X                        <v> is a dimensioned array, the address
  1874. X                        returned is for the string at the
  1875. X                        position indicated by the integer array
  1876. X                        <pp>.
  1877. X
  1878. X***************************************************************/
  1879. X
  1880. X#if ANSI_C
  1881. Xbstring *
  1882. Xvar_findsval( struct bwb_variable *v, int *pp )
  1883. X#else
  1884. Xbstring *
  1885. Xvar_findsval( v, pp )
  1886. X   struct bwb_variable *v;
  1887. X   int *pp;
  1888. X#endif
  1889. X   {
  1890. X   size_t offset;
  1891. X   bstring *p;
  1892. X
  1893. X#if INTENSIVE_DEBUG
  1894. X   sprintf( bwb_ebuf, "in var_findsval(): entered, var <%s>", v->name );
  1895. X   bwb_debug( bwb_ebuf );
  1896. X#endif
  1897. X
  1898. X   /* Check for appropriate type */
  1899. X
  1900. X   if ( v->type != STRING )
  1901. X      {
  1902. X#if PROG_ERRORS
  1903. X      sprintf ( bwb_ebuf, "in var_findsval(): Variable <%s> is not a string.", v->name );
  1904. X      bwb_error( bwb_ebuf );
  1905. X#else
  1906. X      bwb_error( err_mismatch );
  1907. X#endif
  1908. X      return NULL;
  1909. X      }
  1910. X
  1911. X   /* Check subscripts */
  1912. X
  1913. X   if ( dim_check( v, pp ) == FALSE )
  1914. X      {
  1915. X      return NULL;
  1916. X      }
  1917. X
  1918. X   /* Calculate and return the address of the dimensioned array */
  1919. X
  1920. X   offset = dim_unit( v, pp );
  1921. X
  1922. X#if INTENSIVE_DEBUG
  1923. X   for ( n = 0; n < v->dimensions; ++n )
  1924. X      {
  1925. X      sprintf( bwb_ebuf,
  1926. X         "in var_findsval(): dimensioned variable pos <%d> val <%d>.",
  1927. X         n, pp[ n ] );
  1928. X      bwb_debug( bwb_ebuf );
  1929. X      }
  1930. X#endif
  1931. X
  1932. X   p = v->memstr;
  1933. X   return (p + offset);
  1934. X
  1935. X   }
  1936. X
  1937. X/***************************************************************
  1938. X
  1939. X        FUNCTION:       dim_check()
  1940. X
  1941. X        DESCRIPTION:    This function checks subscripts of a
  1942. X                        specific variable to be sure that they
  1943. X                        are within the correct range.
  1944. X
  1945. X***************************************************************/
  1946. X
  1947. X#if ANSI_C
  1948. Xstatic int
  1949. Xdim_check( struct bwb_variable *v, int *pp )
  1950. X#else
  1951. Xstatic int
  1952. Xdim_check( v, pp )
  1953. X   struct bwb_variable *v;
  1954. X   int *pp;
  1955. X#endif
  1956. X   {
  1957. X   register int n;
  1958. X
  1959. X   /* Check for dimensions */
  1960. X
  1961. X   if ( v->dimensions < 1 )
  1962. X      {
  1963. X#if PROG_ERRORS
  1964. X      sprintf( bwb_ebuf, "in dim_check(): var <%s> dimensions <%d>",
  1965. X         v->name, v->dimensions );
  1966. X      bwb_error( bwb_ebuf );
  1967. X#else
  1968. X      bwb_error( err_valoorange );
  1969. X#endif
  1970. X      return FALSE;
  1971. X      }
  1972. X
  1973. X   /* Check for validly allocated array */
  1974. X
  1975. X   if (( v->type == NUMBER ) && ( v->memnum == NULL ))
  1976. X      {
  1977. X#if PROG_ERRORS
  1978. X      sprintf( bwb_ebuf, "in dim_check(): numerical var <%s> memnum not allocated",
  1979. X     v->name );
  1980. X      bwb_error( bwb_ebuf );
  1981. X#else
  1982. X      bwb_error( err_valoorange );
  1983. X#endif
  1984. X      return FALSE;
  1985. X      }
  1986. X
  1987. X   if (( v->type == STRING ) && ( v->memstr == NULL ))
  1988. X      {
  1989. X#if PROG_ERRORS
  1990. X      sprintf( bwb_ebuf, "in dim_check(): string var <%s> memstr not allocated",
  1991. X     v->name );
  1992. X      bwb_error( bwb_ebuf );
  1993. X#else
  1994. X      bwb_error( err_valoorange );
  1995. X#endif
  1996. X      return FALSE;
  1997. X      }
  1998. X
  1999. X   /* Now check subscript values */
  2000. X
  2001. X   for ( n = 0; n < v->dimensions; ++n )
  2002. X      {
  2003. X      if ( ( pp[ n ] < dim_base ) || ( ( pp[ n ] - dim_base )
  2004. X         > v->array_sizes[ n ] ))
  2005. X         {
  2006. X#if PROG_ERRORS
  2007. X         sprintf( bwb_ebuf, "in dim_check(): array subscript var <%s> pos <%d> val <%d> out of range <%d>-<%d>.",
  2008. X            v->name, n, pp[ n ], dim_base, v->array_sizes[ n ]  );
  2009. X         bwb_error( bwb_ebuf );
  2010. X#else
  2011. X         bwb_error( err_valoorange );
  2012. X#endif
  2013. X         return FALSE;
  2014. X         }
  2015. X      }
  2016. X
  2017. X   /* No problems found */
  2018. X
  2019. X   return TRUE;
  2020. X
  2021. X   }
  2022. X
  2023. X/***************************************************************
  2024. X
  2025. X        FUNCTION:       var_make()
  2026. X
  2027. X        DESCRIPTION:    This function initializes a variable,
  2028. X                allocating necessary memory for it.
  2029. X
  2030. X***************************************************************/
  2031. X
  2032. X#if ANSI_C
  2033. Xint
  2034. Xvar_make( struct bwb_variable *v, int type )
  2035. X#else
  2036. Xint
  2037. Xvar_make( v, type )
  2038. X   struct bwb_variable *v;
  2039. X   int type;
  2040. X#endif
  2041. X   {
  2042. X   size_t data_size;
  2043. X   bstring *b;
  2044. X#if TEST_BSTRING
  2045. X   static int tnumber = 0;
  2046. X#endif
  2047. X
  2048. X   switch( type )
  2049. X      {
  2050. X      case STRING:
  2051. X         v->type = STRING;
  2052. X         data_size = sizeof( bstring );
  2053. X         break;
  2054. X      default:
  2055. X         v->type = NUMBER;
  2056. X         data_size = sizeof( bnumber );
  2057. X         break;
  2058. X      }
  2059. X
  2060. X   /* get memory for array */
  2061. X
  2062. X   if ( v->type == NUMBER )
  2063. X      {
  2064. X      if ( ( v->memnum = calloc( 2, sizeof( bnumber ) )) == NULL )
  2065. X     {
  2066. X     bwb_error( err_getmem );
  2067. X     return FALSE;
  2068. X     }
  2069. X      }
  2070. X   else
  2071. X      {
  2072. X      if ( ( v->memstr = calloc( 2, sizeof( bstring ) )) == NULL )
  2073. X     {
  2074. X     bwb_error( err_getmem );
  2075. X     return FALSE;
  2076. X     }
  2077. X      }
  2078. X
  2079. X   /* get memory for array_sizes and array_pos */
  2080. X
  2081. X   if ( ( v->array_sizes = (int *) calloc( 2, sizeof( int ) )) == NULL )
  2082. X      {
  2083. X      bwb_error( err_getmem );
  2084. X      return FALSE;
  2085. X      }
  2086. X
  2087. X   if ( ( v->array_pos = (int *) calloc( 2, sizeof( int ) )) == NULL )
  2088. X      {
  2089. X      bwb_error( err_getmem );
  2090. X      return FALSE;
  2091. X      }
  2092. X
  2093. X   v->array_pos[ 0 ] = dim_base;
  2094. X   v->array_sizes[ 0 ] = 1;
  2095. X   v->dimensions = 1;
  2096. X   v->common = FALSE;
  2097. X   v->array_units = 1;
  2098. X
  2099. X   if ( type == STRING )
  2100. X      {
  2101. X      b = var_findsval( v, v->array_pos );
  2102. X      b->rab = FALSE;
  2103. X      }
  2104. X
  2105. X#if INTENSIVE_DEBUG
  2106. X   sprintf( bwb_ebuf, "in var_make(): made variable <%s> type <%c> pos[ 0 ] <%d>",
  2107. X      v->name, v->type, v->array_pos[ 0 ] );
  2108. X   bwb_debug( bwb_ebuf );
  2109. X#endif
  2110. X
  2111. X#if TEST_BSTRING
  2112. X   if ( type == STRING )
  2113. X      {
  2114. X      b = var_findsval( v, v->array_pos );
  2115. X      sprintf( b->name, "bstring# %d", tnumber );
  2116. X      ++tnumber;
  2117. X      sprintf( bwb_ebuf, "in var_make(): new string variable <%s>",
  2118. X         b->name );
  2119. X      bwb_debug( bwb_ebuf );
  2120. X      }
  2121. X#endif
  2122. X
  2123. X   return TRUE;
  2124. X
  2125. X   }
  2126. X
  2127. X/***************************************************************
  2128. X
  2129. X    FUNCTION:       var_islocal()
  2130. X
  2131. X    DESCRIPTION:    This function determines whether the string
  2132. X            pointed to by 'buffer' has the name of
  2133. X            a local variable at the present EXEC stack
  2134. X            level.
  2135. X
  2136. X***************************************************************/
  2137. X
  2138. X#if ANSI_C
  2139. Xextern struct bwb_variable *
  2140. Xvar_islocal( char *buffer )
  2141. X#else
  2142. Xstruct bwb_variable *
  2143. Xvar_islocal( buffer )
  2144. X   char *buffer;
  2145. X#endif
  2146. X   {
  2147. X   struct bwb_variable *v;
  2148. X
  2149. X#if INTENSIVE_DEBUG
  2150. X   sprintf( bwb_ebuf, "in var_islocal(): check for local variable <%s> EXEC level <%d>",
  2151. X      buffer, CURTASK exsc );
  2152. X   bwb_debug( bwb_ebuf );
  2153. X#endif
  2154. X
  2155. X   /* run through the local variable list and try to find a match */
  2156. X
  2157. X   for ( v = CURTASK excs[ CURTASK exsc ].local_variable; v != NULL; v = v->next )
  2158. X      {
  2159. X
  2160. X#if INTENSIVE_DEBUG
  2161. X      sprintf( bwb_ebuf, "in var_islocal(): checking var <%s> level <%d>...",
  2162. X         v->name, CURTASK exsc );
  2163. X      bwb_debug( bwb_ebuf );
  2164. X#endif
  2165. X
  2166. X      if ( strcmp( v->name, buffer ) == 0 )
  2167. X         {
  2168. X
  2169. X#if PROG_ERRORS
  2170. X         switch( v->type )
  2171. X            {
  2172. X            case STRING:
  2173. X            case NUMBER:
  2174. X               break;
  2175. X            default:
  2176. X               sprintf( bwb_ebuf, "in var_islocal(): inappropriate precision for variable <%s>",
  2177. X                  v->name );
  2178. X               bwb_error( bwb_ebuf );
  2179. X               break;
  2180. X            }
  2181. X#endif
  2182. X
  2183. X#if INTENSIVE_DEBUG
  2184. X         sprintf( bwb_ebuf, "in var_islocal(): found local variable <%s>", v->name );
  2185. X         bwb_debug( bwb_ebuf );
  2186. X#endif
  2187. X
  2188. X         return v;
  2189. X         }
  2190. X
  2191. X      }
  2192. X
  2193. X   /* search failed, return NULL */
  2194. X
  2195. X#if INTENSIVE_DEBUG
  2196. X   sprintf( bwb_ebuf, "in var_islocal(): Failed to find local variable <%s> level <%d>",
  2197. X      buffer, CURTASK exsc );
  2198. X   bwb_debug( bwb_ebuf );
  2199. X#endif
  2200. X
  2201. X   return NULL;
  2202. X
  2203. X   }
  2204. X
  2205. X/***************************************************************
  2206. X
  2207. X        FUNCTION:       bwb_vars()
  2208. X
  2209. X        DESCRIPTION:    This function implements the Bywater-
  2210. X                specific debugging command VARS, which
  2211. X                gives a list of all variables defined
  2212. X                in memory.
  2213. X
  2214. X***************************************************************/
  2215. X
  2216. X#if PERMANENT_DEBUG
  2217. X
  2218. X#if ANSI_C
  2219. Xstruct bwb_line *
  2220. Xbwb_vars( struct bwb_line *l )
  2221. X#else
  2222. Xstruct bwb_line *
  2223. Xbwb_vars( l )
  2224. X   struct bwb_line *l;
  2225. X#endif
  2226. X   {
  2227. X   struct bwb_variable *v;
  2228. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  2229. X
  2230. X   /* run through the variable list and print variables */
  2231. X
  2232. X   for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next )
  2233. X      {
  2234. X      sprintf( bwb_ebuf, "variable <%s>\t", v->name );
  2235. X      prn_xprintf( stdout, bwb_ebuf );
  2236. X      switch( v->type )
  2237. X         {
  2238. X         case STRING:
  2239. X            str_btoc( tbuf, var_getsval( v ) );
  2240. X        sprintf( bwb_ebuf, "STRING\tval: <%s>\n", tbuf );
  2241. X        prn_xprintf( stdout, bwb_ebuf );
  2242. X            break;
  2243. X         case NUMBER:
  2244. X#if NUMBER_DOUBLE
  2245. X        sprintf( bwb_ebuf, "NUMBER\tval: <%lf>\n", var_getnval( v ) );
  2246. X        prn_xprintf( stdout, bwb_ebuf );
  2247. X#else
  2248. X        sprintf( bwb_ebuf, "NUMBER\tval: <%f>\n", var_getnval( v ) );
  2249. X        prn_xprintf( stdout, bwb_ebuf );
  2250. X#endif
  2251. X            break;
  2252. X         default:
  2253. X        sprintf( bwb_ebuf, "ERROR: type is <%c>", (char) v->type );
  2254. X        prn_xprintf( stdout, bwb_ebuf );
  2255. X            break;
  2256. X         }
  2257. X      }
  2258. X
  2259. X   return bwb_zline( l );
  2260. X   }
  2261. X
  2262. X#endif
  2263. X
  2264. END_OF_FILE
  2265.   if test 50907 -ne `wc -c <'bwbasic-2.10/bwb_var.c'`; then
  2266.     echo shar: \"'bwbasic-2.10/bwb_var.c'\" unpacked with wrong size!
  2267.   fi
  2268.   # end of 'bwbasic-2.10/bwb_var.c'
  2269. fi
  2270. if test -f 'bwbasic-2.10/bwbtest/writeinp.bas' -a "${1}" != "-c" ; then 
  2271.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwbtest/writeinp.bas'\"
  2272. else
  2273.   echo shar: Extracting \"'bwbasic-2.10/bwbtest/writeinp.bas'\" \(584 characters\)
  2274.   sed "s/^X//" >'bwbasic-2.10/bwbtest/writeinp.bas' <<'END_OF_FILE'
  2275. X10 rem WRITEINP.BAS -- Test WRITE # and INPUT # Statements
  2276. X20 print "WRITEINP.BAS -- Test WRITE # and INPUT # Statements"
  2277. X30 s1$ = "String 1"
  2278. X40 s2$ = "String 2"
  2279. X50 s3$ = "String 3"
  2280. X60 x1 = 1.1234567
  2281. X70 x2 = 2.2345678
  2282. X80 x3 = 3.3456789
  2283. X90 open "o", #1, "data.tmp"
  2284. X100 write #1, s1$, x1, s2$, x2, s3$, x3
  2285. X110 close #1
  2286. X120 print "This is what was written:"
  2287. X130 write s1$, x1, s2$, x2, s3$, x3
  2288. X140 open "i", #2, "data.tmp"
  2289. X150 input #2, b1$, n1, b2$, n2, b3$, n3
  2290. X160 close #2
  2291. X170 print "This is what was read:"
  2292. X180 write b1$, n1, b2$, n2, b3$, n3
  2293. X190 print "End of WRITEINP.BAS"
  2294. X200 end
  2295. END_OF_FILE
  2296.   if test 584 -ne `wc -c <'bwbasic-2.10/bwbtest/writeinp.bas'`; then
  2297.     echo shar: \"'bwbasic-2.10/bwbtest/writeinp.bas'\" unpacked with wrong size!
  2298.   fi
  2299.   # end of 'bwbasic-2.10/bwbtest/writeinp.bas'
  2300. fi
  2301. if test -f 'bwbasic-2.10/bwx_iqc.c' -a "${1}" != "-c" ; then 
  2302.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwx_iqc.c'\"
  2303. else
  2304.   echo shar: Extracting \"'bwbasic-2.10/bwx_iqc.c'\" \(14913 characters\)
  2305.   sed "s/^X//" >'bwbasic-2.10/bwx_iqc.c' <<'END_OF_FILE'
  2306. X/***************************************************************
  2307. X
  2308. X        bwx_iqc.c       Environment-dependent implementation
  2309. X                        of Bywater BASIC Interpreter
  2310. X            for IBM PC and Compatibles
  2311. X            using the Microsoft QuickC (tm) Compiler
  2312. X
  2313. X                        Copyright (c) 1993, Ted A. Campbell
  2314. X            Bywater Software
  2315. X
  2316. X                        email: tcamp@delphi.com
  2317. X
  2318. X        Copyright and Permissions Information:
  2319. X
  2320. X        All U.S. and international rights are claimed by the author,
  2321. X        Ted A. Campbell.
  2322. X
  2323. X    This software is released under the terms of the GNU General
  2324. X    Public License (GPL), which is distributed with this software
  2325. X    in the file "COPYING".  The GPL specifies the terms under
  2326. X    which users may copy and use the software in this distribution.
  2327. X
  2328. X    A separate license is available for commercial distribution,
  2329. X    for information on which you should contact the author.
  2330. X
  2331. X***************************************************************/
  2332. X
  2333. X#include <stdio.h>
  2334. X#include <stdlib.h>
  2335. X#include <setjmp.h>
  2336. X#include <bios.h>
  2337. X#include <graph.h>
  2338. X#include <signal.h>
  2339. X
  2340. X#include "bwbasic.h"
  2341. X#include "bwb_mes.h"
  2342. X
  2343. Xextern int prn_col;
  2344. Xextern jmp_buf mark;
  2345. Xshort oldfgd;
  2346. Xlong oldbgd;
  2347. Xint reset_mode = FALSE;
  2348. X
  2349. Xstatic int iqc_setpos( void );
  2350. X
  2351. X/***************************************************************
  2352. X
  2353. X        FUNCTION:       main()
  2354. X
  2355. X        DESCRIPTION:    As in any C program, main() is the basic
  2356. X                        function from which the rest of the
  2357. X                        program is called. Some environments,
  2358. X            however, provide their own main() functions
  2359. X            (Microsoft Windows (tm) is an example).
  2360. X            In these cases, the following code will
  2361. X            have to be included in the initialization
  2362. X            function that is called by the environment.
  2363. X
  2364. X***************************************************************/
  2365. X
  2366. Xvoid
  2367. Xmain( int argc, char **argv )
  2368. X   {
  2369. X#if MS_CMDS
  2370. X   struct videoconfig vc;
  2371. X   short videomode;
  2372. X
  2373. X   /* Save original foreground, background, and text position. */
  2374. X
  2375. X   _getvideoconfig( &vc );
  2376. X   oldfgd = _gettextcolor();
  2377. X   oldbgd = _getbkcolor();
  2378. X
  2379. X   if ( vc.mode != _TEXTC80 )
  2380. X      {
  2381. X      if ( _setvideomode( _TEXTC80 ) == 0 )
  2382. X         {
  2383. X     _getvideoconfig( &vc );
  2384. X     prn_xprintf( stderr, "Failed to set color video mode\n" );
  2385. X         }
  2386. X      else
  2387. X     {
  2388. X     reset_mode = FALSE;
  2389. X     }
  2390. X      }
  2391. X   else
  2392. X      {
  2393. X      reset_mode = FALSE;
  2394. X      }
  2395. X
  2396. X#endif       /* MS_CMDS */
  2397. X
  2398. X   bwb_init( argc, argv );
  2399. X
  2400. X#if INTERACTIVE
  2401. X   setjmp( mark );
  2402. X#endif
  2403. X
  2404. X   /* now set the number of colors available */
  2405. X
  2406. X   * var_findnval( co, co->array_pos ) = (bnumber) vc.numcolors;
  2407. X
  2408. X   /* main program loop */
  2409. X
  2410. X   while( !feof( stdin ) )        /* condition !feof( stdin ) added in v1.11 */
  2411. X      {
  2412. X      bwb_mainloop();
  2413. X      }
  2414. X
  2415. X   }
  2416. X
  2417. X/***************************************************************
  2418. X
  2419. X        FUNCTION:       bwx_signon()
  2420. X
  2421. X        DESCRIPTION:
  2422. X
  2423. X***************************************************************/
  2424. X
  2425. Xint
  2426. Xbwx_signon( void )
  2427. X   {
  2428. X
  2429. X   sprintf( bwb_ebuf, "\r%s %s\n", MES_SIGNON, VERSION );
  2430. X   prn_xprintf( stdout, bwb_ebuf );
  2431. X   sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT );
  2432. X   prn_xprintf( stdout, bwb_ebuf );
  2433. X#if PERMANENT_DEBUG
  2434. X   sprintf( bwb_ebuf, "\r%s\n", "Debugging Mode" );
  2435. X   prn_xprintf( stdout, bwb_ebuf );
  2436. X#else
  2437. X   sprintf( bwb_ebuf, "\r%s\n", MES_LANGUAGE );
  2438. X   prn_xprintf( stdout, bwb_ebuf );
  2439. X#endif
  2440. X
  2441. X   return TRUE;
  2442. X
  2443. X   }
  2444. X
  2445. X/***************************************************************
  2446. X
  2447. X        FUNCTION:       bwx_message()
  2448. X
  2449. X        DESCRIPTION:
  2450. X
  2451. X***************************************************************/
  2452. X
  2453. Xint
  2454. Xbwx_message( char *m )
  2455. X   {
  2456. X
  2457. X#if DEBUG
  2458. X   _outtext( "<MES>" );
  2459. X#endif
  2460. X
  2461. X   _outtext( m );
  2462. X
  2463. X   return TRUE;
  2464. X
  2465. X   }
  2466. X
  2467. X/***************************************************************
  2468. X
  2469. X    FUNCTION:       bwx_putc()
  2470. X
  2471. X    DESCRIPTION:
  2472. X
  2473. X***************************************************************/
  2474. X
  2475. Xextern int
  2476. Xbwx_putc( char c )
  2477. X   {
  2478. X   static char tbuf[ 2 ];
  2479. X
  2480. X   tbuf[ 0 ] = c;
  2481. X   tbuf[ 1 ] = '\0';
  2482. X   _outtext( tbuf );
  2483. X
  2484. X   return TRUE;
  2485. X
  2486. X   }
  2487. X
  2488. X/***************************************************************
  2489. X
  2490. X        FUNCTION:       bwx_error()
  2491. X
  2492. X        DESCRIPTION:
  2493. X
  2494. X***************************************************************/
  2495. X
  2496. Xint
  2497. Xbwx_errmes( char *m )
  2498. X   {
  2499. X   static char tbuf[ MAXSTRINGSIZE + 1 ];    /* this memory should be
  2500. X                           permanent in case of memory
  2501. X                           overrun errors */
  2502. X
  2503. X   if (( prn_col != 1 ) && ( errfdevice == stderr ))
  2504. X      {
  2505. X      prn_xprintf( errfdevice, "\n" );
  2506. X      }
  2507. X   if ( CURTASK number == 0 )
  2508. X      {
  2509. X      sprintf( tbuf, "\n%s: %s\n", ERRD_HEADER, m );
  2510. X      }
  2511. X   else
  2512. X      {
  2513. X      sprintf( tbuf, "\n%s %d: %s\n", ERROR_HEADER, CURTASK number, m );
  2514. X      }
  2515. X
  2516. X#if INTENSIVE_DEBUG
  2517. X   prn_xprintf( stderr, "<ERR>" );
  2518. X#endif
  2519. X
  2520. X   prn_xprintf( errfdevice, tbuf );
  2521. X
  2522. X   return TRUE;
  2523. X
  2524. X   }
  2525. X
  2526. X/***************************************************************
  2527. X
  2528. X        FUNCTION:       bwx_input()
  2529. X
  2530. X    DESCRIPTION:    As implemented here, the input facility
  2531. X            is a hybrid of _outtext output (which allows
  2532. X            the color to be set) and standard output
  2533. X            (which does not).  The reason is that I've
  2534. X            found it helpful to use the DOS facility
  2535. X            for text entry, with its backspace-delete
  2536. X            and recognition of the SIGINT, depite the
  2537. X            fact that its output goes to stdout.
  2538. X
  2539. X***************************************************************/
  2540. X
  2541. Xint
  2542. Xbwx_input( char *prompt, char *buffer )
  2543. X   {
  2544. X
  2545. X#if INTENSIVE_DEBUG
  2546. X   prn_xprintf( stdout, "<INP>" );
  2547. X#endif
  2548. X
  2549. X   prn_xprintf( stdout, prompt );
  2550. X
  2551. X   fgets( buffer, MAXREADLINESIZE, stdin );
  2552. X   prn_xprintf( stdout, "\n" );               /* let _outtext catch up */
  2553. X
  2554. X   * prn_getcol( stdout ) = 1;            /* reset column */
  2555. X
  2556. X   return TRUE;
  2557. X
  2558. X   }
  2559. X
  2560. X/***************************************************************
  2561. X
  2562. X        FUNCTION:       bwx_terminate()
  2563. X
  2564. X        DESCRIPTION:
  2565. X
  2566. X***************************************************************/
  2567. X
  2568. Xvoid
  2569. Xbwx_terminate( void )
  2570. X   {
  2571. X#if MS_CMDS
  2572. X
  2573. X   if ( reset_mode == TRUE )
  2574. X      {
  2575. X
  2576. X      _setvideomode( _DEFAULTMODE );
  2577. X
  2578. X      /* Restore original foreground and background. */
  2579. X
  2580. X      _settextcolor( oldfgd );
  2581. X      _setbkcolor( oldbgd );
  2582. X
  2583. X      }
  2584. X
  2585. X#endif
  2586. X
  2587. X   exit( 0 );
  2588. X   }
  2589. X
  2590. X/***************************************************************
  2591. X
  2592. X    FUNCTION:       bwx_shell()
  2593. X
  2594. X    DESCRIPTION:
  2595. X
  2596. X***************************************************************/
  2597. X
  2598. X#if COMMAND_SHELL
  2599. Xextern int
  2600. Xbwx_shell( struct bwb_line *l )
  2601. X   {
  2602. X   static char *s_buffer;
  2603. X   static int init = FALSE;
  2604. X   static int position;
  2605. X
  2606. X   /* get memory for temporary buffer if necessary */
  2607. X
  2608. X   if ( init == FALSE )
  2609. X      {
  2610. X      init = TRUE;
  2611. X      if ( ( s_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  2612. X     {
  2613. X     bwb_error( err_getmem );
  2614. X     return FALSE;
  2615. X     }
  2616. X      }
  2617. X
  2618. X   /* get the first element and check for a line number */
  2619. X
  2620. X#if INTENSIVE_DEBUG
  2621. X   sprintf( bwb_ebuf, "in bwx_shell(): line buffer is <%s>.", l->buffer );
  2622. X   bwb_debug( bwb_ebuf );
  2623. X#endif
  2624. X
  2625. X   position = 0;
  2626. X   adv_element( l->buffer, &position, s_buffer );
  2627. X   if ( is_numconst( s_buffer ) != TRUE )                  /* not a line number */
  2628. X      {
  2629. X
  2630. X#if INTENSIVE_DEBUG
  2631. X      sprintf( bwb_ebuf, "in bwx_shell(): no line number, command <%s>.",
  2632. X     l->buffer );
  2633. X      bwb_debug( bwb_ebuf );
  2634. X#endif
  2635. X
  2636. X      if ( system( l->buffer ) == 0 )
  2637. X     {
  2638. X     iqc_setpos();
  2639. X     return TRUE;
  2640. X     }
  2641. X      else
  2642. X     {
  2643. X     iqc_setpos();
  2644. X     return FALSE;
  2645. X     }
  2646. X      }
  2647. X
  2648. X   else                                         /* advance past line number */
  2649. X      {
  2650. X      adv_ws( l->buffer, &position );           /* advance past whitespace */
  2651. X
  2652. X#if INTENSIVE_DEBUG
  2653. X      sprintf( bwb_ebuf, "in bwx_shell(): line number, command <%s>.",
  2654. X     l->buffer );
  2655. X      bwb_debug( bwb_ebuf );
  2656. X#endif
  2657. X
  2658. X      if ( system( &( l->buffer[ position ] ) ) == 0 )
  2659. X     {
  2660. X     iqc_setpos();
  2661. X     return TRUE;
  2662. X     }
  2663. X      else
  2664. X     {
  2665. X     iqc_setpos();
  2666. X     return FALSE;
  2667. X     }
  2668. X      }
  2669. X   }
  2670. X#endif
  2671. X
  2672. X/***************************************************************
  2673. X
  2674. X    FUNCTION:      iqc_setpos()
  2675. X
  2676. X    DESCRIPTION:
  2677. X
  2678. X***************************************************************/
  2679. X
  2680. Xstatic int
  2681. Xiqc_setpos( void )
  2682. X   {
  2683. X   union REGS ibm_registers;
  2684. X
  2685. X   /* call the BDOS function 0x10 to read the current cursor position */
  2686. X
  2687. X   ibm_registers.h.ah = 3;
  2688. X   ibm_registers.h.bh = (unsigned char) _getvisualpage();
  2689. X   int86( 0x10, &ibm_registers, &ibm_registers );
  2690. X
  2691. X   /* set text to this position */
  2692. X
  2693. X   _settextposition( ibm_registers.h.dh, ibm_registers.h.dl );
  2694. X
  2695. X   /* and move down one position */
  2696. X
  2697. X   prn_xprintf( stdout, "\n" );
  2698. X
  2699. X   return TRUE;
  2700. X   }
  2701. X
  2702. X
  2703. X#if COMMON_CMDS
  2704. X
  2705. X/***************************************************************
  2706. X
  2707. X        FUNCTION:       bwb_edit()
  2708. X
  2709. X        DESCRIPTION:
  2710. X
  2711. X***************************************************************/
  2712. X
  2713. Xstruct bwb_line *
  2714. Xbwb_edit( struct bwb_line *l )
  2715. X   {
  2716. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  2717. X   char edname[ MAXSTRINGSIZE + 1 ];
  2718. X   struct bwb_variable *ed;
  2719. X   FILE *loadfile;
  2720. X
  2721. X   ed = var_find( DEFVNAME_EDITOR );
  2722. X   str_btoc( edname, var_getsval( ed ));
  2723. X
  2724. X   sprintf( tbuf, "%s %s", edname, CURTASK progfile );
  2725. X
  2726. X#if INTENSIVE_DEBUG
  2727. X   sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf );
  2728. X   bwb_debug( bwb_ebuf );
  2729. X#else
  2730. X   system( tbuf );
  2731. X#endif
  2732. X
  2733. X   /* clear current contents */
  2734. X
  2735. X   bwb_new( l );
  2736. X
  2737. X   /* open edited file for read */
  2738. X
  2739. X   if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
  2740. X      {
  2741. X      sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
  2742. X      bwb_error( bwb_ebuf );
  2743. X
  2744. X      iqc_setpos();
  2745. X      return bwb_zline( l );
  2746. X      }
  2747. X
  2748. X   /* and (re)load the file into memory */
  2749. X
  2750. X   bwb_fload( loadfile );
  2751. X
  2752. X
  2753. X   iqc_setpos();
  2754. X   return bwb_zline( l );
  2755. X   }
  2756. X
  2757. X/***************************************************************
  2758. X
  2759. X        FUNCTION:       bwb_files()
  2760. X
  2761. X        DESCRIPTION:
  2762. X
  2763. X***************************************************************/
  2764. X
  2765. Xstruct bwb_line *
  2766. Xbwb_files( struct bwb_line *l )
  2767. X   {
  2768. X   char tbuf[ MAXVARNAMESIZE + 1 ];
  2769. X   char finame[ MAXVARNAMESIZE + 1 ];
  2770. X   char argument[ MAXVARNAMESIZE + 1 ];
  2771. X   struct bwb_variable *fi;
  2772. X   struct exp_ese *e;
  2773. X
  2774. X   fi = var_find( DEFVNAME_FILES );
  2775. X   str_btoc( finame, var_getsval( fi ));
  2776. X
  2777. X   /* get argument */
  2778. X
  2779. X   adv_ws( l->buffer, &( l->position ));
  2780. X   switch( l->buffer[ l->position ] )
  2781. X      {
  2782. X      case '\0':
  2783. X      case '\r':
  2784. X      case '\n':
  2785. X         argument[ 0 ] = '\0';
  2786. X         break;
  2787. X      default:
  2788. X         e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  2789. X         if ( e->type != STRING )
  2790. X            {
  2791. X            bwb_error( err_mismatch );
  2792. X            return bwb_zline( l );
  2793. X            }
  2794. X         str_btoc( argument, exp_getsval( e ) );
  2795. X         break;
  2796. X      }
  2797. X
  2798. X
  2799. X   sprintf( tbuf, "%s %s", finame, argument );
  2800. X
  2801. X#if INTENSIVE_DEBUG
  2802. X   sprintf( bwb_ebuf, "in bwb_files(): command line <%s>", tbuf );
  2803. X   bwb_debug( bwb_ebuf );
  2804. X#else
  2805. X   system( tbuf );
  2806. X#endif
  2807. X
  2808. X   iqc_setpos();
  2809. X   return bwb_zline( l );
  2810. X
  2811. X   }
  2812. X
  2813. X#endif                    /* COMMON_CMDS */
  2814. X
  2815. X#if INTERACTIVE
  2816. X
  2817. X/***************************************************************
  2818. X
  2819. X        FUNCTION:       fnc_inkey()
  2820. X
  2821. X        DESCRIPTION:    This C function implements the BASIC INKEY$
  2822. X                function.  It is implementation-specific.
  2823. X
  2824. X***************************************************************/
  2825. X
  2826. Xextern struct bwb_variable *
  2827. Xfnc_inkey( int argc, struct bwb_variable *argv )
  2828. X   {
  2829. X   static struct bwb_variable nvar;
  2830. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  2831. X   static int init = FALSE;
  2832. X
  2833. X   /* initialize the variable if necessary */
  2834. X
  2835. X   if ( init == FALSE )
  2836. X      {
  2837. X      init = TRUE;
  2838. X      var_make( &nvar, STRING );
  2839. X      }
  2840. X
  2841. X   /* check arguments */
  2842. X
  2843. X#if PROG_ERRORS
  2844. X   if ( argc > 0 )
  2845. X      {
  2846. X      sprintf( bwb_ebuf, "Two many arguments to function INKEY$()" );
  2847. X      bwb_error( bwb_ebuf );
  2848. X      return &nvar;
  2849. X      }
  2850. X
  2851. X#else
  2852. X   if ( fnc_checkargs( argc, argv, 0, 0 ) == FALSE )
  2853. X      {
  2854. X      return NULL;
  2855. X      }
  2856. X#endif
  2857. X
  2858. X   /* body of the INKEY$ function */
  2859. X
  2860. X   if ( _bios_keybrd( _KEYBRD_READY ) == 0 )
  2861. X      {
  2862. X      tbuf[ 0 ] = '\0';
  2863. X      }
  2864. X   else
  2865. X      {
  2866. X      tbuf[ 0 ] = (char) _bios_keybrd( _KEYBRD_READ );
  2867. X      tbuf[ 1 ] = '\0';
  2868. X      }
  2869. X
  2870. X   /* assign value to nvar variable */
  2871. X
  2872. X   str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  2873. X
  2874. X   /* return value contained in nvar */
  2875. X
  2876. X   return &nvar;
  2877. X
  2878. X   }
  2879. X
  2880. X#endif                /* INTERACTIVE */
  2881. X
  2882. X#if MS_CMDS
  2883. X
  2884. X/***************************************************************
  2885. X
  2886. X        FUNCTION:       bwb_cls()
  2887. X
  2888. X        DESCRIPTION:    This C function implements the BASIC CLS
  2889. X                command.  It is implementation-specific.
  2890. X
  2891. X***************************************************************/
  2892. X
  2893. Xextern struct bwb_line *
  2894. Xbwb_cls( struct bwb_line *l )
  2895. X   {
  2896. X
  2897. X   _clearscreen( _GCLEARSCREEN );
  2898. X
  2899. X   return bwb_zline( l );
  2900. X   }
  2901. X
  2902. X/***************************************************************
  2903. X
  2904. X        FUNCTION:       bwb_locate()
  2905. X
  2906. X        DESCRIPTION:    This C function implements the BASIC LOCATE
  2907. X                command.  It is implementation-specific.
  2908. X
  2909. X***************************************************************/
  2910. X
  2911. Xextern struct bwb_line *
  2912. Xbwb_locate( struct bwb_line *l )
  2913. X   {
  2914. X   struct exp_ese *e;
  2915. X   int row, column;
  2916. X
  2917. X   /* get first argument */
  2918. X
  2919. X   e = bwb_exp( l->buffer, FALSE, &( l->position ));
  2920. X   row = (int) exp_getnval( e );
  2921. X
  2922. X   /* advance past comma */
  2923. X
  2924. X   adv_ws( l->buffer, &( l->position ));
  2925. X   if ( l->buffer[ l->position ] != ',' )
  2926. X      {
  2927. X      bwb_error( err_syntax );
  2928. X      return bwb_zline( l );
  2929. X      }
  2930. X   ++( l->position );
  2931. X
  2932. X   /* get second argument */
  2933. X
  2934. X   e = bwb_exp( l->buffer, FALSE, &( l->position ));
  2935. X   column = (int) exp_getnval( e );
  2936. X
  2937. X   /* position the cursor */
  2938. X
  2939. X   _settextposition( row, column );
  2940. X
  2941. X   return bwb_zline( l );
  2942. X   }
  2943. X
  2944. X/***************************************************************
  2945. X
  2946. X    FUNCTION:       bwb_color()
  2947. X
  2948. X    DESCRIPTION:    This C function implements the BASIC COLOR
  2949. X            command.  It is implementation-specific.
  2950. X
  2951. X***************************************************************/
  2952. X
  2953. Xextern struct bwb_line *
  2954. Xbwb_color( struct bwb_line *l )
  2955. X   {
  2956. X   struct exp_ese *e;
  2957. X   int color;
  2958. X
  2959. X   /* get first argument */
  2960. X
  2961. X   e = bwb_exp( l->buffer, FALSE, &( l->position ));
  2962. X   color = (int) exp_getnval( e );
  2963. X
  2964. X#if INTENSIVE_DEBUG
  2965. X   sprintf( bwb_ebuf, "Setting text color to %d", color );
  2966. X   bwb_debug( bwb_ebuf );
  2967. X#endif
  2968. X
  2969. X   _settextcolor( (short) color );
  2970. X
  2971. X#if INTENSIVE_DEBUG
  2972. X   sprintf( bwb_ebuf, "Set text color to %d", color );
  2973. X   bwb_debug( bwb_ebuf );
  2974. X#endif
  2975. X
  2976. X   /* advance past comma */
  2977. X
  2978. X   adv_ws( l->buffer, &( l->position ));
  2979. X   if ( l->buffer[ l->position ] == ',' )
  2980. X      {
  2981. X
  2982. X      ++( l->position );
  2983. X
  2984. X      /* get second argument */
  2985. X
  2986. X      e = bwb_exp( l->buffer, FALSE, &( l->position ));
  2987. X      color = (int) exp_getnval( e );
  2988. X
  2989. X#if INTENSIVE_DEBUG
  2990. X      sprintf( bwb_ebuf, "Setting background color to %d", color );
  2991. X      bwb_debug( bwb_ebuf );
  2992. X#endif
  2993. X
  2994. X      /* set the background color */
  2995. X
  2996. X      _setbkcolor( (long) color );
  2997. X
  2998. X#if INTENSIVE_DEBUG
  2999. X      sprintf( bwb_ebuf, "Setting background color to %d\n", color );
  3000. X      bwb_debug( bwb_ebuf );
  3001. X#endif
  3002. X
  3003. X      }
  3004. X
  3005. X   return bwb_zline( l );
  3006. X   }
  3007. X
  3008. X#endif                /* MS_CMDS */
  3009. X
  3010. END_OF_FILE
  3011.   if test 14913 -ne `wc -c <'bwbasic-2.10/bwx_iqc.c'`; then
  3012.     echo shar: \"'bwbasic-2.10/bwx_iqc.c'\" unpacked with wrong size!
  3013.   fi
  3014.   # end of 'bwbasic-2.10/bwx_iqc.c'
  3015. fi
  3016. echo shar: End of archive 5 \(of 15\).
  3017. cp /dev/null ark5isdone
  3018. MISSING=""
  3019. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  3020.     if test ! -f ark${I}isdone ; then
  3021.     MISSING="${MISSING} ${I}"
  3022.     fi
  3023. done
  3024. if test "${MISSING}" = "" ; then
  3025.     echo You have unpacked all 15 archives.
  3026.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3027. else
  3028.     echo You still must unpack the following archives:
  3029.     echo "        " ${MISSING}
  3030. fi
  3031. exit 0
  3032. exit 0 # Just in case...
  3033.