-
Notifications
You must be signed in to change notification settings - Fork 0
/
graphviz.h
120 lines (93 loc) · 3.54 KB
/
graphviz.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//
// graphviz.h
// PL/0
//
// Created by Kevin Colley on 11/3/15.
// Copyright © 2015 Kevin Colley. All rights reserved.
//
#ifndef PL0_GRAPHVIZ_H
#define PL0_GRAPHVIZ_H
#include <stdarg.h>
#include <stdbool.h>
typedef struct Graphviz Graphviz;
#include "object.h"
struct Graphviz {
OBJECT_BASE;
/*! True if this is a subgraph of another graph */
bool subgraph;
union {
FILE* fout; /*!< Output file stream where the DOT data will be written */
Graphviz* gv; /*!< Parent graph */
} output;
};
DECL(Graphviz);
/*! Initializes the graphviz object to write to the specified file and names the output graph
@param fout Output file stream where the DOT data will be written
@param name Format string for the name of the main graph to output
*/
Graphviz* Graphviz_initWithFile(Graphviz* self, FILE* fout, const char* name, ...);
Graphviz* Graphviz_vInitWithFile(Graphviz* self, FILE* fout, const char* name, va_list ap);
/*! Initializes the graphviz object to write a subgraph within the specified writer
@param parent Parent graph writer this graph is a subgraph of
@param name Format string for the name of the subgraph to output
*/
Graphviz* Graphviz_initWithParentGraph(Graphviz* self, Graphviz* parent, const char* name, ...);
Graphviz* Graphviz_vInitWithParentGraph(Graphviz* self, Graphviz* parent, const char* name, va_list ap);
/*! Prints raw Graphviz DOT code to the output file */
void Graphviz_printf(Graphviz* self, const char* fmt, ...);
void Graphviz_vprintf(Graphviz* self, const char* fmt, va_list ap);
/*! Prints the indentation for the current graph level */
void Graphviz_indent(Graphviz* self);
/*! Draws a line of raw Graphviz DOT code to the output file
@param fmt Formatted string for DOT code
*/
void Graphviz_draw(Graphviz* self, const char* fmt, ...);
void Graphviz_vDraw(Graphviz* self, const char* fmt, va_list ap);
/*! Draws a node with the specified id and formatted label
@param id Node identifier
@param fmt Label format string
*/
void Graphviz_drawNode(Graphviz* self, const char* id, const char* fmt, ...);
void Graphviz_vDrawNode(Graphviz* self, const char* id, const char* fmt, va_list ap);
/*! Draws a node using the object pointer as its node id, and with the given formatted label
@param obj Object pointer to use as the node identifier
@param fmt Label format string
*/
void Graphviz_drawPtrNode(Graphviz* self, void* obj, const char* fmt, ...);
void Graphviz_vDrawPtrNode(Graphviz* self, void* obj, const char* fmt, va_list ap);
/*! Draws an edge between two nodes referenced by their ids
@param from Node identifier of the source node
@param to Node identifier of the destination node
*/
void Graphviz_drawEdge(Graphviz* self, const char* from, const char* to);
/*! Draws an edge between two nodes using object pointer node ids
@param from Object pointer used as the source node id
@param to Object pointer used as the destination node id
*/
void Graphviz_drawPtrEdge(Graphviz* self, void* from, void* to);
/* Helpful functions */
/*! Convert a character into an HTML-escaped string */
static inline const char* html_char(char c) {
static char literal[2] = {};
switch(c) {
case '<': return "<";
case '>': return ">";
case '&': return "&";
case '"': return """;
default:
literal[0] = c;
return literal;
}
}
/* Convert a string into an HTML-escaped string */
static inline char* html_str(const char* s) {
if(s == NULL) {
return NULL;
}
dynamic_string str = {};
while(*s != '\0') {
string_append(&str, html_char(*s++));
}
return string_cstr(&str);
}
#endif /* PL0_GRAPHVIZ_H */