Upgrade rust/crates/clang-sys to 1.2.2 am: eabe835c04

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/clang-sys/+/1832738

Change-Id: Ia07396848c3f23e0d0ea689f7bbaf96b67b9fa23
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 630eef7..859474d 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "c9ae24a7a218e73e1eccd320174349eef5a3bd1a"
+    "sha1": "fa181dee9b829be68d581ec02583c0568576bbed"
   }
 }
diff --git a/Android.bp b/Android.bp
index 75f78f9..d834ae9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,4 @@
-// This file is generated by cargo2android.py --run --features=runtime,clang_10_0 --dependencies --copy-out.
+// This file is generated by cargo2android.py --run --features=runtime,clang_10_0 --copy-out.
 // Do not modify this file as changes will be overridden on upgrade.
 
 package {
@@ -31,6 +31,8 @@
 rust_library_host {
     name: "libclang_sys",
     crate_name: "clang_sys",
+    cargo_env_compat: true,
+    cargo_pkg_version: "1.2.2",
     srcs: [
         "src/lib.rs",
         ":copy_clang-sys_build_out",
@@ -58,9 +60,3 @@
         "liblibloading",
     ],
 }
-
-// dependent_library ["feature_list"]
-//   cfg-if-1.0.0
-//   glob-0.3.0
-//   libc-0.2.94
-//   libloading-0.7.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 50af79f..dd5d8a3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+## [1.2.2] - 2021-09-02
+
+### Fixed
+- Fixed handling of paths that contain characters that have special meaning in
+glob patterns (e.g., `[` or `]`)
+
+## [1.2.1] - 2021-08-24
+
+### Changed
+- Updated build script to check the install location used by the
+[Scoop](https://scoop.sh/) command-line installer on Windows
+
+### Fixed
+- Updated build script to support environments where the `PATH` environment
+variable is not set
+
 ## [1.2.0] - 2021-04-08
 
 ### Changed
diff --git a/Cargo.toml b/Cargo.toml
index 512c53b..29bf4e5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
 
 [package]
 name = "clang-sys"
-version = "1.2.0"
+version = "1.2.2"
 authors = ["Kyle Mayes <kyle@mayeses.com>"]
 build = "build.rs"
 links = "clang"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index e34929a..e04a103 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -3,7 +3,7 @@
 name = "clang-sys"
 authors = ["Kyle Mayes <kyle@mayeses.com>"]
 
-version = "1.2.0"
+version = "1.2.2"
 
 readme = "README.md"
 license = "Apache-2.0"
diff --git a/METADATA b/METADATA
index 700cc55..8766dad 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/clang-sys/clang-sys-1.2.0.crate"
+    value: "https://static.crates.io/crates/clang-sys/clang-sys-1.2.2.crate"
   }
-  version: "1.2.0"
+  version: "1.2.2"
   license_type: NOTICE
   last_upgrade_date {
     year: 2021
-    month: 5
-    day: 19
+    month: 9
+    day: 22
   }
 }
