diff --git a/NEWS b/NEWS index d23275ac78..fcc86a5f6d 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,12 @@ Breaking Changes New Functionality ----------------- +- Support ``delete`` on tables, sets and vectors to clear their contents. + + global v = vector(1, 2, 3); + delete v; + assert |v| == 0; + Changed Functionality --------------------- diff --git a/src/Expr.cc b/src/Expr.cc index 348b34356a..dde0575490 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -408,6 +408,24 @@ NameExpr::NameExpr(IDPtr arg_id, bool const_init) : Expr(EXPR_NAME), id(std::mov #pragma GCC diagnostic pop } +bool NameExpr::CanDel() const { + if ( IsError() ) + return true; // avoid cascading the error report + + return GetType()->Tag() == TYPE_TABLE || GetType()->Tag() == TYPE_VECTOR; +} + +void NameExpr::Delete(Frame* f) { + if ( auto v = Eval(f) ) { + if ( GetType()->Tag() == TYPE_TABLE ) + v->AsTableVal()->RemoveAll(); + else if ( GetType()->Tag() == TYPE_VECTOR ) + v->AsVectorVal()->Resize(0); + else + RuntimeError("delete unsupported"); + } +} + // This isn't in-lined to avoid needing to pull in ID.h. const IDPtr& NameExpr::IdPtr() const { return id; } diff --git a/src/Expr.h b/src/Expr.h index 524cd1440d..bc0990fcec 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -428,6 +428,9 @@ class NameExpr final : public Expr { public: explicit NameExpr(IDPtr id, bool const_init = false); + bool CanDel() const override; + void Delete(Frame* f) override; + ID* Id() const { return id.get(); } const IDPtr& IdPtr() const; diff --git a/testing/btest/Baseline/language.delete-containers/.stderr b/testing/btest/Baseline/language.delete-containers/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/language.delete-containers/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/language.delete-containers/output b/testing/btest/Baseline/language.delete-containers/output new file mode 100644 index 0000000000..45ecb158e1 --- /dev/null +++ b/testing/btest/Baseline/language.delete-containers/output @@ -0,0 +1,15 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +t, { +[42] = 4711 +} +s, { +42 +} +v, [1, 2, 3] +t, { + +} +s, { + +} +v, [] diff --git a/testing/btest/Baseline/language.delete-table-set/.stderr b/testing/btest/Baseline/language.delete-table-set/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/language.delete-table-set/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/language/delete-containers.zeek b/testing/btest/language/delete-containers.zeek new file mode 100644 index 0000000000..38de3eaa42 --- /dev/null +++ b/testing/btest/language/delete-containers.zeek @@ -0,0 +1,24 @@ +# @TEST-DOC: Deleteing a table, set or vector removes all of its elements. + +# @TEST-EXEC: zeek -b %INPUT >output +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff .stderr + +global t: table[count] of count &read_expire=1sec; +global s: set[count]; +global v = vector(1,2,3); + +t[42] = 4711; +add s[42]; + +print "t", t; +print "s", s; +print "v", v; + +delete t; +delete s; +delete v; + +print "t", t; +print "s", s; +print "v", v;