1 /*
2 memory and string operations and some more common stuff
3
4 Copyright (C) 2000-2002 David Necas (Yeti) <yeti@physics.muni.cz>
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of version 2 of the GNU General Public License as published
8 by the Free Software Foundation.
9
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18 */
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif /* HAVE_CONFIG_H */
22
23 #include <stdarg.h>
24
25 #include "enca.h"
26 #include "internal.h"
27
28 /**
29 * enca_malloc:
30 * @size: The number of bytes to allocate.
31 *
32 * Allocates memory, always successfully (when fails, aborts program).
33 *
34 * Returns: Pointer to the newly allocated memory.
35 **/
36 void*
enca_malloc(size_t size)37 enca_malloc(size_t size)
38 {
39 void *ptr;
40
41 if (size == 0)
42 size = 1;
43 ptr = malloc(size);
44 assert(ptr != NULL);
45
46 return ptr;
47 }
48
49 /**
50 * enca_realloc:
51 * @ptr: Pointer to block of previously allocated memory.
52 * @size: The number of bytes to resize the block.
53 *
54 * Reallocates memory, always successfully (when fails, aborts program).
55 *
56 * Returns: Pointer to the newly allocated memory, #NULL when @size is zero.
57 **/
58 void*
enca_realloc(void * ptr,size_t size)59 enca_realloc(void *ptr, size_t size)
60 {
61 if (size == 0) {
62 free(ptr);
63 return NULL;
64 }
65
66 ptr = realloc(ptr, size);
67 assert(ptr != NULL);
68
69 return ptr;
70 }
71
72 /**
73 * enca_strdup:
74 * @s: A string.
75 *
76 * Duplicates string.
77 *
78 * Will be defined as strdup() when system provides it.
79 *
80 * Returns: The newly allocated string copy.
81 **/
82 char*
enca_strdup(const char * s)83 enca_strdup(const char *s) {
84 if (s == NULL)
85 return NULL;
86 else
87 return strcpy(enca_malloc(strlen(s) + 1), s);
88 }
89
90 #ifndef HAVE_STRSTR
91 /**
92 * enca_strstr:
93 * @haystack: A string where to search.
94 * @needle: A string to find.
95 *
96 * Finds occurence of a substring in a string.
97 *
98 * Will be defined as strstr() when system provides it.
99 *
100 * Returns: Pointer to the first occurence of @needle in @haystack; #NULL if
101 * not found.
102 **/
103 const char*
enca_strstr(const char * haystack,const char * needle)104 enca_strstr(const char *haystack,
105 const char *needle)
106 {
107 char c;
108 size_t n;
109
110 /* handle singularities */
111 if (needle == NULL)
112 return haystack;
113 if ((n = strlen(needle)) == 0)
114 return haystack;
115
116 /* search */
117 c = needle[0];
118 while ((haystack = strchr(haystack, c)) != NULL) {
119 if (strncmp(haystack, needle, n) == 0)
120 return haystack;
121 }
122
123 return NULL;
124 }
125 #endif
126
127 #ifndef HAVE_STPCPY
128 /**
129 * enca_stpcpy:
130 * @dest: A string.
131 * @src: A string to append.
132 *
133 * Appends a string to the end of another strings, returning pointer to
134 * the terminating zero byte.
135 *
136 * Will be defined as stpcpy() when system provides it.
137 *
138 * Caller is responisble for providing @dest long enough to hold the result.
139 *
140 * Returns: Pointer to the terminating zero byte of resulting string.
141 **/
142 char*
enca_stpcpy(char * dest,const char * src)143 enca_stpcpy(char *dest,
144 const char *src)
145 {
146 const char *p = src;
147
148 if (src == NULL)
149 return dest;
150
151 while (*p != '\0')
152 *dest++ = *p++;
153
154 *dest = '\0';
155 return dest;
156 }
157 #endif
158
159 /**
160 * enca_strconcat:
161 * @str: A string.
162 * @...: A #NULL-terminated list of string to append.
163 *
164 * Concatenates arbitrary (but at least one) number of strings.
165 *
166 * Returns: All the strings concatenated together.
167 **/
168 char*
enca_strconcat(const char * str,...)169 enca_strconcat(const char *str,
170 ...)
171 {
172 va_list ap;
173 char *result = NULL;
174 size_t n;
175 const char *s;
176 char *r;
177
178 /* compute size of resulting string */
179 n = 1;
180 va_start(ap, str);
181 for (s = str; s != NULL; s = va_arg(ap, const char*))
182 n += strlen(s);
183 va_end(ap);
184
185 /* and construct it using the smart stpcpy() function */
186 r = result = (char*)enca_malloc(n);
187 va_start(ap, str);
188 for (s = str; s != NULL; s = va_arg(ap, const char*))
189 r = enca_stpcpy(r, s);
190 va_end(ap);
191
192 return result;
193 }
194
195 /**
196 * enca_strappend:
197 * @str: A string.
198 * @...: A #NULL-terminated list of string to append.
199 *
200 * Appends arbitrary number of strings to a string.
201 *
202 * The string @str is destroyed (reallocated), the others are kept.
203 *
204 * Returns: All the strings concatenated together.
205 **/
206 char*
enca_strappend(char * str,...)207 enca_strappend(char *str,
208 ...)
209 {
210 va_list ap;
211 size_t n, n1;
212 const char *s;
213 char *r;
214
215 /* compute size of resulting string */
216 n1 = strlen(str);
217 n = 1 + n1;
218 va_start(ap, str);
219 for (s = va_arg(ap, const char*); s != NULL; s = va_arg(ap, const char*))
220 n += strlen(s);
221 va_end(ap);
222
223 /* and construct it using the smart stpcpy() function */
224 str = (char*)enca_realloc(str, n);
225 r = str + n1;
226 va_start(ap, str);
227 for (s = va_arg(ap, const char*); s != NULL; s = va_arg(ap, const char*))
228 r = enca_stpcpy(r, s);
229 va_end(ap);
230
231 return str;
232 }
233
234 /* vim: ts=2
235 */
236