Skip to content

Commit 3ac36b0

Browse files
committed
Handle backslashes in token names when printing DOT debug graphs
1 parent 04381dc commit 3ac36b0

File tree

4 files changed

+28
-19
lines changed

4 files changed

+28
-19
lines changed

lib/src/language.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,31 @@ static inline void ts_language_aliases_for_symbol(
283283
}
284284
}
285285

286+
static inline void ts_language_write_symbol_as_dot_string(
287+
const TSLanguage *self,
288+
FILE *f,
289+
TSSymbol symbol
290+
) {
291+
const char *name = ts_language_symbol_name(self, symbol);
292+
for (const char *c = name; *c; c++) {
293+
switch (*c) {
294+
case '"':
295+
case '\\':
296+
fputc('\\', f);
297+
fputc(*c, f);
298+
break;
299+
case '\n':
300+
fputs("\\n", f);
301+
break;
302+
case '\t':
303+
fputs("\\n", f);
304+
break;
305+
default:
306+
fputc(*c, f);
307+
break;
308+
}
309+
}
310+
}
286311

287312
#ifdef __cplusplus
288313
}

lib/src/parser.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ static void ts_parser__log(TSParser *self) {
160160
if (self->dot_graph_file) {
161161
fprintf(self->dot_graph_file, "graph {\nlabel=\"");
162162
for (char *c = &self->lexer.debug_buffer[0]; *c != 0; c++) {
163-
if (*c == '"') fputc('\\', self->dot_graph_file);
163+
if (*c == '"' || *c == '\\') fputc('\\', self->dot_graph_file);
164164
fputc(*c, self->dot_graph_file);
165165
}
166166
fprintf(self->dot_graph_file, "\"\n}\n\n");

lib/src/stack.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -846,11 +846,7 @@ bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f)
846846
fprintf(f, "label=\"");
847847
bool quoted = ts_subtree_visible(link.subtree) && !ts_subtree_named(link.subtree);
848848
if (quoted) fprintf(f, "'");
849-
const char *name = ts_language_symbol_name(language, ts_subtree_symbol(link.subtree));
850-
for (const char *c = name; *c; c++) {
851-
if (*c == '\"' || *c == '\\') fprintf(f, "\\");
852-
fprintf(f, "%c", *c);
853-
}
849+
ts_language_write_symbol_as_dot_string(language, f, ts_subtree_symbol(link.subtree));
854850
if (quoted) fprintf(f, "'");
855851
fprintf(f, "\"");
856852
fprintf(

lib/src/subtree.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -834,18 +834,6 @@ static size_t ts_subtree__write_char_to_string(char *s, size_t n, int32_t c) {
834834
return snprintf(s, n, "%d", c);
835835
}
836836

837-
static void ts_subtree__write_dot_string(FILE *f, const char *string) {
838-
for (const char *c = string; *c; c++) {
839-
if (*c == '"') {
840-
fputs("\\\"", f);
841-
} else if (*c == '\n') {
842-
fputs("\\n", f);
843-
} else {
844-
fputc(*c, f);
845-
}
846-
}
847-
}
848-
849837
static const char *ROOT_FIELD = "__ROOT__";
850838

851839
static size_t ts_subtree__write_to_string(
@@ -975,7 +963,7 @@ void ts_subtree__print_dot_graph(const Subtree *self, uint32_t start_offset,
975963
TSSymbol symbol = alias_symbol ? alias_symbol : subtree_symbol;
976964
uint32_t end_offset = start_offset + ts_subtree_total_bytes(*self);
977965
fprintf(f, "tree_%p [label=\"", (void *)self);
978-
ts_subtree__write_dot_string(f, ts_language_symbol_name(language, symbol));
966+
ts_language_write_symbol_as_dot_string(language, f, symbol);
979967
fprintf(f, "\"");
980968

981969
if (ts_subtree_child_count(*self) == 0) fprintf(f, ", shape=plaintext");

0 commit comments

Comments
 (0)