Skip to content

Commit e4ca7a9

Browse files
committed
Add CompileCommand class
Represents a single compile command from a compilation database. Signed-off-by: John Pennycook <john.pennycook@intel.com>
1 parent 667caf7 commit e4ca7a9

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

codebasin/__init__.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Copyright (C) 2019-2024 Intel Corporation
22
# SPDX-License-Identifier: BSD-3-Clause
3+
import shlex
34
import warnings
45

6+
import codebasin.source
57
import codebasin.walkers
68

79
warnings.warn(
@@ -11,3 +13,114 @@
1113
+ "a future release of Code Base Investigator.",
1214
DeprecationWarning,
1315
)
16+
17+
18+
class CompileCommand:
19+
"""
20+
A single compile command from a compilation database.
21+
22+
Attributes
23+
----------
24+
filename: string
25+
The name of the source file compiled by this command.
26+
27+
directory: string, optional
28+
The working directory for this command.
29+
30+
arguments: list[string], optional
31+
The `argv` for this command, including the executable as `argv[0]`.
32+
33+
output: string, optional
34+
The name of the file produced by this command, or None if not
35+
specified.
36+
"""
37+
38+
def __init__(
39+
self,
40+
filename,
41+
directory=None,
42+
arguments=None,
43+
command=None,
44+
output=None,
45+
):
46+
"""
47+
Raises
48+
------
49+
ValueError
50+
If both arguments and command are None.
51+
"""
52+
self._filename = filename
53+
self._directory = directory
54+
if arguments is None and command is None:
55+
raise ValueError("CompileCommand requires arguments or command.")
56+
self._arguments = arguments
57+
self._command = command
58+
self._output = output
59+
60+
@property
61+
def directory(self):
62+
return self._directory
63+
64+
@property
65+
def filename(self):
66+
return self._filename
67+
68+
@property
69+
def arguments(self):
70+
if self._arguments is None:
71+
return shlex.split(self._command)
72+
else:
73+
return self._arguments
74+
75+
@property
76+
def output(self):
77+
return self._output
78+
79+
def __str__(self):
80+
if self._command is None:
81+
return " ".join(self._arguments)
82+
else:
83+
return self._command
84+
85+
def is_supported(self):
86+
"""
87+
Returns
88+
-------
89+
bool
90+
True if the command can be emulated and False otherwise.
91+
Commands that are not supported will not impact analysis.
92+
"""
93+
# Empty commands don't do anything
94+
if len(self.arguments) == 0:
95+
return False
96+
97+
# Ignore commands operating on non-source files (e.g. linking)
98+
if not codebasin.source.is_source_file(self.filename):
99+
return False
100+
101+
return True
102+
103+
@classmethod
104+
def from_json(cls, instance: dict):
105+
"""
106+
Parameters
107+
----------
108+
instance: dict
109+
A JSON object representing a single compile command.
110+
111+
Returns
112+
-------
113+
CompileCommand
114+
A CompileCommand corresponding to the JSON object.
115+
"""
116+
directory = instance["directory"] if "directory" in instance else None
117+
arguments = instance["arguments"] if "arguments" in instance else None
118+
command = instance["command"] if "command" in instance else None
119+
output = instance["output"] if "output" in instance else None
120+
return cls(
121+
instance["file"],
122+
directory=directory,
123+
arguments=arguments,
124+
command=command,
125+
output=output,
126+
)

0 commit comments

Comments
 (0)