summaryrefslogtreecommitdiffstats
path: root/HACKING
diff options
context:
space:
mode:
Diffstat (limited to 'HACKING')
-rw-r--r--HACKING178
1 files changed, 178 insertions, 0 deletions
diff --git a/HACKING b/HACKING
new file mode 100644
index 0000000..6b6c449
--- /dev/null
+++ b/HACKING
@@ -0,0 +1,178 @@
+ Copyright 2022-2023 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without
+ modification, are permitted in any medium without royalty provided
+ the copyright notice and this notice are preserved.
+
+This file contains advice on developing and contributing to groff. It
+assumes that developers will install the 'git' revision control
+system and build groff using the instructions in 'INSTALL.repo'.
+Familiarize yourself with the structure of the source tree by studying
+its 'MANIFEST' file at the top level.
+
+Implementation languages
+------------------------
+
+Beyond what is said under "Dependencies" in 'INSTALL.extra',
+contributors should note that due to the age of the code base, much of
+the C++ dialect employed by groff components, while standard, is older
+than C++98--closer to Annotated Reference Manual C++ (Ellis, Stroustrup;
+Addison-Wesley, 1990). groff implements its own string class and the
+Standard Template Library is little used. A modest effort is underway
+to update the code to more idiomatic C++98. Where a C++11 feature
+promises to be advantageous, it may be annotated in a code comment.
+
+
+Automake
+--------
+
+A document explaining the basics of GNU Automake and its usage in groff
+is available in 'doc/automake.mom'; peruse a PDF rendering in
+'doc/automake.pdf' in your build tree.
+
+
+Testing
+-------
+
+Running the test suite with 'make check' after building any substantive
+change to groff logic is encouraged. You should certainly do so, and
+confirm that the tests pass, before submitting patches to the groff
+mailing list <groff@gnu.org> or Savannah issue tracker.
+
+If you find a defect in a test script, that can be reported via Savannah
+like any other bug.
+
+
+Documenting changes
+-------------------
+
+The groff project has a long history and a large, varied audience.
+Changes may need to be documented in up to three places depending on
+their impact.
+
+1. Changes should of course be documented in the Git commit message.
+ If a change alters only comments or formatting of source code, or
+ makes editorial changes to documentation, and does not resolve a
+ Savannah ticket, you can stop at that.
+
+2. The 'ChangeLog' file follows the format and practices documented in
+ the GNU Coding Standards.
+ https://www.gnu.org/prep/standards/html_node/Change-Logs.html
+
+ The sub-projects in the 'contrib' directory each have their own
+ dedicated ChangeLog files. The file specifications documented there
+ are relative to the sub-project, not the root of the groff source
+ tree. When converted to a commit message, add 'contrib/$SUBPROJECT'
+ to the entries.
+
+ Apart from 'contrib', groff uses a single (current) 'ChangeLog' file
+ for the rest of its source tree.
+
+ It is convenient to write the ChangeLog entry or entries first, then
+ construct a commit message from it (or them).
+
+3. The 'NEWS' file documents changes to groff that a user, not just a
+ developer, would notice, not including the resolution of defects.
+
+ As a hypothetical example, correcting a rendering error in tbl(1)
+ such that any table with more than 20 rows no longer had the text
+ "FOOBAR" spuriously added to some entries would not be a 'NEWS'
+ item, because the appearance of such text in the first place is a
+ surprising deviation from tbl's ideal and historical behavior. In
+ contrast, adding a command-line option to tbl, or changing the
+ meaning of its "expand" region option such that it no longer
+ horizontally compresses tables as well, _would_ be 'NEWS'-worthy.
+
+
+Writing Tests
+-------------
+
+Here are some portability notes on writing automated tests.
+
+* Write to the POSIX standard for the shell and utilities where
+ possible. Issue 4 from 1994 is old enough that no contemporary system
+ has a good reason for not conforming. A copy of the standard is
+ available at the Open Group's web site.
+ https://pubs.opengroup.org/onlinepubs/009656399/toc.pdf
+
+* The GNU coreutils "seq" command is handy but not standardized by
+ POSIX. Replace it with a while loop.
+
+ # emulate "seq 53"
+ n=1; while [ $n -le 53 ]; do echo $n; n=$(( n + 1 )); done; unset n
+
+* The "od" command on macOS can put extra space characters (i.e., spaces
+ that don't correspond to the input) at the ends of lines when using
+ the "od -t c" format; GNU od does not.
+
+ So a regex like this that works with GNU od:
+ grep -Eqx '0000000 +A +\\b +B +\\b +C D +\\n'
+ might need to be weakened to the following on macOS.
+ grep -Eqx '0000000 +A +\\b +B +\\b +C D +\\n *'
+
+* The "od" command on macOS does not respect the environment variable
+ assignment "LC_ALL=C" when processing byte values 127<x<256 decimal
+ and using the "character" output format (option "-t c"). An
+ alternative output must be used, like bytewise octal (option "-t o1").
+ (macOS od may be non-conforming here, despite the claim of its man
+ page. POSIX Issue 4 od's description says "The type specifier
+ character c specifies that bytes will be interpreted as characters
+ specified by the current setting of the LC_CTYPE locale category. ...
+ Other non-printable characters will be written as one three-digit
+ octal number for each byte in the character." (p. 538) The language
+ in Issue 7 (2018) appears unchanged.
+ https://pubs.opengroup.org/onlinepubs/9699919799/utilities/od.html )
+
+* macOS sed requires semicolons after commands even if they are followed
+ immediately by a closing brace.
+
+ Rewrite
+ sed -n '/Foo\./{n;s/^$/FAILURE/;p}'
+ as follows.
+ sed -n '/Foo\./{n;s/^$/FAILURE/;p;}'
+
+ But see below regarding the opening braces.
+
+* POSIX doesn't say that sed has to accept semicolons as command
+ separators after label (':') and branch ('t') commands, or after brace
+ commands, so macOS sed doesn't. GNU sed does.
+
+ So rewrite tidy, compact sed scripts like this:
+ sed -n '/Foo\./{n;s/^$/FAILURE/;tA;s/.*/SUCCESS/;:A;p}'
+ as this more cumbersome alternative.
+ sed -n \
+ -e '/Foo\./{n;s/^$/FAILURE/;tA;' \
+ -e 's/.*/SUCCESS/;:A;' \
+ -e 'p;}')
+
+ But see below regarding the opening braces.
+
+ Similarly, a brace sequence like that in this partial sed script:
+ /f1/p}}}}}}
+ must be rewritten as follows (or with '-e' expressions).
+ /f1/p;}
+ }
+ }
+ }
+ }
+ }
+
+* macOS and GNU sed don't require newlines (or '-e' expression endings)
+ after _opening_ braces, but Solaris 11 sed does.
+
+ So the sed script
+ /i/{N;/Table of Contents/{N;/Foo[. ][. ]*1/p;};}
+ must be rewritten as follows (or with '-e' expressions).
+ /i/{
+ N;/Table of Contents/{
+ N;/Foo[. ][. ]*1/p;
+ };
+ }
+
+
+##### Editor settings
+Local Variables:
+fill-column: 72
+mode: text
+End:
+vim: set autoindent textwidth=72: