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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <string.h>
#include <stdint.h> /* defines SIZE_MAX */
#include "../core/char.h"
#include "../core/index.h"
#include "../error/error.h"
#include "../knowledge/knowledge.h"
#include "sequence.h"
/******************************************************************************/
/** MEMORY ALLOCATION *********************************************************/
/******************************************************************************/
static int ensure_string_capacity
(
JH_char * string [const restrict static 1],
size_t string_capacity [const restrict static 1],
const size_t string_required_capacity,
FILE io [const restrict static 1]
)
{
JH_char * new_string;
if (string_required_capacity <= *string_capacity)
{
return 0;
}
new_string =
(JH_char *) realloc
(
(void *) *string,
((size_t) string_required_capacity) * sizeof(JH_char)
);
if (new_string== (JH_char *) NULL)
{
JH_S_ERROR
(
io,
"Unable to reallocate memory to match string's required size."
);
return -1;
}
*string_capacity = string_required_capacity;
*string = new_string;
return 1;
}
/******************************************************************************/
/** ADD WORD ******************************************************************/
/******************************************************************************/
static int increment_required_capacity
(
size_t current_capacity [const restrict static 1],
const size_t increase_factor,
FILE io [const restrict static 1]
)
{
if ((JH_INDEX_MAX - increase_factor) < *current_capacity)
{
JH_S_ERROR
(
io,
"String capacity increment aborted, as the new capacity would not "
"fit in a JH_index variable."
);
return -1;
}
*current_capacity += increase_factor;
if ((SIZE_MAX / sizeof(JH_char)) < *current_capacity)
{
*current_capacity -= increase_factor;
JH_S_ERROR
(
io,
"String capacity increment aborted, as the new size would not fit "
"in a size_t variable."
);
return -2;
}
return 0;
}
static int add_word
(
const JH_index word_id,
struct JH_knowledge k [const restrict static 1],
JH_char * destination [const restrict static 1],
size_t destination_capacity [const restrict static 1],
size_t destination_length [const restrict static 1],
FILE io [const restrict static 1]
)
{
const JH_char * word;
JH_index word_size;
size_t insertion_point;
if (word_id < JH_RESERVED_IDS_COUNT)
{
return 0;
}
(void) JH_knowledge_lock_access(k, io);
JH_knowledge_get_word(k, word_id, &word, &word_size);
(void) JH_knowledge_unlock_access(k, io);
insertion_point = *destination_length;
/* word_size includes '\n', which will be replaced by a space. */
/* (word_size == JH_INDEX_MAX) ==> could not have learned word. */
if (increment_required_capacity(destination_length, (word_size + 1), io) < 0)
{
return -1;
}
if
(
ensure_string_capacity
(
destination,
destination_capacity,
*destination_length,
io
) < 0
)
{
return -2;
}
memcpy
(
(*destination + insertion_point),
(const void *) word,
word_size
);
(*destination)[*destination_length - 1] = ' ';
return 0;
}
/******************************************************************************/
/** EXPORTED ******************************************************************/
/******************************************************************************/
int JH_sequence_to_undercase_string
(
const JH_index sequence [const restrict static 1],
const size_t sequence_length,
struct JH_knowledge k [const restrict static 1],
JH_char * destination [const restrict static 1],
size_t destination_capacity [const restrict static 1],
size_t destination_length [const restrict static 1],
FILE io [const restrict static 1]
)
{
size_t i;
*destination_length = 0;
for (i = 0; i < sequence_length; ++i)
{
if
(
add_word
(
sequence[i],
k,
destination,
destination_capacity,
destination_length,
io
) < 0
)
{
*destination_length = 0;
return -1;
}
}
return 0;
}
|