summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock12
-rw-r--r--Cargo.toml2
-rw-r--r--globset/Cargo.toml10
-rw-r--r--globset/src/lib.rs (renamed from src/glob.rs)10
-rw-r--r--globset/src/pathutil.rs38
-rw-r--r--src/gitignore.rs16
-rw-r--r--src/main.rs3
-rw-r--r--src/types.rs20
9 files changed, 88 insertions, 24 deletions
diff --git a/.gitignore b/.gitignore
index 0ab88579..27b8f40d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
tags
target
/grep/Cargo.lock
+/globset/Cargo.lock
diff --git a/Cargo.lock b/Cargo.lock
index 12f5b17f..21640763 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5,8 +5,8 @@ dependencies = [
"deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "globset 0.1.0",
"grep 0.1.3",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -79,6 +79,16 @@ version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "globset"
+version = "0.1.0"
+dependencies = [
+ "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "grep"
version = "0.1.3"
dependencies = [
diff --git a/Cargo.toml b/Cargo.toml
index 9506c584..b4446974 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,7 +26,7 @@ path = "tests/tests.rs"
deque = "0.3"
docopt = "0.6"
env_logger = "0.3"
-fnv = "1.0"
+globset = { version = "0.1.0", path = "globset" }
grep = { version = "0.1.3", path = "grep" }
lazy_static = "0.2"
libc = "0.2"
diff --git a/globset/Cargo.toml b/globset/Cargo.toml
new file mode 100644
index 00000000..48e375fb
--- /dev/null
+++ b/globset/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "globset"
+version = "0.1.0"
+authors = ["Andrew Gallant <jamslam@gmail.com>"]
+
+[dependencies]
+fnv = "1.0"
+lazy_static = "0.2"
+memchr = "0.1"
+regex = "0.1.77"
diff --git a/src/glob.rs b/globset/src/lib.rs
index 295474cc..b5cbb5be 100644
--- a/src/glob.rs
+++ b/globset/src/lib.rs
@@ -26,6 +26,12 @@ to make its way into `glob` proper.
// at the .gitignore for the chromium repo---just about every pattern satisfies
// that assumption.)
+extern crate fnv;
+#[macro_use]
+extern crate lazy_static;
+extern crate memchr;
+extern crate regex;
+
use std::borrow::Cow;
use std::collections::HashMap;
use std::error::Error as StdError;
@@ -36,12 +42,12 @@ use std::iter;
use std::path::Path;
use std::str;
-use fnv;
-use regex;
use regex::bytes::Regex;
use pathutil::file_name;
+mod pathutil;
+
lazy_static! {
static ref FILE_SEPARATORS: String = regex::quote(r"/\");
}
diff --git a/globset/src/pathutil.rs b/globset/src/pathutil.rs
new file mode 100644
index 00000000..73caf0e5
--- /dev/null
+++ b/globset/src/pathutil.rs
@@ -0,0 +1,38 @@
+use std::ffi::OsStr;
+use std::path::Path;
+
+/// The final component of the path, if it is a normal file.
+///
+/// If the path terminates in ., .., or consists solely of a root of prefix,
+/// file_name will return None.
+#[cfg(unix)]
+pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
+ path: &'a P,
+) -> Option<&'a OsStr> {
+ use std::os::unix::ffi::OsStrExt;
+ use memchr::memrchr;
+
+ let path = path.as_ref().as_os_str().as_bytes();
+ if path.is_empty() {
+ return None;
+ } else if path.len() == 1 && path[0] == b'.' {
+ return None;
+ } else if path.last() == Some(&b'.') {
+ return None;
+ } else if path.len() >= 2 && &path[path.len() - 2..] == &b".."[..] {
+ return None;
+ }
+ let last_slash = memrchr(b'/', path).map(|i| i + 1).unwrap_or(0);
+ Some(OsStr::from_bytes(&path[last_slash..]))
+}
+
+/// The final component of the path, if it is a normal file.
+///
+/// If the path terminates in ., .., or consists solely of a root of prefix,
+/// file_name will return None.
+#[cfg(not(unix))]
+pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
+ path: &'a P,
+) -> Option<&'a OsStr> {
+ path.as_ref().file_name()
+}
diff --git a/src/gitignore.rs b/src/gitignore.rs
index bfc83846..6191f0b5 100644
--- a/src/gitignore.rs
+++ b/src/gitignore.rs
@@ -28,15 +28,15 @@ use std::fs::File;
use std::io::{self, BufRead};
use std::path::{Path, PathBuf};
+use globset;
use regex;
-use glob;
use pathutil::{is_file_name, strip_prefix};
/// Represents an error that can occur when parsing a gitignore file.
#[derive(Debug)]
pub enum Error {
- Glob(glob::Error),
+ Glob(globset::Error),
Regex(regex::Error),
Io(io::Error),
}
@@ -61,8 +61,8 @@ impl fmt::Display for Error {
}
}
-impl From<glob::Error> for Error {
- fn from(err: glob::Error) -> Error {
+impl From<globset::Error> for Error {
+ fn from(err: globset::Error) -> Error {
Error::Glob(err)
}
}
@@ -82,7 +82,7 @@ impl From<io::Error> for Error {
/// Gitignore is a matcher for the glob patterns in a single gitignore file.
#[derive(Clone, Debug)]
pub struct Gitignore {
- set: glob::Set,
+ set: globset::Set,
root: PathBuf,
patterns: Vec<Pattern>,
num_ignores: u64,
@@ -207,7 +207,7 @@ impl<'a> Match<'a> {
/// GitignoreBuilder constructs a matcher for a single set of globs from a
/// .gitignore file.
pub struct GitignoreBuilder {
- builder: glob::SetBuilder,
+ builder: globset::SetBuilder,
root: PathBuf,
patterns: Vec<Pattern>,
}
@@ -237,7 +237,7 @@ impl GitignoreBuilder {
pub fn new<P: AsRef<Path>>(root: P) -> GitignoreBuilder {
let root = strip_prefix("./", root.as_ref()).unwrap_or(root.as_ref());
GitignoreBuilder {
- builder: glob::SetBuilder::new(),
+ builder: globset::SetBuilder::new(),
root: root.to_path_buf(),
patterns: vec![],
}
@@ -299,7 +299,7 @@ impl GitignoreBuilder {
whitelist: false,
only_dir: false,
};
- let mut opts = glob::MatchOptions::default();
+ let mut opts = globset::MatchOptions::default();
let has_slash = line.chars().any(|c| c == '/');
let is_absolute = line.chars().nth(0).unwrap() == '/';
if line.starts_with("\\!") || line.starts_with("\\#") {
diff --git a/src/main.rs b/src/main.rs
index 5f8b3dfe..c70a3c52 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,7 @@
extern crate deque;
extern crate docopt;
extern crate env_logger;
-extern crate fnv;
+extern crate globset;
extern crate grep;
#[cfg(windows)]
extern crate kernel32;
@@ -61,7 +61,6 @@ macro_rules! eprintln {
mod args;
mod atty;
mod gitignore;
-mod glob;
mod ignore;
mod out;
mod pathutil;
diff --git a/src/types.rs b/src/types.rs
index 320a7247..362d0f03 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -11,7 +11,7 @@ use std::path::Path;
use regex;
use gitignore::{Match, Pattern};
-use glob::{self, MatchOptions};
+use globset::{self, MatchOptions};
const TYPE_EXTENSIONS: &'static [(&'static str, &'static [&'static str])] = &[
("asm", &["*.asm", "*.s", "*.S"]),
@@ -93,7 +93,7 @@ pub enum Error {
/// A user specified file type definition could not be parsed.
InvalidDefinition,
/// There was an error building the matcher (probably a bad glob).
- Glob(glob::Error),
+ Glob(globset::Error),
/// There was an error compiling a glob as a regex.
Regex(regex::Error),
}
@@ -125,8 +125,8 @@ impl fmt::Display for Error {
}
}
-impl From<glob::Error> for Error {
- fn from(err: glob::Error) -> Error {
+impl From<globset::Error> for Error {
+ fn from(err: globset::Error) -> Error {
Error::Glob(err)
}
}
@@ -160,8 +160,8 @@ impl FileTypeDef {
#[derive(Clone, Debug)]
pub struct Types {
defs: Vec<FileTypeDef>,
- selected: Option<glob::SetYesNo>,
- negated: Option<glob::SetYesNo>,
+ selected: Option<globset::SetYesNo>,
+ negated: Option<globset::SetYesNo>,
has_selected: bool,
unmatched_pat: Pattern,
}
@@ -174,8 +174,8 @@ impl Types {
/// If has_selected is true, then at least one file type was selected.
/// Therefore, any non-matches should be ignored.
fn new(
- selected: Option<glob::SetYesNo>,
- negated: Option<glob::SetYesNo>,
+ selected: Option<globset::SetYesNo>,
+ negated: Option<globset::SetYesNo>,
has_selected: bool,
defs: Vec<FileTypeDef>,
) -> Types {
@@ -271,7 +271,7 @@ impl TypesBuilder {
if self.selected.is_empty() {
None
} else {
- let mut bset = glob::SetBuilder::new();
+ let mut bset = globset::SetBuilder::new();
for name in &self.selected {
let globs = match self.types.get(name) {
Some(globs) => globs,
@@ -290,7 +290,7 @@ impl TypesBuilder {
if self.negated.is_empty() {
None
} else {
- let mut bset = glob::SetBuilder::new();
+ let mut bset = globset::SetBuilder::new();
for name in &self.negated {
let globs = match self.types.get(name) {
Some(globs) => globs,