xref: /petsc/include/petscstring.h (revision c0d8b5b961be93010fbbd9619a716d547914b922)
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);
24*c0d8b5b9SStefano Zampini PETSC_EXTERN PetscErrorCode PetscStrcmpAny(const char[], PetscBool *, const char[], ...);
25bbcf679cSJacob Faibussowitsch 
26bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscTokenCreate(const char[], char, PetscToken *);
27bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscTokenFind(PetscToken, char *[]);
28bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscTokenDestroy(PetscToken *);
29bbcf679cSJacob Faibussowitsch 
30bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrInList(const char[], const char[], char, PetscBool *);
31bbcf679cSJacob Faibussowitsch PETSC_EXTERN const char    *PetscBasename(const char[]);
32bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscEListFind(PetscInt, const char *const *, const char *, PetscInt *, PetscBool *);
33bbcf679cSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscEnumFind(const char *const *, const char *, PetscEnum *, PetscBool *);
34bbcf679cSJacob Faibussowitsch 
35d11110bcSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrcat(char[], const char[]);
36d11110bcSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscStrcpy(char[], const char[]);
37d11110bcSJacob Faibussowitsch 
38bbcf679cSJacob Faibussowitsch #define PetscAssertPointer_Private(ptr, arg) PetscAssert((ptr), PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Null Pointer: Parameter '" PetscStringize(ptr) "' # " PetscStringize(arg))
39bbcf679cSJacob Faibussowitsch 
40bbcf679cSJacob Faibussowitsch /*@C
4116a05f60SBarry Smith   PetscStrtolower - Converts a string to lower case
42bbcf679cSJacob Faibussowitsch 
43667f096bSBarry Smith   Not Collective, No Fortran Support
44bbcf679cSJacob Faibussowitsch 
452fe279fdSBarry Smith   Input Parameter:
46bbcf679cSJacob Faibussowitsch . a - pointer to string
47bbcf679cSJacob Faibussowitsch 
48bbcf679cSJacob Faibussowitsch   Level: intermediate
49bbcf679cSJacob Faibussowitsch 
50bbcf679cSJacob Faibussowitsch .seealso: `PetscStrtoupper()`
51bbcf679cSJacob Faibussowitsch @*/
52bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrtolower(char a[])
53bbcf679cSJacob Faibussowitsch {
54bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
55bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
56bbcf679cSJacob Faibussowitsch   while (*a) {
57bbcf679cSJacob Faibussowitsch     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
58bbcf679cSJacob Faibussowitsch     a++;
59bbcf679cSJacob Faibussowitsch   }
60bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
61bbcf679cSJacob Faibussowitsch }
62bbcf679cSJacob Faibussowitsch 
63bbcf679cSJacob Faibussowitsch /*@C
6416a05f60SBarry Smith   PetscStrtoupper - Converts a string to upper case
65bbcf679cSJacob Faibussowitsch 
66667f096bSBarry Smith   Not Collective, No Fortran Support
67bbcf679cSJacob Faibussowitsch 
682fe279fdSBarry Smith   Input Parameter:
69bbcf679cSJacob Faibussowitsch . a - pointer to string
70bbcf679cSJacob Faibussowitsch 
71bbcf679cSJacob Faibussowitsch   Level: intermediate
72bbcf679cSJacob Faibussowitsch 
73bbcf679cSJacob Faibussowitsch .seealso: `PetscStrtolower()`
74bbcf679cSJacob Faibussowitsch @*/
75bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrtoupper(char a[])
76bbcf679cSJacob Faibussowitsch {
77bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
78bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
79bbcf679cSJacob Faibussowitsch   while (*a) {
80bbcf679cSJacob Faibussowitsch     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
81bbcf679cSJacob Faibussowitsch     a++;
82bbcf679cSJacob Faibussowitsch   }
83bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
84bbcf679cSJacob Faibussowitsch }
85bbcf679cSJacob Faibussowitsch 
86bbcf679cSJacob Faibussowitsch /*@C
8716a05f60SBarry Smith   PetscStrlen - Gets the length of a string
88bbcf679cSJacob Faibussowitsch 
89667f096bSBarry Smith   Not Collective, No Fortran Support
90bbcf679cSJacob Faibussowitsch 
912fe279fdSBarry Smith   Input Parameter:
92bbcf679cSJacob Faibussowitsch . s - pointer to string
93bbcf679cSJacob Faibussowitsch 
94bbcf679cSJacob Faibussowitsch   Output Parameter:
95bbcf679cSJacob Faibussowitsch . len - length in bytes
96bbcf679cSJacob Faibussowitsch 
97bbcf679cSJacob Faibussowitsch   Level: intermediate
98bbcf679cSJacob Faibussowitsch 
99bbcf679cSJacob Faibussowitsch   Notes:
100bbcf679cSJacob Faibussowitsch   This routine is analogous to `strlen()`. `NULL` string returns a length of zero.
101bbcf679cSJacob Faibussowitsch 
102bbcf679cSJacob Faibussowitsch .seealso: `PetscStrallocpy()`
103bbcf679cSJacob Faibussowitsch @*/
104bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrlen(const char s[], size_t *len)
105bbcf679cSJacob Faibussowitsch {
106bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
107bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(len, 2);
108bbcf679cSJacob Faibussowitsch   if (s) {
109bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strlen)
110bbcf679cSJacob Faibussowitsch     *len = __builtin_strlen(s);
111bbcf679cSJacob Faibussowitsch #else
112bbcf679cSJacob Faibussowitsch     *len = strlen(s);
113bbcf679cSJacob Faibussowitsch #endif
114bbcf679cSJacob Faibussowitsch   } else {
115bbcf679cSJacob Faibussowitsch     *len = 0;
116bbcf679cSJacob Faibussowitsch   }
117bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
118bbcf679cSJacob Faibussowitsch }
119bbcf679cSJacob Faibussowitsch 
120bbcf679cSJacob Faibussowitsch /*@C
12116a05f60SBarry Smith   PetscStrallocpy - Allocates space to hold a copy of a string then copies the string into the new space
122bbcf679cSJacob Faibussowitsch 
123667f096bSBarry Smith   Not Collective, No Fortran Support
124bbcf679cSJacob Faibussowitsch 
1252fe279fdSBarry Smith   Input Parameter:
126bbcf679cSJacob Faibussowitsch . s - pointer to string
127bbcf679cSJacob Faibussowitsch 
128bbcf679cSJacob Faibussowitsch   Output Parameter:
129bbcf679cSJacob Faibussowitsch . t - the copied string
130bbcf679cSJacob Faibussowitsch 
131bbcf679cSJacob Faibussowitsch   Level: intermediate
132bbcf679cSJacob Faibussowitsch 
133bbcf679cSJacob Faibussowitsch   Notes:
134bbcf679cSJacob Faibussowitsch   `NULL` string returns a new `NULL` string.
135bbcf679cSJacob Faibussowitsch 
136bbcf679cSJacob Faibussowitsch   If `t` has previously been allocated then that memory is lost, you may need to `PetscFree()`
137bbcf679cSJacob Faibussowitsch   the array before calling this routine.
138bbcf679cSJacob Faibussowitsch 
139d11110bcSJacob Faibussowitsch .seealso: `PetscStrArrayallocpy()`, `PetscStrNArrayallocpy()`
140bbcf679cSJacob Faibussowitsch @*/
141bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrallocpy(const char s[], char *t[])
142bbcf679cSJacob Faibussowitsch {
143bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
144bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(t, 2);
145bbcf679cSJacob Faibussowitsch   *t = PETSC_NULLPTR;
146bbcf679cSJacob Faibussowitsch   if (s) {
147bbcf679cSJacob Faibussowitsch     size_t len;
148bbcf679cSJacob Faibussowitsch     char  *tmp;
149bbcf679cSJacob Faibussowitsch 
150bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(s, 1);
151bbcf679cSJacob Faibussowitsch     PetscCall(PetscStrlen(s, &len));
152bbcf679cSJacob Faibussowitsch     PetscCall(PetscMalloc1(len + 1, &tmp));
153bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_memcpy)
154bbcf679cSJacob Faibussowitsch     __builtin_memcpy(tmp, s, len);
155bbcf679cSJacob Faibussowitsch #else
156bbcf679cSJacob Faibussowitsch     memcpy(tmp, s, len);
157bbcf679cSJacob Faibussowitsch #endif
158bbcf679cSJacob Faibussowitsch     tmp[len] = '\0';
159bbcf679cSJacob Faibussowitsch     *t       = tmp;
160bbcf679cSJacob Faibussowitsch   }
161bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
162bbcf679cSJacob Faibussowitsch }
163bbcf679cSJacob Faibussowitsch 
164bbcf679cSJacob Faibussowitsch static inline void PetscStrcmpNoError(const char a[], const char b[], PetscBool *flg)
165bbcf679cSJacob Faibussowitsch {
166bbcf679cSJacob Faibussowitsch   if (!a && !b) {
167bbcf679cSJacob Faibussowitsch     *flg = PETSC_TRUE;
168bbcf679cSJacob Faibussowitsch   } else if (!a || !b) {
169bbcf679cSJacob Faibussowitsch     *flg = PETSC_FALSE;
170bbcf679cSJacob Faibussowitsch   } else {
171bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strcmp)
172bbcf679cSJacob Faibussowitsch     *flg = __builtin_strcmp(a, b) ? PETSC_FALSE : PETSC_TRUE;
173bbcf679cSJacob Faibussowitsch #else
174bbcf679cSJacob Faibussowitsch     *flg = strcmp(a, b) ? PETSC_FALSE : PETSC_TRUE;
175bbcf679cSJacob Faibussowitsch #endif
176bbcf679cSJacob Faibussowitsch   }
177bbcf679cSJacob Faibussowitsch }
178bbcf679cSJacob Faibussowitsch 
179bbcf679cSJacob Faibussowitsch /*@C
18016a05f60SBarry Smith   PetscStrcmp - Compares two strings
181bbcf679cSJacob Faibussowitsch 
182667f096bSBarry Smith   Not Collective, No Fortran Support
183bbcf679cSJacob Faibussowitsch 
184bbcf679cSJacob Faibussowitsch   Input Parameters:
185bbcf679cSJacob Faibussowitsch + a - pointer to string first string
186bbcf679cSJacob Faibussowitsch - b - pointer to second string
187bbcf679cSJacob Faibussowitsch 
188bbcf679cSJacob Faibussowitsch   Output Parameter:
189bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if the two strings are equal
190bbcf679cSJacob Faibussowitsch 
191bbcf679cSJacob Faibussowitsch   Level: intermediate
192bbcf679cSJacob Faibussowitsch 
193*c0d8b5b9SStefano Zampini .seealso: `PetscStrcmpAny()`, `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`
194bbcf679cSJacob Faibussowitsch @*/
195bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrcmp(const char a[], const char b[], PetscBool *flg)
196bbcf679cSJacob Faibussowitsch {
197bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
198bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
199bbcf679cSJacob Faibussowitsch   PetscStrcmpNoError(a, b, flg);
200bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
201bbcf679cSJacob Faibussowitsch }
202bbcf679cSJacob Faibussowitsch 
203363da2dcSJacob Faibussowitsch #if defined(__GNUC__) && !defined(__clang__)
204363da2dcSJacob Faibussowitsch   #if __GNUC__ >= 8
205363da2dcSJacob Faibussowitsch     #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN \
206363da2dcSJacob Faibussowitsch       do { \
207363da2dcSJacob Faibussowitsch         _Pragma("GCC diagnostic push"); \
208363da2dcSJacob Faibussowitsch         _Pragma("GCC diagnostic ignored \"-Wstringop-truncation\""); \
209363da2dcSJacob Faibussowitsch       } while (0)
210363da2dcSJacob Faibussowitsch     #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_END _Pragma("GCC diagnostic pop")
211363da2dcSJacob Faibussowitsch   #endif
212363da2dcSJacob Faibussowitsch #endif
213363da2dcSJacob Faibussowitsch 
214363da2dcSJacob Faibussowitsch #ifndef PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN
215363da2dcSJacob Faibussowitsch   #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN (void)0
216363da2dcSJacob Faibussowitsch   #define PETSC_SILENCE_WSTRINGOP_TRUNCATION_END   (void)0
217363da2dcSJacob Faibussowitsch #endif
218363da2dcSJacob Faibussowitsch 
219bbcf679cSJacob Faibussowitsch /*@C
220bbcf679cSJacob Faibussowitsch   PetscStrncpy - Copies a string up to a certain length
221bbcf679cSJacob Faibussowitsch 
222bbcf679cSJacob Faibussowitsch   Not Collective
223bbcf679cSJacob Faibussowitsch 
224bbcf679cSJacob Faibussowitsch   Input Parameters:
225bbcf679cSJacob Faibussowitsch + t - pointer to string
226bbcf679cSJacob Faibussowitsch - n - the length to copy
227bbcf679cSJacob Faibussowitsch 
228bbcf679cSJacob Faibussowitsch   Output Parameter:
229bbcf679cSJacob Faibussowitsch . s - the copied string
230bbcf679cSJacob Faibussowitsch 
231bbcf679cSJacob Faibussowitsch   Level: intermediate
232bbcf679cSJacob Faibussowitsch 
233bbcf679cSJacob Faibussowitsch   Notes:
234bbcf679cSJacob Faibussowitsch   `NULL` string returns a string starting with zero.
235bbcf679cSJacob Faibussowitsch 
236bbcf679cSJacob Faibussowitsch   If the string that is being copied is of length `n` or larger, then the entire string is not
237bbcf679cSJacob Faibussowitsch   copied and the final location of `s` is set to `NULL`. This is different then the behavior of
238bbcf679cSJacob Faibussowitsch   `strncpy()` which leaves `s` non-terminated if there is not room for the entire string.
239bbcf679cSJacob Faibussowitsch 
240bbcf679cSJacob Faibussowitsch   Developers Notes:
241bbcf679cSJacob Faibussowitsch   Should this be `PetscStrlcpy()` to reflect its behavior which is like `strlcpy()` not
242bbcf679cSJacob Faibussowitsch   `strncpy()`?
243bbcf679cSJacob Faibussowitsch 
244d11110bcSJacob Faibussowitsch .seealso: `PetscStrlcat()`, `PetscStrallocpy()`
245bbcf679cSJacob Faibussowitsch @*/
246bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrncpy(char s[], const char t[], size_t n)
247bbcf679cSJacob Faibussowitsch {
248bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
249bbcf679cSJacob 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");
250bbcf679cSJacob Faibussowitsch   if (t) {
251bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(s, 1);
252363da2dcSJacob Faibussowitsch     PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN;
253bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncpy)
2549b15cf9aSJacob Faibussowitsch     __builtin_strncpy(s, t, n);
255bbcf679cSJacob Faibussowitsch #else
2569b15cf9aSJacob Faibussowitsch     strncpy(s, t, n);
2579b15cf9aSJacob Faibussowitsch #endif
258363da2dcSJacob Faibussowitsch     PETSC_SILENCE_WSTRINGOP_TRUNCATION_END;
259bbcf679cSJacob Faibussowitsch     s[n - 1] = '\0';
260bbcf679cSJacob Faibussowitsch   } else if (s) {
261bbcf679cSJacob Faibussowitsch     s[0] = '\0';
262bbcf679cSJacob Faibussowitsch   }
263bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
264bbcf679cSJacob Faibussowitsch }
265bbcf679cSJacob Faibussowitsch 
266bbcf679cSJacob Faibussowitsch /*@C
267bbcf679cSJacob Faibussowitsch   PetscStrlcat - Concatenates a string onto a given string, up to a given length
268bbcf679cSJacob Faibussowitsch 
269667f096bSBarry Smith   Not Collective, No Fortran Support
270bbcf679cSJacob Faibussowitsch 
271bbcf679cSJacob Faibussowitsch   Input Parameters:
272bbcf679cSJacob Faibussowitsch + s - pointer to string to be added to at end
273bbcf679cSJacob Faibussowitsch . t - string to be added
274bbcf679cSJacob Faibussowitsch - n - length of the original allocated string
275bbcf679cSJacob Faibussowitsch 
276bbcf679cSJacob Faibussowitsch   Level: intermediate
277bbcf679cSJacob Faibussowitsch 
278bbcf679cSJacob Faibussowitsch   Notes:
279bbcf679cSJacob Faibussowitsch   Unlike the system call `strncat()`, the length passed in is the length of the
280bbcf679cSJacob Faibussowitsch   original allocated space, not the length of the left-over space. This is
281bbcf679cSJacob Faibussowitsch   similar to the BSD system call `strlcat()`.
282bbcf679cSJacob Faibussowitsch 
283d11110bcSJacob Faibussowitsch .seealso: `PetscStrncpy()`
284bbcf679cSJacob Faibussowitsch @*/
285bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrlcat(char s[], const char t[], size_t n)
286bbcf679cSJacob Faibussowitsch {
287bbcf679cSJacob Faibussowitsch   size_t len;
288bbcf679cSJacob Faibussowitsch 
289bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
290bbcf679cSJacob Faibussowitsch   if (!t) PetscFunctionReturn(PETSC_SUCCESS);
291bbcf679cSJacob Faibussowitsch   PetscAssert(n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "String buffer length must be positive");
292ca7fbcdfSJacob Faibussowitsch   PetscCall(PetscStrlen(s, &len));
293363da2dcSJacob Faibussowitsch   PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN;
294bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncat)
295bbcf679cSJacob Faibussowitsch   __builtin_strncat(s, t, n - len);
296bbcf679cSJacob Faibussowitsch #else
297bbcf679cSJacob Faibussowitsch   strncat(s, t, n - len);
298bbcf679cSJacob Faibussowitsch #endif
299363da2dcSJacob Faibussowitsch   PETSC_SILENCE_WSTRINGOP_TRUNCATION_END;
300bbcf679cSJacob Faibussowitsch   s[n - 1] = '\0';
301bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
302bbcf679cSJacob Faibussowitsch }
303bbcf679cSJacob Faibussowitsch 
304363da2dcSJacob Faibussowitsch #undef PETSC_SILENCE_WSTRINGOP_TRUNCATION_BEGIN
305363da2dcSJacob Faibussowitsch #undef PETSC_SILENCE_WSTRINGOP_TRUNCATION_END
306363da2dcSJacob Faibussowitsch 
307bbcf679cSJacob Faibussowitsch /*@C
308bbcf679cSJacob Faibussowitsch   PetscStrncmp - Compares two strings, up to a certain length
309bbcf679cSJacob Faibussowitsch 
310667f096bSBarry Smith   Not Collective, No Fortran Support
311bbcf679cSJacob Faibussowitsch 
312bbcf679cSJacob Faibussowitsch   Input Parameters:
313bbcf679cSJacob Faibussowitsch + a - pointer to first string
314bbcf679cSJacob Faibussowitsch . b - pointer to second string
315bbcf679cSJacob Faibussowitsch - n - length to compare up to
316bbcf679cSJacob Faibussowitsch 
317bbcf679cSJacob Faibussowitsch   Output Parameter:
318bbcf679cSJacob Faibussowitsch . t - `PETSC_TRUE` if the two strings are equal, `PETSC_FALSE` otherwise
319bbcf679cSJacob Faibussowitsch 
320bbcf679cSJacob Faibussowitsch   Level: intermediate
321bbcf679cSJacob Faibussowitsch 
32216a05f60SBarry Smith   Note:
323bbcf679cSJacob Faibussowitsch   If `n` is `0`, `t` is set to `PETSC_FALSE`. `a` and/or `b` may be `NULL` in this case.
324bbcf679cSJacob Faibussowitsch 
325bbcf679cSJacob Faibussowitsch .seealso: `PetscStrgrt()`, `PetscStrcmp()`, `PetscStrcasecmp()`
326bbcf679cSJacob Faibussowitsch @*/
327bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrncmp(const char a[], const char b[], size_t n, PetscBool *t)
328bbcf679cSJacob Faibussowitsch {
329bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
330bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(t, 4);
331bbcf679cSJacob Faibussowitsch   *t = PETSC_FALSE;
332bbcf679cSJacob Faibussowitsch   if (n) {
333bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(a, 1);
334bbcf679cSJacob Faibussowitsch     PetscAssertPointer_Private(b, 2);
335bbcf679cSJacob Faibussowitsch   }
336bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strncmp)
337bbcf679cSJacob Faibussowitsch   *t = __builtin_strncmp(a, b, n) ? PETSC_FALSE : PETSC_TRUE;
338bbcf679cSJacob Faibussowitsch #else
339bbcf679cSJacob Faibussowitsch   *t = strncmp(a, b, n) ? PETSC_FALSE : PETSC_TRUE;
340bbcf679cSJacob Faibussowitsch #endif
341bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
342bbcf679cSJacob Faibussowitsch }
343bbcf679cSJacob Faibussowitsch 
344bbcf679cSJacob Faibussowitsch /*@C
345bbcf679cSJacob Faibussowitsch   PetscStrrstr - Locates last occurrence of string in another string
346bbcf679cSJacob Faibussowitsch 
347667f096bSBarry Smith   Not Collective, No Fortran Support
348bbcf679cSJacob Faibussowitsch 
349bbcf679cSJacob Faibussowitsch   Input Parameters:
350bbcf679cSJacob Faibussowitsch + a - pointer to string
351bbcf679cSJacob Faibussowitsch - b - string to find
352bbcf679cSJacob Faibussowitsch 
353bbcf679cSJacob Faibussowitsch   Output Parameter:
354bbcf679cSJacob Faibussowitsch . tmp - location of occurrence
355bbcf679cSJacob Faibussowitsch 
356bbcf679cSJacob Faibussowitsch   Level: intermediate
357bbcf679cSJacob Faibussowitsch 
358bbcf679cSJacob Faibussowitsch .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
359bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
360bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
361bbcf679cSJacob Faibussowitsch @*/
362bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrrstr(const char a[], const char b[], char *tmp[])
363bbcf679cSJacob Faibussowitsch {
364bbcf679cSJacob Faibussowitsch   const char *ltmp = PETSC_NULLPTR;
365bbcf679cSJacob Faibussowitsch 
366bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
367bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
368bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(b, 2);
369bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(tmp, 3);
370bbcf679cSJacob Faibussowitsch   while (a) {
371bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strstr)
372bbcf679cSJacob Faibussowitsch     a = (char *)__builtin_strstr(a, b);
373bbcf679cSJacob Faibussowitsch #else
374bbcf679cSJacob Faibussowitsch     a = (char *)strstr(a, b);
375bbcf679cSJacob Faibussowitsch #endif
376bbcf679cSJacob Faibussowitsch     if (a) ltmp = a++;
377bbcf679cSJacob Faibussowitsch   }
378bbcf679cSJacob Faibussowitsch   *tmp = (char *)ltmp;
379bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
380bbcf679cSJacob Faibussowitsch }
381bbcf679cSJacob Faibussowitsch 
382bbcf679cSJacob Faibussowitsch /*@C
383bbcf679cSJacob Faibussowitsch   PetscStrstr - Locates first occurrence of string in another string
384bbcf679cSJacob Faibussowitsch 
385667f096bSBarry Smith   Not Collective, No Fortran Support
386bbcf679cSJacob Faibussowitsch 
387bbcf679cSJacob Faibussowitsch   Input Parameters:
388bbcf679cSJacob Faibussowitsch + haystack - string to search
389bbcf679cSJacob Faibussowitsch - needle   - string to find
390bbcf679cSJacob Faibussowitsch 
391bbcf679cSJacob Faibussowitsch   Output Parameter:
392bbcf679cSJacob Faibussowitsch . tmp - location of `needle` within `haystack`, `NULL` if `needle` is not found
393bbcf679cSJacob Faibussowitsch 
394bbcf679cSJacob Faibussowitsch   Level: intermediate
395bbcf679cSJacob Faibussowitsch 
396bbcf679cSJacob Faibussowitsch .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
397bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
398bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
399bbcf679cSJacob Faibussowitsch @*/
400bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrstr(const char haystack[], const char needle[], char *tmp[])
401bbcf679cSJacob Faibussowitsch {
402bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
403bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(haystack, 1);
404bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(needle, 2);
405bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(tmp, 3);
406bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strstr)
407bbcf679cSJacob Faibussowitsch   *tmp = (char *)__builtin_strstr(haystack, needle);
408bbcf679cSJacob Faibussowitsch #else
409bbcf679cSJacob Faibussowitsch   *tmp = (char *)strstr(haystack, needle);
410bbcf679cSJacob Faibussowitsch #endif
411bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
412bbcf679cSJacob Faibussowitsch }
413bbcf679cSJacob Faibussowitsch 
414bbcf679cSJacob Faibussowitsch /*@C
415bbcf679cSJacob Faibussowitsch   PetscStrgrt - If first string is greater than the second
416bbcf679cSJacob Faibussowitsch 
417667f096bSBarry Smith   Not Collective, No Fortran Support
418bbcf679cSJacob Faibussowitsch 
419bbcf679cSJacob Faibussowitsch   Input Parameters:
420bbcf679cSJacob Faibussowitsch + a - pointer to first string
421bbcf679cSJacob Faibussowitsch - b - pointer to second string
422bbcf679cSJacob Faibussowitsch 
423bbcf679cSJacob Faibussowitsch   Output Parameter:
424bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` is strictly greater than `b`, `PETSC_FALSE` otherwise
425bbcf679cSJacob Faibussowitsch 
426bbcf679cSJacob Faibussowitsch   Level: intermediate
427bbcf679cSJacob Faibussowitsch 
428bbcf679cSJacob Faibussowitsch   Notes:
429bbcf679cSJacob Faibussowitsch   `NULL` arguments are OK, a `NULL` string is considered smaller than all others. If both `a`
430bbcf679cSJacob Faibussowitsch   and `b` are `NULL` then `t` is set to `PETSC_FALSE`.
431bbcf679cSJacob Faibussowitsch 
432bbcf679cSJacob Faibussowitsch .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrcasecmp()`
433bbcf679cSJacob Faibussowitsch @*/
434bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrgrt(const char a[], const char b[], PetscBool *t)
435bbcf679cSJacob Faibussowitsch {
436bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
437bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(t, 3);
438bbcf679cSJacob Faibussowitsch   if (!a && !b) {
439bbcf679cSJacob Faibussowitsch     *t = PETSC_FALSE;
440bbcf679cSJacob Faibussowitsch   } else if (a && !b) {
441bbcf679cSJacob Faibussowitsch     *t = PETSC_TRUE;
442bbcf679cSJacob Faibussowitsch   } else if (!a && b) {
443bbcf679cSJacob Faibussowitsch     *t = PETSC_FALSE;
444bbcf679cSJacob Faibussowitsch   } else {
445bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strcmp)
446bbcf679cSJacob Faibussowitsch     *t = __builtin_strcmp(a, b) > 0 ? PETSC_TRUE : PETSC_FALSE;
447bbcf679cSJacob Faibussowitsch #else
448bbcf679cSJacob Faibussowitsch     *t = strcmp(a, b) > 0 ? PETSC_TRUE : PETSC_FALSE;
449bbcf679cSJacob Faibussowitsch #endif
450bbcf679cSJacob Faibussowitsch   }
451bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
452bbcf679cSJacob Faibussowitsch }
453bbcf679cSJacob Faibussowitsch 
454bbcf679cSJacob Faibussowitsch /*@C
455bbcf679cSJacob Faibussowitsch   PetscStrchr - Locates first occurrence of a character in a string
456bbcf679cSJacob Faibussowitsch 
457667f096bSBarry Smith   Not Collective, No Fortran Support
458bbcf679cSJacob Faibussowitsch 
459bbcf679cSJacob Faibussowitsch   Input Parameters:
460bbcf679cSJacob Faibussowitsch + a - pointer to string
461bbcf679cSJacob Faibussowitsch - b - character
462bbcf679cSJacob Faibussowitsch 
463bbcf679cSJacob Faibussowitsch   Output Parameter:
464bbcf679cSJacob Faibussowitsch . c - location of occurrence, `NULL` if not found
465bbcf679cSJacob Faibussowitsch 
466bbcf679cSJacob Faibussowitsch   Level: intermediate
467bbcf679cSJacob Faibussowitsch 
468bbcf679cSJacob Faibussowitsch .seealso: `PetscStrrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()`
469bbcf679cSJacob Faibussowitsch @*/
470bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrchr(const char a[], char b, char *c[])
471bbcf679cSJacob Faibussowitsch {
472bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
473bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
474bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(c, 3);
475bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strchr)
476bbcf679cSJacob Faibussowitsch   *c = (char *)__builtin_strchr(a, b);
477bbcf679cSJacob Faibussowitsch #else
478bbcf679cSJacob Faibussowitsch   *c = (char *)strchr(a, b);
479bbcf679cSJacob Faibussowitsch #endif
480bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
481bbcf679cSJacob Faibussowitsch }
482bbcf679cSJacob Faibussowitsch 
483bbcf679cSJacob Faibussowitsch /*@C
484bbcf679cSJacob Faibussowitsch   PetscStrrchr - Locates one location past the last occurrence of a character in a string, if
485bbcf679cSJacob Faibussowitsch   the character is not found then returns entire string
486bbcf679cSJacob Faibussowitsch 
487667f096bSBarry Smith   Not Collective, No Fortran Support
488bbcf679cSJacob Faibussowitsch 
489bbcf679cSJacob Faibussowitsch   Input Parameters:
490bbcf679cSJacob Faibussowitsch + a - pointer to string
491bbcf679cSJacob Faibussowitsch - b - character
492bbcf679cSJacob Faibussowitsch 
493bbcf679cSJacob Faibussowitsch   Output Parameter:
4948ca48ce9SPierre Jolivet . c - one past location of `b` in `a`, or `a` if `b` was not found
495bbcf679cSJacob Faibussowitsch 
496bbcf679cSJacob Faibussowitsch   Level: intermediate
497bbcf679cSJacob Faibussowitsch 
498bbcf679cSJacob Faibussowitsch .seealso: `PetscStrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()`
499bbcf679cSJacob Faibussowitsch @*/
5008ca48ce9SPierre Jolivet static inline PetscErrorCode PetscStrrchr(const char a[], char b, char *c[])
501bbcf679cSJacob Faibussowitsch {
502bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
503bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(a, 1);
5048ca48ce9SPierre Jolivet   PetscAssertPointer_Private(c, 3);
505bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_strrchr)
5068ca48ce9SPierre Jolivet   *c = (char *)__builtin_strrchr(a, b);
507bbcf679cSJacob Faibussowitsch #else
5088ca48ce9SPierre Jolivet   *c = (char *)strrchr(a, b);
509bbcf679cSJacob Faibussowitsch #endif
5108ca48ce9SPierre Jolivet   if (!*c) *c = (char *)a;
5118ca48ce9SPierre Jolivet   else *c = *c + 1;
512bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
513bbcf679cSJacob Faibussowitsch }
514bbcf679cSJacob Faibussowitsch 
515bbcf679cSJacob Faibussowitsch /*@C
516bbcf679cSJacob Faibussowitsch   PetscStrendswith - Determines if a string ends with a certain string
517bbcf679cSJacob Faibussowitsch 
518667f096bSBarry Smith   Not Collective, No Fortran Support
519bbcf679cSJacob Faibussowitsch 
520bbcf679cSJacob Faibussowitsch   Input Parameters:
521bbcf679cSJacob Faibussowitsch + a - string to search
522bbcf679cSJacob Faibussowitsch - b - string to end with
523bbcf679cSJacob Faibussowitsch 
524bbcf679cSJacob Faibussowitsch   Output Parameter:
525bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` ends with `b`, `PETSC_FALSE` otherwise
526bbcf679cSJacob Faibussowitsch 
527bbcf679cSJacob Faibussowitsch   Level: intermediate
528bbcf679cSJacob Faibussowitsch 
529bbcf679cSJacob Faibussowitsch   Notes:
530bbcf679cSJacob Faibussowitsch   Both `a` and `b` may be `NULL` (in which case `flg` is set to `PETSC_FALSE`) bot not either.
531bbcf679cSJacob Faibussowitsch 
532bbcf679cSJacob Faibussowitsch .seealso: `PetscStrendswithwhich()`, `PetscStrbeginswith()`, `PetscStrtoupper`,
533bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
534bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
535bbcf679cSJacob Faibussowitsch @*/
536bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrendswith(const char a[], const char b[], PetscBool *flg)
537bbcf679cSJacob Faibussowitsch {
538bbcf679cSJacob Faibussowitsch   size_t na = 0, nb = 0;
539bbcf679cSJacob Faibussowitsch 
540bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
541bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
542bbcf679cSJacob Faibussowitsch   // do this here to silence stupid "may be used uninitialized"" warnings
543bbcf679cSJacob Faibussowitsch   *flg = PETSC_FALSE;
544bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(a, &na));
545bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(b, &nb));
546bbcf679cSJacob Faibussowitsch   if (na >= nb) {
547bbcf679cSJacob Faibussowitsch #if PetscHasBuiltin(__builtin_memcmp)
548bbcf679cSJacob Faibussowitsch     *flg = __builtin_memcmp(b, a + (na - nb), nb) == 0 ? PETSC_TRUE : PETSC_FALSE;
549bbcf679cSJacob Faibussowitsch #else
550bbcf679cSJacob Faibussowitsch     *flg = memcmp(b, a + (na - nb), nb) == 0 ? PETSC_TRUE : PETSC_FALSE;
551bbcf679cSJacob Faibussowitsch #endif
552bbcf679cSJacob Faibussowitsch   }
553bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
554bbcf679cSJacob Faibussowitsch }
555bbcf679cSJacob Faibussowitsch 
556bbcf679cSJacob Faibussowitsch /*@C
557bbcf679cSJacob Faibussowitsch   PetscStrbeginswith - Determines if a string begins with a certain string
558bbcf679cSJacob Faibussowitsch 
559667f096bSBarry Smith   Not Collective, No Fortran Support
560bbcf679cSJacob Faibussowitsch 
561bbcf679cSJacob Faibussowitsch   Input Parameters:
562bbcf679cSJacob Faibussowitsch + a - string to search
563bbcf679cSJacob Faibussowitsch - b - string to begin with
564bbcf679cSJacob Faibussowitsch 
565bbcf679cSJacob Faibussowitsch   Output Parameter:
566bbcf679cSJacob Faibussowitsch . flg - `PETSC_TRUE` if `a` begins with `b`, `PETSC_FALSE` otherwise
567bbcf679cSJacob Faibussowitsch 
568bbcf679cSJacob Faibussowitsch   Level: intermediate
569bbcf679cSJacob Faibussowitsch 
570bbcf679cSJacob Faibussowitsch   Notes:
571bbcf679cSJacob Faibussowitsch   Both `a` and `b` may be `NULL` (in which case `flg` is set to `PETSC_FALSE`) but not
57216a05f60SBarry Smith   either.
57316a05f60SBarry Smith 
57416a05f60SBarry Smith   `a` and `b` may point to the same string.
575bbcf679cSJacob Faibussowitsch 
576bbcf679cSJacob Faibussowitsch .seealso: `PetscStrendswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`,
577bbcf679cSJacob Faibussowitsch           `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, `PetscStrncmp()`, `PetscStrlen()`,
578bbcf679cSJacob Faibussowitsch           `PetscStrcmp()`
579bbcf679cSJacob Faibussowitsch @*/
580bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg)
581bbcf679cSJacob Faibussowitsch {
582bbcf679cSJacob Faibussowitsch   size_t len = 0;
583bbcf679cSJacob Faibussowitsch 
584bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
585bbcf679cSJacob Faibussowitsch   PetscAssertPointer_Private(flg, 3);
586bbcf679cSJacob Faibussowitsch   // do this here to silence stupid "may be used uninitialized"" warnings
587bbcf679cSJacob Faibussowitsch   *flg = PETSC_FALSE;
588bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrlen(b, &len));
589bbcf679cSJacob Faibussowitsch   PetscCall(PetscStrncmp(a, b, len, flg));
590bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
591bbcf679cSJacob Faibussowitsch }
592bbcf679cSJacob Faibussowitsch 
593bbcf679cSJacob Faibussowitsch #undef PetscAssertPointer_Private
594bbcf679cSJacob Faibussowitsch 
595bbcf679cSJacob Faibussowitsch /*@C
59616a05f60SBarry Smith    PetscMemmove - Copies `n` bytes, beginning at location `b`, to the space
59716a05f60SBarry Smith    beginning at location `a`. Copying  between regions that overlap will
598bbcf679cSJacob Faibussowitsch    take place correctly. Use `PetscMemcpy()` if the locations do not overlap
599bbcf679cSJacob Faibussowitsch 
600bbcf679cSJacob Faibussowitsch    Not Collective
601bbcf679cSJacob Faibussowitsch 
602bbcf679cSJacob Faibussowitsch    Input Parameters:
603bbcf679cSJacob Faibussowitsch +  b - pointer to initial memory space
604bbcf679cSJacob Faibussowitsch .  a - pointer to copy space
605bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of space to copy
606bbcf679cSJacob Faibussowitsch 
607bbcf679cSJacob Faibussowitsch    Level: intermediate
608bbcf679cSJacob Faibussowitsch 
609bbcf679cSJacob Faibussowitsch    Notes:
610bbcf679cSJacob Faibussowitsch    `PetscArraymove()` is preferred
611bbcf679cSJacob Faibussowitsch 
612bbcf679cSJacob Faibussowitsch    This routine is analogous to `memmove()`.
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
65016a05f60SBarry Smith    PetscMemcpy - Copies `n` bytes, beginning at location `b`, to the space
65116a05f60SBarry Smith    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:
66616a05f60SBarry Smith     `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 .seealso: `PetscMemzero()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`
679bbcf679cSJacob Faibussowitsch @*/
680bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemcpy(void *a, const void *b, size_t n)
681bbcf679cSJacob Faibussowitsch {
682bbcf679cSJacob Faibussowitsch   const PETSC_UINTPTR_T al = (PETSC_UINTPTR_T)a;
683bbcf679cSJacob Faibussowitsch   const PETSC_UINTPTR_T bl = (PETSC_UINTPTR_T)b;
684bbcf679cSJacob Faibussowitsch 
685bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
686bbcf679cSJacob Faibussowitsch   if (PetscUnlikely((n == 0) || (a == b))) PetscFunctionReturn(PETSC_SUCCESS);
687bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes to a null pointer (Argument #1)", n);
688bbcf679cSJacob Faibussowitsch   PetscAssert(b, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to copy %zu bytes from a null pointer (Argument #2)", n);
689bbcf679cSJacob 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);
690bbcf679cSJacob Faibussowitsch   if (PetscDefined(PREFER_DCOPY_FOR_MEMCPY) || PetscDefined(PREFER_COPY_FOR_MEMCPY) || PetscDefined(PREFER_FORTRAN_FORMEMCPY)) {
691bbcf679cSJacob Faibussowitsch     if (!(al % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
692bbcf679cSJacob Faibussowitsch       const size_t       scalar_len = n / sizeof(PetscScalar);
693bbcf679cSJacob Faibussowitsch       const PetscScalar *x          = (PetscScalar *)b;
694bbcf679cSJacob Faibussowitsch       PetscScalar       *y          = (PetscScalar *)a;
695bbcf679cSJacob Faibussowitsch 
696bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_DCOPY_FOR_MEMCPY)
697bbcf679cSJacob Faibussowitsch       {
698bbcf679cSJacob Faibussowitsch         const PetscBLASInt one = 1;
699bbcf679cSJacob Faibussowitsch         PetscBLASInt       blen;
700bbcf679cSJacob Faibussowitsch 
701bbcf679cSJacob Faibussowitsch         PetscCall(PetscBLASIntCast(scalar_len, &blen));
702bbcf679cSJacob Faibussowitsch         PetscCallBLAS("BLAScopy", BLAScopy_(&blen, x, &one, y, &one));
703bbcf679cSJacob Faibussowitsch       }
704bbcf679cSJacob Faibussowitsch #elif PetscDefined(PREFER_FORTRAN_FORMEMCPY)
705bbcf679cSJacob Faibussowitsch       fortrancopy_(&scalar_len, x, y);
706bbcf679cSJacob Faibussowitsch #else
707bbcf679cSJacob Faibussowitsch       for (size_t i = 0; i < scalar_len; i++) y[i] = x[i];
708bbcf679cSJacob Faibussowitsch #endif
709bbcf679cSJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
710bbcf679cSJacob Faibussowitsch     }
711bbcf679cSJacob Faibussowitsch   }
712bbcf679cSJacob Faibussowitsch   memcpy(a, b, n);
713bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
714bbcf679cSJacob Faibussowitsch }
715bbcf679cSJacob Faibussowitsch 
716bbcf679cSJacob Faibussowitsch /*@C
717bbcf679cSJacob Faibussowitsch    PetscMemzero - Zeros the specified memory.
718bbcf679cSJacob Faibussowitsch 
719bbcf679cSJacob Faibussowitsch    Not Collective
720bbcf679cSJacob Faibussowitsch 
721bbcf679cSJacob Faibussowitsch    Input Parameters:
722bbcf679cSJacob Faibussowitsch +  a - pointer to beginning memory location
723bbcf679cSJacob Faibussowitsch -  n - length (in bytes) of memory to initialize
724bbcf679cSJacob Faibussowitsch 
725bbcf679cSJacob Faibussowitsch    Level: intermediate
726bbcf679cSJacob Faibussowitsch 
727bbcf679cSJacob Faibussowitsch    Compile Option:
728bbcf679cSJacob Faibussowitsch    `PETSC_PREFER_BZERO` - on certain machines (the IBM RS6000) the bzero() routine happens
729bbcf679cSJacob Faibussowitsch   to be faster than the memset() routine. This flag causes the bzero() routine to be used.
730bbcf679cSJacob Faibussowitsch 
731bbcf679cSJacob Faibussowitsch    Notes:
732bbcf679cSJacob Faibussowitsch    Prefer `PetscArrayzero()`
733bbcf679cSJacob Faibussowitsch 
734bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`
735bbcf679cSJacob Faibussowitsch @*/
736bbcf679cSJacob Faibussowitsch static inline PetscErrorCode PetscMemzero(void *a, size_t n)
737bbcf679cSJacob Faibussowitsch {
738bbcf679cSJacob Faibussowitsch   PetscFunctionBegin;
739bbcf679cSJacob Faibussowitsch   if (PetscUnlikely(n == 0)) PetscFunctionReturn(PETSC_SUCCESS);
740bbcf679cSJacob Faibussowitsch   PetscAssert(a, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to zero %zu bytes at a null pointer", n);
741bbcf679cSJacob Faibussowitsch   if (PetscDefined(PREFER_ZERO_FOR_MEMZERO) || PetscDefined(PREFER_FORTRAN_FOR_MEMZERO)) {
742bbcf679cSJacob Faibussowitsch     if (!(((PETSC_UINTPTR_T)a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
743bbcf679cSJacob Faibussowitsch       const size_t scalar_len = n / sizeof(PetscScalar);
744bbcf679cSJacob Faibussowitsch       PetscScalar *x          = (PetscScalar *)a;
745bbcf679cSJacob Faibussowitsch 
746bbcf679cSJacob Faibussowitsch       if (PetscDefined(PREFER_ZERO_FOR_MEMZERO)) {
747bbcf679cSJacob Faibussowitsch         for (size_t i = 0; i < scalar_len; ++i) x[i] = 0;
748bbcf679cSJacob Faibussowitsch       } else {
749bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_FORTRAN_FOR_MEMZERO)
750bbcf679cSJacob Faibussowitsch         fortranzero_(&scalar_len, x);
751bbcf679cSJacob Faibussowitsch #else
752bbcf679cSJacob Faibussowitsch         (void)scalar_len;
753bbcf679cSJacob Faibussowitsch         (void)x;
754bbcf679cSJacob Faibussowitsch #endif
755bbcf679cSJacob Faibussowitsch       }
756bbcf679cSJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
757bbcf679cSJacob Faibussowitsch     }
758bbcf679cSJacob Faibussowitsch   }
759bbcf679cSJacob Faibussowitsch #if PetscDefined(PREFER_BZERO)
760bbcf679cSJacob Faibussowitsch   bzero(a, n);
761bbcf679cSJacob Faibussowitsch #else
762bbcf679cSJacob Faibussowitsch   memset(a, 0, n);
763bbcf679cSJacob Faibussowitsch #endif
764bbcf679cSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
765bbcf679cSJacob Faibussowitsch }
766bbcf679cSJacob Faibussowitsch 
767bbcf679cSJacob Faibussowitsch /*MC
768bbcf679cSJacob Faibussowitsch    PetscArraycmp - Compares two arrays in memory.
769bbcf679cSJacob Faibussowitsch 
770bbcf679cSJacob Faibussowitsch    Synopsis:
771bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
772bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraycmp(const anytype *str1,const anytype *str2,size_t cnt,PetscBool *e)
773bbcf679cSJacob Faibussowitsch 
774bbcf679cSJacob Faibussowitsch    Not Collective
775bbcf679cSJacob Faibussowitsch 
776bbcf679cSJacob Faibussowitsch    Input Parameters:
777bbcf679cSJacob Faibussowitsch +  str1 - First array
778bbcf679cSJacob Faibussowitsch .  str2 - Second array
779bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
780bbcf679cSJacob Faibussowitsch 
7812fe279fdSBarry Smith    Output Parameter:
782bbcf679cSJacob Faibussowitsch .   e - `PETSC_TRUE` if equal else `PETSC_FALSE`.
783bbcf679cSJacob Faibussowitsch 
784bbcf679cSJacob Faibussowitsch    Level: intermediate
785bbcf679cSJacob Faibussowitsch 
786bbcf679cSJacob Faibussowitsch    Notes:
787bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemcmp()`
788bbcf679cSJacob Faibussowitsch 
789bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
790bbcf679cSJacob Faibussowitsch 
791bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`,
792bbcf679cSJacob Faibussowitsch           `PetscArraymove()`
793bbcf679cSJacob Faibussowitsch M*/
794bbcf679cSJacob Faibussowitsch #define PetscArraycmp(str1, str2, cnt, e) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemcmp((str1), (str2), (size_t)(cnt) * sizeof(*(str1)), (e)) : PETSC_ERR_ARG_SIZ)
795bbcf679cSJacob Faibussowitsch 
796bbcf679cSJacob Faibussowitsch /*MC
797bbcf679cSJacob Faibussowitsch    PetscArraymove - Copies from one array in memory to another, the arrays may overlap. Use `PetscArraycpy()` when the arrays
798bbcf679cSJacob Faibussowitsch                     do not overlap
799bbcf679cSJacob Faibussowitsch 
800bbcf679cSJacob Faibussowitsch    Synopsis:
801bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
802bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraymove(anytype *str1,const anytype *str2,size_t cnt)
803bbcf679cSJacob Faibussowitsch 
804bbcf679cSJacob Faibussowitsch    Not Collective
805bbcf679cSJacob Faibussowitsch 
806bbcf679cSJacob Faibussowitsch    Input Parameters:
807bbcf679cSJacob Faibussowitsch +  str1 - First array
808bbcf679cSJacob Faibussowitsch .  str2 - Second array
809bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
810bbcf679cSJacob Faibussowitsch 
811bbcf679cSJacob Faibussowitsch    Level: intermediate
812bbcf679cSJacob Faibussowitsch 
813bbcf679cSJacob Faibussowitsch    Notes:
814bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemmove()`
815bbcf679cSJacob Faibussowitsch 
816bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
817bbcf679cSJacob Faibussowitsch 
818bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscArraycmp()`, `PetscStrallocpy()`
819bbcf679cSJacob Faibussowitsch M*/
820bbcf679cSJacob Faibussowitsch #define PetscArraymove(str1, str2, cnt) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemmove((str1), (str2), (size_t)(cnt) * sizeof(*(str1))) : PETSC_ERR_ARG_SIZ)
821bbcf679cSJacob Faibussowitsch 
822bbcf679cSJacob Faibussowitsch /*MC
823bbcf679cSJacob Faibussowitsch    PetscArraycpy - Copies from one array in memory to another
824bbcf679cSJacob Faibussowitsch 
825bbcf679cSJacob Faibussowitsch    Synopsis:
826bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
827bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArraycpy(anytype *str1,const anytype *str2,size_t cnt)
828bbcf679cSJacob Faibussowitsch 
829bbcf679cSJacob Faibussowitsch    Not Collective
830bbcf679cSJacob Faibussowitsch 
831bbcf679cSJacob Faibussowitsch    Input Parameters:
832bbcf679cSJacob Faibussowitsch +  str1 - First array (destination)
833bbcf679cSJacob Faibussowitsch .  str2 - Second array (source)
834bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the arrays
835bbcf679cSJacob Faibussowitsch 
836bbcf679cSJacob Faibussowitsch    Level: intermediate
837bbcf679cSJacob Faibussowitsch 
838bbcf679cSJacob Faibussowitsch    Notes:
839bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemcpy()`
840bbcf679cSJacob Faibussowitsch 
841bbcf679cSJacob Faibussowitsch    The arrays must be of the same type
842bbcf679cSJacob Faibussowitsch 
843bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscArrayzero()`, `PetscMemzero()`, `PetscArraymove()`, `PetscMemmove()`, `PetscArraycmp()`, `PetscStrallocpy()`
844bbcf679cSJacob Faibussowitsch M*/
845bbcf679cSJacob Faibussowitsch #define PetscArraycpy(str1, str2, cnt) ((sizeof(*(str1)) == sizeof(*(str2))) ? PetscMemcpy((str1), (str2), (size_t)(cnt) * sizeof(*(str1))) : PETSC_ERR_ARG_SIZ)
846bbcf679cSJacob Faibussowitsch 
847bbcf679cSJacob Faibussowitsch /*MC
848bbcf679cSJacob Faibussowitsch    PetscArrayzero - Zeros an array in memory.
849bbcf679cSJacob Faibussowitsch 
850bbcf679cSJacob Faibussowitsch    Synopsis:
851bbcf679cSJacob Faibussowitsch     #include <petscstring.h>
852bbcf679cSJacob Faibussowitsch     PetscErrorCode PetscArrayzero(anytype *str1,size_t cnt)
853bbcf679cSJacob Faibussowitsch 
854bbcf679cSJacob Faibussowitsch    Not Collective
855bbcf679cSJacob Faibussowitsch 
856bbcf679cSJacob Faibussowitsch    Input Parameters:
857bbcf679cSJacob Faibussowitsch +  str1 - array
858bbcf679cSJacob Faibussowitsch -  cnt  - Count of the array, not in bytes, but number of entries in the array
859bbcf679cSJacob Faibussowitsch 
860bbcf679cSJacob Faibussowitsch    Level: intermediate
861bbcf679cSJacob Faibussowitsch 
862bbcf679cSJacob Faibussowitsch    Notes:
863bbcf679cSJacob Faibussowitsch    This routine is a preferred replacement to `PetscMemzero()`
864bbcf679cSJacob Faibussowitsch 
865bbcf679cSJacob Faibussowitsch .seealso: `PetscMemcpy()`, `PetscMemcmp()`, `PetscMemzero()`, `PetscArraycmp()`, `PetscArraycpy()`, `PetscMemmove()`, `PetscStrallocpy()`, `PetscArraymove()`
866bbcf679cSJacob Faibussowitsch M*/
867bbcf679cSJacob Faibussowitsch #define PetscArrayzero(str1, cnt) PetscMemzero((str1), (size_t)(cnt) * sizeof(*(str1)))
868bbcf679cSJacob Faibussowitsch 
869bbcf679cSJacob Faibussowitsch #endif // PETSC_STRING_H
870