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.
 
 
 
 
 
 

1951 lines
44 KiB

  1. /****************************************************************
  2. bwb_fnc.c Interpretation Routines
  3. for Predefined Functions
  4. for Bywater BASIC Interpreter
  5. Copyright (c) 1993, Ted A. Campbell
  6. Bywater Software
  7. email: tcamp@delphi.com
  8. Copyright and Permissions Information:
  9. All U.S. and international rights are claimed by the author,
  10. Ted A. Campbell.
  11. This software is released under the terms of the GNU General
  12. Public License (GPL), which is distributed with this software
  13. in the file "COPYING". The GPL specifies the terms under
  14. which users may copy and use the software in this distribution.
  15. A separate license is available for commercial distribution,
  16. for information on which you should contact the author.
  17. ****************************************************************/
  18. /*---------------------------------------------------------------*/
  19. /* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */
  20. /* 11/1995 (eidetics@cerf.net). */
  21. /*---------------------------------------------------------------*/
  22. #define FSTACKSIZE 32
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include <math.h>
  26. #include <time.h>
  27. #include "bwbasic.h"
  28. #include "bwb_mes.h"
  29. #if UNIX_CMDS
  30. #include <sys/stat.h>
  31. #endif
  32. #ifndef RAND_MAX /* added in v1.11 */
  33. #define RAND_MAX 32767
  34. #endif
  35. static time_t t;
  36. static struct tm *lt;
  37. /***************************************************************
  38. FUNCTION: fnc_init()
  39. DESCRIPTION: This command initializes the function
  40. linked list, placing all predefined functions
  41. in the list.
  42. ***************************************************************/
  43. #if ANSI_C
  44. int
  45. fnc_init( int task )
  46. #else
  47. int
  48. fnc_init( task )
  49. int task;
  50. #endif
  51. {
  52. register int n;
  53. struct bwb_function *f;
  54. strcpy( LOCALTASK fnc_start.name, "FNC_START" );
  55. LOCALTASK fnc_start.type = 'X';
  56. LOCALTASK fnc_start.vector = fnc_null;
  57. strcpy( LOCALTASK fnc_end.name, "FNC_END" );
  58. LOCALTASK fnc_end.type = 'x';
  59. LOCALTASK fnc_end.vector = fnc_null;
  60. LOCALTASK fnc_end.next = &LOCALTASK fnc_end;
  61. f = &LOCALTASK fnc_start;
  62. /* now go through each of the preestablished functions and set up
  63. links between them; from this point the program address the functions
  64. only as a linked list (not as an array) */
  65. for ( n = 0; n < FUNCTIONS; ++n )
  66. {
  67. f->next = &( bwb_prefuncs[ n ] );
  68. f = f->next;
  69. }
  70. /* link the last pointer to the end; this completes the list */
  71. f->next = &LOCALTASK fnc_end;
  72. return TRUE;
  73. }
  74. /***************************************************************
  75. FUNCTION: fnc_find()
  76. DESCRIPTION: This C function attempts to locate
  77. a BASIC function with the specified name.
  78. If successful, it returns a pointer to
  79. the C structure for the BASIC function,
  80. if not successful, it returns NULL.
  81. ***************************************************************/
  82. #if ANSI_C
  83. struct bwb_function *
  84. fnc_find( char *buffer )
  85. #else
  86. struct bwb_function *
  87. fnc_find( buffer )
  88. char *buffer;
  89. #endif
  90. {
  91. struct bwb_function * f;
  92. register int n;
  93. static char *tbuf;
  94. static int init = FALSE;
  95. if ( strlen( buffer ) == 0 )
  96. {
  97. return NULL;
  98. }
  99. /* get memory for temporary buffer if necessary */
  100. if ( init == FALSE )
  101. {
  102. init = TRUE;
  103. /* Revised to CALLOC pass-thru call by JBV */
  104. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_find" )) == NULL )
  105. {
  106. #if PROG_ERRORS
  107. bwb_error( "in fnc_find(): failed to find memory for tbuf" );
  108. #else
  109. bwb_error( err_getmem );
  110. #endif
  111. }
  112. }
  113. #if INTENSIVE_DEBUG
  114. sprintf( bwb_ebuf, "in fnc_find(): called for <%s> ", buffer );
  115. bwb_debug( bwb_ebuf );
  116. #endif
  117. strcpy( tbuf, buffer );
  118. bwb_strtoupper( tbuf );
  119. for ( f = CURTASK fnc_start.next; f != &CURTASK fnc_end; f = f->next )
  120. {
  121. if ( strcmp( f->name, tbuf ) == 0 )
  122. {
  123. #if INTENSIVE_DEBUG
  124. sprintf( bwb_ebuf, "in fnc_find(): found <%s> ", f->name );
  125. bwb_debug( bwb_ebuf );
  126. #endif
  127. return f;
  128. }
  129. }
  130. /* search has failed: return NULL */
  131. return NULL;
  132. }
  133. /***************************************************************
  134. FUNCTION: fnc_null()
  135. DESCRIPTION: This is a null function that can be used
  136. to fill in a required function-structure
  137. pointer when needed.
  138. ***************************************************************/
  139. #if ANSI_C
  140. struct bwb_variable *
  141. fnc_null( int argc, struct bwb_variable *argv, int unique_id )
  142. #else
  143. struct bwb_variable *
  144. fnc_null( argc, argv, unique_id )
  145. int argc;
  146. struct bwb_variable *argv;
  147. int unique_id;
  148. #endif
  149. {
  150. static struct bwb_variable nvar;
  151. static int init = FALSE;
  152. /* initialize the variable if necessary */
  153. if ( init == FALSE )
  154. {
  155. init = TRUE;
  156. var_make( &nvar, NUMBER );
  157. }
  158. return &nvar;
  159. }
  160. /***************************************************************
  161. FUNCTION: fnc_tab()
  162. DESCRIPTION: This C function implements the BASIC TAB()
  163. function, adding tab spaces to a specified
  164. column.
  165. TAB is a core function, i.e., required
  166. for ANSI Minimal BASIC.
  167. SYNTAX: TAB( number )
  168. ***************************************************************/
  169. #if ANSI_C
  170. struct bwb_variable *
  171. fnc_tab( int argc, struct bwb_variable *argv, int unique_id )
  172. #else
  173. struct bwb_variable *
  174. fnc_tab( argc, argv, unique_id )
  175. int argc;
  176. struct bwb_variable *argv;
  177. int unique_id;
  178. #endif
  179. {
  180. static struct bwb_variable nvar;
  181. static int init = FALSE;
  182. static char t_string[ 4 ];
  183. bstring *b;
  184. /* initialize nvar if necessary */
  185. if ( init == FALSE )
  186. {
  187. init = TRUE;
  188. var_make( &nvar, (int) STRING );
  189. }
  190. /* check for correct number of parameters */
  191. if ( argc < 1 )
  192. {
  193. #if PROG_ERRORS
  194. sprintf( bwb_ebuf, "Not enough parameters (%d) to function TAB().",
  195. argc );
  196. bwb_error( bwb_ebuf );
  197. #else
  198. bwb_error( err_syntax );
  199. #endif
  200. break_handler();
  201. return NULL;
  202. }
  203. else if ( argc > 1 )
  204. {
  205. #if PROG_ERRORS
  206. sprintf( bwb_ebuf, "Too many parameters (%d) to function TAB().",
  207. argc );
  208. bwb_error( bwb_ebuf );
  209. #else
  210. bwb_error( err_syntax );
  211. #endif
  212. break_handler();
  213. return NULL;
  214. }
  215. t_string[ 0 ] = PRN_TAB;
  216. t_string[ 1 ] = (char) var_getnval( &( argv[ 0 ] ));
  217. t_string[ 2 ] = '\0';
  218. b = var_getsval( &nvar );
  219. str_ctob( b, t_string );
  220. return &nvar;
  221. }
  222. #if COMMON_FUNCS
  223. /***************************************************************
  224. FUNCTION: fnc_date()
  225. DESCRIPTION: This C function implements the BASIC
  226. predefined DATE$ function, returning
  227. a string containing the year, month,
  228. and day of the month.
  229. SYNTAX: DATE$
  230. ***************************************************************/
  231. #if ANSI_C
  232. struct bwb_variable *
  233. fnc_date( int argc, struct bwb_variable *argv, int unique_id )
  234. #else
  235. struct bwb_variable *
  236. fnc_date( argc, argv, unique_id )
  237. int argc;
  238. struct bwb_variable *argv;
  239. int unique_id;
  240. #endif
  241. {
  242. static struct bwb_variable nvar;
  243. static int init = FALSE;
  244. static char *tbuf;
  245. /* initialize the variable if necessary */
  246. if ( init == FALSE )
  247. {
  248. init = TRUE;
  249. var_make( &nvar, STRING );
  250. /* Revised to CALLOC pass-thru call by JBV */
  251. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_date" )) == NULL )
  252. {
  253. #if PROG_ERRORS
  254. bwb_error( "in fnc_date(): failed to get memory for tbuf" );
  255. #else
  256. bwb_error( err_getmem );
  257. #endif
  258. }
  259. }
  260. time( &t );
  261. lt = localtime( &t );
  262. sprintf( tbuf, "%02d-%02d-%04d", lt->tm_mon + 1, lt->tm_mday,
  263. 1900 + lt->tm_year );
  264. str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  265. return &nvar;
  266. }
  267. /***************************************************************
  268. FUNCTION: fnc_time()
  269. DESCRIPTION: This C function implements the BASIC
  270. predefined TIME$ function, returning a
  271. string containing the hour, minute, and
  272. second count.
  273. SYNTAX: TIME$
  274. ***************************************************************/
  275. #if ANSI_C
  276. struct bwb_variable *
  277. fnc_time( int argc, struct bwb_variable *argv, int unique_id )
  278. #else
  279. struct bwb_variable *
  280. fnc_time( argc, argv, unique_id )
  281. int argc;
  282. struct bwb_variable *argv;
  283. int unique_id;
  284. #endif
  285. {
  286. static struct bwb_variable nvar;
  287. static char *tbuf;
  288. static int init = FALSE;
  289. /* initialize the variable if necessary */
  290. if ( init == FALSE )
  291. {
  292. init = TRUE;
  293. var_make( &nvar, STRING );
  294. /* Revised to CALLOC pass-thru call by JBV */
  295. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_time" )) == NULL )
  296. {
  297. #if PROG_ERRORS
  298. bwb_error( "in fnc_time(): failed to get memory for tbuf" );
  299. #else
  300. bwb_error( err_getmem );
  301. #endif
  302. }
  303. }
  304. time( &t );
  305. lt = localtime( &t );
  306. sprintf( tbuf, "%02d:%02d:%02d", lt->tm_hour, lt->tm_min,
  307. lt->tm_sec );
  308. str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  309. return &nvar;
  310. }
  311. /***************************************************************
  312. FUNCTION: fnc_chr()
  313. DESCRIPTION: This C function implements the BASIC
  314. predefined CHR$ function, returning a
  315. string containing the single character
  316. whose ASCII value is the argument to
  317. this function.
  318. SYNTAX: CHR$( number )
  319. ***************************************************************/
  320. #if ANSI_C
  321. struct bwb_variable *
  322. fnc_chr( int argc, struct bwb_variable *argv, int unique_id )
  323. #else
  324. struct bwb_variable *
  325. fnc_chr( argc, argv, unique_id )
  326. int argc;
  327. struct bwb_variable *argv;
  328. int unique_id;
  329. #endif
  330. {
  331. static struct bwb_variable nvar;
  332. char tbuf[ MAXSTRINGSIZE + 1 ];
  333. static int init = FALSE;
  334. #if TEST_BSTRING
  335. bstring *b;
  336. #endif
  337. #if INTENSIVE_DEBUG
  338. sprintf( bwb_ebuf, "in fnc_chr(): entered function, argc <%d>",
  339. argc );
  340. bwb_debug( bwb_ebuf );
  341. #endif
  342. /* initialize the variable if necessary */
  343. if ( init == FALSE )
  344. {
  345. init = TRUE;
  346. var_make( &nvar, STRING );
  347. #if INTENSIVE_DEBUG
  348. sprintf( bwb_ebuf, "in fnc_chr(): entered function, initialized nvar" );
  349. bwb_debug( bwb_ebuf );
  350. #endif
  351. }
  352. /* check arguments */
  353. #if PROG_ERRORS
  354. if ( argc < 1 )
  355. {
  356. sprintf( bwb_ebuf, "Not enough arguments to function CHR$()" );
  357. bwb_error( bwb_ebuf );
  358. return NULL;
  359. }
  360. else if ( argc > 1 )
  361. {
  362. sprintf( bwb_ebuf, "Too many parameters (%d) to function CHR$().",
  363. argc );
  364. bwb_error( bwb_ebuf );
  365. return NULL;
  366. }
  367. #else
  368. if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  369. {
  370. return NULL;
  371. }
  372. #endif
  373. #if INTENSIVE_DEBUG
  374. sprintf( bwb_ebuf, "in fnc_chr(): entered function, checkargs ok" );
  375. bwb_debug( bwb_ebuf );
  376. #endif
  377. tbuf[ 0 ] = (char) var_getnval( &( argv[ 0 ] ) );
  378. tbuf[ 1 ] = '\0';
  379. str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  380. #if TEST_BSTRING
  381. b = var_findsval( &nvar, nvar.array_pos );
  382. sprintf( bwb_ebuf, "in fnc_chr(): bstring name is <%s>", b->name );
  383. bwb_debug( bwb_ebuf );
  384. #endif
  385. #if INTENSIVE_DEBUG
  386. sprintf( bwb_ebuf, "in fnc_chr(): tbuf[ 0 ] is <%c>", tbuf[ 0 ] );
  387. bwb_debug( bwb_ebuf );
  388. #endif
  389. return &nvar;
  390. }
  391. /***************************************************************
  392. FUNCTION: fnc_len()
  393. DESCRIPTION: This C function implements the BASIC LEN()
  394. function, returning the length of a
  395. specified string in bytes.
  396. SYNTAX: LEN( string$ )
  397. ***************************************************************/
  398. #if ANSI_C
  399. struct bwb_variable *
  400. fnc_len( int argc, struct bwb_variable *argv, int unique_id )
  401. #else
  402. struct bwb_variable *
  403. fnc_len( argc, argv, unique_id )
  404. int argc;
  405. struct bwb_variable *argv;
  406. int unique_id;
  407. #endif
  408. {
  409. static struct bwb_variable nvar;
  410. static int init = FALSE;
  411. static char *tbuf;
  412. /* initialize the variable if necessary */
  413. if ( init == FALSE )
  414. {
  415. init = TRUE;
  416. var_make( &nvar, NUMBER );
  417. /* Revised to CALLOC pass-thru call by JBV */
  418. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_len" )) == NULL )
  419. {
  420. #if PROG_ERRORS
  421. bwb_error( "in fnc_len(): failed to get memory for tbuf" );
  422. #else
  423. bwb_error( err_getmem );
  424. #endif
  425. }
  426. }
  427. /* check parameters */
  428. #if PROG_ERRORS
  429. if ( argc < 1 )
  430. {
  431. sprintf( bwb_ebuf, "Not enough parameters (%d) to function LEN().",
  432. argc );
  433. bwb_error( bwb_ebuf );
  434. return NULL;
  435. }
  436. else if ( argc > 1 )
  437. {
  438. sprintf( bwb_ebuf, "Too many parameters (%d) to function LEN().",
  439. argc );
  440. bwb_error( bwb_ebuf );
  441. return NULL;
  442. }
  443. #else
  444. if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  445. {
  446. return NULL;
  447. }
  448. #endif
  449. /* return length as an integer */
  450. str_btoc( tbuf, var_getsval( &( argv[ 0 ] )) );
  451. * var_findnval( &nvar, nvar.array_pos )
  452. = (bnumber) strlen( tbuf );
  453. return &nvar;
  454. }
  455. /***************************************************************
  456. FUNCTION: fnc_pos()
  457. DESCRIPTION: This C function implements the BASIC
  458. POS() function, returning the current
  459. column position for the output device.
  460. SYNTAX: POS
  461. ***************************************************************/
  462. #if ANSI_C
  463. struct bwb_variable *
  464. fnc_pos( int argc, struct bwb_variable *argv, int unique_id )
  465. #else
  466. struct bwb_variable *
  467. fnc_pos( argc, argv, unique_id )
  468. int argc;
  469. struct bwb_variable *argv;
  470. int unique_id;
  471. #endif
  472. {
  473. static struct bwb_variable nvar;
  474. static int init = FALSE;
  475. /* initialize nvar if necessary */
  476. if ( init == FALSE )
  477. {
  478. init = TRUE;
  479. var_make( &nvar, (int) NUMBER );
  480. }
  481. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) prn_col;
  482. return &nvar;
  483. }
  484. #endif /* COMMON_FUNCS */
  485. #if MS_FUNCS
  486. /***************************************************************
  487. FUNCTION: fnc_timer()
  488. DESCRIPTION: This C function implements the BASIC
  489. predefined TIMER function
  490. SYNTAX: TIMER
  491. ***************************************************************/
  492. #if ANSI_C
  493. struct bwb_variable *
  494. fnc_timer( int argc, struct bwb_variable *argv, int unique_id )
  495. #else
  496. struct bwb_variable *
  497. fnc_timer( argc, argv, unique_id )
  498. int argc;
  499. struct bwb_variable *argv;
  500. int unique_id;
  501. #endif
  502. {
  503. static struct bwb_variable nvar;
  504. static time_t now;
  505. static int init = FALSE;
  506. /* initialize the variable if necessary */
  507. if ( init == FALSE )
  508. {
  509. init = TRUE;
  510. var_make( &nvar, NUMBER );
  511. }
  512. time( &now );
  513. /* Following statement was (bnumber) (JBV) */
  514. * var_findnval( &nvar, nvar.array_pos )
  515. = (float) fmod( (double) now, (double) (60*60*24));
  516. return &nvar;
  517. }
  518. /***************************************************************
  519. FUNCTION: fnc_mid()
  520. DESCRIPTION: This C function implements the BASIC
  521. predefined MID$ function
  522. SYNTAX: MID$( string$, start-position-in-string[, number-of-spaces ] )
  523. ***************************************************************/
  524. #if ANSI_C
  525. struct bwb_variable *
  526. fnc_mid( int argc, struct bwb_variable *argv, int unique_id )
  527. #else
  528. struct bwb_variable *
  529. fnc_mid( argc, argv, unique_id )
  530. int argc;
  531. struct bwb_variable *argv;
  532. int unique_id;
  533. #endif
  534. {
  535. static struct bwb_variable nvar;
  536. register int c;
  537. char target_string[ MAXSTRINGSIZE + 1 ];
  538. int target_counter, num_spaces;
  539. char tbuf[ MAXSTRINGSIZE + 1 ];
  540. static int init = FALSE;
  541. /* initialize the variable if necessary */
  542. if ( init == FALSE )
  543. {
  544. init = TRUE;
  545. var_make( &nvar, STRING );
  546. }
  547. /* check arguments */
  548. #if PROG_ERRORS
  549. if ( argc < 2 )
  550. {
  551. sprintf( bwb_ebuf, "Not enough arguments to function MID$()" );
  552. bwb_error( bwb_ebuf );
  553. return &nvar;
  554. }
  555. if ( argc > 3 )
  556. {
  557. sprintf( bwb_ebuf, "Two many arguments to function MID$()" );
  558. bwb_error( bwb_ebuf );
  559. return &nvar;
  560. }
  561. #else
  562. if ( fnc_checkargs( argc, argv, 2, 3 ) == FALSE )
  563. {
  564. return NULL;
  565. }
  566. #endif
  567. /* get arguments */
  568. str_btoc( target_string, var_getsval( &( argv[ 0 ] ) ));
  569. target_counter = (int) var_getnval( &( argv[ 1 ] ) ) - 1;
  570. if ( target_counter > (int) strlen( target_string ))
  571. {
  572. tbuf[ 0 ] = '\0';
  573. str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  574. return &nvar;
  575. }
  576. if ( argc == 3 )
  577. {
  578. num_spaces = (int) var_getnval( &( argv[ 2 ] ));
  579. }
  580. else
  581. {
  582. num_spaces = MAXSTRINGSIZE;
  583. }
  584. #if INTENSIVE_DEBUG
  585. sprintf( bwb_ebuf, "in fnc_mid() string <%s> startpos <%d> spaces <%d>",
  586. target_string, target_counter, num_spaces );
  587. bwb_debug( bwb_ebuf );
  588. #endif
  589. c = 0;
  590. tbuf[ c ] = '\0';
  591. while ( ( c < num_spaces ) && ( target_string[ target_counter ] != '\0' ))
  592. {
  593. tbuf[ c ] = target_string[ target_counter ];
  594. ++c;
  595. tbuf[ c ] = '\0';
  596. ++target_counter;
  597. }
  598. str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  599. return &nvar;
  600. }
  601. /***************************************************************
  602. FUNCTION: fnc_left()
  603. DESCRIPTION: This C function implements the BASIC
  604. predefined LEFT$ function
  605. SYNTAX: LEFT$( string$, number-of-spaces )
  606. ***************************************************************/
  607. #if ANSI_C
  608. struct bwb_variable *
  609. fnc_left( int argc, struct bwb_variable *argv, int unique_id )
  610. #else
  611. struct bwb_variable *
  612. fnc_left( argc, argv, unique_id )
  613. int argc;
  614. struct bwb_variable *argv;
  615. int unique_id;
  616. #endif
  617. {
  618. static struct bwb_variable nvar;
  619. register int c;
  620. char target_string[ MAXSTRINGSIZE + 1 ];
  621. int target_counter, num_spaces;
  622. char tbuf[ MAXSTRINGSIZE + 1 ];
  623. static int init = FALSE;
  624. /* initialize the variable if necessary */
  625. if ( init == FALSE )
  626. {
  627. init = TRUE;
  628. var_make( &nvar, STRING );
  629. }
  630. /* check arguments */
  631. #if PROG_ERRORS
  632. if ( argc < 2 )
  633. {
  634. sprintf( bwb_ebuf, "Not enough arguments to function LEFT$()" );
  635. bwb_error( bwb_ebuf );
  636. return &nvar;
  637. }
  638. if ( argc > 2 )
  639. {
  640. sprintf( bwb_ebuf, "Two many arguments to function LEFT$()" );
  641. bwb_error( bwb_ebuf );
  642. return &nvar;
  643. }
  644. #else
  645. if ( fnc_checkargs( argc, argv, 2, 2 ) == FALSE )
  646. {
  647. return NULL;
  648. }
  649. #endif
  650. /* get arguments */
  651. str_btoc( tbuf, var_getsval( &( argv[ 0 ] ) ));
  652. target_counter = 0;
  653. num_spaces = (int) var_getnval( &( argv[ 1 ] ));
  654. #if INTENSIVE_DEBUG
  655. sprintf( bwb_ebuf, "in fnc_left() string <%s> startpos <%d> spaces <%d>",
  656. tbuf, target_counter, num_spaces );
  657. bwb_debug( bwb_ebuf );
  658. #endif
  659. c = 0;
  660. target_string[ 0 ] = '\0';
  661. while (( c < num_spaces ) && ( tbuf[ c ] != '\0' ))
  662. {
  663. target_string[ target_counter ] = tbuf[ c ];
  664. ++target_counter;
  665. target_string[ target_counter ] = '\0';
  666. ++c;
  667. }
  668. str_ctob( var_findsval( &nvar, nvar.array_pos ), target_string );
  669. return &nvar;
  670. }
  671. /***************************************************************
  672. FUNCTION: fnc_right()
  673. DESCRIPTION: This C function implements the BASIC
  674. predefined RIGHT$ function
  675. SYNTAX: RIGHT$( string$, number-of-spaces )
  676. ***************************************************************/
  677. #if ANSI_C
  678. struct bwb_variable *
  679. fnc_right( int argc, struct bwb_variable *argv, int unique_id )
  680. #else
  681. struct bwb_variable *
  682. fnc_right( argc, argv, unique_id )
  683. int argc;
  684. struct bwb_variable *argv;
  685. int unique_id;
  686. #endif
  687. {
  688. static struct bwb_variable nvar;
  689. register int c;
  690. char target_string[ MAXSTRINGSIZE + 1 ];
  691. int target_counter, num_spaces;
  692. char tbuf[ MAXSTRINGSIZE + 1 ];
  693. static int init = FALSE;
  694. /* initialize the variable if necessary */
  695. if ( init == FALSE )
  696. {
  697. init = TRUE;
  698. var_make( &nvar, STRING );
  699. }
  700. /* check arguments */
  701. #if PROG_ERRORS
  702. if ( argc < 2 )
  703. {
  704. sprintf( bwb_ebuf, "Not enough arguments to function RIGHT$()" );
  705. bwb_error( bwb_ebuf );
  706. return &nvar;
  707. }
  708. if ( argc > 2 )
  709. {
  710. sprintf( bwb_ebuf, "Two many arguments to function RIGHT$()" );
  711. bwb_error( bwb_ebuf );
  712. return &nvar;
  713. }
  714. #else
  715. if ( fnc_checkargs( argc, argv, 2, 2 ) == FALSE )
  716. {
  717. return NULL;
  718. }
  719. #endif
  720. /* get arguments */
  721. str_btoc( target_string, var_getsval( &( argv[ 0 ] ) ));
  722. target_counter = strlen( target_string ) - (int) var_getnval( &( argv[ 1 ] ));
  723. num_spaces = MAXSTRINGSIZE;
  724. #if INTENSIVE_DEBUG
  725. sprintf( bwb_ebuf, "in fnc_right() string <%s> startpos <%d> spaces <%d>",
  726. target_string, target_counter, num_spaces );
  727. bwb_debug( bwb_ebuf );
  728. #endif
  729. c = 0;
  730. tbuf[ c ] = '\0';
  731. while ( ( c < num_spaces ) && ( target_string[ target_counter ] != '\0' ))
  732. {
  733. tbuf[ c ] = target_string[ target_counter ];
  734. ++c;
  735. tbuf[ c ] = '\0';
  736. ++target_counter;
  737. }
  738. str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  739. return &nvar;
  740. }
  741. /***************************************************************
  742. FUNCTION: fnc_asc()
  743. DESCRIPTION: This function implements the predefined
  744. BASIC ASC() function, returning the ASCII
  745. number associated with the first character
  746. in the string argument.
  747. SYNTAX: ASC( string$ )
  748. ***************************************************************/
  749. #if ANSI_C
  750. struct bwb_variable *
  751. fnc_asc( int argc, struct bwb_variable *argv, int unique_id )
  752. #else
  753. struct bwb_variable *
  754. fnc_asc( argc, argv, unique_id )
  755. int argc;
  756. struct bwb_variable *argv;
  757. int unique_id;
  758. #endif
  759. {
  760. static struct bwb_variable nvar;
  761. static char *tbuf;
  762. static int init = FALSE;
  763. /* initialize the variable if necessary */
  764. if ( init == FALSE )
  765. {
  766. init = TRUE;
  767. var_make( &nvar, NUMBER );
  768. /* Revised to CALLOC pass-thru call by JBV */
  769. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_asc" )) == NULL )
  770. {
  771. #if PROG_ERRORS
  772. bwb_error( "in fnc_asc(): failed to get memory for tbuf" );
  773. #else
  774. bwb_error( err_getmem );
  775. #endif
  776. }
  777. }
  778. /* check parameters */
  779. #if PROG_ERRORS
  780. if ( argc < 1 )
  781. {
  782. sprintf( bwb_ebuf, "Not enough parameters (%d) to function ASC().",
  783. argc );
  784. bwb_error( bwb_ebuf );
  785. return NULL;
  786. }
  787. else if ( argc > 1 )
  788. {
  789. sprintf( bwb_ebuf, "Too many parameters (%d) to function ASC().",
  790. argc );
  791. bwb_error( bwb_ebuf );
  792. return NULL;
  793. }
  794. #else
  795. if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  796. {
  797. return NULL;
  798. }
  799. #endif
  800. if ( argv[ 0 ].type != STRING )
  801. {
  802. #if PROG_ERRORS
  803. sprintf( bwb_ebuf, "Argument to function ASC() must be a string." );
  804. bwb_error( bwb_ebuf );
  805. #else
  806. bwb_error( err_mismatch );
  807. #endif
  808. return NULL;
  809. }
  810. /* assign ASCII value of first character in the buffer */
  811. str_btoc( tbuf, var_findsval( &( argv[ 0 ] ), argv[ 0 ].array_pos ) );
  812. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) tbuf[ 0 ];
  813. #if INTENSIVE_DEBUG
  814. sprintf( bwb_ebuf, "in fnc_asc(): string is <%s>",
  815. tbuf );
  816. bwb_debug( bwb_ebuf );
  817. #endif
  818. return &nvar;
  819. }
  820. /***************************************************************
  821. FUNCTION: fnc_string()
  822. DESCRIPTION: This C function implements the BASIC
  823. STRING$() function.
  824. SYNTAX: STRING$( number, ascii-value|string$ )
  825. ***************************************************************/
  826. #if ANSI_C
  827. struct bwb_variable *
  828. fnc_string( int argc, struct bwb_variable *argv, int unique_id )
  829. #else
  830. struct bwb_variable *
  831. fnc_string( argc, argv, unique_id )
  832. int argc;
  833. struct bwb_variable *argv;
  834. int unique_id;
  835. #endif
  836. {
  837. static struct bwb_variable nvar;
  838. int length;
  839. register int i;
  840. char c;
  841. static char *tbuf;
  842. static int init = FALSE;
  843. /* initialize the variable if necessary */
  844. if ( init == FALSE )
  845. {
  846. init = TRUE;
  847. var_make( &nvar, STRING );
  848. /* Revised to CALLOC pass-thru call by JBV */
  849. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_string" )) == NULL )
  850. {
  851. #if PROG_ERRORS
  852. bwb_error( "in fnc_string(): failed to get memory for tbuf" );
  853. #else
  854. bwb_error( err_getmem );
  855. #endif
  856. }
  857. }
  858. /* check for correct number of parameters */
  859. #if PROG_ERRORS
  860. if ( argc < 2 )
  861. {
  862. sprintf( bwb_ebuf, "Not enough parameters (%d) to function STRING$().",
  863. argc );
  864. bwb_error( bwb_ebuf );
  865. return NULL;
  866. }
  867. else if ( argc > 2 )
  868. {
  869. sprintf( bwb_ebuf, "Too many parameters (%d) to function STRING$().",
  870. argc );
  871. bwb_error( bwb_ebuf );
  872. return NULL;
  873. }
  874. #else
  875. if ( fnc_checkargs( argc, argv, 2, 2 ) == FALSE )
  876. {
  877. return NULL;
  878. }
  879. #endif
  880. strcpy( nvar.name, "(string$)!" );
  881. nvar.type = STRING;
  882. tbuf[ 0 ] = '\0';
  883. length = (int) var_getnval( &( argv[ 0 ] ));
  884. if ( argv[ 1 ].type == STRING )
  885. {
  886. str_btoc( tbuf, var_getsval( &( argv[ 1 ] )));
  887. c = tbuf[ 0 ];
  888. }
  889. else
  890. {
  891. c = (char) var_getnval( &( argv[ 1 ] ) );
  892. }
  893. #if INTENSIVE_DEBUG
  894. sprintf( bwb_ebuf, "in fnc_string(): argument <%s> arg type <%c>, length <%d>",
  895. tbuf, argv[ 1 ].type, length );
  896. bwb_debug( bwb_ebuf );
  897. sprintf( bwb_ebuf, "in fnc_string(): type <%c>, c <0x%x>=<%c>",
  898. argv[ 1 ].type, c, c );
  899. bwb_debug( bwb_ebuf );
  900. #endif
  901. /* add characters to the string */
  902. for ( i = 0; i < length; ++i )
  903. {
  904. tbuf[ i ] = c;
  905. tbuf[ i + 1 ] = '\0';
  906. }
  907. str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
  908. return &nvar;
  909. }
  910. /***************************************************************
  911. FUNCTION: fnc_instr()
  912. DESCRIPTION: This C function implements the BASIC
  913. INSTR() function, returning the position
  914. in string string-searched$ at which
  915. string-pattern$ occurs.
  916. SYNTAX: INSTR( [start-position,] string-searched$, string-pattern$ )
  917. ***************************************************************/
  918. #if ANSI_C
  919. struct bwb_variable *
  920. fnc_instr( int argc, struct bwb_variable *argv, int unique_id )
  921. #else
  922. struct bwb_variable *
  923. fnc_instr( argc, argv, unique_id )
  924. int argc;
  925. struct bwb_variable *argv;
  926. int unique_id;
  927. #endif
  928. {
  929. static struct bwb_variable nvar;
  930. static int init = FALSE;
  931. int n_pos, x_pos, y_pos;
  932. int start_pos;
  933. register int n;
  934. char xbuf[ MAXSTRINGSIZE + 1 ];
  935. char ybuf[ MAXSTRINGSIZE + 1 ];
  936. /* initialize the variable if necessary */
  937. if ( init == FALSE )
  938. {
  939. init = TRUE;
  940. var_make( &nvar, NUMBER );
  941. }
  942. /* check for correct number of parameters */
  943. #if PROG_ERRORS
  944. if ( argc < 2 )
  945. {
  946. sprintf( bwb_ebuf, "Not enough parameters (%d) to function INSTR().",
  947. argc );
  948. bwb_error( bwb_ebuf );
  949. return NULL;
  950. }
  951. else if ( argc > 3 )
  952. {
  953. sprintf( bwb_ebuf, "Too many parameters (%d) to function INSTR().",
  954. argc );
  955. bwb_error( bwb_ebuf );
  956. return NULL;
  957. }
  958. #else
  959. if ( fnc_checkargs( argc, argv, 2, 3 ) == FALSE )
  960. {
  961. return NULL;
  962. }
  963. #endif
  964. /* determine argument positions */
  965. if ( argc == 3 )
  966. {
  967. n_pos = 0;
  968. x_pos = 1;
  969. y_pos = 2;
  970. }
  971. else
  972. {
  973. n_pos = -1;
  974. x_pos = 0;
  975. y_pos = 1;
  976. }
  977. /* determine starting position */
  978. if ( n_pos == 0 )
  979. {
  980. start_pos = (int) var_getnval( &( argv[ n_pos ] ) ) - 1;
  981. }
  982. else
  983. {
  984. start_pos = 0;
  985. }
  986. /* get x and y strings */
  987. str_btoc( xbuf, var_getsval( &( argv[ x_pos ] ) ) );
  988. str_btoc( ybuf, var_getsval( &( argv[ y_pos ] ) ) );
  989. /* now search for match */
  990. for ( n = start_pos; n < (int) strlen( xbuf ); ++n )
  991. {
  992. if ( strncmp( &( xbuf[ n ] ), ybuf, strlen( ybuf ) ) == 0 )
  993. {
  994. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) n + 1;
  995. return &nvar;
  996. }
  997. }
  998. /* match not found */
  999. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) 0;
  1000. return &nvar;
  1001. }
  1002. /***************************************************************
  1003. FUNCTION: fnc_spc()
  1004. DESCRIPTION: This C function implements the BASIC
  1005. SPC() function, returning a string
  1006. containing a specified number of
  1007. (blank) spaces.
  1008. SYNTAX: SPC( number )
  1009. ***************************************************************/
  1010. #if ANSI_C
  1011. struct bwb_variable *
  1012. fnc_spc( int argc, struct bwb_variable *argv, int unique_id )
  1013. #else
  1014. struct bwb_variable *
  1015. fnc_spc( argc, argv, unique_id )
  1016. int argc;
  1017. struct bwb_variable *argv;
  1018. int unique_id;
  1019. #endif
  1020. {
  1021. return fnc_space( argc, argv, unique_id );
  1022. }
  1023. /***************************************************************
  1024. FUNCTION: fnc_space()
  1025. DESCRIPTION: This C function implements the BASIC
  1026. SPACE() function, returning a string
  1027. containing a specified number of
  1028. (blank) spaces.
  1029. SYNTAX: SPACE$( number )
  1030. ***************************************************************/
  1031. #if ANSI_C
  1032. struct bwb_variable *
  1033. fnc_space( int argc, struct bwb_variable *argv, int unique_id )
  1034. #else
  1035. struct bwb_variable *
  1036. fnc_space( argc, argv, unique_id )
  1037. int argc;
  1038. struct bwb_variable *argv;
  1039. int unique_id;
  1040. #endif
  1041. {
  1042. static struct bwb_variable nvar;
  1043. static char *tbuf;
  1044. static int init = FALSE;
  1045. int spaces;
  1046. register int i;
  1047. bstring *b;
  1048. /* check for correct number of parameters */
  1049. if ( argc < 1 )
  1050. {
  1051. #if PROG_ERRORS
  1052. sprintf( bwb_ebuf, "Not enough parameters (%d) to function SPACE$().",
  1053. argc );
  1054. bwb_error( bwb_ebuf );
  1055. #else
  1056. bwb_error( err_syntax );
  1057. #endif
  1058. break_handler();
  1059. return NULL;
  1060. }
  1061. else if ( argc > 1 )
  1062. {
  1063. #if PROG_ERRORS
  1064. sprintf( bwb_ebuf, "Too many parameters (%d) to function SPACE$().",
  1065. argc );
  1066. bwb_error( bwb_ebuf );
  1067. #else
  1068. bwb_error( err_syntax );
  1069. #endif
  1070. break_handler();
  1071. return NULL;
  1072. }
  1073. /* initialize nvar if necessary */
  1074. if ( init == FALSE )
  1075. {
  1076. init = TRUE;
  1077. var_make( &nvar, (int) STRING );
  1078. /* Revised to CALLOC pass-thru call by JBV */
  1079. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_space" )) == NULL )
  1080. {
  1081. #if PROG_ERRORS
  1082. bwb_error( "in fnc_space(): failed to get memory for tbuf" );
  1083. #else
  1084. bwb_error( err_getmem );
  1085. #endif
  1086. }
  1087. }
  1088. tbuf[ 0 ] = '\0';
  1089. spaces = (int) var_getnval( &( argv[ 0 ] ));
  1090. /* add spaces to the string */
  1091. for ( i = 0; i < spaces; ++i )
  1092. {
  1093. tbuf[ i ] = ' ';
  1094. tbuf[ i + 1 ] = '\0';
  1095. }
  1096. b = var_getsval( &nvar );
  1097. str_ctob( b, tbuf );
  1098. return &nvar;
  1099. }
  1100. /***************************************************************
  1101. FUNCTION: fnc_environ()
  1102. DESCRIPTION: This C function implements the BASIC
  1103. ENVIRON$() function, returning the value
  1104. of a specified environment string.
  1105. SYNTAX: ENVIRON$( variable-string )
  1106. ***************************************************************/
  1107. #if ANSI_C
  1108. struct bwb_variable *
  1109. fnc_environ( int argc, struct bwb_variable *argv, int unique_id )
  1110. #else
  1111. struct bwb_variable *
  1112. fnc_environ( argc, argv, unique_id )
  1113. int argc;
  1114. struct bwb_variable *argv;
  1115. int unique_id;
  1116. #endif
  1117. {
  1118. char tbuf[ MAXSTRINGSIZE + 1 ];
  1119. char tmp[ MAXSTRINGSIZE + 1 ];
  1120. static struct bwb_variable nvar;
  1121. static int init = FALSE;
  1122. /* initialize the variable if necessary */
  1123. if ( init == FALSE )
  1124. {
  1125. init = TRUE;
  1126. var_make( &nvar, STRING );
  1127. }
  1128. /* check for correct number of parameters */
  1129. #if PROG_ERRORS
  1130. if ( argc < 1 )
  1131. {
  1132. sprintf( bwb_ebuf, "Not enough parameters (%d) to function ENVIRON$().",
  1133. argc );
  1134. bwb_error( bwb_ebuf );
  1135. return NULL;
  1136. }
  1137. else if ( argc > 1 )
  1138. {
  1139. sprintf( bwb_ebuf, "Too many parameters (%d) to function ENVIRON$().",
  1140. argc );
  1141. bwb_error( bwb_ebuf );
  1142. return NULL;
  1143. }
  1144. #else
  1145. if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
  1146. {
  1147. return NULL;
  1148. }
  1149. #endif
  1150. /* resolve the argument and place string value in tbuf */
  1151. str_btoc( tbuf, var_getsval( &( argv[ 0 ] )));
  1152. /* call getenv() then write value to string */
  1153. strcpy( tmp, getenv( tbuf ));
  1154. str_ctob( var_findsval( &nvar, nvar.array_pos ), tmp );
  1155. /* return address of nvar */
  1156. return &nvar;
  1157. }
  1158. /***************************************************************
  1159. FUNCTION: fnc_err()
  1160. DESCRIPTION: This C function implements the BASIC
  1161. ERR function, returning the error number
  1162. for the most recent error.
  1163. Please note that as of revision level
  1164. 2.10, bwBASIC does not utilize a standard
  1165. list of error numbers, so numbers returned
  1166. by this function will not be those found
  1167. in either ANSI or Microsoft or other
  1168. BASIC error tables.
  1169. SYNTAX: ERR
  1170. ***************************************************************/
  1171. #if ANSI_C
  1172. struct bwb_variable *
  1173. fnc_err( int argc, struct bwb_variable *argv, int unique_id )
  1174. #else
  1175. struct bwb_variable *
  1176. fnc_err( argc, argv, unique_id )
  1177. int argc;
  1178. struct bwb_variable *argv;
  1179. int unique_id;
  1180. #endif
  1181. {
  1182. static struct bwb_variable nvar;
  1183. static int init = FALSE;
  1184. /* initialize nvar if necessary */
  1185. if ( init == FALSE )
  1186. {
  1187. init = TRUE;
  1188. var_make( &nvar, (int) NUMBER );
  1189. }
  1190. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) err_number;
  1191. return &nvar;
  1192. }
  1193. /***************************************************************
  1194. FUNCTION: fnc_erl()
  1195. DESCRIPTION: This C function implements the BASIC
  1196. ERL function, returning the line number
  1197. for the most recent error.
  1198. SYNTAX: ERL
  1199. ***************************************************************/
  1200. #if ANSI_C
  1201. struct bwb_variable *
  1202. fnc_erl( int argc, struct bwb_variable *argv, int unique_id )
  1203. #else
  1204. struct bwb_variable *
  1205. fnc_erl( argc, argv, unique_id )
  1206. int argc;
  1207. struct bwb_variable *argv;
  1208. int unique_id;
  1209. #endif
  1210. {
  1211. static struct bwb_variable nvar;
  1212. static int init = FALSE;
  1213. /* initialize nvar if necessary */
  1214. if ( init == FALSE )
  1215. {
  1216. init = TRUE;
  1217. var_make( &nvar, (int) NUMBER );
  1218. }
  1219. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) err_line;
  1220. return &nvar;
  1221. }
  1222. /***************************************************************
  1223. FUNCTION: fnc_loc()
  1224. DESCRIPTION: This C function implements the BASIC
  1225. LOC() function. As implemented here,
  1226. this only works for random-acess files.
  1227. SYNTAX: LOC( device-number )
  1228. ***************************************************************/
  1229. #if ANSI_C
  1230. struct bwb_variable *
  1231. fnc_loc( int argc, struct bwb_variable *argv, int unique_id )
  1232. #else
  1233. struct bwb_variable *
  1234. fnc_loc( argc, argv, unique_id )
  1235. int argc;
  1236. struct bwb_variable *argv;
  1237. int unique_id;
  1238. #endif
  1239. {
  1240. static struct bwb_variable nvar;
  1241. static int init = FALSE;
  1242. int dev_number;
  1243. #if INTENSIVE_DEBUG
  1244. sprintf( bwb_ebuf, "in fnc_loc(): received f_arg <%f> ",
  1245. var_getnval( &( argv[ 0 ] ) ) );
  1246. bwb_debug( bwb_ebuf );
  1247. #endif
  1248. if ( argc < 1 )
  1249. {
  1250. #if PROG_ERRORS
  1251. sprintf( bwb_ebuf, "Not enough parameters (%d) to function LOC().",
  1252. argc );
  1253. bwb_error( bwb_ebuf );
  1254. #else
  1255. bwb_error( err_syntax );
  1256. #endif
  1257. return NULL;
  1258. }
  1259. else if ( argc > 1 )
  1260. {
  1261. #if PROG_ERRORS
  1262. sprintf( bwb_ebuf, "Too many parameters (%d) to function LOC().",
  1263. argc );
  1264. bwb_error( bwb_ebuf );
  1265. #else
  1266. bwb_error( err_syntax );
  1267. #endif
  1268. return NULL;
  1269. }
  1270. dev_number = (int) var_getnval( &( argv[ 0 ] ) );
  1271. if ( init == FALSE )
  1272. {
  1273. init = TRUE;
  1274. var_make( &nvar, NUMBER );
  1275. }
  1276. /* note if this is the very beginning of the file */
  1277. if ( dev_table[ dev_number ].loc == 0 )
  1278. {
  1279. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) 0;
  1280. }
  1281. else
  1282. {
  1283. * var_findnval( &nvar, nvar.array_pos ) =
  1284. (bnumber) dev_table[ dev_number ].next_record;
  1285. }
  1286. return &nvar;
  1287. }
  1288. /***************************************************************
  1289. FUNCTION: fnc_eof()
  1290. DESCRIPTION: This C function implements the BASIC
  1291. EOF() function.
  1292. SYNTAX: EOF( device-number )
  1293. ***************************************************************/
  1294. #if ANSI_C
  1295. struct bwb_variable *
  1296. fnc_eof( int argc, struct bwb_variable *argv, int unique_id )
  1297. #else
  1298. struct bwb_variable *
  1299. fnc_eof( argc, argv, unique_id )
  1300. int argc;
  1301. struct bwb_variable *argv;
  1302. int unique_id;
  1303. #endif
  1304. {
  1305. static struct bwb_variable nvar;
  1306. static int init = FALSE;
  1307. int dev_number;
  1308. int cur_pos, end_pos; /* JBV */
  1309. #if INTENSIVE_DEBUG
  1310. sprintf( bwb_ebuf, "in fnc_loc(): received f_arg <%f> ",
  1311. var_getnval( &( argv[ 0 ] ) ) );
  1312. bwb_debug( bwb_ebuf );
  1313. #endif
  1314. if ( argc < 1 )
  1315. {
  1316. #if PROG_ERRORS
  1317. sprintf( bwb_ebuf, "Not enough parameters (%d) to function EOF().",
  1318. argc );
  1319. bwb_error( bwb_ebuf );
  1320. #else
  1321. bwb_error( err_syntax );
  1322. #endif
  1323. return NULL;
  1324. }
  1325. else if ( argc > 1 )
  1326. {
  1327. #if PROG_ERRORS
  1328. sprintf( bwb_ebuf, "Too many parameters (%d) to function EOF().",
  1329. argc );
  1330. bwb_error( bwb_ebuf );
  1331. #else
  1332. bwb_error( err_syntax );
  1333. #endif
  1334. return NULL;
  1335. }
  1336. dev_number = (int) var_getnval( &( argv[ 0 ] ) );
  1337. if ( init == FALSE )
  1338. {
  1339. init = TRUE;
  1340. var_make( &nvar, NUMBER );
  1341. }
  1342. /* note if this is the very beginning of the file */
  1343. if ( dev_table[ dev_number ].mode == DEVMODE_AVAILABLE )
  1344. {
  1345. bwb_error( err_devnum );
  1346. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) TRUE;
  1347. }
  1348. else if ( dev_table[ dev_number ].mode == DEVMODE_CLOSED )
  1349. {
  1350. bwb_error( err_devnum );
  1351. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) TRUE;
  1352. }
  1353. /*------------------------------------------------------*/
  1354. /* feof() finds EOF when you read past the end of file. */
  1355. /* This is not how BASIC works, at least not GWBASIC. */
  1356. /* The EOF function should return an EOF indication */
  1357. /* when you are <at> the end of the file, not past it. */
  1358. /* This routine was modified to reflect this. */
  1359. /* (JBV, 10/15/95) */
  1360. /*------------------------------------------------------*/
  1361. /* else if ( feof( dev_table[ dev_number ].cfp ) == 0 ) */
  1362. else if ( ftell( dev_table[ dev_number ].cfp ) !=
  1363. dev_table [ dev_number ].lof )
  1364. {
  1365. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) FALSE;
  1366. }
  1367. else
  1368. {
  1369. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) TRUE;
  1370. }
  1371. return &nvar;
  1372. }
  1373. /***************************************************************
  1374. FUNCTION: fnc_lof()
  1375. DESCRIPTION: This C function implements the BASIC
  1376. LOF() function.
  1377. SYNTAX: LOF( device-number )
  1378. ***************************************************************/
  1379. #if ANSI_C
  1380. struct bwb_variable *
  1381. fnc_lof( int argc, struct bwb_variable *argv, int unique_id )
  1382. #else
  1383. struct bwb_variable *
  1384. fnc_lof( argc, argv, unique_id )
  1385. int argc;
  1386. struct bwb_variable *argv;
  1387. int unique_id;
  1388. #endif
  1389. {
  1390. static struct bwb_variable nvar;
  1391. static int init = FALSE;
  1392. int dev_number;
  1393. /* Following section no longer needed, removed by JBV */
  1394. /* #if UNIX_CMDS
  1395. static struct stat statbuf;
  1396. int r;
  1397. #endif */
  1398. #if INTENSIVE_DEBUG
  1399. sprintf( bwb_ebuf, "in fnc_lof(): received f_arg <%f> ",
  1400. var_getnval( &( argv[ 0 ] ) ) );
  1401. bwb_debug( bwb_ebuf );
  1402. #endif
  1403. if ( argc < 1 )
  1404. {
  1405. #if PROG_ERRORS
  1406. sprintf( bwb_ebuf, "Not enough parameters (%d) to function LOF().",
  1407. argc );
  1408. bwb_error( bwb_ebuf );
  1409. #else
  1410. bwb_error( err_syntax );
  1411. #endif
  1412. return NULL;
  1413. }
  1414. else if ( argc > 1 )
  1415. {
  1416. #if PROG_ERRORS
  1417. sprintf( bwb_ebuf, "Too many parameters (%d) to function LOF().",
  1418. argc );
  1419. bwb_error( bwb_ebuf );
  1420. #else
  1421. bwb_error( err_syntax );
  1422. #endif
  1423. return NULL;
  1424. }
  1425. dev_number = (int) var_getnval( &( argv[ 0 ] ) );
  1426. if ( init == FALSE )
  1427. {
  1428. init = TRUE;
  1429. var_make( &nvar, NUMBER );
  1430. }
  1431. /* stat the file */
  1432. /* Following section no longer needed, removed by JBV */
  1433. /* #if UNIX_CMDS
  1434. r = stat( dev_table[ dev_number ].filename, &statbuf );
  1435. if ( r != 0 )
  1436. {
  1437. #if PROG_ERRORS
  1438. sprintf( bwb_ebuf, "in fnc_lof(): failed to find file <%s>",
  1439. dev_table[ dev_number ].filename );
  1440. bwb_error( bwb_ebuf );
  1441. #else
  1442. sprintf( bwb_ebuf, ERR_OPENFILE,
  1443. dev_table[ dev_number ].filename );
  1444. bwb_error( bwb_ebuf );
  1445. #endif
  1446. return NULL;
  1447. }
  1448. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) statbuf.st_size; */
  1449. /* #else */ /* Removed by JBV, no longer needed */
  1450. /* * var_findnval( &nvar, nvar.array_pos ) = (bnumber) FALSE; */
  1451. * var_findnval( &nvar, nvar.array_pos ) =
  1452. (bnumber) dev_table[ dev_number ].lof; /* JBV */
  1453. /* #endif */ /* Removed by JBV, no longer needed */
  1454. return &nvar;
  1455. }
  1456. #endif /* MS_FUNCS */
  1457. /***************************************************************
  1458. FUNCTION: fnc_test()
  1459. DESCRIPTION: This is a test function, developed in
  1460. order to test argument passing to
  1461. BASIC functions.
  1462. ***************************************************************/
  1463. #if INTENSIVE_DEBUG
  1464. #if ANSI_C
  1465. struct bwb_variable *
  1466. fnc_test( int argc, struct bwb_variable *argv, int unique_id )
  1467. #else
  1468. struct bwb_variable *
  1469. fnc_test( argc, argv, unique_id )
  1470. int argc;
  1471. struct bwb_variable *argv;
  1472. int unique_id;
  1473. #endif
  1474. {
  1475. register int c;
  1476. static struct bwb_variable rvar;
  1477. static char *tbuf;
  1478. static int init = FALSE;
  1479. /* initialize the variable if necessary */
  1480. if ( init == FALSE )
  1481. {
  1482. init = TRUE;
  1483. var_make( &rvar, NUMBER );
  1484. /* Revised to CALLOC pass-thru call by JBV */
  1485. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_test" )) == NULL )
  1486. {
  1487. #if PROG_ERRORS
  1488. bwb_error( "in fnc_test(): failed to get memory for tbuf" );
  1489. #else
  1490. bwb_error( err_getmem );
  1491. #endif
  1492. }
  1493. }
  1494. sprintf( bwb_ebuf, "TEST function: received %d arguments: \n", argc );
  1495. prn_xprintf( stderr, bwb_ebuf );
  1496. for ( c = 0; c < argc; ++c )
  1497. {
  1498. str_btoc( tbuf, var_getsval( &argv[ c ] ) );
  1499. sprintf( bwb_ebuf, " arg %d (%c): <%s> \n", c,
  1500. argv[ c ].type, tbuf );
  1501. prn_xprintf( stderr, bwb_ebuf );
  1502. }
  1503. return &rvar;
  1504. }
  1505. #endif
  1506. /***************************************************************
  1507. FUNCTION: fnc_checkargs()
  1508. DESCRIPTION: This C function checks the arguments to
  1509. functions.
  1510. ***************************************************************/
  1511. #if PROG_ERRORS
  1512. #else
  1513. #if ANSI_C
  1514. int
  1515. fnc_checkargs( int argc, struct bwb_variable *argv, int min, int max )
  1516. #else
  1517. int
  1518. fnc_checkargs( argc, argv, min, max )
  1519. int argc;
  1520. struct bwb_variable *argv;
  1521. int min;
  1522. int max;
  1523. #endif
  1524. {
  1525. if ( argc < min )
  1526. {
  1527. bwb_error( err_syntax );
  1528. return FALSE;
  1529. }
  1530. if ( argc > max )
  1531. {
  1532. bwb_error( err_syntax );
  1533. return FALSE;
  1534. }
  1535. return TRUE;
  1536. }
  1537. #endif
  1538. /***************************************************************
  1539. FUNCTION: fnc_fncs()
  1540. DESCRIPTION: This C function is used for debugging
  1541. purposes; it prints a list of all defined
  1542. functions.
  1543. SYNTAX: FNCS
  1544. ***************************************************************/
  1545. #if PERMANENT_DEBUG
  1546. #if ANSI_C
  1547. struct bwb_line *
  1548. bwb_fncs( struct bwb_line *l )
  1549. #else
  1550. struct bwb_line *
  1551. bwb_fncs( l )
  1552. struct bwb_line *l;
  1553. #endif
  1554. {
  1555. struct bwb_function *f;
  1556. for ( f = CURTASK fnc_start.next; f != &CURTASK fnc_end; f = f->next )
  1557. {
  1558. sprintf( bwb_ebuf, "%s\t%c \n", f->name, f->type );
  1559. prn_xprintf( stderr, bwb_ebuf );
  1560. }
  1561. return bwb_zline( l );
  1562. }
  1563. #endif