diff --git a/NEWS b/NEWS index 6abb21c055..7ae2250cfe 100644 --- a/NEWS +++ b/NEWS @@ -94,6 +94,12 @@ New Functionality is available in the events: ``ssl_extension_pre_shared_key_client_hello`` and ``ssl_extension_pre_shared_key_server_hello``. +- Add support for vector slicing operations. For example:: + + local v = vector(1, 2, 3, 4, 5); + v[2:4] = vector(6, 7, 8); # v is now [1, 2, 6, 7, 8, 5] + print v[:4]; # prints [1, 2, 6, 7] + Changed Functionality --------------------- diff --git a/src/Expr.cc b/src/Expr.cc index ea8253e347..58963579fd 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3200,27 +3200,26 @@ void IndexExpr::Assign(Frame* f, Val* v, Opcode op) switch ( v1->Type()->Tag() ) { case TYPE_VECTOR: { - const ListVal *lv = v2->AsListVal(); + const ListVal* lv = v2->AsListVal(); VectorVal* v1_vect = v1->AsVectorVal(); if ( lv->Length() > 1 ) { - int len = v1_vect->Size(); + auto len = v1_vect->Size(); bro_int_t first = get_slice_index(lv->Index(0)->CoerceToInt(), len); bro_int_t last = get_slice_index(lv->Index(1)->CoerceToInt(), len); // Remove the elements from the vector within the slice - for ( int idx = first; idx < last; idx++ ) + for ( auto idx = first; idx < last; idx++ ) v1_vect->Remove(first); // Insert the new elements starting at the first position VectorVal* v_vect = v->AsVectorVal(); - for ( int idx = 0; idx < v_vect->Size(); idx++, first++ ) - { + + for ( auto idx = 0u; idx < v_vect->Size(); idx++, first++ ) v1_vect->Insert(first, v_vect->Lookup(idx)->Ref()); - } } - else if ( !v1_vect->Assign(v2, v, op) ) + else if ( ! v1_vect->Assign(v2, v, op) ) { if ( v ) { diff --git a/src/Val.cc b/src/Val.cc index 0a6c7dd985..21a2d4a7db 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -3417,6 +3417,7 @@ bool VectorVal::Insert(unsigned int index, Val* element) } vector::iterator it; + if ( index < val.vector_val->size() ) it = std::next(val.vector_val->begin(), index); else diff --git a/src/Val.h b/src/Val.h index 20302e3a9d..66ad7e907e 100644 --- a/src/Val.h +++ b/src/Val.h @@ -1197,8 +1197,8 @@ public: // Insert an element at a specific position into the underlying vector. bool Insert(unsigned int index, Val* element); - // Removes an element or a range of elements from a specific position. - bool Remove(unsigned int start_index); + // Removes an element at a specific position. + bool Remove(unsigned int index); protected: friend class Val; diff --git a/src/parse.y b/src/parse.y index 07a544bb64..4c39ee191d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -484,8 +484,10 @@ expr: set_location(@1, @6); Expr* low = $3 ? $3 : new ConstExpr(val_mgr->GetCount(0)); Expr* high = $5 ? $5 : new SizeExpr($1); + if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) ) - reporter->FatalError("slice notation must have integral values as indexes"); + reporter->Error("slice notation must have integral values as indexes"); + ListExpr* le = new ListExpr(low); le->Append(high); $$ = new IndexExpr($1, le, true);