diff --git a/Dockerfile b/Dockerfile index c7a7e739..9fecd070 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,4 +43,5 @@ FROM base AS final WORKDIR /tmp -CMD ["/usr/src/cloc", "--help"] +ENTRYPOINT ["/usr/src/cloc"] +CMD ["--help"] diff --git a/README.md b/README.md index 67ea7fb1..80268fb4 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ * * * cloc counts blank lines, comment lines, and physical lines of source code in many programming languages. -Latest release: v1.94 (July 4, 2022) +Latest release: v1.96 (Dec. 18, 2022) DOI - + cloc moved to GitHub in September 2015 after being hosted at http://cloc.sourceforge.net/ since August 2006. @@ -64,10 +64,18 @@ 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-1.94.pl`) or a Windows executable -(`cloc-1.94.exe`). On this page, `cloc` is the generic term +released version (`cloc-1.96.pl`) or a Windows executable +(`cloc-1.96.1.exe`). +(2023-01-10: a special +[1.96.1 release](https://github.com/AlDanial/cloc/releases/tag/v1.96.1) of cloc was made to update the Windows executable to use the +``Win32::LongPath`` module.) +On this page, `cloc` is the generic term used to refer to any of these. +[Include Security](https://www.youtube.com/user/IncludeSecurity) has a +[YouTube video](https://www.youtube.com/watch?v=eRLTkDMsCqs) +showing the steps in action. + **a file**
 prompt> cloc hello.c
@@ -424,6 +432,12 @@ executable and also check sites such
 https://www.virustotal.com/ .
 The entries for recent versions are:
 
+cloc-1.96.1.exe:
+https://www.virustotal.com/gui/file/00b1c9dbbfb920dabd374418e1b86d2c24b8cd2b8705aeb956dee910d0d75d45?nocache=1
+
+cloc-1.96.exe:
+https://www.virustotal.com/gui/file/54bf5f46fbaba7949c4eb2d4837b03c774c0ba587448a5bad9b8efc0222b1583?nocache=1
+
 cloc-1.94.exe:
 https://www.virustotal.com/gui/file/b48a6002fb75fa66ec5d0c05a5c4d51f2ad22b5b025b7eb4e3945d18419c0952?nocache=1
 
@@ -503,7 +517,8 @@ 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.94.exe cloc-1.94.pl
+C:> cpan -i Win32::LongPath
+C:> pp -M Win32::LongPath -M Encode::Unicode -M Digest::MD5 -c -x -o cloc-1.96.exe cloc-1.96.pl
 
