1 | /* ----------------------------------------------------------------------- * |
2 | * |
3 | * Copyright 2017 The NASM Authors - All Rights Reserved |
4 | * See the file AUTHORS included with the NASM distribution for |
5 | * the specific copyright holders. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following |
9 | * conditions are met: |
10 | * |
11 | * * Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * * Redistributions in binary form must reproduce the above |
14 | * copyright notice, this list of conditions and the following |
15 | * disclaimer in the documentation and/or other materials provided |
16 | * with the distribution. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
19 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
30 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | * |
32 | * ----------------------------------------------------------------------- */ |
33 | |
34 | /* |
35 | * Common string table handling |
36 | * |
37 | * A number of output formats use a "string table"; a container for |
38 | * a number of strings which may be reused at will. This implements |
39 | * a string table which eliminates duplicates and returns the index |
40 | * into the string table when queried. |
41 | */ |
42 | |
43 | #include "compiler.h" |
44 | |
45 | #include "nasm.h" |
46 | #include "nasmlib.h" |
47 | #include "error.h" |
48 | #include "strtbl.h" |
49 | |
50 | struct strtbl_entry { |
51 | size_t index; |
52 | size_t bytes; |
53 | char str[1]; |
54 | }; |
55 | |
56 | void strtbl_init(struct nasm_strtbl *tbl) |
57 | { |
58 | tbl->size = 0; |
59 | hash_init(&tbl->hash, HASH_LARGE); |
60 | strtbl_add(tbl, "" ); /* Index 0 is always an empty string */ |
61 | } |
62 | |
63 | void strtbl_free(struct nasm_strtbl *tbl) |
64 | { |
65 | hash_free_all(&tbl->hash, false); |
66 | } |
67 | |
68 | size_t strtbl_add(struct nasm_strtbl *tbl, const char *str) |
69 | { |
70 | void **sep; |
71 | struct strtbl_entry *se; |
72 | struct hash_insert hi; |
73 | |
74 | sep = hash_find(&tbl->hash, str, &hi); |
75 | if (sep) { |
76 | se = *sep; |
77 | } else { |
78 | size_t bytes = strlen(str) + 1; |
79 | |
80 | se = nasm_malloc(sizeof(struct strtbl_entry)-1+bytes); |
81 | se->index = tbl->size; |
82 | tbl->size += bytes; |
83 | se->bytes = bytes; |
84 | memcpy(se->str, str, bytes); |
85 | |
86 | hash_add(&hi, se->str, se); |
87 | } |
88 | |
89 | return se->index; |
90 | } |
91 | |
92 | size_t strtbl_find(struct nasm_strtbl *tbl, const char *str) |
93 | { |
94 | void **sep; |
95 | struct strtbl_entry *se; |
96 | |
97 | sep = hash_find(&tbl->hash, str, NULL); |
98 | if (sep) { |
99 | se = *sep; |
100 | return se->index; |
101 | } else { |
102 | return STRTBL_NONE; |
103 | } |
104 | } |
105 | |
106 | /* This create a linearized buffer containing the actual string table */ |
107 | void *strtbl_generate(const struct nasm_strtbl *tbl) |
108 | { |
109 | char *buf = nasm_malloc(strtbl_size(tbl)); |
110 | struct hash_tbl_node *iter = NULL; |
111 | struct strtbl_entry *se; |
112 | |
113 | while ((se = hash_iterate(&tbl->hash, &iter, NULL))) |
114 | memcpy(buf + se->index, se->str, se->bytes); |
115 | |
116 | return buf; |
117 | } |
118 | |