diff --git a/build/common.rs b/build/common.rs
index f06aff5..56480df 100644
--- a/build/common.rs
+++ b/build/common.rs
@@ -20,7 +20,7 @@
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
-use glob::MatchOptions;
+use glob::{MatchOptions, Pattern};
 
 /// `libclang` directory patterns for FreeBSD and Linux.
 const DIRECTORIES_LINUX: &[&str] = &[
@@ -49,6 +49,9 @@
     // LLVM + Clang can be installed as a component of Visual Studio.
     // https://github.com/KyleMayes/clang-sys/issues/121
     "C:\\Program Files*\\Microsoft Visual Studio\\*\\BuildTools\\VC\\Tools\\Llvm\\**\\bin",
+    // Scoop user installation https://scoop.sh/.
+    // Chocolatey, WinGet and other installers use to the system wide dir listed above
+    "C:\\Users\\*\\scoop\\apps\\llvm\\current\\bin",
 ];
 
 thread_local! {
@@ -152,10 +155,15 @@
 /// Returns the paths to and the filenames of the files matching the supplied
 /// filename patterns in the supplied directory.
 fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> {
+    // Escape the directory in case it contains characters that have special
+    // meaning in glob patterns (e.g., `[` or `]`).
+    let directory = Pattern::escape(directory.to_str().unwrap());
+    let directory = Path::new(&directory);
+
     // Join the directory to the filename patterns to obtain the path patterns.
     let paths = filenames
         .iter()
-        .filter_map(|f| directory.join(f).to_str().map(ToOwned::to_owned));
+        .map(|f| directory.join(f).to_str().unwrap().to_owned());
 
     // Prevent wildcards from matching path separators.
     let mut options = MatchOptions::new();
@@ -170,7 +178,7 @@
             }
         })
         .filter_map(|p| {
-            let filename = p.file_name().and_then(|f| f.to_str())?;
+            let filename = p.file_name()?.to_str().unwrap();
 
             // The `libclang_shared` library has been renamed to `libclang-cpp`
             // in Clang 10. This can cause instances of this library (e.g.,
diff --git a/build/dynamic.rs b/build/dynamic.rs
index c15973c..156afe4 100644
--- a/build/dynamic.rs
+++ b/build/dynamic.rs
@@ -90,8 +90,8 @@
 /// Returns the components of the version in the supplied `libclang` shared
 // library filename.
 fn parse_version(filename: &str) -> Vec<u32> {
-    let version = if filename.starts_with("libclang.so.") {
-        &filename[12..]
+    let version = if let Some(version) = filename.strip_prefix("libclang.so.") {
+        version
     } else if filename.starts_with("libclang-") {
         &filename[9..filename.len() - 3]
     } else {
@@ -252,7 +252,7 @@
         // `libclang.so.7.0`).
         let name = match name.find(".dylib").or_else(|| name.find(".so")) {
             Some(index) => &name[0..index],
-            None => &name,
+            None => name,
         };
 
         println!("cargo:rustc-link-lib=dylib={}", name);
diff --git a/build/static.rs b/build/static.rs
index 83a8185..66da274 100644
--- a/build/static.rs
+++ b/build/static.rs
@@ -16,14 +16,16 @@
 
 use std::path::{Path, PathBuf};
 
+use glob::Pattern;
+
 use common;
 
 /// Returns the name of an LLVM or Clang library from a path to such a library.
 fn get_library_name(path: &Path) -> Option<String> {
     path.file_stem().map(|p| {
         let string = p.to_string_lossy();
-        if string.starts_with("lib") {
-            string[3..].to_owned()
+        if let Some(name) = string.strip_prefix("lib") {
+            name.to_owned()
         } else {
             string.to_string()
         }
@@ -39,8 +41,8 @@
             // Depending on the version of `llvm-config` in use, listed
             // libraries may be in one of two forms, a full path to the library
             // or simply prefixed with `-l`.
-            if p.starts_with("-l") {
-                Some(p[2..].into())
+            if let Some(path) = p.strip_prefix("-l") {
+                Some(path.into())
             } else {
                 get_library_name(Path::new(p))
             }
@@ -67,11 +69,12 @@
 
 /// Returns the Clang libraries required to link to `libclang` statically.
 fn get_clang_libraries<P: AsRef<Path>>(directory: P) -> Vec<String> {
-    let pattern = directory
-        .as_ref()
-        .join("libclang*.a")
-        .to_string_lossy()
-        .to_string();
+    // Escape the directory in case it contains characters that have special
+    // meaning in glob patterns (e.g., `[` or `]`).
+    let directory = Pattern::escape(directory.as_ref().to_str().unwrap());
+    let directory = Path::new(&directory);
+
+    let pattern = directory.join("libclang*.a").to_str().unwrap().to_owned();
     if let Ok(libraries) = glob::glob(&pattern) {
         libraries
             .filter_map(|l| l.ok().and_then(|l| get_library_name(&l)))
diff --git a/out/common.rs b/out/common.rs
index f06aff5..56480df 100644
--- a/out/common.rs
+++ b/out/common.rs
@@ -20,7 +20,7 @@
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
-use glob::MatchOptions;
+use glob::{MatchOptions, Pattern};
 
 /// `libclang` directory patterns for FreeBSD and Linux.
 const DIRECTORIES_LINUX: &[&str] = &[
@@ -49,6 +49,9 @@
     // LLVM + Clang can be installed as a component of Visual Studio.
     // https://github.com/KyleMayes/clang-sys/issues/121
     "C:\\Program Files*\\Microsoft Visual Studio\\*\\BuildTools\\VC\\Tools\\Llvm\\**\\bin",
+    // Scoop user installation https://scoop.sh/.
+    // Chocolatey, WinGet and other installers use to the system wide dir listed above
+    "C:\\Users\\*\\scoop\\apps\\llvm\\current\\bin",
 ];
 
 thread_local! {
@@ -152,10 +155,15 @@
 /// Returns the paths to and the filenames of the files matching the supplied
 /// filename patterns in the supplied directory.
 fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> {
+    // Escape the directory in case it contains characters that have special
+    // meaning in glob patterns (e.g., `[` or `]`).
+    let directory = Pattern::escape(directory.to_str().unwrap());
+    let directory = Path::new(&directory);
+
     // Join the directory to the filename patterns to obtain the path patterns.
     let paths = filenames
         .iter()
-        .filter_map(|f| directory.join(f).to_str().map(ToOwned::to_owned));
+        .map(|f| directory.join(f).to_str().unwrap().to_owned());
 
     // Prevent wildcards from matching path separators.
     let mut options = MatchOptions::new();
@@ -170,7 +178,7 @@
             }
         })
         .filter_map(|p| {
-            let filename = p.file_name().and_then(|f| f.to_str())?;
+            let filename = p.file_name()?.to_str().unwrap();
 
             // The `libclang_shared` library has been renamed to `libclang-cpp`
             // in Clang 10. This can cause instances of this library (e.g.,
diff --git a/out/dynamic.rs b/out/dynamic.rs
index c15973c..156afe4 100644
--- a/out/dynamic.rs
+++ b/out/dynamic.rs
@@ -90,8 +90,8 @@
 /// Returns the components of the version in the supplied `libclang` shared
 // library filename.
 fn parse_version(filename: &str) -> Vec<u32> {
-    let version = if filename.starts_with("libclang.so.") {
-        &filename[12..]
+    let version = if let Some(version) = filename.strip_prefix("libclang.so.") {
+        version
     } else if filename.starts_with("libclang-") {
         &filename[9..filename.len() - 3]
     } else {
@@ -252,7 +252,7 @@
         // `libclang.so.7.0`).
         let name = match name.find(".dylib").or_else(|| name.find(".so")) {
             Some(index) => &name[0..index],
-            None => &name,
+            None => name,
         };
 
         println!("cargo:rustc-link-lib=dylib={}", name);
diff --git a/src/support.rs b/src/support.rs
index 4e698ff..48bae28 100644
--- a/src/support.rs
+++ b/src/support.rs
@@ -18,26 +18,13 @@
 use std::process::Command;
 use std::{env, io};
 
-use glob;
+use glob::{self, Pattern};
 
 use libc::c_int;
 
 use super::CXVersion;
 
 //================================================
-// Macros
-//================================================
-
-macro_rules! try_opt {
-    ($option:expr) => {{
-        match $option {
-            Some(some) => some,
-            None => return None,
-        }
-    }};
-}
-
-//================================================
 // Structs
 //================================================
 
@@ -117,7 +104,9 @@
             }
         }
 
-        paths.extend(env::split_paths(&env::var("PATH").unwrap()));
+        if let Ok(path) = env::var("PATH") {
+            paths.extend(env::split_paths(&path));
+        }
 
         // First, look for a target-prefixed `clang` executable.
 
@@ -126,7 +115,7 @@
             let versioned = format!("{}-clang-[0-9]*{}", target, env::consts::EXE_SUFFIX);
             let patterns = &[&default[..], &versioned[..]];
             for path in &paths {
-                if let Some(path) = find(&path, patterns) {
+                if let Some(path) = find(path, patterns) {
                     return Some(Clang::new(path, args));
                 }
             }
@@ -154,12 +143,17 @@
 /// Returns the first match to the supplied glob patterns in the supplied
 /// directory if there are any matches.
 fn find(directory: &Path, patterns: &[&str]) -> Option<PathBuf> {
+    // Escape the directory in case it contains characters that have special
+    // meaning in glob patterns (e.g., `[` or `]`).
+    let directory = if let Some(directory) = directory.to_str() {
+        Path::new(&Pattern::escape(directory)).to_owned()
+    } else {
+        return None;
+    };
+
     for pattern in patterns {
         let pattern = directory.join(pattern).to_string_lossy().into_owned();
-        if let Some(path) = try_opt!(glob::glob(&pattern).ok())
-            .filter_map(|p| p.ok())
-            .next()
-        {
+        if let Some(path) = glob::glob(&pattern).ok()?.filter_map(|p| p.ok()).next() {
             if path.is_file() && is_executable(&path).unwrap_or(false) {
                 return Some(path);
             }
@@ -221,10 +215,10 @@
 /// Parses the version from the output of a `clang` executable if possible.
 fn parse_version(path: &Path) -> Option<CXVersion> {
     let output = run_clang(path, &["--version"]).0;
-    let start = try_opt!(output.find("version ")) + 8;
-    let mut numbers = try_opt!(output[start..].split_whitespace().next()).split('.');
-    let major = try_opt!(numbers.next().and_then(parse_version_number));
-    let minor = try_opt!(numbers.next().and_then(parse_version_number));
+    let start = output.find("version ")? + 8;
+    let mut numbers = output[start..].split_whitespace().next()?.split('.');
+    let major = numbers.next().and_then(parse_version_number)?;
+    let minor = numbers.next().and_then(parse_version_number)?;
     let subminor = numbers.next().and_then(parse_version_number).unwrap_or(0);
     Some(CXVersion {
         Major: major,
@@ -238,8 +232,8 @@
     let mut clang_args = vec!["-E", "-x", language, "-", "-v"];
     clang_args.extend(args.iter().map(|s| &**s));
     let output = run_clang(path, &clang_args).1;
-    let start = try_opt!(output.find("#include <...> search starts here:")) + 34;
-    let end = try_opt!(output.find("End of search list."));
+    let start = output.find("#include <...> search starts here:")? + 34;
+    let end = output.find("End of search list.")?;
     let paths = output[start..end].replace("(framework directory)", "");
     Some(
         paths