renamed QSE_AWK_EXTRAKWS to QSE_AWK_NEXTOFILE

fixed a minor glitch in qse_pio_t
fixed the nil field to xnil in qse_rbt_t to minimize collision with external header files since nil is a commonly found macro
added a simple optimization to qse_memcpy()
This commit is contained in:
hyung-hwan 2013-01-29 03:43:32 +00:00
parent c7d88c455a
commit 543376b7d9
11 changed files with 107 additions and 37 deletions

View File

@ -376,7 +376,7 @@ struct opttab_t
} opttab[] = } opttab[] =
{ {
{ QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") }, { QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") },
{ QSE_T("extrakws"), QSE_AWK_EXTRAKWS, QSE_T("enable nextofile,OFILENAME") }, { QSE_T("nextofile"), QSE_AWK_NEXTOFILE, QSE_T("enable nextofile & OFILENAME") },
{ QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") }, { QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") },
{ QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") }, { QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") },
{ QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("enable a newline to terminate a statement") }, { QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("enable a newline to terminate a statement") },

View File

@ -88,6 +88,43 @@ When QSEAWK parses a program, it classifies a series of input characters
into meaningful tokens. It can extract the smallest meaningful unit through into meaningful tokens. It can extract the smallest meaningful unit through
this tokenization process. this tokenization process.
### Reserved Words ###
The following words are reserved and cannot be used as a variable name,
a parameter name, or a function name.
- BEGIN
- END
- function
- @local
- @global
- @include
- if
- else
- while
- for
- do
- break
- continue
- return
- exit
- @abort
- delete
- @reset
- next
- nextfile
- nextofile
- print
- printf
- getline
However, these words can be used as normal names in the context of a
module call.
In practice, the predefined names used for built-in commands, functions,
and variables are treated as if they are reserved since you can't create
another denifition with the same name.
### Numbers ### ### Numbers ###
An integer begins with a numeric digit between 0 and 9 inclusive and can be An integer begins with a numeric digit between 0 and 9 inclusive and can be

View File

@ -1007,8 +1007,8 @@ enum qse_awk_trait_t
/** allows undeclared variables */ /** allows undeclared variables */
QSE_AWK_IMPLICIT = (1 << 0), QSE_AWK_IMPLICIT = (1 << 0),
/** enable abort,reset,nextofile,OFILENAME,@include. */ /** enables nextofile and NEXTOFILE */
QSE_AWK_EXTRAKWS = (1 << 2), QSE_AWK_NEXTOFILE = (1 << 0),
/** supports \b getline, \b print, \b printf, \b close, \b fflush, /** supports \b getline, \b print, \b printf, \b close, \b fflush,
* piping, and file rediction */ * piping, and file rediction */
@ -1110,8 +1110,8 @@ enum qse_awk_trait_t
QSE_AWK_STRIPSTRSPC | QSE_AWK_NCMPONSTR | QSE_AWK_STRICTNAMING, QSE_AWK_STRIPSTRSPC | QSE_AWK_NCMPONSTR | QSE_AWK_STRICTNAMING,
QSE_AWK_MODERN = QSE_AWK_MODERN =
QSE_AWK_CLASSIC | QSE_AWK_EXTRAKWS | QSE_AWK_FLEXMAP | QSE_AWK_CLASSIC | QSE_AWK_FLEXMAP |
QSE_AWK_RWPIPE | QSE_AWK_TOLERANT QSE_AWK_RWPIPE | QSE_AWK_TOLERANT | QSE_AWK_NEXTOFILE
}; };
typedef enum qse_awk_trait_t qse_awk_trait_t; typedef enum qse_awk_trait_t qse_awk_trait_t;

View File

@ -226,7 +226,7 @@ struct qse_rbt_t
qse_byte_t scale[2]; /**< length scale */ qse_byte_t scale[2]; /**< length scale */
qse_rbt_pair_t nil; /**< internal nil node */ qse_rbt_pair_t xnil; /**< internal nil node */
qse_size_t size; /**< number of pairs */ qse_size_t size; /**< number of pairs */
qse_rbt_pair_t* root; /**< root pair */ qse_rbt_pair_t* root; /**< root pair */

View File

