Ninja
eval_env.h
Go to the documentation of this file.
00001 // Copyright 2011 Google Inc. All Rights Reserved.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //     http://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #ifndef NINJA_EVAL_ENV_H_
00016 #define NINJA_EVAL_ENV_H_
00017 
00018 #include <map>
00019 #include <string>
00020 #include <vector>
00021 using namespace std;
00022 
00023 #include "string_piece.h"
00024 
00025 struct EvalString;
00026 
00027 /// An interface for a scope for variable (e.g. "$foo") lookups.
00028 struct Env {
00029   virtual ~Env() {}
00030   virtual string LookupVariable(const string& var) = 0;
00031 };
00032 
00033 /// An Env which contains a mapping of variables to values
00034 /// as well as a pointer to a parent scope.
00035 struct BindingEnv : public Env {
00036   BindingEnv() : parent_(NULL) {}
00037   explicit BindingEnv(Env* parent) : parent_(parent) {}
00038 
00039   virtual ~BindingEnv() {}
00040   virtual string LookupVariable(const string& var);
00041 
00042   void AddBinding(const string& key, const string& val);
00043 
00044   /// This is tricky.  Edges want lookup scope to go in this order:
00045   /// 1) value set on edge itself (edge_->env_)
00046   /// 2) value set on rule, with expansion in the edge's scope
00047   /// 3) value set on enclosing scope of edge (edge_->env_->parent_)
00048   /// This function takes as parameters the necessary info to do (2).
00049   string LookupWithFallback(const string& var, const EvalString* eval,
00050                             Env* env);
00051 
00052 private:
00053   map<string, string> bindings_;
00054   Env* parent_;
00055 };
00056 
00057 /// A tokenized string that contains variable references.
00058 /// Can be evaluated relative to an Env.
00059 struct EvalString {
00060   string Evaluate(Env* env) const;
00061 
00062   void Clear() { parsed_.clear(); }
00063   bool empty() const { return parsed_.empty(); }
00064 
00065   void AddText(StringPiece text);
00066   void AddSpecial(StringPiece text);
00067 
00068   /// Construct a human-readable representation of the parsed state,
00069   /// for use in tests.
00070   string Serialize() const;
00071 
00072 private:
00073   enum TokenType { RAW, SPECIAL };
00074   typedef vector<pair<string, TokenType> > TokenList;
00075   TokenList parsed_;
00076 };
00077 
00078 #endif  // NINJA_EVAL_ENV_H_