A variation on the instructions above is if you installed the portable @@ -1055,9 +1070,12 @@ C# (cs) C# Designer (designer.cs) C++ (C, c++, cc, CPP, cpp, cxx, h++, inl, ipp, pcc, tcc, tpp) C/C++ Header (H, h, hh, hpp, hxx) +Cairo (cairo) Cake Build Script (cake) +Carbon (carbon) CCS (ccs) Chapel (chpl) +Circom (circom) Clean (dcl, icl) Clojure (boot, cl2, clj, cljs.hl, cljscm, cljx, hic, riemann.config) ClojureC (cljc) @@ -1067,6 +1085,7 @@ COBOL (CBL, cbl, ccp, COB, cob, cobol, cpy) CoffeeScript (_coffee, cakefile, cjsx, coffee, iced) ColdFusion (cfm, cfml) ColdFusion CFScript (cfc) +Containerfile (Containerfile) Coq (v) Crystal (cr) CSON (cson) @@ -1134,6 +1153,7 @@ Haskell (hs, hsc, lhs) Haxe (hx, hxsl) HCL (hcl, nomad, tf, tfvars) HLSL (cg, cginc, fxh, hlsl, hlsli, shader) +HolyC (HC) Hoon (hoon) HTML (htm, html, html.hl, xht) HTML EEx (heex) @@ -1156,15 +1176,16 @@ JSX (jsx) Julia (jl) Juniper Junos (junos) Jupyter Notebook (ipynb) -kvlang (kv) Kermit (ksc) Korn Shell (ksh) Kotlin (kt, ktm, kts) +kvlang (kv) Lean (hlean, lean) Lem (lem) LESS (less) lex (l, lex) LFE (lfe) +Linker Script (ld) liquid (liquid) Lisp (asd, el, lisp, lsp, cl, jl) Literate Idris (lidr) @@ -1193,14 +1214,17 @@ NASTRAN DMAP (dmap) Nemerle (n) Nim (nim, nim.cfg, nimble, nimrod, nims) Nix (nix) +Nunjucks (njk) Objective-C (m) Objective-C++ (mm) OCaml (eliom, eliomi, ml, ml4, mli, mll, mly) Odin (odin) OpenCL (cl) +OpenSCAD (scad) Oracle Forms (fmt) Oracle PL/SQL (bod, fnc, prc, spc, trg) Oracle Reports (rex) +P4 (p4) Pascal (dpr, lpr, p, pas, pascal) Pascal/Puppet (pp) Patran Command Language (pcl, ses) @@ -1208,6 +1232,7 @@ PEG (peg) peg.js (pegjs) peggy (peggy) Perl (ack, al, cpanfile, makefile.pl, perl, ph, plh, plx, pm, psgi, rexfile, pl, p6) +Pest (pest) PHP (aw, ctp, phakefile, php, php3, php4, php5, php_cs, php_cs.dist, phps, phpt, phtml) PHP/Pascal (inc) Pig Latin (pig) @@ -1215,6 +1240,7 @@ PL/I (pl1) PL/M (lit, plm) PlantUML (puml) PO File (po) +Pony (pony) PowerBuilder (pbt, sra, srf, srm, srs, sru, srw) PowerShell (ps1, psd1, psm1) ProGuard (pro) @@ -1277,6 +1303,7 @@ Swift (swift) SWIG (i) TableGen (td) Tcl/Tk (itk, tcl, tk) +TEAL (teal) Teamcenter met (met) Teamcenter mth (mth) TeX (aux, bbx, bib, bst, cbx, dtx, ins, lbx, ltx, mkii, mkiv, mkvi, sty, tex, cls) @@ -1310,6 +1337,7 @@ Visualforce Page (page) Vuejs Component (vue) Web Services Description (wsdl) WebAssembly (wast, wat) +WGSL (wgsl) Windows Message File (mc) Windows Module Definition (def) Windows Resource File (rc, rc2) @@ -3062,7 +3090,7 @@ provided the [Serbo-Croatian](http://science.webhostinggeeks.com/cloc) translation. -Gill Ajoft of [Ajoft Softwares](http://www.ajoft.com) +Gill Ajoft of [Ajoft Software](http://www.ajoft.com) provided the [Bulgarian](http://www.ajoft.com/wpaper/aj-cloc.html) translation. diff --git a/Unix/NEWS b/Unix/NEWS index 36b32e5e..62d900bb 100644 --- a/Unix/NEWS +++ b/Unix/NEWS @@ -1,3 +1,36 @@ + Release Notes for cloc version 1.96 + https://github.com/AlDanial/cloc + Dec. 18, 2022 + +New Languages and File Types: + o Cairo + o Carbon + o Circom + o Containerfile + o HolyC + o kvlang + o Nunjucks + o OpenSCAD + o P4 + o Pest + o Pony + o TEAL + o WGSL + +Updates: + o New switch --diff-list-files to run diff given two list + files. + o Handle comments embedded in OCaml strings. + o Write empty JSON and XML structures if the inputs yield zero + counts. + o Including Win32::LongPath to support long paths on Windows. + o Better support for building and running Docker image on Windows + o Better output file names when running with --count-and-diff + and --out. + o Resolve internal file handle conflict when running --diff with + --sdir or --categorized. + +============================================================================ Release Notes for cloc version 1.94 https://github.com/AlDanial/cloc July 4, 2022 @@ -263,7 +296,7 @@ Updates: logic. o Improve Perl v. Prolog identification. o New switch --docstring-as-code to count Python docstrings as code. - o Partial support fot Lua nested comments. + o Partial support for Lua nested comments. o Renamed Skylark to Starlark. o Modified Java filter to try to handle embedded comments better. o Recognize groovy as one of the #! languages. @@ -283,7 +316,7 @@ Updates: https://github.com/AlDanial/cloc Oct. 5, 2018 -This is a bug-fix release to solve mis-handling of git inputs for +This is a bug-fix release to solve miss-handling of git inputs for straight counts in 1.78 (--git --diff works ok in 1.78), https://github.com/AlDanial/cloc/issues/328. @@ -438,10 +471,10 @@ Updates: on older versions of Perl on Windows). o Put timeout around Regexp::Common regex evaluation to prevent hangs on unbalanced comment markers within huge strings (issue 206). - o Fix Pascal regex wiht '{' for Perl version >= 5.26 (issue 209) + o Fix Pascal regex with '{' for Perl version >= 5.26 (issue 209) and '(*', '*)' comment matching (issue 212). o Rename Antlr to ANTLR Grammar. - o Add .g4 extension fo ANTLR Grammar. + o Add .g4 extension for ANTLR Grammar. o Replace soon-to-be deprecated File::Glob::glob() with File::Glob::bsd_glob() (issue 214). o Revert from charset=iso-8859-1 to charset=utf-8 on undocumented @@ -1180,7 +1213,7 @@ Bug Fixes: IDL: Include .pro as a recognized file extension. --3: - o Correct XSLT syle when running with --3. + o Correct XSLT style when running with --3. --diff: o Implemented YAML output option. diff --git a/Unix/cloc b/Unix/cloc index 805e738f..0c39e86c 100755 --- a/Unix/cloc +++ b/Unix/cloc @@ -1,6 +1,6 @@ #!/usr/bin/env perl # cloc -- Count Lines of Code {{{1 -# Copyright (C) 2006-2022 Al Danial +# Copyright (C) 2006-2023 Al Danial # First release August 2006 # # Includes code from: @@ -8,13 +8,13 @@ # http://www.dwheeler.com/sloccount/ # by David Wheeler. # - Regexp::Common v2017060201 -# http://search.cpan.org/~abigail/Regexp-Common-2017060201/lib/Regexp/Common.pm +# https://metacpan.org/pod/Regexp::Common # by Damian Conway and Abigail. -# - Win32::Autoglob -# http://search.cpan.org/~sburke/Win32-Autoglob-1.01/Autoglob.pm +# - Win32::Autoglob 1.01 +# https://metacpan.org/pod/Win32::Autoglob # by Sean M. Burke. -# - Algorithm::Diff -# http://search.cpan.org/~tyemq/Algorithm-Diff-1.1902/lib/Algorithm/Diff.pm +# - Algorithm::Diff 1.1902 +# https://metacpan.org/pod/Algorithm::Diff # by Tye McQueen. # # This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ # . # # 1}}} -my $VERSION = "1.95"; # odd number == beta; even number == stable +my $VERSION = "1.97"; # odd number == beta; even number == stable my $URL = "github.com/AlDanial/cloc"; # 'https://' pushes header too wide require 5.10.0; # use modules {{{1 @@ -58,11 +58,11 @@ use Time::HiRes; my $HAVE_Rexexp_Common = 1; use Regexp::Common; -my $HAVE_Algorith_Diff = 1; +my $HAVE_Algorithm_Diff = 1; use Algorithm::Diff qw ( sdiff ); -# print "2 HAVE_Algorith_Diff = $HAVE_Algorith_Diff\n"; +# print "2 HAVE_Algorithm_Diff = $HAVE_Algorithm_Diff\n"; # test_alg_diff($ARGV[$#ARGV - 1], $ARGV[$#ARGV]); die; -# die "Hre=$HAVE_Rexexp_Common Had=$HAVE_Algorith_Diff"; +# die "Hre=$HAVE_Rexexp_Common Had=$HAVE_Algorithm_Diff"; # Uncomment next two lines when building Windows executable with perl2exe # or if running on a system that already has Regexp::Common. @@ -110,6 +110,17 @@ if ($ON_WINDOWS and $ENV{'SHELL'}) { $ON_WINDOWS = 1; # MKS defines $SHELL but still acts like Windows } } + +my $HAVE_Win32_Long_Path = 0; +# Win32::LongPath is an optional dependency that when available on +# Windows will be used to support reading files past the 255 char +# path length limit. +if ($ON_WINDOWS) { + eval "use Win32::LongPath;"; + if (defined $Win32::LongPath::VERSION) { + $HAVE_Win32_Long_Path = 1; + } +} my $config_file = ''; if ( $ENV{'HOME'} ) { $config_file = File::Spec->catfile( $ENV{'HOME'}, '.config', 'cloc', 'options.txt'); @@ -187,7 +198,18 @@ Usage: $script [options] | | + Compute differences in code and comments between + the files and directories listed in and + . Each input file should use the same + format as --list-file, where there is one file or + directory name per line. Only exact matches are + counted; relative path names will be resolved + starting from the directory where cloc is invoked. + This enables --diff mode. See also --list-file, + --diff-list-file, --diff. --vcs= Invoke a system call to to obtain a list of files to work on. If is 'git', then will invoke 'git ls-files' to get a file list and @@ -343,6 +365,7 @@ Usage: $script [options] | | | | Only count files containing text that matches the + given regular expression. --exclude-content= Exclude files containing text that matches the given regular expression. --exclude-dir=[,D2,] Exclude the given comma separated directories @@ -500,6 +525,7 @@ Usage: $script [options] | | Only count files whose basenames match the Perl regex. For example --match-f='^[Ww]idget' @@ -509,7 +535,7 @@ Usage: $script [options] | | Count all files except those whose basenames match the Perl regex. Add --fullpath to include parent directories in the regex instead of just - the basename. + the basename. This option may be repeated. --skip-archive= Ignore files that end with the given Perl regular expression. For example, if given --skip-archive='(zip|tar(\.(gz|Z|bz2|xz|7z))?)' @@ -581,8 +607,9 @@ Usage: $script [options] | | encodings(\":all\")), \"\\n\"' - --hide-rate Do not show line and file processing rates in the - output header. This makes output deterministic. + --hide-rate Do not show elapsed time, line processing rate, or + file processing rates in the output header. This + makes output deterministic. --json Write the results as JavaScript Object Notation (JSON) formatted output. --md Write the results as Markdown-formatted text. @@ -644,6 +671,7 @@ my ( $opt_diff , $opt_diff_alignment , $opt_diff_list_file , + $opt_diff_list_files , $opt_diff_timeout , $opt_timeout , $opt_html , @@ -656,6 +684,7 @@ my ( $opt_v , $opt_vcs , $opt_version , + $opt_include_content , $opt_exclude_content , $opt_exclude_lang , $opt_exclude_list_file , @@ -691,9 +720,9 @@ my ( $opt_json , $opt_md , $opt_match_f , - $opt_not_match_f , + @opt_not_match_f , $opt_match_d , - $opt_not_match_d , + @opt_not_match_d , $opt_skip_uniqueness , $opt_list_file , $opt_help , @@ -731,6 +760,7 @@ my ( $opt_summary_cutoff , $opt_skip_leading , $opt_no_recurse , + $opt_only_count_files , ); my $getopt_success = GetOptions( # {{{1 @@ -740,6 +770,7 @@ my $getopt_success = GetOptions( # {{{1 "counted=s" => \$opt_counted , "include_ext|include-ext=s" => \$opt_include_ext , "include_lang|include-lang=s" => \$opt_include_lang , + "include_content|include-content=s" => \$opt_include_content , "exclude_content|exclude-content=s" => \$opt_exclude_content , "exclude_lang|exclude-lang=s" => \$opt_exclude_lang , "exclude_dir|exclude-dir=s" => \$opt_exclude_dir , @@ -752,6 +783,7 @@ my $getopt_success = GetOptions( # {{{1 "diff-alignment|diff_alignment=s" => \$opt_diff_alignment , "diff-timeout|diff_timeout=i" => \$opt_diff_timeout , "diff-list-file|diff_list_file=s" => \$opt_diff_list_file , + "diff-list-files|diff_list_files" => \$opt_diff_list_files , "timeout=i" => \$opt_timeout , "html" => \$opt_html , "ignored=s" => \$opt_ignored , @@ -791,9 +823,9 @@ my $getopt_success = GetOptions( # {{{1 "md" => \$opt_md , "fullpath" => \$opt_fullpath , "match_f|match-f=s" => \$opt_match_f , - "not_match_f|not-match-f=s" => \$opt_not_match_f , + "not_match_f|not-match-f=s" => \@opt_not_match_f , "match_d|match-d=s" => \$opt_match_d , - "not_match_d|not-match-d=s" => \$opt_not_match_d , + "not_match_d|not-match-d=s" => \@opt_not_match_d , "list_file|list-file=s" => \$opt_list_file , "help" => \$opt_help , "skip_win_hidden|skip-win-hidden" => \$opt_skip_win_hidden , @@ -831,6 +863,7 @@ my $getopt_success = GetOptions( # {{{1 "summary_cutoff|summary-cutoff=s" => \$opt_summary_cutoff , "skip_leading|skip-leading:s" => \$opt_skip_leading , "no_recurse|no-recurse" => \$opt_no_recurse , + "only_count_files|only-count-files" => \$opt_only_count_files , ); # 1}}} $config_file = $opt_config_file if defined $opt_config_file; @@ -841,6 +874,7 @@ load_from_config_file($config_file, # {{{2 \$opt_counted , \$opt_include_ext , \$opt_include_lang , + \$opt_include_content , \$opt_exclude_content , \$opt_exclude_lang , \$opt_exclude_dir , @@ -849,6 +883,7 @@ load_from_config_file($config_file, # {{{2 \$opt_extract_with , \$opt_found , \$opt_count_diff , + \$opt_diff_list_files , \$opt_diff , \$opt_diff_alignment , \$opt_diff_timeout , @@ -889,9 +924,9 @@ load_from_config_file($config_file, # {{{2 \$opt_md , \$opt_fullpath , \$opt_match_f , - \$opt_not_match_f , + \@opt_not_match_f , \$opt_match_d , - \$opt_not_match_d , + \@opt_not_match_d , \$opt_list_file , \$opt_help , \$opt_skip_win_hidden , @@ -937,6 +972,10 @@ if ($opt_version) { printf "$VERSION\n"; exit; } +my $opt_git = 0; +$opt_git = 1 if defined($opt_git_diff_all) or + defined($opt_git_diff_rel) or + (defined($opt_vcs) and ($opt_vcs eq "git")); $opt_by_file = 1 if defined $opt_by_file_by_lang; my $CLOC_XSL = "cloc.xsl"; # created with --xsl $CLOC_XSL = "cloc-diff.xsl" if $opt_diff; @@ -968,6 +1007,7 @@ $Exclude_Dir{".config"} = 1; $opt_count_diff = defined $opt_count_diff ? 1 : 0; $opt_diff = 1 if $opt_diff_alignment or $opt_diff_list_file or + $opt_diff_list_files or $opt_git_diff_rel or $opt_git_diff_all or $opt_git_diff_simindex; @@ -1023,6 +1063,17 @@ if ($opt_use_sloccount) { } $opt_vcs = 0 if $opt_force_git; +# replace Windows path separators with / +if ($ON_WINDOWS) { + map { s{\\}{/}g } @ARGV; + if ($opt_git) { + # PowerShell tab expansion automatically prefixes local directories + # with ".\" (now mapped to "./"). git ls-files output does not + # include this. Strip this prefix to permit clean matches. + map { s{^\./}{} } @ARGV; + } +} + my @COUNT_DIFF_ARGV = undef; my $COUNT_DIFF_report_file = undef; if ($opt_count_diff and !$opt_diff_list_file) { @@ -1037,7 +1088,8 @@ if ($opt_count_diff and !$opt_diff_list_file) { } # Options defaults: -$opt_quiet = 1 if ($opt_md or $opt_json) and !defined $opt_report_file; +$opt_quiet = 1 if ($opt_md or $opt_json or !(-t STDOUT)) + and !defined $opt_report_file; $opt_progress_rate = 100 unless defined $opt_progress_rate; $opt_progress_rate = 0 if defined $opt_quiet; if (!defined $opt_v) { @@ -1077,9 +1129,9 @@ $opt_by_percent = lc $opt_by_percent; if (defined $opt_vcs) { if ($opt_vcs eq "auto") { - if (-d ".git") { + if (is_dir(".git")) { $opt_vcs = "git"; - } elsif (-d ".svn") { + } elsif (is_dir(".svn")) { $opt_vcs = "svn"; } else { warn "--vcs auto: unable to determine versioning system\n"; @@ -1330,6 +1382,8 @@ if ($opt_count_diff) { if ($opt_count_diff == 3) { $opt_diff = 1; @ARGV = @{$COUNT_DIFF_ARGV[ $opt_count_diff ]}; # last arg is list of list + } elsif ($opt_diff_list_files) { + $opt_diff = 0; } if ($opt_report_file) { # Instead of just one output file, will have three. @@ -1682,11 +1736,16 @@ if ($opt_diff_list_file) { } for (my $i = 0; $i < scalar @ARGV; $i++) { if ($opt_diff_list_file) { - push @fh, make_file_list($files_for_set[$i], + push @fh, make_file_list($files_for_set[$i], $i+1, + \%Error_Codes, \@Errors, \%Ignored); + @{$files_for_set[$i]} = @file_list; + } elsif ($opt_diff_list_files) { + my @list_files = read_list_file($ARGV[$i]); + push @fh, make_file_list(\@list_files, $i+1, \%Error_Codes, \@Errors, \%Ignored); @{$files_for_set[$i]} = @file_list; } else { - push @fh, make_file_list([ $ARGV[$i] ], + push @fh, make_file_list([ $ARGV[$i] ], $i+1, \%Error_Codes, \@Errors, \%Ignored); @{$files_for_set[$i]} = @file_list; } @@ -1720,6 +1779,10 @@ foreach my $FH (@fh) { # loop over each pair of file sets exclude_by_regex($opt_exclude_content, # in \%{$unique_source_file{$FH}}, # in/out \%Ignored); # out + } elsif ($opt_include_content) { + include_by_regex($opt_include_content, # in + \%{$unique_source_file{$FH}}, # in/out + \%Ignored); # out } if ($opt_include_lang) { @@ -1918,16 +1981,18 @@ if ($opt_by_file) { } else { # Step 4: Separate code from non-code files. {{{1 my $fh = 0; -if ($opt_list_file or $opt_vcs) { +if ($opt_list_file or $opt_diff_list_files or $opt_vcs) { my @list; if ($opt_vcs) { @list = invoke_generator($opt_vcs, \@ARGV); - } else { + } elsif ($opt_list_file) { @list = read_list_file($opt_list_file); + } else { + @list = read_list_file($ARGV[0]); } - $fh = make_file_list(\@list, \%Error_Codes, \@Errors, \%Ignored); + $fh = make_file_list(\@list, 0, \%Error_Codes, \@Errors, \%Ignored); } else { - $fh = make_file_list(\@ARGV, \%Error_Codes, \@Errors, \%Ignored); + $fh = make_file_list(\@ARGV, 0, \%Error_Codes, \@Errors, \%Ignored); # make_file_list populates global variable @file_list via call to # File::Find's find() which in turn calls files() } @@ -1938,7 +2003,7 @@ if ($opt_exclude_list_file) { \%Ignored); } if ($opt_skip_win_hidden and $ON_WINDOWS) { - my @file_list_minus_hidded = (); + my @file_list_minus_hidden = (); # eval code to run on Unix without 'missing Win32::File module' error. my $win32_file_invocation = ' use Win32::File; @@ -1950,11 +2015,11 @@ if ($opt_skip_win_hidden and $ON_WINDOWS) { print "Ignoring $F since it is a Windows hidden file\n" if $opt_v > 1; } else { - push @file_list_minus_hidded, $F; + push @file_list_minus_hidden, $F; } }'; eval $win32_file_invocation; - @file_list = @file_list_minus_hidded; + @file_list = @file_list_minus_hidden; } if ($opt_no_autogen) { exclude_autogenerated_files(\@file_list, # in/out @@ -1979,6 +2044,10 @@ if ($opt_exclude_content) { exclude_by_regex($opt_exclude_content, # in \%unique_source_file , # in/out \%Ignored); # out +} elsif ($opt_include_content) { + include_by_regex($opt_include_content, # in + \%unique_source_file , # in/out + \%Ignored); # out } printf "%8d unique file%s. \n", plural_form(scalar keys %unique_source_file) @@ -2061,7 +2130,10 @@ my $end_time = get_time(); printf "%8d file%s ignored.\n", plural_form(scalar keys %Ignored) unless $opt_quiet; print_errors(\%Error_Codes, \@Errors) if @Errors; -exit unless %Results_by_Language; +if (!%Results_by_Language) { + write_null_results($opt_json, $opt_xml, $opt_report_file); + exit; +} generate_sql($end_time - $start_time, \%Results_by_File, \%Scale_Factor) if $opt_sql; @@ -2192,6 +2264,29 @@ sub exclude_by_regex { # {{{1 delete $rh_unique_source_file->{$file}; } } # 1}}} +sub include_by_regex { # {{{1 + my ($regex, + $rh_unique_source_file, # in/out + $rh_ignored , # out + ) = @_; + my @exclude = (); + foreach my $file (keys %{$rh_unique_source_file}) { + my $keep_this_one = 0; + foreach my $line (read_file($file)) { + if ($line =~ /$regex/) { + $keep_this_one = 1; + last; + } + } + if (!$keep_this_one) { + $rh_ignored->{$file} = "does not satisfy --include-content=$regex"; + push @exclude, $file; + } + } + foreach my $file (@exclude) { + delete $rh_unique_source_file->{$file}; + } +} # 1}}} sub get_max_processes { # {{{1 # If user has specified valid number of processes, use that. if (defined $opt_processes) { @@ -2249,7 +2344,7 @@ sub get_max_processes { # {{{1 return 0; } # 1}}} sub exclude_autogenerated_files { # {{{1 - my ($ra_file_list, # in + my ($ra_file_list, # in/out $rh_Err , # in hash of error codes $raa_errors , # out $rh_Ignored , # out @@ -2271,8 +2366,40 @@ sub exclude_autogenerated_files { # {{{1 } } @{$ra_file_list} = @file_list_minus_autogen; + + if ($opt_force_git) { + my $repo_dir = git_root_dir(); + my @file_list_minus_linguist = (); + # if there's a .gitattributes file, look for linguist-generated + # and linguist-vendored entries to ignore + my $GA = ".gitattributes"; + if (-f $GA) { + foreach my $line (read_file($GA)) { + next unless $line =~ /^(.*?)\s+(linguist-(vendored|generated))/; + my $re = glob2regex($1); + foreach my $file (@{$ra_file_list}) { + my $full_path = File::Spec->catfile($repo_dir, $file); + my $rel_file = File::Spec->abs2rel($full_path, $cwd); + if ($rel_file =~ m{$re}) { +#print "RULE [$rel_file] v [$re]\n"; + $rh_Ignored->{$file} = "matches $GA rule '$line'"; + } else { + push @file_list_minus_linguist, $file; + } + } + } + } + } print "<- exclude_autogenerated_files()\n" if $opt_v > 2; } # 1}}} +sub git_root_dir { # {{{1 + # if in a git repo, return the repo's top level directory + my $cmd = "git rev-parse --show-toplevel"; + print $cmd, "\n" if $opt_v > 1; + my $dir = undef; + chomp($dir = `$cmd`); + die "Not in a git repository" unless $dir +} # 1}}} sub file_extension { # {{{1 my ($fname, ) = @_; $fname =~ m/\.(\w+)$/; @@ -2331,30 +2458,32 @@ sub count_files { # {{{1 next; } - my ($all_line_count, $blank_count, $comment_count, $code_count); - if ($opt_use_sloccount and $Language{$file} =~ /^(C|C\+\+|XML|PHP|Pascal|Java)$/) { - chomp ($blank_count = `grep -cv \"[^[:space:]]\" '$file'`); - chomp ($all_line_count = `cat '$file' | wc -l`); - if ($Language{$file} =~ /^(C|C\+\+)$/) { - $code_count = `cat '$file' | c_count | head -n 1`; - } elsif ($Language{$file} eq "XML") { - $code_count = `cat '$file' | xml_count | head -n 1`; - } elsif ($Language{$file} eq "PHP") { - $code_count = `cat '$file' | php_count | head -n 1`; - } elsif ($Language{$file} eq "Pascal") { - $code_count = `cat '$file' | pascal_count | head -n 1`; - } elsif ($Language{$file} eq "Java") { - $code_count = `cat '$file' | java_count | head -n 1`; + my ($all_line_count, $blank_count, $comment_count, $code_count) = (0, 0, 0, 0); + if (!$opt_only_count_files) { + if ($opt_use_sloccount and $Language{$file} =~ /^(C|C\+\+|XML|PHP|Pascal|Java)$/) { + chomp ($blank_count = `grep -cv \"[^[:space:]]\" '$file'`); + chomp ($all_line_count = `cat '$file' | wc -l`); + if ($Language{$file} =~ /^(C|C\+\+)$/) { + $code_count = `cat '$file' | c_count | head -n 1`; + } elsif ($Language{$file} eq "XML") { + $code_count = `cat '$file' | xml_count | head -n 1`; + } elsif ($Language{$file} eq "PHP") { + $code_count = `cat '$file' | php_count | head -n 1`; + } elsif ($Language{$file} eq "Pascal") { + $code_count = `cat '$file' | pascal_count | head -n 1`; + } elsif ($Language{$file} eq "Java") { + $code_count = `cat '$file' | java_count | head -n 1`; + } else { + die "SLOCCount match failure: file=[$file] lang=[$Language{$file}]"; + } + $code_count = substr($code_count, 0, -2); + $comment_count = $all_line_count - $code_count - $blank_count; } else { - die "SLOCCount match failure: file=[$file] lang=[$Language{$file}]"; + ($all_line_count, + $blank_count , + $comment_count ,) = call_counter($file, $Language{$file}, \@Errors); + $code_count = $all_line_count - $blank_count - $comment_count; } - $code_count = substr($code_count, 0, -2); - $comment_count = $all_line_count - $code_count - $blank_count; - } else { - ($all_line_count, - $blank_count , - $comment_count ,) = call_counter($file, $Language{$file}, \@Errors); - $code_count = $all_line_count - $blank_count - $comment_count; } if ($opt_by_file) { @@ -2448,6 +2577,10 @@ sub count_filesets { # {{{1 # is in a known language. next if $opt_include_ext and not $Include_Ext{ file_extension($f) }; + if (!defined $Language{$fset_b}{$f}) { + $p_ignored{$f} = "excluded or unknown language"; + next; + } next if $opt_include_lang and not $Include_Language{lc($Language{$fset_b}{$f})}; my $this_lang = $Language{$fset_b}{$f}; @@ -2496,7 +2629,7 @@ sub count_filesets { # {{{1 and (not defined $Language{$fset_a}{$f} or not defined $Include_Language{lc($Language{$fset_a}{$f})}); my $this_lang = $Language{$fset_a}{$f}; - if ($this_lang eq "(unknown)") { + if ((not defined $this_lang) or ($this_lang eq "(unknown)")) { $p_ignored{$f} = "unknown language"; next; } @@ -2937,7 +3070,7 @@ sub combine_results { # {{{1 foreach my $file (@{$ra_report_files}) { my $n_results_found = 0; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { warn "Unable to read $file; ignoring.\n"; next; @@ -3312,7 +3445,15 @@ sub xml_yaml_or_json_header { # {{{1 if ($opt_xml) { $header = ""; $header .= "\n" if $opt_xsl; - $header .= "<${type}results> + if ($opt_hide_rate) { + $header .= "<${type}results> +
+ $URL + $version + $sum_files + $sum_lines"; + } else { + $header .= "<${type}results>
$URL $version @@ -3321,6 +3462,7 @@ sub xml_yaml_or_json_header { # {{{1 $sum_lines $file_rate $line_rate"; + } $header .= "\n$report_file" if $opt_report_file; $header .= "\n
"; @@ -3336,7 +3478,14 @@ sub xml_yaml_or_json_header { # {{{1 } } elsif ($opt_yaml or $opt_json) { my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators(); - $header = "${start}${Q}header${Q} : $open_B + if ($opt_hide_rate) { + $header = "${start}${Q}header${Q} : $open_B + ${Q}cloc_url${Q} : ${Q}$URL${Q}${C} + ${Q}cloc_version${Q} : ${Q}$version${Q}${C} + ${Q}n_files${Q} : $sum_files${C} + ${Q}n_lines${Q} : $sum_lines${C}"; + } else { + $header = "${start}${Q}header${Q} : $open_B ${Q}cloc_url${Q} : ${Q}$URL${Q}${C} ${Q}cloc_version${Q} : ${Q}$version${Q}${C} ${Q}elapsed_seconds${Q} : $elapsed_sec${C} @@ -3344,6 +3493,7 @@ sub xml_yaml_or_json_header { # {{{1 ${Q}n_lines${Q} : $sum_lines${C} ${Q}files_per_second${Q} : $file_rate${C} ${Q}lines_per_second${Q} : $line_rate"; + } if ($opt_report_file) { my $Fname = $opt_report_file; $Fname =~ s{\\}{\\\\}g if $ON_WINDOWS; @@ -3808,9 +3958,17 @@ create table t ( my $open_mode = ">"; $open_mode = ">>" if $opt_sql_append; - my $fh = new IO::File; # $opt_sql, "w"; - if (!$fh->open("${open_mode}${opt_sql}")) { - die "Unable to write to $opt_sql $!\n"; + my $fh; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path and $opt_sql ne "-") { + # only use the Win32::LongPath wrapper here when needed, + # and only when not writing to STDOUT. + $fh = open_file($open_mode, $opt_sql, 1); + die "Unable to write to $opt_sql\n" if !defined $fh; + } else { + $fh = new IO::File; # $opt_sql, "w"; + if (!$fh->open("${open_mode}${opt_sql}")) { + die "Unable to write to $opt_sql $!\n"; + } } print $fh $schema unless defined $opt_sql_append; @@ -4863,10 +5021,16 @@ sub top_level_SMB_dir { # {{{1 my ($ra_arg_list,) = @_; # in user supplied file name, directory name, git hash, etc foreach my $entry (@{$ra_arg_list}) { - next unless -d $entry; + next unless is_dir($entry); # gets here if $entry is a directory; now get its nlink value - my @stats = stat($entry); - my $nlink = $stats[3]; + my $nlink; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $stats = statL($entry); + $nlink = $stats->{nlink} if defined $stats; + } else { + my @stats = stat($entry); + $nlink = $stats[3]; + } return 1 if $nlink == 2; # meaning it is an SMB mount } return 0; @@ -4880,12 +5044,12 @@ sub get_git_metadata { # {{{1 my $prt_args = join(",", @{$ra_arg_list}); print "-> get_git_metadata($prt_args)\n" if $opt_v > 2; foreach my $arg (@{$ra_arg_list}) { - next if -f $arg; + next if is_file($arg); my $origin = `git remote get-url origin 2>&1`; next if $origin =~ /^fatal:/; chomp($rh_git_metadata->{$arg}{"origin"} = $origin); chomp($rh_git_metadata->{$arg}{"branch"} = `git symbolic-ref --short HEAD`); - if (-d $arg) { + if (is_dir($arg)) { chomp($rh_git_metadata->{$arg}{"commit"} = `git rev-parse HEAD`); } else { chomp($rh_git_metadata->{$arg}{"commit"} = `git rev-parse $arg`); @@ -4933,7 +5097,7 @@ sub replace_git_hash_with_tarfile { # {{{1 my $i = 0; foreach my $file_or_dir (@{$ra_arg_list}) { ++$i; - if (-r $file_or_dir) { # readable file or dir; not a git hash + if (can_read($file_or_dir)) { # readable file or dir; not a git hash $replacement_arg_list{$i} = $file_or_dir; next; } elsif ($opt_force_git or $file_or_dir =~ m/$hash_regex/) { @@ -5122,7 +5286,7 @@ sub empty_tar { # {{{1 my $cmd = $ON_WINDOWS ? "type nul > $Tarfile" : "tar -cf $Tarfile -T /dev/null"; print $cmd, "\n" if $opt_v; system $cmd; - if (!-r $Tarfile) { + if (!can_read($Tarfile)) { # not readable die "Failed to create empty tarfile."; } @@ -5199,7 +5363,7 @@ sub git_archive { # {{{1 my $cmd = "git archive -o $Tarfile $files_this_commit"; print $cmd, "\n" if $opt_v; system $cmd; - if (!-r $Tarfile or !-s $Tarfile) { + if (!can_read($Tarfile) or !get_size($Tarfile)) { # not readable, or zero sized die "Failed to create tarfile of files from git."; } @@ -5220,7 +5384,7 @@ sub git_archive { # {{{1 my $extract_dir = tempdir( CLEANUP => 0 ); # 1 = delete on exit chdir "$extract_dir"; foreach my $T (@tar_files) { - next unless -f $T and -s $T; + next unless is_file($T) and get_size($T); my $cmd = "tar -x -f \"$T\""; print $cmd, "\n" if $opt_v; system $cmd; @@ -5269,6 +5433,7 @@ sub lower_on_Windows { # {{{1 # }}} sub make_file_list { # {{{1 my ($ra_arg_list, # in file and/or directory names to examine + $iteration , # in 0 if only called once, 1 or 2 if twice for diff $rh_Err , # in hash of error codes $raa_errors , # out errors encountered $rh_ignored , # out files not recognized as computer languages @@ -5278,13 +5443,22 @@ sub make_file_list { # {{{1 my $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : ","; my ($fh, $filename); if ($opt_categorized) { - $filename = $opt_categorized; - $fh = new IO::File $filename, "+>"; # open for read/write + if ($iteration) { + # am being called twice for diff of Left and Right + my $ext = $iteration == 1 ? "L" : "R"; + $filename = $opt_categorized . "-$ext"; + } else { + $filename = $opt_categorized; + } + $fh = open_file('+>', $filename, 1); # open for read/write die "Unable to write to $filename: $!\n" unless defined $fh; } elsif ($opt_sdir) { # write to the user-defined scratch directory - $filename = $opt_sdir . '/cloc_file_list.txt'; - $fh = new IO::File $filename, "+>"; # open for read/write + ++$TEMP_OFF; + my $scr_dir = "$opt_sdir/$TEMP_OFF"; + File::Path::mkpath($scr_dir) unless is_dir($scr_dir); + $filename = $scr_dir . '/cloc_file_list.txt'; + $fh = open_file('+>', $filename, 1); # open for read/write die "Unable to write to $filename: $!\n" unless defined $fh; } else { # let File::Temp create a suitable temporary file @@ -5296,16 +5470,16 @@ sub make_file_list { # {{{1 foreach my $file_or_dir (@{$ra_arg_list}) { my $size_in_bytes = 0; my $F = lower_on_Windows($file_or_dir); - my $ul_F = $upper_lower_map{$F} ? $ON_WINDOWS : $F; - if (!-r $file_or_dir) { + my $ul_F = $ON_WINDOWS ? $upper_lower_map{$F} : $F; + if (!can_read($file_or_dir)) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F]; next; } if (is_file($file_or_dir)) { - if (!(-s $file_or_dir)) { # 0 sized file, named pipe, socket + if (!get_size($file_or_dir)) { # 0 sized file, named pipe, socket $rh_ignored->{$F} = 'zero sized file'; next; - } elsif (-B $file_or_dir and !$opt_read_binary_files) { + } elsif (is_binary($file_or_dir) and !$opt_read_binary_files) { # avoid binary files unless user insists on reading them if ($opt_unicode) { # only ignore if not a Unicode file w/trivial @@ -5353,9 +5527,16 @@ sub make_file_list { # {{{1 next; } if ($opt_no_recurse) { - opendir(DIR, $dir); - push @file_list, grep(-f $_, readdir(DIR)); - closedir(DIR); + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $d = Win32::LongPath->new(); + $d->opendirL($dir); + push @file_list, grep(is_file($_), $d->readdirL()); + $d->closedirL(); + } else { + opendir(DIR, $dir); + push @file_list, grep(is_file($_), readdir(DIR)); + closedir(DIR); + } } else { find({wanted => \&files , preprocess => \&find_preprocessor, @@ -5398,7 +5579,13 @@ sub make_file_list { # {{{1 next; } - my $size_in_bytes = (stat $file)[7]; + my $size_in_bytes; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $stats = statL($file); + $size_in_bytes = $stats->{size} if defined $stats; + } else { + $size_in_bytes = (stat $file)[7]; + } my $language = ""; if ($All_One_Language) { # user over-rode auto-language detection by using @@ -5452,6 +5639,7 @@ sub invoke_generator { # {{{1 # is this file desired? my $want_this_one = 0; foreach my $file_dir (@{$ra_user_inputs}) { + $file_dir =~ s{\\}{/}g if $ON_WINDOWS; if (/^$file_dir/) { $want_this_one = 1; last; @@ -5472,20 +5660,24 @@ sub invoke_generator { # {{{1 push @post_filter, $F if $F =~ m{$opt_match_d}; next; } - if ($opt_not_match_d) { - if ($opt_fullpath and $F =~ m{$opt_not_match_d}) { - $Ignored{$F} = "--not-match-d=$opt_not_match_d"; + if (@opt_not_match_d) { + my $rule; + if ($opt_fullpath and any_match($F, 0, \$rule, @opt_not_match_d)) { + $Ignored{$F} = "--not-match-d=$rule"; next; - } elsif (basename($F) =~ m{$opt_not_match_d}) { - $Ignored{$F} = "--not-match-d (basename) =$opt_not_match_d"; + } elsif (any_match(basename($F), 0, \$rule, @opt_not_match_d)) { + $Ignored{$F} = "--not-match-d (basename) =$rule"; next; } } - if ($opt_not_match_f) { - push @post_filter, $F unless basename($F) =~ m{$opt_not_match_f}; - next; + if (@opt_not_match_f) { + my $rule; + if (any_match(basename($F), 0, \$rule, @opt_not_match_f)) { + $Ignored{$F} = "--not-match-d =$rule"; + next; + } } - my $nBytes = -s $F ; + my $nBytes = get_size($F); if (!$nBytes) { $Ignored{$F} = 'zero sized file'; printf "files(%s) zero size\n", $F if $opt_v > 5; @@ -5499,7 +5691,7 @@ sub invoke_generator { # {{{1 $F if $opt_v > 5; next; } - my $is_bin = -B $F ; + my $is_bin = is_binary($F); printf "files(%s) size=%d -B=%d\n", $F, $nBytes, $is_bin if $opt_v > 5; $is_bin = 0 if $opt_unicode and unicode_file($_); @@ -5510,6 +5702,24 @@ sub invoke_generator { # {{{1 print "<- invoke_generator\n" if $opt_v > 2; return @post_filter; } # 1}}} +sub any_match { # {{{1 + my ($string, $entire, $rs_matched_pattern, @patterns) = @_; + foreach my $pattern (@patterns) { + if ($entire) { + if ($string =~ m{^${pattern}$}) { + ${$rs_matched_pattern} = $pattern; + return 1; + } + } else { + if ($string =~ m{$pattern}) { + ${$rs_matched_pattern} = $pattern; + return 1; + } + } + } + return 0; +} +# }}} sub remove_duplicate_files { # {{{1 my ($fh , # in $rh_Language , # out @@ -5614,16 +5824,17 @@ sub manual_find_preprocessor { # {{{1 $Ignored{$File} = "--exclude-dir=$Exclude_Dir{$got_exclude_dir}"; #print "ignoring $File\n"; } else { - if ($opt_not_match_d) { + if (@opt_not_match_d) { + my $rule; if ($opt_fullpath) { - if ($Dir =~ m{^${opt_not_match_d}$}) { - $Ignored{$File} = "--not-match-d=$opt_not_match_d"; + if (any_match($Dir, 1, \$rule, @opt_not_match_d)) { + $Ignored{$File} = "--not-match-d=$rule"; #print "matched fullpath\n" } else { push @ok, $File; } - } elsif (basename($Dir) =~ m{$opt_not_match_d}) { - $Ignored{$File} = "--not-match-d=$opt_not_match_d"; + } elsif (any_match(basename($Dir), 0, \$rule, @opt_not_match_d)) { + $Ignored{$File} = "--not-match-d=$rule"; #print "matched partial\n" } else { push @ok, $File; @@ -5653,15 +5864,18 @@ sub find_preprocessor { # {{{1 $Ignored{$File::Find::name} = "--exclude-dir=$Exclude_Dir{$F_or_D}"; } else { #printf " F_or_D=%-20s File::Find::name=%s\n", $F_or_D, $File::Find::name; - if ($opt_not_match_d) { + if (@opt_not_match_d) { + my $rule; if ($opt_fullpath) { - if ($File::Find::name =~ m{$opt_not_match_d}) { - $Ignored{$File::Find::name} = "--not-match-d=$opt_not_match_d"; + if (any_match($File::Find::name, 0, \$rule, @opt_not_match_d)) { + $Ignored{$File::Find::name} = "--not-match-d=$rule"; } else { push @ok, $F_or_D; } - } elsif (!-d $F_or_D and basename($File::Find::name) =~ m{$opt_not_match_d}) { - $Ignored{$File::Find::name} = "--not-match-d (basename) =$opt_not_match_d"; + } elsif (!is_dir($F_or_D) and + any_match(basename($File::Find::name), 0, \$rule, + @opt_not_match_d)) { + $Ignored{$File::Find::name} = "--not-match-d (basename) =$rule"; } else { push @ok, $F_or_D; } @@ -5679,23 +5893,24 @@ sub files { # {{{1 # See also find_preprocessor() which prunes undesired directories. my $Dir = fastcwd(); # not $File::Find::dir which just gives relative path + my $rule; if ($opt_fullpath) { # look at as much of the path as is known if ($opt_match_f ) { return unless $File::Find::name =~ m{$opt_match_f}; } - if ($opt_not_match_f) { - return if $File::Find::name =~ m{$opt_not_match_f}; + if (@opt_not_match_f) { + return if any_match($File::Find::name, 0, \$rule, @opt_not_match_f); } } else { # only look at the basename if ($opt_match_f ) { return unless /$opt_match_f/; } - if ($opt_not_match_f) { return if /$opt_not_match_f/; } + if (@opt_not_match_f) { return if any_match($_, 0, \$rule, @opt_not_match_f)} } if ($opt_match_d ) { return unless $Dir =~ m{$opt_match_d} } - my $nBytes = -s $_ ; - if (!$nBytes and -f $File::Find::name) { + my $nBytes = get_size($_); + if (!$nBytes and is_file($File::Find::name)) { $Ignored{$File::Find::name} = 'zero sized file'; printf "files(%s) zero size\n", $File::Find::name if $opt_v > 5; } @@ -5709,7 +5924,7 @@ sub files { # {{{1 return; } my $is_dir = is_dir($_); - my $is_bin = -B $_ ; + my $is_bin = is_binary($_); printf "files(%s) size=%d is_dir=%d -B=%d\n", $File::Find::name, $nBytes, $is_dir, $is_bin if $opt_v > 5; $is_bin = 0 if $opt_unicode and unicode_file($_); @@ -5731,10 +5946,79 @@ sub archive_files { # {{{1 if $File::Find::name =~ m{$ext$}; } } # 1}}} +sub open_file { # {{{1 + # portable method to open a file. On Windows this uses Win32::LongPath to + # allow reading/writing files past the 255 char path length limit. When on + # other operating systems, $use_new_file can be used to specify opening a + # file with `new IO::File` instead of `open`. Note: `openL` doesn't support + # the C-like fopen modes ("w", "r+", etc.), it only supports Perl mode + # strings (">", "+<", etc.). So be sure to only use Perl mode strings to + # ensure compatibility. Additionally, openL doesn't handle pipe modes; if + # you need to open a pipe/STDIN/STDOUT, use the native `open` function. + my ($mode, # Perl file mode; can not be C-style file mode + $filename, # filename to open + $use_new_file, # whether to use `new IO::File` or `open` when not using Win32::LongPath + ) = @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $file = undef; + openL(\$file, $mode, $filename); + return $file; + } elsif ($use_new_file) { + return new IO::File $filename, $mode; + } + my $file = undef; + open($file, $mode, $filename); + return $file; +} # 1}}} +sub unlink_file { # {{{1 + # portable method to unlink a file. On Windows this uses Win32::LongPath to + # allow unlinking files past the 255 char path length limit. Otherwise, the + # native `unlink` will be used. + my $filename = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return unlinkL($filename); + } + return unlink $filename; +} # 1}}} +sub is_binary { # {{{1 + # portable method to test if item is a binary file. For Windows, + # Win32::LongPath doesn't provide a testL option for -B, but -B + # accepts a filehandle which does work with files opened with openL. + my $item = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $IN = open_file('<', $item, 0); + if (defined $IN) { + my $res = -B $IN; + close($IN); + return $res; + } + return; + } + return (-B $item); +} # 1}}} +sub can_read { # {{{1 + # portable method to test if item can be read + my $item = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return testL('r', $item); + } + return (-r $item); +} # 1}}} +sub get_size { # {{{1 + # portable method to get size in bytes of a file + my $filename = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return testL('s', $filename); + } + return (-s $filename); +} # 1}}} sub is_file { # {{{1 # portable method to test if item is a file # (-f doesn't work in ActiveState Perl on Windows) my $item = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return testL('f', $item); + } return (-f $item); # Was: @@ -5749,6 +6033,9 @@ sub is_file { # {{{1 } # 1}}} sub is_dir { # {{{1 my $item = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return testL('d', $item); + } return (-d $item); # should work everywhere now (July 2017) # Was: @@ -6024,11 +6311,11 @@ sub first_line { # {{{1 ) = @_; my $line = ""; print "-> first_line($file, $n_lines)\n" if $opt_v > 2; - if (!-r $file) { + if (!can_read($file)) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $line; } - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; print "<- first_line($file, $n_lines)\n" if $opt_v > 2; @@ -6088,7 +6375,7 @@ sub different_files { # {{{1 my %file_hash = (); # file_hash{md5 hash} = [ file1, file2, ... ] foreach my $F (@{$ra_files}) { next if is_dir($F); # needed for Windows - my $IN = new IO::File $F, "r"; + my $IN = open_file('<', $F, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F]; $rh_ignored->{$F} = 'cannot read'; @@ -6155,11 +6442,11 @@ sub call_counter { # {{{1 my @lines = (); my $ascii = ""; - if (-B $file and $opt_unicode) { + if (is_binary($file) and $opt_unicode) { # was binary so must be unicode $/ = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); my $bin_text = <$IN>; $IN->close; $/ = "\n"; @@ -6287,12 +6574,12 @@ sub write_file { # {{{1 mkpath($volume . $directories, 1, 0777); my $OUT = undef; - unlink $file; + unlink_file($file); if ($opt_file_encoding) { # $OUT = IO::File->new($file, ">:$opt_file_encoding"); # doesn't work? - open($OUT, "> :encoding($opt_file_encoding)", $file); + $OUT = open_file(">:encoding($opt_file_encoding)", $file, 0); } else { - $OUT = new IO::File $file, "w"; + $OUT = open_file('>', $file, 1); } my $n_col = undef; @@ -6365,7 +6652,7 @@ sub write_file { # {{{1 } $OUT->close; - if (-r $file) { + if (can_read($file)) { print "Wrote $file" unless $opt_quiet; print ", $CLOC_XSL" if $opt_xsl and $opt_xsl eq $CLOC_XSL; print "\n" unless $opt_quiet; @@ -6456,7 +6743,7 @@ sub read_file { # {{{1 ); my @lines = (); - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (defined $IN) { @lines = <$IN>; $IN->close; @@ -7242,7 +7529,7 @@ sub really_is_bf { # {{{1 $decision, $file, $ratio, $n_bf_indicators if $opt_v > 2; return $decision; } # 1}}} -sub remove_intented_block { # {{{1 +sub remove_indented_block { # {{{1 # Haml block comments are defined by a silent comment marker like # / # or @@ -7251,7 +7538,7 @@ sub remove_intented_block { # {{{1 # http://haml.info/docs/yardoc/file.REFERENCE.html#comments my ($ra_lines, $regex, ) = @_; - print "-> remove_intented_block\n" if $opt_v > 2; + print "-> remove_indented_block\n" if $opt_v > 2; my @save_lines = (); my $in_comment = 0; @@ -7282,7 +7569,7 @@ sub remove_intented_block { # {{{1 push @save_lines, $line; } - print "<- remove_intented_block\n" if $opt_v > 2; + print "<- remove_indented_block\n" if $opt_v > 2; return @save_lines; } # 1}}} sub remove_haml_block { # {{{1 @@ -7294,7 +7581,7 @@ sub remove_haml_block { # {{{1 # http://haml.info/docs/yardoc/file.REFERENCE.html#comments my ($ra_lines, ) = @_; - return remove_intented_block($ra_lines, '^(\s*)(/|-#)\s*$'); + return remove_indented_block($ra_lines, '^(\s*)(/|-#)\s*$'); } # 1}}} sub remove_pug_block { # {{{1 @@ -7303,7 +7590,7 @@ sub remove_pug_block { # {{{1 # followed by indented text on subsequent lines. # http://jade-lang.com/reference/comments/ my ($ra_lines, ) = @_; - return remove_intented_block($ra_lines, '^(\s*)(//)\s*$'); + return remove_indented_block($ra_lines, '^(\s*)(//)\s*$'); } # 1}}} sub remove_OCaml_comments { # {{{1 my ($ra_lines, ) = @_; @@ -7338,7 +7625,7 @@ sub remove_slim_block { # {{{1 # followed by indented text on subsequent lines. # http://www.rubydoc.info/gems/slim/frames my ($ra_lines, ) = @_; - return remove_intented_block($ra_lines, '^(\s*)(/[^!])'); + return remove_indented_block($ra_lines, '^(\s*)(/[^!])'); } # 1}}} sub add_newlines { # {{{1 my ($ra_lines, ) = @_; @@ -7503,10 +7790,10 @@ sub smarty_to_C { # {{{1 sub determine_lit_type { # {{{1 my ($file) = @_; - open (FILE, $file); - while () { - if (m/^\\begin\{code\}/) { close FILE; return 2; } - if (m/^>\s/) { close FILE; return 1; } + my $FILE = open_file('<', $file, 0); + while (<$FILE>) { + if (m/^\\begin\{code\}/) { close $FILE; return 2; } + if (m/^>\s/) { close $FILE; return 1; } } return 0; @@ -7655,6 +7942,7 @@ sub set_constants { # {{{1 'aspx' => 'ASP.NET' , 'master' => 'ASP.NET' , 'sitemap' => 'ASP.NET' , + 'asy' => 'Asymptote' , 'cshtml' => 'Razor' , 'razor' => 'Razor' , # Client-side Blazor 'nawk' => 'awk' , @@ -7726,6 +8014,9 @@ sub set_constants { # {{{1 '_coffee' => 'CoffeeScript' , 'coffee' => 'CoffeeScript' , 'component' => 'Visualforce Component' , + 'cg3' => 'Constraint Grammar' , + 'rlx' => 'Constraint Grammar' , + 'Containerfile' => 'Containerfile' , 'cpp' => 'C++' , 'CPP' => 'C++' , 'cr' => 'Crystal' , @@ -7886,6 +8177,7 @@ sub set_constants { # {{{1 'haml' => 'Haml' , 'handlebars' => 'Handlebars' , 'hbs' => 'Handlebars' , + 'ha' => 'Hare' , 'hxsl' => 'Haxe' , 'hx' => 'Haxe' , 'HC' => 'HolyC' , @@ -7923,6 +8215,7 @@ sub set_constants { # {{{1 'java' => 'Java' , 'jcl' => 'JCL' , # IBM Job Control Lang. 'jl' => 'Lisp/Julia' , + 'jai' => 'Jai' , 'xsjslib' => 'JavaScript' , 'xsjs' => 'JavaScript' , 'ssjs' => 'JavaScript' , @@ -7984,6 +8277,7 @@ sub set_constants { # {{{1 'lhs' => 'Haskell' , 'lex' => 'lex' , 'l' => 'lex' , + 'ld' => 'Linker Script' , 'lem' => 'Lem' , 'less' => 'LESS' , 'lfe' => 'LFE' , @@ -8054,6 +8348,8 @@ sub set_constants { # {{{1 'mps' => 'MUMPS' , 'mth' => 'Teamcenter mth' , 'n' => 'Nemerle' , + 'nlogo' => 'NetLogo' , + 'nls' => 'NetLogo' , 'nims' => 'Nim' , 'nimrod' => 'Nim' , 'nimble' => 'Nim' , @@ -8108,6 +8404,7 @@ sub set_constants { # {{{1 'rakumod' => 'Raku' , 'pom.xml' => 'Maven' , 'pom' => 'Maven' , + 'scad' => 'OpenSCAD' , 'yap' => 'Prolog' , 'prolog' => 'Prolog' , 'P' => 'Prolog' , @@ -8208,11 +8505,13 @@ sub set_constants { # {{{1 'sed' => 'sed' , 'sp' => 'SparForte' , 'sol' => 'Solidity' , + 'p4' => 'P4' , 'ses' => 'Patran Command Language' , 'pcl' => 'Patran Command Language' , 'peg' => 'PEG' , 'pegjs' => 'peg.js' , 'peggy' => 'peggy' , + 'pest' => 'Pest' , 'tspeg' => 'tspeg' , 'jspeg' => 'tspeg' , 'pl1' => 'PL/I' , @@ -8221,6 +8520,7 @@ sub set_constants { # {{{1 'puml' => 'PlantUML' , 'properties' => 'Properties' , 'po' => 'PO File' , + 'pony' => 'Pony' , 'pbt' => 'PowerBuilder' , 'sra' => 'PowerBuilder' , 'srf' => 'PowerBuilder' , @@ -8592,10 +8892,12 @@ sub set_constants { # {{{1 'dockerfile' => 'Dockerfile' , 'dockerfile.m4' => 'Dockerfile' , 'dockerfile.cmake' => 'Dockerfile' , + 'Containerfile' => 'Containerfile' , ); # 1}}} %{$rh_Language_by_Prefix} = ( # {{{1 'Dockerfile' => 'Dockerfile' , + 'Containerfile' => 'Containerfile' , ); # 1}}} %{$rhaa_Filters_by_Language} = ( # {{{1 @@ -8675,6 +8977,11 @@ sub set_constants { # {{{1 [ 'remove_inline' , '--.*$' ], [ 'remove_matches' , '^\*' ], # z/OS Assembly ], + 'Asymptote' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'call_regexp_common' , 'C++' ], + ], 'AutoHotkey' => [ [ 'remove_matches' , '^\s*;' ], [ 'remove_inline' , ';.*$' ], @@ -8758,6 +9065,10 @@ sub set_constants { # {{{1 [ 'remove_matches' , '^\s*#' ], [ 'remove_inline' , '#.*$' ], ], + 'Constraint Grammar' => [ + [ 'remove_matches' , '^\s*#' ], + [ 'remove_inline' , '#.*$' ], + ], 'CUDA' => [ [ 'rm_comments_in_strings', '"', '/*', '*/' ], [ 'rm_comments_in_strings', '"', '//', '' ], @@ -8820,6 +9131,10 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'Containerfile' => [ + [ 'remove_matches' , '^\s*#' ], + [ 'remove_inline' , '#.*$' ], + ], 'Coq' => [ [ 'remove_between_general', '(*', '*)' ], ], @@ -9081,6 +9396,12 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', "'''", '//', '', 1], [ 'call_regexp_common' , 'C++' ], ], + 'Haml' => [ + [ 'remove_haml_block' , ], + [ 'remove_html_comments', ], + [ 'remove_matches' , '^\s*/\s*\S+' ], + [ 'remove_matches' , '^\s*-#\s*\S+' ], + ], 'Handlebars' => [ [ 'remove_between_general', '{{!--', '--}}' ], [ 'remove_between_general', '{{!', '}}' ], @@ -9098,11 +9419,9 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], - 'Haml' => [ - [ 'remove_haml_block' , ], - [ 'remove_html_comments', ], - [ 'remove_matches' , '^\s*/\s*\S+' ], - [ 'remove_matches' , '^\s*-#\s*\S+' ], + 'Hare' => [ + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'remove_matches' , '//.*$' ], ], 'Haxe' => [ [ 'rm_comments_in_strings', '"', '/*', '*/' ], @@ -9173,6 +9492,11 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'Jai' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'call_regexp_common' , 'C++' ], + ], 'Jam' => [ [ 'remove_matches' , '^\s*#' ], [ 'remove_inline' , '#.*$' ], @@ -9271,6 +9595,10 @@ sub set_constants { # {{{1 [ 'remove_matches' , '^\s*;' ], [ 'remove_between_general', '#|', '|#' ], ], + 'Linker Script' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/'], + [ 'call_regexp_common', 'C' ], + ], 'liquid' => [ [ 'remove_between_general', '{% comment %}', '{% endcomment %}' ], @@ -9364,6 +9692,7 @@ sub set_constants { # {{{1 [ 'call_regexp_common' , 'C++' ], ], 'OCaml' => [ + [ 'rm_comments_in_strings', '"', '(*', '*)', 1 ], [ 'remove_OCaml_comments', ], ], 'OpenCL' => [ @@ -9376,6 +9705,7 @@ sub set_constants { # {{{1 [ 'remove_matches' , '##.*$' ], ], 'Markdown' => [ + [ 'remove_between_general', '' ], [ 'remove_between_regex', '\[(comment|\/\/)?\]\s*:?\s*(<\s*>|#)?\s*\(.*?', '.*?\)' ], # http://stackoverflow.com/questions/4823468/comments-in-markdown @@ -9392,6 +9722,10 @@ sub set_constants { # {{{1 # [ 'call_regexp_common' , 'C' ], [ 'remove_inline' , '#.*$' ], ], + 'NetLogo' => [ + [ 'remove_matches' , '^\s*;' ], + [ 'remove_inline' , ';.*$' ], + ], 'Nix' => [ [ 'call_regexp_common' , 'C' ], [ 'remove_matches' , '^\s*#' ], @@ -9406,6 +9740,11 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'OpenSCAD' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'call_regexp_common' , 'C++' ], + ], 'Oracle Forms' => [ [ 'call_regexp_common' , 'C' ], ], 'Oracle Reports' => [ [ 'call_regexp_common' , 'C' ], ], 'Oracle PL/SQL' => [ @@ -9426,6 +9765,11 @@ sub set_constants { # {{{1 [ 'call_regexp_common' , 'C' ], [ 'remove_inline' , '#.*$' ], ], + 'P4' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'call_regexp_common' , 'C++' ], + ], 'Patran Command Language'=> [ [ 'remove_matches' , '^\s*#' ], [ 'remove_matches' , '^\s*\$#' ], @@ -9451,6 +9795,10 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'Pest' => [ + [ 'remove_matches' , '^\s*//' ], + [ 'remove_inline' , '//.*$' ], + ], 'tspeg' => [ [ 'rm_comments_in_strings', '"', '/*', '*/' ], [ 'rm_comments_in_strings', '"', '//', '' ], @@ -9479,6 +9827,12 @@ sub set_constants { # {{{1 'PO File' => [ [ 'remove_matches' , '^\s*#[^,]' ], # '#,' is not a comment ], + 'Pony' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'docstring_to_C' ], + [ 'call_regexp_common' , 'C++' ], + ], 'PowerBuilder' => [ [ 'rm_comments_in_strings', '"', '/*', '*/' ], [ 'rm_comments_in_strings', '"', '//', '' ], @@ -10305,6 +10659,7 @@ sub set_constants { # {{{1 'Assembly' => 0.25, 'Assembly (macro)' => 0.51, 'associative default' => 1.25, + 'Asymptote' => 2.50, 'autocoder' => 0.25, 'AutoHotkey' => 1.29, 'awk' => 3.81, @@ -10338,9 +10693,8 @@ sub set_constants { # {{{1 'COBOL ii' => 0.75, 'COBOL/400' => 0.88, 'CoffeeScript' => 2.00, - 'common lisp' => 1.25, - 'concurrent pascal' => 1.00, - 'conniver' => 1.25, + 'Constraint Grammar' => 4.00, + 'Containerfile' => 2.00, 'Coq' => 5.00, 'Crystal' => 2.50, 'Crystal Reports' => 4.00, @@ -10356,7 +10710,6 @@ sub set_constants { # {{{1 'DAL' => 1.50, 'Dart' => 2.00, 'DenizenScript' => 1.00, - 'data base default' => 2.00, 'Delphi Form' => 2.00, 'DIET' => 2.00, 'diff' => 1.00, @@ -10380,7 +10733,6 @@ sub set_constants { # {{{1 'ERB' => 2.00, 'Erlang' => 2.11, 'Fennel' => 2.50, - 'filemaker pro' => 2.22, 'Finite State Language' => 2.00, 'Focus' => 1.90, 'Forth' => 1.25, @@ -10399,7 +10751,6 @@ sub set_constants { # {{{1 'Gleam' => 2.50, 'GLSL' => 2.00, 'gml' => 1.74, - 'golden common lisp' => 1.25, 'gpss' => 1.74, 'guest' => 2.86, 'guru' => 1.63, @@ -10413,14 +10764,15 @@ sub set_constants { # {{{1 'GraphQL' => 4.00, 'Groovy' => 4.10, 'gw basic' => 0.82, - 'Harbour' => 2.00, - 'Haskell' => 2.11, 'HCL' => 2.50, 'high c' => 0.63, 'hlevel' => 1.38, 'hp basic' => 0.63, 'Haml' => 2.50, 'Handlebars' => 2.50, + 'Harbour' => 2.00, + 'Hare' => 2.50, + 'Haskell' => 2.11, 'Haxe' => 2.00, 'HolyC' => 2.50, 'Hoon' => 2.00, @@ -10439,41 +10791,15 @@ sub set_constants { # {{{1 'Visual Studio Module' => 1.00, 'Visual Studio Solution' => 1.00, 'HLSL' => 2.00, - 'HTML 2' => 5.00, - 'HTML 3' => 5.33, - 'huron' => 5.00, - 'ibm adf i' => 4.00, - 'ibm adf ii' => 4.44, - 'ibm advanced basic' => 0.82, - 'ibm compiled basic' => 0.88, - 'ibm vs cobol' => 0.75, - 'ibm vs cobol ii' => 0.88, - 'ices' => 1.13, - 'icon' => 1.00, - 'ideal' => 1.54, - 'idms' => 2.00, 'Idris' => 2.00, 'Literate Idris' => 2.00, 'Igor Pro' => 4.00, 'Imba' => 3.00, - 'imprs' => 2.00, - 'informix' => 2.58, - 'ingres' => 2.00, 'INI' => 1.00, - 'inquire' => 6.15, - 'insight2' => 1.63, - 'install/1' => 5.00, 'InstallShield' => 1.90, - 'intellect' => 1.51, - 'interlisp' => 1.38, - 'interpreted basic' => 0.75, - 'interpreted c' => 0.63, 'IPL' => 2.00, - 'iqlisp' => 1.38, - 'iqrp' => 6.15, - 'j2ee' => 1.60, + 'Jai' => 1.13, 'Jam' => 2.00, - 'janus' => 1.13, 'Java' => 1.36, 'JavaScript' => 1.48, 'JavaServer Faces' => 1.5 , @@ -10484,125 +10810,55 @@ sub set_constants { # {{{1 'JSX' => 1.48, 'Velocity Template Language' => 1.00, 'JCL' => 1.67, - 'joss' => 0.75, - 'jovial' => 0.75, - 'jsp' => 1.36, 'Juniper Junos' => 2.00, - 'kappa' => 2.00, - 'kbms' => 1.63, - 'kcl' => 1.25, - 'kee' => 1.63, - 'keyplus' => 2.00, - 'kl' => 1.25, - 'klo' => 1.25, - 'knowol' => 1.63, - 'krl' => 1.38, 'kvlang' => 2.00, 'Kermit' => 2.00, 'Korn Shell' => 3.81, 'Kotlin' => 2.00, - 'ladder logic' => 2.22, - 'lambit/l' => 1.25, - 'lattice c' => 0.63, 'Lean' => 3.00, 'LESS' => 1.50, 'Lem' => 3.00, 'LFE' => 1.25, - 'liana' => 0.63, - 'lilith' => 1.13, - 'linc ii' => 5.71, + 'Linker Script' => 1.00, 'liquid' => 3.00, 'Lisp' => 1.25, 'LiveLink OScript' => 3.5 , 'LLVM IR' => 0.90, - 'loglisp' => 1.38, 'Logos' => 2.00, 'Logtalk' => 2.00, - 'loops' => 3.81, - 'lotus 123 dos' => 13.33, - 'lotus macros' => 0.75, - 'lotus notes' => 3.64, - 'lucid 3d' => 13.33, - 'lyric' => 1.51, 'm4' => 1.00, - 'm' => 5.00, - 'macforth' => 1.25, - 'mach1' => 2.00, - 'machine language' => 0.13, - 'maestro' => 5.00, - 'magec' => 5.00, - 'magik' => 3.81, - 'Lake' => 3.81, 'make' => 2.50, - 'Mako' => 1.50, # Not sure about the scaling. - 'mantis' => 2.96, - 'mapper' => 0.99, - 'mark iv' => 2.00, - 'mark v' => 2.22, + 'Mako' => 1.50, 'Markdown' => 1.00, 'mathcad' => 16.00, 'Maven' => 1.90, - 'mdl' => 2.22, - 'mentor' => 1.51, - 'mesa' => 0.75, 'Meson' => 1.00, 'Metal' => 1.51, - 'microfocus cobol' => 1.00, - 'microforth' => 1.25, - 'microsoft c' => 0.63, - 'microstep' => 4.00, - 'miranda' => 2.00, - 'model 204' => 2.11, - 'modula 2' => 1.00, - 'mosaic' => 13.33, - # 'ms c ++ v. 7' => 1.51, - 'ms compiled basic' => 0.88, - 'msl' => 1.25, - 'mulisp' => 1.25, 'MUMPS' => 4.21, 'Mustache' => 1.75, 'Nastran' => 1.13, - 'natural' => 1.54, - 'natural 1' => 1.51, - 'natural 2' => 1.74, - 'natural construct' => 3.20, - 'natural language' => 0.03, 'Nemerle' => 2.50, - 'netron/cap' => 4.21, - 'nexpert' => 1.63, - 'nial' => 1.63, + 'NetLogo' => 4.00, 'Nim' => 2.00, 'Nix' => 2.70, 'Nunjucks' => 1.5 , - 'object assembler' => 1.25, - 'object lisp' => 2.76, - 'object logo' => 2.76, - 'object pascal' => 2.76, - 'object star' => 5.00, 'Objective-C' => 2.96, 'Objective-C++' => 2.96, 'OCaml' => 3.00, 'Odin' => 2.00, - 'ogl' => 1.00, - 'omnis 7' => 2.00, - 'oodl' => 2.76, - 'ops' => 1.74, - 'ops5' => 1.38, - 'oracle' => 2.76, + 'OpenSCAD' => 1.00, 'Oracle Reports' => 2.76, 'Oracle Forms' => 2.67, 'Oracle Developer/2000' => 3.48, - 'oscar' => 0.75, 'Other' => 1.00, - 'pacbase' => 1.67, - 'pace' => 2.00, - 'paradox/pal' => 2.22, + 'P4' => 1.5 , 'Pascal' => 0.88, 'Patran Command Language' => 2.50, 'Perl' => 4.00, 'PEG' => 3.00, 'peg.js' => 3.00, 'peggy' => 3.00, + 'Pest' => 2.00, 'tspeg' => 3.00, 'Pig Latin' => 1.00, 'PL/I' => 1.38, @@ -10610,6 +10866,7 @@ sub set_constants { # {{{1 'PlantUML' => 2.00, 'Oracle PL/SQL' => 2.58, 'PO File' => 1.50, + 'Pony' => 3.00, 'PowerBuilder' => 3.33, 'PowerShell' => 3.00, 'problemoriented default' => 1.13, @@ -10669,13 +10926,10 @@ sub set_constants { # {{{1 'Specman e' => 2.00, 'SQL' => 2.29, 'Squirrel' => 2.50, - 'statistical default' => 2.50, 'Standard ML' => 3.00, 'Stata' => 3.00, 'Stylus' => 1.48, 'SugarSS' => 2.50, - 'superbase 1.3' => 2.22, - 'surpass' => 13.33, 'Svelte' => 2.00, 'SVG' => 1.00, 'Swift' => 2.50, @@ -10703,23 +10957,14 @@ sub set_constants { # {{{1 'Verilog-SystemVerilog' => 1.51, 'VHDL' => 4.21, 'vim script' => 3.00, - 'visual basic' => 1.90, 'Visual Basic' => 2.76, 'VB for Applications' => 2.76, 'Visual Basic .NET' => 2.76, 'Visual Basic Script' => 2.76, - 'visual c++' => 2.35, - 'visual cobol' => 4.00, 'Visual Fox Pro' => 4.00, # Visual Fox Pro is not available in the language gearing ratios listed at Mayes Consulting web site - 'visual objects' => 5.00, - 'visualage' => 3.81, 'Visualforce Component' => 1.9 , 'Visualforce Page' => 1.9 , - 'visualgen' => 4.44, - 'VM' => 2.00, 'Vuejs Component' => 2.00, - 'vulcan' => 1.25, - 'web scripts' => 5.33, 'Web Services Description' => 1.00, 'WebAssembly' => 0.45, 'WGSL' => 2.50, @@ -10729,7 +10974,6 @@ sub set_constants { # {{{1 'WiX source' => 1.90, 'WiX include' => 1.90, 'WiX string localization' => 1.90, - 'wizard' => 2.86, 'WXML' => 1.90, 'WXSS' => 1.00, 'xBase' => 2.00, @@ -10741,9 +10985,6 @@ sub set_constants { # {{{1 'yacc' => 1.51, 'yacc++' => 1.51, 'YAML' => 0.90, - 'zbasic' => 0.88, - 'zim' => 4.21, - 'zlisp' => 1.25, 'Expect' => 2.00, 'Gencat NLS' => 1.50, 'C/C++ Header' => 1.00, @@ -10931,7 +11172,7 @@ sub matlab_or_objective_C { # {{{1 # BeginPackage ${$rs_language} = ""; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return; @@ -10976,7 +11217,7 @@ printf ".m: ; obj C=% 2d matlab=% 2d mumps=% 2d mercury= % 2d\n", $obje # Objective-C without a doubt $objective_C_points = 1000; $matlab_points = 0; -printf ".m: #includ obj C=% 2d matlab=% 2d mumps=% 2d mercury= % 2d\n", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG; +printf ".m: #include obj C=% 2d matlab=% 2d mumps=% 2d mercury= % 2d\n", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG; $has_braces = 2; last; } elsif (m{^\s*@(interface|implementation|protocol|public|protected|private|end)\s}o) { @@ -11031,7 +11272,7 @@ sub Lisp_or_OpenCL { # {{{1 print "-> Lisp_or_OpenCL\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11063,7 +11304,7 @@ sub Lisp_or_Julia { # {{{1 print "-> Lisp_or_Julia\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11095,7 +11336,7 @@ sub Perl_or_Prolog { # {{{1 print "-> Perl_or_Prolog\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11152,7 +11393,7 @@ sub IDL_or_QtProject { # {{{1 print "-> IDL_or_QtProject($file)\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11198,7 +11439,7 @@ sub Ant_or_XML { # {{{1 print "-> Ant_or_XML($file)\n" if $opt_v > 2; my $lang = "XML"; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11236,7 +11477,7 @@ sub Maven_or_XML { # {{{1 print "-> Maven_or_XML($file)\n" if $opt_v > 2; my $lang = "XML"; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11276,7 +11517,7 @@ sub pascal_or_puppet { # {{{1 print "-> pascal_or_puppet\n" if $opt_v > 2; ${$rs_language} = ""; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return; @@ -11344,7 +11585,7 @@ sub Forth_or_Fortran { # {{{1 print "-> Forth_or_Fortran\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11374,7 +11615,7 @@ sub Forth_or_Fsharp { # {{{1 print "-> Forth_or_Fsharp\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11404,7 +11645,7 @@ sub Verilog_or_Coq { # {{{1 print "-> Verilog_or_Coq\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11439,7 +11680,7 @@ sub TypeScript_or_QtLinguist { # {{{1 print "-> TypeScript_or_QtLinguist\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11470,7 +11711,7 @@ sub Qt_or_Glade { # {{{1 print "-> Qt_or_Glade\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11502,7 +11743,7 @@ sub Csharp_or_Smalltalk { # {{{1 print "-> Csharp_or_Smalltalk($file)\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11545,7 +11786,7 @@ sub Visual_Basic_or_TeX_or_Apex { # {{{1 print "-> Visual_Basic_or_TeX_or_Apex($file)\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11594,7 +11835,7 @@ sub Scheme_or_SaltStack { # {{{1 print "-> Scheme_or_SaltStack($file)\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11681,12 +11922,12 @@ sub test_alg_diff { # {{{1 my ($file_1 , $file_2 ) = @_; - my $fh_1 = new IO::File $file_1, "r"; + my $fh_1 = open_file('<', $file_1, 1); die "Unable to read $file_1: $!\n" unless defined $fh_1; chomp(my @lines_1 = <$fh_1>); $fh_1->close; - my $fh_2 = new IO::File $file_2, "r"; + my $fh_2 = open_file('<', $file_2, 1); die "Unable to read $file_2: $!\n" unless defined $fh_2; chomp(my @lines_2 = <$fh_2>); $fh_2->close; @@ -12219,10 +12460,9 @@ sub get_leading_dirs { # {{{1 ########++$candidate_leading_dir_R{$leading_dir_R}; } #use Data::Dumper::Simple; - if ($ON_WINDOWS) { - $L_drop =~ s{\\}{/}g; - $R_drop =~ s{\\}{/}g; - } + # at this point path separator on Windows is already / + $L_drop =~ s{//}{/}g; + $R_drop =~ s{//}{/}g; #print "L_drop=$L_drop\n"; #print "R_drop=$R_drop\n"; return $L_drop, $R_drop, 1; @@ -12412,10 +12652,10 @@ sub unicode_file { # {{{1 my $file = shift @_; print "-> unicode_file($file)\n" if $opt_v > 2; - return 0 if (-s $file > 2_000_000); + return 0 if (get_size($file) > 2_000_000); # don't bother trying to test binary files bigger than 2 MB - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { warn "Unable to read $file; ignoring.\n"; return 0; @@ -13116,7 +13356,7 @@ sub combine_diffs { # {{{1 my %HoH = (); foreach my $file (@{$ra_files}) { - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { warn "Unable to read $file; ignoring.\n"; next; @@ -13194,7 +13434,7 @@ sub combine_csv_diffs { # {{{1 my %sum = (); # sum{ language } = array of 17 values foreach my $file (@{$ra_files}) { - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { warn "Unable to read $file; ignoring.\n"; next; @@ -13333,6 +13573,7 @@ sub load_from_config_file { # {{{1 $rs_counted , $rs_include_ext , $rs_include_lang , + $rs_include_content , $rs_exclude_content , $rs_exclude_lang , $rs_exclude_dir , @@ -13341,6 +13582,7 @@ sub load_from_config_file { # {{{1 $rs_extract_with , $rs_found , $rs_count_diff , + $rs_diff_list_files , $rs_diff , $rs_diff_alignment , $rs_diff_timeout , @@ -13381,9 +13623,9 @@ sub load_from_config_file { # {{{1 $rs_md , $rs_fullpath , $rs_match_f , - $rs_not_match_f , + $ra_not_match_f , $rs_match_d , - $rs_not_match_d , + $ra_not_match_d , $rs_list_file , $rs_help , $rs_skip_win_hidden , @@ -13420,10 +13662,10 @@ sub load_from_config_file { # {{{1 # $ENV{'APPDATA'} . 'cloc' print "-> load_from_config_file($config_file)\n" if $opt_v and $opt_v > 2; - if (!-f $config_file) { + if (!is_file($config_file)) { print "<- load_from_config_file() (no such file: $config_file)\n" if $opt_v and $opt_v > 2; return; - } elsif (!-r $config_file) { + } elsif (!can_read($config_file)) { print "<- load_from_config_file() (unable to read $config_file)\n" if $opt_v and $opt_v > 2; return; } @@ -13442,6 +13684,7 @@ sub load_from_config_file { # {{{1 } elsif (!defined ${$rs_counted} and /^counted(=|\s+)(.*?)$/) { ${$rs_counted} = $2; } elsif (!defined ${$rs_include_ext} and /^(?:include_ext|include-ext)(=|\s+)(.*?)$/) { ${$rs_include_ext} = $2; } elsif (!defined ${$rs_include_lang} and /^(?:include_lang|include-lang)(=|\s+)(.*?)$/) { ${$rs_include_lang} = $2; + } elsif (!defined ${$rs_include_content} and /^(?:include_content|include-content)(=|\s+)(.*?)$/) { ${$rs_include_content} = $2; } elsif (!defined ${$rs_exclude_content} and /^(?:exclude_content|exclude-content)(=|\s+)(.*?)$/) { ${$rs_exclude_content} = $2; } elsif (!defined ${$rs_exclude_lang} and /^(?:exclude_lang|exclude-lang)(=|\s+)(.*?)$/) { ${$rs_exclude_lang} = $2; } elsif (!defined ${$rs_exclude_dir} and /^(?:exclude_dir|exclude-dir)(=|\s+)(.*?)$/) { ${$rs_exclude_dir} = $2; @@ -13449,6 +13692,7 @@ sub load_from_config_file { # {{{1 } elsif (!defined ${$rs_extract_with} and /^(?:extract_with|extract-with)(=|\s+)(.*?)$/) { ${$rs_extract_with} = $2; } elsif (!defined ${$rs_found} and /^found(=|\s+)(.*?)$/) { ${$rs_found} = $2; } elsif (!defined ${$rs_count_diff} and /^(count_and_diff|count-and-diff)/) { ${$rs_count_diff} = 1; + } elsif (!defined ${$rs_diff_list_files} and /^(diff_list_files|diff-list-files)/) { ${$rs_diff_list_files} = 1; } elsif (!defined ${$rs_diff} and /^diff/) { ${$rs_diff} = 1; } elsif (!defined ${$rs_diff_alignment} and /^(?:diff-alignment|diff_alignment)(=|\s+)(.*?)$/) { ${$rs_diff_alignment} = $2; } elsif (!defined ${$rs_diff_timeout} and /^(?:diff-timeout|diff_timeout)(=|\s+)i/) { ${$rs_diff_timeout} = $1; @@ -13485,9 +13729,9 @@ sub load_from_config_file { # {{{1 } elsif (!defined ${$rs_md} and /^md/) { ${$rs_md} = 1; } elsif (!defined ${$rs_fullpath} and /^fullpath/) { ${$rs_fullpath} = 1; } elsif (!defined ${$rs_match_f} and /^(?:match_f|match-f)(=|\s+)(.*?)$/) { ${$rs_match_f} = $2; - } elsif (!defined ${$rs_not_match_f} and /^(?:not_match_f|not-match-f)(=|\s+)(.*?)$/) { ${$rs_not_match_f} = $2; + } elsif (! @{$ra_not_match_f} and /^(?:not_match_f|not-match-f)(=|\s+)(.*?)$/) { push @{$ra_not_match_f} , $2; } elsif (!defined ${$rs_match_d} and /^(?:match_d|match-d)(=|\s+)(.*?)$/) { ${$rs_match_d} = $2; - } elsif (!defined ${$rs_not_match_d} and /^(?:not_match_d|not-match-d)(=|\s+)(.*?)$/) { ${$rs_not_match_d} = $2; + } elsif (! @{$ra_not_match_d} and /^(?:not_match_d|not-match-d)(=|\s+)(.*?)$/) { push @{$ra_not_match_d} , $2; } elsif (!defined ${$rs_list_file} and /^(?:list_file|list-file)(=|\s+)(.*?)$/) { ${$rs_list_file} = $2; } elsif (!defined ${$rs_help} and /^help/) { ${$rs_help} = 1; } elsif (!defined ${$rs_skip_win_hidden} and /^(skip_win_hidden|skip-win-hidden)/) { ${$rs_skip_win_hidden} = 1; @@ -13516,7 +13760,7 @@ sub load_from_config_file { # {{{1 } elsif (!defined ${$rs_force_git} and /^git/) { ${$rs_force_git} = 1; } elsif (!defined ${$rs_exclude_list_file} and /^(?:exclude_list_file|exclude-list-file)(=|\s+)(.*?)$/) { ${$rs_exclude_list_file} = $2; - } elsif (!defined ${$rs_v} and /(verbose|v)((=|\s+)(\d+))?/) { + } elsif (!defined ${$rs_v} and /^(verbose|v)((=|\s+)(\d+))?/) { if (!defined $4) { ${$rs_v} = 0; } else { ${$rs_v} = $4; } } elsif (!$has_script_lang and /^(?:script_lang|script-lang)(=|\s+)(.*?)$/) { @@ -13578,9 +13822,9 @@ sub check_alternate_config_files { # {{{1 $diff_list_file ) { next unless defined $file; my $dir = dirname $file; - next unless -r $dir and -d $dir; + next unless can_read($dir) and is_dir($dir); my $bn = basename $config_file; - if (-r "$dir/$bn") { + if (can_read("$dir/$bn")) { $found_it = "$dir/$bn"; print "Using configuration file $found_it\n" if $opt_v; last; @@ -13589,6 +13833,40 @@ sub check_alternate_config_files { # {{{1 return $found_it; } # 1}}} +sub write_null_results { # {{{ + my ($json, $xml, $report_file,) = @_; + print "-> write_null_results\n" if $opt_v > 2; + if ((defined $json) or (defined $xml)) { + my $line = ""; + if (defined $json) { + $line = "{}"; + } else { + $line = ''; + } + if (defined $report_file) { + open OUT, ">$report_file" or die "Cannot write to $report_file $!\n"; + print OUT "$line\n"; + close OUT; + } else { + print "$line\n"; + } + } + print "<- write_null_results\n" if $opt_v > 2; +} # }}} +sub glob2regex { # {{{ + # convert simple xpath-style glob pattern to a regex + my $globstr = shift; + my $re = $globstr; + $re =~ s{^["']}{}; + $re =~ s{^\.\/}{}; + $re =~ s{["']$}{}; + $re =~ s{\.}{\\.}g; + $re =~ s{\*\*}{\cx}g; # ctrl x = .*? + $re =~ s{\*}{\cy}g; # ctrl y = [^/]* + $re =~ s{\cx}{.*?}g; + $re =~ s{\cy}{[^/]*}g; + return '^' . $re . '$'; +} # }}} # really_is_pascal, really_is_incpascal, really_is_php from SLOCCount my %php_files = (); # really_is_php() sub really_is_pascal { # {{{1 @@ -13653,9 +13931,9 @@ sub really_is_pascal { # {{{1 my $found_terminating_end = 0; my $has_begin = 0; - open(PASCAL_FILE, "<$filename") || - die "Can't open $filename to determine if it's pascal.\n"; - while() { + my $PASCAL_FILE = open_file('<', $filename, 0); + die "Can't open $filename to determine if it's pascal.\n" if !defined $PASCAL_FILE; + while(<$PASCAL_FILE>) { s/\{.*?\}//g; # Ignore {...} comments on this line; imperfect, but effective. s/\(\*.*?\*\)//g; # Ignore (*...*) comments on this line; imperfect, but effective. if (m/\bprogram\s+[A-Za-z]/i) {$has_program=1;} @@ -13676,7 +13954,7 @@ sub really_is_pascal { # {{{1 if (m/end\.\s*$/i) {$found_terminating_end = 1;} # elsif (m/\S/) {$found_terminating_end = 0;} } - close(PASCAL_FILE); + close($PASCAL_FILE); # Okay, we've examined the entire file looking for clues; # let's use those clues to determine if it's really Pascal: @@ -13708,9 +13986,9 @@ sub really_is_incpascal { # {{{1 my $is_pascal = 0; # Value to determine. my $found_begin = 0; - open(PASCAL_FILE, "<$filename") || - die "Can't open $filename to determine if it's pascal.\n"; - while() { + my $PASCAL_FILE = open_file('<', $filename, 0); + die "Can't open $filename to determine if it's pascal.\n" if !defined $PASCAL_FILE; + while(<$PASCAL_FILE>) { s/\{.*?\}//g; # Ignore {...} comments on this line; imperfect, but effective. s/\(\*.*?\*\)//g; # Ignore (*...*) comments on this line; imperfect, but effective. if (m/\bprogram\s+[A-Za-z]/i) {$is_pascal=1;} @@ -13728,7 +14006,7 @@ sub really_is_incpascal { # {{{1 } } - close(PASCAL_FILE); + close($PASCAL_FILE); return $is_pascal; } # 1}}} sub really_is_php { # {{{1 @@ -13746,9 +14024,9 @@ sub really_is_php { # {{{1 # Return cached result, if available: if ($php_files{$filename}) { return $php_files{$filename};} - open(PHP_FILE, "<$filename") || - die "Can't open $filename to determine if it's php.\n"; - while() { + my $PHP_FILE = open_file('<', $filename, 0); + die "Can't open $filename to determine if it's php.\n" if !defined $PHP_FILE; + while(<$PHP_FILE>) { if (m/\<\?/) { $normal_surround |= 1; } if (m/\?\>/ && ($normal_surround & 1)) { $normal_surround |= 2; } if (m/\/ && ($asp_surround & 1)) { $asp_surround |= 2; } } - close(PHP_FILE); + close($PHP_FILE); if ( ($normal_surround == 3) || ($script_surround == 3) || ($asp_surround == 3)) { diff --git a/Unix/cloc.1.pod b/Unix/cloc.1.pod index 17c89371..e84549aa 100644 --- a/Unix/cloc.1.pod +++ b/Unix/cloc.1.pod @@ -1,6 +1,6 @@ # Copyright # -# Copyright (C) 2018-2021 Al Danial . +# Copyright (C) 2018-2022 Al Danial . # Copyright (C) 2010-2017 Jari Aalto # # License @@ -391,7 +391,7 @@ the number of its subdirectories. Consequently cloc may undercount or completely skip the contents of such file systems. This switch forces File::Find to stat directories to obtain the -correct count. File search spead will decrease. +correct count. File search speed will decrease. See also B<--follow-links>. =item B<--stdin-name=FILE> @@ -426,7 +426,7 @@ Input arguments are report files previously created with the B<--report-file> option. Makes a cumulative set of results containing the sum of data from the individual report files. -B<--timeout=N> +=item B<--timeout=N> Ignore files which take more than seconds to process at any of the language's filter stages. @@ -471,6 +471,11 @@ Microsoft Windows mode. See also B<--unix>, B<--show-os>. =over 4 +=item B<--include-content=REGEX> + +Only count files containing text that matches the given +regular expression. + =item B<--exclude-content=REGEX> Exclude files containing text that matches the given @@ -814,7 +819,7 @@ To see how cloc aligns files for comparison between two code bases, use the B<--diff-alignment=FILE> option. Here the alignment information is written to C: - cloc --diff-aligment=align.txt gcc-4.4.0.tar.bz2 gcc-4.5.0.tar.bz2 + cloc --diff-alignment=align.txt gcc-4.4.0.tar.bz2 gcc-4.5.0.tar.bz2 Count file, code, and comment changes between two git commits: @@ -846,7 +851,7 @@ sloccount(1) =head1 AUTHORS The cloc program was written by Al Danial and -is Copyright (C) 2006-2021 . +is Copyright (C) 2006-2022 . The manual page was originally written by Jari Aalto . diff --git a/Unix/t/00_C.t b/Unix/t/00_C.t index 0eb18dfd..80f02d44 100755 --- a/Unix/t/00_C.t +++ b/Unix/t/00_C.t @@ -9,6 +9,16 @@ my @Tests = ( 'ref' => '../tests/outputs/Lookup.agda.yaml', 'args' => '../tests/inputs/Lookup.agda', }, + { + 'name' => 'ANTLR Grammar 1', + 'ref' => '../tests/outputs/ExprParser.g.yaml', + 'args' => '../tests/inputs/ExprParser.g', + }, + { + 'name' => 'ANTLR Grammar 2', + 'ref' => '../tests/outputs/C.g4.yaml', + 'args' => '../tests/inputs/C.g4', + }, { 'name' => 'Apex Class', 'ref' => '../tests/outputs/RemoteSiteHelperTest.cls.yaml', @@ -50,14 +60,9 @@ my @Tests = ( 'args' => '../tests/inputs/zos_assembly.s', }, { - 'name' => 'ANTLR Grammar 1', - 'ref' => '../tests/outputs/ExprParser.g.yaml', - 'args' => '../tests/inputs/ExprParser.g', - }, - { - 'name' => 'ANTLR Grammar 2', - 'ref' => '../tests/outputs/C.g4.yaml', - 'args' => '../tests/inputs/C.g4', + 'name' => 'Asymptote', + 'ref' => '../tests/outputs/cad.asy.yaml', + 'args' => '../tests/inputs/cad.asy', }, { 'name' => 'Bazel', @@ -119,11 +124,21 @@ my @Tests = ( 'ref' => '../tests/outputs/locale_facets.h.yaml', 'args' => '../tests/inputs/locale_facets.h', }, + { + 'name' => 'Cairo', + 'ref' => '../tests/outputs/ERC20.cairo.yaml', + 'args' => '../tests/inputs/ERC20.cairo', + }, { 'name' => 'Cake Build Script', 'ref' => '../tests/outputs/build.cake.yaml', 'args' => '../tests/inputs/build.cake', }, + { + 'name' => 'Circom', + 'ref' => '../tests/outputs/eddsa.circom.yaml', + 'args' => '../tests/inputs/eddsa.circom', + }, { 'name' => 'Chapel', 'ref' => '../tests/outputs/Chapel.chpl.yaml', @@ -154,6 +169,16 @@ my @Tests = ( 'ref' => '../tests/outputs/ColdFusion.cfm.yaml', 'args' => '../tests/inputs/ColdFusion.cfm', }, + { + 'name' => 'Containerfile', + 'ref' => '../tests/outputs/Containerfile.yaml', + 'args' => '../tests/inputs/Containerfile', + }, + { + 'name' => 'Context Grammar', + 'ref' => '../tests/outputs/apertium-dan.dan.rlx.yaml', + 'args' => '../tests/inputs/apertium-dan.dan.rlx', + }, { 'name' => 'C++', 'ref' => '../tests/outputs/C++-MFC.cc.yaml', @@ -255,7 +280,7 @@ my @Tests = ( 'args' => '../tests/inputs/capture.ecr', }, { - 'name' => 'Fennel', + 'name' => 'Fennel', 'ref' => '../tests/outputs/generate.fnl.yaml', 'args' => '../tests/inputs/generate.fnl', }, @@ -386,6 +411,11 @@ my @Tests = ( 'ref' => '../tests/outputs/just_stuff.haml.yaml', 'args' => '../tests/inputs/just_stuff.haml', }, + { + 'name' => 'Hare', + 'ref' => '../tests/outputs/fmt.ha.yaml', + 'args' => '../tests/inputs/fmt.ha', + }, { 'name' => 'Haskell', 'ref' => '../tests/outputs/test2.lhs.yaml', @@ -456,21 +486,6 @@ my @Tests = ( 'ref' => '../tests/outputs/igorpro.ipf.yaml', 'args' => '../tests/inputs/igorpro.ipf', }, - { - 'name' => 'Jinja Templates', - 'ref' => '../tests/outputs/child_template.jinja2.yaml', - 'args' => '../tests/inputs/child_template.jinja2', - }, - { - 'name' => 'Jupyter Notebook', - 'ref' => '../tests/outputs/Trapezoid_Rule.ipynb.yaml', - 'args' => '../tests/inputs/Trapezoid_Rule.ipynb', - }, - { - 'name' => 'Juniper Junos', - 'ref' => '../tests/outputs/config.junos.yaml', - 'args' => '../tests/inputs/config.junos', - }, { 'name' => 'Imba', 'ref' => '../tests/outputs/class.imba.yaml', @@ -486,6 +501,11 @@ my @Tests = ( 'ref' => '../tests/outputs/insertJournalEntry.ipl.yaml', 'args' => '../tests/inputs/insertJournalEntry.ipl', }, + { + 'name' => 'Jai', + 'ref' => '../tests/outputs/poly_constructor.jai.yaml', + 'args' => '../tests/inputs/poly_constructor.jai', + }, { 'name' => 'Java', 'ref' => '../tests/outputs/Java.java.yaml', @@ -501,11 +521,26 @@ my @Tests = ( 'ref' => '../tests/outputs/glossary.json.yaml', 'args' => '../tests/inputs/glossary.json', }, + { + 'name' => 'Jinja Templates', + 'ref' => '../tests/outputs/child_template.jinja2.yaml', + 'args' => '../tests/inputs/child_template.jinja2', + }, { 'name' => 'JSON5', 'ref' => '../tests/outputs/glossary.json5.yaml', 'args' => '../tests/inputs/glossary.json5', }, + { + 'name' => 'Jupyter Notebook', + 'ref' => '../tests/outputs/Trapezoid_Rule.ipynb.yaml', + 'args' => '../tests/inputs/Trapezoid_Rule.ipynb', + }, + { + 'name' => 'Juniper Junos', + 'ref' => '../tests/outputs/config.junos.yaml', + 'args' => '../tests/inputs/config.junos', + }, { 'name' => 'Julia', 'ref' => '../tests/outputs/julia.jl.yaml', @@ -541,6 +576,11 @@ my @Tests = ( 'ref' => '../tests/outputs/sharpsign.cl.yaml', 'args' => '../tests/inputs/sharpsign.cl', }, + { + 'name' => 'Linker Script', + 'ref' => '../tests/outputs/linker.ld.yaml', + 'args' => '../tests/inputs/linker.ld', + }, { 'name' => 'Literate Idris', 'ref' => '../tests/outputs/Hello.lidr.yaml', @@ -651,6 +691,11 @@ my @Tests = ( 'ref' => '../tests/outputs/drupal.mxml.yaml', 'args' => '../tests/inputs/drupal.mxml', }, + { + 'name' => 'NetLogo', + 'ref' => '../tests/outputs/vinos.nlogo.yaml', + 'args' => '../tests/inputs/vinos.nlogo', + }, { 'name' => 'Nim', 'ref' => '../tests/outputs/statcsv.nim.yaml', @@ -676,11 +721,21 @@ my @Tests = ( 'ref' => '../tests/outputs/demo.odin.yaml', 'args' => '../tests/inputs/demo.odin', }, + { + 'name' => 'OpenSCAD', + 'ref' => '../tests/outputs/Rounds.scad.yaml', + 'args' => '../tests/inputs/Rounds.scad', + }, { 'name' => 'Oracle PL/SQL', 'ref' => '../tests/outputs/bubs_tak_ard.prc.yaml', 'args' => '../tests/inputs/bubs_tak_ard.prc', }, + { + 'name' => 'P4', + 'ref' => '../tests/outputs/basic.p4.yaml', + 'args' => '../tests/inputs/basic.p4', + }, { 'name' => 'Pascal', 'ref' => '../tests/outputs/Pascal.pas.yaml', @@ -716,6 +771,11 @@ my @Tests = ( 'ref' => '../tests/outputs/sdp_parser.peggy.yaml', 'args' => '../tests/inputs/sdp_parser.peggy', }, + { + 'name' => 'Pest', + 'ref' => '../tests/outputs/toml.pest.yaml', + 'args' => '../tests/inputs/toml.pest', + }, { 'name' => 'tspeg 1', 'ref' => '../tests/outputs/sdp_parser.tspeg.yaml', @@ -761,6 +821,16 @@ my @Tests = ( 'ref' => '../tests/outputs/en_AU.po.yaml', 'args' => '../tests/inputs/en_AU.po', }, + { + 'name' => 'Pony (--docstring-as-code)', + 'ref' => '../tests/outputs/ring.pony.1.yaml', + 'args' => '--docstring-as-code ../tests/inputs/ring.pony', + }, + { + 'name' => 'Pony', + 'ref' => '../tests/outputs/ring.pony.2.yaml', + 'args' => '../tests/inputs/ring.pony', + }, { 'name' => 'ProGuard', 'ref' => '../tests/outputs/proguard-project-app.pro.yaml', diff --git a/Unix/t/01_opts.t b/Unix/t/01_opts.t index ccf14e55..9687b208 100755 --- a/Unix/t/01_opts.t +++ b/Unix/t/01_opts.t @@ -7,673 +7,729 @@ use Cwd; #use YAML qw(LoadFile); my @Tests = ( - { - 'name' => '--exclude-dir 1 (baseline for github issue #82)', - 'args' => '--exclude-dir cc ../tests/inputs/dd', - 'ref' => '../tests/outputs/exclude_dir_1.yaml', - }, - { - 'name' => '--exclude-dir 2 (github issue #82)', - 'cd' => '../tests/inputs/dd', - 'args' => '--exclude-dir cc *', - 'ref' => '../tests/outputs/exclude_dir_1.yaml', - }, - { - 'name' => '--not-match-d', - 'cd' => '../tests/inputs/dd', - 'args' => '--not-match-d cc *', - 'ref' => '../tests/outputs/exclude_dir_1.yaml', - }, - { - 'name' => '--not-match-d (github issue #114 T1)', - 'cd' => '../tests/inputs', - 'args' => '--by-file issues/114', - 'ref' => '../tests/outputs/issues/114/T1.yaml', - }, - { - 'name' => '--not-match-d (github issue #114 T2)', - 'cd' => '../tests/inputs', - 'args' => '--by-file --not-match-d bar issues/114', - 'ref' => '../tests/outputs/issues/114/T2.yaml', - }, - { - 'name' => '--not-match-d (github issue #114 T3)', - 'cd' => '../tests/inputs', - 'args' => '--by-file --not-match-d bee issues/114', - 'ref' => '../tests/outputs/issues/114/T3.yaml', - }, - { - 'name' => '--not-match-d (github issue #114 T4)', - 'cd' => '../tests/inputs', - 'args' => '--by-file --not-match-d bar/bee issues/114', - 'ref' => '../tests/outputs/issues/114/T4.yaml', - }, - { - 'name' => '--not-match-d (github issue #114 T5)', - 'cd' => '../tests/inputs', - 'args' => '--by-file --fullpath --not-match-d bar issues/114', - 'ref' => '../tests/outputs/issues/114/T5.yaml', - }, - { - 'name' => '--not-match-d (github issue #114 T6)', - 'cd' => '../tests/inputs', - 'args' => '--by-file --fullpath --not-match-d ./bar issues/114', - 'ref' => '../tests/outputs/issues/114/T6.yaml', - }, - { - 'name' => '--not-match-d (github issue #114 T7)', - 'cd' => '../tests/inputs', - 'args' => '--by-file --fullpath --not-match-d bar/bee issues/114', - 'ref' => '../tests/outputs/issues/114/T7.yaml', - }, - # { - # 'name' => 'git submodule handling (github issue #131 T1)', - # 'cd' => '../tests/inputs', - # 'args' => 'issues/131', - # 'ref' => '../tests/outputs/issues/131/T1.yaml', - # }, - # { - # 'name' => 'git submodule handling (github issue #131 T2)', - # 'cd' => '../tests/inputs', - # 'args' => '--vcs git issues/131', - # 'ref' => '../tests/outputs/issues/131/T2.yaml', - # }, - { - 'name' => 'all files (github issue #132 T1)', - 'cd' => '../tests/inputs', - 'args' => 'issues/132', - 'ref' => '../tests/outputs/issues/132/T1.yaml', - }, - { - 'name' => '--vcs git issues/132 (github issue #132 T2)', - 'cd' => '../tests/inputs', - 'args' => '--vcs git issues/132', - 'ref' => '../tests/outputs/issues/132/T2.yaml', - }, - { - 'name' => '--vcs-git --exclude-dir ignore_dir (github issue #132 T3)', - 'cd' => '../tests/inputs/issues/132', - 'args' => '--vcs git --exclude-dir ignore_dir .', - 'ref' => '../tests/outputs/issues/132/T3.yaml', - }, - { - 'name' => '--vcs git --fullpath --not-match-d issues/132/ignore_dir (github issue #132 T4)', - 'cd' => '../tests/inputs', - 'args' => '--vcs git --fullpath --not-match-d issues/132/ignore_dir issues/132', - 'ref' => '../tests/outputs/issues/132/T4.yaml', - }, - { - 'name' => '--vcs git --match-f C-Ansi (github issue #132 T5)', - 'cd' => '../tests/inputs', - 'args' => '--vcs git --match-f C-Ansi issues/132', - 'ref' => '../tests/outputs/issues/132/T5.yaml', - }, - { - 'name' => '--vcs git --match-f "\.c$" (github issue #132 T6)', - 'cd' => '../tests/inputs', - 'args' => '--vcs git --match-f "\.c$" issues/132', - 'ref' => '../tests/outputs/issues/132/T6.yaml', - }, - { - 'name' => '--vcs "find X" (github issue #147)', - 'cd' => '../tests/inputs', - 'args' => '--vcs "find foo_bar"', - 'ref' => '../tests/outputs/issues/147/T1.yaml', - }, - { - 'name' => '--read-lang-def w/remove_between_general (github issue #166)', - 'cd' => '../tests/inputs/issues/166', - 'args' => '--read-lang-def X fake.thy', - 'ref' => '../tests/outputs/issues/166/fake.thy.yaml', - }, - { - 'name' => '--read-lang-def w/triple_extension', - 'cd' => '../tests/inputs', - 'args' => '--read-lang-def triple_lang_def.txt custom.triple.extension.js', - 'ref' => '../tests/outputs/custom.triple.extension.js.yaml', - }, - { - 'name' => 'Forth balanced parentheses #1 (github issue #183)', - 'cd' => '../tests/inputs/issues/183', - 'args' => 'file.fth', - 'ref' => '../tests/outputs/issues/183/file.fth.yaml', - }, - { - 'name' => 'Forth balanced parentheses #2 (github issue #183)', - 'cd' => '../tests/inputs/issues/183', - 'args' => 'eval1957.SACunidir.fr', - 'ref' => '../tests/outputs/issues/183/eval1957.SACunidir.fr.yaml', - }, - { - 'name' => 'diff identical files (github issue #280)', - 'cd' => '../tests/inputs/issues/280', - 'args' => '--diff L R', - 'ref' => '../tests/outputs/issues/280/280.yaml', - }, - { - 'name' => 'diff identical files by file (github issue #280)', - 'cd' => '../tests/inputs/issues/280', - 'args' => '--by-file --diff L R', - 'ref' => '../tests/outputs/issues/280/280_by_file.yaml', - }, - - { - 'name' => '--follow-links, --not-match-d, --fullpath 1/6 (github issue #286)', - 'cd' => '../tests/inputs/issues/286', - 'args' => ' --not-match-d ignore_subdir project', - 'ref' => '../tests/outputs/issues/286/1.yaml', - }, - - { - 'name' => '--follow-links, --not-match-d, --fullpath 2/6 (github issue #286)', - 'cd' => '../tests/inputs/issues/286', - 'args' => '--follow-links --not-match-d ignore_subdir project', - - 'ref' => '../tests/outputs/issues/286/2.yaml', - }, - - { - 'name' => '--follow-links, --not-match-d, --fullpath 3/6 (github issue #286)', - 'cd' => '../tests/inputs/issues/286', - 'args' => ' --not-match-d ignore_subdir --fullpath project', - - 'ref' => '../tests/outputs/issues/286/3.yaml', - }, - - { - 'name' => '--follow-links, --not-match-d, --fullpath 4/6 (github issue #286)', - 'cd' => '../tests/inputs/issues/286', - 'args' => '--follow-links --not-match-d ignore_subdir --fullpath project', - 'ref' => '../tests/outputs/issues/286/4.yaml', - }, - - { - 'name' => '--follow-links, --not-match-d, --fullpath 5/6 (github issue #286)', - 'cd' => '../tests/inputs/issues/286', - 'args' => ' --not-match-d project/ignore_subdir --fullpath project', - 'ref' => '../tests/outputs/issues/286/5.yaml', - }, - - { - 'name' => '--follow-links, --not-match-d, --fullpath 6/6 (github issue #286)', - 'cd' => '../tests/inputs/issues/286', - 'args' => '--follow-links --not-match-d project/ignore_subdir --fullpath project', - 'ref' => '../tests/outputs/issues/286/6.yaml', - }, - - { - 'name' => '--include-ext m,lua (github issue #296)', - 'cd' => '../tests/inputs/issues/296', - 'args' => '--include-ext m,lua .', - 'ref' => '../tests/outputs/issues/296/results.yaml', - }, - - { - 'name' => '--strip-str-comments (github issue #245)', - 'cd' => '../tests/inputs/issues/245', - 'args' => '--strip-str-comments .', - 'ref' => '../tests/outputs/issues/245/CRS.scala.yaml', - }, - - { - 'name' => 'YAML --by-file output with unusual filename (github issue #312)', - 'cd' => '../tests/inputs/issues/312', - 'args' => '--by-file .', - 'ref' => '../tests/outputs/issues/312/results.yaml', - }, - - { - 'name' => 'custom Smarty definition (github issue #327)', - 'cd' => '../tests/inputs/issues/327', - 'args' => '--force-lang-def=lang.config example.smarty2', - 'ref' => '../tests/outputs/issues/327/results.yaml', - }, - - { - 'name' => 'UTF-8 output file encoding', - 'cd' => '../tests/inputs/issues/318', - 'args' => '--by-file --file-encoding utf8 R*.cs', - 'ref' => '../tests/inputs/issues/318/Rcs.yaml', # results in input dir - }, - - { - 'name' => 'distinguish TeX from VB (github issue #341)', - 'cd' => '../tests/inputs/issues/341', - 'args' => '.', - 'ref' => '../tests/outputs/issues/341/results.yaml', - }, - - { - 'name' => '--strip-str-comments (github issue #350)', - 'cd' => '../tests/inputs/issues/350', - 'args' => '--strip-str-comments .', - 'ref' => '../tests/outputs/issues/350/fs.go.yaml', - }, - - { - 'name' => 'Java comments in strings, issue #365', - 'cd' => '../tests/inputs/issues/365', - 'args' => 'RSpecTests.java', - 'ref' => '../tests/outputs/issues/365/results.yaml', - }, - - { - 'name' => 'Arduino IDE 0xA0 characters', - 'cd' => '../tests/inputs/issues/370', - 'args' => 'arduino_issue_370.ino', - 'ref' => '../tests/outputs/issues/370/results.yaml', - }, - - { - 'name' => 'Python docstrings --docstring-as-code', - 'cd' => '../tests/inputs/issues/375', - 'args' => '--docstring-as-code docstring.py', - 'ref' => '../tests/outputs/issues/375/results.yaml', - }, - - { - 'name' => 'Perl v. Prolog', - 'cd' => '../tests/inputs/issues/380', - 'args' => 'wrapper.pl', - 'ref' => '../tests/outputs/issues/380/wrapper.pl.yaml', - }, - - { - 'name' => 'Java comments and continuation lines issue 381', - 'cd' => '../tests/inputs/issues/381', - 'args' => 'issue381.java', - 'ref' => '../tests/outputs/issues/381/issue381.java.yaml', - }, - - { - 'name' => 'C comments w/ backslashed quote in strings issue 381', - 'cd' => '../tests/inputs/issues/381', - 'args' => '--strip-str-comments issue381.c', - 'ref' => '../tests/outputs/issues/381/issue381.c.yaml', - }, - - { - 'name' => '--exclude-content issue 396', - 'cd' => '../tests/inputs', - 'args' => '--exclude-content Lambda acpclust.R sample.R utilities.R', - 'ref' => '../tests/outputs/issues/396/excl.yaml', - }, - - { - 'name' => '--exclude-content w/--diff issue 396', - 'cd' => '../tests/inputs/issues/280', - 'args' => '--exclude-content Copyright --diff L R', - 'ref' => '../tests/outputs/issues/396/excl_diff.yaml', - }, - - { - 'name' => 'Python with /* in strings issue 405', - 'cd' => '../tests/inputs/issues/405', - 'args' => 'globs.py', - 'ref' => '../tests/outputs/issues/405/globs.py.yaml', - }, - - { - 'name' => '--exclude-dir and --follow-link, #407 1/3', - 'cd' => '../tests/inputs/issues/407', - 'args' => '--follow-link --exclude-dir Test count_dir', - 'ref' => '../tests/outputs/issues/407/results1.yaml', - }, - - { - 'name' => '--exclude-dir and --follow-link, #407 2/3', - 'cd' => '../tests/inputs/issues/407', - 'args' => '--exclude-dir Test level2', - 'ref' => '../tests/outputs/issues/407/results2.yaml', - }, - - { - 'name' => '--exclude-dir and --follow-link, #407 3/3', - 'cd' => '../tests/inputs/issues/407', - 'args' => '--follow-link --exclude-dir Test level2', - 'ref' => '../tests/outputs/issues/407/results3.yaml', - }, - - { - 'name' => 'doubly counted she-bang line, #408', - 'cd' => '../tests/inputs/issues/408', - 'args' => 'badly_named_ruby.pl', - 'ref' => '../tests/outputs/issues/408/badly_named_ruby.yaml', - }, - - { - 'name' => 'case insensitive file ext, #420', - 'cd' => '../tests/inputs/issues/420', - 'args' => '--ignore-case-ext .', - 'ref' => '../tests/outputs/issues/420/results.yaml', - }, - - { - 'name' => 'diff with --exclude-list-file, #433', - 'cd' => '../tests/inputs/issues/433', - 'args' => '--exclude-list-file excl.txt --by-file --follow-links --diff L R - ', - 'ref' => '../tests/outputs/issues/433/results.yaml', - }, - { - 'name' => 'JavaScript comment in string, #454', - 'cd' => '../tests/inputs/issues/454', - 'args' => '--strip-str-comments createServer.js', - 'ref' => '../tests/outputs/issues/454/createServer.js.yaml', - }, - { - 'name' => 'XML with no extension, #456', - 'cd' => '../tests/inputs/issues/456', - 'args' => 'XML_no_ext', - 'ref' => '../tests/outputs/issues/456/XML_no_ext.yaml', - }, - { - 'name' => 'XML with unusual extension, #456', - 'cd' => '../tests/inputs/issues/456', - 'args' => 'XML_weird_ext.profile', - 'ref' => '../tests/outputs/issues/456/XML_weird_ext.profile.yaml', - }, - { - 'name' => 'ignore Algorithm::Diff::sdiff() failures, #463', - 'cd' => '../tests/inputs/issues/463', - 'args' => '--diff left.C right.C', - 'ref' => '../tests/outputs/issues/463/diff.yaml', - }, - { - 'name' => 'diff list input format 1, #455', - 'cd' => '../', - 'args' => '--diff-list-file tests/inputs/issues/455/list.txt', - 'ref' => '../tests/outputs/issues/455/list.yaml', - }, - { - 'name' => 'diff list input format 2, #455', - 'cd' => '../', - 'args' => '--diff-list-file tests/inputs/issues/455/list_align.txt', - 'ref' => '../tests/outputs/issues/455/list_align.yaml', - }, - { - 'name' => 'replace_regex with null, #472', - 'cd' => '../tests/inputs/issues/472', - 'args' => '--force-lang-def lua_def.txt not_really.lua', - 'ref' => '../tests/outputs/issues/472/not_really.lua.yaml', - }, - { - 'name' => '--exclude-lang --diff 1/3, #476', - 'cd' => '../tests/inputs/issues/476', - 'args' => '--diff A B', - 'ref' => '../tests/outputs/issues/476/all.yaml', - }, - { - 'name' => '--exclude-lang --diff 2/3, #476', - 'cd' => '../tests/inputs/issues/476', - 'args' => "--exclude-lang 'Fortran 90' --diff A B", - 'ref' => '../tests/outputs/issues/476/no_fortran.yaml', - }, - { - 'name' => '--exclude-lang --diff 3/3, #476', - 'cd' => '../tests/inputs/issues/476', - 'args' => "--exclude-lang C++ --diff A B", - 'ref' => '../tests/outputs/issues/476/no_cpp.yaml', - }, - # Next test, 482, requires an empty directory B. Git - # does not like this so create it at runtime. - { - 'name' => '--include-lang --diff, #482', - 'cd' => '../tests/inputs/issues/482', - 'args' => '--include-lang C --diff A B', - 'ref' => '../tests/outputs/issues/482/results.yaml', - }, - - { - 'name' => '--unicode #494', - 'cd' => '../tests/inputs/issues/494', - 'args' => '--unicode --by-file P*.sql', - 'ref' => '../tests/outputs/issues/494/results.yaml', - }, - - { - 'name' => '--diff-list-file #513', - 'cd' => '../tests/inputs/issues/513', - 'args' => '--diff-list-file diff_list.txt', - 'ref' => '../tests/outputs/issues/513/results.yaml', - }, - - { - 'name' => '--list-file BOM #502', - 'cd' => '../tests/inputs/issues/502', - 'args' => '--list-file FileCounter20200715140433.txt', - 'ref' => '../tests/outputs/issues/502/results.yaml', - }, - - { - 'name' => 'Julia with docstring as comment #520 1/2', - 'cd' => '../tests/inputs/issues/520', - 'args' => 'julia_docstr.jl', - 'ref' => '../tests/outputs/issues/520/doc_as_comment.yaml', - }, - - { - 'name' => 'Julia with docstring as comment #520 2/2', - 'cd' => '../tests/inputs/issues/520', - 'args' => '--docstring-as-code julia_docstr.jl', - 'ref' => '../tests/outputs/issues/520/doc_as_code.yaml', - }, - - { - 'name' => 'diff alignment on Windows #521 1/2', - 'cd' => '../tests/inputs/issues/521', - 'args' => '--diff "Test 188" ../521/Test188New', - 'ref' => '../tests/outputs/issues/521/uniq.yaml', - }, - - { - 'name' => 'diff alignment on Windows #521 2/2', - 'cd' => '../tests/inputs/issues/521', - 'args' => '--skip-uniqueness --diff "Test 188" ../521/Test188New', - 'ref' => '../tests/outputs/issues/521/skip_uniq.yaml', - }, - - { - 'name' => '--summary-cutoff (f:1) #528 1/3', - 'cd' => '../tests/inputs/issues/528', - 'args' => '--summary-cutoff f:1 .', - 'ref' => '../tests/outputs/issues/528/cutoff_files_1.yaml', - }, - - { - 'name' => '--summary-cutoff (c:10) #528 2/3', - 'cd' => '../tests/inputs/issues/528', - 'args' => '--summary-cutoff c:10 .', - 'ref' => '../tests/outputs/issues/528/cutoff_code_10.yaml', - }, - - { - 'name' => '--summary-cutoff (c:50%) #528 3/3', - 'cd' => '../tests/inputs/issues/528', - 'args' => '--summary-cutoff c:50% .', - 'ref' => '../tests/outputs/issues/528/cutoff_code_50pct.yaml', - }, - - { - 'name' => '--skip-leading 2 #530 1/4', - 'cd' => '../tests/inputs/issues/530', - 'args' => '--skip-leading 2 .', - 'ref' => '../tests/outputs/issues/530/case_1.yaml', - }, - - { - 'name' => '--skip-leading 100 #530 2/4', - 'cd' => '../tests/inputs/issues/530', - 'args' => '--skip-leading 100 .', - 'ref' => '../tests/outputs/issues/530/case_2.yaml', - }, - - { - 'name' => '--skip-leading 2,c,h #530 3/4', - 'cd' => '../tests/inputs/issues/530', - 'args' => '--skip-leading 2,c,h .', - 'ref' => '../tests/outputs/issues/530/case_3.yaml', - }, - - { - 'name' => '--skip-leading 2,C,H #530 4/4', - 'cd' => '../tests/inputs/issues/530', - 'args' => '--skip-leading 2,C,H .', - 'ref' => '../tests/outputs/issues/530/case_4.yaml', - }, - - { - 'name' => '--force-lang-def #537 1/2', - 'cd' => '../tests/inputs/issues/537', - 'args' => '--force-lang-def my_define.txt sourceCounter.vsql', - 'ref' => '../tests/outputs/issues/537/results_force.yaml', - }, - - { - 'name' => '--read-lang-def #537 2/2', - 'cd' => '../tests/inputs/issues/537', - 'args' => '--read-lang-def my_define.txt sourceCounter.vsql', - 'ref' => '../tests/outputs/issues/537/results_read.yaml', - }, - - { - 'name' => 'Elm empty comment, #538', - 'cd' => '../tests/inputs/issues/538', - 'args' => 'add.elm', - 'ref' => '../tests/outputs/issues/538/add.elm.yaml', - }, - - { - 'name' => 'Elm nested block comments, #539', - 'cd' => '../tests/inputs/issues/539', - 'args' => 'nested_comments.elm', - 'ref' => '../tests/outputs/issues/539/nested_comments.elm.yaml', - }, - - { - 'name' => 'preserve upper/lowercase filenames on Windows, #540', - 'cd' => '../tests/inputs/issues/540', - 'args' => '--windows --by-file Hello.f', - 'ref' => '../tests/outputs/issues/540/Hello.f.yaml', - }, - - { - 'name' => 'accept all file extensions in user-provided language definitions, #542', - 'cd' => '../tests/inputs/issues/542', - 'args' => '--read-lang-def txt_lang_def.txtt txt_lang_def.txtt', - 'ref' => '../tests/outputs/issues/542/results.yaml', - }, - - { - 'name' => 'small unicode files, #580', - 'cd' => '../tests/inputs/issues/580', - 'args' => '--unicode encodingtest.cs', - 'ref' => '../tests/outputs/issues/580/encodingtest.cs.yaml', - }, - - { - 'name' => 'identify autogenerated C#, #579', - 'cd' => '../tests/inputs/issues/579', - 'args' => 'csharp-autogen.cs', - 'ref' => '../tests/outputs/issues/579/csharp-autogen.cs.yaml', - }, - - { - 'name' => 'config file from list file directory, #577', - 'cd' => '../tests/inputs/issues/577', - 'args' => '--diff-list-file diff_list_file.txt', - 'ref' => '../tests/outputs/issues/577/diff_list.yaml', - }, - - { - 'name' => '--force-lang-def without XML definition, #596', - 'cd' => '../tests/inputs/issues/596', - 'args' => '--force-lang-def def.txt .', - 'ref' => '../tests/outputs/issues/596/results.yaml', - }, - - { - 'name' => '--csv-delimiter="#", #597', - 'cd' => '../tests/inputs/issues/597', - 'args' => '--csv-delimiter="#" .', - 'ref' => '../tests/outputs/issues/597/results.yaml', - }, - - { - 'name' => '--unicode (uninitialized value), #606', - 'cd' => '../tests/inputs/issues/606', - 'args' => '--unicode in', - 'ref' => '../tests/outputs/issues/606/results.yaml', - }, - - { - 'name' => 'CMakeLists.txt on Windows (lowercase file), #611', - 'cd' => '../tests/inputs/issues/611', - 'args' => '.', - 'ref' => '../tests/outputs/issues/611/cmakelists.txt.yaml', - }, - - { - 'name' => 'SCSS separate from Sass, #613', - 'cd' => '../tests/inputs/issues/613', - 'args' => '.', - 'ref' => '../tests/outputs/issues/613/nav.scss.yaml', - }, - - { - 'name' => 'sequence of Assembly filters, #619', - 'cd' => '../tests/inputs/issues/619', - 'args' => '.', - 'ref' => '../tests/outputs/issues/619/RA.s.yaml', - }, - - { - 'name' => 'GraphQL descriptions, #628', - 'cd' => '../tests/inputs/issues/628', - 'args' => '.', - 'ref' => '../tests/outputs/issues/628/results.yaml', - }, - - { - 'name' => 'diff with dir of excluded extensions, #625', - 'cd' => '../tests/inputs/issues/625', - 'args' => '--diff old new', - 'ref' => '../tests/outputs/issues/625/results.yaml', - }, - - { - 'name' => 'case insensitive --include-lang, #637', - 'cd' => '../tests/inputs/issues/637', - 'args' => '--include-lang python,perl --follow-links A B', - 'ref' => '../tests/outputs/issues/637/straight_incl_lang.yaml', - }, - - { - 'name' => 'case insensitive --include-lang --diff, #637', - 'cd' => '../tests/inputs/issues/637', - 'args' => '--include-lang python,perl --follow-links --diff A B', - 'ref' => '../tests/outputs/issues/637/diff_incl_lang.yaml', - }, - - { - 'name' => 'empty Unicode file w/only BOM, #644', - 'cd' => '../tests/inputs/issues/644', - 'args' => 'UInt8.cs', - 'ref' => '../tests/outputs/issues/644/results.yaml', - }, - - { - 'name' => '--no-recurse, #657', - 'cd' => '../tests/inputs/issues/657', - 'args' => '--no-recurse .', - 'ref' => '../tests/outputs/issues/657/results.yaml', - }, - - { - 'name' => '--csv-delimiter="|", #670', - 'cd' => '../tests/inputs/issues/670', - 'args' => '--csv-delimiter="|" .', - 'ref' => '../tests/outputs/issues/670/results.yaml', + { + 'name' => '--exclude-dir 1 (baseline for github issue #82)', + 'args' => '--exclude-dir cc ../tests/inputs/dd', + 'ref' => '../tests/outputs/exclude_dir_1.yaml', + }, + { + 'name' => '--exclude-dir 2 (github issue #82)', + 'cd' => '../tests/inputs/dd', + 'args' => '--exclude-dir cc *', + 'ref' => '../tests/outputs/exclude_dir_1.yaml', + }, + { + 'name' => '--not-match-d', + 'cd' => '../tests/inputs/dd', + 'args' => '--not-match-d cc *', + 'ref' => '../tests/outputs/exclude_dir_1.yaml', + }, + { + 'name' => '--not-match-d (github issue #114 T1)', + 'cd' => '../tests/inputs', + 'args' => '--by-file issues/114', + 'ref' => '../tests/outputs/issues/114/T1.yaml', + }, + { + 'name' => '--not-match-d (github issue #114 T2)', + 'cd' => '../tests/inputs', + 'args' => '--by-file --not-match-d bar issues/114', + 'ref' => '../tests/outputs/issues/114/T2.yaml', + }, + { + 'name' => '--not-match-d (github issue #114 T3)', + 'cd' => '../tests/inputs', + 'args' => '--by-file --not-match-d bee issues/114', + 'ref' => '../tests/outputs/issues/114/T3.yaml', + }, + { + 'name' => '--not-match-d (github issue #114 T4)', + 'cd' => '../tests/inputs', + 'args' => '--by-file --not-match-d bar/bee issues/114', + 'ref' => '../tests/outputs/issues/114/T4.yaml', + }, + { + 'name' => '--not-match-d (github issue #114 T5)', + 'cd' => '../tests/inputs', + 'args' => '--by-file --fullpath --not-match-d bar issues/114', + 'ref' => '../tests/outputs/issues/114/T5.yaml', + }, + { + 'name' => '--not-match-d (github issue #114 T6)', + 'cd' => '../tests/inputs', + 'args' => '--by-file --fullpath --not-match-d ./bar issues/114', + 'ref' => '../tests/outputs/issues/114/T6.yaml', + }, + { + 'name' => '--not-match-d (github issue #114 T7)', + 'cd' => '../tests/inputs', + 'args' => '--by-file --fullpath --not-match-d bar/bee issues/114', + 'ref' => '../tests/outputs/issues/114/T7.yaml', + }, + # { + # 'name' => 'git submodule handling (github issue #131 T1)', + # 'cd' => '../tests/inputs', + # 'args' => 'issues/131', + # 'ref' => '../tests/outputs/issues/131/T1.yaml', + # }, + # { + # 'name' => 'git submodule handling (github issue #131 T2)', + # 'cd' => '../tests/inputs', + # 'args' => '--vcs git issues/131', + # 'ref' => '../tests/outputs/issues/131/T2.yaml', + # }, + { + 'name' => 'all files (github issue #132 T1)', + 'cd' => '../tests/inputs', + 'args' => 'issues/132', + 'ref' => '../tests/outputs/issues/132/T1.yaml', + }, + { + 'name' => '--vcs git issues/132 (github issue #132 T2)', + 'cd' => '../tests/inputs', + 'args' => '--vcs git issues/132', + 'ref' => '../tests/outputs/issues/132/T2.yaml', + }, + { + 'name' => '--vcs-git --exclude-dir ignore_dir (github issue #132 T3)', + 'cd' => '../tests/inputs/issues/132', + 'args' => '--vcs git --exclude-dir ignore_dir .', + 'ref' => '../tests/outputs/issues/132/T3.yaml', + }, + { + 'name' => '--vcs git --fullpath --not-match-d issues/132/ignore_dir (github issue #132 T4)', + 'cd' => '../tests/inputs', + 'args' => '--vcs git --fullpath --not-match-d issues/132/ignore_dir issues/132', + 'ref' => '../tests/outputs/issues/132/T4.yaml', + }, + { + 'name' => '--vcs git --match-f C-Ansi (github issue #132 T5)', + 'cd' => '../tests/inputs', + 'args' => '--vcs git --match-f C-Ansi issues/132', + 'ref' => '../tests/outputs/issues/132/T5.yaml', + }, + { + 'name' => '--vcs git --match-f "\.c$" (github issue #132 T6)', + 'cd' => '../tests/inputs', + 'args' => '--vcs git --match-f "\.c$" issues/132', + 'ref' => '../tests/outputs/issues/132/T6.yaml', + }, + { + 'name' => '--vcs "find X" (github issue #147)', + 'cd' => '../tests/inputs', + 'args' => '--vcs "find foo_bar"', + 'ref' => '../tests/outputs/issues/147/T1.yaml', + }, + { + 'name' => '--read-lang-def w/remove_between_general (github issue #166)', + 'cd' => '../tests/inputs/issues/166', + 'args' => '--read-lang-def X fake.thy', + 'ref' => '../tests/outputs/issues/166/fake.thy.yaml', + }, + { + 'name' => '--read-lang-def w/triple_extension', + 'cd' => '../tests/inputs', + 'args' => '--read-lang-def triple_lang_def.txt custom.triple.extension.js', + 'ref' => '../tests/outputs/custom.triple.extension.js.yaml', + }, + { + 'name' => 'Forth balanced parentheses #1 (github issue #183)', + 'cd' => '../tests/inputs/issues/183', + 'args' => 'file.fth', + 'ref' => '../tests/outputs/issues/183/file.fth.yaml', + }, + { + 'name' => 'Forth balanced parentheses #2 (github issue #183)', + 'cd' => '../tests/inputs/issues/183', + 'args' => 'eval1957.SACunidir.fr', + 'ref' => '../tests/outputs/issues/183/eval1957.SACunidir.fr.yaml', + }, + { + 'name' => 'diff identical files (github issue #280)', + 'cd' => '../tests/inputs/issues/280', + 'args' => '--diff L R', + 'ref' => '../tests/outputs/issues/280/280.yaml', + }, + { + 'name' => 'diff identical files by file (github issue #280)', + 'cd' => '../tests/inputs/issues/280', + 'args' => '--by-file --diff L R', + 'ref' => '../tests/outputs/issues/280/280_by_file.yaml', + }, + + { + 'name' => '--follow-links, --not-match-d, --fullpath 1/6 (github issue #286)', + 'cd' => '../tests/inputs/issues/286', + 'args' => ' --not-match-d ignore_subdir project', + 'ref' => '../tests/outputs/issues/286/1.yaml', + }, + + { + 'name' => '--follow-links, --not-match-d, --fullpath 2/6 (github issue #286)', + 'cd' => '../tests/inputs/issues/286', + 'args' => '--follow-links --not-match-d ignore_subdir project', + + 'ref' => '../tests/outputs/issues/286/2.yaml', + }, + + { + 'name' => '--follow-links, --not-match-d, --fullpath 3/6 (github issue #286)', + 'cd' => '../tests/inputs/issues/286', + 'args' => ' --not-match-d ignore_subdir --fullpath project', + + 'ref' => '../tests/outputs/issues/286/3.yaml', + }, + + { + 'name' => '--follow-links, --not-match-d, --fullpath 4/6 (github issue #286)', + 'cd' => '../tests/inputs/issues/286', + 'args' => '--follow-links --not-match-d ignore_subdir --fullpath project', + 'ref' => '../tests/outputs/issues/286/4.yaml', + }, + + { + 'name' => '--follow-links, --not-match-d, --fullpath 5/6 (github issue #286)', + 'cd' => '../tests/inputs/issues/286', + 'args' => ' --not-match-d project/ignore_subdir --fullpath project', + 'ref' => '../tests/outputs/issues/286/5.yaml', + }, + + { + 'name' => '--follow-links, --not-match-d, --fullpath 6/6 (github issue #286)', + 'cd' => '../tests/inputs/issues/286', + 'args' => '--follow-links --not-match-d project/ignore_subdir --fullpath project', + 'ref' => '../tests/outputs/issues/286/6.yaml', + }, + + { + 'name' => '--include-ext m,lua (github issue #296)', + 'cd' => '../tests/inputs/issues/296', + 'args' => '--include-ext m,lua .', + 'ref' => '../tests/outputs/issues/296/results.yaml', + }, + + { + 'name' => '--strip-str-comments (github issue #245)', + 'cd' => '../tests/inputs/issues/245', + 'args' => '--strip-str-comments .', + 'ref' => '../tests/outputs/issues/245/CRS.scala.yaml', + }, + + { + 'name' => 'YAML --by-file output with unusual filename (github issue #312)', + 'cd' => '../tests/inputs/issues/312', + 'args' => '--by-file .', + 'ref' => '../tests/outputs/issues/312/results.yaml', + }, + + { + 'name' => 'custom Smarty definition (github issue #327)', + 'cd' => '../tests/inputs/issues/327', + 'args' => '--force-lang-def=lang.config example.smarty2', + 'ref' => '../tests/outputs/issues/327/results.yaml', + }, + + { + 'name' => 'UTF-8 output file encoding', + 'cd' => '../tests/inputs/issues/318', + 'args' => '--by-file --file-encoding utf8 R*.cs', + 'ref' => '../tests/inputs/issues/318/Rcs.yaml', # results in input dir + }, + + { + 'name' => 'distinguish TeX from VB (github issue #341)', + 'cd' => '../tests/inputs/issues/341', + 'args' => '.', + 'ref' => '../tests/outputs/issues/341/results.yaml', + }, + + { + 'name' => '--strip-str-comments (github issue #350)', + 'cd' => '../tests/inputs/issues/350', + 'args' => '--strip-str-comments .', + 'ref' => '../tests/outputs/issues/350/fs.go.yaml', + }, + + { + 'name' => 'Java comments in strings, issue #365', + 'cd' => '../tests/inputs/issues/365', + 'args' => 'RSpecTests.java', + 'ref' => '../tests/outputs/issues/365/results.yaml', + }, + + { + 'name' => 'Arduino IDE 0xA0 characters', + 'cd' => '../tests/inputs/issues/370', + 'args' => 'arduino_issue_370.ino', + 'ref' => '../tests/outputs/issues/370/results.yaml', + }, + + { + 'name' => 'Python docstrings --docstring-as-code', + 'cd' => '../tests/inputs/issues/375', + 'args' => '--docstring-as-code docstring.py', + 'ref' => '../tests/outputs/issues/375/results.yaml', + }, + + { + 'name' => 'Perl v. Prolog', + 'cd' => '../tests/inputs/issues/380', + 'args' => 'wrapper.pl', + 'ref' => '../tests/outputs/issues/380/wrapper.pl.yaml', + }, + + { + 'name' => 'Java comments and continuation lines issue 381', + 'cd' => '../tests/inputs/issues/381', + 'args' => 'issue381.java', + 'ref' => '../tests/outputs/issues/381/issue381.java.yaml', + }, + + { + 'name' => 'C comments w/ backslashed quote in strings issue 381', + 'cd' => '../tests/inputs/issues/381', + 'args' => '--strip-str-comments issue381.c', + 'ref' => '../tests/outputs/issues/381/issue381.c.yaml', + }, + + { + 'name' => '--exclude-content issue 396', + 'cd' => '../tests/inputs', + 'args' => '--exclude-content Lambda acpclust.R sample.R utilities.R', + 'ref' => '../tests/outputs/issues/396/excl.yaml', + }, + + { + 'name' => '--exclude-content w/--diff issue 396', + 'cd' => '../tests/inputs/issues/280', + 'args' => '--exclude-content Copyright --diff L R', + 'ref' => '../tests/outputs/issues/396/excl_diff.yaml', + }, + + { + 'name' => 'Python with /* in strings issue 405', + 'cd' => '../tests/inputs/issues/405', + 'args' => 'globs.py', + 'ref' => '../tests/outputs/issues/405/globs.py.yaml', + }, + + { + 'name' => '--exclude-dir and --follow-link, #407 1/3', + 'cd' => '../tests/inputs/issues/407', + 'args' => '--follow-link --exclude-dir Test count_dir', + 'ref' => '../tests/outputs/issues/407/results1.yaml', + }, + + { + 'name' => '--exclude-dir and --follow-link, #407 2/3', + 'cd' => '../tests/inputs/issues/407', + 'args' => '--exclude-dir Test level2', + 'ref' => '../tests/outputs/issues/407/results2.yaml', + }, + + { + 'name' => '--exclude-dir and --follow-link, #407 3/3', + 'cd' => '../tests/inputs/issues/407', + 'args' => '--follow-link --exclude-dir Test level2', + 'ref' => '../tests/outputs/issues/407/results3.yaml', + }, + + { + 'name' => 'doubly counted she-bang line, #408', + 'cd' => '../tests/inputs/issues/408', + 'args' => 'badly_named_ruby.pl', + 'ref' => '../tests/outputs/issues/408/badly_named_ruby.yaml', + }, + + { + 'name' => 'case insensitive file ext, #420', + 'cd' => '../tests/inputs/issues/420', + 'args' => '--ignore-case-ext .', + 'ref' => '../tests/outputs/issues/420/results.yaml', + }, + + { + 'name' => 'diff with --exclude-list-file, #433', + 'cd' => '../tests/inputs/issues/433', + 'args' => '--exclude-list-file excl.txt --by-file --follow-links --diff L R + ', + 'ref' => '../tests/outputs/issues/433/results.yaml', + }, + { + 'name' => 'JavaScript comment in string, #454', + 'cd' => '../tests/inputs/issues/454', + 'args' => '--strip-str-comments createServer.js', + 'ref' => '../tests/outputs/issues/454/createServer.js.yaml', + }, + { + 'name' => 'XML with no extension, #456', + 'cd' => '../tests/inputs/issues/456', + 'args' => 'XML_no_ext', + 'ref' => '../tests/outputs/issues/456/XML_no_ext.yaml', + }, + { + 'name' => 'XML with unusual extension, #456', + 'cd' => '../tests/inputs/issues/456', + 'args' => 'XML_weird_ext.profile', + 'ref' => '../tests/outputs/issues/456/XML_weird_ext.profile.yaml', + }, + { + 'name' => 'ignore Algorithm::Diff::sdiff() failures, #463', + 'cd' => '../tests/inputs/issues/463', + 'args' => '--diff left.C right.C', + 'ref' => '../tests/outputs/issues/463/diff.yaml', + }, + { + 'name' => 'diff list input format 1, #455', + 'cd' => '../', + 'args' => '--diff-list-file tests/inputs/issues/455/list.txt', + 'ref' => '../tests/outputs/issues/455/list.yaml', + }, + { + 'name' => 'diff list input format 2, #455', + 'cd' => '../', + 'args' => '--diff-list-file tests/inputs/issues/455/list_align.txt', + 'ref' => '../tests/outputs/issues/455/list_align.yaml', + }, + { + 'name' => 'replace_regex with null, #472', + 'cd' => '../tests/inputs/issues/472', + 'args' => '--force-lang-def lua_def.txt not_really.lua', + 'ref' => '../tests/outputs/issues/472/not_really.lua.yaml', + }, + { + 'name' => '--exclude-lang --diff 1/3, #476', + 'cd' => '../tests/inputs/issues/476', + 'args' => '--diff A B', + 'ref' => '../tests/outputs/issues/476/all.yaml', + }, + { + 'name' => '--exclude-lang --diff 2/3, #476', + 'cd' => '../tests/inputs/issues/476', + 'args' => "--exclude-lang 'Fortran 90' --diff A B", + 'ref' => '../tests/outputs/issues/476/no_fortran.yaml', + }, + { + 'name' => '--exclude-lang --diff 3/3, #476', + 'cd' => '../tests/inputs/issues/476', + 'args' => "--exclude-lang C++ --diff A B", + 'ref' => '../tests/outputs/issues/476/no_cpp.yaml', + }, + # Next test, 482, requires an empty directory B. Git + # does not like this so create it at runtime. + { + 'name' => '--include-lang --diff, #482', + 'cd' => '../tests/inputs/issues/482', + 'args' => '--include-lang C --diff A B', + 'ref' => '../tests/outputs/issues/482/results.yaml', + }, + + { + 'name' => '--unicode #494', + 'cd' => '../tests/inputs/issues/494', + 'args' => '--unicode --by-file P*.sql', + 'ref' => '../tests/outputs/issues/494/results.yaml', + }, + + { + 'name' => '--diff-list-file #513', + 'cd' => '../tests/inputs/issues/513', + 'args' => '--diff-list-file diff_list.txt', + 'ref' => '../tests/outputs/issues/513/results.yaml', + }, + + { + 'name' => '--list-file BOM #502', + 'cd' => '../tests/inputs/issues/502', + 'args' => '--list-file FileCounter20200715140433.txt', + 'ref' => '../tests/outputs/issues/502/results.yaml', + }, + + { + 'name' => 'Julia with docstring as comment #520 1/2', + 'cd' => '../tests/inputs/issues/520', + 'args' => 'julia_docstr.jl', + 'ref' => '../tests/outputs/issues/520/doc_as_comment.yaml', + }, + + { + 'name' => 'Julia with docstring as comment #520 2/2', + 'cd' => '../tests/inputs/issues/520', + 'args' => '--docstring-as-code julia_docstr.jl', + 'ref' => '../tests/outputs/issues/520/doc_as_code.yaml', + }, + + { + 'name' => 'diff alignment on Windows #521 1/2', + 'cd' => '../tests/inputs/issues/521', + 'args' => '--diff "Test 188" ../521/Test188New', + 'ref' => '../tests/outputs/issues/521/uniq.yaml', + }, + + { + 'name' => 'diff alignment on Windows #521 2/2', + 'cd' => '../tests/inputs/issues/521', + 'args' => '--skip-uniqueness --diff "Test 188" ../521/Test188New', + 'ref' => '../tests/outputs/issues/521/skip_uniq.yaml', + }, + + { + 'name' => '--summary-cutoff (f:1) #528 1/3', + 'cd' => '../tests/inputs/issues/528', + 'args' => '--summary-cutoff f:1 .', + 'ref' => '../tests/outputs/issues/528/cutoff_files_1.yaml', + }, + + { + 'name' => '--summary-cutoff (c:10) #528 2/3', + 'cd' => '../tests/inputs/issues/528', + 'args' => '--summary-cutoff c:10 .', + 'ref' => '../tests/outputs/issues/528/cutoff_code_10.yaml', + }, + + { + 'name' => '--summary-cutoff (c:50%) #528 3/3', + 'cd' => '../tests/inputs/issues/528', + 'args' => '--summary-cutoff c:50% .', + 'ref' => '../tests/outputs/issues/528/cutoff_code_50pct.yaml', + }, + + { + 'name' => '--skip-leading 2 #530 1/4', + 'cd' => '../tests/inputs/issues/530', + 'args' => '--skip-leading 2 .', + 'ref' => '../tests/outputs/issues/530/case_1.yaml', + }, + + { + 'name' => '--skip-leading 100 #530 2/4', + 'cd' => '../tests/inputs/issues/530', + 'args' => '--skip-leading 100 .', + 'ref' => '../tests/outputs/issues/530/case_2.yaml', + }, + + { + 'name' => '--skip-leading 2,c,h #530 3/4', + 'cd' => '../tests/inputs/issues/530', + 'args' => '--skip-leading 2,c,h .', + 'ref' => '../tests/outputs/issues/530/case_3.yaml', + }, + + { + 'name' => '--skip-leading 2,C,H #530 4/4', + 'cd' => '../tests/inputs/issues/530', + 'args' => '--skip-leading 2,C,H .', + 'ref' => '../tests/outputs/issues/530/case_4.yaml', + }, + + { + 'name' => '--force-lang-def #537 1/2', + 'cd' => '../tests/inputs/issues/537', + 'args' => '--force-lang-def my_define.txt sourceCounter.vsql', + 'ref' => '../tests/outputs/issues/537/results_force.yaml', + }, + + { + 'name' => '--read-lang-def #537 2/2', + 'cd' => '../tests/inputs/issues/537', + 'args' => '--read-lang-def my_define.txt sourceCounter.vsql', + 'ref' => '../tests/outputs/issues/537/results_read.yaml', + }, + + { + 'name' => 'Elm empty comment, #538', + 'cd' => '../tests/inputs/issues/538', + 'args' => 'add.elm', + 'ref' => '../tests/outputs/issues/538/add.elm.yaml', + }, + + { + 'name' => 'Elm nested block comments, #539', + 'cd' => '../tests/inputs/issues/539', + 'args' => 'nested_comments.elm', + 'ref' => '../tests/outputs/issues/539/nested_comments.elm.yaml', + }, + + { + 'name' => 'preserve upper/lowercase filenames on Windows, #540', + 'cd' => '../tests/inputs/issues/540', + 'args' => '--windows --by-file Hello.f', + 'ref' => '../tests/outputs/issues/540/Hello.f.yaml', + }, + + { + 'name' => 'accept all file extensions in user-provided language definitions, #542', + 'cd' => '../tests/inputs/issues/542', + 'args' => '--read-lang-def txt_lang_def.txtt txt_lang_def.txtt', + 'ref' => '../tests/outputs/issues/542/results.yaml', + }, + + { + 'name' => 'small unicode files, #580', + 'cd' => '../tests/inputs/issues/580', + 'args' => '--unicode encodingtest.cs', + 'ref' => '../tests/outputs/issues/580/encodingtest.cs.yaml', + }, + + { + 'name' => 'identify autogenerated C#, #579', + 'cd' => '../tests/inputs/issues/579', + 'args' => 'csharp-autogen.cs', + 'ref' => '../tests/outputs/issues/579/csharp-autogen.cs.yaml', + }, + + { + 'name' => 'config file from list file directory, #577', + 'cd' => '../tests/inputs/issues/577', + 'args' => '--diff-list-file diff_list_file.txt', + 'ref' => '../tests/outputs/issues/577/diff_list.yaml', + }, + + { + 'name' => '--force-lang-def without XML definition, #596', + 'cd' => '../tests/inputs/issues/596', + 'args' => '--force-lang-def def.txt .', + 'ref' => '../tests/outputs/issues/596/results.yaml', + }, + + { + 'name' => '--csv-delimiter="#", #597', + 'cd' => '../tests/inputs/issues/597', + 'args' => '--csv-delimiter="#" .', + 'ref' => '../tests/outputs/issues/597/results.yaml', + }, + + { + 'name' => '--unicode (uninitialized value), #606', + 'cd' => '../tests/inputs/issues/606', + 'args' => '--unicode in', + 'ref' => '../tests/outputs/issues/606/results.yaml', + }, + + { + 'name' => 'CMakeLists.txt on Windows (lowercase file), #611', + 'cd' => '../tests/inputs/issues/611', + 'args' => '.', + 'ref' => '../tests/outputs/issues/611/cmakelists.txt.yaml', + }, + + { + 'name' => 'SCSS separate from Sass, #613', + 'cd' => '../tests/inputs/issues/613', + 'args' => '.', + 'ref' => '../tests/outputs/issues/613/nav.scss.yaml', + }, + + { + 'name' => 'sequence of Assembly filters, #619', + 'cd' => '../tests/inputs/issues/619', + 'args' => '.', + 'ref' => '../tests/outputs/issues/619/RA.s.yaml', + }, + + { + 'name' => 'GraphQL descriptions, #628', + 'cd' => '../tests/inputs/issues/628', + 'args' => '.', + 'ref' => '../tests/outputs/issues/628/results.yaml', + }, + + { + 'name' => 'diff with dir of excluded extensions, #625', + 'cd' => '../tests/inputs/issues/625', + 'args' => '--diff old new', + 'ref' => '../tests/outputs/issues/625/results.yaml', + }, + + { + 'name' => 'case insensitive --include-lang, #637', + 'cd' => '../tests/inputs/issues/637', + 'args' => '--include-lang python,perl --follow-links A B', + 'ref' => '../tests/outputs/issues/637/straight_incl_lang.yaml', + }, + + { + 'name' => 'case insensitive --include-lang --diff, #637', + 'cd' => '../tests/inputs/issues/637', + 'args' => '--include-lang python,perl --follow-links --diff A B', + 'ref' => '../tests/outputs/issues/637/diff_incl_lang.yaml', + }, + + { + 'name' => 'empty Unicode file w/only BOM, #644', + 'cd' => '../tests/inputs/issues/644', + 'args' => 'UInt8.cs', + 'ref' => '../tests/outputs/issues/644/results.yaml', + }, + + { + 'name' => '--no-recurse, #657', + 'cd' => '../tests/inputs/issues/657', + 'args' => '--no-recurse .', + 'ref' => '../tests/outputs/issues/657/results.yaml', + }, + + { + 'name' => '--csv-delimiter="|", #670', + 'cd' => '../tests/inputs/issues/670', + 'args' => '--csv-delimiter="|" .', + 'ref' => '../tests/outputs/issues/670/results.yaml', + }, + + { + 'name' => '--diff-list-files, #692', + 'cd' => '../tests/inputs/issues/692', + 'args' => '--diff-list-files A.txt B.txt', + 'ref' => '../tests/outputs/issues/692/results.yaml', + }, + + { + 'name' => 'comments in OCaml strings, #701', + 'cd' => '../tests/inputs/issues/701', + 'args' => '--strip-str-comments demo.ml', + 'ref' => '../tests/outputs/issues/701/results.yaml', + }, + + { + 'name' => '--only-count-files, #708', + 'cd' => '../tests/inputs/dd', + 'args' => '--only-count-files .', + 'ref' => '../tests/outputs/issues/708/results.yaml', + }, + + { + 'name' => '--diff-list-file w/unknown lang, #710', + 'cd' => '../tests/inputs/issues/710', + 'args' => '--diff-list-file test_files.list', + 'ref' => '../tests/outputs/issues/710/results.yaml', + }, + + { + 'name' => 'nondeterministic --diff, #712', + 'cd' => '../tests/inputs/issues/712', + 'args' => "--include-lang='C' --by-file --diff dir1/ dir2/", + 'ref' => '../tests/outputs/issues/712/results.yaml', + }, + + { + 'name' => '--hide-rate --yaml, #713', + 'cd' => '../tests/inputs/issues/713', + 'args' => '--hide-rate --yaml .', + 'ref' => '../tests/outputs/issues/713/results.yaml', + }, + + { + 'name' => '--include-content, #720', + 'cd' => '../tests/inputs/issues/720', + 'args' => '--include-content=for --by-file ../../*.m', + 'ref' => '../tests/outputs/issues/720/results.yaml', + }, + + { + 'name' => 'additive --not-match-f, #722', + 'cd' => '../tests/inputs/issues/722', + 'args' => '--not-match-f lua --not-match-f 77 --by-file .', + 'ref' => '../tests/outputs/issues/722/results_1.yaml', }, ); diff --git a/cloc b/cloc index e5c0fba2..66557d34 100755 --- a/cloc +++ b/cloc @@ -1,6 +1,6 @@ #!/usr/bin/env perl # cloc -- Count Lines of Code {{{1 -# Copyright (C) 2006-2022 Al Danial +# Copyright (C) 2006-2023 Al Danial # First release August 2006 # # Includes code from: @@ -8,13 +8,13 @@ # http://www.dwheeler.com/sloccount/ # by David Wheeler. # - Regexp::Common v2017060201 -# http://search.cpan.org/~abigail/Regexp-Common-2017060201/lib/Regexp/Common.pm +# https://metacpan.org/pod/Regexp::Common # by Damian Conway and Abigail. -# - Win32::Autoglob -# http://search.cpan.org/~sburke/Win32-Autoglob-1.01/Autoglob.pm +# - Win32::Autoglob 1.01 +# https://metacpan.org/pod/Win32::Autoglob # by Sean M. Burke. -# - Algorithm::Diff -# http://search.cpan.org/~tyemq/Algorithm-Diff-1.1902/lib/Algorithm/Diff.pm +# - Algorithm::Diff 1.1902 +# https://metacpan.org/pod/Algorithm::Diff # by Tye McQueen. # # This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ # . # # 1}}} -my $VERSION = "1.95"; # odd number == beta; even number == stable +my $VERSION = "1.97"; # odd number == beta; even number == stable my $URL = "github.com/AlDanial/cloc"; # 'https://' pushes header too wide require 5.10.0; # use modules {{{1 @@ -75,18 +75,19 @@ if (defined $Regexp::Common::VERSION) { $HAVE_Rexexp_Common = 0; } -my $HAVE_Algorith_Diff = 0; +my $HAVE_Algorithm_Diff = 0; # Algorithm::Diff isn't in the standard distribution. It will # be installed in a temp directory if necessary. eval "use Algorithm::Diff qw ( sdiff ) "; if (defined $Algorithm::Diff::VERSION) { - $HAVE_Algorith_Diff = 1; + $HAVE_Algorithm_Diff = 1; } else { Install_Algorithm_Diff(); } -# print "2 HAVE_Algorith_Diff = $HAVE_Algorith_Diff\n"; + +# print "2 HAVE_Algorithm_Diff = $HAVE_Algorithm_Diff\n"; # test_alg_diff($ARGV[$#ARGV - 1], $ARGV[$#ARGV]); die; -# die "Hre=$HAVE_Rexexp_Common Had=$HAVE_Algorith_Diff"; +# die "Hre=$HAVE_Rexexp_Common Had=$HAVE_Algorithm_Diff"; # Uncomment next two lines when building Windows executable with perl2exe # or if running on a system that already has Regexp::Common. @@ -134,6 +135,17 @@ if ($ON_WINDOWS and $ENV{'SHELL'}) { $ON_WINDOWS = 1; # MKS defines $SHELL but still acts like Windows } } + +my $HAVE_Win32_Long_Path = 0; +# Win32::LongPath is an optional dependency that when available on +# Windows will be used to support reading files past the 255 char +# path length limit. +if ($ON_WINDOWS) { + eval "use Win32::LongPath;"; + if (defined $Win32::LongPath::VERSION) { + $HAVE_Win32_Long_Path = 1; + } +} my $config_file = ''; if ( $ENV{'HOME'} ) { $config_file = File::Spec->catfile( $ENV{'HOME'}, '.config', 'cloc', 'options.txt'); @@ -211,7 +223,18 @@ Usage: $script [options] | | + Compute differences in code and comments between + the files and directories listed in and + . Each input file should use the same + format as --list-file, where there is one file or + directory name per line. Only exact matches are + counted; relative path names will be resolved + starting from the directory where cloc is invoked. + This enables --diff mode. See also --list-file, + --diff-list-file, --diff. --vcs= Invoke a system call to to obtain a list of files to work on. If is 'git', then will invoke 'git ls-files' to get a file list and @@ -367,6 +390,7 @@ Usage: $script [options] | | | | Only count files containing text that matches the + given regular expression. --exclude-content= Exclude files containing text that matches the given regular expression. --exclude-dir=[,D2,] Exclude the given comma separated directories @@ -524,6 +550,7 @@ Usage: $script [options] | | Only count files whose basenames match the Perl regex. For example --match-f='^[Ww]idget' @@ -533,7 +560,7 @@ Usage: $script [options] | | Count all files except those whose basenames match the Perl regex. Add --fullpath to include parent directories in the regex instead of just - the basename. + the basename. This option may be repeated. --skip-archive= Ignore files that end with the given Perl regular expression. For example, if given --skip-archive='(zip|tar(\.(gz|Z|bz2|xz|7z))?)' @@ -605,8 +632,9 @@ Usage: $script [options] | | encodings(\":all\")), \"\\n\"' - --hide-rate Do not show line and file processing rates in the - output header. This makes output deterministic. + --hide-rate Do not show elapsed time, line processing rate, or + file processing rates in the output header. This + makes output deterministic. --json Write the results as JavaScript Object Notation (JSON) formatted output. --md Write the results as Markdown-formatted text. @@ -668,6 +696,7 @@ my ( $opt_diff , $opt_diff_alignment , $opt_diff_list_file , + $opt_diff_list_files , $opt_diff_timeout , $opt_timeout , $opt_html , @@ -680,6 +709,7 @@ my ( $opt_v , $opt_vcs , $opt_version , + $opt_include_content , $opt_exclude_content , $opt_exclude_lang , $opt_exclude_list_file , @@ -715,9 +745,9 @@ my ( $opt_json , $opt_md , $opt_match_f , - $opt_not_match_f , + @opt_not_match_f , $opt_match_d , - $opt_not_match_d , + @opt_not_match_d , $opt_skip_uniqueness , $opt_list_file , $opt_help , @@ -755,6 +785,7 @@ my ( $opt_summary_cutoff , $opt_skip_leading , $opt_no_recurse , + $opt_only_count_files , ); my $getopt_success = GetOptions( # {{{1 @@ -764,6 +795,7 @@ my $getopt_success = GetOptions( # {{{1 "counted=s" => \$opt_counted , "include_ext|include-ext=s" => \$opt_include_ext , "include_lang|include-lang=s" => \$opt_include_lang , + "include_content|include-content=s" => \$opt_include_content , "exclude_content|exclude-content=s" => \$opt_exclude_content , "exclude_lang|exclude-lang=s" => \$opt_exclude_lang , "exclude_dir|exclude-dir=s" => \$opt_exclude_dir , @@ -776,6 +808,7 @@ my $getopt_success = GetOptions( # {{{1 "diff-alignment|diff_alignment=s" => \$opt_diff_alignment , "diff-timeout|diff_timeout=i" => \$opt_diff_timeout , "diff-list-file|diff_list_file=s" => \$opt_diff_list_file , + "diff-list-files|diff_list_files" => \$opt_diff_list_files , "timeout=i" => \$opt_timeout , "html" => \$opt_html , "ignored=s" => \$opt_ignored , @@ -815,9 +848,9 @@ my $getopt_success = GetOptions( # {{{1 "md" => \$opt_md , "fullpath" => \$opt_fullpath , "match_f|match-f=s" => \$opt_match_f , - "not_match_f|not-match-f=s" => \$opt_not_match_f , + "not_match_f|not-match-f=s" => \@opt_not_match_f , "match_d|match-d=s" => \$opt_match_d , - "not_match_d|not-match-d=s" => \$opt_not_match_d , + "not_match_d|not-match-d=s" => \@opt_not_match_d , "list_file|list-file=s" => \$opt_list_file , "help" => \$opt_help , "skip_win_hidden|skip-win-hidden" => \$opt_skip_win_hidden , @@ -855,6 +888,7 @@ my $getopt_success = GetOptions( # {{{1 "summary_cutoff|summary-cutoff=s" => \$opt_summary_cutoff , "skip_leading|skip-leading:s" => \$opt_skip_leading , "no_recurse|no-recurse" => \$opt_no_recurse , + "only_count_files|only-count-files" => \$opt_only_count_files , ); # 1}}} $config_file = $opt_config_file if defined $opt_config_file; @@ -865,6 +899,7 @@ load_from_config_file($config_file, # {{{2 \$opt_counted , \$opt_include_ext , \$opt_include_lang , + \$opt_include_content , \$opt_exclude_content , \$opt_exclude_lang , \$opt_exclude_dir , @@ -873,6 +908,7 @@ load_from_config_file($config_file, # {{{2 \$opt_extract_with , \$opt_found , \$opt_count_diff , + \$opt_diff_list_files , \$opt_diff , \$opt_diff_alignment , \$opt_diff_timeout , @@ -913,9 +949,9 @@ load_from_config_file($config_file, # {{{2 \$opt_md , \$opt_fullpath , \$opt_match_f , - \$opt_not_match_f , + \@opt_not_match_f , \$opt_match_d , - \$opt_not_match_d , + \@opt_not_match_d , \$opt_list_file , \$opt_help , \$opt_skip_win_hidden , @@ -951,6 +987,10 @@ if ($opt_version) { printf "$VERSION\n"; exit; } +my $opt_git = 0; +$opt_git = 1 if defined($opt_git_diff_all) or + defined($opt_git_diff_rel) or + (defined($opt_vcs) and ($opt_vcs eq "git")); $opt_by_file = 1 if defined $opt_by_file_by_lang; my $CLOC_XSL = "cloc.xsl"; # created with --xsl $CLOC_XSL = "cloc-diff.xsl" if $opt_diff; @@ -982,6 +1022,7 @@ $Exclude_Dir{".config"} = 1; $opt_count_diff = defined $opt_count_diff ? 1 : 0; $opt_diff = 1 if $opt_diff_alignment or $opt_diff_list_file or + $opt_diff_list_files or $opt_git_diff_rel or $opt_git_diff_all or $opt_git_diff_simindex; @@ -1037,6 +1078,17 @@ if ($opt_use_sloccount) { } $opt_vcs = 0 if $opt_force_git; +# replace Windows path separators with / +if ($ON_WINDOWS) { + map { s{\\}{/}g } @ARGV; + if ($opt_git) { + # PowerShell tab expansion automatically prefixes local directories + # with ".\" (now mapped to "./"). git ls-files output does not + # include this. Strip this prefix to permit clean matches. + map { s{^\./}{} } @ARGV; + } +} + my @COUNT_DIFF_ARGV = undef; my $COUNT_DIFF_report_file = undef; if ($opt_count_diff and !$opt_diff_list_file) { @@ -1051,7 +1103,8 @@ if ($opt_count_diff and !$opt_diff_list_file) { } # Options defaults: -$opt_quiet = 1 if ($opt_md or $opt_json) and !defined $opt_report_file; +$opt_quiet = 1 if ($opt_md or $opt_json or !(-t STDOUT)) + and !defined $opt_report_file; $opt_progress_rate = 100 unless defined $opt_progress_rate; $opt_progress_rate = 0 if defined $opt_quiet; if (!defined $opt_v) { @@ -1091,9 +1144,9 @@ $opt_by_percent = lc $opt_by_percent; if (defined $opt_vcs) { if ($opt_vcs eq "auto") { - if (-d ".git") { + if (is_dir(".git")) { $opt_vcs = "git"; - } elsif (-d ".svn") { + } elsif (is_dir(".svn")) { $opt_vcs = "svn"; } else { warn "--vcs auto: unable to determine versioning system\n"; @@ -1344,6 +1397,8 @@ if ($opt_count_diff) { if ($opt_count_diff == 3) { $opt_diff = 1; @ARGV = @{$COUNT_DIFF_ARGV[ $opt_count_diff ]}; # last arg is list of list + } elsif ($opt_diff_list_files) { + $opt_diff = 0; } if ($opt_report_file) { # Instead of just one output file, will have three. @@ -1696,11 +1751,16 @@ if ($opt_diff_list_file) { } for (my $i = 0; $i < scalar @ARGV; $i++) { if ($opt_diff_list_file) { - push @fh, make_file_list($files_for_set[$i], + push @fh, make_file_list($files_for_set[$i], $i+1, + \%Error_Codes, \@Errors, \%Ignored); + @{$files_for_set[$i]} = @file_list; + } elsif ($opt_diff_list_files) { + my @list_files = read_list_file($ARGV[$i]); + push @fh, make_file_list(\@list_files, $i+1, \%Error_Codes, \@Errors, \%Ignored); @{$files_for_set[$i]} = @file_list; } else { - push @fh, make_file_list([ $ARGV[$i] ], + push @fh, make_file_list([ $ARGV[$i] ], $i+1, \%Error_Codes, \@Errors, \%Ignored); @{$files_for_set[$i]} = @file_list; } @@ -1734,6 +1794,10 @@ foreach my $FH (@fh) { # loop over each pair of file sets exclude_by_regex($opt_exclude_content, # in \%{$unique_source_file{$FH}}, # in/out \%Ignored); # out + } elsif ($opt_include_content) { + include_by_regex($opt_include_content, # in + \%{$unique_source_file{$FH}}, # in/out + \%Ignored); # out } if ($opt_include_lang) { @@ -1932,16 +1996,18 @@ if ($opt_by_file) { } else { # Step 4: Separate code from non-code files. {{{1 my $fh = 0; -if ($opt_list_file or $opt_vcs) { +if ($opt_list_file or $opt_diff_list_files or $opt_vcs) { my @list; if ($opt_vcs) { @list = invoke_generator($opt_vcs, \@ARGV); - } else { + } elsif ($opt_list_file) { @list = read_list_file($opt_list_file); + } else { + @list = read_list_file($ARGV[0]); } - $fh = make_file_list(\@list, \%Error_Codes, \@Errors, \%Ignored); + $fh = make_file_list(\@list, 0, \%Error_Codes, \@Errors, \%Ignored); } else { - $fh = make_file_list(\@ARGV, \%Error_Codes, \@Errors, \%Ignored); + $fh = make_file_list(\@ARGV, 0, \%Error_Codes, \@Errors, \%Ignored); # make_file_list populates global variable @file_list via call to # File::Find's find() which in turn calls files() } @@ -1952,7 +2018,7 @@ if ($opt_exclude_list_file) { \%Ignored); } if ($opt_skip_win_hidden and $ON_WINDOWS) { - my @file_list_minus_hidded = (); + my @file_list_minus_hidden = (); # eval code to run on Unix without 'missing Win32::File module' error. my $win32_file_invocation = ' use Win32::File; @@ -1964,11 +2030,11 @@ if ($opt_skip_win_hidden and $ON_WINDOWS) { print "Ignoring $F since it is a Windows hidden file\n" if $opt_v > 1; } else { - push @file_list_minus_hidded, $F; + push @file_list_minus_hidden, $F; } }'; eval $win32_file_invocation; - @file_list = @file_list_minus_hidded; + @file_list = @file_list_minus_hidden; } if ($opt_no_autogen) { exclude_autogenerated_files(\@file_list, # in/out @@ -1993,6 +2059,10 @@ if ($opt_exclude_content) { exclude_by_regex($opt_exclude_content, # in \%unique_source_file , # in/out \%Ignored); # out +} elsif ($opt_include_content) { + include_by_regex($opt_include_content, # in + \%unique_source_file , # in/out + \%Ignored); # out } printf "%8d unique file%s. \n", plural_form(scalar keys %unique_source_file) @@ -2075,7 +2145,10 @@ my $end_time = get_time(); printf "%8d file%s ignored.\n", plural_form(scalar keys %Ignored) unless $opt_quiet; print_errors(\%Error_Codes, \@Errors) if @Errors; -exit unless %Results_by_Language; +if (!%Results_by_Language) { + write_null_results($opt_json, $opt_xml, $opt_report_file); + exit; +} generate_sql($end_time - $start_time, \%Results_by_File, \%Scale_Factor) if $opt_sql; @@ -2206,6 +2279,29 @@ sub exclude_by_regex { # {{{1 delete $rh_unique_source_file->{$file}; } } # 1}}} +sub include_by_regex { # {{{1 + my ($regex, + $rh_unique_source_file, # in/out + $rh_ignored , # out + ) = @_; + my @exclude = (); + foreach my $file (keys %{$rh_unique_source_file}) { + my $keep_this_one = 0; + foreach my $line (read_file($file)) { + if ($line =~ /$regex/) { + $keep_this_one = 1; + last; + } + } + if (!$keep_this_one) { + $rh_ignored->{$file} = "does not satisfy --include-content=$regex"; + push @exclude, $file; + } + } + foreach my $file (@exclude) { + delete $rh_unique_source_file->{$file}; + } +} # 1}}} sub get_max_processes { # {{{1 # If user has specified valid number of processes, use that. if (defined $opt_processes) { @@ -2263,7 +2359,7 @@ sub get_max_processes { # {{{1 return 0; } # 1}}} sub exclude_autogenerated_files { # {{{1 - my ($ra_file_list, # in + my ($ra_file_list, # in/out $rh_Err , # in hash of error codes $raa_errors , # out $rh_Ignored , # out @@ -2285,8 +2381,40 @@ sub exclude_autogenerated_files { # {{{1 } } @{$ra_file_list} = @file_list_minus_autogen; + + if ($opt_force_git) { + my $repo_dir = git_root_dir(); + my @file_list_minus_linguist = (); + # if there's a .gitattributes file, look for linguist-generated + # and linguist-vendored entries to ignore + my $GA = ".gitattributes"; + if (-f $GA) { + foreach my $line (read_file($GA)) { + next unless $line =~ /^(.*?)\s+(linguist-(vendored|generated))/; + my $re = glob2regex($1); + foreach my $file (@{$ra_file_list}) { + my $full_path = File::Spec->catfile($repo_dir, $file); + my $rel_file = File::Spec->abs2rel($full_path, $cwd); + if ($rel_file =~ m{$re}) { +#print "RULE [$rel_file] v [$re]\n"; + $rh_Ignored->{$file} = "matches $GA rule '$line'"; + } else { + push @file_list_minus_linguist, $file; + } + } + } + } + } print "<- exclude_autogenerated_files()\n" if $opt_v > 2; } # 1}}} +sub git_root_dir { # {{{1 + # if in a git repo, return the repo's top level directory + my $cmd = "git rev-parse --show-toplevel"; + print $cmd, "\n" if $opt_v > 1; + my $dir = undef; + chomp($dir = `$cmd`); + die "Not in a git repository" unless $dir +} # 1}}} sub file_extension { # {{{1 my ($fname, ) = @_; $fname =~ m/\.(\w+)$/; @@ -2345,30 +2473,32 @@ sub count_files { # {{{1 next; } - my ($all_line_count, $blank_count, $comment_count, $code_count); - if ($opt_use_sloccount and $Language{$file} =~ /^(C|C\+\+|XML|PHP|Pascal|Java)$/) { - chomp ($blank_count = `grep -cv \"[^[:space:]]\" '$file'`); - chomp ($all_line_count = `cat '$file' | wc -l`); - if ($Language{$file} =~ /^(C|C\+\+)$/) { - $code_count = `cat '$file' | c_count | head -n 1`; - } elsif ($Language{$file} eq "XML") { - $code_count = `cat '$file' | xml_count | head -n 1`; - } elsif ($Language{$file} eq "PHP") { - $code_count = `cat '$file' | php_count | head -n 1`; - } elsif ($Language{$file} eq "Pascal") { - $code_count = `cat '$file' | pascal_count | head -n 1`; - } elsif ($Language{$file} eq "Java") { - $code_count = `cat '$file' | java_count | head -n 1`; + my ($all_line_count, $blank_count, $comment_count, $code_count) = (0, 0, 0, 0); + if (!$opt_only_count_files) { + if ($opt_use_sloccount and $Language{$file} =~ /^(C|C\+\+|XML|PHP|Pascal|Java)$/) { + chomp ($blank_count = `grep -cv \"[^[:space:]]\" '$file'`); + chomp ($all_line_count = `cat '$file' | wc -l`); + if ($Language{$file} =~ /^(C|C\+\+)$/) { + $code_count = `cat '$file' | c_count | head -n 1`; + } elsif ($Language{$file} eq "XML") { + $code_count = `cat '$file' | xml_count | head -n 1`; + } elsif ($Language{$file} eq "PHP") { + $code_count = `cat '$file' | php_count | head -n 1`; + } elsif ($Language{$file} eq "Pascal") { + $code_count = `cat '$file' | pascal_count | head -n 1`; + } elsif ($Language{$file} eq "Java") { + $code_count = `cat '$file' | java_count | head -n 1`; + } else { + die "SLOCCount match failure: file=[$file] lang=[$Language{$file}]"; + } + $code_count = substr($code_count, 0, -2); + $comment_count = $all_line_count - $code_count - $blank_count; } else { - die "SLOCCount match failure: file=[$file] lang=[$Language{$file}]"; + ($all_line_count, + $blank_count , + $comment_count ,) = call_counter($file, $Language{$file}, \@Errors); + $code_count = $all_line_count - $blank_count - $comment_count; } - $code_count = substr($code_count, 0, -2); - $comment_count = $all_line_count - $code_count - $blank_count; - } else { - ($all_line_count, - $blank_count , - $comment_count ,) = call_counter($file, $Language{$file}, \@Errors); - $code_count = $all_line_count - $blank_count - $comment_count; } if ($opt_by_file) { @@ -2462,6 +2592,10 @@ sub count_filesets { # {{{1 # is in a known language. next if $opt_include_ext and not $Include_Ext{ file_extension($f) }; + if (!defined $Language{$fset_b}{$f}) { + $p_ignored{$f} = "excluded or unknown language"; + next; + } next if $opt_include_lang and not $Include_Language{lc($Language{$fset_b}{$f})}; my $this_lang = $Language{$fset_b}{$f}; @@ -2510,7 +2644,7 @@ sub count_filesets { # {{{1 and (not defined $Language{$fset_a}{$f} or not defined $Include_Language{lc($Language{$fset_a}{$f})}); my $this_lang = $Language{$fset_a}{$f}; - if ($this_lang eq "(unknown)") { + if ((not defined $this_lang) or ($this_lang eq "(unknown)")) { $p_ignored{$f} = "unknown language"; next; } @@ -2951,7 +3085,7 @@ sub combine_results { # {{{1 foreach my $file (@{$ra_report_files}) { my $n_results_found = 0; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { warn "Unable to read $file; ignoring.\n"; next; @@ -3326,7 +3460,15 @@ sub xml_yaml_or_json_header { # {{{1 if ($opt_xml) { $header = ""; $header .= "\n" if $opt_xsl; - $header .= "<${type}results> + if ($opt_hide_rate) { + $header .= "<${type}results> +
+ $URL + $version + $sum_files + $sum_lines"; + } else { + $header .= "<${type}results>
$URL $version @@ -3335,6 +3477,7 @@ sub xml_yaml_or_json_header { # {{{1 $sum_lines $file_rate $line_rate"; + } $header .= "\n$report_file" if $opt_report_file; $header .= "\n
"; @@ -3350,7 +3493,14 @@ sub xml_yaml_or_json_header { # {{{1 } } elsif ($opt_yaml or $opt_json) { my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators(); - $header = "${start}${Q}header${Q} : $open_B + if ($opt_hide_rate) { + $header = "${start}${Q}header${Q} : $open_B + ${Q}cloc_url${Q} : ${Q}$URL${Q}${C} + ${Q}cloc_version${Q} : ${Q}$version${Q}${C} + ${Q}n_files${Q} : $sum_files${C} + ${Q}n_lines${Q} : $sum_lines${C}"; + } else { + $header = "${start}${Q}header${Q} : $open_B ${Q}cloc_url${Q} : ${Q}$URL${Q}${C} ${Q}cloc_version${Q} : ${Q}$version${Q}${C} ${Q}elapsed_seconds${Q} : $elapsed_sec${C} @@ -3358,6 +3508,7 @@ sub xml_yaml_or_json_header { # {{{1 ${Q}n_lines${Q} : $sum_lines${C} ${Q}files_per_second${Q} : $file_rate${C} ${Q}lines_per_second${Q} : $line_rate"; + } if ($opt_report_file) { my $Fname = $opt_report_file; $Fname =~ s{\\}{\\\\}g if $ON_WINDOWS; @@ -3822,9 +3973,17 @@ create table t ( my $open_mode = ">"; $open_mode = ">>" if $opt_sql_append; - my $fh = new IO::File; # $opt_sql, "w"; - if (!$fh->open("${open_mode}${opt_sql}")) { - die "Unable to write to $opt_sql $!\n"; + my $fh; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path and $opt_sql ne "-") { + # only use the Win32::LongPath wrapper here when needed, + # and only when not writing to STDOUT. + $fh = open_file($open_mode, $opt_sql, 1); + die "Unable to write to $opt_sql\n" if !defined $fh; + } else { + $fh = new IO::File; # $opt_sql, "w"; + if (!$fh->open("${open_mode}${opt_sql}")) { + die "Unable to write to $opt_sql $!\n"; + } } print $fh $schema unless defined $opt_sql_append; @@ -4877,10 +5036,16 @@ sub top_level_SMB_dir { # {{{1 my ($ra_arg_list,) = @_; # in user supplied file name, directory name, git hash, etc foreach my $entry (@{$ra_arg_list}) { - next unless -d $entry; + next unless is_dir($entry); # gets here if $entry is a directory; now get its nlink value - my @stats = stat($entry); - my $nlink = $stats[3]; + my $nlink; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $stats = statL($entry); + $nlink = $stats->{nlink} if defined $stats; + } else { + my @stats = stat($entry); + $nlink = $stats[3]; + } return 1 if $nlink == 2; # meaning it is an SMB mount } return 0; @@ -4894,12 +5059,12 @@ sub get_git_metadata { # {{{1 my $prt_args = join(",", @{$ra_arg_list}); print "-> get_git_metadata($prt_args)\n" if $opt_v > 2; foreach my $arg (@{$ra_arg_list}) { - next if -f $arg; + next if is_file($arg); my $origin = `git remote get-url origin 2>&1`; next if $origin =~ /^fatal:/; chomp($rh_git_metadata->{$arg}{"origin"} = $origin); chomp($rh_git_metadata->{$arg}{"branch"} = `git symbolic-ref --short HEAD`); - if (-d $arg) { + if (is_dir($arg)) { chomp($rh_git_metadata->{$arg}{"commit"} = `git rev-parse HEAD`); } else { chomp($rh_git_metadata->{$arg}{"commit"} = `git rev-parse $arg`); @@ -4947,7 +5112,7 @@ sub replace_git_hash_with_tarfile { # {{{1 my $i = 0; foreach my $file_or_dir (@{$ra_arg_list}) { ++$i; - if (-r $file_or_dir) { # readable file or dir; not a git hash + if (can_read($file_or_dir)) { # readable file or dir; not a git hash $replacement_arg_list{$i} = $file_or_dir; next; } elsif ($opt_force_git or $file_or_dir =~ m/$hash_regex/) { @@ -5136,7 +5301,7 @@ sub empty_tar { # {{{1 my $cmd = $ON_WINDOWS ? "type nul > $Tarfile" : "tar -cf $Tarfile -T /dev/null"; print $cmd, "\n" if $opt_v; system $cmd; - if (!-r $Tarfile) { + if (!can_read($Tarfile)) { # not readable die "Failed to create empty tarfile."; } @@ -5213,7 +5378,7 @@ sub git_archive { # {{{1 my $cmd = "git archive -o $Tarfile $files_this_commit"; print $cmd, "\n" if $opt_v; system $cmd; - if (!-r $Tarfile or !-s $Tarfile) { + if (!can_read($Tarfile) or !get_size($Tarfile)) { # not readable, or zero sized die "Failed to create tarfile of files from git."; } @@ -5234,7 +5399,7 @@ sub git_archive { # {{{1 my $extract_dir = tempdir( CLEANUP => 0 ); # 1 = delete on exit chdir "$extract_dir"; foreach my $T (@tar_files) { - next unless -f $T and -s $T; + next unless is_file($T) and get_size($T); my $cmd = "tar -x -f \"$T\""; print $cmd, "\n" if $opt_v; system $cmd; @@ -5283,6 +5448,7 @@ sub lower_on_Windows { # {{{1 # }}} sub make_file_list { # {{{1 my ($ra_arg_list, # in file and/or directory names to examine + $iteration , # in 0 if only called once, 1 or 2 if twice for diff $rh_Err , # in hash of error codes $raa_errors , # out errors encountered $rh_ignored , # out files not recognized as computer languages @@ -5292,13 +5458,22 @@ sub make_file_list { # {{{1 my $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : ","; my ($fh, $filename); if ($opt_categorized) { - $filename = $opt_categorized; - $fh = new IO::File $filename, "+>"; # open for read/write + if ($iteration) { + # am being called twice for diff of Left and Right + my $ext = $iteration == 1 ? "L" : "R"; + $filename = $opt_categorized . "-$ext"; + } else { + $filename = $opt_categorized; + } + $fh = open_file('+>', $filename, 1); # open for read/write die "Unable to write to $filename: $!\n" unless defined $fh; } elsif ($opt_sdir) { # write to the user-defined scratch directory - $filename = $opt_sdir . '/cloc_file_list.txt'; - $fh = new IO::File $filename, "+>"; # open for read/write + ++$TEMP_OFF; + my $scr_dir = "$opt_sdir/$TEMP_OFF"; + File::Path::mkpath($scr_dir) unless is_dir($scr_dir); + $filename = $scr_dir . '/cloc_file_list.txt'; + $fh = open_file('+>', $filename, 1); # open for read/write die "Unable to write to $filename: $!\n" unless defined $fh; } else { # let File::Temp create a suitable temporary file @@ -5310,16 +5485,16 @@ sub make_file_list { # {{{1 foreach my $file_or_dir (@{$ra_arg_list}) { my $size_in_bytes = 0; my $F = lower_on_Windows($file_or_dir); - my $ul_F = $upper_lower_map{$F} ? $ON_WINDOWS : $F; - if (!-r $file_or_dir) { + my $ul_F = $ON_WINDOWS ? $upper_lower_map{$F} : $F; + if (!can_read($file_or_dir)) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F]; next; } if (is_file($file_or_dir)) { - if (!(-s $file_or_dir)) { # 0 sized file, named pipe, socket + if (!get_size($file_or_dir)) { # 0 sized file, named pipe, socket $rh_ignored->{$F} = 'zero sized file'; next; - } elsif (-B $file_or_dir and !$opt_read_binary_files) { + } elsif (is_binary($file_or_dir) and !$opt_read_binary_files) { # avoid binary files unless user insists on reading them if ($opt_unicode) { # only ignore if not a Unicode file w/trivial @@ -5367,9 +5542,16 @@ sub make_file_list { # {{{1 next; } if ($opt_no_recurse) { - opendir(DIR, $dir); - push @file_list, grep(-f $_, readdir(DIR)); - closedir(DIR); + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $d = Win32::LongPath->new(); + $d->opendirL($dir); + push @file_list, grep(is_file($_), $d->readdirL()); + $d->closedirL(); + } else { + opendir(DIR, $dir); + push @file_list, grep(is_file($_), readdir(DIR)); + closedir(DIR); + } } else { find({wanted => \&files , preprocess => \&find_preprocessor, @@ -5412,7 +5594,13 @@ sub make_file_list { # {{{1 next; } - my $size_in_bytes = (stat $file)[7]; + my $size_in_bytes; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $stats = statL($file); + $size_in_bytes = $stats->{size} if defined $stats; + } else { + $size_in_bytes = (stat $file)[7]; + } my $language = ""; if ($All_One_Language) { # user over-rode auto-language detection by using @@ -5466,6 +5654,7 @@ sub invoke_generator { # {{{1 # is this file desired? my $want_this_one = 0; foreach my $file_dir (@{$ra_user_inputs}) { + $file_dir =~ s{\\}{/}g if $ON_WINDOWS; if (/^$file_dir/) { $want_this_one = 1; last; @@ -5486,20 +5675,24 @@ sub invoke_generator { # {{{1 push @post_filter, $F if $F =~ m{$opt_match_d}; next; } - if ($opt_not_match_d) { - if ($opt_fullpath and $F =~ m{$opt_not_match_d}) { - $Ignored{$F} = "--not-match-d=$opt_not_match_d"; + if (@opt_not_match_d) { + my $rule; + if ($opt_fullpath and any_match($F, 0, \$rule, @opt_not_match_d)) { + $Ignored{$F} = "--not-match-d=$rule"; next; - } elsif (basename($F) =~ m{$opt_not_match_d}) { - $Ignored{$F} = "--not-match-d (basename) =$opt_not_match_d"; + } elsif (any_match(basename($F), 0, \$rule, @opt_not_match_d)) { + $Ignored{$F} = "--not-match-d (basename) =$rule"; next; } } - if ($opt_not_match_f) { - push @post_filter, $F unless basename($F) =~ m{$opt_not_match_f}; - next; + if (@opt_not_match_f) { + my $rule; + if (any_match(basename($F), 0, \$rule, @opt_not_match_f)) { + $Ignored{$F} = "--not-match-d =$rule"; + next; + } } - my $nBytes = -s $F ; + my $nBytes = get_size($F); if (!$nBytes) { $Ignored{$F} = 'zero sized file'; printf "files(%s) zero size\n", $F if $opt_v > 5; @@ -5513,7 +5706,7 @@ sub invoke_generator { # {{{1 $F if $opt_v > 5; next; } - my $is_bin = -B $F ; + my $is_bin = is_binary($F); printf "files(%s) size=%d -B=%d\n", $F, $nBytes, $is_bin if $opt_v > 5; $is_bin = 0 if $opt_unicode and unicode_file($_); @@ -5524,6 +5717,24 @@ sub invoke_generator { # {{{1 print "<- invoke_generator\n" if $opt_v > 2; return @post_filter; } # 1}}} +sub any_match { # {{{1 + my ($string, $entire, $rs_matched_pattern, @patterns) = @_; + foreach my $pattern (@patterns) { + if ($entire) { + if ($string =~ m{^${pattern}$}) { + ${$rs_matched_pattern} = $pattern; + return 1; + } + } else { + if ($string =~ m{$pattern}) { + ${$rs_matched_pattern} = $pattern; + return 1; + } + } + } + return 0; +} +# }}} sub remove_duplicate_files { # {{{1 my ($fh , # in $rh_Language , # out @@ -5628,16 +5839,17 @@ sub manual_find_preprocessor { # {{{1 $Ignored{$File} = "--exclude-dir=$Exclude_Dir{$got_exclude_dir}"; #print "ignoring $File\n"; } else { - if ($opt_not_match_d) { + if (@opt_not_match_d) { + my $rule; if ($opt_fullpath) { - if ($Dir =~ m{^${opt_not_match_d}$}) { - $Ignored{$File} = "--not-match-d=$opt_not_match_d"; + if (any_match($Dir, 1, \$rule, @opt_not_match_d)) { + $Ignored{$File} = "--not-match-d=$rule"; #print "matched fullpath\n" } else { push @ok, $File; } - } elsif (basename($Dir) =~ m{$opt_not_match_d}) { - $Ignored{$File} = "--not-match-d=$opt_not_match_d"; + } elsif (any_match(basename($Dir), 0, \$rule, @opt_not_match_d)) { + $Ignored{$File} = "--not-match-d=$rule"; #print "matched partial\n" } else { push @ok, $File; @@ -5667,15 +5879,18 @@ sub find_preprocessor { # {{{1 $Ignored{$File::Find::name} = "--exclude-dir=$Exclude_Dir{$F_or_D}"; } else { #printf " F_or_D=%-20s File::Find::name=%s\n", $F_or_D, $File::Find::name; - if ($opt_not_match_d) { + if (@opt_not_match_d) { + my $rule; if ($opt_fullpath) { - if ($File::Find::name =~ m{$opt_not_match_d}) { - $Ignored{$File::Find::name} = "--not-match-d=$opt_not_match_d"; + if (any_match($File::Find::name, 0, \$rule, @opt_not_match_d)) { + $Ignored{$File::Find::name} = "--not-match-d=$rule"; } else { push @ok, $F_or_D; } - } elsif (!-d $F_or_D and basename($File::Find::name) =~ m{$opt_not_match_d}) { - $Ignored{$File::Find::name} = "--not-match-d (basename) =$opt_not_match_d"; + } elsif (!is_dir($F_or_D) and + any_match(basename($File::Find::name), 0, \$rule, + @opt_not_match_d)) { + $Ignored{$File::Find::name} = "--not-match-d (basename) =$rule"; } else { push @ok, $F_or_D; } @@ -5693,23 +5908,24 @@ sub files { # {{{1 # See also find_preprocessor() which prunes undesired directories. my $Dir = fastcwd(); # not $File::Find::dir which just gives relative path + my $rule; if ($opt_fullpath) { # look at as much of the path as is known if ($opt_match_f ) { return unless $File::Find::name =~ m{$opt_match_f}; } - if ($opt_not_match_f) { - return if $File::Find::name =~ m{$opt_not_match_f}; + if (@opt_not_match_f) { + return if any_match($File::Find::name, 0, \$rule, @opt_not_match_f); } } else { # only look at the basename if ($opt_match_f ) { return unless /$opt_match_f/; } - if ($opt_not_match_f) { return if /$opt_not_match_f/; } + if (@opt_not_match_f) { return if any_match($_, 0, \$rule, @opt_not_match_f)} } if ($opt_match_d ) { return unless $Dir =~ m{$opt_match_d} } - my $nBytes = -s $_ ; - if (!$nBytes and -f $File::Find::name) { + my $nBytes = get_size($_); + if (!$nBytes and is_file($File::Find::name)) { $Ignored{$File::Find::name} = 'zero sized file'; printf "files(%s) zero size\n", $File::Find::name if $opt_v > 5; } @@ -5723,7 +5939,7 @@ sub files { # {{{1 return; } my $is_dir = is_dir($_); - my $is_bin = -B $_ ; + my $is_bin = is_binary($_); printf "files(%s) size=%d is_dir=%d -B=%d\n", $File::Find::name, $nBytes, $is_dir, $is_bin if $opt_v > 5; $is_bin = 0 if $opt_unicode and unicode_file($_); @@ -5745,10 +5961,79 @@ sub archive_files { # {{{1 if $File::Find::name =~ m{$ext$}; } } # 1}}} +sub open_file { # {{{1 + # portable method to open a file. On Windows this uses Win32::LongPath to + # allow reading/writing files past the 255 char path length limit. When on + # other operating systems, $use_new_file can be used to specify opening a + # file with `new IO::File` instead of `open`. Note: `openL` doesn't support + # the C-like fopen modes ("w", "r+", etc.), it only supports Perl mode + # strings (">", "+<", etc.). So be sure to only use Perl mode strings to + # ensure compatibility. Additionally, openL doesn't handle pipe modes; if + # you need to open a pipe/STDIN/STDOUT, use the native `open` function. + my ($mode, # Perl file mode; can not be C-style file mode + $filename, # filename to open + $use_new_file, # whether to use `new IO::File` or `open` when not using Win32::LongPath + ) = @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $file = undef; + openL(\$file, $mode, $filename); + return $file; + } elsif ($use_new_file) { + return new IO::File $filename, $mode; + } + my $file = undef; + open($file, $mode, $filename); + return $file; +} # 1}}} +sub unlink_file { # {{{1 + # portable method to unlink a file. On Windows this uses Win32::LongPath to + # allow unlinking files past the 255 char path length limit. Otherwise, the + # native `unlink` will be used. + my $filename = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return unlinkL($filename); + } + return unlink $filename; +} # 1}}} +sub is_binary { # {{{1 + # portable method to test if item is a binary file. For Windows, + # Win32::LongPath doesn't provide a testL option for -B, but -B + # accepts a filehandle which does work with files opened with openL. + my $item = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + my $IN = open_file('<', $item, 0); + if (defined $IN) { + my $res = -B $IN; + close($IN); + return $res; + } + return; + } + return (-B $item); +} # 1}}} +sub can_read { # {{{1 + # portable method to test if item can be read + my $item = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return testL('r', $item); + } + return (-r $item); +} # 1}}} +sub get_size { # {{{1 + # portable method to get size in bytes of a file + my $filename = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return testL('s', $filename); + } + return (-s $filename); +} # 1}}} sub is_file { # {{{1 # portable method to test if item is a file # (-f doesn't work in ActiveState Perl on Windows) my $item = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return testL('f', $item); + } return (-f $item); # Was: @@ -5763,6 +6048,9 @@ sub is_file { # {{{1 } # 1}}} sub is_dir { # {{{1 my $item = shift @_; + if ($ON_WINDOWS and $HAVE_Win32_Long_Path) { + return testL('d', $item); + } return (-d $item); # should work everywhere now (July 2017) # Was: @@ -6038,11 +6326,11 @@ sub first_line { # {{{1 ) = @_; my $line = ""; print "-> first_line($file, $n_lines)\n" if $opt_v > 2; - if (!-r $file) { + if (!can_read($file)) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $line; } - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; print "<- first_line($file, $n_lines)\n" if $opt_v > 2; @@ -6102,7 +6390,7 @@ sub different_files { # {{{1 my %file_hash = (); # file_hash{md5 hash} = [ file1, file2, ... ] foreach my $F (@{$ra_files}) { next if is_dir($F); # needed for Windows - my $IN = new IO::File $F, "r"; + my $IN = open_file('<', $F, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F]; $rh_ignored->{$F} = 'cannot read'; @@ -6169,11 +6457,11 @@ sub call_counter { # {{{1 my @lines = (); my $ascii = ""; - if (-B $file and $opt_unicode) { + if (is_binary($file) and $opt_unicode) { # was binary so must be unicode $/ = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); my $bin_text = <$IN>; $IN->close; $/ = "\n"; @@ -6301,12 +6589,12 @@ sub write_file { # {{{1 mkpath($volume . $directories, 1, 0777); my $OUT = undef; - unlink $file; + unlink_file($file); if ($opt_file_encoding) { # $OUT = IO::File->new($file, ">:$opt_file_encoding"); # doesn't work? - open($OUT, "> :encoding($opt_file_encoding)", $file); + $OUT = open_file(">:encoding($opt_file_encoding)", $file, 0); } else { - $OUT = new IO::File $file, "w"; + $OUT = open_file('>', $file, 1); } my $n_col = undef; @@ -6379,7 +6667,7 @@ sub write_file { # {{{1 } $OUT->close; - if (-r $file) { + if (can_read($file)) { print "Wrote $file" unless $opt_quiet; print ", $CLOC_XSL" if $opt_xsl and $opt_xsl eq $CLOC_XSL; print "\n" unless $opt_quiet; @@ -6470,7 +6758,7 @@ sub read_file { # {{{1 ); my @lines = (); - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (defined $IN) { @lines = <$IN>; $IN->close; @@ -7256,7 +7544,7 @@ sub really_is_bf { # {{{1 $decision, $file, $ratio, $n_bf_indicators if $opt_v > 2; return $decision; } # 1}}} -sub remove_intented_block { # {{{1 +sub remove_indented_block { # {{{1 # Haml block comments are defined by a silent comment marker like # / # or @@ -7265,7 +7553,7 @@ sub remove_intented_block { # {{{1 # http://haml.info/docs/yardoc/file.REFERENCE.html#comments my ($ra_lines, $regex, ) = @_; - print "-> remove_intented_block\n" if $opt_v > 2; + print "-> remove_indented_block\n" if $opt_v > 2; my @save_lines = (); my $in_comment = 0; @@ -7296,7 +7584,7 @@ sub remove_intented_block { # {{{1 push @save_lines, $line; } - print "<- remove_intented_block\n" if $opt_v > 2; + print "<- remove_indented_block\n" if $opt_v > 2; return @save_lines; } # 1}}} sub remove_haml_block { # {{{1 @@ -7308,7 +7596,7 @@ sub remove_haml_block { # {{{1 # http://haml.info/docs/yardoc/file.REFERENCE.html#comments my ($ra_lines, ) = @_; - return remove_intented_block($ra_lines, '^(\s*)(/|-#)\s*$'); + return remove_indented_block($ra_lines, '^(\s*)(/|-#)\s*$'); } # 1}}} sub remove_pug_block { # {{{1 @@ -7317,7 +7605,7 @@ sub remove_pug_block { # {{{1 # followed by indented text on subsequent lines. # http://jade-lang.com/reference/comments/ my ($ra_lines, ) = @_; - return remove_intented_block($ra_lines, '^(\s*)(//)\s*$'); + return remove_indented_block($ra_lines, '^(\s*)(//)\s*$'); } # 1}}} sub remove_OCaml_comments { # {{{1 my ($ra_lines, ) = @_; @@ -7352,7 +7640,7 @@ sub remove_slim_block { # {{{1 # followed by indented text on subsequent lines. # http://www.rubydoc.info/gems/slim/frames my ($ra_lines, ) = @_; - return remove_intented_block($ra_lines, '^(\s*)(/[^!])'); + return remove_indented_block($ra_lines, '^(\s*)(/[^!])'); } # 1}}} sub add_newlines { # {{{1 my ($ra_lines, ) = @_; @@ -7517,10 +7805,10 @@ sub smarty_to_C { # {{{1 sub determine_lit_type { # {{{1 my ($file) = @_; - open (FILE, $file); - while () { - if (m/^\\begin\{code\}/) { close FILE; return 2; } - if (m/^>\s/) { close FILE; return 1; } + my $FILE = open_file('<', $file, 0); + while (<$FILE>) { + if (m/^\\begin\{code\}/) { close $FILE; return 2; } + if (m/^>\s/) { close $FILE; return 1; } } return 0; @@ -7669,6 +7957,7 @@ sub set_constants { # {{{1 'aspx' => 'ASP.NET' , 'master' => 'ASP.NET' , 'sitemap' => 'ASP.NET' , + 'asy' => 'Asymptote' , 'cshtml' => 'Razor' , 'razor' => 'Razor' , # Client-side Blazor 'nawk' => 'awk' , @@ -7740,6 +8029,9 @@ sub set_constants { # {{{1 '_coffee' => 'CoffeeScript' , 'coffee' => 'CoffeeScript' , 'component' => 'Visualforce Component' , + 'cg3' => 'Constraint Grammar' , + 'rlx' => 'Constraint Grammar' , + 'Containerfile' => 'Containerfile' , 'cpp' => 'C++' , 'CPP' => 'C++' , 'cr' => 'Crystal' , @@ -7900,6 +8192,7 @@ sub set_constants { # {{{1 'haml' => 'Haml' , 'handlebars' => 'Handlebars' , 'hbs' => 'Handlebars' , + 'ha' => 'Hare' , 'hxsl' => 'Haxe' , 'hx' => 'Haxe' , 'HC' => 'HolyC' , @@ -7937,6 +8230,7 @@ sub set_constants { # {{{1 'java' => 'Java' , 'jcl' => 'JCL' , # IBM Job Control Lang. 'jl' => 'Lisp/Julia' , + 'jai' => 'Jai' , 'xsjslib' => 'JavaScript' , 'xsjs' => 'JavaScript' , 'ssjs' => 'JavaScript' , @@ -7998,6 +8292,7 @@ sub set_constants { # {{{1 'lhs' => 'Haskell' , 'lex' => 'lex' , 'l' => 'lex' , + 'ld' => 'Linker Script' , 'lem' => 'Lem' , 'less' => 'LESS' , 'lfe' => 'LFE' , @@ -8068,6 +8363,8 @@ sub set_constants { # {{{1 'mps' => 'MUMPS' , 'mth' => 'Teamcenter mth' , 'n' => 'Nemerle' , + 'nlogo' => 'NetLogo' , + 'nls' => 'NetLogo' , 'nims' => 'Nim' , 'nimrod' => 'Nim' , 'nimble' => 'Nim' , @@ -8122,6 +8419,7 @@ sub set_constants { # {{{1 'rakumod' => 'Raku' , 'pom.xml' => 'Maven' , 'pom' => 'Maven' , + 'scad' => 'OpenSCAD' , 'yap' => 'Prolog' , 'prolog' => 'Prolog' , 'P' => 'Prolog' , @@ -8222,11 +8520,13 @@ sub set_constants { # {{{1 'sed' => 'sed' , 'sp' => 'SparForte' , 'sol' => 'Solidity' , + 'p4' => 'P4' , 'ses' => 'Patran Command Language' , 'pcl' => 'Patran Command Language' , 'peg' => 'PEG' , 'pegjs' => 'peg.js' , 'peggy' => 'peggy' , + 'pest' => 'Pest' , 'tspeg' => 'tspeg' , 'jspeg' => 'tspeg' , 'pl1' => 'PL/I' , @@ -8235,6 +8535,7 @@ sub set_constants { # {{{1 'puml' => 'PlantUML' , 'properties' => 'Properties' , 'po' => 'PO File' , + 'pony' => 'Pony' , 'pbt' => 'PowerBuilder' , 'sra' => 'PowerBuilder' , 'srf' => 'PowerBuilder' , @@ -8606,10 +8907,12 @@ sub set_constants { # {{{1 'dockerfile' => 'Dockerfile' , 'dockerfile.m4' => 'Dockerfile' , 'dockerfile.cmake' => 'Dockerfile' , + 'Containerfile' => 'Containerfile' , ); # 1}}} %{$rh_Language_by_Prefix} = ( # {{{1 'Dockerfile' => 'Dockerfile' , + 'Containerfile' => 'Containerfile' , ); # 1}}} %{$rhaa_Filters_by_Language} = ( # {{{1 @@ -8689,6 +8992,11 @@ sub set_constants { # {{{1 [ 'remove_inline' , '--.*$' ], [ 'remove_matches' , '^\*' ], # z/OS Assembly ], + 'Asymptote' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'call_regexp_common' , 'C++' ], + ], 'AutoHotkey' => [ [ 'remove_matches' , '^\s*;' ], [ 'remove_inline' , ';.*$' ], @@ -8772,6 +9080,10 @@ sub set_constants { # {{{1 [ 'remove_matches' , '^\s*#' ], [ 'remove_inline' , '#.*$' ], ], + 'Constraint Grammar' => [ + [ 'remove_matches' , '^\s*#' ], + [ 'remove_inline' , '#.*$' ], + ], 'CUDA' => [ [ 'rm_comments_in_strings', '"', '/*', '*/' ], [ 'rm_comments_in_strings', '"', '//', '' ], @@ -8834,6 +9146,10 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'Containerfile' => [ + [ 'remove_matches' , '^\s*#' ], + [ 'remove_inline' , '#.*$' ], + ], 'Coq' => [ [ 'remove_between_general', '(*', '*)' ], ], @@ -9095,6 +9411,12 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', "'''", '//', '', 1], [ 'call_regexp_common' , 'C++' ], ], + 'Haml' => [ + [ 'remove_haml_block' , ], + [ 'remove_html_comments', ], + [ 'remove_matches' , '^\s*/\s*\S+' ], + [ 'remove_matches' , '^\s*-#\s*\S+' ], + ], 'Handlebars' => [ [ 'remove_between_general', '{{!--', '--}}' ], [ 'remove_between_general', '{{!', '}}' ], @@ -9112,11 +9434,9 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], - 'Haml' => [ - [ 'remove_haml_block' , ], - [ 'remove_html_comments', ], - [ 'remove_matches' , '^\s*/\s*\S+' ], - [ 'remove_matches' , '^\s*-#\s*\S+' ], + 'Hare' => [ + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'remove_matches' , '//.*$' ], ], 'Haxe' => [ [ 'rm_comments_in_strings', '"', '/*', '*/' ], @@ -9187,6 +9507,11 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'Jai' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'call_regexp_common' , 'C++' ], + ], 'Jam' => [ [ 'remove_matches' , '^\s*#' ], [ 'remove_inline' , '#.*$' ], @@ -9285,6 +9610,10 @@ sub set_constants { # {{{1 [ 'remove_matches' , '^\s*;' ], [ 'remove_between_general', '#|', '|#' ], ], + 'Linker Script' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/'], + [ 'call_regexp_common', 'C' ], + ], 'liquid' => [ [ 'remove_between_general', '{% comment %}', '{% endcomment %}' ], @@ -9378,6 +9707,7 @@ sub set_constants { # {{{1 [ 'call_regexp_common' , 'C++' ], ], 'OCaml' => [ + [ 'rm_comments_in_strings', '"', '(*', '*)', 1 ], [ 'remove_OCaml_comments', ], ], 'OpenCL' => [ @@ -9390,6 +9720,7 @@ sub set_constants { # {{{1 [ 'remove_matches' , '##.*$' ], ], 'Markdown' => [ + [ 'remove_between_general', '' ], [ 'remove_between_regex', '\[(comment|\/\/)?\]\s*:?\s*(<\s*>|#)?\s*\(.*?', '.*?\)' ], # http://stackoverflow.com/questions/4823468/comments-in-markdown @@ -9406,6 +9737,10 @@ sub set_constants { # {{{1 # [ 'call_regexp_common' , 'C' ], [ 'remove_inline' , '#.*$' ], ], + 'NetLogo' => [ + [ 'remove_matches' , '^\s*;' ], + [ 'remove_inline' , ';.*$' ], + ], 'Nix' => [ [ 'call_regexp_common' , 'C' ], [ 'remove_matches' , '^\s*#' ], @@ -9420,6 +9755,11 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'OpenSCAD' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'call_regexp_common' , 'C++' ], + ], 'Oracle Forms' => [ [ 'call_regexp_common' , 'C' ], ], 'Oracle Reports' => [ [ 'call_regexp_common' , 'C' ], ], 'Oracle PL/SQL' => [ @@ -9440,6 +9780,11 @@ sub set_constants { # {{{1 [ 'call_regexp_common' , 'C' ], [ 'remove_inline' , '#.*$' ], ], + 'P4' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'call_regexp_common' , 'C++' ], + ], 'Patran Command Language'=> [ [ 'remove_matches' , '^\s*#' ], [ 'remove_matches' , '^\s*\$#' ], @@ -9465,6 +9810,10 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'Pest' => [ + [ 'remove_matches' , '^\s*//' ], + [ 'remove_inline' , '//.*$' ], + ], 'tspeg' => [ [ 'rm_comments_in_strings', '"', '/*', '*/' ], [ 'rm_comments_in_strings', '"', '//', '' ], @@ -9493,6 +9842,12 @@ sub set_constants { # {{{1 'PO File' => [ [ 'remove_matches' , '^\s*#[^,]' ], # '#,' is not a comment ], + 'Pony' => [ + [ 'rm_comments_in_strings', '"', '/*', '*/' ], + [ 'rm_comments_in_strings', '"', '//', '' ], + [ 'docstring_to_C' ], + [ 'call_regexp_common' , 'C++' ], + ], 'PowerBuilder' => [ [ 'rm_comments_in_strings', '"', '/*', '*/' ], [ 'rm_comments_in_strings', '"', '//', '' ], @@ -10319,6 +10674,7 @@ sub set_constants { # {{{1 'Assembly' => 0.25, 'Assembly (macro)' => 0.51, 'associative default' => 1.25, + 'Asymptote' => 2.50, 'autocoder' => 0.25, 'AutoHotkey' => 1.29, 'awk' => 3.81, @@ -10352,9 +10708,8 @@ sub set_constants { # {{{1 'COBOL ii' => 0.75, 'COBOL/400' => 0.88, 'CoffeeScript' => 2.00, - 'common lisp' => 1.25, - 'concurrent pascal' => 1.00, - 'conniver' => 1.25, + 'Constraint Grammar' => 4.00, + 'Containerfile' => 2.00, 'Coq' => 5.00, 'Crystal' => 2.50, 'Crystal Reports' => 4.00, @@ -10370,7 +10725,6 @@ sub set_constants { # {{{1 'DAL' => 1.50, 'Dart' => 2.00, 'DenizenScript' => 1.00, - 'data base default' => 2.00, 'Delphi Form' => 2.00, 'DIET' => 2.00, 'diff' => 1.00, @@ -10394,7 +10748,6 @@ sub set_constants { # {{{1 'ERB' => 2.00, 'Erlang' => 2.11, 'Fennel' => 2.50, - 'filemaker pro' => 2.22, 'Finite State Language' => 2.00, 'Focus' => 1.90, 'Forth' => 1.25, @@ -10413,7 +10766,6 @@ sub set_constants { # {{{1 'Gleam' => 2.50, 'GLSL' => 2.00, 'gml' => 1.74, - 'golden common lisp' => 1.25, 'gpss' => 1.74, 'guest' => 2.86, 'guru' => 1.63, @@ -10427,14 +10779,15 @@ sub set_constants { # {{{1 'GraphQL' => 4.00, 'Groovy' => 4.10, 'gw basic' => 0.82, - 'Harbour' => 2.00, - 'Haskell' => 2.11, 'HCL' => 2.50, 'high c' => 0.63, 'hlevel' => 1.38, 'hp basic' => 0.63, 'Haml' => 2.50, 'Handlebars' => 2.50, + 'Harbour' => 2.00, + 'Hare' => 2.50, + 'Haskell' => 2.11, 'Haxe' => 2.00, 'HolyC' => 2.50, 'Hoon' => 2.00, @@ -10453,41 +10806,15 @@ sub set_constants { # {{{1 'Visual Studio Module' => 1.00, 'Visual Studio Solution' => 1.00, 'HLSL' => 2.00, - 'HTML 2' => 5.00, - 'HTML 3' => 5.33, - 'huron' => 5.00, - 'ibm adf i' => 4.00, - 'ibm adf ii' => 4.44, - 'ibm advanced basic' => 0.82, - 'ibm compiled basic' => 0.88, - 'ibm vs cobol' => 0.75, - 'ibm vs cobol ii' => 0.88, - 'ices' => 1.13, - 'icon' => 1.00, - 'ideal' => 1.54, - 'idms' => 2.00, 'Idris' => 2.00, 'Literate Idris' => 2.00, 'Igor Pro' => 4.00, 'Imba' => 3.00, - 'imprs' => 2.00, - 'informix' => 2.58, - 'ingres' => 2.00, 'INI' => 1.00, - 'inquire' => 6.15, - 'insight2' => 1.63, - 'install/1' => 5.00, 'InstallShield' => 1.90, - 'intellect' => 1.51, - 'interlisp' => 1.38, - 'interpreted basic' => 0.75, - 'interpreted c' => 0.63, 'IPL' => 2.00, - 'iqlisp' => 1.38, - 'iqrp' => 6.15, - 'j2ee' => 1.60, + 'Jai' => 1.13, 'Jam' => 2.00, - 'janus' => 1.13, 'Java' => 1.36, 'JavaScript' => 1.48, 'JavaServer Faces' => 1.5 , @@ -10498,125 +10825,55 @@ sub set_constants { # {{{1 'JSX' => 1.48, 'Velocity Template Language' => 1.00, 'JCL' => 1.67, - 'joss' => 0.75, - 'jovial' => 0.75, - 'jsp' => 1.36, 'Juniper Junos' => 2.00, - 'kappa' => 2.00, - 'kbms' => 1.63, - 'kcl' => 1.25, - 'kee' => 1.63, - 'keyplus' => 2.00, - 'kl' => 1.25, - 'klo' => 1.25, - 'knowol' => 1.63, - 'krl' => 1.38, 'kvlang' => 2.00, 'Kermit' => 2.00, 'Korn Shell' => 3.81, 'Kotlin' => 2.00, - 'ladder logic' => 2.22, - 'lambit/l' => 1.25, - 'lattice c' => 0.63, 'Lean' => 3.00, 'LESS' => 1.50, 'Lem' => 3.00, 'LFE' => 1.25, - 'liana' => 0.63, - 'lilith' => 1.13, - 'linc ii' => 5.71, + 'Linker Script' => 1.00, 'liquid' => 3.00, 'Lisp' => 1.25, 'LiveLink OScript' => 3.5 , 'LLVM IR' => 0.90, - 'loglisp' => 1.38, 'Logos' => 2.00, 'Logtalk' => 2.00, - 'loops' => 3.81, - 'lotus 123 dos' => 13.33, - 'lotus macros' => 0.75, - 'lotus notes' => 3.64, - 'lucid 3d' => 13.33, - 'lyric' => 1.51, 'm4' => 1.00, - 'm' => 5.00, - 'macforth' => 1.25, - 'mach1' => 2.00, - 'machine language' => 0.13, - 'maestro' => 5.00, - 'magec' => 5.00, - 'magik' => 3.81, - 'Lake' => 3.81, 'make' => 2.50, - 'Mako' => 1.50, # Not sure about the scaling. - 'mantis' => 2.96, - 'mapper' => 0.99, - 'mark iv' => 2.00, - 'mark v' => 2.22, + 'Mako' => 1.50, 'Markdown' => 1.00, 'mathcad' => 16.00, 'Maven' => 1.90, - 'mdl' => 2.22, - 'mentor' => 1.51, - 'mesa' => 0.75, 'Meson' => 1.00, 'Metal' => 1.51, - 'microfocus cobol' => 1.00, - 'microforth' => 1.25, - 'microsoft c' => 0.63, - 'microstep' => 4.00, - 'miranda' => 2.00, - 'model 204' => 2.11, - 'modula 2' => 1.00, - 'mosaic' => 13.33, - # 'ms c ++ v. 7' => 1.51, - 'ms compiled basic' => 0.88, - 'msl' => 1.25, - 'mulisp' => 1.25, 'MUMPS' => 4.21, 'Mustache' => 1.75, 'Nastran' => 1.13, - 'natural' => 1.54, - 'natural 1' => 1.51, - 'natural 2' => 1.74, - 'natural construct' => 3.20, - 'natural language' => 0.03, 'Nemerle' => 2.50, - 'netron/cap' => 4.21, - 'nexpert' => 1.63, - 'nial' => 1.63, + 'NetLogo' => 4.00, 'Nim' => 2.00, 'Nix' => 2.70, 'Nunjucks' => 1.5 , - 'object assembler' => 1.25, - 'object lisp' => 2.76, - 'object logo' => 2.76, - 'object pascal' => 2.76, - 'object star' => 5.00, 'Objective-C' => 2.96, 'Objective-C++' => 2.96, 'OCaml' => 3.00, 'Odin' => 2.00, - 'ogl' => 1.00, - 'omnis 7' => 2.00, - 'oodl' => 2.76, - 'ops' => 1.74, - 'ops5' => 1.38, - 'oracle' => 2.76, + 'OpenSCAD' => 1.00, 'Oracle Reports' => 2.76, 'Oracle Forms' => 2.67, 'Oracle Developer/2000' => 3.48, - 'oscar' => 0.75, 'Other' => 1.00, - 'pacbase' => 1.67, - 'pace' => 2.00, - 'paradox/pal' => 2.22, + 'P4' => 1.5 , 'Pascal' => 0.88, 'Patran Command Language' => 2.50, 'Perl' => 4.00, 'PEG' => 3.00, 'peg.js' => 3.00, 'peggy' => 3.00, + 'Pest' => 2.00, 'tspeg' => 3.00, 'Pig Latin' => 1.00, 'PL/I' => 1.38, @@ -10624,6 +10881,7 @@ sub set_constants { # {{{1 'PlantUML' => 2.00, 'Oracle PL/SQL' => 2.58, 'PO File' => 1.50, + 'Pony' => 3.00, 'PowerBuilder' => 3.33, 'PowerShell' => 3.00, 'problemoriented default' => 1.13, @@ -10683,13 +10941,10 @@ sub set_constants { # {{{1 'Specman e' => 2.00, 'SQL' => 2.29, 'Squirrel' => 2.50, - 'statistical default' => 2.50, 'Standard ML' => 3.00, 'Stata' => 3.00, 'Stylus' => 1.48, 'SugarSS' => 2.50, - 'superbase 1.3' => 2.22, - 'surpass' => 13.33, 'Svelte' => 2.00, 'SVG' => 1.00, 'Swift' => 2.50, @@ -10717,23 +10972,14 @@ sub set_constants { # {{{1 'Verilog-SystemVerilog' => 1.51, 'VHDL' => 4.21, 'vim script' => 3.00, - 'visual basic' => 1.90, 'Visual Basic' => 2.76, 'VB for Applications' => 2.76, 'Visual Basic .NET' => 2.76, 'Visual Basic Script' => 2.76, - 'visual c++' => 2.35, - 'visual cobol' => 4.00, 'Visual Fox Pro' => 4.00, # Visual Fox Pro is not available in the language gearing ratios listed at Mayes Consulting web site - 'visual objects' => 5.00, - 'visualage' => 3.81, 'Visualforce Component' => 1.9 , 'Visualforce Page' => 1.9 , - 'visualgen' => 4.44, - 'VM' => 2.00, 'Vuejs Component' => 2.00, - 'vulcan' => 1.25, - 'web scripts' => 5.33, 'Web Services Description' => 1.00, 'WebAssembly' => 0.45, 'WGSL' => 2.50, @@ -10743,7 +10989,6 @@ sub set_constants { # {{{1 'WiX source' => 1.90, 'WiX include' => 1.90, 'WiX string localization' => 1.90, - 'wizard' => 2.86, 'WXML' => 1.90, 'WXSS' => 1.00, 'xBase' => 2.00, @@ -10755,9 +11000,6 @@ sub set_constants { # {{{1 'yacc' => 1.51, 'yacc++' => 1.51, 'YAML' => 0.90, - 'zbasic' => 0.88, - 'zim' => 4.21, - 'zlisp' => 1.25, 'Expect' => 2.00, 'Gencat NLS' => 1.50, 'C/C++ Header' => 1.00, @@ -10945,7 +11187,7 @@ sub matlab_or_objective_C { # {{{1 # BeginPackage ${$rs_language} = ""; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return; @@ -10990,7 +11232,7 @@ printf ".m: ; obj C=% 2d matlab=% 2d mumps=% 2d mercury= % 2d\n", $obje # Objective-C without a doubt $objective_C_points = 1000; $matlab_points = 0; -printf ".m: #includ obj C=% 2d matlab=% 2d mumps=% 2d mercury= % 2d\n", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG; +printf ".m: #include obj C=% 2d matlab=% 2d mumps=% 2d mercury= % 2d\n", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG; $has_braces = 2; last; } elsif (m{^\s*@(interface|implementation|protocol|public|protected|private|end)\s}o) { @@ -11045,7 +11287,7 @@ sub Lisp_or_OpenCL { # {{{1 print "-> Lisp_or_OpenCL\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11077,7 +11319,7 @@ sub Lisp_or_Julia { # {{{1 print "-> Lisp_or_Julia\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11109,7 +11351,7 @@ sub Perl_or_Prolog { # {{{1 print "-> Perl_or_Prolog\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11166,7 +11408,7 @@ sub IDL_or_QtProject { # {{{1 print "-> IDL_or_QtProject($file)\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11212,7 +11454,7 @@ sub Ant_or_XML { # {{{1 print "-> Ant_or_XML($file)\n" if $opt_v > 2; my $lang = "XML"; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11250,7 +11492,7 @@ sub Maven_or_XML { # {{{1 print "-> Maven_or_XML($file)\n" if $opt_v > 2; my $lang = "XML"; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11290,7 +11532,7 @@ sub pascal_or_puppet { # {{{1 print "-> pascal_or_puppet\n" if $opt_v > 2; ${$rs_language} = ""; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return; @@ -11358,7 +11600,7 @@ sub Forth_or_Fortran { # {{{1 print "-> Forth_or_Fortran\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11388,7 +11630,7 @@ sub Forth_or_Fsharp { # {{{1 print "-> Forth_or_Fsharp\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11418,7 +11660,7 @@ sub Verilog_or_Coq { # {{{1 print "-> Verilog_or_Coq\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11453,7 +11695,7 @@ sub TypeScript_or_QtLinguist { # {{{1 print "-> TypeScript_or_QtLinguist\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11484,7 +11726,7 @@ sub Qt_or_Glade { # {{{1 print "-> Qt_or_Glade\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11516,7 +11758,7 @@ sub Csharp_or_Smalltalk { # {{{1 print "-> Csharp_or_Smalltalk($file)\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11559,7 +11801,7 @@ sub Visual_Basic_or_TeX_or_Apex { # {{{1 print "-> Visual_Basic_or_TeX_or_Apex($file)\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11608,7 +11850,7 @@ sub Scheme_or_SaltStack { # {{{1 print "-> Scheme_or_SaltStack($file)\n" if $opt_v > 2; my $lang = undef; - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file]; return $lang; @@ -11695,12 +11937,12 @@ sub test_alg_diff { # {{{1 my ($file_1 , $file_2 ) = @_; - my $fh_1 = new IO::File $file_1, "r"; + my $fh_1 = open_file('<', $file_1, 1); die "Unable to read $file_1: $!\n" unless defined $fh_1; chomp(my @lines_1 = <$fh_1>); $fh_1->close; - my $fh_2 = new IO::File $file_2, "r"; + my $fh_2 = open_file('<', $file_2, 1); die "Unable to read $file_2: $!\n" unless defined $fh_2; chomp(my @lines_2 = <$fh_2>); $fh_2->close; @@ -12233,10 +12475,9 @@ sub get_leading_dirs { # {{{1 ########++$candidate_leading_dir_R{$leading_dir_R}; } #use Data::Dumper::Simple; - if ($ON_WINDOWS) { - $L_drop =~ s{\\}{/}g; - $R_drop =~ s{\\}{/}g; - } + # at this point path separator on Windows is already / + $L_drop =~ s{//}{/}g; + $R_drop =~ s{//}{/}g; #print "L_drop=$L_drop\n"; #print "R_drop=$R_drop\n"; return $L_drop, $R_drop, 1; @@ -12426,10 +12667,10 @@ sub unicode_file { # {{{1 my $file = shift @_; print "-> unicode_file($file)\n" if $opt_v > 2; - return 0 if (-s $file > 2_000_000); + return 0 if (get_size($file) > 2_000_000); # don't bother trying to test binary files bigger than 2 MB - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { warn "Unable to read $file; ignoring.\n"; return 0; @@ -13130,7 +13371,7 @@ sub combine_diffs { # {{{1 my %HoH = (); foreach my $file (@{$ra_files}) { - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { warn "Unable to read $file; ignoring.\n"; next; @@ -13208,7 +13449,7 @@ sub combine_csv_diffs { # {{{1 my %sum = (); # sum{ language } = array of 17 values foreach my $file (@{$ra_files}) { - my $IN = new IO::File $file, "r"; + my $IN = open_file('<', $file, 1); if (!defined $IN) { warn "Unable to read $file; ignoring.\n"; next; @@ -13347,6 +13588,7 @@ sub load_from_config_file { # {{{1 $rs_counted , $rs_include_ext , $rs_include_lang , + $rs_include_content , $rs_exclude_content , $rs_exclude_lang , $rs_exclude_dir , @@ -13355,6 +13597,7 @@ sub load_from_config_file { # {{{1 $rs_extract_with , $rs_found , $rs_count_diff , + $rs_diff_list_files , $rs_diff , $rs_diff_alignment , $rs_diff_timeout , @@ -13395,9 +13638,9 @@ sub load_from_config_file { # {{{1 $rs_md , $rs_fullpath , $rs_match_f , - $rs_not_match_f , + $ra_not_match_f , $rs_match_d , - $rs_not_match_d , + $ra_not_match_d , $rs_list_file , $rs_help , $rs_skip_win_hidden , @@ -13434,10 +13677,10 @@ sub load_from_config_file { # {{{1 # $ENV{'APPDATA'} . 'cloc' print "-> load_from_config_file($config_file)\n" if $opt_v and $opt_v > 2; - if (!-f $config_file) { + if (!is_file($config_file)) { print "<- load_from_config_file() (no such file: $config_file)\n" if $opt_v and $opt_v > 2; return; - } elsif (!-r $config_file) { + } elsif (!can_read($config_file)) { print "<- load_from_config_file() (unable to read $config_file)\n" if $opt_v and $opt_v > 2; return; } @@ -13456,6 +13699,7 @@ sub load_from_config_file { # {{{1 } elsif (!defined ${$rs_counted} and /^counted(=|\s+)(.*?)$/) { ${$rs_counted} = $2; } elsif (!defined ${$rs_include_ext} and /^(?:include_ext|include-ext)(=|\s+)(.*?)$/) { ${$rs_include_ext} = $2; } elsif (!defined ${$rs_include_lang} and /^(?:include_lang|include-lang)(=|\s+)(.*?)$/) { ${$rs_include_lang} = $2; + } elsif (!defined ${$rs_include_content} and /^(?:include_content|include-content)(=|\s+)(.*?)$/) { ${$rs_include_content} = $2; } elsif (!defined ${$rs_exclude_content} and /^(?:exclude_content|exclude-content)(=|\s+)(.*?)$/) { ${$rs_exclude_content} = $2; } elsif (!defined ${$rs_exclude_lang} and /^(?:exclude_lang|exclude-lang)(=|\s+)(.*?)$/) { ${$rs_exclude_lang} = $2; } elsif (!defined ${$rs_exclude_dir} and /^(?:exclude_dir|exclude-dir)(=|\s+)(.*?)$/) { ${$rs_exclude_dir} = $2; @@ -13463,6 +13707,7 @@ sub load_from_config_file { # {{{1 } elsif (!defined ${$rs_extract_with} and /^(?:extract_with|extract-with)(=|\s+)(.*?)$/) { ${$rs_extract_with} = $2; } elsif (!defined ${$rs_found} and /^found(=|\s+)(.*?)$/) { ${$rs_found} = $2; } elsif (!defined ${$rs_count_diff} and /^(count_and_diff|count-and-diff)/) { ${$rs_count_diff} = 1; + } elsif (!defined ${$rs_diff_list_files} and /^(diff_list_files|diff-list-files)/) { ${$rs_diff_list_files} = 1; } elsif (!defined ${$rs_diff} and /^diff/) { ${$rs_diff} = 1; } elsif (!defined ${$rs_diff_alignment} and /^(?:diff-alignment|diff_alignment)(=|\s+)(.*?)$/) { ${$rs_diff_alignment} = $2; } elsif (!defined ${$rs_diff_timeout} and /^(?:diff-timeout|diff_timeout)(=|\s+)i/) { ${$rs_diff_timeout} = $1; @@ -13499,9 +13744,9 @@ sub load_from_config_file { # {{{1 } elsif (!defined ${$rs_md} and /^md/) { ${$rs_md} = 1; } elsif (!defined ${$rs_fullpath} and /^fullpath/) { ${$rs_fullpath} = 1; } elsif (!defined ${$rs_match_f} and /^(?:match_f|match-f)(=|\s+)(.*?)$/) { ${$rs_match_f} = $2; - } elsif (!defined ${$rs_not_match_f} and /^(?:not_match_f|not-match-f)(=|\s+)(.*?)$/) { ${$rs_not_match_f} = $2; + } elsif (! @{$ra_not_match_f} and /^(?:not_match_f|not-match-f)(=|\s+)(.*?)$/) { push @{$ra_not_match_f} , $2; } elsif (!defined ${$rs_match_d} and /^(?:match_d|match-d)(=|\s+)(.*?)$/) { ${$rs_match_d} = $2; - } elsif (!defined ${$rs_not_match_d} and /^(?:not_match_d|not-match-d)(=|\s+)(.*?)$/) { ${$rs_not_match_d} = $2; + } elsif (! @{$ra_not_match_d} and /^(?:not_match_d|not-match-d)(=|\s+)(.*?)$/) { push @{$ra_not_match_d} , $2; } elsif (!defined ${$rs_list_file} and /^(?:list_file|list-file)(=|\s+)(.*?)$/) { ${$rs_list_file} = $2; } elsif (!defined ${$rs_help} and /^help/) { ${$rs_help} = 1; } elsif (!defined ${$rs_skip_win_hidden} and /^(skip_win_hidden|skip-win-hidden)/) { ${$rs_skip_win_hidden} = 1; @@ -13530,7 +13775,7 @@ sub load_from_config_file { # {{{1 } elsif (!defined ${$rs_force_git} and /^git/) { ${$rs_force_git} = 1; } elsif (!defined ${$rs_exclude_list_file} and /^(?:exclude_list_file|exclude-list-file)(=|\s+)(.*?)$/) { ${$rs_exclude_list_file} = $2; - } elsif (!defined ${$rs_v} and /(verbose|v)((=|\s+)(\d+))?/) { + } elsif (!defined ${$rs_v} and /^(verbose|v)((=|\s+)(\d+))?/) { if (!defined $4) { ${$rs_v} = 0; } else { ${$rs_v} = $4; } } elsif (!$has_script_lang and /^(?:script_lang|script-lang)(=|\s+)(.*?)$/) { @@ -13592,9 +13837,9 @@ sub check_alternate_config_files { # {{{1 $diff_list_file ) { next unless defined $file; my $dir = dirname $file; - next unless -r $dir and -d $dir; + next unless can_read($dir) and is_dir($dir); my $bn = basename $config_file; - if (-r "$dir/$bn") { + if (can_read("$dir/$bn")) { $found_it = "$dir/$bn"; print "Using configuration file $found_it\n" if $opt_v; last; @@ -13603,6 +13848,40 @@ sub check_alternate_config_files { # {{{1 return $found_it; } # 1}}} +sub write_null_results { # {{{ + my ($json, $xml, $report_file,) = @_; + print "-> write_null_results\n" if $opt_v > 2; + if ((defined $json) or (defined $xml)) { + my $line = ""; + if (defined $json) { + $line = "{}"; + } else { + $line = ''; + } + if (defined $report_file) { + open OUT, ">$report_file" or die "Cannot write to $report_file $!\n"; + print OUT "$line\n"; + close OUT; + } else { + print "$line\n"; + } + } + print "<- write_null_results\n" if $opt_v > 2; +} # }}} +sub glob2regex { # {{{ + # convert simple xpath-style glob pattern to a regex + my $globstr = shift; + my $re = $globstr; + $re =~ s{^["']}{}; + $re =~ s{^\.\/}{}; + $re =~ s{["']$}{}; + $re =~ s{\.}{\\.}g; + $re =~ s{\*\*}{\cx}g; # ctrl x = .*? + $re =~ s{\*}{\cy}g; # ctrl y = [^/]* + $re =~ s{\cx}{.*?}g; + $re =~ s{\cy}{[^/]*}g; + return '^' . $re . '$'; +} # }}} # really_is_pascal, really_is_incpascal, really_is_php from SLOCCount my %php_files = (); # really_is_php() sub really_is_pascal { # {{{1 @@ -13667,9 +13946,9 @@ sub really_is_pascal { # {{{1 my $found_terminating_end = 0; my $has_begin = 0; - open(PASCAL_FILE, "<$filename") || - die "Can't open $filename to determine if it's pascal.\n"; - while() { + my $PASCAL_FILE = open_file('<', $filename, 0); + die "Can't open $filename to determine if it's pascal.\n" if !defined $PASCAL_FILE; + while(<$PASCAL_FILE>) { s/\{.*?\}//g; # Ignore {...} comments on this line; imperfect, but effective. s/\(\*.*?\*\)//g; # Ignore (*...*) comments on this line; imperfect, but effective. if (m/\bprogram\s+[A-Za-z]/i) {$has_program=1;} @@ -13690,7 +13969,7 @@ sub really_is_pascal { # {{{1 if (m/end\.\s*$/i) {$found_terminating_end = 1;} # elsif (m/\S/) {$found_terminating_end = 0;} } - close(PASCAL_FILE); + close($PASCAL_FILE); # Okay, we've examined the entire file looking for clues; # let's use those clues to determine if it's really Pascal: @@ -13722,9 +14001,9 @@ sub really_is_incpascal { # {{{1 my $is_pascal = 0; # Value to determine. my $found_begin = 0; - open(PASCAL_FILE, "<$filename") || - die "Can't open $filename to determine if it's pascal.\n"; - while() { + my $PASCAL_FILE = open_file('<', $filename, 0); + die "Can't open $filename to determine if it's pascal.\n" if !defined $PASCAL_FILE; + while(<$PASCAL_FILE>) { s/\{.*?\}//g; # Ignore {...} comments on this line; imperfect, but effective. s/\(\*.*?\*\)//g; # Ignore (*...*) comments on this line; imperfect, but effective. if (m/\bprogram\s+[A-Za-z]/i) {$is_pascal=1;} @@ -13742,7 +14021,7 @@ sub really_is_incpascal { # {{{1 } } - close(PASCAL_FILE); + close($PASCAL_FILE); return $is_pascal; } # 1}}} sub really_is_php { # {{{1 @@ -13760,9 +14039,9 @@ sub really_is_php { # {{{1 # Return cached result, if available: if ($php_files{$filename}) { return $php_files{$filename};} - open(PHP_FILE, "<$filename") || - die "Can't open $filename to determine if it's php.\n"; - while() { + my $PHP_FILE = open_file('<', $filename, 0); + die "Can't open $filename to determine if it's php.\n" if !defined $PHP_FILE; + while(<$PHP_FILE>) { if (m/\<\?/) { $normal_surround |= 1; } if (m/\?\>/ && ($normal_surround & 1)) { $normal_surround |= 2; } if (m/\/ && ($asp_surround & 1)) { $asp_surround |= 2; } } - close(PHP_FILE); + close($PHP_FILE); if ( ($normal_surround == 3) || ($script_surround == 3) || ($asp_surround == 3)) { @@ -14294,7 +14573,7 @@ effortlessly interpolated, and because it also allows them to be my $num = $RE{num}{int}; - my $commad = $num->{-sep=>','}{-group=>3}; + my $command = $num->{-sep=>','}{-group=>3}; my $duodecimal = $num->{-base=>12}; @@ -14978,7 +15257,7 @@ pattern name => [qw /comment Fortran fixed/], # http://www.csis.ul.ie/cobol/Course/COBOLIntro.htm -# Traditionally, comments in COBOL were indicated with an asteriks in +# Traditionally, comments in COBOL were indicated with an asterisk in # the seventh column. Modern compilers may be more lenient. pattern name => [qw /comment COBOL/], create => '(?<=^......)(?k:(?k:[*])(?k:[^\n]*)(?k:\n))', @@ -15176,7 +15455,7 @@ L. =item COBOL -Traditionally, comments in I are indicated by an asteriks in the +Traditionally, comments in I are indicated by an asterisk in the seventh column. This is what the pattern matches. Modern compiler may more lenient though. See L, and L. @@ -15534,7 +15813,7 @@ of the line. =item Q-BAL Comments in the I language start with C<`> (a backtick), and -contine till the end of the line. +continue till the end of the line. =item QML @@ -15572,7 +15851,7 @@ a C<;>. See L. =item SLIDE -The I language has two froms of comments. First there is the +The I language has two forms of comments. First there is the line comment, which starts with a C<#> and includes the rest of the line (just like Perl). Second, there is the multiline, nested comment, which are delimited by C<(*> and C<*)>. Under C{-keep}>, only @@ -16270,7 +16549,7 @@ EOD mkdir $Regexp_Common_dir; foreach my $module_file (keys %Regexp_Common_Contents) { - my $OUT = new IO::File "$dir/Regexp/${module_file}.pm", "w"; + my $OUT = open_file('>', "$dir/Regexp/${module_file}.pm", 1); if (defined $OUT) { print $OUT $Regexp_Common_Contents{$module_file}; $OUT->close; @@ -17118,7 +17397,7 @@ for my $meth ( qw( EOAlgDiff # 2}}} my $problems = 0; - $HAVE_Algorith_Diff = 0; + $HAVE_Algorithm_Diff = 0; my $dir = ""; if ($opt_sdir) { ++$TEMP_OFF; @@ -17136,7 +17415,7 @@ EOAlgDiff mkdir $Algorithm_dir ; mkdir $Algorithm_Diff_dir; - my $OUT = new IO::File "$dir/Algorithm/Diff.pm", "w"; + my $OUT = open_file('>', "$dir/Algorithm/Diff.pm", 1); if (defined $OUT) { print $OUT $Algorithm_Diff_Contents; $OUT->close; @@ -17147,7 +17426,7 @@ EOAlgDiff push @INC, $dir; # between this & Regexp::Common only need to do once eval "use Algorithm::Diff qw / sdiff /"; - $HAVE_Algorith_Diff = 1 unless $problems; + $HAVE_Algorithm_Diff = 1 unless $problems; } # 1}}} __END__ mode values (stat $item)[2] @@ -17156,4 +17435,3 @@ file: 33188 33206 dir : 16832 16895 link: 33261 33206 pipe: 4544 null -if ($opt_vcs eq "git" or $opt_force_git); diff --git a/tests/inputs/Containerfile b/tests/inputs/Containerfile new file mode 100644 index 00000000..d0f15122 --- /dev/null +++ b/tests/inputs/Containerfile @@ -0,0 +1,60 @@ +# this is a copy of tests/inputs/Dockerfile + +FROM centos:centos6 + +# just a comment + +RUN yum clean all && \ + yum -y install epel-release && \ + yum -y install \ + acl \ + asciidoc \ + bzip2 \ + file \ + gcc \ + git \ + make \ + mercurial \ + mysql \ + MySQL-python \ + mysql-server \ + openssh-clients \ + openssh-server \ + python-coverage \ + python-devel \ + python-httplib2 \ + python-keyczar \ + python-mock \ + python-nose \ + python-paramiko \ + python-passlib \ + python-pip \ + python-setuptools \ + python-virtualenv \ + PyYAML \ + rpm-build \ + rubygems \ + sed \ + subversion \ + sudo \ + unzip \ + which \ + zip \ + && \ + yum clean all + +RUN rpm -e --nodeps python-crypto && pip install --upgrade jinja2 pycrypto + +RUN /bin/sed -i -e 's/^\(Defaults\s*requiretty\)/#--- \1/' /etc/sudoers +RUN mkdir /etc/ansible/ +RUN /bin/echo -e '[local]\nlocalhost ansible_connection=local' > /etc/ansible/hosts +VOLUME /sys/fs/cgroup /run /tmp +RUN ssh-keygen -q -t rsa1 -N '' -f /etc/ssh/ssh_host_key && \ + ssh-keygen -q -t dsa -N '' -f /etc/ssh/ssh_host_dsa_key && \ + ssh-keygen -q -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key && \ + ssh-keygen -q -t rsa -N '' -f /root/.ssh/id_rsa && \ + cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys && \ + for key in /etc/ssh/ssh_host_*_key.pub; do echo "localhost $(cat ${key})" >> /root/.ssh/known_hosts; done +RUN pip install junit-xml +ENV container=docker +CMD ["/sbin/init"] diff --git a/tests/inputs/ERC20.cairo b/tests/inputs/ERC20.cairo new file mode 100644 index 00000000..3d4232f1 --- /dev/null +++ b/tests/inputs/ERC20.cairo @@ -0,0 +1,101 @@ +// https://raw.githubusercontent.com/OpenZeppelin/cairo-contracts/main/src/openzeppelin/token/erc20/presets/ERC20.cairo +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts for Cairo v0.4.0b (token/erc20/presets/ERC20.cairo) + +%lang starknet + +from starkware.cairo.common.cairo_builtins import HashBuiltin +from starkware.cairo.common.uint256 import Uint256 + +from openzeppelin.token.erc20.library import ERC20 + +@constructor +func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + name: felt, symbol: felt, decimals: felt, initial_supply: Uint256, recipient: felt +) { + ERC20.initializer(name, symbol, decimals); + ERC20._mint(recipient, initial_supply); + return (); +} + +// +// Getters +// + +@view +func name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (name: felt) { + return ERC20.name(); +} + +@view +func symbol{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (symbol: felt) { + return ERC20.symbol(); +} + +@view +func totalSupply{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + totalSupply: Uint256 +) { + let (totalSupply: Uint256) = ERC20.total_supply(); + return (totalSupply=totalSupply); +} + +@view +func decimals{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + decimals: felt +) { + return ERC20.decimals(); +} + +@view +func balanceOf{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(account: felt) -> ( + balance: Uint256 +) { + return ERC20.balance_of(account); +} + +@view +func allowance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + owner: felt, spender: felt +) -> (remaining: Uint256) { + return ERC20.allowance(owner, spender); +} + +// +// Externals +// + +@external +func transfer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + recipient: felt, amount: Uint256 +) -> (success: felt) { + return ERC20.transfer(recipient, amount); +} + +@external +func transferFrom{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + sender: felt, recipient: felt, amount: Uint256 +) -> (success: felt) { + return ERC20.transfer_from(sender, recipient, amount); +} + +@external +func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + spender: felt, amount: Uint256 +) -> (success: felt) { + return ERC20.approve(spender, amount); +} + +@external +func increaseAllowance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + spender: felt, added_value: Uint256 +) -> (success: felt) { + return ERC20.increase_allowance(spender, added_value); +} + +@external +func decreaseAllowance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + spender: felt, subtracted_value: Uint256 +) -> (success: felt) { + return ERC20.decrease_allowance(spender, subtracted_value); +} diff --git a/tests/inputs/Rounds.scad b/tests/inputs/Rounds.scad new file mode 100644 index 00000000..f2f04546 --- /dev/null +++ b/tests/inputs/Rounds.scad @@ -0,0 +1,63 @@ +// https://raw.githubusercontent.com/UBaer21/UB.scad/main/examples/UBexamples/Rounds.scad +include//https://github.com/UBaer21/UB.scad +/*[Hidden]*/ + useVersion=22.016; + designVersion=1.1; + info=true; + +/*[ Round Objects ]*/ +r=[16,8,4,2]; // corner 1-4 radius - can also be just a number + + +LinEx(20) Quad(20); + +LinEx() Quad([25,30],r=r); +Tz(20)LinEx2()Rund(1,2)Stern(5,r1=12,r2=5); + +Rundrum(x=30,y=40,r=r)Quad(x=15,y=20,r=r/2,center=false); +Tz(30)Rundrum(x=15,eck=3,r=3)Quad(x=5,y=3,r=1,center=false); + +T(50)Pille(l=20,d=10); +T(65)Pille(l=20,d=10,rad=[1,15]); +T(80)Pille(l=20,d=10,rad=1); + + + +T(-50) { + RotEx()T(10)Pille(); + RotEx()T(-8)Pille(); +} +T(-80) Kassette(gon=3,r=5,help=1); +T(-80,30) Kassette(gon=4,r=[5,2,4,1],mitte=false,help=1); + +T(-80,60)Rundrum(20,20,r=5,grad=60,grad2=120)rotate(90)Vollwelle(extrude=1); + +T(-50,30) RotEx()T(10)Quad(5); + +T(y=-60){ + + Prisma(10,20,30,c1=5,s=3); + T(15)Prisma(10,20,30,x2=5,y2=10,c1=5,s=3); + T(30)Prisma(10,20,30,x2=5,y2=10,x2d=10,c1=5,s=3); + T(60) Box(20,z=20,eck=5,s=5,c=10,outer=false);// outer = x= side radius or edge + + T(-30) Tz(15)Superellipse(r=[10,20,30]/2,help=1); + T(-50) Tz(15)Superellipse(r=[10,20,30]/2,n=10); + T(-70) Tz(15)Superellipse(r=[10,20,30]/2,n=4,n3=20); + +} + + +T(y=90){ + Torus(trx=5,help=1); + Torus(dia=30,d=5,end=true); + Torus(dia=43,d=5,end=1,grad=270); + Torus(dia=59,d=5,end=+10,grad=270)Quad($d,10); + Torus(dia=79,trxEnd=-9,d=5,end=1,grad=270)Quad($d,10); + T(80) Polar(3)RingSeg(120,r=15,help=1,size=3,h=5,fn2=16); +} + +T(y=160){ + RStern(); + T(x=50) RStern(messpunkt=0)circle(); +} diff --git a/tests/inputs/apertium-dan.dan.rlx b/tests/inputs/apertium-dan.dan.rlx new file mode 100644 index 00000000..885e4773 --- /dev/null +++ b/tests/inputs/apertium-dan.dan.rlx @@ -0,0 +1,100 @@ +# based on +# https://raw.githubusercontent.com/apertium/apertium-dan/master/apertium-dan.dan.rlx +# -*- cg-pre-pipe: "apertium -d . dan-morph|cg-conv -a 2>/dev/null" -*- + +SOFT-DELIMITERS = "<,>" cm ; +DELIMITERS = "<.>" "<:>" "" "" "<|>" "<$.>" "<$:>" "<$!>" "<$?>" "<$|>" ssingular ; + +#PARENTHESES = ("<$(>" "$<)>") ("<$[>" "<$]>") ("<${>" "<$}>") ; + +LIST GENDER = m f nt mf ut ; +LIST NUMBER = sg pl sp ; +LIST DEFNES = def ind ; +LIST TEMPUS = inf pres pasv pret pp imp ; + +# For use with http://beta.visl.sdu.dk/cg3/single/#set-unification-set +# as &&ADJ_N_AGR (also works for demonstratives): +LIST AGR_MF = ut mf f m ; +LIST AGR_SP = (sp un) ; +SET AGR_MF_SG = (sg) + AGR_MF OR AGR_SP ; +SET AGR_NT_SG = (sg) + (nt) OR AGR_SP ; +SET AGR_PL = (pl) OR AGR_SP ; +SET ADJ_N_AGR = AGR_MF_SG OR AGR_NT_SG OR AGR_PL ; +# ADD:agrtest (@agrtest) &&ADJ_N_AGR IF (-1 &&ADJ_N_AGR); +# sitt telefoner. sine telefoner. si telefoner. sin telefoner. +# sitt telefon. sine telefon. si telefon. sin telefon. +# sitt bidrag. sine bidrag. si bidrag. sin bidrag. +# sitt hus. sine hus. si hus. sin hus. + +LIST ADJ_NUMGEN = pl (nt sg) (mf sg) ; + + +LIST sg = sg ; +LIST pl = pl ; +LIST ut = ut ; +LIST nt = nt ; + +LIST n = n ; +LIST pr = pr ; +LIST vblex = vblex ; + +LIST expl = expl ; +LIST ord = ord ; +LIST adj = adj ; +LIST def = def ; +LIST ind = ind ; +LIST ref = ref ; +LIST pers = pers ; +LIST pres = pres ; +LIST pret = pret ; +LIST cm = cm ; +LIST cnjadv = cnjadv ; + +LIST fv = pres pret ; + +SET pre-np-head = (*) - (gen) - (adj); + +LIST %al% = "al" ; +LIST %al%-det = "al" det qnt ; +LIST %aller% = ("aller" adv) ; +LIST %alt% = ("al" det nt) ; +LIST %andre% = "andre" ; +LIST %anden% = "anden" ; +LIST %andet% = "andet" ; +LIST %anden/samme%/quantifier-neuter = ("anden" nt) ("samme" ) (det qnt) ; +LIST %bodyparts%-plural = ("arm" pl) ("ben" pl) ("krop" pl) ("læg" pl) ; +LIST %at% = "at" ; +LIST %særlig% = "særlig" ; +LIST %at/om% = "om" "at" ; +LIST %om-at% = "om at" ; +LIST %af% = "af" ; +LIST %bare% = ("bare" adv) ; +LIST %begge/selve/alle% = "selv" "begge" ("al" det pl) ; +LIST %bla% = "blandt andet" "bl.a." ; +LIST %blik% = ("blik" adv) ; +LIST %både% = "både" ; +LIST %da% = "da" ; +LIST %den% = ("den" det) ; +LIST %den/denne% = ("den" det) ("denne" det) ; +LIST %den/det/de% = "det" "den" "de" ; +LIST %der% = "der" ; +LIST %det% = "det" ("den" det nt) ; +LIST %det%-pron = ("det" prn) ; +LIST %det/dette% = ("den" det nt) ("denne" det nt) ; +LIST %disse% = ("denne" det dem un pl) ; +LIST %eksempel% = "eksempel" ; +LIST %eksklusiv/e% = "eksklusive" "eksklusiv" ; +LIST %eller% = "eller" ; +LIST %endnu% = "endnu" ; +LIST %end% = "end" ; +LIST %et% = ("en" det nt sg) ; +LIST %en% = ("en" det ut sg) ; +LIST %en/et% = ("en" det sg ut) ("en" det sg nt) ; +LIST %fare%-past = ("fare" vblex past) ; +LIST %fast% = ("fast" adj) ; +LIST %flere% = ("mange" adj comp) ; +LIST %for% = "for" ; +LIST %for/før/når% = "når" "før" "for" ; +LIST %frem/ind/op% = ("frem" pr) ("ind" pr) ("op" pr) ; +LIST %fuldstændig% = ("fuldstændig") ; +LIST %fuldt/mange% = "mange" ("fuld" adj nt ind sg) ; # diff --git a/tests/inputs/basic.p4 b/tests/inputs/basic.p4 new file mode 100644 index 00000000..5fd6d4fc --- /dev/null +++ b/tests/inputs/basic.p4 @@ -0,0 +1,163 @@ +// https://raw.githubusercontent.com/p4lang/tutorials/master/exercises/basic/basic.p4 +/* -*- P4_16 -*- */ +#include +#include + +const bit<16> TYPE_IPV4 = 0x800; + +/************************************************************************* +*********************** H E A D E R S *********************************** +*************************************************************************/ + +typedef bit<9> egressSpec_t; +typedef bit<48> macAddr_t; +typedef bit<32> ip4Addr_t; + +header ethernet_t { + macAddr_t dstAddr; + macAddr_t srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + ip4Addr_t srcAddr; + ip4Addr_t dstAddr; +} + +struct metadata { + /* empty */ +} + +struct headers { + ethernet_t ethernet; + ipv4_t ipv4; +} + +/************************************************************************* +*********************** P A R S E R *********************************** +*************************************************************************/ + +parser MyParser(packet_in packet, + out headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + + state start { + /* TODO: add parser logic */ + transition accept; + } +} + + +/************************************************************************* +************ C H E C K S U M V E R I F I C A T I O N ************* +*************************************************************************/ + +control MyVerifyChecksum(inout headers hdr, inout metadata meta) { + apply { } +} + + +/************************************************************************* +************** I N G R E S S P R O C E S S I N G ******************* +*************************************************************************/ + +control MyIngress(inout headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + action drop() { + mark_to_drop(standard_metadata); + } + + action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) { + /* TODO: fill out code in action body */ + } + + table ipv4_lpm { + key = { + hdr.ipv4.dstAddr: lpm; + } + actions = { + ipv4_forward; + drop; + NoAction; + } + size = 1024; + default_action = NoAction(); + } + + apply { + /* TODO: fix ingress control logic + * - ipv4_lpm should be applied only when IPv4 header is valid + */ + ipv4_lpm.apply(); + } +} + +/************************************************************************* +**************** E G R E S S P R O C E S S I N G ******************* +*************************************************************************/ + +control MyEgress(inout headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + apply { } +} + +/************************************************************************* +************* C H E C K S U M C O M P U T A T I O N ************** +*************************************************************************/ + +control MyComputeChecksum(inout headers hdr, inout metadata meta) { + apply { + update_checksum( + hdr.ipv4.isValid(), + { hdr.ipv4.version, + hdr.ipv4.ihl, + hdr.ipv4.diffserv, + hdr.ipv4.totalLen, + hdr.ipv4.identification, + hdr.ipv4.flags, + hdr.ipv4.fragOffset, + hdr.ipv4.ttl, + hdr.ipv4.protocol, + hdr.ipv4.srcAddr, + hdr.ipv4.dstAddr }, + hdr.ipv4.hdrChecksum, + HashAlgorithm.csum16); + } +} + + +/************************************************************************* +*********************** D E P A R S E R ******************************* +*************************************************************************/ + +control MyDeparser(packet_out packet, in headers hdr) { + apply { + /* TODO: add deparser logic */ + } +} + +/************************************************************************* +*********************** S W I T C H ******************************* +*************************************************************************/ + +V1Switch( +MyParser(), +MyVerifyChecksum(), +MyIngress(), +MyEgress(), +MyComputeChecksum(), +MyDeparser() +) main; diff --git a/tests/inputs/cad.asy b/tests/inputs/cad.asy new file mode 100644 index 00000000..7cc15c20 --- /dev/null +++ b/tests/inputs/cad.asy @@ -0,0 +1,46 @@ +// https://asymptote.sourceforge.io/gallery/CAD1.asy +import CAD; + +sCAD cad=sCAD.Create(); + +/* Freehand line +this is a comment +*/ +draw(g=cad.MakeFreehand(pFrom=(3,-1)*cm,(6,-1)*cm), + p=cad.pFreehand); + +// Standard measurement lines +draw(g=box((0,0)*cm,(1,1)*cm),p=cad.pVisibleEdge); +cad.MeasureParallel(L="$\sqrt{2}$", + pFrom=(0,1)*cm, + pTo=(1,0)*cm, + dblDistance=-15mm); + +// Label inside,shifted to the right; arrows outside +draw(g=box((2,0)*cm,(3,1)*cm),p=cad.pVisibleEdge); +cad.MeasureParallel(L="1", + pFrom=(2,1)*cm, + pTo=(3,1)*cm, + dblDistance=5mm, + dblLeft=5mm, + dblRelPosition=0.75); + +// Label and arrows outside +draw(g=box((5,0)*cm,(5.5,1)*cm),p=cad.pVisibleEdge); +cad.MeasureParallel(L="0.5", + pFrom=(5,1)*cm, + pTo=(5.5,1)*cm, + dblDistance=5mm, + dblLeft=10mm, + dblRelPosition=-1); + +// Small bounds,asymmetric measurement line +draw(g=box((7,0)*cm,(7.5,1)*cm),p=cad.pVisibleEdge); +cad.MeasureParallel(L="0.5", + pFrom=(7,1)*cm, + pTo=(7.5,1)*cm, + dblDistance=5mm, + dblLeft=2*cad.GetMeasurementBoundSize(bSmallBound=true), + dblRight=10mm, + dblRelPosition=2, + bSmallBound=true); diff --git a/tests/inputs/eddsa.circom b/tests/inputs/eddsa.circom new file mode 100644 index 00000000..534d9855 --- /dev/null +++ b/tests/inputs/eddsa.circom @@ -0,0 +1,140 @@ +// https://raw.githubusercontent.com/iden3/circomlib/master/circuits/eddsa.circom +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "compconstant.circom"; +include "pointbits.circom"; +include "pedersen.circom"; +include "escalarmulany.circom"; +include "escalarmulfix.circom"; + +template EdDSAVerifier(n) { + signal input msg[n]; + + signal input A[256]; + signal input R8[256]; + signal input S[256]; + + signal Ax; + signal Ay; + + signal R8x; + signal R8y; + + var i; + +// Ensure S compConstant.in[i]; + } + compConstant.out === 0; + S[254] === 0; + S[255] === 0; + +// Convert A to Field elements (And verify A) + + component bits2pointA = Bits2Point_Strict(); + + for (i=0; i<256; i++) { + bits2pointA.in[i] <== A[i]; + } + Ax <== bits2pointA.out[0]; + Ay <== bits2pointA.out[1]; + +// Convert R8 to Field elements (And verify R8) + + component bits2pointR8 = Bits2Point_Strict(); + + for (i=0; i<256; i++) { + bits2pointR8.in[i] <== R8[i]; + } + R8x <== bits2pointR8.out[0]; + R8y <== bits2pointR8.out[1]; + +// Calculate the h = H(R,A, msg) + + component hash = Pedersen(512+n); + + for (i=0; i<256; i++) { + hash.in[i] <== R8[i]; + hash.in[256+i] <== A[i]; + } + for (i=0; i +// (c) 2021 Andri Yngvason +// (c) 2021-2022 Bor Grošelj Simić +// (c) 2021 Byron Torres +// (c) 2021 Drew DeVault +// (c) 2021 Ember Sawady +use ascii; +use bufio; +use encoding::utf8; +use io; +// https://git.sr.ht/~sircmpwn/hare/tree/master/item/fmt/fmt.ha +use math; +use os; +use strconv; +use strings; +use types; + +// Tagged union of the [[formattable]] types and [[modifiers]]. Used for +// functions which accept format strings. +export type field = (...formattable | *modifiers); + +// Tagged union of all types which are formattable. +export type formattable = (...types::numeric | uintptr | str | rune | bool | + nullable *void | void); + +// Formats text for printing and writes it to [[os::stdout]]. +export fn printf(fmt: str, args: field...) (io::error | size) = + fprintf(os::stdout, fmt, args...); + +// Formats text for printing and writes it to [[os::stdout]], followed by a line +// feed. +export fn printfln(fmt: str, args: field...) (io::error | size) = + fprintfln(os::stdout, fmt, args...); diff --git a/tests/inputs/issues/692/A.txt b/tests/inputs/issues/692/A.txt new file mode 100644 index 00000000..eb9a0615 --- /dev/null +++ b/tests/inputs/issues/692/A.txt @@ -0,0 +1,7 @@ +../../diff/A +../../diff/A/d2 +../../diff/A/d2/hi.py +../../diff/A/d2/hello.java +../../diff/A/d1 +../../diff/A/d1/hello.f90 +../../diff/A/hello.C diff --git a/tests/inputs/issues/692/B.txt b/tests/inputs/issues/692/B.txt new file mode 100644 index 00000000..ce268835 --- /dev/null +++ b/tests/inputs/issues/692/B.txt @@ -0,0 +1,6 @@ +# directory names are ignored +../../diff/B/d2/hi.py +../../diff/B/d1 +../../diff/B/d1/hello.f90 +../../diff/B/extra_file.pl +../../diff/B/hello.C diff --git a/tests/inputs/issues/701/demo.ml b/tests/inputs/issues/701/demo.ml new file mode 100644 index 00000000..f6726288 --- /dev/null +++ b/tests/inputs/issues/701/demo.ml @@ -0,0 +1,8 @@ +let just_a_string = " + (* +" +let x = 0 +let also_a_string = " + *) +" +let y = x diff --git a/tests/inputs/issues/710/A/cal.data b/tests/inputs/issues/710/A/cal.data new file mode 100644 index 00000000..225ce0f8 --- /dev/null +++ b/tests/inputs/issues/710/A/cal.data @@ -0,0 +1,8 @@ + February 2023 +Su Mo Tu We Th Fr Sa + 1 2 3 4 +_ _5 6 7 8 9 10 11 +12 13 14 15 16 17 18 +19 20 21 22 23 24 25 +26 27 28 + diff --git a/tests/inputs/issues/710/A/hello.C b/tests/inputs/issues/710/A/hello.C new file mode 100644 index 00000000..af677129 --- /dev/null +++ b/tests/inputs/issues/710/A/hello.C @@ -0,0 +1,8 @@ +// hello.C +#include +int main () +{ + std::cout << "hello" << std::endl; // comment 1 + std::cout << "again" << std::endl; /* comment + 2 */ +} diff --git a/tests/inputs/issues/710/B/hello.C b/tests/inputs/issues/710/B/hello.C new file mode 100644 index 00000000..af677129 --- /dev/null +++ b/tests/inputs/issues/710/B/hello.C @@ -0,0 +1,8 @@ +// hello.C +#include +int main () +{ + std::cout << "hello" << std::endl; // comment 1 + std::cout << "again" << std::endl; /* comment + 2 */ +} diff --git a/tests/inputs/issues/710/test_files.list b/tests/inputs/issues/710/test_files.list new file mode 100644 index 00000000..66a07885 --- /dev/null +++ b/tests/inputs/issues/710/test_files.list @@ -0,0 +1,5 @@ +Files removed: 1 + - A/cal.data ; Text + +File pairs compared: 1 + == A/hello.C | B/hello.C ; C++ diff --git a/tests/inputs/issues/712/dir1/main.c b/tests/inputs/issues/712/dir1/main.c new file mode 100644 index 00000000..d5c0b66c --- /dev/null +++ b/tests/inputs/issues/712/dir1/main.c @@ -0,0 +1,6 @@ +#include + +int main(void){ + printf("Hello world\n"); + return 0; +} diff --git a/tests/inputs/issues/712/dir1/sub_dir1/foo.txt b/tests/inputs/issues/712/dir1/sub_dir1/foo.txt new file mode 100644 index 00000000..257cc564 --- /dev/null +++ b/tests/inputs/issues/712/dir1/sub_dir1/foo.txt @@ -0,0 +1 @@ +foo diff --git a/tests/inputs/issues/712/dir2/foo.txt b/tests/inputs/issues/712/dir2/foo.txt new file mode 100644 index 00000000..257cc564 --- /dev/null +++ b/tests/inputs/issues/712/dir2/foo.txt @@ -0,0 +1 @@ +foo diff --git a/tests/inputs/issues/712/dir2/main.c b/tests/inputs/issues/712/dir2/main.c new file mode 100644 index 00000000..d5c0b66c --- /dev/null +++ b/tests/inputs/issues/712/dir2/main.c @@ -0,0 +1,6 @@ +#include + +int main(void){ + printf("Hello world\n"); + return 0; +} diff --git a/tests/inputs/issues/713/hello.C b/tests/inputs/issues/713/hello.C new file mode 100644 index 00000000..af677129 --- /dev/null +++ b/tests/inputs/issues/713/hello.C @@ -0,0 +1,8 @@ +// hello.C +#include +int main () +{ + std::cout << "hello" << std::endl; // comment 1 + std::cout << "again" << std::endl; /* comment + 2 */ +} diff --git a/tests/inputs/issues/720/inputs.txt b/tests/inputs/issues/720/inputs.txt new file mode 100644 index 00000000..383fbeea --- /dev/null +++ b/tests/inputs/issues/720/inputs.txt @@ -0,0 +1,12 @@ +These files are considered: + ../../Lanczos.m + ../../Mathematica_1.m + ../../matlab_line_colors.m + ../../Octave.m + ../../qsort_demo.m + +These files are counted: + ../../Lanczos.m + ../../qsort_demo.m + ../../matlab_line_colors.m + diff --git a/tests/inputs/issues/722/Fortran77.f b/tests/inputs/issues/722/Fortran77.f new file mode 100644 index 00000000..d61994ec --- /dev/null +++ b/tests/inputs/issues/722/Fortran77.f @@ -0,0 +1,6 @@ +C from http://www.roesler-ac.de/wolfram/hello.htm +C Hello World in Fortran 77 + + PROGRAM HELLO + PRINT*, 'Hello World!' + END diff --git a/tests/inputs/issues/722/hello.f90 b/tests/inputs/issues/722/hello.f90 new file mode 100644 index 00000000..6b26a2eb --- /dev/null +++ b/tests/inputs/issues/722/hello.f90 @@ -0,0 +1,7 @@ +! Hello World +program hello + implicit none + print '("Hello, World!")' +end program hello +!hpf$ not a comment +!omp$ not a comment either diff --git a/tests/inputs/issues/722/hello.lua b/tests/inputs/issues/722/hello.lua new file mode 100644 index 00000000..eaa1bab8 --- /dev/null +++ b/tests/inputs/issues/722/hello.lua @@ -0,0 +1,14 @@ +-- single line comment + +--[[ +multi +line +comment +]] + +--[[ +also a comment +--]] + +print("hello, world") +print([[not a comment]]) diff --git a/tests/inputs/linker.ld b/tests/inputs/linker.ld new file mode 100644 index 00000000..6d5b7eed --- /dev/null +++ b/tests/inputs/linker.ld @@ -0,0 +1,260 @@ +/* Obtained from command `ld --verbose` */ + +/* +GNU ld (GNU Binutils for Ubuntu) 2.34 + Supported emulations: + elf_x86_64 + elf32_x86_64 + elf_i386 + elf_iamcu + elf_l1om + elf_k1om + i386pep + i386pe +using internal linker script: +================================================== +*/ + +/* Script for -z combreloc -z separate-code */ +/* Copyright (C) 2014-2020 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", + "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib"); +SECTIONS +{ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) + *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) + *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + . = ALIGN(CONSTANT (MAXPAGESIZE)); + .init : + { + KEEP (*(SORT_NONE(.init))) + } + .plt : { *(.plt) *(.iplt) } +.plt.got : { *(.plt.got) } +.plt.sec : { *(.plt.sec) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(SORT(.text.sorted.*)) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf.em. */ + *(.gnu.warning) + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + . = ALIGN(CONSTANT (MAXPAGESIZE)); + /* Adjust the address for the rodata segment. We want to adjust up to + the same address within the page on the next page up. */ + . = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1))); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : + { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + .data : + { + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + .lbss : + { + *(.dynlbss) + *(.lbss .lbss.* .gnu.linkonce.lb.*) + *(LARGE_COMMON) + } + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.lrodata .lrodata.* .gnu.linkonce.lr.*) + } + .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.ldata .ldata.* .gnu.linkonce.l.*) + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + . = ALIGN(64 / 8); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + +/* +================================================== +*/ diff --git a/tests/inputs/poly_constructor.jai b/tests/inputs/poly_constructor.jai new file mode 100644 index 00000000..5dbdc308 --- /dev/null +++ b/tests/inputs/poly_constructor.jai @@ -0,0 +1,29 @@ +/* +http://the-witness.net/news/2018/03/testing-the-jai-compiler/ +with init_thing commented out +*/ +#import "Basic"; + +Thing :: struct { + mem : *u8; + value := 42; + #constructor init_thing; + #destructor free_thing; +} + +// init_thing :: (using thing : *$T) { +// mem = alloc(1000); +// } + +free_thing :: (using thing: *$T) { + free(mem); + mem = null; + print("Thing memory freed.\n"); +} + +main :: () { + { + our_thing : Thing; // Constructor fires off. + print("%\n", our_thing); + } // Destructor fires off. +} diff --git a/tests/inputs/ring.pony b/tests/inputs/ring.pony new file mode 100644 index 00000000..76cc785d --- /dev/null +++ b/tests/inputs/ring.pony @@ -0,0 +1,132 @@ +/* + * https://github.com/ponylang/ponyc/raw/908402b60f083d66d3b59a1879efb6adee5ca3cc/examples/ring/main.pony + */ + +""" +A ring is a group of processes connected to each other using +unidirectional links through which messages can pass from process to +process in a cyclic manner. + +The logic of this program is as follows: +* Each process in a ring is represented by the actor `Ring` +* `Main` creates Ring by instantiating `Ring` actors based on the + arguments passed and links them with each other by setting the next + actor as the previous ones number and at the end linking the last actor + to the first one thereby closing the links and completing the ring +* Once the ring is complete messages can be passed by calling the `pass` + behaviour on the current `Ring` to its neighbour. +* The program prints the id of the last `Ring` to receive a message + +For example if you run this program with the following options `--size 3` +and `--pass 2`. It will create a ring that looks like this: + + + * * * * + * * * * + * 1 *_ _ _ * 2 * + * * * * + * * * * + * * * * + \ / + \ / + \ / + \ * * / + * * + * 3 * + * * + * * + * * + +and print 3 as the id of the last Ring actor that received the +message. +""" + +use "collections" + +actor Ring + let _id: U32 + let _env: Env + var _next: (Ring | None) + + new create(id: U32, env: Env, neighbor: (Ring | None) = None) => + _id = id + _env = env + _next = neighbor + + be set(neighbor: Ring) => + _next = neighbor + + be pass(i: USize) => + if i > 0 then + match _next + | let n: Ring => + n.pass(i - 1) + end + else + _env.out.print(_id.string()) + end + +actor Main + var _ring_size: U32 = 3 + var _ring_count: U32 = 1 + var _pass: USize = 10 + + var _env: Env + + new create(env: Env) => + _env = env + + try + parse_args()? + setup_ring() + else + usage() + end + + fun ref parse_args() ? => + var i: USize = 1 + + while i < _env.args.size() do + // Every option has an argument. + var option = _env.args(i)? + var value = _env.args(i + 1)? + i = i + 2 + + match option + | "--size" => + _ring_size = value.u32()? + | "--count" => + _ring_count = value.u32()? + | "--pass" => + _pass = value.usize()? + else + error + end + end + + fun setup_ring() => + for j in Range[U32](0, _ring_count) do + let first = Ring(1, _env) + var next = first + + for k in Range[U32](0, _ring_size - 1) do + let current = Ring(_ring_size - k, _env, next) + next = current + end + + first.set(next) + + if _pass > 0 then + first.pass(_pass) + end + end + + fun usage() => + _env.out.print( + """ + rings OPTIONS + --size N number of actors in each ring + --count N number of rings + --pass N number of messages to pass around each ring + """ + ) diff --git a/tests/inputs/toml.pest b/tests/inputs/toml.pest new file mode 100644 index 00000000..4b869e07 --- /dev/null +++ b/tests/inputs/toml.pest @@ -0,0 +1,76 @@ +// pest. The Elegant Parser +// Copyright (c) 2018 Dragoș Tiselice +// +// Licensed under the Apache License, Version 2.0 +// or the MIT +// license , at your +// option. All files in the project carrying such notice may not be copied, +// modified, or distributed except according to those terms. + +toml = { SOI ~ (table | array_table | pair)* ~ EOI } + +table = { "[" ~ key ~ ("." ~ key)* ~ "]" ~ pair* } +array_table = { "[[" ~ key ~ ("." ~ key)* ~ "]]" ~ pair* } +pair = { key ~ "=" ~ value } + +key = @{ identifier | string | literal } +value = _{ + inline_table | + array | + multi_line_string | + string | + multi_line_literal | + literal | + date_time | + local_date_time | + full_date | + partial_time | + float | + integer | + boolean +} + +inline_table = { "{" ~ pair ~ ("," ~ pair)* ~ ","? ~ "}" | "{" ~ "}" } + +array = { "[" ~ value ~ ("," ~ value)* ~ ","? ~ "]" | "[" ~ "]" } + +identifier = { (ASCII_ALPHANUMERIC | "_" | "-")+ } + +multi_line_string = @{ "\"\"\"" ~ inner ~ "\"\"\"" } +string = @{ "\"" ~ inner ~ "\"" } +inner = @{ (!("\"" | "\\" | "\u{0000}" | "\u{001F}") ~ ANY)* ~ (escape ~ inner)? } +multi_line_literal = @{ "'''" ~ (!"'''" ~ ANY)* ~ "'''" } +literal = @{ "'" ~ (!"'" ~ ANY)* ~ "'" } + +// another comment + +escape = @{ "\\" ~ ("b" | "t" | "n" | "f" | "r" | "\"" | "\\" | unicode | NEWLINE)? } +unicode = @{ "u" ~ ASCII_HEX_DIGIT{4} | "U" ~ ASCII_HEX_DIGIT{8} } + +date_time = ${ full_date ~ "T" ~ full_time } +local_date_time = ${ full_date ~ "T" ~ partial_time } + +partial_time = ${ time_hour ~ ":" ~ time_minute ~ ":" ~ time_second ~ time_secfrac? } +full_date = ${ date_fullyear ~ "-" ~ date_month ~ "-" ~ date_mday } +full_time = ${ partial_time ~ time_offset } + +date_fullyear = @{ ASCII_DIGIT{4} } +date_month = @{ ASCII_DIGIT{2} } +date_mday = @{ ASCII_DIGIT{2} } + +time_hour = @{ ASCII_DIGIT{2} } +time_minute = @{ ASCII_DIGIT{2} } +time_second = @{ ASCII_DIGIT{2} } +time_secfrac = @{ "." ~ ASCII_DIGIT+ } +time_offset = ${ "Z" | ("+" | "-") ~ time_hour ~ ":" ~ time_minute } + +integer = @{ ("+" | "-")? ~ int } +float = @{ ("+" | "-")? ~ int ~ ("." ~ digits ~ exp? | exp)? } +int = @{ "0" | (ASCII_NONZERO_DIGIT ~ digits?) } +digits = @{ (ASCII_DIGIT | ("_" ~ ASCII_DIGIT))+ } +exp = @{ ("E" | "e") ~ ("+" | "-")? ~ int } + +boolean = { "true" | "false" } + +WHITESPACE = _{ " " | "\t" | NEWLINE } +COMMENT = _{ "#" ~ (!NEWLINE ~ ANY)* } diff --git a/tests/inputs/vinos.nlogo b/tests/inputs/vinos.nlogo new file mode 100644 index 00000000..ad7a62ff --- /dev/null +++ b/tests/inputs/vinos.nlogo @@ -0,0 +1,93 @@ +; https://codebase.helmholtz.cloud/mussel/netlogo-northsea-species/-/blob/main/netlogo/vinos.nlogo +; SPDX-FileCopyrightText: 2022-2023 Universität Hamburg (UHH) +; SPDX-FileCopyrightText: 2022-2023 Helmholtz-Zentrum hereon GmbH (Hereon) +; SPDX-License-Identifier: Apache-2.0 +; +; SPDX-FileContributor: Carsten Lemmen +; SPDX-FileContributor: Sascha Hokamp +; SPDX-FileContributor: Jieun Seo + +extensions [ + gis + csv + profiler + palette + bitmap +] + +__includes [ + "include/geodata.nls" + "include/calendar.nls" + "include/gear.nls" + "include/plot.nls" + "include/utilities.nls" + "include/boat.nls" + "include/view.nls" + "include/prey.nls" + "include/port.nls" +] + +; breed [gears gear] ; defined in gear.nls +; breed [boats boat] ; defined in boat.nls +; breed [legends legend] ; defined in view.nls +; breed [preys prey] ; defined in prey.nls +; breed [ports port] ; defined in port.nls + +breed [actions action] + +actions-own [ + action-patch ; targeted patch id + action-gain ; gain for the fishing trip of the boat + action-gear +] + +globals [ + navigable-depth ; minimum depth where a boat can navigate + min-fresh-catch ; wether the boat decides to go back to harbor, maybe change name + + sum-ports-total-landings-kg ; overall sum of total landings per period + percentage-landings-kg ; percentage of other landing over total landings per period + sum-ports-crangon-landings-euro ; overall sum of landings of crangon per period in EUR 2015 + sum-ports-platessa-landings-euro ; overall sum of landings of platessa per period in EUR 2015 + sum-ports-solea-landings-euro ; overall sum of landings of solea per period in EUR 2015 + sum-ports-crangon-landings-kg ; overall sum of landings of crangon per period in kg + sum-ports-platessa-landings-kg ; overall sum of landings of platessa per period in kg + sum-ports-solea-landings-kg ; overall sum of landings of solea per period in kg + sum-boats ; overall boats of all ports + + owf-dataset ; Off-shore wind farms + + year month day ; time frame + day-of-year + days-in-months + + home-ports ; agentset of breed ports + ;favorite-landing-ports ; agentset of breed ports + + view-legend-n + view-legend-thresholds + date-patch +] + +patches-own [ + fish-biomass ; vektor of biomass of the fish species + + + fishing-effort-hours ; fishing effort in hours + crangon-summer ; data from TI + crangon-winter + platessa-summer + platessa-winter + solea-summer + solea-winter + + fish-abundance + + pollution-exceedance + depth + owf-fraction + accessible? ; false if not accessible to fishery, i.e. close to port, too shallow, restricted area + plaice-box? + + patch-prey-names +] diff --git a/tests/outputs/Containerfile.yaml b/tests/outputs/Containerfile.yaml new file mode 100644 index 00000000..c51ef1bf --- /dev/null +++ b/tests/outputs/Containerfile.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.00706195831298828 + n_files : 1 + n_lines : 60 + files_per_second : 141.603781228899 + lines_per_second : 8496.22687373396 + report_file : ../outputs/Containerfile.yaml +'Containerfile' : + nFiles: 1 + blank: 5 + comment: 2 + code: 53 +SUM: + blank: 5 + comment: 2 + code: 53 + nFiles: 1 diff --git a/tests/outputs/ERC20.cairo.yaml b/tests/outputs/ERC20.cairo.yaml new file mode 100644 index 00000000..1e7ab452 --- /dev/null +++ b/tests/outputs/ERC20.cairo.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.00880813598632812 + n_files : 1 + n_lines : 101 + files_per_second : 113.531398873971 + lines_per_second : 11466.6712862711 + report_file : ../outputs/ERC20.cairo.yaml +'Cairo' : + nFiles: 1 + blank: 17 + comment: 9 + code: 75 +SUM: + blank: 17 + comment: 9 + code: 75 + nFiles: 1 diff --git a/tests/outputs/Rounds.scad.yaml b/tests/outputs/Rounds.scad.yaml new file mode 100644 index 00000000..1a29ffcb --- /dev/null +++ b/tests/outputs/Rounds.scad.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.00699782371520996 + n_files : 1 + n_lines : 63 + files_per_second : 142.901570644952 + lines_per_second : 9002.79895063201 + report_file : ../outputs/Rounds.scad.yaml +'OpenSCAD' : + nFiles: 1 + blank: 18 + comment: 3 + code: 42 +SUM: + blank: 18 + comment: 3 + code: 42 + nFiles: 1 diff --git a/tests/outputs/apertium-dan.dan.rlx.yaml b/tests/outputs/apertium-dan.dan.rlx.yaml new file mode 100644 index 00000000..58bbc1e9 --- /dev/null +++ b/tests/outputs/apertium-dan.dan.rlx.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00721979141235352 + n_files : 1 + n_lines : 100 + files_per_second : 138.508156660723 + lines_per_second : 13850.8156660723 + report_file : ../outputs/apertium-dan.dan.rlx.yaml +'Constraint Grammar' : + nFiles: 1 + blank: 12 + comment: 11 + code: 77 +SUM: + blank: 12 + comment: 11 + code: 77 + nFiles: 1 diff --git a/tests/outputs/basic.p4.yaml b/tests/outputs/basic.p4.yaml new file mode 100644 index 00000000..f2f733f9 --- /dev/null +++ b/tests/outputs/basic.p4.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.0072929859161377 + n_files : 1 + n_lines : 163 + files_per_second : 137.118048971853 + lines_per_second : 22350.241982412 + report_file : ../outputs/basic.p4.yaml +'P4' : + nFiles: 1 + blank: 28 + comment: 33 + code: 102 +SUM: + blank: 28 + comment: 33 + code: 102 + nFiles: 1 diff --git a/tests/outputs/cad.asy.yaml b/tests/outputs/cad.asy.yaml new file mode 100644 index 00000000..761f263b --- /dev/null +++ b/tests/outputs/cad.asy.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00954914093017578 + n_files : 1 + n_lines : 46 + files_per_second : 104.721462099271 + lines_per_second : 4817.18725656646 + report_file : ../outputs/cad.asy.yaml +'Asymptote' : + nFiles: 1 + blank: 6 + comment: 8 + code: 32 +SUM: + blank: 6 + comment: 8 + code: 32 + nFiles: 1 diff --git a/tests/outputs/eddsa.circom.yaml b/tests/outputs/eddsa.circom.yaml new file mode 100644 index 00000000..9515804f --- /dev/null +++ b/tests/outputs/eddsa.circom.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.00864696502685547 + n_files : 1 + n_lines : 140 + files_per_second : 115.647512959082 + lines_per_second : 16190.6518142715 + report_file : ../outputs/eddsa.circom.yaml +'Circom' : + nFiles: 1 + blank: 34 + comment: 26 + code: 80 +SUM: + blank: 34 + comment: 26 + code: 80 + nFiles: 1 diff --git a/tests/outputs/fmt.ha.yaml b/tests/outputs/fmt.ha.yaml new file mode 100644 index 00000000..2dc8fa64 --- /dev/null +++ b/tests/outputs/fmt.ha.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00677204132080078 + n_files : 1 + n_lines : 34 + files_per_second : 147.665962540487 + lines_per_second : 5020.64272637657 + report_file : tests/outputs/fmt.ha.yaml +'Hare' : + nFiles: 1 + blank: 4 + comment: 14 + code: 16 +SUM: + blank: 4 + comment: 14 + code: 16 + nFiles: 1 diff --git a/tests/outputs/issues/692/results.yaml b/tests/outputs/issues/692/results.yaml new file mode 100644 index 00000000..0cf28c37 --- /dev/null +++ b/tests/outputs/issues/692/results.yaml @@ -0,0 +1,136 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.0124430656433105 + n_files : 5 + n_lines : 47 + files_per_second : 401.830235677333 + lines_per_second : 3777.20421536693 + report_file : ../../../outputs/issues/692/results.yaml +added : + 'Fortran 90' : + nFiles : 0 + blank : 0 + comment : 1 + code : 0 + 'Perl' : + code : 2 + comment : 0 + blank : 0 + nFiles : 1 + 'C++' : + nFiles : 0 + blank : 0 + code : 0 + comment : 0 + 'Java' : + code : 0 + blank : 0 + comment : 0 + nFiles : 0 + 'Python' : + blank : 0 + code : 0 + comment : 0 + nFiles : 0 +same : + 'Fortran 90' : + nFiles : 0 + blank : 0 + comment : 3 + code : 4 + 'Perl' : + code : 0 + comment : 0 + blank : 0 + nFiles : 0 + 'C++' : + nFiles : 0 + blank : 0 + code : 6 + comment : 1 + 'Java' : + code : 0 + blank : 0 + comment : 0 + nFiles : 0 + 'Python' : + blank : 4 + code : 3 + comment : 10 + nFiles : 1 +modified : + 'Fortran 90' : + nFiles : 1 + blank : 0 + comment : 0 + code : 0 + 'Perl' : + code : 0 + comment : 0 + blank : 0 + nFiles : 0 + 'C++' : + nFiles : 1 + blank : 0 + code : 0 + comment : 1 + 'Java' : + code : 0 + blank : 0 + comment : 0 + nFiles : 0 + 'Python' : + blank : 0 + code : 0 + comment : 0 + nFiles : 0 +removed : + 'Fortran 90' : + nFiles : 0 + blank : 0 + comment : 0 + code : 1 + 'Perl' : + code : 0 + comment : 0 + blank : 0 + nFiles : 0 + 'C++' : + nFiles : 0 + blank : 0 + code : 0 + comment : 0 + 'Java' : + code : 7 + blank : 0 + comment : 4 + nFiles : 1 + 'Python' : + blank : 0 + code : 0 + comment : 0 + nFiles : 0 +SUM : + added : + nFiles : 1 + blank : 0 + code : 2 + comment : 1 + same : + nFiles : 1 + blank : 4 + code : 13 + comment : 14 + modified : + nFiles : 2 + blank : 0 + code : 0 + comment : 1 + removed : + nFiles : 1 + blank : 0 + code : 8 + comment : 4 diff --git a/tests/outputs/issues/701/results.yaml b/tests/outputs/issues/701/results.yaml new file mode 100644 index 00000000..7918886d --- /dev/null +++ b/tests/outputs/issues/701/results.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.00726699829101562 + n_files : 1 + n_lines : 8 + files_per_second : 137.608398950131 + lines_per_second : 1100.86719160105 + report_file : ../../../outputs/issues/701/results.yaml +'OCaml' : + nFiles: 1 + blank: 0 + comment: 0 + code: 8 +SUM: + blank: 0 + comment: 0 + code: 8 + nFiles: 1 diff --git a/tests/outputs/issues/708/results.yaml b/tests/outputs/issues/708/results.yaml new file mode 100644 index 00000000..b77abd65 --- /dev/null +++ b/tests/outputs/issues/708/results.yaml @@ -0,0 +1,26 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00759720802307129 + n_files : 3 + n_lines : 0 + files_per_second : 394.881908049584 + lines_per_second : 0 + report_file : ../tests/outputs/issues/708/results.yaml +'C' : + nFiles: 1 + blank: 0 + comment: 0 + code: 0 +'C++' : + nFiles: 2 + blank: 0 + comment: 0 + code: 0 +SUM: + blank: 0 + comment: 0 + code: 0 + nFiles: 3 diff --git a/tests/outputs/issues/710/results.yaml b/tests/outputs/issues/710/results.yaml new file mode 100644 index 00000000..4b185288 --- /dev/null +++ b/tests/outputs/issues/710/results.yaml @@ -0,0 +1,56 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00808811187744141 + n_files : 1 + n_lines : 8 + files_per_second : 123.638250206344 + lines_per_second : 989.106001650749 + report_file : /home/al/git-cloc/tests/outputs/issues/710/results.txt +added : + 'C++' : + comment : 0 + blank : 0 + nFiles : 0 + code : 0 +same : + 'C++' : + comment : 2 + blank : 0 + nFiles : 1 + code : 6 +modified : + 'C++' : + comment : 0 + blank : 0 + nFiles : 0 + code : 0 +removed : + 'C++' : + comment : 0 + blank : 0 + nFiles : 0 + code : 0 +SUM : + added : + nFiles : 0 + blank : 0 + code : 0 + comment : 0 + same : + nFiles : 1 + blank : 0 + code : 6 + comment : 2 + modified : + nFiles : 0 + blank : 0 + code : 0 + comment : 0 + removed : + nFiles : 0 + blank : 0 + code : 0 + comment : 0 diff --git a/tests/outputs/issues/712/results.yaml b/tests/outputs/issues/712/results.yaml new file mode 100644 index 00000000..3729d09a --- /dev/null +++ b/tests/outputs/issues/712/results.yaml @@ -0,0 +1,56 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00920295715332031 + n_files : 0 + n_lines : 6 + files_per_second : 0 + lines_per_second : 651.964352331606 + report_file : /home/al/git-cloc/tests/outputs/issues/712/results.yaml +added : + 'dir1/main.c' : + comment : 0 + code : 0 + nFiles : 0 + blank : 0 +same : + 'dir1/main.c' : + comment : 0 + code : 5 + nFiles : 0 + blank : 1 +modified : + 'dir1/main.c' : + comment : 0 + code : 0 + nFiles : 0 + blank : 0 +removed : + 'dir1/main.c' : + comment : 0 + code : 0 + nFiles : 0 + blank : 0 +SUM : + added : + blank : 0 + comment : 0 + code : 0 + nFiles : 0 + same : + blank : 1 + comment : 0 + code : 5 + nFiles : 0 + modified : + blank : 0 + comment : 0 + code : 0 + nFiles : 0 + removed : + blank : 0 + comment : 0 + code : 0 + nFiles : 0 diff --git a/tests/outputs/issues/713/results.yaml b/tests/outputs/issues/713/results.yaml new file mode 100644 index 00000000..8f6699a9 --- /dev/null +++ b/tests/outputs/issues/713/results.yaml @@ -0,0 +1,18 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + n_files : 1 + n_lines : 8 + report_file : /home/al/git-cloc/tests/outputs/issues/713/results.yaml +'C++' : + nFiles: 1 + blank: 0 + comment: 2 + code: 6 +SUM: + blank: 0 + comment: 2 + code: 6 + nFiles: 1 diff --git a/tests/outputs/issues/720/results.yaml b/tests/outputs/issues/720/results.yaml new file mode 100644 index 00000000..9352af5f --- /dev/null +++ b/tests/outputs/issues/720/results.yaml @@ -0,0 +1,31 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.0102310180664062 + n_files : 3 + n_lines : 126 + files_per_second : 293.225950782998 + lines_per_second : 12315.4899328859 + report_file : ../../../outputs/issues/720/results.yaml +'../../Lanczos.m' : + blank: 0 + comment: 0 + code: 48 + language: MATLAB +'../../qsort_demo.m' : + blank: 11 + comment: 11 + code: 25 + language: Objective-C +'../../matlab_line_colors.m' : + blank: 3 + comment: 10 + code: 18 + language: MATLAB +SUM: + blank: 14 + comment: 21 + code: 91 + nFiles: 3 diff --git a/tests/outputs/issues/722/results_1.yaml b/tests/outputs/issues/722/results_1.yaml new file mode 100644 index 00000000..0e0dd75f --- /dev/null +++ b/tests/outputs/issues/722/results_1.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00737595558166504 + n_files : 1 + n_lines : 7 + files_per_second : 135.575653747939 + lines_per_second : 949.029576235576 + report_file : /home/al/git-cloc/tests/outputs/issues/722/results_1.yaml +'./hello.f90' : + blank: 0 + comment: 3 + code: 4 + language: Fortran 90 +SUM: + blank: 0 + comment: 3 + code: 4 + nFiles: 1 diff --git a/tests/outputs/linker.ld.yaml b/tests/outputs/linker.ld.yaml new file mode 100644 index 00000000..5f4f4317 --- /dev/null +++ b/tests/outputs/linker.ld.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00527691841125488 + n_files : 1 + n_lines : 260 + files_per_second : 189.504540731035 + lines_per_second : 49271.1805900691 + report_file : results.yaml +'Linker Script' : + nFiles: 1 + blank: 3 + comment: 60 + code: 197 +SUM: + blank: 3 + comment: 60 + code: 197 + nFiles: 1 diff --git a/tests/outputs/poly_constructor.jai.yaml b/tests/outputs/poly_constructor.jai.yaml new file mode 100644 index 00000000..5522d172 --- /dev/null +++ b/tests/outputs/poly_constructor.jai.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00720787048339844 + n_files : 1 + n_lines : 29 + files_per_second : 138.737232071977 + lines_per_second : 4023.37973008732 + report_file : ../outputs/poly_constructor.jai.yaml +'Jai' : + nFiles: 1 + blank: 4 + comment: 7 + code: 18 +SUM: + blank: 4 + comment: 7 + code: 18 + nFiles: 1 diff --git a/tests/outputs/ring.pony.1.yaml b/tests/outputs/ring.pony.1.yaml new file mode 100644 index 00000000..9ed5ccf1 --- /dev/null +++ b/tests/outputs/ring.pony.1.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.00724482536315918 + n_files : 1 + n_lines : 132 + files_per_second : 138.0295521111 + lines_per_second : 18219.9008786652 + report_file : ../outputs/ring.pony.1.yaml +'Pony' : + nFiles: 1 + blank: 23 + comment: 4 + code: 105 +SUM: + blank: 23 + comment: 4 + code: 105 + nFiles: 1 diff --git a/tests/outputs/ring.pony.2.yaml b/tests/outputs/ring.pony.2.yaml new file mode 100644 index 00000000..90d9221d --- /dev/null +++ b/tests/outputs/ring.pony.2.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.00731205940246582 + n_files : 1 + n_lines : 132 + files_per_second : 136.760376927842 + lines_per_second : 18052.3697544752 + report_file : ../outputs/ring.pony.2.yaml +'Pony' : + nFiles: 1 + blank: 23 + comment: 43 + code: 66 +SUM: + blank: 23 + comment: 43 + code: 66 + nFiles: 1 diff --git a/tests/outputs/toml.pest.yaml b/tests/outputs/toml.pest.yaml new file mode 100644 index 00000000..066de5bb --- /dev/null +++ b/tests/outputs/toml.pest.yaml @@ -0,0 +1,20 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.95 + elapsed_seconds : 0.00414586067199707 + n_files : 1 + n_lines : 76 + files_per_second : 241.204439588245 + lines_per_second : 18331.5374087067 +'Pest' : + nFiles: 1 + blank: 16 + comment: 9 + code: 51 +SUM: + blank: 16 + comment: 9 + code: 51 + nFiles: 1 diff --git a/tests/outputs/vinos.nlogo.yaml b/tests/outputs/vinos.nlogo.yaml new file mode 100644 index 00000000..c6bd65fe --- /dev/null +++ b/tests/outputs/vinos.nlogo.yaml @@ -0,0 +1,21 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 1.97 + elapsed_seconds : 0.00728893280029297 + n_files : 1 + n_lines : 93 + files_per_second : 137.19429543373 + lines_per_second : 12759.0694753369 + report_file : ../outputs/vinos.nlogo.yaml +'NetLogo' : + nFiles: 1 + blank: 17 + comment: 14 + code: 62 +SUM: + blank: 17 + comment: 14 + code: 62 + nFiles: 1