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; }
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 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; }
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; }
void MCS_putintourl(MCObject *p_target, const MCString& p_data, const char *p_url) { bool t_success = true; char *t_processed = nil; MCObjectHandle *t_obj = nil; MCSPutUrlState 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.put_sent = 0; t_state.put_length = p_data.getlength(); t_success = MCSystemPutUrl(t_processed, p_data . getstring(), p_data . getlength(), MCS_puturl_callback, &t_state); } if (t_success); { MCurlresult->clear(); while (t_state.status != kMCSystemUrlStatusUploaded && t_state.status != kMCSystemUrlStatusError) MCscreen->wait(60.0, True, True); if (t_state.status == kMCSystemUrlStatusUploaded) MCresult->clear(); else MCresult->sets(MCString(t_state.error)); } MCCStringFree(t_processed); if (t_obj != nil) t_obj->Release(); }
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; }
MCOldFontnode::MCOldFontnode(const MCString &fname, uint2 &size, uint2 style) { char fontname[XLFD_LENGTH]; uint4 length = fname.getlength(); reqname = new char[length + 1]; MCU_lower(reqname, fname); reqname[length] = '\0'; reqsize = size; reqstyle = style; uint2 t_original_size; t_original_size = size; XFontStruct *fs = NULL; memset(&font, 0, sizeof(MCFontStruct)); font.charset = 0; if (MCnoui) return; Boolean t_is_unicode = False; // MW-2005-02-08: We aren't going to use XMBTEXT for now, instead we will // search for an appropriate ISO10646 font if in 'encoding mode'. if (strchr(reqname, ',') != NULL) { sprintf(fontname, "-*-%.*s-%s-%s-%s--%d-*-*-*-*-*-iso10646-*", strchr(reqname, ',') - reqname, reqname, MCF_getweightstring(style), MCF_getslantshortstring(style), MCF_getexpandstring(style), size); t_is_unicode = True; } else sprintf(fontname, "-*-%s-%s-%s-%s--%d-*-*-*-*-*-iso8859-%d", reqname, MCF_getweightstring(style), MCF_getslantshortstring(style), MCF_getexpandstring(style), size, MCcharset); if ((fs = XLoadQueryFont(MCdpy, fontname)) == NULL) fs = lookup(reqname, size, style); else font.unicode = t_is_unicode; if (fs == NULL) if ((fs = XLoadQueryFont(MCdpy, reqname)) != NULL) { if (pixelsize == 0) pixelsize = XInternAtom(MCdpy, "PIXEL_SIZE", True); uint2 i = fs->n_properties; while (i--) if (fs->properties[i].name == pixelsize) { size = reqsize = fs->properties[i].card32; break; } size = reqsize = fs->ascent + fs->descent - 2; } if (fs == NULL) fs = lookup(DEFAULT_TEXT_FONT, size, style); if (fs == NULL) fs = XLoadQueryFont(MCdpy, "fixed"); font.reqname = strdup(reqname) ; font.reqsize = reqsize ; font.reqstyle = reqstyle ; font.fstruct = fs; font.max_byte1 = fs -> max_byte1; font.ascent = fs -> ascent; font.descent = fs -> descent; font.unicode = t_is_unicode; if (t_is_unicode) font.charset = LCH_UNICODE; }
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 MCEPS::setprop_legacy(uint4 parid, Properties p, MCExecPoint &ep, Boolean effective) { Boolean dirty = True; real8 n; int2 i; int2 i1, i2, i3, i4; MCString data = ep.getsvalue(); switch (p) { #ifdef /* MCEPS::setprop */ LEGACY_EXEC case P_TRAVERSAL_ON: case P_SHOW_BORDER: if (MCControl::setprop(parid, p, ep, effective) != ES_NORMAL) return ES_ERROR; resetscale(); break; case P_ANGLE: if (!MCU_stoi2(data, i)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } angle = i; break; case P_POSTSCRIPT: delete postscript; postscript = data.clone(); size = data.getlength() + 1; setextents(); resetscale(); break; case P_PROLOG: delete prolog; prolog = data.clone(); break; case P_RETAIN_IMAGE: if (!MCU_matchflags(data, flags, F_RETAIN_IMAGE, dirty)) { MCeerror->add (EE_OBJECT_NAB, 0, 0, data); return ES_ERROR; } dirty = False; break; case P_RETAIN_POSTSCRIPT: if (!MCU_matchflags(data, flags, F_RETAIN_POSTSCRIPT, dirty)) { MCeerror->add (EE_OBJECT_NAB, 0, 0, data); return ES_ERROR; } dirty = False; break; case P_SCALE_INDEPENDENTLY: if (!MCU_matchflags(data, flags, F_SCALE_INDEPENDENTLY, dirty)) { MCeerror->add (EE_OBJECT_NAB, 0, 0, data); return ES_ERROR; } if (dirty) resetscale(); break; case P_BOUNDING_RECT: if (!MCU_stoi2x4(data, i1, i2, i3, i4)) { MCeerror->add (EE_OBJECT_NAR, 0, 0, data); return ES_ERROR; } if (tx != i1 || ty != i2 || tx + ex != i3 || ty + ey != i4) { tx = i1; ty = i2; ex = MCU_max(i3 - i1, 1); ey = MCU_max(i4 - i2, 1); resetscale(); } else dirty = False; break; case P_SCALE: if (!MCU_stor8(data, n)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } xscale = yscale = n; break; case P_X_SCALE: if (!MCU_stor8(data, n)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } xscale = n; ex = (uint2)(rect.width * xf / xscale + 0.5); flags |= F_SCALE_INDEPENDENTLY; break; case P_Y_SCALE: if (!MCU_stor8(data, n)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } yscale = n; ey = (uint2)(rect.height * yf / yscale + 0.5); flags |= F_SCALE_INDEPENDENTLY; break; case P_X_OFFSET: if (!MCU_stoi2(data, i)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } tx = i; break; case P_Y_OFFSET: if (!MCU_stoi2(data, i)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } ty = i; break; case P_X_EXTENT: if (!MCU_stoi2(data, i)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } ex = i; resetscale(); break; case P_Y_EXTENT: if (!MCU_stoi2(data, i)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } ey = i; resetscale(); break; case P_CURRENT_PAGE: //set eps current page to display if (!MCU_stoi2(data, i)) { MCeerror->add (EE_OBJECT_NAN, 0, 0, data); return ES_ERROR; } if ((uint2)i > pagecount) curpage = pagecount; else curpage = i; break; #endif /* MCEPS::setprop */ default: return MCControl::setprop_legacy(parid, p, ep, effective); } if (dirty && opened) { // MW-2011-08-18: [[ Layers ]] Invalidate the whole object. layer_redrawall(); } return ES_NORMAL; }
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; }
IO_stat MCDispatch::dosavestack(MCStack *sptr, const MCString &fname) { if (MCModeCheckSaveStack(sptr, fname) != IO_NORMAL) return IO_ERROR; char *linkname; if (fname.getlength() != 0) linkname = fname.clone(); else if ((linkname = strclone(sptr->getfilename())) == NULL) { MCresult->sets("stack does not have a filename"); return IO_ERROR; } if (linkname == NULL) { MCresult->sets("can't open stack file, bad path"); return IO_ERROR; } if (MCS_noperm(linkname)) { MCresult->sets("can't open stack file, no permission"); delete linkname; return IO_ERROR; } char *oldfiletype = MCfiletype; MCfiletype = MCstackfiletype; char *backup = new char[strlen(linkname) + 2]; strcpy(backup, linkname); strcat(backup, "~"); MCS_unlink(backup); if (MCS_exists(linkname, True) && !MCS_backup(linkname, backup)) { MCresult->sets("can't open stack backup file"); MCfiletype = oldfiletype; delete linkname; delete backup; return IO_ERROR; } IO_handle stream; if ((stream = MCS_open(linkname, IO_WRITE_MODE, True, False, 0)) == NULL) { MCresult->sets("can't open stack file"); cleanup(stream, linkname, backup); MCfiletype = oldfiletype; return IO_ERROR; } MCfiletype = oldfiletype; MCString errstring = "Error writing stack (disk full?)"; // MW-2012-03-04: [[ StackFile5500 ]] Work out what header to emit, and the size. const char *t_header; uint32_t t_header_size; if (MCstackfileversion >= 5500) t_header = newheader5500, t_header_size = 8; else if (MCstackfileversion >= 2700) t_header = newheader, t_header_size = 8; else t_header = header, t_header_size = HEADERSIZE; if (IO_write(t_header, sizeof(char), t_header_size, stream) != IO_NORMAL || IO_write_uint1(CHARSET, stream) != IO_NORMAL) { MCresult->sets(errstring); cleanup(stream, linkname, backup); return IO_ERROR; } if (IO_write_uint1(OT_NOTHOME, stream) != IO_NORMAL || IO_write_string(NULL, stream) != IO_NORMAL) { // was stackfiles MCresult->sets(errstring); cleanup(stream, linkname, backup); return IO_ERROR; } // MW-2012-02-22; [[ NoScrollSave ]] Adjust the rect by the current group offset. MCgroupedobjectoffset . x = 0; MCgroupedobjectoffset . y = 0; MCresult -> clear(); if (sptr->save(stream, 0, false) != IO_NORMAL || IO_write_uint1(OT_END, stream) != IO_NORMAL) { if (MCresult -> isclear()) MCresult->sets(errstring); cleanup(stream, linkname, backup); return IO_ERROR; } MCS_close(stream); uint2 oldmask = MCS_umask(0); uint2 newmask = ~oldmask & 00777; if (oldmask & 00400) newmask &= ~00100; if (oldmask & 00040) newmask &= ~00010; if (oldmask & 00004) newmask &= ~00001; MCS_umask(oldmask); MCS_chmod(linkname, newmask); if (sptr->getfilename() != NULL && !strequal(linkname, sptr->getfilename())) MCS_copyresourcefork(sptr->getfilename(), linkname); else if (sptr -> getfilename() != NULL) MCS_copyresourcefork(backup, linkname); sptr->setfilename(linkname); if (backup != NULL) { MCS_unlink(backup); delete backup; } return IO_NORMAL; }