1 /*******************************************************************************
2 *
3 * McStas, neutron ray-tracing package
4 * Copyright (C) 1997-2009, All rights reserved
5 * Risoe National Laboratory, Roskilde, Denmark
6 * Institut Laue Langevin, Grenoble, France
7 *
8 * Kernel: memory.c
9 *
10 * %Identification
11 * Written by: K.N.
12 * Date: Jul 1, 1997
13 * Origin: Risoe
14 * Release: McStas CVS_090504
15 * Version: $Revision$
16 *
17 * Memory management functions.
18 *
19 * $Id$
20 *
21 *******************************************************************************/
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <ctype.h>
27 #include <stdio.h>
28
29 #include "mccode.h"
30
31
32 /*******************************************************************************
33 * Allocate memory. This function never returns NULL; instead, the
34 * program is aborted if insufficient memory is available.
35 *******************************************************************************/
36 void *
mem(size_t size)37 mem(size_t size)
38 {
39 void *p = calloc(1, size); /* Allocate and clear memory. */
40 if(p == NULL)
41 fatal_error("memory exhausted during allocation of size %ld.", (long)size);
42 return p;
43 }
44
45 /*******************************************************************************
46 * Free memory allocated with mem().
47 *******************************************************************************/
memfree(void * p)48 void memfree(void *p)
49 {
50 if(p == NULL)
51 debug(("memfree(): freeing NULL memory.\n"));
52 else
53 free(p);
54 }
55
56 /*******************************************************************************
57 * Allocate a new copy of a string.
58 *******************************************************************************/
59 char *
str_dup(char * string)60 str_dup(char *string)
61 {
62 char *s;
63
64 s = mem(strlen(string) + 1);
65 strcpy(s, string);
66 return s;
67 }
68
69
70 /*******************************************************************************
71 * Allocate a new copy of initial N chars in a string.
72 *******************************************************************************/
73 char *
str_dup_n(char * string,int n)74 str_dup_n(char *string, int n)
75 {
76 char *s;
77
78 s = mem(n + 1);
79 strncpy(s, string, n);
80 s[n] = '\0';
81 return s;
82 }
83
84
85 /*******************************************************************************
86 * Allocate a new string to hold the concatenation of given strings. Arguments
87 * are the strings to concatenate, terminated by NULL.
88 *******************************************************************************/
89 char *
str_cat(char * first,...)90 str_cat(char *first, ...)
91 {
92 char *s;
93 va_list ap;
94 int size;
95 char *arg;
96
97 size = 1; /* Count final '\0'. */
98 va_start(ap, first);
99 for(arg = first; arg != NULL; arg = va_arg(ap, char *))
100 size += strlen(arg); /* Calculate string size. */
101 va_end(ap);
102 s = mem(size);
103 size = 0;
104 va_start(ap, first);
105 for(arg = first; arg != NULL; arg = va_arg(ap, char *))
106 {
107 strcpy(&(s[size]), arg);
108 size += strlen(arg);
109 }
110 va_end(ap);
111 return s;
112 }
113
114 /*******************************************************************************
115 * Allocate a new string holding the result of quoting the input string. The
116 * result is suitable for inclusion in C source code.
117 *******************************************************************************/
118 char *
str_quote(char * string)119 str_quote(char *string)
120 {
121 char *badchars = "\\\"\r\n\t";
122 char *quotechars = "\\\"rnt";
123 char *q=NULL, *res=NULL, *ptr;
124 int len, pass;
125 int c;
126 char new[5];
127
128 /* Loop over the string twice, first counting chars and afterwards copying
129 them into an allocated buffer. */
130 for(pass = 0; pass < 2; pass++)
131 {
132 char *p = string;
133
134 if(pass == 0)
135 len = 0; /* Prepare to compute length */
136 else
137 q = res = mem(len + 1); /* Allocate buffer */
138 /* Notice the cast to unsigned char; without it, the isprint(c) below will
139 fail for characters with negative plain char values. */
140 while((c = (unsigned char)(*p++)))
141 {
142 ptr = strchr(badchars, c);
143 if(ptr != NULL)
144 sprintf(new, "\\%c", quotechars[ptr - badchars]);
145 else if(isprint(c))
146 sprintf(new, "%c", c);
147 else
148 sprintf(new, "\\%03o", c);
149 if(pass == 0)
150 len += strlen(new); /* Count in length */
151 else
152 for(ptr = new; (*q = *ptr) != 0; ptr++)
153 q++; /* Copy over chars */
154 }
155 }
156 return res;
157 }
158
159
160 /*******************************************************************************
161 * Free memory for a string.
162 *******************************************************************************/
163 void
str_free(char * string)164 str_free(char *string)
165 {
166 memfree(string);
167 }
168
169 #ifndef MCFORMAT
170
171 struct Pool_header
172 {
173 List list;
174 };
175
176 /*******************************************************************************
177 * Create a pool in which to allocate memory that may be easily freed all at a
178 * time by freeing the pool.
179 *******************************************************************************/
180 Pool
pool_create(void)181 pool_create(void)
182 {
183 Pool p;
184
185 palloc(p);
186 p->list = list_create();
187 return p;
188 }
189
190 /*******************************************************************************
191 * Deallocate a pool as well as all memory allocated within it.
192 *******************************************************************************/
193 void
pool_free(Pool p)194 pool_free(Pool p)
195 {
196 List_handle liter;
197 void *mem;
198
199 liter = list_iterate(p->list);
200 while(mem = list_next(liter))
201 {
202 memfree(mem);
203 }
204 list_iterate_end(liter);
205 memfree(p);
206 }
207
208
209 /*******************************************************************************
210 * Allocate memory in a pool.
211 *******************************************************************************/
212 void *
pool_mem(Pool p,size_t size)213 pool_mem(Pool p, size_t size)
214 {
215 void *m = mem(size);
216 list_add(p->list, m);
217 return m;
218 }
219
220 #endif /* MCSTAS_H */
221