// Should be removed when 'combine by row' and 'combine by column' only differs by the delimiter used, // not by the way the array is handled - any index is fine for combine by row void MCArraysExecCombineByRow(MCExecContext& ctxt, MCArrayRef p_array, MCStringRef &r_string) { MCAutoListRef t_list; MCListCreateMutable(ctxt . GetRowDelimiter(), &t_list); uindex_t t_count = MCArrayGetCount(p_array); combine_array_t t_lisctxt; bool t_success; t_lisctxt . elements = nil; t_lisctxt . index = 0; t_success = MCMemoryNewArray(t_count, t_lisctxt . elements); if (t_success) { MCArrayApply(p_array, list_array_elements, &t_lisctxt); qsort(t_lisctxt . elements, t_count, sizeof(array_element_t), compare_array_element); for (int i = 0; i < t_count && t_success; ++i) { MCAutoStringRef t_string; if (ctxt . ConvertToString(t_lisctxt . elements[i] . value, &t_string)) t_success = MCListAppend(*t_list, *t_string); else t_success = false; } MCMemoryDeleteArray(t_lisctxt . elements); } if (t_success && MCListCopyAsString(*t_list, r_string)) return; ctxt . Throw(); }
void MCArraysEvalIsAnArray(MCExecContext& ctxt, MCValueRef p_value, bool& r_result) { // FG-2014-10-21: [[ Bugfix 13737 ]] An array is only an array if it has at // least one key (i.e the empty array is not an array...) r_result = MCValueGetTypeCode(p_value) == kMCValueTypeCodeArray && MCArrayGetCount((MCArrayRef)p_value) > 0; }
static bool WidgetGeometryFromLCBList(MCValueRef p_list, uint32_t &r_width, uint32_t &r_height) { // MCProperList gets converted to a sequence array if (!MCValueIsArray(p_list)) return false; MCArrayRef t_array; t_array = (MCArrayRef)p_list; if (!MCArrayIsSequence(t_array) || MCArrayGetCount(t_array) != 2) return false; uint32_t t_width, t_height; MCValueRef t_value; if (!MCArrayFetchValueAtIndex(t_array, 1, t_value) || MCValueGetTypeCode(t_value) != kMCValueTypeCodeNumber) return false; t_width = MCNumberFetchAsUnsignedInteger((MCNumberRef)t_value); if (!MCArrayFetchValueAtIndex(t_array, 2, t_value) || MCValueGetTypeCode(t_value) != kMCValueTypeCodeNumber) return false; t_height = MCNumberFetchAsUnsignedInteger((MCNumberRef)t_value); r_width = t_width; r_height = t_height; return true; }
void MCArraysExecCombine(MCExecContext& ctxt, MCArrayRef p_array, MCStringRef p_element_delimiter, MCStringRef p_key_delimiter, MCStringRef& r_string) { bool t_success; t_success = true; uindex_t t_count; t_count = MCArrayGetCount(p_array); MCAutoStringRef t_string; if (t_success) t_success = MCStringCreateMutable(0, &t_string); combine_array_t t_lisctxt; t_lisctxt . elements = nil; if (t_success) t_success = MCMemoryNewArray(t_count, t_lisctxt . elements); if (t_success) { t_lisctxt . index = 0; MCArrayApply(p_array, list_array_elements, &t_lisctxt); qsort(t_lisctxt . elements, t_count, sizeof(array_element_t), compare_array_element); for(uindex_t i = 0; i < t_count; i++) { MCAutoStringRef t_value_as_string; t_success = ctxt . ConvertToString(t_lisctxt . elements[i] . value, &t_value_as_string); if (!t_success) break; t_success = (p_key_delimiter == nil || (MCStringAppend(*t_string, MCNameGetString(t_lisctxt . elements[i] . key)) && MCStringAppend(*t_string, p_key_delimiter)))&& MCStringAppend(*t_string, *t_value_as_string) && (i == t_count - 1 || MCStringAppend(*t_string, p_element_delimiter)); if (!t_success) break; } } if (t_success) t_success = MCStringCopy(*t_string, r_string); MCMemoryDeleteArray(t_lisctxt . elements); if (t_success) return; // Throw the current error code (since last library call returned false). ctxt . Throw(); }
bool MCArraysCopyTransposed(MCArrayRef self, MCArrayRef& r_transposed) { MCAutoArray<array_extent_t> t_extents; if (!MCArraysCopyExtents(self, t_extents.PtrRef(), t_extents.SizeRef()) || t_extents.Size() != 2) return false; integer_t t_rows = extent_size(t_extents[0]); integer_t t_cols = extent_size(t_extents[1]); integer_t t_row_end = t_extents[0].min + t_rows; integer_t t_col_end = t_extents[1].min + t_cols; if (MCArrayGetCount(self) != t_rows * t_cols) return false; MCAutoArrayRef t_transposed; if (!MCArrayCreateMutable(&t_transposed)) return false; for (integer_t r = t_extents[0].min; r < t_row_end; r++) { for (integer_t c = t_extents[1].min; c < t_col_end; c++) { MCAutoStringRef t_src_string, t_dst_string; MCNewAutoNameRef t_src_name, t_dst_name; MCValueRef t_value; if (!MCStringFormat(&t_src_string, "%d,%d", r, c) || !MCStringFormat(&t_dst_string, "%d,%d", c, r)) return false; if (!MCNameCreate(*t_src_string, &t_src_name) || !MCNameCreate(*t_dst_string, &t_dst_name)) return false; if (!MCArrayFetchValue(self, true, *t_src_name, t_value) || !MCArrayStoreValue(*t_transposed, true, *t_dst_name, t_value)) return false; } } return MCArrayCopy(*t_transposed, r_transposed); }
bool MCContactAddPropertyWithLabel(MCArrayRef p_contact, MCNameRef p_property, MCNameRef p_label, MCValueRef p_value) { MCValueRef t_element; MCValueRef t_array; if (!MCArrayFetchValue(p_contact, false, p_property, t_array) || !MCValueIsArray(t_array) || !MCArrayFetchValue((MCArrayRef)t_array, false, p_label, t_array)) return false; uindex_t t_index = 1; if (!MCValueIsArray(t_array)) t_index = 1; else t_index = MCArrayGetCount((MCArrayRef)t_array) + 1; MCAutoArrayRef t_copied_array; if (MCArrayCopy((MCArrayRef) t_array, &t_copied_array)) return MCArrayStoreValueAtIndex(*t_copied_array, t_index, p_value); return false; }
bool MCArraysCopyMatrix(MCExecContext& ctxt, MCArrayRef self, matrix_t*& r_matrix) { MCAutoArray<array_extent_t> t_extents; if (!MCArraysCopyExtents(self, t_extents.PtrRef(), t_extents.SizeRef()) || t_extents.Size() != 2) return false; integer_t t_rows = extent_size(t_extents[0]); integer_t t_cols = extent_size(t_extents[1]); integer_t t_row_offset = t_extents[0].min; integer_t t_col_offset = t_extents[1].min; if (MCArrayGetCount(self) != t_rows * t_cols) return false; MCAutoPointer<matrix_t> t_matrix; if (!MCMatrixNew(t_rows, t_cols, t_row_offset, t_col_offset, &t_matrix)) return false; for (integer_t row = 0; row < t_rows; row++) { for (integer_t col = 0; col < t_cols; col++) { MCAutoStringRef t_string; MCNewAutoNameRef t_name; MCValueRef t_value; if (!MCStringFormat(&t_string, "%d,%d", row + t_row_offset, col + t_col_offset) || !MCNameCreate(*t_string, &t_name) || !MCArrayFetchValue(self, true, *t_name, t_value) || !ctxt.ConvertToReal(t_value, MCMatrixEntry(*t_matrix, row, col))) return false; } } t_matrix.Take(r_matrix); return true; }
void MCMailDoComposeMail(MCExecContext& ctxt, MCStringRef p_to, MCStringRef p_cc, MCStringRef p_bcc, MCStringRef p_subject, MCStringRef p_body, MCArrayRef p_attachments, MCMailType p_type) { bool t_can_send; MCMailGetCanSendMail(ctxt, t_can_send); if (!t_can_send) return; MCAutoArray<MCAttachmentData> t_attachments; if (p_attachments != nil && !MCArrayIsEmpty(p_attachments)) { MCValueRef t_data; MCValueRef t_file; MCValueRef t_type; MCValueRef t_name; MCAttachmentData t_attachment; if (MCArrayIsSequence(p_attachments)) { for(uindex_t i = 0; i < MCArrayGetCount(p_attachments); i++) { MCValueRef t_value; MCArrayFetchValueAtIndex(p_attachments, i + 1, t_value); if (!MCValueIsArray(t_value)) continue; if (!MCArrayFetchValue((MCArrayRef)t_value, false, MCNAME("data"), t_data) || !ctxt . ConvertToData(t_data, t_attachment . data)) t_attachment . data = nil; if (!MCArrayFetchValue((MCArrayRef)t_value, false, MCNAME("file"), t_file) || !ctxt . ConvertToString(t_file, t_attachment . file)) t_attachment . file = nil; if (!MCArrayFetchValue((MCArrayRef)t_value, false, MCNAME("type"), t_type) || !ctxt . ConvertToString(t_type, t_attachment . type)) t_attachment . type = nil; if (!MCArrayFetchValue((MCArrayRef)t_value, false, MCNAME("name"), t_name) || !ctxt . ConvertToString(t_name, t_attachment . name)) t_attachment . name = nil; t_attachments . Push(t_attachment); } } else { if (!MCArrayFetchValue(p_attachments, false, MCNAME("data"), t_data) || !ctxt . ConvertToData(t_data, t_attachment . data)) t_attachment . data = nil; if (!MCArrayFetchValue(p_attachments, false, MCNAME("file"), t_file) || !ctxt . ConvertToString(t_file, t_attachment . file)) t_attachment . file = nil; if (!MCArrayFetchValue(p_attachments, false, MCNAME("type"), t_type) || !ctxt . ConvertToString(t_type, t_attachment . type)) t_attachment . type = nil; if (!MCArrayFetchValue(p_attachments, false, MCNAME("name"), t_name) || !ctxt . ConvertToString(t_name, t_attachment . name)) t_attachment . name = nil; t_attachments . Push(t_attachment); } } MCAutoStringRef t_result; MCSystemSendMailWithAttachments(p_to, p_cc, p_bcc, p_subject, p_body, p_type, t_attachments . Ptr(), t_attachments . Size(), &t_result); ctxt . SetTheResultToValue(*t_result); }
void MCLicenseSetRevLicenseLimits(MCExecContext& ctxt, MCArrayRef p_settings) { if(!MCenvironmentactive) return; bool t_case_sensitive = ctxt . GetCaseSensitive(); MCValueRef t_value; MCStringRef t_string; if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("token"), t_value) && ctxt . ConvertToString(t_value, t_string)) { MCValueRelease(MClicenseparameters . license_token); MClicenseparameters . license_token = t_string; } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("name"), t_value) && ctxt . ConvertToString(t_value, t_string)) { MCValueRelease(MClicenseparameters . license_name); MClicenseparameters . license_name = t_string; } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("organization"), t_value) && ctxt . ConvertToString(t_value, t_string)) { MCValueRelease( MClicenseparameters . license_organization); MClicenseparameters . license_organization = t_string; } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("class"), t_value)) { MCAutoStringRef t_class; MCLicenseClass t_license_class; if (ctxt . ConvertToString(t_value, &t_class) && MCStringToLicenseClass(*t_class, t_license_class)) { MClicenseparameters . license_class = t_license_class; } else MClicenseparameters . license_class = kMCLicenseClassNone; } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("multiplicity"), t_value)) { MCAutoNumberRef t_number; if (ctxt.ConvertToNumber(t_value, &t_number)) { MClicenseparameters . license_multiplicity = MCNumberFetchAsUnsignedInteger(*t_number); } } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("scriptlimit"), t_value)) { MCAutoNumberRef t_number; if (ctxt.ConvertToNumber(t_value, &t_number)) { integer_t t_limit; t_limit = MCNumberFetchAsInteger(*t_number); MClicenseparameters . script_limit = t_limit <= 0 ? 0 : t_limit; } } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("dolimit"), t_value)) { MCAutoNumberRef t_number; if (ctxt.ConvertToNumber(t_value, &t_number)) { integer_t t_limit; t_limit = MCNumberFetchAsInteger(*t_number); MClicenseparameters . do_limit = t_limit <= 0 ? 0 : t_limit; } } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("usinglimit"), t_value)) { MCAutoNumberRef t_number; if (ctxt.ConvertToNumber(t_value, &t_number)) { integer_t t_limit; t_limit = MCNumberFetchAsInteger(*t_number); MClicenseparameters . using_limit = t_limit <= 0 ? 0 : t_limit; } } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("insertlimit"), t_value)) { MCAutoNumberRef t_number; if (ctxt.ConvertToNumber(t_value, &t_number)) { integer_t t_limit; t_limit = MCNumberFetchAsInteger(*t_number); MClicenseparameters . insert_limit = t_limit <= 0 ? 0 : t_limit; } } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("deploy"), t_value)) { static struct { const char *tag; uint32_t value; } s_deploy_map[] = { { "windows", kMCLicenseDeployToWindows }, { "macosx", kMCLicenseDeployToMacOSX }, { "linux", kMCLicenseDeployToLinux }, { "ios", kMCLicenseDeployToIOS }, { "android", kMCLicenseDeployToAndroid }, { "winmobile", kMCLicenseDeployToWinMobile }, { "meego", kMCLicenseDeployToLinuxMobile }, { "server", kMCLicenseDeployToServer }, { "ios-embedded", kMCLicenseDeployToIOSEmbedded }, { "android-embedded", kMCLicenseDeployToIOSEmbedded }, { "html5", kMCLicenseDeployToHTML5 }, { "filemaker", kMCLicenseDeployToFileMaker }, }; MClicenseparameters . deploy_targets = 0; MCAutoStringRef t_params; if (ctxt . ConvertToString(t_value, &t_params)) { MCAutoArrayRef t_split_strings; MCValueRef t_fetched_string; if (MCStringSplit(*t_params, MCSTR(","), nil, kMCCompareExact, &t_split_strings)) { for(uint32_t i = 0; i < MCArrayGetCount(*t_split_strings); i++) { // Fetch the string value created with MCStringSplit MCArrayFetchValueAtIndex(*t_split_strings, i+1, t_fetched_string); for(uint32_t j = 0; j < sizeof(s_deploy_map) / sizeof(s_deploy_map[0]); j++) if (MCStringIsEqualToCString((MCStringRef)t_fetched_string, s_deploy_map[j] . tag, kMCStringOptionCompareCaseless)) { MClicenseparameters . deploy_targets |= s_deploy_map[j] . value; break; } } } } } if (MCArrayFetchValue(p_settings, t_case_sensitive, MCNAME("addons"), t_value) && MCValueIsArray(t_value)) { MCValueRelease(MClicenseparameters . addons); MCArrayCopy((MCArrayRef)t_value, MClicenseparameters . addons); } }
// SN-2014-09-01: [[ Bug 13297 ]] Combining by column deserves its own function as it is too // different from combining by row void MCArraysExecCombineByColumn(MCExecContext& ctxt, MCArrayRef p_array, MCStringRef &r_string) { MCStringRef t_row_delimiter, t_col_delimiter; t_row_delimiter = ctxt . GetRowDelimiter(); t_col_delimiter = ctxt . GetColumnDelimiter(); MCAutoListRef t_list; MCListCreateMutable(t_row_delimiter, &t_list); uindex_t t_count = MCArrayGetCount(p_array); combine_int_indexed_array_t t_lisctxt; bool t_success; t_lisctxt . elements = nil; t_lisctxt . index = 0; t_lisctxt . converter = &ctxt; t_success = MCMemoryNewArray(t_count, t_lisctxt . elements); if (t_success) { if (MCArrayApply(p_array, list_int_indexed_array_elements, &t_lisctxt)) { bool t_valid_keys; qsort(t_lisctxt . elements, t_count, sizeof(array_element_t), compare_int_indexed_elements); // Combine by row/column is only valid if all the indices are consecutive numbers // Otherwise, an empty string is returned - no error index_t t_last_index; t_valid_keys = true; t_last_index = 0; for (int i = 0; i < t_count && t_valid_keys; ++i) { if (!t_last_index) t_last_index = t_lisctxt . elements[i] . key; else t_valid_keys = ++t_last_index == t_lisctxt . elements[i] . key; } if (t_valid_keys) { // SN-2014-09-01: [[ Bug 13297 ]] // We need to store the converted strings in a array, to be able to iterate through the elements by one row-delimitated // at a time MCStringRef* t_strings; uindex_t *t_next_row_indices; t_strings = NULL; t_next_row_indices = NULL; /* UNCHECKED */ MCMemoryNewArray(t_count, t_strings); // MCMemoryNewArray initialises all t_next_row_indices elements to 0. /* UNCHECKED */ MCMemoryNewArray(t_count, t_next_row_indices); for (int i = 0; i < t_count && t_success; ++i) { if (t_lisctxt . elements[i] . key == 0) // The index 0 is ignored continue; t_success = ctxt . ConvertToString(t_lisctxt . elements[i] . value, t_strings[i]); } // SN-2014-09-01: [[ Bug 13297 ]] Added a missed part in column-combining: // only combining row-by-row the array elements. if (t_success) { uindex_t t_elements_over; t_elements_over = 0; // We iterate as long as one element still has uncombined rows while (t_success && t_elements_over != t_count) { MCAutoListRef t_row; t_success = MCListCreateMutable(t_col_delimiter, &t_row); t_elements_over = 0; // Iterate through all the elements of the array for (int i = 0; i < t_count && t_success; ++i) { // Only consider this element if it has any uncombined rows remaining if (t_next_row_indices[i] < MCStringGetLength(t_strings[i])) { MCRange t_cell_range; if (MCStringFind(t_strings[i], MCRangeMake(t_next_row_indices[i], UINDEX_MAX), t_row_delimiter, ctxt.GetStringComparisonType(), &t_cell_range)) { // We found a row delimiter, so we stop the copy range before it and update the next index from which to look t_success = MCListAppendSubstring(*t_row, t_strings[i], MCRangeMake(t_next_row_indices[i], t_cell_range . offset - t_next_row_indices[i])); t_next_row_indices[i] = t_cell_range . offset + t_cell_range . length; } else { // No row delimiter: we copy the remaining part of the string and mark the element // as wholly combined by setting the next index to the length of the element t_success = MCListAppendSubstring(*t_row, t_strings[i], MCRangeMake(t_next_row_indices[i], UINDEX_MAX)); t_next_row_indices[i] = MCStringGetLength(t_strings[i]); } } else { // Everything has been combined in this element t_elements_over++; MCListAppend(*t_row, kMCEmptyString); } } // One more row has been combined - doing it anyway mimics the previous behaviour of having an empty row // added in the end when combining by columns if (t_elements_over != t_count) MCListAppend(*t_list, *t_row); } } MCMemoryDeleteArray(t_next_row_indices); MCMemoryDeleteArray(t_strings); } } MCMemoryDeleteArray(t_lisctxt . elements); } if (t_success && MCListCopyAsString(*t_list, r_string)) return; ctxt . Throw(); }