By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,127 Members | 1,147 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,127 IT Pros & Developers. It's quick & easy.

Counting program lines except comments

P: n/a
Is there any tool to count C-program lines except comments?

Thanks,

=====================================
Alex Vinokur
mailto:al****@connect.to
http://mathforum.org/library/view/10978.html
news://news.gmane.org/gmane.comp.lang.c++.perfometer
=====================================

Nov 13 '05 #1
Share this Question
Share on Google+
19 Replies


P: n/a
Alex Vinokur <al****@bigfoot.com> scribbled the following:
Is there any tool to count C-program lines except comments?


Try that comment stripping program posted here, and use wc on the
result.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"We're women. We've got double standards to live up to."
- Ally McBeal
Nov 13 '05 #2

P: n/a
Alex Vinokur wrote:

Is there any tool to count C-program lines except comments?


This is Question 18.1 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

.... and I'm shocked! shocked! to learn that a "regular"
behaved like a newbie and failed to check the FAQ first.

--
Er*********@sun.com
Nov 13 '05 #3

P: n/a


On 11/18/2003 1:26 PM, Eric Sosman wrote:
Alex Vinokur wrote:
Is there any tool to count C-program lines except comments?

This is Question 18.1 in the comp.lang.c Frequently
Asked Questions (FAQ) list


The FAQ doesn't adequately answer this specific question (as the FAQ says, using
"wc" or "grep -c ';'" are both crude approximations). Try "ncsl" available for
free at http://www.lucentssg.com/displayProduct.cfm?prodid=33

Ed.
Nov 13 '05 #4

P: n/a

"Ed Morton" <mo****************@lucent.com> wrote in message
news:3F**************@lucent.com...


On 11/18/2003 1:26 PM, Eric Sosman wrote:
Alex Vinokur wrote:
Is there any tool to count C-program lines except comments?

This is Question 18.1 in the comp.lang.c Frequently
Asked Questions (FAQ) list


The FAQ doesn't adequately answer this specific question


Your objection has apparently already been anticipated:
From the bottom of 18.1:

<quote>
(This list of tools is by no means complete; if you know of tools not
mentioned, you're welcome to contact this list's maintainer.)

Other lists of tools, and discussion about them, can be found in the Usenet
newsgroups comp.compilers and comp.software-eng .
</quote>

(as the FAQ says, using
"wc" or "grep -c ';'" are both crude approximations). Try "ncsl" available for free at http://www.lucentssg.com/displayProduct.cfm?prodid=33


Perhaps you'd consider submitting that link to the FAQ maintainer.

-Mike
Nov 13 '05 #5

P: n/a


On 11/18/2003 2:18 PM, Mike Wahler wrote:
"Ed Morton" <mo****************@lucent.com> wrote in message <snip>
(as the FAQ says, using
"wc" or "grep -c ';'" are both crude approximations). Try "ncsl" available


for
free at http://www.lucentssg.com/displayProduct.cfm?prodid=33

Perhaps you'd consider submitting that link to the FAQ maintainer.


I'd like to see some other people try it first. For the past 15 years or so,
it's always worked fine for me on various UNIX platforms but I've never tried
compiling or running it on any other platform, nor have I tried it on C99 code.
I did find that if I added a //-style comment to my code and then run the tool
using "-lc", then it didn't recognize that commentary style - I had to run the
tool using "-lc++" for it to strip out //-style comments. Not sure if there's
other noteworthy differences.

So, if anyone out there feels like trying it out, I'd be interested in hearing
the result and then I can write a note with approriate caveats (if any) to the
FAQ maiuntainer.

NOTE: I didn't write "ncsl" and I don't maintain it, I just use it.

Ed.

-Mike


Nov 13 '05 #6

P: n/a
On Tue, 18 Nov 2003 20:35:06 +0200, in comp.lang.c , "Alex Vinokur"
<al****@bigfoot.com> wrote:
Is there any tool to count C-program lines except comments?


run it through the preprocessor, then use wc?
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
Nov 13 '05 #7

P: n/a

"Mark McIntyre" <ma**********@spamcop.net> wrote in message news:7a********************************@4ax.com...
On Tue, 18 Nov 2003 20:35:06 +0200, in comp.lang.c , "Alex Vinokur"
<al****@bigfoot.com> wrote:
Is there any tool to count C-program lines except comments?


run it through the preprocessor, then use wc?


Preprocessored program includes header files.

Sample : Program "Hello word" (foo.c)

$ wc foo.c
8 15 103 foo.c

$ gcc -E foo.c | wc
829 2246 18879

