*** empty log message ***

This commit is contained in:
hyung-hwan 2006-09-03 15:47:11 +00:00
parent b82fbb2070
commit 3aab1e7631
7 changed files with 279 additions and 78 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h,v 1.107 2006-09-01 16:30:50 bacon Exp $
* $Id: awk.h,v 1.108 2006-09-03 15:46:49 bacon Exp $
*/
#ifndef _XP_AWK_AWK_H_
@ -372,6 +372,11 @@ xp_char_t* xp_awk_strxtok (
xp_awk_t* awk, const xp_char_t* s, xp_size_t len,
const xp_char_t* delim, xp_char_t** tok, xp_size_t* tok_len);
xp_char_t* xp_awk_strntok (
xp_awk_t* awk, const xp_char_t* s,
const xp_char_t* delim, xp_size_t delim_len,
xp_char_t** tok, xp_size_t* tok_len);
xp_char_t* xp_awk_strxntok (
xp_awk_t* awk, const xp_char_t* s, xp_size_t len,
const xp_char_t* delim, xp_size_t delim_len,

View File

@ -1,5 +1,5 @@
/*
* $Id: func.c,v 1.44 2006-09-02 14:58:27 bacon Exp $
* $Id: func.c,v 1.45 2006-09-03 15:46:49 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -499,12 +499,14 @@ static int __bfn_substr (xp_awk_t* awk, void* run)
static int __bfn_split (xp_awk_t* awk, void* run)
{
xp_size_t nargs;
xp_awk_val_t* a0, * a1, * a2, * t1, * t2, ** a1r;
xp_char_t* str, * p, * tok;
xp_size_t len, left, tok_len;
xp_awk_val_t* a0, * a1, * a2, * t1, * t2, ** a1ref;
xp_char_t* str, * str_free, * p, * tok;
xp_size_t str_len, str_left, tok_len;
xp_long_t num;
xp_char_t key[xp_sizeof(xp_long_t)*8+2];
xp_size_t key_len;
xp_char_t* fs_ptr, * fs_free;
xp_size_t fs_len;
nargs = xp_awk_getnargs (run);
xp_assert (nargs >= 2 && nargs <= 3);
@ -523,9 +525,9 @@ static int __bfn_split (xp_awk_t* awk, void* run)
return -1;
}
a1r = (xp_awk_val_t**)((xp_awk_val_ref_t*)a1)->adr;
if ((*a1r)->type != XP_AWK_VAL_NIL &&
(*a1r)->type != XP_AWK_VAL_MAP)
a1ref = (xp_awk_val_t**)((xp_awk_val_ref_t*)a1)->adr;
if ((*a1ref)->type != XP_AWK_VAL_NIL &&
(*a1ref)->type != XP_AWK_VAL_MAP)
{
/* cannot change a scalar value to a map */
xp_awk_seterrnum (run, XP_AWK_ESCALARTOMAP);
@ -535,32 +537,93 @@ static int __bfn_split (xp_awk_t* awk, void* run)
if (a0->type == XP_AWK_VAL_STR)
{
str = ((xp_awk_val_str_t*)a0)->buf;
len = ((xp_awk_val_str_t*)a0)->len;
str_len = ((xp_awk_val_str_t*)a0)->len;
str_free = XP_NULL;
}
else
{
str = xp_awk_valtostr (run, a0, xp_true, XP_NULL, &len);
str = xp_awk_valtostr (run, a0, xp_true, XP_NULL, &str_len);
if (str == XP_NULL) return -1;
str_free = str;
}
if (a2 == XP_NULL)
{
/* get the value from FS */
t1 = xp_awk_getglobal (run, XP_AWK_GLOBAL_FS);
if (t1->type == XP_AWK_VAL_NIL)
{
fs_ptr = XP_T(" ");
fs_len = 1;
fs_free = XP_NULL;
}
else if (t1->type == XP_AWK_VAL_STR)
{
fs_ptr = ((xp_awk_val_str_t*)t1)->buf;
fs_len = ((xp_awk_val_str_t*)t1)->len;
fs_free = XP_NULL;
}
else
{
fs_ptr = xp_awk_valtostr (
run, t1, xp_true, XP_NULL, &fs_len);
if (fs_ptr == XP_NULL)
{
if (str_free != XP_NULL)
XP_AWK_FREE (awk, str_free);
return -1;
}
fs_free = fs_ptr;
}
}
else
{
if (a2->type == XP_AWK_VAL_STR)
{
fs_ptr = ((xp_awk_val_str_t*)a2)->buf;
fs_len = ((xp_awk_val_str_t*)a2)->len;
fs_free = XP_NULL;
}
else
{
fs_ptr = xp_awk_valtostr (
run, a2, xp_true, XP_NULL, &fs_len);
if (fs_ptr == XP_NULL)
{
if (str_free != XP_NULL)
XP_AWK_FREE (awk, str_free);
return -1;
}
fs_free = fs_ptr;
}
}
t1 = xp_awk_makemapval (run);
if (t1 == XP_NULL)
{
if (a0->type != XP_AWK_VAL_STR) XP_AWK_FREE (awk, str);
if (str_free != XP_NULL) XP_AWK_FREE (awk, str_free);
if (fs_free != XP_NULL) XP_AWK_FREE (awk, fs_free);
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
return -1;
}
xp_awk_refdownval (run, *a1r);
*a1r = t1;
xp_awk_refupval (*a1r);
xp_awk_refdownval (run, *a1ref);
*a1ref = t1;
xp_awk_refupval (*a1ref);
p = str; left = len; num = 0;
p = str; str_left = str_len; num = 0;
while (p != XP_NULL)
{
/* TODO: use FS when a2 is missing. apply a difference scheme */
p = xp_awk_strxtok (
awk, p, left, XP_T(" \t"), &tok, &tok_len);
if (fs_len <= 1)
{
p = xp_awk_strxntok (awk,
p, str_len, fs_ptr, fs_len, &tok, &tok_len);
}
else
{
/* TODO: FS regular expression */
xp_printf (XP_T("MULTI-CHARACTER FS NOT READY IN SPLIT\n"));
}
if (num == 0 && p == XP_NULL && tok_len == 0)
{
@ -574,7 +637,8 @@ static int __bfn_split (xp_awk_t* awk, void* run)
t2 = xp_awk_makestrval (run, tok, tok_len);
if (t2 == XP_NULL)
{
if (a0->type != XP_AWK_VAL_STR) XP_AWK_FREE (awk, str);
if (str_free != XP_NULL) XP_AWK_FREE (awk, str_free);
if (fs_free != XP_NULL) XP_AWK_FREE (awk, fs_free);
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
return -1;
}
@ -588,7 +652,8 @@ static int __bfn_split (xp_awk_t* awk, void* run)
((xp_awk_val_map_t*)t1)->map,
key, key_len, t2, XP_NULL) == -1)
{
if (a0->type != XP_AWK_VAL_STR) XP_AWK_FREE (awk, str);
if (str_free != XP_NULL) XP_AWK_FREE (awk, str_free);
if (fs_free != XP_NULL) XP_AWK_FREE (awk, fs_free);
xp_awk_seterrnum (run, XP_AWK_ENOMEM);
return -1;
}
@ -599,10 +664,11 @@ static int __bfn_split (xp_awk_t* awk, void* run)
xp_awk_refupval (t2);
num++;
len = len - (p - str);
str_len = str_left - (p - str + 1);
}
if (a0->type != XP_AWK_VAL_STR) XP_AWK_FREE (awk, str);
if (str_free != XP_NULL) XP_AWK_FREE (awk, str_free);
if (fs_free != XP_NULL) XP_AWK_FREE (awk, fs_free);
t1 = xp_awk_makeintval (run, num);
if (t1 == XP_NULL)

