*** empty log message ***
This commit is contained in:
parent
ddeb802ade
commit
8dd23af516
@ -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;
|
||||
|
@ -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);
|
||||
|
240
ase/awk/func.c
240
ase/awk/func.c
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
30
ase/awk/sa.c
30
ase/awk/sa.c
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
2
ase/test/awk/t29.awk
Normal file
@ -0,0 +1,2 @@
|
||||
{ gsub ("abc", "&&&&"); print $0; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user