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