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.
 
 
 
 
 
 

1957 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 HAVE_SYSSTAT
  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. /*--------------------------------------------------------------------*/
  1154. /* Added check for getenv return value to prevent segmentation faults */
  1155. /* JBV 3/15/96 */
  1156. /*--------------------------------------------------------------------*/
  1157. if (getenv( tbuf ) != NULL) strcpy( tmp, getenv( tbuf ));
  1158. else strcpy( tmp, "" );
  1159. str_ctob( var_findsval( &nvar, nvar.array_pos ), tmp );
  1160. /* return address of nvar */
  1161. return &nvar;
  1162. }
  1163. /***************************************************************
  1164. FUNCTION: fnc_err()
  1165. DESCRIPTION: This C function implements the BASIC
  1166. ERR function, returning the error number
  1167. for the most recent error.
  1168. Please note that as of revision level
  1169. 2.10, bwBASIC does not utilize a standard
  1170. list of error numbers, so numbers returned
  1171. by this function will not be those found
  1172. in either ANSI or Microsoft or other
  1173. BASIC error tables.
  1174. SYNTAX: ERR
  1175. ***************************************************************/
  1176. #if ANSI_C
  1177. struct bwb_variable *
  1178. fnc_err( int argc, struct bwb_variable *argv, int unique_id )
  1179. #else
  1180. struct bwb_variable *
  1181. fnc_err( argc, argv, unique_id )
  1182. int argc;
  1183. struct bwb_variable *argv;
  1184. int unique_id;
  1185. #endif
  1186. {
  1187. static struct bwb_variable nvar;
  1188. static int init = FALSE;
  1189. /* initialize nvar if necessary */
  1190. if ( init == FALSE )
  1191. {
  1192. init = TRUE;
  1193. var_make( &nvar, (int) NUMBER );
  1194. }
  1195. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) err_number;
  1196. return &nvar;
  1197. }
  1198. /***************************************************************
  1199. FUNCTION: fnc_erl()
  1200. DESCRIPTION: This C function implements the BASIC
  1201. ERL function, returning the line number
  1202. for the most recent error.
  1203. SYNTAX: ERL
  1204. ***************************************************************/
  1205. #if ANSI_C
  1206. struct bwb_variable *
  1207. fnc_erl( int argc, struct bwb_variable *argv, int unique_id )
  1208. #else
  1209. struct bwb_variable *
  1210. fnc_erl( argc, argv, unique_id )
  1211. int argc;
  1212. struct bwb_variable *argv;
  1213. int unique_id;
  1214. #endif
  1215. {
  1216. static struct bwb_variable nvar;
  1217. static int init = FALSE;
  1218. /* initialize nvar if necessary */
  1219. if ( init == FALSE )
  1220. {
  1221. init = TRUE;
  1222. var_make( &nvar, (int) NUMBER );
  1223. }
  1224. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) err_line;
  1225. return &nvar;
  1226. }
  1227. /***************************************************************
  1228. FUNCTION: fnc_loc()
  1229. DESCRIPTION: This C function implements the BASIC
  1230. LOC() function. As implemented here,
  1231. this only works for random-acess files.
  1232. SYNTAX: LOC( device-number )
  1233. ***************************************************************/
  1234. #if ANSI_C
  1235. struct bwb_variable *
  1236. fnc_loc( int argc, struct bwb_variable *argv, int unique_id )
  1237. #else
  1238. struct bwb_variable *
  1239. fnc_loc( argc, argv, unique_id )
  1240. int argc;
  1241. struct bwb_variable *argv;
  1242. int unique_id;
  1243. #endif
  1244. {
  1245. static struct bwb_variable nvar;
  1246. static int init = FALSE;
  1247. int dev_number;
  1248. #if INTENSIVE_DEBUG
  1249. sprintf( bwb_ebuf, "in fnc_loc(): received f_arg <%f> ",
  1250. var_getnval( &( argv[ 0 ] ) ) );
  1251. bwb_debug( bwb_ebuf );
  1252. #endif
  1253. if ( argc < 1 )
  1254. {
  1255. #if PROG_ERRORS
  1256. sprintf( bwb_ebuf, "Not enough parameters (%d) to function LOC().",
  1257. argc );
  1258. bwb_error( bwb_ebuf );
  1259. #else
  1260. bwb_error( err_syntax );
  1261. #endif
  1262. return NULL;
  1263. }
  1264. else if ( argc > 1 )
  1265. {
  1266. #if PROG_ERRORS
  1267. sprintf( bwb_ebuf, "Too many parameters (%d) to function LOC().",
  1268. argc );
  1269. bwb_error( bwb_ebuf );
  1270. #else
  1271. bwb_error( err_syntax );
  1272. #endif
  1273. return NULL;
  1274. }
  1275. dev_number = (int) var_getnval( &( argv[ 0 ] ) );
  1276. if ( init == FALSE )
  1277. {
  1278. init = TRUE;
  1279. var_make( &nvar, NUMBER );
  1280. }
  1281. /* note if this is the very beginning of the file */
  1282. if ( dev_table[ dev_number ].loc == 0 )
  1283. {
  1284. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) 0;
  1285. }
  1286. else
  1287. {
  1288. * var_findnval( &nvar, nvar.array_pos ) =
  1289. (bnumber) dev_table[ dev_number ].next_record;
  1290. }
  1291. return &nvar;
  1292. }
  1293. /***************************************************************
  1294. FUNCTION: fnc_eof()
  1295. DESCRIPTION: This C function implements the BASIC
  1296. EOF() function.
  1297. SYNTAX: EOF( device-number )
  1298. ***************************************************************/
  1299. #if ANSI_C
  1300. struct bwb_variable *
  1301. fnc_eof( int argc, struct bwb_variable *argv, int unique_id )
  1302. #else
  1303. struct bwb_variable *
  1304. fnc_eof( argc, argv, unique_id )
  1305. int argc;
  1306. struct bwb_variable *argv;
  1307. int unique_id;
  1308. #endif
  1309. {
  1310. static struct bwb_variable nvar;
  1311. static int init = FALSE;
  1312. int dev_number;
  1313. int cur_pos, end_pos; /* JBV */
  1314. #if INTENSIVE_DEBUG
  1315. sprintf( bwb_ebuf, "in fnc_loc(): received f_arg <%f> ",
  1316. var_getnval( &( argv[ 0 ] ) ) );
  1317. bwb_debug( bwb_ebuf );
  1318. #endif
  1319. if ( argc < 1 )
  1320. {
  1321. #if PROG_ERRORS
  1322. sprintf( bwb_ebuf, "Not enough parameters (%d) to function EOF().",
  1323. argc );
  1324. bwb_error( bwb_ebuf );
  1325. #else
  1326. bwb_error( err_syntax );
  1327. #endif
  1328. return NULL;
  1329. }
  1330. else if ( argc > 1 )
  1331. {
  1332. #if PROG_ERRORS
  1333. sprintf( bwb_ebuf, "Too many parameters (%d) to function EOF().",
  1334. argc );
  1335. bwb_error( bwb_ebuf );
  1336. #else
  1337. bwb_error( err_syntax );
  1338. #endif
  1339. return NULL;
  1340. }
  1341. dev_number = (int) var_getnval( &( argv[ 0 ] ) );
  1342. if ( init == FALSE )
  1343. {
  1344. init = TRUE;
  1345. var_make( &nvar, NUMBER );
  1346. }
  1347. /* note if this is the very beginning of the file */
  1348. if ( dev_table[ dev_number ].mode == DEVMODE_AVAILABLE )
  1349. {
  1350. bwb_error( err_devnum );
  1351. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) TRUE;
  1352. }
  1353. else if ( dev_table[ dev_number ].mode == DEVMODE_CLOSED )
  1354. {
  1355. bwb_error( err_devnum );
  1356. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) TRUE;
  1357. }
  1358. /*------------------------------------------------------*/
  1359. /* feof() finds EOF when you read past the end of file. */
  1360. /* This is not how BASIC works, at least not GWBASIC. */
  1361. /* The EOF function should return an EOF indication */
  1362. /* when you are <at> the end of the file, not past it. */
  1363. /* This routine was modified to reflect this. */
  1364. /* (JBV, 10/15/95) */
  1365. /*------------------------------------------------------*/
  1366. /* else if ( feof( dev_table[ dev_number ].cfp ) == 0 ) */
  1367. else if ( ftell( dev_table[ dev_number ].cfp ) !=
  1368. dev_table [ dev_number ].lof )
  1369. {
  1370. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) FALSE;
  1371. }
  1372. else
  1373. {
  1374. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) TRUE;
  1375. }
  1376. return &nvar;
  1377. }
  1378. /***************************************************************
  1379. FUNCTION: fnc_lof()
  1380. DESCRIPTION: This C function implements the BASIC
  1381. LOF() function.
  1382. SYNTAX: LOF( device-number )
  1383. ***************************************************************/
  1384. #if ANSI_C
  1385. struct bwb_variable *
  1386. fnc_lof( int argc, struct bwb_variable *argv, int unique_id )
  1387. #else
  1388. struct bwb_variable *
  1389. fnc_lof( argc, argv, unique_id )
  1390. int argc;
  1391. struct bwb_variable *argv;
  1392. int unique_id;
  1393. #endif
  1394. {
  1395. static struct bwb_variable nvar;
  1396. static int init = FALSE;
  1397. int dev_number;
  1398. /* Following section no longer needed, removed by JBV */
  1399. /* #if UNIX_CMDS
  1400. static struct stat statbuf;
  1401. int r;
  1402. #endif */
  1403. #if INTENSIVE_DEBUG
  1404. sprintf( bwb_ebuf, "in fnc_lof(): received f_arg <%f> ",
  1405. var_getnval( &( argv[ 0 ] ) ) );
  1406. bwb_debug( bwb_ebuf );
  1407. #endif
  1408. if ( argc < 1 )
  1409. {
  1410. #if PROG_ERRORS
  1411. sprintf( bwb_ebuf, "Not enough parameters (%d) to function LOF().",
  1412. argc );
  1413. bwb_error( bwb_ebuf );
  1414. #else
  1415. bwb_error( err_syntax );
  1416. #endif
  1417. return NULL;
  1418. }
  1419. else if ( argc > 1 )
  1420. {
  1421. #if PROG_ERRORS
  1422. sprintf( bwb_ebuf, "Too many parameters (%d) to function LOF().",
  1423. argc );
  1424. bwb_error( bwb_ebuf );
  1425. #else
  1426. bwb_error( err_syntax );
  1427. #endif
  1428. return NULL;
  1429. }
  1430. dev_number = (int) var_getnval( &( argv[ 0 ] ) );
  1431. if ( init == FALSE )
  1432. {
  1433. init = TRUE;
  1434. var_make( &nvar, NUMBER );
  1435. }
  1436. /* stat the file */
  1437. /* Following section no longer needed, removed by JBV */
  1438. /* #if UNIX_CMDS
  1439. r = stat( dev_table[ dev_number ].filename, &statbuf );
  1440. if ( r != 0 )
  1441. {
  1442. #if PROG_ERRORS
  1443. sprintf( bwb_ebuf, "in fnc_lof(): failed to find file <%s>",
  1444. dev_table[ dev_number ].filename );
  1445. bwb_error( bwb_ebuf );
  1446. #else
  1447. sprintf( bwb_ebuf, ERR_OPENFILE,
  1448. dev_table[ dev_number ].filename );
  1449. bwb_error( bwb_ebuf );
  1450. #endif
  1451. return NULL;
  1452. }
  1453. * var_findnval( &nvar, nvar.array_pos ) = (bnumber) statbuf.st_size; */
  1454. /* #else */ /* Removed by JBV, no longer needed */
  1455. /* * var_findnval( &nvar, nvar.array_pos ) = (bnumber) FALSE; */
  1456. * var_findnval( &nvar, nvar.array_pos ) =
  1457. (bnumber) dev_table[ dev_number ].lof; /* JBV */
  1458. /* #endif */ /* Removed by JBV, no longer needed */
  1459. return &nvar;
  1460. }
  1461. #endif /* MS_FUNCS */
  1462. /***************************************************************
  1463. FUNCTION: fnc_test()
  1464. DESCRIPTION: This is a test function, developed in
  1465. order to test argument passing to
  1466. BASIC functions.
  1467. ***************************************************************/
  1468. #if INTENSIVE_DEBUG
  1469. #if ANSI_C
  1470. struct bwb_variable *
  1471. fnc_test( int argc, struct bwb_variable *argv, int unique_id )
  1472. #else
  1473. struct bwb_variable *
  1474. fnc_test( argc, argv, unique_id )
  1475. int argc;
  1476. struct bwb_variable *argv;
  1477. int unique_id;
  1478. #endif
  1479. {
  1480. register int c;
  1481. static struct bwb_variable rvar;
  1482. static char *tbuf;
  1483. static int init = FALSE;
  1484. /* initialize the variable if necessary */
  1485. if ( init == FALSE )
  1486. {
  1487. init = TRUE;
  1488. var_make( &rvar, NUMBER );
  1489. /* Revised to CALLOC pass-thru call by JBV */
  1490. if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_test" )) == NULL )
  1491. {
  1492. #if PROG_ERRORS
  1493. bwb_error( "in fnc_test(): failed to get memory for tbuf" );
  1494. #else
  1495. bwb_error( err_getmem );
  1496. #endif
  1497. }
  1498. }
  1499. sprintf( bwb_ebuf, "TEST function: received %d arguments: \n", argc );
  1500. prn_xprintf( stderr, bwb_ebuf );
  1501. for ( c = 0; c < argc; ++c )
  1502. {
  1503. str_btoc( tbuf, var_getsval( &argv[ c ] ) );
  1504. sprintf( bwb_ebuf, " arg %d (%c): <%s> \n", c,
  1505. argv[ c ].type, tbuf );
  1506. prn_xprintf( stderr, bwb_ebuf );
  1507. }
  1508. return &rvar;
  1509. }
  1510. #endif
  1511. /***************************************************************
  1512. FUNCTION: fnc_checkargs()
  1513. DESCRIPTION: This C function checks the arguments to
  1514. functions.
  1515. ***************************************************************/
  1516. #if PROG_ERRORS
  1517. #else
  1518. #if ANSI_C
  1519. int
  1520. fnc_checkargs( int argc, struct bwb_variable *argv, int min, int max )
  1521. #else
  1522. int
  1523. fnc_checkargs( argc, argv, min, max )
  1524. int argc;
  1525. struct bwb_variable *argv;
  1526. int min;
  1527. int max;
  1528. #endif
  1529. {
  1530. if ( argc < min )
  1531. {
  1532. bwb_error( err_syntax );
  1533. return FALSE;
  1534. }
  1535. if ( argc > max )
  1536. {
  1537. bwb_error( err_syntax );
  1538. return FALSE;
  1539. }
  1540. return TRUE;
  1541. }
  1542. #endif
  1543. /***************************************************************
  1544. FUNCTION: fnc_fncs()
  1545. DESCRIPTION: This C function is used for debugging
  1546. purposes; it prints a list of all defined
  1547. functions.
  1548. SYNTAX: FNCS
  1549. ***************************************************************/
  1550. #if PERMANENT_DEBUG
  1551. #if ANSI_C
  1552. struct bwb_line *
  1553. bwb_fncs( struct bwb_line *l )
  1554. #else
  1555. struct bwb_line *
  1556. bwb_fncs( l )
  1557. struct bwb_line *l;
  1558. #endif
  1559. {
  1560. struct bwb_function *f;
  1561. for ( f = CURTASK fnc_start.next; f != &CURTASK fnc_end; f = f->next )
  1562. {
  1563. sprintf( bwb_ebuf, "%s\t%c \n", f->name, f->type );
  1564. prn_xprintf( stderr, bwb_ebuf );
  1565. }
  1566. return bwb_zline( l );
  1567. }
  1568. #endif