foxygit / doom Log in
commit 3951c995ebb761de6bfc2f852c5a81eb51ba42f5
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Mon Feb 25 23:50:07 2008 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Mon Feb 25 23:50:07 2008 +0000

    Replace manpage header, footer, environment files with a single template
    file. Generate documentation for the default.cfg and chocolate-doom.cfg
    configuration files.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 1091
---
 Makefile.am                           |   2 +-
 man/.gitignore                        |   1 +
 man/CMDLINE.template                  |   8 ++
 man/Makefile.am                       |  16 ++-
 man/default.cfg.template              |  53 ++++++++
 man/docgen                            | 240 +++++++++++++++++++++++-----------
 man/extra.cfg.template                |  30 +++++
 man/footer                            |   8 --
 man/header                            |  12 --
 man/{environment => manpage.template} |  21 +++
 src/m_misc.c                          |   4 +
 11 files changed, 297 insertions(+), 98 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index aa980bdd..663873e5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,7 +49,7 @@ SUBDIRS=textscreen pcsound src man setup
 if HAVE_PYTHON

 CMDLINE : src/
-	./man/docgen -p src/ > $@
+	./man/docgen -p man/CMDLINE.template src/ > $@

 endif

diff --git a/man/.gitignore b/man/.gitignore
index dd9b296c..b7b7be5f 100644
--- a/man/.gitignore
+++ b/man/.gitignore
@@ -1,3 +1,4 @@
 Makefile.in
 Makefile
 *.6
+*.5
diff --git a/man/CMDLINE.template b/man/CMDLINE.template
new file mode 100644
index 00000000..fee4a3f9
--- /dev/null
+++ b/man/CMDLINE.template
@@ -0,0 +1,8 @@
+== Command line parameters ==
+
+This is a list of the command line parameters supported by Chocolate Doom.
+A number of additional parameters are supported in addition to those
+present in Vanilla Doom.
+
+@content
+
diff --git a/man/Makefile.am b/man/Makefile.am
index 9d38c92c..d3c90f7e 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,12 +1,22 @@

-MANPAGE_GEN_FILES=header footer environment docgen
+MANPAGE_GEN_FILES=manpage.template docgen default.cfg.template extra.cfg.template

 if HAVE_PYTHON

-man_MANS=chocolate-doom.6 chocolate-server.6 chocolate-setup.6
+man_MANS=chocolate-doom.6      \
+         chocolate-server.6    \
+	 chocolate-setup.6     \
+	 default.cfg.5         \
+	 $(PACKAGE).cfg.5

 chocolate-doom.6: ../src $(MANPAGE_GEN_FILES)
-	./docgen -m ../src > $@
+	./docgen -m manpage.template ../src > $@
+
+default.cfg.5: ../src default.cfg.template
+	./docgen -m default.cfg.template -c default.cfg ../src > $@
+
+$(PACKAGE).cfg.5: ../src extra.cfg.template
+	./docgen -m extra.cfg.template -c $(PACKAGE).cfg ../src > $@

 endif

