2008-05-25 07:05:11 +00:00
|
|
|
/*
|
|
|
|
* $Id$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ase/tgp/tgp.h>
|
2008-08-21 03:58:42 +00:00
|
|
|
#include "../cmn/mem.h"
|
2008-05-25 07:05:11 +00:00
|
|
|
|
|
|
|
struct ase_tgp_t
|
|
|
|
{
|
2008-06-27 04:46:39 +00:00
|
|
|
ase_mmgr_t mmgr;
|
2008-06-30 07:41:11 +00:00
|
|
|
void* assoc_data;
|
2008-05-25 07:07:30 +00:00
|
|
|
int errnum;
|
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
ase_tgp_io_t func;
|
|
|
|
void* arg;
|
|
|
|
} ih;
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
ase_tgp_io_t func;
|
|
|
|
void* arg;
|
|
|
|
} oh;
|
2008-06-30 07:41:11 +00:00
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
ase_tgp_io_t func;
|
|
|
|
void* arg;
|
|
|
|
} rh;
|
2008-06-30 07:41:11 +00:00
|
|
|
|
2008-06-27 04:46:39 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
ase_size_t pos;
|
|
|
|
ase_size_t len;
|
|
|
|
ase_char_t ptr[512];
|
|
|
|
} ib;
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
ase_size_t len;
|
|
|
|
ase_char_t ptr[512];
|
|
|
|
} ob;
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
ase_size_t len;
|
|
|
|
ase_char_t ptr[512];
|
|
|
|
} rb;
|
|
|
|
|
|
|
|
int (*read) (ase_tgp_t* tgp, ase_char_t* buf, int len);
|
|
|
|
int (*write) (ase_tgp_t* tgp, const ase_char_t* buf, int len);
|
|
|
|
int (*run) (ase_tgp_t* tgp, const ase_char_t* buf, int len);
|
2008-05-25 07:05:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
ase_tgp_t* ase_tgp_open (ase_mmgr_t* mmgr)
|
|
|
|
{
|
|
|
|
ase_tgp_t* tgp;
|
|
|
|
|
2008-06-27 04:46:39 +00:00
|
|
|
/*
|
|
|
|
if (mmgr == ASE_NULL) mmgr = ASE_GETMMGR();
|
|
|
|
if (mmgr == ASE_NULL)
|
|
|
|
{
|
|
|
|
ASE_ASSERTX (mmgr != ASE_NULL,
|
|
|
|
"Provide the memory manager or set the global memory manager with ASE_SETMMGR()");
|
|
|
|
return ASE_NULL;
|
|
|
|
}
|
|
|
|
*/
|
2008-05-25 07:05:11 +00:00
|
|
|
|
2008-08-21 03:58:42 +00:00
|
|
|
tgp = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(*tgp));
|
2008-05-25 07:05:11 +00:00
|
|
|
if (tgp == ASE_NULL) return ASE_NULL;
|
|
|
|
|
2008-08-21 03:58:42 +00:00
|
|
|
ASE_MEMSET (tgp, 0, ASE_SIZEOF(*tgp));
|
|
|
|
ASE_MEMCPY (&tgp->mmgr, mmgr, ASE_SIZEOF(*mmgr));
|
2008-05-25 07:05:11 +00:00
|
|
|
|
|
|
|
return tgp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ase_tgp_close (ase_tgp_t* tgp)
|
|
|
|
{
|
2008-08-21 03:58:42 +00:00
|
|
|
ASE_MMGR_FREE (&tgp->mmgr, tgp);
|
2008-05-25 07:05:11 +00:00
|
|
|
}
|
|
|
|
|
2008-06-30 07:41:11 +00:00
|
|
|
void ase_tgp_setassocdata (ase_tgp_t* tgp, void* data)
|
|
|
|
{
|
|
|
|
tgp->assoc_data = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* ase_tgp_getassocdata (ase_tgp_t* tgp)
|
|
|
|
{
|
|
|
|
return tgp->assoc_data;
|
|
|
|
}
|
|
|
|
|
2008-05-25 07:07:30 +00:00
|
|
|
int ase_tgp_geterrnum (ase_tgp_t* tgp)
|
|
|
|
{
|
|
|
|
return tgp->errnum;
|
|
|
|
}
|
|
|
|
|
2008-06-27 04:46:39 +00:00
|
|
|
static int getc (ase_tgp_t* tgp, ase_char_t* c)
|
2008-05-25 07:07:30 +00:00
|
|
|
{
|
2008-06-27 04:46:39 +00:00
|
|
|
if (tgp->ib.pos >= tgp->ib.len)
|
|
|
|
{
|
|
|
|
ase_ssize_t n;
|
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
n = tgp->ih.func (ASE_TGP_IO_READ, tgp->ih.arg, tgp->ib.ptr, ASE_COUNTOF(tgp->ib.ptr));
|
2008-06-27 04:46:39 +00:00
|
|
|
if (n < 0) return -1;
|
|
|
|
else if (n == 0)
|
|
|
|
{
|
|
|
|
*c = ASE_CHAR_EOF;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tgp->ib.pos = 0;
|
|
|
|
tgp->ib.len = n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*c = tgp->ib.ptr[tgp->ib.pos++];
|
|
|
|
return 1;
|
2008-05-25 07:07:30 +00:00
|
|
|
}
|
2008-06-04 02:14:05 +00:00
|
|
|
|
2008-06-27 04:46:39 +00:00
|
|
|
static int putc (ase_tgp_t* tgp, ase_char_t c)
|
2008-06-04 02:14:05 +00:00
|
|
|
{
|
2008-06-27 04:46:39 +00:00
|
|
|
if (tgp->ob.len >= ASE_COUNTOF(tgp->ob.ptr))
|
|
|
|
{
|
|
|
|
ase_ssize_t n;
|
2008-06-04 02:14:05 +00:00
|
|
|
|
2008-06-30 07:41:11 +00:00
|
|
|
/* TODO: submit on a newline as well */
|
2008-07-06 01:25:54 +00:00
|
|
|
n = tgp->oh.func (ASE_TGP_IO_WRITE, tgp->oh.arg, tgp->ob.ptr, ASE_COUNTOF(tgp->ob.ptr));
|
2008-06-27 04:46:39 +00:00
|
|
|
if (n < 0) return -1;
|
|
|
|
else if (n == 0) return 0;
|
|
|
|
}
|
2008-06-04 02:14:05 +00:00
|
|
|
|
2008-06-27 04:46:39 +00:00
|
|
|
tgp->ob.ptr[tgp->ob.len++] = c;
|
|
|
|
return 1;
|
2008-06-04 02:14:05 +00:00
|
|
|
}
|
|
|
|
|
2008-06-27 04:46:39 +00:00
|
|
|
static int runc (ase_tgp_t* tgp, ase_char_t c)
|
|
|
|
{
|
|
|
|
if (tgp->rb.len >= ASE_COUNTOF(tgp->rb.ptr))
|
|
|
|
{
|
|
|
|
ase_ssize_t n;
|
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
n = tgp->rh.func (ASE_TGP_IO_WRITE, tgp->rh.arg, tgp->rb.ptr, tgp->rb.len);
|
2008-06-27 04:46:39 +00:00
|
|
|
if (n < 0) return -1;
|
|
|
|
else if (n == 0) return 0;
|
2008-06-30 07:41:11 +00:00
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
tgp->rh.func (ASE_TGP_IO_READ, tgp->rh.arg, tgp->rb.ptr, tgp->rb.len);
|
2008-06-27 04:46:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tgp->rb.ptr[tgp->rb.len++] = c;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ase_tgp_run (ase_tgp_t* tgp)
|
|
|
|
{
|
|
|
|
ase_bool_t in_tag = ASE_FALSE;
|
|
|
|
ase_char_t c;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
tgp->ib.pos = 0;
|
|
|
|
tgp->ib.len = 0;
|
|
|
|
tgp->ob.len = 0;
|
|
|
|
tgp->rb.len = 0;
|
|
|
|
|
2008-06-30 07:41:11 +00:00
|
|
|
n = tgp->ih.func (ASE_TGP_IO_OPEN, tgp->ih.arg, ASE_NULL, 0);
|
|
|
|
if (n == -1)
|
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
/* reached end of input upon opening the file... */
|
|
|
|
tgp->ih.func (ASE_TGP_IO_CLOSE, tgp->ih.arg, ASE_NULL, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
n = tgp->oh.func (ASE_TGP_IO_OPEN, tgp->oh.arg, ASE_NULL, 0);
|
|
|
|
if (n == -1)
|
|
|
|
{
|
|
|
|
tgp->ih.func (ASE_TGP_IO_CLOSE, tgp->ih.arg, ASE_NULL, 0);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
/* reached end of input upon opening the file... */
|
|
|
|
tgp->oh.func (ASE_TGP_IO_CLOSE, tgp->oh.arg, ASE_NULL, 0);
|
|
|
|
tgp->ih.func (ASE_TGP_IO_CLOSE, tgp->ih.arg, ASE_NULL, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-06-27 04:46:39 +00:00
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
n = getc (tgp, &c);
|
|
|
|
if (n == -1) return -1;
|
|
|
|
if (n == 0) break;
|
|
|
|
|
|
|
|
if (c == ASE_T('<'))
|
|
|
|
{
|
|
|
|
n = getc (tgp, &c);
|
|
|
|
if (n == -1) return -1;
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
putc (tgp, ASE_T('<'));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == ASE_T('?'))
|
|
|
|
{
|
|
|
|
if (in_tag)
|
|
|
|
{
|
|
|
|
/* ERROR - netsted tag */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else in_tag = ASE_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (putc (tgp, ASE_T('<')) <= 0) return -1;
|
|
|
|
if (putc (tgp, c) <= 0) return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (c == ASE_T('?'))
|
|
|
|
{
|
|
|
|
n = getc (tgp, &c);
|
|
|
|
if (n == -1) return -1;
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
if (putc (tgp, ASE_T('<')) <= 0) return -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == ASE_T('>'))
|
|
|
|
{
|
|
|
|
if (in_tag) in_tag = ASE_FALSE;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* ERROR - unpaired tag close */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (putc (tgp, ASE_T('?')) <= 0) return -1;
|
|
|
|
if (putc (tgp, c) <= 0) return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (in_tag)
|
|
|
|
{
|
|
|
|
runc (tgp, c);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (putc (tgp, c) <= 0) return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-30 07:41:11 +00:00
|
|
|
tgp->oh.func (ASE_TGP_IO_CLOSE, tgp->oh.arg, ASE_NULL, 0);
|
|
|
|
tgp->ih.func (ASE_TGP_IO_CLOSE, tgp->ih.arg, ASE_NULL, 0);
|
2008-06-27 04:46:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-06-30 07:41:11 +00:00
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
void ase_tgp_attachin (ase_tgp_t* tgp, ase_tgp_io_t io, void* arg)
|
2008-06-30 07:41:11 +00:00
|
|
|
{
|
2008-07-06 01:25:54 +00:00
|
|
|
tgp->ih.func = io;
|
|
|
|
tgp->ih.arg = arg;
|
2008-06-30 07:41:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ase_tgp_detachin (ase_tgp_t* tgp)
|
|
|
|
{
|
2008-07-06 01:25:54 +00:00
|
|
|
tgp->ih.func = ASE_NULL;
|
|
|
|
tgp->ih.arg = ASE_NULL;
|
2008-06-30 07:41:11 +00:00
|
|
|
}
|
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
void ase_tgp_attachout (ase_tgp_t* tgp, ase_tgp_io_t io, void* arg)
|
2008-06-30 07:41:11 +00:00
|
|
|
{
|
2008-07-06 01:25:54 +00:00
|
|
|
tgp->oh.func = io;
|
|
|
|
tgp->oh.arg = arg;
|
2008-06-30 07:41:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ase_tgp_detachout (ase_tgp_t* tgp)
|
|
|
|
{
|
2008-07-06 01:25:54 +00:00
|
|
|
tgp->oh.func = ASE_NULL;
|
|
|
|
tgp->oh.arg = ASE_NULL;
|
2008-06-30 07:41:11 +00:00
|
|
|
}
|
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
void ase_tgp_attachexec (ase_tgp_t* tgp, ase_tgp_io_t io, void* arg)
|
2008-06-30 07:41:11 +00:00
|
|
|
{
|
2008-07-06 01:25:54 +00:00
|
|
|
tgp->rh.func = io;
|
|
|
|
tgp->rh.arg = arg;
|
2008-06-30 07:41:11 +00:00
|
|
|
}
|
|
|
|
|
2008-07-06 01:25:54 +00:00
|
|
|
void ase_tgp_detachexec (ase_tgp_t* tgp)
|
2008-06-30 07:41:11 +00:00
|
|
|
{
|
2008-07-06 01:25:54 +00:00
|
|
|
tgp->rh.func = ASE_NULL;
|
|
|
|
tgp->rh.arg = ASE_NULL;
|
2008-06-30 07:41:11 +00:00
|
|
|
}
|