1#include "clang-c/CXCompilationDatabase.h"
2#include "CXString.h"
3#include "clang/Tooling/CompilationDatabase.h"
4
5using namespace clang;
6using namespace clang::tooling;
7
8extern "C" {
9
10// FIXME: do something more usefull with the error message
11CXCompilationDatabase
12clang_CompilationDatabase_fromDirectory(const char *BuildDir,
13                                        CXCompilationDatabase_Error *ErrorCode)
14{
15  std::string ErrorMsg;
16  CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;
17
18  CompilationDatabase *db = CompilationDatabase::loadFromDirectory(BuildDir,
19                                                                   ErrorMsg);
20
21  if (!db) {
22    fprintf(stderr, "LIBCLANG TOOLING ERROR: %s\n", ErrorMsg.c_str());
23    Err = CXCompilationDatabase_CanNotLoadDatabase;
24  }
25
26  if (ErrorCode)
27    *ErrorCode = Err;
28
29  return db;
30}
31
32void
33clang_CompilationDatabase_dispose(CXCompilationDatabase CDb)
34{
35  delete static_cast<CompilationDatabase *>(CDb);
36}
37
38struct AllocatedCXCompileCommands
39{
40  std::vector<CompileCommand> CCmd;
41
42  AllocatedCXCompileCommands(const std::vector<CompileCommand>& Cmd)
43    : CCmd(Cmd)
44  { }
45};
46
47CXCompileCommands
48clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
49                                             const char *CompleteFileName)
50{
51  if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
52    const std::vector<CompileCommand>
53      CCmd(db->getCompileCommands(CompleteFileName));
54    if (!CCmd.empty())
55      return new AllocatedCXCompileCommands( CCmd );
56  }
57
58  return 0;
59}
60
61CXCompileCommands
62clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
63  if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
64    const std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
65    if (!CCmd.empty())
66      return new AllocatedCXCompileCommands( CCmd );
67  }
68
69  return 0;
70}
71
72void
73clang_CompileCommands_dispose(CXCompileCommands Cmds)
74{
75  delete static_cast<AllocatedCXCompileCommands *>(Cmds);
76}
77
78unsigned
79clang_CompileCommands_getSize(CXCompileCommands Cmds)
80{
81  if (!Cmds)
82    return 0;
83
84  AllocatedCXCompileCommands *ACC =
85    static_cast<AllocatedCXCompileCommands *>(Cmds);
86
87  return ACC->CCmd.size();
88}
89
90CXCompileCommand
91clang_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
92{
93  if (!Cmds)
94    return 0;
95
96  AllocatedCXCompileCommands *ACC =
97    static_cast<AllocatedCXCompileCommands *>(Cmds);
98
99  if (I >= ACC->CCmd.size())
100    return 0;
101
102  return &ACC->CCmd[I];
103}
104
105CXString
106clang_CompileCommand_getDirectory(CXCompileCommand CCmd)
107{
108  if (!CCmd)
109    return cxstring::createNull();
110
111  CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
112  return cxstring::createRef(cmd->Directory.c_str());
113}
114
115unsigned
116clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)
117{
118  if (!CCmd)
119    return 0;
120
121  return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
122}
123
124CXString
125clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
126{
127  if (!CCmd)
128    return cxstring::createNull();
129
130  CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
131
132  if (Arg >= Cmd->CommandLine.size())
133    return cxstring::createNull();
134
135  return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
136}
137
138
139} // end: extern "C"
140