-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdynamic_string.c
219 lines (192 loc) · 5.68 KB
/
dynamic_string.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
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/**
* @file dynamic_string.c
* @author André Dietrich
* @date 14 December 2016
*
* @copyright Copyright 2016 André Dietrich. All rights reserved.
*
* @license This project is released under the MIT-License.
*
* @brief Definition of C string manipulation functions.
*
*
*/
#include "dynamic_string.h"
#define FLOAT_DIGITS 100000.
/**
* Iteratates through an character array to sum up its length, the end is
* defined by the character '\0'.
*
* @param str Pointer to an character array
*
* @return string length
*/
dyn_ushort dyn_strlen(dyn_const_str str)
{
dyn_ushort len = 0;
while (*str++)
++len;
return len;
}
/**
* Appends a copy of the source string to the destination string. The
* terminating null character in destination is overwritten by the first
* character of source, and a null-character is included at the end of the new
* string formed by the concatenation of both in destination.
*
* destination and source shall not overlap and the length of destination must
* be sufficient for concatenation, otherwise use dyn_strcat2.
*
* @see dyn_strcat2
*
* @param destination Pointer to the destination array, which should contain
* a C string, and be large enough to contain the
* concatenated resulting string.
* @param source C string to be appended. This should not overlap
* destination.
*/
void dyn_strcat(dyn_str destination, dyn_const_str source)
{
dyn_strcpy(&destination[dyn_strlen(destination)], source);
}
/**
* Appends a copy of the source string to the destination string and adds
* automatically required memory. The terminating null character in destination
+ is overwritten by the first character of source, and a null-character is
* included at the end of the new string formed by the concatenation of both in
* destination.
*
* destination and source shall not overlap.
*
* @see dyn_strcat
*
* @param destination Pointer to the destination array, which should contain
* a C string, and be large enough to contain the
* concatenated resulting string.
* @param source C string to be appended. This should not overlap
* destination.
*/
void dyn_strcat2(dyn_str destination, dyn_const_str source)
{
destination = (dyn_str) realloc(destination, dyn_strlen(destination)+dyn_strlen(source)+1);
dyn_strcat(destination, source);
}
/**
* Copies the C string pointed by source into the array pointed by destination,
* including the terminating null character (and stopping at that point).
*
* To avoid overflows, the size of the array pointed by destination shall be
* long enough to contain the same C string as source (including the
* terminating null character), and should not overlap in memory with source.
*
* @param [out] destination Pointer to the destination array where the content
* is to be copied.
* @param [in] source C string to be copied.
*/
void dyn_strcpy (dyn_str destination, dyn_const_str source)
{
while(*source)
*destination++=*source++;
*destination = '\0';
}
/**
* Examples:
* @code
* dyn_itoa_len(0) == 1
* dyn_itoa_len(1) == 1
* dyn_itoa_len(999) == 3
* dyn_itoa_len(-999) == 4
* @endcode
*
* @param i integer value to convert
* @returns length of decimal string
*/
dyn_ushort dyn_itoa_len (dyn_int i)
{
if (!i) return 1;
dyn_ushort len = 0;
if (i < 0) {
i *= -1;
++len;
}
while (i)
i/=10, ++len;
return len;
}
/**
* The length of the character array has to have a sufficient length, it can be
* calculated previously with function dyn_itoa_len "(" str ")"
*
* @see dyn_ftoa
*
* @param [out] str character array with ASCII representation of i
* @param [in] i integer value to convert
*/
void dyn_itoa (dyn_str str, dyn_int i)
{
char const digit[] = "0123456789";
if (i<0) {
*str++ = '-';
i *= -1;
}
str += dyn_itoa_len(i);
*str = '\0';
do {
*--str = digit[i%10];
i /= 10;
} while(i);
}
/**
* @param f float value to check
* @returns string length
*/
dyn_ushort dyn_ftoa_len (const dyn_float f)
{
dyn_ushort len = 1;
dyn_int a = (dyn_int) f;
dyn_int b = (dyn_int) ((f - a) * FLOAT_DIGITS);
len += dyn_itoa_len(a);
len += dyn_itoa_len(b);
return len;
}
/**
* The length of the character-array has to be sufficient, it can be
* calculated previously with function dyn_ftoa_len.
*
* @see dyn_ftoa_len
* @see dyn_itoa
*
* @param [out] str character array with with new ASCII representation of f
* @param [in] f float value to convert
*/
void dyn_ftoa (dyn_str str, const dyn_float f)
{
dyn_int a = (dyn_int) f;
dyn_int b = (dyn_int) ((f - a) * FLOAT_DIGITS);
dyn_itoa(str, a);
dyn_ushort len = dyn_strlen(str);
str[len] = '.';
dyn_itoa(&str[len+1], b < 0 ? -b : b);
}
/**
* This function starts comparing the first character of each string. If they
* are equal to each other, it continues with the following pairs until the
* characters differ or until a terminating '\0' is reached.
*
* @param a char array to be compared
* @param b char array to be compared
*
* @retval <0 the first character that does not match has a lower value in a
* than in b
* @retval 0 the contents of both strings are equal
* @retval >0 the first character that does not match has a greater value in a
* than in b
*/
dyn_char dyn_strcmp(dyn_const_str a, dyn_const_str b)
{
while (*a == *b++) {
if (*a++ == 0)
return 0;
}
return (*a - *(b - 1));
}