~sircmpwn/scdoc

baaebab77db8123ee97a1c4c6a25c0873abf25e7 — Damien Tardy-Panis 8 months ago 656484e
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.
2 files changed, 35 insertions(+), 14 deletions(-)

M src/main.c
M test/preamble
M src/main.c => src/main.c +15 -12
@@ 16,31 16,35 @@
char *strstr(const char *haystack, const char *needle);
char *strerror(int errnum);

static int parse_section(struct parser *p) {
static struct str *parse_section(struct parser *p) {
	struct str *section = str_create();
	uint32_t ch;
	char *subsection;
	while ((ch = parser_getch(p)) != UTF8_INVALID) {
		if (ch < 0x80 && isdigit(ch)) {
		if (ch < 0x80 && isalnum(ch)) {
			int ret = str_append_ch(section, ch);
			assert(ret != -1);
		} else if (ch == ')') {
			if (section->len == 0) {
				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) {
				parser_fatal(p, "Expected section between 0 and 9");
				break;
			}
			str_free(section);
			return sec;
			return section;
		} else {
			parser_fatal(p, "Expected digit or )");
			parser_fatal(p, "Expected alphanumerical character or )");
			break;
		}
	};
	parser_fatal(p, "Expected manual section");
	return -1;
	return NULL;
}

static struct str *parse_extra(struct parser *p) {


@@ 69,7 73,7 @@ static void parse_preamble(struct parser *p) {
	struct str *name = str_create();
	int ex = 0;
	struct str *extras[2] = { NULL };
	int section = -1;
	struct str *section = NULL;
	uint32_t ch;
	time_t date_time;
	char date[256];


@@ 122,13 126,12 @@ static void parse_preamble(struct parser *p) {
			if (name->len == 0) {
				parser_fatal(p, "Expected preamble");
			}
			if (section == -1) {
			if (section == NULL) {
				parser_fatal(p, "Expected manual section");
			}
			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, section->str, date);
			/* ex2 and ex3 are already double-quoted */
			if (ex2) {
				fprintf(p->output, " %s", ex2);


@@ 138,7 141,7 @@ static void parse_preamble(struct parser *p) {
			}
			fprintf(p->output, "\n");
			break;
		} else if (section == -1) {
		} else if (section == NULL) {
			parser_fatal(p, "Name characters must be A-Z, a-z, 0-9, `-`, `_`, or `.`");
		}
	}

M test/preamble => test/preamble +20 -2
@@ 25,24 25,42 @@ scdoc <<EOF >/dev/null
EOF
end 1

begin "Expects section to be a number"
begin "Expects section to start with a number"
scdoc <<EOF >/dev/null
test(hello)
EOF
end 1

begin "Expects section to legit"
begin "Expects section to be legit"
scdoc <<EOF >/dev/null
test(100)
EOF
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"
scdoc <<EOF >/dev/null
test(8)
EOF
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
unset SOURCE_DATE_EPOCH