/*
 * LANGUAGE TEST - Language testing main file
 *
 * Author:
 * Emile van Bergen, emile@evbergen.xs4all.nl
 *
 * Permission to redistribute an original or modified version of this program
 * in source, intermediate or object code form is hereby granted exclusively
 * under the terms of the GNU General Public License, version 2. Please see the
 * file COPYING for details, or refer to http://www.gnu.org/copyleft/gpl.html.
 *
 * History:
 * 2001/04/27 - EvB - Created
 */

char langtest_id[] = "LANGTEST - Copyright (C) 2001 Emile van Bergen.";


/*
 * INCLUDES & DEFINES
 */

#include <stdio.h>	/* For printf() */
#include <stdlib.h>	/* For malloc() */
#include <string.h>	/* For memset() */
#include <time.h>	/* For strftime(), localtime(), gmtime() */
#include <unistd.h>	/* For exit() */

#include <metadict.h>
#include <md5.h>

#define COMP_MEM	1	/* Use strings, not streams in lang comp. */
#include <language.h>
#include <srvtypes.h>
#include <debug.h>


#define STDTOO		0
#define EVALTOO		1


/*
 * FUNCTIONS
 */


#define LANGBUF		8192


void dotest(VM *vm, META *m, IFACE *ifaces, char *expr)
{
	INSN *c;
	ssize_t n;

	c = (INSN *)malloc(LANGBUF);
	if (!c) {
		msg(F_MISC, L_ERR, "main: ERROR: No memory for compiler "
				   "output!\n");
		_exit(1);
	}
	memset(c, 0xaa, LANGBUF);

	n = lang_compile(m, ifaces, expr, c, LANGBUF);
	hexdump((char *)c, n);
	lang_disassemble(m, c, n);
#if EVALTOO
	vm_chgcode(vm, c, n);
	vm_popall(vm);
	for(;;) {
		n = vm_run(m, vm);

		printf("--- Result code: %ld\n--- Stack:\n", (long)n); 
		fflush(stdout);
		vm_dumpstack(vm, m);
		printf("--- Request list:\n"); fflush(stdout);
		meta_printavlist(m, vm->head[VM_REQ], 0);
		printf("--- Reply list:\n"); fflush(stdout);
		meta_printavlist(m, vm->head[VM_REP], 0);

		if (n != VM_IFACETRAP) break;
		printf("\n***INTERFACE: %s\n", vm_getiface(vm)->name);
		
		printf("\n--- Stack:\n"); fflush(stdout); vm_dumpstack(vm, m);
		printf("--- Request list:\n"); fflush(stdout);
		meta_printavlist(m, vm->head[VM_REQ], 0);
		printf("--- Reply list:\n"); fflush(stdout);
		meta_printavlist(m, vm->head[VM_REP], 0);
	}
#endif
}


int main()
{
	META *m;
	IFACE *ifaces;
	VM *vm;
	char *s;

	msg_setthresh(F_LANG, L_DEBUG);

	/* Open dictionary */
	m = meta_newfromdict("/usr/local/etc/openradius/");
	if (!m) {
		msg(F_MISC, L_ERR, "main: ERROR: Could not open dictionary!\n");
		return 1;
	}

	/* Create fictive interface */
	ifaces = (IFACE *)malloc(sizeof(IFACE));
	if (!ifaces) {
		msg(F_MISC, L_ERR, "main: ERROR: Could not create ifaces!\n");
		return 1;
	}
	memset(ifaces, 0, sizeof(IFACE));
	strcpy(ifaces->name, "Iftest");

	/* Create new VM with no initial code, a 32 level deep stack and
	   an empty initial request and reply list */
	vm = vm_new(0, 0, 32, 0, 0, 0, 0);

#if STDTOO 
	s = "2+5*(1+2)*3+1";
	printf("TEST 1: %s\n", s);
	dotest(vm, m, s);

	s= "1 firstof 2 lastof \"H\\x31\\x32\\0377\\0ello\" . \"GRIC/User@Service\" afterfirst \"/\", 42";
	printf("TEST 2: %s\n", s);
	dotest(vm, m, s);

	s= "1 + 2 == 3 && RAD-Code = Access-Accept";
	printf("TEST 3: %s\n", s);
	dotest(vm, m, s);

	s= "Reply-Message = Framed-Route = \"Bullshit\"";
	printf("TEST 4: %s\n", s);
	dotest(vm, m, s);

	s= "Reply-Message || Reply-Message = \"Starting PPP for \" . Framed-IP-Address, Reply-Message = Reply-Message . \"\n\"";
	printf("TEST 5: %s\n", s);
	dotest(vm, m, s);

	/* s= "Reply-Message = \"You're coming in on \" . (NAS-Identifier || NAS-IP-Address)"; */
	s= "Reply-Message = \"You're coming in on \" . (NAS-IP-Address && NAS-IP-Address asstr || NAS-Identifier)";
	printf("TEST 6: %s\n", s);
	dotest(vm, m, s);

/*	s= "Reply-Message = (REP:RAD-Code == Access-Accept && \"Welcome, user!\" || \"Go away, imposter!\")"; */
	s= "Reply-Message = (REP:RAD-Code == Access-Accept && \"Welcome, user!\" || 1234)";
	printf("TEST 7: %s\n", s);
	dotest(vm, m, s);
#endif

	/* Clear stack and allocate expression buffer */
	vm_popall(vm);
	s = malloc(2048);
	if (!s) { msg(F_MISC, L_ERR, "main: No memory!\n"); return 1; }

	printf("\nExpression: ");
	while(fgets(s, 2047, stdin)) {
		if (s[0]) s[strlen(s) - 1] = 0;
		dotest(vm, m, ifaces, s);
		printf("\nExpression: ");
	}
	printf("\nDone.\n");

	free(s);
	meta_freeavlist(vm->head[VM_REQ]);
	meta_freeavlist(vm->head[VM_REP]);
	vm_del(vm);

	return 0;
}



syntax highlighted by Code2HTML, v. 0.9.1