Merge remote-tracking branch 'origin/topic/jsiwek/table-init-container-ctors'

* origin/topic/jsiwek/table-init-container-ctors:
  Add test of record() constructor to table initializer unit test.
  Fix table(), set(), vector() constructors in table initializer lists.

Closes #5.
This commit is contained in:
Robin Sommer 2012-12-03 14:08:56 -08:00
commit d4792dc7fe
6 changed files with 191 additions and 7 deletions

10
CHANGES
View file

@ -1,4 +1,14 @@
2.1-191 | 2012-12-03 14:08:56 -0800
* Add test of record() constructor to table initializer unit test.
(Jon Siwek)
* Fix table(), set(), vector() constructors in table initializer
lists. Also adds type checking of yield values to table()
constructor and fixes the type checking of yield values in
vector() constructor. Addresses #5. (Jon Siwek)
2.1-188 | 2012-12-03 14:04:29 -0800 2.1-188 | 2012-12-03 14:04:29 -0800
* Hook functions now callable with "hook" expression (i.e., hook is * Hook functions now callable with "hook" expression (i.e., hook is

View file

@ -1 +1 @@
2.1-188 2.1-191

View file

@ -2663,7 +2663,7 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const
TableVal* tv = aggr->AsTableVal(); TableVal* tv = aggr->AsTableVal();
Val* index = op1->Eval(f); Val* index = op1->Eval(f);
Val* v = op2->Eval(f); Val* v = check_and_promote(op2->Eval(f), t->YieldType(), 1);
if ( ! index || ! v ) if ( ! index || ! v )
return; return;
@ -3386,7 +3386,14 @@ Val* TableConstructorExpr::InitVal(const BroType* t, Val* aggr) const
if ( IsError() ) if ( IsError() )
return 0; return 0;
return op->InitVal(t, aggr); TableType* tt = Type()->AsTableType();
TableVal* tval = aggr ? aggr->AsTableVal() : new TableVal(tt, attrs);
const expr_list& exprs = op->AsListExpr()->Exprs();
loop_over_list(exprs, i)
exprs[i]->EvalIntoAggregate(t, tval, 0);
return tval;
} }
void TableConstructorExpr::ExprDescribe(ODesc* d) const void TableConstructorExpr::ExprDescribe(ODesc* d) const
@ -3456,7 +3463,26 @@ Val* SetConstructorExpr::InitVal(const BroType* t, Val* aggr) const
if ( IsError() ) if ( IsError() )
return 0; return 0;
return op->InitVal(t, aggr); const BroType* index_type = t->AsTableType()->Indices();
TableType* tt = Type()->AsTableType();
TableVal* tval = aggr ? aggr->AsTableVal() : new TableVal(tt, attrs);
const expr_list& exprs = op->AsListExpr()->Exprs();
loop_over_list(exprs, i)
{
Expr* e = exprs[i];
Val* element = check_and_promote(e->Eval(0), index_type, 1);
if ( ! element || ! tval->Assign(element, 0) )
{
Error(fmt("initialization type mismatch in set"), e);
return 0;
}
Unref(element);
}
return tval;
} }
void SetConstructorExpr::ExprDescribe(ODesc* d) const void SetConstructorExpr::ExprDescribe(ODesc* d) const
@ -3536,14 +3562,14 @@ Val* VectorConstructorExpr::InitVal(const BroType* t, Val* aggr) const
if ( IsError() ) if ( IsError() )
return 0; return 0;
VectorVal* vec = aggr->AsVectorVal(); VectorType* vt = Type()->AsVectorType();
const BroType* vt = vec->Type()->AsVectorType()->YieldType(); VectorVal* vec = aggr ? aggr->AsVectorVal() : new VectorVal(vt);
const expr_list& exprs = op->AsListExpr()->Exprs(); const expr_list& exprs = op->AsListExpr()->Exprs();
loop_over_list(exprs, i) loop_over_list(exprs, i)
{ {
Expr* e = exprs[i]; Expr* e = exprs[i];
Val* v = check_and_promote(e->Eval(0), vt, 1); Val* v = check_and_promote(e->Eval(0), t->YieldType(), 1);
if ( ! v || ! vec->Assign(i, v, e) ) if ( ! v || ! vec->Assign(i, v, e) )
{ {

View file

@ -3117,6 +3117,9 @@ void VectorVal::ValDescribe(ODesc* d) const
Val* check_and_promote(Val* v, const BroType* t, int is_init) Val* check_and_promote(Val* v, const BroType* t, int is_init)
{ {
if ( ! v )
return 0;
BroType* vt = v->Type(); BroType* vt = v->Type();
vt = flatten_type(vt); vt = flatten_type(vt);

View file

@ -0,0 +1,50 @@
table of set
{
[13] = {
[bar, 2] ,
[foo, 1]
},
[5] = {
[bah, 3] ,
[baz, 4]
}
}
table of vector
{
[13] = [1, 2],
[5] = [3, 4]
}
table of table
{
[13] = {
[bar, 2] = 2,
[foo, 1] = 1
},
[5] = {
[bah, 3] = 3,
[baz, 4] = 4
}
}
table of record
{
[13] = [a=1, b=foo],
[5] = [a=2, b=bar]
}
T
T
T
T
T
T
T
T
T
T
T
T
T
T

View file

@ -0,0 +1,95 @@
# @TEST-EXEC: bro -b %INPUT >output
# @TEST-EXEC: btest-diff output
# The various container constructor expressions should work in table
# initialization lists.
type set_yield: set[string, count];
type vector_yield: vector of count;
type table_yield: table[string, count] of count;
type record_yield: record {
a: count;
b: string;
};
global lone_set_ctor: set_yield = set(["foo", 1], ["bar", 2]);
global lone_vector_ctor: vector_yield = vector(1, 2);
global lone_table_ctor: table_yield = table(["foo", 1] = 1, ["bar", 2] = 2);
global lone_record_ctor: record_yield = record($a=1, $b="foo");
global table_of_set: table[count] of set_yield = {
[13] = lone_set_ctor,
[5] = set(["bah", 3], ["baz", 4]),
};
global table_of_vector: table[count] of vector_yield = {
[13] = lone_vector_ctor,
[5] = vector(3, 4),
};
global table_of_table: table[count] of table_yield = {
[13] = lone_table_ctor,
[5] = table(["bah", 3] = 3, ["baz", 4] = 4),
};
global table_of_record: table[count] of record_yield = {
[13] = lone_record_ctor,
[5] = record($a=2, $b="bar"),
};
# Just copying the inline ctors used in the table initializer lists here
# for later comparisons.
global inline_set_ctor: set_yield = set(["bah", 3], ["baz", 4]);
global inline_vector_ctor: vector_yield = vector(3, 4);
global inline_table_ctor: table_yield = table(["bah", 3] = 3, ["baz", 4] = 4);
global inline_record_ctor: record_yield = record($a=2, $b="bar");
function compare_set_yield(a: set_yield, b: set_yield)
{
local s: string;
local c: count;
for ( [s, c] in a )
print [s, c] in b;
}
function compare_vector_yield(a: vector_yield, b: vector_yield)
{
local c: count;
for ( c in a )
print a[c] == b[c];
}
function compare_table_yield(a: table_yield, b: table_yield)
{
local s: string;
local c: count;
for ( [s, c] in a )
print [s, c] in b && a[s, c] == b[s, c];
}
function compare_record_yield(a: record_yield, b: record_yield)
{
print a$a == b$a && a$b == b$b;
}
print "table of set";
print table_of_set;
print "";
print "table of vector";
print table_of_vector;
print "";
print "table of table";
print table_of_table;
print "";
print "table of record";
print table_of_record;
print "";
compare_set_yield(table_of_set[13], lone_set_ctor);
compare_set_yield(table_of_set[5], inline_set_ctor);
compare_vector_yield(table_of_vector[13], lone_vector_ctor);
compare_vector_yield(table_of_vector[5], inline_vector_ctor);
compare_table_yield(table_of_table[13], lone_table_ctor);
compare_table_yield(table_of_table[5], inline_table_ctor);
compare_record_yield(table_of_record[13], lone_record_ctor);
compare_record_yield(table_of_record[5], inline_record_ctor);