2008-08-04 08:14:52 +00:00
|
|
|
/*
|
2011-04-18 09:28:22 +00:00
|
|
|
* $Id: std.c 436 2011-04-17 15:28:22Z hyunghwan.chung $
|
2008-12-27 04:35:14 +00:00
|
|
|
*
|
2009-09-16 04:01:02 +00:00
|
|
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
|
|
|
This file is part of QSE.
|
2008-12-27 04:35:14 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
QSE is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Lesser General Public License as
|
|
|
|
published by the Free Software Foundation, either version 3 of
|
|
|
|
the License, or (at your option) any later version.
|
2008-12-27 04:35:14 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
QSE is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Lesser General Public License for more details.
|
2008-12-27 04:35:14 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
2008-08-04 08:14:52 +00:00
|
|
|
*/
|
|
|
|
|
2008-08-21 03:17:25 +00:00
|
|
|
#include "awk.h"
|
2009-02-23 08:10:34 +00:00
|
|
|
#include <qse/awk/std.h>
|
2008-12-21 21:35:07 +00:00
|
|
|
#include <qse/cmn/sio.h>
|
2009-01-29 08:50:30 +00:00
|
|
|
#include <qse/cmn/pio.h>
|
2008-12-21 21:35:07 +00:00
|
|
|
#include <qse/cmn/str.h>
|
|
|
|
#include <qse/cmn/time.h>
|
2009-09-05 07:08:19 +00:00
|
|
|
#include <qse/cmn/misc.h>
|
2009-06-04 15:50:32 +00:00
|
|
|
#include <qse/cmn/stdio.h> /* TODO: remove dependency on qse_vsprintf */
|
2009-12-22 06:29:52 +00:00
|
|
|
#include "../cmn/mem.h"
|
2008-12-11 04:19:59 +00:00
|
|
|
|
2008-12-15 07:25:42 +00:00
|
|
|
#include <stdarg.h>
|
2008-12-17 03:42:48 +00:00
|
|
|
#include <stdlib.h>
|
2009-08-29 05:58:05 +00:00
|
|
|
#include <math.h>
|
2008-08-04 08:13:03 +00:00
|
|
|
|
2011-04-18 09:28:22 +00:00
|
|
|
#if defined(_WIN32)
|
|
|
|
# include <tchar.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef QSE_HAVE_CONFIG_H
|
|
|
|
# if defined(__OS2__) || defined(_WIN32)
|
|
|
|
# define HAVE_POW
|
|
|
|
# define HAVE_SIN
|
|
|
|
# define HAVE_COS
|
|
|
|
# define HAVE_TAN
|
|
|
|
# define HAVE_ATAN
|
|
|
|
# define HAVE_ATAN2
|
|
|
|
# define HAVE_LOG
|
|
|
|
# define HAVE_EXP
|
|
|
|
# define HAVE_SQRT
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2008-12-16 03:56:48 +00:00
|
|
|
typedef struct xtn_t
|
2009-02-14 04:57:09 +00:00
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
struct
|
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
qse_awk_parsestd_type_t type;
|
2009-02-16 08:31:34 +00:00
|
|
|
union
|
|
|
|
{
|
2009-02-22 06:28:02 +00:00
|
|
|
const qse_char_t* file;
|
2009-02-23 08:10:34 +00:00
|
|
|
const qse_char_t* cp;
|
2009-02-22 06:28:02 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
const qse_char_t* ptr;
|
|
|
|
const qse_char_t* end;
|
2009-02-23 08:10:34 +00:00
|
|
|
} cpl;
|
2009-02-18 07:55:48 +00:00
|
|
|
} u;
|
2009-08-10 21:29:59 +00:00
|
|
|
qse_cstr_t dir;
|
2009-02-22 06:28:02 +00:00
|
|
|
qse_sio_t* handle; /* the handle to an open file */
|
2009-02-16 08:31:34 +00:00
|
|
|
} in;
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
qse_awk_parsestd_type_t type;
|
2009-02-21 23:06:45 +00:00
|
|
|
union
|
|
|
|
{
|
|
|
|
const qse_char_t* file;
|
2009-02-23 08:10:34 +00:00
|
|
|
qse_char_t* cp;
|
2009-02-22 06:28:02 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
qse_xstr_t* osp;
|
|
|
|
qse_char_t* ptr;
|
|
|
|
qse_char_t* end;
|
2009-02-23 08:10:34 +00:00
|
|
|
} cpl;
|
2009-02-21 23:06:45 +00:00
|
|
|
} u;
|
2009-09-22 07:28:18 +00:00
|
|
|
qse_sio_t* handle;
|
2009-02-16 08:31:34 +00:00
|
|
|
} out;
|
|
|
|
|
|
|
|
} s;
|
|
|
|
} xtn_t;
|
|
|
|
|
2009-02-14 04:57:09 +00:00
|
|
|
|
2008-12-17 03:42:48 +00:00
|
|
|
typedef struct rxtn_t
|
|
|
|
{
|
|
|
|
unsigned int seed;
|
2009-02-16 08:31:34 +00:00
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
struct {
|
2009-02-18 07:55:48 +00:00
|
|
|
const qse_char_t*const* files;
|
2009-02-18 04:37:34 +00:00
|
|
|
qse_size_t index;
|
2009-06-25 02:29:33 +00:00
|
|
|
qse_size_t count;
|
2009-02-16 08:31:34 +00:00
|
|
|
} in;
|
2009-02-18 04:37:34 +00:00
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
2009-02-18 07:55:48 +00:00
|
|
|
const qse_char_t*const* files;
|
2009-02-18 04:37:34 +00:00
|
|
|
qse_size_t index;
|
2009-07-08 07:05:10 +00:00
|
|
|
qse_size_t count;
|
2009-02-18 04:37:34 +00:00
|
|
|
} out;
|
2009-02-16 08:31:34 +00:00
|
|
|
} c; /* console */
|
2009-02-18 04:37:34 +00:00
|
|
|
|
2008-12-17 03:42:48 +00:00
|
|
|
} rxtn_t;
|
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
static qse_real_t custom_awk_pow (qse_awk_t* awk, qse_real_t x, qse_real_t y)
|
2008-08-04 08:13:03 +00:00
|
|
|
{
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_POWL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2008-12-17 03:42:48 +00:00
|
|
|
return powl (x, y);
|
|
|
|
#elif defined(HAVE_POW)
|
2008-08-04 08:13:03 +00:00
|
|
|
return pow (x, y);
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_POWF)
|
|
|
|
return powf (x, y);
|
|
|
|
#else
|
|
|
|
#error ### no pow function available ###
|
|
|
|
#endif
|
2008-08-04 08:13:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int custom_awk_sprintf (
|
2009-02-16 08:31:34 +00:00
|
|
|
qse_awk_t* awk, qse_char_t* buf, qse_size_t size,
|
2008-12-21 21:35:07 +00:00
|
|
|
const qse_char_t* fmt, ...)
|
2008-08-04 08:13:03 +00:00
|
|
|
{
|
|
|
|
int n;
|
|
|
|
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
2008-12-21 21:35:07 +00:00
|
|
|
n = qse_vsprintf (buf, size, fmt, ap);
|
2008-08-04 08:13:03 +00:00
|
|
|
va_end (ap);
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static int add_functions (qse_awk_t* awk);
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-02-27 04:56:12 +00:00
|
|
|
qse_awk_t* qse_awk_openstd (qse_size_t xtnsize)
|
2010-07-25 06:43:26 +00:00
|
|
|
{
|
|
|
|
return qse_awk_openstdwithmmgr (QSE_MMGR_GETDFL(), xtnsize);
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
2008-08-04 08:13:03 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_t* awk;
|
2009-02-16 08:31:34 +00:00
|
|
|
qse_awk_prm_t prm;
|
|
|
|
xtn_t* xtn;
|
2008-08-04 08:13:03 +00:00
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
prm.pow = custom_awk_pow;
|
|
|
|
prm.sprintf = custom_awk_sprintf;
|
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
/* create an object */
|
2010-07-25 06:43:26 +00:00
|
|
|
awk = qse_awk_open (mmgr, QSE_SIZEOF(xtn_t) + xtnsize, &prm);
|
2009-02-16 08:31:34 +00:00
|
|
|
if (awk == QSE_NULL) return QSE_NULL;
|
2008-08-04 08:13:03 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
/* initialize extension */
|
2009-02-17 02:11:31 +00:00
|
|
|
xtn = (xtn_t*) QSE_XTN (awk);
|
2009-02-16 08:31:34 +00:00
|
|
|
QSE_MEMSET (xtn, 0, QSE_SIZEOF(xtn_t));
|
2008-12-16 03:56:48 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
/* add intrinsic functions */
|
2008-12-17 03:42:48 +00:00
|
|
|
if (add_functions (awk) == -1)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_close (awk);
|
|
|
|
return QSE_NULL;
|
2008-12-17 03:42:48 +00:00
|
|
|
}
|
|
|
|
|
2008-08-04 08:13:03 +00:00
|
|
|
return awk;
|
|
|
|
}
|
2008-10-01 05:14:20 +00:00
|
|
|
|
2009-02-27 04:56:12 +00:00
|
|
|
void* qse_awk_getxtnstd (qse_awk_t* awk)
|
|
|
|
{
|
|
|
|
return (void*)((xtn_t*)QSE_XTN(awk) + 1);
|
|
|
|
}
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
/*** PARSESTD ***/
|
2008-12-11 04:19:59 +00:00
|
|
|
|
2009-07-27 20:31:58 +00:00
|
|
|
static qse_ssize_t sf_in_open (
|
|
|
|
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
|
2008-10-01 05:14:20 +00:00
|
|
|
{
|
2009-07-27 20:31:58 +00:00
|
|
|
if (arg == QSE_NULL || arg->name == QSE_NULL)
|
2008-10-01 05:14:20 +00:00
|
|
|
{
|
2009-02-22 06:28:02 +00:00
|
|
|
switch (xtn->s.in.type)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_FILE:
|
2009-02-22 06:28:02 +00:00
|
|
|
if (xtn->s.in.u.file == QSE_NULL) return -1;
|
2008-10-01 05:14:20 +00:00
|
|
|
|
2009-06-24 07:29:18 +00:00
|
|
|
if (xtn->s.in.u.file[0] == QSE_T('-') &&
|
|
|
|
xtn->s.in.u.file[1] == QSE_T('\0'))
|
|
|
|
{
|
|
|
|
/* special file name '-' */
|
|
|
|
xtn->s.in.handle = qse_sio_in;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-08-10 21:29:59 +00:00
|
|
|
const qse_char_t* base;
|
|
|
|
|
2009-06-24 07:29:18 +00:00
|
|
|
xtn->s.in.handle = qse_sio_open (
|
|
|
|
awk->mmgr,
|
|
|
|
0,
|
|
|
|
xtn->s.in.u.file,
|
|
|
|
QSE_SIO_READ
|
|
|
|
);
|
2009-07-25 23:18:42 +00:00
|
|
|
if (xtn->s.in.handle == QSE_NULL)
|
|
|
|
{
|
2009-07-27 20:31:58 +00:00
|
|
|
qse_cstr_t ea;
|
|
|
|
ea.ptr = xtn->s.in.u.file;
|
|
|
|
ea.len = qse_strlen(ea.ptr);
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EOPEN, &ea);
|
2009-07-25 23:18:42 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2009-08-10 21:29:59 +00:00
|
|
|
|
2009-09-05 07:08:19 +00:00
|
|
|
base = qse_basename (xtn->s.in.u.file);
|
2009-08-10 21:29:59 +00:00
|
|
|
if (base != xtn->s.in.u.file)
|
|
|
|
{
|
|
|
|
xtn->s.in.dir.ptr = xtn->s.in.u.file;
|
|
|
|
xtn->s.in.dir.len = base - xtn->s.in.u.file;
|
|
|
|
}
|
2009-06-24 07:29:18 +00:00
|
|
|
}
|
2009-02-22 06:28:02 +00:00
|
|
|
return 1;
|
2008-12-13 03:42:32 +00:00
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_STDIO:
|
2009-02-22 06:28:02 +00:00
|
|
|
xtn->s.in.handle = qse_sio_in;
|
|
|
|
return 1;
|
2008-10-01 05:14:20 +00:00
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CP:
|
|
|
|
case QSE_AWK_PARSESTD_CPL:
|
2009-02-22 06:28:02 +00:00
|
|
|
xtn->s.in.handle = QSE_NULL;
|
|
|
|
return 1;
|
2009-08-01 07:01:04 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
return -1;
|
2009-02-22 06:28:02 +00:00
|
|
|
}
|
2008-10-01 05:14:20 +00:00
|
|
|
}
|
2009-07-27 20:31:58 +00:00
|
|
|
else
|
|
|
|
{
|
2009-08-10 21:29:59 +00:00
|
|
|
const qse_char_t* file = arg->name;
|
|
|
|
qse_char_t fbuf[64];
|
|
|
|
qse_char_t* dbuf = QSE_NULL;
|
|
|
|
|
2009-08-20 08:04:15 +00:00
|
|
|
if (xtn->s.in.dir.len > 0 && arg->name[0] != QSE_T('/'))
|
2009-08-10 21:29:59 +00:00
|
|
|
{
|
|
|
|
qse_size_t tmplen, totlen;
|
|
|
|
|
|
|
|
totlen = qse_strlen(arg->name) + xtn->s.in.dir.len;
|
|
|
|
if (totlen >= QSE_COUNTOF(fbuf))
|
|
|
|
{
|
|
|
|
dbuf = QSE_MMGR_ALLOC (
|
|
|
|
awk->mmgr,
|
|
|
|
QSE_SIZEOF(qse_char_t) * (totlen + 1)
|
|
|
|
);
|
|
|
|
if (dbuf == QSE_NULL)
|
|
|
|
{
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
|
2009-08-10 21:29:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
file = dbuf;
|
|
|
|
}
|
|
|
|
else file = fbuf;
|
|
|
|
|
|
|
|
tmplen = qse_strncpy (
|
|
|
|
(qse_char_t*)file,
|
|
|
|
xtn->s.in.dir.ptr,
|
|
|
|
xtn->s.in.dir.len
|
|
|
|
);
|
|
|
|
qse_strcpy ((qse_char_t*)file + tmplen, arg->name);
|
|
|
|
}
|
|
|
|
|
2009-07-27 20:31:58 +00:00
|
|
|
arg->handle = qse_sio_open (
|
2009-08-10 21:29:59 +00:00
|
|
|
awk->mmgr, 0, file, QSE_SIO_READ
|
2009-07-27 20:31:58 +00:00
|
|
|
);
|
2009-08-10 21:29:59 +00:00
|
|
|
|
|
|
|
if (dbuf != QSE_NULL) QSE_MMGR_FREE (awk->mmgr, dbuf);
|
|
|
|
if (arg->handle == QSE_NULL)
|
2009-07-27 20:31:58 +00:00
|
|
|
{
|
|
|
|
qse_cstr_t ea;
|
|
|
|
ea.ptr = arg->name;
|
|
|
|
ea.len = qse_strlen(ea.ptr);
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EOPEN, &ea);
|
2009-07-27 20:31:58 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static qse_ssize_t sf_in_close (
|
|
|
|
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
|
|
|
|
{
|
|
|
|
if (arg == QSE_NULL || arg->name == QSE_NULL)
|
2008-10-01 05:14:20 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
if (xtn->s.in.handle != QSE_NULL &&
|
|
|
|
xtn->s.in.handle != qse_sio_in &&
|
|
|
|
xtn->s.in.handle != qse_sio_out &&
|
|
|
|
xtn->s.in.handle != qse_sio_err)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
qse_sio_close (xtn->s.in.handle);
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2008-10-01 05:14:20 +00:00
|
|
|
}
|
2009-07-27 20:31:58 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
qse_sio_close (arg->handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static qse_ssize_t sf_in_read (
|
|
|
|
qse_awk_t* awk, qse_awk_sio_arg_t* arg,
|
|
|
|
qse_char_t* data, qse_size_t size, xtn_t* xtn)
|
|
|
|
{
|
|
|
|
if (arg == QSE_NULL || arg->name == QSE_NULL)
|
2008-10-01 05:14:20 +00:00
|
|
|
{
|
2009-02-22 06:28:02 +00:00
|
|
|
switch (xtn->s.in.type)
|
2008-12-11 04:19:59 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_FILE:
|
|
|
|
case QSE_AWK_PARSESTD_STDIO:
|
2009-07-25 23:18:42 +00:00
|
|
|
{
|
|
|
|
qse_ssize_t n;
|
|
|
|
|
2009-02-22 06:28:02 +00:00
|
|
|
QSE_ASSERT (xtn->s.in.handle != QSE_NULL);
|
2009-07-25 23:18:42 +00:00
|
|
|
n = qse_sio_getsn (xtn->s.in.handle, data, size);
|
|
|
|
if (n == -1)
|
|
|
|
{
|
2009-07-27 20:31:58 +00:00
|
|
|
qse_cstr_t ea;
|
|
|
|
ea.ptr = xtn->s.in.u.file;
|
|
|
|
ea.len = qse_strlen(ea.ptr);
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EREAD, &ea);
|
2009-07-25 23:18:42 +00:00
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
2008-12-13 03:42:32 +00:00
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CP:
|
2008-12-11 04:19:59 +00:00
|
|
|
{
|
2009-02-22 06:28:02 +00:00
|
|
|
qse_size_t n = 0;
|
2009-02-23 08:10:34 +00:00
|
|
|
while (n < size && *xtn->s.in.u.cp != QSE_T('\0'))
|
2008-12-13 03:42:32 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
data[n++] = *xtn->s.in.u.cp++;
|
2008-12-13 03:42:32 +00:00
|
|
|
}
|
2009-02-22 06:28:02 +00:00
|
|
|
return n;
|
2008-12-11 04:19:59 +00:00
|
|
|
}
|
2009-02-22 06:28:02 +00:00
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CPL:
|
2008-12-11 04:19:59 +00:00
|
|
|
{
|
2009-02-22 06:28:02 +00:00
|
|
|
qse_size_t n = 0;
|
2009-02-23 08:10:34 +00:00
|
|
|
while (n < size && xtn->s.in.u.cpl.ptr < xtn->s.in.u.cpl.end)
|
2009-02-22 06:28:02 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
data[n++] = *xtn->s.in.u.cpl.ptr++;
|
2009-02-22 06:28:02 +00:00
|
|
|
}
|
|
|
|
return n;
|
2008-12-11 04:19:59 +00:00
|
|
|
}
|
2009-08-01 07:01:04 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
return -1;
|
2008-10-01 05:14:20 +00:00
|
|
|
}
|
|
|
|
}
|
2009-07-27 20:31:58 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
qse_ssize_t n;
|
2008-10-01 05:14:20 +00:00
|
|
|
|
2009-07-27 20:31:58 +00:00
|
|
|
QSE_ASSERT (arg->handle != QSE_NULL);
|
|
|
|
n = qse_sio_getsn (arg->handle, data, size);
|
|
|
|
if (n == -1)
|
|
|
|
{
|
|
|
|
qse_cstr_t ea;
|
|
|
|
ea.ptr = arg->name;
|
|
|
|
ea.len = qse_strlen(ea.ptr);
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EREAD, &ea);
|
2009-07-27 20:31:58 +00:00
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static qse_ssize_t sf_in (
|
|
|
|
qse_awk_t* awk, qse_awk_sio_cmd_t cmd,
|
|
|
|
qse_awk_sio_arg_t* arg, qse_char_t* data, qse_size_t size)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = QSE_XTN (awk);
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case QSE_AWK_SIO_OPEN:
|
|
|
|
return sf_in_open (awk, arg, xtn);
|
|
|
|
|
|
|
|
case QSE_AWK_SIO_CLOSE:
|
|
|
|
return sf_in_close (awk, arg, xtn);
|
|
|
|
|
|
|
|
case QSE_AWK_SIO_READ:
|
|
|
|
return sf_in_read (awk, arg, data, size, xtn);
|
|
|
|
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
2008-10-01 05:14:20 +00:00
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
static qse_ssize_t sf_out (
|
2009-07-25 23:18:42 +00:00
|
|
|
qse_awk_t* awk, qse_awk_sio_cmd_t cmd,
|
|
|
|
qse_awk_sio_arg_t* arg, qse_char_t* data, qse_size_t size)
|
2008-10-01 05:14:20 +00:00
|
|
|
{
|
2009-02-17 02:11:31 +00:00
|
|
|
xtn_t* xtn = QSE_XTN (awk);
|
2008-10-14 05:32:58 +00:00
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
if (cmd == QSE_AWK_SIO_OPEN)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2009-02-22 06:28:02 +00:00
|
|
|
switch (xtn->s.out.type)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_FILE:
|
2009-02-22 06:28:02 +00:00
|
|
|
if (xtn->s.out.u.file == QSE_NULL) return -1;
|
2008-10-01 05:14:20 +00:00
|
|
|
|
2009-06-24 07:29:18 +00:00
|
|
|
if (xtn->s.out.u.file[0] == QSE_T('-') &&
|
|
|
|
xtn->s.out.u.file[1] == QSE_T('\0'))
|
|
|
|
{
|
|
|
|
/* special file name '-' */
|
|
|
|
xtn->s.out.handle = qse_sio_out;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xtn->s.out.handle = qse_sio_open (
|
|
|
|
awk->mmgr,
|
|
|
|
0,
|
|
|
|
xtn->s.out.u.file,
|
|
|
|
QSE_SIO_WRITE |
|
|
|
|
QSE_SIO_CREATE |
|
|
|
|
QSE_SIO_TRUNCATE
|
|
|
|
);
|
2009-07-25 23:18:42 +00:00
|
|
|
if (xtn->s.out.handle == QSE_NULL)
|
|
|
|
{
|
2009-07-27 20:31:58 +00:00
|
|
|
qse_cstr_t ea;
|
|
|
|
ea.ptr = xtn->s.out.u.file;
|
|
|
|
ea.len = qse_strlen(ea.ptr);
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EOPEN, &ea);
|
2009-07-25 23:18:42 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2009-06-24 07:29:18 +00:00
|
|
|
}
|
2009-02-22 06:28:02 +00:00
|
|
|
return 1;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_STDIO:
|
2009-02-22 06:28:02 +00:00
|
|
|
xtn->s.out.handle = qse_sio_out;
|
|
|
|
return 1;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CP:
|
|
|
|
case QSE_AWK_PARSESTD_CPL:
|
2009-02-22 06:28:02 +00:00
|
|
|
xtn->s.out.handle = QSE_NULL;
|
|
|
|
return 1;
|
|
|
|
}
|
2008-10-14 05:32:58 +00:00
|
|
|
}
|
2009-02-17 02:11:31 +00:00
|
|
|
else if (cmd == QSE_AWK_SIO_CLOSE)
|
2008-10-01 05:14:20 +00:00
|
|
|
{
|
2009-02-22 06:28:02 +00:00
|
|
|
switch (xtn->s.out.type)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_FILE:
|
|
|
|
case QSE_AWK_PARSESTD_STDIO:
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2009-02-22 06:28:02 +00:00
|
|
|
qse_sio_flush (xtn->s.out.handle);
|
|
|
|
if (xtn->s.out.handle != qse_sio_in &&
|
|
|
|
xtn->s.out.handle != qse_sio_out &&
|
|
|
|
xtn->s.out.handle != qse_sio_err)
|
|
|
|
{
|
|
|
|
qse_sio_close (xtn->s.out.handle);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CP:
|
|
|
|
*xtn->s.out.u.cp = QSE_T('\0');
|
2009-02-22 06:28:02 +00:00
|
|
|
return 0;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CPL:
|
|
|
|
xtn->s.out.u.cpl.osp->len =
|
|
|
|
xtn->s.out.u.cpl.ptr -
|
|
|
|
xtn->s.out.u.cpl.osp->ptr;
|
2009-02-22 06:28:02 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-10-01 05:14:20 +00:00
|
|
|
}
|
2009-02-17 02:11:31 +00:00
|
|
|
else if (cmd == QSE_AWK_SIO_WRITE)
|
2008-10-01 05:14:20 +00:00
|
|
|
{
|
2009-02-22 06:28:02 +00:00
|
|
|
switch (xtn->s.out.type)
|
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_FILE:
|
|
|
|
case QSE_AWK_PARSESTD_STDIO:
|
2009-07-25 23:18:42 +00:00
|
|
|
{
|
|
|
|
qse_ssize_t n;
|
2009-02-22 06:28:02 +00:00
|
|
|
QSE_ASSERT (xtn->s.out.handle != QSE_NULL);
|
2009-07-25 23:18:42 +00:00
|
|
|
n = qse_sio_putsn (xtn->s.out.handle, data, size);
|
|
|
|
if (n == -1)
|
|
|
|
{
|
2009-07-27 20:31:58 +00:00
|
|
|
qse_cstr_t ea;
|
|
|
|
ea.ptr = xtn->s.in.u.file;
|
|
|
|
ea.len = qse_strlen(ea.ptr);
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EWRITE, &ea);
|
2009-07-25 23:18:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
2009-02-22 06:28:02 +00:00
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CP:
|
2009-02-22 06:28:02 +00:00
|
|
|
{
|
|
|
|
qse_size_t n = 0;
|
2009-02-23 08:10:34 +00:00
|
|
|
while (n < size && *xtn->s.out.u.cp != QSE_T('\0'))
|
2009-02-22 06:28:02 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
*xtn->s.out.u.cp++ = data[n++];
|
2009-02-22 06:28:02 +00:00
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CPL:
|
2009-02-22 06:28:02 +00:00
|
|
|
{
|
|
|
|
qse_size_t n = 0;
|
2009-02-23 08:10:34 +00:00
|
|
|
while (n < size && xtn->s.out.u.cpl.ptr < xtn->s.out.u.cpl.end)
|
2009-02-22 06:28:02 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
*xtn->s.out.u.cpl.ptr++ = data[n++];
|
2009-02-22 06:28:02 +00:00
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
}
|
2008-10-01 05:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
int qse_awk_parsestd (
|
2009-02-21 23:06:45 +00:00
|
|
|
qse_awk_t* awk,
|
2009-02-23 08:10:34 +00:00
|
|
|
const qse_awk_parsestd_in_t* in,
|
|
|
|
qse_awk_parsestd_out_t* out)
|
2008-10-01 05:14:20 +00:00
|
|
|
{
|
2009-02-12 04:46:24 +00:00
|
|
|
qse_awk_sio_t sio;
|
2009-02-17 02:11:31 +00:00
|
|
|
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
|
2008-10-01 05:14:20 +00:00
|
|
|
|
2009-02-22 08:16:35 +00:00
|
|
|
if (in == QSE_NULL)
|
2008-10-14 05:32:58 +00:00
|
|
|
{
|
2009-02-22 08:16:35 +00:00
|
|
|
/* the input is a must */
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
|
2009-02-22 08:16:35 +00:00
|
|
|
return -1;
|
2009-02-21 23:06:45 +00:00
|
|
|
}
|
2009-02-22 06:28:02 +00:00
|
|
|
|
2009-02-22 08:16:35 +00:00
|
|
|
switch (in->type)
|
2008-12-11 04:19:59 +00:00
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_FILE:
|
2009-02-22 08:16:35 +00:00
|
|
|
xtn->s.in.u.file = in->u.file;
|
2009-02-22 06:28:02 +00:00
|
|
|
break;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CP:
|
|
|
|
xtn->s.in.u.cp = in->u.cp;
|
2009-02-22 06:28:02 +00:00
|
|
|
break;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CPL:
|
|
|
|
xtn->s.in.u.cpl.ptr = in->u.cpl.ptr;
|
|
|
|
xtn->s.in.u.cpl.end = in->u.cpl.ptr + in->u.cpl.len;
|
2009-02-22 06:28:02 +00:00
|
|
|
break;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_STDIO:
|
2009-02-22 06:28:02 +00:00
|
|
|
/* nothing to do */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
|
2009-02-22 06:28:02 +00:00
|
|
|
return -1;
|
2008-12-11 04:19:59 +00:00
|
|
|
}
|
2009-02-22 08:16:35 +00:00
|
|
|
xtn->s.in.type = in->type;
|
2009-02-16 08:31:34 +00:00
|
|
|
xtn->s.in.handle = QSE_NULL;
|
2009-02-22 08:16:35 +00:00
|
|
|
sio.in = sf_in;
|
2008-12-13 03:42:32 +00:00
|
|
|
|
2009-02-22 08:16:35 +00:00
|
|
|
if (out == QSE_NULL) sio.out = QSE_NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (out->type)
|
|
|
|
{
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_FILE:
|
2009-02-22 08:16:35 +00:00
|
|
|
xtn->s.out.u.file = out->u.file;
|
|
|
|
break;
|
2008-10-13 09:08:26 +00:00
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CP:
|
|
|
|
xtn->s.out.u.cp = out->u.cp;
|
2009-02-22 08:16:35 +00:00
|
|
|
break;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_CPL:
|
|
|
|
xtn->s.out.u.cpl.osp = &out->u.cpl;
|
|
|
|
xtn->s.out.u.cpl.ptr = out->u.cpl.ptr;
|
|
|
|
xtn->s.out.u.cpl.end = out->u.cpl.ptr + out->u.cpl.len;
|
2009-02-22 08:16:35 +00:00
|
|
|
break;
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
case QSE_AWK_PARSESTD_STDIO:
|
2009-02-22 08:16:35 +00:00
|
|
|
/* nothing to do */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
|
2009-02-22 08:16:35 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
xtn->s.out.type = out->type;
|
|
|
|
xtn->s.out.handle = QSE_NULL;
|
|
|
|
sio.out = sf_out;
|
|
|
|
}
|
2008-10-01 05:14:20 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
return qse_awk_parse (awk, &sio);
|
2008-10-01 05:14:20 +00:00
|
|
|
}
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
/*** RTX_OPENSTD ***/
|
2009-02-16 08:31:34 +00:00
|
|
|
static qse_ssize_t awk_rio_pipe (
|
2009-06-17 00:05:40 +00:00
|
|
|
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
|
2009-02-16 08:31:34 +00:00
|
|
|
qse_char_t* data, qse_size_t size)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
|
|
|
switch (cmd)
|
|
|
|
{
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_OPEN:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-29 08:50:30 +00:00
|
|
|
qse_pio_t* handle;
|
2009-01-15 03:58:27 +00:00
|
|
|
int flags;
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
if (riod->mode == QSE_AWK_RIO_PIPE_READ)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-17 04:20:22 +00:00
|
|
|
/* TODO: should we specify ERRTOOUT? */
|
2009-01-29 08:50:30 +00:00
|
|
|
flags = QSE_PIO_READOUT |
|
|
|
|
QSE_PIO_ERRTOOUT;
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2009-02-16 08:31:34 +00:00
|
|
|
else if (riod->mode == QSE_AWK_RIO_PIPE_WRITE)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-29 08:50:30 +00:00
|
|
|
flags = QSE_PIO_WRITEIN;
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2009-02-16 08:31:34 +00:00
|
|
|
else if (riod->mode == QSE_AWK_RIO_PIPE_RW)
|
2009-01-17 04:20:22 +00:00
|
|
|
{
|
2009-01-29 08:50:30 +00:00
|
|
|
flags = QSE_PIO_READOUT |
|
|
|
|
QSE_PIO_ERRTOOUT |
|
|
|
|
QSE_PIO_WRITEIN;
|
2009-01-17 04:20:22 +00:00
|
|
|
}
|
2008-12-12 04:05:28 +00:00
|
|
|
else return -1; /* TODO: any way to set the error number? */
|
|
|
|
|
2009-01-29 08:50:30 +00:00
|
|
|
handle = qse_pio_open (
|
2009-02-16 08:31:34 +00:00
|
|
|
rtx->awk->mmgr,
|
2009-01-15 03:58:27 +00:00
|
|
|
0,
|
2009-02-16 08:31:34 +00:00
|
|
|
riod->name,
|
2009-01-29 08:50:30 +00:00
|
|
|
flags|QSE_PIO_SHELL|QSE_PIO_TEXT
|
2009-01-15 03:58:27 +00:00
|
|
|
);
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (handle == QSE_NULL) return -1;
|
2009-02-16 08:31:34 +00:00
|
|
|
riod->handle = (void*)handle;
|
2008-12-12 04:05:28 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_CLOSE:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-08-28 06:52:20 +00:00
|
|
|
qse_pio_t* pio = (qse_pio_t*)riod->handle;
|
|
|
|
if (riod->mode == QSE_AWK_RIO_PIPE_RW)
|
|
|
|
{
|
|
|
|
/* specialy treatment is needef for rwpipe.
|
2009-08-29 03:48:02 +00:00
|
|
|
* inspect rwcmode to see if partial closing is
|
2009-08-28 06:52:20 +00:00
|
|
|
* requested. */
|
2009-08-29 03:48:02 +00:00
|
|
|
if (riod->rwcmode == QSE_AWK_RIO_CLOSE_READ)
|
2009-08-28 06:52:20 +00:00
|
|
|
{
|
|
|
|
qse_pio_end (pio, QSE_PIO_IN);
|
|
|
|
return 0;
|
|
|
|
}
|
2009-08-29 03:48:02 +00:00
|
|
|
if (riod->rwcmode == QSE_AWK_RIO_CLOSE_WRITE)
|
2009-08-28 06:52:20 +00:00
|
|
|
{
|
|
|
|
qse_pio_end (pio, QSE_PIO_OUT);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_pio_close (pio);
|
2009-02-16 08:31:34 +00:00
|
|
|
riod->handle = QSE_NULL;
|
2008-12-12 04:05:28 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_READ:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-29 08:50:30 +00:00
|
|
|
return qse_pio_read (
|
2009-02-16 08:31:34 +00:00
|
|
|
(qse_pio_t*)riod->handle,
|
2008-12-12 04:05:28 +00:00
|
|
|
data,
|
2009-01-15 03:58:27 +00:00
|
|
|
size,
|
2009-01-29 08:50:30 +00:00
|
|
|
QSE_PIO_OUT
|
2008-12-12 04:05:28 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_WRITE:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-29 08:50:30 +00:00
|
|
|
return qse_pio_write (
|
2009-02-16 08:31:34 +00:00
|
|
|
(qse_pio_t*)riod->handle,
|
2008-12-12 04:05:28 +00:00
|
|
|
data,
|
2009-01-15 03:58:27 +00:00
|
|
|
size,
|
2009-01-29 08:50:30 +00:00
|
|
|
QSE_PIO_IN
|
2008-12-12 04:05:28 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_FLUSH:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
/*if (riod->mode == QSE_AWK_RIO_PIPE_READ) return -1;*/
|
|
|
|
return qse_pio_flush ((qse_pio_t*)riod->handle, QSE_PIO_IN);
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_NEXT:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
static qse_ssize_t awk_rio_file (
|
2009-06-17 00:05:40 +00:00
|
|
|
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
|
2009-02-16 08:31:34 +00:00
|
|
|
qse_char_t* data, qse_size_t size)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
|
|
|
switch (cmd)
|
|
|
|
{
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_OPEN:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-31 04:31:40 +00:00
|
|
|
qse_fio_t* handle;
|
|
|
|
int flags;
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
if (riod->mode == QSE_AWK_RIO_FILE_READ)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-31 04:31:40 +00:00
|
|
|
flags = QSE_FIO_READ;
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2009-02-16 08:31:34 +00:00
|
|
|
else if (riod->mode == QSE_AWK_RIO_FILE_WRITE)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-31 04:31:40 +00:00
|
|
|
flags = QSE_FIO_WRITE |
|
2009-02-22 06:28:02 +00:00
|
|
|
QSE_FIO_CREATE |
|
|
|
|
QSE_FIO_TRUNCATE;
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2009-02-16 08:31:34 +00:00
|
|
|
else if (riod->mode == QSE_AWK_RIO_FILE_APPEND)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-31 04:31:40 +00:00
|
|
|
flags = QSE_FIO_APPEND |
|
2009-02-22 06:28:02 +00:00
|
|
|
QSE_FIO_CREATE;
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
|
|
|
else return -1; /* TODO: any way to set the error number? */
|
|
|
|
|
2009-01-31 04:31:40 +00:00
|
|
|
handle = qse_fio_open (
|
2009-02-16 08:31:34 +00:00
|
|
|
rtx->awk->mmgr,
|
2008-12-12 04:05:28 +00:00
|
|
|
0,
|
2009-02-16 08:31:34 +00:00
|
|
|
riod->name,
|
2009-01-31 04:31:40 +00:00
|
|
|
flags | QSE_FIO_TEXT,
|
|
|
|
QSE_FIO_RUSR | QSE_FIO_WUSR |
|
|
|
|
QSE_FIO_RGRP | QSE_FIO_ROTH
|
2008-12-12 04:05:28 +00:00
|
|
|
);
|
2008-12-21 21:35:07 +00:00
|
|
|
if (handle == QSE_NULL)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_cstr_t errarg;
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
errarg.ptr = riod->name;
|
|
|
|
errarg.len = qse_strlen(riod->name);
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EOPEN, &errarg);
|
2008-12-12 04:05:28 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
riod->handle = (void*)handle;
|
2008-12-12 04:05:28 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_CLOSE:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
qse_fio_close ((qse_fio_t*)riod->handle);
|
|
|
|
riod->handle = QSE_NULL;
|
2008-12-12 04:05:28 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_READ:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-31 04:31:40 +00:00
|
|
|
return qse_fio_read (
|
2009-02-16 08:31:34 +00:00
|
|
|
(qse_fio_t*)riod->handle,
|
2008-12-12 04:05:28 +00:00
|
|
|
data,
|
|
|
|
size
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_WRITE:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-31 04:31:40 +00:00
|
|
|
return qse_fio_write (
|
2009-02-16 08:31:34 +00:00
|
|
|
(qse_fio_t*)riod->handle,
|
2008-12-12 04:05:28 +00:00
|
|
|
data,
|
|
|
|
size
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_FLUSH:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
return qse_fio_flush ((qse_fio_t*)riod->handle);
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
case QSE_AWK_RIO_NEXT:
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-06-17 00:05:40 +00:00
|
|
|
static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod)
|
2008-12-12 07:43:05 +00:00
|
|
|
{
|
2009-02-17 02:11:31 +00:00
|
|
|
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
|
2008-12-12 07:43:05 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
if (riod->mode == QSE_AWK_RIO_CONSOLE_READ)
|
2008-12-12 07:43:05 +00:00
|
|
|
{
|
2009-02-18 04:37:34 +00:00
|
|
|
if (rxtn->c.in.files == QSE_NULL)
|
|
|
|
{
|
2009-06-11 07:18:25 +00:00
|
|
|
/* if no input files is specified,
|
|
|
|
* open the standard input */
|
|
|
|
QSE_ASSERT (rxtn->c.in.index == 0);
|
2009-07-08 07:05:10 +00:00
|
|
|
|
|
|
|
if (rxtn->c.in.count == 0)
|
|
|
|
{
|
|
|
|
riod->handle = qse_sio_in;
|
|
|
|
rxtn->c.in.count++;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2008-12-12 07:43:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-18 04:37:34 +00:00
|
|
|
/* a temporary variable sio is used here not to change
|
2009-02-16 08:31:34 +00:00
|
|
|
* any fields of riod when the open operation fails */
|
2009-02-18 04:37:34 +00:00
|
|
|
qse_sio_t* sio;
|
2009-06-11 07:18:25 +00:00
|
|
|
const qse_char_t* file;
|
2009-06-25 02:29:33 +00:00
|
|
|
qse_awk_val_t* argv;
|
2010-07-09 00:58:44 +00:00
|
|
|
qse_htb_t* map;
|
|
|
|
qse_htb_pair_t* pair;
|
2009-06-25 02:29:33 +00:00
|
|
|
qse_char_t ibuf[128];
|
|
|
|
qse_size_t ibuflen;
|
|
|
|
qse_awk_val_t* v;
|
|
|
|
qse_awk_rtx_valtostr_out_t out;
|
|
|
|
|
|
|
|
nextfile:
|
2009-06-11 07:18:25 +00:00
|
|
|
file = rxtn->c.in.files[rxtn->c.in.index];
|
|
|
|
|
|
|
|
if (file == QSE_NULL)
|
2008-12-12 07:43:05 +00:00
|
|
|
{
|
2009-06-11 07:18:25 +00:00
|
|
|
/* no more input file */
|
2009-06-25 02:29:33 +00:00
|
|
|
|
|
|
|
if (rxtn->c.in.count == 0)
|
|
|
|
{
|
|
|
|
/* all ARGVs are empty strings.
|
|
|
|
* so no console files were opened.
|
|
|
|
* open the standard input here.
|
|
|
|
*
|
|
|
|
* 'BEGIN { ARGV[1]=""; ARGV[2]=""; }
|
|
|
|
* { print $0; }' file1 file2
|
|
|
|
*/
|
|
|
|
riod->handle = qse_sio_in;
|
|
|
|
rxtn->c.in.count++;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-06-11 07:18:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-12-12 07:43:05 +00:00
|
|
|
|
2009-06-25 02:29:33 +00:00
|
|
|
/* handle special case when ARGV[x] has been altered.
|
|
|
|
* so from here down, the file name gotten from
|
|
|
|
* rxtn->c.in.files is not important and is overridden
|
|
|
|
* from ARGV.
|
|
|
|
* 'BEGIN { ARGV[1]="file3"; }
|
|
|
|
* { print $0; }' file1 file2
|
|
|
|
*/
|
|
|
|
argv = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_ARGV);
|
|
|
|
QSE_ASSERT (argv != QSE_NULL);
|
|
|
|
QSE_ASSERT (argv->type == QSE_AWK_VAL_MAP);
|
|
|
|
|
|
|
|
map = ((qse_awk_val_map_t*)argv)->map;
|
|
|
|
QSE_ASSERT (map != QSE_NULL);
|
|
|
|
|
|
|
|
ibuflen = qse_awk_longtostr (
|
|
|
|
rtx->awk, rxtn->c.in.index + 1, 10, QSE_NULL,
|
|
|
|
ibuf, QSE_COUNTOF(ibuf));
|
|
|
|
|
2010-07-09 00:58:44 +00:00
|
|
|
pair = qse_htb_search (map, ibuf, ibuflen);
|
2009-06-25 02:29:33 +00:00
|
|
|
QSE_ASSERT (pair != QSE_NULL);
|
|
|
|
|
2010-07-09 00:58:44 +00:00
|
|
|
v = QSE_HTB_VPTR(pair);
|
2009-06-25 02:29:33 +00:00
|
|
|
QSE_ASSERT (v != QSE_NULL);
|
|
|
|
|
|
|
|
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
|
|
|
if (qse_awk_rtx_valtostr (rtx, v, &out) == QSE_NULL) return -1;
|
|
|
|
|
|
|
|
if (out.u.cpldup.len == 0)
|
|
|
|
{
|
|
|
|
/* the name is empty */
|
|
|
|
qse_awk_rtx_free (rtx, out.u.cpldup.ptr);
|
|
|
|
rxtn->c.in.index++;
|
|
|
|
goto nextfile;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qse_strlen(out.u.cpldup.ptr) < out.u.cpldup.len)
|
|
|
|
{
|
|
|
|
/* the name contains one or more '\0' */
|
|
|
|
qse_cstr_t errarg;
|
|
|
|
|
|
|
|
errarg.ptr = out.u.cpldup.ptr;
|
|
|
|
/* use this length not to contains '\0'
|
|
|
|
* in an error message */
|
|
|
|
errarg.len = qse_strlen(out.u.cpldup.ptr);
|
|
|
|
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_rtx_seterrnum (
|
|
|
|
rtx, QSE_AWK_EIONMNL, &errarg);
|
2009-06-25 02:29:33 +00:00
|
|
|
|
|
|
|
qse_awk_rtx_free (rtx, out.u.cpldup.ptr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
file = out.u.cpldup.ptr;
|
|
|
|
|
2009-06-11 07:18:25 +00:00
|
|
|
if (file[0] == QSE_T('-') && file[1] == QSE_T('\0'))
|
|
|
|
{
|
|
|
|
/* special file name '-' */
|
|
|
|
sio = qse_sio_in;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sio = qse_sio_open (
|
|
|
|
rtx->awk->mmgr, 0, file, QSE_SIO_READ);
|
|
|
|
if (sio == QSE_NULL)
|
|
|
|
{
|
|
|
|
qse_cstr_t errarg;
|
2008-12-12 07:43:05 +00:00
|
|
|
|
2009-06-11 07:18:25 +00:00
|
|
|
errarg.ptr = file;
|
|
|
|
errarg.len = qse_strlen(file);
|
|
|
|
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_rtx_seterrnum (
|
|
|
|
rtx, QSE_AWK_EOPEN, &errarg);
|
2009-06-25 02:29:33 +00:00
|
|
|
|
|
|
|
qse_awk_rtx_free (rtx, out.u.cpldup.ptr);
|
2009-06-11 07:18:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-12-12 07:43:05 +00:00
|
|
|
}
|
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
if (qse_awk_rtx_setfilename (
|
2011-04-18 09:28:22 +00:00
|
|
|
rtx, file, qse_strlen(file)) <= -1)
|
2008-12-12 07:43:05 +00:00
|
|
|
{
|
2009-06-11 07:18:25 +00:00
|
|
|
if (sio != qse_sio_in) qse_sio_close (sio);
|
2009-06-25 02:29:33 +00:00
|
|
|
qse_awk_rtx_free (rtx, out.u.cpldup.ptr);
|
2008-12-12 07:43:05 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-06-25 02:29:33 +00:00
|
|
|
qse_awk_rtx_free (rtx, out.u.cpldup.ptr);
|
2009-02-18 04:37:34 +00:00
|
|
|
riod->handle = sio;
|
2009-06-25 02:29:33 +00:00
|
|
|
|
|
|
|
/* increment the counter of files successfully opened */
|
|
|
|
rxtn->c.in.count++;
|
2009-07-08 07:05:10 +00:00
|
|
|
rxtn->c.in.index++;
|
|
|
|
return 1;
|
2008-12-12 07:43:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2009-02-16 08:31:34 +00:00
|
|
|
else if (riod->mode == QSE_AWK_RIO_CONSOLE_WRITE)
|
2008-12-12 07:43:05 +00:00
|
|
|
{
|
2009-02-18 04:37:34 +00:00
|
|
|
if (rxtn->c.out.files == QSE_NULL)
|
|
|
|
{
|
2009-06-11 07:18:25 +00:00
|
|
|
QSE_ASSERT (rxtn->c.out.index == 0);
|
2009-07-08 07:05:10 +00:00
|
|
|
|
|
|
|
if (rxtn->c.out.count == 0)
|
|
|
|
{
|
|
|
|
riod->handle = qse_sio_out;
|
|
|
|
rxtn->c.out.count++;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2009-02-18 04:37:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* a temporary variable sio is used here not to change
|
|
|
|
* any fields of riod when the open operation fails */
|
|
|
|
qse_sio_t* sio;
|
2009-06-11 07:18:25 +00:00
|
|
|
const qse_char_t* file;
|
|
|
|
|
|
|
|
file = rxtn->c.out.files[rxtn->c.out.index];
|
|
|
|
|
|
|
|
if (file == QSE_NULL)
|
|
|
|
{
|
|
|
|
/* no more input file */
|
|
|
|
return 0;
|
|
|
|
}
|
2009-02-18 04:37:34 +00:00
|
|
|
|
2009-06-24 07:29:18 +00:00
|
|
|
if (file[0] == QSE_T('-') && file[1] == QSE_T('\0'))
|
2009-02-18 04:37:34 +00:00
|
|
|
{
|
2009-06-24 07:29:18 +00:00
|
|
|
/* special file name '-' */
|
|
|
|
sio = qse_sio_out;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sio = qse_sio_open (
|
2011-04-17 08:55:26 +00:00
|
|
|
rtx->awk->mmgr, 0, file,
|
|
|
|
QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE
|
|
|
|
);
|
2009-06-24 07:29:18 +00:00
|
|
|
if (sio == QSE_NULL)
|
|
|
|
{
|
|
|
|
qse_cstr_t errarg;
|
2009-02-18 04:37:34 +00:00
|
|
|
|
2009-06-24 07:29:18 +00:00
|
|
|
errarg.ptr = file;
|
|
|
|
errarg.len = qse_strlen(file);
|
2009-02-18 04:37:34 +00:00
|
|
|
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_rtx_seterrnum (
|
|
|
|
rtx, QSE_AWK_EOPEN, &errarg);
|
2009-06-24 07:29:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2009-02-18 04:37:34 +00:00
|
|
|
}
|
2009-06-24 07:29:18 +00:00
|
|
|
|
2009-02-18 04:37:34 +00:00
|
|
|
if (qse_awk_rtx_setofilename (
|
2011-04-18 09:28:22 +00:00
|
|
|
rtx, file, qse_strlen(file)) <= -1)
|
2009-02-18 04:37:34 +00:00
|
|
|
{
|
|
|
|
qse_sio_close (sio);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
riod->handle = sio;
|
2009-07-08 07:05:10 +00:00
|
|
|
|
|
|
|
rxtn->c.out.index++;
|
|
|
|
rxtn->c.out.count++;
|
|
|
|
return 1;
|
2008-12-12 07:43:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
static qse_ssize_t awk_rio_console (
|
2009-06-17 00:05:40 +00:00
|
|
|
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
|
2009-02-16 08:31:34 +00:00
|
|
|
qse_char_t* data, qse_size_t size)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-17 02:11:31 +00:00
|
|
|
if (cmd == QSE_AWK_RIO_OPEN)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
return open_rio_console (rtx, riod);
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2009-02-17 02:11:31 +00:00
|
|
|
else if (cmd == QSE_AWK_RIO_CLOSE)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
if (riod->handle != QSE_NULL &&
|
|
|
|
riod->handle != qse_sio_in &&
|
|
|
|
riod->handle != qse_sio_out &&
|
|
|
|
riod->handle != qse_sio_err)
|
2008-12-12 07:43:05 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
qse_sio_close ((qse_sio_t*)riod->handle);
|
2008-12-12 07:43:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2009-02-17 02:11:31 +00:00
|
|
|
else if (cmd == QSE_AWK_RIO_READ)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-07-08 07:05:10 +00:00
|
|
|
qse_ssize_t nn;
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2009-07-08 07:05:10 +00:00
|
|
|
while ((nn = qse_sio_getsn((qse_sio_t*)riod->handle,data,size)) == 0)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-07-08 07:05:10 +00:00
|
|
|
int n;
|
|
|
|
qse_sio_t* sio = (qse_sio_t*)riod->handle;
|
|
|
|
|
|
|
|
n = open_rio_console (rtx, riod);
|
|
|
|
if (n == -1) return -1;
|
2009-06-11 07:18:25 +00:00
|
|
|
|
2009-07-08 07:05:10 +00:00
|
|
|
if (n == 0)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
|
|
|
/* no more input console */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-08 07:05:10 +00:00
|
|
|
if (sio != QSE_NULL &&
|
|
|
|
sio != qse_sio_in &&
|
|
|
|
sio != qse_sio_out &&
|
|
|
|
sio != qse_sio_err)
|
2009-06-11 07:18:25 +00:00
|
|
|
{
|
2009-07-08 07:05:10 +00:00
|
|
|
qse_sio_close (sio);
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-08 07:05:10 +00:00
|
|
|
return nn;
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2009-02-17 02:11:31 +00:00
|
|
|
else if (cmd == QSE_AWK_RIO_WRITE)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-01-31 04:31:40 +00:00
|
|
|
return qse_sio_putsn (
|
2009-02-16 08:31:34 +00:00
|
|
|
(qse_sio_t*)riod->handle,
|
2008-12-12 04:05:28 +00:00
|
|
|
data,
|
|
|
|
size
|
|
|
|
);
|
|
|
|
}
|
2009-02-17 02:11:31 +00:00
|
|
|
else if (cmd == QSE_AWK_RIO_FLUSH)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-16 08:31:34 +00:00
|
|
|
return qse_sio_flush ((qse_sio_t*)riod->handle);
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
2009-02-17 02:11:31 +00:00
|
|
|
else if (cmd == QSE_AWK_RIO_NEXT)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2008-12-12 07:43:05 +00:00
|
|
|
int n;
|
2009-02-18 04:37:34 +00:00
|
|
|
qse_sio_t* sio = (qse_sio_t*)riod->handle;
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
n = open_rio_console (rtx, riod);
|
2008-12-12 07:43:05 +00:00
|
|
|
if (n == -1) return -1;
|
2008-12-12 04:05:28 +00:00
|
|
|
|
2008-12-12 07:43:05 +00:00
|
|
|
if (n == 0)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2008-12-12 07:43:05 +00:00
|
|
|
/* if there is no more file, keep the previous handle */
|
2008-12-12 04:05:28 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-18 04:37:34 +00:00
|
|
|
if (sio != QSE_NULL &&
|
|
|
|
sio != qse_sio_in &&
|
|
|
|
sio != qse_sio_out &&
|
|
|
|
sio != qse_sio_err)
|
2008-12-12 04:05:28 +00:00
|
|
|
{
|
2009-02-18 04:37:34 +00:00
|
|
|
qse_sio_close (sio);
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
|
|
|
|
2008-12-12 07:43:05 +00:00
|
|
|
return n;
|
2008-12-12 04:05:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-02-23 08:10:34 +00:00
|
|
|
qse_awk_rtx_t* qse_awk_rtx_openstd (
|
2011-04-18 09:28:22 +00:00
|
|
|
qse_awk_t* awk,
|
|
|
|
qse_size_t xtnsize,
|
|
|
|
const qse_char_t* id,
|
2009-08-29 05:58:05 +00:00
|
|
|
const qse_char_t*const icf[],
|
|
|
|
const qse_char_t*const ocf[])
|
2009-02-13 04:55:25 +00:00
|
|
|
{
|
2009-02-14 04:57:09 +00:00
|
|
|
qse_awk_rtx_t* rtx;
|
2009-02-13 04:55:25 +00:00
|
|
|
qse_awk_rio_t rio;
|
|
|
|
rxtn_t* rxtn;
|
|
|
|
qse_ntime_t now;
|
|
|
|
|
2009-06-10 07:07:42 +00:00
|
|
|
const qse_char_t*const* p;
|
|
|
|
qse_size_t argc = 0;
|
|
|
|
qse_cstr_t argv[16];
|
|
|
|
qse_cstr_t* argvp = QSE_NULL, * p2;
|
2009-08-29 05:58:05 +00:00
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
rio.pipe = awk_rio_pipe;
|
|
|
|
rio.file = awk_rio_file;
|
|
|
|
rio.console = awk_rio_console;
|
2009-02-13 04:55:25 +00:00
|
|
|
|
2009-06-10 07:07:42 +00:00
|
|
|
if (icf != QSE_NULL)
|
|
|
|
{
|
|
|
|
for (p = icf; *p != QSE_NULL; p++);
|
|
|
|
argc = p - icf;
|
|
|
|
}
|
|
|
|
|
|
|
|
argc++; /* for id */
|
|
|
|
|
|
|
|
if (argc < QSE_COUNTOF(argv)) argvp = argv;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
argvp = QSE_AWK_ALLOC (
|
|
|
|
awk, QSE_SIZEOF(*argvp) * (argc + 1));
|
|
|
|
if (argvp == QSE_NULL)
|
|
|
|
{
|
2009-08-17 07:44:20 +00:00
|
|
|
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
|
2009-06-10 07:07:42 +00:00
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p2 = argvp;
|
|
|
|
|
|
|
|
p2->ptr = id;
|
|
|
|
p2->len = qse_strlen(id);
|
|
|
|
p2++;
|
|
|
|
|
|
|
|
if (icf != QSE_NULL)
|
|
|
|
{
|
|
|
|
for (p = icf; *p != QSE_NULL; p++, p2++)
|
|
|
|
{
|
|
|
|
p2->ptr = *p;
|
|
|
|
p2->len = qse_strlen(*p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p2->ptr = QSE_NULL;
|
|
|
|
p2->len = 0;
|
|
|
|
|
2009-02-13 04:55:25 +00:00
|
|
|
rtx = qse_awk_rtx_open (
|
|
|
|
awk,
|
2009-02-27 06:55:05 +00:00
|
|
|
QSE_SIZEOF(rxtn_t) + xtnsize,
|
2009-02-13 04:55:25 +00:00
|
|
|
&rio,
|
2009-06-10 07:07:42 +00:00
|
|
|
argvp
|
2009-02-13 04:55:25 +00:00
|
|
|
);
|
2009-06-10 07:07:42 +00:00
|
|
|
|
|
|
|
if (argvp != QSE_NULL && argvp != argv) QSE_AWK_FREE (awk, argvp);
|
2009-02-13 04:55:25 +00:00
|
|
|
if (rtx == QSE_NULL) return QSE_NULL;
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
rxtn = (rxtn_t*) QSE_XTN (rtx);
|
2009-02-16 08:31:34 +00:00
|
|
|
QSE_MEMSET (rxtn, 0, QSE_SIZEOF(rxtn_t));
|
|
|
|
|
2009-02-13 04:55:25 +00:00
|
|
|
if (qse_gettime (&now) == -1) rxtn->seed = 0;
|
2009-02-13 08:23:35 +00:00
|
|
|
else rxtn->seed = (unsigned int) now;
|
2009-02-13 04:55:25 +00:00
|
|
|
srand (rxtn->seed);
|
|
|
|
|
2009-02-16 08:31:34 +00:00
|
|
|
rxtn->c.in.files = icf;
|
|
|
|
rxtn->c.in.index = 0;
|
2009-06-25 02:29:33 +00:00
|
|
|
rxtn->c.in.count = 0;
|
2009-02-18 04:37:34 +00:00
|
|
|
rxtn->c.out.files = ocf;
|
|
|
|
rxtn->c.out.index = 0;
|
2009-07-08 07:05:10 +00:00
|
|
|
rxtn->c.out.count = 0;
|
2009-02-13 08:23:35 +00:00
|
|
|
|
2011-04-18 09:28:22 +00:00
|
|
|
if (icf && icf[0])
|
|
|
|
{
|
|
|
|
/* If an explicit console file name is given,
|
|
|
|
* set FILENAME in advance in case FILENAME printing
|
|
|
|
* is the first output statement executed. FILENAME
|
|
|
|
* would be printed as an empty string without this
|
|
|
|
* as FILENAME is resolved before the I/O handler is
|
|
|
|
* executed.
|
|
|
|
*/
|
|
|
|
if (qse_awk_rtx_setfilename (rtx, icf[0], qse_strlen(icf[0])) <= -1)
|
|
|
|
{
|
|
|
|
awk->errinf = rtx->errinf; /* transfer error info */
|
|
|
|
qse_awk_rtx_close (rtx);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ocf && ocf[0])
|
|
|
|
{
|
|
|
|
/* If an explicit console file name is given,
|
|
|
|
* set OFILENAME in advance in case OFILENAME printing
|
|
|
|
* is the first output statement executed. OFILENAME
|
|
|
|
* would be printed as an empty string without this
|
|
|
|
* as OFILENAME is resolved before the I/O handler is
|
|
|
|
* executed.
|
|
|
|
*/
|
|
|
|
if (qse_awk_rtx_setofilename (rtx, ocf[0], qse_strlen(ocf[0])) <= -1)
|
|
|
|
{
|
|
|
|
awk->errinf = rtx->errinf; /* transfer error info */
|
|
|
|
qse_awk_rtx_close (rtx);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-13 04:55:25 +00:00
|
|
|
return rtx;
|
|
|
|
}
|
2008-12-16 03:56:48 +00:00
|
|
|
|
2009-02-27 06:55:05 +00:00
|
|
|
void* qse_awk_rtx_getxtnstd (qse_awk_rtx_t* rtx)
|
|
|
|
{
|
|
|
|
return (void*)((rxtn_t*)QSE_XTN(rtx) + 1);
|
|
|
|
}
|
|
|
|
|
2008-12-16 03:56:48 +00:00
|
|
|
/*** EXTRA BUILTIN FUNCTIONS ***/
|
2008-12-17 03:42:48 +00:00
|
|
|
enum
|
|
|
|
{
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD,
|
|
|
|
FNC_MATH_D,
|
|
|
|
FNC_MATH_F
|
2008-12-17 03:42:48 +00:00
|
|
|
};
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
static int fnc_math_1 (
|
2009-07-16 04:43:31 +00:00
|
|
|
qse_awk_rtx_t* run, const qse_cstr_t* fnm,
|
2009-06-26 01:39:27 +00:00
|
|
|
int type, void* f)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t nargs;
|
|
|
|
qse_awk_val_t* a0;
|
|
|
|
qse_long_t lv;
|
|
|
|
qse_real_t rv;
|
|
|
|
qse_awk_val_t* r;
|
2008-12-17 03:42:48 +00:00
|
|
|
int n;
|
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
nargs = qse_awk_rtx_getnargs (run);
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (nargs == 1);
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
a0 = qse_awk_rtx_getarg (run, 0);
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
n = qse_awk_rtx_valtonum (run, a0, &lv, &rv);
|
2008-12-17 03:42:48 +00:00
|
|
|
if (n == -1) return -1;
|
2008-12-21 21:35:07 +00:00
|
|
|
if (n == 0) rv = (qse_real_t)lv;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-02-01 04:06:30 +00:00
|
|
|
if (type == FNC_MATH_LD)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
|
|
|
long double (*rf) (long double) =
|
|
|
|
(long double(*)(long double))f;
|
2009-02-01 03:59:46 +00:00
|
|
|
r = qse_awk_rtx_makerealval (run, rf(rv));
|
2008-12-17 03:42:48 +00:00
|
|
|
}
|
2009-02-01 04:06:30 +00:00
|
|
|
else if (type == FNC_MATH_D)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
|
|
|
double (*rf) (double) = (double(*)(double))f;
|
2009-02-01 03:59:46 +00:00
|
|
|
r = qse_awk_rtx_makerealval (run, rf(rv));
|
2008-12-17 03:42:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-06-19 06:08:06 +00:00
|
|
|
float (*rf) (float);
|
2009-02-01 04:06:30 +00:00
|
|
|
QSE_ASSERT (type == FNC_MATH_F);
|
2009-06-19 06:08:06 +00:00
|
|
|
rf = (float(*)(float))f;
|
2009-02-01 03:59:46 +00:00
|
|
|
r = qse_awk_rtx_makerealval (run, rf(rv));
|
2008-12-17 03:42:48 +00:00
|
|
|
}
|
|
|
|
|
2009-11-23 07:58:53 +00:00
|
|
|
if (r == QSE_NULL) return -1;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
qse_awk_rtx_setretval (run, r);
|
2008-12-17 03:42:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
static int fnc_math_2 (
|
2009-07-16 04:43:31 +00:00
|
|
|
qse_awk_rtx_t* run, const qse_cstr_t* fnm, int type, void* f)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t nargs;
|
|
|
|
qse_awk_val_t* a0, * a1;
|
|
|
|
qse_long_t lv0, lv1;
|
|
|
|
qse_real_t rv0, rv1;
|
|
|
|
qse_awk_val_t* r;
|
2008-12-17 03:42:48 +00:00
|
|
|
int n;
|
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
nargs = qse_awk_rtx_getnargs (run);
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (nargs == 2);
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
a0 = qse_awk_rtx_getarg (run, 0);
|
|
|
|
a1 = qse_awk_rtx_getarg (run, 1);
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
n = qse_awk_rtx_valtonum (run, a0, &lv0, &rv0);
|
2008-12-17 03:42:48 +00:00
|
|
|
if (n == -1) return -1;
|
2008-12-21 21:35:07 +00:00
|
|
|
if (n == 0) rv0 = (qse_real_t)lv0;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
n = qse_awk_rtx_valtonum (run, a1, &lv1, &rv1);
|
2008-12-17 03:42:48 +00:00
|
|
|
if (n == -1) return -1;
|
2008-12-21 21:35:07 +00:00
|
|
|
if (n == 0) rv1 = (qse_real_t)lv1;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-02-01 04:06:30 +00:00
|
|
|
if (type == FNC_MATH_LD)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
|
|
|
long double (*rf) (long double,long double) =
|
|
|
|
(long double(*)(long double,long double))f;
|
2009-02-01 03:59:46 +00:00
|
|
|
r = qse_awk_rtx_makerealval (run, rf(rv0,rv1));
|
2008-12-17 03:42:48 +00:00
|
|
|
}
|
2009-02-01 04:06:30 +00:00
|
|
|
else if (type == FNC_MATH_D)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
|
|
|
double (*rf) (double,double) = (double(*)(double,double))f;
|
2009-02-01 03:59:46 +00:00
|
|
|
r = qse_awk_rtx_makerealval (run, rf(rv0,rv1));
|
2008-12-17 03:42:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-06-19 06:08:06 +00:00
|
|
|
float (*rf) (float,float);
|
2009-02-01 04:06:30 +00:00
|
|
|
QSE_ASSERT (type == FNC_MATH_F);
|
2009-06-19 06:08:06 +00:00
|
|
|
rf = (float(*)(float,float))f;
|
2009-02-01 03:59:46 +00:00
|
|
|
r = qse_awk_rtx_makerealval (run, rf(rv0,rv1));
|
2008-12-17 03:42:48 +00:00
|
|
|
}
|
|
|
|
|
2009-11-23 07:58:53 +00:00
|
|
|
if (r == QSE_NULL) return -1;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
qse_awk_rtx_setretval (run, r);
|
2008-12-17 03:42:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_sin (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
return fnc_math_1 (
|
2009-07-16 04:43:31 +00:00
|
|
|
run, fnm,
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_SINL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD, (void*)sinl
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_SIN)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_D, (void*)sin
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_SINF)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_F, (void*)sinf
|
2008-12-17 03:42:48 +00:00
|
|
|
#else
|
|
|
|
#error ### no sin function available ###
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_cos (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
return fnc_math_1 (
|
2009-07-16 04:43:31 +00:00
|
|
|
run, fnm,
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_COSL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD, (void*)cosl
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_COS)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_D, (void*)cos
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_COSF)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_F, (void*)cosf
|
2008-12-17 03:42:48 +00:00
|
|
|
#else
|
|
|
|
#error ### no cos function available ###
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_tan (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
return fnc_math_1 (
|
2009-07-16 04:43:31 +00:00
|
|
|
run, fnm,
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_TANL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD, (void*)tanl
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_TAN)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_D, (void*)tan
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_TANF)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_F, (void*)tanf
|
2008-12-17 03:42:48 +00:00
|
|
|
#else
|
|
|
|
#error ### no tan function available ###
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_atan (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
return fnc_math_1 (
|
2009-07-16 04:43:31 +00:00
|
|
|
run, fnm,
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_ATANL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD, (void*)atanl
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_ATAN)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_D, (void*)atan
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_ATANF)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_F, (void*)atanf
|
2008-12-17 03:42:48 +00:00
|
|
|
#else
|
|
|
|
#error ### no atan function available ###
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_atan2 (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
return fnc_math_2 (
|
2009-07-16 04:43:31 +00:00
|
|
|
run, fnm,
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_ATAN2L) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD, (void*)atan2l
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_ATAN2)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_D, (void*)atan2
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_ATAN2F)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_F, (void*)atan2f
|
2008-12-17 03:42:48 +00:00
|
|
|
#else
|
|
|
|
#error ### no atan2 function available ###
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_log (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
return fnc_math_1 (
|
2009-07-16 04:43:31 +00:00
|
|
|
run, fnm,
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_LOGL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD, (void*)logl
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_LOG)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_D, (void*)log
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_LOGF)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_F, (void*)logf
|
2008-12-17 03:42:48 +00:00
|
|
|
#else
|
|
|
|
#error ### no log function available ###
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_exp (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
return fnc_math_1 (
|
2009-07-16 04:43:31 +00:00
|
|
|
run, fnm,
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_EXPL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD, (void*)expl
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_EXP)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_D, (void*)exp
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_EXPF)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_F, (void*)expf
|
2008-12-17 03:42:48 +00:00
|
|
|
#else
|
|
|
|
#error ### no exp function available ###
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_sqrt (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
return fnc_math_1 (
|
2009-07-16 04:43:31 +00:00
|
|
|
run, fnm,
|
2011-02-01 07:46:52 +00:00
|
|
|
#if defined(HAVE_SQRTL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_LD, (void*)sqrtl
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_SQRT)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_D, (void*)sqrt
|
2008-12-17 03:42:48 +00:00
|
|
|
#elif defined(HAVE_SQRTF)
|
2009-02-01 04:06:30 +00:00
|
|
|
FNC_MATH_F, (void*)sqrtf
|
2008-12-17 03:42:48 +00:00
|
|
|
#else
|
|
|
|
#error ### no sqrt function available ###
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_int (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-16 03:56:48 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t nargs;
|
|
|
|
qse_awk_val_t* a0;
|
|
|
|
qse_long_t lv;
|
|
|
|
qse_real_t rv;
|
|
|
|
qse_awk_val_t* r;
|
2008-12-16 03:56:48 +00:00
|
|
|
int n;
|
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
nargs = qse_awk_rtx_getnargs (run);
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (nargs == 1);
|
2008-12-16 03:56:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
a0 = qse_awk_rtx_getarg (run, 0);
|
2008-12-16 03:56:48 +00:00
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
n = qse_awk_rtx_valtonum (run, a0, &lv, &rv);
|
2008-12-16 03:56:48 +00:00
|
|
|
if (n == -1) return -1;
|
2008-12-21 21:35:07 +00:00
|
|
|
if (n == 1) lv = (qse_long_t)rv;
|
2008-12-16 03:56:48 +00:00
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
r = qse_awk_rtx_makeintval (run, lv);
|
2009-11-23 07:58:53 +00:00
|
|
|
if (r == QSE_NULL) return -1;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
qse_awk_rtx_setretval (run, r);
|
2008-12-17 03:42:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_rand (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_t* r;
|
2008-12-16 03:56:48 +00:00
|
|
|
|
2009-06-11 07:18:25 +00:00
|
|
|
/*
|
|
|
|
rxtn_t* rxtn;
|
|
|
|
rxtn = (rxtn_t*) QSE_XTN (run);
|
|
|
|
r = qse_awk_rtx_makerealval (
|
|
|
|
run, (qse_real_t)(rand_r(rxtn->seed) % RAND_MAX) / RAND_MAX );
|
|
|
|
*/
|
|
|
|
r = qse_awk_rtx_makerealval (
|
|
|
|
run, (qse_real_t)(rand() % RAND_MAX) / RAND_MAX);
|
2009-11-23 07:58:53 +00:00
|
|
|
if (r == QSE_NULL) return -1;
|
2008-12-16 03:56:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
qse_awk_rtx_setretval (run, r);
|
2008-12-16 03:56:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_srand (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t nargs;
|
|
|
|
qse_awk_val_t* a0;
|
|
|
|
qse_long_t lv;
|
|
|
|
qse_real_t rv;
|
|
|
|
qse_awk_val_t* r;
|
2008-12-17 03:42:48 +00:00
|
|
|
int n;
|
|
|
|
unsigned int prev;
|
|
|
|
rxtn_t* rxtn;
|
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
rxtn = (rxtn_t*) QSE_XTN (run);
|
2009-01-31 22:03:05 +00:00
|
|
|
nargs = qse_awk_rtx_getnargs (run);
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (nargs == 0 || nargs == 1);
|
2008-12-17 03:42:48 +00:00
|
|
|
|
|
|
|
prev = rxtn->seed;
|
|
|
|
|
|
|
|
if (nargs == 1)
|
|
|
|
{
|
2009-01-31 22:03:05 +00:00
|
|
|
a0 = qse_awk_rtx_getarg (run, 0);
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
n = qse_awk_rtx_valtonum (run, a0, &lv, &rv);
|
2009-07-17 06:43:47 +00:00
|
|
|
if (n <= -1) return -1;
|
|
|
|
if (n >= 1) lv = (qse_long_t)rv;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
|
|
|
rxtn->seed = lv;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_ntime_t now;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-07-17 06:43:47 +00:00
|
|
|
if (qse_gettime(&now) <= -1) rxtn->seed >>= 1;
|
2008-12-17 03:42:48 +00:00
|
|
|
else rxtn->seed = (unsigned int)now;
|
|
|
|
}
|
|
|
|
|
|
|
|
srand (rxtn->seed);
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
r = qse_awk_rtx_makeintval (run, prev);
|
2009-11-23 07:58:53 +00:00
|
|
|
if (r == QSE_NULL) return -1;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
qse_awk_rtx_setretval (run, r);
|
2008-12-17 03:42:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-16 04:43:31 +00:00
|
|
|
static int fnc_system (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2008-12-30 04:49:25 +00:00
|
|
|
qse_size_t nargs;
|
|
|
|
qse_awk_val_t* v;
|
|
|
|
qse_char_t* str, * ptr, * end;
|
|
|
|
qse_size_t len;
|
|
|
|
int n = 0;
|
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
nargs = qse_awk_rtx_getnargs (run);
|
2008-12-30 04:49:25 +00:00
|
|
|
QSE_ASSERT (nargs == 1);
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
v = qse_awk_rtx_getarg (run, 0);
|
2008-12-30 04:49:25 +00:00
|
|
|
if (v->type == QSE_AWK_VAL_STR)
|
|
|
|
{
|
|
|
|
str = ((qse_awk_val_str_t*)v)->ptr;
|
|
|
|
len = ((qse_awk_val_str_t*)v)->len;
|
|
|
|
}
|
2008-12-18 02:39:15 +00:00
|
|
|
else
|
2008-12-30 04:49:25 +00:00
|
|
|
{
|
2009-03-02 03:58:19 +00:00
|
|
|
str = qse_awk_rtx_valtocpldup (run, v, &len);
|
2008-12-30 04:49:25 +00:00
|
|
|
if (str == QSE_NULL) return -1;
|
|
|
|
}
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2008-12-30 04:49:25 +00:00
|
|
|
/* the target name contains a null character.
|
|
|
|
* make system return -1 */
|
|
|
|
ptr = str; end = str + len;
|
|
|
|
while (ptr < end)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2008-12-30 04:49:25 +00:00
|
|
|
if (*ptr == QSE_T('\0'))
|
|
|
|
{
|
|
|
|
n = -1;
|
|
|
|
goto skip_system;
|
|
|
|
}
|
|
|
|
|
|
|
|
ptr++;
|
2008-12-17 03:42:48 +00:00
|
|
|
}
|
|
|
|
|
2008-12-30 04:49:25 +00:00
|
|
|
#if defined(_WIN32)
|
|
|
|
n = _tsystem (str);
|
|
|
|
#elif defined(QSE_CHAR_IS_MCHAR)
|
|
|
|
n = system (str);
|
|
|
|
#else
|
|
|
|
{
|
|
|
|
char* mbs;
|
|
|
|
qse_size_t mbl;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2008-12-30 04:49:25 +00:00
|
|
|
mbs = (char*) qse_awk_alloc (run->awk, len*5+1);
|
|
|
|
if (mbs == QSE_NULL)
|
|
|
|
{
|
|
|
|
n = -1;
|
|
|
|
goto skip_system;
|
|
|
|
}
|
2008-12-22 08:31:30 +00:00
|
|
|
|
2008-12-30 04:49:25 +00:00
|
|
|
/* at this point, the string is guaranteed to be
|
|
|
|
* null-terminating. so qse_wcstombs() can be used to convert
|
|
|
|
* the string, not qse_wcsntombsn(). */
|
2008-12-22 08:31:30 +00:00
|
|
|
|
2008-12-30 04:49:25 +00:00
|
|
|
mbl = len * 5;
|
|
|
|
if (qse_wcstombs (str, mbs, &mbl) != len && mbl >= len * 5)
|
|
|
|
{
|
|
|
|
/* not the entire string is converted.
|
|
|
|
* mbs is not null-terminated properly. */
|
|
|
|
n = -1;
|
|
|
|
goto skip_system_mbs;
|
|
|
|
}
|
2008-12-23 04:12:59 +00:00
|
|
|
|
2008-12-30 04:49:25 +00:00
|
|
|
mbs[mbl] = '\0';
|
|
|
|
n = system (mbs);
|
2008-12-22 08:31:30 +00:00
|
|
|
|
2008-12-30 04:49:25 +00:00
|
|
|
skip_system_mbs:
|
|
|
|
qse_awk_free (run->awk, mbs);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
skip_system:
|
|
|
|
if (v->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, str);
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
v = qse_awk_rtx_makeintval (run, (qse_long_t)n);
|
2009-08-17 07:44:20 +00:00
|
|
|
if (v == QSE_NULL) return -1;
|
2008-12-30 04:49:25 +00:00
|
|
|
|
2009-01-31 22:03:05 +00:00
|
|
|
qse_awk_rtx_setretval (run, v);
|
2008-12-30 04:49:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-12-31 00:08:03 +00:00
|
|
|
|
2009-02-02 08:28:04 +00:00
|
|
|
#define ADDFNC(awk,name,min,max,fnc) \
|
2009-02-01 03:59:46 +00:00
|
|
|
if (qse_awk_addfnc (\
|
2008-12-21 21:35:07 +00:00
|
|
|
(awk), (name), qse_strlen(name), \
|
2009-02-01 03:59:46 +00:00
|
|
|
0, (min), (max), QSE_NULL, (fnc)) == QSE_NULL) return -1;
|
2008-12-17 03:42:48 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static int add_functions (qse_awk_t* awk)
|
2008-12-17 03:42:48 +00:00
|
|
|
{
|
2009-02-02 08:28:04 +00:00
|
|
|
ADDFNC (awk, QSE_T("sin"), 1, 1, fnc_sin);
|
|
|
|
ADDFNC (awk, QSE_T("cos"), 1, 1, fnc_cos);
|
|
|
|
ADDFNC (awk, QSE_T("tan"), 1, 1, fnc_tan);
|
|
|
|
ADDFNC (awk, QSE_T("atan"), 1, 1, fnc_atan);
|
|
|
|
ADDFNC (awk, QSE_T("atan2"), 2, 2, fnc_atan2);
|
|
|
|
ADDFNC (awk, QSE_T("log"), 1, 1, fnc_log);
|
|
|
|
ADDFNC (awk, QSE_T("exp"), 1, 1, fnc_exp);
|
|
|
|
ADDFNC (awk, QSE_T("sqrt"), 1, 1, fnc_sqrt);
|
|
|
|
ADDFNC (awk, QSE_T("int"), 1, 1, fnc_int);
|
|
|
|
ADDFNC (awk, QSE_T("rand"), 0, 0, fnc_rand);
|
|
|
|
ADDFNC (awk, QSE_T("srand"), 0, 1, fnc_srand);
|
|
|
|
ADDFNC (awk, QSE_T("system"), 1, 1, fnc_system);
|
2008-12-17 03:42:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|