// 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(); }
bool MCArraysCopyExtents(MCArrayRef self, MCListRef& r_list) { MCAutoArray<array_extent_t> t_extents; if (!MCArraysCopyExtents(self, t_extents.PtrRef(), t_extents.SizeRef())) return false; uindex_t t_dimensions = t_extents.Size(); if (t_dimensions == 0) { r_list = MCValueRetain(kMCEmptyList); return true; } MCAutoListRef t_list; if (!MCListCreateMutable('\n', &t_list)) return false; for (uindex_t i = 0; i < t_dimensions; i++) { MCAutoStringRef t_string; if (!MCStringFormat(&t_string, "%d,%d", t_extents[i].min, t_extents[i].max)) return false; if (!MCListAppend(*t_list, *t_string)) return false; } return MCListCopy(*t_list, r_list); }
bool MCExternalHandlerList::ListExternals(MCStringRef& r_list) { bool t_success; t_success = true; MCAutoListRef t_external_list; if (t_success) t_success = MCListCreateMutable('\n', &t_external_list); for(uindex_t i = 0; i < m_externals . Count(); i++) { MCAutoStringRef t_name_string; if (t_success) t_success = MCStringCreateWithCString(m_externals[i] -> GetName(), &t_name_string); if (t_success) t_success = MCListAppend(*t_external_list, *t_name_string); } if (t_success) t_success = MCListCopyAsString(*t_external_list, r_list); return t_success; }
void MCDebuggingGetDebugContext(MCExecContext& ctxt, MCStringRef& r_value) { if (MCdebugcontext == MAXUINT2) { r_value = MCValueRetain(kMCEmptyString); return; } bool t_success; t_success = true; MCAutoListRef t_list; if (t_success) t_success = MCListCreateMutable(',', &t_list); if (t_success) { MCAutoValueRef t_context_id; t_success = MCexecutioncontexts[MCdebugcontext]->GetObject()->names(P_LONG_ID, &t_context_id) && MCListAppend(*t_list, *t_context_id); } if (t_success) t_success = MCListAppend(*t_list, MCexecutioncontexts[MCdebugcontext]->GetHandler()->getname()); if (t_success) t_success = MCListAppendInteger(*t_list, MCexecutioncontexts[MCdebugcontext] -> GetLine()); if (t_success) t_success = MCListCopyAsString(*t_list, r_value); if (t_success) return; ctxt . Throw(); }
bool MCExternalHandlerList::ListHandlers(Handler_type p_type, MCStringRef& r_list) { bool t_success; t_success = true; MCAutoListRef t_handler_list; if (t_success) t_success = MCListCreateMutable('\n', &t_handler_list); for(uindex_t i = 0; i < m_handlers . Count(); i++) { if (t_success && m_externals[m_handlers[i] . external] -> GetHandlerType(m_handlers[i] . handler) == p_type) t_success = MCListAppend(*t_handler_list, m_handlers[i] . name); } if (t_success) t_success = MCListCopyAsString(*t_handler_list, r_list); return t_success; }
bool MCScreenDC::listprinters(MCStringRef& r_printers) { MCAutoListRef t_list; if (!MCListCreateMutable('\n', &t_list)) return false; DWORD t_flags; DWORD t_level; t_flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS; t_level = 4; DWORD t_printer_count; DWORD t_bytes_needed; t_printer_count = 0; t_bytes_needed = 0; if (EnumPrintersW(t_flags, NULL, t_level, NULL, 0, &t_bytes_needed, &t_printer_count) != 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { MCAutoPointer<byte_t> t_printers; if (!MCMemoryNewArray(t_bytes_needed, &t_printers)) return false; if (EnumPrintersW(t_flags, NULL, t_level, (LPBYTE)*t_printers, t_bytes_needed, &t_bytes_needed, &t_printer_count) != 0) { for(uint4 i = 0; i < t_printer_count; ++i) { MCAutoStringRef t_printer_name; if (!MCStringCreateWithWString(((PRINTER_INFO_4W *)*t_printers)[i] . pPrinterName, &t_printer_name)) return false; if (!MCListAppend(*t_list, *t_printer_name)) return false; } } } return MCListCopyAsString(*t_list, r_printers); }
void MCDebuggingGetExecutionContexts(MCExecContext& ctxt, MCStringRef& r_value) { int i; bool added = false; if (MCnexecutioncontexts < MAX_CONTEXTS) { MCexecutioncontexts[MCnexecutioncontexts++] = &ctxt; added = true; } bool t_success; t_success = true; MCAutoListRef t_context_list; if (t_success) t_success = MCListCreateMutable('\n', &t_context_list); if (t_success) { for (i = 0 ; i < MCnexecutioncontexts ; i++) { MCAutoListRef t_context; t_success = MCListCreateMutable(',', &t_context); if (t_success) { MCAutoValueRef t_context_id; t_success = MCexecutioncontexts[i]->GetObject()->names(P_LONG_ID, &t_context_id) && MCListAppend(*t_context, *t_context_id); } // PM-2014-04-14: [[Bug 12125]] Do this check to avoid a crash in LC server if (t_success && MCexecutioncontexts[i]->GetHandler() != NULL) t_success = MCListAppend(*t_context, MCexecutioncontexts[i]->GetHandler()->getname()); if (t_success) { MCAutoStringRef t_line; t_success = MCStringFormat(&t_line, "%d", MCexecutioncontexts[i] -> GetLine()) && MCListAppend(*t_context, *t_line); } if (t_success && MCexecutioncontexts[i] -> GetParentScript() != NULL) { MCAutoValueRef t_parent; t_success = MCexecutioncontexts[i] -> GetParentScript() -> GetParent() -> GetObject() -> names(P_LONG_ID, &t_parent) && MCListAppend(*t_context, *t_parent); } if (t_success) t_success = MCListAppend(*t_context_list, *t_context); } } if (added) MCnexecutioncontexts--; if (t_success) t_success = MCListCopyAsString(*t_context_list, r_value); if (!t_success) r_value = MCValueRetain(kMCEmptyString); }
// 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(); }
void MCPickExecPickOptionByIndex(MCExecContext &ctxt, int p_chunk_type, MCStringRef *p_option_lists, uindex_t p_option_list_count, uindex_t *p_initial_indices, uindex_t p_indices_count, bool p_use_hilite_type, bool p_use_picker, bool p_use_cancel, bool p_use_done, MCRectangle p_button_rect) { MCAutoArray<MCPickList> t_pick_lists; char_t t_delimiter; switch ((MCChunkType)p_chunk_type) { // No access to the line/item delimiter set in the handler from the mobile-specific functions/commands // so following the old engine default values for them case kMCChunkTypeItem: t_delimiter = ','; break; case kMCChunkTypeWord: case kMCChunkTypeLine: t_delimiter = '\n'; break; default: MCUnreachable(); } uindex_t t_old_offset = 0; uindex_t t_new_offset = 0; bool t_success; t_success = true; for (uindex_t i = 0; i < p_option_list_count; i++) { MCStringRef t_option; MCPickList t_pick_list; MCAutoArray<MCStringRef> t_options; t_old_offset = 0; while (t_success && MCStringFirstIndexOfChar(p_option_lists[i], t_delimiter, t_old_offset, kMCCompareCaseless, t_new_offset)) { t_success = MCStringCopySubstring(p_option_lists[i], MCRangeMakeMinMax(t_old_offset, t_new_offset), t_option); if (t_success) t_options . Push(t_option); t_old_offset = t_new_offset + 1; } // Append the remaining part of the options t_success = MCStringCopySubstring(p_option_lists[i], MCRangeMakeMinMax(t_old_offset, MCStringGetLength(p_option_lists[i])), t_option); if (t_success) t_options . Push(t_option); t_options . Take(t_pick_list . options, t_pick_list . option_count); t_pick_list . initial = p_initial_indices[i]; t_pick_lists . Push(t_pick_list); } bool t_cancelled; uindex_t *t_result; uindex_t t_result_count = 0; // Open the picker and allow the user to select the options if (t_success) t_success = MCSystemPickOption(t_pick_lists . Ptr(), t_pick_lists . Size(), t_result, t_result_count, p_use_hilite_type, p_use_picker, p_use_cancel, p_use_done, t_cancelled, p_button_rect); ctxt.SetTheResultToEmpty(); if (t_success) { if (t_cancelled) { // HC-2012-02-15 [[ BUG 9999 ]] Picker should return 0 if cancel was selected. ctxt . SetTheResultToNumber(0); } else { MCAutoListRef t_indices; t_success = MCListCreateMutable(',', &t_indices); for (uindex_t i = 0; i < t_result_count && t_success; i++) { MCAutoStringRef t_index; t_success = MCStringFormat(&t_index, "%u", t_result[i]); if (t_success) t_success = MCListAppend(*t_indices, *t_index); } MCAutoStringRef t_string; /* UNCHECKED */ MCListCopyAsString(*t_indices, &t_string); ctxt . SetTheResultToValue(*t_string); } } // Free memory for (uindex_t i = 0; i < t_pick_lists . Size(); i++) for (uindex_t j = 0; j < t_pick_lists[i] . option_count; j++) MCValueRelease(t_pick_lists[i] . options[j]); }