[snip]
--
=====================================
Alex Vinokur
mailto:al****@connect.to
http://mathforum.org/library/view/10978.html
news://news.gmane.org/gmane.comp.lang.c++.perfometer
=====================================


Nov 13 '05 #8

P: n/a


Alex Vinokur wrote:
"Mark McIntyre" <ma**********@spamcop.net> wrote in message news:7a********************************@4ax.com...
On Tue, 18 Nov 2003 20:35:06 +0200, in comp.lang.c , "Alex Vinokur"
<al****@bigfoot.com> wrote:

Is there any tool to count C-program lines except comments?


run it through the preprocessor, then use wc?

Preprocessored program includes header files.


It also includes white-space and an added indication of the source file
name. If you're on *NIX, though, and you don't want to download the
"ncsl" tool I mentioned in a previous posting, then this seems like it
should work:

sed '/#include/s/#//' foo.c |
gcc -E - |
sed -e 's/[ ]//g' -e '/^$/d' -e '1d' |
wc -l

The first sed turns "#include" into just "include" so it's ignored by
the preprocessor. Then gcc -E strips out comments and adds # 1 "" as the
first line. The first "-e" of the second sed has a single space and a
tab within it's RE specifier ([...]) so it deletes all spaces and tabs
so that there are no lines with just white-space. The second "-e"
deletes all empty lines. The third -e gets rid of the first line added
by gcc. Finally wc -l counts the number of lines.

Ed.

Nov 13 '05 #9

P: n/a
"Alex Vinokur" <al****@bigfoot.com> wrote in message news:<bp*************@ID-79865.news.uni-berlin.de>...
Is there any tool to count C-program lines except comments?

Thanks,

=====================================
Alex Vinokur
mailto:al****@connect.to
http://mathforum.org/library/view/10978.html
news://news.gmane.org/gmane.comp.lang.c++.perfometer
=====================================


Alex:

Check this :

/* File uncmntc.c - demo of a text filter
Strips C comments and counts number of non-commented codes.
Tested to strip itself
by Ravi Uday. 2003-08-15
Public Domain. Attribution appreciated
report bugs to <mailto:ra*****@yahoo.com>
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Maximum chars in any line. If this is crossed then the remaining
bytes are ignored */
#define BYTES 512

/* line is valid if it contains any of the following chars. Otherwise
treated as commented */
#define VALID_CHARS "\\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU VWXYZ;,'/#{}()*+-0123456789"

int comment_handler ( FILE *fptr, char *c, char *str, int *len, int
*line_count)
{
int ind = 0;
char ch;
if ( ( ch = fgetc ( fptr )) =='*')/* checks for beginning of comment
*/
{
while ( !ind )
{
if (fgetc ( fptr ) == '*' )
{
if ( fgetc ( fptr ) == '/')/* checks for end of comment */
{
ind = 1;
*c = fgetc ( fptr);
}
}
}
}
else if ( ch == '/')/* checks cpp comment */
{
while ( (!feof (fptr) ) && ( ch != '\n'))/* end of line check for \n
*/
ch = fgetc ( fptr );

*c = ch;
}
else if ( *c == '"' )/* checks for comment in a string. */
{
str[(*len)++] = *c;/* Store the '"' char. */
str[(*len)++] = ch;/* Store the next char. */
while ( !ind )
{
str[*len] = fgetc ( fptr );
if ( str[*len] == '"')
ind = 1;
else if (str[*len] == '\n')
(*line_count)++;

(*len)++;
}
*len = *len-1;
*c = str[*len];
return 1;
}
else/* Special case: No comments found */
{
*c = ch;/* Storing next character */
return 0;/* The char is single '/' */
}
return 1;
}

