This function was unsafe to use in the way described. It relied on semantics
that are not guaranteed under C99. That is, the lifetime extension of a struct
member of an rvalue. This changes under C11 to something that would make this
not problematic. But it is unlikely Graphviz will be able to migrate to C11 in
the foreseeable future as MSVC is lacking C11 support.
Usage of `itos` in this way relies on lifetime extension of a struct member in
an rvalue. While these semantics exist in C11 and C++, they do not in C99. As a
result, this causes undefined behavior.
Usage of `itos` in this way relies on lifetime extension of a struct member in
an rvalue. While these semantics exist in C11 and C++, they do not in C99. As a
result, this causes undefined behavior.
It does not seem worth maintaining this abstraction for a single usage.
Especially when the surrounding code directly calls numerous other ctype.h
functions.
gvpack: manage graph collection as a 'std::vector'
This removes a number of manual allocations as well as awkward passing of the
base pointer and size of this array around. We also drop the `nGraphs` hint, as
it is simpler and more optimal to let `std::vector`’s standard allocation
algorithm handle this.
This removes some manual memory management leaving an easier to read function,
as well as removing a static unfreed buffer that impedes Valgrind and ASan.
When ipsepcola is enabled, `gvpack` transitively links against lib/vpsc which is
partly written in C++. A consequence of this is that building `gvpack` requires
a C++ toolchain and linking against the C++ standard library. With this in mind,
there is no advantage for `gvpack` itself to be written in C instead of C++.
Moving to C++ will allow removing some manual memory management and data
structures.
This commit itself is just a straight rename. Upcoming changes will make the
code more idiomatic C++.
gvpack: mark 'gvplugin_neato_layout_LTX_library' as having C linkage
gvpack.c is currently compiled as C, so this symbol already has C linkage by
default. However an upcoming commit converts it to C++, which then results in
link failures due to this defaulting to C++ linkage. To pre-empt that, we note
its linkage explicitly for now. These guards will be removed in a future commit.
gxl2gv: replace custom 'slist' string stack with generic stack
Similar to previous changes to `gc` in 4e2875fd7376338259dcb3ccc8f029d58bdf22dd,
this replaces some duplicated functionality with the generic Graphviz stack
implementation. Apart from reducing code duplication and complexity, this
removes an unnecessary rounding of allocations. The prior code rounded up
`slist` allocations to `sizeof(void*)`, but `malloc` effectively does this
internally anyway. This also adds checks for allocation failures that were
previously missing.
gxl2gv: replace inline stack implementation with generic API
Similar to previous changes to `gc` in 4e2875fd7376338259dcb3ccc8f029d58bdf22dd,
this replaces some duplicated functionality with the generic Graphviz stack
implementation. This removes the previously hard coded nested subgraph limit of
32. The number of supported subgraphs in now solely limited by available memory.
treat 'X_OK' as an alias of 'R_OK' in the Windows unistd.h shim
This is not technically correct (Windows does not have `X_OK` at all), but this
is an accurate approximation for the ways in which Graphviz uses `X_OK`. This is
another step towards replacing lib/ast/compat_unistd.h.
This will enable further migration away from lib/ast/compat_unistd.h. Note that
the `S_ISDIR` wrapper there appears incorrect, in using a platform-specific
constant for the mask. Its definition of `X_OK` also seems incorrect, as this
value has no documented meaning when calling `_access` on Windows.
(1) is more comprehensive than (2), and we would like to replace (2) entirely
with (1). However, it is not currently possible to put (1) in the compiler’s
include path during the CMake build. Because it lives in the same directory as
the config.h used in the MS Build build, putting it in the compiler’s include
path also makes this config.h eligible for inclusion. This conflicts with the
CMake build system’s own generated config.h.
Moving this unistd.h to its own directory allows us to more selectively put it
in the include path when relevant. Though surprisingly this file seems unused
right now; even the adjacent config.h does not define `HAVE_UNISTD_H`,
indicating it should not be included.
With unistd.h available natively on every supported platform except Windows,
this change should allow removing unistd.h detection in future and
unconditionally including it when desired.
lib/neatogen: replace inline stack with generic implementation
Similar to previous changes to `gc` in 4e2875fd7376338259dcb3ccc8f029d58bdf22dd,
this replaces some duplicated functionality with the generic Graphviz stack
implementation. This also introduces some missing allocation failure checks.
This seems to be support for some legacy platform lost to the sands of time.
Various internet code searches turn up some clues, but I cannot precisely
determine what platform or system was expected to define these. AFAIK these are
undefined on all currently supported Graphviz platforms.
With the `Agiodisc_t` output function now taking a format string, this code can
be written more readably and concisely. This also avoids the need for
intermediate buffering.
With the `Agiodisc_t` output function now taking a format string, this code can
be written more readably and concisely. This also avoids the need for
intermediate buffering.
pack: replace inline stack with generic implementation
Similar to previous changes to `gc` in 4e2875fd7376338259dcb3ccc8f029d58bdf22dd,
this replaces some duplicated functionality with the generic Graphviz stack
implementation.
Even when this is fixed to not crash, it should still not exit with success
because the input it is given is invalid. Unfortunately we need to also adjust
the xfail condition to be non-strict because this passes under ASan, due to
exiting with 1 when an invalid memory reference is detected.
This appended path was clearly wrong. Yet this test was running (and passing) in
CI. It seems somehow `./rtest` is already in the `$PYTHONPATH` in CI. A bit
mysterious, but this correction lets the test suite run locally correctly too.
dotgen: replace inline stack with generic implementation
Similar to previous changes to `gc` in 4e2875fd7376338259dcb3ccc8f029d58bdf22dd,
this replaces some duplicated functionality with the generic Graphviz stack
implementation.
This macro was implemented to optimize the case of calling `gvputs` with a
string literal. It has since proven error prone to use.¹ The sharp edge is that
it is possible to call the macro with something that is not a string literal:
This will pass through the compiler with no warnings, but on e.g. x86-64 will
result in a `gvputs` of `"hello wo"`. For safety, we remove it.
This effectively reverts commit 1764f50bcbdf944e003fe475aba2c26e2fd370ff. The
`GVPUTS` macro was originally introduced to optimize I/O resulting in a ~1%
runtime improvement on tests/regression_tests/large/long_chain. That example
should probably no longer be considered “expensive.” I/O is typically an
insignificant fraction of the computation done by currently known expensive
inputs that spend most of their time in layout or cycle resolution. If I/O _is_
a factor in an expensive graph, we could consider providing a vectorized
interface in future in the style of `writev`.
¹ E.g. https://gitlab.com/graphviz/graphviz/-/merge_requests/2472#note_861834540