]> git.proxmox.com Git - rustc.git/blame - src/libsyntax_ext/env.rs
New upstream version 1.29.0+dfsg1
[rustc.git] / src / libsyntax_ext / env.rs
CommitLineData
1a4d82fc 1// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
223e47cc
LB
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
9e0c209e
SL
11// The compiler code necessary to support the env! extension. Eventually this
12// should all get sucked into either the compiler syntax extension plugin
13// interface.
14//
223e47cc 15
8faf50e0 16use syntax::ast::{self, Ident, GenericArg};
9cc50fc6
SL
17use syntax::ext::base::*;
18use syntax::ext::base;
19use syntax::ext::build::AstBuilder;
0531ce1d 20use syntax::symbol::{keywords, Symbol};
3157f602
XL
21use syntax_pos::Span;
22use syntax::tokenstream;
970d7e83 23
85aaf69f 24use std::env;
223e47cc 25
9e0c209e
SL
26pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
27 sp: Span,
28 tts: &[tokenstream::TokenTree])
8faf50e0 29 -> Box<dyn base::MacResult + 'cx> {
1a4d82fc
JJ
30 let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
31 None => return DummyResult::expr(sp),
9e0c209e 32 Some(v) => v,
1a4d82fc
JJ
33 };
34
83c7162d 35 let sp = sp.apply_mark(cx.current_expansion.mark);
476ff2be 36 let e = match env::var(&*var.as_str()) {
9e0c209e 37 Err(..) => {
0531ce1d 38 let lt = cx.lifetime(sp, keywords::StaticLifetime.ident());
9e0c209e
SL
39 cx.expr_path(cx.path_all(sp,
40 true,
41 cx.std_path(&["option", "Option", "None"]),
8faf50e0 42 vec![GenericArg::Type(cx.ty_rptr(sp,
7cac9316 43 cx.ty_ident(sp, Ident::from_str("str")),
0531ce1d 44 Some(lt),
8faf50e0
XL
45 ast::Mutability::Immutable))],
46 vec![]))
9e0c209e
SL
47 }
48 Ok(s) => {
49 cx.expr_call_global(sp,
50 cx.std_path(&["option", "Option", "Some"]),
476ff2be 51 vec![cx.expr_str(sp, Symbol::intern(&s))])
9e0c209e 52 }
1a4d82fc 53 };
c34b1796 54 MacEager::expr(e)
1a4d82fc 55}
223e47cc 56
9e0c209e
SL
57pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt,
58 sp: Span,
59 tts: &[tokenstream::TokenTree])
8faf50e0 60 -> Box<dyn base::MacResult + 'cx> {
1a4d82fc 61 let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
9346a6ac 62 Some(ref exprs) if exprs.is_empty() => {
1a4d82fc
JJ
63 cx.span_err(sp, "env! takes 1 or 2 arguments");
64 return DummyResult::expr(sp);
65 }
66 None => return DummyResult::expr(sp),
9e0c209e 67 Some(exprs) => exprs.into_iter(),
1a4d82fc
JJ
68 };
69
9e0c209e 70 let var = match expr_to_string(cx, exprs.next().unwrap(), "expected string literal") {
1a4d82fc 71 None => return DummyResult::expr(sp),
9e0c209e 72 Some((v, _style)) => v,
1a4d82fc
JJ
73 };
74 let msg = match exprs.next() {
476ff2be 75 None => Symbol::intern(&format!("environment variable `{}` not defined", var)),
1a4d82fc
JJ
76 Some(second) => {
77 match expr_to_string(cx, second, "expected string literal") {
78 None => return DummyResult::expr(sp),
9e0c209e 79 Some((s, _style)) => s,
1a4d82fc
JJ
80 }
81 }
82 };
223e47cc 83
3157f602
XL
84 if let Some(_) = exprs.next() {
85 cx.span_err(sp, "env! takes 1 or 2 arguments");
86 return DummyResult::expr(sp);
1a4d82fc 87 }
223e47cc 88
476ff2be 89 let e = match env::var(&*var.as_str()) {
85aaf69f 90 Err(_) => {
476ff2be 91 cx.span_err(sp, &msg.as_str());
85aaf69f 92 cx.expr_usize(sp, 0)
1a4d82fc 93 }
476ff2be 94 Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
223e47cc 95 };
c34b1796 96 MacEager::expr(e)
223e47cc 97}