28 if (*
s ==
'x' || *
s ==
'X') {
61 int (*cb)(
void *state,
const char *
s),
void *state) {
63 const char *
s = *current;
71 return cb(state,
"&");
76 return cb(state,
"<");
79 return cb(state,
">");
82 if (c ==
'-' &&
flags.dash)
83 return cb(state,
"-");
85 if (c ==
' ' && previous ==
' ' &&
flags.nbsp)
87 return cb(state,
" ");
90 return cb(state,
""");
93 return cb(state,
"'");
95 if (c ==
'\n' &&
flags.raw)
96 return cb(state,
" ");
98 if (c ==
'\r' &&
flags.raw)
99 return cb(state,
" ");
101 unsigned char uc = (
unsigned char)c;
102 if (uc > 0x7f &&
flags.utf8) {
116 size_t length = (uc >> 5) == 6 ? 2
117 : (uc >> 4) == 14 ? 3
118 : (uc >> 3) == 30 ? 4
122 bool is_invalid = length == 0;
123 for (
size_t l = 1; !is_invalid && length > l; ++l)
124 is_invalid |=
s[l] ==
'\0';
128 fprintf(stderr,
"Error during conversion to \"UTF-8\". Quiting.\n");
134 uint32_t utf8_char = 0;
137 uint32_t low = ((uint32_t)
s[1]) & ((1 << 6) - 1);
138 uint32_t high = ((uint32_t)
s[0]) & ((1 << 5) - 1);
139 utf8_char = low | (high << 6);
143 uint32_t low = ((uint32_t)
s[2]) & ((1 << 6) - 1);
144 uint32_t mid = ((uint32_t)
s[1]) & ((1 << 6) - 1);
145 uint32_t high = ((uint32_t)
s[0]) & ((1 << 4) - 1);
146 utf8_char = low | (mid << 6) | (high << 12);
150 uint32_t low = ((uint32_t)
s[3]) & ((1 << 6) - 1);
151 uint32_t mid1 = ((uint32_t)
s[2]) & ((1 << 6) - 1);
152 uint32_t mid2 = ((uint32_t)
s[1]) & ((1 << 6) - 1);
153 uint32_t high = ((uint32_t)
s[0]) & ((1 << 3) - 1);
154 utf8_char = low | (mid1 << 6) | (mid2 << 12) | (high << 18);
162 char buffer[
sizeof(
"�")];
165 snprintf(buffer,
sizeof(buffer),
"&#x%" PRIx32
";", utf8_char);
168 *current += length - 1;
170 return cb(state, buffer);
174 char buffer[2] = {c,
'\0'};
175 return cb(state, buffer);
179 int (*cb)(
void *state,
const char *
s),
void *state) {
180 char previous =
'\0';
200static int put(
void *stream,
const char *
s) {
return fputs(
s, stream); }
203int main(
int argc,
char **argv) {
208 static const struct option
opts[] = {
209 {
"dash", no_argument, 0,
'd'},
210 {
"nbsp", no_argument, 0,
'n'},
211 {
"raw", no_argument, 0,
'r'},
212 {
"utf8", no_argument, 0,
'u'},
217 int c = getopt_long(argc, argv,
"dnru",
opts, &index);
241 fprintf(stderr,
"unexpected error\n");
247 for (
int i = optind; i < argc; ++i) {
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.