diff options
Diffstat (limited to 'src/format.c')
-rw-r--r-- | src/format.c | 121 |
1 files changed, 102 insertions, 19 deletions
diff --git a/src/format.c b/src/format.c index fc6c8d6..11b405a 100644 --- a/src/format.c +++ b/src/format.c @@ -24,7 +24,7 @@ #include <string.h> const char * -grecs_data_type_string (enum grecs_data_type type) +grecs_data_type_string(enum grecs_data_type type) { switch (type) { case grecs_type_void: @@ -68,14 +68,14 @@ grecs_data_type_string (enum grecs_data_type type) } static void -format_level(FILE *stream, unsigned level) +format_level(unsigned level, FILE *stream) { while (level--) fprintf(stream, " "); } void -grecs_format_docstring(FILE *stream, const char *docstring, unsigned level) +grecs_format_docstring(const char *docstring, unsigned level, FILE *stream) { size_t len = strlen(docstring); int width = 78 - level * 2; @@ -101,7 +101,7 @@ grecs_format_docstring(FILE *stream, const char *docstring, unsigned level) if (seglen == 0 || *p == 0) seglen = p - docstring; - format_level(stream, level); + format_level(level, stream); fprintf(stream, "# "); fwrite(docstring, seglen, 1, stream); fputc('\n', stream); @@ -119,14 +119,14 @@ grecs_format_docstring(FILE *stream, const char *docstring, unsigned level) } void -grecs_format_simple_statement(FILE *stream, struct grecs_keyword *kwp, - unsigned level) +grecs_format_simple_statement(struct grecs_keyword *kwp, unsigned level, + FILE *stream) { const char *argstr; if (kwp->docstring) - grecs_format_docstring(stream, kwp->docstring, level); - format_level(stream, level); + grecs_format_docstring(kwp->docstring, level, stream); + format_level(level, stream); if (kwp->argname) argstr = kwp->argname; @@ -136,7 +136,7 @@ grecs_format_simple_statement(FILE *stream, struct grecs_keyword *kwp, if (strchr("<[", argstr[0])) fprintf(stream, "%s %s;\n", kwp->ident, gettext(argstr)); else if (strchr (argstr, ':')) - fprintf (stream, "%s <%s>;\n", kwp->ident, gettext(argstr)); + fprintf(stream, "%s <%s>;\n", kwp->ident, gettext(argstr)); else { fprintf(stream, "%s <%s: ", kwp->ident, gettext(argstr)); if (GRECS_IS_LIST(kwp->type)) @@ -151,34 +151,117 @@ grecs_format_simple_statement(FILE *stream, struct grecs_keyword *kwp, } void -grecs_format_block_statement(FILE *stream, struct grecs_keyword *kwp, - unsigned level) +grecs_format_block_statement(struct grecs_keyword *kwp, unsigned level, + FILE *stream) { if (kwp->docstring) - grecs_format_docstring(stream, kwp->docstring, level); - format_level(stream, level); + grecs_format_docstring(kwp->docstring, level, stream); + format_level(level, stream); fprintf(stream, "%s", kwp->ident); if (kwp->argname) fprintf(stream, " <%s>", gettext(kwp->argname)); fprintf(stream, " {\n"); - grecs_format_statement_array(stream, kwp->kwd, 0, level + 1); - format_level(stream, level); + grecs_format_statement_array(kwp->kwd, 0, level + 1, stream); + format_level(level, stream); fprintf(stream, "}\n"); } void -grecs_format_statement_array(FILE *stream, struct grecs_keyword *kwp, +grecs_format_statement_array(struct grecs_keyword *kwp, unsigned n, - unsigned level) + unsigned level, + FILE *stream) { for (; kwp->ident; kwp++, n++) { if (n) fputc('\n', stream); if (kwp->type == grecs_type_section) - grecs_format_block_statement(stream, kwp, level); + grecs_format_block_statement(kwp, level, stream); else - grecs_format_simple_statement(stream, kwp, level); + grecs_format_simple_statement(kwp, level, stream); } } + +void +grecs_format_locus(grecs_locus_t *locus, FILE *fp) +{ + fprintf(fp, "%s:%d:", locus->file, locus->line); +} + +void +grecs_format_node_ident(struct grecs_node *node, int delim, FILE *fp) +{ + if (node->up) + grecs_format_node_ident(node->up, delim, fp); + fputc(delim, fp); + fprintf(fp, "%s", node->ident); + if (node->type == grecs_node_block && + !GRECS_VALUE_EMPTY_P(&node->value)) { + fputc('=', fp); + grecs_format_value(&node->value, fp); + } +} + +void +grecs_format_value(struct grecs_value *val, FILE *fp) +{ + int i; + struct grecs_list_entry *ep; + + switch (val->type) { + case GRECS_TYPE_STRING: + fprintf(fp, "\"%s\"", val->v.string); /*FIXME: Quoting*/ + break; + + case GRECS_TYPE_LIST: + fputc('(', fp); + for (ep = val->v.list->head; ep; ep = ep->next) { + grecs_format_value(ep->data, fp); + if (ep->next) { + fputc(',', fp); + fputc(' ', fp); + } + } + fputc(')', fp); + break; + + case GRECS_TYPE_ARRAY: + for (i = 0; i < val->v.arg.c; i++) { + if (i) + fputc(' ', fp); + grecs_format_value(&val->v.arg.v[i], fp); + } + } +} + +void +grecs_format_node(struct grecs_node *node, int flags, FILE *fp) +{ + int delim = flags & 0xff; + + if (!delim) + delim = '.'; + switch (node->type) { + case grecs_node_block: + for (node = node->down; node; node = node->next) { + grecs_format_node(node, flags, fp); + if (node->next) + fputc('\n', fp); + } + break; + + case grecs_node_stmt: + if (flags & GRECS_NODE_FLAG_LOCUS) { + grecs_format_locus(&node->locus, fp); + fputc(' ', fp); + } + grecs_format_node_ident(node, delim, fp); + fputc(':', fp); + fputc(' ', fp); + grecs_format_value(&node->value, fp); + } +} + + |