Beispiel #1
0
Exec_stat MCEPS::getprop_legacy(uint4 parid, Properties which, MCExecPoint& ep, Boolean effective)
{
	switch (which)
	{
#ifdef /* MCEPS::getprop */ LEGACY_EXEC
	case P_SIZE:
		ep.setint(size);
		break;
	case P_ANGLE:
		ep.setr8(angle, ep.getnffw(), ep.getnftrailing(), ep.getnfforce());
		break;
	case P_POSTSCRIPT:
		ep.setsvalue(postscript);
		break;
	case P_PROLOG:
		ep.setsvalue(prolog);
		break;
	case P_RETAIN_IMAGE:
		ep.setboolean(getflag(F_RETAIN_IMAGE));
		break;
	case P_RETAIN_POSTSCRIPT:
		ep.setboolean(getflag(F_RETAIN_POSTSCRIPT));
		break;
	case P_SCALE_INDEPENDENTLY:
		ep.setboolean(getflag(F_SCALE_INDEPENDENTLY));
		break;
	case P_BOUNDING_RECT:
		ep.setrectangle(tx, ty, tx + ex, ty + ey);
		break;
	case P_SCALE:
	case P_X_SCALE:
		ep.setr8(xscale, ep.getnffw(), ep.getnftrailing(), ep.getnfforce());
		break;
	case P_Y_SCALE:
		ep.setr8(yscale, ep.getnffw(), ep.getnftrailing(), ep.getnfforce());
		break;
	case P_X_OFFSET:
		ep.setint(tx);
		break;
	case P_Y_OFFSET:
		ep.setint(ty);
		break;
	case P_X_EXTENT:
		ep.setint(ex);
		break;
	case P_Y_EXTENT:
		ep.setint(ey);
		break;
	case P_CURRENT_PAGE:
		ep.setint(MCU_max(curpage, 1));
		break;
	case P_PAGE_COUNT:
		ep.setint(MCU_max(pagecount, 1));
		break;
#endif /* MCEPS::getprop */
	default:
		return MCControl::getprop_legacy(parid, which, ep, effective);
	}
	return ES_NORMAL;
}
Beispiel #2
0
bool MCParseMenuString(MCString &r_string, IParseMenuCallback *p_callback, bool p_is_unicode, uint1 p_menumode)
{
	MCString *t_lines = NULL;
	uint2 t_nlines = 0;
	MCMenuItem t_menuitem;
	MCU_break_string(r_string, t_lines, t_nlines, p_is_unicode);
	MCExecPoint ep;
	bool t_hastags = false;
	
	p_callback->Start();
	
	for (int i=0; i<t_nlines; i++)
	{
		memset(&t_menuitem, 0, sizeof(MCMenuItem));
		t_menuitem.is_unicode = p_is_unicode;
		t_menuitem.menumode = p_menumode;

		char *t_string;
		uint4 t_strlen;
		if (p_is_unicode)
		{
			ep.setsvalue(t_lines[i]);
			ep.utf16toutf8();
			t_string = ep.getsvalue().clone();
			t_strlen = ep.getsvalue().getlength();
		}
		else
		{
			t_string = t_lines[i].clone();
			t_strlen = t_lines[i].getlength();
		}
		
		ParseMenuItemString(t_string, t_strlen, &t_menuitem);
		
		if (p_is_unicode)
		{
			ep.setsvalue(t_menuitem.label);
			ep.utf8toutf16();
			t_menuitem.label.set(ep.getsvalue().clone(), ep.getsvalue().getlength());
		}
		p_callback->ProcessItem(&t_menuitem);

		delete t_string;

		if (t_menuitem.tag != NULL)
		{
			delete t_menuitem.tag.getstring();
			t_hastags = true;
		}
		if (p_is_unicode)
			delete t_menuitem.label.getstring();
	}
	
	p_callback->End(t_hastags);

	delete t_lines;
	return false;
}
Beispiel #3
0
float android_font_measure_text(void *p_font, const char *p_text, uint32_t p_text_length, bool p_is_unicode)
{
	MCAndroidFont *t_font = (MCAndroidFont*)p_font;
    
	SkPaint t_paint;
	t_paint.setTypeface(t_font->sk_typeface);
	t_paint.setTextSize(t_font->size);
    
	if (p_is_unicode)
	{
		t_paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
		return t_paint.measureText(p_text, p_text_length);
	}
	else
	{
		MCExecPoint ep;
		ep.setsvalue(MCString(p_text, p_text_length));
        
		ep.nativetoutf8();
        
		const MCString &t_utf_string = ep.getsvalue();
        
		t_paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
        
		return t_paint.measureText(t_utf_string.getstring(), t_utf_string.getlength());
	}
}
Beispiel #4
0
Exec_stat MCAndroidPlayerControl::Get(MCNativeControlProperty p_property, MCExecPoint &ep)
{
    bool t_bool = false;
    int32_t t_integer;
    
    jobject t_view;
    t_view = GetView();
    
    switch (p_property)
    {
        case kMCNativeControlPropertyContent:
        {
            ep.setsvalue(m_path);
            return ES_NORMAL;
        }
            
        case kMCNativeControlPropertyShowController:
        {
            MCAndroidObjectRemoteCall(t_view, "getShowController", "b", &t_bool);
            FormatBoolean(ep, t_bool);
            return ES_NORMAL;
        }
        
        case kMCNativeControlPropertyLooping:
        {
            MCAndroidObjectRemoteCall(t_view, "getLooping", "b", &t_bool);
            FormatBoolean(ep, t_bool);
            return ES_NORMAL;
        }
            
        case kMCNativeControlPropertyDuration:
        {
            MCAndroidObjectRemoteCall(t_view, "getDuration", "i", &t_integer);
            FormatInteger(ep, t_integer);
            return ES_NORMAL;
        }
            
        case kMCNativeControlPropertyCurrentTime:
        {
            MCAndroidObjectRemoteCall(t_view, "getCurrentTime", "i", &t_integer);
            FormatInteger(ep, t_integer);
            return ES_NORMAL;
        }
            
        case kMCNativeControlPropertyNaturalSize:
        {
            int32_t t_width = 0, t_height = 0;
            MCAndroidObjectRemoteCall(t_view, "getVideoWidth", "i", &t_width);
            MCAndroidObjectRemoteCall(t_view, "getVideoHeight", "i", &t_height);
            sprintf(ep.getbuffer(I2L * 2 + 3), "%d,%d", t_width, t_height);
            ep.setstrlen();
            return ES_NORMAL;
        }
            
        default:
            break;
    }
    
    return MCAndroidControl::Get(p_property, ep);
}
Beispiel #5
0
Exec_stat MCVideoClip::getprop(uint4 parid, Properties which, MCExecPoint &ep, Boolean effective)
{
	switch (which)
	{
	case P_DONT_REFRESH:
		ep.setboolean(getflag(F_DONT_REFRESH));
		break;
	case P_FRAME_RATE:
		if (flags & F_FRAME_RATE)
			ep.setint(framerate);
		else
			ep.clear();
		break;
	case P_SCALE:
		ep.setnvalue(scale);
		break;
	case P_SIZE:
		ep.setint(size);
		break;
	case P_TEXT:
		{
			MCString s((const char *)frames, size);
			ep.setsvalue(s);
		}
		break;
	default:
		return MCObject::getprop(parid, which, ep, effective);
	}
	return ES_NORMAL;
}
Beispiel #6
0
static char *set_global(const char *arg1, const char *arg2,
                        const char *arg3, int *retval)
{
	MCVariable *tmp;
	if (!MCVariable::ensureglobal_cstring(arg1, tmp))
	{
		*retval = xresFail;
		return NULL;
	}
	MCExecPoint ep;
	*retval = xresSucc;
	ep.setsvalue(arg2);
	tmp->store(ep, False);
	return NULL;
}
Beispiel #7
0
void MCSort::additem(MCExecPoint &ep, MCSortnode *&items, uint4 &nitems, Sort_type form, MCString &s, MCExpression *by)
{
	if (by != NULL)
	{
		MCerrorlock++;
		ep.setsvalue(s);
		MCeach->store(ep, False);
		if (by->eval(ep) == ES_NORMAL)
			s = ep.getsvalue();
		else
			s = MCnullmcstring;
		MCerrorlock--;
	}
	switch (form)
	{
	case ST_DATETIME:
		ep.setsvalue(s);
		if (MCD_convert(ep, CF_UNDEFINED, CF_UNDEFINED, CF_SECONDS, CF_UNDEFINED))
		{
			if (!MCU_stor8(ep.getsvalue(), items[nitems].nvalue))
				items[nitems].nvalue = -MAXREAL8;
		}
		else
			items[nitems].nvalue = -MAXREAL8;
		break;
	case ST_NUMERIC:
		{
			const char *sptr = s.getstring();
			uint4 length = s.getlength();
			
			// MW-2013-03-21: [[ Bug ]] Make sure we skip any whitespace before the
			//   number starts - making it consistent with string->number conversions
			//   elsewhere.
			MCU_skip_spaces(sptr, length);
			
		    // REVIEW - at the moment the numeric prefix of the string is used to
			//   derive the sort key e.g. 1000abc would get processed as 1000.
			while (length && (isdigit((uint1)*sptr) ||
			                  *sptr == '.' || *sptr == '-' || *sptr == '+'))
			{
				sptr++;
				length--;
			}
			s.setlength(s.getlength() - length);
			if (!MCU_stor8(s, items[nitems].nvalue))
				items[nitems].nvalue = -MAXREAL8;
		}
		break;
	default:
		if (ep.getcasesensitive() && by == NULL)
			items[nitems].svalue = (char *)s.getstring();
		else
			if (ep.getcasesensitive())
				items[nitems].svalue = s.clone();
			else
			{
#if defined(_MAC_DESKTOP) || defined(_IOS_MOBILE)
				if (form == ST_INTERNATIONAL)
				{
					extern char *MCSystemLowercaseInternational(const MCString& s);
					items[nitems].svalue = MCSystemLowercaseInternational(s);
				}
				else
#endif

				{
					items[nitems].svalue = new char[s.getlength() + 1];
					MCU_lower(items[nitems].svalue, s);
					items[nitems].svalue[s.getlength()] = '\0';
				}
			}
		break;
	}
	nitems++;
}
Beispiel #8
0
Exec_stat MCF_unparsetextatts(Properties which, MCExecPoint &ep, uint4 flags,
                              const char *name, uint2 height, uint2 size,
                              uint2 style)
{
	switch (which)
	{
	case P_TEXT_ALIGN:
		switch (flags & F_ALIGNMENT)
		{
		case F_ALIGN_LEFT:
			ep.setstaticcstring(MCleftstring);
			break;
		case F_ALIGN_CENTER:
			ep.setstaticcstring(MCcenterstring);
			break;
		case F_ALIGN_RIGHT:
			ep.setstaticcstring(MCrightstring);
			break;
		case F_ALIGN_JUSTIFY:
			ep.setstaticcstring(MCjustifystring);
			break;
		}
		break;
	case P_TEXT_FONT:
		ep.setsvalue(name);
		break;
	case P_TEXT_HEIGHT:
		ep.setint(height);
		break;
	case P_TEXT_SIZE:
		ep.setint(size);
		break;
	case P_TEXT_STYLE:
		{
			if (style == FA_DEFAULT_STYLE)
			{
				ep.setstaticcstring(MCplainstring);
				return ES_NORMAL;
			}
			
			uint32_t j;
			j = 0;

			ep.clear();
			if (MCF_getweightint(style) != MCFW_MEDIUM)
				ep.concatcstring(MCF_getweightstring(style), EC_COMMA, j++ == 0);
			if (style & FA_ITALIC || style & FA_OBLIQUE)
				ep.concatcstring(MCF_getslantlongstring(style), EC_COMMA, j++ == 0);
			if (style & FA_BOX)
				ep.concatcstring(MCboxstring, EC_COMMA, j++ == 0);
			if (style & FA_3D_BOX)
				ep.concatcstring(MCthreedboxstring, EC_COMMA, j++ == 0);
			if (style & FA_UNDERLINE)
				ep.concatcstring(MCunderlinestring, EC_COMMA, j++ == 0);
			if (style & FA_STRIKEOUT)
				ep.concatcstring(MCstrikeoutstring, EC_COMMA, j++ == 0);
			if (style & FA_LINK)
				ep.concatcstring(MClinkstring, EC_COMMA, j++ == 0);
			if (MCF_getexpandint(style) != FE_NORMAL)
				ep.concatcstring(MCF_getexpandstring(style), EC_COMMA, j++ == 0);
		}
		break;
	default:
		break;
	}
	return ES_NORMAL;
}
Beispiel #9
0
MCObject *MCDispatch::getobjname(Chunk_term type, const MCString &s)
{
	if (stacks != NULL)
	{
		MCStack *tstk = stacks;
		do
		{
			MCObject *optr;
			if ((optr = tstk->getsubstackobjname(type, s)) != NULL)
				return optr;
			tstk = (MCStack *)tstk->next();
		}
		while (tstk != stacks);
	}

	if (type == CT_IMAGE)
	{
		const char *sptr = s.getstring();
		uint4 l = s.getlength();

		MCAutoNameRef t_image_name;
		if (MCU_strchr(sptr, l, ':'))
			/* UNCHECKED */ t_image_name . CreateWithOldString(s);

		MCImage *iptr = imagecache;
		if (iptr != NULL)
		{
			do
			{
check:
				if (t_image_name != nil && iptr -> hasname(t_image_name))
					return iptr;
				if (!iptr->getopened())
				{
					iptr->remove(imagecache);
					delete iptr;
					iptr = imagecache;
					if (iptr == NULL)
						break;
					goto check;
				}
				iptr = (MCImage *)iptr->next();
			}
			while (iptr != imagecache);
		}

		if (MCU_strchr(sptr, l, ':'))
		{
			MCresult->clear(False);
			MCExecPoint ep(MCdefaultstackptr, NULL, NULL);
			MCExecPoint *epptr = MCEPptr == NULL ? &ep : MCEPptr;
			epptr->setsvalue(s);
			MCU_geturl(*epptr);
			if (MCresult->isempty())
			{
				iptr = new MCImage;
				iptr->appendto(imagecache);
				iptr->setprop(0, P_TEXT, *epptr, False);
				iptr->setname(t_image_name);
				return iptr;
			}
		}
	}
	return NULL;
}
Beispiel #10
0
void MCS_delete_registry(const char *key, MCExecPoint &dest)
{
	MCresult->sets("not supported");
	dest.setsvalue(MCU_btos(False));
}
Beispiel #11
0
static bool cgi_multipart_body_callback(void *p_context, const char *p_data, uint32_t p_data_length, bool p_finished, bool p_truncated)
{
	cgi_multipart_context_t *t_context = (cgi_multipart_context_t*)p_context;
	bool t_success = true;

	if (cgi_context_is_form_data(t_context))
	{
		if (t_context->post_binary_variable != NULL)
		{
			t_success = t_context->post_binary_variable->append_string(MCString(p_data, p_data_length));

			if (t_success && p_finished)
			{
				uint32_t t_native_length;
				char *t_native = NULL;
				MCString t_value;
				t_value = t_context->post_binary_variable->get_string();
				if (cgi_native_from_encoding(MCserveroutputtextencoding, t_value.getstring(), t_value.getlength(), t_native, t_native_length))
					t_context->post_variable -> assign_buffer(t_native, t_native_length);
			}
		}
	}
	else if (cgi_context_is_file(t_context))
	{
		if (t_context->file_status == kMCFileStatusOK)
		{
			if (IO_NORMAL == MCS_write(p_data, 1, p_data_length, t_context->file_handle))
				t_context->file_size += p_data_length;
			else
				t_context->file_status = kMCFileStatusIOError;
		}
		
		if (t_success && (p_finished || p_truncated))
		{
			MCExecPoint ep;
			MCVariableValue *t_file_varvalue = NULL;
			cgi_fetch_variable_value_for_key(s_cgi_files, t_context->name, MCCStringLength(t_context->name), ep, t_context->file_variable);
			
			if (t_context->file_status == kMCFileStatusOK && t_context->file_size == 0)
				t_context->file_status = kMCFileStatusFailed;
			
			if (p_truncated)
				t_context->file_status = kMCFileStatusStopped;
			
			ep.setsvalue(MCString(t_context->file_name));
			t_context->file_variable->store_element(ep, MCString("name"));
			ep.setsvalue(MCString(t_context->type));
			t_context->file_variable->store_element(ep, MCString("type"));
			ep.setsvalue(MCString(t_context->temp_name));
			t_context->file_variable->store_element(ep, MCString("filename"));
			ep.setuint(t_context->file_size);
			t_context->file_variable->store_element(ep, MCString("size"));

			if (t_context->file_status != kMCFileStatusOK)
			{
				ep.setsvalue(MCMultiPartGetErrorMessage(t_context->file_status));
				t_context->file_variable->store_element(ep, MCString("error"));
			}
		}
	}
	
	if (t_success && p_finished)
	{
		// clear context for next part
		cgi_dispose_multipart_context(t_context);
	}
	
	return t_success;
}
Beispiel #12
0
Exec_stat MCRepeat::exec(MCExecPoint &ep)
{
	real8 endn = 0.0;
	int4 count = 0;
	MCExecPoint ep2(ep);
	MCScriptPoint *sp = NULL;
	Parse_stat ps;
	const char *sptr;
	uint4 l;
	MCVariableValue *tvar = NULL;
	MCHashentry *hptr = NULL;
	uint4 kindex = 0;
	Boolean donumeric = False;
	Exec_stat stat;
	switch (form)
	{
	case RF_FOR:
		if (loopvar != NULL)
		{
			while ((stat = endcond->eval(ep2)) != ES_NORMAL
			        && (MCtrace || MCnbreakpoints) && !MCtrylock && !MClockerrors)
				MCB_error(ep2, getline(), getpos(), EE_REPEAT_BADFORCOND);
			if (stat != ES_NORMAL)
			{
				MCeerror->add(EE_REPEAT_BADFORCOND, line, pos);
				return ES_ERROR;
			}
			if (each == FU_ELEMENT)
			{
				tvar = ep2.getarray();
				if (tvar != NULL && tvar -> is_array())
				{
					l = 1;
					kindex = 0;
					donumeric = tvar -> get_array() -> isnumeric();
					hptr = tvar -> get_array() -> getnextelement(kindex, hptr, donumeric, ep);
					if (hptr == NULL)
					{
						kindex = 0;
						donumeric = False;
						hptr = tvar -> get_array() -> getnextelement(kindex, hptr, donumeric, ep);
					}
				}
				else
					l = 0;
			}
			else if (each == FU_KEY)
			{
				tvar = ep2.getarray();
				if (tvar != NULL && tvar -> is_array())
				{
					l = 1;
					kindex = 0;
					donumeric = False;
					hptr = tvar -> get_array() -> getnextkey(kindex, hptr);
					// [[ Bug 3871 ]] : If hptr is NULL then we are done already (this can happen
					//                  with an empty custom property set).
					if (hptr == NULL)
						l = 0;
				}
				else
					l = 0;
			}
			else
			{
				sptr = ep2.getsvalue().getstring();
				l = ep2.getsvalue().getlength();
				if (each == FU_WORD)
					MCU_skip_spaces(sptr, l);
				else
					if (each == FU_TOKEN)
					{
						sp = new MCScriptPoint(ep2);
						ps = sp->nexttoken();
						if (ps == PS_ERROR || ps == PS_EOF)
							l = 0;
					}
			}
		}
		else
		{
			while (((stat = endcond->eval(ep)) != ES_NORMAL
			        || (stat = ep.ton()) != ES_NORMAL) && (MCtrace || MCnbreakpoints)
			        && !MCtrylock && !MClockerrors)
				MCB_error(ep, getline(), getpos(), EE_REPEAT_BADFORCOND);
			if (stat != ES_NORMAL)
			{
				MCeerror->add
				(EE_REPEAT_BADFORCOND, line, pos);
				return ES_ERROR;
			}
			count = MCU_max(ep.getint4(), 0);
		}
		break;
	case RF_WITH:
		if (step != NULL)
		{
			while (((stat = step->eval(ep)) != ES_NORMAL
			        || (stat = ep.ton()) != ES_NORMAL) && (MCtrace || MCnbreakpoints)
			        && !MCtrylock && !MClockerrors)
				MCB_error(ep, getline(), getpos(), EE_REPEAT_BADWITHSTEP);
			stepval = ep.getnvalue();
			if (stat != ES_NORMAL || stepval == 0.0)
			{
				MCeerror->add
				(EE_REPEAT_BADWITHSTEP, line, pos);
				return ES_ERROR;
			}
		}
		while (((stat = startcond->eval(ep)) != ES_NORMAL
		        || (stat = ep.ton()) != ES_NORMAL) && (MCtrace || MCnbreakpoints)
		        && !MCtrylock && !MClockerrors)
			MCB_error(ep, getline(), getpos(), EE_REPEAT_BADWITHSTART);
		if (stat != ES_NORMAL)
		{
			MCeerror->add
			(EE_REPEAT_BADWITHSTART, line, pos);
			return ES_ERROR;
		}
		ep.setnvalue(ep.getnvalue() - stepval);
		while ((stat = loopvar->set
		               (ep)) != ES_NORMAL
		        && (MCtrace || MCnbreakpoints) && !MCtrylock && !MClockerrors)
			MCB_error(ep, getline(), getpos(), EE_REPEAT_BADWITHVAR);
		if (stat != ES_NORMAL)
		{
			MCeerror->add
			(EE_REPEAT_BADWITHVAR, line, pos);
			return ES_ERROR;
		}
		while (((stat = endcond->eval(ep)) != ES_NORMAL
		        || (stat = ep.ton()) != ES_NORMAL)
		        && (MCtrace || MCnbreakpoints) && !MCtrylock && !MClockerrors)
			MCB_error(ep, getline(), getpos(), EE_REPEAT_BADWITHEND);
		if (stat != ES_NORMAL)
		{
			MCeerror->add
			(EE_REPEAT_BADWITHEND, line, pos);
			return ES_ERROR;
		}
		endn = ep.getnvalue();
		break;
	default:
		break;
	}

	MCString s;
	Boolean done = False;
	bool t_first;
	t_first = false;
	while (True)
	{
		switch (form)
		{
		case RF_FOREVER:
			break;
		case RF_FOR:
			if (loopvar != NULL)
			{
				if (l == 0)
				{
					done = True;
					// OK-2007-12-05 : Bug 5605. If there has been at least one iteration, set the loop variable to 
					// whatever the value was in the last iteration. 
					if (!t_first)
					{
						// MW-2011-02-08: [[ Bug ]] Make sure we don't use 's' if the repeat type is 'key' or
						//   'element'.
						if (each != FU_ELEMENT && each != FU_KEY)
						{
							ep.setsvalue(s);
							loopvar->set(ep);
						}
					}
				}
				else
				{
					const char *startptr; // = sptr;
					switch (each)
					{
					case FU_KEY:
						// MW-2010-12-15: [[ Bug 9218 ]] Make a copy of the key so that it can't be mutated
						//   accidentally.
						ep . setstaticcstring(hptr -> string);
						loopvar -> set(ep);
						hptr = tvar -> get_array() -> getnextkey(kindex, hptr);
						if (hptr == NULL)
							l = 0;
						break;
					case FU_ELEMENT:
						hptr -> value . fetch(ep);
						loopvar -> set(ep);
						hptr = tvar -> get_array() -> getnextelement(kindex, hptr, donumeric, ep);
						if (hptr == NULL)
							l = 0;
						break;
					case FU_LINE:
						startptr = sptr;
						if (!MCU_strchr(sptr, l, ep.getlinedel()))
						{
							sptr += l;
							l = 0;
						}
						s.set(startptr, sptr - startptr);
						MCU_skip_char(sptr, l);
						break;
					case FU_ITEM:
						startptr = sptr;
						if (!MCU_strchr(sptr, l, ep.getitemdel()))
						{
							sptr += l;
							l = 0;
						}
						s.set(startptr, sptr - startptr);
						MCU_skip_char(sptr, l);
						break;
					case FU_WORD:
						startptr = sptr;
						if (*sptr == '\"')
						{
							MCU_skip_char(sptr, l);
							while (l && *sptr != '\"' && *sptr != '\n')
								MCU_skip_char(sptr, l);
							MCU_skip_char(sptr, l);
						}
						else
							while (l && !isspace((uint1)*sptr))
								MCU_skip_char(sptr, l);
						s.set(startptr, sptr - startptr);
						MCU_skip_spaces(sptr, l);
						break;
					case FU_TOKEN:
						s = sp->gettoken();
						ps = sp->nexttoken();
						if (ps == PS_ERROR || ps == PS_EOF)
							l = 0;
						break;
					case FU_CHARACTER:
					default:
						startptr = sptr;
						s.set(startptr, 1);
						MCU_skip_char(sptr, l);
					}
					// MW-2010-12-15: [[ Bug 9218 ]] Added KEY to the type of repeat that already
					//   copies the value.
					if (each != FU_ELEMENT && each != FU_KEY)
					{
						if (MCtrace)
						{
							ep.setsvalue(s);
							loopvar->set(ep);
						}
						else
							loopvar->sets(s);
					}
				}
			}
			else
				done = count-- == 0;
			break;
		case RF_UNTIL:
			while ((stat = endcond->eval(ep)) != ES_NORMAL
			        && (MCtrace || MCnbreakpoints) && !MCtrylock && !MClockerrors)
				MCB_error(ep, getline(), getpos(), EE_REPEAT_BADUNTILCOND);
			if (stat != ES_NORMAL)
			{
				MCeerror->add
				(EE_REPEAT_BADUNTILCOND, line, pos);
				return ES_ERROR;
			}
			done = ep.getsvalue() == MCtruemcstring;
			break;
		case RF_WHILE:
			while ((stat = endcond->eval(ep)) != ES_NORMAL
			        && (MCtrace || MCnbreakpoints) && !MCtrylock && !MClockerrors)
				MCB_error(ep, getline(), getpos(), EE_REPEAT_BADWHILECOND);
			if (stat != ES_NORMAL)
			{
				MCeerror->add
				(EE_REPEAT_BADWHILECOND, line, pos);
				return ES_ERROR;
			}
			done = ep.getsvalue() != MCtruemcstring;
			break;
		case RF_WITH:
			while (((stat = loopvar->eval(ep)) != ES_NORMAL
			        || (stat = ep.ton()) != ES_NORMAL)
			        && (MCtrace || MCnbreakpoints) && !MCtrylock && !MClockerrors)
				MCB_error(ep, getline(), getpos(), EE_REPEAT_BADWITHVAR);
			if (stat != ES_NORMAL)
			{
				MCeerror->add
				(EE_REPEAT_BADWITHVAR, line, pos);
				return ES_ERROR;
			}
			if (stepval < 0)
			{
				if (ep.getnvalue() <= endn)
					done = True;
			}
			else
				if (ep.getnvalue() >= endn)
					done = True;
			if (!done)
			{
				ep.setnvalue(ep.getnvalue() + stepval);
				while ((stat = loopvar->set
				               (ep)) != ES_NORMAL
				        && (MCtrace || MCnbreakpoints) && !MCtrylock && !MClockerrors)
					MCB_error(ep, getline(), getpos(), EE_REPEAT_BADWITHVAR);
				if (stat != ES_NORMAL)
				{
					MCeerror->add
					(EE_REPEAT_BADWITHVAR, line, pos);
					return ES_ERROR;
				}
			}
			break;
		default:
			break;
		}
		if (done)
			break;

		Exec_stat stat;
		MCStatement *tspr = statements;
		while (tspr != NULL)
		{
			if (MCtrace || MCnbreakpoints)
			{
				MCB_trace(ep, tspr->getline(), tspr->getpos());
				if (MCexitall)
					break;
			}
			ep.setline(tspr->getline());

			stat = tspr->exec(ep);

			// MW-2011-08-17: [[ Redraw ]] Flush any screen updates.
			MCRedrawUpdateScreen();
			
			switch(stat)
			{
			case ES_NORMAL:
				if (MCexitall)
				{
					// OK-2007-12-05 : Bug 5605 : If exiting loop, set the loop variable to the value it had
					//   in the last iteration.
					// MW-2011-02-08: [[ Bug ]] Make sure we don't use 's' if the repeat type is 'key' or
					//   'element'.
					if (form == RF_FOR && loopvar != NULL && each != FU_ELEMENT && each != FU_KEY)
					{
						ep.setsvalue(s);
						loopvar->set(ep);
					}
					delete sp;
					return ES_NORMAL;
				}
				tspr = tspr->getnext();
				break;
			case ES_NEXT_REPEAT:
				tspr = NULL;
				break;
			case ES_EXIT_REPEAT:
				// OK-2007-12-05 : Bug 5605 : If exiting loop, set the loop variable to the value it had
				//   in the last iteration.
				// MW-2011-02-08: [[ Bug ]] Make sure we don't use 's' if the repeat type is 'key' or
				//   'element'.
				if (form == RF_FOR && loopvar != NULL && each != FU_ELEMENT && each != FU_KEY)
				{
					ep.setsvalue(s);
					loopvar->set(ep);
				}
				delete sp;
				return ES_NORMAL;
			case ES_ERROR:
				if ((MCtrace || MCnbreakpoints) && !MCtrylock && !MClockerrors)
					do
					{
						MCB_error(ep, tspr->getline(), tspr->getpos(),
						          EE_REPEAT_BADSTATEMENT);
					}
					while (MCtrace && (stat = tspr->exec(ep)) != ES_NORMAL);
				if (stat == ES_ERROR)
				{
					// OK-2007-12-05 : Bug 5605 : If exiting loop, set the loop variable to the value it had
					//   in the last iteration.
					// MW-2011-02-08: [[ Bug ]] Make sure we don't use 's' if the repeat type is 'key' or
					//   'element'.
					if (form == RF_FOR && loopvar != NULL && each != FU_ELEMENT && each != FU_KEY)
					{
						ep.setsvalue(s);
						loopvar->set(ep);
					}
					delete sp;
					if (MCexitall)
						return ES_NORMAL;
					else
					{
						MCeerror->add(EE_REPEAT_BADSTATEMENT, line, pos);
						return ES_ERROR;
					}
				}
				else
					tspr = tspr->getnext();
				break;
			default:
				// OK-2007-12-05 : Bug 5605 : If exiting loop, set the loop variable to the value it had
				//   in the last iteration.
				// MW-2011-02-08: [[ Bug ]] Make sure we don't use 's' if the repeat type is 'key' or
				//   'element'.
				if (form == RF_FOR && loopvar != NULL && each != FU_ELEMENT && each != FU_KEY)
				{
					ep.setsvalue(s);
					loopvar->set(ep);
				}
				delete sp;
				return stat;
			}
		}
		if (MCscreen->abortkey())
		{
			// OK-2007-12-05 : Bug 5605 : If exiting loop, set the loop variable to the value it had
			//   in the last iteration.
			// MW-2011-02-08: [[ Bug ]] Make sure we don't use 's' if the repeat type is 'key' or
			//   'element'.
			if (form == RF_FOR && loopvar != NULL && each != FU_ELEMENT && each != FU_KEY)
			{
				ep.setsvalue(s);
				loopvar->set(ep);
			}
			delete sp;
			MCeerror->add(EE_REPEAT_ABORT, line, pos);
			return ES_ERROR;
		}
		if (MCtrace || MCnbreakpoints)
		{
			MCB_trace(ep, getline(), getpos());
			if (MCexitall)
				break;
		}

		t_first = false;
	}
	delete sp;
	return ES_NORMAL;
}