blob: 42daa9178ebb5c8b41be41d40087f360affbdea0 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// TODO( Once possible, only define this for test code.
// In any case, we do not want to include tests options when generating
// boot option documentation.
#include <stdio.h>
#include <zircon/assert.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <string_view>
#include "test-types.h"
#include <lib/uart/all.h>
#include "types.h"
struct BootOptions; // Declared below.
// This points to the only instance of BootOptions that ever exists outside
// test code. It's allocated in reserved physical memory by physboot and then
// handed off to the kernel proper. A global by this name exists both in
// physboot with the physical address pointer and in the kernel with the
// virtual address pointer.
extern BootOptions* gBootOptions;
struct BootOptions {
// General string values get this done to each character.
static constexpr char SanitizeChar(char c) {
switch (c) {
// Only printable ASCII characters come through as is.
case ' ' ... '~':
return c;
// Other whitespace chars become ' '.
case '\n':
case '\r':
case '\t':
return ' ';
// Anything else becomes '.'.
return '.';
// Return the length in the out buffer filled with the sanitized contents of
// the input string.
static size_t SanitizeString(char* out, size_t out_size, std::string_view in) {
ZX_ASSERT(out_size >= in.size());
return std::transform(in.begin(), in.end(), out, SanitizeChar) - out;
// This modifies the string in place even though it's const.
static void Redact(std::string_view string) {
if (string.empty()) {
constexpr char kRedacted = 'x';
char* begin = const_cast<char*>(&string[0]);
char* end = begin + string.size();
std::fill(begin, end, kRedacted);
// Parse a string to an integer in C syntax.
static std::optional<int64_t> ParseInt(std::string_view);
// Split the command line into words and parse each one as an option. This
// can be called multiple times with separate command line fragments. Each
// word is processed in order and sets its corresponding member in this
// struct, replacing any earlier option argument or the initial default.
// If complain is set, print messages there if a key is not recognized.
void SetMany(std::string_view cmdline, FILE* complain = nullptr);
// Display the key, its value, and its default.
int Show(std::string_view key, bool defaults = true, FILE* out = stdout);
// Display all keys, values, and defaults.
void Show(bool defaults = true, FILE* out = stdout);
// Write out "key=value".
template <typename T>
static void Print(std::string_view key, const T& value, FILE* out = stdout) {
fprintf(out, "%.*s=", static_cast<int>(key.size()),;
PrintValue(value, out);
// Overloads parse and print values of various types.
// If the string can't be parsed in Parse, the member is not written.
#define OPTION_TYPE(T) \
void Parse(std::string_view, T BootOptions::*member); \
static void PrintValue(const T& value, FILE* out = stdout)
#if BOOT_OPTIONS_GENERATOR || defined(__x86_64__)
struct WordResult {
std::string_view key;
bool known = false;
// Returns true if the command-line word matches a known "key=value" or "key"
// string. If the value was parsable for the type of the key's member, then
// the member was updated, else it wasn't touched (but still returns true).
WordResult ParseWord(std::string_view);
#define DEFINE_OPTION(name, type, member, init, doc) type member init;
#include ""
#include ""
#include ""