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.
 
 
 
 
 
 

2465 lines
57 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 ) == TRUE )
  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. /* call bwb_exp() to interpret the expression */
  1132. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  1133. if ( (int) exp_getnval( e ) == TRUE )
  1134. {
  1135. /* if this is the first time at this WHILE statement, note it */
  1136. if ( CURTASK excs[ CURTASK exsc ].while_line != l )
  1137. {
  1138. bwb_incexec();
  1139. CURTASK excs[ CURTASK exsc ].while_line = l;
  1140. /* find the WEND statement (or LOOP statement) */
  1141. #if STRUCT_CMDS
  1142. if ( l->cmdnum == getcmdnum( CMD_DO ))
  1143. {
  1144. CURTASK excs[ CURTASK exsc ].wend_line = find_loop( l );
  1145. }
  1146. else
  1147. {
  1148. CURTASK excs[ CURTASK exsc ].wend_line = find_wend( l );
  1149. }
  1150. #else
  1151. CURTASK excs[ CURTASK exsc ].wend_line = find_wend( l );
  1152. #endif
  1153. if ( CURTASK excs[ CURTASK exsc ].wend_line == NULL )
  1154. {
  1155. return bwb_zline( l );
  1156. }
  1157. #if INTENSIVE_DEBUG
  1158. sprintf( bwb_ebuf, "in bwb_while(): initialize WHILE loop, line <%d>",
  1159. l->number );
  1160. bwb_debug( bwb_ebuf );
  1161. #endif
  1162. }
  1163. #if INTENSIVE_DEBUG
  1164. else
  1165. {
  1166. sprintf( bwb_ebuf, "in bwb_while(): return to WHILE loop, line <%d>",
  1167. l->number );
  1168. bwb_debug( bwb_ebuf );
  1169. }
  1170. #endif
  1171. bwb_setexec( l, l->position, EXEC_WHILE );
  1172. return bwb_zline( l );
  1173. }
  1174. else
  1175. {
  1176. CURTASK excs[ CURTASK exsc ].while_line = NULL;
  1177. r = CURTASK excs[ CURTASK exsc ].wend_line;
  1178. bwb_setexec( r, 0, CURTASK excs[ CURTASK exsc - 1 ].code );
  1179. r->position = 0;
  1180. bwb_decexec();
  1181. return r;
  1182. }
  1183. }
  1184. /***************************************************************
  1185. FUNCTION: bwb_wend()
  1186. DESCRIPTION: This function handles the BASIC WEND
  1187. statement and the LOOP statement ending
  1188. a DO WHILE loop.
  1189. SYNTAX: WEND
  1190. LOOP
  1191. ***************************************************************/
  1192. #if ANSI_C
  1193. struct bwb_line *
  1194. bwb_wend( struct bwb_line *l )
  1195. #else
  1196. struct bwb_line *
  1197. bwb_wend( l )
  1198. struct bwb_line *l;
  1199. #endif
  1200. {
  1201. /* check integrity of WHILE loop */
  1202. if ( CURTASK excs[ CURTASK exsc ].code != EXEC_WHILE )
  1203. {
  1204. #if PROG_ERRORS
  1205. sprintf( bwb_ebuf, "in bwb_wend(): exec stack code != EXEC_WHILE" );
  1206. bwb_error( bwb_ebuf );
  1207. #else
  1208. bwb_error( err_syntax );
  1209. #endif
  1210. }
  1211. if ( CURTASK excs[ CURTASK exsc ].while_line == NULL )
  1212. {
  1213. #if PROG_ERRORS
  1214. sprintf( bwb_ebuf, "in bwb_wend(): exec stack while_line == NULL" );
  1215. bwb_error( bwb_ebuf );
  1216. #else
  1217. bwb_error( err_syntax );
  1218. #endif
  1219. }
  1220. /* reset to the top of the current WHILE loop */
  1221. #if INTENSIVE_DEBUG
  1222. sprintf( bwb_ebuf, "in bwb_wend() return to line <%d>",
  1223. CURTASK excs[ CURTASK exsc ].while_line->number );
  1224. bwb_debug( bwb_ebuf );
  1225. #endif
  1226. CURTASK excs[ CURTASK exsc ].while_line->position = 0;
  1227. bwb_setexec( CURTASK excs[ CURTASK exsc ].while_line, 0, EXEC_WHILE );
  1228. return CURTASK excs[ CURTASK exsc ].while_line;
  1229. }
  1230. /***************************************************************
  1231. FUNCTION: find_wend()
  1232. DESCRIPTION: This function searches for a line containing
  1233. a WEND statement corresponding to a previous
  1234. WHILE statement.
  1235. ***************************************************************/
  1236. #if ANSI_C
  1237. static struct bwb_line *
  1238. find_wend( struct bwb_line *l )
  1239. #else
  1240. static struct bwb_line *
  1241. find_wend( l )
  1242. struct bwb_line *l;
  1243. #endif
  1244. {
  1245. struct bwb_line *current;
  1246. register int w_level;
  1247. int position;
  1248. w_level = 1;
  1249. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  1250. {
  1251. position = 0;
  1252. if ( current->marked != TRUE )
  1253. {
  1254. line_start( current->buffer, &position, &( current->lnpos ),
  1255. &( current->lnum ),
  1256. &( current->cmdpos ),
  1257. &( current->cmdnum ),
  1258. &( current->startpos ) );
  1259. }
  1260. current->position = current->startpos;
  1261. if ( current->cmdnum > -1 )
  1262. {
  1263. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_while )
  1264. {
  1265. ++w_level;
  1266. #if INTENSIVE_DEBUG
  1267. sprintf( bwb_ebuf, "in find_wend(): found WHILE at line %d, level %d",
  1268. current->number, w_level );
  1269. bwb_debug( bwb_ebuf );
  1270. #endif
  1271. }
  1272. else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_wend )
  1273. {
  1274. --w_level;
  1275. #if INTENSIVE_DEBUG
  1276. sprintf( bwb_ebuf, "in find_wend(): found WEND at line %d, level %d",
  1277. current->number, w_level );
  1278. bwb_debug( bwb_ebuf );
  1279. #endif
  1280. if ( w_level == 0 )
  1281. {
  1282. return current->next;
  1283. }
  1284. }
  1285. }
  1286. }
  1287. #if PROG_ERRORS
  1288. sprintf( bwb_ebuf, "in find_wend(): WHILE without WEND" );
  1289. bwb_error( bwb_ebuf );
  1290. #else
  1291. bwb_error( err_syntax );
  1292. #endif
  1293. return NULL;
  1294. }
  1295. #if STRUCT_CMDS
  1296. /***************************************************************
  1297. FUNCTION: find_loop()
  1298. DESCRIPTION: This function searches for a line containing
  1299. a LOOP statement corresponding to a previous
  1300. DO statement.
  1301. ***************************************************************/
  1302. #if ANSI_C
  1303. extern struct bwb_line *
  1304. find_loop( struct bwb_line *l )
  1305. #else
  1306. extern struct bwb_line *
  1307. find_loop( l )
  1308. struct bwb_line *l;
  1309. #endif
  1310. {
  1311. struct bwb_line *current;
  1312. register int w_level;
  1313. int position;
  1314. w_level = 1;
  1315. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  1316. {
  1317. position = 0;
  1318. if ( current->marked != TRUE )
  1319. {
  1320. line_start( current->buffer, &position, &( current->lnpos ),
  1321. &( current->lnum ),
  1322. &( current->cmdpos ),
  1323. &( current->cmdnum ),
  1324. &( current->startpos ) );
  1325. }
  1326. current->position = current->startpos;
  1327. if ( current->cmdnum > -1 )
  1328. {
  1329. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_do )
  1330. {
  1331. ++w_level;
  1332. #if INTENSIVE_DEBUG
  1333. sprintf( bwb_ebuf, "in find_loop(): found DO at line %d, level %d",
  1334. current->number, w_level );
  1335. bwb_debug( bwb_ebuf );
  1336. #endif
  1337. }
  1338. else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_loop )
  1339. {
  1340. --w_level;
  1341. #if INTENSIVE_DEBUG
  1342. sprintf( bwb_ebuf, "in fnd_loop(): found LOOP at line %d, level %d",
  1343. current->number, w_level );
  1344. bwb_debug( bwb_ebuf );
  1345. #endif
  1346. if ( w_level == 0 )
  1347. {
  1348. return current->next;
  1349. }
  1350. }
  1351. }
  1352. }
  1353. #if PROG_ERRORS
  1354. sprintf( bwb_ebuf, "in find_loop(): DO without LOOP" );
  1355. bwb_error( bwb_ebuf );
  1356. #else
  1357. bwb_error( err_syntax );
  1358. #endif
  1359. return NULL;
  1360. }
  1361. #endif /* STRUCT_CMDS */
  1362. #endif /* COMMON_CMDS || STRUCT_CMDS */
  1363. /*** FOR-NEXT ***/
  1364. /***************************************************************
  1365. FUNCTION: bwb_for()
  1366. DESCRIPTION: This function handles the BASIC FOR
  1367. statement.
  1368. SYNTAX: FOR counter = start TO finish [STEP increment]
  1369. ***************************************************************/
  1370. #if ANSI_C
  1371. struct bwb_line *
  1372. bwb_for( struct bwb_line *l )
  1373. #else
  1374. struct bwb_line *
  1375. bwb_for( l )
  1376. struct bwb_line *l;
  1377. #endif
  1378. {
  1379. register int n;
  1380. int e, loop;
  1381. int to, step, p;
  1382. int for_step, for_target;
  1383. struct exp_ese *exp;
  1384. struct bwb_variable *v;
  1385. char tbuf[ MAXSTRINGSIZE + 1 ];
  1386. /* get the variable name */
  1387. exp_getvfname( &( l->buffer[ l->position ] ), tbuf );
  1388. l->position += strlen( tbuf );
  1389. v = var_find( tbuf );
  1390. #if INTENSIVE_DEBUG
  1391. sprintf( bwb_ebuf, "in bwb_for(): variable name <%s>.", v->name );
  1392. bwb_debug( bwb_ebuf );
  1393. #endif
  1394. /*--------------------------------------------------------------*/
  1395. /* Make sure we are in the right FOR-NEXT level! */
  1396. /* If we aren't (which could happen for legit reasons), fix the */
  1397. /* exec stack. */
  1398. /* JBV, 9/20/95 */
  1399. /*--------------------------------------------------------------*/
  1400. if (v == CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec();
  1401. /* at this point one should find an equals sign ('=') */
  1402. adv_ws( l->buffer, &( l->position ) );
  1403. if ( l->buffer[ l->position ] != '=' )
  1404. {
  1405. #if PROG_ERRORS
  1406. sprintf( bwb_ebuf, "in bwb_for(): failed to find equals sign, buf <%s>",
  1407. &( l->buffer[ l->position ] ) );
  1408. bwb_error( bwb_ebuf );
  1409. #else
  1410. bwb_error( err_syntax );
  1411. #endif
  1412. return bwb_zline( l );
  1413. }
  1414. else
  1415. {
  1416. ++( l->position );
  1417. }
  1418. /* Find the TO and STEP statements */
  1419. cnd_tostep( l->buffer, l->position, &to, &step );
  1420. /* if there is no TO statement, then an error has ocurred */
  1421. if ( to < 1 )
  1422. {
  1423. #if PROG_ERRORS
  1424. sprintf( bwb_ebuf, "FOR statement without TO" );
  1425. bwb_error( bwb_ebuf );
  1426. #else
  1427. bwb_error( err_syntax );
  1428. #endif
  1429. return bwb_zline( l );
  1430. }
  1431. /* copy initial value to buffer and evaluate it */
  1432. tbuf[ 0 ] = '\0';
  1433. p = 0;
  1434. for ( n = l->position; n < to; ++n )
  1435. {
  1436. tbuf[ p ] = l->buffer[ n ];
  1437. ++p;
  1438. ++l->position;
  1439. tbuf[ p ] = '\0';
  1440. }
  1441. #if INTENSIVE_DEBUG
  1442. sprintf( bwb_ebuf, "in bwb_for(): initial value string <%s>",
  1443. tbuf );
  1444. bwb_debug( bwb_ebuf );
  1445. #endif
  1446. p = 0;
  1447. exp = bwb_exp( tbuf, FALSE, &p );
  1448. var_setnval( v, exp_getnval( exp ) );
  1449. #if INTENSIVE_DEBUG
  1450. sprintf( bwb_ebuf, "in bwb_for(): initial value <%d> pos <%d>",
  1451. exp_getnval( exp ), l->position );
  1452. bwb_debug( bwb_ebuf );
  1453. #endif
  1454. /* copy target value to small buffer and evaluate it */
  1455. tbuf[ 0 ] = '\0';
  1456. p = 0;
  1457. l->position = to + 2;
  1458. if ( step < 1 )
  1459. {
  1460. e = strlen( l->buffer );
  1461. }
  1462. else
  1463. {
  1464. e = step - 1;
  1465. }
  1466. loop = TRUE;
  1467. n = l->position;
  1468. while( loop == TRUE )
  1469. {
  1470. tbuf[ p ] = l->buffer[ n ];
  1471. ++p;
  1472. ++l->position;
  1473. tbuf[ p ] = '\0';
  1474. if ( n >= e )
  1475. {
  1476. loop = FALSE;
  1477. }
  1478. ++n;
  1479. if ( l->buffer[ n ] == ':' )
  1480. {
  1481. loop = FALSE;
  1482. }
  1483. }
  1484. #if INTENSIVE_DEBUG
  1485. sprintf( bwb_ebuf, "in bwb_for(): target value string <%s>",
  1486. tbuf );
  1487. bwb_debug( bwb_ebuf );
  1488. #endif
  1489. p = 0;
  1490. exp = bwb_exp( tbuf, FALSE, &p );
  1491. for_target = (int) exp_getnval( exp );
  1492. #if INTENSIVE_DEBUG
  1493. sprintf( bwb_ebuf, "in bwb_for(): target value <%d> pos <%d>",
  1494. exp_getnval( exp ), l->position );
  1495. bwb_debug( bwb_ebuf );
  1496. #endif
  1497. /* If there is a STEP statement, copy it to a buffer
  1498. and evaluate it */
  1499. if ( step > 1 )
  1500. {
  1501. tbuf[ 0 ] = '\0';
  1502. p = 0;
  1503. l->position = step + 4;
  1504. for ( n = l->position; n < (int) strlen( l->buffer ); ++n )
  1505. {
  1506. tbuf[ p ] = l->buffer[ n ];
  1507. ++p;
  1508. ++l->position;
  1509. tbuf[ p ] = '\0';
  1510. }
  1511. #if INTENSIVE_DEBUG
  1512. sprintf( bwb_ebuf, "in bwb_for(): step value string <%s>",
  1513. tbuf );
  1514. bwb_debug( bwb_ebuf );
  1515. #endif
  1516. p = 0;
  1517. exp = bwb_exp( tbuf, FALSE, &p );
  1518. for_step = (int) exp_getnval( exp );
  1519. }
  1520. else
  1521. {
  1522. for_step = 1;
  1523. }
  1524. #if INTENSIVE_DEBUG
  1525. sprintf( bwb_ebuf, "in bwb_for(): step value <%d>",
  1526. for_step );
  1527. bwb_debug( bwb_ebuf );
  1528. #endif
  1529. /* set position in current line and increment EXEC counter */
  1530. /* bwb_setexec( l, l->position, EXEC_NORM ); */ /* WRONG */
  1531. bwb_incexec();
  1532. CURTASK excs[ CURTASK exsc ].local_variable = v;
  1533. CURTASK excs[ CURTASK exsc ].for_step = for_step;
  1534. CURTASK excs[ CURTASK exsc ].for_target = for_target;
  1535. /* set exit line to be used by EXIT FOR */
  1536. #if STRUCT_CMDS
  1537. CURTASK excs[ CURTASK exsc ].wend_line = find_next( l );
  1538. #endif
  1539. /* set top line and position to be used in multisegmented FOR-NEXT loop */
  1540. #if MULTISEG_LINES
  1541. CURTASK excs[ CURTASK exsc ].for_line = l;
  1542. CURTASK excs[ CURTASK exsc ].for_position = l->position;
  1543. #endif
  1544. #if INTENSIVE_DEBUG
  1545. sprintf( bwb_ebuf, "in bwb_for(): setting code to EXEC_FOR",
  1546. l->position );
  1547. bwb_debug( bwb_ebuf );
  1548. #endif
  1549. bwb_setexec( l, l->position, EXEC_FOR );
  1550. #if INTENSIVE_DEBUG
  1551. sprintf( bwb_ebuf, "in bwb_for(): ready to exit, position <%d>",
  1552. l->position );
  1553. bwb_debug( bwb_ebuf );
  1554. #endif
  1555. /* proceed with processing */
  1556. return bwb_zline( l );
  1557. }
  1558. /***************************************************************
  1559. FUNCTION: bwb_next()
  1560. DESCRIPTION: This function handles the BASIC NEXT
  1561. statement.
  1562. SYNTAX: NEXT counter
  1563. ***************************************************************/
  1564. #if ANSI_C
  1565. struct bwb_line *
  1566. bwb_next( struct bwb_line *l )
  1567. #else
  1568. struct bwb_line *
  1569. bwb_next( l )
  1570. struct bwb_line *l;
  1571. #endif
  1572. {
  1573. char tbuf[ MAXSTRINGSIZE + 1 ];
  1574. struct bwb_variable *v; /* Relocated from INTENSIVE_DEBUG (JBV) */
  1575. #if INTENSIVE_DEBUG
  1576. sprintf( bwb_ebuf, "in bwb_next(): entered function, cmdnum <%d> exsc level <%d> code <%d>",
  1577. l->cmdnum, CURTASK exsc, CURTASK excs[ CURTASK exsc ].code );
  1578. bwb_debug( bwb_ebuf );
  1579. #endif
  1580. /* Check the integrity of the FOR statement */
  1581. if ( CURTASK excs[ CURTASK exsc ].code != EXEC_FOR )
  1582. {
  1583. #if PROG_ERRORS
  1584. sprintf( bwb_ebuf, "in bwb_next(): NEXT without FOR; code is <%d> instead of <%d>",
  1585. CURTASK excs[ CURTASK exsc ].code, EXEC_FOR );
  1586. bwb_error( bwb_ebuf );
  1587. #else
  1588. bwb_error( err_syntax );
  1589. #endif
  1590. }
  1591. /* read the argument, if there is one */
  1592. /* Relocated from MULTISEG_LINES (JBV) */
  1593. exp_getvfname( &( l->buffer[ l->position ] ), tbuf );
  1594. if (strlen(tbuf) != 0)
  1595. {
  1596. /* Relocated from INTENSIVE_DEBUG (JBV) */
  1597. v = var_find( tbuf );
  1598. #if MULTISEG_LINES /* not currently needed otherwise */
  1599. l->position += strlen( tbuf );
  1600. #if INTENSIVE_DEBUG
  1601. sprintf( bwb_ebuf, "in bwb_next(): variable name detected <%s>.", v->name );
  1602. bwb_debug( bwb_ebuf );
  1603. #endif
  1604. #endif
  1605. /* decrement or increment the value */
  1606. /*--------------------------------------------------------------*/
  1607. /* Make sure we are in the right FOR-NEXT level! */
  1608. /* If we aren't (which could happen for legit reasons), fix the */
  1609. /* exec stack. */
  1610. /* JBV, 9/20/95 */
  1611. /*--------------------------------------------------------------*/
  1612. while (v != CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec();
  1613. }
  1614. var_setnval( CURTASK excs[ CURTASK exsc ].local_variable,
  1615. var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )
  1616. + (bnumber) CURTASK excs[ CURTASK exsc ].for_step );
  1617. /* check for completion of the loop */
  1618. if ( CURTASK excs[ CURTASK exsc ].for_step > 0 ) /* if step is positive */
  1619. {
  1620. if ( (int) var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )
  1621. > CURTASK excs[ CURTASK exsc ].for_target )
  1622. {
  1623. bwb_decexec();
  1624. #if MULTISEG_LINES
  1625. bwb_setexec( l, l->position, CURTASK excs[ CURTASK exsc ].code );
  1626. #else
  1627. bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );
  1628. #endif
  1629. #if INTENSIVE_DEBUG
  1630. sprintf( bwb_ebuf, "in bwb_next(): end of loop" );
  1631. bwb_debug( bwb_ebuf );
  1632. #endif
  1633. #ifdef OLD_WAY
  1634. l->next->position = 0;
  1635. return l->next;
  1636. #else
  1637. return bwb_zline( l );
  1638. #endif
  1639. }
  1640. }
  1641. else /* if step is negative */
  1642. {
  1643. if ( (int) var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )
  1644. < CURTASK excs[ CURTASK exsc ].for_target )
  1645. {
  1646. bwb_decexec();
  1647. bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );
  1648. #if INTENSIVE_DEBUG
  1649. sprintf( bwb_ebuf, "in bwb_next(): end of loop" );
  1650. bwb_debug( bwb_ebuf );
  1651. #endif
  1652. #ifdef OLD_WAY
  1653. l->next->position = 0;
  1654. return l->next;
  1655. #else
  1656. return bwb_zline( l );
  1657. #endif
  1658. }
  1659. }
  1660. /* Target not reached: return to the top of the FOR loop */
  1661. #if INTENSIVE_DEBUG
  1662. sprintf( bwb_ebuf, "in bwb_next(): resetting code to EXEC_FOR",
  1663. l->position );
  1664. bwb_debug( bwb_ebuf );
  1665. #endif
  1666. #if MULTISEG_LINES
  1667. CURTASK excs[ CURTASK exsc ].for_line->position
  1668. = CURTASK excs[ CURTASK exsc ].for_position;
  1669. bwb_setexec( CURTASK excs[ CURTASK exsc ].for_line,
  1670. CURTASK excs[ CURTASK exsc ].for_position, EXEC_FOR );
  1671. return CURTASK excs[ CURTASK exsc ].for_line; /* Added (JBV) */
  1672. #else
  1673. bwb_setexec( CURTASK excs[ CURTASK exsc - 1 ].line,
  1674. CURTASK excs[ CURTASK exsc - 1 ].position, EXEC_FOR );
  1675. return CURTASK excs[ CURTASK exsc - 1 ].line; /* Relocated (JBV) */
  1676. #endif
  1677. }
  1678. #if STRUCT_CMDS
  1679. /***************************************************************
  1680. FUNCTION: bwb_exitfor()
  1681. DESCRIPTION: This function handles the BASIC EXIT
  1682. FOR statement. This is a structured
  1683. programming command compatible with ANSI
  1684. BASIC. It is called from the bwb_exit()
  1685. subroutine.
  1686. SYNTAX: EXIT FOR
  1687. ***************************************************************/
  1688. #if ANSI_C
  1689. struct bwb_line *
  1690. bwb_exitfor( struct bwb_line *l )
  1691. #else
  1692. struct bwb_line *
  1693. bwb_exitfor( l )
  1694. struct bwb_line *l;
  1695. #endif
  1696. {
  1697. struct bwb_line *next_line;
  1698. int found;
  1699. register int level;
  1700. #if INTENSIVE_DEBUG
  1701. sprintf( bwb_ebuf, "in bwb_exitfor(): entered subroutine" );
  1702. bwb_debug( bwb_ebuf );
  1703. #endif
  1704. /* Check the integrity of the FOR statement */
  1705. found = FALSE;
  1706. level = CURTASK exsc;
  1707. do
  1708. {
  1709. if ( CURTASK excs[ level ].code == EXEC_FOR )
  1710. {
  1711. next_line = CURTASK excs[ CURTASK level ].wend_line;
  1712. found = TRUE;
  1713. }
  1714. else
  1715. {
  1716. --level;
  1717. }
  1718. }
  1719. while ( ( level >= 0 ) && ( found == FALSE ) );
  1720. if ( found != TRUE )
  1721. {
  1722. #if PROG_ERRORS
  1723. sprintf( bwb_ebuf, "in bwb_exitfor(): EXIT FOR without FOR" );
  1724. bwb_error( bwb_ebuf );
  1725. #else
  1726. bwb_error( err_syntax );
  1727. #endif
  1728. return bwb_zline( l );
  1729. }
  1730. #if INTENSIVE_DEBUG
  1731. sprintf( bwb_ebuf, "in bwb_exitfor(): level found is <%d>, current <%d>",
  1732. level, CURTASK exsc );
  1733. bwb_debug( bwb_ebuf );
  1734. #endif
  1735. /* decrement below the level of the NEXT statement */
  1736. while( CURTASK exsc >= level )
  1737. {
  1738. bwb_decexec();
  1739. }
  1740. /* set the next line in the exec stack */
  1741. next_line->position = 0;
  1742. /* bwb_setexec( next_line, 0, EXEC_NORM ); */ /* WRONG (JBV) */
  1743. bwb_setexec( next_line, 0, CURTASK excs[ CURTASK exsc ].code ); /* JBV */
  1744. return next_line;
  1745. }
  1746. /***************************************************************
  1747. FUNCTION: find_next()
  1748. DESCRIPTION: This function searches for a line containing
  1749. a NEXT statement corresponding to a previous
  1750. FOR statement.
  1751. ***************************************************************/
  1752. #if ANSI_C
  1753. static struct bwb_line *
  1754. find_next( struct bwb_line *l )
  1755. #else
  1756. static struct bwb_line *
  1757. find_next( l )
  1758. struct bwb_line *l;
  1759. #endif
  1760. {
  1761. struct bwb_line *current;
  1762. register int w_level;
  1763. int position;
  1764. w_level = 1;
  1765. for ( current = l->next; current != &CURTASK bwb_end; current = current->next )
  1766. {
  1767. position = 0;
  1768. if ( current->marked != TRUE )
  1769. {
  1770. line_start( current->buffer, &position, &( current->lnpos ),
  1771. &( current->lnum ),
  1772. &( current->cmdpos ),
  1773. &( current->cmdnum ),
  1774. &( current->startpos ) );
  1775. }
  1776. current->position = current->startpos;
  1777. if ( current->cmdnum > -1 )
  1778. {
  1779. if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_for )
  1780. {
  1781. ++w_level;
  1782. #if INTENSIVE_DEBUG
  1783. sprintf( bwb_ebuf, "in find_next(): found FOR at line %d, level %d",
  1784. current->number, w_level );
  1785. bwb_debug( bwb_ebuf );
  1786. #endif
  1787. }
  1788. else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_next )
  1789. {
  1790. --w_level;
  1791. #if INTENSIVE_DEBUG
  1792. sprintf( bwb_ebuf, "in find_next(): found NEXT at line %d, level %d",
  1793. current->number, w_level );
  1794. bwb_debug( bwb_ebuf );
  1795. #endif
  1796. if ( w_level == 0 )
  1797. {
  1798. #if INTENSIVE_DEBUG
  1799. sprintf( bwb_ebuf, "in find_next(): found returning line <%d>",
  1800. current->next->number );
  1801. bwb_debug( bwb_ebuf );
  1802. #endif
  1803. return current->next;
  1804. }
  1805. }
  1806. }
  1807. }
  1808. #if PROG_ERRORS
  1809. sprintf( bwb_ebuf, "FOR without NEXT" );
  1810. bwb_error( bwb_ebuf );
  1811. #else
  1812. bwb_error( err_syntax );
  1813. #endif
  1814. return NULL;
  1815. }
  1816. #endif /* STRUCT_CMDS for EXIT FOR */
  1817. /***************************************************************
  1818. FUNCTION: cnd_tostep()
  1819. DESCRIPTION: This function searches through the
  1820. <buffer> beginning at point <position>
  1821. and attempts to find positions of TO
  1822. and STEP statements.
  1823. ***************************************************************/
  1824. #if ANSI_C
  1825. static int
  1826. cnd_tostep( char *buffer, int position, int *to, int *step )
  1827. #else
  1828. static int
  1829. cnd_tostep( buffer, position, to, step )
  1830. char *buffer;
  1831. int position;
  1832. int *to;
  1833. int *step;
  1834. #endif
  1835. {
  1836. int loop, t_pos, b_pos, p_word;
  1837. char tbuf[ MAXSTRINGSIZE + 1 ];
  1838. /* set then and els to FALSE initially */
  1839. *to = *step = FALSE;
  1840. /* loop to find words */
  1841. p_word = b_pos = position;
  1842. t_pos = 0;
  1843. tbuf[ 0 ] = '\0';
  1844. loop = TRUE;
  1845. while ( loop == TRUE )
  1846. {
  1847. switch( buffer[ b_pos ] )
  1848. {
  1849. case '\0': /* end of string */
  1850. case ':': /* end of line segment */
  1851. return TRUE;
  1852. case ' ': /* whitespace = end of word */
  1853. case '\t':
  1854. #if INTENSIVE_DEBUG
  1855. sprintf( bwb_ebuf, "in cnd_tostep(): word is <%s>", tbuf );
  1856. bwb_debug( bwb_ebuf );
  1857. #endif
  1858. if ( strncmp( tbuf, CMD_TO, (size_t) strlen( CMD_TO ) ) == 0 )
  1859. {
  1860. #if INTENSIVE_DEBUG
  1861. sprintf( bwb_ebuf, "in cnd_tostep(): TO found at position <%d>.",
  1862. p_word );
  1863. bwb_debug( bwb_ebuf );
  1864. #endif
  1865. *to = p_word;
  1866. }
  1867. else if ( strncmp( tbuf, CMD_STEP, (size_t) strlen( CMD_STEP ) ) == 0 )
  1868. {
  1869. #if INTENSIVE_DEBUG
  1870. sprintf( bwb_ebuf, "in cnd_tostep(): STEP found at position <%d>.",
  1871. p_word );
  1872. bwb_debug( bwb_ebuf );
  1873. #endif
  1874. *step = p_word;
  1875. }
  1876. ++b_pos;
  1877. p_word = b_pos;
  1878. t_pos = 0;
  1879. tbuf[ 0 ] = '\0';
  1880. break;
  1881. default:
  1882. if ( islower( buffer[ b_pos ] ) != FALSE )
  1883. {
  1884. tbuf[ t_pos ] = (char) toupper( buffer[ b_pos ] );
  1885. }
  1886. else
  1887. {
  1888. tbuf[ t_pos ] = buffer[ b_pos ];
  1889. }
  1890. ++b_pos;
  1891. ++t_pos;
  1892. tbuf[ t_pos ] = '\0';
  1893. break;
  1894. }
  1895. }
  1896. return TRUE;
  1897. }
  1898. /***************************************************************
  1899. FUNCTION: var_setnval()
  1900. DESCRIPTION: This function sets the value of numerical
  1901. variable v to the value of i.
  1902. ***************************************************************/
  1903. #if ANSI_C
  1904. extern int
  1905. var_setnval( struct bwb_variable *v, bnumber i )
  1906. #else
  1907. int
  1908. var_setnval( v, i )
  1909. struct bwb_variable *v;
  1910. bnumber i;
  1911. #endif
  1912. {
  1913. switch( v->type )
  1914. {
  1915. case NUMBER:
  1916. * var_findnval( v, v->array_pos ) = i;
  1917. break;
  1918. default:
  1919. #if INTENSIVE_DEBUG
  1920. sprintf( bwb_ebuf, "in var_setnval(): variable <%s> is not a number",
  1921. v->name );
  1922. bwb_error( bwb_ebuf );
  1923. #else
  1924. bwb_error( err_mismatch );
  1925. #endif
  1926. }
  1927. /* successful assignment */
  1928. return TRUE;
  1929. }