| 1 | /******************************************************************************* |
|---|
| 2 | * |
|---|
| 3 | * McStas, neutron ray-tracing package |
|---|
| 4 | * Copyright 1997-2002, 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 1.6 |
|---|
| 15 | * Version: $Revision: 1.20 $ |
|---|
| 16 | * |
|---|
| 17 | * Memory management functions. |
|---|
| 18 | * |
|---|
| 19 | * $Id: memory.c,v 1.20 2006-04-19 13:06:25 farhi Exp $ |
|---|
| 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 "mcstas.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 * |
|---|
| 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 %d.", size); |
|---|
| 42 | return p; |
|---|
| 43 | } |
|---|
| 44 | |
|---|
| 45 | /******************************************************************************* |
|---|
| 46 | * Free memory allocated with mem(). |
|---|
| 47 | *******************************************************************************/ |
|---|
| 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 * |
|---|
| 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 * |
|---|
| 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 * |
|---|
| 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 * |
|---|
| 119 | str_quote(char *string) |
|---|
| 120 | { |
|---|
| 121 | char *badchars = "\\\"\r\n\t"; |
|---|
| 122 | char *quotechars = "\\\"rnt"; |
|---|
| 123 | char *q, *res, *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 |
|---|
| 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 |
|---|
| 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 |
|---|
| 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 * |
|---|
| 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 */ |
|---|