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