Coverage Report

Created: 2023-03-26 07:42

/src/openvswitch/lib/namemap.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2017-2018 Nicira, Inc.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at:
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#include <config.h>
18
#include "openvswitch/namemap.h"
19
#include <ctype.h>
20
#include "hash.h"
21
#include "openvswitch/dynamic-string.h"
22
#include "openvswitch/json.h"
23
24
void
25
namemap_init(struct namemap *map)
26
0
{
27
0
    hmap_init(&map->by_name);
28
0
    hmap_init(&map->by_number);
29
0
}
30
31
struct namemap_node *
32
namemap_find_by_name(const struct namemap *map, const char *name)
33
0
{
34
0
    struct namemap_node *node;
35
36
0
    HMAP_FOR_EACH_WITH_HASH (node, name_node, hash_string(name, 0),
37
0
                             &map->by_name) {
38
0
        if (!strcmp(name, node->name)) {
39
0
            return node;
40
0
        }
41
0
    }
42
0
    return NULL;
43
0
}
44
45
struct namemap_node *
46
namemap_find_by_number(const struct namemap *map, uint32_t number)
47
0
{
48
0
    struct namemap_node *node;
49
50
0
    HMAP_FOR_EACH_IN_BUCKET (node, number_node, hash_int(number, 0),
51
0
                             &map->by_number) {
52
0
        if (node->number == number) {
53
0
            return node;
54
0
        }
55
0
    }
56
0
    return NULL;
57
0
}
58
59
void
60
namemap_put(struct namemap *map, uint32_t number, const char *name)
61
0
{
62
0
    struct namemap_node *node;
63
64
    /* Look for duplicate name. */
65
0
    node = namemap_find_by_name(map, name);
66
0
    if (node) {
67
0
        if (node->number != number) {
68
0
            node->duplicate = true;
69
0
        }
70
0
        return;
71
0
    }
72
73
    /* Look for duplicate number. */
74
0
    node = namemap_find_by_number(map, number);
75
0
    if (node) {
76
0
        node->duplicate = true;
77
0
        return;
78
0
    }
79
80
    /* Add new node. */
81
0
    node = xmalloc(sizeof *node);
82
0
    hmap_insert(&map->by_number, &node->number_node, hash_int(number, 0));
83
0
    hmap_insert(&map->by_name, &node->name_node, hash_string(name, 0));
84
0
    node->number = number;
85
0
    node->name = xstrdup(name);
86
0
    node->duplicate = false;
87
0
}
88
89
void
90
namemap_destroy(struct namemap *map)
91
0
{
92
0
    if (map) {
93
0
        struct namemap_node *node;
94
95
0
        HMAP_FOR_EACH_SAFE (node, name_node, &map->by_name) {
96
0
            hmap_remove(&map->by_name, &node->name_node);
97
0
            hmap_remove(&map->by_number, &node->number_node);
98
0
            free(node->name);
99
0
            free(node);
100
0
        }
101
0
        hmap_destroy(&map->by_name);
102
0
        hmap_destroy(&map->by_number);
103
0
    }
104
0
}
105
106
/* A table or port name doesn't need to be quoted if it is alphanumeric and
107
 * starts with a letter. */
108
static bool
109
name_needs_quotes(const char *name)
110
0
{
111
0
    if (!isalpha((unsigned char) name[0])) {
112
0
        return true;
113
0
    }
114
115
0
    for (const char *p = name + 1; *p; p++) {
116
0
        if (!isalnum((unsigned char) *p)) {
117
0
            return true;
118
0
        }
119
0
    }
120
0
    return false;
121
0
}
122
123
/* Appends port or table 'name' to 's', quoting it if necessary. */
124
void
125
namemap_put_name(const char *name, struct ds *s)
126
0
{
127
0
    if (name_needs_quotes(name)) {
128
0
        json_string_escape(name, s);
129
0
    } else {
130
0
        ds_put_cstr(s, name);
131
0
    }
132
0
}