| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 55baaf3 commit f324477
59 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -59,6 +59,7 @@ New measurement/analysis features: | |||
| 59 | 59 | ||
| 60 | 60 | Other new features: | |
| 61 | 61 | * New command-line interface, for batch exporting and more. | |
| 62 | + * The graphical interface now supports HiDPI screens on every OS. | ||
| 62 | 63 | * New link to match the on-screen size of the sketch with its actual size, | |
| 63 | 64 | "view → set to full scale". | |
| 64 | 65 | * When zooming to fit, constraints are also considered. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -118,7 +118,7 @@ endfunction() | |||
| 118 | 118 | # Second, register all resources. | |
| 119 | 119 | if(WIN32) | |
| 120 | 120 | add_resource(win32/icon.ico 4000 ICON) | |
| 121 | - add_resource(win32/manifest.xml 2 RT_MANIFEST) | ||
| 121 | + add_resource(win32/manifest.xml 1 RT_MANIFEST) | ||
| 122 | 122 | elseif(APPLE) | |
| 123 | 123 | add_iconset (cocoa/AppIcon.iconset) | |
| 124 | 124 | add_xib (cocoa/MainMenu.xib) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,17 +1,18 @@ | |||
| 1 | 1 | <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |
| 2 | - <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | ||
| 2 | + <assembly xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0"> | ||
| 3 | 3 | <assemblyIdentity | |
| 4 | 4 | version="1.0.0.0" | |
| 5 | 5 | processorArchitecture="*" | |
| 6 | 6 | name="JonathanWesthues.3dCAD.SolveSpace" | |
| 7 | 7 | type="win32" | |
| 8 | 8 | /> | |
| 9 | - <application xmlns="urn:schemas-microsoft-com:asm.v3"> | ||
| 10 | - <windowsSettings> | ||
| 11 | - <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> | ||
| 12 | - </windowsSettings> | ||
| 13 | - </application> | ||
| 14 | 9 | <description>Parametric 3d CAD tool.</description> | |
| 10 | + <asmv3:application> | ||
| 11 | + <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> | ||
| 12 | + <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness> | ||
| 13 | + <dpiAware>true</dpiAware> | ||
| 14 | + </asmv3:windowsSettings> | ||
| 15 | + </asmv3:application> | ||
| 15 | 16 | <dependency> | |
| 16 | 17 | <dependentAssembly> | |
| 17 | 18 | <assemblyIdentity | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -329,7 +329,7 @@ if(ENABLE_GUI) | |||
| 329 | 329 | ||
| 330 | 330 | if(MSVC) | |
| 331 | 331 | set_target_properties(solvespace PROPERTIES | |
| 332 | - LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /INCREMENTAL:NO /OPT:REF") | ||
| 332 | + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /INCREMENTAL:NO /OPT:REF /STACK:33554432") | ||
| 333 | 333 | endif() | |
| 334 | 334 | endif() | |
| 335 | 335 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -325,7 +325,7 @@ void GraphicsWindow::MenuClipboard(Command id) { | |||
| 325 | 325 | } | |
| 326 | 326 | } | |
| 327 | 327 | ||
| 328 | - bool TextWindow::EditControlDoneForPaste(const char *s) { | ||
| 328 | + bool TextWindow::EditControlDoneForPaste(const std::string &s) { | ||
| 329 | 329 | Expr *e; | |
| 330 | 330 | switch(edit.meaning) { | |
| 331 | 331 | case Edit::PASTE_TIMES_REPEATED: { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -80,28 +80,27 @@ void TextWindow::ScreenChangeFixExportColors(int link, uint32_t v) { | |||
| 80 | 80 | ||
| 81 | 81 | void TextWindow::ScreenChangeBackFaces(int link, uint32_t v) { | |
| 82 | 82 | SS.drawBackFaces = !SS.drawBackFaces; | |
| 83 | - SS.GW.persistentDirty = true; | ||
| 84 | - InvalidateGraphics(); | ||
| 83 | + SS.GW.Invalidate(/*clearPersistent=*/true); | ||
| 85 | 84 | } | |
| 86 | 85 | ||
| 87 | 86 | void TextWindow::ScreenChangeShowContourAreas(int link, uint32_t v) { | |
| 88 | 87 | SS.showContourAreas = !SS.showContourAreas; | |
| 89 | - InvalidateGraphics(); | ||
| 88 | + SS.GW.Invalidate(); | ||
| 90 | 89 | } | |
| 91 | 90 | ||
| 92 | 91 | void TextWindow::ScreenChangeCheckClosedContour(int link, uint32_t v) { | |
| 93 | 92 | SS.checkClosedContour = !SS.checkClosedContour; | |
| 94 | - InvalidateGraphics(); | ||
| 93 | + SS.GW.Invalidate(); | ||
| 95 | 94 | } | |
| 96 | 95 | ||
| 97 | 96 | void TextWindow::ScreenChangeShadedTriangles(int link, uint32_t v) { | |
| 98 | 97 | SS.exportShadedTriangles = !SS.exportShadedTriangles; | |
| 99 | - InvalidateGraphics(); | ||
| 98 | + SS.GW.Invalidate(); | ||
| 100 | 99 | } | |
| 101 | 100 | ||
| 102 | 101 | void TextWindow::ScreenChangePwlCurves(int link, uint32_t v) { | |
| 103 | 102 | SS.exportPwlCurves = !SS.exportPwlCurves; | |
| 104 | - InvalidateGraphics(); | ||
| 103 | + SS.GW.Invalidate(); | ||
| 105 | 104 | } | |
| 106 | 105 | ||
| 107 | 106 | void TextWindow::ScreenChangeCanvasSizeAuto(int link, uint32_t v) { | |
@@ -110,7 +109,7 @@ void TextWindow::ScreenChangeCanvasSizeAuto(int link, uint32_t v) { | |||
| 110 | 109 | } else { | |
| 111 | 110 | SS.exportCanvasSizeAuto = false; | |
| 112 | 111 | } | |
| 113 | - InvalidateGraphics(); | ||
| 112 | + SS.GW.Invalidate(); | ||
| 114 | 113 | } | |
| 115 | 114 | ||
| 116 | 115 | void TextWindow::ScreenChangeCanvasSize(int link, uint32_t v) { | |
@@ -321,26 +320,26 @@ void TextWindow::ShowConfiguration() { | |||
| 321 | 320 | } | |
| 322 | 321 | } | |
| 323 | 322 | ||
| 324 | - bool TextWindow::EditControlDoneForConfiguration(const char *s) { | ||
| 323 | + bool TextWindow::EditControlDoneForConfiguration(const std::string &s) { | ||
| 325 | 324 | switch(edit.meaning) { | |
| 326 | 325 | case Edit::LIGHT_INTENSITY: | |
| 327 | - SS.lightIntensity[edit.i] = min(1.0, max(0.0, atof(s))); | ||
| 328 | - InvalidateGraphics(); | ||
| 326 | + SS.lightIntensity[edit.i] = min(1.0, max(0.0, atof(s.c_str()))); | ||
| 327 | + SS.GW.Invalidate(); | ||
| 329 | 328 | break; | |
| 330 | 329 | ||
| 331 | 330 | case Edit::LIGHT_DIRECTION: { | |
| 332 | 331 | double x, y, z; | |
| 333 | - if(sscanf(s, "%lf, %lf, %lf", &x, &y, &z)==3) { | ||
| 332 | + if(sscanf(s.c_str(), "%lf, %lf, %lf", &x, &y, &z)==3) { | ||
| 334 | 333 | SS.lightDir[edit.i] = Vector::From(x, y, z); | |
| 335 | 334 | } else { | |
| 336 | 335 | Error(_("Bad format: specify coordinates as x, y, z")); | |
| 337 | 336 | } | |
| 338 | - InvalidateGraphics(); | ||
| 337 | + SS.GW.Invalidate(); | ||
| 339 | 338 | break; | |
| 340 | 339 | } | |
| 341 | 340 | case Edit::COLOR: { | |
| 342 | 341 | Vector rgb; | |
| 343 | - if(sscanf(s, "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) { | ||
| 342 | + if(sscanf(s.c_str(), "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) { | ||
| 344 | 343 | rgb = rgb.ClampWithin(0, 1); | |
| 345 | 344 | SS.modelColor[edit.i] = RGBf(rgb.x, rgb.y, rgb.z); | |
| 346 | 345 | } else { | |
@@ -350,44 +349,44 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) { | |||
| 350 | 349 | } | |
| 351 | 350 | case Edit::CHORD_TOLERANCE: { | |
| 352 | 351 | if(edit.i == 0) { | |
| 353 | - SS.chordTol = max(0.0, atof(s)); | ||
| 352 | + SS.chordTol = max(0.0, atof(s.c_str())); | ||
| 354 | 353 | SS.GenerateAll(SolveSpaceUI::Generate::ALL); | |
| 355 | 354 | } else { | |
| 356 | - SS.exportChordTol = max(0.0, atof(s)); | ||
| 355 | + SS.exportChordTol = max(0.0, atof(s.c_str())); | ||
| 357 | 356 | } | |
| 358 | 357 | break; | |
| 359 | 358 | } | |
| 360 | 359 | case Edit::MAX_SEGMENTS: { | |
| 361 | 360 | if(edit.i == 0) { | |
| 362 | - SS.maxSegments = min(1000, max(7, atoi(s))); | ||
| 361 | + SS.maxSegments = min(1000, max(7, atoi(s.c_str()))); | ||
| 363 | 362 | SS.GenerateAll(SolveSpaceUI::Generate::ALL); | |
| 364 | 363 | } else { | |
| 365 | - SS.exportMaxSegments = min(1000, max(7, atoi(s))); | ||
| 364 | + SS.exportMaxSegments = min(1000, max(7, atoi(s.c_str()))); | ||
| 366 | 365 | } | |
| 367 | 366 | break; | |
| 368 | 367 | } | |
| 369 | 368 | case Edit::CAMERA_TANGENT: { | |
| 370 | - SS.cameraTangent = (min(2.0, max(0.0, atof(s))))/1000.0; | ||
| 369 | + SS.cameraTangent = (min(2.0, max(0.0, atof(s.c_str()))))/1000.0; | ||
| 371 | 370 | if(!SS.usePerspectiveProj) { | |
| 372 | 371 | Message(_("The perspective factor will have no effect until you " | |
| 373 | 372 | "enable View -> Use Perspective Projection.")); | |
| 374 | 373 | } | |
| 375 | - InvalidateGraphics(); | ||
| 374 | + SS.GW.Invalidate(); | ||
| 376 | 375 | break; | |
| 377 | 376 | } | |
| 378 | 377 | case Edit::GRID_SPACING: { | |
| 379 | 378 | SS.gridSpacing = (float)min(1e4, max(1e-3, SS.StringToMm(s))); | |
| 380 | - InvalidateGraphics(); | ||
| 379 | + SS.GW.Invalidate(); | ||
| 381 | 380 | break; | |
| 382 | 381 | } | |
| 383 | 382 | case Edit::DIGITS_AFTER_DECIMAL: { | |
| 384 | - int v = atoi(s); | ||
| 383 | + int v = atoi(s.c_str()); | ||
| 385 | 384 | if(v < 0 || v > 8) { | |
| 386 | 385 | Error(_("Specify between 0 and 8 digits after the decimal.")); | |
| 387 | 386 | } else { | |
| 388 | 387 | SS.SetUnitDigitsAfterDecimal(v); | |
| 389 | 388 | } | |
| 390 | - InvalidateGraphics(); | ||
| 389 | + SS.GW.Invalidate(); | ||
| 391 | 390 | break; | |
| 392 | 391 | } | |
| 393 | 392 | case Edit::EXPORT_SCALE: { | |
@@ -455,8 +454,8 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) { | |||
| 455 | 454 | break; | |
| 456 | 455 | } | |
| 457 | 456 | case Edit::AUTOSAVE_INTERVAL: { | |
| 458 | - int interval; | ||
| 459 | - if(sscanf(s, "%d", &interval)==1) { | ||
| 457 | + int interval = atoi(s.c_str()); | ||
| 458 | + if(interval) { | ||
| 460 | 459 | if(interval >= 1) { | |
| 461 | 460 | SS.autosaveInterval = interval; | |
| 462 | 461 | SS.ScheduleAutosave(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -744,7 +744,7 @@ void Constraint::MenuConstrain(Command id) { | |||
| 744 | 744 | } | |
| 745 | 745 | ||
| 746 | 746 | SS.GW.ClearSelection(); | |
| 747 | - InvalidateGraphics(); | ||
| 747 | + SS.GW.Invalidate(); | ||
| 748 | 748 | } | |
| 749 | 749 | ||
| 750 | 750 | #endif /* ! LIBRARY */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -80,7 +80,7 @@ void GraphicsWindow::Selection::Draw(bool isHovered, Canvas *canvas) { | |||
| 80 | 80 | void GraphicsWindow::ClearSelection() { | |
| 81 | 81 | selection.Clear(); | |
| 82 | 82 | SS.ScheduleShowTW(); | |
| 83 | - InvalidateGraphics(); | ||
| 83 | + Invalidate(); | ||
| 84 | 84 | } | |
| 85 | 85 | ||
| 86 | 86 | void GraphicsWindow::ClearNonexistentSelectionItems() { | |
@@ -98,7 +98,7 @@ void GraphicsWindow::ClearNonexistentSelectionItems() { | |||
| 98 | 98 | } | |
| 99 | 99 | } | |
| 100 | 100 | selection.RemoveTagged(); | |
| 101 | - if(change) InvalidateGraphics(); | ||
| 101 | + if(change) Invalidate(); | ||
| 102 | 102 | } | |
| 103 | 103 | ||
| 104 | 104 | //----------------------------------------------------------------------------- | |
@@ -304,14 +304,14 @@ void GraphicsWindow::GroupSelection() { | |||
| 304 | 304 | ||
| 305 | 305 | Camera GraphicsWindow::GetCamera() const { | |
| 306 | 306 | Camera camera = {}; | |
| 307 | - camera.width = (int)width; | ||
| 308 | - camera.height = (int)height; | ||
| 309 | - camera.offset = offset; | ||
| 310 | - camera.projUp = projUp; | ||
| 311 | - camera.projRight = projRight; | ||
| 312 | - camera.scale = scale; | ||
| 313 | - camera.tangent = SS.CameraTangent(); | ||
| 314 | - camera.hasPixels = true; | ||
| 307 | + window->GetContentSize(&camera.width, &camera.height); | ||
| 308 | + camera.pixelRatio = window->GetDevicePixelRatio(); | ||
| 309 | + camera.gridFit = (window->GetDevicePixelRatio() == 1); | ||
| 310 | + camera.offset = offset; | ||
| 311 | + camera.projUp = projUp; | ||
| 312 | + camera.projRight = projRight; | ||
| 313 | + camera.scale = scale; | ||
| 314 | + camera.tangent = SS.CameraTangent(); | ||
| 315 | 315 | return camera; | |
| 316 | 316 | } | |
| 317 | 317 | ||
@@ -457,7 +457,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) { | |||
| 457 | 457 | ||
| 458 | 458 | if(!sel.Equals(&hover)) { | |
| 459 | 459 | hover = sel; | |
| 460 | - InvalidateGraphics(); | ||
| 460 | + Invalidate(); | ||
| 461 | 461 | } | |
| 462 | 462 | } | |
| 463 | 463 | ||
@@ -545,6 +545,10 @@ void GraphicsWindow::NormalizeProjectionVectors() { | |||
| 545 | 545 | void GraphicsWindow::DrawSnapGrid(Canvas *canvas) { | |
| 546 | 546 | if(!LockedInWorkplane()) return; | |
| 547 | 547 | ||
| 548 | + const Camera &camera = canvas->GetCamera(); | ||
| 549 | + double width = camera.width, | ||
| 550 | + height = camera.height; | ||
| 551 | + | ||
| 548 | 552 | hEntity he = ActiveWorkplane(); | |
| 549 | 553 | EntityBase *wrkpl = SK.GetEntity(he), | |
| 550 | 554 | *norm = wrkpl->Normal(); | |
@@ -816,15 +820,11 @@ void GraphicsWindow::Draw(Canvas *canvas) { | |||
| 816 | 820 | } | |
| 817 | 821 | ||
| 818 | 822 | void GraphicsWindow::Paint() { | |
| 819 | - if(!canvas) return; | ||
| 823 | + ssassert(window != NULL && canvas != NULL, | ||
| 824 | + "Cannot paint without window and canvas"); | ||
| 820 | 825 | ||
| 821 | 826 | havePainted = true; | |
| 822 | 827 | ||
| 823 | - int w, h; | ||
| 824 | - GetGraphicsWindowSize(&w, &h); | ||
| 825 | - width = w; | ||
| 826 | - height = h; | ||
| 827 | - | ||
| 828 | 828 | Camera camera = GetCamera(); | |
| 829 | 829 | Lighting lighting = GetLighting(); | |
| 830 | 830 | ||
@@ -902,3 +902,12 @@ void GraphicsWindow::Paint() { | |||
| 902 | 902 | canvas->FlushFrame(); | |
| 903 | 903 | canvas->Clear(); | |
| 904 | 904 | } | |
| 905 | + | ||
| 906 | + void GraphicsWindow::Invalidate(bool clearPersistent) { | ||
| 907 | + if(window) { | ||
| 908 | + if(clearPersistent) { | ||
| 909 | + persistentDirty = true; | ||
| 910 | + } | ||
| 911 | + window->Invalidate(); | ||
| 912 | + } | ||
| 913 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -263,7 +263,7 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const Platform::Path &filename, bool | |||
| 263 | 263 | } | |
| 264 | 264 | ||
| 265 | 265 | SS.justExportedInfo.draw = true; | |
| 266 | - InvalidateGraphics(); | ||
| 266 | + GW.Invalidate(); | ||
| 267 | 267 | } | |
| 268 | 268 | ||
| 269 | 269 | edges.Clear(); | |
@@ -839,7 +839,7 @@ void SolveSpaceUI::ExportMeshTo(const Platform::Path &filename) { | |||
| 839 | 839 | ||
| 840 | 840 | SS.justExportedInfo.showOrigin = false; | |
| 841 | 841 | SS.justExportedInfo.draw = true; | |
| 842 | - InvalidateGraphics(); | ||
| 842 | + GW.Invalidate(); | ||
| 843 | 843 | } | |
| 844 | 844 | ||
| 845 | 845 | //----------------------------------------------------------------------------- | |
@@ -1108,5 +1108,5 @@ void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const Platform::Path &filename | |||
| 1108 | 1108 | void SolveSpaceUI::ExportAsPngTo(const Platform::Path &filename) { | |
| 1109 | 1109 | screenshotFile = filename; | |
| 1110 | 1110 | // The rest of the work is done in the next redraw. | |
| 1111 | - InvalidateGraphics(); | ||
| 1111 | + GW.Invalidate(); | ||
| 1112 | 1112 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -605,8 +605,7 @@ class ExprParser { | |||
| 605 | 605 | bool IsError() const { return type == TokenType::ERROR; } | |
| 606 | 606 | }; | |
| 607 | 607 | ||
| 608 | - const char *input; | ||
| 609 | - unsigned inputPos; | ||
| 608 | + std::string::const_iterator it, end; | ||
| 610 | 609 | std::vector<Token> stack; | |
| 611 | 610 | ||
| 612 | 611 | char ReadChar(); | |
@@ -624,7 +623,7 @@ class ExprParser { | |||
| 624 | 623 | bool Reduce(std::string *error); | |
| 625 | 624 | bool Parse(std::string *error, size_t reduceUntil = 0); | |
| 626 | 625 | ||
| 627 | - static Expr *Parse(const char *input, std::string *error); | ||
| 626 | + static Expr *Parse(const std::string &input, std::string *error); | ||
| 628 | 627 | }; | |
| 629 | 628 | ||
| 630 | 629 | ExprParser::Token ExprParser::Token::From(TokenType type, Expr *expr) { | |
@@ -643,11 +642,15 @@ ExprParser::Token ExprParser::Token::From(TokenType type, Expr::Op op) { | |||
| 643 | 642 | } | |
| 644 | 643 | ||
| 645 | 644 | char ExprParser::ReadChar() { | |
| 646 | - return input[inputPos++]; | ||
| 645 | + return *it++; | ||
| 647 | 646 | } | |
| 648 | 647 | ||
| 649 | 648 | char ExprParser::PeekChar() { | |
| 650 | - return input[inputPos]; | ||
| 649 | + if(it == end) { | ||
| 650 | + return '\0'; | ||
| 651 | + } else { | ||
| 652 | + return *it; | ||
| 653 | + } | ||
| 651 | 654 | } | |
| 652 | 655 | ||
| 653 | 656 | std::string ExprParser::ReadWord() { | |
@@ -889,28 +892,29 @@ bool ExprParser::Parse(std::string *error, size_t reduceUntil) { | |||
| 889 | 892 | return true; | |
| 890 | 893 | } | |
| 891 | 894 | ||
| 892 | - Expr *ExprParser::Parse(const char *input, std::string *error) { | ||
| 895 | + Expr *ExprParser::Parse(const std::string &input, std::string *error) { | ||
| 893 | 896 | ExprParser parser; | |
| 894 | - parser.input = input; | ||
| 895 | - parser.inputPos = 0; | ||
| 897 | + parser.it = input.cbegin(); | ||
| 898 | + parser.end = input.cend(); | ||
| 896 | 899 | if(!parser.Parse(error)) return NULL; | |
| 897 | 900 | ||
| 898 | 901 | Token r = parser.PopOperand(error); | |
| 899 | 902 | if(r.IsError()) return NULL; | |
| 900 | 903 | return r.expr; | |
| 901 | 904 | } | |
| 902 | 905 | ||
| 903 | - Expr *Expr::Parse(const char *input, std::string *error) { | ||
| 906 | + Expr *Expr::Parse(const std::string &input, std::string *error) { | ||
| 904 | 907 | return ExprParser::Parse(input, error); | |
| 905 | 908 | } | |
| 906 | 909 | ||
| 907 | - Expr *Expr::From(const char *input, bool popUpError) { | ||
| 910 | + Expr *Expr::From(const std::string &input, bool popUpError) { | ||
| 908 | 911 | std::string error; | |
| 909 | 912 | Expr *e = ExprParser::Parse(input, &error); | |
| 910 | 913 | if(!e) { | |
| 911 | 914 | dbp("Parse/lex error: %s", error.c_str()); | |
| 912 | 915 | if(popUpError) { | |
| 913 | - Error("Not a valid number or expression: '%s'.\n%s.", input, error.c_str()); | ||
| 916 | + Error("Not a valid number or expression: '%s'.\n%s.", | ||
| 917 | + input.c_str(), error.c_str()); | ||
| 914 | 918 | } | |
| 915 | 919 | } | |
| 916 | 920 | return e; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments