Say that an option's file is one the assembler writes, and check we said it

-S was added without a row in the Assembler Manual, and the usage it
printed listed a bare "-S <file>" with no long name and no statement of
what the file is for. That is not merely incomplete, it is misleading:
"-S <file>" reads just as naturally as "dump the symbols of <file>", and
asking for it that way hands the source to -S, leaves nothing positional
behind it, and is answered with "No source file specified" on a command
line that plainly names a source. The error described the hole the
mistake left and hid the mistake.

So the usage now prints the long names, says outright that every <file>
is a path it writes and the source is the last argument on its own, and
ends with a whole example command. When the source is missing and a
file-taking option was given, the error says which options take a path
to write. The manual gains the -S row it never had, a warning in the
same words, and a sentence on what a symbol dump is for.

Documenting it twice is how it went wrong once, so docs.sh now settles
both against getopt's own option table: every option the assembler takes
has a row in the manual and a line in its own usage. Verified with
break.sh against the manual row and the usage line separately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-09-05 09:40:21 -04:00
co-authored by Claude Opus 5
parent cdee9acfae
commit 7a55cfe151
3 changed files with 65 additions and 5 deletions
+34
View File
@@ -172,6 +172,40 @@ else:
problems.append("%s (0x%02X) is a device class and has no row in the Devices"
" table" % (name, value))
# ---- Every option the assembler takes is written down in both places ----
#
# An option added to getopt is an option nobody knows about until it is said twice: in the
# manual's table, and in the usage the assembler prints when it is asked for help or refuses
# a command line. -S arrived with neither, and the damage was worse than an undocumented
# switch. The usage listed a bare "-S <file>" with no long name and no statement that the
# file is one it WRITES, so it read as "dump the symbols of <file>" - which hands the source
# to -S, leaves nothing positional behind it, and gets answered with "No source file
# specified" on a command line that plainly names one.
#
# The option table is the source of truth because it is what getopt_long is actually given.
assembler = read("Source/Assembler/Assembler.c")
options = re.findall(r'^\s*\{"([a-z]+)",\s*\w+,\s*0,\s*\'(\w)\'\s*\},', assembler, re.M)
if not options:
problems.append("could not find the assembler's option table")
elif "void printUsage" not in assembler:
problems.append("the assembler has lost its printUsage")
elif "## Running the Assembler:" not in am:
problems.append("the Assembler Manual has lost its options table")
else:
usage = assembler.split("void printUsage")[1].split("\n}")[0]
section = am.split("## Running the Assembler:")[1].split("\n## ")[0]
# Only the table rows count, so a switch merely mentioned in the prose below it does not
# pass for a documented one.
rows = re.findall(r'^\| (-\w, --[a-z]+)', section, re.M)
for longName, shortName in options:
spelled = "-%s, --%s" % (shortName, longName)
if spelled not in rows:
problems.append("the assembler takes %s and the Assembler Manual's option table"
" has no row for it" % spelled)
if spelled not in usage:
problems.append("the assembler takes %s and its own usage message does not name"
" it" % spelled)
# ---- The vector ranges the manuals quote are the ones the assembler uses ----
#
# Both manuals print the boundary between numbers a program may pin and numbers the