]> granicus.if.org Git - strace/blob - dyxlat.c
0568f3187f3681d39ebd60e62c8f895354673d40
[strace] / dyxlat.c
1 /*
2  * Copyright (c) 2017 The strace developers.
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  */
6
7 #include "defs.h"
8
9 struct dyxlat {
10         size_t used;
11         size_t allocated;
12         struct xlat *xlat;
13 };
14
15 #define MARK_END(xlat)                          \
16         do {                                    \
17                 (xlat).val = 0;                 \
18                 (xlat).str = 0;                 \
19         } while (0)
20
21 struct dyxlat *
22 dyxlat_alloc(const size_t nmemb)
23 {
24         struct dyxlat *const dyxlat = xmalloc(sizeof(*dyxlat));
25
26         dyxlat->used = 1;
27         dyxlat->allocated = nmemb;
28         dyxlat->xlat = xgrowarray(NULL, &dyxlat->allocated, sizeof(struct xlat));
29         MARK_END(dyxlat->xlat[0]);
30
31         return dyxlat;
32 }
33
34 void
35 dyxlat_free(struct dyxlat *const dyxlat)
36 {
37         size_t i;
38
39         for (i = 0; i < dyxlat->used - 1; ++i) {
40                 free((void *) dyxlat->xlat[i].str);
41                 dyxlat->xlat[i].str = NULL;
42         }
43
44         free(dyxlat->xlat);
45         dyxlat->xlat = NULL;
46         free(dyxlat);
47 }
48
49 const struct xlat *
50 dyxlat_get(const struct dyxlat *const dyxlat)
51 {
52         return dyxlat->xlat;
53 }
54
55 void
56 dyxlat_add_pair(struct dyxlat *const dyxlat, const uint64_t val,
57                 const char *const str, const size_t len)
58 {
59         size_t i;
60
61         for (i = 0; i < dyxlat->used - 1; ++i) {
62                 if (dyxlat->xlat[i].val == val) {
63                         if (strncmp(dyxlat->xlat[i].str, str, len) == 0
64                             && dyxlat->xlat[i].str[len] == '\0')
65                                 return;
66
67                         free((void *) dyxlat->xlat[i].str);
68                         dyxlat->xlat[i].str = xstrndup(str, len);
69                         return;
70                 }
71         }
72
73         if (dyxlat->used >= dyxlat->allocated)
74                 dyxlat->xlat = xgrowarray(dyxlat->xlat, &dyxlat->allocated,
75                                           sizeof(struct xlat));
76
77         dyxlat->xlat[dyxlat->used - 1].val = val;
78         dyxlat->xlat[dyxlat->used - 1].str = xstrndup(str, len);
79         MARK_END(dyxlat->xlat[dyxlat->used]);
80         dyxlat->used++;
81 }