Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Jun 2006 23:25:50 +0300
From:      Giorgos Keramidas <keramida@ceid.upatras.gr>
To:        Rich Morin <rdm@cfcl.com>
Cc:        freebsd-doc@freebsd.org
Subject:   Re: checking man page includes and prototypes?
Message-ID:  <20060622202550.GB2655@gothmog.pc>
In-Reply-To: <p062309d5c0b5e6114077@[192.168.254.205]>
References:  <p062309d5c0b5e6114077@[192.168.254.205]>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2006-06-14 09:15, Rich Morin <rdm@cfcl.com> wrote:
> I'm doing a lot of editing of section 2 and 3 man pages, concentrating
> on the includes and prototypes.  Although I'm trying to be careful,
> it's quite likely that some errors will slip past me.  So, I'm casting
> about for a way to do an automated sanity check.  Here's one idea:
>
>   For each man page
>     For each prototype
>       Construct a C test file.
>       Compile the test file.
>       Look for nastygrams, etc.
>
> For example, the sysconf(3) SYNOPSIS contains the lines:
>
>   #include <unistd.h>
>
>   long
>   sysconf(int name);
>
> I can turn this into the file test.c:
>
>   #include <unistd.h>
>
>   main() {
>
>     int name;
>     sysconf(name);
>   }
>
> Compiling this (e.g., "cc test.c") finishes silently.  So far, so
> good...
>
> Editing "sysconf" into "sysconfx" produces a promising nastygram:
>
>   /usr/bin/ld: Undefined symbols:
>   _sysconfx
>   collect2: ld returned 1 exit status
>
>
> However, editing "int name;" into "float name;' does NOT cause a
> nastygram.  So, it appears that prototype checking is not being done.
> The gcc(1) man page gave me the idea of trying
>
>   gcc -pedantic -ansi test.c
>
> but this didn't make any visible difference.  I see a bazillion other
> options, including a bunch of "-W..."  goodies, but I'd rather not try
> them all at random.  I tried "gcc -pedantic -ansi -Wstrict-prototypes
> test.c", but it only complained about my "main" statement (?):
>
>   test.c:3: warning: function declaration isn't a prototype
>
> Any suggestions (general or specific) on how I might be able to cajole
> gcc (or whatever) into helping me?

This is a _great_ idea!

If it's not too much trouble to generate a `Makefile' along with your
test source file, you can generate something like:

# giorgos@gothmog:/var/tmp/testimdR$ cat -n Makefile
#      1  PROG=           test-sysconf
#      2  NO_MAN=         No manpage generated for automated test.
#      3
#      4  WARNS?=         6
#      5
#      6  .include <bsd.prog.mk>
# giorgos@gothmog:/var/tmp/testimdR$ cat -n test-sysconf.c
#      1  #include <unistd.h>
#      2
#      3  int
#      4  main(void)
#      5  {
#      6          int name = 0;
#      7
#      8          sysconf(name);
#      9          return 0;
#     10  }
# giorgos@gothmog:/var/tmp/testimdR$

This will let you catch *some* of the potential bugs, by reusing the
makefile magic of the bsd.prog.mk suite, i.e.:

# giorgos@gothmog:/var/tmp/testimdR$ env CFLAGS='-O -pipe -ansi -pedantic' make clean
# rm -f test-sysconf test-sysconf.o
# giorgos@gothmog:/var/tmp/testimdR$ env CFLAGS='-O -pipe -ansi -pedantic' make
# Warning: Object directory not changed from original /var/tmp/testimdR
# cc -O -pipe -ansi -pedantic -g -Wsystem-headers -Werror -Wall \
#   -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes \
#   -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual \
#   -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wunused-parameter \
#   -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls \
#   -c test-sysconf.c
# cc -O -pipe -ansi -pedantic -g -Wsystem-headers -Werror -Wall \
#   -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes \
#   -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual \
#   -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wunused-parameter \
#   -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls  \
#   -o test-sysconf test-sysconf.o
# giorgos@gothmog:/var/tmp/testimdR$

Alas, this will not catch all type-errors too, because the compiler may
implicitly convert values.  For instance, it doesn't catch the bug of
passing a `double' argument to sysconf() here:

# giorgos@gothmog:/var/tmp/testimdR$ cat -n test-sysconf.c
#      1  #include <unistd.h>
#      2  
#      3  int
#      4  main(void)
#      5  {
#      6          double name = 123456789.0E10L;
#      7  
#      8          sysconf(name);
#      9          return 0;
#     10  }
# giorgos@gothmog:/var/tmp/testimdR$ env CFLAGS='-O -pipe -ansi -pedantic' make clean all
# rm -f test-sysconf test-sysconf.o
# Warning: Object directory not changed from original /var/tmp/testimdR
# cc -O -pipe -ansi -pedantic -g -Wsystem-headers -Werror -Wall \
#   -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes \
#   -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual \
#   -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wunused-parameter \
#   -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls \
#   -c test-sysconf.c
# cc -O -pipe -ansi -pedantic -g -Wsystem-headers -Werror -Wall \
#   -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes \
#   -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual \
#   -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wunused-parameter \
#   -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls  \
#   -o test-sysconf test-sysconf.o
# giorgos@gothmog:/var/tmp/testimdR$ 

The only good things about generating a temporary regression test in
`/var/tmp/testXXXX'-style directories, full with a minimal `Makefile'
and `test-foo.c' file are that:

    * You can take advantage of the `clean' and `cleandir' targets to
      rerun the test manually if it fails (as long as the test directory
      is left untouched for inspection).

    * You can take advantage of the existing `makefile magic' for
      compiler options, flags, warning levels, etc.

    * You can auto-generate the LDADD and DPADD parts of the Makefile
      from the LIBRARY section of the manpage and see if that one os
      correct too.

    * etc.

There are probably other good reasons why a Makefile-based approach is
good, but unfortunately it still doesn't catch all possible errors (as
you can see above).

Regards,
Giorgos




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060622202550.GB2655>