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

2472 lines
58 KiB

  1. /***************************************************************
  2. bwb_cnd.c Conditional Expressions and Commands
  3. for Bywater BASIC Interpreter
  4. Copyright (c) 1993, Ted A. Campbell
  5. Bywater Software
  6. email: tcamp@delphi.com
  7. Copyright and Permissions Information:
  8. All U.S. and international rights are claimed by the author,
  9. Ted A. Campbell.
  10. This software is released under the terms of the GNU General
  11. Public License (GPL), which is distributed with this software
  12. in the file "COPYING". The GPL specifies the terms under
  13. which users may copy and use the software in this distribution.
  14. A separate license is available for commercial distribution,
  15. for information on which you should contact the author.
  16. ***************************************************************/
  17. /*---------------------------------------------------------------*/
  18. /* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */
  19. /* 11/1995 (eidetics@cerf.net). */
  20. /* */
  21. /* Those additionally marked with "DD" were at the suggestion of */
  22. /* Dale DePriest (daled@cadence.com). */
  23. /*---------------------------------------------------------------*/
  24. #include <stdio.h>
  25. #include <math.h>
  26. #include <ctype.h>
  27. #include "bwbasic.h"
  28. #include "bwb_mes.h"
  29. /* declarations of functions visible to this file only */
  30. #if ANSI_C
  31. static int cnd_thenels( char *buffer, int position, int *then, int *els );
  32. static int cnd_tostep( char *buffer, int position, int *to, int *step );
  33. static struct bwb_line *find_wend( struct bwb_line *l );
  34. static struct bwb_line *find_endif( struct bwb_line *l,
  35. struct bwb_line **else_line );
  36. static int is_endif( struct bwb_line *l );
  37. extern int var_setnval( struct bwb_variable *v, bnumber i );
  38. static int case_eval( struct exp_ese *expression, struct exp_ese *minval,
  39. struct exp_ese *maxval );
  40. static struct bwb_line *find_case( struct bwb_line *l );
  41. static struct bwb_line *find_endselect( struct bwb_line *l );
  42. static int is_endselect( struct bwb_line *l );
  43. static struct bwb_line *bwb_caseif( struct bwb_line *l );
  44. #if STRUCT_CMDS
  45. static struct bwb_line *find_next( struct bwb_line *l );
  46. #endif
  47. #else
  48. static int cnd_thenels();
  49. static int cnd_tostep();
  50. static struct bwb_line *find_wend();
  51. static struct bwb_line *find_endif();
  52. static int is_endif();
  53. extern int var_setnval();
  54. static int case_eval();
  55. static struct bwb_line *find_case();
  56. static struct bwb_line *find_endselect();
  57. static int is_endselect();
  58. static struct bwb_line *bwb_caseif();
  59. #if STRUCT_CMDS
  60. static struct bwb_line *find_next();
  61. #endif
  62. #endif /* ANSI_C for prototypes */
  63. /*** IF-THEN-ELSE ***/
  64. /***************************************************************
  65. FUNCTION: bwb_if()
  66. DESCRIPTION: This function handles the BASIC IF
  67. statement.
  68. SYNTAX: IF expression THEN [statement [ELSE statement]]
  69. ***************************************************************/
  70. #if ANSI_C
  71. struct bwb_line *
  72. bwb_if( struct bwb_line *l )
  73. #else
  74. struct bwb_line *
  75. bwb_if( l )
  76. struct bwb_line *l;
  77. #endif
  78. {
  79. int then, els;
  80. struct exp_ese *e;
  81. int glnumber;
  82. int tpos;
  83. static char tbuf[ MAXSTRINGSIZE + 1 ];
  84. static struct bwb_line gline;
  85. #if STRUCT_CMDS
  86. static struct bwb_line *else_line;
  87. static struct bwb_line *endif_line;
  88. #endif
  89. #if INTENSIVE_DEBUG
  90. sprintf( bwb_ebuf, "in bwb_if(): entry, line <%d> buffer <%s>",
  91. l->number, &( l->buffer[ l->position ] ) );
  92. bwb_debug( bwb_ebuf );
  93. getchar();
  94. #endif
  95. #if INTENSIVE_DEBUG
  96. if ( l == &gline )
  97. {
  98. sprintf( bwb_ebuf, "in bwb_if(): recursive call, l = &gline" );
  99. bwb_debug( bwb_ebuf );
  100. }
  101. #endif
  102. /* Call bwb_exp() to evaluate the condition. This should return
  103. with position set to the "THEN" statement */
  104. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  105. #if INTENSIVE_DEBUG
  106. sprintf( bwb_ebuf, "in bwb_if(): line <%d> condition returns <%d>",
  107. l->number, exp_getnval( e ) );
  108. bwb_debug( bwb_ebuf );
  109. #endif
  110. /* test for "THEN" and "ELSE" statements */
  111. cnd_thenels( l->buffer, l->position, &then, &els );
  112. #if INTENSIVE_DEBUG
  113. sprintf( bwb_ebuf, "in bwb_if(): return from cnd_thenelse, line is <%s>",
  114. l->buffer );
  115. bwb_debug( bwb_ebuf );
  116. #endif
  117. /* test for multiline IF statement: this presupposes ANSI-compliant
  118. structured BASIC */
  119. #if STRUCT_CMDS
  120. tpos = then + strlen( CMD_THEN ) + 1;
  121. if ( is_eol( l->buffer, &tpos ) == TRUE )
  122. {
  123. #if INTENSIVE_DEBUG
  124. sprintf( bwb_ebuf, "in bwb_if(): found multi-line IF statement, line <%d>",
  125. l->number );
  126. bwb_debug( bwb_ebuf );
  127. #endif
  128. /* find END IF and possibly ELSE[IF] line(s) */
  129. else_line = NULL;
  130. endif_line = find_endif( l, &else_line );
  131. /* evaluate the expression */
  132. if ( (int) exp_getnval( e ) != FALSE )
  133. {
  134. bwb_incexec();
  135. bwb_setexec( l->next, 0, EXEC_IFTRUE );
  136. #if MULTISEG_LINES
  137. adv_eos( l->buffer, &( l->position ));
  138. #endif
  139. return bwb_zline( l );
  140. }
  141. else if ( else_line != NULL )
  142. {
  143. bwb_incexec();
  144. bwb_setexec( else_line, 0, EXEC_IFFALSE );
  145. else_line->position = 0;
  146. return else_line;
  147. }
  148. else
  149. {
  150. /* Following line incorrect, replaced by next two (bug found by DD) */
  151. /* bwb_setexec( endif_line, 0, CURTASK excs[ CURTASK exsc ].code ); */
  152. bwb_incexec(); /* JBV */
  153. bwb_setexec( endif_line, 0, EXEC_IFFALSE ); /* JBV */
  154. endif_line->position = 0;
  155. return endif_line;
  156. }
  157. }
  158. #endif /* STRUCT_CMDS for Multi-line IF...THEN */
  159. /* Not a Multi-line IF...THEN: test for THEN line-number */
  160. #if INTENSIVE_DEBUG
  161. sprintf( bwb_ebuf, "in bwb_if(): not multi-line; line is <%s>",
  162. l->buffer );
  163. bwb_debug( bwb_ebuf );
  164. #endif
  165. /* evaluate and execute */
  166. if ( (int) exp_getnval( e ) != FALSE )
  167. {
  168. #if INTENSIVE_DEBUG
  169. sprintf( bwb_ebuf, "in bwb_if(): expression is TRUE" );
  170. bwb_debug( bwb_ebuf );
  171. #endif
  172. if ( then == FALSE )
  173. {
  174. #if PROG_ERRORS
  175. sprintf( bwb_ebuf, "in bwb_if(): IF without THEN" );
  176. bwb_error( bwb_ebuf );
  177. #else
  178. bwb_error( err_syntax );
  179. #endif
  180. }
  181. else
  182. {
  183. /* check for THEN followed by literal line number */
  184. tpos = then + strlen( CMD_THEN ) + 1;
  185. adv_element( l->buffer, &tpos, tbuf );
  186. if ( isdigit( tbuf[ 0 ] ) != 0 )
  187. {
  188. glnumber = atoi( tbuf );
  189. #if INTENSIVE_DEBUG
  190. sprintf( bwb_ebuf, "Detected THEN followed by line number <%d>",
  191. glnumber );
  192. bwb_debug( bwb_ebuf );
  193. #endif
  194. sprintf( tbuf, "%s %d", CMD_GOTO, glnumber );
  195. gline.buffer = tbuf;
  196. gline.marked = FALSE;
  197. gline.position = 0;
  198. gline.next = l->next;
  199. bwb_setexec( &gline, 0, CURTASK excs[ CURTASK exsc ].code );
  200. return &gline;
  201. }
  202. /* form is not THEN followed by line number */
  203. else
  204. {
  205. bwb_setexec( l, then, CURTASK excs[ CURTASK exsc ].code );
  206. l->position = then + strlen( CMD_THEN ) + 1;
  207. }
  208. return l;
  209. }
  210. }
  211. else
  212. {
  213. #if INTENSIVE_DEBUG
  214. sprintf( bwb_ebuf, "in bwb_if(): expression is FALSE" );
  215. bwb_debug( bwb_ebuf );
  216. #endif
  217. if ( els != FALSE )
  218. {
  219. l->position = els + strlen( CMD_ELSE ) + 1;
  220. /* bwb_setexec( l, els, EXEC_NORM ); */ /* Nope (JBV) */
  221. bwb_setexec( l, els, CURTASK excs[ CURTASK exsc ].code ); /* JBV */
  222. return l;
  223. }
  224. }
  225. /* if neither then nor else were found, advance to next line */
  226. /* DO NOT advance to next segment (only if TRUE should we do that) */
  227. l->next->position = 0;
  228. return l->next;
  229. }
  230. /***************************************************************
  231. FUNCTION: cnd_thenelse()
  232. DESCRIPTION: This function searches through the
  233. <buffer> beginning at point <position>
  234. and attempts to find positions of THEN
  235. and ELSE statements.
  236. ***************************************************************/
  237. #if ANSI_C
  238. static int
  239. cnd_thenels( char *buffer, int position, int *then, int *els )
  240. #else
  241. static int
  242. cnd_thenels( buffer, position, then, els )
  243. char *buffer;
  244. int position;
  245. int *then;
  246. int *els;
  247. #endif
  248. {
  249. int loop, t_pos, b_pos, p_word;
  250. char tbuf[ MAXSTRINGSIZE + 1 ];
  251. #if INTENSIVE_DEBUG
  252. sprintf( bwb_ebuf, "in cnd_thenels(): entry, line is <%s>",
  253. &( buffer[ position ] ) );
  254. bwb_debug( bwb_ebuf );
  255. #endif
  256. /* set then and els to 0 initially */
  257. *then = *els = 0;
  258. /* loop to find words */
  259. p_word = b_pos = position;
  260. t_pos = 0;
  261. tbuf[ 0 ] = '\0';
  262. loop = TRUE;
  263. while( loop == TRUE )
  264. {
  265. switch( buffer[ b_pos ] )
  266. {
  267. case '\0': /* end of string */
  268. case ' ': /* whitespace = end of word */
  269. case '\t':
  270. #if INTENSIVE_DEBUG
  271. sprintf( bwb_ebuf, "in cnd_thenels(): word is <%s>", tbuf );
  272. bwb_debug( bwb_ebuf );
  273. #endif
  274. if ( strncmp( tbuf, CMD_THEN, (size_t) strlen( CMD_THEN ) ) == 0 )
  275. {
  276. #if INTENSIVE_DEBUG
  277. sprintf( bwb_ebuf, "in cnd_thenels(): THEN found at position <%d>.",
  278. p_word );
  279. bwb_debug( bwb_ebuf );
  280. sprintf( bwb_ebuf, "in cnd_thenelse(): after THEN, line is <%s>", buffer );
  281. bwb_debug( bwb_ebuf );
  282. #endif
  283. *then = p_word;
  284. }
  285. else if ( strncmp( tbuf, CMD_ELSE, (size_t) strlen( CMD_ELSE ) ) == 0 )
  286. {
  287. #if INTENSIVE_DEBUG
  288. sprintf( bwb_ebuf, "in cnd_thenels(): ELSE found at position <%d>.",
  289. p_word );
  290. bwb_debug( bwb_ebuf );
  291. sprintf( bwb_ebuf, "in cnd_thenelse(): after ELSE, line is <%s>", buffer );
  292. bwb_debug( bwb_ebuf );
  293. #endif
  294. *els = p_word;
  295. }
  296. /* check for end of the line */
  297. if ( buffer[ b_pos ] == '\0' )
  298. {
  299. #if INTENSIVE_DEBUG
  300. sprintf( bwb_ebuf, "in cnd_thenels(): return: end of string" );
  301. bwb_debug( bwb_ebuf );
  302. #endif
  303. return TRUE;
  304. }
  305. ++b_pos;
  306. p_word = b_pos;
  307. t_pos = 0;
  308. tbuf[ 0 ] = '\0';
  309. break;
  310. default:
  311. if ( islower( buffer[ b_pos ] ) != FALSE )
  312. {
  313. tbuf[ t_pos ] = (char) toupper( buffer[ b_pos ] );
  314. }
  315. else
  316. {
  317. tbuf[ t_pos ] = buffer[ b_pos ];
  318. }
  319. ++b_pos;
  320. ++t_pos;
  321. tbuf[ t_pos ] = '\0';
  322. break;
  323. }
  324. }
  325. #if INTENSIVE_DEBUG
  326. sprintf( bwb_ebuf, "in cnd_thenelse(): exit, line is <%s>", buffer );
  327. bwb_debug( bwb_ebuf );
  328. #endif
  329. return FALSE;
  330. }
  331. #if STRUCT_CMDS
  332. /***************************************************************
  333. FUNCTION: bwb_else()
  334. DESCRIPTION: This function handles the BASIC ELSE
  335. statement.
  336. SYNTAX: ELSE
  337. ***************************************************************/
  338. #if ANSI_C
  339. struct bwb_line *
  340. bwb_else( struct bwb_line *l )
  341. #else
  342. struct bwb_line *
  343. bwb_else( l )
  344. struct bwb_line *l;
  345. #endif
  346. {
  347. struct bwb_line *endif_line;
  348. struct bwb_line *else_line;
  349. #if INTENSIVE_DEBUG
  350. sprintf( bwb_ebuf, "in bwb_else(): entered function" );
  351. bwb_debug( bwb_ebuf );
  352. #endif
  353. /* If the code is EXEC_NORM, then this is a continuation of a single-
  354. line IF...THEN...ELSE... statement and we should return */
  355. /*----------------------------------------------------------------------*/
  356. /* Well, not really... better to check for EXEC_IFTRUE or EXEC_IFFALSE, */
  357. /* and if not equal, then blow entirely out of current line (JBV) */
  358. /*----------------------------------------------------------------------*/
  359. /* Section removed by JBV */
  360. /* if ( CURTASK excs[ CURTASK exsc ].code == EXEC_NORM )
  361. {
  362. #if INTENSIVE_DEBUG
  363. sprintf( bwb_ebuf, "in bwb_else(): detected EXEC_NORM" );
  364. bwb_debug( bwb_ebuf );
  365. #endif
  366. return bwb_zline( l );
  367. } */
  368. /* Section added by JBV */
  369. if (( CURTASK excs[ CURTASK exsc ].code != EXEC_IFTRUE ) &&
  370. ( CURTASK excs[ CURTASK exsc ].code != EXEC_IFFALSE ))
  371. {
  372. #if INTENSIVE_DEBUG
  373. sprintf( bwb_ebuf, "in bwb_else(): no EXEC_IFTRUE or EXEC_IFFALSE" );
  374. bwb_debug( bwb_ebuf );
  375. #endif
  376. l->next->position = 0;
  377. return l->next;
  378. }
  379. endif_line = find_endif( l, &else_line );
  380. if ( CURTASK excs[ CURTASK exsc ].code == EXEC_IFTRUE )
  381. {
  382. endif_line->position = 0;
  383. return endif_line;
  384. }
  385. else if ( CURTASK excs[ CURTASK exsc ].code == EXEC_IFFALSE )
  386. {
  387. return bwb_zline( l );
  388. }
  389. #if PROG_ERRORS
  390. sprintf( bwb_ebuf, "in bwb_else(): ELSE without IF" );
  391. bwb_error( bwb_ebuf );
  392. #else
  393. bwb_error( err_syntax );
  394. #endif
  395. return bwb_zline( l );
  396. }
  397. /***************************************************************
  398. FUNCTION: bwb_elseif()
  399. DESCRIPTION: This function handles the BASIC ELSEIF
  400. statement.
  401. SYNTAX: ELSEIF
  402. ***************************************************************/
  403. #if ANSI_C
  404. struct bwb_line *
  405. bwb_elseif( struct bwb_line *l )
  406. #else
  407. struct bwb_line *
  408. bwb_elseif( l )
  409. struct bwb_line *l;
  410. #endif
  411. {
  412. struct bwb_line *endif_line;
  413. struct bwb_line *else_line;
  414. struct exp_ese *e;
  415. #if INTENSIVE_DEBUG
  416. sprintf( bwb_ebuf, "in bwb_elseif(): entered function" );
  417. bwb_debug( bwb_ebuf );
  418. #endif
  419. else_line = NULL;
  420. endif_line = find_endif( l, &else_line );
  421. if ( CURTASK excs[ CURTASK exsc ].code == EXEC_IFTRUE )
  422. {
  423. endif_line->position = 0;
  424. return endif_line;
  425. }
  426. else if ( CURTASK excs[ CURTASK exsc ].code == EXEC_IFFALSE )
  427. {
  428. /* Call bwb_exp() to evaluate the condition. This should return
  429. with position set to the "THEN" statement */
  430. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  431. if ( (int) exp_getnval( e ) != FALSE ) /* Was == TRUE (JBV 10/1996) */
  432. {
  433. /* ELSEIF condition is TRUE: proceed to the next line */
  434. CURTASK excs[ CURTASK exsc ].code = EXEC_IFTRUE;
  435. #if MULTISEG_LINES
  436. adv_eos( l->buffer, &( l->position ));
  437. #endif
  438. return bwb_zline( l );
  439. }
  440. /* ELSEIF condition FALSE: proceed to next ELSE line if there is one */
  441. else if ( else_line != NULL )
  442. {
  443. bwb_setexec( else_line, 0, EXEC_IFFALSE );
  444. else_line->position = 0;
  445. return else_line;
  446. }
  447. /* ELSEIF condition is FALSE and no more ELSExx lines: proceed to END IF */
  448. else
  449. {
  450. bwb_setexec( endif_line, 0, CURTASK excs[ CURTASK exsc ].code );
  451. endif_line->position = 0;
  452. return endif_line;
  453. }
  454. }
  455. #if PROG_ERRORS
  456. sprintf( bwb_ebuf, "in bwb_elseif(): ELSEIF without IF" );
  457. bwb_error( bwb_ebuf );
  458. #else
  459. bwb_error( err_syntax );
  460. #endif
  461. #if MULTISEG_LINES
  462. adv_eos( l->buffer, &( l->position ));
  463. #endif
  464. return bwb_zline( l );
  465. }
  466. /***************************************************************
  467. FUNCTION: bwb_endif()
  468. DESCRIPTION: This function handles the BASIC END IF
  469. statement.
  470. SYNTAX: END IF
  471. ***************************************************************/
  472. #if ANSI_C
  473. struct bwb_line *
  474. bwb_endif( struct bwb_line *l )
  475. #else
  476. struct bwb_line *
  477. bwb_endif( l )
  478. struct bwb_line *l;
  479. #endif
  480. {
  481. #if INTENSIVE_DEBUG
  482. sprintf( bwb_ebuf, "in bwb_endif(): entered function" );
  483. bwb_debug( bwb_ebuf );
  484. #endif
  485. if (( CURTASK excs[ CURTASK exsc ].code != EXEC_IFTRUE )
  486. && ( CURTASK excs[ CURTASK exsc ].code != EXEC_IFFALSE ))
  487. {
  488. #if PROG_ERRORS
  489. sprintf( bwb_ebuf, "in bwb_endif(): END IF without IF" );
  490. bwb_error( bwb_ebuf );
  491. #else
  492. bwb_error( err_syntax );
  493. #endif
  494. }
  495. bwb_decexec();
  496. #if MULTISEG_LINES
  497. adv_eos( l->buffer, &( l->position ));
  498. #endif
  499. return bwb_zline( l );
  500. }
  501. /***************************************************************
  502. FUNCTION: find_endif()
  503. DESCRIPTION: This C function attempts to find an
  504. END IF statement.
  505. ***************************************************************/
  506. #if ANSI_C
  507. static struct bwb_line *
  508. find_endif( struct bwb_line *l, struct bwb_line **else_line )
  509. #else
  510. static struct bwb_line *
  511. find_endif( l, else_line )
  512. struct bwb_line *l;
  513. struct bwb_line **else_line;
  514. #endif
  515. {
  516. struct bwb_line *current;
  517. register int i_level;
  518. int position;
  519. *else_line = NULL;
  520. i_level = 1;
  521. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  522. {
  523. position = 0;
  524. if ( current->marked != TRUE )
  525. {
  526. line_start( current->buffer, &position, &( current->lnpos ),
  527. &( current->lnum ),
  528. &( current->cmdpos ),
  529. &( current->cmdnum ),
  530. &( current->startpos ) );
  531. }
  532. current->position = current->startpos;
  533. if ( current->cmdnum > -1 )
  534. {
  535. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_if )
  536. {
  537. ++i_level;
  538. #if INTENSIVE_DEBUG
  539. sprintf( bwb_ebuf, "in find_endif(): found IF at line %d, level %d",
  540. current->number, i_level );
  541. bwb_debug( bwb_ebuf );
  542. #endif
  543. }
  544. else if ( is_endif( current ) == TRUE )
  545. {
  546. --i_level;
  547. #if INTENSIVE_DEBUG
  548. sprintf( bwb_ebuf, "in find_endif(): found END IF at line %d, level %d",
  549. current->number, i_level );
  550. bwb_debug( bwb_ebuf );
  551. #endif
  552. if ( i_level == 0 )
  553. {
  554. return current;
  555. }
  556. }
  557. else if ( ( bwb_cmdtable[ current->cmdnum ].vector == bwb_else )
  558. || ( bwb_cmdtable[ current->cmdnum ].vector == bwb_elseif ))
  559. {
  560. /* we must only report the first ELSE or ELSE IF we encounter
  561. at level 1 */
  562. if ( ( i_level == 1 ) && ( *else_line == NULL ))
  563. {
  564. *else_line = current;
  565. }
  566. }
  567. }
  568. }
  569. #if PROG_ERRORS
  570. sprintf( bwb_ebuf, "Multiline IF without END IF" );
  571. bwb_error( bwb_ebuf );
  572. #else
  573. bwb_error( err_syntax );
  574. #endif
  575. return NULL;
  576. }
  577. /***************************************************************
  578. FUNCTION: is_endif()
  579. DESCRIPTION: This C function attempts to determine if
  580. a given line contains an END IF statement.
  581. ***************************************************************/
  582. #if ANSI_C
  583. static int
  584. is_endif( struct bwb_line *l )
  585. #else
  586. static int
  587. is_endif( l )
  588. struct bwb_line *l;
  589. #endif
  590. {
  591. int position;
  592. char tbuf[ MAXVARNAMESIZE + 1];
  593. if ( bwb_cmdtable[ l->cmdnum ].vector != bwb_xend )
  594. {
  595. return FALSE;
  596. }
  597. position = l->startpos;
  598. adv_ws( l->buffer, &position );
  599. adv_element( l->buffer, &position, tbuf );
  600. bwb_strtoupper( tbuf );
  601. if ( strcmp( tbuf, "IF" ) == 0 )
  602. {
  603. return TRUE;
  604. }
  605. return FALSE;
  606. }
  607. /***************************************************************
  608. FUNCTION: bwb_select()
  609. DESCRIPTION: This C function handles the BASIC SELECT
  610. statement.
  611. SYNTAX: SELECT CASE expression
  612. ***************************************************************/
  613. #if ANSI_C
  614. struct bwb_line *
  615. bwb_select( struct bwb_line *l )
  616. #else
  617. struct bwb_line *
  618. bwb_select( l )
  619. struct bwb_line *l;
  620. #endif
  621. {
  622. char tbuf[ MAXSTRINGSIZE + 1 ];
  623. struct exp_ese *e;
  624. #if INTENSIVE_DEBUG
  625. sprintf( bwb_ebuf, "in bwb_select(): entered function" );
  626. bwb_debug( bwb_ebuf );
  627. #endif
  628. /* first element should be "CASE" */
  629. adv_element( l->buffer, &( l->position ), tbuf );
  630. bwb_strtoupper( tbuf );
  631. if ( strcmp( tbuf, "CASE" ) != 0 )
  632. {
  633. #if PROG_ERRORS
  634. sprintf( bwb_ebuf, "SELECT without CASE" );
  635. bwb_error( bwb_ebuf );
  636. #else
  637. bwb_error( err_syntax );
  638. return bwb_zline( l );
  639. #endif
  640. }
  641. /* increment the level and set to EXEC_SELFALSE */
  642. bwb_incexec();
  643. CURTASK excs[ CURTASK exsc ].code = EXEC_SELFALSE;
  644. /* evaluate the expression at this level */
  645. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  646. #if OLDWAY
  647. memcpy( &( CURTASK excs[ CURTASK exsc ].expression ), e,
  648. sizeof( struct exp_ese ) );
  649. #endif
  650. if ( e->type == STRING )
  651. {
  652. CURTASK excs[ CURTASK exsc ].expression.type = STRING;
  653. str_btob( &( CURTASK excs[ CURTASK exsc ].expression.sval ),
  654. &( e->sval ) );
  655. }
  656. else
  657. {
  658. CURTASK excs[ CURTASK exsc ].expression.type = NUMBER;
  659. CURTASK excs[ CURTASK exsc ].expression.nval
  660. = exp_getnval( e );
  661. }
  662. /* return */
  663. #if MULTISEG_LINES
  664. adv_eos( l->buffer, &( l->position ));
  665. #endif
  666. return bwb_zline( l );
  667. }
  668. /***************************************************************
  669. FUNCTION: bwb_case()
  670. DESCRIPTION: This C function handles the BASIC CASE
  671. statement.
  672. SYNTAX: CASE constant | IF partial-expression | ELSE
  673. ***************************************************************/
  674. #if ANSI_C
  675. struct bwb_line *
  676. bwb_case( struct bwb_line *l )
  677. #else
  678. struct bwb_line *
  679. bwb_case( l )
  680. struct bwb_line *l;
  681. #endif
  682. {
  683. char tbuf[ MAXSTRINGSIZE + 1 ];
  684. int oldpos;
  685. struct exp_ese minvalue;
  686. struct exp_ese *maxval, *minval;
  687. struct bwb_line *retline;
  688. char cbuf1[ MAXSTRINGSIZE + 1 ];
  689. char cbuf2[ MAXSTRINGSIZE + 1 ];
  690. #if INTENSIVE_DEBUG
  691. sprintf( bwb_ebuf, "in bwb_case(): entered function" );
  692. bwb_debug( bwb_ebuf );
  693. #endif
  694. /* if code is EXEC_SELTRUE, then we should jump to the end */
  695. if ( CURTASK excs[ CURTASK exsc ].code == EXEC_SELTRUE )
  696. {
  697. #if INTENSIVE_DEBUG
  698. sprintf( bwb_ebuf, "in bwb_case(): exit EXEC_SELTRUE" );
  699. bwb_debug( bwb_ebuf );
  700. #endif
  701. retline = find_endselect( l );
  702. retline->position = 0;
  703. return retline;
  704. }
  705. /* read first element */
  706. oldpos = l->position;
  707. adv_element( l->buffer, &( l->position ), tbuf );
  708. bwb_strtoupper( tbuf );
  709. /* check for CASE IF */
  710. if ( strcmp( tbuf, CMD_IF ) == 0 )
  711. {
  712. return bwb_caseif( l );
  713. }
  714. /* check for CASE ELSE: if true, simply proceed to the next line,
  715. because other options should have been detected by now */
  716. else if ( strcmp( tbuf, CMD_ELSE ) == 0 )
  717. {
  718. #if INTENSIVE_DEBUG
  719. sprintf( bwb_ebuf, "in bwb_case(): execute CASE ELSE" );
  720. bwb_debug( bwb_ebuf );
  721. #endif
  722. return bwb_zline( l );
  723. }
  724. /* neither CASE ELSE nor CASE IF; presume constant here for min value */
  725. l->position = oldpos;
  726. minval = bwb_exp( l->buffer, FALSE, &( l->position ));
  727. memcpy( &minvalue, minval, sizeof( struct exp_ese ) );
  728. maxval = minval = &minvalue;
  729. /* check for string value */
  730. if ( minvalue.type == STRING )
  731. {
  732. str_btoc( cbuf1, &( CURTASK excs[ CURTASK exsc ].expression.sval ) );
  733. str_btoc( cbuf2, &( minvalue.sval ) );
  734. #if INTENSIVE_DEBUG
  735. sprintf( bwb_ebuf, "in bwb_case(): compare strings <%s> and <%s>",
  736. cbuf1, cbuf2 );
  737. bwb_debug( bwb_ebuf );
  738. #endif
  739. if ( strncmp( cbuf1, cbuf2, MAXSTRINGSIZE ) == 0 )
  740. {
  741. #if INTENSIVE_DEBUG
  742. sprintf( bwb_ebuf, "in bwb_case(): string comparison returns TRUE" );
  743. bwb_debug( bwb_ebuf );
  744. #endif
  745. CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;
  746. #if MULTISEG_LINES
  747. adv_eos( l->buffer, &( l->position ));
  748. #endif
  749. return bwb_zline( l );
  750. }
  751. else
  752. {
  753. #if INTENSIVE_DEBUG
  754. sprintf( bwb_ebuf, "in bwb_case(): string comparison returns FALSE" );
  755. bwb_debug( bwb_ebuf );
  756. #endif
  757. retline = find_case( l );
  758. retline->position = 0;
  759. return retline;
  760. }
  761. }
  762. /* not a string; advance */
  763. adv_ws( l->buffer, &( l->position ));
  764. /* check for TO */
  765. if ( is_eol( l->buffer, &( l->position )) != TRUE )
  766. {
  767. /* find the TO statement */
  768. adv_element( l->buffer, &( l->position ), tbuf );
  769. bwb_strtoupper( tbuf );
  770. if ( strcmp( tbuf, CMD_TO ) != 0 )
  771. {
  772. #if PROG_ERRORS
  773. sprintf( bwb_ebuf, "CASE has inexplicable code following expression" );
  774. bwb_error( bwb_ebuf );
  775. #else
  776. bwb_error( err_syntax );
  777. #if MULTISEG_LINES
  778. adv_eos( l->buffer, &( l->position ));
  779. #endif
  780. return bwb_zline( l );
  781. #endif
  782. }
  783. /* now evaluate the MAX expression */
  784. maxval = bwb_exp( l->buffer, FALSE, &( l->position ));
  785. }
  786. /* evaluate the expression */
  787. if ( case_eval( &( CURTASK excs[ CURTASK exsc ].expression ),
  788. minval, maxval ) == TRUE )
  789. {
  790. #if INTENSIVE_DEBUG
  791. sprintf( bwb_ebuf, "in bwb_case(): evaluation returns TRUE" );
  792. bwb_debug( bwb_ebuf );
  793. #endif
  794. CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;
  795. #if MULTISEG_LINES
  796. adv_eos( l->buffer, &( l->position ));
  797. #endif
  798. return bwb_zline( l );
  799. }
  800. /* evaluation returns a FALSE value; find next CASE or END SELECT statement */
  801. else
  802. {
  803. #if INTENSIVE_DEBUGb
  804. sprintf( bwb_ebuf, "in bwb_case(): evaluation returns FALSE" );
  805. bwb_debug( bwb_ebuf );
  806. #endif
  807. retline = find_case( l );
  808. retline->position = 0;
  809. return retline;
  810. }
  811. }
  812. /***************************************************************
  813. FUNCTION: bwb_caseif()
  814. DESCRIPTION: This C function handles the BASIC CASE IF
  815. statement.
  816. ***************************************************************/
  817. #if ANSI_C
  818. static struct bwb_line *
  819. bwb_caseif( struct bwb_line *l )
  820. #else
  821. static struct bwb_line *
  822. bwb_caseif( l )
  823. struct bwb_line *l;
  824. #endif
  825. {
  826. char tbuf[ MAXSTRINGSIZE + 1 ];
  827. int position;
  828. struct exp_ese *r;
  829. struct bwb_line *retline;
  830. if ( CURTASK excs[ CURTASK exsc ].expression.type == NUMBER )
  831. {
  832. sprintf( tbuf, "%f %s",
  833. (float) CURTASK excs[ CURTASK exsc ].expression.nval,
  834. &( l->buffer[ l->position ] ) );
  835. }
  836. else
  837. {
  838. bwb_error( err_mismatch );
  839. #if MULTISEG_LINES
  840. adv_eos( l->buffer, &( l->position ));
  841. #endif
  842. return bwb_zline( l );
  843. }
  844. position = 0;
  845. r = bwb_exp( tbuf, FALSE, &position );
  846. if ( r->nval == (bnumber) TRUE )
  847. {
  848. CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;
  849. #if MULTISEG_LINES
  850. adv_eos( l->buffer, &( l->position ));
  851. #endif
  852. return bwb_zline( l );
  853. }
  854. else
  855. {
  856. retline = find_case( l );
  857. retline->position = 0;
  858. return retline;
  859. }
  860. }
  861. /***************************************************************
  862. FUNCTION: case_eval()
  863. DESCRIPTION: This function evaluates a case statement
  864. by comparing minimum and maximum values
  865. with a set expression. It returns either
  866. TRUE or FALSE
  867. ***************************************************************/
  868. #if ANSI_C
  869. static int
  870. case_eval( struct exp_ese *expression, struct exp_ese *minval,
  871. struct exp_ese *maxval )
  872. #else
  873. static int
  874. case_eval( expression, minval, maxval )
  875. struct exp_ese *expression;
  876. struct exp_ese *minval;
  877. struct exp_ese *maxval;
  878. #endif
  879. {
  880. /* string value */
  881. if ( expression->type == STRING )
  882. {
  883. bwb_error( err_mismatch );
  884. return FALSE;
  885. }
  886. /* numerical value */
  887. #if INTENSIVE_DEBUG
  888. sprintf( bwb_ebuf, "in case_eval(): n <%f> min <%f> max <%f>",
  889. (float) expression->nval,
  890. (float) minval->nval,
  891. (float) maxval->nval );
  892. bwb_debug( bwb_ebuf );
  893. #endif
  894. if ( ( expression->nval >= minval->nval )
  895. && ( expression->nval <= maxval->nval ))
  896. {
  897. return TRUE;
  898. }
  899. return FALSE;
  900. }
  901. /***************************************************************
  902. FUNCTION: find_case()
  903. DESCRIPTION: This function searches for a line containing
  904. a CASE statement corresponding to a previous
  905. SELECT CASE statement.
  906. ***************************************************************/
  907. #if ANSI_C
  908. static struct bwb_line *
  909. find_case( struct bwb_line *l )
  910. #else
  911. static struct bwb_line *
  912. find_case( l )
  913. struct bwb_line *l;
  914. #endif
  915. {
  916. struct bwb_line *current;
  917. register int c_level;
  918. int position;
  919. c_level = 1;
  920. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  921. {
  922. position = 0;
  923. if ( current->marked != TRUE )
  924. {
  925. line_start( current->buffer, &position, &( current->lnpos ),
  926. &( current->lnum ),
  927. &( current->cmdpos ),
  928. &( current->cmdnum ),
  929. &( current->startpos ) );
  930. }
  931. current->position = current->startpos;
  932. if ( current->cmdnum > -1 )
  933. {
  934. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_select )
  935. {
  936. ++c_level;
  937. #if INTENSIVE_DEBUG
  938. sprintf( bwb_ebuf, "in find_case(): found SELECT at line %d, level %d",
  939. current->number, c_level );
  940. bwb_debug( bwb_ebuf );
  941. #endif
  942. }
  943. else if ( is_endselect( current ) == TRUE )
  944. {
  945. --c_level;
  946. #if INTENSIVE_DEBUG
  947. sprintf( bwb_ebuf, "in find_endif(): found END SELECT at line %d, level %d",
  948. current->number, c_level );
  949. bwb_debug( bwb_ebuf );
  950. #endif
  951. if ( c_level == 0 )
  952. {
  953. return current;
  954. }
  955. }
  956. else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_case )
  957. {
  958. --c_level;
  959. #if INTENSIVE_DEBUG
  960. sprintf( bwb_ebuf, "in find_case(): found CASE at line %d, level %d",
  961. current->number, c_level );
  962. bwb_debug( bwb_ebuf );
  963. #endif
  964. if ( c_level == 0 )
  965. {
  966. return current;
  967. }
  968. }
  969. }
  970. }
  971. #if PROG_ERRORS
  972. sprintf( bwb_ebuf, "SELECT without CASE" );
  973. bwb_error( bwb_ebuf );
  974. #else
  975. bwb_error( err_syntax );
  976. #endif
  977. return NULL;
  978. }
  979. /***************************************************************
  980. FUNCTION: find_case()
  981. DESCRIPTION: This function searches for a line containing
  982. an END SELECT statement corresponding to a previous
  983. SELECT CASE statement.
  984. ***************************************************************/
  985. #if ANSI_C
  986. static struct bwb_line *
  987. find_endselect( struct bwb_line *l )
  988. #else
  989. static struct bwb_line *
  990. find_endselect( l )
  991. struct bwb_line *l;
  992. #endif
  993. {
  994. struct bwb_line *current;
  995. register int c_level;
  996. int position;
  997. c_level = 1;
  998. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  999. {
  1000. position = 0;
  1001. if ( current->marked != TRUE )
  1002. {
  1003. line_start( current->buffer, &position, &( current->lnpos ),
  1004. &( current->lnum ),
  1005. &( current->cmdpos ),
  1006. &( current->cmdnum ),
  1007. &( current->startpos ) );
  1008. }
  1009. current->position = current->startpos;
  1010. if ( current->cmdnum > -1 )
  1011. {
  1012. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_select )
  1013. {
  1014. ++c_level;
  1015. #if INTENSIVE_DEBUG
  1016. sprintf( bwb_ebuf, "in find_case(): found SELECT at line %d, level %d",
  1017. current->number, c_level );
  1018. bwb_debug( bwb_ebuf );
  1019. #endif
  1020. }
  1021. else if ( is_endselect( current ) == TRUE )
  1022. {
  1023. --c_level;
  1024. #if INTENSIVE_DEBUG
  1025. sprintf( bwb_ebuf, "in find_endif(): found END SELECT at line %d, level %d",
  1026. current->number, c_level );
  1027. bwb_debug( bwb_ebuf );
  1028. #endif
  1029. if ( c_level == 0 )
  1030. {
  1031. return current;
  1032. }
  1033. }
  1034. }
  1035. }
  1036. #if PROG_ERRORS
  1037. sprintf( bwb_ebuf, "SELECT without END SELECT" );
  1038. bwb_error( bwb_ebuf );
  1039. #else
  1040. bwb_error( err_syntax );
  1041. #endif
  1042. return NULL;
  1043. }
  1044. /***************************************************************
  1045. FUNCTION: is_endselect()
  1046. DESCRIPTION: This C function attempts to determine if
  1047. a given line contains an END SELECT statement.
  1048. ***************************************************************/
  1049. #if ANSI_C
  1050. static int
  1051. is_endselect( struct bwb_line *l )
  1052. #else
  1053. static int
  1054. is_endselect( l )
  1055. struct bwb_line *l;
  1056. #endif
  1057. {
  1058. int position;
  1059. char tbuf[ MAXVARNAMESIZE + 1];
  1060. if ( bwb_cmdtable[ l->cmdnum ].vector != bwb_xend )
  1061. {
  1062. return FALSE;
  1063. }
  1064. position = l->startpos;
  1065. adv_ws( l->buffer, &position );
  1066. adv_element( l->buffer, &position, tbuf );
  1067. bwb_strtoupper( tbuf );
  1068. if ( strcmp( tbuf, "SELECT" ) == 0 )
  1069. {
  1070. return TRUE;
  1071. }
  1072. return FALSE;
  1073. }
  1074. /***************************************************************
  1075. FUNCTION: bwb_endselect()
  1076. DESCRIPTION: This function handles the BASIC END
  1077. SELECT statement.
  1078. SYNTAX: END SELECT
  1079. ***************************************************************/
  1080. #if ANSI_C
  1081. struct bwb_line *
  1082. bwb_endselect( struct bwb_line *l )
  1083. #else
  1084. struct bwb_line *
  1085. bwb_endselect( l )
  1086. struct bwb_line *l;
  1087. #endif
  1088. {
  1089. #if INTENSIVE_DEBUG
  1090. sprintf( bwb_ebuf, "in bwb_endselect(): entered function" );
  1091. bwb_debug( bwb_ebuf );
  1092. #endif
  1093. if ( ( CURTASK excs[ CURTASK exsc ].code != EXEC_SELTRUE )
  1094. && ( CURTASK excs[ CURTASK exsc ].code != EXEC_SELFALSE ))
  1095. {
  1096. #if PROG_ERRORS
  1097. sprintf( bwb_ebuf, "in bwb_endselect(): END SELECT without SELECT" );
  1098. bwb_error( bwb_ebuf );
  1099. #else
  1100. bwb_error( err_syntax );
  1101. #endif
  1102. }
  1103. bwb_decexec();
  1104. #if MULTISEG_LINES
  1105. adv_eos( l->buffer, &( l->position ));
  1106. #endif
  1107. return bwb_zline( l );
  1108. }
  1109. #endif /* STRUCT_CMDS */
  1110. #if COMMON_CMDS || STRUCT_CMDS
  1111. /*** WHILE-WEND ***/
  1112. /***************************************************************
  1113. FUNCTION: bwb_while()
  1114. DESCRIPTION: This function handles the BASIC WHILE
  1115. statement and also the ANSI DO WHILE
  1116. statement.
  1117. SYNTAX: WHILE expression
  1118. DO WHILE expression
  1119. ***************************************************************/
  1120. #if ANSI_C
  1121. struct bwb_line *
  1122. bwb_while( struct bwb_line *l )
  1123. #else
  1124. struct bwb_line *
  1125. bwb_while( l )
  1126. struct bwb_line *l;
  1127. #endif
  1128. {
  1129. struct exp_ese *e;
  1130. struct bwb_line *r;
  1131. /* if this is the first time at this WHILE statement, note it */
  1132. if ( CURTASK excs[ CURTASK exsc ].while_line != l )
  1133. {
  1134. bwb_incexec();
  1135. CURTASK excs[ CURTASK exsc ].while_line = l;
  1136. /* find the WEND statement (or LOOP statement) */
  1137. #if STRUCT_CMDS
  1138. if ( l->cmdnum == getcmdnum( CMD_DO ))
  1139. {
  1140. CURTASK excs[ CURTASK exsc ].wend_line = find_loop( l );
  1141. }
  1142. else
  1143. {
  1144. CURTASK excs[ CURTASK exsc ].wend_line = find_wend( l );
  1145. }
  1146. #else
  1147. CURTASK excs[ CURTASK exsc ].wend_line = find_wend( l );
  1148. #endif
  1149. if ( CURTASK excs[ CURTASK exsc ].wend_line == NULL )
  1150. {
  1151. return bwb_zline( l );
  1152. }
  1153. #if INTENSIVE_DEBUG
  1154. sprintf( bwb_ebuf, "in bwb_while(): initialize WHILE loop, line <%d>",
  1155. l->number );
  1156. bwb_debug( bwb_ebuf );
  1157. #endif
  1158. }
  1159. #if INTENSIVE_DEBUG
  1160. else
  1161. {
  1162. sprintf( bwb_ebuf, "in bwb_while(): return to WHILE loop, line <%d>",
  1163. l->number );
  1164. bwb_debug( bwb_ebuf );
  1165. }
  1166. #endif
  1167. /*----------------------------------------------------*/
  1168. /* Expression evaluation was at the top of bwb_while, */
  1169. /* and the init portion was performed only if TRUE. */
  1170. /* The init routine should be performed regardless of */
  1171. /* expression value, else a segmentation fault can */
  1172. /* occur! (JBV) */
  1173. /*----------------------------------------------------*/
  1174. /* call bwb_exp() to interpret the expression */
  1175. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  1176. if ( (int) exp_getnval( e ) != FALSE ) /* Was == TRUE (JBV 10/1996) */
  1177. {
  1178. bwb_setexec( l, l->position, EXEC_WHILE );
  1179. return bwb_zline( l );
  1180. }
  1181. else
  1182. {
  1183. CURTASK excs[ CURTASK exsc ].while_line = NULL;
  1184. r = CURTASK excs[ CURTASK exsc ].wend_line;
  1185. bwb_setexec( r, 0, CURTASK excs[ CURTASK exsc - 1 ].code );
  1186. r->position = 0;
  1187. bwb_decexec();
  1188. return r;
  1189. }
  1190. }
  1191. /***************************************************************
  1192. FUNCTION: bwb_wend()
  1193. DESCRIPTION: This function handles the BASIC WEND
  1194. statement and the LOOP statement ending
  1195. a DO WHILE loop.
  1196. SYNTAX: WEND
  1197. LOOP
  1198. ***************************************************************/
  1199. #if ANSI_C
  1200. struct bwb_line *
  1201. bwb_wend( struct bwb_line *l )
  1202. #else
  1203. struct bwb_line *
  1204. bwb_wend( l )
  1205. struct bwb_line *l;
  1206. #endif
  1207. {
  1208. /* check integrity of WHILE loop */
  1209. if ( CURTASK excs[ CURTASK exsc ].code != EXEC_WHILE )
  1210. {
  1211. #if PROG_ERRORS
  1212. sprintf( bwb_ebuf, "in bwb_wend(): exec stack code != EXEC_WHILE" );
  1213. bwb_error( bwb_ebuf );
  1214. #else
  1215. bwb_error( err_syntax );
  1216. #endif
  1217. }
  1218. if ( CURTASK excs[ CURTASK exsc ].while_line == NULL )
  1219. {
  1220. #if PROG_ERRORS
  1221. sprintf( bwb_ebuf, "in bwb_wend(): exec stack while_line == NULL" );
  1222. bwb_error( bwb_ebuf );
  1223. #else
  1224. bwb_error( err_syntax );
  1225. #endif
  1226. }
  1227. /* reset to the top of the current WHILE loop */
  1228. #if INTENSIVE_DEBUG
  1229. sprintf( bwb_ebuf, "in bwb_wend() return to line <%d>",
  1230. CURTASK excs[ CURTASK exsc ].while_line->number );
  1231. bwb_debug( bwb_ebuf );
  1232. #endif
  1233. CURTASK excs[ CURTASK exsc ].while_line->position = 0;
  1234. bwb_setexec( CURTASK excs[ CURTASK exsc ].while_line, 0, EXEC_WHILE );
  1235. return CURTASK excs[ CURTASK exsc ].while_line;
  1236. }
  1237. /***************************************************************
  1238. FUNCTION: find_wend()
  1239. DESCRIPTION: This function searches for a line containing
  1240. a WEND statement corresponding to a previous
  1241. WHILE statement.
  1242. ***************************************************************/
  1243. #if ANSI_C
  1244. static struct bwb_line *
  1245. find_wend( struct bwb_line *l )
  1246. #else
  1247. static struct bwb_line *
  1248. find_wend( l )
  1249. struct bwb_line *l;
  1250. #endif
  1251. {
  1252. struct bwb_line *current;
  1253. register int w_level;
  1254. int position;
  1255. w_level = 1;
  1256. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  1257. {
  1258. position = 0;
  1259. if ( current->marked != TRUE )
  1260. {
  1261. line_start( current->buffer, &position, &( current->lnpos ),
  1262. &( current->lnum ),
  1263. &( current->cmdpos ),
  1264. &( current->cmdnum ),
  1265. &( current->startpos ) );
  1266. }
  1267. current->position = current->startpos;
  1268. if ( current->cmdnum > -1 )
  1269. {
  1270. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_while )
  1271. {
  1272. ++w_level;
  1273. #if INTENSIVE_DEBUG
  1274. sprintf( bwb_ebuf, "in find_wend(): found WHILE at line %d, level %d",
  1275. current->number, w_level );
  1276. bwb_debug( bwb_ebuf );
  1277. #endif
  1278. }
  1279. else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_wend )
  1280. {
  1281. --w_level;
  1282. #if INTENSIVE_DEBUG
  1283. sprintf( bwb_ebuf, "in find_wend(): found WEND at line %d, level %d",
  1284. current->number, w_level );
  1285. bwb_debug( bwb_ebuf );
  1286. #endif
  1287. if ( w_level == 0 )
  1288. {
  1289. return current->next;
  1290. }
  1291. }
  1292. }
  1293. }
  1294. #if PROG_ERRORS
  1295. sprintf( bwb_ebuf, "in find_wend(): WHILE without WEND" );
  1296. bwb_error( bwb_ebuf );
  1297. #else
  1298. bwb_error( err_syntax );
  1299. #endif
  1300. return NULL;
  1301. }
  1302. #if STRUCT_CMDS
  1303. /***************************************************************
  1304. FUNCTION: find_loop()
  1305. DESCRIPTION: This function searches for a line containing
  1306. a LOOP statement corresponding to a previous
  1307. DO statement.
  1308. ***************************************************************/
  1309. #if ANSI_C
  1310. extern struct bwb_line *
  1311. find_loop( struct bwb_line *l )
  1312. #else
  1313. extern struct bwb_line *
  1314. find_loop( l )
  1315. struct bwb_line *l;
  1316. #endif
  1317. {
  1318. struct bwb_line *current;
  1319. register int w_level;
  1320. int position;
  1321. w_level = 1;
  1322. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  1323. {
  1324. position = 0;
  1325. if ( current->marked != TRUE )
  1326. {
  1327. line_start( current->buffer, &position, &( current->lnpos ),
  1328. &( current->lnum ),
  1329. &( current->cmdpos ),
  1330. &( current->cmdnum ),
  1331. &( current->startpos ) );
  1332. }
  1333. current->position = current->startpos;
  1334. if ( current->cmdnum > -1 )
  1335. {
  1336. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_do )
  1337. {
  1338. ++w_level;
  1339. #if INTENSIVE_DEBUG
  1340. sprintf( bwb_ebuf, "in find_loop(): found DO at line %d, level %d",
  1341. current->number, w_level );
  1342. bwb_debug( bwb_ebuf );
  1343. #endif
  1344. }
  1345. else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_loop )
  1346. {
  1347. --w_level;
  1348. #if INTENSIVE_DEBUG
  1349. sprintf( bwb_ebuf, "in fnd_loop(): found LOOP at line %d, level %d",
  1350. current->number, w_level );
  1351. bwb_debug( bwb_ebuf );
  1352. #endif
  1353. if ( w_level == 0 )
  1354. {
  1355. return current->next;
  1356. }
  1357. }
  1358. }
  1359. }
  1360. #if PROG_ERRORS
  1361. sprintf( bwb_ebuf, "in find_loop(): DO without LOOP" );
  1362. bwb_error( bwb_ebuf );
  1363. #else
  1364. bwb_error( err_syntax );
  1365. #endif
  1366. return NULL;
  1367. }
  1368. #endif /* STRUCT_CMDS */
  1369. #endif /* COMMON_CMDS || STRUCT_CMDS */
  1370. /*** FOR-NEXT ***/
  1371. /***************************************************************
  1372. FUNCTION: bwb_for()
  1373. DESCRIPTION: This function handles the BASIC FOR
  1374. statement.
  1375. SYNTAX: FOR counter = start TO finish [STEP increment]
  1376. ***************************************************************/
  1377. #if ANSI_C
  1378. struct bwb_line *
  1379. bwb_for( struct bwb_line *l )
  1380. #else
  1381. struct bwb_line *
  1382. bwb_for( l )
  1383. struct bwb_line *l;
  1384. #endif
  1385. {
  1386. register int n;
  1387. int e, loop;
  1388. int to, step, p;
  1389. int for_step, for_target;
  1390. struct exp_ese *exp;
  1391. struct bwb_variable *v;
  1392. char tbuf[ MAXSTRINGSIZE + 1 ];
  1393. /* get the variable name */
  1394. exp_getvfname( &( l->buffer[ l->position ] ), tbuf );
  1395. l->position += strlen( tbuf );
  1396. v = var_find( tbuf );
  1397. #if INTENSIVE_DEBUG
  1398. sprintf( bwb_ebuf, "in bwb_for(): variable name <%s>.", v->name );
  1399. bwb_debug( bwb_ebuf );
  1400. #endif
  1401. /*--------------------------------------------------------------*/
  1402. /* Make sure we are in the right FOR-NEXT level! */
  1403. /* If we aren't (which could happen for legit reasons), fix the */
  1404. /* exec stack. */
  1405. /* JBV, 9/20/95 */
  1406. /*--------------------------------------------------------------*/
  1407. if (v == CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec();
  1408. /* at this point one should find an equals sign ('=') */
  1409. adv_ws( l->buffer, &( l->position ) );
  1410. if ( l->buffer[ l->position ] != '=' )
  1411. {
  1412. #if PROG_ERRORS
  1413. sprintf( bwb_ebuf, "in bwb_for(): failed to find equals sign, buf <%s>",
  1414. &( l->buffer[ l->position ] ) );
  1415. bwb_error( bwb_ebuf );
  1416. #else
  1417. bwb_error( err_syntax );
  1418. #endif
  1419. return bwb_zline( l );
  1420. }
  1421. else
  1422. {
  1423. ++( l->position );
  1424. }
  1425. /* Find the TO and STEP statements */
  1426. cnd_tostep( l->buffer, l->position, &to, &step );
  1427. /* if there is no TO statement, then an error has ocurred */
  1428. if ( to < 1 )
  1429. {
  1430. #if PROG_ERRORS
  1431. sprintf( bwb_ebuf, "FOR statement without TO" );
  1432. bwb_error( bwb_ebuf );
  1433. #else
  1434. bwb_error( err_syntax );
  1435. #endif
  1436. return bwb_zline( l );
  1437. }
  1438. /* copy initial value to buffer and evaluate it */
  1439. tbuf[ 0 ] = '\0';
  1440. p = 0;
  1441. for ( n = l->position; n < to; ++n )
  1442. {
  1443. tbuf[ p ] = l->buffer[ n ];
  1444. ++p;
  1445. ++l->position;
  1446. tbuf[ p ] = '\0';
  1447. }
  1448. #if INTENSIVE_DEBUG
  1449. sprintf( bwb_ebuf, "in bwb_for(): initial value string <%s>",
  1450. tbuf );
  1451. bwb_debug( bwb_ebuf );
  1452. #endif
  1453. p = 0;
  1454. exp = bwb_exp( tbuf, FALSE, &p );
  1455. var_setnval( v, exp_getnval( exp ) );
  1456. #if INTENSIVE_DEBUG
  1457. sprintf( bwb_ebuf, "in bwb_for(): initial value <%d> pos <%d>",
  1458. exp_getnval( exp ), l->position );
  1459. bwb_debug( bwb_ebuf );
  1460. #endif
  1461. /* copy target value to small buffer and evaluate it */
  1462. tbuf[ 0 ] = '\0';
  1463. p = 0;
  1464. l->position = to + 2;
  1465. if ( step < 1 )
  1466. {
  1467. e = strlen( l->buffer );
  1468. }
  1469. else
  1470. {
  1471. e = step - 1;
  1472. }
  1473. loop = TRUE;
  1474. n = l->position;
  1475. while( loop == TRUE )
  1476. {
  1477. tbuf[ p ] = l->buffer[ n ];
  1478. ++p;
  1479. ++l->position;
  1480. tbuf[ p ] = '\0';
  1481. if ( n >= e )
  1482. {
  1483. loop = FALSE;
  1484. }
  1485. ++n;
  1486. if ( l->buffer[ n ] == ':' )
  1487. {
  1488. loop = FALSE;
  1489. }
  1490. }
  1491. #if INTENSIVE_DEBUG
  1492. sprintf( bwb_ebuf, "in bwb_for(): target value string <%s>",
  1493. tbuf );
  1494. bwb_debug( bwb_ebuf );
  1495. #endif
  1496. p = 0;
  1497. exp = bwb_exp( tbuf, FALSE, &p );
  1498. for_target = (int) exp_getnval( exp );
  1499. #if INTENSIVE_DEBUG
  1500. sprintf( bwb_ebuf, "in bwb_for(): target value <%d> pos <%d>",
  1501. exp_getnval( exp ), l->position );
  1502. bwb_debug( bwb_ebuf );
  1503. #endif
  1504. /* If there is a STEP statement, copy it to a buffer
  1505. and evaluate it */
  1506. if ( step > 1 )
  1507. {
  1508. tbuf[ 0 ] = '\0';
  1509. p = 0;
  1510. l->position = step + 4;
  1511. for ( n = l->position; n < (int) strlen( l->buffer ); ++n )
  1512. {
  1513. tbuf[ p ] = l->buffer[ n ];
  1514. ++p;
  1515. ++l->position;
  1516. tbuf[ p ] = '\0';
  1517. }
  1518. #if INTENSIVE_DEBUG
  1519. sprintf( bwb_ebuf, "in bwb_for(): step value string <%s>",
  1520. tbuf );
  1521. bwb_debug( bwb_ebuf );
  1522. #endif
  1523. p = 0;
  1524. exp = bwb_exp( tbuf, FALSE, &p );
  1525. for_step = (int) exp_getnval( exp );
  1526. }
  1527. else
  1528. {
  1529. for_step = 1;
  1530. }
  1531. #if INTENSIVE_DEBUG
  1532. sprintf( bwb_ebuf, "in bwb_for(): step value <%d>",
  1533. for_step );
  1534. bwb_debug( bwb_ebuf );
  1535. #endif
  1536. /* set position in current line and increment EXEC counter */
  1537. /* bwb_setexec( l, l->position, EXEC_NORM ); */ /* WRONG */
  1538. bwb_incexec();
  1539. CURTASK excs[ CURTASK exsc ].local_variable = v;
  1540. CURTASK excs[ CURTASK exsc ].for_step = for_step;
  1541. CURTASK excs[ CURTASK exsc ].for_target = for_target;
  1542. /* set exit line to be used by EXIT FOR */
  1543. #if STRUCT_CMDS
  1544. CURTASK excs[ CURTASK exsc ].wend_line = find_next( l );
  1545. #endif
  1546. /* set top line and position to be used in multisegmented FOR-NEXT loop */
  1547. #if MULTISEG_LINES
  1548. CURTASK excs[ CURTASK exsc ].for_line = l;
  1549. CURTASK excs[ CURTASK exsc ].for_position = l->position;
  1550. #endif
  1551. #if INTENSIVE_DEBUG
  1552. sprintf( bwb_ebuf, "in bwb_for(): setting code to EXEC_FOR",
  1553. l->position );
  1554. bwb_debug( bwb_ebuf );
  1555. #endif
  1556. bwb_setexec( l, l->position, EXEC_FOR );
  1557. #if INTENSIVE_DEBUG
  1558. sprintf( bwb_ebuf, "in bwb_for(): ready to exit, position <%d>",
  1559. l->position );
  1560. bwb_debug( bwb_ebuf );
  1561. #endif
  1562. /* proceed with processing */
  1563. return bwb_zline( l );
  1564. }
  1565. /***************************************************************
  1566. FUNCTION: bwb_next()
  1567. DESCRIPTION: This function handles the BASIC NEXT
  1568. statement.
  1569. SYNTAX: NEXT counter
  1570. ***************************************************************/
  1571. #if ANSI_C
  1572. struct bwb_line *
  1573. bwb_next( struct bwb_line *l )
  1574. #else
  1575. struct bwb_line *
  1576. bwb_next( l )
  1577. struct bwb_line *l;
  1578. #endif
  1579. {
  1580. char tbuf[ MAXSTRINGSIZE + 1 ];
  1581. struct bwb_variable *v; /* Relocated from INTENSIVE_DEBUG (JBV) */
  1582. #if INTENSIVE_DEBUG
  1583. sprintf( bwb_ebuf, "in bwb_next(): entered function, cmdnum <%d> exsc level <%d> code <%d>",
  1584. l->cmdnum, CURTASK exsc, CURTASK excs[ CURTASK exsc ].code );
  1585. bwb_debug( bwb_ebuf );
  1586. #endif
  1587. /* Check the integrity of the FOR statement */
  1588. if ( CURTASK excs[ CURTASK exsc ].code != EXEC_FOR )
  1589. {
  1590. #if PROG_ERRORS
  1591. sprintf( bwb_ebuf, "in bwb_next(): NEXT without FOR; code is <%d> instead of <%d>",
  1592. CURTASK excs[ CURTASK exsc ].code, EXEC_FOR );
  1593. bwb_error( bwb_ebuf );
  1594. #else
  1595. bwb_error( err_syntax );
  1596. #endif
  1597. }
  1598. /* read the argument, if there is one */
  1599. /* Relocated from MULTISEG_LINES (JBV) */
  1600. exp_getvfname( &( l->buffer[ l->position ] ), tbuf );
  1601. if (strlen(tbuf) != 0)
  1602. {
  1603. /* Relocated from INTENSIVE_DEBUG (JBV) */
  1604. v = var_find( tbuf );
  1605. #if MULTISEG_LINES /* not currently needed otherwise */
  1606. l->position += strlen( tbuf );
  1607. #if INTENSIVE_DEBUG
  1608. sprintf( bwb_ebuf, "in bwb_next(): variable name detected <%s>.", v->name );
  1609. bwb_debug( bwb_ebuf );
  1610. #endif
  1611. #endif
  1612. /* decrement or increment the value */
  1613. /*--------------------------------------------------------------*/
  1614. /* Make sure we are in the right FOR-NEXT level! */
  1615. /* If we aren't (which could happen for legit reasons), fix the */
  1616. /* exec stack. */
  1617. /* JBV, 9/20/95 */
  1618. /*--------------------------------------------------------------*/
  1619. while (v != CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec();
  1620. }
  1621. var_setnval( CURTASK excs[ CURTASK exsc ].local_variable,
  1622. var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )
  1623. + (bnumber) CURTASK excs[ CURTASK exsc ].for_step );
  1624. /* check for completion of the loop */
  1625. if ( CURTASK excs[ CURTASK exsc ].for_step > 0 ) /* if step is positive */
  1626. {
  1627. if ( (int) var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )
  1628. > CURTASK excs[ CURTASK exsc ].for_target )
  1629. {
  1630. bwb_decexec();
  1631. #if MULTISEG_LINES
  1632. bwb_setexec( l, l->position, CURTASK excs[ CURTASK exsc ].code );
  1633. #else
  1634. bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );
  1635. #endif
  1636. #if INTENSIVE_DEBUG
  1637. sprintf( bwb_ebuf, "in bwb_next(): end of loop" );
  1638. bwb_debug( bwb_ebuf );
  1639. #endif
  1640. #ifdef OLD_WAY
  1641. l->next->position = 0;
  1642. return l->next;
  1643. #else
  1644. return bwb_zline( l );
  1645. #endif
  1646. }
  1647. }
  1648. else /* if step is negative */
  1649. {
  1650. if ( (int) var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )
  1651. < CURTASK excs[ CURTASK exsc ].for_target )
  1652. {
  1653. bwb_decexec();
  1654. bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );
  1655. #if INTENSIVE_DEBUG
  1656. sprintf( bwb_ebuf, "in bwb_next(): end of loop" );
  1657. bwb_debug( bwb_ebuf );
  1658. #endif
  1659. #ifdef OLD_WAY
  1660. l->next->position = 0;
  1661. return l->next;
  1662. #else
  1663. return bwb_zline( l );
  1664. #endif
  1665. }
  1666. }
  1667. /* Target not reached: return to the top of the FOR loop */
  1668. #if INTENSIVE_DEBUG
  1669. sprintf( bwb_ebuf, "in bwb_next(): resetting code to EXEC_FOR",
  1670. l->position );
  1671. bwb_debug( bwb_ebuf );
  1672. #endif
  1673. #if MULTISEG_LINES
  1674. CURTASK excs[ CURTASK exsc ].for_line->position
  1675. = CURTASK excs[ CURTASK exsc ].for_position;
  1676. bwb_setexec( CURTASK excs[ CURTASK exsc ].for_line,
  1677. CURTASK excs[ CURTASK exsc ].for_position, EXEC_FOR );
  1678. return CURTASK excs[ CURTASK exsc ].for_line; /* Added (JBV) */
  1679. #else
  1680. bwb_setexec( CURTASK excs[ CURTASK exsc - 1 ].line,
  1681. CURTASK excs[ CURTASK exsc - 1 ].position, EXEC_FOR );
  1682. return CURTASK excs[ CURTASK exsc - 1 ].line; /* Relocated (JBV) */
  1683. #endif
  1684. }
  1685. #if STRUCT_CMDS
  1686. /***************************************************************
  1687. FUNCTION: bwb_exitfor()
  1688. DESCRIPTION: This function handles the BASIC EXIT
  1689. FOR statement. This is a structured
  1690. programming command compatible with ANSI
  1691. BASIC. It is called from the bwb_exit()
  1692. subroutine.
  1693. SYNTAX: EXIT FOR
  1694. ***************************************************************/
  1695. #if ANSI_C
  1696. struct bwb_line *
  1697. bwb_exitfor( struct bwb_line *l )
  1698. #else
  1699. struct bwb_line *
  1700. bwb_exitfor( l )
  1701. struct bwb_line *l;
  1702. #endif
  1703. {
  1704. struct bwb_line *next_line;
  1705. int found;
  1706. register int level;
  1707. #if INTENSIVE_DEBUG
  1708. sprintf( bwb_ebuf, "in bwb_exitfor(): entered subroutine" );
  1709. bwb_debug( bwb_ebuf );
  1710. #endif
  1711. /* Check the integrity of the FOR statement */
  1712. found = FALSE;
  1713. level = CURTASK exsc;
  1714. do
  1715. {
  1716. if ( CURTASK excs[ level ].code == EXEC_FOR )
  1717. {
  1718. next_line = CURTASK excs[ CURTASK level ].wend_line;
  1719. found = TRUE;
  1720. }
  1721. else
  1722. {
  1723. --level;
  1724. }
  1725. }
  1726. while ( ( level >= 0 ) && ( found == FALSE ) );
  1727. if ( found != TRUE )
  1728. {
  1729. #if PROG_ERRORS
  1730. sprintf( bwb_ebuf, "in bwb_exitfor(): EXIT FOR without FOR" );
  1731. bwb_error( bwb_ebuf );
  1732. #else
  1733. bwb_error( err_syntax );
  1734. #endif
  1735. return bwb_zline( l );
  1736. }
  1737. #if INTENSIVE_DEBUG
  1738. sprintf( bwb_ebuf, "in bwb_exitfor(): level found is <%d>, current <%d>",
  1739. level, CURTASK exsc );
  1740. bwb_debug( bwb_ebuf );
  1741. #endif
  1742. /* decrement below the level of the NEXT statement */
  1743. while( CURTASK exsc >= level )
  1744. {
  1745. bwb_decexec();
  1746. }
  1747. /* set the next line in the exec stack */
  1748. next_line->position = 0;
  1749. /* bwb_setexec( next_line, 0, EXEC_NORM ); */ /* WRONG (JBV) */
  1750. bwb_setexec( next_line, 0, CURTASK excs[ CURTASK exsc ].code ); /* JBV */
  1751. return next_line;
  1752. }
  1753. /***************************************************************
  1754. FUNCTION: find_next()
  1755. DESCRIPTION: This function searches for a line containing
  1756. a NEXT statement corresponding to a previous
  1757. FOR statement.
  1758. ***************************************************************/
  1759. #if ANSI_C
  1760. static struct bwb_line *
  1761. find_next( struct bwb_line *l )
  1762. #else
  1763. static struct bwb_line *
  1764. find_next( l )
  1765. struct bwb_line *l;
  1766. #endif
  1767. {
  1768. struct bwb_line *current;
  1769. register int w_level;
  1770. int position;
  1771. w_level = 1;
  1772. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  1773. {
  1774. position = 0;
  1775. if ( current->marked != TRUE )
  1776. {
  1777. line_start( current->buffer, &position, &( current->lnpos ),
  1778. &( current->lnum ),
  1779. &( current->cmdpos ),
  1780. &( current->cmdnum ),
  1781. &( current->startpos ) );
  1782. }
  1783. current->position = current->startpos;
  1784. if ( current->cmdnum > -1 )
  1785. {
  1786. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_for )
  1787. {
  1788. ++w_level;
  1789. #if INTENSIVE_DEBUG
  1790. sprintf( bwb_ebuf, "in find_next(): found FOR at line %d, level %d",
  1791. current->number, w_level );
  1792. bwb_debug( bwb_ebuf );
  1793. #endif
  1794. }
  1795. else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_next )
  1796. {
  1797. --w_level;
  1798. #if INTENSIVE_DEBUG
  1799. sprintf( bwb_ebuf, "in find_next(): found NEXT at line %d, level %d",
  1800. current->number, w_level );
  1801. bwb_debug( bwb_ebuf );
  1802. #endif
  1803. if ( w_level == 0 )
  1804. {
  1805. #if INTENSIVE_DEBUG
  1806. sprintf( bwb_ebuf, "in find_next(): found returning line <%d>",
  1807. current->next->number );
  1808. bwb_debug( bwb_ebuf );
  1809. #endif
  1810. return current->next;
  1811. }
  1812. }
  1813. }
  1814. }
  1815. #if PROG_ERRORS
  1816. sprintf( bwb_ebuf, "FOR without NEXT" );
  1817. bwb_error( bwb_ebuf );
  1818. #else
  1819. bwb_error( err_syntax );
  1820. #endif
  1821. return NULL;
  1822. }
  1823. #endif /* STRUCT_CMDS for EXIT FOR */
  1824. /***************************************************************
  1825. FUNCTION: cnd_tostep()
  1826. DESCRIPTION: This function searches through the
  1827. <buffer> beginning at point <position>
  1828. and attempts to find positions of TO
  1829. and STEP statements.
  1830. ***************************************************************/
  1831. #if ANSI_C
  1832. static int
  1833. cnd_tostep( char *buffer, int position, int *to, int *step )
  1834. #else
  1835. static int
  1836. cnd_tostep( buffer, position, to, step )
  1837. char *buffer;
  1838. int position;
  1839. int *to;
  1840. int *step;
  1841. #endif
  1842. {
  1843. int loop, t_pos, b_pos, p_word;
  1844. char tbuf[ MAXSTRINGSIZE + 1 ];
  1845. /* set then and els to FALSE initially */
  1846. *to = *step = FALSE;
  1847. /* loop to find words */
  1848. p_word = b_pos = position;
  1849. t_pos = 0;
  1850. tbuf[ 0 ] = '\0';
  1851. loop = TRUE;
  1852. while ( loop == TRUE )
  1853. {
  1854. switch( buffer[ b_pos ] )
  1855. {
  1856. case '\0': /* end of string */
  1857. case ':': /* end of line segment */
  1858. return TRUE;
  1859. case ' ': /* whitespace = end of word */
  1860. case '\t':
  1861. #if INTENSIVE_DEBUG
  1862. sprintf( bwb_ebuf, "in cnd_tostep(): word is <%s>", tbuf );
  1863. bwb_debug( bwb_ebuf );
  1864. #endif
  1865. if ( strncmp( tbuf, CMD_TO, (size_t) strlen( CMD_TO ) ) == 0 )
  1866. {
  1867. #if INTENSIVE_DEBUG
  1868. sprintf( bwb_ebuf, "in cnd_tostep(): TO found at position <%d>.",
  1869. p_word );
  1870. bwb_debug( bwb_ebuf );
  1871. #endif
  1872. *to = p_word;
  1873. }
  1874. else if ( strncmp( tbuf, CMD_STEP, (size_t) strlen( CMD_STEP ) ) == 0 )
  1875. {
  1876. #if INTENSIVE_DEBUG
  1877. sprintf( bwb_ebuf, "in cnd_tostep(): STEP found at position <%d>.",
  1878. p_word );
  1879. bwb_debug( bwb_ebuf );
  1880. #endif
  1881. *step = p_word;
  1882. }
  1883. ++b_pos;
  1884. p_word = b_pos;
  1885. t_pos = 0;
  1886. tbuf[ 0 ] = '\0';
  1887. break;
  1888. default:
  1889. if ( islower( buffer[ b_pos ] ) != FALSE )
  1890. {
  1891. tbuf[ t_pos ] = (char) toupper( buffer[ b_pos ] );
  1892. }
  1893. else
  1894. {
  1895. tbuf[ t_pos ] = buffer[ b_pos ];
  1896. }
  1897. ++b_pos;
  1898. ++t_pos;
  1899. tbuf[ t_pos ] = '\0';
  1900. break;
  1901. }
  1902. }
  1903. return TRUE;
  1904. }
  1905. /***************************************************************
  1906. FUNCTION: var_setnval()
  1907. DESCRIPTION: This function sets the value of numerical
  1908. variable v to the value of i.
  1909. ***************************************************************/
  1910. #if ANSI_C
  1911. extern int
  1912. var_setnval( struct bwb_variable *v, bnumber i )
  1913. #else
  1914. int
  1915. var_setnval( v, i )
  1916. struct bwb_variable *v;
  1917. bnumber i;
  1918. #endif
  1919. {
  1920. switch( v->type )
  1921. {
  1922. case NUMBER:
  1923. * var_findnval( v, v->array_pos ) = i;
  1924. break;
  1925. default:
  1926. #if INTENSIVE_DEBUG
  1927. sprintf( bwb_ebuf, "in var_setnval(): variable <%s> is not a number",
  1928. v->name );
  1929. bwb_error( bwb_ebuf );
  1930. #else
  1931. bwb_error( err_mismatch );
  1932. #endif
  1933. }
  1934. /* successful assignment */
  1935. return TRUE;
  1936. }