This seems to have been a mistake in aadee957012e676c9aaf36ec40cb2860c178e269.
lib/edgepaint does not depend on libANN, so it does not seem correct to apply
ANN’s CFLAGS when compiling it.
CI: move macOS dependency installation out of line
Makes these a little easier to manage. Note that this also unifies the runtime
dependencies installed in Autotools and CMake jobs which simplifies ongoing
maintenance.
This is the equivalent of b4925c87f1e28a1bc66d111ef046e4e083db8c5b and friends,
but for mingle. It was not previously detected that this problem also affects
mingle because it is not currently built on macOS or Windows in CI. This will be
improved in future.
htmlparse.y: consistently treat 'kind' as a 'char'
The `kind` field in `htmllabel_t` is a `char`, so this code was causing
conversion compiler warnings when trying to assign an `int` to it. We can avoid
this ambiguity by consistently using the same type everywhere.
Nothing in the build systems defines this macro. It is also unclear how this
code could be used given it calls `pathnext`, a function that has never been
committted to the Graphviz repository.
This function was only ever called with `0` as `flags`, which disables a lot of
its logic. We can reduce the amount of ongoing code to maintain by paring this
back to just the core in use.
This change replicates and extends the exit-on-failure allocation wrappers from
lib/common/memory.c into a header-only implementation in cgraph. The existing
common wrappers worked but there were two limitations preventing their wider
use:
1. lib/common is not the base of the Graphviz dependency graph. E.g.
lib/cgraph does not depend on lib/common, preventing calling
lib/common/memory.h functions from cgraph code. lib/cgraph is not the base
of the dependency graph either (it depends on lib/cdt), but it has become a
de facto home for header-only implementations of general utility functions
called throughout the rest of the Graphviz code base.
2. lib/common is not linked against by every Graphviz component. This meant
other code could attempt to call functions in lib/common/memory.h but would
fail to link because it was not pulling in lib/common/memory.c.
Relocating these functions neatly solves both the above two. It also has the
side effect of allowing compilers to inline these short wrappers. This could
(and would) previously be achieved with Link-Time Optimization, but now a
regular optimizing compilation can also achieve this.
Future changes will remove the lib/common/memory.c wrappers in favor of these.
Stephen C North [Mon, 7 Mar 2022 23:39:41 +0000 (18:39 -0500)]
Attempt to fix initialization of subgraph attributes on existing subgraphs…
Attempt to fix initialization of subgraph attributes on existing subgraphs when
a new root graph attribute is created.
Fix issue 2184, initialization of existing subgraph attributes when a new top
level graph attribute is created. Looks ok, but new code unviewsubgraphsattr is
executed on many of the test graphs, so this should be tested carefully.
This function was retaining a pointer to memory pointed to by its parameter,
`name`, in the global `suffix`. So it is unsafe to call this with anything
except a long lived string. We can make this more obvious/explicit by inlining
the use of `outfile`, the only parameter it is ever called with.
GD plugin: remove repurposing of 'tell' member of I/O context
The GD plugin was using (abusing) the `gdIOCtx.tell` field as a way to pass
around the Graphviz context through GD library functions and callbacks. The GD
docs¹ have this to say about the `tell` field:
The seek and tell functions are only required in conjunction with the gd2 file
format, which supports quick loading of partial images.
The Graphviz GD plugin _is_ using gd2 functionality, so it seems its usage only
works out because it coincidentally does not hit any code paths that use `tell`.
We can avoid this latent issue entirely by rephrasing the way the plugin passes
the Graphviz context around to something less brittle. The approach taken in
this commit is inspired by something like Linux’s `container_of` macro.
The GD plugin was creating `gdIOCtx` objects on the stack with some
uninitialized members. At time of writing, the GD docs¹ claim this struct’s
layout is:
typedef struct gdIOCtx
{
int (*getC)(gdIOCtxPtr);
int (*getBuf)(gdIOCtxPtr, void *, int wanted);
void (*putC)(gdIOCtxPtr, int);
int (*putBuf)(gdIOCtxPtr, const void *, int wanted);
// seek must return 1 on SUCCESS, 0 on FAILURE. Unlike fseek!
int (*seek)(gdIOCtxPtr, const int);
long (*tell)(gdIOCtxPtr);
void (*gd_free)(gdIOCtxPtr);
} gdIOCtx;
So Graphviz’ usage was leaving `getC`, `getBuf`, `seek`, and `gd_free`
uninitialized. This seems to work out OK; Graphviz’ usage of libgd apparently
does not involve any code paths that use these members. But this does not seem
to be an API guarantee. This change zeroes these members for future stability.
gvplugin_install: remove 63-character limit on plugin names
This change rephrases `gvplugin_install` to avoid the use of intermediate
buffers and, in the process, removes a constraint on the maximum length of
plugin names. That is, this is a performance improvement and a functional
improvement.
avoid use of '__builtin_unreachable' in 'UNREACHABLE' macro
There was some discussion on !2503¹ around the effect of `__builtin_unreachable`
and whether we are really confident applying such a strong compiler hint to
complex control flow logic that is, in some cases, only partially understood.
This change softens the effect of the `UNREACHABLE` macro to a reliable program
abort rather than undefined behavior if mistakenly tagged unreachable code is
reached. The result is slightly less efficient but safer code.
fix corruption of user shape characteristics during EPSF initialization
From the surrounding context, it is clear this code was intending to set `h`,
the height of the shape, not overwrite the `y` coordinate it had previously set
for the shape. This change not only fixes the overwrite of `us->y` but fixes a
read of uninitialized memory in `us->h` by the caller of this function.
It is not clear to me what the full user-visible effect of this change is.
Costa Shulyupin [Thu, 10 Mar 2022 07:47:14 +0000 (09:47 +0200)]
fix out of source build error in lib/expr
make[3]: Entering directory '/home/costa/oss/graphviz/build/lib/expr'
CC excc.lo
In file included from ../../../lib/expr/expr.h:28,
from ../../../lib/expr/exlib.h:126,
from ../../../lib/expr/excc.c:25:
../../../lib/expr/exparse.h:4:10: fatal error: expr/y.tab.h: No such file or directory
4 | #include <expr/y.tab.h>
| ^~~~~~~~~~~~~~
compilation terminated.
Costa Shulyupin [Thu, 10 Mar 2022 07:40:06 +0000 (09:40 +0200)]
fix out of source build error in lib/common
make[4]: Entering directory '/home/costa/oss/graphviz/build/lib/common'
CC arrows.lo
../../../lib/common/arrows.c: In function ‘arrowOrthoClip’:
.....
../../../lib/common/colxlate.c:21:10: fatal error: common/colortbl.h: No such file or directory
21 | #include <common/colortbl.h>
| ^~~~~~~~~~~~~~~~~~~
compilation terminated.
make[3]: Entering directory '/home/costa/oss/graphviz/build/lib/gvpr'
CC actions.lo
In file included from ../../../lib/expr/expr.h:28,
from ../../../lib/gvpr/actions.h:18,
from ../../../lib/gvpr/actions.c:16:
../../../lib/expr/exparse.h:4:10: fatal error: expr/y.tab.h: No such file or directory
4 | #include <expr/y.tab.h>
| ^~~~~~~~~~~~~~
compilation terminated.
core plugin map_output_shape: replace dynamic buffer with inline conversion
This function was using a long lived buffer to hold conversions of the input
array `AF`. However each entry was only used once or twice. It is faster to
avoid the heap buffer altogether and simply do the conversions on-demand when
they are needed.
This change is expected to be a slight performance improvement as well as
further progress towards thread safety in this code.
core plugin: remove assumptions that pen width fits in an int
By dealing with this field consistently as a double, we retain the previous
intent while removing assumptions on the characteristics of `int`. Squashes 8
compiler warnings.
GNU Make supports both this syntax and `patsubst` for pattern substitution. The
former is more portable to other Make implementations, so use this in preference
to the latter.