added partial code to support close ("name", "r or w")
This commit is contained in:
parent
cefda5ffc6
commit
9d635709f3
@ -1,4 +1,68 @@
|
|||||||
/** @page awk AWK
|
/** @page awk AWK
|
||||||
|
|
||||||
AWK Interpreter
|
AWK Interpreter
|
||||||
|
|
||||||
|
VARIABLE DECLARATION
|
||||||
|
|
||||||
|
QSE_AWK_EXPLICIT enables variable declaration. Variables declared are accessed
|
||||||
|
directly bypassing the global named map that stores undeclared variables.
|
||||||
|
The keyword global introduces a global variable and the keyword local introduces
|
||||||
|
a local variable. Local variable declaraion in a block should be located before
|
||||||
|
an expression or a statement appears.
|
||||||
|
|
||||||
|
@code
|
||||||
|
global g1, g2; #declares two global variables g1 and g2
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
local a1, a2, a3; # declares three local variables
|
||||||
|
|
||||||
|
g1 = 300; a1 = 200;
|
||||||
|
|
||||||
|
{
|
||||||
|
local a1; # this a1 hides the a1 at the outer scope
|
||||||
|
local g1; # this g1 hides the global g1
|
||||||
|
a1 = 10; g1 = 5;
|
||||||
|
print a1, g1; # it prints 10 and 5
|
||||||
|
}
|
||||||
|
|
||||||
|
print a1, g1; # it prints 200 and 300
|
||||||
|
}
|
||||||
|
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
However, turning on QSE_AWK_EXPLICIT does not disable named variables.
|
||||||
|
To disable named variables, you must turn off QSE_AWK_IMPLICIT.
|
||||||
|
|
||||||
|
INCLUDE
|
||||||
|
|
||||||
|
The \@include directive inserts the contents of the object specified in the
|
||||||
|
following string, typically a file name, as if they appeared in the source
|
||||||
|
stream being processed. The directive can only be used at the outmost scope
|
||||||
|
where global variable declarations, BEGIN, END, and/or pattern-action blocks
|
||||||
|
appear. To use @include, you must turn on QSE_AWK_INCLUDE.
|
||||||
|
|
||||||
|
@code
|
||||||
|
@include "abc.awk"
|
||||||
|
BEGIN { func_in_abc (); }
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
TWO-WAY PIPE
|
||||||
|
|
||||||
|
The two-way pipe indicated by '||' is supproted, in addition to the one-way
|
||||||
|
pipe indicated by '|'. Turn on QSE_AWK_RWPIPE to enable the two-way pipe.
|
||||||
|
|
||||||
|
@code
|
||||||
|
BEGIN {
|
||||||
|
print "15" || "sort";
|
||||||
|
print "14" || "sort";
|
||||||
|
print "13" || "sort";
|
||||||
|
print "12" || "sort";
|
||||||
|
print "11" || "sort";
|
||||||
|
#close the input as sort emits when the input is closed
|
||||||
|
close ("sort", "r");
|
||||||
|
while (("sort" || getline x) > 0) print x;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.h 267 2009-08-25 09:50:07Z hyunghwan.chung $
|
* $Id: awk.h 270 2009-08-26 12:59:08Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -351,6 +351,12 @@ enum qse_awk_rio_mode_t
|
|||||||
};
|
};
|
||||||
typedef enum qse_awk_rio_mode_t qse_awk_rio_mode_t;
|
typedef enum qse_awk_rio_mode_t qse_awk_rio_mode_t;
|
||||||
|
|
||||||
|
enum qse_awk_rio_close_opt_t
|
||||||
|
{
|
||||||
|
QSE_AWK_RIO_CLOSE_R = (1 << 0),
|
||||||
|
QSE_AWK_RIO_CLOSE_W = (1 << 1)
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_awk_rio_arg_t defines the data structure passed to a runtime
|
* The qse_awk_rio_arg_t defines the data structure passed to a runtime
|
||||||
* I/O handler. An I/O handler should inspect the @a mode field and the
|
* I/O handler. An I/O handler should inspect the @a mode field and the
|
||||||
@ -361,9 +367,10 @@ typedef enum qse_awk_rio_mode_t qse_awk_rio_mode_t;
|
|||||||
typedef struct qse_awk_rio_arg_t qse_awk_rio_arg_t;
|
typedef struct qse_awk_rio_arg_t qse_awk_rio_arg_t;
|
||||||
struct qse_awk_rio_arg_t
|
struct qse_awk_rio_arg_t
|
||||||
{
|
{
|
||||||
qse_awk_rio_mode_t mode; /**< [IN] I/O mode */
|
qse_awk_rio_mode_t mode; /**< [IN] I/O mode */
|
||||||
qse_char_t* name; /**< [IN] name of I/O object */
|
qse_char_t* name; /**< [IN] name of I/O object */
|
||||||
void* handle; /**< [OUT] I/O handle set by a handler */
|
int copt; /**< [IN] closing option */
|
||||||
|
void* handle; /**< [OUT] I/O handle set by a handler */
|
||||||
|
|
||||||
/*-- from here down, internal use only --*/
|
/*-- from here down, internal use only --*/
|
||||||
int type;
|
int type;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: fnc.c 259 2009-08-20 11:28:03Z hyunghwan.chung $
|
* $Id: fnc.c 270 2009-08-26 12:59:08Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ static int fnc_sprintf (qse_awk_rtx_t*, const qse_cstr_t*);
|
|||||||
static qse_awk_fnc_t sys_fnc[] =
|
static qse_awk_fnc_t sys_fnc[] =
|
||||||
{
|
{
|
||||||
/* io functions */
|
/* io functions */
|
||||||
{ {QSE_T("close"), 5}, 0, QSE_AWK_RIO, {1, 1, QSE_NULL}, fnc_close},
|
{ {QSE_T("close"), 5}, 0, QSE_AWK_RIO, {1, 2, QSE_NULL}, fnc_close},
|
||||||
{ {QSE_T("fflush"), 6}, 0, QSE_AWK_RIO, {0, 1, QSE_NULL}, fnc_fflush},
|
{ {QSE_T("fflush"), 6}, 0, QSE_AWK_RIO, {0, 1, QSE_NULL}, fnc_fflush},
|
||||||
|
|
||||||
/* string functions */
|
/* string functions */
|
||||||
@ -227,20 +227,20 @@ qse_awk_fnc_t* qse_awk_getfnc (
|
|||||||
return fnc;
|
return fnc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fnc_close (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
static int fnc_close (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||||
{
|
{
|
||||||
qse_size_t nargs;
|
qse_size_t nargs;
|
||||||
qse_awk_val_t* v, * a0;
|
qse_awk_val_t* v, * a0, * a1 = QSE_NULL;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
qse_char_t* name;
|
qse_char_t* name, * opt = QSE_NULL;
|
||||||
qse_size_t len;
|
qse_size_t len, optlen = 0;
|
||||||
|
|
||||||
nargs = qse_awk_rtx_getnargs (run);
|
nargs = qse_awk_rtx_getnargs (rtx);
|
||||||
QSE_ASSERT (nargs == 1);
|
QSE_ASSERT (nargs == 1 || nargs == 2);
|
||||||
/* TODO: support close (xxx, "to"/"from"/"rw"/"r"/"w"/????) */
|
|
||||||
|
|
||||||
a0 = qse_awk_rtx_getarg (run, 0);
|
a0 = qse_awk_rtx_getarg (rtx, 0);
|
||||||
|
a1 = qse_awk_rtx_getarg (rtx, 1);
|
||||||
QSE_ASSERT (a0 != QSE_NULL);
|
QSE_ASSERT (a0 != QSE_NULL);
|
||||||
|
|
||||||
if (a0->type == QSE_AWK_VAL_STR)
|
if (a0->type == QSE_AWK_VAL_STR)
|
||||||
@ -250,10 +250,29 @@ static int fnc_close (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
name = qse_awk_rtx_valtocpldup (run, a0, &len);
|
name = qse_awk_rtx_valtocpldup (rtx, a0, &len);
|
||||||
if (name == QSE_NULL) return -1;
|
if (name == QSE_NULL) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a1 != QSE_NULL)
|
||||||
|
{
|
||||||
|
if (a1->type == QSE_AWK_VAL_STR)
|
||||||
|
{
|
||||||
|
opt = ((qse_awk_val_str_t*)a1)->ptr;
|
||||||
|
optlen = ((qse_awk_val_str_t*)a1)->len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opt = qse_awk_rtx_valtocpldup (rtx, a1, &optlen);
|
||||||
|
if (opt == QSE_NULL)
|
||||||
|
{
|
||||||
|
if (a1->type != QSE_AWK_VAL_STR)
|
||||||
|
QSE_AWK_FREE (rtx->awk, name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
/* getline or print doesn't allow an emptry for the
|
/* getline or print doesn't allow an emptry for the
|
||||||
@ -272,30 +291,44 @@ static int fnc_close (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
|||||||
{
|
{
|
||||||
if (name[--len] == QSE_T('\0'))
|
if (name[--len] == QSE_T('\0'))
|
||||||
{
|
{
|
||||||
/* the name contains a null string.
|
/* the name contains a null charater.
|
||||||
* make close return -1 */
|
* make close return -1 */
|
||||||
n = -1;
|
n = -1;
|
||||||
goto skip_close;
|
goto skip_close;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n = qse_awk_rtx_closeio (run, name);
|
if (opt != QSE_NULL)
|
||||||
/*
|
{
|
||||||
if (n == -1 && run->errinf.num != QSE_AWK_EIONMNF)
|
if (optlen != 1 ||
|
||||||
|
(opt[0] != QSE_T('r') && opt[0] != QSE_T('w')))
|
||||||
|
{
|
||||||
|
n = -1;
|
||||||
|
goto skip_close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n = qse_awk_rtx_closeio (rtx, name, opt);
|
||||||
|
/* failure to close is not a critical error. instead, that is
|
||||||
|
* flagged by the return value of close().
|
||||||
|
if (n == -1 && rtx->errinf.num != QSE_AWK_EIONMNF)
|
||||||
{
|
{
|
||||||
if (a0->type != QSE_AWK_VAL_STR)
|
if (a0->type != QSE_AWK_VAL_STR)
|
||||||
QSE_AWK_FREE (run->awk, name);
|
QSE_AWK_FREE (rtx->awk, name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
skip_close:
|
skip_close:
|
||||||
if (a0->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, name);
|
if (a1 != QSE_NULL && a1->type != QSE_AWK_VAL_STR)
|
||||||
|
QSE_AWK_FREE (rtx->awk, opt);
|
||||||
|
|
||||||
v = qse_awk_rtx_makeintval (run, (qse_long_t)n);
|
if (a0->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, name);
|
||||||
|
|
||||||
|
v = qse_awk_rtx_makeintval (rtx, (qse_long_t)n);
|
||||||
if (v == QSE_NULL) return -1;
|
if (v == QSE_NULL) return -1;
|
||||||
|
|
||||||
qse_awk_rtx_setretval (run, v);
|
qse_awk_rtx_setretval (rtx, v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: rio.c 256 2009-08-16 13:44:20Z hyunghwan.chung $
|
* $Id: rio.c 270 2009-08-26 12:59:08Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -904,9 +904,10 @@ int qse_awk_rtx_closio_write (
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name)
|
int qse_awk_rtx_closeio (
|
||||||
|
qse_awk_rtx_t* rtx, const qse_char_t* name, const qse_char_t* opt)
|
||||||
{
|
{
|
||||||
qse_awk_rio_arg_t* p = run->rio.chain, * px = QSE_NULL;
|
qse_awk_rio_arg_t* p = rtx->rio.chain, * px = QSE_NULL;
|
||||||
|
|
||||||
while (p != QSE_NULL)
|
while (p != QSE_NULL)
|
||||||
{
|
{
|
||||||
@ -915,34 +916,58 @@ int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name)
|
|||||||
if (qse_strcmp (p->name, name) == 0)
|
if (qse_strcmp (p->name, name) == 0)
|
||||||
{
|
{
|
||||||
qse_awk_rio_fun_t handler;
|
qse_awk_rio_fun_t handler;
|
||||||
|
int copt = QSE_AWK_RIO_CLOSE_R | QSE_AWK_RIO_CLOSE_W;
|
||||||
handler = run->rio.handler[p->type & MASK_CLEAR];
|
|
||||||
if (handler != QSE_NULL)
|
if (opt != QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL);
|
if (opt[0] == QSE_T('r'))
|
||||||
if (handler (run, QSE_AWK_RIO_CLOSE, p, QSE_NULL, 0) <= -1)
|
|
||||||
{
|
{
|
||||||
/* this is not a run-time error.*/
|
if (p->type & MASK_RDWR) copt = QSE_AWK_RIO_CLOSE_R;
|
||||||
if (run->errinf.num == QSE_AWK_ENOERR)
|
else if (!(p->type & MASK_READ)) goto skip;
|
||||||
qse_awk_rtx_seterrnum (run, QSE_AWK_EIOIMPL, QSE_NULL);
|
}
|
||||||
return -1;
|
else
|
||||||
|
{
|
||||||
|
QSE_ASSERT (opt[0] == QSE_T('w'));
|
||||||
|
if (p->type & MASK_RDWR) copt = QSE_AWK_RIO_CLOSE_W;
|
||||||
|
else if (!(p->type & MASK_WRITE)) goto skip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (px != QSE_NULL) px->next = p->next;
|
handler = rtx->rio.handler[p->type & MASK_CLEAR];
|
||||||
else run->rio.chain = p->next;
|
if (handler != QSE_NULL)
|
||||||
|
{
|
||||||
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR, QSE_NULL);
|
||||||
|
p->copt = copt;
|
||||||
|
if (handler (rtx, QSE_AWK_RIO_CLOSE, p, QSE_NULL, 0) <= -1)
|
||||||
|
{
|
||||||
|
/* this is not a run-time error.*/
|
||||||
|
if (rtx->errinf.num == QSE_AWK_ENOERR)
|
||||||
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EIOIMPL, QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* TODO:
|
||||||
|
if (p->type & MASK_RDWR)
|
||||||
|
{
|
||||||
|
if partially closed don't destroy it yet...
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
QSE_AWK_FREE (run->awk, p->name);
|
if (px != QSE_NULL) px->next = p->next;
|
||||||
QSE_AWK_FREE (run->awk, p);
|
else rtx->rio.chain = p->next;
|
||||||
|
|
||||||
|
QSE_AWK_FREE (rtx->awk, p->name);
|
||||||
|
QSE_AWK_FREE (rtx->awk, p);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip:
|
||||||
px = p;
|
px = p;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_awk_rtx_seterrnum (run, QSE_AWK_EIONMNF, QSE_NULL);
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EIONMNF, QSE_NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: rio.h 196 2009-06-11 07:44:44Z hyunghwan.chung $
|
* $Id: rio.h 270 2009-08-26 12:59:08Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -44,7 +44,12 @@ int qse_awk_rtx_nextio_read (
|
|||||||
int qse_awk_rtx_nextio_write (
|
int qse_awk_rtx_nextio_write (
|
||||||
qse_awk_rtx_t* run, int out_type, const qse_char_t* name);
|
qse_awk_rtx_t* run, int out_type, const qse_char_t* name);
|
||||||
|
|
||||||
int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name);
|
int qse_awk_rtx_closeio (
|
||||||
|
qse_awk_rtx_t* run,
|
||||||
|
const qse_char_t* name,
|
||||||
|
const qse_char_t* opt
|
||||||
|
);
|
||||||
|
|
||||||
void qse_awk_rtx_cleario (qse_awk_rtx_t* run);
|
void qse_awk_rtx_cleario (qse_awk_rtx_t* run);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user