home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
s
/
snip1292.zip
/
GETCMT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-19
|
10KB
|
268 lines
/* getcmt.c - get comments from a C or C++ source file */
/*
Byte_Magic Software
9850 Meadowglen Ln. #35
Houston, Tx. 77042
(713) 975-9033
Author: Greg Messer
Program: getcmt.c
Purpose: Isolate comments from a C or C++ source file. Filter.
Syntax: getcmt [/L?] [filename]
(may use redirection for file and/or device I/O)
Release: Released to the Public Domain by Byte_Magic Software.
Date: 07-11-88 GM...
First release.
Revised: 01-13-90 GM...
Streamlined logic.
01-15-90 Bob Stout (RBS)...
Fixed unsigned char error as return from getc().
01-22-90 GM...
Fixed bug handling "xx/" (xx = **) at end of comment.
Added C++ comment extraction.
Added return of count to OS (ERRORLEVEL in MS-DOS).
01-24-90 RBS
Added filename spec option
Added /? switch
System: Compiled with Zortech C V2.06 under MS-DOS 3.20
for IBM PCs and compatibles.
Rules: ANSI C comments begin with /x and end with x/. (x = *).
Comments do not nest and do not appear in string or character
constants.
C++ comments begin with double slashes and end at EOL.
A Microsoft extension to C allows C++ style comments to serve as
single-line comments in C source.
Comments: Useful for creating documentation and improving commenting style.
Input may be from a specified filename or stdin.
Output is to stdout, so use DOS redirection for output.
Messages go to stderr so they are not redirectable from the screen.
Returns ERRORLEVEL = number of comments in source file(s).
Examples:
Example... Output to screen:
getcmt < cfile.c
(displays comments from cfile.c on screen)
type cfile.c | getcmt
(same as above but slightly slower)
getcmt < cfile.c | more
(same as above, but pauses after each full screen)
getcmt cfile.c /l | more
(same as above, but display line numbers)
Example... Output to printer:
getcmt < cfile.c > prn
(same as above but prints output on printer)
type cfile.c | getcmt > prn
(same as above but slightly slower)
Example... Output to file:
getcmt < cfile.c > cfile.cmt
(writes cfile.c comments to cfile.cmt, overwriting existing file)
getcmt < cfile.c >> cfile.doc
(writes cfile.c comments to end of cfile.doc (appends))
getcmt /?
(displays help screen, returns ERRORLEVEL = 0)
getcmt /x
(invalid option - displays help screen, returns ERRORLEVEL = -1)
For complete instructions on using redirection symbols, consult
the PC-DOS or MS-DOS manual or a general DOS reference book.
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define LOOKS_GREAT 1
#define LESS_FILLING 0
int extract_c_cmts(void);
void inside_c_cmt(int);
FILE *infile = stdin; /* read input from here */
int show_nos = 0; /* 0 = don't display line numbers */
int line_no = 1; /* line_no = line number */
/* * * * * * * * * * * * * * * * * * * */
main(int argc, char *argv[]) /* main logic: */
{
register int i;
const char *hype =
"\nGETCMT v1.1 - GET CoMmenTs\nby Byte_Magic Software\n";
const char *help =
"\nUsage: GETCMT [/l?] [filename | <sourcefile.ext] "
"[>destination file or device]\n"
"Options: l - Print line numbers\n"
" ? - Help\n"
"\nFilename optional - Reads source code from stdin "
"(Ctrl-C to quit before EOF)\n";
const char *oops =
"\a*** GETCMT - Can't open input file ";
/* display messages to operator */
#if LOOKS_GREAT
fputs(hype, stderr);
#elif LESS_FILLING
i = 0;
while(hype[i] != '\0')
putc(hype[i++], stderr);
#endif
if (1 < argc)
{
for (i = 1; i < argc; ++i)
{
if ('/' == *argv[i])
{
if ('l' == tolower(argv[i][1]))
show_nos = 1;
else
{
int ercode;
ercode = ('?' == argv[i][1]) ? 0 : -1;
#if LOOKS_GREAT
fputs(help, stderr);
#elif LESS_FILLING
i = 0;
while(help[i] != '\0')
putc(help[i++], stderr);
#endif
if (ercode) /* output BEL if invalid seitch */
putc('\a', stderr);
return(ercode);
}
}
else
{
infile = fopen(argv[i], "r");
if (!infile)
{
#if LOOKS_GREAT
fputs(oops, stderr);
fputs(argv[i], stderr);
#elif LESS_FILLING
char *p = argv[i];
i = 0;
while (oops[i])
putc(oops[i], stderr);
i = 0;
while (*p)
putc(*p++, stderr);
#endif
}
}
}
}
i = extract_c_cmts(); /* extract comments in infile */
putc('\n', stdout);
return(i); /* return number of comments to */
/* OS (ERRORLEVEL in DOS) */
}
/* * * * * * * * * * * * * * * * * * * */
int extract_c_cmts() /* comment extraction logic: */
{
register int chi, cht; /* chi = char in, cht = char test */
int count; /* count = comment count */
count = 0;
chi = getc(infile);
while(chi != EOF) /* as long as there is input... */
{
if(chi == '/') /* process comments */
{
cht = getc(infile);
if(cht == EOF)
return(count);
if(cht == '*' || cht == '/') /* if start of a comment... */
{
count++; /* count it and */
inside_c_cmt(cht); /* output all of the comment */
}
else
ungetc(cht, infile);
}
if ('\n' == chi)
line_no += 1;
chi = getc(infile); /* continue scanning input */
}
return(count);
}
/* * * * * * * * * * * * * * * * * * * */
char *lntoaz(void) /* line number to zero-padded ASCII */
{
int i, num = line_no;
static char numbuf[] = "0000: ";
if (9999 < num)
strncpy(numbuf, "0000", 4);
else for (i = 3; i >= 0; --i)
{
numbuf[i] = (char)('0' + num % 10);
num /= 10;
}
return numbuf;
}
/* * * * * * * * * * * * * * * * * * * */
void inside_c_cmt(int ch) /* comment output logic: */
{ /* input ch = either '*' for C */
/* or '/' for C++ */
register int chi, cht; /* chi = char in, cht = char test */
#if LESS_FILLING
char *p;
#endif
if(ch == '/') /* make ch = '\n' if C++ */
ch = '\n'; /* note: ch is already 1st char */
/* of end comment if this is C */
putc('\n', stdout);
if (show_nos)
{
#if LOOKS_GREAT
fputs(lntoaz(), stdout);
#elif LESS_FILLING
p = lntoaz();
while (*p)
putc(*p++, stdout);
#endif
}
chi = getc(infile);
while(chi != EOF) /* as long as there is input... */
{ /* process comments */
if(chi == ch)
{
if(ch == '\n') /* if C++ comment is ended... */
return; /* stop outputting */
cht = getc(infile);
if(cht == '/') /* if C comment is ended... */
return; /* stop outputting */
else
{
ungetc(cht, infile);
putc(chi, stdout);
}
}
else
putc(chi, stdout); /* else comment text, output it */
if ('\n' == chi)
line_no += 1;
chi = getc(infile); /* continue scanning input */
}
return;
}
/* * * * * * * * * * * * * * * * * * * */
/* end of getcmt.c */