Skip to content

Commit

Permalink
Make file / directory completion work properly on Windows.
Browse files Browse the repository at this point in the history
There were a couple of problems with this function on Windows. Different
separators and differences in how tilde expressions are resolved for
starters, but in addition there was no clear indication of what the
function's inputs or outputs were supposed to be, and there were no tests
to demonstrate its use.

To more easily paper over the differences between Windows paths,
non-Windows paths, and tilde expressions, I've ported this function to use
LLVM-based directory iteration (in fact, I would like to eliminate all of
LLDB's directory iteration code entirely since LLVM's is cleaner / more
efficient (i.e. it invokes fewer stat calls)). and llvm's portable path
manipulation library.

Since file and directory completion assumes you are referring to files and
directories on your local machine, it's safe to assume the path syntax
properties of the host in doing so, so LLVM's APIs are perfect for this.

I've also added a fairly robust set of unit tests. Since you can't really
predict what users will be on your machine, or what their home directories
will be, I added an interface called TildeExpressionResolver, and in the
unit test I've mocked up a fake implementation that acts like a unix
password database. This allows us to configure some fake users and home
directories in the test, so we can exercise all of those hard-to-test
codepaths that normally otherwise depend on the host.

Differential Revision: https://reviews.llvm.org/D30789

llvm-svn: 297585
  • Loading branch information
Zachary Turner committed Mar 12, 2017
1 parent 8b9373a commit d5bd3a1
Show file tree
Hide file tree
Showing 7 changed files with 613 additions and 166 deletions.
10 changes: 10 additions & 0 deletions lldb/include/lldb/Interpreter/CommandCompletions.h
Expand Up @@ -21,7 +21,10 @@
#include "lldb/Utility/RegularExpression.h"
#include "lldb/lldb-private.h"

#include "llvm/ADT/Twine.h"

namespace lldb_private {
struct TildeExpressionResolver;
class CommandCompletions {
public:
//----------------------------------------------------------------------
Expand Down Expand Up @@ -76,12 +79,19 @@ class CommandCompletions {
int max_return_elements, SearchFilter *searcher,
bool &word_complete, StringList &matches);

static int DiskFiles(const llvm::Twine &partial_file_name,
StringList &matches, TildeExpressionResolver &Resolver);

static int DiskDirectories(CommandInterpreter &interpreter,
llvm::StringRef partial_file_name,
int match_start_point, int max_return_elements,
SearchFilter *searcher, bool &word_complete,
StringList &matches);

static int DiskDirectories(const llvm::Twine &partial_file_name,
StringList &matches,
TildeExpressionResolver &Resolver);

static int SourceFiles(CommandInterpreter &interpreter,
llvm::StringRef partial_file_name,
int match_start_point, int max_return_elements,
Expand Down
57 changes: 57 additions & 0 deletions lldb/include/lldb/Utility/TildeExpressionResolver.h
@@ -0,0 +1,57 @@
//===--------------------- TildeExpressionResolver.h ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H
#define LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"

namespace lldb_private {
class TildeExpressionResolver {
public:
virtual ~TildeExpressionResolver();

/// \brief Resolve a Tilde Expression contained according to bash rules.
///
/// \param Expr Contains the tilde expression to resolve. A valid tilde
/// expression must begin with a tilde and contain only non
/// separator characters.
///
/// \param Output Contains the resolved tilde expression, or the original
/// input if the tilde expression could not be resolved.
///
/// \returns true if \p Expr was successfully resolved, false otherwise.
virtual bool ResolveExact(llvm::StringRef Expr,
llvm::SmallVectorImpl<char> &Output) = 0;

/// \brief Auto-complete a tilde expression with all matching values.
///
/// \param Expr Contains the tilde expression prefix to resolve. See
/// ResolveExact() for validity rules.
///
/// \param Output Contains all matching home directories, each one
/// itself unresolved (i.e. you need to call ResolveExact
/// on each item to turn it into a real path).
///
/// \returns true if there were any matches, false otherwise.
virtual bool ResolvePartial(llvm::StringRef Expr,
llvm::StringSet<> &Output) = 0;
};

class StandardTildeExpressionResolver : public TildeExpressionResolver {
public:
bool ResolveExact(llvm::StringRef Expr,
llvm::SmallVectorImpl<char> &Output) override;
bool ResolvePartial(llvm::StringRef Expr, llvm::StringSet<> &Output) override;
};
}

#endif // #ifndef LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H

0 comments on commit d5bd3a1

Please sign in to comment.