Titan Core Initial Contribution
[deliverable/titan.core.git] / common / memory.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #ifndef _Common_memory_H
9 #define _Common_memory_H
10
11 #include <stddef.h>
12 #include <stdarg.h>
13
14 #ifndef __GNUC__
15 /** If a C compiler other than GCC is used the macro below will substitute all
16 * GCC-specific non-standard attributes with an empty string. */
17 #ifndef __attribute__
18 #define __attribute__(arg)
19 #endif
20 #endif
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 /**
27 * \defgroup mem Memory management and expstring functions
28 * \brief Functions for memory management and string handling.
29 * \author Janos Zoltan Szabo <Janos.Zoltan.Szabo@ericsson.com>
30 *
31 * Primarily used in the TTCN-3 Test Executor (TTCN-3, ASN.1 compilers and
32 * runtime environment).
33 * @{
34 */
35
36 /**
37 * Same as the standard \c malloc(), but it never returns NULL.
38 * It increases a malloc counter. If there is not enough memory,
39 * it calls \c fatal_error(), which exits the application.
40 *
41 * @param size number of bytes to allocate
42 * @return pointer to the beginning of the allocated memory, or
43 * NULL if and only if \c size is 0
44 */
45 extern void *Malloc(size_t size);
46 #ifdef MEMORY_DEBUG
47 extern void *Malloc_dbg(const char *filename, int line, size_t size);
48 #define Malloc(s) Malloc_dbg(__FILE__, __LINE__, s)
49 #endif
50
51 /**
52 * Same as the standard \c realloc(), but it never returns NULL if \a size is
53 * positive. It updates the malloc or free counters if necessary.
54 * Exits if there is not enough memory.
55 *
56 * @param ptr pointer to a memory block allocated by Malloc(). If \p ptr
57 * is NULL, calls Malloc(size)
58 * @param size new size for the memory block. If \p size is 0, it calls
59 * Free(ptr) and returns NULL.
60 * @return pointer to the beginning of the re-allocated memory.
61 * Will only be NULL if size==0.
62 */
63 extern void *Realloc(void *ptr, size_t size);
64 #ifdef MEMORY_DEBUG
65 extern void *Realloc_dbg(const char *filename, int line, void *ptr, size_t size);
66 #define Realloc(p,s) Realloc_dbg(__FILE__, __LINE__, p, s)
67 #endif
68
69 /**
70 * Same as the standard \c free(). It increases the free counter if \a ptr
71 * is not NULL.
72 *
73 * @param ptr pointer to a memory block allocated by Malloc(). If \p ptr
74 * is NULL, this function does nothing.
75 */
76 extern void Free(void *ptr);
77 #ifdef MEMORY_DEBUG
78 extern void Free_dbg(const char *filename, int line, void *ptr);
79 #define Free(p) Free_dbg(__FILE__, __LINE__, p)
80 #endif
81
82 /**
83 * Prints a warning message to stderr if the malloc and free counters
84 * are not equals. It shall be called immediately before the end of
85 * program run.
86 */
87 extern void check_mem_leak(const char *program_name);
88
89 #ifdef MEMORY_DEBUG
90 /**
91 * Checks all allocated blocks of the program. Prints an error message and
92 * aborts if memory over-indexing is detected.
93 */
94 extern void check_mem_corrupt(const char *program_name);
95
96 #ifdef MEMORY_DEBUG_ADDRESS
97 /** @brief Memory allocation checkpoint.
98
99 If this variable is set to a nonzero value, allocations starting
100 at that address will be logged to stderr.
101
102 This can be used in conjunction with the output of check_mem_leak().
103 */
104 extern void * memory_debug_address;
105 #endif
106 #endif
107
108 /**
109 * Character string type with exponential buffer allocation. The size of
110 * allocated buffer is always a power of 2. The terminating '\\0' character
111 * is always present and the remaining bytes in the buffer are also set to
112 * zero. This allows binary search for the end of string, which is
113 * significantly faster than the linear one especially for long strings.
114 * The spare bytes at the end make appending of small chunks very efficient.
115 *
116 * \warning If a function takes expstring_t as argument
117 * you should not pass a regular string (or a static string literal)
118 * to it. This may result in an unpredictable behaviour. You can
119 * convert any regular string to expstring_t using mcopystr:
120 * myexpstring = mcopystr(myregularstring);
121 */
122 typedef char *expstring_t;
123
124 /**
125 * mprintf() takes its arguments like \c printf() and prints according
126 * to the format string \a fmt into a string buffer. It allocates
127 * enough memory for the resulting string and returns the pointer
128 * to the result string. The result string is an exponential string.
129 * mprintf() never returns NULL.
130 */
131 extern expstring_t mprintf(const char *fmt, ...)
132 __attribute__ ((__format__ (__printf__, 1, 2)));
133 #ifdef MEMORY_DEBUG
134 extern expstring_t mprintf_dbg(const char *filename, int line, const char *fmt, ...)
135 __attribute__ ((__format__ (__printf__, 3, 4)));
136 #if defined(__GNUC__) && __GNUC__ < 3
137 # define mprintf(f, args...) mprintf_dbg(__FILE__, __LINE__, f, ## args)
138 #else
139 # define mprintf(f,...) mprintf_dbg(__FILE__, __LINE__, f, __VA_ARGS__)
140 #endif
141 #endif
142
143 /**
144 * The same as \a mprintf(), but it takes the arguments as va_list.
145 * It is useful in wrapper functions with printf style argument strings.
146 */
147 extern expstring_t mprintf_va_list(const char *fmt, va_list pvar);
148 #ifdef MEMORY_DEBUG
149 extern expstring_t mprintf_va_list_dbg(const char *filename, int line,
150 const char *fmt, va_list pvar);
151 #define mprintf_va_list(f,v) mprintf_va_list_dbg(__FILE__, __LINE__, f, v)
152 #endif
153
154 /**
155 * mputprintf() prints its additional arguments according to the
156 * format string \a fmt at the end of \a str. The buffer of \a str is
157 * increased if the appended bytes do not fit in it. The result
158 * string, which is also an expstring, is returned.
159 * mputprintf() never returns NULL.
160 * \note If str is NULL it is equivalent to \a mprintf().
161 * \warning The first argument must be an exponential string,
162 * otherwise its behaviour may be unpredictable.
163 */
164 extern expstring_t mputprintf(expstring_t str, const char *fmt, ...)
165 __attribute__ ((__format__ (__printf__, 2, 3)));
166
167 /**
168 * The same as \a mputprintf(), but it takes the arguments as va_list.
169 * It is useful in wrapper functions with printf style argument strings.
170 */
171 extern expstring_t mputprintf_va_list(expstring_t str, const char *fmt,
172 va_list pvar);
173
174 /**
175 * memptystr() creates and returns a new empty exponential string.
176 * The returned value is never NULL,
177 * it shall be deallocated using \a Free().
178 */
179 extern expstring_t memptystr(void);
180 #ifdef MEMORY_DEBUG
181 extern expstring_t memptystr_dbg(const char *filename, int line);
182 #define memptystr() memptystr_dbg(__FILE__, __LINE__)
183 #endif
184
185
186 /**
187 * mcopystr() creates a new exponential string and copies the contents of
188 * \a str into it. The resulting expstring is returned.
189 * The regular string \a str will not be deallocated and it may be
190 * a static string literal.
191 * If \a str is NULL an empty exponential string is returned.
192 * mcopystr() never returns NULL.
193 */
194 extern expstring_t mcopystr(const char *str);
195 #ifdef MEMORY_DEBUG
196 extern expstring_t mcopystr_dbg(const char *filename, int line, const char *str);
197 #define mcopystr(s) mcopystr_dbg(__FILE__, __LINE__, s)
198 #endif
199
200 /**
201 * Create a new exponential string when the length is known.
202 * Works exactly like mcopystr(), except the length is not measured;
203 * the given length is used instead.
204 *
205 * @param str pointer to the original string; does not need to be 0-terminated
206 * @param len number of characters to copy
207 * @return the newly constructed string (it needs to be Free()-d)
208 */
209 extern expstring_t mcopystrn(const char *str, size_t len);
210 #ifdef MEMORY_DEBUG
211 extern expstring_t mcopystrn_dbg(const char *filename, int line, const char *str,
212 size_t len);
213 #define mcopystrn(s, len) mcopystrn_dbg(__FILE__, __LINE__, s, len)
214 #endif
215
216 /**
217 * mputstr() appends the regular string \a str2 to the end of
218 * expstring \a str. The resulting expstring is returned.
219 * The buffer of \a str is increased if necessary.
220 * If \a str is NULL then \a str2 is copied into a new exponential string
221 * (i.e. mputstr(NULL, str) is identical to mcopystr(str)).
222 * If \a str2 is NULL then \a str is returned and remains unchanged
223 * (i.e. mputstr(str, NULL) is identical to str,
224 * mputstr(NULL, NULL) always returns NULL).
225 * \warning The first argument must be an exponential string,
226 * otherwise its behaviour may be unpredictable.
227 */
228 extern expstring_t mputstr(expstring_t str, const char *str2);
229
230 /** Appends \a len2 characters from the regular string \a str2 to the end of
231 * expstring \a str. The resulting expstring is returned. @see mputstr()
232 * @param str destination string
233 * @param str2 pointer to characters; does not need to be 0-terminated
234 * @param len2 number of characters to copy
235 * @return the (possibly reallocated) str
236 */
237 extern expstring_t mputstrn(expstring_t str, const char *str2, size_t len2);
238
239 /**
240 * mputc() appends the single character \a c to the end of
241 * expstring \a str. The buffer of \a str is increased if necessary.
242 * The resulting expstring is returned.
243 * If \a str is NULL then \a c is converted to a new exponential string.
244 * If \a c is '\\0' then \a str is returned.
245 * mputc() never returns NULL.
246 * \warning The first argument must be an exponential string,
247 * otherwise its behaviour may be unpredictable.
248 */
249 extern expstring_t mputc(expstring_t str, char c);
250
251 /**
252 * mtruncstr() truncates the expstring \a str by keeping only the first
253 * \a newlen characters and returns the resulting string.
254 * If the string is shorter than \a newlen it remains unchanged.
255 * mtruncstr() may perform memory reallocation if necessary.
256 * If \a str is NULL then a NULL pointer is returned.
257 * If \a str is not an exponential string the behaviour of mtruncstr() may
258 * be unpredictable.
259 */
260 extern expstring_t mtruncstr(expstring_t str, size_t newlen);
261
262 /**
263 * mstrlen() returns the length of expstring \a str or zero if \a str is
264 * NULL. If \a str is not NULL the function has identical result as libc's
265 * strlen(), but operates significantly faster. The behaviour may be
266 * unpredictable if \a str is not an exponential string.
267 */
268 extern size_t mstrlen(const expstring_t str);
269
270 /** @} end of mem group */
271
272 /** Return the string for the build number.
273 *
274 * @param b build number.
275 * @return a string which must be Free()-d by the caller
276 * @pre b > 0 and b <= 99, or else NULL is returned
277 */
278 char * buildstr(int b);
279
280 #ifdef __cplusplus
281 /** Convert a patch level to the "Ericsson letter" */
282 inline char eri(unsigned int p) { /* p stands for patch level */
283 char i = (char)('A' + p); /* i stands for "if only it was that simple" */
284 return i + (i >= 'I') + 4 * (i >= 'N') + (i >= 'R');
285 }
286
287 } /* extern "C" */
288
289 #endif
290
291 #endif /* _Common_memory_H */
This page took 0.063017 seconds and 5 git commands to generate.