*** empty log message ***
This commit is contained in:
		@ -1,4 +1,4 @@
 | 
			
		||||
SRCS = awk.c tree.c parse.c run.c sa.c
 | 
			
		||||
SRCS = awk.c tree.c tab.c parse.c run.c sa.c
 | 
			
		||||
OBJS = $(SRCS:.c=.obj)
 | 
			
		||||
OUT = xpawk.lib
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $Id: awk.c,v 1.11 2006-01-24 16:14:28 bacon Exp $
 | 
			
		||||
 * $Id: awk.c,v 1.12 2006-01-29 18:28:14 bacon Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <xp/awk/awk.h>
 | 
			
		||||
@ -23,6 +23,12 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
 | 
			
		||||
		return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (xp_awk_tab_open(&awk->parse.func) == XP_NULL) {
 | 
			
		||||
		xp_str_close (&awk->token.name);
 | 
			
		||||
		if (awk->__dynamic) xp_free (awk);
 | 
			
		||||
		return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	awk->opt = 0;
 | 
			
		||||
	awk->errnum = XP_AWK_ENOERR;
 | 
			
		||||
 | 
			
		||||
@ -39,6 +45,7 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
 | 
			
		||||
	awk->tree.unnamed = XP_NULL;
 | 
			
		||||
	//awk->tree.funcs = XP_NULL;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	awk->lex.curc = XP_CHAR_EOF;
 | 
			
		||||
	awk->lex.ungotc_count = 0;
 | 
			
		||||
 | 
			
		||||
@ -49,14 +56,21 @@ int xp_awk_close (xp_awk_t* awk)
 | 
			
		||||
{
 | 
			
		||||
	xp_awk_clear (awk);
 | 
			
		||||
	if (xp_awk_detsrc(awk) == -1) return -1;
 | 
			
		||||
 | 
			
		||||
	xp_awk_tab_close(&awk->parse.func);
 | 
			
		||||
	xp_str_close (&awk->token.name);
 | 
			
		||||
 | 
			
		||||
	if (awk->__dynamic) xp_free (awk);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: write a function to clear awk->parse data structure.
 | 
			
		||||
//       this would be need either as a separate function or as a part of xp_awk_clear...
 | 
			
		||||
//       do i have to pass an option to xp_awk_clear to do this???
 | 
			
		||||
 | 
			
		||||
void xp_awk_clear (xp_awk_t* awk)
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
	/* clear parse trees */
 | 
			
		||||
	if (awk->tree.begin != XP_NULL) {
 | 
			
		||||
		xp_assert (awk->tree.begin->next == XP_NULL);
 | 
			
		||||
		xp_awk_clrpt (awk->tree.begin);
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * $Id: awk.h,v 1.20 2006-01-26 15:35:20 bacon Exp $
 | 
			
		||||
 * $Id: awk.h,v 1.21 2006-01-29 18:28:14 bacon Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _XP_AWK_AWK_H_
 | 
			
		||||
@ -14,6 +14,7 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <xp/awk/tree.h>
 | 
			
		||||
#include <xp/awk/tab.h>
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
@ -39,8 +40,9 @@ enum
 | 
			
		||||
	XP_AWK_EASSIGN, /* assignment statement expected */
 | 
			
		||||
	XP_AWK_EIDENT,  /* identifier expected */
 | 
			
		||||
	XP_AWK_EDUPBEGIN, /* duplicate BEGIN */
 | 
			
		||||
	XP_AWK_EDUPEND, /* duplicate END */
 | 
			
		||||
	XP_AWK_EDUPFUNC /* duplicate function name */
 | 
			
		||||
	XP_AWK_EDUPEND,   /* duplicate END */
 | 
			
		||||
	XP_AWK_EDUPFUNC,  /* duplicate function name */
 | 
			
		||||
	XP_AWK_EDUPNAME   /* duplicate name - function, variable, etc */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@ -94,6 +96,7 @@ struct xp_awk_t
 | 
			
		||||
	/* temporary information that the parser needs */
 | 
			
		||||
	struct
 | 
			
		||||
	{
 | 
			
		||||
		xp_awk_tab_t func;
 | 
			
		||||
		// TODO: locals, globals???
 | 
			
		||||
		xp_char_t* vars; /* global and local variable names... */
 | 
			
		||||
		xp_char_t* args; /* function arguments */
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,33 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $Id: hash.h,v 1.1 2005-11-07 16:02:44 bacon Exp $
 | 
			
		||||
 * $Id: hash.h,v 1.2 2006-01-29 18:28:14 bacon Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _XP_AWK_HASH_H_
 | 
			
		||||
#define _XP_AWK_HASH_H_
 | 
			
		||||
 | 
			
		||||
#ifdef __STAND_ALONE
 | 
			
		||||
#include <xp/awk/sa.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <xp/types.h>
 | 
			
		||||
#include <xp/macros.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct xp_awk_hash_t xp_awk_hash_t;
 | 
			
		||||
typedef struct xp_awk_hashdatum_t xp_awk_hashdatum_t;
 | 
			
		||||
 | 
			
		||||
struct xp_awk_hashdatum_t
 | 
			
		||||
{
 | 
			
		||||
	xp_char_t* key;
 | 
			
		||||
	void* value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct xp_awk_hash_t
 | 
			
		||||
{
 | 
			
		||||
	xp_size_t size;
 | 
			
		||||
	xp_size_t capa;
 | 
			
		||||
	xp_bool_t __dynamic;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										193
									
								
								ase/awk/parse.c
									
									
									
									
									
								
							
							
						
						
									
										193
									
								
								ase/awk/parse.c
									
									
									
									
									
								
							@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $Id: parse.c,v 1.36 2006-01-28 06:38:01 bacon Exp $
 | 
			
		||||
 * $Id: parse.c,v 1.37 2006-01-29 18:28:14 bacon Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <xp/awk/awk.h>
 | 
			
		||||
@ -75,6 +75,13 @@ enum {
 | 
			
		||||
	BINOP_MOD
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
 | 
			
		||||
	#define INLINE 
 | 
			
		||||
#else
 | 
			
		||||
	#define INLINE inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static xp_awk_node_t* __parse_progunit (xp_awk_t* awk);
 | 
			
		||||
static xp_awk_node_t* __parse_function (xp_awk_t* awk);
 | 
			
		||||
static xp_awk_node_t* __parse_begin (xp_awk_t* awk);
 | 
			
		||||
@ -109,10 +116,14 @@ static int __skip_spaces (xp_awk_t* awk);
 | 
			
		||||
static int __skip_comment (xp_awk_t* awk);
 | 
			
		||||
static int __classfy_ident (const xp_char_t* ident);
 | 
			
		||||
 | 
			
		||||
static xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name);
 | 
			
		||||
static xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name);
 | 
			
		||||
static xp_long_t __str_to_long (const xp_char_t* name);
 | 
			
		||||
 | 
			
		||||
static INLINE xp_size_t __add_func_name (xp_awk_t* awk, const xp_char_t* name);
 | 
			
		||||
static INLINE xp_size_t __find_func_name (xp_awk_t* awk, const xp_char_t* name);
 | 
			
		||||
static INLINE xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name);
 | 
			
		||||
static INLINE xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct __kwent 
 | 
			
		||||
{ 
 | 
			
		||||
	const xp_char_t* name; 
 | 
			
		||||
@ -188,9 +199,13 @@ int xp_awk_parse (xp_awk_t* awk)
 | 
			
		||||
 | 
			
		||||
		if (__parse_progunit(awk) == XP_NULL) {
 | 
			
		||||
			// TODO: cleanup the parse tree created so far....
 | 
			
		||||
			//       function tables also etc...
 | 
			
		||||
xp_printf (XP_TEXT("error - %d\n"), awk->errnum);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
xp_awk_prnpt(node);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum);
 | 
			
		||||
@ -207,24 +222,15 @@ static xp_awk_node_t* __parse_progunit (xp_awk_t* awk)
 | 
			
		||||
 | 
			
		||||
	if (MATCH(awk,TOKEN_FUNCTION)) {
 | 
			
		||||
		node = __parse_function(awk);
 | 
			
		||||
		if (node == XP_NULL) {
 | 
			
		||||
			// TODO: cleanup
 | 
			
		||||
			return XP_NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (node == XP_NULL) return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
	else if (MATCH(awk,TOKEN_BEGIN)) {
 | 
			
		||||
		node = __parse_begin (awk);
 | 
			
		||||
		if (node == XP_NULL) {
 | 
			
		||||
			// TODO: cleanup
 | 
			
		||||
			return XP_NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (node == XP_NULL) return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
	else if (MATCH(awk, TOKEN_END)) {
 | 
			
		||||
		node = __parse_end (awk);
 | 
			
		||||
		if (node == XP_NULL) {
 | 
			
		||||
			// TODO: cleanup
 | 
			
		||||
			return XP_NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (node == XP_NULL) return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
	/* TODO: process patterns and expressions */
 | 
			
		||||
	/* 
 | 
			
		||||
@ -239,55 +245,67 @@ static xp_awk_node_t* __parse_progunit (xp_awk_t* awk)
 | 
			
		||||
	else {
 | 
			
		||||
		/* pattern-less actions */
 | 
			
		||||
		node = __parse_action (awk);
 | 
			
		||||
		if (node == XP_NULL) {
 | 
			
		||||
			// TODO: cleanup
 | 
			
		||||
			return XP_NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (node == XP_NULL) return XP_NULL;
 | 
			
		||||
 | 
			
		||||
		// TODO: weave the action block into awk->tree.actions...
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
xp_awk_prnpt(node);
 | 
			
		||||
	return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xp_bool_t __function_defined (xp_awk_t* awk, const xp_char_t* name)
 | 
			
		||||
{
 | 
			
		||||
// TODO:  complete this...
 | 
			
		||||
	return xp_false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xp_awk_node_t* __parse_function (xp_awk_t* awk)
 | 
			
		||||
{
 | 
			
		||||
	xp_char_t* name;
 | 
			
		||||
	//xp_awk_func_t* func;
 | 
			
		||||
	xp_char_t* name_dup;
 | 
			
		||||
	xp_awk_node_t* body;
 | 
			
		||||
	xp_size_t fnpos; 
 | 
			
		||||
	xp_size_t nargs = 0;
 | 
			
		||||
 | 
			
		||||
	if (__get_token(awk) == -1) return XP_NULL;  
 | 
			
		||||
 | 
			
		||||
	/* function name */
 | 
			
		||||
	if (!MATCH(awk,TOKEN_IDENT)) PANIC (awk, XP_AWK_EIDENT);
 | 
			
		||||
 | 
			
		||||
	if (__function_defined(awk,XP_STR_BUF(&awk->token.name))) {
 | 
			
		||||
		PANIC (awk, XP_AWK_EDUPFUNC);
 | 
			
		||||
	name = XP_STR_BUF(&awk->token.name);
 | 
			
		||||
	if (__find_func_name(awk,name) != (xp_size_t)-1) {
 | 
			
		||||
// TODO: do i have to tell DUPFUNC from DUPNAME???
 | 
			
		||||
		//PANIC (awk, XP_AWK_EDUPFUNC);
 | 
			
		||||
		PANIC (awk, XP_AWK_EDUPNAME);
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	name = xp_strdup (XP_STR_BUF(&awk->token.name));
 | 
			
		||||
	if (name == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
 | 
			
		||||
// TODO: make this feature optional..
 | 
			
		||||
// find in the global variable list...
 | 
			
		||||
	if (__find_variable(awk,name) != (xp_size_t)-1) {
 | 
			
		||||
		PANIC (awk, XP_AWK_EDUPNAME);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fnpos = __add_func_name (awk, name);
 | 
			
		||||
	if (fnpos == -1) PANIC (awk, XP_AWK_ENOMEM);
 | 
			
		||||
 | 
			
		||||
	// TODO: move this strdup down the function....
 | 
			
		||||
	//       maybe just before func_t is allocated...
 | 
			
		||||
	name_dup = xp_strdup (name);
 | 
			
		||||
	if (name_dup == XP_NULL) {
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
		PANIC (awk, XP_AWK_ENOMEM);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* skip the function name */
 | 
			
		||||
	if (__get_token(awk) == -1) {
 | 
			
		||||
		xp_free (name);
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
		xp_free (name_dup);
 | 
			
		||||
		return XP_NULL;  
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!MATCH(awk,TOKEN_LPAREN)) {
 | 
			
		||||
		xp_free (name);
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
		xp_free (name_dup);
 | 
			
		||||
		PANIC (awk, XP_AWK_ELPAREN);
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	if (__get_token(awk) == -1) {
 | 
			
		||||
		xp_free (name);
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
		xp_free (name_dup);
 | 
			
		||||
		return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -295,75 +313,97 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
 | 
			
		||||
	if (MATCH(awk,TOKEN_RPAREN)) {
 | 
			
		||||
		/* no function parameter */
 | 
			
		||||
		if (__get_token(awk) == -1) {
 | 
			
		||||
			xp_free (name);
 | 
			
		||||
			__remove_func_name (awk, fnpos);
 | 
			
		||||
			xp_free (name_dup);
 | 
			
		||||
			return XP_NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		while (1) {
 | 
			
		||||
			if (!MATCH(awk,TOKEN_IDENT)) {
 | 
			
		||||
				xp_free (name);
 | 
			
		||||
				__remove_func_name (awk, fnpos);
 | 
			
		||||
				xp_free (name_dup);
 | 
			
		||||
				PANIC (awk, XP_AWK_EIDENT);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			nargs++;
 | 
			
		||||
			// TODO: push args to param list...
 | 
			
		||||
 | 
			
		||||
			if (__get_token(awk) == -1) {
 | 
			
		||||
				xp_free (name);
 | 
			
		||||
				__remove_func_name (awk, fnpos);
 | 
			
		||||
				xp_free (name_dup);
 | 
			
		||||
				return XP_NULL;
 | 
			
		||||
			}	
 | 
			
		||||
 | 
			
		||||
			if (MATCH(awk,TOKEN_RPAREN)) break;
 | 
			
		||||
 | 
			
		||||
			if (!MATCH(awk,TOKEN_COMMA)) {
 | 
			
		||||
				xp_free (name);
 | 
			
		||||
				__remove_func_name (awk, fnpos);
 | 
			
		||||
				xp_free (name_dup);
 | 
			
		||||
				PANIC (awk, XP_AWK_ECOMMA);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (__get_token(awk) == -1) {
 | 
			
		||||
				xp_free (name);
 | 
			
		||||
				__remove_func_name (awk, fnpos);
 | 
			
		||||
				xp_free (name_dup);
 | 
			
		||||
				return XP_NULL;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (__get_token(awk) == -1) {
 | 
			
		||||
			__remove_func_name (awk, fnpos);
 | 
			
		||||
// TODO: cleanup parameter name list
 | 
			
		||||
			xp_free (name);
 | 
			
		||||
			xp_free (name_dup);
 | 
			
		||||
			return XP_NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* check if the function body starts with a left brace */
 | 
			
		||||
	if (!MATCH(awk,TOKEN_LBRACE)) {
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
// TODO: cleanup parameter name list
 | 
			
		||||
		xp_free (name);
 | 
			
		||||
		xp_free (name_dup);
 | 
			
		||||
		PANIC (awk, XP_AWK_ELBRACE);
 | 
			
		||||
	}
 | 
			
		||||
	if (__get_token(awk) == -1) {
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
// TODO: cleanup parameter name list
 | 
			
		||||
		xp_free (name);
 | 
			
		||||
		xp_free (name_dup);
 | 
			
		||||
		return XP_NULL; 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* function body */
 | 
			
		||||
	/* actual function body */
 | 
			
		||||
	body = __parse_block (awk);
 | 
			
		||||
	if (body == XP_NULL) {
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
// TODO: cleanup parameter name list
 | 
			
		||||
		xp_free (name);
 | 
			
		||||
		xp_free (name_dup);
 | 
			
		||||
		return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	func = (xp_awk_func_t*) xp_malloc (xp_sizeof(xp_awk_func_t));
 | 
			
		||||
	if (func == XP_NULL) {
 | 
			
		||||
		xp_free (name);
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
		xp_free (name_dup);
 | 
			
		||||
		xp_awk_clrpt (body);
 | 
			
		||||
		return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	func->name = name;
 | 
			
		||||
	func->nargs = 0;
 | 
			
		||||
	func->body = body;
 | 
			
		||||
	func->name  = name_dup;
 | 
			
		||||
	func->nargs = nargs;
 | 
			
		||||
	func->body  = body;
 | 
			
		||||
 | 
			
		||||
	xp_assert (xp_awk_hash_get(&awk->tree.func, name_dup) == XP_NULL);
 | 
			
		||||
	if (xp_awk_hash_put(&awk->tree.func, name_dup, func) == XP_NULL) {
 | 
			
		||||
		__remove_func_name (awk, fnpos);
 | 
			
		||||
		xp_free (name_dup);
 | 
			
		||||
		xp_awk_clrpt (body);
 | 
			
		||||
		xp_free (func);
 | 
			
		||||
		PANIC (awk, XP_AWK_ENOMEM);
 | 
			
		||||
	}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* TODO: weave the function body into awk->tree.funcs */
 | 
			
		||||
	return body;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -422,6 +462,7 @@ static xp_awk_node_t* __parse_block (xp_awk_t* awk)
 | 
			
		||||
				// TODO: cleanup the variable name list...
 | 
			
		||||
				return XP_NULL; 
 | 
			
		||||
			}
 | 
			
		||||
			head = XP_NULL;
 | 
			
		||||
			goto skip_block_body;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -493,7 +534,7 @@ skip_block_body:
 | 
			
		||||
	block->lvc  = lvc;
 | 
			
		||||
	block->body = head;
 | 
			
		||||
 | 
			
		||||
	// TODO: cleanup the variable name list...
 | 
			
		||||
// TODO: cleanup the variable name list...
 | 
			
		||||
 | 
			
		||||
	return (xp_awk_node_t*)block;
 | 
			
		||||
}
 | 
			
		||||
@ -1682,23 +1723,6 @@ static int __classfy_ident (const xp_char_t* ident)
 | 
			
		||||
	return TOKEN_IDENT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name)
 | 
			
		||||
{
 | 
			
		||||
	return (xp_size_t)-1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name)
 | 
			
		||||
{
 | 
			
		||||
/*
 | 
			
		||||
	if (awk->curfunc != XP_NULL) {
 | 
			
		||||
		
 | 
			
		||||
// TODO: finish this....
 | 
			
		||||
	}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
	return (xp_size_t)-1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xp_long_t __str_to_long (const xp_char_t* name)
 | 
			
		||||
{
 | 
			
		||||
	xp_long_t n = 0;
 | 
			
		||||
@ -1710,3 +1734,38 @@ static xp_long_t __str_to_long (const xp_char_t* name)
 | 
			
		||||
 | 
			
		||||
	return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static INLINE xp_size_t __add_func_name (xp_awk_t* awk, const xp_char_t* name)
 | 
			
		||||
{
 | 
			
		||||
	xp_assert (__find_func_name(awk,name) == (xp_size_t)-1);
 | 
			
		||||
 | 
			
		||||
	return xp_awk_tab_adddatum(&awk->parse.func, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static INLINE int __remove_func_name (xp_awk_t* awk, xp_size_t index)
 | 
			
		||||
{
 | 
			
		||||
	return xp_awk_tab_remrange (&awk->parse.func, index, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static INLINE xp_size_t __find_func_name (xp_awk_t* awk, const xp_char_t* name)
 | 
			
		||||
{
 | 
			
		||||
	return xp_awk_tab_find(&awk->parse.func, name, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static INLINE xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name)
 | 
			
		||||
{
 | 
			
		||||
/*
 | 
			
		||||
	if (awk->curfunc != XP_NULL) {
 | 
			
		||||
		
 | 
			
		||||
// TODO: finish this....
 | 
			
		||||
	}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
	return (xp_size_t)-1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name)
 | 
			
		||||
{
 | 
			
		||||
	return (xp_size_t)-1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $Id: sa.h,v 1.7 2006-01-25 04:27:01 bacon Exp $
 | 
			
		||||
 * $Id: sa.h,v 1.8 2006-01-29 18:28:14 bacon Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _XP_AWK_SA_H_
 | 
			
		||||
@ -31,6 +31,9 @@
 | 
			
		||||
#define xp_strcmp wcscmp
 | 
			
		||||
#define xp_strlen wcslen
 | 
			
		||||
 | 
			
		||||
#define xp_memcpy memcpy
 | 
			
		||||
#define xp_memcmp memcmp
 | 
			
		||||
 | 
			
		||||
#define xp_va_start(pvar,param) va_start(pvar,param)
 | 
			
		||||
#define xp_va_list va_list
 | 
			
		||||
#define xp_va_end(pvar)      va_end(pvar)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										161
									
								
								ase/awk/tab.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								ase/awk/tab.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,161 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $Id: tab.c,v 1.1 2006-01-29 18:28:14 bacon Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <xp/awk/tab.h>
 | 
			
		||||
#ifndef __STAND_ALONE
 | 
			
		||||
#include <xp/bas/memory.h>
 | 
			
		||||
#include <xp/bas/assert.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
xp_awk_tab_t* xp_awk_tab_open (xp_awk_tab_t* tab)
 | 
			
		||||
{
 | 
			
		||||
	if (tab == XP_NULL) {
 | 
			
		||||
		tab = (xp_awk_tab_t*) xp_malloc (xp_sizeof(xp_awk_tab_t));
 | 
			
		||||
		if (tab == XP_NULL) return XP_NULL;
 | 
			
		||||
		tab->__dynamic = xp_true;
 | 
			
		||||
	}
 | 
			
		||||
	else tab->__dynamic = xp_false;
 | 
			
		||||
 | 
			
		||||
	tab->buf = XP_NULL;
 | 
			
		||||
	tab->size = 0;
 | 
			
		||||
	tab->capa = 0;
 | 
			
		||||
 | 
			
		||||
	return tab;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void xp_awk_tab_close (xp_awk_tab_t* tab)
 | 
			
		||||
{
 | 
			
		||||
	xp_awk_tab_clear (tab);
 | 
			
		||||
	if (tab->buf != XP_NULL) {
 | 
			
		||||
		xp_free (tab->buf);
 | 
			
		||||
		tab->buf = XP_NULL;
 | 
			
		||||
		tab->capa = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (tab->__dynamic) xp_free (tab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_getsize (xp_awk_tab_t* tab)
 | 
			
		||||
{
 | 
			
		||||
	return tab->size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_getcapa (xp_awk_tab_t* tab)
 | 
			
		||||
{
 | 
			
		||||
	return tab->capa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xp_awk_tab_t* xp_awk_tab_setcapa (xp_awk_tab_t* tab, xp_size_t capa)
 | 
			
		||||
{
 | 
			
		||||
	xp_char_t** tmp;
 | 
			
		||||
 | 
			
		||||
	if (tab->size > capa) {
 | 
			
		||||
		xp_awk_tab_remrange (tab, capa, tab->size - capa);
 | 
			
		||||
		xp_assert (tab->size <= capa);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (capa > 0) {
 | 
			
		||||
		tmp = (xp_char_t**)xp_realloc (
 | 
			
		||||
			tab->buf, xp_sizeof(xp_char_t*) * capa);
 | 
			
		||||
		if (tmp == XP_NULL) return XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		if (tab->buf != XP_NULL) xp_free (tab->buf);
 | 
			
		||||
		tmp = XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tab->buf = tmp;
 | 
			
		||||
	tab->capa = capa;
 | 
			
		||||
	
 | 
			
		||||
	return tab;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void xp_awk_tab_clear (xp_awk_tab_t* tab)
 | 
			
		||||
{
 | 
			
		||||
	xp_size_t i;
 | 
			
		||||
 | 
			
		||||
	xp_assert (tab != XP_NULL);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < tab->size; i++) {
 | 
			
		||||
		xp_free (tab->buf[i]);
 | 
			
		||||
		tab->buf[i] = XP_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tab->size = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_insdatum (
 | 
			
		||||
	xp_awk_tab_t* tab, xp_size_t index, const xp_char_t* value)
 | 
			
		||||
{
 | 
			
		||||
	xp_size_t i;
 | 
			
		||||
	xp_char_t* value_dup;
 | 
			
		||||
 | 
			
		||||
	value_dup = xp_strdup(value);
 | 
			
		||||
	if (value_dup == XP_NULL) return (xp_size_t)-1;
 | 
			
		||||
 | 
			
		||||
	if (index >= tab->capa) {
 | 
			
		||||
		xp_size_t capa;
 | 
			
		||||
 | 
			
		||||
		if (tab->capa <= 0) capa = (index + 1);
 | 
			
		||||
		else {
 | 
			
		||||
			do { capa = tab->capa * 2; } while (index >= capa);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (xp_awk_tab_setcapa(tab,capa) == XP_NULL) {
 | 
			
		||||
			xp_free (value_dup);
 | 
			
		||||
			return (xp_size_t)-1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = tab->size; i > index; i--) tab->buf[i] = tab->buf[i-1];
 | 
			
		||||
	tab->buf[index] = value_dup;
 | 
			
		||||
 | 
			
		||||
	if (index > tab->size) tab->size = index + 1;
 | 
			
		||||
	else tab->size++;
 | 
			
		||||
 | 
			
		||||
	return index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_remrange (
 | 
			
		||||
	xp_awk_tab_t* tab, xp_size_t index, xp_size_t count)
 | 
			
		||||
{
 | 
			
		||||
	xp_size_t i, j, k;
 | 
			
		||||
 | 
			
		||||
	if (index >= tab->size) return 0;
 | 
			
		||||
	if (count > tab->size - index) count = tab->size - index;
 | 
			
		||||
 | 
			
		||||
	i = index;
 | 
			
		||||
	j = index + count;
 | 
			
		||||
	k = index + count;
 | 
			
		||||
 | 
			
		||||
	while (i < k) {
 | 
			
		||||
		xp_free (tab->buf[i]);	
 | 
			
		||||
		if (j >= tab->size) 
 | 
			
		||||
		tab->buf[i] = (j >= tab->size)? XP_NULL: tab->buf[j];
 | 
			
		||||
		i++; j++;		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tab->size -= count;
 | 
			
		||||
	return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_adddatum (xp_awk_tab_t* tab, const xp_char_t* value)
 | 
			
		||||
{
 | 
			
		||||
	return xp_awk_tab_insdatum (tab, tab->size, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_find (
 | 
			
		||||
	xp_awk_tab_t* tab, const xp_char_t* value, xp_size_t index)
 | 
			
		||||
{
 | 
			
		||||
	xp_size_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = index; i < tab->size; i++) {
 | 
			
		||||
		if (xp_strcmp(tab->buf[i], value) == 0) return i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (xp_size_t)-1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										54
									
								
								ase/awk/tab.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								ase/awk/tab.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $Id: tab.h,v 1.1 2006-01-29 18:28:14 bacon Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _XP_AWK_TAB_H_
 | 
			
		||||
#define _XP_AWK_TAB_H_
 | 
			
		||||
 | 
			
		||||
#ifdef __STAND_ALONE
 | 
			
		||||
#include <xp/awk/sa.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <xp/types.h>
 | 
			
		||||
#include <xp/macros.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// TODO: you have to turn this into a hash table.
 | 
			
		||||
//	 as of now, this is an arrayed table.
 | 
			
		||||
 | 
			
		||||
typedef struct xp_awk_tab_t xp_awk_tab_t;
 | 
			
		||||
 | 
			
		||||
struct xp_awk_tab_t
 | 
			
		||||
{
 | 
			
		||||
	xp_char_t** buf;
 | 
			
		||||
	xp_size_t size;
 | 
			
		||||
	xp_size_t capa;
 | 
			
		||||
	xp_bool_t __dynamic;	
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
xp_awk_tab_t* xp_awk_tab_open (xp_awk_tab_t* tab);
 | 
			
		||||
void xp_awk_tab_close (xp_awk_tab_t* tab);
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_getsize (xp_awk_tab_t* tab);
 | 
			
		||||
xp_size_t xp_awk_tab_getcapa (xp_awk_tab_t* tab);
 | 
			
		||||
xp_awk_tab_t* xp_awk_tab_setcapa (xp_awk_tab_t* tab, xp_size_t capa);
 | 
			
		||||
 | 
			
		||||
void xp_awk_tab_clear (xp_awk_tab_t* tab);
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_insdatum (
 | 
			
		||||
	xp_awk_tab_t* tab, xp_size_t index, const xp_char_t* value);
 | 
			
		||||
xp_size_t xp_awk_tab_remrange (
 | 
			
		||||
	xp_awk_tab_t* tab, xp_size_t index, xp_size_t count);
 | 
			
		||||
 | 
			
		||||
xp_size_t xp_awk_tab_adddatum (xp_awk_tab_t* tab, const xp_char_t* value);
 | 
			
		||||
xp_size_t xp_awk_tab_find (
 | 
			
		||||
	xp_awk_tab_t* tab, const xp_char_t* value, xp_size_t index);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user