You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
5.2 KiB
114 lines
5.2 KiB
// Copyright 2022 The Centipede Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifndef THIRD_PARTY_CENTIPEDE_GOOGLE_CONFIG_FILE_H_
|
|
#define THIRD_PARTY_CENTIPEDE_GOOGLE_CONFIG_FILE_H_
|
|
|
|
#include <filesystem> // NOLINT
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "absl/base/nullability.h"
|
|
#include "./centipede/config_init.h"
|
|
|
|
// TODO(ussuri): Move implementation-only functions to .cc.
|
|
|
|
namespace fuzztest::internal {
|
|
|
|
// Constructs an augmented copy of `argv` with any substrings appearing in the
|
|
// original elements replaced according to a list replacements.
|
|
// TODO(ussuri): Make more robust. What we really want is replace any possible
|
|
// form of --flag=value with an equivalent form of --new_flag=new_value.
|
|
// TODO(ussuri): Remove and just use the required bits of logic in .cc.
|
|
class AugmentedArgvWithCleanup final {
|
|
public:
|
|
using Replacements = std::vector<std::pair<std::string, std::string>>;
|
|
using BackingResourcesCleanup = std::function<void()>;
|
|
|
|
// Ctor. The `orig_argc` and `orig_argv` are compatible with those passed to a
|
|
// main(). Each item in `orig_argv` is first processed with
|
|
// `flag_replacements` if the item has the format "-flag", "-flag=...",
|
|
// "--flag", or "--flag=", and the flag name matches. Then the `replacements`
|
|
// map should map an old substring to a new one. Only simple, one-stage string
|
|
// replacement is performed: no regexes, placeholders, envvars or recursion.
|
|
// The `cleanup` callback should clean up any temporary resources backing the
|
|
// modified flags, such as temporary files.
|
|
AugmentedArgvWithCleanup(const std::vector<std::string>& orig_argv,
|
|
const Replacements& flag_replacements,
|
|
const Replacements& replacements,
|
|
BackingResourcesCleanup&& cleanup);
|
|
// Dtor. Invokes `cleanup_`.
|
|
~AugmentedArgvWithCleanup();
|
|
|
|
// Movable by not copyable to prevent `cleanup_` from running twice.
|
|
AugmentedArgvWithCleanup(const AugmentedArgvWithCleanup&) = delete;
|
|
AugmentedArgvWithCleanup& operator=(const AugmentedArgvWithCleanup&) = delete;
|
|
AugmentedArgvWithCleanup(AugmentedArgvWithCleanup&&) noexcept;
|
|
AugmentedArgvWithCleanup& operator=(AugmentedArgvWithCleanup&&) noexcept;
|
|
|
|
// The new argc. Currently, will always match the original argc.
|
|
int argc() const { return static_cast<int>(argv_.size()); }
|
|
// The new, possibly augmented argv. Note that all its char* elements are
|
|
// backed by newly allocated std::strings, so they will all be different from
|
|
// their counterparts in the original argv.
|
|
const std::vector<std::string>& argv() const { return argv_; }
|
|
// Whether the original argv has been augmented from the original, i.e. if any
|
|
// of the requested string replacements actually occurred.
|
|
bool was_augmented() const { return was_augmented_; }
|
|
|
|
private:
|
|
std::vector<std::string> argv_;
|
|
bool was_augmented_;
|
|
BackingResourcesCleanup cleanup_;
|
|
};
|
|
|
|
// Replaces any --config=<config_file> in `argv` (or any alternative form of
|
|
// that flag) with a --flagfile=<possibly_localized_config_file>, where
|
|
// localization means that a remote <config_file> is copied to a temporary local
|
|
// mirror. If <config_file> is already local, it is used as-is.
|
|
//
|
|
// The remote file contents is additionally checked for possible nested
|
|
// --config, --save_config and --flagfile: such usage is currently unsupported.
|
|
//
|
|
// The returned AugmentedArgvWithCleanup deletes the localized files (if any) in
|
|
// dtor.
|
|
AugmentedArgvWithCleanup LocalizeConfigFilesInArgv(
|
|
const std::vector<std::string>& argv);
|
|
|
|
// If --save_config=<path> was passed on the command line, saves _all_
|
|
// Centipede flags (i.e. those specified on the command line AND the defaulted
|
|
// ones) to <path> in the format compatible with --config (defined by
|
|
// Centipede), as well as --flagfile (defined by Abseil Flags), and returns
|
|
// <path>. Otherwise, returns an empty string. If the <path>'s extension is .sh,
|
|
// saves a runnable script instead.
|
|
std::filesystem::path MaybeSaveConfigToFile(
|
|
const std::vector<std::string>& leftover_argv);
|
|
|
|
// Initializes Centipede:
|
|
// - Calls `InitRuntime()` at the right time to initialize the runtime
|
|
// subsystems and perform the initial flag parsing.
|
|
// - Handles config-related flags: loads the config from --config, if any,
|
|
// and saves it to --save_config (or --update_config), if any.
|
|
// - Logs the final resolved config.
|
|
// - Returns the runtime state that the caller should take ownership of and
|
|
// keep alive the duration of the process.
|
|
[[nodiscard]] std::unique_ptr<RuntimeState> InitCentipede(
|
|
int argc, char** absl_nonnull argv);
|
|
|
|
} // namespace fuzztest::internal
|
|
|
|
#endif // THIRD_PARTY_CENTIPEDE_GOOGLE_CONFIG_FILE_H_
|
|
|