int is_equ(mval *u,mval *v) { char utyp, vtyp, land, lor; utyp = u->mvtype; vtyp = v->mvtype; land = utyp & vtyp; lor = utyp | vtyp; if ((land & MV_NM) != 0 && (lor & MV_NUM_APPROX) == 0) { /* at this point, the mval's are both exact numbers, we can do a numeric comparison */ /* If they are both integers, compare only the relevant cells */ if (land & MV_INT) return (u->m[1] == v->m[1]); /* If one is an integer and the other is not, the two values cannot be equal */ if (lor & MV_INT) return 0; /* They are both decimal floating numbers, do a full comparison */ return (u->sgn == v->sgn && u->e == v->e && u->m[1] == v->m[1] && u->m[0]==v->m[0]); } /* At least one of the numbers is not in numeric form or is not a cannoical number, do a string compare */ MV_FORCE_STR(u); MV_FORCE_STR(v); if (u->str.len != v->str.len || u->str.len > 0 && memcmp(u->str.addr,v->str.addr,u->str.len) != 0) return 0; else return 1; }
int op_open(mval *device, mval *devparms, int timeout, mval *mspace) { LITREF unsigned char io_params_size[]; char buf1[MAX_TRANS_NAME_LEN]; /* buffer to hold translated name */ io_log_name *naml; /* logical record for passed name */ io_log_name *tl; /* logical record for translated name */ io_log_name *prev; /* logical record for removal search */ uint4 stat; /* status */ mstr tn; /* translated name */ error_def(LP_NOTACQ); /* bad license */ MV_FORCE_STR(device); MV_FORCE_STR(devparms); if (mspace) MV_FORCE_STR(mspace); if (timeout < 0) timeout = 0; assert((unsigned char)*devparms->str.addr < n_iops); naml = get_log_name(&device->str, INSERT); if (naml->iod != 0) tl = naml; else { #ifdef NOLICENSE licensed= TRUE; #else CRYPT_CHKSYSTEM; if (!licensed || LP_CONFIRM(lid, lkid)==LP_NOTACQ) licensed= FALSE; #endif switch(stat = trans_log_name(&device->str, &tn, &buf1[0])) { case SS_NORMAL: tl = get_log_name(&tn, INSERT); break; case SS_NOLOGNAM: tl = naml; break; default: for (prev = io_root_log_name, tl = prev->next; tl != 0; prev = tl, tl = tl->next) { if (naml == tl) { prev->next = tl->next; free(tl); break; } } rts_error(VARLSTCNT(1) stat); } } stat = io_open_try(naml, tl, devparms, timeout, mspace); return (stat); }
/* The third parameter is dummy to keep the inteface same as op_open */ int mu_op_open(mval *v, mval *p, int t, mval *mspace) { char buf1[MAX_TRANS_NAME_LEN]; /* buffer to hold translated name */ io_log_name *naml; /* logical record for passed name */ io_log_name *tl; /* logical record for translated name */ int4 stat; /* status */ mstr tn; /* translated name */ error_def(LP_NOTACQ); /* bad license */ error_def(ERR_LOGTOOLONG); MV_FORCE_STR(v); MV_FORCE_STR(p); if (mspace) MV_FORCE_STR(mspace); if (t < 0) t = 0; assert((unsigned char)*p->str.addr < n_iops); naml = get_log_name(&v->str, INSERT); if (naml->iod != 0) tl = naml; else { # ifdef NOLICENSE licensed= TRUE ; # else CRYPT_CHKSYSTEM; if (!licensed || LP_CONFIRM(lid,lkid)==LP_NOTACQ) { licensed= FALSE ; } # endif switch(stat = TRANS_LOG_NAME(&v->str, &tn, &buf1[0], sizeof(buf1), dont_sendmsg_on_log2long)) { case SS_NORMAL: tl = get_log_name(&tn, INSERT); break; case SS_NOLOGNAM: tl = naml; break; case SS_LOG2LONG: rts_error(VARLSTCNT(5) ERR_LOGTOOLONG, 3, v->str.len, v->str.addr, sizeof(buf1) - 1); break; default: rts_error(VARLSTCNT(1) stat); } } stat = mu_open_try(naml, tl, p, mspace); return (stat); }
void op_fnzbitxor(mval *dst, mval *bitstr1, mval *bitstr2) { int n, str_len1, str_len2, new_str_len; unsigned char *byte_1, *byte_n; unsigned char *byte1_1, *byte1_n, byte1_len; unsigned char *byte2_1, *byte2_n, byte2_len; error_def(ERR_INVBITSTR); MV_FORCE_STR(bitstr1); MV_FORCE_STR(bitstr2); if (!bitstr1->str.len || !bitstr2->str.len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); byte1_len = *(unsigned char *)bitstr1->str.addr; str_len1 = (bitstr1->str.len - 1) * 8; if (7 < byte1_len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); byte2_len = *(unsigned char *)bitstr2->str.addr; str_len2 = (bitstr2->str.len -1) * 8; if (7 < byte2_len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); if (str_len1 - byte1_len > str_len2 - byte2_len) new_str_len = str_len2 - byte2_len; else new_str_len = str_len1 - byte1_len; n = (new_str_len + 7)/8 ; if (stringpool.top - stringpool.free < n + 1) stp_gcol(n + 1); byte_1 = (unsigned char *)stringpool.free; *byte_1 = n * 8 - new_str_len; byte1_1 = (unsigned char *)bitstr1->str.addr; byte2_1 = (unsigned char *)bitstr2->str.addr; for(byte_n = byte_1 + 1, byte1_n = byte1_1 + 1, byte2_n = byte2_1 + 1 ; byte_n <= (byte_1 + n); byte_n++, byte1_n++, byte2_n++) { *byte_n = *byte1_n ^ *byte2_n; } *--byte_n &= mask[*byte_1]; dst->mvtype = MV_STR; dst->str.addr = (char *)stringpool.free; dst->str.len = n + 1; stringpool.free += n + 1; }
void op_indfun(mval *v, mint code, mval *dst) { bool rval; mstr *obj, object; oprtype x; unsigned char argcode; error_def(ERR_INDMAXNEST); argcode = (unsigned char)code; assert(UCHAR_MAX >= code); /* if not, the assignment to argcode is lossy */ assert(indir_opcode[argcode]); MV_FORCE_STR(v); if (!(obj = cache_get(argcode, &v->str))) { comp_init(&v->str); rval = (*indir_fcn[argcode])(&x, indir_opcode[argcode]); if (!comp_fini(rval, &object, OC_IRETMVAL, &x, v->str.len)) return; cache_put(argcode, &v->str, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); return; } *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(obj); return; }
int do_patfixed(mval *str, mval *pat) { int4 count, tempint; int4 *min, *reptr, *rtop; int4 repeat; int4 *ptop; int bit; int letter; int repcnt; int len; unsigned char *strptr, *pstr; uint4 code, tempuint, patstream_len; uint4 *patptr; uint4 mbit; char buf[CHAR_CLASSES]; error_def(ERR_PATNOTFOUND); /* set up information */ MV_FORCE_STR(str); patptr = (uint4 *)pat->str.addr; DEBUG_ONLY( GET_ULONG(tempuint, patptr); assert(tempuint); /* ensure first uint4 is non-zero indicating fixed length pattern string */ )
void op_indpat(mval *v, mval *dst) { bool rval; mstr *obj, object; oprtype x; error_def(ERR_INDMAXNEST); MV_FORCE_STR(v); if (!(obj = cache_get(indir_pattern, &v->str))) { comp_init(&v->str); source_column = 1; /* to coordinate with scanner redirection*/ rval = compile_pattern(&x,window_token == TK_ATSIGN); if (comp_fini(rval, &object, OC_IRETMVAL, &x, v->str.len)) { cache_put(indir_pattern, &v->str, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); } } else { *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(obj); } }
void op_indpat(mval *v, mval *dst) { int rval; icode_str indir_src; mstr *obj, object; oprtype x, getdst; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; MV_FORCE_STR(v); indir_src.str = v->str; indir_src.code = indir_pattern; if (NULL == (obj = cache_get(&indir_src))) { obj = &object; comp_init(&v->str, &getdst); source_column = 1; /* to coordinate with scanner redirection*/ rval = compile_pattern(&x, (TK_ATSIGN == TREF(window_token))); if (EXPR_FAIL == comp_fini(rval, obj, OC_IRETMVAL, &x, &getdst, v->str.len)) return; indir_src.str.addr = v->str.addr; cache_put(&indir_src, obj); /* Fall into code activation below */ } TREF(ind_result) = dst; /* Where to store return value */ comp_indr(obj); return; }
/* returns FALSE if gv_currkey is undefined in the server end and undef_inhibit is turned OFF */ void gvcmx_increment(mval *increment, mval *result) { unsigned char buff[MAX_ZWR_KEY_SZ], *end; mval tmpmval; error_def(ERR_UNIMPLOP); error_def(ERR_TEXT); error_def(ERR_GVIS); if (!((link_info *)gv_cur_region->dyn.addr->cm_blk->usr)->server_supports_dollar_incr) { assert(dba_cm == gv_cur_region->dyn.addr->acc_meth); /* we should've covered all other access methods elsewhere */ end = format_targ_key(buff, MAX_ZWR_KEY_SZ, gv_currkey, TRUE); rts_error(VARLSTCNT(14) ERR_UNIMPLOP, 0, ERR_TEXT, 2, LEN_AND_LIT("GT.CM server does not support $INCREMENT operation"), ERR_GVIS, 2, end - buff, buff, ERR_TEXT, 2, REG_LEN_STR(gv_cur_region)); } /* gvcmz_doop() currently accepts only one argument. * It serves as an input argument for SET. * It serves as an output argument for GET etc. * $INCR is unique in that it needs to pass the increment as input and expects the post-increment as output. * * In order to accomplish this without changing the gvcmz_doop() interface, we overload the one argument to * serve two purposes. It will be an input argument until the send of the message to the server and will * then serve as an output argument after the response from the server. ("result" is used for this purpose) * i.e. * to serve as increment for client --> server message * to serve as post-increment value for server --> client message */ assert(MV_IS_NUMERIC(increment)); /* op_gvincr would have forced it to be a NUMERIC */ MV_FORCE_STR(increment); /* convert it to a string before sending it to gvcmz_doop */ *result = *increment; gvcmz_doop(CMMS_Q_INCREMENT, CMMS_R_INCREMENT, result); }
/* For routine name given, return routine header address if rhd not already set */ rhdtyp *op_rhdaddr(mval *name, rhdtyp *rhd) { mval routine; mident_fixed routname; rhdtyp *answer; if (NULL != rhd) answer = rhd; else { MV_FORCE_STR(name); routine = *name; routine.str.len = (MAX_MIDENT_LEN < routine.str.len ? MAX_MIDENT_LEN : routine.str.len); memcpy(&routname.c[0], routine.str.addr, routine.str.len); routine.str.addr = (char *)&routname.c[0]; if ((NULL == rtn_names) || (NULL == (answer = find_rtn_hdr(&routine.str)))) /* Note assignment */ { /* Initial check for rtn_names is so we avoid the call to find_rtn_hdr() if we have just * unlinked all modules as find_rtn_hdr() does not deal well with an empty rtn table. */ op_zlink(&routine, NULL); answer = find_rtn_hdr(&routine.str); if (NULL == answer) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, name->str.len, name->str.addr, ERR_ZLMODULE, 2, strlen(&zlink_mname.c[0]), &zlink_mname); # if defined (__alpha) && defined (__vms) answer = answer->linkage_ptr; if (NULL == answer) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, name->str.len, name->str.addr, ERR_ZLMODULE, 2, strlen(&zlink_mname.c[0]), zlink_mname.c); # endif } } return answer; }
int do_patsplit(mval *str, mval *pat) { int4 count, total_min, total_max; int4 min[MAX_PATTERN_ATOMS], max[MAX_PATTERN_ATOMS], size[MAX_PATTERN_ATOMS]; int4 bytelen, charlen, charstoskip, fixedcharlen, leftcharlen, rightcharlen, deltalen, numchars; int4 strbytelen, strcharlen; int4 alt_rep_min, alt_rep_max; int4 alt; uint4 tempuint; uint4 code, flags; uint4 *patptr, *patptr_start, *patptr_end, *fixed_patptr, *right_patptr, *tmp_patptr; ptstr left_ptstr, right_ptstr, fixed_ptstr; mval left_pat, right_pat, fixed_pat, left_str, right_str, fixed_str; int4 index, fixed_index; /* index of our current fixed-length pattern-atom */ boolean_t right; /* 0 indicates we are processing left side, 1 indicates right side */ boolean_t fixed[2]; /* fixed[0] is for the left, fixed[1] is for the right */ int4 tot_min[2], tot_max[2], cnt[2]; /* index 0 is for left, index 1 is for right */ int4 offset; unsigned char *strptr, *strtop, *rightptr, *rightnext, *fixedptr, *fixednext, *maxfixedptr; boolean_t match; /* match status of input pattern with input string */ gtm_uint64_t bound; MV_FORCE_STR(str); patptr = (uint4 *)pat->str.addr; DEBUG_ONLY( GET_ULONG(tempuint, patptr); assert(!tempuint); )
void op_indglvn(mval *v,mval *dst) { bool rval; mstr *obj, object; oprtype x; lv_val *a; icode_str indir_src; lv_val *lv; var_tabent targ_key; ht_ent_mname *tabent; error_def(ERR_INDMAXNEST); error_def(ERR_UNDEF); MV_FORCE_STR(v); indir_src.str = v->str; indir_src.code = indir_glvn; if (NULL == (obj = cache_get(&indir_src))) { if (valid_mname(&v->str)) { targ_key.var_name = v->str; COMPUTE_HASH_MNAME(&targ_key); tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &targ_key); assert(NULL == tabent || NULL != tabent->value); if (!tabent || !MV_DEFINED(&((lv_val *)tabent->value)->v)) { if (undef_inhibit) { *dst = literal_null; return; } else rts_error(VARLSTCNT(4) ERR_UNDEF, 2, v->str.len, v->str.addr); } a = (lv_val *)tabent->value; *dst = a->v; return; } comp_init(&v->str); rval = glvn(&x); if (comp_fini(rval, &object, OC_IRETMVAL, &x, v->str.len)) { indir_src.str.addr = v->str.addr; cache_put(&indir_src, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); } } else { *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(obj); } }
void op_indlvarg(mval *v, mval *dst) { bool rval; mstr *obj, object; oprtype x; triple *ref; icode_str indir_src; error_def(ERR_INDMAXNEST); error_def(ERR_VAREXPECTED); MV_FORCE_STR(v); if (v->str.len < 1) rts_error(VARLSTCNT(1) ERR_VAREXPECTED); if (valid_mname(&v->str)) { *dst = *v; dst->mvtype &= ~MV_ALIASCONT; /* Make sure alias container property does not pass */ return; } if (*v->str.addr == '@') { indir_src.str = v->str; indir_src.code = indir_lvarg; if (NULL == (obj = cache_get(&indir_src))) { object.addr = v->str.addr; object.len = v->str.len; comp_init(&object); if (rval = indirection(&x)) { ref = newtriple(OC_INDLVARG); ref->operand[0] = x; x = put_tref(ref); } if (comp_fini(rval, &object, OC_IRETMVAL, &x, object.len)) { indir_src.str.addr = v->str.addr; cache_put(&indir_src, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); return; } } else { *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(obj); return; } } rts_error(VARLSTCNT(1) ERR_VAREXPECTED); }
/* Routine to return a string in zwrite format */ void op_fnzwrite(mval* src, mval* dst) { int dst_len, str_len; MV_FORCE_STR(src); MV_FORCE_NUM(src); if MV_IS_CANONICAL(src) *dst = *src; else {
void op_commarg(mval *v, unsigned char argcode) { bool rval; mstr *obj, object; icode_str indir_src; error_def (ERR_INDEXTRACHARS); MV_FORCE_STR(v); assert(argcode >=3 && argcode < SIZEOF(indir_fcn) / SIZEOF(indir_fcn[0])); indir_src.str = v->str; indir_src.code = argcode; if (NULL == (obj = cache_get(&indir_src))) { if (((indir_do == argcode) || (indir_goto == argcode)) && (frame_pointer->type & SFT_COUNT) && v->str.len && (v->str.len < MAX_MIDENT_LEN) && !proc_act_type && do_indir_do(v, argcode)) { return; } comp_init(&v->str); for (;;) { if (!(rval = (*indir_fcn[argcode])())) break; if (TK_EOL == window_token) break; if (TK_COMMA == window_token) advancewindow(); else { /* Allow trailing spaces/comments that we will ignore */ while (TK_SPACE == window_token) advancewindow(); if (TK_EOL == window_token) break; rts_error(VARLSTCNT(1) ERR_INDEXTRACHARS); } } if (comp_fini(rval, &object, OC_RET, 0, v->str.len)) { indir_src.str.addr = v->str.addr; /* we reassign because v->str.addr might have been changed by stp_gcol() */ cache_put(&indir_src, &object); comp_indr(&object); if (indir_linetail == argcode) frame_pointer->type = SFT_COUNT; } } else { comp_indr(obj); if (indir_linetail == argcode) frame_pointer->type = SFT_COUNT; } }
void op_zhelp_xfr(mval *subject, mval *lib) { mstr x; mval *action; MV_FORCE_STR(subject); MV_FORCE_STR(lib); if (!lib->str.len) lib = &dlib; flush_pio(); action = push_mval(subject); action->mvtype = 0; action->str.len = SIZEOF("D ^GTMHELP(") - 1; action->str.addr = "D ^GTMHELP("; s2pool(&action->str); action->mvtype = MV_STR; mval_lex(subject, &x); if (x.addr == (char *)stringpool.free) { action->str.len += x.len; stringpool.free += x.len; } else op_cat(VARLSTCNT(3) action, action, subject); op_cat(VARLSTCNT(3) action, action, &com); /* add "," */ mval_lex(lib, &x); if (x.addr == (char *)stringpool.free) { action->str.len += x.len; stringpool.free += x.len; } else op_cat(VARLSTCNT(3) action, action, lib); op_cat(VARLSTCNT(3) action, action, &rpar); /* add ")" */ op_commarg(action,indir_linetail); }
/* compute post_incr_mval from the current value of gv_currkey that was just now searched down the tree */ enum cdb_sc gvincr_compute_post_incr(srch_blk_status *bh) { int4 cur_blk_size; sm_uc_ptr_t buffaddr; rec_hdr_ptr_t rp; unsigned short rec_size; int4 target_key_size, data_len; uint4 gvincr_malloc_len; mval pre_incr_mval; int tmp_cmpc; buffaddr = bh->buffaddr; cur_blk_size = ((blk_hdr_ptr_t)buffaddr)->bsiz; rp = (rec_hdr_ptr_t)(buffaddr + bh->curr_rec.offset); GET_USHORT(rec_size, &rp->rsiz); target_key_size = bh->curr_rec.match; assert(target_key_size == gv_currkey->end + 1); data_len = rec_size + EVAL_CMPC(rp) - SIZEOF(rec_hdr) - target_key_size; if ((0 > data_len) || (((sm_uc_ptr_t)rp + rec_size) > ((sm_uc_ptr_t)buffaddr + cur_blk_size))) { assert(CDB_STAGNATE > t_tries); return cdb_sc_rmisalign; } if (data_len > gvincr_pre_incr_bufflen) { if (NULL != gvincr_pre_incr_buff) free(gvincr_pre_incr_buff); gvincr_malloc_len = (data_len > GVINCR_PRE_INCR_MIN_BUFFLEN) ? data_len : GVINCR_PRE_INCR_MIN_BUFFLEN; gvincr_pre_incr_buff = (char *)malloc(gvincr_malloc_len); gvincr_pre_incr_bufflen = gvincr_malloc_len; } /* malloced buffer is used for pre_incr_mval instead of stringpool because this is memory that is * inherently used only by $INCREMENT and is needed only during the lifetime of the increment. * keeping it in the stringpool causes it to stay until the next garbage collection which adds * to unnecessary overheads. */ pre_incr_mval.mvtype = MV_STR; pre_incr_mval.str.addr = (char *)gvincr_pre_incr_buff; pre_incr_mval.str.len = data_len; memcpy(pre_incr_mval.str.addr, (sm_uc_ptr_t)rp + rec_size - data_len, data_len); op_add(&pre_incr_mval, &increment_delta_mval, post_incr_mval); assert(MV_IS_NUMERIC(post_incr_mval)); /* "post_incr_mval" is of numeric type, convert it to a string type so it can be used by the caller to set "value" */ MV_FORCE_STR(post_incr_mval); /* will use stringpool to store string representation */ /* "post_incr_mval" is a copy of the mval pointer passed to "op_gvincr" and hence is on the M-stack * and therefore is known to the garbage collector (stp_gcol). hence it is ok for it to use the stringpool */ return cdb_sc_normal; }
void op_fnzconvert3(mval *src, mval* ichset, mval* ochset, mval* dst) { UConverter *from, *to; int dstlen; MV_FORCE_STR(src); if (!gtm_utf8_mode) { /* Unicode not enabled, report error rather than silently ignoring the conversion */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_INVFCN, 0, ERR_TEXT, 2, LEN_AND_LIT("Three-argument form of $ZCONVERT() is not allowed in the current $ZCHSET")); } MV_FORCE_STR(ichset); MV_FORCE_STR(ochset); /* The only supported names are: "UTF-8", "UTF-16", "UTF-16LE" and "UTF-16BE */ if (NULL == (from = get_chset_desc(&ichset->str))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_BADCHSET, 2, ichset->str.len, ichset->str.addr); if (NULL == (to = get_chset_desc(&ochset->str))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_BADCHSET, 2, ochset->str.len, ochset->str.addr); dstlen = gtm_conv(from, to, &src->str, NULL, NULL); assert(-1 != dstlen); MV_INIT_STRING(dst, dstlen, stringpool.free); stringpool.free += dst->str.len; }
/* pkeys MUST be a va_list initialized in the caller via a va_start */ unsigned char *undx (lv_val *start, va_list pkeys, int cnt, unsigned char *buff, unsigned short size) { static lvname_info_ptr lvn_info = NULL; int cur_subscr; if (!lvn_info) lvn_info = (lvname_info_ptr) malloc(SIZEOF(struct lvname_info_struct)); lvn_info->total_lv_subs = cnt + 1; lvn_info->start_lvp = start; for (cur_subscr = 0; cur_subscr < cnt; cur_subscr++) { lvn_info->lv_subs[cur_subscr] = va_arg(pkeys, mval *); MV_FORCE_STR(lvn_info->lv_subs[cur_subscr]); } return(format_key_mvals(buff, size, lvn_info)); }
void op_indlvarg(mval *v, mval *dst) { icode_str indir_src; int rval; mstr *obj, object; oprtype x; triple *ref; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (TREF(ind_result_sp) >= TREF(ind_result_top)) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); /* mdbcondition_handler resets ind_result_sp */ MV_FORCE_STR(v); if (v->str.len < 1) rts_error(VARLSTCNT(1) ERR_VAREXPECTED); if (valid_mname(&v->str)) { *dst = *v; dst->mvtype &= ~MV_ALIASCONT; /* Make sure alias container property does not pass */ return; } if (*v->str.addr != '@') rts_error(VARLSTCNT(1) ERR_VAREXPECTED); indir_src.str = v->str; indir_src.code = indir_lvarg; if (NULL == (obj = cache_get(&indir_src))) { obj = &object; obj->addr = v->str.addr; obj->len = v->str.len; comp_init(obj); if (EXPR_FAIL != (rval = indirection(&x))) /* NOTE assignment */ { ref = newtriple(OC_INDLVARG); ref->operand[0] = x; x = put_tref(ref); } if (EXPR_FAIL == comp_fini(rval, obj, OC_IRETMVAL, &x, obj->len)) return; indir_src.str.addr = v->str.addr; cache_put(&indir_src, obj); /* Fall into code activation below */ } *(TREF(ind_result_sp))++ = dst; /* Where to store return value */ comp_indr(obj); return; }
STATICFNDEF void gvtr_set_hasht_gblsubs(mval *subs_mval, mval *set_mval) { uint4 curend; boolean_t was_null = FALSE, is_null = FALSE; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; curend = gv_currkey->end; /* note down gv_currkey->end before changing it so we can restore it before function returns */ assert(KEY_DELIMITER == gv_currkey->base[curend]); assert(gv_target->gd_csa == cs_addrs); COPY_SUBS_TO_GVCURRKEY(subs_mval, gv_cur_region, gv_currkey, was_null, is_null); /* updates gv_currkey */ MV_FORCE_STR(set_mval); gvcst_put(set_mval); gv_currkey->end = curend; /* reset gv_currkey->end to what it was at function entry */ gv_currkey->base[curend] = KEY_DELIMITER; /* restore terminator for entire key so key is well-formed */ return; }
/* Set ^#t(<gbl>,"#TRHASH",hash_code,nnn)=<gbl>_$c(0)_trigindx where gv_currkey is ^#t(<gbl>). * Note: This routine has code very similar to that in "add_trigger_hash_entry". There is just * not enough commonality to justify merging the two. */ STATICFNDEF void gvtr_set_hashtrhash(char *trigvn, int trigvn_len, uint4 hash_code, int trigindx) { uint4 curend; mval mv_indx, *mv_indx_ptr; mval mv_hash; int hash_indx, num_len; char name_and_index[MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT]; char *ptr; char indx_str[MAX_DIGITS_IN_INT]; uint4 len; int4 result; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; curend = gv_currkey->end; /* note down gv_currkey->end before changing it so we can restore it before function returns */ assert(KEY_DELIMITER == gv_currkey->base[curend]); assert(gv_target->gd_csa == cs_addrs); /* Set ^#t(<gvn>,"#TRHASH",kill_hash_code,i). To do that, first determine the * highest i such that ^#t(<gvn>,"#TRHASH",kill_hash_code,i) exists. Set * ^#t(<gvn>,"#TRHASH",kill_hash_code,i+1)=kill_hash_code in that case. */ MV_FORCE_UMVAL(&mv_hash, hash_code); BUILD_HASHT_SUB_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, "", 0); op_zprevious(&mv_indx); mv_indx_ptr = &mv_indx; hash_indx = (0 == mv_indx.str.len) ? 1 : (mval2i(mv_indx_ptr) + 1); i2mval(mv_indx_ptr, hash_indx); MV_FORCE_STR(mv_indx_ptr); /* Prepare the value of the SET */ num_len = 0; I2A(indx_str, num_len, trigindx); assert(MAX_MIDENT_LEN >= trigvn_len); memcpy(name_and_index, trigvn, trigvn_len); ptr = name_and_index + trigvn_len; *ptr++ = '\0'; memcpy(ptr, indx_str, num_len); len = trigvn_len + 1 + num_len; /* Do the SET */ SET_TRIGGER_GLOBAL_SUB_SUB_MSUB_MSUB_STR(trigvn, trigvn_len, LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_indx, name_and_index, len, result); assert(PUT_SUCCESS == result); gv_currkey->end = curend; /* reset gv_currkey->end to what it was at function entry */ gv_currkey->base[curend] = KEY_DELIMITER; /* restore terminator for entire key so key is well-formed */ return; }
/* WARNING!!! - the it is left to the caller of this routine to protect the stringpool if appropriate */ void mval_lex(mval *v, mstr *output) { int space_needed, des_len; MV_FORCE_STR(v); if (MV_IS_CANONICAL(v)) *output = v->str; else { space_needed = ZWR_EXP_RATIO(v->str.len); ENSURE_STP_FREE_SPACE(space_needed); output->addr = (char *)stringpool.free; format2zwr((sm_uc_ptr_t)v->str.addr, v->str.len, (unsigned char *)output->addr, &des_len); output->len = des_len; /* need a temporary des_len since output->len is short on the VAX * and format2zwr expects an (int *) as the last parameter */ assert(space_needed >= output->len); } }
void op_indlvadr(mval *target) { error_def(ERR_VAREXPECTED); bool rval; mstr object, *obj; oprtype v; triple *s; MV_FORCE_STR(target); if (!(obj = cache_get(indir_lvadr, &target->str))) { comp_init(&target->str); switch (window_token) { case TK_IDENT: rval = lvn(&v, OC_PUTINDX, 0); if (comp_fini(rval, &object, OC_IRETMVAD, &v, target->str.len)) { cache_put(indir_lvadr, &target->str, &object); comp_indr(&object); } break; case TK_ATSIGN: if (rval = indirection(&v)) { s = newtriple(OC_INDLVADR); s->operand[0] = v; v = put_tref(s); if (comp_fini(rval, &object, OC_IRETMVAD, &v, target->str.len)) { cache_put(indir_lvadr, &target->str, &object); comp_indr(&object); } } break; default: stx_error(ERR_VAREXPECTED); break; } } else { comp_indr(obj); } }
void op_fnstack2(int level, mval *info, mval *result) { int cur_zlevel; stack_mode_t mode; unsigned char info_upper[SIZEOF("MCODE")]; error_def(ERR_INVSTACODE); mode = DOLLAR_STACK_INVALID; /* make sure that info is one of the three valid strings */ MV_FORCE_STR(info); /* force input string to null string in case it is undefined */ if (info->str.len == 5) { lower_to_upper(info_upper, (unsigned char *)info->str.addr, 5); if (!memcmp("MCODE", info_upper, SIZEOF("MCODE")-1)) mode = DOLLAR_STACK_MCODE; else if (!memcmp("ECODE", info_upper, SIZEOF("ECODE")-1)) mode = DOLLAR_STACK_ECODE; else if (!memcmp("PLACE", info_upper, SIZEOF("PLACE")-1)) mode = DOLLAR_STACK_PLACE; } if (DOLLAR_STACK_INVALID == mode) rts_error(VARLSTCNT(4) ERR_INVSTACODE, 2, info->str.len, info->str.addr); result->mvtype = MV_STR; result->str.len = 0; /* set result to null string before any processing */ cur_zlevel = dollar_zlevel(); if (0 <= level) { if (!dollar_stack.index) { if (level < cur_zlevel) { GET_FRAME_INFO(level, mode, cur_zlevel, result); } } else if (level < dollar_stack.index) get_dollar_stack_info(level, mode, result); else if (!dollar_stack.incomplete && (1 == dollar_ecode.index) && (error_frame == dollar_ecode.first_ecode_error_frame) && (level < cur_zlevel)) { GET_FRAME_INFO(level, mode, cur_zlevel, result); } } return; }
void op_write(mval *v) { GBLREF spdesc stringpool; size_t insize, outsize; int cnt; unsigned char *temp_ch; char *start_ptr, *save_ptr; MV_FORCE_STR(v); active_device = io_curr_device.out; #if defined(KEEP_zOS_EBCDIC) || defined(VMS) if (DEFAULT_CODE_SET != active_device->out_code_set) { cnt = insize = outsize = v->str.len; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); ENSURE_STP_FREE_SPACE(cnt); temp_ch = stringpool.free; save_ptr = v->str.addr; start_ptr = (char *)temp_ch; stringpool.free += cnt; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); ICONVERT(active_device->output_conv_cd, (unsigned char **)&v->str.addr, &insize, &temp_ch, &outsize); v->str.addr = start_ptr; } #endif (io_curr_device.out->disp_ptr->write)(&v->str); #if defined(KEEP_zOS_EBCDIC) || defined(VMS) if (DEFAULT_CODE_SET != active_device->out_code_set) v->str.addr = save_ptr; #endif active_device = 0; return; }
void op_inddevparms(mval *devpsrc, int4 ok_iop_parms, mval *devpiopl) { int rval; icode_str indir_src; mstr *obj, object; oprtype devpopr, plist, getdst; triple *indref; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; MV_FORCE_STR(devpsrc); indir_src.str = devpsrc->str; indir_src.code = indir_devparms; if (NULL == (obj = cache_get(&indir_src))) /* NOTE assignment */ { /* No cached version, compile it now */ obj = &object; comp_init(&devpsrc->str, &getdst); if (TK_ATSIGN == TREF(window_token)) { /* For the indirection-obsessive */ if (EXPR_FAIL != (rval = indirection(&devpopr))) /* NOTE assignment */ { indref = newtriple(OC_INDDEVPARMS); indref->operand[0] = devpopr; indref->operand[1] = put_ilit(ok_iop_parms); plist = put_tref(indref); } } else /* We have the parm string to process now */ rval = deviceparameters(&plist, ok_iop_parms); if (EXPR_FAIL == comp_fini(rval, obj, OC_IRETMVAL, &plist, &getdst, devpsrc->str.len)) return; indir_src.str.addr = devpsrc->str.addr; cache_put(&indir_src, obj); /* Fall into code activation below */ } TREF(ind_result) = devpiopl; /* Where to store return value */ comp_indr(obj); return; }
void setzdir(mval *newdir, mval *full_path_of_newdir) { /* newdir is the directory to change to; NULL to set full_path_of_newdir to current working directory. * If full_path_of_newdir is non NULL, return the full path of the new directory in full_path_of_newdir. * NOTE : the full path of directory is stored in a static buffer which might get overwritten by the next call to setzdir. * Callers should save return value if needed. */ char directory[GTM_MAX_DIR_LEN], *getcwd_res, *err_str; uint4 length, status; assert(NULL != newdir || NULL != full_path_of_newdir); if (NULL != newdir) { MV_FORCE_STR(newdir); assert(SIZEOF(directory) > newdir->str.len); memcpy(directory, newdir->str.addr, newdir->str.len); directory[newdir->str.len] = '\0'; if (-1 == CHDIR(directory)) { /* On VMS, chdir(directory, 0) [actually, any non 1 value] is supposed to restore the process startup cwd at * exit (see help cc run). We've noticed that it doesn't behave the way it has been documented in the mumps * executable. Vinaya, 08/22/2001. */ err_str = STRERROR(errno); rts_error(VARLSTCNT(8) ERR_SETZDIR, 2, newdir->str.len, newdir->str.addr, ERR_TEXT, 2, LEN_AND_STR(err_str)); } } /* We need to find the full path of the current working directory because newdir might be a relative path, in which case * $ZDIR will show up as a relative path. */ if (NULL != full_path_of_newdir) { GETCWD(directory_buffer, SIZEOF(directory_buffer), getcwd_res); if (NULL != getcwd_res) { length = USTRLEN(directory_buffer); UNIX_ONLY(directory_buffer[length++] = '/';) } else
void op_fnzbitnot(mval *dst,mval *bitstr) { int str_len; unsigned char *byte_1, *byte_n, *dist_byte, byte_len; int n; error_def(ERR_INVBITSTR); MV_FORCE_STR(bitstr); if (!bitstr->str.len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); byte_len = *(unsigned char *)bitstr->str.addr; str_len = (bitstr->str.len -1) * 8; if ((byte_len < 0) || (byte_len > 7)) { rts_error(VARLSTCNT(1) ERR_INVBITSTR); } if (stringpool.top - stringpool.free < bitstr->str.len) stp_gcol(bitstr->str.len); byte_1 = (unsigned char *)bitstr->str.addr; dist_byte = (unsigned char *)stringpool.free; *dist_byte = *byte_1; dist_byte++; n = bitstr->str.len; for (byte_n = byte_1 + 1; byte_n <= (byte_1 + n); byte_n++, dist_byte++) { *dist_byte = ~(*byte_n); } dst->mvtype = MV_STR; dst->str.addr = (char *)stringpool.free; dst->str.len = bitstr->str.len; stringpool.free += bitstr->str.len; }
/* Routine to compute the display width of a string */ void op_fnzwidth(mval* src, mval* dst) { unsigned char *srctop, *srcptr, *nextptr; int width; MV_FORCE_STR(src); srcptr = (unsigned char *)src->str.addr; #ifdef UNICODE_SUPPORTED if (!gtm_utf8_mode) { #endif width = src->str.len; for (srctop = srcptr + src->str.len; srcptr < srctop; ++srcptr) { /* All non-control characters are printable. Control characters are ignored (=0 width) in width calculations. */ if ((pattern_typemask[*srcptr] & PATM_C)) width -= 1; } #ifdef UNICODE_SUPPORTED } else width = gtm_wcswidth(srcptr, src->str.len, TRUE, 0); /* TRUE => strict checking of BADCHARs */ #endif MV_FORCE_MVAL(dst, width); }