Thread View: alt.sources.patches
1 messages
1 total messages
Started by Graham Stoney
Tue, 25 Aug 1992 07:16
c2man: generate man pages from C comments; patch v1.4 -> v1.5
Author: Graham Stoney
Date: Tue, 25 Aug 1992 07:16
Date: Tue, 25 Aug 1992 07:16
1708 lines
44062 bytes
44062 bytes
Archive-name: c2man/patch.1.4-1.5
Submitted-by: greyham@research.canon.oz.au
This official patch brings c2man v1.4 up to v1.5.
You should remove the file:
ctype.terse
After applying this patch.
This patch fixes a few bugs, and adds a -g option which groups functions from
the same file together in the one manual page like -G, but reads the terse
description for the NAME section from the file(s) rather than the command line.
See the CHANGES file for more details.
As before, any feedback, comments or tips are greatly appreciated.
Graham
*** 1.6 1992/08/17 06:18:38
--- CHANGES 1992/08/25 07:05:04
***************
*** 60,62 ****
--- 60,76 ----
Output function prototype on a single line for all functions with one
or less parameters (ignoring -f...).
+
+ Version 1.5:
+ Recognise end-of-line comments after K&R style function parameters.
+
+ Specify C-preprocessor command in Makefile and add -P option to specify
+ a different preprocessor at runtime.
+
+ Add -g option like -G, but read the terse description from the file.
+
+ Don't disable nroff line filling in SYNOPSIS section so very long lines
+ still get broken.
+
+ Require a white-space after a period before capitalising the next
+ letter. i.e. Don't damage "i.e.".
*** 1.1 1992/08/12 00:36:22
--- INSTALL 1992/08/25 07:05:04
***************
*** 16,23 ****
If using gcc on a Sun, you may need GNU libc to get stdarg.h
! 2. Look at the Makefile, and check that CC, DEFINES, WARN, LIBS and BSD are
! set if necessary. Optionally, set LEX and YACC too.
3. Type "make"
--- 16,25 ----
If using gcc on a Sun, you may need GNU libc to get stdarg.h
! 2. Look at the Makefile, and check that CPP, CC, DEFINES, WARN, LIBS and BSD
! are set if necessary. Optionally, set LEX and YACC too.
!
! Don't set CPP to use Sun's acc -E, or c2man will ignore your header files.
3. Type "make"
*** 1.8 1992/08/17 06:21:01
--- Makefile 1992/08/25 07:05:05
***************
*** 1,25 ****
! # $Id: Makefile,v 1.8 1992/08/17 06:21:01 greyham Exp $
#
# UNIX makefile for manual page generator
#
! # Choose one of the pre-packaged configurations here, or customize your own
! # down below. To pick one here, uncomment only ONE of these sets of lines.
! # NeXT:
! DEFINES=-O
WARN=-Wall
# Sun with gcc:
#CC=gcc
- #DEFINES=-O
#WARN=
# Sun with acc:
#CC=/usr/local/lang/acc
- #DEFINES=-O
#WARN=
#BSD=-DBSD
# HPUX:
#DEFINES= -Aa -D_INCLUDE_POSIX_SOURCE -D_INCLUDE_XOPEN_SOURCE \
--- 1,53 ----
! # $Id: Makefile,v 1.11 1992/08/25 07:04:48 greyham Exp $
#
# UNIX makefile for manual page generator
#
! #--- Configuration settings. Pre-packaged configurations exist below these;
! #--- check to see if one of them applies to you before customising these.
! # How should c2man run the C-preprocessor?
! CPP=/lib/cpp
! #CPP=/usr/local/bin/gcc -E
! #CPP=$(CC) -E
!
! # Pick the ANSI-C compiler to build c2man with.
! #CC=gcc
!
! # Define BSD if your library doesn't have ANSI string functions.
! #BSD = -DBSD
!
! # Pick what extra warnings you'd like.
WARN=-Wall
+ # Pick whatever other compiler defines are needed.
+ DEFINES=-O
+ # -g
+ # -DYYDEBUG
+ # -DDEBUG
+
+ # Pick if you want yacc or bison. (use the first one)
+ #YACC = bison -y
+ #YACC = bison -y -v -t
+
+ # Want to use flex?
+ #LEX=flex
+
+ #--- Choose one of the pre-packaged configurations here, or customize your own
+ #--- up above. To pick one here, uncomment only ONE of these sets of lines.
+
+ # NeXT:
+ # [The default configuration is actually for a NeXT; just run make]
+
# Sun with gcc:
#CC=gcc
#WARN=
# Sun with acc:
#CC=/usr/local/lang/acc
#WARN=
#BSD=-DBSD
+ #CPP=gcc -E
# HPUX:
#DEFINES= -Aa -D_INCLUDE_POSIX_SOURCE -D_INCLUDE_XOPEN_SOURCE \
***************
*** 29,59 ****
# Interactive UNIX with gcc:
#CC=gcc -nostdinc -I/usr/include
#DEFINES=-O -D_POSIX_SOURCE
- #WARN=-Wall
#LIBS=-lcposix
! # End of pre-packaged configurations.
!
! # Pick the ANSI-C compiler you use.
! #CC=gcc
!
! # Define BSD if your library doesn't have ANSI string functions.
! #BSD = -DBSD
!
! # Pick what extra warnings you'd like.
! #WARN=-Wall
!
! # Pick whatever other compiler defines are needed.
! #DEFINES=-g
! # -DYYDEBUG
! # -DDEBUG
!
! # Pick if you want yacc or bison. (use the first one)
! #YACC = bison -y
! #YACC = bison -y -v -t
- # Want to use flex?
- #LEX=flex
# For MallocDebug on the NeXT:
#LIBS=-lMallocDebug -lsys_s
--- 57,66 ----
# Interactive UNIX with gcc:
#CC=gcc -nostdinc -I/usr/include
#DEFINES=-O -D_POSIX_SOURCE
#LIBS=-lcposix
! #--- End of pre-packaged configurations.
# For MallocDebug on the NeXT:
#LIBS=-lMallocDebug -lsys_s
***************
*** 60,66 ****
#DEFINES=-g -DMALLOC_DEBUG
DIST1 = README CHANGES INSTALL c2man.1 Makefile example.h \
! flatten.sed ctype.h ctype.terse $(OSOURCES)
DIST2 = $(DCSOURCES)
OSOURCES = lex.l grammar.y \
config.h c2man.h semantic.h symbol.h strconcat.h \
--- 67,73 ----
#DEFINES=-g -DMALLOC_DEBUG
DIST1 = README CHANGES INSTALL c2man.1 Makefile example.h \
! flatten.sed ctype.h $(OSOURCES)
DIST2 = $(DCSOURCES)
OSOURCES = lex.l grammar.y \
config.h c2man.h semantic.h symbol.h strconcat.h \
***************
*** 91,97 ****
$(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LIBS)
y.tab.c: grammar.y
! @echo Expect 29 shift/reduce conflicts.
$(YACC) grammar.y
# don't compile y.tab.c with all warnings; yacc/bison are not up to it.
--- 98,104 ----
$(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LIBS)
y.tab.c: grammar.y
! @echo Expect 33 shift/reduce conflicts.
$(YACC) grammar.y
# don't compile y.tab.c with all warnings; yacc/bison are not up to it.
***************
*** 101,106 ****
--- 108,116 ----
lex.yy.c: lex.l
$(LEX) lex.l
+ c2man.o: c2man.c
+ $(CC) $(CFLAGS) -DCPP="\"$(CPP)\"" -c c2man.c
+
c2man.man: c2man.1 example.inc ctype.inc
nroff -man c2man.1 >$@
***************
*** 109,116 ****
(echo ".ll -1i"; cat dowork.3) | nroff -man | cat -s | \
sed -e '2s/ / /g' > example.inc
! ctype.inc: c2man ctype.h ctype.terse
! ./c2man -o- -G"`cat ctype.terse`" ctype.h > ctype.out
(echo ".ll -1i"; cat ctype.out) | nroff -man | cat -s | \
sed -e '2s/ / /g' > ctype.inc
--- 119,126 ----
(echo ".ll -1i"; cat dowork.3) | nroff -man | cat -s | \
sed -e '2s/ / /g' > example.inc
! ctype.inc: c2man ctype.h
! ./c2man -o- -g ctype.h > ctype.out
(echo ".ll -1i"; cat ctype.out) | nroff -man | cat -s | \
sed -e '2s/ / /g' > ctype.inc
*** 1.5 1992/08/12 00:35:35
--- README 1992/08/25 07:05:04
***************
*** 1,4 ****
! This is c2man (Version 1.4), a program for generating Unix style manual pages
in nroff/troff -man format directly from ordinary comments embedded in C source
code. It owes a huge debt to the public domain program cproto, by Chin Huang,
from which much of the code is derived.
--- 1,4 ----
! This is c2man (Version 1.5), a program for generating Unix style manual pages
in nroff/troff -man format directly from ordinary comments embedded in C source
code. It owes a huge debt to the public domain program cproto, by Chin Huang,
from which much of the code is derived.
*** 1.8 1992/08/17 06:44:52
--- c2man.1 1992/08/25 07:05:04
***************
*** 1,4 ****
! .\" $Id: c2man.1,v 1.8 1992/08/17 06:44:52 greyham Exp $
.de EX \"Begin example
.ne 5
.if n .sp 1
--- 1,4 ----
! .\" $Id: c2man.1,v 1.9 1992/08/25 06:41:02 greyham Exp $
.de EX \"Begin example
.ne 5
.if n .sp 1
***************
*** 89,97 ****
.LP
The manual page starts with a
.B NAME
! section, containing the terse description on the first line or sentence of the
comment
! immediately before the declaration/definition.
.LP
The
.B SYNOPSIS
--- 89,106 ----
.LP
The manual page starts with a
.B NAME
! section, listing the name(s) of the identifier(s) documented, along with a
! terse description.
! By default, this description is the first line or sentence of the
comment
! immediately before the declaration/definition of the identifier.
! With the
! .B \-g
! option, it is found after the first
! .B \-
! in the first comment of the file, and the
! .B \-G
! option specifies it explicitly.
.LP
The
.B SYNOPSIS
***************
*** 101,107 ****
line
if the source file is a header.
After this is an external declaration for the
! identifier being documented.
.LP
Information in the
.B PARAMETERS
--- 110,116 ----
line
if the source file is a header.
After this is an external declaration for the
! identifier(s) being documented.
.LP
Information in the
.B PARAMETERS
***************
*** 111,118 ****
thing on the line.
.LP
If the manual page is for a group of functions (ie:
.B \-G
! option),
identical parameters (in both name and type) common to more than one function
are described only once if only one has a comment (as in the ctype
example below).
--- 120,129 ----
thing on the line.
.LP
If the manual page is for a group of functions (ie:
+ .B \-g
+ or
.B \-G
! options),
identical parameters (in both name and type) common to more than one function
are described only once if only one has a comment (as in the ctype
example below).
***************
*** 255,276 ****
.LP
That may all sound a bit complex, but the upshot is that
.B c2man
! will usually know which object a comment is associated with, unless you do
something truly bizarre.
.LP
Simple, closely related objects can be grouped together onto a single page with the
.B \-G
! option; for example, if ctype.h contains:
.IF
.so ctype.h
.IE
.LP
then using:
! .CS
! c2man -G"\c
! .so ctype.terse
! " ctype.h
! .CE
yields:
.IF
.so ctype.inc
--- 266,285 ----
.LP
That may all sound a bit complex, but the upshot is that
.B c2man
! will usually know which identifier a comment is associated with, unless you do
something truly bizarre.
.LP
Simple, closely related objects can be grouped together onto a single page with the
+ .B \-g
+ or
.B \-G
! options; for example, if ctype.h contains:
.IF
.so ctype.h
.IE
.LP
then using:
! .CD c2man -g ctype.h
yields:
.IF
.so ctype.inc
***************
*** 333,348 ****
.B inline
functions).
.TP
! .BI \-M name
! Set the name of the manual in which the page will go.
! .TP
! .BI \-G terse
Group all info generated from the same file together into a single
! page (ala ctype(3)) with the specified terse description in the
.B NAME
! section. A link to
! the output file is made for each object documented.
.TP
.BI \-i dirprefix
Use
.B dirprefix
--- 342,360 ----
.B inline
functions).
.TP
! .B \-g
Group all info generated from the same file together into a single
! page (ala ctype(3)), reading the terse description for the
.B NAME
! section from the first comment in the file. A link to
! the output file is made for each identifier documented.
.TP
+ .BI \-G terse
+ Like
+ .BR \-g ,
+ but using the specified terse description rather than reading it from the
+ file.
+ .TP
.BI \-i dirprefix
Use
.B dirprefix
***************
*** 352,357 ****
--- 364,372 ----
.B SYNOPSIS
section.
.TP
+ .BI \-M name
+ Set the name of the manual in which the page will go.
+ .TP
.BI \-F string
Set the format used to output the prototype for functions with more than 1
parameter
***************
*** 382,387 ****
--- 397,411 ----
);
.EE
.TP
+ .BI \-P preprocessor
+ Run a different C preprocessor to normal (use
+ .B \-V
+ to determine the configured default).
+ For example, to use
+ .BR gcc 's
+ cpp instead:
+ .CD c2man -P \{"gcc -E"\}
+ .TP
.BI \-D name\[=value\]
This option is passed through to the preprocessor and is used to define
symbols for use with conditionals such as
***************
*** 445,451 ****
.EE
.LP
A comment before a preprocessor directive will be considered to apply
! to the object that immediately follows, if it has no
comment of its own.
This is because the preprocessor directive gets removed by cpp before
c2man looks at it.
--- 469,475 ----
.EE
.LP
A comment before a preprocessor directive will be considered to apply
! to the identifier that immediately follows, if it has no
comment of its own.
This is because the preprocessor directive gets removed by cpp before
c2man looks at it.
***************
*** 452,457 ****
--- 476,486 ----
.LP
Comments aren't legal in some of the more obscure places that they
would be in 'C'.
+ .LP
+ Some cpp's (Sun's acc -E is one example) won't process .h files passed on
+ the command line; so they shouldn't be used with
+ .B c2man
+ since it will appear to ignore them entirely.
.LP
Comment placement (particularly with respect to comma positioning) is more
the result of the author's personal style than of any defined logic.
*** 1.4 1992/08/17 06:18:38
--- c2man.c 1992/08/25 07:05:08
***************
*** 1,10 ****
! /* $Id: c2man.c,v 1.4 1992/08/17 06:18:38 greyham Exp $
*
* C Manual page.
* Reads C source code and outputs manual pages.
*/
#ifndef lint
! static char *rcsid = "$Id: c2man.c,v 1.4 1992/08/17 06:18:38 greyham Exp $";
#endif
#include <stdio.h>
#include <ctype.h>
--- 1,10 ----
! /* $Id: c2man.c,v 1.5 1992/08/25 06:41:02 greyham Exp $
*
* C Manual page.
* Reads C source code and outputs manual pages.
*/
#ifndef lint
! static char *rcsid = "$Id: c2man.c,v 1.5 1992/08/25 06:41:02 greyham Exp $";
#endif
#include <stdio.h>
#include <ctype.h>
***************
*** 11,25 ****
#include "c2man.h"
#include "strconcat.h"
- /* C preprocessor */
- #ifndef CPP
- #define CPP "/lib/cpp -C"
- #endif
-
- #ifdef MSDOS
- #define NO_CPP /* don't run CPP */
- #endif
-
/* getopt declarations */
extern int getopt();
extern char *optarg;
--- 11,16 ----
***************
*** 69,75 ****
/* prefix for generated #include lines */
char *include_prefix = NULL;
! /* do we group related stuff into one file? if so, its terse description? */
char *group_terse = NULL;
/* Include file directories */
--- 60,72 ----
/* prefix for generated #include lines */
char *include_prefix = NULL;
! /* do we group related stuff into one file? */
! boolean group_together;
!
! /* was terse description read from file or command line option? */
! boolean terse_specified;
!
! /* terse description when grouped together */
char *group_terse = NULL;
/* Include file directories */
***************
*** 84,91 ****
/* total number of errors encountered */
int errors;
! #ifndef NO_CPP
! char *cpp_cmd;
#endif
boolean verbose = FALSE;
--- 81,89 ----
/* total number of errors encountered */
int errors;
! #ifdef CPP
! char *cpp_cmd = CPP;
! char *cpp_opts;
#endif
boolean verbose = FALSE;
***************
*** 164,183 ****
int process_file(char *name)
{
! #ifndef NO_CPP
! char *cmd;
#endif
strcpy(cur_file, name ? name : "stdin");
! #ifdef NO_CPP
! if (verbose) fprintf(stderr,"reading %s\n", cur_file);
!
! if (name && freopen(name, "r", yyin) == NULL)
{
! fprintf(stderr, "%s: cannot open file %s\n", progname, argv[i]);
! return 0;
}
- #else
- cmd = name ? strconcat(cpp_cmd, " ", name, NULL) : cpp_cmd;
if (verbose) fprintf(stderr,"%s\n", cmd);
--- 162,178 ----
int process_file(char *name)
{
! #ifdef CPP
! char *cmd = strconcat(cpp_cmd, " ", cpp_opts, NULL);
#endif
strcpy(cur_file, name ? name : "stdin");
! #ifdef CPP
! if (name)
{
! char *new_cmd = strconcat(cmd, " ", name, NULL);
! free(cmd);
! cmd = new_cmd;
}
if (verbose) fprintf(stderr,"%s\n", cmd);
***************
*** 185,198 ****
fprintf(stderr, "%s: error running %s\n", progname, cmd);
return 0;
}
#endif
parse_file();
! #ifdef NO_CPP
! fclose(yyin);
! #else
pclose(yyin);
! if (name) free(cmd);
#endif
return !errors;
}
--- 180,201 ----
fprintf(stderr, "%s: error running %s\n", progname, cmd);
return 0;
}
+ #else
+ if (verbose) fprintf(stderr,"reading %s\n", cur_file);
+
+ if (name && freopen(name, "r", yyin) == NULL)
+ {
+ fprintf(stderr, "%s: cannot open file %s\n", progname, argv[i]);
+ return 0;
+ }
#endif
parse_file();
! #ifdef CPP
pclose(yyin);
! free(cmd);
! #else
! fclose(yyin);
#endif
return !errors;
}
***************
*** 203,228 ****
char **argv;
{
int i, c;
! char *s, *new_cmd, cbuf[2];
#ifdef YYDEBUG
extern int yydebug;
#endif
! /* Allocate buffer for C preprocessor command line. */
! cpp_cmd = strconcat(CPP, NULL);
!
/* Scan command line options. */
! while ((c = getopt(argc, argv, "D:F:I:psU:Vvo:M:i:G:")) != EOF) {
switch (c) {
case 'I':
case 'D':
case 'U':
cbuf[0] = c; cbuf[1] = '\0';
! new_cmd = strconcat(cpp_cmd," -",cbuf,optarg,NULL);
! free(cpp_cmd);
! cpp_cmd = new_cmd;
break;
case 'G':
group_terse = optarg;
break;
case 'F':
s = escape_string(optarg);
--- 206,239 ----
char **argv;
{
int i, c;
! char *s, *new_opts, cbuf[2];
#ifdef YYDEBUG
extern int yydebug;
#endif
! #ifdef CPP
! /* Allocate buffer for C preprocessor command line options. */
! cpp_opts = strconcat("-C", NULL);
! #endif
/* Scan command line options. */
! while ((c = getopt(argc, argv, "D:F:I:psU:Vvo:M:i:G:g")) != EOF) {
switch (c) {
case 'I':
case 'D':
case 'U':
cbuf[0] = c; cbuf[1] = '\0';
! new_opts = strconcat(cpp_opts," -",cbuf,optarg,NULL);
! free(cpp_opts);
! cpp_opts = new_opts;
! break;
! case 'P':
! cpp_cmd = optarg;
break;
case 'G':
group_terse = optarg;
+ terse_specified = TRUE;
+ /* FALLTHROUGH */
+ case 'g':
+ group_together = TRUE;
break;
case 'F':
s = escape_string(optarg);
*** 1.3 1992/08/17 06:18:38
--- c2man.h 1992/08/25 07:05:06
***************
*** 1,4 ****
! /* $Id: c2man.h,v 1.3 1992/08/17 06:18:38 greyham Exp $
*
* Definitions for C language manual page generator
*/
--- 1,4 ----
! /* $Id: c2man.h,v 1.4 1992/08/25 06:41:02 greyham Exp $
*
* Definitions for C language manual page generator
*/
***************
*** 102,108 ****
--- 102,112 ----
extern char *manual_name;
extern char *progname;
extern char *include_prefix;
+
extern char *group_terse;
+ extern boolean group_together;
+ extern boolean terse_specified;
+
extern char *output_dir;
/* Global declarations */
*** 1.1 1992/08/17 06:18:38
--- ctype.h 1992/08/25 07:05:05
***************
*** 1,3 ****
--- 1,5 ----
+ /* ctype.h - character classification functions */
+
/* character is alphanumeric
* returns 0 if the character doesn't fit the
* classification; non-zero (but not necessarily 1)
*** 1.1 1992/07/07 09:24:32
--- enum.c 1992/08/25 07:05:10
***************
*** 1,4 ****
! /* $Id: enum.c,v 1.1 1992/07/07 09:24:32 greyham Exp $
* enumerator operations
*/
#include "c2man.h"
--- 1,4 ----
! /* $Id: enum.c,v 1.2 1992/08/25 06:41:02 greyham Exp $
* enumerator operations
*/
#include "c2man.h"
***************
*** 71,78 ****
new_enumerator(Enumerator *e, char *name,
char *comment_before, char *comment_after)
{
e-> name = name;
! e-> comment = join_comments(comment_before, comment_after);
}
/* Free the storage used by the enumerator.*/
--- 71,86 ----
new_enumerator(Enumerator *e, char *name,
char *comment_before, char *comment_after)
{
+ if (comment_before && comment_after)
+ {
+ enumerator_error(name);
+ free(comment_before);
+ free(comment_after);
+ return;
+ }
+
e-> name = name;
! e-> comment = comment_before ? comment_before : comment_after;
}
/* Free the storage used by the enumerator.*/
*** 1.3 1992/08/17 06:44:52
--- flatten.sed 1992/08/25 07:05:05
***************
*** 17,24 ****
r ctype.inc
d
}
-
- /^.so *ctype.terse$/{
- r ctype.terse
- d
- }
--- 17,19 ----
*** 1.3 1992/08/12 00:35:35
--- grammar.y 1992/08/25 07:05:06
***************
*** 1,4 ****
! /* $Id: grammar.y,v 1.3 1992/08/12 00:35:35 greyham Exp $
*
* yacc grammar for C prototype generator
* This was derived from the grammar given in Appendix A of
--- 1,4 ----
! /* $Id: grammar.y,v 1.4 1992/08/25 06:41:02 greyham Exp $
*
* yacc grammar for C prototype generator
* This was derived from the grammar given in Appendix A of
***************
*** 88,95 ****
/* Table of typedef names */
SymbolTable *typedef_names;
! char *basefile; /* the name of the base file we are parsing */
! int inbasefile; /* are we parsing in that base file? */
%}
%%
--- 88,96 ----
/* Table of typedef names */
SymbolTable *typedef_names;
! char *basefile; /* the name of the base file we are parsing */
! boolean inbasefile; /* are we parsing in that base file? */
! boolean first_comment; /* are we still looking for the first comment? */
%}
%%
***************
*** 127,134 ****
}
cur_params = &($3.params);
func_params = TRUE;
! if ($4 && !comment_last_parameter(&$3.params, $4))
! YYERROR;
}
opt_declaration_list T_BRACES
{
--- 128,134 ----
}
cur_params = &($3.params);
func_params = TRUE;
! if ($4) comment_last_parameter(&$3.params, $4);
}
opt_declaration_list T_BRACES
{
***************
*** 143,150 ****
}
cur_params = &($2.params);
func_params = TRUE;
! if ($3 && !comment_last_parameter(&$2.params, $3))
! YYERROR;
}
opt_declaration_list T_BRACES
{
--- 143,149 ----
}
cur_params = &($2.params);
func_params = TRUE;
! if ($3) comment_last_parameter(&$2.params, $3);
}
opt_declaration_list T_BRACES
{
***************
*** 167,173 ****
opt_eolcomment
{
if (func_params) {
! set_param_types(cur_params, &$2, &$3, $1);
free($1);
free_decl_spec(&$2);
free_decl_list(&$3);
--- 166,172 ----
opt_eolcomment
{
if (func_params) {
! set_param_types(cur_params, &$2, &$3, $1, $5);
free($1);
free_decl_spec(&$2);
free_decl_list(&$3);
***************
*** 174,181 ****
free($5);
} else {
/* either frees or needs to retain the decl stuff */
! if (!remember_declarations($1, &$2, &$3, $5))
! YYERROR;
}
}
| opt_comment T_TYPEDEF declaration_specifiers declarator_list ';'
--- 173,179 ----
free($5);
} else {
/* either frees or needs to retain the decl stuff */
! remember_declarations($1, &$2, &$3, $5);
}
}
| opt_comment T_TYPEDEF declaration_specifiers declarator_list ';'
***************
*** 196,210 ****
}
| declarator_list ',' opt_eolcomment declarator
{
! if ($3 && !comment_last_decl(&$1, $3))
! YYERROR;
add_decl_list(&$$, &$1, &$4);
}
| declarator_list opt_eolcomment
{
$$ = $1;
! if ($2 && !comment_last_decl(&$1, $2))
! YYERROR;
}
;
--- 194,206 ----
}
| declarator_list ',' opt_eolcomment declarator
{
! if ($3) comment_last_decl(&$1, $3);
add_decl_list(&$$, &$1, &$4);
}
| declarator_list opt_eolcomment
{
$$ = $1;
! if ($2) comment_last_decl(&$1, $2);
}
;
***************
*** 373,387 ****
}
| init_declarator_list ',' opt_eolcomment init_declarator
{
! if ($3 && !comment_last_decl(&$1, $3))
! YYERROR;
add_decl_list(&$$, &$1, &$4);
}
| init_declarator_list opt_eolcomment
{
$$ = $1;
! if ($2 && !comment_last_decl(&$1, $2))
! YYERROR;
}
;
--- 369,381 ----
}
| init_declarator_list ',' opt_eolcomment init_declarator
{
! if ($3) comment_last_decl(&$1, $3);
add_decl_list(&$$, &$1, &$4);
}
| init_declarator_list opt_eolcomment
{
$$ = $1;
! if ($2) comment_last_decl(&$1, $2);
}
;
***************
*** 391,407 ****
;
enum_specifier
! : T_ENUM any_id '{' enumerator_list '}'
{
! add_enum_symbol($2, $4);
new_enum_decl_spec(&$$, strconcat("enum ",$2," {}",NULL),
! DE_EXTERN, $4);
free($2);
}
! | T_ENUM '{' enumerator_list '}'
{
new_enum_decl_spec(&$$, strdup("enum {}"), DE_EXTERN,
! $3);
}
| T_ENUM any_id
{
--- 385,403 ----
;
enum_specifier
! : T_ENUM any_id '{' opt_eolcomment enumerator_list '}'
{
! add_enum_symbol($2, $5);
new_enum_decl_spec(&$$, strconcat("enum ",$2," {}",NULL),
! DE_EXTERN, $5);
free($2);
+ free($4);
}
! | T_ENUM '{' opt_eolcomment enumerator_list '}'
{
new_enum_decl_spec(&$$, strdup("enum {}"), DE_EXTERN,
! $4);
! free($3);
}
| T_ENUM any_id
{
***************
*** 419,454 ****
| enumerator_list ',' opt_eolcomment enumerator
{
$$ = $1;
! if ($3 && !comment_last_enumerator($$, $3))
! YYERROR;
add_enumerator_list($$, &$4);
}
| enumerator_list opt_eolcomment
{
$$ = $1;
! if ($2 && !comment_last_enumerator($$, $2))
! YYERROR;
}
;
enumerator
! : T_IDENTIFIER
! {
! new_enumerator(&$$,$1,NULL,NULL);
! }
! | T_COMMENT T_IDENTIFIER
! {
! new_enumerator(&$$,$2,$1,NULL);
! }
! | T_IDENTIFIER T_COMMENT
{
! new_enumerator(&$$,$1,$2,NULL);
}
- | T_COMMENT T_IDENTIFIER T_COMMENT
- {
- enumerator_error($2);
- YYERROR;
- }
;
any_id
--- 415,435 ----
| enumerator_list ',' opt_eolcomment enumerator
{
$$ = $1;
! if ($3) comment_last_enumerator($$, $3);
add_enumerator_list($$, &$4);
}
| enumerator_list opt_eolcomment
{
$$ = $1;
! if ($2) comment_last_enumerator($$, $2);
}
;
enumerator
! : opt_comment T_IDENTIFIER opt_comment
{
! new_enumerator(&$$,$2,$1,$3);
}
;
any_id
***************
*** 547,554 ****
: parameter_list opt_eolcomment
{
$$ = $1;
! if ($2 && !comment_last_parameter(&$1, $2))
! YYERROR;
}
| parameter_list ',' T_ELLIPSIS
{
--- 528,534 ----
: parameter_list opt_eolcomment
{
$$ = $1;
! if ($2) comment_last_parameter(&$1, $2);
}
| parameter_list ',' T_ELLIPSIS
{
***************
*** 563,570 ****
}
| parameter_list ',' opt_eolcomment parameter_declaration
{
! if ($3 && !comment_last_parameter(&$1, $3))
! YYERROR;
add_param_list(&$$, &$1, &$4);
}
;
--- 543,549 ----
}
| parameter_list ',' opt_eolcomment parameter_declaration
{
! if ($3) comment_last_parameter(&$1, $3);
add_param_list(&$$, &$1, &$4);
}
;
***************
*** 572,586 ****
parameter_declaration
: opt_comment declaration_specifiers declarator opt_comment
{
! if (!new_parameter(&$$, &$2, &$3, $1, $4)) YYERROR;
}
| opt_comment declaration_specifiers abstract_declarator opt_comment
{
! if (!new_parameter(&$$, &$2, &$3, $1, $4)) YYERROR;
}
| opt_comment declaration_specifiers opt_comment
{
! if (!new_parameter(&$$, &$2, NULL, $1, $3)) YYERROR;
}
;
--- 551,565 ----
parameter_declaration
: opt_comment declaration_specifiers declarator opt_comment
{
! new_parameter(&$$, &$2, &$3, $1, $4);
}
| opt_comment declaration_specifiers abstract_declarator opt_comment
{
! new_parameter(&$$, &$2, &$3, $1, $4);
}
| opt_comment declaration_specifiers opt_comment
{
! new_parameter(&$$, &$2, NULL, $1, $3);
}
;
***************
*** 665,670 ****
--- 644,657 ----
$$ = NULL;
}
| T_COMMENT
+ {
+ $$ = $1;
+ if (inbasefile && first_comment)
+ {
+ remember_terse($1);
+ first_comment = FALSE;
+ }
+ }
| opt_comment T_COMMENT
{
free($1);
***************
*** 722,727 ****
--- 709,716 ----
create_enum_symbol_table();
line_num = 1;
ly_count = 0;
+ first_comment = group_together && !terse_specified;
+
yyparse();
if (!errors) output_manual_pages(firstpage);
free_manual_pages(firstpage);
*** 1.9 1992/08/17 06:18:38
--- manpage.c 1992/08/25 07:05:10
***************
*** 1,4 ****
! /* $Id: manpage.c,v 1.9 1992/08/17 06:18:38 greyham Exp $
* stuff to do with manual page outputing
*/
--- 1,4 ----
! /* $Id: manpage.c,v 1.10 1992/08/25 06:41:02 greyham Exp $
* stuff to do with manual page outputing
*/
***************
*** 98,103 ****
--- 98,110 ----
void free_manual_pages(ManualPage *first)
{
ManualPage *page, *next;
+
+ /* free any terse description read from the file */
+ if (group_terse && !terse_specified)
+ {
+ free(group_terse);
+ group_terse = NULL;
+ }
for (page = first;page;page = next)
{
***************
*** 107,119 ****
}
}
/* output a comment as the description */
void
output_comment(comment)
char *comment;
{
boolean new_line = TRUE;
- boolean capitalise = TRUE;
boolean dot_command = FALSE;
if (!comment || !comment[0])
--- 114,167 ----
}
}
+ /* allocate a substring starting at start, ending at end (including *end) */
+ char *alloc_string(char *start,char *end)
+ {
+ int len = end - start + 1;
+ char *ret;
+ if (len == 0) return NULL;
+
+ if ((ret = malloc(len+1)) == 0)
+ outmem();
+
+ strncpy(ret,start,len);
+ ret[len] = '\0';
+
+ return ret;
+ }
+
+ /* remember the terse description from the first comment in a file */
+ void remember_terse(char *comment)
+ {
+ char *c = strchr(comment,'-');
+
+ if (c)
+ {
+ while (*c == '-')
+ c++;
+
+ while (*c && isspace(*c))
+ c++;
+
+ if (*c)
+ {
+ char *d = c + 1;
+
+ while (*d && *d != '\n')
+ d++;
+
+ group_terse = alloc_string(c,d-1);
+ }
+ }
+ }
+
/* output a comment as the description */
void
output_comment(comment)
char *comment;
{
+ enum { TEXT, PERIOD, CAPITALISE } state = CAPITALISE;
boolean new_line = TRUE;
boolean dot_command = FALSE;
if (!comment || !comment[0])
***************
*** 134,144 ****
else if (new_line && c == '.')
dot_command = TRUE;
else if (c == '.')
! capitalise = TRUE;
! else if (!isspace(c) && capitalise)
! {
if (islower(c)) c = toupper(c);
! capitalise = FALSE;
}
putchar(c);
--- 182,194 ----
else if (new_line && c == '.')
dot_command = TRUE;
else if (c == '.')
! state = PERIOD;
! else if (isspace(c))
! state = state == PERIOD ? CAPITALISE : TEXT;
! else if (state == CAPITALISE)
! {
if (islower(c)) c = toupper(c);
! state = TEXT;
}
putchar(c);
***************
*** 146,152 ****
}
/* do a full stop if there wasn't one */
! if (!dot_command && !capitalise) putchar('.');
}
/* Output the list of function parameter descriptions.
--- 196,202 ----
}
/* do a full stop if there wasn't one */
! if (!dot_command && state == TEXT) putchar('.');
}
/* Output the list of function parameter descriptions.
***************
*** 267,307 ****
}
}
- char *alloc_string(char *start,char *end)
- {
- int len = end - start + 1;
- char *ret;
- if (len == 0) return NULL;
-
- if ((ret = malloc(len+1)) == 0)
- outmem();
-
- strncpy(ret,start,len);
- ret[len] = '\0';
-
- return ret;
- }
-
- /* join before and after comments */
- char *join_comments(char *comment_before, char *comment_after)
- {
- char *ret;
-
- if (!comment_before && !comment_after)
- ret = NULL;
- else if (comment_before && !comment_after)
- ret = comment_before;
- else if (!comment_before && comment_after)
- ret = comment_after;
- else
- {
- ret = strconcat(comment_before, " ",comment_after,NULL);
- free(comment_before);
- free(comment_after);
- }
- return ret;
- }
-
/* split out the 'Returns:' section of a function comment */
void
split_returns_comment(char *comment,
--- 317,322 ----
***************
*** 469,474 ****
--- 484,501 ----
return any;
}
+ /* output a formatting string so that it works with filling on */
+ void output_format_string(char *fmt)
+ {
+ while (*fmt)
+ {
+ putchar(*fmt);
+
+ if (*fmt++ == '\n')
+ put_string(".br\n"); /* break the line */
+ }
+ }
+
void sub_section(char *name)
{
#ifdef NeXT /* NeXT's SS macro doesn't move to the left a little */
***************
*** 492,498 ****
char *terse = NULL;
/* check if there's more than one page in the group */
! boolean grouped = group_terse && firstpage->next;
printf(".\\\" WARNING! THIS FILE WAS GENERATED AUTOMATICALLY BY c2man!\n");
printf(".\\\" DO NOT EDIT! CHANGES MADE TO THIS FILE WILL BE LOST!\n");
--- 519,525 ----
char *terse = NULL;
/* check if there's more than one page in the group */
! boolean grouped = group_together && firstpage->next;
printf(".\\\" WARNING! THIS FILE WAS GENERATED AUTOMATICALLY BY c2man!\n");
printf(".\\\" DO NOT EDIT! CHANGES MADE TO THIS FILE WILL BE LOST!\n");
***************
*** 524,530 ****
#endif
put_string(".SH NAME\n");
! if (group_terse)
{
for (page = firstpage; page; page = page->next)
{
--- 551,557 ----
#endif
put_string(".SH NAME\n");
! if (group_together)
{
for (page = firstpage; page; page = page->next)
{
***************
*** 537,543 ****
}
put_string("\\- ");
! put_string(group_terse);
putchar('\n');
}
else
--- 564,570 ----
}
put_string("\\- ");
! put_string(group_terse ? group_terse : "Not Described");
putchar('\n');
}
else
***************
*** 549,555 ****
printf(".SH SYNOPSIS\n");
! put_string(".nf\n.ft B\n");
/* if it's a header file, say to #include it */
if (header_file())
--- 576,582 ----
printf(".SH SYNOPSIS\n");
! put_string(".ft B\n");
/* if it's a header file, say to #include it */
if (header_file())
***************
*** 561,576 ****
for (page = firstpage; page; page = page->next)
{
! put_string(decl_spec_prefix);
!
/* make sure variables are prefixed extern */
if (!(page->decl_spec->flags & DE_STATIC) &&
page->declarator->func_def == FUNC_NONE &&
!strstr(page->decl_spec->text, "extern"))
put_string("extern ");
!
output_decl_spec(page->decl_spec);
! put_string(declarator_prefix);
/* format it nicely if there's more than one parameter */
output_declarator(page->declarator,
--- 588,603 ----
for (page = firstpage; page; page = page->next)
{
! output_format_string(decl_spec_prefix);
!
/* make sure variables are prefixed extern */
if (!(page->decl_spec->flags & DE_STATIC) &&
page->declarator->func_def == FUNC_NONE &&
!strstr(page->decl_spec->text, "extern"))
put_string("extern ");
!
output_decl_spec(page->decl_spec);
! output_format_string(declarator_prefix);
/* format it nicely if there's more than one parameter */
output_declarator(page->declarator,
***************
*** 582,588 ****
if (page->next) put_string("\n\n");
}
! put_string("\n.ft R\n.fi\n");
/* only output paramaters if there actually are some,
* not including merely (void)
--- 609,615 ----
if (page->next) put_string("\n\n");
}
! put_string("\n.ft R\n");
/* only output paramaters if there actually are some,
* not including merely (void)
***************
*** 719,725 ****
output_manpage(page, filetime, month);
/* no SEE ALSO if grouped */
! if (group_terse) break;
/* add the SEE ALSO section */
/* look for any other functions to refer to */
--- 746,752 ----
output_manpage(page, filetime, month);
/* no SEE ALSO if grouped */
! if (group_together) break;
/* add the SEE ALSO section */
/* look for any other functions to refer to */
***************
*** 749,755 ****
}
/* if pages are grouped, just link the rest to the first */
! if (group_terse && !tostdout)
{
for (page=page->next;page;page = page->next)
{
--- 776,782 ----
}
/* if pages are grouped, just link the rest to the first */
! if (group_together && !tostdout)
{
for (page=page->next;page;page = page->next)
{
*** 1.3 1992/08/17 06:18:38
--- manpage.h 1992/08/25 07:05:08
***************
*** 1,4 ****
! /* $Id: manpage.h,v 1.3 1992/08/17 06:18:38 greyham Exp $
* stuff to do with manual page outputing
*/
--- 1,4 ----
! /* $Id: manpage.h,v 1.4 1992/08/25 06:41:02 greyham Exp $
* stuff to do with manual page outputing
*/
***************
*** 22,28 ****
--- 22,33 ----
void
new_manual_page(char *comment, DeclSpec *decl_spec, Declarator *declarator);
+ /* remember the terse description from the first comment in a file */
+ void remember_terse(char *comment);
+
void outmem(void);
void output_manual_pages(ManualPage *first);
void free_manual_pages(ManualPage *first);
+
+ void output_format_string(char *fmt);
*** 1.5 1992/08/17 06:18:38
--- semantic.c 1992/08/25 07:05:08
***************
*** 1,4 ****
! /* $Id: semantic.c,v 1.5 1992/08/17 06:18:38 greyham Exp $
*
* C manual page generator
* These routines implement the semantic actions executed by the yacc parser.
--- 1,4 ----
! /* $Id: semantic.c,v 1.6 1992/08/25 06:41:02 greyham Exp $
*
* C manual page generator
* These routines implement the semantic actions executed by the yacc parser.
***************
*** 375,390 ****
* "int". Parameters of type "float" are promoted to "double".
*/
void
! set_param_types (params, decl_spec, declarators, comment)
ParameterList *params;
DeclSpec *decl_spec;
DeclaratorList *declarators;
char *comment;
{
Declarator *d;
Parameter *p;
char *decl_spec_text, *s;
for (d = declarators->first; d != NULL; d = d->next) {
/* Search the parameter list for a matching name. */
p = search_parameter_list(params, d->name);
--- 375,399 ----
* "int". Parameters of type "float" are promoted to "double".
*/
void
! set_param_types (params, decl_spec, declarators, comment, eolcomment)
ParameterList *params;
DeclSpec *decl_spec;
DeclaratorList *declarators;
char *comment;
+ char *eolcomment;
{
Declarator *d;
Parameter *p;
char *decl_spec_text, *s;
+ if (comment && eolcomment)
+ {
+ yyerror("parameter has multiple comments");
+ return;
+ }
+
+ if (!comment) comment = eolcomment;
+
for (d = declarators->first; d != NULL; d = d->next) {
/* Search the parameter list for a matching name. */
p = search_parameter_list(params, d->name);
***************
*** 448,454 ****
*s = '\0';
put_string(d->text);
if (format && has_parameters(d))
! put_string(declarator_suffix);
fputc(*s++ = '(', stdout);
output_parameters(d, format);
fputc(*s++, stdout);
--- 457,463 ----
*s = '\0';
put_string(d->text);
if (format && has_parameters(d))
! output_format_string(declarator_suffix);
fputc(*s++ = '(', stdout);
output_parameters(d, format);
fputc(*s++, stdout);
***************
*** 479,494 ****
{
if (has_parameters(d)) {
Parameter *p = d->params.first;
! if (format) put_string(first_param_prefix);
output_parameter(p);
p = p->next;
while (p != NULL) {
putchar(',');
! if (format) put_string(middle_param_prefix);
output_parameter(p);
p = p->next;
}
! if (format) put_string(last_param_suffix);
}
else
put_string("void");
--- 488,503 ----
{
if (has_parameters(d)) {
Parameter *p = d->params.first;
! if (format) output_format_string(first_param_prefix);
output_parameter(p);
p = p->next;
while (p != NULL) {
putchar(',');
! if (format) output_format_string(middle_param_prefix);
output_parameter(p);
p = p->next;
}
! if (format) output_format_string(last_param_suffix);
}
else
put_string("void");
*** 1.3 1992/08/17 06:18:38
--- semantic.h 1992/08/25 07:05:07
***************
*** 1,4 ****
! /* $Id: semantic.h,v 1.3 1992/08/17 06:18:38 greyham Exp $
*
* Declarations for semantic action routines
*/
--- 1,4 ----
! /* $Id: semantic.h,v 1.4 1992/08/25 06:41:02 greyham Exp $
*
* Declarations for semantic action routines
*/
***************
*** 85,91 ****
ParameterList *params,
DeclSpec *decl_spec,
DeclaratorList *declarators,
! char *comment
);
extern void output_declarations(
DeclSpec *decl_spec,
--- 85,92 ----
ParameterList *params,
DeclSpec *decl_spec,
DeclaratorList *declarators,
! char *comment,
! char *eolcomment
);
extern void output_declarations(
DeclSpec *decl_spec,
--
Graham Stoney. Ph: +61-2-805-2909. Totally unrelated message follows:
Since 1972, more than 40 innocent people have been sentenced to death in the
USA.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads