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

  1. Newsgroups: comp.sources.misc
  2. From: tcamp@delphi.com (Ted A. Campbell)
  3. Subject: v40i055:  bwbasic - Bywater BASIC interpreter version 2.10, Part04/15
  4. Message-ID: <1993Oct29.162506.3537@sparky.sterling.com>
  5. X-Md4-Signature: ef4bc5de3fd9dac027682183ba78e8f0
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 29 Oct 1993 16:25:06 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: tcamp@delphi.com (Ted A. Campbell)
  12. Posting-number: Volume 40, Issue 55
  13. Archive-name: bwbasic/part04
  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/README bwbasic-2.10/bwb_stc.c
  22. #   bwbasic-2.10/configure
  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 4 (of 15)."'
  27. if test -f 'bwbasic-2.10/README' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'bwbasic-2.10/README'\"
  29. else
  30.   echo shar: Extracting \"'bwbasic-2.10/README'\" \(5592 characters\)
  31.   sed "s/^X//" >'bwbasic-2.10/README' <<'END_OF_FILE'
  32. X
  33. X
  34. X                        Bywater Software Announces
  35. X
  36. X
  37. X               Bywater BASIC Interpreter/Shell, version 2.10
  38. X               ---------------------------------------------
  39. X
  40. X                    Copyright (c) 1993, Ted A. Campbell
  41. X                  for bwBASIC version 2.10, 11 October 1993
  42. X
  43. X
  44. X
  45. XDESCRIPTION:
  46. X
  47. X   The Bywater BASIC Interpreter (bwBASIC) implements a large
  48. X   superset of the ANSI Standard for Minimal BASIC (X3.60-1978)
  49. X   and a significant subset of the ANSI Standard for Full BASIC
  50. X   (X3.113-1987) in C. It also offers shell programming facilities
  51. X   as an extension of BASIC. bwBASIC seeks to be as portable
  52. X   as possible.
  53. X
  54. X   This version of Bywater BASIC is released under the terms of the 
  55. X   GNU General Public License (GPL), which is distributed with this 
  56. X   software in the file "COPYING".  The GPL specifies the terms 
  57. X   under which users may copy and use the software in this distribution.
  58. X
  59. X   A separate license is available for commercial distribution,
  60. X   for information on which you should contact the author.
  61. X
  62. X
  63. XIMPROVEMENTS OVER PREVIOUS VERSION (1.11):
  64. X
  65. X   * now compilable on "stock" (older K&R specification) C compilers; 
  66. X
  67. X   * implements ANSI-BASIC-style structured programming, with
  68. X     called subroutines, multi-line functions, multi-line IF-THEN
  69. X     ELSE statements, SELECT CASE statements, etc.;
  70. X
  71. X   * new enhancements to the interactive environment, such as DO NUM
  72. X     and DO UNNUM to number or unnumber all program lines;
  73. X
  74. X   * addition of some hardware-specific commands such as CLS, LOCATE,
  75. X     and INKEY$ (at present for IBM PC and compatibles, using the
  76. X     Microsoft QuickC compiler), opening the way for more hardware-
  77. X     specific commands and functions in the future; 
  78. X
  79. X   * general improvements to reliability and portability, including
  80. X     more extensive testing than previous versions; 
  81. X
  82. X
  83. XOBTAINING THE SOURCE CODE:
  84. X
  85. X   The source code for bwBASIC 2.10 will be posted to network news
  86. X   groups and is available immediately by anonymous ftp. To obtain
  87. X   the source code, ftp to site ftp.eng.umd.edu, cd to pub/basic and
  88. X   get the file bwbasic-2.10.tar.gz.
  89. X
  90. X
  91. XCOMMUNICATIONS:
  92. X
  93. X   email:  tcamp@delphi.com
  94. X
  95. X
  96. XA LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC 2.10:
  97. X
  98. X   Be aware that many of these commands and functions will not be
  99. X   available unless you have set certain flags in the header files.
  100. X
  101. X   ABS( number )
  102. X   ASC( string$ )
  103. X   ATN( number )
  104. X   CALL subroutine-name
  105. X   CASE constant | IF partial-expression | ELSE
  106. X   CHAIN file-name
  107. X   CHDIR pathname
  108. X   CHR$( number )
  109. X   CINT( number )
  110. X   CLEAR
  111. X   CLOSE [[#]file-number]...
  112. X   CLS
  113. X   COMMON variable [, variable...]
  114. X   COS( number )
  115. X   CSNG( number )
  116. X   CVD( string$ )
  117. X   CVI( string$ )
  118. X   CVS( string$ )
  119. X   DATA constant[,constant]...
  120. X   DATE$
  121. X   DEF FNname(arg...)] = expression
  122. X   DEFDBL letter[-letter](, letter[-letter])...
  123. X   DEFINT letter[-letter](, letter[-letter])...
  124. X   DEFSNG letter[-letter](, letter[-letter])...
  125. X   DEFSTR letter[-letter](, letter[-letter])...
  126. X   DELETE line[-line]
  127. X   DIM variable(elements...)[variable(elements...)]...
  128. X   DO NUM|UNNUM
  129. X   DO [WHILE expression]
  130. X   EDIT        (* depends on variable BWB.EDITOR$)
  131. X   ELSE
  132. X   ELSEIF
  133. X   END FUNCTION | IF | SELECT | SUB
  134. X   ENVIRON variable-string$ = string$
  135. X   ENVIRON$( variable-string )
  136. X   EOF( device-number )
  137. X   ERASE variable[, variable]...
  138. X   ERL
  139. X   ERR
  140. X   ERROR number
  141. X   EXIT FOR|DO
  142. X   EXP( number )
  143. X   FIELD [#] device-number, number AS string-variable [, number AS string-variable...]
  144. X   FILES filespec$    (* depends on variable BWB.FILES$)
  145. X   FOR counter = start TO finish [STEP increment]
  146. X   FUNCTION function-definition
  147. X   GET [#] device-number [, record-number]
  148. X   GOSUB line | label
  149. X   GOTO line | label
  150. X   HEX$( number )
  151. X   IF expression THEN [statement [ELSE statement]]
  152. X   INKEY$
  153. X   INPUT [# device-number]|[;]["prompt string";]list of variables
  154. X   INSTR( [start-position,] string-searched$, string-pattern$ )
  155. X   INT( number )
  156. X   KILL file-name
  157. X   LEFT$( string$, number-of-spaces )
  158. X   LEN( string$ )
  159. X   LET variable = expression
  160. X   LINE INPUT [[#] device-number,]["prompt string";] string-variable$
  161. X   LIST line[-line]
  162. X   LOAD file-name
  163. X   LOC( device-number )
  164. X   LOCATE
  165. X   LOF( device-number )
  166. X   LOG( number )
  167. X   LOOP [UNTIL expression]
  168. X   LSET string-variable$ = expression
  169. X   MERGE file-name
  170. X   MID$( string$, start-position-in-string[, number-of-spaces ] )
  171. X   MKD$( number )
  172. X   MKDIR pathname
  173. X   MKI$( number )
  174. X   MKS$( number )
  175. X   NAME old-file-name AS new-file-name
  176. X   NEW
  177. X   NEXT counter
  178. X   OCT$( number )
  179. X   ON variable GOTO|GOSUB line[,line,line,...]
  180. X   ON ERROR GOSUB line | label
  181. X   OPEN O|I|R, [#]device-number, file-name [,record length]
  182. X        file-name FOR INPUT|OUTPUT|APPEND AS [#]device-number [LEN = record-length]
  183. X   OPTION BASE number
  184. X   POS
  185. X   PRINT [# device-number,][USING format-string$;] expressions...
  186. X   PUT [#] device-number [, record-number]
  187. X   RANDOMIZE number
  188. X   READ variable[, variable]...
  189. X   REM string
  190. X   RESTORE line
  191. X   RETURN
  192. X   RIGHT$( string$, number-of-spaces )
  193. X   RMDIR pathname
  194. X   RND( number )
  195. X   RSET string-variable$ = expression
  196. X   RUN [line]|[file-name]
  197. X   SAVE file-name
  198. X   SELECT CASE expression
  199. X   SGN( number )
  200. X   SIN( number )
  201. X   SPACE$( number )
  202. X   SPC( number )
  203. X   SQR( number )
  204. X   STOP
  205. X   STR$( number )
  206. X   STRING$( number, ascii-value|string$ )
  207. X   SUB subroutine-name
  208. X   SWAP variable, variable
  209. X   SYSTEM
  210. X   TAB( number )
  211. X   TAN( number )
  212. X   TIME$
  213. X   TIMER
  214. X   TROFF
  215. X   TRON
  216. X   VAL( string$ )
  217. X   WEND
  218. X   WHILE expression
  219. X   WIDTH [# device-number,] number
  220. X   WRITE [# device-number,] element [, element ]....
  221. X
  222. END_OF_FILE
  223.   if test 5592 -ne `wc -c <'bwbasic-2.10/README'`; then
  224.     echo shar: \"'bwbasic-2.10/README'\" unpacked with wrong size!
  225.   fi
  226.   # end of 'bwbasic-2.10/README'
  227. fi
  228. if test -f 'bwbasic-2.10/bwb_stc.c' -a "${1}" != "-c" ; then 
  229.   echo shar: Will not clobber existing file \"'bwbasic-2.10/bwb_stc.c'\"
  230. else
  231.   echo shar: Extracting \"'bwbasic-2.10/bwb_stc.c'\" \(52211 characters\)
  232.   sed "s/^X//" >'bwbasic-2.10/bwb_stc.c' <<'END_OF_FILE'
  233. X/***************************************************************
  234. X
  235. X        bwb_stc.c       Commands Related to Structured Programming
  236. X                        for Bywater BASIC Interpreter
  237. X
  238. X                        Commands:    CALL
  239. X                    SUB
  240. X                    FUNCTION
  241. X                    END SUB
  242. X                    END FUNCTION
  243. X
  244. X                        Copyright (c) 1993, Ted A. Campbell
  245. X                        Bywater Software
  246. X
  247. X                        email: tcamp@delphi.com
  248. X
  249. X        Copyright and Permissions Information:
  250. X
  251. X        All U.S. and international rights are claimed by the author,
  252. X        Ted A. Campbell.
  253. X
  254. X    This software is released under the terms of the GNU General
  255. X    Public License (GPL), which is distributed with this software
  256. X    in the file "COPYING".  The GPL specifies the terms under
  257. X    which users may copy and use the software in this distribution.
  258. X
  259. X    A separate license is available for commercial distribution,
  260. X    for information on which you should contact the author.
  261. X
  262. X***************************************************************/
  263. X
  264. X#include <stdio.h>
  265. X#include <ctype.h>
  266. X
  267. X#include "bwbasic.h"
  268. X#include "bwb_mes.h"
  269. X
  270. X/* prototypes */
  271. X
  272. X#if ANSI_C
  273. Xstatic int fslt_clear( void );
  274. Xstatic int fslt_add( struct bwb_line *line, int *position, int code );
  275. Xstatic struct bwb_line *fslt_findl( char *buffer );
  276. Xstatic struct fslte    *fslt_findf( char *buffer );
  277. Xstatic int scan_getcmd( struct bwb_line *line, int *position );
  278. Xstatic int scan_readargs( struct fslte *f,
  279. X   struct bwb_line *line, int *position );
  280. Xstatic int call_readargs( struct fslte *f,
  281. X   char *expression, int *position );
  282. Xstatic int is_endsub( struct bwb_line *l );
  283. Xstatic struct bwb_line *find_endsub( struct bwb_line *l );
  284. Xstatic struct bwb_line *bwb_loopuntil( struct bwb_line *l );
  285. Xstruct bwb_variable *bwb_vtov( struct bwb_variable *dst, struct bwb_variable *src );
  286. Xstruct bwb_variable *bwb_etov( struct bwb_variable *dst, struct exp_ese *src );
  287. Xstruct bwb_variable *var_pos( struct bwb_variable *firstvar, int p );
  288. Xint fslt_addcallvar( struct bwb_variable *v );
  289. Xint fslt_addlocalvar( struct fslte *f, struct bwb_variable *v );
  290. X#else
  291. Xstatic int fslt_clear();
  292. Xstatic int fslt_add();
  293. Xstatic struct bwb_line *fslt_findl();
  294. Xstatic struct fslte    *fslt_findf();
  295. Xstatic int scan_getcmd();
  296. Xstatic int scan_readargs();
  297. Xstatic int call_readargs();
  298. Xstatic int is_endsub();
  299. Xstatic struct bwb_line *find_endsub();
  300. Xstatic struct bwb_line *bwb_loopuntil();
  301. Xstruct bwb_variable *bwb_vtov();
  302. Xstruct bwb_variable *bwb_etov();
  303. Xstruct bwb_variable *var_pos();
  304. Xint fslt_addcallvar();
  305. Xint fslt_addlocalvar();
  306. X#endif                /* ANSI_C for prototypes */
  307. X
  308. X/***************************************************************
  309. X
  310. X        FUNCTION:       bwb_scan()
  311. X
  312. X        DESCRIPTION:    This function scans all lines of the
  313. X                program in memory and creates a FUNCTION-
  314. X                SUB lookup table (fslt) for the program.
  315. X
  316. X***************************************************************/
  317. X
  318. X#if ANSI_C
  319. Xint
  320. Xbwb_scan( void )
  321. X#else
  322. Xint
  323. Xbwb_scan()
  324. X#endif
  325. X   {
  326. X   struct bwb_line *current;
  327. X   int position;
  328. X   int c;
  329. X
  330. X#if PROG_ERRORS
  331. X   if ( CURTASK rescan != TRUE )
  332. X      {
  333. X      bwb_error( "in bwb_scan(): call to scan while CURTASK rescan != TRUE" );
  334. X      return FALSE;
  335. X      }
  336. X#endif
  337. X
  338. X#if INTENSIVE_DEBUG
  339. X   sprintf( bwb_ebuf, "in bwb_scan(): beginning scan..." );
  340. X   bwb_debug( bwb_ebuf );
  341. X#endif
  342. X
  343. X   /* first run through the FUNCTION - SUB loopkup table
  344. X      and free any existing memory */
  345. X
  346. X   fslt_clear();
  347. X
  348. X   /* run through the list of lines and identify SUB and FUNCTION statements */
  349. X
  350. X   for ( current = CURTASK bwb_start.next; current != &CURTASK bwb_end; current = current->next )
  351. X      {
  352. X
  353. X#if INTENSIVE_DEBUG
  354. X      sprintf( bwb_ebuf, "in bwb_scan(): scanning line <%d>", current->number );
  355. X      bwb_debug( bwb_ebuf );
  356. X#endif
  357. X
  358. X      c = scan_getcmd( current, &position );
  359. X      if ( c == getcmdnum( CMD_SUB ))
  360. X         {
  361. X         fslt_add( current, &position, EXEC_CALLSUB );
  362. X         }
  363. X      else if ( c == getcmdnum( CMD_FUNCTION ))
  364. X         {
  365. X         fslt_add( current, &position, EXEC_FUNCTION );
  366. X         }
  367. X      else if ( c == getcmdnum( CMD_DEF ))
  368. X         {
  369. X         fslt_add( current, &position, EXEC_FUNCTION );
  370. X         }
  371. X#if STRUCT_CMDS
  372. X      else if ( c == getcmdnum( CMD_LABEL ))
  373. X         {
  374. X         fslt_add( current, &position, EXEC_LABEL );
  375. X         }
  376. X#endif
  377. X      }
  378. X
  379. X   /* return */
  380. X
  381. X   CURTASK rescan = FALSE;
  382. X   return TRUE;
  383. X
  384. X   }
  385. X
  386. X/***************************************************************
  387. X
  388. X        FUNCTION:       fslt_clear()
  389. X
  390. X        DESCRIPTION:    This C function clears all existing memory
  391. X                in the FUNCTION-SUB lookup table.
  392. X
  393. X***************************************************************/
  394. X
  395. X#if ANSI_C
  396. Xstatic int
  397. Xfslt_clear( void )
  398. X#else
  399. Xstatic int
  400. Xfslt_clear()
  401. X#endif
  402. X   {
  403. X   struct fslte *current, *next;
  404. X   struct bwb_variable *c, *n;
  405. X
  406. X   /* run through table and clear memory */
  407. X
  408. X   next = CURTASK fslt_start.next;
  409. X   for ( current = CURTASK fslt_start.next; current != &CURTASK fslt_end;
  410. X      current = next )
  411. X      {
  412. X
  413. X      /* check for local variables and free them */
  414. X
  415. X      c = current->local_variable;
  416. X      while ( c != NULL )
  417. X         {
  418. X         n = c->next;
  419. X         free( c );
  420. X         c = n;
  421. X         }
  422. X
  423. X      next = current->next;
  424. X      free( current );
  425. X      }
  426. X
  427. X   /* reset linkage */
  428. X
  429. X   CURTASK fslt_start.next = &CURTASK fslt_end;
  430. X
  431. X   return TRUE;
  432. X   }
  433. X
  434. X/***************************************************************
  435. X
  436. X        FUNCTION:       scan_getcmd()
  437. X
  438. X        DESCRIPTION:    This command returns the command number
  439. X                for the first BASIC command word encountered
  440. X                in a line.
  441. X
  442. X***************************************************************/
  443. X
  444. X#if ANSI_C
  445. Xstatic int
  446. Xscan_getcmd( struct bwb_line *line, int *position )
  447. X#else
  448. Xstatic int
  449. Xscan_getcmd( line, position )
  450. X   struct bwb_line *line;
  451. X   int *position;
  452. X#endif
  453. X   {
  454. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  455. X
  456. X   *position = 0;
  457. X   adv_ws( line->buffer, position );
  458. X
  459. X   /* check for NULL line */
  460. X
  461. X   if ( line->buffer[ *position ] == '\0' )
  462. X      {
  463. X      return -1;
  464. X      }
  465. X
  466. X   /* check for line number and advance beyond it */
  467. X
  468. X   if ( isdigit( line->buffer[ *position ] ))
  469. X      {
  470. X      scan_element( line->buffer, position, tbuf );
  471. X      }
  472. X
  473. X   /* get the command element in the buffer */
  474. X
  475. X   scan_element( line->buffer, position, tbuf );
  476. X
  477. X#if INTENSIVE_DEBUG
  478. X   sprintf( bwb_ebuf, "in scan_getcmd(): scanning element <%s>", tbuf );
  479. X   bwb_debug( bwb_ebuf );
  480. X#endif
  481. X
  482. X#if STRUCT_CMDS
  483. X
  484. X   if ( is_label( tbuf ) == TRUE )
  485. X      {
  486. X#if INTENSIVE_DEBUG
  487. X      sprintf( bwb_ebuf, "in scan_getcmd(): found label <%s>", tbuf );
  488. X      bwb_debug( bwb_ebuf );
  489. X#endif
  490. X
  491. X      return getcmdnum( CMD_LABEL );
  492. X      }
  493. X
  494. X#endif
  495. X
  496. X   bwb_strtoupper( tbuf );
  497. X
  498. X   /* return command number */
  499. X
  500. X   return getcmdnum( tbuf );
  501. X
  502. X   }
  503. X
  504. X/***************************************************************
  505. X
  506. X    FUNCTION:       scan_element()
  507. X
  508. X        DESCRIPTION:    This function reads characters in <buffer>
  509. X                        beginning at <pos> and advances past a
  510. X                        line element, incrementing <pos> appropri-
  511. X                        ately and returning the line element in
  512. X            <element>.
  513. X
  514. X            This function is almost identical to adv_element(),
  515. X            but it will not stop at a full colon.  This is
  516. X            necessary to detect a label in the first element
  517. X            position.  If MULTISEG_LINES is defined as TRUE,
  518. X            adv_element() will stop at the colon, interpreting
  519. X            it as the end-of-segment marker.
  520. X
  521. X***************************************************************/
  522. X
  523. X#if ANSI_C
  524. Xextern int
  525. Xscan_element( char *buffer, int *pos, char *element )
  526. X#else
  527. Xint
  528. Xscan_element( buffer, pos, element )
  529. X   char *buffer;
  530. X   int *pos;
  531. X   char *element;
  532. X#endif
  533. X   {
  534. X   int loop;                                    /* control loop */
  535. X   int e_pos;                                   /* position in element buffer */
  536. X   int str_const;                               /* boolean: building a string constant */
  537. X
  538. X   /* advance beyond any initial whitespace */
  539. X
  540. X   adv_ws( buffer, pos );
  541. X
  542. X#if INTENSIVE_DEBUG
  543. X   sprintf( bwb_ebuf, "in adv_element(): receieved <%s>.", &( buffer[ *pos ] ));
  544. X   bwb_debug( bwb_ebuf );
  545. X#endif
  546. X
  547. X   /* now loop while building an element and looking for an
  548. X      element terminator */
  549. X
  550. X   loop = TRUE;
  551. X   e_pos = 0;
  552. X   element[ e_pos ] = '\0';
  553. X   str_const = FALSE;
  554. X
  555. X   while ( loop == TRUE )
  556. X      {
  557. X      switch( buffer[ *pos ] )
  558. X         {
  559. X         case ',':                      /* element terminators */
  560. X         case ';':
  561. X     case '=':
  562. X     case ' ':
  563. X         case '\t':
  564. X         case '\0':
  565. X         case '\n':
  566. X         case '\r':
  567. X            if ( str_const == TRUE )
  568. X               {
  569. X               element[ e_pos ] = buffer[ *pos ];
  570. X               ++e_pos;
  571. X               ++( *pos );
  572. X               element[ e_pos ] = '\0';
  573. X               }
  574. X            else
  575. X               {
  576. X               return TRUE;
  577. X               }
  578. X            break;
  579. X
  580. X         case '\"':                     /* string constant */
  581. X            element[ e_pos ] = buffer[ *pos ];
  582. X            ++e_pos;
  583. X            ++( *pos );
  584. X            element[ e_pos ] = '\0';
  585. X            if ( str_const == TRUE )    /* termination of string constant */
  586. X               {
  587. X               return TRUE;
  588. X               }
  589. X            else                        /* beginning of string constant */
  590. X               {
  591. X               str_const = TRUE;
  592. X               }
  593. X            break;
  594. X
  595. X         default:
  596. X            element[ e_pos ] = buffer[ *pos ];
  597. X            ++e_pos;
  598. X            ++( *pos );
  599. X            element[ e_pos ] = '\0';
  600. X            break;
  601. X         }
  602. X      }
  603. X
  604. X   /* This should not happen */
  605. X
  606. X   return FALSE;
  607. X
  608. X   }
  609. X
  610. X/***************************************************************
  611. X
  612. X        FUNCTION:       fslt_add()
  613. X
  614. X        DESCRIPTION:    This C function adds an entry to the
  615. X                FUNCTION-SUB lookup table.
  616. X
  617. X***************************************************************/
  618. X
  619. X#if ANSI_C
  620. Xstatic int
  621. Xfslt_add( struct bwb_line *line, int *position, int code )
  622. X#else
  623. Xstatic int
  624. Xfslt_add( line, position, code )
  625. X   struct bwb_line *line;
  626. X   int *position;
  627. X   int code;
  628. X#endif
  629. X   {
  630. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  631. X   char *name;
  632. X   struct bwb_variable *v;
  633. X   struct fslte *f, *n;
  634. X   int p;
  635. X
  636. X   /* get the element for name */
  637. X
  638. X   if ( code == EXEC_LABEL )
  639. X      {
  640. X      p = 0;
  641. X      scan_element( line->buffer, &p, tbuf );
  642. X      if ( isdigit( tbuf[ 0 ] ))
  643. X         {
  644. X     scan_element( line->buffer, &p, tbuf );
  645. X         }
  646. X      tbuf[ strlen( tbuf ) - 1 ] = '\0';
  647. X      }
  648. X   else
  649. X      {
  650. X      adv_ws( line->buffer, position );
  651. X      exp_getvfname( &( line->buffer[ *position ] ), tbuf );
  652. X      *position += strlen( tbuf );
  653. X      }
  654. X
  655. X#if INTENSIVE_DEBUG
  656. X   sprintf( bwb_ebuf, "in fslt_add(): adding SUB/FUNCTION/LABEL code <%d> name <%s>",
  657. X      code, tbuf );
  658. X   bwb_debug( bwb_ebuf );
  659. X#endif
  660. X
  661. X   /* get memory for name buffer */
  662. X
  663. X   if ( ( name = calloc( 1, strlen( tbuf ) + 1 ) ) == NULL )
  664. X      {
  665. X#if PROG_ERRORS
  666. X      bwb_error( "in fslt_add(): failed to get memory for name buffer" );
  667. X#else
  668. X      bwb_error( err_getmem );
  669. X#endif
  670. X      return FALSE;
  671. X      }
  672. X
  673. X   strcpy( name, tbuf );
  674. X
  675. X   /* get memory for fslt structure */
  676. X
  677. X   if ( ( f = calloc( 1, sizeof( struct fslte ) ) ) == NULL )
  678. X      {
  679. X#if PROG_ERRORS
  680. X      bwb_error( "in fslt_add(): failed to get memory for fslt structure" );
  681. X#else
  682. X      bwb_error( err_getmem );
  683. X#endif
  684. X      return FALSE;
  685. X      }
  686. X
  687. X   /* fill in structure */
  688. X
  689. X   f->line = line;
  690. X   f->name = name;
  691. X   f->code = code;
  692. X   f->local_variable = NULL;
  693. X
  694. X#if INTENSIVE_DEBUG
  695. X   sprintf( bwb_ebuf, "in fslt_add(): current buffer <%s>",
  696. X      &( line->buffer[ *position ] ) );
  697. X   bwb_debug( bwb_ebuf );
  698. X#endif
  699. X
  700. X   /* read arguments */
  701. X
  702. X   adv_ws( line->buffer, position );
  703. X   if ( line->buffer[ *position ] == '(' )
  704. X      {
  705. X      scan_readargs( f, line, position );
  706. X      }
  707. X
  708. X   /* if function, add one more local variable expressing the name
  709. X      of the function */
  710. X
  711. X   if ( code == EXEC_FUNCTION )
  712. X      {
  713. X
  714. X      v = var_new( tbuf );
  715. X      fslt_addlocalvar( f, v );
  716. X
  717. X#if INTENSIVE_DEBUG
  718. X      sprintf( bwb_ebuf, "in fslt_add(): added function-name variable <%s>",
  719. X         v->name );
  720. X      bwb_debug( bwb_ebuf );
  721. X      getchar();
  722. X#endif
  723. X
  724. X      }
  725. X
  726. X   /* establish linkages */
  727. X
  728. X   n = CURTASK fslt_start.next;
  729. X   CURTASK fslt_start.next = f;
  730. X   f->next = n;
  731. X
  732. X   return TRUE;
  733. X
  734. X   }
  735. X
  736. X/***************************************************************
  737. X
  738. X        FUNCTION:       scan_readargs()
  739. X
  740. X        DESCRIPTION:    This C function reads arguments (variable
  741. X                names for an entry added to the FUNCTION-
  742. X            SUB lookup table.
  743. X
  744. X***************************************************************/
  745. X
  746. X#if ANSI_C
  747. Xstatic int
  748. Xscan_readargs( struct fslte *f, struct bwb_line *line, int *position )
  749. X#else
  750. Xstatic int
  751. Xscan_readargs( f, line, position )
  752. X   struct fslte *f;
  753. X   struct bwb_line *line;
  754. X   int *position;
  755. X#endif
  756. X   {
  757. X   int control_loop;
  758. X   struct bwb_variable *v;
  759. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  760. X
  761. X#if INTENSIVE_DEBUG
  762. X   sprintf( bwb_ebuf, "in scan_readargs(): reading arguments, buffer <%s>",
  763. X      &( line->buffer[ *position ] ) );
  764. X   bwb_debug( bwb_ebuf );
  765. X#endif
  766. X
  767. X   /* if we are at begin paren, advance */
  768. X
  769. X   if ( line->buffer[ *position ] == '(' )
  770. X      {
  771. X      ++( *position );
  772. X      }
  773. X
  774. X   /* loop through looking for arguments */
  775. X
  776. X   control_loop = TRUE;
  777. X   adv_ws( line->buffer, position );
  778. X   while ( control_loop == TRUE )
  779. X      {
  780. X
  781. X      switch( line->buffer[ *position ] )
  782. X         {
  783. X         case '\n':        /* premature end of line */
  784. X         case '\r':
  785. X         case '\0':
  786. X            control_loop = FALSE;
  787. X            f->startpos = *position;
  788. X            bwb_error( err_syntax );
  789. X            return FALSE;
  790. X         case ')':        /* end of argument list */
  791. X            ++( *position );
  792. X            control_loop = FALSE;
  793. X            f->startpos = *position;
  794. X            return TRUE;
  795. X
  796. X         default:        /* presume beginning of argument == variable name */
  797. X
  798. X            exp_getvfname( &( line->buffer[ *position ] ), tbuf );
  799. X            *position += strlen( tbuf );
  800. X
  801. X#if INTENSIVE_DEBUG
  802. X            sprintf( bwb_ebuf, "in scan_readargs(): read argument <%s>",
  803. X               tbuf );
  804. X            bwb_debug( bwb_ebuf );
  805. X#endif
  806. X
  807. X            /* initialize the variable and add it to local chain */
  808. X
  809. X            v = var_new( tbuf );
  810. X            fslt_addlocalvar( f, v );
  811. X
  812. X            /* advance past the comma */
  813. X
  814. X            if ( line->buffer[ *position ] == ',' )
  815. X               {
  816. X               ++( *position );
  817. X               }
  818. X
  819. X            break;
  820. X         }
  821. X
  822. X      adv_ws( line->buffer, position );
  823. X      }
  824. X
  825. X   return TRUE;
  826. X
  827. X   }
  828. X
  829. X/***************************************************************
  830. X
  831. X        FUNCTION:       call_readargs()
  832. X
  833. X        DESCRIPTION:    This C function reads arguments (variable
  834. X                names for a subroutine CALL or function
  835. X            call.
  836. X
  837. X***************************************************************/
  838. X
  839. X#if ANSI_C
  840. Xstatic int
  841. Xcall_readargs( struct fslte *f, char *expression, int *position )
  842. X#else
  843. Xstatic int
  844. Xcall_readargs( f, expression, position )
  845. X   struct fslte *f;
  846. X   char *expression;
  847. X   int *position;
  848. X#endif
  849. X   {
  850. X   int control_loop;
  851. X   struct bwb_variable *v, *c;
  852. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  853. X   int argument_counter;
  854. X   int local_pos, single_var;
  855. X   struct exp_ese *e;
  856. X
  857. X#if INTENSIVE_DEBUG
  858. X   sprintf( bwb_ebuf, "in call_readargs(): reading arguments, buffer <%s>",
  859. X      &( expression[ *position ] ) );
  860. X   bwb_debug( bwb_ebuf );
  861. X#endif
  862. X
  863. X   /* if we are at begin paren, advance */
  864. X
  865. X   if ( expression[ *position ] == '(' )
  866. X      {
  867. X      ++( *position );
  868. X      }
  869. X
  870. X   /* loop through looking for arguments */
  871. X
  872. X   control_loop = TRUE;
  873. X   argument_counter = 0;
  874. X
  875. X   while ( control_loop == TRUE )
  876. X      {
  877. X
  878. X      adv_ws( expression, position );
  879. X
  880. X#if INTENSIVE_DEBUG
  881. X      sprintf( bwb_ebuf, "in call_readargs(): in loop, buffer <%s>",
  882. X         &( expression[ *position ] ) );
  883. X      bwb_debug( bwb_ebuf );
  884. X#endif
  885. X
  886. X      switch( expression[ *position ] )
  887. X         {
  888. X         case '\n':        /* end of line */
  889. X         case '\r':
  890. X     case '\0':
  891. X#if MULTISEG_LINES
  892. X     case ':':              /* end of segment */
  893. X#endif
  894. X            control_loop = FALSE;
  895. X            return FALSE;
  896. X
  897. X         case ')':        /* end of argument list */
  898. X            ++( *position );
  899. X            control_loop = FALSE;
  900. X            return TRUE;
  901. X
  902. X         default:        /* presume beginning of argument */
  903. X
  904. X            /* read the first word to see if it is a single variable name */
  905. X
  906. X            single_var = FALSE;
  907. X            exp_getvfname( &( expression[ *position ] ), tbuf );
  908. X            local_pos = *position + strlen( tbuf );
  909. X
  910. X            adv_ws( expression, &local_pos );
  911. X
  912. X#if INTENSIVE_DEBUG
  913. X            sprintf( bwb_ebuf, "in call_readargs(): in loop, tbuf <%s>",
  914. X               tbuf );
  915. X            bwb_debug( bwb_ebuf );
  916. X#endif
  917. X
  918. X            /* check now for the single variable name */
  919. X
  920. X            if ( strlen( tbuf ) == 0 )
  921. X               {
  922. X               single_var = FALSE;
  923. X               }
  924. X
  925. X            else
  926. X               {
  927. X               switch ( expression[ local_pos ] )
  928. X                  {
  929. X                  case ')':        /* end of argument list */
  930. X
  931. X#if INTENSIVE_DEBUG
  932. X             sprintf( bwb_ebuf, "in call_readargs(): detected end of argument list" );
  933. X             bwb_debug( bwb_ebuf );
  934. X#endif
  935. X
  936. X             ++local_pos;       /* and fall through */
  937. X                  case '\n':        /* end of line */
  938. X                  case '\r':
  939. X          case '\0':
  940. X#if MULTISEG_LINES
  941. X          case ':':             /* end of segment */
  942. X#endif
  943. X             control_loop = FALSE;      /* and fall through */
  944. X                        /* added 1993-06-16 */
  945. X          case ',':             /* end of argument */
  946. X
  947. X             single_var = TRUE;
  948. X
  949. X             /* look for variable from previous (calling) level */
  950. X
  951. X             -- CURTASK exsc;
  952. X             v = var_find( tbuf );      /* find variable there */
  953. X             ++ CURTASK exsc;
  954. X
  955. X             c = var_pos( CURTASK excs[ CURTASK exsc ].local_variable,
  956. X                        argument_counter );    /* find local equivalent */
  957. X                     bwb_vtov( c, v );        /* assign calling value to local variable */
  958. X
  959. X#if INTENSIVE_DEBUG
  960. X             sprintf( bwb_ebuf, "in call_readargs(): variable name is <%s>, local name <%s>",
  961. X            v->name, c->name );
  962. X             bwb_debug( bwb_ebuf );
  963. X#endif
  964. X
  965. X             *position = local_pos;
  966. X                     break;
  967. X                  default:
  968. X                     single_var = FALSE;
  969. X                     break;
  970. X                  }
  971. X               }
  972. X
  973. X            if ( single_var == FALSE )
  974. X               {
  975. X#if INTENSIVE_DEBUG
  976. X               sprintf( bwb_ebuf, "in call_readargs(): in loop, parse expression <%s>",
  977. X                  &( expression[ *position ] ) );
  978. X               bwb_debug( bwb_ebuf );
  979. X#endif
  980. X
  981. X               e = bwb_exp( expression, FALSE, position );    /* parse */
  982. X
  983. X#if INTENSIVE_DEBUG
  984. X           sprintf( bwb_ebuf, "in call_readargs(): in loop, parsed expression, buffer <%s>",
  985. X          &( expression[ *position ] ) );
  986. X               bwb_debug( bwb_ebuf );
  987. X#endif
  988. X
  989. X               v = var_pos( CURTASK excs[ CURTASK exsc ].local_variable,
  990. X                  argument_counter );        /* assign to variable */
  991. X               bwb_etov( v, e );        /* assign value */
  992. X               }
  993. X
  994. X            /* add the variable to the calling variable chain */
  995. X
  996. X            fslt_addcallvar( v );
  997. X
  998. X#if INTENSIVE_DEBUG
  999. X            str_btoc( tbuf, var_getsval( v ));
  1000. X            if ( single_var == TRUE )
  1001. X               {
  1002. X               sprintf( bwb_ebuf, "in call_readargs(): added arg <%d> (single) name <%s> value <%s>",
  1003. X                  argument_counter, v->name, tbuf );
  1004. X               }
  1005. X            else
  1006. X               {
  1007. X               sprintf( bwb_ebuf, "in call_readargs(): added arg <%d> (expression) name <%s> value <%s>",
  1008. X                  argument_counter, v->name, tbuf );
  1009. X               }
  1010. X            bwb_debug( bwb_ebuf );
  1011. X            getchar();
  1012. X#endif
  1013. X
  1014. X            /* advance past comma if present */
  1015. X
  1016. X            adv_ws( expression, position );
  1017. X            if ( expression[ *position ] == ',' )
  1018. X               {
  1019. X               ++( *position );
  1020. X               }
  1021. X
  1022. X            break;
  1023. X         }
  1024. X
  1025. X      ++argument_counter;
  1026. X
  1027. X      }
  1028. X
  1029. X#if INTENSIVE_DEBUG
  1030. X   sprintf( bwb_ebuf, "in call_readargs(): exiting function" );
  1031. X   bwb_debug( bwb_ebuf );
  1032. X#endif
  1033. X
  1034. X   return TRUE;
  1035. X
  1036. X   }
  1037. X
  1038. X/***************************************************************
  1039. X
  1040. X        FUNCTION:       fslt_findl()
  1041. X
  1042. X        DESCRIPTION:    This C function finds a line corresponding
  1043. X                to a name in the FUNCTION-SUB lookup
  1044. X            table.
  1045. X
  1046. X***************************************************************/
  1047. X
  1048. X#if ANSI_C
  1049. Xstatic struct bwb_line *
  1050. Xfslt_findl( char *buffer )
  1051. X#else
  1052. Xstatic struct bwb_line *
  1053. Xfslt_findl( buffer )
  1054. X   char *buffer;
  1055. X#endif
  1056. X   {
  1057. X   struct fslte *r;
  1058. X
  1059. X   r = fslt_findf( buffer );
  1060. X
  1061. X   return r->line;
  1062. X
  1063. X   }
  1064. X
  1065. X/***************************************************************
  1066. X
  1067. X        FUNCTION:       fslt_findf()
  1068. X
  1069. X        DESCRIPTION:    This C function finds an fslte structure
  1070. X            corresponding to a name in the FUNCTION-
  1071. X            SUB lookup table.
  1072. X
  1073. X***************************************************************/
  1074. X
  1075. X#if ANSI_C
  1076. Xstatic struct fslte *
  1077. Xfslt_findf( char *buffer )
  1078. X#else
  1079. Xstatic struct fslte *
  1080. Xfslt_findf( buffer )
  1081. X   char *buffer;
  1082. X#endif
  1083. X   {
  1084. X   struct fslte *f;
  1085. X   register int c;
  1086. X
  1087. X   /* remove open-paren from string */
  1088. X
  1089. X   for ( c = 0; buffer[ c ] != '\0'; ++c )
  1090. X      {
  1091. X      if ( buffer[ c ] == '(' )
  1092. X         {
  1093. X         buffer[ c ] = '\0';
  1094. X         }
  1095. X      }
  1096. X
  1097. X#if INTENSIVE_DEBUG
  1098. X   sprintf( bwb_ebuf, "in fslt_findf(): search for name <%s>", buffer );
  1099. X   bwb_debug( bwb_ebuf );
  1100. X#endif
  1101. X
  1102. X   /* run through the table */
  1103. X
  1104. X   for ( f = CURTASK fslt_start.next; f != &CURTASK fslt_end; f = f->next )
  1105. X      {
  1106. X      if ( strcmp( f->name, buffer ) == 0 )
  1107. X         {
  1108. X         return f;
  1109. X         }
  1110. X      }
  1111. X
  1112. X   /* search has failed */
  1113. X
  1114. X#if PROG_ERRORS
  1115. X   sprintf( bwb_ebuf, "in fslt_findf(): failed to find Function/Subroutine <%s>",
  1116. X      buffer );
  1117. X   bwb_error( bwb_ebuf );
  1118. X#else
  1119. X   bwb_error( err_lnnotfound );
  1120. X#endif
  1121. X
  1122. X   return NULL;
  1123. X
  1124. X   }
  1125. X
  1126. X/***************************************************************
  1127. X
  1128. X        FUNCTION:       bwb_def()
  1129. X
  1130. X        DESCRIPTION:    This C function implements the BASIC
  1131. X                        DEF statement. Since DEF and FUNCTION
  1132. X            are equivalent, it simply passes execution
  1133. X            to bwb_function().
  1134. X
  1135. X    SYNTAX:        DEF FNname(arg...)] = expression
  1136. X
  1137. X    NOTE:        It is not a strict requirement that the
  1138. X            function name should begin with "FN".
  1139. X
  1140. X***************************************************************/
  1141. X
  1142. X#if ANSI_C
  1143. Xstruct bwb_line *
  1144. Xbwb_def( struct bwb_line *l )
  1145. X#else
  1146. Xstruct bwb_line *
  1147. Xbwb_def( l )
  1148. X   struct bwb_line *l;
  1149. X#endif
  1150. X   {
  1151. X
  1152. X#if MULTISEG_LINES
  1153. X   adv_eos( l->buffer, &( l->position ));
  1154. X#endif
  1155. X
  1156. X   return bwb_zline( l );
  1157. X   }
  1158. X
  1159. X#if STRUCT_CMDS
  1160. X
  1161. X/***************************************************************
  1162. X
  1163. X        FUNCTION:       bwb_function()
  1164. X
  1165. X        DESCRIPTION:    This C function implements the BASIC
  1166. X            FUNCTION and DEF commands.
  1167. X
  1168. X    SYNTAX:        FUNCTION function-definition
  1169. X
  1170. X***************************************************************/
  1171. X
  1172. X#if ANSI_C
  1173. Xstruct bwb_line *
  1174. Xbwb_function( struct bwb_line *l )
  1175. X#else
  1176. Xstruct bwb_line *
  1177. Xbwb_function( l )
  1178. X   struct bwb_line *l;
  1179. X#endif
  1180. X   {
  1181. X
  1182. X   return bwb_def( l );
  1183. X
  1184. X   }
  1185. X
  1186. X/***************************************************************
  1187. X
  1188. X        FUNCTION:       bwb_endfnc()
  1189. X
  1190. X        DESCRIPTION:    This C function implements the BASIC
  1191. X            END FUNCTION command, ending a subroutine
  1192. X            definition.  Because the command END
  1193. X            can have multiple meanings, this function
  1194. X            should be called from the bwb_xend()
  1195. X            function, which should be able to identify
  1196. X            an END FUNCTION command.
  1197. X
  1198. X    SYNTAX:        END FUNCTION
  1199. X
  1200. X***************************************************************/
  1201. X
  1202. X#if ANSI_C
  1203. Xstruct bwb_line *
  1204. Xbwb_endfnc( struct bwb_line *l )
  1205. X#else
  1206. Xstruct bwb_line *
  1207. Xbwb_endfnc( l )
  1208. X   struct bwb_line *l;
  1209. X#endif
  1210. X   {
  1211. X   struct bwb_variable *local;
  1212. X   register int c;
  1213. X
  1214. X   /* assign local variable values to calling variables */
  1215. X
  1216. X   local = CURTASK excs[ CURTASK exsc ].local_variable;
  1217. X   for ( c = 0; c < CURTASK excs[ CURTASK exsc ].n_cvs; ++c )
  1218. X      {
  1219. X      bwb_vtov( CURTASK excs[ CURTASK exsc ].calling_variable[ c ], local );
  1220. X      local = local->next;
  1221. X      }
  1222. X
  1223. X   /* decrement the EXEC stack counter */
  1224. X
  1225. X   bwb_decexec();
  1226. X
  1227. X   /* and return next from old line */
  1228. X
  1229. X   CURTASK excs[ CURTASK exsc ].line->next->position = 0;
  1230. X   return CURTASK excs[ CURTASK exsc ].line->next;
  1231. X
  1232. X   }
  1233. X
  1234. X/***************************************************************
  1235. X
  1236. X        FUNCTION:       bwb_call()
  1237. X
  1238. X        DESCRIPTION:    This C function implements the BASIC
  1239. X                CALL subroutine command.
  1240. X
  1241. X    SYNTAX:        CALL subroutine-name
  1242. X
  1243. X***************************************************************/
  1244. X
  1245. X#if ANSI_C
  1246. Xstruct bwb_line *
  1247. Xbwb_call( struct bwb_line *l )
  1248. X#else
  1249. Xstruct bwb_line *
  1250. Xbwb_call( l )
  1251. X   struct bwb_line *l;
  1252. X#endif
  1253. X   {
  1254. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1255. X   struct bwb_line *call_line;
  1256. X   struct fslte *f;
  1257. X
  1258. X   adv_element( l->buffer, &( l->position ), tbuf );
  1259. X
  1260. X#if INTENSIVE_DEBUG
  1261. X   sprintf( bwb_ebuf, "in bwb_call(): call to subroutine <%s>", tbuf );
  1262. X   bwb_debug( bwb_ebuf );
  1263. X#endif
  1264. X
  1265. X   /* find the line to call */
  1266. X
  1267. X   call_line = fslt_findl( tbuf );
  1268. X   f = fslt_findf( tbuf );
  1269. X
  1270. X   if ( call_line == NULL )
  1271. X      {
  1272. X      return bwb_zline( l );
  1273. X      }
  1274. X
  1275. X#if INTENSIVE_DEBUG
  1276. X   sprintf( bwb_ebuf, "in bwb_call(): found line <%s>",
  1277. X      call_line->buffer );
  1278. X   bwb_debug( bwb_ebuf );
  1279. X#endif
  1280. X
  1281. X   /* save the old position on the EXEC stack */
  1282. X
  1283. X   bwb_setexec( l, l->position, CURTASK excs[ CURTASK exsc ].code );
  1284. X
  1285. X   /* increment and set new EXEC stack */
  1286. X
  1287. X   bwb_incexec();
  1288. X   call_line->position = 0;
  1289. X   bwb_setexec( call_line, 0, EXEC_CALLSUB );
  1290. X
  1291. X   /* attach local variables */
  1292. X
  1293. X   CURTASK excs[ CURTASK exsc ].local_variable = f->local_variable;
  1294. X
  1295. X   /* read calling variables for this call */
  1296. X
  1297. X   call_readargs( f, l->buffer, &( l->position ) );
  1298. X
  1299. X   return call_line;
  1300. X
  1301. X   }
  1302. X
  1303. X/***************************************************************
  1304. X
  1305. X        FUNCTION:       bwb_sub()
  1306. X
  1307. X    DESCRIPTION:    This function implements the BASIC
  1308. X            SUB command, introducing a named
  1309. X            subroutine.
  1310. X
  1311. X    SYNTAX:        SUB subroutine-name
  1312. X            (followed by subroutine definition ending
  1313. X            with END SUB).
  1314. X
  1315. X***************************************************************/
  1316. X
  1317. X#if ANSI_C
  1318. Xstruct bwb_line *
  1319. Xbwb_sub( struct bwb_line *l )
  1320. X#else
  1321. Xstruct bwb_line *
  1322. Xbwb_sub( l )
  1323. X   struct bwb_line *l;
  1324. X#endif
  1325. X   {
  1326. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1327. X   struct bwb_line *rline;
  1328. X#if MULTISEG_LINES
  1329. X   struct fslte *f;
  1330. X#endif
  1331. X
  1332. X#if INTENSIVE_DEBUG
  1333. X   sprintf( bwb_ebuf, "in bwb_sub(): entered function at exec level <%d>",
  1334. X      CURTASK exsc );
  1335. X   bwb_debug( bwb_ebuf );
  1336. X#endif
  1337. X
  1338. X   /* check current exec level: if 1 then only MAIN should be executed */
  1339. X
  1340. X   if ( CURTASK exsc == 0 )
  1341. X      {
  1342. X      adv_element( l->buffer, &( l->position ), tbuf );
  1343. X      bwb_strtoupper( tbuf );
  1344. X      if ( strcmp( tbuf, "MAIN" ) == 0 )
  1345. X         {
  1346. X#if INTENSIVE_DEBUG
  1347. X         sprintf( bwb_ebuf, "in bwb_sub(): found MAIN function at level 0" );
  1348. X         bwb_debug( bwb_ebuf );
  1349. X#endif
  1350. X
  1351. X         bwb_incexec();
  1352. X
  1353. X         bwb_setexec( l->next, 0, EXEC_MAIN );
  1354. X
  1355. X         return bwb_zline( l );
  1356. X
  1357. X         }
  1358. X
  1359. X      /* if a MAIN function was not found at level 0, then skip the subroutine */
  1360. X
  1361. X      else
  1362. X         {
  1363. X
  1364. X#if INTENSIVE_DEBUG
  1365. X         sprintf( bwb_ebuf, "in bwb_sub(): found non-MAIN function at level 0" );
  1366. X         bwb_debug( bwb_ebuf );
  1367. X#endif
  1368. X
  1369. X         rline = find_endsub( l );
  1370. X         bwb_setexec( rline->next, 0, EXEC_CALLSUB );
  1371. X         rline->next->position = 0;
  1372. X         return rline->next;
  1373. X         }
  1374. X      }
  1375. X
  1376. X   /* check for integrity of CALL-SUB sequence if above level 0 */
  1377. X
  1378. X   else if ( CURTASK excs[ CURTASK exsc ].code != EXEC_CALLSUB )
  1379. X      {
  1380. X#if PROG_ERRORS
  1381. X      sprintf( bwb_ebuf, "in bwb_sub(): SUB without CALL" );
  1382. X      bwb_error( bwb_ebuf );
  1383. X#else
  1384. X      bwb_error( err_retnogosub );
  1385. X#endif
  1386. X      }
  1387. X
  1388. X   /* advance position */
  1389. X
  1390. X#if MULTISEG_LINES
  1391. X   adv_ws( l->buffer, &( l->position ));
  1392. X   adv_element( l->buffer, &( l->position ), tbuf );
  1393. X   f = fslt_findf( tbuf );
  1394. X
  1395. X   l->position = f->startpos;
  1396. X
  1397. X   return bwb_zline( l );
  1398. X#else
  1399. X   return bwb_zline( l );
  1400. X#endif
  1401. X   }
  1402. X
  1403. X/***************************************************************
  1404. X
  1405. X        FUNCTION:       find_endsub()
  1406. X
  1407. X        DESCRIPTION:    This function searches for a line containing
  1408. X                        an END SUB statement corresponding to a previous
  1409. X                        SUB statement.
  1410. X
  1411. X***************************************************************/
  1412. X
  1413. X#if ANSI_C
  1414. Xstatic struct bwb_line *
  1415. Xfind_endsub( struct bwb_line *l )
  1416. X#else
  1417. Xstatic struct bwb_line *
  1418. Xfind_endsub( l )
  1419. X   struct bwb_line *l;
  1420. X#endif
  1421. X   {
  1422. X   struct bwb_line *current;
  1423. X   register int s_level;
  1424. X   int position;
  1425. X
  1426. X   s_level = 1;
  1427. X   for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  1428. X      {
  1429. X      position = 0;
  1430. X      if ( current->marked != TRUE )
  1431. X         {
  1432. X         line_start( current->buffer, &position, &( current->lnpos ),
  1433. X            &( current->lnum ),
  1434. X            &( current->cmdpos ),
  1435. X            &( current->cmdnum ),
  1436. X            &( current->startpos ) );
  1437. X         }
  1438. X      current->position = current->startpos;
  1439. X
  1440. X      if ( current->cmdnum > -1 )
  1441. X         {
  1442. X
  1443. X         if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_sub )
  1444. X            {
  1445. X            ++s_level;
  1446. X
  1447. X#if INTENSIVE_DEBUG
  1448. X            sprintf( bwb_ebuf, "in find_endsub(): found SUB at line %d, level %d",
  1449. X               current->number, s_level );
  1450. X            bwb_debug( bwb_ebuf );
  1451. X#endif
  1452. X
  1453. X            }
  1454. X         else if ( is_endsub( current ) == TRUE )
  1455. X            {
  1456. X            --s_level;
  1457. X
  1458. X#if INTENSIVE_DEBUG
  1459. X            sprintf( bwb_ebuf, "in find_endsub(): found END SUB at line %d, level %d",
  1460. X               current->number, s_level );
  1461. X            bwb_debug( bwb_ebuf );
  1462. X#endif
  1463. X
  1464. X            if ( s_level == 0 )
  1465. X               {
  1466. X               return current;
  1467. X               }
  1468. X            }
  1469. X
  1470. X         }
  1471. X      }
  1472. X
  1473. X#if PROG_ERRORS
  1474. X   sprintf( bwb_ebuf, "SUB without END SUB" );
  1475. X   bwb_error( bwb_ebuf );
  1476. X#else
  1477. X   bwb_error( err_syntax  );
  1478. X#endif
  1479. X
  1480. X   return NULL;
  1481. X
  1482. X   }
  1483. X
  1484. X/***************************************************************
  1485. X
  1486. X    FUNCTION:       is_endsub()
  1487. X
  1488. X    DESCRIPTION:    This function determines whether the
  1489. X            line buffer for line 'l' is positioned
  1490. X            at an END SUB statement.
  1491. X
  1492. X***************************************************************/
  1493. X
  1494. X#if ANSI_C
  1495. Xstatic int
  1496. Xis_endsub( struct bwb_line *l )
  1497. X#else
  1498. Xstatic int
  1499. Xis_endsub( l )
  1500. X   struct bwb_line *l;
  1501. X#endif
  1502. X   {
  1503. X   int position;
  1504. X   char tbuf[ MAXVARNAMESIZE + 1];
  1505. X
  1506. X   if ( bwb_cmdtable[ l->cmdnum ].vector != bwb_xend )
  1507. X      {
  1508. X      return FALSE;
  1509. X      }
  1510. X
  1511. X   position = l->startpos;
  1512. X   adv_ws( l->buffer, &position );
  1513. X   adv_element( l->buffer, &position, tbuf );
  1514. X   bwb_strtoupper( tbuf );
  1515. X
  1516. X   if ( strcmp( tbuf, "SUB" ) == 0 )
  1517. X      {
  1518. X      return TRUE;
  1519. X      }
  1520. X
  1521. X   return FALSE;
  1522. X
  1523. X   }
  1524. X
  1525. X/***************************************************************
  1526. X
  1527. X        FUNCTION:       bwb_endsub()
  1528. X
  1529. X        DESCRIPTION:    This C function implements the BASIC
  1530. X            END SUB command, ending a subroutine
  1531. X            definition.  Because the command END
  1532. X            can have multiple meanings, this function
  1533. X            should be called from the bwb_xend()
  1534. X            function, which should be able to identify
  1535. X            an END SUB command.
  1536. X
  1537. X    SYNTAX:        END SUB
  1538. X
  1539. X***************************************************************/
  1540. X
  1541. X#if ANSI_C
  1542. Xstruct bwb_line *
  1543. Xbwb_endsub( struct bwb_line *line )
  1544. X#else
  1545. Xstruct bwb_line *
  1546. Xbwb_endsub( line )
  1547. X   struct bwb_line *line;
  1548. X#endif
  1549. X   {
  1550. X   struct bwb_variable *l;
  1551. X   register int c;
  1552. X
  1553. X   /* assign local variable values to calling variables */
  1554. X
  1555. X   l = CURTASK excs[ CURTASK exsc ].local_variable;
  1556. X   for ( c = 0; c < CURTASK excs[ CURTASK exsc ].n_cvs; ++c )
  1557. X      {
  1558. X      bwb_vtov( CURTASK excs[ CURTASK exsc ].calling_variable[ c ], l );
  1559. X      l = l->next;
  1560. X      }
  1561. X
  1562. X   /* decrement the EXEC stack counter */
  1563. X
  1564. X   bwb_decexec();
  1565. X
  1566. X   /* if the previous level was EXEC_MAIN,
  1567. X      then execution continues from this point */
  1568. X
  1569. X   if ( CURTASK excs[ CURTASK exsc + 1 ].code == EXEC_MAIN )
  1570. X      {
  1571. X      return bwb_zline( line );
  1572. X      }
  1573. X
  1574. X   /* else return next from old line */
  1575. X
  1576. X   CURTASK excs[ CURTASK exsc ].line->next->position = 0;
  1577. X   return CURTASK excs[ CURTASK exsc ].line->next;
  1578. X
  1579. X   }
  1580. X
  1581. X/***************************************************************
  1582. X
  1583. X    FUNCTION:    find_label()
  1584. X
  1585. X    DESCRIPTION:    This C function finds a program line that
  1586. X            begins with the label included in <buffer>.
  1587. X
  1588. X***************************************************************/
  1589. X
  1590. X#if ANSI_C
  1591. Xextern struct bwb_line *
  1592. Xfind_label( char *buffer )
  1593. X#else
  1594. Xextern struct bwb_line *
  1595. Xfind_label( buffer )
  1596. X   char *buffer;
  1597. X#endif
  1598. X   {
  1599. X   struct fslte *f;
  1600. X
  1601. X   for ( f = CURTASK fslt_start.next; f != & ( CURTASK fslt_end ); f = f->next )
  1602. X      {
  1603. X      if ( strcmp( buffer, f->name ) == 0 )
  1604. X         {
  1605. X#if INTENSIVE_DEBUG
  1606. X         sprintf( bwb_ebuf, "in find_label(): found label <%s>", buffer );
  1607. X         bwb_debug( bwb_ebuf );
  1608. X#endif
  1609. X         return f->line;
  1610. X         }
  1611. X      }
  1612. X
  1613. X#if PROG_ERRORS
  1614. X   sprintf( bwb_ebuf, "in find_label(): failed to find label <%s>", buffer );
  1615. X   bwb_error( bwb_ebuf );
  1616. X#else
  1617. X   bwb_error( err_lnnotfound );
  1618. X#endif
  1619. X
  1620. X   return NULL;
  1621. X
  1622. X   }
  1623. X
  1624. X/***************************************************************
  1625. X
  1626. X    FUNCTION:       bwb_doloop()
  1627. X
  1628. X    DESCRIPTION:    This C function implements the ANSI BASIC
  1629. X            DO statement, when DO is not followed by
  1630. X            an argument.  It is called by bwb_do() in
  1631. X            bwb_cmd.c.
  1632. X
  1633. X    SYNTAX:        DO
  1634. X
  1635. X***************************************************************/
  1636. X
  1637. X#if ANSI_C
  1638. Xstruct bwb_line *
  1639. Xbwb_doloop( struct bwb_line *l )
  1640. X#else
  1641. Xstruct bwb_line *
  1642. Xbwb_doloop( l )
  1643. X   struct bwb_line *l;
  1644. X#endif
  1645. X   {
  1646. X
  1647. X   /* if this is the first time at this DO statement, note it */
  1648. X
  1649. X   if ( CURTASK excs[ CURTASK exsc ].while_line != l )
  1650. X      {
  1651. X
  1652. X      bwb_incexec();
  1653. X      CURTASK excs[ CURTASK exsc ].while_line = l;
  1654. X
  1655. X      /* find the LOOP statement */
  1656. X
  1657. X      CURTASK excs[ CURTASK exsc ].wend_line = find_loop( l );
  1658. X
  1659. X      if ( CURTASK excs[ CURTASK exsc ].wend_line == NULL )
  1660. X     {
  1661. X     return bwb_zline( l );
  1662. X     }
  1663. X
  1664. X#if INTENSIVE_DEBUG
  1665. X      sprintf( bwb_ebuf, "in bwb_doloop(): initialize DO loop, line <%d>",
  1666. X     l->number );
  1667. X      bwb_debug( bwb_ebuf );
  1668. X#endif
  1669. X
  1670. X      }
  1671. X#if INTENSIVE_DEBUG
  1672. X   else
  1673. X      {
  1674. X      sprintf( bwb_ebuf, "in bwb_doloop(): return to DO loop, line <%d>",
  1675. X     l->number );
  1676. X      bwb_debug( bwb_ebuf );
  1677. X      }
  1678. X#endif
  1679. X
  1680. X   bwb_setexec( l, l->position, EXEC_DO );
  1681. X   return bwb_zline( l );
  1682. X   }
  1683. X
  1684. X/***************************************************************
  1685. X
  1686. X        FUNCTION:       bwb_loop()
  1687. X
  1688. X    DESCRIPTION:    This C function implements the ANSI BASIC
  1689. X            LOOP statement.
  1690. X
  1691. X    SYNTAX:        LOOP [UNTIL expression]
  1692. X            
  1693. X***************************************************************/
  1694. X
  1695. X#if ANSI_C
  1696. Xstruct bwb_line *
  1697. Xbwb_loop( struct bwb_line *l )
  1698. X#else
  1699. Xstruct bwb_line *
  1700. Xbwb_loop( l )
  1701. X   struct bwb_line *l;
  1702. X#endif
  1703. X   {
  1704. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1705. X
  1706. X#if INTENSIVE_DEBUG
  1707. X   sprintf( bwb_ebuf, "in bwb_loop(): entered subroutine" );
  1708. X   bwb_debug( bwb_ebuf );
  1709. X#endif
  1710. X
  1711. X   /* If the current exec stack is set for EXEC_WHILE, then we
  1712. X      presume that this is a LOOP statement ending a DO WHILE
  1713. X      loop */
  1714. X
  1715. X   if ( CURTASK excs[ CURTASK exsc ].code == EXEC_WHILE )
  1716. X      {
  1717. X      return bwb_wend( l );
  1718. X      }
  1719. X
  1720. X   /* check integrity of DO loop */
  1721. X
  1722. X   if ( CURTASK excs[ CURTASK exsc ].code != EXEC_DO )
  1723. X      {
  1724. X#if PROG_ERRORS
  1725. X      sprintf( bwb_ebuf, "in bwb_loop(): exec stack code != EXEC_DO" );
  1726. X      bwb_error( bwb_ebuf );
  1727. X#else
  1728. X      bwb_error( err_syntax );
  1729. X#endif
  1730. X      }
  1731. X
  1732. X   if ( CURTASK excs[ CURTASK exsc ].while_line == NULL )
  1733. X      {
  1734. X#if PROG_ERRORS
  1735. X      sprintf( bwb_ebuf, "in bwb_loop(): exec stack while_line == NULL" );
  1736. X      bwb_error( bwb_ebuf );
  1737. X#else
  1738. X      bwb_error( err_syntax );
  1739. X#endif
  1740. X      }
  1741. X
  1742. X   /* advance to find the first argument */
  1743. X
  1744. X   adv_element( l->buffer, &( l->position ), tbuf );
  1745. X   bwb_strtoupper( tbuf );
  1746. X
  1747. X   /* detect a LOOP UNTIL structure */
  1748. X
  1749. X   if ( strcmp( tbuf, CMD_XUNTIL ) == 0 )
  1750. X      {
  1751. X
  1752. X#if INTENSIVE_DEBUG
  1753. X      sprintf( bwb_ebuf, "in bwb_loop(): detected LOOP UNTIL" );
  1754. X      bwb_debug( bwb_ebuf );
  1755. X#endif
  1756. X
  1757. X      return bwb_loopuntil( l );
  1758. X
  1759. X      }
  1760. X
  1761. X   /* LOOP does not have UNTIL */
  1762. X
  1763. X   else
  1764. X      {
  1765. X
  1766. X      /* reset to the top of the current DO loop */
  1767. X
  1768. X#if INTENSIVE_DEBUG
  1769. X      sprintf( bwb_ebuf, "in bwb_loop() return to line <%d>",
  1770. X     CURTASK excs[ CURTASK exsc ].while_line->number );
  1771. X      bwb_debug( bwb_ebuf );
  1772. X#endif
  1773. X
  1774. X      CURTASK excs[ CURTASK exsc ].while_line->position = 0;
  1775. X      bwb_setexec( CURTASK excs[ CURTASK exsc ].while_line, 0, EXEC_DO );
  1776. X
  1777. X      return CURTASK excs[ CURTASK exsc ].while_line;
  1778. X
  1779. X      }
  1780. X
  1781. X   }
  1782. X
  1783. X/***************************************************************
  1784. X
  1785. X    FUNCTION:       bwb_loopuntil()
  1786. X
  1787. X    DESCRIPTION:    This C function implements the ANSI BASIC
  1788. X            LOOP UNTIL statement and is called by
  1789. X            bwb_loop().
  1790. X
  1791. X***************************************************************/
  1792. X
  1793. X#if ANSI_C
  1794. Xstatic struct bwb_line *
  1795. Xbwb_loopuntil( struct bwb_line *l )
  1796. X#else
  1797. Xstatic struct bwb_line *
  1798. Xbwb_loopuntil( l )
  1799. X   struct bwb_line *l;
  1800. X#endif
  1801. X   {
  1802. X   struct exp_ese *e;
  1803. X   struct bwb_line *r;
  1804. X
  1805. X#if INTENSIVE_DEBUG
  1806. X   sprintf( bwb_ebuf, "in bwb_loopuntil(): entered subroutine" );
  1807. X   bwb_debug( bwb_ebuf );
  1808. X#endif
  1809. X
  1810. X   /* call bwb_exp() to interpret the expression */
  1811. X
  1812. X   e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  1813. X
  1814. X   if ( (int) exp_getnval( e ) == TRUE )
  1815. X      {
  1816. X      CURTASK excs[ CURTASK exsc ].while_line = NULL;
  1817. X      r = CURTASK excs[ CURTASK exsc ].wend_line;
  1818. X      bwb_setexec( r, 0, CURTASK excs[ CURTASK exsc - 1 ].code );
  1819. X      r->position = 0;
  1820. X      bwb_decexec();
  1821. X      return r;
  1822. X      }
  1823. X
  1824. X   /* condition is false: loop around to DO again */
  1825. X
  1826. X   else
  1827. X      {
  1828. X
  1829. X#if INTENSIVE_DEBUG
  1830. X      sprintf( bwb_ebuf, "in bwb_loopuntil() return to line <%d>",
  1831. X     CURTASK excs[ CURTASK exsc ].while_line->number );
  1832. X      bwb_debug( bwb_ebuf );
  1833. X#endif
  1834. X
  1835. X      CURTASK excs[ CURTASK exsc ].while_line->position = 0;
  1836. X      bwb_setexec( CURTASK excs[ CURTASK exsc ].while_line, 0, EXEC_DO );
  1837. X
  1838. X      return CURTASK excs[ CURTASK exsc ].while_line;
  1839. X
  1840. X      }
  1841. X
  1842. X   }
  1843. X
  1844. X/***************************************************************
  1845. X
  1846. X        FUNCTION:       bwb_exit()
  1847. X
  1848. X    DESCRIPTION:    This C function implements the BASIC EXIT
  1849. X            statement, calling subroutines for either
  1850. X            EXIT FOR or EXIT DO.
  1851. X
  1852. X    SYNTAX:        EXIT FOR|DO
  1853. X
  1854. X***************************************************************/
  1855. X
  1856. X#if ANSI_C
  1857. Xstruct bwb_line *
  1858. Xbwb_exit( struct bwb_line *l )
  1859. X#else
  1860. Xstruct bwb_line *
  1861. Xbwb_exit( l )
  1862. X   struct bwb_line *l;
  1863. X#endif
  1864. X   {
  1865. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  1866. X
  1867. X#if INTENSIVE_DEBUG
  1868. X   sprintf( bwb_ebuf, "in bwb_exit(): entered subroutine" );
  1869. X   bwb_debug( bwb_ebuf );
  1870. X#endif
  1871. X
  1872. X   adv_element( l->buffer, &( l->position ), tbuf );
  1873. X   bwb_strtoupper( tbuf );
  1874. X
  1875. X   if ( strcmp( tbuf, CMD_XFOR ) == 0 )
  1876. X      {
  1877. X
  1878. X#if INTENSIVE_DEBUG
  1879. X      sprintf( bwb_ebuf, "in bwb_exit(): detected EXIT FOR" );
  1880. X      bwb_debug( bwb_ebuf );
  1881. X#endif
  1882. X
  1883. X      return bwb_exitfor( l );
  1884. X      }
  1885. X
  1886. X   if ( strcmp( tbuf, CMD_XDO ) == 0 )
  1887. X      {
  1888. X      return bwb_exitdo( l );
  1889. X      }
  1890. X
  1891. X#if PROG_ERRORS
  1892. X   sprintf( bwb_ebuf, "in bwb_exit(): Nonsense or nothing following EXIT" );
  1893. X   bwb_error( bwb_ebuf );
  1894. X#else
  1895. X   bwb_error( err_syntax );
  1896. X#endif
  1897. X
  1898. X   return bwb_zline( l );
  1899. X   }
  1900. X
  1901. X/***************************************************************
  1902. X
  1903. X    FUNCTION:       bwb_exitdo()
  1904. X
  1905. X    DESCRIPTION:    This function handles the BASIC EXIT
  1906. X            DO statement.  This is a structured
  1907. X            programming command compatible with ANSI
  1908. X            BASIC. It is called from the bwb_exit()
  1909. X            subroutine.
  1910. X
  1911. X***************************************************************/
  1912. X
  1913. X#if ANSI_C
  1914. Xstruct bwb_line *
  1915. Xbwb_exitdo( struct bwb_line *l )
  1916. X#else
  1917. Xstruct bwb_line *
  1918. Xbwb_exitdo( l )
  1919. X   struct bwb_line *l;
  1920. X#endif
  1921. X   {
  1922. X   struct bwb_line *next_line;
  1923. X   int found;
  1924. X   register int level;
  1925. X
  1926. X#if INTENSIVE_DEBUG
  1927. X   sprintf( bwb_ebuf, "in bwb_exitdo(): entered subroutine" );
  1928. X   bwb_debug( bwb_ebuf );
  1929. X#endif
  1930. X
  1931. X   /* Check the integrity of the DO statement */
  1932. X
  1933. X   found = FALSE;
  1934. X   level = CURTASK exsc;
  1935. X   do
  1936. X      {
  1937. X      if ( CURTASK excs[ level ].code == EXEC_DO )
  1938. X     {
  1939. X     next_line = CURTASK excs[ CURTASK level ].wend_line;
  1940. X     found = TRUE;
  1941. X     }
  1942. X      else
  1943. X     {
  1944. X     --level;
  1945. X     }
  1946. X      }
  1947. X   while ( ( level >= 0 ) && ( found == FALSE ) );
  1948. X
  1949. X   if ( found != TRUE )
  1950. X      {
  1951. X
  1952. X#if PROG_ERRORS
  1953. X      sprintf( bwb_ebuf, "in bwb_exitfor(): EXIT DO without DO" );
  1954. X      bwb_error( bwb_ebuf );
  1955. X#else
  1956. X      bwb_error( err_syntax );
  1957. X#endif
  1958. X
  1959. X      return bwb_zline( l );
  1960. X
  1961. X      }
  1962. X
  1963. X#if INTENSIVE_DEBUG
  1964. X   sprintf( bwb_ebuf, "in bwb_exitdo(): level found is <%d>, current <%d>",
  1965. X      level, CURTASK exsc );
  1966. X   bwb_debug( bwb_ebuf );
  1967. X#endif
  1968. X
  1969. X   /* decrement below the level of the NEXT statement */
  1970. X
  1971. X   while( CURTASK exsc >= level )
  1972. X      {
  1973. X      bwb_decexec();
  1974. X      }
  1975. X
  1976. X   /* set the next line in the exec stack */
  1977. X
  1978. X   next_line->position = 0;
  1979. X   bwb_setexec( next_line, 0, EXEC_NORM );
  1980. X
  1981. X   return next_line;
  1982. X
  1983. X   }
  1984. X
  1985. X#endif                    /* STRUCT_CMDS */
  1986. X
  1987. X/***************************************************************
  1988. X
  1989. X    FUNCTION:       bwb_vtov()
  1990. X
  1991. X    DESCRIPTION:    This function assigns the value of one
  1992. X            bwBASIC variable (src) to the value of another
  1993. X            bwBASIC variable (dst).
  1994. X
  1995. X***************************************************************/
  1996. X
  1997. X#if ANSI_C
  1998. Xstruct bwb_variable *
  1999. Xbwb_vtov( struct bwb_variable *dst,
  2000. X   struct bwb_variable *src )
  2001. X#else
  2002. Xstruct bwb_variable *
  2003. Xbwb_vtov( dst, src )
  2004. X   struct bwb_variable *dst;
  2005. X   struct bwb_variable *src;
  2006. X#endif
  2007. X   {
  2008. X
  2009. X   if ( dst == src )
  2010. X      {
  2011. X      return dst;
  2012. X      }
  2013. X
  2014. X   if ( src->type != dst->type )
  2015. X      {
  2016. X#if PROG_ERRORS
  2017. X      sprintf( bwb_ebuf, "in bwb_vtov(): mismatch src <%s> type <%d> dst <%s> type <%d>",
  2018. X     src->name, src->type, dst->name, dst->type );
  2019. X      bwb_error( bwb_ebuf );
  2020. X#else
  2021. X      bwb_error( err_mismatch );
  2022. X#endif
  2023. X      return NULL;
  2024. X      }
  2025. X
  2026. X   if ( dst->type == NUMBER )
  2027. X      {
  2028. X
  2029. X#if INTENSIVE_DEBUG
  2030. X      sprintf( bwb_ebuf, "in bwb_vtov(): assigning var <%s> val <%lf> to var <%s>",
  2031. X     src->name, var_getnval( src ), dst->name );
  2032. X      bwb_debug( bwb_ebuf );
  2033. X#endif
  2034. X
  2035. X      * var_findnval( dst, dst->array_pos ) = var_getnval( src );
  2036. X      }
  2037. X   else
  2038. X      {
  2039. X      str_btob( var_getsval( dst ), var_getsval( src ) );
  2040. X      }
  2041. X
  2042. X   return dst;
  2043. X   }
  2044. X
  2045. X/***************************************************************
  2046. X
  2047. X    FUNCTION:       bwb_etov()
  2048. X
  2049. X    DESCRIPTION:    This function assigns the value of a
  2050. X            bwBASIC expression stack element (src)
  2051. X            to the value of a bwBASIC variable (dst).
  2052. X
  2053. X***************************************************************/
  2054. X
  2055. X#if ANSI_C
  2056. Xstruct bwb_variable *
  2057. Xbwb_etov( struct bwb_variable *dst, struct exp_ese *src )
  2058. X#else
  2059. Xstruct bwb_variable *
  2060. Xbwb_etov( dst, src )
  2061. X   struct bwb_variable *dst;
  2062. X   struct exp_ese *src;
  2063. X#endif
  2064. X   {
  2065. X
  2066. X   if ( (int) src->type != dst->type )
  2067. X      {
  2068. X#if PROG_ERRORS
  2069. X      sprintf( bwb_ebuf, "in bwb_etov(): mismatch src <%d> dst <%d>",
  2070. X         src->type, dst->type );
  2071. X      bwb_error( bwb_ebuf );
  2072. X#else
  2073. X      bwb_error( err_mismatch );
  2074. X#endif
  2075. X      return NULL;
  2076. X      }
  2077. X
  2078. X   if ( dst->type == NUMBER )
  2079. X      {
  2080. X      * var_findnval( dst, dst->array_pos ) = exp_getnval( src );
  2081. X      }
  2082. X   else
  2083. X      {
  2084. X      str_btob( var_getsval( dst ), exp_getsval( src ) );
  2085. X      }
  2086. X
  2087. X   return dst;
  2088. X   }
  2089. X
  2090. X/***************************************************************
  2091. X
  2092. X    FUNCTION:       var_pos()
  2093. X
  2094. X    DESCRIPTION:    This function returns the name of a
  2095. X            local variable at a specified position
  2096. X            in the local variable list.
  2097. X
  2098. X***************************************************************/
  2099. X
  2100. X#if ANSI_C
  2101. Xstruct bwb_variable *
  2102. Xvar_pos( struct bwb_variable *firstvar, int p )
  2103. X#else
  2104. Xstruct bwb_variable *
  2105. Xvar_pos( firstvar, p )
  2106. X   struct bwb_variable *firstvar;
  2107. X   int p;
  2108. X#endif
  2109. X   {
  2110. X   register int c;
  2111. X   struct bwb_variable *v;
  2112. X
  2113. X   v = firstvar;
  2114. X   for ( c = 0; c != p; ++c )
  2115. X      {
  2116. X      v = v->next;
  2117. X      }
  2118. X
  2119. X#if INTENSIVE_DEBUG
  2120. X   sprintf( bwb_ebuf, "in var_pos(): returning pos <%d> variable <%s>",
  2121. X      p, v->name );
  2122. X   bwb_debug( bwb_ebuf );
  2123. X#endif
  2124. X
  2125. X   return v;
  2126. X   }
  2127. X
  2128. X/***************************************************************
  2129. X
  2130. X    FUNCTION:       fslt_addcallvar()
  2131. X
  2132. X    DESCRIPTION:    This function adds a calling variable
  2133. X            to the FUNCTION-SUB lookuop table at
  2134. X            a specific level.
  2135. X
  2136. X***************************************************************/
  2137. X
  2138. X#if ANSI_C
  2139. Xint
  2140. Xfslt_addcallvar( struct bwb_variable *v )
  2141. X#else
  2142. Xint
  2143. Xfslt_addcallvar( v )
  2144. X   struct bwb_variable *v;
  2145. X#endif
  2146. X   {
  2147. X
  2148. X   if ( CURTASK excs[ CURTASK exsc ].n_cvs >= MAX_FARGS )
  2149. X      {
  2150. X#if PROG_ERRORS
  2151. X      sprintf( bwb_ebuf, "in fslt_addcallvar(): Maximum number of Function Args Exceeded" );
  2152. X      bwb_error( bwb_ebuf );
  2153. X#else
  2154. X      bwb_error( err_overflow );
  2155. X#endif
  2156. X      }
  2157. X
  2158. X   CURTASK excs[ CURTASK exsc ].calling_variable[ CURTASK excs[ CURTASK exsc ].n_cvs ] = v;
  2159. X   ++CURTASK excs[ CURTASK exsc ].n_cvs;
  2160. X
  2161. X   return TRUE;
  2162. X
  2163. X   }
  2164. X
  2165. X/***************************************************************
  2166. X
  2167. X    FUNCTION:       expufnc()
  2168. X
  2169. X        DESCRIPTION:    This C function interprets a user-defined
  2170. X            function, returning its value at the current
  2171. X            level of the expression stack.
  2172. X
  2173. X***************************************************************/
  2174. X
  2175. X#if ANSI_C
  2176. Xint
  2177. Xexp_ufnc( char *expression )
  2178. X#else
  2179. Xint
  2180. Xexp_ufnc( expression )
  2181. X   char *expression;
  2182. X#endif
  2183. X   {
  2184. X   char tbuf[ MAXSTRINGSIZE + 1 ];
  2185. X   struct bwb_line *call_line;
  2186. X   struct fslte *f, *c;
  2187. X   struct bwb_variable *v, *r;
  2188. X   struct exp_ese *e;
  2189. X   int save_elevel;
  2190. X   int position, epos;
  2191. X#if INTENSIVE_DEBUG
  2192. X   register int i;
  2193. X#endif
  2194. X
  2195. X   position = 0;
  2196. X
  2197. X   /* get the function name in tbuf */
  2198. X
  2199. X   exp_getvfname( expression, tbuf );
  2200. X
  2201. X   /* find the function name in the function-subroutine lookup table */
  2202. X
  2203. X   for ( f = CURTASK fslt_start.next; f != &CURTASK fslt_end; f = f->next )
  2204. X      {
  2205. X      if ( strcmp( f->name, tbuf ) == 0 )
  2206. X     {
  2207. X#if INTENSIVE_DEBUG
  2208. X     sprintf( bwb_ebuf, "in exp_ufnc(): found user function <%s>",
  2209. X        tbuf );
  2210. X     bwb_debug( bwb_ebuf );
  2211. X#endif
  2212. X     c = f;         /* current function-subroutine lookup table element */
  2213. X     call_line = f->line;    /* line to call for function */
  2214. X     }
  2215. X      }
  2216. X
  2217. X#if INTENSIVE_DEBUG
  2218. X   sprintf( bwb_ebuf, "in exp_ufnc(): call to function <%s>", tbuf );
  2219. X   bwb_debug( bwb_ebuf );
  2220. X#endif
  2221. X
  2222. X   position += strlen( tbuf );
  2223. X
  2224. X#if INTENSIVE_DEBUG
  2225. X   sprintf( bwb_ebuf, "in exp_ufnc(): found line <%s>",
  2226. X      call_line->buffer );
  2227. X   bwb_debug( bwb_ebuf );
  2228. X#endif
  2229. X
  2230. X   /* save the old position on the EXEC stack */
  2231. X
  2232. X   bwb_setexec( CURTASK excs[ CURTASK exsc ].line,
  2233. X      position, CURTASK excs[ CURTASK exsc ].code );
  2234. X   save_elevel = CURTASK exsc;
  2235. X
  2236. X   /* increment and set new EXEC stack */
  2237. X
  2238. X   bwb_incexec();
  2239. X   call_line->position = 0;
  2240. X   bwb_setexec( call_line, 0, EXEC_FUNCTION );
  2241. X
  2242. X   /* attach local variables */
  2243. X
  2244. X   CURTASK excs[ CURTASK exsc ].local_variable = c->local_variable;
  2245. X
  2246. X#if INTENSIVE_DEBUG
  2247. X   i = 0;
  2248. X   sprintf( bwb_ebuf, "in exp_ufnc(): <%s> attached local variables EXEC level <%d>",
  2249. X      tbuf, CURTASK exsc );
  2250. X   bwb_debug( bwb_ebuf );
  2251. X   for ( v = CURTASK excs[ CURTASK exsc ].local_variable; v != NULL; v = v->next )
  2252. X      {
  2253. X      sprintf( bwb_ebuf, "in exp_ufnc():   <%s> level <%d> variable <%d> name <%s>",
  2254. X     tbuf, CURTASK exsc, i, v->name );
  2255. X      bwb_debug( bwb_ebuf );
  2256. X      ++i;
  2257. X      }
  2258. X   getchar();
  2259. X#endif
  2260. X
  2261. X   /* read calling variables for this call */
  2262. X
  2263. X   call_readargs( c, expression, &position );
  2264. X
  2265. X#if INTENSIVE_DEBUG
  2266. X   sprintf( bwb_ebuf, "in exp_ufnc(): current buffer <%s>",
  2267. X      &( call_line->buffer[ c->startpos ] ) );
  2268. X   bwb_debug( bwb_ebuf );
  2269. X#endif
  2270. X
  2271. X   /* determine if single-line function */
  2272. X
  2273. X   epos = c->startpos;
  2274. X   adv_ws( call_line->buffer, &epos );
  2275. X   if ( call_line->buffer[ epos ] == '=' )
  2276. X      {
  2277. X
  2278. X#if INTENSIVE_DEBUG
  2279. X      sprintf( bwb_ebuf, "in exp_ufnc(): found SINGLE-LINE function" );
  2280. X      bwb_debug( bwb_ebuf );
  2281. X#endif
  2282. X
  2283. X      ++epos;
  2284. X      call_line->position = epos;
  2285. X      bwb_setexec( call_line, epos, EXEC_FUNCTION );
  2286. X
  2287. X#if INTENSIVE_DEBUG
  2288. X      sprintf( bwb_ebuf, "in exp_ufnc(): single line: parse <%s>",
  2289. X     &( call_line->buffer[ epos ] ) );
  2290. X      bwb_debug( bwb_ebuf );
  2291. X#endif
  2292. X
  2293. X      e = bwb_exp( call_line->buffer, FALSE, &epos );
  2294. X      v = var_find( tbuf );
  2295. X
  2296. X#if INTENSIVE_DEBUG
  2297. X      if ( e->type == STRING )
  2298. X     {
  2299. X     sprintf( bwb_ebuf, "in exp_ufnc(): expression returns <%d>-byte string",
  2300. X        exp_getsval( e )->length );
  2301. X     bwb_debug( bwb_ebuf );
  2302. X     }
  2303. X      else
  2304. X     {
  2305. X     sprintf( bwb_ebuf, "in exp_ufnc(): expression returns number <%lf>",
  2306. X        (double) exp_getnval( e ) );
  2307. X     bwb_debug( bwb_ebuf );
  2308. X     }
  2309. X#endif
  2310. X
  2311. X#if INTENSIVE_DEBUG
  2312. X      sprintf( bwb_ebuf, "in exp_ufnc(): single line after parsing, <%s>",
  2313. X     &( call_line->buffer[ epos ] ) );
  2314. X      bwb_debug( bwb_ebuf );
  2315. X#endif
  2316. X
  2317. X      bwb_etov( v, e );
  2318. X      bwb_decexec();
  2319. X      }
  2320. X
  2321. X   /* multi-line function must be executed now */
  2322. X
  2323. X   else
  2324. X      {
  2325. X
  2326. X#if INTENSIVE_DEBUG
  2327. X      sprintf( bwb_ebuf, "in exp_ufnc(): found MULTI-LINE function" );
  2328. X      bwb_debug( bwb_ebuf );
  2329. X#endif
  2330. X
  2331. X      /* now execute until function is resolved */
  2332. X
  2333. X      bwb_execline();
  2334. X      while( CURTASK exsc > save_elevel )
  2335. X     {
  2336. X     bwb_execline();
  2337. X     }
  2338. X
  2339. X      /* find the return value */
  2340. X
  2341. X      for ( r = c->local_variable; r != NULL; r = r->next )
  2342. X     {
  2343. X     if ( strcmp( r->name, c->name ) == 0 )
  2344. X        {
  2345. X        v = r;
  2346. X        }
  2347. X     }
  2348. X
  2349. X      }
  2350. X
  2351. X   /* now place value in expression stack */
  2352. X
  2353. X   CURTASK exps[ CURTASK expsc ].type = (char) v->type;
  2354. X   CURTASK exps[ CURTASK expsc ].pos_adv = position;
  2355. X
  2356. X   switch( v->type )
  2357. X      {
  2358. X      case STRING:
  2359. X     CURTASK exps[ CURTASK expsc ].operation = CONST_STRING;
  2360. X
  2361. X#if INTENSIVE_DEBUG
  2362. X     sprintf( bwb_ebuf, "in exp_ufnc(): ready to assign <%d>-byte STRING",
  2363. X        var_getsval( v )->length );
  2364. X     bwb_debug( bwb_ebuf );
  2365. X#endif
  2366. X
  2367. X     str_btob( exp_getsval( &( CURTASK exps[ CURTASK expsc ] )),
  2368. X        var_getsval( v ) );
  2369. X
  2370. X#if INTENSIVE_DEBUG
  2371. X     str_btoc( tbuf, var_getsval( v ) );
  2372. X     sprintf( bwb_ebuf, "in exp_ufnc(): string assigned <%s>", tbuf );
  2373. X     bwb_debug( bwb_ebuf );
  2374. X#endif
  2375. X
  2376. X     break;
  2377. X
  2378. X      default:
  2379. X     CURTASK exps[ CURTASK expsc ].operation = NUMBER;
  2380. X     CURTASK exps[ CURTASK expsc ].nval = var_getnval( v );
  2381. X     break;
  2382. X      }
  2383. X
  2384. X   return TRUE;
  2385. X
  2386. X   }
  2387. X
  2388. X/***************************************************************
  2389. X
  2390. X    FUNCTION:       fslt_addlocalvar()
  2391. X
  2392. X    DESCRIPTION:    This function adds a local variable
  2393. X            to the FUNCTION-SUB lookuop table at
  2394. X            a specific level.
  2395. X
  2396. X***************************************************************/
  2397. X
  2398. X#if ANSI_C
  2399. Xint
  2400. Xfslt_addlocalvar( struct fslte *f, struct bwb_variable *v )
  2401. X#else
  2402. Xint
  2403. Xfslt_addlocalvar( f, v )
  2404. X   struct fslte *f;
  2405. X   struct bwb_variable *v;
  2406. X#endif
  2407. X   {
  2408. X   struct bwb_variable *c, *p;
  2409. X#if INTENSIVE_DEBUG
  2410. X   register int i;
  2411. X#endif
  2412. X
  2413. X   /* find end of local chain */
  2414. X
  2415. X   if ( f->local_variable == NULL )
  2416. X      {
  2417. X#if INTENSIVE_DEBUG
  2418. X      i = 0;
  2419. X#endif
  2420. X      f->local_variable = v;
  2421. X      }
  2422. X   else
  2423. X      {
  2424. X#if INTENSIVE_DEBUG
  2425. X      i = 1;
  2426. X#endif
  2427. X      p = f->local_variable;
  2428. X      for ( c = f->local_variable->next; c != NULL; c = c->next )
  2429. X         {
  2430. X         p = c;
  2431. X#if INTENSIVE_DEBUG
  2432. X         ++i;
  2433. X#endif
  2434. X         }
  2435. X      p->next = v;
  2436. X      }
  2437. X
  2438. X   v->next = NULL;
  2439. X
  2440. X#if INTENSIVE_DEBUG
  2441. X   sprintf( bwb_ebuf, "in fslt_addlocalvar(): added local variable variable <%s> arg number <%d>",
  2442. X      v->name, i );
  2443. X   bwb_debug( bwb_ebuf );
  2444. X   getchar();
  2445. X#endif
  2446. X
  2447. X   return TRUE;
  2448. X
  2449. X   }
  2450. X
  2451. X/***************************************************************
  2452. X
  2453. X    FUNCTION:       fslt_init()
  2454. X
  2455. X    DESCRIPTION:    This function initializes the FUNCTION-SUB
  2456. X            lookup table.
  2457. X
  2458. X***************************************************************/
  2459. X
  2460. X#if ANSI_C
  2461. Xint
  2462. Xfslt_init( int task )
  2463. X#else
  2464. Xint
  2465. Xfslt_init( task )
  2466. X   int task;
  2467. X#endif
  2468. X   {
  2469. X   LOCALTASK fslt_start.next = &(LOCALTASK fslt_end);
  2470. X   return TRUE;
  2471. X   }
  2472. X
  2473. X/***************************************************************
  2474. X
  2475. X    FUNCTION:       is_label()
  2476. X
  2477. X    DESCRIPTION:    This function determines whether the string
  2478. X            pointed to by 'buffer' is a label (i.e.,
  2479. X            ends with colon).
  2480. X
  2481. X***************************************************************/
  2482. X
  2483. X#if ANSI_C
  2484. Xextern int
  2485. Xis_label( char *buffer )
  2486. X#else
  2487. Xint
  2488. Xis_label( buffer )
  2489. X   char *buffer;
  2490. X#endif
  2491. X   {
  2492. X
  2493. X#if INTENSIVE_DEBUG
  2494. X   sprintf( bwb_ebuf, "in is_label(): check element <%s>", buffer );
  2495. X   bwb_debug( bwb_ebuf );
  2496. X#endif
  2497. X
  2498. X   if ( buffer[ strlen( buffer ) - 1 ] == ':' )
  2499. X      {
  2500. X      return TRUE;
  2501. X      }
  2502. X   else
  2503. X      {
  2504. X      return FALSE;
  2505. X      }
  2506. X
  2507. X   }
  2508. X
  2509. X
  2510. END_OF_FILE
  2511.   if test 52211 -ne `wc -c <'bwbasic-2.10/bwb_stc.c'`; then
  2512.     echo shar: \"'bwbasic-2.10/bwb_stc.c'\" unpacked with wrong size!
  2513.   fi
  2514.   # end of 'bwbasic-2.10/bwb_stc.c'
  2515. fi
  2516. if test -f 'bwbasic-2.10/configure' -a "${1}" != "-c" ; then 
  2517.   echo shar: Will not clobber existing file \"'bwbasic-2.10/configure'\"
  2518. else
  2519.   echo shar: Extracting \"'bwbasic-2.10/configure'\" \(8681 characters\)
  2520.   sed "s/^X//" >'bwbasic-2.10/configure' <<'END_OF_FILE'
  2521. X#!/bin/sh
  2522. X# Guess values for system-dependent variables and create Makefiles.
  2523. X# Generated automatically using autoconf.
  2524. X# Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
  2525. X
  2526. X# This program is free software; you can redistribute it and/or modify
  2527. X# it under the terms of the GNU General Public License as published by
  2528. X# the Free Software Foundation; either version 2, or (at your option)
  2529. X# any later version.
  2530. X
  2531. X# This program is distributed in the hope that it will be useful,
  2532. X# but WITHOUT ANY WARRANTY; without even the implied warranty of
  2533. X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2534. X# GNU General Public License for more details.
  2535. X
  2536. X# You should have received a copy of the GNU General Public License
  2537. X# along with this program; if not, write to the Free Software
  2538. X# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2539. X
  2540. X# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create]
  2541. X#        [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET]
  2542. X# Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and
  2543. X# --with-PACKAGE unless this script has special code to handle it.
  2544. X
  2545. X
  2546. Xfor arg
  2547. Xdo
  2548. X  # Handle --exec-prefix with a space before the argument.
  2549. X  if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix=
  2550. X  # Handle --host with a space before the argument.
  2551. X  elif test x$next_host = xyes; then next_host=
  2552. X  # Handle --prefix with a space before the argument.
  2553. X  elif test x$next_prefix = xyes; then prefix=$arg; next_prefix=
  2554. X  # Handle --srcdir with a space before the argument.
  2555. X  elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir=
  2556. X  else
  2557. X    case $arg in
  2558. X     # For backward compatibility, also recognize exact --exec_prefix.
  2559. X     -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*)
  2560. X    exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  2561. X     -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e)
  2562. X    next_exec_prefix=yes ;;
  2563. X
  2564. X     -gas | --gas | --ga | --g) ;;
  2565. X
  2566. X     -host=* | --host=* | --hos=* | --ho=* | --h=*) ;;
  2567. X     -host | --host | --hos | --ho | --h)
  2568. X    next_host=yes ;;
  2569. X
  2570. X     -nfp | --nfp | --nf) ;;
  2571. X
  2572. X     -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no)
  2573. X        no_create=1 ;;
  2574. X
  2575. X     -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
  2576. X    prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  2577. X     -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
  2578. X    next_prefix=yes ;;
  2579. X
  2580. X     -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*)
  2581. X    srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  2582. X     -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s)
  2583. X    next_srcdir=yes ;;
  2584. X
  2585. X     -with-* | --with-*)
  2586. X       package=`echo $arg|sed 's/-*with-//'`
  2587. X       # Delete all the valid chars; see if any are left.
  2588. X       if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then
  2589. X         echo "configure: $package: invalid package name" >&2; exit 1
  2590. X       fi
  2591. X       eval "with_`echo $package|sed s/-/_/g`=1" ;;
  2592. X
  2593. X     *) ;;
  2594. X    esac
  2595. X  fi
  2596. Xdone
  2597. X
  2598. Xtrap 'rm -f conftest* core; exit 1' 1 3 15
  2599. X
  2600. Xrm -f conftest*
  2601. Xcompile='${CC-cc} $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1'
  2602. X
  2603. X# A filename unique to this package, relative to the directory that
  2604. X# configure is in, which we can look for to find out if srcdir is correct.
  2605. Xunique_file=bwb_cmd.c
  2606. X
  2607. X# Find the source files, if location was not specified.
  2608. Xif test -z "$srcdir"; then
  2609. X  srcdirdefaulted=yes
  2610. X  # Try the directory containing this script, then `..'.
  2611. X  prog=$0
  2612. X  confdir=`echo $prog|sed 's%/[^/][^/]*$%%'`
  2613. X  test "X$confdir" = "X$prog" && confdir=.
  2614. X  srcdir=$confdir
  2615. X  if test ! -r $srcdir/$unique_file; then
  2616. X    srcdir=..
  2617. X  fi
  2618. Xfi
  2619. Xif test ! -r $srcdir/$unique_file; then
  2620. X  if test x$srcdirdefaulted = xyes; then
  2621. X    echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2
  2622. X  else
  2623. X    echo "configure: Can not find sources in \`${srcdir}'." 1>&2
  2624. X  fi
  2625. X  exit 1
  2626. Xfi
  2627. X# Preserve a srcdir of `.' to avoid automounter screwups with pwd.
  2628. X# But we can't avoid them for `..', to make subdirectories work.
  2629. Xcase $srcdir in
  2630. X  .|/*|~*) ;;
  2631. X  *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute.
  2632. Xesac
  2633. X
  2634. Xif test -z "$CC"; then
  2635. X  echo checking for gcc
  2636. X  saveifs="$IFS"; IFS="${IFS}:"
  2637. X  for dir in $PATH; do
  2638. X    test -z "$dir" && dir=.
  2639. X    if test -f $dir/gcc; then
  2640. X      CC="gcc"
  2641. X      break
  2642. X    fi
  2643. X  done
  2644. X  IFS="$saveifs"
  2645. Xfi
  2646. Xtest -z "$CC" && CC="cc"
  2647. X
  2648. X# Find out if we are using GNU C, under whatever name.
  2649. Xcat > conftest.c <<EOF
  2650. X#ifdef __GNUC__
  2651. X  yes
  2652. X#endif
  2653. XEOF
  2654. X${CC-cc} -E conftest.c > conftest.out 2>&1
  2655. Xif egrep yes conftest.out >/dev/null 2>&1; then
  2656. X  GCC=1 # For later tests.
  2657. Xfi
  2658. Xrm -f conftest*
  2659. X
  2660. Xecho checking how to run the C preprocessor
  2661. Xif test -z "$CPP"; then
  2662. X  CPP='${CC-cc} -E'
  2663. X  cat > conftest.c <<EOF
  2664. X#include <stdio.h>
  2665. XEOF
  2666. Xerr=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
  2667. Xif test -z "$err"; then
  2668. X  :
  2669. Xelse
  2670. X  CPP=/lib/cpp
  2671. Xfi
  2672. Xrm -f conftest*
  2673. Xfi
  2674. X
  2675. X# Make sure to not get the incompatible SysV /etc/install and
  2676. X# /usr/sbin/install, which might be in PATH before a BSD-like install,
  2677. X# or the SunOS /usr/etc/install directory, or the AIX /bin/install,
  2678. X# or the AFS install, which mishandles nonexistent args.  (Sigh.)
  2679. Xif test -z "$INSTALL"; then
  2680. X  echo checking for install
  2681. X  saveifs="$IFS"; IFS="${IFS}:"
  2682. X  for dir in $PATH; do
  2683. X    test -z "$dir" && dir=.
  2684. X    case $dir in
  2685. X    /etc|/usr/sbin|/usr/etc|/usr/afsws/bin) ;;
  2686. X    *)
  2687. X      if test -f $dir/install; then
  2688. X    if grep dspmsg $dir/install >/dev/null 2>&1; then
  2689. X      : # AIX
  2690. X    else
  2691. X      INSTALL="$dir/install -c"
  2692. X      INSTALL_PROGRAM='$(INSTALL)'
  2693. X      INSTALL_DATA='$(INSTALL) -m 644'
  2694. X      break
  2695. X    fi
  2696. X      fi
  2697. X      ;;
  2698. X    esac
  2699. X  done
  2700. X  IFS="$saveifs"
  2701. Xfi
  2702. XINSTALL=${INSTALL-cp}
  2703. XINSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'}
  2704. XINSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'}
  2705. X
  2706. Xecho checking for size_t in sys/types.h
  2707. Xecho '#include <sys/types.h>' > conftest.c
  2708. Xeval "$CPP $DEFS conftest.c > conftest.out 2>&1"
  2709. Xif egrep "size_t" conftest.out >/dev/null 2>&1; then
  2710. X  :
  2711. Xelse 
  2712. X  DEFS="$DEFS -Dsize_t=unsigned"
  2713. Xfi
  2714. Xrm -f conftest*
  2715. X
  2716. Xecho checking for string.h
  2717. Xcat > conftest.c <<EOF
  2718. X#include <string.h>
  2719. XEOF
  2720. Xerr=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
  2721. Xif test -z "$err"; then
  2722. X  DEFS="$DEFS -DHAVE_STRING=1"
  2723. Xfi
  2724. Xrm -f conftest*
  2725. X
  2726. Xecho checking for stdlib.h
  2727. Xcat > conftest.c <<EOF
  2728. X#include <stdlib.h>
  2729. XEOF
  2730. Xerr=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
  2731. Xif test -z "$err"; then
  2732. X  DEFS="$DEFS -DHAVE_STDLIB=1"
  2733. Xfi
  2734. Xrm -f conftest*
  2735. X
  2736. Xecho checking for raise
  2737. Xcat > conftest.c <<EOF
  2738. X#include <sys/types.h>
  2739. X#include <signal.h>
  2740. Xmain() { exit(0); } 
  2741. Xt() { raise(1); }
  2742. XEOF
  2743. Xif eval $compile; then
  2744. X  DEFS="$DEFS -DHAVE_RAISE=1"
  2745. Xfi
  2746. Xrm -f conftest*
  2747. X
  2748. Xif test -n "$prefix"; then
  2749. X  test -z "$exec_prefix" && exec_prefix='${prefix}'
  2750. X  prsub="s%^prefix\\([     ]*\\)=\\([     ]*\\).*$%prefix\\1=\\2$prefix%"
  2751. Xfi
  2752. Xif test -n "$exec_prefix"; then
  2753. X  prsub="$prsub
  2754. Xs%^exec_prefix\\([     ]*\\)=\\([     ]*\\).*$%\
  2755. Xexec_prefix\\1=\\2$exec_prefix%"
  2756. Xfi
  2757. X
  2758. Xtrap 'rm -f config.status; exit 1' 1 3 15
  2759. Xecho creating config.status
  2760. Xrm -f config.status
  2761. Xcat > config.status <<EOF
  2762. X#!/bin/sh
  2763. X# Generated automatically by configure.
  2764. X# Run this file to recreate the current configuration.
  2765. X# This directory was configured as follows,
  2766. X# on host `(hostname || uname -n) 2>/dev/null`:
  2767. X#
  2768. X# $0 $*
  2769. X
  2770. Xfor arg
  2771. Xdo
  2772. X  case "\$arg" in
  2773. X    -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
  2774. X    exec /bin/sh $0 $* ;;
  2775. X    *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;;
  2776. X  esac
  2777. Xdone
  2778. X
  2779. Xtrap 'rm -f Makefile; exit 1' 1 3 15
  2780. XCC='$CC'
  2781. XCPP='$CPP'
  2782. XINSTALL='$INSTALL'
  2783. XINSTALL_PROGRAM='$INSTALL_PROGRAM'
  2784. XINSTALL_DATA='$INSTALL_DATA'
  2785. XLIBS='$LIBS'
  2786. Xsrcdir='$srcdir'
  2787. XDEFS='$DEFS'
  2788. Xprefix='$prefix'
  2789. Xexec_prefix='$exec_prefix'
  2790. Xprsub='$prsub'
  2791. XEOF
  2792. Xcat >> config.status <<\EOF
  2793. X
  2794. Xtop_srcdir=$srcdir
  2795. Xfor file in .. Makefile; do if [ "x$file" != "x.." ]; then
  2796. X  srcdir=$top_srcdir
  2797. X  # Remove last slash and all that follows it.  Not all systems have dirname.
  2798. X  dir=`echo $file|sed 's%/[^/][^/]*$%%'`
  2799. X  if test "$dir" != "$file"; then
  2800. X    test "$top_srcdir" != . && srcdir=$top_srcdir/$dir
  2801. X    test ! -d $dir && mkdir $dir
  2802. X  fi
  2803. X  echo creating $file
  2804. X  rm -f $file
  2805. X  echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file
  2806. X  sed -e "
  2807. X$prsub
  2808. Xs%@CC@%$CC%g
  2809. Xs%@CPP@%$CPP%g
  2810. Xs%@INSTALL@%$INSTALL%g
  2811. Xs%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
  2812. Xs%@INSTALL_DATA@%$INSTALL_DATA%g
  2813. Xs%@LIBS@%$LIBS%g
  2814. Xs%@srcdir@%$srcdir%g
  2815. Xs%@DEFS@%$DEFS%
  2816. X" $top_srcdir/${file}.in >> $file
  2817. Xfi; done
  2818. X
  2819. XEOF
  2820. Xchmod +x config.status
  2821. Xtest -n "$no_create" || ./config.status
  2822. X
  2823. END_OF_FILE
  2824.   if test 8681 -ne `wc -c <'bwbasic-2.10/configure'`; then
  2825.     echo shar: \"'bwbasic-2.10/configure'\" unpacked with wrong size!
  2826.   fi
  2827.   chmod +x 'bwbasic-2.10/configure'
  2828.   # end of 'bwbasic-2.10/configure'
  2829. fi
  2830. echo shar: End of archive 4 \(of 15\).
  2831. cp /dev/null ark4isdone
  2832. MISSING=""
  2833. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  2834.     if test ! -f ark${I}isdone ; then
  2835.     MISSING="${MISSING} ${I}"
  2836.     fi
  2837. done
  2838. if test "${MISSING}" = "" ; then
  2839.     echo You have unpacked all 15 archives.
  2840.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2841. else
  2842.     echo You still must unpack the following archives:
  2843.     echo "        " ${MISSING}
  2844. fi
  2845. exit 0
  2846. exit 0 # Just in case...
  2847.