source: castxml/trunk/fuentes/src/Utils.cxx @ 6513

Last change on this file since 6513 was 6513, checked in by mabarracus, 2 years ago

Initial port to lliurex from ubuntu

File size: 6.4 KB
Line 
1/*
2  Copyright Kitware, Inc.
3
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8      http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15*/
16
17#include "Utils.h"
18#include "Version.h"
19
20#include <cxsys/Process.h>
21#include <llvm/ADT/SmallString.h>
22#include <llvm/Support/FileSystem.h>
23#include <llvm/Support/Path.h>
24#include <fstream>
25#include <vector>
26
27static std::string castxmlResourceDir;
28static std::string castxmlClangResourceDir;
29
30//----------------------------------------------------------------------------
31static std::string GetMainExecutable(const char* argv0)
32{
33  return llvm::sys::fs::getMainExecutable
34    (argv0, (void*)(intptr_t)GetMainExecutable);
35}
36
37//----------------------------------------------------------------------------
38static bool tryBuildDir(std::string const& dir)
39{
40  // Build tree has
41  //   <build>/CMakeFiles/castxmlSourceDir.txt
42  //   <build>/CMakeFiles/castxmlClangResourceDir.txt
43  std::string src_dir_txt = dir + "/CMakeFiles/castxmlSourceDir.txt";
44  std::string cl_dir_txt = dir + "/CMakeFiles/castxmlClangResourceDir.txt";
45  std::ifstream src_fin(src_dir_txt.c_str());
46  std::ifstream cl_fin(cl_dir_txt.c_str());
47  std::string src_dir;
48  std::string cl_dir;
49  if (std::getline(src_fin, src_dir) &&
50      llvm::sys::fs::is_directory(src_dir) &&
51      std::getline(cl_fin, cl_dir) &&
52      llvm::sys::fs::is_directory(cl_dir)) {
53    castxmlResourceDir = src_dir + "/share/castxml";
54    castxmlClangResourceDir = cl_dir;
55    return true;
56  }
57  return false;
58}
59
60//----------------------------------------------------------------------------
61bool findResourceDir(const char* argv0, std::ostream& error)
62{
63  std::string exe = GetMainExecutable(argv0);
64  if (!llvm::sys::path::is_absolute(exe)) {
65    error << "error: unable to locate " << argv0 << "\n";
66    return false;
67  }
68
69  // Install tree has
70  //   <prefix>/bin/castxml
71  //   <prefix>/<CASTXML_INSTALL_DATA_DIR>
72  //   <prefix>/<CASTXML_INSTALL_DATA_DIR>/clang
73  llvm::SmallString<16> dir(exe);
74  llvm::sys::path::remove_filename(dir);
75  llvm::sys::path::remove_filename(dir);
76  castxmlResourceDir = std::string(dir.str()) + "/" + CASTXML_INSTALL_DATA_DIR;
77  castxmlClangResourceDir = castxmlResourceDir + "/clang";
78  if (!llvm::sys::fs::is_directory(castxmlResourceDir) ||
79      !llvm::sys::fs::is_directory(castxmlClangResourceDir)) {
80    llvm::SmallString<16> dir2(dir);
81    llvm::sys::path::remove_filename(dir2);
82    // Build tree has
83    //   <build>/bin[/<config>]/castxml
84    if (!tryBuildDir(dir.str()) &&
85        !tryBuildDir(dir2.str())) {
86      error << "Unable to locate resources for " << exe << "\n";
87      return false;
88    }
89  }
90
91  return true;
92}
93
94//----------------------------------------------------------------------------
95std::string getResourceDir()
96{
97  return castxmlResourceDir;
98}
99
100//----------------------------------------------------------------------------
101std::string getClangResourceDir()
102{
103  return castxmlClangResourceDir;
104}
105
106//----------------------------------------------------------------------------
107std::string getVersionString()
108{
109  return CASTXML_VERSION_STRING;
110}
111
112//----------------------------------------------------------------------------
113unsigned int getVersionValue()
114{
115  return (CASTXML_VERSION_MAJOR * 1000000 +
116          CASTXML_VERSION_MINOR *    1000 +
117          CASTXML_VERSION_PATCH *       1);
118}
119
120//----------------------------------------------------------------------------
121bool runCommand(int argc, const char* const* argv,
122                int& ret, std::string& out, std::string& err,
123                std::string& msg)
124{
125  std::vector<const char*> cmd(argv, argv + argc);
126  cmd.push_back(0);
127  ret = 1;
128  out = "";
129  err = "";
130  std::vector<char> outBuf;
131  std::vector<char> errBuf;
132
133  cxsysProcess* cp = cxsysProcess_New();
134  cxsysProcess_SetCommand(cp, &*cmd.begin());
135  cxsysProcess_SetOption(cp, cxsysProcess_Option_HideWindow, 1);
136#ifdef _WIN32
137  cxsysProcess_SetPipeFile(cp, cxsysProcess_Pipe_STDIN, "//./nul");
138#else
139  cxsysProcess_SetPipeFile(cp, cxsysProcess_Pipe_STDIN, "/dev/null");
140#endif
141  cxsysProcess_Execute(cp);
142
143  char* data;
144  int length;
145  int pipe;
146  while((pipe = cxsysProcess_WaitForData(cp, &data, &length, 0)) > 0) {
147    if(pipe == cxsysProcess_Pipe_STDOUT) {
148      outBuf.insert(outBuf.end(), data, data+length);
149    } else if(pipe == cxsysProcess_Pipe_STDERR) {
150      errBuf.insert(errBuf.end(), data, data+length);
151    }
152  }
153
154  cxsysProcess_WaitForExit(cp, 0);
155  if(!outBuf.empty()) {
156    out.append(&*outBuf.begin(), outBuf.size());
157  }
158  if(!errBuf.empty()) {
159    err.append(&*errBuf.begin(), errBuf.size());
160  }
161
162  bool result = true;
163  switch(cxsysProcess_GetState(cp)) {
164  case cxsysProcess_State_Exited:
165    ret = cxsysProcess_GetExitValue(cp);
166    break;
167  case cxsysProcess_State_Exception:
168    msg = cxsysProcess_GetExceptionString(cp);
169    result = false;
170    break;
171  case cxsysProcess_State_Error:
172    msg = cxsysProcess_GetErrorString(cp);
173    result = false;
174    break;
175  default:
176    msg = "Process terminated in unexpected state.\n";
177    result = false;
178    break;
179  }
180
181  cxsysProcess_Delete(cp);
182  return result;
183}
184
185//----------------------------------------------------------------------------
186std::string encodeXML(std::string const& in, bool cdata)
187{
188  std::string xml;
189  const char* last = in.c_str();
190  for(const char* c = last; *c; ++c) {
191    switch(*c) {
192#   define XML(OUT)               \
193      xml.append(last, c - last); \
194      last = c + 1;               \
195      xml.append(OUT)
196    case '&': XML("&amp;"); break;
197    case '<': XML("&lt;"); break;
198    case '>': XML("&gt;"); break;
199    case '\'':
200      if(!cdata) {
201        XML("&apos;");
202      }
203      break;
204    case '"':
205      if(!cdata) {
206        XML("&quot;");
207      }
208      break;
209    default: break;
210#   undef XML
211    }
212  }
213  xml.append(last);
214  return xml;
215}
216
217#if defined(_WIN32)
218# include <windows.h>
219#endif
220
221//----------------------------------------------------------------------------
222void suppressInteractiveErrors()
223{
224#if defined(_WIN32)
225  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
226#endif
227}
Note: See TracBrowser for help on using the repository browser.