Sambar Server Documentation

ICScript Source Code - icscript.c


/*
** ICSCRIPT
**
**      Interactive JavaScript utility.
**
**		Confidential Property of Tod Sambar
**		(c) Copyright Tod Sambar 1998
**		All rights reserved.
**
** Usage:
**		icscript [-f<filename>]
**
*/
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<cspublic.h>

/*
** Here are the symbols for possible user input values.
*/
#define PROMPT          "%d> "

#define ACTION_GO		1
#define ACTION_QUIT		2
#define ACTION_RUN		3
#define ACTION_RESET	4

/*
** Local Arguments
*/
static char				filename[255];

/*
** Local Prototypes
*/
static void 		syntax_error(char *name, char *argv);
static CS_RETCODE	get_args(int argc, char **argv);
static CS_RETCODE	get_command(FILE *file, char *buf, int maxlen, 
							int *len, int *cmdp);
static void			error_callback(CS_CTX *ctx, CS_PROG *prog, 
							void *sactx, void *saconn, CS_ERROR *error);
static CS_RETCODE	ics_write(CS_CTX *ctx, void *sactx, void *saconn,
							CS_STACK *stack, CS_ARGS *args, int numargs, 
							CS_RESULT *result);

/*
** Function Arguments
*/
static CS_FUNCDEFN	funcs[] =
{
	{ "write",		ics_write,	CS_DATATYPE_VOID,
	  0,
	  CS_FUNCARGS_UNLIMITED, (CS_FUNCARG *)NULL,
	  "Core write function." }
};

/*
**  MAIN
**
**	Main program wrapper.
**
*/
int
main(argc, argv)
int		argc;
char	*argv[];
{
	int				cmd;
	int				info;
	int				buflen;
	int				flags;
	CS_CTX			*csctx;
	CS_PROG			*csprog;
	CS_MAIN			*csmain;
	char			buffer[1024];

	/* Initialization													*/
	filename[0] = '\0';

	/* Initialize the CScript Engine.									*/
	if (cs_ctx_init((void *)NULL, &csctx, &info) != CS_SUCCEED)
        exit (1);

	/* Define library functions											*/
	if (cs_package_define(csctx, "core",
		funcs, sizeof(funcs) / sizeof(CS_FUNCDEFN),
		(CS_CONSTDEFN *)NULL, 0) != CS_SUCCEED)
	{
		(void)cs_ctx_exit(csctx);
    	exit (1);
	}

	if (cs_prog_alloc(csctx, error_callback, (void *)NULL, &csprog) 
		!= CS_SUCCEED)
	{
		(void)cs_ctx_exit(csctx);
    	exit (1);
	}

	if (get_args(argc, argv) != CS_SUCCEED)
    	exit (1);

	if (filename[0] != '\0')
	{
		buflen = strlen(filename);
		flags = 0;
		if (strnicmp(&filename[buflen - 4], ".asp", 4) == 0)
			flags |= CS_PARSEFLAGS_ASP;

		/* PARSE the program											*/
		if (cs_prog_parsefile(csctx, csprog, filename, flags) != CS_SUCCEED)
		{
			fprintf(stderr, "Parse of file %s failed.\n", filename);
			(void)cs_prog_free(csctx, csprog);
			(void)cs_ctx_exit(csctx);
    		exit (1);
		}

		/* Prepare the program											*/
		if (cs_prog_prepare(csctx, csprog, (void *)NULL, &csmain) 
			!= CS_SUCCEED)
		{
			fprintf(stderr, "Program preparation failed.\n");
			(void)cs_prog_free(csctx, csprog);
			(void)cs_ctx_exit(csctx);
    		exit (1);
		}

		/* RUN the program												*/
		if (cs_main_run(csmain) != CS_SUCCEED)
		{
			fprintf(stderr, "Program execution failed.\n");
			(void)cs_prog_free(csctx, csprog);
			(void)cs_ctx_exit(csctx);
    		exit (1);
		}
	}
	else
	{
		/*
		** Process each statement as a program...
		*/
		cmd = ACTION_GO;
		while (cmd != ACTION_QUIT)
		{
			if (get_command(stdin, buffer, 1000, &buflen, &cmd) 
				!= CS_SUCCEED)
			{
				cmd = ACTION_QUIT;
			}
	
			if (cmd == ACTION_QUIT)
				continue;
	
			if (cs_prog_parsebuf(csctx, csprog, buffer, buflen) != CS_SUCCEED)
			{
				fprintf(stdout, "ICSCRIPT:  Program parse failure.\n");
				(void)cs_prog_free(csctx, csprog);
				if (cs_prog_alloc(csctx, error_callback, (void *)NULL, 
					&csprog) != CS_SUCCEED)
				{
					(void)cs_prog_free(csctx, csprog);
					(void)cs_ctx_exit(csctx);
   					exit (1);
				}
				continue;
			}

			switch((int)cmd)
			{
			case ACTION_GO:
				break;
	
			case ACTION_RUN:
				if (cs_prog_prepare(csctx, csprog, (void *)NULL, &csmain) 
					!= CS_SUCCEED)
				{
					fprintf(stderr, "Program preparation failed.\n");
					(void)cs_prog_free(csctx, csprog);
					(void)cs_ctx_exit(csctx);
	   				exit (1);
				}

				if (cs_main_run(csmain) != CS_SUCCEED)
					fprintf(stderr, "Program execution failed.\n");
	
				fprintf(stdout, "\n");
				break;
			
			case ACTION_RESET:
				(void)cs_prog_free(csctx, csprog);
				if (cs_prog_alloc(csctx, error_callback, (void *)NULL, 
					&csprog) != CS_SUCCEED)
				{
					(void)cs_ctx_exit(csctx);
	   				exit (1);
				}
				break;
			}
		}
	}
	
	(void)cs_ctx_exit(csctx);

	return (0);
}


