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