int main (int argc, char *argv[])
{
int i = 0, j = 0, flag = 0;
char ch = 0;
char buffer[BYTES];/* variable holds a max of BYTES (defined) chars in
any line */
FILE *fp = NULL, *fout = NULL;

if ( argc < 3 ) return EXIT_FAILURE;

fp = fopen ( argv[1], "rb");/* open the source file */

if ( fp == NULL ) return EXIT_FAILURE;

fflush ( stdout);
fout = fopen ( argv[2], "wb");/* open the output file */

if ( fout == NULL ) return EXIT_FAILURE;

while ( (!feof (fp )) && (!ferror (fp)) )
{
memset ( buffer, 0x00, BYTES);
while ( (j != BYTES-1) && (!flag) )/* Check for max BYTES-1 chars */
{
ch = fgetc ( fp );

if ( ( ch == '/') || ( ch == '"'))
if (comment_handler ( fp, &ch, buffer, &j, &i ) == 0)
buffer[j++] = '/';

if ( (ch == '\n') || (feof (fp)))
flag = 1;

/* dont add '\n' or '\r' to the running buffer cause its appended in
the fprintf */
if ( ( ch !='\n' ) && ( ch != '\r'))
buffer[j++] = ch;
}
if (j == BYTES-1)/* line has more than BYTES chars, so ignore them !
*/
{
j++;
while ( (!feof (fp )) && (!ferror (fp) ))
{
ch = fgetc(fp);
if ( ch == '\n')
break;
}
}
if (strpbrk (buffer, VALID_CHARS))
{
fprintf ( fout, "%s\n", buffer);
i++;
}
j = flag = ch = 0;/* reset the loop variables. */
}
printf ("\n*** Number of non commented lines is : %d ***\n\n", i);

fclose ( fp );
fclose ( fout );

return EXIT_SUCCESS;
}

Good luck
- Ravi
Nov 13 '05 #10

P: n/a
"Alex Vinokur" <al****@bigfoot.com> wrote in message news:<bp*************@ID-79865.news.uni-berlin.de>...
Is there any tool to count C-program lines except comments?


Lines or statements? A single statement may take multiple source
lines. Then again, multiple statements may occupy a single line.
Nov 13 '05 #11

P: n/a


On 11/20/2003 2:02 AM, Ravi Uday wrote:
"Alex Vinokur" <al****@bigfoot.com> wrote in message news:<bp*************@ID-79865.news.uni-berlin.de>...
Is there any tool to count C-program lines except comments?

Thanks,

=====================================
Alex Vinokur
mailto:al****@connect.to
http://mathforum.org/library/view/10978.html
news://news.gmane.org/gmane.comp.lang.c++.perfometer
=====================================

Alex:

Check this :


<snip>

I tried it and it miscounted the number of lines in it's source program. It
reported 112 lines, whereas there's only 103. Sometimes it deletes the comments
from it's output, sometimes it leaves them in (e.g. the line " else if ( *c ==
'"' )/* checks for comment in a string. */"). Sometimes it deletes blank lines,
sometimes it leaves them in (in this case it left in 9, which I assume is why
its count is off by 9). To try to get some more information, I tried deleting
the "comment_handler" function and running the tool again on that modified
source file, but this time it core dumped.

Playing with it DID uncover a problem with using "gcc -E" to strip out comments
- if there are macros defined within the source file, then of course they get
expanded so the NCSL (Non-Commentary Source Line) count doesn't actually match
the NCSL written.

Ed.

Nov 13 '05 #12

P: n/a
<snip>
<snip>

I tried it and it miscounted the number of lines in it's source program. It
reported 112 lines, whereas there's only 103. Sometimes it deletes the comments
from it's output, sometimes it leaves them in (e.g. the line " else if ( *c ==
'"' )/* checks for comment in a string. */"). Sometimes it deletes blank lines,
sometimes it leaves them in (in this case it left in 9, which I assume is why
its count is off by 9). To try to get some more information, I tried deleting
the "comment_handler" function and running the tool again on that modified
source file, but this time it core dumped.
Hey the comment_handler and main are inter-connected. Cause the input
pointer gets filled on returning from comment_handler. Dont comment it
!!
Playing with it DID uncover a problem with using "gcc -E" to strip out comments
- if there are macros defined within the source file, then of course they get
expanded so the NCSL (Non-Commentary Source Line) count doesn't actually match
the NCSL written.

Ed.


Ed,
Those were some interesting observations you made. Can you send me the
input file that you used, so that i can check on that.
Eg: if the file had ...

#define he "hello"/*is a
macro*/"int i;
Then number of lines in this snippet is 1 and not 2 !!

Any suggestions welcome.
- Ravi
Nov 13 '05 #13

P: n/a
On Wed, 19 Nov 2003 06:34:57 +0200, in comp.lang.c , "Alex Vinokur"
<al****@bigfoot.com> wrote:

"Mark McIntyre" <ma**********@spamcop.net> wrote in message news:7a********************************@4ax.com...
On Tue, 18 Nov 2003 20:35:06 +0200, in comp.lang.c , "Alex Vinokur"
<al****@bigfoot.com> wrote:
>Is there any tool to count C-program lines except comments?


run it through the preprocessor, then use wc?


Preprocessored program includes header files.


He didn't say he wanted to exclude headers.
Anyway, some snippage in an editor would solve that easily enough.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
Nov 13 '05 #14

