From 11f29b1231620cb07e2a91b1e0d143ade8bf3c58 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 6 Nov 2015 11:40:12 +0300 Subject: [PATCH] Replace NameStr with std::string. This removes the arbitrary 64 byte restriction (which effectively limits us to as little as 16 Unicode characters with CJK encodings), makes classes smaller, and is easier to use. As a consequence of making the length of all ex-NameStr fields unbounded, all functions that returned a buffer derived from those were changed to return std::string. Then, functions that are contextually similar to the ones described above were changed to return std::string. Then, functions that now happened to mostly take an std::string argument converted to a C string were changed to accept std::string. This has produced a bit of churn, but is probably for the better. --- src/clipboard.cpp | 20 ++++++------ src/cocoa/cocoamain.mm | 8 ++--- src/confscreen.cpp | 43 ++++++++++++------------ src/constraint.cpp | 7 ++-- src/describescreen.cpp | 52 +++++++++++++++-------------- src/drawconstraint.cpp | 36 ++++++++++---------- src/drawentity.cpp | 10 +++--- src/dsc.h | 10 ------ src/exportvector.cpp | 10 +++--- src/expr.cpp | 40 +++++++---------------- src/expr.h | 6 ++-- src/file.cpp | 32 +++++++++--------- src/group.cpp | 30 ++++++++--------- src/gtk/gtkmain.cpp | 6 ++-- src/mouse.cpp | 26 +++++++-------- src/request.cpp | 11 +++---- src/sketch.h | 36 ++++++++++---------- src/solvespace.cpp | 18 +++------- src/solvespace.h | 19 +++++++---- src/style.cpp | 74 ++++++++++++++++++------------------------ src/textscreens.cpp | 69 ++++++++++++++++++--------------------- src/textwin.cpp | 4 +-- src/ttf.cpp | 13 +++----- src/ui.h | 2 +- src/util.cpp | 19 +++++++++++ src/view.cpp | 29 ++++++++--------- src/win32/w32main.cpp | 8 ++--- 27 files changed, 297 insertions(+), 341 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index 031002aa..4855f2ce 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -86,8 +86,8 @@ void GraphicsWindow::CopySelection(void) { cr.type = req; cr.extraPoints = e->extraPoints; cr.style = e->style; - cr.str.strcpy( e->str.str); - cr.font.strcpy( e->font.str); + cr.str = e->str; + cr.font = e->font; cr.construction = e->construction; {for(int i = 0; i < pts; i++) { Vector pt = SK.GetEntity(e->point[i])->PointGetNum(); @@ -133,8 +133,8 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { Request *r = SK.GetRequest(hr); r->extraPoints = cr->extraPoints; r->style = cr->style; - r->str.strcpy( cr->str.str); - r->font.strcpy( cr->font.str); + r->str = cr->str; + r->font = cr->font; r->construction = cr->construction; // Need to regen to get the right number of points, if extraPoints // changed. @@ -374,14 +374,14 @@ void TextWindow::ShowPasteTransformed(void) { shown.paste.theta*180/PI, &ScreenChangePasteTransformed); Printf(false, "%Ba %Ftabout pt%E (%s, %s, %s) %Fl%Lo%f[use selected]%E", - SS.MmToString(shown.paste.origin.x), - SS.MmToString(shown.paste.origin.y), - SS.MmToString(shown.paste.origin.z), + SS.MmToString(shown.paste.origin.x).c_str(), + SS.MmToString(shown.paste.origin.y).c_str(), + SS.MmToString(shown.paste.origin.z).c_str(), &ScreenPasteTransformed); Printf(false, "%Bd %Fttranslate%E (%s, %s, %s) %Fl%Lt%f[use selected]%E", - SS.MmToString(shown.paste.trans.x), - SS.MmToString(shown.paste.trans.y), - SS.MmToString(shown.paste.trans.z), + SS.MmToString(shown.paste.trans.x).c_str(), + SS.MmToString(shown.paste.trans.y).c_str(), + SS.MmToString(shown.paste.trans.z).c_str(), &ScreenPasteTransformed); Printf(false, "%Ba %Ftscale%E %@ %Fl%Ls%f[change]%E", shown.paste.scale, diff --git a/src/cocoa/cocoamain.mm b/src/cocoa/cocoamain.mm index be30e63f..4779ef7d 100644 --- a/src/cocoa/cocoamain.mm +++ b/src/cocoa/cocoamain.mm @@ -487,8 +487,8 @@ bool FullScreenIsActive(void) { return [GWDelegate isFullscreen]; } -void ShowGraphicsEditControl(int x, int y, char *str) { - [GWView startEditing:[NSString stringWithUTF8String:str] +void ShowGraphicsEditControl(int x, int y, const std::string &str) { + [GWView startEditing:[NSString stringWithUTF8String:str.c_str()] at:(NSPoint){(CGFloat)x, (CGFloat)y}]; } @@ -1010,8 +1010,8 @@ void SetMousePointerToHand(bool is_hand) { [TWView setCursorHand:is_hand]; } -void ShowTextEditControl(int x, int y, char *str) { - return [TWView startEditing:[NSString stringWithUTF8String:str] +void ShowTextEditControl(int x, int y, const std::string &str) { + return [TWView startEditing:[NSString stringWithUTF8String:str.c_str()] at:(NSPoint){(CGFloat)x, (CGFloat)y}]; } diff --git a/src/confscreen.cpp b/src/confscreen.cpp index 135998d2..1ea254e8 100644 --- a/src/confscreen.cpp +++ b/src/confscreen.cpp @@ -137,30 +137,30 @@ void TextWindow::ScreenChangeCanvasSize(int link, uint32_t v) { } void TextWindow::ScreenChangeGCodeParameter(int link, uint32_t v) { - char buf[1024] = ""; + std::string buf; int row = 93; switch(link) { case 'd': SS.TW.edit.meaning = EDIT_G_CODE_DEPTH; - strcpy(buf, SS.MmToString(SS.gCode.depth)); + buf += SS.MmToString(SS.gCode.depth); row += 0; break; case 's': SS.TW.edit.meaning = EDIT_G_CODE_PASSES; - sprintf(buf, "%d", SS.gCode.passes); + buf += std::to_string(SS.gCode.passes); row += 2; break; case 'F': SS.TW.edit.meaning = EDIT_G_CODE_FEED; - strcpy(buf, SS.MmToString(SS.gCode.feed)); + buf += SS.MmToString(SS.gCode.feed); row += 4; break; case 'P': SS.TW.edit.meaning = EDIT_G_CODE_PLUNGE_FEED; - strcpy(buf, SS.MmToString(SS.gCode.plungeFeed)); + buf += SS.MmToString(SS.gCode.plungeFeed); row += 6; break; } @@ -168,10 +168,7 @@ void TextWindow::ScreenChangeGCodeParameter(int link, uint32_t v) { } void TextWindow::ScreenChangeAutosaveInterval(int link, uint32_t v) { - char str[1024]; - sprintf(str, "%d", SS.autosaveInterval); - - SS.TW.ShowEditControl(111, 3, str); + SS.TW.ShowEditControl(111, 3, std::to_string(SS.autosaveInterval)); SS.TW.edit.meaning = EDIT_AUTOSAVE_INTERVAL; } @@ -218,13 +215,13 @@ void TextWindow::ShowConfiguration(void) { &ScreenChangeCameraTangent, 0); Printf(false, "%Ft snap grid spacing%E"); Printf(false, "%Ba %s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.gridSpacing), + SS.MmToString(SS.gridSpacing).c_str(), &ScreenChangeGridSpacing, 0); Printf(false, "%Ft digits after decimal point to show%E"); Printf(false, "%Ba %d %Fl%Ll%f%D[change]%E (e.g. '%s')", SS.UnitDigitsAfterDecimal(), &ScreenChangeDigitsAfterDecimal, 0, - SS.MmToString(SS.StringToMm("1.23456789"))); + SS.MmToString(SS.StringToMm("1.23456789")).c_str()); Printf(false, ""); Printf(false, "%Ft export scale factor (1:1=mm, 1:25.4=inch)"); @@ -233,7 +230,7 @@ void TextWindow::ShowConfiguration(void) { &ScreenChangeExportScale, 0); Printf(false, "%Ft cutter radius offset (0=no offset) "); Printf(false, "%Ba %s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportOffset), + SS.MmToString(SS.exportOffset).c_str(), &ScreenChangeExportOffset, 0); Printf(false, ""); @@ -264,35 +261,35 @@ void TextWindow::ShowConfiguration(void) { if(SS.exportCanvasSizeAuto) { Printf(false, "%Ft (by margins around exported geometry)"); Printf(false, "%Ba%Ft left: %Fd%s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportMargin.left), &ScreenChangeCanvasSize, 0); + SS.MmToString(SS.exportMargin.left).c_str(), &ScreenChangeCanvasSize, 0); Printf(false, "%Bd%Ft right: %Fd%s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportMargin.right), &ScreenChangeCanvasSize, 1); + SS.MmToString(SS.exportMargin.right).c_str(), &ScreenChangeCanvasSize, 1); Printf(false, "%Ba%Ft bottom: %Fd%s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportMargin.bottom), &ScreenChangeCanvasSize, 2); + SS.MmToString(SS.exportMargin.bottom).c_str(), &ScreenChangeCanvasSize, 2); Printf(false, "%Bd%Ft top: %Fd%s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportMargin.top), &ScreenChangeCanvasSize, 3); + SS.MmToString(SS.exportMargin.top).c_str(), &ScreenChangeCanvasSize, 3); } else { Printf(false, "%Ft (by absolute dimensions and offsets)"); Printf(false, "%Ba%Ft width: %Fd%s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportCanvas.width), &ScreenChangeCanvasSize, 10); + SS.MmToString(SS.exportCanvas.width).c_str(), &ScreenChangeCanvasSize, 10); Printf(false, "%Bd%Ft height: %Fd%s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportCanvas.height), &ScreenChangeCanvasSize, 11); + SS.MmToString(SS.exportCanvas.height).c_str(), &ScreenChangeCanvasSize, 11); Printf(false, "%Ba%Ft offset x: %Fd%s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportCanvas.dx), &ScreenChangeCanvasSize, 12); + SS.MmToString(SS.exportCanvas.dx).c_str(), &ScreenChangeCanvasSize, 12); Printf(false, "%Bd%Ft offset y: %Fd%s %Fl%Ll%f%D[change]%E", - SS.MmToString(SS.exportCanvas.dy), &ScreenChangeCanvasSize, 13); + SS.MmToString(SS.exportCanvas.dy).c_str(), &ScreenChangeCanvasSize, 13); } Printf(false, ""); Printf(false, "%Ft exported g code parameters"); Printf(false, "%Ba%Ft depth: %Fd%s %Fl%Ld%f[change]%E", - SS.MmToString(SS.gCode.depth), &ScreenChangeGCodeParameter); + SS.MmToString(SS.gCode.depth).c_str(), &ScreenChangeGCodeParameter); Printf(false, "%Bd%Ft passes: %Fd%d %Fl%Ls%f[change]%E", SS.gCode.passes, &ScreenChangeGCodeParameter); Printf(false, "%Ba%Ft feed: %Fd%s %Fl%LF%f[change]%E", - SS.MmToString(SS.gCode.feed), &ScreenChangeGCodeParameter); + SS.MmToString(SS.gCode.feed).c_str(), &ScreenChangeGCodeParameter); Printf(false, "%Bd%Ft plunge fd: %Fd%s %Fl%LP%f[change]%E", - SS.MmToString(SS.gCode.plungeFeed), &ScreenChangeGCodeParameter); + SS.MmToString(SS.gCode.plungeFeed).c_str(), &ScreenChangeGCodeParameter); Printf(false, ""); Printf(false, " %Fd%f%Ll%s draw triangle back faces in red%E", diff --git a/src/constraint.cpp b/src/constraint.cpp index a672cb62..2e2ef1f0 100644 --- a/src/constraint.cpp +++ b/src/constraint.cpp @@ -6,9 +6,7 @@ //----------------------------------------------------------------------------- #include "solvespace.h" -char *Constraint::DescriptionString(void) { - static char ret[1024]; - +std::string Constraint::DescriptionString(void) { const char *s; switch(type) { case POINTS_COINCIDENT: s = "pts-coincident"; break; @@ -49,8 +47,7 @@ char *Constraint::DescriptionString(void) { default: s = "???"; break; } - sprintf(ret, "c%03x-%s", h.v, s); - return ret; + return ssprintf("c%03x-%s", h.v, s); } #ifndef LIBRARY diff --git a/src/describescreen.cpp b/src/describescreen.cpp index 7c4e752f..c6d7f07a 100644 --- a/src/describescreen.cpp +++ b/src/describescreen.cpp @@ -14,7 +14,7 @@ void TextWindow::ScreenEditTtfText(int link, uint32_t v) { hRequest hr = { v }; Request *r = SK.GetRequest(hr); - SS.TW.ShowEditControl(13, 10, r->str.str); + SS.TW.ShowEditControl(13, 10, r->str.c_str()); SS.TW.edit.meaning = EDIT_TTF_TEXT; SS.TW.edit.request = hr; } @@ -35,7 +35,7 @@ void TextWindow::ScreenSetTtfFont(int link, uint32_t v) { if(!r) return; SS.UndoRemember(); - r->font.strcpy(SS.fonts.l.elem[i].FontFileBaseName().c_str()); + r->font = SS.fonts.l.elem[i].FontFileBaseName(); SS.MarkGroupDirty(r->group); SS.ScheduleGenerateAll(); SS.ScheduleShowTW(); @@ -61,7 +61,9 @@ void TextWindow::DescribeSelection(void) { e = SK.GetEntity(gs.points == 1 ? gs.point[0] : gs.entity[0]); #define COSTR(p) \ - SS.MmToString((p).x), SS.MmToString((p).y), SS.MmToString((p).z) + SS.MmToString((p).x).c_str(), \ + SS.MmToString((p).y).c_str(), \ + SS.MmToString((p).z).c_str() #define PT_AS_STR "(%Fi%s%E, %Fi%s%E, %Fi%s%E)" #define PT_AS_NUM "(%Fi%3%E, %Fi%3%E, %Fi%3%E)" switch(e->type) { @@ -108,7 +110,7 @@ void TextWindow::DescribeSelection(void) { p = p1; Printf(false, " " PT_AS_STR, COSTR(p)); Printf(true, " len = %Fi%s%E", - SS.MmToString((p1.Minus(p0).Magnitude()))); + SS.MmToString((p1.Minus(p0).Magnitude())).c_str()); break; } case Entity::CUBIC_PERIODIC: @@ -139,11 +141,11 @@ void TextWindow::DescribeSelection(void) { p = SK.GetEntity(e->point[2])->PointGetNum(); Printf(false, " " PT_AS_STR, COSTR(p)); double r = e->CircleGetRadiusNum(); - Printf(true, " diameter = %Fi%s", SS.MmToString(r*2)); - Printf(false, " radius = %Fi%s", SS.MmToString(r)); + Printf(true, " diameter = %Fi%s", SS.MmToString(r*2).c_str()); + Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str()); double thetas, thetaf, dtheta; e->ArcGetAngles(&thetas, &thetaf, &dtheta); - Printf(false, " arc len = %Fi%s", SS.MmToString(dtheta*r)); + Printf(false, " arc len = %Fi%s", SS.MmToString(dtheta*r).c_str()); break; } case Entity::CIRCLE: { @@ -151,8 +153,8 @@ void TextWindow::DescribeSelection(void) { p = SK.GetEntity(e->point[0])->PointGetNum(); Printf(true, " center = " PT_AS_STR, COSTR(p)); double r = e->CircleGetRadiusNum(); - Printf(true, " diameter = %Fi%s", SS.MmToString(r*2)); - Printf(false, " radius = %Fi%s", SS.MmToString(r)); + Printf(true, " diameter = %Fi%s", SS.MmToString(r*2).c_str()); + Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str()); break; } case Entity::FACE_NORMAL_PT: @@ -169,29 +171,29 @@ void TextWindow::DescribeSelection(void) { case Entity::TTF_TEXT: { Printf(false, "%FtTRUETYPE FONT TEXT%E"); - Printf(true, " font = '%Fi%s%E'", e->font.str); + Printf(true, " font = '%Fi%s%E'", e->font.c_str()); if(e->h.isFromRequest()) { Printf(false, " text = '%Fi%s%E' %Fl%Ll%f%D[change]%E", - e->str.str, &ScreenEditTtfText, e->h.request()); + e->str.c_str(), &ScreenEditTtfText, e->h.request()); Printf(true, " select new font"); SS.fonts.LoadAll(); int i; for(i = 0; i < SS.fonts.l.n; i++) { TtfFont *tf = &(SS.fonts.l.elem[i]); - if(strcmp(e->font.str, tf->FontFileBaseName().c_str())==0) { + if(e->font == tf->FontFileBaseName()) { Printf(false, "%Bp %s", (i & 1) ? 'd' : 'a', - tf->name.str); + tf->name.c_str()); } else { Printf(false, "%Bp %f%D%Fl%Ll%s%E%Bp", (i & 1) ? 'd' : 'a', &ScreenSetTtfFont, i, - tf->name.str, + tf->name.c_str(), (i & 1) ? 'd' : 'a'); } } } else { - Printf(false, " text = '%Fi%s%E'", e->str.str); + Printf(false, " text = '%Fi%s%E'", e->str.c_str()); } break; } @@ -203,16 +205,16 @@ void TextWindow::DescribeSelection(void) { Group *g = SK.GetGroup(e->group); Printf(false, ""); - Printf(false, "%FtIN GROUP%E %s", g->DescriptionString()); + Printf(false, "%FtIN GROUP%E %s", g->DescriptionString().c_str()); if(e->workplane.v == Entity::FREE_IN_3D.v) { Printf(false, "%FtNOT LOCKED IN WORKPLANE%E"); } else { Entity *w = SK.GetEntity(e->workplane); - Printf(false, "%FtIN WORKPLANE%E %s", w->DescriptionString()); + Printf(false, "%FtIN WORKPLANE%E %s", w->DescriptionString().c_str()); } if(e->style.v) { Style *s = Style::Get(e->style); - Printf(false, "%FtIN STYLE%E %s", s->DescriptionString()); + Printf(false, "%FtIN STYLE%E %s", s->DescriptionString().c_str()); } else { Printf(false, "%FtIN STYLE%E none"); } @@ -226,7 +228,7 @@ void TextWindow::DescribeSelection(void) { Vector p1 = SK.GetEntity(gs.point[1])->PointGetNum(); Printf(false, " " PT_AS_STR, COSTR(p1)); double d = (p1.Minus(p0)).Magnitude(); - Printf(true, " d = %Fi%s", SS.MmToString(d)); + Printf(true, " d = %Fi%s", SS.MmToString(d).c_str()); } else if(gs.n == 2 && gs.faces == 1 && gs.points == 1) { Printf(false, "%FtA POINT AND A PLANE FACE"); Vector pt = SK.GetEntity(gs.point[0])->PointGetNum(); @@ -236,7 +238,7 @@ void TextWindow::DescribeSelection(void) { Vector pl = SK.GetEntity(gs.face[0])->FaceGetPointNum(); Printf(false, " plane thru = " PT_AS_STR, COSTR(pl)); double dd = n.Dot(pl) - n.Dot(pt); - Printf(true, " distance = %Fi%s", SS.MmToString(dd)); + Printf(true, " distance = %Fi%s", SS.MmToString(dd).c_str()); } else if(gs.n == 3 && gs.points == 2 && gs.vectors == 1) { Printf(false, "%FtTWO POINTS AND A VECTOR"); Vector p0 = SK.GetEntity(gs.point[0])->PointGetNum(); @@ -247,7 +249,7 @@ void TextWindow::DescribeSelection(void) { v = v.WithMagnitude(1); Printf(true, " vector = " PT_AS_NUM, CO(v)); double d = (p1.Minus(p0)).Dot(v); - Printf(true, " proj_d = %Fi%s", SS.MmToString(d)); + Printf(true, " proj_d = %Fi%s", SS.MmToString(d).c_str()); } else if(gs.n == 2 && gs.lineSegments == 1 && gs.points == 1) { Entity *ln = SK.GetEntity(gs.entity[0]); Vector lp0 = SK.GetEntity(ln->point[0])->PointGetNum(), @@ -258,7 +260,7 @@ void TextWindow::DescribeSelection(void) { Vector pp = SK.GetEntity(gs.point[0])->PointGetNum(); Printf(true, " point " PT_AS_STR, COSTR(pp)); Printf(true, " pt-ln distance = %Fi%s%E", - SS.MmToString(pp.DistanceToLine(lp0, lp1.Minus(lp0)))); + SS.MmToString(pp.DistanceToLine(lp0, lp1.Minus(lp0))).c_str()); } else if(gs.n == 2 && gs.vectors == 2) { Printf(false, "%FtTWO VECTORS"); @@ -296,7 +298,7 @@ void TextWindow::DescribeSelection(void) { if(fabs(theta) < 0.01) { double d = (p1.Minus(p0)).Dot(n0); - Printf(true, " distance = %Fi%s", SS.MmToString(d)); + Printf(true, " distance = %Fi%s", SS.MmToString(d).c_str()); } } else if(gs.n == 0 && gs.stylables > 0) { Printf(false, "%FtSELECTED:%E comment text"); @@ -311,7 +313,7 @@ void TextWindow::DescribeSelection(void) { c->other ? CHECK_TRUE : CHECK_FALSE); } else { Printf(false, "%FtSELECTED:%E %s", - c->DescriptionString()); + c->DescriptionString().c_str()); } } else { int n = SS.GW.selection.n; @@ -327,7 +329,7 @@ void TextWindow::DescribeSelection(void) { Printf(true, "%Fl%D%f%Ll(assign to style %s)%E", shown.style.v, &ScreenAssignSelectionToStyle, - s->DescriptionString()); + s->DescriptionString().c_str()); } // If any of the selected entities have an assigned style, then offer // the option to remove that style. diff --git a/src/drawconstraint.cpp b/src/drawconstraint.cpp index 82a1708b..f9b8f9b0 100644 --- a/src/drawconstraint.cpp +++ b/src/drawconstraint.cpp @@ -57,31 +57,31 @@ double Constraint::EllipticalInterpolation(double rx, double ry, double theta) { return v; } -char *Constraint::Label(void) { - static char Ret[1024]; +std::string Constraint::Label(void) { + std::string result; if(type == ANGLE) { - sprintf(Ret, "%.2f", valA); + result = ssprintf("%.2f", valA); } else if(type == LENGTH_RATIO) { - sprintf(Ret, "%.3f:1", valA); + result = ssprintf("%.3f:1", valA); } else if(type == LENGTH_DIFFERENCE) { - sprintf(Ret, "%.3f", valA); + result = ssprintf("%.3f", valA); } else if(type == COMMENT) { - strcpy(Ret, comment.str); + result = comment; } else if(type == DIAMETER) { if(!other) { // leading spaces for diameter symbol - sprintf(Ret, " %s", SS.MmToString(valA)); + result = " " + SS.MmToString(valA); } else { - sprintf(Ret, "R%s", SS.MmToString(valA / 2)); + result = "R" + SS.MmToString(valA / 2); } } else { // valA has units of distance - strcpy(Ret, SS.MmToString(fabs(valA))); + result = SS.MmToString(fabs(valA)); } if(reference) { - strcat(Ret, " REF"); + result += " REF"; } - return Ret; + return result; } void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) { @@ -92,8 +92,8 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) { th = DEFAULT_TEXT_HEIGHT; } - char *s = Label(); - double swidth = ssglStrWidth(s, th), + std::string s = Label(); + double swidth = ssglStrWidth(s.c_str(), th), sheight = ssglStrHeight(th); // By default, the reference is from the center; but the style could @@ -124,7 +124,7 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) { if(dogd.drawing) { - ssglWriteTextRefCenter(s, th, ref, gr, gu, LineCallback, this); + ssglWriteTextRefCenter(s.c_str(), th, ref, gr, gu, LineCallback, this); } else { double l = swidth/2 - sheight/2; l = max(l, 5/SS.GW.scale); @@ -163,9 +163,9 @@ int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b) { gr = SS.GW.projRight.WithMagnitude(1); double pixels = 1.0 / SS.GW.scale; - char *s = Label(); - double swidth = ssglStrWidth(s, DEFAULT_TEXT_HEIGHT) + 4*pixels, - sheight = ssglStrHeight(DEFAULT_TEXT_HEIGHT) + 8*pixels; + std::string s = Label(); + double swidth = ssglStrWidth(s.c_str(), DEFAULT_TEXT_HEIGHT) + 4*pixels, + sheight = ssglStrHeight(DEFAULT_TEXT_HEIGHT) + 8*pixels; struct { Vector n; @@ -370,7 +370,7 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db, // complex and this looks pretty good. double tl = atan2(rm.Dot(gu), rm.Dot(gr)); double adj = EllipticalInterpolation( - ssglStrWidth(Label(), DEFAULT_TEXT_HEIGHT)/2, + ssglStrWidth(Label().c_str(), DEFAULT_TEXT_HEIGHT)/2, ssglStrHeight(DEFAULT_TEXT_HEIGHT)/2, tl); *ref = (*ref).Plus(rm.WithMagnitude(adj + 3/SS.GW.scale)); diff --git a/src/drawentity.cpp b/src/drawentity.cpp index b90436c1..743ce516 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -7,7 +7,7 @@ //----------------------------------------------------------------------------- #include "solvespace.h" -char *Entity::DescriptionString(void) { +std::string Entity::DescriptionString(void) { if(h.isFromRequest()) { Request *r = SK.GetRequest(h.request()); return r->DescriptionString(); @@ -446,7 +446,7 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) { Vector v = topLeft.Minus(botLeft); Vector u = (v.Cross(n)).WithMagnitude(v.Magnitude()); - SS.fonts.PlotString(font.str, str.str, 0, sbl, botLeft, u, v); + SS.fonts.PlotString(font.c_str(), str.c_str(), 0, sbl, botLeft, u, v); break; } @@ -608,12 +608,12 @@ void Entity::DrawOrGetDistance(void) { if(dogd.drawing) glDisable(GL_LINE_STIPPLE); - char *str = DescriptionString()+5; + std::string str = DescriptionString().substr(5); double th = DEFAULT_TEXT_HEIGHT; if(dogd.drawing) { - ssglWriteText(str, th, mm2, u, v, NULL, NULL); + ssglWriteText(str.c_str(), th, mm2, u, v, NULL, NULL); } else { - Vector pos = mm2.Plus(u.ScaledBy(ssglStrWidth(str, th)/2)).Plus( + Vector pos = mm2.Plus(u.ScaledBy(ssglStrWidth(str.c_str(), th)/2)).Plus( v.ScaledBy(ssglStrHeight(th)/2)); Point2d pp = SS.GW.ProjectPoint(pos); dogd.dmin = min(dogd.dmin, pp.DistanceTo(dogd.mp) - 10); diff --git a/src/dsc.h b/src/dsc.h index e5e21fc2..61b3782c 100644 --- a/src/dsc.h +++ b/src/dsc.h @@ -397,16 +397,6 @@ public: }; -class NameStr { -public: - char str[64]; - - inline void strcpy(const char *in) { - memcpy(str, in, min(strlen(in)+1, sizeof(str))); - str[sizeof(str)-1] = '\0'; - } -}; - class BandedMatrix { public: enum { diff --git a/src/exportvector.cpp b/src/exportvector.cpp index 1d11f8e7..e78b0e4c 100644 --- a/src/exportvector.cpp +++ b/src/exportvector.cpp @@ -661,19 +661,19 @@ void GCodeFileWriter::FinishAndCloseFile(void) { SPoint *pt = sc->l.First(); fprintf(f, "G00 X%s Y%s\r\n", - SS.MmToString(pt->p.x), SS.MmToString(pt->p.y)); + SS.MmToString(pt->p.x).c_str(), SS.MmToString(pt->p.y).c_str()); fprintf(f, "G01 Z%s F%s\r\n", - SS.MmToString(depth), SS.MmToString(SS.gCode.plungeFeed)); + SS.MmToString(depth).c_str(), SS.MmToString(SS.gCode.plungeFeed).c_str()); pt = sc->l.NextAfter(pt); for(; pt; pt = sc->l.NextAfter(pt)) { fprintf(f, "G01 X%s Y%s F%s\r\n", - SS.MmToString(pt->p.x), SS.MmToString(pt->p.y), - SS.MmToString(SS.gCode.feed)); + SS.MmToString(pt->p.x).c_str(), SS.MmToString(pt->p.y).c_str(), + SS.MmToString(SS.gCode.feed).c_str()); } // Move up to a clearance plane 5mm above the work. fprintf(f, "G00 Z%s\r\n", - SS.MmToString(SS.gCode.depth < 0 ? +5 : -5)); + SS.MmToString(SS.gCode.depth < 0 ? +5 : -5).c_str()); } } diff --git a/src/expr.cpp b/src/expr.cpp index 2f6a08ed..81702417 100644 --- a/src/expr.cpp +++ b/src/expr.cpp @@ -547,47 +547,31 @@ hParam Expr::ReferencedParams(ParamList *pl) { // Routines to pretty-print an expression. Mostly for debugging. //----------------------------------------------------------------------------- -static char StringBuffer[4096]; -void Expr::App(const char *s, ...) { - va_list f; - va_start(f, s); - vsprintf(StringBuffer+strlen(StringBuffer), s, f); -} -const char *Expr::Print(void) { +std::string Expr::Print(void) { if(!this) return "0"; - StringBuffer[0] = '\0'; - PrintW(); - return StringBuffer; -} - -void Expr::PrintW(void) { char c; switch(op) { - case PARAM: App("param(%08x)", x.parh.v); break; - case PARAM_PTR: App("param(p%08x)", x.parp->h.v); break; + case PARAM: return ssprintf("param(%08x)", x.parh.v); + case PARAM_PTR: return ssprintf("param(p%08x)", x.parp->h.v); - case CONSTANT: App("%.3f", x.v); break; + case CONSTANT: return ssprintf("%.3f", x.v); case PLUS: c = '+'; goto p; case MINUS: c = '-'; goto p; case TIMES: c = '*'; goto p; case DIV: c = '/'; goto p; p: - App("("); - a->PrintW(); - App(" %c ", c); - b->PrintW(); - App(")"); + return "(" + a->Print() + " " + c + " " + b->Print() + ")"; break; - case NEGATE: App("(- "); a->PrintW(); App(")"); break; - case SQRT: App("(sqrt "); a->PrintW(); App(")"); break; - case SQUARE: App("(square "); a->PrintW(); App(")"); break; - case SIN: App("(sin "); a->PrintW(); App(")"); break; - case COS: App("(cos "); a->PrintW(); App(")"); break; - case ASIN: App("(asin "); a->PrintW(); App(")"); break; - case ACOS: App("(acos "); a->PrintW(); App(")"); break; + case NEGATE: return "(- " + a->Print() + ")"; + case SQRT: return "(sqrt " + a->Print() + ")"; + case SQUARE: return "(square " + a->Print() + ")"; + case SIN: return "(sin " + a->Print() + ")"; + case COS: return "(cos " + a->Print() + ")"; + case ASIN: return "(asin " + a->Print() + ")"; + case ACOS: return "(acos " + a->Print() + ")"; default: oops(); } diff --git a/src/expr.h b/src/expr.h index d53b0b28..2bc97dae 100644 --- a/src/expr.h +++ b/src/expr.h @@ -65,7 +65,7 @@ public: Expr() { } Expr(double v) : op(CONSTANT) { x.v = v; } - + static inline Expr *AllocExpr(void) { return (Expr *)AllocTemporary(sizeof(Expr)); } @@ -99,9 +99,7 @@ public: void ParamsToPointers(void); - void App(const char *str, ...); - const char *Print(void); - void PrintW(void); // worker + std::string Print(void); // number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+) int Children(void); diff --git a/src/file.cpp b/src/file.cpp index d5d2ca7b..cf72bcf4 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -44,7 +44,7 @@ hGroup SolveSpaceUI::CreateDefaultDrawingGroup(void) { g.predef.q = Quaternion::From(1, 0, 0, 0); hRequest hr = Request::HREQUEST_REFERENCE_XY; g.predef.origin = hr.entity(1); - g.name.strcpy("sketch-in-plane"); + g.name = "sketch-in-plane"; SK.group.AddAndAssignId(&g); SK.GetGroup(g.h)->activeWorkplane = g.h.entity(0); return g.h; @@ -56,7 +56,7 @@ void SolveSpaceUI::NewFile(void) { // Our initial group, that contains the references. Group g = {}; g.visible = true; - g.name.strcpy("#references"); + g.name = "#references"; g.type = Group::DRAWING_3D; g.h = Group::HGROUP_REFERENCES; SK.group.Add(&g); @@ -84,7 +84,7 @@ const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = { { 'g', "Group.h.v", 'x', &(SS.sv.g.h.v) }, { 'g', "Group.type", 'd', &(SS.sv.g.type) }, { 'g', "Group.order", 'd', &(SS.sv.g.order) }, - { 'g', "Group.name", 'N', &(SS.sv.g.name) }, + { 'g', "Group.name", 'S', &(SS.sv.g.name) }, { 'g', "Group.activeWorkplane.v", 'x', &(SS.sv.g.activeWorkplane.v) }, { 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) }, { 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) }, @@ -112,8 +112,8 @@ const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = { { 'g', "Group.allDimsReference", 'b', &(SS.sv.g.allDimsReference) }, { 'g', "Group.scale", 'f', &(SS.sv.g.scale) }, { 'g', "Group.remap", 'M', &(SS.sv.g.remap) }, - { 'g', "Group.impFile", 'P', &(SS.sv.g.impFile) }, - { 'g', "Group.impFileRel", 'P', &(SS.sv.g.impFileRel) }, + { 'g', "Group.impFile", 'S', &(SS.sv.g.impFile) }, + { 'g', "Group.impFileRel", 'S', &(SS.sv.g.impFileRel) }, { 'p', "Param.h.v.", 'x', &(SS.sv.p.h.v) }, { 'p', "Param.val", 'f', &(SS.sv.p.val) }, @@ -125,15 +125,15 @@ const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = { { 'r', "Request.group.v", 'x', &(SS.sv.r.group.v) }, { 'r', "Request.construction", 'b', &(SS.sv.r.construction) }, { 'r', "Request.style", 'x', &(SS.sv.r.style) }, - { 'r', "Request.str", 'N', &(SS.sv.r.str) }, - { 'r', "Request.font", 'N', &(SS.sv.r.font) }, + { 'r', "Request.str", 'S', &(SS.sv.r.str) }, + { 'r', "Request.font", 'S', &(SS.sv.r.font) }, { 'e', "Entity.h.v", 'x', &(SS.sv.e.h.v) }, { 'e', "Entity.type", 'd', &(SS.sv.e.type) }, { 'e', "Entity.construction", 'b', &(SS.sv.e.construction) }, { 'e', "Entity.style", 'x', &(SS.sv.e.style) }, - { 'e', "Entity.str", 'N', &(SS.sv.e.str) }, - { 'e', "Entity.font", 'N', &(SS.sv.e.font) }, + { 'e', "Entity.str", 'S', &(SS.sv.e.str) }, + { 'e', "Entity.font", 'S', &(SS.sv.e.font) }, { 'e', "Entity.point[0].v", 'x', &(SS.sv.e.point[0].v) }, { 'e', "Entity.point[1].v", 'x', &(SS.sv.e.point[1].v) }, { 'e', "Entity.point[2].v", 'x', &(SS.sv.e.point[2].v) }, @@ -175,14 +175,14 @@ const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = { { 'c', "Constraint.other", 'b', &(SS.sv.c.other) }, { 'c', "Constraint.other2", 'b', &(SS.sv.c.other2) }, { 'c', "Constraint.reference", 'b', &(SS.sv.c.reference) }, - { 'c', "Constraint.comment", 'N', &(SS.sv.c.comment) }, + { 'c', "Constraint.comment", 'S', &(SS.sv.c.comment) }, { 'c', "Constraint.disp.offset.x", 'f', &(SS.sv.c.disp.offset.x) }, { 'c', "Constraint.disp.offset.y", 'f', &(SS.sv.c.disp.offset.y) }, { 'c', "Constraint.disp.offset.z", 'f', &(SS.sv.c.disp.offset.z) }, { 'c', "Constraint.disp.style", 'x', &(SS.sv.c.disp.style) }, { 's', "Style.h.v", 'x', &(SS.sv.s.h.v) }, - { 's', "Style.name", 'N', &(SS.sv.s.name) }, + { 's', "Style.name", 'S', &(SS.sv.s.name) }, { 's', "Style.width", 'f', &(SS.sv.s.width) }, { 's', "Style.widthAs", 'd', &(SS.sv.s.widthAs) }, { 's', "Style.textHeight", 'f', &(SS.sv.s.textHeight) }, @@ -200,8 +200,7 @@ const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = { union SAVEDptr { IdList M; - NameStr N; - /* std::string P */ + /* std::string S; */ bool b; RgbaColor c; int d; @@ -217,15 +216,14 @@ void SolveSpaceUI::SaveUsingTable(int type) { int fmt = SAVED[i].fmt; union SAVEDptr *p = (union SAVEDptr *)SAVED[i].ptr; // Any items that aren't specified are assumed to be zero - if(fmt == 'N' && p->N.str[0] == '\0') continue; + if(fmt == 'S' && ((std::string*)p)->empty()) continue; if(fmt == 'd' && p->d == 0) continue; if(fmt == 'f' && EXACT(p->f == 0.0)) continue; if(fmt == 'x' && p->x == 0) continue; fprintf(fh, "%s=", SAVED[i].desc); switch(fmt) { - case 'N': fprintf(fh, "%s", p->N.str); break; - case 'P': fprintf(fh, "%s", ((std::string*)p)->c_str()); break; + case 'S': fprintf(fh, "%s", ((std::string*)p)->c_str()); break; case 'b': fprintf(fh, "%d", p->b ? 1 : 0); break; case 'c': fprintf(fh, "%08x", p->c.ToPackedInt()); break; case 'd': fprintf(fh, "%d", p->d); break; @@ -373,7 +371,7 @@ void SolveSpaceUI::LoadUsingTable(char *key, char *val) { union SAVEDptr *p = (union SAVEDptr *)SAVED[i].ptr; unsigned int u = 0; switch(SAVED[i].fmt) { - case 'N': p->N.strcpy(val); break; + case 'S': (*(std::string*)p) = val; break; case 'b': p->b = (atoi(val) != 0); break; case 'd': p->d = atoi(val); break; case 'f': p->f = atof(val); break; diff --git a/src/group.cpp b/src/group.cpp index 68420571..6333696b 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -66,12 +66,12 @@ void Group::MenuGroup(int id) { switch(id) { case GraphicsWindow::MNU_GROUP_3D: g.type = DRAWING_3D; - g.name.strcpy("sketch-in-3d"); + g.name = "sketch-in-3d"; break; case GraphicsWindow::MNU_GROUP_WRKPL: g.type = DRAWING_WORKPLANE; - g.name.strcpy("sketch-in-plane"); + g.name = "sketch-in-plane"; if(gs.points == 1 && gs.n == 1) { g.subtype = WORKPLANE_BY_POINT_ORTHO; @@ -122,7 +122,7 @@ void Group::MenuGroup(int id) { g.opA = SS.GW.activeGroup; g.predef.entityB = SS.GW.ActiveWorkplane(); g.subtype = ONE_SIDED; - g.name.strcpy("extrude"); + g.name = "extrude"; break; case GraphicsWindow::MNU_GROUP_LATHE: @@ -144,7 +144,7 @@ void Group::MenuGroup(int id) { } g.type = LATHE; g.opA = SS.GW.activeGroup; - g.name.strcpy("lathe"); + g.name = "lathe"; break; case GraphicsWindow::MNU_GROUP_ROT: { @@ -170,7 +170,7 @@ void Group::MenuGroup(int id) { g.opA = SS.GW.activeGroup; g.valA = 3; g.subtype = ONE_SIDED; - g.name.strcpy("rotate"); + g.name = "rotate"; break; } @@ -181,7 +181,7 @@ void Group::MenuGroup(int id) { g.subtype = ONE_SIDED; g.predef.entityB = SS.GW.ActiveWorkplane(); g.activeWorkplane = SS.GW.ActiveWorkplane(); - g.name.strcpy("translate"); + g.name = "translate"; break; case GraphicsWindow::MNU_GROUP_IMPORT: { @@ -212,9 +212,9 @@ void Group::MenuGroup(int id) { } if(groupName.length() > 0) { - g.name.strcpy(groupName.substr(0, 64).c_str()); + g.name = groupName; } else { - g.name.strcpy("import"); + g.name = "import"; } g.meshCombine = COMBINE_AS_ASSEMBLE; @@ -274,14 +274,12 @@ void Group::TransformImportedBy(Vector t, Quaternion q) { SK.GetParam(qz)->val = qg.vz; } -char *Group::DescriptionString(void) { - static char ret[100]; - if(name.str[0]) { - sprintf(ret, "g%03x-%s", h.v, name.str); +std::string Group::DescriptionString(void) { + if(name.empty()) { + return ssprintf("g%03x-(unnamed)", h.v); } else { - sprintf(ret, "g%03x-(unnamed)", h.v); + return ssprintf("g%03x-%s", h.v, name.c_str()); } - return ret; } void Group::Activate(void) { @@ -636,8 +634,8 @@ void Group::CopyEntity(IdList *el, en.group = h; en.construction = ep->construction; en.style = ep->style; - en.str.strcpy(ep->str.str); - en.font.strcpy(ep->font.str); + en.str = ep->str; + en.font = ep->font; switch(ep->type) { case Entity::WORKPLANE: diff --git a/src/gtk/gtkmain.cpp b/src/gtk/gtkmain.cpp index 56d40a78..f119ec71 100644 --- a/src/gtk/gtkmain.cpp +++ b/src/gtk/gtkmain.cpp @@ -387,7 +387,7 @@ public: connect(sigc::mem_fun(this, &EditorOverlay::on_activate)); } - void start_editing(int x, int y, const char *val) { + void start_editing(int x, int y, const std::string &val) { move(_entry, x, y - 4); _entry.set_text(val); if(!_entry.is_visible()) { @@ -720,7 +720,7 @@ bool FullScreenIsActive(void) { return GW->is_fullscreen(); } -void ShowGraphicsEditControl(int x, int y, char *val) { +void ShowGraphicsEditControl(int x, int y, const std::string &val) { Gdk::Rectangle rect = GW->get_widget().get_allocation(); // Convert to ij (vs. xy) style coordinates, @@ -1378,7 +1378,7 @@ void SetMousePointerToHand(bool is_hand) { TW->get_widget().set_cursor_hand(is_hand); } -void ShowTextEditControl(int x, int y, char *val) { +void ShowTextEditControl(int x, int y, const std::string &val) { TW->get_overlay().start_editing(x, y, val); } diff --git a/src/mouse.cpp b/src/mouse.cpp index e9faf516..240caf1b 100644 --- a/src/mouse.cpp +++ b/src/mouse.cpp @@ -476,7 +476,7 @@ void GraphicsWindow::ContextMenuListStyles(void) { for(s = SK.style.First(); s; s = SK.style.NextAfter(s)) { if(s->h.v < Style::FIRST_CUSTOM) continue; - AddContextMenuItem(s->DescriptionString(), CMNU_FIRST_STYLE + s->h.v); + AddContextMenuItem(s->DescriptionString().c_str(), CMNU_FIRST_STYLE + s->h.v); empty = false; } @@ -933,8 +933,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) { } hr = AddRequest(Request::TTF_TEXT); Request *r = SK.GetRequest(hr); - r->str.strcpy("Abc"); - r->font.strcpy("arial.ttf"); + r->str = "Abc"; + r->font = "arial.ttf"; SK.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(2))->PointForceTo(v); @@ -952,7 +952,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) { c.workplane = SS.GW.ActiveWorkplane(); c.type = Constraint::COMMENT; c.disp.offset = v; - c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT"); + c.comment = "NEW COMMENT -- DOUBLE-CLICK TO EDIT"; Constraint::AddConstraint(&c); break; } @@ -1145,16 +1145,16 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) { Vector p3 = c->GetLabelPos(); Point2d p2 = ProjectPoint(p3); - char s[1024]; + std::string edit_value; switch(c->type) { case Constraint::COMMENT: - strcpy(s, c->comment.str); + edit_value = c->comment; break; case Constraint::ANGLE: case Constraint::LENGTH_RATIO: case Constraint::LENGTH_DIFFERENCE: - sprintf(s, "%.3f", c->valA); + edit_value = ssprintf("%.3f", c->valA); break; default: { @@ -1164,26 +1164,26 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) { if(c->type == Constraint::DIAMETER && c->other) v /= 2; - char *def = SS.MmToString(v); + std::string def = SS.MmToString(v); double eps = 1e-12; if(fabs(SS.StringToMm(def) - v) < eps) { // Show value with default number of digits after decimal, // which is at least enough to represent it exactly. - strcpy(s, def); + edit_value = def; } else { // Show value with as many digits after decimal as // required to represent it exactly, up to 10. v /= SS.MmPerUnit(); int i; for(i = 0; i <= 10; i++) { - sprintf(s, "%.*f", i, v); - if(fabs(atof(s) - v) < eps) break; + edit_value = ssprintf("%.*f", i, v); + if(fabs(std::stod(edit_value) - v) < eps) break; } } break; } } - ShowGraphicsEditControl((int)p2.x, (int)p2.y-4, s); + ShowGraphicsEditControl((int)p2.x, (int)p2.y-4, edit_value); } } @@ -1193,7 +1193,7 @@ void GraphicsWindow::EditControlDone(const char *s) { if(c->type == Constraint::COMMENT) { SS.UndoRemember(); - c->comment.strcpy(s); + c->comment = s; return; } diff --git a/src/request.cpp b/src/request.cpp index 15297ca3..2da6eafb 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -102,8 +102,8 @@ void Request::Generate(IdList *entity, e.style = style; e.workplane = workplane; e.construction = construction; - e.str.strcpy(str.str); - e.font.strcpy(font.str); + e.str = str; + e.font = font; e.h = h.entity(0); // And generate entities for the points @@ -169,7 +169,7 @@ void Request::Generate(IdList *entity, if(et) entity->Add(&e); } -char *Request::DescriptionString(void) { +std::string Request::DescriptionString(void) { const char *s; if(h.v == Request::HREQUEST_REFERENCE_XY.v) { s = "#XY"; @@ -180,9 +180,8 @@ char *Request::DescriptionString(void) { } else { s = EntReqTable::DescriptionForRequest(type); } - static char ret[100]; - sprintf(ret, "r%03x-%s", h.v, s); - return ret; + + return ssprintf("r%03x-%s", h.v, s); } hParam Request::AddParam(IdList *param, hParam hp) { diff --git a/src/sketch.h b/src/sketch.h index c61bdbf0..b86200b2 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -195,11 +195,11 @@ public: SShell impShell; EntityList impEntity; - NameStr name; + std::string name; void Activate(void); - char *DescriptionString(void); + std::string DescriptionString(void); void Clear(void); static void AddParam(ParamList *param, hParam hp, double v); @@ -284,13 +284,13 @@ public: hStyle style; bool construction; - NameStr str; - NameStr font; + std::string str; + std::string font; static hParam AddParam(ParamList *param, hParam hp); void Generate(EntityList *entity, ParamList *param); - char *DescriptionString(void); + std::string DescriptionString(void); void Clear(void) {} }; @@ -357,8 +357,8 @@ public: Quaternion numNormal; double numDistance; - NameStr str; - NameStr font; + std::string str; + std::string font; // For entities that are derived by a transformation, the number of // times to apply the transformation. @@ -491,7 +491,7 @@ public: void CalculateNumerical(bool forExport); - char *DescriptionString(void); + std::string DescriptionString(void); }; class EntReqTable { @@ -606,7 +606,7 @@ public: bool other2; bool reference; // a ref dimension, that generates no eqs - NameStr comment; // since comments are represented as constraints + std::string comment; // since comments are represented as constraints bool HasLabel(void); @@ -654,7 +654,7 @@ public: void LineDrawOrGetDistance(Vector a, Vector b); void DrawOrGetDistance(Vector *labelPos); double EllipticalInterpolation(double rx, double ry, double theta); - char *Label(void); + std::string Label(void); void DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db, Vector offset, Vector *ref); void DoLineWithArrows(Vector ref, Vector a, Vector b, bool onlyOneExt); @@ -665,7 +665,7 @@ public: void DoEqualLenTicks(Vector a, Vector b, Vector gn); void DoEqualRadiusTicks(hEntity he); - char *DescriptionString(void); + std::string DescriptionString(void); static void AddConstraint(Constraint *c, bool rememberForUndo); static void AddConstraint(Constraint *c); @@ -726,7 +726,7 @@ public: FIRST_CUSTOM = 0x100 }; - NameStr name; + std::string name; enum { UNITS_AS_PIXELS = 0, @@ -760,9 +760,9 @@ public: } Default; static const Default Defaults[]; - static char *CnfColor(const char *prefix); - static char *CnfWidth(const char *prefix); - static char *CnfPrefixToName(const char *prefix); + static std::string CnfColor(const std::string &prefix); + static std::string CnfWidth(const std::string &prefix); + static std::string CnfPrefixToName(const std::string &prefix); static void CreateAllDefaultStyles(void); static void CreateDefaultStyle(hStyle h); @@ -785,7 +785,7 @@ public: static bool Exportable(int hs); static hStyle ForEntity(hEntity he); - char *DescriptionString(void); + std::string DescriptionString(void); void Clear(void) {} }; @@ -836,8 +836,8 @@ public: int type; int extraPoints; hStyle style; - NameStr str; - NameStr font; + std::string str; + std::string font; bool construction; Vector point[MAX_POINTS_IN_ENTITY]; diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 90f889ae..56597b1b 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -242,26 +242,18 @@ const char *SolveSpaceUI::UnitName(void) { return "mm"; } } -char *SolveSpaceUI::MmToString(double v) { - static int WhichBuf; - static char Bufs[8][128]; - - WhichBuf++; - if(WhichBuf >= 8 || WhichBuf < 0) WhichBuf = 0; - - char *s = Bufs[WhichBuf]; +std::string SolveSpaceUI::MmToString(double v) { if(viewUnits == UNIT_INCHES) { - sprintf(s, "%.*f", afterDecimalInch, v/25.4); + return ssprintf("%.*f", afterDecimalInch, v/25.4); } else { - sprintf(s, "%.*f", afterDecimalMm, v); + return ssprintf("%.*f", afterDecimalMm, v); } - return s; } double SolveSpaceUI::ExprToMm(Expr *e) { return (e->Eval()) * MmPerUnit(); } -double SolveSpaceUI::StringToMm(const char *str) { - return atof(str) * MmPerUnit(); +double SolveSpaceUI::StringToMm(const std::string &str) { + return std::stod(str) * MmPerUnit(); } double SolveSpaceUI::ChordTolMm(void) { return SS.chordTol / SS.GW.scale; diff --git a/src/solvespace.h b/src/solvespace.h index 3dcd3b58..03d21de8 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -65,6 +65,11 @@ using std::min; using std::max; using std::swap; +#if defined(__GNUC__) +__attribute__((__format__ (__printf__, 1, 2))) +#endif +std::string ssprintf(const char *fmt, ...); + inline int WRAP(int v, int n) { // Clamp it to the range [0, n) while(v >= n) v -= n; @@ -220,10 +225,10 @@ void CheckMenuById(int id, bool checked); void RadioMenuById(int id, bool selected); void EnableMenuById(int id, bool enabled); -void ShowGraphicsEditControl(int x, int y, char *s); +void ShowGraphicsEditControl(int x, int y, const std::string &str); void HideGraphicsEditControl(void); bool GraphicsEditControlIsVisible(void); -void ShowTextEditControl(int x, int y, char *s); +void ShowTextEditControl(int x, int y, const std::string &str); void HideTextEditControl(void); bool TextEditControlIsVisible(void); void MoveTextScrollbarTo(int pos, int maxPos, int page); @@ -462,7 +467,7 @@ public: } IntPoint; std::string fontFile; - NameStr name; + std::string name; bool loaded; // The font itself, plus the mapping from ASCII codes to glyphs @@ -502,7 +507,7 @@ public: void Flush(void); void Handle(int *dx, int x, int y, bool onCurve); void PlotCharacter(int *dx, int c, double spacing); - void PlotString(char *str, double spacing, + void PlotString(const char *str, double spacing, SBezierList *sbl, Vector origin, Vector u, Vector v); Vector TransformIntPoint(int x, int y); @@ -517,7 +522,7 @@ public: void LoadAll(void); - void PlotString(const std::string &font, char *str, double spacing, + void PlotString(const std::string &font, const char *str, double spacing, SBezierList *sbl, Vector origin, Vector u, Vector v); }; @@ -785,9 +790,9 @@ public: int afterDecimalInch; int autosaveInterval; // in minutes - char *MmToString(double v); + std::string MmToString(double v); double ExprToMm(Expr *e); - double StringToMm(const char *s); + double StringToMm(const std::string &s); const char *UnitName(void); double MmPerUnit(void); int UnitDigitsAfterDecimal(void); diff --git a/src/style.cpp b/src/style.cpp index a6eaf013..d5130038 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -25,30 +25,22 @@ const Style::Default Style::Defaults[] = { { { 0 }, NULL, RGBf(0.0, 0.0, 0.0), 0.0 } }; -char *Style::CnfColor(const char *prefix) { - static char name[100]; - sprintf(name, "Style_%s_Color", prefix); - return name; +std::string Style::CnfColor(const std::string &prefix) { + return "Style_" + prefix + "_Color"; } -char *Style::CnfWidth(const char *prefix) { - static char name[100]; - sprintf(name, "Style_%s_Width", prefix); - return name; +std::string Style::CnfWidth(const std::string &prefix) { + return "Style_" + prefix + "_Width"; } -char *Style::CnfPrefixToName(const char *prefix) { - static char name[100]; - int i = 0, j; - strcpy(name, "#def-"); - j = 5; - while(prefix[i] && j < 90) { - if(isupper(prefix[i]) && i != 0) { - name[j++] = '-'; - } - name[j++] = (char)tolower(prefix[i]); - i++; +std::string Style::CnfPrefixToName(const std::string &prefix) { + std::string name = "#def-"; + + for(int i = 0; i < prefix.length(); i++) { + if(isupper(prefix[i]) && i != 0) + name += '-'; + name += tolower(prefix[i]); } - name[j++] = '\0'; + return name; } @@ -86,9 +78,9 @@ void Style::CreateDefaultStyle(hStyle h) { ns.fillColor = RGBf(0.3, 0.3, 0.3); ns.h = h; if(isDefaultStyle) { - ns.name.strcpy(CnfPrefixToName(d->cnfPrefix)); + ns.name = CnfPrefixToName(d->cnfPrefix); } else { - ns.name.strcpy("new-custom-style"); + ns.name = "new-custom-style"; } SK.style.Add(&ns); @@ -110,7 +102,7 @@ void Style::LoadFactoryDefaults(void) { s->exportable = true; s->filled = false; s->fillColor = RGBf(0.3, 0.3, 0.3); - s->name.strcpy(CnfPrefixToName(d->cnfPrefix)); + s->name = CnfPrefixToName(d->cnfPrefix); } SS.backgroundColor = RGBi(0, 0, 0); if(SS.bgImage.fromFile) MemFree(SS.bgImage.fromFile); @@ -319,14 +311,12 @@ hStyle Style::ForEntity(hEntity he) { return hs; } -char *Style::DescriptionString(void) { - static char ret[100]; - if(name.str[0]) { - sprintf(ret, "s%03x-%s", h.v, name.str); +std::string Style::DescriptionString(void) { + if(name.empty()) { + return ssprintf("s%03x-(unnamed)", h.v); } else { - sprintf(ret, "s%03x-(unnamed)", h.v); + return ssprintf("s%03x-%s", h.v, name.c_str()); } - return ret; } @@ -444,7 +434,7 @@ void TextWindow::ShowListOfStyles(void) { &s->color, darkbg ? 'd' : 'a', ScreenShowStyleInfo, s->h.v, - s->DescriptionString()); + s->DescriptionString().c_str()); darkbg = !darkbg; } @@ -488,7 +478,7 @@ void TextWindow::ShowListOfStyles(void) { void TextWindow::ScreenChangeStyleName(int link, uint32_t v) { hStyle hs = { v }; Style *s = Style::Get(hs); - SS.TW.ShowEditControl(10, 12, s->name.str); + SS.TW.ShowEditControl(10, 12, s->name.c_str()); SS.TW.edit.style = hs; SS.TW.edit.meaning = EDIT_STYLE_NAME; } @@ -512,11 +502,11 @@ void TextWindow::ScreenChangeStyleWidthOrTextHeight(int link, uint32_t v) { double val = (link == 't') ? s->textHeight : s->width; int units = (link == 't') ? s->textHeightAs : s->widthAs; - char str[300]; + std::string edit_value; if(units == Style::UNITS_AS_PIXELS) { - sprintf(str, "%.2f", val); + edit_value = ssprintf("%.2f", val); } else { - strcpy(str, SS.MmToString(val)); + edit_value = SS.MmToString(val); } int row = 0, col = 9; if(link == 'w') { @@ -527,7 +517,7 @@ void TextWindow::ScreenChangeStyleWidthOrTextHeight(int link, uint32_t v) { row = 33; // text height (for custom styles only) col++; } - SS.TW.ShowEditControl(row, col, str); + SS.TW.ShowEditControl(row, col, edit_value); SS.TW.edit.style = hs; SS.TW.edit.meaning = (link == 't') ? EDIT_STYLE_TEXT_HEIGHT : EDIT_STYLE_WIDTH; @@ -536,9 +526,7 @@ void TextWindow::ScreenChangeStyleWidthOrTextHeight(int link, uint32_t v) { void TextWindow::ScreenChangeStyleTextAngle(int link, uint32_t v) { hStyle hs = { v }; Style *s = Style::Get(hs); - char str[300]; - sprintf(str, "%.2f", s->textAngle); - SS.TW.ShowEditControl(37, 9, str); + SS.TW.ShowEditControl(37, 9, ssprintf("%.2f", s->textAngle)); SS.TW.edit.style = hs; SS.TW.edit.meaning = EDIT_STYLE_TEXT_ANGLE; } @@ -700,7 +688,7 @@ bool TextWindow::EditControlDoneForStyles(const char *str) { } else { SS.UndoRemember(); s = Style::Get(edit.style); - s->name.strcpy(str); + s->name = str; } break; @@ -727,11 +715,11 @@ void TextWindow::ShowStyleInfo(void) { Style *s = Style::Get(shown.style); if(s->h.v < Style::FIRST_CUSTOM) { - Printf(true, "%FtSTYLE %E%s ", s->DescriptionString()); + Printf(true, "%FtSTYLE %E%s ", s->DescriptionString().c_str()); } else { Printf(true, "%FtSTYLE %E%s " "[%Fl%Ll%D%frename%E/%Fl%Ll%D%fdel%E]", - s->DescriptionString(), + s->DescriptionString().c_str(), s->h.v, &ScreenChangeStyleName, s->h.v, &ScreenDeleteStyle); } @@ -750,7 +738,7 @@ void TextWindow::ShowStyleInfo(void) { (s->h.v < Style::FIRST_CUSTOM) ? 'w' : 'W'); } else { Printf(false, " %Ftwidth%E %s %D%f%Lp%Fl[change]%E", - SS.MmToString(s->width), + SS.MmToString(s->width).c_str(), s->h.v, &ScreenChangeStyleWidthOrTextHeight, (s->h.v < Style::FIRST_CUSTOM) ? 'w' : 'W'); } @@ -797,7 +785,7 @@ void TextWindow::ShowStyleInfo(void) { chng); } else { Printf(false, "%Ba %Ftheight %E%s %D%f%Lt%Fl%s%E", - SS.MmToString(s->textHeight), + SS.MmToString(s->textHeight).c_str(), s->h.v, &ScreenChangeStyleWidthOrTextHeight, chng); } diff --git a/src/textscreens.cpp b/src/textscreens.cpp index c8b320c4..fe46cacd 100644 --- a/src/textscreens.cpp +++ b/src/textscreens.cpp @@ -16,21 +16,22 @@ void TextWindow::ScreenHome(int link, uint32_t v) { void TextWindow::ShowHeader(bool withNav) { ClearScreen(); - char cd[1024], cd2[1024]; + const char *header; + std::string desc; if(SS.GW.LockedInWorkplane()) { - sprintf(cd, "in plane: "); - strcpy(cd2, SK.GetEntity(SS.GW.ActiveWorkplane())->DescriptionString()); + header = "in plane: "; + desc = SK.GetEntity(SS.GW.ActiveWorkplane())->DescriptionString(); } else { - sprintf(cd, "drawing / constraining in 3d"); - strcpy(cd2, ""); + header = "drawing / constraining in 3d"; + desc = ""; } // Navigation buttons if(withNav) { Printf(false, " %Fl%Lh%fhome%E %Ft%s%E%s", - (&TextWindow::ScreenHome), cd, cd2); + (&TextWindow::ScreenHome), header, desc.c_str()); } else { - Printf(false, " %Ft%s%E%s", cd, cd2); + Printf(false, " %Ft%s%E%s", header, desc.c_str()); } // Leave space for the icons that are painted here. @@ -108,7 +109,7 @@ void TextWindow::ShowListOfGroups(void) { bool afterActive = false; for(i = 0; i < SK.group.n; i++) { Group *g = &(SK.group.elem[i]); - char *s = g->DescriptionString(); + std::string s = g->DescriptionString(); bool active = (g->h.v == SS.GW.activeGroup.v); bool shown = g->visible; bool ok = (g->solved.how == System::SOLVED_OKAY); @@ -133,7 +134,7 @@ void TextWindow::ShowListOfGroups(void) { ok ? "ok" : "", ok ? "" : "NO", // Link to a screen that gives more details on the group - g->h.v, (&TextWindow::ScreenSelectGroup), s); + g->h.v, (&TextWindow::ScreenSelectGroup), s.c_str()); if(active) afterActive = true; } @@ -246,16 +247,14 @@ void TextWindow::ScreenChangeExprA(int link, uint32_t v) { } void TextWindow::ScreenChangeGroupName(int link, uint32_t v) { Group *g = SK.GetGroup(SS.TW.shown.group); - SS.TW.ShowEditControl(7, 12, g->DescriptionString()+5); + SS.TW.ShowEditControl(7, 12, g->DescriptionString().substr(5)); SS.TW.edit.meaning = EDIT_GROUP_NAME; SS.TW.edit.group.v = v; } void TextWindow::ScreenChangeGroupScale(int link, uint32_t v) { Group *g = SK.GetGroup(SS.TW.shown.group); - char str[1024]; - sprintf(str, "%.3f", g->scale); - SS.TW.ShowEditControl(14, 13, str); + SS.TW.ShowEditControl(14, 13, ssprintf("%.3f", g->scale)); SS.TW.edit.meaning = EDIT_GROUP_SCALE; SS.TW.edit.group.v = v; } @@ -279,11 +278,11 @@ void TextWindow::ShowGroupInfo(void) { const char *s = "???"; if(shown.group.v == Group::HGROUP_REFERENCES.v) { - Printf(true, "%FtGROUP %E%s", g->DescriptionString()); + Printf(true, "%FtGROUP %E%s", g->DescriptionString().c_str()); goto list_items; } else { Printf(true, "%FtGROUP %E%s [%Fl%Ll%D%frename%E/%Fl%Ll%D%fdel%E]", - g->DescriptionString(), + g->DescriptionString().c_str(), g->h.v, &TextWindow::ScreenChangeGroupName, g->h.v, &TextWindow::ScreenDeleteGroup); } @@ -426,11 +425,11 @@ list_items: Request *r = &(SK.request.elem[i]); if(r->group.v == shown.group.v) { - char *s = r->DescriptionString(); + std::string s = r->DescriptionString(); Printf(false, "%Bp %Fl%Ll%D%f%h%s%E", (a & 1) ? 'd' : 'a', r->h.v, (&TextWindow::ScreenSelectRequest), - &(TextWindow::ScreenHoverRequest), s); + &(TextWindow::ScreenHoverRequest), s.c_str()); a++; } } @@ -443,11 +442,11 @@ list_items: Constraint *c = &(SK.constraint.elem[i]); if(c->group.v == shown.group.v) { - char *s = c->DescriptionString(); + std::string s = c->DescriptionString(); Printf(false, "%Bp %Fl%Ll%D%f%h%s%E %s", (a & 1) ? 'd' : 'a', c->h.v, (&TextWindow::ScreenSelectConstraint), - (&TextWindow::ScreenHoverConstraint), s, + (&TextWindow::ScreenHoverConstraint), s.c_str(), c->reference ? "(ref)" : ""); a++; } @@ -469,7 +468,7 @@ void TextWindow::ShowGroupSolveInfo(void) { return; } - Printf(true, "%FtGROUP %E%s", g->DescriptionString()); + Printf(true, "%FtGROUP %E%s", g->DescriptionString().c_str()); switch(g->solved.how) { case System::DIDNT_CONVERGE: Printf(true, "%FxSOLVE FAILED!%Fd no convergence"); @@ -495,7 +494,7 @@ void TextWindow::ShowGroupSolveInfo(void) { (i & 1) ? 'd' : 'a', c->h.v, (&TextWindow::ScreenSelectConstraint), (&TextWindow::ScreenHoverConstraint), - c->DescriptionString()); + c->DescriptionString().c_str()); } Printf(true, "It may be possible to fix the problem "); @@ -509,19 +508,17 @@ void TextWindow::ShowGroupSolveInfo(void) { //----------------------------------------------------------------------------- void TextWindow::ScreenStepDimFinish(int link, uint32_t v) { SS.TW.edit.meaning = EDIT_STEP_DIM_FINISH; - char s[1024]; + std::string edit_value; if(SS.TW.shown.dimIsDistance) { - strcpy(s, SS.MmToString(SS.TW.shown.dimFinish)); + edit_value = SS.MmToString(SS.TW.shown.dimFinish); } else { - sprintf(s, "%.3f", SS.TW.shown.dimFinish); + edit_value = ssprintf("%.3f", SS.TW.shown.dimFinish); } - SS.TW.ShowEditControl(12, 12, s); + SS.TW.ShowEditControl(12, 12, edit_value); } void TextWindow::ScreenStepDimSteps(int link, uint32_t v) { - char str[1024]; - sprintf(str, "%d", SS.TW.shown.dimSteps); SS.TW.edit.meaning = EDIT_STEP_DIM_STEPS; - SS.TW.ShowEditControl(14, 12, str); + SS.TW.ShowEditControl(14, 12, ssprintf("%d", SS.TW.shown.dimSteps)); } void TextWindow::ScreenStepDimGo(int link, uint32_t v) { hConstraint hc = SS.TW.shown.constraint; @@ -553,12 +550,12 @@ void TextWindow::ShowStepDimension(void) { return; } - Printf(true, "%FtSTEP DIMENSION%E %s", c->DescriptionString()); + Printf(true, "%FtSTEP DIMENSION%E %s", c->DescriptionString().c_str()); if(shown.dimIsDistance) { - Printf(true, "%Ba %Ftstart%E %s", SS.MmToString(c->valA)); + Printf(true, "%Ba %Ftstart%E %s", SS.MmToString(c->valA).c_str()); Printf(false, "%Bd %Ftfinish%E %s %Fl%Ll%f[change]%E", - SS.MmToString(shown.dimFinish), &ScreenStepDimFinish); + SS.MmToString(shown.dimFinish).c_str(), &ScreenStepDimFinish); } else { Printf(true, "%Ba %Ftstart%E %@", c->valA); Printf(false, "%Bd %Ftfinish%E %@ %Fl%Ll%f[change]%E", @@ -580,10 +577,8 @@ void TextWindow::ShowStepDimension(void) { void TextWindow::ScreenChangeTangentArc(int link, uint32_t v) { switch(link) { case 'r': { - char str[1024]; - strcpy(str, SS.MmToString(SS.tangentArcRadius)); SS.TW.edit.meaning = EDIT_TANGENT_ARC_RADIUS; - SS.TW.ShowEditControl(12, 3, str); + SS.TW.ShowEditControl(12, 3, SS.MmToString(SS.tangentArcRadius)); break; } @@ -597,7 +592,7 @@ void TextWindow::ShowTangentArc(void) { Printf(true, "%Ft radius of created arc%E"); if(SS.tangentArcManual) { Printf(false, "%Ba %s %Fl%Lr%f[change]%E", - SS.MmToString(SS.tangentArcRadius), + SS.MmToString(SS.tangentArcRadius).c_str(), &(TextWindow::ScreenChangeTangentArc)); } else { Printf(false, "%Ba automatic"); @@ -671,7 +666,7 @@ void TextWindow::EditControlDone(const char *s) { SS.UndoRemember(); Group *g = SK.GetGroup(edit.group); - g->name.strcpy(s); + g->name = s; } break; } @@ -727,7 +722,7 @@ void TextWindow::EditControlDone(const char *s) { SS.UndoRemember(); Request *r = SK.request.FindByIdNoOops(edit.request); if(r) { - r->str.strcpy(s); + r->str = s; SS.MarkGroupDirty(r->group); SS.ScheduleGenerateAll(); } diff --git a/src/textwin.cpp b/src/textwin.cpp index b4a7c907..e20d2331 100644 --- a/src/textwin.cpp +++ b/src/textwin.cpp @@ -79,14 +79,14 @@ void TextWindow::HideEditControl(void) { HideTextEditControl(); } -void TextWindow::ShowEditControl(int halfRow, int col, char *s) { +void TextWindow::ShowEditControl(int halfRow, int col, const std::string &str) { editControl.halfRow = halfRow; editControl.col = col; int x = LEFT_MARGIN + CHAR_WIDTH*col; int y = (halfRow - SS.TW.scrollPos)*(LINE_HEIGHT/2); - ShowTextEditControl(x - 3, y + 2, s); + ShowTextEditControl(x - 3, y + 2, str); } void TextWindow::ShowEditControlWithColorPicker(int halfRow, int col, RgbaColor rgb) diff --git a/src/ttf.cpp b/src/ttf.cpp index 129f7d17..4a7e0e25 100644 --- a/src/ttf.cpp +++ b/src/ttf.cpp @@ -26,7 +26,7 @@ void TtfFontList::LoadAll(void) { loaded = true; } -void TtfFontList::PlotString(const std::string &font, char *str, double spacing, +void TtfFontList::PlotString(const std::string &font, const char *str, double spacing, SBezierList *sbl, Vector origin, Vector u, Vector v) { @@ -350,14 +350,11 @@ bool TtfFont::LoadFontFromFile(bool nameOnly) { if(nameOnly) { // Find the display name, and store it in the provided buffer. fseek(fh, nameAddr+nameStringOffset+displayNameOffset, SEEK_SET); - int c = 0; + name.clear(); for(i = 0; i < displayNameLength; i++) { - uint8_t b = GetBYTE(); - if(b && c < ((int)sizeof(name.str) - 2)) { - name.str[c++] = b; - } + char b = (char)GetBYTE(); + if(b) name += b; } - name.str[c++] = '\0'; fclose(fh); return true; @@ -673,7 +670,7 @@ void TtfFont::PlotCharacter(int *dx, int c, double spacing) { *dx = dx0 + g->advanceWidth + (int)(spacing + 0.5); } -void TtfFont::PlotString(char *str, double spacing, +void TtfFont::PlotString(const char *str, double spacing, SBezierList *sbl, Vector porigin, Vector pu, Vector pv) { diff --git a/src/ui.h b/src/ui.h index ed73f780..705a2e8d 100644 --- a/src/ui.h +++ b/src/ui.h @@ -208,7 +208,7 @@ public: } editControl; void HideEditControl(void); - void ShowEditControl(int halfRow, int col, char *s); + void ShowEditControl(int halfRow, int col, const std::string &str); void ShowEditControlWithColorPicker(int halfRow, int col, RgbaColor rgb); void ClearSuper(void); diff --git a/src/util.cpp b/src/util.cpp index 633b15bc..959026cb 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -6,6 +6,25 @@ //----------------------------------------------------------------------------- #include "solvespace.h" +std::string SolveSpace::ssprintf(const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + int size = vsnprintf(NULL, 0, fmt, va); + if(size < 0) oops(); + va_end(va); + + std::string result; + result.resize(size); + + va_start(va, fmt); + vsnprintf(&result[0], size + 1, fmt, va); + va_end(va); + + return result; +} + // See https://github.com/GNOME/glibmm/blob/2fbd9f23/glib/glibmm/ustring.cc#L227 const char *SolveSpace::ReadUTF8(const char *str, char32_t *result) { diff --git a/src/view.cpp b/src/view.cpp index ed2858c2..0ce5cd34 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -18,9 +18,9 @@ void TextWindow::ShowEditView(void) { Printf(false, "%Bd %Ftorigin (maps to center of screen)%E"); Printf(false, "%Ba (%s, %s, %s) %Fl%Ll%f[edit]%E", - SS.MmToString(-SS.GW.offset.x), - SS.MmToString(-SS.GW.offset.y), - SS.MmToString(-SS.GW.offset.z), + SS.MmToString(-SS.GW.offset.x).c_str(), + SS.MmToString(-SS.GW.offset.y).c_str(), + SS.MmToString(-SS.GW.offset.z).c_str(), &ScreenChangeViewOrigin); Printf(false, ""); @@ -38,29 +38,26 @@ void TextWindow::ShowEditView(void) { } void TextWindow::ScreenChangeViewScale(int link, uint32_t v) { - char buf[1024]; - sprintf(buf, "%.3f", SS.GW.scale * SS.MmPerUnit()); - SS.TW.edit.meaning = EDIT_VIEW_SCALE; - SS.TW.ShowEditControl(12, 3, buf); + SS.TW.ShowEditControl(12, 3, ssprintf("%.3f", SS.GW.scale * SS.MmPerUnit())); } void TextWindow::ScreenChangeViewOrigin(int link, uint32_t v) { - char buf[1024]; - sprintf(buf, "%s, %s, %s", - SS.MmToString(-SS.GW.offset.x), - SS.MmToString(-SS.GW.offset.y), - SS.MmToString(-SS.GW.offset.z)); + std::string edit_value = + ssprintf("%s, %s, %s", + SS.MmToString(-SS.GW.offset.x).c_str(), + SS.MmToString(-SS.GW.offset.y).c_str(), + SS.MmToString(-SS.GW.offset.z).c_str()); SS.TW.edit.meaning = EDIT_VIEW_ORIGIN; - SS.TW.ShowEditControl(18, 3, buf); + SS.TW.ShowEditControl(18, 3, edit_value); } void TextWindow::ScreenChangeViewProjection(int link, uint32_t v) { - char buf[1024]; - sprintf(buf, "%.3f, %.3f, %.3f", CO(SS.GW.projRight)); + std::string edit_value = + ssprintf("%.3f, %.3f, %.3f", CO(SS.GW.projRight)); SS.TW.edit.meaning = EDIT_VIEW_PROJ_RIGHT; - SS.TW.ShowEditControl(24, 10, buf); + SS.TW.ShowEditControl(24, 10, edit_value); } bool TextWindow::EditControlDoneForView(const char *s) { diff --git a/src/win32/w32main.cpp b/src/win32/w32main.cpp index fe9f64e3..702f5682 100644 --- a/src/win32/w32main.cpp +++ b/src/win32/w32main.cpp @@ -812,11 +812,11 @@ static void ShowEditControl(HWND h, int x, int y, const std::wstring &s) { SetFocus(h); } } -void SolveSpace::ShowTextEditControl(int x, int y, char *s) +void SolveSpace::ShowTextEditControl(int x, int y, const std::string &str) { if(GraphicsEditControlIsVisible()) return; - ShowEditControl(TextEditControl, x, y, Widen(s)); + ShowEditControl(TextEditControl, x, y, Widen(str)); } void SolveSpace::HideTextEditControl(void) { @@ -826,7 +826,7 @@ bool SolveSpace::TextEditControlIsVisible(void) { return IsWindowVisible(TextEditControl) ? true : false; } -void SolveSpace::ShowGraphicsEditControl(int x, int y, char *s) +void SolveSpace::ShowGraphicsEditControl(int x, int y, const std::string &str) { if(GraphicsEditControlIsVisible()) return; @@ -839,7 +839,7 @@ void SolveSpace::ShowGraphicsEditControl(int x, int y, char *s) // top left corner y -= 20; - ShowEditControl(GraphicsEditControl, x, y, Widen(s)); + ShowEditControl(GraphicsEditControl, x, y, Widen(str)); } void SolveSpace::HideGraphicsEditControl(void) {