void op_zprint(mval *rtn, mval *start_label, int start_int_exp, mval *end_label, int end_int_exp) /* contains label to be located or null string */ /* contains label offset or line number to reference */ /* contains routine to look in or null string */ /* NOTE: If only the first label is specified, the */ /* parser makes the second label the duplicate */ /* of the first. (not so vice versa) */ { mval print_line, null_str; mstr *src1, *src2; uint4 stat1, stat2; rhdtyp *rtn_vector; error_def(ERR_FILENOTFND); error_def(ERR_TXTSRCMAT); error_def(ERR_ZPRTLABNOTFND); error_def(ERR_ZLINKFILE); error_def(ERR_ZLMODULE); MV_FORCE_STR(start_label); MV_FORCE_STR(end_label); MV_FORCE_STR(rtn); if (NULL == (rtn_vector = find_rtn_hdr(&rtn->str))) { op_zlink(rtn, NULL); rtn_vector = find_rtn_hdr(&rtn->str); if (NULL == rtn_vector) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, rtn->str.len, rtn->str.addr, ERR_ZLMODULE, 2, mid_len(&zlink_mname), &zlink_mname.c[0]); } stat1 = get_src_line(rtn, start_label, start_int_exp, &src1); if (stat1 & LABELNOTFOUND) rts_error(VARLSTCNT(1) ERR_ZPRTLABNOTFND); if (stat1 & SRCNOTFND) rts_error(VARLSTCNT(4) ERR_FILENOTFND, 2, rtn_vector->src_full_name.len, rtn_vector->src_full_name.addr); if (stat1 & (SRCNOTAVAIL | AFTERLASTLINE)) return; if (stat1 & (ZEROLINE | NEGATIVELINE)) { null_str.mvtype = MV_STR; null_str.str.len = 0; stat1 = get_src_line(rtn, &null_str, 1, &src1); if (stat1 & AFTERLASTLINE) /* the "null" file */ return; } if (end_int_exp == 0 && (end_label->str.len == 0 || *end_label->str.addr == 0)) stat2 = AFTERLASTLINE; else if ((stat2 = get_src_line(rtn, end_label, end_int_exp, &src2)) & LABELNOTFOUND) rts_error(VARLSTCNT(1) ERR_ZPRTLABNOTFND); if (stat2 & (ZEROLINE | NEGATIVELINE)) return; if (stat2 & AFTERLASTLINE) { null_str.mvtype = MV_STR; null_str.str.len = 0; stat2 = get_src_line(rtn, &null_str, 1, &src2); /* number of lines less one for duplicated zero'th line and one due to termination condition being <= */ assert((INTPTR_T)src2 > 0); src2 += rtn_vector->lnrtab_len - 2; } if (stat1 & CHECKSUMFAIL) { rts_error(VARLSTCNT(1) INFO_MSK(ERR_TXTSRCMAT)); op_wteol(1); } print_line.mvtype = MV_STR; for ( ; src1 <= src2 ; src1++) { if (outofband) outofband_action(FALSE); print_line.str.addr = src1->addr; print_line.str.len = src1->len; op_write(&print_line); op_wteol(1); } return; }
void open_ceprep_file(void) { #ifdef VMS /* stub except for VMS */ #ifdef __ALPHA # pragma member_alignment save # pragma nomember_alignment #endif static readonly struct { unsigned char newversion; unsigned char wrap; unsigned char width; int4 v_width; unsigned char eol; } open_params_list = { (unsigned char) iop_newversion, (unsigned char) iop_wrap, (unsigned char) iop_recordsize, (int4) MAX_SRCLINE, (unsigned char) iop_eol }; #ifdef __ALPHA # pragma member_alignment restore #endif int mname_len; uint4 status; char charspace, ceprep_name_buff[sizeof(mident) + sizeof(".MCI") - 1], fname[255]; mval file, params; struct NAM ceprep_nam; /* name block for file access block for compiler escape preprocessor output */ /* Create cepreprocessor output file. */ ceprep_fab = cc$rms_fab; ceprep_fab.fab$l_dna = ceprep_name_buff; mname_len = mid_len(module_name); assert(mname_len <= sizeof(mident)); if (0 == mname_len) { memcpy(ceprep_name_buff, "MDEFAULT.MCI", sizeof("MDEFAULT.MCI") - 1); ceprep_fab.fab$b_dns = sizeof("MDEFAULT.MCI") - 1; } else { memcpy(ceprep_name_buff, module_name, mname_len); memcpy(&ceprep_name_buff[mname_len], ".MCI", sizeof(".MCI") - 1); ceprep_fab.fab$b_dns = mname_len + sizeof(".MCI") - 1; } if (MV_DEFINED(&cmd_qlf.ceprep_file)) { ceprep_fab.fab$b_fns = cmd_qlf.ceprep_file.str.len; ceprep_fab.fab$l_fna = cmd_qlf.ceprep_file.str.addr; } ceprep_nam = cc$rms_nam; ceprep_nam.nam$l_esa = fname; ceprep_nam.nam$b_ess = sizeof(fname); ceprep_nam.nam$b_nop = (NAM$M_SYNCHK); ceprep_fab.fab$l_nam = &ceprep_nam; ceprep_fab.fab$l_fop = FAB$M_NAM; if (RMS$_NORMAL != (status = sys$parse(&ceprep_fab, 0, 0))) rts_error(VARLSTCNT(1) status); file.mvtype = params.mvtype = MV_STR; file.str.len = ceprep_nam.nam$b_esl; file.str.addr = fname; params.str.len = sizeof(open_params_list); params.str.addr = &open_params_list; op_open(&file, ¶ms, CEPREP_OPEN_TIMEOUT, 0); params.str.len = 1; charspace = (char)iop_eol; params.str.addr = &charspace; dev_in_use = io_curr_device; op_use(&file, ¶ms); #endif return; }
int m_zprint(void) { oprtype lab1,lab2,off1,off2,rtn; triple *ref,*next; bool got_some; error_def(ERR_LABELEXPECTED); error_def(ERR_RTNNAME); got_some = FALSE; lab1 = put_str(&zero_ident.c[0],sizeof(mident)); off1 = put_ilit(0); if (window_token != TK_EOL && window_token != TK_SPACE && !lref(&lab1,&off1,TRUE,indir_zprint,TRUE,&got_some)) return FALSE; if (lab1.oprclass == TRIP_REF && lab1.oprval.tref->opcode == OC_COMMARG) return TRUE; if (window_token != TK_CIRCUMFLEX) { if (!run_time) rtn = put_str(routine_name, mid_len ((mident *)routine_name)); else rtn = put_tref(newtriple(OC_CURRTN)); } else { got_some = TRUE; advancewindow(); switch(window_token) { case TK_IDENT: rtn = put_str(window_ident.c, mid_len (&window_ident)); advancewindow(); break; case TK_ATSIGN: if (!indirection(&rtn)) return FALSE; break; default: stx_error(ERR_RTNNAME); return FALSE; } } if (window_token == TK_COLON) { if (!got_some) { stx_error(ERR_LABELEXPECTED); return FALSE; } lab2 = put_str(&zero_ident.c[0],sizeof(mident)); off2 = put_ilit(0); advancewindow(); if (!lref(&lab2,&off2,TRUE,indir_zprint,FALSE,&got_some)) return FALSE; if (!got_some) { stx_error(ERR_LABELEXPECTED); return FALSE; } } else { lab2 = lab1; off2 = off1; } ref = newtriple(OC_ZPRINT); ref->operand[0] = rtn; next = newtriple(OC_PARAMETER); ref->operand[1] = put_tref(next); next->operand[0] = lab1; ref = newtriple(OC_PARAMETER); next->operand[1] = put_tref(ref); ref->operand[0] = off1; next = newtriple(OC_PARAMETER); ref->operand[1] = put_tref(next); next->operand[0] = lab2; ref = newtriple(OC_PARAMETER); next->operand[1] = put_tref(ref); ref->operand[0] = off2; return TRUE; }
void cdbg_dump_operand(int indent, oprtype *opr, int opnum) { triple *rtrip; int offset, len; char *buff; if (opr) PRINTF("%s %s [0x%08lx] Type: %s\n", cdbg_indent(indent), oprtype_names[opnum], opr, oprtype_type_names[opr->oprclass]); else PRINTF("%s ** Warning ** Null opr passed as operand\n", cdbg_indent(indent)); if (!opr->oprclass) return; /* We have a real oprclass, dump it's info */ switch(opr->oprclass) { case TVAR_REF: PRINTF("%s Temporary variable index %d\n", cdbg_indent(indent), opr->oprval.temp); break; case TCAD_REF: case TVAD_REF: PRINTF("%s %s reference - whatever it means: value is %d\n", cdbg_indent(indent), ((TCAD_REF == opr->oprclass) ? "TCAD_REF" : "TVAD_REF"), opr->oprval.temp); break; case MVAR_REF: if (opr->oprval.vref) { PRINTF("%s LS vref: 0x%08lx RS vref: 0x%08lx index: %d varname: %s last triple: 0x%08lx\n", cdbg_indent(indent), opr->oprval.vref->lson, opr->oprval.vref->rson, opr->oprval.vref->mvidx, cdbg_makstr(opr->oprval.vref->mvname.c, &buff, sizeof(opr->oprval.vref->mvname)), opr->oprval.vref->last_fetch); free(buff); } else PRINTF("%s ** Warning ** oprval.vref is NULL\n", cdbg_indent(indent)); break; case TINT_REF: case TVAL_REF: offset = sa_temps_offset[opr->oprclass]; offset -= (sa_temps[opr->oprclass] - opr->oprval.temp) * sa_class_sizes[opr->oprclass]; PRINTF("%s temp index: %d offset: 0x%08lx\n", cdbg_indent(indent), opr->oprval.temp, offset); break; case ILIT_REF: PRINTF("%s ilit value: %d [0x%08lx]\n", cdbg_indent(indent), opr->oprval.ilit, opr->oprval.ilit); break; case MLIT_REF: if (opr->oprval.mlit) PRINTF("%s lit-ref fwdptr: 0x%08lx bkwdptr: 0x%08lx rtaddr: 0x%08lx\n", cdbg_indent(indent), opr->oprval.mlit->que.fl, opr->oprval.mlit->que.bl, opr->oprval.mlit->rt_addr); else PRINTF("%s ** Warning ** oprval.mlit is NULL\n", cdbg_indent(indent)); cdbg_dump_mval(indent, &opr->oprval.mlit->v); break; case TJMP_REF: if (opr->oprval.tref) PRINTF("%s tjmp-ref jump list ptr: 0x%08lx\n", cdbg_indent(indent), &opr->oprval.tref->jmplist); else PRINTF("%s ** Warning ** oprval.tref is NULL\n", cdbg_indent(indent)); break; case TRIP_REF: rtrip = opr->oprval.tref; PRINTF("%s Trip reference:\n", cdbg_indent(indent)); cdbg_dump_triple(rtrip, indent + 1); break; case INDR_REF: cdbg_dump_operand(indent, opr->oprval.indr, opnum); break; case TSIZ_REF: if (opr->oprval.tsize) PRINTF("%s triple at 0x%08lx has size %d\n", cdbg_indent(indent), opr->oprval.tsize->ct, opr->oprval.tsize->size); else PRINTF("%s ** Warning ** oprval.tsize is NULL\n", cdbg_indent(indent)); break; case OCNT_REF: PRINTF("%s offset from call to next triple: %d\n", cdbg_indent(indent), opr->oprval.offset); break; case MFUN_REF: if (opr->oprval.lab) { unsigned char mid[sizeof(mident) + 1]; len = mid_len(&opr->oprval.lab->mvname); memcpy(mid, &opr->oprval.lab->mvname, len); mid[len] = 0; PRINTF("%s mlabel name: %s\n", cdbg_indent(indent), mid); } else PRINTF("%s ** Warning ** oprval.lab is NULL\n", cdbg_indent(indent)); break; default: PRINTF("%s %s bogus reference\n", cdbg_indent(indent), oprtype_type_names[opr->oprclass]); } }
int m_zwrite(void) { int4 pcount; /* parameter count */ triple *ref,*ref1,*head,*last,*count; opctype op; oprtype name,limit; mval mv; mint code; mint subscount; char c; bool pat; error_def(ERR_VAREXPECTED); error_def(ERR_RPARENMISSING); error_def(ERR_ZWRSPONE); error_def(ERR_COMMA); subscount = 0; count = 0; pat = FALSE; if (window_token == TK_CIRCUMFLEX) { advancewindow(); op = OC_GVZWRITE; } else { op = OC_LVZWRITE; } switch(window_token) { case TK_SPACE: case TK_EOL: if (op == OC_GVZWRITE) { stx_error(ERR_VAREXPECTED); return FALSE; } else { op = OC_LVPATWRITE; } head = maketriple(op); head->operand[0] = put_ilit((mint)3); ref1 = newtriple(OC_PARAMETER); head->operand[1] = put_tref(ref1); ref1->operand[0] = put_ilit(0); /* shows not from zshow */ ref = newtriple(OC_PARAMETER); ref1->operand[1] = put_tref(ref); ref->operand[0] = put_str((char *)pat_everything,sizeof_pat_everything); MV_FORCE_MVAL(&mv,ZWRITE_ASTERISK) ; ref->operand[1] = put_lit(&mv); ins_triple(head); return TRUE; case TK_IDENT: name = put_str(&window_ident.c[0],mid_len(&window_ident)); advancewindow(); break; case TK_LPAREN: if (op != OC_GVZWRITE) /* naked reference */ { stx_error(ERR_VAREXPECTED); return FALSE; } name = put_str(&window_ident.c[0], 0); break; case TK_ATSIGN: if (!indirection(&name)) return FALSE; if (op == OC_LVZWRITE && window_token != TK_LPAREN) { ref = maketriple(OC_COMMARG); ref->operand[0] = name; ref->operand[1] = put_ilit(indir_zwrite); ins_triple(ref); return TRUE; } ref = newtriple(OC_INDPAT); ref->operand[0] = name; name = put_tref(ref); break; case TK_QUESTION: advancewindow(); source_column = last_source_column; if (!compile_pattern(&name,FALSE)) return FALSE; if (op == OC_LVZWRITE) op = OC_LVPATWRITE; pat = TRUE; break; default: stx_error(ERR_VAREXPECTED); return FALSE; } head = maketriple(op); last = newtriple(OC_PARAMETER); head->operand[1] = put_tref(last); pcount = 1; if (op == OC_LVPATWRITE || op == OC_GVZWRITE) { pcount++; last->operand[0] = put_ilit((op == OC_GVZWRITE ? pat : 0)); ref = newtriple(OC_PARAMETER); last->operand[1] = put_tref(ref); last = ref; if (op == OC_GVZWRITE) { pcount++; count = last; ref = newtriple(OC_PARAMETER); last->operand[1] = put_tref(ref); last = ref; } } last->operand[0] = name; if (window_token != TK_LPAREN) { pcount++; if (pat) { MV_FORCE_MVAL(&mv,ZWRITE_END) ; } else { subscount++ ; MV_FORCE_MVAL(&mv,ZWRITE_ASTERISK) ; } last->operand[1] = put_lit(&mv); head->operand[0] = put_ilit(pcount); if (count) count->operand[0] = put_ilit(subscount); ins_triple(head); return TRUE; } advancewindow(); for(;;) { ref = newtriple(OC_PARAMETER); last->operand[1] = put_tref(ref); switch (window_token) { case TK_RPAREN: dqdel(ref,exorder); advancewindow(); MV_FORCE_MVAL(&mv,ZWRITE_END) ; last->operand[1] = put_lit(&mv); pcount++; head->operand[0] = put_ilit((mint)pcount); if (count) count->operand[0] = put_ilit(subscount); ins_triple(head); return TRUE; case TK_ASTERISK: dqdel(ref,exorder); advancewindow(); if (window_token != TK_RPAREN) { stx_error(ERR_RPARENMISSING); return FALSE; } advancewindow(); MV_FORCE_MVAL(&mv,ZWRITE_ASTERISK) ; last->operand[1] = put_lit(&mv); pcount++; subscount++; head->operand[0] = put_ilit((mint)pcount); if (count) count->operand[0] = put_ilit(subscount); ins_triple(head); return TRUE; case TK_QUESTION: advancewindow(); source_column = last_source_column; if (!compile_pattern(&limit,FALSE)) return FALSE; if (window_token != TK_COMMA && window_token != TK_RPAREN) { stx_error(ERR_ZWRSPONE); return FALSE; } if (window_token == TK_COMMA) advancewindow(); subscount++; MV_FORCE_MVAL(&mv,ZWRITE_PATTERN) ; ref->operand[0] = put_lit(&mv); pcount++; ref1 = newtriple(OC_PARAMETER); ref->operand[1] = put_tref(ref1); ref1->operand[0] = limit; last = ref1; pcount++; continue; case TK_COLON: if ((c = director_token) != TK_RPAREN) { if (c != TK_COMMA) { advancewindow(); MV_FORCE_MVAL(&mv,ZWRITE_UPPER) ; ref->operand[0] = put_lit(&mv); pcount++; subscount++; break; } advancewindow(); } /* caution: fall through */ case TK_COMMA: advancewindow(); MV_FORCE_MVAL(&mv,ZWRITE_ALL) ; ref->operand[0] = put_lit(&mv); pcount++; subscount++; last = ref; continue; default: if (!expr(&limit)) return FALSE; subscount++; last = newtriple(OC_PARAMETER); ref->operand[1] = put_tref(last); last->operand[0] = limit; pcount++; if ((c = window_token) == TK_COLON) { code = ZWRITE_LOWER; advancewindow(); c = window_token; } else code = ZWRITE_VAL; switch (c) { case TK_COMMA: advancewindow(); /* caution: fall through */ case TK_RPAREN: MV_FORCE_MVAL(&mv,code) ; ref->operand[0] = put_lit(&mv); pcount++; continue; default: if (code == ZWRITE_VAL) { stx_error(ERR_COMMA); return FALSE; } MV_FORCE_MVAL(&mv,ZWRITE_BOTH) ; ref->operand[0] = put_lit(&mv); pcount++; ref = last; break; } break; } if (!expr(&limit)) return FALSE; last = newtriple(OC_PARAMETER); ref->operand[1] = put_tref(last); last->operand[0] = limit; pcount++; if (window_token == TK_COMMA) { advancewindow(); } } }
void op_gvorder (mval *v) { int4 n; gd_binding *map; mstr name; enum db_acc_method acc_meth; boolean_t found, ok_to_change_currkey; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; acc_meth = gv_cur_region->dyn.addr->acc_meth; /* Modify gv_currkey such that a gvcst_search of the resulting gv_currkey will find the next available subscript. * But in case of dba_usr (the custom implementation of $ORDER which is overloaded for DDP but could be more in the * future) it is better to hand over gv_currkey as it is so the custom implementation can decide what to do with it. */ ok_to_change_currkey = (dba_usr != acc_meth); if (ok_to_change_currkey) { /* Modify gv_currkey to reflect the next possible key value in collating order */ if (!TREF(gv_last_subsc_null) || gv_cur_region->std_null_coll) { *(&gv_currkey->base[0] + gv_currkey->end - 1) = 1; *(&gv_currkey->base[0] + gv_currkey->end + 1) = 0; gv_currkey->end += 1; } else { assert(STR_SUB_PREFIX == gv_currkey->base[gv_currkey->prev]); assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end]); assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end - 1]); assert(2 == (gv_currkey->end - gv_currkey->prev)); *(&gv_currkey->base[0] + gv_currkey->prev) = 01; } } if (gv_currkey->prev) { if (acc_meth == dba_bg || acc_meth == dba_mm) { if (gv_target->root == 0) /* global does not exist */ found = FALSE; else found = gvcst_order(); } else if (acc_meth == dba_cm) found = gvcmx_order(); else found = gvusr_order(); v->mvtype = 0; /* so stp_gcol (if invoked below) can free up space currently occupied by * this to-be-overwritten mval */ if (found) { gv_altkey->prev = gv_currkey->prev; if (!(IS_STP_SPACE_AVAILABLE(MAX_KEY_SZ))) { if (*(&gv_altkey->base[0] + gv_altkey->prev) != 0xFF) n = MAX_FORM_NUM_SUBLEN; else { n = gv_altkey->end - gv_altkey->prev; assert (n > 0); } ENSURE_STP_FREE_SPACE(n); } v->str.addr = (char *)stringpool.free; stringpool.free = gvsub2str (&gv_altkey->base[0] + gv_altkey->prev, stringpool.free, FALSE); v->str.len = INTCAST((char *)stringpool.free - v->str.addr); assert (v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base); assert (v->str.addr + v->str.len <= (char *)stringpool.top && v->str.addr + v->str.len >= (char *)stringpool.base); } else v->str.len = 0; v->mvtype = MV_STR; /* initialize mvtype now that mval has been otherwise completely set up */ if (ok_to_change_currkey) { /* Restore gv_currkey to what it was at function entry time */ if (!TREF(gv_last_subsc_null) || gv_cur_region->std_null_coll) { assert(1 == gv_currkey->base[gv_currkey->end - 2]); assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end-1]); assert(KEY_DELIMITER == gv_currkey->base[gv_currkey->end]); gv_currkey->base[gv_currkey->end - 2] = KEY_DELIMITER; gv_currkey->end--; } else { assert(01 == gv_currkey->base[gv_currkey->prev]); gv_currkey->base[gv_currkey->prev] = STR_SUB_PREFIX; } } } else /* the following section is for $O(^gname) */ { assert (2 < gv_currkey->end); assert (gv_currkey->end < (MAX_MIDENT_LEN + 3)); /* until names are not in midents */ map = gd_map + 1; while (map < gd_map_top && (memcmp(gv_currkey->base, map->name, gv_currkey->end == (MAX_MIDENT_LEN + 2) ? MAX_MIDENT_LEN : gv_currkey->end - 1) >= 0)) { map++; } for (; map < gd_map_top; ++map) { gv_cur_region = map->reg.addr; if (!gv_cur_region->open) gv_init_reg(gv_cur_region); change_reg(); acc_meth = gv_cur_region->dyn.addr->acc_meth; for (; ;) /* search region, entries in directory tree could be empty */ { if (acc_meth == dba_bg || acc_meth == dba_mm) { gv_target = cs_addrs->dir_tree; found = gvcst_order (); } else if (acc_meth == dba_cm) found = gvcmx_order (); else found = gvusr_order(); if (!found) break; assert (1 < gv_altkey->end); assert (gv_altkey->end < (MAX_MIDENT_LEN + 2)); /* until names are not in midents */ if (memcmp(gv_altkey->base, map->name, gv_altkey->end - 1) > 0) { found = FALSE; break; } name.addr = (char *)&gv_altkey->base[0]; name.len = gv_altkey->end - 1; if (acc_meth == dba_cm) break; GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &name); if (gv_cur_region != map->reg.addr) { found = FALSE; break; } if ((gv_target->root != 0) && (gvcst_data() != 0)) break; *(&gv_currkey->base[0] + gv_currkey->end - 1) = 1; *(&gv_currkey->base[0] + gv_currkey->end + 1) = 0; gv_currkey->end += 1; } if (found) break; else { assert(SIZEOF(map->name) == SIZEOF(mident_fixed)); gv_currkey->end = mid_len((mident_fixed *)map->name); memcpy(&gv_currkey->base[0], map->name, gv_currkey->end); gv_currkey->base[ gv_currkey->end - 1 ] -= 1; gv_currkey->base[ gv_currkey->end ] = 0xFF; /* back off 1 spot from map */ gv_currkey->base[ gv_currkey->end + 1] = 0; gv_currkey->base[ gv_currkey->end + 2] = 0; gv_currkey->end += 2; } } /* Reset gv_currkey as we have potentially skipped one or more regions so we no * longer can expect gv_currkey/gv_cur_region/gv_target to match each other. */ gv_currkey->end = 0; gv_currkey->base[0] = 0; v->mvtype = 0; /* so stp_gcol (if invoked below) can free up space currently occupied by * this to-be-overwritten mval */ if (found) { if (!IS_STP_SPACE_AVAILABLE(name.len + 1)) { v->str.len = 0; /* so stp_gcol ignores otherwise incompletely setup mval */ INVOKE_STP_GCOL(name.len + 1); } #ifdef mips /* the following line works around a tandem compiler bug. */ v->str.addr = (char *)0; #endif v->str.addr = (char *)stringpool.free; *stringpool.free++ = '^'; memcpy (stringpool.free, name.addr, name.len); stringpool.free += name.len; v->str.len = name.len + 1; assert (v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base); assert (v->str.addr + v->str.len <= (char *)stringpool.top && v->str.addr + v->str.len >= (char *)stringpool.base); } else v->str.len = 0; v->mvtype = MV_STR; /* initialize mvtype now that mval has been otherwise completely set up */ } return; }