P: n/a


Ravi Uday wrote:

<snip>
Hey the comment_handler and main are inter-connected. Cause the input
pointer gets filled on returning from comment_handler. Dont comment it
!!
I don't mean that I commented it out then tried to recompile and run it
- I compiled your code, then ran the tool on it's own source, then
editted the source to try to get to a minimal set that could reproduce
the problem (but didn't recompile!) and reran the previously compiled
(i.e. original) version on the newly editted source.

<snip>
Those were some interesting observations you made. Can you send me the
input file that you used, so that i can check on that.
I just did a copy-and-paste of your posted code.

By the way, I wouldn't have posted this if I wasn't reply anyway, but in
case anyone wants it (e.g. Ravi - you could use it to check your code's
output), here's a shell script that'll count NCSL, getting round the
file inclusion and macro expansion problems:

_file="$1"

_sed=/whatever/bin/sed # path to a sed that supports
# the "[[:space:]]" RE (e.g. GNU)

_hash="__HASH__$$__"
$_sed -e "s/#/${_hash}/g" ${_file} |
gcc -E - |
$_sed -e "s/${_hash}/#/g" \
-e '/^[[:space:]][[:space:]]*$/d' \
-e '/^$/d' \
-e '1d'

Regards,

Ed.
Eg: if the file had ...

#define he "hello"/*is a
macro*/"int i;
Then number of lines in this snippet is 1 and not 2 !!

Any suggestions welcome.
- Ravi


Nov 13 '05 #15

P: n/a


Ed Morton wrote:

<snip>
output), here's a shell script that'll count NCSL, getting round the
file inclusion and macro expansion problems:


I meant to say it'll produce the NCSL. To count it, just pipe the output
to "wc -l".

Ed.

Nov 13 '05 #16

P: n/a
<snip>
I meant to say it'll produce the NCSL. To count it, just pipe the output
to "wc -l".

Ed,
See what i did was to copy your shell script file contents and put
in a file and took that as an input to my parser code.

It gave me correct results. ( NCSL = 10 , blank lines
ignored. )

I have posted my corrected code: just have a look at
it. It prints to the 'stdout', instead of a file. You
can also print it to a file.
/* File uncmntc.c - demo of a text filter
Strips C comments and counts number of non-commented lines.
Tested to strip itself
by Ravi Uday. 2003-08-15
Public Domain. Attribution appreciated
report bugs to <mailto:ra*****@yahoo.com>
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Maximum chars in any line. If this is crossed then
the remaining bytes are ignored */
#define BYTES 512

/* line is valid if it contains any of the following
chars. Otherwise treated as commented */
#define VALID_CHARS
"\\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU VWXYZ;,'/#{}()*+-0123456789"

int comment_handler ( FILE *fptr, char *c, char *str,
int *len, int *line_count)
{
int ind = 0;
char ch;

if ( ( ch = fgetc ( fptr )) =='*')/* checks for
beginning of comment */
{
while ( !ind )
{
if (fgetc ( fptr ) == '*' )
{
if ( fgetc ( fptr ) == '/')/* checks for end of
comment */
{
ind = 1;
*c = fgetc ( fptr);
}
}
}
}
else if ( ch == '/')/* checks cpp comment */
{
while ( (!feof (fptr) ) && ( ch != '\n'))/* end of
line check for \n */
ch = fgetc ( fptr );

*c = ch;
}
else if ( *c == '"' )/* checks for comment in a
string. */
{
str[(*len)++] = *c;/* Store the '"' char. */
str[(*len)++] = ch;/* Store the next char. */

if ( ch == 0x27 )/* Char is a single quote "'"*/
{
*len = *len-1;
*c = str[*len];
return 1;/* It is not a string just a char. */
}

while ( !ind )
{
str[*len] = fgetc ( fptr );
if ( str[*len] == '"')
ind = 1;
else if (str[*len] == '\n')
(*line_count)++;

(*len)++;
}
*len = *len-1;
*c = str[*len];
return 1;
}

else/* Special case: No comments found */
{
*c = ch;/* Storing next character */
return 0;/* The char is single '/' */
}

return 1;
}

