src/Pure/Tools/check_sources.scala
author wenzelm
Sun, 04 Sep 2016 21:09:18 +0200
changeset 63781 af9fe0b6b78e
parent 62834 970cedec9748
child 63997 e11ccb5aa82f
permissions -rw-r--r--
support for (single) primary key; more operations;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62452
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
     1
/*  Title:      Pure/Tools/check_sources.scala
56791
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
     3
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
     4
Some sanity checks for Isabelle sources.
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
     5
*/
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
     6
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
     7
package isabelle
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
     8
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
     9
62452
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    10
object Check_Sources
56791
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    11
{
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    12
  def check_file(path: Path)
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    13
  {
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    14
    val file_name = path.implode
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    15
    val file_pos = path.position
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    16
    def line_pos(i: Int) = Position.Line_File(i + 1, file_name)
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    17
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    18
    val content = File.read(path)
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    19
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    20
    for { (line, i) <- split_lines(content).iterator.zipWithIndex }
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    21
    {
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    22
      try {
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    23
        Symbol.decode_strict(line)
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    24
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    25
        for { c <- Word.codepoint_iterator(line); if c > 128 && !Character.isAlphabetic(c) }
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    26
        {
56792
wenzelm
parents: 56791
diff changeset
    27
          Output.warning("Suspicious Unicode character " + quote(Word.codepoint(c)) +
56791
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    28
            Position.here(line_pos(i)))
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    29
        }
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    30
      }
62814
29ca4cdd998d clarified check_sources;
wenzelm
parents: 62615
diff changeset
    31
      catch { case ERROR(msg) => Output.warning(msg + Position.here(line_pos(i))) }
56791
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    32
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    33
      if (line.contains('\t'))
56792
wenzelm
parents: 56791
diff changeset
    34
        Output.warning("TAB character" + Position.here(line_pos(i)))
56791
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    35
    }
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    36
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    37
    if (content.contains('\r'))
56792
wenzelm
parents: 56791
diff changeset
    38
      Output.warning("CR character" + Position.here(file_pos))
62814
29ca4cdd998d clarified check_sources;
wenzelm
parents: 62615
diff changeset
    39
29ca4cdd998d clarified check_sources;
wenzelm
parents: 62615
diff changeset
    40
    if (Word.bidi_detect(content))
29ca4cdd998d clarified check_sources;
wenzelm
parents: 62615
diff changeset
    41
      Output.warning("Bidirectional Unicode text " + Position.here(file_pos))
56791
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    42
  }
56829
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    43
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    44
  def check_hg(root: Path)
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    45
  {
56830
e760242101fc tuned signature -- channels for diagnostic output for system tools means stderr;
wenzelm
parents: 56829
diff changeset
    46
    Output.writeln("Checking " + root + " ...")
62545
8ebffdaf2ce2 Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
wenzelm
parents: 62454
diff changeset
    47
    Isabelle_System.hg("--repository " + File.bash_path(root) + " root").check
56829
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    48
    for {
62615
8e5b631d203b tuned signature;
wenzelm
parents: 62545
diff changeset
    49
      file <- Isabelle_System.hg("manifest", cwd = root.file).check.out_lines
62226
9f7293af6fb8 check more files;
wenzelm
parents: 60988
diff changeset
    50
      if file.endsWith(".thy") || file.endsWith(".ML") || file.endsWith("/ROOT")
56829
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    51
    } check_file(root + Path.explode(file))
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    52
  }
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    53
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    54
62834
970cedec9748 prefer internal tool;
wenzelm
parents: 62814
diff changeset
    55
  /* Isabelle tool wrapper */
56829
f151ade98b15 proper tool wrap-up;
wenzelm
parents: 56792
diff changeset
    56
62834
970cedec9748 prefer internal tool;
wenzelm
parents: 62814
diff changeset
    57
  val isabelle_tool =
970cedec9748 prefer internal tool;
wenzelm
parents: 62814
diff changeset
    58
    Isabelle_Tool("check_sources", "some sanity checks for Isabelle sources", args =>
970cedec9748 prefer internal tool;
wenzelm
parents: 62814
diff changeset
    59
    {
62454
38c89353b349 tuned signature;
wenzelm
parents: 62452
diff changeset
    60
      val getopts = Getopts("""
62452
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    61
Usage: isabelle check_sources [ROOT_DIRS...]
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    62
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    63
  Check .thy, .ML, ROOT files from manifest of Mercurial ROOT_DIRS.
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    64
""")
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    65
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    66
      val specs = getopts(args)
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    67
      if (specs.isEmpty) getopts.usage()
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    68
f25b67245699 more official "isabelle check_sources";
wenzelm
parents: 62303
diff changeset
    69
      for (root <- specs) check_hg(Path.explode(root))
62834
970cedec9748 prefer internal tool;
wenzelm
parents: 62814
diff changeset
    70
    })
56791
23883e1879c5 some sanity checks for Isabelle sources;
wenzelm
parents:
diff changeset
    71
}