fis-gtm/sr_port/m_write.c

148 lines
3.3 KiB
C

/****************************************************************
* *
* Copyright 2001, 2011 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "compiler.h"
#include "stringpool.h"
#include "opcode.h"
#include "indir_enum.h"
#include "toktyp.h"
#include "advancewindow.h"
#include "cmd.h"
#include "rwformat.h"
GBLREF spdesc stringpool;
GBLREF bool devctlexp;
error_def(ERR_STRINGOFLOW);
#define STO_LLPTR(X) (llptr ? *++llptr = (X) : 0)
#define LITLST_TOP (&litlst[(SIZEOF(litlst) / SIZEOF(triple *)) - 2])
int m_write(void)
{
char *cp;
int lnx;
mval lit;
mstr *msp;
oprtype *oprptr, x;
triple *litlst[128], **llptr, **ltop, **ptx, *ref, *t1;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
llptr = litlst;
ltop = 0;
*llptr = 0;
for (;;)
{
devctlexp = FALSE;
switch (TREF(window_token))
{
case TK_ASTERISK:
advancewindow();
if (EXPR_FAIL == expr(&x, MUMPS_INT))
return FALSE;
assert(TRIP_REF == x.oprclass);
ref = newtriple(OC_WTONE);
ref->operand[0] = x;
STO_LLPTR((OC_ILIT == x.oprval.tref->opcode) ? ref : 0);
break;
case TK_QUESTION:
case TK_EXCLAIMATION:
case TK_HASH:
case TK_SLASH:
if (!rwformat())
return FALSE;
STO_LLPTR(0);
break;
default:
switch (expr(&x, MUMPS_STR))
{
case EXPR_FAIL:
return FALSE;
case EXPR_GOOD:
assert(TRIP_REF == x.oprclass);
if (devctlexp)
{
ref = newtriple(OC_WRITE);
ref->operand[0] = x;
STO_LLPTR(0);
} else if (x.oprval.tref->opcode == OC_CAT)
wrtcatopt(x.oprval.tref, &llptr, LITLST_TOP);
else
{
ref = newtriple(OC_WRITE);
ref->operand[0] = x;
STO_LLPTR((OC_LIT == x.oprval.tref->opcode) ? ref : 0);
}
break;
case EXPR_INDR:
make_commarg(&x, indir_write);
STO_LLPTR(0);
break;
default:
assert(FALSE);
}
break;
}
if (TK_COMMA != TREF(window_token))
break;
advancewindow();
if (LITLST_TOP <= llptr)
{
*++llptr = 0;
ltop = llptr;
llptr = 0;
}
}
STO_LLPTR(0);
if (ltop)
llptr = ltop;
for (ptx = litlst ; ptx < llptr ; ptx++)
{
if (*ptx && *(ptx + 1))
{
lit.mvtype = MV_STR;
lit.str.addr = cp = (char *)stringpool.free;
for (t1 = ref = *ptx++ ; ref ; ref = *ptx++)
{
if (OC_WRITE == ref->opcode)
{
msp = &(ref->operand[0].oprval.tref->operand[0].oprval.mlit->v.str);
lnx = msp->len;
ENSURE_STP_FREE_SPACE(lnx);
memcpy(cp, msp->addr, lnx);
cp += lnx;
} else
{
assert(OC_WTONE == ref->opcode);
ENSURE_STP_FREE_SPACE(1);
*cp++ = ref->operand[0].oprval.tref->operand[0].oprval.ilit;
}
ref->operand[0].oprval.tref->opcode = OC_NOOP;
ref->opcode = OC_NOOP;
ref->operand[0].oprval.tref->operand[0].oprclass = OC_NOOP;
ref->operand[0].oprclass = 0;
}
ptx--;
stringpool.free = (unsigned char *) cp;
lit.str.len = INTCAST(cp - lit.str.addr);
s2n(&lit);
t1->opcode = OC_WRITE;
t1->operand[0] = put_lit(&lit);
}
}
return TRUE;
}