int main (int argc, char *argv[])
{
int i = 0, j = 0, flag = 0;
char ch = 0;
char buffer[BYTES];/* variable holds a max of BYTES
(defined) chars in any line */
FILE *fp = NULL, *fout = NULL;

if ( argc < 3 ) return EXIT_FAILURE;

fp = fopen ( argv[1], "rb");/* open the source file */

if ( fp == NULL ) return EXIT_FAILURE;

fflush ( stdout);
fout = fopen ( argv[2], "wb");/* open the output file
*/

if ( fout == NULL ) return EXIT_FAILURE;

while ( (!feof (fp )) && (!ferror (fp)) )
{
memset ( buffer, 0x00, BYTES);
while ( (j != BYTES-1) && (!flag) )/* Check for max
BYTES-1 chars */
{
ch = fgetc ( fp );

if ( ( ch == '/') || ( ch == '"'))
if (comment_handler ( fp, &ch, buffer, &j, &i ) ==
0)
buffer[j++] = '/';

if ( (ch == '\n') || (feof (fp)))
flag = 1;

/* dont add '\n' or '\r' to the running buffer cause
its appended in the fprintf */
if ( ( ch !='\n' ) && ( ch != '\r'))
buffer[j++] = ch;
}
if (j == BYTES-1)/* line has more than BYTES chars,
so ignore them ! */
{
j++;
while ( (!feof (fp )) && (!ferror (fp) ))
{
ch = fgetc(fp);
if ( ch == '\n')
break;
}
}

if (strpbrk (buffer, VALID_CHARS))
{
fprintf ( stdout, "%s\n", buffer);
i++;
}

j = flag = ch = 0;/* reset the loop variables. */
}
printf ("\n*** Number of non commented lines is : %d
***\n\n", i);

fclose ( fp );
//fclose ( fout );

return EXIT_SUCCESS;
}
Thanks,
Ravi Uday
Nov 13 '05 #17

P: n/a


Ravi Uday wrote:
<snip>
I meant to say it'll produce the NCSL. To count it, just pipe the output
to "wc -l".


Ed,
See what i did was to copy your shell script file contents and put
in a file and took that as an input to my parser code.

It gave me correct results. ( NCSL = 10 , blank lines
ignored. )


I take it you mean "108" rather than "10" ;-). Looks good, but there are
a couple of issues:

1) It still requires a second file name argument, even though it doesn't
write to it,
2) It should print the analysis result to stderr instead of stdout so
the user can redirect stdout to a file to capture the de-commented code
without appending the NCSL count,
3) It deletes comments instead of replacing them with a single blank (as
"gcc -E" does).

Item "3" is the important one. If I have this code:

#include "stdio.h"
#define X/* whatever */7
int main(void)
{
printf("%d\n",X);
return 0;
}

in a file, then when I run my shell script on it I end up with:

#include "stdio.h"
#define X 7
int main(void)
{
printf("%d\n",X);
return 0;
}

which compiles and runs exactly like the original, but when I run your
tool on it I get:

#include "stdio.h"
#define X7
int main(void)
{
printf("%d\n",X);
return 0;
}

which won't compile since it now defines "X7" on the second line instead
of "X".

Ed.

Nov 13 '05 #18

P: n/a

"Alex Vinokur" <al****@bigfoot.com> wrote in message news:bp*************@ID-79865.news.uni-berlin.de...
Is there any tool to count C-program lines except comments?

[snip]

Counter of C/C++ source lines and bytes can be downloaded at :
http://alexvn.freeservers.com/s1/download.html ("Counter of C/C++ source lines and bytes").
NAME
nlcs - count C/C++ source lines and bytes

SYNOPSIS
nlcs [OPTIONS]... [FILE]...

DESCRIPTION
Count code-lines, empty-lines, comment-lines,
code-fields, empty-fields, comment-fields of C/C++-sources
which have been successfully compiled.
Summary and detailed reports are generated.

Here is Summary Report Sample.

--- Summary Report ---
==================================
| : Lines : Bytes |
|--------------------------------|
| Code Only : 47 : 873 |
| Code+Comment : 32 : - |
| Comment Only : 20 : 984 |
| Empty : 87 : 441 |
|................................|
| * Total : 186 : 2298 |
==================================
=====================================
Alex Vinokur
mailto:al****@connect.to
http://mathforum.org/library/view/10978.html
=====================================


Nov 14 '05 #19

P: n/a

"Alex Vinokur" <al****@big.foot.com> wrote in message news:bs************@ID-79865.news.uni-berlin.de...
[snip]
Counter of C/C++ source lines and bytes can be downloaded at :
http://alexvn.freeservers.com/s1/download.html ("Counter of C/C++ source lines and bytes").

[snip]

Also at https://sourceforge.net/projects/cncc/

--
Alex Vinokur
http://mathforum.org/library/view/10978.html


Nov 14 '05 #20

This discussion thread is closed

Replies have been disabled for this discussion.