LCOV - code coverage report
Current view: top level - home/gitlab-runner/builds/q8svuz_Y/0/slepc/petsc/include - petscstring.h (source / functions) Hit Total Coverage
Test: SLEPc Lines: 94 100 94.0 %
Date: 2025-02-05 00:35:45 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14