cloc
Count Lines of Code
cloc counts blank lines, comment lines, and physical lines of source code in many programming languages.
Latest release: v2.10 (July 4, 2026)
cloc moved to GitHub in September 2015 after being hosted
at http://cloc.sourceforge.net/ since August 2006.
Quick Start
Step 1: Install cloc (see Install from Github Releases
and Install via package manager) or run cloc's
docker image. The Windows executable has no requirements.
The source version of cloc requires a Perl interpreter, and the
Docker version of cloc requires a Docker installation.
Step 2: Open a terminal (cmd.exe on Windows).
Step 3: Invoke cloc to count your source files, directories, archives,
or git commits.
The executable name differs depending on whether you use the
development source version (cloc), source for a
released version (cloc-2.10.pl) or a Windows executable
(cloc-2.10.exe).
On this page, cloc is the generic term
used to refer to any of these.
Include Security has a
YouTube video
showing the steps in action.
a file
prompt> cloc hello.c
1 text file.
1 unique file.
0 files ignored.
https://github.com/AlDanial/cloc v 1.65 T=0.04 s (28.3 files/s, 340.0 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C 1 0 7 5
-------------------------------------------------------------------------------a directory
prompt> cloc gcc-5.2.0/gcc/c
16 text files.
15 unique files.
3 files ignored.
https://github.com/AlDanial/cloc v 1.65 T=0.23 s (57.1 files/s, 188914.0 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C 10 4680 6621 30812
C/C++ Header 3 99 286 496
-------------------------------------------------------------------------------
SUM: 13 4779 6907 31308
-------------------------------------------------------------------------------an archive
We'll pull cloc's source zip file from GitHub, then count the contents:
prompt> wget https://github.com/AlDanial/cloc/archive/master.zip
prompt> cloc master.zip
https://github.com/AlDanial/cloc v 1.65 T=0.07 s (26.8 files/s, 141370.3 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Perl 2 725 1103 8713
-------------------------------------------------------------------------------
SUM: 2 725 1103 8713
-------------------------------------------------------------------------------a git repository, using a specific commit
This example uses code from
PuDB, a fantastic Python debugger.
prompt> git clone https://github.com/inducer/pudb.git
prompt> cd pudb
prompt> cloc 6be804e07a5db
48 text files.
41 unique files.
8 files ignored.
github.com/AlDanial/cloc v 1.99 T=0.04 s (1054.9 files/s, 189646.8 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Python 28 1519 728 4659
reStructuredText 6 102 20 203
YAML 2 9 2 75
Bourne Shell 3 6 0 17
Text 1 0 0 11
make 1 4 6 10
-------------------------------------------------------------------------------
SUM: 41 1640 756 4975
-------------------------------------------------------------------------------each subdirectory of a particular directory
Say you have a directory with three different git-managed projects,
Project0, Project1, and Project2. You can use your shell's looping
capability to count the code in each. This example uses bash (scroll down for cmd.exe example):
/* Detailed source-code truncated for AI context efficiency. */each subdirectory of a particular directory (Windows/cmd.exe)
for /D %I in (.\*) do cd %I && cloc --vcs git && cd ..Sponsors
Atlas Cloud
is a full-modal AI inference platform that gives developers a single AI API
to access video generation, image generation, and LLM APIs. Instead of managing
multiple vendor integrations, you connect once and get unified access to
300+ curated models across all modalities.
Overview
cloc counts blank lines, comment lines, and physical lines of source
code in many programming languages. Given two versions of
a code base, cloc can compute differences in blank, comment, and source
lines. It is written entirely in Perl with no dependencies outside the
standard distribution of Perl v5.6 and higher (code from some external
modules is embedded within
cloc) and so is
quite portable. cloc is known to run on many flavors of Linux, FreeBSD,
NetBSD, OpenBSD, macOS, AIX, HP-UX, Solaris, IRIX, z/OS, and Windows.
(To run the Perl source version of cloc on Windows one needs
ActiveState Perl 5.6.1 or
higher, Strawberry Perl,
Windows Subsystem for Linux,
Cygwin,
MobaXTerm with the Perl plug-in
installed,
or
a mingw environment and terminal such as provided by
Git for Windows.
Alternatively one can use the Windows binary of cloc
generated with PAR::Packer
to run on Windows computers that have neither Perl nor Cygwin.)
In addition to counting code in individual text files, directories,
and git repositories, cloc can also count code in archive files such
as .tar (including compressed versions), .zip, Python
wheel .whl, Jupyter notebook .ipynb, source RPMs .rpm
or .src (requires rpm2cpio),
and Debian .deb files (requires dpkg-deb).
cloc contains code from David Wheeler's
SLOCCount,
Damian Conway and Abigail's Perl module
Regexp::Common,
Sean M. Burke's Perl module
Win32::Autoglob,
and Tye McQueen's Perl module
Algorithm::Diff.
Language scale factors were derived from Mayes Consulting, LLC web site
http://softwareestimator.com/IndustryData2.htm.
New releases nominally appear every six months.
Install from Github Releases
Grab the latest release of cloc from the Releases section of this repository.
Source version on Linux/macOS
Save the latest source file, for example cloc-2.10.pl,
as cloc (if you prefer the shorter command name) somewhere on your PATH.
After downloading, make the file executable:
cd ~/Downloads
mv cloc-2.10.pl cloc
chmod a+rx cloc
./cloc --version # make sure it runs
mv cloc ~/bin # for example, if ~/bin is in $PATHSource version on Windows
You'll need a Perl interpreter such as Strawberry Perl
installed to run the source version of cloc.
After downloading the cloc source file, open a command prompt or PowerShell window,
navigate to the download directory (C:\TEMP in the example below), then test cloc with:
cd C:\TEMP>
C:TEMP\> perl cloc-2.10.pl --versionBinary version on Windows
Download the latest released Windows executable, for example cloc-2.10.exe
and save it as cloc.exe (if desired) in a directory on your PATH.
There is no binary version for Linux or macOS.
Install via package manager
Depending your operating system, one of these installation methods may
work for you (all but the last two entries for Windows require
a Perl interpreter):
npm install cloc # https://www.npmjs.com/package/cloc
sudo apt install cloc # Debian, Ubuntu
sudo yum install cloc # Red Hat, Fedora
sudo dnf install cloc # Fedora 22 or later
sudo pacman -S cloc # Arch
yay -S cloc-git # Arch AUR (latest git version)
sudo emerge -av dev-util/cloc # Gentoo https://packages.gentoo.org/packages/dev-util/cloc
sudo apk add cloc # Alpine Linux
doas pkg_add cloc # OpenBSD
sudo pkg install cloc # FreeBSD
sudo port install cloc # macOS with MacPorts
brew install cloc # macOS with Homebrew
winget install AlDanial.Cloc # Windows with winget (might not work, ref https://github.com/AlDanial/cloc/issues/849)
choco install cloc # Windows with Chocolatey
scoop install cloc # Windows with ScoopNote: I don't control any of these packages.
If you encounter a bug in cloc using one of the above
packages, try with cloc pulled from the latest stable release here
on GitHub (link follows below) before submitting a problem report.
Run via docker
These docker commands count lines of code in and below
the current directory:
docker run --rm -v $PWD:/tmp aldanial/cloc .Run via docker on git-bash
docker run --rm -v "/$(pwd -W)":/tmp aldanial/cloc .Development version
Download the cloc source code at https://github.com/AlDanial/cloc/raw/master/cloc and
save it as the file cloc (or cloc.pl, or whatever executable name you wish).
The next step depends on the operating system you're using.
License
cloc is licensed under the
GNU General Public License, v 2,
excluding portions which
are copied from other sources. Code
copied from the Regexp::Common, Win32::Autoglob, and Algorithm::Diff
Perl modules is subject to the
Artistic License.
Why Use cloc?
cloc has many features that make it easy to use, thorough, extensible, and portable:
- Exists as a single, self-contained file that requires minimal installation effort---just download the file and run it.
- Can read language comment definitions from a file and thus potentially work with computer languages that do not yet exist.
- Allows results from multiple runs to be summed together by language and by project.
- Can produce results in a variety of formats: plain text, Markdown, SQL, JSON, XML, YAML, comma separated values.
- Can count code within compressed archives (tar balls, Zip files, Java .ear files).
- Has numerous troubleshooting options.
- Handles file and directory names with spaces and other unusual characters.
- Has no dependencies outside the standard Perl distribution.
- Runs on Linux, FreeBSD, NetBSD, OpenBSD, macOS, AIX, HP-UX, Solaris, IRIX, and z/OS systems that have Perl 5.6 or higher. The source version runs on Windows with either ActiveState Perl, Strawberry Perl, Cygwin, or MobaXTerm+Perl plugin. Alternatively on Windows one can run the Windows binary which has no dependencies.
Other Counters
If cloc does not suit your needs here are other freely available counters to consider:
Other references:
- QSM's directory of code counting tools.
- The Wikipedia entry for source code line counts.
Regexp::Common, Digest::MD5, Win32::Autoglob, Algorithm::Diff
Although cloc does not need Perl modules outside those found in the
standard distribution, cloc does rely on a few external modules. Code
from three of these external modules--Regexp::Common, Win32::Autoglob,
and Algorithm::Diff--is embedded within cloc. A fourth module,
Digest::MD5, is used only if it is available. If cloc finds
Regexp::Common or Algorithm::Diff installed locally it will use those
installation. If it doesn't, cloc will install the parts of
Regexp::Common and/or Algorithm:Diff it needs to temporary directories
that are created at the start of a cloc run then removed when the run is
complete. The necessary code from Regexp::Common v2.120 and
Algorithm::Diff v1.1902 are embedded within the cloc source code (see
subroutines Install_Regexp_Common() and Install_Algorithm_Diff() ).
Only three lines are needed from Win32::Autoglob and these are included
directly in cloc.
Additionally, cloc will use Digest::MD5 to validate uniqueness among
equally-sized input files if Digest::MD5 is installed locally.
A parallel processing option, --processes=*N*, was introduced with
cloc version 1.76 to enable faster runs on multi-core machines. However,
to use it, one must have the module Parallel::ForkManager installed.
This module does not work reliably on Windows so parallel processing
will only work on Unix-like operating systems.
The Windows binary is built on a computer that has both Regexp::Common
and Digest::MD5 installed locally.
Building a Windows Executable
Create your own executable
The most robust option for creating a Windows executable of
cloc is to use ActiveState's Perl Development Kit.
It includes a utility, perlapp, which can build stand-alone
Windows, Mac, and Linux binaries of Perl source code.
perl2exe
will also do the trick. If you do have perl2exe, modify lines
84-87 in the cloc source code for a minor code
modification that is necessary to make a cloc Windows executable.
Otherwise, to build a Windows executable with pp fromPAR::Packer, first install a Windows-based Perl distribution
(for example Strawberry Perl or ActivePerl) following their
instructions. Next, open a command prompt, aka a DOS window and install
the PAR::Packer module. Finally, invoke the newly installed pp
command with the cloc source code to create an .exe file:
C:> cpan -i Digest::MD5
C:> cpan -i Regexp::Common
C:> cpan -i Algorithm::Diff
C:> cpan -i PAR::Packer
C:> cpan -i Win32::LongPath
C:> pp -M Win32::LongPath -M Encode::Unicode -M Digest::MD5 -c -x -o cloc-2.10.exe cloc-2.10.plA variation on the instructions above is if you installed the portable
version of Strawberry Perl, you will need to run portableshell.bat first
to properly set up your environment.
The Windows executable in the Releases section, cloc-2.10.exe,
was built on a 64 bit Windows 11 computer using
Strawberry Perl
5.32.1 and
PAR::Packer
to build the .exe.
Is the Windows executable safe to run? Does it have malware?
Ideally, no one would need the Windows executable because they
have a Perl interpreter installed on their machines and can
run the cloc source file.
On centrally-managed corporate Windows machines, however, this
this may be difficult or impossible.
The Windows executable distributed with cloc is provided as
a best-effort of a virus and malware-free .exe.
You are encouraged to run your own virus scanners against the
executable and also check sites such
https://www.virustotal.com/ .
The entries for recent versions are:
cloc-2.10.exe:
https://www.virustotal.com/gui/file/97786c4b5bb71d2be67e42061a2f5d03db73bbf88228f8710001d770e867bbef/detection
cloc-2.08.exe:
https://www.virustotal.com/gui/file/4529557d957ade0dd45746eae10e9c51ee01061bb617eeeab256672faf6e42c6?nocache=1
cloc-2.06.exe:
https://www.virustotal.com/gui/file/bbe48de9102d0f2520d292d65897001c1d068340eb7cd74dd1ee30c1a9091c4a?nocache=1
cloc-2.04.exe:
https://www.virustotal.com/gui/file/89cda0038bf4e13c6c13ebc1e60bec4dfad362e69ac8a5b8e2d5ebe3020359e1
cloc-2.02-winget.exe: (includes PR 850 to allow
running from a symlink on Windows)
https://www.virustotal.com/gui/file/be033061e091fea48a5bc9e8964cee0416ddd5b34bd5226a1c9aa4b30bdba66a?nocache=1
cloc-2.02.exe:
https://www.virustotal.com/gui/file/369ed76125f7399cd582d169adf39a2e08ae5066031fea0cc8b2836ea50e7ce2?nocache=1
cloc-2.00.exe:
https://www.virustotal.com/gui/file/7a234ef0cb495de1b5776acf88c5554e2bab1fb02725a5fb85756a6db3121c1f
Why is the Windows executable so large?
Windows executables of cloc versions 1.60 and earlier, created with
perl2exe as noted above, are about 1.6 MB, while versions 1.62 and 1.54, created
with PAR::Packer, are 11 MB.
Version 1.66, built with a newer version of PAR::Packer, is about 5.5 MB.
Why are the PAR::Packer, executables so
much larger than those built with perl2exe? My theory is that perl2exe
uses smarter tree pruning logic
than PAR::Packer, but that's pure speculation.
Basic Use
cloc is a command line program that takes file, directory, and/or
archive names as inputs. Here's an example of running cloc against the
Perl v5.22.0 source distribution:
/* Detailed source-code truncated for AI context efficiency. */To run cloc on Windows computers, open up a command (aka DOS) window
and invoke cloc.exe from the command line there.
Alternatively, try ClocViewer, the GUI wrapper around cloc found at
https://github.com/Roemer/ClocViewer.
See also https://github.com/jmensch1/codeflower for a
graphical rendering of cloc results.
GUI Frontends
Several GUI frontends to cloc are available:
- cloctui
- ClocViewer
- codeflower
- cloc-studio (for macOS)
Options
Full options list (cloc --help) (click the triangle to see all option)
/* Detailed source-code truncated for AI context efficiency. */Recognized Languages
Full language list (cloc --show-lang) (click the triangle to see all languages)
/* Detailed source-code truncated for AI context efficiency. */The above list can be customized by reading language definitions from a
file with the --read-lang-def or --force-lang-def options.
These file extensions map to multiple languages:
cjfiles could be Clojure or Cangjieclfiles could be Lisp or OpenCLclsfiles could be Visual Basic, TeX or Apex Classconffiles could be BitBake or plain textcsfiles could be C# or Smalltalkdfiles could be D or dtraceffiles could be Fortran 77 or Forthfncfiles could be Oracle PL or SQLforfiles could be Fortran 77 or Forthfsfiles could be F# or Forthincfiles could be PHP, Pascal, Fortran, Pawn, BitBake or Assemblyitkfiles could be Tcl or Tkjlfiles could be Lisp or Julialitfiles could be PL or Mmfiles could be MATLAB, Mathematica, Objective-C, MUMPS or Mercuryp6files could be Perl or Prologplfiles could be Perl or PrologPLfiles could be Perl or Prologppfiles could be Pascal or Puppetprofiles could be IDL, Qt Project, Prolog or ProGuardtsfiles could be TypeScript or Qt Linguistuifiles could be Qt or Gladevfiles could be Verilog-SystemVerilog or Coq
cloc has subroutines that attempt to identify the correct language based
on the file's contents for these special cases. Language identification
accuracy is a function of how much code the file contains; .m files with
just one or two lines for example, seldom have enough information to
correctly distinguish between MATLAB, Mercury, MUMPS, or Objective-C.
Languages with file extension collisions are difficult to customize with--read-lang-def or --force-lang-def as they have no mechanism to
identify languages with common extensions. In this situation one must
modify the cloc source code.
How It Works
cloc's method of operation resembles SLOCCount's: First, create a list
of files to consider. Next, attempt to determine whether or not found
files contain recognized computer language source code. Finally, for
files identified as source files, invoke language-specific routines to
count the number of source lines.
A more detailed description:
If the input file is an archive (such as a .tar.gz or .zip file),
create a temporary directory and expand the archive there using a
system call to an appropriate underlying utility (tar, bzip2, unzip,
etc) then add this temporary directory as one of the inputs. (This
works more reliably on Unix than on Windows.)Use File::Find to recursively descend the input directories and make
a list of candidate file names. Ignore binary and zero-sized files.Make sure the files in the candidate list have unique contents
(first by comparing file sizes, then, for similarly sized files,
compare MD5 hashes of the file contents with Digest::MD5). For each
set of identical files, remove all but the first copy, as determined
by a lexical sort, of identical files from the set. The removed
files are not included in the report. (The--skip-uniquenessswitch
disables the uniqueness tests and forces all copies of files to be
included in the report.) See also the--ignored=switch to see which
files were ignored and why.Scan the candidate file list for file extensions which cloc
associates with programming languages (see the--show-langand--show-extoptions). Files which match are classified as
containing source
code for that language. Each file without an extension is opened
and its first line read to see if it is a Unix shell script
(anything that begins with #!). If it is shell script, the file is
classified by that scripting language (if the language is
recognized). If the file does not have a recognized extension or is
not a recognized scripting language, the file is ignored.All remaining files in the candidate list should now be source files
for known programming languages. For each of these files:- Read the entire file into memory.
- Count the number of lines (= Loriginal).
- Remove blank lines, then count again (= Lnon_blank).
- Loop over the comment filters defined for this language. (For
example, C++ has two filters: (1) remove lines that start with
optional whitespace followed by // and (2) remove text between
/* and */) Apply each filter to the code to remove comments.
Count the left over lines (= Lcode). - Save the counts for this language:
- blank lines = Loriginal - Lnon_blank
- comment lines = Lnon_blank - Lcode
- code lines = Lcode
The options modify the algorithm slightly. The --read-lang-def option
for example allows the user to read definitions of comment filters,
known file extensions, and known scripting languages from a file. The
code for this option is processed between Steps 2 and 3.
Advanced Use
Remove Comments from Source Code
How can you tell if cloc correctly identifies comments? One way to
convince yourself cloc is doing the right thing is to use its--strip-comments option to remove comments and blank lines from files, then
compare the stripped-down files to originals.
Let's try this out with the SQLite amalgamation, a C file containing all
code needed to build the SQLite library along with a header file:
prompt> tar zxf sqlite-amalgamation-3.5.6.tar.gz
prompt> cd sqlite-3.5.6/
prompt> cloc --strip-comments=nc sqlite.c
1 text file.
1 unique file.
Wrote sqlite3.c.nc
0 files ignored.
http://cloc.sourceforge.net v 1.03 T=1.0 s (1.0 files/s, 82895.0 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code scale 3rd gen. equiv
-------------------------------------------------------------------------------
C 1 5167 26827 50901 x 0.77 = 39193.77
-------------------------------------------------------------------------------The extension argument given to --strip-comments is arbitrary; here nc was used as an abbreviation for "no comments".
cloc removed over 31,000 lines from the file:
prompt> wc -l sqlite3.c sqlite3.c.nc
82895 sqlite3.c
50901 sqlite3.c.nc
133796 total
prompt> echo "82895 - 50901" | bc
31994We can now compare the original file, sqlite3.c and the one stripped of
comments, sqlite3.c.nc with tools like diff or vimdiff and see what
exactly cloc considered comments and blank lines. A rigorous proof that
the stripped-down file contains the same C code as the original is to
compile these files and compare checksums of the resulting object files.
First, the original source file:
prompt> gcc -c sqlite3.c
prompt> md5sum sqlite3.o
cce5f1a2ea27c7e44b2e1047e2588b49 sqlite3.oNext, the version without comments:
prompt> mv sqlite3.c.nc sqlite3.c
prompt> gcc -c sqlite3.c
prompt> md5sum sqlite3.o
cce5f1a2ea27c7e44b2e1047e2588b49 sqlite3.ocloc removed over 31,000 lines of comments and blanks but did not modify the source code in any significant way since the resulting object file matches the original.
Work with Compressed Archives
Versions of cloc before v1.07 required an
--extract-with=CMD option to tell cloc how
to expand an archive file. Beginning with v1.07 this is extraction is
attempted automatically. At the moment the automatic extraction method works
reasonably well on Unix-type OS's for the following file types:.deb..ear,.gem,.tar.bz2,.tar.gz,.tar.xz,.tgz,.zip,
Some of these extensions work on Windows if one has WinZip installed
in the default location (C:\Program Files\WinZip\WinZip32.exe).
Additionally, with newer versions of WinZip, the
[http://www.winzip.com/downcl.htm](command line add-on)
is needed for correct operation; in this case one would invoke cloc with
something like
--extract-with="\"c:\Program Files\WinZip\wzunzip\" -e -o >FILE< ."
</code>Ref. http://sourceforge.net/projects/cloc/forums/forum/600963/topic/4021070?message=8938196
In situations where the automatic extraction fails, one can try the--extract-with=CMD
option to count lines of code within tar files, Zip files, or
other compressed archives for which one has an extraction tool.
cloc takes the user-provided extraction command and expands the archive
to a temporary directory (created with File::Temp),
counts the lines of code in the temporary directory,
then removes that directory. While not especially helpful when dealing
with a single compressed archive (after all, if you're going to type
the extraction command anyway why not just manually expand the archive?)
this option is handy for working with several archives at once.
For example, say you have the following source tarballs on a Unix machine
perl-5.8.5.tar.gz
Python-2.4.2.tar.gzand you want to count all the code within them. The command would be
cloc --extract-with='gzip -dc >FILE< | tar xf -' perl-5.8.5.tar.gz Python-2.4.2.tar.gzIf that Unix machine has GNU tar (which can uncompress and extract in
one step) the command can be shortened to
cloc --extract-with='tar zxf >FILE<' perl-5.8.5.tar.gz Python-2.4.2.tar.gzOn a Windows computer with WinZip installed inc:\Program Files\WinZip the command would look like
cloc.exe --extract-with="\"c:\Program Files\WinZip\WinZip32.exe\" -e -o >FILE< ." perl-5.8.5.tar.gz Python-2.4.2.tar.gzJava .ear files are Zip files that contain additional Zip
files. cloc can handle nested compressed archives without
difficulty--provided all such files are compressed and archived in the
same way. Examples of counting a
Java .ear file in Unix and Windows:
Unix> cloc --extract-with="unzip -d . >FILE< " Project.ear
DOS> cloc.exe --extract-with="\"c:\Program Files\WinZip\WinZip32.exe\" -e -o >FILE< ." Project.earDifferences
The --diff switch allows one to measure the relative change in
source code and comments between two versions of a file, directory,
or archive. Differences reveal much more than absolute code
counts of two file versions. For example, say a source file
has 100 lines and its developer delivers a newer version with
102 lines. Did the developer add two comment lines,
or delete seventeen source
lines and add fourteen source lines and five comment lines, or did
the developer
do a complete rewrite, discarding all 100 original lines and
adding 102 lines of all new source? The diff option tells how
many lines of source were added, removed, modified or stayed
the same, and how many lines of comments were added, removed,
modified or stayed the same.
Differences in blank lines are handled much more coarsely
because these are stripped by cloc early on. Unless a
file pair is identical, cloc will report only differences
in absolute counts of blank lines. In other words, one
can expect to see only entries for 'added' if the second
file has more blanks than the first, and 'removed' if the
situation is reversed. The entry for 'same' will be non-zero
only when the two files are identical.
In addition to file pairs, one can give cloc pairs of
directories, or pairs of file archives, or a file archive
and a directory. cloc will try to align
file pairs within the directories or archives and compare diffs
for each pair. For example, to see what changed between
GCC 4.4.0 and 4.5.0 one could do
cloc --diff gcc-4.4.0.tar.bz2 gcc-4.5.0.tar.bz2Be prepared to wait a while for the results though; the --diff
option runs much more slowly than an absolute code count.
To see how cloc aligns files between the two archives, use the--diff-alignment option
cloc --diff-alignment=align.txt gcc-4.4.0.tar.bz2 gcc-4.5.0.tar.bz2to produce the file align.txt which shows the file pairs as well
as files added and deleted. The symbols == and != before each
file pair indicate if the files are identical (==)
or if they have different content (!=).
Here's sample output showing the difference between the Python 2.6.6 and 2.7
releases:
/* Detailed source-code truncated for AI context efficiency. */A pair of errors occurred.
The first pair was caused by timing out when computing diffs of the filePython-X/Mac/Modules/qt/_Qtmodule.c in each Python version.
This file has > 26,000 lines of C code and takes more than
10 seconds--the default maximum duration for diff'ing a
single file--on my slow computer. (Note: this refers to
performing differences with
the sdiff() function in the Perl Algorithm::Diff module,
not the command line diff utility.) This error can be
overcome by raising the time to, say, 20 seconds
with --diff-timeout 20.
The second error is more problematic. The filesPython-X/Mac/Modules/qd/qdsupport.py
include Python docstring (text between pairs of triple quotes)
containing C comments. cloc treats docstrings as comments and handles them
by first converting them to C comments, then using the C comment removing
regular expression. Nested C comments yield erroneous results however.
Create Custom Language Definitions
cloc can write its language comment definitions to a file or can read
comment definitions from a file, overriding the built-in definitions.
This can be useful when you want to use cloc to count lines of a
language not yet included, to change association of file extensions
to languages, or to modify the way existing languages are counted.
The easiest way to create a custom language definition file is to
make cloc write its definitions to a file, then modify that file:
Unix> cloc --write-lang-def=my_definitions.txtcreates the file my_definitions.txt which can be modified
then read back in with either the --read-lang-def or--force-lang-def option. The difference between the options is
former merges language definitions from the given file in with
cloc's internal definitions with cloc's taking precedence
if there are overlaps. The --force-lang-def option, on the
other hand, replaces cloc's definitions completely.
This option has a disadvantage in preventing cloc from counting
languages whose extensions map to multiple languages
as these languages require additional logic that is not easily
expressed in a definitions file.
Unix> cloc --read-lang-def=my_definitions.txt file1 file2 dir1 ...Each language entry has four parts:
- The language name starting in column 1.
- One or more comment filters starting in column 5.
- One or more filename extensions starting in column 5.
- A 3rd generation scale factor starting in column 5.
This entry must be provided
but its value is not important
unless you want to compare your language to a hypothetical
third generation programming language.
A filter defines a method to remove comment text from the source file.
For example the entry for C++ looks like this
C++
filter call_regexp_common C++
filter remove_inline //.*$
extension C
extension c++
extension cc
extension cpp
extension cxx
extension pcc
3rd_gen_scale 1.51
end_of_line_continuation \\$C++ has two filters: first, remove lines matching
Regexp::Common's C++ comment regex.
The second filter using remove_inline is currently
unused. Its intent is to identify lines with both
code and comments and it may be implemented in the future.
A more complete discussion of the different filter options may appear
here in the future. The output of cloc's--write-lang-def option should provide enough examples
for motivated individuals to modify or extend cloc's language definitions.
Combine Reports
If you manage multiple software projects you might be interested in
seeing line counts by project, not just by language.
Say you manage three software projects called MariaDB, PostgreSQL, and SQLite.
The teams responsible for each of these projects run cloc on their
source code and provide you with the output.
For example, the MariaDB team does
cloc --out mariadb-10.1.txt mariadb-server-10.1.zipand provides you with the file mariadb-10.1.txt.
The contents of the three files you get are
/* Detailed source-code truncated for AI context efficiency. */While these three files are interesting, you also want to see
the combined counts from all projects.
That can be done with cloc's --sum_reports
option:
Unix> cloc --sum-reports --out=databases mariadb-10.1.txt sqlite-3081101.txt postgresql-9.4.4.txt
Wrote databases.lang
Wrote databases.fileThe report combination produces two output files, one for sums by
programming language (databases.lang) and one by project
(databases.file).
Their contents are
/* Detailed source-code truncated for AI context efficiency. */Report files themselves can be summed together. Say you also manage
development of Perl and Python and you want to keep track
of those line counts separately from your database projects. First
create reports for Perl and Python separately:
cloc --out perl-5.22.0.txt perl-5.22.0.tar.gz
cloc --out python-2.7.10.txt Python-2.7.10.tar.xzthen sum these together with
/* Detailed source-code truncated for AI context efficiency. */Finally, combine the combination files:
/* Detailed source-code truncated for AI context efficiency. */One limitation of the --sum-reports feature is that the individual counts must
be saved in the plain text format. Counts saved as
XML, JSON, YAML, or SQL will produce errors if used in a summation.
SQL
Cloc can write results in the form of SQL table create and insert
statements for use
with relational database programs such as SQLite, MySQL,
PostgreSQL, Oracle, or Microsoft SQL.
Once the code count information is in a database,
the information can be interrogated and displayed in interesting ways.
A database created from cloc SQL output has two tables,
metadata and t:
Table metadata:
| Field | Type |
|---|---|
| id | integer primary key |
| timestamp | text |
| project | text |
| elapsed_s | text |
Table t:
| Field | Type |
|---|---|
| project | text |
| language | text |
| file | text |
| nBlank | integer |
| nComment | integer |
| nCode | integer |
| nScaled | real |
| foreign key (id) | references metadata (id) |
The metadata table contains information about when the cloc run
was made. Run time is stored two ways: as Unix epoch
seconds in id and as an ISO 8601 formatted text string
in the local time zone
(for example 2024-03-01 14:19:41) in timestamp.
The --sql-append switch allows one to combine
many runs in a single database; each run adds a
row to the metadata table.
The code count information resides in table t.
The id key makes it easy to associate a run's code count with
its metadata.
Let's repeat the code count examples of Perl, Python, SQLite, MySQL and
PostgreSQL tarballs shown in the
Combine Reports
example above, this time
using the SQL output options and the
SQLite
database engine.
The --sql switch tells cloc to generate output in the form
of SQL table create and insert commands. The switch takes
an argument of a file name to write these SQL statements into, or,
if the argument is 1 (numeric one), streams output to STDOUT.
Since the SQLite command line program, sqlite3, can read
commands from STDIN, we can dispense with storing SQL statements to
a file and use --sql 1 to pipe data directly into the
SQLite executable:
cloc --sql 1 --sql-project mariadb mariadb-server-10.1.zip | sqlite3 code.dbThe --sql-project mariadb part is optional; there's no need
to specify a project name when working with just one code base. However,
since we'll be adding code counts from four other tarballs, we'll only
be able to identify data by input source if we supply a
project name for each run.
Now that we have a database we will need to pass in the --sql-append
switch to tell cloc not to wipe out this database but instead add more data:
cloc --sql 1 --sql-project postgresql --sql-append postgresql-9.4.4.tar.bz2 | sqlite3 code.db
cloc --sql 1 --sql-project sqlite --sql-append sqlite-amalgamation-3081101.zip | sqlite3 code.db
cloc --sql 1 --sql-project python --sql-append Python-2.7.10.tar.xz | sqlite3 code.db
cloc --sql 1 --sql-project perl --sql-append perl-5.22.0.tar.gz | sqlite3 code.dbNow the fun begins--we have a database, code.db, with lots of
information about the five projects and can query it
for all manner of interesting facts.
Which is the longest file over all projects?
prompt> sqlite3 code.db 'select project,file,nBlank+nComment+nCode as nL from t
where nL = (select max(nBlank+nComment+nCode) from t)'
sqlite|sqlite-amalgamation-3081101/sqlite3.c|161623sqlite3's default output format leaves a bit to be desired.
We can add an option to the program's rc file,~/.sqliterc, to show column headers:
.header onOne might be tempted to also include
.mode columnin ~/.sqliterc but this causes problems when the output has more than
one row since the widths of entries in the first row govern the maximum
width for all subsequent rows. Often this leads to truncated output--not
at all desirable. One option is to write a custom SQLite output
formatter such as sqlite_formatter, included with cloc.
To use it, simply pass sqlite3's STDOUT into sqlite_formatter
via a pipe:
prompt> sqlite3 code.db 'select project,file,nBlank+nComment+nCode as nL from t
where nL = (select max(nBlank+nComment+nCode) from t)' | ./sqlite_formatter
-- Loading resources from ~/.sqliterc
Project File nL
_______ _____________________________________ ______
sqlite sqlite-amalgamation-3081101/sqlite3.c 161623If the "Project File" line doesn't appear, add .header on to your~/.sqliterc file as explained above.
What is the longest file over all projects?
prompt> sqlite3 code.db 'select project,file,nBlank+nComment+nCode as nL from t
where nL = (select max(nBlank+nComment+nCode) from t)' | sqlite_formatter
Project File nL
_______ _____________________________________ ______
sqlite sqlite-amalgamation-3081101/sqlite3.c 161623What is the longest file in each project?
prompt> sqlite3 code.db 'select project,file,max(nBlank+nComment+nCode) as nL from t
group by project order by nL;' | sqlite_formatter
Project File nL
__________ ________________________________________________________________ ______
python Python-2.7.10/Mac/Modules/qt/_Qtmodule.c 28091
postgresql postgresql-9.4.4/src/interfaces/ecpg/preproc/preproc.c 54623
mariadb server-10.1/storage/mroonga/vendor/groonga/lib/nfkc.c 80246
perl perl-5.22.0/cpan/Locale-Codes/lib/Locale/Codes/Language_Codes.pm 100747
sqlite sqlite-amalgamation-3081101/sqlite3.c 161623Which files in each project have the most code lines?
prompt> sqlite3 code.db 'select project,file,max(nCode) as nL from t
group by project order by nL desc;' | sqlite_formatter
Project File nL
__________ ________________________________________________________________ ______
perl perl-5.22.0/cpan/Locale-Codes/lib/Locale/Codes/Language_Codes.pm 100735
sqlite sqlite-amalgamation-3081101/sqlite3.c 97469
mariadb server-10.1/storage/mroonga/vendor/groonga/lib/nfkc.c 80221
postgresql postgresql-9.4.4/src/interfaces/ecpg/preproc/preproc.c 45297
python Python-2.7.10/Mac/Modules/qt/_Qtmodule.c 26705Which C source files with more than 300 lines have a comment ratio below 1%?
/* Detailed source-code truncated for AI context efficiency. */What are the ten longest files (based on code lines) that have no comments at all? Exclude header, .html, and YAML files.
prompt> sqlite3 code.db 'select project, file, nCode from t
where nComment = 0 and
language not in ("C/C++ Header", "YAML", "HTML")
order by nCode desc limit 10;' | sqlite_formatter
Project File nCode
_______ ____________________________________________________________________ _____
perl perl-5.22.0/cpan/Unicode-Collate/Collate/Locale/ja.pl 1938
python Python-2.7.10/PCbuild/pythoncore.vcproj 1889
python Python-2.7.10/PC/VS8.0/pythoncore.vcproj 1889
mariadb server-10.1/mysql-test/extra/binlog_tests/mysqlbinlog_row_engine.inc 1862
perl perl-5.22.0/cpan/Unicode-Collate/Collate/Locale/zh_strk.pl 1589
perl perl-5.22.0/cpan/Unicode-Collate/Collate/Locale/zh_zhu.pl 1563
mariadb server-10.1/storage/mroonga/vendor/groonga/configure.ac 1526
perl perl-5.22.0/cpan/Unicode-Collate/Collate/Locale/zh_pin.pl 1505
mariadb server-10.1/mysql-test/suite/funcs_1/storedproc/storedproc_02.inc 1465
python Python-2.7.10/PC/VS8.0/_bsddb.vcproj 1463What are the most popular languages (in terms of lines
of code) in each project?
/* Detailed source-code truncated for AI context efficiency. */Custom Column Output
Cloc's default output is a text table with five columns:
language, file count, number of blank lines, number of comment
lines and number of code lines. The switches --by-file,--3, and --by-percent generate additional information but
sometimes even those are insufficient.
The --sql option described in the previous section offers the
ability to create custom output. This section has a pair of examples
that show how to create custom columns.
The first example includes an extra column, Total, which is the
sum of the numbers of blank, comment, and code lines.
The second shows how to include the language name when running
with --by-file.
Example 1: Add a "Totals" column.
The first step is to run cloc and save the output to a relational database,
SQLite in this case:
cloc --sql 1 --sql-project x yaml-cpp-yaml-cpp-0.5.3.tar.gz | sqlite3 counts.db(the tar file comes from the
YAML-C++ project).
Second, we craft an SQL query that returns the regular cloc output
plus an extra column for totals, then save the SQL statement to
a file, query_with_totals.sql:
-- file query_with_totals.sql
select Language, count(File) as files ,
sum(nBlank) as blank ,
sum(nComment) as comment ,
sum(nCode) as code ,
sum(nBlank)+sum(nComment)+sum(nCode) as Total
from t group by Language order by code desc;Third, we run this query through SQLite using the counts.db database.
We'll include the -header switch so that SQLite prints the
column names:
> cat query_with_totals.sql | sqlite3 -header counts.db
Language|files|blank|comment|code|Total
C++|141|12786|17359|60378|90523
C/C++ Header|110|8566|17420|51502|77488
Bourne Shell|10|6351|6779|38264|51394
m4|11|2037|260|17980|20277
Python|30|1613|2486|4602|8701
MSBuild script|11|0|0|1711|1711
CMake|7|155|285|606|1046
make|5|127|173|464|764
Markdown|2|30|0|39|69The extra column for Total is there but the format is unappealing.
Running the output through sqlite_formatter yields the desired result:
> cat query_with_totals.sql | sqlite3 -header counts.db | sqlite_formatter
Language files blank comment code Total
______________ _____ _____ _______ _____ _____
C++ 141 12786 17359 60378 90523
C/C++ Header 110 8566 17420 51502 77488
Bourne Shell 10 6351 6779 38264 51394
m4 11 2037 260 17980 20277
Python 30 1613 2486 4602 8701
MSBuild script 11 0 0 1711 1711
CMake 7 155 285 606 1046
make 5 127 173 464 764
Markdown 2 30 0 39 69The next section,
Wrapping cloc in other scripts,
shows one way these commands can be combined
into a new utility program.
Example 2: Include a column for "Language" when running with --by-file.
Output from --by-file omits each file's language to save screen real estate;
file paths for large projects can be long and including an extra 20 or so
characters for a Language column can be excessive.
As an example, here are the first few lines of output using the same
code base as in Example 1:
/* Detailed source-code truncated for AI context efficiency. */The absence of language identification for each file
is a bit disappointing, but
this can be remedied with a custom column solution.
The first step, creating a database, matches that from Example 1 so
we'll go straight to the second step of creating the desired
SQL query. We'll store this one in the file by_file_with_language.sql:
-- file by_file_with_language.sql
select File, Language, nBlank as blank ,
nComment as comment,
nCode as code
from t order by code desc;Our desired extra column appears when we pass this custom SQL query
through our database:
/* Detailed source-code truncated for AI context efficiency. */Wrapping cloc in other scripts
More complex code counting solutions are possible by wrapping
cloc in scripts or programs. The "total lines" column from
example 1 of Custom Column Output
could be simplified to a single command with this shell script (on Linux):
#!/bin/sh
#
# These commands must be in the user's $PATH:
# cloc
# sqlite3
# sqlite_formatter
#
if test $# -eq 0 ; then
echo "Usage: $0 [cloc arguments]"
echo " Run cloc to count lines of code with an additional"
echo " output column for total lines (code+comment+blank)."
exit
fi
DBFILE=`tempfile`
cloc --sql 1 --sql-project x $@ | sqlite3 ${DBFILE}
SQL="select Language, count(File) as files ,
sum(nBlank) as blank ,
sum(nComment) as comment ,
sum(nCode) as code ,
sum(nBlank)+sum(nComment)+sum(nCode) as Total
from t group by Language order by code desc;
"
echo ${SQL} | sqlite3 -header ${DBFILE} | sqlite_formatter
rm ${DBFILE}Saving the lines above to total_columns.sh and making it
executable (chmod +x total_columns.sh) would let us do
./total_columns.sh yaml-cpp-yaml-cpp-0.5.3.tar.gzto directly get
Language files blank comment code Total
______________ _____ _____ _______ _____ _____
C++ 141 12786 17359 60378 90523
C/C++ Header 110 8566 17420 51502 77488
Bourne Shell 10 6351 6779 38264 51394
m4 11 2037 260 17980 20277
Python 30 1613 2486 4602 8701
MSBuild script 11 0 0 1711 1711
CMake 7 155 285 606 1046
make 5 127 173 464 764
Markdown 2 30 0 39 69Other examples:
- Count code from a specific branch of a web-hosted
git repository and send the results as a .csv email attachment:
https://github.com/dannyloweatx/checkmarx
git and UTF8 pathnames
cloc's --git option may fail if you work with directory or
file names with UTF-8 characters (for example, see
issue 457).
The solution,
https://stackoverflow.com/questions/22827239/how-to-make-git-properly-display-utf-8-encoded-pathnames-in-the-console-window,
is to apply this git configuration command:
git config --global core.quotepath offYour console's font will need to be capable of displaying
Unicode characters.
Third Generation Language Scale Factors
cloc versions before 1.50 by default computed, for the provided inputs, a
rough estimate of how many lines of code would be needed to write the
same code in a hypothetical third-generation computer language.
To produce this output one must now use the --3 switch.
Scale factors were derived from the 2006 version of language gearing ratios
listed at Mayes Consulting web site,
http://softwareestimator.com/IndustryData2.htm, using this equation:
cloc scale factor for language X = 3rd generation default gearing ratio / language X gearing ratio
For example, cloc 3rd generation scale factor for DOS Batch = 80 / 128 = 0.625.
The biggest flaw with this approach is that gearing ratios are defined
for logical lines of source code not physical lines (which cloc counts).
The values in cloc's 'scale' and '3rd gen. equiv.' columns should be
taken with a large grain of salt.
options.txt configuration file
If you find yourself using the same command line switches every
time you invoke cloc, you can save some typing by adding those
switches to the options.txt runtime configuration file.
cloc will look for this file in the following default locations:
# Linux, NetBSD, FreeBSD, macOS:
/home/USERNAME/.config/cloc/options.txt
# Windows
C:\Users\USERNAME\AppData\Roaming\clocIf you run cloc with --help, cloc will tell you
where it expects to find this config file file. The information
appears by the explanation of the --config switch after
the text the default location of.
On Unix-like operating systems, this can be simplified to
> cloc --help | grep "default location"
the default location of /home/al/.config/cloc/options.txt.and in a Windows cmd terminal with
> cloc --help | findstr default | findstr location
the default location of C:\Users\al\AppData\Roaming\clocPlace each switch and arguments, if any, on a line by itself.
Lines prefixed with # symbol are ignored as comments and
blank lines are skipped. Leading hyphens on the switches are
optional. Here's a sample file:
# options.txt
--vcs git
v # verbose level 1
exclude-ext svg,htmlThe path to the options.txt file can also be specified
with the --config FILE switch.
Finally, if cloc finds an options.txt file in the same
directory as files given by any of these switches (in the
listed priority), it will use that configuration file
from that location:
--list-file--exclude-list-file--read-lang-def--force-lang-def--diff-list-file
Run with --verbose to have cloc tell you which, if
any, options.txt file it uses.
Python Programmatic Interface
Stefano Campanella
created a Python programmatic interface to cloc.
It is available at https://github.com/pycloc/pycloc
Java Programmatic Interface
Ozren DabiΔ
created a Java programmatic interface to cloc.
It is available at https://github.com/seart-group/jcloc
Complex regular subexpression recursion limit
cloc relies on the Regexp::Common module's regular expressions to remove
comments from source code. If comments are malformed, for example the/* start comment marker appears in a C program without a corresponding */
marker, the regular expression engine could enter a recursive
loop, eventually triggering the warningComplex regular subexpression recursion limit.
The most common cause for this warning is the existence of comment markers
in string literals. While language compilers and interpreters are smart
enough to recognize that "/*" (for example) is a string and not a comment,
cloc is fooled. File path globs, as in this line of JavaScript
var paths = globArray("**/*.js", {cwd: srcPath});are frequent culprits.
In an attempt to overcome this problem, a different
algorithm which removes comment markers in strings can be enabled
with the --strip-str-comments switch. Doing so, however,
has drawbacks: cloc
will run more slowly and the output of --strip-comments
will contain strings that no longer match the input source.
Limitations
Identifying comments within source code is trickier than one might expect.
Many languages would need a complete parser to be counted correctly.
cloc does not attempt to parse any of
the languages it aims to count and therefore is an imperfect tool.
The following are known problems:
- Lines containing both source code and comments are counted as lines of code.
- Comment markers within strings or
[here-documents](http://www.faqs.org/docs/abs/HTML/here-docs.html)
are treated as actual comment markers and not string literals.
For example the following lines of C code
```
printf(" /* ");
for (i = 0; i < 100; i++) {
a += i;
}
printf(" */ ");
```
look to cloc like this:
```
printf(" xxxxxxx
xxxxxxx
xxxxxxx
xxxxxxx
xxxxxxx ");
```
where `xxxxxxx` represents cloc's view of commented text.
Therefore cloc counts the five lines as two lines of C code and three
lines of comments (lines with both code and comment are counted as code).
If you suspect your code has such strings, use the switch
--strip-str-commentsto switch to the algorithm which removes
embedded comment markers. Its use will render the five lines above astextprintf(" "); for (i = 0; i < 100; i++) { a += i; } printf(" ");and therefore return a count of five lines of code.
See the
previous section
on drawbacks to using--strip-str-comments. - Embedded languages are not recognized. For example, an HTML file containing JavaScript will be counted entirely as HTML.
- Python docstrings can serve several purposes. They may contain documentation, comment out blocks of code, or they can be regular strings (when they appear on the right hand side of an assignment or as a function argument). cloc is unable to infer the meaning of docstrings by context; by default cloc treats all docstrings as comments. The switch `--docstring-as-code` treats all docstrings as code.
- Language definition files read with `--read-lang-def` or `--force-lang-def` must be plain ASCII text files.
- cloc treats compiler pragma's, for example `#if` / `#endif`, as code even if these are used to block lines of source from being compiled; the blocked lines still contribute to the code count.
- On Windows, cloc will fail with Can't cd to ... No such file or directory at /File/Find.pm if the code being scanned has file paths longer than 255 characters. A work-around is to run cloc from the Windows Subsystem for Linux (WSL).
- cloc's comment match code uses regular expressions which cannot properly account for nested comments using the same comment markers (such as `/* /* */ */`).
- XML comments embedded within `CDATA` blocks are counted as comments rather than code.
Support for Additional Languages
If cloc does not recognize a language you are interested in counting,
you can either
Implement an Additional Language
In short, you will need to:
edit the
clocfile:look for
%{$rh_Language_by_Extension} = ( # {{{1and add, respecting the alphabetical order,text'<ext>' => '<Language Name>' ,where
<ext>is the extension used by your language, and<Language Name>is its name. Repeat for each extension used by your language.look for
%{$rhaa_Filters_by_Language} = ( # {{{1, and add, respecting the alphabetical order,
text'<Language Name>' => [ <list> ],where
<Language Name>is the name of the language you are implementing, and<list>is a list of filter options (whose documentation remains to be written -- take inspiration from existing languages).look for
%{$rh_Scale_Factor} = ( # {{{1, and add, respecting the alphabetical order,text'<Language Name>' => <factor>,where
<Language Name>is the name of the language you are implementing, and<factor>is a third generation language scale factor.
edit the
Readme.mdfile, adding under "Recognized Languages"text<Language Name> (<list of extensions>)for
<Language Name>the name of the language you are implementing, and<list of extensions>the list of extensions you declared inrh_Language_by_Extension.(optional, but recommended) Add a test case:
Create a
tests/inputs/<Language name>.<extension>file, containing some code written in<Language name>,Generate a
βtests/outputs/<Language name>.<extension>.yamlfile, usingtextcloc --yaml tests/inputs/<Language name>.<extension> --out βtests/outputs/<Language name>.<extension>.yamlAdd your case in
Unix/t/00_C.t: undermy @Tests = (, addtext{ 'name' => '<Language name>', 'ref' => '../tests/outputs/<Language name>.<extension>.yaml', 'args' => '../tests/inputs/<Language name>.<extension>', },Make sure you examine the output of
βtests/outputs/<Language name>.<extension>.yamland that it is correct, then runmake testfrom theUnixfolder to make sure your test was successful.
You can use this pull request or this one as guidelines.
Request an Additional Language
Create a GitHub issue
requesting support for your language. Include this information:
- File extensions associated with the language. If the language does not rely on file extensions and instead works with fixed file names or with `#!` style program invocations, explain what those are.
- A description of how comments are defined.
- Links to sample code.
Reporting Problems
If you encounter a problem with cloc, first check to see if
you're running with the latest version of the tool:
cloc --versionIf the version is older than the most recent release
at https://github.com/AlDanial/cloc/releases, download the
latest version and see if it solves your problem.
If the problem happens with the latest release, submit
a new issue at https://github.com/AlDanial/cloc/issues only
if you can supply enough information for anyone reading the
issue report to reproduce the problem.
That means providing
- the operating system you're running on
- the cloc command with all options
- the code you are counting (URL to a public git repo or zip file or tar file, et cetera)
Problem reports that cannot be reproduced will be ignored and
eventually closed.
Citation
Please use the following bibtex entry to cite cloc in a publication:
@software{adanial_cloc,
author = {Albert Danial},
title = {cloc: v2.10},
month = jan,
year = 2026,
publisher = {Zenodo},
version = {v2.10},
doi = {10.5281/zenodo.18364352},
url = {https://doi.org/10.5281/zenodo.18364352}
}(Update the version number and corresponding year if this
entry is outdated.)
Acknowledgments
Wolfram RΓΆsler provided most of the code examples in the test suite.
These examples come from his Hello World collection.
Ismet Kursunoglu found errors with the MUMPS counter and provided
access to a computer with a large body of MUMPS code to test cloc.
Tod Huggins gave helpful suggestions for the Visual Basic filters.
Anton Demichev found a flaw with the JSP counter in cloc v0.76
and wrote the XML output generator for the --xml option.
Reuben Thomas pointed out that ISO C99 allows // as a comment
marker, provided code for the --no3 and --stdin-name
options, counting the m4 language,
and suggested several user-interface enhancements.
Michael Bello provided code for the --opt-match-f,--opt-not-match-f,--opt-match-d, and --opt-not-match-d
options.
Mahboob Hussain inspired the --original-dir and--skip-uniqueness options, found a
bug in the duplicate file detection logic and improved the JSP filter.
Randy Sharo found and fixed an uninitialized variable bug for shell
scripts having only one line.
Steven Baker found and fixed a problem with the YAML output generator.
Greg Toth provided code to improve blank line detection in COBOL.
Joel Oliveira provided code to let --exclude-list-file handle
directory name exclusion.
Blazej Kroll provided code to produce an XSLT file, cloc-diff.xsl,
when producing XML output for the --diff option.
Denis Silakov enhanced the code which generates cloc.xsl when
using --by-file and --by-file-by-lang options, and
provided an XSL file that works with --diff output.
Andy ([email protected]) provided code to fix several bugs:
correct output of --counted
so that only files that are used in the code count appear and
that results are shown by language rather than file name;
allow --diff output from multiple runs to be summed
together with --sum-reports.
Jari Aalto created the initial version of cloc.1.pod and
maintains the Debian package for cloc.
Mikkel Christiansen ([email protected]) provided counter definitions
for Clojure and ClojureScript.
Vera Djuraskovic from Webhostinggeeks.com
provided the
Serbo-Croatian
translation.
Gill Ajoft of Ajoft Software
provided the
Bulgarian
translation.
The
Knowledge Team
provided the
Slovakian translation.
Erik Gooven Arellano Casillas provided an update to the MXML counter to
recognize ActionScript comments.
Gianluca Casati created the
cloc CPAN package.
Ryan Lindeman implemented the --by-percent feature.
Kent C. Dodds, @kentcdodds,
created and maintains the npm package of cloc.
Viktoria Parnak
provided the
Ukrainian
translation.
Natalie Harmann provided the
Belarussian
translation.
Nithyal at Healthcare Administration Portal
provided the
Tamil
translation.
Patricia Motosan
provided the
Romanian
translation.
Gajk Melikyan provided the
provided the
Armenian translation
for http://studybay.com.
Hungarian translation
courtesy of Zsolt Boros.
Sietse Snel implemented the parallel
processing capability available with the --processes=*N*
switch.
The development of cloc was partially funded by the Northrop Grumman
Corporation.
Copyright
Copyright (c) 2006-2026, Al Danial