Skip to content

Commit

Permalink
Add support for feature flags
Browse files Browse the repository at this point in the history
This introduces a new type features_t that exposes feature flags. The intent
is to allow a deprecation/incremental adoption path. This is not a general
purpose configuration mechanism, but instead allows for compatibility during
the transition as features are added/removed.

Each feature has a user-presentable short name and a short description. Their
values are tracked in a struct features_t.

We start with one feature stderr_nocaret, but it's not hooked up yet.
  • Loading branch information
ridiculousfish committed May 6, 2018
1 parent 7cbc0c3 commit 14f766b
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 1 deletion.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ SET(FISH_SRCS
src/postfork.cpp src/proc.cpp src/reader.cpp src/sanity.cpp src/screen.cpp
src/signal.cpp src/tnode.cpp src/tokenizer.cpp src/utf8.cpp src/util.cpp
src/wcstringutil.cpp src/wgetopt.cpp src/wildcard.cpp src/wutil.cpp
src/future_feature_flags.cpp
)

# Header files are just globbed.
Expand Down
3 changes: 2 additions & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ FISH_OBJS := obj/autoload.o obj/builtin.o obj/builtin_bg.o obj/builtin_bind.o ob
obj/parse_productions.o obj/parse_tree.o obj/parse_util.o obj/parser.o \
obj/parser_keywords.o obj/path.o obj/postfork.o obj/proc.o obj/reader.o \
obj/sanity.o obj/screen.o obj/signal.o obj/tinyexpr.o obj/tokenizer.o obj/tnode.o obj/utf8.o \
obj/util.o obj/wcstringutil.o obj/wgetopt.o obj/wildcard.o obj/wutil.o
obj/util.o obj/wcstringutil.o obj/wgetopt.o obj/wildcard.o obj/wutil.o \
obj/future_feature_flags.o

FISH_INDENT_OBJS := obj/fish_indent.o obj/print_help.o $(FISH_OBJS)

Expand Down
25 changes: 25 additions & 0 deletions src/fish_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "expand.h"
#include "fallback.h" // IWYU pragma: keep
#include "function.h"
#include "future_feature_flags.h"
#include "highlight.h"
#include "history.h"
#include "input.h"
Expand Down Expand Up @@ -1352,6 +1353,29 @@ static void test_utf8() {
#endif
}

static void test_feature_flags() {
say(L"Testing future feature flags");
using ft = features_t;
ft f;
do_test(!f.test(ft::stderr_nocaret));
f.set(ft::stderr_nocaret, true);
do_test(f.test(ft::stderr_nocaret));
f.set(ft::stderr_nocaret, false);
do_test(!f.test(ft::stderr_nocaret));

// Ensure every metadata is represented once.
size_t counts[ft::flag_count] = {};
for (const auto &md : ft::metadata) {
counts[md.flag]++;
}
for (size_t c : counts) {
do_test(c == 1);
}
do_test(ft::metadata[ft::stderr_nocaret].name == wcstring(L"stderr-nocaret"));
do_test(ft::metadata_for(L"stderr-nocaret") == &ft::metadata[ft::stderr_nocaret]);
do_test(ft::metadata_for(L"not-a-flag") == nullptr);
}

static void test_escape_sequences() {
say(L"Testing escape_sequences");
if (escape_code_length(L"") != 0) err(L"test_escape_sequences failed on line %d\n", __LINE__);
Expand Down Expand Up @@ -4611,6 +4635,7 @@ int main(int argc, char **argv) {
if (should_test_function("cancellation")) test_cancellation();
if (should_test_function("indents")) test_indents();
if (should_test_function("utf8")) test_utf8();
if (should_test_function("feature_flags")) test_feature_flags();
if (should_test_function("escape_sequences")) test_escape_sequences();
if (should_test_function("lru")) test_lru();
if (should_test_function("expand")) test_expand();
Expand Down
23 changes: 23 additions & 0 deletions src/future_feature_flags.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "config.h" // IWYU pragma: keep

#include <wchar.h>
#include "future_feature_flags.h"

/// The set of features applying to this instance.
static features_t global_features;

const features_t &fish_features() { return global_features; }

features_t &mutable_fish_features() { return global_features; }

const features_t::metadata_t features_t::metadata[features_t::flag_count] = {
{stderr_nocaret, L"stderr-nocaret", L"3.0", L"^ no longer redirects stderr"},
};

const struct features_t::metadata_t *features_t::metadata_for(const wchar_t *name) {
assert(name && "null flag name");
for (const auto &md : metadata) {
if (!wcscmp(name, md.name)) return &md;
}
return nullptr;
}
63 changes: 63 additions & 0 deletions src/future_feature_flags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Flags to enable upcoming features
#ifndef FISH_FUTURE_FEATURE_FLAGS_H
#define FISH_FUTURE_FEATURE_FLAGS_H

#include <assert.h>

class features_t {
public:
/// The list of flags.
enum flag_t {
/// Whether ^ is supported for stderr redirection.
stderr_nocaret,

/// The number of flags.
flag_count
};

/// Return whether a flag is set.
bool test(flag_t f) const {
assert(f >= 0 && f < flag_count && "Invalid flag");
return values[f];
}

/// Set a flag.
void set(flag_t f, bool value) {
assert(f >= 0 && f < flag_count && "Invalid flag");
values[f] = value;
}

/// Metadata about feature flags.
struct metadata_t {
/// The flag itself.
features_t::flag_t flag;

/// User-presentable short name of the feature flag.
const wchar_t *name;

/// Comma-separated list of feature groups.
const wchar_t *groups;

/// User-presentable description of the feature flag.
const wchar_t *description;
};

/// The metadata, indexed by flag.
static const metadata_t metadata[flag_count];

/// Return the metadata for a particular name, or nullptr if not found.
static const struct metadata_t *metadata_for(const wchar_t *name);

private:
/// Values for the flags.
bool values[flag_count] = {};
};

/// Return the global set of features for fish. This is const to prevent accidental mutation.
const features_t &fish_features();

/// Return the global set of features for fish, but mutable. In general fish features should be set
/// at startup only.
features_t &mutable_fish_features();

#endif

0 comments on commit 14f766b

Please sign in to comment.