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