/*
**  GET_COMMAND
**
**	Read input and save until CMDEND or EOF is read.
**
**  Parameters:
**	buf 	Data area to read into.
**	len		Pointer to the length to fill in.
**	quit	Termination requested.
**
**  Returns:
**	CS_SUCCEED | CS_FAIL
*/
static CS_RETCODE
get_command(FILE *file, char *buf, int maxlen, int *len, int *cmdp)
{
	int		lineno;
	int		tlen;
	char	tbuf[1024];

	/* Initialization													*/
	lineno = 1;
	tlen = 0;
	*len = 0;
	*cmdp = ACTION_GO;

	for (;;)
	{
		fprintf(stdout, PROMPT, lineno);

		/* 
		** Read a line and check for exit 			
		*/
		if (fgets(buf, 1000, file) == (char *)NULL)
		{
			/* Got EOF or error.									*/
			return (CS_FAIL);
		}

		tlen = strlen(tbuf);

		/* Check to see if this is and EXIT command					*/
		if (((strnicmp(tbuf, "exit", 4) == 0) || 
		     (strnicmp(tbuf, "quit", 4) == 0)) &&
		    ((tbuf[4] == '\n') || (tbuf[4] == ' ') || (tbuf[4] == '\t')))
		{
			*cmdp = ACTION_QUIT;
			return (CS_SUCCEED);
		}

		/* Check to see if this is GO command 						*/
		if ((strnicmp(tbuf, "go", 2) == 0) && 
		    ((tbuf[2] == '\n') || (tbuf[2] == ' ') || (tbuf[2] == '\t')))
		{
			*cmdp = ACTION_GO;
			return (CS_SUCCEED);
		}

		/* Check to see if this is RUN command 						*/
		if ((strnicmp(tbuf, "run", 3) == 0) && 
		    ((tbuf[3] == '\n') || (tbuf[3] == ' ') || (tbuf[3] == '\t')))
		{
			*cmdp = ACTION_RUN;
			return (CS_SUCCEED);
		}

		/* Check to see if this is RESET command 					*/
		if ((strnicmp(tbuf, "reset", 5) == 0) && 
		    ((tbuf[5] == '\n') || (tbuf[5] == ' ') || (tbuf[5] == '\t')))
		{
			*len = 0;
			*cmdp = ACTION_RESET;
			return (CS_SUCCEED);
		}

		/* 
		** Append the data buffer onto the buffer
		*/
		if (tlen > (maxlen - *len))
		{
			fprintf(stdout, "Command too long...\n");
			return (CS_FAIL);
		}

		memcpy(&buf[*len], tbuf, tlen);
		*len += tlen;
	}

	return (CS_SUCCEED);
}