View File

@ -1,5 +1,5 @@
/*
* $Id: misc.c,v 1.12 2006-09-01 16:30:50 bacon Exp $
* $Id: misc.c,v 1.13 2006-09-03 15:46:49 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -491,7 +491,18 @@ xp_char_t* xp_awk_strxtok (
const xp_char_t* delim, xp_char_t** tok, xp_size_t* tok_len)
{
return xp_awk_strxntok (
awk, s, len, delim, xp_awk_strlen(delim), tok, tok_len);
awk, s, len,
delim, xp_awk_strlen(delim), tok, tok_len);
}
xp_char_t* xp_awk_strntok (
xp_awk_t* awk, const xp_char_t* s,
const xp_char_t* delim, xp_size_t delim_len,
xp_char_t** tok, xp_size_t* tok_len)
{
return xp_awk_strxntok (
awk, s, xp_awk_strlen(s),
delim, delim_len, tok, tok_len);
}
xp_char_t* xp_awk_strxntok (
@ -506,21 +517,48 @@ xp_char_t* xp_awk_strxntok (
xp_char_t c;
int delim_mode;
/* skip preceding space xp_char_tacters */
while (p < end && XP_AWK_ISSPACE(awk,*p)) p++;
if (delim == XP_NULL) delim_mode = 0;
#define __DELIM_NULL 0
#define __DELIM_EMPTY 1
#define __DELIM_SPACES 2
#define __DELIM_NOSPACES 3
#define __DELIM_COMPOSITE 4
if (delim == XP_NULL) delim_mode = __DELIM_NULL;
else
{
delim_mode = 1;
for (d = delim; d < delim_end; d++)
if (!XP_AWK_ISSPACE(awk,*d)) delim_mode = 2;
}
delim_mode = __DELIM_EMPTY;
if (delim_mode == 0)
for (d = delim; d < delim_end; d++)
{
if (XP_AWK_ISSPACE(awk,*d))
{
if (delim_mode == __DELIM_EMPTY)
delim_mode = __DELIM_SPACES;
else if (delim_mode == __DELIM_NOSPACES)
{
delim_mode = __DELIM_COMPOSITE;
break;
}
}
else
{
if (delim_mode == __DELIM_EMPTY)
delim_mode = __DELIM_NOSPACES;
else if (delim_mode == __DELIM_SPACES)
{
delim_mode = __DELIM_COMPOSITE;
break;
}
}
}
}
if (delim_mode == __DELIM_NULL)
{
/* when XP_NULL is given as "delim", it has an effect of cutting
preceding and trailing space xp_char_tacters off "s". */
/* when XP_NULL is given as "delim", it trims off the
* leading and trailing spaces characters off the source
* string "s" eventually. */
while (p < end && XP_AWK_ISSPACE(awk,*p)) p++;
while (p < end)
{
c = *p;
@ -533,8 +571,22 @@ xp_char_t* xp_awk_strxntok (
p++;
}
}
else if (delim_mode == 1)
else if (delim_mode == __DELIM_EMPTY)
{
/* each character in the source string "s" becomes a token. */
if (p < end)
{
c = *p;
sp = p;
ep = p++;
}
}
else if (delim_mode == __DELIM_SPACES)
{
/* each token is delimited by space characters. all leading
* and trailing spaces are removed. */
while (p < end && XP_AWK_ISSPACE(awk,*p)) p++;
while (p < end)
{
c = *p;
@ -543,8 +595,22 @@ xp_char_t* xp_awk_strxntok (
ep = p++;
}
}
else /* if (delim_mode == 2) */
else if (delim_mode == __DELIM_NOSPACES)
{
while (p < end)
{
c = *p;
for (d = delim; d < delim_end; d++)
{
if (c == *d) goto exit_loop;
}
if (sp == XP_NULL) sp = p;
ep = p++;
}
}
else /* if (delim_mode == __DELIM_COMPOSITE) */
{
while (p < end && XP_AWK_ISSPACE(awk,*p)) p++;
while (p < end)
{
c = *p;
@ -574,7 +640,9 @@ exit_loop:
*tok_len = ep - sp + 1;
}
return (p >= end)? XP_NULL: ((xp_char_t*)++p);
/* if XP_NULL is returned, this function should not be called anymore */
return (p >= end)? XP_NULL:
(delim_mode == __DELIM_EMPTY)? p: ((xp_char_t*)++p);
}
int xp_awk_printf (xp_awk_t* awk, const xp_char_t* fmt, ...)

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c,v 1.195 2006-09-02 14:58:28 bacon Exp $
* $Id: run.c,v 1.196 2006-09-03 15:46:49 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -4678,32 +4678,33 @@ static int __split_record (xp_awk_run_t* run)
xp_char_t* p, * tok;
xp_size_t len, tok_len, nflds;
xp_awk_val_t* v, * fs;
xp_char_t* fs_ptr;
xp_char_t* fs_ptr, * fs_free;
xp_size_t fs_len;
/* inrec should be cleared before __split_record is called */
xp_assert (run->inrec.nflds == 0);
/* get FS */
#if 0
fs = xp_awk_getglobal (run, XP_AWK_GLOBAL_FS);
if (fs->type == XP_AWK_VAL_NIL)
{
fs_ptr = XP_NULL;
fs_len = 0;
fs_ptr = XP_T(" ");
fs_len = 1;
fs_free = XP_NULL;
}
else if (fs->type == XP_AWK_VAL_STR)
{
fs_ptr = ((xp_awk_val_str_t*)fs)->buf;
fs_len = ((xp_awk_val_str_t*)fs)->len;
fs_free = XP_NULL;
}
else
{
fs_ptr = xp_awk_valtostr (
run, fs, xp_true, XP_NULL, &fs_len);
if (fs_ptr == XP_NULL) return -1;
fs_free = fs_ptr;
}
#endif
/* scan the input record to count the fields */
p = XP_AWK_STR_BUF(&run->inrec.line);
@ -4712,40 +4713,25 @@ static int __split_record (xp_awk_run_t* run)
nflds = 0;
while (p != XP_NULL)
{
/* TODO: support FS */
#if 0
if (fs->type == XP_AWK_VAL_NIL)
if (fs_len <= 1)
{
#endif
p = xp_awk_strxtok (
run->awk, p, len, XP_T(" \t"), &tok, &tok_len);
#if 0
}
else if (fs_len == 0)
{
}
else if (fs_len == 1)
{
p = xp_awk_strxntok (
run->awk, p, len,
fs_ptr, fs_len, &tok, &tok_len);
p = xp_awk_strxntok (run->awk,
p, len, fs_ptr, fs_len, &tok, &tok_len);
}
else
{
/* TODO: FS regular expression */
run->errnum = XP_AWK_EINTERNAL;
if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free);
xp_printf (XP_T("MULTI-CHARACTER FS NOT READY..\n"));
return -1;
}
#endif
if (nflds == 0 && p == XP_NULL && tok_len == 0)
{
/* there are no fields. it can just return here
* as __clear_record has been called before this */
#if 0
if (fs->type != XP_AWK_VAL_STR)
{
if (fs_ptr != XP_NULL) XP_AWK_FREE (run->awk, fs_ptr);
}
#endif
if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free);
return 0;
}
@ -4756,20 +4742,16 @@ static int __split_record (xp_awk_run_t* run)
(p - XP_AWK_STR_BUF(&run->inrec.line));
}
/* THIS PART IS WRONG. XP_AWK_FREE IT AFTER THE NEXT SPLIT LOOP */
#if 0
if (fs->type != XP_AWK_VAL_STR)
{
if (fs_ptr != XP_NULL) XP_AWK_FREE (run->awk, fs_ptr);
}
#endif
/* allocate space */
if (nflds > run->inrec.maxflds)
{
void* tmp = XP_AWK_MALLOC (
run->awk, xp_sizeof(*run->inrec.flds) * nflds);
if (tmp == XP_NULL) PANIC_I (run, XP_AWK_ENOMEM);
if (tmp == XP_NULL)
{
if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free);
PANIC_I (run, XP_AWK_ENOMEM);
}
if (run->inrec.flds != NULL)
XP_AWK_FREE (run->awk, run->inrec.flds);
@ -4783,8 +4765,24 @@ static int __split_record (xp_awk_run_t* run)
while (p != XP_NULL)
{
p = xp_awk_strxtok (
run->awk, p, len, XP_T(" \t"), &tok, &tok_len);
if (fs->type == XP_AWK_VAL_NIL)
{
p = xp_awk_strxntok (run->awk,
p, len, XP_T(" "), 1, &tok, &tok_len);
}
else if (fs_len <= 1)
{
p = xp_awk_strxntok (run->awk,
p, len, fs_ptr, fs_len, &tok, &tok_len);
}
else
{
/* TODO: FS regular expression */
run->errnum = XP_AWK_EINTERNAL;
if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free);
xp_printf (XP_T("MULTI-CHARACTER FS NOT READY..\n"));
return -1;
}
xp_assert ((tok != XP_NULL && tok_len > 0) || tok_len == 0);
@ -4794,7 +4792,10 @@ static int __split_record (xp_awk_run_t* run)
xp_awk_makestrval (run, tok, tok_len);
if (run->inrec.flds[run->inrec.nflds].val == XP_NULL)
{
if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free);
PANIC_I (run, XP_AWK_ENOMEM);
}
xp_awk_refupval (run->inrec.flds[run->inrec.nflds].val);
run->inrec.nflds++;
@ -4803,6 +4804,8 @@ static int __split_record (xp_awk_run_t* run)
(p - XP_AWK_STR_BUF(&run->inrec.line));
}
if (fs_free != XP_NULL) XP_AWK_FREE (run->awk, fs_free);
/* set the number of fields */
v = xp_awk_makeintval (run, (xp_long_t)nflds);
if (v == XP_NULL) PANIC_I (run, XP_AWK_ENOMEM);

