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.
 
 
 
 
 
 

582 lines
12 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. void
  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. }
  71. /***************************************************************
  72. FUNCTION: bwx_signon()
  73. DESCRIPTION: This function prints out the sign-on
  74. message for bwBASIC.
  75. ***************************************************************/
  76. #if ANSI_C
  77. int
  78. bwx_signon( void )
  79. #else
  80. int
  81. bwx_signon()
  82. #endif
  83. {
  84. sprintf( bwb_ebuf, "\r%s %s\n", MES_SIGNON, VERSION );
  85. prn_xprintf( stdout, bwb_ebuf );
  86. sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT );
  87. prn_xprintf( stdout, bwb_ebuf );
  88. #if PERMANENT_DEBUG
  89. sprintf( bwb_ebuf, "\r%s\n", "Debugging Mode" );
  90. prn_xprintf( stdout, bwb_ebuf );
  91. #else
  92. sprintf( bwb_ebuf, "\r%s\n", MES_LANGUAGE );
  93. prn_xprintf( stdout, bwb_ebuf );
  94. #endif
  95. return TRUE;
  96. }
  97. /***************************************************************
  98. FUNCTION: bwx_message()
  99. DESCRIPTION: This function outputs a message to the
  100. default output device.
  101. ***************************************************************/
  102. #if ANSI_C
  103. int
  104. bwx_message( char *m )
  105. #else
  106. int
  107. bwx_message( m )
  108. char *m;
  109. #endif
  110. {
  111. #if INTENSIVE_DEBUG
  112. fprintf( stderr, "<MES>" );
  113. #endif
  114. prn_xprintf( stdout, m );
  115. return TRUE;
  116. }
  117. /***************************************************************
  118. FUNCTION: bwx_putc()
  119. DESCRIPTION: This function outputs a single character
  120. to the default output device.
  121. ***************************************************************/
  122. #if ANSI_C
  123. int
  124. bwx_putc( char c )
  125. #else
  126. int
  127. bwx_putc( c )
  128. char c;
  129. #endif
  130. {
  131. return fputc( c, stdout );
  132. }
  133. /***************************************************************
  134. FUNCTION: bwx_error()
  135. DESCRIPTION: This function outputs a message to the
  136. default error-message device.
  137. ***************************************************************/
  138. #if ANSI_C
  139. int
  140. bwx_errmes( char *m )
  141. #else
  142. int
  143. bwx_errmes( m )
  144. char *m;
  145. #endif
  146. {
  147. static char tbuf[ MAXSTRINGSIZE + 1 ]; /* this memory should be
  148. permanent in case of memory
  149. overrun errors */
  150. if (( prn_col != 1 ) && ( errfdevice == stderr ))
  151. {
  152. prn_xprintf( errfdevice, "\n" );
  153. }
  154. if ( CURTASK number == 0 )
  155. {
  156. sprintf( tbuf, "\n%s: %s\n", ERRD_HEADER, m );
  157. }
  158. else
  159. {
  160. sprintf( tbuf, "\n%s %d: %s\n", ERROR_HEADER, CURTASK number, m );
  161. }
  162. #if INTENSIVE_DEBUG
  163. fprintf( stderr, "<ERR>" );
  164. #endif
  165. prn_xprintf( errfdevice, tbuf );
  166. return TRUE;
  167. }
  168. /***************************************************************
  169. FUNCTION: bwx_input()
  170. DESCRIPTION: This function outputs the string pointed
  171. to by 'prompt', then inputs a character
  172. string.
  173. ***************************************************************/
  174. #if ANSI_C
  175. int
  176. bwx_input( char *prompt, char *buffer )
  177. #else
  178. int
  179. bwx_input( prompt, buffer )
  180. char *prompt;
  181. char *buffer;
  182. #endif
  183. {
  184. #if INTENSIVE_DEBUG
  185. fprintf( stderr, "<INP>" );
  186. #endif
  187. prn_xprintf( stdout, prompt );
  188. fgets( buffer, MAXREADLINESIZE, stdin );
  189. * prn_getcol( stdout ) = 1; /* reset column */
  190. return TRUE;
  191. }
  192. /***************************************************************
  193. FUNCTION: bwx_terminate()
  194. DESCRIPTION: This function terminates program execution.
  195. ***************************************************************/
  196. #if ANSI_C
  197. void
  198. bwx_terminate( void )
  199. #else
  200. void
  201. bwx_terminate()
  202. #endif
  203. {
  204. exit( 0 );
  205. }
  206. /***************************************************************
  207. FUNCTION: bwx_shell()
  208. DESCRIPTION: This function runs a shell program.
  209. ***************************************************************/
  210. #if COMMAND_SHELL
  211. #if ANSI_C
  212. extern int
  213. bwx_shell( struct bwb_line *l )
  214. #else
  215. extern int
  216. bwx_shell( l )
  217. struct bwb_line *l;
  218. #endif
  219. {
  220. static char *s_buffer;
  221. static int init = FALSE;
  222. static int position;
  223. /* get memory for temporary buffer if necessary */
  224. if ( init == FALSE )
  225. {
  226. init = TRUE;
  227. /* Revised to CALLOC pass-thru call by JBV */
  228. if ( ( s_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwx_shell" )) == NULL )
  229. {
  230. bwb_error( err_getmem );
  231. return FALSE;
  232. }
  233. }
  234. /* get the first element and check for a line number */
  235. #if INTENSIVE_DEBUG
  236. sprintf( bwb_ebuf, "in bwx_shell(): line buffer is <%s>.", l->buffer );
  237. bwb_debug( bwb_ebuf );
  238. #endif
  239. position = 0;
  240. adv_element( l->buffer, &position, s_buffer );
  241. if ( is_numconst( s_buffer ) != TRUE ) /* not a line number */
  242. {
  243. #if INTENSIVE_DEBUG
  244. sprintf( bwb_ebuf, "in bwx_shell(): no line number, command <%s>.",
  245. l->buffer );
  246. bwb_debug( bwb_ebuf );
  247. #endif
  248. if ( system( l->buffer ) == 0 )
  249. {
  250. return TRUE;
  251. }
  252. else
  253. {
  254. return FALSE;
  255. }
  256. }
  257. else /* advance past line number */
  258. {
  259. adv_ws( l->buffer, &position ); /* advance past whitespace */
  260. #if INTENSIVE_DEBUG
  261. sprintf( bwb_ebuf, "in bwx_shell(): line number, command <%s>.",
  262. l->buffer );
  263. bwb_debug( bwb_ebuf );
  264. #endif
  265. if ( system( &( l->buffer[ position ] ) ) == 0 )
  266. {
  267. return TRUE;
  268. }
  269. else
  270. {
  271. return FALSE;
  272. }
  273. }
  274. }
  275. #endif
  276. /***************************************************************
  277. FUNCTION: matherr()
  278. DESCRIPTION: This function is called to handle math
  279. errors in Bywater BASIC. It displays
  280. the error message, then calls the
  281. break_handler() routine.
  282. ***************************************************************/
  283. #if ANSI_C
  284. int
  285. matherr( struct exception *except )
  286. #else
  287. int
  288. matherr( except )
  289. struct exception *except;
  290. #endif
  291. {
  292. perror( MATHERR_HEADER );
  293. break_handler();
  294. return FALSE;
  295. }
  296. #if COMMON_CMDS
  297. /***************************************************************
  298. FUNCTION: bwb_edit()
  299. DESCRIPTION: This function implements the BASIC EDIT
  300. program by shelling out to a default editor
  301. specified by the variable BWB.EDITOR$.
  302. SYNTAX: EDIT
  303. ***************************************************************/
  304. #if ANSI_C
  305. struct bwb_line *
  306. bwb_edit( struct bwb_line *l )
  307. #else
  308. struct bwb_line *
  309. bwb_edit( l )
  310. struct bwb_line *l;
  311. #endif
  312. {
  313. char tbuf[ MAXSTRINGSIZE + 1 ];
  314. char edname[ MAXSTRINGSIZE + 1 ];
  315. struct bwb_variable *ed;
  316. FILE *loadfile;
  317. ed = var_find( DEFVNAME_EDITOR );
  318. str_btoc( edname, var_getsval( ed ));
  319. sprintf( tbuf, "%s %s", edname, CURTASK progfile );
  320. #if INTENSIVE_DEBUG
  321. sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf );
  322. bwb_debug( bwb_ebuf );
  323. #else
  324. system( tbuf );
  325. #endif
  326. /* open edited file for read */
  327. if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
  328. {
  329. sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
  330. bwb_error( bwb_ebuf );
  331. return bwb_zline( l );
  332. }
  333. /* clear current contents */
  334. bwb_new( l ); /* Relocated by JBV (bug found by DD) */
  335. /* and (re)load the file into memory */
  336. bwb_fload( loadfile );
  337. return bwb_zline( l );
  338. }
  339. /***************************************************************
  340. FUNCTION: bwb_renum()
  341. DESCRIPTION: This function implements the BASIC RENUM
  342. command by shelling out to a default
  343. renumbering program called "renum".
  344. Added by JBV 10/95
  345. SYNTAX: RENUM
  346. ***************************************************************/
  347. #if ANSI_C
  348. struct bwb_line *
  349. bwb_renum( struct bwb_line *l )
  350. #else
  351. struct bwb_line *
  352. bwb_renum( l )
  353. struct bwb_line *l;
  354. #endif
  355. {
  356. char tbuf[ MAXSTRINGSIZE + 1 ];
  357. FILE *loadfile;
  358. sprintf( tbuf, "renum %s\0", CURTASK progfile );
  359. #if INTENSIVE_DEBUG
  360. sprintf( bwb_ebuf, "in bwb_renum(): command line <%s>", tbuf );
  361. bwb_debug( bwb_ebuf );
  362. #else
  363. system( tbuf );
  364. #endif
  365. /* open edited file for read */
  366. if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
  367. {
  368. sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
  369. bwb_error( bwb_ebuf );
  370. return bwb_zline( l );
  371. }
  372. /* clear current contents */
  373. bwb_new( l ); /* Relocated by JBV (bug found by DD) */
  374. /* and (re)load the file into memory */
  375. bwb_fload( loadfile );
  376. return bwb_zline( l );
  377. }
  378. /***************************************************************
  379. FUNCTION: bwb_files()
  380. DESCRIPTION: This function implements the BASIC FILES
  381. command, in this case by shelling out to
  382. a directory listing program or command
  383. specified in the variable BWB.FILES$.
  384. SYNTAX: FILES filespec$
  385. ***************************************************************/
  386. #if ANSI_C
  387. struct bwb_line *
  388. bwb_files( struct bwb_line *l )
  389. #else
  390. struct bwb_line *
  391. bwb_files( l )
  392. struct bwb_line *l;
  393. #endif
  394. {
  395. char tbuf[ MAXVARNAMESIZE + 1 ];
  396. char finame[ MAXVARNAMESIZE + 1 ];
  397. char argument[ MAXVARNAMESIZE + 1 ];
  398. struct bwb_variable *fi;
  399. struct exp_ese *e;
  400. fi = var_find( DEFVNAME_FILES );
  401. str_btoc( finame, var_getsval( fi ));
  402. /* get argument */
  403. adv_ws( l->buffer, &( l->position ));
  404. switch( l->buffer[ l->position ] )
  405. {
  406. case '\0':
  407. case '\r':
  408. case '\n':
  409. argument[ 0 ] = '\0';
  410. break;
  411. default:
  412. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  413. if ( e->type != STRING )
  414. {
  415. bwb_error( err_mismatch );
  416. return bwb_zline( l );
  417. }
  418. str_btoc( argument, exp_getsval( e ) );
  419. break;
  420. }
  421. sprintf( tbuf, "%s %s", finame, argument );
  422. #if INTENSIVE_DEBUG
  423. sprintf( bwb_ebuf, "in bwb_files(): command line <%s>", tbuf );
  424. bwb_debug( bwb_ebuf );
  425. #else
  426. system( tbuf );
  427. #endif
  428. return bwb_zline( l );
  429. }
  430. #endif /* COMMON_CMDS */