#!/bin/bash exec scala -savecompiled "$0" "$@" !# // sjcount ディレクトリ // あるディレクトリ内のScala及びJavaソースの数と総行数を表示 // Scalaライブラリはまだよく知らないので、あらかたJavaライブラリを利用している import java.io._ val baseFiles = new File(args(0)).listFiles if (baseFiles == null) { println("A directory is needed.") exit } // ディレクトリは展開してファイルだけのリスト作成 def getFiles(files: List[File]): List[File] = files match { case f::fl if f.isFile => f::getFiles(fl) case f::fl if f.isDirectory => getFiles(f.listFiles.toList:::fl) case f::fl if fl == Nil => f::fl case f::fl => getFiles(fl) case _ => Nil } val fileList = getFiles(baseFiles.toList) abstract class Files { val files: List[File] def isComment(s: String): Boolean // ある種類のファイル群すべてのコメント行を除く行数を返す def getLines: Long = { var count: Long = 0 for (f <- files) { val inFile = new BufferedReader(new FileReader(f)) var line = inFile.readLine while (line != null) { if (!isComment(line.trim)) count += 1 line = inFile.readLine } inFile.close } count } } class Scalas(flist: List[File]) extends Files { val files = for (f <- flist if f.getName.endsWith(".scala")) yield f def isComment(s: String): Boolean = s.startsWith("/*") || s.startsWith("*") } class Javas(flist: List[File]) extends Files { val files = for (f <- flist if f.getName.endsWith(".java")) yield f def isComment(s: String): Boolean = s.startsWith("/*") || s.startsWith("*") } // 拡張子が.scalaでも.javaでも無いもの(バイナリファイルもおそらくに含む) class Others(flist: List[File]) extends Files { val files = for {f <- flist if !(f.getName.endsWith(".scala") || f.getName.endsWith(".java")) } yield f def isComment(s: String): Boolean = false } val s = new Scalas(fileList); val sl = s.getLines; val sf = s.files.length val j = new Javas(fileList); val jl = j.getLines; val jf = j.files.length val o = new Others(fileList) println("Scala files: " + sl + " lines in " + sf + " files.") println("Java files: " + jl + " lines in " + jf + " files.") println("Total : " + (sl + jl) + " lines in " + (sf + jf) + " files.") println("Other files: " + o.files.sort((f1, f2) => (f1 compareTo f2) < 0).mkString(", "))