47
ase/test/awk/t36.awk Normal file
View File

@ -0,0 +1,47 @@
# test cases
#
# input data []
# result:
# NF=0
#
# input data [abcdefg]
# NF=2
# 0 []
# 1 [bcdefg]
#
# input data [abdefg abcdefg]
# NF=3
# 0 []
# 1 [bdefg ]
# 2 [bcdefg]
#
# input data [ abcdefg hij a a]
# NF=4
# 0 [ ]
# 1 [bcdefg hij ]
# 2 [ ]
# 3 []
#
# input data [ abcdefg hij a a ]
# NF=4
# 0 [ ]
# 1 [bcdefg hij ]
# 2 [ ]
# 3 [ ]
#
# input data [aaaaa]
# NF=6
# 0 []
# 1 []
# 2 []
# 3 []
# 4 []
# 5 []
#
BEGIN { FS="a"; }
{
print "NF=" NF;
for (i = 0; i < NF; i++) print i " [" $(i+1) "]";
}

6
ase/test/awk/t37.awk Normal file
View File

@ -0,0 +1,6 @@
BEGIN { FS=" "; }
{
print "NF=" NF;
for (i = 0; i < NF; i++) print i " [" $(i+1) "]";
}

6
ase/test/awk/t38.awk Normal file
View File

@ -0,0 +1,6 @@
BEGIN {
split ("a b c d e", x, "");
for (j in x) print j "->" x[j];
print "-------------------";
}