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.
 
 
 
 
 
 

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