forked from andbof/yastg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnames.c
138 lines (122 loc) · 2.74 KB
/
names.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "log.h"
#include "names.h"
#include "ptrarray.h"
#include "mtrandom.h"
#include "stringtree.h"
void names_init(struct name_list *l)
{
INIT_LIST_HEAD(&l->taken);
l->prefix = ptrarray_create();
l->first = ptrarray_create();
l->second = ptrarray_create();
l->suffix = ptrarray_create();
}
void names_free(struct name_list *l)
{
st_destroy(&l->taken, ST_DONT_FREE_DATA);
ptrarray_free(l->prefix);
ptrarray_free(l->first);
ptrarray_free(l->second);
ptrarray_free(l->suffix);
}
void names_load(struct name_list *l, const char * const prefix, const char * const first,
const char * const second, const char * const suffix)
{
if (prefix)
l->prefix = file_to_ptrarray(prefix, l->prefix);
if (first)
l->first = file_to_ptrarray(first, l->first);
if (second)
l->second = file_to_ptrarray(second, l->second);
if (suffix)
l->suffix = file_to_ptrarray(suffix, l->suffix);
}
static char* create_name(struct name_list *l)
{
char *pr = NULL;
char *fi = NULL;
char *se = NULL;
char *su = NULL;
size_t len = 0;
if (mtrandom_uint(2) == 0) {
pr = ptrarray_get(l->prefix, mtrandom_uint(l->prefix->used));
if (pr)
len += strlen(pr);
} else {
su = ptrarray_get(l->suffix, mtrandom_uint(l->suffix->used));
if (su)
len += strlen(su);
}
fi = ptrarray_get(l->first, mtrandom_uint(l->first->used));
if (fi)
len += strlen(fi);
se = ptrarray_get(l->second, mtrandom_uint(l->second->used));
if (se)
len += strlen(se);
assert(len > 0); /* Fails if no names are loaded */
len += 4; /* Spaces between words and ending null */
char *name;
name = malloc(len);
if (!name)
return NULL;
*name = '\0';
char *p = name;
if (pr) {
strcpy(p, pr);
p += strlen(pr);
*p = ' ';
p++;
}
if (fi) {
strcpy(p, fi);
p += strlen(fi);
*p = ' ';
p++;
}
if (se) {
strcpy(p, se);
p += strlen(se);
*p = ' ';
p++;
}
if (su) {
strcpy(p, su);
p += strlen(su);
*p = ' ';
p++;
}
assert(*name); /* Fails if nothing has been added to the string at all */
if (*(p - 1) == ' ')
*(p - 1) = '\0';
return name;
}
char* create_unique_name(struct name_list *l)
{
char *name = NULL;
do {
free(name);
name = create_name(l);
} while (st_lookup_exact(&l->taken, name));
/*
* The data pointer in the string tree merely needs to evaluate to true,
* because it will never be dereferenced. Using the name string itself
* is fine, even though it might not be a valid pointer in the future.
*/
if (st_add_string(&l->taken, name, name)) {
free(name);
return NULL;
}
return name;
}
int is_names_loaded(struct name_list *l)
{
if (l->prefix->used || l->first->used || l->second->used || l->suffix->used)
return 1;
else
return 0;
}