Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
performance
Megadep
Commits
e291b255
Commit
e291b255
authored
Aug 21, 2019
by
Pádraig Ó Conbhuí
Browse files
Add custom .clang-format configuration
parent
51b3bf20
Changes
10
Hide whitespace changes
Inline
Side-by-side
.clang-format
View file @
e291b255
Language: Cpp
BasedOnStyle: LLVM
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: false
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Stroustrup
BreakBeforeInheritanceComma: false
BreakInheritanceList: AfterColon
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 80
CommentPragmas: '^ *@'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
- SECTION
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...
src/megadep.main.cpp
View file @
e291b255
...
...
@@ -5,29 +5,41 @@
#include
<iostream>
#include
<variant>
// NOLINTNEXTLINE(fuchsia-multiple-inheritance)
template
<
class
...
Ts
>
struct
overloaded
:
Ts
...
{
using
Ts
::
operator
()...;
};
template
<
class
...
Ts
>
overloaded
(
Ts
...)
->
overloaded
<
Ts
...
>
;
template
<
class
...
Ts
>
struct
overloaded
:
Ts
...
{
using
Ts
::
operator
()...;
explicit
overloaded
(
Ts
&&
...
ts
)
:
Ts
(
std
::
forward
<
Ts
>
(
ts
))...
{}
};
template
<
class
...
Ts
>
overloaded
(
Ts
...)
->
overloaded
<
Ts
...
>
;
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
auto
parser
=
megadep
::
cli_parser
();
auto
parse_result
=
parser
.
parse
(
argc
,
argv
);
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
auto
parser
=
megadep
::
cli_parser
();
auto
parse_result
=
parser
.
parse
(
argc
,
argv
);
return
std
::
visit
(
overloaded
{[](
int
exit_value
)
{
return
exit_value
;
},
[](
const
megadep
::
cli_options
&
options
)
{
megadep
::
megadep
(
megadep
::
serial_dependency_calculation
{},
options
.
scan_directories
,
options
.
include_directories
);
return
EXIT_SUCCESS
;
}},
parse_result
);
}
catch
(
const
std
::
bad_variant_access
&
)
{
std
::
cerr
<<
"Unknown error parsing command line!
\n
"
;
return
EXIT_FAILURE
;
}
catch
(...)
{
std
::
cerr
<<
"Unexpected exception!
\n
"
;
return
EXIT_FAILURE
;
}
return
std
::
visit
(
overloaded
(
[](
int
exit_value
)
{
return
exit_value
;
},
[](
const
megadep
::
cli_options
&
options
)
{
megadep
::
megadep
(
megadep
::
serial_dependency_calculation
{},
options
.
scan_directories
,
options
.
include_directories
);
return
EXIT_SUCCESS
;
}),
parse_result
);
}
catch
(
const
std
::
bad_variant_access
&
)
{
std
::
cerr
<<
"Unknown error parsing command line!
\n
"
;
return
EXIT_FAILURE
;
}
catch
(...)
{
std
::
cerr
<<
"Unexpected exception!
\n
"
;
return
EXIT_FAILURE
;
}
}
src/megadep/bidirectional_index_map.hpp
View file @
e291b255
...
...
@@ -9,42 +9,48 @@
#include
<utility>
#include
<vector>
namespace
megadep
{
template
<
typename
T
>
class
bidirectional_index_map
{
std
::
vector
<
T
>
m_values
;
namespace
megadep
{
public:
explicit
bidirectional_index_map
(
std
::
vector
<
T
>
value_list
)
:
m_values
{
std
::
move
(
value_list
)}
{
template
<
typename
T
>
class
bidirectional_index_map
{
std
::
vector
<
T
>
m_values
;
public:
explicit
bidirectional_index_map
(
std
::
vector
<
T
>
value_list
)
:
m_values
{
std
::
move
(
value_list
)}
{
// Sort the files so we can refer to them by index, and look them up
// quickly by index.
// Also, erase any duplicates using a unique / erase.
std
::
sort
(
m_values
.
begin
(),
m_values
.
end
());
m_values
.
erase
(
std
::
unique
(
m_values
.
begin
(),
m_values
.
end
()),
m_values
.
end
());
}
// Sort the files so we can refer to them by index, and look them up
// quickly by index.
// Also, erase any duplicates using a unique / erase.
std
::
sort
(
m_values
.
begin
(),
m_values
.
end
());
m_values
.
erase
(
std
::
unique
(
m_values
.
begin
(),
m_values
.
end
()),
m_values
.
end
());
}
const
std
::
string
&
operator
[](
size_t
index
)
const
{
assert
(
index
<
m_values
.
size
());
const
std
::
string
&
operator
[](
size_t
index
)
const
{
assert
(
index
<
m_values
.
size
());
return
m_values
[
index
];
}
return
m_values
[
index
];
}
std
::
optional
<
uint64_t
>
operator
[](
const
T
&
value
)
const
{
auto
found_ptr
=
std
::
lower_bound
(
m_values
.
begin
(),
m_values
.
end
(),
value
);
std
::
optional
<
uint64_t
>
operator
[](
const
T
&
value
)
const
{
auto
found_ptr
=
std
::
lower_bound
(
m_values
.
begin
(),
m_values
.
end
(),
value
);
if
(
*
found_ptr
!=
value
)
{
return
std
::
nullopt
;
}
if
(
*
found_ptr
!=
value
)
{
return
std
::
nullopt
;
return
std
::
distance
(
m_values
.
begin
(),
found_ptr
);
}
return
std
::
distance
(
m_values
.
begin
(),
found_ptr
);
}
[[
nodiscard
]]
size_t
size
()
const
{
return
m_values
.
size
();
}
[[
nodiscard
]]
size_t
size
()
const
{
return
m_values
.
size
();
}
};
}
// namespace megadep
}
// namespace megadep
#endif // MEGADEP_BIDIRECTIONAL_INDEX_MAP
#endif
// MEGADEP_BIDIRECTIONAL_INDEX_MAP
src/megadep/cli.hpp
View file @
e291b255
...
...
@@ -9,104 +9,119 @@
#include
<variant>
#include
<vector>
namespace
megadep
{
struct
cli_options
{
std
::
vector
<
std
::
string
>
scan_directories
;
std
::
vector
<
std
::
string
>
include_directories
;
std
::
vector
<
std
::
string
>
scan_directories
;
std
::
vector
<
std
::
string
>
include_directories
;
};
class
cli_parser
{
CLI
::
App
app
;
CLI
::
App
app
;
std
::
vector
<
std
::
string
>
m_scan_directories
{};
std
::
vector
<
std
::
string
>
m_include_directories
{};
std
::
vector
<
std
::
string
>
m_system_include_directories
{};
public:
cli_parser
()
:
app
{
"megadep: distributed dependency scanner"
}
{
app
.
add_option
(
"scan_directory"
,
m_scan_directories
,
"Scan directory"
);
app
.
add_option
(
"--include,-I"
,
m_include_directories
,
"Include directory"
);
app
.
add_option
(
"--isystem"
,
m_system_include_directories
,
"System include directory"
);
}
std
::
vector
<
std
::
string
>
m_scan_directories
{};
std
::
vector
<
std
::
string
>
m_include_directories
{};
std
::
vector
<
std
::
string
>
m_system_include_directories
{};
std
::
variant
<
cli_options
,
int
>
parse
(
int
argc
,
char
**
argv
)
{
auto
fixed_args
=
fixup_args
(
app
,
argc
,
argv
);
auto
fixed_argv
=
arg_ptrs
(
fixed_args
);
try
{
app
.
parse
(
argc
,
fixed_argv
.
data
());
}
catch
(
const
CLI
::
ParseError
&
e
)
{
return
app
.
exit
(
e
);
}
public:
cli_parser
()
:
app
{
"megadep: distributed dependency scanner"
}
{
// Combine include_directories and system_include_directories
std
::
vector
<
std
::
string
>
combined_includes
;
combined_includes
.
reserve
(
m_include_directories
.
size
()
+
m_system_include_directories
.
size
());
app
.
add_option
(
"scan_directory"
,
m_scan_directories
,
"Scan directory"
);
app
.
add_option
(
"--include,-I"
,
m_include_directories
,
"Include directory"
);
app
.
add_option
(
"--isystem"
,
m_system_include_directories
,
"System include directory"
);
}
std
::
copy
(
m_include_directories
.
begin
(),
m_include_directories
.
end
(),
std
::
back_inserter
(
combined_includes
));
std
::
variant
<
cli_options
,
int
>
parse
(
int
argc
,
char
**
argv
)
{
auto
fixed_args
=
fixup_args
(
app
,
argc
,
argv
);
auto
fixed_argv
=
arg_ptrs
(
fixed_args
);
std
::
copy
(
m_system_include_directories
.
begin
(),
m_system_include_directories
.
end
(),
std
::
back_inserter
(
combined_includes
));
try
{
app
.
parse
(
argc
,
fixed_argv
.
data
());
}
catch
(
const
CLI
::
ParseError
&
e
)
{
return
app
.
exit
(
e
);
return
cli_options
{
m_scan_directories
,
combined_includes
};
}
// Combine include_directories and system_include_directories
std
::
vector
<
std
::
string
>
combined_includes
;
combined_includes
.
reserve
(
m_include_directories
.
size
()
+
m_system_include_directories
.
size
());
std
::
copy
(
m_include_directories
.
begin
(),
m_include_directories
.
end
(),
std
::
back_inserter
(
combined_includes
));
std
::
copy
(
m_system_include_directories
.
begin
(),
m_system_include_directories
.
end
(),
std
::
back_inserter
(
combined_includes
));
return
cli_options
{
m_scan_directories
,
combined_includes
};
}
private:
// Fix any -include or -isystem options to --include and --isystem
static
std
::
vector
<
std
::
string
>
fixup_args
(
const
CLI
::
App
&
app
,
int
argc
,
char
**
argv
)
{
std
::
vector
<
std
::
string
>
args
{
argv
,
std
::
next
(
argv
,
argc
)};
const
auto
options
=
app
.
get_options
();
for
(
auto
&
arg
:
args
)
{
// We have at least -- or -x
if
(
arg
.
size
()
<
2
)
{
continue
;
}
// We're starting with a '-'
if
(
arg
[
0
]
!=
'-'
)
{
continue
;
}
// We've got -X and not --X
if
(
arg
[
1
]
==
'-'
)
{
continue
;
}
const
std
::
string_view
arg_view
=
arg
;
for
(
const
auto
&
option
:
options
)
{
const
auto
lnames
=
option
->
get_lnames
();
for
(
const
auto
&
lname
:
lnames
)
{
// if we have -lname, turn it into --lname
if
(
arg_view
.
substr
(
1
,
lname
.
size
())
==
lname
)
{
arg
.
insert
(
0
,
1
,
'-'
);
}
private:
// Fix any -include or -isystem options to --include and --isystem
static
std
::
vector
<
std
::
string
>
fixup_args
(
const
CLI
::
App
&
app
,
int
argc
,
char
**
argv
)
{
std
::
vector
<
std
::
string
>
args
{
argv
,
std
::
next
(
argv
,
argc
)};
const
auto
options
=
app
.
get_options
();
for
(
auto
&
arg
:
args
)
{
// We have at least -- or -x
if
(
arg
.
size
()
<
2
)
{
continue
;
}
// We're starting with a '-'
if
(
arg
[
0
]
!=
'-'
)
{
continue
;
}
// We've got -X and not --X
if
(
arg
[
1
]
==
'-'
)
{
continue
;
}
const
std
::
string_view
arg_view
=
arg
;
for
(
const
auto
&
option
:
options
)
{
const
auto
lnames
=
option
->
get_lnames
();
for
(
const
auto
&
lname
:
lnames
)
{
// if we have -lname, turn it into --lname
if
(
arg_view
.
substr
(
1
,
lname
.
size
())
==
lname
)
{
arg
.
insert
(
0
,
1
,
'-'
);
}
}
}
}
}
return
args
;
}
return
args
;
}
static
std
::
vector
<
const
char
*>
arg_ptrs
(
const
std
::
vector
<
std
::
string
>&
argv
)
{
std
::
vector
<
const
char
*>
result
;
result
.
reserve
(
argv
.
size
());
static
std
::
vector
<
const
char
*>
arg_ptrs
(
const
std
::
vector
<
std
::
string
>
&
argv
)
{
std
::
vector
<
const
char
*>
result
;
result
.
reserve
(
argv
.
size
());
for
(
const
auto
&
arg
:
argv
)
{
result
.
push_back
(
arg
.
c_str
());
}
for
(
const
auto
&
arg
:
argv
)
{
result
.
push_back
(
arg
.
c_str
());
return
result
;
}
return
result
;
}
};
}
// namespace megadep
}
// namespace megadep
#endif // MEGADEP_CLI_HPP
#endif
// MEGADEP_CLI_HPP
src/megadep/config.hpp
View file @
e291b255
...
...
@@ -7,6 +7,6 @@ namespace megadep {
constexpr
size_t
filename_max
=
4096
;
}
// namespace megadep
}
// namespace megadep
#endif // MEGADEP_CONFIG_HPP
#endif
// MEGADEP_CONFIG_HPP
src/megadep/filesystem.cpp
View file @
e291b255
...
...
@@ -11,21 +11,24 @@
#include
<dirent.h>
#include
<unistd.h>
namespace
megadep
{
static
void
list_files_impl
(
char
*
path_begin
,
char
*
path_end
,
std
::
vector
<
std
::
string
>
&
file_names
);
static
void
list_files_impl
(
char
*
path_begin
,
char
*
path_end
,
std
::
vector
<
std
::
string
>&
file_names
);
std
::
vector
<
std
::
string
>
list_files
(
std
::
string_view
directory
)
{
std
::
vector
<
std
::
string
>
file_names
;
std
::
array
<
char
,
filename_max
>
path_buffer
{};
std
::
vector
<
std
::
string
>
list_files
(
std
::
string_view
directory
)
{
std
::
vector
<
std
::
string
>
file_names
;
std
::
array
<
char
,
filename_max
>
path_buffer
{};
directory
.
copy
(
path_buffer
.
begin
(),
path_buffer
.
size
());
directory
.
copy
(
path_buffer
.
begin
(),
path_buffer
.
size
());
list_files_impl
(
path_buffer
.
begin
(),
path_buffer
.
begin
()
+
directory
.
size
(),
file_names
);
list_files_impl
(
path_buffer
.
begin
(),
path_buffer
.
begin
()
+
directory
.
size
(),
file_names
);
return
file_names
;
return
file_names
;
}
// This implimentation takes advantage of recursing into directories only
...
...
@@ -33,304 +36,317 @@ std::vector<std::string> list_files(std::string_view directory) {
// The function only ever reads the region [path_begin, path_end], and
// edits the region [path_end, path_max) for recursive calls, bumping the
// `path_end` pointer along to recursive calls.
static
void
list_files_impl
(
char
*
path_begin
,
char
*
path_end
,
std
::
vector
<
std
::
string
>
&
file_names
)
{
*
path_end
=
'\0'
;
DIR
*
dir_ptr
=
opendir
(
path_begin
);
// Directory is a file, return the directory name
if
(
dir_ptr
==
nullptr
)
{
if
(
errno
==
ENOTDIR
||
errno
==
ENOENT
)
{
file_names
.
emplace_back
(
path_begin
);
return
;
static
void
list_files_impl
(
char
*
path_begin
,
char
*
path_end
,
std
::
vector
<
std
::
string
>&
file_names
)
{
*
path_end
=
'\0'
;
DIR
*
dir_ptr
=
opendir
(
path_begin
);
// Directory is a file, return the directory name
if
(
dir_ptr
==
nullptr
)
{
if
(
errno
==
ENOTDIR
||
errno
==
ENOENT
)
{
file_names
.
emplace_back
(
path_begin
);
return
;
}
return
;
}
return
;
}
dirent
*
entity_ptr
;
while
((
entity_ptr
=
readdir
(
dir_ptr
))
!=
nullptr
)
{
const
char
*
entity_name
=
static_cast
<
const
char
*>
(
entity_ptr
->
d_name
);
const
size_t
entity_name_size
=
strlen
(
entity_name
);
dirent
*
entity_ptr
;
while
((
entity_ptr
=
readdir
(
dir_ptr
))
!=
nullptr
)
{
const
char
*
entity_name
=
static_cast
<
const
char
*>
(
entity_ptr
->
d_name
);
const
size_t
entity_name_size
=
strlen
(
entity_name
);
// Skip . and ..
if
(
strcmp
(
entity_name
,
"."
)
==
0
)
{
continue
;
}
if
(
strcmp
(
entity_name
,
".."
)
==
0
)
{
continue
;
}
// Skip . and ..
if
(
strcmp
(
entity_name
,
"."
)
==
0
)
{
continue
;
}
if
(
strcmp
(
entity_name
,
".."
)
==
0
)
{
continue
;
}
// Copy the entity to the end of the current path and recurse.
assert
(
path_end
-
path_begin
+
entity_name_size
+
2
<
filename_max
&&
"Filename is too big for filename buffer!"
);
// Copy the entity to the end of the current path and recurse.
assert
(
path_end
-
path_begin
+
entity_name_size
+
2
<
filename_max
&&
"Filename is too big for filename buffer!"
);
*
path_end
=
'/'
;
*
path_end
=
'/'
;
auto
new_entity_start
=
std
::
next
(
path_end
);
std
::
copy_n
(
entity_name
,
entity_name_size
,
new_entity_start
);
auto
new_entity_end
=
std
::
next
(
new_entity_start
,
entity_name_size
);
auto
new_entity_start
=
std
::
next
(
path_end
);
std
::
copy_n
(
entity_name
,
entity_name_size
,
new_entity_start
);
auto
new_entity_end
=
std
::
next
(
new_entity_start
,
entity_name_size
);
list_files_impl
(
path_begin
,
new_entity_end
,
file_names
);
}
list_files_impl
(
path_begin
,
new_entity_end
,
file_names
);
}
closedir
(
dir_ptr
);
closedir
(
dir_ptr
);
}
namespace
{
// Wrap fopen and fclose in an RAII class.
class
raii_fopen
{
FILE
*
m_file_ptr
=
nullptr
;
FILE
*
m_file_ptr
=
nullptr
;
public:
FILE
*
file_ptr
()
{
return
m_file_ptr
;
}
public:
FILE
*
file_ptr
()
{
return
m_file_ptr
;
}
explicit
raii_fopen
(
std
::
string_view
file_name
)
{
assert
(
file_name
.
size
()
+
1
<
filename_max
);
explicit
raii_fopen
(
std
::
string_view
file_name
)
{
assert
(
file_name
.
size
()
+
1
<
filename_max
);
std
::
array
<
char
,
filename_max
>
file_name_buf
{};
std
::
array
<
char
,
filename_max
>
file_name_buf
{};
file_name
.
copy
(
file_name_buf
.
data
(),
file_name
.
size
());
file_name_buf
[
file_name
.
size
()]
=
'\0'
;
file_name
.
copy
(
file_name_buf
.
data
(),
file_name
.
size
());
file_name_buf
[
file_name
.
size
()]
=
'\0'
;
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
m_file_ptr
=
fopen
(
file_name_buf
.
data
(),
"re"
);
}
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
m_file_ptr
=
fopen
(
file_name_buf
.
data
(),
"re"
);