Home | History | Annotate | Download | only in kati
      1 // Copyright 2015 Google Inc. All rights reserved
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #ifndef VAR_H_
     16 #define VAR_H_
     17 
     18 #include <memory>
     19 #include <string>
     20 #include <unordered_map>
     21 #include <unordered_set>
     22 
     23 #include "eval.h"
     24 #include "expr.h"
     25 #include "log.h"
     26 #include "stmt.h"
     27 #include "string_piece.h"
     28 #include "symtab.h"
     29 
     30 using namespace std;
     31 
     32 class Evaluator;
     33 class Value;
     34 
     35 enum struct VarOrigin {
     36   UNDEFINED,
     37   DEFAULT,
     38   ENVIRONMENT,
     39   ENVIRONMENT_OVERRIDE,
     40   FILE,
     41   COMMAND_LINE,
     42   OVERRIDE,
     43   AUTOMATIC,
     44 };
     45 
     46 const char* GetOriginStr(VarOrigin origin);
     47 
     48 class Var : public Evaluable {
     49  public:
     50   virtual ~Var();
     51 
     52   virtual const char* Flavor() const = 0;
     53   virtual VarOrigin Origin() const = 0;
     54   virtual bool IsDefined() const { return true; }
     55 
     56   virtual void AppendVar(Evaluator* ev, Value* v);
     57 
     58   virtual StringPiece String() const = 0;
     59 
     60   virtual string DebugString() const = 0;
     61 
     62   bool ReadOnly() const { return readonly_; }
     63   void SetReadOnly() { readonly_ = true; }
     64 
     65   bool Deprecated() const { return message_ && !error_; }
     66   void SetDeprecated(StringPiece msg) {
     67     message_.reset(new string(msg.as_string()));
     68   }
     69 
     70   bool Obsolete() const { return error_; }
     71   void SetObsolete(StringPiece msg) {
     72     message_.reset(new string(msg.as_string()));
     73     error_ = true;
     74   }
     75 
     76   const string& DeprecatedMessage() const { return *message_; }
     77 
     78   // This variable was used (either written or read from)
     79   void Used(Evaluator* ev, const Symbol& sym) const {
     80     if (!message_) {
     81       return;
     82     }
     83 
     84     if (error_) {
     85       ev->Error(StringPrintf("*** %s is obsolete%s.", sym.c_str(),
     86                              message_->c_str()));
     87     } else {
     88       WARN_LOC(ev->loc(), "%s has been deprecated%s.", sym.c_str(),
     89                message_->c_str());
     90     }
     91   }
     92 
     93  protected:
     94   Var();
     95 
     96  private:
     97   bool readonly_;
     98   unique_ptr<string> message_;
     99   bool error_;
    100 };
    101 
    102 class SimpleVar : public Var {
    103  public:
    104   explicit SimpleVar(VarOrigin origin);
    105   SimpleVar(const string& v, VarOrigin origin);
    106 
    107   virtual const char* Flavor() const override { return "simple"; }
    108   virtual VarOrigin Origin() const override { return origin_; }
    109 
    110   virtual void Eval(Evaluator* ev, string* s) const override;
    111 
    112   virtual void AppendVar(Evaluator* ev, Value* v) override;
    113 
    114   virtual StringPiece String() const override;
    115 
    116   virtual string DebugString() const override;
    117 
    118   string* mutable_value() { return &v_; }
    119 
    120  private:
    121   string v_;
    122   VarOrigin origin_;
    123 };
    124 
    125 class RecursiveVar : public Var {
    126  public:
    127   RecursiveVar(Value* v, VarOrigin origin, StringPiece orig);
    128 
    129   virtual const char* Flavor() const override { return "recursive"; }
    130   virtual VarOrigin Origin() const override { return origin_; }
    131 
    132   virtual void Eval(Evaluator* ev, string* s) const override;
    133 
    134   virtual void AppendVar(Evaluator* ev, Value* v) override;
    135 
    136   virtual StringPiece String() const override;
    137 
    138   virtual string DebugString() const override;
    139 
    140  private:
    141   Value* v_;
    142   VarOrigin origin_;
    143   StringPiece orig_;
    144 };
    145 
    146 class UndefinedVar : public Var {
    147  public:
    148   UndefinedVar();
    149 
    150   virtual const char* Flavor() const override { return "undefined"; }
    151   virtual VarOrigin Origin() const override { return VarOrigin::UNDEFINED; }
    152   virtual bool IsDefined() const override { return false; }
    153 
    154   virtual void Eval(Evaluator* ev, string* s) const override;
    155 
    156   virtual StringPiece String() const override;
    157 
    158   virtual string DebugString() const override;
    159 };
    160 
    161 extern UndefinedVar* kUndefined;
    162 
    163 class RuleVar : public Var {
    164  public:
    165   RuleVar(Var* v, AssignOp op) : v_(v), op_(op) {}
    166   virtual ~RuleVar() { delete v_; }
    167 
    168   virtual const char* Flavor() const override { return v_->Flavor(); }
    169   virtual VarOrigin Origin() const override { return v_->Origin(); }
    170   virtual bool IsDefined() const override { return v_->IsDefined(); }
    171   virtual void Eval(Evaluator* ev, string* s) const override {
    172     v_->Eval(ev, s);
    173   }
    174   virtual void AppendVar(Evaluator* ev, Value* v) override {
    175     v_->AppendVar(ev, v);
    176   }
    177   virtual StringPiece String() const override { return v_->String(); }
    178   virtual string DebugString() const override { return v_->DebugString(); }
    179 
    180   Var* v() const { return v_; }
    181   AssignOp op() const { return op_; }
    182 
    183  private:
    184   Var* v_;
    185   AssignOp op_;
    186 };
    187 
    188 class Vars : public unordered_map<Symbol, Var*> {
    189  public:
    190   ~Vars();
    191 
    192   Var* Lookup(Symbol name) const;
    193   Var* Peek(Symbol name) const;
    194 
    195   void Assign(Symbol name, Var* v, bool* readonly);
    196 
    197   static void add_used_env_vars(Symbol v);
    198 
    199   static const unordered_set<Symbol>& used_env_vars() { return used_env_vars_; }
    200 
    201  private:
    202   static unordered_set<Symbol> used_env_vars_;
    203 };
    204 
    205 class ScopedVar {
    206  public:
    207   // Does not take ownerships of arguments.
    208   ScopedVar(Vars* vars, Symbol name, Var* var);
    209   ~ScopedVar();
    210 
    211  private:
    212   Vars* vars_;
    213   Var* orig_;
    214   Vars::iterator iter_;
    215 };
    216 
    217 #endif  // VAR_H_
    218