xref: /petsc/include/petscstring.h (revision 2fe279fdf3e687a416e4eadb7d3c7a82d60442c6)
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 
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
40bbcf679cSJacob Faibussowitsch   PetscStrtolower - Converts string to lower case
41bbcf679cSJacob Faibussowitsch 
42667f096bSBarry Smith   Not Collective, No Fortran Support
43bbcf679cSJacob Faibussowitsch 
44*2fe279fdSBarry 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
63bbcf679cSJacob Faibussowitsch   PetscStrtoupper - Converts string to upper case
64bbcf679cSJacob Faibussowitsch 
65667f096bSBarry Smith   Not Collective, No Fortran Support
66bbcf679cSJacob Faibussowitsch 
67*2fe279fdSBarry 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
86bbcf679cSJacob Faibussowitsch   PetscStrlen - Gets length of a string
87bbcf679cSJacob Faibussowitsch 
88667f096bSBarry Smith   Not Collective, No Fortran Support
89bbcf679cSJacob Faibussowitsch 
90*2fe279fdSBarry 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 
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 
124*2fe279fdSBarry 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
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 
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 
239bbcf679cSJacob Faibussowitsch   Developers Notes:
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 
277bbcf679cSJacob Faibussowitsch   Notes:
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 
321bbcf679cSJacob Faibussowitsch   Notes:
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 
427bbcf679cSJacob Faibussowitsch   Notes:
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 
528bbcf679cSJacob Faibussowitsch   Notes:
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
571bbcf679cSJacob Faibussowitsch   either. Both `a` and `b` may point to the same string.
572bbcf679cSJacob Faibussowitsch 
573bbcf679cSJacob Faibussowitsch .seealso: `PetscStrendswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
574bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
575bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
576bbcf679cSJacob Faibussowitsch @*/
577bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg)
578bbcf679cSJacob Faibussowitsch {
579bbcf679cSJacob Faibussowitsch   size_t len = 0;
580bbcf679cSJacob Faibussowitsch 
581bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
582bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
583bbcf679cSJacob Faibussowitsch   // do this here to silence stupid "may be used uninitialized"" warnings
584bbcf679cSJacob Faibussowitsch   *flg = PETSC_FALSE;
585bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(b, &len));
586bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrncmp(a, b, len, flg));
587bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
588bbcf679cSJacob Faibussowitsch }
589bbcf679cSJacob Faibussowitsch 
590bbcf679cSJacob Faibussowitsch #undef PetscAssertPointer_Private
591bbcf679cSJacob Faibussowitsch 
592bbcf679cSJacob Faibussowitsch /*@C
593bbcf679cSJacob Faibussowitsch    PetscMemmove - Copies n bytes, beginning at location b, to the space
594bbcf679cSJacob Faibussowitsch    beginning at location a. Copying  between regions that overlap will
595bbcf679cSJacob Faibussowitsch    take place correctly. Use `PetscMemcpy()` if the locations do not overlap
596bbcf679cSJacob Faibussowitsch 
597bbcf679cSJacob Faibussowitsch    Not Collective
598bbcf679cSJacob Faibussowitsch 
599bbcf679cSJacob Faibussowitsch    Input Parameters:
600bbcf679cSJacob Faibussowitsch +  b - pointer to initial memory space
601bbcf679cSJacob Faibussowitsch .  a - pointer to copy space
602bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of space to copy
603bbcf679cSJacob Faibussowitsch 
604bbcf679cSJacob Faibussowitsch    Level: intermediate
605bbcf679cSJacob Faibussowitsch 
606bbcf679cSJacob Faibussowitsch    Notes:
607bbcf679cSJacob Faibussowitsch    `PetscArraymove()` is preferred
608bbcf679cSJacob Faibussowitsch 
609bbcf679cSJacob Faibussowitsch    This routine is analogous to `memmove()`.
610bbcf679cSJacob Faibussowitsch 
611bbcf679cSJacob Faibussowitsch    Developers Notes:
612bbcf679cSJacob Faibussowitsch    This is inlined for performance
613bbcf679cSJacob Faibussowitsch 
614bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscStrallocpy()`,
615bbcf679cSJacob Faibussowitsch           `PetscArraymove()`
616bbcf679cSJacob Faibussowitsch @*/
617bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemmove(void *a, const void *b, size_t n)
618bbcf679cSJacob Faibussowitsch {
619bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
620bbcf679cSJacob Faibussowitsch   if (PetscUnlikely((n == 0) || (a == b))) PetscFunctionReturn(PETSC_SUCCESS);
621bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes to null pointer (Argument #1)", n);
622bbcf679cSJacob Faibussowitsch   PetscAssert(b, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes from a null pointer (Argument #2)", n);
623bbcf679cSJacob Faibussowitsch #if PetscDefined(HAVE_MEMMOVE)
624bbcf679cSJacob Faibussowitsch   memmove((char *)a, (const char *)b, n);
625bbcf679cSJacob Faibussowitsch #else
626bbcf679cSJacob Faibussowitsch   if (a < b) {
627ffdfd6a8SLisandro Dalcin     if ((char *)a <= (char *)b - n) {
628bbcf679cSJacob Faibussowitsch       memcpy(a, b, n);
629bbcf679cSJacob Faibussowitsch     } else {
630ffdfd6a8SLisandro Dalcin       const size_t ptr_diff = (size_t)((char *)b - (char *)a);
631bbcf679cSJacob Faibussowitsch 
632bbcf679cSJacob Faibussowitsch       memcpy(a, b, ptr_diff);
633ffdfd6a8SLisandro Dalcin       PetscCall(PetscMemmove((void *)b, (char *)b + ptr_diff, n - ptr_diff));
634bbcf679cSJacob Faibussowitsch     }
635bbcf679cSJacob Faibussowitsch   } else {
636ffdfd6a8SLisandro Dalcin     if ((char *)b <= (char *)a - n) {
637bbcf679cSJacob Faibussowitsch       memcpy(a, b, n);
638bbcf679cSJacob Faibussowitsch     } else {
639ffdfd6a8SLisandro Dalcin       const size_t ptr_diff = (size_t)((char *)a - (char *)b);
640bbcf679cSJacob Faibussowitsch 
641ffdfd6a8SLisandro Dalcin       memcpy((void *)((char *)b + n), (char *)b + (n - ptr_diff), ptr_diff);
642bbcf679cSJacob Faibussowitsch       PetscCall(PetscMemmove(a, b, n - ptr_diff));
643bbcf679cSJacob Faibussowitsch     }
644bbcf679cSJacob Faibussowitsch   }
645bbcf679cSJacob Faibussowitsch #endif
646bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
647bbcf679cSJacob Faibussowitsch }
648bbcf679cSJacob Faibussowitsch 
649bbcf679cSJacob Faibussowitsch /*@C
650bbcf679cSJacob Faibussowitsch    PetscMemcpy - Copies n bytes, beginning at location b, to the space
651bbcf679cSJacob Faibussowitsch    beginning at location a. The two memory regions CANNOT overlap, use
652bbcf679cSJacob Faibussowitsch    `PetscMemmove()` in that case.
653bbcf679cSJacob Faibussowitsch 
654bbcf679cSJacob Faibussowitsch    Not Collective
655bbcf679cSJacob Faibussowitsch 
656bbcf679cSJacob Faibussowitsch    Input Parameters:
657bbcf679cSJacob Faibussowitsch +  b - pointer to initial memory space
658bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of space to copy
659bbcf679cSJacob Faibussowitsch 
660bbcf679cSJacob Faibussowitsch    Output Parameter:
661bbcf679cSJacob Faibussowitsch .  a - pointer to copy space
662bbcf679cSJacob Faibussowitsch 
663bbcf679cSJacob Faibussowitsch    Level: intermediate
664bbcf679cSJacob Faibussowitsch 
665bbcf679cSJacob Faibussowitsch    Compile Option:
666bbcf679cSJacob Faibussowitsch     `PETSC_PREFER_DCOPY_FOR_MEMCPY` will cause the BLAS dcopy() routine to be used
667bbcf679cSJacob Faibussowitsch                                   for memory copies on double precision values.
668bbcf679cSJacob Faibussowitsch     `PETSC_PREFER_COPY_FOR_MEMCPY` will cause C code to be used
669bbcf679cSJacob Faibussowitsch                                   for memory copies on double precision values.
670bbcf679cSJacob Faibussowitsch     `PETSC_PREFER_FORTRAN_FORMEMCPY` will cause Fortran code to be used
671bbcf679cSJacob Faibussowitsch                                   for memory copies on double precision values.
672bbcf679cSJacob Faibussowitsch 
673bbcf679cSJacob Faibussowitsch    Notes:
674bbcf679cSJacob Faibussowitsch    Prefer `PetscArraycpy()`
675bbcf679cSJacob Faibussowitsch 
676bbcf679cSJacob Faibussowitsch    This routine is analogous to `memcpy()`.
677bbcf679cSJacob Faibussowitsch 
678bbcf679cSJacob Faibussowitsch    Developer Notes:
679bbcf679cSJacob Faibussowitsch    This is inlined for fastest performance
680bbcf679cSJacob Faibussowitsch 
681bbcf679cSJacob Faibussowitsch .seealso: `PetscMemzero()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`
682bbcf679cSJacob Faibussowitsch @*/
683bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemcpy(void *a, const void *b, size_t n)
684bbcf679cSJacob Faibussowitsch {
685bbcf679cSJacob Faibussowitsch   const PETSC_UINTPTR_T al = (PETSC_UINTPTR_T)a;
686bbcf679cSJacob Faibussowitsch   const PETSC_UINTPTR_T bl = (PETSC_UINTPTR_T)b;
687bbcf679cSJacob Faibussowitsch 
688bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
689bbcf679cSJacob Faibussowitsch   if (PetscUnlikely((n == 0) || (a == b))) PetscFunctionReturn(PETSC_SUCCESS);
690bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes to a null pointer (Argument #1)", n);
691bbcf679cSJacob Faibussowitsch   PetscAssert(b, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes from a null pointer (Argument #2)", n);
692bbcf679cSJacob 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);
693bbcf679cSJacob Faibussowitsch   if (PetscDefined(PREFER_DCOPY_FOR_MEMCPY) || PetscDefined(PREFER_COPY_FOR_MEMCPY) || PetscDefined(PREFER_FORTRAN_FORMEMCPY)) {
694bbcf679cSJacob Faibussowitsch     if (!(al % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
695bbcf679cSJacob Faibussowitsch       const size_t       scalar_len = n / sizeof(PetscScalar);
696bbcf679cSJacob Faibussowitsch       const PetscScalar *x          = (PetscScalar *)b;
697bbcf679cSJacob Faibussowitsch       PetscScalar       *y          = (PetscScalar *)a;
698bbcf679cSJacob Faibussowitsch 
699bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_DCOPY_FOR_MEMCPY)
700bbcf679cSJacob Faibussowitsch       {
701bbcf679cSJacob Faibussowitsch         const PetscBLASInt one = 1;
702bbcf679cSJacob Faibussowitsch         PetscBLASInt       blen;
703bbcf679cSJacob Faibussowitsch 
704bbcf679cSJacob Faibussowitsch         PetscCall(PetscBLASIntCast(scalar_len, &blen));
705bbcf679cSJacob Faibussowitsch         PetscCallBLAS("BLAScopy", BLAScopy_(&blen, x, &one, y, &one));
706bbcf679cSJacob Faibussowitsch       }
707bbcf679cSJacob Faibussowitsch #elif PetscDefined(PREFER_FORTRAN_FORMEMCPY)
708bbcf679cSJacob Faibussowitsch       fortrancopy_(&scalar_len, x, y);
709bbcf679cSJacob Faibussowitsch #else
710bbcf679cSJacob Faibussowitsch       for (size_t i = 0; i < scalar_len; i++) y[i] = x[i];
711bbcf679cSJacob Faibussowitsch #endif
712bbcf679cSJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
713bbcf679cSJacob Faibussowitsch     }
714bbcf679cSJacob Faibussowitsch   }
715bbcf679cSJacob Faibussowitsch   memcpy(a, b, n);
716bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
717bbcf679cSJacob Faibussowitsch }
718bbcf679cSJacob Faibussowitsch 
719bbcf679cSJacob Faibussowitsch /*@C
720bbcf679cSJacob Faibussowitsch    PetscMemzero - Zeros the specified memory.
721bbcf679cSJacob Faibussowitsch 
722bbcf679cSJacob Faibussowitsch    Not Collective
723bbcf679cSJacob Faibussowitsch 
724bbcf679cSJacob Faibussowitsch    Input Parameters:
725bbcf679cSJacob Faibussowitsch +  a - pointer to beginning memory location
726bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of memory to initialize
727bbcf679cSJacob Faibussowitsch 
728bbcf679cSJacob Faibussowitsch    Level: intermediate
729bbcf679cSJacob Faibussowitsch 
730bbcf679cSJacob Faibussowitsch    Compile Option:
731bbcf679cSJacob Faibussowitsch    `PETSC_PREFER_BZERO` - on certain machines (the IBM RS6000) the bzero() routine happens
732bbcf679cSJacob Faibussowitsch   to be faster than the memset() routine. This flag causes the bzero() routine to be used.
733bbcf679cSJacob Faibussowitsch 
734bbcf679cSJacob Faibussowitsch    Notes:
735bbcf679cSJacob Faibussowitsch    Prefer `PetscArrayzero()`
736bbcf679cSJacob Faibussowitsch 
737bbcf679cSJacob Faibussowitsch    Developer Notes:
738bbcf679cSJacob Faibussowitsch    This is inlined for fastest performance
739bbcf679cSJacob Faibussowitsch 
740bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`
741bbcf679cSJacob Faibussowitsch @*/
742bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemzero(void *a, size_t n)
743bbcf679cSJacob Faibussowitsch {
744bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
745bbcf679cSJacob Faibussowitsch   if (PetscUnlikely(n == 0)) PetscFunctionReturn(PETSC_SUCCESS);
746bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to zero %zu bytes at a null pointer", n);
747bbcf679cSJacob Faibussowitsch   if (PetscDefined(PREFER_ZERO_FOR_MEMZERO) || PetscDefined(PREFER_FORTRAN_FOR_MEMZERO)) {
748bbcf679cSJacob Faibussowitsch     if (!(((PETSC_UINTPTR_T)a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
749bbcf679cSJacob Faibussowitsch       const size_t scalar_len = n / sizeof(PetscScalar);
750bbcf679cSJacob Faibussowitsch       PetscScalar *x          = (PetscScalar *)a;
751bbcf679cSJacob Faibussowitsch 
752bbcf679cSJacob Faibussowitsch       if (PetscDefined(PREFER_ZERO_FOR_MEMZERO)) {
753bbcf679cSJacob Faibussowitsch         for (size_t i = 0; i < scalar_len; ++i) x[i] = 0;
754bbcf679cSJacob Faibussowitsch       } else {
755bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_FORTRAN_FOR_MEMZERO)
756bbcf679cSJacob Faibussowitsch         fortranzero_(&scalar_len, x);
757bbcf679cSJacob Faibussowitsch #else
758bbcf679cSJacob Faibussowitsch         (void)scalar_len;
759bbcf679cSJacob Faibussowitsch         (void)x;
760bbcf679cSJacob Faibussowitsch #endif
761bbcf679cSJacob Faibussowitsch       }
762bbcf679cSJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
763bbcf679cSJacob Faibussowitsch     }
764bbcf679cSJacob Faibussowitsch   }
765bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_BZERO)
766bbcf679cSJacob Faibussowitsch   bzero(a, n);
767bbcf679cSJacob Faibussowitsch #else
768bbcf679cSJacob Faibussowitsch   memset(a, 0, n);
769bbcf679cSJacob Faibussowitsch #endif
770bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
771bbcf679cSJacob Faibussowitsch }
772bbcf679cSJacob Faibussowitsch 
773bbcf679cSJacob Faibussowitsch /*MC
774bbcf679cSJacob Faibussowitsch    PetscArraycmp - Compares two arrays in memory.
775bbcf679cSJacob Faibussowitsch 
776bbcf679cSJacob Faibussowitsch    Synopsis:
777bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
778bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraycmp(const anytype *str1,const anytype *str2,size_t cnt,PetscBool *e)
779bbcf679cSJacob Faibussowitsch 
780bbcf679cSJacob Faibussowitsch    Not Collective
781bbcf679cSJacob Faibussowitsch 
782bbcf679cSJacob Faibussowitsch    Input Parameters:
783bbcf679cSJacob Faibussowitsch +  str1 - First array
784bbcf679cSJacob Faibussowitsch .  str2 - Second array
785bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
786bbcf679cSJacob Faibussowitsch 
787*2fe279fdSBarry Smith    Output Parameter:
788bbcf679cSJacob Faibussowitsch .   e - `PETSC_TRUE` if equal else `PETSC_FALSE`.
789bbcf679cSJacob Faibussowitsch 
790bbcf679cSJacob Faibussowitsch    Level: intermediate
791bbcf679cSJacob Faibussowitsch 
792bbcf679cSJacob Faibussowitsch    Notes:
793bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemcmp()`
794bbcf679cSJacob Faibussowitsch 
795bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
796bbcf679cSJacob Faibussowitsch 
797bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`,
798bbcf679cSJacob Faibussowitsch           `PetscArraymove()`
799bbcf679cSJacob Faibussowitsch M*/
800bbcf679cSJacob Faibussowitsch #define PetscArraycmp(str1, str2, cnt, e) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemcmp((str1), (str2), (size_t)(cnt) * sizeof(*(str1)), (e)) : PETSC_ERR_ARG_SIZ)
801bbcf679cSJacob Faibussowitsch 
802bbcf679cSJacob Faibussowitsch /*MC
803bbcf679cSJacob Faibussowitsch    PetscArraymove - Copies from one array in memory to another, the arrays may overlap. Use `PetscArraycpy()` when the arrays
804bbcf679cSJacob Faibussowitsch                     do not overlap
805bbcf679cSJacob Faibussowitsch 
806bbcf679cSJacob Faibussowitsch    Synopsis:
807bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
808bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraymove(anytype *str1,const anytype *str2,size_t cnt)
809bbcf679cSJacob Faibussowitsch 
810bbcf679cSJacob Faibussowitsch    Not Collective
811bbcf679cSJacob Faibussowitsch 
812bbcf679cSJacob Faibussowitsch    Input Parameters:
813bbcf679cSJacob Faibussowitsch +  str1 - First array
814bbcf679cSJacob Faibussowitsch .  str2 - Second array
815bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
816bbcf679cSJacob Faibussowitsch 
817bbcf679cSJacob Faibussowitsch    Level: intermediate
818bbcf679cSJacob Faibussowitsch 
819bbcf679cSJacob Faibussowitsch    Notes:
820bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemmove()`
821bbcf679cSJacob Faibussowitsch 
822bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
823bbcf679cSJacob Faibussowitsch 
824bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscArraycmp()`, `PetscStrallocpy()`
825bbcf679cSJacob Faibussowitsch M*/
826bbcf679cSJacob Faibussowitsch #define PetscArraymove(str1, str2, cnt) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemmove((str1), (str2), (size_t)(cnt) * sizeof(*(str1))) : PETSC_ERR_ARG_SIZ)
827bbcf679cSJacob Faibussowitsch 
828bbcf679cSJacob Faibussowitsch /*MC
829bbcf679cSJacob Faibussowitsch    PetscArraycpy - Copies from one array in memory to another
830bbcf679cSJacob Faibussowitsch 
831bbcf679cSJacob Faibussowitsch    Synopsis:
832bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
833bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraycpy(anytype *str1,const anytype *str2,size_t cnt)
834bbcf679cSJacob Faibussowitsch 
835bbcf679cSJacob Faibussowitsch    Not Collective
836bbcf679cSJacob Faibussowitsch 
837bbcf679cSJacob Faibussowitsch    Input Parameters:
838bbcf679cSJacob Faibussowitsch +  str1 - First array (destination)
839bbcf679cSJacob Faibussowitsch .  str2 - Second array (source)
840bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
841bbcf679cSJacob Faibussowitsch 
842bbcf679cSJacob Faibussowitsch    Level: intermediate
843bbcf679cSJacob Faibussowitsch 
844bbcf679cSJacob Faibussowitsch    Notes:
845bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemcpy()`
846bbcf679cSJacob Faibussowitsch 
847bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
848bbcf679cSJacob Faibussowitsch 
849bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraymove()`, `PetscMemmove()`, `PetscArraycmp()`, `PetscStrallocpy()`
850bbcf679cSJacob Faibussowitsch M*/
851bbcf679cSJacob Faibussowitsch #define PetscArraycpy(str1, str2, cnt) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemcpy((str1), (str2), (size_t)(cnt) * sizeof(*(str1))) : PETSC_ERR_ARG_SIZ)
852bbcf679cSJacob Faibussowitsch 
853bbcf679cSJacob Faibussowitsch /*MC
854bbcf679cSJacob Faibussowitsch    PetscArrayzero - Zeros an array in memory.
855bbcf679cSJacob Faibussowitsch 
856bbcf679cSJacob Faibussowitsch    Synopsis:
857bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
858bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArrayzero(anytype *str1,size_t cnt)
859bbcf679cSJacob Faibussowitsch 
860bbcf679cSJacob Faibussowitsch    Not Collective
861bbcf679cSJacob Faibussowitsch 
862bbcf679cSJacob Faibussowitsch    Input Parameters:
863bbcf679cSJacob Faibussowitsch +  str1 - array
864bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the array
865bbcf679cSJacob Faibussowitsch 
866bbcf679cSJacob Faibussowitsch    Level: intermediate
867bbcf679cSJacob Faibussowitsch 
868bbcf679cSJacob Faibussowitsch    Notes:
869bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemzero()`
870bbcf679cSJacob Faibussowitsch 
871bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscMemzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`, `PetscArraymove()`
872bbcf679cSJacob Faibussowitsch M*/
873bbcf679cSJacob Faibussowitsch #define PetscArrayzero(str1, cnt) PetscMemzero((str1), (size_t)(cnt) * sizeof(*(str1)))
874bbcf679cSJacob Faibussowitsch 
875bbcf679cSJacob Faibussowitsch #endif // PETSC_STRING_H
876