xref: /petsc/include/petscstring.h (revision 9d47de495d3c23378050c1b4a410c12a375cb6c6)
1a4963045SJacob Faibussowitsch #pragma once
2bbcf679cSJacob Faibussowitsch 
3bbcf679cSJacob Faibussowitsch #include <petscsys.h>
4bbcf679cSJacob Faibussowitsch 
5bbcf679cSJacob Faibussowitsch /* SUBMANSEC = Sys */
6bbcf679cSJacob Faibussowitsch 
7bbcf679cSJacob Faibussowitsch #include <stddef.h> /* size_t */
8bbcf679cSJacob Faibussowitsch #include <string.h> /* for memcpy, memset */
9bbcf679cSJacob Faibussowitsch 
10bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscMemcmp(const void *, const void *, size_t, PetscBool *);
11bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrToArray(const char[], char, int *, char ***);
12bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrToArrayDestroy(int, char **);
13bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrcasecmp(const char[], const char[], PetscBool *);
14bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrendswithwhich(const char[], const char *const *, PetscInt *);
15bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrArrayallocpy(const char *const *, char ***);
16bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrArrayDestroy(char ***);
17bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrNArrayallocpy(PetscInt, const char *const *, char ***);
18bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrNArrayDestroy(PetscInt, char ***);
19bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrreplace(MPI_Comm, const char[], char[], size_t);
20c0d8b5b9SStefano Zampini PETSC_EXTERN PetscErrorCode PetscStrcmpAny(const char[], PetscBool *, const char[], ...);
21bbcf679cSJacob Faibussowitsch 
22bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscTokenCreate(const char[], char, PetscToken *);
23ce78bad3SBarry Smith PETSC_EXTERN PetscErrorCode PetscTokenFind(PetscToken, const char *[]);
24bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscTokenDestroy(PetscToken *);
25bbcf679cSJacob Faibussowitsch 
26bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrInList(const char[], const char[], char, PetscBool *);
27bbcf679cSJacob Faibussowitsch PETSC_EXTERN const char    *PetscBasename(const char[]);
28bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscEListFind(PetscInt, const char *const *, const char *, PetscInt *, PetscBool *);
29bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscEnumFind(const char *const *, const char *, PetscEnum *, PetscBool *);
30bbcf679cSJacob Faibussowitsch 
31d11110bcSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrcat(char[], const char[]);
32d11110bcSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrcpy(char[], const char[]);
33d11110bcSJacob Faibussowitsch 
34bbcf679cSJacob Faibussowitsch #define PetscAssertPointer_Private(ptr, arg) PetscAssert((ptr), PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Null Pointer: Parameter '" PetscStringize(ptr) "' # " PetscStringize(arg))
35bbcf679cSJacob Faibussowitsch 
36bbcf679cSJacob Faibussowitsch /*@C
3716a05f60SBarry Smith   PetscStrtolower - Converts a string to lower case
38bbcf679cSJacob Faibussowitsch 
39667f096bSBarry Smith   Not Collective, No Fortran Support
40bbcf679cSJacob Faibussowitsch 
412fe279fdSBarry Smith   Input Parameter:
42bbcf679cSJacob Faibussowitsch . a - pointer to string
43bbcf679cSJacob Faibussowitsch 
44bbcf679cSJacob Faibussowitsch   Level: intermediate
45bbcf679cSJacob Faibussowitsch 
46bbcf679cSJacob Faibussowitsch .seealso: `PetscStrtoupper()`
47bbcf679cSJacob Faibussowitsch @*/
PetscStrtolower(char a[])48bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrtolower(char a[])
49bbcf679cSJacob Faibussowitsch {
50bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
51bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
52bbcf679cSJacob Faibussowitsch   while (*a) {
53bbcf679cSJacob Faibussowitsch     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
54bbcf679cSJacob Faibussowitsch     a++;
55bbcf679cSJacob Faibussowitsch   }
56bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
57bbcf679cSJacob Faibussowitsch }
58bbcf679cSJacob Faibussowitsch 
59bbcf679cSJacob Faibussowitsch /*@C
6016a05f60SBarry Smith   PetscStrtoupper - Converts a string to upper case
61bbcf679cSJacob Faibussowitsch 
62667f096bSBarry Smith   Not Collective, No Fortran Support
63bbcf679cSJacob Faibussowitsch 
642fe279fdSBarry Smith   Input Parameter:
65bbcf679cSJacob Faibussowitsch . a - pointer to string
66bbcf679cSJacob Faibussowitsch 
67bbcf679cSJacob Faibussowitsch   Level: intermediate
68bbcf679cSJacob Faibussowitsch 
69bbcf679cSJacob Faibussowitsch .seealso: `PetscStrtolower()`
70bbcf679cSJacob Faibussowitsch @*/
PetscStrtoupper(char a[])71bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrtoupper(char a[])
72bbcf679cSJacob Faibussowitsch {
73bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
74bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
75bbcf679cSJacob Faibussowitsch   while (*a) {
76bbcf679cSJacob Faibussowitsch     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
77bbcf679cSJacob Faibussowitsch     a++;
78bbcf679cSJacob Faibussowitsch   }
79bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
80bbcf679cSJacob Faibussowitsch }
81bbcf679cSJacob Faibussowitsch 
82bbcf679cSJacob Faibussowitsch /*@C
8316a05f60SBarry Smith   PetscStrlen - Gets the length of a string
84bbcf679cSJacob Faibussowitsch 
85667f096bSBarry Smith   Not Collective, No Fortran Support
86bbcf679cSJacob Faibussowitsch 
872fe279fdSBarry Smith   Input Parameter:
88bbcf679cSJacob Faibussowitsch . s - pointer to string
89bbcf679cSJacob Faibussowitsch 
90bbcf679cSJacob Faibussowitsch   Output Parameter:
91bbcf679cSJacob Faibussowitsch . len - length in bytes
92bbcf679cSJacob Faibussowitsch 
93bbcf679cSJacob Faibussowitsch   Level: intermediate
94bbcf679cSJacob Faibussowitsch 
9595bd0b28SBarry Smith   Note:
96bbcf679cSJacob Faibussowitsch   This routine is analogous to `strlen()`. `NULL` string returns a length of zero.
97bbcf679cSJacob Faibussowitsch 
98bbcf679cSJacob Faibussowitsch .seealso: `PetscStrallocpy()`
99bbcf679cSJacob Faibussowitsch @*/
PetscStrlen(const char s[],size_t * len)100bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrlen(const char s[], size_t *len)
101bbcf679cSJacob Faibussowitsch {
102bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
103bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(len, 2);
104bbcf679cSJacob Faibussowitsch   if (s) {
105bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strlen)
106bbcf679cSJacob Faibussowitsch     *len = __builtin_strlen(s);
107bbcf679cSJacob Faibussowitsch #else
108bbcf679cSJacob Faibussowitsch     *len = strlen(s);
109bbcf679cSJacob Faibussowitsch #endif
110bbcf679cSJacob Faibussowitsch   } else {
111bbcf679cSJacob Faibussowitsch     *len = 0;
112bbcf679cSJacob Faibussowitsch   }
113bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
114bbcf679cSJacob Faibussowitsch }
115bbcf679cSJacob Faibussowitsch 
116bbcf679cSJacob Faibussowitsch /*@C
11716a05f60SBarry Smith   PetscStrallocpy - Allocates space to hold a copy of a string then copies the string into the new space
118bbcf679cSJacob Faibussowitsch 
119667f096bSBarry Smith   Not Collective, No Fortran Support
120bbcf679cSJacob Faibussowitsch 
1212fe279fdSBarry Smith   Input Parameter:
122bbcf679cSJacob Faibussowitsch . s - pointer to string
123bbcf679cSJacob Faibussowitsch 
124bbcf679cSJacob Faibussowitsch   Output Parameter:
125bbcf679cSJacob Faibussowitsch . t - the copied string
126bbcf679cSJacob Faibussowitsch 
127bbcf679cSJacob Faibussowitsch   Level: intermediate
128bbcf679cSJacob Faibussowitsch 
129bbcf679cSJacob Faibussowitsch   Notes:
130bbcf679cSJacob Faibussowitsch   `NULL` string returns a new `NULL` string.
131bbcf679cSJacob Faibussowitsch 
1320b4b7b1cSBarry Smith   Use `PetscFree()` to release the data when it is no longer needed.
1330b4b7b1cSBarry Smith 
134bbcf679cSJacob Faibussowitsch   If `t` has previously been allocated then that memory is lost, you may need to `PetscFree()`
135bbcf679cSJacob Faibussowitsch   the array before calling this routine.
136bbcf679cSJacob Faibussowitsch 
137d11110bcSJacob Faibussowitsch .seealso: `PetscStrArrayallocpy()`, `PetscStrNArrayallocpy()`
138bbcf679cSJacob Faibussowitsch @*/
PetscStrallocpy(const char s[],char * t[])139958cab43SBarry Smith static inline PetscErrorCode PetscStrallocpy(const char s[], char *t[]) PeNS
140bbcf679cSJacob Faibussowitsch {
141bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
142bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(t, 2);
143bbcf679cSJacob Faibussowitsch   *t = PETSC_NULLPTR;
144bbcf679cSJacob Faibussowitsch   if (s) {
145bbcf679cSJacob Faibussowitsch     size_t len;
146bbcf679cSJacob Faibussowitsch     char  *tmp;
147bbcf679cSJacob Faibussowitsch 
148bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(s, 1);
149bbcf679cSJacob Faibussowitsch     PetscCall(PetscStrlen(s, &len));
150bbcf679cSJacob Faibussowitsch     PetscCall(PetscMalloc1(len + 1, &tmp));
151bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_memcpy)
152bbcf679cSJacob Faibussowitsch     __builtin_memcpy(tmp, s, len);
153bbcf679cSJacob Faibussowitsch #else
154bbcf679cSJacob Faibussowitsch     memcpy(tmp, s, len);
155bbcf679cSJacob Faibussowitsch #endif
156bbcf679cSJacob Faibussowitsch     tmp[len] = '\0';
157bbcf679cSJacob Faibussowitsch     *t       = tmp;
158bbcf679cSJacob Faibussowitsch   }
159bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
160bbcf679cSJacob Faibussowitsch }
161bbcf679cSJacob Faibussowitsch 
PetscStrcmpNoError(const char a[],const char b[],PetscBool * flg)162bbcf679cSJacob Faibussowitsch static inline void PetscStrcmpNoError(const char a[], const char b[], PetscBool *flg)
163bbcf679cSJacob Faibussowitsch {
164bbcf679cSJacob Faibussowitsch   if (!a && !b) {
165bbcf679cSJacob Faibussowitsch     *flg = PETSC_TRUE;
166bbcf679cSJacob Faibussowitsch   } else if (!a || !b) {
167bbcf679cSJacob Faibussowitsch     *flg = PETSC_FALSE;
168bbcf679cSJacob Faibussowitsch   } else {
169bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strcmp)
170bbcf679cSJacob Faibussowitsch     *flg = __builtin_strcmp(a, b) ? PETSC_FALSE : PETSC_TRUE;
171bbcf679cSJacob Faibussowitsch #else
172bbcf679cSJacob Faibussowitsch     *flg = strcmp(a, b) ? PETSC_FALSE : PETSC_TRUE;
173bbcf679cSJacob Faibussowitsch #endif
174bbcf679cSJacob Faibussowitsch   }
175bbcf679cSJacob Faibussowitsch }
176bbcf679cSJacob Faibussowitsch 
177bbcf679cSJacob Faibussowitsch /*@C
17816a05f60SBarry Smith   PetscStrcmp - Compares two strings
179bbcf679cSJacob Faibussowitsch 
180667f096bSBarry Smith   Not Collective, No Fortran Support
181bbcf679cSJacob Faibussowitsch 
182bbcf679cSJacob Faibussowitsch   Input Parameters:
183bbcf679cSJacob Faibussowitsch + a - pointer to string first string
184bbcf679cSJacob Faibussowitsch - b - pointer to second string
185bbcf679cSJacob Faibussowitsch 
186bbcf679cSJacob Faibussowitsch   Output Parameter:
187bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if the two strings are equal
188bbcf679cSJacob Faibussowitsch 
189bbcf679cSJacob Faibussowitsch   Level: intermediate
190bbcf679cSJacob Faibussowitsch 
191c0d8b5b9SStefano Zampini .seealso: `PetscStrcmpAny()`, `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`
192bbcf679cSJacob Faibussowitsch @*/
PetscStrcmp(const char a[],const char b[],PetscBool * flg)193bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrcmp(const char a[], const char b[], PetscBool *flg)
194bbcf679cSJacob Faibussowitsch {
195bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
196bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
197bbcf679cSJacob Faibussowitsch   PetscStrcmpNoError(a, b, flg);
198bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
199bbcf679cSJacob Faibussowitsch }
200bbcf679cSJacob Faibussowitsch 
201363da2dcSJacob Faibussowitsch #if defined(__GNUC__) && !defined(__clang__)
202363da2dcSJacob Faibussowitsch   #if __GNUC__ >= 8
203363da2dcSJacob Faibussowitsch     #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN \
204363da2dcSJacob Faibussowitsch       do { \
205363da2dcSJacob Faibussowitsch         _Pragma("GCC diagnostic push"); \
206363da2dcSJacob Faibussowitsch         _Pragma("GCC diagnostic ignored \"-Wstringop-truncation\""); \
207363da2dcSJacob Faibussowitsch       } while (0)
208363da2dcSJacob Faibussowitsch     #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_END _Pragma("GCC diagnostic pop")
209363da2dcSJacob Faibussowitsch   #endif
210363da2dcSJacob Faibussowitsch #endif
211363da2dcSJacob Faibussowitsch 
212*beceaeb6SBarry Smith #if !defined(PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN)
213363da2dcSJacob Faibussowitsch   #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN (void)0
214363da2dcSJacob Faibussowitsch   #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_END   (void)0
215363da2dcSJacob Faibussowitsch #endif
216363da2dcSJacob Faibussowitsch 
217bbcf679cSJacob Faibussowitsch /*@C
218bbcf679cSJacob Faibussowitsch   PetscStrncpy - Copies a string up to a certain length
219bbcf679cSJacob Faibussowitsch 
220bbcf679cSJacob Faibussowitsch   Not Collective
221bbcf679cSJacob Faibussowitsch 
222bbcf679cSJacob Faibussowitsch   Input Parameters:
223bbcf679cSJacob Faibussowitsch + t - pointer to string
224bbcf679cSJacob Faibussowitsch - n - the length to copy
225bbcf679cSJacob Faibussowitsch 
226bbcf679cSJacob Faibussowitsch   Output Parameter:
227bbcf679cSJacob Faibussowitsch . s - the copied string
228bbcf679cSJacob Faibussowitsch 
229bbcf679cSJacob Faibussowitsch   Level: intermediate
230bbcf679cSJacob Faibussowitsch 
231bbcf679cSJacob Faibussowitsch   Notes:
232bbcf679cSJacob Faibussowitsch   `NULL` string returns a string starting with zero.
233bbcf679cSJacob Faibussowitsch 
234bbcf679cSJacob Faibussowitsch   If the string that is being copied is of length `n` or larger, then the entire string is not
235bbcf679cSJacob Faibussowitsch   copied and the final location of `s` is set to `NULL`. This is different then the behavior of
236bbcf679cSJacob Faibussowitsch   `strncpy()` which leaves `s` non-terminated if there is not room for the entire string.
237bbcf679cSJacob Faibussowitsch 
238b5e6e808SPierre Jolivet   Developer Note:
239bbcf679cSJacob Faibussowitsch   Should this be `PetscStrlcpy()` to reflect its behavior which is like `strlcpy()` not
240bbcf679cSJacob Faibussowitsch   `strncpy()`?
241bbcf679cSJacob Faibussowitsch 
242d11110bcSJacob Faibussowitsch .seealso: `PetscStrlcat()`, `PetscStrallocpy()`
243bbcf679cSJacob Faibussowitsch @*/
PetscStrncpy(char s[],const char t[],size_t n)244958cab43SBarry Smith static inline PetscErrorCode PetscStrncpy(char s[], const char t[], size_t n) PeNS
245bbcf679cSJacob Faibussowitsch {
246bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
247bbcf679cSJacob Faibussowitsch   if (s) PetscAssert(n, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Requires an output string of length at least 1 to hold the termination character");
248bbcf679cSJacob Faibussowitsch   if (t) {
249bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(s, 1);
250363da2dcSJacob Faibussowitsch     PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN;
251bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncpy)
2529b15cf9aSJacob Faibussowitsch     __builtin_strncpy(s, t, n);
253bbcf679cSJacob Faibussowitsch #else
2549b15cf9aSJacob Faibussowitsch     strncpy(s, t, n);
2559b15cf9aSJacob Faibussowitsch #endif
256363da2dcSJacob Faibussowitsch     PETSC_SILENCE_WSTRINGOP_TRUNCATION_END;
257bbcf679cSJacob Faibussowitsch     s[n - 1] = '\0';
258bbcf679cSJacob Faibussowitsch   } else if (s) {
259bbcf679cSJacob Faibussowitsch     s[0] = '\0';
260bbcf679cSJacob Faibussowitsch   }
261bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
262bbcf679cSJacob Faibussowitsch }
263bbcf679cSJacob Faibussowitsch 
264bbcf679cSJacob Faibussowitsch /*@C
265bbcf679cSJacob Faibussowitsch   PetscStrlcat - Concatenates a string onto a given string, up to a given length
266bbcf679cSJacob Faibussowitsch 
267667f096bSBarry Smith   Not Collective, No Fortran Support
268bbcf679cSJacob Faibussowitsch 
269bbcf679cSJacob Faibussowitsch   Input Parameters:
270bbcf679cSJacob Faibussowitsch + s - pointer to string to be added to at end
271bbcf679cSJacob Faibussowitsch . t - string to be added
272bbcf679cSJacob Faibussowitsch - n - length of the original allocated string
273bbcf679cSJacob Faibussowitsch 
274bbcf679cSJacob Faibussowitsch   Level: intermediate
275bbcf679cSJacob Faibussowitsch 
27695bd0b28SBarry Smith   Note:
277bbcf679cSJacob Faibussowitsch   Unlike the system call `strncat()`, the length passed in is the length of the
278bbcf679cSJacob Faibussowitsch   original allocated space, not the length of the left-over space. This is
279bbcf679cSJacob Faibussowitsch   similar to the BSD system call `strlcat()`.
280bbcf679cSJacob Faibussowitsch 
281d11110bcSJacob Faibussowitsch .seealso: `PetscStrncpy()`
282bbcf679cSJacob Faibussowitsch @*/
PetscStrlcat(char s[],const char t[],size_t n)283bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrlcat(char s[], const char t[], size_t n)
284bbcf679cSJacob Faibussowitsch {
285bbcf679cSJacob Faibussowitsch   size_t len;
286bbcf679cSJacob Faibussowitsch 
287bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
288bbcf679cSJacob Faibussowitsch   if (!t) PetscFunctionReturn(PETSC_SUCCESS);
289bbcf679cSJacob Faibussowitsch   PetscAssert(n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "String buffer length must be positive");
290ca7fbcdfSJacob Faibussowitsch   PetscCall(PetscStrlen(s, &len));
291363da2dcSJacob Faibussowitsch   PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN;
292bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncat)
293bbcf679cSJacob Faibussowitsch   __builtin_strncat(s, t, n - len);
294bbcf679cSJacob Faibussowitsch #else
295bbcf679cSJacob Faibussowitsch   strncat(s, t, n - len);
296bbcf679cSJacob Faibussowitsch #endif
297363da2dcSJacob Faibussowitsch   PETSC_SILENCE_WSTRINGOP_TRUNCATION_END;
298bbcf679cSJacob Faibussowitsch   s[n - 1] = '\0';
299bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
300bbcf679cSJacob Faibussowitsch }
301bbcf679cSJacob Faibussowitsch 
302363da2dcSJacob Faibussowitsch #undef PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN
303363da2dcSJacob Faibussowitsch #undef PETSC_SILENCE_WSTRINGOP_TRUNCATION_END
304363da2dcSJacob Faibussowitsch 
305bbcf679cSJacob Faibussowitsch /*@C
306bbcf679cSJacob Faibussowitsch   PetscStrncmp - Compares two strings, up to a certain length
307bbcf679cSJacob Faibussowitsch 
308667f096bSBarry Smith   Not Collective, No Fortran Support
309bbcf679cSJacob Faibussowitsch 
310bbcf679cSJacob Faibussowitsch   Input Parameters:
311bbcf679cSJacob Faibussowitsch + a - pointer to first string
312bbcf679cSJacob Faibussowitsch . b - pointer to second string
313bbcf679cSJacob Faibussowitsch - n - length to compare up to
314bbcf679cSJacob Faibussowitsch 
315bbcf679cSJacob Faibussowitsch   Output Parameter:
316bbcf679cSJacob Faibussowitsch . t - `PETSC_TRUE` if the two strings are equal, `PETSC_FALSE` otherwise
317bbcf679cSJacob Faibussowitsch 
318bbcf679cSJacob Faibussowitsch   Level: intermediate
319bbcf679cSJacob Faibussowitsch 
32016a05f60SBarry Smith   Note:
321bbcf679cSJacob Faibussowitsch   If `n` is `0`, `t` is set to `PETSC_FALSE`. `a` and/or `b` may be `NULL` in this case.
322bbcf679cSJacob Faibussowitsch 
323bbcf679cSJacob Faibussowitsch .seealso: `PetscStrgrt()`, `PetscStrcmp()`, `PetscStrcasecmp()`
324bbcf679cSJacob Faibussowitsch @*/
PetscStrncmp(const char a[],const char b[],size_t n,PetscBool * t)325bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrncmp(const char a[], const char b[], size_t n, PetscBool *t)
326bbcf679cSJacob Faibussowitsch {
327bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
328bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(t, 4);
329bbcf679cSJacob Faibussowitsch   *t = PETSC_FALSE;
330bbcf679cSJacob Faibussowitsch   if (n) {
331bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(a, 1);
332bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(b, 2);
333bbcf679cSJacob Faibussowitsch   }
334bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncmp)
335bbcf679cSJacob Faibussowitsch   *t = __builtin_strncmp(a, b, n) ? PETSC_FALSE : PETSC_TRUE;
336bbcf679cSJacob Faibussowitsch #else
337bbcf679cSJacob Faibussowitsch   *t = strncmp(a, b, n) ? PETSC_FALSE : PETSC_TRUE;
338bbcf679cSJacob Faibussowitsch #endif
339bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
340bbcf679cSJacob Faibussowitsch }
341bbcf679cSJacob Faibussowitsch 
342bbcf679cSJacob Faibussowitsch /*@C
343bbcf679cSJacob Faibussowitsch   PetscStrrstr - Locates last occurrence of string in another string
344bbcf679cSJacob Faibussowitsch 
345667f096bSBarry Smith   Not Collective, No Fortran Support
346bbcf679cSJacob Faibussowitsch 
347bbcf679cSJacob Faibussowitsch   Input Parameters:
348bbcf679cSJacob Faibussowitsch + a - pointer to string
349bbcf679cSJacob Faibussowitsch - b - string to find
350bbcf679cSJacob Faibussowitsch 
351bbcf679cSJacob Faibussowitsch   Output Parameter:
352bbcf679cSJacob Faibussowitsch . tmp - location of occurrence
353bbcf679cSJacob Faibussowitsch 
354bbcf679cSJacob Faibussowitsch   Level: intermediate
355bbcf679cSJacob Faibussowitsch 
356bbcf679cSJacob Faibussowitsch .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
357bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
358bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
359bbcf679cSJacob Faibussowitsch @*/
PetscStrrstr(const char a[],const char b[],char * tmp[])360958cab43SBarry Smith static inline PetscErrorCode PetscStrrstr(const char a[], const char b[], char *tmp[]) PeNS
361bbcf679cSJacob Faibussowitsch {
362bbcf679cSJacob Faibussowitsch   const char *ltmp = PETSC_NULLPTR;
363bbcf679cSJacob Faibussowitsch 
364bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
365bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
366bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(b, 2);
367bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(tmp, 3);
368bbcf679cSJacob Faibussowitsch   while (a) {
369bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strstr)
370bbcf679cSJacob Faibussowitsch     a = (char *)__builtin_strstr(a, b);
371bbcf679cSJacob Faibussowitsch #else
372bbcf679cSJacob Faibussowitsch     a = (char *)strstr(a, b);
373bbcf679cSJacob Faibussowitsch #endif
374bbcf679cSJacob Faibussowitsch     if (a) ltmp = a++;
375bbcf679cSJacob Faibussowitsch   }
376bbcf679cSJacob Faibussowitsch   *tmp = (char *)ltmp;
377bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
378bbcf679cSJacob Faibussowitsch }
379bbcf679cSJacob Faibussowitsch 
380bbcf679cSJacob Faibussowitsch /*@C
381bbcf679cSJacob Faibussowitsch   PetscStrstr - Locates first occurrence of string in another string
382bbcf679cSJacob Faibussowitsch 
383667f096bSBarry Smith   Not Collective, No Fortran Support
384bbcf679cSJacob Faibussowitsch 
385bbcf679cSJacob Faibussowitsch   Input Parameters:
386bbcf679cSJacob Faibussowitsch + haystack - string to search
387bbcf679cSJacob Faibussowitsch - needle   - string to find
388bbcf679cSJacob Faibussowitsch 
389bbcf679cSJacob Faibussowitsch   Output Parameter:
390bbcf679cSJacob Faibussowitsch . tmp - location of `needle` within `haystack`, `NULL` if `needle` is not found
391bbcf679cSJacob Faibussowitsch 
392bbcf679cSJacob Faibussowitsch   Level: intermediate
393bbcf679cSJacob Faibussowitsch 
394bbcf679cSJacob Faibussowitsch .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
395bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
396bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
397bbcf679cSJacob Faibussowitsch @*/
PetscStrstr(const char haystack[],const char needle[],char * tmp[])398958cab43SBarry Smith static inline PetscErrorCode PetscStrstr(const char haystack[], const char needle[], char *tmp[]) PeNS
399bbcf679cSJacob Faibussowitsch {
400bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
401bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(haystack, 1);
402bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(needle, 2);
403bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(tmp, 3);
404bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strstr)
405bbcf679cSJacob Faibussowitsch   *tmp = (char *)__builtin_strstr(haystack, needle);
406bbcf679cSJacob Faibussowitsch #else
407bbcf679cSJacob Faibussowitsch   *tmp = (char *)strstr(haystack, needle);
408bbcf679cSJacob Faibussowitsch #endif
409bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
410bbcf679cSJacob Faibussowitsch }
411bbcf679cSJacob Faibussowitsch 
412bbcf679cSJacob Faibussowitsch /*@C
413bbcf679cSJacob Faibussowitsch   PetscStrgrt - If first string is greater than the second
414bbcf679cSJacob Faibussowitsch 
415667f096bSBarry Smith   Not Collective, No Fortran Support
416bbcf679cSJacob Faibussowitsch 
417bbcf679cSJacob Faibussowitsch   Input Parameters:
418bbcf679cSJacob Faibussowitsch + a - pointer to first string
419bbcf679cSJacob Faibussowitsch - b - pointer to second string
420bbcf679cSJacob Faibussowitsch 
421bbcf679cSJacob Faibussowitsch   Output Parameter:
422bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` is strictly greater than `b`, `PETSC_FALSE` otherwise
423bbcf679cSJacob Faibussowitsch 
424bbcf679cSJacob Faibussowitsch   Level: intermediate
425bbcf679cSJacob Faibussowitsch 
42695bd0b28SBarry Smith   Note:
427bbcf679cSJacob Faibussowitsch   `NULL` arguments are OK, a `NULL` string is considered smaller than all others. If both `a`
428bbcf679cSJacob Faibussowitsch   and `b` are `NULL` then `t` is set to `PETSC_FALSE`.
429bbcf679cSJacob Faibussowitsch 
430bbcf679cSJacob Faibussowitsch .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrcasecmp()`
431bbcf679cSJacob Faibussowitsch @*/
PetscStrgrt(const char a[],const char b[],PetscBool * t)432bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrgrt(const char a[], const char b[], PetscBool *t)
433bbcf679cSJacob Faibussowitsch {
434bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
435bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(t, 3);
436bbcf679cSJacob Faibussowitsch   if (!a && !b) {
437bbcf679cSJacob Faibussowitsch     *t = PETSC_FALSE;
438bbcf679cSJacob Faibussowitsch   } else if (a && !b) {
439bbcf679cSJacob Faibussowitsch     *t = PETSC_TRUE;
440bbcf679cSJacob Faibussowitsch   } else if (!a && b) {
441bbcf679cSJacob Faibussowitsch     *t = PETSC_FALSE;
442bbcf679cSJacob Faibussowitsch   } else {
443bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strcmp)
444bbcf679cSJacob Faibussowitsch     *t = __builtin_strcmp(a, b) > 0 ? PETSC_TRUE : PETSC_FALSE;
445bbcf679cSJacob Faibussowitsch #else
446bbcf679cSJacob Faibussowitsch     *t = strcmp(a, b) > 0 ? PETSC_TRUE : PETSC_FALSE;
447bbcf679cSJacob Faibussowitsch #endif
448bbcf679cSJacob Faibussowitsch   }
449bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
450bbcf679cSJacob Faibussowitsch }
451bbcf679cSJacob Faibussowitsch 
452bbcf679cSJacob Faibussowitsch /*@C
453bbcf679cSJacob Faibussowitsch   PetscStrchr - Locates first occurrence of a character in a string
454bbcf679cSJacob Faibussowitsch 
455667f096bSBarry Smith   Not Collective, No Fortran Support
456bbcf679cSJacob Faibussowitsch 
457bbcf679cSJacob Faibussowitsch   Input Parameters:
458bbcf679cSJacob Faibussowitsch + a - pointer to string
459bbcf679cSJacob Faibussowitsch - b - character
460bbcf679cSJacob Faibussowitsch 
461bbcf679cSJacob Faibussowitsch   Output Parameter:
462bbcf679cSJacob Faibussowitsch . c - location of occurrence, `NULL` if not found
463bbcf679cSJacob Faibussowitsch 
464bbcf679cSJacob Faibussowitsch   Level: intermediate
465bbcf679cSJacob Faibussowitsch 
466bbcf679cSJacob Faibussowitsch .seealso: `PetscStrrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()`
467bbcf679cSJacob Faibussowitsch @*/
PetscStrchr(const char a[],char b,char * c[])468958cab43SBarry Smith static inline PetscErrorCode PetscStrchr(const char a[], char b, char *c[]) PeNS
469bbcf679cSJacob Faibussowitsch {
470bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
471bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
472bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(c, 3);
473bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strchr)
474bbcf679cSJacob Faibussowitsch   *c = (char *)__builtin_strchr(a, b);
475bbcf679cSJacob Faibussowitsch #else
476bbcf679cSJacob Faibussowitsch   *c = (char *)strchr(a, b);
477bbcf679cSJacob Faibussowitsch #endif
478bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
479bbcf679cSJacob Faibussowitsch }
480bbcf679cSJacob Faibussowitsch 
481bbcf679cSJacob Faibussowitsch /*@C
482bbcf679cSJacob Faibussowitsch   PetscStrrchr - Locates one location past the last occurrence of a character in a string, if
483bbcf679cSJacob Faibussowitsch   the character is not found then returns entire string
484bbcf679cSJacob Faibussowitsch 
485667f096bSBarry Smith   Not Collective, No Fortran Support
486bbcf679cSJacob Faibussowitsch 
487bbcf679cSJacob Faibussowitsch   Input Parameters:
488bbcf679cSJacob Faibussowitsch + a - pointer to string
489bbcf679cSJacob Faibussowitsch - b - character
490bbcf679cSJacob Faibussowitsch 
491bbcf679cSJacob Faibussowitsch   Output Parameter:
4928ca48ce9SPierre Jolivet . c - one past location of `b` in `a`, or `a` if `b` was not found
493bbcf679cSJacob Faibussowitsch 
494bbcf679cSJacob Faibussowitsch   Level: intermediate
495bbcf679cSJacob Faibussowitsch 
496bbcf679cSJacob Faibussowitsch .seealso: `PetscStrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()`
497bbcf679cSJacob Faibussowitsch @*/
PetscStrrchr(const char a[],char b,char * c[])498958cab43SBarry Smith static inline PetscErrorCode PetscStrrchr(const char a[], char b, char *c[]) PeNS
499bbcf679cSJacob Faibussowitsch {
500bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
501bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
5028ca48ce9SPierre Jolivet   PetscAssertPointer_Private(c, 3);
503bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strrchr)
5048ca48ce9SPierre Jolivet   *c = (char *)__builtin_strrchr(a, b);
505bbcf679cSJacob Faibussowitsch #else
5068ca48ce9SPierre Jolivet   *c = (char *)strrchr(a, b);
507bbcf679cSJacob Faibussowitsch #endif
5088ca48ce9SPierre Jolivet   if (!*c) *c = (char *)a;
5098ca48ce9SPierre Jolivet   else *c = *c + 1;
510bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
511bbcf679cSJacob Faibussowitsch }
512bbcf679cSJacob Faibussowitsch 
513bbcf679cSJacob Faibussowitsch /*@C
514bbcf679cSJacob Faibussowitsch   PetscStrendswith - Determines if a string ends with a certain string
515bbcf679cSJacob Faibussowitsch 
516667f096bSBarry Smith   Not Collective, No Fortran Support
517bbcf679cSJacob Faibussowitsch 
518bbcf679cSJacob Faibussowitsch   Input Parameters:
519bbcf679cSJacob Faibussowitsch + a - string to search
520bbcf679cSJacob Faibussowitsch - b - string to end with
521bbcf679cSJacob Faibussowitsch 
522bbcf679cSJacob Faibussowitsch   Output Parameter:
523bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` ends with `b`, `PETSC_FALSE` otherwise
524bbcf679cSJacob Faibussowitsch 
525bbcf679cSJacob Faibussowitsch   Level: intermediate
526bbcf679cSJacob Faibussowitsch 
52795bd0b28SBarry Smith   Note:
528bbcf679cSJacob Faibussowitsch   Both `a` and `b` may be `NULL` (in which case `flg` is set to `PETSC_FALSE`) bot not either.
529bbcf679cSJacob Faibussowitsch 
530bbcf679cSJacob Faibussowitsch .seealso: `PetscStrendswithwhich()`, `PetscStrbeginswith()`, `PetscStrtoupper`,
531bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
532bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
533bbcf679cSJacob Faibussowitsch @*/
PetscStrendswith(const char a[],const char b[],PetscBool * flg)534bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrendswith(const char a[], const char b[], PetscBool *flg)
535bbcf679cSJacob Faibussowitsch {
536bbcf679cSJacob Faibussowitsch   size_t na = 0, nb = 0;
537bbcf679cSJacob Faibussowitsch 
538bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
539bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
540bbcf679cSJacob Faibussowitsch   // do this here to silence stupid "may be used uninitialized"" warnings
541bbcf679cSJacob Faibussowitsch   *flg = PETSC_FALSE;
542bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(a, &na));
543bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(b, &nb));
544bbcf679cSJacob Faibussowitsch   if (na >= nb) {
545bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_memcmp)
546bbcf679cSJacob Faibussowitsch     *flg = __builtin_memcmp(b, a + (na - nb), nb) == 0 ? PETSC_TRUE : PETSC_FALSE;
547bbcf679cSJacob Faibussowitsch #else
548bbcf679cSJacob Faibussowitsch     *flg = memcmp(b, a + (na - nb), nb) == 0 ? PETSC_TRUE : PETSC_FALSE;
549bbcf679cSJacob Faibussowitsch #endif
550bbcf679cSJacob Faibussowitsch   }
551bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
552bbcf679cSJacob Faibussowitsch }
553bbcf679cSJacob Faibussowitsch 
554bbcf679cSJacob Faibussowitsch /*@C
555bbcf679cSJacob Faibussowitsch   PetscStrbeginswith - Determines if a string begins with a certain string
556bbcf679cSJacob Faibussowitsch 
557667f096bSBarry Smith   Not Collective, No Fortran Support
558bbcf679cSJacob Faibussowitsch 
559bbcf679cSJacob Faibussowitsch   Input Parameters:
560bbcf679cSJacob Faibussowitsch + a - string to search
561bbcf679cSJacob Faibussowitsch - b - string to begin with
562bbcf679cSJacob Faibussowitsch 
563bbcf679cSJacob Faibussowitsch   Output Parameter:
564bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` begins with `b`, `PETSC_FALSE` otherwise
565bbcf679cSJacob Faibussowitsch 
566bbcf679cSJacob Faibussowitsch   Level: intermediate
567bbcf679cSJacob Faibussowitsch 
568bbcf679cSJacob Faibussowitsch   Notes:
569bbcf679cSJacob Faibussowitsch   Both `a` and `b` may be `NULL` (in which case `flg` is set to `PETSC_FALSE`) but not
57016a05f60SBarry Smith   either.
57116a05f60SBarry Smith 
57216a05f60SBarry Smith   `a` and `b` may point to the same string.
573bbcf679cSJacob Faibussowitsch 
574bbcf679cSJacob Faibussowitsch .seealso: `PetscStrendswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
575bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
576bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
577bbcf679cSJacob Faibussowitsch @*/
PetscStrbeginswith(const char a[],const char b[],PetscBool * flg)578bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg)
579bbcf679cSJacob Faibussowitsch {
580bbcf679cSJacob Faibussowitsch   size_t len = 0;
581bbcf679cSJacob Faibussowitsch 
582bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
583bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
584bbcf679cSJacob Faibussowitsch   // do this here to silence stupid "may be used uninitialized"" warnings
585bbcf679cSJacob Faibussowitsch   *flg = PETSC_FALSE;
586bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(b, &len));
587bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrncmp(a, b, len, flg));
588bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
589bbcf679cSJacob Faibussowitsch }
590bbcf679cSJacob Faibussowitsch 
591bbcf679cSJacob Faibussowitsch #undef PetscAssertPointer_Private
592bbcf679cSJacob Faibussowitsch 
593bbcf679cSJacob Faibussowitsch /*@C
59416a05f60SBarry Smith    PetscMemmove - Copies `n` bytes, beginning at location `b`, to the space
59516a05f60SBarry Smith    beginning at location `a`. Copying  between regions that overlap will
596bbcf679cSJacob Faibussowitsch    take place correctly. Use `PetscMemcpy()` if the locations do not overlap
597bbcf679cSJacob Faibussowitsch 
598cc4c1da9SBarry Smith    Not Collective, No Fortran Support
599bbcf679cSJacob Faibussowitsch 
600bbcf679cSJacob Faibussowitsch    Input Parameters:
601bbcf679cSJacob Faibussowitsch +  b - pointer to initial memory space
602bbcf679cSJacob Faibussowitsch .  a - pointer to copy space
603bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of space to copy
604bbcf679cSJacob Faibussowitsch 
605bbcf679cSJacob Faibussowitsch    Level: intermediate
606bbcf679cSJacob Faibussowitsch 
607bbcf679cSJacob Faibussowitsch    Notes:
608bbcf679cSJacob Faibussowitsch    `PetscArraymove()` is preferred
609bbcf679cSJacob Faibussowitsch 
610bbcf679cSJacob Faibussowitsch    This routine is analogous to `memmove()`.
611bbcf679cSJacob Faibussowitsch 
612bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscStrallocpy()`,
613bbcf679cSJacob Faibussowitsch           `PetscArraymove()`
614bbcf679cSJacob Faibussowitsch @*/
PetscMemmove(void * a,const void * b,size_t n)615bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemmove(void *a, const void *b, size_t n)
616bbcf679cSJacob Faibussowitsch {
617bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
618bbcf679cSJacob Faibussowitsch   if (PetscUnlikely((n == 0) || (a == b))) PetscFunctionReturn(PETSC_SUCCESS);
619bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes to null pointer (Argument #1)", n);
620bbcf679cSJacob Faibussowitsch   PetscAssert(b, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes from a null pointer (Argument #2)", n);
621bbcf679cSJacob Faibussowitsch #if PetscDefined(HAVE_MEMMOVE)
622bbcf679cSJacob Faibussowitsch   memmove((char *)a, (const char *)b, n);
623bbcf679cSJacob Faibussowitsch #else
624bbcf679cSJacob Faibussowitsch   if (a < b) {
625ffdfd6a8SLisandro Dalcin     if ((char *)a <= (char *)b - n) {
626bbcf679cSJacob Faibussowitsch       memcpy(a, b, n);
627bbcf679cSJacob Faibussowitsch     } else {
628ffdfd6a8SLisandro Dalcin       const size_t ptr_diff = (size_t)((char *)b - (char *)a);
629bbcf679cSJacob Faibussowitsch 
630bbcf679cSJacob Faibussowitsch       memcpy(a, b, ptr_diff);
631ffdfd6a8SLisandro Dalcin       PetscCall(PetscMemmove((void *)b, (char *)b + ptr_diff, n - ptr_diff));
632bbcf679cSJacob Faibussowitsch     }
633bbcf679cSJacob Faibussowitsch   } else {
634ffdfd6a8SLisandro Dalcin     if ((char *)b <= (char *)a - n) {
635bbcf679cSJacob Faibussowitsch       memcpy(a, b, n);
636bbcf679cSJacob Faibussowitsch     } else {
637ffdfd6a8SLisandro Dalcin       const size_t ptr_diff = (size_t)((char *)a - (char *)b);
638bbcf679cSJacob Faibussowitsch 
639ffdfd6a8SLisandro Dalcin       memcpy((void *)((char *)b + n), (char *)b + (n - ptr_diff), ptr_diff);
640bbcf679cSJacob Faibussowitsch       PetscCall(PetscMemmove(a, b, n - ptr_diff));
641bbcf679cSJacob Faibussowitsch     }
642bbcf679cSJacob Faibussowitsch   }
643bbcf679cSJacob Faibussowitsch #endif
644bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
645bbcf679cSJacob Faibussowitsch }
646bbcf679cSJacob Faibussowitsch 
647bbcf679cSJacob Faibussowitsch /*@C
64816a05f60SBarry Smith    PetscMemcpy - Copies `n` bytes, beginning at location `b`, to the space
64916a05f60SBarry Smith    beginning at location `a`. The two memory regions CANNOT overlap, use
650bbcf679cSJacob Faibussowitsch    `PetscMemmove()` in that case.
651bbcf679cSJacob Faibussowitsch 
652cc4c1da9SBarry Smith    Not Collective, No Fortran Support
653bbcf679cSJacob Faibussowitsch 
654bbcf679cSJacob Faibussowitsch    Input Parameters:
655bbcf679cSJacob Faibussowitsch +  b - pointer to initial memory space
656bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of space to copy
657bbcf679cSJacob Faibussowitsch 
658bbcf679cSJacob Faibussowitsch    Output Parameter:
659bbcf679cSJacob Faibussowitsch .  a - pointer to copy space
660bbcf679cSJacob Faibussowitsch 
661bbcf679cSJacob Faibussowitsch    Level: intermediate
662bbcf679cSJacob Faibussowitsch 
663af27ebaaSBarry Smith    Compile Options\:
664af27ebaaSBarry Smith +  `PETSC_PREFER_DCOPY_FOR_MEMCPY` - cause the BLAS `dcopy()` routine to be used for memory copies on double precision values.
665af27ebaaSBarry Smith .  `PETSC_PREFER_COPY_FOR_MEMCPY` - cause C code to be used for memory copies on double precision values.
666af27ebaaSBarry Smith -  `PETSC_PREFER_FORTRAN_FORMEMCPY` - cause Fortran code to be used for memory copies on double precision values.
667bbcf679cSJacob Faibussowitsch 
668bbcf679cSJacob Faibussowitsch    Notes:
669bbcf679cSJacob Faibussowitsch    Prefer `PetscArraycpy()`
670bbcf679cSJacob Faibussowitsch 
671bbcf679cSJacob Faibussowitsch    This routine is analogous to `memcpy()`.
672bbcf679cSJacob Faibussowitsch 
673bbcf679cSJacob Faibussowitsch .seealso: `PetscMemzero()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`
674bbcf679cSJacob Faibussowitsch @*/
PetscMemcpy(void * a,const void * b,size_t n)675bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemcpy(void *a, const void *b, size_t n)
676bbcf679cSJacob Faibussowitsch {
677bbcf679cSJacob Faibussowitsch   const PETSC_UINTPTR_T al = (PETSC_UINTPTR_T)a;
678bbcf679cSJacob Faibussowitsch   const PETSC_UINTPTR_T bl = (PETSC_UINTPTR_T)b;
679bbcf679cSJacob Faibussowitsch 
680bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
681bbcf679cSJacob Faibussowitsch   if (PetscUnlikely((n == 0) || (a == b))) PetscFunctionReturn(PETSC_SUCCESS);
682bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes to a null pointer (Argument #1)", n);
683bbcf679cSJacob Faibussowitsch   PetscAssert(b, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes from a null pointer (Argument #2)", n);
68400045ab3SPierre Jolivet   PetscAssert(!(((al > bl) && (al - bl) < n) || (bl - al) < n), PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Memory regions overlap: either use PetscMemmove(), or make sure your copy regions and lengths are correct. Length (bytes) %zu first address %" PRIxPTR " second address %" PRIxPTR, n, al, bl);
685312eb7a1SZach Atkins #if PetscDefined(PREFER_DCOPY_FOR_MEMCPY) || PetscDefined(PREFER_COPY_FOR_MEMCPY) || PetscDefined(PREFER_FORTRAN_FORMEMCPY)
686bbcf679cSJacob Faibussowitsch   if (!(al % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
687bbcf679cSJacob Faibussowitsch     const size_t       scalar_len = n / sizeof(PetscScalar);
688bbcf679cSJacob Faibussowitsch     const PetscScalar *x          = (PetscScalar *)b;
689bbcf679cSJacob Faibussowitsch     PetscScalar       *y          = (PetscScalar *)a;
690bbcf679cSJacob Faibussowitsch 
691bbcf679cSJacob Faibussowitsch   #if PetscDefined(PREFER_DCOPY_FOR_MEMCPY)
692bbcf679cSJacob Faibussowitsch     {
693bbcf679cSJacob Faibussowitsch       const PetscBLASInt one = 1;
694bbcf679cSJacob Faibussowitsch       PetscBLASInt       blen;
695bbcf679cSJacob Faibussowitsch 
696bbcf679cSJacob Faibussowitsch       PetscCall(PetscBLASIntCast(scalar_len, &blen));
697bbcf679cSJacob Faibussowitsch       PetscCallBLAS("BLAScopy", BLAScopy_(&blen, x, &one, y, &one));
698bbcf679cSJacob Faibussowitsch     }
699bbcf679cSJacob Faibussowitsch   #elif PetscDefined(PREFER_FORTRAN_FORMEMCPY)
700bbcf679cSJacob Faibussowitsch     fortrancopy_(&scalar_len, x, y);
701bbcf679cSJacob Faibussowitsch   #else
702bbcf679cSJacob Faibussowitsch     for (size_t i = 0; i < scalar_len; i++) y[i] = x[i];
703bbcf679cSJacob Faibussowitsch   #endif
704bbcf679cSJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
705bbcf679cSJacob Faibussowitsch   }
706312eb7a1SZach Atkins #endif
707bbcf679cSJacob Faibussowitsch   memcpy(a, b, n);
708bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
709bbcf679cSJacob Faibussowitsch }
710bbcf679cSJacob Faibussowitsch 
711bbcf679cSJacob Faibussowitsch /*@C
712bbcf679cSJacob Faibussowitsch    PetscMemzero - Zeros the specified memory.
713bbcf679cSJacob Faibussowitsch 
714cc4c1da9SBarry Smith    Not Collective, No Fortran Support
715bbcf679cSJacob Faibussowitsch 
716bbcf679cSJacob Faibussowitsch    Input Parameters:
717bbcf679cSJacob Faibussowitsch +  a - pointer to beginning memory location
718bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of memory to initialize
719bbcf679cSJacob Faibussowitsch 
720bbcf679cSJacob Faibussowitsch    Level: intermediate
721bbcf679cSJacob Faibussowitsch 
722bbcf679cSJacob Faibussowitsch    Compile Option:
723bbcf679cSJacob Faibussowitsch    `PETSC_PREFER_BZERO` - on certain machines (the IBM RS6000) the bzero() routine happens
724bbcf679cSJacob Faibussowitsch    to be faster than the memset() routine. This flag causes the bzero() routine to be used.
725bbcf679cSJacob Faibussowitsch 
72695bd0b28SBarry Smith    Note:
727bbcf679cSJacob Faibussowitsch    Prefer `PetscArrayzero()`
728bbcf679cSJacob Faibussowitsch 
729bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`
730bbcf679cSJacob Faibussowitsch @*/
PetscMemzero(void * a,size_t n)731bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemzero(void *a, size_t n)
732bbcf679cSJacob Faibussowitsch {
733bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
734bbcf679cSJacob Faibussowitsch   if (PetscUnlikely(n == 0)) PetscFunctionReturn(PETSC_SUCCESS);
735bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to zero %zu bytes at a null pointer", n);
736312eb7a1SZach Atkins #if PetscDefined(PREFER_ZERO_FOR_MEMZERO) || PetscDefined(PREFER_FORTRAN_FOR_MEMZERO)
737bbcf679cSJacob Faibussowitsch   if (!(((PETSC_UINTPTR_T)a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
738bbcf679cSJacob Faibussowitsch     const size_t scalar_len = n / sizeof(PetscScalar);
739bbcf679cSJacob Faibussowitsch     PetscScalar *x          = (PetscScalar *)a;
740bbcf679cSJacob Faibussowitsch 
741312eb7a1SZach Atkins   #if PetscDefined(PREFER_ZERO_FOR_MEMZERO)
742bbcf679cSJacob Faibussowitsch     for (size_t i = 0; i < scalar_len; ++i) x[i] = 0;
743312eb7a1SZach Atkins   #elif PetscDefined(PREFER_FORTRAN_FOR_MEMZERO)
744bbcf679cSJacob Faibussowitsch     fortranzero_(&scalar_len, x);
745bbcf679cSJacob Faibussowitsch   #endif
746bbcf679cSJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
747bbcf679cSJacob Faibussowitsch   }
748312eb7a1SZach Atkins #endif
749bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_BZERO)
750bbcf679cSJacob Faibussowitsch   bzero(a, n);
751bbcf679cSJacob Faibussowitsch #else
752bbcf679cSJacob Faibussowitsch   memset(a, 0, n);
753bbcf679cSJacob Faibussowitsch #endif
754bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
755bbcf679cSJacob Faibussowitsch }
756bbcf679cSJacob Faibussowitsch 
757bbcf679cSJacob Faibussowitsch /*MC
758bbcf679cSJacob Faibussowitsch    PetscArraycmp - Compares two arrays in memory.
759bbcf679cSJacob Faibussowitsch 
760bbcf679cSJacob Faibussowitsch    Synopsis:
761bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
762bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraycmp(const anytype *str1, const anytype *str2, size_t cnt, PetscBool *e)
763bbcf679cSJacob Faibussowitsch 
764bbcf679cSJacob Faibussowitsch    Not Collective
765bbcf679cSJacob Faibussowitsch 
766bbcf679cSJacob Faibussowitsch    Input Parameters:
767bbcf679cSJacob Faibussowitsch +  str1 - First array
768bbcf679cSJacob Faibussowitsch .  str2 - Second array
769bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
770bbcf679cSJacob Faibussowitsch 
7712fe279fdSBarry Smith    Output Parameter:
772bbcf679cSJacob Faibussowitsch .   e - `PETSC_TRUE` if equal else `PETSC_FALSE`.
773bbcf679cSJacob Faibussowitsch 
774bbcf679cSJacob Faibussowitsch    Level: intermediate
775bbcf679cSJacob Faibussowitsch 
776bbcf679cSJacob Faibussowitsch    Notes:
777bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemcmp()`
778bbcf679cSJacob Faibussowitsch 
779bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
780bbcf679cSJacob Faibussowitsch 
781bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`,
782bbcf679cSJacob Faibussowitsch           `PetscArraymove()`
783bbcf679cSJacob Faibussowitsch M*/
784bbcf679cSJacob Faibussowitsch #define PetscArraycmp(str1, str2, cnt, e) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemcmp((str1), (str2), (size_t)(cnt) * sizeof(*(str1)), (e)) : PETSC_ERR_ARG_SIZ)
785bbcf679cSJacob Faibussowitsch 
786bbcf679cSJacob Faibussowitsch /*MC
787bbcf679cSJacob Faibussowitsch    PetscArraymove - Copies from one array in memory to another, the arrays may overlap. Use `PetscArraycpy()` when the arrays
788bbcf679cSJacob Faibussowitsch                     do not overlap
789bbcf679cSJacob Faibussowitsch 
790bbcf679cSJacob Faibussowitsch    Synopsis:
791bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
792bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraymove(anytype *str1, const anytype *str2, size_t cnt)
793bbcf679cSJacob Faibussowitsch 
794bbcf679cSJacob Faibussowitsch    Not Collective
795bbcf679cSJacob Faibussowitsch 
796bbcf679cSJacob Faibussowitsch    Input Parameters:
797bbcf679cSJacob Faibussowitsch +  str1 - First array
798bbcf679cSJacob Faibussowitsch .  str2 - Second array
799bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
800bbcf679cSJacob Faibussowitsch 
801bbcf679cSJacob Faibussowitsch    Level: intermediate
802bbcf679cSJacob Faibussowitsch 
803bbcf679cSJacob Faibussowitsch    Notes:
804bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemmove()`
805bbcf679cSJacob Faibussowitsch 
806bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
807bbcf679cSJacob Faibussowitsch 
808bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscArraycmp()`, `PetscStrallocpy()`
809bbcf679cSJacob Faibussowitsch M*/
810bbcf679cSJacob Faibussowitsch #define PetscArraymove(str1, str2, cnt) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemmove((str1), (str2), (size_t)(cnt) * sizeof(*(str1))) : PETSC_ERR_ARG_SIZ)
811bbcf679cSJacob Faibussowitsch 
812bbcf679cSJacob Faibussowitsch /*MC
813bbcf679cSJacob Faibussowitsch    PetscArraycpy - Copies from one array in memory to another
814bbcf679cSJacob Faibussowitsch 
815bbcf679cSJacob Faibussowitsch    Synopsis:
816bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
817bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraycpy(anytype *str1, const anytype *str2, size_t cnt)
818bbcf679cSJacob Faibussowitsch 
819bbcf679cSJacob Faibussowitsch    Not Collective
820bbcf679cSJacob Faibussowitsch 
821bbcf679cSJacob Faibussowitsch    Input Parameters:
822bbcf679cSJacob Faibussowitsch +  str1 - First array (destination)
823bbcf679cSJacob Faibussowitsch .  str2 - Second array (source)
824bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
825bbcf679cSJacob Faibussowitsch 
826bbcf679cSJacob Faibussowitsch    Level: intermediate
827bbcf679cSJacob Faibussowitsch 
828bbcf679cSJacob Faibussowitsch    Notes:
829bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemcpy()`
830bbcf679cSJacob Faibussowitsch 
831bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
832bbcf679cSJacob Faibussowitsch 
833bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraymove()`, `PetscMemmove()`, `PetscArraycmp()`, `PetscStrallocpy()`
834bbcf679cSJacob Faibussowitsch M*/
835bbcf679cSJacob Faibussowitsch #define PetscArraycpy(str1, str2, cnt) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemcpy((str1), (str2), (size_t)(cnt) * sizeof(*(str1))) : PETSC_ERR_ARG_SIZ)
836bbcf679cSJacob Faibussowitsch 
837bbcf679cSJacob Faibussowitsch /*MC
838bbcf679cSJacob Faibussowitsch    PetscArrayzero - Zeros an array in memory.
839bbcf679cSJacob Faibussowitsch 
840bbcf679cSJacob Faibussowitsch    Synopsis:
841bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
842bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArrayzero(anytype *str1, size_t cnt)
843bbcf679cSJacob Faibussowitsch 
844bbcf679cSJacob Faibussowitsch    Not Collective
845bbcf679cSJacob Faibussowitsch 
846bbcf679cSJacob Faibussowitsch    Input Parameters:
847bbcf679cSJacob Faibussowitsch +  str1 - array
848bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the array
849bbcf679cSJacob Faibussowitsch 
850bbcf679cSJacob Faibussowitsch    Level: intermediate
851bbcf679cSJacob Faibussowitsch 
85295bd0b28SBarry Smith    Note:
853bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemzero()`
854bbcf679cSJacob Faibussowitsch 
855bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscMemzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`, `PetscArraymove()`
856bbcf679cSJacob Faibussowitsch M*/
8579f0612e4SBarry Smith #define PetscArrayzero(str1, cnt) PetscMemzero((str1), ((size_t)(cnt)) * sizeof(*(str1)))
858