1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 /*!
21 * \file util.h
22 * \brief Defines some common utility function..
23 */
24 #ifndef TVM_COMMON_UTIL_H_
25 #define TVM_COMMON_UTIL_H_
26
27 #include <stdio.h>
28 #ifndef _WIN32
29 #include <sys/wait.h>
30 #include <sys/types.h>
31 #endif
32 #include <vector>
33 #include <string>
34 #include <sstream>
35 #include <algorithm>
36 #include <array>
37 #include <cctype>
38 #include <memory>
39
40 namespace tvm {
41 namespace common {
42 /*!
43 * \brief TVMPOpen wrapper of popen between windows / unix.
44 * \param command executed command
45 * \param type "r" is for reading or "w" for writing.
46 * \return normal standard stream
47 */
TVMPOpen(const char * command,const char * type)48 inline FILE* TVMPOpen(const char* command, const char* type) {
49 #if defined(_WIN32)
50 return _popen(command, type);
51 #else
52 return popen(command, type);
53 #endif
54 }
55
56 /*!
57 * \brief TVMPClose wrapper of pclose between windows / linux
58 * \param stream the stream needed to be close.
59 * \return exit status
60 */
TVMPClose(FILE * stream)61 inline int TVMPClose(FILE* stream) {
62 #if defined(_WIN32)
63 return _pclose(stream);
64 #else
65 return pclose(stream);
66 #endif
67 }
68
69 /*!
70 * \brief TVMWifexited wrapper of WIFEXITED between windows / linux
71 * \param status The status field that was filled in by the wait or waitpid function
72 * \return the exit code of the child process
73 */
TVMWifexited(int status)74 inline int TVMWifexited(int status) {
75 #if defined(_WIN32)
76 return (status != 3);
77 #else
78 return WIFEXITED(status);
79 #endif
80 }
81
82 /*!
83 * \brief TVMWexitstatus wrapper of WEXITSTATUS between windows / linux
84 * \param status The status field that was filled in by the wait or waitpid function.
85 * \return the child process exited normally or not
86 */
TVMWexitstatus(int status)87 inline int TVMWexitstatus(int status) {
88 #if defined(_WIN32)
89 return status;
90 #else
91 return WEXITSTATUS(status);
92 #endif
93 }
94
95
96 /*!
97 * \brief IsNumber check whether string is a number.
98 * \param str input string
99 * \return result of operation.
100 */
IsNumber(const std::string & str)101 inline bool IsNumber(const std::string& str) {
102 return !str.empty() && std::find_if(str.begin(),
103 str.end(), [](char c) { return !std::isdigit(c); }) == str.end();
104 }
105
106 /*!
107 * \brief split Split the string based on delimiter
108 * \param str Input string
109 * \param delim The delimiter.
110 * \return vector of strings which are splitted.
111 */
Split(const std::string & str,char delim)112 inline std::vector<std::string> Split(const std::string& str, char delim) {
113 std::string item;
114 std::istringstream is(str);
115 std::vector<std::string> ret;
116 while (std::getline(is, item, delim)) {
117 ret.push_back(item);
118 }
119 return ret;
120 }
121
122 /*!
123 * \brief EndsWith check whether the strings ends with
124 * \param value The full string
125 * \param end The end substring
126 * \return bool The result.
127 */
EndsWith(std::string const & value,std::string const & end)128 inline bool EndsWith(std::string const& value, std::string const& end) {
129 if (end.size() <= value.size()) {
130 return std::equal(end.rbegin(), end.rend(), value.rbegin());
131 }
132 return false;
133 }
134
135 /*!
136 * \brief Execute the command
137 * \param cmd The command we want to execute
138 * \param err_msg The error message if we have
139 * \return executed output status
140 */
Execute(std::string cmd,std::string * err_msg)141 inline int Execute(std::string cmd, std::string* err_msg) {
142 std::array<char, 128> buffer;
143 std::string result;
144 cmd += " 2>&1";
145 FILE* fd = TVMPOpen(cmd.c_str(), "r");
146 while (fgets(buffer.data(), buffer.size(), fd) != nullptr) {
147 *err_msg += buffer.data();
148 }
149 int status = TVMPClose(fd);
150 if (TVMWifexited(status)) {
151 return TVMWexitstatus(status);
152 }
153 return 255;
154 }
155
156 } // namespace common
157 } // namespace tvm
158 #endif // TVM_COMMON_UTIL_H_
159