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.
 
 
 
 
 
 

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