@ -107,14 +107,18 @@ enum tok_t
TOK_ATSIGN, TOK_ATSIGN,
/* == begin reserved words == */ /* == begin reserved words == */
/* === extended reserved words === */
TOK_XGLOBAL,
TOK_XLOCAL,
TOK_XINCLUDE,
TOK_XABORT,
TOK_XRESET,
/* === normal reserved words === */
TOK_BEGIN, TOK_BEGIN,
TOK_END, TOK_END,
TOK_FUNCTION, TOK_FUNCTION,
TOK_XLOCAL,
TOK_XGLOBAL,
TOK_XINCLUDE,
TOK_IF, TOK_IF,
TOK_ELSE, TOK_ELSE,
TOK_WHILE, TOK_WHILE,
@ -124,15 +128,13 @@ enum tok_t
TOK_CONTINUE, TOK_CONTINUE,
TOK_RETURN, TOK_RETURN,
TOK_EXIT, TOK_EXIT,
TOK_XABORT, TOK_DELETE,
TOK_NEXT, TOK_NEXT,
TOK_NEXTFILE, TOK_NEXTFILE,
TOK_NEXTOFILE, TOK_NEXTOFILE,
TOK_DELETE,
TOK_XRESET,
TOK_PRINT, TOK_PRINT,
TOK_PRINTF, TOK_PRINTF,
TOK_GETLINE, TOK_GETLINE,
/* == end reserved words == */ /* == end reserved words == */
@ -292,7 +294,7 @@ static kwent_t kwtab[] =
{ { QSE_T("in"), 2 }, TOK_IN, 0 }, { { QSE_T("in"), 2 }, TOK_IN, 0 },
{ { QSE_T("next"), 4 }, TOK_NEXT, QSE_AWK_PABLOCK }, { { QSE_T("next"), 4 }, TOK_NEXT, QSE_AWK_PABLOCK },
{ { QSE_T("nextfile"), 8 }, TOK_NEXTFILE, QSE_AWK_PABLOCK }, { { QSE_T("nextfile"), 8 }, TOK_NEXTFILE, QSE_AWK_PABLOCK },
{ { QSE_T("nextofile"), 9 }, TOK_NEXTOFILE, QSE_AWK_PABLOCK | QSE_AWK_EXTRAKWS }, { { QSE_T("nextofile"), 9 }, TOK_NEXTOFILE, QSE_AWK_PABLOCK | QSE_AWK_NEXTOFILE },
{ { QSE_T("print"), 5 }, TOK_PRINT, QSE_AWK_RIO }, { { QSE_T("print"), 5 }, TOK_PRINT, QSE_AWK_RIO },
{ { QSE_T("printf"), 6 }, TOK_PRINTF, QSE_AWK_RIO }, { { QSE_T("printf"), 6 }, TOK_PRINTF, QSE_AWK_RIO },
{ { QSE_T("return"), 6 }, TOK_RETURN, 0 }, { { QSE_T("return"), 6 }, TOK_RETURN, 0 },
@ -310,6 +312,10 @@ struct global_t
static global_t gtab[] = static global_t gtab[] =
{ {
/*
* this table must match the order of the qse_awk_gbl_id_t enumerators
*/
/* output real-to-str conversion format for other cases than 'print' */ /* output real-to-str conversion format for other cases than 'print' */
{ QSE_T("CONVFMT"), 7, 0 }, { QSE_T("CONVFMT"), 7, 0 },
@ -334,7 +340,7 @@ static global_t gtab[] =
{ QSE_T("NR"), 2, QSE_AWK_PABLOCK }, { QSE_T("NR"), 2, QSE_AWK_PABLOCK },
/* current output file name */ /* current output file name */
{ QSE_T("OFILENAME"), 9, QSE_AWK_PABLOCK | QSE_AWK_EXTRAKWS }, { QSE_T("OFILENAME"), 9, QSE_AWK_PABLOCK | QSE_AWK_NEXTOFILE },
/* output real-to-str conversion format for 'print' */ /* output real-to-str conversion format for 'print' */
{ QSE_T("OFMT"), 4, QSE_AWK_RIO }, { QSE_T("OFMT"), 4, QSE_AWK_RIO },
@ -4741,6 +4747,11 @@ static int dup_ident_and_get_next (
if (get_token(awk) <= -1) goto oops; if (get_token(awk) <= -1) goto oops;
/* the identifier after ::
* allow reserved words as well since i view the whole name(mod::ident)
* as one segment. however, i don't want the identifier part to begin
* with @. some extended keywords begin with @ like @include.
* TOK_XGLOBAL to TOK_XRESET are excuded from the check for that reason. */
if (!MATCH(awk, TOK_IDENT) && !(MATCH_RANGE(awk, TOK_BEGIN, TOK_GETLINE))) if (!MATCH(awk, TOK_IDENT) && !(MATCH_RANGE(awk, TOK_BEGIN, TOK_GETLINE)))
{ {
SETERR_TOK (awk, QSE_AWK_EIDENT); SETERR_TOK (awk, QSE_AWK_EIDENT);

View File

@ -666,7 +666,7 @@ int qse_awk_rtx_setofilename (
qse_awk_val_t* tmp; qse_awk_val_t* tmp;
int n; int n;
if (rtx->awk->opt.trait & QSE_AWK_EXTRAKWS) if (rtx->awk->opt.trait & QSE_AWK_NEXTOFILE)
{ {
if (len == 0) tmp = qse_awk_val_zls; if (len == 0) tmp = qse_awk_val_zls;
else else

View File

@ -84,6 +84,25 @@ void* qse_memcpy (void* dst, const void* src, qse_size_t n)
qse_byte_t* d; qse_byte_t* d;
qse_byte_t* s; qse_byte_t* s;
if (n < 8)
{
d = (qse_byte_t*)dst;
s = (qse_byte_t*)src;
switch (n)
{
case 7: *d++ = *s++;
case 6: *d++ = *s++;
case 5: *d++ = *s++;
case 4: *d++ = *s++;
case 3: *d++ = *s++;
case 2: *d++ = *s++;
case 1: *d++ = *s++;
}
return dst;
}
if (n >= QSE_SIZEOF(qse_size_t) && IS_BOTH_ALIGNED(dst,src)) if (n >= QSE_SIZEOF(qse_size_t) && IS_BOTH_ALIGNED(dst,src))
{ {
qse_size_t* du = (qse_size_t*)dst; qse_size_t* du = (qse_size_t*)dst;

View File

@ -1264,7 +1264,7 @@ create_process:
if (!(flags & QSE_PIO_NOCLOEXEC)) if (!(flags & QSE_PIO_NOCLOEXEC))
{ {
int fd = get_highest_fd (); int fd = get_highest_fd ();
while (--fd > 2) while (fd > 2)
{ {
if (fd == handle[0] || fd == handle[1] || if (fd == handle[0] || fd == handle[1] ||
fd == handle[2] || fd == handle[3] || fd == handle[2] || fd == handle[3] ||
@ -1280,6 +1280,7 @@ create_process:
pio->errnum = syserr_to_errnum (pserr); pio->errnum = syserr_to_errnum (pserr);
goto oops; goto oops;
} }
fd--;
} }
} }
@ -1419,7 +1420,7 @@ create_process:
/* close all other unknown open handles except /* close all other unknown open handles except
* stdin/out/err and the pipes. */ * stdin/out/err and the pipes. */
while (--fd > 2) while (fd > 2)
{ {
if (fd != handle[0] && fd != handle[1] && if (fd != handle[0] && fd != handle[1] &&
fd != handle[2] && fd != handle[3] && fd != handle[2] && fd != handle[3] &&
@ -1427,6 +1428,7 @@ create_process:
{ {
QSE_SYSCALL1 (dummy, SYS_close, fd); QSE_SYSCALL1 (dummy, SYS_close, fd);
} }
fd--;
} }
} }
@ -1610,7 +1612,7 @@ create_process:
/* close all other unknown open handles except /* close all other unknown open handles except
* stdin/out/err and the pipes. */ * stdin/out/err and the pipes. */
while (--fd > 2) while (fd > 2)
{ {
if (fd != handle[0] && fd != handle[1] && if (fd != handle[0] && fd != handle[1] &&
fd != handle[2] && fd != handle[3] && fd != handle[2] && fd != handle[3] &&
@ -1618,6 +1620,7 @@ create_process:
{ {
QSE_CLOSE (fd); QSE_CLOSE (fd);
} }
fd--;
} }
} }

View File

@ -51,7 +51,7 @@
#define ENSERT 3 #define ENSERT 3
#define INSERT 4 #define INSERT 4
#define IS_NIL(rbt,x) ((x) == &((rbt)->nil)) #define IS_NIL(rbt,x) ((x) == &((rbt)->xnil))
#define LEFT 0 #define LEFT 0
#define RIGHT 1 #define RIGHT 1
#define left child[LEFT] #define left child[LEFT]
@ -76,8 +76,8 @@ QSE_INLINE pair_t* qse_rbt_allocpair (
n->color = QSE_RBT_RED; n->color = QSE_RBT_RED;
n->parent = QSE_NULL; n->parent = QSE_NULL;
n->child[LEFT] = &rbt->nil; n->child[LEFT] = &rbt->xnil;
n->child[RIGHT] = &rbt->nil; n->child[RIGHT] = &rbt->xnil;
KLEN(n) = klen; KLEN(n) = klen;
if (kcop == QSE_RBT_COPIER_SIMPLE) if (kcop == QSE_RBT_COPIER_SIMPLE)
@ -231,13 +231,13 @@ int qse_rbt_init (rbt_t* rbt, mmgr_t* mmgr, int kscale, int vscale)
rbt->mancbs = &mancbs[0]; rbt->mancbs = &mancbs[0];
/* self-initializing nil */ /* self-initializing nil */
QSE_MEMSET(&rbt->nil, 0, QSE_SIZEOF(rbt->nil)); QSE_MEMSET(&rbt->xnil, 0, QSE_SIZEOF(rbt->xnil));
rbt->nil.color = QSE_RBT_BLACK; rbt->xnil.color = QSE_RBT_BLACK;
rbt->nil.left = &rbt->nil; rbt->xnil.left = &rbt->xnil;
rbt->nil.right = &rbt->nil; rbt->xnil.right = &rbt->xnil;
/* root is set to nil initially */ /* root is set to nil initially */
rbt->root = &rbt->nil; rbt->root = &rbt->xnil;
return 0; return 0;
} }
@ -546,7 +546,7 @@ static pair_t* insert (
if (x_par == QSE_NULL) if (x_par == QSE_NULL)
{ {
/* the tree contains no pair */ /* the tree contains no pair */
QSE_ASSERT (rbt->root == &rbt->nil); QSE_ASSERT (rbt->root == &rbt->xnil);
rbt->root = x_new; rbt->root = x_new;
} }
else else
@ -555,12 +555,12 @@ static pair_t* insert (
int n = rbt->mancbs->comper (rbt, kptr, klen, KPTR(x_par), KLEN(x_par)); int n = rbt->mancbs->comper (rbt, kptr, klen, KPTR(x_par), KLEN(x_par));
if (n > 0) if (n > 0)
{ {
QSE_ASSERT (x_par->right == &rbt->nil); QSE_ASSERT (x_par->right == &rbt->xnil);
x_par->right = x_new; x_par->right = x_new;
} }
else else
{ {
QSE_ASSERT (x_par->left == &rbt->nil); QSE_ASSERT (x_par->left == &rbt->xnil);
x_par->left = x_new; x_par->left = x_new;
} }
@ -666,7 +666,7 @@ pair_t* qse_rbt_cbsert (
if (x_par == QSE_NULL) if (x_par == QSE_NULL)
{ {
/* the tree contains no pair */ /* the tree contains no pair */
QSE_ASSERT (rbt->root == &rbt->nil); QSE_ASSERT (rbt->root == &rbt->xnil);
rbt->root = x_new; rbt->root = x_new;
} }
else else
@ -675,12 +675,12 @@ pair_t* qse_rbt_cbsert (
int n = rbt->mancbs->comper (rbt, kptr, klen, KPTR(x_par), KLEN(x_par)); int n = rbt->mancbs->comper (rbt, kptr, klen, KPTR(x_par), KLEN(x_par));
if (n > 0) if (n > 0)
{ {
QSE_ASSERT (x_par->right == &rbt->nil); QSE_ASSERT (x_par->right == &rbt->xnil);
x_par->right = x_new; x_par->right = x_new;
} }
else else
{ {
QSE_ASSERT (x_par->left == &rbt->nil); QSE_ASSERT (x_par->left == &rbt->xnil);
x_par->left = x_new; x_par->left = x_new;
} }

View File

@ -44,7 +44,7 @@ int main ()
} }
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt); qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
opt |= QSE_AWK_EXTRAKWS; opt |= QSE_AWK_NEXTOFILE;
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt); qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
psin[0].type = QSE_AWK_PARSESTD_STR; psin[0].type = QSE_AWK_PARSESTD_STR;

View File

@ -361,10 +361,10 @@ static int awk_main_2 (MyAwk& awk, int argc, qse_char_t* argv[])
cmdline_t cmdline; cmdline_t cmdline;
int n; int n;
awk.setTrait (awk.getTrait() | QSE_AWK_EXTRAKWS | QSE_AWK_FLEXMAP | QSE_AWK_RWPIPE); awk.setTrait (awk.getTrait() | QSE_AWK_FLEXMAP | QSE_AWK_RWPIPE | QSE_AWK_NEXTOFILE);
// ARGV[0] // ARGV[0]
if (awk.addArgument (QSE_T("awk08")) <= -1) if (awk.addArgument (QSE_T("awk25")) <= -1)
{ {
print_error (awk); print_error (awk);
return -1; return -1;