// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>   // for strlen

#include <set>
#include <string>
#include <utility>
#include <vector>

#include "config.h"
#include "gflags/gflags.h"
#include "gflags/gflags_completions.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
