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
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//! This shell should be both POSIX compatible and yet modern and exciting.
//! Fancy features should not be prevented by POSIX compatibility. This will
//! effect the design of the shell.
//!
//! The name of the shell is `oursh` which is both somewhat unique, and
//! memorable.  It's also a nice name to play with pseudo-satirical themes...
//! right comrade?  It's short (ish) and sneakily fits `rs` in it, which is the
//! extension of Rust programs, the language this will be written in.
//!
//!
//! ## Features
//!
//! - POSIX compatibility
//! - Shebang blocks, `{#!/usr/bin/env ruby; puts 1}`, `{# ... }`
//! - bash/zsh autocomplete compatibility
//! - `man` / `-h` / `--help` parsing
//! - Multi-line input
//! - Modern scripting language (types, higher-order functions, threading?, etc)
//! - obfuscated strings (`!'password'!`)
//! - mosh like remote session support
//! - Smart history, sync'd across devices
//! - Package manager
//! - Sane defaults
//! - Fast
//!
//! ## Usage
//!
//! While this project is in early stages, there are no OS packages to use.
//! However, you can compile and run directly from source easily. Just ensure
//! you have [`rustup`][rustup] installed.
//!
//! ```sh
//! cargo run
//! ```
//!
//!
//! ## Previous Work
//!
//! I've been using [`fish`][fish] as my main shell for a few years now. Fish
//! inspires a lot of the modern syntax.
//!
//! POSIX compatibility comes from my desire to use this shell as my `chsh -s
//! ...` shell on [Arch Linux][arch]. See the full POSIX reference for more
//! information.
//!
//! I've built and wrote a few things about shells before:
//!
//! - [`rush`][rush] A glorified homework assignment for computer architecture.
//! - [`myshell.py`][myshell.py] My submission for computer organization a8.
//! - [Building a Shell - Part 1][basp1] Start of this project.
//!
//! ## [POSIX Reference][posix]
//!
//! See the following sections for building the POSIX `sh` compliant program
//! language, and interactive terminal based REPL.
//!
//! - 3§2 Shell Command Language
//!     - 10.2 Shell Grammar Rules
//! - 2§2.5 Standard I/O Streams
//! - 3§1.6 Built-In Utilities
//! - 3§1.4 Utility Description Defaults
//! - 2§2.3 Error Numbers
//! - 1§11 General Terminal Interface
//! - 2§2.4 Signal Concepts
//!
//!
//! [documentation]: https://nixpulvis.com/oursh/oursh
//! [rustup]: https://github.com/rust-lang-nursery/rustup.rs
//! [posix]: http://pubs.opengroup.org/onlinepubs/9699919799/
//! [termios]: https://crates.io/crates/termios
//! [libc]: https://crates.io/crates/libc
//! [fish]: https://github.com/fish-shell/fish-shell
//! [arch]: https://www.archlinux.org/
//! [rush]: https://github.com/nixpulvis/rush
//! [myshell.py]: https://github.com/nixpulvis/oursh/blob/master/doc/cs2600-a8-myshell.py
//! [basp1]: https://nixpulvis.com/ramblings/2018-07-11-building-a-shell-part-1
#![feature(alloc_system, box_syntax, box_patterns)]
#![crate_type = "dylib"]

extern crate nix;
extern crate pwd;
extern crate termion;

#[macro_use]
extern crate lalrpop_util;

/// Print debug information to stderr..
///
/// ### Examples
///
/// ```
/// use oursh::debug;
///
/// debug!(1 + 2);
///
/// let msg = "because.";
/// debug!("why!? {}", msg);
/// ```
#[macro_export]
macro_rules! debug {
    ($e:expr) => {
        if let Ok(_level) = ::std::env::var("LOG") {
            eprintln!("----- {} -----", stringify!($e));
            eprintln!("{:#?}", $e);
            eprintln!("-----");
        }
    };
    ($format:expr, $e:expr) => {
        if let Ok(_level) = ::std::env::var("LOG") {
            eprintln!("----- {} -----", stringify!($e));
            eprintln!($format, $e);
            eprintln!("-----");
        }
    };
}

pub mod job;
pub mod program;
pub mod repl;


#[cfg(test)]
mod tests {
    #[test]
    fn it_has_a_test() {}
}