static void
error_callback(CS_CTX *ctx, CS_PROG *prog, void *sactx, void *saconn,
	CS_ERROR *error)
{
	/* Exception throw inside a try/catch block?						*/
	if (!error->e_flags & CS_ERRORFLAGS_TRYCATCH)
	{
		fprintf(stderr, "%s / %s (line %d)\n", 
			error->i_filename, error->i_func, error->i_linenum);
		fprintf(stderr, "    (%s) %s\n", 
			(error->e_severity == CS_SEVERITY_FATAL ? "FATAL Error" :
			(error->e_severity == CS_SEVERITY_ERROR ? "Error" : "Info")),
			error->e_msg);
		fprintf(stderr, "    %s [line %d]\n\n", 
			error->p_func, error->p_linenum);
	}

	return;
}

static CS_RETCODE
ics_write(CS_CTX *ctx, void *sactx, void *saconn, CS_STACK *stack, 
	CS_ARGS *args, int numargs, CS_RESULT *result)
{
	int			i;
	int			datatype;
	void		*value;

	for (i = 0; i < numargs; i++)
	{
		if (cs_arg_get(stack, args, i + 1, &datatype, &value) != CS_SUCCEED)
			return (CS_FAIL);

		switch (datatype)
		{
		case CS_DATATYPE_NUMBER:
			fprintf(stdout, "%f", *(double *)value);
			break;
		case CS_DATATYPE_INT:
			fprintf(stdout, "%ld", *(long *)value);
			break;
		case CS_DATATYPE_STRING:
			if (value == (void *)NULL)
				fprintf(stdout, "(null)");
			else
				fprintf(stdout, (char *)value);
			break;
		case CS_DATATYPE_VOID:
		case CS_DATATYPE_OBJECT:
		default:
			break;
		}
	}

	return (CS_SUCCEED);
}

/*
**  GET_ARGS
**
** 	This routine parses the command line arguments passed to the
** 	ICSCRIPT application.
**
*/
static CS_RETCODE
get_args(int argc, char **argv)
{
	int	p;
	int	j;

	/*
	** Are there any arguments to parse?
	*/
	if (argc < 1)
	{
		/*
		** We don't have any arguments, so we're all done.
		*/
		return (CS_SUCCEED);
	}

	/* Loop through the arguments					*/
	j = 1;

	while (j < argc)
	{
		/*
		** Input File
		*/
		if (strncmp(argv[j], "-f", 2) == 0)
		{
			p = 0;

			if (strlen(argv[j]) > 2)
			{
				p = 2;
			}
			else
			{
				/* More arguments?			*/
				if (j == argc -1)
				{
					syntax_error(argv[0], argv[j]);
					return (CS_FAIL);
				}
				j++;
			}

			/*
			** Save input filename in IODBC context
			*/
			strcpy(filename, &argv[j][p]);
		}
		/*
		** IODBC flags
		*/
		else
		{
			syntax_error(argv[0], argv[j]);
			return (CS_FAIL);
		}

		j++;
	}

	/*
	** All done.
	*/
	return (CS_SUCCEED);
}

/*
** SYNTAX_ERROR
**
** 	This routine is used to inform the user that a command-line
** 	syntax error occurred.
*/
static void
syntax_error(char *name, char *argv)
{
	/*
	** Print the error string.
	*/
	fprintf(stdout, "Correct syntax is: %s\n", name);
	fprintf(stdout, "\t\t[-f <infile>]\n");
	return;
}

© 2001 Sambar Technologies. All rights reserved. Terms of Use.