void MCError::add(uint2 id, uint2 line, uint2 pos, const MCString &token) { if (MCerrorlock != 0 || thrown) return; if (line != 0 && errorline == 0) { errorline = line; errorpos = pos; } if (depth > 1024) return; char *newerror = new char[U2L * 3 + token.getlength()]; if (token == MCnullmcstring) sprintf(newerror, "%d,%d,%d", id, line, pos); else { const char *eptr = token.getstring(); int4 length = 0; while (length < (int4)token.getlength()) { if (*eptr++ == '\n') break; length++; } sprintf(newerror, "%d,%d,%d,%*.*s", id, line, pos, length, length, token.getstring()); } MCU_addline(buffer, newerror, strlen(buffer) == 0); depth += 1; delete newerror; }
void MCExecPoint::insert(const MCString &istring, uint4 s, uint4 e) { if (format == VF_NUMBER) tos(); uint4 oldlength = svalue.getlength(); uint4 ilength = istring.getlength(); uint4 newlength = oldlength - (e - s) + ilength; const char *sptr = svalue.getstring(); const char *isptr = istring.getstring(); char *oldbuffer = NULL; if (newlength > size || sptr >= buffer && sptr < buffer + newlength || isptr >= buffer && isptr < buffer + newlength) { oldbuffer = buffer; size = newlength + EP_PAD & EP_MASK; buffer = new char[size]; memcpy(buffer, sptr, s); memcpy(&buffer[s], isptr, ilength); memcpy(&buffer[s + ilength], &sptr[e], oldlength - e); } else { memmove(buffer, sptr, s); memmove(&buffer[s], isptr, ilength); memmove(&buffer[s + ilength], &sptr[e], oldlength - e); } delete oldbuffer; svalue.set(buffer, newlength); format = VF_STRING; }
Exec_stat MCVideoClip::setprop(uint4 parid, Properties p, MCExecPoint &ep, Boolean effective) { MCString data = ep.getsvalue(); Boolean dirty = False; switch (p) { case P_DONT_REFRESH: if (!MCU_matchflags(data, flags, F_DONT_REFRESH, dirty)) { MCeerror->add (EE_OBJECT_NAB, 0, 0, data); return ES_ERROR; } return ES_NORMAL; case P_FRAME_RATE: if (data.getlength() == 0) flags &= ~F_FRAME_RATE; else { if (!MCU_stoui2(data, framerate)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } flags |= F_FRAME_RATE; } return ES_NORMAL; case P_SCALE: if (!MCU_stor8(data, scale)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } flags |= F_SCALE_FACTOR; return ES_NORMAL; case P_TEXT: delete frames; size = data.getlength(); frames = new uint1[size]; memcpy(frames, data.getstring(), size); return ES_NORMAL; default: break; } return MCObject::setprop(parid, p, ep, effective); }
void MCS_posttourl(MCObject *p_target, const MCString& p_data, const char *p_url) { bool t_success = true; char *t_processed = nil; MCObjectHandle *t_obj = nil; MCSPostUrlState t_state; t_success = MCSystemProcessUrl(p_url, kMCSystemUrlOperationStrip, t_processed); if (t_success) t_success = nil != (t_obj = p_target->gethandle()); if (t_success) { t_state . url = t_processed; t_state . status = kMCSystemUrlStatusNone; t_state . object = t_obj; t_state . data . assign_empty(); t_state . post_sent = 0; t_state . post_length = p_data . getlength(); t_success = MCSystemPostUrl(t_processed, p_data.getstring(), p_data.getlength(), MCS_posturl_callback, &t_state); } if (t_success) { MCurlresult -> clear(); while(t_state . status != kMCSystemUrlStatusFinished && t_state . status != kMCSystemUrlStatusError) MCscreen -> wait(60.0, True, True); if (t_state . status == kMCSystemUrlStatusFinished) { MCurlresult -> getvalue() . exchange(t_state . data); MCresult -> clear(); } else { MCurlresult -> clear(); MCresult -> getvalue() . exchange(t_state . data); } } MCCStringFree(t_processed); if (t_obj != nil) t_obj -> Release(); }
static bool MCParseRGBA(const MCString &p_data, bool p_require_alpha, uint1 &r_red, uint1 &r_green, uint1 &r_blue, uint1 &r_alpha) { bool t_success = true; Boolean t_parsed; uint2 r, g, b, a; const char *t_data = p_data.getstring(); uint32_t l = p_data.getlength(); if (t_success) { r = MCU_max(0, MCU_min(255, MCU_strtol(t_data, l, ',', t_parsed))); t_success = t_parsed; } if (t_success) { g = MCU_max(0, MCU_min(255, MCU_strtol(t_data, l, ',', t_parsed))); t_success = t_parsed; } if (t_success) { b = MCU_max(0, MCU_min(255, MCU_strtol(t_data, l, ',', t_parsed))); t_success = t_parsed; } if (t_success) { a = MCU_max(0, MCU_min(255, MCU_strtol(t_data, l, ',', t_parsed))); if (!t_parsed) { if (p_require_alpha) t_success = false; else a = 255; } } if (t_success) { r_red = r; r_green = g; r_blue = b; r_alpha = a; } return t_success; }
IO_stat IO_write_string(const MCString &p_string, IO_handle p_stream, uint8_t p_size, bool p_write_null) { IO_stat stat = IO_NORMAL; uint32_t t_strlen = p_string.getlength(); uint4 length = 0; uint32_t t_inc = p_write_null ? 1 : 0; switch (p_size) { case 1: { uint1 len = t_strlen == 0 ? 0 : MCU_min(t_strlen + t_inc, MAXUINT1); if ((stat = IO_write_uint1(len, p_stream)) != IO_NORMAL) return stat; length = len; break; } case 2: { uint2 len = t_strlen == 0 ? 0 : MCU_min(t_strlen + t_inc, MAXUINT2); if ((stat = IO_write_uint2(len, p_stream)) != IO_NORMAL) return stat; length = len; break; } case 4: length = t_strlen == 0 ? 0 : t_strlen + t_inc; if ((stat = IO_write_uint4(length, p_stream)) != IO_NORMAL) return stat; break; } if (length) { stat = MCStackSecurityWrite(p_string.getstring(), length - t_inc, p_stream); if (stat == IO_NORMAL && p_write_null) stat = IO_write_uint1(0, p_stream); } return stat; }
void MCExecPoint::concat(const MCString &two, Exec_concat ec, Boolean first) { if (format == VF_NUMBER) tos(); uint4 oldlength = svalue.getlength(); uint4 newlength = oldlength + two.getlength(); if (!first && ec != EC_NONE) newlength++; if (newlength > size) { // MW-2012-01-25: [[ Bug 9956 ]] Small optimization to improve large // concatenations. Using 'realloc' means that no copying of data is // needed in the best cases. size = newlength + EP_PAD & EP_MASK; if (svalue.getstring() != buffer) { char *newbuffer = new char[size]; memcpy(newbuffer, svalue.getstring(), oldlength); delete buffer; buffer = newbuffer; } else { char *newbuffer = (char *)realloc(buffer, size); if (newbuffer == nil) return; buffer = newbuffer; } svalue.setstring(buffer); } else if (svalue.getstring() != buffer) { memmove(buffer, svalue.getstring(), oldlength); svalue.setstring(buffer); } if (!first) switch (ec) { case EC_NONE: break; case EC_SPACE: buffer[oldlength++] = ' '; break; case EC_COMMA: buffer[oldlength++] = ','; break; case EC_NULL: buffer[oldlength++] = '\0'; break; case EC_RETURN: buffer[oldlength++] = '\n'; break; // MW-2009-06-17: Can now concatenate with tab into an EP. case EC_TAB: buffer[oldlength++] = '\t'; break; } if (two.getlength() == 1) buffer[oldlength] = two.getstring()[0]; else memcpy(&buffer[oldlength], two.getstring(), two.getlength()); svalue.setlength(newlength); format = VF_STRING; }
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++; }
MCFontnode::MCFontnode(const MCString &fname, uint2 &size, uint2 style, Boolean printer) { reqname = fname.clone(); reqsize = size; reqstyle = style; reqprinter = printer; font = new MCFontStruct; if (MCnoui) { memset(font, 0, sizeof(MCFontStruct)); return; } LOGFONTA logfont; memset(&logfont, 0, sizeof(LOGFONTA)); uint4 maxlength = MCU_min(LF_FACESIZE - 1U, fname.getlength()); strncpy(logfont.lfFaceName, fname.getstring(), maxlength); logfont.lfFaceName[maxlength] = '\0'; // MW-2012-05-03: [[ Bug 10180 ]] Make sure the default charset for the font // is chosen - otherwise things like WingDings don't work! logfont.lfCharSet = DEFAULT_CHARSET; //parse font and encoding char *sptr = logfont.lfFaceName; if (sptr = strchr(logfont.lfFaceName, ',')) { *sptr = '\0'; sptr++; } HDC hdc; // MW-2013-11-07: [[ Bug 11393 ]] 'printer' in the fontstruct now means use ideal // metrics for rendering and measuring. MCScreenDC *pms = (MCScreenDC *)MCscreen; hdc = pms->getsrchdc(); logfont.lfHeight = MulDiv(MulDiv(size, 7, 8), SCREEN_WIDTH_FOR_FONT_USE, 72); logfont.lfWeight = weighttable[MCF_getweightint(style)]; if (style & FA_ITALIC) logfont.lfItalic = TRUE; if (style & FA_OBLIQUE) logfont.lfOrientation = 3600 - 150; /* 15 degree forward slant */ HFONT newfont = CreateFontIndirectA(&logfont); SelectObject(hdc, newfont); char testname[LF_FACESIZE]; memset(testname, 0, LF_FACESIZE); GetTextFaceA(hdc, LF_FACESIZE, testname); // MW-2012-02-13: If we failed to find an exact match then remap the font name and // try again. if (newfont == NULL || (MCU_strncasecmp(testname, logfont.lfFaceName, strlen(testname) + 1))) { if (newfont != NULL) DeleteObject(newfont); mapfacename(logfont.lfFaceName, logfont.lfFaceName, printer == True); // Force the resulting font to be TrueType and with ANSI charset (otherwise // we get strange UI symbol font on XP). logfont.lfCharSet = ANSI_CHARSET; logfont.lfOutPrecision = OUT_TT_ONLY_PRECIS; newfont = CreateFontIndirectA(&logfont); SelectObject(hdc, newfont); } // At this point we will have either found an exact match for the textFont, mapped // using the defaults table and found a match, or been given a default truetype font. TEXTMETRICA tm; GetTextMetricsA(hdc, &tm); font->fid = (MCSysFontHandle)newfont; font->size = size; // MW-2013-12-19: [[ Bug 11606 ]] Use Mac-style metric adjustment in printer (ideal // layout mode). if (!printer) { font->ascent = MulDiv(tm.tmAscent, 15, 16); font->descent = tm.tmDescent; } else { font -> ascent = size - 1; font -> descent = size * 2 / 14 + 1; } font->printer = printer; }
Exec_stat MCF_parsetextatts(Properties which, const MCString &data, uint4 &flags, char *&fname, uint2 &height, uint2 &size, uint2 &style) { int2 i1; switch (which) { case P_TEXT_ALIGN: flags &= ~F_ALIGNMENT; if (data == MCleftstring || data.getlength() == 0) flags |= F_ALIGN_LEFT; else if (data == MCcenterstring) flags |= F_ALIGN_CENTER; else if (data == MCrightstring) flags |= F_ALIGN_RIGHT; else if (data == MCjustifystring) flags |= F_ALIGN_JUSTIFY; else { MCeerror->add(EE_OBJECT_BADALIGN, 0, 0, data); return ES_ERROR; } break; case P_TEXT_FONT: { fname = data.clone(); // MW-2012-02-17: [[ IntrinsicUnicode ]] Strip any lang tag from the // fontname. char *t_tag; t_tag = strchr(fname, ','); if (t_tag != nil) t_tag[0] = '\0'; } break; case P_TEXT_HEIGHT: if (!MCU_stoi2(data, i1)) { MCeerror->add (EE_OBJECT_TEXTHEIGHTNAN, 0, 0, data); return ES_ERROR; } height = i1; break; case P_TEXT_SIZE: if (data.getlength() == 0) i1 = 0; else if (!MCU_stoi2(data, i1)) { MCeerror->add (EE_OBJECT_TEXTSIZENAN, 0, 0, data); return ES_ERROR; } size = i1; break; case P_TEXT_STYLE: { // MW-2012-02-17: [[ SplitTextAttrs ]] If the string is empty, then // return 0 for the style - indicating to unset the property. uint4 l = data.getlength(); const char *sptr = data.getstring(); if (l == 0) style = 0; else { style = FA_DEFAULT_STYLE; while (l) { const char *startptr = sptr; if (!MCU_strchr(sptr, l, ',')) { sptr += l; l = 0; } MCString tdata(startptr, sptr - startptr); MCU_skip_char(sptr, l); MCU_skip_spaces(sptr, l); if (MCF_setweightstring(style, tdata)) continue; if (MCF_setexpandstring(style, tdata)) continue; if (MCF_setslantlongstring(style, tdata)) continue; if (tdata == MCplainstring) { style = FA_DEFAULT_STYLE; continue; } if (tdata == MCmixedstring) { style = FA_DEFAULT_STYLE; continue; } if (tdata == MCboxstring) { style &= ~FA_3D_BOX; style |= FA_BOX; continue; } if (tdata == MCthreedboxstring) { style &= ~FA_BOX; style |= FA_3D_BOX; continue; } if (tdata == MCunderlinestring) { style |= FA_UNDERLINE; continue; } if (tdata == MCstrikeoutstring) { style |= FA_STRIKEOUT; continue; } if (tdata == MCgroupstring || tdata == MClinkstring) { style |= FA_LINK; continue; } MCeerror->add(EE_OBJECT_BADSTYLE, 0, 0, data); return ES_ERROR; } } } break; default: break; } return ES_NORMAL; }