summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/getcmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONTRIB/SNIP/getcmt.c')
-rwxr-xr-xreference/C/CONTRIB/SNIP/getcmt.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/getcmt.c b/reference/C/CONTRIB/SNIP/getcmt.c
new file mode 100755
index 0000000..23651a7
--- /dev/null
+++ b/reference/C/CONTRIB/SNIP/getcmt.c
@@ -0,0 +1,267 @@
+/* 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 */