use std::cmp;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::io::{self, BufRead};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use clap;
use encoding_rs::Encoding;
use grep::{Grep, GrepBuilder};
use log;
use num_cpus;
use regex;
use same_file;
use termcolor;
use app;
use atty;
use ignore::overrides::{Override, OverrideBuilder};
use ignore::types::{FileTypeDef, Types, TypesBuilder};
use ignore;
use printer::{ColorSpecs, Printer};
use unescape::unescape;
use worker::{Worker, WorkerBuilder};
use config;
use logger::Logger;
use Result;
/// `Args` are transformed/normalized from `ArgMatches`.
#[derive(Debug)]
pub struct Args {
paths: Vec<PathBuf>,
after_context: usize,
before_context: usize,
byte_offset: bool,
color_choice: termcolor::ColorChoice,
colors: ColorSpecs,
column: bool,
context_separator: Vec<u8>,
count: bool,
count_matches: bool,
encoding: Option<&'static Encoding>,
files_with_matches: bool,
files_without_matches: bool,
eol: u8,
files: bool,
follow: bool,
glob_overrides: Override,
grep: Grep,
heading: bool,
hidden: bool,
ignore_files: Vec<PathBuf>,
invert_match: bool,
line_number: bool,
line_per_match: bool,
max_columns: Option<usize>,
max_count: Option<u64>,
max_filesize: Option<u64>,
maxdepth: Option<usize>,
mmap: bool,
no_ignore: bool,
no_ignore_messages: bool,
no_ignore_parent: bool,
no_ignore_vcs: bool,
no_messages: bool,
null: bool,
only_matching: bool,
path_separator: Option<u8>,
quiet: bool,
quiet_matched: QuietMatched,
replace: Option<Vec<u8>>,
sort_files: bool,
stdout_handle: Option<same_file::Handle>,
text: bool,
threads: usize,
type_list: bool,
types: Types,
with_filename: bool,
search_zip_files: bool,
stats: bool
}
impl Args {
/// Parse the command line arguments for this process.
///
/// If a CLI usage error occurred, then exit the process and print a usage
/// or error message. Similarly, if the user requested the version of
/// ripgrep, then print the version and exit.
///
/// Also, initialize a global logger.
pub fn parse() -> Result<Args> {
// We parse the args given on CLI. This does not include args from
// the config. We use the CLI args as an initial configuration while
// trying to parse config files. If a config file exists and has
// arguments, then we re-parse argv, otherwise we just use the matches
// we have here.
let early_matches = ArgMatches(app::app().get_matches());
if let Err(err) = Logger::init() {
errored!("failed to initialize logger: {}&