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

Generated by: LCOV version 1.14