Allow subsection in preamble

Subsections are useful in case on name conflicts within a section.
Typically man pages in distributions are using the 'p' subsection.
They are also needed for the man pages of wrapper commands for example.
master
Damien Tardy-Panis 5 years ago committed by Drew DeVault
parent 656484e0ab
commit baaebab77d
  1. 27
      src/main.c
  2. 22
      test/preamble

@ -16,31 +16,35 @@
char *strstr(const char *haystack, const char *needle); char *strstr(const char *haystack, const char *needle);
char *strerror(int errnum); char *strerror(int errnum);
static int parse_section(struct parser *p) { static struct str *parse_section(struct parser *p) {
struct str *section = str_create(); struct str *section = str_create();
uint32_t ch; uint32_t ch;
char *subsection;
while ((ch = parser_getch(p)) != UTF8_INVALID) { while ((ch = parser_getch(p)) != UTF8_INVALID) {
if (ch < 0x80 && isdigit(ch)) { if (ch < 0x80 && isalnum(ch)) {
int ret = str_append_ch(section, ch); int ret = str_append_ch(section, ch);
assert(ret != -1); assert(ret != -1);
} else if (ch == ')') { } else if (ch == ')') {
if (section->len == 0) { if (section->len == 0) {
break; break;
} }
int sec = strtol(section->str, NULL, 10); int sec = strtol(section->str, &subsection, 10);
if (section->str == subsection) {
parser_fatal(p, "Expected section digit");
break;
}
if (sec < 0 || sec > 9) { if (sec < 0 || sec > 9) {
parser_fatal(p, "Expected section between 0 and 9"); parser_fatal(p, "Expected section between 0 and 9");
break; break;
} }
str_free(section); return section;
return sec;
} else { } else {
parser_fatal(p, "Expected digit or )"); parser_fatal(p, "Expected alphanumerical character or )");
break; break;
} }
}; };
parser_fatal(p, "Expected manual section"); parser_fatal(p, "Expected manual section");
return -1; return NULL;
} }
static struct str *parse_extra(struct parser *p) { static struct str *parse_extra(struct parser *p) {
@ -69,7 +73,7 @@ static void parse_preamble(struct parser *p) {
struct str *name = str_create(); struct str *name = str_create();
int ex = 0; int ex = 0;
struct str *extras[2] = { NULL }; struct str *extras[2] = { NULL };
int section = -1; struct str *section = NULL;
uint32_t ch; uint32_t ch;
time_t date_time; time_t date_time;
char date[256]; char date[256];
@ -122,13 +126,12 @@ static void parse_preamble(struct parser *p) {
if (name->len == 0) { if (name->len == 0) {
parser_fatal(p, "Expected preamble"); parser_fatal(p, "Expected preamble");
} }
if (section == -1) { if (section == NULL) {
parser_fatal(p, "Expected manual section"); parser_fatal(p, "Expected manual section");
} }
char sec[2] = { '0' + section, 0 };
char *ex2 = extras[0] != NULL ? extras[0]->str : NULL; char *ex2 = extras[0] != NULL ? extras[0]->str : NULL;
char *ex3 = extras[1] != NULL ? extras[1]->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, section->str, date);
/* ex2 and ex3 are already double-quoted */ /* ex2 and ex3 are already double-quoted */
if (ex2) { if (ex2) {
fprintf(p->output, " %s", ex2); fprintf(p->output, " %s", ex2);
@ -138,7 +141,7 @@ static void parse_preamble(struct parser *p) {
} }
fprintf(p->output, "\n"); fprintf(p->output, "\n");
break; break;
} else if (section == -1) { } else if (section == NULL) {
parser_fatal(p, "Name characters must be A-Z, a-z, 0-9, `-`, `_`, or `.`"); parser_fatal(p, "Name characters must be A-Z, a-z, 0-9, `-`, `_`, or `.`");
} }
} }

@ -25,24 +25,42 @@ scdoc <<EOF >/dev/null
EOF EOF
end 1 end 1
begin "Expects section to be a number" begin "Expects section to start with a number"
scdoc <<EOF >/dev/null scdoc <<EOF >/dev/null
test(hello) test(hello)
EOF EOF
end 1 end 1
begin "Expects section to legit" begin "Expects section to be legit"
scdoc <<EOF >/dev/null scdoc <<EOF >/dev/null
test(100) test(100)
EOF EOF
end 1 end 1
begin "Expects section to be legit with subsection"
scdoc <<EOF >/dev/null
test(100hello)
EOF
end 1
begin "Expects section not to contain a space"
scdoc <<EOF >/dev/null
test(8 hello)
EOF
end 1
begin "Accepts a valid preamble" begin "Accepts a valid preamble"
scdoc <<EOF >/dev/null scdoc <<EOF >/dev/null
test(8) test(8)
EOF EOF
end 0 end 0
begin "Accepts a valid preamble with subsection"
scdoc <<EOF >/dev/null
test(8hello)
EOF
end 0
# Make sure SOURCE_DATE_EPOCH is not set for the next tests # Make sure SOURCE_DATE_EPOCH is not set for the next tests
unset SOURCE_DATE_EPOCH unset SOURCE_DATE_EPOCH

Loading…
Cancel
Save