xref: /petsc/include/petscstring.h (revision 95bd0b288699658b2c0494283621ad75424207a4)
1a4963045SJacob Faibussowitsch #pragma once
2bbcf679cSJacob Faibussowitsch 
3bbcf679cSJacob Faibussowitsch #include <petscsystypes.h>
4bbcf679cSJacob Faibussowitsch #include <petscerror.h>
5bbcf679cSJacob Faibussowitsch #include <petscmacros.h>
6bbcf679cSJacob Faibussowitsch #include <petscsys.h>
7bbcf679cSJacob Faibussowitsch 
8bbcf679cSJacob Faibussowitsch /* SUBMANSEC = Sys */
9bbcf679cSJacob Faibussowitsch 
10bbcf679cSJacob Faibussowitsch #include <stddef.h> /* size_t */
11bbcf679cSJacob Faibussowitsch #include <string.h> /* for memcpy, memset */
12bbcf679cSJacob Faibussowitsch 
13bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscMemcmp(const void *, const void *, size_t, PetscBool *);
14bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrToArray(const char[], char, int *, char ***);
15bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrToArrayDestroy(int, char **);
16bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrcasecmp(const char[], const char[], PetscBool *);
17bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrendswithwhich(const char[], const char *const *, PetscInt *);
18bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrArrayallocpy(const char *const *, char ***);
19bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrArrayDestroy(char ***);
20bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrNArrayallocpy(PetscInt, const char *const *, char ***);
21bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrNArrayDestroy(PetscInt, char ***);
22bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrreplace(MPI_Comm, const char[], char[], size_t);
23c0d8b5b9SStefano Zampini PETSC_EXTERN PetscErrorCode PetscStrcmpAny(const char[], PetscBool *, const char[], ...);
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 
34d11110bcSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrcat(char[], const char[]);
35d11110bcSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrcpy(char[], const char[]);
36d11110bcSJacob 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
4016a05f60SBarry Smith   PetscStrtolower - Converts a string to lower case
41bbcf679cSJacob Faibussowitsch 
42667f096bSBarry Smith   Not Collective, No Fortran Support
43bbcf679cSJacob Faibussowitsch 
442fe279fdSBarry Smith   Input Parameter:
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
6316a05f60SBarry Smith   PetscStrtoupper - Converts a string to upper case
64bbcf679cSJacob Faibussowitsch 
65667f096bSBarry Smith   Not Collective, No Fortran Support
66bbcf679cSJacob Faibussowitsch 
672fe279fdSBarry Smith   Input Parameter:
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
8616a05f60SBarry Smith   PetscStrlen - Gets the length of a string
87bbcf679cSJacob Faibussowitsch 
88667f096bSBarry Smith   Not Collective, No Fortran Support
89bbcf679cSJacob Faibussowitsch 
902fe279fdSBarry Smith   Input Parameter:
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 
98*95bd0b28SBarry Smith   Note:
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
12016a05f60SBarry Smith   PetscStrallocpy - Allocates space to hold a copy of a string then copies the string into the new space
121bbcf679cSJacob Faibussowitsch 
122667f096bSBarry Smith   Not Collective, No Fortran Support
123bbcf679cSJacob Faibussowitsch 
1242fe279fdSBarry Smith   Input Parameter:
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 
138d11110bcSJacob 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
17916a05f60SBarry Smith   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 
192c0d8b5b9SStefano Zampini .seealso: `PetscStrcmpAny()`, `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 
202363da2dcSJacob Faibussowitsch #if defined(__GNUC__) && !defined(__clang__)
203363da2dcSJacob Faibussowitsch   #if __GNUC__ >= 8
204363da2dcSJacob Faibussowitsch     #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN \
205363da2dcSJacob Faibussowitsch       do { \
206363da2dcSJacob Faibussowitsch         _Pragma("GCC diagnostic push"); \
207363da2dcSJacob Faibussowitsch         _Pragma("GCC diagnostic ignored \"-Wstringop-truncation\""); \
208363da2dcSJacob Faibussowitsch       } while (0)
209363da2dcSJacob Faibussowitsch     #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_END _Pragma("GCC diagnostic pop")
210363da2dcSJacob Faibussowitsch   #endif
211363da2dcSJacob Faibussowitsch #endif
212363da2dcSJacob Faibussowitsch 
213363da2dcSJacob Faibussowitsch #ifndef PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN
214363da2dcSJacob Faibussowitsch   #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN (void)0
215363da2dcSJacob Faibussowitsch   #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_END   (void)0
216363da2dcSJacob Faibussowitsch #endif
217363da2dcSJacob Faibussowitsch 
218bbcf679cSJacob Faibussowitsch /*@C
219bbcf679cSJacob Faibussowitsch   PetscStrncpy - Copies a string up to a certain length
220bbcf679cSJacob Faibussowitsch 
221bbcf679cSJacob Faibussowitsch   Not Collective
222bbcf679cSJacob Faibussowitsch 
223bbcf679cSJacob Faibussowitsch   Input Parameters:
224bbcf679cSJacob Faibussowitsch + t - pointer to string
225bbcf679cSJacob Faibussowitsch - n - the length to copy
226bbcf679cSJacob Faibussowitsch 
227bbcf679cSJacob Faibussowitsch   Output Parameter:
228bbcf679cSJacob Faibussowitsch . s - the copied string
229bbcf679cSJacob Faibussowitsch 
230bbcf679cSJacob Faibussowitsch   Level: intermediate
231bbcf679cSJacob Faibussowitsch 
232bbcf679cSJacob Faibussowitsch   Notes:
233bbcf679cSJacob Faibussowitsch   `NULL` string returns a string starting with zero.
234bbcf679cSJacob Faibussowitsch 
235bbcf679cSJacob Faibussowitsch   If the string that is being copied is of length `n` or larger, then the entire string is not
236bbcf679cSJacob Faibussowitsch   copied and the final location of `s` is set to `NULL`. This is different then the behavior of
237bbcf679cSJacob Faibussowitsch   `strncpy()` which leaves `s` non-terminated if there is not room for the entire string.
238bbcf679cSJacob Faibussowitsch 
239*95bd0b28SBarry Smith   Developers Note:
240bbcf679cSJacob Faibussowitsch   Should this be `PetscStrlcpy()` to reflect its behavior which is like `strlcpy()` not
241bbcf679cSJacob Faibussowitsch   `strncpy()`?
242bbcf679cSJacob Faibussowitsch 
243d11110bcSJacob Faibussowitsch .seealso: `PetscStrlcat()`, `PetscStrallocpy()`
244bbcf679cSJacob Faibussowitsch @*/
245bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrncpy(char s[], const char t[], size_t n)
246bbcf679cSJacob Faibussowitsch {
247bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
248bbcf679cSJacob 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");
249bbcf679cSJacob Faibussowitsch   if (t) {
250bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(s, 1);
251363da2dcSJacob Faibussowitsch     PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN;
252bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncpy)
2539b15cf9aSJacob Faibussowitsch     __builtin_strncpy(s, t, n);
254bbcf679cSJacob Faibussowitsch #else
2559b15cf9aSJacob Faibussowitsch     strncpy(s, t, n);
2569b15cf9aSJacob Faibussowitsch #endif
257363da2dcSJacob Faibussowitsch     PETSC_SILENCE_WSTRINGOP_TRUNCATION_END;
258bbcf679cSJacob Faibussowitsch     s[n - 1] = '\0';
259bbcf679cSJacob Faibussowitsch   } else if (s) {
260bbcf679cSJacob Faibussowitsch     s[0] = '\0';
261bbcf679cSJacob Faibussowitsch   }
262bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
263bbcf679cSJacob Faibussowitsch }
264bbcf679cSJacob Faibussowitsch 
265bbcf679cSJacob Faibussowitsch /*@C
266bbcf679cSJacob Faibussowitsch   PetscStrlcat - Concatenates a string onto a given string, up to a given length
267bbcf679cSJacob Faibussowitsch 
268667f096bSBarry Smith   Not Collective, No Fortran Support
269bbcf679cSJacob Faibussowitsch 
270bbcf679cSJacob Faibussowitsch   Input Parameters:
271bbcf679cSJacob Faibussowitsch + s - pointer to string to be added to at end
272bbcf679cSJacob Faibussowitsch . t - string to be added
273bbcf679cSJacob Faibussowitsch - n - length of the original allocated string
274bbcf679cSJacob Faibussowitsch 
275bbcf679cSJacob Faibussowitsch   Level: intermediate
276bbcf679cSJacob Faibussowitsch 
277*95bd0b28SBarry Smith   Note:
278bbcf679cSJacob Faibussowitsch   Unlike the system call `strncat()`, the length passed in is the length of the
279bbcf679cSJacob Faibussowitsch   original allocated space, not the length of the left-over space. This is
280bbcf679cSJacob Faibussowitsch   similar to the BSD system call `strlcat()`.
281bbcf679cSJacob Faibussowitsch 
282d11110bcSJacob Faibussowitsch .seealso: `PetscStrncpy()`
283bbcf679cSJacob Faibussowitsch @*/
284bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrlcat(char s[], const char t[], size_t n)
285bbcf679cSJacob Faibussowitsch {
286bbcf679cSJacob Faibussowitsch   size_t len;
287bbcf679cSJacob Faibussowitsch 
288bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
289bbcf679cSJacob Faibussowitsch   if (!t) PetscFunctionReturn(PETSC_SUCCESS);
290bbcf679cSJacob Faibussowitsch   PetscAssert(n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "String buffer length must be positive");
291ca7fbcdfSJacob Faibussowitsch   PetscCall(PetscStrlen(s, &len));
292363da2dcSJacob Faibussowitsch   PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN;
293bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncat)
294bbcf679cSJacob Faibussowitsch   __builtin_strncat(s, t, n - len);
295bbcf679cSJacob Faibussowitsch #else
296bbcf679cSJacob Faibussowitsch   strncat(s, t, n - len);
297bbcf679cSJacob Faibussowitsch #endif
298363da2dcSJacob Faibussowitsch   PETSC_SILENCE_WSTRINGOP_TRUNCATION_END;
299bbcf679cSJacob Faibussowitsch   s[n - 1] = '\0';
300bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
301bbcf679cSJacob Faibussowitsch }
302bbcf679cSJacob Faibussowitsch 
303363da2dcSJacob Faibussowitsch #undef PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN
304363da2dcSJacob Faibussowitsch #undef PETSC_SILENCE_WSTRINGOP_TRUNCATION_END
305363da2dcSJacob Faibussowitsch 
306bbcf679cSJacob Faibussowitsch /*@C
307bbcf679cSJacob Faibussowitsch   PetscStrncmp - Compares two strings, up to a certain length
308bbcf679cSJacob Faibussowitsch 
309667f096bSBarry Smith   Not Collective, No Fortran Support
310bbcf679cSJacob Faibussowitsch 
311bbcf679cSJacob Faibussowitsch   Input Parameters:
312bbcf679cSJacob Faibussowitsch + a - pointer to first string
313bbcf679cSJacob Faibussowitsch . b - pointer to second string
314bbcf679cSJacob Faibussowitsch - n - length to compare up to
315bbcf679cSJacob Faibussowitsch 
316bbcf679cSJacob Faibussowitsch   Output Parameter:
317bbcf679cSJacob Faibussowitsch . t - `PETSC_TRUE` if the two strings are equal, `PETSC_FALSE` otherwise
318bbcf679cSJacob Faibussowitsch 
319bbcf679cSJacob Faibussowitsch   Level: intermediate
320bbcf679cSJacob Faibussowitsch 
32116a05f60SBarry Smith   Note:
322bbcf679cSJacob Faibussowitsch   If `n` is `0`, `t` is set to `PETSC_FALSE`. `a` and/or `b` may be `NULL` in this case.
323bbcf679cSJacob Faibussowitsch 
324bbcf679cSJacob Faibussowitsch .seealso: `PetscStrgrt()`, `PetscStrcmp()`, `PetscStrcasecmp()`
325bbcf679cSJacob Faibussowitsch @*/
326bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrncmp(const char a[], const char b[], size_t n, PetscBool *t)
327bbcf679cSJacob Faibussowitsch {
328bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
329bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(t, 4);
330bbcf679cSJacob Faibussowitsch   *t = PETSC_FALSE;
331bbcf679cSJacob Faibussowitsch   if (n) {
332bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(a, 1);
333bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(b, 2);
334bbcf679cSJacob Faibussowitsch   }
335bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncmp)
336bbcf679cSJacob Faibussowitsch   *t = __builtin_strncmp(a, b, n) ? PETSC_FALSE : PETSC_TRUE;
337bbcf679cSJacob Faibussowitsch #else
338bbcf679cSJacob Faibussowitsch   *t = strncmp(a, b, n) ? PETSC_FALSE : PETSC_TRUE;
339bbcf679cSJacob Faibussowitsch #endif
340bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
341bbcf679cSJacob Faibussowitsch }
342bbcf679cSJacob Faibussowitsch 
343bbcf679cSJacob Faibussowitsch /*@C
344bbcf679cSJacob Faibussowitsch   PetscStrrstr - Locates last occurrence of string in another string
345bbcf679cSJacob Faibussowitsch 
346667f096bSBarry Smith   Not Collective, No Fortran Support
347bbcf679cSJacob Faibussowitsch 
348bbcf679cSJacob Faibussowitsch   Input Parameters:
349bbcf679cSJacob Faibussowitsch + a - pointer to string
350bbcf679cSJacob Faibussowitsch - b - string to find
351bbcf679cSJacob Faibussowitsch 
352bbcf679cSJacob Faibussowitsch   Output Parameter:
353bbcf679cSJacob Faibussowitsch . tmp - location of occurrence
354bbcf679cSJacob Faibussowitsch 
355bbcf679cSJacob Faibussowitsch   Level: intermediate
356bbcf679cSJacob Faibussowitsch 
357bbcf679cSJacob Faibussowitsch .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
358bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
359bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
360bbcf679cSJacob Faibussowitsch @*/
361bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrrstr(const char a[], const char b[], char *tmp[])
362bbcf679cSJacob Faibussowitsch {
363bbcf679cSJacob Faibussowitsch   const char *ltmp = PETSC_NULLPTR;
364bbcf679cSJacob Faibussowitsch 
365bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
366bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
367bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(b, 2);
368bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(tmp, 3);
369bbcf679cSJacob Faibussowitsch   while (a) {
370bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strstr)
371bbcf679cSJacob Faibussowitsch     a = (char *)__builtin_strstr(a, b);
372bbcf679cSJacob Faibussowitsch #else
373bbcf679cSJacob Faibussowitsch     a = (char *)strstr(a, b);
374bbcf679cSJacob Faibussowitsch #endif
375bbcf679cSJacob Faibussowitsch     if (a) ltmp = a++;
376bbcf679cSJacob Faibussowitsch   }
377bbcf679cSJacob Faibussowitsch   *tmp = (char *)ltmp;
378bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
379bbcf679cSJacob Faibussowitsch }
380bbcf679cSJacob Faibussowitsch 
381bbcf679cSJacob Faibussowitsch /*@C
382bbcf679cSJacob Faibussowitsch   PetscStrstr - Locates first occurrence of string in another string
383bbcf679cSJacob Faibussowitsch 
384667f096bSBarry Smith   Not Collective, No Fortran Support
385bbcf679cSJacob Faibussowitsch 
386bbcf679cSJacob Faibussowitsch   Input Parameters:
387bbcf679cSJacob Faibussowitsch + haystack - string to search
388bbcf679cSJacob Faibussowitsch - needle   - string to find
389bbcf679cSJacob Faibussowitsch 
390bbcf679cSJacob Faibussowitsch   Output Parameter:
391bbcf679cSJacob Faibussowitsch . tmp - location of `needle` within `haystack`, `NULL` if `needle` is not found
392bbcf679cSJacob Faibussowitsch 
393bbcf679cSJacob Faibussowitsch   Level: intermediate
394bbcf679cSJacob Faibussowitsch 
395bbcf679cSJacob Faibussowitsch .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
396bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
397bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
398bbcf679cSJacob Faibussowitsch @*/
399bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrstr(const char haystack[], const char needle[], char *tmp[])
400bbcf679cSJacob Faibussowitsch {
401bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
402bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(haystack, 1);
403bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(needle, 2);
404bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(tmp, 3);
405bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strstr)
406bbcf679cSJacob Faibussowitsch   *tmp = (char *)__builtin_strstr(haystack, needle);
407bbcf679cSJacob Faibussowitsch #else
408bbcf679cSJacob Faibussowitsch   *tmp = (char *)strstr(haystack, needle);
409bbcf679cSJacob Faibussowitsch #endif
410bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
411bbcf679cSJacob Faibussowitsch }
412bbcf679cSJacob Faibussowitsch 
413bbcf679cSJacob Faibussowitsch /*@C
414bbcf679cSJacob Faibussowitsch   PetscStrgrt - If first string is greater than the second
415bbcf679cSJacob Faibussowitsch 
416667f096bSBarry Smith   Not Collective, No Fortran Support
417bbcf679cSJacob Faibussowitsch 
418bbcf679cSJacob Faibussowitsch   Input Parameters:
419bbcf679cSJacob Faibussowitsch + a - pointer to first string
420bbcf679cSJacob Faibussowitsch - b - pointer to second string
421bbcf679cSJacob Faibussowitsch 
422bbcf679cSJacob Faibussowitsch   Output Parameter:
423bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` is strictly greater than `b`, `PETSC_FALSE` otherwise
424bbcf679cSJacob Faibussowitsch 
425bbcf679cSJacob Faibussowitsch   Level: intermediate
426bbcf679cSJacob Faibussowitsch 
427*95bd0b28SBarry Smith   Note:
428bbcf679cSJacob Faibussowitsch   `NULL` arguments are OK, a `NULL` string is considered smaller than all others. If both `a`
429bbcf679cSJacob Faibussowitsch   and `b` are `NULL` then `t` is set to `PETSC_FALSE`.
430bbcf679cSJacob Faibussowitsch 
431bbcf679cSJacob Faibussowitsch .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrcasecmp()`
432bbcf679cSJacob Faibussowitsch @*/
433bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrgrt(const char a[], const char b[], PetscBool *t)
434bbcf679cSJacob Faibussowitsch {
435bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
436bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(t, 3);
437bbcf679cSJacob Faibussowitsch   if (!a && !b) {
438bbcf679cSJacob Faibussowitsch     *t = PETSC_FALSE;
439bbcf679cSJacob Faibussowitsch   } else if (a && !b) {
440bbcf679cSJacob Faibussowitsch     *t = PETSC_TRUE;
441bbcf679cSJacob Faibussowitsch   } else if (!a && b) {
442bbcf679cSJacob Faibussowitsch     *t = PETSC_FALSE;
443bbcf679cSJacob Faibussowitsch   } else {
444bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strcmp)
445bbcf679cSJacob Faibussowitsch     *t = __builtin_strcmp(a, b) > 0 ? PETSC_TRUE : PETSC_FALSE;
446bbcf679cSJacob Faibussowitsch #else
447bbcf679cSJacob Faibussowitsch     *t = strcmp(a, b) > 0 ? PETSC_TRUE : PETSC_FALSE;
448bbcf679cSJacob Faibussowitsch #endif
449bbcf679cSJacob Faibussowitsch   }
450bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
451bbcf679cSJacob Faibussowitsch }
452bbcf679cSJacob Faibussowitsch 
453bbcf679cSJacob Faibussowitsch /*@C
454bbcf679cSJacob Faibussowitsch   PetscStrchr - Locates first occurrence of a character in a string
455bbcf679cSJacob Faibussowitsch 
456667f096bSBarry Smith   Not Collective, No Fortran Support
457bbcf679cSJacob Faibussowitsch 
458bbcf679cSJacob Faibussowitsch   Input Parameters:
459bbcf679cSJacob Faibussowitsch + a - pointer to string
460bbcf679cSJacob Faibussowitsch - b - character
461bbcf679cSJacob Faibussowitsch 
462bbcf679cSJacob Faibussowitsch   Output Parameter:
463bbcf679cSJacob Faibussowitsch . c - location of occurrence, `NULL` if not found
464bbcf679cSJacob Faibussowitsch 
465bbcf679cSJacob Faibussowitsch   Level: intermediate
466bbcf679cSJacob Faibussowitsch 
467bbcf679cSJacob Faibussowitsch .seealso: `PetscStrrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()`
468bbcf679cSJacob Faibussowitsch @*/
469bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrchr(const char a[], char b, char *c[])
470bbcf679cSJacob Faibussowitsch {
471bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
472bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
473bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(c, 3);
474bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strchr)
475bbcf679cSJacob Faibussowitsch   *c = (char *)__builtin_strchr(a, b);
476bbcf679cSJacob Faibussowitsch #else
477bbcf679cSJacob Faibussowitsch   *c = (char *)strchr(a, b);
478bbcf679cSJacob Faibussowitsch #endif
479bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
480bbcf679cSJacob Faibussowitsch }
481bbcf679cSJacob Faibussowitsch 
482bbcf679cSJacob Faibussowitsch /*@C
483bbcf679cSJacob Faibussowitsch   PetscStrrchr - Locates one location past the last occurrence of a character in a string, if
484bbcf679cSJacob Faibussowitsch   the character is not found then returns entire string
485bbcf679cSJacob Faibussowitsch 
486667f096bSBarry Smith   Not Collective, No Fortran Support
487bbcf679cSJacob Faibussowitsch 
488bbcf679cSJacob Faibussowitsch   Input Parameters:
489bbcf679cSJacob Faibussowitsch + a - pointer to string
490bbcf679cSJacob Faibussowitsch - b - character
491bbcf679cSJacob Faibussowitsch 
492bbcf679cSJacob Faibussowitsch   Output Parameter:
4938ca48ce9SPierre Jolivet . c - one past location of `b` in `a`, or `a` if `b` was not found
494bbcf679cSJacob Faibussowitsch 
495bbcf679cSJacob Faibussowitsch   Level: intermediate
496bbcf679cSJacob Faibussowitsch 
497bbcf679cSJacob Faibussowitsch .seealso: `PetscStrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()`
498bbcf679cSJacob Faibussowitsch @*/
4998ca48ce9SPierre Jolivet static inline PetscErrorCode PetscStrrchr(const char a[], char b, char *c[])
500bbcf679cSJacob Faibussowitsch {
501bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
502bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
5038ca48ce9SPierre Jolivet   PetscAssertPointer_Private(c, 3);
504bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strrchr)
5058ca48ce9SPierre Jolivet   *c = (char *)__builtin_strrchr(a, b);
506bbcf679cSJacob Faibussowitsch #else
5078ca48ce9SPierre Jolivet   *c = (char *)strrchr(a, b);
508bbcf679cSJacob Faibussowitsch #endif
5098ca48ce9SPierre Jolivet   if (!*c) *c = (char *)a;
5108ca48ce9SPierre Jolivet   else *c = *c + 1;
511bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
512bbcf679cSJacob Faibussowitsch }
513bbcf679cSJacob Faibussowitsch 
514bbcf679cSJacob Faibussowitsch /*@C
515bbcf679cSJacob Faibussowitsch   PetscStrendswith - Determines if a string ends with a certain string
516bbcf679cSJacob Faibussowitsch 
517667f096bSBarry Smith   Not Collective, No Fortran Support
518bbcf679cSJacob Faibussowitsch 
519bbcf679cSJacob Faibussowitsch   Input Parameters:
520bbcf679cSJacob Faibussowitsch + a - string to search
521bbcf679cSJacob Faibussowitsch - b - string to end with
522bbcf679cSJacob Faibussowitsch 
523bbcf679cSJacob Faibussowitsch   Output Parameter:
524bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` ends with `b`, `PETSC_FALSE` otherwise
525bbcf679cSJacob Faibussowitsch 
526bbcf679cSJacob Faibussowitsch   Level: intermediate
527bbcf679cSJacob Faibussowitsch 
528*95bd0b28SBarry Smith   Note:
529bbcf679cSJacob Faibussowitsch   Both `a` and `b` may be `NULL` (in which case `flg` is set to `PETSC_FALSE`) bot not either.
530bbcf679cSJacob Faibussowitsch 
531bbcf679cSJacob Faibussowitsch .seealso: `PetscStrendswithwhich()`, `PetscStrbeginswith()`, `PetscStrtoupper`,
532bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
533bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
534bbcf679cSJacob Faibussowitsch @*/
535bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrendswith(const char a[], const char b[], PetscBool *flg)
536bbcf679cSJacob Faibussowitsch {
537bbcf679cSJacob Faibussowitsch   size_t na = 0, nb = 0;
538bbcf679cSJacob Faibussowitsch 
539bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
540bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
541bbcf679cSJacob Faibussowitsch   // do this here to silence stupid "may be used uninitialized"" warnings
542bbcf679cSJacob Faibussowitsch   *flg = PETSC_FALSE;
543bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(a, &na));
544bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(b, &nb));
545bbcf679cSJacob Faibussowitsch   if (na >= nb) {
546bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_memcmp)
547bbcf679cSJacob Faibussowitsch     *flg = __builtin_memcmp(b, a + (na - nb), nb) == 0 ? PETSC_TRUE : PETSC_FALSE;
548bbcf679cSJacob Faibussowitsch #else
549bbcf679cSJacob Faibussowitsch     *flg = memcmp(b, a + (na - nb), nb) == 0 ? PETSC_TRUE : PETSC_FALSE;
550bbcf679cSJacob Faibussowitsch #endif
551bbcf679cSJacob Faibussowitsch   }
552bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
553bbcf679cSJacob Faibussowitsch }
554bbcf679cSJacob Faibussowitsch 
555bbcf679cSJacob Faibussowitsch /*@C
556bbcf679cSJacob Faibussowitsch   PetscStrbeginswith - Determines if a string begins with a certain string
557bbcf679cSJacob Faibussowitsch 
558667f096bSBarry Smith   Not Collective, No Fortran Support
559bbcf679cSJacob Faibussowitsch 
560bbcf679cSJacob Faibussowitsch   Input Parameters:
561bbcf679cSJacob Faibussowitsch + a - string to search
562bbcf679cSJacob Faibussowitsch - b - string to begin with
563bbcf679cSJacob Faibussowitsch 
564bbcf679cSJacob Faibussowitsch   Output Parameter:
565bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` begins with `b`, `PETSC_FALSE` otherwise
566bbcf679cSJacob Faibussowitsch 
567bbcf679cSJacob Faibussowitsch   Level: intermediate
568bbcf679cSJacob Faibussowitsch 
569bbcf679cSJacob Faibussowitsch   Notes:
570bbcf679cSJacob Faibussowitsch   Both `a` and `b` may be `NULL` (in which case `flg` is set to `PETSC_FALSE`) but not
57116a05f60SBarry Smith   either.
57216a05f60SBarry Smith 
57316a05f60SBarry Smith   `a` and `b` may point to the same string.
574bbcf679cSJacob Faibussowitsch 
575bbcf679cSJacob Faibussowitsch .seealso: `PetscStrendswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
576bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
577bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
578bbcf679cSJacob Faibussowitsch @*/
579bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg)
580bbcf679cSJacob Faibussowitsch {
581bbcf679cSJacob Faibussowitsch   size_t len = 0;
582bbcf679cSJacob Faibussowitsch 
583bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
584bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
585bbcf679cSJacob Faibussowitsch   // do this here to silence stupid "may be used uninitialized"" warnings
586bbcf679cSJacob Faibussowitsch   *flg = PETSC_FALSE;
587bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(b, &len));
588bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrncmp(a, b, len, flg));
589bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
590bbcf679cSJacob Faibussowitsch }
591bbcf679cSJacob Faibussowitsch 
592bbcf679cSJacob Faibussowitsch #undef PetscAssertPointer_Private
593bbcf679cSJacob Faibussowitsch 
594bbcf679cSJacob Faibussowitsch /*@C
59516a05f60SBarry Smith    PetscMemmove - Copies `n` bytes, beginning at location `b`, to the space
59616a05f60SBarry Smith    beginning at location `a`. Copying  between regions that overlap will
597bbcf679cSJacob Faibussowitsch    take place correctly. Use `PetscMemcpy()` if the locations do not overlap
598bbcf679cSJacob Faibussowitsch 
599bbcf679cSJacob Faibussowitsch    Not Collective
600bbcf679cSJacob Faibussowitsch 
601bbcf679cSJacob Faibussowitsch    Input Parameters:
602bbcf679cSJacob Faibussowitsch +  b - pointer to initial memory space
603bbcf679cSJacob Faibussowitsch .  a - pointer to copy space
604bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of space to copy
605bbcf679cSJacob Faibussowitsch 
606bbcf679cSJacob Faibussowitsch    Level: intermediate
607bbcf679cSJacob Faibussowitsch 
608bbcf679cSJacob Faibussowitsch    Notes:
609bbcf679cSJacob Faibussowitsch    `PetscArraymove()` is preferred
610bbcf679cSJacob Faibussowitsch 
611bbcf679cSJacob Faibussowitsch    This routine is analogous to `memmove()`.
612bbcf679cSJacob Faibussowitsch 
613bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscStrallocpy()`,
614bbcf679cSJacob Faibussowitsch           `PetscArraymove()`
615bbcf679cSJacob Faibussowitsch @*/
616bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemmove(void *a, const void *b, size_t n)
617bbcf679cSJacob Faibussowitsch {
618bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
619bbcf679cSJacob Faibussowitsch   if (PetscUnlikely((n == 0) || (a == b))) PetscFunctionReturn(PETSC_SUCCESS);
620bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes to null pointer (Argument #1)", n);
621bbcf679cSJacob Faibussowitsch   PetscAssert(b, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes from a null pointer (Argument #2)", n);
622bbcf679cSJacob Faibussowitsch #if PetscDefined(HAVE_MEMMOVE)
623bbcf679cSJacob Faibussowitsch   memmove((char *)a, (const char *)b, n);
624bbcf679cSJacob Faibussowitsch #else
625bbcf679cSJacob Faibussowitsch   if (a < b) {
626ffdfd6a8SLisandro Dalcin     if ((char *)a <= (char *)b - n) {
627bbcf679cSJacob Faibussowitsch       memcpy(a, b, n);
628bbcf679cSJacob Faibussowitsch     } else {
629ffdfd6a8SLisandro Dalcin       const size_t ptr_diff = (size_t)((char *)b - (char *)a);
630bbcf679cSJacob Faibussowitsch 
631bbcf679cSJacob Faibussowitsch       memcpy(a, b, ptr_diff);
632ffdfd6a8SLisandro Dalcin       PetscCall(PetscMemmove((void *)b, (char *)b + ptr_diff, n - ptr_diff));
633bbcf679cSJacob Faibussowitsch     }
634bbcf679cSJacob Faibussowitsch   } else {
635ffdfd6a8SLisandro Dalcin     if ((char *)b <= (char *)a - n) {
636bbcf679cSJacob Faibussowitsch       memcpy(a, b, n);
637bbcf679cSJacob Faibussowitsch     } else {
638ffdfd6a8SLisandro Dalcin       const size_t ptr_diff = (size_t)((char *)a - (char *)b);
639bbcf679cSJacob Faibussowitsch 
640ffdfd6a8SLisandro Dalcin       memcpy((void *)((char *)b + n), (char *)b + (n - ptr_diff), ptr_diff);
641bbcf679cSJacob Faibussowitsch       PetscCall(PetscMemmove(a, b, n - ptr_diff));
642bbcf679cSJacob Faibussowitsch     }
643bbcf679cSJacob Faibussowitsch   }
644bbcf679cSJacob Faibussowitsch #endif
645bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
646bbcf679cSJacob Faibussowitsch }
647bbcf679cSJacob Faibussowitsch 
648bbcf679cSJacob Faibussowitsch /*@C
64916a05f60SBarry Smith    PetscMemcpy - Copies `n` bytes, beginning at location `b`, to the space
65016a05f60SBarry Smith    beginning at location `a`. The two memory regions CANNOT overlap, use
651bbcf679cSJacob Faibussowitsch    `PetscMemmove()` in that case.
652bbcf679cSJacob Faibussowitsch 
653bbcf679cSJacob Faibussowitsch    Not Collective
654bbcf679cSJacob Faibussowitsch 
655bbcf679cSJacob Faibussowitsch    Input Parameters:
656bbcf679cSJacob Faibussowitsch +  b - pointer to initial memory space
657bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of space to copy
658bbcf679cSJacob Faibussowitsch 
659bbcf679cSJacob Faibussowitsch    Output Parameter:
660bbcf679cSJacob Faibussowitsch .  a - pointer to copy space
661bbcf679cSJacob Faibussowitsch 
662bbcf679cSJacob Faibussowitsch    Level: intermediate
663bbcf679cSJacob Faibussowitsch 
664bbcf679cSJacob Faibussowitsch    Compile Option:
66516a05f60SBarry Smith     `PETSC_PREFER_DCOPY_FOR_MEMCPY` will cause the BLAS `dcopy()` routine to be used
666bbcf679cSJacob Faibussowitsch                                   for memory copies on double precision values.
667bbcf679cSJacob Faibussowitsch     `PETSC_PREFER_COPY_FOR_MEMCPY` will cause C code to be used
668bbcf679cSJacob Faibussowitsch                                   for memory copies on double precision values.
669bbcf679cSJacob Faibussowitsch     `PETSC_PREFER_FORTRAN_FORMEMCPY` will cause Fortran code to be used
670bbcf679cSJacob Faibussowitsch                                   for memory copies on double precision values.
671bbcf679cSJacob Faibussowitsch 
672bbcf679cSJacob Faibussowitsch    Notes:
673bbcf679cSJacob Faibussowitsch    Prefer `PetscArraycpy()`
674bbcf679cSJacob Faibussowitsch 
675bbcf679cSJacob Faibussowitsch    This routine is analogous to `memcpy()`.
676bbcf679cSJacob Faibussowitsch 
677bbcf679cSJacob Faibussowitsch .seealso: `PetscMemzero()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`
678bbcf679cSJacob Faibussowitsch @*/
679bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemcpy(void *a, const void *b, size_t n)
680bbcf679cSJacob Faibussowitsch {
681bbcf679cSJacob Faibussowitsch   const PETSC_UINTPTR_T al = (PETSC_UINTPTR_T)a;
682bbcf679cSJacob Faibussowitsch   const PETSC_UINTPTR_T bl = (PETSC_UINTPTR_T)b;
683bbcf679cSJacob Faibussowitsch 
684bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
685bbcf679cSJacob Faibussowitsch   if (PetscUnlikely((n == 0) || (a == b))) PetscFunctionReturn(PETSC_SUCCESS);
686bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes to a null pointer (Argument #1)", n);
687bbcf679cSJacob Faibussowitsch   PetscAssert(b, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes from a null pointer (Argument #2)", n);
688bbcf679cSJacob 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);
689bbcf679cSJacob Faibussowitsch   if (PetscDefined(PREFER_DCOPY_FOR_MEMCPY) || PetscDefined(PREFER_COPY_FOR_MEMCPY) || PetscDefined(PREFER_FORTRAN_FORMEMCPY)) {
690bbcf679cSJacob Faibussowitsch     if (!(al % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
691bbcf679cSJacob Faibussowitsch       const size_t       scalar_len = n / sizeof(PetscScalar);
692bbcf679cSJacob Faibussowitsch       const PetscScalar *x          = (PetscScalar *)b;
693bbcf679cSJacob Faibussowitsch       PetscScalar       *y          = (PetscScalar *)a;
694bbcf679cSJacob Faibussowitsch 
695bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_DCOPY_FOR_MEMCPY)
696bbcf679cSJacob Faibussowitsch       {
697bbcf679cSJacob Faibussowitsch         const PetscBLASInt one = 1;
698bbcf679cSJacob Faibussowitsch         PetscBLASInt       blen;
699bbcf679cSJacob Faibussowitsch 
700bbcf679cSJacob Faibussowitsch         PetscCall(PetscBLASIntCast(scalar_len, &blen));
701bbcf679cSJacob Faibussowitsch         PetscCallBLAS("BLAScopy", BLAScopy_(&blen, x, &one, y, &one));
702bbcf679cSJacob Faibussowitsch       }
703bbcf679cSJacob Faibussowitsch #elif PetscDefined(PREFER_FORTRAN_FORMEMCPY)
704bbcf679cSJacob Faibussowitsch       fortrancopy_(&scalar_len, x, y);
705bbcf679cSJacob Faibussowitsch #else
706bbcf679cSJacob Faibussowitsch       for (size_t i = 0; i < scalar_len; i++) y[i] = x[i];
707bbcf679cSJacob Faibussowitsch #endif
708bbcf679cSJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
709bbcf679cSJacob Faibussowitsch     }
710bbcf679cSJacob Faibussowitsch   }
711bbcf679cSJacob Faibussowitsch   memcpy(a, b, n);
712bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
713bbcf679cSJacob Faibussowitsch }
714bbcf679cSJacob Faibussowitsch 
715bbcf679cSJacob Faibussowitsch /*@C
716bbcf679cSJacob Faibussowitsch    PetscMemzero - Zeros the specified memory.
717bbcf679cSJacob Faibussowitsch 
718bbcf679cSJacob Faibussowitsch    Not Collective
719bbcf679cSJacob Faibussowitsch 
720bbcf679cSJacob Faibussowitsch    Input Parameters:
721bbcf679cSJacob Faibussowitsch +  a - pointer to beginning memory location
722bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of memory to initialize
723bbcf679cSJacob Faibussowitsch 
724bbcf679cSJacob Faibussowitsch    Level: intermediate
725bbcf679cSJacob Faibussowitsch 
726bbcf679cSJacob Faibussowitsch    Compile Option:
727bbcf679cSJacob Faibussowitsch    `PETSC_PREFER_BZERO` - on certain machines (the IBM RS6000) the bzero() routine happens
728bbcf679cSJacob Faibussowitsch   to be faster than the memset() routine. This flag causes the bzero() routine to be used.
729bbcf679cSJacob Faibussowitsch 
730*95bd0b28SBarry Smith    Note:
731bbcf679cSJacob Faibussowitsch    Prefer `PetscArrayzero()`
732bbcf679cSJacob Faibussowitsch 
733bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`
734bbcf679cSJacob Faibussowitsch @*/
735bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemzero(void *a, size_t n)
736bbcf679cSJacob Faibussowitsch {
737bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
738bbcf679cSJacob Faibussowitsch   if (PetscUnlikely(n == 0)) PetscFunctionReturn(PETSC_SUCCESS);
739bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to zero %zu bytes at a null pointer", n);
740bbcf679cSJacob Faibussowitsch   if (PetscDefined(PREFER_ZERO_FOR_MEMZERO) || PetscDefined(PREFER_FORTRAN_FOR_MEMZERO)) {
741bbcf679cSJacob Faibussowitsch     if (!(((PETSC_UINTPTR_T)a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
742bbcf679cSJacob Faibussowitsch       const size_t scalar_len = n / sizeof(PetscScalar);
743bbcf679cSJacob Faibussowitsch       PetscScalar *x          = (PetscScalar *)a;
744bbcf679cSJacob Faibussowitsch 
745bbcf679cSJacob Faibussowitsch       if (PetscDefined(PREFER_ZERO_FOR_MEMZERO)) {
746bbcf679cSJacob Faibussowitsch         for (size_t i = 0; i < scalar_len; ++i) x[i] = 0;
747bbcf679cSJacob Faibussowitsch       } else {
748bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_FORTRAN_FOR_MEMZERO)
749bbcf679cSJacob Faibussowitsch         fortranzero_(&scalar_len, x);
750bbcf679cSJacob Faibussowitsch #else
751bbcf679cSJacob Faibussowitsch         (void)scalar_len;
752bbcf679cSJacob Faibussowitsch         (void)x;
753bbcf679cSJacob Faibussowitsch #endif
754bbcf679cSJacob Faibussowitsch       }
755bbcf679cSJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
756bbcf679cSJacob Faibussowitsch     }
757bbcf679cSJacob Faibussowitsch   }
758bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_BZERO)
759bbcf679cSJacob Faibussowitsch   bzero(a, n);
760bbcf679cSJacob Faibussowitsch #else
761bbcf679cSJacob Faibussowitsch   memset(a, 0, n);
762bbcf679cSJacob Faibussowitsch #endif
763bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
764bbcf679cSJacob Faibussowitsch }
765bbcf679cSJacob Faibussowitsch 
766bbcf679cSJacob Faibussowitsch /*MC
767bbcf679cSJacob Faibussowitsch    PetscArraycmp - Compares two arrays in memory.
768bbcf679cSJacob Faibussowitsch 
769bbcf679cSJacob Faibussowitsch    Synopsis:
770bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
771bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraycmp(const anytype *str1,const anytype *str2,size_t cnt,PetscBool *e)
772bbcf679cSJacob Faibussowitsch 
773bbcf679cSJacob Faibussowitsch    Not Collective
774bbcf679cSJacob Faibussowitsch 
775bbcf679cSJacob Faibussowitsch    Input Parameters:
776bbcf679cSJacob Faibussowitsch +  str1 - First array
777bbcf679cSJacob Faibussowitsch .  str2 - Second array
778bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
779bbcf679cSJacob Faibussowitsch 
7802fe279fdSBarry Smith    Output Parameter:
781bbcf679cSJacob Faibussowitsch .   e - `PETSC_TRUE` if equal else `PETSC_FALSE`.
782bbcf679cSJacob Faibussowitsch 
783bbcf679cSJacob Faibussowitsch    Level: intermediate
784bbcf679cSJacob Faibussowitsch 
785bbcf679cSJacob Faibussowitsch    Notes:
786bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemcmp()`
787bbcf679cSJacob Faibussowitsch 
788bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
789bbcf679cSJacob Faibussowitsch 
790bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`,
791bbcf679cSJacob Faibussowitsch           `PetscArraymove()`
792bbcf679cSJacob Faibussowitsch M*/
793bbcf679cSJacob Faibussowitsch #define PetscArraycmp(str1, str2, cnt, e) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemcmp((str1), (str2), (size_t)(cnt) * sizeof(*(str1)), (e)) : PETSC_ERR_ARG_SIZ)
794bbcf679cSJacob Faibussowitsch 
795bbcf679cSJacob Faibussowitsch /*MC
796bbcf679cSJacob Faibussowitsch    PetscArraymove - Copies from one array in memory to another, the arrays may overlap. Use `PetscArraycpy()` when the arrays
797bbcf679cSJacob Faibussowitsch                     do not overlap
798bbcf679cSJacob Faibussowitsch 
799bbcf679cSJacob Faibussowitsch    Synopsis:
800bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
801bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraymove(anytype *str1,const anytype *str2,size_t cnt)
802bbcf679cSJacob Faibussowitsch 
803bbcf679cSJacob Faibussowitsch    Not Collective
804bbcf679cSJacob Faibussowitsch 
805bbcf679cSJacob Faibussowitsch    Input Parameters:
806bbcf679cSJacob Faibussowitsch +  str1 - First array
807bbcf679cSJacob Faibussowitsch .  str2 - Second array
808bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
809bbcf679cSJacob Faibussowitsch 
810bbcf679cSJacob Faibussowitsch    Level: intermediate
811bbcf679cSJacob Faibussowitsch 
812bbcf679cSJacob Faibussowitsch    Notes:
813bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemmove()`
814bbcf679cSJacob Faibussowitsch 
815bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
816bbcf679cSJacob Faibussowitsch 
817bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscArraycmp()`, `PetscStrallocpy()`
818bbcf679cSJacob Faibussowitsch M*/
819bbcf679cSJacob Faibussowitsch #define PetscArraymove(str1, str2, cnt) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemmove((str1), (str2), (size_t)(cnt) * sizeof(*(str1))) : PETSC_ERR_ARG_SIZ)
820bbcf679cSJacob Faibussowitsch 
821bbcf679cSJacob Faibussowitsch /*MC
822bbcf679cSJacob Faibussowitsch    PetscArraycpy - Copies from one array in memory to another
823bbcf679cSJacob Faibussowitsch 
824bbcf679cSJacob Faibussowitsch    Synopsis:
825bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
826bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraycpy(anytype *str1,const anytype *str2,size_t cnt)
827bbcf679cSJacob Faibussowitsch 
828bbcf679cSJacob Faibussowitsch    Not Collective
829bbcf679cSJacob Faibussowitsch 
830bbcf679cSJacob Faibussowitsch    Input Parameters:
831bbcf679cSJacob Faibussowitsch +  str1 - First array (destination)
832bbcf679cSJacob Faibussowitsch .  str2 - Second array (source)
833bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
834bbcf679cSJacob Faibussowitsch 
835bbcf679cSJacob Faibussowitsch    Level: intermediate
836bbcf679cSJacob Faibussowitsch 
837bbcf679cSJacob Faibussowitsch    Notes:
838bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemcpy()`
839bbcf679cSJacob Faibussowitsch 
840bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
841bbcf679cSJacob Faibussowitsch 
842bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraymove()`, `PetscMemmove()`, `PetscArraycmp()`, `PetscStrallocpy()`
843bbcf679cSJacob Faibussowitsch M*/
844bbcf679cSJacob Faibussowitsch #define PetscArraycpy(str1, str2, cnt) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemcpy((str1), (str2), (size_t)(cnt) * sizeof(*(str1))) : PETSC_ERR_ARG_SIZ)
845bbcf679cSJacob Faibussowitsch 
846bbcf679cSJacob Faibussowitsch /*MC
847bbcf679cSJacob Faibussowitsch    PetscArrayzero - Zeros an array in memory.
848bbcf679cSJacob Faibussowitsch 
849bbcf679cSJacob Faibussowitsch    Synopsis:
850bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
851bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArrayzero(anytype *str1,size_t cnt)
852bbcf679cSJacob Faibussowitsch 
853bbcf679cSJacob Faibussowitsch    Not Collective
854bbcf679cSJacob Faibussowitsch 
855bbcf679cSJacob Faibussowitsch    Input Parameters:
856bbcf679cSJacob Faibussowitsch +  str1 - array
857bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the array
858bbcf679cSJacob Faibussowitsch 
859bbcf679cSJacob Faibussowitsch    Level: intermediate
860bbcf679cSJacob Faibussowitsch 
861*95bd0b28SBarry Smith    Note:
862bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemzero()`
863bbcf679cSJacob Faibussowitsch 
864bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscMemzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`, `PetscArraymove()`
865bbcf679cSJacob Faibussowitsch M*/
866bbcf679cSJacob Faibussowitsch #define PetscArrayzero(str1, cnt) PetscMemzero((str1), (size_t)(cnt) * sizeof(*(str1)))
867