- qse_strxfcpy(), qse_strfcpy() cleaned up code a little - renamed a few functions. qse_awk_strtok() to qse_awk_rtx_strtok(), etc
1561 lines
37 KiB
C
1561 lines
37 KiB
C
/*
|
|
* $Id: awk.h 501 2008-12-17 08:39:15Z baconevi $
|
|
*
|
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
#ifndef _QSE_AWK_AWK_H_
|
|
#define _QSE_AWK_AWK_H_
|
|
|
|
#include <qse/types.h>
|
|
#include <qse/macros.h>
|
|
#include <qse/cmn/map.h>
|
|
#include <qse/cmn/str.h>
|
|
|
|
/****o* AWK/AWK Interpreter
|
|
* DESCRIPTION
|
|
* The library includes an AWK interpreter that can be embedded into other
|
|
* applications or can run stand-alone.
|
|
*
|
|
* #include <qse/awk/awk.h>
|
|
******
|
|
*/
|
|
|
|
/****t* AWK/qse_awk_t
|
|
* NAME
|
|
* qse_awk_t - define an AWK type
|
|
* SYNOPSIS
|
|
*/
|
|
typedef struct qse_awk_t qse_awk_t;
|
|
/******/
|
|
|
|
/****t* AWK/qse_awk_rtx_t
|
|
* NAME
|
|
* qse_awk_rtx_t - define an AWK runtime context type
|
|
* SYNOPSIS
|
|
*/
|
|
typedef struct qse_awk_rtx_t qse_awk_rtx_t; /* (R)untime con(T)e(X)t */
|
|
/******/
|
|
|
|
typedef struct qse_awk_val_t qse_awk_val_t;
|
|
typedef struct qse_awk_eio_t qse_awk_eio_t; /* (E)xternal (IO) */
|
|
|
|
typedef struct qse_awk_prm_t qse_awk_prm_t;
|
|
typedef struct qse_awk_sio_t qse_awk_sio_t;
|
|
typedef struct qse_awk_rio_t qse_awk_rio_t;
|
|
typedef struct qse_awk_rcb_t qse_awk_rcb_t;
|
|
typedef struct qse_awk_rexfns_t qse_awk_rexfns_t;
|
|
|
|
typedef qse_real_t (*qse_awk_pow_t) (
|
|
void* data,
|
|
qse_real_t x,
|
|
qse_real_t y
|
|
);
|
|
|
|
typedef int (*qse_awk_sprintf_t) (
|
|
void* data,
|
|
qse_char_t* buf,
|
|
qse_size_t size,
|
|
const qse_char_t* fmt,
|
|
...
|
|
);
|
|
|
|
typedef qse_ssize_t (*qse_awk_io_t) (
|
|
int cmd,
|
|
void* arg,
|
|
qse_char_t* data,
|
|
qse_size_t count
|
|
);
|
|
|
|
struct qse_awk_eio_t
|
|
{
|
|
qse_awk_rtx_t* rtx; /* [IN] */
|
|
int type; /* [IN] console, file, pipe */
|
|
int mode; /* [IN] read, write, etc */
|
|
qse_char_t* name; /* [IN] */
|
|
void* data; /* [IN] */
|
|
void* handle; /* [OUT] */
|
|
|
|
/* input */
|
|
struct
|
|
{
|
|
qse_char_t buf[2048];
|
|
qse_size_t pos;
|
|
qse_size_t len;
|
|
qse_bool_t eof;
|
|
qse_bool_t eos;
|
|
} in;
|
|
|
|
/* output */
|
|
struct
|
|
{
|
|
qse_bool_t eof;
|
|
qse_bool_t eos;
|
|
} out;
|
|
|
|
qse_awk_eio_t* next;
|
|
};
|
|
|
|
struct qse_awk_prm_t
|
|
{
|
|
qse_awk_pow_t pow; /* required */
|
|
qse_awk_sprintf_t sprintf; /* required */
|
|
|
|
/* user-defined data passed to the functions above */
|
|
void* data; /* optional */
|
|
};
|
|
|
|
struct qse_awk_sio_t
|
|
{
|
|
qse_awk_io_t in;
|
|
qse_awk_io_t out;
|
|
void* data;
|
|
};
|
|
|
|
struct qse_awk_rio_t
|
|
{
|
|
qse_awk_io_t pipe;
|
|
qse_awk_io_t file;
|
|
qse_awk_io_t console;
|
|
void* data;
|
|
};
|
|
|
|
struct qse_awk_rcb_t
|
|
{
|
|
int (*on_enter) (
|
|
qse_awk_rtx_t* rtx, void* data);
|
|
|
|
void (*on_statement) (
|
|
qse_awk_rtx_t* rtx, qse_size_t line, void* data);
|
|
|
|
void (*on_exit) (
|
|
qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* data);
|
|
|
|
void* data;
|
|
};
|
|
|
|
struct qse_awk_rexfns_t
|
|
{
|
|
/* TODO: implement functions to get/set rexfns */
|
|
void* (*build) (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* ptn,
|
|
qse_size_t len,
|
|
int* errnum
|
|
);
|
|
|
|
int (*match) (
|
|
qse_awk_t* awk,
|
|
void* code,
|
|
int option,
|
|
const qse_char_t* str,
|
|
qse_size_t len,
|
|
const qse_char_t** mptr,
|
|
qse_size_t* mlen,
|
|
int* errnum
|
|
);
|
|
|
|
void (*free) (
|
|
qse_awk_t* awk,
|
|
void* code
|
|
);
|
|
|
|
qse_bool_t (*isempty) (
|
|
qse_awk_t* awk,
|
|
void* code
|
|
);
|
|
};
|
|
|
|
/* io function commands */
|
|
enum qse_awk_iocmd_t
|
|
{
|
|
QSE_AWK_IO_OPEN = 0,
|
|
QSE_AWK_IO_CLOSE = 1,
|
|
QSE_AWK_IO_READ = 2,
|
|
QSE_AWK_IO_WRITE = 3,
|
|
QSE_AWK_IO_FLUSH = 4,
|
|
QSE_AWK_IO_NEXT = 5
|
|
};
|
|
|
|
/* various options */
|
|
enum qse_awk_option_t
|
|
{
|
|
/* allow undeclared variables and implicit concatenation */
|
|
QSE_AWK_IMPLICIT = (1 << 0),
|
|
|
|
/* allow explicit variable declaration, the concatenation
|
|
* operator(.), and a parse-time function check. */
|
|
QSE_AWK_EXPLICIT = (1 << 1),
|
|
|
|
/* change ^ from exponentation to bitwise xor */
|
|
QSE_AWK_BXOR = (1 << 3),
|
|
|
|
/* support shift operators */
|
|
QSE_AWK_SHIFT = (1 << 4),
|
|
|
|
/* enable the idiv operator (double slashes) */
|
|
QSE_AWK_IDIV = (1 << 5),
|
|
|
|
/* support getline and print */
|
|
QSE_AWK_EIO = (1 << 7),
|
|
|
|
/* support dual direction pipe. QSE_AWK_EIO must be on */
|
|
QSE_AWK_RWPIPE = (1 << 8),
|
|
|
|
/* can terminate a statement with a new line */
|
|
QSE_AWK_NEWLINE = (1 << 9),
|
|
|
|
/* use 1 as the start index for string operations and ARGV */
|
|
QSE_AWK_BASEONE = (1 << 10),
|
|
|
|
/* strip off leading and trailing spaces when splitting a record
|
|
* into fields with a regular expression.
|
|
*
|
|
* Consider the following program.
|
|
* BEGIN { FS="[:[:space:]]+"; }
|
|
* {
|
|
* print "NF=" NF;
|
|
* for (i = 0; i < NF; i++) print i " [" $(i+1) "]";
|
|
* }
|
|
*
|
|
* The program splits " a b c " into [a], [b], [c] when this
|
|
* option is on while into [], [a], [b], [c], [] when it is off.
|
|
*/
|
|
QSE_AWK_STRIPSPACES = (1 << 11),
|
|
|
|
/* enable the nextoutfile keyword */
|
|
QSE_AWK_NEXTOFILE = (1 << 12),
|
|
|
|
/* cr + lf by default */
|
|
QSE_AWK_CRLF = (1 << 13),
|
|
|
|
/* enable the non-standard keyword reset */
|
|
QSE_AWK_RESET = (1 << 14),
|
|
|
|
/* allows the assignment of a map value to a variable */
|
|
QSE_AWK_MAPTOVAR = (1 << 15),
|
|
|
|
/* allows BEGIN, END, pattern-action blocks */
|
|
QSE_AWK_PABLOCK = (1 << 16)
|
|
};
|
|
|
|
/* error code */
|
|
enum qse_awk_errnum_t
|
|
{
|
|
QSE_AWK_ENOERR, /* no error */
|
|
QSE_AWK_EUNKNOWN, /* unknown error */
|
|
|
|
/* common errors */
|
|
QSE_AWK_EINVAL, /* invalid parameter or data */
|
|
QSE_AWK_ENOMEM, /* out of memory */
|
|
QSE_AWK_ENOSUP, /* not supported */
|
|
QSE_AWK_ENOPER, /* operation not allowed */
|
|
QSE_AWK_ENODEV, /* no such device */
|
|
QSE_AWK_ENOSPC, /* no space left on device */
|
|
QSE_AWK_EMFILE, /* too many open files */
|
|
QSE_AWK_EMLINK, /* too many links */
|
|
QSE_AWK_EAGAIN, /* resource temporarily unavailable */
|
|
QSE_AWK_ENOENT, /* "'%.*s' not existing */
|
|
QSE_AWK_EEXIST, /* file or data exists */
|
|
QSE_AWK_EFTBIG, /* file or data too big */
|
|
QSE_AWK_ETBUSY, /* system too busy */
|
|
QSE_AWK_EISDIR, /* is a directory */
|
|
QSE_AWK_EIOERR, /* i/o error */
|
|
|
|
/* mostly parse errors */
|
|
QSE_AWK_EOPEN, /* cannot open */
|
|
QSE_AWK_EREAD, /* cannot read */
|
|
QSE_AWK_EWRITE, /* cannot write */
|
|
QSE_AWK_ECLOSE, /* cannot close */
|
|
|
|
QSE_AWK_EINTERN, /* internal error */
|
|
QSE_AWK_ERUNTIME, /* run-time error */
|
|
QSE_AWK_EBLKNST, /* blocke nested too deeply */
|
|
QSE_AWK_EEXPRNST, /* expression nested too deeply */
|
|
|
|
QSE_AWK_ESINOP,
|
|
QSE_AWK_ESINCL,
|
|
QSE_AWK_ESINRD,
|
|
|
|
QSE_AWK_ESOUTOP,
|
|
QSE_AWK_ESOUTCL,
|
|
QSE_AWK_ESOUTWR,
|
|
|
|
QSE_AWK_ELXCHR, /* lexer came accross an wrong character */
|
|
QSE_AWK_ELXDIG, /* invalid digit */
|
|
QSE_AWK_ELXUNG, /* lexer failed to unget a character */
|
|
|
|
QSE_AWK_EENDSRC, /* unexpected end of source */
|
|
QSE_AWK_EENDCMT, /* a comment not closed properly */
|
|
QSE_AWK_EENDSTR, /* a string not closed with a quote */
|
|
QSE_AWK_EENDREX, /* unexpected end of a regular expression */
|
|
QSE_AWK_ELBRACE, /* left brace expected */
|
|
QSE_AWK_ELPAREN, /* left parenthesis expected */
|
|
QSE_AWK_ERPAREN, /* right parenthesis expected */
|
|
QSE_AWK_ERBRACK, /* right bracket expected */
|
|
QSE_AWK_ECOMMA, /* comma expected */
|
|
QSE_AWK_ESCOLON, /* semicolon expected */
|
|
QSE_AWK_ECOLON, /* colon expected */
|
|
QSE_AWK_ESTMEND, /* statement not ending with a semicolon */
|
|
QSE_AWK_EIN, /* keyword 'in' is expected */
|
|
QSE_AWK_ENOTVAR, /* not a variable name after 'in' */
|
|
QSE_AWK_EEXPRES, /* expression expected */
|
|
|
|
QSE_AWK_EFUNCTION, /* keyword 'function' is expected */
|
|
QSE_AWK_EWHILE, /* keyword 'while' is expected */
|
|
QSE_AWK_EASSIGN, /* assignment statement expected */
|
|
QSE_AWK_EIDENT, /* identifier expected */
|
|
QSE_AWK_EFUNNAME, /* not a valid function name */
|
|
QSE_AWK_EBLKBEG, /* BEGIN requires an action block */
|
|
QSE_AWK_EBLKEND, /* END requires an action block */
|
|
QSE_AWK_EDUPBEG, /* duplicate BEGIN */
|
|
QSE_AWK_EDUPEND, /* duplicate END */
|
|
QSE_AWK_EFNCRED, /* intrinsic function redefined */
|
|
QSE_AWK_EFUNRED, /* function redefined */
|
|
QSE_AWK_EGBLRED, /* global variable redefined */
|
|
QSE_AWK_EPARRED, /* parameter redefined */
|
|
QSE_AWK_EVARRED, /* named variable redefined */
|
|
QSE_AWK_EDUPPAR, /* duplicate parameter name */
|
|
QSE_AWK_EDUPGBL, /* duplicate global variable name */
|
|
QSE_AWK_EDUPLCL, /* duplicate local variable name */
|
|
QSE_AWK_EBADPAR, /* not a valid parameter name */
|
|
QSE_AWK_EBADVAR, /* not a valid variable name */
|
|
QSE_AWK_EUNDEF, /* undefined identifier */
|
|
QSE_AWK_ELVALUE, /* l-value required */
|
|
QSE_AWK_EGBLTM, /* too many global variables */
|
|
QSE_AWK_ELCLTM, /* too many local variables */
|
|
QSE_AWK_EPARTM, /* too many parameters */
|
|
QSE_AWK_EDELETE, /* delete not followed by a variable */
|
|
QSE_AWK_ERESET, /* reset not followed by a variable */
|
|
QSE_AWK_EBREAK, /* break outside a loop */
|
|
QSE_AWK_ECONTINUE, /* continue outside a loop */
|
|
QSE_AWK_ENEXTBEG, /* next illegal in BEGIN block */
|
|
QSE_AWK_ENEXTEND, /* next illegal in END block */
|
|
QSE_AWK_ENEXTFBEG, /* nextfile illegal in BEGIN block */
|
|
QSE_AWK_ENEXTFEND, /* nextfile illegal in END block */
|
|
QSE_AWK_EPRINTFARG, /* printf not followed by any arguments */
|
|
QSE_AWK_EPREPST, /* both prefix and postfix increment/decrement
|
|
operator present */
|
|
|
|
/* run time error */
|
|
QSE_AWK_EDIVBY0, /* divide by zero */
|
|
QSE_AWK_EOPERAND, /* invalid operand */
|
|
QSE_AWK_EPOSIDX, /* wrong position index */
|
|
QSE_AWK_EARGTF, /* too few arguments */
|
|
QSE_AWK_EARGTM, /* too many arguments */
|
|
QSE_AWK_EFUNNONE, /* "function '%.*s' not found" */
|
|
QSE_AWK_ENOTIDX, /* variable not indexable */
|
|
QSE_AWK_ENOTDEL, /* variable not deletable */
|
|
QSE_AWK_ENOTMAP, /* value not a map */
|
|
QSE_AWK_ENOTMAPIN, /* right-hand side of 'in' not a map */
|
|
QSE_AWK_ENOTMAPNILIN, /* right-hand side of 'in' not a map nor nil */
|
|
QSE_AWK_ENOTREF, /* value not referenceable */
|
|
QSE_AWK_ENOTASS, /* value not assignable */
|
|
QSE_AWK_EIDXVALASSMAP, /* indexed value cannot be assigned a map */
|
|
QSE_AWK_EPOSVALASSMAP, /* a positional cannot be assigned a map */
|
|
QSE_AWK_EMAPTOSCALAR, /* cannot change a map to a scalar value */
|
|
QSE_AWK_ESCALARTOMAP, /* cannot change a scalar value to a map */
|
|
QSE_AWK_EMAPNOTALLOWED, /* a map is not allowed */
|
|
QSE_AWK_EVALTYPE, /* wrong value type */
|
|
QSE_AWK_ERDELETE, /* delete called with a wrong target */
|
|
QSE_AWK_ERRESET, /* reset called with a wrong target */
|
|
QSE_AWK_ERNEXTBEG, /* next called from BEGIN */
|
|
QSE_AWK_ERNEXTEND, /* next called from END */
|
|
QSE_AWK_ERNEXTFBEG, /* nextfile called from BEGIN */
|
|
QSE_AWK_ERNEXTFEND, /* nextfile called from END */
|
|
QSE_AWK_EFNCUSER, /* wrong intrinsic function implementation */
|
|
QSE_AWK_EFNCIMPL, /* intrinsic function handler failed */
|
|
QSE_AWK_EIOUSER, /* wrong user io handler implementation */
|
|
QSE_AWK_EIONONE, /* no such io name found */
|
|
QSE_AWK_EIOIMPL, /* i/o callback returned an error */
|
|
QSE_AWK_EIONMEM, /* i/o name empty */
|
|
QSE_AWK_EIONMNL, /* i/o name contains '\0' */
|
|
QSE_AWK_EFMTARG, /* arguments to format string not sufficient */
|
|
QSE_AWK_EFMTCNV, /* recursion detected in format conversion */
|
|
QSE_AWK_ECONVFMTCHR, /* an invalid character found in CONVFMT */
|
|
QSE_AWK_EOFMTCHR, /* an invalid character found in OFMT */
|
|
|
|
/* regular expression error */
|
|
QSE_AWK_EREXRECUR, /* recursion too deep */
|
|
QSE_AWK_EREXRPAREN, /* a right parenthesis is expected */
|
|
QSE_AWK_EREXRBRACKET, /* a right bracket is expected */
|
|
QSE_AWK_EREXRBRACE, /* a right brace is expected */
|
|
QSE_AWK_EREXUNBALPAR, /* unbalanced parenthesis */
|
|
QSE_AWK_EREXCOLON, /* a colon is expected */
|
|
QSE_AWK_EREXCRANGE, /* invalid character range */
|
|
QSE_AWK_EREXCCLASS, /* invalid character class */
|
|
QSE_AWK_EREXBRANGE, /* invalid boundary range */
|
|
QSE_AWK_EREXEND, /* unexpected end of the pattern */
|
|
QSE_AWK_EREXGARBAGE, /* garbage after the pattern */
|
|
|
|
/* the number of error numbers, internal use only */
|
|
QSE_AWK_NUMERRNUM
|
|
};
|
|
|
|
/* depth types */
|
|
enum qse_awk_depth_t
|
|
{
|
|
QSE_AWK_DEPTH_BLOCK_PARSE = (1 << 0),
|
|
QSE_AWK_DEPTH_BLOCK_RUN = (1 << 1),
|
|
QSE_AWK_DEPTH_EXPR_PARSE = (1 << 2),
|
|
QSE_AWK_DEPTH_EXPR_RUN = (1 << 3),
|
|
QSE_AWK_DEPTH_REX_BUILD = (1 << 4),
|
|
QSE_AWK_DEPTH_REX_MATCH = (1 << 5)
|
|
};
|
|
|
|
/* eio types */
|
|
enum qse_awk_eio_type_t
|
|
{
|
|
/* eio types available */
|
|
QSE_AWK_EIO_PIPE,
|
|
QSE_AWK_EIO_FILE,
|
|
QSE_AWK_EIO_CONSOLE,
|
|
|
|
/* reserved for internal use only */
|
|
QSE_AWK_EIO_NUM
|
|
};
|
|
|
|
enum qse_awk_eio_mode_t
|
|
{
|
|
QSE_AWK_EIO_PIPE_READ = 0,
|
|
QSE_AWK_EIO_PIPE_WRITE = 1,
|
|
QSE_AWK_EIO_PIPE_RW = 2,
|
|
|
|
QSE_AWK_EIO_FILE_READ = 0,
|
|
QSE_AWK_EIO_FILE_WRITE = 1,
|
|
QSE_AWK_EIO_FILE_APPEND = 2,
|
|
|
|
QSE_AWK_EIO_CONSOLE_READ = 0,
|
|
QSE_AWK_EIO_CONSOLE_WRITE = 1
|
|
};
|
|
|
|
enum qse_awk_gbl_id_t
|
|
{
|
|
/* this table should match gtab in parse.c.
|
|
* in addition, qse_awk_rtx_setgbl also counts
|
|
* on the order of these values */
|
|
|
|
QSE_AWK_GBL_ARGC,
|
|
QSE_AWK_GBL_ARGV,
|
|
QSE_AWK_GBL_CONVFMT,
|
|
QSE_AWK_GBL_FILENAME,
|
|
QSE_AWK_GBL_FNR,
|
|
QSE_AWK_GBL_FS,
|
|
QSE_AWK_GBL_IGNORECASE,
|
|
QSE_AWK_GBL_NF,
|
|
QSE_AWK_GBL_NR,
|
|
QSE_AWK_GBL_OFILENAME,
|
|
QSE_AWK_GBL_OFMT,
|
|
QSE_AWK_GBL_OFS,
|
|
QSE_AWK_GBL_ORS,
|
|
QSE_AWK_GBL_RLENGTH,
|
|
QSE_AWK_GBL_RS,
|
|
QSE_AWK_GBL_RSTART,
|
|
QSE_AWK_GBL_SUBSEP,
|
|
|
|
/* these are not not the actual IDs and are used internally only
|
|
* Make sure you update these values properly if you add more
|
|
* ID definitions, however */
|
|
QSE_AWK_MIN_GBL_ID = QSE_AWK_GBL_ARGC,
|
|
QSE_AWK_MAX_GBL_ID = QSE_AWK_GBL_SUBSEP
|
|
};
|
|
|
|
enum qse_awk_val_type_t
|
|
{
|
|
/* the values between QSE_AWK_VAL_NIL and QSE_AWK_VAL_STR inclusive
|
|
* must be synchronized with an internal table of the __cmp_val
|
|
* function in run.c */
|
|
QSE_AWK_VAL_NIL = 0,
|
|
QSE_AWK_VAL_INT = 1,
|
|
QSE_AWK_VAL_REAL = 2,
|
|
QSE_AWK_VAL_STR = 3,
|
|
|
|
QSE_AWK_VAL_REX = 4,
|
|
QSE_AWK_VAL_MAP = 5,
|
|
QSE_AWK_VAL_REF = 6
|
|
};
|
|
|
|
enum qse_awk_val_ref_id_t
|
|
{
|
|
/* keep these items in the same order as corresponding items
|
|
* in tree.h */
|
|
QSE_AWK_VAL_REF_NAMED,
|
|
QSE_AWK_VAL_REF_GBL,
|
|
QSE_AWK_VAL_REF_LCL,
|
|
QSE_AWK_VAL_REF_ARG,
|
|
QSE_AWK_VAL_REF_NAMEDIDX,
|
|
QSE_AWK_VAL_REF_GBLIDX,
|
|
QSE_AWK_VAL_REF_LCLIDX,
|
|
QSE_AWK_VAL_REF_ARGIDX,
|
|
QSE_AWK_VAL_REF_POS
|
|
};
|
|
|
|
enum qse_awk_rtx_valtostr_opt_t
|
|
{
|
|
QSE_AWK_VALTOSTR_CLEAR = (1 << 0),
|
|
QSE_AWK_VALTOSTR_FIXED = (1 << 1), /* this overrides CLEAR */
|
|
QSE_AWK_VALTOSTR_PRINT = (1 << 2)
|
|
};
|
|
|
|
enum qse_awk_parse_ist_t
|
|
{
|
|
QSE_AWK_PARSE_FILES = 0,
|
|
QSE_AWK_PARSE_STRING = 1
|
|
};
|
|
|
|
typedef struct qse_awk_val_nil_t qse_awk_val_nil_t;
|
|
typedef struct qse_awk_val_int_t qse_awk_val_int_t;
|
|
typedef struct qse_awk_val_real_t qse_awk_val_real_t;
|
|
typedef struct qse_awk_val_str_t qse_awk_val_str_t;
|
|
typedef struct qse_awk_val_rex_t qse_awk_val_rex_t;
|
|
typedef struct qse_awk_val_map_t qse_awk_val_map_t;
|
|
typedef struct qse_awk_val_ref_t qse_awk_val_ref_t;
|
|
|
|
/* this is not a value. it is just a value holder */
|
|
typedef struct qse_awk_val_chunk_t qse_awk_val_chunk_t;
|
|
|
|
#if QSE_SIZEOF_INT == 2
|
|
# define QSE_AWK_VAL_HDR \
|
|
unsigned int type: 3; \
|
|
unsigned int ref: 13
|
|
#else
|
|
# define QSE_AWK_VAL_HDR \
|
|
unsigned int type: 3; \
|
|
unsigned int ref: 29
|
|
#endif
|
|
|
|
#define QSE_AWK_VAL_TYPE(x) ((x)->type)
|
|
|
|
struct qse_awk_val_t
|
|
{
|
|
QSE_AWK_VAL_HDR;
|
|
};
|
|
|
|
/* QSE_AWK_VAL_NIL */
|
|
struct qse_awk_val_nil_t
|
|
{
|
|
QSE_AWK_VAL_HDR;
|
|
};
|
|
|
|
/* QSE_AWK_VAL_INT */
|
|
struct qse_awk_val_int_t
|
|
{
|
|
QSE_AWK_VAL_HDR;
|
|
qse_long_t val;
|
|
void* nde;
|
|
};
|
|
|
|
/* QSE_AWK_VAL_REAL */
|
|
struct qse_awk_val_real_t
|
|
{
|
|
QSE_AWK_VAL_HDR;
|
|
qse_real_t val;
|
|
void* nde;
|
|
};
|
|
|
|
/* QSE_AWK_VAL_STR */
|
|
struct qse_awk_val_str_t
|
|
{
|
|
QSE_AWK_VAL_HDR;
|
|
qse_char_t* ptr;
|
|
qse_size_t len;
|
|
};
|
|
|
|
/* QSE_AWK_VAL_REX */
|
|
struct qse_awk_val_rex_t
|
|
{
|
|
QSE_AWK_VAL_HDR;
|
|
qse_char_t* ptr;
|
|
qse_size_t len;
|
|
void* code;
|
|
};
|
|
|
|
/* QSE_AWK_VAL_MAP */
|
|
struct qse_awk_val_map_t
|
|
{
|
|
QSE_AWK_VAL_HDR;
|
|
|
|
/* TODO: make val_map to array if the indices used are all
|
|
* integers switch to map dynamically once the
|
|
* non-integral index is seen.
|
|
*/
|
|
qse_map_t* map;
|
|
};
|
|
|
|
/* QSE_AWK_VAL_REF */
|
|
struct qse_awk_val_ref_t
|
|
{
|
|
QSE_AWK_VAL_HDR;
|
|
|
|
int id;
|
|
/* if id is QSE_AWK_VAL_REF_POS, adr holds an index of the
|
|
* positional variable. Otherwise, adr points to the value
|
|
* directly. */
|
|
qse_awk_val_t** adr;
|
|
};
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** represents the nil value */
|
|
extern qse_awk_val_t* qse_awk_val_nil;
|
|
|
|
/** represents an empty string */
|
|
extern qse_awk_val_t* qse_awk_val_zls;
|
|
|
|
/** represents a numeric value -1 */
|
|
extern qse_awk_val_t* qse_awk_val_negone;
|
|
|
|
/** represents a numeric value 0 */
|
|
extern qse_awk_val_t* qse_awk_val_zero;
|
|
|
|
/** represents a numeric value 1 */
|
|
extern qse_awk_val_t* qse_awk_val_one;
|
|
|
|
/****f* AWK/qse_awk_open
|
|
* NAME
|
|
* qse_awk_open - create an awk object
|
|
* DESCRIPTION
|
|
* The qse_awk_open() function creates a new qse_awk_t instance.
|
|
* The instance created can be passed to other qse_awk_xxx() functions and
|
|
* is valid until it is successfully destroyed using the qse_qse_close()
|
|
* function.
|
|
* RETURN
|
|
* The qse_awk_open() function returns the pointer to a qse_awk_t instance
|
|
* on success and QSE_NULL on failure.
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_t* qse_awk_open (
|
|
qse_mmgr_t* mmgr /* a memory manager */,
|
|
qse_size_t xtn /* the size of extension in bytes */
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_close
|
|
* NAME
|
|
* qse_awk_close - destroy an awk object
|
|
* DESCRIPTION
|
|
* A qse_awk_t instance must be destroyed using the qse_awk_close() function
|
|
* when finished being used. The instance passed is not valid any more once
|
|
* the function returns success.
|
|
* RETURN
|
|
* 0 on success, -1 on failure
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_close (
|
|
qse_awk_t* awk
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_getmmgr
|
|
* NAME
|
|
* qse_awk_getmmgr - get the memory manager
|
|
* DESCRIPTION
|
|
* The qse_awk_getmmgr() function returns the pointer to the memory manager.
|
|
* SYNOPSIS
|
|
*/
|
|
qse_mmgr_t* qse_awk_getmmgr (
|
|
qse_awk_t* awk
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_setmmgr
|
|
* NAME
|
|
* qse_awk_setmmgr - set the extension
|
|
* DESCRIPTION
|
|
* The qse_awk_setmmgr() specify the memory manager to use. As the memory
|
|
* manager is specified into qse_awk_open(), you are not encouraged to change
|
|
* it by calling this function. Doing so may cause a lot of problems.
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_setmmgr (
|
|
qse_awk_t* awk,
|
|
qse_mmgr_t* mmgr
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_getxtn
|
|
* NAME
|
|
* qse_awk_getxtn - get the extension
|
|
* DESCRIPTION
|
|
* The extension area is allocated in the qse_awk_open() function when it is
|
|
* given a positive extension size. The pointer to the beginning of the area
|
|
* can be acquired using the qse_awk_getxtn() function and be utilized
|
|
* for various purposes.
|
|
* SYNOPSIS
|
|
*/
|
|
void* qse_awk_getxtn (
|
|
qse_awk_t* awk /* an awk object */
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_getccls
|
|
* NAME
|
|
* qse_awk_getccls - get a character classifier
|
|
* SYNOPSIS
|
|
*/
|
|
qse_ccls_t* qse_awk_getccls (
|
|
qse_awk_t* awk
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_setccls
|
|
* NAME
|
|
* qse_awk_setccls - set the character classfier
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_setccls (
|
|
qse_awk_t* awk,
|
|
qse_ccls_t* ccls
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_getprm
|
|
* NAME
|
|
* qse_awk_getprm - get primitive functions
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_prm_t* qse_awk_getprm (
|
|
qse_awk_t* awk
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_setprm
|
|
* NAME
|
|
* qse_awk_setprm - set primitive functions
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_setprm (
|
|
qse_awk_t* awk,
|
|
qse_awk_prm_t* prm
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_clear
|
|
* NAME
|
|
* qse_awk_clear - clear a qse_awk_t object
|
|
* DESCRIPTION
|
|
* If you want to reuse a qse_awk_t instance that finished being used,
|
|
* you may call qse_awk_close instead of destroying and creating a new
|
|
* qse_awk_t instance using qse_awk_close() and qse_awk_open().
|
|
* RETURN
|
|
* 0 on success, -1 on failure
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_clear (
|
|
qse_awk_t* awk
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_geterrstr
|
|
* NAME
|
|
* qse_awk_geterrstr - get a format string for an error
|
|
* DESCRIPTION
|
|
* The qse_awk_geterrstr() function returns a pointer to a format string for
|
|
* the error number num.
|
|
* SYNOPSIS
|
|
*/
|
|
const qse_char_t* qse_awk_geterrstr (
|
|
qse_awk_t* awk,
|
|
int num
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_seterrstr
|
|
* NAME
|
|
* qse_awk_geterrstr - set a format string for an error
|
|
* DESCRIPTION
|
|
* The qse_awk_seterrstr() function sets a format string for an error. The
|
|
* format string is used to compose an actual error message to be returned
|
|
* by qse_awk_geterrmsg() and qse_awk_geterror().
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_seterrstr (
|
|
qse_awk_t* awk,
|
|
int num,
|
|
const qse_char_t* str
|
|
);
|
|
/******/
|
|
|
|
int qse_awk_geterrnum (
|
|
qse_awk_t* awk
|
|
);
|
|
|
|
qse_size_t qse_awk_geterrlin (
|
|
qse_awk_t* awk
|
|
);
|
|
|
|
const qse_char_t* qse_awk_geterrmsg (
|
|
qse_awk_t* awk
|
|
);
|
|
|
|
void qse_awk_seterrnum (
|
|
qse_awk_t* awk,
|
|
int errnum
|
|
);
|
|
|
|
void qse_awk_seterrmsg (
|
|
qse_awk_t* awk,
|
|
int errnum,
|
|
qse_size_t errlin,
|
|
const qse_char_t* errmsg
|
|
);
|
|
|
|
void qse_awk_geterror (
|
|
qse_awk_t* awk,
|
|
int* errnum,
|
|
qse_size_t* errlin,
|
|
const qse_char_t** errmsg
|
|
);
|
|
|
|
void qse_awk_seterror (
|
|
qse_awk_t* awk,
|
|
int errnum,
|
|
qse_size_t errlin,
|
|
const qse_cstr_t* errarg,
|
|
qse_size_t argcnt
|
|
);
|
|
|
|
int qse_awk_getoption (
|
|
qse_awk_t* awk
|
|
);
|
|
|
|
void qse_awk_setoption (
|
|
qse_awk_t* awk,
|
|
int opt
|
|
);
|
|
|
|
qse_size_t qse_awk_getmaxdepth (
|
|
qse_awk_t* awk,
|
|
int type
|
|
);
|
|
|
|
void qse_awk_setmaxdepth (
|
|
qse_awk_t* awk,
|
|
int types,
|
|
qse_size_t depth
|
|
);
|
|
|
|
int qse_awk_getword (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* okw,
|
|
qse_size_t olen,
|
|
const qse_char_t** nkw,
|
|
qse_size_t* nlen
|
|
);
|
|
|
|
int qse_awk_unsetword (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* kw,
|
|
qse_size_t len
|
|
);
|
|
|
|
void qse_awk_unsetallwords (
|
|
qse_awk_t* awk
|
|
);
|
|
|
|
/*
|
|
* NAME:
|
|
* enable replacement of a name of a keyword, intrinsic global variables,
|
|
* and intrinsic functions.
|
|
*
|
|
* DESCRIPTION:
|
|
* If nkw is QSE_NULL or nlen is zero and okw is QSE_NULL or olen is zero,
|
|
* it unsets all word replacements. If nkw is QSE_NULL or nlen is zero,
|
|
* it unsets the replacement for okw and olen. If all of them are valid,
|
|
* it sets the word replace for okw and olen to nkw and nlen.
|
|
*
|
|
* RETURN: 0 on success, -1 on failure
|
|
*/
|
|
int qse_awk_setword (
|
|
/* the pointer to a qse_awk_t instance */
|
|
qse_awk_t* awk,
|
|
/* the pointer to an old keyword */
|
|
const qse_char_t* okw,
|
|
/* the length of the old keyword */
|
|
qse_size_t olen,
|
|
/* the pointer to an new keyword */
|
|
const qse_char_t* nkw,
|
|
/* the length of the new keyword */
|
|
qse_size_t nlen
|
|
);
|
|
|
|
/****f* AWK/qse_awk_addgbl
|
|
* NAME
|
|
* qse_awk_addgbl - add an intrinsic global variable.
|
|
* RETURN
|
|
* The qse_awk_addgbl() function returns the ID of the global variable
|
|
* added on success and -1 on failure.
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_addgbl (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* name,
|
|
qse_size_t len
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_delgbl
|
|
* NAME
|
|
* qse_awk_delgbl - delete an instrinsic global variable.
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_delgbl (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* name,
|
|
qse_size_t len
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_addfnc
|
|
* NAME
|
|
* qse_awk_addfnc - add an intrinsic function
|
|
* SYNOPSIS
|
|
*/
|
|
void* qse_awk_addfnc (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* name,
|
|
qse_size_t name_len,
|
|
int when_valid,
|
|
qse_size_t min_args,
|
|
qse_size_t max_args,
|
|
const qse_char_t* arg_spec,
|
|
int (*handler)(qse_awk_rtx_t*,const qse_char_t*,qse_size_t)
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_delfnc
|
|
* NAME
|
|
* qse_awk_delfnc - delete an intrinsic function
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_delfnc (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* name,
|
|
qse_size_t len
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_clrfnc
|
|
* NAME
|
|
* qse_awk_clrfnc - delete all intrinsic functions
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_clrfnc (
|
|
qse_awk_t* awk
|
|
);
|
|
/*****/
|
|
|
|
|
|
/****f* AWK/qse_awk_parse
|
|
* NAME
|
|
* qse_awk_parse - parse source code
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_parse (
|
|
qse_awk_t* awk,
|
|
qse_awk_sio_t* sio
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_alloc
|
|
* NAME
|
|
* qse_awk_alloc - allocate dynamic memory
|
|
* RETURN
|
|
* the pointer to the memory space allocated on success, QSE_NULL on failure
|
|
* SYNOPSIS
|
|
*/
|
|
void* qse_awk_alloc (
|
|
qse_awk_t* awk /* the pointer to a qse_awk_t instance */,
|
|
qse_size_t size /* the size of memory to allocate in bytes */
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_free
|
|
* NAME
|
|
* qse_awk_free - free dynamic memory
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_free (
|
|
qse_awk_t* awk /* the pointer to a qse_awk_t instance */,
|
|
void* ptr /* the pointer to the memory space to free */
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_strdup
|
|
* NAME
|
|
* qse_awk_strdup - duplicate a null-terminated string
|
|
* DESCRIPTION
|
|
* The qse_awk_strdup() function is used to duplicate a string using
|
|
* the memory manager used by the associated qse_awk_t instance.
|
|
* The new string should be freed using the qse_awk_free() function.
|
|
* RETURN
|
|
* The qse_awk_strdup() function returns the pointer to a new string which
|
|
* is a duplicate of the string s. It returns QSE_NULL on failure.
|
|
* SYNOPSIS
|
|
*/
|
|
qse_char_t* qse_awk_strdup (
|
|
qse_awk_t* awk /* the pointer to a qse_awk_t instance */,
|
|
const qse_char_t* str /* the pointer to a string */
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_strxdup
|
|
* NAME
|
|
* qse_awk_strxdup - duplicate a length-delimited string
|
|
* DESCRIPTION
|
|
* The qse_awk_strxdup() function is used to duplicate a string whose length
|
|
* is as long as len characters using the memory manager used by the
|
|
* qse_awk_t instance. The new string should be freed using the qse_awk_free()
|
|
* function.
|
|
* RETURN
|
|
* The qse_awk_strxdup() function returns the pointer to a new string which
|
|
* is a duplicate of the string s on success. It returns QSE_NULL on failure.
|
|
* SYNOPSIS
|
|
*/
|
|
qse_char_t* qse_awk_strxdup (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* str,
|
|
qse_size_t len
|
|
);
|
|
/******/
|
|
|
|
qse_long_t qse_awk_strxtolong (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* str,
|
|
qse_size_t len,
|
|
int base,
|
|
const qse_char_t** endptr
|
|
);
|
|
|
|
qse_real_t qse_awk_strxtoreal (
|
|
qse_awk_t* awk,
|
|
const qse_char_t* str,
|
|
qse_size_t len,
|
|
const qse_char_t** endptr
|
|
);
|
|
|
|
qse_size_t qse_awk_longtostr (
|
|
qse_long_t value,
|
|
int radix,
|
|
const qse_char_t* prefix,
|
|
qse_char_t* buf,
|
|
qse_size_t size
|
|
);
|
|
|
|
/****f* AWK/qse_awk_rtx_open
|
|
* NAME
|
|
* qse_awk_rtx_open - create a runtime context
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_rtx_t* qse_awk_rtx_open (
|
|
qse_awk_t* awk,
|
|
qse_size_t xtn,
|
|
qse_awk_rio_t* rio,
|
|
const qse_cstr_t* arg
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_close
|
|
* NAME
|
|
* qse_awk_rtx_close - destroy a runtime context
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_rtx_close (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_loop
|
|
* NAME
|
|
* qse_awk_rtx_loop - run BEGIN/pattern-action/END blocks
|
|
* DESCRIPTION
|
|
* The qse_awk_rtx_loop() function executes the BEGIN block, pattern-action
|
|
* blocks and the END blocks in an AWk program. Multiple invocations of the
|
|
* function for the lifetime of a runtime context is not desirable.
|
|
* RETURN
|
|
* The qse_awk_rtx_loop() function returns 0 on success and -1 on failure.
|
|
* EXAMPLE
|
|
* rtx = qse_awk_rtx_open (awk, rio, rcb, QSE_NULL, QSE_NULL);
|
|
* if (rtx != QSE_NULL)
|
|
* {
|
|
* qse_awk_rtx_loop (rtx);
|
|
* qse_awk_rtx_close (rtx);
|
|
* }
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_rtx_loop (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_call
|
|
* NAME
|
|
* qse_awk_rtx_call - call a function
|
|
* DESCRIPTION
|
|
* The qse_awk_rtx_call() function invokes an AWK function. However, it is
|
|
* not able to invoke an intrinsic function such as split().
|
|
* The QSE_AWK_PABLOCK option can be turned off to make illegal the BEGIN
|
|
* block, pattern-action blocks, and the END block.
|
|
* RETURN
|
|
* The qse_awk_rtx_call() function returns 0 on success and -1 on failure.
|
|
* EXAMPLE
|
|
* rtx = qse_awk_rtx_open (awk, rio, rcb, QSE_NULL, QSE_NULL);
|
|
* if (rtx != QSE_NULL)
|
|
* {
|
|
* qse_awk_rtx_call (rtx, QSE_T("init"), QSE_NULL, 0);
|
|
* qse_awk_rtx_call (rtx, QSE_T("fini"), QSE_NULL, 0);
|
|
* qse_awk_rtx_close (rtx);
|
|
* }
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_rtx_call (
|
|
qse_awk_rtx_t* rtx,
|
|
const qse_char_t* name,
|
|
qse_awk_val_t** args,
|
|
qse_size_t nargs
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_stopall
|
|
* NAME
|
|
* qse_awk_stopall - stop all runtime contexts
|
|
* DESCRIPTION
|
|
* The qse_awk_stopall() function aborts all active qse_awk_run() functions
|
|
* invoked with the awk parameter.
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_stopall (
|
|
qse_awk_t* awk
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_shouldstop
|
|
* NAME
|
|
* qse_awk_shouldstop - test if qse_awk_rtx_stop() is called
|
|
* SYNOPSIS
|
|
*/
|
|
qse_bool_t qse_awk_rtx_shouldstop (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_stop
|
|
* NAME
|
|
* qse_awk_rtx_stop - stop a runtime context
|
|
* DESCRIPTION
|
|
* The qse_awk_rtx_stop() function causes the active qse_awk_run() function to
|
|
* be aborted.
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_rtx_stop (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_getrcb
|
|
* NAME
|
|
* qse_awk_rtx_getrcb - get callback
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_rcb_t* qse_awk_rtx_getrcb (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_setrcb
|
|
* NAME
|
|
* qse_awk_rtx_setrcb - set callback
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_rtx_setrcb (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_rcb_t* rcb
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_getnargs
|
|
* NAME
|
|
* qse_awk_rtx_getnargs - get the number of arguments passed to qse_awk_run()
|
|
* SYNOPSIS
|
|
*/
|
|
qse_size_t qse_awk_rtx_getnargs (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_getarg
|
|
* NAME
|
|
* qse_awk_rtx_getarg - get an argument passed to qse_awk_run
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_val_t* qse_awk_rtx_getarg (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_size_t idx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_getgbl
|
|
* NAME
|
|
* qse_awk_rtx_getgbl - gets the value of a global variable
|
|
* INPUTS
|
|
* * rtx - a runtime context
|
|
* * id - a global variable ID. It is one of the predefined global
|
|
* variable IDs or a value returned by qse_awk_addgbl().
|
|
* RETURN
|
|
* The pointer to a value is returned. This function never fails
|
|
* so long as the ID is valid. Otherwise, you may fall into trouble.
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_val_t* qse_awk_rtx_getgbl (
|
|
qse_awk_rtx_t* rtx,
|
|
int id
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_setgbl
|
|
* NAME
|
|
* qse_awk_rtx_setgbl - set the value of a global variable
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_rtx_setgbl (
|
|
qse_awk_rtx_t* rtx,
|
|
int id,
|
|
qse_awk_val_t* val
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_setretval
|
|
* NAME
|
|
* qse_awk_rtx_setretval - set the return value
|
|
* DESCRIPTION
|
|
* The qse_awk_rtx_setretval() sets the return value of a function
|
|
* when called from within a function handlers. The caller doesn't
|
|
* have to invoke qse_awk_rtx_refupval() and qse_awk_rtx_refdownval()
|
|
* with the value to be passed to qse_awk_rtx_setretval().
|
|
* The qse_awk_rtx_setretval() will update its reference count properly
|
|
* once the return value is set.
|
|
* SYNOPSIS
|
|
*/
|
|
void qse_awk_rtx_setretval (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* val
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_setfilename
|
|
* NAME
|
|
* qse_awk_rtx_setfilename - set FILENAME
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_rtx_setfilename (
|
|
qse_awk_rtx_t* rtx,
|
|
const qse_char_t* name,
|
|
qse_size_t len
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_setofilename
|
|
* NAME
|
|
* qse_awk_rtx_setofilename - set OFILENAME
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_rtx_setofilename (
|
|
qse_awk_rtx_t* rtx,
|
|
const qse_char_t* name,
|
|
qse_size_t len
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_getawk
|
|
* NAME
|
|
* qse_awk_rtx_getawk - get the owning awk object
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_t* qse_awk_rtx_getawk (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_getmmgr
|
|
* NAME
|
|
* qse_awk_rtx_getmmgr - get the memory manager of a runtime context
|
|
* SYNOPSIS
|
|
*/
|
|
qse_mmgr_t* qse_awk_rtx_getmmgr (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_getxtn
|
|
* NAME
|
|
* qse_awk_rtx_getxtn - get the pointer to extension space
|
|
* SYNOPSIS
|
|
*/
|
|
void* qse_awk_rtx_getxtn (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_getnvmap
|
|
* NAME
|
|
* qse_awk_rtx_getnvmap - get the map of named variables
|
|
* SYNOPSIS
|
|
*/
|
|
qse_map_t* qse_awk_rtx_getnvmap (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_geterrnum
|
|
* NAME
|
|
* qse_awk_rtx_geterrnum - get an error code of a runtime context
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_rtx_geterrnum (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
/******/
|
|
|
|
qse_size_t qse_awk_rtx_geterrlin (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
|
|
const qse_char_t* qse_awk_rtx_geterrmsg (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
|
|
void qse_awk_rtx_seterrnum (
|
|
qse_awk_rtx_t* rtx,
|
|
int errnum
|
|
);
|
|
|
|
void qse_awk_rtx_seterrmsg (
|
|
qse_awk_rtx_t* rtx,
|
|
int errnum,
|
|
qse_size_t errlin,
|
|
const qse_char_t* errmsg
|
|
);
|
|
|
|
void qse_awk_rtx_geterror (
|
|
qse_awk_rtx_t* rtx,
|
|
int* errnum,
|
|
qse_size_t* errlin,
|
|
const qse_char_t** errmsg
|
|
);
|
|
|
|
void qse_awk_rtx_seterror (
|
|
qse_awk_rtx_t* rtx,
|
|
int errnum,
|
|
qse_size_t errlin,
|
|
const qse_cstr_t* errarg,
|
|
qse_size_t argcnt
|
|
);
|
|
|
|
|
|
/* record and field functions */
|
|
int qse_awk_rtx_clrrec (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_bool_t skip_inrec_line
|
|
);
|
|
|
|
int qse_awk_rtx_setrec (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_size_t idx,
|
|
const qse_char_t* str,
|
|
qse_size_t len
|
|
);
|
|
|
|
/* value manipulation functions */
|
|
qse_awk_val_t* qse_awk_rtx_makeintval (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_long_t v
|
|
);
|
|
qse_awk_val_t* qse_awk_rtx_makerealval (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_real_t v
|
|
);
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrval0 (
|
|
qse_awk_rtx_t* rtx,
|
|
const qse_char_t* str
|
|
);
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrval (
|
|
qse_awk_rtx_t* rtx,
|
|
const qse_char_t* str,
|
|
qse_size_t len
|
|
);
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrval_nodup (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_char_t* str,
|
|
qse_size_t len
|
|
);
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrval2 (
|
|
qse_awk_rtx_t* rtx,
|
|
const qse_char_t* str1,
|
|
qse_size_t len1,
|
|
const qse_char_t* str2,
|
|
qse_size_t len2
|
|
);
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makerexval (
|
|
qse_awk_rtx_t* rtx,
|
|
const qse_char_t* buf,
|
|
qse_size_t len,
|
|
void* code
|
|
);
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makemapval (
|
|
qse_awk_rtx_t* rtx
|
|
);
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makerefval (
|
|
qse_awk_rtx_t* rtx,
|
|
int id,
|
|
qse_awk_val_t** adr
|
|
);
|
|
|
|
qse_bool_t qse_awk_isstaticval (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* val
|
|
);
|
|
|
|
void qse_awk_rtx_freeval (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* val,
|
|
qse_bool_t cache
|
|
);
|
|
|
|
void qse_awk_rtx_refupval (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* val
|
|
);
|
|
|
|
void qse_awk_rtx_refdownval (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* val
|
|
);
|
|
|
|
void qse_awk_rtx_refdownval_nofree (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* val
|
|
);
|
|
|
|
qse_bool_t qse_awk_rtx_valtobool (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* val
|
|
);
|
|
|
|
qse_char_t* qse_awk_rtx_valtostr (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* val,
|
|
int opt,
|
|
qse_str_t* buf,
|
|
qse_size_t* len
|
|
);
|
|
|
|
/****f* AWK/qse_awk_rtx_valtonum
|
|
* NAME
|
|
* qse_awk_rtx_valtonum - convert a value to a number
|
|
* DESCRIPTION
|
|
* The qse_awk_rtx_valtonum() function converts a value to a number.
|
|
* If the value is converted to a long number, it is stored in the memory
|
|
* pointed to by l and 0 is returned. If the value is converted to a real
|
|
* number, it is stored in the memory pointed to by r and 1 is returned.
|
|
* RETURN
|
|
* The qse_awk_rtx_valtonum() function returns -1 on error, 0 if the converted
|
|
* number is a long number and 1 if it is a real number.
|
|
* EXAMPLES
|
|
* qse_long_t l;
|
|
* qse_real_t r;
|
|
* int n;
|
|
*
|
|
* n = qse_awk_rtx_valtonum (v, &l, &r);
|
|
* if (n == -1) error ();
|
|
* else if (n == 0) do_long (l);
|
|
* else if (n == 1) do_real (r);
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_rtx_valtonum (
|
|
qse_awk_rtx_t* rtx,
|
|
qse_awk_val_t* v /* the value to convert to a number */,
|
|
qse_long_t* l /* a pointer to a long number */,
|
|
qse_real_t* r /* a pointer to a qse_real_t */
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_strtonum
|
|
* NAME
|
|
* qse_awk_rtx_strtonum - convert a string to a number
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_rtx_strtonum (
|
|
qse_awk_rtx_t* run,
|
|
const qse_char_t* ptr,
|
|
qse_size_t len,
|
|
qse_long_t* l,
|
|
qse_real_t* r
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_opensimple
|
|
* NAME
|
|
* qse_awk_opensimple - create an awk object
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_t* qse_awk_opensimple (
|
|
void
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_parsesimple
|
|
* NAME
|
|
* qse_awk_parsesimple - parse source code
|
|
* DESCRIPTION
|
|
* If 'ist' is QSE_AWK_PARSE_STRING, 'isp' should be a null-terminated string
|
|
* of the type 'const qse_char_t*'; If 'ist' is QSE_AWK_PARSE_FILES, 'isp'
|
|
* should be an array of null-terminated strings whose last element is a
|
|
* null pointer.
|
|
* SYNOPSIS
|
|
*/
|
|
int qse_awk_parsesimple (
|
|
qse_awk_t* awk,
|
|
int ist /* QSE_AWK_PARSE_FILES, QSE_AWK_PARSE_STRING */,
|
|
const void* isp /* source file names or source string */,
|
|
const qse_char_t* osf /* an output source file name */
|
|
);
|
|
/******/
|
|
|
|
/****f* AWK/qse_awk_rtx_opensimple
|
|
* NAME
|
|
* qse_awk_rtx_opensimple - create a runtime context
|
|
* SYNOPSIS
|
|
*/
|
|
qse_awk_rtx_t* qse_awk_rtx_opensimple (
|
|
qse_awk_t* awk,
|
|
qse_char_t** icf
|
|
);
|
|
/******/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|