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