1 /* Unit test for ldconfig string tables.
2 Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <https://www.gnu.org/licenses/>. */
18 #include <array_length.h>
21 #include <stringtable.h>
22 #include <support/check.h>
23 #include <support/support.h>
28 /* Empty string table. */
30 struct stringtable s
= { 0, };
31 struct stringtable_finalized f
;
32 stringtable_finalize (&s
, &f
);
33 TEST_COMPARE_STRING (f
.strings
, "");
34 TEST_COMPARE (f
.size
, 0);
36 stringtable_free (&s
);
39 /* String table with one empty string. */
41 struct stringtable s
= { 0, };
42 struct stringtable_entry
*e
= stringtable_add (&s
, "");
43 TEST_COMPARE_STRING (e
->string
, "");
44 TEST_COMPARE (e
->length
, 0);
45 TEST_COMPARE (s
.count
, 1);
47 struct stringtable_finalized f
;
48 stringtable_finalize (&s
, &f
);
49 TEST_COMPARE (e
->offset
, 0);
50 TEST_COMPARE_STRING (f
.strings
, "");
51 TEST_COMPARE (f
.size
, 1);
53 stringtable_free (&s
);
56 /* String table with one non-empty string. */
58 struct stringtable s
= { 0, };
59 struct stringtable_entry
*e
= stringtable_add (&s
, "name");
60 TEST_COMPARE_STRING (e
->string
, "name");
61 TEST_COMPARE (e
->length
, 4);
62 TEST_COMPARE (s
.count
, 1);
64 struct stringtable_finalized f
;
65 stringtable_finalize (&s
, &f
);
66 TEST_COMPARE (e
->offset
, 0);
67 TEST_COMPARE_STRING (f
.strings
, "name");
68 TEST_COMPARE (f
.size
, 5);
70 stringtable_free (&s
);
73 /* Two strings, one is a prefix of the other. Tail-merging can only
74 happen in one way in this case. */
76 struct stringtable s
= { 0, };
77 struct stringtable_entry
*suffix
= stringtable_add (&s
, "suffix");
78 TEST_COMPARE_STRING (suffix
->string
, "suffix");
79 TEST_COMPARE (suffix
->length
, 6);
80 TEST_COMPARE (s
.count
, 1);
82 struct stringtable_entry
*prefix
83 = stringtable_add (&s
, "prefix-suffix");
84 TEST_COMPARE_STRING (prefix
->string
, "prefix-suffix");
85 TEST_COMPARE (prefix
->length
, strlen ("prefix-suffix"));
86 TEST_COMPARE (s
.count
, 2);
88 struct stringtable_finalized f
;
89 stringtable_finalize (&s
, &f
);
90 TEST_COMPARE (prefix
->offset
, 0);
91 TEST_COMPARE (suffix
->offset
, strlen ("prefix-"));
92 TEST_COMPARE_STRING (f
.strings
, "prefix-suffix");
93 TEST_COMPARE (f
.size
, sizeof ("prefix-suffix"));
95 stringtable_free (&s
);
98 /* String table with various shared prefixes. Triggers hash
101 enum { count
= 1500 };
102 char *strings
[2 * count
];
103 struct stringtable_entry
*entries
[2 * count
];
104 struct stringtable s
= { 0, };
105 for (int i
= 0; i
< count
; ++i
)
107 strings
[i
] = xasprintf ("%d", i
);
108 entries
[i
] = stringtable_add (&s
, strings
[i
]);
109 TEST_COMPARE (entries
[i
]->length
, strlen (strings
[i
]));
110 TEST_COMPARE_STRING (entries
[i
]->string
, strings
[i
]);
111 strings
[i
+ count
] = xasprintf ("prefix/%d", i
);
112 entries
[i
+ count
] = stringtable_add (&s
, strings
[i
+ count
]);
113 TEST_COMPARE (entries
[i
+ count
]->length
, strlen (strings
[i
+ count
]));
114 TEST_COMPARE_STRING (entries
[i
+ count
]->string
, strings
[i
+ count
]);
117 struct stringtable_finalized f
;
118 stringtable_finalize (&s
, &f
);
120 for (int i
= 0; i
< 2 * count
; ++i
)
122 TEST_COMPARE (entries
[i
]->length
, strlen (strings
[i
]));
123 TEST_COMPARE_STRING (entries
[i
]->string
, strings
[i
]);
124 TEST_COMPARE_STRING (f
.strings
+ entries
[i
]->offset
, strings
[i
]);
129 stringtable_free (&s
);
132 /* Verify that maximum tail merging happens. */
134 struct stringtable s
= { 0, };
135 const char *strings
[] = {
148 struct stringtable_entry
*entries
[array_length (strings
)];
149 for (int i
= 0; i
< array_length (strings
); ++i
)
150 entries
[i
] = stringtable_add (&s
, strings
[i
]);
151 for (int i
= 0; i
< array_length (strings
); ++i
)
152 TEST_COMPARE_STRING (entries
[i
]->string
, strings
[i
]);
154 struct stringtable_finalized f
;
155 stringtable_finalize (&s
, &f
);
157 /* There are only four different strings, "aaa", "ba", "baa",
158 "bb". The rest is shared in an unspecified fashion. */
159 TEST_COMPARE (f
.size
, 4 + 3 + 4 + 3);
161 for (int i
= 0; i
< array_length (strings
); ++i
)
163 TEST_COMPARE_STRING (entries
[i
]->string
, strings
[i
]);
164 TEST_COMPARE_STRING (f
.strings
+ entries
[i
]->offset
, strings
[i
]);
168 stringtable_free (&s
);
174 #include <support/test-driver.c>
176 /* Re-compile the string table implementation here. It is not
177 possible to link against the actual build because it was built for
180 #include "stringtable.c"
181 #include "stringtable_free.c"