Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/libmv/third_party/gflags/gflags_completions.cc')
-rw-r--r--extern/libmv/third_party/gflags/gflags_completions.cc769
1 files changed, 0 insertions, 769 deletions
diff --git a/extern/libmv/third_party/gflags/gflags_completions.cc b/extern/libmv/third_party/gflags/gflags_completions.cc
deleted file mode 100644
index 3a476230ff9..00000000000
--- a/extern/libmv/third_party/gflags/gflags_completions.cc
+++ /dev/null
@@ -1,769 +0,0 @@
-// Copyright (c) 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// ---
-
-// Bash-style command line flag completion for C++ binaries
-//
-// This module implements bash-style completions. It achieves this
-// goal in the following broad chunks:
-//
-// 1) Take a to-be-completed word, and examine it for search hints
-// 2) Identify all potentially matching flags
-// 2a) If there are no matching flags, do nothing.
-// 2b) If all matching flags share a common prefix longer than the
-// completion word, output just that matching prefix
-// 3) Categorize those flags to produce a rough ordering of relevence.
-// 4) Potentially trim the set of flags returned to a smaller number
-// that bash is happier with
-// 5) Output the matching flags in groups ordered by relevence.
-// 5a) Force bash to place most-relevent groups at the top of the list
-// 5b) Trim most flag's descriptions to fit on a single terminal line
-
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> // for strlen
-
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "gflags.h"
-#include "util.h"
-
-using std::set;
-using std::string;
-using std::vector;
-
-
-DEFINE_string(tab_completion_word, "",
- "If non-empty, HandleCommandLineCompletions() will hijack the "
- "process and attempt to do bash-style command line flag "
- "completion on this value.");
-DEFINE_int32(tab_completion_columns, 80,
- "Number of columns to use in output for tab completion");
-
-
-namespace GFLAGS_NAMESPACE {
-
-
-namespace {
-// Function prototypes and Type forward declarations. Code may be
-// more easily understood if it is roughly ordered according to
-// control flow, rather than by C's "declare before use" ordering
-struct CompletionOptions;
-struct NotableFlags;
-
-// The entry point if flag completion is to be used.
-static void PrintFlagCompletionInfo(void);
-
-
-// 1) Examine search word
-static void CanonicalizeCursorWordAndSearchOptions(
- const string &cursor_word,
- string *canonical_search_token,
- CompletionOptions *options);
-
-static bool RemoveTrailingChar(string *str, char c);
-
-
-// 2) Find all matches
-static void FindMatchingFlags(
- const vector<CommandLineFlagInfo> &all_flags,
- const CompletionOptions &options,
- const string &match_token,
- set<const CommandLineFlagInfo *> *all_matches,
- string *longest_common_prefix);
-
-static bool DoesSingleFlagMatch(
- const CommandLineFlagInfo &flag,
- const CompletionOptions &options,
- const string &match_token);
-
-
-// 3) Categorize matches
-static void CategorizeAllMatchingFlags(
- const set<const CommandLineFlagInfo *> &all_matches,
- const string &search_token,
- const string &module,
- const string &package_dir,
- NotableFlags *notable_flags);
-
-static void TryFindModuleAndPackageDir(
- const vector<CommandLineFlagInfo> all_flags,
- string *module,
- string *package_dir);
-
-
-// 4) Decide which flags to use
-static void FinalizeCompletionOutput(
- const set<const CommandLineFlagInfo *> &matching_flags,
- CompletionOptions *options,
- NotableFlags *notable_flags,
- vector<string> *completions);
-
-static void RetrieveUnusedFlags(
- const set<const CommandLineFlagInfo *> &matching_flags,
- const NotableFlags &notable_flags,
- set<const CommandLineFlagInfo *> *unused_flags);
-
-
-// 5) Output matches
-static void OutputSingleGroupWithLimit(
- const set<const CommandLineFlagInfo *> &group,
- const string &line_indentation,
- const string &header,
- const string &footer,
- bool long_output_format,
- int *remaining_line_limit,
- size_t *completion_elements_added,
- vector<string> *completions);
-
-// (helpers for #5)
-static string GetShortFlagLine(
- const string &line_indentation,
- const CommandLineFlagInfo &info);
-
-static string GetLongFlagLine(
- const string &line_indentation,
- const CommandLineFlagInfo &info);
-
-
-//
-// Useful types
-
-// Try to deduce the intentions behind this completion attempt. Return the
-// canonical search term in 'canonical_search_token'. Binary search options
-// are returned in the various booleans, which should all have intuitive
-// semantics, possibly except:
-// - return_all_matching_flags: Generally, we'll trim the number of
-// returned candidates to some small number, showing those that are
-// most likely to be useful first. If this is set, however, the user
-// really does want us to return every single flag as an option.
-// - force_no_update: Any time we output lines, all of which share a
-// common prefix, bash will 'helpfully' not even bother to show the
-// output, instead changing the current word to be that common prefix.
-// If it's clear this shouldn't happen, we'll set this boolean
-struct CompletionOptions {
- bool flag_name_substring_search;
- bool flag_location_substring_search;
- bool flag_description_substring_search;
- bool return_all_matching_flags;
- bool force_no_update;
-};
-
-// Notable flags are flags that are special or preferred for some
-// reason. For example, flags that are defined in the binary's module
-// are expected to be much more relevent than flags defined in some
-// other random location. These sets are specified roughly in precedence
-// order. Once a flag is placed in one of these 'higher' sets, it won't
-// be placed in any of the 'lower' sets.
-struct NotableFlags {
- typedef set<const CommandLineFlagInfo *> FlagSet;
- FlagSet perfect_match_flag;
- FlagSet module_flags; // Found in module file
- FlagSet package_flags; // Found in same directory as module file
- FlagSet most_common_flags; // One of the XXX most commonly supplied flags
- FlagSet subpackage_flags; // Found in subdirectories of package
-};
-
-
-//
-// Tab completion implementation - entry point
-static void PrintFlagCompletionInfo(void) {
- string cursor_word = FLAGS_tab_completion_word;
- string canonical_token;
- CompletionOptions options = { };
- CanonicalizeCursorWordAndSearchOptions(
- cursor_word,
- &canonical_token,
- &options);
-
- DVLOG(1) << "Identified canonical_token: '" << canonical_token << "'";
-
- vector<CommandLineFlagInfo> all_flags;
- set<const CommandLineFlagInfo *> matching_flags;
- GetAllFlags(&all_flags);
- DVLOG(2) << "Found " << all_flags.size() << " flags overall";
-
- string longest_common_prefix;
- FindMatchingFlags(
- all_flags,
- options,
- canonical_token,
- &matching_flags,
- &longest_common_prefix);
- DVLOG(1) << "Identified " << matching_flags.size() << " matching flags";
- DVLOG(1) << "Identified " << longest_common_prefix
- << " as longest common prefix.";
- if (longest_common_prefix.size() > canonical_token.size()) {
- // There's actually a shared common prefix to all matching flags,
- // so may as well output that and quit quickly.
- DVLOG(1) << "The common prefix '" << longest_common_prefix
- << "' was longer than the token '" << canonical_token
- << "'. Returning just this prefix for completion.";
- fprintf(stdout, "--%s", longest_common_prefix.c_str());
- return;
- }
- if (matching_flags.empty()) {
- VLOG(1) << "There were no matching flags, returning nothing.";
- return;
- }
-
- string module;
- string package_dir;
- TryFindModuleAndPackageDir(all_flags, &module, &package_dir);
- DVLOG(1) << "Identified module: '" << module << "'";
- DVLOG(1) << "Identified package_dir: '" << package_dir << "'";
-
- NotableFlags notable_flags;
- CategorizeAllMatchingFlags(
- matching_flags,
- canonical_token,
- module,
- package_dir,
- &notable_flags);
- DVLOG(2) << "Categorized matching flags:";
- DVLOG(2) << " perfect_match: " << notable_flags.perfect_match_flag.size();
- DVLOG(2) << " module: " << notable_flags.module_flags.size();
- DVLOG(2) << " package: " << notable_flags.package_flags.size();
- DVLOG(2) << " most common: " << notable_flags.most_common_flags.size();
- DVLOG(2) << " subpackage: " << notable_flags.subpackage_flags.size();
-
- vector<string> completions;
- FinalizeCompletionOutput(
- matching_flags,
- &options,
- &notable_flags,
- &completions);
-
- if (options.force_no_update)
- completions.push_back("~");
-
- DVLOG(1) << "Finalized with " << completions.size()
- << " chosen completions";
-
- for (vector<string>::const_iterator it = completions.begin();
- it != completions.end();
- ++it) {
- DVLOG(9) << " Completion entry: '" << *it << "'";
- fprintf(stdout, "%s\n", it->c_str());
- }
-}
-
-
-// 1) Examine search word (and helper method)
-static void CanonicalizeCursorWordAndSearchOptions(
- const string &cursor_word,
- string *canonical_search_token,
- CompletionOptions *options) {
- *canonical_search_token = cursor_word;
- if (canonical_search_token->empty()) return;
-
- // Get rid of leading quotes and dashes in the search term
- if ((*canonical_search_token)[0] == '"')
- *canonical_search_token = canonical_search_token->substr(1);
- while ((*canonical_search_token)[0] == '-')
- *canonical_search_token = canonical_search_token->substr(1);
-
- options->flag_name_substring_search = false;
- options->flag_location_substring_search = false;
- options->flag_description_substring_search = false;
- options->return_all_matching_flags = false;
- options->force_no_update = false;
-
- // Look for all search options we can deduce now. Do this by walking
- // backwards through the term, looking for up to three '?' and up to
- // one '+' as suffixed characters. Consume them if found, and remove
- // them from the canonical search token.
- int found_question_marks = 0;
- int found_plusses = 0;
- while (true) {
- if (found_question_marks < 3 &&
- RemoveTrailingChar(canonical_search_token, '?')) {
- ++found_question_marks;
- continue;
- }
- if (found_plusses < 1 &&
- RemoveTrailingChar(canonical_search_token, '+')) {
- ++found_plusses;
- continue;
- }
- break;
- }
-
- switch (found_question_marks) { // all fallthroughs
- case 3: options->flag_description_substring_search = true;
- case 2: options->flag_location_substring_search = true;
- case 1: options->flag_name_substring_search = true;
- };
-
- options->return_all_matching_flags = (found_plusses > 0);
-}
-
-// Returns true if a char was removed
-static bool RemoveTrailingChar(string *str, char c) {
- if (str->empty()) return false;
- if ((*str)[str->size() - 1] == c) {
- *str = str->substr(0, str->size() - 1);
- return true;
- }
- return false;
-}
-
-
-// 2) Find all matches (and helper methods)
-static void FindMatchingFlags(
- const vector<CommandLineFlagInfo> &all_flags,
- const CompletionOptions &options,
- const string &match_token,
- set<const CommandLineFlagInfo *> *all_matches,
- string *longest_common_prefix) {
- all_matches->clear();
- bool first_match = true;
- for (vector<CommandLineFlagInfo>::const_iterator it = all_flags.begin();
- it != all_flags.end();
- ++it) {
- if (DoesSingleFlagMatch(*it, options, match_token)) {
- all_matches->insert(&*it);
- if (first_match) {
- first_match = false;
- *longest_common_prefix = it->name;
- } else {
- if (longest_common_prefix->empty() || it->name.empty()) {
- longest_common_prefix->clear();
- continue;
- }
- string::size_type pos = 0;
- while (pos < longest_common_prefix->size() &&
- pos < it->name.size() &&
- (*longest_common_prefix)[pos] == it->name[pos])
- ++pos;
- longest_common_prefix->erase(pos);
- }
- }
- }
-}
-
-// Given the set of all flags, the parsed match options, and the
-// canonical search token, produce the set of all candidate matching
-// flags for subsequent analysis or filtering.
-static bool DoesSingleFlagMatch(
- const CommandLineFlagInfo &flag,
- const CompletionOptions &options,
- const string &match_token) {
- // Is there a prefix match?
- string::size_type pos = flag.name.find(match_token);
- if (pos == 0) return true;
-
- // Is there a substring match if we want it?
- if (options.flag_name_substring_search &&
- pos != string::npos)
- return true;
-
- // Is there a location match if we want it?
- if (options.flag_location_substring_search &&
- flag.filename.find(match_token) != string::npos)
- return true;
-
- // TODO(user): All searches should probably be case-insensitive
- // (especially this one...)
- if (options.flag_description_substring_search &&
- flag.description.find(match_token) != string::npos)
- return true;
-
- return false;
-}
-
-// 3) Categorize matches (and helper method)
-
-// Given a set of matching flags, categorize them by
-// likely relevence to this specific binary
-static void CategorizeAllMatchingFlags(
- const set<const CommandLineFlagInfo *> &all_matches,
- const string &search_token,
- const string &module, // empty if we couldn't find any
- const string &package_dir, // empty if we couldn't find any
- NotableFlags *notable_flags) {
- notable_flags->perfect_match_flag.clear();
- notable_flags->module_flags.clear();
- notable_flags->package_flags.clear();
- notable_flags->most_common_flags.clear();
- notable_flags->subpackage_flags.clear();
-
- for (set<const CommandLineFlagInfo *>::const_iterator it =
- all_matches.begin();
- it != all_matches.end();
- ++it) {
- DVLOG(2) << "Examining match '" << (*it)->name << "'";
- DVLOG(7) << " filename: '" << (*it)->filename << "'";
- string::size_type pos = string::npos;
- if (!package_dir.empty())
- pos = (*it)->filename.find(package_dir);
- string::size_type slash = string::npos;
- if (pos != string::npos) // candidate for package or subpackage match
- slash = (*it)->filename.find(
- PATH_SEPARATOR,
- pos + package_dir.size() + 1);
-
- if ((*it)->name == search_token) {
- // Exact match on some flag's name
- notable_flags->perfect_match_flag.insert(*it);
- DVLOG(3) << "Result: perfect match";
- } else if (!module.empty() && (*it)->filename == module) {
- // Exact match on module filename
- notable_flags->module_flags.insert(*it);
- DVLOG(3) << "Result: module match";
- } else if (!package_dir.empty() &&
- pos != string::npos && slash == string::npos) {
- // In the package, since there was no slash after the package portion
- notable_flags->package_flags.insert(*it);
- DVLOG(3) << "Result: package match";
- } else if (false) {
- // In the list of the XXX most commonly supplied flags overall
- // TODO(user): Compile this list.
- DVLOG(3) << "Result: most-common match";
- } else if (!package_dir.empty() &&
- pos != string::npos && slash != string::npos) {
- // In a subdirectory of the package
- notable_flags->subpackage_flags.insert(*it);
- DVLOG(3) << "Result: subpackage match";
- }
-
- DVLOG(3) << "Result: not special match";
- }
-}
-
-static void PushNameWithSuffix(vector<string>* suffixes, const char* suffix) {
- suffixes->push_back(
- StringPrintf("/%s%s", ProgramInvocationShortName(), suffix));
-}
-
-static void TryFindModuleAndPackageDir(
- const vector<CommandLineFlagInfo> all_flags,
- string *module,
- string *package_dir) {
- module->clear();
- package_dir->clear();
-
- vector<string> suffixes;
- // TODO(user): There's some inherant ambiguity here - multiple directories
- // could share the same trailing folder and file structure (and even worse,
- // same file names), causing us to be unsure as to which of the two is the
- // actual package for this binary. In this case, we'll arbitrarily choose.
- PushNameWithSuffix(&suffixes, ".");
- PushNameWithSuffix(&suffixes, "-main.");
- PushNameWithSuffix(&suffixes, "_main.");
- // These four are new but probably merited?
- PushNameWithSuffix(&suffixes, "-test.");
- PushNameWithSuffix(&suffixes, "_test.");
- PushNameWithSuffix(&suffixes, "-unittest.");
- PushNameWithSuffix(&suffixes, "_unittest.");
-
- for (vector<CommandLineFlagInfo>::const_iterator it = all_flags.begin();
- it != all_flags.end();
- ++it) {
- for (vector<string>::const_iterator suffix = suffixes.begin();
- suffix != suffixes.end();
- ++suffix) {
- // TODO(user): Make sure the match is near the end of the string
- if (it->filename.find(*suffix) != string::npos) {
- *module = it->filename;
- string::size_type sep = it->filename.rfind(PATH_SEPARATOR);
- *package_dir = it->filename.substr(0, (sep == string::npos) ? 0 : sep);
- return;
- }
- }
- }
-}
-
-// Can't specialize template type on a locally defined type. Silly C++...
-struct DisplayInfoGroup {
- const char* header;
- const char* footer;
- set<const CommandLineFlagInfo *> *group;
-
- int SizeInLines() const {
- int size_in_lines = static_cast<int>(group->size()) + 1;
- if (strlen(header) > 0) {
- size_in_lines++;
- }
- if (strlen(footer) > 0) {
- size_in_lines++;
- }
- return size_in_lines;
- }
-};
-
-// 4) Finalize and trim output flag set
-static void FinalizeCompletionOutput(
- const set<const CommandLineFlagInfo *> &matching_flags,
- CompletionOptions *options,
- NotableFlags *notable_flags,
- vector<string> *completions) {
-
- // We want to output lines in groups. Each group needs to be indented
- // the same to keep its lines together. Unless otherwise required,
- // only 99 lines should be output to prevent bash from harassing the
- // user.
-
- // First, figure out which output groups we'll actually use. For each
- // nonempty group, there will be ~3 lines of header & footer, plus all
- // output lines themselves.
- int max_desired_lines = // "999999 flags should be enough for anyone. -dave"
- (options->return_all_matching_flags ? 999999 : 98);
- int lines_so_far = 0;
-
- vector<DisplayInfoGroup> output_groups;
- bool perfect_match_found = false;
- if (lines_so_far < max_desired_lines &&
- !notable_flags->perfect_match_flag.empty()) {
- perfect_match_found = true;
- DisplayInfoGroup group =
- { "",
- "==========",
- &notable_flags->perfect_match_flag };
- lines_so_far += group.SizeInLines();
- output_groups.push_back(group);
- }
- if (lines_so_far < max_desired_lines &&
- !notable_flags->module_flags.empty()) {
- DisplayInfoGroup group = {
- "-* Matching module flags *-",
- "===========================",
- &notable_flags->module_flags };
- lines_so_far += group.SizeInLines();
- output_groups.push_back(group);
- }
- if (lines_so_far < max_desired_lines &&
- !notable_flags->package_flags.empty()) {
- DisplayInfoGroup group = {
- "-* Matching package flags *-",
- "============================",
- &notable_flags->package_flags };
- lines_so_far += group.SizeInLines();
- output_groups.push_back(group);
- }
- if (lines_so_far < max_desired_lines &&
- !notable_flags->most_common_flags.empty()) {
- DisplayInfoGroup group = {
- "-* Commonly used flags *-",
- "=========================",
- &notable_flags->most_common_flags };
- lines_so_far += group.SizeInLines();
- output_groups.push_back(group);
- }
- if (lines_so_far < max_desired_lines &&
- !notable_flags->subpackage_flags.empty()) {
- DisplayInfoGroup group = {
- "-* Matching sub-package flags *-",
- "================================",
- &notable_flags->subpackage_flags };
- lines_so_far += group.SizeInLines();
- output_groups.push_back(group);
- }
-
- set<const CommandLineFlagInfo *> obscure_flags; // flags not notable
- if (lines_so_far < max_desired_lines) {
- RetrieveUnusedFlags(matching_flags, *notable_flags, &obscure_flags);
- if (!obscure_flags.empty()) {
- DisplayInfoGroup group = {
- "-* Other flags *-",
- "",
- &obscure_flags };
- lines_so_far += group.SizeInLines();
- output_groups.push_back(group);
- }
- }
-
- // Second, go through each of the chosen output groups and output
- // as many of those flags as we can, while remaining below our limit
- int remaining_lines = max_desired_lines;
- size_t completions_output = 0;
- int indent = static_cast<int>(output_groups.size()) - 1;
- for (vector<DisplayInfoGroup>::const_iterator it =
- output_groups.begin();
- it != output_groups.end();
- ++it, --indent) {
- OutputSingleGroupWithLimit(
- *it->group, // group
- string(indent, ' '), // line indentation
- string(it->header), // header
- string(it->footer), // footer
- perfect_match_found, // long format
- &remaining_lines, // line limit - reduces this by number printed
- &completions_output, // completions (not lines) added
- completions); // produced completions
- perfect_match_found = false;
- }
-
- if (completions_output != matching_flags.size()) {
- options->force_no_update = false;
- completions->push_back("~ (Remaining flags hidden) ~");
- } else {
- options->force_no_update = true;
- }
-}
-
-static void RetrieveUnusedFlags(
- const set<const CommandLineFlagInfo *> &matching_flags,
- const NotableFlags &notable_flags,
- set<const CommandLineFlagInfo *> *unused_flags) {
- // Remove from 'matching_flags' set all members of the sets of
- // flags we've already printed (specifically, those in notable_flags)
- for (set<const CommandLineFlagInfo *>::const_iterator it =
- matching_flags.begin();
- it != matching_flags.end();
- ++it) {
- if (notable_flags.perfect_match_flag.count(*it) ||
- notable_flags.module_flags.count(*it) ||
- notable_flags.package_flags.count(*it) ||
- notable_flags.most_common_flags.count(*it) ||
- notable_flags.subpackage_flags.count(*it))
- continue;
- unused_flags->insert(*it);
- }
-}
-
-// 5) Output matches (and helper methods)
-
-static void OutputSingleGroupWithLimit(
- const set<const CommandLineFlagInfo *> &group,
- const string &line_indentation,
- const string &header,
- const string &footer,
- bool long_output_format,
- int *remaining_line_limit,
- size_t *completion_elements_output,
- vector<string> *completions) {
- if (group.empty()) return;
- if (!header.empty()) {
- if (*remaining_line_limit < 2) return;
- *remaining_line_limit -= 2;
- completions->push_back(line_indentation + header);
- completions->push_back(line_indentation + string(header.size(), '-'));
- }
- for (set<const CommandLineFlagInfo *>::const_iterator it = group.begin();
- it != group.end() && *remaining_line_limit > 0;
- ++it) {
- --*remaining_line_limit;
- ++*completion_elements_output;
- completions->push_back(
- (long_output_format
- ? GetLongFlagLine(line_indentation, **it)
- : GetShortFlagLine(line_indentation, **it)));
- }
- if (!footer.empty()) {
- if (*remaining_line_limit < 1) return;
- --*remaining_line_limit;
- completions->push_back(line_indentation + footer);
- }
-}
-
-static string GetShortFlagLine(
- const string &line_indentation,
- const CommandLineFlagInfo &info) {
- string prefix;
- bool is_string = (info.type == "string");
- SStringPrintf(&prefix, "%s--%s [%s%s%s] ",
- line_indentation.c_str(),
- info.name.c_str(),
- (is_string ? "'" : ""),
- info.default_value.c_str(),
- (is_string ? "'" : ""));
- int remainder =
- FLAGS_tab_completion_columns - static_cast<int>(prefix.size());
- string suffix;
- if (remainder > 0)
- suffix =
- (static_cast<int>(info.description.size()) > remainder ?
- (info.description.substr(0, remainder - 3) + "...").c_str() :
- info.description.c_str());
- return prefix + suffix;
-}
-
-static string GetLongFlagLine(
- const string &line_indentation,
- const CommandLineFlagInfo &info) {
-
- string output = DescribeOneFlag(info);
-
- // Replace '-' with '--', and remove trailing newline before appending
- // the module definition location.
- string old_flagname = "-" + info.name;
- output.replace(
- output.find(old_flagname),
- old_flagname.size(),
- "-" + old_flagname);
- // Stick a newline and indentation in front of the type and default
- // portions of DescribeOneFlag()s description
- static const char kNewlineWithIndent[] = "\n ";
- output.replace(output.find(" type:"), 1, string(kNewlineWithIndent));
- output.replace(output.find(" default:"), 1, string(kNewlineWithIndent));
- output = StringPrintf("%s Details for '--%s':\n"
- "%s defined: %s",
- line_indentation.c_str(),
- info.name.c_str(),
- output.c_str(),
- info.filename.c_str());
-
- // Eliminate any doubled newlines that crept in. Specifically, if
- // DescribeOneFlag() decided to break the line just before "type"
- // or "default", we don't want to introduce an extra blank line
- static const string line_of_spaces(FLAGS_tab_completion_columns, ' ');
- static const char kDoubledNewlines[] = "\n \n";
- for (string::size_type newlines = output.find(kDoubledNewlines);
- newlines != string::npos;
- newlines = output.find(kDoubledNewlines))
- // Replace each 'doubled newline' with a single newline
- output.replace(newlines, sizeof(kDoubledNewlines) - 1, string("\n"));
-
- for (string::size_type newline = output.find('\n');
- newline != string::npos;
- newline = output.find('\n')) {
- int newline_pos = static_cast<int>(newline) % FLAGS_tab_completion_columns;
- int missing_spaces = FLAGS_tab_completion_columns - newline_pos;
- output.replace(newline, 1, line_of_spaces, 1, missing_spaces);
- }
- return output;
-}
-} // anonymous
-
-void HandleCommandLineCompletions(void) {
- if (FLAGS_tab_completion_word.empty()) return;
- PrintFlagCompletionInfo();
- gflags_exitfunc(0);
-}
-
-
-} // namespace GFLAGS_NAMESPACE