qse/ase/com/Awk.cpp

517 lines
10 KiB
C++
Raw Normal View History

2006-12-09 11:50:08 +00:00
/*
2006-12-11 06:29:19 +00:00
* $Id: Awk.cpp,v 1.5 2006-12-11 06:29:18 bacon Exp $
2006-12-09 11:50:08 +00:00
*/
#include "stdafx.h"
#include "ase.h"
#include "Awk.h"
2006-12-09 17:36:27 +00:00
#include "AwkExtio.h"
2006-12-09 11:50:08 +00:00
#include "Buffer.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <wctype.h>
#include <stdio.h>
STDMETHODIMP CAwk::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IAwk,
};
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
if (/*Inline*/IsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
CAwk::CAwk (): handle(NULL),
2006-12-11 06:29:19 +00:00
read_src_buf(NULL), write_src_buf(NULL),
2006-12-09 17:36:27 +00:00
write_extio_buf(NULL)
2006-12-09 11:50:08 +00:00
{
#ifdef _DEBUG
TCHAR x[128];
_sntprintf (x, 128, _T("CAwk::CAwk %p"), this);
MessageBox (NULL, x, x, MB_OK);
#endif
}
CAwk::~CAwk ()
{
#ifdef _DEBUG
TCHAR x[128];
_sntprintf (x, 128, _T("CAwk::~CAwk %p"), this);
MessageBox (NULL, x, x, MB_OK);
#endif
2006-12-09 17:36:27 +00:00
if (write_extio_buf != NULL)
{
write_extio_buf->Release ();
}
2006-12-11 06:29:19 +00:00
if (write_src_buf != NULL)
2006-12-09 11:50:08 +00:00
{
2006-12-11 06:29:19 +00:00
write_src_buf->Release ();
2006-12-09 11:50:08 +00:00
}
2006-12-11 06:29:19 +00:00
if (read_src_buf != NULL)
2006-12-09 11:50:08 +00:00
{
2006-12-11 06:29:19 +00:00
read_src_buf->Release ();
2006-12-09 11:50:08 +00:00
}
if (handle != NULL)
{
ase_awk_close (handle);
handle = NULL;
}
}
static void* __awk_malloc (ase_size_t n, void* custom_data)
{
return malloc (n);
}
static void* __awk_realloc (void* ptr, ase_size_t n, void* custom_data)
{
return realloc (ptr, n);
}
static void __awk_free (void* ptr, void* custom_data)
{
free (ptr);
}
static ase_real_t __awk_pow (ase_real_t x, ase_real_t y)
{
return pow (x, y);
}
static int __awk_sprintf (
ase_char_t* buf, ase_size_t len, const ase_char_t* fmt, ...)
{
int n;
va_list ap;
va_start (ap, fmt);
#if defined(_WIN32)
n = _vsntprintf (buf, len, fmt, ap);
if (n < 0 || (ase_size_t)n >= len)
{
if (len > 0) buf[len-1] = ASE_T('\0');
n = -1;
}
#elif defined(__MSDOS__)
/* TODO: check buffer overflow */
n = vsprintf (buf, fmt, ap);
#else
n = xp_vsprintf (buf, len, fmt, ap);
#endif
va_end (ap);
return n;
}
static void __awk_aprintf (const ase_char_t* fmt, ...)
{
va_list ap;
#ifdef _WIN32
int n;
ase_char_t buf[1024];
#endif
va_start (ap, fmt);
#if defined(_WIN32)
n = _vsntprintf (buf, ASE_COUNTOF(buf), fmt, ap);
if (n < 0) buf[ASE_COUNTOF(buf)-1] = ASE_T('\0');
#if defined(_MSC_VER) && (_MSC_VER<1400)
MessageBox (NULL, buf,
ASE_T("Assertion Failure"), MB_OK|MB_ICONERROR);
#else
MessageBox (NULL, buf,
ASE_T("\uB2DD\uAE30\uB9AC \uC870\uB610"), MB_OK|MB_ICONERROR);
#endif
#elif defined(__MSDOS__)
vprintf (fmt, ap);
#else
xp_vprintf (fmt, ap);
#endif
va_end (ap);
}
static void __awk_dprintf (const ase_char_t* fmt, ...)
{
va_list ap;
va_start (ap, fmt);
#if defined(_WIN32)
_vftprintf (stderr, fmt, ap);
#elif defined(__MSDOS__)
vfprintf (stderr, fmt, ap);
#else
xp_vfprintf (stderr, fmt, ap);
#endif
va_end (ap);
}
static ase_ssize_t __read_source (
int cmd, void* arg, ase_char_t* data, ase_size_t count)
{
CAwk* awk = (CAwk*)arg;
if (cmd == ASE_AWK_IO_OPEN)
{
return (ase_ssize_t)awk->Fire_OpenSource (0);
}
else if (cmd == ASE_AWK_IO_CLOSE)
{
return (ase_ssize_t)awk->Fire_CloseSource (0);
}
else if (cmd == ASE_AWK_IO_READ)
{
2006-12-11 06:29:19 +00:00
if (awk->read_src_buf == NULL)
2006-12-09 11:50:08 +00:00
{
2006-12-10 05:59:52 +00:00
HRESULT hr = CoCreateInstance (
2006-12-09 11:50:08 +00:00
CLSID_Buffer, NULL, CLSCTX_ALL,
2006-12-11 06:29:19 +00:00
IID_IBuffer, (void**)&awk->read_src_buf);
2006-12-09 11:50:08 +00:00
if (FAILED(hr))
{
MessageBox (NULL, _T("COCREATEINSTANCE FAILED"), _T("FUCK"), MB_OK);
return -1;
}
2006-12-11 06:29:19 +00:00
awk->read_src_pos = 0;
awk->read_src_len = 0;
2006-12-09 11:50:08 +00:00
}
2006-12-11 06:29:19 +00:00
CBuffer* tmp = (CBuffer*)awk->read_src_buf;
2006-12-10 05:59:52 +00:00
2006-12-11 06:29:19 +00:00
if (awk->read_src_pos >= awk->read_src_len)
2006-12-09 11:50:08 +00:00
{
2006-12-11 06:29:19 +00:00
INT n = awk->Fire_ReadSource (awk->read_src_buf);
2006-12-09 11:50:08 +00:00
if (n <= 0) return (ase_ssize_t)n;
2006-12-10 16:13:50 +00:00
if (SysStringLen(tmp->str) < (UINT)n) return -1;
2006-12-11 06:29:19 +00:00
awk->read_src_pos = 0;
awk->read_src_len = n;
2006-12-09 11:50:08 +00:00
}
2006-12-10 05:59:52 +00:00
2006-12-09 11:50:08 +00:00
ASE_AWK_ASSERT (awk->handle,
2006-12-11 06:29:19 +00:00
awk->read_src_pos < awk->read_src_len);
2006-12-09 11:50:08 +00:00
2006-12-10 16:13:50 +00:00
BSTR str = tmp->str;
2006-12-11 06:29:19 +00:00
INT left = awk->read_src_len - awk->read_src_pos;
2006-12-09 11:50:08 +00:00
if (left > (ase_ssize_t)count)
{
memcpy (data,
2006-12-11 06:29:19 +00:00
((TCHAR*)str)+awk->read_src_pos,
2006-12-09 11:50:08 +00:00
count * ASE_SIZEOF(ase_char_t));
2006-12-11 06:29:19 +00:00
awk->read_src_pos += count;
2006-12-09 11:50:08 +00:00
return count;
}
else
{
memcpy (data,
2006-12-11 06:29:19 +00:00
((TCHAR*)str)+awk->read_src_pos,
2006-12-09 11:50:08 +00:00
left * ASE_SIZEOF(ase_char_t));
2006-12-11 06:29:19 +00:00
awk->read_src_pos = 0;
awk->read_src_len = 0;
2006-12-09 11:50:08 +00:00
return (ase_ssize_t)left;
}
}
return -1;
}
static ase_ssize_t __write_source (
int cmd, void* arg, ase_char_t* data, ase_size_t count)
{
CAwk* awk = (CAwk*)arg;
if (cmd == ASE_AWK_IO_OPEN)
{
return (ase_ssize_t)awk->Fire_OpenSource (1);
}
else if (cmd == ASE_AWK_IO_CLOSE)
{
return (ase_ssize_t)awk->Fire_CloseSource (1);
}
else if (cmd == ASE_AWK_IO_WRITE)
{
HRESULT hr;
2006-12-11 06:29:19 +00:00
if (awk->write_src_buf == NULL)
2006-12-09 11:50:08 +00:00
{
hr = CoCreateInstance (
CLSID_Buffer, NULL, CLSCTX_ALL,
2006-12-11 06:29:19 +00:00
IID_IBuffer, (void**)&awk->write_src_buf);
2006-12-09 11:50:08 +00:00
if (FAILED(hr))
{
MessageBox (NULL, _T("COCREATEINSTANCE FAILED"), _T("FUCK"), MB_OK);
return -1;
}
}
2006-12-11 06:29:19 +00:00
CBuffer* tmp = (CBuffer*)awk->write_src_buf;
2006-12-10 16:13:50 +00:00
if (tmp->PutValue (data, count) == FALSE) return -1; /* TODO: better error handling */
2006-12-10 05:59:52 +00:00
2006-12-11 06:29:19 +00:00
INT n = awk->Fire_WriteSource (awk->write_src_buf);
2006-12-09 17:36:27 +00:00
if (n > (INT)count) return -1;
2006-12-09 11:50:08 +00:00
return (ase_ssize_t)n;
}
return -1;
}
HRESULT CAwk::Parse (int* ret)
{
if (handle == NULL)
{
ase_awk_syscas_t syscas;
memset (&syscas, 0, sizeof(syscas));
syscas.malloc = __awk_malloc;
syscas.realloc = __awk_realloc;
syscas.free = __awk_free;
syscas.is_upper = iswupper;
syscas.is_lower = iswlower;
syscas.is_alpha = iswalpha;
syscas.is_digit = iswdigit;
syscas.is_xdigit = iswxdigit;
syscas.is_alnum = iswalnum;
syscas.is_space = iswspace;
syscas.is_print = iswprint;
syscas.is_graph = iswgraph;
syscas.is_cntrl = iswcntrl;
syscas.is_punct = iswpunct;
syscas.to_upper = towupper;
syscas.to_lower = towlower;
syscas.memcpy = memcpy;
syscas.memset = memset;
syscas.pow = __awk_pow;
syscas.sprintf = __awk_sprintf;
syscas.aprintf = __awk_aprintf;
syscas.dprintf = __awk_dprintf;
syscas.abort = abort;
handle = ase_awk_open (&syscas);
if (handle == NULL)
{
*ret = -1;
return S_OK;
}
int opt = /*ASE_AWK_IMPLICIT |
ASE_AWK_EXPLICIT |
ASE_AWK_UNIQUEAFN |
ASE_AWK_HASHSIGN |
ASE_AWK_IDIV |
ASE_AWK_SHADING |
ASE_AWK_SHIFT | */
ASE_AWK_EXTIO /*|
ASE_AWK_BLOCKLESS |
ASE_AWK_STRINDEXONE |
ASE_AWK_STRIPSPACES |
ASE_AWK_NEXTOFILE*/;
ase_awk_setopt (handle, opt);
}
ase_awk_srcios_t srcios;
srcios.in = __read_source;
srcios.out = __write_source;
srcios.custom_data = this;
if (ase_awk_parse (handle, &srcios) == -1)
{
*ret = -1;
return S_OK;
}
*ret = 0;
return S_OK;
}
static ase_ssize_t __process_extio (
int cmd, void* arg, ase_char_t* data, ase_size_t size)
{
ase_awk_extio_t* epa = (ase_awk_extio_t*)arg;
CAwk* awk = (CAwk*)epa->custom_data;
if (cmd == ASE_AWK_IO_OPEN)
{
2006-12-09 17:36:27 +00:00
IAwkExtio* extio;
CAwkExtio* extio2;
2006-12-11 06:29:19 +00:00
IBuffer* read_buf;
2006-12-09 17:36:27 +00:00
HRESULT hr = CoCreateInstance (
CLSID_AwkExtio, NULL, CLSCTX_ALL,
IID_IAwkExtio, (void**)&extio);
if (FAILED(hr)) return -1; /* TODO: better error handling.. */
2006-12-11 06:29:19 +00:00
hr = CoCreateInstance (
CLSID_Buffer, NULL, CLSCTX_ALL,
IID_IBuffer, (void**)&read_buf);
if (FAILED(hr))
{
extio->Release ();
return -1;
}
2006-12-10 16:13:50 +00:00
extio2 = (CAwkExtio*)extio;
if (extio2->PutName (epa->name) == FALSE)
2006-12-10 05:59:52 +00:00
{
2006-12-11 06:29:19 +00:00
read_buf->Release ();
2006-12-10 05:59:52 +00:00
extio->Release ();
return -1; /* TODO: better error handling */
}
2006-12-09 17:36:27 +00:00
extio2->type = epa->type & 0xFF;
extio2->mode = epa->mode;
2006-12-11 06:29:19 +00:00
read_buf->AddRef ();
extio2->read_buf = read_buf;
extio2->read_buf_pos = 0;
extio2->read_buf_len = 0;
2006-12-09 17:36:27 +00:00
INT n = awk->Fire_OpenExtio (extio);
if (n >= 0)
{
extio->AddRef ();
epa->handle = extio;
}
2006-12-11 06:29:19 +00:00
read_buf->Release ();
2006-12-09 17:36:27 +00:00
extio->Release ();
return n;
2006-12-09 11:50:08 +00:00
}
else if (cmd == ASE_AWK_IO_CLOSE)
{
2006-12-11 06:29:19 +00:00
IAwkExtio* extio;
CAwkExtio* extio2;
extio = (IAwkExtio*)epa->handle;
extio2 = (CAwkExtio*)extio;
2006-12-09 17:36:27 +00:00
ASE_AWK_ASSERT (ase_awk_getrunawk(epa->run), extio != NULL);
INT n = awk->Fire_CloseExtio (extio);
if (n >= 0)
{
2006-12-11 06:29:19 +00:00
extio2->read_buf->Release();
2006-12-09 17:36:27 +00:00
extio->Release();
epa->handle = NULL;
}
2006-12-11 06:29:19 +00:00
2006-12-09 17:36:27 +00:00
return n;
2006-12-09 11:50:08 +00:00
}
else if (cmd == ASE_AWK_IO_READ)
{
2006-12-11 06:29:19 +00:00
IAwkExtio* extio;
CAwkExtio* extio2;
extio = (IAwkExtio*)epa->handle;
extio2 = (CAwkExtio*)extio;
2006-12-09 17:36:27 +00:00
ASE_AWK_ASSERT (ase_awk_getrunawk(epa->run), extio != NULL);
2006-12-11 06:29:19 +00:00
CBuffer* tmp = (CBuffer*)extio2->read_buf;
if (extio2->read_buf_pos >= extio2->read_buf_len)
2006-12-09 17:36:27 +00:00
{
2006-12-11 06:29:19 +00:00
INT n = awk->Fire_ReadSource (extio2->read_buf);
if (n <= 0) return (ase_ssize_t)n;
if (SysStringLen(tmp->str) < (UINT)n) return -1;
extio2->read_buf_pos = 0;
extio2->read_buf_len = n;
2006-12-09 17:36:27 +00:00
}
2006-12-11 06:29:19 +00:00
ASE_AWK_ASSERT (awk->handle,
extio2->read_buf_pos < extio2->read_buf_len);
BSTR str = tmp->str;
INT left = extio2->read_buf_len - extio2->read_buf_pos;
if (left > (ase_ssize_t)size)
{
memcpy (data,
((TCHAR*)str)+extio2->read_buf_pos,
size * ASE_SIZEOF(ase_char_t));
extio2->read_buf_pos += size;
return size;
}
else
{
memcpy (data,
((TCHAR*)str)+extio2->read_buf_pos,
left * ASE_SIZEOF(ase_char_t));
extio2->read_buf_pos = 0;
extio2->read_buf_len = 0;
return (ase_ssize_t)left;
}
2006-12-09 11:50:08 +00:00
}
else if (cmd == ASE_AWK_IO_WRITE)
{
2006-12-10 05:59:52 +00:00
HRESULT hr;
2006-12-09 17:36:27 +00:00
IAwkExtio* extio = (IAwkExtio*)epa->handle;
ASE_AWK_ASSERT (ase_awk_getrunawk(epa->run), extio != NULL);
if (awk->write_extio_buf == NULL)
{
2006-12-10 05:59:52 +00:00
hr = CoCreateInstance (
2006-12-09 17:36:27 +00:00
CLSID_Buffer, NULL, CLSCTX_ALL,
IID_IBuffer, (void**)&awk->write_extio_buf);
if (FAILED(hr)) return -1;
}
2006-12-10 16:13:50 +00:00
CBuffer* tmp = (CBuffer*)awk->write_extio_buf;
if (tmp->PutValue (data, size) == FALSE) return -1; /* TODO: better error handling */
2006-12-10 05:59:52 +00:00
2006-12-09 17:36:27 +00:00
INT n = awk->Fire_WriteExtio (extio, awk->write_extio_buf);
if (n > (INT)size) return -1;
return (ase_ssize_t)n;
2006-12-09 11:50:08 +00:00
}
else if (cmd == ASE_AWK_IO_FLUSH)
{
2006-12-09 17:36:27 +00:00
return 1;
2006-12-09 11:50:08 +00:00
}
else if (cmd == ASE_AWK_IO_NEXT)
{
}
return -1;
}
HRESULT CAwk::Run (int* ret)
{
if (handle == NULL)
{
/* TODO: better error handling... */
/* call parse first... */
*ret = -1;
return S_OK;
}
ase_awk_runios_t runios;
2006-12-09 17:36:27 +00:00
runios.pipe = NULL;
2006-12-09 11:50:08 +00:00
runios.coproc = NULL;
runios.file = NULL;
2006-12-09 17:36:27 +00:00
runios.console = __process_extio;
2006-12-09 11:50:08 +00:00
runios.custom_data = this;
if (ase_awk_run (handle, NULL, &runios, NULL, NULL, this) == -1)
{
2006-12-09 17:36:27 +00:00
int err = ase_awk_geterrnum (handle);
MessageBox (NULL, ase_awk_geterrstr(err), ase_awk_geterrstr(err), MB_OK);
2006-12-09 11:50:08 +00:00
*ret = -1;
return S_OK;
}
*ret = 0;
return S_OK;
}