void op_fnstack1(int level, mval *result) { int cur_zlevel; result->mvtype = MV_STR; cur_zlevel = dollar_zlevel(); if (-1 == level) { if (!dollar_ecode.index) { MV_FORCE_MVAL(result, cur_zlevel - 1); } else if ((1 < dollar_ecode.index) || (error_frame != dollar_ecode.first_ecode_error_frame)) MV_FORCE_MVAL(result, dollar_stack.index - 1); else { /* we are in first ECODE error-handler */ if (cur_zlevel > dollar_stack.index) { MV_FORCE_MVAL(result, cur_zlevel - 1); } else { MV_FORCE_MVAL(result, dollar_stack.index - 1); } } } else if (0 > level) result->str.len = 0; else if (0 == level) get_command_line(result, FALSE); /* FALSE to indicate we want actual (not processed) command line */ else if (!dollar_stack.index) { if (level < cur_zlevel) get_frame_creation_info(level, cur_zlevel, result); else result->str.len = 0; } else if (level < dollar_stack.index) get_dollar_stack_info(level, DOLLAR_STACK_MODE, result); else if (!dollar_stack.incomplete && (1 == dollar_ecode.index) && (error_frame == dollar_ecode.first_ecode_error_frame) && (level < cur_zlevel)) get_frame_creation_info(level, cur_zlevel, result); else result->str.len = 0; return; }
/* * ----------------------------------------------- * op_fnqlength() * MUMPS QLength function * * Arguments: * src - Pointer to Source Name string mval * dst - destination buffer to save the piece in * Return: * none * ----------------------------------------------- */ void op_fnqlength(mval *src, mval *dst) { int dummy1; int dummy2; int subscripts = -2; /* no interest in finding a particular component */ error_def(ERR_NOCANONICNAME); if (!is_canonic_name(src, &subscripts, &dummy1, &dummy2)) rts_error(VARLSTCNT(4) ERR_NOCANONICNAME, 2, src->str.len, src->str.addr); MV_FORCE_MVAL(dst, subscripts); /* is_canonic_name has to parse anyway, so take count from it */ return; }
void zsrch_clr (int indx) { lv_val *tmp; mval x; MV_FORCE_MVAL(&x, indx); op_kill(zsrch_dir1); op_kill(zsrch_dir2); tmp = op_srchindx(VARLSTCNT(2) zsrch_var, &x); op_kill(tmp); }
void ztrap_save_ctxt(void) { int level; error_def(ERR_STACKOFLOW); error_def(ERR_STACKCRIT); level = dollar_zlevel(); if (level == MV_FORCE_INT(&ztrap_pop2level)) return; PUSH_MV_STENT(MVST_MSAV); mv_chain->mv_st_cont.mvs_msav.v = ztrap_pop2level; mv_chain->mv_st_cont.mvs_msav.addr = &ztrap_pop2level; MV_FORCE_MVAL(&ztrap_pop2level, level); return; }
/* 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); }
void op_fnlength(mval *src, mval *dest) { MV_FORCE_STR(src); MV_FORCE_LEN(src); MV_FORCE_MVAL(dest, (int)src->str.char_len); }
void trigger_delete_all(void) { int count; char count_str[MAX_DIGITS_IN_INT + 1]; sgmnt_addrs *csa; mval curr_gbl_name; int cycle; mstr gbl_name; mname_entry gvent; gv_namehead *hasht_tree, *gvt; mval *mv_count_ptr; mval *mv_cycle_ptr; mval mv_indx; gd_region *reg; int reg_indx; int4 result; char save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)]; gv_key *save_gv_currkey; gd_region *save_gv_cur_region; gv_namehead *save_gv_target; sgm_info *save_sgm_info_ptr; int trig_indx; mval trigger_cycle; mval trigger_count; mval val; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(0 < dollar_tlevel); /* Before we delete any triggers, verify that none of the triggers have been fired in this transaction. If they have, * this creates an un-commitable transaction that will end in a TPFAIL error. Since that error indicates database * damage, we'd rather detect this avoidable condition and give a descriptive error instead (TRIGMODINTP). */ for (gvt = gv_target_list; NULL != gvt; gvt = gvt->next_gvnh) { if (gvt->trig_local_tn == local_tn) rts_error(VARLSTCNT(1) ERR_TRIGMODINTP); } SWITCH_TO_DEFAULT_REGION; INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED; if (0 != gv_target->root) { /* kill ^#t("#TRHASH") */ BUILD_HASHT_SUB_CURRKEY(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH)); gvcst_kill(TRUE); /* kill ^#t("#TNAME") */ BUILD_HASHT_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME)); gvcst_kill(TRUE); } for (reg_indx = 0, reg = gd_header->regions; reg_indx < gd_header->n_regions; reg_indx++, reg++) { if (!reg->open) gv_init_reg(reg); if (!reg->read_only) { gv_cur_region = reg; change_reg(); csa = cs_addrs; SETUP_TRIGGER_GLOBAL; INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED; /* There might not be any ^#t in this region, so check */ if (0 != gv_target->root) { /* Kill all descendents of ^#t(trigvn, indx) where trigvn is any global with a trigger, * but skip the "#XYZ" entries. setup ^#t(trigvn,"$") as the PREV key for op_gvorder */ BUILD_HASHT_SUB_CURRKEY(LITERAL_MAXHASHVAL, STRLEN(LITERAL_MAXHASHVAL)); TREF(gv_last_subsc_null) = FALSE; /* We know its not null, but prior state is unreliable */ while (TRUE) { op_gvorder(&curr_gbl_name); /* quit:$length(curr_gbl_name)=0 */ if (0 == curr_gbl_name.str.len) break; /* $get(^#t(curr_gbl_name,#COUNT)) */ BUILD_HASHT_SUB_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len, LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT)); if (gvcst_get(&trigger_count)) { mv_count_ptr = &trigger_count; count = MV_FORCE_INT(mv_count_ptr); /* $get(^#t(curr_gbl_name,#CYCLE)) */ BUILD_HASHT_SUB_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len, LITERAL_HASHCYCLE, STRLEN(LITERAL_HASHCYCLE)); if (!gvcst_get(&trigger_cycle)) assert(FALSE); /* Found #COUNT, there must be #CYCLE */ mv_cycle_ptr = &trigger_cycle; cycle = MV_FORCE_INT(mv_cycle_ptr); /* kill ^#t(curr_gbl_name) */ BUILD_HASHT_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len); gvcst_kill(TRUE); cycle++; MV_FORCE_MVAL(&trigger_cycle, cycle); /* set ^#t(curr_gbl_name,#CYCLE)=trigger_cycle */ SET_TRIGGER_GLOBAL_SUB_SUB_MVAL(curr_gbl_name.str.addr, curr_gbl_name.str.len, LITERAL_HASHCYCLE, STRLEN(LITERAL_HASHCYCLE), trigger_cycle, result); assert(PUT_SUCCESS == result); } /* else there is no #COUNT, then no triggers, leave #CYCLE alone */ /* get ready for op_gvorder() call for next trigger under ^#t */ BUILD_HASHT_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len); } csa->incr_db_trigger_cycle = TRUE; if (dollar_ztrigger_invoked) { /* increment db_dztrigger_cycle so that next gvcst_put/gvcst_kill in this transaction, * on this region, will re-read. See trigger_update.c for a comment on why it is okay * for db_dztrigger_cycle to be incremented more than once in the same transaction */ csa->db_dztrigger_cycle++; } } } } util_out_print_gtmio("All existing triggers deleted", FLUSH); }
int4 trigger_delete(char *trigvn, int trigvn_len, mval *trigger_count, int index) { int count; mval *mv_cnt_ptr; mval mv_val; mval *mv_val_ptr; int num_len; char *ptr1; int4 result; int4 retval; char save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)]; gv_key *save_gv_currkey; stringkey kill_hash, set_hash; int sub_indx; char tmp_trig_str[MAX_BUFF_SIZE]; int4 trig_len; char trig_name[MAX_TRIGNAME_LEN]; int trig_name_len; int tmp_len; char *tt_val[NUM_SUBS]; uint4 tt_val_len[NUM_SUBS]; mval trigger_value; mval trigger_index; mval xecute_index; uint4 xecute_idx; uint4 used_trigvn_len; mval val; char val_str[MAX_DIGITS_IN_INT + 1]; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; mv_val_ptr = &mv_val; MV_FORCE_MVAL(&trigger_index, index); count = MV_FORCE_INT(trigger_count); /* build up array of values - needed for comparison in hash stuff */ ptr1 = tmp_trig_str; memcpy(ptr1, trigvn, trigvn_len); ptr1 += trigvn_len; *ptr1++ = '\0'; tmp_len = trigvn_len + 1; for (sub_indx = 0; sub_indx < NUM_SUBS; sub_indx++) { BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, trigger_index, trigger_subs[sub_indx], STRLEN(trigger_subs[sub_indx])); trig_len = gvcst_get(&trigger_value) ? trigger_value.str.len : 0; if (0 == trig_len) { tt_val[sub_indx] = NULL; tt_val_len[sub_indx] = 0; continue; } if (TRIGNAME_SUB == sub_indx) { trig_name_len = trig_len; assert(MAX_TRIGNAME_LEN >= trig_len); memcpy(trig_name, trigger_value.str.addr, trig_name_len); tt_val[sub_indx] = NULL; tt_val_len[sub_indx] = 0; continue; } tt_val[sub_indx] = ptr1; tt_val_len[sub_indx] = trig_len; tmp_len += trig_len; if (0 < trig_len) { if (MAX_BUFF_SIZE <= tmp_len) return VAL_TOO_LONG; memcpy(ptr1, trigger_value.str.addr, trig_len); ptr1 += trig_len; } *ptr1++ = '\0'; tmp_len++; } /* Get trigger name, set hash value, and kill hash values from trigger before we delete it. * The values will be used in clean ups associated with the deletion */ /* $get(^#t(GVN,trigger_index,"LHASH") for deletion in cleanup_trigger_hash */ BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, trigger_index, trigger_subs[LHASH_SUB], STRLEN(trigger_subs[LHASH_SUB])); if (gvcst_get(mv_val_ptr)) kill_hash.hash_code = (uint4)MV_FORCE_INT(mv_val_ptr); else { util_out_print_gtmio("The LHASH for global ^!AD does not exist", FLUSH, trigvn_len, trigvn); kill_hash.hash_code = 0; } /* $get(^#t(GVN,trigger_index,"BHASH") for deletion in cleanup_trigger_hash */ BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, trigger_index, trigger_subs[BHASH_SUB], STRLEN(trigger_subs[BHASH_SUB])); if (gvcst_get(mv_val_ptr)) set_hash.hash_code = (uint4)MV_FORCE_INT(mv_val_ptr); else { util_out_print_gtmio("The BHASH for global ^!AD does not exist", FLUSH, trigvn_len, trigvn); set_hash.hash_code = 0; } /* kill ^#t(GVN,trigger_index) */ BUILD_HASHT_SUB_MSUB_CURRKEY(trigvn, trigvn_len, trigger_index); gvcst_kill(TRUE); assert(0 == gvcst_data()); if (1 == count) { /* This is the last trigger for "trigvn" - clean up trigger name, remove #LABEL and #COUNT */ assert(1 == index); BUILD_HASHT_SUB_SUB_CURRKEY(trigvn, trigvn_len, LITERAL_HASHLABEL, STRLEN(LITERAL_HASHLABEL)); gvcst_kill(TRUE); BUILD_HASHT_SUB_SUB_CURRKEY(trigvn, trigvn_len, LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT)); gvcst_kill(TRUE); cleanup_trigger_name(trigvn, trigvn_len, trig_name, trig_name_len); cleanup_trigger_hash(trigvn, trigvn_len, tt_val, tt_val_len, &set_hash, &kill_hash, TRUE, 0); } else { cleanup_trigger_hash(trigvn, trigvn_len, tt_val, tt_val_len, &set_hash, &kill_hash, TRUE, index); cleanup_trigger_name(trigvn, trigvn_len, trig_name, trig_name_len); if (index != count) { /* Shift the last trigger (index is #COUNT value) to the just deleted trigger's index. * This way count is always accurate and can still be used as the index for new triggers. * Note - there is no dependence on the trigger order, or this technique wouldn't work. */ ptr1 = tmp_trig_str; memcpy(ptr1, trigvn, trigvn_len); ptr1 += trigvn_len; *ptr1++ = '\0'; for (sub_indx = 0; sub_indx < NUM_TOTAL_SUBS; sub_indx++) { /* $get(^#t(GVN,trigger_count,sub_indx) */ BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, *trigger_count, trigger_subs[sub_indx], STRLEN(trigger_subs[sub_indx])); if (gvcst_get(&trigger_value)) { trig_len = trigger_value.str.len; /* set ^#t(GVN,trigger_index,sub_indx)=^#t(GVN,trigger_count,sub_indx) */ SET_TRIGGER_GLOBAL_SUB_MSUB_SUB_MVAL(trigvn, trigvn_len, trigger_index, trigger_subs[sub_indx], STRLEN(trigger_subs[sub_indx]), trigger_value, result); assert(PUT_SUCCESS == result); } else if (XECUTE_SUB == sub_indx) { /* multi line trigger broken up because it exceeds record size */ for (xecute_idx = 0; ; xecute_idx++) { i2mval(&xecute_index, xecute_idx); BUILD_HASHT_SUB_MSUB_SUB_MSUB_CURRKEY(trigvn, trigvn_len, *trigger_count, trigger_subs[sub_indx], STRLEN(trigger_subs[sub_indx]), xecute_index); if (!gvcst_get(&trigger_value)) break; SET_TRIGGER_GLOBAL_SUB_MSUB_SUB_MSUB_MVAL(trigvn, trigvn_len, trigger_index, trigger_subs[sub_indx], STRLEN(trigger_subs[sub_indx]), xecute_index, trigger_value, result); assert(PUT_SUCCESS == result); } assert (xecute_idx >= 2); /* multi-line trigger, indices 0, 1 and 2 MUST be defined */ } else { /* in PRO this is a nasty case that will result in an access violation * because data that should be present is not. In the next go around * with trigger installation this case should be handled better */ assert(!((TRIGNAME_SUB == sub_indx) || (CMD_SUB == sub_indx) || (CHSET_SUB == sub_indx))); /* these should not be zero length */ trig_len = 0; } if (NUM_SUBS > sub_indx) { tt_val[sub_indx] = ptr1; tt_val_len[sub_indx] = trig_len; if (0 < trig_len) { memcpy(ptr1, trigger_value.str.addr, trig_len); ptr1 += trig_len; } *ptr1++ = '\0'; } } /* $get(^#t(GVN,trigger_count,"LHASH") for update_trigger_hash_value */ BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, *trigger_count, trigger_subs[LHASH_SUB], STRLEN(trigger_subs[LHASH_SUB])); if (!gvcst_get(mv_val_ptr)) return PUT_SUCCESS; kill_hash.hash_code = (uint4)MV_FORCE_INT(mv_val_ptr); /* $get(^#t(GVN,trigger_count,"BHASH") for update_trigger_hash_value */ BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, *trigger_count, trigger_subs[BHASH_SUB], STRLEN(trigger_subs[BHASH_SUB])); if (!gvcst_get(mv_val_ptr)) return PUT_SUCCESS; set_hash.hash_code = (uint4)MV_FORCE_INT(mv_val_ptr); /* update hash values from above */ if (VAL_TOO_LONG == (retval = update_trigger_hash_value(trigvn, trigvn_len, tt_val, tt_val_len, &set_hash, &kill_hash, count, index))) return VAL_TOO_LONG; /* fix the value ^#t("#TNAME",^#t(GVN,index,"#TRIGNAME")) to point to the correct "index" */ if (VAL_TOO_LONG == (retval = update_trigger_name_value(trigvn_len, tt_val[TRIGNAME_SUB], tt_val_len[TRIGNAME_SUB], index))) return VAL_TOO_LONG; /* kill ^#t(GVN,COUNT) which was just shifted to trigger_index */ BUILD_HASHT_SUB_MSUB_CURRKEY(trigvn, trigvn_len, *trigger_count); gvcst_kill(TRUE); } /* Update #COUNT */ count--; MV_FORCE_MVAL(trigger_count, count); SET_TRIGGER_GLOBAL_SUB_SUB_MVAL(trigvn, trigvn_len, LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT), *trigger_count, result); assert(PUT_SUCCESS == result); /* Size of count can only get shorter or stay the same */ } trigger_incr_cycle(trigvn, trigvn_len); return PUT_SUCCESS; }
short rc_fnd_file(rc_xdsid *xdsid) { gv_namehead *g; short dsid, node; gd_binding *map; char buff[1024], *cp, *cp1; mstr fpath1, fpath2; mval v; int i, keysize; int len, node2; GET_SHORT(dsid, &xdsid->dsid.value); GET_SHORT(node, &xdsid->node.value); if (!dsid_list) { /* open special database, set up entry */ dsid_list = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list)); dsid_list->dsid = RC_NSPACE_DSID; dsid_list->next = NULL; fpath1.addr = RC_NSPACE_PATH; fpath1.len = SIZEOF(RC_NSPACE_PATH); if (SS_NORMAL != TRANS_LOG_NAME(&fpath1, &fpath2, buff, SIZEOF(buff), do_sendmsg_on_log2long)) { char msg[256]; SPRINTF(msg, "Invalid DB filename, \"%s\"", fpath1.addr); gtcm_rep_err(msg, errno); return RC_BADFILESPEC; } if (fpath2.len > MAX_FN_LEN) return RC_BADFILESPEC; dsid_list->fname = (char *)malloc(fpath2.len + 1); memcpy(dsid_list->fname, fpath2.addr, fpath2.len); *((char*)(dsid_list->fname + fpath2.len)) = 0; gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region)); memset(gv_cur_region, 0, SIZEOF(gd_region)); gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment)); memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment)); memcpy(gv_cur_region->dyn.addr->fname, fpath2.addr, fpath2.len); gv_cur_region->dyn.addr->fname_len = fpath2.len; gv_cur_region->dyn.addr->acc_meth = dba_bg; ESTABLISH_RET(rc_fnd_file_ch1, RC_SUCCESS); gvcst_init(gv_cur_region); REVERT; change_reg(); /* check to see if this DB has the reserved bytes field set * correctly. Global pages must always have some extra unused * space left in them (RC_RESERVED bytes) so that the page * will fit into the client buffer when unpacked by the * client. */ if (cs_data->reserved_bytes < RC_RESERVED) { OMI_DBG((omi_debug, "Unable to access database file: \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n", fpath2.addr)); free(dsid_list->fname); dsid_list->fname = NULL; free(dsid_list); dsid_list = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } gv_keysize = DBKEYSIZE(gv_cur_region->max_key_size); GVKEY_INIT(gv_currkey, gv_keysize); GVKEY_INIT(gv_altkey, gv_keysize); cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (gv_keysize - 1)); g = cs_addrs->dir_tree; g->first_rec = (gv_key*)(g->clue.base + gv_keysize); g->last_rec = (gv_key*)(g->first_rec->base + gv_keysize); g->clue.top = g->last_rec->top = g->first_rec->top = gv_keysize; g->clue.prev = g->clue.end = 0; g->root = DIR_ROOT; dsid_list->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding)); dsid_list->gda->n_maps = 3; dsid_list->gda->n_regions = 1; dsid_list->gda->n_segments = 1; dsid_list->gda->maps = (gd_binding*)((char*)dsid_list->gda + SIZEOF(gd_addr)); dsid_list->gda->max_rec_size = gv_cur_region->max_rec_size; map = dsid_list->gda->maps; map ++; memset(map->name, 0, SIZEOF(map->name)); map->name[0] = '%'; map->reg.addr = gv_cur_region; map++; map->reg.addr = gv_cur_region; memset(map->name, -1, SIZEOF(map->name)); dsid_list->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname)); init_hashtab_mname(dsid_list->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE); change_reg(); if (rc_overflow->top < cs_addrs->hdr->blk_size) { if (rc_overflow->buff) free(rc_overflow->buff); rc_overflow->top = cs_addrs->hdr->blk_size; rc_overflow->buff = (char*)malloc(rc_overflow->top); if (rc_overflow_size < rc_overflow->top) rc_overflow_size = rc_overflow->top; } } for (fdi_ptr = dsid_list; fdi_ptr && (fdi_ptr->dsid != dsid); fdi_ptr = fdi_ptr->next) ; if (!fdi_ptr) { /* need to open new database, add to list, set fdi_ptr */ gd_header = dsid_list->gda; gv_currkey->end = 0; v.mvtype = MV_STR; v.str.len = RC_NSPACE_GLOB_LEN-1; v.str.addr = RC_NSPACE_GLOB; GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str); if (!gv_target->root) /* No namespace global */ return RC_UNDEFNAMSPC; v.mvtype = MV_STR; v.str.len = SIZEOF(RC_NSPACE_DSI_SUB)-1; v.str.addr = RC_NSPACE_DSI_SUB; mval2subsc(&v,gv_currkey); node2 = node; MV_FORCE_MVAL(&v,node2); mval2subsc(&v,gv_currkey); i = dsid / 256; MV_FORCE_MVAL(&v,i); mval2subsc(&v,gv_currkey); if (gvcst_get(&v)) return RC_UNDEFNAMSPC; for (cp = v.str.addr, i = 1; i < RC_FILESPEC_PIECE; i++) for (; *cp++ != RC_FILESPEC_DELIM; ) ; for (cp1 = cp; *cp1++ != RC_FILESPEC_DELIM; ) ; cp1--; len = (int)(cp1 - cp); if (len > MAX_FN_LEN) return RC_BADFILESPEC; fdi_ptr = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list)); fdi_ptr->fname = (char *)malloc(len+1); fdi_ptr->dsid = dsid; memcpy(fdi_ptr->fname, cp, len); *(fdi_ptr->fname + (len)) = 0; gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region)); memset(gv_cur_region, 0, SIZEOF(gd_region)); gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment)); memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment)); memcpy(gv_cur_region->dyn.addr->fname, cp, len); gv_cur_region->dyn.addr->fname_len = len; gv_cur_region->dyn.addr->acc_meth = dba_bg; ESTABLISH_RET(rc_fnd_file_ch2, RC_SUCCESS); gvcst_init(gv_cur_region); REVERT; change_reg(); /* check to see if this DB has the reserved bytes field set * correctly. Global pages must always have some extra unused * space left in them (RC_RESERVED bytes) so that the page * will fit into the client buffer when unpacked by the * client. */ if (cs_data->reserved_bytes < RC_RESERVED) { OMI_DBG((omi_debug, "Unable to access database file: \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n", fdi_ptr->fname)); free(dsid_list->fname); dsid_list->fname = NULL; free(dsid_list); dsid_list = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } assert(!cs_addrs->hold_onto_crit); /* this ensures we can safely do unconditional grab_crit and rel_crit */ grab_crit(gv_cur_region); cs_data->rc_srv_cnt++; if (!cs_data->dsid) { cs_data->dsid = dsid; cs_data->rc_node = node; } else if (cs_data->dsid != dsid || cs_data->rc_node != node) { cs_data->rc_srv_cnt--; rel_crit(gv_cur_region); OMI_DBG((omi_debug, "Dataset ID/RC node mismatch")); OMI_DBG((omi_debug, "DB file: \"%s\"\n", dsid_list->fname)); OMI_DBG((omi_debug, "Stored DSID: %d\tRC Node: %d\n", cs_data->dsid, cs_data->rc_node)); OMI_DBG((omi_debug, "RC Rq DSID: %d\tRC Node: %d\n", dsid,node)); free(fdi_ptr->fname); fdi_ptr->fname = NULL; free(fdi_ptr); fdi_ptr = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } rel_crit(gv_cur_region); keysize = DBKEYSIZE(gv_cur_region->max_key_size); GVKEYSIZE_INCREASE_IF_NEEDED(keysize); cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (keysize - 1)); g = cs_addrs->dir_tree; g->first_rec = (gv_key*)(g->clue.base + keysize); g->last_rec = (gv_key*)(g->first_rec->base + keysize); g->clue.top = g->last_rec->top = g->first_rec->top = keysize; g->clue.prev = g->clue.end = 0; g->root = DIR_ROOT; fdi_ptr->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding)); fdi_ptr->gda->n_maps = 3; fdi_ptr->gda->n_regions = 1; fdi_ptr->gda->n_segments = 1; fdi_ptr->gda->maps = (gd_binding*)((char*)fdi_ptr->gda + SIZEOF(gd_addr)); fdi_ptr->gda->max_rec_size = gv_cur_region->max_rec_size; map = fdi_ptr->gda->maps; map ++; memset(map->name, 0, SIZEOF(map->name)); map->name[0] = '%'; map->reg.addr = gv_cur_region; map++; map->reg.addr = gv_cur_region; memset(map->name, -1, SIZEOF(map->name)); fdi_ptr->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname)); init_hashtab_mname(fdi_ptr->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE); fdi_ptr->next = dsid_list->next; dsid_list->next = fdi_ptr; } gv_cur_region = fdi_ptr->gda->maps[1].reg.addr; change_reg(); if (rc_overflow->top < cs_addrs->hdr->blk_size) { if (rc_overflow->buff) free(rc_overflow->buff); rc_overflow->top = cs_addrs->hdr->blk_size; rc_overflow->buff = (char*)malloc(rc_overflow->top); if (rc_overflow_size < rc_overflow->top) rc_overflow_size = rc_overflow->top; } if (!rc_overflow -> top) { rc_overflow -> top = rc_overflow_size; rc_overflow->buff = (char *)malloc(rc_overflow->top); } gd_header = fdi_ptr->gda; return RC_SUCCESS; }
int m_merge(void) { int type; boolean_t used_glvn_slot; mval mv; opctype put_oc; oprtype mopr, control_slot; triple *obp, *ref, *restart, *s1, *sub, tmpchain; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; used_glvn_slot = FALSE; sub = NULL; restart = newtriple(OC_RESTARTPC); /* Here is where a restart should pick up */ dqinit(&tmpchain, exorder); /* Left Hand Side of EQUAL sign */ switch (TREF(window_token)) { case TK_IDENT: if (!lvn(&mopr, OC_PUTINDX, 0)) return FALSE; if (OC_PUTINDX == mopr.oprval.tref->opcode) { /* we insert left hand side argument into tmpchain. */ sub = mopr.oprval.tref; put_oc = OC_PUTINDX; dqdel(mopr.oprval.tref, exorder); dqins(tmpchain.exorder.bl, exorder, mopr.oprval.tref); } ref = maketriple(OC_MERGE_LVARG); ref->operand[0] = put_ilit(MARG1_LCL); ref->operand[1] = mopr; dqins(tmpchain.exorder.bl, exorder, ref); break; case TK_CIRCUMFLEX: s1 = (TREF(curtchain))->exorder.bl; if (!gvn()) return FALSE; assert(OC_GVRECTARG != (TREF(curtchain))->opcode); /* we count on gvn not having been shifted */ for (sub = (TREF(curtchain))->exorder.bl; sub != s1; sub = sub->exorder.bl) { put_oc = sub->opcode; if (OC_GVNAME == put_oc || OC_GVNAKED == put_oc || OC_GVEXTNAM == put_oc) break; } assert((OC_GVNAME == put_oc) || (OC_GVNAKED == put_oc) || (OC_GVEXTNAM == put_oc)); /* we insert left hand side argument into tmpchain. */ dqdel(sub, exorder); dqins(tmpchain.exorder.bl ,exorder, sub); ref = maketriple(OC_MERGE_GVARG); ref->operand[0] = put_ilit(MARG1_GBL); dqins(tmpchain.exorder.bl, exorder, ref); break; case TK_ATSIGN: if (!indirection(&mopr)) return FALSE; if (TK_EQUAL != TREF(window_token)) { ref = newtriple(OC_COMMARG); ref->operand[0] = mopr; ref->operand[1] = put_ilit((mint) indir_merge); return TRUE; } type = MARG1_LCL | MARG1_GBL; memset(&mv, 0, SIZEOF(mval)); /* Initialize so unused fields don't cause object hash differences */ MV_FORCE_MVAL(&mv, type); MV_FORCE_STRD(&mv); if (TREF(side_effect_handling)) { /* save and restore the variable lookup for true left-to-right evaluation */ used_glvn_slot = TRUE; INSERT_INDSAVGLVN(control_slot, mopr, ANY_SLOT, 0); /* 0 flag to defer global reference */ ref = maketriple(OC_INDMERGE2); ref->operand[0] = control_slot; } else { /* quick and dirty old way */ ref = maketriple(OC_INDMERGE); ref->operand[0] = put_lit(&mv); ref->operand[1] = mopr; } /* we insert left hand side argument into tmpchain. */ dqins(tmpchain.exorder.bl, exorder, ref); break; default: stx_error(ERR_VAREXPECTED); return FALSE; } if (TREF(window_token) != TK_EQUAL) { stx_error(ERR_EQUAL); return FALSE; } advancewindow(); /* Right Hand Side of EQUAL sign */ TREF(temp_subs) = FALSE; switch (TREF(window_token)) { case TK_IDENT: if (!lvn(&mopr, OC_M_SRCHINDX, 0)) return FALSE; ref = newtriple(OC_MERGE_LVARG); ref->operand[0] = put_ilit(MARG2_LCL); ref->operand[1] = mopr; break; case TK_CIRCUMFLEX: if (!gvn()) return FALSE; ref = newtriple(OC_MERGE_GVARG); ref->operand[0] = put_ilit(MARG2_GBL); break; case TK_ATSIGN: TREF(temp_subs) = TRUE; if (!indirection(&mopr)) { stx_error(ERR_VAREXPECTED); return FALSE; } type = MARG2_LCL | MARG2_GBL; memset(&mv, 0, SIZEOF(mval)); /* Initialize so unused fields don't cause object hash differences */ MV_FORCE_MVAL(&mv, type); MV_FORCE_STRD(&mv); ref = maketriple(OC_INDMERGE); ref->operand[0] = put_lit(&mv); ref->operand[1] = mopr; ins_triple(ref); break; default: stx_error(ERR_VAREXPECTED); return FALSE; } /* * Make sure that during runtime right hand side argument is processed first. * This is specially important if global naked variable is used . */ obp = (TREF(curtchain))->exorder.bl; dqadd(obp, &tmpchain, exorder); if (TREF(temp_subs) && TREF(side_effect_handling) && sub) create_temporaries(sub, put_oc); TREF(temp_subs) = FALSE; if (used_glvn_slot) { ref = newtriple(OC_GLVNPOP); ref->operand[0] = control_slot; } ref = newtriple(OC_MERGE); return TRUE; }
int m_merge(void) { error_def(ERR_VAREXPECTED); error_def(ERR_RPARENMISSING); error_def(ERR_EQUAL); opctype put_oc; oprtype mopr; triple *sub, *ref, *obp, *s1, *restart, tmpchain; mval mv; int type; restart = newtriple(OC_RESTARTPC); /* Here is where a restart should pick up */ dqinit(&tmpchain, exorder); /* Left Hand Side of EQUAL sign */ switch (window_token) { case TK_IDENT: if (!lvn(&mopr, OC_PUTINDX, 0)) return FALSE; if (OC_PUTINDX == mopr.oprval.tref->opcode); { /* we insert left hand side argument into tmpchain. */ dqdel(mopr.oprval.tref, exorder); dqins(tmpchain.exorder.bl, exorder, mopr.oprval.tref); } ref = maketriple(OC_MERGE_LVARG); ref->operand[0] = put_ilit(MARG1_LCL); ref->operand[1] = mopr; dqins(tmpchain.exorder.bl, exorder, ref); break; case TK_CIRCUMFLEX: s1 = curtchain->exorder.bl; if (!gvn()) return FALSE; for (sub = curtchain->exorder.bl; sub != s1; sub = sub->exorder.bl) { put_oc = sub->opcode; if (OC_GVNAME == put_oc || OC_GVNAKED == put_oc || OC_GVEXTNAM == put_oc) break; } assert(OC_GVNAME == put_oc || OC_GVNAKED == put_oc || OC_GVEXTNAM == put_oc); /* we insert left hand side argument into tmpchain. */ dqdel(sub, exorder); dqins(tmpchain.exorder.bl ,exorder, sub); ref = maketriple(OC_MERGE_GVARG); ref->operand[0] = put_ilit(MARG1_GBL); dqins(tmpchain.exorder.bl, exorder, ref); break; case TK_ATSIGN: if (!indirection(&mopr)) return FALSE; if (window_token != TK_EQUAL) { ref = newtriple(OC_COMMARG); ref->operand[0] = mopr; ref->operand[1] = put_ilit((mint) indir_merge); ins_triple(ref); return TRUE; } type = MARG1_LCL | MARG1_GBL; MV_FORCE_MVAL(&mv, type); MV_FORCE_STR(&mv); ref = maketriple(OC_INDMERGE); ref->operand[0] = put_lit(&mv); ref->operand[1] = mopr; /* we insert left hand side argument into tmpchain. */ dqins(tmpchain.exorder.bl, exorder, ref); break; default: stx_error(ERR_VAREXPECTED); return FALSE; } if (window_token != TK_EQUAL) { stx_error(ERR_EQUAL); return FALSE; } advancewindow(); /* Right Hand Side of EQUAL sign */ switch (window_token) { case TK_IDENT: if (!lvn(&mopr, OC_M_SRCHINDX, 0)) return FALSE; ref = newtriple(OC_MERGE_LVARG); ref->operand[0] = put_ilit(MARG2_LCL); ref->operand[1] = mopr; break; case TK_CIRCUMFLEX: if (!gvn()) return FALSE; ref = newtriple(OC_MERGE_GVARG); ref->operand[0] = put_ilit(MARG2_GBL); break; case TK_ATSIGN: if (!indirection(&mopr)) { stx_error(ERR_VAREXPECTED); return FALSE; } type = MARG2_LCL | MARG2_GBL; MV_FORCE_MVAL(&mv, type); MV_FORCE_STR(&mv); ref = maketriple(OC_INDMERGE); ref->operand[0] = put_lit(&mv); ref->operand[1] = mopr; ins_triple(ref); break; default: stx_error(ERR_VAREXPECTED); return FALSE; } /* * Make sure that during runtime right hand side argument is processed first. * This is specially important if global naked variable is used . */ obp = curtchain->exorder.bl; dqadd(obp, &tmpchain, exorder); ref = newtriple(OC_MERGE); return TRUE; }
/* routine to convert external return values to mval's */ static void extarg2mval(void *src, enum xc_types typ, mval *dst) { int str_len; int4 s_int_num; uint4 uns_int_num; char *cp; struct extcall_string *sp; error_def(ERR_ZCSTATUSRET); error_def(ERR_MAXSTRLEN); switch(typ) { case xc_notfound: break; case xc_void: break; case xc_status: s_int_num = (int4)src; if (0 != s_int_num) dec_err(VARLSTCNT(1) ERR_ZCSTATUSRET,0,s_int_num); MV_FORCE_MVAL(dst, s_int_num); break; case xc_long: s_int_num = (int4)src; MV_FORCE_MVAL(dst, s_int_num); break; case xc_ulong: uns_int_num = (uint4)src; MV_FORCE_ULONG_MVAL(dst, uns_int_num); break; case xc_long_star: s_int_num = *((int4 *)src); MV_FORCE_MVAL(dst, s_int_num); break; case xc_ulong_star: uns_int_num = *((uint4 *)src); MV_FORCE_ULONG_MVAL(dst, uns_int_num); break; case xc_string_star: sp = (struct extcall_string *)src; dst->mvtype = MV_STR; if (sp->len > MAX_STRLEN) rts_error(VARLSTCNT(1) ERR_MAXSTRLEN); dst->str.len = sp->len; if ((0 < sp->len) && (NULL != sp->addr)) { dst->str.addr = sp->addr; s2pool(&dst->str); } break; case xc_float_star: double2mval(dst, (double)*((float *)src)); break; case xc_char_star: cp = (char *)src; assert(((int)cp < (int)stringpool.base) || ((int)cp > (int)stringpool.top)); dst->mvtype = MV_STR; str_len = strlen(cp); if (str_len > MAX_STRLEN) rts_error(VARLSTCNT(1) ERR_MAXSTRLEN); dst->str.len = str_len; dst->str.addr = cp; s2pool(&dst->str); break; case xc_char_starstar: if (!src) dst->mvtype = 0; else extarg2mval(*((char **)src), xc_char_star, dst); break; case xc_double_star: double2mval(dst, *((double *)src)); break; default: rts_error(VARLSTCNT(1) ERR_UNIMPLOP); break; } return; }
void op_fnztrnlnm(mval *name,mval *table,int4 ind,mval *mode,mval *case_blind,mval *item,mval *ret) { struct dsc$descriptor lname, ltable; uint4 attribute, status, retlen, mask, full_mask; char acmode; short int *item_code, pass, index; bool full; char buff[256], result[MAX_RESULT_SIZE]; char i, slot, last_slot; char def_table[] = "LNM$DCL_LOGICAL"; struct { item_list_3 item[3]; int4 terminator; } item_list; error_def(ERR_BADTRNPARAM); if(!name->str.len || MAX_LOGNAM_LENGTH < name->str.len || MAX_LOGNAM_LENGTH < table->str.len) rts_error(VARLSTCNT(1) SS$_IVLOGNAM); memset(&item_list,0,SIZEOF(item_list)); item_list.item[0].item_code = 0; item_list.item[0].buffer_address = result; item_list.item[0].buffer_length = MAX_RESULT_SIZE; item_list.item[0].return_length_address = &retlen; item_code = &item_list.item[0].item_code; lname.dsc$w_length = name->str.len; lname.dsc$a_pointer = name->str.addr; lname.dsc$b_dtype = DSC$K_DTYPE_T; lname.dsc$b_class = DSC$K_CLASS_S; if (table->str.len) { ltable.dsc$w_length = table->str.len; ltable.dsc$a_pointer = table->str.addr; }else { ltable.dsc$a_pointer = def_table; ltable.dsc$w_length = strlen(def_table); } ltable.dsc$b_dtype = DSC$K_DTYPE_T; ltable.dsc$b_class = DSC$K_CLASS_S; if(ind) { item_list.item[0].item_code = LNM$_INDEX; item_list.item[0].buffer_address = &ind; item_list.item[1].item_code = 0; item_list.item[1].buffer_address = result; item_list.item[1].buffer_length = MAX_RESULT_SIZE; item_list.item[1].return_length_address = &retlen; item_code = &item_list.item[1].item_code; } attribute = LNM$M_CASE_BLIND; if (case_blind->str.len) { if (case_blind->str.len > 14) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, MIN(SHRT_MAX, case_blind->str.len), case_blind->str.addr); lower_to_upper(buff,case_blind->str.addr,case_blind->str.len); if (case_blind->str.len == 14 && !memcmp(buff,"CASE_SENSITIVE",14)) attribute = 0; else if (case_blind->str.len != 10 || memcmp(buff,"CASE_BLIND",10)) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,case_blind->str.len,case_blind->str.addr); } acmode = NOVALUE; if (mode->str.len) { if (mode->str.len > 14) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, MIN(SHRT_MAX, mode->str.len), mode->str.addr); lower_to_upper(buff,mode->str.addr,mode->str.len); switch (buff[0]) { case 'U': if ( mode->str.len = 4 && !memcmp(buff, "USER", 4)) acmode = PSL$C_USER; case 'S': if ( mode->str.len = 10 && !memcmp(buff, "SUPERVISOR", 10)) acmode = PSL$C_SUPER; case 'K': if ( mode->str.len = 6 && !memcmp(buff, "KERNEL", 6)) acmode = PSL$C_KERNEL; case 'E': if ( mode->str.len = 9 && !memcmp(buff, "EXECUTIVE", 9)) acmode = PSL$C_EXEC; } if (acmode == NOVALUE) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,mode->str.len,mode->str.addr); } full = FALSE; *item_code = NOVALUE; if (item->str.len) { if (item->str.len > 12) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, MIN(SHRT_MAX, item->str.len), item->str.addr); lower_to_upper(buff,item->str.addr,item->str.len); if ((i = buff[0] - 'A') < MIN_INDEX || i > MAX_INDEX) { rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, item->str.len, item->str.addr); } if ( trnlnm_index[i].len) { slot = trnlnm_index[i].index; last_slot = trnlnm_index[i].len; for (; slot < last_slot; slot++) { if (item->str.len == trnlnm_table[slot].len && !memcmp(trnlnm_table[slot].name, buff, item->str.len)) { if (trnlnm_table[slot].item_code == FULL_VALUE) { if (ind) index = 2; else index = 1; *item_code = LNM$_STRING; item_list.item[index].buffer_address = &full_mask; item_list.item[index].buffer_length = SIZEOF(full_mask); item_list.item[index].item_code = LNM$_ATTRIBUTES; item_code = &item_list.item[index].item_code; full = TRUE; }else { *item_code = trnlnm_table[slot].item_code; } break; } } } if (*item_code == NOVALUE) { rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,item->str.len,item->str.addr); } }else { *item_code = LNM$_STRING; } for ( pass = 0 ; ; pass++ ) { retlen = 0; status = sys$trnlnm(&attribute, <able, &lname, acmode == NOVALUE ? 0 : &acmode, &item_list); if (status & 1) { if (*item_code == LNM$_STRING || *item_code == LNM$_TABLE) { ret->mvtype = MV_STR; ENSURE_STP_FREE_SPACE(retlen); ret->str.addr = stringpool.free; ret->str.len = retlen; memcpy(ret->str.addr, result, retlen); stringpool.free += retlen; return; }else if (*item_code == LNM$_LENGTH || *item_code == LNM$_MAX_INDEX) { MV_FORCE_MVAL(ret,*(int4 *)result) ; n2s(ret); return; }else if (*item_code == LNM$_ACMODE) { ret->mvtype = MV_STR; switch(*result) { case PSL$C_USER: ENSURE_STP_FREE_SPACE(4); ret->str.addr = stringpool.free; ret->str.len = 4; memcpy(ret->str.addr, "USER", 4); stringpool.free += 4; return; case PSL$C_SUPER: ENSURE_STP_FREE_SPACE(5); ret->str.addr = stringpool.free; ret->str.len = 5; memcpy(ret->str.addr, "SUPER", 5); stringpool.free += 5; return; case PSL$C_EXEC: ENSURE_STP_FREE_SPACE(9); ret->str.addr = stringpool.free; ret->str.len = 9; memcpy(ret->str.addr, "EXECUTIVE", 9); stringpool.free += 9; return; case PSL$C_KERNEL: ENSURE_STP_FREE_SPACE(6); ret->str.addr = stringpool.free; ret->str.len = 6; memcpy(ret->str.addr, "KERNEL", 6); stringpool.free += 6; return; default: GTMASSERT; } }else { assert(*item_code == LNM$_ATTRIBUTES); if (full) { if (!retlen) /* If the logical name exists, but has no entry for the specified index, */ { /* then the return status will be normal as the TERMINAL attribute will */ /* be filled in, but there will be no equivalence name, thus retlen == 0 */ ret->mvtype = MV_STR; if (!pass) { ret->str.len = 0; return; } ENSURE_STP_FREE_SPACE(lname.dsc$w_length); ret->str.addr = stringpool.free; ret->str.len = lname.dsc$w_length; memcpy(ret->str.addr, lname.dsc$a_pointer, lname.dsc$w_length); stringpool.free += lname.dsc$w_length; return; } if(full_mask & LNM$M_TERMINAL) { ret->mvtype = MV_STR; ENSURE_STP_FREE_SPACE(retlen); ret->str.addr = stringpool.free; ret->str.len = retlen; memcpy(ret->str.addr, result, retlen); stringpool.free += retlen; return; } memcpy(buff,result,retlen); lname.dsc$w_length = retlen; lname.dsc$a_pointer = buff; }else { mask = attr_tab[slot]; if (mask == NOVALUE) GTMASSERT; MV_FORCE_MVAL(ret,( *((int4*)result) & mask ? 1 : 0 )) ; n2s(ret); return; } } }else if (status == SS$_NOLOGNAM) { ret->mvtype = MV_STR; if (full && pass > 0) { ENSURE_STP_FREE_SPACE(lname.dsc$w_length); ret->str.addr = stringpool.free; ret->str.len = lname.dsc$w_length; memcpy(ret->str.addr, lname.dsc$a_pointer, lname.dsc$w_length); stringpool.free += lname.dsc$w_length; }else { ret->str.len = 0; } return; }else { rts_error(VARLSTCNT(1) status); } } MV_FORCE_MVAL(ret, 0) ; return; }
void op_fnzbitfind(mval *dst, mval *bitstr, int truthval, int pos) { int str_len, find_bit; unsigned char *byte_1, *byte_n, byte_0; int m, n, mp, np, i, i1, j; static const unsigned char mask[8] = {0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1}; error_def(ERR_INVBITSTR); MV_FORCE_STR(bitstr); if (!bitstr->str.len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); byte_1 = (unsigned char *)bitstr->str.addr; str_len = (bitstr->str.len -1) * 8; if (*byte_1 > 7) { rts_error(VARLSTCNT(1) ERR_INVBITSTR); } if (pos < 1) { pos = 1; /* It is the way it works in DATA TREE */ } else if (pos > str_len - *byte_1) { find_bit = 0; MV_FORCE_MVAL(dst, find_bit); return; /* It is the way it works in DATA TREE */ } np = (pos + 7)/8; mp = pos % 8; if (mp == 0) mp = 8; n = (str_len - *byte_1 + 7)/8 - 1; m = (str_len - *byte_1) % 8; if (m == 0) m = 8; byte_n = byte_1 + np; find_bit = 0; if (truthval) { if (np == n + 1) i1 = m; else i1 = 8; for (i = mp - 1; i < i1; i++) { if (byte_0 = *byte_n & mask[i]) { find_bit = i + 2 + (np - 1)*8; MV_FORCE_MVAL(dst, find_bit); return; } } if (np == n + 1) { MV_FORCE_MVAL(dst, find_bit); return; } for(j = 1; j <= n - np; j++) { byte_n++; for (i = 0; i < 8; i++) { if (byte_0 = *byte_n & mask[i]) { find_bit = i + 2 + (np + j - 1)*8; MV_FORCE_MVAL(dst, find_bit); return; } } } byte_n++; for (i = 0; i < m; i++) { if (byte_0 = *byte_n & mask[i]) { find_bit = i + 2 + n*8; MV_FORCE_MVAL(dst, find_bit); return; } } } else { if (np == n + 1) i1 = m; else i1 = 8; for (i = mp - 1; i < i1; i++) { if (!(byte_0 = *byte_n & mask[i])) { find_bit = i + 2 + (np - 1)*8; MV_FORCE_MVAL(dst, find_bit); return; } } if (np == n + 1) { MV_FORCE_MVAL(dst, find_bit); return; } for(j = 1; j <= n - np; j++) { byte_n++; for (i = 0; i < 8; i++) { if (!(byte_0 = *byte_n & mask[i])) { find_bit = i + 2 + (np + j - 1)*8; MV_FORCE_MVAL(dst, find_bit); return; } } } byte_n++; for (i = 0; i < m; i++) { if (!(byte_0 = *byte_n & mask[i])) { find_bit = i + 2 + n*8; MV_FORCE_MVAL(dst, find_bit); return; } } } MV_FORCE_MVAL(dst, find_bit); return; }
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(); } } }
unsigned char *set_zstatus(mstr *src, int arg, unsigned char **ctxtp, boolean_t need_rtsloc) { unsigned char *b_line; /* beginning of line (used to restart line) */ mval val; /* pointer to dollar_zstatus */ unsigned char zstatus_buff[2*OUT_BUFF_SIZE]; unsigned char *zstatus_bptr, *zstatus_iter; int save_arg; size_t util_len ; mval *status_loc; boolean_t trans_frame; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; b_line = 0; if (!need_rtsloc) trans_frame = FALSE; else { /* get the line address of the last "known" MUMPS code that was executed. MUMPS * indirection consitutes MUMPS code that is "unknown" is the sense that there is no * line address for it. */ trans_frame = !(SFT_DM & frame_pointer->type) && ((!(frame_pointer->type & SFT_COUNT || 0 == frame_pointer->type)) || (SFT_ZINTR & frame_pointer->type)); if (trans_frame) { save_arg = arg; SET_ERR_CODE(frame_pointer, arg); } src->len = INTCAST(get_symb_line((unsigned char*)src->addr, &b_line, ctxtp) - (unsigned char*)src->addr); } MV_FORCE_MVAL(&val, arg); n2s(&val); memcpy(zstatus_buff, val.str.addr, val.str.len); zstatus_bptr = zstatus_buff + val.str.len; *zstatus_bptr++ = ','; if (0 != b_line) { memcpy(zstatus_bptr, src->addr, src->len); zstatus_bptr += src->len; *zstatus_bptr++ = ','; } zstatus_iter = zstatus_bptr; util_len = TREF(util_outptr) - TREF(util_outbuff_ptr); if (trans_frame) { /* currently no inserted message (arg) needs arguments. The following code needs * to be changed if any new parametered message is added. */ *(TREF(util_outbuff_ptr)) = '-'; memcpy(&zstatus_buff[OUT_BUFF_SIZE], TREF(util_outbuff_ptr), util_len); /* save original message */ util_out_print(NULL, RESET); /* clear any pending msgs and reset util_out_buff */ gtm_putmsg_noflush(VARLSTCNT(1) arg); memcpy(zstatus_bptr, TREF(util_outbuff_ptr), TREF(util_outptr) - TREF(util_outbuff_ptr)); zstatus_bptr += (TREF(util_outptr) - TREF(util_outbuff_ptr)); *zstatus_bptr++ = ','; memcpy(zstatus_bptr, &zstatus_buff[OUT_BUFF_SIZE], util_len); /* restore original message into util_outbuf */ memcpy(TREF(util_outbuff_ptr), &zstatus_buff[OUT_BUFF_SIZE], util_len); *(TREF(util_outbuff_ptr)) = '%'; TREF(util_outptr) = TREF(util_outbuff_ptr) + util_len; arg = save_arg; } else memcpy(zstatus_bptr, TREF(util_outbuff_ptr), util_len); zstatus_bptr += util_len; for (; zstatus_iter < zstatus_bptr; zstatus_iter++) { if ('\n' == *zstatus_iter) *zstatus_iter = ','; } status_loc = (NULL == zyerr_frame) ? &dollar_zstatus : &dollar_zerror; status_loc->str.len = INTCAST(zstatus_bptr - zstatus_buff); status_loc->str.addr = (char *)zstatus_buff; s2pool(&status_loc->str); status_loc->mvtype = MV_STR; /* If this is a MEMORY issue, setting the ecode is of dubious worth since we are not going * to drive any handlers and it can definitely be expensive in terms of memory use as ecode_add() * (further down the pike) is likely to load the text of the module into storage if it can. So we bypass * ecode setting for these two fatal errors. 02/2008 se */ if (ERR_MEMORY != arg) ecode_set(arg); return (b_line); }
void gvcmz_doop(unsigned char query_code, unsigned char reply_code, mval *v) { unsigned char *ptr; short len, temp_short; int4 status, max_reply_len; struct CLB *lnk; unsigned char buff[MAX_ZWR_KEY_SZ], *end; error_def(ERR_BADSRVRNETMSG); error_def(ERR_UNIMPLOP); error_def(ERR_TEXT); error_def(ERR_GVIS); lnk = gv_cur_region->dyn.addr->cm_blk; if (!((link_info *)lnk->usr)->server_supports_long_names && (PRE_V5_MAX_MIDENT_LEN < strlen((char *)gv_currkey->base))) { 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 global names longer than 8 characters"), ERR_GVIS, 2, end - buff, buff, ERR_TEXT, 2, DB_LEN_STR(gv_cur_region)); } lnk->ast = 0; /* all database queries are sync */ lnk->cbl = 1 + /* HDR */ gv_currkey->end + /* key */ sizeof(unsigned short) + /* gv_key.top */ sizeof(unsigned short) + /* gv_key.end */ sizeof(unsigned short) + /* gv_key.prev */ sizeof(unsigned char) + /* gv_key.base */ sizeof(unsigned char) + /* regnum */ sizeof(unsigned short); /* size for variable len SUBSC */ /* the current GT.CM maximum message buffer length is bounded by the size of a short which is 64K. but the * calculation below of lnk->cbl and max_reply_len takes into account the fact that the value that is sent in as * input or read in from the server side can be at most MAX_DBSTRLEN in size. therefore, there is a dependency * that MAX_DBSTRLEN always be less than the GT.CM maximum message buffer length. to ensure this is always the * case, the following assert is added so that whenever MAX_DBSTRLEN is increased, we will fail this assert * and reexamine the code below. */ assert(sizeof(lnk->cbl) == 2); /* assert it is a short. when it becomes a uint4 the assert can be removed * if the macro CM_MAX_BUF_LEN (used below) is changed appropriately */ assert(MAX_DBSTRLEN == (32 * 1024 - 1)); if (CMMS_Q_PUT == query_code || CMMS_Q_INCREMENT == query_code) { if (CMMS_Q_INCREMENT == query_code) { /* 1-byte boolean value of "undef_inhibit" passed to the server for $INCREMENT although, effective V5.0-000, undef_inhibit is no longer relevant as $INCREMENT() implicitly does a $GET() on the global. We keep this byte to ensure compatibility with V5.0-FT01 */ lnk->cbl++; } assert((uint4)lnk->cbl + sizeof(unsigned short) + (uint4)MAX_DBSTRLEN <= (uint4)CM_MAX_BUF_LEN); lnk->cbl += (sizeof(unsigned short) + v->str.len); /* VALUE + length */ } if ((CMMS_Q_GET == query_code) || (CMMS_Q_INCREMENT == query_code) || (CMMS_Q_QUERY == query_code) && ((link_info *)lnk->usr)->query_is_queryget) max_reply_len = lnk->mbl + SIZEOF(unsigned short) + MAX_DBSTRLEN; /* can't predict the length of data value */ else max_reply_len = lnk->mbl; assert(max_reply_len <= (int4)CM_MAX_BUF_LEN); if (stringpool.top < stringpool.free + max_reply_len) stp_gcol(max_reply_len); lnk->mbf = stringpool.free; ptr = lnk->mbf; *ptr++ = query_code; /* temp_short = gv_currkey->end + sizeof(gv_key) + 1; */ temp_short = gv_currkey->end + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(char) + 1; CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); *ptr++ = gv_cur_region->cmx_regnum; CM_PUT_SHORT(ptr, gv_currkey->top, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); CM_PUT_SHORT(ptr, gv_currkey->end, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); CM_PUT_SHORT(ptr, gv_currkey->prev, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); memcpy(ptr, gv_currkey->base, gv_currkey->end + 1); if (CMMS_Q_PUT == query_code || CMMS_Q_INCREMENT == query_code) { ptr += gv_currkey->end + 1; temp_short = (short)v->str.len; assert((int4)temp_short == v->str.len); /* short <- int4 assignment lossy? */ CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); memcpy(ptr,v->str.addr, v->str.len); if (CMMS_Q_INCREMENT == query_code) { /* UNDEF flag is no longer relevant, but set the flag to ensure compatibility with V5.0-FT01 */ assert(sizeof(undef_inhibit) == 1); ptr[v->str.len] = (unsigned char)undef_inhibit; } } status = cmi_write(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } status = cmi_read(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } ptr = lnk->mbf; if (CMMS_Q_PUT == query_code || CMMS_Q_ZWITHDRAW == query_code || CMMS_Q_KILL == query_code) { if (reply_code != *ptr) { if (*ptr != CMMS_E_ERROR) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); gvcmz_errmsg(lnk,FALSE); } return; } if (reply_code != *ptr) { if ((CMMS_R_UNDEF != *ptr) || ((CMMS_Q_GET != query_code) && (CMMS_Q_INCREMENT != query_code))) { if (CMMS_E_ERROR != *ptr) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); gvcmz_errmsg(lnk, FALSE); } if (CMMS_Q_INCREMENT == query_code) v->mvtype = 0; /* set the result to be undefined */ return; } ptr++; if (CMMS_R_DATA == reply_code) { CM_GET_SHORT(temp_short, ptr, ((link_info *)(lnk->usr))->convert_byteorder); if (1 != temp_short) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); ptr += sizeof(short); status = *ptr; /* Temp assignment to status gets rid of compiler warning in MV_FORCE_MVAL macro */ MV_FORCE_MVAL(v, status); return; } if (reply_code == CMMS_R_PREV || reply_code == CMMS_R_QUERY || reply_code == CMMS_R_ORDER) { CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); if (1 == len) { MV_FORCE_MVAL(v, 0); } else { if (*ptr++ != gv_cur_region->cmx_regnum) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); /* memcpy(gv_altkey, ptr, len - 1); */ CM_GET_USHORT(gv_altkey->top, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); CM_GET_USHORT(gv_altkey->end, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); CM_GET_USHORT(gv_altkey->prev, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); memcpy(gv_altkey->base, ptr, len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short)); ptr += (len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short)); MV_FORCE_MVAL(v, 1); } if (CMMS_R_QUERY != reply_code || 1 == len || !((link_info *)lnk->usr)->query_is_queryget) { if (CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget) v->mvtype = 0; /* force undefined to distinguish $Q returning "" from value of QUERYGET being 0 */ return; } } assert(CMMS_R_GET == reply_code || CMMS_R_INCREMENT == reply_code || CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget && 1 < len); CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); assert(ptr >= stringpool.base && ptr + len < stringpool.top); /* incoming message is in stringpool */ v->mvtype = MV_STR; v->str.len = len; v->str.addr = (char *)stringpool.free; /* we don't need the reply msg anymore, can overwrite reply */ memcpy(v->str.addr, ptr, len); /* so that we don't leave a gaping hole in the stringpool */ stringpool.free += len; return; }
void op_fnorder(lv_val *src, mval *key, mval *dst) { int cur_subscr; mval tmp_sbs; int length; sbs_blk *num, *str; boolean_t found, is_neg; int4 i; lv_val **lv; lv_sbs_tbl *tbl; sbs_search_status status; boolean_t is_fnnext; is_fnnext = in_op_fnnext; in_op_fnnext = FALSE; found = FALSE; if (src) { if (tbl = src->ptrs.val_ent.children) { MV_FORCE_DEFINED(key); num = tbl->num; str = tbl->str; assert(tbl->ident == MV_SBS); if ((MV_IS_STRING(key) && key->str.len == 0) || (is_fnnext && MV_IS_INT(key) && key->m[1] == MINUS_ONE)) { /* With GT.M collation , if last subscript is null, $o returns the first subscript in that level */ if (tbl->int_flag) { assert(num); for (i = 0, lv = &num->ptr.lv[0]; i < SBS_NUM_INT_ELE; i++, lv++) { if (*lv) { MV_FORCE_MVAL(dst,i); found = TRUE; break; } } } else if (num) { assert(num->cnt); MV_ASGN_FLT2MVAL((*dst),num->ptr.sbs_flt[0].flt); found = TRUE; } } else { if (MV_IS_CANONICAL(key)) { MV_FORCE_NUM(key); if (tbl->int_flag) { assert(num); is_neg = (key->mvtype & MV_INT) ? key->m[1] < 0 : key->sgn; if (is_neg) i = 0; else { if (!is_fnnext && (1 == numcmp(key, (mval *)&SBS_MVAL_INT_ELE))) i = SBS_NUM_INT_ELE; else { i = MV_FORCE_INT(key); i++; } } for (lv = &num->ptr.lv[i]; i < SBS_NUM_INT_ELE; i++, lv++) { if (*lv) { MV_FORCE_MVAL(dst,i); found = TRUE; break; } } } else if (num && lv_nxt_num_inx(num, key, &status)) { MV_ASGN_FLT2MVAL((*dst),((sbs_flt_struct*)status.ptr)->flt); found = TRUE; } } else { if (local_collseq) { ALLOC_XFORM_BUFF(&key->str); tmp_sbs.mvtype = MV_STR; tmp_sbs.str.len = max_lcl_coll_xform_bufsiz; assert(NULL != lcl_coll_xform_buff); tmp_sbs.str.addr = lcl_coll_xform_buff; do_xform(local_collseq, XFORM, &key->str, &tmp_sbs.str, &length); tmp_sbs.str.len = length; s2pool(&(tmp_sbs.str)); key = &tmp_sbs; } if (str && lv_nxt_str_inx(str, &key->str, &status)) { dst->mvtype = MV_STR; dst->str = ((sbs_str_struct *)status.ptr)->str; } else { if (!is_fnnext) { dst->mvtype = MV_STR; dst->str.len = 0; } else MV_FORCE_MVAL(dst, -1); } found = TRUE; } } if (!found && str) { /* We are here because * a. key is "" and there is no numeric subscript, OR * b. key is numeric and it is >= the largest numeric subscript at this level implying a switch from * numeric to string subscripts * Either case, return the first string subscript. However, for STDNULLCOLL, skip to the next * subscript should the first subscript be "" */ assert(str->cnt); dst->mvtype = MV_STR; dst->str = str->ptr.sbs_str[0].str; found = TRUE; if (local_collseq_stdnull && 0 == dst->str.len) { assert(lv_null_subs); if (lv_nxt_str_inx(str, &dst->str, &status)) { dst->str = ((sbs_str_struct*)status.ptr)->str; } else found = FALSE; } } } } if (!found) { if (!is_fnnext) { dst->mvtype = MV_STR; dst->str.len = 0; } else MV_FORCE_MVAL(dst, -1); } else if (dst->mvtype == MV_STR && local_collseq) { ALLOC_XFORM_BUFF(&dst->str); assert(NULL != lcl_coll_xform_buff); tmp_sbs.str.addr = lcl_coll_xform_buff; tmp_sbs.str.len = max_lcl_coll_xform_bufsiz; do_xform(local_collseq, XBACK, &dst->str, &tmp_sbs.str, &length); tmp_sbs.str.len = length; s2pool(&(tmp_sbs.str)); dst->str = tmp_sbs.str; } }
void op_fnzlength(mval *src, mval *dest) { MV_FORCE_STR(src); MV_FORCE_MVAL(dest, src->str.len); }
void zshow_devices(zshow_out *output) { static readonly char filchar_text[] = "CHARACTERS"; static readonly char filesc_text[] = "ESCAPES"; static readonly char terminal_text[] = "TERMINAL "; static readonly char magtape_text[] = "MAGTAPE "; static readonly char rmsfile_text[] = "RMS "; static readonly char mailbox_text[] = "MAILBOX "; static readonly char dollarc_text[] = "$C("; static readonly char equal_text[] = {'='}; static readonly char comma_text[] = {','}; static readonly char quote_text[] = {'"'}; static readonly char lparen_text[] = {'('}; static readonly char rparen_text[] = {')'}; static readonly char devop[] = "OPEN "; static readonly char devcl[] = "CLOSED "; static readonly char largerecord[] = "BIGRECORD "; static readonly char rfm_tab[][7] = {"UDF ", "FIXED ", "VAR ", "VFC ", "STM ", "STMLF ", "STMCR "}; bool first; int4 i, j, ii, jj; io_log_name *l; /* logical name pointer */ mval v; mval m; struct FAB *f; struct RAB *r; d_mb_struct *mb_ptr; d_mt_struct *mt_ptr; d_rm_struct *rm_ptr; d_tt_struct *tt_ptr; d_socket_struct *dsocketptr; socket_struct *socketptr; io_termmask *mask_out; unsigned char delim_buff_sm[MAX_DELIM_LEN]; unsigned short delim_len_sm; char delim_mstr_buff[(MAX_DELIM_LEN * MAX_ZWR_EXP_RATIO) + 11]; mstr delim; int delim_len; static readonly char space8_text[] = " "; /* starting from here, for gtmsocket only */ static readonly char lb_text[] = {'['}; static readonly char rb_text[] = {']'}; static readonly char at_text[] = {'@'}; static readonly char delimiter_text[] = "DELIMITER "; static readonly char nodelimiter_text[] = "NODELIMITER "; static readonly char local_text[] = "LOCAL="; static readonly char remote_text[] = "REMOTE="; static readonly char total_text[] = "TOTAL="; static readonly char current_text[] = "CURRENT="; static readonly char passive_text[] = "PASSIVE "; static readonly char active_text[] = "ACTIVE "; static readonly char socket_text[] = "SOCKET"; static readonly char descriptor_text[] = "DESC="; static readonly char trap_text[] = "TRAP "; static readonly char notrap_text[] = "NOTRAP "; static readonly char zdelay_text[] = "ZDELAY "; static readonly char znodelay_text[] = "ZNODELAY "; static readonly char zbfsize_text[] = "ZBFSIZE="; static readonly char zibfsize_text[] = "ZIBFSIZE="; static readonly char port_text[] = "PORT="; static readonly char zsh_socket_state[][10] = { "CONNECTED" ,"LISTENING" ,"BOUND" ,"CREATED" }; static readonly char morereadtime_text[] = "MOREREADTIME="; v.mvtype = MV_STR; for (l = io_root_log_name; l != 0; l = l->next) { if (l->dollar_io[0] != IO_ESC && l->iod->trans_name == l) { v.str.addr = &l->dollar_io[0]; v.str.len = l->len; zshow_output(output, &v.str); ZS_ONE_OUT(&v, space_text); if (l->iod->state == dev_open) { ZS_STR_OUT(&v, devop); switch(l->iod->type) { case tt: ZS_STR_OUT(&v, terminal_text); tt_ptr = (d_tt_struct *)l->iod->dev_sp; if (!ctrlc_on && io_std_device->out == l->iod) /* and standard input */ ZS_PARM_SP(&v, zshow_nocene); if ((int4)(tt_ptr->item_list[0].addr) & TRM$M_TM_CVTLOW) ZS_PARM_SP(&v, zshow_conv); if (tt_ptr->enbld_outofbands.mask) { ZS_PARM_EQU(&v, zshow_ctra); ZS_STR_OUT(&v, dollarc_text); first = TRUE; for (i = 1, j = 0; j < 32; j++, i = i * 2) { if (i & tt_ptr->enbld_outofbands.mask) { if (!first) ZS_ONE_OUT(&v, comma_text); else first = FALSE; MV_FORCE_MVAL(&m, j); mval_write(output, &m, FALSE); } } ZS_ONE_OUT(&v, rparen_text); ZS_ONE_OUT(&v, space_text); } if ((int4)(tt_ptr->term_char) & TT$M_NOECHO) ZS_PARM_SP(&v, zshow_noecho); if ((int4)(tt_ptr->ext_cap) & TT2$M_EDITING) ZS_PARM_SP(&v, zshow_edit); else ZS_PARM_SP(&v, zshow_noedit); if (!((int4)(tt_ptr->term_char) & TT$M_ESCAPE)) ZS_PARM_SP(&v, zshow_noesca); if (tt_ptr->in_buf_sz != TTDEF_BUF_SZ) { ZS_PARM_EQU(&v, zshow_field); MV_FORCE_MVAL(&m, tt_ptr->in_buf_sz); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } if (tt_ptr->term_char & TT$M_HOSTSYNC) ZS_PARM_SP(&v, zshow_host); else ZS_PARM_SP(&v, zshow_nohost); if (tt_ptr->ext_cap & TT2$M_INSERT) ZS_PARM_SP(&v, zshow_inse); else ZS_PARM_SP(&v, zshow_noinse); if (tt_ptr->ext_cap & TT2$M_PASTHRU) ZS_PARM_SP(&v, zshow_past); else ZS_PARM_SP(&v, zshow_nopast); if (tt_ptr->term_char & TT$M_READSYNC) ZS_PARM_SP(&v, zshow_reads); else ZS_PARM_SP(&v, zshow_noreads); if (tt_ptr->term_char & TT$M_TTSYNC) ZS_PARM_SP(&v, zshow_ttsy); else ZS_PARM_SP(&v, zshow_nottsy); if (tt_ptr->term_char & TT$M_NOTYPEAHD) ZS_PARM_SP(&v, zshow_notype); else ZS_PARM_SP(&v, zshow_type); if (!l->iod->wrap) ZS_PARM_SP(&v, zshow_nowrap); mask_out = tt_ptr->item_list[2].addr; if (mask_out->mask[0] != TERM_MSK) { ZS_PARM_EQU(&v, zshow_term); ZS_STR_OUT(&v, dollarc_text); first = TRUE; for (i = 0; i < 8; i++) { for (j = 0; j < 32; j++) if (mask_out->mask[i] & (1 << j)) { if (!first) ZS_ONE_OUT(&v, comma_text); else first = FALSE; MV_FORCE_MVAL(&m, i * 32 + j); mval_write(output, &m, FALSE); } } ZS_ONE_OUT(&v, rparen_text); ZS_ONE_OUT(&v, space_text); } ZS_PARM_EQU(&v, zshow_width); MV_FORCE_MVAL(&m, l->iod->width); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); ZS_PARM_EQU(&v, zshow_leng); MV_FORCE_MVAL(&m, l->iod->pair.out->length); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); if (l->iod->write_filter) { bool twoparms = FALSE; ZS_PARM_EQU(&v, zshow_fil); if (l->iod->write_filter & CHAR_FILTER) { if (l->iod->write_filter & ESC1) { twoparms = TRUE; ZS_ONE_OUT(&v, lparen_text); } ZS_STR_OUT(&v, filchar_text); if (twoparms) { ZS_ONE_OUT(&v, comma_text); ZS_ONE_OUT(&v, space_text); } } if (l->iod->write_filter & ESC1) ZS_STR_OUT(&v, filesc_text); if (twoparms) ZS_ONE_OUT(&v, rparen_text); ZS_ONE_OUT(&v, space_text); } break; case mt: ZS_STR_OUT(&v, magtape_text); mt_ptr = (d_tt_struct *)l->iod->dev_sp; if (mt_ptr->block_sz != MTDEF_BUF_SZ) { ZS_PARM_EQU(&v, zshow_bloc); MV_FORCE_MVAL(&m, mt_ptr->block_sz); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } if (mt_ptr->record_sz != MTDEF_REC_SZ) { ZS_PARM_EQU(&v, zshow_rec); MV_FORCE_MVAL(&m, mt_ptr->record_sz); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } if (mt_ptr->read_only) ZS_PARM_SP(&v, zshow_read); if (mt_ptr->ebcdic) ZS_PARM_SP(&v, zshow_ebcd); if (mt_ptr->fixed) ZS_PARM_SP(&v, zshow_fixed); if (mt_ptr->read_mask & IO$M_DATACHECK) ZS_PARM_SP(&v, zshow_rchk); if (mt_ptr->write_mask & IO$M_DATACHECK) ZS_PARM_SP(&v, zshow_wchk); if (!l->iod->wrap) ZS_PARM_SP(&v, zshow_nowrap); break; case rm: ZS_STR_OUT(&v, rmsfile_text); rm_ptr = (d_rm_struct *)l->iod->dev_sp; f = &rm_ptr->f; r = &rm_ptr->r; if (r->rab$l_rop & RAB$M_CVT) ZS_PARM_SP(&v, zshow_conv); if (f->fab$l_alq != 0) { ZS_PARM_EQU(&v, zshow_allo); MV_FORCE_MVAL(&m, f->fab$l_alq); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } if (f->fab$l_fop & FAB$M_DLT) ZS_PARM_SP(&v, zshow_dele); if (f->fab$w_deq != 0) { ZS_PARM_EQU(&v, zshow_exte); MV_FORCE_MVAL(&m, f->fab$w_deq); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } assert(FAB$C_MAXRFM == (SIZEOF(rfm_tab)/SIZEOF(rfm_tab[0]) - 1)); if (FAB$C_MAXRFM >= rm_ptr->b_rfm && FAB$C_RFM_DFLT != rm_ptr->b_rfm) ZS_STR_OUT(&v, rfm_tab[rm_ptr->b_rfm]); if (rm_ptr->largerecord) ZS_STR_OUT(&v, largerecord); if (f->fab$b_fac == FAB$M_GET) ZS_PARM_SP(&v, zshow_read); if (rm_ptr->l_mrs != DEF_RM_WIDTH) { ZS_PARM_EQU(&v, zshow_rec); MV_FORCE_MVAL(&m, rm_ptr->l_mrs); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } /* smw should we add width aka usz */ if (f->fab$b_shr & FAB$M_SHRGET) ZS_PARM_SP(&v, zshow_shar); /* if (f->fab$l_fop & FAB$M_SPL) ZS_PARM_SP(&v, zshow_spo); if (f->fab$l_fop & FAB$M_SCF) ZS_PARM_SP(&v, zshow_sub); */ if (!l->iod->wrap) ZS_PARM_SP(&v, zshow_nowrap); if (f->fab$l_xab) { /* smw need to handle other XABs and uic as octal */ struct XABPRO *xabpro; uic_struct uic; ZS_PARM_EQU(&v, zshow_uic); ZS_ONE_OUT(&v, quote_text); xabpro = f->fab$l_xab; memcpy(&uic, &xabpro->xab$l_uic, SIZEOF(int4)); MV_FORCE_MVAL(&m, uic.grp); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, comma_text); MV_FORCE_MVAL(&m, uic.mem); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, quote_text); ZS_ONE_OUT(&v, space_text); } break; case mb: ZS_STR_OUT(&v, mailbox_text); mb_ptr = (d_mb_struct *)l->iod->dev_sp; if (!(mb_ptr->write_mask & IO$M_NOW)) ZS_PARM_SP(&v, zshow_wait); if (mb_ptr->prmflg) ZS_PARM_SP(&v, zshow_prmmbx); if (mb_ptr->maxmsg != DEF_MB_MAXMSG) { ZS_PARM_EQU(&v, zshow_bloc); MV_FORCE_MVAL(&m, mb_ptr->maxmsg); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } if (mb_ptr->promsk & IO_RD_ONLY) ZS_PARM_SP(&v, zshow_read); if (mb_ptr->del_on_close) ZS_PARM_SP(&v, zshow_dele); if (mb_ptr->promsk & IO_SEQ_WRT) ZS_PARM_SP(&v, zshow_write); if (l->iod->width != DEF_MB_MAXMSG) { ZS_PARM_EQU(&v, zshow_width); MV_FORCE_MVAL(&m, l->iod->width); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } if (!l->iod->wrap) ZS_PARM_SP(&v, zshow_nowrap); if (l->iod->length != DEF_MB_LENGTH) { ZS_PARM_EQU(&v, zshow_leng); MV_FORCE_MVAL(&m, l->iod->length); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); } break; case gtmsocket: delim.addr = delim_mstr_buff; delim_len = 0; ZS_STR_OUT(&v, socket_text); dsocketptr = (d_socket_struct *)l->iod->dev_sp; ZS_ONE_OUT(&v, space_text); ZS_STR_OUT(&v, total_text); MV_FORCE_MVAL(&m, (int)dsocketptr->n_socket); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); ZS_STR_OUT(&v, current_text); MV_FORCE_MVAL(&m, (int)dsocketptr->current_socket); mval_write(output, &m, FALSE); output->flush = TRUE; zshow_output(output, 0); for(ii = 0; ii < dsocketptr->n_socket; ii++) { /* output each socket */ socketptr = dsocketptr->socket[ii]; ZS_STR_OUT(&v, space8_text); /* socket handle */ ZS_STR_OUT(&v, socket_text); ZS_ONE_OUT(&v, lb_text); MV_FORCE_MVAL(&m, ii); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, rb_text); ZS_ONE_OUT(&v, equal_text); v.str.addr = socketptr->handle; v.str.len = socketptr->handle_len; zshow_output(output, &v.str); ZS_ONE_OUT(&v, space_text); /* socket descriptor */ ZS_STR_OUT(&v, descriptor_text); MV_FORCE_MVAL(&m, socketptr->sd); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); /* socket state */ ZS_STR_OUT(&v, zsh_socket_state[socketptr->state]); ZS_ONE_OUT(&v, space_text); /* socket type */ if (socketptr->passive) { ZS_STR_OUT(&v, passive_text); } else { ZS_STR_OUT(&v, active_text); } ZS_ONE_OUT(&v, space_text); /* error trapping */ if (socketptr->ioerror) { ZS_STR_OUT(&v, trap_text); } else { ZS_STR_OUT(&v, notrap_text); } ZS_ONE_OUT(&v, space_text); /* address + port */ if (socketptr->passive) { ZS_STR_OUT(&v, port_text); MV_FORCE_MVAL(&m, (int)socketptr->local.port); mval_write(output, &m, FALSE); } else { ZS_STR_OUT(&v, remote_text); if (NULL != socketptr->remote.saddr_ip) { v.str.addr = socketptr->remote.saddr_ip; v.str.len = strlen(socketptr->remote.saddr_ip); } else { v.str.addr = ""; v.str.len = 0; } zshow_output(output, &v.str); ZS_ONE_OUT(&v, at_text); MV_FORCE_MVAL(&m, (int)socketptr->remote.port); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); /* to be added later ... ZS_STR_OUT(&v, local_text); v.str.addr = socketptr->local.saddr_ip; v.str.len = strlen(socketptr->local.saddr_ip); zshow_output(output, &v.str); ZS_ONE_OUT(&v, at_text); MV_FORCE_MVAL(&m, (int)socketptr->local.port); mval_write(output, &m, FALSE); */ } ZS_ONE_OUT(&v, space_text); output->flush = TRUE; zshow_output(output, 0); ZS_STR_OUT(&v, space8_text); ZS_STR_OUT(&v, space8_text); /* zdelay */ if (socketptr->nodelay) { ZS_STR_OUT(&v, znodelay_text); } else { ZS_STR_OUT(&v, zdelay_text); } ZS_ONE_OUT(&v, space_text); /* zbfsize */ ZS_STR_OUT(&v, zbfsize_text); MV_FORCE_MVAL(&m, socketptr->buffer_size); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); /* izbfsize */ ZS_STR_OUT(&v, zibfsize_text); MV_FORCE_MVAL(&m, socketptr->bufsiz); mval_write(output, &m, FALSE); ZS_ONE_OUT(&v, space_text); /* delimiters */ if (socketptr->n_delimiter > 0) { output->flush = TRUE; zshow_output(output, 0); ZS_STR_OUT(&v, space8_text); ZS_STR_OUT(&v, space8_text); ZS_STR_OUT(&v, delimiter_text); for (jj = 0; jj < socketptr->n_delimiter; jj++) { delim_len_sm = socketptr->delimiter[jj].len; memcpy(delim_buff_sm, socketptr->delimiter[jj].addr, delim_len_sm); format2zwr(delim_buff_sm, delim_len_sm, (uchar_ptr_t)delim.addr, &delim_len); delim.len = (unsigned short) delim_len; assert(SIZEOF(delim_mstr_buff) >= delim_len); zshow_output(output, &delim); ZS_ONE_OUT(&v, space_text); } } else { ZS_STR_OUT(&v, nodelimiter_text); } /* readmoretime */ if (DEFAULT_MOREREAD_TIMEOUT != socketptr->moreread_timeout) { ZS_STR_OUT(&v, morereadtime_text); MV_FORCE_MVAL(&m, socketptr->moreread_timeout); mval_write(output, &m, FALSE); } output->flush = TRUE; zshow_output(output, 0); } default: v.str.len = 0; break; } if (l->iod->error_handler.len) { ZS_PARM_EQU(&v, zshow_exce); ZS_ONE_OUT(&v, quote_text); v.str = l->iod->error_handler; zshow_output(output, &v.str); output->flush = TRUE; ZS_ONE_OUT(&v, quote_text); } else { output->flush = TRUE; zshow_output(output, 0); } } else { output->flush = TRUE; ZS_STR_OUT(&v, devcl); } } } }
void trigger_delete_all(char *trigger_rec, uint4 len, uint4 *trig_stats) { int count; sgmnt_addrs *csa; mval curr_gbl_name; int cycle; mval *mv_count_ptr; mval *mv_cycle_ptr; gd_region *reg, *reg_top; int4 result; gd_region *lgtrig_reg; mval trigger_cycle; mval trigger_count; boolean_t this_db_updated; uint4 triggers_deleted; mval trigjrec; boolean_t jnl_format_done; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(0 < dollar_tlevel); jnl_format_done = FALSE; lgtrig_reg = NULL; trigjrec.mvtype = MV_STR; trigjrec.str.len = len; trigjrec.str.addr = trigger_rec; triggers_deleted = 0; for (reg = gd_header->regions, reg_top = reg + gd_header->n_regions; reg < reg_top; reg++) { GVTR_SWITCH_REG_AND_HASHT_BIND_NAME(reg); csa = cs_addrs; if (NULL == csa) /* not BG or MM access method */ continue; /* gv_target now points to ^#t in region "reg" */ /* To write the LGTRIG logical jnl record, choose some region that has journaling enabled */ if (!reg->read_only && !jnl_format_done && JNL_WRITE_LOGICAL_RECS(csa)) lgtrig_reg = reg; if (!gv_target->root) continue; /* kill ^#t("#TNAME") */ BUILD_HASHT_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME)); if (0 != gvcst_data()) { /* Issue error if we dont have permissions to touch ^#t global */ if (reg->read_only) rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(reg)); gvcst_kill(TRUE); } /* Kill all descendents of ^#t(trigvn, ...) where trigvn is any global with a trigger, * but skip the ^#t("#...",...) entries. Setup ^#t("$") as the key for op_gvorder */ BUILD_HASHT_SUB_CURRKEY(LITERAL_MAXHASHVAL, STRLEN(LITERAL_MAXHASHVAL)); TREF(gv_last_subsc_null) = FALSE; /* We know its not null, but prior state is unreliable */ this_db_updated = FALSE; while (TRUE) { op_gvorder(&curr_gbl_name); /* quit:$length(curr_gbl_name)=0 */ if (0 == curr_gbl_name.str.len) break; /* $get(^#t(curr_gbl_name,#COUNT)) */ BUILD_HASHT_SUB_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len, LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT)); if (gvcst_get(&trigger_count)) { /* Now that we know there is something to kill, check if we have permissions to touch ^#t global */ if (reg->read_only) rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(reg)); mv_count_ptr = &trigger_count; count = MV_FORCE_UINT(mv_count_ptr); /* $get(^#t(curr_gbl_name,#CYCLE)) */ BUILD_HASHT_SUB_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len, LITERAL_HASHCYCLE, STRLEN(LITERAL_HASHCYCLE)); if (!gvcst_get(&trigger_cycle)) { /* Found #COUNT, there must be #CYCLE */ if (CDB_STAGNATE > t_tries) t_retry(cdb_sc_triggermod); assert(WBTEST_HELPOUT_TRIGDEFBAD == gtm_white_box_test_case_number); rts_error_csa(CSA_ARG(csa) VARLSTCNT(12) ERR_TRIGDEFBAD, 6, curr_gbl_name.str.len, curr_gbl_name.str.addr, curr_gbl_name.str.len, curr_gbl_name.str.addr, LEN_AND_LIT("\"#CYCLE\""), ERR_TEXT, 2, RTS_ERROR_TEXT("#CYCLE field is missing")); } mv_cycle_ptr = &trigger_cycle; cycle = MV_FORCE_UINT(mv_cycle_ptr); if (!jnl_format_done && JNL_WRITE_LOGICAL_RECS(csa)) { jnl_format(JNL_LGTRIG, NULL, &trigjrec, 0); jnl_format_done = TRUE; } /* kill ^#t(curr_gbl_name) */ BUILD_HASHT_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len); gvcst_kill(TRUE); /* Note : ^#t(curr_gbl_name,"#TRHASH") is also killed as part of the above */ cycle++; MV_FORCE_MVAL(&trigger_cycle, cycle); /* set ^#t(curr_gbl_name,#CYCLE)=trigger_cycle */ SET_TRIGGER_GLOBAL_SUB_SUB_MVAL(curr_gbl_name.str.addr, curr_gbl_name.str.len, LITERAL_HASHCYCLE, STRLEN(LITERAL_HASHCYCLE), trigger_cycle, result); assert(PUT_SUCCESS == result); this_db_updated = TRUE; triggers_deleted += count; } /* else there is no #COUNT, then no triggers, leave #CYCLE alone */ /* get ready for op_gvorder() call for next trigger under ^#t */ BUILD_HASHT_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len); } if (this_db_updated) { csa->incr_db_trigger_cycle = TRUE; if (dollar_ztrigger_invoked) { /* increment db_dztrigger_cycle so that next gvcst_put/gvcst_kill in this transaction, * on this region, will re-read. See trigger_update.c for a comment on why it is okay * for db_dztrigger_cycle to be incremented more than once in the same transaction */ csa->db_dztrigger_cycle++; } } } if (!jnl_format_done && (NULL != lgtrig_reg)) { /* There was no journaled region that had a ^#t update, but found at least one journaled region * so write a LGTRIG logical jnl record there. */ GVTR_SWITCH_REG_AND_HASHT_BIND_NAME(lgtrig_reg); csa = cs_addrs; JNLPOOL_INIT_IF_NEEDED(csa, csa->hdr, csa->nl); /* see previous usage for comment on why it is needed */ assert(dollar_tlevel); T_BEGIN_SETORKILL_NONTP_OR_TP(ERR_TRIGLOADFAIL); /* needed to set update_trans TRUE on this region * even if NO db updates happen to ^#t nodes. */ jnl_format(JNL_LGTRIG, NULL, &trigjrec, 0); jnl_format_done = TRUE; } if (triggers_deleted) { util_out_print_gtmio("All existing triggers (count = !UL) deleted", FLUSH, triggers_deleted); trig_stats[STATS_DELETED] += triggers_deleted; trig_stats[STATS_NOERROR_TRIGFILE]++; } else { util_out_print_gtmio("No matching triggers found for deletion", FLUSH); trig_stats[STATS_UNCHANGED_TRIGFILE]++; } }
int op_fnzsearch (mval *file, mint indx, mval *ret) { struct stat statbuf; int stat_res; parse_blk pblk; plength *plen, pret; char buf1[MAX_FBUFF + 1]; /* buffer to hold translated name */ mval sub; mstr tn; lv_val *ind_tmp; error_def(ERR_INVSTRLEN); MV_FORCE_STR(file); if (file->str.len > MAX_FBUFF) rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, file->str.len, MAX_FBUFF); MV_FORCE_MVAL(&ind_val, indx); ind_var = op_srchindx(VARLSTCNT(2) zsrch_var, &ind_val); if (ind_var) { assert(ind_var->v.mvtype & MV_STR); if (file->str.len != ind_var->v.str.len || memcmp(file->str.addr, ind_var->v.str.addr, file->str.len)) { op_kill(ind_var); ind_var = (lv_val*) 0; } } if (ind_var) { for (;;) { pret.p.pint = pop_top(ind_var, ret); /* get next element off the top */ if (!ret->str.len) break; memcpy(buf1, ret->str.addr, ret->str.len); buf1[ret->str.len] = 0; STAT_FILE(buf1, &statbuf, stat_res); if (-1 == stat_res) { if (errno == ENOENT) continue; rts_error(VARLSTCNT(1) errno); } break; } } else { memset(&pblk, 0, sizeof(pblk)); pblk.buffer = buf1; pblk.buff_size = MAX_FBUFF; if (!(parse_file(&file->str, &pblk) & 1)) { ret->mvtype = MV_STR; ret->str.len = 0; } else { assert(!ind_var); buf1[pblk.b_esl] = 0; /* establish new search context */ ind_var = op_putindx(VARLSTCNT(2) zsrch_var, &ind_val); ind_var->v = *file; /* zsrch_var(indx)=original spec */ if (!(pblk.fnb & F_WILD)) { sub.mvtype = MV_STR; sub.str.len = pblk.b_esl; sub.str.addr = buf1; s2pool(&sub.str); ind_tmp = op_putindx(VARLSTCNT(2) ind_var, &sub); ind_tmp->v.mvtype = MV_STR; ind_tmp->v.str.len = 0; plen = (plength *)&ind_tmp->v.m[1]; plen->p.pblk.b_esl = pblk.b_esl; plen->p.pblk.b_dir = pblk.b_dir; plen->p.pblk.b_name = pblk.b_name; plen->p.pblk.b_ext = pblk.b_ext; } else dir_srch(&pblk); for (;;) { pret.p.pint = pop_top(ind_var, ret); /* get next element off the top */ if (!ret->str.len) break; memcpy(buf1, ret->str.addr, ret->str.len); buf1[ret->str.len] = 0; STAT_FILE(buf1, &statbuf, stat_res); if (-1 == stat_res) { if (errno == ENOENT) continue; rts_error(VARLSTCNT(1) errno); } break; } } } assert(pret.p.pblk.b_esl == ret->str.len); return pret.p.pint; }
void op_svget(int varnum, mval *v) { io_log_name *tl; int count; gtm_uint64_t ucount; char *c1, *c2; mval *mvp; # ifdef UNIX d_rm_struct *d_rm; # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; # if defined(UNIX) && defined(DEBUG) if (gtm_white_box_test_case_enabled && (WBTEST_HUGE_ALLOC == gtm_white_box_test_case_number)) { if (1 == gtm_white_box_test_case_count) totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xffff; else if (2 == gtm_white_box_test_case_count) totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xfffffff; else if (3 == gtm_white_box_test_case_count) { # ifdef GTM64 if (8 == SIZEOF(size_t)) totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xfffffffffffffff; else # endif totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xfffffff; } else totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = GTM64_ONLY(SIZEOF(size_t)) NON_GTM64_ONLY(SIZEOF(size_t) > 4 ? 4 : SIZEOF(size_t)); } # endif switch (varnum) { case SV_HOROLOG: op_horolog(v); break; case SV_ZGBLDIR: v->mvtype = MV_STR; v->str = dollar_zgbldir.str; break; case SV_PRINCIPAL: tl = dollar_principal ? dollar_principal : io_root_log_name->iod->trans_name; v->str.addr = tl->dollar_io; v->str.len = tl->len; /*** The following should be in the I/O code ***/ if (ESC == *v->str.addr) { if (5 > v->str.len) v->str.len = 0; else { v->str.addr += ESC_OFFSET; v->str.len -= ESC_OFFSET; } } s2pool(&(v->str)); v->mvtype = MV_STR; break; case SV_ZIO: v->mvtype = MV_STR; /* NOTE: This is **NOT** equivalent to : * io_curr_log_name->dollar_io */ v->str.addr = io_curr_device.in->trans_name->dollar_io; v->str.len = io_curr_device.in->trans_name->len; if (ESC == *v->str.addr) { if (5 > v->str.len) v->str.len = 0; else { v->str.addr += ESC_OFFSET; v->str.len -= ESC_OFFSET; } } s2pool(&(v->str)); break; case SV_JOB: *v = dollar_job; break; case SV_REFERENCE: get_reference(v); break; case SV_SYSTEM: *v = dollar_system; break; case SV_STORAGE: /* double2mval(v, getstorage()); Causes issues with unaligned stack on x86_64 - remove until fixed */ i2mval(v, getstorage()); break; case SV_TLEVEL: count = (int)dollar_tlevel; MV_FORCE_MVAL(v, count); break; case SV_TRESTART: MV_FORCE_MVAL(v, (int)((MAX_VISIBLE_TRESTART < dollar_trestart) ? MAX_VISIBLE_TRESTART : dollar_trestart)); break; case SV_X: count = (int)io_curr_device.out->dollar.x; MV_FORCE_MVAL(v, count); break; case SV_Y: count = (int)io_curr_device.out->dollar.y; MV_FORCE_MVAL(v, count); break; case SV_ZA: count = (int)io_curr_device.in->dollar.za; MV_FORCE_MVAL(v, count); break; case SV_ZB: c1 = (char *)io_curr_device.in->dollar.zb; c2 = c1 + SIZEOF(io_curr_device.in->dollar.zb); ENSURE_STP_FREE_SPACE(SIZEOF(io_curr_device.in->dollar.zb)); v->mvtype = MV_STR; v->str.addr = (char *)stringpool.free; while (c1 < c2 && *c1) *stringpool.free++ = *c1++; v->str.len = INTCAST((char *)stringpool.free - v->str.addr); break; case SV_ZC: /****THESE ARE DUMMY VALUES ONLY!!!!!!!!!!!!!!!!!****/ MV_FORCE_MVAL(v, 0); break; case SV_ZCMDLINE: get_command_line(v, TRUE); /* TRUE to indicate we want $ZCMDLINE (i.e. processed not actual command line) */ break; case SV_ZEOF: # ifdef UNIX if (rm == io_curr_device.in->type) { d_rm = (d_rm_struct *)io_curr_device.in->dev_sp; if (RM_READ != d_rm->lastop) { *v = literal_zero; break; } } # endif *v = io_curr_device.in->dollar.zeof ? literal_one : literal_zero; break; case SV_ZQUIT: *v = dollar_zquit_anyway ? literal_one : literal_zero; break; case SV_IO: v->str.addr = io_curr_device.in->name->dollar_io; v->str.len = io_curr_device.in->name->len; /*** The following should be in the I/O code ***/ if (ESC == *v->str.addr) { if (5 > v->str.len) v->str.len = 0; else { v->str.addr += ESC_OFFSET; v->str.len -= ESC_OFFSET; } } s2pool(&(v->str)); v->mvtype = MV_STR; break; case SV_PROMPT: v->mvtype = MV_STR; v->str.addr = (TREF(gtmprompt)).addr; v->str.len = (TREF(gtmprompt)).len; s2pool(&v->str); break; case SV_ZCOMPILE: v->mvtype = MV_STR; v->str = TREF(dollar_zcompile); s2pool(&(v->str)); break; case SV_ZDIR: setzdir(NULL, v); if (v->str.len != dollar_zdir.str.len || 0 != memcmp(v->str.addr, dollar_zdir.str.addr, v->str.len)) gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ZDIROUTOFSYNC, 4, v->str.len, v->str.addr, dollar_zdir.str.len, dollar_zdir.str.addr); SKIP_DEVICE_IF_NOT_NEEDED(v); s2pool(&(v->str)); break; case SV_ZSTEP: *v = dollar_zstep; break; case SV_ZMODE: *v = TREF(dollar_zmode); break; case SV_ZMAXTPTIME: i2mval(v, TREF(dollar_zmaxtptime)); break; case SV_ZPOS: getzposition(v); break; case SV_ZPROC: getzprocess(); *v = dollar_zproc; break; case SV_ZLEVEL: count = dollar_zlevel(); MV_FORCE_MVAL(v, count); break; case SV_ZROUTINES: if (!TREF(zro_root)) zro_init(); v->mvtype = MV_STR; v->str = TREF(dollar_zroutines); s2pool(&(v->str)); break; case SV_ZSOURCE: v->mvtype = MV_STR; v->str = dollar_zsource.str; break; case SV_ZSTATUS: *v = dollar_zstatus; s2pool(&(v->str)); break; case SV_ZTRAP: v->mvtype = MV_STR; v->str = dollar_ztrap.str; assert(!v->str.len || !ztrap_explicit_null); s2pool(&(v->str)); break; case SV_DEVICE: get_dlr_device(v); break; case SV_KEY: get_dlr_key(v); break; case SV_ZVERSION: v->mvtype = MV_STR; v->str.addr = (char *)gtm_release_name; v->str.len = gtm_release_name_len; break; case SV_ZSYSTEM: MV_FORCE_MVAL(v, dollar_zsystem); break; case SV_ZCSTATUS: /* Maintain the external $ZCSTATUS == 1 for SUCCESS on UNIX while internal good is 0 */ MV_FORCE_MVAL(v, UNIX_ONLY((0 == TREF(dollar_zcstatus)) ? 1 : ) TREF(dollar_zcstatus)); break; case SV_ZEDITOR: MV_FORCE_MVAL(v, dollar_zeditor); break; case SV_QUIT: MV_FORCE_MVAL(v, dollar_quit()); break; case SV_ECODE: ecode_get(-1, v); break; case SV_ESTACK: count = (dollar_zlevel() - 1) - dollar_estack_delta.m[0]; MV_FORCE_MVAL(v, count); break; case SV_ETRAP: v->mvtype = MV_STR; v->str = dollar_etrap.str; assert(!v->str.len || !ztrap_explicit_null); s2pool(&(v->str)); break; case SV_STACK: count = (dollar_zlevel() - 1); MV_FORCE_MVAL(v, count); break; case SV_ZERROR: v->mvtype = MV_STR; v->str = dollar_zerror.str; s2pool(&(v->str)); break; case SV_ZYERROR: v->mvtype = MV_STR; v->str = dollar_zyerror.str; s2pool(&(v->str)); break; case SV_ZINTERRUPT: v->mvtype = MV_STR; v->str = dollar_zinterrupt.str; s2pool(&(v->str)); break; case SV_ZININTERRUPT: MV_FORCE_MVAL(v, dollar_zininterrupt); break; case SV_ZJOB: MV_FORCE_UMVAL(v, dollar_zjob); break; case SV_ZDATE_FORM: MV_FORCE_MVAL(v, TREF(zdate_form)); break; case SV_ZTEXIT: *v = dollar_ztexit; break; case SV_ZALLOCSTOR: ucount = (gtm_uint64_t)totalAlloc + (gtm_uint64_t)totalAllocGta; ui82mval(v, ucount); break; case SV_ZREALSTOR: ucount = (gtm_uint64_t)totalRmalloc + (gtm_uint64_t)totalRallocGta; ui82mval(v, ucount); break; case SV_ZUSEDSTOR: ucount = (gtm_uint64_t)totalUsed + (gtm_uint64_t)totalUsedGta; ui82mval(v, ucount); break; case SV_ZCHSET: v->mvtype = MV_STR; v->str = dollar_zchset; break; case SV_ZPATNUMERIC: v->mvtype = MV_STR; v->str = dollar_zpatnumeric; break; case SV_ZTNAME: case SV_ZTCODE: /* deprecated */ # ifdef GTM_TRIGGER if (NULL == dollar_ztname) memcpy(v, &literal_null, SIZEOF(mval)); else { v->mvtype = MV_STR; v->str.addr = dollar_ztname->addr; v->str.len = dollar_ztname->len; } break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTDATA: # ifdef GTM_TRIGGER /* Value comes from GT.M, but it might be numeric and need conversion to a string */ assert(!dollar_ztdata || MV_DEFINED(dollar_ztdata)); if (NULL != dollar_ztdata) MV_FORCE_STR(dollar_ztdata); memcpy(v, (NULL != dollar_ztdata) ? dollar_ztdata : &literal_null, SIZEOF(mval)); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTDELIM: # ifdef GTM_TRIGGER assert(!dollar_ztdelim || MV_DEFINED(dollar_ztdelim)); if (NULL == dollar_ztdelim || !(MV_STR & dollar_ztdelim->mvtype) || (0 == dollar_ztdelim->str.len)) memcpy(v, &literal_null, SIZEOF(mval)); else memcpy(v, dollar_ztdelim, SIZEOF(mval)); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTOLDVAL: # ifdef GTM_TRIGGER /* Value comes from GT.M, but it might be numeric and need conversion to a string */ assert(!dollar_ztoldval || MV_DEFINED(dollar_ztoldval)); if (NULL != dollar_ztoldval) MV_FORCE_STR(dollar_ztoldval); memcpy(v, (NULL != dollar_ztoldval) ? dollar_ztoldval : &literal_null, SIZEOF(mval)); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTRIGGEROP: # ifdef GTM_TRIGGER /* Value comes from GT.M, but assert it's a string */ assert(!dollar_ztriggerop || (MV_STR & dollar_ztriggerop->mvtype)); memcpy(v, (NULL != dollar_ztriggerop) ? dollar_ztriggerop : &literal_null, SIZEOF(mval)); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTUPDATE: # ifdef GTM_TRIGGER /* Value comes from GT.M, but if there were no delims involved, the value will be undefined, and * we return a "literal_null". */ memcpy(v, ((NULL != dollar_ztupdate && (MV_STR & dollar_ztupdate->mvtype)) ? dollar_ztupdate : &literal_null), SIZEOF(mval)); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTVALUE: # ifdef GTM_TRIGGER /* Value comes from user-land so make sure things are proper */ assert(!dollar_ztvalue || MV_DEFINED(dollar_ztvalue)); if (NULL != dollar_ztvalue) MV_FORCE_STR(dollar_ztvalue); memcpy(v, (NULL != dollar_ztvalue) ? dollar_ztvalue : &literal_null, SIZEOF(mval)); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTWORMHOLE: # ifdef GTM_TRIGGER /* Value comes from user-land so make sure things are proper */ mvp = &dollar_ztwormhole; if (MV_DEFINED(mvp)) { MV_FORCE_STR(mvp); memcpy(v, mvp, SIZEOF(mval)); } else memcpy(v, &literal_null, SIZEOF(mval)); ztwormhole_used = TRUE; break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTSLATE: # ifdef GTM_TRIGGER /* Value comes from user-land so make sure things are proper */ assert(MV_DEFINED((&dollar_ztslate))); mvp = &dollar_ztslate; MV_FORCE_STR(mvp); memcpy(v, mvp, SIZEOF(mval)); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZTLEVEL: # ifdef GTM_TRIGGER MV_FORCE_MVAL(v, gtm_trigger_depth); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZONLNRLBK: # ifdef UNIX count = TREF(dollar_zonlnrlbk); MV_FORCE_MVAL(v, count); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZCLOSE: # ifdef UNIX count = TREF(dollar_zclose); MV_FORCE_MVAL(v, count); break; # else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP); # endif case SV_ZKEY: get_dlr_zkey(v); break; default: assertpro(FALSE); } }
int op_fnzsearch(mval *file, mint indx, mval *ret) { struct stat statbuf; int stat_res; parse_blk pblk; plength *plen, pret; char buf1[MAX_FBUFF + 1]; /* buffer to hold translated name */ mval sub; mstr tn; lv_val *ind_tmp; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; ESTABLISH_RET(fnzsrch_ch, -1); TREF(fnzsearch_nullsubs_sav) = TREF(lv_null_subs); TREF(lv_null_subs) = LVNULLSUBS_OK; /* $ZSearch processing depends on this */ MV_FORCE_STR(file); if (file->str.len > MAX_FBUFF) rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, file->str.len, MAX_FBUFF); MV_FORCE_MVAL(((mval *)TADR(fnzsearch_sub_mval)), indx); TREF(fnzsearch_lv_vars) = op_srchindx(VARLSTCNT(2) TREF(zsearch_var), (mval *)TADR(fnzsearch_sub_mval)); if (TREF(fnzsearch_lv_vars)) { assert((TREF(fnzsearch_lv_vars))->v.mvtype & MV_STR); if ((file->str.len != (TREF(fnzsearch_lv_vars))->v.str.len) || memcmp(file->str.addr, (TREF(fnzsearch_lv_vars))->v.str.addr, file->str.len)) { op_kill(TREF(fnzsearch_lv_vars)); TREF(fnzsearch_lv_vars) = NULL; } } if (TREF(fnzsearch_lv_vars)) { for (;;) { pret.p.pint = pop_top(TREF(fnzsearch_lv_vars), ret); /* get next element off the top */ if (!ret->str.len) break; memcpy(buf1, ret->str.addr, ret->str.len); buf1[ret->str.len] = 0; STAT_FILE(buf1, &statbuf, stat_res); if (-1 == stat_res) { if (errno == ENOENT) continue; rts_error(VARLSTCNT(1) errno); } break; } } else { memset(&pblk, 0, SIZEOF(pblk)); pblk.buffer = buf1; pblk.buff_size = MAX_FBUFF; if (!(parse_file(&file->str, &pblk) & 1)) { ret->mvtype = MV_STR; ret->str.len = 0; } else { assert(!TREF(fnzsearch_lv_vars)); buf1[pblk.b_esl] = 0; /* establish new search context */ TREF(fnzsearch_lv_vars) = op_putindx(VARLSTCNT(2) TREF(zsearch_var), TADR(fnzsearch_sub_mval)); (TREF(fnzsearch_lv_vars))->v = *file; /* zsearch_var(indx)=original spec */ if (!(pblk.fnb & F_WILD)) { sub.mvtype = MV_STR; sub.str.len = pblk.b_esl; sub.str.addr = buf1; s2pool(&sub.str); ind_tmp = op_putindx(VARLSTCNT(2) TREF(fnzsearch_lv_vars), &sub); ind_tmp->v.mvtype = MV_STR; ind_tmp->v.str.len = 0; plen = (plength *)&ind_tmp->v.m[1]; plen->p.pblk.b_esl = pblk.b_esl; plen->p.pblk.b_dir = pblk.b_dir; plen->p.pblk.b_name = pblk.b_name; plen->p.pblk.b_ext = pblk.b_ext; } else dir_srch(&pblk); for (;;) { pret.p.pint = pop_top(TREF(fnzsearch_lv_vars), ret); /* get next element off the top */ if (!ret->str.len) break; memcpy(buf1, ret->str.addr, ret->str.len); buf1[ret->str.len] = 0; STAT_FILE(buf1, &statbuf, stat_res); if (-1 == stat_res) { if (errno == ENOENT) continue; rts_error(VARLSTCNT(1) errno); } break; } } } assert((0 == ret->str.len) || (pret.p.pblk.b_esl == ret->str.len)); TREF(lv_null_subs) = TREF(fnzsearch_nullsubs_sav); REVERT; return pret.p.pint; }
void op_fnorder(lv_val *src, mval *key, mval *dst) { mval tmp_sbs; int length; boolean_t is_canonical, is_fnnext, get_first; lvTree *lvt; lvTreeNode *node; uint4 mvt; /* Local copy of mvtype, bit ands use a int4, so do conversion once */ mstr *str; int4 intval; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; is_fnnext = TREF(in_op_fnnext); TREF(in_op_fnnext) = FALSE; if (src && (lvt = LV_GET_CHILD(src))) /* caution: assignment */ { MV_FORCE_DEFINED(key); /* If last subscript is null, $ORDER returns the first subscript in that level. * With the obsoleted $NEXT function, a subscript of -1 also triggers the same behavior. */ get_first = FALSE; if (MV_IS_STRING(key) && (0 == key->str.len)) get_first = TRUE; else if (is_fnnext) { mvt = key->mvtype; if (!(mvt & (MV_NM | MV_NUM_APPROX))) { /* Not currently in numeric form. Is it cannonical? */ if (val_iscan(key)) { /* Yes, convert it to numeric */ (void)s2n(key); mvt = key->mvtype; if (!(mvt & MV_NM)) rts_error(VARLSTCNT(1) ERR_NUMOFLOW); } else /* No, not numeric. Note the fact for future reference */ mvt = key->mvtype |= MV_NUM_APPROX; } if (MV_IS_TRUEINT(key, &intval) && (MINUS_ONE == key->m[1])) get_first = TRUE; } if (get_first) node = lvAvlTreeFirst(lvt); else { is_canonical = MV_IS_CANONICAL(key); if (!is_canonical) { assert(!TREE_KEY_SUBSCR_IS_CANONICAL(key->mvtype)); if (TREF(local_collseq)) { ALLOC_XFORM_BUFF(key->str.len); tmp_sbs.mvtype = MV_STR; tmp_sbs.str.len = TREF(max_lcl_coll_xform_bufsiz); assert(NULL != TREF(lcl_coll_xform_buff)); tmp_sbs.str.addr = TREF(lcl_coll_xform_buff); do_xform(TREF(local_collseq), XFORM, &key->str, &tmp_sbs.str, &length); tmp_sbs.str.len = length; s2pool(&(tmp_sbs.str)); key = &tmp_sbs; } } else { /* Need to set canonical bit before calling tree search functions. * But input mval could be read-only so cannot modify that even if temporarily. * So take a copy of the mval and modify that instead. */ tmp_sbs = *key; key = &tmp_sbs; MV_FORCE_NUM(key); TREE_KEY_SUBSCR_SET_MV_CANONICAL_BIT(key); /* used by the lvTreeKeyNext function */ } node = lvAvlTreeKeyNext(lvt, key); } /* If STDNULLCOLL, skip to the next subscript should the current subscript be "" */ if (TREF(local_collseq_stdnull) && (NULL != node) && LV_NODE_KEY_IS_NULL_SUBS(node)) { assert(LVNULLSUBS_OK == TREF(lv_null_subs)); node = lvAvlTreeNext(node); } } else node = NULL; if (NULL == node) { if (!is_fnnext) { dst->mvtype = MV_STR; dst->str.len = 0; } else MV_FORCE_MVAL(dst, -1); } else { LV_NODE_GET_KEY(node, dst); /* Get node key into "dst" depending on the structure type of "node" */ /* Code outside lv_tree.c does not currently know to make use of MV_CANONICAL bit so reset it * until the entire codebase gets fixed to maintain MV_CANONICAL bit accurately at which point, * this RESET can be removed */ TREE_KEY_SUBSCR_RESET_MV_CANONICAL_BIT(dst); if (TREF(local_collseq) && MV_IS_STRING(dst)) { ALLOC_XFORM_BUFF(dst->str.len); assert(NULL != TREF(lcl_coll_xform_buff)); tmp_sbs.str.addr = TREF(lcl_coll_xform_buff); tmp_sbs.str.len = TREF(max_lcl_coll_xform_bufsiz); do_xform(TREF(local_collseq), XBACK, &dst->str, &tmp_sbs.str, &length); tmp_sbs.str.len = length; s2pool(&(tmp_sbs.str)); dst->str = tmp_sbs.str; } } }
STATICFNDEF int4 update_trigger_hash_value(char *trigvn, int trigvn_len, char **values, uint4 *value_len, stringkey *set_hash, stringkey *kill_hash, int old_trig_index, int new_trig_index) { sgmnt_addrs *csa; int hash_index; mval key_val; uint4 len; mval mv_hash; mval mv_hash_indx; int num_len; char *ptr; int4 result; char save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)]; gv_key *save_gv_currkey; gd_region *save_gv_cur_region; gv_namehead *save_gv_target; sgm_info *save_sgm_info_ptr; char tmp_str[MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT]; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; SAVE_TRIGGER_REGION_INFO; SWITCH_TO_DEFAULT_REGION; assert(0 != gv_target->root); if (NULL != strchr(values[CMD_SUB], 'S')) { if (search_trigger_hash(trigvn, trigvn_len, set_hash, old_trig_index, &hash_index)) { MV_FORCE_UMVAL(&mv_hash, set_hash->hash_code); MV_FORCE_MVAL(&mv_hash_indx, hash_index); BUILD_HASHT_SUB_MSUB_MSUB_CURRKEY(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx); if (!gvcst_get(&key_val)) { /* There has to be a #TRHASH entry */ assert(FALSE); rts_error(VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn, LEN_AND_LIT("\"#TRHASH\""), set_hash->str.len, set_hash->str.addr); } assert((MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT) >= key_val.str.len); len = STRLEN(key_val.str.addr); memcpy(tmp_str, key_val.str.addr, len); ptr = tmp_str + len; *ptr++ = '\0'; num_len = 0; I2A(ptr, num_len, new_trig_index); len += num_len + 1; SET_TRIGGER_GLOBAL_SUB_MSUB_MSUB_STR(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx, tmp_str, len, result); if (PUT_SUCCESS != result) { RESTORE_TRIGGER_REGION_INFO; return result; } } else { /* There has to be an entry with the old hash value, we just looked it up */ assert(FALSE); rts_error(VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn, LEN_AND_LIT("\"#TRHASH\""), set_hash->str.len, set_hash->str.addr); } } if (search_trigger_hash(trigvn, trigvn_len, kill_hash, old_trig_index, &hash_index)) { MV_FORCE_UMVAL(&mv_hash, kill_hash->hash_code); MV_FORCE_MVAL(&mv_hash_indx, hash_index); BUILD_HASHT_SUB_MSUB_MSUB_CURRKEY(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx); if (!gvcst_get(&key_val)) { /* There has to be a #TRHASH entry */ assert(FALSE); rts_error(VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn, LEN_AND_LIT("\"#TRHASH\""), kill_hash->str.len, kill_hash->str.addr); } assert((MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT) >= key_val.str.len); len = STRLEN(key_val.str.addr); memcpy(tmp_str, key_val.str.addr, len); ptr = tmp_str + len; *ptr++ = '\0'; num_len = 0; I2A(ptr, num_len, new_trig_index); len += num_len + 1; SET_TRIGGER_GLOBAL_SUB_MSUB_MSUB_STR(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx, tmp_str, len, result); if (PUT_SUCCESS != result) { RESTORE_TRIGGER_REGION_INFO; return result; } } else { /* There has to be an entry with the old hash value, we just looked it up */ assert(FALSE); rts_error(VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn, LEN_AND_LIT("\"#TRHASH\""), kill_hash->str.len, kill_hash->str.addr); } RESTORE_TRIGGER_REGION_INFO; return PUT_SUCCESS; }
void zshow_locks(zshow_out *output) { static readonly char zal[] = "ZAL "; static readonly char lck[] = "LOCK "; static readonly char lvl[] = " LEVEL="; mval v; mlk_pvtblk *temp; for (temp = mlk_pvt_root; temp; temp = temp->next) { if (!temp->granted) continue; if (temp->nodptr && (temp->nodptr->owner != process_id || temp->sequence != temp->nodptr->sequence)) continue; output->flush = FALSE; if (temp->level && temp->zalloc) { v.str.addr = &zal[0]; v.str.len = sizeof(zal) - 1; zshow_output(output,&v.str); zshow_format_lock(output,temp); output->flush = TRUE; v.str.len = 0; zshow_output(output,&v.str); output->flush = FALSE; v.str.addr = &lck[0]; v.str.len = sizeof(lck) - 1; zshow_output(output,&v.str); zshow_format_lock(output,temp); v.str.addr = &lvl[0]; v.str.len = sizeof(lvl) - 1; zshow_output(output,&v.str); MV_FORCE_MVAL(&v,temp->level) ; mval_write(output,&v,TRUE); } else if (temp->level) { v.str.addr = &lck[0]; v.str.len = sizeof(lck) - 1; zshow_output(output,&v.str); zshow_format_lock(output,temp); v.str.addr = &lvl[0]; v.str.len = sizeof(lvl) - 1; zshow_output(output,&v.str); MV_FORCE_MVAL(&v,temp->level) ; mval_write(output,&v,TRUE); }else if (temp->zalloc) { v.str.addr = &zal[0]; v.str.len = sizeof(zal) - 1; zshow_output(output,&v.str); zshow_format_lock(output,temp); output->flush = TRUE; v.str.len = 0; zshow_output(output,&v.str); } } }
void gvcmz_doop(unsigned char query_code, unsigned char reply_code, mval *v) { unsigned char *ptr; short len, temp_short; int4 status, max_reply_len; struct CLB *lnk; error_def(ERR_BADSRVRNETMSG); lnk = gv_cur_region->dyn.addr->cm_blk; lnk->ast = 0; /* all database queries are sync */ lnk->cbl = 1 + /* HDR */ gv_currkey->end + /* key */ sizeof(unsigned short) + /* gv_key.top */ sizeof(unsigned short) + /* gv_key.end */ sizeof(unsigned short) + /* gv_key.prev */ sizeof(unsigned char) + /* gv_key.base */ sizeof(unsigned char) + /* regnum */ sizeof(unsigned short); /* size for variable len SUBSC */ if (CMMS_Q_PUT == query_code) lnk->cbl += (sizeof(unsigned short) + v->str.len); /* VALUE + length */ if (CMMS_Q_GET == query_code || CMMS_Q_QUERY == query_code && ((link_info *)lnk->usr)->query_is_queryget) max_reply_len = lnk->mbl + sizeof(unsigned short) + MAX_STRLEN; /* can't predict the length of data value */ else max_reply_len = lnk->mbl; if (stringpool.top < stringpool.free + max_reply_len) stp_gcol(max_reply_len); lnk->mbf = stringpool.free; ptr = lnk->mbf; *ptr++ = query_code; /* temp_short = gv_currkey->end + sizeof(gv_key) + 1; */ temp_short = gv_currkey->end + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(char) + 1; CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); *ptr++ = gv_cur_region->cmx_regnum; CM_PUT_SHORT(ptr, gv_currkey->top, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); CM_PUT_SHORT(ptr, gv_currkey->end, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); CM_PUT_SHORT(ptr, gv_currkey->prev, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); memcpy(ptr, gv_currkey->base, gv_currkey->end + 1); if (query_code == CMMS_Q_PUT) { ptr += gv_currkey->end + 1; temp_short = (short)v->str.len; assert((int4)temp_short == v->str.len); /* short <- int4 assignment lossy? */ CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); memcpy(ptr,v->str.addr, v->str.len); } status = cmi_write(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } if (CMMS_Q_PUT == query_code || CMMS_Q_ZWITHDRAW == query_code || CMMS_Q_KILL == query_code) { status = cmi_read(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } ptr = lnk->mbf; if (reply_code != *ptr) { if (*ptr != CMMS_E_ERROR) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); gvcmz_errmsg(lnk,FALSE); } return; } status = cmi_read(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } ptr = lnk->mbf; if (reply_code != *ptr) { if (CMMS_R_UNDEF != *ptr || CMMS_Q_GET != query_code) { if (CMMS_E_ERROR != *ptr) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); gvcmz_errmsg(lnk, FALSE); } return; } ptr++; if (CMMS_R_DATA == reply_code) { CM_GET_SHORT(temp_short, ptr, ((link_info *)(lnk->usr))->convert_byteorder); if (1 != temp_short) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); ptr += sizeof(short); status = *ptr; /* Temp assignment to status gets rid of compiler warning in MV_FORCE_MVAL macro */ MV_FORCE_MVAL(v, status); return; } if (reply_code == CMMS_R_PREV || reply_code == CMMS_R_QUERY || reply_code == CMMS_R_ORDER) { CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); if (1 == len) { MV_FORCE_MVAL(v, 0); } else { if (*ptr++ != gv_cur_region->cmx_regnum) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); /* memcpy(gv_altkey, ptr, len - 1); */ CM_GET_USHORT(gv_altkey->top, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); CM_GET_USHORT(gv_altkey->end, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); CM_GET_USHORT(gv_altkey->prev, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); memcpy(gv_altkey->base, ptr, len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short)); ptr += (len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short)); MV_FORCE_MVAL(v, 1); } if (CMMS_R_QUERY != reply_code || 1 == len || !((link_info *)lnk->usr)->query_is_queryget) { if (CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget) v->mvtype = 0; /* force undefined to distinguish $Q returning "" from value of QUERYGET being 0 */ return; } } assert(CMMS_R_GET == reply_code || CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget && 1 < len); CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); assert(ptr >= stringpool.base && ptr + len < stringpool.top); /* incoming message is in stringpool */ v->mvtype = MV_STR; v->str.len = len; v->str.addr = (char *)stringpool.free; /* we don't need the reply msg anymore, can overwrite reply */ memcpy(v->str.addr, ptr, len); /* so that we don't leave a gaping hole in the stringpool */ stringpool.free += len; return; }
void op_indtext(mval *lab, mint offset, mval *rtn, mval *dst) { bool rval; mstr *obj, object; mval mv_off; oprtype opt; triple *ref; icode_str indir_src; error_def(ERR_INDMAXNEST); error_def(ERR_STACKOFLOW); error_def(ERR_STACKCRIT); MV_FORCE_STR(lab); indir_src.str.len = lab->str.len; indir_src.str.len += SIZEOF("+^") - 1; indir_src.str.len += MAX_NUM_SIZE; indir_src.str.len += rtn->str.len; ENSURE_STP_FREE_SPACE(indir_src.str.len); DBG_MARK_STRINGPOOL_UNEXPANDABLE; /* Now that we have ensured enough space in the stringpool, we dont expect any more * garbage collections or expansions until we are done with the below initialization. */ /* Push an mval pointing to the complete entry ref on to the stack so the string is valid even * if garbage collection occurs before cache_put() */ PUSH_MV_STENT(MVST_MVAL); mv_chain->mv_st_cont.mvs_mval.mvtype = 0; /* so stp_gcol (if invoked below) does not get confused by this otherwise * incompletely initialized mval in the M-stack */ mv_chain->mv_st_cont.mvs_mval.str.addr = (char *)stringpool.free; memcpy(stringpool.free, lab->str.addr, lab->str.len); stringpool.free += lab->str.len; *stringpool.free++ = '+'; MV_FORCE_MVAL(&mv_off, offset); MV_FORCE_STRD(&mv_off); /* goes at stringpool.free. we already made enough space in the stp_gcol() call */ *stringpool.free++ = '^'; memcpy(stringpool.free, rtn->str.addr, rtn->str.len); stringpool.free += rtn->str.len; mv_chain->mv_st_cont.mvs_mval.str.len = INTCAST(stringpool.free - (unsigned char*)mv_chain->mv_st_cont.mvs_mval.str.addr); mv_chain->mv_st_cont.mvs_mval.mvtype = MV_STR; /* initialize mvtype now that mval has been otherwise completely set up */ DBG_MARK_STRINGPOOL_EXPANDABLE; /* Now that we are done with stringpool.free initializations, mark as free for expansion */ indir_src.str = mv_chain->mv_st_cont.mvs_mval.str; indir_src.code = indir_text; if (NULL == (obj = cache_get(&indir_src))) { comp_init(&indir_src.str); rval = f_text(&opt, OC_FNTEXT); if (!comp_fini(rval, &object, OC_IRETMVAL, &opt, indir_src.str.len)) { assert(mv_chain->mv_st_type == MVST_MVAL); POP_MV_STENT(); return; } indir_src.str.addr = mv_chain->mv_st_cont.mvs_mval.str.addr; cache_put(&indir_src, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); assert(mv_chain->mv_st_type == MVST_MVAL); POP_MV_STENT(); /* unwind the mval entry before the new frame gets added by comp_indir below */ comp_indr(&object); return; } *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); assert(mv_chain->mv_st_type == MVST_MVAL); POP_MV_STENT(); /* unwind the mval entry before the new frame gets added by comp_indir below */ comp_indr(obj); return; }
STATICFNDEF void cleanup_trigger_name(char *trigvn, int trigvn_len, char *trigger_name, int trigger_name_len) { sgmnt_addrs *csa; mname_entry gvent; gv_namehead *hasht_tree; int4 result; char save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)]; char save_altkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)]; gv_key *save_gv_altkey; gv_key *save_gv_currkey; gd_region *save_gv_cur_region; gv_namehead *save_gv_target; gv_namehead *save_gvtarget; sgm_info *save_sgm_info_ptr; char trunc_name[MAX_TRIGNAME_LEN + 1]; uint4 used_trigvn_len; mval val; mval *val_ptr; char val_str[MAX_DIGITS_IN_INT + 1]; int var_count; boolean_t is_auto_name; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; /* assume user defined name or auto gen name whose GVN < 21 chars */ is_auto_name = FALSE; if (!trigger_user_name(trigger_name, trigger_name_len)) { /* auto gen name uses #TNCOUNT and #SEQNO under #TNAME */ is_auto_name = TRUE; used_trigvn_len = MIN(trigvn_len, MAX_AUTO_TRIGNAME_LEN); memcpy(trunc_name, trigvn, used_trigvn_len); } SAVE_TRIGGER_REGION_INFO; SWITCH_TO_DEFAULT_REGION; if (0 != gv_target->root) { if (is_auto_name) { /* $get(^#t("#TNAME",<trunc_name>,"#TNCOUNT")) */ BUILD_HASHT_SUB_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trunc_name, used_trigvn_len, LITERAL_HASHTNCOUNT, STRLEN(LITERAL_HASHTNCOUNT)); if (gvcst_get(&val)) { /* only long autogenerated names have a #TNCOUNT entry */ val_ptr = &val; var_count = MV_FORCE_INT(val_ptr); if (1 == var_count) { /* kill ^#t("#TNAME",<trunc_name>) to kill #TNCOUNT and #SEQNO */ BUILD_HASHT_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trunc_name, used_trigvn_len); gvcst_kill(TRUE); } else { var_count--; MV_FORCE_MVAL(&val, var_count); /* set ^#t("#TNAME",GVN,"#TNCOUNT")=var_count */ SET_TRIGGER_GLOBAL_SUB_SUB_SUB_MVAL(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trunc_name, used_trigvn_len, LITERAL_HASHTNCOUNT, STRLEN(LITERAL_HASHTNCOUNT), val, result); assert(PUT_SUCCESS == result); /* The count size can only decrease */ } } } /* kill ^#t("#TNAME",<trigger_name>,:) or zkill ^#t("#TNAME",<trigger_name>) if is_auto_name==FALSE */ BUILD_HASHT_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trigger_name, trigger_name_len - 1); gvcst_kill(is_auto_name); } RESTORE_TRIGGER_REGION_INFO; }