Esempio n. 1
0
File: lex.c Progetto: l8huang/ovs
static const char *
lex_parse_mask(const char *p, struct lex_token *token)
{
    struct lex_token mask;

    /* Parse just past the '/' as a second integer.  Handle errors. */
    p = lex_parse_integer__(p + 1, &mask);
    if (mask.type == LEX_T_ERROR) {
        lex_token_swap(&mask, token);
        lex_token_destroy(&mask);
        return p;
    }
    ovs_assert(mask.type == LEX_T_INTEGER);

    /* Now convert the value and mask into a masked integer token.
     * We have a few special cases. */
    token->type = LEX_T_MASKED_INTEGER;
    memset(&token->mask, 0, sizeof token->mask);
    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;
    }

    /* Check invariant that a 1-bit in the value corresponds to a 1-bit in the
     * mask. */
    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;
        }
    }

    /* Done! */
    lex_token_destroy(&mask);
    return p;
}
Esempio n. 2
0
File: lex.c Progetto: l8huang/ovs
/* Obtains the next token from 'lexer' into 'lexer->token', and returns the
 * token's type.  The caller may examine 'lexer->token' directly to obtain full
 * information about the token. */
enum lex_type
lexer_get(struct lexer *lexer)
{
    lex_token_destroy(&lexer->token);
    lexer->input = lex_token_parse(&lexer->token, lexer->input, &lexer->start);
    return lexer->token.type;
}
Esempio n. 3
0
File: lex.c Progetto: ALutzG/ovs
/* The string 's' need not be null-terminated at 'length'. */
void
lex_token_strcpy(struct lex_token *token, const char *s, size_t length)
{
    lex_token_destroy(token);
    token->s = (length + 1 <= sizeof token->buffer
                ? token->buffer
                : xmalloc(length + 1));
    memcpy(token->s, s, length);
    token->buffer[length] = '\0';
}
Esempio n. 4
0
File: lex.c Progetto: l8huang/ovs
/* Returns the type of the next token that will be fetched by lexer_get(),
 * without advancing 'lexer->token' to that token. */
enum lex_type
lexer_lookahead(const struct lexer *lexer)
{
    struct lex_token next;
    enum lex_type type;
    const char *start;

    lex_token_parse(&next, lexer->input, &start);
    type = next.type;
    lex_token_destroy(&next);
    return type;
}
Esempio n. 5
0
File: lex.c Progetto: ALutzG/ovs
void
lex_token_vsprintf(struct lex_token *token, const char *format, va_list args)
{
    lex_token_destroy(token);

    va_list args2;
    va_copy(args2, args);
    token->s = (vsnprintf(token->buffer, sizeof token->buffer, format, args)
                < sizeof token->buffer
                ? token->buffer
                : xvasprintf(format, args2));
    va_end(args2);
}
Esempio n. 6
0
File: lex.c Progetto: l8huang/ovs
/* Frees storage associated with 'lexer'. */
void
lexer_destroy(struct lexer *lexer)
{
    lex_token_destroy(&lexer->token);
}
Esempio n. 7
0
File: lex.c Progetto: ALutzG/ovs
void
lex_token_strset(struct lex_token *token, char *s)
{
    lex_token_destroy(token);
    token->s = s;
}