scdoc2mdoc

A fork of scdoc to output mdoc(7)
git clone git://git.sgregoratto.me/scdoc2mdoc
Log | Files | Refs | README | LICENSE

commit a7921cae1814bdf9df117c1250814434b6a97bce
parent 09886a5fa318213ad21f5c12b6441cfb5088be34
Author: Stephen Gregoratto <dev@sgregoratto.me>
Date:   Sat, 15 Jun 2019 17:47:15 +1000

Inital K&R reformatting of sources

Diffstat:
Mmain.c | 222+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mstring.c | 29++++++++++++++++++-----------
Mutf8.c | 65+++++++++++++++++++++++++++++++++++++----------------------------
Mutf8.h | 3++-
Mutil.c | 29++++++++++++++++++-----------
5 files changed, 196 insertions(+), 152 deletions(-)

diff --git a/main.c b/main.c @@ -20,7 +20,9 @@ char *strstr(const char *haystack, const char *needle); char *strerror(int errnum); -static int parse_section(struct parser *p) { +int +parse_section(struct parser *p) +{ str_t *section = str_create(); uint32_t ch; while ((ch = parser_getch(p)) != UTF8_INVALID) { @@ -28,9 +30,8 @@ static int parse_section(struct parser *p) { int ret = str_append_ch(section, ch); assert(ret != -1); } else if (ch == ')') { - if (!section->str) { + if (!section->str) break; - } int sec = strtol(section->str, NULL, 10); if (sec < 0 || sec > 9) { parser_fatal(p, "Expected section between 0 and 9"); @@ -42,12 +43,15 @@ static int parse_section(struct parser *p) { parser_fatal(p, "Expected digit or )"); break; } - }; + } + parser_fatal(p, "Expected manual section"); return -1; } -static str_t *parse_extra(struct parser *p) { +str_t * +parse_extra(struct parser *p) +{ str_t *extra = str_create(); int ret = str_append_ch(extra, '"'); assert(ret != -1); @@ -65,14 +69,17 @@ static str_t *parse_extra(struct parser *p) { assert(ret != -1); } } + str_free(extra); return NULL; } -static void parse_preamble(struct parser *p) { +void +parse_preamble(struct parser *p) +{ str_t *name = str_create(); int ex = 0; - str_t *extras[2] = { NULL }; + str_t *extras[2] = {NULL}; int section = -1; uint32_t ch; time_t date_time; @@ -84,66 +91,66 @@ static void parse_preamble(struct parser *p) { errno = 0; epoch = strtoull(source_date_epoch, &endptr, 10); if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) - || (errno != 0 && epoch == 0)) { + || (errno != 0 && epoch == 0)) { fprintf(stderr, "$SOURCE_DATE_EPOCH: strtoull: %s\n", - strerror(errno)); + strerror(errno)); exit(EXIT_FAILURE); - } - if (endptr == source_date_epoch) { - fprintf(stderr, "$SOURCE_DATE_EPOCH: No digits were found: %s\n", - endptr); + } else if (endptr == source_date_epoch) { + fprintf(stderr, + "$SOURCE_DATE_EPOCH: No digits were found: %s\n", + endptr); exit(EXIT_FAILURE); - } - if (*endptr != '\0') { - fprintf(stderr, "$SOURCE_DATE_EPOCH: Trailing garbage: %s\n", - endptr); + } else if (*endptr != '\0') { + fprintf(stderr, + "$SOURCE_DATE_EPOCH: Trailing garbage: %s\n", + endptr); exit(EXIT_FAILURE); - } - if (epoch > ULONG_MAX) { - fprintf(stderr, "$SOURCE_DATE_EPOCH: value must be smaller than or " - "equal to %lu but was found to be: %llu \n", - ULONG_MAX, epoch); + } else if (epoch > ULONG_MAX) { + fprintf(stderr, + "$SOURCE_DATE_EPOCH: value must be smaller than or " + "equal to %lu but was found to be: %llu \n", + ULONG_MAX, epoch); exit(EXIT_FAILURE); } date_time = epoch; } else { date_time = time(NULL); } + struct tm *date_tm = gmtime(&date_time); strftime(date, sizeof(date), "%F", date_tm); while ((ch = parser_getch(p)) != UTF8_INVALID) { - if ((ch < 0x80 && isalnum(ch)) || ch == '_' || ch == '-' || ch == '.') { + if ((ch < 0x80 && isalnum(ch)) || + ch == '_' || ch == '-' || ch == '.') { int ret = str_append_ch(name, ch); assert(ret != -1); } else if (ch == '(') { section = parse_section(p); } else if (ch == '"') { - if (ex == 2) { + if (ex == 2) parser_fatal(p, "Too many extra preamble fields"); - } extras[ex++] = parse_extra(p); } else if (ch == '\n') { - if (name->len == 0) { + if (name->len == 0) parser_fatal(p, "Expected preamble"); - } - if (section == -1) { + else if (section == -1) parser_fatal(p, "Expected manual section"); - } - char sec[2] = { '0' + section, 0 }; + + char sec[2] = {'0' + section, 0}; char *ex2 = extras[0] != NULL ? extras[0]->str : NULL; char *ex3 = extras[1] != NULL ? extras[1]->str : NULL; - fprintf(p->output, ".TH \"%s\" \"%s\" \"%s\"", name->str, sec, date); + fprintf(p->output, ".TH \"%s\" \"%s\" \"%s\"", + name->str, sec, date); /* ex2 and ex3 are already double-quoted */ - if (ex2) { + if (ex2) fprintf(p->output, " %s", ex2); - } - if (ex3) { + if (ex3) fprintf(p->output, " %s", ex3); - } - fprintf(p->output, "\n"); + fputc('\n', p->output); break; } } + str_free(name); for (int i = 0; i < 2; ++i) { if (extras[i] != NULL) { @@ -152,7 +159,9 @@ static void parse_preamble(struct parser *p) { } } -static void parse_format(struct parser *p, enum formatting fmt) { +void +parse_format(struct parser *p, enum formatting fmt) +{ char formats[FORMAT_LAST] = { [FORMAT_BOLD] = 'B', [FORMAT_UNDERLINE] = 'I', @@ -160,10 +169,11 @@ static void parse_format(struct parser *p, enum formatting fmt) { char error[512]; if (p->flags) { if ((p->flags & ~fmt)) { - snprintf(error, sizeof(error), "Cannot nest inline formatting " - "(began with %c at %d:%d)", - p->flags == FORMAT_BOLD ? '*' : '_', - p->fmt_line, p->fmt_col); + snprintf(error, sizeof(error), + "Cannot nest inline formatting " + "(began with %c at %d:%d)", + p->flags == FORMAT_BOLD ? '*' : '_', + p->fmt_line, p->fmt_col); parser_fatal(p, error); } fprintf(p->output, "\\fR"); @@ -175,7 +185,9 @@ static void parse_format(struct parser *p, enum formatting fmt) { p->flags ^= fmt; } -static void parse_linebreak(struct parser *p) { +void +parse_linebreak(struct parser *p) +{ uint32_t plus = parser_getch(p); if (plus != '+') { fprintf(p->output, "+"); @@ -190,15 +202,15 @@ static void parse_linebreak(struct parser *p) { return; } uint32_t ch = parser_getch(p); - if (ch == '\n') { - parser_fatal( - p, "Explicit line breaks cannot be followed by a blank line"); - } + if (ch == '\n') + parser_fatal(p, "Explicit line breaks cannot be followed by a blank line"); parser_pushch(p, ch); fprintf(p->output, "\n.br\n"); } -static void parse_text(struct parser *p) { +void +parse_text(struct parser *p) +{ uint32_t ch, next, last = ' '; int i = 0; while ((ch = parser_getch(p)) != UTF8_INVALID) { @@ -218,14 +230,14 @@ static void parse_text(struct parser *p) { break; case '_': next = parser_getch(p); - if (!isalnum(last) || ((p->flags & FORMAT_UNDERLINE) && !isalnum(next))) { + if (!isalnum(last) + || ((p->flags & FORMAT_UNDERLINE) && + !isalnum(next))) parse_format(p, FORMAT_UNDERLINE); - } else { + else utf8_fputch(p->output, ch); - } - if (next == UTF8_INVALID) { + if (next == UTF8_INVALID) return; - } parser_pushch(p, next); break; case '+': @@ -250,7 +262,9 @@ static void parse_text(struct parser *p) { } } -static void parse_heading(struct parser *p) { +void +parse_heading(struct parser *p) +{ uint32_t ch; int level = 1; while ((ch = parser_getch(p)) != UTF8_INVALID) { @@ -281,18 +295,19 @@ static void parse_heading(struct parser *p) { } } -static int parse_indent(struct parser *p, int *indent, bool write) { +int +parse_indent(struct parser *p, int *indent, bool write) +{ int i = 0; uint32_t ch; - while ((ch = parser_getch(p)) == '\t') { + while ((ch = parser_getch(p)) == '\t') ++i; - } + parser_pushch(p, ch); if (ch == '\n' && *indent != 0) { - // Don't change indent when we encounter empty lines + /* Don't change indent when we encounter empty lines */ return *indent; - } - if (write) { + } else if (write) { if (i < *indent) { for (int j = *indent; i < j; --j) { roff_macro(p, "RE", NULL); @@ -307,15 +322,17 @@ static int parse_indent(struct parser *p, int *indent, bool write) { return i; } -static void list_header(struct parser *p, int *num) { +void +list_header(struct parser *p, int *num) +{ fprintf(p->output, ".RS 4\n"); fprintf(p->output, ".ie n \\{\\\n"); if (*num == -1) { fprintf(p->output, "\\h'-0%d'%s\\h'+03'\\c\n", - *num >= 10 ? 5 : 4, "\\(bu"); + *num >= 10 ? 5 : 4, "\\(bu"); } else { fprintf(p->output, "\\h'-0%d'%d.\\h'+03'\\c\n", - *num >= 10 ? 5 : 4, *num); + *num >= 10 ? 5 : 4, *num); } fprintf(p->output, ".\\}\n"); fprintf(p->output, ".el \\{\\\n"); @@ -328,34 +345,32 @@ static void list_header(struct parser *p, int *num) { fprintf(p->output, ".\\}\n"); } -static void parse_list(struct parser *p, int *indent, int num) { +void +parse_list(struct parser *p, int *indent, int num) +{ uint32_t ch; - if ((ch = parser_getch(p)) != ' ') { + if ((ch = parser_getch(p)) != ' ') parser_fatal(p, "Expected space before start of list entry"); - } + list_header(p, &num); parse_text(p); bool closed = false; do { parse_indent(p, indent, true); - if ((ch = parser_getch(p)) == UTF8_INVALID) { + if ((ch = parser_getch(p)) == UTF8_INVALID) break; - } switch (ch) { case ' ': - if ((ch = parser_getch(p)) != ' ') { + if ((ch = parser_getch(p)) != ' ') parser_fatal(p, "Expected two spaces for list entry continuation"); - } parse_text(p); break; case '-': case '.': - if ((ch = parser_getch(p)) != ' ') { + if ((ch = parser_getch(p)) != ' ') parser_fatal(p, "Expected space before start of list entry"); - } - if (!closed) { + else if (!closed) roff_macro(p, "RE", NULL); - } list_header(p, &num); parse_text(p); closed = false; @@ -367,12 +382,13 @@ static void parse_list(struct parser *p, int *indent, int num) { } } while (ch != UTF8_INVALID); ret: - if (!closed) { + if (!closed) roff_macro(p, "RE", NULL); - } } -static void parse_literal(struct parser *p, int *indent) { +void +parse_literal(struct parser *p, int *indent) +{ uint32_t ch; if ((ch = parser_getch(p)) != '`' || (ch = parser_getch(p)) != '`' || @@ -439,7 +455,7 @@ enum table_align { struct table_row { struct table_cell *cell; - struct table_row *next; + struct table_row *next; }; struct table_cell { @@ -448,7 +464,9 @@ struct table_cell { struct table_cell *next; }; -static void parse_table(struct parser *p, uint32_t style) { +void +parse_table(struct parser *p, uint32_t style) +{ struct table_row *table = NULL; struct table_row *currow = NULL, *prevrow = NULL; struct table_cell *curcell = NULL; @@ -457,9 +475,8 @@ static void parse_table(struct parser *p, uint32_t style) { parser_pushch(p, '|'); do { - if ((ch = parser_getch(p)) == UTF8_INVALID) { + if ((ch = parser_getch(p)) == UTF8_INVALID) break; - } switch (ch) { case '\n': goto commit_table; @@ -473,9 +490,8 @@ static void parse_table(struct parser *p, uint32_t style) { curcell = calloc(1, sizeof(struct table_cell)); currow->cell = curcell; column = 0; - if (!table) { + if (!table) table = currow; - } break; case ':': if (!currow) { @@ -550,16 +566,14 @@ continue_cell: } commit_cell: if (strstr(curcell->contents->str, "T{") - || strstr(curcell->contents->str, "T}")) { + || strstr(curcell->contents->str, "T}")) parser_fatal(p, "Cells cannot contain T{ or T} " "due to roff limitations"); - } } while (ch != UTF8_INVALID); commit_table: - if (ch == UTF8_INVALID) { + if (ch == UTF8_INVALID) return; - } roff_macro(p, "TS", NULL); @@ -613,22 +627,22 @@ commit_table: fprintf(p->output, ".sp 1\n"); } -static void parse_document(struct parser *p) { +void +parse_document(struct parser *p) +{ uint32_t ch; int indent = 0; do { parse_indent(p, &indent, true); - if ((ch = parser_getch(p)) == UTF8_INVALID) { + if ((ch = parser_getch(p)) == UTF8_INVALID) break; - } switch (ch) { case ';': - if ((ch = parser_getch(p)) != ' ') { + if ((ch = parser_getch(p)) != ' ') parser_fatal(p, "Expected space after ; to begin comment"); - } - do { + do ch = parser_getch(p); - } while (ch != UTF8_INVALID && ch != '\n'); + while (ch != UTF8_INVALID && ch != '\n'); break; case '#': if (indent != 0) { @@ -684,26 +698,32 @@ static void parse_document(struct parser *p) { } while (ch != UTF8_INVALID); } -static void output_scdoc_preamble(struct parser *p) { +void +output_scdoc_preamble(struct parser *p) +{ fprintf(p->output, ".\\\" Generated by scdoc " VERSION "\n"); - // Fix weird quotation marks - // http://bugs.debian.org/507673 - // http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html + /* + * Fix weird quotation marks + * http://bugs.debian.org/507673 + * http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html + */ fprintf(p->output, ".ie \\n(.g .ds Aq \\(aq\n"); fprintf(p->output, ".el .ds Aq '\n"); - // Disable hyphenation: + /* Disable hyphenation: */ roff_macro(p, "nh", NULL); - // Disable justification: + /* Disable justification: */ roff_macro(p, "ad l", NULL); fprintf(p->output, ".\\\" Begin generated content:\n"); } -int main(int argc, char **argv) { +int +main(int argc, char **argv) +{ if (argc == 2 && strcmp(argv[1], "-v") == 0) { printf("scdoc " VERSION "\n"); return 0; } else if (argc > 1) { - fprintf(stderr, "Usage: scdoc < input.scd > output.roff\n"); + fputs("Usage: scdoc < input.scd > output.roff", stderr); return 1; } struct parser p = { diff --git a/string.c b/string.c @@ -6,19 +6,22 @@ #include "str.h" #include "utf8.h" -static int ensure_capacity(str_t *str, size_t len) { +static int +ensure_capacity(str_t *str, size_t len) +{ if (len + 1 >= str->size) { char *new = realloc(str->str, str->size * 2); - if (!new) { + if (!new) return 0; - } str->str = new; str->size *= 2; } return 1; } -str_t *str_create() { +str_t * +str_create() +{ str_t *str = calloc(sizeof(str_t), 1); str->str = malloc(16); str->size = 16; @@ -27,20 +30,24 @@ str_t *str_create() { return str; } -void str_free(str_t *str) { - if (!str) return; +void +str_free(str_t *str) +{ + if (!str) + return; free(str->str); free(str); } -int str_append_ch(str_t *str, uint32_t ch) { +int +str_append_ch(str_t *str, uint32_t ch) +{ int size = utf8_chsize(ch); - if (size <= 0) { + if (size <= 0) return -1; - } - if (!ensure_capacity(str, str->len + size)) { + else if (!ensure_capacity(str, str->len + size)) return -1; - } + utf8_encode(&str->str[str->len], ch); str->len += size; str->str[str->len] = '\0'; diff --git a/utf8.c b/utf8.c @@ -4,15 +4,17 @@ #include "utf8.h" -size_t utf8_chsize(uint32_t ch) { - if (ch < 0x80) { +size_t +utf8_chsize(uint32_t ch) +{ + if (ch < 0x80) return 1; - } else if (ch < 0x800) { + else if (ch < 0x800) return 2; - } else if (ch < 0x10000) { + else if (ch < 0x10000) return 3; - } - return 4; + else + return 4; } uint8_t masks[] = { @@ -24,7 +26,9 @@ uint8_t masks[] = { 0x01 }; -uint32_t utf8_decode(const char **char_str) { +uint32_t +utf8_decode(const char **char_str) +{ uint8_t **s = (uint8_t **)char_str; uint32_t cp = 0; @@ -50,7 +54,9 @@ uint32_t utf8_decode(const char **char_str) { return cp; } -size_t utf8_encode(char *str, uint32_t ch) { +size_t +utf8_encode(char *str, uint32_t ch) +{ size_t len = 0; uint8_t first; @@ -77,31 +83,33 @@ size_t utf8_encode(char *str, uint32_t ch) { return len; } -uint32_t utf8_fgetch(FILE *f) { +uint32_t +utf8_fgetch(FILE *f) +{ char buffer[UTF8_MAX_SIZE]; int c = fgetc(f); - if (c == EOF) { + if (c == EOF) return UTF8_INVALID; - } + buffer[0] = (char)c; int size = utf8_size(buffer); if (size > UTF8_MAX_SIZE) { fseek(f, size - 1, SEEK_CUR); return UTF8_INVALID; - } - - if (size > 1) { + } else if (size > 1) { int amt = fread(&buffer[1], 1, size - 1, f); - if (amt != size - 1) { + if (amt != size - 1) return UTF8_INVALID; - } } + const char *ptr = buffer; return utf8_decode(&ptr); } -size_t utf8_fputch(FILE *f, uint32_t ch) { +size_t +utf8_fputch(FILE *f, uint32_t ch) +{ char buffer[UTF8_MAX_SIZE]; char *ptr = buffer; size_t size = utf8_encode(ptr, ch); @@ -113,21 +121,22 @@ struct { uint8_t result; int octets; } sizes[] = { - { 0x80, 0x00, 1 }, - { 0xE0, 0xC0, 2 }, - { 0xF0, 0xE0, 3 }, - { 0xF8, 0xF0, 4 }, - { 0xFC, 0xF8, 5 }, - { 0xFE, 0xF8, 6 }, + { 0x80, 0x00, 1 }, + { 0xE0, 0xC0, 2 }, + { 0xF0, 0xE0, 3 }, + { 0xF8, 0xF0, 4 }, + { 0xFC, 0xF8, 5 }, + { 0xFE, 0xF8, 6 }, { 0x80, 0x80, -1 }, }; -int utf8_size(const char *s) { +int +utf8_size(const char *s) +{ uint8_t c = (uint8_t)*s; - for (size_t i = 0; i < sizeof(sizes) / 2; ++i) { - if ((c & sizes[i].mask) == sizes[i].result) { + for (size_t i = 0; i < sizeof(sizes) / 2; ++i) + if ((c & sizes[i].mask) == sizes[i].result) return sizes[i].octets; - } - } + return -1; } diff --git a/utf8.h b/utf8.h @@ -1,6 +1,7 @@ #ifndef _UTF8_H #define _UTF8_H -/* Technically UTF-8 supports up to 6 byte codepoints, +/* + * Technically UTF-8 supports up to 6 byte codepoints, * but Unicode itself doesn't really bother with more than 4. */ #define UTF8_MAX_SIZE 4 diff --git a/util.c b/util.c @@ -7,19 +7,21 @@ #include "utf8.h" #include "util.h" -void parser_fatal(struct parser *parser, const char *err) { - fprintf(stderr, "Error at %d:%d: %s\n", - parser->line, parser->col, err); +void +parser_fatal(struct parser *parser, const char *err) +{ + fprintf(stderr, "Error at %d:%d: %s\n", parser->line, parser->col, err); fclose(parser->input); fclose(parser->output); exit(1); } -uint32_t parser_getch(struct parser *parser) { +uint32_t +parser_getch(struct parser *parser) +{ if (parser->qhead) { return parser->queue[--parser->qhead]; - } - if (parser->str) { + } else if (parser->str) { uint32_t ch = utf8_decode(&parser->str); if (!ch || ch == UTF8_INVALID) { parser->str = NULL; @@ -37,17 +39,22 @@ uint32_t parser_getch(struct parser *parser) { return ch; } -void parser_pushch(struct parser *parser, uint32_t ch) { - if (ch != UTF8_INVALID) { +void +parser_pushch(struct parser *parser, uint32_t ch) +{ + if (ch != UTF8_INVALID) parser->queue[parser->qhead++] = ch; - } } -void parser_pushstr(struct parser *parser, const char *str) { +void +parser_pushstr(struct parser *parser, const char *str) +{ parser->str = str; } -int roff_macro(struct parser *p, char *cmd, ...) { +int +roff_macro(struct parser *p, char *cmd, ...) +{ FILE *f = p->output; int l = fprintf(f, ".%s", cmd); va_list ap;