mirror of
https://github.com/XAMPPRocky/tokei
synced 2024-08-28 19:59:31 +00:00
ICE error
This commit is contained in:
parent
77c52b4aea
commit
bc83358d82
158
Cargo.lock
generated
158
Cargo.lock
generated
|
@ -6,6 +6,12 @@ dependencies = [
|
||||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"maplit 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"maplit 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_cbor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_codegen 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_yaml 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -14,11 +20,24 @@ name = "ansi_term"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aster"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "0.3.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.5.1"
|
version = "2.5.1"
|
||||||
|
@ -60,11 +79,48 @@ name = "libc"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maplit"
|
name = "maplit"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num"
|
||||||
|
version = "0.1.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-iter"
|
||||||
|
version = "0.1.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.1.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
|
@ -73,6 +129,24 @@ dependencies = [
|
||||||
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quasi"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quasi_codegen"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"aster 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.3.14"
|
version = "0.3.14"
|
||||||
|
@ -91,16 +165,100 @@ dependencies = [
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-serialize"
|
||||||
|
version = "0.3.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_cbor"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_codegen"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"aster 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quasi 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quasi_codegen 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"serde 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"yaml-rust 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syntex"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"syntex_syntax 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syntex_syntax"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "term"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
|
27
Cargo.toml
27
Cargo.toml
|
@ -10,16 +10,31 @@ homepage = "https://aaronepower.github.io/tokei/"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
description = "Count code, quickly."
|
description = "Count code, quickly."
|
||||||
|
build = "src/build.rs"
|
||||||
|
|
||||||
[profile.dev]
|
# For building serde in stable.
|
||||||
debug = true
|
[build-dependencies]
|
||||||
|
serde_codegen = "*"
|
||||||
[profile.release]
|
syntex = "*"
|
||||||
opt-level = 3
|
|
||||||
|
|
||||||
|
# Dependencies, and why they are used.
|
||||||
|
# - Clap: For CLI argument parsing.
|
||||||
|
# - Glob: When a user passes in a ./*.rs path.
|
||||||
|
# - Maplit: Cleaner initialization of the language map.
|
||||||
|
# - Rayon: Parallelization of language analysation.
|
||||||
|
# - Rustc-serialize: Converting String to hex, for CBOR.
|
||||||
|
# - Serde: Converting Language struct to other formats.
|
||||||
|
# - Serde_cbor: To CBOR. http://cbor.io/
|
||||||
|
# - Serde_json: To JSON. http://json.org/
|
||||||
|
# - Serde_yaml: To YAML. http://yaml.org/
|
||||||
|
# - Walkdir: Handling recursively reading directories across Windows, OSX, and UNIX.
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = {version = "2.5.1", features = ["yaml"]}
|
clap = {version = "2.5.1", features = ["yaml"]}
|
||||||
glob = "0.2.11"
|
glob = "0.2.11"
|
||||||
maplit = "0.1.3"
|
maplit = "0.1.3"
|
||||||
walkdir = "0.1.5"
|
|
||||||
rayon = "0.3.1"
|
rayon = "0.3.1"
|
||||||
|
serde = "*"
|
||||||
|
serde_cbor = "*"
|
||||||
|
serde_json = "*"
|
||||||
|
serde_yaml = "*"
|
||||||
|
walkdir = "0.1.5"
|
||||||
|
|
4
cli.yml
4
cli.yml
|
@ -40,10 +40,10 @@ args:
|
||||||
short: i
|
short: i
|
||||||
long: input
|
long: input
|
||||||
takes_value: true
|
takes_value: true
|
||||||
help: "Gives statistics for Tokei to start with Accepted formats: JSON"
|
help: "Gives statistics from a previous tokei run."
|
||||||
- output:
|
- output:
|
||||||
short: o
|
short: o
|
||||||
long: output
|
long: output
|
||||||
takes_value: true
|
takes_value: true
|
||||||
help: Outputs Tokei in a specific format.
|
help: Outputs Tokei in a specific format.
|
||||||
possible_values: [csv, json, xml, yml]
|
possible_values: [cbor, json, yaml]
|
||||||
|
|
17
src/build.rs
Normal file
17
src/build.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
extern crate syntex;
|
||||||
|
extern crate serde_codegen;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
|
||||||
|
let src = Path::new("src/main.rs.in");
|
||||||
|
let dst = Path::new(&out_dir).join("main.rs");
|
||||||
|
|
||||||
|
let mut registry = syntex::Registry::new();
|
||||||
|
|
||||||
|
serde_codegen::register(&mut registry);
|
||||||
|
registry.expand("", &src, &dst).unwrap();
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub const CLEAR: &'static str = " \r";
|
||||||
pub const ROW: &'static str = "-------------------------------------------------------------------------------";
|
pub const ROW: &'static str = "-------------------------------------------------------------------------------";
|
||||||
pub const BLANKS: &'static str = "blanks";
|
pub const BLANKS: &'static str = "blanks";
|
||||||
pub const COMMENTS: &'static str = "comments";
|
pub const COMMENTS: &'static str = "comments";
|
||||||
|
|
103
src/fsutil.rs
103
src/fsutil.rs
|
@ -6,11 +6,16 @@ use std::collections::BTreeMap;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
|
use serde_cbor;
|
||||||
|
use serde_json;
|
||||||
|
use serde_yaml;
|
||||||
use walkdir::{WalkDir, WalkDirIterator};
|
use walkdir::{WalkDir, WalkDirIterator};
|
||||||
|
|
||||||
use language::{Language, LanguageName};
|
use language::Language;
|
||||||
use language::LanguageName::*;
|
use language_name::LanguageName;
|
||||||
|
use language_name::LanguageName::*;
|
||||||
|
|
||||||
pub fn contains_comments(file: &str, comment: &str, comment_end: &str) -> bool {
|
pub fn contains_comments(file: &str, comment: &str, comment_end: &str) -> bool {
|
||||||
let mut in_comments: usize = 0;
|
let mut in_comments: usize = 0;
|
||||||
|
@ -129,112 +134,76 @@ pub fn get_language<P: AsRef<Path>>(entry: P) -> Option<LanguageName> {
|
||||||
if let Some(extension) = get_extension(entry) {
|
if let Some(extension) = get_extension(entry) {
|
||||||
match &*extension {
|
match &*extension {
|
||||||
"as" => Some(ActionScript),
|
"as" => Some(ActionScript),
|
||||||
"bash" => Some(Bash),
|
"bash" | "sh" => Some(Bash),
|
||||||
"bat" => Some(Batch),
|
"bat" | "btm" | "cmd" => Some(Batch),
|
||||||
"btm" => Some(Batch),
|
"c" | "ec" | "pgc" => Some(C),
|
||||||
"c" => Some(C),
|
"cc" | "cpp" | "cxx" | "c++" | "pcc" => Some(Cpp),
|
||||||
"cc" => Some(Cpp),
|
|
||||||
"cfc" => Some(ColdFusionScript),
|
"cfc" => Some(ColdFusionScript),
|
||||||
"cfm" => Some(ColdFusion),
|
"cfm" => Some(ColdFusion),
|
||||||
"clj" => Some(Clojure),
|
"clj" => Some(Clojure),
|
||||||
"cmd" => Some(Batch),
|
|
||||||
"coffee" => Some(CoffeeScript),
|
"coffee" => Some(CoffeeScript),
|
||||||
"cs" => Some(CSharp),
|
"cs" => Some(CSharp),
|
||||||
"csh" => Some(CShell),
|
"csh" => Some(CShell),
|
||||||
"css" => Some(Css),
|
"css" => Some(Css),
|
||||||
"cpp" => Some(Cpp),
|
|
||||||
"cxx" => Some(Cpp),
|
|
||||||
"c++" => Some(Cpp),
|
|
||||||
"d" => Some(D),
|
"d" => Some(D),
|
||||||
"dart" => Some(Dart),
|
"dart" => Some(Dart),
|
||||||
"dts" => Some(DeviceTree),
|
"dts" | "dtsi" => Some(DeviceTree),
|
||||||
"dtsi" => Some(DeviceTree),
|
"el" | "lisp" | "lsp" | "sc" => Some(Lisp),
|
||||||
"ec" => Some(C),
|
"erl" | "hrl" => Some(Erlang),
|
||||||
"el" => Some(Lisp),
|
"f" | "for" | "ftn" | "f77" | "pfo" => Some(FortranLegacy),
|
||||||
"erl" => Some(Erlang),
|
"f03" | "f08" | "f90" | "f95" => Some(FortranModern),
|
||||||
"f" => Some(FortranLegacy),
|
|
||||||
"for" => Some(FortranLegacy),
|
|
||||||
"ftn" => Some(FortranLegacy),
|
|
||||||
"f03" => Some(FortranModern),
|
|
||||||
"f08" => Some(FortranModern),
|
|
||||||
"f77" => Some(FortranLegacy),
|
|
||||||
"f90" => Some(FortranModern),
|
|
||||||
"f95" => Some(FortranModern),
|
|
||||||
"go" => Some(Go),
|
"go" => Some(Go),
|
||||||
"h" => Some(CHeader),
|
"h" => Some(CHeader),
|
||||||
"hh" => Some(CppHeader),
|
"hh" | "hpp" | "hxx" => Some(CppHeader),
|
||||||
"hpp" => Some(CppHeader),
|
|
||||||
"hrl" => Some(Erlang),
|
|
||||||
"hs" => Some(Haskell),
|
"hs" => Some(Haskell),
|
||||||
"html" => Some(Html),
|
"html" => Some(Html),
|
||||||
"hxx" => Some(CppHeader),
|
"idr" | "lidr" => Some(Idris),
|
||||||
"idr" => Some(Idris),
|
|
||||||
"jai" => Some(Jai),
|
"jai" => Some(Jai),
|
||||||
"java" => Some(Java),
|
"java" => Some(Java),
|
||||||
"jl" => Some(Julia),
|
"jl" => Some(Julia),
|
||||||
"js" => Some(JavaScript),
|
"js" => Some(JavaScript),
|
||||||
"json" => Some(Json),
|
"json" => Some(Json),
|
||||||
"jsx" => Some(Jsx),
|
"jsx" => Some(Jsx),
|
||||||
"kt" => Some(Kotlin),
|
"kt" | "kts" => Some(Kotlin),
|
||||||
"kts" => Some(Kotlin),
|
|
||||||
"lds" => Some(LinkerScript),
|
"lds" => Some(LinkerScript),
|
||||||
"less" => Some(Less),
|
"less" => Some(Less),
|
||||||
"lidr" => Some(Idris),
|
|
||||||
"lisp" => Some(Lisp),
|
|
||||||
"lsp" => Some(Lisp),
|
|
||||||
"lua" => Some(Lua),
|
"lua" => Some(Lua),
|
||||||
"m" => Some(ObjectiveC),
|
"m" => Some(ObjectiveC),
|
||||||
"markdown" => Some(Markdown),
|
"markdown" | "md" => Some(Markdown),
|
||||||
"md" => Some(Markdown),
|
"ml" | "mli" => Some(OCaml),
|
||||||
"ml" => Some(OCaml),
|
|
||||||
"mli" => Some(OCaml),
|
|
||||||
"mm" => Some(ObjectiveCpp),
|
"mm" => Some(ObjectiveCpp),
|
||||||
"makefile" => Some(Makefile),
|
"makefile" => Some(Makefile),
|
||||||
"mustache" => Some(Mustache),
|
"mustache" => Some(Mustache),
|
||||||
"nim" => Some(Nim),
|
"nim" => Some(Nim),
|
||||||
"nb" => Some(Wolfram),
|
"nb" | "wl" => Some(Wolfram),
|
||||||
"oz" => Some(Oz),
|
"oz" => Some(Oz),
|
||||||
"p" => Some(Prolog),
|
"p" | "pro" => Some(Prolog),
|
||||||
"pas" => Some(Pascal),
|
"pas" => Some(Pascal),
|
||||||
"pfo" => Some(FortranLegacy),
|
|
||||||
"pcc" => Some(Cpp),
|
|
||||||
"php" => Some(Php),
|
"php" => Some(Php),
|
||||||
"pl" => Some(Perl),
|
"pl" => Some(Perl),
|
||||||
"pro" => Some(Prolog),
|
|
||||||
"qcl" => Some(Qcl),
|
"qcl" => Some(Qcl),
|
||||||
"text" => Some(Text),
|
"text" | "txt" => Some(Text),
|
||||||
"txt" => Some(Text),
|
|
||||||
"pgc" => Some(C),
|
|
||||||
"polly" => Some(Polly),
|
"polly" => Some(Polly),
|
||||||
"proto" => Some(Protobuf),
|
"proto" => Some(Protobuf),
|
||||||
"py" => Some(Python),
|
"py" => Some(Python),
|
||||||
"r" => Some(R),
|
"r" => Some(R),
|
||||||
"rake" => Some(Ruby),
|
"rake" | "rb" => Some(Ruby),
|
||||||
"rb" => Some(Ruby),
|
|
||||||
"rhtml" => Some(RubyHtml),
|
"rhtml" => Some(RubyHtml),
|
||||||
"rs" => Some(Rust),
|
"rs" => Some(Rust),
|
||||||
"s" => Some(Assembly),
|
"s" => Some(Assembly),
|
||||||
"sass" => Some(Sass),
|
"sass" | "scss" => Some(Sass),
|
||||||
"sc" => Some(Lisp),
|
|
||||||
"scss" => Some(Sass),
|
|
||||||
"scala" => Some(Scala),
|
"scala" => Some(Scala),
|
||||||
"sh" => Some(Bash),
|
|
||||||
"sml" => Some(Sml),
|
"sml" => Some(Sml),
|
||||||
"sql" => Some(Sql),
|
"sql" => Some(Sql),
|
||||||
"swift" => Some(Swift),
|
"swift" => Some(Swift),
|
||||||
"tex" => Some(Tex),
|
"tex" | "sty" => Some(Tex),
|
||||||
"sty" => Some(Tex),
|
|
||||||
"toml" => Some(Toml),
|
"toml" => Some(Toml),
|
||||||
"ts" => Some(TypeScript),
|
"ts" => Some(TypeScript),
|
||||||
"uc" => Some(UnrealScript),
|
"uc" | "uci" | "upkg" => Some(UnrealScript),
|
||||||
"uci" => Some(UnrealScript),
|
|
||||||
"upkg" => Some(UnrealScript),
|
|
||||||
"v" => Some(Coq),
|
"v" => Some(Coq),
|
||||||
"vim" => Some(VimScript),
|
"vim" => Some(VimScript),
|
||||||
"wl" => Some(Wolfram),
|
|
||||||
"xml" => Some(Xml),
|
"xml" => Some(Xml),
|
||||||
"yaml" => Some(Yaml),
|
"yaml" | "yml" => Some(Yaml),
|
||||||
"yml" => Some(Yaml),
|
|
||||||
"zsh" => Some(Zsh),
|
"zsh" => Some(Zsh),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -243,6 +212,20 @@ pub fn get_language<P: AsRef<Path>>(entry: P) -> Option<LanguageName> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn convert_input(contents: &[u8]) -> Option<BTreeMap<LanguageName, Language>> {
|
||||||
|
if contents.is_empty() {
|
||||||
|
None
|
||||||
|
} else if let Ok(result) = serde_json::from_slice(contents) {
|
||||||
|
Some(result)
|
||||||
|
} else if let Ok(result) = serde_yaml::from_slice(contents) {
|
||||||
|
Some(result)
|
||||||
|
} else if let Ok(result) = serde_cbor::from_slice(contents) {
|
||||||
|
Some(result)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code, unused_imports)]
|
#[allow(dead_code, unused_imports)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
201
src/language.rs
201
src/language.rs
|
@ -2,23 +2,27 @@
|
||||||
// Use of this source code is governed by the MIT/APACHE2.0 license that can be
|
// Use of this source code is governed by the MIT/APACHE2.0 license that can be
|
||||||
// found in the LICENCE-{APACHE - MIT} file.
|
// found in the LICENCE-{APACHE - MIT} file.
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::ops::AddAssign;
|
use std::ops::AddAssign;
|
||||||
|
|
||||||
use consts::*;
|
use consts::*;
|
||||||
|
use language_name::LanguageName;
|
||||||
use stats::Stats;
|
use stats::Stats;
|
||||||
|
|
||||||
#[derive(Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Debug, Default, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub struct Language {
|
pub struct Language {
|
||||||
pub blanks: usize,
|
pub blanks: usize,
|
||||||
pub code: usize,
|
pub code: usize,
|
||||||
pub comments: usize,
|
pub comments: usize,
|
||||||
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub files: Vec<PathBuf>,
|
pub files: Vec<PathBuf>,
|
||||||
pub stats: Vec<Stats>,
|
pub stats: Vec<Stats>,
|
||||||
pub lines: usize,
|
pub lines: usize,
|
||||||
|
#[serde(skip_deserializing,skip_serializing, rename(serialize="lineComment"))]
|
||||||
pub line_comment: &'static str,
|
pub line_comment: &'static str,
|
||||||
|
#[serde(skip_deserializing,skip_serializing, rename(serialize="multiLine"))]
|
||||||
pub multi_line: &'static str,
|
pub multi_line: &'static str,
|
||||||
|
#[serde(skip_deserializing,skip_serializing, rename(serialize="multiLineEnd"))]
|
||||||
pub multi_line_end: &'static str,
|
pub multi_line_end: &'static str,
|
||||||
pub total_files: usize,
|
pub total_files: usize,
|
||||||
}
|
}
|
||||||
|
@ -56,7 +60,7 @@ impl Language {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_blank() -> Self {
|
pub fn new_blank() -> Self {
|
||||||
Language { ..Self::default() }
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_func() -> Self {
|
pub fn new_func() -> Self {
|
||||||
|
@ -120,10 +124,18 @@ impl Language {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AddAssign for Language {
|
||||||
// Adding languages to the raw total_files.
|
fn add_assign(&mut self, rhs: Self) {
|
||||||
impl<'a> AddAssign<&'a Language> for Language {
|
self.total_files += rhs.total_files;
|
||||||
fn add_assign(&mut self, rhs: &Self) {
|
self.lines += rhs.lines;
|
||||||
|
self.comments += rhs.comments;
|
||||||
|
self.blanks += rhs.blanks;
|
||||||
|
self.code += rhs.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> AddAssign<&'a Language> for Language {
|
||||||
|
fn add_assign(&mut self, rhs: &'a Self) {
|
||||||
self.total_files += rhs.total_files;
|
self.total_files += rhs.total_files;
|
||||||
self.lines += rhs.lines;
|
self.lines += rhs.lines;
|
||||||
self.comments += rhs.comments;
|
self.comments += rhs.comments;
|
||||||
|
@ -132,7 +144,6 @@ impl<'a> AddAssign<&'a Language> for Language {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adding languages to the raw total_files.
|
|
||||||
impl<'a> AddAssign<&'a mut Language> for Language {
|
impl<'a> AddAssign<&'a mut Language> for Language {
|
||||||
fn add_assign(&mut self, rhs: &mut Self) {
|
fn add_assign(&mut self, rhs: &mut Self) {
|
||||||
self.total_files += rhs.total_files;
|
self.total_files += rhs.total_files;
|
||||||
|
@ -154,168 +165,12 @@ impl AddAssign<Stats> for Language {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl AddAssign<BTreeMap<LanguageName, Language>> for BTreeMap<LanguageName, Language> {
|
||||||
#[derive(Debug, Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
|
// fn add_assign(&mut self, rhs: BTreeMap<LanguageName, Language>) {
|
||||||
pub enum LanguageName {
|
// for (name, rhs_language) in rhs {
|
||||||
ActionScript,
|
// if let Some(language) = self.get_mut(name) {
|
||||||
Assembly,
|
// language += rhs_language;
|
||||||
Bash,
|
// }
|
||||||
Batch,
|
// }
|
||||||
C,
|
// }
|
||||||
CHeader,
|
// }
|
||||||
Clojure,
|
|
||||||
CoffeeScript,
|
|
||||||
ColdFusion,
|
|
||||||
ColdFusionScript,
|
|
||||||
Coq,
|
|
||||||
Cpp,
|
|
||||||
CppHeader,
|
|
||||||
CSharp,
|
|
||||||
CShell,
|
|
||||||
Css,
|
|
||||||
D,
|
|
||||||
Dart,
|
|
||||||
DeviceTree,
|
|
||||||
Erlang,
|
|
||||||
FortranLegacy,
|
|
||||||
FortranModern,
|
|
||||||
Go,
|
|
||||||
Haskell,
|
|
||||||
Html,
|
|
||||||
Idris,
|
|
||||||
Jai,
|
|
||||||
Java,
|
|
||||||
JavaScript,
|
|
||||||
Julia,
|
|
||||||
Json,
|
|
||||||
Jsx,
|
|
||||||
Kotlin,
|
|
||||||
Less,
|
|
||||||
LinkerScript,
|
|
||||||
Lisp,
|
|
||||||
Lua,
|
|
||||||
Makefile,
|
|
||||||
Markdown,
|
|
||||||
Mustache,
|
|
||||||
Nim,
|
|
||||||
ObjectiveC,
|
|
||||||
ObjectiveCpp,
|
|
||||||
OCaml,
|
|
||||||
Oz,
|
|
||||||
Pascal,
|
|
||||||
Perl,
|
|
||||||
Polly,
|
|
||||||
Php,
|
|
||||||
Protobuf,
|
|
||||||
Prolog,
|
|
||||||
Python,
|
|
||||||
Qcl,
|
|
||||||
R,
|
|
||||||
Ruby,
|
|
||||||
RubyHtml,
|
|
||||||
Rust,
|
|
||||||
Sass,
|
|
||||||
Scala,
|
|
||||||
Sml,
|
|
||||||
Sql,
|
|
||||||
Swift,
|
|
||||||
Tex,
|
|
||||||
Text,
|
|
||||||
Toml,
|
|
||||||
TypeScript,
|
|
||||||
VimScript,
|
|
||||||
UnrealScript,
|
|
||||||
Wolfram,
|
|
||||||
Xml,
|
|
||||||
Yaml,
|
|
||||||
Zsh,
|
|
||||||
__Total,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LanguageName {
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
use self::LanguageName::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
ActionScript => "ActionScript",
|
|
||||||
Assembly => "Assembly",
|
|
||||||
Bash => "BASH",
|
|
||||||
Batch => "Batch",
|
|
||||||
C => "C",
|
|
||||||
CHeader => "C Header",
|
|
||||||
Clojure => "Clojure",
|
|
||||||
CoffeeScript => "CoffeeScript",
|
|
||||||
ColdFusion => "ColdFusion",
|
|
||||||
ColdFusionScript => "ColdFusion CFScript",
|
|
||||||
Coq => "Coq",
|
|
||||||
Cpp => "C++",
|
|
||||||
CppHeader => "C++ Header",
|
|
||||||
CSharp => "C#",
|
|
||||||
CShell => "C Shell",
|
|
||||||
Css => "CSS",
|
|
||||||
D => "D",
|
|
||||||
Dart => "Dart",
|
|
||||||
DeviceTree => "Device Tree",
|
|
||||||
Erlang => "Erlang",
|
|
||||||
FortranLegacy => "FORTRAN Legacy",
|
|
||||||
FortranModern => "FORTRAN Modern",
|
|
||||||
Go => "Go",
|
|
||||||
Haskell => "Haskell",
|
|
||||||
Html => "HTML",
|
|
||||||
Idris => "Idris",
|
|
||||||
Jai => "JAI",
|
|
||||||
Java => "Java",
|
|
||||||
JavaScript => "JavaScript",
|
|
||||||
Json => "JSON",
|
|
||||||
Jsx => "JSX",
|
|
||||||
Julia => "Julia",
|
|
||||||
Kotlin => "Kotlin",
|
|
||||||
Less => "LESS",
|
|
||||||
LinkerScript => "LD Script",
|
|
||||||
Lisp => "LISP",
|
|
||||||
Lua => "Lua",
|
|
||||||
Makefile => "Makefile",
|
|
||||||
Markdown => "Markdown",
|
|
||||||
Mustache => "Mustache",
|
|
||||||
Nim => "Nim",
|
|
||||||
ObjectiveC => "Objective C",
|
|
||||||
ObjectiveCpp => "Objective C++",
|
|
||||||
OCaml => "OCaml",
|
|
||||||
Oz => "Oz",
|
|
||||||
Pascal => "Pascal",
|
|
||||||
Perl => "Perl",
|
|
||||||
Polly => "Polly",
|
|
||||||
Php => "PHP",
|
|
||||||
Protobuf => "Protocol Buffers",
|
|
||||||
Prolog => "Prolog",
|
|
||||||
Python => "Python",
|
|
||||||
Qcl => "QCL",
|
|
||||||
R => "R",
|
|
||||||
Ruby => "Ruby",
|
|
||||||
RubyHtml => "Ruby HTML",
|
|
||||||
Rust => "Rust",
|
|
||||||
Sass => "Sass",
|
|
||||||
Scala => "Scala",
|
|
||||||
Sml => "Standard ML",
|
|
||||||
Sql => "SQL",
|
|
||||||
Swift => "Swift",
|
|
||||||
Tex => "TeX",
|
|
||||||
Text => "Plain Text",
|
|
||||||
Toml => "TOML",
|
|
||||||
TypeScript => "TypeScript",
|
|
||||||
UnrealScript => "Unreal Script",
|
|
||||||
VimScript => "Vim Script",
|
|
||||||
Wolfram => "Wolfram",
|
|
||||||
Xml => "XML",
|
|
||||||
Yaml => "YAML",
|
|
||||||
Zsh => "Zsh",
|
|
||||||
__Total => "Total",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for LanguageName {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{}", self.name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
166
src/language_name.rs
Normal file
166
src/language_name.rs
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
|
pub enum LanguageName {
|
||||||
|
ActionScript,
|
||||||
|
Assembly,
|
||||||
|
Bash,
|
||||||
|
Batch,
|
||||||
|
C,
|
||||||
|
CHeader,
|
||||||
|
Clojure,
|
||||||
|
CoffeeScript,
|
||||||
|
ColdFusion,
|
||||||
|
ColdFusionScript,
|
||||||
|
Coq,
|
||||||
|
Cpp,
|
||||||
|
CppHeader,
|
||||||
|
CSharp,
|
||||||
|
CShell,
|
||||||
|
Css,
|
||||||
|
D,
|
||||||
|
Dart,
|
||||||
|
DeviceTree,
|
||||||
|
Erlang,
|
||||||
|
FortranLegacy,
|
||||||
|
FortranModern,
|
||||||
|
Go,
|
||||||
|
Haskell,
|
||||||
|
Html,
|
||||||
|
Idris,
|
||||||
|
Jai,
|
||||||
|
Java,
|
||||||
|
JavaScript,
|
||||||
|
Julia,
|
||||||
|
Json,
|
||||||
|
Jsx,
|
||||||
|
Kotlin,
|
||||||
|
Less,
|
||||||
|
LinkerScript,
|
||||||
|
Lisp,
|
||||||
|
Lua,
|
||||||
|
Makefile,
|
||||||
|
Markdown,
|
||||||
|
Mustache,
|
||||||
|
Nim,
|
||||||
|
ObjectiveC,
|
||||||
|
ObjectiveCpp,
|
||||||
|
OCaml,
|
||||||
|
Oz,
|
||||||
|
Pascal,
|
||||||
|
Perl,
|
||||||
|
Polly,
|
||||||
|
Php,
|
||||||
|
Protobuf,
|
||||||
|
Prolog,
|
||||||
|
Python,
|
||||||
|
Qcl,
|
||||||
|
R,
|
||||||
|
Ruby,
|
||||||
|
RubyHtml,
|
||||||
|
Rust,
|
||||||
|
Sass,
|
||||||
|
Scala,
|
||||||
|
Sml,
|
||||||
|
Sql,
|
||||||
|
Swift,
|
||||||
|
Tex,
|
||||||
|
Text,
|
||||||
|
Toml,
|
||||||
|
TypeScript,
|
||||||
|
VimScript,
|
||||||
|
UnrealScript,
|
||||||
|
Wolfram,
|
||||||
|
Xml,
|
||||||
|
Yaml,
|
||||||
|
Zsh,
|
||||||
|
__Total,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LanguageName {
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
use self::LanguageName::*;
|
||||||
|
|
||||||
|
match *self {
|
||||||
|
ActionScript => "ActionScript",
|
||||||
|
Assembly => "Assembly",
|
||||||
|
Bash => "BASH",
|
||||||
|
Batch => "Batch",
|
||||||
|
C => "C",
|
||||||
|
CHeader => "C Header",
|
||||||
|
Clojure => "Clojure",
|
||||||
|
CoffeeScript => "CoffeeScript",
|
||||||
|
ColdFusion => "ColdFusion",
|
||||||
|
ColdFusionScript => "ColdFusion CFScript",
|
||||||
|
Coq => "Coq",
|
||||||
|
Cpp => "C++",
|
||||||
|
CppHeader => "C++ Header",
|
||||||
|
CSharp => "C#",
|
||||||
|
CShell => "C Shell",
|
||||||
|
Css => "CSS",
|
||||||
|
D => "D",
|
||||||
|
Dart => "Dart",
|
||||||
|
DeviceTree => "Device Tree",
|
||||||
|
Erlang => "Erlang",
|
||||||
|
FortranLegacy => "FORTRAN Legacy",
|
||||||
|
FortranModern => "FORTRAN Modern",
|
||||||
|
Go => "Go",
|
||||||
|
Haskell => "Haskell",
|
||||||
|
Html => "HTML",
|
||||||
|
Idris => "Idris",
|
||||||
|
Jai => "JAI",
|
||||||
|
Java => "Java",
|
||||||
|
JavaScript => "JavaScript",
|
||||||
|
Json => "JSON",
|
||||||
|
Jsx => "JSX",
|
||||||
|
Julia => "Julia",
|
||||||
|
Kotlin => "Kotlin",
|
||||||
|
Less => "LESS",
|
||||||
|
LinkerScript => "LD Script",
|
||||||
|
Lisp => "LISP",
|
||||||
|
Lua => "Lua",
|
||||||
|
Makefile => "Makefile",
|
||||||
|
Markdown => "Markdown",
|
||||||
|
Mustache => "Mustache",
|
||||||
|
Nim => "Nim",
|
||||||
|
ObjectiveC => "Objective C",
|
||||||
|
ObjectiveCpp => "Objective C++",
|
||||||
|
OCaml => "OCaml",
|
||||||
|
Oz => "Oz",
|
||||||
|
Pascal => "Pascal",
|
||||||
|
Perl => "Perl",
|
||||||
|
Polly => "Polly",
|
||||||
|
Php => "PHP",
|
||||||
|
Protobuf => "Protocol Buffers",
|
||||||
|
Prolog => "Prolog",
|
||||||
|
Python => "Python",
|
||||||
|
Qcl => "QCL",
|
||||||
|
R => "R",
|
||||||
|
Ruby => "Ruby",
|
||||||
|
RubyHtml => "Ruby HTML",
|
||||||
|
Rust => "Rust",
|
||||||
|
Sass => "Sass",
|
||||||
|
Scala => "Scala",
|
||||||
|
Sml => "Standard ML",
|
||||||
|
Sql => "SQL",
|
||||||
|
Swift => "Swift",
|
||||||
|
Tex => "TeX",
|
||||||
|
Text => "Plain Text",
|
||||||
|
Toml => "TOML",
|
||||||
|
TypeScript => "TypeScript",
|
||||||
|
UnrealScript => "Unreal Script",
|
||||||
|
VimScript => "Vim Script",
|
||||||
|
Wolfram => "Wolfram",
|
||||||
|
Xml => "XML",
|
||||||
|
Yaml => "YAML",
|
||||||
|
Zsh => "Zsh",
|
||||||
|
__Total => "Total",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LanguageName {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.name())
|
||||||
|
}
|
||||||
|
}
|
317
src/main.rs
317
src/main.rs
|
@ -1,316 +1,13 @@
|
||||||
// Copyright (c) 2015 Aaron Power
|
|
||||||
// Use of this source code is governed by the MIT/APACHE2.0 license that can be
|
|
||||||
// found in the LICENCE-{APACHE, MIT} file.
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
extern crate glob;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate maplit;
|
extern crate maplit;
|
||||||
extern crate glob;
|
|
||||||
extern crate walkdir;
|
|
||||||
extern crate rayon;
|
extern crate rayon;
|
||||||
#[macro_use]
|
extern crate serde;
|
||||||
mod macros;
|
extern crate serde_cbor;
|
||||||
mod consts;
|
extern crate serde_json;
|
||||||
mod fsutil;
|
extern crate serde_yaml;
|
||||||
mod language;
|
extern crate walkdir;
|
||||||
mod stats;
|
|
||||||
|
|
||||||
use std::io::Read;
|
include!(concat!(env!("OUT_DIR"), "/main.rs"));
|
||||||
use std::fs::File;
|
|
||||||
use std::thread;
|
|
||||||
use std::time::Duration;
|
|
||||||
use std::sync::mpsc::channel;
|
|
||||||
|
|
||||||
use clap::App;
|
|
||||||
use rayon::prelude::*;
|
|
||||||
|
|
||||||
use consts::*;
|
|
||||||
use fsutil::*;
|
|
||||||
use language::{Language, LanguageName};
|
|
||||||
use language::LanguageName::*;
|
|
||||||
use stats::Stats;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let yaml = load_yaml!("../cli.yml");
|
|
||||||
let matches = App::from_yaml(yaml).get_matches();
|
|
||||||
|
|
||||||
let files_option = matches.is_present(FILES);
|
|
||||||
let language_option = matches.is_present("languages");
|
|
||||||
|
|
||||||
// Languages are placed inside a BTreeMap, in order to print alphabetically by default
|
|
||||||
let mut languages = btreemap! {
|
|
||||||
ActionScript => Language::new_c(),
|
|
||||||
Assembly => Language::new_single(";"),
|
|
||||||
Bash => Language::new_hash(),
|
|
||||||
Batch => Language::new_single("REM"),
|
|
||||||
C => Language::new_c(),
|
|
||||||
CHeader => Language::new_c(),
|
|
||||||
Clojure => Language::new_single(";,#,#_"),
|
|
||||||
CoffeeScript => Language::new("#", "###", "###"),
|
|
||||||
ColdFusion => Language::new_multi("<!---", "--->"),
|
|
||||||
ColdFusionScript => Language::new_c(),
|
|
||||||
Coq => Language::new_func(),
|
|
||||||
Cpp => Language::new_c(),
|
|
||||||
CppHeader => Language::new_c(),
|
|
||||||
CSharp => Language::new_c(),
|
|
||||||
CShell => Language::new_hash(),
|
|
||||||
Css => Language::new_c(),
|
|
||||||
D => Language::new_c(),
|
|
||||||
Dart => Language::new_c(),
|
|
||||||
DeviceTree => Language::new_c(),
|
|
||||||
Erlang => Language::new_single("%"),
|
|
||||||
FortranLegacy => Language::new_single("c,C,!,*"),
|
|
||||||
FortranModern => Language::new_single("!"),
|
|
||||||
Go => Language::new_c(),
|
|
||||||
Haskell => Language::new_single("--"),
|
|
||||||
Html => Language::new_html(),
|
|
||||||
Idris => Language::new("--", "{-", "-}"),
|
|
||||||
Jai => Language::new_c(),
|
|
||||||
Java => Language::new_c(),
|
|
||||||
JavaScript => Language::new_c(),
|
|
||||||
Json => Language::new_blank(),
|
|
||||||
Jsx => Language::new_c(),
|
|
||||||
Julia => Language::new("#", "#=", "=#"),
|
|
||||||
Kotlin => Language::new_c(),
|
|
||||||
Less => Language::new_c(),
|
|
||||||
LinkerScript => Language::new_c(),
|
|
||||||
Lisp => Language::new(";", "#|", "|#"),
|
|
||||||
Lua => Language::new("--", "--[[", "]]"),
|
|
||||||
Makefile => Language::new_hash(),
|
|
||||||
Markdown => Language::new_blank(),
|
|
||||||
Mustache => Language::new_multi("{{!", "}}"),
|
|
||||||
Nim => Language::new_hash(),
|
|
||||||
ObjectiveC => Language::new_c(),
|
|
||||||
ObjectiveCpp => Language::new_c(),
|
|
||||||
OCaml => Language::new_func(),
|
|
||||||
Oz => Language::new_pro(),
|
|
||||||
Pascal => Language::new("//,(*", "{", "}"),
|
|
||||||
Perl => Language::new("#", "=", "=cut"),
|
|
||||||
Php => Language::new("#,//", "/*", "*/"),
|
|
||||||
Polly => Language::new_html(),
|
|
||||||
Prolog => Language::new_pro(),
|
|
||||||
Protobuf => Language::new_single("//"),
|
|
||||||
Python => Language::new("#", "'''", "'''"),
|
|
||||||
Qcl => Language::new_c(),
|
|
||||||
R => Language::new_hash(),
|
|
||||||
Ruby => Language::new("#", "=begin", "=end"),
|
|
||||||
RubyHtml => Language::new_html(),
|
|
||||||
Rust => Language::new("//,///,//!", "/*", "*/"),
|
|
||||||
Sass => Language::new_c(),
|
|
||||||
Sml => Language::new_func(),
|
|
||||||
Sql => Language::new("--", "/*", "*/"),
|
|
||||||
Swift => Language::new_c(),
|
|
||||||
Tex => Language::new_single("%"),
|
|
||||||
Text => Language::new_blank(),
|
|
||||||
Toml => Language::new_hash(),
|
|
||||||
TypeScript => Language::new_c(),
|
|
||||||
UnrealScript => Language::new_c(),
|
|
||||||
VimScript => Language::new_single("\""),
|
|
||||||
Wolfram => Language::new_func(),
|
|
||||||
Xml => Language::new_html(),
|
|
||||||
Yaml => Language::new_hash(),
|
|
||||||
Zsh => Language::new_hash(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Print every supported language.
|
|
||||||
if language_option {
|
|
||||||
for key in languages.keys() {
|
|
||||||
println!("{:<25}", key);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let paths = matches.values_of("input").unwrap();
|
|
||||||
|
|
||||||
let ignored_directories = {
|
|
||||||
let mut ignored_directories = vec![".git"];
|
|
||||||
if let Some(user_ignored) = matches.values_of("exclude") {
|
|
||||||
for ignored in user_ignored {
|
|
||||||
ignored_directories.push(ignored);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ignored_directories
|
|
||||||
};
|
|
||||||
|
|
||||||
let sort = if let Some(sort_by) = matches.value_of("sort") {
|
|
||||||
match &*sort_by.to_lowercase() {
|
|
||||||
BLANKS | CODE | COMMENTS | FILES | TOTAL => Some(sort_by.to_lowercase()),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("{}", ROW);
|
|
||||||
println!(" {:<12} {:>12} {:>12} {:>12} {:>12} {:>12}",
|
|
||||||
"Language",
|
|
||||||
"Files",
|
|
||||||
"Lines",
|
|
||||||
"Code",
|
|
||||||
"Comments",
|
|
||||||
"Blanks");
|
|
||||||
println!("{}", ROW);
|
|
||||||
|
|
||||||
get_all_files(paths, &mut languages, ignored_directories);
|
|
||||||
|
|
||||||
let mut total = Language::new_blank();
|
|
||||||
|
|
||||||
let mut languages: Vec<(LanguageName, Language)> = languages.into_iter().collect();
|
|
||||||
|
|
||||||
let (tx, rx) = channel();
|
|
||||||
let child = thread::spawn(move || {
|
|
||||||
loop {
|
|
||||||
if let Ok(_) = rx.try_recv() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
print!("\x1B[?25l");
|
|
||||||
print!(" Counting files. \r");
|
|
||||||
thread::sleep(Duration::from_millis(4));
|
|
||||||
print!(" Counting files..\r");
|
|
||||||
thread::sleep(Duration::from_millis(4));
|
|
||||||
print!(" Counting files...\r");
|
|
||||||
thread::sleep(Duration::from_millis(4));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
languages.par_iter_mut()
|
|
||||||
.for_each(|&mut (name, ref mut language)| {
|
|
||||||
if language.files.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
language.total_files = language.files.len();
|
|
||||||
let files: Vec<_> = language.files.drain(..).collect();
|
|
||||||
for file in files {
|
|
||||||
let mut contents = String::new();
|
|
||||||
let is_fortran = name == FortranModern || name == FortranLegacy;
|
|
||||||
let mut stats = Stats::new(opt_or_cont!(file.to_str()));
|
|
||||||
let _ = rs_or_cont!(rs_or_cont!(File::open(file))
|
|
||||||
.read_to_string(&mut contents));
|
|
||||||
|
|
||||||
let mut is_in_comments = false;
|
|
||||||
let lines = contents.lines();
|
|
||||||
|
|
||||||
|
|
||||||
if language.is_blank() {
|
|
||||||
stats.code += lines.count();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
'line: for line in lines {
|
|
||||||
let line = if is_fortran {
|
|
||||||
line
|
|
||||||
} else {
|
|
||||||
line.trim()
|
|
||||||
};
|
|
||||||
stats.lines += 1;
|
|
||||||
|
|
||||||
if line.trim().is_empty() {
|
|
||||||
stats.blanks += 1;
|
|
||||||
continue 'line;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !language.multi_line.is_empty() {
|
|
||||||
let multi_line = language.multi_line;
|
|
||||||
let multi_line_end = language.multi_line_end;
|
|
||||||
if line.starts_with(multi_line) ||
|
|
||||||
contains_comments(line, multi_line, multi_line_end) {
|
|
||||||
is_in_comments = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if is_in_comments {
|
|
||||||
if line.contains(language.multi_line_end) {
|
|
||||||
is_in_comments = false;
|
|
||||||
}
|
|
||||||
stats.comments += 1;
|
|
||||||
continue 'line;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !language.line_comment.is_empty() {
|
|
||||||
for single in language.line_comment.split(',') {
|
|
||||||
if line.starts_with(single) {
|
|
||||||
stats.comments += 1;
|
|
||||||
continue 'line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stats.code += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*language += stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
print!(" \r");
|
|
||||||
if !language.is_empty() {
|
|
||||||
if let None = sort {
|
|
||||||
if files_option {
|
|
||||||
language.print(name);
|
|
||||||
println!("{}", ROW);
|
|
||||||
|
|
||||||
for stat in &language.stats {
|
|
||||||
println!("{}", stat);
|
|
||||||
}
|
|
||||||
println!("{}", ROW);
|
|
||||||
} else {
|
|
||||||
language.print(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let _ = tx.send(());
|
|
||||||
let _ = child.join();
|
|
||||||
|
|
||||||
for &(_, ref language) in &languages {
|
|
||||||
if !language.is_empty() {
|
|
||||||
total += language;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(sort_category) = sort {
|
|
||||||
|
|
||||||
for &mut (_, ref mut language) in &mut languages {
|
|
||||||
match &*sort_category {
|
|
||||||
BLANKS => language.sort_by(BLANKS),
|
|
||||||
COMMENTS => language.sort_by(COMMENTS),
|
|
||||||
CODE => language.sort_by(CODE),
|
|
||||||
FILES => {}
|
|
||||||
TOTAL => language.sort_by(TOTAL),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match &*sort_category {
|
|
||||||
BLANKS => languages.sort_by(|a, b| b.1.blanks.cmp(&a.1.blanks)),
|
|
||||||
COMMENTS => languages.sort_by(|a, b| b.1.comments.cmp(&a.1.comments)),
|
|
||||||
CODE => languages.sort_by(|a, b| b.1.code.cmp(&a.1.code)),
|
|
||||||
FILES => languages.sort_by(|a, b| b.1.files.len().cmp(&a.1.files.len())),
|
|
||||||
TOTAL => languages.sort_by(|a, b| b.1.lines.cmp(&a.1.lines)),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
|
|
||||||
for (name, language) in languages {
|
|
||||||
if !language.is_empty() {
|
|
||||||
if !files_option {
|
|
||||||
language.print(name);
|
|
||||||
} else {
|
|
||||||
language.print(name);
|
|
||||||
println!("{}", ROW);
|
|
||||||
for file in &language.stats {
|
|
||||||
println!("{}", file);
|
|
||||||
}
|
|
||||||
println!("{}", ROW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !files_option {
|
|
||||||
println!("{}", ROW);
|
|
||||||
}
|
|
||||||
total.print(__Total);
|
|
||||||
println!("{}", ROW);
|
|
||||||
print!("\x1B[?25h\r");
|
|
||||||
}
|
|
||||||
|
|
364
src/main.rs.in
Normal file
364
src/main.rs.in
Normal file
|
@ -0,0 +1,364 @@
|
||||||
|
// Copyright (c) 2015 Aaron Power
|
||||||
|
// Use of this source code is governed by the MIT/APACHE2.0 license that can be
|
||||||
|
// found in the LICENCE-{APACHE, MIT} file.
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod macros;
|
||||||
|
mod consts;
|
||||||
|
mod fsutil;
|
||||||
|
mod language;
|
||||||
|
mod language_name;
|
||||||
|
mod stats;
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::sync::mpsc::channel;
|
||||||
|
|
||||||
|
use clap::App;
|
||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
|
use consts::*;
|
||||||
|
use fsutil::*;
|
||||||
|
use language::Language;
|
||||||
|
use language_name::LanguageName::*;
|
||||||
|
use stats::Stats;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let yaml = load_yaml!("../cli.yml");
|
||||||
|
let matches = App::from_yaml(yaml).get_matches();
|
||||||
|
|
||||||
|
let files_option = matches.is_present(FILES);
|
||||||
|
let input_option = matches.value_of("file_input");
|
||||||
|
let output_option = matches.value_of("output");
|
||||||
|
let language_option = matches.is_present("languages");
|
||||||
|
let sort_option = matches.value_of("sort");
|
||||||
|
let paths = matches.values_of("input").unwrap();
|
||||||
|
let ignored_directories = {
|
||||||
|
let mut ignored_directories = vec![".git"];
|
||||||
|
if let Some(user_ignored) = matches.values_of("exclude") {
|
||||||
|
for ignored in user_ignored {
|
||||||
|
ignored_directories.push(ignored);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ignored_directories
|
||||||
|
};
|
||||||
|
|
||||||
|
// Languages are placed inside a BTreeMap over a HashMap, in order to be printed alphabetically
|
||||||
|
// by default.
|
||||||
|
let mut languages = btreemap! {
|
||||||
|
ActionScript => Language::new_c(),
|
||||||
|
Assembly => Language::new_single(";"),
|
||||||
|
Bash => Language::new_hash(),
|
||||||
|
Batch => Language::new_single("REM"),
|
||||||
|
C => Language::new_c(),
|
||||||
|
CHeader => Language::new_c(),
|
||||||
|
Clojure => Language::new_single(";,#,#_"),
|
||||||
|
CoffeeScript => Language::new("#", "###", "###"),
|
||||||
|
ColdFusion => Language::new_multi("<!---", "--->"),
|
||||||
|
ColdFusionScript => Language::new_c(),
|
||||||
|
Coq => Language::new_func(),
|
||||||
|
Cpp => Language::new_c(),
|
||||||
|
CppHeader => Language::new_c(),
|
||||||
|
CSharp => Language::new_c(),
|
||||||
|
CShell => Language::new_hash(),
|
||||||
|
Css => Language::new_c(),
|
||||||
|
D => Language::new_c(),
|
||||||
|
Dart => Language::new_c(),
|
||||||
|
DeviceTree => Language::new_c(),
|
||||||
|
Erlang => Language::new_single("%"),
|
||||||
|
FortranLegacy => Language::new_single("c,C,!,*"),
|
||||||
|
FortranModern => Language::new_single("!"),
|
||||||
|
Go => Language::new_c(),
|
||||||
|
Haskell => Language::new_single("--"),
|
||||||
|
Html => Language::new_html(),
|
||||||
|
Idris => Language::new("--", "{-", "-}"),
|
||||||
|
Jai => Language::new_c(),
|
||||||
|
Java => Language::new_c(),
|
||||||
|
JavaScript => Language::new_c(),
|
||||||
|
Json => Language::new_blank(),
|
||||||
|
Jsx => Language::new_c(),
|
||||||
|
Julia => Language::new("#", "#=", "=#"),
|
||||||
|
Kotlin => Language::new_c(),
|
||||||
|
Less => Language::new_c(),
|
||||||
|
LinkerScript => Language::new_c(),
|
||||||
|
Lisp => Language::new(";", "#|", "|#"),
|
||||||
|
Lua => Language::new("--", "--[[", "]]"),
|
||||||
|
Makefile => Language::new_hash(),
|
||||||
|
Markdown => Language::new_blank(),
|
||||||
|
Mustache => Language::new_multi("{{!", "}}"),
|
||||||
|
Nim => Language::new_hash(),
|
||||||
|
ObjectiveC => Language::new_c(),
|
||||||
|
ObjectiveCpp => Language::new_c(),
|
||||||
|
OCaml => Language::new_func(),
|
||||||
|
Oz => Language::new_pro(),
|
||||||
|
Pascal => Language::new("//,(*", "{", "}"),
|
||||||
|
Perl => Language::new("#", "=", "=cut"),
|
||||||
|
Php => Language::new("#,//", "/*", "*/"),
|
||||||
|
Polly => Language::new_html(),
|
||||||
|
Prolog => Language::new_pro(),
|
||||||
|
Protobuf => Language::new_single("//"),
|
||||||
|
Python => Language::new("#", "'''", "'''"),
|
||||||
|
Qcl => Language::new_c(),
|
||||||
|
R => Language::new_hash(),
|
||||||
|
Ruby => Language::new("#", "=begin", "=end"),
|
||||||
|
RubyHtml => Language::new_html(),
|
||||||
|
Rust => Language::new("//,///,//!", "/*", "*/"),
|
||||||
|
Sass => Language::new_c(),
|
||||||
|
Sml => Language::new_func(),
|
||||||
|
Sql => Language::new("--", "/*", "*/"),
|
||||||
|
Swift => Language::new_c(),
|
||||||
|
Tex => Language::new_single("%"),
|
||||||
|
Text => Language::new_blank(),
|
||||||
|
Toml => Language::new_hash(),
|
||||||
|
TypeScript => Language::new_c(),
|
||||||
|
UnrealScript => Language::new_c(),
|
||||||
|
VimScript => Language::new_single("\""),
|
||||||
|
Wolfram => Language::new_func(),
|
||||||
|
Xml => Language::new_html(),
|
||||||
|
Yaml => Language::new_hash(),
|
||||||
|
Zsh => Language::new_hash(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Print every supported language.
|
||||||
|
if language_option {
|
||||||
|
for key in languages.keys() {
|
||||||
|
println!("{:<25}", key);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(input) = input_option {
|
||||||
|
let res = match File::open(input) {
|
||||||
|
Ok(mut file) => {
|
||||||
|
let contents = {
|
||||||
|
let mut contents = Vec::new();
|
||||||
|
file.read_to_end(&mut contents).unwrap();
|
||||||
|
contents
|
||||||
|
};
|
||||||
|
|
||||||
|
convert_input(&contents)
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
|
||||||
|
if input == "stdin" {
|
||||||
|
let mut stdin = std::io::stdin();
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
|
||||||
|
let _ = stdin.read_to_string(&mut buffer);
|
||||||
|
convert_input(&buffer)
|
||||||
|
} else {
|
||||||
|
convert_input(&input.to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(res) = res {
|
||||||
|
for (name, res_language) in res {
|
||||||
|
if let Some(language) = languages.get_mut(&name) {
|
||||||
|
*language += res_language;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("Input provided wasn't a path, or valid CBOR, JSON, or YAML.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if output_option == None {
|
||||||
|
println!("{}", ROW);
|
||||||
|
println!(" {:<12} {:>12} {:>12} {:>12} {:>12} {:>12}",
|
||||||
|
"Language",
|
||||||
|
"Files",
|
||||||
|
"Lines",
|
||||||
|
"Code",
|
||||||
|
"Comments",
|
||||||
|
"Blanks");
|
||||||
|
println!("{}", ROW);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_all_files(paths, &mut languages, ignored_directories);
|
||||||
|
|
||||||
|
let mut total = Language::new_blank();
|
||||||
|
|
||||||
|
let mut languages: Vec<_> = languages.into_iter().collect();
|
||||||
|
|
||||||
|
let print_animation = output_option == None;
|
||||||
|
let (tx, rx) = channel();
|
||||||
|
let child = thread::spawn(move || {
|
||||||
|
loop {
|
||||||
|
if let Ok(_) = rx.try_recv() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if print_animation {
|
||||||
|
print!("\x1B[?25l");
|
||||||
|
print!(" Counting files. \r");
|
||||||
|
thread::sleep(Duration::from_millis(4));
|
||||||
|
print!(" Counting files..\r");
|
||||||
|
thread::sleep(Duration::from_millis(4));
|
||||||
|
print!(" Counting files...\r");
|
||||||
|
thread::sleep(Duration::from_millis(4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
languages.par_iter_mut().for_each(|&mut (name, ref mut language)| {
|
||||||
|
if language.files.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
language.total_files = language.files.len();
|
||||||
|
let is_fortran = name == FortranModern || name == FortranLegacy;
|
||||||
|
|
||||||
|
let files: Vec<_> = language.files.drain(..).collect();
|
||||||
|
for file in files {
|
||||||
|
let mut contents = String::new();
|
||||||
|
let mut is_in_comments = false;
|
||||||
|
let mut stats = Stats::new(opt_or_cont!(file.to_str()));
|
||||||
|
|
||||||
|
let _ = rs_or_cont!(rs_or_cont!(File::open(file)).read_to_string(&mut contents));
|
||||||
|
let lines = contents.lines();
|
||||||
|
|
||||||
|
if language.is_blank() {
|
||||||
|
stats.code += lines.count();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
'line: for line in lines {
|
||||||
|
// FORTRAN has a rule where it only counts as a comment if it's the first character
|
||||||
|
// in the column, so removing starting whitespace could cause a miscount.
|
||||||
|
let line = if is_fortran {
|
||||||
|
line
|
||||||
|
} else {
|
||||||
|
line.trim()
|
||||||
|
};
|
||||||
|
stats.lines += 1;
|
||||||
|
|
||||||
|
if line.trim().is_empty() {
|
||||||
|
stats.blanks += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !language.multi_line.is_empty() {
|
||||||
|
let multi_line = language.multi_line;
|
||||||
|
let multi_line_end = language.multi_line_end;
|
||||||
|
if line.starts_with(multi_line) ||
|
||||||
|
contains_comments(line, multi_line, multi_line_end) {
|
||||||
|
is_in_comments = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if is_in_comments {
|
||||||
|
if line.contains(language.multi_line_end) {
|
||||||
|
is_in_comments = false;
|
||||||
|
}
|
||||||
|
stats.comments += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !language.line_comment.is_empty() {
|
||||||
|
for single in language.line_comment.split(',') {
|
||||||
|
if line.starts_with(single) {
|
||||||
|
stats.comments += 1;
|
||||||
|
continue 'line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stats.code += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*language += stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
print!("{}", CLEAR);
|
||||||
|
if !language.is_empty() {
|
||||||
|
if sort_option == None && output_option == None {
|
||||||
|
if files_option {
|
||||||
|
language.print(name);
|
||||||
|
println!("{}", ROW);
|
||||||
|
|
||||||
|
for stat in &language.stats {
|
||||||
|
println!("{}", stat);
|
||||||
|
}
|
||||||
|
println!("{}", ROW);
|
||||||
|
} else if output_option == None {
|
||||||
|
language.print(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let _ = tx.send(());
|
||||||
|
let _ = child.join();
|
||||||
|
|
||||||
|
for &(_, ref language) in &languages {
|
||||||
|
if !language.is_empty() {
|
||||||
|
total += language;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(format) = output_option {
|
||||||
|
|
||||||
|
match &*format {
|
||||||
|
"cbor" => {
|
||||||
|
let cbor: Vec<_> = serde_cbor::to_vec(&languages).unwrap();
|
||||||
|
|
||||||
|
for byte in cbor {
|
||||||
|
print!("{:02x}", byte);
|
||||||
|
}
|
||||||
|
println!("");
|
||||||
|
}
|
||||||
|
"json" => println!("{}", serde_json::to_string(&languages).unwrap()),
|
||||||
|
"yaml" => println!("{}", serde_yaml::to_string(&languages).unwrap()),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
} else if let Some(sort_category) = sort_option {
|
||||||
|
|
||||||
|
for &mut (_, ref mut language) in &mut languages {
|
||||||
|
match &*sort_category {
|
||||||
|
BLANKS => language.sort_by(BLANKS),
|
||||||
|
COMMENTS => language.sort_by(COMMENTS),
|
||||||
|
CODE => language.sort_by(CODE),
|
||||||
|
FILES => {}
|
||||||
|
TOTAL => language.sort_by(TOTAL),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match &*sort_category {
|
||||||
|
BLANKS => languages.sort_by(|a, b| b.1.blanks.cmp(&a.1.blanks)),
|
||||||
|
COMMENTS => languages.sort_by(|a, b| b.1.comments.cmp(&a.1.comments)),
|
||||||
|
CODE => languages.sort_by(|a, b| b.1.code.cmp(&a.1.code)),
|
||||||
|
FILES => languages.sort_by(|a, b| b.1.files.len().cmp(&a.1.files.len())),
|
||||||
|
TOTAL => languages.sort_by(|a, b| b.1.lines.cmp(&a.1.lines)),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for (name, language) in languages {
|
||||||
|
if !language.is_empty() {
|
||||||
|
if !files_option {
|
||||||
|
language.print(name);
|
||||||
|
} else {
|
||||||
|
language.print(name);
|
||||||
|
println!("{}", ROW);
|
||||||
|
for file in &language.stats {
|
||||||
|
println!("{}", file);
|
||||||
|
}
|
||||||
|
println!("{}", ROW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if output_option == None {
|
||||||
|
if !files_option {
|
||||||
|
println!("{}", ROW);
|
||||||
|
}
|
||||||
|
total.print(__Total);
|
||||||
|
println!("{}", ROW);
|
||||||
|
}
|
||||||
|
print!("\x1B[?25h\r");
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Default, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Default, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub struct Stats {
|
pub struct Stats {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub code: usize,
|
pub code: usize,
|
||||||
|
|
Loading…
Reference in a new issue