From 512d311228e61441dbe8d54883aa745603433c4b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 12 Jan 2025 14:58:51 +0000 Subject: [PATCH] dvisvgm 3.4.3 git-svn-id: svn://tug.org/texlive/trunk/Build/source@73430 c570f23f-e606-0410-a88d-b1316a301751 --- texk/README | 2 +- texk/dvisvgm/ChangeLog | 4 + texk/dvisvgm/TLpatches/TL-Changes | 5 +- texk/dvisvgm/TLpatches/patch-04-configure | 16 +- texk/dvisvgm/TLpatches/patch-08-makefiles | 4 +- texk/dvisvgm/configure | 24 +- texk/dvisvgm/configure.ac | 6 +- texk/dvisvgm/dvisvgm-src/AUTHORS | 4 - texk/dvisvgm/dvisvgm-src/Makefile.am | 2 +- texk/dvisvgm/dvisvgm-src/Makefile.in | 2 +- texk/dvisvgm/dvisvgm-src/NEWS | 44 + texk/dvisvgm/dvisvgm-src/README | 2 +- texk/dvisvgm/dvisvgm-src/aminclude_static.am | 2 +- texk/dvisvgm/dvisvgm-src/configure.ac | 6 +- texk/dvisvgm/dvisvgm-src/doc/Makefile.am | 2 +- .../dvisvgm-src/doc/conf-dblatex-man.xsl | 2 +- .../dvisvgm-src/doc/conf-dblatex-pdf.xsl | 4 +- texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 | 172 +- texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in | 297 ++-- .../dvisvgm-src/doc/tweak-db-refentry.xsl | 2 +- .../dvisvgm-src/doc/tweak-dblatex-pdf.xsl | 2 +- texk/dvisvgm/dvisvgm-src/libs/Makefile.am | 2 +- texk/dvisvgm/dvisvgm-src/libs/defs.am | 2 +- texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c | 7 +- texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h | 1315 +++++++++----- texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp | 2 +- .../dvisvgm-src/src/BasicDVIReader.cpp | 2 +- .../dvisvgm-src/src/BasicDVIReader.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Bezier.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Bezier.hpp | 2 +- .../dvisvgm-src/src/BgColorSpecialHandler.cpp | 2 +- .../dvisvgm-src/src/BgColorSpecialHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/CLCommandLine.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/CLCommandLine.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/CLOption.hpp | 13 +- texk/dvisvgm/dvisvgm-src/src/CMap.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/CMap.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Calculator.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Calculator.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Character.hpp | 3 +- texk/dvisvgm/dvisvgm-src/src/Color.cpp | 340 +++- texk/dvisvgm/dvisvgm-src/src/Color.hpp | 34 +- .../dvisvgm-src/src/ColorSpecialHandler.cpp | 88 +- .../dvisvgm-src/src/ColorSpecialHandler.hpp | 17 +- texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp | 4 +- texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp | 15 +- texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp | 8 +- .../dvisvgm-src/src/DVIToSVGActions.cpp | 21 +- .../dvisvgm-src/src/DVIToSVGActions.hpp | 11 +- texk/dvisvgm/dvisvgm-src/src/Directory.cpp | 8 +- texk/dvisvgm/dvisvgm-src/src/Directory.hpp | 2 +- .../dvisvgm-src/src/DvisvgmSpecialHandler.cpp | 65 +- .../dvisvgm-src/src/DvisvgmSpecialHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/EllipticalArc.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/EllipticalArc.hpp | 2 +- .../dvisvgm-src/src/EmSpecialHandler.cpp | 6 +- .../dvisvgm-src/src/EmSpecialHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/EncFile.cpp | 4 +- texk/dvisvgm/dvisvgm-src/src/EncFile.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FilePath.cpp | 36 +- texk/dvisvgm/dvisvgm-src/src/FilePath.hpp | 15 +- texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FixWord.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Font.cpp | 4 +- texk/dvisvgm/dvisvgm-src/src/Font.hpp | 34 +- texk/dvisvgm/dvisvgm-src/src/FontCache.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontCache.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp | 4 +- texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp | 3 +- texk/dvisvgm/dvisvgm-src/src/FontManager.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontManager.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontMap.cpp | 131 +- texk/dvisvgm/dvisvgm-src/src/FontMap.hpp | 29 +- texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/GFReader.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/GFReader.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Glyph.hpp | 2 +- .../dvisvgm-src/src/GlyphTracerMessages.hpp | 4 +- texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp | 2 +- .../dvisvgm-src/src/GraphicsPathParser.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp | 3 +- .../dvisvgm-src/src/HtmlSpecialHandler.cpp | 2 +- .../dvisvgm-src/src/HtmlSpecialHandler.hpp | 2 +- .../dvisvgm-src/src/HyperlinkManager.cpp | 15 +- .../dvisvgm-src/src/HyperlinkManager.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp | 14 +- texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp | 8 +- texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/InputReader.cpp | 17 +- texk/dvisvgm/dvisvgm-src/src/InputReader.hpp | 5 +- texk/dvisvgm/dvisvgm-src/src/JFM.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/JFM.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Length.cpp | 4 +- texk/dvisvgm/dvisvgm-src/src/Length.hpp | 2 +- .../dvisvgm-src/src/MD5HashFunction.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Makefile.am | 2 +- texk/dvisvgm/dvisvgm-src/src/MapLine.cpp | 6 +- texk/dvisvgm/dvisvgm-src/src/MapLine.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Matrix.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Matrix.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Message.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Message.hpp | 2 +- .../dvisvgm-src/src/MessageException.hpp | 2 +- .../dvisvgm-src/src/MetafontWrapper.cpp | 7 +- .../dvisvgm-src/src/MetafontWrapper.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp | 2 +- .../dvisvgm-src/src/NoPsSpecialHandler.cpp | 2 +- .../dvisvgm-src/src/NoPsSpecialHandler.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/NumericRanges.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/OFM.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/OFM.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Opacity.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Opacity.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PDFHandler.cpp | 16 +- texk/dvisvgm/dvisvgm-src/src/PDFHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PDFToSVG.cpp | 4 +- texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/PSInterpreter.cpp | 9 +- .../dvisvgm/dvisvgm-src/src/PSInterpreter.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp | 4 +- texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp | 2 +- .../dvisvgm-src/src/PSPreviewHandler.cpp | 2 +- .../dvisvgm-src/src/PSPreviewHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PageSize.cpp | 4 +- texk/dvisvgm/dvisvgm-src/src/PageSize.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Pair.hpp | 2 +- .../src/PapersizeSpecialHandler.cpp | 4 +- .../src/PapersizeSpecialHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp | 2 +- .../dvisvgm-src/src/PdfSpecialHandler.cpp | 4 +- .../dvisvgm-src/src/PdfSpecialHandler.hpp | 2 +- .../dvisvgm-src/src/PreScanDVIReader.cpp | 2 +- .../dvisvgm-src/src/PreScanDVIReader.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Process.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Process.hpp | 2 +- .../dvisvgm-src/src/PsSpecialHandler.cpp | 69 +- .../dvisvgm-src/src/PsSpecialHandler.hpp | 3 +- .../dvisvgm-src/src/PsSpecialHandlerProxy.cpp | 2 +- .../dvisvgm-src/src/PsSpecialHandlerProxy.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp | 2 +- .../dvisvgm-src/src/SVGCharHandler.cpp | 2 +- .../dvisvgm-src/src/SVGCharHandler.hpp | 11 +- .../dvisvgm-src/src/SVGCharHandlerFactory.cpp | 2 +- .../dvisvgm-src/src/SVGCharHandlerFactory.hpp | 2 +- .../dvisvgm-src/src/SVGCharPathHandler.cpp | 6 +- .../dvisvgm-src/src/SVGCharPathHandler.hpp | 2 +- .../src/SVGCharTspanTextHandler.cpp | 14 +- .../src/SVGCharTspanTextHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/SVGElement.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp | 6 +- texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp | 8 +- .../src/SVGSingleCharTextHandler.cpp | 8 +- .../src/SVGSingleCharTextHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp | 22 +- texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp | 9 +- texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp | 23 +- texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp | 4 +- .../dvisvgm/dvisvgm-src/src/SignalHandler.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/SignalHandler.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp | 2 +- .../dvisvgm-src/src/SpecialActions.cpp | 36 +- .../dvisvgm-src/src/SpecialActions.hpp | 14 +- .../dvisvgm-src/src/SpecialHandler.hpp | 2 +- .../dvisvgm-src/src/SpecialManager.cpp | 2 +- .../dvisvgm-src/src/SpecialManager.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Subfont.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Subfont.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/System.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/System.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/TFM.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/TFM.hpp | 2 +- .../dvisvgm-src/src/TensorProductPatch.cpp | 189 +-- .../dvisvgm-src/src/TensorProductPatch.hpp | 12 +- texk/dvisvgm/dvisvgm-src/src/Terminal.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/Terminal.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp | 2 +- .../dvisvgm-src/src/TpicSpecialHandler.cpp | 6 +- .../dvisvgm-src/src/TpicSpecialHandler.hpp | 2 +- .../dvisvgm-src/src/TriangularPatch.cpp | 37 +- .../dvisvgm-src/src/TriangularPatch.hpp | 6 +- texk/dvisvgm/dvisvgm-src/src/Unicode.cpp | 6 +- texk/dvisvgm/dvisvgm-src/src/Unicode.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/VFActions.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/VFReader.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/VFReader.hpp | 2 +- .../dvisvgm-src/src/VectorIterator.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/XMLParser.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/XMLParser.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/XMLString.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/XMLString.hpp | 2 +- .../dvisvgm-src/src/XXHashFunction.hpp | 2 +- .../dvisvgm-src/src/ZLibOutputStream.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp | 8 +- .../dvisvgm-src/src/fonts/Base14Fonts.cpp | 2 +- .../dvisvgm-src/src/fonts/Base14Fonts.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/ierrors.h | 123 +- texk/dvisvgm/dvisvgm-src/src/macros.hpp | 2 +- .../src/optimizer/AttributeExtractor.cpp | 2 +- .../src/optimizer/AttributeExtractor.hpp | 2 +- .../src/optimizer/ClipPathReassigner.cpp | 21 +- .../src/optimizer/ClipPathReassigner.hpp | 2 +- .../src/optimizer/DependencyGraph.hpp | 2 +- .../src/optimizer/GroupCollapser.cpp | 2 +- .../src/optimizer/GroupCollapser.hpp | 2 +- .../src/optimizer/OptimizerModule.hpp | 2 +- .../src/optimizer/RedundantElementRemover.cpp | 2 +- .../src/optimizer/RedundantElementRemover.hpp | 2 +- .../src/optimizer/SVGOptimizer.cpp | 2 +- .../src/optimizer/SVGOptimizer.hpp | 2 +- .../src/optimizer/TextSimplifier.cpp | 2 +- .../src/optimizer/TextSimplifier.hpp | 2 +- .../src/optimizer/TransformSimplifier.cpp | 2 +- .../src/optimizer/TransformSimplifier.hpp | 2 +- .../src/optimizer/WSNodeRemover.cpp | 2 +- .../src/optimizer/WSNodeRemover.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/options.dtd | 2 +- texk/dvisvgm/dvisvgm-src/src/options.xml | 4 +- texk/dvisvgm/dvisvgm-src/src/psdefs.cpp | 4 +- .../dvisvgm/dvisvgm-src/src/ttf/CmapTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/CmapTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/GlyfTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/GlyfTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/HeadTable.cpp | 25 +- .../dvisvgm/dvisvgm-src/src/ttf/HeadTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/HheaTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/HheaTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/HmtxTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/HmtxTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/LocaTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/MaxpTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/MaxpTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/NameTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/NameTable.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/PostTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/PostTable.hpp | 2 +- .../dvisvgm-src/src/ttf/TTFAutohint.cpp | 2 +- .../dvisvgm-src/src/ttf/TTFAutohint.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.cpp | 2 +- texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/TTFWriter.cpp | 4 +- .../dvisvgm/dvisvgm-src/src/ttf/TTFWriter.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/VheaTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/VheaTable.hpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/VmtxTable.cpp | 2 +- .../dvisvgm/dvisvgm-src/src/ttf/VmtxTable.hpp | 2 +- texk/dvisvgm/dvisvgm-src/src/utility.cpp | 66 +- texk/dvisvgm/dvisvgm-src/src/utility.hpp | 17 +- texk/dvisvgm/dvisvgm-src/src/version.hpp.in | 2 +- texk/dvisvgm/dvisvgm-src/src/windows.hpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp | 2 +- .../dvisvgm-src/tests/BoundingBoxTest.cpp | 2 +- .../dvisvgm-src/tests/CMapManagerTest.cpp | 2 +- .../dvisvgm-src/tests/CMapReaderTest.cpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp | 2 +- .../dvisvgm-src/tests/CalculatorTest.cpp | 2 +- .../dvisvgm-src/tests/ColorSpecialTest.cpp | 75 +- texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp | 35 +- .../dvisvgm-src/tests/CommandLineTest.cpp | 2 +- .../dvisvgm-src/tests/DVIReaderTest.cpp | 2 +- .../dvisvgm-src/tests/DependencyGraphTest.cpp | 2 +- .../dvisvgm-src/tests/DirectoryTest.cpp | 2 +- .../dvisvgm-src/tests/DvisvgmSpecialTest.cpp | 22 +- .../dvisvgm-src/tests/EllipticalArcTest.cpp | 2 +- .../dvisvgm-src/tests/EmSpecialTest.cpp | 28 +- .../dvisvgm-src/tests/FileFinderTest.cpp | 2 +- .../dvisvgm-src/tests/FilePathTest.cpp | 14 +- .../dvisvgm-src/tests/FileSystemTest.cpp | 2 +- .../dvisvgm-src/tests/FontCacheTest.cpp | 2 +- .../dvisvgm-src/tests/FontManagerTest.cpp | 4 +- .../dvisvgm/dvisvgm-src/tests/FontMapTest.cpp | 2 +- .../dvisvgm-src/tests/GFGlyphTracerTest.cpp | 2 +- .../dvisvgm-src/tests/GFReaderTest.cpp | 2 +- .../dvisvgm-src/tests/GhostscriptTest.cpp | 2 +- .../tests/GraphicsPathParserTest.cpp | 2 +- .../dvisvgm-src/tests/GraphicsPathTest.cpp | 2 +- .../dvisvgm-src/tests/HashFunctionTest.cpp | 2 +- .../dvisvgm-src/tests/JFMReaderTest.cpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/Makefile.am | 3 +- texk/dvisvgm/dvisvgm-src/tests/Makefile.in | 1 + .../dvisvgm/dvisvgm-src/tests/MapLineTest.cpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp | 2 +- .../tests/MessageExceptionTest.cpp | 2 +- .../dvisvgm-src/tests/OFMReaderTest.cpp | 2 +- .../dvisvgm-src/tests/PDFParserTest.cpp | 2 +- .../dvisvgm-src/tests/PSInterpreterTest.cpp | 2 +- .../dvisvgm-src/tests/PageRagesTest.cpp | 2 +- .../dvisvgm-src/tests/PageSizeTest.cpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp | 2 +- .../tests/PapersizeSpecialTest.cpp | 2 +- .../dvisvgm-src/tests/RangeMapTest.cpp | 2 +- .../dvisvgm-src/tests/SVGOutputTest.cpp | 2 +- .../dvisvgm-src/tests/ShadingPatchTest.cpp | 22 +- .../dvisvgm-src/tests/SpecialManagerTest.cpp | 2 +- .../tests/SplittedCharInputBufferTest.cpp | 2 +- .../tests/StreamInputBufferTest.cpp | 23 +- .../dvisvgm-src/tests/StreamReaderTest.cpp | 2 +- .../dvisvgm-src/tests/StreamWriterTest.cpp | 2 +- .../dvisvgm-src/tests/StringMatcherTest.cpp | 2 +- .../dvisvgm/dvisvgm-src/tests/SubfontTest.cpp | 2 +- .../dvisvgm-src/tests/TFMReaderTest.cpp | 2 +- .../tests/TensorProductPatchTest.cpp | 88 +- .../dvisvgm-src/tests/ToUnicodeMapTest.cpp | 2 +- .../dvisvgm-src/tests/TpicSpecialTest.cpp | 6 +- .../dvisvgm-src/tests/TriangularPatchTest.cpp | 13 +- .../dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp | 2 +- .../dvisvgm/dvisvgm-src/tests/UtilityTest.cpp | 2 +- .../dvisvgm-src/tests/VectorIteratorTest.cpp | 2 +- .../dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp | 2 +- .../dvisvgm-src/tests/XMLStringTest.cpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/check-conv | 2 +- .../dvisvgm-src/tests/data/Makefile.am | 2 +- .../dvisvgm/dvisvgm-src/tests/genhashcheck.py | 2 +- .../include/gtest/gtest-assertion-result.h | 237 +++ .../gtest/include/gtest/gtest-death-test.h | 89 +- .../gtest/include/gtest/gtest-matchers.h | 76 +- .../tests/gtest/include/gtest/gtest-message.h | 27 +- .../gtest/include/gtest/gtest-param-test.h | 87 +- .../gtest/include/gtest/gtest-printers.h | 65 +- .../tests/gtest/include/gtest/gtest-spi.h | 132 +- .../gtest/include/gtest/gtest-test-part.h | 14 +- .../gtest/include/gtest/gtest-typed-test.h | 38 +- .../tests/gtest/include/gtest/gtest.h | 536 ++---- .../gtest/include/gtest/gtest_pred_impl.h | 200 +-- .../tests/gtest/include/gtest/gtest_prod.h | 9 +- .../internal/gtest-death-test-internal.h | 74 +- .../include/gtest/internal/gtest-filepath.h | 17 +- .../include/gtest/internal/gtest-internal.h | 330 ++-- .../include/gtest/internal/gtest-param-util.h | 145 +- .../include/gtest/internal/gtest-port-arch.h | 100 +- .../gtest/include/gtest/internal/gtest-port.h | 982 +++++------ .../include/gtest/internal/gtest-string.h | 18 +- .../include/gtest/internal/gtest-type-util.h | 21 +- .../dvisvgm-src/tests/gtest/src/gtest-all.cc | 3 +- .../tests/gtest/src/gtest-assertion-result.cc | 77 + .../tests/gtest/src/gtest-death-test.cc | 520 +++--- .../tests/gtest/src/gtest-filepath.cc | 78 +- .../tests/gtest/src/gtest-internal-inl.h | 217 ++- .../tests/gtest/src/gtest-matchers.cc | 5 +- .../dvisvgm-src/tests/gtest/src/gtest-port.cc | 349 ++-- .../tests/gtest/src/gtest-printers.cc | 124 +- .../tests/gtest/src/gtest-test-part.cc | 19 +- .../tests/gtest/src/gtest-typed-test.cc | 7 +- .../dvisvgm-src/tests/gtest/src/gtest.cc | 1510 +++++++++-------- .../dvisvgm-src/tests/gtest/src/gtest_main.cc | 5 +- texk/dvisvgm/dvisvgm-src/tests/normalize.xsl | 2 +- texk/dvisvgm/dvisvgm-src/tests/testmain.cpp | 2 +- texk/dvisvgm/dvisvgm-src/tests/testutil.hpp | 9 + texk/dvisvgm/tests/sample_v2-nf.svg | 4 +- texk/dvisvgm/tests/sample_v2-wf.svg | 4 +- texk/dvisvgm/tests/sample_v3-nf.svg | 2 +- texk/dvisvgm/tests/sample_v3-wf.svg | 2 +- texk/dvisvgm/tests/upjf.svg | 2 +- texk/dvisvgm/tests/upjf1.svg | 2 +- texk/dvisvgm/version.ac | 4 +- 411 files changed, 5928 insertions(+), 4786 deletions(-) create mode 100644 texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-assertion-result.h create mode 100644 texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-assertion-result.cc diff --git a/texk/README b/texk/README index 048ebf90b0..0465c0c161 100644 --- a/texk/README +++ b/texk/README @@ -61,7 +61,7 @@ dvipos - maintained here, by us dvipsk - maintained here, by us -dvisvgm 3.2.2 - checked 7mar24 +dvisvgm 3.4.3 - checked 11jan25 https://dvisvgm.de/Downloads/ https://github.com/mgieseki/dvisvgm https://ctan.org/pkg/dvisvgm diff --git a/texk/dvisvgm/ChangeLog b/texk/dvisvgm/ChangeLog index 4c178262e9..ad7b293c16 100644 --- a/texk/dvisvgm/ChangeLog +++ b/texk/dvisvgm/ChangeLog @@ -1,3 +1,7 @@ +2025-01-11 Karl Berry + + * Import dvisvgm-3.4.3, patch from Martin. + 2024-01-27 TANAKA Takuji * tests/dvisvgm-{uptex,hara}.test: diff --git a/texk/dvisvgm/TLpatches/TL-Changes b/texk/dvisvgm/TLpatches/TL-Changes index dd3306c9d6..9226a62a4c 100644 --- a/texk/dvisvgm/TLpatches/TL-Changes +++ b/texk/dvisvgm/TLpatches/TL-Changes @@ -42,7 +42,7 @@ diff -u2 dvisvgm-{prev,$ver}/configure.ac patch -d dvisvgm-src -p1 TLpatches/patch-04-configure for m in `(cd ./dvisvgm-src && find -name Makefile.am -o -name defs.am)`; do \ diff -u2 dvisvgm-{$ver,src}/$m; done >TLpatches/patch-08-makefiles +# check changes: +svn diff TLpatches + # commit: svn commit -m"dvisvgm $ver" . ../README diff --git a/texk/dvisvgm/TLpatches/patch-04-configure b/texk/dvisvgm/TLpatches/patch-04-configure index 80c822aa0c..01661e7198 100644 --- a/texk/dvisvgm/TLpatches/patch-04-configure +++ b/texk/dvisvgm/TLpatches/patch-04-configure @@ -1,16 +1,16 @@ ---- dvisvgm-3.2.2/configure.ac 2024-03-07 03:07:02.000000000 -0800 -+++ ./configure.ac 2024-03-07 14:41:00.745785681 -0800 +--- dvisvgm-3.4.3/configure.ac 2025-01-04 03:40:14.000000000 -0800 ++++ ./configure.ac 2025-01-11 10:11:01.398834796 -0800 @@ -1,18 +1,31 @@ -# This file is part of dvisvgm --# Copyright (C) 2005-2024 Martin Gieseking +-# Copyright (C) 2005-2025 Martin Gieseking -# -# Process this file with autoconf to produce a configure script. - -+dnl $Id: configure.ac 70431 2024-03-05 23:23:42Z karl $ ++dnl $Id: configure.ac 70487 2024-03-07 22:55:09Z karl $ +dnl Process this file with autoconf to produce a configure script +dnl for dvisvgm in TeX Live. +dnl -+dnl Copyright 2015-2024 Karl Berry ++dnl Copyright 2015-2025 Karl Berry +dnl Copyright 2009-2014 Peter Breitenlohner +dnl +dnl This file is free software; the copyright holder @@ -18,13 +18,13 @@ +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl Adapted for TeX Live from original dvisvgm configure.ac -+dnl Copyright 2005-2024 Martin Gieseking ++dnl Copyright 2005-2025 Martin Gieseking +dnl AC_PREREQ([2.69]) --AC_INIT([dvisvgm],[3.2.2],[martin.gieseking@uos.de]) +-AC_INIT([dvisvgm],[3.4.3],[martin.gieseking@uos.de]) +m4_include([version.ac])[] dnl define dvisvgm_version +AC_INIT([dvisvgm (TeX Live)], dvisvgm_version, [tex-k@tug.org]) - DATE="March 2024" + DATE="January 2025" -AC_CONFIG_SRCDIR(src) +AC_CONFIG_SRCDIR([dvisvgm-src/src/dvisvgm.cpp]) AC_CONFIG_HEADERS([config.h]) diff --git a/texk/dvisvgm/TLpatches/patch-08-makefiles b/texk/dvisvgm/TLpatches/patch-08-makefiles index 0368072f27..839b0b2542 100644 --- a/texk/dvisvgm/TLpatches/patch-08-makefiles +++ b/texk/dvisvgm/TLpatches/patch-08-makefiles @@ -1,5 +1,5 @@ ---- dvisvgm-3.2.2/./Makefile.am 2024-03-07 03:04:19.000000000 -0800 -+++ dvisvgm-src/./Makefile.am 2024-03-07 14:43:29.913090622 -0800 +--- dvisvgm-3.4.3/./Makefile.am 2025-01-04 03:38:04.000000000 -0800 ++++ dvisvgm-src/./Makefile.am 2025-01-11 10:13:34.973835948 -0800 @@ -4,5 +4,5 @@ ## Process this file with automake. diff --git a/texk/dvisvgm/configure b/texk/dvisvgm/configure index b42e2eca71..192c427b4b 100755 --- a/texk/dvisvgm/configure +++ b/texk/dvisvgm/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for dvisvgm (TeX Live) 3.2.2. +# Generated by GNU Autoconf 2.72 for dvisvgm (TeX Live) 3.4.3. # # Report bugs to . # @@ -614,8 +614,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dvisvgm (TeX Live)' PACKAGE_TARNAME='dvisvgm--tex-live-' -PACKAGE_VERSION='3.2.2' -PACKAGE_STRING='dvisvgm (TeX Live) 3.2.2' +PACKAGE_VERSION='3.4.3' +PACKAGE_STRING='dvisvgm (TeX Live) 3.4.3' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1435,7 +1435,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures dvisvgm (TeX Live) 3.2.2 to adapt to many kinds of systems. +'configure' configures dvisvgm (TeX Live) 3.4.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1507,7 +1507,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of dvisvgm (TeX Live) 3.2.2:";; + short | recursive ) echo "Configuration of dvisvgm (TeX Live) 3.4.3:";; esac cat <<\_ACEOF @@ -1647,7 +1647,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -dvisvgm (TeX Live) configure 3.2.2 +dvisvgm (TeX Live) configure 3.4.3 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2395,7 +2395,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by dvisvgm (TeX Live) $as_me 3.2.2, which was +It was created by dvisvgm (TeX Live) $as_me 3.4.3, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3392,7 +3392,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -DATE="March 2024" +DATE="January 2025" ac_config_headers="$ac_config_headers config.h" @@ -9520,7 +9520,7 @@ fi # Define the identity of the package. PACKAGE='dvisvgm--tex-live-' - VERSION='3.2.2' + VERSION='3.4.3' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -23137,7 +23137,7 @@ Usage: $0 [OPTIONS] Report bugs to ." lt_cl_version="\ -dvisvgm (TeX Live) config.lt 3.2.2 +dvisvgm (TeX Live) config.lt 3.4.3 configured by $0, generated by GNU Autoconf 2.72. Copyright (C) 2024 Free Software Foundation, Inc. @@ -26646,7 +26646,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by dvisvgm (TeX Live) $as_me 3.2.2, which was +This file was extended by dvisvgm (TeX Live) $as_me 3.4.3, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -26714,7 +26714,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -dvisvgm (TeX Live) config.status 3.2.2 +dvisvgm (TeX Live) config.status 3.4.3 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/texk/dvisvgm/configure.ac b/texk/dvisvgm/configure.ac index 5263285512..0d2e087c68 100644 --- a/texk/dvisvgm/configure.ac +++ b/texk/dvisvgm/configure.ac @@ -2,7 +2,7 @@ dnl $Id$ dnl Process this file with autoconf to produce a configure script dnl for dvisvgm in TeX Live. dnl -dnl Copyright 2015-2024 Karl Berry +dnl Copyright 2015-2025 Karl Berry dnl Copyright 2009-2014 Peter Breitenlohner dnl dnl This file is free software; the copyright holder @@ -10,12 +10,12 @@ dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl Adapted for TeX Live from original dvisvgm configure.ac -dnl Copyright 2005-2024 Martin Gieseking +dnl Copyright 2005-2025 Martin Gieseking dnl AC_PREREQ([2.69]) m4_include([version.ac])[] dnl define dvisvgm_version AC_INIT([dvisvgm (TeX Live)], dvisvgm_version, [tex-k@tug.org]) -DATE="March 2024" +DATE="January 2025" AC_CONFIG_SRCDIR([dvisvgm-src/src/dvisvgm.cpp]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIRS([../../m4])dnl not just _DIR diff --git a/texk/dvisvgm/dvisvgm-src/AUTHORS b/texk/dvisvgm/dvisvgm-src/AUTHORS index 2d02014047..cfafb0fdd7 100644 --- a/texk/dvisvgm/dvisvgm-src/AUTHORS +++ b/texk/dvisvgm/dvisvgm-src/AUTHORS @@ -26,7 +26,3 @@ Peter Selinger libs/potrace/* http://potrace.sourceforge.net -George Williams - libs/ff-woff/* - https://github.com/fontforge/fontforge - diff --git a/texk/dvisvgm/dvisvgm-src/Makefile.am b/texk/dvisvgm/dvisvgm-src/Makefile.am index 02611daeb1..f1e06b4f54 100644 --- a/texk/dvisvgm/dvisvgm-src/Makefile.am +++ b/texk/dvisvgm/dvisvgm-src/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2024 Martin Gieseking +## Copyright (C) 2005-2025 Martin Gieseking ## ## Process this file with automake. diff --git a/texk/dvisvgm/dvisvgm-src/Makefile.in b/texk/dvisvgm/dvisvgm-src/Makefile.in index aa32d95021..44198409a9 100644 --- a/texk/dvisvgm/dvisvgm-src/Makefile.in +++ b/texk/dvisvgm/dvisvgm-src/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Thu Mar 7 12:08:01 CET 2024 +# from AX_AM_MACROS_STATIC on Sat Jan 4 12:43:26 CET 2025 VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ diff --git a/texk/dvisvgm/dvisvgm-src/NEWS b/texk/dvisvgm/dvisvgm-src/NEWS index 4ac2ea0a36..78bdd84fc7 100644 --- a/texk/dvisvgm/dvisvgm-src/NEWS +++ b/texk/dvisvgm/dvisvgm-src/NEWS @@ -1,3 +1,47 @@ +dvisvgm-3.4.3 (2025-01-04) +- fixed index error in PS operator "colorimage" (GH issue #279) +- updated bundled xxHash library to version 0.8.3 +- minor changes to the manual page + +dvisvgm-3.4.2 (2024-11-14) +- fixed evaluation of Unicode data when converting PDF files (GH issue #276) +- fixed horizontal character positioning in the PDF handler (GH issue #276) +- fixed drawing of single-colored tensor product patches +- use static creation and modification dates in TTF/WOFF fonts generated by + dvisvgm in order to prevent varying SVG output for unchanged input files + (GH issue #120) +- small improvements of the manual page + +dvisvgm-3.4.1 (2024-09-16) +- show number of page being processed when converting PDF files +- added missing #include required as of GCC 15 (GH issue #273) + +dvisvgm-3.4 (2024-07-24) +- option --embed-bitmaps is now also applied to images included with special + dvisvgm:img +- added macro {?cmyk(c,m,y,k)} to allow for directly specifying CMYK colors + in literal SVG fragments +- extended dvips color specials to distinguish between fill and stroke colors +- added color special "color set" to replace the current color without pushing + a new value onto the color stack +- added macros {?fillcolor} and {?strokecolor} to retrieve the current fill and + stroke color, respectively. Former macro {?color} equals {?fillcolor} and is + still available too +- replaced millimeter units with big point (bp) units in the message showing + the extent of generated SVG file +- fixed the detection of MIME types depending of file name suffixes +- several small code improvements + +dvisvgm-3.3 (2024-04-10) +- added file dvisvgm.map to the default font map files being looked up +- added evaluation of #include and #includefirst present in font map files +- changed conversion of CMYK colors to RGB so that the resulting colors are + now similar to those created by Ghostscript and several PDF viewers +- fixed invalid bounding boxes assigned when converting multiple DVI pages + (GH issue #268) +- fixed computation of internal Coons tensor points +- updated bundled Google Test to version 1.12.1 + dvisvgm-3.2.2 (2024-03-07) - fixed the extraction of bitmaps from PS/EPS files that no longer worked since Ghostscript 10.02.1 due to the removal of GS-specific operators diff --git a/texk/dvisvgm/dvisvgm-src/README b/texk/dvisvgm/dvisvgm-src/README index 2903e4e241..62794130e9 100644 --- a/texk/dvisvgm/dvisvgm-src/README +++ b/texk/dvisvgm/dvisvgm-src/README @@ -116,7 +116,7 @@ ADDITIONAL INFORMATION COPYRIGHT - Copyright (C) 2005-2024 Martin Gieseking + Copyright (C) 2005-2025 Martin Gieseking This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/texk/dvisvgm/dvisvgm-src/aminclude_static.am b/texk/dvisvgm/dvisvgm-src/aminclude_static.am index 027474ed26..16290387b2 100644 --- a/texk/dvisvgm/dvisvgm-src/aminclude_static.am +++ b/texk/dvisvgm/dvisvgm-src/aminclude_static.am @@ -1,6 +1,6 @@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Thu Mar 7 12:08:01 CET 2024 +# from AX_AM_MACROS_STATIC on Sat Jan 4 12:43:26 CET 2025 # Code coverage diff --git a/texk/dvisvgm/dvisvgm-src/configure.ac b/texk/dvisvgm/dvisvgm-src/configure.ac index 135bc8ae36..4bd239d115 100644 --- a/texk/dvisvgm/dvisvgm-src/configure.ac +++ b/texk/dvisvgm/dvisvgm-src/configure.ac @@ -1,11 +1,11 @@ # This file is part of dvisvgm -# Copyright (C) 2005-2024 Martin Gieseking +# Copyright (C) 2005-2025 Martin Gieseking # # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([dvisvgm],[3.2.2],[martin.gieseking@uos.de]) -DATE="March 2024" +AC_INIT([dvisvgm],[3.4.3],[martin.gieseking@uos.de]) +DATE="January 2025" AC_CONFIG_SRCDIR(src) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/texk/dvisvgm/dvisvgm-src/doc/Makefile.am b/texk/dvisvgm/dvisvgm-src/doc/Makefile.am index 575998c202..78e8cd8235 100644 --- a/texk/dvisvgm/dvisvgm-src/doc/Makefile.am +++ b/texk/dvisvgm/dvisvgm-src/doc/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2024 Martin Gieseking +## Copyright (C) 2005-2025 Martin Gieseking ## ## Process this file with automake. diff --git a/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-man.xsl b/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-man.xsl index 175f7fb962..3a3cb45ed4 100644 --- a/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-man.xsl +++ b/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-man.xsl @@ -1,6 +1,6 @@ - + diff --git a/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-pdf.xsl b/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-pdf.xsl index 0ae2632b4a..aabd5a3224 100644 --- a/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-pdf.xsl +++ b/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-pdf.xsl @@ -1,11 +1,11 @@ - + \setmainfont{Source Serif 4} \setsansfont{Source Sans 3} - \setmonofont[Scale=0.9]{Source Code Pro} + \setmonofont[Scale=0.9]{Source Code Pro Medium} 0 diff --git a/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 b/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 index 8e6814b7e6..7acb1d2803 100644 --- a/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 +++ b/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 @@ -2,12 +2,12 @@ .\" Title: dvisvgm .\" Author: Martin Gieseking .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 2024-02-04 +.\" Date: 2025-01-04 .\" Manual: dvisvgm Manual -.\" Source: dvisvgm 3.2.2 +.\" Source: dvisvgm 3.4.3 .\" Language: English .\" -.TH "DVISVGM" "1" "2024\-02\-04" "dvisvgm 3\&.2\&.2" "dvisvgm Manual" +.TH "DVISVGM" "1" "2025\-01\-04" "dvisvgm 3\&.4\&.3" "dvisvgm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -44,14 +44,14 @@ Since the current SVG standard 1\&.1 doesn\(cqt specify multi\-page graphics, dv .sp SVG is a vector\-based graphics format and therefore dvisvgm tries to convert the glyph outlines of all fonts referenced in a DVI page section to scalable path descriptions\&. The fastest way to achieve this is to extract the path information from vector\-based font files available in PFB, TTF, or OTF format\&. If dvisvgm is able to find such a file, it extracts all necessary outline information about the glyphs from it\&. .sp -However, TeX\(cqs main source for font descriptions is Metafont, which produces bitmap output (GF files)\&. That\(cqs why not all obtainable TeX fonts are available in a scalable format\&. In these cases, dvisvgm tries to vectorize Metafont\(cqs output by tracing the glyph bitmaps\&. The results are not as perfect as most (manually optimized) PFB or OTF counterparts, but are nonetheless really nice in most cases\&. +However, TeX\(cqs former main source for font descriptions is Metafont, which produces bitmap output in terms of GF files\&. That\(cqs why not all obtainable TeX fonts are available in a scalable format\&. In these cases, dvisvgm tries to vectorize Metafont\(cqs output by tracing the glyph bitmaps\&. The results are not as perfect as most (manually optimized) PFB or OTF counterparts, but are nonetheless really nice in most cases\&. .sp -When running dvisvgm without option \fB\-\-no\-fonts\fR, it creates \fIfont\fR elements (\fB\fR\&...\fB\fR) to embed the font data into the SVG files\&. Unfortunately, only few SVG renderers support these elements yet\&. Most web browsers and vector graphics applications don\(cqt evaluate them properly so that the text components of the resulting graphics might look strange\&. In order to create more compatible SVG files, command\-line option \fB\-\-no\-fonts\fR can be given to replace the font elements by plain graphics paths\&. Most web browsers (but only few external SVG renderers) also support WOFF and WOFF2 fonts that can be used instead of the default SVG fonts\&. Option \fB\-\-font\-format\fR offers the functionality to change the format applied to the fonts being embedded\&. This, however, only works when converting DVI files\&. Text present in PDF and PostScript files is always converted to path elements\&. +When running dvisvgm without option \fB\-\-no\-fonts\fR, it creates \fIfont\fR elements (\fB\fR\&...\fB\fR) to embed the font data into the SVG files\&. Unfortunately, only few SVG renderers support these elements\&. Most web browsers and vector graphics applications don\(cqt evaluate them properly so that the text components of the resulting graphics might look strange\&. In order to create more compatible SVG files, command\-line option \fB\-\-no\-fonts\fR can be given to replace the font elements by plain graphics paths\&. Most web browsers (but only few external SVG renderers) also support WOFF and WOFF2 fonts that can be used instead of the default SVG fonts\&. Option \fB\-\-font\-format\fR offers the functionality to change the format applied to the fonts being embedded\&. This, however, only works when converting DVI files\&. Text present in PDF and PostScript files is always converted to path elements\&. .SH "OPTIONS" .sp -dvisvgm provides a POSIX\-compliant command\-line interface with short and long option names\&. They may be given before and/or after the name of the file to be converted\&. Also, the order of specifying the options is not significant, i\&.e\&. you can add them in any order without changing dvisvgm\(cqs behavior\&. Certain options accept or require additional parameters which are directly appended to or separated by whitespace from a short option (e\&.g\&. \fB\-v0\fR or \fB\-v 0\fR)\&. Long options require an additional equals sign (\fB=\fR) between option name and argument but without any surrounding whitespace (e\&.g\&. \fB\-\-verbosity=0\fR)\&. Multiple short options that don\(cqt expect a further parameter can be combined after a single dash (e\&.g\&. \fB\-ejs\fR rather than \fB\-e \-j \-s\fR)\&. +dvisvgm provides a POSIX\-compliant command\-line interface with short and long option names\&. They may be given before and/or after the name of the file to be converted\&. Also, the order of specifying the options is not significant, i\&.e\&. you can add them in any order without changing dvisvgm\(cqs behavior\&. Certain options accept or require additional parameters which are directly appended to or separated by whitespace from a short option (e\&.g\&. \fB\-v0\fR or \fB\-v 0\fR)\&. Long options require an additional equals sign (\fB=\fR) between option name and argument but without any surrounding whitespace (e\&.g\&. \fB\-\-verbosity=0\fR)\&. Multiple short options that don\(cqt expect further parameters can be combined after a single dash (e\&.g\&. \fB\-ejs\fR rather than \fB\-e \-j \-s\fR)\&. .sp -Long option names may also be shortened by omitting trailing characters\&. As long as the shortened name is unambiguous, it\(cqs recognized and applied\&. For example, option \fB\-\-exact\-bbox\fR can be shortened to \fB\-\-exact\fR, \fB\-\-exa\fR, or \fB\-\-ex\fR\&. In case of an ambiguous abbreviation, dvisvgm prints an error message together with all matching option names\&. +Long option names may also be shortened by omitting trailing characters as long as the shortened name is still unambiguous\&. For example, option \fB\-\-exact\-bbox\fR can be shortened to \fB\-\-exact\fR, \fB\-\-exa\fR, or \fB\-\-ex\fR\&. In case of ambiguous abbreviations, dvisvgm prints an error message together with all matching option names\&. .PP \fB\-b, \-\-bbox\fR=\fIfmt\fR .RS 4 @@ -167,7 +167,7 @@ only affects the bounding box and does not transform the page content\&. Hence, .PP \fB\-B, \-\-bitmap\-format\fR=\fIfmt\fR .RS 4 -This option sets the image format used to embed bitmaps extracted from PostScript or PDF data\&. By default, dvisvgm embeds all bitmaps as JPEG images because it\(cqs the most compact of the two formats supported by SVG\&. To select the alternative lossless PNG format, +This option sets the image format used to embed bitmaps that are extracted from PostScript or PDF data\&. By default, dvisvgm embeds all bitmaps as JPEG images because it\(cqs the most compact of the two formats supported by SVG\&. To select the alternative lossless PNG format, \fB\-\-bitmap\-format=png\fR can be used\&. There are some more format variants dvisvgm currently supports even though \fBjpeg\fR @@ -322,8 +322,11 @@ for blue\&. If the optional argument is omitted, black is assumed\&. .RS 4 Embeds the contents of bitmap files into the generated SVG files instead of adding file references\&. Because of the base64\-encoded data, the SVG files are usually much bigger but at the same time more portable because they don\(cqt rely on external bitmap files\&. .sp -This option only affects bitmaps referenced in DVI/XDV files, e\&.g\&. added by -\fB\eincludegraphics\fR\&. Bitmaps in PostScript or PDF files are always embedded\&. Also see option +This option only affects bitmaps referenced in DVI/XDV files, e\&.g\&. by +\fB\eincludegraphics\fR +or special command +\fBdvisvgm:img\fR +(see below)\&. Bitmaps present in PostScript or PDF files are always embedded\&. Also see option \fBbitmap\-format\fR\&. .RE .PP @@ -379,6 +382,7 @@ is only available if dvisvgm was built with WOFF support enabled\&. Loads and evaluates a single font map file or a sequence of font map files\&. These files are required to resolve font file names and encodings\&. dvisvgm does not provide its own map files but tries to read available ones coming with dvips or dvipdfm\&. If option \fB\-\-fontmap\fR is omitted, dvisvgm looks for the default map files +\fIdvisvgm\&.map\fR, \fIps2pk\&.map\fR, \fIpdftex\&.map\fR, \fIdvipdfm\&.map\fR, and @@ -429,6 +433,52 @@ For further information about the map file formats and the mode specifiers, see dvips (\m[blue]https://tug.org/texinfohtml/dvips.html\m[]) and dvipdfm (\m[blue]https://ctan.org/tex-archive/dviware/dvipdfm\m[])\&. +.sp +dvisvgm supports both the +\fIdvips\fR +and the +\fIdvipdfm\fR +map file formats\&. It extends both variants by two include statements that allow for loading other map files inside a map file\&. The syntax is as follows: +.sp +.if n \{\ +.RS 4 +.\} +.nf +#include [] +#includefirst [] +.fi +.if n \{\ +.RE +.\} +.sp +They must be placed on a separate line and start at the first column of that line\&. Otherwise, they are ignored\&. While the first variant always tries to include the specified file, +\fB#includefirst\fR +is only executed once, i\&.e\&. once a file was successfully included by this statement, all subsequent +\fB#includefirst\fR +lines are skipped\&. This can be used to include one of several alternative files, whereby the first one found is loaded and all others are ignored\&. +.sp +The optional parameter +\fI\fR +(which can be +\fB+\fR, +\fB\-\fR, or +\fB=\fR) determines how to integrate the data read from the included file into the already present mapping data\&. They work the same way as the mode specifiers described above\&. If +\fI\fR +parameter is omitted, it defaults to +\fB+\fR\&. +.sp +The following filename or file path specifies the file to include\&. In case of plain filenames (without path indicators), the files are looked up using the TeX file search functionality, i\&.e\&. files in the TeX directory tree can easily be added\&. Relative paths are relative to the location of the file containing the +\fB#include\fR +statement\&. Path components must be separated by forward slashes (\fB/\fR), also on Windows systems\&. +.sp +Examples: +\fB#include pdftex\&.map\fR +looks for +\fIpdftex\&.map\fR +in the current working directory and in the TeX directory tree\&. +\fB#include \&./pdftex\&.map\fR, on the other hand, looks for +\fIpdftex\&.map\fR +only in the directory where the including file is located\&. .RE .RE .PP @@ -441,11 +491,11 @@ below)\&. By default, adjacent segments don\(cqt overlap but only touch each oth .PP \fB\-\-grad\-segments\fR=\fInumber\fR .RS 4 -Determines the maximal number of segments per column and row used to approximate gradient color fills\&. Since SVG 1\&.1 only supports a small subset of the shading algorithms available in PostScript, dvisvgm approximates some of them by subdividing the area to be filled into smaller, monochromatic segments\&. Each of these segments gets the average color of the region it covers\&. Thus, increasing the number of segments leads to smaller monochromatic areas and therefore a better approximation of the actual color gradient\&. As a drawback, more segments imply bigger SVG files because every segment is represented by a separate path element\&. +Determines the maximum number of segments per column and row used to approximate gradient color fills\&. Since SVG 1\&.1 only supports a small subset of the shading algorithms available in PostScript, dvisvgm approximates some of them by subdividing the area to be filled into smaller, monochromatic segments\&. Each of these segments gets the average color of the region it covers\&. Thus, increasing the number of segments leads to smaller monochromatic areas and therefore a better approximation of the actual color gradient\&. As a drawback, more segments imply bigger SVG files because every segment is represented by a separate path element\&. .sp Currently, dvisvgm supports free\- and lattice\-form triangular patch meshes as well as Coons and tensor\-product patch meshes\&. They are approximated by subdividing the area of each patch into a \fIn\fR\(mu\fIn\fR -grid of smaller segments\&. The maximal number of segments per column and row can be changed with option +grid of smaller segments\&. The maximum number of segments per column and row can be changed with option \fB\-\-grad\-segments\fR\&. .RE .PP @@ -556,14 +606,14 @@ Sets the magnification factor applied in conjunction with Metafont calls prior t .RS 4 Prints a given message to the console after an SVG file has been written\&. Argument \fItext\fR -may consist of static text and the macros listed below in the description of special command +may consist of static text as well as the macros listed below in the description of special command \fBdvisvgm:raw\fR\&. For example, \fB\-\-message="page {?pageno} written to {?svgfile}"\fR prints the message with the macros expanded after the conversion of each page of a DVI or PDF file or after processing an EPS file\&. .sp The output of option \fB\-\-message\fR -is not affected by the specified verbosity level, i\&.e\&. it prints the text even with +is not affected by a specified verbosity level, i\&.e\&. dvisvgm prints the text even with \fB\-\-verbosity=0\fR\&. .RE .PP @@ -812,11 +862,11 @@ converts all pages up to page 10, \fB\-\-page=10\-\fR converts all pages starting with page 10\&. Please consider that the page values don\(cqt refer to the page numbers printed on the corresponding page\&. Instead, the physical page count is expected, where the first page always gets number 1\&. .sp -At the end of the range sequence an optional filter specifier can be added\&. Currently, the two filters +At the end of the range sequence an optional filter specifier can be appended in order to remove certain page numbers from the sequence\&. Currently, the two filters \fB:even\fR and \fB:odd\fR -are supported which restrict the preceding values to even or odd numbers\&. For example, +are supported which restrict the preceding values to even and odd numbers, respectively\&. For example, \fB\-\-page=1\-11,20:even\fR is equivalent to \fB\-\-page=2,4,6,8,10,20\fR\&. @@ -920,7 +970,7 @@ and .PP \fB\-d, \-\-precision\fR=\fIdigits\fR .RS 4 -Specifies the maximal number of decimal places applied to floating\-point attribute values\&. All attribute values written to the generated SVG file(s) are rounded accordingly\&. The parameter +Specifies the maximum number of decimal places applied to floating\-point attribute values\&. All attribute values written to the generated SVG file(s) are rounded accordingly\&. The parameter \fIdigits\fR accepts integer values from 0 to 6, where 0 enables the automatic selection of significant decimal places\&. This is also the default value if dvisvgm is called without option \fB\-\-precision\fR\&. @@ -1300,6 +1350,25 @@ dvips manual (\m[blue]https://tug.org/texinfohtml/dvips.html#Color-specification \fBcolor\fR .RS 4 Statements of this command set provide instructions to change the text/paint color\&. For an overview of the exact syntax, see the documentation of dvips, for instance\&. +.sp +dvisvgm extends the dvips syntax of the color specials by two optional modifiers to enable the differentiation between fill and stroke colors, i\&.e\&. colors used to fill enclosed areas and to draw lines, respectively\&. If one of the color specifiers, like a color name or a color model followed by a sequence of color components, is preceded by +\fBfill\fR +or +\fBstroke\fR, only the corresponding color is changed\&. Without these modifiers both colors are affected\&. Example: +\fBcolor push fill rgb 1 0 1\fR +pushes a new color pair onto the color stack whereby the fill color is set to magenta and the stroke color retains its current value\&. +\fBcolor push rgb 1 0 1\fR +pushes a color pair with both colors set to magenta\&. +.sp +Additionally, the new special +\fBcolor set\fR +is introduced\&. Its syntax is the same as the one of +\fBcolor push\fR +including the optional +\fBfill\fR +and +\fBstroke\fR +modifiers\&. Instead of pushing a new color pair it modifies the topmost one on the stack\&. If the color stack is empty, the default (black) fill/stroke color is changed\&. .RE .PP \fBdvisvgm\fR @@ -1312,30 +1381,49 @@ Adds an arbitrary sequence of XML nodes to the page section of the SVG document\ \fIraw\fR specials\&. The tags themselves can also be split but must be continued with the immediately following \fIraw\fR -special\&. Both syntactically incorrect and wrongly nested tags lead to error messages\&. Parameter +special\&. Both syntactically incorrect and wrongly nested tags lead to error messages\&. +.sp +Parameter \fItext\fR may also contain the expressions \fB{?x}\fR, \fB{?y}\fR, \fB{?color}\fR, +\fB{?fillcolor}\fR, +\fB{?strokecolor}\fR, \fB{?matrix}\fR, \fB{?pageno}\fR, \fB{?svgfile}\fR, and \fB{?svgpath}\fR -that expand to the current +that respectively expand to the current \fIx\fR -or +and \fIy\fR -coordinate, the current color, the current transformation matrix, the current page number, and the relative and absolute path of the SVG file being created, respectively\&. Character sequence +coordinate, an RGB hex string of the current active fill and stroke color, the current transformation matrix, the current page number, and the relative and absolute path of the SVG file being created\&. +\fB{?color}\fR +expands to the same string as +\fB{?fillcolor}\fR +and is still available for compatibility with older dvisvgm versions that didn\(cqt distinguish between fill and stroke colors (see information about color specials below)\&. +.sp +As SVG doesn\(cqt support CMYK colors, for example in +\fBfill\fR +and +\fBstroke\fR +attributes, dvisvgm provides macro +\fB{?cmyk(\fR\fB\fIc\fR\fR\fB,\fR\fB\fIm\fR\fR\fB,\fR\fB\fIy\fR\fR\fB,\fR\fB\fIk\fR\fR\fB)}\fR +to create an RGB hex string from a CMYK color\&. It can be used instead of a combination of color/PostScript specials and color macros to directly insert a CMYK color value\&. +.sp +Character sequence \fB{?nl}\fR expands to a newline character\&. Finally, constructions of the form \fB{?(\fR\fB\fIexpr\fR\fR\fB)}\fR -enable the evaluation of mathematical expressions which may consist of basic arithmetic operations including modulo\&. Like above, the variables +enable the evaluation of mathematical expressions which may consist of basic arithmetic operations including modulo\&. As above, the variables \fIx\fR and \fIy\fR -represent the current coordinates\&. Example: -\fB{?(\-10*(x+2y)\-5)}\fR\&. +represent the current coordinates\&. Invalid operations, like divisions by zero, lead to an error message on the console\&. Example: +\fB{?(\-10*(x+2y)\-5)}\fR +is a valid expresssion and expands to the corresponding numeric string\&. .RE .PP \fBdvisvgm:rawdef\fR \fItext\fR @@ -1394,12 +1482,20 @@ portions go to the section of the current SVG document only once\&. .PP \fBdvisvgm:img\fR \fIwidth\fR \fIheight\fR \fIfile\fR .RS 4 -Creates an image element at the current graphic position referencing the given file\&. JPEG, PNG, and SVG images can be used here\&. However, dvisvgm does not check the file format or the file name suffix\&. The lengths +Creates an +\fBimage\fR +element using the current graphic position, transformation matrix, the specified extents, and the given filename\&. This special command also updates the bounding box of the resulting SVG to entirely enclose the transformed image\&. The image itself is positioned such that the lower left corner of the untransformed image lies at the current graphic position\&. The length \fIwidth\fR and \fIheight\fR -can be given together with a unit specifier (see option -\fB\-\-bbox\fR) or as plain floating point numbers\&. In the latter case, TeX point units are assumed (1in = 72\&.27pt)\&. +specify the extents of the untransformed image\&. For a list of supported length units see option +\fB\-\-bbox\fR\&. Plain numbers without an appended unit specifier imply TeX points (1in = 72\&.27pt)\&. +.sp +Parameter +\fIfile\fR +can be a plain filename or a relative or absolute path of a file\&. By default, dvisvgm just creates links referencing the image file so that the SVG renderer will evaluate the filename or path relative to the location of the generated SVG file\&. If option +\fB\-\-embed\-bitmaps\fR +is given, JPEG and PNG images are embedded into the SVG document\&. As this requires base64\-encoding of the image data, the resulting SVG files can become quite big\&. .RE .PP \fBdvisvgm:bbox\fR lock @@ -1415,7 +1511,9 @@ Unlocks the previously locked bounding box of the current page so that it gets u \fBdvisvgm:bbox\fR n[ew] \fIname\fR .RS 4 Defines or resets a local bounding box called -\fIname\fR\&. The name may consist of letters and digits\&. While processing a DVI page, dvisvgm continuously updates the (global) bounding box of the current page in order to determine the minimal rectangle containing all visible page components (characters, images, drawing elements etc\&.) Additionally to the global bounding box, the user can request an arbitrary number of named local bounding boxes\&. Once defined, these boxes are updated together with the global bounding box starting with the first character that follows the definition\&. Thus, the local boxes can be used to compute the extent of parts of the page\&. This is useful for scenarios where the generated SVG file is post\-processed\&. In conjunction with special +\fIname\fR\&. The name may consist of letters and digits\&. While processing a DVI page, dvisvgm continuously updates the (global) bounding box of the current page in order to determine the minimal rectangle containing all visible page components (characters, images, drawing elements etc\&.) Additionally to the global bounding box, the user can request an arbitrary number of named local bounding boxes\&. Once defined, these boxes are updated together with the global bounding box starting with the first character that follows the definition\&. Thus, the local boxes can be used to compute the extent of parts of the page\&. This is useful for scenarios where the generated SVG file is post\-processed\&. +.sp +In conjunction with special \fBdvisvgm:raw\fR, the macro \fB{?bbox \fR\fB\fIname\fR\fR\fB}\fR expands to the four values @@ -1443,7 +1541,9 @@ is specified, dvisvgm embeds a second rectangle (\fIx\fR, \fIheight\fR, and \fIdepth\fR can be given together with a unit specifier (see option -\fB\-\-bbox\fR) or as plain floating point numbers\&. In the latter case, TeX point units are assumed (1in = 72\&.27pt)\&. Depending on size and position of the virtual rectangle, this command either enlarges the overall bounding box or leaves it as is\&. It\(cqs not possible to reduce its extent\&. This special should be used together with +\fB\-\-bbox\fR) or as plain floating point numbers\&. In the latter case, TeX point units are assumed (1in = 72\&.27pt)\&. Depending on size and position of the virtual rectangle, this command either enlarges the overall bounding box or leaves it as is\&. So, it\(cqs not possible to reduce its extent\&. +.sp +This special is supposed to be used together with \fBdvisvgm:raw\fR in order to update the viewport of the page properly\&. By default, the box extents are assigned unchanged and, in particular, are not altered by transformation commands\&. In order to apply the current transformation matrix, the optional modifier \fBtransform\fR @@ -1486,7 +1586,7 @@ The following TeX snippet adds two raw SVG elements to the output and updates th This special works similar to option \fB\-\-currentcolor\fR but doesn\(cqt require an explicit color argument\&. Instead, it takes the currently active color and replaces it with -\fBcurrentColor\fR\&. Therefore, the result depends on the placement of the special and the preceding color changes\&. Argument +\fBcurrentColor\fR\&. Therefore, the result depends on both the placement of the special and the preceding color changes\&. Argument \fBon\fR \(en which activates the \fIcurrentColor\fR @@ -1498,10 +1598,12 @@ functionality \(en can be omitted\&. When called with argument .RS 4 Prints the given text \fImsg\fR -to the console\&. It may also contain the macros -\fI{?\&...}\fR -mentioned above (see -\fBdvisvgm:raw\fR)\&. +to the console\&. Besides static text it may also contain the macros +\fB{?\&...}\fR +mentioned in the description of +\fBdvisvgm:raw\fR\&. The messages created by this special can be suppressed with option +\fB\-\-verbosity\fR +(see above)\&. .RE .RE .PP @@ -1848,4 +1950,4 @@ Please report bugs using the bug tracker at GitHub (\m[blue]https://github.com/m Written by Martin Gieseking <\m[blue]\fBmartin\&.gieseking@uos\&.de\fR\m[]> .SH "COPYING" .sp -Copyright \(co 2005\-2024 Martin Gieseking\&. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 3 or, (at your option) any later version\&. +Copyright \(co 2005\-2025 Martin Gieseking\&. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 3 or, (at your option) any later version\&. diff --git a/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in b/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in index f055998145..f9d1822eee 100644 --- a/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in +++ b/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////// // This file is part of dvisvgm -- a fast DVI to SVG converter // -// Copyright (C) 2005-2024 Martin Gieseking // +// Copyright (C) 2005-2025 Martin Gieseking // // // // This program is free software; you can redistribute it and/or // // modify it under the terms of the GNU General Public License as // @@ -22,7 +22,7 @@ Martin Gieseking <@PACKAGE_BUGREPORT@> :man source: dvisvgm :man version: @VERSION@ :man manual: dvisvgm Manual -:revdate: 2024-02-04 15:33 +0100 +:revdate: 2025-01-04 12:28 +0100 Name ---- @@ -58,15 +58,15 @@ to achieve this is to extract the path information from vector-based font files PFB, TTF, or OTF format. If dvisvgm is able to find such a file, it extracts all necessary outline information about the glyphs from it. -However, TeX's main source for font descriptions is Metafont, which produces bitmap output -(GF files). That's why not all obtainable TeX fonts are available in a scalable format. +However, TeX's former main source for font descriptions is Metafont, which produces bitmap output +in terms of GF files. That's why not all obtainable TeX fonts are available in a scalable format. In these cases, dvisvgm tries to vectorize Metafont's output by tracing the glyph bitmaps. The results are not as perfect as most (manually optimized) PFB or OTF counterparts, but are nonetheless really nice in most cases. When running dvisvgm without option *--no-fonts*, it creates 'font' elements (++...++) to embed the font data into the SVG files. Unfortunately, only few SVG renderers support these -elements yet. Most web browsers and vector graphics applications don't evaluate them properly so +elements. Most web browsers and vector graphics applications don't evaluate them properly so that the text components of the resulting graphics might look strange. In order to create more compatible SVG files, command-line option *--no-fonts* can be given to replace the font elements by plain graphics paths. Most web browsers (but only few external SVG renderers) also support @@ -84,13 +84,13 @@ specifying the options is not significant, i.e. you can add them in any order wi dvisvgm's behavior. Certain options accept or require additional parameters which are directly appended to or separated by whitespace from a short option (e.g. +-v0+ or +-v 0+). Long options require an additional equals sign (+=+) between option name and argument but without any surrounding -whitespace (e.g. +--verbosity=0+). Multiple short options that don't expect a further parameter can +whitespace (e.g. +--verbosity=0+). Multiple short options that don't expect further parameters can be combined after a single dash (e.g. +-ejs+ rather than +-e -j -s+). -Long option names may also be shortened by omitting trailing characters. As long as the shortened -name is unambiguous, it's recognized and applied. For example, option +--exact-bbox+ can be shortened -to +--exact+, +--exa+, or +--ex+. In case of an ambiguous abbreviation, dvisvgm prints an error -message together with all matching option names. +Long option names may also be shortened by omitting trailing characters as long as the shortened +name is still unambiguous. For example, option +--exact-bbox+ can be shortened to +--exact+, ++--exa+, or +--ex+. In case of ambiguous abbreviations, dvisvgm prints an error message together +with all matching option names. *-b, --bbox*='fmt':: Sets the bounding box of the generated SVG graphic to the specified format. This option only affects @@ -141,7 +141,7 @@ Hence, if you choose a landscape format, the page won't be rotated. // *-B, --bitmap-format*='fmt':: -This option sets the image format used to embed bitmaps extracted from PostScript or PDF data. +This option sets the image format used to embed bitmaps that are extracted from PostScript or PDF data. By default, dvisvgm embeds all bitmaps as JPEG images because it's the most compact of the two formats supported by SVG. To select the alternative lossless PNG format, *--bitmap-format=png* can be used. There are some more format variants dvisvgm currently supports even though +jpeg+ and +png+ should be @@ -221,8 +221,9 @@ Embeds the contents of bitmap files into the generated SVG files instead of addi Because of the base64-encoded data, the SVG files are usually much bigger but at the same time more portable because they don't rely on external bitmap files. + -This option only affects bitmaps referenced in DVI/XDV files, e.g. added by +\includegraphics+. -Bitmaps in PostScript or PDF files are always embedded. Also see option *bitmap-format*. +This option only affects bitmaps referenced in DVI/XDV files, e.g. by +\includegraphics+ or +special command +dvisvgm:img+ (see below). Bitmaps present in PostScript or PDF files are always +embedded. Also see option *bitmap-format*. *-E, --eps*:: If this option is given, dvisvgm does not expect a DVI but a single or multiple EPS input files, @@ -264,7 +265,7 @@ Option *--font-format* is only available if dvisvgm was built with WOFF support Loads and evaluates a single font map file or a sequence of font map files. These files are required to resolve font file names and encodings. dvisvgm does not provide its own map files but tries to read available ones coming with dvips or dvipdfm. If option *--fontmap* is omitted, dvisvgm looks for the -default map files 'ps2pk.map', 'pdftex.map', 'dvipdfm.map', and 'psfonts.map' (in this order). +default map files 'dvisvgm.map', 'ps2pk.map', 'pdftex.map', 'dvipdfm.map', and 'psfonts.map' (in this order). Otherwise, the files given as option arguments are evaluated in the given order. Multiple filenames must be separated by commas without leading and/or trailing whitespace. + @@ -295,6 +296,34 @@ given in 'myfile2.map' are removed from the font map tree. + For further information about the map file formats and the mode specifiers, see the manuals of https://tug.org/texinfohtml/dvips.html[dvips] and https://ctan.org/tex-archive/dviware/dvipdfm[dvipdfm]. ++ +dvisvgm supports both the 'dvips' and the 'dvipdfm' map file formats. It extends both variants by two +include statements that allow for loading other map files inside a map file. The syntax is as follows: ++ +[listing] +---------------------------------------------- +#include [] +#includefirst [] +---------------------------------------------- ++ +They must be placed on a separate line and start at the first column of that line. Otherwise, they are ignored. +While the first variant always tries to include the specified file, +#includefirst+ is only executed once, i.e. +once a file was successfully included by this statement, all subsequent +#includefirst+ lines are skipped. +This can be used to include one of several alternative files, whereby the first one found is loaded and all +others are ignored. ++ +The optional parameter '' (which can be +pass:[+]+, +-+, or +=+) determines how to integrate the data +read from the included file into the already present mapping data. They work the same way as the mode +specifiers described above. If '' parameter is omitted, it defaults to +pass:[+]+. ++ +The following filename or file path specifies the file to include. In case of plain filenames (without path +indicators), the files are looked up using the TeX file search functionality, i.e. files in the TeX directory +tree can easily be added. Relative paths are relative to the location of the file containing the +#include+ +statement. Path components must be separated by forward slashes (+/+), also on Windows systems. ++ +Examples: +#include pdftex.map+ looks for _pdftex.map_ in the current working directory and in the +TeX directory tree. +#include ./pdftex.map+, on the other hand, looks for _pdftex.map_ only in the +directory where the including file is located. *--grad-overlap*:: Tells dvisvgm to create overlapping grid segments when approximating color gradient fills (also see @@ -311,7 +340,7 @@ may consist of multiple patches of the same type). Therefore, there still might at the seam of two adjacent patches. *--grad-segments*='number':: -Determines the maximal number of segments per column and row used to approximate gradient color fills. +Determines the maximum number of segments per column and row used to approximate gradient color fills. Since SVG 1.1 only supports a small subset of the shading algorithms available in PostScript, dvisvgm approximates some of them by subdividing the area to be filled into smaller, monochromatic segments. Each of these segments gets the average color of the region it covers. Thus, increasing the @@ -321,7 +350,7 @@ represented by a separate path element. + Currently, dvisvgm supports free- and lattice-form triangular patch meshes as well as Coons and tensor-product patch meshes. They are approximated by subdividing the area of each patch into a -__n__×__n__ grid of smaller segments. The maximal number of segments per column and row can be +__n__×__n__ grid of smaller segments. The maximum number of segments per column and row can be changed with option *--grad-segments*. *--grad-simplify*='delta':: @@ -395,11 +424,11 @@ The default setting usually produces nice results. *--message*='text':: Prints a given message to the console after an SVG file has been written. Argument 'text' may consist -of static text and the macros listed below in the description of special command +dvisvgm:raw+. +of static text as well as the macros listed below in the description of special command +dvisvgm:raw+. For example, +--message="page {?pageno} written to {?svgfile}"+ prints the message with the macros expanded after the conversion of each page of a DVI or PDF file or after processing an EPS file. + -The output of option *--message* is not affected by the specified verbosity level, i.e. it prints +The output of option *--message* is not affected by a specified verbosity level, i.e. dvisvgm prints the text even with +--verbosity=0+. *--no-merge*:: @@ -547,9 +576,10 @@ Please consider that the page values don't refer to the page numbers printed on corresponding page. Instead, the physical page count is expected, where the first page always gets number 1. + -At the end of the range sequence an optional filter specifier can be added. Currently, the two -filters +:even+ and +:odd+ are supported which restrict the preceding values to even or odd -numbers. For example, +--page=1-11,20:even+ is equivalent to +--page=2,4,6,8,10,20+. +At the end of the range sequence an optional filter specifier can be appended in order to remove +certain page numbers from the sequence. Currently, the two filters +:even+ and +:odd+ are supported +which restrict the preceding values to even and odd numbers, respectively. For example, ++--page=1-11,20:even+ is equivalent to +--page=2,4,6,8,10,20+. *-H, --page-hashes*[='params']:: If this option is given, dvisvgm computes hash values of all pages to be processed. As long as the @@ -614,7 +644,7 @@ Alternatively, environment variable +DVISVGM_PDF_PROC+ can be used to select the The currently supported values are +gs+ and +mutool+. *-d, --precision*='digits':: -Specifies the maximal number of decimal places applied to floating-point attribute values. +Specifies the maximum number of decimal places applied to floating-point attribute values. All attribute values written to the generated SVG file(s) are rounded accordingly. The parameter 'digits' accepts integer values from 0 to 6, where 0 enables the automatic selection of significant decimal places. This is also the default value if dvisvgm is called without @@ -814,94 +844,126 @@ the user turn it off. *color*:: Statements of this command set provide instructions to change the text/paint color. For an overview of the exact syntax, see the documentation of dvips, for instance. ++ +dvisvgm extends the dvips syntax of the color specials by two optional modifiers to enable the differentiation +between fill and stroke colors, i.e. colors used to fill enclosed areas and to draw lines, respectively. +If one of the color specifiers, like a color name or a color model followed by a sequence of color components, +is preceded by +fill+ or +stroke+, only the corresponding color is changed. Without these modifiers both colors +are affected. Example: +color push fill rgb 1 0 1+ pushes a new color pair onto the color stack whereby the fill +color is set to magenta and the stroke color retains its current value. ++color push rgb 1 0 1+ pushes a color pair with both colors set to magenta. ++ +Additionally, the new special *color set* is introduced. Its syntax is the same as the one of *color push* +including the optional +fill+ and +stroke+ modifiers. Instead of pushing a new color pair it modifies the +topmost one on the stack. If the color stack is empty, the default (black) fill/stroke color is changed. *dvisvgm*:: The following list gives a brief overview of dvisvgm's own set of currently supported specials. -*dvisvgm:raw* 'text';; - Adds an arbitrary sequence of XML nodes to the page section of the SVG document. dvisvgm checks syntax and - proper nesting of the inserted elements but does not perform any validation, thus the user has to ensure - that the resulting SVG is still valid. Opening and closing tags may be distributed among different 'raw' - specials. The tags themselves can also be split but must be continued with the immediately following 'raw' - special. Both syntactically incorrect and wrongly nested tags lead to error messages. - Parameter 'text' may also contain the expressions *{?x}*, *{?y}*, *{?color}*, *{?matrix}*, *{?pageno}*, - *{?svgfile}*, and *{?svgpath}* that expand to the current 'x' or 'y' coordinate, the current color, the - current transformation matrix, the current page number, and the relative and absolute path of the SVG file - being created, respectively. - Character sequence *{?nl}* expands to a newline character. Finally, constructions of the form *{?(__expr__)}* - enable the evaluation of mathematical expressions which may consist of basic arithmetic operations including - modulo. Like above, the variables 'x' and 'y' represent the current coordinates. - Example: +{?(-10*(x+2y)-5)}+. - - *dvisvgm:rawdef* 'text';; - This command is similar to *dvisvgm:raw*, but puts the XML nodes into the section of the SVG document - currently being generated. - - *dvisvgm:rawset* 'name' ... *dvisvgm:endrawset*;; - This pair of specials marks the begin and end of a definition of a named raw SVG fragment. All *dvisvgm:raw* - and *dvisvgm:rawdef* specials enclosed by *dvisvgm:rawset* and *dvisvgm:endrawset* are not evaluated - immediately but stored together under the given 'name' for later use. Once defined, the named fragment can be - referenced throughout the DVI file by *dvisvgm:rawput* (see below). - The two commands *dvisvgm:rawset* and *dvisvgm:endrawset* must not be nested, i.e. each call of *dvisvgm:rawset* - has to be followed by a corresponding call of *dvisvgm:endrawset* before another *dvisvgm:rawset* may occur. - Also, the identifier 'name' must be unique throughout the DVI file. Using *dvisvgm:rawset* multiple times - together with the same 'name' leads to warning messages. - - *dvisvgm:rawput* 'name';; - Inserts raw SVG fragments previously stored under the given 'name'. dvisvgm distinguishes between fragments - that were specified with *dvisvgm:raw* or *dvisvgm:rawdef*, and handles them differently: It inserts all - *dvisvgm:raw* parts every time *dvisvgm:rawput* is called, whereas the *dvisvgm:rawdef* portions go to the - section of the current SVG document only once. - - *dvisvgm:img* 'width' 'height' 'file';; - Creates an image element at the current graphic position referencing the given file. JPEG, PNG, and SVG images - can be used here. However, dvisvgm does not check the file format or the file name suffix. The lengths 'width' - and 'height' can be given together with a unit specifier (see option *--bbox*) or as plain floating point numbers. - In the latter case, TeX point units are assumed (1in = 72.27pt). - - *dvisvgm:bbox* lock;; - Locks the bounding box of the current page and prevents it from further updating, i.e. graphics elements added - after calling this special are not taken into account in determining the extent of the bounding box. - - *dvisvgm:bbox* unlock;; - Unlocks the previously locked bounding box of the current page so that it gets updated again when adding - graphics elements to the page. - - *dvisvgm:bbox* n[ew] 'name';; - Defines or resets a local bounding box called 'name'. The name may consist of letters and digits. - While processing a DVI page, dvisvgm continuously updates the (global) bounding box of the current page in order to - determine the minimal rectangle containing all visible page components (characters, images, drawing elements etc.) - Additionally to the global bounding box, the user can request an arbitrary number of named local bounding boxes. - Once defined, these boxes are updated together with the global bounding box starting with the first character that - follows the definition. Thus, the local boxes can be used to compute the extent of parts of the page. This is useful - for scenarios where the generated SVG file is post-processed. - In conjunction with special *dvisvgm:raw*, the macro *{?bbox 'name'}* expands to the four values 'x', 'y', 'w', and 'h' - (separated by spaces) specifying the coordinates of the upper left corner, width, and height of the local box 'name'. - If box 'name' wasn't previously defined, all four values equal to zero. - - *dvisvgm:bbox* 'width' 'height' ['depth'] [+transform+];; - Updates the bounding box of the current page by embedding a virtual rectangle ('x', 'y', 'width', 'height') - where the lower left corner is located at the current DVI drawing position ('x','y'). If the optional parameter 'depth' - is specified, dvisvgm embeds a second rectangle ('x', 'y', 'width', -__depth__). The lengths 'width', 'height', and - 'depth' can be given together with a unit specifier (see option *--bbox*) or as plain floating point numbers. - In the latter case, TeX point units are assumed (1in = 72.27pt). Depending on size and position of the virtual rectangle, - this command either enlarges the overall bounding box or leaves it as is. It's not possible to reduce its extent. This - special should be used together with *dvisvgm:raw* in order to update the viewport of the page properly. - By default, the box extents are assigned unchanged and, in particular, are not altered by transformation commands. - In order to apply the current transformation matrix, the optional modifier +transform+ can be added at the end of - the special statement. - - *dvisvgm:bbox* a[bs] 'x1' 'y1' 'x2' 'y2' [+transform+];; - This variant of the bbox special updates the bounding box by embedding a virtual rectangle ('x1','y1','x2','y2'). - The points ('x1','y1') and ('x2','y2') denote the absolute coordinates of two diagonal corners of the rectangle. - As with the relative special variant described above, the optional modifier +transform+ allows for applying the - current transformation matrix to the bounding box. - - *dvisvgm:bbox* f[ix] 'x1' 'y1' 'x2' 'y2' [+transform+];; - This variant of the bbox special assigns an absolute (final) bounding box to the resulting SVG. After executing - this command, dvisvgm doesn't further alter the bounding box coordinates, except this special is called again later. - The points ('x1','y1') and ('x2','y2') denote the absolute coordinates of two diagonal corners of the rectangle. - As with the relative special variant described above, the optional modifier +transform+ allows for applying the - current transformation matrix to the bounding box. + +*dvisvgm:raw* 'text'::: +Adds an arbitrary sequence of XML nodes to the page section of the SVG document. dvisvgm checks syntax and +proper nesting of the inserted elements but does not perform any validation, thus the user has to ensure +that the resulting SVG is still valid. Opening and closing tags may be distributed among different 'raw' +specials. The tags themselves can also be split but must be continued with the immediately following 'raw' +special. Both syntactically incorrect and wrongly nested tags lead to error messages. ++ +Parameter 'text' may also contain the expressions *{?x}*, *{?y}*, *{?color}*, *{?fillcolor}*, *{?strokecolor}*, +*{?matrix}*, *{?pageno}*, *{?svgfile}*, and *{?svgpath}* that respectively expand to the current 'x' and 'y' +coordinate, an RGB hex string of the current active fill and stroke color, the current transformation matrix, +the current page number, and the relative and absolute path of the SVG file being created. *{?color}* expands +to the same string as *{?fillcolor}* and is still available for compatibility with older dvisvgm versions that +didn't distinguish between fill and stroke colors (see information about color specials below). ++ +As SVG doesn't support CMYK colors, for example in +fill+ and +stroke+ attributes, dvisvgm provides macro +*{?cmyk(_c_,_m_,_y_,_k_)}* to create an RGB hex string from a CMYK color. It can be used instead of +a combination of color/PostScript specials and color macros to directly insert a CMYK color value. ++ +Character sequence *{?nl}* expands to a newline character. Finally, constructions of the form *{?(_expr_)}* +enable the evaluation of mathematical expressions which may consist of basic arithmetic operations including +modulo. As above, the variables 'x' and 'y' represent the current coordinates. +Invalid operations, like divisions by zero, lead to an error message on the console. +Example: +{?(-10*(x+2y)-5)}+ is a valid expresssion and expands to the corresponding numeric string. + +*dvisvgm:rawdef* 'text'::: +This command is similar to *dvisvgm:raw*, but puts the XML nodes into the section of the SVG document +currently being generated. + +*dvisvgm:rawset* 'name' ... *dvisvgm:endrawset*::: +This pair of specials marks the begin and end of a definition of a named raw SVG fragment. All *dvisvgm:raw* +and *dvisvgm:rawdef* specials enclosed by *dvisvgm:rawset* and *dvisvgm:endrawset* are not evaluated +immediately but stored together under the given 'name' for later use. Once defined, the named fragment can be +referenced throughout the DVI file by *dvisvgm:rawput* (see below). +The two commands *dvisvgm:rawset* and *dvisvgm:endrawset* must not be nested, i.e. each call of *dvisvgm:rawset* +has to be followed by a corresponding call of *dvisvgm:endrawset* before another *dvisvgm:rawset* may occur. +Also, the identifier 'name' must be unique throughout the DVI file. Using *dvisvgm:rawset* multiple times +together with the same 'name' leads to warning messages. + +*dvisvgm:rawput* 'name'::: +Inserts raw SVG fragments previously stored under the given 'name'. dvisvgm distinguishes between fragments +that were specified with *dvisvgm:raw* or *dvisvgm:rawdef*, and handles them differently: It inserts all +*dvisvgm:raw* parts every time *dvisvgm:rawput* is called, whereas the *dvisvgm:rawdef* portions go to the + section of the current SVG document only once. + +*dvisvgm:img* 'width' 'height' 'file'::: +Creates an +image+ element using the current graphic position, transformation matrix, the specified extents, +and the given filename. This special command also updates the bounding box of the resulting SVG to entirely +enclose the transformed image. The image itself is positioned such that the lower left corner of the +untransformed image lies at the current graphic position. The length 'width' and 'height' specify the extents +of the untransformed image. For a list of supported length units see option *--bbox*. Plain numbers without an +appended unit specifier imply TeX points (1in = 72.27pt). ++ +Parameter 'file' can be a plain filename or a relative or absolute path of a file. By default, dvisvgm just +creates links referencing the image file so that the SVG renderer will evaluate the filename or path relative +to the location of the generated SVG file. If option *--embed-bitmaps* is given, JPEG and PNG images are +embedded into the SVG document. As this requires base64-encoding of the image data, the resulting SVG files +can become quite big. + +*dvisvgm:bbox* lock::: +Locks the bounding box of the current page and prevents it from further updating, i.e. graphics elements added +after calling this special are not taken into account in determining the extent of the bounding box. + +*dvisvgm:bbox* unlock::: +Unlocks the previously locked bounding box of the current page so that it gets updated again when adding +graphics elements to the page. + +*dvisvgm:bbox* n[ew] 'name'::: +Defines or resets a local bounding box called 'name'. The name may consist of letters and digits. +While processing a DVI page, dvisvgm continuously updates the (global) bounding box of the current page in order to +determine the minimal rectangle containing all visible page components (characters, images, drawing elements etc.) +Additionally to the global bounding box, the user can request an arbitrary number of named local bounding boxes. +Once defined, these boxes are updated together with the global bounding box starting with the first character that +follows the definition. Thus, the local boxes can be used to compute the extent of parts of the page. This is useful +for scenarios where the generated SVG file is post-processed. ++ +In conjunction with special *dvisvgm:raw*, the macro *{?bbox 'name'}* expands to the four values 'x', 'y', 'w', and 'h' +(separated by spaces) specifying the coordinates of the upper left corner, width, and height of the local box 'name'. +If box 'name' wasn't previously defined, all four values equal to zero. + +*dvisvgm:bbox* 'width' 'height' ['depth'] [+transform+]::: +Updates the bounding box of the current page by embedding a virtual rectangle ('x', 'y', 'width', 'height') +where the lower left corner is located at the current DVI drawing position ('x','y'). If the optional parameter 'depth' +is specified, dvisvgm embeds a second rectangle ('x', 'y', 'width', -__depth__). The lengths 'width', 'height', and +'depth' can be given together with a unit specifier (see option *--bbox*) or as plain floating point numbers. +In the latter case, TeX point units are assumed (1in = 72.27pt). Depending on size and position of the virtual rectangle, +this command either enlarges the overall bounding box or leaves it as is. So, it's not possible to reduce its extent. ++ +This special is supposed to be used together with *dvisvgm:raw* in order to update the viewport of the page properly. +By default, the box extents are assigned unchanged and, in particular, are not altered by transformation commands. +In order to apply the current transformation matrix, the optional modifier +transform+ can be added at the end of +the special statement. + +*dvisvgm:bbox* a[bs] 'x1' 'y1' 'x2' 'y2' [+transform+]::: +This variant of the bbox special updates the bounding box by embedding a virtual rectangle ('x1','y1','x2','y2'). +The points ('x1','y1') and ('x2','y2') denote the absolute coordinates of two diagonal corners of the rectangle. +As with the relative special variant described above, the optional modifier +transform+ allows for applying the +current transformation matrix to the bounding box. + +*dvisvgm:bbox* f[ix] 'x1' 'y1' 'x2' 'y2' [+transform+]::: +This variant of the bbox special assigns an absolute (final) bounding box to the resulting SVG. After executing +this command, dvisvgm doesn't further alter the bounding box coordinates, except this special is called again later. +The points ('x1','y1') and ('x2','y2') denote the absolute coordinates of two diagonal corners of the rectangle. +As with the relative special variant described above, the optional modifier +transform+ allows for applying the +current transformation matrix to the bounding box. + The following TeX snippet adds two raw SVG elements to the output and updates the bounding box accordingly: + @@ -914,16 +976,17 @@ The following TeX snippet adds two raw SVG elements to the output and updates th \special{dvisvgm:raw }% \special{dvisvgm:bbox abs 10bp 200bp 100bp 250bp transform} ------------------------------------------------------------------------------------- -+ - *dvisvgm:currentcolor* [on|off];; - This special works similar to option `--currentcolor` but doesn't require an explicit color argument. Instead, - it takes the currently active color and replaces it with `currentColor`. Therefore, the result depends on the - placement of the special and the preceding color changes. Argument `on` – which activates the 'currentColor' - functionality – can be omitted. When called with argument `off`, the functionality is deactivated again. - *dvisvgm:message* 'msg';; - Prints the given text 'msg' to the console. It may also contain the macros '{?...}' mentioned above - (see *dvisvgm:raw*). +*dvisvgm:currentcolor* [on|off]::: +This special works similar to option `--currentcolor` but doesn't require an explicit color argument. Instead, +it takes the currently active color and replaces it with `currentColor`. Therefore, the result depends on both the +placement of the special and the preceding color changes. Argument `on` – which activates the 'currentColor' +functionality – can be omitted. When called with argument `off`, the functionality is deactivated again. + +*dvisvgm:message* 'msg'::: +Prints the given text 'msg' to the console. Besides static text it may also contain the macros +{?...}+ mentioned +in the description of *dvisvgm:raw*. The messages created by this special can be suppressed with option +*--verbosity* (see above). *em*:: These specials were introduced with the 'emTeX' distribution by Eberhard Mattes. They provide line drawing @@ -1107,7 +1170,7 @@ Written by {author} <{email}> Copying ------- -Copyright (C) 2005-2024 Martin Gieseking. Free use of this software is +Copyright (C) 2005-2025 Martin Gieseking. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 3 or, (at your option) any later version. diff --git a/texk/dvisvgm/dvisvgm-src/doc/tweak-db-refentry.xsl b/texk/dvisvgm/dvisvgm-src/doc/tweak-db-refentry.xsl index 942d35dd72..8f3a78bb3f 100644 --- a/texk/dvisvgm/dvisvgm-src/doc/tweak-db-refentry.xsl +++ b/texk/dvisvgm/dvisvgm-src/doc/tweak-db-refentry.xsl @@ -1,6 +1,6 @@ - + - + diff --git a/texk/dvisvgm/dvisvgm-src/libs/Makefile.am b/texk/dvisvgm/dvisvgm-src/libs/Makefile.am index a0c8361610..b9e08412c1 100644 --- a/texk/dvisvgm/dvisvgm-src/libs/Makefile.am +++ b/texk/dvisvgm/dvisvgm-src/libs/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2024 Martin Gieseking +## Copyright (C) 2005-2025 Martin Gieseking ## ## Process this file with automake. diff --git a/texk/dvisvgm/dvisvgm-src/libs/defs.am b/texk/dvisvgm/dvisvgm-src/libs/defs.am index 8383a36cbe..072f67f0cf 100644 --- a/texk/dvisvgm/dvisvgm-src/libs/defs.am +++ b/texk/dvisvgm/dvisvgm-src/libs/defs.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2024 Martin Gieseking +## Copyright (C) 2005-2025 Martin Gieseking if !HAVE_BROTLI BROTLI_CFLAGS += -I$(dvisvgm_srcdir)/libs/brotli/include diff --git a/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c b/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c index 083b039d70..e60cc37f13 100644 --- a/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c +++ b/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c @@ -1,6 +1,6 @@ /* * xxHash - Extremely Fast Hash algorithm - * Copyright (C) 2012-2021 Yann Collet + * Copyright (C) 2012-2023 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -32,12 +32,11 @@ * - xxHash source repository: https://github.com/Cyan4973/xxHash */ - /* * xxhash.c instantiates functions defined in xxhash.h */ -#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */ -#define XXH_IMPLEMENTATION /* access definitions */ +#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */ +#define XXH_IMPLEMENTATION /* access definitions */ #include "xxhash.h" diff --git a/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h b/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h index a18e8c762d..78fc2e8dbf 100644 --- a/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h +++ b/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (C) 2012-2021 Yann Collet + * Copyright (C) 2012-2023 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -130,6 +130,7 @@ * } * @endcode * + * * @anchor streaming_example * **Streaming** * @@ -165,6 +166,77 @@ * } * @endcode * + * Streaming functions generate the xxHash value from an incremental input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + * + * + * @anchor canonical_representation_example + * **Canonical Representation** + * + * The default return values from XXH functions are unsigned 32, 64 and 128 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + * + * XXH32_canonicalFromHash(), XXH32_hashFromCanonical(), + * XXH64_canonicalFromHash(), XXH64_hashFromCanonical(), + * XXH128_canonicalFromHash(), XXH128_hashFromCanonical(), + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which prints XXH32_hash_t in human readable format + * void printXxh32(XXH32_hash_t hash) + * { + * XXH32_canonical_t cano; + * XXH32_canonicalFromHash(&cano, hash); + * size_t i; + * for(i = 0; i < sizeof(cano.digest); ++i) { + * printf("%02x", cano.digest[i]); + * } + * printf("\n"); + * } + * + * // Example for a function which converts XXH32_canonical_t to XXH32_hash_t + * XXH32_hash_t convertCanonicalToXxh32(XXH32_canonical_t cano) + * { + * XXH32_hash_t hash = XXH32_hashFromCanonical(&cano); + * return hash; + * } + * @endcode + * + * * @file xxhash.h * xxHash prototypes and implementation */ @@ -261,7 +333,7 @@ extern "C" { /* make all functions private */ # undef XXH_PUBLIC_API # if defined(__GNUC__) -# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# define XXH_PUBLIC_API static __inline __attribute__((__unused__)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # define XXH_PUBLIC_API static inline # elif defined(_MSC_VER) @@ -373,7 +445,7 @@ extern "C" { /*! @brief Marks a global symbol. */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -449,7 +521,7 @@ extern "C" { /* specific declaration modes for Windows */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -461,9 +533,9 @@ extern "C" { #endif #if defined (__GNUC__) -# define XXH_CONSTF __attribute__((const)) -# define XXH_PUREF __attribute__((pure)) -# define XXH_MALLOCF __attribute__((malloc)) +# define XXH_CONSTF __attribute__((__const__)) +# define XXH_PUREF __attribute__((__pure__)) +# define XXH_MALLOCF __attribute__((__malloc__)) #else # define XXH_CONSTF /* disable */ # define XXH_PUREF @@ -475,7 +547,7 @@ extern "C" { ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 8 -#define XXH_VERSION_RELEASE 2 +#define XXH_VERSION_RELEASE 3 /*! @brief Version number, encoded as two digits each */ #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) @@ -517,7 +589,11 @@ typedef uint32_t XXH32_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint32_t XXH32_hash_t; #else @@ -551,10 +627,6 @@ typedef uint32_t XXH32_hash_t; /*! * @brief Calculates the 32-bit hash of @p input using xxHash32. * - * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s - * - * See @ref single_shot_example "Single Shot Example" for an example. - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 32-bit seed to alter the hash's output predictably. @@ -564,63 +636,44 @@ typedef uint32_t XXH32_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 32-bit hash value. + * @return The calculated 32-bit xxHash32 value. * - * @see - * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); #ifndef XXH_NO_STREAM -/*! - * Streaming functions generate the xxHash value from an incremental input. - * This method is slower than single-call functions, due to state management. - * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. - * - * An XXH state must first be allocated using `XXH*_createState()`. - * - * Start a new hash by initializing the state with a seed using `XXH*_reset()`. - * - * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. - * - * The function returns an error code, with 0 meaning OK, and any other value - * meaning there is an error. - * - * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. - * This function returns the nn-bits hash as an int or long long. - * - * It's still possible to continue inserting input into the hash state after a - * digest, and generate new hash values later on by invoking `XXH*_digest()`. - * - * When done, release the state using `XXH*_freeState()`. - * - * @see streaming_example at the top of @ref xxhash.h for an example. - */ - /*! * @typedef struct XXH32_state_s XXH32_state_t * @brief The opaque state struct for the XXH32 streaming API. * * @see XXH32_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH32_state_s XXH32_state_t; /*! * @brief Allocates an @ref XXH32_state_t. * - * Must be freed with XXH32_freeState(). - * @return An allocated XXH32_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH32_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH32_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void); /*! * @brief Frees an @ref XXH32_state_t. * - * Must be allocated with XXH32_createState(). * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH32_createState(). + * + * @see @ref streaming_example "Streaming Example" + * */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); /*! @@ -636,23 +689,24 @@ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_ /*! * @brief Resets an @ref XXH32_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH32_update(). - * * @param statePtr The state struct to reset. * @param seed The 32-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH32_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH32_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -664,48 +718,36 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH32_state_t. * - * @note - * Calling XXH32_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash32 value from that state. + * @return The calculated 32-bit xxHash32 value from that state. + * + * @note + * Calling XXH32_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/* - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * This the simplest and fastest format for further post-processing. - * - * However, this leaves open the question of what is the order on the byte level, - * since little and big endian conventions will store the same number differently. - * - * The canonical representation settles this issue by mandating big-endian - * convention, the same convention as human-readable numbers (large digits first). - * - * When writing hash values to storage, sending them over a network, or printing - * them, it's highly recommended to use the canonical representation to ensure - * portability across a wider range of systems, present and future. - * - * The following functions allow transformation of hash values to and from - * canonical format. - */ - /*! * @brief Canonical (big endian) representation of @ref XXH32_hash_t. */ @@ -716,11 +758,13 @@ typedef struct { /*! * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t. * - * @param dst The @ref XXH32_canonical_t pointer to be stored to. + * @param dst The @ref XXH32_canonical_t pointer to be stored to. * @param hash The @ref XXH32_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); @@ -733,6 +777,8 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); @@ -794,7 +840,7 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni * As of writing this, only supported by clang. */ #if XXH_HAS_ATTRIBUTE(noescape) -# define XXH_NOESCAPE __attribute__((noescape)) +# define XXH_NOESCAPE __attribute__((__noescape__)) #else # define XXH_NOESCAPE #endif @@ -821,7 +867,11 @@ typedef uint64_t XXH64_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint64_t XXH64_hash_t; #else # include @@ -851,9 +901,6 @@ typedef uint64_t XXH64_hash_t; /*! * @brief Calculates the 64-bit hash of @p input using xxHash64. * - * This function usually runs faster on 64-bit systems, but slower on 32-bit - * systems (see benchmark). - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 64-bit seed to alter the hash's output predictably. @@ -863,13 +910,9 @@ typedef uint64_t XXH64_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 64-bit hash. + * @return The calculated 64-bit xxHash64 value. * - * @see - * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -879,23 +922,32 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size * @brief The opaque state struct for the XXH64 streaming API. * * @see XXH64_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ /*! * @brief Allocates an @ref XXH64_state_t. * - * Must be freed with XXH64_freeState(). - * @return An allocated XXH64_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH64_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH64_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void); /*! * @brief Frees an @ref XXH64_state_t. * - * Must be allocated with XXH64_createState(). * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH64_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); @@ -912,23 +964,24 @@ XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const /*! * @brief Resets an @ref XXH64_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH64_update(). - * * @param statePtr The state struct to reset. * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH64_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH64_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -940,23 +993,30 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH64_state_t. * - * @note - * Calling XXH64_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash64 value from that state. + * @return The calculated 64-bit xxHash64 value from that state. + * + * @note + * Calling XXH64_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -975,6 +1035,8 @@ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash); @@ -987,6 +1049,8 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src); @@ -1046,40 +1110,74 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const * * The API supports one-shot hashing, streaming mode, and custom secrets. */ + +/*! + * @ingroup tuning + * @brief Possible values for @ref XXH_VECTOR. + * + * Unless set explicitly, determined automatically. + */ +# define XXH_SCALAR 0 /*!< Portable scalar version */ +# define XXH_SSE2 1 /*!< SSE2 for Pentium 4, Opteron, all x86_64. */ +# define XXH_AVX2 2 /*!< AVX2 for Haswell and Bulldozer */ +# define XXH_AVX512 3 /*!< AVX512 for Skylake and Icelake */ +# define XXH_NEON 4 /*!< NEON for most ARMv7-A, all AArch64, and WASM SIMD128 */ +# define XXH_VSX 5 /*!< VSX and ZVector for POWER8/z13 (64-bit) */ +# define XXH_SVE 6 /*!< SVE for some ARMv8-A and ARMv9-A */ +# define XXH_LSX 7 /*!< LSX (128-bit SIMD) for LoongArch64 */ + + /*-********************************************************************** * XXH3 64-bit variant ************************************************************************/ /*! - * @brief 64-bit unseeded variant of XXH3. + * @brief Calculates 64-bit unseeded variant of XXH3 hash of @p input. * - * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however - * it may have slightly better performance due to constant propagation of the - * defaults. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. * - * @see - * XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms * @see * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants - * @see - * XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length); /*! - * @brief 64-bit seeded variant of XXH3 + * @brief Calculates 64-bit seeded variant of XXH3 hash of @p input. * - * This variant generates a custom secret on the fly based on default secret - * altered using the `seed` value. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. * - * While this operation is decently fast, note that it's not completely free. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. * * @note * seed == 0 produces the same results as @ref XXH3_64bits(). * - * @param input The data to hash - * @param length The length - * @param seed The 64-bit seed to alter the state. + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -1093,22 +1191,36 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const vo #define XXH3_SECRET_SIZE_MIN 136 /*! - * @brief 64-bit variant of XXH3 with a custom "secret". + * @brief Calculates 64-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. * * It's possible to provide any blob of bytes as a "secret" to generate the hash. * This makes it more difficult for an external actor to prepare an intentional collision. - * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). * However, the quality of the secret impacts the dispersion of the hash algorithm. * Therefore, the secret _must_ look like a bunch of random bytes. * Avoid "trivial" or structured data such as repeated sequences or a text document. * Whenever in doubt about the "randomness" of the blob of bytes, - * consider employing "XXH3_generateSecret()" instead (see below). + * consider employing @ref XXH3_generateSecret() instead (see below). * It will generate a proper high entropy secret derived from the blob of bytes. * Another advantage of using XXH3_generateSecret() is that * it guarantees that all bits within the initial blob of bytes * will impact every bit of the output. * This is not necessarily the case when using the blob of bytes directly * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); @@ -1123,9 +1235,10 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const */ /*! - * @brief The state struct for the XXH3 streaming API. + * @brief The opaque state struct for the XXH3 streaming API. * * @see XXH3_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH3_state_s XXH3_state_t; XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void); @@ -1144,15 +1257,20 @@ XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOE /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); @@ -1160,36 +1278,54 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* stateP /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits_withSeed()`. - * * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); /*! - * XXH3_64bits_reset_withSecret(): - * `secret` is referenced, it _must outlive_ the hash streaming session. - * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * `secret` is referenced, it _must outlive_ the hash streaming session. + * + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, * and the quality of produced hash values depends on secret's entropy * (secret's content should look like a bunch of random bytes). * When in doubt about the randomness of a candidate `secret`, * consider employing `XXH3_generateSecret()` instead (see below). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! * @brief Consumes a block of @p input to an @ref XXH3_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -1201,23 +1337,30 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_stat * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 64-bit hash value from that state. + * + * @note + * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1242,26 +1385,71 @@ typedef struct { } XXH128_hash_t; /*! - * @brief Unseeded 128-bit variant of XXH3 + * @brief Calculates 128-bit unseeded variant of XXH3 of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. * * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead * for shorter inputs. * - * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0, however + * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of `0`, however * it may have slightly better performance due to constant propagation of the * defaults. * - * @see - * XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms - * @see - * XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants - * @see - * XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version. + * @see XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len); -/*! @brief Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */ +/*! @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see XXH3_128bits(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */ +/*! + * @brief Calculates 128-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing @ref XXH3_generateSecret() instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ @@ -1281,36 +1469,65 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE cons /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits()`. * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits_withSeed()`. + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. * - * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). * + * @see @ref streaming_example "Streaming Example" */ -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH_64bits_reset_withSecret(). */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! @@ -1324,28 +1541,32 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_sta * * @pre * @p statePtr must not be `NULL`. - * @pre + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note * The memory between @p input and @p input + @p length must be valid, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 128-bit hash value from that state. + * + * @note + * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1355,18 +1576,27 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const X * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ /*! - * XXH128_isEqual(): - * Return: 1 if `h1` and `h2` are equal, 0 if they are not. + * @brief Check equality of two XXH128_hash_t values + * + * @param h1 The 128-bit hash value. + * @param h2 Another 128-bit hash value. + * + * @return `1` if `h1` and `h2` are equal. + * @return `0` if they are not. */ XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); /*! * @brief Compares two @ref XXH128_hash_t + * * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. * - * @return: >0 if *h128_1 > *h128_2 - * =0 if *h128_1 == *h128_2 - * <0 if *h128_1 < *h128_2 + * @param h128_1 Left-hand side value + * @param h128_2 Right-hand side value + * + * @return >0 if @p h128_1 > @p h128_2 + * @return =0 if @p h128_1 == @p h128_2 + * @return <0 if @p h128_1 < @p h128_2 */ XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2); @@ -1378,11 +1608,12 @@ typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical /*! * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t. * - * @param dst The @ref XXH128_canonical_t pointer to be stored to. + * @param dst The @ref XXH128_canonical_t pointer to be stored to. * @param hash The @ref XXH128_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash); @@ -1395,6 +1626,7 @@ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* ds * @p src must not be `NULL`. * * @return The converted hash. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src); @@ -1440,9 +1672,9 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE con struct XXH32_state_s { XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */ XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */ - XXH32_hash_t v[4]; /*!< Accumulator lanes */ - XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */ + XXH32_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[16]; /*!< Internal buffer for partial reads. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */ }; /* typedef'd to XXH32_state_t */ @@ -1463,9 +1695,9 @@ struct XXH32_state_s { */ struct XXH64_state_s { XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */ - XXH64_hash_t v[4]; /*!< Accumulator lanes */ - XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */ + XXH64_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[32]; /*!< Internal buffer for partial reads.. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/ XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ }; /* typedef'd to XXH64_state_t */ @@ -1473,8 +1705,7 @@ struct XXH64_state_s { #ifndef XXH_NO_XXH3 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ -# include -# define XXH_ALIGN(n) alignas(n) +# define XXH_ALIGN(n) _Alignas(n) #elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */ /* In C++ alignas() is a keyword */ # define XXH_ALIGN(n) alignas(n) @@ -1587,7 +1818,20 @@ struct XXH3_state_s { /*! - * simple alias to pre-selected XXH3_128bits variant + * @brief Calculates the 128-bit hash of @p data using XXH3. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p len is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 128-bit XXH3 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); @@ -1596,9 +1840,16 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, siz /* Symbols defined below must be considered tied to a specific library version. */ /*! - * XXH3_generateSecret(): + * @brief Derive a high-entropy secret from any user-defined content, named customSeed. + * + * @param secretBuffer A writable buffer for derived high-entropy secret data. + * @param secretSize Size of secretBuffer, in bytes. Must be >= XXH3_SECRET_SIZE_MIN. + * @param customSeed A user-defined content. + * @param customSeedSize Size of customSeed, in bytes. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. * - * Derive a high-entropy secret from any user-defined content, named customSeed. * The generated secret can be used in combination with `*_withSecret()` functions. * The `_withSecret()` variants are useful to provide a higher level of protection * than 64-bit seed, as it becomes much more difficult for an external actor to @@ -1651,6 +1902,9 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer /*! * @brief Generate the same secret as the _withSeed() variants. * + * @param secretBuffer A writable buffer of @ref XXH3_SECRET_DEFAULT_SIZE bytes + * @param seed The 64-bit seed to alter the hash result predictably. + * * The generated secret can be used in combination with *`*_withSecret()` and `_withSecretandSeed()` variants. * @@ -1670,7 +1924,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * }; * // Fast, caches the seeded secret for future uses. * class HashFast { - * unsigned char secret[XXH3_SECRET_SIZE_MIN]; + * unsigned char secret[XXH3_SECRET_DEFAULT_SIZE]; * public: * HashFast(XXH64_hash_t s) { * XXH3_generateSecret_fromSeed(secret, seed); @@ -1682,15 +1936,26 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * } * }; * @endcode - * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes - * @param seed The seed to seed the state. */ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed); /*! - * These variants generate hash values using either - * @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) - * or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX). + * @brief Maximum size of "short" key in bytes. + */ +#define XXH3_MIDSIZE_MAX 240 + +/*! + * @brief Calculates 64/128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * These variants generate hash values using either: + * - @p seed for "short" keys (< @ref XXH3_MIDSIZE_MAX = 240 bytes) + * - @p secret for "large" keys (>= @ref XXH3_MIDSIZE_MAX). * * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. * `_withSeed()` has to generate the secret on the fly for "large" keys. @@ -1717,22 +1982,71 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The memory segment to be hashed, at least @p len bytes in size. + * @param length The length of @p data, in bytes. + * @param secret The secret used to alter hash result predictably. + * @param secretSize The length of @p secret, in bytes (must be >= XXH3_SECRET_SIZE_MIN) + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(): contract is the same. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #ifndef XXH_NO_STREAM -/*! @copydoc XXH3_64bits_withSecretandSeed() */ +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + * + * Note: there was a bug in an earlier version of this function (<= v0.8.2) + * that would make it generate an incorrect hash value + * when @p seed == 0 and @p length < XXH3_MIDSIZE_MAX + * and @p secret is different from XXH3_generateSecret_fromSeed(). + * As stated in the contract, the correct hash result must be + * the same as XXH3_128bits_withSeed() when @p length <= XXH3_MIDSIZE_MAX. + * Results generated by this older version are wrong, hence not comparable. + */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #endif /* !XXH_NO_STREAM */ #endif /* !XXH_NO_XXH3 */ @@ -2100,15 +2414,15 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if XXH_NO_INLINE_HINTS /* disable inlining hints */ # if defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __attribute__((unused)) +# define XXH_FORCE_INLINE static __attribute__((__unused__)) # else # define XXH_FORCE_INLINE static # endif # define XXH_NO_INLINE static /* enable inlining hints */ #elif defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) -# define XXH_NO_INLINE static __attribute__((noinline)) +# define XXH_FORCE_INLINE static __inline__ __attribute__((__always_inline__, __unused__)) +# define XXH_NO_INLINE static __attribute__((__noinline__)) #elif defined(_MSC_VER) /* Visual Studio */ # define XXH_FORCE_INLINE static __forceinline # define XXH_NO_INLINE static __declspec(noinline) @@ -2121,12 +2435,34 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) # define XXH_NO_INLINE static #endif +#if defined(XXH_INLINE_ALL) +# define XXH_STATIC XXH_FORCE_INLINE +#else +# define XXH_STATIC static +#endif + #if XXH3_INLINE_SECRET # define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE #else # define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE #endif +#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ +# define XXH_RESTRICT /* disable */ +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined (__clang__)) \ + || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ + || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) +/* + * There are a LOT more compilers that recognize __restrict but this + * covers the major ones. + */ +# define XXH_RESTRICT __restrict +#else +# define XXH_RESTRICT /* disable */ +#endif /* ************************************* * Debug @@ -2206,10 +2542,14 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t xxh_u8; +# ifdef _AIX +# include +# else +# include +# endif + typedef uint8_t xxh_u8; #else - typedef unsigned char xxh_u8; + typedef unsigned char xxh_u8; #endif typedef XXH32_hash_t xxh_u32; @@ -2295,11 +2635,11 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; +typedef union { xxh_u32 u32; } __attribute__((__packed__)) unalign; #endif static xxh_u32 XXH_read32(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u32 xxh_unalign32; + typedef __attribute__((__aligned__(1))) xxh_u32 xxh_unalign32; return *((const xxh_unalign32*)ptr); } @@ -2445,6 +2785,9 @@ static int XXH_isLittleEndian(void) && XXH_HAS_BUILTIN(__builtin_rotateleft64) # define XXH_rotl32 __builtin_rotateleft32 # define XXH_rotl64 __builtin_rotateleft64 +#elif XXH_HAS_BUILTIN(__builtin_stdc_rotate_left) +# define XXH_rotl32 __builtin_stdc_rotate_left +# define XXH_rotl64 __builtin_stdc_rotate_left /* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ #elif defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) @@ -2590,7 +2933,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) #if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) /* * UGLY HACK: - * A compiler fence is the only thing that prevents GCC and Clang from + * A compiler fence is used to prevent GCC and Clang from * autovectorizing the XXH32 loop (pragmas and attributes don't work for some * reason) without globally disabling SSE4.1. * @@ -2651,6 +2994,61 @@ static xxh_u32 XXH32_avalanche(xxh_u32 hash) #define XXH_get32bits(p) XXH_readLE32_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH32(). + */ +XXH_FORCE_INLINE void +XXH32_initAccs(xxh_u32 *acc, xxh_u32 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + acc[1] = seed + XXH_PRIME32_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME32_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH32(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH32_consumeLong( + xxh_u32 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 15; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 16); + do { + acc[0] = XXH32_round(acc[0], XXH_get32bits(input)); input += 4; + acc[1] = XXH32_round(acc[1], XXH_get32bits(input)); input += 4; + acc[2] = XXH32_round(acc[2], XXH_get32bits(input)); input += 4; + acc[3] = XXH32_round(acc[3], XXH_get32bits(input)); input += 4; + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH32() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u32 +XXH32_mergeAccs(const xxh_u32 *acc) +{ + XXH_ASSERT(acc != NULL); + return XXH_rotl32(acc[0], 1) + XXH_rotl32(acc[1], 7) + + XXH_rotl32(acc[2], 12) + XXH_rotl32(acc[3], 18); +} + /*! * @internal * @brief Processes the last 0-15 bytes of @p ptr. @@ -2763,22 +3161,12 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment if (input==NULL) XXH_ASSERT(len == 0); if (len>=16) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 15; - xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - xxh_u32 v2 = seed + XXH_PRIME32_2; - xxh_u32 v3 = seed + 0; - xxh_u32 v4 = seed - XXH_PRIME32_1; + xxh_u32 acc[4]; + XXH32_initAccs(acc, seed); - do { - v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; - v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; - v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; - v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; - } while (input < limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) - + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + input = XXH32_consumeLong(acc, input, len, align); + + h32 = XXH32_mergeAccs(acc); } else { h32 = seed + XXH_PRIME32_5; } @@ -2834,10 +3222,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s { XXH_ASSERT(statePtr != NULL); memset(statePtr, 0, sizeof(*statePtr)); - statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - statePtr->v[1] = seed + XXH_PRIME32_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME32_1; + XXH32_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -2851,45 +3236,37 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len) return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len_32 += (XXH32_hash_t)len; + state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); - state->total_len_32 += (XXH32_hash_t)len; - state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); + XXH_ASSERT(state->bufferedSize < sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); - state->memsize += (XXH32_hash_t)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const xxh_u32* p32 = state->mem32; - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32)); - } - p += 16-state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer: complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* then process one round */ + (void)XXH32_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p <= bEnd-16) { - const xxh_u8* const limit = bEnd - 16; - - do { - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH32_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -2903,36 +3280,20 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) xxh_u32 h32; if (state->large_len) { - h32 = XXH_rotl32(state->v[0], 1) - + XXH_rotl32(state->v[1], 7) - + XXH_rotl32(state->v[2], 12) - + XXH_rotl32(state->v[3], 18); + h32 = XXH32_mergeAccs(state->acc); } else { - h32 = state->v[2] /* == seed */ + XXH_PRIME32_5; + h32 = state->acc[2] /* == seed */ + XXH_PRIME32_5; } h32 += state->total_len_32; - return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); + return XXH32_finalize(h32, state->buffer, state->bufferedSize, XXH_aligned); } #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/*! - * @ingroup XXH32_family - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * - * The canonical representation uses big endian convention, the same convention - * as human-readable numbers (large digits first). - * - * This way, hash values can be written into a file or buffer, remaining - * comparable across different systems. - * - * The following functions allow transformation of hash values to and from their - * canonical format. - */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); @@ -2987,11 +3348,11 @@ static xxh_u64 XXH_read64(const void* memPtr) * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; +typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((__packed__)) unalign64; #endif static xxh_u64 XXH_read64(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u64 xxh_unalign64; + typedef __attribute__((__aligned__(1))) xxh_u64 xxh_unalign64; return *((const xxh_unalign64*)ptr); } @@ -3110,6 +3471,23 @@ static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) acc += input * XXH_PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= XXH_PRIME64_1; +#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * DISABLE AUTOVECTORIZATION: + * A compiler fence is used to prevent GCC and Clang from + * autovectorizing the XXH64 loop (pragmas and attributes don't work for some + * reason) without globally disabling AVX512. + * + * Autovectorization of XXH64 tends to be detrimental, + * though the exact outcome may change depending on exact cpu and compiler version. + * For information, it has been reported as detrimental for Skylake-X, + * but possibly beneficial for Zen4. + * + * The default is to disable auto-vectorization, + * but you can select to enable it instead using `XXH_ENABLE_AUTOVECTORIZE` build variable. + */ + XXH_COMPILER_GUARD(acc); +#endif return acc; } @@ -3135,6 +3513,85 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) #define XXH_get64bits(p) XXH_readLE64_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH64(). + */ +XXH_FORCE_INLINE void +XXH64_initAccs(xxh_u64 *acc, xxh_u64 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + acc[1] = seed + XXH_PRIME64_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME64_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH64(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH64_consumeLong( + xxh_u64 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 31; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 32); + do { + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + acc[i] = XXH64_round(acc[i], XXH_get64bits(input)); + input += 8; + } + } else { + acc[0] = XXH64_round(acc[0], XXH_get64bits(input)); input += 8; + acc[1] = XXH64_round(acc[1], XXH_get64bits(input)); input += 8; + acc[2] = XXH64_round(acc[2], XXH_get64bits(input)); input += 8; + acc[3] = XXH64_round(acc[3], XXH_get64bits(input)); input += 8; + } + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH64() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u64 +XXH64_mergeAccs(const xxh_u64 *acc) +{ + XXH_ASSERT(acc != NULL); + { + xxh_u64 h64 = XXH_rotl64(acc[0], 1) + XXH_rotl64(acc[1], 7) + + XXH_rotl64(acc[2], 12) + XXH_rotl64(acc[3], 18); + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + h64 = XXH64_mergeRound(h64, acc[i]); + } + } else { + h64 = XXH64_mergeRound(h64, acc[0]); + h64 = XXH64_mergeRound(h64, acc[1]); + h64 = XXH64_mergeRound(h64, acc[2]); + h64 = XXH64_mergeRound(h64, acc[3]); + } + return h64; + } +} + /*! * @internal * @brief Processes the last 0-31 bytes of @p ptr. @@ -3150,7 +3607,7 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) * @return The finalized hash * @see XXH32_finalize(). */ -static XXH_PUREF xxh_u64 +XXH_STATIC XXH_PUREF xxh_u64 XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { if (ptr==NULL) XXH_ASSERT(len == 0); @@ -3200,27 +3657,13 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment xxh_u64 h64; if (input==NULL) XXH_ASSERT(len == 0); - if (len>=32) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 31; - xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - xxh_u64 v2 = seed + XXH_PRIME64_2; - xxh_u64 v3 = seed + 0; - xxh_u64 v4 = seed - XXH_PRIME64_1; + if (len>=32) { /* Process a large block of data */ + xxh_u64 acc[4]; + XXH64_initAccs(acc, seed); - do { - v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; - v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; - v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; - v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; - } while (inputv[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - statePtr->v[1] = seed + XXH_PRIME64_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME64_1; + XXH64_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -3292,42 +3732,36 @@ XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len += len; - state->total_len += len; + XXH_ASSERT(state->bufferedSize <= sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 32) { /* fill in tmp buffer */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); - state->memsize += (xxh_u32)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0)); - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1)); - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2)); - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3)); - p += 32 - state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer => complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* and process one round */ + (void)XXH64_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p+32 <= bEnd) { - const xxh_u8* const limit = bEnd - 32; - - do { - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8; - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8; - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8; - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH64_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -3341,18 +3775,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state xxh_u64 h64; if (state->total_len >= 32) { - h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18); - h64 = XXH64_mergeRound(h64, state->v[0]); - h64 = XXH64_mergeRound(h64, state->v[1]); - h64 = XXH64_mergeRound(h64, state->v[2]); - h64 = XXH64_mergeRound(h64, state->v[3]); + h64 = XXH64_mergeAccs(state->acc); } else { - h64 = state->v[2] /*seed*/ + XXH_PRIME64_5; + h64 = state->acc[2] /*seed*/ + XXH_PRIME64_5; } h64 += (xxh_u64) state->total_len; - return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); + return XXH64_finalize(h64, state->buffer, (size_t)state->total_len, XXH_aligned); } #endif /* !XXH_NO_STREAM */ @@ -3387,22 +3817,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can /* === Compiler specifics === */ -#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ -# define XXH_RESTRICT /* disable */ -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ -# define XXH_RESTRICT restrict -#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ - || (defined (__clang__)) \ - || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ - || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) -/* - * There are a LOT more compilers that recognize __restrict but this - * covers the major ones. - */ -# define XXH_RESTRICT __restrict -#else -# define XXH_RESTRICT /* disable */ -#endif #if (defined(__GNUC__) && (__GNUC__ >= 3)) \ || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ @@ -3416,7 +3830,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can #ifndef XXH_HAS_INCLUDE # ifdef __has_include -# define XXH_HAS_INCLUDE(x) __has_include(x) +/* + * Not defined as XXH_HAS_INCLUDE(x) (function-like) because + * this causes segfaults in Apple Clang 4.2 (on Mac OS X 10.7 Lion) + */ +# define XXH_HAS_INCLUDE __has_include # else # define XXH_HAS_INCLUDE(x) 0 # endif @@ -3437,6 +3855,8 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can # include # elif defined(__SSE2__) # include +# elif defined(__loongarch_sx) +# include # endif #endif @@ -3533,33 +3953,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can * implementation. */ # define XXH_VECTOR XXH_SCALAR -/*! - * @ingroup tuning - * @brief Possible values for @ref XXH_VECTOR. - * - * Note that these are actually implemented as macros. - * - * If this is not defined, it is detected automatically. - * internal macro XXH_X86DISPATCH overrides this. - */ -enum XXH_VECTOR_TYPE /* fake enum */ { - XXH_SCALAR = 0, /*!< Portable scalar version */ - XXH_SSE2 = 1, /*!< - * SSE2 for Pentium 4, Opteron, all x86_64. - * - * @note SSE2 is also guaranteed on Windows 10, macOS, and - * Android x86. - */ - XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ - XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ - XXH_NEON = 4, /*!< - * NEON for most ARMv7-A, all AArch64, and WASM SIMD128 - * via the SIMDeverywhere polyfill provided with the - * Emscripten SDK. - */ - XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ - XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */ -}; /*! * @ingroup tuning * @brief Selects the minimum alignment for XXH3's accumulators. @@ -3574,13 +3967,6 @@ enum XXH_VECTOR_TYPE /* fake enum */ { /* Actual definition */ #ifndef XXH_DOXYGEN -# define XXH_SCALAR 0 -# define XXH_SSE2 1 -# define XXH_AVX2 2 -# define XXH_AVX512 3 -# define XXH_NEON 4 -# define XXH_VSX 5 -# define XXH_SVE 6 #endif #ifndef XXH_VECTOR /* can be defined on command line */ @@ -3605,6 +3991,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { || (defined(__s390x__) && defined(__VEC__)) \ && defined(__GNUC__) /* TODO: IBM XL */ # define XXH_VECTOR XXH_VSX +# elif defined(__loongarch_sx) +# define XXH_VECTOR XXH_LSX # else # define XXH_VECTOR XXH_SCALAR # endif @@ -3642,6 +4030,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_ACC_ALIGN 64 # elif XXH_VECTOR == XXH_SVE /* sve */ # define XXH_ACC_ALIGN 64 +# elif XXH_VECTOR == XXH_LSX /* lsx */ +# define XXH_ACC_ALIGN 64 # endif #endif @@ -3655,7 +4045,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ { #endif #if defined(__GNUC__) || defined(__clang__) -# define XXH_ALIASING __attribute__((may_alias)) +# define XXH_ALIASING __attribute__((__may_alias__)) #else # define XXH_ALIASING /* nothing */ #endif @@ -4408,8 +4798,6 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, } } -#define XXH3_MIDSIZE_MAX 240 - XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -5281,6 +5669,71 @@ XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc, #endif +#if (XXH_VECTOR == XXH_LSX) +#define _LSX_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_lsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i *) acc; + const __m128i* const xinput = (const __m128i *) input; + const __m128i* const xsecret = (const __m128i *) secret; + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = __lsx_vld(xinput + i, 0); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + // __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = __lsx_vmulwev_d_wu(data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = __lsx_vshuf4i_w(data_vec, _LSX_SHUFFLE(1, 0, 3, 2)); + __m128i const sum = __lsx_vadd_d(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = __lsx_vadd_d(product, sum); + } + } +} +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lsx) + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_lsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i*) acc; + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = __lsx_vreplgr2vr_w((int)XXH_PRIME32_1); + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = __lsx_vsrli_d(acc_vec, 47); + __m128i const data_vec = __lsx_vxor_v(acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = __lsx_vsrli_d(data_key, 32); + __m128i const prod_lo = __lsx_vmulwev_d_wu(data_key, prime32); + __m128i const prod_hi = __lsx_vmulwev_d_wu(data_key_hi, prime32); + xacc[i] = __lsx_vadd_d(prod_lo, __lsx_vslli_d(prod_hi, 32)); + } + } +} + +#endif + /* scalar variants - universal */ #if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) @@ -5511,6 +5964,12 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#elif (XXH_VECTOR == XXH_LSX) +#define XXH3_accumulate_512 XXH3_accumulate_512_lsx +#define XXH3_accumulate XXH3_accumulate_lsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_lsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + #else /* scalar */ #define XXH3_accumulate_512 XXH3_accumulate_512_scalar @@ -5566,7 +6025,7 @@ XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret acc[1] ^ XXH_readLE64(secret+8) ); } -static XXH64_hash_t +static XXH_PUREF XXH64_hash_t XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) { xxh_u64 result64 = start; @@ -5593,6 +6052,15 @@ XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secre return XXH3_avalanche(result64); } +/* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + +static XXH_PUREF XXH64_hash_t +XXH3_finalizeLong_64b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 len) +{ + return XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, len * XXH_PRIME64_1); +} + #define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } @@ -5608,10 +6076,8 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); - /* do not align on 8, so that the secret is different from the accumulator */ -#define XXH_SECRET_MERGEACCS_START 11 XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, (const xxh_u8*)secret, (xxh_u64)len); } /* @@ -5747,7 +6213,7 @@ XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH /* === XXH3 streaming === */ #ifndef XXH_NO_STREAM /* - * Malloc's a pointer that is always aligned to align. + * Malloc's a pointer that is always aligned to @align. * * This must be freed with `XXH_alignedFree()`. * @@ -5815,8 +6281,12 @@ static void XXH_alignedFree(void* p) /*! * @brief Allocate an @ref XXH3_state_t. * - * Must be freed with XXH3_freeState(). - * @return An allocated XXH3_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH3_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH3_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) { @@ -5830,9 +6300,13 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) /*! * @brief Frees an @ref XXH3_state_t. * - * Must be allocated with XXH3_createState(). * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note Must be allocated with XXH3_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) { @@ -6111,9 +6585,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* if (state->totalLen > XXH3_MIDSIZE_MAX) { XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); - return XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, secret, (xxh_u64)state->totalLen); } /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ if (state->useSeed) @@ -6405,6 +6877,17 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, } } +static XXH_PUREF XXH128_hash_t +XXH3_finalizeLong_128b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, xxh_u64 len) +{ + XXH128_hash_t h128; + h128.low64 = XXH3_finalizeLong_64b(acc, secret, len); + h128.high64 = XXH3_mergeAccs(acc, secret + secretSize + - XXH_STRIPE_LEN - XXH_SECRET_MERGEACCS_START, + ~(len * XXH_PRIME64_2)); + return h128; +} + XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -6418,16 +6901,7 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)len * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + secretSize - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)len * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, secretSize, (xxh_u64)len); } /* @@ -6610,19 +7084,10 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_ XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + state->secretLimit + XXH_STRIPE_LEN - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, state->secretLimit + XXH_STRIPE_LEN, (xxh_u64)state->totalLen); } /* len <= XXH3_MIDSIZE_MAX : short code */ - if (state->seed) + if (state->useSeed) return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); diff --git a/texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp b/texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp index c6a5abb2b7..41832d6c48 100644 --- a/texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp @@ -2,7 +2,7 @@ ** AGLTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp b/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp index a6ae7495c4..f5e0800204 100644 --- a/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp @@ -2,7 +2,7 @@ ** BasicDVIReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp b/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp index f3976a6b92..f129c2ceea 100644 --- a/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp @@ -2,7 +2,7 @@ ** BasicDVIReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Bezier.cpp b/texk/dvisvgm/dvisvgm-src/src/Bezier.cpp index c534224139..dd51857819 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Bezier.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Bezier.cpp @@ -2,7 +2,7 @@ ** Bezier.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Bezier.hpp b/texk/dvisvgm/dvisvgm-src/src/Bezier.hpp index 7f384a006a..093d2b5f4c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Bezier.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Bezier.hpp @@ -2,7 +2,7 @@ ** Bezier.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp index 84f2e4e1fd..bfa8488932 100644 --- a/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp @@ -2,7 +2,7 @@ ** BgColorSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp index 00fce30380..1dca9ab7e5 100644 --- a/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp @@ -2,7 +2,7 @@ ** BgColorSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp b/texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp index d8b9f74da3..7ad7e8d6d3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp @@ -2,7 +2,7 @@ ** Bitmap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp b/texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp index 3d621586b2..d2cb3cc5e8 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp @@ -2,7 +2,7 @@ ** Bitmap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp b/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp index a2a0198e7a..66c1b03a0a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp @@ -2,7 +2,7 @@ ** BoundingBox.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp b/texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp index 026bd11b57..6445333630 100644 --- a/texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp @@ -2,7 +2,7 @@ ** BoundingBox.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp b/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp index d13cdfc3f2..776b101a90 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp @@ -2,7 +2,7 @@ ** CLCommandLine.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp b/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp index ba3089f2c6..9a3c3dbf0a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp @@ -2,7 +2,7 @@ ** CLCommandLine.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CLOption.hpp b/texk/dvisvgm/dvisvgm-src/src/CLOption.hpp index 1bdd1780e6..df7abd5098 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CLOption.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/CLOption.hpp @@ -2,7 +2,7 @@ ** CLOption.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -27,8 +27,7 @@ namespace CL { -class Option -{ +class Option { friend class CommandLine; public: enum class ArgMode {NONE, OPTIONAL, REQUIRED}; @@ -122,11 +121,10 @@ inline std::string parseValue (std::istream &is) { template -class TypedOption : public Option -{ +class TypedOption : public Option { public: TypedOption (const char *longName, char shortName, const char *argName, T val, const char *summary) - : Option(longName, shortName, summary), _argName(argName), _value(val) {} + : Option(longName, shortName, summary), _argName(argName), _value(std::move(val)) {} TypedOption (const char *longName, char shortName, const char *argName, const char *summary) : Option(longName, shortName, summary), _argName(argName), _value() {} @@ -158,8 +156,7 @@ class TypedOption : public Option template -class TypedOption : public Option -{ +class TypedOption : public Option { public: TypedOption (const char *longName, char shortName, const char *argName, bool val, const char *summary) : Option(longName, shortName, summary), _argName(argName), _value(val) {} diff --git a/texk/dvisvgm/dvisvgm-src/src/CMap.cpp b/texk/dvisvgm/dvisvgm-src/src/CMap.cpp index a690085c6f..659c9a0d10 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CMap.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/CMap.cpp @@ -2,7 +2,7 @@ ** CMap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CMap.hpp b/texk/dvisvgm/dvisvgm-src/src/CMap.hpp index 1af1901bfe..a0f51d9e45 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CMap.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/CMap.hpp @@ -2,7 +2,7 @@ ** CMap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp b/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp index e7d5e87e72..1d17733128 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp @@ -2,7 +2,7 @@ ** CMapManager.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp b/texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp index 1e674ba375..52e2cd45f3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp @@ -2,7 +2,7 @@ ** CMapManager.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp b/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp index 59729edbb1..936e875fe3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp @@ -2,7 +2,7 @@ ** CMapReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp b/texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp index 716b2faec7..430fdf7205 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp @@ -2,7 +2,7 @@ ** CMapReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp b/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp index 00226761fc..9c18c5f02d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp @@ -2,7 +2,7 @@ ** Calculator.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Calculator.hpp b/texk/dvisvgm/dvisvgm-src/src/Calculator.hpp index 355cbbae0d..a7824b1866 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Calculator.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Calculator.hpp @@ -2,7 +2,7 @@ ** Calculator.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp b/texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp index b68c50fe32..f62dfeb27d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp @@ -2,7 +2,7 @@ ** CharMapID.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp b/texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp index 87c4294035..7b47bfd7fe 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp @@ -2,7 +2,7 @@ ** CharMapID.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Character.hpp b/texk/dvisvgm/dvisvgm-src/src/Character.hpp index 0569205ae3..bb80d8791f 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Character.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Character.hpp @@ -2,7 +2,7 @@ ** Character.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -21,6 +21,7 @@ #ifndef CHARACTER_HPP #define CHARACTER_HPP +#include class Character { public: diff --git a/texk/dvisvgm/dvisvgm-src/src/Color.cpp b/texk/dvisvgm/dvisvgm-src/src/Color.cpp index cffdb41531..48b70e5bde 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Color.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Color.cpp @@ -2,7 +2,7 @@ ** Color.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -35,21 +35,65 @@ bool Color::SUPPRESS_COLOR_NAMES = true; const Color Color::BLACK(uint32_t(0)); const Color Color::WHITE(uint8_t(255), uint8_t(255), uint8_t(255)); -const Color Color::TRANSPARENT(uint32_t(0xff000000)); -static inline uint8_t double_to_byte (double v) { +inline uint8_t double_to_byte (double v) { v = max(0.0, min(1.0, v)); return uint8_t(round(255.0*v)); } -Color::Color (const string &psname) { - if (!setPSName(psname, false)) +/** Reads n double values from input stream is. The values may be + * separated by whitespace and/or commas. */ +static valarray read_doubles (istream &is, int n) { + valarray values(n); + for (double &val : values) { + is >> ws; + if (!util::read_double(is, val)) + val = 0; + is >> ws; + if (is.peek() == ',') { + is.get(); + is >> ws; + } + } + return values; +} + + +/** Creates a color object from a string specifying the color. It can + * either be a PS color name or one of the color functions rgb(r,g,b), + * cmyk(c,m,y,k) where the parameters are numbers in the interval + * from 0 to 1. */ +Color::Color (const string &colorstr) { + if (colorstr.substr(0, 4) == "rgb(") { + istringstream iss(colorstr.substr(4)); + setRGB(read_doubles(iss, 3)); + } + else if (colorstr.substr(0, 5) == "cmyk(") { + istringstream iss(colorstr.substr(5)); + setCMYK(read_doubles(iss, 4)); + } + else if (!setPSName(colorstr, false)) setGray(uint8_t(0)); } +Color::Color (const valarray &values, ColorSpace cs) noexcept : _cspace(cs) { + int n = numComponents(cs); + int i=0; + _value = 0; + for (int shift=(n-1)*8; shift >= 0; shift-=8) + _value |= double_to_byte(values[i++]) << shift; +} + + +void Color::setRGB (uint8_t r, uint8_t g, uint8_t b) { + _value = (r << 16) | (g << 8) | b; + _cspace = ColorSpace::RGB; +} + + void Color::setRGB (double r, double g, double b) { setRGB(double_to_byte(r), double_to_byte(g), double_to_byte(b)); } @@ -73,7 +117,8 @@ bool Color::setRGBHexString (string hexString) { } if (hexString.length() == 6) { try { - _rgb = stoi(hexString, nullptr, 16); + _value = stoi(hexString, nullptr, 16); + _cspace = ColorSpace::RGB; return true; } catch (...) { @@ -89,12 +134,13 @@ bool Color::setRGBHexString (string hexString) { * @param[in] case_sensitive if true, upper/lower case spelling is significant * @return true if color name could be applied properly */ bool Color::setPSName (string name, bool case_sensitive) { + _cspace = ColorSpace::RGB; if (name[0] == '#') { char *p=nullptr; - _rgb = uint32_t(strtol(name.c_str()+1, &p, 16)); + _value = uint32_t(strtol(name.c_str()+1, &p, 16)); while (isspace(*p)) p++; - return (*p == 0 && _rgb <= 0xFFFFFF); + return (*p == 0 && _value <= 0xFFFFFF); } struct ColorConstant { @@ -180,7 +226,7 @@ bool Color::setPSName (string name, bool case_sensitive) { } ); if (it != constants.end() && it->name == name) { - _rgb = it->rgb; + _value = it->rgb; return true; } } @@ -190,7 +236,7 @@ bool Color::setPSName (string name, bool case_sensitive) { return name == util::tolower(cc.name); }); if (it != constants.end()) { - _rgb = it->rgb; + _value = it->rgb; return true; } } @@ -208,21 +254,19 @@ void Color::setHSB (double h, double s, double b) { } +void Color::setCMYK (uint8_t c, uint8_t m, uint8_t y, uint8_t k) { + _value = (c << 24) | (m << 16) | (y << 8) | k; + _cspace = ColorSpace::CMYK; +} + + void Color::setCMYK (double c, double m, double y, double k) { - valarray cmyk(4), rgb(3); - cmyk[0] = c; - cmyk[1] = m; - cmyk[2] = y; - cmyk[3] = k; - CMYK2RGB(cmyk, rgb); - setRGB(rgb); + setCMYK(double_to_byte(c), double_to_byte(m), double_to_byte(y), double_to_byte(k)); } void Color::setCMYK (const std::valarray &cmyk) { - valarray rgb(3); - CMYK2RGB(cmyk, rgb); - setRGB(rgb); + setCMYK(cmyk[0], cmyk[1], cmyk[2], cmyk[3]); } @@ -232,20 +276,21 @@ void Color::set (ColorSpace colorSpace, VectorIterator &it) { case ColorSpace::RGB : setRGB(*it, *(it+1), *(it+2)); it+=3; break; case ColorSpace::LAB : setLab(*it, *(it+1), *(it+2)); it+=3; break; case ColorSpace::CMYK: setCMYK(*it, *(it+1), *(it+2), *(it+3)); it+=4; break; + default: ; } } Color Color::operator *= (double c) { if (abs(c) < 0.001) - _rgb &= 0xff000000; + _value &= 0xff000000; else if (abs(c-trunc(c)) < 0.999) { - uint32_t rgb=0; - for (int i=0; i < 3; i++) { - rgb |= lround((_rgb & 0xff)*c) << (8*i); - _rgb >>= 8; + uint32_t value=0; + for (int i=0; i < 4; i++) { + value |= lround((_value & 0xff)*c) << (8*i); + _value >>= 8; } - _rgb = rgb; + _value = value; } return *this; } @@ -255,11 +300,12 @@ Color Color::operator *= (double c) { * color value, the string either consists of 3 or 6 hex digits * plus a leading '#' character. */ string Color::rgbString () const { + uint32_t rgb = getRGBUInt32(); ostringstream oss; oss << '#'; for (int i=2; i >= 0; i--) { oss << setbase(16) << setfill('0') << setw(2) - << (((_rgb >> (8*i)) & 0xff)); + << (((rgb >> (8*i)) & 0xff)); } // check if RGB string can be reduced to a three digit hex value // #RRGGBB => #RGB, e.g. #112233 => #123 @@ -423,36 +469,51 @@ string Color::svgColorString (bool rgbonly) const { {0xfffff0, "ivory"}, {0xffffff, "white"} }}; - ColorName cmppair = {_rgb, nullptr}; + ColorName cmppair = {_value, nullptr}; auto it = lower_bound(colornames.begin(), colornames.end(), cmppair, [](const ColorName &c1, const ColorName &c2) { return c1.rgb < c2.rgb; }); - if (it != colornames.end() && it->rgb == _rgb) + if (it != colornames.end() && it->rgb == _value) return it->name; } return rgbString(); } +valarray Color::getDoubleValues () const { + int n = numComponents(_cspace); + valarray values(n); + int i=0; + for (int shift= (n-1)*8; shift >= 0; shift-=8) + values[i++] = ((_value >> shift) & 0xff)/255.0; + return values; +} + + +static uint32_t interpolate_cmyk2rgb (const valarray &cmyk); + /** Approximates a CMYK color by an RGB triple. The component values * are expected to be normalized, i.e. 0 <= cmyk[i],rgb[j] <= 1. * @param[in] cmyk color in CMYK space * @param[out] rgb RGB approximation */ void Color::CMYK2RGB (const valarray &cmyk, valarray &rgb) { - double kc = 1.0-cmyk[3]; +#if 0 + double cc = 1-cmyk[0]; + double mc = 1-cmyk[1]; + double yc = 1-cmyk[2]; + double kc = 1-cmyk[3]; + // https://graphicdesign.stackexchange.com/a/137902 + rgb[0] = 0.3137+0.5882*cc-0.3529*mc-0.1373*yc+0.47175*cc*mc+0.1173*yc*cc; + rgb[1] = 0.2588-0.1961*cc+0.2745*mc-0.0627*yc+0.54825*cc*mc+0.0204*yc*cc+0.1581*yc*mc; + rgb[2] = 0.3373-0.3255*cc-0.1569*mc+0.1647*yc+0.1173*cc*mc+0.31365*yc*cc+0.54825*yc*mc; for (int i=0; i < 3; i++) - rgb[i] = min(1.0, max(0.0, (1.0-cmyk[i])*kc)); -} - - -void Color::RGB2CMYK (const valarray &rgb, valarray &cmyk) { - double c = 1-rgb[0]; - double m = 1-rgb[1]; - double y = 1-rgb[2]; - cmyk[3] = min(min(c, m), y); - cmyk[0] = c-cmyk[3]; - cmyk[1] = m-cmyk[3]; - cmyk[2] = y-cmyk[3]; + rgb[i] = min(1.0, max(0.0, rgb[i]*kc)); +#else + uint32_t rgb32 = interpolate_cmyk2rgb(cmyk); + rgb[0] = (rgb32 >> 16) / 255.0; + rgb[1] = ((rgb32 >> 8) & 0xff) / 255.0; + rgb[2] = (rgb32 & 0xff) / 255.0; +#endif } @@ -495,46 +556,65 @@ void Color::getGray (valarray &gray) const { } -void Color::getRGB (double &r, double &g, double &b) const { - r = ((_rgb >> 16) & 255) / 255.0; - g = ((_rgb >> 8) & 255) / 255.0; - b = (_rgb & 255) / 255.0; +valarray Color::getRGBDouble () const { + valarray values = getDoubleValues(); + valarray rgbValues; + switch (_cspace) { + case ColorSpace::RGB: + rgbValues = std::move(values); + break; + case ColorSpace::CMYK: + rgbValues.resize(3); + CMYK2RGB(values, rgbValues); + break; + case ColorSpace::GRAY: + rgbValues.resize(3); + rgbValues[0] = rgbValues[1] = rgbValues[2] = values[0]; + break; + case ColorSpace::LAB: + rgbValues.resize(3); + Lab2XYZ(values, rgbValues); + XYZ2RGB(rgbValues, values); + rgbValues = std::move(values); + break; + default: ; + } + return rgbValues; } -void Color::getRGB (valarray &rgb) const { - rgb.resize(3); - double r, g, b; - getRGB(r, g, b); - rgb[0] = r; - rgb[1] = g; - rgb[2] = b; +uint32_t Color::getRGBUInt32 () const { + switch (_cspace) { + case ColorSpace::GRAY: { + uint32_t gray = _value & 0xff; + return (gray << 16) | (gray << 8) | gray; + } + case ColorSpace::RGB: + return _value; + default: + valarray rgb = getRGBDouble(); + return (double_to_byte(rgb[0]) << 16) | (double_to_byte(rgb[1]) << 8) | (double_to_byte(rgb[2])); + } } -void Color::getCMYK (double &c, double &m, double &y, double &k) const { - valarray rgb(3), cmyk(4); - getRGB(rgb); - RGB2CMYK(rgb, cmyk); - c = cmyk[0]; - m = cmyk[1]; - y = cmyk[2]; - k = cmyk[3]; +void Color::getRGB (double &r, double &g, double &b) const { + valarray rgb = getRGBDouble(); + r = rgb[0]; + g = rgb[1]; + b = rgb[2]; } -void Color::getCMYK (std::valarray &cmyk) const { - cmyk.resize(4); - valarray rgb(3); - getRGB(rgb); - RGB2CMYK(rgb, cmyk); +void Color::getRGB (valarray &rgb) const { + rgb = getRGBDouble(); } void Color::getXYZ (double &x, double &y, double &z) const { valarray rgb(3), xyz(3); getRGB(rgb); - RGB2XYZ(rgb, xyz); + RGB2XYZ(std::move(rgb), xyz); x = xyz[0]; y = xyz[1]; z = xyz[2]; @@ -548,6 +628,7 @@ void Color::setXYZ (double x, double y, double z) { xyz[2] = z; XYZ2RGB(xyz, rgb); setRGB(rgb); + _cspace = ColorSpace::RGB; } @@ -555,6 +636,7 @@ void Color::setXYZ (const valarray &xyz) { valarray rgb(3); XYZ2RGB(xyz, rgb); setRGB(rgb); + _cspace = ColorSpace::RGB; } @@ -594,8 +676,7 @@ void Color::getLab (std::valarray &lab) const { } -// static inline double sqr (double x) {return x*x;} -static inline double cube (double x) {return x*x*x;} +inline double cube (double x) {return x*x*x;} void Color::Lab2XYZ (const valarray &lab, valarray &xyz) { xyz.resize(3); @@ -705,6 +786,127 @@ int Color::numComponents (ColorSpace colorSpace) { case ColorSpace::LAB: case ColorSpace::RGB: return 3; case ColorSpace::CMYK: return 4; + default: ; } return 0; } + + +struct Cmyk2RgbTable { + using IntVec = vector; + using DoubleVec = vector; + + static constexpr const int GRIDSIZE = 5; // number of grid points per CMYK component + static array rgbvalues; + static const array dimfactors; + + static double interpolate (const IntVec &gi0, const IntVec &gi1, const DoubleVec &t, int icmyk, int irgb, int idx); +}; + +// For grid indices ci, mi, yi, ki, the corresponding table entry is located +// at index ci + mi*GRIDSIZE + yi*GRIDSIZE^2 + ki*GRIDSIZE^3. +const array Cmyk2RgbTable::dimfactors {{ + 1, GRIDSIZE, GRIDSIZE*GRIDSIZE, GRIDSIZE*GRIDSIZE*GRIDSIZE +}}; + + +/** Compute RGB from CMYK by multivariate linear interpolation of sampled color values. + * @param[in] cmyk CMYK color components (all values between 0 and 1) + * @return 24-bit RGB color value (0x00RRGGBB) */ +static uint32_t interpolate_cmyk2rgb (const valarray &cmyk) { + vector gi0(4), gi1(4); // upper and lower grid indices enclosing the CMYK components + vector t(4); // fractional parts of the grid indices where the CMYK components are located + for (int i=0; i < 4; i++) { + double gridpos = math::clip(cmyk[i], 0, 1)*(Cmyk2RgbTable::GRIDSIZE-1); + double gi; + t[i] = modf(gridpos, &gi); // distance of i-th CMYK component to nearest lower grid index (in [0,1)) + gi0[i] = int(gi); // index of nearest grid value <= i-th CMYK component + gi1[i] = ceil(gridpos); // index of nearest grid value >= i-th CMYK component + } + uint32_t rgb=0; + for (int i=0; i < 3; i++) { + double rgb_component = Cmyk2RgbTable::interpolate(gi0, gi1, t, 3, i, 0); + rgb_component = round(math::clip(rgb_component, 0, 255)); + rgb = (rgb << 8) | int(rgb_component); + } + return rgb; +} + + +inline uint32_t get_byte (uint32_t value, int n) { + return (value >> n*8) & 0xff; +} + + +/** Computes an RGB color component for a CMYK color by multi-linear interpolation + * using a 4-dimensional grid of pre-computed color values. + * @param[in] gi0 indices of nearest grid values <= corresponding CMYK components + * @param[in] gi1 indices of nearest grid values >= corresponding CMYK components + * @param[in] t fractional parts of the grid indices where the components of the CMYK color are located + * @param[in] icmyk index of CMYK component to process (0=C, 1=M, 2=Y, 3=K) + * @param[in] irgb index of RGB component to interpolate (0=R, 1=G, 2=B) + * @param[in] idx index of RGB value in lookup table (computed during recursion, final value reached when icmyk==0) + * @return The interpolated RGB color component in the range from 0 to 255. */ +double Cmyk2RgbTable::interpolate (const IntVec &gi0, const IntVec &gi1, const DoubleVec &t, int icmyk, int irgb, int idx) { + int idx0 = gi0[icmyk]*dimfactors[icmyk]+idx; + int idx1 = gi1[icmyk]*dimfactors[icmyk]+idx; + double a, b; + if (icmyk == 0) { + a = get_byte(rgbvalues[idx0], 2-irgb); + b = get_byte(rgbvalues[idx1], 2-irgb); + } + else { + a = interpolate(gi0, gi1, t, icmyk-1, irgb, idx0); + b = interpolate(gi0, gi1, t, icmyk-1, irgb, idx1); + } + return a + (b-a)*t[icmyk]; +} + + +/** RGB values for a 5x5x5x5 grid of CMYK values in [0,1]^4, i.e. the grid values of each dimension + * are 0, 0.25, 0.5, 0.75, and 1. For grid coordinates (c,m,y,k), the corresponding RGB values are + * located at index ci + 5*mi + 5*5*yi + 5*5*5*ki where ci=4*c, mi=4*m, yi=4*y, ki=4*k. + * The RGB values were computed with Little CMS utility 'transicc' using options -t1 and -b + * applied to Ghostscript's ICC profiles default_cmyk.icc and default_rgb.icc. */ +array Cmyk2RgbTable::rgbvalues {{ + 0xffffff,0xb9e5fa,0x6dcff6,0x00bdf2,0x00aeef,0xf9cbdf,0xbbb8dc,0x7da7d9,0x1c9ad6,0x008fd5,0xf49ac1,0xbc8cbf,0x8781bd,0x4978bc,0x0072bc,0xf067a6, + 0xbd60a5,0x8e5ba5,0x5b57a6,0x0054a6,0xec008c,0xbd1a8d,0x92278f,0x662c91,0x2e3092,0xfffbcc,0xc0e2ca,0x7accc8,0x00bac6,0x00abc5,0xfbc8b4,0xc1b6b3, + 0x86a6b2,0x3799b1,0x008eb0,0xf5989d,0xc08c9c,0x8d819c,0x51789c,0x00719c,0xf16687,0xc06188,0x915c89,0x5f588a,0x03558b,0xed0972,0xbf1e74,0x942977, + 0x682f79,0x32327b,0xfff799,0xc4df9b,0x82ca9c,0x07b89d,0x00a99d,0xfdc689,0xc3b48b,0x8aa48c,0x43978d,0x008c8d,0xf69679,0xc28b7b,0x8f807d,0x56777e, + 0x00707e,0xf1666a,0xc1616c,0x925c6e,0x625870,0x145571,0xed145a,0xbf235e,0x942c61,0x693163,0x343465,0xfff45f,0xc8dd69,0x88c86f,0x2bb673,0x00a775, + 0xfec35a,0xc6b261,0x8ea366,0x4b9669,0x008b6b,0xf79552,0xc48a57,0x927f5c,0x5b775f,0x006f61,0xf26649,0xc2614e,0x945c53,0x645855,0x1c5557,0xed1941, + 0xc02646,0x952e4a,0x6a324d,0x35354e,0xfff200,0xcbdb2a,0x8dc63f,0x39b54a,0x00a650,0xffc20d,0xc8b12f,0x91a23d,0x519546,0x008a4b,0xf7941d,0xc5892f, + 0x947f3a,0x5e7641,0x006f45,0xf26522,0xc3602e,0x955c37,0x66583c,0x22543f,0xed1c24,0xc1272d,0x962e34,0x6b3337,0x363639,0xc7c8ca,0x92b6c7,0x57a5c4, + 0x0097c1,0x008bbf,0xc3a0b2,0x9593b0,0x6486ae,0x177bac,0x0072aa,0xc0799a,0x967099,0x6c6798,0x3a6097,0x005a96,0xbd4f84,0x964b84,0x714784,0x484385, + 0x004185,0xba006f,0x960470,0x741372,0x511b74,0x232176,0xcac6a3,0x97b3a2,0x60a3a0,0x00959f,0x008a9e,0xc59f90,0x98918f,0x6a858e,0x2a7a8e,0x00728d, + 0xc1787d,0x986f7d,0x70677d,0x40607d,0x00597d,0xbd506c,0x984b6c,0x73486d,0x4b446e,0x00416f,0xbb005a,0x970e5c,0x75185e,0x531e60,0x262261,0xcbc37b, + 0x9ab07c,0x65a07d,0x00937d,0x00887e,0xc69c6d,0x9a8f6f,0x6d836f,0x337970,0x007071,0xc17760,0x996e61,0x716663,0x435f63,0x005964,0xbe4f53,0x984b55, + 0x744857,0x4c4458,0x0a4159,0xba0546,0x971549,0x751c4b,0x52214d,0x27244f,0xccc04d,0x9cae53,0x6a9f58,0x1c915c,0x00875e,0xc69a47,0x9b8e4c,0x6f824f, + 0x397853,0x006f55,0xc1753f,0x9a6d43,0x736547,0x465e4a,0x00584c,0xbe4f38,0x994b3b,0x74483f,0x4e4442,0x124144,0xba0e31,0x971934,0x761f37,0x53233a, + 0x28253c,0xccbe00,0x9dad20,0x6d9d30,0x28903a,0x008641,0xc7990b,0x9c8c21,0x71812d,0x3d7735,0x006f3b,0xc27514,0x9b6c21,0x74652a,0x485e30,0x005834, + 0xbe4f17,0x994b20,0x754827,0x4f442c,0x17412f,0xba1319,0x981b1e,0x762123,0x542427,0x2a2529,0x939598,0x6c8896,0x3e7c94,0x007192,0x006991,0x917786, + 0x6f6d84,0x496483,0x055b82,0x005581,0x8f5973,0x705273,0x504b72,0x274572,0x004071,0x8e3762,0x713363,0x543063,0x332d63,0x002b64,0x8c0052,0x710053, + 0x570054,0x3b0256,0x140858,0x95937a,0x6f8679,0x447a78,0x007078,0x006877,0x92766b,0x716c6b,0x4c636a,0x175b6a,0x00546a,0x90585d,0x71515d,0x524b5d, + 0x2b455d,0x00405d,0x8e384f,0x713450,0x553151,0x352e51,0x002c52,0x8c0041,0x710043,0x570144,0x3b0846,0x160d47,0x96915b,0x70845c,0x48785d,0x006e5e, + 0x00665e,0x937450,0x716a51,0x4e6252,0x1e5a53,0x005454,0x905745,0x715047,0x524b48,0x2d4549,0x00404a,0x8d383a,0x71353c,0x55323e,0x362f40,0x002c41, + 0x8b0030,0x700032,0x560835,0x3b0d37,0x161038,0x968f37,0x72823c,0x4a7740,0x006d43,0x006545,0x937231,0x726935,0x506039,0x23593b,0x00533e,0x90562a, + 0x71502e,0x534a31,0x2f4534,0x004036,0x8d3823,0x713527,0x55322a,0x362f2d,0x002d2f,0x8b001d,0x700520,0x560c23,0x3b1026,0x161228,0x968d00,0x728012, + 0x4c7520,0x0d6c28,0x00652e,0x937100,0x726812,0x51601c,0x265823,0x005228,0x905500,0x714f0f,0x534919,0x31441e,0x004022,0x8d3802,0x71350d,0x553215, + 0x37301a,0x012d1d,0x8b0204,0x70090a,0x560f10,0x3b1215,0x171417,0x636466,0x465a65,0x225264,0x004b63,0x004563,0x624e59,0x494758,0x2c4058,0x003a57, + 0x003557,0x61374c,0x4a324c,0x322d4c,0x0f284c,0x00244c,0x601b3f,0x4b1740,0x361441,0x1c1041,0x000d42,0x600032,0x4c0034,0x380035,0x220037,0x000038, + 0x636250,0x475950,0x265150,0x004a50,0x004550,0x624d45,0x494646,0x2e4046,0x003a46,0x003546,0x61363a,0x4a323b,0x332d3c,0x12293c,0x00253c,0x601c30, + 0x4b1931,0x361632,0x1c1333,0x001134,0x5f0024,0x4b0027,0x380029,0x22002a,0x00002b,0x64603a,0x48573b,0x28503c,0x00493d,0x00443d,0x624b31,0x4a4532, + 0x2f3f33,0x003a34,0x003535,0x603628,0x4a312a,0x332d2b,0x14292c,0x00252d,0x5f1d1f,0x4b1a21,0x351823,0x1c1525,0x001226,0x5e0015,0x4b0018,0x37001b, + 0x21001d,0x00001e,0x645f1e,0x495623,0x2a4f26,0x004928,0x00442a,0x624a18,0x4a441c,0x303e1f,0x043922,0x003524,0x603510,0x4a3115,0x332d18,0x15291b, + 0x00261d,0x5f1d07,0x4a1b0d,0x351911,0x1c1714,0x001416,0x5e0000,0x4a0004,0x370008,0x21000c,0x00000e,0x635e00,0x495500,0x2b4e08,0x004811,0x004416, + 0x624a00,0x4a4300,0x303e03,0x07390b,0x003510,0x603500,0x4a3100,0x332d00,0x162904,0x002608,0x5f1e00,0x4a1b00,0x351900,0x1c1700,0x001502,0x5e0000, + 0x4a0000,0x360000,0x210000,0x000000,0x231f20,0x0c1a21,0x001522,0x001123,0x000e23,0x230d15,0x100617,0x000019,0x00001a,0x00001b,0x230008,0x13000d, + 0x00000f,0x000011,0x000012,0x230000,0x150001,0x030005,0x000008,0x00000a,0x230000,0x160000,0x060000,0x000000,0x000001,0x201d12,0x081914,0x001515, + 0x001216,0x001017,0x210c04,0x0e0608,0x00020a,0x00000c,0x00000d,0x220000,0x120000,0x000000,0x000002,0x000003,0x230000,0x140000,0x010000,0x000000, + 0x000000,0x230000,0x150000,0x040000,0x000000,0x000000,0x1e1c00,0x061802,0x001504,0x001306,0x001107,0x200c00,0x0d0700,0x000300,0x000100,0x000000, + 0x210000,0x110000,0x000000,0x000000,0x000000,0x220000,0x130000,0x000000,0x000000,0x000000,0x230000,0x150000,0x030000,0x000000,0x000000,0x1c1b00, + 0x041800,0x001500,0x001300,0x001200,0x1f0b00,0x0b0700,0x000400,0x000200,0x000100,0x210000,0x100000,0x000000,0x000000,0x000000,0x220000,0x120000, + 0x000000,0x000000,0x000000,0x230000,0x140000,0x020000,0x000000,0x000000,0x1b1a00,0x021700,0x001500,0x001400,0x001200,0x1e0b00,0x0a0700,0x000500, + 0x000300,0x000200,0x200000,0x0f0000,0x000000,0x000000,0x000000,0x210000,0x120000,0x000000,0x000000,0x000000,0x220000,0x140000,0x010000,0x000000, + 0x000000 +}}; diff --git a/texk/dvisvgm/dvisvgm-src/src/Color.hpp b/texk/dvisvgm/dvisvgm-src/src/Color.hpp index 25d20b755c..9904c70d20 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Color.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Color.hpp @@ -2,7 +2,7 @@ ** Color.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -36,24 +36,26 @@ class Color { static bool SUPPRESS_COLOR_NAMES; static const Color BLACK; static const Color WHITE; - static const Color TRANSPARENT; - enum class ColorSpace {GRAY, RGB, CMYK, LAB}; + enum class ColorSpace {GRAY, RGB, CMYK, LAB, TRANSPARENT}; public: Color () noexcept =default; - explicit Color (uint32_t rgb) noexcept : _rgb(rgb) {} + explicit Color (uint32_t rgb) noexcept : _value(rgb) {} + Color (uint32_t value, ColorSpace cs) : _value(value), _cspace(cs) {} Color (uint8_t r, uint8_t g, uint8_t b) noexcept {setRGB(r,g,b);} Color (double r, double g, double b) noexcept {setRGB(r,g,b);} explicit Color (const std::valarray &rgb) noexcept {setRGB(rgb);} - explicit Color (const std::string &name); - explicit operator uint32_t () const {return _rgb;} - bool operator == (const Color &c) const {return _rgb == c._rgb;} - bool operator != (const Color &c) const {return _rgb != c._rgb;} - bool operator < (const Color &c) const {return _rgb < c._rgb;} + explicit Color (const std::valarray &rgb, ColorSpace cs) noexcept; + explicit Color (const std::string &colorstr); + explicit operator uint32_t () const {return _value;} + bool operator == (const Color &c) const {return _value == c._value;} + bool operator != (const Color &c) const {return _value != c._value;} + bool operator < (const Color &c) const {return _value < c._value;} Color operator *= (double c); Color operator * (double c) const {return Color(*this) *= c;} - void setRGB (uint8_t r, uint8_t g, uint8_t b) {_rgb = (r << 16) | (g << 8) | b;} + bool isTransparent () const {return _cspace == ColorSpace::TRANSPARENT;} + void setRGB (uint8_t r, uint8_t g, uint8_t b); void setRGB (double r, double g, double b); void setRGB (const std::valarray &rgb) {setRGB(rgb[0], rgb[1], rgb[2]);} bool setRGBHexString (std::string hexString); @@ -62,6 +64,7 @@ class Color { void setGray (double g) {setRGB(g,g,g);} void setGray (const std::valarray &gray) {setRGB(gray[0], gray[0], gray[0]);} void setHSB (double h, double s, double b); + void setCMYK (uint8_t c, uint8_t m, uint8_t y, uint8_t k); void setCMYK (double c, double m, double y, double k); void setCMYK (const std::valarray &cmyk); void setXYZ (double x, double y, double z); @@ -69,12 +72,11 @@ class Color { void setLab (double l, double a, double b); void setLab (const std::valarray &lab); void set (ColorSpace colorSpace, VectorIterator &it); + std::valarray getDoubleValues () const; double getGray () const; void getGray (std::valarray &gray) const; void getRGB (double &r, double &g, double &b) const; void getRGB (std::valarray &rgb) const; - void getCMYK (double &c, double &m, double &y, double &k) const; - void getCMYK (std::valarray &cmyk) const; void getXYZ (double &x, double &y, double &z) const; void getLab (double &l, double &a, double &b) const; void getLab (std::valarray &lab) const; @@ -83,7 +85,6 @@ class Color { std::string svgColorString (bool rgbonly) const; std::string svgColorString () const {return svgColorString(SUPPRESS_COLOR_NAMES);} static void CMYK2RGB (const std::valarray &cmyk, std::valarray &rgb); - static void RGB2CMYK (const std::valarray &rgb, std::valarray &cmyk); static void HSB2RGB (const std::valarray &hsb, std::valarray &rgb); static void RGB2XYZ (std::valarray rgb, std::valarray &xyz); static void XYZ2RGB (const std::valarray &xyz, std::valarray &rgb); @@ -91,8 +92,13 @@ class Color { static void Lab2XYZ (const std::valarray &lab, std::valarray &xyz); static int numComponents (ColorSpace colorSpace); + protected: + uint32_t getRGBUInt32 () const; + std::valarray getRGBDouble () const; + private: - uint32_t _rgb=0; + uint32_t _value=0; + ColorSpace _cspace=ColorSpace::RGB; }; #endif diff --git a/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp index c35f6b0eba..59669e13ce 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp @@ -2,7 +2,7 @@ ** ColorSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -52,8 +52,8 @@ static void read_doubles (istream &is, vector &vec) { * _color model_ _component values_ * Currently, the following color models are supported: rgb, cmyk, hsb and gray. * Examples: rgb 1 0.5 0, gray 0.5 - * @param[in] model the color model - * @param[in] is stream to be read from + * @param[in] model the color model + * @param[in] is stream to be read from * @return resulting Color object */ Color ColorSpecialHandler::readColor (const string &model, istream &is) { Color color; @@ -80,7 +80,7 @@ Color ColorSpecialHandler::readColor (const string &model, istream &is) { } -/** Reads the color model (rgb, cmyk, hsb, or gray) and the corresponding color compontents +/** Reads the color model (rgb, cmyk, hsb, or gray) and the corresponding color components * from a given input stream. * @param[in] is stream to be read from * @return resulting Color object */ @@ -92,27 +92,87 @@ Color ColorSpecialHandler::readColor (istream &is) { bool ColorSpecialHandler::process (const string&, istream &is, SpecialActions &actions) { + char colortype=0; + auto pos = is.tellg(); string cmd; is >> cmd; - if (cmd == "push") // color push - _colorStack.push(readColor(is)); + if (cmd == "push") // color push [fill|stroke] + colortype = processPush(is); else if (cmd == "pop") { if (!_colorStack.empty()) // color pop - _colorStack.pop(); + _colorStack.pop_back(); } - else { // color + else if (cmd == "set") // color set [fill|stroke] + colortype = processSet(is); + else { // color [fill|stroke] while (!_colorStack.empty()) - _colorStack.pop(); - _colorStack.push(readColor(cmd, is)); + _colorStack.pop_back(); + is.seekg(pos); + colortype = processPush(is); + } + if (_colorStack.empty()) { + if (colortype == 0 || colortype == 'f') + actions.setFillColor(_defaultFillColor); + if (colortype == 0 || colortype == 's') + actions.setStrokeColor(_defaultStrokeColor); + } + else { + if (colortype == 0 || colortype == 'f') + actions.setFillColor(_colorStack.back().fillColor); + if (colortype == 0 || colortype == 's') + actions.setStrokeColor(_colorStack.back().strokeColor); } - if (_colorStack.empty()) - actions.setColor(Color::BLACK); - else - actions.setColor(_colorStack.top()); return true; } +/** Parses [fill|stroke] . + * @param[in] is stream to read from + * @param[out] type specified type color type ('f'=fill, 's'=stroke, 0=none specified) + * @return color object representing the specified color */ +static Color read_color_and_type (istream &is, char &type) { + string token; + string model; + is >> token; + if (token == "fill" || token == "stroke") { + is >> model; + type = token[0]; + } + else { + model = std::move(token); + type = '\0'; + } + return ColorSpecialHandler::readColor(model, is); +} + + +/** Handles push [fill|stroke] which pushes a new color pair + * onto the stack. If 'fill' or 'stroke' is specified, only that color value is set. + * The other one is copied from the current corresponding value. + * @return color type specified in the special command ('f'=fill, 's'=stroke, 0=none specified) */ +char ColorSpecialHandler::processPush (istream &is) { + _colorStack.emplace_back(ColorPair{}); + return processSet(is); +} + + +/** Handles set [fill|stroke] which changes the current + * color pair without pushing new ones. If the stack is empty, the default + * color values (usually black) are changed. + * @return color type specified in the special command ('f'=fill, 's'=stroke, 0=none specified) */ +char ColorSpecialHandler::processSet (istream &is) { + char type; + Color color = read_color_and_type(is, type); + Color &fillColor = _colorStack.empty() ? _defaultFillColor : _colorStack.back().fillColor; + Color &strokeColor = _colorStack.empty() ? _defaultStrokeColor : _colorStack.back().strokeColor; + if (type == 0 || type == 'f') + fillColor = color; + if (type == 0 || type == 's') + strokeColor = color; + return type; +} + + vector ColorSpecialHandler::prefixes () const { vector pfx {"color"}; return pfx; diff --git a/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp index 20a589bfa1..0b59bc7d50 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp @@ -2,7 +2,7 @@ ** ColorSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -29,6 +29,12 @@ class ColorSpecialHandler : public SpecialHandler { + private: + struct ColorPair { + Color fillColor; + Color strokeColor; + }; + public: bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; static Color readColor (std::istream &is); @@ -37,9 +43,16 @@ class ColorSpecialHandler : public SpecialHandler { static const char* handlerName () {return "color";} const char* info () const override {return "complete support of color specials";} std::vector prefixes () const override; + size_t stackSize () const {return _colorStack.size();} + + protected: + char processPush (std::istream &is); + char processSet (std::istream &is); private: - std::stack _colorStack; + Color _defaultFillColor = Color::BLACK; + Color _defaultStrokeColor = Color::BLACK; + std::vector _colorStack; }; #endif diff --git a/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp b/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp index 76f8208d07..f53085b62d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp @@ -2,7 +2,7 @@ // It is part of the dvisvgm package and published under the terms // of the GNU General Public License version 3, or (at your option) any later version. // See file COPYING for further details. -// Copyright (C) 2016-2024 Martin Gieseking +// Copyright (C) 2016-2025 Martin Gieseking #ifndef COMMANDLINE_HPP #define COMMANDLINE_HPP @@ -20,7 +20,7 @@ class CommandLine : public CL::CommandLine { CommandLine () : CL::CommandLine( "This program converts DVI files, as created by TeX/LaTeX, as well as\nEPS and PDF files to the XML-based scalable vector graphics format SVG.", "[options] dvifile\n--eps [options] epsfile\n--pdf [options] pdffile", - "Copyright (C) 2005-2024 Martin Gieseking " + "Copyright (C) 2005-2025 Martin Gieseking " ) {} CommandLine (int argc, char **argv) : CommandLine() { diff --git a/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp b/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp index 583573d19b..24980de34c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp @@ -2,7 +2,7 @@ ** DLLoader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp b/texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp index 67b7c73a95..0cd92f34af 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp @@ -2,7 +2,7 @@ ** DLLoader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp b/texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp index 04cdec2cdb..aec6215540 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp @@ -2,7 +2,7 @@ ** DVIActions.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp b/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp index 01501f29b0..84c94dc46a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp @@ -2,7 +2,7 @@ ** DVIReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp b/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp index b221960cb6..a384ee44ec 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp @@ -2,7 +2,7 @@ ** DVIReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp b/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp index a1da593d08..de78691aec 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp @@ -2,7 +2,7 @@ ** DVIToSVG.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -102,7 +102,7 @@ void DVIToSVG::convert (unsigned first, unsigned last, HashFunction *hashFunc) { hashFunc->update(PAGE_HASH_SETTINGS.optionsHash()); combinedHash = hashFunc->digestString(); } - const SVGOutput::HashTriple hashTriple(dviHash, shortenedOptHash, combinedHash); + const SVGOutput::HashTriple hashTriple(dviHash, shortenedOptHash, std::move(combinedHash)); FilePath path = _out.filepath(i, numberOfPages(), hashTriple); if (!dviHash.empty() && !PAGE_HASH_SETTINGS.isSet(HashSettings::P_REPLACE) && path.exists()) { Message::mstream(false, Message::MC_PAGE_NUMBER) << "skipping page " << i; @@ -150,7 +150,7 @@ static unique_ptr create_hash_function (const string &algo) { msg += name + ", "; msg.pop_back(); msg.back() = ')'; - throw MessageException(msg); + throw MessageException(std::move(msg)); } @@ -300,13 +300,12 @@ void DVIToSVG::leaveEndPage (unsigned) { Message::wstream(false) << "\npage is empty\n"; if (_bboxFormatString != "none") { _svg.setBBox(bbox); - const double bp2pt = 72.27/72; - const double bp2mm = 25.4/72; + const double bp2pt = (1_bp).pt(); Message::mstream(false) << '\n'; Message::mstream(false, Message::MC_PAGE_SIZE) << "graphic size: " << XMLString(bbox.width()*bp2pt) << "pt" " x " << XMLString(bbox.height()*bp2pt) << "pt" - " (" << XMLString(bbox.width()*bp2mm) << "mm" - " x " << XMLString(bbox.height()*bp2mm) << "mm)"; + " (" << XMLString(bbox.width()) << "bp" + " x " << XMLString(bbox.height()) << "bp)"; Message::mstream(false) << '\n'; } } @@ -580,7 +579,7 @@ void DVIToSVG::HashSettings::setParameters (const string ¶mstr) { msg.pop_back(); msg.pop_back(); msg += ')'; - throw MessageException(msg); + throw MessageException(std::move(msg)); } } } diff --git a/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp b/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp index 1f749bf729..19109f6ebb 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp @@ -2,7 +2,7 @@ ** DVIToSVG.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -39,8 +39,8 @@ class DVIToSVG : public DVIReader { enum Parameter {P_LIST, P_REPLACE}; void setParameters (const std::string ¶mstr); void setOptionHash (const std::string &optHash) {_optHash = optHash;} - std::string algorithm () const {return _algo;} - std::string optionsHash () const {return _optHash;} + const std::string& algorithm () const {return _algo;} + const std::string& optionsHash () const {return _optHash;} bool isSet (Parameter param) {return _params.find(param) != _params.end();} private: @@ -65,7 +65,7 @@ class DVIToSVG : public DVIReader { void listHashes (const std::string &rangestr, std::ostream &os); FilePath getSVGFilePath (unsigned pageno) const; - std::string getUserBBoxString () const {return _bboxFormatString;} + const std::string& getUserBBoxString () const {return _bboxFormatString;} static void setProcessSpecials (const char *ignorelist=nullptr, bool pswarning=false); public: diff --git a/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp b/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp index 6970be756e..dcba15c88c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp @@ -2,7 +2,7 @@ ** DVIToSVGActions.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -32,11 +32,10 @@ using namespace std; -void DVIToSVGActions::reset() { +void DVIToSVGActions::reset () { FontManager::instance().resetUsedChars(); - _bbox = BoundingBox(); - _currentFontNum = -1; - _bgcolor = Color::TRANSPARENT; + _bbox.invalidate(); + _bgcolor = Color(0, Color::ColorSpace::TRANSPARENT); } @@ -168,7 +167,7 @@ void DVIToSVGActions::setRule (double x, double y, double height, double width) rect->addAttribute("height", height); rect->addAttribute("width", width); rect->setTransform(getMatrix()); - rect->setFillColor(_svg.getColor()); + rect->setFillColor(_svg.getFillColor()); _svg.appendToPage(std::move(rect)); // update bounding box @@ -184,7 +183,6 @@ void DVIToSVGActions::setRule (double x, double y, double height, double width) * @param[in] num unique number of the font in the DVI file (not necessarily equal to the DVI font number) * @param[in] font pointer to the font object (always represents a physical font and never a virtual font) */ void DVIToSVGActions::setFont (int num, const Font &font) { - _currentFontNum = num; _svg.setFont(num, font); } @@ -215,6 +213,7 @@ void DVIToSVGActions::beginPage (unsigned pageno, const vector&) { _svg.newPage(++_pageCount); _bbox = BoundingBox(); // clear bounding box _boxes.clear(); + setMatrix(Matrix(1)); SpecialManager::instance().notifyBeginPage(pageno, *this); } @@ -229,7 +228,7 @@ void DVIToSVGActions::endPage (unsigned pageno) { } Matrix matrix = _dvireader->getPageTransformation(); _svg.transformPage(matrix); - if (_bgcolor != Color::TRANSPARENT) { + if (!_bgcolor.isTransparent()) { // create a rectangle filled with the background color auto rect = util::make_unique("rect"); rect->addAttribute("x", _bbox.minX()); @@ -247,14 +246,14 @@ void DVIToSVGActions::setBgColor (const Color &color) { } -void DVIToSVGActions::embed(const BoundingBox &bbox) { +void DVIToSVGActions::embed (const BoundingBox &bbox) { _bbox.embed(bbox); for (auto &strboxpair : _boxes) strboxpair.second.embed(bbox); } -void DVIToSVGActions::embed(const DPair& p, double r) { +void DVIToSVGActions::embed (const DPair& p, double r) { if (r == 0) _bbox.embed(p); else @@ -264,7 +263,7 @@ void DVIToSVGActions::embed(const DPair& p, double r) { } -BoundingBox& DVIToSVGActions::bbox(const string& name, bool reset) { +BoundingBox& DVIToSVGActions::bbox (const string& name, bool reset) { BoundingBox &box = _boxes[name]; if (reset) box = BoundingBox(); diff --git a/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.hpp b/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.hpp index 7dc55536cc..14e4c17779 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.hpp @@ -2,7 +2,7 @@ ** DVIToSVGActions.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -45,13 +45,15 @@ class DVIToSVGActions : public DVIActions, public SpecialActions { void setChar (double x, double y, unsigned c, bool vertical, const Font &f) override; void setRule (double x, double y, double height, double width) override; void setBgColor (const Color &color) override; - void setColor (const Color &color) override {_svg.setColor(color);} + void setFillColor (const Color &color) override {_svg.setFillColor(color);} + void setStrokeColor (const Color &color) override {_svg.setStrokeColor(color);} void setMatrix (const Matrix &m) override {_svg.setMatrix(m);} void setOpacity (const Opacity &opacity) override {_svg.setOpacity(opacity);} const Opacity& getOpacity () const override {return _svg.getOpacity();} const Matrix& getMatrix () const override {return _svg.getMatrix();} Matrix getPageTransformation () const override {return _dvireader->getPageTransformation();} - Color getColor () const override {return _svg.getColor();} + Color getFillColor () const override {return _svg.getFillColor();} + Color getStrokeColor () const override {return _svg.getStrokeColor();} int getDVIStackDepth () const override {return _dvireader->stackDepth();} unsigned getCurrentPageNumber () const override {return _dvireader->currentPageNumber();} void setTextOrientation (bool vertical) override {_svg.setVertical(vertical);} @@ -85,8 +87,7 @@ class DVIToSVGActions : public DVIActions, public SpecialActions { BasicDVIReader *_dvireader; BoundingBox _bbox; int _pageCount=0; - int _currentFontNum=-1; - Color _bgcolor=Color::TRANSPARENT; + Color _bgcolor=Color(0, Color::ColorSpace::TRANSPARENT); BoxMap _boxes; bool _outputLocked=false; }; diff --git a/texk/dvisvgm/dvisvgm-src/src/Directory.cpp b/texk/dvisvgm/dvisvgm-src/src/Directory.cpp index 35c8c49b34..8cffd6cdef 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Directory.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Directory.cpp @@ -2,7 +2,7 @@ ** Directory.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -48,9 +48,11 @@ Directory::~Directory () { bool Directory::open (string dirname) { _dirname = dirname; #ifdef _WIN32 + if (dirname.empty()) + return false; _firstread = true; - if (dirname[dirname.length()-1] == '/' || dirname[dirname.length()-1] == '\\') - dirname = dirname.substr(0, dirname.length()-1); + if (dirname.back() == '/' || dirname.back() == '\\') + dirname.pop_back(); dirname += "\\*"; _handle = FindFirstFile(dirname.c_str(), &_fileData); return _handle != INVALID_HANDLE_VALUE; diff --git a/texk/dvisvgm/dvisvgm-src/src/Directory.hpp b/texk/dvisvgm/dvisvgm-src/src/Directory.hpp index 6c55e03280..6935147e42 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Directory.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Directory.hpp @@ -2,7 +2,7 @@ ** Directory.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp index ca1f4a7fc1..2cd246f2f3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp @@ -2,7 +2,7 @@ ** DvisvgmSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -22,6 +22,8 @@ #include #include "Calculator.hpp" #include "DvisvgmSpecialHandler.hpp" +#include "FileFinder.hpp" +#include "FileSystem.hpp" #include "GraphicsPathParser.hpp" #include "InputBuffer.hpp" #include "InputReader.hpp" @@ -355,20 +357,51 @@ void DvisvgmSpecialHandler::processBBox (InputReader &ir, SpecialActions &action } +inline string filename_suffix (const string &fname) { + string ret; + auto pos = fname.rfind('.'); + if (pos != string::npos) + ret = util::tolower(fname.substr(pos+1)); + return ret; +} + + void DvisvgmSpecialHandler::processImg (InputReader &ir, SpecialActions &actions) { try { - Length w = read_length(ir); - Length h = read_length(ir); - string f = ir.getString(); - update_bbox(w, h, Length(0), false, actions); - auto img = util::make_unique("image"); - img->addAttribute("x", actions.getX()); - img->addAttribute("y", actions.getY()); - img->addAttribute("width", w.bp()); - img->addAttribute("height", h.bp()); - img->addAttribute("xlink:href", f); - img->setTransform(actions.getMatrix()); - actions.svgTree().appendToPage(std::move(img)); + const Length width = read_length(ir); + const Length height = read_length(ir); + const string fname = ir.getString(); + const string suffix = filename_suffix(fname); + + string pathstr; + if (const char *path = FileFinder::instance().lookup(fname, false)) + pathstr = FileSystem::ensureForwardSlashes(path); + if ((pathstr.empty() || !FileSystem::exists(pathstr)) && FileSystem::exists(fname)) + pathstr = fname; + if (pathstr.empty()) + Message::wstream(true) << "file '" << fname << "' not found\n"; + + update_bbox(width, height, Length(0), true, actions); + auto imgageNode = util::make_unique("image"); + imgageNode->addAttribute("x", actions.getX()); + imgageNode->addAttribute("y", actions.getY()-height.bp()); + imgageNode->addAttribute("width", width.bp()); + imgageNode->addAttribute("height", height.bp()); + + string mimetype = util::mimetype(fname); + if (SVGTree::EMBED_BITMAP_DATA && (mimetype == "image/jpeg" || mimetype == "image/png")) + imgageNode->addAttribute("@@xlink:href", "data:"+mimetype+";base64,"+fname); + else { + string href = fname; + // Only reference the image with an absolute path if either an absolute path was given by the user + // or a given plain filename is not present in the current working directory but was found through + // the FileFinder, i.e. it's usually located somewhere in the texmf tree. + if (!FilePath::isAbsolute(fname) && (fname.find('/') != string::npos || FilePath(fname).exists())) + href = FilePath(pathstr).relative(FilePath(actions.getSVGFilePath(1))); + imgageNode->addAttribute("xlink:href", href); + } + imgageNode->setTransform(actions.getMatrix()); + actions.svgTree().appendToPage(std::move(imgageNode)); } catch (const UnitException &e) { throw SpecialException(string("dvisvgm:img: ") + e.what()); @@ -378,7 +411,7 @@ void DvisvgmSpecialHandler::processImg (InputReader &ir, SpecialActions &actions void DvisvgmSpecialHandler::processCurrentColor (InputReader &ir, SpecialActions &actions) { string param = ir.getString(); - Color color = actions.getColor(); + Color color = actions.getFillColor(); if (param.empty() || param == "on") { SVGElement::CURRENTCOLOR = color; SVGElement::USE_CURRENTCOLOR = true; @@ -386,8 +419,8 @@ void DvisvgmSpecialHandler::processCurrentColor (InputReader &ir, SpecialActions else if (param == "off") { if (SVGElement::USE_CURRENTCOLOR) { // force a color change to get the new currentColor setting recognized - actions.setColor(Color{uint32_t(color)+1}); - actions.setColor(color); + actions.setFillColor(Color{uint32_t(color)+1}); + actions.setFillColor(color); SVGElement::USE_CURRENTCOLOR = false; } } diff --git a/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp index 5d04b28952..a718bba02b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp @@ -2,7 +2,7 @@ ** DvisvgmSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp b/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp index abd6fcea8a..dd6f884f15 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp @@ -2,7 +2,7 @@ ** EPSFile.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp b/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp index 8ded7f3963..f9f7eb0f7c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp @@ -2,7 +2,7 @@ ** EPSFile.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp b/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp index 73bec35422..98ae9435e7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp @@ -2,7 +2,7 @@ ** EPSToSVG.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.cpp b/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.cpp index 299530ef7d..664cc6ee24 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.cpp @@ -2,7 +2,7 @@ ** EllipticalArc.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.hpp b/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.hpp index e5a0954f72..5b837f86da 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.hpp @@ -2,7 +2,7 @@ ** EllipticalArc.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp index e939343a13..7fc4d77534 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp @@ -2,7 +2,7 @@ ** EmSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -86,7 +86,7 @@ static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, dou node->addAttribute("x2", p2.x()); node->addAttribute("y2", p2.y()); node->setStrokeWidth(lw); - node->setStrokeColor(actions.getColor()); + node->setStrokeColor(actions.getStrokeColor()); node->setStrokeOpacity(actions.getOpacity()); // update bounding box @@ -108,7 +108,7 @@ static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, dou node = util::make_unique("polygon"); node->setPoints(points); - node->setFillColor(actions.getColor()); + node->setFillColor(actions.getFillColor()); node->setFillOpacity(actions.getOpacity()); // update bounding box diff --git a/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp index 1c195a2b57..03d01ba59b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp @@ -2,7 +2,7 @@ ** EmSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/EncFile.cpp b/texk/dvisvgm/dvisvgm-src/src/EncFile.cpp index d8ad95bca4..84311ded58 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EncFile.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/EncFile.cpp @@ -2,7 +2,7 @@ ** EncFile.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -86,7 +86,7 @@ void EncFile::read (istream &is) { if (entry == ".notdef") entry.clear(); if (n < 256) - _table[n++] = entry; + _table[n++] = std::move(entry); } } // remove trailing .notdef names diff --git a/texk/dvisvgm/dvisvgm-src/src/EncFile.hpp b/texk/dvisvgm/dvisvgm-src/src/EncFile.hpp index 4a991f59d2..1266bc02c9 100644 --- a/texk/dvisvgm/dvisvgm-src/src/EncFile.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/EncFile.hpp @@ -2,7 +2,7 @@ ** EncFile.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp b/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp index 9ba1443de1..6698718000 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp @@ -2,7 +2,7 @@ ** FileFinder.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp b/texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp index c379c1fde1..289ab363a7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp @@ -2,7 +2,7 @@ ** FileFinder.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp b/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp index 441f2cf85b..62125f7915 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp @@ -2,7 +2,7 @@ ** FilePath.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -70,10 +70,10 @@ bool FilePath::Directory::operator == (const Directory &dir) const { /** Constructs a FilePath object. * @param[in] path absolute or relative path to a file or directory - * @param[in] isfile true if 'path' references a file, false if a directory is referenced + * @param[in] type type of path (file or directory) * @param[in] current_dir if 'path' is a relative path expression it will be related to 'current_dir' */ -FilePath::FilePath (const string &path, bool isfile, const string ¤t_dir) { - init(path, isfile, current_dir); +FilePath::FilePath (const std::string &path, PathType type, const std::string ¤t_dir) { + init(path, type, current_dir); } @@ -81,32 +81,32 @@ FilePath::FilePath (const string &path, bool isfile, const string ¤t_dir) * Relative paths are relative to the current working directory. * @param[in] path absolute or relative path to a file or directory */ void FilePath::set (const string &path) { - set(path, !FileSystem::isDirectory(path)); + set(path, FileSystem::isDirectory(path) ? PT_DIR : PT_FILE); } /** Assigns a new path. Relative paths are relative to the current working directory. * @param[in] path absolute or relative path to a file or directory - * @param[in] isfile true if 'path' references a file, false if a directory is referenced */ -void FilePath::set (const string &path, bool isfile) { - init(path, isfile, ""); + * @param[in] type type of path (file or directory) */ +void FilePath::set (const std::string &path, PathType type) { + init(path, type, ""); } /** Assigns a new path. Relative paths are relative to the current working directory. * @param[in] path absolute or relative path to a file or directory - * @param[in] isfile true if 'path' references a file, false if a directory is referenced + * @param[in] type type of path (file or directory) * @param[in] current_dir if 'path' is a relative path expression it will be related to 'current_dir' */ -void FilePath::set (const string &path, bool isfile, const string ¤t_dir) { - init(path, isfile, current_dir); +void FilePath::set (const std::string &path, PathType type, const std::string ¤t_dir) { + init(path, type, current_dir); } /** Initializes a FilePath object. This method should be called by the constructors only. * @param[in] path absolute or relative path to a file or directory - * @param[in] isfile true if 'path' references a file, false if a directory is referenced - * @param[in] current_dir if 'path' is a relative path expression it will be related to 'current_dir' */ -void FilePath::init (string path, bool isfile, string current_dir) { + * @param[in] type type of path (file or directory) + * @param[in] current_dir if 'path' is a relative path expression, it will be related to 'current_dir' */ +void FilePath::init (string path, PathType type, string current_dir) { _dirs.clear(); _fname.clear(); single_slashes(path); @@ -116,14 +116,14 @@ void FilePath::init (string path, bool isfile, string current_dir) { current_dir = FileSystem::getcwd(); #else _drive = strip_drive_letter(path); - if (current_dir.empty() || drive_letter(current_dir) != _drive) + if (current_dir.empty() || (_drive && drive_letter(current_dir) != _drive)) current_dir = FileSystem::getcwd(_drive); if (!_drive) _drive = drive_letter(current_dir); strip_drive_letter(current_dir); path = FileSystem::ensureForwardSlashes(path); #endif - if (isfile) { + if (type == PT_FILE) { auto pos = path.rfind('/'); _fname = path.substr((pos == string::npos) ? 0 : pos+1); // remove filename from path @@ -245,7 +245,7 @@ string FilePath::relative (string reldir, bool with_filename) const { #endif if (!isAbsolute) return absolute(); - FilePath relpath(reldir, false); + FilePath relpath(reldir, PT_DIR); string path; auto it1 = _dirs.begin(); auto it2 = relpath._dirs.begin(); @@ -282,7 +282,7 @@ string FilePath::relative (const FilePath &filepath, bool with_filename) const { * @param[in] with_filename if false, the filename is omitted */ string FilePath::shorterAbsoluteOrRelative (string reldir, bool with_filename) const { string abs = absolute(with_filename); - string rel = relative(reldir, with_filename); + string rel = relative(std::move(reldir), with_filename); return abs.length() < rel.length() ? abs : rel; } diff --git a/texk/dvisvgm/dvisvgm-src/src/FilePath.hpp b/texk/dvisvgm/dvisvgm-src/src/FilePath.hpp index 8833d6beb3..751019661b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FilePath.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FilePath.hpp @@ -2,7 +2,7 @@ ** FilePath.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -38,14 +38,17 @@ class FilePath { std::string _dirstr; }; + public: + enum PathType {PT_DIR, PT_FILE}; + public: FilePath () =default; explicit FilePath (const std::string &path) {set(path);} - FilePath (const std::string &path, bool isfile) : FilePath(path, isfile, "") {} - FilePath (const std::string &path, bool isfile, const std::string ¤t_dir); + FilePath (const std::string &path, PathType type) : FilePath(path, type, "") {} + FilePath (const std::string &path, PathType type, const std::string ¤t_dir); void set (const std::string &path); - void set (const std::string &path, bool isfile); - void set (const std::string &path, bool isfile, const std::string ¤t_dir); + void set (const std::string &path, PathType type); + void set (const std::string &path, PathType type, const std::string ¤t_dir); std::string absolute (bool with_filename=true) const; std::string relative (std::string reldir="", bool with_filename=true) const; std::string relative (const FilePath &filepath, bool with_filename=true) const; @@ -62,7 +65,7 @@ class FilePath { static bool isAbsolute (std::string path); protected: - void init (std::string path, bool isfile, std::string current_dir); + void init (std::string path, PathType type, std::string current_dir); void add (const std::string &elem); private: diff --git a/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp b/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp index 940d77364f..5f8696c49d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp @@ -2,7 +2,7 @@ ** FileSystem.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp b/texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp index ca437e8e97..4eb6d7faab 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp @@ -2,7 +2,7 @@ ** FileSystem.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FixWord.hpp b/texk/dvisvgm/dvisvgm-src/src/FixWord.hpp index e8ad8a3155..8b475c89b5 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FixWord.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FixWord.hpp @@ -2,7 +2,7 @@ ** FixWord.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Font.cpp b/texk/dvisvgm/dvisvgm-src/src/Font.cpp index 56b4c635b0..b066777796 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Font.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Font.cpp @@ -2,7 +2,7 @@ ** Font.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -56,7 +56,7 @@ const FontMap::Entry* Font::fontMapEntry () const { string fontname = name(); auto pos = fontname.rfind('.'); if (pos != string::npos) - fontname = fontname.substr(0, pos); // strip extension + fontname.resize(pos); // strip extension return FontMap::instance().lookup(fontname); } diff --git a/texk/dvisvgm/dvisvgm-src/src/Font.hpp b/texk/dvisvgm/dvisvgm-src/src/Font.hpp index c8a2e340a9..11514e367a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Font.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Font.hpp @@ -2,7 +2,7 @@ ** Font.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -198,11 +198,11 @@ class TFMFont : public virtual Font { }; -class PhysicalFontProxy : public PhysicalFont { +class PhysicalFontRef : public PhysicalFont { friend class PhysicalFontImpl; public: std::unique_ptr clone (double ds, double sc) const override { - return std::unique_ptr(new PhysicalFontProxy(*this, ds, sc)); + return std::unique_ptr(new PhysicalFontRef(*this, ds, sc)); } const Font* uniqueFont () const override {return _pf;} @@ -224,8 +224,8 @@ class PhysicalFontProxy : public PhysicalFont { int collectCharMapIDs (std::vector &charmapIDs) const override {return _pf->collectCharMapIDs(charmapIDs);} protected: - PhysicalFontProxy (const PhysicalFont *font, double ds, double ss) : _pf(font), _dsize(ds), _ssize(ss) {} - PhysicalFontProxy (const PhysicalFontProxy &proxy, double ds, double ss) : _pf(proxy._pf), _dsize(ds), _ssize(ss) {} + PhysicalFontRef (const PhysicalFont *font, double ds, double ss) : _pf(font), _dsize(ds), _ssize(ss) {} + PhysicalFontRef (const PhysicalFontRef &ref, double ds, double ss) : _pf(ref._pf), _dsize(ds), _ssize(ss) {} private: const PhysicalFont *_pf; @@ -240,7 +240,7 @@ class PhysicalFontImpl : public PhysicalFont, public TFMFont { ~PhysicalFontImpl () override; std::unique_ptr clone (double ds, double ss) const override { - return std::unique_ptr(new PhysicalFontProxy(this, ds, ss)); + return std::unique_ptr(new PhysicalFontRef(this, ds, ss)); } const Font* uniqueFont () const override {return this;} @@ -301,15 +301,15 @@ class NativeFont : public PhysicalFont { }; -class NativeFontProxy : public NativeFont { +class NativeFontRef : public NativeFont { friend class NativeFontImpl; public: std::unique_ptr clone (double ptsize, const FontStyle &style, Color color) const override { - return std::unique_ptr(new NativeFontProxy(this, ptsize, style, color)); + return std::unique_ptr(new NativeFontRef(this, ptsize, style, color)); } std::unique_ptr clone (double ds, double sc) const override { - return std::unique_ptr(new NativeFontProxy(this , sc, *style(), color())); + return std::unique_ptr(new NativeFontRef(this , sc, *style(), color())); } const NativeFont* uniqueFont () const override {return _nfont;} @@ -326,7 +326,7 @@ class NativeFontProxy : public NativeFont { } protected: - NativeFontProxy (const NativeFont *nfont, double ptsize, const FontStyle &style, Color color) + NativeFontRef (const NativeFont *nfont, double ptsize, const FontStyle &style, Color color) : NativeFont(ptsize, style, color), _nfont(nfont) {} private: @@ -342,11 +342,11 @@ class NativeFontImpl : public NativeFont { NativeFontImpl (std::string fname, std::string fontname, double ptsize); std::unique_ptr clone (double ptsize, const FontStyle &style, Color color) const override { - return std::unique_ptr(new NativeFontProxy(this, ptsize, style, color)); + return std::unique_ptr(new NativeFontRef(this, ptsize, style, color)); } std::unique_ptr clone (double ds, double sc) const override { - return std::unique_ptr(new NativeFontProxy(this , sc, *style(), color())); + return std::unique_ptr(new NativeFontRef(this , sc, *style(), color())); } const char* path () const override {return _path.c_str();} @@ -367,11 +367,11 @@ class NativeFontImpl : public NativeFont { }; -class VirtualFontProxy : public VirtualFont { +class VirtualFontRef : public VirtualFont { friend class VirtualFontImpl; public: std::unique_ptr clone (double ds, double ss) const override { - return std::unique_ptr(new VirtualFontProxy(*this, ds, ss)); + return std::unique_ptr(new VirtualFontRef(*this, ds, ss)); } const Font* uniqueFont () const override {return _vf;} @@ -387,8 +387,8 @@ class VirtualFontProxy : public VirtualFont { const char* path () const override {return _vf->path();} protected: - VirtualFontProxy (const VirtualFont *font, double ds, double ss) : _vf(font), _dsize(ds), _ssize(ss) {} - VirtualFontProxy (const VirtualFontProxy &proxy, double ds, double ss) : _vf(proxy._vf), _dsize(ds), _ssize(ss) {} + VirtualFontRef (const VirtualFont *font, double ds, double ss) : _vf(font), _dsize(ds), _ssize(ss) {} + VirtualFontRef (const VirtualFontRef &ref, double ds, double ss) : _vf(ref._vf), _dsize(ds), _ssize(ss) {} void assignChar (uint32_t c, DVIVector &&dvi) override {} private: @@ -402,7 +402,7 @@ class VirtualFontImpl : public VirtualFont, public TFMFont { friend class VirtualFont; public: std::unique_ptr clone (double ds, double ss) const override { - return std::unique_ptr(new VirtualFontProxy(this, ds, ss)); + return std::unique_ptr(new VirtualFontRef(this, ds, ss)); } const Font* uniqueFont () const override {return this;} diff --git a/texk/dvisvgm/dvisvgm-src/src/FontCache.cpp b/texk/dvisvgm/dvisvgm-src/src/FontCache.cpp index d3917d67c1..f0ef0c1e73 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontCache.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontCache.cpp @@ -2,7 +2,7 @@ ** FontCache.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontCache.hpp b/texk/dvisvgm/dvisvgm-src/src/FontCache.hpp index e603a93ff8..cc4d4a4bdb 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontCache.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontCache.hpp @@ -2,7 +2,7 @@ ** FontCache.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp b/texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp index b898327e6f..0b4841e8bb 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp @@ -2,7 +2,7 @@ ** FontEncoding.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp b/texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp index f971229314..31117932e3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp @@ -2,7 +2,7 @@ ** FontEncoding.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp b/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp index 18ab319517..b2ba50b49c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp @@ -2,7 +2,7 @@ ** FontEngine.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -188,7 +188,7 @@ unique_ptr FontEngine::createCustomToUnicodeMap () { } FT_Set_Charmap(_currentFace, ftcharmap); } - return std::move(charmap); + return charmap; } diff --git a/texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp b/texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp index 9b08994a29..7bdb947f41 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp @@ -2,7 +2,7 @@ ** FontEngine.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -77,7 +77,6 @@ class FontEngine { int charIndex (const Character &c) const; private: - mutable unsigned int _currentChar=0, _currentGlyphIndex=0; FT_Face _currentFace = nullptr; FT_Library _library; const Font *_currentFont = nullptr; diff --git a/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp b/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp index 2a5778326a..ce3edcc2c3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp @@ -2,7 +2,7 @@ ** FontManager.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontManager.hpp b/texk/dvisvgm/dvisvgm-src/src/FontManager.hpp index a2deb89d95..3859a6fd8c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontManager.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontManager.hpp @@ -2,7 +2,7 @@ ** FontManager.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp b/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp index 5991c4779e..564f040e52 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp @@ -2,7 +2,7 @@ ** FontMap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -26,6 +26,7 @@ #include "CMap.hpp" #include "Directory.hpp" #include "FileFinder.hpp" +#include "FilePath.hpp" #include "FontManager.hpp" #include "FontMap.hpp" #include "MapLine.hpp" @@ -43,48 +44,127 @@ FontMap& FontMap::instance() { /** Reads and evaluates a single font map file. - * @param[in] fname name of map file to read + * @param[in] fname path/name of map file to read (it's not looked up via FileFinder) * @param[in] mode selects how to integrate the map file entries into the global map tree + * @param[in,out] includedFilesRef pointer to sequence of (nested) file paths currently being included * @return true if file could be opened */ -bool FontMap::read (const string &fname, FontMap::Mode mode) { +bool FontMap::read (const string &fname, FontMap::Mode mode, vector *includedFilesRef) { ifstream ifs(fname); if (!ifs) return false; - int line_number = 1; + unique_ptr> includedFilesStore; + int lineNumber = 1; while (ifs) { - int c = ifs.peek(); - if (c < 0 || strchr("\n&#%;*", c)) // comment or empty line? - ifs.ignore(numeric_limits::max(), '\n'); - else { - try { + try { + int c = ifs.peek(); + if (c < 0 || strchr("\n&%;*", c)) // comment or empty line? + ifs.ignore(numeric_limits::max(), '\n'); + else if (c != '#') { MapLine mapline(ifs); apply(mapline, mode); } - catch (const MapLineException &e) { - Message::wstream(true) << fname << ", line " << line_number << ": " << e.what() << '\n'; - } - catch (const SubfontException &e) { - Message::wstream(true) << e.filename(); - if (e.lineno() > 0) - Message::wstream(false) << ", line " << e.lineno(); - Message::wstream(false) << e.what() << '\n'; + else { + char line[256]; + ifs.getline(line, 256); + if (strncmp(line, "#include ", 9) == 0 || strncmp(line, "#includefirst ", 14) == 0) { + FilePath path(fname); + if (!includedFilesRef && !includedFilesStore) { // not yet inside an include chain? + includedFilesStore = util::make_unique>(); + includedFilesRef = includedFilesStore.get(); + includedFilesRef->emplace_back(path.absolute()); + } + if (strncmp(line, "#include ", 9) == 0) + include(line+9, path, *includedFilesRef); + else + includefirst(line+14, path, *includedFilesRef); + } } + lineNumber++; + } + catch (const MapLineException &e) { + Message::wstream(true) << FilePath(fname).shorterAbsoluteOrRelative() + << ", line " << lineNumber << ": " << e.what() << '\n'; + } + catch (const SubfontException &e) { + Message::wstream(true) << FilePath(e.filename()).shorterAbsoluteOrRelative(); + if (e.lineno() > 0) + Message::wstream(false) << ", line " << e.lineno(); + Message::wstream(false) << e.what() << '\n'; } - line_number++; } return true; } -bool FontMap::read (const string &fname, char modechar) { +/** Reads and evaluates a single font map file. + * @param[in] fname path/name of map file to read (it's not looked up via FileFinder) + * @param[in] mode character '+', '-', or '=' to determine how the map file entries are merged into the global map tree + * @param[in,out] includedFilesRef pointer to sequence of (nested) file paths currently being included + * @return true if file could be opened */ +bool FontMap::read (const string &fname, char modechar, vector *includedFilesRef) { Mode mode; switch (modechar) { case '=': mode = Mode::REPLACE; break; case '-': mode = Mode::REMOVE; break; default : mode = Mode::APPEND; } - return read(fname, mode); + return read(fname, mode, includedFilesRef); +} + + +/** Evaluates an #include statement and processes the contents of the included map file. + * @param[in] line parameters of #include statement (optional mode character and file name/path + * @param[in] includingFile path of file containing the #include statement + * @param[in,out] includedFiles sequence of (nested) file paths currently being included */ +void FontMap::include (string line, const FilePath &includingFile, vector &includedFiles) { + auto it = line.begin(); + while (it != line.end() && isspace(*it)) + ++it; + char modechar = '+'; + if (it != line.end() && strchr("+-=", *it)) + modechar = *it++; + string fname = util::trim(line.substr(it-line.begin())); + if (fname.size() > 1 && fname[0] == '"' && fname.back() == '"') + fname = fname.substr(1, fname.size()-2); // strip surrounding quotes + if (fname.empty()) + throw FontMapException("file name missing after #include"); + + const char *path; + auto pos = fname.find('/'); + if (pos == 0) // absolute path given? + path = fname.c_str(); + else if (pos == string::npos) { // filename only given? + path = FileFinder::instance().lookup(fname); + if (!path) + throw FontMapException("include file '"+fname+"' not found", FontMapException::Cause::FILE_ACCESS_ERROR); + } + else { + fname = FilePath(fname, FilePath::PT_FILE, includingFile.absolute(false)).absolute(); + path = fname.c_str(); + } + if (find(includedFiles.begin(), includedFiles.end(), path) != includedFiles.end()) + throw FontMapException("circular inclusion of file '"+string(FilePath(path).shorterAbsoluteOrRelative())+"'"); + includedFiles.emplace_back(path); + if (!read(path, modechar, &includedFiles)) + throw FontMapException("include file '"+fname+"' not found", FontMapException::Cause::FILE_ACCESS_ERROR); + includedFiles.pop_back(); +} + + +void FontMap::includefirst (string line, const FilePath &includingFile, vector &includedFiles) { + if (_firstincludeMode != FirstIncludeMode::OFF) + return; + try { + _firstincludeMode = FirstIncludeMode::ACTIVE; + include(std::move(line), includingFile, includedFiles); + _firstincludeMode = FirstIncludeMode::DONE; + } + catch (FontMapException &e) { + if (e.cause() != FontMapException::Cause::FILE_ACCESS_ERROR) + throw; + _firstincludeMode = FirstIncludeMode::OFF; + } } @@ -122,14 +202,17 @@ bool FontMap::apply (const MapLine& mapline, char modechar) { /** Reads and evaluates a sequence of map files. Each map file is looked up in the local * directory and the TeX file tree. * @param[in] fname_seq comma-separated list of map file names + * @param[in] warn true: print warning if a file couldn't be read * @return true if at least one of the given map files was found */ -bool FontMap::read (const string &fname_seq) { +bool FontMap::read (const string &fname_seq, bool warn) { bool found = false; string::size_type left=0; while (left < fname_seq.length()) { - const char modechar = fname_seq[left]; + char modechar = fname_seq[left]; if (strchr("+-=", modechar)) left++; + else + modechar = '+'; string fname; auto right = fname_seq.find(',', left); if (right != string::npos) @@ -142,8 +225,8 @@ bool FontMap::read (const string &fname_seq) { if (!read(fname, modechar)) { if (const char *path = FileFinder::instance().lookup(fname, false)) found = found || read(path, modechar); - else - Message::wstream(true) << "map file " << fname << " not found\n"; + else if (warn) + Message::wstream(true) << "map file '" << fname << "' not found\n"; } } left = right+1; diff --git a/texk/dvisvgm/dvisvgm-src/src/FontMap.hpp b/texk/dvisvgm/dvisvgm-src/src/FontMap.hpp index cd691660b1..f73c85a7bd 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontMap.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontMap.hpp @@ -2,7 +2,7 @@ ** FontMap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -25,10 +25,13 @@ #include #include #include +#include #include "FontStyle.hpp" +#include "MapLine.hpp" +#include "MessageException.hpp" +class FilePath; struct FontEncoding; -class MapLine; class Subfont; class FontMap { @@ -48,11 +51,12 @@ class FontMap { public: enum class Mode {APPEND, REMOVE, REPLACE}; + enum class FirstIncludeMode {OFF, ACTIVE, DONE}; static FontMap& instance (); - bool read (const std::string &fname, Mode mode); - bool read (const std::string &fname, char modechar); - bool read (const std::string &fname_seq); + bool read (const std::string &fname, Mode mode, std::vector *includedFilesRef=nullptr); + bool read (const std::string &fname, char modechar, std::vector *includedFilesRef=nullptr); + bool read (const std::string &fname_seq, bool warn=false); void readdir (const std::string &dirname); bool apply (const MapLine &mapline, Mode mode); bool apply (const MapLine &mapline, char modechar); @@ -66,9 +70,24 @@ class FontMap { protected: FontMap () =default; + void include (std::string line, const FilePath &includingFile, std::vector &includedFiles); + void includefirst (std::string line, const FilePath &includingFile, std::vector &includedFiles); private: std::unordered_map> _entries; + FirstIncludeMode _firstincludeMode = FirstIncludeMode::OFF; +}; + +class FontMapException : public MapLineException { + public: + enum class Cause {UNSPECIFIED, FILE_ACCESS_ERROR}; + + FontMapException (const std::string &msg, Cause cause) : MapLineException(msg), _cause(cause) {} + explicit FontMapException (const std::string &msg) : FontMapException(msg, Cause::UNSPECIFIED) {} + Cause cause () const {return _cause;} + + private: + Cause _cause = FontMapException::Cause::UNSPECIFIED; }; #endif diff --git a/texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp b/texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp index eeed98a2d8..3b43f48a4c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp @@ -2,7 +2,7 @@ ** FontMetrics.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp b/texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp index eb8796c9c0..b5e69b5761 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp @@ -2,7 +2,7 @@ ** FontMetrics.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp b/texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp index 149cf5fc8e..d1158dba6b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp @@ -2,7 +2,7 @@ ** FontStyle.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp b/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp index 4253562782..337799fa9c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp @@ -2,7 +2,7 @@ ** FontWriter.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp b/texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp index a218694732..1f36e43106 100644 --- a/texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp @@ -2,7 +2,7 @@ ** FontWriter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp b/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp index 8f134654c0..05e5c79e28 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp @@ -2,7 +2,7 @@ ** GFGlyphTracer.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp b/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp index 3a78801ce5..a7e1651ccb 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp @@ -2,7 +2,7 @@ ** GFGlyphTracer.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp b/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp index 6584d06849..8a4fbab629 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp @@ -2,7 +2,7 @@ ** GFReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/GFReader.hpp b/texk/dvisvgm/dvisvgm-src/src/GFReader.hpp index 639d3cfce9..eb12636a62 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GFReader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/GFReader.hpp @@ -2,7 +2,7 @@ ** GFReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp b/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp index 185d8079fe..d411d4a111 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp @@ -2,7 +2,7 @@ ** GFTracer.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp b/texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp index 7bcd802273..6145420ef3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp @@ -2,7 +2,7 @@ ** GFTracer.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp b/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp index a228aa28b6..c2916e596f 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp @@ -2,7 +2,7 @@ ** Ghostscript.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp b/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp index 1e9f189a9b..98725ff2f8 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp @@ -2,7 +2,7 @@ ** Ghostscript.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Glyph.hpp b/texk/dvisvgm/dvisvgm-src/src/Glyph.hpp index a53021211a..c4c2913871 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Glyph.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Glyph.hpp @@ -2,7 +2,7 @@ ** Glyph.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/GlyphTracerMessages.hpp b/texk/dvisvgm/dvisvgm-src/src/GlyphTracerMessages.hpp index 0b1228f38a..d4cf27660f 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GlyphTracerMessages.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/GlyphTracerMessages.hpp @@ -2,7 +2,7 @@ ** GlyphTracerMessages.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -45,7 +45,7 @@ class GlyphTracerMessages : public GFGlyphTracer::Callback { if ((pos = fontname.rfind('/')) != std::string::npos) fontname = fontname.substr(pos+1); if ((pos = fontname.rfind('.')) != std::string::npos) - fontname = fontname.substr(0, pos); + fontname.resize(pos); Message::mstream(false, Message::MC_STATE) << "tracing glyphs of " << fontname << '\n'; } diff --git a/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp b/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp index be9013e086..046349d5d7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp @@ -2,7 +2,7 @@ ** GraphicsPath.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/GraphicsPathParser.hpp b/texk/dvisvgm/dvisvgm-src/src/GraphicsPathParser.hpp index e8d41cd33f..c83c0c0b48 100644 --- a/texk/dvisvgm/dvisvgm-src/src/GraphicsPathParser.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/GraphicsPathParser.hpp @@ -2,7 +2,7 @@ ** GraphicsPathParser.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp b/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp index 449d40285d..2a8d2fd170 100644 --- a/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp @@ -2,7 +2,7 @@ ** HashFunction.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp b/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp index 703a0bc085..f39e670af6 100644 --- a/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp @@ -2,7 +2,7 @@ ** HashFunction.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -21,6 +21,7 @@ #ifndef HASHFUNCTION_HPP #define HASHFUNCTION_HPP +#include #include #include #include diff --git a/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp index 15e3c409ad..4d02a818d3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp @@ -2,7 +2,7 @@ ** HtmlSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp index bb0146fbcc..fd9db78db3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp @@ -2,7 +2,7 @@ ** HtmlSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp b/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp index 14c0003572..73c7d50948 100644 --- a/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp @@ -2,7 +2,7 @@ ** HyperlinkManager.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -153,9 +153,10 @@ void HyperlinkManager::markLinkedBox (SpecialActions &actions) { double y = bbox.maxY()+linewidth; double w = bbox.width(); double h = linewidth; - const Color linecolor = COLORSOURCE == ColorSource::DEFAULT ? actions.getColor() : LINK_LINECOLOR; + const Color strokeColor = COLORSOURCE == ColorSource::DEFAULT ? actions.getStrokeColor() : LINK_LINECOLOR; + const Color fillColor = COLORSOURCE == ColorSource::DEFAULT ? actions.getFillColor() : LINK_LINECOLOR; if (MARKER_TYPE == MarkerType::LINE) - rect->setFillColor(linecolor); + rect->setFillColor(fillColor); else { const double offset = _linewidth < 0 ? linewidth : 0 ; x -= offset; @@ -165,13 +166,13 @@ void HyperlinkManager::markLinkedBox (SpecialActions &actions) { if (MARKER_TYPE == MarkerType::BGCOLOR) { rect->setFillColor(LINK_BGCOLOR); if (COLORSOURCE != ColorSource::DEFAULT) { - rect->setStrokeColor(linecolor); + rect->setStrokeColor(strokeColor); rect->setStrokeWidth(linewidth); } } else { // LM_BOX rect->setNoFillColor(); - rect->setStrokeColor(linecolor); + rect->setStrokeColor(strokeColor); rect->setStrokeWidth(linewidth); } } @@ -243,13 +244,13 @@ bool HyperlinkManager::setLinkMarker (const string &marker) { else if (type == "box") MARKER_TYPE = MarkerType::BOX; else { - if (!LINK_BGCOLOR.setPSName(type, false)) + if (!LINK_BGCOLOR.setPSName(std::move(type), false)) return false; MARKER_TYPE = MarkerType::BGCOLOR; } COLORSOURCE = ColorSource::DEFAULT; if (MARKER_TYPE != MarkerType::NONE && !color.empty()) { - if (!LINK_LINECOLOR.setPSName(color, false)) + if (!LINK_LINECOLOR.setPSName(std::move(color), false)) return false; COLORSOURCE = ColorSource::LINKMARKER; } diff --git a/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp b/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp index 2df68dd59c..57700b92b4 100644 --- a/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp @@ -2,7 +2,7 @@ ** HyperlinkManager.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp b/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp index 5b105ee200..a257440675 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp @@ -2,7 +2,7 @@ ** ImageToSVG.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -57,7 +57,10 @@ void ImageToSVG::convert (int pageno) { if (bbox.valid() && (bbox.width() == 0 || bbox.height() == 0)) Message::wstream(true) << "bounding box of " << imageFormat() << " file is empty\n"; Message::mstream().indent(0); - Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing " << imageFormat() << " file\n"; + if (isSinglePageFormat()) + Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing " << imageFormat() << " file\n"; + else + Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing page " << pageno << "\n"; Message::mstream().indent(1); _svg.newPage(pageno); // create a psfile special and forward it to the PsSpecialHandler @@ -98,13 +101,12 @@ void ImageToSVG::writeSVG (int pageno) { if (!success) Message::wstream() << "failed to write output to " << svgfname << '\n'; else { - const double bp2pt = 72.27/72; - const double bp2mm = 25.4/72; + const double bp2pt = (1_bp).pt(); Message::mstream(false,Message::MC_PAGE_SIZE) << "graphic size: " << XMLString(_bbox.width()*bp2pt) << "pt" << " x " << XMLString(_bbox.height()*bp2pt) << "pt" - << " (" << XMLString(_bbox.width()*bp2mm) << "mm" - << " x " << XMLString(_bbox.height()*bp2mm) << "mm)\n"; + << " (" << XMLString(_bbox.width()) << "bp" + << " x " << XMLString(_bbox.height()) << "bp)\n"; Message::mstream(false, Message::MC_PAGE_WRITTEN) << "output written to " << svgfname << '\n'; if (!_userMessage.empty()) { string msg = expandText(_userMessage); diff --git a/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp b/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp index 943600dbbb..ca52d29d68 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp @@ -2,7 +2,7 @@ ** ImageToSVG.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -58,9 +58,11 @@ class ImageToSVG : protected SpecialActions { void setX (double x) override {_x = x; _svg.setX(x);} void setY (double y) override {_y = y; _svg.setY(y);} void finishLine () override {} - void setColor (const Color &color) override {_svg.setColor(color);} + void setFillColor (const Color &color) override {_svg.setFillColor(color);} + void setStrokeColor (const Color &color) override {_svg.setStrokeColor(color);} void setOpacity (const Opacity &opacity) override {_svg.setOpacity(opacity);} - Color getColor () const override {return _svg.getColor();} + Color getFillColor () const override {return _svg.getFillColor();} + Color getStrokeColor () const override {return _svg.getStrokeColor();} void setMatrix (const Matrix &m) override {_svg.setMatrix(m);} const Matrix& getMatrix () const override {return _svg.getMatrix();} const Opacity& getOpacity () const override {return _svg.getOpacity();} diff --git a/texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp b/texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp index 03687d181d..256e4cad85 100644 --- a/texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp @@ -2,7 +2,7 @@ ** InputBuffer.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp b/texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp index 17a383fb3b..66dbbe329b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp @@ -2,7 +2,7 @@ ** InputBuffer.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/InputReader.cpp b/texk/dvisvgm/dvisvgm-src/src/InputReader.cpp index 8b9c3e80e9..bf03d0bb1d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/InputReader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/InputReader.cpp @@ -2,7 +2,7 @@ ** InputReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -410,3 +410,18 @@ int StreamInputReader::peek (size_t n) const { _is.putback(chars[i]); return ret; } + + +streamsize StreamInputReader::read (char *buf, streamsize size) { + _is.read(buf, size); + return _is.gcount(); +} + + +streamsize BufferInputReader::read (char *buf, streamsize size) { + char *p = buf; + int c = get(); + while (c >= 0 && size-- > 0) + *p++ = char(c); + return p-buf; +} \ No newline at end of file diff --git a/texk/dvisvgm/dvisvgm-src/src/InputReader.hpp b/texk/dvisvgm/dvisvgm-src/src/InputReader.hpp index 90f1658732..f7512c5666 100644 --- a/texk/dvisvgm/dvisvgm-src/src/InputReader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/InputReader.hpp @@ -2,7 +2,7 @@ ** InputReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -31,6 +31,7 @@ class InputReader { public: virtual ~InputReader() =default; virtual int get () =0; + virtual std::streamsize read (char *buf, std::streamsize size) =0; virtual int peek () const =0; virtual int peek (size_t n) const =0; virtual bool eof () const =0; @@ -63,6 +64,7 @@ class StreamInputReader : public InputReader { public: explicit StreamInputReader (std::istream &is) : _is(is) {} int get () override {return _is.get();} + std::streamsize read (char *buf, std::streamsize size) override; int peek () const override {return _is.peek();} int peek (size_t n) const override; bool eof () const override {return !_is || _is.eof();} @@ -78,6 +80,7 @@ class BufferInputReader : public InputReader { explicit BufferInputReader (InputBuffer &ib) : _ib(&ib) {} void assign (InputBuffer &ib) {_ib = &ib;} int get () override {return _ib->get();} + std::streamsize read (char *buf, std::streamsize size) override; int peek () const override {return _ib->peek();} int peek (size_t n) const override {return _ib->peek(n);} bool eof () const override {return _ib->eof();} diff --git a/texk/dvisvgm/dvisvgm-src/src/JFM.cpp b/texk/dvisvgm/dvisvgm-src/src/JFM.cpp index 4d624f1795..33e2266e2a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/JFM.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/JFM.cpp @@ -2,7 +2,7 @@ ** JFM.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/JFM.hpp b/texk/dvisvgm/dvisvgm-src/src/JFM.hpp index 46f412fb72..11ec9db0a6 100644 --- a/texk/dvisvgm/dvisvgm-src/src/JFM.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/JFM.hpp @@ -2,7 +2,7 @@ ** JFM.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Length.cpp b/texk/dvisvgm/dvisvgm-src/src/Length.cpp index e660ab7283..375eb6cd3c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Length.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Length.cpp @@ -2,7 +2,7 @@ ** Length.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -42,7 +42,7 @@ void Length::set (const string &lenstr) { if (!ir.parseDouble(val)) throw UnitException(string("invalid length: ")+lenstr); string unit = ir.getWord(); - set(val, unit); + set(val, std::move(unit)); } } diff --git a/texk/dvisvgm/dvisvgm-src/src/Length.hpp b/texk/dvisvgm/dvisvgm-src/src/Length.hpp index dc1ce9ae67..54bcc79876 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Length.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Length.hpp @@ -2,7 +2,7 @@ ** Length.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp b/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp index f8ef99f64d..eb37ae2133 100644 --- a/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp @@ -2,7 +2,7 @@ ** MD5HashFunction.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Makefile.am b/texk/dvisvgm/dvisvgm-src/src/Makefile.am index f1888535c7..2c7ca5ac3e 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Makefile.am +++ b/texk/dvisvgm/dvisvgm-src/src/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2024 Martin Gieseking +## Copyright (C) 2005-2025 Martin Gieseking ## ## Process this file with automake. diff --git a/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp b/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp index 3ff1405b8c..b364f73571 100644 --- a/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp @@ -2,7 +2,7 @@ ** MapLine.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -39,7 +39,7 @@ MapLine::MapLine (istream &is) : MapLine() { MapLine::MapLine (string str) : MapLine() { auto pos = str.rfind('\n'); if (pos != string::npos) - str = str.substr(0, pos); + str.resize(pos); parse(str.c_str()); } @@ -124,7 +124,7 @@ void MapLine::parseDVIPSLine (InputReader &ir) { if (name.length() > 4 && name.substr(name.length()-4) == ".enc") _encname = name.substr(0, name.length()-4); else - _fontfname = name; + _fontfname = std::move(name); } else { // ir.peek() == '"' => list of PS font operators string options = ir.getQuotedString("\""); diff --git a/texk/dvisvgm/dvisvgm-src/src/MapLine.hpp b/texk/dvisvgm/dvisvgm-src/src/MapLine.hpp index a1d921c954..55adeada90 100644 --- a/texk/dvisvgm/dvisvgm-src/src/MapLine.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/MapLine.hpp @@ -2,7 +2,7 @@ ** MapLine.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Matrix.cpp b/texk/dvisvgm/dvisvgm-src/src/Matrix.cpp index f971e68c04..1b501ca871 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Matrix.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Matrix.cpp @@ -2,7 +2,7 @@ ** Matrix.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Matrix.hpp b/texk/dvisvgm/dvisvgm-src/src/Matrix.hpp index 9e1cb17047..dedc19f5b2 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Matrix.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Matrix.hpp @@ -2,7 +2,7 @@ ** Matrix.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Message.cpp b/texk/dvisvgm/dvisvgm-src/src/Message.cpp index 52fee877ca..cffb63835b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Message.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Message.cpp @@ -2,7 +2,7 @@ ** Message.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Message.hpp b/texk/dvisvgm/dvisvgm-src/src/Message.hpp index d9ab11f830..d997272127 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Message.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Message.hpp @@ -2,7 +2,7 @@ ** Message.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/MessageException.hpp b/texk/dvisvgm/dvisvgm-src/src/MessageException.hpp index d893e7b406..6866c3f59b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/MessageException.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/MessageException.hpp @@ -2,7 +2,7 @@ ** MessageException.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp b/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp index 0dcafe8366..8fa5f78261 100644 --- a/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp @@ -2,7 +2,7 @@ ** MetafontWrapper.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -75,7 +75,7 @@ bool MetafontWrapper::call (const string &mode, double mag) { "batchmode;" // don't halt on errors and don't print informational messages "input " << _fontname << "\""; // load font description Message::mstream(false, Message::MC_STATE) << "\nrunning Metafont for " << _fontname << '\n'; - Process mf_process(mfName, oss.str()); + Process mf_process(std::move(mfName), oss.str()); string mf_messages; mf_process.run(_dir, &mf_messages); @@ -119,7 +119,8 @@ int MetafontWrapper::getResolution (const string &mfMessage) const { if (line.substr(0, 18) == "Output written on ") { line = line.substr(18); auto pos = line.find(' '); - line = line.substr(0, pos); + if (pos != string::npos) + line.resize(pos); pos = line.rfind('.'); if (pos != string::npos && line.substr(line.length()-2) == "gf") { line.pop_back(); diff --git a/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.hpp b/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.hpp index 255b04d34b..204560f753 100644 --- a/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.hpp @@ -2,7 +2,7 @@ ** MetafontWrapper.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp b/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp index 18bfb19837..615d12c26d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp @@ -2,7 +2,7 @@ ** MiKTeXCom.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp b/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp index f2530c7d8d..7574667f93 100644 --- a/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp @@ -2,7 +2,7 @@ ** MiKTeXCom.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp index 3d8e6a3500..dab7e98edc 100644 --- a/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp @@ -2,7 +2,7 @@ ** NoPsSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp index d6de4519ea..20ab48550f 100644 --- a/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp @@ -2,7 +2,7 @@ ** NoPsSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/NumericRanges.hpp b/texk/dvisvgm/dvisvgm-src/src/NumericRanges.hpp index 5ddd3f2711..8ce8180186 100644 --- a/texk/dvisvgm/dvisvgm-src/src/NumericRanges.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/NumericRanges.hpp @@ -2,7 +2,7 @@ ** NumericRanges.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/OFM.cpp b/texk/dvisvgm/dvisvgm-src/src/OFM.cpp index 606635d06a..22871420db 100644 --- a/texk/dvisvgm/dvisvgm-src/src/OFM.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/OFM.cpp @@ -2,7 +2,7 @@ ** OFM.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/OFM.hpp b/texk/dvisvgm/dvisvgm-src/src/OFM.hpp index 993edbc95e..1d3c80abf2 100644 --- a/texk/dvisvgm/dvisvgm-src/src/OFM.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/OFM.hpp @@ -2,7 +2,7 @@ ** OFM.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Opacity.cpp b/texk/dvisvgm/dvisvgm-src/src/Opacity.cpp index ad3edb7075..0757161aff 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Opacity.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Opacity.cpp @@ -2,7 +2,7 @@ ** Opacity.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Opacity.hpp b/texk/dvisvgm/dvisvgm-src/src/Opacity.hpp index 974cb842e1..6d128ccadc 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Opacity.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Opacity.hpp @@ -2,7 +2,7 @@ ** Opacity.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PDFHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/PDFHandler.cpp index f401c34409..6f984a595d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PDFHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PDFHandler.cpp @@ -2,7 +2,7 @@ ** PDFHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -166,7 +166,7 @@ unique_ptr PDFHandler::convert (const string &fname, int pageno, uni auto closefunc = std::bind(&PDFHandler::elementClosed, this, std::placeholders::_1); xmlParser.setNotifyFuncs(openfunc, closefunc); xmlParser.setRootElement(nullptr); - string xmlfname = FileSystem::tmpdir()+FilePath(fname, true).filename()+"-"+ to_string(_pageno)+".xml"; + string xmlfname = FileSystem::tmpdir()+FilePath(fname, FilePath::PT_FILE).filename()+"-"+ to_string(_pageno)+".xml"; mutool("draw -Ftrace -o"+xmlfname+" "+_fname+" "+to_string(_pageno)); ifstream ifs(xmlfname); xmlParser.parse(ifs); @@ -180,7 +180,7 @@ unique_ptr PDFHandler::convert (const string &fname, int pageno, uni void PDFHandler::initFile (const string &fname) { finishFile(); - _fname = FilePath(fname, true).absolute(); + _fname = FilePath(fname, FilePath::PT_FILE).absolute(); _fname = "\"" + _fname + "\""; _numPages = parse_value(mtShow("trailer/Root/Pages/Count")); // extract image and font files from the PDF @@ -651,7 +651,7 @@ void PDFHandler::doFillText (XMLElement *trcFillTextElement) { filename = "sys://"+fontname; double ptsize = matrix_extent({trm[0], trm[1], 0, trm[2], trm[3]}); ptsize = round(100*ptsize)/100; - int fontID = FontManager::instance().registerFont(filename, fontname, ptsize); + int fontID = FontManager::instance().registerFont(filename, std::move(fontname), ptsize); if (fontID >= 0) { auto font = font_cast(FontManager::instance().getFontById(fontID)); if (font != _currentFont) { @@ -662,13 +662,13 @@ void PDFHandler::doFillText (XMLElement *trcFillTextElement) { _x = _y = numeric_limits::max(); } Matrix fontMatrix({trm[0]/ptsize, -trm[2]/ptsize, 0, trm[1]/ptsize, -trm[3]/ptsize}); - fontMatrix.invert(); Matrix matrix = parse_attr_value(trcFillTextElement, "transform"); matrix.rmultiply(fontMatrix); _svg->setMatrix(matrix); + fontMatrix.invert(); string colorspace = parse_attr_value(trcFillTextElement, "colorspace"); string colorval = parse_attr_value(trcFillTextElement, "color"); - _svg->setColor(to_color(colorspace, colorval)); + _svg->setFillColor(to_color(colorspace, colorval)); for (const XMLNode *spanchild : *spanElement) { const XMLElement *charElement = spanchild->toElement(); if (!charElement || charElement->name() != "g" || !charElement->hasAttribute("glyph")) @@ -684,7 +684,7 @@ void PDFHandler::doFillText (XMLElement *trcFillTextElement) { // determine code point of current character string utf8; if (charElement->hasAttribute("unicode")) - utf8 = parse_attr_value(charElement, "unicode"); + utf8 = to_utf8(parse_attr_value(charElement, "unicode")); if (utf8.empty()) utf8 = compose_utf8_char(charElement, glyph); if (glyph == 0 || utf8.empty()) @@ -805,7 +805,7 @@ void PDFHandler::collectObjects () { string fontname = mtShow(to_string(entry.first) + "/FontName", SearchPattern(R"(/((\w|[+-])+))", "$1")); if (!psFontname.empty() && fontname.find('+') == string::npos) fontname = std::move(psFontname); - _objDict.emplace(fontname, ObjID(entry.first, 0, filepath)); + _objDict.emplace(fontname, ObjID(entry.first, 0, std::move(filepath))); } } } diff --git a/texk/dvisvgm/dvisvgm-src/src/PDFHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/PDFHandler.hpp index abc71a681b..1cc963d06e 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PDFHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PDFHandler.hpp @@ -2,7 +2,7 @@ ** PDFHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp b/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp index 7d604a49ab..81ed76f48d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp @@ -2,7 +2,7 @@ ** PDFParser.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp b/texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp index 750984d72d..8da72d4aef 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp @@ -2,7 +2,7 @@ ** PDFParser.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.cpp b/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.cpp index b1a751915d..ebbbe778b0 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.cpp @@ -2,7 +2,7 @@ ** PDFToSVG.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -86,7 +86,7 @@ void PDFToSVG::convert (int pageno) { ImageToSVG::convert(pageno); else { Message::mstream().indent(0); - Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing PDF file\n"; + Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing page " << pageno << "\n"; Message::mstream().indent(1); _pdfHandler.convert(filename(), pageno); embed(_pdfHandler.bbox()); diff --git a/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp b/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp index 598d6c3a3d..7834d535e8 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp @@ -2,7 +2,7 @@ ** PDFToSVG.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp b/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp index 7b9656be7e..4b8b30104f 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp @@ -2,7 +2,7 @@ ** PSInterpreter.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -98,6 +98,9 @@ void PSInterpreter::checkStatus (int status) { throw PSException("fatal error"); if (_errorMessage.empty()) throw PSException(_gs.error_name(status)); + size_t pos = _errorMessage.rfind("Operand stack:"); + if (pos != string::npos && pos > 0 && !isspace(_errorMessage[pos-1])) + _errorMessage.insert(pos, "\n"); throw PSException(_errorMessage); } } @@ -412,7 +415,9 @@ void PSInterpreter::listImageDeviceInfos (ostream &os) { bool PSInterpreter::imageDeviceKnown (string deviceStr) { if (deviceStr.empty() || !isalpha(deviceStr[0])) return false; - deviceStr = deviceStr.substr(0, deviceStr.find(':')); // strip optional argument + size_t colonpos = deviceStr.find(':'); + if (colonpos != string::npos) + deviceStr.resize(colonpos); // strip optional argument auto infos = getImageDeviceInfos(); auto it = find_if(infos.begin(), infos.end(), [&](const PSDeviceInfo &info) { return info.name == deviceStr; diff --git a/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp b/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp index d77d8bfa97..ed85fa3ece 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp @@ -2,7 +2,7 @@ ** PSInterpreter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp b/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp index 8271d7277d..40e9d83e6f 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp @@ -2,7 +2,7 @@ ** PSPattern.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -108,7 +108,7 @@ unique_ptr PSTilingPattern::createGroupNode () const { // add all succeeding path elements to this group auto group = util::make_unique("g"); group->setClipPathUrl("pc"+XMLString(psID())); - return std::move(group); + return group; } diff --git a/texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp b/texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp index 4462285623..e723df1cfb 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp @@ -2,7 +2,7 @@ ** PSPattern.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PSPreviewHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/PSPreviewHandler.cpp index 33fedbff22..34022d5f7c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PSPreviewHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PSPreviewHandler.cpp @@ -2,7 +2,7 @@ ** PSPreviewHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PSPreviewHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/PSPreviewHandler.hpp index 911f3c0183..7747ed9600 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PSPreviewHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PSPreviewHandler.hpp @@ -2,7 +2,7 @@ ** PSPreviewHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp b/texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp index 587e1e6101..b01f2f9bd7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp @@ -2,7 +2,7 @@ ** PageRanges.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp b/texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp index ccf188f412..cb55b5a5e7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp @@ -2,7 +2,7 @@ ** PageRanges.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp b/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp index 85401baccf..ce3710ed4b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp @@ -2,7 +2,7 @@ ** PageSize.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -100,7 +100,7 @@ void PageSize::resize (string name) { bool landscape = false; if (pos != string::npos) { string suffix = name.substr(pos); - name = name.substr(0, pos); + name.resize(pos); if (suffix == "-l" || suffix == "-landscape") landscape = true; else if (suffix != "-p" && suffix != "-portrait") diff --git a/texk/dvisvgm/dvisvgm-src/src/PageSize.hpp b/texk/dvisvgm/dvisvgm-src/src/PageSize.hpp index 3a97fe2c5f..34bc2d4464 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PageSize.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PageSize.hpp @@ -2,7 +2,7 @@ ** PageSize.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Pair.hpp b/texk/dvisvgm/dvisvgm-src/src/Pair.hpp index 21afb20f76..b18de90c34 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Pair.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Pair.hpp @@ -2,7 +2,7 @@ ** Pair.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp index 3424527076..78c4a42e52 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp @@ -2,7 +2,7 @@ ** PapersizeSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -56,7 +56,7 @@ void PapersizeSpecialHandler::storePaperSize (unsigned pageno, Length width, Len DoublePair whpair(width.bp(), height.bp()); if (_pageSizes.empty() || _pageSizes.back().second != whpair) { if (!_pageSizes.empty() && _pageSizes.back().first == pageno) - _pageSizes.back().second = whpair; + _pageSizes.back().second = std::move(whpair); else _pageSizes.emplace_back(pageno, whpair); } diff --git a/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp index d92c563b06..a88fcd78ab 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp @@ -2,7 +2,7 @@ ** PapersizeSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp b/texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp index 346400d687..5482f5b5e0 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp @@ -2,7 +2,7 @@ ** PathClipper.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp b/texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp index 64d6273991..61fc1af7d1 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp @@ -2,7 +2,7 @@ ** PathClipper.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp index dee88b27da..62674f8dde 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp @@ -2,7 +2,7 @@ ** PdfSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -247,7 +247,7 @@ void PdfSpecialHandler::processBeginAnn (StreamInputReader &ir, SpecialActions & it = annotDict.find("C"); if (it != annotDict.end()) HyperlinkManager::setDefaultLinkColor(to_color(it->second)); - HyperlinkManager::instance().createLink(uri, actions); + HyperlinkManager::instance().createLink(std::move(uri), actions); } diff --git a/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp index 68071d2c32..d04c44b0ea 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp @@ -2,7 +2,7 @@ ** PdfSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.cpp b/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.cpp index 898f411466..faa3c129cc 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.cpp @@ -2,7 +2,7 @@ ** PreScanDVIReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.hpp b/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.hpp index a6905b35ec..0f14e9d7f1 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.hpp @@ -2,7 +2,7 @@ ** PreScanDVIReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Process.cpp b/texk/dvisvgm/dvisvgm-src/src/Process.cpp index 3281396f3a..eb3929d656 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Process.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Process.cpp @@ -2,7 +2,7 @@ ** Process.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Process.hpp b/texk/dvisvgm/dvisvgm-src/src/Process.hpp index e0cbf7ce08..4bdd5bb3a8 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Process.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Process.hpp @@ -2,7 +2,7 @@ ** Process.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp index bc56362722..818759dd24 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp @@ -2,7 +2,7 @@ ** PsSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -44,7 +44,6 @@ bool PsSpecialHandler::SHADING_SEGMENT_OVERLAP = false; int PsSpecialHandler::SHADING_SEGMENT_SIZE = 20; double PsSpecialHandler::SHADING_SIMPLIFY_DELTA = 0.01; string PsSpecialHandler::BITMAP_FORMAT; -bool PsSpecialHandler::EMBED_BITMAP_DATA = false; PsSpecialHandler::PsSpecialHandler () : _psi(this), _previewHandler(_psi) @@ -148,10 +147,10 @@ void PsSpecialHandler::moveToDVIPos () { * @param[in] is stream to read the PS code from * @param[in] updatePos if true, move the DVI drawing position to the current PS point */ void PsSpecialHandler::executeAndSync (istream &is, bool updatePos) { - if (_actions && _actions->getColor() != _currentcolor) { + if (_actions && _actions->getFillColor() != _currentcolor) { // update the PS graphics state if the color has been changed by a color special double r, g, b; - _actions->getColor().getRGB(r, g, b); + _actions->getFillColor().getRGB(r, g, b); ostringstream oss; oss << '\n' << r << ' ' << g << ' ' << b << " setrgbcolor "; _psi.execute(oss.str(), false); @@ -419,8 +418,9 @@ PsSpecialHandler::ImageNode PsSpecialHandler::createBitmapNode (const string &fn imgnode.element->addAttribute("y", 0); imgnode.element->addAttribute("width", bbox.width()); imgnode.element->addAttribute("height", bbox.height()); - if (EMBED_BITMAP_DATA) - imgnode.element->addAttribute("@@xlink:href", "data:" + util::mimetype(fname) + ";base64," + fname); + string mimetype = util::mimetype(fname); + if (SVGTree::EMBED_BITMAP_DATA && mimetype != "image/svg+xml") + imgnode.element->addAttribute("@@xlink:href", "data:" + mimetype + ";base64," + fname); else { string href = path; // Only reference the image with an absolute path if either an absolute path was given by the user @@ -471,7 +471,7 @@ PsSpecialHandler::ImageNode PsSpecialHandler::createPDFNode (const string &fname // save SVG state auto savedFont = _actions->svgTree().getFontPair(); auto savedMatrix = _actions->svgTree().getMatrix(); - auto savedColor = _actions->svgTree().getColor(); + auto savedColor = _actions->svgTree().getFillColor(); imgnode.element = util::make_unique("g"); _pdfHandler.assignSVGTree(_actions->svgTree()); @@ -481,7 +481,7 @@ PsSpecialHandler::ImageNode PsSpecialHandler::createPDFNode (const string &fname if (savedFont.second) _actions->svgTree().setFont(savedFont.first, *savedFont.second); _actions->svgTree().setMatrix(savedMatrix); - _actions->svgTree().setColor(savedColor); + _actions->svgTree().setFillColor(savedColor); if (imgnode.element->empty()) imgnode.element.reset(nullptr); @@ -724,7 +724,7 @@ void PsSpecialHandler::stroke (vector &p) { path->addAttribute("cx", x); path->addAttribute("cy", y); path->addAttribute("r", r); - path->setFillColor(_actions->getColor()); + path->setFillColor(_actions->getFillColor()); bbox = BoundingBox(x-r, y-r, x+r, y+r); } } @@ -737,7 +737,7 @@ void PsSpecialHandler::stroke (vector &p) { _path.writeSVG(oss, SVGTree::RELATIVE_PATH_CMDS); path = util::make_unique("path"); path->addAttribute("d", oss.str()); - path->setStrokeColor(_actions->getColor()); + path->setStrokeColor(_actions->getStrokeColor()); path->setNoFillColor(); path->setStrokeWidth(_linewidth); path->setStrokeMiterLimit(_miterlimit); @@ -786,8 +786,8 @@ void PsSpecialHandler::fill (vector &p, bool evenodd) { path->addAttribute("d", oss.str()); if (_pattern) path->setFillPatternUrl(XMLString(_pattern->svgID())); - else if (_actions->getColor() != Color::BLACK || _makingPattern) - path->setFillColor(_actions->getColor(), false); + else if (_actions->getFillColor() != Color::BLACK || _makingPattern) + path->setFillColor(_actions->getFillColor(), false); if (_clipStack.path() && !_makingPattern) { // clip path active and not inside pattern definition? // assign clipping path and clip bounding box path->setClipPathUrl("clip"+XMLString(_clipStack.topID())); @@ -865,8 +865,8 @@ void PsSpecialHandler::image (std::vector &p) { * The given values must be arranged in PostScript matrix order. * @param[in] v vector containing the matrix values * @param[in] startindex vector index of first component - * @param[out] matrix the generated matrix */ -static void create_matrix (vector &v, int startindex, Matrix &matrix) { + * @return the generated matrix */ +static Matrix create_matrix (vector &v, int startindex=0) { // Ensure vector p has 6 elements. If necessary, add missing ones // using corresponding values of the identity matrix. if (v.size()-startindex < 6) { @@ -881,7 +881,7 @@ static void create_matrix (vector &v, int startindex, Matrix &matrix) { swap(v[startindex+1], v[startindex+2]); // => (a, c, b, d, e, f) swap(v[startindex+2], v[startindex+4]); // => (a, c, e, d, b, f) swap(v[startindex+3], v[startindex+4]); // => (a, c, e, b, d, f) - matrix.set(v, startindex); + return Matrix(v, startindex); } @@ -910,8 +910,8 @@ void PsSpecialHandler::makepattern (vector &p) { const double &xstep=p[6], &ystep=p[7]; // horizontal and vertical distance of adjacent tiles int paint_type = static_cast(p[8]); - Matrix matrix; // transformation matrix given together with pattern definition - create_matrix(p, 9, matrix); + // transformation matrix given together with pattern definition + Matrix matrix = create_matrix(p, 9); matrix.lmultiply(_actions->getMatrix()); unique_ptr pattern; @@ -1068,7 +1068,7 @@ void PsSpecialHandler::shfill (vector ¶ms) { bboxPath.lineto(x2, y2); bboxPath.lineto(x1, y2); bboxPath.closepath(); - clip(bboxPath, false); + clip(std::move(bboxPath), false); } try { if (shadingTypeID == 5) @@ -1256,11 +1256,8 @@ void PsSpecialHandler::newpath (vector &p) { void PsSpecialHandler::setmatrix (vector &p) { - if (_actions) { - Matrix m; - create_matrix(p, 0, m); - _actions->setMatrix(m); - } + if (_actions) + _actions->setMatrix(create_matrix(p)); } @@ -1303,8 +1300,10 @@ void PsSpecialHandler::setgray (vector &p) { if (!_patternEnabled) _pattern = nullptr; _currentcolor.setGray(p[0]); - if (_actions) - _actions->setColor(_currentcolor); + if (_actions) { + _actions->setFillColor(_currentcolor); + _actions->setStrokeColor(_currentcolor); + } } @@ -1312,8 +1311,10 @@ void PsSpecialHandler::setrgbcolor (vector &p) { if (!_patternEnabled) _pattern= nullptr; _currentcolor.setRGB(p[0], p[1], p[2]); - if (_actions) - _actions->setColor(_currentcolor); + if (_actions) { + _actions->setFillColor(_currentcolor); + _actions->setStrokeColor(_currentcolor); + } } @@ -1321,8 +1322,10 @@ void PsSpecialHandler::setcmykcolor (vector &p) { if (!_patternEnabled) _pattern = nullptr; _currentcolor.setCMYK(p[0], p[1], p[2], p[3]); - if (_actions) - _actions->setColor(_currentcolor); + if (_actions) { + _actions->setFillColor(_currentcolor); + _actions->setStrokeColor(_currentcolor); + } } @@ -1330,8 +1333,10 @@ void PsSpecialHandler::sethsbcolor (vector &p) { if (!_patternEnabled) _pattern = nullptr; _currentcolor.setHSB(p[0], p[1], p[2]); - if (_actions) - _actions->setColor(_currentcolor); + if (_actions) { + _actions->setFillColor(_currentcolor); + _actions->setStrokeColor(_currentcolor); + } } @@ -1379,7 +1384,7 @@ void PsSpecialHandler::ClippingStack::push (const Path &path, int saveID) { _stack.emplace(saveID); else _stack.emplace(path, ++_maxID, saveID); - _stack.top().prependedPath = prependedPath; + _stack.top().prependedPath = std::move(prependedPath); } diff --git a/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp index 67d6219752..96e71e11b9 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp @@ -2,7 +2,7 @@ ** PsSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -107,7 +107,6 @@ class PsSpecialHandler : public SpecialHandler, protected PSActions { static int SHADING_SEGMENT_SIZE; static double SHADING_SIMPLIFY_DELTA; static std::string BITMAP_FORMAT; - static bool EMBED_BITMAP_DATA; protected: void initialize (); diff --git a/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandlerProxy.cpp b/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandlerProxy.cpp index d13cc124ae..17ecd63a91 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandlerProxy.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandlerProxy.cpp @@ -2,7 +2,7 @@ ** PsSpecialHandlerProxy.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandlerProxy.hpp b/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandlerProxy.hpp index f2a1b3ab13..c102ab1a8a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandlerProxy.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandlerProxy.hpp @@ -2,7 +2,7 @@ ** PsSpecialHandlerProxy.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp b/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp index 7eca6ee659..1d3114f8e1 100644 --- a/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp @@ -2,7 +2,7 @@ ** RangeMap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp b/texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp index ff6db0270e..e5c353fe18 100644 --- a/texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp @@ -2,7 +2,7 @@ ** RangeMap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp index 812b215fe8..7f0fceb600 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp @@ -2,7 +2,7 @@ ** SVGCharHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.hpp index f50ec46652..21cd7d6871 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.hpp @@ -2,7 +2,7 @@ ** SVGCharHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -68,12 +68,14 @@ class SVGCharHandler { virtual void appendChar (uint32_t c, double x, double y) =0; virtual void notifyXAdjusted () {} virtual void notifyYAdjusted () {} - void setColor (const Color &color) {_color.set(color);} + void setFillColor (const Color &color) {_fillColor.set(color);} + void setStrokeColor (const Color &color) {_strokeColor.set(color);} void setOpacity (const Opacity &opacity) {_opacity.set(opacity);} void setFont (const Font &font, int id) {_font.set(&font); _fontnum = id;} void setMatrix (const Matrix &matrix) {_matrix.set(matrix);} void setVertical (bool vertical) {_vertical.set(vertical);} - Color getColor () const {return _color.get();} + Color getFillColor () const {return _fillColor.get();} + Color getStrokeColor () const {return _strokeColor.get();} const Opacity& getOpacity () const {return _opacity.get();} const Font* getFont () const {return _font.get();} int getFontID () const {return _fontnum;} @@ -88,7 +90,8 @@ class SVGCharHandler { return _contextNodeStack.empty() ? _initialContextNode : _contextNodeStack.top(); } - CharProperty _color=Color::BLACK; ///< current color + CharProperty _fillColor=Color::BLACK; ///< current fill color + CharProperty _strokeColor=Color::BLACK; ///< current stroke color CharProperty _opacity; ///< current opacity values CharProperty _font=0; ///< current font int _fontnum=0; ///< current font ID diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp b/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp index 4e91d290f0..eb4f5d430f 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp @@ -2,7 +2,7 @@ ** SVGCharHandlerFactory.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.hpp b/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.hpp index 5ff8d9b4c2..4c8eac592e 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.hpp @@ -2,7 +2,7 @@ ** SVGCharHandlerFactory.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp index e5e69a0ca1..4becb60cf4 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp @@ -2,7 +2,7 @@ ** SVGCharPathHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -54,12 +54,12 @@ void SVGCharPathHandler::appendChar (uint32_t c, double x, double y) { if (_font.changed()) { _fontColor.set(_font.get()->color()); if (_fontColor.changed() && _fontColor.get() != Color::BLACK) - _color.changed(true); // ensure application of text color when resetting the font color to black + _fillColor.changed(true); // ensure application of text color when resetting the font color to black _font.changed(false); } // Apply text color changes only if the color of the entire font is black. // Glyphs of non-black fonts (e.g. defined in a XeTeX document) can't change their color. - CharProperty &color = (_fontColor.get() != Color::BLACK) ? _fontColor : _color; + CharProperty &color = (_fontColor.get() != Color::BLACK) ? _fontColor : _fillColor; bool applyColor = color.get() != Color::BLACK || (SVGElement::USE_CURRENTCOLOR && SVGElement::CURRENTCOLOR == Color::BLACK); bool applyMatrix = !_matrix->isIdentity(); bool applyOpacity = !_opacity->isFillDefault(); diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.hpp index b0c675df5c..0a380be1ab 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.hpp @@ -2,7 +2,7 @@ ** SVGCharPathHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp index 5851eda463..129cdb8110 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp @@ -2,7 +2,7 @@ ** SVGCharTspanTextHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -36,23 +36,23 @@ void SVGCharTspanTextHandler::appendChar (uint32_t c, double x, double y) { if (!_textNode || _font.changed() || _matrix.changed() || _vertical.changed()) { resetContextNode(); _textNode = pushContextNode(createTextNode(x, y)); - _color.changed(true); // force creating tspan with color attribute if current color differs from font color + _fillColor.changed(true); // force creating tspan with color attribute if current color differs from font color _opacity.changed(true); // dito for opacity properties } - if (_tspanNode && (_xchanged || _ychanged || _color.changed() || _opacity.changed())) { + if (_tspanNode && (_xchanged || _ychanged || _fillColor.changed() || _opacity.changed())) { // if drawing position or color was explicitly changed, finish current tspan element popContextNode(); _tspanNode = nullptr; } // Apply text color changes only if the color of the entire font is black. // Glyphs of non-black fonts (e.g. defined in a XeTeX document) can't change their color. - bool applyColor = _color.get() != Color::BLACK || (SVGElement::USE_CURRENTCOLOR && _font.get()->color() == Color::BLACK); + bool applyColor = _fillColor.get() != Color::BLACK || (SVGElement::USE_CURRENTCOLOR && _font.get()->color() == Color::BLACK); bool applyOpacity = !_opacity->isFillDefault(); - if (_xchanged || _ychanged || (_color.changed() && applyColor) || (_opacity.changed() && applyOpacity)) { + if (_xchanged || _ychanged || (_fillColor.changed() && applyColor) || (_opacity.changed() && applyOpacity)) { _tspanNode = pushContextNode(util::make_unique("tspan")); if (applyColor) - _tspanNode->setFillColor(_color); - _color.changed(false); + _tspanNode->setFillColor(_fillColor); + _fillColor.changed(false); _tspanNode->setFillOpacity(_opacity); _opacity.changed(false); if (_xchanged) { diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.hpp index dd6df1a861..6dbd20140e 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.hpp @@ -2,7 +2,7 @@ ** SVGCharTspanTextHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGElement.cpp b/texk/dvisvgm/dvisvgm-src/src/SVGElement.cpp index 9664e89280..1648dcf574 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGElement.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGElement.cpp @@ -2,7 +2,7 @@ ** SVGElement.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp b/texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp index dac3749eb4..d75c255949 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp @@ -2,7 +2,7 @@ ** SVGElement.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp b/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp index b7b4780131..8315299a2a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp @@ -2,7 +2,7 @@ ** SVGOutput.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -83,10 +83,10 @@ FilePath SVGOutput::filepath (int page, int numPages, const HashTriple &hashes) // set and expand default pattern if necessary if (expanded_pattern.empty()) { string pattern = hashes.empty() ? (numPages > 1 ? "%f-%p" : "%f") : "%f-%hd"; - expanded_pattern = expandFormatString(pattern, page, numPages, hashes); + expanded_pattern = expandFormatString(std::move(pattern), page, numPages, hashes); } // append suffix if necessary - outpath.set(expanded_pattern, true); + outpath.set(expanded_pattern, FilePath::PT_FILE); if (outpath.suffix().empty()) outpath.suffix(_zipLevel > 0 ? "svgz" : "svg"); } diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp b/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp index e71f8c5790..a83cdeb642 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp @@ -2,7 +2,7 @@ ** SVGOutput.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -33,9 +33,9 @@ struct SVGOutputBase { HashTriple () =default; HashTriple (std::string dviHash, std::string optHash, std::string cmbHash) : _dviHash(std::move(dviHash)), _optHash(std::move(optHash)), _cmbHash(std::move(cmbHash)) {} - std::string dviHash () const {return _dviHash;} - std::string optHash () const {return _optHash;} - std::string cmbHash () const {return _cmbHash;} + const std::string& dviHash () const {return _dviHash;} + const std::string& optHash () const {return _optHash;} + const std::string& cmbHash () const {return _cmbHash;} bool empty () const {return _dviHash.empty();} private: diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp index c4af8d627d..1b0969bd04 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp @@ -2,7 +2,7 @@ ** SVGSingleCharTextHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -29,9 +29,9 @@ void SVGSingleCharTextHandler::appendChar (uint32_t c, double x, double y) { textNode->append(XMLString(font->unicode(c), false)); // Apply color changes only if the color differs from black and if the font color itself is black. // Glyphs from non-black fonts (e.g. defined in a XeTeX document) can't change their color. - if (font->color() == Color::BLACK && (_color.get() != Color::BLACK || (SVGElement::USE_CURRENTCOLOR && SVGElement::CURRENTCOLOR == Color::BLACK))) - textNode->setFillColor(_color); - _color.changed(false); + if (font->color() == Color::BLACK && (_fillColor.get() != Color::BLACK || (SVGElement::USE_CURRENTCOLOR && SVGElement::CURRENTCOLOR == Color::BLACK))) + textNode->setFillColor(_fillColor); + _fillColor.changed(false); if (!_opacity->isFillDefault()) textNode->setFillOpacity(_opacity); _opacity.changed(false); diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.hpp index 15bbd59ac3..e9464e070b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.hpp @@ -2,7 +2,7 @@ ** SVGSingleCharTextHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp b/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp index f6f896dfd1..ba8fb6041b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp @@ -2,7 +2,7 @@ ** SVGTree.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -43,6 +43,7 @@ bool SVGTree::CREATE_USE_ELEMENTS=false; bool SVGTree::RELATIVE_PATH_CMDS=false; bool SVGTree::MERGE_CHARS=true; bool SVGTree::ADD_COMMENTS=false; +bool SVGTree::EMBED_BITMAP_DATA = false; double SVGTree::ZOOM_FACTOR=1.0; @@ -76,18 +77,25 @@ void SVGTree::setBBox (const BoundingBox &bbox) { } -void SVGTree::setColor (const Color &c) { +void SVGTree::setFillColor (const Color &c) { const Font *font = _charHandler->getFont(); if (!font || font->color() == Color::BLACK) - _charHandler->setColor(c); + _charHandler->setFillColor(c); +} + + +void SVGTree::setStrokeColor (const Color &c) { + const Font *font = _charHandler->getFont(); + if (!font || font->color() == Color::BLACK) + _charHandler->setStrokeColor(c); } void SVGTree::setFont (int num, const Font &font) { _charHandler->setFont(font, num); // set default color assigned to the font - if (font.color() != Color::BLACK && getColor() != font.color()) - setColor(font.color()); + if (font.color() != Color::BLACK && getFillColor() != font.color()) + setFillColor(font.color()); } @@ -103,9 +111,9 @@ bool SVGTree::setFontFormat (string formatstr) { string opt; if (pos != string::npos) { opt = formatstr.substr(pos+1); - formatstr = formatstr.substr(0, pos); + formatstr.resize(pos); } - FontWriter::FontFormat format = FontWriter::toFontFormat(formatstr); + FontWriter::FontFormat format = FontWriter::toFontFormat(std::move(formatstr)); if (format == FontWriter::FontFormat::UNKNOWN) return false; FONT_FORMAT = format; diff --git a/texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp b/texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp index cc9338c535..6777ae16c1 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp @@ -2,7 +2,7 @@ ** SVGTree.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -66,11 +66,13 @@ class SVGTree { void setX (double x) {_charHandler->notifyXAdjusted();} void setY (double y) {_charHandler->notifyYAdjusted();} void setMatrix (const Matrix &m) {_charHandler->setMatrix(m);} - void setColor (const Color &c); + void setFillColor (const Color &c); + void setStrokeColor (const Color &c); void setOpacity (const Opacity &op) {_charHandler->setOpacity(op);} void setVertical (bool state) {_charHandler->setVertical(state);} void transformPage (const Matrix &m); - Color getColor () const {return _charHandler->getColor();} + Color getFillColor () const {return _charHandler->getFillColor();} + Color getStrokeColor () const {return _charHandler->getStrokeColor();} const Opacity& getOpacity () const {return _charHandler->getOpacity();} const Matrix& getMatrix () const {return _charHandler->getMatrix();} XMLElement* rootNode () const {return _root;} @@ -89,6 +91,7 @@ class SVGTree { static bool MERGE_CHARS; ///< whether to merge chars with common properties into the same tag static bool ADD_COMMENTS; ///< add comments with additional information static double ZOOM_FACTOR; ///< factor applied to width/height attribute + static bool EMBED_BITMAP_DATA; ///< if true, bitmaps are embedded into the SVG document private: XMLDocument _doc; diff --git a/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp b/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp index e1d860febb..15adb48b53 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp @@ -2,7 +2,7 @@ ** ShadingPatch.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -26,27 +26,6 @@ using namespace std; -/** Get functions to get/set the current color depending on the assigned color space. */ -void ShadingPatch::colorQueryFuncs (ColorGetter &getter, ColorSetter &setter) const { - switch (_colorspace) { - case Color::ColorSpace::CMYK: - getter = &Color::getCMYK; - setter = &Color::setCMYK; - break; - case Color::ColorSpace::LAB: - getter = &Color::getLab; - setter = &Color::setLab; - break; - case Color::ColorSpace::RGB: - getter = &Color::getRGB; - setter = &Color::setRGB; - break; - case Color::ColorSpace::GRAY: - getter = &Color::getGray; - setter = &Color::setGray; - } -} - /** Factory method: Creates a shading patch object depending on the given PostScript shading type. */ unique_ptr ShadingPatch::create (int psShadingType, Color::ColorSpace cspace) { diff --git a/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp b/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp index 88300a7f46..5f6b433662 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp @@ -2,7 +2,7 @@ ** ShadingPatch.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -48,14 +48,12 @@ class ShadingPatch { virtual void setColors (const ColorVec &colors, int edgeflag, ShadingPatch *patch) =0; virtual int numPoints (int edgeflag) const =0; virtual int numColors (int edgeflag) const =0; - virtual Color averageColor() const =0; Color::ColorSpace colorSpace () const {return _colorspace;} static std::unique_ptr create (int psShadingType, Color::ColorSpace cspace); protected: using ColorGetter = void (Color::*)(std::valarray &va) const; using ColorSetter = void (Color::*)(const std::valarray &va); - void colorQueryFuncs (ColorGetter &getter, ColorSetter &setter) const; private: Color::ColorSpace _colorspace; ///< color space used to compute the shading values diff --git a/texk/dvisvgm/dvisvgm-src/src/SignalHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/SignalHandler.cpp index 8b2501fa2f..8e35127756 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SignalHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SignalHandler.cpp @@ -2,7 +2,7 @@ ** SignalHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SignalHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/SignalHandler.hpp index 5c5f0d4850..4cb32c5359 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SignalHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SignalHandler.hpp @@ -2,7 +2,7 @@ ** SignalHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp b/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp index 294a52422c..b3eca8c98d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp @@ -2,7 +2,7 @@ ** SourceInput.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp b/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp index e09d8705e1..1407d7ca49 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp @@ -2,7 +2,7 @@ ** SourceInput.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SpecialActions.cpp b/texk/dvisvgm/dvisvgm-src/src/SpecialActions.cpp index 16cd161102..851be6ed3a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SpecialActions.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SpecialActions.cpp @@ -2,7 +2,7 @@ ** SpecialActions.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -19,11 +19,20 @@ *************************************************************************/ #include +#include #include "Calculator.hpp" #include "SpecialActions.hpp" using namespace std; + +inline string get_color_string (SpecialActions &actions, Color (SpecialActions::*getColor)() const) { + return SVGElement::USE_CURRENTCOLOR && SVGElement::CURRENTCOLOR == (actions.*getColor)() + ? "currentColor" + : (actions.*getColor)().svgColorString(); +} + + /** Replaces constants of the form {?name} by their corresponding value. * @param[in,out] str text to expand * @param[in] actions interfcae to the world outside the special handler */ @@ -37,7 +46,7 @@ static void expand_constants (string &str, SpecialActions &actions) { auto endpos = pos+7; while (endpos < str.length() && isalnum(str[endpos])) ++endpos; - if (str[endpos] != '}') + if (endpos == str.length() || str[endpos] != '}') repl_bbox = false; else { BoundingBox &box = actions.bbox(str.substr(pos+7, endpos-pos-7)); @@ -49,14 +58,16 @@ static void expand_constants (string &str, SpecialActions &actions) { const char *name; string val; } constants[] = { - {"x", XMLString(actions.getX())}, - {"y", XMLString(actions.getY())}, - {"color", SVGElement::USE_CURRENTCOLOR && SVGElement::CURRENTCOLOR == actions.getColor() ? "currentColor" : actions.getColor().svgColorString()}, - {"matrix", actions.getMatrix().toSVG()}, - {"nl", "\n"}, - {"pageno", to_string(actions.getCurrentPageNumber())}, - {"svgfile", actions.getSVGFilePath(actions.getCurrentPageNumber()).relative()}, - {"svgpath", actions.getSVGFilePath(actions.getCurrentPageNumber()).absolute()}, + {"x", XMLString(actions.getX())}, + {"y", XMLString(actions.getY())}, + {"color", get_color_string(actions, &SpecialActions::getFillColor)}, + {"fillcolor", get_color_string(actions, &SpecialActions::getFillColor)}, + {"strokecolor", get_color_string(actions, &SpecialActions::getStrokeColor)}, + {"matrix", actions.getMatrix().toSVG()}, + {"nl", "\n"}, + {"pageno", to_string(actions.getCurrentPageNumber())}, + {"svgfile", actions.getSVGFilePath(actions.getCurrentPageNumber()).relative()}, + {"svgpath", actions.getSVGFilePath(actions.getCurrentPageNumber()).absolute()}, }; for (const Constant &constant : constants) { const string pattern = string("{?")+constant.name+"}"; @@ -66,6 +77,11 @@ static void expand_constants (string &str, SpecialActions &actions) { pos = str.find(pattern, pos+constant.val.length()); // look for further matches } } + // expand {?cmyk(c,m,y,k)} to #RRGGBB + std::smatch match; + std::regex pattern(R"(\{\?(cmyk\(([0-9.]+,){3}[0-9.]\))\})"); + while (regex_search(str, match, pattern)) + str = match.prefix().str() + Color(match[1].str()).rgbString() + match.suffix().str(); } diff --git a/texk/dvisvgm/dvisvgm-src/src/SpecialActions.hpp b/texk/dvisvgm/dvisvgm-src/src/SpecialActions.hpp index b1d4384016..686ee657c8 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SpecialActions.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SpecialActions.hpp @@ -2,7 +2,7 @@ ** SpecialActions.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -46,8 +46,10 @@ class SpecialActions { virtual void setX (double x) =0; virtual void setY (double y) =0; virtual void finishLine () =0; - virtual void setColor (const Color &color) =0; - virtual Color getColor () const =0; + virtual void setFillColor (const Color &color) =0; + virtual void setStrokeColor (const Color &color) =0; + virtual Color getFillColor () const =0; + virtual Color getStrokeColor () const =0; virtual void setMatrix (const Matrix &m) =0; virtual const Matrix& getMatrix () const =0; virtual Matrix getPageTransformation () const {return Matrix(1);} @@ -82,11 +84,13 @@ class EmptySpecialActions : public SpecialActions { void setX (double x) override {} void setY (double y) override {} void finishLine () override {} - void setColor (const Color &color) override {} + void setFillColor (const Color &color) override {} + void setStrokeColor (const Color &color) override {} void setBgColor (const Color &color) override {} void setOpacity (const Opacity &opacity) override {} const Opacity& getOpacity () const override {return _svg.getOpacity();} - Color getColor () const override {return Color::BLACK;} + Color getFillColor () const override {return Color::BLACK;} + Color getStrokeColor () const override {return Color::BLACK;} void setMatrix (const Matrix &m) override {} const Matrix& getMatrix () const override {return _matrix;} const SVGTree& svgTree () const override {return _svg;} diff --git a/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp index 2182919361..bb3c00f2e9 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp @@ -2,7 +2,7 @@ ** SpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp b/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp index 175f3c54fb..f219940d8e 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp @@ -2,7 +2,7 @@ ** SpecialManager.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp b/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp index 00cc3ebc6b..ea8564f446 100644 --- a/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp @@ -2,7 +2,7 @@ ** SpecialManager.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp b/texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp index 5fcdd8d808..ed44804779 100644 --- a/texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp @@ -2,7 +2,7 @@ ** StreamReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp b/texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp index 70f05a5c77..582bd18e01 100644 --- a/texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp @@ -2,7 +2,7 @@ ** StreamReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp b/texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp index 7f7909b5ef..c6bcb08018 100644 --- a/texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp @@ -2,7 +2,7 @@ ** StreamWriter.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp b/texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp index 059632076a..e4fc9f12f1 100644 --- a/texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp @@ -2,7 +2,7 @@ ** StreamWriter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Subfont.cpp b/texk/dvisvgm/dvisvgm-src/src/Subfont.cpp index 4bec7c7666..04bae2aea3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Subfont.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Subfont.cpp @@ -2,7 +2,7 @@ ** Subfont.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Subfont.hpp b/texk/dvisvgm/dvisvgm-src/src/Subfont.hpp index b6167bb636..ab2479bd0a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Subfont.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Subfont.hpp @@ -2,7 +2,7 @@ ** Subfont.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/System.cpp b/texk/dvisvgm/dvisvgm-src/src/System.cpp index f210771620..b4033b774e 100644 --- a/texk/dvisvgm/dvisvgm-src/src/System.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/System.cpp @@ -2,7 +2,7 @@ ** System.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/System.hpp b/texk/dvisvgm/dvisvgm-src/src/System.hpp index 5b83e0d227..6cfd7d6b91 100644 --- a/texk/dvisvgm/dvisvgm-src/src/System.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/System.hpp @@ -2,7 +2,7 @@ ** System.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/TFM.cpp b/texk/dvisvgm/dvisvgm-src/src/TFM.cpp index 5105f5c9b3..1a6e59fb88 100644 --- a/texk/dvisvgm/dvisvgm-src/src/TFM.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/TFM.cpp @@ -2,7 +2,7 @@ ** TFM.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/TFM.hpp b/texk/dvisvgm/dvisvgm-src/src/TFM.hpp index 0ee44ec7ad..24bf823ca5 100644 --- a/texk/dvisvgm/dvisvgm-src/src/TFM.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/TFM.hpp @@ -2,7 +2,7 @@ ** TFM.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp b/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp index e0be694500..0c884aeded 100644 --- a/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp @@ -2,7 +2,7 @@ ** TensorProductPatch.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -44,13 +44,6 @@ void TensorProductPatch::setFirstMatrixColumn (DPair source[4][4], int col, bool } -/*void TensorProductPatch::setPoints (const DPair points[4][4]) { - for (int i=0; i < 4; i++) - for (int j=0; j < 4; j++) - _points[i][j] = points[i][j]; -}*/ - - /** Sets the control points defining the structure of the patch. If the edge flag is 0, * the point vector must contain all 16 control points of the 4x4 matrix in "spiral" order: * 0 11 10 9 @@ -73,32 +66,33 @@ void TensorProductPatch::setPoints (const PointVec &points, int edgeflag, Shadin // assign the 12 control points that are invariant for all edge flag values int i = (edgeflag == 0 ? 4 : 0); - _points[3][1] = points[i++]; - _points[3][2] = points[i++]; - _points[3][3] = points[i++]; - _points[2][3] = points[i++]; - _points[1][3] = points[i++]; - _points[0][3] = points[i++]; - _points[0][2] = points[i++]; - _points[0][1] = points[i++]; - _points[1][1] = points[i++]; - _points[2][1] = points[i++]; - _points[2][2] = points[i++]; - _points[1][2] = points[i]; - // populate the first column of the control point matrix + _points[3][1] = points[i++]; // 4 + _points[3][2] = points[i++]; // 5 + _points[3][3] = points[i++]; // 6 + _points[2][3] = points[i++]; // 7 + _points[1][3] = points[i++]; // 8 + _points[0][3] = points[i++]; // 9 + _points[0][2] = points[i++]; // 10 + _points[0][1] = points[i++]; // 11 + _points[1][1] = points[i++]; // 12 + _points[2][1] = points[i++]; // 13 + _points[2][2] = points[i++]; // 14 + _points[1][2] = points[i]; // 15 + // populate first column of control point tensor depending on edge flag value switch (edgeflag) { case 0: setFirstMatrixColumn(&points[0], false); break; case 1: setFirstMatrixColumn(tpPatch->_points[3], false); break; case 2: setFirstMatrixColumn(tpPatch->_points, 3, true); break; case 3: setFirstMatrixColumn(tpPatch->_points[0], true); break; + default: ; } } /** Sets the vertex colors of the patch. If the edge flag is 0, * the color vector must contain all 4 colors in the following order: - * c00, c30, c33, c03, where cXY belongs to the vertex pXY of the control - * point matrix. + * c00, c30, c33, c03, where cXY belongs to vertex pXY of the control + * point tensor. * c00 ---- c03 * | | * | | @@ -108,7 +102,7 @@ void TensorProductPatch::setPoints (const PointVec &points, int edgeflag, Shadin * @param[in] points the color values in the order c00, c30, c33, c03 * @param[in] edgeflag defines how to connect this patch with another one * @param[in] patch reference patch required if edgeflag > 0 */ -void TensorProductPatch::setColors(const ColorVec &colors, int edgeflag, ShadingPatch* patch) { +void TensorProductPatch::setColors (const ColorVec &colors, int edgeflag, ShadingPatch* patch) { TensorProductPatch *tpPatch = nullptr; if (patch && patch->psShadingType() == psShadingType()) tpPatch = static_cast(patch); @@ -132,18 +126,9 @@ void TensorProductPatch::setColors(const ColorVec &colors, int edgeflag, Shading /** Returns the point P(u,v) of the patch. */ DPair TensorProductPatch::valueAt (double u, double v) const { // check if we can return one of the vertices - if (u == 0) { - if (v == 0) - return _points[0][0]; - else if (v == 1) - return _points[3][0]; - } - else if (u == 1) { - if (v == 0) - return _points[0][3]; - else if (v == 1) - return _points[3][3]; - } + if ((u == 0 || u == 1) && (v == 0 || v == 1)) + return _points[3*int(v)][3*int(u)]; + // compute tensor product DPair p[4]; for (int i=0; i < 4; i++) { @@ -172,39 +157,14 @@ Color TensorProductPatch::colorAt (double u, double v) const { return _colors[3]; } // interpolate color - ColorGetter getComponents; - ColorSetter setComponents; - colorQueryFuncs(getComponents, setComponents); valarray comp[4]; for (int i=0; i < 4; i++) - (_colors[i].*getComponents)(comp[i]); - Color color; - (color.*setComponents)((1-u)*(1-v)*comp[0] + u*(1-v)*comp[1] + (1-u)*v*comp[2] + u*v*comp[3]); + comp[i] = _colors[i].getDoubleValues(); + Color color((1-u)*(1-v)*comp[0] + u*(1-v)*comp[1] + (1-u)*v*comp[2] + u*v*comp[3], colorSpace()); return color; } -Color TensorProductPatch::averageColor () const { - return averageColor(_colors[0], _colors[1], _colors[2], _colors[3]); -} - - -/** Compute the average of four given colors depending on the assigned color space. */ -Color TensorProductPatch::averageColor (const Color &c1, const Color &c2, const Color &c3, const Color &c4) const { - ColorGetter getComponents; - ColorSetter setComponents; - colorQueryFuncs(getComponents, setComponents); - valarray va1, va2, va3, va4; - (c1.*getComponents)(va1); - (c2.*getComponents)(va2); - (c3.*getComponents)(va3); - (c4.*getComponents)(va4); - Color averageColor; - (averageColor.*setComponents)((va1+va2+va3+va4)/4.0); - return averageColor; -} - - GraphicsPath TensorProductPatch::getBoundaryPath () const { // Simple approach: Use the outer curves as boundary path. This doesn't always lead // to correct results since, depending on the control points, P(u,v) might exceed @@ -224,7 +184,8 @@ GraphicsPath TensorProductPatch::getBoundaryPath () const { * runs "vertically" from P(u,0) to P(u,1) through the patch P. * @param[in] u "horizontal" parameter in the range from 0 to 1 * @param[out] bezier the resulting Bézier curve */ -void TensorProductPatch::verticalCurve (double u, CubicBezier &bezier) const { +CubicBezier TensorProductPatch::verticalCurve (double u) const { + CubicBezier bezier; // check for simple cases (boundary curves) first if (u == 0) bezier.setPoints(_points[0][0], _points[1][0], _points[2][0], _points[3][0]); @@ -234,11 +195,12 @@ void TensorProductPatch::verticalCurve (double u, CubicBezier &bezier) const { // compute "inner" curve DPair p[4]; for (int i=0; i < 4; i++) { - CubicBezier bezier(_points[i][0], _points[i][1], _points[i][2], _points[i][3]); - p[i] = bezier.valueAt(u); + CubicBezier hbezier(_points[i][0], _points[i][1], _points[i][2], _points[i][3]); + p[i] = hbezier.valueAt(u); } bezier.setPoints(p[0], p[1], p[2], p[3]); } + return bezier; } @@ -246,7 +208,8 @@ void TensorProductPatch::verticalCurve (double u, CubicBezier &bezier) const { * runs "horizontally" from P(0,v) to P(1,v) through the patch P. * @param[in] v "vertical" parameter in the range from 0 to 1 * @param[out] bezier the resulting Bézier curve */ -void TensorProductPatch::horizontalCurve (double v, CubicBezier &bezier) const { +CubicBezier TensorProductPatch::horizontalCurve (double v) const { + CubicBezier bezier; // check for simple cases (boundary curves) first if (v == 0) bezier.setPoints(_points[0][0], _points[0][1], _points[0][2], _points[0][3]); @@ -256,11 +219,12 @@ void TensorProductPatch::horizontalCurve (double v, CubicBezier &bezier) const { // compute "inner" curve DPair p[4]; for (int i=0; i < 4; i++) { - CubicBezier bezier(_points[0][i], _points[1][i], _points[2][i], _points[3][i]); - p[i] = bezier.valueAt(v); + CubicBezier vbezier(_points[0][i], _points[1][i], _points[2][i], _points[3][i]); + p[i] = vbezier.valueAt(v); } bezier.setPoints(p[0], p[1], p[2], p[3]); } + return bezier; } @@ -316,9 +280,8 @@ static inline double snap (double x) { void TensorProductPatch::approximateRow (double v1, double inc, bool overlap, double delta, const vector &vbeziers, Callback &callback) const { double v2 = snap(v1+inc); double ov2 = (overlap && v2 < 1) ? snap(v2+inc) : v2; - CubicBezier hbezier1, hbezier2; - horizontalCurve(v1, hbezier1); - horizontalCurve(ov2, hbezier2); + CubicBezier hbezier1 = horizontalCurve(v1); + CubicBezier hbezier2 = horizontalCurve(ov2); double u1 = 0; for (size_t i=1; i < vbeziers.size(); i++) { double u2 = snap(u1+inc); @@ -342,7 +305,8 @@ void TensorProductPatch::approximateRow (double v1, double inc, bool overlap, do path.lineto(b3.point(0)); } path.closepath(); - callback.patchSegment(path, averageColor(colorAt(u1, v1), colorAt(u2, v1), colorAt(u1, v2), colorAt(u2, v2))); + // draw segment filled with its midpoint color + callback.patchSegment(path, colorAt((u1+u2)/2, (v1+v2)/2)); u1 = u2; } } @@ -358,26 +322,19 @@ void TensorProductPatch::approximateRow (double v1, double inc, bool overlap, do * @param[in] delta reduce level of detail if the segment size is smaller than the given value * @param[in] callback object notified */ void TensorProductPatch::approximate (int gridsize, bool overlap, double delta, Callback &callback) const { - if (_colors[0] == _colors[1] && _colors[1] == _colors[2] && _colors[2] == _colors[3]) { - // simple case: monochromatic patch - GraphicsPath path = getBoundaryPath(); - callback.patchSegment(path, _colors[0]); + const double inc = 1.0/gridsize; + // collect curves dividing the patch into several columns (curved vertical stripes) + vector vbeziers(gridsize+1); + double u=0; + for (CubicBezier &vbezier : vbeziers) { + vbezier = verticalCurve(u); + u = snap(u+inc); } - else { - const double inc = 1.0/gridsize; - // collect curves dividing the patch into several columns (curved vertical stripes) - vector vbeziers(gridsize+1); - double u=0; - for (int i=0; i <= gridsize; i++) { - verticalCurve(u, vbeziers[i]); - u = snap(u+inc); - } - // compute the segments row by row - double v=0; - for (int i=0; i < gridsize; i++) { - approximateRow(v, inc, overlap, delta, vbeziers, callback); - v = snap(v+inc); - } + // compute the segments row by row + double v=0; + for (int i=0; i < gridsize; i++) { + approximateRow(v, inc, overlap, delta, vbeziers, callback); + v = snap(v+inc); } } @@ -386,9 +343,9 @@ BoundingBox TensorProductPatch::getBBox () const { BoundingBox bbox; CubicBezier bezier; for (int i=0; i <= 1; i++) { - horizontalCurve(i, bezier); + bezier = horizontalCurve(i); bbox.embed(bezier.getBBox()); - verticalCurve(i, bezier); + bezier = verticalCurve(i); bbox.embed(bezier.getBBox()); } return bbox; @@ -463,27 +420,25 @@ void TensorProductPatch::approximate (int gridsize, Callback &callback) const { CoonsPatch::CoonsPatch (const PointVec &points, const ColorVec &colors, Color::ColorSpace cspace, int edgeflag, CoonsPatch *patch) : TensorProductPatch(cspace) { - setPoints(points, edgeflag, patch); - setColors(colors, edgeflag, patch); + CoonsPatch::setPoints(points, edgeflag, patch); + CoonsPatch::setColors(colors, edgeflag, patch); } -DPair CoonsPatch::valueAt (double u, double v) const { - // Compute the value of P(u,v) using the Coons equation rather than the - // tensor product since the "inner" control points of the tensor matrix - // might not be set yet. - CubicBezier bezier1(_points[3][0], _points[3][1], _points[3][2], _points[3][3]); - CubicBezier bezier2(_points[0][0], _points[0][1], _points[0][2], _points[0][3]); - CubicBezier bezier3(_points[3][0], _points[2][0], _points[1][0], _points[0][0]); - CubicBezier bezier4(_points[3][3], _points[2][3], _points[1][3], _points[0][3]); - DPair ph = bezier1.valueAt(u)*(1-v) + bezier2.valueAt(u)*v; - DPair pv = bezier3.valueAt(v)*(1-u) + bezier4.valueAt(v)*u; - DPair pc = (_points[3][0]*(1-u) + _points[3][3]*u)*(1-v) + (_points[0][0]*(1-u) + _points[0][3]*u)*v; - return ph+pv-pc; +inline DPair internal_control_point (const DPair p[4][4], array i) { + const DPair &a = p[i[ 0]][i[ 1]]; + const DPair &b = p[i[ 2]][i[ 3]]; + const DPair &c = p[i[ 4]][i[ 5]]; + const DPair &d = p[i[ 6]][i[ 7]]; + const DPair &e = p[i[ 8]][i[ 9]]; + const DPair &f = p[i[10]][i[11]]; + const DPair &g = p[i[12]][i[13]]; + const DPair &h = p[i[14]][i[15]]; + return (-a*4.0 + (b+c)*6.0 - (d+e)*2.0 + (f+g)*3.0 - h) / 9.0; } -/** Sets the 12 control points defining the geometry of the coons patch. The points +/** Sets the 12 control points defining the geometry of the Coons patch. The points * must be given in the following order: * 3 4 5 6 * 2 7 @@ -505,9 +460,9 @@ void CoonsPatch::setPoints (const PointVec &points, int edgeflag, ShadingPatch * throw ShadingException("invalid number of control points in Coons patch definition"); // Since a Coons patch is a special tensor product patch, we only have to reorder the - // control points and compute the additional "inner" points of the 4x4 point tensor matrix. + // control points and compute the additional "internal" points of the 4x4 point tensor. - // set outer control points of the tensor matrix except those of the first column + // set outer control points of the tensor except those of the first column // because these points depend on the edge flag int i = (edgeflag == 0 ? 4 : 0); _points[3][1] = points[i++]; @@ -525,12 +480,13 @@ void CoonsPatch::setPoints (const PointVec &points, int edgeflag, ShadingPatch * case 1: setFirstMatrixColumn(coonsPatch->_points[3], false); break; case 2: setFirstMatrixColumn(coonsPatch->_points, 3, true); break; case 3: setFirstMatrixColumn(coonsPatch->_points[0], true); break; + default: ; } - // compute inner control points of the tensor matrix - _points[1][1] = valueAt(1.0/3.0, 2.0/3.0); - _points[1][2] = valueAt(2.0/3.0, 2.0/3.0); - _points[2][1] = valueAt(1.0/3.0, 1.0/3.0); - _points[2][2] = valueAt(2.0/3.0, 1.0/3.0); + // compute internal control points of the tensor (see PDF Reference 1.7, p. 330) + _points[1][1] = internal_control_point(_points, {0, 0, 0, 1, 1, 0, 0, 3, 3, 0, 3, 1, 1, 3, 3, 3}); + _points[1][2] = internal_control_point(_points, {0, 3, 0, 2, 1, 3, 0, 0, 3, 3, 3, 2, 1, 0, 3, 0}); + _points[2][1] = internal_control_point(_points, {3, 0, 3, 1, 2, 0, 3, 3, 0, 0, 0, 1, 2, 3, 0, 3}); + _points[2][2] = internal_control_point(_points, {3, 3, 3, 2, 2, 3, 3, 0, 0, 3, 0, 2, 2, 0, 0, 0}); } @@ -551,6 +507,7 @@ void CoonsPatch::setColors (const ColorVec &colors, int edgeflag, ShadingPatch * case 1: _colors[0] = coonsPatch->_colors[2]; _colors[2] = coonsPatch->_colors[3]; break; case 2: _colors[0] = coonsPatch->_colors[3]; _colors[2] = coonsPatch->_colors[1]; break; case 3: _colors[0] = coonsPatch->_colors[1]; _colors[2] = coonsPatch->_colors[0]; break; + default: ; } } diff --git a/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.hpp b/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.hpp index f81d0686b0..e57eb5b020 100644 --- a/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.hpp @@ -2,7 +2,7 @@ ** TensorProductPatch.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -43,14 +43,12 @@ class TensorProductPatch : public ShadingPatch { explicit TensorProductPatch (Color::ColorSpace cspace) : ShadingPatch(cspace) {} TensorProductPatch (const PointVec &points, const ColorVec &colors, Color::ColorSpace cspace, int edgeflag, TensorProductPatch *patch); int psShadingType() const override {return 7;} - void setPoints (const DPair points[4][4], int edgeflag, TensorProductPatch *patch); void setPoints (const PointVec &points, int edgeflag, ShadingPatch *patch) override; void setColors (const ColorVec &colors, int edgeflag, ShadingPatch *patch) override; virtual DPair valueAt (double u, double v) const; Color colorAt (double u, double v) const; - Color averageColor () const override; - void horizontalCurve (double v, CubicBezier &bezier) const; - void verticalCurve (double u, CubicBezier &bezier) const; + CubicBezier horizontalCurve (double v) const; + CubicBezier verticalCurve (double u) const; GraphicsPath getBoundaryPath () const override; void subpatch (double u1, double u2, double v1, double v2, TensorProductPatch &patch) const; DPair blossomValue (double u1, double u2, double u3, double v1, double v2, double v3) const; @@ -61,13 +59,12 @@ class TensorProductPatch : public ShadingPatch { int numColors (int edgeflag) const override {return edgeflag == 0 ? 4 : 2;} protected: - Color averageColor (const Color &c1, const Color &c2, const Color &c3, const Color &c4) const; void approximateRow (double v1, double inc, bool overlap, double delta, const std::vector &beziers, Callback &callback) const; void setFirstMatrixColumn (const DPair source[4], bool reverse); void setFirstMatrixColumn (DPair source[4][4], int col, bool reverse); private: - DPair _points[4][4]; ///< control point matrix defining the patch surface + DPair _points[4][4]; ///< control point tensor defining the geometry of the patch surface Color _colors[4]; ///< vertex colors cK (c0->p00, c1->p03, c2->p30, c3->p33) }; @@ -84,7 +81,6 @@ class CoonsPatch : public TensorProductPatch { int psShadingType() const override {return 6;} void setPoints (const PointVec &points, int edgeflag, ShadingPatch *patch) override; void setColors (const ColorVec &colors, int edgeflag, ShadingPatch *patch) override; - DPair valueAt (double u, double v) const override; int numPoints (int edgeflag) const override {return edgeflag == 0 ? 12 : 8;} int numColors (int edgeflag) const override {return edgeflag == 0 ? 4 : 2;} }; diff --git a/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp b/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp index 4604cb5613..2174e8a1aa 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp @@ -2,7 +2,7 @@ ** Terminal.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/Terminal.hpp b/texk/dvisvgm/dvisvgm-src/src/Terminal.hpp index 80191b396f..69866e8218 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Terminal.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Terminal.hpp @@ -2,7 +2,7 @@ ** Terminal.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp b/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp index c9d87e4c09..efb5863d90 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp @@ -2,7 +2,7 @@ ** ToUnicodeMap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp b/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp index dc0f2bc804..f8c29df3b7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp @@ -2,7 +2,7 @@ ** ToUnicodeMap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp b/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp index 0ff9c881af..1a6fcaa4e9 100644 --- a/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp @@ -2,7 +2,7 @@ ** TpicSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -226,7 +226,7 @@ void TpicSpecialHandler::drawArc (double cx, double cy, double rx, double ry, do } if (_penwidth > 0) { elem->setStrokeWidth(_penwidth); - elem->setStrokeColor(actions.getColor()); + elem->setStrokeColor(actions.getStrokeColor()); if (!closed) elem->setStrokeLineCap(SVGElement::LC_ROUND); } @@ -271,7 +271,7 @@ constexpr int cmd_id (const char *cmd) { bool TpicSpecialHandler::process (const string &prefix, istream &is, SpecialActions &actions) { if (prefix.length() != 2) return false; - _dviColor = actions.getColor(); + _dviColor = actions.getFillColor(); const double mi2bp=0.072; // factor for milli-inch to PS points StreamInputBuffer ib(is); BufferInputReader ir(ib); diff --git a/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp b/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp index 59f1786d49..c99e8f82b1 100644 --- a/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp @@ -2,7 +2,7 @@ ** TpicSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp b/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp index 4b0bebfde0..232ac1670b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp @@ -2,7 +2,7 @@ ** TriangularPatch.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -111,35 +111,10 @@ DPair TriangularPatch::valueAt (double u, double v) const { * The relation between the vertices of the triangle and their barycentric coordinates * is as follows: \f$(1,0,0)=p_1, (0,1,0)=p_2, (0,0,1)=p_0\f$. */ Color TriangularPatch::colorAt (double u, double v) const { - ColorGetter getComponents; - ColorSetter setComponents; - colorQueryFuncs(getComponents, setComponents); valarray comp[3]; for (int i=0; i < 3; i++) - (_colors[i].*getComponents)(comp[i]); - Color color; - (color.*setComponents)(comp[0]*(1-u-v) + comp[1]*u + comp[2]*v); - return color; -} - - -Color TriangularPatch::averageColor () const { - return averageColor(_colors[0], _colors[1], _colors[2]); -} - - -/** Compute the average of three given colors depending on the assigned color space. */ -Color TriangularPatch::averageColor (const Color &c1, const Color &c2, const Color &c3) const { - ColorGetter getComponents; - ColorSetter setComponents; - colorQueryFuncs(getComponents, setComponents); - valarray va1, va2, va3; - (c1.*getComponents)(va1); - (c2.*getComponents)(va2); - (c3.*getComponents)(va3); - Color averageColor; - (averageColor.*setComponents)((va1+va2+va3)/3.0); - return averageColor; + comp[i] = _colors[i].getDoubleValues(); + return Color(comp[0]*(1-u-v) + comp[1]*u + comp[2]*v, colorSpace()); } @@ -183,7 +158,8 @@ void TriangularPatch::approximate (int gridsize, bool overlap, double delta, Cal path.lineto(valueAt(ou2, v1)); path.lineto(valueAt(u1, ov2)); path.closepath(); - callback.patchSegment(path, averageColor(colorAt(u1, v1), colorAt(u2, v1), colorAt(u1, v2))); + // draw segment filled with its midpoint color + callback.patchSegment(path, colorAt((2*u1+u2)/3, (2*v1+v2)/3)); if (snap(u2+v2) <= 1 && (!overlap || inc > delta)) { // create triangular segments pointing in the opposite direction as the whole patch path.clear(); @@ -191,7 +167,8 @@ void TriangularPatch::approximate (int gridsize, bool overlap, double delta, Cal path.lineto(valueAt(u2, v1)); path.lineto(valueAt(u2, v2)); path.closepath(); - callback.patchSegment(path, averageColor(colorAt(u1, v2), colorAt(u2, v1), colorAt(u2, v2))); + // draw segment filled with its midpoint color + callback.patchSegment(path, colorAt((u1+2*u2)/3, (v1+2*v2)/3)); } } } diff --git a/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.hpp b/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.hpp index 82a22f2a8e..c5277f4689 100644 --- a/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.hpp @@ -2,7 +2,7 @@ ** TriangularPatch.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -33,7 +33,6 @@ class TriangularPatch : public ShadingPatch { int psShadingType() const override {return 4;} DPair valueAt (double u, double v) const; Color colorAt (double u, double v) const; - Color averageColor() const override; void setPoints (const PointVec &points, int edgeflag, ShadingPatch *patch) override; void setPoints (const DPair &p1, const DPair &p2, const DPair &p3); void setColors (const ColorVec &colors, int edgeflag, ShadingPatch *patch) override; @@ -44,9 +43,6 @@ class TriangularPatch : public ShadingPatch { int numPoints (int edgeflag) const override {return edgeflag == 0 ? 3 : 1;} int numColors (int edgeflag) const override {return edgeflag == 0 ? 3 : 1;} - protected: - Color averageColor (const Color &c1, const Color &c2, const Color &c3) const; - private: DPair _points[3]; Color _colors[3]; diff --git a/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp b/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp index 646acaa127..a094d43c05 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp @@ -2,7 +2,7 @@ ** Unicode.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -124,7 +124,7 @@ uint32_t Unicode::utf8ToCodepoint (const string &utf8) { auto len = utf8.length(); if (len > 0) { unsigned char c0 = utf8[0]; - if (c0 >= 0 && c0 <= 127) + if (c0 <= 127) return c0; if (len > 1) { unsigned char c1 = utf8[1]; @@ -242,7 +242,7 @@ static int32_t extract_codepoint_from_name (const string &name) { if (hexstr.length() < 4 || (offset == 3 && hexstr.length() % 4 != 0)) return 0; if (offset == 3) - hexstr = hexstr.substr(0, 4); + hexstr.resize(4); int32_t codepoint; istringstream iss(hexstr); iss >> hex >> codepoint; diff --git a/texk/dvisvgm/dvisvgm-src/src/Unicode.hpp b/texk/dvisvgm/dvisvgm-src/src/Unicode.hpp index 7f04bcf83a..171c351596 100644 --- a/texk/dvisvgm/dvisvgm-src/src/Unicode.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/Unicode.hpp @@ -2,7 +2,7 @@ ** Unicode.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/VFActions.hpp b/texk/dvisvgm/dvisvgm-src/src/VFActions.hpp index dc62329359..8d074f19d8 100644 --- a/texk/dvisvgm/dvisvgm-src/src/VFActions.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/VFActions.hpp @@ -2,7 +2,7 @@ ** VFActions.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp b/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp index 5ca91ced3d..c76a19e396 100644 --- a/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp @@ -2,7 +2,7 @@ ** VFReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/VFReader.hpp b/texk/dvisvgm/dvisvgm-src/src/VFReader.hpp index b708ca711c..f144a66bbd 100644 --- a/texk/dvisvgm/dvisvgm-src/src/VFReader.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/VFReader.hpp @@ -2,7 +2,7 @@ ** VFReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/VectorIterator.hpp b/texk/dvisvgm/dvisvgm-src/src/VectorIterator.hpp index 1ec84f1e9f..9445405db9 100644 --- a/texk/dvisvgm/dvisvgm-src/src/VectorIterator.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/VectorIterator.hpp @@ -2,7 +2,7 @@ ** VectorIterator.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp b/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp index b2adcb65e1..e08bb071f3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp @@ -2,7 +2,7 @@ ** XMLDocument.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp b/texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp index c9694c6c2b..1bc1ddc834 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp @@ -2,7 +2,7 @@ ** XMLDocument.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp b/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp index aaf381c65b..10da96cc29 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp @@ -2,7 +2,7 @@ ** XMLNode.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp b/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp index 35e4d500bf..7488038a85 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp @@ -2,7 +2,7 @@ ** XMLNode.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XMLParser.cpp b/texk/dvisvgm/dvisvgm-src/src/XMLParser.cpp index 23fee696a3..f9a23c189a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XMLParser.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/XMLParser.cpp @@ -2,7 +2,7 @@ ** XMLParser.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XMLParser.hpp b/texk/dvisvgm/dvisvgm-src/src/XMLParser.hpp index a181e4c2af..05bc8141f0 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XMLParser.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/XMLParser.hpp @@ -2,7 +2,7 @@ ** XMLParser.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp b/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp index 426b75b7d0..8e4c685741 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp @@ -2,7 +2,7 @@ ** XMLString.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XMLString.hpp b/texk/dvisvgm/dvisvgm-src/src/XMLString.hpp index 8731a26e84..9e9ab8384a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XMLString.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/XMLString.hpp @@ -2,7 +2,7 @@ ** XMLString.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp b/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp index d26cd3c058..4a118d1758 100644 --- a/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp @@ -2,7 +2,7 @@ ** XXHashFunction.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp b/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp index 7f3e7d72f4..dd4099544a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp @@ -2,7 +2,7 @@ ** ZLibOutputStream.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp b/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp index 8815fb77b8..3d5669704d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp @@ -2,7 +2,7 @@ ** dvisvgm.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -293,7 +293,7 @@ static void init_fontmap (const CommandLine &cmdline) { bool additional = !mapseq.empty() && strchr("+-=", mapseq[0]); if (mapseq.empty() || additional) { bool found = false; - for (string mapfile : {"ps2pk", "pdftex", "dvipdfm", "psfonts"}) { + for (string mapfile : {"dvisvgm", "ps2pk", "pdftex", "dvipdfm", "psfonts"}) { if ((found = FontMap::instance().read(mapfile+".map"))) break; } @@ -301,7 +301,7 @@ static void init_fontmap (const CommandLine &cmdline) { Message::wstream(true) << "none of the default map files could be found\n"; } if (!mapseq.empty()) - FontMap::instance().read(mapseq); + FontMap::instance().read(mapseq, true); } @@ -382,7 +382,7 @@ static void set_variables (const CommandLine &cmdline) { #ifdef TTFDEBUG ttf::TTFWriter::CREATE_PS_GLYPH_OUTLINES = cmdline.debugGlyphsOpt.given(); #endif - PsSpecialHandler::EMBED_BITMAP_DATA = cmdline.embedBitmapsOpt.given(); + SVGTree::EMBED_BITMAP_DATA = cmdline.embedBitmapsOpt.given(); if (!PSInterpreter::imageDeviceKnown(PsSpecialHandler::BITMAP_FORMAT)) { ostringstream oss; oss << "unknown image format '" << PsSpecialHandler::BITMAP_FORMAT << "'\nknown formats:\n"; diff --git a/texk/dvisvgm/dvisvgm-src/src/fonts/Base14Fonts.cpp b/texk/dvisvgm/dvisvgm-src/src/fonts/Base14Fonts.cpp index 2861ad96c1..34f3f658b7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/fonts/Base14Fonts.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/fonts/Base14Fonts.cpp @@ -2,7 +2,7 @@ ** Base14Fonts.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/fonts/Base14Fonts.hpp b/texk/dvisvgm/dvisvgm-src/src/fonts/Base14Fonts.hpp index 9acf3d7d78..7ccc2e1e3d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/fonts/Base14Fonts.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/fonts/Base14Fonts.hpp @@ -2,7 +2,7 @@ ** Base14Fonts.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ierrors.h b/texk/dvisvgm/dvisvgm-src/src/ierrors.h index 3184341177..3629639fd7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ierrors.h +++ b/texk/dvisvgm/dvisvgm-src/src/ierrors.h @@ -1,22 +1,26 @@ -/* Copyright (C) 2001-2006 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. - + This software is provided AS-IS with no warranty, either express or implied. - This software is distributed under license and may not be copied, modified - or distributed except as expressly authorized under the terms of that - license. Refer to licensing information at http://www.artifex.com/ - or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, - San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ -/* $Id: ierrors.h 8022 2007-06-05 22:23:38Z giles $ */ + /* Definition of error codes */ #ifndef ierrors_INCLUDED # define ierrors_INCLUDED +//#include "gserrors.h" + /* * DO NOT USE THIS FILE IN THE GRAPHICS LIBRARY. * THIS FILE IS PART OF THE POSTSCRIPT INTERPRETER. @@ -33,33 +37,7 @@ /* Define the error name table */ extern const char *const gs_error_names[]; - /* ------ PostScript Level 1 errors ------ */ - -#define e_unknownerror (-1) /* unknown error */ -#define e_dictfull (-2) -#define e_dictstackoverflow (-3) -#define e_dictstackunderflow (-4) -#define e_execstackoverflow (-5) -#define e_interrupt (-6) -#define e_invalidaccess (-7) -#define e_invalidexit (-8) -#define e_invalidfileaccess (-9) -#define e_invalidfont (-10) -#define e_invalidrestore (-11) -#define e_ioerror (-12) -#define e_limitcheck (-13) -#define e_nocurrentpoint (-14) -#define e_rangecheck (-15) -#define e_stackoverflow (-16) -#define e_stackunderflow (-17) -#define e_syntaxerror (-18) -#define e_timeout (-19) -#define e_typecheck (-20) -#define e_undefined (-21) -#define e_undefinedfilename (-22) -#define e_undefinedresult (-23) -#define e_unmatchedmark (-24) -#define e_VMerror (-25) /* must be the last Level 1 error */ + /* ------ PostScript Level 1 errors ------ */ #define LEVEL1_ERROR_NAMES\ "unknownerror", "dictfull", "dictstackoverflow", "dictstackunderflow",\ @@ -69,85 +47,26 @@ extern const char *const gs_error_names[]; "stackunderflow", "syntaxerror", "timeout", "typecheck", "undefined",\ "undefinedfilename", "undefinedresult", "unmatchedmark", "VMerror" - /* ------ Additional Level 2 errors (also in DPS) ------ */ - -#define e_configurationerror (-26) -#define e_undefinedresource (-27) -#define e_unregistered (-28) + /* ------ Additional Level 2 errors (also in DPS) ------ */ #define LEVEL2_ERROR_NAMES\ "configurationerror", "undefinedresource", "unregistered" - /* ------ Additional DPS errors ------ */ - -#define e_invalidcontext (-29) -/* invalidid is for the NeXT DPS extension. */ -#define e_invalidid (-30) + /* ------ Additional DPS errors ------ */ #define DPS_ERROR_NAMES\ "invalidcontext", "invalidid" -#define ERROR_NAMES\ - LEVEL1_ERROR_NAMES, LEVEL2_ERROR_NAMES, DPS_ERROR_NAMES - - /* ------ Pseudo-errors used internally ------ */ - -/* - * Internal code for a fatal error. - * gs_interpret also returns this for a .quit with a positive exit code. - */ -#define e_Fatal (-100) - -/* - * Internal code for the .quit operator. - * The real quit code is an integer on the operand stack. - * gs_interpret returns this only for a .quit with a zero exit code. - */ -#define e_Quit (-101) - -/* - * Internal code for a normal exit from the interpreter. - * Do not use outside of interp.c. - */ -#define e_InterpreterExit (-102) - -/* - * Internal code that indicates that a procedure has been stored in the - * remap_proc of the graphics state, and should be called before retrying - * the current token. This is used for color remapping involving a call - * back into the interpreter -- inelegant, but effective. - */ -#define e_RemapColor (-103) - -/* - * Internal code to indicate we have underflowed the top block - * of the e-stack. - */ -#define e_ExecStackUnderflow (-104) - -/* - * Internal code for the vmreclaim operator with a positive operand. - * We need to handle this as an error because otherwise the interpreter - * won't reload enough of its state when the operator returns. - */ -#define e_VMreclaim (-105) - -/* - * Internal code for requesting more input from run_string. - */ -#define e_NeedInput (-106) +#define PDF_ERROR_NAMES\ + "pdf_stackoverflow", "pdf_circular_reference" -/* - * Internal code for a normal exit when usage info is displayed. - * This allows Window versions of Ghostscript to pause until - * the message can be read. - */ -#define e_Info (-110) +#define ERROR_NAMES\ + LEVEL1_ERROR_NAMES, LEVEL2_ERROR_NAMES, DPS_ERROR_NAMES, PDF_ERROR_NAMES /* * Define which error codes require re-executing the current object. */ -#define ERROR_IS_INTERRUPT(ecode)\ - ((ecode) == e_interrupt || (ecode) == e_timeout) +#define GS_ERROR_IS_INTERRUPT(ecode)\ + ((ecode) == gs_error_interrupt || (ecode) == gs_error_timeout) #endif /* ierrors_INCLUDED */ diff --git a/texk/dvisvgm/dvisvgm-src/src/macros.hpp b/texk/dvisvgm/dvisvgm-src/src/macros.hpp index cc546f72c2..baaf133ff0 100644 --- a/texk/dvisvgm/dvisvgm-src/src/macros.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/macros.hpp @@ -2,7 +2,7 @@ ** macros.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp index 8fd7552dd6..303a04ae60 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp @@ -2,7 +2,7 @@ ** AttributeExtractor.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp index 5c75974685..d962ee52f2 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp @@ -2,7 +2,7 @@ ** AttributeExtractor.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/ClipPathReassigner.cpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/ClipPathReassigner.cpp index e04a31c18d..8971cd3361 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/ClipPathReassigner.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/ClipPathReassigner.cpp @@ -2,7 +2,7 @@ ** ClipPathReassigner.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -76,15 +76,18 @@ void ClipPathReassigner::execute (XMLElement *defs, XMLElement *context) { for (auto &mapEntry : clipPathMap) { vector &identicalClipPathElements = mapEntry.second; set ids; - for (auto elem : identicalClipPathElements) - ids.insert(elem->getAttributeValue("id")); + for (auto elem : identicalClipPathElements) { + if (const char *id = elem->getAttributeValue("id")) + ids.insert(id); + } for (auto it = descendants.begin(); it != descendants.end();) { - string id = extract_id_from_url((*it)->getAttributeValue("clip-path")); - if (ids.find(id) == ids.end()) - ++it; - else { - (*it)->addAttribute("clip-path", string("url(#") + (*ids.begin()) + ")"); - it = descendants.erase(it); // no need to process this element again + if (const char *clipPathRef = (*it)->getAttributeValue("clip-path")) { + if (ids.find(extract_id_from_url(clipPathRef)) == ids.end()) + ++it; + else { + (*it)->addAttribute("clip-path", string("url(#") + (*ids.begin()) + ")"); + it = descendants.erase(it); // no need to process this element again + } } } } diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/ClipPathReassigner.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/ClipPathReassigner.hpp index 798d431ef7..c60d3c6656 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/ClipPathReassigner.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/ClipPathReassigner.hpp @@ -2,7 +2,7 @@ ** ClipPathReassigner.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/DependencyGraph.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/DependencyGraph.hpp index 81ab6d9615..df70f901d7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/DependencyGraph.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/DependencyGraph.hpp @@ -2,7 +2,7 @@ ** DependencyGraph.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp index 6454ceb5cb..66989dc914 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp @@ -2,7 +2,7 @@ ** GroupCollapser.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.hpp index f5edb946e7..e446c3b1d2 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.hpp @@ -2,7 +2,7 @@ ** GroupCollapser.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/OptimizerModule.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/OptimizerModule.hpp index dbf61eac92..49d27bf82b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/OptimizerModule.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/OptimizerModule.hpp @@ -2,7 +2,7 @@ ** OptimizerModule.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.cpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.cpp index 12fb9e0816..d96ff1c57a 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.cpp @@ -2,7 +2,7 @@ ** RedundantElementRemover.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.hpp index 3cedd27dd6..02c0a8f955 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.hpp @@ -2,7 +2,7 @@ ** RedundantElementRemover.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.cpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.cpp index 402a83997f..fb58e6e896 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.cpp @@ -2,7 +2,7 @@ ** SVGOptimizer.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.hpp index a29c273704..d7c13323a7 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.hpp @@ -2,7 +2,7 @@ ** SVGOptimizer.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp index 25fec00997..806b720927 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp @@ -2,7 +2,7 @@ ** TextSimplifier.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.hpp index 3ec9e3954f..4c6b8779f1 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.hpp @@ -2,7 +2,7 @@ ** TextSimplifier.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp index 6b36db1551..b78bd56cb8 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp @@ -2,7 +2,7 @@ ** TransformSimplifier.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.hpp index 15052fb87e..8aca3214cc 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.hpp @@ -2,7 +2,7 @@ ** TransformSimplifier.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.cpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.cpp index 55f1ed77fb..a70f4f9215 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.cpp @@ -2,7 +2,7 @@ ** WSNodeRemover.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.hpp b/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.hpp index 3898ca3767..8d9ab9bbff 100644 --- a/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.hpp @@ -2,7 +2,7 @@ ** WSNodeRemover.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/options.dtd b/texk/dvisvgm/dvisvgm-src/src/options.dtd index 49ff5aa4cf..5a876ed703 100644 --- a/texk/dvisvgm/dvisvgm-src/src/options.dtd +++ b/texk/dvisvgm/dvisvgm-src/src/options.dtd @@ -3,7 +3,7 @@ ** options.dtd ** ** ** ** This file is part of dvisvgm - a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/options.xml b/texk/dvisvgm/dvisvgm-src/src/options.xml index df8f40c6c2..286a9807be 100644 --- a/texk/dvisvgm/dvisvgm-src/src/options.xml +++ b/texk/dvisvgm/dvisvgm-src/src/options.xml @@ -3,7 +3,7 @@ ** options.xml ** ** ** ** This file is part of dvisvgm - a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -26,7 +26,7 @@ --eps [options] epsfile --pdf [options] pdffile This program converts DVI files, as created by TeX/LaTeX, as well as\nEPS and PDF files to the XML-based scalable vector graphics format SVG. - Copyright (C) 2005-2024 Martin Gieseking <martin.gieseking@uos.de> + Copyright (C) 2005-2025 Martin Gieseking <martin.gieseking@uos.de>
diff --git a/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp b/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp index 3b955a9558..1d8b624996 100644 --- a/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp @@ -2,7 +2,7 @@ ** psdefs.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -80,7 +80,7 @@ const char *PSInterpreter::PSDEFS = "{ColorSpace load add}if bbknown{4 add}if ShadingType 5 eq{1 add}if(shfill)prcm" "d}if end}if}if end}put @SD/image{dup type/dicttype eq{dup}{<>}ifelse @execimg}put @SD/colorimage{<<2 index{/Wi" -"dth 2 index 8 add index/Height 4 index 9 add index}{/Width 8 index/Height 9 in" +"dth 2 index 7 add index/Height 4 index 8 add index}{/Width 8 index/Height 9 in" "dex}ifelse/colorimg true>>@execimg}put/@imgbase(./)def/@imgdevice(jpeg)def/@ex" "ecimg{@GD/@imgcnt 2 copy .knownget{1 add}{1}ifelse put begin< ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/CmapTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/CmapTable.hpp index 6c0b3fb735..ecc9c56bd9 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/CmapTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/CmapTable.hpp @@ -2,7 +2,7 @@ ** CmapTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/GlyfTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/GlyfTable.cpp index c5bf302ed2..d2b48e2f78 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/GlyfTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/GlyfTable.cpp @@ -2,7 +2,7 @@ ** GlyfTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/GlyfTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/GlyfTable.hpp index 774851b50c..10866ecc9e 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/GlyfTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/GlyfTable.hpp @@ -2,7 +2,7 @@ ** GlyfTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/HeadTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/HeadTable.cpp index 0c908e2018..411209c8a0 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/HeadTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/HeadTable.cpp @@ -2,7 +2,7 @@ ** HeadTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -37,20 +37,6 @@ void HeadTable::updateGlobalBbox (int16_t xmin, int16_t ymin, int16_t xmax, int1 } -/** Returns the number of seconds elapsed since 1.1.1904 00:00:00 until now. - * @return number of seconds separated in upper and lower dword of a 64-bit value */ -static pair seconds_since_1904 () { - auto now = chrono::system_clock::now(); - time_t now_time = chrono::system_clock::to_time_t(now); - struct tm *comp = gmtime(&now_time); - util::Date date1(1904, 1, 1); - util::Date date2(comp->tm_year+1900, comp->tm_mon+1, comp->tm_mday); - uint64_t days = date2 - date1 - 1; - uint64_t seconds = ((days*24 + comp->tm_hour)*60 + comp->tm_min)*60 + comp->tm_sec; - return {uint32_t(seconds >> 32), uint32_t(seconds & 0xffffffff)}; -} - - /** Writes the head table to a given output stream. * https://docs.microsoft.com/en-us/typography/opentype/spec/head */ void HeadTable::write (ostream &os) const { @@ -61,11 +47,10 @@ void HeadTable::write (ostream &os) const { writeUInt32(os, 0x5F0F3CF5); // magic number writeUInt16(os, 1+2); // flags (baseline at y=0, left sidebearing point at x=0) writeUInt16(os, uint16_t(std::round(ttfWriter()->targetUnitsPerEm()))); - auto seconds = seconds_since_1904(); - writeUInt32(os, seconds.first); // creation time, upper dword - writeUInt32(os, seconds.second); // creation time, lower dword - writeUInt32(os, seconds.first); // modification time, upper dword - writeUInt32(os, seconds.second); // modification time, lower dword + writeUInt32(os, 0); // creation time, upper dword + writeUInt32(os, 0); // creation time, lower dword + writeUInt32(os, 0); // modification time, upper dword + writeUInt32(os, 0); // modification time, lower dword writeInt16(os, _xMin); writeInt16(os, _yMin); writeInt16(os, _xMax); diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/HeadTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/HeadTable.hpp index b1f8a9bfd2..7c9515d056 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/HeadTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/HeadTable.hpp @@ -2,7 +2,7 @@ ** HeadTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/HheaTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/HheaTable.cpp index e00c91036c..79842c4033 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/HheaTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/HheaTable.cpp @@ -2,7 +2,7 @@ ** HheaTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/HheaTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/HheaTable.hpp index 561e0bcdde..eb5bb7fd12 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/HheaTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/HheaTable.hpp @@ -2,7 +2,7 @@ ** HheaTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/HmtxTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/HmtxTable.cpp index bf8624fe75..69b9565f99 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/HmtxTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/HmtxTable.cpp @@ -2,7 +2,7 @@ ** HmtxTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/HmtxTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/HmtxTable.hpp index 489f02d835..935473f80b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/HmtxTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/HmtxTable.hpp @@ -2,7 +2,7 @@ ** HmtxTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/LocaTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/LocaTable.hpp index 9253a29144..5efc41f69c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/LocaTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/LocaTable.hpp @@ -2,7 +2,7 @@ ** LocaTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/MaxpTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/MaxpTable.cpp index 42e1058c51..d0531c2dd2 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/MaxpTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/MaxpTable.cpp @@ -2,7 +2,7 @@ ** MaxpTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/MaxpTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/MaxpTable.hpp index ea50b86ed9..4b28130128 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/MaxpTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/MaxpTable.hpp @@ -2,7 +2,7 @@ ** MaxpTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/NameTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/NameTable.cpp index 312ddf973b..3db2ce06d5 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/NameTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/NameTable.cpp @@ -2,7 +2,7 @@ ** NameTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/NameTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/NameTable.hpp index 26de581124..9a3c843104 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/NameTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/NameTable.hpp @@ -2,7 +2,7 @@ ** NameTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.cpp index 58ded2965e..8de76c673d 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.cpp @@ -2,7 +2,7 @@ ** OS2Table.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.hpp index 042194df22..c7b6e8d99b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/OS2Table.hpp @@ -2,7 +2,7 @@ ** OS2Table.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/PostTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/PostTable.cpp index 1f94f1654c..eb848ad6df 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/PostTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/PostTable.cpp @@ -2,7 +2,7 @@ ** PostTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/PostTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/PostTable.hpp index d2a703dea1..84b53cda1e 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/PostTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/PostTable.hpp @@ -2,7 +2,7 @@ ** PostTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFAutohint.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFAutohint.cpp index c707c9e5ae..76bbb4b4b4 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFAutohint.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFAutohint.cpp @@ -2,7 +2,7 @@ ** TTFAutohint.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFAutohint.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFAutohint.hpp index 081930b8f7..f3bc28751c 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFAutohint.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFAutohint.hpp @@ -2,7 +2,7 @@ ** TTFAutohint.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.cpp index 8d9f97011f..279d87e940 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.cpp @@ -2,7 +2,7 @@ ** TTFTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.hpp index 21217349d4..1087f88c69 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFTable.hpp @@ -2,7 +2,7 @@ ** TTFTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFWriter.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFWriter.cpp index b3ec81cb07..e3293489df 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFWriter.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFWriter.cpp @@ -2,7 +2,7 @@ ** TTFWriter.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -63,7 +63,7 @@ class TTFHeader : public TTFTable { void write (ostream &os) const override { writeUInt32(os, 0x00010000); // sfntVersion writeUInt16(os, _numTables); - uint16_t entrySelector = util::ilog2(_numTables); + uint16_t entrySelector = max(0, util::ilog2(_numTables)); uint16_t searchRange = (1 << entrySelector)*16; writeUInt16(os, searchRange); writeUInt16(os, entrySelector); diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFWriter.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFWriter.hpp index 445696ee4b..a8f9b8d789 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/TTFWriter.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/TTFWriter.hpp @@ -2,7 +2,7 @@ ** TTFWriter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/VheaTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/VheaTable.cpp index e703a46fa1..bc6b2e220f 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/VheaTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/VheaTable.cpp @@ -2,7 +2,7 @@ ** VheaTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/VheaTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/VheaTable.hpp index 58521979af..a024997ab5 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/VheaTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/VheaTable.hpp @@ -2,7 +2,7 @@ ** VheaTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/VmtxTable.cpp b/texk/dvisvgm/dvisvgm-src/src/ttf/VmtxTable.cpp index d4c941750a..17793902c8 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/VmtxTable.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/VmtxTable.cpp @@ -2,7 +2,7 @@ ** VmtxTable.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/ttf/VmtxTable.hpp b/texk/dvisvgm/dvisvgm-src/src/ttf/VmtxTable.hpp index c26585fcff..3d70b0ab62 100644 --- a/texk/dvisvgm/dvisvgm-src/src/ttf/VmtxTable.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/ttf/VmtxTable.hpp @@ -2,7 +2,7 @@ ** VmtxTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/utility.cpp b/texk/dvisvgm/dvisvgm-src/src/utility.cpp index b4938f70ed..1f7753d999 100644 --- a/texk/dvisvgm/dvisvgm-src/src/utility.cpp +++ b/texk/dvisvgm/dvisvgm-src/src/utility.cpp @@ -2,7 +2,7 @@ ** utility.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -282,11 +282,11 @@ string util::mimetype (const string &fname) { string ret; auto pos = fname.rfind('.'); if (pos != string::npos) { - string suffix = fname.substr(pos+1); + string suffix = tolower(fname.substr(pos+1)); if (suffix == "svg") ret = "svg+xml"; else if (suffix == "png" || suffix == "gif") - ret = suffix; + ret = std::move(suffix); else if (suffix == "jpg" || suffix == "jpeg") ret = "jpeg"; else if (suffix == "tif" || suffix == "tiff") @@ -296,63 +296,3 @@ string util::mimetype (const string &fname) { ret = "image/"+ret; return ret; } - -/////////////////////////////////////////////////////////////////////// - -static bool is_leap_year (int year) { - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); -} - - -/** Returns the number of leap years in the interval [year1, year2]. */ -static size_t number_of_leap_years (int year1, int year2) { - year1--; - size_t ly1 = year1/4 - year1/100 + year1/400; - size_t ly2 = year2/4 - year2/100 + year2/400; - return ly2-ly1; -} - - -static size_t number_of_days (int year, int month1, int month2) { - const int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - size_t days = is_leap_year(year) ? 366 : 365; - for (int i=0; i < month1; i++) - days -= mdays[i]; - for (int i=month2+1; i < 12; i++) - days -= mdays[i]; - return days; -} - - -static size_t number_of_days (int year1, int month1, int year2, int month2) { - size_t days = 0; - if (year1 == year2) - days = number_of_days(year1, month1, month2); - else { - if (year2-year1 > 1) - days = (year2-year1-1)*365 + number_of_leap_years(year1+1, year2-1); - days += number_of_days(year1, month1, 11); - days += number_of_days(year2, 0, month2); - } - return days; -} - - -/** Returns the number of days spanning the interval from this date up to another one. */ -size_t util::Date::operator - (Date date2) const { - Date date1 = *this; - if (date2 < date1) - std::swap(date1, date2); - size_t days = ::number_of_days(date1._year, date1._month, date2._year, date2._month-1); - days += date2._day - date1._day + 1; - return days; -} - - -bool util::Date::operator < (const Date &date) const { - if (_year < date._year) return true; - if (_year > date._year) return false; - if (_month < date._month) return true; - if (_month > date._month) return false; - return _day < date._day; -} \ No newline at end of file diff --git a/texk/dvisvgm/dvisvgm-src/src/utility.hpp b/texk/dvisvgm/dvisvgm-src/src/utility.hpp index d12e3c6746..237c0b2b2b 100644 --- a/texk/dvisvgm/dvisvgm-src/src/utility.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/utility.hpp @@ -2,7 +2,7 @@ ** utility.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -25,6 +25,7 @@ #include #endif +#include #include #include #include @@ -51,6 +52,10 @@ double integral (double t0, double t1, int n, const std::function inline int sgn (T x) {return (x > T(0)) - (x < T(0));} +inline double clip (double x, double min, double max) { + return x < min ? min : (x > max ? max : x); +} + } // namespace math namespace util { @@ -231,16 +236,6 @@ struct set_const_of { }; }; -class Date { - public: - Date (int year, int month, int day) : _year(year), _month(month-1), _day(day-1) {} - bool operator < (const Date &date) const; - size_t operator - (Date date2) const; - - private: - int _year, _month, _day; // _month and _day are 0-based -}; - } // namespace util #endif diff --git a/texk/dvisvgm/dvisvgm-src/src/version.hpp.in b/texk/dvisvgm/dvisvgm-src/src/version.hpp.in index 0a819bdaf1..030bdd8bb3 100644 --- a/texk/dvisvgm/dvisvgm-src/src/version.hpp.in +++ b/texk/dvisvgm/dvisvgm-src/src/version.hpp.in @@ -2,7 +2,7 @@ ** version.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/src/windows.hpp b/texk/dvisvgm/dvisvgm-src/src/windows.hpp index 6eb2b45ba3..b66f355375 100644 --- a/texk/dvisvgm/dvisvgm-src/src/windows.hpp +++ b/texk/dvisvgm/dvisvgm-src/src/windows.hpp @@ -2,7 +2,7 @@ ** windows.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp index 28e1ec5853..c21ca93bbd 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp @@ -2,7 +2,7 @@ ** BezierTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp index 043a77d045..8fe70e10e5 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp @@ -2,7 +2,7 @@ ** BitmapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/BoundingBoxTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/BoundingBoxTest.cpp index 872cf9858a..233539554e 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/BoundingBoxTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/BoundingBoxTest.cpp @@ -2,7 +2,7 @@ ** BoundingBoxTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/CMapManagerTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/CMapManagerTest.cpp index ca4b612d86..4c8c3cff9d 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/CMapManagerTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/CMapManagerTest.cpp @@ -2,7 +2,7 @@ ** CMapManagerTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/CMapReaderTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/CMapReaderTest.cpp index a30f78ed16..d3431e0ef6 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/CMapReaderTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/CMapReaderTest.cpp @@ -2,7 +2,7 @@ ** CMapReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp index 2c555b6f93..49106b42a9 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp @@ -2,7 +2,7 @@ ** CMapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/CalculatorTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/CalculatorTest.cpp index 65f24e8e21..5b737f98aa 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/CalculatorTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/CalculatorTest.cpp @@ -2,7 +2,7 @@ ** CalculatorTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/ColorSpecialTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/ColorSpecialTest.cpp index 43284c991d..3d93de19bc 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/ColorSpecialTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/ColorSpecialTest.cpp @@ -2,7 +2,7 @@ ** ColorSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -28,10 +28,11 @@ using namespace std; class ColorSpecialTest : public ::testing::Test { protected: struct SetColor : EmptySpecialActions { - SetColor () : color(0) {} - void setColor (const Color &c) {color = uint32_t(c);} - bool equals (uint32_t c) {return color == c;} - uint32_t color; + void setFillColor (const Color &c) override {fillColor = uint32_t(c);} + void setStrokeColor (const Color &c) override {strokeColor = uint32_t(c);} + bool equals (uint32_t c) const {return fillColor == c && strokeColor == c;} + bool equals (uint32_t fc, uint32_t sc) const {return fillColor == fc && strokeColor == sc;} + uint32_t fillColor=0, strokeColor=0; }; ColorSpecialHandler handler; SetColor actions; @@ -73,6 +74,17 @@ TEST_F(ColorSpecialTest, rgb) { std::istringstream iss("rgb 1 0 1"); handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0xff00ff)); + EXPECT_EQ(handler.stackSize(), 1u); + iss.clear(); + iss.str("fill rgb 1 0 0"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0xff0000, 0xff00ff)); + EXPECT_EQ(handler.stackSize(), 1u); + iss.clear(); + iss.str("stroke rgb 0 1 1"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0xff0000, 0x00ffff)); + EXPECT_EQ(handler.stackSize(), 1u); } @@ -80,13 +92,15 @@ TEST_F(ColorSpecialTest, hsb) { std::istringstream iss("hsb 1 0.5 1"); handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0xff8080)); + EXPECT_EQ(handler.stackSize(), 1u); } TEST_F(ColorSpecialTest, cmyk) { std::istringstream iss("cmyk 0.1 0.2 0.4 0.6"); handler.process("", iss, actions); - EXPECT_TRUE(actions.equals(0x5c523d)); + EXPECT_TRUE(actions.equals(0x1a336699)); + EXPECT_EQ(handler.stackSize(), 1u); } @@ -94,18 +108,22 @@ TEST_F(ColorSpecialTest, stack1) { std::istringstream iss("push rgb 1 0 0"); handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0xff0000)); + EXPECT_EQ(handler.stackSize(), 1u); iss.clear(); iss.str("push Blue"); handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0x0000ff)); + EXPECT_EQ(handler.stackSize(), 2u); iss.clear(); iss.str("pop"); handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0xff0000)); + EXPECT_EQ(handler.stackSize(), 1u); iss.clear(); iss.str("pop"); handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0x000000)); + EXPECT_EQ(handler.stackSize(), 0u); } @@ -113,17 +131,62 @@ TEST_F(ColorSpecialTest, stack2) { std::istringstream iss("push rgb 1 0 0"); handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0xff0000)); + EXPECT_EQ(handler.stackSize(), 1u); iss.clear(); iss.str("push rgb 0 1 0"); handler.process("", iss, actions); + EXPECT_EQ(handler.stackSize(), 2u); iss.clear(); iss.str("gray 0.2"); // clear color stack implicitly handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0x333333)); + EXPECT_EQ(handler.stackSize(), 1u); iss.clear(); iss.str("pop"); handler.process("", iss, actions); EXPECT_TRUE(actions.equals(0x000000)); + EXPECT_EQ(handler.stackSize(), 0u); +} + + +TEST_F(ColorSpecialTest, stack3) { + std::istringstream iss("push fill cmyk 0.1 0.2 0.4 0.6"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0x1a336699, 0)); + EXPECT_EQ(handler.stackSize(), 1u); + iss.clear(); + iss.str("push stroke Blue"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0x1a336699, 0x0000ff)); + EXPECT_EQ(handler.stackSize(), 2u); + iss.clear(); + iss.str("set fill Green"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0x00ff00, 0x0000ff)); + EXPECT_EQ(handler.stackSize(), 2u); + iss.clear(); + iss.str("set White"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0xffffff)); + EXPECT_EQ(handler.stackSize(), 2u); +} + + +TEST_F(ColorSpecialTest, stack4) { + std::istringstream iss("set stroke Cyan"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0, 0x00ffff)); + EXPECT_EQ(handler.stackSize(), 0u); + iss.clear(); + iss.str("push fill Blue"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0x0000ff, 0x00ffff)); + EXPECT_EQ(handler.stackSize(), 1u); + iss.clear(); + iss.str("pop"); + handler.process("", iss, actions); + EXPECT_TRUE(actions.equals(0, 0x00ffff)); + EXPECT_EQ(handler.stackSize(), 0u); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp index fd27478a85..34ad44fd87 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp @@ -2,7 +2,7 @@ ** ColorTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -65,20 +65,7 @@ TEST(ColorTest, hsb) { TEST(ColorTest, cmyk) { Color color; color.setCMYK(0.5, 0.4, 0.6, 0.2); - EXPECT_EQ(color.rgbString(), "#667a52"); - double c, m, y, k; - color.setRGB(0.0, 0.0, 0.0); - color.getCMYK(c, m, y, k); - EXPECT_DOUBLE_EQ(c, 0.0); - EXPECT_DOUBLE_EQ(m, 0.0); - EXPECT_DOUBLE_EQ(y, 0.0); - EXPECT_DOUBLE_EQ(k, 1.0); - color.setRGB(1.0, 0.0, 0.0); - color.getCMYK(c, m, y, k); - EXPECT_DOUBLE_EQ(c, 0.0); - EXPECT_DOUBLE_EQ(m, 1.0); - EXPECT_DOUBLE_EQ(y, 1.0); - EXPECT_DOUBLE_EQ(k, 0.0); + EXPECT_EQ(color.rgbString(), "#767761"); } @@ -101,6 +88,22 @@ TEST(ColorTest, name) { } +TEST(ColorTest, rgbfunc) { + EXPECT_EQ(Color("rgb(1,0,1)").rgbString(), "#f0f"); + EXPECT_EQ(Color("rgb(1)").rgbString(), "#f00"); + EXPECT_EQ(Color("rgb(1 1)").rgbString(), "#ff0"); + EXPECT_EQ(Color("rgb(0 0 0.5)").rgbString(), "#000080"); +} + + +TEST(ColorTest, cmykfunc) { + EXPECT_EQ(Color("cmyk(1,0,1,0)").rgbString(), "#00a650"); + EXPECT_EQ(Color("cmyk(1)").rgbString(), "#00aeef"); + EXPECT_EQ(Color("cmyk(1,1)").rgbString(), "#2e3092"); + EXPECT_EQ(Color("cmyk(0.5 1 0 0)").rgbString(), "#92278f"); +} + + TEST(ColorTest, getXYZ) { Color c; double x, y, z; @@ -207,7 +210,7 @@ TEST(ColorTest, set) { EXPECT_EQ(uint32_t(color), 0x1a334du); it.reset(); color.set(Color::ColorSpace::CMYK, it); - EXPECT_EQ(uint32_t(color), 0x8a7a6bu); + EXPECT_EQ(uint32_t(color), 0x1A334D66u); it.reset(); color.set(Color::ColorSpace::LAB, it); EXPECT_EQ(uint32_t(color), 0x010000u); diff --git a/texk/dvisvgm/dvisvgm-src/tests/CommandLineTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/CommandLineTest.cpp index 67f8e3e649..72fd1831b3 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/CommandLineTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/CommandLineTest.cpp @@ -2,7 +2,7 @@ ** CommandLineTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/DVIReaderTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/DVIReaderTest.cpp index a4cc90090c..4e9d2d4ede 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/DVIReaderTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/DVIReaderTest.cpp @@ -2,7 +2,7 @@ ** DVIReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/DependencyGraphTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/DependencyGraphTest.cpp index 3eaa8d4bee..e58ba349a7 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/DependencyGraphTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/DependencyGraphTest.cpp @@ -2,7 +2,7 @@ ** DependencyGraphTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/DirectoryTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/DirectoryTest.cpp index 2b679aa0f7..cb4e704d43 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/DirectoryTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/DirectoryTest.cpp @@ -2,7 +2,7 @@ ** DirectoryTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp index c3303275e2..16d7139e75 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp @@ -2,7 +2,7 @@ ** DvisvgmSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -20,11 +20,16 @@ #include #include +#include #include #include "DvisvgmSpecialHandler.hpp" #include "SpecialActions.hpp" #include "XMLNode.hpp" +#ifndef SRCDIR +#define SRCDIR "." +#endif + using namespace std; @@ -51,9 +56,12 @@ class DvisvgmSpecialTest : public ::testing::Test { double getX () const override {return -42;} double getY () const override {return 14;} unsigned getCurrentPageNumber() const override {return 1;} + Color getFillColor () const override {return Color(0xff0000);} + Color getStrokeColor () const override {return Color(0x00ff00);} FilePath getSVGFilePath(unsigned pageno) const override {return FilePath("test.svg");} bool defsEquals (const string &str) const {return defsString() == str;} bool pageEquals (const string &str) const {return pageString() == str;} + bool pageMatches (const string &pattern) const {return regex_match(pageString(), regex(pattern));} bool bboxEquals (const string &str) const {return bbox.svgViewBoxString() == str;} string bboxString () const {return bbox.svgViewBoxString();} string defsString () const {return toString(svgTree().defsNode());} @@ -319,16 +327,16 @@ TEST_F(DvisvgmSpecialTest, fail2) { TEST_F(DvisvgmSpecialTest, processImg) { - std::istringstream iss("img 72.27 72.27 test.png"); + std::istringstream iss("img 72.27 72.27 " SRCDIR "/data/rectangle.png"); handler.process("", iss, recorder); EXPECT_TRUE(recorder.defsEquals("")); - EXPECT_TRUE(recorder.pageEquals("")) << recorder.pageString(); + EXPECT_TRUE(recorder.pageMatches("")) << recorder.pageString(); recorder.clear(); iss.clear(); - iss.str("img 10bp 20bp test2.png"); + iss.str("img 10bp 20bp " SRCDIR "/data/rectangle.png"); handler.process("", iss, recorder); - EXPECT_TRUE(recorder.pageEquals("")) << recorder.pageString(); + EXPECT_TRUE(recorder.pageMatches("")) << recorder.pageString(); } @@ -376,6 +384,10 @@ TEST_F(DvisvgmSpecialTest, expandText) { EXPECT_EQ(recorder.expandText("static text"), "static text"); EXPECT_EQ(recorder.expandText("x={?x}, y={?y}"), "x=-42, y=14"); EXPECT_EQ(recorder.expandText("page:{?pageno}, file:{?svgfile}"), "page:1, file:test.svg"); + EXPECT_EQ(recorder.expandText("xxx{?cmyk(1,0,1,0)}yyy"), "xxx#00a650yyy"); + EXPECT_EQ(recorder.expandText("xxx{?cmyk(1,0,1,0)}yyy{?cmyk(1,0,0,0)}zzz"), "xxx#00a650yyy#00aeefzzz"); + EXPECT_EQ(recorder.expandText("fill='{?fillcolor}' stroke='{?strokecolor}'"), "fill='#f00' stroke='#0f0'"); + EXPECT_EQ(recorder.expandText("stroke='{?color}'"), "stroke='#f00'"); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/EllipticalArcTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/EllipticalArcTest.cpp index f08e3513e7..9cd45b2009 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/EllipticalArcTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/EllipticalArcTest.cpp @@ -2,7 +2,7 @@ ** EllipticalArcTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/EmSpecialTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/EmSpecialTest.cpp index 3bde3cc210..77ab35b5c6 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/EmSpecialTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/EmSpecialTest.cpp @@ -2,7 +2,7 @@ ** EmSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -34,15 +34,17 @@ class EmSpecialTest : public ::testing::Test { class ActionsRecorder : public EmptySpecialActions { public: ActionsRecorder () : x(), y() {} - void embed (const BoundingBox &bb) override {bbox.embed(bb);} - void setX (double xx) override {x = xx;} - void setY (double yy) override {x = yy;} - double getX () const override {return x;} - double getY () const override {return y;} - Color getColor () const override {return color;} - void setColor (const Color &c) override {color = c;} - string getPageXML () const {ostringstream oss; oss << *svgTree().pageNode(); return oss.str();} - const Matrix& getMatrix () const override {static Matrix m(1); return m;} + void embed (const BoundingBox &bb) override {bbox.embed(bb);} + void setX (double xx) override {x = xx;} + void setY (double yy) override {x = yy;} + double getX () const override {return x;} + double getY () const override {return y;} + Color getFillColor () const override {return fillColor;} + void setFillColor (const Color &c) override {fillColor = c;} + Color getStrokeColor () const override {return strokeColor;} + void setStrokeColor (const Color &c) override {strokeColor = c;} + string getPageXML () const {ostringstream oss; oss << *svgTree().pageNode(); return oss.str();} + const Matrix& getMatrix () const override {static Matrix m(1); return m;} void clear () { SpecialActions::svgTree().reset(); @@ -58,7 +60,7 @@ class EmSpecialTest : public ::testing::Test { private: double x, y; BoundingBox bbox; - Color color; + Color fillColor, strokeColor; }; @@ -171,7 +173,7 @@ TEST_F(EmSpecialTest, hvline) { EXPECT_EQ(recorder.getPageXML(), "\n\n"); recorder.clear(); - recorder.setColor(Color(0.0, 0.0, 1.0)); + recorder.setFillColor(Color(0.0, 0.0, 1.0)); handler.processSpecial("point 1, 10, 10"); handler.processSpecial("point 2, 100, 100"); handler.processSpecial("line 1v, 2h, 10bp"); // cut line ends horizontally @@ -182,7 +184,7 @@ TEST_F(EmSpecialTest, hvline) { TEST_F(EmSpecialTest, lineto) { DPair p[] = {DPair(0,0), DPair(0,10), DPair(10,10), DPair(10,0)}; int n = sizeof(p)/sizeof(DPair); - recorder.setColor(Color(1.0, 0.0, 0.0)); + recorder.setStrokeColor(Color(1.0, 0.0, 0.0)); for (int i=0; i <= n; i++) { recorder.setX(p[i%n].x()); recorder.setY(p[i%n].y()); diff --git a/texk/dvisvgm/dvisvgm-src/tests/FileFinderTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/FileFinderTest.cpp index fd9c9aeb5d..0299aba864 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/FileFinderTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/FileFinderTest.cpp @@ -2,7 +2,7 @@ ** FileFinderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/FilePathTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/FilePathTest.cpp index a2876ee02a..ad1d81479f 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/FilePathTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/FilePathTest.cpp @@ -2,7 +2,7 @@ ** FilePathTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -33,14 +33,14 @@ using namespace std; TEST(FilePathTest, empty) { FilePath path; ASSERT_TRUE(path.empty()); - path.set("/a/b/c/d", false, "/"); + path.set("/a/b/c/d", FilePath::PT_DIR, "/"); ASSERT_FALSE(path.empty()); ASSERT_EQ(path.absolute(), "/a/b/c/d"); } TEST(FilePathTest, dir1) { - FilePath fp("a/b/c/d", false, "/"); + FilePath fp("a/b/c/d", FilePath::PT_DIR, "/"); ASSERT_EQ(fp.absolute(), "/a/b/c/d"); ASSERT_EQ(fp.relative("/"), "a/b/c/d"); ASSERT_EQ(fp.relative("/a/b"), "c/d"); @@ -52,7 +52,7 @@ TEST(FilePathTest, dir1) { TEST(FilePathTest, dir2) { - FilePath fp("a/b/c/d", false, "/x/y"); + FilePath fp("a/b/c/d", FilePath::PT_DIR, "/x/y"); ASSERT_EQ(fp.absolute(), "/x/y/a/b/c/d"); ASSERT_EQ(fp.relative("/"), "x/y/a/b/c/d"); ASSERT_EQ(fp.relative("/x/y/a/b"), "c/d"); @@ -64,7 +64,7 @@ TEST(FilePathTest, dir2) { TEST(FilePathTest, file1) { - FilePath fp("a/b/c/d/f.ext", true, "/"); + FilePath fp("a/b/c/d/f.ext", FilePath::PT_FILE, "/"); ASSERT_EQ(fp.absolute(), "/a/b/c/d/f.ext"); ASSERT_EQ(fp.relative("/"), "a/b/c/d/f.ext"); ASSERT_EQ(fp.relative("/a/b"), "c/d/f.ext"); @@ -84,14 +84,14 @@ TEST(FilePathTest, file1) { TEST(FilePathTest, file2) { - FilePath fp("/f.ext", true, "/"); + FilePath fp("/f.ext", FilePath::PT_FILE, "/"); ASSERT_EQ(fp.absolute(), "/f.ext"); ASSERT_EQ(fp.relative("/a/b"), "../../f.ext"); } TEST(FilePathTest, file3) { - FilePath fp("/f.ext", true, "/x/y"); + FilePath fp("/f.ext", FilePath::PT_FILE, "/x/y"); ASSERT_EQ(fp.absolute(), "/f.ext"); ASSERT_EQ(fp.relative("/a/b"), "../../f.ext"); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/FileSystemTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/FileSystemTest.cpp index 2952392af3..33a9615b5c 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/FileSystemTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/FileSystemTest.cpp @@ -2,7 +2,7 @@ ** FileSystemTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/FontCacheTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/FontCacheTest.cpp index 88d446454e..9eac448d65 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/FontCacheTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/FontCacheTest.cpp @@ -2,7 +2,7 @@ ** FontCacheTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/FontManagerTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/FontManagerTest.cpp index 6d6eea6aef..9803da70ad 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/FontManagerTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/FontManagerTest.cpp @@ -2,7 +2,7 @@ ** FontManagerTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -68,7 +68,7 @@ TEST_F(FontManagerTest, getFont) { EXPECT_TRUE(f2); EXPECT_NE(f1, f2); EXPECT_EQ(f2->name(), "cmr10"); - EXPECT_TRUE(dynamic_cast(f2)); + EXPECT_TRUE(dynamic_cast(f2)); EXPECT_EQ(f2->uniqueFont(), f1); EXPECT_EQ(f2->color(), Color::BLACK); diff --git a/texk/dvisvgm/dvisvgm-src/tests/FontMapTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/FontMapTest.cpp index 9ec3b7233a..45a7affe16 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/FontMapTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/FontMapTest.cpp @@ -2,7 +2,7 @@ ** FontMapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/GFGlyphTracerTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/GFGlyphTracerTest.cpp index 74a8ed35a0..5bcac70af7 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/GFGlyphTracerTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/GFGlyphTracerTest.cpp @@ -2,7 +2,7 @@ ** GFGlyphTracerTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/GFReaderTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/GFReaderTest.cpp index e23f079ff6..abbb5c59f1 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/GFReaderTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/GFReaderTest.cpp @@ -2,7 +2,7 @@ ** GFReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/GhostscriptTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/GhostscriptTest.cpp index 411a3b5cb8..b7ea3fc2ef 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/GhostscriptTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/GhostscriptTest.cpp @@ -2,7 +2,7 @@ ** GhostscriptTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathParserTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathParserTest.cpp index 3d94790fdc..ef9cb1c69e 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathParserTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathParserTest.cpp @@ -2,7 +2,7 @@ ** GraphicsPathParserTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathTest.cpp index ff1c12948e..cfc3bc90cd 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathTest.cpp @@ -2,7 +2,7 @@ ** GraphicsPathTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/HashFunctionTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/HashFunctionTest.cpp index 0cac1e9be3..991a8d5475 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/HashFunctionTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/HashFunctionTest.cpp @@ -2,7 +2,7 @@ ** HashFunctionTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/JFMReaderTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/JFMReaderTest.cpp index a4f85b728f..27cebca294 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/JFMReaderTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/JFMReaderTest.cpp @@ -2,7 +2,7 @@ ** JFMReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp index 6ee6c3aab3..376f83b368 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp @@ -2,7 +2,7 @@ ** LengthTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/Makefile.am b/texk/dvisvgm/dvisvgm-src/tests/Makefile.am index 0811c94312..de5098e717 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/Makefile.am +++ b/texk/dvisvgm/dvisvgm-src/tests/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2024 Martin Gieseking +## Copyright (C) 2005-2025 Martin Gieseking ## ## Process this file with automake. @@ -12,6 +12,7 @@ libgtest_la_LDFLAGS = -pthread EXTRA_DIST = gtest/LICENSE \ gtest/include \ gtest/src/gtest.cc \ + gtest/src/gtest-assertion-result.cc \ gtest/src/gtest-death-test.cc \ gtest/src/gtest-filepath.cc \ gtest/src/gtest-internal-inl.h \ diff --git a/texk/dvisvgm/dvisvgm-src/tests/Makefile.in b/texk/dvisvgm/dvisvgm-src/tests/Makefile.in index e46f3e0a9a..a14a3e6b3f 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/Makefile.in +++ b/texk/dvisvgm/dvisvgm-src/tests/Makefile.in @@ -1016,6 +1016,7 @@ libgtest_la_SOURCES = gtest/src/gtest-all.cc testmain.cpp libgtest_la_CPPFLAGS = -I$(dvisvgm_srcdir)/tests/gtest/include -I$(dvisvgm_srcdir)/tests/gtest libgtest_la_LDFLAGS = -pthread EXTRA_DIST = gtest/LICENSE gtest/include gtest/src/gtest.cc \ + gtest/src/gtest-assertion-result.cc \ gtest/src/gtest-death-test.cc gtest/src/gtest-filepath.cc \ gtest/src/gtest-internal-inl.h gtest/src/gtest_main.cc \ gtest/src/gtest-matchers.cc gtest/src/gtest-port.cc \ diff --git a/texk/dvisvgm/dvisvgm-src/tests/MapLineTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/MapLineTest.cpp index 71d035658d..0f3ed3890c 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/MapLineTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/MapLineTest.cpp @@ -2,7 +2,7 @@ ** MapLineTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp index b5a8fdc3fd..45b5013fcb 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp @@ -2,7 +2,7 @@ ** MatrixTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/MessageExceptionTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/MessageExceptionTest.cpp index 8ec162c414..b41b59b75e 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/MessageExceptionTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/MessageExceptionTest.cpp @@ -2,7 +2,7 @@ ** MessageExceptionTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/OFMReaderTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/OFMReaderTest.cpp index 231d411cae..2d366057c2 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/OFMReaderTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/OFMReaderTest.cpp @@ -2,7 +2,7 @@ ** OFMReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/PDFParserTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/PDFParserTest.cpp index feb977f818..5b9a7fbebb 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/PDFParserTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/PDFParserTest.cpp @@ -2,7 +2,7 @@ ** PDFParserTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/PSInterpreterTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/PSInterpreterTest.cpp index 28c75a7451..a54dd90d5b 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/PSInterpreterTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/PSInterpreterTest.cpp @@ -2,7 +2,7 @@ ** PSInterpreterTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/PageRagesTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/PageRagesTest.cpp index 8e1b3f4514..4e0b20c22c 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/PageRagesTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/PageRagesTest.cpp @@ -2,7 +2,7 @@ ** PageRagesTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/PageSizeTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/PageSizeTest.cpp index d53af5196c..0040e5c6cc 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/PageSizeTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/PageSizeTest.cpp @@ -2,7 +2,7 @@ ** PageSizeTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp index 7aac710db8..5925804a29 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp @@ -2,7 +2,7 @@ ** PairTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/PapersizeSpecialTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/PapersizeSpecialTest.cpp index 41e31889d5..f4ff159b9e 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/PapersizeSpecialTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/PapersizeSpecialTest.cpp @@ -2,7 +2,7 @@ ** PapersizeSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/RangeMapTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/RangeMapTest.cpp index 1409071bd4..8e85c915eb 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/RangeMapTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/RangeMapTest.cpp @@ -2,7 +2,7 @@ ** RangeMapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/SVGOutputTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/SVGOutputTest.cpp index ee3f8b984a..57178af006 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/SVGOutputTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/SVGOutputTest.cpp @@ -2,7 +2,7 @@ ** SVGOutputTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/ShadingPatchTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/ShadingPatchTest.cpp index 31ed9cd5c1..92eca93a9d 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/ShadingPatchTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/ShadingPatchTest.cpp @@ -2,7 +2,7 @@ ** ShadingPatchTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -51,7 +51,7 @@ TEST(ShadingPatchTest, colorQueryFuncs) { colors[0].setRGB(1.0, 0.0, 0.0); colors[1].setRGB(0.0, 1.0, 0.0); colors[2].setRGB(0.0, 0.0, 1.0); - TriangularPatch tp1(points, colors, Color::ColorSpace::RGB, 0, 0); + TriangularPatch tp1(points, colors, Color::ColorSpace::RGB, 0, nullptr); EXPECT_EQ(tp1.colorAt(0, 0).rgbString(), "#f00"); EXPECT_EQ(tp1.colorAt(1, 0).rgbString(), "#0f0"); EXPECT_EQ(tp1.colorAt(0, 1).rgbString(), "#00f"); @@ -59,7 +59,7 @@ TEST(ShadingPatchTest, colorQueryFuncs) { colors[0].setGray(0.2); colors[1].setGray(0.4); colors[2].setGray(0.6); - TriangularPatch tp2(points, colors, Color::ColorSpace::GRAY, 0, 0); + TriangularPatch tp2(points, colors, Color::ColorSpace::GRAY, 0, nullptr); EXPECT_EQ(tp2.colorAt(0, 0).rgbString(), "#333"); EXPECT_EQ(tp2.colorAt(1, 0).rgbString(), "#666"); EXPECT_EQ(tp2.colorAt(0, 1).rgbString(), "#999"); @@ -67,16 +67,16 @@ TEST(ShadingPatchTest, colorQueryFuncs) { colors[0].setCMYK(1.0, 0.0, 0.0, 0.2); colors[1].setCMYK(0.0, 1.0, 0.0, 0.4); colors[2].setCMYK(0.0, 0.0, 1.0, 0.6); - TriangularPatch tp3(points, colors, Color::ColorSpace::CMYK, 0, 0); - EXPECT_EQ(tp3.colorAt(0, 0).rgbString(), "#29cccc"); - EXPECT_EQ(tp3.colorAt(1, 0).rgbString(), "#993d99"); - EXPECT_EQ(tp3.colorAt(0, 1).rgbString(), "#66663d"); + TriangularPatch tp3(points, colors, Color::ColorSpace::CMYK, 0, nullptr); + EXPECT_EQ(tp3.colorAt(0, 0).rgbString(), "#0092c9"); + EXPECT_EQ(tp3.colorAt(1, 0).rgbString(), "#9e005e"); + EXPECT_EQ(tp3.colorAt(0, 1).rgbString(), "#827a00"); colors[0].setLab(55, 80, 68); colors[1].setLab(30, 62, -108); colors[2].setLab(85, -72, 61); - TriangularPatch tp4(points, colors, Color::ColorSpace::LAB, 0, 0); - EXPECT_EQ(tp4.colorAt(0, 0).rgbString(), "#ff1402"); - EXPECT_EQ(tp4.colorAt(1, 0).rgbString(), "#002bf8"); - EXPECT_EQ(tp4.colorAt(0, 1).rgbString(), "#4af356"); + TriangularPatch tp4(points, colors, Color::ColorSpace::LAB, 0, nullptr); + EXPECT_EQ(tp4.colorAt(0, 0).rgbString(), "#040404"); + EXPECT_EQ(tp4.colorAt(1, 0).rgbString(), "#020000"); + EXPECT_EQ(tp4.colorAt(0, 1).rgbString(), "#040000"); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/SpecialManagerTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/SpecialManagerTest.cpp index 99439feb85..bff0226ee2 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/SpecialManagerTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/SpecialManagerTest.cpp @@ -2,7 +2,7 @@ ** SpecialManagerTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/SplittedCharInputBufferTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/SplittedCharInputBufferTest.cpp index 7ad96f2ed8..5229492204 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/SplittedCharInputBufferTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/SplittedCharInputBufferTest.cpp @@ -2,7 +2,7 @@ ** SplittedCharInputBufferTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/StreamInputBufferTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/StreamInputBufferTest.cpp index bbc03c7f3d..2f358430d8 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/StreamInputBufferTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/StreamInputBufferTest.cpp @@ -2,7 +2,7 @@ ** StreamInputBufferTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -43,6 +43,27 @@ TEST(StreamInputBufferTest, get) { } +TEST(StreamInputBufferTest, read) { + istringstream iss("abcdefghijklmnopqrst"); + StreamInputReader ir(iss); + char buf[10]; + auto count = ir.read(buf, 9); + ASSERT_EQ(count, 9); + buf[count] = 0; + EXPECT_EQ(string(buf), "abcdefghi"); + + count = ir.read(buf, 9); + ASSERT_EQ(count, 9); + buf[count] = 0; + EXPECT_EQ(string(buf), "jklmnopqr"); + + count = ir.read(buf, 9); + ASSERT_EQ(count, 2); + buf[count] = 0; + EXPECT_EQ(string(buf), "st"); +} + + TEST(StreamInputBufferTest, peek) { istringstream iss("abcdefghijklmnopqrstuvwxyz"); StreamInputBuffer buffer(iss, 10); diff --git a/texk/dvisvgm/dvisvgm-src/tests/StreamReaderTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/StreamReaderTest.cpp index 01ab6f4a1c..fe48ff0c99 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/StreamReaderTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/StreamReaderTest.cpp @@ -2,7 +2,7 @@ ** StreamReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/StreamWriterTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/StreamWriterTest.cpp index a16fbfc6f4..420029f3cc 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/StreamWriterTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/StreamWriterTest.cpp @@ -2,7 +2,7 @@ ** StreamWriterTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/StringMatcherTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/StringMatcherTest.cpp index b15ec1ff9b..146ed5617e 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/StringMatcherTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/StringMatcherTest.cpp @@ -2,7 +2,7 @@ ** StringMatcherTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/SubfontTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/SubfontTest.cpp index b9dd448ac7..3cb453605b 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/SubfontTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/SubfontTest.cpp @@ -2,7 +2,7 @@ ** SubfontTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/TFMReaderTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/TFMReaderTest.cpp index 3e6b9011e4..9fc6b3287f 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/TFMReaderTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/TFMReaderTest.cpp @@ -2,7 +2,7 @@ ** TFMReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/TensorProductPatchTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/TensorProductPatchTest.cpp index accff638bb..b489da8cda 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/TensorProductPatchTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/TensorProductPatchTest.cpp @@ -2,7 +2,7 @@ ** TensorProductPatchTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -68,7 +68,7 @@ class TensorProductPatchTest : public ::testing::Test { _points[13] = DPair(40, 80); _points[14] = DPair(60, 70); _points[15] = DPair(40, 40); - _patch.setPoints(_points, 0, 0); + _patch.setPoints(_points, 0, nullptr); vector colors(4); colors[0].setRGB(1.0, 0.0, 0.0); @@ -136,40 +136,34 @@ TEST_F(TensorProductPatchTest, valueAt) { EXPECT_EQ(tpp3.valueAt(1, 1), DPair(20, 40)); colors.resize(4); - CoonsPatch cp1(points, colors, Color::ColorSpace::RGB, 0, 0); - EXPECT_EQ(cp1.valueAt(0, 0), DPair(10, 70)); - EXPECT_EQ(cp1.valueAt(0, 1), DPair(10, 10)); - EXPECT_EQ(cp1.valueAt(1, 0), DPair(100, 70)); - EXPECT_EQ(cp1.valueAt(1, 1), DPair(70, 20)); + CoonsPatch cp1(points, colors, Color::ColorSpace::RGB, 0, nullptr); + EXPECT_EQ(cp1.valueAt(0, 0), DPair(10, 10)); + EXPECT_EQ(cp1.valueAt(0, 1), DPair(10, 70)); + EXPECT_EQ(cp1.valueAt(1, 0), DPair(70, 20)); + EXPECT_EQ(cp1.valueAt(1, 1), DPair(100, 70)); points.resize(8); colors.resize(2); CoonsPatch cp2(points, colors, Color::ColorSpace::RGB, 1, &cp1); - EXPECT_EQ(cp2.valueAt(0, 0), DPair(100, 70)); - EXPECT_EQ(cp2.valueAt(0, 1), DPair(10, 70)); - EXPECT_EQ(cp2.valueAt(1, 0), DPair(20, 40)); - EXPECT_EQ(cp2.valueAt(1, 1), DPair(70, 100)); + EXPECT_EQ(cp2.valueAt(0, 0), DPair(10, 70)); + EXPECT_EQ(cp2.valueAt(0, 1), DPair(100, 70)); + EXPECT_EQ(cp2.valueAt(1, 0), DPair(70, 100)); + EXPECT_EQ(cp2.valueAt(1, 1), DPair(20, 40)); CoonsPatch cp3(points, colors, Color::ColorSpace::RGB, 2, &cp1); - EXPECT_EQ(cp3.valueAt(0, 0), DPair(70, 20)); - EXPECT_EQ(cp3.valueAt(0, 1), DPair(100, 70)); - EXPECT_EQ(cp3.valueAt(1, 0), DPair(20, 40)); - EXPECT_EQ(cp3.valueAt(1, 1), DPair(70, 100)); + EXPECT_EQ(cp3.valueAt(0, 0), DPair(100, 70)); + EXPECT_EQ(cp3.valueAt(0, 1), DPair(70, 20)); + EXPECT_EQ(cp3.valueAt(1, 0), DPair(70, 100)); + EXPECT_EQ(cp3.valueAt(1, 1), DPair(20, 40)); CoonsPatch cp4(points, colors, Color::ColorSpace::RGB, 3, &cp1); - EXPECT_EQ(cp4.valueAt(0, 0), DPair(10, 10)); - EXPECT_EQ(cp4.valueAt(0, 1), DPair(70, 20)); - EXPECT_EQ(cp4.valueAt(1, 0), DPair(20, 40)); - EXPECT_EQ(cp4.valueAt(1, 1), DPair(70, 100)); + EXPECT_EQ(cp4.valueAt(0, 0), DPair(70, 20)); + EXPECT_EQ(cp4.valueAt(0, 1), DPair(10, 10)); + EXPECT_EQ(cp4.valueAt(1, 0), DPair(70, 100)); + EXPECT_EQ(cp4.valueAt(1, 1), DPair(20, 40)); } -TEST_F(TensorProductPatchTest, averageColor) { - EXPECT_EQ(_patch.averageColor().rgbString(), "#bf8040"); -} - - - TEST_F(TensorProductPatchTest, vertices) { EXPECT_EQ(_patch.valueAt(0,0), DPair(10,10)); EXPECT_EQ(_patch.valueAt(0,1), DPair(10,70)); @@ -185,13 +179,13 @@ TEST_F(TensorProductPatchTest, vertices) { TEST_F(TensorProductPatchTest, curves) { CubicBezier bezier; - _patch.horizontalCurve(0, bezier); + bezier = _patch.horizontalCurve(0); CHECK_BEZIER_POINTS("A", bezier, DPair(10, 10), DPair(20, 0), DPair(50, 30), DPair(70, 20)); - _patch.horizontalCurve(1, bezier); + bezier = _patch.horizontalCurve(1); CHECK_BEZIER_POINTS("B", bezier, DPair(10, 70), DPair(20, 100), DPair(70, 100), DPair(100, 70)); - _patch.verticalCurve(0, bezier); + bezier = _patch.verticalCurve(0); CHECK_BEZIER_POINTS("C", bezier, DPair(10, 10), DPair(0, 30), DPair(20, 40), DPair(10, 70)); - _patch.verticalCurve(1, bezier); + bezier = _patch.verticalCurve(1); CHECK_BEZIER_POINTS("D", bezier, DPair(70, 20), DPair(80, 50), DPair(90, 60), DPair(100, 70)); } @@ -267,7 +261,7 @@ TEST_F(TensorProductPatchTest, bbox) { class Callback : public ShadingPatch::Callback { public: - void patchSegment (GraphicsPath &path, const Color &color) { + void patchSegment (GraphicsPath &path, const Color &color) override { ostringstream oss; path.writeSVG(oss, false); _pathstr += oss.str(); @@ -286,10 +280,15 @@ class Callback : public ShadingPatch::Callback { TEST_F(TensorProductPatchTest, approximate) { Callback callback; vector colors(4); - TensorProductPatch tpp(_points, colors, Color::ColorSpace::RGB, 0, 0); + TensorProductPatch tpp(_points, colors, Color::ColorSpace::RGB, 0, nullptr); tpp.approximate(2, false, 0.1, callback); - EXPECT_EQ(callback.pathstr(), "M10 10C20 0 50 30 70 20C80 50 90 60 100 70C70 100 20 100 10 70C20 40 0 30 10 10Z"); - EXPECT_EQ(callback.colorstr(), "#000"); + EXPECT_EQ(callback.pathstr(), + "M10 10C15 5 25 10 36.25 15C36.25 27.5 40 40.9375 43.28125 54.21875C31.25 52.1875 20.625 46.875 10 36.25" + "C7.5 27.5 5 20 10 10ZM36.25 15C47.5 20 60 25 70 20C75 35 80 45 85 52.5C68.75 55 55.3125 56.25 43.28125 54.21875" + "C40 40.9375 36.25 27.5 36.25 15ZM10 36.25C20.625 46.875 31.25 52.1875 43.28125 54.21875C46.5625 67.5 49.375 80.625 47.5 92.5" + "C30 92.5 15 85 10 70C15 55 12.5 45 10 36.25ZM43.28125 54.21875C55.3125 56.25 68.75 55 85 52.5C90 60 95 65 100 70" + "C85 85 65 92.5 47.5 92.5C49.375 80.625 46.5625 67.5 43.28125 54.21875Z"); + EXPECT_EQ(callback.colorstr(), "#000#000#000#000"); callback.reset(); _patch.approximate(2, false, 0.1, callback); @@ -299,33 +298,32 @@ TEST_F(TensorProductPatchTest, approximate) { "M36.25 15C47.5 20 60 25 70 20C75 35 80 45 85 52.5C68.75 55 55.3125 56.25 43.28125 54.21875C40 40.9375 36.25 27.5 36.25 15Z" "M10 36.25C20.625 46.875 31.25 52.1875 43.28125 54.21875C46.5625 67.5 49.375 80.625 47.5 92.5C30 92.5 15 85 10 70C15 55 12.5 45 10 36.25Z" "M43.28125 54.21875C55.3125 56.25 68.75 55 85 52.5C90 60 95 65 100 70C85 85 65 92.5 47.5 92.5C49.375 80.625 46.5625 67.5 43.28125 54.21875Z"); - EXPECT_EQ(callback.colorstr(), "#cf6010#70a030#efa030#cf6090"); + EXPECT_EQ(callback.colorstr(), "#cf6010#709f30#ef9f30#cf608f"); } - TEST_F(TensorProductPatchTest, fail) { // edge flag == 0 vector points(15); - EXPECT_THROW(_patch.setPoints(points, 0, 0), ShadingException); + EXPECT_THROW(_patch.setPoints(points, 0, nullptr), ShadingException); points.resize(17); // too many points - EXPECT_THROW(_patch.setPoints(points, 0, 0), ShadingException); + EXPECT_THROW(_patch.setPoints(points, 0, nullptr), ShadingException); vector colors(2); // too few colors - EXPECT_THROW(_patch.setColors(colors, 0, 0), ShadingException); + EXPECT_THROW(_patch.setColors(colors, 0, nullptr), ShadingException); colors.resize(5); // too many colors - EXPECT_THROW(_patch.setColors(colors, 0, 0), ShadingException); + EXPECT_THROW(_patch.setColors(colors, 0, nullptr), ShadingException); // edge flag > 0 points.resize(16); - EXPECT_THROW(_patch.setPoints(points, 1, 0), ShadingException); + EXPECT_THROW(_patch.setPoints(points, 1, nullptr), ShadingException); points.resize(11); // too few points EXPECT_THROW(_patch.setPoints(points, 1, &_patch), ShadingException); points.resize(13); // too many points EXPECT_THROW(_patch.setPoints(points, 1, &_patch), ShadingException); colors.resize(4); - EXPECT_THROW(_patch.setColors(colors, 1, 0), ShadingException); + EXPECT_THROW(_patch.setColors(colors, 1, nullptr), ShadingException); colors.resize(1); // too few colors EXPECT_THROW(_patch.setColors(colors, 1, &_patch), ShadingException); colors.resize(3); // too many colors @@ -333,11 +331,11 @@ TEST_F(TensorProductPatchTest, fail) { CoonsPatch cp; points.resize(8); - EXPECT_THROW(cp.setPoints(points, 1, 0), ShadingException); + EXPECT_THROW(cp.setPoints(points, 1, nullptr), ShadingException); points.resize(11); - EXPECT_THROW(cp.setPoints(points, 0, 0), ShadingException); + EXPECT_THROW(cp.setPoints(points, 0, nullptr), ShadingException); colors.resize(2); - EXPECT_THROW(cp.setColors(colors, 1, 0), ShadingException); + EXPECT_THROW(cp.setColors(colors, 1, nullptr), ShadingException); colors.resize(5); - EXPECT_THROW(cp.setColors(colors, 0, 0), ShadingException); + EXPECT_THROW(cp.setColors(colors, 0, nullptr), ShadingException); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/ToUnicodeMapTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/ToUnicodeMapTest.cpp index f0eee80dc9..310e1a7f8d 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/ToUnicodeMapTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/ToUnicodeMapTest.cpp @@ -2,7 +2,7 @@ ** ToUnicodeMapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/TpicSpecialTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/TpicSpecialTest.cpp index 66cccbd379..28baff8e78 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/TpicSpecialTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/TpicSpecialTest.cpp @@ -2,7 +2,7 @@ ** TpicSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -39,8 +39,8 @@ class TpicSpecialTest : public ::testing::Test { void setY (double yy) override {x = yy;} double getX () const override {return x;} double getY () const override {return y;} - Color getColor () const override {return color;} - void setColor (const Color &c) override {color = c;} + Color getFillColor () const override {return color;} + void setFillColor (const Color &c) override {color = c;} const Matrix& getMatrix () const override {static Matrix m(1); return m;} string getXMLSnippet () const { diff --git a/texk/dvisvgm/dvisvgm-src/tests/TriangularPatchTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/TriangularPatchTest.cpp index 6ed87f5d7e..c1d78e72ab 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/TriangularPatchTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/TriangularPatchTest.cpp @@ -2,7 +2,7 @@ ** TriangularPatchTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -105,17 +105,6 @@ TEST(TriangularPatchTest, colorAt) { } -TEST(TriangularPatchTest, averageColor) { - vector points(3); - vector colors(3); - colors[0] = Color(1.0, 0.0, 0.0); - colors[1] = Color(0.0, 1.0, 0.0); - colors[2] = Color(0.0, 0.0, 1.0); - TriangularPatch tp(points, colors, Color::ColorSpace::RGB, 0, 0); - EXPECT_EQ(tp.averageColor(), Color(uint8_t(85), uint8_t(85), uint8_t(85))); -} - - TEST(TriangularPatchTest, bbox) { vector points(3); points[0] = DPair(0, 0); diff --git a/texk/dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp index cad32eee52..a9fc41fe79 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp @@ -2,7 +2,7 @@ ** UnicodeTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/UtilityTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/UtilityTest.cpp index 8a1d138d8f..68fd4afb62 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/UtilityTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/UtilityTest.cpp @@ -2,7 +2,7 @@ ** UtilityTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/VectorIteratorTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/VectorIteratorTest.cpp index cbe02e2658..bae6a0d655 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/VectorIteratorTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/VectorIteratorTest.cpp @@ -2,7 +2,7 @@ ** VectorIteratorTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp index 33105fd37f..76e14ce06f 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp @@ -2,7 +2,7 @@ ** XMLNodeTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/XMLStringTest.cpp b/texk/dvisvgm/dvisvgm-src/tests/XMLStringTest.cpp index 09758dc9e4..0e7c33638a 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/XMLStringTest.cpp +++ b/texk/dvisvgm/dvisvgm-src/tests/XMLStringTest.cpp @@ -2,7 +2,7 @@ ** XMLStringTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2024 Martin Gieseking ** +** Copyright (C) 2005-2025 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/texk/dvisvgm/dvisvgm-src/tests/check-conv b/texk/dvisvgm/dvisvgm-src/tests/check-conv index 5c352e68f1..6c6a127375 100755 --- a/texk/dvisvgm/dvisvgm-src/tests/check-conv +++ b/texk/dvisvgm/dvisvgm-src/tests/check-conv @@ -2,7 +2,7 @@ # This file is part of the dvisvgm package and published under the # terms of the GNU General Public License version 3 or later. # See file COPYING for further details. -# Copyright (C) 2009-2024 Martin Gieseking +# Copyright (C) 2009-2025 Martin Gieseking files=(sample frktest) diff --git a/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.am b/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.am index 60e79bca81..d13a6961f4 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.am +++ b/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2016-2024 Martin Gieseking +## Copyright (C) 2016-2025 Martin Gieseking ## ## Process this file with automake. diff --git a/texk/dvisvgm/dvisvgm-src/tests/genhashcheck.py b/texk/dvisvgm/dvisvgm-src/tests/genhashcheck.py index e94fa1b657..0f67862288 100755 --- a/texk/dvisvgm/dvisvgm-src/tests/genhashcheck.py +++ b/texk/dvisvgm/dvisvgm-src/tests/genhashcheck.py @@ -2,7 +2,7 @@ # This file is part of the dvisvgm package and published under the # terms of the GNU General Public License version 3 or later. # See file COPYING for further details. -# Copyright (C) 2016-2024 Martin Gieseking +# Copyright (C) 2016-2025 Martin Gieseking import re import sys diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-assertion-result.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-assertion-result.h new file mode 100644 index 0000000000..addbb59c64 --- /dev/null +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-assertion-result.h @@ -0,0 +1,237 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This file implements the AssertionResult type. + +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* + +#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ +#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ + +#include +#include +#include +#include + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-port.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + +// C4800 is a level 3 warning in Visual Studio 2015 and earlier. +// This warning is not emitted in Visual Studio 2017. +// This warning is off by default starting in Visual Studio 2019 but can be +// enabled with command-line options. +#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) +#endif + + // Used in the EXPECT_TRUE/FALSE(bool_expression). + // + // T must be contextually convertible to bool. + // + // The second parameter prevents this overload from being considered if + // the argument is implicitly convertible to AssertionResult. In that case + // we want AssertionResult's copy constructor to be used. + template + explicit AssertionResult( + const T& success, + typename std::enable_if< + !std::is_convertible::value>::type* + /*enabler*/ + = nullptr) + : success_(success) {} + +#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) + GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif + + // Assignment operator. + AssertionResult& operator=(AssertionResult other) { + swap(other); + return *this; + } + + // Returns true if and only if the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != nullptr ? message_->c_str() : ""; + } + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template + AssertionResult& operator<<(const T& value) { + AppendMessage(Message() << value); + return *this; + } + + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { + AppendMessage(Message() << basic_manipulator); + return *this; + } + + private: + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) { + if (message_.get() == nullptr) message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } + + // Swap the contents of this AssertionResult with other. + void swap(AssertionResult& other); + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + std::unique_ptr< ::std::string> message_; +}; + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-death-test.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-death-test.h index 9b4d4d1337..84e5a5bbd3 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-death-test.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-death-test.h @@ -27,21 +27,21 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// // The Google C++ Testing and Mocking Framework (Google Test) // // This header file defines the public API for death tests. It is // #included by gtest.h so a user doesn't need to include this // directly. -// GOOGLETEST_CM0001 DO NOT DELETE + +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #include "gtest/internal/gtest-death-test-internal.h" -namespace testing { - // This flag controls the style of death tests. Valid values are "threadsafe", // meaning that the death test child process will re-execute the test binary // from the start, running only a single death test, or "fast", @@ -49,6 +49,8 @@ namespace testing { // after forking. GTEST_DECLARE_string_(death_test_style); +namespace testing { + #if GTEST_HAS_DEATH_TEST namespace internal { @@ -103,7 +105,6 @@ GTEST_API_ bool InDeathTestChild(); // // On the regular expressions used in death tests: // -// GOOGLETEST_CM0005 DO NOT DELETE // On POSIX-compliant systems (*nix), we use the library, // which uses the POSIX extended regex syntax. // @@ -169,24 +170,24 @@ GTEST_API_ bool InDeathTestChild(); // Asserts that a given `statement` causes the program to exit, with an // integer exit status that satisfies `predicate`, and emitting error output // that matches `matcher`. -# define ASSERT_EXIT(statement, predicate, matcher) \ - GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_) +#define ASSERT_EXIT(statement, predicate, matcher) \ + GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_) // Like `ASSERT_EXIT`, but continues on to successive tests in the // test suite, if any: -# define EXPECT_EXIT(statement, predicate, matcher) \ - GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_) +#define EXPECT_EXIT(statement, predicate, matcher) \ + GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_) // Asserts that a given `statement` causes the program to exit, either by // explicitly exiting with a nonzero exit code or being killed by a // signal, and emitting error output that matches `matcher`. -# define ASSERT_DEATH(statement, matcher) \ - ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher) +#define ASSERT_DEATH(statement, matcher) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher) // Like `ASSERT_DEATH`, but continues on to successive tests in the // test suite, if any: -# define EXPECT_DEATH(statement, matcher) \ - EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher) +#define EXPECT_DEATH(statement, matcher) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher) // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: @@ -197,22 +198,23 @@ class GTEST_API_ ExitedWithCode { ExitedWithCode(const ExitedWithCode&) = default; void operator=(const ExitedWithCode& other) = delete; bool operator()(int exit_status) const; + private: const int exit_code_; }; -# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA // Tests that an exit code describes an exit due to termination by a // given signal. -// GOOGLETEST_CM0006 DO NOT DELETE class GTEST_API_ KilledBySignal { public: explicit KilledBySignal(int signum); bool operator()(int exit_status) const; + private: const int signum_; }; -# endif // !GTEST_OS_WINDOWS +#endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, @@ -257,23 +259,21 @@ class GTEST_API_ KilledBySignal { // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // }, "death"); // -# ifdef NDEBUG +#ifdef NDEBUG -# define EXPECT_DEBUG_DEATH(statement, regex) \ +#define EXPECT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) -# define ASSERT_DEBUG_DEATH(statement, regex) \ +#define ASSERT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) -# else +#else -# define EXPECT_DEBUG_DEATH(statement, regex) \ - EXPECT_DEATH(statement, regex) +#define EXPECT_DEBUG_DEATH(statement, regex) EXPECT_DEATH(statement, regex) -# define ASSERT_DEBUG_DEATH(statement, regex) \ - ASSERT_DEATH(statement, regex) +#define ASSERT_DEBUG_DEATH(statement, regex) ASSERT_DEATH(statement, regex) -# endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST // This macro is used for implementing macros such as @@ -311,18 +311,17 @@ class GTEST_API_ KilledBySignal { // statement unconditionally returns or throws. The Message constructor at // the end allows the syntax of streaming additional messages into the // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. -# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - GTEST_LOG_(WARNING) \ - << "Death tests are not supported on this platform.\n" \ - << "Statement '" #statement "' cannot be verified."; \ - } else if (::testing::internal::AlwaysFalse()) { \ - ::testing::internal::RE::PartialMatch(".*", (regex)); \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - terminator; \ - } else \ - ::testing::Message() +#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if @@ -330,15 +329,15 @@ class GTEST_API_ KilledBySignal { // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST -# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - EXPECT_DEATH(statement, regex) -# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - ASSERT_DEATH(statement, regex) +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) #else -# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, ) -# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return) +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, ) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return) #endif } // namespace testing diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-matchers.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-matchers.h index 9fa34a05ba..bffa00c533 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-matchers.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-matchers.h @@ -32,6 +32,10 @@ // This file implements just enough of the matcher interface to allow // EXPECT_DEATH and friends to accept a matcher argument. +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* + #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ @@ -98,11 +102,11 @@ class MatchResultListener { private: ::std::ostream* const stream_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); + MatchResultListener(const MatchResultListener&) = delete; + MatchResultListener& operator=(const MatchResultListener&) = delete; }; -inline MatchResultListener::~MatchResultListener() { -} +inline MatchResultListener::~MatchResultListener() {} // An instance of a subclass of this knows how to describe itself as a // matcher. @@ -176,27 +180,39 @@ namespace internal { struct AnyEq { template - bool operator()(const A& a, const B& b) const { return a == b; } + bool operator()(const A& a, const B& b) const { + return a == b; + } }; struct AnyNe { template - bool operator()(const A& a, const B& b) const { return a != b; } + bool operator()(const A& a, const B& b) const { + return a != b; + } }; struct AnyLt { template - bool operator()(const A& a, const B& b) const { return a < b; } + bool operator()(const A& a, const B& b) const { + return a < b; + } }; struct AnyGt { template - bool operator()(const A& a, const B& b) const { return a > b; } + bool operator()(const A& a, const B& b) const { + return a > b; + } }; struct AnyLe { template - bool operator()(const A& a, const B& b) const { return a <= b; } + bool operator()(const A& a, const B& b) const { + return a <= b; + } }; struct AnyGe { template - bool operator()(const A& a, const B& b) const { return a >= b; } + bool operator()(const A& a, const B& b) const { + return a >= b; + } }; // A match result listener that ignores the explanation. @@ -205,7 +221,8 @@ class DummyMatchResultListener : public MatchResultListener { DummyMatchResultListener() : MatchResultListener(nullptr) {} private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener); + DummyMatchResultListener(const DummyMatchResultListener&) = delete; + DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete; }; // A match result listener that forwards the explanation to a given @@ -217,7 +234,9 @@ class StreamMatchResultListener : public MatchResultListener { : MatchResultListener(os) {} private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener); + StreamMatchResultListener(const StreamMatchResultListener&) = delete; + StreamMatchResultListener& operator=(const StreamMatchResultListener&) = + delete; }; struct SharedPayloadBase { @@ -284,17 +303,18 @@ class MatcherBase : private MatcherDescriberInterface { } protected: - MatcherBase() : vtable_(nullptr) {} + MatcherBase() : vtable_(nullptr), buffer_() {} // Constructs a matcher from its implementation. template - explicit MatcherBase(const MatcherInterface* impl) { + explicit MatcherBase(const MatcherInterface* impl) + : vtable_(nullptr), buffer_() { Init(impl); } template ::type::is_gtest_matcher> - MatcherBase(M&& m) { // NOLINT + MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT Init(std::forward(m)); } @@ -420,8 +440,8 @@ class MatcherBase : private MatcherDescriberInterface { static const M& Get(const MatcherBase& m) { // When inlined along with Init, need to be explicit to avoid violating // strict aliasing rules. - const M *ptr = static_cast( - static_cast(&m.buffer_)); + const M* ptr = + static_cast(static_cast(&m.buffer_)); return *ptr; } static void Init(MatcherBase& m, M impl) { @@ -741,7 +761,7 @@ template class EqMatcher : public ComparisonBase, Rhs, AnyEq> { public: explicit EqMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyEq>(rhs) { } + : ComparisonBase, Rhs, AnyEq>(rhs) {} static const char* Desc() { return "is equal to"; } static const char* NegatedDesc() { return "isn't equal to"; } }; @@ -749,7 +769,7 @@ template class NeMatcher : public ComparisonBase, Rhs, AnyNe> { public: explicit NeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyNe>(rhs) { } + : ComparisonBase, Rhs, AnyNe>(rhs) {} static const char* Desc() { return "isn't equal to"; } static const char* NegatedDesc() { return "is equal to"; } }; @@ -757,7 +777,7 @@ template class LtMatcher : public ComparisonBase, Rhs, AnyLt> { public: explicit LtMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyLt>(rhs) { } + : ComparisonBase, Rhs, AnyLt>(rhs) {} static const char* Desc() { return "is <"; } static const char* NegatedDesc() { return "isn't <"; } }; @@ -765,7 +785,7 @@ template class GtMatcher : public ComparisonBase, Rhs, AnyGt> { public: explicit GtMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyGt>(rhs) { } + : ComparisonBase, Rhs, AnyGt>(rhs) {} static const char* Desc() { return "is >"; } static const char* NegatedDesc() { return "isn't >"; } }; @@ -773,7 +793,7 @@ template class LeMatcher : public ComparisonBase, Rhs, AnyLe> { public: explicit LeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyLe>(rhs) { } + : ComparisonBase, Rhs, AnyLe>(rhs) {} static const char* Desc() { return "is <="; } static const char* NegatedDesc() { return "isn't <="; } }; @@ -781,7 +801,7 @@ template class GeMatcher : public ComparisonBase, Rhs, AnyGe> { public: explicit GeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyGe>(rhs) { } + : ComparisonBase, Rhs, AnyGe>(rhs) {} static const char* Desc() { return "is >="; } static const char* NegatedDesc() { return "isn't >="; } }; @@ -872,12 +892,16 @@ PolymorphicMatcher ContainsRegex( // Note: if the parameter of Eq() were declared as const T&, Eq("foo") // wouldn't compile. template -inline internal::EqMatcher Eq(T x) { return internal::EqMatcher(x); } +inline internal::EqMatcher Eq(T x) { + return internal::EqMatcher(x); +} // Constructs a Matcher from a 'value' of type T. The constructed // matcher matches any value that's equal to 'value'. template -Matcher::Matcher(T value) { *this = Eq(value); } +Matcher::Matcher(T value) { + *this = Eq(value); +} // Creates a monomorphic matcher that matches anything with type Lhs // and equal to rhs. A user may need to use this instead of Eq(...) @@ -892,7 +916,9 @@ Matcher::Matcher(T value) { *this = Eq(value); } // can always write Matcher(Lt(5)) to be explicit about the type, // for example. template -inline Matcher TypedEq(const Rhs& rhs) { return Eq(rhs); } +inline Matcher TypedEq(const Rhs& rhs) { + return Eq(rhs); +} // Creates a polymorphic matcher that matches anything >= x. template diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-message.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-message.h index becfd49fcb..6c8bf90009 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-message.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-message.h @@ -27,7 +27,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// // The Google C++ Testing and Mocking Framework (Google Test) // // This header file defines the Message class. @@ -42,7 +41,9 @@ // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ @@ -110,8 +111,8 @@ class GTEST_API_ Message { // Streams a non-pointer value to this object. template - inline Message& operator <<(const T& val) { - // Some libraries overload << for STL containers. These + inline Message& operator<<(const T& val) { + // Some libraries overload << for STL containers. These // overloads are defined in the global namespace instead of ::std. // // C++'s symbol lookup rule (i.e. Koenig lookup) says that these @@ -125,7 +126,7 @@ class GTEST_API_ Message { // from the global namespace. With this using declaration, // overloads of << defined in the global namespace and those // visible via Koenig lookup are both exposed in this function. - using ::operator <<; + using ::operator<<; *ss_ << val; return *this; } @@ -144,7 +145,7 @@ class GTEST_API_ Message { // ensure consistent result across compilers, we always treat NULL // as "(null)". template - inline Message& operator <<(T* const& pointer) { // NOLINT + inline Message& operator<<(T* const& pointer) { // NOLINT if (pointer == nullptr) { *ss_ << "(null)"; } else { @@ -159,25 +160,23 @@ class GTEST_API_ Message { // templatized version above. Without this definition, streaming // endl or other basic IO manipulators to Message will confuse the // compiler. - Message& operator <<(BasicNarrowIoManip val) { + Message& operator<<(BasicNarrowIoManip val) { *ss_ << val; return *this; } // Instead of 1/0, we want to see true/false for bool values. - Message& operator <<(bool b) { - return *this << (b ? "true" : "false"); - } + Message& operator<<(bool b) { return *this << (b ? "true" : "false"); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. - Message& operator <<(const wchar_t* wide_c_str); - Message& operator <<(wchar_t* wide_c_str); + Message& operator<<(const wchar_t* wide_c_str); + Message& operator<<(wchar_t* wide_c_str); #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. - Message& operator <<(const ::std::wstring& wstr); + Message& operator<<(const ::std::wstring& wstr); #endif // GTEST_HAS_STD_WSTRING // Gets the text streamed to this object so far as an std::string. @@ -196,7 +195,7 @@ class GTEST_API_ Message { }; // Streams a Message to an ostream. -inline std::ostream& operator <<(std::ostream& os, const Message& sb) { +inline std::ostream& operator<<(std::ostream& os, const Message& sb) { return os << sb.GetString(); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-param-test.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-param-test.h index 804e702817..b55119ac62 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-param-test.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-param-test.h @@ -26,11 +26,14 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// + // Macros and functions for implementing parameterized tests // in Google C++ Testing and Mocking Framework (Google Test) -// -// GOOGLETEST_CM0001 DO NOT DELETE + +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* + #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ @@ -353,9 +356,7 @@ internal::ValueArray Values(T... v) { // } // INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool()); // -inline internal::ParamGenerator Bool() { - return Values(false, true); -} +inline internal::ParamGenerator Bool() { return Values(false, true); } // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. @@ -428,8 +429,11 @@ internal::CartesianProductHolder Combine(const Generator&... g) { return 0; \ } \ static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name)); \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ + (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \ + const GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name) &) = delete; /* NOLINT */ \ }; \ int GTEST_TEST_CLASS_NAME_(test_suite_name, \ test_name)::gtest_registering_dummy_ = \ @@ -453,43 +457,42 @@ internal::CartesianProductHolder Combine(const Generator&... g) { #define GTEST_GET_FIRST_(first, ...) first #define GTEST_GET_SECOND_(first, second, ...) second -#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \ - static ::testing::internal::ParamGenerator \ - gtest_##prefix##test_suite_name##_EvalGenerator_() { \ - return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ - } \ - static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \ - const ::testing::TestParamInfo& info) { \ - if (::testing::internal::AlwaysFalse()) { \ - ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \ - __VA_ARGS__, \ - ::testing::internal::DefaultParamName, \ - DUMMY_PARAM_))); \ - auto t = std::make_tuple(__VA_ARGS__); \ - static_assert(std::tuple_size::value <= 2, \ - "Too Many Args!"); \ - } \ - return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \ - __VA_ARGS__, \ - ::testing::internal::DefaultParamName, \ - DUMMY_PARAM_))))(info); \ - } \ - static int gtest_##prefix##test_suite_name##_dummy_ \ - GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::UnitTest::GetInstance() \ - ->parameterized_test_registry() \ - .GetTestSuitePatternHolder( \ - GTEST_STRINGIFY_(test_suite_name), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ - ->AddTestSuiteInstantiation( \ - GTEST_STRINGIFY_(prefix), \ - >est_##prefix##test_suite_name##_EvalGenerator_, \ - >est_##prefix##test_suite_name##_EvalGenerateName_, \ +#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \ + static ::testing::internal::ParamGenerator \ + gtest_##prefix##test_suite_name##_EvalGenerator_() { \ + return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ + } \ + static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \ + const ::testing::TestParamInfo& info) { \ + if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \ + __VA_ARGS__, \ + ::testing::internal::DefaultParamName, \ + DUMMY_PARAM_))); \ + auto t = std::make_tuple(__VA_ARGS__); \ + static_assert(std::tuple_size::value <= 2, \ + "Too Many Args!"); \ + } \ + return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \ + __VA_ARGS__, \ + ::testing::internal::DefaultParamName, \ + DUMMY_PARAM_))))(info); \ + } \ + static int gtest_##prefix##test_suite_name##_dummy_ \ + GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::UnitTest::GetInstance() \ + ->parameterized_test_registry() \ + .GetTestSuitePatternHolder( \ + GTEST_STRINGIFY_(test_suite_name), \ + ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ + ->AddTestSuiteInstantiation( \ + GTEST_STRINGIFY_(prefix), \ + >est_##prefix##test_suite_name##_EvalGenerator_, \ + >est_##prefix##test_suite_name##_EvalGenerateName_, \ __FILE__, __LINE__) - // Allow Marking a Parameterized test class as not needing to be instantiated. -#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \ +#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \ namespace gtest_do_not_use_outside_namespace_scope {} \ static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \ GTEST_STRINGIFY_(T)) diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-printers.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-printers.h index 076c9de1f4..a91e8b8b10 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-printers.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-printers.h @@ -27,7 +27,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - // Google Test - The Google C++ Testing and Mocking Framework // // This file implements a universal value printer that can print a @@ -95,7 +94,9 @@ // being defined as many user-defined container types don't have // value_type. -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ @@ -257,12 +258,10 @@ struct ConvertibleToStringViewPrinter { #endif }; - // Prints the given number of bytes in the given object to the given // ostream. GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, - size_t count, - ::std::ostream* os); + size_t count, ::std::ostream* os); struct RawBytesPrinter { // SFINAE on `sizeof` to make sure we have a complete type. template @@ -360,7 +359,7 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); -#ifdef __cpp_char8_t +#ifdef __cpp_lib_char8_t GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t); #endif @@ -375,12 +374,12 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t); // to point to a NUL-terminated string, and thus can print it as a string. #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ - template <> \ - class FormatForComparison { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(value); \ - } \ + template <> \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(value); \ + } \ } GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); @@ -410,8 +409,8 @@ GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template -std::string FormatForComparisonFailureMessage( - const T1& value, const T2& /* other_operand */) { +std::string FormatForComparisonFailureMessage(const T1& value, + const T2& /* other_operand */) { return FormatForComparison::Format(value); } @@ -479,6 +478,12 @@ inline void PrintTo(char8_t c, ::std::ostream* os) { } #endif +// gcc/clang __{u,}int128_t +#if defined(__SIZEOF_INT128__) +GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os); +GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os); +#endif // __SIZEOF_INT128__ + // Overloads for C strings. GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); inline void PrintTo(char* s, ::std::ostream* os) { @@ -545,7 +550,7 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { } // Overloads for ::std::string. -GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); +GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os); inline void PrintTo(const ::std::string& s, ::std::ostream* os) { PrintStringTo(s, os); } @@ -572,7 +577,7 @@ inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) { // Overloads for ::std::wstring. #if GTEST_HAS_STD_WSTRING -GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); +GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os); inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } @@ -587,6 +592,12 @@ inline void PrintTo(internal::StringView sp, ::std::ostream* os) { inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; } +#if GTEST_HAS_RTTI +inline void PrintTo(const std::type_info& info, std::ostream* os) { + *os << internal::GetTypeName(info); +} +#endif // GTEST_HAS_RTTI + template void PrintTo(std::reference_wrapper ref, ::std::ostream* os) { UniversalPrinter::Print(ref.get(), os); @@ -744,6 +755,14 @@ class UniversalPrinter> { } }; +template <> +class UniversalPrinter { + public: + static void Print(decltype(Nullopt()), ::std::ostream* os) { + *os << "(nullopt)"; + } +}; + #endif // GTEST_INTERNAL_HAS_OPTIONAL #if GTEST_INTERNAL_HAS_VARIANT @@ -802,8 +821,8 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { } } // This overload prints a (const) char array compactly. -GTEST_API_ void UniversalPrintArray( - const char* begin, size_t len, ::std::ostream* os); +GTEST_API_ void UniversalPrintArray(const char* begin, size_t len, + ::std::ostream* os); #ifdef __cpp_char8_t // This overload prints a (const) char8_t array compactly. @@ -820,8 +839,8 @@ GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len, ::std::ostream* os); // This overload prints a (const) wchar_t array compactly. -GTEST_API_ void UniversalPrintArray( - const wchar_t* begin, size_t len, ::std::ostream* os); +GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len, + ::std::ostream* os); // Implements printing an array type T[N]. template @@ -980,10 +999,10 @@ void UniversalPrint(const T& value, ::std::ostream* os) { UniversalPrinter::Print(value, os); } -typedef ::std::vector< ::std::string> Strings; +typedef ::std::vector<::std::string> Strings; - // Tersely prints the first N fields of a tuple to a string vector, - // one element for each field. +// Tersely prints the first N fields of a tuple to a string vector, +// one element for each field. template void TersePrintPrefixToStrings(const Tuple&, std::integral_constant, Strings*) {} diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-spi.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-spi.h index eacef44669..bec8c4810b 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-spi.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-spi.h @@ -27,12 +27,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// // Utilities for testing Google Test itself and code that uses Google Test // (e.g. frameworks built on top of Google Test). -// GOOGLETEST_CM0004 DO NOT DELETE - #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ @@ -88,7 +85,10 @@ class GTEST_API_ ScopedFakeTestPartResultReporter TestPartResultReporterInterface* old_reporter_; TestPartResultArray* const result_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); + ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) = + delete; + ScopedFakeTestPartResultReporter& operator=( + const ScopedFakeTestPartResultReporter&) = delete; }; namespace internal { @@ -104,12 +104,14 @@ class GTEST_API_ SingleFailureChecker { SingleFailureChecker(const TestPartResultArray* results, TestPartResult::Type type, const std::string& substr); ~SingleFailureChecker(); + private: const TestPartResultArray* const results_; const TestPartResult::Type type_; const std::string substr_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); + SingleFailureChecker(const SingleFailureChecker&) = delete; + SingleFailureChecker& operator=(const SingleFailureChecker&) = delete; }; } // namespace internal @@ -119,7 +121,8 @@ class GTEST_API_ SingleFailureChecker { GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 // A set of macros for testing Google Test assertions or code that's expected -// to generate Google Test fatal failures. It verifies that the given +// to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but +// not a non-fatal failure, as from EXPECT_EQ). It verifies that the given // statement will cause exactly one fatal Google Test failure with 'substr' // being part of the failure message. // @@ -141,44 +144,46 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 // helper macro, due to some peculiarity in how the preprocessor // works. The AcceptsMacroThatExpandsToUnprotectedComma test in // gtest_unittest.cc will fail to compile if we do that. -#define EXPECT_FATAL_FAILURE(statement, substr) \ - do { \ - class GTestExpectFatalFailureHelper {\ - public:\ - static void Execute() { statement; }\ - };\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ - GTestExpectFatalFailureHelper::Execute();\ - }\ +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper { \ + public: \ + static void Execute() { statement; } \ + }; \ + ::testing::TestPartResultArray gtest_failures; \ + ::testing::internal::SingleFailureChecker gtest_checker( \ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, \ + >est_failures); \ + GTestExpectFatalFailureHelper::Execute(); \ + } \ } while (::testing::internal::AlwaysFalse()) -#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ - do { \ - class GTestExpectFatalFailureHelper {\ - public:\ - static void Execute() { statement; }\ - };\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ALL_THREADS, >est_failures);\ - GTestExpectFatalFailureHelper::Execute();\ - }\ +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper { \ + public: \ + static void Execute() { statement; } \ + }; \ + ::testing::TestPartResultArray gtest_failures; \ + ::testing::internal::SingleFailureChecker gtest_checker( \ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ + >est_failures); \ + GTestExpectFatalFailureHelper::Execute(); \ + } \ } while (::testing::internal::AlwaysFalse()) // A macro for testing Google Test assertions or code that's expected to -// generate Google Test non-fatal failures. It asserts that the given -// statement will cause exactly one non-fatal Google Test failure with 'substr' -// being part of the failure message. +// generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ, +// but not from an ASSERT_EQ). It asserts that the given statement will cause +// exactly one non-fatal Google Test failure with 'substr' being part of the +// failure message. // // There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only // affects and considers failures generated in the current thread and @@ -207,32 +212,37 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 // instead of // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) // to avoid an MSVC warning on unreachable code. -#define EXPECT_NONFATAL_FAILURE(statement, substr) \ - do {\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do { \ + ::testing::TestPartResultArray gtest_failures; \ + ::testing::internal::SingleFailureChecker gtest_checker( \ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ - (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ - if (::testing::internal::AlwaysTrue()) { statement; }\ - }\ + (substr)); \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, \ + >est_failures); \ + if (::testing::internal::AlwaysTrue()) { \ + statement; \ + } \ + } \ } while (::testing::internal::AlwaysFalse()) -#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ - do {\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ - (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + ::testing::TestPartResultArray gtest_failures; \ + ::testing::internal::SingleFailureChecker gtest_checker( \ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr)); \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ - >est_failures);\ - if (::testing::internal::AlwaysTrue()) { statement; }\ - }\ + >est_failures); \ + if (::testing::internal::AlwaysTrue()) { \ + statement; \ + } \ + } \ } while (::testing::internal::AlwaysFalse()) #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-test-part.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-test-part.h index 203fdf98c6..09cc8c34f0 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-test-part.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-test-part.h @@ -26,14 +26,17 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// GOOGLETEST_CM0001 DO NOT DELETE + +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #include #include + #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" @@ -142,7 +145,8 @@ class GTEST_API_ TestPartResultArray { private: std::vector array_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); + TestPartResultArray(const TestPartResultArray&) = delete; + TestPartResultArray& operator=(const TestPartResultArray&) = delete; }; // This interface knows how to report a test part result. @@ -168,11 +172,13 @@ class GTEST_API_ HasNewFatalFailureHelper ~HasNewFatalFailureHelper() override; void ReportTestPartResult(const TestPartResult& result) override; bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: bool has_new_fatal_failure_; TestPartResultReporterInterface* original_reporter_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); + HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete; + HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete; }; } // namespace internal diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-typed-test.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-typed-test.h index 9fdc6be10d..bd35a32660 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-typed-test.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest-typed-test.h @@ -27,7 +27,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ @@ -190,7 +192,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); typedef ::testing::internal::GenerateTypeList::type \ GTEST_TYPE_PARAMS_(CaseName); \ typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \ - GTEST_NAME_GENERATOR_(CaseName) + GTEST_NAME_GENERATOR_(CaseName) #define TYPED_TEST(CaseName, TestName) \ static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ @@ -256,7 +258,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); // #included in multiple translation units linked together. #define TYPED_TEST_SUITE_P(SuiteName) \ static ::testing::internal::TypedTestSuitePState \ - GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName) + GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName) // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ @@ -301,21 +303,21 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); REGISTER_TYPED_TEST_SUITE_P #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ - static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ - "test-suit-prefix must not be empty"); \ - static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::internal::TypeParameterizedTestSuite< \ - SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ - ::testing::internal::GenerateTypeList::type>:: \ - Register(GTEST_STRINGIFY_(Prefix), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__), \ - >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ - GTEST_STRINGIFY_(SuiteName), \ - GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ - ::testing::internal::GenerateNames< \ - ::testing::internal::NameGeneratorSelector< \ - __VA_ARGS__>::type, \ +#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ + static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ + "test-suit-prefix must not be empty"); \ + static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTestSuite< \ + SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ + ::testing::internal::GenerateTypeList::type>:: \ + Register(GTEST_STRINGIFY_(Prefix), \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ + GTEST_STRINGIFY_(SuiteName), \ + GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ + ::testing::internal::GenerateNames< \ + ::testing::internal::NameGeneratorSelector< \ + __VA_ARGS__>::type, \ ::testing::internal::GenerateTypeList::type>()) // Legacy API is deprecated but still available diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest.h index 20f8930fcf..d19a587a18 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest.h @@ -27,7 +27,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// // The Google C++ Testing and Mocking Framework (Google Test) // // This header file defines the public API for Google Test. It should be @@ -47,8 +46,6 @@ // registration from Barthelemy Dagenais' (barthelemy@prologique.com) // easyUnit framework. -// GOOGLETEST_CM0001 DO NOT DELETE - #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_H_ @@ -59,31 +56,22 @@ #include #include -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-string.h" +#include "gtest/gtest-assertion-result.h" #include "gtest/gtest-death-test.h" #include "gtest/gtest-matchers.h" #include "gtest/gtest-message.h" #include "gtest/gtest-param-test.h" #include "gtest/gtest-printers.h" -#include "gtest/gtest_prod.h" #include "gtest/gtest-test-part.h" #include "gtest/gtest-typed-test.h" +#include "gtest/gtest_pred_impl.h" +#include "gtest/gtest_prod.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ /* class A needs to have dll-interface to be used by clients of class B */) -namespace testing { - -// Silence C4100 (unreferenced formal parameter) and 4805 -// unsafe mix of type 'const int' and type 'const bool' -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4805) -# pragma warning(disable:4100) -#endif - - // Declares the flags. // This flag temporary enables the disabled tests. @@ -138,6 +126,12 @@ GTEST_DECLARE_int32_(random_seed); // is 1. If the value is -1 the tests are repeating forever. GTEST_DECLARE_int32_(repeat); +// This flag controls whether Google Test Environments are recreated for each +// repeat of the tests. The default value is true. If set to false the global +// test Environment objects are only set up once, for the first iteration, and +// only torn down once, for the last. +GTEST_DECLARE_bool_(recreate_environments_when_repeating); + // This flag controls whether Google Test includes Google Test internal // stack frames in failure stack traces. GTEST_DECLARE_bool_(show_internal_stack_frames); @@ -163,6 +157,16 @@ GTEST_DECLARE_string_(stream_result_to); GTEST_DECLARE_string_(flagfile); #endif // GTEST_USE_OWN_FLAGFILE_FLAG_ +namespace testing { + +// Silence C4100 (unreferenced formal parameter) and 4805 +// unsafe mix of type 'const int' and type 'const bool' +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4805) +#pragma warning(disable : 4100) +#endif + // The upper limit for valid stack trace depths. const int kMaxStackTraceDepth = 100; @@ -186,10 +190,6 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message); std::set* GetIgnoredParameterizedTestSuites(); -enum class GTestColor { kDefault, kRed, kGreen, kYellow }; - -GTEST_ATTRIBUTE_PRINTF_(2, 3) -void ColoredPrintf(GTestColor color, const char *fmt, ...); } // namespace internal // The friend relationship of some of these classes is cyclic. @@ -205,193 +205,6 @@ using TestCase = TestSuite; class TestInfo; class UnitTest; -// A class for indicating whether an assertion was successful. When -// the assertion wasn't successful, the AssertionResult object -// remembers a non-empty message that describes how it failed. -// -// To create an instance of this class, use one of the factory functions -// (AssertionSuccess() and AssertionFailure()). -// -// This class is useful for two purposes: -// 1. Defining predicate functions to be used with Boolean test assertions -// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts -// 2. Defining predicate-format functions to be -// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). -// -// For example, if you define IsEven predicate: -// -// testing::AssertionResult IsEven(int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess(); -// else -// return testing::AssertionFailure() << n << " is odd"; -// } -// -// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) -// will print the message -// -// Value of: IsEven(Fib(5)) -// Actual: false (5 is odd) -// Expected: true -// -// instead of a more opaque -// -// Value of: IsEven(Fib(5)) -// Actual: false -// Expected: true -// -// in case IsEven is a simple Boolean predicate. -// -// If you expect your predicate to be reused and want to support informative -// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up -// about half as often as positive ones in our tests), supply messages for -// both success and failure cases: -// -// testing::AssertionResult IsEven(int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess() << n << " is even"; -// else -// return testing::AssertionFailure() << n << " is odd"; -// } -// -// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print -// -// Value of: IsEven(Fib(6)) -// Actual: true (8 is even) -// Expected: false -// -// NB: Predicates that support negative Boolean assertions have reduced -// performance in positive ones so be careful not to use them in tests -// that have lots (tens of thousands) of positive Boolean assertions. -// -// To use this class with EXPECT_PRED_FORMAT assertions such as: -// -// // Verifies that Foo() returns an even number. -// EXPECT_PRED_FORMAT1(IsEven, Foo()); -// -// you need to define: -// -// testing::AssertionResult IsEven(const char* expr, int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess(); -// else -// return testing::AssertionFailure() -// << "Expected: " << expr << " is even\n Actual: it's " << n; -// } -// -// If Foo() returns 5, you will see the following message: -// -// Expected: Foo() is even -// Actual: it's 5 -// -class GTEST_API_ AssertionResult { - public: - // Copy constructor. - // Used in EXPECT_TRUE/FALSE(assertion_result). - AssertionResult(const AssertionResult& other); - -// C4800 is a level 3 warning in Visual Studio 2015 and earlier. -// This warning is not emitted in Visual Studio 2017. -// This warning is off by default starting in Visual Studio 2019 but can be -// enabled with command-line options. -#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) -#endif - - // Used in the EXPECT_TRUE/FALSE(bool_expression). - // - // T must be contextually convertible to bool. - // - // The second parameter prevents this overload from being considered if - // the argument is implicitly convertible to AssertionResult. In that case - // we want AssertionResult's copy constructor to be used. - template - explicit AssertionResult( - const T& success, - typename std::enable_if< - !std::is_convertible::value>::type* - /*enabler*/ - = nullptr) - : success_(success) {} - -#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) - GTEST_DISABLE_MSC_WARNINGS_POP_() -#endif - - // Assignment operator. - AssertionResult& operator=(AssertionResult other) { - swap(other); - return *this; - } - - // Returns true if and only if the assertion succeeded. - operator bool() const { return success_; } // NOLINT - - // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. - AssertionResult operator!() const; - - // Returns the text streamed into this AssertionResult. Test assertions - // use it when they fail (i.e., the predicate's outcome doesn't match the - // assertion's expectation). When nothing has been streamed into the - // object, returns an empty string. - const char* message() const { - return message_.get() != nullptr ? message_->c_str() : ""; - } - // Deprecated; please use message() instead. - const char* failure_message() const { return message(); } - - // Streams a custom failure message into this object. - template AssertionResult& operator<<(const T& value) { - AppendMessage(Message() << value); - return *this; - } - - // Allows streaming basic output manipulators such as endl or flush into - // this object. - AssertionResult& operator<<( - ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { - AppendMessage(Message() << basic_manipulator); - return *this; - } - - private: - // Appends the contents of message to message_. - void AppendMessage(const Message& a_message) { - if (message_.get() == nullptr) message_.reset(new ::std::string); - message_->append(a_message.GetString().c_str()); - } - - // Swap the contents of this AssertionResult with other. - void swap(AssertionResult& other); - - // Stores result of the assertion predicate. - bool success_; - // Stores the message describing the condition in case the expectation - // construct is not satisfied with the predicate's outcome. - // Referenced via a pointer to avoid taking too much stack frame space - // with test assertions. - std::unique_ptr< ::std::string> message_; -}; - -// Makes a successful assertion result. -GTEST_API_ AssertionResult AssertionSuccess(); - -// Makes a failed assertion result. -GTEST_API_ AssertionResult AssertionFailure(); - -// Makes a failed assertion result with the given failure message. -// Deprecated; use AssertionFailure() << msg. -GTEST_API_ AssertionResult AssertionFailure(const Message& msg); - -} // namespace testing - -// Includes the auto-generated header that implements a family of generic -// predicate assertion macros. This include comes late because it relies on -// APIs declared above. -#include "gtest/gtest_pred_impl.h" - -namespace testing { - // The abstract class that all tests inherit from. // // In Google Test, a unit test program contains one or many TestSuites, and @@ -526,7 +339,8 @@ class GTEST_API_ Test { virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; } // We disallow copying Tests. - GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); + Test(const Test&) = delete; + Test& operator=(const Test&) = delete; }; typedef internal::TimeInMillis TimeInMillis; @@ -540,24 +354,17 @@ class TestProperty { // C'tor. TestProperty does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestProperty object. - TestProperty(const std::string& a_key, const std::string& a_value) : - key_(a_key), value_(a_value) { - } + TestProperty(const std::string& a_key, const std::string& a_value) + : key_(a_key), value_(a_value) {} // Gets the user supplied key. - const char* key() const { - return key_.c_str(); - } + const char* key() const { return key_.c_str(); } // Gets the user supplied value. - const char* value() const { - return value_.c_str(); - } + const char* value() const { return value_.c_str(); } // Sets a new value, overriding the one supplied in the constructor. - void SetValue(const std::string& new_value) { - value_ = new_value; - } + void SetValue(const std::string& new_value) { value_ = new_value; } private: // The key supplied by the user. @@ -691,7 +498,8 @@ class GTEST_API_ TestResult { TimeInMillis elapsed_time_; // We disallow copying TestResult. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); + TestResult(const TestResult&) = delete; + TestResult& operator=(const TestResult&) = delete; }; // class TestResult // A TestInfo object stores the following information about a test: @@ -815,8 +623,8 @@ class GTEST_API_ TestInfo { } // These fields are immutable properties of the test. - const std::string test_suite_name_; // test suite name - const std::string name_; // Test name + const std::string test_suite_name_; // test suite name + const std::string name_; // Test name // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const std::unique_ptr type_param_; @@ -837,7 +645,8 @@ class GTEST_API_ TestInfo { // test for the second time. TestResult result_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); + TestInfo(const TestInfo&) = delete; + TestInfo& operator=(const TestInfo&) = delete; }; // A test suite, which consists of a vector of TestInfos. @@ -945,7 +754,7 @@ class GTEST_API_ TestSuite { // Adds a TestInfo to this test suite. Will delete the TestInfo upon // destruction of the TestSuite object. - void AddTestInfo(TestInfo * test_info); + void AddTestInfo(TestInfo* test_info); // Clears the results of all tests in this test suite. void ClearResult(); @@ -1046,7 +855,8 @@ class GTEST_API_ TestSuite { TestResult ad_hoc_test_result_; // We disallow copying TestSuites. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestSuite); + TestSuite(const TestSuite&) = delete; + TestSuite& operator=(const TestSuite&) = delete; }; // An Environment object is capable of setting up and tearing down an @@ -1073,6 +883,7 @@ class Environment { // Override this to define how to tear down the environment. virtual void TearDown() {} + private: // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). @@ -1124,6 +935,9 @@ class TestEventListener { // Fired before the test starts. virtual void OnTestStart(const TestInfo& test_info) = 0; + // Fired when a test is disabled + virtual void OnTestDisabled(const TestInfo& /*test_info*/) {} + // Fired after a failed assertion or a SUCCEED() invocation. // If you want to throw an exception from this function to skip to the next // TEST, it must be AssertionException defined above, or inherited from it. @@ -1147,8 +961,7 @@ class TestEventListener { virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; // Fired after each iteration of tests finishes. - virtual void OnTestIterationEnd(const UnitTest& unit_test, - int iteration) = 0; + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0; // Fired after all test activities have ended. virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; @@ -1173,6 +986,7 @@ class EmptyTestEventListener : public TestEventListener { #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ void OnTestStart(const TestInfo& /*test_info*/) override {} + void OnTestDisabled(const TestInfo& /*test_info*/) override {} void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {} void OnTestEnd(const TestInfo& /*test_info*/) override {} void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {} @@ -1262,7 +1076,8 @@ class GTEST_API_ TestEventListeners { TestEventListener* default_xml_generator_; // We disallow copying TestEventListeners. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); + TestEventListeners(const TestEventListeners&) = delete; + TestEventListeners& operator=(const TestEventListeners&) = delete; }; // A UnitTest consists of a vector of TestSuites. @@ -1305,8 +1120,7 @@ class GTEST_API_ UnitTest { // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. - const TestInfo* current_test_info() const - GTEST_LOCK_EXCLUDED_(mutex_); + const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the random seed used at the start of the current test run. int random_seed() const; @@ -1412,8 +1226,7 @@ class GTEST_API_ UnitTest { // eventually call this to report their results. The user code // should use the assertion macros instead of calling this directly. void AddTestPartResult(TestPartResult::Type result_type, - const char* file_name, - int line_number, + const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_); @@ -1444,8 +1257,7 @@ class GTEST_API_ UnitTest { friend std::set* internal::GetIgnoredParameterizedTestSuites(); friend internal::UnitTestImpl* internal::GetUnitTestImpl(); friend void internal::ReportFailureInUnknownLocation( - TestPartResult::Type result_type, - const std::string& message); + TestPartResult::Type result_type, const std::string& message); // Creates an empty UnitTest. UnitTest(); @@ -1459,8 +1271,7 @@ class GTEST_API_ UnitTest { GTEST_LOCK_EXCLUDED_(mutex_); // Pops a trace from the per-thread Google Test trace stack. - void PopGTestTrace() - GTEST_LOCK_EXCLUDED_(mutex_); + void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_); // Protects mutable state in *impl_. This is mutable as some const // methods need to lock it too. @@ -1473,7 +1284,8 @@ class GTEST_API_ UnitTest { internal::UnitTestImpl* impl_; // We disallow copying UnitTest. - GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); + UnitTest(const UnitTest&) = delete; + UnitTest& operator=(const UnitTest&) = delete; }; // A convenient wrapper for adding an environment for the test @@ -1524,13 +1336,11 @@ namespace internal { // when calling EXPECT_* in a tight loop. template AssertionResult CmpHelperEQFailure(const char* lhs_expression, - const char* rhs_expression, - const T1& lhs, const T2& rhs) { - return EqFailure(lhs_expression, - rhs_expression, + const char* rhs_expression, const T1& lhs, + const T2& rhs) { + return EqFailure(lhs_expression, rhs_expression, FormatForComparisonFailureMessage(lhs, rhs), - FormatForComparisonFailureMessage(rhs, lhs), - false); + FormatForComparisonFailureMessage(rhs, lhs), false); } // This block of code defines operator==/!= @@ -1543,8 +1353,7 @@ inline bool operator!=(faketype, faketype) { return false; } // The helper function for {ASSERT|EXPECT}_EQ. template AssertionResult CmpHelperEQ(const char* lhs_expression, - const char* rhs_expression, - const T1& lhs, + const char* rhs_expression, const T1& lhs, const T2& rhs) { if (lhs == rhs) { return AssertionSuccess(); @@ -1575,8 +1384,7 @@ class EqHelper { // Even though its body looks the same as the above version, we // cannot merge the two, as it will make anonymous enums unhappy. static AssertionResult Compare(const char* lhs_expression, - const char* rhs_expression, - BiggestInt lhs, + const char* rhs_expression, BiggestInt lhs, BiggestInt rhs) { return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); } @@ -1611,16 +1419,16 @@ AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2, // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ -template \ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - const T1& val1, const T2& val2) {\ - if (val1 op val2) {\ - return AssertionSuccess();\ - } else {\ - return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);\ - }\ -} +#define GTEST_IMPL_CMP_HELPER_(op_name, op) \ + template \ + AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) { \ + if (val1 op val2) { \ + return AssertionSuccess(); \ + } else { \ + return CmpHelperOpFailure(expr1, expr2, val1, val2, #op); \ + } \ + } // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. @@ -1642,49 +1450,42 @@ GTEST_IMPL_CMP_HELPER_(GT, >) // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression, const char* s2_expression, - const char* s1, - const char* s2); + const char* s1, const char* s2); // The helper function for {ASSERT|EXPECT}_STRCASEEQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* s1_expression, const char* s2_expression, - const char* s1, - const char* s2); + const char* s1, const char* s2); // The helper function for {ASSERT|EXPECT}_STRNE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, - const char* s1, - const char* s2); + const char* s1, const char* s2); // The helper function for {ASSERT|EXPECT}_STRCASENE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, - const char* s1, - const char* s2); - + const char* s1, const char* s2); // Helper function for *_STREQ on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression, const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2); + const wchar_t* s1, const wchar_t* s2); // Helper function for *_STRNE on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2); + const wchar_t* s1, const wchar_t* s2); } // namespace internal @@ -1696,32 +1497,40 @@ GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, // // The {needle,haystack}_expr arguments are the stringified // expressions that generated the two real arguments. -GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack); -GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack); -GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack); -GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack); -GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack); -GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, + const char* haystack_expr, + const char* needle, + const char* haystack); +GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, + const char* haystack_expr, + const wchar_t* needle, + const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, + const char* needle, + const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, + const wchar_t* needle, + const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, + const char* haystack_expr, + const ::std::string& needle, + const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, + const ::std::string& needle, + const ::std::string& haystack); #if GTEST_HAS_STD_WSTRING -GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack); -GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, + const char* haystack_expr, + const ::std::wstring& needle, + const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, + const ::std::wstring& needle, + const ::std::wstring& haystack); #endif // GTEST_HAS_STD_WSTRING namespace internal { @@ -1736,8 +1545,7 @@ namespace internal { template AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression, const char* rhs_expression, - RawType lhs_value, - RawType rhs_value) { + RawType lhs_value, RawType rhs_value) { const FloatingPoint lhs(lhs_value), rhs(rhs_value); if (lhs.AlmostEquals(rhs)) { @@ -1752,10 +1560,8 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression, rhs_ss << std::setprecision(std::numeric_limits::digits10 + 2) << rhs_value; - return EqFailure(lhs_expression, - rhs_expression, - StringStreamToString(&lhs_ss), - StringStreamToString(&rhs_ss), + return EqFailure(lhs_expression, rhs_expression, + StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss), false); } @@ -1765,8 +1571,7 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression, GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, - double val1, - double val2, + double val1, double val2, double abs_error); // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -1774,9 +1579,7 @@ GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, class GTEST_API_ AssertHelper { public: // Constructor. - AssertHelper(TestPartResult::Type type, - const char* file, - int line, + AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message); ~AssertHelper(); @@ -1790,11 +1593,9 @@ class GTEST_API_ AssertHelper { // re-using stack space even for temporary variables, so every EXPECT_EQ // reserves stack space for another AssertHelper. struct AssertHelperData { - AssertHelperData(TestPartResult::Type t, - const char* srcfile, - int line_num, + AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num, const char* msg) - : type(t), file(srcfile), line(line_num), message(msg) { } + : type(t), file(srcfile), line(line_num), message(msg) {} TestPartResult::Type const type; const char* const file; @@ -1802,12 +1603,14 @@ class GTEST_API_ AssertHelper { std::string const message; private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + AssertHelperData(const AssertHelperData&) = delete; + AssertHelperData& operator=(const AssertHelperData&) = delete; }; AssertHelperData* const data_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); + AssertHelper(const AssertHelper&) = delete; + AssertHelper& operator=(const AssertHelper&) = delete; }; } // namespace internal @@ -1864,15 +1667,14 @@ class WithParamInterface { private: // Sets parameter value. The caller is responsible for making sure the value // remains alive and unchanged throughout the current test. - static void SetParam(const ParamType* parameter) { - parameter_ = parameter; - } + static void SetParam(const ParamType* parameter) { parameter_ = parameter; } // Static value used for accessing parameter during a test lifetime. static const ParamType* parameter_; // TestClass must be a subclass of WithParamInterface and Test. - template friend class internal::ParameterizedTestFactory; + template + friend class internal::ParameterizedTestFactory; }; template @@ -1882,8 +1684,7 @@ const T* WithParamInterface::parameter_ = nullptr; // WithParamInterface, and can just inherit from ::testing::TestWithParam. template -class TestWithParam : public Test, public WithParamInterface { -}; +class TestWithParam : public Test, public WithParamInterface {}; // Macros for indicating success/failure in test code. @@ -1914,7 +1715,7 @@ class TestWithParam : public Test, public WithParamInterface { // Generates a nonfatal failure at the given source file location with // a generic message. -#define ADD_FAILURE_AT(file, line) \ +#define ADD_FAILURE_AT(file, line) \ GTEST_MESSAGE_AT_(file, line, "Failed", \ ::testing::TestPartResult::kNonFatalFailure) @@ -1929,7 +1730,7 @@ class TestWithParam : public Test, public WithParamInterface { // Define this macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_FAIL -# define FAIL() GTEST_FAIL() +#define FAIL() GTEST_FAIL() #endif // Generates a success with a generic message. @@ -1938,7 +1739,7 @@ class TestWithParam : public Test, public WithParamInterface { // Define this macro to 1 to omit the definition of SUCCEED(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_SUCCEED -# define SUCCEED() GTEST_SUCCEED() +#define SUCCEED() GTEST_SUCCEED() #endif // Macros for testing exceptions. @@ -1966,16 +1767,15 @@ class TestWithParam : public Test, public WithParamInterface { // Boolean assertions. Condition can be either a Boolean expression or an // AssertionResult. For more information on how to use AssertionResult with // these macros see comments on that class. -#define GTEST_EXPECT_TRUE(condition) \ +#define GTEST_EXPECT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_NONFATAL_FAILURE_) -#define GTEST_EXPECT_FALSE(condition) \ +#define GTEST_EXPECT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_NONFATAL_FAILURE_) #define GTEST_ASSERT_TRUE(condition) \ - GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ - GTEST_FATAL_FAILURE_) -#define GTEST_ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_) +#define GTEST_ASSERT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_FATAL_FAILURE_) @@ -2074,27 +1874,27 @@ class TestWithParam : public Test, public WithParamInterface { // ASSERT_XY(), which clashes with some users' own code. #if !GTEST_DONT_DEFINE_ASSERT_EQ -# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_NE -# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LE -# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LT -# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GE -# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GT -# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) #endif // C-string Comparisons. All tests treat NULL and any non-NULL string @@ -2119,7 +1919,7 @@ class TestWithParam : public Test, public WithParamInterface { EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define EXPECT_STRCASEEQ(s1, s2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2) -#define EXPECT_STRCASENE(s1, s2)\ +#define EXPECT_STRCASENE(s1, s2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) #define ASSERT_STREQ(s1, s2) \ @@ -2128,7 +1928,7 @@ class TestWithParam : public Test, public WithParamInterface { ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define ASSERT_STRCASEEQ(s1, s2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2) -#define ASSERT_STRCASENE(s1, s2)\ +#define ASSERT_STRCASENE(s1, s2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) // Macros for comparing floating-point numbers. @@ -2145,29 +1945,29 @@ class TestWithParam : public Test, public WithParamInterface { // FloatingPoint template class in gtest-internal.h if you are // interested in the implementation details. -#define EXPECT_FLOAT_EQ(val1, val2)\ +#define EXPECT_FLOAT_EQ(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ val1, val2) -#define EXPECT_DOUBLE_EQ(val1, val2)\ +#define EXPECT_DOUBLE_EQ(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ val1, val2) -#define ASSERT_FLOAT_EQ(val1, val2)\ +#define ASSERT_FLOAT_EQ(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ val1, val2) -#define ASSERT_DOUBLE_EQ(val1, val2)\ +#define ASSERT_DOUBLE_EQ(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ val1, val2) -#define EXPECT_NEAR(val1, val2, abs_error)\ - EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ - val1, val2, abs_error) +#define EXPECT_NEAR(val1, val2, abs_error) \ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \ + abs_error) -#define ASSERT_NEAR(val1, val2, abs_error)\ - ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ - val1, val2, abs_error) +#define ASSERT_NEAR(val1, val2, abs_error) \ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \ + abs_error) // These predicate format functions work on floating-point values, and // can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. @@ -2181,7 +1981,6 @@ GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2); - #if GTEST_OS_WINDOWS // Macros that test for HRESULT failure and success, these are only useful @@ -2193,17 +1992,17 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, // expected result and the actual result with both a human-readable // string representation of the error, if available, as well as the // hex result code. -# define EXPECT_HRESULT_SUCCEEDED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) +#define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) -# define ASSERT_HRESULT_SUCCEEDED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) +#define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) -# define EXPECT_HRESULT_FAILED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) +#define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) -# define ASSERT_HRESULT_FAILED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) +#define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) #endif // GTEST_OS_WINDOWS @@ -2218,9 +2017,9 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, // ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; // #define ASSERT_NO_FATAL_FAILURE(statement) \ - GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) #define EXPECT_NO_FATAL_FAILURE(statement) \ - GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) // Causes a trace (including the given source file path and line number, // and the given message) to be included in every test failure message generated @@ -2262,7 +2061,8 @@ class GTEST_API_ ScopedTrace { private: void PushTrace(const char* file, int line, std::string message); - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); + ScopedTrace(const ScopedTrace&) = delete; + ScopedTrace& operator=(const ScopedTrace&) = delete; } GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its // c'tor and d'tor. Therefore it doesn't // need to be used otherwise. @@ -2282,9 +2082,9 @@ class GTEST_API_ ScopedTrace { // Assuming that each thread maintains its own stack of traces. // Therefore, a SCOPED_TRACE() would (correctly) only affect the // assertions in its own thread. -#define SCOPED_TRACE(message) \ - ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ - __FILE__, __LINE__, (message)) +#define SCOPED_TRACE(message) \ + ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \ + __FILE__, __LINE__, (message)) // Compile-time assertion for type equality. // StaticAssertTypeEq() compiles if and only if type1 and type2 @@ -2382,20 +2182,19 @@ constexpr bool StaticAssertTypeEq() noexcept { // EXPECT_EQ(a_.size(), 0); // EXPECT_EQ(b_.size(), 1); // } -// -// GOOGLETEST_CM0011 DO NOT DELETE -#if !GTEST_DONT_DEFINE_TEST -#define TEST_F(test_fixture, test_name)\ +#define GTEST_TEST_F(test_fixture, test_name) \ GTEST_TEST_(test_fixture, test_name, test_fixture, \ ::testing::internal::GetTypeId()) -#endif // !GTEST_DONT_DEFINE_TEST +#if !GTEST_DONT_DEFINE_TEST_F +#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name) +#endif // Returns a path to temporary directory. // Tries to determine an appropriate directory for the platform. GTEST_API_ std::string TempDir(); #ifdef _MSC_VER -# pragma warning(pop) +#pragma warning(pop) #endif // Dynamically registers a test with the framework. @@ -2449,6 +2248,7 @@ GTEST_API_ std::string TempDir(); // } // ... // int main(int argc, char** argv) { +// ::testing::InitGoogleTest(&argc, argv); // std::vector values_to_test = LoadValuesFromConfig(); // RegisterMyTests(values_to_test); // ... @@ -2490,9 +2290,7 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name, // namespace and has an all-caps name. int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; -inline int RUN_ALL_TESTS() { - return ::testing::UnitTest::GetInstance()->Run(); -} +inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); } GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest_pred_impl.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest_pred_impl.h index 5029a9bb02..47a24aa687 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest_pred_impl.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest_pred_impl.h @@ -26,17 +26,19 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command -// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // // Implements a family of generic predicate assertion macros. -// GOOGLETEST_CM0001 DO NOT DELETE + +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ -#include "gtest/gtest.h" +#include "gtest/gtest-assertion-result.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-port.h" namespace testing { @@ -72,22 +74,18 @@ namespace testing { // GTEST_ASSERT_ is the basic statement to which all of the assertions // in this file reduce. Don't use this in your code. -#define GTEST_ASSERT_(expression, on_failure) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar = (expression)) \ - ; \ - else \ + ; \ + else \ on_failure(gtest_ar.failure_message()) - // Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. -template -AssertionResult AssertPred1Helper(const char* pred_text, - const char* e1, - Pred pred, - const T1& v1) { +template +AssertionResult AssertPred1Helper(const char* pred_text, const char* e1, + Pred pred, const T1& v1) { if (pred(v1)) return AssertionSuccess(); return AssertionFailure() @@ -98,40 +96,27 @@ AssertionResult AssertPred1Helper(const char* pred_text, // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Don't use this in your code. -#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, v1), \ - on_failure) +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, v1), on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. -#define GTEST_PRED1_(pred, v1, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ - #v1, \ - pred, \ - v1), on_failure) +#define GTEST_PRED1_(pred, v1, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure) // Unary predicate assertion macros. #define EXPECT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED1(pred, v1) \ - GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED1(pred, v1) \ - GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) - - +#define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. -template -AssertionResult AssertPred2Helper(const char* pred_text, - const char* e1, - const char* e2, - Pred pred, - const T1& v1, +template +AssertionResult AssertPred2Helper(const char* pred_text, const char* e1, + const char* e2, Pred pred, const T1& v1, const T2& v2) { if (pred(v1, v2)) return AssertionSuccess(); @@ -145,19 +130,14 @@ AssertionResult AssertPred2Helper(const char* pred_text, // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Don't use this in your code. -#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ - on_failure) +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. -#define GTEST_PRED2_(pred, v1, v2, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ - #v1, \ - #v2, \ - pred, \ - v1, \ - v2), on_failure) +#define GTEST_PRED2_(pred, v1, v2, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \ + on_failure) // Binary predicate assertion macros. #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ @@ -169,22 +149,12 @@ AssertionResult AssertPred2Helper(const char* pred_text, #define ASSERT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) - - // Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. -template -AssertionResult AssertPred3Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3) { +template +AssertionResult AssertPred3Helper(const char* pred_text, const char* e1, + const char* e2, const char* e3, Pred pred, + const T1& v1, const T2& v2, const T3& v3) { if (pred(v1, v2, v3)) return AssertionSuccess(); return AssertionFailure() @@ -198,21 +168,15 @@ AssertionResult AssertPred3Helper(const char* pred_text, // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Don't use this in your code. -#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ - on_failure) +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. -#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - pred, \ - v1, \ - v2, \ - v3), on_failure) +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure) \ + GTEST_ASSERT_( \ + ::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \ + on_failure) // Ternary predicate assertion macros. #define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ @@ -224,25 +188,13 @@ AssertionResult AssertPred3Helper(const char* pred_text, #define ASSERT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) - - // Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. -template -AssertionResult AssertPred4Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - const char* e4, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3, - const T4& v4) { +template +AssertionResult AssertPred4Helper(const char* pred_text, const char* e1, + const char* e2, const char* e3, + const char* e4, Pred pred, const T1& v1, + const T2& v2, const T3& v3, const T4& v4) { if (pred(v1, v2, v3, v4)) return AssertionSuccess(); return AssertionFailure() @@ -257,23 +209,15 @@ AssertionResult AssertPred4Helper(const char* pred_text, // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Don't use this in your code. -#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ - on_failure) +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. -#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - #v4, \ - pred, \ - v1, \ - v2, \ - v3, \ - v4), on_failure) +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \ + v1, v2, v3, v4), \ + on_failure) // 4-ary predicate assertion macros. #define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ @@ -285,28 +229,15 @@ AssertionResult AssertPred4Helper(const char* pred_text, #define ASSERT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) - - // Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. -template -AssertionResult AssertPred5Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - const char* e4, - const char* e5, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3, - const T4& v4, - const T5& v5) { +AssertionResult AssertPred5Helper(const char* pred_text, const char* e1, + const char* e2, const char* e3, + const char* e4, const char* e5, Pred pred, + const T1& v1, const T2& v2, const T3& v3, + const T4& v4, const T5& v5) { if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); return AssertionFailure() @@ -322,25 +253,16 @@ AssertionResult AssertPred5Helper(const char* pred_text, // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Don't use this in your code. -#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure) \ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. -#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - #v4, \ - #v5, \ - pred, \ - v1, \ - v2, \ - v3, \ - v4, \ - v5), on_failure) +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \ + pred, v1, v2, v3, v4, v5), \ + on_failure) // 5-ary predicate assertion macros. #define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ @@ -352,8 +274,6 @@ AssertionResult AssertPred5Helper(const char* pred_text, #define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) - - } // namespace testing #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest_prod.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest_prod.h index 38b9d85a51..1f37dc31c3 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest_prod.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/gtest_prod.h @@ -27,9 +27,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Google C++ Testing and Mocking Framework definitions useful in production code. -// GOOGLETEST_CM0003 DO NOT DELETE +// Google C++ Testing and Mocking Framework definitions useful in production +// code. #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ @@ -55,7 +54,7 @@ // Note: The test class must be in the same namespace as the class being tested. // For example, putting MyClassTest in an anonymous namespace will not work. -#define FRIEND_TEST(test_case_name, test_name)\ -friend class test_case_name##_##test_name##_Test +#define FRIEND_TEST(test_case_name, test_name) \ + friend class test_case_name##_##test_name##_Test #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-death-test-internal.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-death-test-internal.h index 490296dfad..45580ae805 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-death-test-internal.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-death-test-internal.h @@ -26,27 +26,31 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// + // The Google C++ Testing and Mocking Framework (Google Test) // // This header file defines internal utilities needed for implementing // death tests. They are subject to change without notice. -// GOOGLETEST_CM0001 DO NOT DELETE + +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#include + +#include + #include "gtest/gtest-matchers.h" #include "gtest/internal/gtest-internal.h" -#include -#include +GTEST_DECLARE_string_(internal_run_death_test); namespace testing { namespace internal { -GTEST_DECLARE_string_(internal_run_death_test); - // Names of the flags (needed for parsing Google Test flags). const char kDeathTestStyleFlag[] = "death_test_style"; const char kDeathTestUseFork[] = "death_test_use_fork"; @@ -83,16 +87,18 @@ class GTEST_API_ DeathTest { static bool Create(const char* statement, Matcher matcher, const char* file, int line, DeathTest** test); DeathTest(); - virtual ~DeathTest() { } + virtual ~DeathTest() {} // A helper class that aborts a death test when it's deleted. class ReturnSentinel { public: - explicit ReturnSentinel(DeathTest* test) : test_(test) { } + explicit ReturnSentinel(DeathTest* test) : test_(test) {} ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: DeathTest* const test_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + ReturnSentinel(const ReturnSentinel&) = delete; + ReturnSentinel& operator=(const ReturnSentinel&) = delete; } GTEST_ATTRIBUTE_UNUSED_; // An enumeration of possible roles that may be taken when a death @@ -137,7 +143,8 @@ class GTEST_API_ DeathTest { // A string containing a description of the outcome of the last death test. static std::string last_death_test_message_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); + DeathTest(const DeathTest&) = delete; + DeathTest& operator=(const DeathTest&) = delete; }; GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 @@ -145,7 +152,7 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 // Factory interface for death tests. May be mocked out for testing. class DeathTestFactory { public: - virtual ~DeathTestFactory() { } + virtual ~DeathTestFactory() {} virtual bool Create(const char* statement, Matcher matcher, const char* file, int line, DeathTest** test) = 0; @@ -186,28 +193,28 @@ inline Matcher MakeDeathTestMatcher( // Traps C++ exceptions escaping statement and reports them as test // failures. Note that trapping SEH exceptions is not implemented here. -# if GTEST_HAS_EXCEPTIONS -# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (const ::std::exception& gtest_exception) { \ - fprintf(\ - stderr, \ - "\n%s: Caught std::exception-derived exception escaping the " \ - "death test statement. Exception message: %s\n", \ +#if GTEST_HAS_EXCEPTIONS +#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (const ::std::exception& gtest_exception) { \ + fprintf( \ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ - gtest_exception.what()); \ - fflush(stderr); \ + gtest_exception.what()); \ + fflush(stderr); \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ - } catch (...) { \ + } catch (...) { \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } -# else -# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ +#else +#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) -# endif +#endif // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // ASSERT_EXIT*, and EXPECT_EXIT*. @@ -236,8 +243,6 @@ inline Matcher MakeDeathTestMatcher( gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ - default: \ - break; \ } \ } \ } else \ @@ -265,16 +270,12 @@ inline Matcher MakeDeathTestMatcher( // RUN_ALL_TESTS was called. class InternalRunDeathTestFlag { public: - InternalRunDeathTestFlag(const std::string& a_file, - int a_line, - int an_index, + InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index, int a_write_fd) - : file_(a_file), line_(a_line), index_(an_index), - write_fd_(a_write_fd) {} + : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {} ~InternalRunDeathTestFlag() { - if (write_fd_ >= 0) - posix::Close(write_fd_); + if (write_fd_ >= 0) posix::Close(write_fd_); } const std::string& file() const { return file_; } @@ -288,7 +289,8 @@ class InternalRunDeathTestFlag { int index_; int write_fd_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); + InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete; + InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete; }; // Returns a newly created InternalRunDeathTestFlag object with fields diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-filepath.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-filepath.h index 0c033abc34..a2a60a962b 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-filepath.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-filepath.h @@ -26,7 +26,7 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// + // Google Test filepath utilities // // This header file declares classes and functions used internally by @@ -35,7 +35,9 @@ // This file is #included in gtest/internal/gtest-internal.h. // Do not include this header file separately! -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ @@ -61,8 +63,8 @@ namespace internal { class GTEST_API_ FilePath { public: - FilePath() : pathname_("") { } - FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + FilePath() : pathname_("") {} + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {} explicit FilePath(const std::string& pathname) : pathname_(pathname) { Normalize(); @@ -73,9 +75,7 @@ class GTEST_API_ FilePath { return *this; } - void Set(const FilePath& rhs) { - pathname_ = rhs.pathname_; - } + void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; } const std::string& string() const { return pathname_; } const char* c_str() const { return pathname_.c_str(); } @@ -88,8 +88,7 @@ class GTEST_API_ FilePath { // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. static FilePath MakeFileName(const FilePath& directory, - const FilePath& base_name, - int number, + const FilePath& base_name, int number, const char* extension); // Given directory = "dir", relative_path = "test.xml", diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-internal.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-internal.h index f8cbdbd81d..9b04e4c85f 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-internal.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-internal.h @@ -26,13 +26,15 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// + // The Google C++ Testing and Mocking Framework (Google Test) // // This header file declares functions and macros used internally by // Google Test. They are subject to change without notice. -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ @@ -40,19 +42,20 @@ #include "gtest/internal/gtest-port.h" #if GTEST_OS_LINUX -# include -# include -# include -# include +#include +#include +#include +#include #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS -# include +#include #endif #include #include #include + #include #include #include @@ -76,7 +79,7 @@ // the current line number. For more details, see // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) -#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar // Stringifies its argument. // Work around a bug in visual studio which doesn't accept code like this: @@ -98,21 +101,21 @@ namespace testing { // Forward declarations. -class AssertionResult; // Result of an assertion. -class Message; // Represents a failure message. -class Test; // Represents a test. -class TestInfo; // Information about a test. -class TestPartResult; // Result of a test part. -class UnitTest; // A collection of test suites. +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test suites. template ::std::string PrintToString(const T& value); namespace internal { -struct TraceInfo; // Information about a trace point. -class TestInfoImpl; // Opaque implementation of TestInfo -class UnitTestImpl; // Opaque implementation of UnitTest +struct TraceInfo; // Information about a trace point. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest // The text used in failure messages to indicate the start of the // stack trace. @@ -121,6 +124,7 @@ GTEST_API_ extern const char kStackTraceMarker[]; // An IgnoredValue object can be implicitly constructed from ANY value. class IgnoredValue { struct Sink {}; + public: // This constructor template allows any value to be implicitly // converted to IgnoredValue. The object has no data member and @@ -136,13 +140,13 @@ class IgnoredValue { }; // Appends the user-supplied message to the Google-Test-generated message. -GTEST_API_ std::string AppendUserMessage( - const std::string& gtest_msg, const Message& user_msg); +GTEST_API_ std::string AppendUserMessage(const std::string& gtest_msg, + const Message& user_msg); #if GTEST_HAS_EXCEPTIONS -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4275 \ -/* an exported class was derived from a class that was not exported */) +GTEST_DISABLE_MSC_WARNINGS_PUSH_( + 4275 /* an exported class was derived from a class that was not exported */) // This exception is thrown by (and only by) a failed Google Test // assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions @@ -181,14 +185,6 @@ GTEST_API_ std::string CreateUnifiedDiff(const std::vector& left, } // namespace edit_distance -// Calculate the diff between 'left' and 'right' and return it in unified diff -// format. -// If not null, stores in 'total_line_count' the total number of lines found -// in left + right. -GTEST_API_ std::string DiffStrings(const std::string& left, - const std::string& right, - size_t* total_line_count); - // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // @@ -212,10 +208,8 @@ GTEST_API_ AssertionResult EqFailure(const char* expected_expression, // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. GTEST_API_ std::string GetBoolAssertionFailureMessage( - const AssertionResult& assertion_result, - const char* expression_text, - const char* actual_predicate_value, - const char* expected_predicate_value); + const AssertionResult& assertion_result, const char* expression_text, + const char* actual_predicate_value, const char* expected_predicate_value); // This template class represents an IEEE floating-point number // (either single-precision or double-precision, depending on the @@ -256,11 +250,11 @@ class FloatingPoint { // Constants. // # of bits in a number. - static const size_t kBitCount = 8*sizeof(RawType); + static const size_t kBitCount = 8 * sizeof(RawType); // # of fraction bits in a number. static const size_t kFractionBitCount = - std::numeric_limits::digits - 1; + std::numeric_limits::digits - 1; // # of exponent bits in a number. static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; @@ -269,8 +263,8 @@ class FloatingPoint { static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); // The mask for the fraction bits. - static const Bits kFractionBitMask = - ~static_cast(0) >> (kExponentBitCount + 1); + static const Bits kFractionBitMask = ~static_cast(0) >> + (kExponentBitCount + 1); // The mask for the exponent bits. static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); @@ -309,9 +303,7 @@ class FloatingPoint { } // Returns the floating-point number that represent positive infinity. - static RawType Infinity() { - return ReinterpretBits(kExponentBitMask); - } + static RawType Infinity() { return ReinterpretBits(kExponentBitMask); } // Returns the maximum representable finite floating-point number. static RawType Max(); @@ -319,7 +311,7 @@ class FloatingPoint { // Non-static methods // Returns the bits that represents this number. - const Bits &bits() const { return u_.bits_; } + const Bits& bits() const { return u_.bits_; } // Returns the exponent bits of this number. Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } @@ -348,8 +340,8 @@ class FloatingPoint { // a NAN must return false. if (is_nan() || rhs.is_nan()) return false; - return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) - <= kMaxUlps; + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <= + kMaxUlps; } private: @@ -374,7 +366,7 @@ class FloatingPoint { // // Read http://en.wikipedia.org/wiki/Signed_number_representations // for more details on signed number representations. - static Bits SignAndMagnitudeToBiased(const Bits &sam) { + static Bits SignAndMagnitudeToBiased(const Bits& sam) { if (kSignBitMask & sam) { // sam represents a negative number. return ~sam + 1; @@ -386,8 +378,8 @@ class FloatingPoint { // Given two numbers in the sign-and-magnitude representation, // returns the distance between them as an unsigned number. - static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, - const Bits &sam2) { + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1, + const Bits& sam2) { const Bits biased1 = SignAndMagnitudeToBiased(sam1); const Bits biased2 = SignAndMagnitudeToBiased(sam2); return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); @@ -399,9 +391,13 @@ class FloatingPoint { // We cannot use std::numeric_limits::max() as it clashes with the max() // macro defined by . template <> -inline float FloatingPoint::Max() { return FLT_MAX; } +inline float FloatingPoint::Max() { + return FLT_MAX; +} template <> -inline double FloatingPoint::Max() { return DBL_MAX; } +inline double FloatingPoint::Max() { + return DBL_MAX; +} // Typedefs the instances of the FloatingPoint template class that we // care to use. @@ -461,7 +457,8 @@ class TestFactoryBase { TestFactoryBase() {} private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); + TestFactoryBase(const TestFactoryBase&) = delete; + TestFactoryBase& operator=(const TestFactoryBase&) = delete; }; // This class provides implementation of TeastFactoryBase interface. @@ -510,11 +507,11 @@ inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull( template // Note that SuiteApiResolver inherits from T because -// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way +// SetUpTestSuite()/TearDownTestSuite() could be protected. This way // SuiteApiResolver can access them. struct SuiteApiResolver : T { // testing::Test is only forward declared at this point. So we make it a - // dependend class for the compiler to be OK with it. + // dependent class for the compiler to be OK with it. using Test = typename std::conditional::type; @@ -654,7 +651,8 @@ inline const char* SkipComma(const char* str) { if (comma == nullptr) { return nullptr; } - while (IsSpace(*(++comma))) {} + while (IsSpace(*(++comma))) { + } return comma; } @@ -668,7 +666,7 @@ inline std::string GetPrefixUntilComma(const char* str) { // Splits a given string on a given delimiter, populating a given // vector with the fields. void SplitString(const ::std::string& str, char delimiter, - ::std::vector< ::std::string>* dest); + ::std::vector<::std::string>* dest); // The default argument to the template below for the case when the user does // not provide a name generator. @@ -781,13 +779,13 @@ class TypeParameterizedTestSuite { const std::vector& type_names = GenerateNames()) { RegisterTypeParameterizedTestSuiteInstantiation(case_name); - std::string test_name = StripTrailingSpaces( - GetPrefixUntilComma(test_names)); + std::string test_name = + StripTrailingSpaces(GetPrefixUntilComma(test_names)); if (!state->TestExists(test_name)) { fprintf(stderr, "Failed to get code location for test %s.%s at %s.", case_name, test_name.c_str(), - FormatFileLocation(code_location.file.c_str(), - code_location.line).c_str()); + FormatFileLocation(code_location.file.c_str(), code_location.line) + .c_str()); fflush(stderr); posix::Abort(); } @@ -831,8 +829,8 @@ class TypeParameterizedTestSuite { // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( - UnitTest* unit_test, int skip_count); +GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, + int skip_count); // Helpers for suppressing warnings on unreachable code or constant // condition. @@ -881,7 +879,8 @@ class GTEST_API_ Random { private: uint32_t state_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); + Random(const Random&) = delete; + Random& operator=(const Random&) = delete; }; // Turns const U&, U&, const U, and U all into U. @@ -954,7 +953,9 @@ IsContainer IsContainerTest(int /* dummy */) { typedef char IsNotContainer; template -IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } +IsNotContainer IsContainerTest(long /* dummy */) { + return '\0'; +} // Trait to detect whether a type T is a hash table. // The heuristic used is that the type contains an inner type `hasher` and does @@ -1017,11 +1018,13 @@ bool ArrayEq(const T* lhs, size_t size, const U* rhs); // This generic version is used when k is 0. template -inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } +inline bool ArrayEq(const T& lhs, const U& rhs) { + return lhs == rhs; +} // This overload is used when k >= 1. template -inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { +inline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) { return internal::ArrayEq(lhs, N, rhs); } @@ -1031,8 +1034,7 @@ inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { template bool ArrayEq(const T* lhs, size_t size, const U* rhs) { for (size_t i = 0; i != size; i++) { - if (!internal::ArrayEq(lhs[i], rhs[i])) - return false; + if (!internal::ArrayEq(lhs[i], rhs[i])) return false; } return true; } @@ -1042,8 +1044,7 @@ bool ArrayEq(const T* lhs, size_t size, const U* rhs) { template Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { for (Iter it = begin; it != end; ++it) { - if (internal::ArrayEq(*it, elem)) - return it; + if (internal::ArrayEq(*it, elem)) return it; } return end; } @@ -1057,11 +1058,13 @@ void CopyArray(const T* from, size_t size, U* to); // This generic version is used when k is 0. template -inline void CopyArray(const T& from, U* to) { *to = from; } +inline void CopyArray(const T& from, U* to) { + *to = from; +} // This overload is used when k >= 1. template -inline void CopyArray(const T(&from)[N], U(*to)[N]) { +inline void CopyArray(const T (&from)[N], U (*to)[N]) { internal::CopyArray(from, N, *to); } @@ -1114,8 +1117,7 @@ class NativeArray { } ~NativeArray() { - if (clone_ != &NativeArray::InitRef) - delete[] array_; + if (clone_ != &NativeArray::InitRef) delete[] array_; } // STL-style container methods. @@ -1123,8 +1125,7 @@ class NativeArray { const_iterator begin() const { return array_; } const_iterator end() const { return array_ + size_; } bool operator==(const NativeArray& rhs) const { - return size() == rhs.size() && - ArrayEq(begin(), size(), rhs.begin()); + return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin()); } private: @@ -1335,9 +1336,9 @@ struct tuple_size> #endif } // namespace std -#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ - ::testing::internal::AssertHelper(result_type, file, line, message) \ - = ::testing::Message() +#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ + ::testing::internal::AssertHelper(result_type, file, line, message) = \ + ::testing::Message() #define GTEST_MESSAGE_(message, result_type) \ GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) @@ -1458,103 +1459,112 @@ class NeverThrown { #endif // GTEST_HAS_EXCEPTIONS -#define GTEST_TEST_NO_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::TrueWithString gtest_msg{}) { \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \ - catch (...) { \ - gtest_msg.value = "it throws."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ - fail(("Expected: " #statement " doesn't throw an exception.\n" \ - " Actual: " + gtest_msg.value).c_str()) - -#define GTEST_TEST_ANY_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - bool gtest_caught_any = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (...) { \ - gtest_caught_any = true; \ - } \ - if (!gtest_caught_any) { \ +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::TrueWithString gtest_msg{}) { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \ + catch (...) { \ + gtest_msg.value = "it throws."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__) \ + : fail(("Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: " + \ + gtest_msg.value) \ + .c_str()) + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ - fail("Expected: " #statement " throws an exception.\n" \ - " Actual: it doesn't.") - + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__) \ + : fail("Expected: " #statement \ + " throws an exception.\n" \ + " Actual: it doesn't.") // Implements Boolean test assertions such as EXPECT_TRUE. expression can be // either a boolean expression or an AssertionResult. text is a textual // representation of expression as it was passed into the EXPECT_TRUE. #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const ::testing::AssertionResult gtest_ar_ = \ - ::testing::AssertionResult(expression)) \ - ; \ - else \ - fail(::testing::internal::GetBoolAssertionFailureMessage(\ - gtest_ar_, text, #actual, #expected).c_str()) - -#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage( \ + gtest_ar_, text, #actual, #expected) \ + .c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ - fail("Expected: " #statement " doesn't generate new fatal " \ - "failures in the current thread.\n" \ - " Actual: it does.") + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) \ + : fail("Expected: " #statement \ + " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") // Expands to the name of the class that implements the given test. #define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ test_suite_name##_##test_name##_Test // Helper macro for defining tests. -#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \ - static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ - "test_suite_name must not be empty"); \ - static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \ - "test_name must not be empty"); \ - class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - : public parent_class { \ - public: \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \ - ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \ - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name)); \ - GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name)); \ - \ - private: \ - void TestBody() override; \ - static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ - }; \ - \ - ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name)::test_info_ = \ - ::testing::internal::MakeAndRegisterTestInfo( \ - #test_suite_name, #test_name, nullptr, nullptr, \ - ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \ - ::testing::internal::SuiteApiResolver< \ - parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \ - ::testing::internal::SuiteApiResolver< \ - parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \ - new ::testing::internal::TestFactoryImpl); \ +#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \ + static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ + "test_suite_name must not be empty"); \ + static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \ + "test_name must not be empty"); \ + class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ + : public parent_class { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \ + ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ + (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \ + const GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name) &) = delete; /* NOLINT */ \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ + (GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &&) noexcept = delete; \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \ + GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name) &&) noexcept = delete; /* NOLINT */ \ + \ + private: \ + void TestBody() override; \ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ + }; \ + \ + ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ + test_name)::test_info_ = \ + ::testing::internal::MakeAndRegisterTestInfo( \ + #test_suite_name, #test_name, nullptr, nullptr, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \ + ::testing::internal::SuiteApiResolver< \ + parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \ + ::testing::internal::SuiteApiResolver< \ + parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \ + new ::testing::internal::TestFactoryImpl); \ void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-param-util.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-param-util.h index c2ef6e3124..e7af2f904a 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-param-util.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-param-util.h @@ -27,10 +27,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - // Type and function utilities for implementing parameterized tests. -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ @@ -46,19 +47,18 @@ #include #include -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-port.h" #include "gtest/gtest-printers.h" #include "gtest/gtest-test-part.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-port.h" namespace testing { // Input to a parameterized test name generator, describing a test parameter. // Consists of the parameter value and the integer parameter index. template struct TestParamInfo { - TestParamInfo(const ParamType& a_param, size_t an_index) : - param(a_param), - index(an_index) {} + TestParamInfo(const ParamType& a_param, size_t an_index) + : param(a_param), index(an_index) {} ParamType param; size_t index; }; @@ -84,8 +84,10 @@ namespace internal { GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name, CodeLocation code_location); -template class ParamGeneratorInterface; -template class ParamGenerator; +template +class ParamGeneratorInterface; +template +class ParamGenerator; // Interface for iterating over elements provided by an implementation // of ParamGeneratorInterface. @@ -129,8 +131,7 @@ class ParamIterator { // ParamIterator assumes ownership of the impl_ pointer. ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} ParamIterator& operator=(const ParamIterator& other) { - if (this != &other) - impl_.reset(other.impl_->Clone()); + if (this != &other) impl_.reset(other.impl_->Clone()); return *this; } @@ -157,7 +158,7 @@ class ParamIterator { private: friend class ParamGenerator; explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} - std::unique_ptr > impl_; + std::unique_ptr> impl_; }; // ParamGeneratorInterface is the binary interface to access generators @@ -179,7 +180,7 @@ class ParamGeneratorInterface { // This class implements copy initialization semantics and the contained // ParamGeneratorInterface instance is shared among all copies // of the original object. This is possible because that instance is immutable. -template +template class ParamGenerator { public: typedef ParamIterator iterator; @@ -196,7 +197,7 @@ class ParamGenerator { iterator end() const { return iterator(impl_->End()); } private: - std::shared_ptr > impl_; + std::shared_ptr> impl_; }; // Generates values from a range of two comparable values. Can be used to @@ -207,8 +208,10 @@ template class RangeGenerator : public ParamGeneratorInterface { public: RangeGenerator(T begin, T end, IncrementT step) - : begin_(begin), end_(end), - step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + : begin_(begin), + end_(end), + step_(step), + end_index_(CalculateEndIndex(begin, end, step)) {} ~RangeGenerator() override {} ParamIteratorInterface* Begin() const override { @@ -251,7 +254,9 @@ class RangeGenerator : public ParamGeneratorInterface { private: Iterator(const Iterator& other) : ParamIteratorInterface(), - base_(other.base_), value_(other.value_), index_(other.index_), + base_(other.base_), + value_(other.value_), + index_(other.index_), step_(other.step_) {} // No implementation - assignment is unsupported. @@ -263,12 +268,10 @@ class RangeGenerator : public ParamGeneratorInterface { const IncrementT step_; }; // class RangeGenerator::Iterator - static int CalculateEndIndex(const T& begin, - const T& end, + static int CalculateEndIndex(const T& begin, const T& end, const IncrementT& step) { int end_index = 0; - for (T i = begin; i < end; i = static_cast(i + step)) - end_index++; + for (T i = begin; i < end; i = static_cast(i + step)) end_index++; return end_index; } @@ -283,7 +286,6 @@ class RangeGenerator : public ParamGeneratorInterface { const int end_index_; }; // class RangeGenerator - // Generates values from a pair of STL-style iterators. Used in the // ValuesIn() function. The elements are copied from the source range // since the source can be located on the stack, and the generator @@ -341,13 +343,13 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { << "The program attempted to compare iterators " << "from different generators." << std::endl; return iterator_ == - CheckedDowncastToActualType(&other)->iterator_; + CheckedDowncastToActualType(&other)->iterator_; } private: Iterator(const Iterator& other) - // The explicit constructor call suppresses a false warning - // emitted by gcc when supplied with the -Wextra option. + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. : ParamIteratorInterface(), base_(other.base_), iterator_(other.iterator_) {} @@ -394,8 +396,8 @@ template class ParameterizedTestFactory : public TestFactoryBase { public: typedef typename TestClass::ParamType ParamType; - explicit ParameterizedTestFactory(ParamType parameter) : - parameter_(parameter) {} + explicit ParameterizedTestFactory(ParamType parameter) + : parameter_(parameter) {} Test* CreateTest() override { TestClass::SetParam(¶meter_); return new TestClass(); @@ -404,7 +406,8 @@ class ParameterizedTestFactory : public TestFactoryBase { private: const ParamType parameter_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); + ParameterizedTestFactory(const ParameterizedTestFactory&) = delete; + ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete; }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -440,7 +443,8 @@ class TestMetaFactory } private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); + TestMetaFactory(const TestMetaFactory&) = delete; + TestMetaFactory& operator=(const TestMetaFactory&) = delete; }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -471,7 +475,10 @@ class ParameterizedTestSuiteInfoBase { ParameterizedTestSuiteInfoBase() {} private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase); + ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) = + delete; + ParameterizedTestSuiteInfoBase& operator=( + const ParameterizedTestSuiteInfoBase&) = delete; }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -547,8 +554,8 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { test_it != tests_.end(); ++test_it) { std::shared_ptr test_info = *test_it; for (typename InstantiationContainer::iterator gen_it = - instantiations_.begin(); gen_it != instantiations_.end(); - ++gen_it) { + instantiations_.begin(); + gen_it != instantiations_.end(); ++gen_it) { const std::string& instantiation_name = gen_it->name; ParamGenerator generator((*gen_it->generator)()); ParamNameGeneratorFunc* name_func = gen_it->name_func; @@ -556,7 +563,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { int line = gen_it->line; std::string test_suite_name; - if ( !instantiation_name.empty() ) + if (!instantiation_name.empty()) test_suite_name = instantiation_name + "/"; test_suite_name += test_info->test_suite_base_name; @@ -569,17 +576,16 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { Message test_name_stream; - std::string param_name = name_func( - TestParamInfo(*param_it, i)); + std::string param_name = + name_func(TestParamInfo(*param_it, i)); GTEST_CHECK_(IsValidParamName(param_name)) << "Parameterized test name '" << param_name - << "' is invalid, in " << file - << " line " << line << std::endl; + << "' is invalid, in " << file << " line " << line << std::endl; GTEST_CHECK_(test_param_names.count(param_name) == 0) - << "Duplicate parameterized test name '" << param_name - << "', in " << file << " line " << line << std::endl; + << "Duplicate parameterized test name '" << param_name << "', in " + << file << " line " << line << std::endl; test_param_names.insert(param_name); @@ -596,15 +602,15 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { SuiteApiResolver::GetTearDownCaseOrSuite(file, line), test_info->test_meta_factory->CreateTestFactory(*param_it)); } // for param_it - } // for gen_it - } // for test_it + } // for gen_it + } // for test_it if (!generated_instantiations) { // There are no generaotrs, or they all generate nothing ... InsertSyntheticTestCase(GetTestSuiteName(), code_location_, !tests_.empty()); } - } // RegisterTests + } // RegisterTests private: // LocalTestInfo structure keeps information about a single test registered @@ -620,42 +626,39 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { const std::string test_suite_base_name; const std::string test_base_name; - const std::unique_ptr > test_meta_factory; + const std::unique_ptr> test_meta_factory; const CodeLocation code_location; }; - using TestInfoContainer = ::std::vector >; + using TestInfoContainer = ::std::vector>; // Records data received from INSTANTIATE_TEST_SUITE_P macros: // struct InstantiationInfo { - InstantiationInfo(const std::string &name_in, - GeneratorCreationFunc* generator_in, - ParamNameGeneratorFunc* name_func_in, - const char* file_in, - int line_in) - : name(name_in), - generator(generator_in), - name_func(name_func_in), - file(file_in), - line(line_in) {} - - std::string name; - GeneratorCreationFunc* generator; - ParamNameGeneratorFunc* name_func; - const char* file; - int line; + InstantiationInfo(const std::string& name_in, + GeneratorCreationFunc* generator_in, + ParamNameGeneratorFunc* name_func_in, const char* file_in, + int line_in) + : name(name_in), + generator(generator_in), + name_func(name_func_in), + file(file_in), + line(line_in) {} + + std::string name; + GeneratorCreationFunc* generator; + ParamNameGeneratorFunc* name_func; + const char* file; + int line; }; typedef ::std::vector InstantiationContainer; static bool IsValidParamName(const std::string& name) { // Check for empty string - if (name.empty()) - return false; + if (name.empty()) return false; // Check for invalid characters for (std::string::size_type index = 0; index < name.size(); ++index) { - if (!IsAlNum(name[index]) && name[index] != '_') - return false; + if (!IsAlNum(name[index]) && name[index] != '_') return false; } return true; @@ -666,7 +669,9 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { TestInfoContainer tests_; InstantiationContainer instantiations_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo); + ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete; + ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) = + delete; }; // class ParameterizedTestSuiteInfo // Legacy API is deprecated but still available @@ -709,7 +714,7 @@ class ParameterizedTestSuiteRegistry { // type we are looking for, so we downcast it to that type // without further checks. typed_test_info = CheckedDowncastToActualType< - ParameterizedTestSuiteInfo >(test_suite_info); + ParameterizedTestSuiteInfo>(test_suite_info); } break; } @@ -741,7 +746,10 @@ class ParameterizedTestSuiteRegistry { TestSuiteInfoContainer test_suite_infos_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry); + ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) = + delete; + ParameterizedTestSuiteRegistry& operator=( + const ParameterizedTestSuiteRegistry&) = delete; }; // Keep track of what type-parameterized test suite are defined and @@ -836,7 +844,8 @@ class CartesianProductGenerator : public ParamIteratorInterface { public: IteratorImpl(const ParamGeneratorInterface* base, - const std::tuple...>& generators, bool is_end) + const std::tuple...>& generators, + bool is_end) : base_(base), begin_(std::get(generators).begin()...), end_(std::get(generators).end()...), diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-port-arch.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-port-arch.h index dd845915e3..f025db76ad 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-port-arch.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-port-arch.h @@ -26,7 +26,7 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// + // The Google C++ Testing and Mocking Framework (Google Test) // // This header file defines the GTEST_OS_* macro. @@ -37,70 +37,72 @@ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ -# define GTEST_OS_CYGWIN 1 -# elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) -# define GTEST_OS_WINDOWS_MINGW 1 -# define GTEST_OS_WINDOWS 1 +#define GTEST_OS_CYGWIN 1 +#elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) +#define GTEST_OS_WINDOWS_MINGW 1 +#define GTEST_OS_WINDOWS 1 #elif defined _WIN32 -# define GTEST_OS_WINDOWS 1 -# ifdef _WIN32_WCE -# define GTEST_OS_WINDOWS_MOBILE 1 -# elif defined(WINAPI_FAMILY) -# include -# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -# define GTEST_OS_WINDOWS_DESKTOP 1 -# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) -# define GTEST_OS_WINDOWS_PHONE 1 -# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) -# define GTEST_OS_WINDOWS_RT 1 -# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) -# define GTEST_OS_WINDOWS_PHONE 1 -# define GTEST_OS_WINDOWS_TV_TITLE 1 -# else - // WINAPI_FAMILY defined but no known partition matched. - // Default to desktop. -# define GTEST_OS_WINDOWS_DESKTOP 1 -# endif -# else -# define GTEST_OS_WINDOWS_DESKTOP 1 -# endif // _WIN32_WCE +#define GTEST_OS_WINDOWS 1 +#ifdef _WIN32_WCE +#define GTEST_OS_WINDOWS_MOBILE 1 +#elif defined(WINAPI_FAMILY) +#include +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define GTEST_OS_WINDOWS_DESKTOP 1 +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +#define GTEST_OS_WINDOWS_PHONE 1 +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define GTEST_OS_WINDOWS_RT 1 +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) +#define GTEST_OS_WINDOWS_PHONE 1 +#define GTEST_OS_WINDOWS_TV_TITLE 1 +#else +// WINAPI_FAMILY defined but no known partition matched. +// Default to desktop. +#define GTEST_OS_WINDOWS_DESKTOP 1 +#endif +#else +#define GTEST_OS_WINDOWS_DESKTOP 1 +#endif // _WIN32_WCE #elif defined __OS2__ -# define GTEST_OS_OS2 1 +#define GTEST_OS_OS2 1 #elif defined __APPLE__ -# define GTEST_OS_MAC 1 -# include -# if TARGET_OS_IPHONE -# define GTEST_OS_IOS 1 -# endif +#define GTEST_OS_MAC 1 +#include +#if TARGET_OS_IPHONE +#define GTEST_OS_IOS 1 +#endif #elif defined __DragonFly__ -# define GTEST_OS_DRAGONFLY 1 +#define GTEST_OS_DRAGONFLY 1 #elif defined __FreeBSD__ -# define GTEST_OS_FREEBSD 1 +#define GTEST_OS_FREEBSD 1 #elif defined __Fuchsia__ -# define GTEST_OS_FUCHSIA 1 +#define GTEST_OS_FUCHSIA 1 +#elif defined(__GNU__) +#define GTEST_OS_GNU_HURD 1 #elif defined(__GLIBC__) && defined(__FreeBSD_kernel__) -# define GTEST_OS_GNU_KFREEBSD 1 +#define GTEST_OS_GNU_KFREEBSD 1 #elif defined __linux__ -# define GTEST_OS_LINUX 1 -# if defined __ANDROID__ -# define GTEST_OS_LINUX_ANDROID 1 -# endif +#define GTEST_OS_LINUX 1 +#if defined __ANDROID__ +#define GTEST_OS_LINUX_ANDROID 1 +#endif #elif defined __MVS__ -# define GTEST_OS_ZOS 1 +#define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) -# define GTEST_OS_SOLARIS 1 +#define GTEST_OS_SOLARIS 1 #elif defined(_AIX) -# define GTEST_OS_AIX 1 +#define GTEST_OS_AIX 1 #elif defined(__hpux) -# define GTEST_OS_HPUX 1 +#define GTEST_OS_HPUX 1 #elif defined __native_client__ -# define GTEST_OS_NACL 1 +#define GTEST_OS_NACL 1 #elif defined __NetBSD__ -# define GTEST_OS_NETBSD 1 +#define GTEST_OS_NETBSD 1 #elif defined __OpenBSD__ -# define GTEST_OS_OPENBSD 1 +#define GTEST_OS_OPENBSD 1 #elif defined __QNX__ -# define GTEST_OS_QNX 1 +#define GTEST_OS_QNX 1 #elif defined(__HAIKU__) #define GTEST_OS_HAIKU 1 #elif defined ESP8266 diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-port.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-port.h index 0953a781c0..0003d27658 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-port.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-port.h @@ -26,7 +26,7 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// + // Low-level types and utilities for porting Google Test to various // platforms. All macros ending with _ and symbols defined in an // internal namespace are subject to change without notice. Code @@ -38,7 +38,9 @@ // files are expected to #include this. Therefore, it cannot #include // any other Google Test header. -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ @@ -116,6 +118,7 @@ // GTEST_OS_DRAGONFLY - DragonFlyBSD // GTEST_OS_FREEBSD - FreeBSD // GTEST_OS_FUCHSIA - Fuchsia +// GTEST_OS_GNU_HURD - GNU/Hurd // GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD // GTEST_OS_HAIKU - Haiku // GTEST_OS_HPUX - HP-UX @@ -167,7 +170,7 @@ // GTEST_HAS_TYPED_TEST - typed tests // GTEST_HAS_TYPED_TEST_P - type-parameterized tests // GTEST_IS_THREADSAFE - Google Test is thread-safe. -// GOOGLETEST_CM0007 DO NOT DELETE +// GTEST_USES_RE2 - the RE2 regular expression library is used // GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with // GTEST_HAS_POSIX_RE (see above) which users can // define themselves. @@ -190,10 +193,6 @@ // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a // variable don't have to be used. -// GTEST_DISALLOW_ASSIGN_ - disables copy operator=. -// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. -// GTEST_DISALLOW_MOVE_ASSIGN_ - disables move operator=. -// GTEST_DISALLOW_MOVE_AND_ASSIGN_ - disables move ctor and operator=. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is // suppressed (constant conditional). @@ -217,11 +216,13 @@ // - synchronization primitives. // // Regular expressions: -// RE - a simple regular expression class using the POSIX -// Extended Regular Expression syntax on UNIX-like platforms -// GOOGLETEST_CM0008 DO NOT DELETE -// or a reduced regular exception syntax on other -// platforms, including Windows. +// RE - a simple regular expression class using +// 1) the RE2 syntax on all platforms when built with RE2 +// and Abseil as dependencies +// 2) the POSIX Extended Regular Expression syntax on +// UNIX-like platforms, +// 3) A reduced regular exception syntax on other platforms, +// including Windows. // Logging: // GTEST_LOG_() - logs messages at the specified severity level. // LogToStderr() - directs all log messages to stderr. @@ -241,8 +242,6 @@ // BiggestInt - the biggest signed integer type. // // Command-line utilities: -// GTEST_DECLARE_*() - declares a flag. -// GTEST_DEFINE_*() - defines a flag. // GetInjectableArgvs() - returns the command line as a vector of strings. // // Environment variable utilities: @@ -263,48 +262,55 @@ #include #include +// #include // Guarded by GTEST_IS_THREADSAFE below #include +#include #include +#include +#include +#include +// #include // Guarded by GTEST_IS_THREADSAFE below +#include #include +#include #ifndef _WIN32_WCE -# include -# include +#include +#include #endif // !_WIN32_WCE #if defined __APPLE__ -# include -# include +#include +#include #endif -#include // NOLINT -#include -#include -#include // NOLINT -#include -#include // NOLINT - #include "gtest/internal/custom/gtest-port.h" #include "gtest/internal/gtest-port-arch.h" +#if GTEST_HAS_ABSL +#include "absl/flags/declare.h" +#include "absl/flags/flag.h" +#include "absl/flags/reflection.h" +#endif + #if !defined(GTEST_DEV_EMAIL_) -# define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" -# define GTEST_FLAG_PREFIX_ "gtest_" -# define GTEST_FLAG_PREFIX_DASH_ "gtest-" -# define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" -# define GTEST_NAME_ "Google Test" -# define GTEST_PROJECT_URL_ "https://github.com/google/googletest/" +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "https://github.com/google/googletest/" #endif // !defined(GTEST_DEV_EMAIL_) #if !defined(GTEST_INIT_GOOGLE_TEST_NAME_) -# define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest" +#define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest" #endif // !defined(GTEST_INIT_GOOGLE_TEST_NAME_) // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ // 40302 means version 4.3.2. -# define GTEST_GCC_VER_ \ - (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#define GTEST_GCC_VER_ \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif // __GNUC__ // Macros for disabling Microsoft Visual C++ warnings. @@ -313,41 +319,37 @@ // /* code that triggers warnings C4800 and C4385 */ // GTEST_DISABLE_MSC_WARNINGS_POP_() #if defined(_MSC_VER) -# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ - __pragma(warning(push)) \ - __pragma(warning(disable: warnings)) -# define GTEST_DISABLE_MSC_WARNINGS_POP_() \ - __pragma(warning(pop)) +#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ + __pragma(warning(push)) __pragma(warning(disable : warnings)) +#define GTEST_DISABLE_MSC_WARNINGS_POP_() __pragma(warning(pop)) #else // Not all compilers are MSVC -# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) -# define GTEST_DISABLE_MSC_WARNINGS_POP_() +#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) +#define GTEST_DISABLE_MSC_WARNINGS_POP_() #endif // Clang on Windows does not understand MSVC's pragma warning. // We need clang-specific way to disable function deprecation warning. #ifdef __clang__ -# define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ - _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"") -#define GTEST_DISABLE_MSC_DEPRECATED_POP_() \ - _Pragma("clang diagnostic pop") +#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"") +#define GTEST_DISABLE_MSC_DEPRECATED_POP_() _Pragma("clang diagnostic pop") #else -# define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) -# define GTEST_DISABLE_MSC_DEPRECATED_POP_() \ - GTEST_DISABLE_MSC_WARNINGS_POP_() +#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) +#define GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_() #endif // Brings in definitions for functions used in the testing::internal::posix // namespace (read, write, close, chdir, isatty, stat). We do not currently // use them on Windows Mobile. #if GTEST_OS_WINDOWS -# if !GTEST_OS_WINDOWS_MOBILE -# include -# include -# endif +#if !GTEST_OS_WINDOWS_MOBILE +#include +#include +#endif // In order to avoid having to include , use forward declaration #if GTEST_OS_WINDOWS_MINGW && !defined(__MINGW64_VERSION_MAJOR) // MinGW defined _CRITICAL_SECTION and _RTL_CRITICAL_SECTION as two @@ -367,68 +369,55 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // This assumes that non-Windows OSes provide unistd.h. For OSes where this // is not the case, we need to include headers that provide the functions // mentioned above. -# include -# include +#include +#include #endif // GTEST_OS_WINDOWS #if GTEST_OS_LINUX_ANDROID // Used to define __ANDROID_API__ matching the target NDK API level. -# include // NOLINT +#include // NOLINT #endif // Defines this to true if and only if Google Test can use POSIX regular // expressions. #ifndef GTEST_HAS_POSIX_RE -# if GTEST_OS_LINUX_ANDROID +#if GTEST_OS_LINUX_ANDROID // On Android, is only available starting with Gingerbread. -# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) -# else +#define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) +#else #define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS && !GTEST_OS_XTENSA) -# endif +#endif #endif -#if GTEST_USES_PCRE -// The appropriate headers have already been included. - +// Select the regular expression implementation. +#if GTEST_HAS_ABSL +// When using Abseil, RE2 is required. +#include "absl/strings/string_view.h" +#include "re2/re2.h" +#define GTEST_USES_RE2 1 #elif GTEST_HAS_POSIX_RE - -// On some platforms, needs someone to define size_t, and -// won't compile otherwise. We can #include it here as we already -// included , which is guaranteed to define size_t through -// . -# include // NOLINT - -# define GTEST_USES_POSIX_RE 1 - -#elif GTEST_OS_WINDOWS - -// is not available on Windows. Use our own simple regex -// implementation instead. -# define GTEST_USES_SIMPLE_RE 1 - +#include // NOLINT +#define GTEST_USES_POSIX_RE 1 #else - -// may not be available on this platform. Use our own -// simple regex implementation instead. -# define GTEST_USES_SIMPLE_RE 1 - -#endif // GTEST_USES_PCRE +// Use our own simple regex implementation. +#define GTEST_USES_SIMPLE_RE 1 +#endif #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need // to figure it out. -# if defined(_MSC_VER) && defined(_CPPUNWIND) +#if defined(_MSC_VER) && defined(_CPPUNWIND) // MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__BORLANDC__) +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__BORLANDC__) // C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS // macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. -# ifndef _HAS_EXCEPTIONS -# define _HAS_EXCEPTIONS 1 -# endif // _HAS_EXCEPTIONS -# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -# elif defined(__clang__) +#ifndef _HAS_EXCEPTIONS +#define _HAS_EXCEPTIONS 1 +#endif // _HAS_EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +#elif defined(__clang__) // clang defines __EXCEPTIONS if and only if exceptions are enabled before clang // 220714, but if and only if cleanups are enabled after that. In Obj-C++ files, // there can be cleanups for ObjC exceptions which also need cleanups, even if @@ -437,27 +426,27 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // cleanups prior to that. To reliably check for C++ exception availability with // clang, check for // __EXCEPTIONS && __has_feature(cxx_exceptions). -# define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions)) -# elif defined(__GNUC__) && __EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions)) +#elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__SUNPRO_CC) +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__SUNPRO_CC) // Sun Pro CC supports exceptions. However, there is no compile-time way of // detecting whether they are enabled or not. Therefore, we assume that // they are enabled unless the user tells us otherwise. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__IBMCPP__) && __EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__IBMCPP__) && __EXCEPTIONS // xlC defines __EXCEPTIONS to 1 if and only if exceptions are enabled. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__HP_aCC) +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__HP_aCC) // Exception handling is in effect by default in HP aCC compiler. It has to // be turned of by +noeh compiler option if desired. -# define GTEST_HAS_EXCEPTIONS 1 -# else +#define GTEST_HAS_EXCEPTIONS 1 +#else // For other compilers, we assume exceptions are disabled to be // conservative. -# define GTEST_HAS_EXCEPTIONS 0 -# endif // defined(_MSC_VER) || defined(__BORLANDC__) +#define GTEST_HAS_EXCEPTIONS 0 +#endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS #ifndef GTEST_HAS_STD_WSTRING @@ -477,63 +466,62 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // The user didn't tell us whether RTTI is enabled, so we need to // figure it out. -# ifdef _MSC_VER +#ifdef _MSC_VER #ifdef _CPPRTTI // MSVC defines this macro if and only if RTTI is enabled. -# define GTEST_HAS_RTTI 1 -# else -# define GTEST_HAS_RTTI 0 -# endif +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif // Starting with version 4.3.2, gcc defines __GXX_RTTI if and only if RTTI is // enabled. -# elif defined(__GNUC__) +#elif defined(__GNUC__) -# ifdef __GXX_RTTI +#ifdef __GXX_RTTI // When building against STLport with the Android NDK and with // -frtti -fno-exceptions, the build fails at link time with undefined // references to __cxa_bad_typeid. Note sure if STL or toolchain bug, // so disable RTTI when detected. -# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ - !defined(__EXCEPTIONS) -# define GTEST_HAS_RTTI 0 -# else -# define GTEST_HAS_RTTI 1 -# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS -# else -# define GTEST_HAS_RTTI 0 -# endif // __GXX_RTTI +#if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && !defined(__EXCEPTIONS) +#define GTEST_HAS_RTTI 0 +#else +#define GTEST_HAS_RTTI 1 +#endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS +#else +#define GTEST_HAS_RTTI 0 +#endif // __GXX_RTTI // Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends // using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the // first version with C++ support. -# elif defined(__clang__) +#elif defined(__clang__) -# define GTEST_HAS_RTTI __has_feature(cxx_rtti) +#define GTEST_HAS_RTTI __has_feature(cxx_rtti) // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // both the typeid and dynamic_cast features are present. -# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) +#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) -# ifdef __RTTI_ALL__ -# define GTEST_HAS_RTTI 1 -# else -# define GTEST_HAS_RTTI 0 -# endif +#ifdef __RTTI_ALL__ +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif -# else +#else // For all other compilers, we assume RTTI is enabled. -# define GTEST_HAS_RTTI 1 +#define GTEST_HAS_RTTI 1 -# endif // _MSC_VER +#endif // _MSC_VER #endif // GTEST_HAS_RTTI // It's this header's responsibility to #include when RTTI // is enabled. #if GTEST_HAS_RTTI -# include +#include #endif // Determines whether Google Test can use the pthreads library. @@ -547,16 +535,16 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \ GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \ - GTEST_OS_HAIKU) + GTEST_OS_HAIKU || GTEST_OS_GNU_HURD) #endif // GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD // gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is // true. -# include // NOLINT +#include // NOLINT // For timespec and nanosleep, used below. -# include // NOLINT +#include // NOLINT #endif // Determines whether clone(2) is supported. @@ -566,24 +554,23 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. -# if GTEST_OS_LINUX && !defined(__ia64__) -# if GTEST_OS_LINUX_ANDROID +#if GTEST_OS_LINUX && !defined(__ia64__) +#if GTEST_OS_LINUX_ANDROID // On Android, clone() became available at different API levels for each 32-bit // architecture. -# if defined(__LP64__) || \ - (defined(__arm__) && __ANDROID_API__ >= 9) || \ - (defined(__mips__) && __ANDROID_API__ >= 12) || \ - (defined(__i386__) && __ANDROID_API__ >= 17) -# define GTEST_HAS_CLONE 1 -# else -# define GTEST_HAS_CLONE 0 -# endif -# else -# define GTEST_HAS_CLONE 1 -# endif -# else -# define GTEST_HAS_CLONE 0 -# endif // GTEST_OS_LINUX && !defined(__ia64__) +#if defined(__LP64__) || (defined(__arm__) && __ANDROID_API__ >= 9) || \ + (defined(__mips__) && __ANDROID_API__ >= 12) || \ + (defined(__i386__) && __ANDROID_API__ >= 17) +#define GTEST_HAS_CLONE 1 +#else +#define GTEST_HAS_CLONE 0 +#endif +#else +#define GTEST_HAS_CLONE 1 +#endif +#else +#define GTEST_HAS_CLONE 0 +#endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE @@ -594,10 +581,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // platforms except known mobile ones. #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA -# define GTEST_HAS_STREAM_REDIRECTION 0 -# else -# define GTEST_HAS_STREAM_REDIRECTION 1 -# endif // !GTEST_OS_WINDOWS_MOBILE +#define GTEST_HAS_STREAM_REDIRECTION 0 +#else +#define GTEST_HAS_STREAM_REDIRECTION 1 +#endif // !GTEST_OS_WINDOWS_MOBILE #endif // GTEST_HAS_STREAM_REDIRECTION // Determines whether to support death tests. @@ -607,8 +594,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \ GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \ GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ - GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU) -# define GTEST_HAS_DEATH_TEST 1 + GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \ + GTEST_OS_GNU_HURD) +#define GTEST_HAS_DEATH_TEST 1 #endif // Determines whether to support type-driven tests. @@ -617,8 +605,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // Sun Pro CC, IBM Visual Age, and HP aCC support. #if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \ defined(__IBMCPP__) || defined(__HP_aCC) -# define GTEST_HAS_TYPED_TEST 1 -# define GTEST_HAS_TYPED_TEST_P 1 +#define GTEST_HAS_TYPED_TEST 1 +#define GTEST_HAS_TYPED_TEST_P 1 #endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. @@ -627,8 +615,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // Determines whether test results can be streamed to a socket. #if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \ - GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD -# define GTEST_CAN_STREAM_RESULTS_ 1 + GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD || \ + GTEST_OS_GNU_HURD +#define GTEST_CAN_STREAM_RESULTS_ 1 #endif // Defines some utility macros. @@ -642,9 +631,12 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // // The "switch (0) case 0:" idiom is used to suppress this. #ifdef __INTEL_COMPILER -# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ #else -# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + switch (0) \ + case 0: \ + default: // NOLINT #endif // Use this annotation at the end of a struct/class definition to @@ -659,55 +651,32 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // Also use it after a variable or parameter declaration to tell the // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) -# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) #elif defined(__clang__) -# if __has_attribute(unused) -# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) -# endif +#if __has_attribute(unused) +#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) +#endif #endif #ifndef GTEST_ATTRIBUTE_UNUSED_ -# define GTEST_ATTRIBUTE_UNUSED_ +#define GTEST_ATTRIBUTE_UNUSED_ #endif // Use this annotation before a function that takes a printf format string. #if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC) -# if defined(__MINGW_PRINTF_FORMAT) +#if defined(__MINGW_PRINTF_FORMAT) // MinGW has two different printf implementations. Ensure the format macro // matches the selected implementation. See // https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. -# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ - __attribute__((__format__(__MINGW_PRINTF_FORMAT, string_index, \ - first_to_check))) -# else -# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ - __attribute__((__format__(__printf__, string_index, first_to_check))) -# endif +#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ + __attribute__(( \ + __format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check))) #else -# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) +#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +#endif +#else +#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) #endif - - -// A macro to disallow copy operator= -// This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_ASSIGN_(type) \ - type& operator=(type const &) = delete - -// A macro to disallow copy constructor and operator= -// This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \ - type(type const&) = delete; \ - type& operator=(type const&) = delete - -// A macro to disallow move operator= -// This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_MOVE_ASSIGN_(type) \ - type& operator=(type &&) noexcept = delete - -// A macro to disallow move constructor and operator= -// This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_MOVE_AND_ASSIGN_(type) \ - type(type&&) noexcept = delete; \ - type& operator=(type&&) noexcept = delete // Tell the compiler to warn about unused return values for functions declared // with this macro. The macro should be used on function declarations @@ -715,9 +684,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; #if defined(__GNUC__) && !defined(COMPILER_ICC) -# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result)) #else -# define GTEST_MUST_USE_RESULT_ +#define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && !COMPILER_ICC // MS C++ compiler emits warning when a conditional expression is compile time @@ -728,10 +697,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // while (true) { // GTEST_INTENTIONAL_CONST_COND_POP_() // } -# define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) -# define GTEST_INTENTIONAL_CONST_COND_POP_() \ - GTEST_DISABLE_MSC_WARNINGS_POP_() +#define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) +#define GTEST_INTENTIONAL_CONST_COND_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_() // Determine whether the compiler supports Microsoft's Structured Exception // Handling. This is supported by several Windows compilers but generally @@ -739,13 +707,13 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #ifndef GTEST_HAS_SEH // The user didn't tell us, so we need to figure it out. -# if defined(_MSC_VER) || defined(__BORLANDC__) +#if defined(_MSC_VER) || defined(__BORLANDC__) // These two compilers are known to support SEH. -# define GTEST_HAS_SEH 1 -# else +#define GTEST_HAS_SEH 1 +#else // Assume no SEH. -# define GTEST_HAS_SEH 0 -# endif +#define GTEST_HAS_SEH 0 +#endif #endif // GTEST_HAS_SEH @@ -758,94 +726,112 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif // GTEST_IS_THREADSAFE +#if GTEST_IS_THREADSAFE +// Some platforms don't support including these threading related headers. +#include // NOLINT +#include // NOLINT +#endif // GTEST_IS_THREADSAFE + // GTEST_API_ qualifies all symbols that must be exported. The definitions below // are guarded by #ifndef to give embedders a chance to define GTEST_API_ in // gtest/internal/custom/gtest-port.h #ifndef GTEST_API_ #ifdef _MSC_VER -# if GTEST_LINKED_AS_SHARED_LIBRARY -# define GTEST_API_ __declspec(dllimport) -# elif GTEST_CREATE_SHARED_LIBRARY -# define GTEST_API_ __declspec(dllexport) -# endif +#if GTEST_LINKED_AS_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllimport) +#elif GTEST_CREATE_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllexport) +#endif #elif __GNUC__ >= 4 || defined(__clang__) -# define GTEST_API_ __attribute__((visibility ("default"))) +#define GTEST_API_ __attribute__((visibility("default"))) #endif // _MSC_VER #endif // GTEST_API_ #ifndef GTEST_API_ -# define GTEST_API_ +#define GTEST_API_ #endif // GTEST_API_ #ifndef GTEST_DEFAULT_DEATH_TEST_STYLE -# define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" +#define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" #endif // GTEST_DEFAULT_DEATH_TEST_STYLE #ifdef __GNUC__ // Ask the compiler to never inline a given function. -# define GTEST_NO_INLINE_ __attribute__((noinline)) +#define GTEST_NO_INLINE_ __attribute__((noinline)) #else -# define GTEST_NO_INLINE_ +#define GTEST_NO_INLINE_ +#endif + +#if defined(__clang__) +// Nested ifs to avoid triggering MSVC warning. +#if __has_attribute(disable_tail_calls) +// Ask the compiler not to perform tail call optimization inside +// the marked function. +#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls)) +#endif +#elif __GNUC__ +#define GTEST_NO_TAIL_CALL_ \ + __attribute__((optimize("no-optimize-sibling-calls"))) +#else +#define GTEST_NO_TAIL_CALL_ #endif // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. #if !defined(GTEST_HAS_CXXABI_H_) -# if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) -# define GTEST_HAS_CXXABI_H_ 1 -# else -# define GTEST_HAS_CXXABI_H_ 0 -# endif +#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) +#define GTEST_HAS_CXXABI_H_ 1 +#else +#define GTEST_HAS_CXXABI_H_ 0 +#endif #endif // A function level attribute to disable checking for use of uninitialized // memory when built with MemorySanitizer. #if defined(__clang__) -# if __has_feature(memory_sanitizer) -# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ \ - __attribute__((no_sanitize_memory)) -# else -# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ -# endif // __has_feature(memory_sanitizer) +#if __has_feature(memory_sanitizer) +#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory)) +#else +#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +#endif // __has_feature(memory_sanitizer) #else -# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ #endif // __clang__ // A function level attribute to disable AddressSanitizer instrumentation. #if defined(__clang__) -# if __has_feature(address_sanitizer) -# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \ - __attribute__((no_sanitize_address)) -# else -# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -# endif // __has_feature(address_sanitizer) +#if __has_feature(address_sanitizer) +#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \ + __attribute__((no_sanitize_address)) +#else +#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +#endif // __has_feature(address_sanitizer) #else -# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ #endif // __clang__ // A function level attribute to disable HWAddressSanitizer instrumentation. #if defined(__clang__) -# if __has_feature(hwaddress_sanitizer) -# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \ - __attribute__((no_sanitize("hwaddress"))) -# else -# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -# endif // __has_feature(hwaddress_sanitizer) +#if __has_feature(hwaddress_sanitizer) +#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \ + __attribute__((no_sanitize("hwaddress"))) #else -# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ +#endif // __has_feature(hwaddress_sanitizer) +#else +#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ #endif // __clang__ // A function level attribute to disable ThreadSanitizer instrumentation. #if defined(__clang__) -# if __has_feature(thread_sanitizer) -# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ \ - __attribute__((no_sanitize_thread)) -# else -# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -# endif // __has_feature(thread_sanitizer) +#if __has_feature(thread_sanitizer) +#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute__((no_sanitize_thread)) +#else +#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +#endif // __has_feature(thread_sanitizer) #else -# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ #endif // __clang__ namespace testing { @@ -867,25 +853,37 @@ namespace internal { // Secret object, which is what we want. class Secret; -// The GTEST_COMPILE_ASSERT_ is a legacy macro used to verify that a compile -// time expression is true (in new code, use static_assert instead). For -// example, you could use it to verify the size of a static array: -// -// GTEST_COMPILE_ASSERT_(GTEST_ARRAY_SIZE_(names) == NUM_NAMES, -// names_incorrect_size); -// -// The second argument to the macro must be a valid C++ identifier. If the -// expression is false, compiler will issue an error containing this identifier. -#define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg) - // A helper for suppressing warnings on constant condition. It just // returns 'condition'. GTEST_API_ bool IsTrue(bool condition); // Defines RE. -#if GTEST_USES_PCRE -// if used, PCRE is injected by custom/gtest-port.h +#if GTEST_USES_RE2 + +// This is almost `using RE = ::RE2`, except it is copy-constructible, and it +// needs to disambiguate the `std::string`, `absl::string_view`, and `const +// char*` constructors. +class GTEST_API_ RE { + public: + RE(absl::string_view regex) : regex_(regex) {} // NOLINT + RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT + RE(const std::string& regex) : RE(absl::string_view(regex)) {} // NOLINT + RE(const RE& other) : RE(other.pattern()) {} + + const std::string& pattern() const { return regex_.pattern(); } + + static bool FullMatch(absl::string_view str, const RE& re) { + return RE2::FullMatch(str, re.regex_); + } + static bool PartialMatch(absl::string_view str, const RE& re) { + return RE2::PartialMatch(str, re.regex_); + } + + private: + RE2 regex_; +}; + #elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE // A simple C++ wrapper for . It uses the POSIX Extended @@ -924,19 +922,19 @@ class GTEST_API_ RE { const char* pattern_; bool is_valid_; -# if GTEST_USES_POSIX_RE +#if GTEST_USES_POSIX_RE regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). -# else // GTEST_USES_SIMPLE_RE +#else // GTEST_USES_SIMPLE_RE const char* full_pattern_; // For FullMatch(); -# endif +#endif }; -#endif // GTEST_USES_PCRE +#endif // ::testing::internal::RE implementation // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. @@ -954,12 +952,7 @@ GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. -enum GTestLogSeverity { - GTEST_INFO, - GTEST_WARNING, - GTEST_ERROR, - GTEST_FATAL -}; +enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL }; // Formats log entry severity, provides a stream object for streaming the // log message, and terminates the message with a newline when going out of @@ -976,14 +969,16 @@ class GTEST_API_ GTestLog { private: const GTestLogSeverity severity_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); + GTestLog(const GTestLog&) = delete; + GTestLog& operator=(const GTestLog&) = delete; }; #if !defined(GTEST_LOG_) -# define GTEST_LOG_(severity) \ - ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ - __FILE__, __LINE__).GetStream() +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__) \ + .GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(nullptr); } @@ -995,7 +990,7 @@ inline void FlushInfoLog() { fflush(nullptr); } // // GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition // is not satisfied. -// Synopsys: +// Synopsis: // GTEST_CHECK_(boolean_condition); // or // GTEST_CHECK_(boolean_condition) << "Additional message"; @@ -1005,12 +1000,12 @@ inline void FlushInfoLog() { fflush(nullptr); } // condition itself, plus additional message streamed into it, if any, // and then it aborts the program. It aborts the program irrespective of // whether it is built in the debug mode or not. -# define GTEST_CHECK_(condition) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::IsTrue(condition)) \ - ; \ - else \ - GTEST_LOG_(FATAL) << "Condition " #condition " failed. " +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " #endif // !defined(GTEST_CHECK_) // An all-mode assert to verify that the given POSIX-style function @@ -1019,9 +1014,8 @@ inline void FlushInfoLog() { fflush(nullptr); } // in {} if you need to use it as the only statement in an 'if' // branch. #define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ - if (const int gtest_error = (posix_call)) \ - GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ - << gtest_error + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " << gtest_error // Transforms "T" into "const T&" according to standard reference collapsing // rules (this is only needed as a backport for C++98 compilers that do not @@ -1035,9 +1029,13 @@ inline void FlushInfoLog() { fflush(nullptr); } // Note that the non-const reference will not have "const" added. This is // standard, and necessary so that "T" can always bind to "const T&". template -struct ConstRef { typedef const T& type; }; +struct ConstRef { + typedef const T& type; +}; template -struct ConstRef { typedef T& type; }; +struct ConstRef { + typedef T& type; +}; // The argument T must depend on some template parameters. #define GTEST_REFERENCE_TO_CONST_(T) \ @@ -1050,7 +1048,7 @@ struct ConstRef { typedef T& type; }; // const Foo*). When you use ImplicitCast_, the compiler checks that // the cast is safe. Such explicit ImplicitCast_s are necessary in // surprisingly many situations where C++ demands an exact type match -// instead of an argument type convertable to a target type. +// instead of an argument type convertible to a target type. // // The syntax for using ImplicitCast_ is the same as for static_cast: // @@ -1063,8 +1061,10 @@ struct ConstRef { typedef T& type; }; // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., implicit_cast). The internal // namespace alone is not enough because the function can be found by ADL. -template -inline To ImplicitCast_(To x) { return x; } +template +inline To ImplicitCast_(To x) { + return x; +} // When you upcast (that is, cast a pointer from type Foo to type // SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts @@ -1087,17 +1087,17 @@ inline To ImplicitCast_(To x) { return x; } // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., down_cast). The internal // namespace alone is not enough because the function can be found by ADL. -template // use like this: DownCast_(foo); -inline To DownCast_(From* f) { // so we only accept pointers +template // use like this: DownCast_(foo); +inline To DownCast_(From* f) { // so we only accept pointers // Ensures that To is a sub-type of From *. This test is here only // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away // completely. GTEST_INTENTIONAL_CONST_COND_PUSH_() if (false) { - GTEST_INTENTIONAL_CONST_COND_POP_() - const To to = nullptr; - ::testing::internal::ImplicitCast_(to); + GTEST_INTENTIONAL_CONST_COND_POP_() + const To to = nullptr; + ::testing::internal::ImplicitCast_(to); } #if GTEST_HAS_RTTI @@ -1162,71 +1162,8 @@ void ClearInjectableArgvs(); // Defines synchronization primitives. #if GTEST_IS_THREADSAFE -# if GTEST_HAS_PTHREAD -// Sleeps for (roughly) n milliseconds. This function is only for testing -// Google Test's own constructs. Don't use it in user tests, either -// directly or indirectly. -inline void SleepMilliseconds(int n) { - const timespec time = { - 0, // 0 seconds. - n * 1000L * 1000L, // And n ms. - }; - nanosleep(&time, nullptr); -} -# endif // GTEST_HAS_PTHREAD - -# if GTEST_HAS_NOTIFICATION_ -// Notification has already been imported into the namespace. -// Nothing to do here. - -# elif GTEST_HAS_PTHREAD -// Allows a controller thread to pause execution of newly created -// threads until notified. Instances of this class must be created -// and destroyed in the controller thread. -// -// This class is only for testing Google Test's own constructs. Do not -// use it in user tests, either directly or indirectly. -class Notification { - public: - Notification() : notified_(false) { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr)); - } - ~Notification() { - pthread_mutex_destroy(&mutex_); - } - - // Notifies all threads created with this notification to start. Must - // be called from the controller thread. - void Notify() { - pthread_mutex_lock(&mutex_); - notified_ = true; - pthread_mutex_unlock(&mutex_); - } - - // Blocks until the controller thread notifies. Must be called from a test - // thread. - void WaitForNotification() { - for (;;) { - pthread_mutex_lock(&mutex_); - const bool notified = notified_; - pthread_mutex_unlock(&mutex_); - if (notified) - break; - SleepMilliseconds(10); - } - } - - private: - pthread_mutex_t mutex_; - bool notified_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); -}; - -# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT - -GTEST_API_ void SleepMilliseconds(int n); +#if GTEST_OS_WINDOWS // Provides leak-safe Windows kernel handle ownership. // Used in death tests and in threading support. class GTEST_API_ AutoHandle { @@ -1253,8 +1190,18 @@ class GTEST_API_ AutoHandle { Handle handle_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); + AutoHandle(const AutoHandle&) = delete; + AutoHandle& operator=(const AutoHandle&) = delete; }; +#endif + +#if GTEST_HAS_NOTIFICATION_ +// Notification has already been imported into the namespace. +// Nothing to do here. + +#else +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) // Allows a controller thread to pause execution of newly created // threads until notified. Instances of this class must be created @@ -1262,23 +1209,40 @@ class GTEST_API_ AutoHandle { // // This class is only for testing Google Test's own constructs. Do not // use it in user tests, either directly or indirectly. +// TODO(b/203539622): Replace unconditionally with absl::Notification. class GTEST_API_ Notification { public: - Notification(); - void Notify(); - void WaitForNotification(); + Notification() : notified_(false) {} + Notification(const Notification&) = delete; + Notification& operator=(const Notification&) = delete; - private: - AutoHandle event_; + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { + std::lock_guard lock(mu_); + notified_ = true; + cv_.notify_all(); + } - GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + std::unique_lock lock(mu_); + cv_.wait(lock, [this]() { return notified_; }); + } + + private: + std::mutex mu_; + std::condition_variable cv_; + bool notified_; }; -# endif // GTEST_HAS_NOTIFICATION_ +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 +#endif // GTEST_HAS_NOTIFICATION_ // On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD // defined, but we don't want to use MinGW's pthreads implementation, which // has conformance problems with some versions of the POSIX standard. -# if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW +#if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW // As a C-function, ThreadFuncWithCLinkage cannot be templated itself. // Consequently, it cannot select a correct instantiation of ThreadWithParam @@ -1354,16 +1318,17 @@ class ThreadWithParam : public ThreadWithParamBase { // finished. pthread_t thread_; // The native thread object. - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); + ThreadWithParam(const ThreadWithParam&) = delete; + ThreadWithParam& operator=(const ThreadWithParam&) = delete; }; -# endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD || - // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ +#endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD || + // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ -# if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ +#if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ // Mutex and ThreadLocal have already been imported into the namespace. // Nothing to do here. -# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT +#elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // Mutex implements mutex on Windows platforms. It is used in conjunction // with class MutexLock: @@ -1417,14 +1382,15 @@ class GTEST_API_ Mutex { long critical_section_init_phase_; // NOLINT GTEST_CRITICAL_SECTION* critical_section_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; }; -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::Mutex mutex +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex -# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ - ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex) +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex) // We cannot name this class MutexLock because the ctor declaration would // conflict with a macro named MutexLock, which is defined on some @@ -1433,15 +1399,15 @@ class GTEST_API_ Mutex { // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: - explicit GTestMutexLock(Mutex* mutex) - : mutex_(mutex) { mutex_->Lock(); } + explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); } ~GTestMutexLock() { mutex_->Unlock(); } private: Mutex* const mutex_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); + GTestMutexLock(const GTestMutexLock&) = delete; + GTestMutexLock& operator=(const GTestMutexLock&) = delete; }; typedef GTestMutexLock MutexLock; @@ -1468,7 +1434,8 @@ class ThreadLocalBase { virtual ~ThreadLocalBase() {} private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalBase); + ThreadLocalBase(const ThreadLocalBase&) = delete; + ThreadLocalBase& operator=(const ThreadLocalBase&) = delete; }; // Maps a thread to a set of ThreadLocals that have values instantiated on that @@ -1497,7 +1464,7 @@ class GTEST_API_ ThreadWithParamBase { virtual void Run() = 0; }; - ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start); + ThreadWithParamBase(Runnable* runnable, Notification* thread_can_start); virtual ~ThreadWithParamBase(); private: @@ -1511,30 +1478,26 @@ class ThreadWithParam : public ThreadWithParamBase { typedef void UserThreadFunc(T); ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) - : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) { - } + : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {} virtual ~ThreadWithParam() {} private: class RunnableImpl : public Runnable { public: - RunnableImpl(UserThreadFunc* func, T param) - : func_(func), - param_(param) { - } + RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {} virtual ~RunnableImpl() {} - virtual void Run() { - func_(param_); - } + virtual void Run() { func_(param_); } private: UserThreadFunc* const func_; const T param_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(RunnableImpl); + RunnableImpl(const RunnableImpl&) = delete; + RunnableImpl& operator=(const RunnableImpl&) = delete; }; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); + ThreadWithParam(const ThreadWithParam&) = delete; + ThreadWithParam& operator=(const ThreadWithParam&) = delete; }; // Implements thread-local storage on Windows systems. @@ -1571,7 +1534,7 @@ class ThreadLocal : public ThreadLocalBase { explicit ThreadLocal(const T& value) : default_factory_(new InstanceValueHolderFactory(value)) {} - ~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } + ~ThreadLocal() override { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } T* pointer() { return GetOrCreateValue(); } const T* pointer() const { return GetOrCreateValue(); } @@ -1590,16 +1553,17 @@ class ThreadLocal : public ThreadLocalBase { private: T value_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + ValueHolder(const ValueHolder&) = delete; + ValueHolder& operator=(const ValueHolder&) = delete; }; - T* GetOrCreateValue() const { return static_cast( - ThreadLocalRegistry::GetValueOnCurrentThread(this))->pointer(); + ThreadLocalRegistry::GetValueOnCurrentThread(this)) + ->pointer(); } - virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const { + ThreadLocalValueHolderBase* NewValueForCurrentThread() const override { return default_factory_->MakeNewHolder(); } @@ -1610,7 +1574,8 @@ class ThreadLocal : public ThreadLocalBase { virtual ValueHolder* MakeNewHolder() const = 0; private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); + ValueHolderFactory(const ValueHolderFactory&) = delete; + ValueHolderFactory& operator=(const ValueHolderFactory&) = delete; }; class DefaultValueHolderFactory : public ValueHolderFactory { @@ -1619,7 +1584,9 @@ class ThreadLocal : public ThreadLocalBase { ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); + DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete; + DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) = + delete; }; class InstanceValueHolderFactory : public ValueHolderFactory { @@ -1632,15 +1599,18 @@ class ThreadLocal : public ThreadLocalBase { private: const T value_; // The value for each thread. - GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); + InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete; + InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) = + delete; }; std::unique_ptr default_factory_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); + ThreadLocal(const ThreadLocal&) = delete; + ThreadLocal& operator=(const ThreadLocal&) = delete; }; -# elif GTEST_HAS_PTHREAD +#elif GTEST_HAS_PTHREAD // MutexBase and Mutex implement mutex on pthreads-based platforms. class MutexBase { @@ -1687,8 +1657,8 @@ class MutexBase { }; // Forward-declares a static mutex. -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::MutexBase mutex +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. // The initialization list here does not explicitly initialize each field, @@ -1707,12 +1677,11 @@ class Mutex : public MutexBase { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr)); has_owner_ = false; } - ~Mutex() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); - } + ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); } private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; }; // We cannot name this class MutexLock because the ctor declaration would @@ -1722,15 +1691,15 @@ class Mutex : public MutexBase { // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: - explicit GTestMutexLock(MutexBase* mutex) - : mutex_(mutex) { mutex_->Lock(); } + explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); } ~GTestMutexLock() { mutex_->Unlock(); } private: MutexBase* const mutex_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); + GTestMutexLock(const GTestMutexLock&) = delete; + GTestMutexLock& operator=(const GTestMutexLock&) = delete; }; typedef GTestMutexLock MutexLock; @@ -1787,7 +1756,8 @@ class GTEST_API_ ThreadLocal { private: T value_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + ValueHolder(const ValueHolder&) = delete; + ValueHolder& operator=(const ValueHolder&) = delete; }; static pthread_key_t CreateKey() { @@ -1819,7 +1789,8 @@ class GTEST_API_ ThreadLocal { virtual ValueHolder* MakeNewHolder() const = 0; private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); + ValueHolderFactory(const ValueHolderFactory&) = delete; + ValueHolderFactory& operator=(const ValueHolderFactory&) = delete; }; class DefaultValueHolderFactory : public ValueHolderFactory { @@ -1828,7 +1799,9 @@ class GTEST_API_ ThreadLocal { ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); + DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete; + DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) = + delete; }; class InstanceValueHolderFactory : public ValueHolderFactory { @@ -1841,17 +1814,20 @@ class GTEST_API_ ThreadLocal { private: const T value_; // The value for each thread. - GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); + InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete; + InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) = + delete; }; // A key pthreads uses for looking up per-thread values. const pthread_key_t key_; std::unique_ptr default_factory_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); + ThreadLocal(const ThreadLocal&) = delete; + ThreadLocal& operator=(const ThreadLocal&) = delete; }; -# endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ +#endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ #else // GTEST_IS_THREADSAFE @@ -1868,10 +1844,10 @@ class Mutex { void AssertHeld() const {} }; -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::Mutex mutex -# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex // We cannot name this class MutexLock because the ctor declaration would // conflict with a macro named MutexLock, which is defined on some @@ -1894,6 +1870,7 @@ class GTEST_API_ ThreadLocal { const T* pointer() const { return &value_; } const T& get() const { return value_; } void set(const T& value) { value_ = value; } + private: T value_; }; @@ -1905,11 +1882,11 @@ class GTEST_API_ ThreadLocal { GTEST_API_ size_t GetThreadCount(); #if GTEST_OS_WINDOWS -# define GTEST_PATH_SEP_ "\\" -# define GTEST_HAS_ALT_PATH_SEP_ 1 +#define GTEST_PATH_SEP_ "\\" +#define GTEST_HAS_ALT_PATH_SEP_ 1 #else -# define GTEST_PATH_SEP_ "/" -# define GTEST_HAS_ALT_PATH_SEP_ 0 +#define GTEST_PATH_SEP_ "/" +#define GTEST_HAS_ALT_PATH_SEP_ 0 #endif // GTEST_OS_WINDOWS // Utilities for char. @@ -1967,8 +1944,7 @@ inline char ToUpper(char ch) { inline std::string StripTrailingSpaces(std::string str) { std::string::iterator it = str.end(); - while (it != str.begin() && IsSpace(*--it)) - it = str.erase(it); + while (it != str.begin() && IsSpace(*--it)) it = str.erase(it); return str; } @@ -1986,36 +1962,35 @@ namespace posix { typedef struct _stat StatStruct; -# ifdef __BORLANDC__ +#ifdef __BORLANDC__ inline int DoIsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } -# else // !__BORLANDC__ -# if GTEST_OS_WINDOWS_MOBILE +#else // !__BORLANDC__ +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \ + GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM) inline int DoIsATTY(int /* fd */) { return 0; } -# else +#else inline int DoIsATTY(int fd) { return _isatty(fd); } -# endif // GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } -# endif // __BORLANDC__ +#endif // __BORLANDC__ -# if GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS_MOBILE inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this // time and thus not defined there. -# else +#else inline int FileNo(FILE* file) { return _fileno(file); } inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } -inline bool IsDir(const StatStruct& st) { - return (_S_IFDIR & st.st_mode) != 0; -} -# endif // GTEST_OS_WINDOWS_MOBILE +inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } +#endif // GTEST_OS_WINDOWS_MOBILE #elif GTEST_OS_ESP8266 typedef struct stat StatStruct; @@ -2079,12 +2054,12 @@ inline FILE* FOpen(const char* path, const char* mode) { std::wstring wide_path = converter.from_bytes(path); std::wstring wide_mode = converter.from_bytes(mode); return _wfopen(wide_path.c_str(), wide_mode.c_str()); -#else // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW +#else // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW return fopen(path, mode); #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW } #if !GTEST_OS_WINDOWS_MOBILE -inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { +inline FILE* FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } @@ -2136,13 +2111,13 @@ GTEST_DISABLE_MSC_DEPRECATED_POP_() // snprintf is a variadic function. #if _MSC_VER && !GTEST_OS_WINDOWS_MOBILE // MSVC 2005 and above support variadic macros. -# define GTEST_SNPRINTF_(buffer, size, format, ...) \ - _snprintf_s(buffer, size, size, format, __VA_ARGS__) +#define GTEST_SNPRINTF_(buffer, size, format, ...) \ + _snprintf_s(buffer, size, size, format, __VA_ARGS__) #elif defined(_MSC_VER) // Windows CE does not define _snprintf_s -# define GTEST_SNPRINTF_ _snprintf +#define GTEST_SNPRINTF_ _snprintf #else -# define GTEST_SNPRINTF_ snprintf +#define GTEST_SNPRINTF_ snprintf #endif // The biggest signed integer type the compiler supports. @@ -2202,37 +2177,84 @@ using TimeInMillis = int64_t; // Represents time in milliseconds. // Macro for referencing flags. #if !defined(GTEST_FLAG) -# define GTEST_FLAG(name) FLAGS_gtest_##name +#define GTEST_FLAG_NAME_(name) gtest_##name +#define GTEST_FLAG(name) FLAGS_gtest_##name #endif // !defined(GTEST_FLAG) -#if !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) -# define GTEST_USE_OWN_FLAGFILE_FLAG_ 1 -#endif // !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) +// Pick a command line flags implementation. +#if GTEST_HAS_ABSL -#if !defined(GTEST_DECLARE_bool_) -# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + ABSL_FLAG(bool, GTEST_FLAG_NAME_(name), default_val, doc) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + ABSL_FLAG(int32_t, GTEST_FLAG_NAME_(name), default_val, doc) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + ABSL_FLAG(std::string, GTEST_FLAG_NAME_(name), default_val, doc) // Macros for declaring flags. -# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) -# define GTEST_DECLARE_int32_(name) \ - GTEST_API_ extern std::int32_t GTEST_FLAG(name) -# define GTEST_DECLARE_string_(name) \ - GTEST_API_ extern ::std::string GTEST_FLAG(name) +#define GTEST_DECLARE_bool_(name) \ + ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name)) +#define GTEST_DECLARE_int32_(name) \ + ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name)) +#define GTEST_DECLARE_string_(name) \ + ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name)) + +#define GTEST_FLAG_SAVER_ ::absl::FlagSaver + +#define GTEST_FLAG_GET(name) ::absl::GetFlag(GTEST_FLAG(name)) +#define GTEST_FLAG_SET(name, value) \ + (void)(::absl::SetFlag(>EST_FLAG(name), value)) +#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0 + +#else // GTEST_HAS_ABSL // Macros for defining flags. -# define GTEST_DEFINE_bool_(name, default_val, doc) \ - GTEST_API_ bool GTEST_FLAG(name) = (default_val) -# define GTEST_DEFINE_int32_(name, default_val, doc) \ - GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val) -# define GTEST_DEFINE_string_(name, default_val, doc) \ - GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + namespace testing { \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val); \ + } \ + static_assert(true, "no-op to require trailing semicolon") +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + namespace testing { \ + GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \ + } \ + static_assert(true, "no-op to require trailing semicolon") +#define GTEST_DEFINE_string_(name, default_val, doc) \ + namespace testing { \ + GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \ + } \ + static_assert(true, "no-op to require trailing semicolon") -#endif // !defined(GTEST_DECLARE_bool_) +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) \ + namespace testing { \ + GTEST_API_ extern bool GTEST_FLAG(name); \ + } \ + static_assert(true, "no-op to require trailing semicolon") +#define GTEST_DECLARE_int32_(name) \ + namespace testing { \ + GTEST_API_ extern std::int32_t GTEST_FLAG(name); \ + } \ + static_assert(true, "no-op to require trailing semicolon") +#define GTEST_DECLARE_string_(name) \ + namespace testing { \ + GTEST_API_ extern ::std::string GTEST_FLAG(name); \ + } \ + static_assert(true, "no-op to require trailing semicolon") + +#define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver + +#define GTEST_FLAG_GET(name) ::testing::GTEST_FLAG(name) +#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value) +#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1 + +#endif // GTEST_HAS_ABSL // Thread annotations #if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) -# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) -# define GTEST_LOCK_EXCLUDED_(locks) +#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +#define GTEST_LOCK_EXCLUDED_(locks) #endif // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) // Parses 'str' for a 32-bit signed integer. If successful, writes the result @@ -2308,6 +2330,7 @@ namespace testing { namespace internal { template using Optional = ::absl::optional; +inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; } } // namespace internal } // namespace testing #else @@ -2321,6 +2344,7 @@ namespace testing { namespace internal { template using Optional = ::std::optional; +inline ::std::nullopt_t Nullopt() { return ::std::nullopt; } } // namespace internal } // namespace testing // The case where absl is configured NOT to alias std::optional is not @@ -2332,7 +2356,7 @@ using Optional = ::std::optional; #if GTEST_HAS_ABSL // Always use absl::string_view for Matcher<> specializations if googletest // is built with absl support. -# define GTEST_INTERNAL_HAS_STRING_VIEW 1 +#define GTEST_INTERNAL_HAS_STRING_VIEW 1 #include "absl/strings/string_view.h" namespace testing { namespace internal { @@ -2340,11 +2364,11 @@ using StringView = ::absl::string_view; } // namespace internal } // namespace testing #else -# ifdef __has_include -# if __has_include() && __cplusplus >= 201703L +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L // Otherwise for C++17 and higher use std::string_view for Matcher<> // specializations. -# define GTEST_INTERNAL_HAS_STRING_VIEW 1 +#define GTEST_INTERNAL_HAS_STRING_VIEW 1 #include namespace testing { namespace internal { @@ -2353,8 +2377,8 @@ using StringView = ::std::string_view; } // namespace testing // The case where absl is configured NOT to alias std::string_view is not // supported. -# endif // __has_include() && __cplusplus >= 201703L -# endif // __has_include +#endif // __has_include() && __cplusplus >= 201703L +#endif // __has_include #endif // GTEST_HAS_ABSL #if GTEST_HAS_ABSL diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-string.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-string.h index 10f774f966..cca2e1f2ad 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-string.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-string.h @@ -26,7 +26,7 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// + // The Google C++ Testing and Mocking Framework (Google Test) // // This header file declares the String class and functions used internally by @@ -36,17 +36,20 @@ // This header file is #included by gtest-internal.h. // It should not be #included by other files. -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #ifdef __BORLANDC__ // string.h is not guaranteed to provide strcpy on C++ Builder. -# include +#include #endif #include + #include #include @@ -123,8 +126,7 @@ class GTEST_API_ String { // Unlike strcasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL C string, // including the empty string. - static bool CaseInsensitiveCStringEquals(const char* lhs, - const char* rhs); + static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs); // Compares two wide C strings, ignoring case. Returns true if and only if // they have the same content. @@ -143,8 +145,8 @@ class GTEST_API_ String { // Returns true if and only if the given string ends with the given suffix, // ignoring case. Any string is considered to end with an empty suffix. - static bool EndsWithCaseInsensitive( - const std::string& str, const std::string& suffix); + static bool EndsWithCaseInsensitive(const std::string& str, + const std::string& suffix); // Formats an int value as "%02d". static std::string FormatIntWidth2(int value); // "%02d" for width == 2 @@ -163,7 +165,7 @@ class GTEST_API_ String { private: String(); // Not meant to be instantiated. -}; // class String +}; // class String // Gets the content of the stringstream's buffer as an std::string. Each '\0' // character in the buffer is replaced with "\\0". diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-type-util.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-type-util.h index b87a2e2cac..6bc02a7de3 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-type-util.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/include/gtest/internal/gtest-type-util.h @@ -30,7 +30,9 @@ // Type utilities needed for implementing typed and type-parameterized // tests. -// GOOGLETEST_CM0001 DO NOT DELETE +// IWYU pragma: private, include "gtest/gtest.h" +// IWYU pragma: friend gtest/.* +// IWYU pragma: friend gmock/.* #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ @@ -39,11 +41,11 @@ // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). -# if GTEST_HAS_CXXABI_H_ -# include -# elif defined(__HP_aCC) -# include -# endif // GTEST_HASH_CXXABI_H_ +#if GTEST_HAS_CXXABI_H_ +#include +#elif defined(__HP_aCC) +#include +#endif // GTEST_HASH_CXXABI_H_ namespace testing { namespace internal { @@ -101,7 +103,9 @@ std::string GetTypeName() { // A unique type indicating an empty node struct None {}; -# define GTEST_TEMPLATE_ template class +#define GTEST_TEMPLATE_ \ + template \ + class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type @@ -119,8 +123,7 @@ struct TemplateSel { }; }; -# define GTEST_BIND_(TmplSel, T) \ - TmplSel::template Bind::type +#define GTEST_BIND_(TmplSel, T) TmplSel::template Bind::type template struct Templates { diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-all.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-all.cc index ad292905cf..2a70ed88c7 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-all.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-all.cc @@ -38,7 +38,7 @@ #include "gtest/gtest.h" // The following lines pull in the real gtest *.cc files. -#include "src/gtest.cc" +#include "src/gtest-assertion-result.cc" #include "src/gtest-death-test.cc" #include "src/gtest-filepath.cc" #include "src/gtest-matchers.cc" @@ -46,3 +46,4 @@ #include "src/gtest-printers.cc" #include "src/gtest-test-part.cc" #include "src/gtest-typed-test.cc" +#include "src/gtest.cc" diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-assertion-result.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-assertion-result.cc new file mode 100644 index 0000000000..f1c0b10dc9 --- /dev/null +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-assertion-result.cc @@ -0,0 +1,77 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The Google C++ Testing and Mocking Framework (Google Test) +// +// This file defines the AssertionResult type. + +#include "gtest/gtest-assertion-result.h" + +#include +#include + +#include "gtest/gtest-message.h" + +namespace testing { + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != nullptr + ? new ::std::string(*other.message_) + : static_cast< ::std::string*>(nullptr)) {} + +// Swaps two AssertionResults. +void AssertionResult::swap(AssertionResult& other) { + using std::swap; + swap(success_, other.success_); + swap(message_, other.message_); +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != nullptr) negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { return AssertionResult(true); } + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { return AssertionResult(false); } + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +} // namespace testing diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-death-test.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-death-test.cc index bf4f6331da..e6abc6278a 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-death-test.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-death-test.cc @@ -35,49 +35,49 @@ #include #include -#include "gtest/internal/gtest-port.h" #include "gtest/internal/custom/gtest.h" +#include "gtest/internal/gtest-port.h" #if GTEST_HAS_DEATH_TEST -# if GTEST_OS_MAC -# include -# endif // GTEST_OS_MAC - -# include -# include -# include - -# if GTEST_OS_LINUX -# include -# endif // GTEST_OS_LINUX - -# include - -# if GTEST_OS_WINDOWS -# include -# else -# include -# include -# endif // GTEST_OS_WINDOWS - -# if GTEST_OS_QNX -# include -# endif // GTEST_OS_QNX - -# if GTEST_OS_FUCHSIA -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# endif // GTEST_OS_FUCHSIA +#if GTEST_OS_MAC +#include +#endif // GTEST_OS_MAC + +#include +#include +#include + +#if GTEST_OS_LINUX +#include +#endif // GTEST_OS_LINUX + +#include + +#if GTEST_OS_WINDOWS +#include +#else +#include +#include +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_QNX +#include +#endif // GTEST_OS_QNX + +#if GTEST_OS_FUCHSIA +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // GTEST_OS_FUCHSIA #endif // GTEST_HAS_DEATH_TEST @@ -96,9 +96,12 @@ namespace testing { // used internally at Google, is "threadsafe". static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE; +} // namespace testing + GTEST_DEFINE_string_( death_test_style, - internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + testing::internal::StringFromGTestEnv("death_test_style", + testing::kDefaultDeathTestStyle), "Indicates how to run a death test in a forked child process: " "\"threadsafe\" (child process re-executes the test binary " "from the beginning, running only the specific death test) or " @@ -107,7 +110,7 @@ GTEST_DEFINE_string_( GTEST_DEFINE_bool_( death_test_use_fork, - internal::BoolFromGTestEnv("death_test_use_fork", false), + testing::internal::BoolFromGTestEnv("death_test_use_fork", false), "Instructs to use fork()/_exit() instead of clone() in death tests. " "Ignored and always uses fork() on POSIX systems where clone() is not " "implemented. Useful when running under valgrind or similar tools if " @@ -117,7 +120,6 @@ GTEST_DEFINE_bool_( "work in 99% of the cases. Once valgrind is fixed, this flag will " "most likely be removed."); -namespace internal { GTEST_DEFINE_string_( internal_run_death_test, "", "Indicates the file, line number, temporal index of " @@ -126,7 +128,8 @@ GTEST_DEFINE_string_( "the '|' characters. This flag is specified if and only if the " "current process is a sub-process launched for running a thread-safe " "death test. FOR INTERNAL USE ONLY."); -} // namespace internal + +namespace testing { #if GTEST_HAS_DEATH_TEST @@ -134,9 +137,9 @@ namespace internal { // Valid only for fast death tests. Indicates the code is running in the // child process of a fast style death test. -# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA static bool g_in_fast_death_test_child = false; -# endif +#endif // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as @@ -144,16 +147,16 @@ static bool g_in_fast_death_test_child = false; // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. bool InDeathTestChild() { -# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA +#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA // On Windows and Fuchsia, death tests are thread-safe regardless of the value // of the death_test_style flag. - return !GTEST_FLAG(internal_run_death_test).empty(); + return !GTEST_FLAG_GET(internal_run_death_test).empty(); -# else +#else - if (GTEST_FLAG(death_test_style) == "threadsafe") - return !GTEST_FLAG(internal_run_death_test).empty(); + if (GTEST_FLAG_GET(death_test_style) == "threadsafe") + return !GTEST_FLAG_GET(internal_run_death_test).empty(); else return g_in_fast_death_test_child; #endif @@ -162,40 +165,38 @@ bool InDeathTestChild() { } // namespace internal // ExitedWithCode constructor. -ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { -} +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {} // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { -# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA +#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA return exit_status == exit_code_; -# else +#else return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; -# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA +#endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA } -# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA // KilledBySignal constructor. -KilledBySignal::KilledBySignal(int signum) : signum_(signum) { -} +KilledBySignal::KilledBySignal(int signum) : signum_(signum) {} // KilledBySignal function-call operator. bool KilledBySignal::operator()(int exit_status) const { -# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) +#if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) { bool result; if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { return result; } } -# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) +#endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } -# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +#endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA namespace internal { @@ -206,23 +207,23 @@ namespace internal { static std::string ExitSummary(int exit_code) { Message m; -# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA +#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA m << "Exited with exit status " << exit_code; -# else +#else if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { m << "Terminated by signal " << WTERMSIG(exit_code); } -# ifdef WCOREDUMP +#ifdef WCOREDUMP if (WCOREDUMP(exit_code)) { m << " (core dumped)"; } -# endif -# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA +#endif +#endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA return m.GetString(); } @@ -233,7 +234,7 @@ bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } -# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the @@ -254,7 +255,7 @@ static std::string DeathTestThreadWarning(size_t thread_count) { << " this is the last message you see before your test times out."; return msg.GetString(); } -# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA +#endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; @@ -304,14 +305,14 @@ static void DeathTestAbort(const std::string& message) { // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. -# define GTEST_DEATH_TEST_CHECK_(expression) \ - do { \ - if (!::testing::internal::IsTrue(expression)) { \ - DeathTestAbort( \ - ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ - + ::testing::internal::StreamableToString(__LINE__) + ": " \ - + #expression); \ - } \ +#define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::std::string("CHECK failed: File ") + __FILE__ + \ + ", line " + \ + ::testing::internal::StreamableToString(__LINE__) + \ + ": " + #expression); \ + } \ } while (::testing::internal::AlwaysFalse()) // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for @@ -321,23 +322,23 @@ static void DeathTestAbort(const std::string& message) { // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. -# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ - do { \ - int gtest_retval; \ - do { \ - gtest_retval = (expression); \ - } while (gtest_retval == -1 && errno == EINTR); \ - if (gtest_retval == -1) { \ - DeathTestAbort( \ - ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ - + ::testing::internal::StreamableToString(__LINE__) + ": " \ - + #expression + " != -1"); \ - } \ +#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::std::string("CHECK failed: File ") + __FILE__ + \ + ", line " + \ + ::testing::internal::StreamableToString(__LINE__) + \ + ": " + #expression + " != -1"); \ + } \ } while (::testing::internal::AlwaysFalse()) // Returns the message describing the last system error in errno. std::string GetLastErrnoDescription() { - return errno == 0 ? "" : posix::StrError(errno); + return errno == 0 ? "" : posix::StrError(errno); } // This is called from a death test parent process to read a failure @@ -370,8 +371,9 @@ static void FailFromInternalError(int fd) { DeathTest::DeathTest() { TestInfo* const info = GetUnitTestImpl()->current_test_info(); if (info == nullptr) { - DeathTestAbort("Cannot run a death test outside of a TEST or " - "TEST_F construct"); + DeathTestAbort( + "Cannot run a death test outside of a TEST or " + "TEST_F construct"); } } @@ -500,9 +502,7 @@ void DeathTestImpl::ReadAndInterpretStatusByte() { set_read_fd(-1); } -std::string DeathTestImpl::GetErrorLogs() { - return GetCapturedStderr(); -} +std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); } // Signals that the death test code which should have exited, didn't. // Should be called only in a death test child process. @@ -512,9 +512,9 @@ void DeathTestImpl::Abort(AbortReason reason) { // The parent process considers the death test to be a failure if // it finds any data in our pipe. So, here we write a single flag byte // to the pipe, then exit. - const char status_ch = - reason == TEST_DID_NOT_DIE ? kDeathTestLived : - reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + const char status_ch = reason == TEST_DID_NOT_DIE ? kDeathTestLived + : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew + : kDeathTestReturned; GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); // We are leaking the descriptor here because on some platforms (i.e., @@ -533,7 +533,7 @@ void DeathTestImpl::Abort(AbortReason reason) { // much easier. static ::std::string FormatDeathTestOutput(const ::std::string& output) { ::std::string ret; - for (size_t at = 0; ; ) { + for (size_t at = 0;;) { const size_t line_end = output.find('\n', at); ret += "[ DEATH ] "; if (line_end == ::std::string::npos) { @@ -568,8 +568,7 @@ static ::std::string FormatDeathTestOutput(const ::std::string& output) { // the first failing condition, in the order given above, is the one that is // reported. Also sets the last death test message string. bool DeathTestImpl::Passed(bool status_ok) { - if (!spawned()) - return false; + if (!spawned()) return false; const std::string error_message = GetErrorLogs(); @@ -580,15 +579,18 @@ bool DeathTestImpl::Passed(bool status_ok) { switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); + << " Error msg:\n" + << FormatDeathTestOutput(error_message); break; case THREW: buffer << " Result: threw an exception.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); + << " Error msg:\n" + << FormatDeathTestOutput(error_message); break; case RETURNED: buffer << " Result: illegal return in test statement.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); + << " Error msg:\n" + << FormatDeathTestOutput(error_message); break; case DIED: if (status_ok) { @@ -605,7 +607,8 @@ bool DeathTestImpl::Passed(bool status_ok) { } else { buffer << " Result: died but not with expected exit code:\n" << " " << ExitSummary(status()) << "\n" - << "Actual msg:\n" << FormatDeathTestOutput(error_message); + << "Actual msg:\n" + << FormatDeathTestOutput(error_message); } break; case IN_PROGRESS: @@ -618,7 +621,7 @@ bool DeathTestImpl::Passed(bool status_ok) { return success; } -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // WindowsDeathTest implements death tests on Windows. Due to the // specifics of starting new processes on Windows, death tests there are // always threadsafe, and Google Test considers the @@ -679,14 +682,12 @@ class WindowsDeathTest : public DeathTestImpl { // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int WindowsDeathTest::Wait() { - if (!spawned()) - return 0; + if (!spawned()) return 0; // Wait until the child either signals that it has acquired the write end // of the pipe or it dies. - const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; - switch (::WaitForMultipleObjects(2, - wait_handles, + const HANDLE wait_handles[2] = {child_handle_.Get(), event_handle_.Get()}; + switch (::WaitForMultipleObjects(2, wait_handles, FALSE, // Waits for any of the handles. INFINITE)) { case WAIT_OBJECT_0: @@ -707,9 +708,8 @@ int WindowsDeathTest::Wait() { // returns immediately if the child has already exited, regardless of // whether previous calls to WaitForMultipleObjects synchronized on this // handle or not. - GTEST_DEATH_TEST_CHECK_( - WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), - INFINITE)); + GTEST_DEATH_TEST_CHECK_(WAIT_OBJECT_0 == + ::WaitForSingleObject(child_handle_.Get(), INFINITE)); DWORD status_code; GTEST_DEATH_TEST_CHECK_( ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); @@ -742,12 +742,12 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() { SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE}; HANDLE read_handle, write_handle; - GTEST_DEATH_TEST_CHECK_( - ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, - 0) // Default buffer size. - != FALSE); - set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), - O_RDONLY)); + GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle, + &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd( + ::_open_osfhandle(reinterpret_cast(read_handle), O_RDONLY)); write_handle_.Reset(write_handle); event_handle_.Reset(::CreateEvent( &handles_are_inheritable, @@ -756,27 +756,26 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() { nullptr)); // The even is unnamed. GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + - kFilterFlag + "=" + info->test_suite_name() + - "." + info->name(); + "filter=" + info->test_suite_name() + "." + + info->name(); const std::string internal_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + - "=" + file_ + "|" + StreamableToString(line_) + "|" + - StreamableToString(death_test_index) + "|" + + std::string("--") + GTEST_FLAG_PREFIX_ + + "internal_run_death_test=" + file_ + "|" + StreamableToString(line_) + + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(static_cast(::GetCurrentProcessId())) + // size_t has the same width as pointers on both 32-bit and 64-bit // Windows platforms. // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. - "|" + StreamableToString(reinterpret_cast(write_handle)) + - "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); + "|" + StreamableToString(reinterpret_cast(write_handle)) + "|" + + StreamableToString(reinterpret_cast(event_handle_.Get())); char executable_path[_MAX_PATH + 1]; // NOLINT GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr, executable_path, _MAX_PATH)); - std::string command_line = - std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + - internal_flag + "\""; + std::string command_line = std::string(::GetCommandLineA()) + " " + + filter_flag + " \"" + internal_flag + "\""; DeathTest::set_last_death_test_message(""); @@ -796,8 +795,8 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() { GTEST_DEATH_TEST_CHECK_( ::CreateProcessA( executable_path, const_cast(command_line.c_str()), - nullptr, // Retuned process handle is not inheritable. - nullptr, // Retuned thread handle is not inheritable. + nullptr, // Returned process handle is not inheritable. + nullptr, // Returned thread handle is not inheritable. TRUE, // Child inherits all inheritable handles (for write_handle_). 0x0, // Default creation flags. nullptr, // Inherit the parent's environment. @@ -809,7 +808,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() { return OVERSEE_TEST; } -# elif GTEST_OS_FUCHSIA +#elif GTEST_OS_FUCHSIA class FuchsiaDeathTest : public DeathTestImpl { public: @@ -855,18 +854,13 @@ class Arguments { template void AddArguments(const ::std::vector& arguments) { for (typename ::std::vector::const_iterator i = arguments.begin(); - i != arguments.end(); - ++i) { + i != arguments.end(); ++i) { args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } - char* const* Argv() { - return &args_[0]; - } + char* const* Argv() { return &args_[0]; } - int size() { - return static_cast(args_.size()) - 1; - } + int size() { return static_cast(args_.size()) - 1; } private: std::vector args_; @@ -880,8 +874,7 @@ int FuchsiaDeathTest::Wait() { const int kSocketKey = 1; const int kExceptionKey = 2; - if (!spawned()) - return 0; + if (!spawned()) return 0; // Create a port to wait for socket/task/exception events. zx_status_t status_zx; @@ -890,8 +883,8 @@ int FuchsiaDeathTest::Wait() { GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); // Register to wait for the child process to terminate. - status_zx = child_process_.wait_async( - port, kProcessKey, ZX_PROCESS_TERMINATED, 0); + status_zx = + child_process_.wait_async(port, kProcessKey, ZX_PROCESS_TERMINATED, 0); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); // Register to wait for the socket to be readable or closed. @@ -900,8 +893,8 @@ int FuchsiaDeathTest::Wait() { GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); // Register to wait for an exception. - status_zx = exception_channel_.wait_async( - port, kExceptionKey, ZX_CHANNEL_READABLE, 0); + status_zx = exception_channel_.wait_async(port, kExceptionKey, + ZX_CHANNEL_READABLE, 0); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); bool process_terminated = false; @@ -931,9 +924,9 @@ int FuchsiaDeathTest::Wait() { size_t old_length = captured_stderr_.length(); size_t bytes_read = 0; captured_stderr_.resize(old_length + kBufferSize); - status_zx = stderr_socket_.read( - 0, &captured_stderr_.front() + old_length, kBufferSize, - &bytes_read); + status_zx = + stderr_socket_.read(0, &captured_stderr_.front() + old_length, + kBufferSize, &bytes_read); captured_stderr_.resize(old_length + bytes_read); } while (status_zx == ZX_OK); if (status_zx == ZX_ERR_PEER_CLOSED) { @@ -987,13 +980,12 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { // Build the child process command line. const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + - kFilterFlag + "=" + info->test_suite_name() + - "." + info->name(); - const std::string internal_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" - + file_ + "|" - + StreamableToString(line_) + "|" - + StreamableToString(death_test_index); + "filter=" + info->test_suite_name() + "." + + info->name(); + const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + + kInternalRunDeathTestFlag + "=" + file_ + + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index); Arguments args; args.AddArguments(GetInjectableArgvs()); args.AddArgument(filter_flag.c_str()); @@ -1016,8 +1008,7 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { // Create a socket pair will be used to receive the child process' stderr. zx::socket stderr_producer_socket; - status = - zx::socket::create(0, &stderr_producer_socket, &stderr_socket_); + status = zx::socket::create(0, &stderr_producer_socket, &stderr_socket_); GTEST_DEATH_TEST_CHECK_(status >= 0); int stderr_producer_fd = -1; status = @@ -1034,35 +1025,32 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { // Create a child job. zx_handle_t child_job = ZX_HANDLE_INVALID; - status = zx_job_create(zx_job_default(), 0, & child_job); + status = zx_job_create(zx_job_default(), 0, &child_job); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); zx_policy_basic_t policy; policy.condition = ZX_POL_NEW_ANY; policy.policy = ZX_POL_ACTION_ALLOW; - status = zx_job_set_policy( - child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, &policy, 1); + status = zx_job_set_policy(child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, + &policy, 1); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); // Create an exception channel attached to the |child_job|, to allow // us to suppress the system default exception handler from firing. - status = - zx_task_create_exception_channel( - child_job, 0, exception_channel_.reset_and_get_address()); + status = zx_task_create_exception_channel( + child_job, 0, exception_channel_.reset_and_get_address()); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); // Spawn the child process. - status = fdio_spawn_etc( - child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], args.Argv(), nullptr, - 2, spawn_actions, child_process_.reset_and_get_address(), nullptr); + status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], + args.Argv(), nullptr, 2, spawn_actions, + child_process_.reset_and_get_address(), nullptr); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); set_spawned(true); return OVERSEE_TEST; } -std::string FuchsiaDeathTest::GetErrorLogs() { - return captured_stderr_; -} +std::string FuchsiaDeathTest::GetErrorLogs() { return captured_stderr_; } #else // We are neither on Windows, nor on Fuchsia. @@ -1093,8 +1081,7 @@ ForkingDeathTest::ForkingDeathTest(const char* a_statement, // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int ForkingDeathTest::Wait() { - if (!spawned()) - return 0; + if (!spawned()) return 0; ReadAndInterpretStatusByte(); @@ -1173,11 +1160,11 @@ class ExecDeathTest : public ForkingDeathTest { private: static ::std::vector GetArgvsForDeathTestChildProcess() { ::std::vector args = GetInjectableArgvs(); -# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) +#if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) ::std::vector extra_args = GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); args.insert(args.end(), extra_args.begin(), extra_args.end()); -# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) +#endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) return args; } // The name of the file in which the death test is located. @@ -1204,14 +1191,11 @@ class Arguments { template void AddArguments(const ::std::vector& arguments) { for (typename ::std::vector::const_iterator i = arguments.begin(); - i != arguments.end(); - ++i) { + i != arguments.end(); ++i) { args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } - char* const* Argv() { - return &args_[0]; - } + char* const* Argv() { return &args_[0]; } private: std::vector args_; @@ -1224,9 +1208,9 @@ struct ExecDeathTestArgs { int close_fd; // File descriptor to close; the read end of a pipe }; -# if GTEST_OS_QNX +#if GTEST_OS_QNX extern "C" char** environ; -# else // GTEST_OS_QNX +#else // GTEST_OS_QNX // The main function for a threadsafe-style death test child process. // This function is called in a clone()-ed process and thus must avoid // any potentially unsafe operations like malloc or libc functions. @@ -1241,8 +1225,8 @@ static int ExecDeathTestChildMain(void* child_arg) { UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { - DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + - GetLastErrnoDescription()); + DeathTestAbort(std::string("chdir(\"") + original_dir + + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } @@ -1253,13 +1237,12 @@ static int ExecDeathTestChildMain(void* child_arg) { // one path separator. execv(args->argv[0], args->argv); DeathTestAbort(std::string("execv(") + args->argv[0] + ", ...) in " + - original_dir + " failed: " + - GetLastErrnoDescription()); + original_dir + " failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } -# endif // GTEST_OS_QNX +#endif // GTEST_OS_QNX -# if GTEST_HAS_CLONE +#if GTEST_HAS_CLONE // Two utility routines that together determine the direction the stack // grows. // This could be accomplished more elegantly by a single recursive @@ -1293,7 +1276,7 @@ static bool StackGrowsDown() { StackLowerThanAddress(&dummy, &result); return result; } -# endif // GTEST_HAS_CLONE +#endif // GTEST_HAS_CLONE // Spawns a child process with the same executable as the current process in // a thread-safe manner and instructs it to run the death test. The @@ -1303,10 +1286,10 @@ static bool StackGrowsDown() { // spawn(2) there instead. The function dies with an error message if // anything goes wrong. static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { - ExecDeathTestArgs args = { argv, close_fd }; + ExecDeathTestArgs args = {argv, close_fd}; pid_t child_pid = -1; -# if GTEST_OS_QNX +#if GTEST_OS_QNX // Obtains the current directory and sets it to be closed in the child // process. const int cwd_fd = open(".", O_RDONLY); @@ -1319,16 +1302,16 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { - DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + - GetLastErrnoDescription()); + DeathTestAbort(std::string("chdir(\"") + original_dir + + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } int fd_flags; // Set close_fd to be closed after spawn. GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); - GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, - fd_flags | FD_CLOEXEC)); + GTEST_DEATH_TEST_CHECK_SYSCALL_( + fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC)); struct inheritance inherit = {0}; // spawn is a system call. child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ); @@ -1336,8 +1319,8 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); -# else // GTEST_OS_QNX -# if GTEST_OS_LINUX +#else // GTEST_OS_QNX +#if GTEST_OS_LINUX // When a SIGPROF signal is received while fork() or clone() are executing, // the process may hang. To avoid this, we ignore SIGPROF here and re-enable // it after the call to fork()/clone() is complete. @@ -1346,12 +1329,12 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); sigemptyset(&ignore_sigprof_action.sa_mask); ignore_sigprof_action.sa_handler = SIG_IGN; - GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( - SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); -# endif // GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +#endif // GTEST_OS_LINUX -# if GTEST_HAS_CLONE - const bool use_fork = GTEST_FLAG(death_test_use_fork); +#if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG_GET(death_test_use_fork); if (!use_fork) { static const bool stack_grows_down = StackGrowsDown(); @@ -1370,7 +1353,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { const size_t kMaxStackAlignment = 64; void* const stack_top = static_cast(stack) + - (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); GTEST_DEATH_TEST_CHECK_( static_cast(stack_size) > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0); @@ -1379,19 +1362,19 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); } -# else +#else const bool use_fork = true; -# endif // GTEST_HAS_CLONE +#endif // GTEST_HAS_CLONE if (use_fork && (child_pid = fork()) == 0) { - ExecDeathTestChildMain(&args); - _exit(0); + ExecDeathTestChildMain(&args); + _exit(0); } -# endif // GTEST_OS_QNX -# if GTEST_OS_LINUX +#endif // GTEST_OS_QNX +#if GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_SYSCALL_( sigaction(SIGPROF, &saved_sigprof_action, nullptr)); -# endif // GTEST_OS_LINUX +#endif // GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_(child_pid != -1); return child_pid; @@ -1420,13 +1403,13 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + - kFilterFlag + "=" + info->test_suite_name() + - "." + info->name(); - const std::string internal_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" - + file_ + "|" + StreamableToString(line_) + "|" - + StreamableToString(death_test_index) + "|" - + StreamableToString(pipe_fd[1]); + "filter=" + info->test_suite_name() + "." + + info->name(); + const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + + "internal_run_death_test=" + file_ + "|" + + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(pipe_fd[1]); Arguments args; args.AddArguments(GetArgvsForDeathTestChildProcess()); args.AddArgument(filter_flag.c_str()); @@ -1447,7 +1430,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { return OVERSEE_TEST; } -# endif // !GTEST_OS_WINDOWS +#endif // !GTEST_OS_WINDOWS // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to @@ -1461,15 +1444,15 @@ bool DefaultDeathTestFactory::Create(const char* statement, UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); - const int death_test_index = impl->current_test_info() - ->increment_death_test_count(); + const int death_test_index = + impl->current_test_info()->increment_death_test_count(); if (flag != nullptr) { if (death_test_index > flag->index()) { DeathTest::set_last_death_test_message( - "Death test count (" + StreamableToString(death_test_index) - + ") somehow exceeded expected maximum (" - + StreamableToString(flag->index()) + ")"); + "Death test count (" + StreamableToString(death_test_index) + + ") somehow exceeded expected maximum (" + + StreamableToString(flag->index()) + ")"); return false; } @@ -1480,50 +1463,50 @@ bool DefaultDeathTestFactory::Create(const char* statement, } } -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS - if (GTEST_FLAG(death_test_style) == "threadsafe" || - GTEST_FLAG(death_test_style) == "fast") { + if (GTEST_FLAG_GET(death_test_style) == "threadsafe" || + GTEST_FLAG_GET(death_test_style) == "fast") { *test = new WindowsDeathTest(statement, std::move(matcher), file, line); } -# elif GTEST_OS_FUCHSIA +#elif GTEST_OS_FUCHSIA - if (GTEST_FLAG(death_test_style) == "threadsafe" || - GTEST_FLAG(death_test_style) == "fast") { + if (GTEST_FLAG_GET(death_test_style) == "threadsafe" || + GTEST_FLAG_GET(death_test_style) == "fast") { *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line); } -# else +#else - if (GTEST_FLAG(death_test_style) == "threadsafe") { + if (GTEST_FLAG_GET(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, std::move(matcher), file, line); - } else if (GTEST_FLAG(death_test_style) == "fast") { + } else if (GTEST_FLAG_GET(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, std::move(matcher)); } -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS else { // NOLINT - this is more readable than unbalanced brackets inside #if. - DeathTest::set_last_death_test_message( - "Unknown death test style \"" + GTEST_FLAG(death_test_style) - + "\" encountered"); + DeathTest::set_last_death_test_message("Unknown death test style \"" + + GTEST_FLAG_GET(death_test_style) + + "\" encountered"); return false; } return true; } -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Recreates the pipe and event handles from the provided parameters, // signals the event, and returns a file descriptor wrapped around the pipe // handle. This function is called in the child process only. static int GetStatusFileDescriptor(unsigned int parent_process_id, - size_t write_handle_as_size_t, - size_t event_handle_as_size_t) { + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, - FALSE, // Non-inheritable. - parent_process_id)); + FALSE, // Non-inheritable. + parent_process_id)); if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { DeathTestAbort("Unable to open parent process " + StreamableToString(parent_process_id)); @@ -1531,8 +1514,7 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id, GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); - const HANDLE write_handle = - reinterpret_cast(write_handle_as_size_t); + const HANDLE write_handle = reinterpret_cast(write_handle_as_size_t); HANDLE dup_write_handle; // The newly initialized handle is accessible only in the parent @@ -1554,9 +1536,7 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id, HANDLE dup_event_handle; if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, - ::GetCurrentProcess(), &dup_event_handle, - 0x0, - FALSE, + ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE, DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the event handle " + StreamableToString(event_handle_as_size_t) + @@ -1578,61 +1558,57 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id, return write_fd; } -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { - if (GTEST_FLAG(internal_run_death_test) == "") return nullptr; + if (GTEST_FLAG_GET(internal_run_death_test) == "") return nullptr; // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // can use it here. int line = -1; int index = -1; ::std::vector< ::std::string> fields; - SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields); int write_fd = -1; -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS unsigned int parent_process_id = 0; size_t write_handle_as_size_t = 0; size_t event_handle_as_size_t = 0; - if (fields.size() != 6 - || !ParseNaturalNumber(fields[1], &line) - || !ParseNaturalNumber(fields[2], &index) - || !ParseNaturalNumber(fields[3], &parent_process_id) - || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) - || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) || + !ParseNaturalNumber(fields[2], &index) || + !ParseNaturalNumber(fields[3], &parent_process_id) || + !ParseNaturalNumber(fields[4], &write_handle_as_size_t) || + !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + - GTEST_FLAG(internal_run_death_test)); + GTEST_FLAG_GET(internal_run_death_test)); } - write_fd = GetStatusFileDescriptor(parent_process_id, - write_handle_as_size_t, + write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t, event_handle_as_size_t); -# elif GTEST_OS_FUCHSIA +#elif GTEST_OS_FUCHSIA - if (fields.size() != 3 - || !ParseNaturalNumber(fields[1], &line) - || !ParseNaturalNumber(fields[2], &index)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " - + GTEST_FLAG(internal_run_death_test)); + if (fields.size() != 3 || !ParseNaturalNumber(fields[1], &line) || + !ParseNaturalNumber(fields[2], &index)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG_GET(internal_run_death_test)); } -# else +#else - if (fields.size() != 4 - || !ParseNaturalNumber(fields[1], &line) - || !ParseNaturalNumber(fields[2], &index) - || !ParseNaturalNumber(fields[3], &write_fd)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " - + GTEST_FLAG(internal_run_death_test)); + if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || + !ParseNaturalNumber(fields[2], &index) || + !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG_GET(internal_run_death_test)); } -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-filepath.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-filepath.cc index 0b5629401b..f6ee90cdb7 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-filepath.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-filepath.cc @@ -30,29 +30,31 @@ #include "gtest/internal/gtest-filepath.h" #include -#include "gtest/internal/gtest-port.h" + #include "gtest/gtest-message.h" +#include "gtest/internal/gtest-port.h" #if GTEST_OS_WINDOWS_MOBILE -# include +#include #elif GTEST_OS_WINDOWS -# include -# include +#include +#include #else -# include -# include // Some Linux distributions define PATH_MAX here. -#endif // GTEST_OS_WINDOWS_MOBILE +#include + +#include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE #include "gtest/internal/gtest-string.h" #if GTEST_OS_WINDOWS -# define GTEST_PATH_MAX_ _MAX_PATH +#define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) -# define GTEST_PATH_MAX_ PATH_MAX +#define GTEST_PATH_MAX_ PATH_MAX #elif defined(_XOPEN_PATH_MAX) -# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX #else -# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS namespace testing { @@ -66,16 +68,16 @@ namespace internal { const char kPathSeparator = '\\'; const char kAlternatePathSeparator = '/'; const char kAlternatePathSeparatorString[] = "/"; -# if GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. const char kCurrentDirectoryString[] = "\\"; // Windows CE doesn't define INVALID_FILE_ATTRIBUTES const DWORD kInvalidFileAttributes = 0xffffffff; -# else +#else const char kCurrentDirectoryString[] = ".\\"; -# endif // GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kCurrentDirectoryString[] = "./"; @@ -99,17 +101,17 @@ FilePath FilePath::GetCurrentDir() { // something reasonable. return FilePath(kCurrentDirectoryString); #elif GTEST_OS_WINDOWS - char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + char cwd[GTEST_PATH_MAX_ + 1] = {'\0'}; return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd); #else - char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + char cwd[GTEST_PATH_MAX_ + 1] = {'\0'}; char* result = getcwd(cwd, sizeof(cwd)); -# if GTEST_OS_NACL +#if GTEST_OS_NACL // getcwd will likely fail in NaCl due to the sandbox, so return something // reasonable. The user may have provided a shim implementation for getcwd, // however, so fallback only when failure is detected. return FilePath(result == nullptr ? kCurrentDirectoryString : cwd); -# endif // GTEST_OS_NACL +#endif // GTEST_OS_NACL return FilePath(result == nullptr ? "" : cwd); #endif // GTEST_OS_WINDOWS_MOBILE } @@ -121,8 +123,8 @@ FilePath FilePath::GetCurrentDir() { FilePath FilePath::RemoveExtension(const char* extension) const { const std::string dot_extension = std::string(".") + extension; if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { - return FilePath(pathname_.substr( - 0, pathname_.length() - dot_extension.length())); + return FilePath( + pathname_.substr(0, pathname_.length() - dot_extension.length())); } return *this; } @@ -178,15 +180,14 @@ FilePath FilePath::RemoveFileName() const { // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. FilePath FilePath::MakeFileName(const FilePath& directory, - const FilePath& base_name, - int number, + const FilePath& base_name, int number, const char* extension) { std::string file; if (number == 0) { file = base_name.string() + "." + extension; } else { - file = base_name.string() + "_" + StreamableToString(number) - + "." + extension; + file = + base_name.string() + "_" + StreamableToString(number) + "." + extension; } return ConcatPaths(directory, FilePath(file)); } @@ -195,8 +196,7 @@ FilePath FilePath::MakeFileName(const FilePath& directory, // On Windows, uses \ as the separator rather than /. FilePath FilePath::ConcatPaths(const FilePath& directory, const FilePath& relative_path) { - if (directory.IsEmpty()) - return relative_path; + if (directory.IsEmpty()) return relative_path; const FilePath dir(directory.RemoveTrailingPathSeparator()); return FilePath(dir.string() + kPathSeparator + relative_path.string()); } @@ -207,7 +207,7 @@ bool FilePath::FileOrDirectoryExists() const { #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); const DWORD attributes = GetFileAttributes(unicode); - delete [] unicode; + delete[] unicode; return attributes != kInvalidFileAttributes; #else posix::StatStruct file_stat{}; @@ -222,8 +222,8 @@ bool FilePath::DirectoryExists() const { #if GTEST_OS_WINDOWS // Don't strip off trailing separator if path is a root directory on // Windows (like "C:\\"). - const FilePath& path(IsRootDirectory() ? *this : - RemoveTrailingPathSeparator()); + const FilePath& path(IsRootDirectory() ? *this + : RemoveTrailingPathSeparator()); #else const FilePath& path(*this); #endif @@ -231,15 +231,15 @@ bool FilePath::DirectoryExists() const { #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); const DWORD attributes = GetFileAttributes(unicode); - delete [] unicode; + delete[] unicode; if ((attributes != kInvalidFileAttributes) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) { result = true; } #else posix::StatStruct file_stat{}; - result = posix::Stat(path.c_str(), &file_stat) == 0 && - posix::IsDir(file_stat); + result = + posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat); #endif // GTEST_OS_WINDOWS_MOBILE return result; @@ -260,10 +260,9 @@ bool FilePath::IsAbsolutePath() const { const char* const name = pathname_.c_str(); #if GTEST_OS_WINDOWS return pathname_.length() >= 3 && - ((name[0] >= 'a' && name[0] <= 'z') || - (name[0] >= 'A' && name[0] <= 'Z')) && - name[1] == ':' && - IsPathSeparator(name[2]); + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && IsPathSeparator(name[2]); #else return IsPathSeparator(name[0]); #endif @@ -321,7 +320,7 @@ bool FilePath::CreateFolder() const { FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); int result = CreateDirectory(unicode, nullptr) ? 0 : -1; - delete [] unicode; + delete[] unicode; #elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); #elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA @@ -341,9 +340,8 @@ bool FilePath::CreateFolder() const { // name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath FilePath::RemoveTrailingPathSeparator() const { - return IsDirectory() - ? FilePath(pathname_.substr(0, pathname_.length() - 1)) - : *this; + return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; } // Removes any redundant separators that might be in the pathname. diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-internal-inl.h b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-internal-inl.h index 6d8cecbbb3..0b9e929c68 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-internal-inl.h +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-internal-inl.h @@ -35,7 +35,7 @@ #define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_ #ifndef _WIN32_WCE -# include +#include #endif // !_WIN32_WCE #include #include // For strtoll/_strtoul64/malloc/free. @@ -50,22 +50,20 @@ #include "gtest/internal/gtest-port.h" #if GTEST_CAN_STREAM_RESULTS_ -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT #endif #if GTEST_OS_WINDOWS -# include // NOLINT -#endif // GTEST_OS_WINDOWS +#include // NOLINT +#endif // GTEST_OS_WINDOWS -#include "gtest/gtest.h" #include "gtest/gtest-spi.h" +#include "gtest/gtest.h" GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ /* class A needs to have dll-interface to be used by clients of class B */) -namespace testing { - // Declares the flags. // // We don't want the users to modify this flag in the code, but want @@ -73,32 +71,13 @@ namespace testing { // declare it here as opposed to in gtest.h. GTEST_DECLARE_bool_(death_test_use_fork); +namespace testing { namespace internal { // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; -// Names of the flags (needed for parsing Google Test flags). -const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; -const char kBreakOnFailureFlag[] = "break_on_failure"; -const char kCatchExceptionsFlag[] = "catch_exceptions"; -const char kColorFlag[] = "color"; -const char kFailFast[] = "fail_fast"; -const char kFilterFlag[] = "filter"; -const char kListTestsFlag[] = "list_tests"; -const char kOutputFlag[] = "output"; -const char kBriefFlag[] = "brief"; -const char kPrintTimeFlag[] = "print_time"; -const char kPrintUTF8Flag[] = "print_utf8"; -const char kRandomSeedFlag[] = "random_seed"; -const char kRepeatFlag[] = "repeat"; -const char kShuffleFlag[] = "shuffle"; -const char kStackTraceDepthFlag[] = "stack_trace_depth"; -const char kStreamResultToFlag[] = "stream_result_to"; -const char kThrowOnFailureFlag[] = "throw_on_failure"; -const char kFlagfileFlag[] = "flagfile"; - // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; @@ -125,21 +104,21 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. -GTEST_API_ bool ParseInt32Flag( - const char* str, const char* flag, int32_t* value); +GTEST_API_ bool ParseFlag(const char* str, const char* flag, int32_t* value); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. inline int GetRandomSeedFromFlag(int32_t random_seed_flag) { - const unsigned int raw_seed = (random_seed_flag == 0) ? - static_cast(GetTimeInMillis()) : - static_cast(random_seed_flag); + const unsigned int raw_seed = + (random_seed_flag == 0) ? static_cast(GetTimeInMillis()) + : static_cast(random_seed_flag); // Normalizes the actual seed to range [1, kMaxRandomSeed] such that // it's easy to type. const int normalized_seed = static_cast((raw_seed - 1U) % - static_cast(kMaxRandomSeed)) + 1; + static_cast(kMaxRandomSeed)) + + 1; return normalized_seed; } @@ -160,50 +139,54 @@ class GTestFlagSaver { public: // The c'tor. GTestFlagSaver() { - also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); - break_on_failure_ = GTEST_FLAG(break_on_failure); - catch_exceptions_ = GTEST_FLAG(catch_exceptions); - color_ = GTEST_FLAG(color); - death_test_style_ = GTEST_FLAG(death_test_style); - death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); - fail_fast_ = GTEST_FLAG(fail_fast); - filter_ = GTEST_FLAG(filter); - internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); - list_tests_ = GTEST_FLAG(list_tests); - output_ = GTEST_FLAG(output); - brief_ = GTEST_FLAG(brief); - print_time_ = GTEST_FLAG(print_time); - print_utf8_ = GTEST_FLAG(print_utf8); - random_seed_ = GTEST_FLAG(random_seed); - repeat_ = GTEST_FLAG(repeat); - shuffle_ = GTEST_FLAG(shuffle); - stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); - stream_result_to_ = GTEST_FLAG(stream_result_to); - throw_on_failure_ = GTEST_FLAG(throw_on_failure); + also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG_GET(break_on_failure); + catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions); + color_ = GTEST_FLAG_GET(color); + death_test_style_ = GTEST_FLAG_GET(death_test_style); + death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork); + fail_fast_ = GTEST_FLAG_GET(fail_fast); + filter_ = GTEST_FLAG_GET(filter); + internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test); + list_tests_ = GTEST_FLAG_GET(list_tests); + output_ = GTEST_FLAG_GET(output); + brief_ = GTEST_FLAG_GET(brief); + print_time_ = GTEST_FLAG_GET(print_time); + print_utf8_ = GTEST_FLAG_GET(print_utf8); + random_seed_ = GTEST_FLAG_GET(random_seed); + repeat_ = GTEST_FLAG_GET(repeat); + recreate_environments_when_repeating_ = + GTEST_FLAG_GET(recreate_environments_when_repeating); + shuffle_ = GTEST_FLAG_GET(shuffle); + stack_trace_depth_ = GTEST_FLAG_GET(stack_trace_depth); + stream_result_to_ = GTEST_FLAG_GET(stream_result_to); + throw_on_failure_ = GTEST_FLAG_GET(throw_on_failure); } // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. ~GTestFlagSaver() { - GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; - GTEST_FLAG(break_on_failure) = break_on_failure_; - GTEST_FLAG(catch_exceptions) = catch_exceptions_; - GTEST_FLAG(color) = color_; - GTEST_FLAG(death_test_style) = death_test_style_; - GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; - GTEST_FLAG(filter) = filter_; - GTEST_FLAG(fail_fast) = fail_fast_; - GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; - GTEST_FLAG(list_tests) = list_tests_; - GTEST_FLAG(output) = output_; - GTEST_FLAG(brief) = brief_; - GTEST_FLAG(print_time) = print_time_; - GTEST_FLAG(print_utf8) = print_utf8_; - GTEST_FLAG(random_seed) = random_seed_; - GTEST_FLAG(repeat) = repeat_; - GTEST_FLAG(shuffle) = shuffle_; - GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; - GTEST_FLAG(stream_result_to) = stream_result_to_; - GTEST_FLAG(throw_on_failure) = throw_on_failure_; + GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_); + GTEST_FLAG_SET(break_on_failure, break_on_failure_); + GTEST_FLAG_SET(catch_exceptions, catch_exceptions_); + GTEST_FLAG_SET(color, color_); + GTEST_FLAG_SET(death_test_style, death_test_style_); + GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_); + GTEST_FLAG_SET(filter, filter_); + GTEST_FLAG_SET(fail_fast, fail_fast_); + GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_); + GTEST_FLAG_SET(list_tests, list_tests_); + GTEST_FLAG_SET(output, output_); + GTEST_FLAG_SET(brief, brief_); + GTEST_FLAG_SET(print_time, print_time_); + GTEST_FLAG_SET(print_utf8, print_utf8_); + GTEST_FLAG_SET(random_seed, random_seed_); + GTEST_FLAG_SET(repeat, repeat_); + GTEST_FLAG_SET(recreate_environments_when_repeating, + recreate_environments_when_repeating_); + GTEST_FLAG_SET(shuffle, shuffle_); + GTEST_FLAG_SET(stack_trace_depth, stack_trace_depth_); + GTEST_FLAG_SET(stream_result_to, stream_result_to_); + GTEST_FLAG_SET(throw_on_failure, throw_on_failure_); } private: @@ -224,6 +207,7 @@ class GTestFlagSaver { bool print_utf8_; int32_t random_seed_; int32_t repeat_; + bool recreate_environments_when_repeating_; bool shuffle_; int32_t stack_trace_depth_; std::string stream_result_to_; @@ -278,8 +262,8 @@ GTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val); // returns true if and only if the test should be run on this shard. The test id // is some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. -GTEST_API_ bool ShouldRunTestOnShard( - int total_shards, int shard_index, int test_id); +GTEST_API_ bool ShouldRunTestOnShard(int total_shards, int shard_index, + int test_id); // STL container utilities. @@ -290,9 +274,8 @@ inline int CountIf(const Container& c, Predicate predicate) { // Implemented as an explicit loop since std::count_if() in libCstd on // Solaris has a non-standard signature. int count = 0; - for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { - if (predicate(*it)) - ++count; + for (auto it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) ++count; } return count; } @@ -441,7 +424,9 @@ class OsStackTraceGetterInterface { static const char* const kElidedFramesMarker; private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); + OsStackTraceGetterInterface(const OsStackTraceGetterInterface&) = delete; + OsStackTraceGetterInterface& operator=(const OsStackTraceGetterInterface&) = + delete; }; // A working implementation of the OsStackTraceGetterInterface interface. @@ -463,7 +448,8 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface { void* caller_frame_ = nullptr; #endif // GTEST_HAS_ABSL - GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); + OsStackTraceGetter(const OsStackTraceGetter&) = delete; + OsStackTraceGetter& operator=(const OsStackTraceGetter&) = delete; }; // Information about a Google Test trace point. @@ -476,7 +462,7 @@ struct TraceInfo { // This is the default global test part result reporter used in UnitTestImpl. // This class should only be used by UnitTestImpl. class DefaultGlobalTestPartResultReporter - : public TestPartResultReporterInterface { + : public TestPartResultReporterInterface { public: explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. Reports the test part @@ -486,7 +472,10 @@ class DefaultGlobalTestPartResultReporter private: UnitTestImpl* const unit_test_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); + DefaultGlobalTestPartResultReporter( + const DefaultGlobalTestPartResultReporter&) = delete; + DefaultGlobalTestPartResultReporter& operator=( + const DefaultGlobalTestPartResultReporter&) = delete; }; // This is the default per thread test part result reporter used in @@ -502,7 +491,10 @@ class DefaultPerThreadTestPartResultReporter private: UnitTestImpl* const unit_test_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); + DefaultPerThreadTestPartResultReporter( + const DefaultPerThreadTestPartResultReporter&) = delete; + DefaultPerThreadTestPartResultReporter& operator=( + const DefaultPerThreadTestPartResultReporter&) = delete; }; // The private implementation of the UnitTest class. We don't protect @@ -640,7 +632,8 @@ class GTEST_API_ UnitTestImpl { // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. - std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + std::string CurrentOsStackTraceExceptTop(int skip_count) + GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_; // Finds and returns a TestSuite with the given name. If one doesn't // exist, creates one and returns it. @@ -744,9 +737,7 @@ class GTEST_API_ UnitTestImpl { } // Clears the results of ad-hoc test assertions. - void ClearAdHocTestResult() { - ad_hoc_test_result_.Clear(); - } + void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test or a test suite, or to the global property set. If the @@ -754,10 +745,7 @@ class GTEST_API_ UnitTestImpl { // updated. void RecordProperty(const TestProperty& test_property); - enum ReactionToSharding { - HONOR_SHARDING_PROTOCOL, - IGNORE_SHARDING_PROTOCOL - }; + enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL }; // Matches the full name of each test against the user-specified // filter to decide whether the test should run, then records the @@ -963,7 +951,8 @@ class GTEST_API_ UnitTestImpl { // starts. bool catch_exceptions_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); + UnitTestImpl(const UnitTestImpl&) = delete; + UnitTestImpl& operator=(const UnitTestImpl&) = delete; }; // class UnitTestImpl // Convenience function for accessing the global UnitTest @@ -986,8 +975,9 @@ GTEST_API_ bool IsValidEscape(char ch); GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); GTEST_API_ bool ValidateRegex(const char* regex); GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); -GTEST_API_ bool MatchRepetitionAndRegexAtHead( - bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch, + char repeat, const char* regex, + const char* str); GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); #endif // GTEST_USES_SIMPLE_RE @@ -1089,8 +1079,7 @@ class StreamingListener : public EmptyTestEventListener { } ~SocketWriter() override { - if (sockfd_ != -1) - CloseConnection(); + if (sockfd_ != -1) CloseConnection(); } // Sends a string to the socket. @@ -1100,9 +1089,8 @@ class StreamingListener : public EmptyTestEventListener { const auto len = static_cast(message.length()); if (write(sockfd_, message.c_str(), len) != static_cast(len)) { - GTEST_LOG_(WARNING) - << "stream_result_to: failed to stream to " - << host_name_ << ":" << port_num_; + GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; } } @@ -1123,7 +1111,8 @@ class StreamingListener : public EmptyTestEventListener { const std::string host_name_; const std::string port_num_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); + SocketWriter(const SocketWriter&) = delete; + SocketWriter& operator=(const SocketWriter&) = delete; }; // class SocketWriter // Escapes '=', '&', '%', and '\n' characters in str as "%xx". @@ -1135,7 +1124,9 @@ class StreamingListener : public EmptyTestEventListener { } explicit StreamingListener(AbstractSocketWriter* socket_writer) - : socket_writer_(socket_writer) { Start(); } + : socket_writer_(socket_writer) { + Start(); + } void OnTestProgramStart(const UnitTest& /* unit_test */) override { SendLn("event=TestProgramStart"); @@ -1158,22 +1149,22 @@ class StreamingListener : public EmptyTestEventListener { void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) override { - SendLn("event=TestIterationEnd&passed=" + - FormatBool(unit_test.Passed()) + "&elapsed_time=" + - StreamableToString(unit_test.elapsed_time()) + "ms"); + SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) + + "&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) + + "ms"); } // Note that "event=TestCaseStart" is a wire format and has to remain // "case" for compatibility - void OnTestCaseStart(const TestCase& test_case) override { - SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); + void OnTestSuiteStart(const TestSuite& test_suite) override { + SendLn(std::string("event=TestCaseStart&name=") + test_suite.name()); } // Note that "event=TestCaseEnd" is a wire format and has to remain // "case" for compatibility - void OnTestCaseEnd(const TestCase& test_case) override { - SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + - "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + + void OnTestSuiteEnd(const TestSuite& test_suite) override { + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_suite.Passed()) + + "&elapsed_time=" + StreamableToString(test_suite.elapsed_time()) + "ms"); } @@ -1183,8 +1174,7 @@ class StreamingListener : public EmptyTestEventListener { void OnTestEnd(const TestInfo& test_info) override { SendLn("event=TestEnd&passed=" + - FormatBool((test_info.result())->Passed()) + - "&elapsed_time=" + + FormatBool((test_info.result())->Passed()) + "&elapsed_time=" + StreamableToString((test_info.result())->elapsed_time()) + "ms"); } @@ -1208,7 +1198,8 @@ class StreamingListener : public EmptyTestEventListener { const std::unique_ptr socket_writer_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); + StreamingListener(const StreamingListener&) = delete; + StreamingListener& operator=(const StreamingListener&) = delete; }; // class StreamingListener #endif // GTEST_CAN_STREAM_RESULTS_ diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-matchers.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-matchers.cc index 65104ebab1..7e3bcc0cff 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-matchers.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-matchers.cc @@ -32,12 +32,13 @@ // This file implements just enough of the matcher interface to allow // EXPECT_DEATH and friends to accept a matcher argument. -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-port.h" #include "gtest/gtest-matchers.h" #include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-port.h" + namespace testing { // Constructs a matcher that matches a const std::string& whose value is diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-port.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-port.cc index 53a4d37f97..d797fe4d58 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-port.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-port.cc @@ -27,61 +27,62 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #include "gtest/internal/gtest-port.h" #include #include #include #include + #include #include #include #if GTEST_OS_WINDOWS -# include -# include -# include -# include // Used in ThreadLocal. -# ifdef _MSC_VER -# include -# endif // _MSC_VER +#include +#include +#include + +#include // Used in ThreadLocal. +#ifdef _MSC_VER +#include +#endif // _MSC_VER #else -# include +#include #endif // GTEST_OS_WINDOWS #if GTEST_OS_MAC -# include -# include -# include +#include +#include +#include #endif // GTEST_OS_MAC #if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ GTEST_OS_NETBSD || GTEST_OS_OPENBSD -# include -# if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD -# include -# endif +#include +#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD +#include +#endif #endif #if GTEST_OS_QNX -# include -# include -# include +#include +#include +#include #endif // GTEST_OS_QNX #if GTEST_OS_AIX -# include -# include +#include +#include #endif // GTEST_OS_AIX #if GTEST_OS_FUCHSIA -# include -# include +#include +#include #endif // GTEST_OS_FUCHSIA -#include "gtest/gtest-spi.h" #include "gtest/gtest-message.h" +#include "gtest/gtest-spi.h" #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" #include "src/gtest-internal-inl.h" @@ -89,16 +90,7 @@ namespace testing { namespace internal { -#if defined(_MSC_VER) || defined(__BORLANDC__) -// MSVC and C++Builder do not provide a definition of STDERR_FILENO. -const int kStdOutFileno = 1; -const int kStdErrFileno = 2; -#else -const int kStdOutFileno = STDOUT_FILENO; -const int kStdErrFileno = STDERR_FILENO; -#endif // _MSC_VER - -#if GTEST_OS_LINUX +#if GTEST_OS_LINUX || GTEST_OS_GNU_HURD namespace { template @@ -131,8 +123,7 @@ size_t GetThreadCount() { if (status == KERN_SUCCESS) { // task_threads allocates resources in thread_list and we need to free them // to avoid leaks. - vm_deallocate(task, - reinterpret_cast(thread_list), + vm_deallocate(task, reinterpret_cast(thread_list), sizeof(thread_t) * thread_count); return static_cast(thread_count); } else { @@ -141,7 +132,7 @@ size_t GetThreadCount() { } #elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ - GTEST_OS_NETBSD + GTEST_OS_NETBSD #if GTEST_OS_NETBSD #undef KERN_PROC @@ -184,12 +175,12 @@ size_t GetThreadCount() { // we cannot detect it. size_t GetThreadCount() { int mib[] = { - CTL_KERN, - KERN_PROC, - KERN_PROC_PID | KERN_PROC_SHOW_THREADS, - getpid(), - sizeof(struct kinfo_proc), - 0, + CTL_KERN, + KERN_PROC, + KERN_PROC_PID | KERN_PROC_SHOW_THREADS, + getpid(), + sizeof(struct kinfo_proc), + 0, }; u_int miblen = sizeof(mib) / sizeof(mib[0]); @@ -210,8 +201,7 @@ size_t GetThreadCount() { // exclude empty members size_t nthreads = 0; for (size_t i = 0; i < size / static_cast(mib[4]); i++) { - if (info[i].p_tid != -1) - nthreads++; + if (info[i].p_tid != -1) nthreads++; } return nthreads; } @@ -254,13 +244,9 @@ size_t GetThreadCount() { size_t GetThreadCount() { int dummy_buffer; size_t avail; - zx_status_t status = zx_object_get_info( - zx_process_self(), - ZX_INFO_PROCESS_THREADS, - &dummy_buffer, - 0, - nullptr, - &avail); + zx_status_t status = + zx_object_get_info(zx_process_self(), ZX_INFO_PROCESS_THREADS, + &dummy_buffer, 0, nullptr, &avail); if (status == ZX_OK) { return avail; } else { @@ -280,27 +266,15 @@ size_t GetThreadCount() { #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS -void SleepMilliseconds(int n) { - ::Sleep(static_cast(n)); -} +AutoHandle::AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} -AutoHandle::AutoHandle() - : handle_(INVALID_HANDLE_VALUE) {} +AutoHandle::AutoHandle(Handle handle) : handle_(handle) {} -AutoHandle::AutoHandle(Handle handle) - : handle_(handle) {} +AutoHandle::~AutoHandle() { Reset(); } -AutoHandle::~AutoHandle() { - Reset(); -} - -AutoHandle::Handle AutoHandle::Get() const { - return handle_; -} +AutoHandle::Handle AutoHandle::Get() const { return handle_; } -void AutoHandle::Reset() { - Reset(INVALID_HANDLE_VALUE); -} +void AutoHandle::Reset() { Reset(INVALID_HANDLE_VALUE); } void AutoHandle::Reset(HANDLE handle) { // Resetting with the same handle we already own is invalid. @@ -312,7 +286,7 @@ void AutoHandle::Reset(HANDLE handle) { } else { GTEST_CHECK_(!IsCloseable()) << "Resetting a valid handle to itself is likely a programmer error " - "and thus not allowed."; + "and thus not allowed."; } } @@ -322,23 +296,6 @@ bool AutoHandle::IsCloseable() const { return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE; } -Notification::Notification() - : event_(::CreateEvent(nullptr, // Default security attributes. - TRUE, // Do not reset automatically. - FALSE, // Initially unset. - nullptr)) { // Anonymous event. - GTEST_CHECK_(event_.Get() != nullptr); -} - -void Notification::Notify() { - GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); -} - -void Notification::WaitForNotification() { - GTEST_CHECK_( - ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); -} - Mutex::Mutex() : owner_thread_id_(0), type_(kDynamic), @@ -391,25 +348,25 @@ namespace { // MemoryIsNotDeallocated memory_is_not_deallocated; // critical_section_ = new CRITICAL_SECTION; // -class MemoryIsNotDeallocated -{ +class MemoryIsNotDeallocated { public: MemoryIsNotDeallocated() : old_crtdbg_flag_(0) { old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT // doesn't report mem leak if there's no matching deallocation. - _CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF); + (void)_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF); } ~MemoryIsNotDeallocated() { // Restore the original _CRTDBG_ALLOC_MEM_DF flag - _CrtSetDbgFlag(old_crtdbg_flag_); + (void)_CrtSetDbgFlag(old_crtdbg_flag_); } private: int old_crtdbg_flag_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated); + MemoryIsNotDeallocated(const MemoryIsNotDeallocated&) = delete; + MemoryIsNotDeallocated& operator=(const MemoryIsNotDeallocated&) = delete; }; #endif // _MSC_VER @@ -435,15 +392,13 @@ void Mutex::ThreadSafeLazyInit() { ::InitializeCriticalSection(critical_section_); // Updates the critical_section_init_phase_ to 2 to signal // initialization complete. - GTEST_CHECK_(::InterlockedCompareExchange( - &critical_section_init_phase_, 2L, 1L) == - 1L); + GTEST_CHECK_(::InterlockedCompareExchange(&critical_section_init_phase_, + 2L, 1L) == 1L); break; case 1: // Somebody else is already initializing the mutex; spin until they // are done. - while (::InterlockedCompareExchange(&critical_section_init_phase_, - 2L, + while (::InterlockedCompareExchange(&critical_section_init_phase_, 2L, 2L) != 2L) { // Possibly yields the rest of the thread's time slice to other // threads. @@ -488,9 +443,7 @@ class ThreadWithParamSupport : public ThreadWithParamBase { private: struct ThreadMainParam { ThreadMainParam(Runnable* runnable, Notification* thread_can_start) - : runnable_(runnable), - thread_can_start_(thread_can_start) { - } + : runnable_(runnable), thread_can_start_(thread_can_start) {} std::unique_ptr runnable_; // Does not own. Notification* thread_can_start_; @@ -508,20 +461,18 @@ class ThreadWithParamSupport : public ThreadWithParamBase { // Prohibit instantiation. ThreadWithParamSupport(); - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); + ThreadWithParamSupport(const ThreadWithParamSupport&) = delete; + ThreadWithParamSupport& operator=(const ThreadWithParamSupport&) = delete; }; } // namespace -ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, +ThreadWithParamBase::ThreadWithParamBase(Runnable* runnable, Notification* thread_can_start) - : thread_(ThreadWithParamSupport::CreateThread(runnable, - thread_can_start)) { -} + : thread_( + ThreadWithParamSupport::CreateThread(runnable, thread_can_start)) {} -ThreadWithParamBase::~ThreadWithParamBase() { - Join(); -} +ThreadWithParamBase::~ThreadWithParamBase() { Join(); } void ThreadWithParamBase::Join() { GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) @@ -548,8 +499,10 @@ class ThreadLocalRegistryImpl { ThreadIdToThreadLocals::iterator thread_local_pos = thread_to_thread_locals->find(current_thread); if (thread_local_pos == thread_to_thread_locals->end()) { - thread_local_pos = thread_to_thread_locals->insert( - std::make_pair(current_thread, ThreadLocalValues())).first; + thread_local_pos = + thread_to_thread_locals + ->insert(std::make_pair(current_thread, ThreadLocalValues())) + .first; StartWatcherThreadFor(current_thread); } ThreadLocalValues& thread_local_values = thread_local_pos->second; @@ -577,9 +530,8 @@ class ThreadLocalRegistryImpl { ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); for (ThreadIdToThreadLocals::iterator it = - thread_to_thread_locals->begin(); - it != thread_to_thread_locals->end(); - ++it) { + thread_to_thread_locals->begin(); + it != thread_to_thread_locals->end(); ++it) { ThreadLocalValues& thread_local_values = it->second; ThreadLocalValues::iterator value_pos = thread_local_values.find(thread_local_instance); @@ -609,9 +561,8 @@ class ThreadLocalRegistryImpl { if (thread_local_pos != thread_to_thread_locals->end()) { ThreadLocalValues& thread_local_values = thread_local_pos->second; for (ThreadLocalValues::iterator value_pos = - thread_local_values.begin(); - value_pos != thread_local_values.end(); - ++value_pos) { + thread_local_values.begin(); + value_pos != thread_local_values.end(); ++value_pos) { value_holders.push_back(value_pos->second); } thread_to_thread_locals->erase(thread_local_pos); @@ -637,9 +588,8 @@ class ThreadLocalRegistryImpl { static void StartWatcherThreadFor(DWORD thread_id) { // The returned handle will be kept in thread_map and closed by // watcher_thread in WatcherThreadFunc. - HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, - FALSE, - thread_id); + HANDLE thread = + ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id); GTEST_CHECK_(thread != nullptr); // We need to pass a valid thread ID pointer into CreateThread for it // to work correctly under Win98. @@ -650,7 +600,8 @@ class ThreadLocalRegistryImpl { &ThreadLocalRegistryImpl::WatcherThreadFunc, reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), CREATE_SUSPENDED, &watcher_thread_id); - GTEST_CHECK_(watcher_thread != nullptr); + GTEST_CHECK_(watcher_thread != nullptr) + << "CreateThread failed with error " << ::GetLastError() << "."; // Give the watcher thread the same priority as ours to avoid being // blocked by it. ::SetThreadPriority(watcher_thread, @@ -664,8 +615,7 @@ class ThreadLocalRegistryImpl { static DWORD WINAPI WatcherThreadFunc(LPVOID param) { const ThreadIdAndHandle* tah = reinterpret_cast(param); - GTEST_CHECK_( - ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); + GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); OnThreadExit(tah->first); ::CloseHandle(tah->second); delete tah; @@ -689,16 +639,17 @@ class ThreadLocalRegistryImpl { }; Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); // NOLINT -Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); // NOLINT +Mutex ThreadLocalRegistryImpl::thread_map_mutex_( + Mutex::kStaticMutex); // NOLINT ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( - const ThreadLocalBase* thread_local_instance) { + const ThreadLocalBase* thread_local_instance) { return ThreadLocalRegistryImpl::GetValueOnCurrentThread( thread_local_instance); } void ThreadLocalRegistry::OnThreadLocalDestroyed( - const ThreadLocalBase* thread_local_instance) { + const ThreadLocalBase* thread_local_instance) { ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); } @@ -786,7 +737,7 @@ bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } bool IsAsciiWordChar(char ch) { return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || - ('0' <= ch && ch <= '9') || ch == '_'; + ('0' <= ch && ch <= '9') || ch == '_'; } // Returns true if and only if "\\c" is a supported escape sequence. @@ -799,17 +750,28 @@ bool IsValidEscape(char c) { bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { if (escaped) { // "\\p" where p is pattern_char. switch (pattern_char) { - case 'd': return IsAsciiDigit(ch); - case 'D': return !IsAsciiDigit(ch); - case 'f': return ch == '\f'; - case 'n': return ch == '\n'; - case 'r': return ch == '\r'; - case 's': return IsAsciiWhiteSpace(ch); - case 'S': return !IsAsciiWhiteSpace(ch); - case 't': return ch == '\t'; - case 'v': return ch == '\v'; - case 'w': return IsAsciiWordChar(ch); - case 'W': return !IsAsciiWordChar(ch); + case 'd': + return IsAsciiDigit(ch); + case 'D': + return !IsAsciiDigit(ch); + case 'f': + return ch == '\f'; + case 'n': + return ch == '\n'; + case 'r': + return ch == '\r'; + case 's': + return IsAsciiWhiteSpace(ch); + case 'S': + return !IsAsciiWhiteSpace(ch); + case 't': + return ch == '\t'; + case 'v': + return ch == '\v'; + case 'w': + return IsAsciiWordChar(ch); + case 'W': + return !IsAsciiWordChar(ch); } return IsAsciiPunct(pattern_char) && pattern_char == ch; } @@ -820,7 +782,8 @@ bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { // Helper function used by ValidateRegex() to format error messages. static std::string FormatRegexSyntaxError(const char* regex, int index) { return (Message() << "Syntax error at index " << index - << " in simple regular expression \"" << regex << "\": ").GetString(); + << " in simple regular expression \"" << regex << "\": ") + .GetString(); } // Generates non-fatal failures and returns false if regex is invalid; @@ -862,12 +825,12 @@ bool ValidateRegex(const char* regex) { << "'$' can only appear at the end."; is_valid = false; } else if (IsInSet(ch, "()[]{}|")) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'" << ch << "' is unsupported."; + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch + << "' is unsupported."; is_valid = false; } else if (IsRepeat(ch) && !prev_repeatable) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'" << ch << "' can only follow a repeatable token."; + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch + << "' can only follow a repeatable token."; is_valid = false; } @@ -885,12 +848,10 @@ bool ValidateRegex(const char* regex) { // characters to be indexable by size_t, in which case the test will // probably time out anyway. We are fine with this limitation as // std::string has it too. -bool MatchRepetitionAndRegexAtHead( - bool escaped, char c, char repeat, const char* regex, - const char* str) { +bool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat, + const char* regex, const char* str) { const size_t min_count = (repeat == '+') ? 1 : 0; - const size_t max_count = (repeat == '?') ? 1 : - static_cast(-1) - 1; + const size_t max_count = (repeat == '?') ? 1 : static_cast(-1) - 1; // We cannot call numeric_limits::max() as it conflicts with the // max() macro on Windows. @@ -903,8 +864,7 @@ bool MatchRepetitionAndRegexAtHead( // greedy match. return true; } - if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) - return false; + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false; } return false; } @@ -918,25 +878,23 @@ bool MatchRegexAtHead(const char* regex, const char* str) { // "$" only matches the end of a string. Note that regex being // valid guarantees that there's nothing after "$" in it. - if (*regex == '$') - return *str == '\0'; + if (*regex == '$') return *str == '\0'; // Is the first thing in regex an escape sequence? const bool escaped = *regex == '\\'; - if (escaped) - ++regex; + if (escaped) ++regex; if (IsRepeat(regex[1])) { // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so // here's an indirect recursion. It terminates as the regex gets // shorter in each recursion. - return MatchRepetitionAndRegexAtHead( - escaped, regex[0], regex[1], regex + 2, str); + return MatchRepetitionAndRegexAtHead(escaped, regex[0], regex[1], regex + 2, + str); } else { // regex isn't empty, isn't "$", and doesn't start with a // repetition. We match the first atom of regex with the first // character of str and recurse. return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && - MatchRegexAtHead(regex + 1, str + 1); + MatchRegexAtHead(regex + 1, str + 1); } } @@ -951,13 +909,11 @@ bool MatchRegexAtHead(const char* regex, const char* str) { bool MatchRegexAnywhere(const char* regex, const char* str) { if (regex == nullptr || str == nullptr) return false; - if (*regex == '^') - return MatchRegexAtHead(regex + 1, str); + if (*regex == '^') return MatchRegexAtHead(regex + 1, str); // A successful match can be anywhere in str. do { - if (MatchRegexAtHead(regex, str)) - return true; + if (MatchRegexAtHead(regex, str)) return true; } while (*str++ != '\0'); return false; } @@ -1038,8 +994,8 @@ GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { // FormatFileLocation in order to contrast the two functions. // Note that FormatCompilerIndependentFileLocation() does NOT append colon // to the file location it produces, unlike FormatFileLocation(). -GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( - const char* file, int line) { +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line) { const std::string file_name(file == nullptr ? kUnknownFile : file); if (line < 0) @@ -1050,12 +1006,13 @@ GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { - const char* const marker = - severity == GTEST_INFO ? "[ INFO ]" : - severity == GTEST_WARNING ? "[WARNING]" : - severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; - GetStream() << ::std::endl << marker << " " - << FormatFileLocation(file, line).c_str() << ": "; + const char* const marker = severity == GTEST_INFO ? "[ INFO ]" + : severity == GTEST_WARNING ? "[WARNING]" + : severity == GTEST_ERROR ? "[ ERROR ]" + : "[ FATAL ]"; + GetStream() << ::std::endl + << marker << " " << FormatFileLocation(file, line).c_str() + << ": "; } // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. @@ -1078,27 +1035,26 @@ class CapturedStream { public: // The ctor redirects the stream to a temporary file. explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { -# if GTEST_OS_WINDOWS - char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT - char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT +#if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = {'\0'}; // NOLINT + char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); - const UINT success = ::GetTempFileNameA(temp_dir_path, - "gtest_redir", + const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, // Generate unique file name. temp_file_path); GTEST_CHECK_(success != 0) << "Unable to create a temporary file in " << temp_dir_path; const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); - GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " - << temp_file_path; + GTEST_CHECK_(captured_fd != -1) + << "Unable to open temporary file " << temp_file_path; filename_ = temp_file_path; -# else +#else // There's no guarantee that a test has write access to the current // directory, so we create the temporary file in a temporary directory. std::string name_template; -# if GTEST_OS_LINUX_ANDROID +#if GTEST_OS_LINUX_ANDROID // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, @@ -1111,7 +1067,7 @@ class CapturedStream { // '/sdcard' and other variants cannot be relied on, as they are not // guaranteed to be mounted, or may have a delay in mounting. name_template = "/data/local/tmp/"; -# elif GTEST_OS_IOS +#elif GTEST_OS_IOS char user_temp_dir[PATH_MAX + 1]; // Documented alternative to NSTemporaryDirectory() (for obtaining creating @@ -1132,9 +1088,9 @@ class CapturedStream { name_template = user_temp_dir; if (name_template.back() != GTEST_PATH_SEP_[0]) name_template.push_back(GTEST_PATH_SEP_[0]); -# else +#else name_template = "/tmp/"; -# endif +#endif name_template.append("gtest_captured_stream.XXXXXX"); // mkstemp() modifies the string bytes in place, and does not go beyond the @@ -1150,15 +1106,13 @@ class CapturedStream { << " for test; does the test have access to the /tmp directory?"; } filename_ = std::move(name_template); -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS fflush(nullptr); dup2(captured_fd, fd_); close(captured_fd); } - ~CapturedStream() { - remove(filename_.c_str()); - } + ~CapturedStream() { remove(filename_.c_str()); } std::string GetCapturedString() { if (uncaptured_fd_ != -1) { @@ -1185,7 +1139,8 @@ class CapturedStream { // Name of the temporary file holding the stderr output. ::std::string filename_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); + CapturedStream(const CapturedStream&) = delete; + CapturedStream& operator=(const CapturedStream&) = delete; }; GTEST_DISABLE_MSC_DEPRECATED_POP_() @@ -1213,6 +1168,15 @@ static std::string GetCapturedStream(CapturedStream** captured_stream) { return content; } +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // defined(_MSC_VER) || defined(__BORLANDC__) + // Starts capturing stdout. void CaptureStdout() { CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); @@ -1235,10 +1199,6 @@ std::string GetCapturedStderr() { #endif // GTEST_HAS_STREAM_REDIRECTION - - - - size_t GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast(ftell(file)); @@ -1256,7 +1216,8 @@ std::string ReadEntireFile(FILE* file) { // Keeps reading the file until we cannot read further or the // pre-determined file size is reached. do { - bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_last_read = + fread(buffer + bytes_read, 1, file_size - bytes_read, file); bytes_read += bytes_last_read; } while (bytes_last_read > 0 && bytes_read < file_size); @@ -1344,7 +1305,7 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { // LONG_MAX or LONG_MIN when the input overflows.) result != long_value // The parsed value overflows as an int32_t. - ) { + ) { Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" @@ -1388,8 +1349,8 @@ int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) { } int32_t result = default_value; - if (!ParseInt32(Message() << "Environment variable " << env_var, - string_value, &result)) { + if (!ParseInt32(Message() << "Environment variable " << env_var, string_value, + &result)) { printf("The default value %s is used.\n", (Message() << default_value).GetString().c_str()); fflush(stdout); @@ -1408,7 +1369,7 @@ int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) { // not check that the flag is 'output' // In essence this checks an env variable called XML_OUTPUT_FILE // and if it is set we prepend "xml:" to its value, if it not set we return "" -std::string OutputFlagAlsoCheckEnvVar(){ +std::string OutputFlagAlsoCheckEnvVar() { std::string default_value_for_output_flag = ""; const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE"); if (nullptr != xml_output_file_env) { diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-printers.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-printers.cc index 1b68fcb500..f3976d230d 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-printers.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-printers.cc @@ -27,7 +27,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - // Google Test - The Google C++ Testing and Mocking Framework // // This file implements a universal value printer that can print a @@ -101,7 +100,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); *os << " ... "; // Rounds up to 2-byte boundary. - const size_t resume_pos = (count - kChunkSize + 1)/2*2; + const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2; PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); } *os << ">"; @@ -136,11 +135,7 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as a hexadecimal escape sequence (e.g. '\x7F'), or // - as a special escape sequence (e.g. '\r', '\n'). -enum CharFormat { - kAsIs, - kHexEscape, - kSpecialEscape -}; +enum CharFormat { kAsIs, kHexEscape, kSpecialEscape }; // Returns true if c is a printable ASCII character. We test the // value of c directly instead of calling isprint(), which is buggy on @@ -213,35 +208,21 @@ static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) { } } -static const char* GetCharWidthPrefix(char) { - return ""; -} +static const char* GetCharWidthPrefix(char) { return ""; } -static const char* GetCharWidthPrefix(signed char) { - return ""; -} +static const char* GetCharWidthPrefix(signed char) { return ""; } -static const char* GetCharWidthPrefix(unsigned char) { - return ""; -} +static const char* GetCharWidthPrefix(unsigned char) { return ""; } #ifdef __cpp_char8_t -static const char* GetCharWidthPrefix(char8_t) { - return "u8"; -} +static const char* GetCharWidthPrefix(char8_t) { return "u8"; } #endif -static const char* GetCharWidthPrefix(char16_t) { - return "u"; -} +static const char* GetCharWidthPrefix(char16_t) { return "u"; } -static const char* GetCharWidthPrefix(char32_t) { - return "U"; -} +static const char* GetCharWidthPrefix(char32_t) { return "U"; } -static const char* GetCharWidthPrefix(wchar_t) { - return "L"; -} +static const char* GetCharWidthPrefix(wchar_t) { return "L"; } // Prints a char c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. @@ -276,8 +257,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) { // To aid user debugging, we also print c's code in decimal, unless // it's 0 (in which case c was printed as '\\0', making the code // obvious). - if (c == 0) - return; + if (c == 0) return; *os << " (" << static_cast(c); // For more convenience, we print c's code again in hexadecimal, @@ -304,17 +284,60 @@ void PrintTo(char32_t c, ::std::ostream* os) { << static_cast(c); } +// gcc/clang __{u,}int128_t +#if defined(__SIZEOF_INT128__) +void PrintTo(__uint128_t v, ::std::ostream* os) { + if (v == 0) { + *os << "0"; + return; + } + + // Buffer large enough for ceil(log10(2^128))==39 and the null terminator + char buf[40]; + char* p = buf + sizeof(buf); + + // Some configurations have a __uint128_t, but no support for built in + // division. Do manual long division instead. + + uint64_t high = static_cast(v >> 64); + uint64_t low = static_cast(v); + + *--p = 0; + while (high != 0 || low != 0) { + uint64_t high_mod = high % 10; + high = high / 10; + // This is the long division algorithm specialized for a divisor of 10 and + // only two elements. + // Notable values: + // 2^64 / 10 == 1844674407370955161 + // 2^64 % 10 == 6 + const uint64_t carry = 6 * high_mod + low % 10; + low = low / 10 + high_mod * 1844674407370955161 + carry / 10; + + char digit = static_cast(carry % 10); + *--p = '0' + digit; + } + *os << p; +} +void PrintTo(__int128_t v, ::std::ostream* os) { + __uint128_t uv = static_cast<__uint128_t>(v); + if (v < 0) { + *os << "-"; + uv = -uv; + } + PrintTo(uv, os); +} +#endif // __SIZEOF_INT128__ + // Prints the given array of characters to the ostream. CharType must be either // char, char8_t, char16_t, char32_t, or wchar_t. // The array starts at begin, the length is len, it may include '\0' characters // and may not be NUL-terminated. template -GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ -GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -static CharFormat PrintCharsAsStringTo( - const CharType* begin, size_t len, ostream* os) { +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ + GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ + GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat + PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) { const char* const quote_prefix = GetCharWidthPrefix(*begin); *os << quote_prefix << "\""; bool is_previous_hex = false; @@ -340,12 +363,11 @@ static CharFormat PrintCharsAsStringTo( // Prints a (const) char/wchar_t array of 'len' elements, starting at address // 'begin'. CharType must be either char or wchar_t. template -GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ -GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -static void UniversalPrintCharArray( - const CharType* begin, size_t len, ostream* os) { +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ + GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ + GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void + UniversalPrintCharArray(const CharType* begin, size_t len, + ostream* os) { // The code // const char kFoo[] = "foo"; // generates an array of 4, not 3, elements, with the last one being '\0'. @@ -436,28 +458,28 @@ void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); } namespace { bool ContainsUnprintableControlCodes(const char* str, size_t length) { - const unsigned char *s = reinterpret_cast(str); + const unsigned char* s = reinterpret_cast(str); for (size_t i = 0; i < length; i++) { unsigned char ch = *s++; if (std::iscntrl(ch)) { - switch (ch) { + switch (ch) { case '\t': case '\n': case '\r': break; default: return true; - } } + } } return false; } -bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; } +bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t <= 0xbf; } bool IsValidUTF8(const char* str, size_t length) { - const unsigned char *s = reinterpret_cast(str); + const unsigned char* s = reinterpret_cast(str); for (size_t i = 0; i < length;) { unsigned char lead = s[i++]; @@ -470,15 +492,13 @@ bool IsValidUTF8(const char* str, size_t length) { } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) { ++i; // 2-byte character } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length && - IsUTF8TrailByte(s[i]) && - IsUTF8TrailByte(s[i + 1]) && + IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) && // check for non-shortest form and surrogate (lead != 0xe0 || s[i] >= 0xa0) && (lead != 0xed || s[i] < 0xa0)) { i += 2; // 3-byte character } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length && - IsUTF8TrailByte(s[i]) && - IsUTF8TrailByte(s[i + 1]) && + IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) && IsUTF8TrailByte(s[i + 2]) && // check for non-shortest form (lead != 0xf0 || s[i] >= 0x90) && @@ -502,7 +522,7 @@ void ConditionalPrintAsText(const char* str, size_t length, ostream* os) { void PrintStringTo(const ::std::string& s, ostream* os) { if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) { - if (GTEST_FLAG(print_utf8)) { + if (GTEST_FLAG_GET(print_utf8)) { ConditionalPrintAsText(s.data(), s.size(), os); } } diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-test-part.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-test-part.cc index a938683ced..eb7c8d1cf9 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-test-part.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-test-part.cc @@ -51,13 +51,11 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { return os << internal::FormatFileLocation(result.file_name(), result.line_number()) << " " - << (result.type() == TestPartResult::kSuccess - ? "Success" - : result.type() == TestPartResult::kSkip - ? "Skipped" - : result.type() == TestPartResult::kFatalFailure - ? "Fatal failure" - : "Non-fatal failure") + << (result.type() == TestPartResult::kSuccess ? "Success" + : result.type() == TestPartResult::kSkip ? "Skipped" + : result.type() == TestPartResult::kFatalFailure + ? "Fatal failure" + : "Non-fatal failure") << ":\n" << result.message() << std::endl; } @@ -86,8 +84,8 @@ namespace internal { HasNewFatalFailureHelper::HasNewFatalFailureHelper() : has_new_fatal_failure_(false), - original_reporter_(GetUnitTestImpl()-> - GetTestPartResultReporterForCurrentThread()) { + original_reporter_( + GetUnitTestImpl()->GetTestPartResultReporterForCurrentThread()) { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); } @@ -98,8 +96,7 @@ HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { void HasNewFatalFailureHelper::ReportTestPartResult( const TestPartResult& result) { - if (result.fatally_failed()) - has_new_fatal_failure_ = true; + if (result.fatally_failed()) has_new_fatal_failure_ = true; original_reporter_->ReportTestPartResult(result); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-typed-test.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-typed-test.cc index c02c3df659..a2828b83c6 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-typed-test.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest-typed-test.cc @@ -27,7 +27,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #include "gtest/gtest-typed-test.h" #include "gtest/gtest.h" @@ -38,8 +37,7 @@ namespace internal { // Skips to the first non-space char in str. Returns an empty string if str // contains only whitespace characters. static const char* SkipSpaces(const char* str) { - while (IsSpace(*str)) - str++; + while (IsSpace(*str)) str++; return str; } @@ -85,8 +83,7 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames( } for (RegisteredTestIter it = registered_tests_.begin(); - it != registered_tests_.end(); - ++it) { + it != registered_tests_.end(); ++it) { if (tests.count(it->first) == 0) { errors << "You forgot to list test " << it->first << ".\n"; } diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest.cc index c85ff9687f..c2611f5038 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest.cc @@ -31,8 +31,6 @@ // The Google C++ Testing and Mocking Framework (Google Test) #include "gtest/gtest.h" -#include "gtest/internal/custom/gtest.h" -#include "gtest/gtest-spi.h" #include #include @@ -46,79 +44,87 @@ #include // NOLINT #include #include +#include #include +#include #include #include #include #include // NOLINT #include +#include #include +#include "gtest/gtest-assertion-result.h" +#include "gtest/gtest-spi.h" +#include "gtest/internal/custom/gtest.h" + #if GTEST_OS_LINUX -# include // NOLINT -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT // Declares vsnprintf(). This header is not available on Windows. -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#include #elif GTEST_OS_ZOS -# include // NOLINT +#include // NOLINT // On z/OS we additionally need strings.h for strcasecmp. -# include // NOLINT +#include // NOLINT #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. -# include // NOLINT -# undef min +#include // NOLINT +#undef min #elif GTEST_OS_WINDOWS // We are on Windows proper. -# include // NOLINT -# undef min +#include // NOLINT +#undef min #ifdef _MSC_VER -# include // NOLINT +#include // NOLINT #endif -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT -# if GTEST_OS_WINDOWS_MINGW -# include // NOLINT -# endif // GTEST_OS_WINDOWS_MINGW +#if GTEST_OS_WINDOWS_MINGW +#include // NOLINT +#endif // GTEST_OS_WINDOWS_MINGW #else // cpplint thinks that the header is already included, so we want to // silence it. -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS -# include +#include #endif #if GTEST_CAN_STREAM_RESULTS_ -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT #endif #include "src/gtest-internal-inl.h" #if GTEST_OS_WINDOWS -# define vsnprintf _vsnprintf +#define vsnprintf _vsnprintf #endif // GTEST_OS_WINDOWS #if GTEST_OS_MAC @@ -131,7 +137,10 @@ #include "absl/debugging/failure_signal_handler.h" #include "absl/debugging/stacktrace.h" #include "absl/debugging/symbolize.h" +#include "absl/flags/parse.h" +#include "absl/flags/usage.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_replace.h" #endif // GTEST_HAS_ABSL namespace testing { @@ -177,7 +186,7 @@ const char kStackTraceMarker[] = "\nStack trace:\n"; // is specified on the command line. bool g_help_flag = false; -// Utilty function to Open File for Writing +// Utility function to Open File for Writing static FILE* OpenFileForWriting(const std::string& output_file) { FILE* fileout = nullptr; FilePath output_file_path(output_file); @@ -216,28 +225,33 @@ static bool GetDefaultFailFast() { return false; } +} // namespace testing + GTEST_DEFINE_bool_( - fail_fast, internal::BoolFromGTestEnv("fail_fast", GetDefaultFailFast()), + fail_fast, + testing::internal::BoolFromGTestEnv("fail_fast", + testing::GetDefaultFailFast()), "True if and only if a test failure should stop further test execution."); GTEST_DEFINE_bool_( also_run_disabled_tests, - internal::BoolFromGTestEnv("also_run_disabled_tests", false), + testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false), "Run disabled tests too, in addition to the tests normally being run."); GTEST_DEFINE_bool_( - break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), + break_on_failure, + testing::internal::BoolFromGTestEnv("break_on_failure", false), "True if and only if a failed assertion should be a debugger " "break-point."); GTEST_DEFINE_bool_(catch_exceptions, - internal::BoolFromGTestEnv("catch_exceptions", true), + testing::internal::BoolFromGTestEnv("catch_exceptions", + true), "True if and only if " GTEST_NAME_ " should catch exceptions and treat them as test failures."); GTEST_DEFINE_string_( - color, - internal::StringFromGTestEnv("color", "auto"), + color, testing::internal::StringFromGTestEnv("color", "auto"), "Whether to use colors in the output. Valid values: yes, no, " "and auto. 'auto' means to use colors if the output is " "being sent to a terminal and the TERM environment variable " @@ -245,7 +259,8 @@ GTEST_DEFINE_string_( GTEST_DEFINE_string_( filter, - internal::StringFromGTestEnv("filter", GetDefaultFilter()), + testing::internal::StringFromGTestEnv("filter", + testing::GetDefaultFilter()), "A colon-separated list of glob (not regex) patterns " "for filtering the tests to run, optionally followed by a " "'-' and a : separated list of negative patterns (tests to " @@ -254,13 +269,14 @@ GTEST_DEFINE_string_( GTEST_DEFINE_bool_( install_failure_signal_handler, - internal::BoolFromGTestEnv("install_failure_signal_handler", false), - "If true and supported on the current platform, " GTEST_NAME_ " should " + testing::internal::BoolFromGTestEnv("install_failure_signal_handler", + false), + "If true and supported on the current platform, " GTEST_NAME_ + " should " "install a signal handler that dumps debugging information when fatal " "signals are raised."); -GTEST_DEFINE_bool_(list_tests, false, - "List all tests without running them."); +GTEST_DEFINE_bool_(list_tests, false, "List all tests without running them."); // The net priority order after flag processing is thus: // --gtest_output command line flag @@ -269,8 +285,8 @@ GTEST_DEFINE_bool_(list_tests, false, // '' GTEST_DEFINE_string_( output, - internal::StringFromGTestEnv("output", - internal::OutputFlagAlsoCheckEnvVar().c_str()), + testing::internal::StringFromGTestEnv( + "output", testing::internal::OutputFlagAlsoCheckEnvVar().c_str()), "A format (defaults to \"xml\" but can be specified to be \"json\"), " "optionally followed by a colon and an output file name or directory. " "A directory is indicated by a trailing pathname separator. " @@ -281,65 +297,79 @@ GTEST_DEFINE_string_( "digits."); GTEST_DEFINE_bool_( - brief, internal::BoolFromGTestEnv("brief", false), + brief, testing::internal::BoolFromGTestEnv("brief", false), "True if only test failures should be displayed in text output."); -GTEST_DEFINE_bool_(print_time, internal::BoolFromGTestEnv("print_time", true), +GTEST_DEFINE_bool_(print_time, + testing::internal::BoolFromGTestEnv("print_time", true), "True if and only if " GTEST_NAME_ " should display elapsed time in text output."); -GTEST_DEFINE_bool_(print_utf8, internal::BoolFromGTestEnv("print_utf8", true), +GTEST_DEFINE_bool_(print_utf8, + testing::internal::BoolFromGTestEnv("print_utf8", true), "True if and only if " GTEST_NAME_ " prints UTF8 characters as text."); GTEST_DEFINE_int32_( - random_seed, - internal::Int32FromGTestEnv("random_seed", 0), + random_seed, testing::internal::Int32FromGTestEnv("random_seed", 0), "Random number seed to use when shuffling test orders. Must be in range " "[1, 99999], or 0 to use a seed based on the current time."); GTEST_DEFINE_int32_( - repeat, - internal::Int32FromGTestEnv("repeat", 1), + repeat, testing::internal::Int32FromGTestEnv("repeat", 1), "How many times to repeat each test. Specify a negative number " "for repeating forever. Useful for shaking out flaky tests."); +GTEST_DEFINE_bool_( + recreate_environments_when_repeating, + testing::internal::BoolFromGTestEnv("recreate_environments_when_repeating", + false), + "Controls whether global test environments are recreated for each repeat " + "of the tests. If set to false the global test environments are only set " + "up once, for the first iteration, and only torn down once, for the last. " + "Useful for shaking out flaky tests with stable, expensive test " + "environments. If --gtest_repeat is set to a negative number, meaning " + "there is no last run, the environments will always be recreated to avoid " + "leaks."); + GTEST_DEFINE_bool_(show_internal_stack_frames, false, "True if and only if " GTEST_NAME_ " should include internal stack frames when " "printing test failure stack traces."); -GTEST_DEFINE_bool_(shuffle, internal::BoolFromGTestEnv("shuffle", false), +GTEST_DEFINE_bool_(shuffle, + testing::internal::BoolFromGTestEnv("shuffle", false), "True if and only if " GTEST_NAME_ " should randomize tests' order on every run."); GTEST_DEFINE_int32_( stack_trace_depth, - internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + testing::internal::Int32FromGTestEnv("stack_trace_depth", + testing::kMaxStackTraceDepth), "The maximum number of stack frames to print when an " "assertion fails. The valid range is 0 through 100, inclusive."); GTEST_DEFINE_string_( stream_result_to, - internal::StringFromGTestEnv("stream_result_to", ""), + testing::internal::StringFromGTestEnv("stream_result_to", ""), "This flag specifies the host name and the port number on which to stream " "test results. Example: \"localhost:555\". The flag is effective only on " "Linux."); GTEST_DEFINE_bool_( throw_on_failure, - internal::BoolFromGTestEnv("throw_on_failure", false), + testing::internal::BoolFromGTestEnv("throw_on_failure", false), "When this flag is specified, a failed assertion will throw an exception " "if exceptions are enabled or exit the program with a non-zero code " "otherwise. For use with an external test framework."); #if GTEST_USE_OWN_FLAGFILE_FLAG_ GTEST_DEFINE_string_( - flagfile, - internal::StringFromGTestEnv("flagfile", ""), + flagfile, testing::internal::StringFromGTestEnv("flagfile", ""), "This flag specifies the flagfile to read command-line flags from."); #endif // GTEST_USE_OWN_FLAGFILE_FLAG_ +namespace testing { namespace internal { // Generates a random number from [0, range), using a Linear @@ -348,10 +378,9 @@ namespace internal { uint32_t Random::Generate(uint32_t range) { // These constants are the same as are used in glibc's rand(3). // Use wider types than necessary to prevent unsigned overflow diagnostics. - state_ = static_cast(1103515245ULL*state_ + 12345U) % kMaxRange; + state_ = static_cast(1103515245ULL * state_ + 12345U) % kMaxRange; - GTEST_CHECK_(range > 0) - << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range > 0) << "Cannot generate a number in the range [0, 0)."; GTEST_CHECK_(range <= kMaxRange) << "Generation of a number in [0, " << range << ") was requested, " << "but this can only generate numbers in [0, " << kMaxRange << ")."; @@ -396,32 +425,26 @@ static bool ShouldRunTestSuite(const TestSuite* test_suite) { } // AssertHelper constructor. -AssertHelper::AssertHelper(TestPartResult::Type type, - const char* file, - int line, - const char* message) - : data_(new AssertHelperData(type, file, line, message)) { -} +AssertHelper::AssertHelper(TestPartResult::Type type, const char* file, + int line, const char* message) + : data_(new AssertHelperData(type, file, line, message)) {} -AssertHelper::~AssertHelper() { - delete data_; -} +AssertHelper::~AssertHelper() { delete data_; } // Message assignment, for assertion streaming support. void AssertHelper::operator=(const Message& message) const { - UnitTest::GetInstance()-> - AddTestPartResult(data_->type, data_->file, data_->line, - AppendUserMessage(data_->message, message), - UnitTest::GetInstance()->impl() - ->CurrentOsStackTraceExceptTop(1) - // Skips the stack frame for this function itself. - ); // NOLINT + UnitTest::GetInstance()->AddTestPartResult( + data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT } namespace { // When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P -// to creates test cases for it, a syntetic test case is +// to creates test cases for it, a synthetic test case is // inserted to report ether an error or a log message. // // This configuration bit will likely be removed at some point. @@ -452,7 +475,6 @@ class FailureTest : public Test { const bool as_error_; }; - } // namespace std::set* GetIgnoredParameterizedTestSuites() { @@ -496,7 +518,8 @@ void InsertSyntheticTestCase(const std::string& name, CodeLocation location, "To suppress this error for this test suite, insert the following line " "(in a non-header) in the namespace it is defined in:" "\n\n" - "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + name + ");"; + "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + + name + ");"; std::string full_name = "UninstantiatedParameterizedTestSuite<" + name + ">"; RegisterTest( // @@ -516,19 +539,18 @@ void RegisterTypeParameterizedTestSuite(const char* test_suite_name, } void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) { - GetUnitTestImpl() - ->type_parameterized_test_registry() - .RegisterInstantiation(case_name); + GetUnitTestImpl()->type_parameterized_test_registry().RegisterInstantiation( + case_name); } void TypeParameterizedTestSuiteRegistry::RegisterTestSuite( const char* test_suite_name, CodeLocation code_location) { suites_.emplace(std::string(test_suite_name), - TypeParameterizedTestSuiteInfo(code_location)); + TypeParameterizedTestSuiteInfo(code_location)); } void TypeParameterizedTestSuiteRegistry::RegisterInstantiation( - const char* test_suite_name) { + const char* test_suite_name) { auto it = suites_.find(std::string(test_suite_name)); if (it != suites_.end()) { it->second.instantiated = true; @@ -606,7 +628,8 @@ FilePath GetCurrentExecutableName() { // Returns the output format, or "" for normal printed output. std::string UnitTestOptions::GetOutputFormat() { - const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + std::string s = GTEST_FLAG_GET(output); + const char* const gtest_output_flag = s.c_str(); const char* const colon = strchr(gtest_output_flag, ':'); return (colon == nullptr) ? std::string(gtest_output_flag) @@ -617,19 +640,19 @@ std::string UnitTestOptions::GetOutputFormat() { // Returns the name of the requested output file, or the default if none // was explicitly specified. std::string UnitTestOptions::GetAbsolutePathToOutputFile() { - const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + std::string s = GTEST_FLAG_GET(output); + const char* const gtest_output_flag = s.c_str(); std::string format = GetOutputFormat(); - if (format.empty()) - format = std::string(kDefaultOutputFormat); + if (format.empty()) format = std::string(kDefaultOutputFormat); const char* const colon = strchr(gtest_output_flag, ':'); if (colon == nullptr) return internal::FilePath::MakeFileName( - internal::FilePath( - UnitTest::GetInstance()->original_working_dir()), - internal::FilePath(kDefaultOutputFile), 0, - format.c_str()).string(); + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile), 0, format.c_str()) + .string(); internal::FilePath output_name(colon + 1); if (!output_name.IsAbsolutePath()) @@ -637,8 +660,7 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() { internal::FilePath(UnitTest::GetInstance()->original_working_dir()), internal::FilePath(colon + 1)); - if (!output_name.IsDirectory()) - return output_name.string(); + if (!output_name.IsDirectory()) return output_name.string(); internal::FilePath result(internal::FilePath::GenerateUniqueFileName( output_name, internal::GetCurrentExecutableName(), @@ -699,59 +721,119 @@ static bool PatternMatchesString(const std::string& name_str, return true; } -bool UnitTestOptions::MatchesFilter(const std::string& name_str, - const char* filter) { - // The filter is a list of patterns separated by colons (:). - const char* pattern = filter; - while (true) { - // Find the bounds of this pattern. - const char* const next_sep = strchr(pattern, ':'); - const char* const pattern_end = - next_sep != nullptr ? next_sep : pattern + strlen(pattern); - - // Check if this pattern matches name_str. - if (PatternMatchesString(name_str, pattern, pattern_end)) { - return true; - } +namespace { + +bool IsGlobPattern(const std::string& pattern) { + return std::any_of(pattern.begin(), pattern.end(), + [](const char c) { return c == '?' || c == '*'; }); +} + +class UnitTestFilter { + public: + UnitTestFilter() = default; + + // Constructs a filter from a string of patterns separated by `:`. + explicit UnitTestFilter(const std::string& filter) { + // By design "" filter matches "" string. + std::vector all_patterns; + SplitString(filter, ':', &all_patterns); + const auto exact_match_patterns_begin = std::partition( + all_patterns.begin(), all_patterns.end(), &IsGlobPattern); + + glob_patterns_.reserve(static_cast( + std::distance(all_patterns.begin(), exact_match_patterns_begin))); + std::move(all_patterns.begin(), exact_match_patterns_begin, + std::inserter(glob_patterns_, glob_patterns_.begin())); + std::move( + exact_match_patterns_begin, all_patterns.end(), + std::inserter(exact_match_patterns_, exact_match_patterns_.begin())); + } + + // Returns true if and only if name matches at least one of the patterns in + // the filter. + bool MatchesName(const std::string& name) const { + return exact_match_patterns_.count(name) > 0 || + std::any_of(glob_patterns_.begin(), glob_patterns_.end(), + [&name](const std::string& pattern) { + return PatternMatchesString( + name, pattern.c_str(), + pattern.c_str() + pattern.size()); + }); + } + + private: + std::vector glob_patterns_; + std::unordered_set exact_match_patterns_; +}; - // Give up on this pattern. However, if we found a pattern separator (:), - // advance to the next pattern (skipping over the separator) and restart. - if (next_sep == nullptr) { - return false; +class PositiveAndNegativeUnitTestFilter { + public: + // Constructs a positive and a negative filter from a string. The string + // contains a positive filter optionally followed by a '-' character and a + // negative filter. In case only a negative filter is provided the positive + // filter will be assumed "*". + // A filter is a list of patterns separated by ':'. + explicit PositiveAndNegativeUnitTestFilter(const std::string& filter) { + std::vector positive_and_negative_filters; + + // NOTE: `SplitString` always returns a non-empty container. + SplitString(filter, '-', &positive_and_negative_filters); + const auto& positive_filter = positive_and_negative_filters.front(); + + if (positive_and_negative_filters.size() > 1) { + positive_filter_ = UnitTestFilter( + positive_filter.empty() ? kUniversalFilter : positive_filter); + + // TODO(b/214626361): Fail on multiple '-' characters + // For the moment to preserve old behavior we concatenate the rest of the + // string parts with `-` as separator to generate the negative filter. + auto negative_filter_string = positive_and_negative_filters[1]; + for (std::size_t i = 2; i < positive_and_negative_filters.size(); i++) + negative_filter_string = + negative_filter_string + '-' + positive_and_negative_filters[i]; + negative_filter_ = UnitTestFilter(negative_filter_string); + } else { + // In case we don't have a negative filter and positive filter is "" + // we do not use kUniversalFilter by design as opposed to when we have a + // negative filter. + positive_filter_ = UnitTestFilter(positive_filter); } - pattern = next_sep + 1; } - return true; + + // Returns true if and only if test name (this is generated by appending test + // suit name and test name via a '.' character) matches the positive filter + // and does not match the negative filter. + bool MatchesTest(const std::string& test_suite_name, + const std::string& test_name) const { + return MatchesName(test_suite_name + "." + test_name); + } + + // Returns true if and only if name matches the positive filter and does not + // match the negative filter. + bool MatchesName(const std::string& name) const { + return positive_filter_.MatchesName(name) && + !negative_filter_.MatchesName(name); + } + + private: + UnitTestFilter positive_filter_; + UnitTestFilter negative_filter_; +}; +} // namespace + +bool UnitTestOptions::MatchesFilter(const std::string& name_str, + const char* filter) { + return UnitTestFilter(filter).MatchesName(name_str); } // Returns true if and only if the user-specified filter matches the test // suite name and the test name. bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name, const std::string& test_name) { - const std::string& full_name = test_suite_name + "." + test_name.c_str(); - // Split --gtest_filter at '-', if there is one, to separate into // positive filter and negative filter portions - const char* const p = GTEST_FLAG(filter).c_str(); - const char* const dash = strchr(p, '-'); - std::string positive; - std::string negative; - if (dash == nullptr) { - positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter - negative = ""; - } else { - positive = std::string(p, dash); // Everything up to the dash - negative = std::string(dash + 1); // Everything after the dash - if (positive.empty()) { - // Treat '-test1' as the same as '*-test1' - positive = kUniversalFilter; - } - } - - // A filter is a colon-separated list of patterns. It matches a - // test if any pattern in it matches the test. - return (MatchesFilter(full_name, positive.c_str()) && - !MatchesFilter(full_name, negative.c_str())); + return PositiveAndNegativeUnitTestFilter(GTEST_FLAG_GET(filter)) + .MatchesTest(test_suite_name, test_name); } #if GTEST_HAS_SEH @@ -771,7 +853,7 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { bool should_handle = true; - if (!GTEST_FLAG(catch_exceptions)) + if (!GTEST_FLAG_GET(catch_exceptions)) should_handle = false; else if (exception_code == EXCEPTION_BREAKPOINT) should_handle = false; @@ -789,8 +871,7 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { // results. Intercepts only failures from the current thread. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( TestPartResultArray* result) - : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), - result_(result) { + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) { Init(); } @@ -799,8 +880,7 @@ ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( // results. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( InterceptMode intercept_mode, TestPartResultArray* result) - : intercept_mode_(intercept_mode), - result_(result) { + : intercept_mode_(intercept_mode), result_(result) { Init(); } @@ -844,9 +924,7 @@ namespace internal { // from user test code. GetTestTypeId() is guaranteed to always // return the same value, as it always calls GetTypeId<>() from the // gtest.cc, which is within the Google Test framework. -TypeId GetTestTypeId() { - return GetTypeId(); -} +TypeId GetTestTypeId() { return GetTypeId(); } // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). @@ -861,9 +939,9 @@ static AssertionResult HasOneFailure(const char* /* results_expr */, const TestPartResultArray& results, TestPartResult::Type type, const std::string& substr) { - const std::string expected(type == TestPartResult::kFatalFailure ? - "1 fatal failure" : - "1 non-fatal failure"); + const std::string expected(type == TestPartResult::kFatalFailure + ? "1 fatal failure" + : "1 non-fatal failure"); Message msg; if (results.size() != 1) { msg << "Expected: " << expected << "\n" @@ -882,10 +960,10 @@ static AssertionResult HasOneFailure(const char* /* results_expr */, } if (strstr(r.message(), substr.c_str()) == nullptr) { - return AssertionFailure() << "Expected: " << expected << " containing \"" - << substr << "\"\n" - << " Actual:\n" - << r; + return AssertionFailure() + << "Expected: " << expected << " containing \"" << substr << "\"\n" + << " Actual:\n" + << r; } return AssertionSuccess(); @@ -908,7 +986,8 @@ SingleFailureChecker::~SingleFailureChecker() { } DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( - UnitTestImpl* unit_test) : unit_test_(unit_test) {} + UnitTestImpl* unit_test) + : unit_test_(unit_test) {} void DefaultGlobalTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { @@ -917,7 +996,8 @@ void DefaultGlobalTestPartResultReporter::ReportTestPartResult( } DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( - UnitTestImpl* unit_test) : unit_test_(unit_test) {} + UnitTestImpl* unit_test) + : unit_test_(unit_test) {} void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { @@ -1024,11 +1104,10 @@ int UnitTestImpl::test_to_run_count() const { // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { return os_stack_trace_getter()->CurrentStackTrace( - static_cast(GTEST_FLAG(stack_trace_depth)), - skip_count + 1 + static_cast(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1 // Skips the user-specified number of frames plus this function // itself. - ); // NOLINT + ); // NOLINT } // A helper class for measuring elapsed times. @@ -1072,8 +1151,7 @@ LPCWSTR String::AnsiToUtf16(const char* ansi) { const int unicode_length = MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0); WCHAR* unicode = new WCHAR[unicode_length + 1]; - MultiByteToWideChar(CP_ACP, 0, ansi, length, - unicode, unicode_length); + MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length); unicode[unicode_length] = 0; return unicode; } @@ -1082,7 +1160,7 @@ LPCWSTR String::AnsiToUtf16(const char* ansi) { // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. -const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { if (!utf16_str) return nullptr; const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr, 0, nullptr, nullptr); @@ -1101,7 +1179,7 @@ const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { // Unlike strcmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. -bool String::CStringEquals(const char * lhs, const char * rhs) { +bool String::CStringEquals(const char* lhs, const char* rhs) { if (lhs == nullptr) return rhs == nullptr; if (rhs == nullptr) return false; @@ -1115,11 +1193,10 @@ bool String::CStringEquals(const char * lhs, const char * rhs) { // encoding, and streams the result to the given Message object. static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, Message* msg) { - for (size_t i = 0; i != length; ) { // NOLINT + for (size_t i = 0; i != length;) { // NOLINT if (wstr[i] != L'\0') { *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); - while (i != length && wstr[i] != L'\0') - i++; + while (i != length && wstr[i] != L'\0') i++; } else { *msg << '\0'; i++; @@ -1161,17 +1238,17 @@ Message::Message() : ss_(new ::std::stringstream) { // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. -Message& Message::operator <<(const wchar_t* wide_c_str) { +Message& Message::operator<<(const wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } -Message& Message::operator <<(wchar_t* wide_c_str) { +Message& Message::operator<<(wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. -Message& Message::operator <<(const ::std::wstring& wstr) { +Message& Message::operator<<(const ::std::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } @@ -1183,44 +1260,6 @@ std::string Message::GetString() const { return internal::StringStreamToString(ss_.get()); } -// AssertionResult constructors. -// Used in EXPECT_TRUE/FALSE(assertion_result). -AssertionResult::AssertionResult(const AssertionResult& other) - : success_(other.success_), - message_(other.message_.get() != nullptr - ? new ::std::string(*other.message_) - : static_cast< ::std::string*>(nullptr)) {} - -// Swaps two AssertionResults. -void AssertionResult::swap(AssertionResult& other) { - using std::swap; - swap(success_, other.success_); - swap(message_, other.message_); -} - -// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. -AssertionResult AssertionResult::operator!() const { - AssertionResult negation(!success_); - if (message_.get() != nullptr) negation << *message_; - return negation; -} - -// Makes a successful assertion result. -AssertionResult AssertionSuccess() { - return AssertionResult(true); -} - -// Makes a failed assertion result. -AssertionResult AssertionFailure() { - return AssertionResult(false); -} - -// Makes a failed assertion result with the given failure message. -// Deprecated; use AssertionFailure() << message. -AssertionResult AssertionFailure(const Message& message) { - return AssertionFailure() << message; -} - namespace internal { namespace edit_distance { @@ -1512,8 +1551,7 @@ std::vector SplitEscapedString(const std::string& str) { AssertionResult EqFailure(const char* lhs_expression, const char* rhs_expression, const std::string& lhs_value, - const std::string& rhs_value, - bool ignoring_case) { + const std::string& rhs_value, bool ignoring_case) { Message msg; msg << "Expected equality of these values:"; msg << "\n " << lhs_expression; @@ -1530,10 +1568,8 @@ AssertionResult EqFailure(const char* lhs_expression, } if (!lhs_value.empty() && !rhs_value.empty()) { - const std::vector lhs_lines = - SplitEscapedString(lhs_value); - const std::vector rhs_lines = - SplitEscapedString(rhs_value); + const std::vector lhs_lines = SplitEscapedString(lhs_value); + const std::vector rhs_lines = SplitEscapedString(rhs_value); if (lhs_lines.size() > 1 || rhs_lines.size() > 1) { msg << "\nWith diff:\n" << edit_distance::CreateUnifiedDiff(lhs_lines, rhs_lines); @@ -1545,27 +1581,21 @@ AssertionResult EqFailure(const char* lhs_expression, // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. std::string GetBoolAssertionFailureMessage( - const AssertionResult& assertion_result, - const char* expression_text, - const char* actual_predicate_value, - const char* expected_predicate_value) { + const AssertionResult& assertion_result, const char* expression_text, + const char* actual_predicate_value, const char* expected_predicate_value) { const char* actual_message = assertion_result.message(); Message msg; msg << "Value of: " << expression_text << "\n Actual: " << actual_predicate_value; - if (actual_message[0] != '\0') - msg << " (" << actual_message << ")"; + if (actual_message[0] != '\0') msg << " (" << actual_message << ")"; msg << "\nExpected: " << expected_predicate_value; return msg.GetString(); } // Helper function for implementing ASSERT_NEAR. -AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, - double val2, - double abs_error) { +AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, + const char* abs_error_expr, double val1, + double val2, double abs_error) { const double diff = fabs(val1 - val2); if (diff <= abs_error) return AssertionSuccess(); @@ -1595,20 +1625,17 @@ AssertionResult DoubleNearPredFormat(const char* expr1, "EXPECT_EQUAL. Consider using EXPECT_DOUBLE_EQ instead."; } return AssertionFailure() - << "The difference between " << expr1 << " and " << expr2 - << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" - << expr1 << " evaluates to " << val1 << ",\n" - << expr2 << " evaluates to " << val2 << ", and\n" - << abs_error_expr << " evaluates to " << abs_error << "."; + << "The difference between " << expr1 << " and " << expr2 << " is " + << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; } - // Helper template for implementing FloatLE() and DoubleLE(). template -AssertionResult FloatingPointLE(const char* expr1, - const char* expr2, - RawType val1, - RawType val2) { +AssertionResult FloatingPointLE(const char* expr1, const char* expr2, + RawType val1, RawType val2) { // Returns success if val1 is less than val2, if (val1 < val2) { return AssertionSuccess(); @@ -1633,24 +1660,24 @@ AssertionResult FloatingPointLE(const char* expr1, << val2; return AssertionFailure() - << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" - << " Actual: " << StringStreamToString(&val1_ss) << " vs " - << StringStreamToString(&val2_ss); + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); } } // namespace internal // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2) { +AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, + float val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2) { +AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, + double val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } @@ -1658,62 +1685,51 @@ namespace internal { // The helper function for {ASSERT|EXPECT}_STREQ. AssertionResult CmpHelperSTREQ(const char* lhs_expression, - const char* rhs_expression, - const char* lhs, + const char* rhs_expression, const char* lhs, const char* rhs) { if (String::CStringEquals(lhs, rhs)) { return AssertionSuccess(); } - return EqFailure(lhs_expression, - rhs_expression, - PrintToString(lhs), - PrintToString(rhs), - false); + return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs), + PrintToString(rhs), false); } // The helper function for {ASSERT|EXPECT}_STRCASEEQ. AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression, - const char* rhs_expression, - const char* lhs, + const char* rhs_expression, const char* lhs, const char* rhs) { if (String::CaseInsensitiveCStringEquals(lhs, rhs)) { return AssertionSuccess(); } - return EqFailure(lhs_expression, - rhs_expression, - PrintToString(lhs), - PrintToString(rhs), - true); + return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs), + PrintToString(rhs), true); } // The helper function for {ASSERT|EXPECT}_STRNE. AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, + const char* s2_expression, const char* s1, const char* s2) { if (!String::CStringEquals(s1, s2)) { return AssertionSuccess(); } else { - return AssertionFailure() << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" << s2_expression + << "), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } // The helper function for {ASSERT|EXPECT}_STRCASENE. AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, + const char* s2_expression, const char* s1, const char* s2) { if (!String::CaseInsensitiveCStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() - << "Expected: (" << s1_expression << ") != (" - << s2_expression << ") (ignoring case), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; + << "Expected: (" << s1_expression << ") != (" << s2_expression + << ") (ignoring case), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } @@ -1741,8 +1757,7 @@ bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { // StringType here can be either ::std::string or ::std::wstring. template -bool IsSubstringPred(const StringType& needle, - const StringType& haystack) { +bool IsSubstringPred(const StringType& needle, const StringType& haystack) { return haystack.find(needle) != StringType::npos; } @@ -1751,21 +1766,22 @@ bool IsSubstringPred(const StringType& needle, // StringType here can be const char*, const wchar_t*, ::std::string, // or ::std::wstring. template -AssertionResult IsSubstringImpl( - bool expected_to_be_substring, - const char* needle_expr, const char* haystack_expr, - const StringType& needle, const StringType& haystack) { +AssertionResult IsSubstringImpl(bool expected_to_be_substring, + const char* needle_expr, + const char* haystack_expr, + const StringType& needle, + const StringType& haystack) { if (IsSubstringPred(needle, haystack) == expected_to_be_substring) return AssertionSuccess(); const bool is_wide_string = sizeof(needle[0]) > 1; const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; return AssertionFailure() - << "Value of: " << needle_expr << "\n" - << " Actual: " << begin_string_quote << needle << "\"\n" - << "Expected: " << (expected_to_be_substring ? "" : "not ") - << "a substring of " << haystack_expr << "\n" - << "Which is: " << begin_string_quote << haystack << "\""; + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; } } // namespace @@ -1774,52 +1790,52 @@ AssertionResult IsSubstringImpl( // substring of haystack (NULL is considered a substring of itself // only), and return an appropriate error message when they fail. -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { +AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { +AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { +AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, const char* needle, + const char* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { +AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, const wchar_t* needle, + const wchar_t* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack) { +AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, + const ::std::string& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack) { +AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, + const ::std::string& needle, + const ::std::string& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #if GTEST_HAS_STD_WSTRING -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack) { +AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, + const ::std::wstring& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack) { +AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, + const ::std::wstring& needle, + const ::std::wstring& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #endif // GTEST_HAS_STD_WSTRING @@ -1831,43 +1847,42 @@ namespace internal { namespace { // Helper function for IsHRESULT{SuccessFailure} predicates -AssertionResult HRESULTFailureHelper(const char* expr, - const char* expected, +AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, long hr) { // NOLINT -# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE // Windows CE doesn't support FormatMessage. const char error_text[] = ""; -# else +#else // Looks up the human-readable system message for the HRESULT code // and since we're not passing any params to FormatMessage, we don't // want inserts expanded. - const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kFlags = + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; const DWORD kBufSize = 4096; // Gets the system's human readable message string for this HRESULT. - char error_text[kBufSize] = { '\0' }; + char error_text[kBufSize] = {'\0'}; DWORD message_length = ::FormatMessageA(kFlags, - 0, // no source, we're asking system + 0, // no source, we're asking system static_cast(hr), // the error - 0, // no line width restrictions + 0, // no line width restrictions error_text, // output buffer kBufSize, // buf size nullptr); // no arguments for inserts // Trims tailing white space (FormatMessage leaves a trailing CR-LF) for (; message_length && IsSpace(error_text[message_length - 1]); - --message_length) { + --message_length) { error_text[message_length - 1] = '\0'; } -# endif // GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_OS_WINDOWS_MOBILE const std::string error_hex("0x" + String::FormatHexInt(hr)); return ::testing::AssertionFailure() - << "Expected: " << expr << " " << expected << ".\n" - << " Actual: " << error_hex << " " << error_text << "\n"; + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << " " << error_text << "\n"; } } // namespace @@ -1901,16 +1916,18 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT // 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // The maximum code-point a one-byte UTF-8 sequence can represent. -constexpr uint32_t kMaxCodePoint1 = (static_cast(1) << 7) - 1; +constexpr uint32_t kMaxCodePoint1 = (static_cast(1) << 7) - 1; // The maximum code-point a two-byte UTF-8 sequence can represent. constexpr uint32_t kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; // The maximum code-point a three-byte UTF-8 sequence can represent. -constexpr uint32_t kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; +constexpr uint32_t kMaxCodePoint3 = + (static_cast(1) << (4 + 2 * 6)) - 1; // The maximum code-point a four-byte UTF-8 sequence can represent. -constexpr uint32_t kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; +constexpr uint32_t kMaxCodePoint4 = + (static_cast(1) << (3 + 3 * 6)) - 1; // Chops off the n lowest bits from a bit pattern. Returns the n // lowest bits. As a side effect, the original bit pattern will be @@ -1935,7 +1952,7 @@ std::string CodePointToUtf8(uint32_t code_point) { char str[5]; // Big enough for the largest valid code point. if (code_point <= kMaxCodePoint1) { str[1] = '\0'; - str[0] = static_cast(code_point); // 0xxxxxxx + str[0] = static_cast(code_point); // 0xxxxxxx } else if (code_point <= kMaxCodePoint2) { str[2] = '\0'; str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx @@ -1963,8 +1980,8 @@ std::string CodePointToUtf8(uint32_t code_point) { // and thus should be combined into a single Unicode code point // using CreateCodePointFromUtf16SurrogatePair. inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { - return sizeof(wchar_t) == 2 && - (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; + return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 && + (second & 0xFC00) == 0xDC00; } // Creates a Unicode code point from UTF16 surrogate pair. @@ -1995,8 +2012,7 @@ inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first, // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. std::string WideStringToUtf8(const wchar_t* str, int num_chars) { - if (num_chars == -1) - num_chars = static_cast(wcslen(str)); + if (num_chars == -1) num_chars = static_cast(wcslen(str)); ::std::stringstream stream; for (int i = 0; i < num_chars; ++i) { @@ -2005,8 +2021,8 @@ std::string WideStringToUtf8(const wchar_t* str, int num_chars) { if (str[i] == L'\0') { break; } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { - unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], - str[i + 1]); + unicode_code_point = + CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]); i++; } else { unicode_code_point = static_cast(str[i]); @@ -2019,7 +2035,7 @@ std::string WideStringToUtf8(const wchar_t* str, int num_chars) { // Converts a wide C string to an std::string using the UTF-8 encoding. // NULL will be converted to "(null)". -std::string String::ShowWideCString(const wchar_t * wide_c_str) { +std::string String::ShowWideCString(const wchar_t* wide_c_str) { if (wide_c_str == nullptr) return "(null)"; return internal::WideStringToUtf8(wide_c_str, -1); @@ -2031,7 +2047,7 @@ std::string String::ShowWideCString(const wchar_t * wide_c_str) { // Unlike wcscmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. -bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { +bool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { if (lhs == nullptr) return rhs == nullptr; if (rhs == nullptr) return false; @@ -2041,33 +2057,27 @@ bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { // Helper function for *_STREQ on wide strings. AssertionResult CmpHelperSTREQ(const char* lhs_expression, - const char* rhs_expression, - const wchar_t* lhs, + const char* rhs_expression, const wchar_t* lhs, const wchar_t* rhs) { if (String::WideCStringEquals(lhs, rhs)) { return AssertionSuccess(); } - return EqFailure(lhs_expression, - rhs_expression, - PrintToString(lhs), - PrintToString(rhs), - false); + return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs), + PrintToString(rhs), false); } // Helper function for *_STRNE on wide strings. AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, + const char* s2_expression, const wchar_t* s1, const wchar_t* s2) { if (!String::WideCStringEquals(s1, s2)) { return AssertionSuccess(); } - return AssertionFailure() << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: " - << PrintToString(s1) - << " vs " << PrintToString(s2); + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" << s2_expression + << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2); } // Compares two C strings, ignoring case. Returns true if and only if they have @@ -2076,7 +2086,7 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression, // Unlike strcasecmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. -bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { +bool String::CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { if (lhs == nullptr) return rhs == nullptr; if (rhs == nullptr) return false; return posix::StrCaseCmp(lhs, rhs) == 0; @@ -2118,8 +2128,8 @@ bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, // Returns true if and only if str ends with the given suffix, ignoring case. // Any string is considered to end with an empty suffix. -bool String::EndsWithCaseInsensitive( - const std::string& str, const std::string& suffix) { +bool String::EndsWithCaseInsensitive(const std::string& str, + const std::string& suffix) { const size_t str_len = str.length(); const size_t suffix_len = suffix.length(); return (str_len >= suffix_len) && @@ -2202,15 +2212,13 @@ TestResult::TestResult() : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {} // D'tor. -TestResult::~TestResult() { -} +TestResult::~TestResult() {} // Returns the i-th test part result among all the results. i can // range from 0 to total_part_count() - 1. If i is not in that range, // aborts the program. const TestPartResult& TestResult::GetTestPartResult(int i) const { - if (i < 0 || i >= total_part_count()) - internal::posix::Abort(); + if (i < 0 || i >= total_part_count()) internal::posix::Abort(); return test_part_results_.at(static_cast(i)); } @@ -2218,15 +2226,12 @@ const TestPartResult& TestResult::GetTestPartResult(int i) const { // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& TestResult::GetTestProperty(int i) const { - if (i < 0 || i >= test_property_count()) - internal::posix::Abort(); + if (i < 0 || i >= test_property_count()) internal::posix::Abort(); return test_properties_.at(static_cast(i)); } // Clears the test part results. -void TestResult::ClearTestPartResults() { - test_part_results_.clear(); -} +void TestResult::ClearTestPartResults() { test_part_results_.clear(); } // Adds a test part result to the list. void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { @@ -2255,15 +2260,8 @@ void TestResult::RecordProperty(const std::string& xml_element, // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuitesAttributes[] = { - "disabled", - "errors", - "failures", - "name", - "random_seed", - "tests", - "time", - "timestamp" -}; + "disabled", "errors", "failures", "name", + "random_seed", "tests", "time", "timestamp"}; // The list of reserved attributes used in the element of XML // output. @@ -2273,8 +2271,8 @@ static const char* const kReservedTestSuiteAttributes[] = { // The list of reserved attributes used in the element of XML output. static const char* const kReservedTestCaseAttributes[] = { - "classname", "name", "status", "time", "type_param", - "value_param", "file", "line"}; + "classname", "name", "status", "time", + "type_param", "value_param", "file", "line"}; // Use a slightly different set for allowed output to ensure existing tests can // still RecordProperty("result") or "RecordProperty(timestamp") @@ -2336,7 +2334,7 @@ static bool ValidateTestPropertyName( const std::string& property_name, const std::vector& reserved_names) { if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != - reserved_names.end()) { + reserved_names.end()) { ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name << " (" << FormatWordList(reserved_names) << " are reserved by " << GTEST_NAME_ << ")"; @@ -2374,8 +2372,7 @@ bool TestResult::Skipped() const { // Returns true if and only if the test failed. bool TestResult::Failed() const { for (int i = 0; i < total_part_count(); ++i) { - if (GetTestPartResult(i).failed()) - return true; + if (GetTestPartResult(i).failed()) return true; } return false; } @@ -2416,27 +2413,22 @@ int TestResult::test_property_count() const { // Creates a Test object. // The c'tor saves the states of all flags. -Test::Test() - : gtest_flag_saver_(new GTEST_FLAG_SAVER_) { -} +Test::Test() : gtest_flag_saver_(new GTEST_FLAG_SAVER_) {} // The d'tor restores the states of all flags. The actual work is // done by the d'tor of the gtest_flag_saver_ field, and thus not // visible here. -Test::~Test() { -} +Test::~Test() {} // Sets up the test fixture. // // A sub-class may override this. -void Test::SetUp() { -} +void Test::SetUp() {} // Tears down the test fixture. // // A sub-class may override this. -void Test::TearDown() { -} +void Test::TearDown() {} // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, const std::string& value) { @@ -2541,8 +2533,8 @@ bool Test::HasSameFixtureClass() { static std::string* FormatSehExceptionMessage(DWORD exception_code, const char* location) { Message message; - message << "SEH exception with code 0x" << std::setbase(16) << - exception_code << std::setbase(10) << " thrown in " << location << "."; + message << "SEH exception with code 0x" << std::setbase(16) << exception_code + << std::setbase(10) << " thrown in " << location << "."; return new std::string(message.GetString()); } @@ -2585,8 +2577,8 @@ GoogleTestFailureException::GoogleTestFailureException( // exceptions in the same function. Therefore, we provide a separate // wrapper function for handling SEH exceptions.) template -Result HandleSehExceptionsInMethodIfSupported( - T* object, Result (T::*method)(), const char* location) { +Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::*method)(), + const char* location) { #if GTEST_HAS_SEH __try { return (object->*method)(); @@ -2595,8 +2587,8 @@ Result HandleSehExceptionsInMethodIfSupported( // We create the exception message on the heap because VC++ prohibits // creation of objects with destructors on stack in functions using __try // (see error C2712). - std::string* exception_message = FormatSehExceptionMessage( - GetExceptionCode(), location); + std::string* exception_message = + FormatSehExceptionMessage(GetExceptionCode(), location); internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, *exception_message); delete exception_message; @@ -2612,8 +2604,8 @@ Result HandleSehExceptionsInMethodIfSupported( // exceptions, if they are supported; returns the 0-value for type // Result in case of an SEH exception. template -Result HandleExceptionsInMethodIfSupported( - T* object, Result (T::*method)(), const char* location) { +Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(), + const char* location) { // NOTE: The user code can affect the way in which Google Test handles // exceptions by setting GTEST_FLAG(catch_exceptions), but only before // RUN_ALL_TESTS() starts. It is technically possible to check the flag @@ -2623,7 +2615,7 @@ Result HandleExceptionsInMethodIfSupported( // try { // // Perform the test method. // } catch (...) { - // if (GTEST_FLAG(catch_exceptions)) + // if (GTEST_FLAG_GET(catch_exceptions)) // // Report the exception as failure. // else // throw; // Re-throws the original exception. @@ -2679,16 +2671,16 @@ void Test::Run() { // GTEST_SKIP(). if (!HasFatalFailure() && !IsSkipped()) { impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &Test::TestBody, "the test body"); + internal::HandleExceptionsInMethodIfSupported(this, &Test::TestBody, + "the test body"); } // However, we want to clean up as much as possible. Hence we will // always call TearDown(), even if SetUp() or the test body has // failed. impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &Test::TearDown, "TearDown()"); + internal::HandleExceptionsInMethodIfSupported(this, &Test::TearDown, + "TearDown()"); } // Returns true if and only if the current test has a fatal failure. @@ -2698,8 +2690,9 @@ bool Test::HasFatalFailure() { // Returns true if and only if the current test has a non-fatal failure. bool Test::HasNonfatalFailure() { - return internal::GetUnitTestImpl()->current_test_result()-> - HasNonfatalFailure(); + return internal::GetUnitTestImpl() + ->current_test_result() + ->HasNonfatalFailure(); } // Returns true if and only if the current test was skipped. @@ -2799,11 +2792,10 @@ class TestNameIs { // Constructor. // // TestNameIs has NO default constructor. - explicit TestNameIs(const char* name) - : name_(name) {} + explicit TestNameIs(const char* name) : name_(name) {} // Returns true if and only if the test name of test_info matches name_. - bool operator()(const TestInfo * test_info) const { + bool operator()(const TestInfo* test_info) const { return test_info && test_info->name() == name_; } @@ -2831,20 +2823,20 @@ void UnitTestImpl::RegisterParameterizedTests() { // Creates the test object, runs it, records its result, and then // deletes it. void TestInfo::Run() { - if (!should_run_) return; + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + if (!should_run_) { + if (is_disabled_ && matches_filter_) repeater->OnTestDisabled(*this); + return; + } // Tells UnitTest where to store test result. internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_info(this); - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - // Notifies the unit test event listeners that a test is about to start. repeater->OnTestStart(*this); - result_.set_start_timestamp(internal::GetTimeInMillis()); internal::Timer timer; - impl->os_stack_trace_getter()->UponLeavingGTest(); // Creates the test object. @@ -3009,11 +3001,18 @@ void TestSuite::Run() { internal::HandleExceptionsInMethodIfSupported( this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()"); + const bool skip_all = ad_hoc_test_result().Failed(); + start_timestamp_ = internal::GetTimeInMillis(); internal::Timer timer; for (int i = 0; i < total_test_count(); i++) { - GetMutableTestInfo(i)->Run(); - if (GTEST_FLAG(fail_fast) && GetMutableTestInfo(i)->result()->Failed()) { + if (skip_all) { + GetMutableTestInfo(i)->Skip(); + } else { + GetMutableTestInfo(i)->Run(); + } + if (GTEST_FLAG_GET(fail_fast) && + GetMutableTestInfo(i)->result()->Failed()) { for (int j = i + 1; j < total_test_count(); j++) { GetMutableTestInfo(j)->Skip(); } @@ -3089,11 +3088,10 @@ void TestSuite::UnshuffleTests() { // // FormatCountableNoun(1, "formula", "formuli") returns "1 formula". // FormatCountableNoun(5, "book", "books") returns "5 books". -static std::string FormatCountableNoun(int count, - const char * singular_form, - const char * plural_form) { +static std::string FormatCountableNoun(int count, const char* singular_form, + const char* plural_form) { return internal::StreamableToString(count) + " " + - (count == 1 ? singular_form : plural_form); + (count == 1 ? singular_form : plural_form); } // Formats the count of tests. @@ -3110,7 +3108,7 @@ static std::string FormatTestSuiteCount(int test_suite_count) { // representation. Both kNonFatalFailure and kFatalFailure are translated // to "Failure", as the user usually doesn't care about the difference // between the two when viewing the test result. -static const char * TestPartResultTypeToString(TestPartResult::Type type) { +static const char* TestPartResultTypeToString(TestPartResult::Type type) { switch (type) { case TestPartResult::kSkip: return "Skipped\n"; @@ -3130,21 +3128,23 @@ static const char * TestPartResultTypeToString(TestPartResult::Type type) { } namespace internal { +enum class GTestColor { kDefault, kRed, kGreen, kYellow }; // Prints a TestPartResult to an std::string. static std::string PrintTestPartResultToString( const TestPartResult& test_part_result) { - return (Message() - << internal::FormatFileLocation(test_part_result.file_name(), - test_part_result.line_number()) - << " " << TestPartResultTypeToString(test_part_result.type()) - << test_part_result.message()).GetString(); + return (Message() << internal::FormatFileLocation( + test_part_result.file_name(), + test_part_result.line_number()) + << " " + << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()) + .GetString(); } // Prints a TestPartResult. static void PrintTestPartResult(const TestPartResult& test_part_result) { - const std::string& result = - PrintTestPartResultToString(test_part_result); + const std::string& result = PrintTestPartResultToString(test_part_result); printf("%s\n", result.c_str()); fflush(stdout); // If the test program runs in Visual Studio or a debugger, the @@ -3161,8 +3161,8 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) { } // class PrettyUnitTestResultPrinter -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ - !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ + !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW // Returns the character attribute for the given color. static WORD GetColorAttribute(GTestColor color) { @@ -3173,7 +3173,8 @@ static WORD GetColorAttribute(GTestColor color) { return FOREGROUND_GREEN; case GTestColor::kYellow: return FOREGROUND_RED | FOREGROUND_GREEN; - default: return 0; + default: + return 0; } } @@ -3229,7 +3230,8 @@ static const char* GetAnsiColorCode(GTestColor color) { // Returns true if and only if Google Test should use colors in the output. bool ShouldUseColor(bool stdout_is_tty) { - const char* const gtest_color = GTEST_FLAG(color).c_str(); + std::string c = GTEST_FLAG_GET(color); + const char* const gtest_color = c.c_str(); if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW @@ -3256,9 +3258,9 @@ bool ShouldUseColor(bool stdout_is_tty) { } return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || - String::CaseInsensitiveCStringEquals(gtest_color, "true") || - String::CaseInsensitiveCStringEquals(gtest_color, "t") || - String::CStringEquals(gtest_color, "1"); + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); // We take "yes", "true", "t", and "1" as meaning "yes". If the // value is neither one of these nor "auto", we treat it as "no" to // be conservative. @@ -3270,18 +3272,13 @@ bool ShouldUseColor(bool stdout_is_tty) { // that would be colored when printed, as can be done on Linux. GTEST_ATTRIBUTE_PRINTF_(2, 3) -void ColoredPrintf(GTestColor color, const char *fmt, ...) { +void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \ - GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM) - const bool use_color = AlwaysFalse(); -#else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); const bool use_color = in_color_mode && (color != GTestColor::kDefault); -#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS if (!use_color) { vprintf(fmt, args); @@ -3289,8 +3286,8 @@ void ColoredPrintf(GTestColor color, const char *fmt, ...) { return; } -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ - !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ + !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -3361,6 +3358,7 @@ class PrettyUnitTestResultPrinter : public TestEventListener { #endif // OnTestCaseStart void OnTestStart(const TestInfo& test_info) override; + void OnTestDisabled(const TestInfo& test_info) override; void OnTestPartResult(const TestPartResult& result) override; void OnTestEnd(const TestInfo& test_info) override; @@ -3381,13 +3379,14 @@ class PrettyUnitTestResultPrinter : public TestEventListener { static void PrintSkippedTests(const UnitTest& unit_test); }; - // Fired before each iteration of tests starts. +// Fired before each iteration of tests starts. void PrettyUnitTestResultPrinter::OnTestIterationStart( const UnitTest& unit_test, int iteration) { - if (GTEST_FLAG(repeat) != 1) + if (GTEST_FLAG_GET(repeat) != 1) printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); - const char* const filter = GTEST_FLAG(filter).c_str(); + std::string f = GTEST_FLAG_GET(filter); + const char* const filter = f.c_str(); // Prints the filter if it's not *. This reminds the user that some // tests may be skipped. @@ -3403,7 +3402,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart( internal::posix::GetEnv(kTestTotalShards)); } - if (GTEST_FLAG(shuffle)) { + if (GTEST_FLAG_GET(shuffle)) { ColoredPrintf(GTestColor::kYellow, "Note: Randomizing tests' orders with a seed of %d .\n", unit_test.random_seed()); @@ -3459,6 +3458,13 @@ void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { fflush(stdout); } +void PrettyUnitTestResultPrinter::OnTestDisabled(const TestInfo& test_info) { + ColoredPrintf(GTestColor::kYellow, "[ DISABLED ] "); + PrintTestName(test_info.test_suite_name(), test_info.name()); + printf("\n"); + fflush(stdout); +} + // Called after an assertion failure. void PrettyUnitTestResultPrinter::OnTestPartResult( const TestPartResult& result) { @@ -3483,12 +3489,12 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); } PrintTestName(test_info.test_suite_name(), test_info.name()); - if (test_info.result()->Failed()) - PrintFullTestCommentIfPresent(test_info); + if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info); - if (GTEST_FLAG(print_time)) { - printf(" (%s ms)\n", internal::StreamableToString( - test_info.result()->elapsed_time()).c_str()); + if (GTEST_FLAG_GET(print_time)) { + printf(" (%s ms)\n", + internal::StreamableToString(test_info.result()->elapsed_time()) + .c_str()); } else { printf("\n"); } @@ -3497,7 +3503,7 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { - if (!GTEST_FLAG(print_time)) return; + if (!GTEST_FLAG_GET(print_time)) return; const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); @@ -3508,7 +3514,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { } #else void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) { - if (!GTEST_FLAG(print_time)) return; + if (!GTEST_FLAG_GET(print_time)) return; const std::string counts = FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); @@ -3604,7 +3610,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); - if (GTEST_FLAG(print_time)) { + if (GTEST_FLAG_GET(print_time)) { printf(" (%s ms total)", internal::StreamableToString(unit_test.elapsed_time()).c_str()); } @@ -3625,7 +3631,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, } int num_disabled = unit_test.reportable_disabled_test_count(); - if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) { if (unit_test.Passed()) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } @@ -3661,6 +3667,7 @@ class BriefUnitTestResultPrinter : public TestEventListener { #endif // OnTestCaseStart void OnTestStart(const TestInfo& /*test_info*/) override {} + void OnTestDisabled(const TestInfo& /*test_info*/) override {} void OnTestPartResult(const TestPartResult& result) override; void OnTestEnd(const TestInfo& test_info) override; @@ -3697,7 +3704,7 @@ void BriefUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { PrintTestName(test_info.test_suite_name(), test_info.name()); PrintFullTestCommentIfPresent(test_info); - if (GTEST_FLAG(print_time)) { + if (GTEST_FLAG_GET(print_time)) { printf(" (%s ms)\n", internal::StreamableToString(test_info.result()->elapsed_time()) .c_str()); @@ -3714,7 +3721,7 @@ void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); - if (GTEST_FLAG(print_time)) { + if (GTEST_FLAG_GET(print_time)) { printf(" (%s ms total)", internal::StreamableToString(unit_test.elapsed_time()).c_str()); } @@ -3729,7 +3736,7 @@ void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, } int num_disabled = unit_test.reportable_disabled_test_count(); - if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) { if (unit_test.Passed()) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } @@ -3749,7 +3756,7 @@ class TestEventRepeater : public TestEventListener { public: TestEventRepeater() : forwarding_enabled_(true) {} ~TestEventRepeater() override; - void Append(TestEventListener *listener); + void Append(TestEventListener* listener); TestEventListener* Release(TestEventListener* listener); // Controls whether events will be forwarded to listeners_. Set to false @@ -3767,6 +3774,7 @@ class TestEventRepeater : public TestEventListener { #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ void OnTestSuiteStart(const TestSuite& parameter) override; void OnTestStart(const TestInfo& test_info) override; + void OnTestDisabled(const TestInfo& test_info) override; void OnTestPartResult(const TestPartResult& result) override; void OnTestEnd(const TestInfo& test_info) override; // Legacy API is deprecated but still available @@ -3786,18 +3794,19 @@ class TestEventRepeater : public TestEventListener { // The list of listeners that receive events. std::vector listeners_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); + TestEventRepeater(const TestEventRepeater&) = delete; + TestEventRepeater& operator=(const TestEventRepeater&) = delete; }; TestEventRepeater::~TestEventRepeater() { ForEach(listeners_, Delete); } -void TestEventRepeater::Append(TestEventListener *listener) { +void TestEventRepeater::Append(TestEventListener* listener) { listeners_.push_back(listener); } -TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { +TestEventListener* TestEventRepeater::Release(TestEventListener* listener) { for (size_t i = 0; i < listeners_.size(); ++i) { if (listeners_[i] == listener) { listeners_.erase(listeners_.begin() + static_cast(i)); @@ -3810,14 +3819,14 @@ TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { // Since most methods are very similar, use macros to reduce boilerplate. // This defines a member that forwards the call to all listeners. -#define GTEST_REPEATER_METHOD_(Name, Type) \ -void TestEventRepeater::Name(const Type& parameter) { \ - if (forwarding_enabled_) { \ - for (size_t i = 0; i < listeners_.size(); i++) { \ - listeners_[i]->Name(parameter); \ - } \ - } \ -} +#define GTEST_REPEATER_METHOD_(Name, Type) \ + void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ + } // This defines a member that forwards the call to all listeners in reverse // order. #define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ @@ -3837,6 +3846,7 @@ GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite) #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite) GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestDisabled, TestInfo) GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) @@ -3887,12 +3897,13 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { private: // Is c a whitespace character that is normalized to a space character // when it appears in an XML attribute value? - static bool IsNormalizableWhitespace(char c) { - return c == 0x9 || c == 0xA || c == 0xD; + static bool IsNormalizableWhitespace(unsigned char c) { + return c == '\t' || c == '\n' || c == '\r'; } // May c appear in a well-formed XML document? - static bool IsValidXmlCharacter(char c) { + // https://www.w3.org/TR/REC-xml/#charsets + static bool IsValidXmlCharacter(unsigned char c) { return IsNormalizableWhitespace(c) || c >= 0x20; } @@ -3962,7 +3973,8 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { // The output file. const std::string output_file_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); + XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete; + XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter&) = delete; }; // Creates a new XmlUnitTestResultPrinter. @@ -4002,8 +4014,8 @@ void XmlUnitTestResultPrinter::ListTestsMatchingFilter( // module will consist of ordinary English text. // If this module is ever modified to produce version 1.1 XML output, // most invalid characters can be retained using character references. -std::string XmlUnitTestResultPrinter::EscapeXml( - const std::string& str, bool is_attribute) { +std::string XmlUnitTestResultPrinter::EscapeXml(const std::string& str, + bool is_attribute) { Message m; for (size_t i = 0; i < str.size(); ++i) { @@ -4031,8 +4043,9 @@ std::string XmlUnitTestResultPrinter::EscapeXml( m << '"'; break; default: - if (IsValidXmlCharacter(ch)) { - if (is_attribute && IsNormalizableWhitespace(ch)) + if (IsValidXmlCharacter(static_cast(ch))) { + if (is_attribute && + IsNormalizableWhitespace(static_cast(ch))) m << "&#x" << String::FormatByte(static_cast(ch)) << ";"; else @@ -4053,7 +4066,7 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( std::string output; output.reserve(str.size()); for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) - if (IsValidXmlCharacter(*it)) + if (IsValidXmlCharacter(static_cast(*it))) output.push_back(*it); return output; @@ -4061,7 +4074,6 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( // The following routines generate an XML representation of a UnitTest // object. -// GOOGLETEST_CM0009 DO NOT DELETE // // This is how Google Test concepts map to the DTD: // @@ -4110,12 +4122,12 @@ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { return ""; // YYYY-MM-DDThh:mm:ss.sss return StreamableToString(time_struct.tm_year + 1900) + "-" + - String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + - String::FormatIntWidth2(time_struct.tm_mday) + "T" + - String::FormatIntWidth2(time_struct.tm_hour) + ":" + - String::FormatIntWidth2(time_struct.tm_min) + ":" + - String::FormatIntWidth2(time_struct.tm_sec) + "." + - String::FormatIntWidthN(static_cast(ms % 1000), 3); + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec) + "." + + String::FormatIntWidthN(static_cast(ms % 1000), 3); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. @@ -4126,8 +4138,8 @@ void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, for (;;) { const char* const next_segment = strstr(segment, "]]>"); if (next_segment != nullptr) { - stream->write( - segment, static_cast(next_segment - segment)); + stream->write(segment, + static_cast(next_segment - segment)); *stream << "]]>]]>"); } else { @@ -4139,15 +4151,13 @@ void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, } void XmlUnitTestResultPrinter::OutputXmlAttribute( - std::ostream* stream, - const std::string& element_name, - const std::string& name, - const std::string& value) { + std::ostream* stream, const std::string& element_name, + const std::string& name, const std::string& value) { const std::vector& allowed_names = GetReservedOutputAttributesForElement(element_name); GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != - allowed_names.end()) + allowed_names.end()) << "Attribute " << name << " is not allowed for element <" << element_name << ">."; @@ -4213,10 +4223,11 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, OutputXmlAttribute(stream, kTestsuite, "type_param", test_info.type_param()); } - if (GTEST_FLAG(list_tests)) { - OutputXmlAttribute(stream, kTestsuite, "file", test_info.file()); - OutputXmlAttribute(stream, kTestsuite, "line", - StreamableToString(test_info.line())); + + OutputXmlAttribute(stream, kTestsuite, "file", test_info.file()); + OutputXmlAttribute(stream, kTestsuite, "line", + StreamableToString(test_info.line())); + if (GTEST_FLAG_GET(list_tests)) { *stream << " />\n"; return; } @@ -4251,8 +4262,7 @@ void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream, internal::FormatCompilerIndependentFileLocation(part.file_name(), part.line_number()); const std::string summary = location + "\n" + part.summary(); - *stream << " "; const std::string detail = location + "\n" + part.message(); OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); @@ -4292,7 +4302,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream, OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name()); OutputXmlAttribute(stream, kTestsuite, "tests", StreamableToString(test_suite.reportable_test_count())); - if (!GTEST_FLAG(list_tests)) { + if (!GTEST_FLAG_GET(list_tests)) { OutputXmlAttribute(stream, kTestsuite, "failures", StreamableToString(test_suite.failed_test_count())); OutputXmlAttribute( @@ -4340,7 +4350,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, stream, kTestsuites, "timestamp", FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); - if (GTEST_FLAG(shuffle)) { + if (GTEST_FLAG_GET(shuffle)) { OutputXmlAttribute(stream, kTestsuites, "random_seed", StreamableToString(unit_test.random_seed())); } @@ -4393,7 +4403,7 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); attributes << " " << property.key() << "=" - << "\"" << EscapeXmlAttribute(property.value()) << "\""; + << "\"" << EscapeXmlAttribute(property.value()) << "\""; } return attributes.GetString(); } @@ -4407,15 +4417,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties( return; } - *stream << "<" << kProperties << ">\n"; + *stream << " <" << kProperties << ">\n"; for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); - *stream << "<" << kProperty; + *stream << " <" << kProperty; *stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\""; *stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\""; *stream << "/>\n"; } - *stream << "\n"; + *stream << " \n"; } // End XmlUnitTestResultPrinter @@ -4439,16 +4449,12 @@ class JsonUnitTestResultPrinter : public EmptyTestEventListener { //// streams the attribute as JSON. static void OutputJsonKey(std::ostream* stream, const std::string& element_name, - const std::string& name, - const std::string& value, - const std::string& indent, - bool comma = true); + const std::string& name, const std::string& value, + const std::string& indent, bool comma = true); static void OutputJsonKey(std::ostream* stream, const std::string& element_name, - const std::string& name, - int value, - const std::string& indent, - bool comma = true); + const std::string& name, int value, + const std::string& indent, bool comma = true); // Streams a test suite JSON stanza containing the given test result. // @@ -4481,7 +4487,9 @@ class JsonUnitTestResultPrinter : public EmptyTestEventListener { // The output file. const std::string output_file_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(JsonUnitTestResultPrinter); + JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete; + JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrinter&) = + delete; }; // Creates a new JsonUnitTestResultPrinter. @@ -4493,7 +4501,7 @@ JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file) } void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { + int /*iteration*/) { FILE* jsonout = OpenFileForWriting(output_file_); std::stringstream stream; PrintJsonUnitTest(&stream, unit_test); @@ -4559,55 +4567,48 @@ static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) { return ""; // YYYY-MM-DDThh:mm:ss return StreamableToString(time_struct.tm_year + 1900) + "-" + - String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + - String::FormatIntWidth2(time_struct.tm_mday) + "T" + - String::FormatIntWidth2(time_struct.tm_hour) + ":" + - String::FormatIntWidth2(time_struct.tm_min) + ":" + - String::FormatIntWidth2(time_struct.tm_sec) + "Z"; + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec) + "Z"; } static inline std::string Indent(size_t width) { return std::string(width, ' '); } -void JsonUnitTestResultPrinter::OutputJsonKey( - std::ostream* stream, - const std::string& element_name, - const std::string& name, - const std::string& value, - const std::string& indent, - bool comma) { +void JsonUnitTestResultPrinter::OutputJsonKey(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value, + const std::string& indent, + bool comma) { const std::vector& allowed_names = GetReservedOutputAttributesForElement(element_name); GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != - allowed_names.end()) + allowed_names.end()) << "Key \"" << name << "\" is not allowed for value \"" << element_name << "\"."; *stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\""; - if (comma) - *stream << ",\n"; + if (comma) *stream << ",\n"; } void JsonUnitTestResultPrinter::OutputJsonKey( - std::ostream* stream, - const std::string& element_name, - const std::string& name, - int value, - const std::string& indent, - bool comma) { + std::ostream* stream, const std::string& element_name, + const std::string& name, int value, const std::string& indent, bool comma) { const std::vector& allowed_names = GetReservedOutputAttributesForElement(element_name); GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != - allowed_names.end()) + allowed_names.end()) << "Key \"" << name << "\" is not allowed for value \"" << element_name << "\"."; *stream << indent << "\"" << name << "\": " << StreamableToString(value); - if (comma) - *stream << ",\n"; + if (comma) *stream << ",\n"; } // Streams a test suite JSON stanza containing the given test result. @@ -4617,7 +4618,7 @@ void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult( *stream << Indent(4) << "{\n"; OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6)); OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6)); - if (!GTEST_FLAG(list_tests)) { + if (!GTEST_FLAG_GET(list_tests)) { OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6)); OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6)); OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6)); @@ -4671,11 +4672,14 @@ void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream, OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(), kIndent); } - if (GTEST_FLAG(list_tests)) { - OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent); - OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false); + + OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent); + OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false); + if (GTEST_FLAG_GET(list_tests)) { *stream << "\n" << Indent(8) << "}"; return; + } else { + *stream << ",\n"; } OutputJsonKey(stream, kTestsuite, "status", @@ -4707,7 +4711,9 @@ void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream, if (part.failed()) { *stream << ",\n"; if (++failures == 1) { - *stream << kIndent << "\"" << "failures" << "\": [\n"; + *stream << kIndent << "\"" + << "failures" + << "\": [\n"; } const std::string location = internal::FormatCompilerIndependentFileLocation(part.file_name(), @@ -4720,8 +4726,7 @@ void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream, } } - if (failures > 0) - *stream << "\n" << kIndent << "]"; + if (failures > 0) *stream << "\n" << kIndent << "]"; *stream << "\n" << Indent(8) << "}"; } @@ -4735,7 +4740,7 @@ void JsonUnitTestResultPrinter::PrintJsonTestSuite( OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent); OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(), kIndent); - if (!GTEST_FLAG(list_tests)) { + if (!GTEST_FLAG_GET(list_tests)) { OutputJsonKey(stream, kTestsuite, "failures", test_suite.failed_test_count(), kIndent); OutputJsonKey(stream, kTestsuite, "disabled", @@ -4782,7 +4787,7 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream, OutputJsonKey(stream, kTestsuites, "disabled", unit_test.reportable_disabled_test_count(), kIndent); OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent); - if (GTEST_FLAG(shuffle)) { + if (GTEST_FLAG_GET(shuffle)) { OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(), kIndent); } @@ -4817,7 +4822,9 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream, OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); } - *stream << "\n" << kIndent << "]\n" << "}\n"; + *stream << "\n" + << kIndent << "]\n" + << "}\n"; } void JsonUnitTestResultPrinter::PrintJsonTestList( @@ -4852,7 +4859,8 @@ std::string JsonUnitTestResultPrinter::TestPropertiesAsJson( Message attributes; for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); - attributes << ",\n" << indent << "\"" << property.key() << "\": " + attributes << ",\n" + << indent << "\"" << property.key() << "\": " << "\"" << EscapeJson(property.value()) << "\""; } return attributes.GetString(); @@ -4892,14 +4900,14 @@ void StreamingListener::SocketWriter::MakeConnection() { addrinfo hints; memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. hints.ai_socktype = SOCK_STREAM; addrinfo* servinfo = nullptr; // Use the getaddrinfo() to get a linked list of IP addresses for // the given host name. - const int error_num = getaddrinfo( - host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + const int error_num = + getaddrinfo(host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); if (error_num != 0) { GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " << gai_strerror(error_num); @@ -4908,8 +4916,8 @@ void StreamingListener::SocketWriter::MakeConnection() { // Loop through all the results and connect to the first we can. for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr; cur_addr = cur_addr->ai_next) { - sockfd_ = socket( - cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + sockfd_ = socket(cur_addr->ai_family, cur_addr->ai_socktype, + cur_addr->ai_protocol); if (sockfd_ != -1) { // Connect the client socket to the server socket. if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { @@ -4959,7 +4967,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count) for (int i = 0; i < raw_stack_size; ++i) { if (raw_stack[i] == caller_frame && - !GTEST_FLAG(show_internal_stack_frames)) { + !GTEST_FLAG_GET(show_internal_stack_frames)) { // Add a marker to the trace and stop adding frames. absl::StrAppend(&result, kElidedFramesMarker, "\n"); break; @@ -4978,7 +4986,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count) return result; -#else // !GTEST_HAS_ABSL +#else // !GTEST_HAS_ABSL static_cast(max_depth); static_cast(skip_count); return ""; @@ -5002,14 +5010,14 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { class ScopedPrematureExitFile { public: explicit ScopedPrematureExitFile(const char* premature_exit_filepath) - : premature_exit_filepath_(premature_exit_filepath ? - premature_exit_filepath : "") { + : premature_exit_filepath_( + premature_exit_filepath ? premature_exit_filepath : "") { // If a path to the premature-exit file is specified... if (!premature_exit_filepath_.empty()) { // create the file with a single "0" character in it. I/O // errors are ignored as there's nothing better we can do and we // don't want to fail the test because of this. - FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); + FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w"); fwrite("0", 1, 1, pfile); fclose(pfile); } @@ -5031,7 +5039,8 @@ class ScopedPrematureExitFile { private: const std::string premature_exit_filepath_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); + ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete; + ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete; }; } // namespace internal @@ -5205,7 +5214,7 @@ int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } // Gets the time of the test program start, in ms from the start of the // UNIX epoch. internal::TimeInMillis UnitTest::start_timestamp() const { - return impl()->start_timestamp(); + return impl()->start_timestamp(); } // Gets the elapsed time, in milliseconds. @@ -5248,9 +5257,7 @@ TestSuite* UnitTest::GetMutableTestSuite(int i) { // Returns the list of event listeners that can be used to track events // inside Google Test. -TestEventListeners& UnitTest::listeners() { - return *impl()->listeners(); -} +TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); } // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in the @@ -5275,12 +5282,11 @@ Environment* UnitTest::AddEnvironment(Environment* env) { // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the // assertion macros instead of calling this directly. -void UnitTest::AddTestPartResult( - TestPartResult::Type result_type, - const char* file_name, - int line_number, - const std::string& message, - const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { +void UnitTest::AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_) { Message msg; msg << message; @@ -5290,8 +5296,9 @@ void UnitTest::AddTestPartResult( for (size_t i = impl_->gtest_trace_stack().size(); i > 0; --i) { const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; - msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) - << " " << trace.message; + msg << "\n" + << internal::FormatFileLocation(trace.file, trace.line) << " " + << trace.message; } } @@ -5301,8 +5308,8 @@ void UnitTest::AddTestPartResult( const TestPartResult result = TestPartResult( result_type, file_name, line_number, msg.GetString().c_str()); - impl_->GetTestPartResultReporterForCurrentThread()-> - ReportTestPartResult(result); + impl_->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult( + result); if (result_type != TestPartResult::kSuccess && result_type != TestPartResult::kSkip) { @@ -5311,7 +5318,7 @@ void UnitTest::AddTestPartResult( // in the code (perhaps in order to use Google Test assertions // with another testing framework) and specify the former on the // command line for debugging. - if (GTEST_FLAG(break_on_failure)) { + if (GTEST_FLAG_GET(break_on_failure)) { #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // Using DebugBreak on Windows allows gtest to still break into a debugger // when a failure happens and both the --gtest_break_on_failure and @@ -5328,7 +5335,7 @@ void UnitTest::AddTestPartResult( // portability: some debuggers don't correctly trap abort(). *static_cast(nullptr) = 1; #endif // GTEST_OS_WINDOWS - } else if (GTEST_FLAG(throw_on_failure)) { + } else if (GTEST_FLAG_GET(throw_on_failure)) { #if GTEST_HAS_EXCEPTIONS throw internal::GoogleTestFailureException(result); #else @@ -5357,7 +5364,7 @@ void UnitTest::RecordProperty(const std::string& key, // from the main thread. int UnitTest::Run() { const bool in_death_test_child_process = - internal::GTEST_FLAG(internal_run_death_test).length() > 0; + GTEST_FLAG_GET(internal_run_death_test).length() > 0; // Google Test implements this protocol for catching that a test // program exits before returning control to Google Test: @@ -5387,7 +5394,7 @@ int UnitTest::Run() { // Captures the value of GTEST_FLAG(catch_exceptions). This value will be // used for the duration of the program. - impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + impl()->set_catch_exceptions(GTEST_FLAG_GET(catch_exceptions)); #if GTEST_OS_WINDOWS // Either the user wants Google Test to catch exceptions thrown by the @@ -5395,26 +5402,26 @@ int UnitTest::Run() { // process. In either case the user does not want to see pop-up dialogs // about crashes - they are expected. if (impl()->catch_exceptions() || in_death_test_child_process) { -# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); -# endif // !GTEST_OS_WINDOWS_MOBILE +#endif // !GTEST_OS_WINDOWS_MOBILE -# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE +#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE // Death test children can be terminated with _abort(). On Windows, // _abort() can show a dialog with a warning message. This forces the // abort message to go to stderr instead. _set_error_mode(_OUT_TO_STDERR); -# endif +#endif -# if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE +#if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE // In the debug version, Visual Studio pops up a separate dialog // offering a choice to debug the aborted program. We need to suppress // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement // executed. Google Test will notify the user of any unexpected // failure via stderr. - if (!GTEST_FLAG(break_on_failure)) + if (!GTEST_FLAG_GET(break_on_failure)) _set_abort_behavior( 0x0, // Clear the following flags: _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. @@ -5428,14 +5435,15 @@ int UnitTest::Run() { _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); } -# endif +#endif } #endif // GTEST_OS_WINDOWS return internal::HandleExceptionsInMethodIfSupported( - impl(), - &internal::UnitTestImpl::RunAllTests, - "auxiliary test code (environments or event listeners)") ? 0 : 1; + impl(), &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") + ? 0 + : 1; } // Returns the working directory when the first TEST() or TEST_F() was @@ -5480,14 +5488,10 @@ UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) { } // Creates an empty UnitTest. -UnitTest::UnitTest() { - impl_ = new internal::UnitTestImpl(this); -} +UnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); } // Destructor of UnitTest. -UnitTest::~UnitTest() { - delete impl_; -} +UnitTest::~UnitTest() { delete impl_; } // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. @@ -5498,8 +5502,7 @@ void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) } // Pops a trace from the per-thread Google Test trace stack. -void UnitTest::PopGTestTrace() - GTEST_LOCK_EXCLUDED_(mutex_) { +void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().pop_back(); } @@ -5596,12 +5599,12 @@ void UnitTestImpl::ConfigureXmlOutput() { // Initializes event listeners for streaming test results in string form. // Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureStreamingOutput() { - const std::string& target = GTEST_FLAG(stream_result_to); + const std::string& target = GTEST_FLAG_GET(stream_result_to); if (!target.empty()) { const size_t pos = target.find(':'); if (pos != std::string::npos) { - listeners()->Append(new StreamingListener(target.substr(0, pos), - target.substr(pos+1))); + listeners()->Append( + new StreamingListener(target.substr(0, pos), target.substr(pos + 1))); } else { GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target << "\" ignored."; @@ -5639,7 +5642,7 @@ void UnitTestImpl::PostFlagParsingInit() { // to shut down the default XML output before invoking RUN_ALL_TESTS. ConfigureXmlOutput(); - if (GTEST_FLAG(brief)) { + if (GTEST_FLAG_GET(brief)) { listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter); } @@ -5649,7 +5652,7 @@ void UnitTestImpl::PostFlagParsingInit() { #endif // GTEST_CAN_STREAM_RESULTS_ #if GTEST_HAS_ABSL - if (GTEST_FLAG(install_failure_signal_handler)) { + if (GTEST_FLAG_GET(install_failure_signal_handler)) { absl::FailureSignalHandlerOptions options; absl::InstallFailureSignalHandler(options); } @@ -5707,9 +5710,9 @@ TestSuite* UnitTestImpl::GetTestSuite( auto* const new_test_suite = new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc); + const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter); // Is this a death test suite? - if (internal::UnitTestOptions::MatchesFilter(test_suite_name, - kDeathTestSuiteFilter)) { + if (death_test_suite_filter.MatchesName(test_suite_name)) { // Yes. Inserts the test suite after the last death test suite // defined so far. This only works when the test suites haven't // been shuffled. Otherwise we may end up running a death test @@ -5746,8 +5749,7 @@ bool UnitTestImpl::RunAllTests() { const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized(); // Do not run any test if the --help flag was specified. - if (g_help_flag) - return true; + if (g_help_flag) return true; // Repeats the call to the post-flag parsing initialization in case the // user didn't call InitGoogleTest. @@ -5765,11 +5767,11 @@ bool UnitTestImpl::RunAllTests() { #if GTEST_HAS_DEATH_TEST in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != nullptr); -# if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) +#if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) if (in_subprocess_for_death_test) { GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_(); } -# endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) +#endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) #endif // GTEST_HAS_DEATH_TEST const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, @@ -5777,19 +5779,18 @@ bool UnitTestImpl::RunAllTests() { // Compares the full test names with the filter to decide which // tests to run. - const bool has_tests_to_run = FilterTests(should_shard - ? HONOR_SHARDING_PROTOCOL - : IGNORE_SHARDING_PROTOCOL) > 0; + const bool has_tests_to_run = + FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; // Lists the tests and exits if the --gtest_list_tests flag was specified. - if (GTEST_FLAG(list_tests)) { + if (GTEST_FLAG_GET(list_tests)) { // This must be called *after* FilterTests() has been called. ListTestsMatchingFilter(); return true; } - random_seed_ = GTEST_FLAG(shuffle) ? - GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + random_seed_ = GetRandomSeedFromFlag(GTEST_FLAG_GET(random_seed)); // True if and only if at least one test has failed. bool failed = false; @@ -5801,9 +5802,21 @@ bool UnitTestImpl::RunAllTests() { // How many times to repeat the tests? We don't want to repeat them // when we are inside the subprocess of a death test. - const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG_GET(repeat); + // Repeats forever if the repeat count is negative. const bool gtest_repeat_forever = repeat < 0; + + // Should test environments be set up and torn down for each repeat, or only + // set up on the first and torn down on the last iteration? If there is no + // "last" iteration because the tests will repeat forever, always recreate the + // environments to avoid leaks in case one of the environments is using + // resources that are external to this process. Without this check there would + // be no way to clean up those external resources automatically. + const bool recreate_environments_when_repeating = + GTEST_FLAG_GET(recreate_environments_when_repeating) || + gtest_repeat_forever; + for (int i = 0; gtest_repeat_forever || i != repeat; i++) { // We want to preserve failures generated by ad-hoc test // assertions executed before RUN_ALL_TESTS(). @@ -5812,7 +5825,7 @@ bool UnitTestImpl::RunAllTests() { Timer timer; // Shuffles test suites and tests if requested. - if (has_tests_to_run && GTEST_FLAG(shuffle)) { + if (has_tests_to_run && GTEST_FLAG_GET(shuffle)) { random()->Reseed(static_cast(random_seed_)); // This should be done before calling OnTestIterationStart(), // such that a test event listener can see the actual test order @@ -5825,10 +5838,13 @@ bool UnitTestImpl::RunAllTests() { // Runs each test suite if there is at least one test to run. if (has_tests_to_run) { - // Sets up all environments beforehand. - repeater->OnEnvironmentsSetUpStart(*parent_); - ForEach(environments_, SetUpEnvironment); - repeater->OnEnvironmentsSetUpEnd(*parent_); + // Sets up all environments beforehand. If test environments aren't + // recreated for each iteration, only do so on the first iteration. + if (i == 0 || recreate_environments_when_repeating) { + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + } // Runs the tests only if there was no fatal failure or skip triggered // during global set-up. @@ -5850,7 +5866,7 @@ bool UnitTestImpl::RunAllTests() { for (int test_index = 0; test_index < total_test_suite_count(); test_index++) { GetMutableSuiteCase(test_index)->Run(); - if (GTEST_FLAG(fail_fast) && + if (GTEST_FLAG_GET(fail_fast) && GetMutableSuiteCase(test_index)->Failed()) { for (int j = test_index + 1; j < total_test_suite_count(); j++) { GetMutableSuiteCase(j)->Skip(); @@ -5868,11 +5884,15 @@ bool UnitTestImpl::RunAllTests() { } } - // Tears down all environments in reverse order afterwards. - repeater->OnEnvironmentsTearDownStart(*parent_); - std::for_each(environments_.rbegin(), environments_.rend(), - TearDownEnvironment); - repeater->OnEnvironmentsTearDownEnd(*parent_); + // Tears down all environments in reverse order afterwards. If test + // environments aren't recreated for each iteration, only do so on the + // last iteration. + if (i == repeat - 1 || recreate_environments_when_repeating) { + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } } elapsed_time_ = timer.Elapsed(); @@ -5893,7 +5913,7 @@ bool UnitTestImpl::RunAllTests() { // (it's always safe to unshuffle the tests). UnshuffleTests(); - if (GTEST_FLAG(shuffle)) { + if (GTEST_FLAG_GET(shuffle)) { // Picks a new random seed for each iteration. random_seed_ = GetNextRandomSeed(random_seed_); } @@ -5944,8 +5964,7 @@ void WriteToShardStatusFileIfNeeded() { // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. -bool ShouldShard(const char* total_shards_env, - const char* shard_index_env, +bool ShouldShard(const char* total_shards_env, const char* shard_index_env, bool in_subprocess_for_death_test) { if (in_subprocess_for_death_test) { return false; @@ -5957,27 +5976,27 @@ bool ShouldShard(const char* total_shards_env, if (total_shards == -1 && shard_index == -1) { return false; } else if (total_shards == -1 && shard_index != -1) { - const Message msg = Message() - << "Invalid environment variables: you have " - << kTestShardIndex << " = " << shard_index - << ", but have left " << kTestTotalShards << " unset.\n"; + const Message msg = Message() << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards + << " unset.\n"; ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (total_shards != -1 && shard_index == -1) { const Message msg = Message() - << "Invalid environment variables: you have " - << kTestTotalShards << " = " << total_shards - << ", but have left " << kTestShardIndex << " unset.\n"; + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (shard_index < 0 || shard_index >= total_shards) { - const Message msg = Message() - << "Invalid environment variables: we require 0 <= " - << kTestShardIndex << " < " << kTestTotalShards - << ", but you have " << kTestShardIndex << "=" << shard_index - << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + const Message msg = + Message() << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); @@ -6019,11 +6038,16 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { // https://github.com/google/googletest/blob/master/googletest/docs/advanced.md // . Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { - const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? - Int32FromEnvOrDie(kTestTotalShards, -1) : -1; - const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? - Int32FromEnvOrDie(kTestShardIndex, -1) : -1; - + const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL + ? Int32FromEnvOrDie(kTestTotalShards, -1) + : -1; + const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL + ? Int32FromEnvOrDie(kTestShardIndex, -1) + : -1; + + const PositiveAndNegativeUnitTestFilter gtest_flag_filter( + GTEST_FLAG_GET(filter)); + const UnitTestFilter disable_test_filter(kDisableTestFilter); // num_runnable_tests are the number of tests that will // run across all shards (i.e., match filter and are not disabled). // num_selected_tests are the number of tests to be run on @@ -6039,18 +6063,17 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { const std::string test_name(test_info->name()); // A test is disabled if test suite name or test name matches // kDisableTestFilter. - const bool is_disabled = internal::UnitTestOptions::MatchesFilter( - test_suite_name, kDisableTestFilter) || - internal::UnitTestOptions::MatchesFilter( - test_name, kDisableTestFilter); + const bool is_disabled = + disable_test_filter.MatchesName(test_suite_name) || + disable_test_filter.MatchesName(test_name); test_info->is_disabled_ = is_disabled; - const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest( - test_suite_name, test_name); + const bool matches_filter = + gtest_flag_filter.MatchesTest(test_suite_name, test_name); test_info->matches_filter_ = matches_filter; const bool is_runnable = - (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + (GTEST_FLAG_GET(also_run_disabled_tests) || !is_disabled) && matches_filter; const bool is_in_another_shard = @@ -6219,8 +6242,8 @@ void UnitTestImpl::UnshuffleTests() { // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, - int skip_count) { +GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string +GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) { // We pass skip_count + 1 to skip this wrapper function in addition // to what the user really wants to skip. return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); @@ -6230,7 +6253,7 @@ std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, // suppress unreachable code warnings. namespace { class ClassUniqueToAlwaysTrue {}; -} +} // namespace bool IsTrue(bool condition) { return condition; } @@ -6238,8 +6261,7 @@ bool AlwaysTrue() { #if GTEST_HAS_EXCEPTIONS // This condition is always false so AlwaysTrue() never actually throws, // but it makes the compiler think that it may throw. - if (IsTrue(false)) - throw ClassUniqueToAlwaysTrue(); + if (IsTrue(false)) throw ClassUniqueToAlwaysTrue(); #endif // GTEST_HAS_EXCEPTIONS return true; } @@ -6261,13 +6283,14 @@ bool SkipPrefix(const char* prefix, const char** pstr) { // part can be omitted. // // Returns the value of the flag, or NULL if the parsing failed. -static const char* ParseFlagValue(const char* str, const char* flag, +static const char* ParseFlagValue(const char* str, const char* flag_name, bool def_optional) { // str and flag must not be NULL. - if (str == nullptr || flag == nullptr) return nullptr; + if (str == nullptr || flag_name == nullptr) return nullptr; // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. - const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const std::string flag_str = + std::string("--") + GTEST_FLAG_PREFIX_ + flag_name; const size_t flag_len = flag_str.length(); if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr; @@ -6298,9 +6321,9 @@ static const char* ParseFlagValue(const char* str, const char* flag, // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. -static bool ParseBoolFlag(const char* str, const char* flag, bool* value) { +static bool ParseFlag(const char* str, const char* flag_name, bool* value) { // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, true); + const char* const value_str = ParseFlagValue(str, flag_name, true); // Aborts if the parsing failed. if (value_str == nullptr) return false; @@ -6314,16 +6337,16 @@ static bool ParseBoolFlag(const char* str, const char* flag, bool* value) { // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. -bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { +bool ParseFlag(const char* str, const char* flag_name, int32_t* value) { // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, false); + const char* const value_str = ParseFlagValue(str, flag_name, false); // Aborts if the parsing failed. if (value_str == nullptr) return false; // Sets *value to the value of the flag. - return ParseInt32(Message() << "The value of flag --" << flag, - value_str, value); + return ParseInt32(Message() << "The value of flag --" << flag_name, value_str, + value); } // Parses a string for a string flag, in the form of "--flag=value". @@ -6331,9 +6354,9 @@ bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. template -static bool ParseStringFlag(const char* str, const char* flag, String* value) { +static bool ParseFlag(const char* str, const char* flag_name, String* value) { // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, false); + const char* const value_str = ParseFlagValue(str, flag_name, false); // Aborts if the parsing failed. if (value_str == nullptr) return false; @@ -6350,8 +6373,7 @@ static bool ParseStringFlag(const char* str, const char* flag, String* value) { // GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test // internal flags and do not trigger the help message. static bool HasGoogleTestFlagPrefix(const char* str) { - return (SkipPrefix("--", &str) || - SkipPrefix("-", &str) || + return (SkipPrefix("--", &str) || SkipPrefix("-", &str) || SkipPrefix("/", &str)) && !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || @@ -6434,6 +6456,10 @@ static const char kColorEncodedHelpMessage[] = "random_seed=@Y[NUMBER]@D\n" " Random number seed to use for shuffling test orders (between 1 and\n" " 99999, or 0 to use a seed based on the current time).\n" + " @G--" GTEST_FLAG_PREFIX_ + "recreate_environments_when_repeating@D\n" + " Sets up and tears down the global test environment on each repeat\n" + " of the test.\n" "\n" "Test Output:\n" " @G--" GTEST_FLAG_PREFIX_ @@ -6451,18 +6477,18 @@ static const char kColorEncodedHelpMessage[] = " Generate a JSON or XML report in the given directory or with the " "given\n" " file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n" -# if GTEST_CAN_STREAM_RESULTS_ +#if GTEST_CAN_STREAM_RESULTS_ " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " Stream test results to the given server.\n" -# endif // GTEST_CAN_STREAM_RESULTS_ +#endif // GTEST_CAN_STREAM_RESULTS_ "\n" "Assertion Behavior:\n" -# if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" " Set the default death test style.\n" -# endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" " Turn assertion failures into debugger break-points.\n" @@ -6494,41 +6520,44 @@ static const char kColorEncodedHelpMessage[] = "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; static bool ParseGoogleTestFlag(const char* const arg) { - return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, - >EST_FLAG(also_run_disabled_tests)) || - ParseBoolFlag(arg, kBreakOnFailureFlag, - >EST_FLAG(break_on_failure)) || - ParseBoolFlag(arg, kCatchExceptionsFlag, - >EST_FLAG(catch_exceptions)) || - ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || - ParseStringFlag(arg, kDeathTestStyleFlag, - >EST_FLAG(death_test_style)) || - ParseBoolFlag(arg, kDeathTestUseFork, - >EST_FLAG(death_test_use_fork)) || - ParseBoolFlag(arg, kFailFast, >EST_FLAG(fail_fast)) || - ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || - ParseStringFlag(arg, kInternalRunDeathTestFlag, - >EST_FLAG(internal_run_death_test)) || - ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || - ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || - ParseBoolFlag(arg, kBriefFlag, >EST_FLAG(brief)) || - ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || - ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) || - ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || - ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || - ParseInt32Flag(arg, kStackTraceDepthFlag, - >EST_FLAG(stack_trace_depth)) || - ParseStringFlag(arg, kStreamResultToFlag, - >EST_FLAG(stream_result_to)) || - ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)); +#define GTEST_INTERNAL_PARSE_FLAG(flag_name) \ + do { \ + auto value = GTEST_FLAG_GET(flag_name); \ + if (ParseFlag(arg, #flag_name, &value)) { \ + GTEST_FLAG_SET(flag_name, value); \ + return true; \ + } \ + } while (false) + + GTEST_INTERNAL_PARSE_FLAG(also_run_disabled_tests); + GTEST_INTERNAL_PARSE_FLAG(break_on_failure); + GTEST_INTERNAL_PARSE_FLAG(catch_exceptions); + GTEST_INTERNAL_PARSE_FLAG(color); + GTEST_INTERNAL_PARSE_FLAG(death_test_style); + GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork); + GTEST_INTERNAL_PARSE_FLAG(fail_fast); + GTEST_INTERNAL_PARSE_FLAG(filter); + GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test); + GTEST_INTERNAL_PARSE_FLAG(list_tests); + GTEST_INTERNAL_PARSE_FLAG(output); + GTEST_INTERNAL_PARSE_FLAG(brief); + GTEST_INTERNAL_PARSE_FLAG(print_time); + GTEST_INTERNAL_PARSE_FLAG(print_utf8); + GTEST_INTERNAL_PARSE_FLAG(random_seed); + GTEST_INTERNAL_PARSE_FLAG(repeat); + GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating); + GTEST_INTERNAL_PARSE_FLAG(shuffle); + GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth); + GTEST_INTERNAL_PARSE_FLAG(stream_result_to); + GTEST_INTERNAL_PARSE_FLAG(throw_on_failure); + return false; } #if GTEST_USE_OWN_FLAGFILE_FLAG_ static void LoadFlagsFromFile(const std::string& path) { FILE* flagfile = posix::FOpen(path.c_str(), "r"); if (!flagfile) { - GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile) + GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG_GET(flagfile) << "\""; } std::string contents(ReadEntireFile(flagfile)); @@ -6536,10 +6565,8 @@ static void LoadFlagsFromFile(const std::string& path) { std::vector lines; SplitString(contents, '\n', &lines); for (size_t i = 0; i < lines.size(); ++i) { - if (lines[i].empty()) - continue; - if (!ParseGoogleTestFlag(lines[i].c_str())) - g_help_flag = true; + if (lines[i].empty()) continue; + if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true; } } #endif // GTEST_USE_OWN_FLAGFILE_FLAG_ @@ -6549,25 +6576,23 @@ static void LoadFlagsFromFile(const std::string& path) { // instantiated to either char or wchar_t. template void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + std::string flagfile_value; for (int i = 1; i < *argc; i++) { const std::string arg_string = StreamableToString(argv[i]); const char* const arg = arg_string.c_str(); - using internal::ParseBoolFlag; - using internal::ParseInt32Flag; - using internal::ParseStringFlag; + using internal::ParseFlag; bool remove_flag = false; if (ParseGoogleTestFlag(arg)) { remove_flag = true; #if GTEST_USE_OWN_FLAGFILE_FLAG_ - } else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) { - LoadFlagsFromFile(GTEST_FLAG(flagfile)); + } else if (ParseFlag(arg, "flagfile", &flagfile_value)) { + GTEST_FLAG_SET(flagfile, flagfile_value); + LoadFlagsFromFile(flagfile_value); remove_flag = true; #endif // GTEST_USE_OWN_FLAGFILE_FLAG_ - } else if (arg_string == "--help" || arg_string == "-h" || - arg_string == "-?" || arg_string == "/?" || - HasGoogleTestFlagPrefix(arg)) { + } else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) { // Both help flag and unrecognized Google Test flags (excluding // internal ones) trigger help display. g_help_flag = true; @@ -6602,7 +6627,27 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { // Parses the command line for Google Test flags, without initializing // other parts of Google Test. void ParseGoogleTestFlagsOnly(int* argc, char** argv) { +#if GTEST_HAS_ABSL + if (*argc > 0) { + // absl::ParseCommandLine() requires *argc > 0. + auto positional_args = absl::flags_internal::ParseCommandLineImpl( + *argc, argv, absl::flags_internal::ArgvListAction::kRemoveParsedArgs, + absl::flags_internal::UsageFlagsAction::kHandleUsage, + absl::flags_internal::OnUndefinedFlag::kReportUndefined); + // Any command-line positional arguments not part of any command-line flag + // (or arguments to a flag) are copied back out to argv, with the program + // invocation name at position 0, and argc is resized. This includes + // positional arguments after the flag-terminating delimiter '--'. + // See https://abseil.io/docs/cpp/guides/flags. + std::copy(positional_args.begin(), positional_args.end(), argv); + if (static_cast(positional_args.size()) < *argc) { + argv[positional_args.size()] = nullptr; + *argc = static_cast(positional_args.size()); + } + } +#else ParseGoogleTestFlagsOnlyImpl(argc, argv); +#endif // Fix the value of *_NSGetArgc() on macOS, but if and only if // *_NSGetArgv() == argv @@ -6637,6 +6682,12 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { #if GTEST_HAS_ABSL absl::InitializeSymbolizer(g_argvs[0].c_str()); + + // When using the Abseil Flags library, set the program usage message to the + // help message, but remove the color-encoding from the message first. + absl::SetProgramUsageMessage(absl::StrReplaceAll( + kColorEncodedHelpMessage, + {{"@D", ""}, {"@R", ""}, {"@G", ""}, {"@Y", ""}, {"@@", "@"}})); #endif // GTEST_HAS_ABSL ParseGoogleTestFlagsOnly(argc, argv); @@ -6657,7 +6708,7 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { void InitGoogleTest(int* argc, char** argv) { #if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); -#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) internal::InitGoogleTestImpl(argc, argv); #endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) } @@ -6667,7 +6718,7 @@ void InitGoogleTest(int* argc, char** argv) { void InitGoogleTest(int* argc, wchar_t** argv) { #if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); -#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) internal::InitGoogleTestImpl(argc, argv); #endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) } @@ -6683,42 +6734,42 @@ void InitGoogleTest() { #if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv); -#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) internal::InitGoogleTestImpl(&argc, argv); #endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) } +#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) +// Return value of first environment variable that is set and contains +// a non-empty string. If there are none, return the "fallback" string. +// Since we like the temporary directory to have a directory separator suffix, +// add it if not provided in the environment variable value. +static std::string GetTempDirFromEnv( + std::initializer_list environment_variables, + const char* fallback, char separator) { + for (const char* variable_name : environment_variables) { + const char* value = internal::posix::GetEnv(variable_name); + if (value != nullptr && value[0] != '\0') { + if (value[strlen(value) - 1] != separator) { + return std::string(value).append(1, separator); + } + return value; + } + } + return fallback; +} +#endif + std::string TempDir() { #if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) return GTEST_CUSTOM_TEMPDIR_FUNCTION_(); -#elif GTEST_OS_WINDOWS_MOBILE - return "\\temp\\"; -#elif GTEST_OS_WINDOWS - const char* temp_dir = internal::posix::GetEnv("TEMP"); - if (temp_dir == nullptr || temp_dir[0] == '\0') { - return "\\temp\\"; - } else if (temp_dir[strlen(temp_dir) - 1] == '\\') { - return temp_dir; - } else { - return std::string(temp_dir) + "\\"; - } +#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE + return GetTempDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\'); #elif GTEST_OS_LINUX_ANDROID - const char* temp_dir = internal::posix::GetEnv("TEST_TMPDIR"); - if (temp_dir == nullptr || temp_dir[0] == '\0') { - return "/data/local/tmp/"; - } else { - return temp_dir; - } -#elif GTEST_OS_LINUX - const char* temp_dir = internal::posix::GetEnv("TEST_TMPDIR"); - if (temp_dir == nullptr || temp_dir[0] == '\0') { - return "/tmp/"; - } else { - return temp_dir; - } + return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/'); #else - return "/tmp/"; -#endif // GTEST_OS_WINDOWS_MOBILE + return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/'); +#endif } // Class ScopedTrace @@ -6735,8 +6786,7 @@ void ScopedTrace::PushTrace(const char* file, int line, std::string message) { } // Pops the info pushed by the c'tor. -ScopedTrace::~ScopedTrace() - GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { +ScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { UnitTest::GetInstance()->PopGTestTrace(); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest_main.cc b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest_main.cc index 46b27c3d7d..44976375c9 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest_main.cc +++ b/texk/dvisvgm/dvisvgm-src/tests/gtest/src/gtest_main.cc @@ -28,15 +28,14 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include + #include "gtest/gtest.h" #if GTEST_OS_ESP8266 || GTEST_OS_ESP32 #if GTEST_OS_ESP8266 extern "C" { #endif -void setup() { - testing::InitGoogleTest(); -} +void setup() { testing::InitGoogleTest(); } void loop() { RUN_ALL_TESTS(); } diff --git a/texk/dvisvgm/dvisvgm-src/tests/normalize.xsl b/texk/dvisvgm/dvisvgm-src/tests/normalize.xsl index 807d373c9d..f5dcc7a1e1 100644 --- a/texk/dvisvgm/dvisvgm-src/tests/normalize.xsl +++ b/texk/dvisvgm/dvisvgm-src/tests/normalize.xsl @@ -2,7 +2,7 @@ + @@ -56,7 +56,7 @@ - + diff --git a/texk/dvisvgm/tests/sample_v2-wf.svg b/texk/dvisvgm/tests/sample_v2-wf.svg index 8a799699d2..bd0f192ef0 100644 --- a/texk/dvisvgm/tests/sample_v2-wf.svg +++ b/texk/dvisvgm/tests/sample_v2-wf.svg @@ -1,5 +1,5 @@ - + @@ -40,7 +40,7 @@ ]]> -Colortest:red,blue,magenta.Lineoftextwitha +Colortest:red,blue,magenta.Lineoftextwitha rotated word. diff --git a/texk/dvisvgm/tests/sample_v3-nf.svg b/texk/dvisvgm/tests/sample_v3-nf.svg index cfabb493df..7bc0bb2258 100644 --- a/texk/dvisvgm/tests/sample_v3-nf.svg +++ b/texk/dvisvgm/tests/sample_v3-nf.svg @@ -1,5 +1,5 @@ - + diff --git a/texk/dvisvgm/tests/sample_v3-wf.svg b/texk/dvisvgm/tests/sample_v3-wf.svg index 3a01e9982c..24b6a086be 100644 --- a/texk/dvisvgm/tests/sample_v3-wf.svg +++ b/texk/dvisvgm/tests/sample_v3-wf.svg @@ -1,5 +1,5 @@ - + diff --git a/texk/dvisvgm/tests/upjf.svg b/texk/dvisvgm/tests/upjf.svg index b6a03aec0d..5b213bdaf6 100644 --- a/texk/dvisvgm/tests/upjf.svg +++ b/texk/dvisvgm/tests/upjf.svg @@ -1,5 +1,5 @@ - + diff --git a/texk/dvisvgm/tests/upjf1.svg b/texk/dvisvgm/tests/upjf1.svg index 66679c4bff..6277b91cd9 100644 --- a/texk/dvisvgm/tests/upjf1.svg +++ b/texk/dvisvgm/tests/upjf1.svg @@ -1,5 +1,5 @@ - + diff --git a/texk/dvisvgm/version.ac b/texk/dvisvgm/version.ac index 443e930e42..5d8a63e58f 100644 --- a/texk/dvisvgm/version.ac +++ b/texk/dvisvgm/version.ac @@ -1,5 +1,5 @@ dnl $Id$ -dnl Copyright 2015-2024 Karl Berry +dnl Copyright 2015-2025 Karl Berry dnl Copyright 2011-2015 Peter Breitenlohner dnl dnl This file is free software; the copyright holder @@ -9,4 +9,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current dvisvgm version -m4_define([dvisvgm_version], [3.2.2]) +m4_define([dvisvgm_version], [3.4.3])