blob: a33ed38aee7b623f1182319490f87ba8ee50dec8 [file] [log] [blame]
// Copyright 2010 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVTOOLS_GOMA_CLIENT_UTIL_H_
#define DEVTOOLS_GOMA_CLIENT_UTIL_H_
#ifndef _WIN32
# include <unistd.h>
#else
# include <direct.h>
#endif
#include <algorithm>
#include <cmath>
#include <cstring>
#include <sstream>
#include <string>
#include <vector>
#ifdef _WIN32
#include "config_win.h"
#endif
#include "absl/strings/ascii.h"
#include "absl/types/optional.h"
#include "google/protobuf/repeated_field.h"
namespace devtools_goma {
// Options to be used with ReadCommandOutput to specify which command output
// will be returned.
enum CommandOutputOption {
MERGE_STDOUT_STDERR,
STDOUT_ONLY,
};
typedef std::string (*ReadCommandOutputFunc)(
const std::string& prog,
const std::vector<std::string>& argv,
const std::vector<std::string>& env,
const std::string& cwd,
CommandOutputOption option,
int32_t* status);
// Installs new ReadCommandOutput function.
// ReadCommandOutput function should be installed before calling it.
void InstallReadCommandOutputFunc(ReadCommandOutputFunc func);
// Calls current ReadCommandOutput function.
// If exit status of the command is not zero and |status| == NULL,
// then fatal error.
// Note: You MUST call InstallReadCommandOuptutFunc beforehand.
std::string ReadCommandOutput(const std::string& prog,
const std::vector<std::string>& argv,
const std::vector<std::string>& env,
const std::string& cwd,
CommandOutputOption option,
int32_t* status);
// Platform independent getenv.
// Note: in chromium/win, gomacc can only get environments that was
// extracted by build/toolchain/win/setup_toolchain.py.
absl::optional<std::string> GetEnv(const std::string& name);
// Platform independent setenv.
void SetEnv(const std::string& name, const std::string& value);
// Gets iterator to the environment variable entry.
template <typename Iter>
Iter GetEnvIterFromEnvIter(Iter env_begin,
Iter env_end,
const std::string& name,
bool ignore_case) {
std::string key = name + "=";
if (ignore_case)
absl::AsciiStrToLower(&key);
for (Iter i = env_begin; i != env_end; ++i) {
std::string token = i->substr(0, key.length());
if (ignore_case)
absl::AsciiStrToLower(&token);
if (token == key) {
return i;
}
}
return env_end;
}
// Gets an environment variable between |envs_begin| and |envs_end|.
// Do not care |name| case if |ignore_case| is true.
template <typename Iter>
std::string GetEnvFromEnvIter(Iter env_begin,
Iter env_end,
const std::string& name,
bool ignore_case) {
Iter found = GetEnvIterFromEnvIter(env_begin, env_end, name, ignore_case);
if (found == env_end)
return "";
return found->substr(name.length() + 1); // Also cuts off "=".
}
// Gets an environment variable between |envs_begin| and |envs_end|.
// It automatically ignores case according to the platform.
template <typename Iter>
std::string GetEnvFromEnvIter(Iter env_begin,
Iter env_end,
const std::string& name) {
#ifdef _WIN32
return GetEnvFromEnvIter(env_begin, env_end, name, true);
#else
return GetEnvFromEnvIter(env_begin, env_end, name, false);
#endif
}
// Replace an environment variable |name| value to |to_replace|
// between |envs_begin| and |envs_end|.
// It automatically ignores case according to the platform.
template <typename Iter>
bool ReplaceEnvInEnvIter(Iter env_begin,
Iter env_end,
const std::string& name,
const std::string& to_replace) {
#ifdef _WIN32
Iter found = GetEnvIterFromEnvIter(env_begin, env_end, name, true);
#else
Iter found = GetEnvIterFromEnvIter(env_begin, env_end, name, false);
#endif
if (found != env_end) {
found->replace(name.size() + 1, found->size() - (name.size() + 1),
to_replace);
return true;
}
return false;
}
// Platform independent getpid function.
pid_t Getpid();
// Wrapper for chdir(). VS2015 warns using chdir().
// Returns true if succeeded.
inline bool Chdir(const char* path) {
#ifndef _WIN32
return chdir(path) == 0;
#else
return _chdir(path) == 0;
#endif
}
// Returns sum of all integers in |input|, which is a repeated field of int32s.
int64_t SumRepeatedInt32(
const google::protobuf::RepeatedField<google::protobuf::int32>& input);
} // namespace devtools_goma
// Convert absl::StrSplit result to std::vector<string>
// Because of clang-cl.exe bug, we cannot write
// std::vector<string> vs = absl::StrSplit(...);
// This function provides an wrapper to avoid this bug.
// After clang-cl.exe or absl has been fixed, this function be removed.
// See b/73514249 for more detail.
template <typename SplitResult>
std::vector<std::string> ToVector(SplitResult split_result) {
std::vector<std::string> result;
for (auto&& s : split_result) {
result.push_back(std::string(s));
}
return result;
}
// Used for printing absl::optional<T>. T must be compatible with the <<
// operator to pass it to a stringstream.
template <typename T>
std::string OptionalToString(const absl::optional<T>& opt_value) {
std::stringstream ss;
if (opt_value.has_value()) {
ss << *opt_value;
} else {
ss << "(none)";
}
return ss.str();
}
#endif // DEVTOOLS_GOMA_CLIENT_UTIL_H_