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