42#define ND_relrank(n) (((Agnodeinfo_t*)((n)->base.data))->relrank)
43#define ND_x(n) (((Agnodeinfo_t*)((n)->base.data))->x)
57static int cmpf(
const void *x,
const void *y) {
62 if (relrank0 < relrank1)
64 if (relrank0 > relrank1)
72 if (sscanf(p,
"%lf %lf %lf", v, v + 1, v + 2) != 3 && p[0]) {
74 sscanf(
agxbuse(&buf),
"%lf %lf %lf", v, v + 1, v + 2);
81static char *
useString =
"Usage: gvcolor [-?] <files>\n\
83If no files are specified, stdin is used";
91static void init(
int argc,
char *argv[])
96 while ((c = getopt(argc, argv,
":?")) != -1) {
99 if (optopt ==
'\0' || optopt ==
'?')
101 fprintf(stderr,
"gvcolor: option -%c unrecognized\n", optopt);
105 fprintf(stderr,
"gvcolor: unexpected error\n");
119 double x, y, maxrank = 0.0;
120 double lowsat, highsat;
124 "graph must be run through 'dot' before 'gvcolor'\n");
130 if ((p =
agget(g,
"Defcolor")))
133 if ((p =
agget(g,
"rankdir")) && p[0] ==
'L')
135 if ((p =
agget(g,
"flow")) && p[0] ==
'b')
137 if ((p =
agget(g,
"saturation"))) {
138 if (sscanf(p,
"%lf,%lf", &lowsat, &highsat) == 2) {
149 if ((p =
agget(n,
"color")))
152 sscanf(p,
"%lf,%lf", &x, &y);
157 for (
size_t i = 0; i <
LIST_SIZE(&nlist); i++) {
164 for (
size_t i = 0; i <
LIST_SIZE(&nlist); i++) {
169 for (
int j = 0; j <
NC; j++)
175 double sum[
NC] = {0};
183 for (
int j = 0; j <
NC; j++) {
185 sum[j] +=
ND_x(v)[j];
192 for (
int j = 0; j <
NC; j++)
197 for (
size_t i = 0; i <
LIST_SIZE(&nlist); i++) {
204 for (
int j = 0; j <
NC; j++)
223 snprintf(buf,
sizeof(buf),
"%f %f %f", h,
s, b);
224 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