(index<- )        ./libsyntax/ext/env.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   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, spSpan, 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))))
  57        }
  58      };
  59      MacExpr::new(e)
  60  }
  61  
  62  pub fn expand_env(cx: &mut ExtCtxt, spSpan, 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_str(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))
  84          }
  85          2 => {
  86              match expr_to_str(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))
 103      };
 104      MacExpr::new(e)
 105  }