Cantera  2.1.2
mdp_allo.cpp
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 
5 #include <new>
6 #include <algorithm>
7 #include <stdarg.h>
8 
9 #include "mdp_allo.h"
10 
11 /*
12  * Allocate global storage for 2 debugging ints that are used in IO of
13  * error information.
14  */
15 #ifdef MDP_MPDEBUGIO
16 int MDP_MP_Nprocs = 1;
17 int MDP_MP_myproc = 0;
18 #endif
19 /*
20  * Error Handling
21  * 7 print and exit
22  * 6 exit
23  * 5 print and create a divide by zero for stack trace analysis.
24  * 4 create a divide by zero for stack trace analysis.
25  * 3 print a message and throw the bad_alloc exception.
26  * 2 throw the bad_alloc exception and be quite
27  * 1 print a message and return from package with the NULL pointer
28  * 0 Keep completely silent about the matter and return with
29  * a null pointer.
30  *
31  * -> Right now, the only way to change this option is to right here
32  */
33 int MDP_ALLO_errorOption = 3;
34 
35 #define MDP_ALLOC_INTERFACE_ERROR 230346
36 
37 /****************************************************************************/
38 /****************************************************************************/
39 /****************************************************************************/
40 
41 static void mdp_alloc_eh(const char* rname, size_t bytes)
42 
43 /*************************************************************************
44 *
45 * mdp_alloc_eh:
46 *
47 * Error Handling
48 * 7 print and exit
49 * 6 exit
50 * 5 print and create a divide by zero for stack trace analysis.
51 * 4 create a divide by zero for stack trace analysis.
52 * 3 print a message and throw the bad_alloc exception.
53 * 2 throw the bad_alloc exception and be quite
54 * 1 print a message and return from package with the NULL pointer
55 * 0 Keep completely silent about the matter and return with
56 * a null pointer.
57 **************************************************************************/
58 {
59  double cd = 0.0;
60  static char mesg[64];
61  if (bytes == MDP_ALLOC_INTERFACE_ERROR) {
62 #ifdef MDP_MPDEBUGIO
63  sprintf(mesg,"MDP_ALLOC Interface ERROR P_%d: %s", MDP_MP_my_proc,
64  rname);
65 #else
66  sprintf(mesg,"MDP_ALLOC Interface ERROR: %s", rname);
67 #endif
68  } else {
69  sprintf(mesg,"%s ERROR: out of memory while mallocing %d bytes",
70  rname, (int) bytes);
71  }
72  if (MDP_ALLO_errorOption % 2 == 1) {
73  fprintf(stderr, "\n%s", mesg);
74 #ifdef MDP_MPDEBUGIO
75  if (MDP_MP_Nprocs > 1) {
76  fprintf(stderr,": proc = %d\n", MDP_MP_myproc);
77  } else {
78  fprintf(stderr,"\n");
79  }
80 #else
81  fprintf(stderr,"\n");
82 #endif
83  }
84  fflush(stderr);
85  if (MDP_ALLO_errorOption == 2 || MDP_ALLO_errorOption == 3) {
86  throw std::bad_alloc();
87  }
88  if (MDP_ALLO_errorOption == 4 || MDP_ALLO_errorOption == 5) {
89  cd = 1.0 / cd;
90  }
91  if (MDP_ALLO_errorOption > 5) {
92  exit(-1);
93  }
94 }
95 
96 /****************************************************************************/
97 /****************************************************************************/
98 /****************************************************************************/
99 
100 static void mdp_alloc_eh2(const char* rname)
101 
102 /*************************************************************************
103 *
104 * mdp_alloc_eh2:
105 *
106 * Second Level Error Handling
107 * This routine is used at the second level.
108 * It will be triggered after mdp_allo_eh() has
109 * been triggered. Thus, it only needs to deal with 1 -> print mess
110 *
111 * 3 create a divide by zero for stack trace analysis.
112 * 2 or above ->
113 * 1 print a message and return with the NULL pointer
114 * 0 Keep completely silent about the matter.
115 **************************************************************************/
116 {
117  if (MDP_ALLO_errorOption == 1) {
118  fprintf(stderr,"%s ERROR: returning with null pointer", rname);
119 #ifdef MDP_MPDEBUGIO
120  if (MDP_MP_Nprocs > 1) {
121  fprintf(stderr,": proc = %d", MDP_MP_myproc);
122  }
123 #endif
124  fprintf(stderr,"\n");
125  }
126 }
127 /****************************************************************************/
128 /****************************************************************************/
129 /****************************************************************************/
130 
131 #define Fprintf (void) fprintf
132 
133 /****************************************************************************/
134 #ifndef HAVE_ARRAY_ALLOC
135 /****************************************************************************/
136 static double* smalloc(size_t n);
137 
138 /*****************************************************************************
139  *
140  * Dynamic Allocation of Multidimensional Arrays
141  *----------------------------------------------------------------------------
142  *
143  * Example Usage:
144  *
145  * typedef struct
146  * { int bus1;
147  * int bus2;
148  * int dest;
149  * } POINT;
150  *
151  * POINT **points, corner;
152  *
153  * points = (POINT **) array_alloc (2, x, y, sizeof(POINT));
154  * ^ ^ ^
155  * | | |
156  * number of dimensions--+ | |
157  * | |
158  * first dimension max----+ |
159  * |
160  * second dimension max-------+
161  *
162  * (points may be now be used as if it were declared
163  * POINT points[x][y])
164  *
165  * Note, the inner loop of the memory layout is the over the
166  * last column.
167  *
168  *
169  * corner = points[2][3]; (refer to the structure as you would any array)
170  *
171  * free (points); (frees the entire structure in one fell swoop)
172  *
173  ****************************************************************************/
174 /*****************************************************************************
175 * The following section is a commented section containing
176 * an example main code:
177 ******************************************************************************
178 *double *array_alloc();
179 *main()
180 *{
181 * int ***temp;
182 * int *temp2;
183 * int i, j, k;
184 * int il, jl, kl;
185 *
186 * malloc_debug(2);
187 * il = 2;
188 * jl = 3;
189 * kl = 3;
190 * temp = (int ***) array_alloc(3,il,jl,kl,sizeof(int));
191 * for (i=0; i<il; i++) {
192 * for (j=0; j<jl; j++) {
193 * for (k=0; k<kl; k++) temp[i][j][k] = 1;
194 * }
195 * }
196 *
197 * temp2 = (int *) malloc(10*sizeof(int));
198 * for (i=0; i<10; i++) temp2[i] = 0;
199 *
200 * for (i=0; i<il; i++) {
201 * for (j=0; j<jl; j++) {
202 * for (k=0; k<kl; k++) (void) printf(" %d\n", temp[i][j][k]);
203 * }
204 * }
205 * malloc_verify();
206 *}
207 *****************************************************************************/
208 
209 /****************************************************************************/
210 /****************************************************************************/
211 /****************************************************************************/
212 
213 double* mdp_array_alloc(int numdim, ...)
214 {
215  int i, j;
216  struct dim {
217  long index; /* Number of elements in the dimension */
218  long total; /* Total number of elements */
219  long size; /* Size of a single element in bytes */
220  long off; /* offset from beginning of array */
221  } dim[4]; /* Info about each dimension */
222 
223 
224  long total; /* Total size of the array */
225  double* dfield; /* ptr to avoid lint complaints */
226  char* field; /* The multi-dimensional array */
227  char** ptr; /* Pointer offset */
228  char* data; /* Data offset */
229  va_list va; /* Current pointer in the argument list */
230 
231  va_start(va, numdim);
232 
233  if (numdim <= 0) {
234  Fprintf(stderr,
235  "mdp_array_alloc ERROR: number of dimensions, %d, is <=0\n",
236  numdim);
237  return NULL;
238  } else if (numdim > 4) {
239  Fprintf(stderr,
240  "mdp_array_alloc ERROR: number of dimensions, %d, is > 4\n",
241  numdim);
242  return NULL;
243  }
244 
245  dim[0].index = va_arg(va, int);
246 
247  if (dim[0].index <= 0) {
248 #ifdef DEBUG
249  Fprintf(stderr, "WARNING: mdp_array_alloc called with first "
250  "dimension <= 0, %d\n\twill return the nil pointer\n",
251  (int)(dim[0].index));
252 #endif
253  return((double*) NULL);
254  }
255 
256  dim[0].total = dim[0].index;
257  dim[0].size = sizeof(void*);
258  dim[0].off = 0;
259  for (i = 1; i < numdim; i++) {
260  dim[i].index = va_arg(va, int);
261  if (dim[i].index <= 0) {
262  Fprintf(stderr,
263  "WARNING: mdp_array_alloc called with dimension %d <= 0, "
264  "%d\n", i+1, (int)(dim[i].index));
265  Fprintf(stderr, "\twill return the nil pointer\n");
266  return((double*) NULL);
267  }
268  dim[i].total = dim[i-1].total * dim[i].index;
269  dim[i].size = sizeof(void*);
270  dim[i].off = dim[i-1].off + dim[i-1].total * dim[i-1].size;
271  }
272 
273  dim[numdim-1].size = va_arg(va, int);
274  va_end(va);
275 
276  /*
277  * Round up the last offset value so data is properly aligned.
278  */
279 
280  dim[numdim-1].off = dim[numdim-1].size *
281  ((dim[numdim-1].off+dim[numdim-1].size-1)/dim[numdim-1].size);
282 
283  total = dim[numdim-1].off + dim[numdim-1].total * dim[numdim-1].size;
284 
285  dfield = (double*) smalloc((size_t) total);
286  field = (char*) dfield;
287 
288  for (i = 0; i < numdim - 1; i++) {
289  ptr = (char**)(field + dim[i].off);
290  data = (char*)(field + dim[i+1].off);
291  for (j = 0; j < dim[i].total; j++) {
292  ptr[j] = data + j * dim[i+1].size * dim[i+1].index;
293  }
294  }
295 
296  return dfield;
297 }
298 /****************************************************************************/
299 /****************************************************************************/
300 /****************************************************************************/
301 
302 static double* smalloc(size_t n)
303 
304 /**************************************************************************
305 * smalloc: safe version of malloc
306 *
307 * This version of smalloc assigns space in even chunks of 8 bytes only
308 **************************************************************************/
309 {
310 #ifdef MDP_MEMDEBUG
311  static int firsttime = 1;
312  FILE* file;
313 #endif
314  double* pntr;
315  if (n == 0) {
316  pntr = NULL;
317  } else {
318  n = ((n - 1) / 8);
319  n = (n + 1) * 8;
320  pntr = (double*) malloc((size_t) n);
321  }
322  if (pntr == NULL && n != 0) {
323  Fprintf(stderr, "smalloc : Out of space - number of bytes "
324  "requested = %d\n", int(n));
325  }
326 #ifdef MDP_MEMDEBUG
327  if (firsttime) {
328  firsttime = 0;
329  file = fopen("memops.txt", "w");
330  } else {
331  file = fopen("memops.txt", "a");
332  }
333  Fprintf(file, "%x %d malloc\n", pntr, n);
334  if ((int) pntr == 0x00000001) {
335  Fprintf(stderr, "FOUND IT!\n");
336  exit(-1);
337  }
338  fclose(file);
339 #endif
340  return pntr;
341 }
342 /****************************************************************************/
343 /****************************************************************************/
344 /****************************************************************************/
345 
346 void mdp_safe_free(void** ptr)
347 
348 /*************************************************************************
349 *
350 * mdp_safe_free():
351 *
352 * This version of free calls the system's free function
353 * with maximum error checking. It also doesn't call free if ptr is
354 * the NULL pointer already.
355 * It will then set the freed pointer to NULL. Thus, a convention may
356 * be established wherein all pointers that can be malloced can be
357 * set to NULL if they are not malloced.
358 **************************************************************************/
359 {
360 #ifdef MDP_MEMDEBUG
361  FILE* file;
362 #endif
363  if (ptr == NULL) {
364  mdp_alloc_eh("mdp_safe_free: handle is NULL", MDP_ALLOC_INTERFACE_ERROR);
365  }
366  if (*ptr != NULL) {
367 #ifdef MDP_MEMDEBUG
368  file = fopen("memops.txt", "a");
369  Fprintf(file, "%x free\n", *ptr);
370  fflush(file);
371  if ((int) *ptr == 0x00000001) {
372  Fprintf(stderr, "FOUND IT!\n");
373  exit(-1);
374  }
375  fclose(file);
376 #endif
377  free(*ptr);
378  /*
379  * Set the value of ptr to NULL, so that further references
380  * to it will be flagged.
381  */
382  *ptr = NULL;
383  }
384 }
385 /****************************************************************************/
386 #endif
387 /*****************************************************************************
388 *
389 * Wrapper Functions
390 * --------------------
391 *
392 * The function definitions below are wrappers around array_alloc for
393 * common operations. The following principles are followed:
394 *
395 * Argument dimensions le 0 are increased to 1 before calling array_alloc.
396 * Thus, something is always malloced during a call. The reason for this is
397 * that it minimizes the number of special cases in the calling program.
398 *
399 * A pointer to something else other than NULL indicates that that pointer
400 * has been previously malloced. Thus, it can be freed. Note, after a free
401 * operation, this package always sets the pointer to NULL before returning.
402 *
403 * "safe_alloc" routines try to free the pointer if nonNULL, before calling
404 * the base alloc_int_#() routines.
405 *
406 * The regular routines always initialize the previously malloced space.
407 *
408 *****************************************************************************/
409 /****************************************************************************/
410 /****************************************************************************/
411 /****************************************************************************/
412 
413 int* mdp_alloc_int_1(int nvalues, const int val)
414 
415 /**************************************************************************
416 *
417 * mdp_alloc_int_1:
418 *
419 * Allocate and initialize a one dimensional array of integers.
420 *
421 * Input
422 * -------
423 * nvalues = Length of the array
424 * val = initialization value
425 * Return
426 * ------
427 * Pointer to the initialized integer array
428 * Failures are indicated by returning the NULL pointer.
429 **************************************************************************/
430 {
431  int* array;
432  if (nvalues <= 0) {
433  nvalues = 1;
434  }
435  array= (int*) mdp_array_alloc(1, nvalues, sizeof(int));
436  if (array != NULL) {
437  if (val != MDP_INT_NOINIT) {
438  if (val == 0) {
439  (void) memset(array, 0, sizeof(int)*nvalues);
440  } else {
441  for (int i = 0; i < nvalues; i++) {
442  array[i] = val;
443  }
444  }
445  }
446  } else {
447  mdp_alloc_eh("mdp_alloc_int_1", nvalues * sizeof(int));
448  }
449  return array;
450 }
451 /****************************************************************************/
452 /****************************************************************************/
453 /****************************************************************************/
454 
455 void mdp_safe_alloc_int_1(int** array_hdl, int nvalues, const int val)
456 
457 /*************************************************************************
458 *
459 * mdp_safe_alloc_int_1:
460 *
461 * Allocates and/or initialize a one dimensional array of integers.
462 *
463 * Input
464 * -------
465 * *array_hdl = Previous value of pointer. If non-NULL will try
466 * to free the memory at this address.
467 * nvalues = Length of the array
468 * val = initialization value
469 * Output
470 * ------
471 * *array_hdl = This value is initialized to the correct address
472 * of the array.
473 * A NULL value in the position indicates an error.
474 **************************************************************************/
475 {
476  if (array_hdl == NULL) {
477  mdp_alloc_eh("mdp_safe_alloc_int_1: handle is NULL",
478  MDP_ALLOC_INTERFACE_ERROR);
479  return;
480  }
481  if (*array_hdl != NULL) {
482  mdp_safe_free((void**) array_hdl);
483  }
484  *array_hdl = mdp_alloc_int_1(nvalues, val);
485  if (*array_hdl == NULL) {
486  mdp_alloc_eh2("mdp_safe_alloc_int_1");
487  }
488 }
489 /****************************************************************************/
490 /****************************************************************************/
491 /****************************************************************************/
492 
493 void
494 mdp_realloc_int_1(int** array_hdl, int new_length, int old_length,
495  const int defval)
496 
497 /*************************************************************************
498 *
499 * mdp_realloc_int_1_(array_hdl, new_num_ptrs, old_num_ptrs);
500 *
501 * Reallocates a one dimensional array of ints.
502 * This routine always allocates space for at least one int.
503 * Calls the smalloc() routine to ensure that all malloc
504 * calls go through one location. This routine will then copy
505 * the pertinent information from the old array to the
506 * new array.
507 *
508 * Input
509 * -------
510 * array_hdl = Pointer to the global variable that
511 * holds the old and (eventually new)
512 * address of the array of integers to be reallocated
513 * new_length = Length of the array
514 * old_length = Length of the old array
515 **************************************************************************/
516 {
517  if (new_length == old_length) {
518  return;
519  }
520  if (new_length <= 0) {
521 #ifdef MDP_MPDEBUGIO
522  fprintf(stderr,
523  "Warning: mdp_realloc_int_1 P_%d: called with n = %d ",
524  MDP_MP_myproc, new_length);
525 #else
526  fprintf(stderr,
527  "Warning: mdp_realloc_int_1: called with n = %d ",
528  new_length);
529 #endif
530  new_length = 1;
531  }
532  if (old_length < 0) {
533  old_length = 0;
534  }
535  if (new_length == old_length) {
536  return;
537  }
538  size_t bytenum = new_length * sizeof(int);
539  int* array = (int*) smalloc(bytenum);
540  if (array != NULL) {
541  if (*array_hdl) {
542  if (old_length > 0) {
543  bytenum = sizeof(int) * old_length;
544  } else {
545  bytenum = 0;
546  }
547  if (new_length < old_length) {
548  bytenum = sizeof(int) * new_length;
549  }
550  (void) memcpy((void*) array, (void*) *array_hdl, bytenum);
551  mdp_safe_free((void**) array_hdl);
552  } else {
553  old_length = 0;
554  }
555  *array_hdl = array;
556  if ((defval != MDP_INT_NOINIT) && (new_length > old_length)) {
557  if (defval == 0) {
558  bytenum = sizeof(int) * (new_length - old_length);
559  (void) memset((void*)(array+old_length), 0, bytenum);
560  } else {
561  for (int i = old_length; i < new_length; i++) {
562  array[i] = defval;
563  }
564  }
565  }
566  } else {
567  mdp_alloc_eh("mdp_realloc_int_1", bytenum);
568  }
569 }
570 /****************************************************************************/
571 /****************************************************************************/
572 /****************************************************************************/
573 
574 int** mdp_alloc_int_2(int ndim1, int ndim2, const int val)
575 
576 /*************************************************************************
577 *
578 * mdp_alloc_int_2:
579 *
580 * Allocate and initialize a two dimensional array of ints.
581 *
582 * Input
583 * -------
584 * ndim1 = Length of the first dimension of the array
585 * ndim2 = Length of the second dimension of the array
586 * val = initialization value
587 * Return
588 * ------
589 * Pointer to the initialized integer array
590 * Failures are indicated by returning the NULL pointer.
591 **************************************************************************/
592 {
593  int i;
594  int** array, *dptr;
595  if (ndim1 <= 0) {
596  ndim1 = 1;
597  }
598  if (ndim2 <= 0) {
599  ndim2 = 1;
600  }
601  array = (int**) mdp_array_alloc(2, ndim1, ndim2, sizeof(int));
602  if (array != NULL) {
603  if (val != MDP_INT_NOINIT) {
604  if (val == 0) {
605  (void) memset((void*) array[0], 0, ndim1 * ndim2 * sizeof(int));
606  } else {
607  dptr = &(array[0][0]);
608  for (i = 0; i < ndim1 * ndim2; i++) {
609  dptr[i] = val;
610  }
611  }
612  }
613  } else {
614  mdp_alloc_eh("mdp_alloc_int_2",
615  sizeof(int) * ndim1 * ndim2 +
616  ndim1 * sizeof(void*));
617  }
618  return array;
619 }
620 /****************************************************************************/
621 /****************************************************************************/
622 /****************************************************************************/
623 
624 double* mdp_alloc_dbl_1(int nvalues, const double val)
625 
626 /*************************************************************************
627 *
628 * mdp_alloc_dbl_1:
629 *
630 * Allocate and initialize a one dimensional array of doubles.
631 *
632 * Input
633 * -------
634 * nvalues = Length of the array
635 * val = initialization value
636 * Return
637 * ------
638 * Pointer to the initialized integer array
639 * Failures are indicated by returning the NULL pointer.
640 **************************************************************************/
641 {
642  int i;
643  double* array;
644  if (nvalues <= 0) {
645  nvalues = 1;
646  }
647  array = (double*) mdp_array_alloc(1, nvalues, sizeof(double));
648  if (array != NULL) {
649  if (val != MDP_DBL_NOINIT) {
650  if (val == 0.0) {
651  (void) memset((void*) array, 0, nvalues * sizeof(double));
652  } else {
653  for (i = 0; i < nvalues; i++) {
654  array[i] = val;
655  }
656  }
657  }
658  } else {
659  mdp_alloc_eh("mdp_alloc_dbl_1", nvalues * sizeof(double));
660  }
661  return array;
662 }
663 /****************************************************************************/
664 /****************************************************************************/
665 /****************************************************************************/
666 
667 void mdp_safe_alloc_dbl_1(double** array_hdl, int nvalues, const double val)
668 
669 /*************************************************************************
670 *
671 * mdp_safe_alloc_dbl_1:
672 *
673 * Allocates and/or initializse a one dimensional array of doubles.
674 *
675 * Input
676 * -------
677 * *array_hdl = Previous value of pointer. If non-NULL will try
678 * to free the memory at this address.
679 * nvalues = Length of the array
680 * val = intialization value
681 * Output
682 * ------
683 * *array_hdl = This value is initialized to the correct address
684 * of the array.
685 * A NULL value in the position indicates an error.
686 **************************************************************************/
687 {
688  if (array_hdl == NULL) {
689  mdp_alloc_eh("mdp_safe_alloc_dbl_1: handle is NULL",
690  MDP_ALLOC_INTERFACE_ERROR);
691  return;
692  }
693  if (*array_hdl != NULL) {
694  mdp_safe_free((void**) array_hdl);
695  }
696  *array_hdl = mdp_alloc_dbl_1(nvalues, val);
697  if (*array_hdl == NULL) {
698  mdp_alloc_eh2("mdp_safe_alloc_dbl_1");
699  }
700 }
701 /****************************************************************************/
702 /****************************************************************************/
703 /****************************************************************************/
704 
705 void mdp_realloc_dbl_1(double** array_hdl, int new_length,
706  int old_length, const double defval)
707 
708 /*************************************************************************
709 *
710 * mdp_realloc_dbl_1_(array_hdl, new_num_ptrs, old_num_ptrs);
711 *
712 * Reallocates a one dimensional array of doubles.
713 * This routine always allocates space for at least one dbl.
714 * Calls the smalloc() routine to ensure that all malloc
715 * calls go through one location. This routine will then copy
716 * the pertinent information from the old array to the
717 * new array.
718 *
719 * Input
720 * -------
721 * array_hdl = Pointer to the global variable that
722 * holds the old and (eventually new)
723 * address of the array of doubles to be reallocated
724 * new_length = Length of the array
725 * old_length = Length of the old array
726 **************************************************************************/
727 {
728  if (new_length == old_length) {
729  return;
730  }
731  if (new_length <= 0) {
732 #ifdef MDP_MPDEBUGIO
733  fprintf(stderr, "Warning: mdp_realloc_dbl_1 P_%d: called with n = %d ",
734  MDP_MP_myproc, new_length);
735 #else
736  fprintf(stderr, "Warning: mdp_realloc_dbl_1: called with n = %d ",
737  new_length);
738 #endif
739  new_length = 1;
740  }
741  if (old_length < 0) {
742  old_length = 0;
743  }
744  if (new_length == old_length) {
745  return;
746  }
747  size_t bytenum = new_length * sizeof(double);
748  double* array = (double*) smalloc(bytenum);
749  if (array != NULL) {
750  if (*array_hdl) {
751  if (old_length > 0) {
752  bytenum = sizeof(double) * old_length;
753  } else {
754  bytenum = 0;
755  }
756  if (new_length < old_length) {
757  bytenum = sizeof(double) * new_length;
758  }
759  (void) memcpy((void*) array, (void*) *array_hdl, bytenum);
760  mdp_safe_free((void**) array_hdl);
761  } else {
762  old_length = 0;
763  }
764  *array_hdl = array;
765  if ((defval != MDP_DBL_NOINIT) && (new_length > old_length)) {
766  if (defval == 0) {
767  bytenum = sizeof(double) * (new_length - old_length);
768  (void) memset((void*)(array+old_length), 0, bytenum);
769  } else {
770  for (int i = old_length; i < new_length; i++) {
771  array[i] = defval;
772  }
773  }
774  }
775  } else {
776  mdp_alloc_eh("mdp_realloc_dbl_1", bytenum);
777  }
778 }
779 /****************************************************************************/
780 /****************************************************************************/
781 /****************************************************************************/
782 
783 char* mdp_alloc_char_1(int nvalues, const char val)
784 
785 /*************************************************************************
786 *
787 * mdp_alloc_char_1:
788 *
789 * Allocate and initialize a one dimensional array of characters.
790 *
791 * Input
792 * -------
793 * nvalues = Length of the array
794 * val = initialization value
795 * Return
796 * ------
797 * Pointer to the initialized character array
798 * Failures are indicated by returning the NULL pointer.
799 **************************************************************************/
800 {
801  int i;
802  char* array;
803  if (nvalues <= 0) {
804  nvalues = 1;
805  }
806  array = (char*) mdp_array_alloc(1, nvalues, sizeof(char));
807  if (array != NULL) {
808  for (i = 0; i < nvalues; i++) {
809  array[i] = val;
810  }
811  } else {
812  mdp_alloc_eh("mdp_alloc_char_1", nvalues * sizeof(char));
813  }
814  return array;
815 }
816 /****************************************************************************/
817 /****************************************************************************/
818 /****************************************************************************/
819 
820 void mdp_safe_alloc_char_1(char** array_hdl, int nvalues, const char val)
821 
822 /*************************************************************************
823 *
824 * mdp_safe_alloc_char_1:
825 *
826 * Allocates and/or initializse a one dimensional array of characters.
827 *
828 * Input
829 * -------
830 * array_hdl = Previous value of pointer. If non-NULL will try
831 * to free the memory at this address.
832 * nvalues = Length of the array
833 * val = intialization value
834 * Output
835 * ------
836 * *array_hdl = This value is initialized to the correct address
837 * of the array.
838 * A NULL value in the position indicates an error.
839 **************************************************************************/
840 {
841  if (array_hdl == NULL) {
842  mdp_alloc_eh("mdp_safe_alloc_char_1: handle is NULL",
843  MDP_ALLOC_INTERFACE_ERROR);
844  return;
845  }
846  if (*array_hdl != NULL) {
847  mdp_safe_free((void**) array_hdl);
848  }
849  *array_hdl = mdp_alloc_char_1(nvalues, val);
850  if (*array_hdl == NULL) {
851  mdp_alloc_eh2("mdp_safe_alloc_char_1");
852  }
853 }
854 /****************************************************************************/
855 /****************************************************************************/
856 /****************************************************************************/
857 
858 double** mdp_alloc_dbl_2(int ndim1, int ndim2, const double val)
859 
860 /*************************************************************************
861 *
862 * mdp_alloc_dbl_2:
863 *
864 * Allocate and initialize a two dimensional array of doubles.
865 *
866 * Input
867 * -------
868 * ndim1 = Length of the first dimension of the array
869 * ndim2 = Length of the second dimension of the array
870 * val = initialization value
871 * Return
872 * ------
873 * Pointer to the initialized double array
874 * Failures are indicated by returning the NULL pointer.
875 **************************************************************************/
876 {
877  int i;
878  double** array, *dptr;
879  if (ndim1 <= 0) {
880  ndim1 = 1;
881  }
882  if (ndim2 <= 0) {
883  ndim2 = 1;
884  }
885  array = (double**) mdp_array_alloc(2, ndim1, ndim2, sizeof(double));
886  if (array != NULL) {
887  if (val != MDP_DBL_NOINIT) {
888  if (val == 0.0) {
889  (void) memset((void*) array[0], 0, ndim1*ndim2 * sizeof(double));
890  } else {
891  dptr = &(array[0][0]);
892  for (i = 0; i < ndim1*ndim2; i++) {
893  dptr[i] = val;
894  }
895  }
896  }
897  } else {
898  mdp_alloc_eh("mdp_alloc_dbl_2",
899  sizeof(double) * ndim1 * ndim2 +
900  ndim1 * sizeof(void*));
901  }
902  return array;
903 }
904 /****************************************************************************/
905 /****************************************************************************/
906 /****************************************************************************/
907 
908 void mdp_safe_alloc_dbl_2(double** *array_hdl, int ndim1, int ndim2,
909  const double val)
910 
911 /*************************************************************************
912 *
913 * mdp_safe_alloc_dbl_2:
914 *
915 * Allocate and initialize a two dimensional array of doubles.
916 *
917 * Input
918 * -------
919 * *array_hdl = Previous value of pointer. If non-NULL will try
920 * to free the memory at this address.
921 * ndim1 = Length of the array
922 * ndim2 = Length of inner loop of the array
923 * val = intialization value
924 * Return
925 * ------
926 * *array_hdl = This value is initialized to the correct address
927 * of the array.
928 * A NULL value in the position indicates an error.
929 **************************************************************************/
930 {
931  if (array_hdl == NULL) {
932  mdp_alloc_eh("mdp_safe_alloc_dbl_2: handle is NULL",
933  MDP_ALLOC_INTERFACE_ERROR);
934  return;
935  }
936  if (*array_hdl != NULL) {
937  mdp_safe_free((void**) array_hdl);
938  }
939  *array_hdl = mdp_alloc_dbl_2(ndim1, ndim2, val);
940  if (*array_hdl == NULL) {
941  mdp_alloc_eh2("mdp_safe_alloc_dbl_2");
942  }
943 }
944 /****************************************************************************/
945 /****************************************************************************/
946 /****************************************************************************/
947 
948 void mdp_realloc_dbl_2(double** *array_hdl, int ndim1, int ndim2,
949  int ndim1Old, int ndim2Old, const double val)
950 
951 /*************************************************************************
952 *
953 * mdp_realloc_dbl_2:
954 *
955 * mdp_realloc_dbl_2(array_hdl, int ndim1, int ndim2,
956 * int ndim1Old, int ndim2Old, const double val)
957 *
958 * Reallocates a two dimensional array of doubles.
959 * This routine will then copy the pertinent information from
960 * the old array to the new array.
961 *
962 * If both old dimensions are set to zero or less, then this routine
963 * will free the old memory before mallocing the new memory. This may
964 * be a benefit for extremely large mallocs.
965 * In all other cases, the new and the old malloced arrays will
966 * exist for a short time together.
967 *
968 * Input
969 * -------
970 * array_hdl = Pointer to the global variable that
971 * holds the old and (eventually new)
972 * address of the array of doubles to be reallocated
973 * ndim1 = First dimension of the new array
974 * ndim2 = Second dimension of the new array
975 * ndim1Old = First dimension of the old array
976 * ndim2Old = Second dimension of the old array
977 * val = Default fill value.
978 **************************************************************************/
979 {
980  if (ndim1 <= 0) {
981  ndim1 = 1;
982  }
983  if (ndim2 <= 0) {
984  ndim2 = 1;
985  }
986  ndim1Old = std::max(ndim1Old, 0);
987  ndim2Old = std::max(ndim2Old, 0);
988  /*
989  * One way to do it, if old information isn't needed. In this algorithm
990  * the arrays are never malloced at the same time.
991  */
992  if ((*array_hdl == NULL) || (ndim1Old <= 0 && ndim2Old <= 0)) {
993  mdp_safe_free((void**) array_hdl);
994  *array_hdl = mdp_alloc_dbl_2(ndim1, ndim2, val);
995  if (*array_hdl == NULL) {
996  mdp_alloc_eh2("mdp_realloc_dbl_2");
997  }
998  }
999  /*
1000  * Other way to do when old information is available and needed
1001  */
1002  else {
1003  double** array_old = *array_hdl;
1004  *array_hdl = (double**) mdp_array_alloc(2, ndim1, ndim2, sizeof(double));
1005  if (*array_hdl == NULL) {
1006  mdp_alloc_eh2("mdp_realloc_dbl_2");
1007  } else {
1008  /*
1009  * Now, let's initialize the arrays
1010  */
1011  int ndim1Min = std::min(ndim1, ndim1Old);
1012  int ndim2Min = std::min(ndim2, ndim2Old);
1013  double** array_new = *array_hdl;
1014  /*
1015  * When the second dimensions are equal, we can copy blocks
1016  * using the very efficient bit moving kernels.
1017  */
1018  if (ndim2 == ndim2Old) {
1019  size_t sz = ndim1Min * ndim2 * sizeof(double);
1020  (void) memcpy((void*) array_new[0], (void*) array_old[0], sz);
1021  }
1022  /*
1023  * If the second dimensions aren't equal, then we have to
1024  * break up the bit operations even more
1025  */
1026  else {
1027  size_t sz = ndim2Min * sizeof(double);
1028  size_t sz2 = (ndim2 - ndim2Min) * sizeof(double);
1029  for (int i = 0; i < ndim1Min; i++) {
1030  (void) memcpy((void*) array_new[i], (void*) array_old[i], sz);
1031  if (ndim2 > ndim2Min && val != MDP_DBL_NOINIT) {
1032  if (val == 0.0) {
1033  (void) memset((void*)(array_new[i] + ndim2Min), 0, sz2);
1034  } else {
1035  double* dptr = array_new[i];
1036  for (int j = ndim2Min; j < ndim2; j++) {
1037  dptr[j] = val;
1038  }
1039  }
1040  }
1041  }
1042  }
1043  /*
1044  * finish up initializing the rest of the array
1045  */
1046  if (ndim1 > ndim1Min && val != MDP_DBL_NOINIT) {
1047  if (val == 0.0) {
1048  size_t sz = (ndim1 - ndim1Min) * ndim2 * sizeof(double);
1049  (void) memset((void*) array_new[ndim1Min], 0, sz);
1050  } else {
1051  double* dptr = array_new[ndim1Min];
1052  int num = (ndim1 - ndim1Min) * ndim2;
1053  for (int i = 0; i < num; i++) {
1054  dptr[i] = val;
1055  }
1056  }
1057  }
1058  /*
1059  * Free the old array
1060  */
1061  mdp_safe_free((void**) &array_old);
1062  }
1063  }
1064 }
1065 /****************************************************************************/
1066 /****************************************************************************/
1067 /****************************************************************************/
1068 
1069 char** mdp_alloc_VecFixedStrings(int numStrings, int lenString)
1070 
1071 /*************************************************************************
1072 *
1073 * mdp_alloc_VecFixedStrings:
1074 *
1075 * Allocate and initialize a vector of fixed-length
1076 * strings. Each string is initialized to the NULL string.
1077 *
1078 * Input
1079 * -------
1080 * numStrings = Number of strings
1081 * lenString = Length of each string including the trailing null
1082 * character
1083 * Return
1084 * ------
1085 * This value is initialized to the correct address of the array.
1086 * A NULL value in the position indicates an error.
1087 **************************************************************************/
1088 {
1089  int i;
1090  char** array;
1091  if (numStrings <= 0) {
1092  numStrings = 1;
1093  }
1094  if (lenString <= 0) {
1095  lenString = 1;
1096  }
1097  array = (char**) mdp_array_alloc(2, numStrings, lenString, sizeof(char));
1098  if (array != NULL) {
1099  for (i = 0; i < numStrings; i++) {
1100  array[i][0] = '\0';
1101  }
1102  } else {
1103  mdp_alloc_eh("mdp_alloc_VecFixedStrings",
1104  sizeof(char) * numStrings * lenString +
1105  numStrings * sizeof(void*));
1106  }
1107  return array;
1108 }
1109 /****************************************************************************/
1110 /****************************************************************************/
1111 /****************************************************************************/
1112 
1113 void mdp_realloc_VecFixedStrings(char** *array_hdl, int numStrings,
1114  int numOldStrings, int lenString)
1115 
1116 /*************************************************************************
1117 *
1118 * mdp_realloc_VecFixedStrings:
1119 *
1120 * Reallocate and initialize a vector of fixed-length
1121 * strings. Each new string is initialized to the NULL string.
1122 * old strings are copied.
1123 *
1124 * Input
1125 * -------
1126 * ***array_hdl = The pointer to the char ** location holding
1127 * the data to be reallocated.
1128 * numStrings = Number of strings
1129 * numOldStrings = Number of old strings
1130 * lenString = Length of each string including the trailing null
1131 * character
1132 **************************************************************************/
1133 {
1134  int i;
1135  char** array, **ao;
1136  if (numStrings <= 0) {
1137  numStrings = 1;
1138  }
1139  if (numStrings == numOldStrings) {
1140  return;
1141  }
1142  if (lenString <= 0) {
1143  lenString = 1;
1144  }
1145  array = (char**) mdp_array_alloc(2, numStrings, lenString, sizeof(char));
1146  if (array != NULL) {
1147  int len = std::min(numStrings, numOldStrings);
1148  ao = *array_hdl;
1149  if (ao) {
1150  for (i = 0; i < len; i++) {
1151  strncpy(array[i], ao[i], lenString);
1152  }
1153  }
1154  if (numStrings > numOldStrings) {
1155  for (i = numOldStrings; i < numStrings; i++) {
1156  array[i][0] = '\0';
1157  }
1158  }
1159  mdp_safe_free((void**) array_hdl);
1160  *array_hdl = array;
1161 
1162  } else {
1163  mdp_alloc_eh("mdp_realloc_VecFixedStrings",
1164  sizeof(char) * numStrings * lenString +
1165  numStrings * sizeof(void*));
1166  }
1167 }
1168 /****************************************************************************/
1169 /****************************************************************************/
1170 /****************************************************************************/
1171 
1172 void mdp_safe_alloc_VecFixedStrings(char** *array_hdl,
1173  int numStrings, int lenString)
1174 
1175 /*************************************************************************
1176 *
1177 * mdp_safe_alloc_VecFixedStrings
1178 *
1179 * Allocate and initialize an array of strings of fixed length
1180 *
1181 * Input
1182 * -------
1183 * *array_hdl = Previous value of pointer. If non-NULL will try
1184 * to free the memory at this address.
1185 * numStrings = Number of strings
1186 * lenString = Length of each string including the trailing null
1187 * character
1188 * Output
1189 * ------
1190 * *array_hdl = This value is initialized to the correct address
1191 * of the array.
1192 * A NULL value in the position indicates an error.
1193 **************************************************************************/
1194 {
1195  if (array_hdl == NULL) {
1196  mdp_alloc_eh("mdp_safe_alloc_VecFixedStrings: handle is NULL",
1197  MDP_ALLOC_INTERFACE_ERROR);
1198  return;
1199  }
1200  if (*array_hdl != NULL) {
1201  mdp_safe_free((void**) array_hdl);
1202  }
1203  *array_hdl = mdp_alloc_VecFixedStrings(numStrings, lenString);
1204  if (*array_hdl == NULL) {
1205  mdp_alloc_eh2("mdp_safe_alloc_VecFixedStrings");
1206  }
1207 }
1208 /****************************************************************************/
1209 /****************************************************************************/
1210 /****************************************************************************/
1211 
1212 C16_NAME* mdp_alloc_C16_NAME_1(int numStrings, const int init)
1213 
1214 /**************************************************************************
1215 *
1216 * mdp_alloc_C16_NAME_1:
1217 *
1218 * Allocate and initialize a vector of fixed-length
1219 * strings of type C16_NAME
1220 *
1221 * Input
1222 * -------
1223 * numStrings = Number of strings
1224 * init = If true, this routine initializes the space to the
1225 * space character.
1226 * Return
1227 * ------
1228 * This value is initialized to the correct address of the array.
1229 * A NULL value in the position indicates an error.
1230 **************************************************************************/
1231 {
1232  int i, j;
1233  char* c_ptr;
1234  if (numStrings <= 0) {
1235  numStrings = 1;
1236  }
1237  C16_NAME* array = (C16_NAME*) mdp_array_alloc(1, numStrings, sizeof(C16_NAME));
1238  if (array != NULL) {
1239  if (init) {
1240  for (i = 0; i < numStrings; i++) {
1241  c_ptr = (char*)(array + i);
1242  for (j = 0; j < (int) sizeof(C16_NAME); j++) {
1243  c_ptr[j] = ' ';
1244  }
1245  }
1246  }
1247  } else {
1248  mdp_alloc_eh("mdp_alloc_C16_NAME_1",
1249  sizeof(C16_NAME) * numStrings);
1250  }
1251  return array;
1252 }
1253 /****************************************************************************/
1254 /****************************************************************************/
1255 /****************************************************************************/
1256 
1257 void mdp_safe_alloc_C16_NAME_1(C16_NAME** array_hdl, int numStrings,
1258  const int init)
1259 
1260 /*************************************************************************
1261 *
1262 * mdp_safe_alloc_C16_NAME_1:
1263 *
1264 * Allocate and initialize a vector of fixed-length
1265 * strings of type C16_NAME
1266 *
1267 * Input
1268 * -------
1269 * *array_hdl = Previous value of pointer. If non-NULL will try
1270 * to free the memory at this address.
1271 * numStrings = Number of strings
1272 * init = If true, this routine initializes the space to the
1273 * space character.
1274 * Output
1275 * ------
1276 * *array_hdl = This value is initialized to the correct address
1277 * of the array.
1278 * A NULL value in the position indicates an error.
1279 **************************************************************************/
1280 {
1281  if (array_hdl == NULL) {
1282  mdp_alloc_eh("mdp_safe_alloc_C16_NAME_1: handle is NULL",
1283  MDP_ALLOC_INTERFACE_ERROR);
1284  return;
1285  }
1286  if (*array_hdl != NULL) {
1287  mdp_safe_free((void**) array_hdl);
1288  }
1289  *array_hdl = mdp_alloc_C16_NAME_1(numStrings, init);
1290  if (*array_hdl == NULL) {
1291  mdp_alloc_eh2("mdp_safe_alloc_C16_NAME_1");
1292  }
1293 }
1294 /****************************************************************************/
1295 /****************************************************************************/
1296 /****************************************************************************/
1297 
1298 void** mdp_alloc_ptr_1(int numPointers)
1299 
1300 /*************************************************************************
1301 *
1302 * mdp_alloc_ptr_1:
1303 *
1304 * Allocate and initialize a vector of pointers
1305 * of type pointer to void. All pointers are initialized to the NULL
1306 * value.
1307 *
1308 * Input
1309 * -------
1310 * numPointers = Number of pointers
1311 * Return
1312 * ------
1313 * This value is initialized to the correct address of the vector.
1314 * A NULL value in the position indicates an error.
1315 **************************************************************************/
1316 {
1317  int i;
1318  void** array;
1319  if (numPointers <= 0) {
1320  numPointers = 1;
1321  }
1322  array = (void**) mdp_array_alloc(1, numPointers, sizeof(void*));
1323  if (array != NULL) {
1324  for (i = 0; i < numPointers; i++) {
1325  array[i] = NULL;
1326  }
1327  } else {
1328  mdp_alloc_eh("mdp_alloc_ptr_1",
1329  sizeof(void*) * numPointers);
1330  }
1331  return array;
1332 }
1333 /****************************************************************************/
1334 /****************************************************************************/
1335 /****************************************************************************/
1336 
1337 void mdp_safe_alloc_ptr_1(void** *array_hdl, int numPointers)
1338 
1339 /**************************************************************************
1340 *
1341 * mdp_safe_alloc_ptr_1:
1342 *
1343 * Allocate and initialize a vector of pointers
1344 * of type pointer to void. All pointers are initialized to the NULL
1345 * value.
1346 *
1347 * Input
1348 * -------
1349 * *array_hdl = Previous value of pointer. If non-NULL will try
1350 * to free the memory at this address.
1351 * numPointers = Number of pointers
1352 * Output
1353 * ------
1354 * *array_hdl = This value is initialized to the correct address
1355 * of the array.
1356 * A NULL value in the position indicates an error.
1357 **************************************************************************/
1358 {
1359  if (array_hdl == NULL) {
1360  mdp_alloc_eh("mdp_safe_alloc_ptr_1: handle is NULL",
1361  MDP_ALLOC_INTERFACE_ERROR);
1362  return;
1363  }
1364  if (*array_hdl != NULL) {
1365  mdp_safe_free((void**) array_hdl);
1366  }
1367  *array_hdl = mdp_alloc_ptr_1(numPointers);
1368  if (*array_hdl == NULL) {
1369  mdp_alloc_eh2("mdp_safe_alloc_ptr_1");
1370  }
1371 }
1372 /****************************************************************************/
1373 /****************************************************************************/
1374 /****************************************************************************/
1375 
1376 void mdp_realloc_ptr_1(void** *array_hdl, int numLen, int numOldLen)
1377 
1378 /*************************************************************************
1379 *
1380 * mdp_realloc__ptr_1:
1381 *
1382 * Reallocate and initialize a vector of pointers
1383 * Each new pointer is initialized to NULL.
1384 * old Pointers are copied.
1385 *
1386 * Input
1387 * -------
1388 * ***array_hdl = The pointer to the char ** location holding
1389 * the data to be reallocated.
1390 * numLen = Number of strings
1391 * numOldLen = Number of old strings
1392 **************************************************************************/
1393 {
1394  if (array_hdl == NULL) {
1395  mdp_alloc_eh("mdp_safe_alloc_ptr_1: handle is NULL",
1396  MDP_ALLOC_INTERFACE_ERROR);
1397  return;
1398  }
1399  if (numLen <= 0) {
1400  numLen = 1;
1401  }
1402  if (numOldLen < 0) {
1403  numOldLen = 0;
1404  }
1405  if (numLen == numOldLen) {
1406  return;
1407  }
1408  size_t bytenum = sizeof(void*) * numLen;
1409  void** array = (void**) smalloc(bytenum);
1410  if (array != NULL) {
1411  int len = std::min(numLen, numOldLen);
1412  if (*array_hdl) {
1413  void** ao = *array_hdl;
1414  for (int i = 0; i < len; i++) {
1415  array[i] = ao[i];
1416  }
1417  } else {
1418  numOldLen = 0;
1419  }
1420  if (numLen > numOldLen) {
1421  bytenum = sizeof(void*) * (numLen - numOldLen);
1422  (void) memset((void*)(array + numOldLen), 0, bytenum);
1423  }
1424  mdp_safe_free((void**) array_hdl);
1425  *array_hdl = array;
1426  } else {
1427  mdp_alloc_eh("mdp_realloc_ptr_1", sizeof(void*) * numLen);
1428  }
1429 }
1430 
1431 /****************************************************************************/
1432 /****************************************************************************/
1433 /****************************************************************************/
1434 
1435 void*** mdp_alloc_ptr_2(int ndim1, int ndim2)
1436 
1437 /*************************************************************************
1438 *
1439 * mdp_alloc_ptr_2:
1440 *
1441 * Allocate and initialize an array of pointers
1442 * of type pointer to void. All pointers are initialized to the NULL
1443 * value.
1444 * referenced by ptrArray[ndim1][ndim2]
1445 *
1446 * Input
1447 * -------
1448 * ndim1 = Number of pointers in din 1
1449 * ndim2 = Number of pointers in dim 2
1450 * Return
1451 * ------
1452 * This value is initialized to the correct address of the vector.
1453 * A NULL value in the position indicates an error.
1454 **************************************************************************/
1455 {
1456  void** *array;
1457  if (ndim1 <= 0) {
1458  ndim1 = 1;
1459  }
1460  if (ndim2 <= 0) {
1461  ndim2 = 1;
1462  }
1463  array = (void***) mdp_array_alloc(2, ndim1, ndim2, sizeof(void*));
1464  if (array != NULL) {
1465  (void) memset((void*) array[0], 0, ndim1*ndim2 * sizeof(void*));
1466  } else {
1467  mdp_alloc_eh("mdp_alloc_ptr_2",
1468  sizeof(void*) * ndim1 * ndim2);
1469  }
1470  return array;
1471 }
1472 
1473 /****************************************************************************/
1474 /****************************************************************************/
1475 /****************************************************************************/
1476 
1477 char* mdp_copy_C16_NAME_to_string(const C16_NAME copyFrom)
1478 
1479 /*************************************************************************
1480 *
1481 * mdp_copy_C16_NAME_to_string:
1482 *
1483 * Allocates space for and copies a C16_NAME
1484 *
1485 * Input
1486 * -------
1487 * copyFrom = C16_NAME string (note, this doesn't necessarily have
1488 * to be null terminate. This is the reason for this
1489 * subroutine.
1490 * If NULL is supplied, then nothing is malloced and
1491 * a NULL value is returned.
1492 * Return
1493 * ------
1494 * This value is initialized to the correct address of the array.
1495 * A NULL value in the position either indicates an error, or
1496 * that the original pointer to the string was NULL.
1497 **************************************************************************/
1498 {
1499  /*
1500  * This routine creates a temporary string with a null terminator at the
1501  * end (assured). Then it uses mdp_copy_string() to do the work
1502  */
1503  C16_NAME_STR tmpString;
1504  if (copyFrom == NULL) {
1505  return NULL;
1506  }
1507  tmpString[sizeof(C16_NAME)] = '\0';
1508  (void) strncpy(tmpString, copyFrom, sizeof(C16_NAME));
1509  return mdp_copy_string(tmpString);
1510 }
1511 /****************************************************************************/
1512 /****************************************************************************/
1513 /****************************************************************************/
1514 
1515 char* mdp_copy_string(const char* copyFrom)
1516 
1517 /*************************************************************************
1518 *
1519 * mdp_copy_string:
1520 *
1521 * Allocates space for and copies a string
1522 *
1523 * Input
1524 * -------
1525 * copyFrom = null terminated string. If NULL is supplied, then
1526 * nothing is malloced and a NULL value is returned.
1527 * Return
1528 * ------
1529 * This value is initialized to the correct address of the array.
1530 * A NULL value in the position either indicates an error, or
1531 * that the original pointer to the string was NULL.
1532 **************************************************************************/
1533 {
1534  char* cptr;
1535  if (copyFrom == NULL) {
1536  return NULL;
1537  }
1538  cptr = (char*) mdp_array_alloc(1, strlen(copyFrom) + 1, sizeof(char));
1539  if (cptr != NULL) {
1540  (void) strcpy(cptr, copyFrom);
1541  } else {
1542  mdp_alloc_eh("mdp_copy_string", sizeof(char) * (strlen(copyFrom) + 1));
1543  }
1544  return cptr;
1545 }
1546 /****************************************************************************/
1547 /****************************************************************************/
1548 /****************************************************************************/
1549 
1550 void mdp_safe_copy_string(char** string_hdl, const char* copyFrom)
1551 
1552 /*************************************************************************
1553 *
1554 * mdp_safe_copy_string:
1555 *
1556 * Allocates space for and copies a string
1557 *
1558 * Input
1559 * -------
1560 * *string_hdl = Previous value of pointer. If non-NULL will try
1561 * to free the memory at this address.
1562 * *copyFrom = String to be copied
1563 * Output
1564 * ------
1565 * *string_hdl = Pointer to the copied string
1566 * A NULL value in the position indicates an error.
1567 **************************************************************************/
1568 {
1569  if (string_hdl == NULL) {
1570  mdp_alloc_eh("mdp_safe_copy_string: string_hdl is NULL",
1571  MDP_ALLOC_INTERFACE_ERROR);
1572  return;
1573  }
1574  if (*string_hdl != NULL) {
1575  mdp_safe_free((void**) string_hdl);
1576  }
1577  if (copyFrom == NULL) {
1578  *string_hdl = NULL;
1579  return;
1580  }
1581  *string_hdl = mdp_copy_string(copyFrom);
1582  if (*string_hdl == NULL) {
1583  mdp_alloc_eh2("mdp_safe_copy_string");
1584  }
1585  return;
1586 }
1587 /****************************************************************************/
1588 /* END of mdp_allo.cpp */
1589 /****************************************************************************/