On Mon, Apr 06, 2015 at 02:11:24PM -0700, Andy Zhou wrote: > I'm determined not to let the terrible style of pseudo-parsing we have in > OVS leak into OVN. Here's the first step. > > Signed-off-by: Ben Pfaff <b...@nicira.com> > > Looks good in general. A few minor comments in line: > Acked-by: Andy Zhou <az...@nicira.com>
Thanks. > > +static void > > +lex_token_format_masked_integer(const struct lex_token *token, struct ds > > *s) > > +{ > > + enum lex_format format = lex_token_get_format(token); > > + > > + lex_token_format_value(&token->value, format, s); > > + ds_put_char(s, '/'); > > + > > + const union mf_subvalue *mask = &token->mask; > > + if (format == LEX_F_IPV4 && ip_is_cidr(mask->ipv4)) { > > + ds_put_format(s, "%d", ip_count_cidr_bits(mask->ipv4)); > > + } else if (token->format == LEX_F_IPV6 && ipv6_is_cidr(&mask->ipv6)) { > > + ds_put_format(s, "%d", ipv6_count_cidr_bits(&mask->ipv6)); > > + } else { > > + lex_token_format_value(&token->mask, format, s); > > + } > > +} > > + > > + > There is an extra blank line above. Thanks, removed. > > +static const char * > > +lex_parse_integer(const char *p, struct lex_token *token) > > +{ > > + memset(&token->value, 0, sizeof token->value); > > + p = lex_parse_integer__(p, token); > > + if (token->type == LEX_T_INTEGER && *p == '/') { > > + struct lex_token mask; > > + > > + lex_token_init(&mask); > > + memset(&mask.value, 0, sizeof mask.value); > > + p = lex_parse_integer__(p + 1, &mask); > > + if (mask.type == LEX_T_INTEGER) { > > + token->type = LEX_T_MASKED_INTEGER; > > + > > + uint32_t prefix_bits = ntohll(mask.value.integer); > > + if (token->format == mask.format) { > > + /* Same format value and mask is always OK. */ > > + token->mask = mask.value; > > + } else if (token->format == LEX_F_IPV4 > > + && mask.format == LEX_F_DECIMAL > > + && prefix_bits <= 32) { > > + /* IPv4 address with decimal mask is a CIDR prefix. */ > > + token->mask.integer = htonll(ntohl(be32_prefix_mask( > > + prefix_bits))); > > + } else if (token->format == LEX_F_IPV6 > > + && mask.format == LEX_F_DECIMAL > > + && prefix_bits <= 128) { > > + /* IPv6 address with decimal mask is a CIDR prefix. */ > > + token->mask.ipv6 = ipv6_create_mask(prefix_bits); > > + } else if (token->format == LEX_F_DECIMAL > > + && mask.format == LEX_F_HEXADECIMAL > > + && token->value.integer == 0) { > > + /* Special case for e.g. 0/0x1234. */ > > + token->format = LEX_F_HEXADECIMAL; > > + token->mask = mask.value; > > + } else { > > + lex_error(token, "Value and mask have incompatible > > formats."); > > + return p; > > + } > > + > > + for (int i = 0; i < ARRAY_SIZE(token->mask.be32); i++) { > > + ovs_be32 v = token->value.be32[i]; > > + ovs_be32 m = token->mask.be32[i]; > > + > > + if (v & ~m) { > > + lex_error(token, "Value contains unmasked 1-bits."); > > + break; > > + } > > + } > > + > > + return p; > > + } else { > > + lex_token_swap(&mask, token); > > Which case was this 'else' for? It would be nice to add a comment here. Thanks, I added a comment and assertino: @@ -392,6 +391,10 @@ lex_parse_integer(const char *p, struct lex_token *token) return p; } else { + /* 'mask' isn't an integer so it must be an error message. Swap + * the integer for the error message so that we return the error + * message (and destroy the pre-mask token just below). */ + ovs_assert(token->type == LEX_T_ERROR); lex_token_swap(&mask, token); } lex_token_destroy(&mask); > > + } > > + lex_token_destroy(&mask); > > + } > > + return p; > > +} > > + > > +static const char * > > +lex_parse_string(const char *p, struct lex_token *token) > > +{ > > + const char *start = ++p; > > + for (;;) { > > + switch (*p) { > > + case '\0': > > + lex_error(token, "Input ends inside quoted string."); > > + return p; > > + > > + case '"': > > + token->type = (json_string_unescape(start, p - start, > > &token->s) > > + ? LEX_T_STRING : LEX_T_ERROR); > > + return p + 1; > > + > > + case '\\': > > + p++; > > + if (*p) { > > + p++; > > + } > > + break; > > + > > + default: > > + p++; > > + break; > > + } > > + } > > + > extra line above or intentional? > > +} Extra. Removed, thanks. > > +/* Initializes 'token' and parses the first token from the beginning of > > + * null-terminated string 'p' into 'token'. Stores a pointer to the start > > of > > + * the token (after skipping white space and comments, if any) into > > '*startp'. > > + * Returns the character position at which to begin parsing the next > > token. */ > > +const char * > > +lex_token_parse(struct lex_token *token, const char *p, const char > > **startp) > > +{ > > + lex_token_init(token); > > + > > +next: > > + *startp = p; > > + switch (*p) { > > + case '\0': > > + token->type = LEX_T_END; > > + return p; > > + > > + case ' ': case '\t': case '\n': case '\r': > > + p++; > > + goto next; > > + > > + case '/': > > + p++; > > + if (*p == '/') { > > + do { > > + p++; > > + } while (*p != '\0' && *p != '\n'); > > + goto next; > > + } else if (*p == '*') { > > + p++; > > + for (;;) { > > + if (*p == '*' && p[1] == '/') { > > + p += 2; > > + goto next; > > + } else if (*p == '\0' || *p == '\n') { > > + lex_error(token, "`/*' without matching `*/'."); > > + return p; > It seems "/* and */" can not be used for multi line comment. May be > worth a comment to point this out. True. (I wanted it to be possible to tokenize a line at a time without dependencies between lines.) I added some documentation: diff --git a/ovn/ovn.xml b/ovn/ovn.xml index 0906272..62e93ed 100644 --- a/ovn/ovn.xml +++ b/ovn/ovn.xml @@ -375,6 +375,13 @@ </p> <p> + <em>Comments</em> may be introduced by <code>//</code>, which extends + to the next new-line. Comments within a line may be bracketed by + <code>/*</code> and <code>*/</code>. Multiline comments are not + supported. + </p> + + <p> (The above is pretty ambitious. It probably makes sense to initially implement only a subset of this specification. The full specification is written out mainly to get an idea of what a fully general matching It sounds like Russell or Justin would like to review this series also, so for now I'll just update my "ovn" branch in my github "reviews" repository. _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev