31 if (*
s ==
'x' || *
s ==
'X') {
64 int (*cb)(
void *state,
const char *
s),
void *state) {
66 const char *
s = *current;
74 return cb(state,
"&");
79 return cb(state,
"<");
82 return cb(state,
">");
85 if (c ==
'-' &&
flags.dash)
86 return cb(state,
"-");
88 if (c ==
' ' && previous ==
' ' &&
flags.nbsp)
90 return cb(state,
" ");
93 return cb(state,
""");
96 return cb(state,
"'");
98 if (c ==
'\n' &&
flags.raw)
99 return cb(state,
" ");
101 if (c ==
'\r' &&
flags.raw)
102 return cb(state,
" ");
104 unsigned char uc = (
unsigned char)c;
105 if (uc > 0x7f &&
flags.utf8) {
119 size_t length = (uc >> 5) == 6 ? 2
120 : (uc >> 4) == 14 ? 3
121 : (uc >> 3) == 30 ? 4
125 bool is_invalid =
length == 0;
126 for (
size_t l = 1; !is_invalid &&
length > l; ++l)
127 is_invalid |=
s[l] ==
'\0';
131 fprintf(stderr,
"Error during conversion to \"UTF-8\". Quiting.\n");
137 uint32_t utf8_char = 0;
140 uint32_t low = ((uint32_t)
s[1]) & ((1 << 6) - 1);
141 uint32_t high = ((uint32_t)
s[0]) & ((1 << 5) - 1);
142 utf8_char = low | (high << 6);
146 uint32_t low = ((uint32_t)
s[2]) & ((1 << 6) - 1);
147 uint32_t mid = ((uint32_t)
s[1]) & ((1 << 6) - 1);
148 uint32_t high = ((uint32_t)
s[0]) & ((1 << 4) - 1);
149 utf8_char = low | (mid << 6) | (high << 12);
153 uint32_t low = ((uint32_t)
s[3]) & ((1 << 6) - 1);
154 uint32_t mid1 = ((uint32_t)
s[2]) & ((1 << 6) - 1);
155 uint32_t mid2 = ((uint32_t)
s[1]) & ((1 << 6) - 1);
156 uint32_t high = ((uint32_t)
s[0]) & ((1 << 3) - 1);
157 utf8_char = low | (mid1 << 6) | (mid2 << 12) | (high << 18);
165 char buffer[
sizeof(
"�")];
168 snprintf(buffer,
sizeof(buffer),
"&#x%" PRIx32
";", utf8_char);
173 return cb(state, buffer);
177 char buffer[2] = {c,
'\0'};
178 return cb(state, buffer);
182 int (*cb)(
void *state,
const char *
s),
void *state) {
183 char previous =
'\0';
200static int put(
void *stream,
const char *
s) {
return fputs(
s, stream); }
203int main(
int argc,
char **argv) {
208 for (i = 1; i < argc; ++i) {
209 if (strcmp(argv[i],
"--dash") == 0) {
211 }
else if (strcmp(argv[i],
"--nbsp") == 0) {
213 }
else if (strcmp(argv[i],
"--raw") == 0) {
215 }
else if (strcmp(argv[i],
"--utf8") == 0) {
217 }
else if (argv[i][0] ==
'-') {
218 fprintf(stderr,
"unrecognized argument %s\n", argv[i]);
228 "usage: %s [--dash] [--nbsp] [--raw] [--utf8] <input> <output>\n",
233 const char *
const in = argv[i];
234 const char *
const out = argv[i + 1];
237 char buffer[128] = {0};
239 FILE *
const f = fopen(
in,
"rb");
241 fprintf(stderr,
"failed to open %s: %s\n",
in, strerror(errno));
244 const size_t read = fread(buffer, 1,
sizeof(buffer), f);
246 if (
read == 0 ||
read ==
sizeof(buffer)) {
249 " bytes is supported, not %" PRISIZE_T " bytes\n",
250 sizeof(buffer) - 1,
read);
256 FILE *
const f = fopen(
out,
"wb");
258 fprintf(stderr,
"failed to open %s: %s\n",
out, strerror(errno));
static void out(agerrlevel_t level, const char *fmt, va_list args)
Report messages using a user-supplied or default write function.
static Extype_t length(Exid_t *rhs, Exdisc_t *disc)
static int in(Extype_t lhs, Exid_t *rhs, Exdisc_t *disc)
static int put(void *buffer, const char *s)
static NORETURN void graphviz_exit(int status)
replacements for ctype.h functions
static bool gv_isxdigit(int c)
static bool gv_isdigit(int c)
static bool gv_isalpha(int c)
options to tweak the behavior of XML escaping
int gv_xml_escape(const char *s, xml_flags_t flags, int(*cb)(void *state, const char *s), void *state)
static bool xml_isentity(const char *s)
static int xml_core(char previous, const char **current, xml_flags_t flags, int(*cb)(void *state, const char *s), void *state)
XML escaping functionality.