LCOV - code coverage report
Current view: top level - src - Var.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 176 221 79.6 %
Date: 2010-12-13 Functions: 20 21 95.2 %
Branches: 147 214 68.7 %

           Branch data     Line data    Source code
       1                 :            : // $Id: Var.cc 6219 2008-10-01 05:39:07Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include "Var.h"
       8                 :            : #include "Func.h"
       9                 :            : #include "Stmt.h"
      10                 :            : #include "Scope.h"
      11                 :            : #include "Serializer.h"
      12                 :            : #include "RemoteSerializer.h"
      13                 :            : #include "EventRegistry.h"
      14                 :            : 
      15                 :       1628 : static Val* init_val(Expr* init, const BroType* t, Val* aggr)
      16                 :            :         {
      17                 :       1628 :         return init->InitVal(t, aggr);
      18                 :            :         }
      19                 :            : 
      20                 :            : static void make_var(ID* id, BroType* t, init_class c, Expr* init,
      21                 :       5262 :                         attr_list* attr, decl_type dt, int do_init)
      22                 :            :         {
      23         [ +  + ]:       5262 :         if ( id->Type() )
      24                 :            :                 {
      25 [ +  + ][ +  - ]:        186 :                 if ( id->IsRedefinable() || (! init && attr) )
         [ +  - ][ +  - ]
      26                 :            :                         {
      27         [ +  + ]:        186 :                         BroObj* redef_obj = init ? (BroObj*) init : (BroObj*) t;
      28         [ -  + ]:        186 :                         if ( dt != VAR_REDEF )
      29                 :        186 :                                 id->Warn("redefinition requires \"redef\"", redef_obj, 1);
      30                 :            :                         }
      31                 :            : 
      32 [ #  # ][ #  # ]:          0 :                 else if ( dt != VAR_REDEF || init || ! attr )
                 [ #  # ]
      33                 :            :                         {
      34                 :          0 :                         id->Error("already defined", init);
      35                 :          0 :                         return;
      36                 :            :                         }
      37                 :            :                 }
      38                 :            : 
      39         [ +  + ]:       5262 :         if ( dt == VAR_REDEF )
      40                 :            :                 {
      41         [ -  + ]:        186 :                 if ( ! id->Type() )
      42                 :            :                         {
      43                 :          0 :                         id->Error("\"redef\" used but not previously defined");
      44                 :          0 :                         return;
      45                 :            :                         }
      46                 :            : 
      47         [ +  + ]:        186 :                 if ( ! t )
      48                 :        184 :                         t = id->Type();
      49                 :            :                 }
      50                 :            : 
      51 [ +  + ][ +  - ]:       5262 :         if ( id->Type() && id->Type()->Tag() != TYPE_ERROR )
                 [ +  + ]
      52                 :            :                 {
      53 [ -  + ][ #  # ]:        186 :                 if ( dt != VAR_REDEF &&
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
      54                 :            :                      (! init || ! do_init || (! t && ! (t = init_type(init)))) )
      55                 :            :                         {
      56                 :          0 :                         id->Error("already defined", init);
      57                 :          0 :                         return;
      58                 :            :                         }
      59                 :            : 
      60                 :            :                 // Allow redeclaration in order to initialize.
      61         [ -  + ]:        186 :                 if ( ! same_type(t, id->Type()) )
      62                 :            :                         {
      63                 :          0 :                         id->Error("redefinition changes type", init);
      64                 :          0 :                         return;
      65                 :            :                         }
      66                 :            :                 }
      67                 :            : 
      68 [ +  + ][ -  + ]:       5262 :         if ( init && optimize )
      69                 :          0 :                 init = init->Simplify(SIMPLIFY_GENERAL);
      70                 :            : 
      71 [ +  + ][ +  + ]:       5262 :         if ( t && t->IsSet() )
                 [ +  + ]
      72                 :            :                 { // Check for set with explicit elements.
      73                 :        251 :                 SetType* st = t->AsTableType()->AsSetType();
      74                 :        251 :                 ListExpr* elements = st->SetElements();
      75                 :            : 
      76         [ -  + ]:        251 :                 if ( elements )
      77                 :            :                         {
      78         [ #  # ]:          0 :                         if ( init )
      79                 :            :                                 {
      80                 :          0 :                                 id->Error("double initialization", init);
      81                 :          0 :                                 return;
      82                 :            :                                 }
      83                 :            : 
      84                 :          0 :                         Ref(elements);
      85                 :          0 :                         init = elements;
      86                 :            :                         }
      87                 :            :                 }
      88                 :            : 
      89         [ +  + ]:       5262 :         if ( ! t )
      90                 :            :                 { // Take type from initialization.
      91         [ -  + ]:       2380 :                 if ( ! init )
      92                 :            :                         {
      93                 :          0 :                         id->Error("no type given");
      94                 :          0 :                         return;
      95                 :            :                         }
      96                 :            : 
      97                 :       2380 :                 t = init_type(init);
      98         [ -  + ]:       2380 :                 if ( ! t )
      99                 :            :                         {
     100                 :          0 :                         id->SetType(error_type());
     101                 :       2380 :                         return;
     102                 :            :                         }
     103                 :            :                 }
     104                 :            :         else
     105                 :       2882 :                 Ref(t);
     106                 :            : 
     107                 :       5262 :         id->SetType(t);
     108                 :            : 
     109         [ +  + ]:       5262 :         if ( attr )
     110                 :       1280 :                 id->AddAttrs(new Attributes(attr, t));
     111                 :            : 
     112 [ +  + ][ +  + ]:       5262 :         if ( id->FindAttr(ATTR_PERSISTENT) || id->FindAttr(ATTR_SYNCHRONIZED) )
                 [ +  + ]
     113                 :            :                 {
     114         [ -  + ]:         18 :                 if ( dt == VAR_CONST )
     115                 :            :                         {
     116                 :          0 :                         id->Error("&persistant/synchronized with constant");
     117                 :          0 :                         return;
     118                 :            :                         }
     119                 :            : 
     120         [ -  + ]:         18 :                 if ( ! id->IsGlobal() )
     121                 :            :                         {
     122                 :          0 :                         id->Error("&persistant/synchronized with non-global");
     123                 :          0 :                         return;
     124                 :            :                         }
     125                 :            :                 }
     126                 :            : 
     127         [ +  + ]:       5262 :         if ( do_init )
     128                 :            :                 {
     129 [ +  + ][ +  + ]:       3893 :                 if ( (c == INIT_EXTRA && id->FindAttr(ATTR_ADD_FUNC)) ||
         [ -  + ][ #  # ]
                 [ +  + ]
     130                 :            :                      (c == INIT_REMOVE && id->FindAttr(ATTR_DEL_FUNC)) )
     131                 :            :                         // Just apply the function.
     132                 :          2 :                         id->SetVal(init, c);
     133                 :            : 
     134 [ +  + ][ +  + ]:       3891 :                 else if ( dt != VAR_REDEF || init || ! attr )
                 [ -  + ]
     135                 :            :                         {
     136                 :            :                         Val* aggr;
     137         [ +  + ]:       3878 :                         if ( t->Tag() == TYPE_RECORD )
     138                 :          8 :                                 aggr = new RecordVal(t->AsRecordType());
     139                 :            : 
     140         [ +  + ]:       3870 :                         else if ( t->Tag() == TYPE_TABLE )
     141                 :        690 :                                 aggr = new TableVal(t->AsTableType(), id->Attrs());
     142                 :            : 
     143         [ +  + ]:       3180 :                         else if ( t->Tag() == TYPE_VECTOR )
     144                 :         14 :                                 aggr = new VectorVal(t->AsVectorType());
     145                 :            : 
     146                 :            :                         else
     147                 :       3166 :                                 aggr = 0;
     148                 :            : 
     149                 :       3878 :                         Val* v = 0;
     150         [ +  + ]:       3878 :                         if ( init )
     151                 :            :                                 {
     152                 :       1628 :                                 v = init_val(init, t, aggr);
     153         [ -  + ]:       1628 :                                 if ( ! v )
     154                 :          0 :                                         return;
     155                 :            :                                 }
     156                 :            : 
     157         [ +  + ]:       3878 :                         if ( aggr )
     158                 :        712 :                                 id->SetVal(aggr, c);
     159         [ +  + ]:       3166 :                         else if ( v )
     160                 :       1264 :                                 id->SetVal(v, c);
     161                 :            :                         }
     162                 :            :                 }
     163                 :            : 
     164         [ +  + ]:       5262 :         if ( dt == VAR_CONST )
     165                 :            :                 {
     166 [ +  + ][ -  + ]:       1336 :                 if ( ! init && ! id->IsRedefinable() )
                 [ -  + ]
     167                 :          0 :                         id->Error("const variable must be initialized");
     168                 :            : 
     169                 :       1336 :                 id->SetConst();
     170                 :            :                 }
     171                 :            : 
     172                 :       5262 :         id->UpdateValAttrs();
     173                 :            :         }
     174                 :            : 
     175                 :            : 
     176                 :            : void add_global(ID* id, BroType* t, init_class c, Expr* init,
     177                 :       3893 :                 attr_list* attr, decl_type dt)
     178                 :            :         {
     179                 :       3893 :         make_var(id, t, c, init, attr, dt, 1);
     180                 :       3893 :         }
     181                 :            : 
     182                 :            : Stmt* add_local(ID* id, BroType* t, init_class c, Expr* init,
     183                 :        272 :                 attr_list* attr, decl_type dt)
     184                 :            :         {
     185                 :        272 :         make_var(id, t, c, init, attr, dt, 0);
     186                 :            : 
     187         [ +  + ]:        272 :         if ( init )
     188                 :            :                 {
     189         [ -  + ]:         21 :                 if ( c != INIT_FULL )
     190                 :          0 :                         id->Error("can't use += / -= for initializations of local variables");
     191                 :            : 
     192                 :         21 :                 Ref(id);
     193                 :            : 
     194                 :            :                 Stmt* stmt =
     195                 :         21 :                         new ExprStmt(new AssignExpr(new NameExpr(id), init, 0));
     196                 :         21 :                 stmt->SetLocationInfo(init->GetLocationInfo());
     197                 :            : 
     198                 :         21 :                 return stmt;
     199                 :            :                 }
     200                 :            : 
     201                 :            :         else
     202                 :            :                 {
     203 [ +  + ][ +  + ]:        251 :                 if ( t->Tag() == TYPE_RECORD || t->Tag() == TYPE_TABLE ||
         [ +  + ][ +  + ]
     204                 :            :                      t->Tag() == TYPE_VECTOR )
     205                 :        103 :                         current_scope()->AddInit(id);
     206                 :            : 
     207                 :        272 :                 return new NullStmt;
     208                 :            :                 }
     209                 :            :         }
     210                 :            : 
     211                 :       1097 : extern Expr* add_and_assign_local(ID* id, Expr* init, Val* val)
     212                 :            :         {
     213                 :       1097 :         make_var(id, 0, INIT_FULL, init, 0, VAR_REGULAR, 0);
     214                 :       1097 :         Ref(id);
     215                 :       1097 :         return new AssignExpr(new NameExpr(id), init, 0, val);
     216                 :            :         }
     217                 :            : 
     218                 :        389 : void add_type(ID* id, BroType* t, attr_list* attr, int /* is_event */)
     219                 :            :         {
     220                 :        389 :         id->SetType(t);
     221                 :        389 :         id->MakeType();
     222                 :            : 
     223         [ -  + ]:        389 :         if ( attr )
     224                 :          0 :                 id->SetAttrs(new Attributes(attr, t));
     225                 :        389 :         }
     226                 :            : 
     227                 :            : void begin_func(ID* id, const char* module_name, function_flavor flavor,
     228                 :       1125 :                 int is_redef, FuncType* t)
     229                 :            :         {
     230         [ +  + ]:       1125 :         if ( flavor == FUNC_FLAVOR_EVENT )
     231                 :            :                 {
     232                 :        575 :                 const BroType* yt = t->YieldType();
     233                 :            : 
     234   [ +  -  -  + ]:        575 :                 if ( yt && yt->Tag() != TYPE_VOID )
                 [ -  + ]
     235                 :          0 :                         id->Error("event cannot yield a value", t);
     236                 :            : 
     237                 :        575 :                 t->ClearYieldType();
     238                 :            :                 }
     239                 :            : 
     240         [ +  + ]:       1125 :         if ( id->Type() )
     241                 :            :                 {
     242         [ -  + ]:        596 :                 if ( ! same_type(id->Type(), t) )
     243                 :        596 :                         id->Type()->Error("incompatible types", t);
     244                 :            :                 }
     245                 :            : 
     246         [ -  + ]:        529 :         else if ( is_redef )
     247                 :          0 :                 id->Error("redef of not-previously-declared value");
     248                 :            : 
     249         [ +  + ]:       1125 :         if ( id->HasVal() )
     250                 :            :                 {
     251                 :        177 :                 int id_is_event = id->ID_Val()->AsFunc()->IsEvent();
     252                 :            : 
     253         [ -  + ]:        177 :                 if ( id_is_event != (flavor == FUNC_FLAVOR_EVENT) )
     254                 :          0 :                         id->Error("inconsistency between event and function", t);
     255         [ +  + ]:        177 :                 if ( id_is_event )
     256                 :            :                         {
     257         [ -  + ]:        176 :                         if ( is_redef )
     258                 :            :                                 // Clear out value so it will be replaced.
     259                 :        176 :                                 id->SetVal(0);
     260                 :            :                         }
     261                 :            :                 else
     262                 :            :                         {
     263         [ -  + ]:          1 :                         if ( ! id->IsRedefinable() )
     264                 :        177 :                                 id->Error("already defined");
     265                 :            :                         }
     266                 :            :                 }
     267                 :            :         else
     268                 :        948 :                 id->SetType(t);
     269                 :            : 
     270                 :       1125 :         push_scope(id);
     271                 :            : 
     272                 :       1125 :         RecordType* args = t->Args();
     273                 :       1125 :         int num_args = args->NumFields();
     274         [ +  + ]:       3447 :         for ( int i = 0; i < num_args; ++i )
     275                 :            :                 {
     276                 :       2322 :                 TypeDecl* arg_i = args->FieldDecl(i);
     277                 :       2322 :                 ID* arg_id = lookup_ID(arg_i->id, module_name);
     278                 :            : 
     279   [ +  +  -  + ]:       2322 :                 if ( arg_id && ! arg_id->IsGlobal() )
                 [ -  + ]
     280                 :          0 :                         arg_id->Error("argument name used twice");
     281                 :            : 
     282                 :            :                 arg_id = install_ID(copy_string(arg_i->id), module_name,
     283                 :       2322 :                                         false, false);
     284                 :       2322 :                 arg_id->SetType(arg_i->type->Ref());
     285                 :            :                 }
     286                 :       1125 :         }
     287                 :            : 
     288                 :       1125 : void end_func(Stmt* body, attr_list* attrs)
     289                 :            :         {
     290                 :       1125 :         int frame_size = current_scope()->Length();
     291                 :       1125 :         id_list* inits = current_scope()->GetInits();
     292                 :            : 
     293                 :       1125 :         Scope* scope = pop_scope();
     294                 :       1125 :         ID* id = scope->ScopeID();
     295                 :            : 
     296                 :       1125 :         int priority = 0;
     297         [ +  + ]:       1125 :         if ( attrs )
     298                 :            :                 {
     299         [ +  + ]:         28 :                 loop_over_list(*attrs, i)
     300                 :            :                         {
     301                 :         14 :                         Attr* a = (*attrs)[i];
     302         [ -  + ]:         14 :                         if ( a->Tag() != ATTR_PRIORITY )
     303                 :            :                                 {
     304                 :          0 :                                 a->Error("illegal attribute for function body");
     305                 :          0 :                                 continue;
     306                 :            :                                 }
     307                 :            : 
     308                 :         14 :                         Val* v = a->AttrExpr()->Eval(0);
     309         [ -  + ]:         14 :                         if ( ! v )
     310                 :            :                                 {
     311                 :          0 :                                 a->Error("cannot evaluate attribute expression");
     312                 :          0 :                                 continue;
     313                 :            :                                 }
     314                 :            : 
     315 [ +  + ][ -  + ]:         14 :                         if ( ! IsIntegral(v->Type()->Tag()) )
         [ #  # ][ -  + ]
     316                 :            :                                 {
     317                 :          0 :                                 a->Error("expression is not of integral type");
     318                 :          0 :                                 continue;
     319                 :            :                                 }
     320                 :            : 
     321                 :         14 :                         priority = v->InternalInt();
     322                 :            :                         }
     323                 :            :                 }
     324                 :            : 
     325         [ +  + ]:       1125 :         if ( id->HasVal() )
     326                 :        177 :                 id->ID_Val()->AsFunc()->AddBody(body, inits, frame_size, priority);
     327                 :            :         else
     328                 :            :                 {
     329                 :        948 :                 Func* f = new BroFunc(id, body, inits, frame_size);
     330                 :        948 :                 id->SetVal(new Val(f));
     331                 :        948 :                 id->SetConst();
     332                 :            :                 }
     333                 :            : 
     334                 :       1125 :         id->ID_Val()->AsFunc()->SetScope(scope);
     335                 :       1125 :         }
     336                 :            : 
     337                 :         55 : Val* internal_val(const char* name)
     338                 :            :         {
     339                 :         55 :         ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
     340         [ -  + ]:         55 :         if ( ! id )
     341                 :          0 :                 internal_error("internal variable %s missing", name);
     342                 :            : 
     343                 :         55 :         return id->ID_Val();
     344                 :            :         }
     345                 :            : 
     346                 :        123 : Val* opt_internal_val(const char* name)
     347                 :            :         {
     348                 :        123 :         ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
     349         [ +  + ]:        123 :         return id ? id->ID_Val() : 0;
     350                 :            :         }
     351                 :            : 
     352                 :         44 : double opt_internal_double(const char* name)
     353                 :            :         {
     354                 :         44 :         Val* v = opt_internal_val(name);
     355         [ +  + ]:         44 :         return v ? v->InternalDouble() : 0.0;
     356                 :            :         }
     357                 :            : 
     358                 :         67 : bro_int_t opt_internal_int(const char* name)
     359                 :            :         {
     360                 :         67 :         Val* v = opt_internal_val(name);
     361         [ +  + ]:         67 :         return v ? v->InternalInt() : 0;
     362                 :            :         }
     363                 :            : 
     364                 :          0 : bro_uint_t opt_internal_unsigned(const char* name)
     365                 :            :         {
     366                 :          0 :         Val* v = opt_internal_val(name);
     367         [ #  # ]:          0 :         return v ? v->InternalUnsigned() : 0;
     368                 :            :         }
     369                 :            : 
     370                 :          7 : StringVal* opt_internal_string(const char* name)
     371                 :            :         {
     372                 :          7 :         Val* v = opt_internal_val(name);
     373         [ +  + ]:          7 :         return v ? v->AsStringVal() : 0;
     374                 :            :         }
     375                 :            : 
     376                 :          4 : TableVal* opt_internal_table(const char* name)
     377                 :            :         {
     378                 :          4 :         Val* v = opt_internal_val(name);
     379         [ +  + ]:          4 :         return v ? v->AsTableVal() : 0;
     380                 :            :         }
     381                 :            : 
     382                 :          7 : ListVal* internal_list_val(const char* name)
     383                 :            :         {
     384                 :          7 :         ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
     385         [ -  + ]:          7 :         if ( ! id )
     386                 :          0 :                 return 0;
     387                 :            : 
     388                 :          7 :         Val* v = id->ID_Val();
     389         [ +  - ]:          7 :         if ( v )
     390                 :            :                 {
     391         [ -  + ]:          7 :                 if ( v->Type()->Tag() == TYPE_LIST )
     392                 :          0 :                         return (ListVal*) v;
     393                 :            : 
     394         [ +  - ]:          7 :                 else if ( v->Type()->IsSet() )
     395                 :            :                         {
     396                 :          7 :                         TableVal* tv = v->AsTableVal();
     397                 :          7 :                         ListVal* lv = tv->ConvertToPureList();
     398                 :          7 :                         return lv;
     399                 :            :                         }
     400                 :            : 
     401                 :            :                 else
     402                 :          0 :                         internal_error("internal variable %s is not a list", name);
     403                 :            :                 }
     404                 :            : 
     405                 :          7 :         return 0;
     406                 :            :         }
     407                 :            : 
     408                 :        452 : BroType* internal_type(const char* name)
     409                 :            :         {
     410                 :        452 :         ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
     411         [ -  + ]:        452 :         if ( ! id )
     412                 :          0 :                 internal_error("internal type %s missing", name);
     413                 :            : 
     414                 :        452 :         return id->Type();
     415                 :            :         }
     416                 :            : 
     417                 :          5 : Func* internal_func(const char* name)
     418                 :            :         {
     419                 :          5 :         Val* v = internal_val(name);
     420         [ -  + ]:          5 :         if ( v )
     421                 :          0 :                 return v->AsFunc();
     422                 :            :         else
     423                 :          5 :                 return 0;
     424                 :            :         }
     425                 :            : 
     426                 :        988 : EventHandlerPtr internal_handler(const char* name)
     427                 :            :         {
     428                 :            :         // If there already is an entry in the registry, we have a
     429                 :            :         // local handler on the script layer.
     430                 :        988 :         EventHandler* h = event_registry->Lookup(name);
     431         [ +  + ]:        988 :         if ( h )
     432                 :            :                 {
     433                 :         16 :                 h->SetUsed();
     434                 :         16 :                 return h;
     435                 :            :                 }
     436                 :            : 
     437                 :       1960 :         h = new EventHandler(name);
     438                 :        972 :         event_registry->Register(h);
     439                 :            : 
     440                 :        972 :         h->SetUsed();
     441                 :            : 
     442                 :        972 :         return h;
     443 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8