LCOV - code coverage report
Current view: top level - src - Attr.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 99 184 53.8 %
Date: 2010-12-13 Functions: 13 27 48.1 %
Branches: 81 200 40.5 %

           Branch data     Line data    Source code
       1                 :            : // $Id: Attr.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 "Attr.h"
       8                 :            : #include "Expr.h"
       9                 :            : #include "Serializer.h"
      10                 :            : 
      11                 :          0 : const char* attr_name(attr_tag t)
      12                 :            :         {
      13                 :            :         static const char* attr_names[int(NUM_ATTRS)] = {
      14                 :            :                 "&optional", "&default", "&redef",
      15                 :            :                 "&rotate_interval", "&rotate_size",
      16                 :            :                 "&add_func", "&delete_func", "&expire_func",
      17                 :            :                 "&read_expire", "&write_expire", "&create_expire",
      18                 :            :                 "&persistent", "&synchronized", "&postprocessor",
      19                 :            :                 "&encrypt", "&match", "&disable_print_hook",
      20                 :            :                 "&raw_output", "&mergeable", "&priority",
      21                 :            :                 "&group", "(&tracked)",
      22                 :            :         };
      23                 :            : 
      24                 :          0 :         return attr_names[int(t)];
      25                 :            :         }
      26                 :            : 
      27                 :       1845 : Attr::Attr(attr_tag t, Expr* e)
      28                 :            :         {
      29                 :       1845 :         tag = t;
      30                 :       1845 :         expr = e;
      31                 :       1845 :         SetLocationInfo(&start_location, &end_location);
      32                 :       1845 :         }
      33                 :            : 
      34                 :          0 : Attr::~Attr()
      35                 :            :         {
      36                 :          0 :         Unref(expr);
      37 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
      38                 :            : 
      39                 :          0 : void Attr::Describe(ODesc* d) const
      40                 :            :         {
      41                 :          0 :         AddTag(d);
      42                 :            : 
      43         [ #  # ]:          0 :         if ( expr )
      44                 :            :                 {
      45         [ #  # ]:          0 :                 if ( ! d->IsBinary() )
      46                 :          0 :                         d->Add("=");
      47                 :            : 
      48                 :          0 :                 expr->Describe(d);
      49                 :            :                 }
      50                 :          0 :         }
      51                 :            : 
      52                 :          0 : void Attr::AddTag(ODesc* d) const
      53                 :            :         {
      54         [ #  # ]:          0 :         if ( d->IsBinary() )
      55                 :          0 :                 d->Add(static_cast<bro_int_t>(Tag()));
      56                 :            :         else
      57                 :          0 :                 d->Add(attr_name(Tag()));
      58                 :          0 :         }
      59                 :            : 
      60                 :       1510 : Attributes::Attributes(attr_list* a, BroType* t)
      61                 :            :         {
      62                 :       1510 :         attrs = new attr_list(a->length());
      63                 :       1510 :         type = t->Ref();
      64                 :            : 
      65                 :       1510 :         SetLocationInfo(&start_location, &end_location);
      66                 :            : 
      67                 :            :         // We loop through 'a' and add each attribute individually,
      68                 :            :         // rather than just taking over 'a' for ourselves, so that
      69                 :            :         // the necessary checking gets done.
      70                 :            : 
      71 [ +  + ][ #  # ]:       3137 :         loop_over_list(*a, i)
      72                 :       1627 :                 AddAttr((*a)[i]);
      73                 :            : 
      74 [ +  - ][ #  # ]:       1510 :         delete a;
      75                 :       1510 :         }
      76                 :            : 
      77                 :         16 : Attributes::~Attributes()
      78                 :            :         {
      79 [ +  + ][ #  # ]:         34 :         loop_over_list(*attrs, i)
                 [ #  # ]
      80                 :         18 :                 Unref((*attrs)[i]);
      81                 :            : 
      82 [ +  - ][ #  # ]:         16 :         delete attrs;
                 [ #  # ]
      83                 :            : 
      84                 :         16 :         Unref(type);
      85 [ +  - ][ #  # ]:         16 :         }
                 [ #  # ]
      86                 :            : 
      87                 :       1645 : void Attributes::AddAttr(Attr* attr)
      88                 :            :         {
      89         [ -  + ]:       1645 :         if ( ! attrs )
      90                 :          0 :                 attrs = new attr_list;
      91                 :            : 
      92         [ +  + ]:       1645 :         if ( ! attr->RedundantAttrOkay() )
      93                 :            :                 // We overwrite old attributes by deleting them first.
      94                 :        514 :                 RemoveAttr(attr->Tag());
      95                 :            : 
      96                 :       1645 :         attrs->append(attr);
      97                 :       1645 :         Ref(attr);
      98                 :            : 
      99                 :            :         // We only check the attribute after we've added it, to facilitate
     100                 :            :         // generating error messages via Attributes::Describe.
     101                 :       1645 :         CheckAttr(attr);
     102                 :            : 
     103                 :            :         // For ADD_FUNC or DEL_FUNC, add in an implicit REDEF, since
     104                 :            :         // those attributes only have meaning for a redefinable value.
     105   [ +  +  -  + ]:       1645 :         if ( (attr->Tag() == ATTR_ADD_FUNC || attr->Tag() == ATTR_DEL_FUNC) &&
         [ +  - ][ +  + ]
     106                 :            :              ! FindAttr(ATTR_REDEF) )
     107                 :          6 :                 attrs->append(new Attr(ATTR_REDEF));
     108                 :            : 
     109                 :            :         // For DEFAULT, add an implicit OPTIONAL.
     110 [ +  + ][ +  + ]:       1645 :         if ( attr->Tag() == ATTR_DEFAULT && ! FindAttr(ATTR_OPTIONAL) )
                 [ +  + ]
     111                 :        198 :                 attrs->append(new Attr(ATTR_OPTIONAL));
     112                 :       1645 :         }
     113                 :            : 
     114                 :         16 : void Attributes::AddAttrs(Attributes* a)
     115                 :            :         {
     116                 :         16 :         attr_list* as = a->Attrs();
     117         [ +  + ]:         34 :         loop_over_list(*as, i)
     118                 :         18 :                 AddAttr((*as)[i]);
     119                 :            : 
     120                 :         16 :         Unref(a);
     121                 :         16 :         }
     122                 :            : 
     123                 :     156094 : Attr* Attributes::FindAttr(attr_tag t) const
     124                 :            :         {
     125         [ -  + ]:     156094 :         if ( ! attrs )
     126                 :          0 :                 return 0;
     127                 :            : 
     128         [ +  + ]:     306500 :         loop_over_list(*attrs, i)
     129                 :            :                 {
     130                 :     201981 :                 Attr* a = (*attrs)[i];
     131         [ +  + ]:     201981 :                 if ( a->Tag() == t )
     132                 :      51575 :                         return a;
     133                 :            :                 }
     134                 :            : 
     135                 :     156094 :         return 0;
     136                 :            :         }
     137                 :            : 
     138                 :        514 : void Attributes::RemoveAttr(attr_tag t)
     139                 :            :         {
     140         [ +  + ]:        681 :         for ( int i = 0; i < attrs->length(); i++ )
     141         [ +  + ]:        167 :                 if ( (*attrs)[i]->Tag() == t )
     142                 :          8 :                         attrs->remove_nth(i--);
     143                 :        514 :         }
     144                 :            : 
     145                 :          0 : void Attributes::Describe(ODesc* d) const
     146                 :            :         {
     147         [ #  # ]:          0 :         if ( ! attrs )
     148                 :            :                 {
     149                 :          0 :                 d->AddCount(0);
     150                 :          0 :                 return;
     151                 :            :                 }
     152                 :            : 
     153                 :          0 :         d->AddCount(attrs->length());
     154                 :            : 
     155         [ #  # ]:          0 :         loop_over_list(*attrs, i)
     156                 :            :                 {
     157 [ #  # ][ #  # ]:          0 :                 if ( (d->IsReadable() || d->IsPortable()) && i > 0 )
         [ #  # ][ #  # ]
     158                 :          0 :                         d->Add(", ");
     159                 :            : 
     160                 :          0 :                 (*attrs)[i]->Describe(d);
     161                 :            :                 }
     162                 :            :         }
     163                 :            : 
     164                 :       1645 : void Attributes::CheckAttr(Attr* a)
     165                 :            :         {
     166 [ +  +  +  -  - :       1645 :         switch ( a->Tag() ) {
          -  -  +  +  +  
          -  -  +  -  +  
                      - ]
     167                 :            :         case ATTR_OPTIONAL:
     168                 :            :         case ATTR_REDEF:
     169                 :       1131 :                 break;
     170                 :            : 
     171                 :            :         case ATTR_ADD_FUNC:
     172                 :            :         case ATTR_DEL_FUNC:
     173                 :            :                 {
     174                 :          6 :                 int is_add = a->Tag() == ATTR_ADD_FUNC;
     175                 :            : 
     176                 :          6 :                 BroType* at = a->AttrExpr()->Type();
     177         [ -  + ]:          6 :                 if ( at->Tag() != TYPE_FUNC )
     178                 :            :                         {
     179                 :            :                         a->AttrExpr()->Error(
     180                 :            :                                 is_add ?
     181                 :            :                                         "&add_func must be a function" :
     182         [ #  # ]:          0 :                                         "&delete_func must be a function");
     183                 :          0 :                         break;
     184                 :            :                         }
     185                 :            : 
     186                 :          6 :                 FuncType* aft = at->AsFuncType();
     187         [ -  + ]:          6 :                 if ( ! same_type(aft->YieldType(), type) )
     188                 :            :                         {
     189                 :            :                         a->AttrExpr()->Error(
     190                 :            :                                 is_add ?
     191                 :            :                                         "&add_func function must yield same type as variable" :
     192         [ #  # ]:          0 :                                         "&delete_func function must yield same type as variable");
     193                 :          0 :                         break;
     194                 :            :                         }
     195                 :            :                 }
     196                 :          6 :                 break;
     197                 :            : 
     198                 :            :         case ATTR_DEFAULT:
     199                 :            :                 {
     200                 :        202 :                 BroType* atype = a->AttrExpr()->Type();
     201                 :            : 
     202   [ +  +  -  + ]:        202 :                 if ( type->Tag() != TYPE_TABLE || type->IsSet() )
                 [ +  + ]
     203                 :            :                         {
     204         [ -  + ]:        118 :                         if ( ! same_type(atype, type) )
     205                 :          0 :                                 a->AttrExpr()->Error("&default value has inconsistent type", type);
     206                 :        118 :                         break;
     207                 :            :                         }
     208                 :            : 
     209                 :         84 :                 TableType* tt = type->AsTableType();
     210                 :            : 
     211         [ +  + ]:         84 :                 if ( ! same_type(atype, tt->YieldType()) )
     212                 :            :                         {
     213                 :            :                         // It can still be a default function.
     214         [ +  - ]:         15 :                         if ( atype->Tag() == TYPE_FUNC )
     215                 :            :                                 {
     216                 :         15 :                                 FuncType* f = atype->AsFuncType();
     217   [ +  -  -  + ]:         15 :                                 if ( ! f->CheckArgs(tt->IndexTypes()) ||
                 [ -  + ]
     218                 :            :                                      ! same_type(f->YieldType(), tt->YieldType()) )
     219                 :         15 :                                         Error("&default function type clash");
     220                 :            :                                 }
     221                 :            :                         else
     222                 :          0 :                                 Error("&default value has inconsistent type");
     223                 :            :                         }
     224                 :            :                 }
     225                 :         84 :                 break;
     226                 :            : 
     227                 :            :         case ATTR_ROTATE_INTERVAL:
     228         [ #  # ]:          0 :                 if ( type->Tag() != TYPE_FILE )
     229                 :          0 :                         Error("&rotate_interval only applicable to files");
     230                 :          0 :                 break;
     231                 :            : 
     232                 :            :         case ATTR_ROTATE_SIZE:
     233         [ #  # ]:          0 :                 if ( type->Tag() != TYPE_FILE )
     234                 :          0 :                         Error("&rotate_size only applicable to files");
     235                 :          0 :                 break;
     236                 :            : 
     237                 :            :         case ATTR_POSTPROCESSOR:
     238         [ #  # ]:          0 :                 if ( type->Tag() != TYPE_FILE )
     239                 :          0 :                         Error("&postprocessor only applicable to files");
     240                 :          0 :                 break;
     241                 :            : 
     242                 :            :         case ATTR_ENCRYPT:
     243         [ #  # ]:          0 :                 if ( type->Tag() != TYPE_FILE )
     244                 :          0 :                         Error("&encrypt only applicable to files");
     245                 :          0 :                 break;
     246                 :            : 
     247                 :            :         case ATTR_EXPIRE_READ:
     248                 :            :         case ATTR_EXPIRE_WRITE:
     249                 :            :         case ATTR_EXPIRE_CREATE:
     250         [ -  + ]:        140 :                 if ( type->Tag() != TYPE_TABLE )
     251                 :            :                         {
     252                 :          0 :                         Error("expiration only applicable to tables");
     253                 :          0 :                         break;
     254                 :            :                         }
     255                 :            : 
     256                 :            : #if 0
     257                 :            :                 //### not easy to test this w/o knowing the ID.
     258                 :            :                 if ( ! IsGlobal() )
     259                 :            :                         Error("expiration not supported for local variables");
     260                 :            : #endif
     261                 :        140 :                 break;
     262                 :            : 
     263                 :            :         case ATTR_EXPIRE_FUNC:
     264                 :            :                 {
     265         [ -  + ]:         19 :                 if ( type->Tag() != TYPE_TABLE )
     266                 :            :                         {
     267                 :          0 :                         Error("expiration only applicable to tables");
     268                 :          0 :                         break;
     269                 :            :                         }
     270                 :            : 
     271                 :         19 :                 const Expr* expire_func = a->AttrExpr();
     272                 :         19 :                 const FuncType* e_ft = expire_func->Type()->AsFuncType();
     273                 :            : 
     274         [ -  + ]:         19 :                 if ( ((const BroType*) e_ft)->YieldType()->Tag() != TYPE_INTERVAL )
     275                 :            :                         {
     276                 :          0 :                         Error("&expire_func must yield a value of type interval");
     277                 :          0 :                         break;
     278                 :            :                         }
     279                 :            : 
     280         [ -  + ]:         19 :                 if ( e_ft->Args()->NumFields() != 2 )
     281                 :            :                         {
     282                 :          0 :                         Error("&expire_func function must take exactly two arguments");
     283                 :          0 :                         break;
     284                 :            :                         }
     285                 :            : 
     286                 :            :                 // ### Should type-check arguments to make sure first is
     287                 :            :                 // table type and second is table index type.
     288                 :            :                 }
     289                 :         19 :                 break;
     290                 :            : 
     291                 :            :         case ATTR_PERSISTENT:
     292                 :            :         case ATTR_SYNCHRONIZED:
     293                 :            :         case ATTR_TRACKED:
     294                 :            :                 // FIXME: Check here for global ID?
     295                 :         20 :                 break;
     296                 :            : 
     297                 :            :         case ATTR_DISABLE_PRINT_HOOK:
     298         [ #  # ]:          0 :                 if ( type->Tag() != TYPE_FILE )
     299                 :          0 :                         Error("&disable_print_hook only applicable to files");
     300                 :          0 :                 break;
     301                 :            : 
     302                 :            :         case ATTR_RAW_OUTPUT:
     303         [ #  # ]:          0 :                 if ( type->Tag() != TYPE_FILE )
     304                 :          0 :                         Error("&raw_output only applicable to files");
     305                 :          0 :                 break;
     306                 :            : 
     307                 :            :         case ATTR_MERGEABLE:
     308         [ -  + ]:         19 :                 if ( type->Tag() != TYPE_TABLE )
     309                 :          0 :                         Error("&mergeable only applicable to tables/sets");
     310                 :         19 :                 break;
     311                 :            : 
     312                 :            :         case ATTR_PRIORITY:
     313                 :          0 :                 Error("&priority only applicable to event bodies");
     314                 :          0 :                 break;
     315                 :            : 
     316                 :            :         case ATTR_GROUP:
     317 [ +  - ][ -  + ]:        108 :                 if ( type->Tag() != TYPE_FUNC ||
                 [ -  + ]
     318                 :            :                      ! type->AsFuncType()->IsEvent() )
     319                 :            :                         {
     320                 :          0 :                         Error("&group only applicable to events");
     321                 :          0 :                         break;
     322                 :            :                         }
     323                 :        108 :                 break;
     324                 :            : 
     325                 :            :         default:
     326                 :          0 :                 BadTag("Attributes::CheckAttr", attr_name(a->Tag()));
     327                 :            :         }
     328                 :       1645 :         }
     329                 :            : 
     330                 :          7 : bool Attributes::Serialize(SerialInfo* info) const
     331                 :            :         {
     332                 :          7 :         return SerialObj::Serialize(info);
     333                 :            :         }
     334                 :            : 
     335                 :          0 : Attributes* Attributes::Unserialize(UnserialInfo* info)
     336                 :            :         {
     337                 :          0 :         return (Attributes*) SerialObj::Unserialize(info, SER_ATTRIBUTES);
     338                 :            :         }
     339                 :            : 
     340                 :         15 : IMPLEMENT_SERIAL(Attributes, SER_ATTRIBUTES);
     341                 :            : 
     342                 :          6 : bool Attributes::DoSerialize(SerialInfo* info) const
     343                 :            :         {
     344 [ +  - ][ -  + ]:          6 :         DO_SERIALIZE(SER_ATTRIBUTES, BroObj);
     345                 :            : 
     346                 :          6 :         info->s->WriteOpenTag("Attributes");
     347         [ -  + ]:          6 :         assert(type);
     348 [ +  - ][ -  + ]:          6 :         if ( ! (type->Serialize(info) && SERIALIZE(attrs->length())) )
                 [ -  + ]
     349                 :          0 :                 return false;
     350                 :            : 
     351         [ +  + ]:         19 :         loop_over_list((*attrs), i)
     352                 :            :                 {
     353                 :         13 :                 Attr* a = (*attrs)[i];
     354   [ +  +  +  - ]:         13 :                 SERIALIZE_OPTIONAL(a->AttrExpr())
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
     355         [ -  + ]:         13 :                 if ( ! SERIALIZE(char(a->Tag())) )
     356                 :          0 :                         return false;
     357                 :            :                 }
     358                 :            : 
     359                 :          6 :         info->s->WriteCloseTag("Attributes");
     360                 :          6 :         return true;
     361                 :            :         }
     362                 :            : 
     363                 :          0 : bool Attributes::DoUnserialize(UnserialInfo* info)
     364                 :            :         {
     365         [ #  # ]:          0 :         DO_UNSERIALIZE(BroObj);
     366                 :            : 
     367                 :          0 :         type = BroType::Unserialize(info);
     368         [ #  # ]:          0 :         if ( ! type )
     369                 :          0 :                 return false;
     370                 :            : 
     371                 :            :         int len;
     372         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&len) )
     373                 :          0 :                 return false;
     374                 :            : 
     375                 :          0 :         attrs = new attr_list(len);
     376         [ #  # ]:          0 :         while ( len-- )
     377                 :            :                 {
     378                 :            :                 Expr* e;
     379 [ #  # ][ #  # ]:          0 :                 UNSERIALIZE_OPTIONAL(e, Expr::Unserialize(info))
                 [ #  # ]
     380                 :            : 
     381                 :            :                 char tag;
     382         [ #  # ]:          0 :                 if ( ! UNSERIALIZE(&tag) )
     383                 :            :                         {
     384         [ #  # ]:          0 :                         delete e;
     385                 :          0 :                         return false;
     386                 :            :                         }
     387                 :            : 
     388                 :          0 :                 attrs->append(new Attr((attr_tag)tag, e));
     389                 :            :                 }
     390                 :            : 
     391                 :          0 :         return true;
     392 [ +  - ][ +  - ]:          6 :         }
     393                 :          3 : 

Generated by: LCOV version 1.8