The `located` member in this struct determines where the backing store is. When
storage is inline, its value is 0. Its only possible values are 0, 1, and 2. It
is also the last member in this struct. Putting these pieces of information
together, we can move it to the last _byte_ of this struct allowing extra room
for inline storage. On top of this, we can claim a further byte by noting that
the inline string is naturally NUL terminated by `AGXBUF_INLINE` itself being
present in the last byte.
This further optimization on top of the previous SSO rearrangements gains us an
extra 8 bytes on x86-64. That is, strings in the range 24 - 31 bytes that
previously would have required heap allocation can now be stored inline just
like strings <24 bytes.
This change switches both `agxbinit` and zero-initialization (`agxbuf xb = {0}`)
to result in a buffer with `AGXBUF_INLINE` set. This means string data is
written inline until it becomes too large to store within the `agxbuf` struct
itself, when it is then relocated to the heap.
This is an optimization. Short dynamic strings can now be written completely
without heap allocation. For example, stringifying a number
(`agxbprint(&xb, "%d", i)`) will fit fully within the inline buffer.
cgraph agxbuf: support storing short strings inline
This commit implements Small String Optimization (SSO) for `axgbuf`. Strings
up to a certain size (23 bytes unterminated on x86-64) can be stored inline
within an `agxbuf` structure itself with no external backing memory.
There is currently no way to create a buffer with `AGXBUF_INLINE`. Neither
`agxbuf_init` nor zero-initialization gives a path to this. The ability to
create inline strings will be added in an upcoming commit.
The expansion logic in `agxbmore` is adjusted in a way that does not preserve
the exact previous behavior but aims to preserve its intent. That is, expansions
from an initially small buffer size will round up to `BUFSIZ` (typically 128).
When a string is stored inline, its size is not maintained anywhere. The string
data is kept NUL terminated. That is, `xb->store[sizeof(xb->store) - 1]` is
always `'\0'` for inline strings.
Note that implementing `agxbuse` on this type of `agxbuf` required a bit of
lateral thinking.
A number of other functions in agxbuf.h open code the logic of `agxblen`. Moving
this function higher in the header will enable us to de-duplicate this code. The
goal here is to fully abstract this, as an upcoming commit will make the way the
length of an `agxbuf` is calculated conditional.
cgraph agxbuf: use an enumerated type for buffer location
This does not change the semantics; 0 still means heap-allocated and 1 means
stack-allocated. However this is preparation for introducing a third location a
buffer can be hosted in.
This squashes a -Wsign-conversion warning. We need to cast back to `int` for
calling `gvpr`, but this is acceptable as the number of arguments cannot
practically exceed `INT_MAX`.
These constants were added in 1b847b5abf50d2ab0701523b90a20306d0ee5528 and it is
unclear why, given they are unused. They shadow a different constant in
general.h, causing compiler warnings.
This reverts commit 2d7852a049b729fb0db71c5a8ef2366215ae2035. This commit
introduced a bug where the string buffer was assumed to be uninitialized when
beginning parsing a string, but it may not be if a previously unterminated
string was processed.
Github: fixes #2272 Reported-by: Rob Hart <robhart@google.com>
Magnus Jacobsson [Wed, 24 Aug 2022 07:37:07 +0000 (09:37 +0200)]
tests: add new test_edge_node_overlap_simple test
Upcoming commit series will add additional such tests so most of the
code is in a separate utilities file and is somewhat more generalized
than what is strictly necessary for this first simple test.
label doxlabel: use cgraph wrappers for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
label xlhdxload: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
GD plugin vrml_begin_job: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
core plugin write_edges: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
Magnus Jacobsson [Sat, 20 Aug 2022 16:12:54 +0000 (18:12 +0200)]
tests: SVGAnalyzer: add 're_create_and_verify_svg' method and use in test_svg_analyzer
Upcoming commits will extend the SVG analyzer's ability to handle new
SVG attributes and add new test cases verifying its ability to
re-create correct SVG containing those attributes. This change will
facilitate the creation of those tests and keep the code DRY.
Magnus Jacobsson [Sat, 20 Aug 2022 16:12:54 +0000 (18:12 +0200)]
tests: SVGAnalyzer: extend 'make_from_dot' method and use in test_svg_analyzer
This change adds support to the SVGAnalyzer for saving a
copy of the Graphviz version and build ID which are needed to exactly
re-create the SVG document.
Upcoming commits will extend the SVG analyzer's ability to handle new
SVG attributes and add new test cases verifying its ability to
re-create correct SVG containing those attributes. This change will
facilitate the creation of those tests and keep the code DRY.
tests: SVGAnalyzer: save a copy of the original SVG and give access to it
This is needed to be able to verify the SVG re-creating capablility of
the SVGAnalyzer.
Upcoming commits will extend the SVG analyzer's ability to handle new
SVG attributes and add new test cases verifying its ability to
re-create correct SVG containing those attributes. This change will
facilitate the creation of those tests and keep the code DRY.
The copying is necessary since the original SVG is modified by the XML
parser in destructive mode. See
http://rapidxml.sourceforge.net/manual.html#namespacerapidxml_1destructive_non_destructive
and we don't want to use the non-destructive mode since no entity
reference translation is done then and we want to avoid having to do
that ourselves.
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho mkMazeGraph: use cgraph wrappers for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho partition: use cgraph wrappers for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho monotonate_trapezoids: use cgraph wrappers for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho make_graph: use cgraph wrappers for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho createSGraph: use cgraph wrappers for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho initSEdges: use cgraph wrappers for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho construct_trapezoids: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho orthoEdges: use cgraph wrappers for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho attachOrthoEdges: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho extractVChans: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho extractHChans: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
ortho convertSPtoRoute: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
Revert "gvc auto_output_filename: avoid 'strdup' when constructing file name"
This reverts commit 4291cc769a3eeef8b1c171e5479194733a4da6cd. This commit that
was intended to be a functional no-op actually altered the generated output
filename to remove `.` characters.
Github: xflr6/graphviz #178, NixOS/nixpkgs #188175
Gitlab: fixes #2270 Reported-by: Sebastian Bank <sebastian.bank@uni-leipzig.de>
smyrna load_attributes: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
smyrna smyrnaPath: use cgraph wrapper for allocation
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
smyrna initFocus: use cgraph wrapper for allocations
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
smyrna positionAllItems: use cgraph wrapper for allocations
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.
smyrna makeXDotSpline: use cgraph wrapper for allocations
The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.