int m_write(void) { error_def(ERR_STRINGOFLOW); oprtype x,*oprptr; mval lit; mstr *msp; int lnx; char *cp; triple *ref, *t1; triple *litlst[128], **llptr, **ptx, **ltop; llptr = litlst; ltop = 0; *llptr = 0; for (;;) { devctlexp = FALSE; switch(window_token) { case TK_ASTERISK: advancewindow(); if (!intexpr(&x)) return FALSE; assert(x.oprclass == TRIP_REF); ref = newtriple(OC_WTONE); ref->operand[0] = x; STO_LLPTR((x.oprval.tref->opcode == OC_ILIT) ? 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 (strexpr(&x)) { case EXPR_FAIL: return FALSE; case EXPR_GOOD: assert(x.oprclass == TRIP_REF); 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((x.oprval.tref->opcode == OC_LIT) ? ref : 0); } break; case EXPR_INDR: make_commarg(&x,indir_write); STO_LLPTR(0); break; default: assert(FALSE); } break; } if (window_token != TK_COMMA) break; advancewindow(); if (llptr >= LITLST_TOP) { *++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 (ref->opcode == OC_WRITE) { msp = &(ref->operand[0].oprval.tref->operand[0].oprval.mlit->v.str); lnx = msp->len; if ( cp + lnx > (char *) stringpool.top) { stx_error(ERR_STRINGOFLOW); return FALSE; } memcpy(cp, msp->addr, lnx); cp += lnx; } else { assert(ref->opcode == OC_WTONE); if (cp + 1 > (char *) stringpool.top) { stx_error(ERR_STRINGOFLOW); return FALSE; } *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; }
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; CLEAR_MVAL_BITS(&lit); 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 = NO_REF; ref->operand[0].oprclass = NO_REF; } ptx--; stringpool.free = (unsigned char *) cp; lit.str.len = INTCAST(cp - lit.str.addr); t1->opcode = OC_WRITE; t1->operand[0] = put_lit(&lit); } } return TRUE; }