cloc counts blank lines, comment lines, and physical lines of source code in many programming languages.

Subscribe to updates I use cloc

Statistics on cloc

Number of watchers on Github 4338
Number of open issues 14
Average time to close an issue 10 days
Main language Perl
Average time to merge a PR 2 days
Open pull requests 2+
Closed pull requests 10+
Last commit about 1 month ago
Repo Created over 2 years ago
Repo Last Updated about 1 month ago
Size 2.21 MB
Organization / Authoraldanial
Latest Releasev1.76
Page Updated
Do you use cloc? Leave a review!
View open issues (14)
View cloc activity
View on github
Latest Open Source Launches
Trendy new open source projects in your inbox! View examples

Subscribe to our mailing list

Evaluating cloc for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)


Count Lines of Code

cloc counts blank lines, comment lines, and physical lines of source code in many programming languages.

Latest release: v1.76 (February 9, 2018)

Hosted at since August 2006, cloc began the transition to GitHub in September 2015.

Quick Start ▲

Step 1: Download cloc (several methods, see below).

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 ( or a Windows executable (cloc-1.76.exe). On this page, cloc is the generic term used to refer to any of these.

a file

prompt> cloc hello.c
       1 text file.
       1 unique file.
       0 files ignored. 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. 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

prompt> 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

prompt> cd pudb

prompt> cloc 6be804e07a5db
      48 text files.
      48 unique files.
      15 files ignored. v 1.73  T=0.15 s (223.1 files/s, 46159.0 lines/s)
Language                     files          blank        comment           code
Python                          28           1519            728           4659
YAML                             2              9              2             75
Bourne Shell                     3              6              0             17
make                             1              4              6             10
SUM:                            34           1538            736           4761

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:

prompt> for d in ./*/ ; do (cd "$d" && echo "$d" && cloc --vcs git); done
7 text files.
       7 unique files.
       1 file ignored. v 1.71  T=0.02 s (390.2 files/s, 25687.6 lines/s)
Language                     files          blank        comment           code
D                                4             61             32            251
Markdown                         1              9              0             38
make                             1              0              0              4
SUM:                             6             70             32            293
       7 text files.
       7 unique files.
       0 files ignored. v 1.71  T=0.02 s (293.0 files/s, 52107.1 lines/s)
Language                     files          blank        comment           code
Go                               7            165            282            798
SUM:                             7            165            282            798
      49 text files.
      47 unique files.
      13 files ignored. v 1.71  T=0.10 s (399.5 files/s, 70409.4 lines/s)
Language                     files          blank        comment           code
Python                          33           1226           1026           3017
C                                4            327            337            888
Markdown                         1             11              0             28
YAML                             1              0              2             12
SUM:                            39           1564           1365           3945

Overview ▲

Translations: Arabic, Armenian, Belarussian, Bulgarian, Hungarian, Portuguese, Serbo-Croatian, Romanian, Slovakian, Tamil

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, Mac OS X, 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, 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.)

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

Install via package manager

Depending your operating system, one of these installation methods may work for you:

npm install -g 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
sudo emerge -av dev-util/cloc          # Gentoo
sudo apk add cloc                      # Alpine Linux
sudo pkg install cloc                  # FreeBSD
sudo port install cloc                 # Mac OS X with MacPorts
brew install cloc                      # Mac OS X with Homebrew
choco install cloc                     # Windows with Chocolatey
scoop install cloc                     # Windows with Scoop

Note: 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.

Stable release

Development version

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:

  1. Exists as a single, self-contained file that requires minimal installation effort---just download the file and run it.
  2. Can read language comment definitions from a file and thus potentially work with computer languages that do not yet exist.
  3. Allows results from multiple runs to be summed together by language and by project.
  4. Can produce results in a variety of formats: plain text, SQL, JSON, XML, YAML, comma separated values.
  5. Can count code within compressed archives (tar balls, Zip files, Java .ear files).
  6. Has numerous troubleshooting options.
  7. Handles file and directory names with spaces and other unusual characters.
  8. Has no dependencies outside the standard Perl distribution.
  9. Runs on Linux, FreeBSD, NetBSD, OpenBSD, Mac OS X, 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:

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 multicored 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 ▲

The Windows downloads cloc-1.70.exe and cloc-1.72.exe were built with PAR::Packer and Strawberry Perl on an Amazon Web Services t2.micro instance running Microsoft Windows Server 2008 (32 bit for 1.70 and 1.72; 64 bit for 1.74).

The 1.74 and 1.76 releases, cloc-1.74_x86.exe and cloc-1.76.exe, were was built on a 32 bit Windows 7 virtual machine ( pulled from using Strawberry Perl

The cloc-1.66.exe executable was built with PAR::Packer on a 32 bit Windows 7 VirtualBox image pulled from and running on an Ubuntu 15.10 host. The virtual machine ran Strawberry Perl version 5.22.1. Windows executables of cloc versions 1.60 and earlier were built with perl2exe on a 32 bit Windows XP computer. A small modification was made to the cloc source code before passing it to perl2exe; lines 87 and 88 were uncommented:

85  # Uncomment next two lines when building Windows executable with perl2exe
86  # or if running on a system that already has Regexp::Common.
87  #use Regexp::Common;
88  #$HAVE_Rexexp_Common = 1;

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 . The entries for recent versions are:



cloc 1.72 exe:

cloc 1.70 exe:

cloc 1.68 exe:

cloc 1.66 exe:

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.

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 from PAR::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:> pp -M Digest::MD5 -c -x -o cloc-1.76.exe cloc

A 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.

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:

prompt> cloc perl-5.22.0.tar.gz
    5605 text files.
    5386 unique files.
    2176 files ignored. v 1.65  T=25.49 s (134.7 files/s, 51980.3 lines/s)
Language                         files          blank        comment           code
Perl                              2892         136396         184362         536445
C                                  130          24676          33684         155648
C/C++ Header                       148           9766          16569         147858
Bourne Shell                       112           4044           6796          42668
Pascal                               8            458           1603           8592
XML                                 33            142              0           2410
YAML                                49             20             15           2078
C++                                 10            313            277           2033
make                                 4            426            488           1986
Prolog                              12            438              2           1146
JSON                                14              1              0           1037
yacc                                 1             85             76            998
Windows Message File                 1            102             11            489
DOS Batch                           14             92             41            389
Windows Resource File                3             10              0             85
D                                    1              5              7              8
Lisp                                 2              0              3              4
SUM:                              3434         176974         243934         903874

To run cloc on Windows computers, one must first open up a command (aka DOS) window and invoke cloc.exe from the command line there.

Options ▲

prompt> cloc --help

Usage: cloc [options]  |   | 

 Count, or compute differences of, physical lines of source code in the
 given files (may be archives such as compressed tarballs or zip files)
 and/or recursively below the given directories.

 Input Options
   --extract-with=CMD        This option is only needed if cloc is unable
                             to figure out how to extract the contents of
                             the input file(s) by itself.
                             Use CMD to extract binary archive files (e.g.:
                             .tar.gz, .zip, .Z).  Use the literal '>FILEFILEFILEFILE # lines of code
                                X = 'cm'  -> # lines of code + comments
                                X = 'cb'  -> # lines of code + blanks
                                X = 'cmb' -> # lines of code + comments + blanks
                             For example, if using method 'c' and your code
                             has twice as many lines of comments as lines
                             of code, the value in the comment column will
                             be 200%.  The code column remains a line count.
   --csv                     Write the results as comma separated values.
   --csv-delimiter=C         Use the character C as the delimiter for comma
                             separated files instead of ,.  This switch forces
   --json                    Write the results as JavaScript Object Notation
                             (JSON) formatted output.
   --md                      Write the results as Markdown-formatted text.
   --out=FILE                Synonym for --report-file=FILE.
   --progress-rate=N         Show progress update after every N files are
                             processed (default N=100).  Set N to 0 to
                             suppress progress output (useful when redirecting
                             output to STDOUT).
   --quiet                   Suppress all information messages except for
                             the final report.
   --report-file=FILE        Write the results to FILE instead of STDOUT.
   --sql=FILE                Write results as SQL create and insert statements
                             which can be read by a database program such as
                             SQLite.  If FILE is -, output is sent to STDOUT.
   --sql-append              Append SQL insert statements to the file specified
                             by --sql and do not generate table creation
                             statements.  Only valid with the --sql option.
   --sql-project=NAME        Use NAME as the project identifier for the
                             current run.  Only valid with the --sql option.
   --sql-style=STYLE         Write SQL statements in the given style instead
                             of the default SQLite format.  Currently, the
                             only style option is Oracle.
   --sum-one                 For plain text reports, show the SUM: output line
                             even if only one input file is processed.
   --xml                     Write the results in XML.
   --xsl=FILE                Reference FILE as an XSL stylesheet within
                             the XML output.  If FILE is 1 (numeric one),
                             writes a default stylesheet, cloc.xsl (or
                             cloc-diff.xsl if --diff is also given).
                             This switch forces --xml on.
   --yaml                    Write the results in YAML.

Recognized Languages ▲

prompt> cloc --show-lang

ABAP                       (abap)
ActionScript               (as)
Ada                        (ada, adb, ads, pad)
ADSO/IDSM                  (adso)
Agda                       (agda, lagda)
AMPLE                      (ample, dofile, startup)
Ant                        (build.xml, build.xml)
ANTLR Grammar              (g, g4)
Apex Trigger               (trigger)
Arduino Sketch             (ino, pde)
AsciiDoc                   (adoc, asciidoc)
ASP                        (asa, asp)
ASP.NET                    (asax, ascx, asmx, aspx, master, sitemap, webinfo)
AspectJ                    (aj)
Assembly                   (asm, S, s)
AutoHotkey                 (ahk)
awk                        (awk)
Blade                      (blade.php)
Bourne Again Shell         (bash)
Bourne Shell               (sh)
BrightScript               (brs)
builder                    (xml.builder)
C                          (c, ec, pgc)
C Shell                    (csh, tcsh)
C#                         (cs)
C++                        (C, c++, cc, CPP, cpp, cxx, pcc)
C/C++ Header               (H, h, hh, hpp, hxx)
CCS                        (ccs)
Chapel                     (chpl)
Clean                      (dcl, icl)
Clojure                    (clj)
ClojureC                   (cljc)
ClojureScript              (cljs)
CMake                      (cmake, CMakeLists.txt)
COBOL                      (cbl, CBL, COB, cob)
CoffeeScript               (coffee)
ColdFusion                 (cfm)
ColdFusion CFScript        (cfc)
Coq                        (v)
Crystal                    (cr)
CSON                       (cson)
CSS                        (css)
Cucumber                   (feature)
CUDA                       (cu, cuh)
Cython                     (pyx)
D                          (d)
DAL                        (da)
Dart                       (dart)
diff                       (diff)
DITA                       (dita)
DOORS Extension Language   (dxl)
DOS Batch                  (bat, BAT, BTM, btm, cmd, CMD)
Drools                     (drl)
DTD                        (dtd)
dtrace                     (d)
ECPP                       (ecpp)
EEx                        (eex)
Elixir                     (ex, exs)
Elm                        (elm)
ERB                        (erb, ERB)
Erlang                     (erl, hrl)
Expect                     (exp)
F#                         (fsi, fs, fs)
F# Script                  (fsx)
Fish Shell                 (fish)
Focus                      (focexec)
Forth                      (4th, e4, f83, fb, forth, fpm, fr, frt, ft, fth, rx, fs, f, for)
Fortran 77                 (F, f77, F77, FOR, ftn, FTN, pfo, f, for)
Fortran 90                 (F90, f90)
Fortran 95                 (f95, F95)
Freemarker Template        (ftl)
GDScript                   (gd)
Gencat NLS                 (msg)
Glade                      (glade, ui)
GLSL                       (comp, frag, geom, glsl, tesc, tese, vert)
Go                         (go)
Grails                     (gsp)
GraphQL                    (gql, graphql)
Groovy                     (gant, gradle, groovy)
Haml                       (haml)
Handlebars                 (handlebars, hbs)
Harbour                    (hb)
Haskell                    (hs, lhs)
Haxe                       (hx)
HCL                        (hcl, nomad, tf)
HLSL                       (cg, cginc, hlsl, shader)
HTML                       (htm, html)
IDL                        (idl, pro)
Idris                      (idr)
INI                        (ini)
InstallShield              (ism)
Java                       (java)
JavaScript                 (es6, js)
JavaServer Faces           (jsf)
JCL                        (jcl)
JSON                       (json)
JSP                        (jsp, jspf)
JSX                        (jsx)
Julia                      (jl)
Kermit                     (ksc)
Korn Shell                 (ksh)
Kotlin                     (kt, kts)
Lean                       (lean)
LESS                       (less)
lex                        (l)
LFE                        (lfe)
liquid                     (liquid)
Lisp                       (asd, el, lisp, lsp, cl, jl)
Literate Idris             (lidr)
LiveLink OScript           (oscript)
Logtalk                    (lgt, logtalk)
Lua                        (lua)
m4                         (ac, m4)
make                       (am, Gnumakefile, gnumakefile, Makefile, makefile, mk)
Mako                       (mako)
Markdown                   (md)
Mathematica                (mt, wl, wlt, m)
MATLAB                     (m)
Maven                      (pom, pom.xml)
Modula3                    (i3, ig, m3, mg)
MSBuild script             (csproj, vbproj, vcproj, wdproj, wixproj)
MUMPS                      (mps, m)
Mustache                   (mustache)
MXML                       (mxml)
NAnt script                (build)
NASTRAN DMAP               (dmap)
Nemerle                    (n)
Nim                        (nim)
Objective C                (m)
Objective C++              (mm)
OCaml                      (ml, mli, mll, mly)
OpenCL                     (cl)
Oracle Forms               (fmt)
Oracle PL/SQL              (bod, fnc, prc, spc, trg)
Oracle Reports             (rex)
Pascal                     (dpr, p, pas)
Pascal/Puppet              (pp)
Patran Command Language    (pcl, ses)
Perl                       (perl, plh, plx, pm, pm6, pl)
PHP                        (php, php3, php4, php5, phtml)
PHP/Pascal                 (inc)
Pig Latin                  (pig)
PL/I                       (pl1)
PL/M                       (lit, plm)
PO File                    (po)
PowerBuilder               (sra, srf, srm, srs, sru, srw)
PowerShell                 (ps1, psd1, psm1)
ProGuard                   (pro)
Prolog                     (P, pl, pro)
Protocol Buffers           (proto)
Pug                        (pug)
PureScript                 (purs)
Python                     (py)
QML                        (qml)
Qt                         (ui)
Qt Linguist                (ts)
Qt Project                 (pro)
R                          (R, r)
Racket                     (rkt, rktl, scrbl)
RAML                       (raml)
RapydScript                (pyj)
Razor                      (cshtml)
Rexx                       (rexx)
RobotFramework             (robot, tsv)
Ruby                       (rake, rb)
Ruby HTML                  (rhtml)
Rust                       (rs)
SAS                        (sas)
Sass                       (sass, scss)
Scala                      (scala)
Scheme                     (sc, sch, scm, sld, sls, ss)
sed                        (sed)
SKILL                      (il)
SKILL++                    (ils)
Skylark                    (bzl)
Slice                      (ice)
Slim                       (slim)
Smalltalk                  (st, cs)
Smarty                     (smarty, tpl)
Softbridge Basic           (SBL, sbl)
Solidity                   (sol)
Specman e                  (e)
SQL                        (psql, sql, SQL)
SQL Data                   (data.sql)
SQL Stored Procedure       (spc.sql, spoc.sql, sproc.sql, udf.sql)
Standard ML                (fun, sig, sml)
Stata                      (do, DO)
Stylus                     (styl)
Swift                      (swift)
SWIG                       (i)
Tcl/Tk                     (itk, tcl, tk)
Teamcenter met             (met)
Teamcenter mth             (mth)
TeX                        (bst, dtx, sty, tex)
TITAN Project File Information (tpd)
Titanium Style Sheet       (tss)
TOML                       (toml)
TTCN                       (ttcn, ttcn2, ttcn3, ttcnpp)
Twig                       (twig)
TypeScript                 (tsx, ts)
Unity-Prefab               (mat, prefab)
Vala                       (vala)
Vala Header                (vapi)
Velocity Template Language (vm)
Verilog-SystemVerilog      (sv, svh, v)
VHDL                       (VHD, vhd, vhdl, VHDL)
vim script                 (vim)
Visual Basic               (bas, cls, ctl, dsr, frm, VB, vb, VBA, vba, VBS, vbs)
Visual Fox Pro             (SCA, sca)
Visualforce Component      (component)
Visualforce Page           (page)
Vuejs Component            (vue)
Windows Message File       (mc)
Windows Module Definition  (def)
Windows Resource File      (rc, rc2)
WiX include                (wxi)
WiX source                 (wxs)
WiX string localization    (wxl)
XAML                       (xaml)
xBase                      (prg)
xBase Header               (ch)
XHTML                      (xhtml)
XMI                        (XMI, xmi)
XML                        (xml, XML)
XQuery                     (xq, xquery)
XSD                        (XSD, xsd)
XSLT                       (XSL, xsl, XSLT, xslt)
yacc                       (y)
YAML                       (yaml, yml)
zsh                        (zsh)

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:

  • .cl files could be Lisp or OpenCL
  • .cs files could be C# or Smalltalk
  • .d files could be D or dtrace
  • .f or .for files could be Fortran or Forth
  • .fs files could be Forth or F#
  • .inc files could be PHP or Pascal
  • .jl files could be Lisp or Julia
  • .m files could be MATLAB, Mathematica, Mercury, MUMPS, or Objective C
  • .pl files could be Perl or Prolog
  • .pp files could be Pascal or Puppet
  • .pro files could be IDL, Prolog, or a Qt Project
  • .ts files could be TypeScript or Qt Linguist
  • .ui files could be Qt or Glade
  • .v files could be Coq or Verilog/SystemVerilog
  • build.xml files could be Ant or XML
  • pom.xml files could be Maven or XML

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:

  1. 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.)
  2. Use File::Find to recursively descend the input directories and make a list of candidate file names. Ignore binary and zero-sized files.
  3. 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-uniqueness switch 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.
  4. Scan the candidate file list for file extensions which cloc associates with programming languages (see the --show-lang and --show-ext options). Files which match are classified as containing source code for that language. Each file without an extensions 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 recognzied scripting language, the file is ignored.
  5. All remaining files in the candidate list should now be source files for known programming languages. For each of these files:

    1. Read the entire file into memory.
    2. Count the number of lines (= Loriginal).
    3. Remove blank lines, then count again (= Lnon_blank).
    4. 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).
    5. 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.
       0 files ignored. 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
  82895 sqlite3.c
 133796 total
prompt> echo "82895 - 50901" | bc

We can now compare the original file, sqlite3.c and the one stripped of comments, 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.o

Next, the version without comments:

prompt> mv sqlite3.c
prompt> gcc -c sqlite3.c
prompt> md5sum sqlite3.o
cce5f1a2ea27c7e44b2e1047e2588b49  sqlite3.o

cloc 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: .tar.gz

cloc open issues Ask a question     (View All Issues)
  • over 1 year JSON Output is not a valid JSON
  • over 1 year Make it available for apk package manager.
  • about 2 years Long paths under windows dont work
  • over 2 years inefficient,--diff,cloc just uses one cpu core to run
cloc open pull requests (View All Pulls)
  • dont traverse into folders in order to support long paths under windows
  • Identify .hxx files as C/C++ Header
cloc questions on Stackoverflow (View All Questions)
  • How to get the total line alone using cloc?
  • CLOC not counting actionscript files correctly
  • How to speedup cloc to diff 2 big dirs?
  • Use cloc on 2 different commits. Only see actual lines of code, no Comments or blank rows
  • How can I make a batch file to run the same cloc command with one click?
  • Do diff in cloc where folders move and solve it with python script
  • Using cloc (count Lines of Codes) result
  • CLOC ignore/exlude list file (.clocignore)
  • Combine `cloc` with `git blame`
  • CLOC- count lines of code, exclude everything in a dir except for certain files
cloc latest release notes
v1.76 v1.76

Parallel processing (Unix, MacOS only), git support on Windows, 13 new languages, bug fixes.

1.74 1.74

Support git hashes and branch names as input; 11 new languages; bug fixes.

v1.72 v1.72

Added support for 11 additional languages, improved support for --vcs, --not-match-d, fixed a few bugs.

Other projects in Perl