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