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.
 
 
 
 
 
 

518 lines
11 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. #include <stdio.h>
  22. #include "bwbasic.h"
  23. #include "bwb_mes.h"
  24. #if HAVE_LONGJMP
  25. #include <setjmp.h>
  26. #endif
  27. extern int prn_col;
  28. #if HAVE_LONGJMP
  29. extern jmp_buf mark;
  30. #endif
  31. /***************************************************************
  32. FUNCTION: main()
  33. DESCRIPTION: As in any C program, main() is the basic
  34. function from which the rest of the
  35. program is called. Some environments,
  36. however, provide their own main() functions
  37. (Microsoft Windows (tm) is an example).
  38. In these cases, the following code will
  39. have to be included in the initialization
  40. function that is called by the environment.
  41. ***************************************************************/
  42. #if ANSI_C
  43. void
  44. main( int argc, char **argv )
  45. #else
  46. main( argc, argv )
  47. int argc;
  48. char **argv;
  49. #endif
  50. {
  51. bwb_init( argc, argv );
  52. #if HAVE_LONGJMP
  53. #if INTERACTIVE
  54. setjmp( mark );
  55. #endif
  56. #endif
  57. /* main program loop */
  58. while( !feof( stdin ) ) /* condition !feof( stdin ) added in v1.11 */
  59. {
  60. bwb_mainloop();
  61. }
  62. bwx_terminate(); /* in case of ^D exit in Unix systems */
  63. }
  64. /***************************************************************
  65. FUNCTION: bwx_signon()
  66. DESCRIPTION: This function prints out the sign-on
  67. message for bwBASIC.
  68. ***************************************************************/
  69. #if ANSI_C
  70. int
  71. bwx_signon( void )
  72. #else
  73. int
  74. bwx_signon()
  75. #endif
  76. {
  77. sprintf( bwb_ebuf, "\r%s %s\n", MES_SIGNON, VERSION );
  78. prn_xprintf( stdout, bwb_ebuf );
  79. sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT );
  80. prn_xprintf( stdout, bwb_ebuf );
  81. #if PERMANENT_DEBUG
  82. sprintf( bwb_ebuf, "\r%s\n", "Debugging Mode" );
  83. prn_xprintf( stdout, bwb_ebuf );
  84. #else
  85. sprintf( bwb_ebuf, "\r%s\n", MES_LANGUAGE );
  86. prn_xprintf( stdout, bwb_ebuf );
  87. #endif
  88. return TRUE;
  89. }
  90. /***************************************************************
  91. FUNCTION: bwx_message()
  92. DESCRIPTION: This function outputs a message to the
  93. default output device.
  94. ***************************************************************/
  95. #if ANSI_C
  96. int
  97. bwx_message( char *m )
  98. #else
  99. int
  100. bwx_message( m )
  101. char *m;
  102. #endif
  103. {
  104. #if INTENSIVE_DEBUG
  105. fprintf( stderr, "<MES>" );
  106. #endif
  107. prn_xprintf( stdout, m );
  108. return TRUE;
  109. }
  110. /***************************************************************
  111. FUNCTION: bwx_putc()
  112. DESCRIPTION: This function outputs a single character
  113. to the default output device.
  114. ***************************************************************/
  115. #if ANSI_C
  116. int
  117. bwx_putc( char c )
  118. #else
  119. int
  120. bwx_putc( c )
  121. char c;
  122. #endif
  123. {
  124. return fputc( c, stdout );
  125. }
  126. /***************************************************************
  127. FUNCTION: bwx_error()
  128. DESCRIPTION: This function outputs a message to the
  129. default error-message device.
  130. ***************************************************************/
  131. #if ANSI_C
  132. int
  133. bwx_errmes( char *m )
  134. #else
  135. int
  136. bwx_errmes( m )
  137. char *m;
  138. #endif
  139. {
  140. static char tbuf[ MAXSTRINGSIZE + 1 ]; /* this memory should be
  141. permanent in case of memory
  142. overrun errors */
  143. if (( prn_col != 1 ) && ( errfdevice == stderr ))
  144. {
  145. prn_xprintf( errfdevice, "\n" );
  146. }
  147. if ( CURTASK number == 0 )
  148. {
  149. sprintf( tbuf, "\n%s: %s\n", ERRD_HEADER, m );
  150. }
  151. else
  152. {
  153. sprintf( tbuf, "\n%s %d: %s\n", ERROR_HEADER, CURTASK number, m );
  154. }
  155. #if INTENSIVE_DEBUG
  156. fprintf( stderr, "<ERR>" );
  157. #endif
  158. prn_xprintf( errfdevice, tbuf );
  159. return TRUE;
  160. }
  161. /***************************************************************
  162. FUNCTION: bwx_input()
  163. DESCRIPTION: This function outputs the string pointed
  164. to by 'prompt', then inputs a character
  165. string.
  166. ***************************************************************/
  167. #if ANSI_C
  168. int
  169. bwx_input( char *prompt, char *buffer )
  170. #else
  171. int
  172. bwx_input( prompt, buffer )
  173. char *prompt;
  174. char *buffer;
  175. #endif
  176. {
  177. #if INTENSIVE_DEBUG
  178. fprintf( stderr, "<INP>" );
  179. #endif
  180. prn_xprintf( stdout, prompt );
  181. fgets( buffer, MAXREADLINESIZE, stdin );
  182. * prn_getcol( stdout ) = 1; /* reset column */
  183. return TRUE;
  184. }
  185. /***************************************************************
  186. FUNCTION: bwx_terminate()
  187. DESCRIPTION: This function terminates program execution.
  188. ***************************************************************/
  189. #if ANSI_C
  190. void
  191. bwx_terminate( void )
  192. #else
  193. void
  194. bwx_terminate()
  195. #endif
  196. {
  197. #if INTENSIVE_DEBUG
  198. fprintf( stderr, "Normal Termination\n" );
  199. #endif
  200. exit( 0 );
  201. }
  202. /***************************************************************
  203. FUNCTION: bwx_shell()
  204. DESCRIPTION: This function runs a shell program.
  205. ***************************************************************/
  206. #if COMMAND_SHELL
  207. #if ANSI_C
  208. extern int
  209. bwx_shell( struct bwb_line *l )
  210. #else
  211. extern int
  212. bwx_shell( l )
  213. struct bwb_line *l;
  214. #endif
  215. {
  216. static char *s_buffer;
  217. static int init = FALSE;
  218. static int position;
  219. /* get memory for temporary buffer if necessary */
  220. if ( init == FALSE )
  221. {
  222. init = TRUE;
  223. if ( ( s_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
  224. {
  225. bwb_error( err_getmem );
  226. return FALSE;
  227. }
  228. }
  229. /* get the first element and check for a line number */
  230. #if INTENSIVE_DEBUG
  231. sprintf( bwb_ebuf, "in bwx_shell(): line buffer is <%s>.", l->buffer );
  232. bwb_debug( bwb_ebuf );
  233. #endif
  234. position = 0;
  235. adv_element( l->buffer, &position, s_buffer );
  236. if ( is_numconst( s_buffer ) != TRUE ) /* not a line number */
  237. {
  238. #if INTENSIVE_DEBUG
  239. sprintf( bwb_ebuf, "in bwx_shell(): no line number, command <%s>.",
  240. l->buffer );
  241. bwb_debug( bwb_ebuf );
  242. #endif
  243. if ( system( l->buffer ) == 0 )
  244. {
  245. return TRUE;
  246. }
  247. else
  248. {
  249. return FALSE;
  250. }
  251. }
  252. else /* advance past line number */
  253. {
  254. adv_ws( l->buffer, &position ); /* advance past whitespace */
  255. #if INTENSIVE_DEBUG
  256. sprintf( bwb_ebuf, "in bwx_shell(): line number, command <%s>.",
  257. l->buffer );
  258. bwb_debug( bwb_ebuf );
  259. #endif
  260. if ( system( &( l->buffer[ position ] ) ) == 0 )
  261. {
  262. return TRUE;
  263. }
  264. else
  265. {
  266. return FALSE;
  267. }
  268. }
  269. }
  270. #endif
  271. /***************************************************************
  272. FUNCTION: matherr()
  273. DESCRIPTION: This function is called to handle math
  274. errors in Bywater BASIC. It displays
  275. the error message, then calls the
  276. break_handler() routine.
  277. ***************************************************************/
  278. #if ANSI_C
  279. int
  280. matherr( struct exception *except )
  281. #else
  282. int
  283. matherr( except )
  284. struct exception *except;
  285. #endif
  286. {
  287. perror( MATHERR_HEADER );
  288. break_handler();
  289. return FALSE;
  290. }
  291. #if COMMON_CMDS
  292. /***************************************************************
  293. FUNCTION: bwb_edit()
  294. DESCRIPTION: This function implements the BASIC EDIT
  295. program by shelling out to a default editor
  296. specified by the variable BWB.EDITOR$.
  297. SYNTAX: EDIT
  298. ***************************************************************/
  299. #if ANSI_C
  300. struct bwb_line *
  301. bwb_edit( struct bwb_line *l )
  302. #else
  303. struct bwb_line *
  304. bwb_edit( l )
  305. struct bwb_line *l;
  306. #endif
  307. {
  308. char tbuf[ MAXSTRINGSIZE + 1 ];
  309. char edname[ MAXSTRINGSIZE + 1 ];
  310. struct bwb_variable *ed;
  311. FILE *loadfile;
  312. ed = var_find( DEFVNAME_EDITOR );
  313. str_btoc( edname, var_getsval( ed ));
  314. sprintf( tbuf, "%s %s", edname, CURTASK progfile );
  315. #if INTENSIVE_DEBUG
  316. sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf );
  317. bwb_debug( bwb_ebuf );
  318. #else
  319. system( tbuf );
  320. #endif
  321. /* clear current contents */
  322. bwb_new( l );
  323. /* open edited file for read */
  324. if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
  325. {
  326. sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
  327. bwb_error( bwb_ebuf );
  328. return bwb_zline( l );
  329. }
  330. /* and (re)load the file into memory */
  331. bwb_fload( loadfile );
  332. return bwb_zline( l );
  333. }
  334. /***************************************************************
  335. FUNCTION: bwb_files()
  336. DESCRIPTION: This function implements the BASIC FILES
  337. command, in this case by shelling out to
  338. a directory listing program or command
  339. specified in the variable BWB.FILES$.
  340. SYNTAX: FILES filespec$
  341. ***************************************************************/
  342. #if ANSI_C
  343. struct bwb_line *
  344. bwb_files( struct bwb_line *l )
  345. #else
  346. struct bwb_line *
  347. bwb_files( l )
  348. struct bwb_line *l;
  349. #endif
  350. {
  351. char tbuf[ MAXVARNAMESIZE + 1 ];
  352. char finame[ MAXVARNAMESIZE + 1 ];
  353. char argument[ MAXVARNAMESIZE + 1 ];
  354. struct bwb_variable *fi;
  355. struct exp_ese *e;
  356. fi = var_find( DEFVNAME_FILES );
  357. str_btoc( finame, var_getsval( fi ));
  358. /* get argument */
  359. adv_ws( l->buffer, &( l->position ));
  360. switch( l->buffer[ l->position ] )
  361. {
  362. case '\0':
  363. case '\r':
  364. case '\n':
  365. argument[ 0 ] = '\0';
  366. break;
  367. default:
  368. e = bwb_exp( l->buffer, FALSE, &( l->position ) );
  369. if ( e->type != STRING )
  370. {
  371. bwb_error( err_mismatch );
  372. return bwb_zline( l );
  373. }
  374. str_btoc( argument, exp_getsval( e ) );
  375. break;
  376. }
  377. sprintf( tbuf, "%s %s", finame, argument );
  378. #if INTENSIVE_DEBUG
  379. sprintf( bwb_ebuf, "in bwb_files(): command line <%s>", tbuf );
  380. bwb_debug( bwb_ebuf );
  381. #else
  382. system( tbuf );
  383. #endif
  384. return bwb_zline( l );
  385. }
  386. #endif /* COMMON_CMDS */