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.
 
 
 
 
 
 

595 lines
13 KiB

  1. /***************************************************************
  2. bwx_tty.c Environment-dependent implementation
  3. for Bywater BASIC Interpreter
  4. using simple TTY-style input/output
  5. This file should be used as a template
  6. for developing more sophisticated
  7. environment-dependent implementations
  8. Copyright (c) 1993, Ted A. Campbell
  9. Bywater Software
  10. email: tcamp@delphi.com
  11. Copyright and Permissions Information:
  12. All U.S. and international rights are claimed by the author,
  13. Ted A. Campbell.
  14. This software is released under the terms of the GNU General
  15. Public License (GPL), which is distributed with this software
  16. in the file "COPYING". The GPL specifies the terms under
  17. which users may copy and use the software in this distribution.
  18. A separate license is available for commercial distribution,
  19. for information on which you should contact the author.
  20. ***************************************************************/
  21. /*---------------------------------------------------------------*/
  22. /* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */
  23. /* 11/1995 (eidetics@cerf.net). */
  24. /* */
  25. /* Those additionally marked with "DD" were at the suggestion of */
  26. /* Dale DePriest (daled@cadence.com). */
  27. /*---------------------------------------------------------------*/
  28. #include <stdio.h>
  29. #include "bwbasic.h"
  30. #include "bwb_mes.h"
  31. #if HAVE_LONGJUMP /* Revised by JBV (bug found by DD) */
  32. #include <setjmp.h>
  33. #endif
  34. extern int prn_col;
  35. #if HAVE_LONGJUMP /* Revised by JBV (bug found by DD) */
  36. extern jmp_buf mark;
  37. #endif
  38. /***************************************************************
  39. FUNCTION: main()
  40. DESCRIPTION: As in any C program, main() is the basic
  41. function from which the rest of the
  42. program is called. Some environments,
  43. however, provide their own main() functions
  44. (Microsoft Windows (tm) is an example).
  45. In these cases, the following code will
  46. have to be included in the initialization
  47. function that is called by the environment.
  48. ***************************************************************/
  49. #if ANSI_C
  50. int
  51. main( int argc, char **argv )
  52. #else
  53. main( argc, argv )
  54. int argc;
  55. char **argv;
  56. #endif
  57. {
  58. bwb_init( argc, argv );
  59. #if HAVE_LONGJUMP /* Revised by JBV (bug found by DD) */
  60. #if INTERACTIVE
  61. setjmp( mark );
  62. #endif
  63. #endif
  64. /* main program loop */
  65. while( !feof( stdin ) ) /* condition !feof( stdin ) added in v1.11 */
  66. {
  67. bwb_mainloop();
  68. }
  69. bwx_terminate(); /* allow ^D (Unix) exit with grace */
  70. return (0);
  71. }
  72. /***************************************************************
  73. FUNCTION: bwx_signon()
  74. DESCRIPTION: This function prints out the sign-on
  75. message for bwBASIC.
  76. ***************************************************************/
  77. #if ANSI_C
  78. int
  79. bwx_signon( void )
  80. #else
  81. int
  82. bwx_signon()
  83. #endif
  84. {
  85. sprintf( bwb_ebuf, "\r%s %s\n", MES_SIGNON, VERSION );
  86. prn_xprintf( stdout, bwb_ebuf );
  87. sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT );
  88. prn_xprintf( stdout, bwb_ebuf );
  89. sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT_2 ); /* JBV 1/97 */
  90. prn_xprintf( stdout, bwb_ebuf );
  91. #if PERMANENT_DEBUG
  92. sprintf( bwb_ebuf, "\r%s\n", "Debugging Mode" );
  93. prn_xprintf( stdout, bwb_ebuf );
  94. #else
  95. sprintf( bwb_ebuf, "\r%s\n", MES_LANGUAGE );
  96. prn_xprintf( stdout, bwb_ebuf );
  97. #endif
  98. return TRUE;
  99. }
  100. /***************************************************************
  101. FUNCTION: bwx_message()
  102. DESCRIPTION: This function outputs a message to the
  103. default output device.
  104. ***************************************************************/
  105. #if ANSI_C
  106. int
  107. bwx_message( char *m )
  108. #else
  109. int
  110. bwx_message( m )
  111. char *m;
  112. #endif
  113. {
  114. #if INTENSIVE_DEBUG
  115. fprintf( stderr, "<MES>" );
  116. #endif
  117. prn_xprintf( stdout, m );
  118. return TRUE;
  119. }
  120. /***************************************************************
  121. FUNCTION: bwx_putc()
  122. DESCRIPTION: This function outputs a single character
  123. to the default output device.
  124. ***************************************************************/
  125. #if ANSI_C
  126. int
  127. bwx_putc( char c )
  128. #else
  129. int
  130. bwx_putc( c )
  131. char c;
  132. #endif
  133. {
  134. return fputc( c, stdout );
  135. }
  136. /***************************************************************
  137. FUNCTION: bwx_error()
  138. DESCRIPTION: This function outputs a message to the
  139. default error-message device.
  140. ***************************************************************/
  141. #if ANSI_C
  142. int
  143. bwx_errmes( char *m )
  144. #else
  145. int
  146. bwx_errmes( m )
  147. char *m;
  148. #endif
  149. {
  150. static char tbuf[ MAXSTRINGSIZE + 1 ]; /* this memory should be
  151. permanent in case of memory
  152. overrun errors */
  153. if (( prn_col != 1 ) && ( errfdevice == stderr ))
  154. {
  155. prn_xprintf( errfdevice, "\n" );
  156. }
  157. if ( CURTASK number == 0 )
  158. {
  159. sprintf( tbuf, "\n%s: %s\n", ERRD_HEADER, m );
  160. }
  161. else
  162. {
  163. sprintf( tbuf, "\n%s %d: %s\n", ERROR_HEADER, CURTASK number, m );
  164. }
  165. #if INTENSIVE_DEBUG
  166. fprintf( stderr, "<ERR>" );
  167. #endif
  168. prn_xprintf( errfdevice, tbuf );
  169. return TRUE;
  170. }
  171. /***************************************************************
  172. FUNCTION: bwx_input()
  173. DESCRIPTION: This function outputs the string pointed
  174. to by 'prompt', then inputs a character
  175. string.
  176. ***************************************************************/
  177. #if ANSI_C
  178. int
  179. bwx_input( char *prompt, char *buffer )
  180. #else
  181. int
  182. bwx_input( prompt, buffer )
  183. char *prompt;
  184. char *buffer;
  185. #endif
  186. {
  187. #if INTENSIVE_DEBUG
  188. fprintf( stderr, "<INP>" );
  189. #endif
  190. prn_xprintf( stdout, prompt );
  191. fgets( buffer, MAXREADLINESIZE, stdin );
  192. * prn_getcol( stdout ) = 1; /* reset column */
  193. return TRUE;
  194. }
  195. /***************************************************************
  196. FUNCTION: bwx_terminate()
  197. DESCRIPTION: This function terminates program execution.
  198. ***************************************************************/
  199. #if ANSI_C
  200. void
  201. bwx_terminate( void )
  202. #else
  203. void
  204. bwx_terminate()
  205. #endif
  206. {
  207. exit( 0 );
  208. }
  209. /***************************************************************
  210. FUNCTION: bwx_shell()
  211. DESCRIPTION: This function runs a shell program.
  212. ***************************************************************/
  213. #if COMMAND_SHELL
  214. #if ANSI_C
  215. extern int
  216. bwx_shell( struct bwb_line *l )
  217. #else
  218. extern int
  219. bwx_shell( l )
  220. struct bwb_line *l;
  221. #endif
  222. {
  223. static char *s_buffer;
  224. static int init = FALSE;
  225. static int position;
  226. /* get memory for temporary buffer if necessary */
  227. if ( init == FALSE )
  228. {
  229. init = TRUE;
  230. /* Revised to CALLOC pass-thru call by JBV */
  231. if ( ( s_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwx_shell" )) == NULL )
  232. {
  233. bwb_error( err_getmem );
  234. return FALSE;
  235. }
  236. }
  237. /* get the first element and check for a line number */
  238. #if INTENSIVE_DEBUG
  239. sprintf( bwb_ebuf, "in bwx_shell(): line buffer is <%s>.", l->buffer );
  240. bwb_debug( bwb_ebuf );
  241. #endif
  242. position = 0;
  243. adv_element( l->buffer, &position, s_buffer );
  244. if ( is_numconst( s_buffer ) != TRUE ) /* not a line number */
  245. {
  246. #if INTENSIVE_DEBUG
  247. sprintf( bwb_ebuf, "in bwx_shell(): no line number, command <%s>.",
  248. l->buffer );
  249. bwb_debug( bwb_ebuf );
  250. #endif
  251. if ( system( l->buffer ) == 0 )
  252. {
  253. return TRUE;
  254. }
  255. else
  256. {
  257. return FALSE;
  258. }
  259. }
  260. else /* advance past line number */
  261. {
  262. adv_ws( l->buffer, &position ); /* advance past whitespace */
  263. #if INTENSIVE_DEBUG
  264. sprintf( bwb_ebuf, "in bwx_shell(): line number, command <%s>.",
  265. l->buffer );
  266. bwb_debug( bwb_ebuf );
  267. #endif
  268. if ( system( &( l->buffer[ position ] ) ) == 0 )
  269. {
  270. return TRUE;
  271. }
  272. else
  273. {
  274. return FALSE;
  275. }
  276. }
  277. }
  278. #endif
  279. /***************************************************************
  280. FUNCTION: matherr()
  281. DESCRIPTION: This function is called to handle math
  282. errors in Bywater BASIC. It displays
  283. the error message, then calls the
  284. break_handler() routine.
  285. Note that this function isn't supported
  286. by all compilers (it's not part of C90).
  287. If it exists, it's an extension in math.h
  288. and it will be called whenever there's
  289. a divide by zero or something like that.
  290. ***************************************************************/
  291. #if HAVE_MATHERR
  292. #if ANSI_C
  293. int
  294. matherr( struct exception *except )
  295. #else
  296. int
  297. matherr( except )
  298. struct exception *except;
  299. #endif
  300. {
  301. perror( MATHERR_HEADER );
  302. break_handler();
  303. return FALSE;
  304. }
  305. #endif
  306. #if COMMON_CMDS
  307. /***************************************************************
  308. FUNCTION: bwb_edit()
  309. DESCRIPTION: This function implements the BASIC EDIT
  310. program by shelling out to a default editor
  311. specified by the variable BWB.EDITOR$.
  312. SYNTAX: EDIT
  313. ***************************************************************/
  314. #if ANSI_C
  315. struct bwb_line *
  316. bwb_edit( struct bwb_line *l )
  317. #else
  318. struct bwb_line *
  319. bwb_edit( l )
  320. struct bwb_line *l;
  321. #endif
  322. {
  323. char tbuf[ MAXSTRINGSIZE + 1 ];
  324. char edname[ MAXSTRINGSIZE + 1 ];
  325. struct bwb_variable *ed;
  326. FILE *loadfile;
  327. ed = var_find( DEFVNAME_EDITOR );
  328. str_btoc( edname, var_getsval( ed ));
  329. sprintf( tbuf, "%s %s", edname, CURTASK progfile );
  330. #if INTENSIVE_DEBUG
  331. sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf );
  332. bwb_debug( bwb_ebuf );
  333. #else
  334. system( tbuf );
  335. #endif
  336. /* open edited file for read */
  337. if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
  338. {
  339. sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
  340. bwb_error( bwb_ebuf );
  341. return bwb_zline( l );
  342. }
  343. /* clear current contents */
  344. bwb_new( l ); /* Relocated by JBV (bug found by DD) */
  345. /* and (re)load the file into memory */
  346. bwb_fload( loadfile );
  347. return bwb_zline( l );
  348. }
  349. /***************************************************************
  350. FUNCTION: bwb_renum()
  351. DESCRIPTION: This function implements the BASIC RENUM
  352. command by shelling out to a default
  353. renumbering program called "renum".
  354. Added by JBV 10/95
  355. SYNTAX: RENUM
  356. ***************************************************************/
  357. #if ANSI_C
  358. struct bwb_line *
  359. bwb_renum( struct bwb_line *l )
  360. #else
  361. struct bwb_line *
  362. bwb_renum( l )
  363. struct bwb_line *l;
  364. #endif
  365. {
  366. char tbuf[ MAXSTRINGSIZE + 1 ];
  367. FILE *loadfile;
  368. sprintf( tbuf, "renum %s\0", CURTASK progfile );
  369. #if INTENSIVE_DEBUG
  370. sprintf( bwb_ebuf, "in bwb_renum(): command line <%s>", tbuf );
  371. bwb_debug( bwb_ebuf );
  372. #else
  373. system( tbuf );
  374. #endif
  375. /* open edited file for read */
  376. if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
  377. {
  378. sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
  379. bwb_error( bwb_ebuf );
  380. return bwb_zline( l );
  381. }
  382. /* clear current contents */
  383. bwb_new( l ); /* Relocated by JBV (bug found by DD) */
  384. /* and (re)load the file into memory */
  385. bwb_fload( loadfile );
  386. return bwb_zline( l );
  387. }
  388. /***************************************************************
  389. FUNCTION: bwb_files()
  390. DESCRIPTION: This function implements the BASIC FILES
  391. command, in this case by shelling out to
  392. a directory listing program or command
  393. specified in the variable BWB.FILES$.
  394. SYNTAX: FILES filespec$
  395. ***************************************************************/
  396. #if ANSI_C
  397. struct bwb_line *
  398. bwb_files( struct bwb_line *l )
  399. #else
  400. struct bwb_line *
  401. bwb_files( l )
  402. struct bwb_line *l;
  403. #endif
  404. {
  405. char tbuf[ MAXVARNAMESIZE + 1 ];
  406. char finame[ MAXVARNAMESIZE + 1 ];
  407. char argument[ MAXVARNAMESIZE + 1 ];
  408. struct bwb_variable *fi;
  409. struct exp_ese *e;
  410. fi = var_find( DEFVNAME_FILES );
  411. str_btoc( finame, var_getsval( fi ));
  412. /* get argument */
  413. adv_ws( l->buffer, &( l->position ));
  414. switch( l->buffer[ l->position ] )
  415. {
  416. case '\0':
  417. case '\r':
  418. case '\n':
  419. argument[ 0 ] = '\0';
  420. break;
  421. default:
  422. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  423. if ( e->type != STRING )
  424. {
  425. bwb_error( err_mismatch );
  426. return bwb_zline( l );
  427. }
  428. str_btoc( argument, exp_getsval( e ) );
  429. break;
  430. }
  431. sprintf( tbuf, "%s %s", finame, argument );
  432. #if INTENSIVE_DEBUG
  433. sprintf( bwb_ebuf, "in bwb_files(): command line <%s>", tbuf );
  434. bwb_debug( bwb_ebuf );
  435. #else
  436. system( tbuf );
  437. #endif
  438. return bwb_zline( l );
  439. }
  440. #endif /* COMMON_CMDS */