1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
pub use std::sync::atomic::{AtomicUsize, Ordering};

pub static CIDX: AtomicUsize = AtomicUsize::new(0);

// Would use lazy_static but it seems kinda useless seeing as this is all single threaded and I
// know there won't be data races and stuff..
pub static mut ARGS: Vec<String> = Vec::new();
pub static mut REMOVEINDICES: Vec<usize> = Vec::new();

#[macro_export]
macro_rules! eargf {
    ( $help:expr ) => {{
        unsafe {
            let index = CIDX.load(Ordering::SeqCst) + 1;
            match ARGS.get(index) {
                Some(s) => {
                    REMOVEINDICES.push(index);
                    s.to_owned()
                },
                None => {
                    $help;
                    String::new()
                }
            }
        }
    }};
    () => {{
        eargf!("")
    }};
}

#[macro_export]
macro_rules! argbegin {
    ( $argv0:expr, $($matcher:pat => $result:expr), *) => {{
        unsafe {
            ARGS = std::env::args().collect();

            *$argv0 = ARGS.remove(0);

            ARGS.iter().enumerate().for_each(|(idx, arg)| {
                if let Some(stripped) = arg.strip_prefix('-') {
                    if stripped.is_empty() {return;}
                    REMOVEINDICES.push(idx);

                    stripped.chars().for_each(|ch| {
                        match ch {
                            $($matcher => $result),*
                        }
                    });
                }

                CIDX.fetch_add(1, Ordering::SeqCst);
            });

            ARGS.iter()
                .enumerate()
                .filter(|(idx, _)| !REMOVEINDICES.contains(idx))
                .map(|(_, a)| a.to_owned())
                .collect::<Vec<String>>()
        }

    }}
}