diff --git a/man/default.cfg.template b/man/default.cfg.template
new file mode 100644
index 00000000..663103ec
--- /dev/null
+++ b/man/default.cfg.template
@@ -0,0 +1,53 @@
+.TH default.cfg 5
+.SH NAME
+default.cfg \- Chocolate Doom configuration file
+.SH DESCRIPTION
+.PP
+\fIdefault.cfg\fR
+is the configuration file for \fBchocolate-doom\fR(6).  The configuration
+options stored in the file are the same as those stored in the
+original DOS Vanilla Doom.
+Extra Chocolate Doom-specific options are stored in a separate
+configuration file, \fBchocolate-doom.cfg\fR.
+.PP
+\fIdefault.cfg\fR is normally stored in the user's home directory,
+in \fI~/.chocolate-doom/default.cfg\fR.
+.PP
+The \fBchocolate-setup\fR(6) tool provides a simple to use front-end
+for editing \fIdefault.cfg\fR.
+.br
+.SH FILE FORMAT
+The file is a plain-text file, consisting of a list of configuration
+options and their values, separated by whitespace.  Each option is stored
+on a separate line.  Options have different types; an option may have
+either an integer, floating point or string value.  If the option is
+of a string type, the value is surrounded by quotes (").
+.PP
+For example:
+.RS
+.PP
+integer_value                1
+.br
+integer_value2               1
+.br
+floating_point_value         4.2
+.br
+string_value                 "hello world"
+.RE
+.PP
+Invalid lines or comments in the file will be ignored, but it is advisable
+not to put them in the file; the file is rewritten from scratch every time
+the game exits, so any invalid lines or comments will be lost.
+.PP
+Some options are used for keyboard key bindings; these are stored as
+integer values containing the keyboard scan code of the key to be bound to.
+Boolean values are also stored as integers, with a value of zero usually
+indicating "false" and a non-zero value indicating "true".
+
+@content
+
+.SH SEE ALSO
+\fBchocolate-doom\fR(6),
+\fBchocolate-doom.cfg\fR(5),
+\fBchocolate-setup\fR(6)
+
diff --git a/man/docgen b/man/docgen
index 8870c60c..d59ff71f 100755
--- a/man/docgen
+++ b/man/docgen
@@ -1,7 +1,11 @@
 #!/usr/bin/env python
 #
-# Command line parameter self-documentation tool.  Reads comments from
-# the source code in the following form:
+# Chocolate Doom self-documentation tool.  This works similar to javadoc
+# or doxygen, but documents command line parameters and configuration
+# file values, generating documentation in Unix manpage, wikitext and
+# plain text forms.
+#
+# Comments are read from the source code in the following form:
 #
 #   //!
 #   // @arg <extra arguments>
@@ -13,37 +17,79 @@
 #
 #   something_involving = M_CheckParm("-param");
 #
-# From this, a manpage can be automatically generated of the command
-# line parameters.
+# For configuration file values:
+#
+#   //! @begin_config_file myconfig.cfg
+#
+#   //!
+#   // Description of the configuration file value.
+#   //
+#
+#   CONFIG_VARIABLE_INT(my_variable,       c_variable),
+#

 import sys
+import os
 import re
 import glob
 import getopt

-class Category:
-    def __init__(self, description):
-        self.description = description
-        self.params = []
+# Find the maximum width of a list of parameters (for plain text output)

-    def add_param(self, param):
-        self.params.append(param)
+def parameter_list_width(params):
+    w = 0

-    # Find the maximum width of a parameter in this category
+    for p in params:
+        pw = len(p.name) + 5

-    def paramtext_width(self):
-        w = 0
+        if p.args:
+            pw += len(p.args)

-        for p in self.params:
-            pw = len(p.name) + 5
+        if pw > w:
+            w = pw
+
+    return w
+
+class ConfigFile:
+    def __init__(self, filename):
+        self.filename = filename
+        self.variables = []
+
+    def add_variable(self, variable):
+        self.variables.append(variable)

-            if p.args:
-                pw += len(p.args)
+    def manpage_output(self):
+        result = ".SH CONFIGURATION VARIABLES\n"
+
+        self.variables.sort()
+
+        for v in self.variables:
+            result += ".TP\n"
+            result += v.manpage_output()
+
+        return result
+
+    def plaintext_output(self):
+        result = ""
+
+        self.variables.sort()

-            if pw > w:
-                w = pw
+        w = parameter_list_width(self.variables)
+
+        for p in self.variables:
+            result += p.plaintext_output(w)
+
+        result = result.rstrip() + "\n"
+
+        return result
+
+class Category:
+    def __init__(self, description):
+        self.description = description
+        self.params = []

-        return w
+    def add_param(self, param):
+        self.params.append(param)

     # Plain text output

@@ -52,7 +98,7 @@ class Category:

         self.params.sort()

-        w = self.paramtext_width()
+        w = parameter_list_width(self.params)

         for p in self.params:
             if p.should_show():
@@ -101,6 +147,7 @@ categories = {
 }

 wikipages = []
+config_files = {}

 # Show options that are in Vanilla Doom? Or only new options?

@@ -249,7 +296,29 @@ def add_wiki_links(text):

     return text

+def add_parameter(param, line, config_file):
+
+    # Is this documenting a command line parameter?
+
+    match = re.search('M_CheckParm\s*\(\s*"(.*?)"\s*\)', line)
+
+    if match:
+        param.name = match.group(1)
+        categories[param.category].add_param(param)
+        return
+
+    # Documenting a configuration file variable?
+
+    match = re.search('CONFIG_VARIABLE_\S+\s*\(\s*(\S+?),', line)
+
+    if match:
+        param.name = match.group(1)
+        config_file.add_variable(param)
+
 def process_file(file):
+
+    current_config_file = None
+
     f = open(file)

     try:
@@ -259,6 +328,11 @@ def process_file(file):
         for line in f:
             line = line.rstrip()

+            # Ignore empty lines
+
+            if re.match('\s*$', line):
+                continue
+
             # Currently reading a doc comment?

             if param:
@@ -267,20 +341,12 @@ def process_file(file):
                 if not re.match('\s*//', line):
                     waiting_for_checkparm = True

-                # Waiting for the M_CheckParm call that contains the
-                # name of the parameter we are documenting?
+                # The first non-empty line after the documentation comment
+                # ends must contain the thing being documented.

                 if waiting_for_checkparm:
-                    match = re.search('M_CheckParm\s*\(\s*"(.*?)"\s*\)', line)
-
-                    if match:
-                        # Found the name!  Finished documenting this
-                        # parameter.
-
-                        param.name = match.group(1)
-                        categories[param.category].add_param(param)
-                        param = None
-
+                    add_parameter(param, line, current_config_file)
+                    param = None
                 else:
                     # More documentation text

@@ -291,72 +357,72 @@ def process_file(file):
             # Check for start of a doc comment

             if re.search("//!", line):
-                param = Parameter()
-                waiting_for_checkparm = False
+                match = re.search("@begin_config_file\s*(\S+)", line)
+
+                if match:
+                    # Beginning a configuration file
+                    filename = match.group(1)
+                    current_config_file = ConfigFile(filename)
+                    config_files[filename] = current_config_file
+                else:
+                    # Start of a normal comment
+                    param = Parameter()
+                    waiting_for_checkparm = False
     finally:
         f.close()

 def process_files(dir):
     # Process all C source files.

-    files = glob.glob(dir + "/*.c")
+    if os.path.isdir(dir):
+        files = glob.glob(dir + "/*.c")

-    for file in files:
-        process_file(file)
+        for file in files:
+            process_file(file)
+    else:
+        # Special case to allow a single file to be specified as a target

-def print_file_contents(file):
-    f = open(file)
+        process_file(dir)
+
+def print_template(template_file, content):
+    f = open(template_file)

     try:
         for line in f:
+            line = line.replace("@content", content)
             print line.rstrip()

     finally:
         f.close()

-def manpage_output(dir):
+def manpage_output(targets, template_file):
+
+    content = ""

-    process_files(dir)
+    for t in targets:
+        content += t.manpage_output() + "\n"

-    print_file_contents("header")
+    print_template(template_file, content)

-    print categories[None].manpage_output()
-
-    for c in categories:
-        if c != None:
-            print categories[c].manpage_output()
-
-    print_file_contents("environment")
-    print_file_contents("footer")
-
-def wiki_output(dir):
+def wiki_output(targets, template):
     read_wikipages()
-    process_files(dir)
-
-    print categories[None].wiki_output()

-    for c in categories:
-        if c != None:
-            print categories[c].wiki_output()
+    for t in targets:
+        print t.wiki_output()

-def plaintext_output(dir):
-    process_files(dir)
+def plaintext_output(targets, template_file):

-    print "== Command line parameters =="
-    print
-    print "This is a list of the command line parameters supported by "
-    print "Chocolate Doom.  A number of additional parameters are supported "
-    print "in addition to those present in Vanilla Doom. "
-    print
+    content = ""

-    print categories[None].plaintext_output()
+    for t in targets:
+        content += t.plaintext_output() + "\n"

-    for c in categories:
-        if c != None:
-            print categories[c].plaintext_output()
+    print_template(template_file, content)

 def usage():
-    print "Usage: %s [-V] ( -m | -w | -p ) <directory>" % sys.argv[0]
+    print "Usage: %s [-V] [-c filename ]( -m | -w | -p ) <directory>" \
+            % sys.argv[0]
+    print "   -c :  Provide documentation for the specified configuration file"
     print "   -m :  Manpage output"
     print "   -w :  Wikitext output"
     print "   -p :  Plaintext output"
@@ -365,22 +431,48 @@ def usage():

 # Parse command line

-opts, args = getopt.getopt(sys.argv[1:], "mwpV")
+opts, args = getopt.getopt(sys.argv[1:], "m:wp:c:V")

 output_function = None
+template = None
+doc_config_file = None

 for opt in opts:
     if opt[0] == "-m":
         output_function = manpage_output
+        template = opt[1]
     elif opt[0] == "-w":
         output_function = wiki_output
     elif opt[0] == "-p":
         output_function = plaintext_output
+        template = opt[1]
     elif opt[0] == "-V":
         show_vanilla_options = False
+    elif opt[0] == "-c":
+        doc_config_file = opt[1]

 if output_function == None or len(args) != 1:
     usage()
 else:
-    output_function(args[0])
+
+    # Process specified files
+
+    process_files(args[0])
+
+    # Build a list of things to document
+
+    documentation_targets = []
+
+    if doc_config_file:
+        documentation_targets.append(config_files[doc_config_file])
+    else:
+        documentation_targets.append(categories[None])
+
+        for c in categories:
+            if c != None:
+                documentation_targets.append(categories[c])
+
+    # Generate the output
+
+    output_function(documentation_targets, template)

diff --git a/man/extra.cfg.template b/man/extra.cfg.template
new file mode 100644
index 00000000..2e0f9301
--- /dev/null
+++ b/man/extra.cfg.template
@@ -0,0 +1,30 @@
+.TH chocolate-doom.cfg 5
+.SH NAME
+chocolate-doom.cfg \- Chocolate Doom configuration file
+.SH DESCRIPTION
+.PP
+\fIchocolate-doom.cfg\fR
+is a configuration file for \fBchocolate-doom\fR(6).  This file acts
+as an auxiliary configuration file; the main configuration options
+are stored in \fBdefault.cfg\fR, which contains the same configuration
+options as Vanilla Doom (for compatibility).  \fIchocolate-doom.cfg\fR
+contains configuration options that are specific to Chocolate Doom
+only.
+.PP
+\fIchocolate-doom.cfg\fR is normally stored in the user's home directory,
+as \fI~/.chocolate-doom/chocolate-doom.cfg\fR.
+.PP
+The \fBchocolate-setup\fR(6) tool provides a simple to use front-end
+for editing \fIchocolate-doom.cfg\fR.
+.SH FILE FORMAT
+.PP
+The file format is the same as that used for \fBdefault.cfg\fR(5).
+.br
+
+@content
+
+.SH SEE ALSO
+\fBchocolate-doom\fR(6),
+\fBdefault.cfg\fR(5),
+\fBchocolate-setup\fR(6)
+
diff --git a/man/footer b/man/footer
deleted file mode 100644
index 9bb3b8b4..00000000
--- a/man/footer
+++ /dev/null
@@ -1,8 +0,0 @@
-.\" this section from foot
-.SH AUTHOR
-Chocolate Doom is written and maintained by Simon Howard.  It is based on
-the LinuxDoom source code, released by Id Software.
-.SH COPYRIGHT
-Copyright \(co id Software Inc.
-Copyright \(co 2005-8 Simon Howard.
-
diff --git a/man/header b/man/header
deleted file mode 100644
index 8917506b..00000000
--- a/man/header
+++ /dev/null
@@ -1,12 +0,0 @@
-.\" this section from head
-.TH chocolate\-doom 6
-.SH NAME
-chocolate\-doom \- historically compatible doom engine
-.SH SYNOPSIS
-.B chocolate\-doom
-[\fIOPTIONS\fR]
-.SH DESCRIPTION
-.PP
-Chocolate Doom is a modern doom engine designed to behave
-as similar to the original doom game as is possible.
-.br
diff --git a/man/environment b/man/manpage.template
similarity index 61%
rename from man/environment
rename to man/manpage.template
index 47e3d8ed..e2df2b57 100644
--- a/man/environment
+++ b/man/manpage.template
@@ -1,3 +1,17 @@
+.TH chocolate\-doom 6
+.SH NAME
+chocolate\-doom \- historically compatible doom engine
+.SH SYNOPSIS
+.B chocolate\-doom
+[\fIOPTIONS\fR]
+.SH DESCRIPTION
+.PP
+Chocolate Doom is a modern doom engine designed to behave
+as similar to the original doom game as is possible.
+.br
+
+@content
+
 .SH ENVIRONMENT
 This section describes environment variables that control Chocolate Doom's
 behavior.
@@ -15,3 +29,10 @@ options are "Linux" for the Linux console mode driver, "BSD" for the
 NetBSD/OpenBSD PC speaker driver, and "SDL" for SDL-based emulated PC speaker
 playback (using the digital output).

+.SH AUTHOR
+Chocolate Doom is written and maintained by Simon Howard.  It is based on
+the LinuxDoom source code, released by Id Software.
+.SH COPYRIGHT
+Copyright \(co id Software Inc.
+Copyright \(co 2005-8 Simon Howard.
+
diff --git a/src/m_misc.c b/src/m_misc.c
index 6f9c9644..67db6abf 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -359,6 +359,8 @@ typedef struct
 #define CONFIG_VARIABLE_STRING(name, variable) \
     { #name, &variable, DEFAULT_STRING, 0, 0 }

+//! @begin_config_file default.cfg
+
 static default_t	doom_defaults_list[] =
 {
     //!
@@ -650,6 +652,8 @@ static default_collection_t doom_defaults =
     NULL,
 };

+//! @begin_config_file chocolate-doom.cfg
+
 static default_t extra_defaults_list[] =
 {
     //!