rocksdb/linters/cpp_linter/FbcodeCppLinter.php
kailiu d0458469c8 Add google-style checker to "arc lint"
Summary:
After we reached a consensus on code format, which follows exactly
Google's coding style, a natural follow-up is to have a style checker
that can handle stuffs beyond format.

Google already has a powerful style checker "cpplint.py" and,
luckily, phabricator already provides the built-in linter for it!
Next time with "arc lint" most style inconsistency will be detected
(but will not be fixed).

Also I copied cpplint.py to linters directory, which is mostly
because we may need the flexibility to make some modifications on
it for our own need.

Test Plan:
ran arc lint table/block_based_table_builder.cc to see the amazing
results.

Reviewers: haobo, sdong, igor, dhruba

Reviewed By: haobo

CC: leveldb

Differential Revision: https://reviews.facebook.net/D15369
2014-01-23 15:04:12 -08:00

100 lines
2.7 KiB
PHP

<?php
class FbcodeCppLinter extends ArcanistLinter {
const CPPLINT = "/home/engshare/tools/cpplint";
const LINT_ERROR = 1;
const LINT_WARNING = 2;
const C_FLAG = "--c_mode=true";
private $rawLintOutput = array();
public function willLintPaths(array $paths) {
$futures = array();
$ret_value = 0;
$last_line = system("which cpplint", $ret_value);
$CPP_LINT = false;
if ($ret_value == 0) {
$CPP_LINT = $last_line;
} else if (file_exists(self::CPPLINT)) {
$CPP_LINT = self::CPPLINT;
}
if ($CPP_LINT) {
foreach ($paths as $p) {
$lpath = $this->getEngine()->getFilePathOnDisk($p);
$lpath_file = file($lpath);
if (preg_match('/\.(c)$/', $lpath) ||
preg_match('/-\*-.*Mode: C[; ].*-\*-/', $lpath_file[0]) ||
preg_match('/vim(:.*)*:\s*(set\s+)?filetype=c\s*:/', $lpath_file[0])
) {
$futures[$p] = new ExecFuture("%s %s %s 2>&1",
$CPP_LINT, self::C_FLAG,
$this->getEngine()->getFilePathOnDisk($p));
} else {
$futures[$p] = new ExecFuture("%s %s 2>&1",
self::CPPLINT, $this->getEngine()->getFilePathOnDisk($p));
}
}
foreach (Futures($futures)->limit(8) as $p => $f) {
$this->rawLintOutput[$p] = $f->resolvex();
}
}
return;
}
public function getLinterName() {
return "FBCPP";
}
public function lintPath($path) {
$msgs = $this->getCppLintOutput($path);
foreach ($msgs as $m) {
$this->raiseLintAtLine($m['line'], 0, $m['severity'], $m['msg']);
}
}
public function getLintSeverityMap() {
return array(
self::LINT_WARNING => ArcanistLintSeverity::SEVERITY_WARNING,
self::LINT_ERROR => ArcanistLintSeverity::SEVERITY_ERROR
);
}
public function getLintNameMap() {
return array(
self::LINT_WARNING => "CppLint Warning",
self::LINT_ERROR => "CppLint Error"
);
}
private function getCppLintOutput($path) {
list($output) = $this->rawLintOutput[$path];
$msgs = array();
$current = null;
foreach (explode("\n", $output) as $line) {
if (preg_match('/[^:]*\((\d+)\):(.*)$/', $line, $matches)) {
if ($current) {
$msgs[] = $current;
}
$line = $matches[1];
$text = $matches[2];
$sev = preg_match('/.*Warning.*/', $text)
? self::LINT_WARNING
: self::LINT_ERROR;
$current = array('line' => $line,
'msg' => $text,
'severity' => $sev);
} else if ($current) {
$current['msg'] .= ' ' . $line;
}
}
if ($current) {
$msgs[] = $current;
}
return $msgs;
}
}