44#define ND_relrank(n) (((Agnodeinfo_t*)((n)->base.data))->relrank)
45#define ND_x(n) (((Agnodeinfo_t*)((n)->base.data))->x)
59static int cmpf(
const void *x,
const void *y) {
64 if (relrank0 < relrank1)
66 if (relrank0 > relrank1)
74 if (sscanf(p,
"%lf %lf %lf", v, v + 1, v + 2) != 3 && p[0]) {
76 sscanf(
agxbuse(&buf),
"%lf %lf %lf", v, v + 1, v + 2);
83static char *
useString =
"Usage: gvcolor [-?] <files>\n\
85If no files are specified, stdin is used";
93static void init(
int argc,
char *argv[])
98 while ((c = getopt(argc, argv,
":?")) != -1) {
101 if (optopt ==
'\0' || optopt ==
'?')
103 fprintf(stderr,
"gvcolor: option -%c unrecognized\n", optopt);
107 fprintf(stderr,
"gvcolor: unexpected error\n");
121 double x, y, maxrank = 0.0;
122 double lowsat, highsat;
126 "graph must be run through 'dot' before 'gvcolor'\n");
132 if ((p =
agget(g,
"Defcolor")))
135 if ((p =
agget(g,
"rankdir")) && p[0] ==
'L')
137 if ((p =
agget(g,
"flow")) && p[0] ==
'b')
139 if ((p =
agget(g,
"saturation"))) {
140 if (sscanf(p,
"%lf,%lf", &lowsat, &highsat) == 2) {
151 if ((p =
agget(n,
"color")))
154 sscanf(p,
"%lf,%lf", &x, &y);
159 for (
size_t i = 0; i <
LIST_SIZE(&nlist); i++) {
166 for (
size_t i = 0; i <
LIST_SIZE(&nlist); i++) {
171 for (
int j = 0; j <
NC; j++)
177 double sum[
NC] = {0};
185 for (
int j = 0; j <
NC; j++) {
187 sum[j] +=
ND_x(v)[j];
194 for (
int j = 0; j <
NC; j++)
199 for (
size_t i = 0; i <
LIST_SIZE(&nlist); i++) {
206 for (
int j = 0; j <
NC; j++)
225 snprintf(buf,
sizeof(buf),
"%f %f %f", h,
s, b);
226 agset(n,
"color", buf);
Dynamically expanding string buffers.
static void agxbfree(agxbuf *xb)
free any malloced resources
static WUR char * agxbuse(agxbuf *xb)
abstract graph C library, Cgraph API
void colorxlate(char *str, agxbuf *buf)
static NORETURN void graphviz_exit(int status)
static int cnt(Dict_t *d, Dtlink_t **set)
Agsym_t * agattr_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text attributes of a graph
int agset(void *obj, char *name, const char *value)
char * agget(void *obj, char *name)
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
int agclose(Agraph_t *g)
deletes a graph, freeing its associated storage
int agwrite(Agraph_t *g, void *chan)
Return 0 on success, EOF on failure.
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
void aginit(Agraph_t *g, int kind, const char *rec_name, int rec_size, int move_to_front)
attach new records to objects of specified kind
Arithmetic helper functions.
static bool is_exactly_zero(double v)
is a value precisely 0.0?
static void init(int argc, char *argv[])
static int cmpf(const void *x, const void *y)
static void color(Agraph_t *g)
static void setcolor(char *p, double *v)
static const char * usage
Agraph_t * nextGraph(ingraph_state *sp)
ingraph_state * newIngraph(ingraph_state *sp, char **files)
supports user-supplied data
type-generic dynamically expanding list
#define LIST_APPEND(list, item)
#define LIST_SORT(list, cmp)
#define LIST_GET(list, index)
implementation of Agrec_t