Skip to content

Commit

Permalink
parser should handle quantifiers and predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
blp committed Aug 23, 2016
1 parent 1d320f8 commit ecc3efc
Show file tree
Hide file tree
Showing 10 changed files with 393 additions and 79 deletions.
5 changes: 3 additions & 2 deletions include/ovn/lex.h
Expand Up @@ -55,6 +55,7 @@ enum lex_type {
LEX_T_LOG_NOT, /* ! */
LEX_T_LOG_AND, /* && */
LEX_T_LOG_OR, /* || */
LEX_T_DOT, /* . */
LEX_T_ELLIPSIS, /* .. */
LEX_T_COMMA, /* , */
LEX_T_SEMICOLON, /* ; */
Expand Down Expand Up @@ -142,8 +143,8 @@ bool lexer_match_id(struct lexer *, const char *id);
bool lexer_force_id(struct lexer *);
bool lexer_force_match_id(struct lexer *, const char *id);
bool lexer_is_int(const struct lexer *);
bool lexer_get_int(struct lexer *, int *value);
bool lexer_force_int(struct lexer *, int *value);
bool lexer_get_int(struct lexer *, int64_t *value);
bool lexer_force_int(struct lexer *, int64_t *value);

void lexer_force_end(struct lexer *);

Expand Down
33 changes: 23 additions & 10 deletions lib/ovsdb-data.c
@@ -1,4 +1,4 @@
/* Copyright (c) 2009, 2010, 2011, 2012, 2014 Nicira, Inc.
/* Copyright (c) 2009, 2010, 2011, 2012, 2014, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -955,14 +955,27 @@ ovsdb_datum_clone(struct ovsdb_datum *new, const struct ovsdb_datum *old,
new->values = clone_atoms(old->values, type->value.type, n);
}

static void
free_data(enum ovsdb_atomic_type type,
union ovsdb_atom *atoms, size_t n_atoms)
/* Frees the contents of 'atom', which must have the specified 'type'.
*
* This does not actually call free(atom). If necessary, the caller must be
* responsible for that. */
void
ovsdb_atom_destroy(union ovsdb_atom *atom, enum ovsdb_atomic_type type)
{
if (ovsdb_atom_needs_destruction(type)) {
unsigned int i;
for (i = 0; i < n_atoms; i++) {
ovsdb_atom_destroy(&atoms[i], type);
if (type == OVSDB_TYPE_STRING) {
free(atom->string);
}
}

/* Frees each of the 'n' atoms in the array starting at 'atoms', each of which
* must have the specified 'type', then calls free(atoms);. */
void
ovsdb_atom_array_destroy(union ovsdb_atom *atoms, size_t n,
enum ovsdb_atomic_type type)
{
if (type == OVSDB_TYPE_STRING) {
for (size_t i = 0; i < n; i++) {
free(atoms[i].string);
}
}
free(atoms);
Expand All @@ -975,8 +988,8 @@ free_data(enum ovsdb_atomic_type type,
void
ovsdb_datum_destroy(struct ovsdb_datum *datum, const struct ovsdb_type *type)
{
free_data(type->key.type, datum->keys, datum->n);
free_data(type->value.type, datum->values, datum->n);
ovsdb_atom_array_destroy(datum->keys, datum->n, type->key.type);
ovsdb_atom_array_destroy(datum->values, datum->n, type->value.type);
}

/* Swaps the contents of 'a' and 'b', which need not have the same type. */
Expand Down
28 changes: 4 additions & 24 deletions lib/ovsdb-data.h
@@ -1,4 +1,4 @@
/* Copyright (c) 2009, 2010, 2011, 2012, 2015 Nicira, Inc.
/* Copyright (c) 2009, 2010, 2011, 2012, 2015, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -41,29 +41,9 @@ void ovsdb_atom_clone(union ovsdb_atom *, const union ovsdb_atom *,
enum ovsdb_atomic_type);
void ovsdb_atom_swap(union ovsdb_atom *, union ovsdb_atom *);

/* Returns false if ovsdb_atom_destroy() is a no-op when it is applied to an
* initialized atom of the given 'type', true if ovsdb_atom_destroy() actually
* does something.
*
* This can be used to avoid calling ovsdb_atom_destroy() for each element in
* an array of homogeneous atoms. (It's not worthwhile for a single atom.) */
static inline bool
ovsdb_atom_needs_destruction(enum ovsdb_atomic_type type)
{
return type == OVSDB_TYPE_STRING;
}

/* Frees the contents of 'atom', which must have the specified 'type'.
*
* This does not actually call free(atom). If necessary, the caller must be
* responsible for that. */
static inline void
ovsdb_atom_destroy(union ovsdb_atom *atom, enum ovsdb_atomic_type type)
{
if (type == OVSDB_TYPE_STRING) {
free(atom->string);
}
}
void ovsdb_atom_destroy(union ovsdb_atom *, enum ovsdb_atomic_type);
void ovsdb_atom_array_destroy(union ovsdb_atom *, size_t n,
enum ovsdb_atomic_type);

uint32_t ovsdb_atom_hash(const union ovsdb_atom *, enum ovsdb_atomic_type,
uint32_t basis);
Expand Down
7 changes: 7 additions & 0 deletions lib/ovsdb-idl.h
Expand Up @@ -76,6 +76,13 @@ int ovsdb_idl_get_last_error(const struct ovsdb_idl *);

void ovsdb_idl_set_probe_interval(const struct ovsdb_idl *, int probe_interval);

/* Examining a database. */

const struct ovsdb_idl_table *ovsdb_idl_lookup_table(
const struct ovsdb_idl *, const char *table_name);
const struct ovsdb_idl_column *ovsdb_idl_table_lookup_column(
const struct ovsdb_idl_table *, const char *column_name);

/* Choosing columns and tables to replicate. */

/* Modes with which the IDL can monitor a column.
Expand Down
4 changes: 2 additions & 2 deletions ovn/lib/actions.c
Expand Up @@ -203,7 +203,7 @@ static bool
action_parse_port(struct action_context *ctx, uint16_t *port)
{
if (lexer_is_int(ctx->lexer)) {
int value = ntohll(ctx->lexer->token.value.integer);
int64_t value = ntohll(ctx->lexer->token.value.integer);
if (value <= UINT16_MAX) {
*port = value;
lexer_get(ctx->lexer);
Expand Down Expand Up @@ -260,7 +260,7 @@ parse_NEXT(struct action_context *ctx)
if (!ctx->pp->n_tables) {
lexer_error(ctx->lexer, "\"next\" action not allowed here.");
} else if (lexer_match(ctx->lexer, LEX_T_LPAREN)) {
int ltable;
int64_t ltable;

if (!lexer_force_int(ctx->lexer, &ltable) ||
!lexer_force_match(ctx->lexer, LEX_T_RPAREN)) {
Expand Down
9 changes: 6 additions & 3 deletions ovn/lib/expr.c
Expand Up @@ -610,7 +610,7 @@ parse_field(struct expr_context *ctx, struct expr_field *f)

f->symbol = symbol;
if (lexer_match(ctx->lexer, LEX_T_LSQUARE)) {
int low, high;
int64_t low, high;

if (!symbol->width) {
lexer_error(ctx->lexer,
Expand All @@ -635,11 +635,14 @@ parse_field(struct expr_context *ctx, struct expr_field *f)
}

if (low > high) {
lexer_error(ctx->lexer, "Invalid bit range %d to %d.", low, high);
lexer_error(ctx->lexer,
"Invalid bit range %"PRId64" to %"PRId64".",
low, high);
return false;
} else if (high >= symbol->width) {
lexer_error(ctx->lexer,
"Cannot select bits %d to %d of %d-bit field %s.",
"Cannot select bits %"PRId64" to %"PRId64" "
"of %d-bit field %s.",
low, high, symbol->width, symbol->name);
return false;
} else if (symbol->level == EXPR_L_NOMINAL
Expand Down
12 changes: 7 additions & 5 deletions ovn/lib/lex.c
Expand Up @@ -276,6 +276,9 @@ lex_token_format(const struct lex_token *token, struct ds *s)
case LEX_T_LOG_OR:
ds_put_cstr(s, "||");
break;
case LEX_T_DOT:
ds_put_char(s, '.');
break;
case LEX_T_ELLIPSIS:
ds_put_cstr(s, "..");
break;
Expand Down Expand Up @@ -723,7 +726,7 @@ lex_token_parse(struct lex_token *token, const char *p,
token->type = LEX_T_ELLIPSIS;
p++;
} else {
lex_error(token, "`.' is only valid as part of `..' or a number.");
token->type = LEX_T_DOT;
}
break;

Expand Down Expand Up @@ -898,12 +901,11 @@ bool
lexer_is_int(const struct lexer *lexer)
{
return (lexer->token.type == LEX_T_INTEGER
&& lexer->token.format == LEX_F_DECIMAL
&& ntohll(lexer->token.value.integer) <= INT_MAX);
&& lexer->token.format == LEX_F_DECIMAL);
}

bool
lexer_get_int(struct lexer *lexer, int *value)
lexer_get_int(struct lexer *lexer, int64_t *value)
{
if (lexer_is_int(lexer)) {
*value = ntohll(lexer->token.value.integer);
Expand All @@ -916,7 +918,7 @@ lexer_get_int(struct lexer *lexer, int *value)
}

bool
lexer_force_int(struct lexer *lexer, int *value)
lexer_force_int(struct lexer *lexer, int64_t *value)
{
bool ok = lexer_get_int(lexer, value);
if (!ok) {
Expand Down
5 changes: 4 additions & 1 deletion ovn/northd/automake.mk
@@ -1,6 +1,9 @@
# ovn-northd
bin_PROGRAMS += ovn/northd/ovn-northd
ovn_northd_ovn_northd_SOURCES = ovn/northd/ovn-northd.c
ovn_northd_ovn_northd_SOURCES = \
ovn/northd/flow-template.c \
ovn/northd/flow-template.h \
ovn/northd/ovn-northd.c
ovn_northd_ovn_northd_LDADD = \
ovn/lib/libovn.la \
ovsdb/libovsdb.la \
Expand Down

0 comments on commit ecc3efc

Please sign in to comment.