Exemple #1
0
// 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();
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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();
}
Exemple #5
0
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;
}
Exemple #6
0
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);
}
Exemple #7
0
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);

}
Exemple #8
0
// 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();
}
Exemple #9
0
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]);
}