int cmp_dv_box (caddr_t dv, caddr_t box) { NUMERIC_VAR (dn1); NUMERIC_VAR (dn2); dtp_t dtp1 = dv_ext_to_num ((db_buf_t) dv, (caddr_t) & dn1); dtp_t dtp2; dtp_t res_dtp; NUM_TO_MEM (dn2, dtp2, box); if (dtp1 == DV_DB_NULL || dtp2 == DV_DB_NULL) GPF_T1 ("not supposed to be null in comparison"); if (n_coerce ((caddr_t) & dn1, (caddr_t) & dn2, dtp1, dtp2, &res_dtp)) { switch (res_dtp) { case DV_LONG_INT: return (NUM_COMPARE (*(boxint *) &dn1, *(boxint *) &dn2)); case DV_SINGLE_FLOAT: return cmp_double (*(float *) &dn1, *(float *) &dn2, FLT_EPSILON); case DV_DOUBLE_FLOAT: return cmp_double (*(double *) &dn1, *(double *) &dn2, DBL_EPSILON); case DV_NUMERIC: return (numeric_compare_dvc ((numeric_t) &dn1, (numeric_t) &dn2)); } } else sqlr_new_error ("22003", "SR082", "Non numeric comparison"); return 0; }
/* INFO: toplevel udt_clr_method_call */ caddr_t dotnet_call (caddr_t * type_vec, int n_args, int _asm_type, caddr_t asm_name, caddr_t type, caddr_t method, void *udt, int sec_unrestricted) { MonoArray *v_args, *i_array = NULL, *o_array = NULL; MonoObject *mono_list; caddr_t ret = NULL; MonoDomain *domain = virtuoso_domain; get_mono_thread (); v_args = MAKE_PARAM_ARRAY (domain, 7); if (param_to_mono_array (type_vec, n_args, &i_array, &o_array)) sqlr_new_error ("22023", "MN009", "Can't convert parameters"); SET_INT_ARG (domain, v_args, 0, _asm_type); SET_INT_ARG (domain, v_args, 1, sec_unrestricted); SET_STRING_ARG (domain, v_args, 2, asm_name); SET_STRING_ARG (domain, v_args, 3, type); SET_STRING_ARG (domain, v_args, 4, method); mono_array_set (v_args, gpointer, 5, i_array); mono_array_set (v_args, gpointer, 6, o_array); mono_list = call_mono (VIRTCLR_NAME, "VInvoke:call_method_asm", v_args, domain); ret = sa_to_dk ((MonoArray *) mono_list, 0, 0, NULL); return ret; }
caddr_t bif_string_time (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t str = bif_string_or_wide_or_null_arg (qst, args, 0, "stringtime"); caddr_t res; char temp[100]; char *txt; caddr_t err_msg = NULL; if (!str) sqlr_new_error ("22002", "DT009", "Nulls not allowed as parameters to stringtime"); if (DV_WIDESTRINGP (str)) { box_wide_string_as_narrow (str, temp, sizeof (temp), QST_CHARSET (qst)); txt = temp; } else txt = str; res = dk_alloc_box (DT_LENGTH, DV_DATETIME); odbc_string_to_time_dt (txt, res, &err_msg); if (NULL != err_msg) { caddr_t err = srv_make_new_error ("22007", "DT010", "Can't convert '%s' to time : %s", str, err_msg); dk_free_box (err_msg); dk_free_box (res); sqlr_resignal (err); } return res; }
caddr_t bif_merge_nasa_tjd_to_datetime (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { boxint num = bif_long_arg (qst, args, 0, "merge_nasa_tjd_to_datetime"); caddr_t res = dk_alloc_box_zero (DT_LENGTH, DV_DATETIME); DT_SET_DAY (res, num + NASA_TJD_OFFSET); if (1 < BOX_ELEMENTS (args)) { double frac = bif_double_arg (qst, args, 1, "merge_nasa_tjd_to_datetime"); boxint frac_microsec = frac * (60*60*24*1000000.0); if ((0 > frac_microsec) || (60*60*24*(boxint)(1000000) <= frac_microsec)) sqlr_new_error ("22023", "SR644", "Fraction of julian day should be nonnegative and less than 1"); DT_SET_FRACTION (res, (frac_microsec % 1000000) * 1000); frac_microsec = frac_microsec / 1000000; DT_SET_SECOND (res, (frac_microsec % 60)); frac_microsec = frac_microsec / 60; DT_SET_MINUTE (res, (frac_microsec % 60)); frac_microsec = frac_microsec / 60; DT_SET_HOUR (res, frac_microsec); DT_SET_DT_TYPE (res, DT_TYPE_DATETIME); } else DT_SET_DT_TYPE (res, DT_TYPE_DATE); return res; }
caddr_t numeric_bin_op (numeric_bop_t num_op, numeric_t x, numeric_t y, caddr_t * qst, state_slot_t * target) { int rc; caddr_t res_box = NULL; if (target) { res_box = QST_GET (qst, target); if (DV_NUMERIC == DV_TYPE_OF (res_box)) { rc = num_op ((numeric_t) res_box, x, y); } else { res_box = (caddr_t) numeric_allocate (); rc = num_op ((numeric_t) res_box, x, y); qst_set (qst, target, res_box); } } else { res_box = (caddr_t) numeric_allocate (); rc = num_op ((numeric_t) res_box, x, y); } if (rc != NUMERIC_STS_SUCCESS) { char state[10]; char msg[200]; numeric_error (rc, state, sizeof (state), msg, sizeof (msg)); sqlr_new_error (state, "SR083", "%s", msg); } return res_box; }
caddr_t bif_timestamp (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { query_instance_t *qi = (query_instance_t *) QST_INSTANCE (qst); lock_trx_t *lt = qi->qi_trx; if (!lt) sqlr_new_error ("25000", "DT008", "now/get_timestamp: No current txn for timestamp"); return lt_timestamp_box (lt); }
int dt_print_to_buffer (char *buf, caddr_t arg, int mode) { int res = 0; int arg_dt_type = DT_DT_TYPE (arg); TIMESTAMP_STRUCT ts; if (0 == ((DT_PRINT_MODE_YMD | DT_PRINT_MODE_HMS) & mode)) mode |= ((DT_TYPE_TIME == arg_dt_type) ? DT_PRINT_MODE_HMS : ((DT_TYPE_DATE == arg_dt_type) ? DT_PRINT_MODE_YMD : (DT_PRINT_MODE_YMD | DT_PRINT_MODE_HMS)) ); if ((DT_PRINT_MODE_YMD & mode) && (DT_TYPE_TIME == arg_dt_type)) sqlr_new_error ("22023", "SR592", "Bit 4 in print mode requires DATE or DATETIME argument, not TIME"); if ((DT_PRINT_MODE_HMS & mode) && (DT_TYPE_DATE == arg_dt_type)) sqlr_new_error ("22023", "SR593", "Bit 2 in print mode requires TIME or DATETIME argument, not DATE"); dt_to_GMTimestamp_struct (arg, &ts); if (DT_PRINT_MODE_YMD & mode) res += sprintf (buf, "%04d-%02d-%02d", ts.year, ts.month, ts.day); if ((DT_PRINT_MODE_YMD & mode) && (DT_PRINT_MODE_HMS & mode)) buf[res++] = ((DT_PRINT_MODE_XML & mode) ? 'T' : ' '); if (DT_PRINT_MODE_HMS & mode) { res += sprintf (buf + res, "%02d:%02d:%02d", ts.hour, ts.minute, ts.second); if (ts.fraction) { if (ts.fraction % 1000) res += sprintf (buf + res, ".%09d", (int)ts.fraction); else if (ts.fraction % 1000000) res += sprintf (buf + res, ".%06d", (int)(ts.fraction / 1000)); else res += sprintf (buf + res, ".%03d", (int)(ts.fraction / 1000000)); } } if (DT_PRINT_MODE_XML & mode) { strcpy (buf + res, "Z"); return res + 1; } else { strcpy (buf + res, " GMT"); return res + 4; } }
caddr_t bif_date_arg (caddr_t * qst, state_slot_t ** args, int nth, char *func) { caddr_t arg = bif_arg (qst, args, nth, func); dtp_t dtp = DV_TYPE_OF (arg); if (dtp != DV_DATETIME && dtp != DV_BIN) sqlr_new_error ("22007", "DT001", "Function %s needs a datetime, date or time as argument %d, not an arg of type %s (%d)", func, nth + 1, dv_type_title (dtp), dtp); return arg; }
caddr_t bif_date_diff (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t unit = bif_string_arg (qst, args, 0, "datediff"); caddr_t dt1 = bif_date_arg (qst, args, 1, "datediff"); caddr_t dt2 = bif_date_arg (qst, args, 2, "datediff"); boxint s1 = (boxint)DT_DAY (dt1) * 24 * 60 * 60 + (boxint)DT_HOUR (dt1) * 60 * 60 + (boxint)DT_MINUTE (dt1) * 60 + DT_SECOND (dt1); boxint s2 = (boxint)DT_DAY (dt2) * 24 * 60 * 60 + (boxint)DT_HOUR (dt2) * 60 * 60 + (boxint)DT_MINUTE (dt2) * 60 + DT_SECOND (dt2); int frac1, frac2; int diffyear, diffmonth; if (0 == stricmp (unit, "day")) return box_num ((boxint)DT_DAY (dt2) - (boxint)DT_DAY (dt1)); if (0 == stricmp (unit, "hour")) return box_num ((s2 - s1) / (60 * 60)); if (0 == stricmp (unit, "minute")) return box_num ((s2 - s1) / 60); if (0 == stricmp (unit, "second")) return box_num (s2 - s1); diffyear = !stricmp (unit, "year"); diffmonth = (diffyear ? 0 : !stricmp (unit, "month")); if (diffyear || diffmonth) { TIMESTAMP_STRUCT ts1; TIMESTAMP_STRUCT ts2; int tz_tweak = DT_TZ (dt1); dt_to_GMTimestamp_struct (dt2, &ts2); dt_to_GMTimestamp_struct (dt1, &ts1); ts_add (&ts1, tz_tweak, "minute"); ts_add (&ts2, tz_tweak, "minute"); if (diffyear) return box_num ((boxint)ts2.year - (boxint)ts1.year); if (diffmonth) return box_num ((boxint)(ts2.year * 12 + ts2.month) - (boxint)(ts1.year * 12 + ts1.month)); } frac1 = DT_FRACTION(dt1); frac2 = DT_FRACTION(dt2); if (0 == stricmp (unit, "millisecond")) return box_num ((s2 - s1) * (boxint)1000 + (frac2 / 1000000 - frac1 / 1000000)); if (0 == stricmp (unit, "microsecond")) return box_num ((s2 - s1) * (boxint)1000000 + (frac2 / 1000 - frac1 / 1000)); if (0 == stricmp (unit, "nanosecond")) return box_num ((s2 - s1) * (boxint)1000000000 + (frac2 - frac1)); sqlr_new_error ("22023", "DT002", "Bad unit in datediff: %s.", unit); return NULL; }
caddr_t bif_string_timestamp (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { caddr_t str = bif_string_or_wide_or_null_arg (qst, args, 0, "stringdate"); caddr_t out; if (!str) sqlr_new_error ("22002", "DT007", "Nulls not allowed as parameters to stringdate"); if (DV_WIDESTRINGP (str)) { char szTemp[100]; szTemp[0] = 0; box_wide_string_as_narrow (str, szTemp, 0, QST_CHARSET (qst)); out = string_to_dt_box (szTemp); } else out = string_to_dt_box (str); return out; }
char * interval_odbc_to_text (ptrlong odbcInterval, char *func_name) { char *szpart = NULL; switch (odbcInterval) { case SQL_TSI_SECOND: szpart = "second"; break; case SQL_TSI_MINUTE: szpart = "minute"; break; case SQL_TSI_HOUR: szpart = "hour"; break; case SQL_TSI_DAY: szpart = "day"; break; case SQL_TSI_MONTH: szpart = "month"; break; case SQL_TSI_YEAR: szpart = "year"; break; default: sqlr_new_error ("22015", "DT003", "Interval not supported in %s: %ld", func_name, (long) odbcInterval); } return szpart; }
/* INFO: toplevel udt_clr_member_mutator */ caddr_t dotnet_set_property (caddr_t *type_vec, long inst, caddr_t prop_name) { MonoArray *v_args, *i_array = NULL, *o_array = NULL; MonoObject *mono_list; caddr_t ret = NULL; MonoDomain *domain = virtuoso_domain; get_mono_thread (); v_args = MAKE_PARAM_ARRAY (domain, 4); if (param_to_mono_array (type_vec, 1, &i_array, &o_array)) sqlr_new_error ("22023", "MN008", "Can't convert parameters"); SET_INT_ARG (domain, v_args, 0, inst); SET_STRING_ARG (domain, v_args, 1, prop_name); mono_array_set (v_args, gpointer, 2, i_array); mono_array_set (v_args, gpointer, 3, o_array); mono_list = call_mono (VIRTCLR_NAME, "VInvoke:set_prop", v_args, domain); ret = sa_to_dk ((MonoArray *) mono_list, 0, 0, NULL); return ret; }
caddr_t bif_timestampdiff (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args) { ptrlong long_unit = bif_long_arg (qst, args, 0, "timestampdiff"); caddr_t dt1 = bif_date_arg (qst, args, 1, "timestampdiff"); caddr_t dt2 = bif_date_arg (qst, args, 2, "timestampdiff"); GMTIMESTAMP_STRUCT ts1, ts2; /* BELOW OVERFLOWS on 32 bit long. Numbers used for computing difference, * hence this works when difference below 2**21 = 34 years */ boxint s1 = (boxint)DT_DAY (dt1) * 24 * 60 * 60 + DT_HOUR (dt1) * 60 * 60 + DT_MINUTE (dt1) * 60 + DT_SECOND (dt1); boxint s2 = (boxint)DT_DAY (dt2) * 24 * 60 * 60 + DT_HOUR (dt2) * 60 * 60 + DT_MINUTE (dt2) * 60 + DT_SECOND (dt2); char *unit = interval_odbc_to_text (long_unit, "timestampdiff"); if (0 == stricmp (unit, "day")) return box_num ((boxint)DT_DAY (dt2) - (boxint)DT_DAY (dt1)); if (0 == stricmp (unit, "hour")) return box_num ((s2 - s1) / (60 * 60)); if (0 == stricmp (unit, "minute")) return box_num ((s2 - s1) / 60); if (0 == stricmp (unit, "second")) return box_num (s2 - s1); dt_to_GMTimestamp_struct (dt2, &ts2); dt_to_GMTimestamp_struct (dt1, &ts1); if (0 == stricmp (unit, "month")) return box_num ((boxint)(ts2.year * 12 + ts2.month) - (boxint)(ts1.year * 12 + ts1.month)); if (0 == stricmp (unit, "year")) return box_num ((boxint)ts2.year - (boxint)ts1.year); sqlr_new_error ("22015", "DT004", "Bad interval in timestampdiff: %s.", unit); return NULL; }
/* INFO: toplevel udt_clr_instantiate_class */ int create_instance (caddr_t *type_vec, int n_args, long _mode, caddr_t asm_name, caddr_t type, void * udt) { MonoArray *v_args, *i_array = NULL, *o_array = NULL; MonoObject *mono_list; int len, ret = 0; MonoDomain *domain = virtuoso_domain; get_mono_thread (); v_args = MAKE_PARAM_ARRAY (domain, 5); if (param_to_mono_array (type_vec, n_args, &i_array, &o_array)) sqlr_new_error ("22023", "MN010", "Can't convert parameters"); SET_INT_ARG (domain, v_args, 0, _mode); SET_STRING_ARG (domain, v_args, 1, asm_name); SET_STRING_ARG (domain, v_args, 2, type); mono_array_set (v_args, gpointer, 3, i_array); mono_array_set (v_args, gpointer, 4, o_array); mono_list = call_mono (VIRTCLR_NAME, "VInvoke:create_ins_asm", v_args, domain); len = mono_array_length ((MonoArray*)mono_list); if (len == 2) { caddr_t aret = sa_to_dk ((MonoArray *) mono_list, 0, 1, udt); ret = unbox (aret); dk_free_box (aret); } else GPF_T1 ("create_instance"); return ret; }
/* equal to ARTM_BIN_FUNC (box_mod, %, numeric_modulo, 1) with some extensions */ caddr_t box_mod (ccaddr_t box1, ccaddr_t box2, caddr_t * qst, state_slot_t * target) { NUMERIC_VAR (dn1); NUMERIC_VAR (dn2); dtp_t dtp1, dtp2, res_dtp; retry_rdf_boxes: NUM_TO_MEM (dn1, dtp1, box1); NUM_TO_MEM (dn2, dtp2, box2); if (dtp1 == DV_DB_NULL || dtp2 == DV_DB_NULL) goto null_result; \ if (n_coerce ((caddr_t) & dn1, (caddr_t) & dn2, dtp1, dtp2, &res_dtp)) { switch (res_dtp) { case DV_LONG_INT: if (0 == *(boxint *) &dn2) sqlr_new_error ("22012", "SR088", "Division by 0."); if (target) return (qst_set_long (qst, target, (*(boxint *) &dn1 % * (boxint *) &dn2)), (caddr_t) 0); return (box_num (*(boxint *) &dn1 % * (boxint *) &dn2)); case DV_SINGLE_FLOAT: if (0 == *(float *) &dn2) sqlr_new_error ("22012", "SR089", "Division by 0."); if (target) return (qst_set_float (qst, target, (float) fmod (*(float *) &dn1, * (float *) &dn2)), (caddr_t) 0); return (box_float ((float) fmod (*(float *) &dn1, * (float *) &dn2))); case DV_DOUBLE_FLOAT: if (0 == *(double*) &dn2) sqlr_new_error ("22012", "SR090", "Division by 0."); if (target) return (qst_set_double (qst, target, fmod (*(double*) &dn1, *(double*) &dn2)), (caddr_t) 0); return (box_double (fmod (*(double*) &dn1, *(double*) &dn2))); case DV_NUMERIC: return (numeric_bin_op (numeric_modulo, (numeric_t) &dn1, (numeric_t) &dn2, qst, target)); } } else { if (dtp1 == DV_RDF || dtp2 == DV_RDF) { if (dtp1 == DV_RDF) box1 = ((rdf_box_t *)(box1))->rb_box; if (dtp2 == DV_RDF) box2 = ((rdf_box_t *)(box2))->rb_box; goto retry_rdf_boxes; } if (((query_instance_t *)qst)->qi_query->qr_no_cast_error) goto null_result; /* see below */ sqlr_new_error ("22003", "SR087", "Non numeric arguments to arithmetic operation modulo"); } null_result: \ if (target) \ { \ qst_set_bin_string (qst, target, NULL, 0, DV_DB_NULL); \ return NULL; \ } \ return (dk_alloc_box (0, DV_DB_NULL)); \ }
static int param_to_mono_array (caddr_t *list_args, int n_args, MonoArray ** p_i_array, MonoArray **p_o_array) { caddr_t * line; MonoObject *arg = NULL; MonoDomain *domain = virtuoso_domain; MonoArray *i_array, *o_array; guint32 is_object; int inx; i_array = (MonoArray*)mono_array_new (domain, mono_get_object_class (), n_args); o_array = (MonoArray*)mono_array_new (domain, mono_get_intptr_class (), n_args); for (inx = 0; inx < n_args; ++inx) { line = (caddr_t *) list_args[inx]; is_object = 0; if (DV_TYPE_OF (line[1]) == DV_DB_NULL) { arg = NULL; goto put_it; } if (!strncmp (line[0], "System.String", sizeof ("System.String")) || !strncmp (line[0], "String", sizeof ("String"))) { if (!DV_STRINGP (line[1])) goto convert_error; arg = (MonoObject *) mono_string_new (domain, line[1]); } else if (!strncmp (line[0], "Int32", sizeof ("Int32")) || !strncmp (line[0], "System.Int32", sizeof ("System.Int32")) || !strncmp (line[0], "int", sizeof ("int"))) { gint32 ivalue; if (DV_TYPE_OF (line[1]) != DV_LONG_INT) goto convert_error; ivalue = unbox (line[1]); arg = mono_value_box (domain, mono_get_int32_class (), &ivalue); } else if (!strncmp (line[0], "System.Single", sizeof ("System.Single")) || !strncmp (line[0], "Single", sizeof ("Single"))) { float flt_value; if (DV_TYPE_OF (line[1]) != DV_SINGLE_FLOAT) goto convert_error; flt_value = unbox_float (line[1]); arg = mono_value_box (domain, mono_get_single_class (), &flt_value); } else if (!strncmp (line[0], "System.Data.SqlTypes.SqlDouble", sizeof ("System.Data.SqlTypes.SqlDouble")) || !strncmp (line[0], "System.Double", sizeof ("System.Double")) || !strncmp (line[0], "Double", sizeof ("Double"))) { double dbl_value; if (DV_TYPE_OF (line[1]) != DV_DOUBLE_FLOAT) goto convert_error; dbl_value = unbox_double (line[1]); arg = mono_value_box (domain, mono_get_double_class (), &dbl_value); } else /*if (!strncmp (line[0], "CLRObject", sizeof ("CLRObject"))) */ { gint32 ivalue; if (DV_TYPE_OF (line[1]) != DV_LONG_INT) goto convert_error; is_object = unbox (line[1]); arg = mono_value_box (domain, mono_get_int32_class (), &ivalue); } put_it: mono_array_set (i_array, gpointer, inx, arg); mono_array_set (o_array, gpointer, inx, (gpointer) is_object); } *p_i_array = i_array; *p_o_array = o_array; return 0; convert_error: sqlr_new_error ("22023", "XXXXX", "wrong or unknown type"); return 0; }
caddr_t bif_mediawiki_lexer_impl (caddr_t * qst, caddr_t * err, state_slot_t ** args, char *bifname, int run_lexer) { caddr_t rawtext = bif_string_arg (qst, args, 0, bifname); caddr_t CLUSTER_arg = bif_string_arg (qst, args, 1, bifname); caddr_t TOPIC = bif_string_arg (qst, args, 2, bifname); caddr_t WIKINAME = bif_string_arg (qst, args, 3, bifname); caddr_t *env = (caddr_t *)bif_arg (qst, args, 4, bifname); int envlen = 0, envctr; dk_session_t *pipe = NULL, *out = NULL; caddr_t macroexpanded = NULL, res = NULL; switch (DV_TYPE_OF ((caddr_t)env)) { case DV_ARRAY_OF_POINTER: envlen = BOX_ELEMENTS ((caddr_t)env); if (envlen % 2) sqlr_new_error ("22023", "WV001", "%s needs an array of even length or NULL argument 4", bifname); for (envctr = 0; envctr < envlen; envctr++) if (DV_STRING != DV_TYPE_OF (env[envctr])) sqlr_new_error ("22023", "WV001", "%s needs an array of even length of strings or NULL argument 4", bifname); break; case DV_DB_NULL: break; default: sqlr_new_error ("22023", "WV001", "%s needs an array or NULL as argument 4", bifname); } pipe = strses_allocate (); mutex_enter (mediawiki_lexer_mutex); mediawiki_env = dk_alloc_box ((8 + envlen) * sizeof (caddr_t), DV_ARRAY_OF_POINTER); mediawiki_env[0] = "CLUSTER"; mediawiki_env[1] = mediawiki_CLUSTER = CLUSTER_arg; mediawiki_env[2] = "TOPIC"; mediawiki_env[3] = mediawiki_TOPIC = TOPIC; mediawiki_env[4] = "WIKINAME"; mediawiki_env[5] = mediawiki_WIKINAME = WIKINAME; mediawiki_env[6] = "WIKIVERSION"; mediawiki_env[7] = mediawiki_WIKIVERSION; for (envctr = 0; envctr < envlen; envctr++) mediawiki_env[8+envctr] = env[envctr]; QR_RESET_CTX { mediamacyyrestart (NULL); mediamacyylex_prepare (rawtext, pipe); mediamacyylex (); macroexpanded = strses_string (pipe); if (run_lexer) { out = strses_allocate (); mediawikiyyrestart (NULL); mediawikiyylex_prepare (macroexpanded, out); mediawikiyylex (); } } QR_RESET_CODE { du_thread_t *self = THREAD_CURRENT_THREAD; caddr_t err = thr_get_error_code (self); dk_free_box (mediawiki_env); /* not dk_free_tree */ mutex_leave (mediawiki_lexer_mutex); strses_free (pipe); dk_free_box (macroexpanded); if (run_lexer) strses_free (out); POP_QR_RESET; sqlr_resignal (err); } END_QR_RESET; dk_free_box (mediawiki_env); /* not dk_free_tree */ mutex_leave (mediawiki_lexer_mutex); if (run_lexer) { res = strses_string (out); strses_free (out); strses_free (pipe); dk_free_box (macroexpanded); return res; } else { strses_free (pipe); return macroexpanded; } }
static caddr_t sa_to_dk (MonoArray *mono_list, int ofs, int mode, void *udt) { guint32 ret_type; int clr_object = 0; MonoObject *type, *value; caddr_t ret = NULL; MonoClass *cls; int len = mono_array_length (mono_list), inx; dk_set_t ret_set = NULL; type = (MonoObject *)mono_array_get (mono_list, gpointer, ofs + 0); ret_type = *(guint32 *)((char *)type + sizeof (MonoObject)); if (!ret_type) { char *error_text; caddr_t err = NULL; value = (MonoObject *)mono_array_get (mono_list, gpointer, ofs + 1); error_text = mono_string_to_utf8 ((MonoString *)value); if (error_text) err = srv_make_new_error ("42000", "MN002", "Mono error : %.200s", mono_class_get_name (mono_object_get_class (value)), error_text); else err = srv_make_new_error ("42000", "MN003", "Unknown mono error"); g_free (error_text); sqlr_resignal (err); } /* get type of object */ clr_object = 0; if (ret_type == 5 || ret_type == 6) clr_object = 1; for (inx = 1; inx < len; inx++) { value = (MonoObject *)mono_array_get (mono_list, gpointer, ofs + inx); if (value) { cls = mono_object_get_class (value); if (cls == mono_get_int32_class ()) { gint32 v = *(gint32 *)((char *)value + sizeof (MonoObject)); if (clr_object) { void * what_udt; if (mode) { /*add_id (v);*/ ret = box_num (v); } else { what_udt = udt_find_class_for_clr_instance (v, udt); if (what_udt) { /*add_id (v);*/ ret = cpp_udt_clr_instance_allocate (v, what_udt); } else { sqlr_new_error ("22023", "MN005", "Can't map Mono result to PL type"); } } } else ret = box_num (v); } else if (cls == mono_get_uint32_class()) ret = box_num (*(guint32 *)((char *)value + sizeof (MonoObject))); else if (cls == mono_get_single_class ()) ret = box_float (*(float *)((char *)value + sizeof (MonoObject))); else if (cls == mono_get_double_class ()) ret = box_double (*(double *)((char *)value + sizeof (MonoObject))); else if (cls == mono_get_boolean_class ()) ret = box_num (*(guint8 *)((guint8 *)value + sizeof (MonoObject))); else if (cls == mono_get_string_class ()) { char *utf8 = mono_string_to_utf8 ((MonoString *)value); ret = box_utf8_as_wide_char (utf8, NULL, strlen (utf8), 0, DV_WIDE); g_free (utf8); } else { const char *name = mono_class_get_name (cls); sqlr_new_error ("22023", "MN006", "Can't map CLR result of type (%s) to PL type", name ? name : "<unknown>"); } } else ret = NULL; if (ret_type != 3 && ret_type != 4 && ret_type != 5) return ret; else dk_set_push (&ret_set, ret); } return list_to_array (dk_set_nreverse (ret_set)); }