void lvzwr_fini(zshow_out *out, int t) { int4 size; mval local; mname_entry temp_key; ht_ent_mname *tabent; mident_fixed m; zwr_output = out; assert(lvzwrite_block); if (zwr_patrn_mident == lvzwrite_block->zwr_intype) { /* Mident specified for "pattern" (fixed name, no pattern) */ size = (lvzwrite_block->pat->str.len <= MAX_MIDENT_LEN) ? lvzwrite_block->pat->str.len : MAX_MIDENT_LEN; temp_key.var_name = lvzwrite_block->pat->str; COMPUTE_HASH_MNAME(&temp_key); tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &temp_key); if (!tabent || !LV_IS_VAL_DEFINED(tabent->value) && !LV_HAS_CHILD(tabent->value)) { lvzwrite_block->subsc_count = 0; rts_error(VARLSTCNT(4) ERR_UNDEF, 2, size, lvzwrite_block->pat->str.addr); } else { lvzwrite_block->curr_name = &tabent->key.var_name; lvzwr_var(((lv_val *)tabent->value), 0); } } else { /* mval specified for character "pattern" (pattern matching) */ assert(zwr_patrn_mval == lvzwrite_block->zwr_intype); memset(m.c, 0, SIZEOF(m.c)); local.mvtype = MV_STR; local.str.addr = &m.c[0]; local.str.len = 1; m.c[0] = '%'; /* Starting variable name for search (first possible varname) */ lvzwrite_block->fixed = FALSE; while (local.str.len) { if (do_pattern(&local, lvzwrite_block->pat)) { memset(&m.c[local.str.len], 0, SIZEOF(m.c) - local.str.len); temp_key.var_name = local.str; COMPUTE_HASH_MNAME(&temp_key); if (NULL != (tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &temp_key))) { lvzwrite_block->curr_name = &tabent->key.var_name; lvzwr_var(((lv_val *)tabent->value), 0); } } op_fnlvname(&local, TRUE, &local); assert(local.str.len <= MAX_MIDENT_LEN); memcpy(&m.c[0], local.str.addr, local.str.len); local.str.addr = &m.c[0]; } } lvzwrite_block->curr_subsc = lvzwrite_block->subsc_count = 0; return; }
void op_indget(mval *dst, mval *target, mval *value) { icode_str indir_src; int rval; ht_ent_mname *tabent; mstr *obj, object; oprtype v; triple *s, *src, *oldchain, tmpchain, *r, *triptr; var_tabent targ_key; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if ((TREF(ind_source_sp) >= TREF(ind_source_top)) || (TREF(ind_result_sp) >= TREF(ind_result_top))) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); /* mdbcondition_handler resets ind_result_sp & ind_source_sp */ MV_FORCE_DEFINED(value); MV_FORCE_STR(target); indir_src.str = target->str; indir_src.code = indir_get; if (NULL == (obj = cache_get(&indir_src))) { obj = &object; if (valid_mname(&target->str)) { targ_key.var_name = target->str; COMPUTE_HASH_MNAME(&targ_key); tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &targ_key); if (!tabent || !LV_IS_VAL_DEFINED(tabent->value)) *dst = *value; else *dst = ((lv_val *)tabent->value)->v; dst->mvtype &= ~MV_ALIASCONT; /* Make sure alias container property does not pass */ return; } comp_init(&target->str); src = newtriple(OC_IGETSRC); switch (TREF(window_token)) { case TK_IDENT: if (EXPR_FAIL != (rval = lvn(&v, OC_SRCHINDX, 0))) /* NOTE assignment */ { s = newtriple(OC_FNGET2); s->operand[0] = v; s->operand[1] = put_tref(src); } break; case TK_CIRCUMFLEX: if (EXPR_FAIL != (rval = gvn())) /* NOTE assignment */ { r = newtriple(OC_FNGVGET1); s = newtriple(OC_FNGVGET2); s->operand[0] = put_tref(r); s->operand[1] = put_tref(src); } break; case TK_ATSIGN: TREF(saw_side_effect) = TREF(shift_side_effects); if (TREF(shift_side_effects) && (GTM_BOOL == TREF(gtm_fullbool))) { dqinit(&tmpchain, exorder); oldchain = setcurtchain(&tmpchain); if (EXPR_FAIL != (rval = indirection(&v))) /* NOTE assignment */ { s = newtriple(OC_INDGET); s->operand[0] = v; s->operand[1] = put_tref(src); newtriple(OC_GVSAVTARG); setcurtchain(oldchain); dqadd(TREF(expr_start), &tmpchain, exorder); TREF(expr_start) = tmpchain.exorder.bl; triptr = newtriple(OC_GVRECTARG); triptr->operand[0] = put_tref(TREF(expr_start)); } else setcurtchain(oldchain); } else { if (EXPR_FAIL != (rval = indirection(&v))) /* NOTE assignment */ { s = newtriple(OC_INDGET); s->operand[0] = v; s->operand[1] = put_tref(src); } } break; default: stx_error(ERR_VAREXPECTED); rval = EXPR_FAIL; break; } v = put_tref(s); if (EXPR_FAIL == comp_fini(rval, obj, OC_IRETMVAL, &v, target->str.len)) return; indir_src.str.addr = target->str.addr; cache_put(&indir_src, obj); /* Fall into code activation below */ } *(TREF(ind_result_sp))++ = dst; *(TREF(ind_source_sp))++ = value; comp_indr(obj); return; }