| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | #include <xp/lsp/lsp.h>
 | 
					
						
							| 
									
										
										
										
											2005-05-01 06:47:49 +00:00
										 |  |  | #include <xp/bas/stdio.h>
 | 
					
						
							|  |  |  | #include <xp/bas/ctype.h>
 | 
					
						
							|  |  |  | #include <xp/bas/stdcli.h>
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | #include <xp/bas/locale.h>
 | 
					
						
							| 
									
										
										
										
											2005-02-05 05:03:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-21 03:31:39 +00:00
										 |  |  | #ifdef __linux
 | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | #include <mcheck.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:54:23 +00:00
										 |  |  | static int get_char (int cmd, void* owner, void* arg) | 
					
						
							| 
									
										
										
										
											2005-02-05 05:03:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-02-15 09:09:09 +00:00
										 |  |  | 	xp_cint_t c; | 
					
						
							| 
									
										
										
										
											2005-09-18 11:54:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case XP_LSP_IO_OPEN: | 
					
						
							|  |  |  | 	case XP_LSP_IO_CLOSE: | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case XP_LSP_IO_CHAR: | 
					
						
							|  |  |  | 		c = xp_fgetc (xp_stdin); | 
					
						
							|  |  |  | 		if (c == XP_CHAR_EOF) { | 
					
						
							|  |  |  | 			if (xp_ferror(xp_stdin)) return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case XP_LSP_IO_STR: | 
					
						
							|  |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-02-05 05:03:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:54:23 +00:00
										 |  |  | static int put_char (int cmd, void* owner, void* arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case XP_LSP_IO_OPEN: | 
					
						
							|  |  |  | 	case XP_LSP_IO_CLOSE: | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case XP_LSP_IO_CHAR: | 
					
						
							|  |  |  | 		xp_fputc (*(xp_char_t*)arg, xp_stdout); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case XP_LSP_IO_STR: | 
					
						
							|  |  |  | 		xp_fputs ((xp_char_t*)arg, xp_stdout); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | int to_int (const xp_char_t* str) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int r = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (*str != XP_CHAR('\0')) { | 
					
						
							|  |  |  | 		if (!xp_isdigit(*str))	break; | 
					
						
							|  |  |  | 		r = r * 10 + (*str - XP_CHAR('0')); | 
					
						
							|  |  |  | 		str++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return r; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-02-07 15:10:41 +00:00
										 |  |  | #include <locale.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-23 14:57:35 +00:00
										 |  |  | int handle_cli_error ( | 
					
						
							|  |  |  | 	const xp_cli_t* cli, int code,  | 
					
						
							|  |  |  | 	const xp_char_t* name, const xp_char_t* value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xp_printf (XP_TEXT("usage: %s /memory=nnn /increment=nnn\n"), cli->verb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (code == XP_CLI_ERROR_INVALID_OPTNAME) { | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("unknown option - %s\n"), name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (code == XP_CLI_ERROR_MISSING_OPTNAME) { | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("missing option - %s\n"), name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (code == XP_CLI_ERROR_REDUNDANT_OPTVAL) { | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("redundant value %s for %s\n"), value, name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (code == XP_CLI_ERROR_MISSING_OPTVAL) { | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("missing value for %s\n"), name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (code == XP_CLI_ERROR_MEMORY) { | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("memory error in processing %s\n"), name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("error code: %d\n"), code); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-09-18 11:54:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-23 14:57:35 +00:00
										 |  |  | xp_cli_t* parse_cli (int argc, xp_char_t* argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static const xp_char_t* optsta[] = | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		XP_TEXT("/"), XP_TEXT("--"), XP_NULL | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static xp_cliopt_t opts[] = | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		{ XP_TEXT("memory"), XP_CLI_OPTNAME | XP_CLI_OPTVAL }, | 
					
						
							|  |  |  |         { XP_TEXT("increment"), XP_CLI_OPTNAME | XP_CLI_OPTVAL }, | 
					
						
							|  |  |  |         { XP_NULL, 0 } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static xp_cli_t cli = | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		handle_cli_error, | 
					
						
							|  |  |  | 		optsta, | 
					
						
							|  |  |  | 		XP_TEXT("="), | 
					
						
							|  |  |  | 		opts | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (xp_parsecli (argc, argv, &cli) == -1) return XP_NULL; | 
					
						
							|  |  |  | 	return &cli; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | int xp_main (int argc, xp_char_t* argv[]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 	xp_lsp_t* lsp; | 
					
						
							|  |  |  | 	xp_lsp_obj_t* obj; | 
					
						
							| 
									
										
										
										
											2005-03-23 14:57:35 +00:00
										 |  |  | 	xp_cli_t* cli; | 
					
						
							|  |  |  | 	int mem, inc; | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-21 03:31:39 +00:00
										 |  |  | #ifdef __linux
 | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 	mtrace (); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-02-07 15:10:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 	if (xp_setlocale () == -1) { | 
					
						
							|  |  |  | 		xp_fprintf (xp_stderr, | 
					
						
							|  |  |  | 			XP_TEXT("error: cannot set locale\n")); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-02-07 15:10:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-23 14:57:35 +00:00
										 |  |  | 	if ((cli = parse_cli (argc, argv)) == XP_NULL) return -1; | 
					
						
							|  |  |  | 	mem = to_int(xp_getclioptval(cli, XP_TEXT("memory"))); | 
					
						
							|  |  |  | 	inc = to_int(xp_getclioptval(cli, XP_TEXT("increment"))); | 
					
						
							|  |  |  | 	xp_clearcli (cli); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mem <= 0) { | 
					
						
							|  |  |  | 		xp_fprintf (xp_stderr, | 
					
						
							|  |  |  | 			XP_TEXT("error: invalid memory size given\n")); | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 	lsp = xp_lsp_open (XP_NULL, mem, inc); | 
					
						
							|  |  |  | 	if (lsp == XP_NULL) { | 
					
						
							| 
									
										
										
										
											2005-03-23 14:57:35 +00:00
										 |  |  | 		xp_fprintf (xp_stderr,  | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 			XP_TEXT("error: cannot create a lsp instance\n")); | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 	xp_printf (XP_TEXT("LSP 0.0001\n")); | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 	xp_lsp_attach_input (lsp, get_char); | 
					
						
							| 
									
										
										
										
											2005-09-18 11:54:23 +00:00
										 |  |  | 	xp_lsp_attach_output (lsp, put_char); | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("%s> "), argv[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 		obj = xp_lsp_read (lsp); | 
					
						
							| 
									
										
										
										
											2005-05-01 06:47:49 +00:00
										 |  |  | 		if (obj == XP_NULL) { | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 			if (lsp->errnum != XP_LSP_ERR_END &&  | 
					
						
							|  |  |  | 			    lsp->errnum != XP_LSP_ERR_ABORT) { | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 				xp_fprintf (xp_stderr,  | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 					XP_TEXT("error while reading: %d\n"), lsp->errnum); | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 			if (lsp->errnum < XP_LSP_ERR_SYNTAX) break; | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 		if ((obj = xp_lsp_eval (lsp, obj)) != XP_NULL) { | 
					
						
							|  |  |  | 			xp_lsp_print (lsp, obj); | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 			xp_printf (XP_TEXT("\n")); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 			if (lsp->errnum == XP_LSP_ERR_ABORT) break; | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 			xp_fprintf (xp_stderr,  | 
					
						
							| 
									
										
										
										
											2005-09-18 11:54:23 +00:00
										 |  |  | 				XP_TEXT("error while evaluating: %d\n"), lsp->errnum); | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-18 11:34:35 +00:00
										 |  |  | 	xp_lsp_close (lsp); | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-21 03:31:39 +00:00
										 |  |  | #ifdef __linux
 | 
					
						
							| 
									
										
										
										
											2005-02-05 05:18:20 +00:00
										 |  |  | 	muntrace (); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |