1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package ClangFormat;
use strict;
use warnings;
our @EXPORT_OK = qw(get_excludelist set_excludelist get_wanted_version get_own_directory get_extension_regex find check_style);
# Reads the excludelist.
sub get_excludelist()
{
my $src = "c|cpp|cxx|h|hxx|inl";
my %excludelist_names = ();
# Read the excludelist.
if (open(LINES, "solenv/clang-format/excludelist"))
{
while (my $line = <LINES>)
{
chomp $line;
$excludelist_names{$line} = 1;
}
}
return \%excludelist_names;
}
# Writes the excludelist.
# The single argument is a reference to an array.
sub set_excludelist
{
my @filenames = @{$_[0]};
open my $fh, ">", "solenv/clang-format/excludelist" or die $!;
print $fh "$_\n" for @filenames;
close $fh;
}
# Returns the clang-format version used of style enforcement.
sub get_wanted_version()
{
return "5.0.0";
}
# Returns the directory that can host a binary which is used automatically, even
# if it's not in PATH.
sub get_own_directory()
{
return "/opt/lo/bin";
}
# Returns a regex matching filenames we clang-format.
sub get_extension_regex()
{
return "c|cpp|cxx|h|hxx|inl";
}
# Use clang-format from CLANG_FORMAT, from our dedicated directory or from
# PATH, in this order.
sub find()
{
my $version = get_wanted_version();
my $opt_lo = get_own_directory();
my $clang_format;
if (!(defined($ENV{CLANG_FORMAT}) && is_matching_clang_format_version($ENV{CLANG_FORMAT}, $version)))
{
my @dirs = split /:/, $ENV{PATH};
unshift(@dirs, $opt_lo);
foreach my $dir (@dirs)
{
if (is_matching_clang_format_version("$dir/clang-format", $version))
{
$clang_format = "$dir/clang-format";
last;
}
}
}
else
{
$clang_format = $ENV{CLANG_FORMAT};
}
if ($^O eq "cygwin" && defined($clang_format))
{
$clang_format = `cygpath -m '$clang_format'`;
chomp $clang_format;
}
return $clang_format;
}
# Diffs the original and the formatted version of a single file from the index.
sub check_style($$)
{
# Make sure that not staged changes are not considered when diffing.
my ($clang_format, $filename) = @_;
my $index = $filename . ".index";
system("git show :$filename > $index");
my $format = $index . ".format";
system("'$clang_format' -assume-filename=$filename $index > $format");
my $ret = system("git --no-pager diff --no-index --exit-code $index $format") == 0;
unlink($index);
unlink($format);
return $ret;
}
# Private functions.
# Is this binary the version we standardize on?
sub is_matching_clang_format_version($$)
{
my ($clang_format, $version) = @_;
if (! -x $clang_format)
{
return 0;
}
return `'$clang_format' -version` =~ /^clang-format version $version(-\d+)? \(tags/;
}
1;
# vim: set shiftwidth=4 softtabstop=4 expandtab:
|