*** empty log message ***

This commit is contained in:
hyung-hwan 2006-08-13 16:05:04 +00:00
parent ddeb802ade
commit 8dd23af516
12 changed files with 325 additions and 46 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.c,v 1.69 2006-08-13 05:55:02 bacon Exp $
* $Id: awk.c,v 1.70 2006-08-13 16:04:32 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -177,6 +177,11 @@ int xp_awk_clear (xp_awk_t* awk)
return 0;
}
int xp_awk_getopt (xp_awk_t* awk)
{
return awk->option;
}
void xp_awk_setopt (xp_awk_t* awk, int opt)
{
awk->option = opt;

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h,v 1.95 2006-08-13 05:55:02 bacon Exp $
* $Id: awk.h,v 1.96 2006-08-13 16:04:32 bacon Exp $
*/
#ifndef _XP_AWK_AWK_H_
@ -96,41 +96,44 @@ enum
enum
{
/* allow undeclared variables */
XP_AWK_IMPLICIT = (1 << 0),
XP_AWK_IMPLICIT = (1 << 0),
/* variable requires explicit declaration */
XP_AWK_EXPLICIT = (1 << 1),
XP_AWK_EXPLICIT = (1 << 1),
/* a function name should not coincide to be a variable name */
XP_AWK_UNIQUE = (1 << 2),
XP_AWK_UNIQUE = (1 << 2),
/* allow variable shading */
XP_AWK_SHADING = (1 << 3),
XP_AWK_SHADING = (1 << 3),
/* support shift operators */
XP_AWK_SHIFT = (1 << 4),
XP_AWK_SHIFT = (1 << 4),
/* support comments by a hash sign */
XP_AWK_HASHSIGN = (1 << 5),
XP_AWK_HASHSIGN = (1 << 5),
/* support comments by double slashes */
XP_AWK_DBLSLASHES = (1 << 6),
XP_AWK_DBLSLASHES = (1 << 6),
/* support string concatenation in tokenization.
* this option can change the behavior of a certain construct.
* getline < "abc" ".def" is treated as if it is getline < "abc.def"
* when this option is on. If this option is off, the same expression
* is treated as if it is (getline < "abc") ".def". */
XP_AWK_STRCONCAT = (1 << 7),
XP_AWK_STRCONCAT = (1 << 7),
/* support getline and print */
XP_AWK_EXTIO = (1 << 8),
XP_AWK_EXTIO = (1 << 8),
/* support blockless patterns */
XP_AWK_BLOCKLESS = (1 << 9),
XP_AWK_BLOCKLESS = (1 << 9),
/* execution starts from main */
XP_AWK_RUNMAIN = (1 << 10)
XP_AWK_RUNMAIN = (1 << 10),
/* use 1 as the start index for string operations */
XP_AWK_STRINDEXONE = (1 << 11)
};
/* error code */
@ -253,6 +256,8 @@ int xp_awk_clear (xp_awk_t* awk);
int xp_awk_geterrnum (xp_awk_t* awk);
xp_size_t xp_awk_getsrcline (xp_awk_t* awk);
int xp_awk_getopt (xp_awk_t* awk);
void xp_awk_setopt (xp_awk_t* awk, int opt);
int xp_awk_parse (xp_awk_t* awk, xp_awk_srcios_t* srcios);

View File

@ -1,5 +1,5 @@
/*
* $Id: func.c,v 1.17 2006-08-04 17:36:40 bacon Exp $
* $Id: func.c,v 1.18 2006-08-13 16:04:32 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -16,28 +16,38 @@
#include <math.h>
#else
#include <stdlib.h>
#include <math.h>
#endif
static int __bfn_close (void* run);
static int __bfn_system (void* run);
static int __bfn_sin (void* run);
static int __bfn_close (xp_awk_t* awk, void* run);
static int __bfn_index (xp_awk_t* awk, void* run);
static int __bfn_length (xp_awk_t* awk, void* run);
static int __bfn_substr (xp_awk_t* awk, void* run);
static int __bfn_split (xp_awk_t* awk, void* run);
static int __bfn_system (xp_awk_t* awk, void* run);
static int __bfn_sin (xp_awk_t* awk, void* run);
/* TODO: move it under the awk structure... */
static xp_awk_bfn_t __sys_bfn[] =
{
/* ensure that this matches XP_AWK_BNF_XXX in func.h */
{ XP_T("close"), 5, XP_AWK_EXTIO, 1, 1, XP_NULL, __bfn_close },
{ XP_T("close"), 5, XP_AWK_EXTIO, 1, 1, __bfn_close },
{ XP_T("system"), 6, 0, 1, 1, __bfn_system },
{ XP_T("index"), 5, 0, 2, 2, XP_NULL, __bfn_index },
{ XP_T("length"), 6, 0, 1, 1, XP_NULL, __bfn_length },
{ XP_T("substr"), 6, 0, 2, 3, XP_NULL, __bfn_substr },
{ XP_T("split"), 5, 0, 2, 3, XP_NULL, __bfn_split },
{ XP_T("sin"), 3, 0, 1, 1, __bfn_sin },
{ XP_T("system"), 6, 0, 1, 1, XP_NULL, __bfn_system },
{ XP_T("sin"), 3, 0, 1, 1, XP_NULL, __bfn_sin },
{ XP_NULL, 0, 0, 0, 0, XP_NULL }
{ XP_NULL, 0, 0, 0, 0, XP_NULL, XP_NULL }
};
xp_awk_bfn_t* xp_awk_addbfn (
xp_awk_t* awk, const xp_char_t* name, int when_valid,
xp_size_t min_args, xp_size_t max_args, int (*handler)(void*))
xp_awk_t* awk, const xp_char_t* name, int when_valid,
xp_size_t min_args, xp_size_t max_args, const xp_char_t* arg_spec,
int (*handler)(xp_awk_t*,void*))
{
xp_awk_bfn_t* p;
@ -51,6 +61,7 @@ xp_awk_bfn_t* xp_awk_addbfn (
p->valid = when_valid;
p->min_args = min_args;
p->max_args = max_args;
p->arg_spec = arg_spec;
p->handler = handler;
p->next = awk->bfn.user;
@ -120,7 +131,7 @@ xp_awk_bfn_t* xp_awk_getbfn (xp_awk_t* awk, const xp_char_t* name)
return XP_NULL;
}
static int __bfn_close (void* run)
static int __bfn_close (xp_awk_t* awk, void* run)
{
xp_size_t nargs;
xp_str_t buf;
@ -213,7 +224,208 @@ skip_close:
return 0;
}
static int __bfn_system (void* run)
static int __bfn_index (xp_awk_t* awk, void* run)
{
xp_size_t nargs;
xp_awk_val_t* a0, * a1;
xp_char_t* str0, * str1, * ptr;
xp_size_t len0, len1;
xp_long_t idx;
int errnum;
nargs = xp_awk_getnargs (run);
xp_assert (nargs == 2);
a0 = xp_awk_getarg (run, 0);
a1 = xp_awk_getarg (run, 1);
if (a0->type == XP_AWK_VAL_STR)
{
str0 = ((xp_awk_val_str_t*)a0)->buf;
len0 = ((xp_awk_val_str_t*)a0)->len;
}
else
{
str0 = xp_awk_valtostr (a0, &errnum, xp_true, XP_NULL, &len0);
if (str0 == XP_NULL)
{
xp_awk_seterrnum (run, errnum);
return -1;
}
}
if (a1->type == XP_AWK_VAL_STR)
{
str1 = ((xp_awk_val_str_t*)a1)->buf;
len1 = ((xp_awk_val_str_t*)a1)->len;
}
else
{
str1 = xp_awk_valtostr (a1, &errnum, xp_true, XP_NULL, &len1);
if (str1 == XP_NULL)
{
xp_awk_seterrnum (run, errnum);
if (a0->type != XP_AWK_VAL_STR) xp_free (str0);
return -1;
}
}
ptr = xp_strxnstr (str0, len0, str1, len1);
idx = (ptr == XP_NULL)? -1: (xp_long_t)(ptr - str0);
if (xp_awk_getopt(awk) & XP_AWK_STRINDEXONE) idx = idx + 1;
if (a0->type != XP_AWK_VAL_STR) xp_free (str0);
if (a1->type != XP_AWK_VAL_STR) xp_free (str1);
a0 = xp_awk_makeintval (run, idx);
if (a0 == XP_NULL)
{
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
return -1;
}
xp_awk_setretval (run, a0);
return 0;
}
static int __bfn_length (xp_awk_t* awk, void* run)
{
xp_size_t nargs;
xp_awk_val_t* v;
xp_char_t* str;
xp_size_t len;
int errnum;
nargs = xp_awk_getnargs (run);
xp_assert (nargs == 1);
v = xp_awk_getarg (run, 0);
if (v->type == XP_AWK_VAL_STR)
{
len = ((xp_awk_val_str_t*)v)->len;
}
else
{
str = xp_awk_valtostr (v, &errnum, xp_true, XP_NULL, &len);
if (str == XP_NULL)
{
xp_awk_seterrnum (run, errnum);
return -1;
}
xp_free (str);
}
v = xp_awk_makeintval (run, len);
if (v == XP_NULL)
{
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
return -1;
}
xp_awk_setretval (run, v);
return 0;
}
static int __bfn_substr (xp_awk_t* awk, void* run)
{
xp_size_t nargs;
xp_awk_val_t* a0, * a1, * a2;
xp_char_t* str;
xp_size_t len;
xp_long_t lindex, lcount;
xp_real_t rindex, rcount;
int errnum, n;
nargs = xp_awk_getnargs (run);
xp_assert (nargs >= 2 && nargs <= 3);
a0 = xp_awk_getarg (run, 0);
a1 = xp_awk_getarg (run, 1);
a2 = (nargs >= 3)? xp_awk_getarg (run, 2): XP_NULL;
if (a0->type == XP_AWK_VAL_STR)
{
str = ((xp_awk_val_str_t*)a0)->buf;
len = ((xp_awk_val_str_t*)a0)->len;
}
else
{
str = xp_awk_valtostr (a0, &errnum, xp_true, XP_NULL, &len);
if (str == XP_NULL)
{
xp_awk_seterrnum (run, errnum);
return -1;
}
}
n = xp_awk_valtonum (a1, &lindex, &rindex);
if (n == -1)
{
if (a0->type != XP_AWK_VAL_STR) xp_free (str);
xp_awk_seterrnum (run, XP_AWK_EVALTYPE);
return -1;
}
if (n == 1) lindex = (xp_long_t)rindex;
if (a2 == XP_NULL) lcount = (xp_long_t)len;
else
{
n = xp_awk_valtonum (a2, &lcount, &rcount);
if (n == -1)
{
if (a0->type != XP_AWK_VAL_STR) xp_free (str);
xp_awk_seterrnum (run, XP_AWK_EVALTYPE);
return -1;
}
if (n == 1) lcount = (xp_long_t)rcount;
}
if (xp_awk_getopt(awk) & XP_AWK_STRINDEXONE) lindex = lindex - 1;
if (lindex >= len) lindex = len;
else if (lindex < 0) lindex = 0;
if (lcount < 0) lcount = 0;
else if (lcount > len - lindex) lcount = len - lindex;
a0 = xp_awk_makestrval (&str[lindex], (xp_size_t)lcount);
if (a0 == XP_NULL)
{
if (a0->type != XP_AWK_VAL_STR) xp_free (str);
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
return -1;
}
if (a0->type != XP_AWK_VAL_STR) xp_free (str);
xp_awk_setretval (run, a0);
return 0;
}
static int __bfn_split (xp_awk_t* awk, void* run)
{
xp_size_t nargs;
xp_awk_val_t* a0, * a1, * a2;
nargs = xp_awk_getnargs (run);
xp_assert (nargs >= 2 && nargs <= 3);
a0 = xp_awk_getarg (run, 0);
a1 = xp_awk_getarg (run, 1);
a2 = (nargs >= 3)? xp_awk_getarg (run, 2): XP_NULL;
/* TODO: what should i do when it is nil??? */
if (a1->type != XP_AWK_VAL_MAP)
{
}
/* TODO: */
xp_awk_setretval (run, a0);
return 0;
}
static int __bfn_system (xp_awk_t* awk, void* run)
{
xp_size_t nargs;
xp_char_t* cmd;
@ -227,7 +439,7 @@ static int __bfn_system (void* run)
xp_awk_getarg(run, 0), &errnum, xp_true, XP_NULL, XP_NULL);
if (cmd == XP_NULL)
{
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
xp_awk_seterrnum (run, errnum);
return -1;
}
@ -251,7 +463,7 @@ static int __bfn_system (void* run)
}
/* math functions */
static int __bfn_sin (void* run)
static int __bfn_sin (xp_awk_t* awk, void* run)
{
xp_size_t nargs;
xp_awk_val_t* v;

View File

@ -1,5 +1,5 @@
/*
* $Id: func.h,v 1.8 2006-08-03 05:05:47 bacon Exp $
* $Id: func.h,v 1.9 2006-08-13 16:04:32 bacon Exp $
*/
#ifndef _XP_AWK_FUNC_H_
@ -19,7 +19,8 @@ struct xp_awk_bfn_t
xp_size_t min_args;
xp_size_t max_args;
int (*handler) (void* run);
const xp_char_t* arg_spec;
int (*handler) (xp_awk_t* awk, void* run);
xp_awk_bfn_t* next;
};
@ -29,8 +30,9 @@ enum
/* ensure that this matches __sys_bfn in func.c */
XP_AWK_BFN_CLOSE,
XP_AWK_BFN_INDEX,
XP_AWK_BFN_LENGTH,
XP_AWK_BFN_SYSTEM,
XP_AWK_BFN_SIN
};
@ -40,10 +42,14 @@ extern "C" {
#endif
xp_awk_bfn_t* xp_awk_addbfn (
xp_awk_t* awk, const xp_char_t* name, int when_valid,
xp_size_t min_args, xp_size_t max_args, int (*handler)(void*));
xp_awk_t* awk, const xp_char_t* name, int when_valid,
xp_size_t min_args, xp_size_t max_args, const xp_char_t* arg_spec,
int (*handler)(xp_awk_t*,void*));
int xp_awk_delbfn (xp_awk_t* awk, const xp_char_t* name);
void xp_awk_clrbfn (xp_awk_t* awk);
xp_awk_bfn_t* xp_awk_getbfn (xp_awk_t* awk, const xp_char_t* name);
#ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/*
* $Id: parse.c,v 1.164 2006-08-13 05:55:02 bacon Exp $
* $Id: parse.c,v 1.165 2006-08-13 16:04:32 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -2501,6 +2501,8 @@ static xp_awk_nde_t* __parse_fncall (
}
else
{
/* parse function parameters */
while (1)
{
nde = __parse_expression (awk);
@ -2559,6 +2561,7 @@ static xp_awk_nde_t* __parse_fncall (
call->what.bfn.name_len = bfn->name_len;
call->what.bfn.min_args = bfn->min_args;
call->what.bfn.max_args = bfn->max_args;
call->what.bfn.arg_spec = bfn->arg_spec;
call->what.bfn.handler = bfn->handler;
call->args = head;

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c,v 1.165 2006-08-13 05:55:02 bacon Exp $
* $Id: run.c,v 1.166 2006-08-13 16:04:32 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -2102,7 +2102,7 @@ static xp_awk_val_t* __do_assignment_pos (
n = xp_awk_valtonum (v, &lv, &rv);
xp_awk_refdownval (run, v);
if (n == -1) PANIC (run, XP_AWK_EPOSIDX);
if (n == -1) PANIC (run, XP_AWK_EPOSIDX);
if (n == 1) lv = (xp_long_t)rv;
if (lv < 0) PANIC (run, XP_AWK_EPOSIDX);
@ -2824,7 +2824,7 @@ static xp_awk_val_t* __eval_binop_lshift (
n1 = xp_awk_valtonum (left, &l1, &r1);
n2 = xp_awk_valtonum (right, &l2, &r2);
if (n1 == -1 || n2 == -1) PANIC (run, XP_AWK_EOPERAND);
if (n1 == -1 || n2 == -1) PANIC (run, XP_AWK_EOPERAND);
n3 = n1 + (n2 << 1);
if (n3 == 0)
@ -2849,7 +2849,7 @@ static xp_awk_val_t* __eval_binop_rshift (
n1 = xp_awk_valtonum (left, &l1, &r1);
n2 = xp_awk_valtonum (right, &l2, &r2);
if (n1 == -1 || n2 == -1) PANIC (run, XP_AWK_EOPERAND);
if (n1 == -1 || n2 == -1) PANIC (run, XP_AWK_EOPERAND);
n3 = n1 + (n2 << 1);
if (n3 == 0)
@ -2874,7 +2874,7 @@ static xp_awk_val_t* __eval_binop_plus (
n1 = xp_awk_valtonum (left, &l1, &r1);
n2 = xp_awk_valtonum (right, &l2, &r2);
if (n1 == -1 || n2 == -1) PANIC (run, XP_AWK_EOPERAND);
if (n1 == -1 || n2 == -1) PANIC (run, XP_AWK_EOPERAND);
/*
n1 n2 n3
0 0 = 0
@ -3926,7 +3926,7 @@ static xp_awk_val_t* __eval_call (
if (call->what.bfn.handler != XP_NULL)
{
n = call->what.bfn.handler (run);
n = call->what.bfn.handler (run->awk, run);
}
}

View File

@ -1,5 +1,5 @@
/*
* $Id: sa.c,v 1.28 2006-07-17 04:17:40 bacon Exp $
* $Id: sa.c,v 1.29 2006-08-13 16:04:32 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -92,6 +92,34 @@ int xp_strxncmp (
return (*s1 > *s2)? 1: -1;
}
xp_char_t* xp_strxnstr (
const xp_char_t* str, xp_size_t strsz,
const xp_char_t* sub, xp_size_t subsz)
{
const xp_char_t* end, * subp;
if (subsz == 0) return (xp_char_t*)str;
if (strsz < subsz) return XP_NULL;
end = str + strsz - subsz;
subp = sub + subsz;
while (str <= end) {
const xp_char_t* x = str;
const xp_char_t* y = sub;
while (xp_true) {
if (y >= subp) return (xp_char_t*)str;
if (*x != *y) break;
x++; y++;
}
str++;
}
return XP_NULL;
}
xp_char_t* xp_strtok (const xp_char_t* s,
const xp_char_t* delim, xp_char_t** tok, xp_size_t* tok_len)
{

View File

@ -1,5 +1,5 @@
/*
* $Id: sa.h,v 1.28 2006-08-13 05:55:02 bacon Exp $
* $Id: sa.h,v 1.29 2006-08-13 16:04:32 bacon Exp $
*/
#ifndef _XP_AWK_SA_H_
@ -124,6 +124,11 @@ int xp_strxncmp (
const xp_char_t* s1, xp_size_t len1,
const xp_char_t* s2, xp_size_t len2);
#define xp_strxnstr xp_awk_strxnstr
xp_char_t* xp_strxnstr (
const xp_char_t* str, xp_size_t strsz,
const xp_char_t* sub, xp_size_t subsz);
#define xp_strtok xp_awk_strtok
xp_char_t* xp_strtok (const xp_char_t* s,
const xp_char_t* delim, xp_char_t** tok, xp_size_t* tok_len);

View File

@ -1,5 +1,5 @@
/*
* $Id: tree.h,v 1.67 2006-08-06 15:02:55 bacon Exp $
* $Id: tree.h,v 1.68 2006-08-13 16:04:32 bacon Exp $
*/
#ifndef _XP_AWK_TREE_H_
@ -252,7 +252,8 @@ struct xp_awk_nde_call_t
xp_size_t name_len;
xp_size_t min_args;
xp_size_t max_args;
int (*handler) (void* run);
const xp_char_t* arg_spec;
int (*handler) (xp_awk_t* awk, void* run);
} bfn;
/* xp_awk_bfn_t* bfn; */
} what;

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.c,v 1.71 2006-08-13 06:33:30 bacon Exp $
* $Id: awk.c,v 1.72 2006-08-13 16:05:04 bacon Exp $
*/
#include <xp/awk/awk.h>
@ -558,7 +558,7 @@ static int __main (int argc, xp_char_t* argv[])
opt = XP_AWK_EXPLICIT | XP_AWK_UNIQUE | XP_AWK_DBLSLASHES |
XP_AWK_SHADING | XP_AWK_IMPLICIT | XP_AWK_SHIFT |
XP_AWK_EXTIO | XP_AWK_BLOCKLESS;
XP_AWK_EXTIO | XP_AWK_BLOCKLESS | XP_AWK_STRINDEXONE;
if (argc == 2)
{

View File

@ -1,5 +1,17 @@
END {
print index ("abc", "abc");
print index ("abc", "b");
print index ("abc", "k");
print index ("abc", "kabc");
print "----------------------------";
print substr ("abc", "abcdefg", 5);
print substr ("abc", -1, 5);
print substr ("abc", 0, 5);
print substr ("abc", 1, 5);
print substr ("abc", 2.829, 5);
print substr ("abc", "3", 5);
print substr ("abc", 4, 5);
a[1] = 20;
substr (a, 3, 4);
}

2
ase/test/awk/t29.awk Normal file
View File

@ -0,0 +1,2 @@
{ gsub ("abc", "&&&&"); print $0; }