Declare subjects instead of picking them up automatically
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 28 Apr 2013 12:38:50 +0000 (14:38 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Wed, 8 May 2013 04:57:57 +0000 (06:57 +0200)
Since subjects were added in Empire 2, we've always picked them up
from .SA requests.  If you mistype a subject there, you get a "is a
NEW subject" warning, and incorrect subject pages.  When building a
pristine tree, you get bogus "is a NEW subject" warnings for all
subjects.  If you somehow delete the generated subjects.mk, but not
the generated subject files, the build breaks.

Declare subjects in Make variable subjects.  Drop generated makefile
subject.mk.

Treat unknown topics in .SA arguments as errors.  This replaces the
"$subj is a NEW subject" warning.

Treat subjects without member pages as errors.  This replaces the "The
subject $subj has been removed" warning.

Safer and simpler.

.gitignore
Make.mk
info/README
info/mksubj.pl
info/subjects.mk [new file with mode: 0644]

index 2646fb9896e09b3e892135fba958edd8f33175a9..6bc335726bdfbf390b935cac8cfcf9ddb9cd0e4f 100644 (file)
@@ -48,7 +48,6 @@
 /src/lib/global/path.c
 /autom4te.cache
 /src/client/autom4te.cache
-/subjects.mk
 # $(src_distgen)
 /aclocal.m4
 /config.h.in
diff --git a/Make.mk b/Make.mk
index d34ad88479f5c0ab3451fca8ca1c44ff43e61eb0..4a1b2328d0fe9a46f879879986d5c6ddb26fe369 100644 (file)
--- a/Make.mk
+++ b/Make.mk
@@ -56,8 +56,8 @@ tsrc := $(filter %.t, $(src))
 man6 := $(filter man/%.6, $(src))
 builtins := $(filter src/lib/global/%.config, $(src))
 
-# Info subjects (automatically generated)
--include subjects.mk
+# Info subjects
+include $(srcdir)/info/subjects.mk
 
 # Abbreviations
 topics := $(patsubst %.t,%,$(notdir $(tsrc)))
@@ -102,7 +102,7 @@ subst.in = sed \
 
 # Generated files
 # See `Cleanliness' below
-mk := subjects.mk
+mk :=
 ifeq ($(revctrl),git)
 mk += $(srcdir)/sources.mk
 endif
@@ -322,19 +322,18 @@ $(libs) $(empth_lib):
 
 # Info formatting
 
-# mksubj.pl reads $(tsrc) and writes subjects.mk $(tsubj).  The naive
-# rule
-#     subjects.mk $(ttop) $(tsubj): $(tsrc)
+# mksubj.pl reads $(tsrc) and writes $(tsubj).  The naive rule
+#     $(ttop) $(tsubj): $(tsrc)
 #           COMMAND
 # runs COMMAND once for each target.  That's because multiple targets
 # in an explicit rule is just a shorthand for one rule per target,
 # each with the same prerequisites and commands.  Use a stamp file.
-subjects.mk $(tsubj): info/stamp-subj ;
+$(tsubj): info/stamp-subj ;
 info/stamp-subj: info/mksubj.pl $(tsrc)
-       $(call quiet-command,perl $(srcdir)/info/mksubj.pl $(filter %.t, $^),GEN '$$(subjects)')
+       $(call quiet-command,perl $(srcdir)/info/mksubj.pl $(subjects) $(filter %.t, $^),GEN '$$(subjects)')
        >$@
 
-$(ttop): info/mktop.pl $(tsrc)
+$(ttop): info/mktop.pl info/subjects.mk
        $(call quiet-command,perl $(srcdir)/info/mktop.pl $@ $(subjects),GEN $@)
 
 info.nr/all: $(filter-out info.nr/all, $(info.nr))
index e35d069f090810b6a2154e06ad9edc461461d59a..b2a06f337b3dc7a8eb24b26f05ad53db302942ce 100644 (file)
@@ -43,9 +43,9 @@ The first line must be a title header:
 The second line must be a name header:
 .NA arg1 arg2
   - arg1 must be the name
-  - arg2 is a one-line description of the info page which will be
-    put on the Subject page that your info page belongs to.  It should
-    be in double quotes
+  - arg2 is a one-line description of the info page which will be put
+    on the subject pages that your info page belongs to.  It should be
+    in double quotes
 
 The third line must be a level header:
 .LV arg
@@ -54,10 +54,11 @@ The third line must be a level header:
 The last line should be a see also:
 .SA "item1, item2, ..., subject1, subject2"
   - the stuff in quotes is a list of other info pages which are
-    related to this page and info Subjects to which this page belongs.
+    related to this page, and subjects to which this page belongs.
   - the stuff in quotes must all be on the same line
-  - You must include at least one subject (see the Subjects
-    subdirectory) in the list (at the end of the list by convention).
+  - You must include at least one subject in the list (at the end of
+    the list by convention).  Valid subjects are listed in
+    info/subjects.mk.
 
 The lines in between can contain troff requests.  The following
 additional requests are available:
@@ -92,17 +93,9 @@ Fancy troff magic is prone to break HTML output.
 The scripts read all of the info pages and create a two-level table of
 contents for them, organized by subject.  An info page belongs to a
 subject if that subject appears as an entry in the .SA ("SEE ALSO")
-field of the info page _and_ that entry is not the name of another
-info page.
+field of the info page.
 
-For example, the .SA field of headlines.t contains the entries
-"newspaper" and "Communication".  Since there's already an info page
-called "newspaper.t", but there is no "Communication" info page, then
-the headlines info page is considered to be a member of the
-Communication
-subject.
-
-The output of these script is a bunch of .t files.  The file TOP.t is
+The output of these scripts is a bunch of .t files.  The file TOP.t is
 the top-level table of contents and lists all of the subjects.  Then
 for each SUBJECT, a SUBJECT.t file is created, listing all of the info
 pages that belong to it.
index 48e589e0a0bd1baf2377c42738b540ed1fc517f6..4e966b123e6434d3de62f5f0c728012f9416fea7 100644 (file)
 #      Ken Stevens (when it was still info.pl)
 #      Markus Armbruster, 2006-2013
 #
-# Usage: mksubj.pl INFO-FILE...
+# Usage: mksubj.pl SUBJECT... INFO-FILE...
 #
-# Read the INFO-FILE..., read and update subjects.mk, create
-# info/SUBJECT.t for each SUBJECT.
+# Read the INFO-FILE..., create info/SUBJECT.t for each SUBJECT.
 
 use strict;
 use warnings;
 use File::stat;
 
-use Errno qw(ENOENT);
 use Fcntl qw(O_WRONLY O_EXCL O_CREAT);
 
 # The chapters, in order
 my @Chapters = qw/Introduction Concept Command Server/;
 
 my @Levels = qw/Basic Expert Obsolete/;
-my @Subjects;
+my %Subjects;
 
 # $filename{TOPIC} is TOPIC's file name
 my %filename;
@@ -74,7 +72,9 @@ my %subject;
 #                 column formatting)
 my %largest;
 
-@Subjects = split(' ', read_make_var("subjects", "subjects.mk", ""));
+while ($#ARGV >= 0 && $ARGV[0] !~ /\.t$/) {
+    $Subjects{shift @ARGV} = undef;
+}
 
 for (@ARGV) {
     parse_file($_);
@@ -84,34 +84,7 @@ for my $t (sort keys %desc) {
     parse_see_also($t);
 }
 
-@Subjects = create_subjects();
-
-open(F, ">subjects.mk")
-    or die "Can't open subjects.mk for writing: $!";
-print F "subjects := " . join(' ', @Subjects) . "\n";
-close(F);
-
-exit 0;
-
-# Read a variable value from a makefile
-sub read_make_var {
-    my ($var, $fname, $dflt) = @_;
-    my $val;
-
-    unless (open(F, "<$fname")) {
-       return $dflt if $! == ENOENT and defined $dflt;
-       die "Can't open $fname: $!";
-    }
-    while (<F>) {
-       if (/^[ \t]*\Q$var\E[ \t]*:?=[ \t]*(.*)/) {
-           $val = $1;
-           last;
-       }
-    }
-    close(F);
-    defined($val) or die "Can't find $var in $fname";
-    return $val;
-}
+create_subjects();
 
 # Parse an info file
 # Set $filename, $filename{TOPIC}, $long{TOPIC}, $chapter{TOPIC},
@@ -194,9 +167,12 @@ sub parse_see_also {
     my $found;                # found a subject?
 
     $wanted = undef if $wanted eq 'Concept' or $wanted eq 'Command';
+    $filename = $filename{$topic};
+    $. = $sanr{$topic};
 
     for (@see_also) {
        if (!exists $desc{$_}) { # is this entry a subject?
+           error("Unknown topic $_ in .SA") unless exists $Subjects{$_};
            set_subject($_, $topic);
            $found = 1;
        }
@@ -205,8 +181,6 @@ sub parse_see_also {
        }
     }
 
-    $filename = $filename{$topic};
-    $. = $sanr{$topic};
     error("No subject listed in .SA") unless $found;
     error("Chapter $wanted not listed in .SA") if $wanted;
 }
@@ -224,10 +198,8 @@ sub set_subject {
 sub create_subj {
     my ($subj) = @_;
     my $fname = "info/$subj.t";
-    my ($any_basic, $any_obsolete, $any_long);
+    my ($any_topic, $any_basic, $any_obsolete, $any_long);
 
-    print "WARNING: $subj is a NEW subject\n"
-       unless grep(/^$subj$/, @Subjects);
     sysopen(SUBJ, $fname, O_WRONLY | O_EXCL | O_CREAT)
        or die "Unable to create $fname: $!\n";
 
@@ -239,6 +211,7 @@ sub create_subj {
        next unless exists $subject{$subj}{$chap};
        print SUBJ ".s1\n";
        for my $topic (split(/\n/, $subject{$subj}{$chap})) {
+           $any_topic = 1;
            my $flags = "";
            if ($level{$topic} eq 'Basic') {
                $flags .= "*";
@@ -257,6 +230,10 @@ sub create_subj {
            print SUBJ "$desc{$topic}\n";
        }
     }
+    unless ($any_topic) {
+       print STDERR "$0: Subject $subj has no topics\n";
+       exit 1;
+    }
     print SUBJ ".s1\n"
        . ".in 0\n"
        . "For info on a particular subject, type \"info <subject>\" where <subject> is\n"
@@ -274,21 +251,15 @@ sub create_subj {
 sub create_subjects {
     my (@subj);
 
-    for (@Subjects) {
+    for (keys %Subjects) {
        unlink "info/$_.t";
     }
 
     @subj = sort keys %subject;
 
-    for my $subj (@Subjects) {
-       print "WARNING: The subject $subj has been removed.\n"
-           unless grep (/^$subj$/, @subj);
-    }
-
     for my $subj (@subj) {
        create_subj($subj);
     }
-    return @subj;
 }
 
 # Print an integrity error message and exit with code 1
diff --git a/info/subjects.mk b/info/subjects.mk
new file mode 100644 (file)
index 0000000..bb7c0b0
--- /dev/null
@@ -0,0 +1,4 @@
+subjects := Combat Commerce Commodities Communication Deity Detection  \
+Diplomacy Distribution Introduction LandUnits Loans Maps Nations       \
+Nukes Occupation Planes Playing Populace Producing Sectors Server      \
+Ships Transportation Updates