summaryrefslogtreecommitdiff
path: root/tools/check-typo
diff options
context:
space:
mode:
authorDamien Doligez <damien.doligez-inria.fr>2012-07-31 13:00:48 +0000
committerDamien Doligez <damien.doligez-inria.fr>2012-07-31 13:00:48 +0000
commit20e73da3a47dfc3cd719aff0c3cc72c301ea8359 (patch)
tree9fe9690a3a154b08cf7907c058064a88d7ea3de3 /tools/check-typo
parent997a678d5ee774930288bfec23d4b145ce45c078 (diff)
downloadocaml-20e73da3a47dfc3cd719aff0c3cc72c301ea8359.tar.gz
Tool to check the OCaml sources for simple typographic rules (no TABs, etc)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@12801 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'tools/check-typo')
-rwxr-xr-xtools/check-typo176
1 files changed, 176 insertions, 0 deletions
diff --git a/tools/check-typo b/tools/check-typo
new file mode 100755
index 0000000000..427873b5d5
--- /dev/null
+++ b/tools/check-typo
@@ -0,0 +1,176 @@
+#!/bin/sh
+
+#########################################################################
+# #
+# OCaml #
+# #
+# Damien Doligez, projet Gallium, INRIA Rocquencourt #
+# #
+# Copyright 2012 Institut National de Recherche en Informatique et #
+# en Automatique. All rights reserved. This file is distributed #
+# under the terms of the Q Public License version 1.0. #
+# #
+#########################################################################
+
+# check-typo - Check typographic conventions on OCaml sources.
+
+# This program will check files for the following rules:
+
+# - absence of TAB characters (tab)
+# - absence of non-ASCII characters (non-ascii)
+# - absence of non-printing ASCII characters (non-printing)
+# - absence of white space at end of line (white-at-eol)
+# - absence of white lines at end of file (white-at-eof)
+# - presence of a LF character at the end of the file (missing-lf)
+# - maximum line length of 80 characters (long-line)
+
+# Exceptions are handled with a SVN property: "ocaml:typo".
+# Its value for a given file is a comma-separated list of rule names,
+# which lists the rules that should be disabled for this file.
+# The rule names are the ones shown above in parentheses.
+
+# Built-in exceptions:
+# - Any binary file (i.e. with svn:mime-type = application/octet-stream)
+# is automatically exempt from all the rules.
+# - Any file whose name begins with "Makefile" is automatically exempt
+# from the "tabs" rule.
+
+# ASCII characters are bytes from 0 to 127. Any other byte is
+# flagged as a non-ASCII character.
+
+# For the purpose of this tool, printing ASCII characters are:
+# - the non-white printable ASCII characters (33 to 126)
+# - TAB (09)
+# - LF (10)
+# - SPC (32)
+# Anything else is flagged as a non-printing ASCII character.
+
+# This program will recursively explore the files and directories given
+# on the command line (or by default the current directory), and check
+# every file therein for compliance to the rules.
+
+# Directories named .svn and _build (and their contents) are always ignored.
+# This program ignores any file that is not under svn control, unless
+# explicitly given on the command line.
+
+# You can ignore a rule by giving the option -<rule> on the command
+# line (before any file names).
+
+usage () {
+ echo "usage: check-typo {-<rule>} [--] [<file-or-dir> ...]" >&2
+ exit 2
+}
+
+userrules=''
+
+while : ; do
+ case "$1" in
+ -*) userrules="${1#-},$userrules"; shift;;
+ --) shift; break;;
+ -*) usage;;
+ *) break;;
+ esac
+done
+
+IGNORE_DIRS='
+ -name .svn -prune -o
+ -name _build -prune -o
+'
+
+( case $# in
+ 0) find . $IGNORE_DIRS -type f -print;;
+ *) for i in "$@"; do find "$i" $IGNORE_DIRS -type f -print; done;;
+ esac
+) | (
+ while read f; do
+ case `svn status "$f" 2>&1` in
+ '?'*) is_svn=false;;
+ I*) is_svn=false;;
+ svn:*"is not a working copy") is_svn=false;;
+ *) is_svn=true;;
+ esac
+ case "$*" in
+ *$f*) is_cmd_line=true;;
+ *) is_cmd_line=false;;
+ esac
+ if $is_svn || $is_cmd_line; then :; else continue; fi
+ svnrules=''
+ if $is_svn; then
+ case `svn propget svn:mime-type "$f"` in
+ application/octet-stream) continue;;
+ esac
+ svnrules=`svn propget ocaml:typo "$f"`
+ fi
+ rules="$userrules"
+ case "$f" in
+ Makefile*) rules="tab,$rules";;
+ */Makefile*) rules="tab,$rules";;
+ esac
+
+ (cat "$f"; echo) \
+ | awk -v rules="$rules" -v svnrules="$svnrules" -v file="$f" \
+ '
+ function err(name, msg) {
+ ++ counts[name];
+ if (!index(("," rules svnrules ","), ("," name ",")) \
+ && counts[name] <= 10){
+ printf ("%s:%d.%d:", file, NR, RSTART + RLENGTH);
+ printf (" [%s] %s\n", name, msg);
+ if (counts[name] == 10){
+ printf ("WARNING: too many [%s] in this file.", name);
+ printf (" Others will not be reported.\n");
+ }
+ }
+ }
+
+ match($0, /\t/) {
+ err("tab", "TAB character(s)");
+ }
+
+ match($0, /[\200-\377]/) {
+ err("non-ascii", "non-ASCII character(s)");
+ }
+
+ match($0, /[^\t\200-\377 -~]/) {
+ err("non-printing", "non-printing ASCII character(s)");
+ }
+
+ match($0, /[ \t]+$/) {
+ err("white-at-eol", "whitespace at end of line");
+ }
+
+ length($0) > 80 {
+ RSTART = 81;
+ RLENGTH = length($0) - 81;
+ err("long-line", "line is over 80 characters");
+ }
+
+ {
+ prev_line = last_line;
+ last_line = $0;
+ }
+
+ END {
+ if (match(last_line, /.+/)){
+ err("missing-lf", "missing linefeed at EOF");
+ prev_line = last_line;
+ ++ NR;
+ empty_file = 0;
+ }else{
+ empty_file = NR == 1;
+ }
+ if (!empty_file && match(prev_line, /^[ \t]*$/)){
+ err("white-at-eof", "white line(s) at EOF");
+ }
+ split(svnrules, r, ",");
+ for (i in r){
+ name = r[i];
+ if (name != "" && !counts[name]){
+ printf ("%s, line 1, char 1: unused rule exception [%s]\n",
+ file, name);
+ }
+ }
+ }
+ '
+ done
+)