The vector has the same functionality as the x2nrealloc for insert. Use vector instead which slightly simplifies the final code.
Signed-off-by: Ales Musil <[email protected]> --- controller/lflow.c | 40 ++++---- include/ovn/expr.h | 3 +- lib/actions.c | 30 +++--- lib/expr.c | 233 ++++++++++++++++++++++----------------------- 4 files changed, 156 insertions(+), 150 deletions(-) diff --git a/controller/lflow.c b/controller/lflow.c index 11ec33faf..197adaae9 100644 --- a/controller/lflow.c +++ b/controller/lflow.c @@ -447,21 +447,24 @@ consider_lflow_for_added_as_ips__( struct expr_constant_set *new_fake_as = NULL; struct in6_addr dummy_ip; bool has_dummy_ip = false; - ovs_assert(as_diff_added->n_values); + ovs_assert(vector_len(&as_diff_added->values)); /* When there is only 1 element, we append a dummy address and create a * fake address set with 2 elements, so that the lflow parsing would * generate exactly the same format of flows as it would when parsing with * the original address set. */ - if (as_diff_added->n_values == 1) { + if (vector_len(&as_diff_added->values) == 1) { new_fake_as = xzalloc(sizeof *new_fake_as); - new_fake_as->values = xzalloc(sizeof *new_fake_as->values * 2); - new_fake_as->n_values = 2; - new_fake_as->values[0] = new_fake_as->values[1] = - as_diff_added->values[0]; + new_fake_as->values = + VECTOR_CAPACITY_INITIALIZER(struct expr_constant, 2); + struct expr_constant c = + vector_get(&as_diff_added->values, 0, struct expr_constant); + vector_push(&new_fake_as->values, &c); /* Make a dummy ip that is different from the real one. */ - new_fake_as->values[1].value.u8_val++; - dummy_ip = new_fake_as->values[1].value.ipv6; + c.value.u8_val++; + dummy_ip = c.value.ipv6; + vector_push(&new_fake_as->values, &c); + has_dummy_ip = true; fake_as = new_fake_as; } @@ -528,13 +531,14 @@ consider_lflow_for_added_as_ips__( * the generated matches can't be mapped from the items in the * as_diff_added. So we need to fall back to reprocessing the lflow. */ - if (hmap_count(&matches) != as_ref_count * as_diff_added->n_values) { + size_t n_values = vector_len(&as_diff_added->values); + if (hmap_count(&matches) != as_ref_count * n_values) { VLOG_DBG("lflow "UUID_FMT", addrset %s: Generated flows count " "(%"PRIuSIZE") " "doesn't match added addresses count " "(%"PRIuSIZE") and ref_count (%"PRIuSIZE"). " "Need reprocessing.", UUID_ARGS(&lflow->header_.uuid), as_name, - hmap_count(&matches), as_diff_added->n_values, as_ref_count); + hmap_count(&matches), n_values, as_ref_count); handled = false; goto done; } @@ -610,19 +614,21 @@ as_update_can_be_handled(const char *as_name, struct addr_set_diff *as_diff, struct expr_constant_set *as = shash_find_data(l_ctx_in->addr_sets, as_name); ovs_assert(as); - size_t n_added = as_diff->added ? as_diff->added->n_values : 0; - size_t n_deleted = as_diff->deleted ? as_diff->deleted->n_values : 0; - size_t old_as_size = as->n_values + n_deleted - n_added; + size_t n_values = vector_len(&as->values); + size_t n_added = as_diff->added ? vector_len(&as_diff->added->values) : 0; + size_t n_deleted = + as_diff->deleted ? vector_len(&as_diff->deleted->values) : 0; + size_t old_as_size = n_values + n_deleted - n_added; /* If the change may impact n_conj, i.e. the template of the flows would * change, we must reprocess the lflow. */ - if (old_as_size <= 1 || as->n_values <= 1) { + if (old_as_size <= 1 || n_values <= 1) { return false; } /* If the size of the diff is too big, reprocessing may be more * efficient than incrementally processing the diffs. */ - if ((n_added + n_deleted) >= as->n_values) { + if ((n_added + n_deleted) >= n_values) { return false; } @@ -719,8 +725,8 @@ lflow_handle_addr_set_update(const char *as_name, if (as_diff->deleted) { struct addrset_info as_info; - for (size_t i = 0; i < as_diff->deleted->n_values; i++) { - struct expr_constant *c = &as_diff->deleted->values[i]; + const struct expr_constant *c; + VECTOR_FOR_EACH_PTR (&as_diff->deleted->values, c) { if (!as_info_from_expr_const(as_name, c, &as_info)) { continue; } diff --git a/include/ovn/expr.h b/include/ovn/expr.h index 9621a2c09..ae5ab1aab 100644 --- a/include/ovn/expr.h +++ b/include/ovn/expr.h @@ -537,8 +537,7 @@ void expr_constant_destroy(const struct expr_constant *, /* A collection of "union expr_constant"s of the same type. */ struct expr_constant_set { - struct expr_constant *values; /* Constants. */ - size_t n_values; /* Number of constants. */ + struct vector values; /* Constants. */ enum expr_constant_type type; /* Type of the constants. */ bool in_curlies; /* Whether the constants were in {}. */ }; diff --git a/lib/actions.c b/lib/actions.c index ba25fbc76..f0758752f 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -2109,7 +2109,7 @@ encode_event_empty_lb_backends_opts(struct ofpbuf *ofpacts, /* All empty_lb_backends fields are of type 'str' */ ovs_assert(!strcmp(o->option->type, "str")); - const struct expr_constant *c = o->value.values; + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); size_t size = strlen(c->string); struct controller_event_opt_header hdr = (struct controller_event_opt_header) { @@ -2585,11 +2585,11 @@ validate_empty_lb_backends(struct action_context *ctx, { for (size_t i = 0; i < n_options; i++) { const struct ovnact_gen_option *o = &options[i]; - const struct expr_constant *c = o->value.values; + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); struct sockaddr_storage ss; struct uuid uuid; - if (o->value.n_values > 1 || !c->string) { + if (vector_len(&o->value.values) > 1 || !c->string) { lexer_error(ctx->lexer, "Invalid value for \"%s\" option", o->option->name); return; @@ -2889,8 +2889,8 @@ encode_put_dhcpv4_option(const struct ovnact_gen_option *o, uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2); opt_header[0] = o->option->code; - const struct expr_constant *c = o->value.values; - size_t n_values = o->value.n_values; + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); + size_t n_values = vector_len(&o->value.values); if (!strcmp(o->option->type, "bool") || !strcmp(o->option->type, "uint8")) { opt_header[1] = 1; @@ -3055,8 +3055,8 @@ encode_put_dhcpv6_option(const struct ovnact_gen_option *o, struct ofpbuf *ofpacts) { struct dhcpv6_opt_header *opt = ofpbuf_put_uninit(ofpacts, sizeof *opt); - const struct expr_constant *c = o->value.values; - size_t n_values = o->value.n_values; + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); + size_t n_values = vector_len(&o->value.values); size_t size; opt->code = htons(o->option->code); @@ -3103,7 +3103,9 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo, * (skipping offerip the second time around). */ const struct ovnact_gen_option *offerip_opt = find_opt( pdo->options, pdo->n_options, 0); - ovs_be32 offerip = offerip_opt->value.values[0].value.ipv4; + const struct expr_constant *c = + vector_get_ptr(&offerip_opt->value.values, 0); + ovs_be32 offerip = c->value.ipv4; ofpbuf_put(ofpacts, &offerip, sizeof offerip); /* Encode bootfile_name opt (67) */ @@ -3111,7 +3113,7 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo, find_opt(pdo->options, pdo->n_options, DHCP_OPT_BOOTFILE_CODE); if (boot_opt) { uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2); - const struct expr_constant *c = boot_opt->value.values; + c = vector_get_ptr(&boot_opt->value.values, 0); opt_header[0] = boot_opt->option->code; opt_header[1] = strlen(c->string); ofpbuf_put(ofpacts, c->string, opt_header[1]); @@ -3121,7 +3123,7 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo, find_opt(pdo->options, pdo->n_options, DHCP_OPT_BOOTFILE_ALT_CODE); if (boot_alt_opt) { uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2); - const struct expr_constant *c = boot_alt_opt->value.values; + c = vector_get_ptr(&boot_alt_opt->value.values, 0); opt_header[0] = boot_alt_opt->option->code; opt_header[1] = strlen(c->string); ofpbuf_put(ofpacts, c->string, opt_header[1]); @@ -3131,7 +3133,7 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo, pdo->options, pdo->n_options, DHCP_OPT_NEXT_SERVER_CODE); if (next_server_opt) { uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2); - const struct expr_constant *c = next_server_opt->value.values; + c = vector_get_ptr(&next_server_opt->value.values, 0); opt_header[0] = next_server_opt->option->code; opt_header[1] = sizeof(ovs_be32); ofpbuf_put(ofpacts, &c->value.ipv4, sizeof(ovs_be32)); @@ -3344,8 +3346,8 @@ parse_put_nd_ra_opts(struct action_context *ctx, const struct expr_field *dst, /* Let's validate the options. */ for (size_t i = 0; i < po->n_options; i++) { const struct ovnact_gen_option *o = &po->options[i]; - const struct expr_constant *c = o->value.values; - if (o->value.n_values > 1) { + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); + if (vector_len(&o->value.values) > 1) { lexer_error(ctx->lexer, "Invalid value for \"%s\" option", o->option->name); return; @@ -3527,7 +3529,7 @@ static void encode_put_nd_ra_option(const struct ovnact_gen_option *o, struct ofpbuf *ofpacts, ptrdiff_t ra_offset) { - const struct expr_constant *c = o->value.values; + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); switch (o->option->code) { case ND_RA_FLAG_ADDR_MODE: diff --git a/lib/expr.c b/lib/expr.c index 937fecb75..e01cd028f 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -585,8 +585,9 @@ type_check(struct expr_context *ctx, const struct expr_field *f, } if (f->symbol->width) { - for (size_t i = 0; i < cs->n_values; i++) { - int w = expr_constant_width(&cs->values[i]); + const struct expr_constant *c; + VECTOR_FOR_EACH_PTR (&cs->values, c) { + int w = expr_constant_width(c); if (w > f->symbol->width) { lexer_error(ctx->lexer, "%d-bit constant is not compatible with %d-bit " @@ -624,12 +625,13 @@ make_cmp(struct expr_context *ctx, f->symbol->name); goto exit; } - if (!cs->n_values) { + if (!vector_len(&cs->values)) { lexer_error(ctx->lexer, "Only == and != operators may be used " "to compare a field against an empty value set."); goto exit; } - if (cs->values[0].masked) { + const struct expr_constant *c = vector_get_ptr(&cs->values, 0); + if (c->masked) { lexer_error(ctx->lexer, "Only == and != operators may be used " "with masked constants. Consider using subfields " "instead (e.g. eth.src[0..15] > 0x1111 in place of " @@ -641,9 +643,9 @@ make_cmp(struct expr_context *ctx, if (f->symbol->level == EXPR_L_NOMINAL) { if (f->symbol->predicate) { ovs_assert(f->symbol->width > 0); - for (size_t i = 0; i < cs->n_values; i++) { - const union mf_subvalue *value = &cs->values[i].value; - bool positive = (value->integer & htonll(1)) != 0; + const struct expr_constant *c; + VECTOR_FOR_EACH_PTR (&cs->values, c) { + bool positive = (c->value.integer & htonll(1)) != 0; positive ^= r == EXPR_R_NE; positive ^= ctx->not; if (!positive) { @@ -664,14 +666,15 @@ make_cmp(struct expr_context *ctx, } } - if (!cs->n_values) { + if (!vector_len(&cs->values)) { e = expr_create_boolean(r == EXPR_R_NE); goto exit; } - e = make_cmp__(f, r, &cs->values[0]); - for (size_t i = 1; i < cs->n_values; i++) { + e = make_cmp__(f, r, vector_get_ptr(&cs->values, 0)); + const struct expr_constant *values = vector_get_array(&cs->values); + for (size_t i = 1; i < vector_len(&cs->values); i++) { e = expr_combine(r == EXPR_R_EQ ? EXPR_T_OR : EXPR_T_AND, - e, make_cmp__(f, r, &cs->values[i])); + e, make_cmp__(f, r, &values[i])); } exit: @@ -767,7 +770,7 @@ assign_constant_set_type(struct expr_context *ctx, struct expr_constant_set *cs, enum expr_constant_type type) { - if (!cs->n_values || cs->type == type) { + if (!vector_len(&cs->values) || cs->type == type) { cs->type = type; return true; } else { @@ -778,8 +781,7 @@ assign_constant_set_type(struct expr_context *ctx, } static bool -parse_addr_sets(struct expr_context *ctx, struct expr_constant_set *cs, - size_t *allocated_values) +parse_addr_sets(struct expr_context *ctx, struct expr_constant_set *cs) { if (ctx->addr_sets_ref) { size_t *ref_count = shash_find_data(ctx->addr_sets_ref, @@ -806,23 +808,19 @@ parse_addr_sets(struct expr_context *ctx, struct expr_constant_set *cs, } struct expr_constant_set *addr_sets = node->data; - size_t n_values = cs->n_values + addr_sets->n_values; - if (n_values >= *allocated_values) { - cs->values = xrealloc(cs->values, n_values * sizeof *cs->values); - *allocated_values = n_values; - } - for (size_t i = 0; i < addr_sets->n_values; i++) { - struct expr_constant *c = &cs->values[cs->n_values++]; - *c = addr_sets->values[i]; - c->as_name = node->name; + vector_reserve(&cs->values, vector_len(&addr_sets->values)); + + struct expr_constant c; + VECTOR_FOR_EACH (&addr_sets->values, c) { + c.as_name = node->name; + vector_push(&cs->values, &c); } return true; } static bool -parse_port_group(struct expr_context *ctx, struct expr_constant_set *cs, - size_t *allocated_values) +parse_port_group(struct expr_context *ctx, struct expr_constant_set *cs) { struct ds sb_name = DS_EMPTY_INITIALIZER; @@ -847,29 +845,22 @@ parse_port_group(struct expr_context *ctx, struct expr_constant_set *cs, return false; } - size_t n_values = cs->n_values + port_group->n_values; - if (n_values >= *allocated_values) { - cs->values = xrealloc(cs->values, n_values * sizeof *cs->values); - *allocated_values = n_values; - } - for (size_t i = 0; i < port_group->n_values; i++) { - struct expr_constant *c = &cs->values[cs->n_values++]; - c->string = xstrdup(port_group->values[i].string); - c->as_name = NULL; + + vector_reserve(&cs->values, vector_len(&port_group->values)); + + struct expr_constant c; + VECTOR_FOR_EACH (&port_group->values, c) { + c.string = xstrdup(c.string); + c.as_name = NULL; + vector_push(&cs->values, &c); } return true; } static bool -parse_constant(struct expr_context *ctx, struct expr_constant_set *cs, - size_t *allocated_values) +parse_constant(struct expr_context *ctx, struct expr_constant_set *cs) { - if (cs->n_values >= *allocated_values) { - cs->values = x2nrealloc(cs->values, allocated_values, - sizeof *cs->values); - } - if (ctx->lexer->token.type == LEX_T_TEMPLATE) { lexer_error(ctx->lexer, "Unexpanded template."); return false; @@ -877,9 +868,11 @@ parse_constant(struct expr_context *ctx, struct expr_constant_set *cs, if (!assign_constant_set_type(ctx, cs, EXPR_C_STRING)) { return false; } - struct expr_constant *c = &cs->values[cs->n_values++]; - c->string = xstrdup(ctx->lexer->token.s); - c->as_name = NULL; + + struct expr_constant c = (struct expr_constant) { + .string = xstrdup(ctx->lexer->token.s), + }; + vector_push(&cs->values, &c); lexer_get(ctx->lexer); return true; } else if (ctx->lexer->token.type == LEX_T_INTEGER || @@ -888,24 +881,26 @@ parse_constant(struct expr_context *ctx, struct expr_constant_set *cs, return false; } - struct expr_constant *c = &cs->values[cs->n_values++]; - c->value = ctx->lexer->token.value; - c->format = ctx->lexer->token.format; - c->masked = ctx->lexer->token.type == LEX_T_MASKED_INTEGER; - if (c->masked) { - c->mask = ctx->lexer->token.mask; + bool masked = ctx->lexer->token.type == LEX_T_MASKED_INTEGER; + struct expr_constant c = (struct expr_constant) { + .value = ctx->lexer->token.value, + .format = ctx->lexer->token.format, + .masked = masked, + }; + if (masked) { + c.mask = ctx->lexer->token.mask; } - c->as_name = NULL; + vector_push(&cs->values, &c); lexer_get(ctx->lexer); return true; } else if (ctx->lexer->token.type == LEX_T_MACRO) { - if (!parse_addr_sets(ctx, cs, allocated_values)) { + if (!parse_addr_sets(ctx, cs)) { return false; } lexer_get(ctx->lexer); return true; } else if (ctx->lexer->token.type == LEX_T_PORT_GROUP) { - if (!parse_port_group(ctx, cs, allocated_values)) { + if (!parse_port_group(ctx, cs)) { return false; } lexer_get(ctx->lexer); @@ -923,22 +918,23 @@ parse_constant(struct expr_context *ctx, struct expr_constant_set *cs, static bool parse_constant_set(struct expr_context *ctx, struct expr_constant_set *cs) { - size_t allocated_values = 0; bool ok; - memset(cs, 0, sizeof *cs); + *cs = (struct expr_constant_set) { + .values = VECTOR_EMPTY_INITIALIZER(struct expr_constant), + }; if (lexer_match(ctx->lexer, LEX_T_LCURLY)) { ok = true; cs->in_curlies = true; do { - if (!parse_constant(ctx, cs, &allocated_values)) { + if (!parse_constant(ctx, cs)) { ok = false; break; } lexer_match(ctx->lexer, LEX_T_COMMA); } while (!lexer_match(ctx->lexer, LEX_T_RCURLY)); } else { - ok = parse_constant(ctx, cs, &allocated_values); + ok = parse_constant(ctx, cs); } if (!ok) { expr_constant_set_destroy(cs); @@ -964,13 +960,13 @@ expr_constant_parse(struct lexer *lexer, const struct expr_field *f, .lexer = lexer, }; - struct expr_constant_set cs; - memset(&cs, 0, sizeof cs); - size_t allocated_values = 0; - if (parse_constant(&ctx, &cs, &allocated_values) + struct expr_constant_set cs = (struct expr_constant_set) { + .values = VECTOR_EMPTY_INITIALIZER(struct expr_constant), + }; + if (parse_constant(&ctx, &cs) && type_check(&ctx, f, &cs)) { - *c = cs.values[0]; - cs.n_values = 0; + *c = vector_get(&cs.values, 0, struct expr_constant); + vector_clear(&cs.values); } expr_constant_set_destroy(&cs); @@ -1031,19 +1027,18 @@ expr_constant_set_parse(struct lexer *lexer, struct expr_constant_set *cs) void expr_constant_set_format(const struct expr_constant_set *cs, struct ds *s) { - bool curlies = cs->in_curlies || cs->n_values != 1; + bool curlies = cs->in_curlies || vector_len(&cs->values) != 1; if (curlies) { ds_put_char(s, '{'); } - for (const struct expr_constant *c = cs->values; - c < &cs->values[cs->n_values]; c++) { - if (c != cs->values) { - ds_put_cstr(s, ", "); - } - + const struct expr_constant *c; + VECTOR_FOR_EACH_PTR (&cs->values, c) { expr_constant_format(c, cs->type, s); + ds_put_cstr(s, ", "); } + ds_chomp(s, ' '); + ds_chomp(s, ','); if (curlies) { ds_put_char(s, '}'); @@ -1055,11 +1050,12 @@ expr_constant_set_destroy(struct expr_constant_set *cs) { if (cs) { if (cs->type == EXPR_C_STRING) { - for (size_t i = 0; i < cs->n_values; i++) { - free(cs->values[i].string); + const struct expr_constant *c; + VECTOR_FOR_EACH_PTR (&cs->values, c) { + free(c->string); } } - free(cs->values); + vector_destroy(&cs->values); } } @@ -1092,8 +1088,7 @@ expr_constant_set_create_integers(const char *const *values, size_t n_values) { struct expr_constant_set *cs = xzalloc(sizeof *cs); cs->in_curlies = true; - cs->n_values = 0; - cs->values = xmalloc(n_values * sizeof *cs->values); + cs->values = VECTOR_CAPACITY_INITIALIZER(struct expr_constant, n_values); cs->type = EXPR_C_INTEGER; for (size_t i = 0; i < n_values; i++) { /* Use the lexer to convert each constant set into the proper @@ -1106,40 +1101,41 @@ expr_constant_set_create_integers(const char *const *values, size_t n_values) VLOG_WARN("Invalid constant set entry: '%s', token type: %d", values[i], lex.token.type); } else { - struct expr_constant *c = &cs->values[cs->n_values++]; - c->value = lex.token.value; - c->format = lex.token.format; - c->masked = lex.token.type == LEX_T_MASKED_INTEGER; - if (c->masked) { - c->mask = lex.token.mask; + bool masked = lex.token.type == LEX_T_MASKED_INTEGER; + struct expr_constant c = (struct expr_constant) { + .value = lex.token.value, + .format = lex.token.format, + .masked = masked, + }; + if (masked) { + c.mask = lex.token.mask; } + vector_push(&cs->values, &c); } lexer_destroy(&lex); } /* Sort the result, so that it is efficient to generate diffs in the * function expr_constant_set_diff */ - qsort(cs->values, cs->n_values, sizeof *cs->values, - compare_expr_constant_integer_cb); + vector_qsort(&cs->values, compare_expr_constant_integer_cb); return cs; } static void expr_constant_set_add_value(struct expr_constant_set **p_cs, - struct expr_constant *c, size_t *allocated) + const struct expr_constant *c) { struct expr_constant_set *cs = *p_cs; if (!cs) { cs = xzalloc(sizeof *cs); + *cs = (struct expr_constant_set) { + .values = VECTOR_CAPACITY_INITIALIZER(struct expr_constant, 1), + }; *p_cs = cs; } - if (cs->n_values >= *allocated) { - cs->values = x2nrealloc(cs->values, allocated, - sizeof *cs->values); - } - cs->values[cs->n_values++] = *c; + vector_push(&cs->values, c); } /* Find the differences between old and new. Both old and new must be integer @@ -1159,33 +1155,33 @@ expr_constant_set_integers_diff(struct expr_constant_set *old, struct expr_constant_set *diff_added = NULL; struct expr_constant_set *diff_deleted = NULL; - size_t oi, ni, added_n_allocated, deleted_n_allocated; - added_n_allocated = deleted_n_allocated = 0; + size_t oi, ni; + + const struct expr_constant *old_c = vector_get_array(&old->values); + size_t old_n_values = vector_len(&old->values); - for (oi = ni = 0; oi < old->n_values && ni < new->n_values;) { - int d = compare_expr_constant_integer_cb(&old->values[oi], - &new->values[ni]); + const struct expr_constant *new_c = vector_get_array(&new->values); + size_t new_n_values = vector_len(&new->values); + + for (oi = ni = 0; oi < old_n_values && ni < new_n_values;) { + int d = compare_expr_constant_integer_cb(&old_c[oi], &new_c[ni]); if (d < 0) { - expr_constant_set_add_value(&diff_deleted, &old->values[oi], - &deleted_n_allocated); + expr_constant_set_add_value(&diff_deleted, &old_c[oi]); oi++; } else if (d > 0) { - expr_constant_set_add_value(&diff_added, &new->values[ni], - &added_n_allocated); + expr_constant_set_add_value(&diff_added, &new_c[ni]); ni++; } else { oi++; ni++; } } - for (; oi < old->n_values; oi++) { - expr_constant_set_add_value(&diff_deleted, &old->values[oi], - &deleted_n_allocated); + for (; oi < old_n_values; oi++) { + expr_constant_set_add_value(&diff_deleted, &old_c[oi]); } - for (; ni < new->n_values; ni++) { - expr_constant_set_add_value(&diff_added, &new->values[ni], - &added_n_allocated); + for (; ni < new_n_values; ni++) { + expr_constant_set_add_value(&diff_added, &new_c[ni]); } *p_diff_added = diff_added; @@ -1228,8 +1224,7 @@ expr_const_sets_add_strings(struct shash *const_sets, const char *name, { struct expr_constant_set *cs = xzalloc(sizeof *cs); cs->in_curlies = true; - cs->n_values = 0; - cs->values = xmalloc(n_values * sizeof *cs->values); + cs->values = VECTOR_CAPACITY_INITIALIZER(struct expr_constant, n_values); cs->type = EXPR_C_STRING; for (size_t i = 0; i < n_values; i++) { if (filter && !sset_find(filter, values[i])) { @@ -1238,8 +1233,10 @@ expr_const_sets_add_strings(struct shash *const_sets, const char *name, values[i], name); continue; } - struct expr_constant *c = &cs->values[cs->n_values++]; - c->string = xstrdup(values[i]); + struct expr_constant c = (struct expr_constant) { + .string = xstrdup(values[i]), + }; + vector_push(&cs->values, &c); } expr_const_sets_add(const_sets, name, cs); @@ -1351,14 +1348,15 @@ expr_parse_primary(struct expr_context *ctx, bool *atomic) *atomic = true; - struct expr_constant *cst = xzalloc(sizeof *cst); - cst->format = LEX_F_HEXADECIMAL; - cst->masked = false; + struct expr_constant cst = (struct expr_constant) { + .format = LEX_F_HEXADECIMAL, + .masked = false, + }; + c.values = VECTOR_CAPACITY_INITIALIZER(struct expr_constant, 1); c.type = EXPR_C_INTEGER; - c.values = cst; - c.n_values = 1; c.in_curlies = false; + vector_push(&c.values, &cst); return make_cmp(ctx, &f, EXPR_R_NE, &c); } else if (parse_relop(ctx, &r) && parse_constant_set(ctx, &c)) { return make_cmp(ctx, &f, r, &c); @@ -1371,13 +1369,14 @@ expr_parse_primary(struct expr_context *ctx, bool *atomic) return NULL; } + struct expr_constant *c = vector_get_ptr(&c1.values, 0); if (!expr_relop_from_token(ctx->lexer->token.type, NULL) - && c1.n_values == 1 + && vector_len(&c1.values) == 1 && c1.type == EXPR_C_INTEGER - && c1.values[0].format == LEX_F_DECIMAL - && !c1.values[0].masked + && c->format == LEX_F_DECIMAL + && !c->masked && !c1.in_curlies) { - uint64_t x = ntohll(c1.values[0].value.integer); + uint64_t x = ntohll(c->value.integer); if (x <= 1) { *atomic = true; expr_constant_set_destroy(&c1); -- 2.51.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
