示例#1
0
void MCDebuggingGetTraceStack(MCExecContext& ctxt, MCStringRef& r_value)
{
	if (MCtracestackptr == nil)
	{
		r_value = (MCStringRef)MCValueRetain(kMCEmptyString);
		return;
	}

	MCAutoValueRef t_value;
	if (MCtracestackptr -> names(P_NAME, &t_value))
		if (ctxt.ConvertToString(*t_value, r_value))
		return;

	ctxt . Throw();
}
示例#2
0
void MCAdExecCreateAd(MCExecContext& ctxt, const char *p_name, MCAdType p_type, MCAdTopLeft p_top_left, MCVariableValue *p_meta_data)
{    
    bool t_success;
    t_success = true;
    
    if (s_inneractive_ad_key == nil || MCCStringLength(s_inneractive_ad_key) == 0)
    {
        ctxt.SetTheResultToStaticCString("not registered with ad service");
        t_success = false;;
    }
    
    MCAd *t_ad;
    t_ad = nil;
    
    if (t_success)
        if (MCAd::FindByNameOrId(p_name, t_ad))
        {
            ctxt.SetTheResultToStaticCString("ad already exists");
            t_success = false;
        }            
    
    if (t_success)
    {
        uint32_t t_timeout;
        if (t_success)
        {
            t_timeout = 0;
            if (p_meta_data != nil && p_meta_data->fetch_element_if_exists(ctxt.GetEP(), "refresh", false))
                t_timeout = ctxt.GetEP().getint4();
            if (p_type == kMCAdTypeFullscreen)
                t_timeout = 0;
            else if (t_timeout < 30 || t_timeout > 500)
                t_timeout = 120;
        }
        
        if (t_success)
            t_success = MCSystemInneractiveAdCreate(ctxt, t_ad, p_type, p_top_left, t_timeout, p_meta_data);
        
        if (t_success)
            t_success = t_ad->Create();
        
        if (t_success)
        {
            t_ad->SetNext(s_ads);
            t_ad->SetName(p_name);
            t_ad->SetOwner(ctxt.GetObjectHandle());
            s_ads = t_ad;        
        }
        else if (t_ad != nil)
            t_ad->Release();
               
    }

	if (!t_success)
		ctxt.SetTheResultToStaticCString("could not create ad"); 
}
示例#3
0
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;
}
示例#4
0
void MCDebuggingExecDebugDo(MCExecContext& ctxt, MCStringRef p_script, uinteger_t p_line, uinteger_t p_pos)
{
	Boolean added = False;
	if (MCnexecutioncontexts < MAX_CONTEXTS)
	{
		ctxt.SetLineAndPos(p_line, p_pos);
		MCexecutioncontexts[MCnexecutioncontexts++] = &ctxt;
		added = True;
	}

	if (MCdebugcontext >= MCnexecutioncontexts)
		MCdebugcontext = MCnexecutioncontexts - 1;

	MCExecContext *t_ctxt_ptr;
	t_ctxt_ptr = MCexecutioncontexts[MCdebugcontext];

	t_ctxt_ptr->GetHandler()->doscript(*t_ctxt_ptr, p_script, p_line, p_pos);
    
    // AL-2014-03-21: [[ Bug 11940 ]] Ensure the debug context is not permanently in a state of error.
    t_ctxt_ptr -> IgnoreLastError();
    
	if (added)
		MCnexecutioncontexts--;
}
示例#5
0
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);
    }
}
示例#6
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();
}
示例#7
0
void MCArraysEvalTransposeMatrix(MCExecContext& ctxt, MCArrayRef p_matrix, MCArrayRef& r_result)
{
	if (!MCArraysCopyTransposed(p_matrix, r_result))
		ctxt.LegacyThrow(EE_TRANSPOSE_MISMATCH);
}
示例#8
0
void MCArraysEvalIsAmongTheKeysOf(MCExecContext& ctxt, MCNameRef p_key, MCArrayRef p_array, bool& r_result)
{
	MCValueRef t_value;
	r_result = MCArrayFetchValue(p_array, ctxt.GetCaseSensitive(), p_key, t_value);
}
示例#9
0
void MCSetOp::exec_ctxt(MCExecContext &ctxt)
{
	// ARRAYEVAL
    MCAutoValueRef t_src;
    if (!ctxt . EvalExprAsValueRef(*source, EE_ARRAYOP_BADEXP, &t_src))
        return;
    
    MCAutoValueRef t_dst;
	MCContainer t_container;
    if (!is_into)
    {
        if (!destvar -> evalcontainer(ctxt, t_container))
        {
            ctxt . LegacyThrow(EE_ARRAYOP_BADEXP);
            return;
        }

        if (!t_container.eval(ctxt, &t_dst))
            return;
    }
    else
    {
        if (!ctxt.EvalExprAsValueRef(*destexpr, EE_ARRAYOP_BADEXP, &t_dst))
        {
            return;
        }
    }

    MCAutoValueRef t_dst_value;
	switch(op)
    {
        case kOpIntersect:
            MCArraysExecIntersect(ctxt, *t_dst, *t_src, &t_dst_value);
            break;
        case kOpIntersectRecursively:
            MCArraysExecIntersectRecursively(ctxt, *t_dst, *t_src, &t_dst_value);
            break;
        case kOpUnion:
            MCArraysExecUnion(ctxt, *t_dst, *t_src, &t_dst_value);
            break;
        case kOpUnionRecursively:
            MCArraysExecUnionRecursively(ctxt, *t_dst, *t_src, &t_dst_value);
            break;
        case kOpDifference:
            MCArraysExecDifference(ctxt, *t_dst, *t_src, &t_dst_value);
            break;
        case kOpSymmetricDifference:
            MCArraysExecSymmetricDifference(ctxt, *t_dst, *t_src, &t_dst_value);
            break;
        case kOpNone:
            MCUnreachable();
            break;
    }

	if (!ctxt . HasError())
    {
        if (!is_into)
            t_container.set(ctxt, *t_dst_value);
        else
            destvar->set(ctxt, *t_dst_value);
    }
}
示例#10
0
// MW-2007-07-03: [[ Bug 5123 ]] - Strict array checking modification
//   Here the source can be an array or number so we use 'tona'.
void MCAdd::exec_ctxt(MCExecContext &ctxt)
{
    MCExecValue t_src;
	
    if (!ctxt . EvaluateExpression(source, EE_ADD_BADSOURCE, t_src)
            || !ctxt . ConvertToNumberOrArray(t_src))
	{
		ctxt.LegacyThrow(EE_ADD_BADSOURCE);
        return;
    }
	
	MCExecValue t_dst;
    MCContainer t_dst_container;
	if (destvar != nil)
	{
        if (!destvar->evalcontainer(ctxt, t_dst_container) ||
            !t_dst_container.eval_ctxt(ctxt, t_dst))
        {
            ctxt . LegacyThrow(EE_ADD_BADDEST);
            MCExecTypeRelease(t_src);
            return;
        }
            
	}
	else
    {
        if (!ctxt . EvaluateExpression(dest, EE_ADD_BADDEST, t_dst))
        {
            MCExecTypeRelease(t_src);
            return;
        }
    }

    if (!ctxt . ConvertToNumberOrArray(t_dst))
    {
        MCExecTypeRelease(t_src);
        MCExecTypeRelease(t_dst);
		ctxt.LegacyThrow(EE_ADD_BADDEST);
		return;
    }

	MCExecValue t_result;
    t_result . type = t_dst . type;
    if (t_src . type == kMCExecValueTypeArrayRef)
	{
        if (t_dst . type == kMCExecValueTypeArrayRef)
            MCMathExecAddArrayToArray(ctxt, t_src . arrayref_value, t_dst . arrayref_value, t_result . arrayref_value);
		else
		{
            ctxt . LegacyThrow(EE_ADD_MISMATCH);
            return;
		}
	}
	else
	{
        if (t_dst . type == kMCExecValueTypeArrayRef)
            MCMathExecAddNumberToArray(ctxt, t_src . double_value, t_dst . arrayref_value, t_result . arrayref_value);
		else
            MCMathExecAddNumberToNumber(ctxt, t_src . double_value, t_dst . double_value, t_result . double_value);
	}
    
    MCExecTypeRelease(t_src);
    MCExecTypeRelease(t_dst);
	
	if (!ctxt . HasError())
	{
		if (destvar != nil)
		{
            if (!t_dst_container.give_value(ctxt, t_result))
                ctxt . Throw();
		}
		else
		{
			if (dest->set(ctxt, PT_INTO, t_result))
				return;
			ctxt . LegacyThrow(EE_ADD_CANTSET);
		}
	}
}
示例#11
0
void MCArrayOp::exec_ctxt(MCExecContext &ctxt)
{
	MCAutoStringRef t_element_del;
	MCAutoStringRef t_key_del;
	uint4 chunk;
	chunk = mode;
	switch(chunk)
	{
		case TYPE_USER:
			if (element != NULL)
			{
                if (!ctxt . EvalExprAsStringRef(element, EE_ARRAYOP_BADEXP, &t_element_del))
                    return;

                if (!ctxt . EvalOptionalExprAsNullableStringRef(key, EE_ARRAYOP_BADEXP, &t_key_del))
                    return;
			}
		break;
        case TYPE_ROW:
            t_element_del = ctxt.GetRowDelimiter();
            break;
        case TYPE_COLUMN:
            t_element_del = ctxt.GetColumnDelimiter();
            break;
        case TYPE_LINE:
            t_element_del = ctxt.GetLineDelimiter();
            break;
        case TYPE_ITEM:
            t_element_del = ctxt.GetItemDelimiter();
            break;
        case TYPE_WORD:
        case TYPE_TOKEN:
        case TYPE_CHARACTER:
		default:
            ctxt . Throw();
            return;
	}

	MCContainer t_container;
    MCAutoValueRef t_container_value;
    if (!destvar -> evalcontainer(ctxt, t_container))
	{
        ctxt . LegacyThrow(EE_ARRAYOP_BADEXP);
        return;
    }

    if (!t_container.eval(ctxt, &t_container_value))
    {
        ctxt . Throw();
        return;
    }

	if (is_combine)
	{
        MCAutoArrayRef t_array;
        if (!ctxt . ConvertToArray(*t_container_value, &t_array))
            return;

		MCAutoStringRef t_string;
		if (form == FORM_NONE)
		{
            // SN-2014-09-01: [[ Bug 13297 ]] Combining by column deserves its own function as it is too
            // different from combining by row
            if (chunk == TYPE_ROW)
                MCArraysExecCombineByRow(ctxt, *t_array, &t_string);
            else if (chunk == TYPE_COLUMN)
                MCArraysExecCombineByColumn(ctxt, *t_array, &t_string);
            else
				MCArraysExecCombine(ctxt, *t_array, *t_element_del, *t_key_del, &t_string);
		}
		else if (form == FORM_SET)
			MCArraysExecCombineAsSet(ctxt, *t_array, *t_element_del, &t_string);

        if (!ctxt . HasError())
            t_container.set(ctxt, *t_string);
	}
	else
	{
		MCAutoStringRef t_string;
        if (!ctxt . ConvertToString(*t_container_value, &t_string))
            return;

		MCAutoArrayRef t_array;
		if (form == FORM_NONE)
		{
			if (chunk == TYPE_COLUMN)
				MCArraysExecSplitByColumn(ctxt, *t_string, &t_array);
			else
				MCArraysExecSplit(ctxt, *t_string, *t_element_del, *t_key_del, &t_array);
		}
		else if (form == FORM_SET)
			MCArraysExecSplitAsSet(ctxt, *t_string, *t_element_del, &t_array);

		if (!ctxt . HasError())
            t_container.set(ctxt, *t_array);
    }
}
示例#12
0
void MCKeywordsExecTry(MCExecContext& ctxt, MCStatement *trystatements, MCStatement *catchstatements, MCStatement *finallystatements, MCVarref *errorvar, uint2 line, uint2 pos)
{
	Try_state state = TS_TRY;
	MCStatement *tspr = trystatements;
	Exec_stat stat;
	Exec_stat retcode = ES_NORMAL;
	MCtrylock++;
	while (tspr != NULL)
	{
		if (MCtrace || MCnbreakpoints)
		{
			MCB_trace(ctxt, tspr->getline(), tspr->getpos());
			if (MCexitall)
				break;
		}
		ctxt . SetLineAndPos(tspr->getline(), tspr->getpos());
        
		//stat = tspr->exec(ctxt . GetEP());
        tspr->exec_ctxt(ctxt);
        stat = ctxt . GetExecStat();
        ctxt . IgnoreLastError();
        
        MCActionsRunAll();
        
		switch(stat)
		{
            case ES_NORMAL:
                tspr = tspr->getnext();
                if (MCexitall)
                {
                    retcode = ES_NORMAL;
                    tspr = NULL;
                }
                
                if (tspr == NULL && state != TS_FINALLY)
                {
                    // Everything has executed normally but there may have been an
                    // error added on another event. The trylock needs refactoring to
                    // ensure a trylock on one event can't cause issues in another
                    // event.
                    MCeerror->clear();
                    
                    tspr = finallystatements;
                    state = TS_FINALLY;
                }
                break;
            case ES_ERROR:
                if ((MCtrace || MCnbreakpoints) && state != TS_TRY)
                    do
                    {
                        if (MCB_error(ctxt, tspr->getline(), tspr->getpos(), EE_TRY_BADSTATEMENT))
                            break;
                        ctxt.IgnoreLastError();
                        tspr->exec_ctxt(ctxt);
                    }
				while(MCtrace && (stat = ctxt . GetExecStat()) != ES_NORMAL);
                
                if (stat == ES_ERROR)
                {
                    if (MCexitall)
                    {
                        retcode = ES_NORMAL;
                        tspr = NULL;
                    }
                    else
                        if (state != TS_TRY)
                        {
                            MCtrylock--;
                            return;
                        }
                        else
                        {
                            if (errorvar != NULL)
                            {
                                MCAutoStringRef t_error;
                                MCeerror -> copyasstringref(&t_error);
                                errorvar->set(ctxt, *t_error);
                            }
                            
                            // MW-2007-09-04: At this point we need to clear the execution error
                            //   stack so that errors inside the catch statements are reported
                            //   correctly.
                            MCeerror->clear();
                            MCperror->clear();
                            
                            
                            tspr = catchstatements;
                            state = TS_CATCH;
                            
                            // MW-2007-07-03: [[ Bug 3029 ]] - If there is no catch clause
                            //   we end up skipping the finally as the loop terminates
                            //   before a state transition is made, thus we force it here.
                            if (catchstatements == NULL)
                            {
                                MCeerror -> clear();
                                tspr = finallystatements;
                                state = TS_FINALLY;
                            }
                        }
                }
                else
                    tspr = tspr->getnext();
                break;
            case ES_PASS:
                if (state == TS_CATCH)
                {
                    MCAutoValueRef t_value;
                    MCAutoStringRef t_string;
                    if ((errorvar->eval(ctxt, &t_value), !ctxt.HasError()) &&
                        ctxt . ConvertToString(*t_value, &t_string))
                    {
                        MCeerror->copystringref(*t_string, False);
                    }
                    
                    MCeerror->add(EE_TRY_BADSTATEMENT, line, pos);
                    stat = ES_ERROR;
                }
            default:
                if (state == TS_FINALLY)
                {
                    MCeerror->clear();
                    retcode = ES_NORMAL;
                    tspr = NULL;
                }
                else
                {
                    retcode = stat;
                    tspr = finallystatements;
                    state = TS_FINALLY;
                }
		}
	}
	if (state == TS_CATCH)
		MCeerror->clear();
	MCtrylock--;
	ctxt . SetExecStat(retcode);
}
示例#13
0
extern "C" MC_DLLEXPORT_DEF MCStringRef MCWidgetExecPopupMenuAtLocation(MCStringRef p_menu, MCCanvasPointRef p_at)
{
    if (!MCWidgetEnsureCurrentWidget())
        return nil;
	
	MCButton *t_button;
	t_button = nil;
	
	t_button = (MCButton*)MCtemplatebutton->clone(True, OP_NONE, true);
	if (t_button == nil)
	{
		MCErrorThrowOutOfMemory();
		return nil;
	}
	
	MCPopupMenuHandler t_handler;
	
	MCExecContext ctxt;
	
	t_button->setmenuhandler(&t_handler);
	
	t_button->SetStyle(ctxt, F_MENU);
	t_button->SetMenuMode(ctxt, WM_POPUP);
	t_button->SetText(ctxt, p_menu);
	
	MCPoint t_at;
	MCPoint *t_at_ptr;
	t_at_ptr = nil;
	
	if (p_at != nil)
	{
		MCGPoint t_point;
		MCCanvasPointGetMCGPoint(p_at, t_point);
		
		t_at = MCGPointToMCPoint(MCWidgetMapPointToGlobal(MCcurrentwidget, t_point));
		t_at_ptr = &t_at;
	}
	
	MCInterfaceExecPopupButton(ctxt, t_button, t_at_ptr);
    
	while (t_button->menuisopen() && !MCquit)
	{
		MCU_resetprops(True);
		// MW-2011-09-08: [[ Redraw ]] Make sure we flush any updates.
		MCRedrawUpdateScreen();
		MCscreen->siguser();
		MCscreen->wait(REFRESH_INTERVAL, True, True);
	}
	
	t_button->SetVisible(ctxt, 0, false);
    MCerrorlock++;
    if (t_button->del(false))
        t_button->scheduledelete();
    MCerrorlock--;
    
	MCAutoStringRef t_string;
	
	if (t_handler.GetPick() != nil)
		ctxt.ConvertToString(t_handler.GetPick(), &t_string);
	
	return t_string.Take();
}
示例#14
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]);
}
示例#15
0
void MCPickDoPickDateTime(MCExecContext& ctxt, MCStringRef p_current, MCStringRef p_start, MCStringRef p_end, int32_t *p_step, MCPickButtonType p_buttons, MCRectangle p_button_rect, int p_which)
{
    MCDateTime t_current;
    MCDateTime *t_current_ptr;
    t_current_ptr = nil;
	
	// PM-2015-09-01: [[ Bug 15844 ]] Allow calling mobilePickDate with empty [, current] [, start] [, end] parameters
	// i.e. mobilePickDate "time",,,,10
    if (!MCStringIsEmpty(p_current))
    {
        if (!MCD_convert_to_datetime(ctxt, p_current, CF_UNDEFINED, CF_UNDEFINED, t_current))
            return;
        t_current_ptr = &t_current;
    }
    
    MCDateTime t_start;
    MCDateTime *t_start_ptr;
    t_start_ptr = nil;
    
    if (!MCStringIsEmpty(p_start))
    {
        if (!MCD_convert_to_datetime(ctxt, p_start, CF_UNDEFINED, CF_UNDEFINED, t_start))
            return;
        t_start_ptr = &t_start;
    }
    
    MCDateTime t_end;
    MCDateTime *t_end_ptr;
    t_end_ptr = nil;
    
    if (!MCStringIsEmpty(p_end))
    {
        if (!MCD_convert_to_datetime(ctxt, p_end, CF_UNDEFINED, CF_UNDEFINED, t_end))
            return;
        t_end_ptr = &t_end;
    }
    
    int32_t t_step;
    if (p_step != nil)
        t_step = *p_step;
    else
        t_step = 1;
    
    bool t_cancel_button, t_done_button;
    
    t_cancel_button = false;
    t_done_button = false;
    
    switch (p_buttons)
    {
        case kMCPickButtonCancel:
            t_cancel_button = true;
            break;
        case kMCPickButtonDone:
            t_done_button = true;
            break;
        case kMCPickButtonCancelAndDone:
            t_cancel_button = true;
            t_done_button = true;
            break;
        case kMCPickButtonNone:
        default:
            break;
    }
    
    MCDateTime t_result;
    bool t_cancelled;
    t_cancelled = false;
    
    bool t_success;
    t_success = true;
    MCAutoValueRef t_result_string;
    
    // SN-2014-12-03: [[ Bug 14120 ]] If the picker has been cancelled, we should not try to convert the uninitialised t_result.
    switch (p_which)
    {
    case kMCPickDate:
            t_success = (MCSystemPickDate(t_current_ptr, t_start_ptr, t_end_ptr, t_cancel_button, t_done_button, &t_result, t_cancelled, p_button_rect)
                         && (t_cancelled || MCD_convert_from_datetime(ctxt, t_result, CF_DATE, CF_UNDEFINED, &t_result_string)));
        break;
    case kMCPickTime:
            t_success = (MCSystemPickTime(t_current_ptr, t_start_ptr, t_end_ptr, t_step, t_cancel_button, t_done_button, &t_result, t_cancelled, p_button_rect)
                         && (t_cancelled || MCD_convert_from_datetime(ctxt, t_result, CF_TIME, CF_UNDEFINED, &t_result_string)));
        break;
    case kMCPickDateAndTime:
            t_success = (MCSystemPickDateAndTime(t_current_ptr, t_start_ptr, t_end_ptr, t_step, t_cancel_button, t_done_button, &t_result, t_cancelled, p_button_rect)
                         && (t_cancelled || MCD_convert_from_datetime(ctxt, t_result, CF_DATE, CF_TIME, &t_result_string)));
        break;
    default:
        MCUnreachable();
    }
    
    if (t_success)
    {
        if (t_cancelled)
            ctxt.SetTheResultToStaticCString("cancel");
        else
            ctxt . SetTheResultToValue(*t_result_string);
        return;
    }
    
    ctxt . SetTheResultToEmpty();
}