]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ext/env.rs
auto merge of #15407 : sneves/rust/master, r=aturon
[rust.git] / src / libsyntax / ext / env.rs
1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*
12  * The compiler code necessary to support the env! extension.  Eventually this
13  * should all get sucked into either the compiler syntax extension plugin
14  * interface.
15  */
16
17 use ast;
18 use codemap::Span;
19 use ext::base::*;
20 use ext::base;
21 use ext::build::AstBuilder;
22 use parse::token;
23
24 use std::os;
25
26 pub fn expand_option_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
27                          -> Box<base::MacResult> {
28     let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
29         None => return DummyResult::expr(sp),
30         Some(v) => v
31     };
32
33     let e = match os::getenv(var.as_slice()) {
34       None => {
35           cx.expr_path(cx.path_all(sp,
36                                    true,
37                                    vec!(cx.ident_of("std"),
38                                         cx.ident_of("option"),
39                                         cx.ident_of("None")),
40                                    Vec::new(),
41                                    vec!(cx.ty_rptr(sp,
42                                                    cx.ty_ident(sp,
43                                                         cx.ident_of("str")),
44                                                    Some(cx.lifetime(sp,
45                                                         cx.ident_of(
46                                                             "'static").name)),
47                                                    ast::MutImmutable))))
48       }
49       Some(s) => {
50           cx.expr_call_global(sp,
51                               vec!(cx.ident_of("std"),
52                                    cx.ident_of("option"),
53                                    cx.ident_of("Some")),
54                               vec!(cx.expr_str(sp,
55                                                token::intern_and_get_ident(
56                                           s.as_slice()))))
57       }
58     };
59     MacExpr::new(e)
60 }
61
62 pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
63                   -> Box<base::MacResult> {
64     let exprs = match get_exprs_from_tts(cx, sp, tts) {
65         Some(ref exprs) if exprs.len() == 0 => {
66             cx.span_err(sp, "env! takes 1 or 2 arguments");
67             return DummyResult::expr(sp);
68         }
69         None => return DummyResult::expr(sp),
70         Some(exprs) => exprs
71     };
72
73     let var = match expr_to_string(cx,
74                                 *exprs.get(0),
75                                 "expected string literal") {
76         None => return DummyResult::expr(sp),
77         Some((v, _style)) => v
78     };
79     let msg = match exprs.len() {
80         1 => {
81             token::intern_and_get_ident(format!("environment variable `{}` \
82                                                  not defined",
83                                                 var).as_slice())
84         }
85         2 => {
86             match expr_to_string(cx, *exprs.get(1), "expected string literal") {
87                 None => return DummyResult::expr(sp),
88                 Some((s, _style)) => s
89             }
90         }
91         _ => {
92             cx.span_err(sp, "env! takes 1 or 2 arguments");
93             return DummyResult::expr(sp);
94         }
95     };
96
97     let e = match os::getenv(var.get()) {
98         None => {
99             cx.span_err(sp, msg.get());
100             cx.expr_uint(sp, 0)
101         }
102         Some(s) => cx.expr_str(sp, token::intern_and_get_ident(s.as_slice()))
103     };
104     MacExpr::new(e)
105 }