1e5c89e4eSSatish Balay /* 2e5c89e4eSSatish Balay We define the string operations here. The reason we just do not use 3e5c89e4eSSatish Balay the standard string routines in the PETSc code is that on some machines 4e5c89e4eSSatish Balay they are broken or have the wrong prototypes. 5e5c89e4eSSatish Balay 6e5c89e4eSSatish Balay */ 75f80ce2aSJacob Faibussowitsch #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 83964eb88SJed Brown #if defined(PETSC_HAVE_STRINGS_H) 93964eb88SJed Brown #include <strings.h> /* strcasecmp */ 103964eb88SJed Brown #endif 113964eb88SJed Brown 123c311c98SBarry Smith /*@C 1351a1f156SVaclav Hapla PetscStrToArray - Separates a string by a character (for example ' ' or '\n') and creates an array of strings 143c311c98SBarry Smith 153c311c98SBarry Smith Not Collective 163c311c98SBarry Smith 173c311c98SBarry Smith Input Parameters: 18d67fe73bSBarry Smith + s - pointer to string 1951a1f156SVaclav Hapla - sp - separator character 203c311c98SBarry Smith 21d8d19677SJose E. Roman Output Parameters: 223c311c98SBarry Smith + argc - the number of entries in the array 233c311c98SBarry Smith - args - an array of the entries with a null at the end 243c311c98SBarry Smith 253c311c98SBarry Smith Level: intermediate 263c311c98SBarry Smith 27811af0c4SBarry Smith Note: 2895452b02SPatrick Sanan this may be called before PetscInitialize() or after PetscFinalize() 293c311c98SBarry Smith 30811af0c4SBarry Smith Fortran Note: 316f013253SBarry Smith Not for use in Fortran 326f013253SBarry Smith 3395452b02SPatrick Sanan Developer Notes: 34811af0c4SBarry Smith Uses raw `malloc()` and does not call error handlers since this may be used before PETSc is initialized. 35811af0c4SBarry Smith 36811af0c4SBarry Smith Used to generate argc, args arguments passed to `MPI_Init()` 37301d30feSBarry Smith 38db781477SPatrick Sanan .seealso: `PetscStrToArrayDestroy()`, `PetscToken`, `PetscTokenCreate()` 393c311c98SBarry Smith @*/ 40d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrToArray(const char s[], char sp, int *argc, char ***args) 41d71ae5a4SJacob Faibussowitsch { 42c3bcdc7eSBarry Smith int i, j, n, *lens, cnt = 0; 43ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 443c311c98SBarry Smith 4540a7e1efSBarry Smith if (!s) n = 0; 4640a7e1efSBarry Smith else n = strlen(s); 473c311c98SBarry Smith *argc = 0; 4861528463SBarry Smith *args = NULL; 49acf7dc08SSatish Balay for (; n > 0; n--) { /* remove separator chars at the end - and will empty the string if all chars are separator chars */ 50acf7dc08SSatish Balay if (s[n - 1] != sp) break; 51acf7dc08SSatish Balay } 525f80ce2aSJacob Faibussowitsch if (!n) return 0; 533c311c98SBarry Smith for (i = 0; i < n; i++) { 54d67fe73bSBarry Smith if (s[i] != sp) break; 553c311c98SBarry Smith } 563c311c98SBarry Smith for (; i < n + 1; i++) { 579371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 589371c9d4SSatish Balay flg = PETSC_TRUE; 599371c9d4SSatish Balay (*argc)++; 609371c9d4SSatish Balay } else if (s[i] != sp) { 619371c9d4SSatish Balay flg = PETSC_FALSE; 623c311c98SBarry Smith } 639371c9d4SSatish Balay } 649371c9d4SSatish Balay (*args) = (char **)malloc(((*argc) + 1) * sizeof(char *)); 659371c9d4SSatish Balay if (!*args) return PETSC_ERR_MEM; 669371c9d4SSatish Balay lens = (int *)malloc((*argc) * sizeof(int)); 679371c9d4SSatish Balay if (!lens) return PETSC_ERR_MEM; 683c311c98SBarry Smith for (i = 0; i < *argc; i++) lens[i] = 0; 693c311c98SBarry Smith 703c311c98SBarry Smith *argc = 0; 713c311c98SBarry Smith for (i = 0; i < n; i++) { 72d67fe73bSBarry Smith if (s[i] != sp) break; 733c311c98SBarry Smith } 747dd9f305SSatish Balay for (; i < n + 1; i++) { 759371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 769371c9d4SSatish Balay flg = PETSC_TRUE; 779371c9d4SSatish Balay (*argc)++; 789371c9d4SSatish Balay } else if (s[i] != sp) { 799371c9d4SSatish Balay lens[*argc]++; 809371c9d4SSatish Balay flg = PETSC_FALSE; 819371c9d4SSatish Balay } 823c311c98SBarry Smith } 833c311c98SBarry Smith 843c311c98SBarry Smith for (i = 0; i < *argc; i++) { 85c3bcdc7eSBarry Smith (*args)[i] = (char *)malloc((lens[i] + 1) * sizeof(char)); 86c3bcdc7eSBarry Smith if (!(*args)[i]) { 87c3bcdc7eSBarry Smith free(lens); 88c3bcdc7eSBarry Smith for (j = 0; j < i; j++) free((*args)[j]); 89c3bcdc7eSBarry Smith free(*args); 90c3bcdc7eSBarry Smith return PETSC_ERR_MEM; 91c3bcdc7eSBarry Smith } 923c311c98SBarry Smith } 93a2ea699eSBarry Smith free(lens); 9402c9f0b5SLisandro Dalcin (*args)[*argc] = NULL; 953c311c98SBarry Smith 963c311c98SBarry Smith *argc = 0; 973c311c98SBarry Smith for (i = 0; i < n; i++) { 98d67fe73bSBarry Smith if (s[i] != sp) break; 993c311c98SBarry Smith } 1003c311c98SBarry Smith for (; i < n + 1; i++) { 1019371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 1029371c9d4SSatish Balay flg = PETSC_TRUE; 1039371c9d4SSatish Balay (*args)[*argc][cnt++] = 0; 1049371c9d4SSatish Balay (*argc)++; 1059371c9d4SSatish Balay cnt = 0; 1069371c9d4SSatish Balay } else if (s[i] != sp && s[i] != 0) { 1079371c9d4SSatish Balay (*args)[*argc][cnt++] = s[i]; 1089371c9d4SSatish Balay flg = PETSC_FALSE; 1099371c9d4SSatish Balay } 1103c311c98SBarry Smith } 1113c311c98SBarry Smith return 0; 1123c311c98SBarry Smith } 1133c311c98SBarry Smith 114301d30feSBarry Smith /*@C 115811af0c4SBarry Smith PetscStrToArrayDestroy - Frees array created with `PetscStrToArray()`. 116301d30feSBarry Smith 117301d30feSBarry Smith Not Collective 118301d30feSBarry Smith 119301d30feSBarry Smith Output Parameters: 120301d30feSBarry Smith + argc - the number of arguments 121301d30feSBarry Smith - args - the array of arguments 122301d30feSBarry Smith 123301d30feSBarry Smith Level: intermediate 124301d30feSBarry Smith 125811af0c4SBarry Smith Note: 126811af0c4SBarry Smith This may be called before `PetscInitialize()` or after `PetscFinalize()` 127301d30feSBarry Smith 128811af0c4SBarry Smith Fortran Note: 1296f013253SBarry Smith Not for use in Fortran 1306f013253SBarry Smith 131db781477SPatrick Sanan .seealso: `PetscStrToArray()` 132301d30feSBarry Smith @*/ 133d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrToArrayDestroy(int argc, char **args) 134d71ae5a4SJacob Faibussowitsch { 1355f80ce2aSJacob Faibussowitsch for (int i = 0; i < argc; ++i) free(args[i]); 136a297a907SKarl Rupp if (args) free(args); 137301d30feSBarry Smith return 0; 138301d30feSBarry Smith } 139301d30feSBarry Smith 140e5c89e4eSSatish Balay /*@C 141e5c89e4eSSatish Balay PetscStrlen - Gets length of a string 142e5c89e4eSSatish Balay 143e5c89e4eSSatish Balay Not Collective 144e5c89e4eSSatish Balay 145e5c89e4eSSatish Balay Input Parameters: 146e5c89e4eSSatish Balay . s - pointer to string 147e5c89e4eSSatish Balay 148e5c89e4eSSatish Balay Output Parameter: 149e5c89e4eSSatish Balay . len - length in bytes 150e5c89e4eSSatish Balay 151e5c89e4eSSatish Balay Level: intermediate 152e5c89e4eSSatish Balay 153e5c89e4eSSatish Balay Note: 154811af0c4SBarry Smith This routine is analogous to `strlen()`. 155e5c89e4eSSatish Balay 156e5c89e4eSSatish Balay Null string returns a length of zero 157e5c89e4eSSatish Balay 158811af0c4SBarry Smith Fortran Note: 1596f013253SBarry Smith Not for use in Fortran 1606f013253SBarry Smith 161811af0c4SBarry Smith .seealso: `PetscStrallocpy()` 162e5c89e4eSSatish Balay @*/ 163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrlen(const char s[], size_t *len) 164d71ae5a4SJacob Faibussowitsch { 165e5c89e4eSSatish Balay PetscFunctionBegin; 1665f80ce2aSJacob Faibussowitsch *len = s ? strlen(s) : 0; 167e5c89e4eSSatish Balay PetscFunctionReturn(0); 168e5c89e4eSSatish Balay } 169e5c89e4eSSatish Balay 170e5c89e4eSSatish Balay /*@C 171811af0c4SBarry Smith PetscStrallocpy - Allocates space to hold a copy of a string then copies the string in the new space 172e5c89e4eSSatish Balay 173e5c89e4eSSatish Balay Not Collective 174e5c89e4eSSatish Balay 175e5c89e4eSSatish Balay Input Parameters: 176e5c89e4eSSatish Balay . s - pointer to string 177e5c89e4eSSatish Balay 178e5c89e4eSSatish Balay Output Parameter: 179e5c89e4eSSatish Balay . t - the copied string 180e5c89e4eSSatish Balay 181e5c89e4eSSatish Balay Level: intermediate 182e5c89e4eSSatish Balay 183811af0c4SBarry Smith Notes: 184e5c89e4eSSatish Balay Null string returns a new null string 185e5c89e4eSSatish Balay 186811af0c4SBarry Smith If t has previously been allocated then that memory is lost, you may need to PetscFree() 1870ecf5a55SBarry Smith the array before calling this routine. 1880ecf5a55SBarry Smith 189811af0c4SBarry Smith Fortran Note: 190811af0c4SBarry Smith Not for use in Fortran 1910ecf5a55SBarry Smith 192811af0c4SBarry Smith .seealso: `PetscStrArrayallocpy()`, `PetscStrcpy()`, `PetscStrNArrayallocpy()` 193e5c89e4eSSatish Balay @*/ 194d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrallocpy(const char s[], char *t[]) 195d71ae5a4SJacob Faibussowitsch { 19602c9f0b5SLisandro Dalcin char *tmp = NULL; 197e5c89e4eSSatish Balay 198e5c89e4eSSatish Balay PetscFunctionBegin; 199e5c89e4eSSatish Balay if (s) { 2005f80ce2aSJacob Faibussowitsch size_t len; 2015f80ce2aSJacob Faibussowitsch 2029566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s, &len)); 2039566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1 + len, &tmp)); 2049566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(tmp, s)); 205e5c89e4eSSatish Balay } 20671573d7dSBarry Smith *t = tmp; 207e5c89e4eSSatish Balay PetscFunctionReturn(0); 208e5c89e4eSSatish Balay } 209e5c89e4eSSatish Balay 21047340559SBarry Smith /*@C 21147340559SBarry Smith PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 21247340559SBarry Smith 21347340559SBarry Smith Not Collective 21447340559SBarry Smith 21547340559SBarry Smith Input Parameters: 21647340559SBarry Smith . s - pointer to array of strings (final string is a null) 21747340559SBarry Smith 21847340559SBarry Smith Output Parameter: 21947340559SBarry Smith . t - the copied array string 22047340559SBarry Smith 22147340559SBarry Smith Level: intermediate 22247340559SBarry Smith 22347340559SBarry Smith Note: 224811af0c4SBarry Smith If t has previously been allocated then that memory is lost, you may need to PetscStrArrayDestroy() 2250ecf5a55SBarry Smith the array before calling this routine. 2260ecf5a55SBarry Smith 227811af0c4SBarry Smith Fortran Note: 228811af0c4SBarry Smith Not for use in Fortran 22947340559SBarry Smith 230811af0c4SBarry Smith .seealso: `PetscStrallocpy()`, `PetscStrArrayDestroy()`, `PetscStrNArrayallocpy()` 23147340559SBarry Smith @*/ 232d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrArrayallocpy(const char *const *list, char ***t) 233d71ae5a4SJacob Faibussowitsch { 2345f80ce2aSJacob Faibussowitsch PetscInt n = 0; 23547340559SBarry Smith 23647340559SBarry Smith PetscFunctionBegin; 2379371c9d4SSatish Balay while (list[n++]) 2389371c9d4SSatish Balay ; 2399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n + 1, t)); 2409566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 2410298fd71SBarry Smith (*t)[n] = NULL; 24247340559SBarry Smith PetscFunctionReturn(0); 24347340559SBarry Smith } 24447340559SBarry Smith 24547340559SBarry Smith /*@C 246811af0c4SBarry Smith PetscStrArrayDestroy - Frees array of strings created with `PetscStrArrayallocpy()`. 24747340559SBarry Smith 24847340559SBarry Smith Not Collective 24947340559SBarry Smith 25047340559SBarry Smith Output Parameters: 25147340559SBarry Smith . list - array of strings 25247340559SBarry Smith 25347340559SBarry Smith Level: intermediate 25447340559SBarry Smith 255811af0c4SBarry Smith Fortran Note: 25695452b02SPatrick Sanan Not for use in Fortran 25747340559SBarry Smith 258db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()` 25947340559SBarry Smith @*/ 260d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrArrayDestroy(char ***list) 261d71ae5a4SJacob Faibussowitsch { 26247340559SBarry Smith PetscInt n = 0; 26347340559SBarry Smith 2646fed8037SJed Brown PetscFunctionBegin; 2656fed8037SJed Brown if (!*list) PetscFunctionReturn(0); 2666fed8037SJed Brown while ((*list)[n]) { 2679566063dSJacob Faibussowitsch PetscCall(PetscFree((*list)[n])); 2685f80ce2aSJacob Faibussowitsch ++n; 26947340559SBarry Smith } 2709566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 2716fed8037SJed Brown PetscFunctionReturn(0); 27247340559SBarry Smith } 27347340559SBarry Smith 2746991f827SBarry Smith /*@C 2756991f827SBarry Smith PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 2766991f827SBarry Smith 2776991f827SBarry Smith Not Collective 2786991f827SBarry Smith 2796991f827SBarry Smith Input Parameters: 2806991f827SBarry Smith + n - the number of string entries 2816991f827SBarry Smith - s - pointer to array of strings 2826991f827SBarry Smith 2836991f827SBarry Smith Output Parameter: 2846991f827SBarry Smith . t - the copied array string 2856991f827SBarry Smith 2866991f827SBarry Smith Level: intermediate 2876991f827SBarry Smith 288811af0c4SBarry Smith Fortran Note: 2896991f827SBarry Smith Not for use in Fortran 2906991f827SBarry Smith 291db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayallocpy()`, `PetscStrNArrayDestroy()` 2926991f827SBarry Smith @*/ 293d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrNArrayallocpy(PetscInt n, const char *const *list, char ***t) 294d71ae5a4SJacob Faibussowitsch { 2956991f827SBarry Smith PetscFunctionBegin; 2969566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, t)); 2979566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 2986991f827SBarry Smith PetscFunctionReturn(0); 2996991f827SBarry Smith } 3006991f827SBarry Smith 3016991f827SBarry Smith /*@C 302811af0c4SBarry Smith PetscStrNArrayDestroy - Frees array of strings created with `PetscStrNArrayallocpy()`. 3036991f827SBarry Smith 3046991f827SBarry Smith Not Collective 3056991f827SBarry Smith 3066991f827SBarry Smith Output Parameters: 3076991f827SBarry Smith + n - number of string entries 3086991f827SBarry Smith - list - array of strings 3096991f827SBarry Smith 3106991f827SBarry Smith Level: intermediate 3116991f827SBarry Smith 312811af0c4SBarry Smith Fortran Note: 31395452b02SPatrick Sanan Not for use in Fortran 3146991f827SBarry Smith 315811af0c4SBarry Smith .seealso: `PetscStrNArrayallocpy()`, `PetscStrArrayallocpy()` 3166991f827SBarry Smith @*/ 317d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrNArrayDestroy(PetscInt n, char ***list) 318d71ae5a4SJacob Faibussowitsch { 3196991f827SBarry Smith PetscFunctionBegin; 3206991f827SBarry Smith if (!*list) PetscFunctionReturn(0); 3219566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscFree((*list)[i])); 3229566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 3236991f827SBarry Smith PetscFunctionReturn(0); 3246991f827SBarry Smith } 3256991f827SBarry Smith 326e5c89e4eSSatish Balay /*@C 327e5c89e4eSSatish Balay PetscStrcpy - Copies a string 328e5c89e4eSSatish Balay 329e5c89e4eSSatish Balay Not Collective 330e5c89e4eSSatish Balay 331e5c89e4eSSatish Balay Input Parameters: 332e5c89e4eSSatish Balay . t - pointer to string 333e5c89e4eSSatish Balay 334e5c89e4eSSatish Balay Output Parameter: 335e5c89e4eSSatish Balay . s - the copied string 336e5c89e4eSSatish Balay 337e5c89e4eSSatish Balay Level: intermediate 338e5c89e4eSSatish Balay 3396f013253SBarry Smith Notes: 340e5c89e4eSSatish Balay Null string returns a string starting with zero 341e5c89e4eSSatish Balay 342811af0c4SBarry Smith It is recommended you use `PetscStrncpy()` instead of this routine 343811af0c4SBarry Smith 344811af0c4SBarry Smith Fortran Note: 3456f013253SBarry Smith Not for use in Fortran 3466f013253SBarry Smith 347811af0c4SBarry Smith .seealso: `PetscStrncpy()`, `PetscStrcat()`, `PetscStrlcat()`, `PetscStrallocpy()` 348e5c89e4eSSatish Balay @*/ 349acc6cc86SBarry Smith 350d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrcpy(char s[], const char t[]) 351d71ae5a4SJacob Faibussowitsch { 352e5c89e4eSSatish Balay PetscFunctionBegin; 3535f80ce2aSJacob Faibussowitsch if (t) { 3545f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s, 1); 3555f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t, 2); 3565f80ce2aSJacob Faibussowitsch strcpy(s, t); 3575f80ce2aSJacob Faibussowitsch } else if (s) s[0] = 0; 358e5c89e4eSSatish Balay PetscFunctionReturn(0); 359e5c89e4eSSatish Balay } 360e5c89e4eSSatish Balay 361e5c89e4eSSatish Balay /*@C 362e5c89e4eSSatish Balay PetscStrncpy - Copies a string up to a certain length 363e5c89e4eSSatish Balay 364e5c89e4eSSatish Balay Not Collective 365e5c89e4eSSatish Balay 366e5c89e4eSSatish Balay Input Parameters: 367e5c89e4eSSatish Balay + t - pointer to string 368e5c89e4eSSatish Balay - n - the length to copy 369e5c89e4eSSatish Balay 370e5c89e4eSSatish Balay Output Parameter: 371e5c89e4eSSatish Balay . s - the copied string 372e5c89e4eSSatish Balay 373e5c89e4eSSatish Balay Level: intermediate 374e5c89e4eSSatish Balay 375e5c89e4eSSatish Balay Note: 376e5c89e4eSSatish Balay Null string returns a string starting with zero 377e5c89e4eSSatish Balay 378ff32304bSBarry Smith If the string that is being copied is of length n or larger then the entire string is not 3791b6ef838SBarry Smith copied and the final location of s is set to NULL. This is different then the behavior of 380811af0c4SBarry Smith `strncpy()` which leaves s non-terminated if there is not room for the entire string. 381ff32304bSBarry Smith 382811af0c4SBarry Smith Developers Note: 383811af0c4SBarry Smith Should this be `PetscStrlcpy()` to reflect its behavior which is like `strlcpy()` not `strncpy()` 38462a5de14SBarry Smith 385811af0c4SBarry Smith .seealso: `PetscStrcpy()`, `PetscStrcat()`, `PetscStrlcat()`, `PetscStrallocpy()` 386e5c89e4eSSatish Balay @*/ 387d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrncpy(char s[], const char t[], size_t n) 388d71ae5a4SJacob Faibussowitsch { 389e5c89e4eSSatish Balay PetscFunctionBegin; 3905f80ce2aSJacob Faibussowitsch if (s) PetscCheck(n, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Requires an output string of length at least 1 to hold the termination character"); 391ff32304bSBarry Smith if (t) { 3925f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s, 1); 3938dc57659SBarry Smith if (n > 1) { 3942c26941aSBarry Smith strncpy(s, t, n - 1); 395ff32304bSBarry Smith s[n - 1] = '\0'; 3968dc57659SBarry Smith } else { 3978dc57659SBarry Smith s[0] = '\0'; 3988dc57659SBarry Smith } 399ff32304bSBarry Smith } else if (s) s[0] = 0; 400e5c89e4eSSatish Balay PetscFunctionReturn(0); 401e5c89e4eSSatish Balay } 402e5c89e4eSSatish Balay 403e5c89e4eSSatish Balay /*@C 404e5c89e4eSSatish Balay PetscStrcat - Concatenates a string onto a given string 405e5c89e4eSSatish Balay 406e5c89e4eSSatish Balay Not Collective 407e5c89e4eSSatish Balay 408e5c89e4eSSatish Balay Input Parameters: 409e5e2177aSMatthew Knepley + s - string to be added to 410e5e2177aSMatthew Knepley - t - pointer to string to be added to end 411e5c89e4eSSatish Balay 412e5c89e4eSSatish Balay Level: intermediate 413e5c89e4eSSatish Balay 414811af0c4SBarry Smith Note: 415811af0c4SBarry Smith It is recommended you use `PetscStrlcat()` instead of this routine 416811af0c4SBarry Smith 417811af0c4SBarry Smith Fortran Note: 41895452b02SPatrick Sanan Not for use in Fortran 4196f013253SBarry Smith 420db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrncpy()`, `PetscStrlcat()` 421e5c89e4eSSatish Balay @*/ 422d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrcat(char s[], const char t[]) 423d71ae5a4SJacob Faibussowitsch { 424e5c89e4eSSatish Balay PetscFunctionBegin; 4259b754dc9SBarry Smith if (!t) PetscFunctionReturn(0); 4265f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s, 1); 4275f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t, 2); 428e5c89e4eSSatish Balay strcat(s, t); 429e5c89e4eSSatish Balay PetscFunctionReturn(0); 430e5c89e4eSSatish Balay } 431e5c89e4eSSatish Balay 432e5c89e4eSSatish Balay /*@C 433a126751eSBarry Smith PetscStrlcat - Concatenates a string onto a given string, up to a given length 434e5c89e4eSSatish Balay 435e5c89e4eSSatish Balay Not Collective 436e5c89e4eSSatish Balay 437e5c89e4eSSatish Balay Input Parameters: 438e0ffd71fSBarry Smith + s - pointer to string to be added to at end 43972fa4726SStefano Zampini . t - string to be added 44024a58d73SPatrick Sanan - n - length of the original allocated string 441e5c89e4eSSatish Balay 442e5c89e4eSSatish Balay Level: intermediate 443e5c89e4eSSatish Balay 444811af0c4SBarry Smith Note: 445811af0c4SBarry Smith Unlike the system call `strncat()`, the length passed in is the length of the 446811af0c4SBarry Smith original allocated space, not the length of the left-over space. This is 447811af0c4SBarry Smith similar to the BSD system call `strlcat()`. 448811af0c4SBarry Smith 449811af0c4SBarry Smith Fortran Note: 45024a58d73SPatrick Sanan Not for use in Fortran 4516f013253SBarry Smith 452db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrncpy()`, `PetscStrcat()` 453e5c89e4eSSatish Balay @*/ 454d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrlcat(char s[], const char t[], size_t n) 455d71ae5a4SJacob Faibussowitsch { 456153a8027SBarry Smith size_t len; 457153a8027SBarry Smith 458e5c89e4eSSatish Balay PetscFunctionBegin; 459e0ffd71fSBarry Smith if (!t) PetscFunctionReturn(0); 4605f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s, 1); 4615f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t, 2); 4625f80ce2aSJacob Faibussowitsch PetscCheck(n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "String buffer length must be positive"); 4639566063dSJacob Faibussowitsch PetscCall(PetscStrlen(t, &len)); 464153a8027SBarry Smith strncat(s, t, n - len); 465681eeb0aSBarry Smith s[n - 1] = 0; 466e5c89e4eSSatish Balay PetscFunctionReturn(0); 467e5c89e4eSSatish Balay } 468e5c89e4eSSatish Balay 469d71ae5a4SJacob Faibussowitsch void PetscStrcmpNoError(const char a[], const char b[], PetscBool *flg) 470d71ae5a4SJacob Faibussowitsch { 471573b0fb4SBarry Smith if (!a && !b) *flg = PETSC_TRUE; 472573b0fb4SBarry Smith else if (!a || !b) *flg = PETSC_FALSE; 4735f80ce2aSJacob Faibussowitsch else *flg = strcmp(a, b) ? PETSC_FALSE : PETSC_TRUE; 474573b0fb4SBarry Smith } 475573b0fb4SBarry Smith 476e5c89e4eSSatish Balay /*@C 477811af0c4SBarry Smith PetscBasename - returns a pointer to the last entry of a / or \ separated directory path 47880b92c66SBarry Smith 47980b92c66SBarry Smith Not Collective 48080b92c66SBarry Smith 48180b92c66SBarry Smith Input Parameter: 48280b92c66SBarry Smith . a - pointer to string 48380b92c66SBarry Smith 48480b92c66SBarry Smith Level: intermediate 48580b92c66SBarry Smith 486811af0c4SBarry Smith Fortran Note: 48780b92c66SBarry Smith Not for use in Fortran 48880b92c66SBarry Smith 48980b92c66SBarry Smith .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`, `PetscStrrchr()`, `PetscStrcmp()`, `PetscStrstr()`, 49080b92c66SBarry Smith `PetscTokenCreate()`, `PetscStrToArray()`, `PetscStrInList()` 49180b92c66SBarry Smith @*/ 492d71ae5a4SJacob Faibussowitsch const char *PetscBasename(const char a[]) 493d71ae5a4SJacob Faibussowitsch { 49480b92c66SBarry Smith const char *ptr; 49580b92c66SBarry Smith 49680b92c66SBarry Smith if (PetscStrrchr(a, '/', (char **)&ptr)) ptr = NULL; 497660278c0SBarry Smith if (ptr == a) { 498660278c0SBarry Smith if (PetscStrrchr(a, '\\', (char **)&ptr)) ptr = NULL; 499660278c0SBarry Smith } 50080b92c66SBarry Smith return ptr; 50180b92c66SBarry Smith } 50280b92c66SBarry Smith 50380b92c66SBarry Smith /*@C 504e5c89e4eSSatish Balay PetscStrcmp - Compares two strings, 505e5c89e4eSSatish Balay 506e5c89e4eSSatish Balay Not Collective 507e5c89e4eSSatish Balay 508e5c89e4eSSatish Balay Input Parameters: 509e5c89e4eSSatish Balay + a - pointer to string first string 510e5c89e4eSSatish Balay - b - pointer to second string 511e5c89e4eSSatish Balay 512e5c89e4eSSatish Balay Output Parameter: 513811af0c4SBarry Smith . flg - `PETSC_TRUE` if the two strings are equal 514e5c89e4eSSatish Balay 515e5c89e4eSSatish Balay Level: intermediate 516e5c89e4eSSatish Balay 517811af0c4SBarry Smith Fortran Note: 51895452b02SPatrick Sanan Not for use in Fortran 5196f013253SBarry Smith 520db781477SPatrick Sanan .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()` 521e5c89e4eSSatish Balay @*/ 522d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrcmp(const char a[], const char b[], PetscBool *flg) 523d71ae5a4SJacob Faibussowitsch { 524e5c89e4eSSatish Balay PetscFunctionBegin; 5255f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg, 3); 526a297a907SKarl Rupp if (!a && !b) *flg = PETSC_TRUE; 527a297a907SKarl Rupp else if (!a || !b) *flg = PETSC_FALSE; 528b45e3bf4SStefano Zampini else *flg = (PetscBool)!strcmp(a, b); 529e5c89e4eSSatish Balay PetscFunctionReturn(0); 530e5c89e4eSSatish Balay } 531e5c89e4eSSatish Balay 532e5c89e4eSSatish Balay /*@C 533e5c89e4eSSatish Balay PetscStrgrt - If first string is greater than the second 534e5c89e4eSSatish Balay 535e5c89e4eSSatish Balay Not Collective 536e5c89e4eSSatish Balay 537e5c89e4eSSatish Balay Input Parameters: 538e5c89e4eSSatish Balay + a - pointer to first string 539e5c89e4eSSatish Balay - b - pointer to second string 540e5c89e4eSSatish Balay 541e5c89e4eSSatish Balay Output Parameter: 542e5c89e4eSSatish Balay . flg - if the first string is greater 543e5c89e4eSSatish Balay 544811af0c4SBarry Smith Note: 545e5c89e4eSSatish Balay Null arguments are ok, a null string is considered smaller than 546e5c89e4eSSatish Balay all others 547e5c89e4eSSatish Balay 548811af0c4SBarry Smith Fortran Note: 5496f013253SBarry Smith Not for use in Fortran 5506f013253SBarry Smith 551e5c89e4eSSatish Balay Level: intermediate 552e5c89e4eSSatish Balay 553db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrcasecmp()` 554e5c89e4eSSatish Balay @*/ 555d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrgrt(const char a[], const char b[], PetscBool *t) 556d71ae5a4SJacob Faibussowitsch { 557e5c89e4eSSatish Balay PetscFunctionBegin; 5585f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t, 3); 559a297a907SKarl Rupp if (!a && !b) *t = PETSC_FALSE; 560a297a907SKarl Rupp else if (a && !b) *t = PETSC_TRUE; 561a297a907SKarl Rupp else if (!a && b) *t = PETSC_FALSE; 562a297a907SKarl Rupp else { 5635f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 5645f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 2); 5655f80ce2aSJacob Faibussowitsch *t = strcmp(a, b) > 0 ? PETSC_TRUE : PETSC_FALSE; 566e5c89e4eSSatish Balay } 567e5c89e4eSSatish Balay PetscFunctionReturn(0); 568e5c89e4eSSatish Balay } 569e5c89e4eSSatish Balay 570e5c89e4eSSatish Balay /*@C 571e5c89e4eSSatish Balay PetscStrcasecmp - Returns true if the two strings are the same 572e5c89e4eSSatish Balay except possibly for case. 573e5c89e4eSSatish Balay 574e5c89e4eSSatish Balay Not Collective 575e5c89e4eSSatish Balay 576e5c89e4eSSatish Balay Input Parameters: 577e5c89e4eSSatish Balay + a - pointer to first string 578e5c89e4eSSatish Balay - b - pointer to second string 579e5c89e4eSSatish Balay 580e5c89e4eSSatish Balay Output Parameter: 581e5c89e4eSSatish Balay . flg - if the two strings are the same 582e5c89e4eSSatish Balay 583811af0c4SBarry Smith Note: 584e5c89e4eSSatish Balay Null arguments are ok 585e5c89e4eSSatish Balay 586811af0c4SBarry Smith Fortran Note: 5876f013253SBarry Smith Not for use in Fortran 5886f013253SBarry Smith 589e5c89e4eSSatish Balay Level: intermediate 590e5c89e4eSSatish Balay 591db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrgrt()` 592e5c89e4eSSatish Balay @*/ 593d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrcasecmp(const char a[], const char b[], PetscBool *t) 594d71ae5a4SJacob Faibussowitsch { 595e5c89e4eSSatish Balay int c; 596e5c89e4eSSatish Balay 597e5c89e4eSSatish Balay PetscFunctionBegin; 5985f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t, 3); 599e5c89e4eSSatish Balay if (!a && !b) c = 0; 600e5c89e4eSSatish Balay else if (!a || !b) c = 1; 60132b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP) 60232b366c8SSatish Balay else c = strcasecmp(a, b); 60332b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP) 604e5c89e4eSSatish Balay else c = stricmp(a, b); 605e5c89e4eSSatish Balay #else 60632b366c8SSatish Balay else { 60732b366c8SSatish Balay char *aa, *bb; 6089566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &aa)); 6099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(b, &bb)); 6109566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(aa)); 6119566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(bb)); 6129566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(aa, bb, t)); 6139566063dSJacob Faibussowitsch PetscCall(PetscFree(aa)); 6149566063dSJacob Faibussowitsch PetscCall(PetscFree(bb)); 61532b366c8SSatish Balay PetscFunctionReturn(0); 61632b366c8SSatish Balay } 617e5c89e4eSSatish Balay #endif 6185f80ce2aSJacob Faibussowitsch *t = c ? PETSC_FALSE : PETSC_TRUE; 619e5c89e4eSSatish Balay PetscFunctionReturn(0); 620e5c89e4eSSatish Balay } 621e5c89e4eSSatish Balay 622e5c89e4eSSatish Balay /*@C 623e5c89e4eSSatish Balay PetscStrncmp - Compares two strings, up to a certain length 624e5c89e4eSSatish Balay 625e5c89e4eSSatish Balay Not Collective 626e5c89e4eSSatish Balay 627e5c89e4eSSatish Balay Input Parameters: 628e5c89e4eSSatish Balay + a - pointer to first string 629e5c89e4eSSatish Balay . b - pointer to second string 630e5c89e4eSSatish Balay - n - length to compare up to 631e5c89e4eSSatish Balay 632e5c89e4eSSatish Balay Output Parameter: 633e5c89e4eSSatish Balay . t - if the two strings are equal 634e5c89e4eSSatish Balay 635e5c89e4eSSatish Balay Level: intermediate 636e5c89e4eSSatish Balay 637811af0c4SBarry Smith Fortran Note: 63895452b02SPatrick Sanan Not for use in Fortran 6396f013253SBarry Smith 640db781477SPatrick Sanan .seealso: `PetscStrgrt()`, `PetscStrcmp()`, `PetscStrcasecmp()` 641e5c89e4eSSatish Balay @*/ 642d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrncmp(const char a[], const char b[], size_t n, PetscBool *t) 643d71ae5a4SJacob Faibussowitsch { 644e5c89e4eSSatish Balay PetscFunctionBegin; 6455f80ce2aSJacob Faibussowitsch if (n) { 6465f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 6475f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 2); 6485f80ce2aSJacob Faibussowitsch } 6495f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t, 4); 6505f80ce2aSJacob Faibussowitsch *t = strncmp(a, b, n) ? PETSC_FALSE : PETSC_TRUE; 651e5c89e4eSSatish Balay PetscFunctionReturn(0); 652e5c89e4eSSatish Balay } 653e5c89e4eSSatish Balay 654e5c89e4eSSatish Balay /*@C 655a5b23f4aSJose E. Roman PetscStrchr - Locates first occurrence of a character in a string 656e5c89e4eSSatish Balay 657e5c89e4eSSatish Balay Not Collective 658e5c89e4eSSatish Balay 659e5c89e4eSSatish Balay Input Parameters: 660e5c89e4eSSatish Balay + a - pointer to string 661e5c89e4eSSatish Balay - b - character 662e5c89e4eSSatish Balay 663e5c89e4eSSatish Balay Output Parameter: 664a5b23f4aSJose E. Roman . c - location of occurrence, NULL if not found 665e5c89e4eSSatish Balay 666e5c89e4eSSatish Balay Level: intermediate 667e5c89e4eSSatish Balay 668811af0c4SBarry Smith Fortran Note: 66995452b02SPatrick Sanan Not for use in Fortran 6706f013253SBarry Smith 671811af0c4SBarry Smith .seealso: `PetscStrrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()` 672e5c89e4eSSatish Balay @*/ 673d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrchr(const char a[], char b, char *c[]) 674d71ae5a4SJacob Faibussowitsch { 675e5c89e4eSSatish Balay PetscFunctionBegin; 6765f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 6775f80ce2aSJacob Faibussowitsch PetscValidPointer(c, 3); 678e5c89e4eSSatish Balay *c = (char *)strchr(a, b); 679e5c89e4eSSatish Balay PetscFunctionReturn(0); 680e5c89e4eSSatish Balay } 681e5c89e4eSSatish Balay 682e5c89e4eSSatish Balay /*@C 683a5b23f4aSJose E. Roman PetscStrrchr - Locates one location past the last occurrence of a character in a string, 684e5c89e4eSSatish Balay if the character is not found then returns entire string 685e5c89e4eSSatish Balay 686e5c89e4eSSatish Balay Not Collective 687e5c89e4eSSatish Balay 688e5c89e4eSSatish Balay Input Parameters: 689e5c89e4eSSatish Balay + a - pointer to string 690e5c89e4eSSatish Balay - b - character 691e5c89e4eSSatish Balay 692e5c89e4eSSatish Balay Output Parameter: 693a5b23f4aSJose E. Roman . tmp - location of occurrence, a if not found 694e5c89e4eSSatish Balay 695e5c89e4eSSatish Balay Level: intermediate 696e5c89e4eSSatish Balay 697811af0c4SBarry Smith Fortran Note: 69895452b02SPatrick Sanan Not for use in Fortran 6996f013253SBarry Smith 700811af0c4SBarry Smith .seealso: `PetscStrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()` 701e5c89e4eSSatish Balay @*/ 702d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrrchr(const char a[], char b, char *tmp[]) 703d71ae5a4SJacob Faibussowitsch { 704e5c89e4eSSatish Balay PetscFunctionBegin; 7055f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 7065f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp, 3); 707e5c89e4eSSatish Balay *tmp = (char *)strrchr(a, b); 708a297a907SKarl Rupp if (!*tmp) *tmp = (char *)a; 709a297a907SKarl Rupp else *tmp = *tmp + 1; 710e5c89e4eSSatish Balay PetscFunctionReturn(0); 711e5c89e4eSSatish Balay } 712e5c89e4eSSatish Balay 713e5c89e4eSSatish Balay /*@C 714e5c89e4eSSatish Balay PetscStrtolower - Converts string to lower case 715e5c89e4eSSatish Balay 716e5c89e4eSSatish Balay Not Collective 717e5c89e4eSSatish Balay 718e5c89e4eSSatish Balay Input Parameters: 719e5c89e4eSSatish Balay . a - pointer to string 720e5c89e4eSSatish Balay 721e5c89e4eSSatish Balay Level: intermediate 722e5c89e4eSSatish Balay 723811af0c4SBarry Smith Fortran Note: 72495452b02SPatrick Sanan Not for use in Fortran 7256f013253SBarry Smith 726811af0c4SBarry Smith .seealso: `PetscStrtoupper()` 727e5c89e4eSSatish Balay @*/ 728d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrtolower(char a[]) 729d71ae5a4SJacob Faibussowitsch { 730e5c89e4eSSatish Balay PetscFunctionBegin; 7315f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 732e5c89e4eSSatish Balay while (*a) { 733e5c89e4eSSatish Balay if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 734e5c89e4eSSatish Balay a++; 735e5c89e4eSSatish Balay } 736e5c89e4eSSatish Balay PetscFunctionReturn(0); 737e5c89e4eSSatish Balay } 738e5c89e4eSSatish Balay 7392f234a98SBarry Smith /*@C 7406e3a5469SBarry Smith PetscStrtoupper - Converts string to upper case 7412f234a98SBarry Smith 7422f234a98SBarry Smith Not Collective 7432f234a98SBarry Smith 7442f234a98SBarry Smith Input Parameters: 7452f234a98SBarry Smith . a - pointer to string 7462f234a98SBarry Smith 7472f234a98SBarry Smith Level: intermediate 7482f234a98SBarry Smith 749811af0c4SBarry Smith Fortran Note: 75095452b02SPatrick Sanan Not for use in Fortran 7512f234a98SBarry Smith 752811af0c4SBarry Smith .seealso: `PetscStrtolower()` 7532f234a98SBarry Smith @*/ 754d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrtoupper(char a[]) 755d71ae5a4SJacob Faibussowitsch { 7562f234a98SBarry Smith PetscFunctionBegin; 7575f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 7582f234a98SBarry Smith while (*a) { 7592f234a98SBarry Smith if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a'; 7602f234a98SBarry Smith a++; 7612f234a98SBarry Smith } 7622f234a98SBarry Smith PetscFunctionReturn(0); 7632f234a98SBarry Smith } 7642f234a98SBarry Smith 7657ba3a57cSBarry Smith /*@C 7667ba3a57cSBarry Smith PetscStrendswith - Determines if a string ends with a certain string 7671d1a0024SBarry Smith 7687ba3a57cSBarry Smith Not Collective 7697ba3a57cSBarry Smith 7707ba3a57cSBarry Smith Input Parameters: 7717ba3a57cSBarry Smith + a - pointer to string 7727ba3a57cSBarry Smith - b - string to endwith 7737ba3a57cSBarry Smith 7747ba3a57cSBarry Smith Output Parameter: 775811af0c4SBarry Smith . flg - `PETSC_TRUE` or `PETSC_FALSE` 7767ba3a57cSBarry Smith 777811af0c4SBarry Smith Fortran Note: 77895452b02SPatrick Sanan Not for use in Fortran 7797ba3a57cSBarry Smith 7807ba3a57cSBarry Smith Level: intermediate 7817ba3a57cSBarry Smith 782811af0c4SBarry Smith .seealso: `PetscStrendswithwhich()`, `PetscStrbeginswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 783811af0c4SBarry Smith `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 7847ba3a57cSBarry Smith @*/ 785d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrendswith(const char a[], const char b[], PetscBool *flg) 786d71ae5a4SJacob Faibussowitsch { 7877ba3a57cSBarry Smith char *test; 7887ba3a57cSBarry Smith 7897ba3a57cSBarry Smith PetscFunctionBegin; 7905f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg, 3); 7917ba3a57cSBarry Smith *flg = PETSC_FALSE; 7929566063dSJacob Faibussowitsch PetscCall(PetscStrrstr(a, b, &test)); 7937ba3a57cSBarry Smith if (test) { 7945f80ce2aSJacob Faibussowitsch size_t na, nb; 7955f80ce2aSJacob Faibussowitsch 7969566063dSJacob Faibussowitsch PetscCall(PetscStrlen(a, &na)); 7979566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b, &nb)); 7987ba3a57cSBarry Smith if (a + na - nb == test) *flg = PETSC_TRUE; 7997ba3a57cSBarry Smith } 8007ba3a57cSBarry Smith PetscFunctionReturn(0); 8017ba3a57cSBarry Smith } 8027ba3a57cSBarry Smith 8032c9581d2SBarry Smith /*@C 8042c9581d2SBarry Smith PetscStrbeginswith - Determines if a string begins with a certain string 8052c9581d2SBarry Smith 8062c9581d2SBarry Smith Not Collective 8072c9581d2SBarry Smith 8082c9581d2SBarry Smith Input Parameters: 8092c9581d2SBarry Smith + a - pointer to string 8102c9581d2SBarry Smith - b - string to begin with 8112c9581d2SBarry Smith 8122c9581d2SBarry Smith Output Parameter: 8132c9581d2SBarry Smith . flg - PETSC_TRUE or PETSC_FALSE 8142c9581d2SBarry Smith 815811af0c4SBarry Smith Fortran Note: 81695452b02SPatrick Sanan Not for use in Fortran 8172c9581d2SBarry Smith 8182c9581d2SBarry Smith Level: intermediate 8192c9581d2SBarry Smith 820db781477SPatrick Sanan .seealso: `PetscStrendswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 821db781477SPatrick Sanan `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 8222c9581d2SBarry Smith @*/ 823d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg) 824d71ae5a4SJacob Faibussowitsch { 8252c9581d2SBarry Smith char *test; 8262c9581d2SBarry Smith 8272c9581d2SBarry Smith PetscFunctionBegin; 8285f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 8295f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 2); 8305f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg, 3); 8312c9581d2SBarry Smith *flg = PETSC_FALSE; 8329566063dSJacob Faibussowitsch PetscCall(PetscStrrstr(a, b, &test)); 833a297a907SKarl Rupp if (test && (test == a)) *flg = PETSC_TRUE; 8342c9581d2SBarry Smith PetscFunctionReturn(0); 8352c9581d2SBarry Smith } 8362c9581d2SBarry Smith 8377ba3a57cSBarry Smith /*@C 8387ba3a57cSBarry Smith PetscStrendswithwhich - Determines if a string ends with one of several possible strings 8397ba3a57cSBarry Smith 8407ba3a57cSBarry Smith Not Collective 8417ba3a57cSBarry Smith 8427ba3a57cSBarry Smith Input Parameters: 8437ba3a57cSBarry Smith + a - pointer to string 844fa4b66f2SVaclav Hapla - bs - strings to end with (last entry must be NULL) 8457ba3a57cSBarry Smith 8467ba3a57cSBarry Smith Output Parameter: 847fa4b66f2SVaclav Hapla . cnt - the index of the string it ends with or the index of NULL 8487ba3a57cSBarry Smith 849811af0c4SBarry Smith Fortran Note: 85095452b02SPatrick Sanan Not for use in Fortran 8517ba3a57cSBarry Smith 8527ba3a57cSBarry Smith Level: intermediate 8537ba3a57cSBarry Smith 854811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 855811af0c4SBarry Smith `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 8567ba3a57cSBarry Smith @*/ 857d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrendswithwhich(const char a[], const char *const *bs, PetscInt *cnt) 858d71ae5a4SJacob Faibussowitsch { 8597ba3a57cSBarry Smith PetscFunctionBegin; 8605f80ce2aSJacob Faibussowitsch PetscValidPointer(bs, 2); 8615f80ce2aSJacob Faibussowitsch PetscValidIntPointer(cnt, 3); 8627ba3a57cSBarry Smith *cnt = 0; 8637ba3a57cSBarry Smith while (bs[*cnt]) { 8645f80ce2aSJacob Faibussowitsch PetscBool flg; 8655f80ce2aSJacob Faibussowitsch 8669566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(a, bs[*cnt], &flg)); 8677ba3a57cSBarry Smith if (flg) PetscFunctionReturn(0); 8685f80ce2aSJacob Faibussowitsch ++(*cnt); 8697ba3a57cSBarry Smith } 8707ba3a57cSBarry Smith PetscFunctionReturn(0); 8717ba3a57cSBarry Smith } 8727ba3a57cSBarry Smith 8737ba3a57cSBarry Smith /*@C 874a5b23f4aSJose E. Roman PetscStrrstr - Locates last occurrence of string in another string 8757ba3a57cSBarry Smith 8767ba3a57cSBarry Smith Not Collective 8777ba3a57cSBarry Smith 8787ba3a57cSBarry Smith Input Parameters: 8797ba3a57cSBarry Smith + a - pointer to string 8807ba3a57cSBarry Smith - b - string to find 8817ba3a57cSBarry Smith 8827ba3a57cSBarry Smith Output Parameter: 883a5b23f4aSJose E. Roman . tmp - location of occurrence 8847ba3a57cSBarry Smith 885811af0c4SBarry Smith Fortran Note: 88695452b02SPatrick Sanan Not for use in Fortran 8877ba3a57cSBarry Smith 8887ba3a57cSBarry Smith Level: intermediate 8897ba3a57cSBarry Smith 890811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 891811af0c4SBarry Smith `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 8927ba3a57cSBarry Smith @*/ 893d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrrstr(const char a[], const char b[], char *tmp[]) 894d71ae5a4SJacob Faibussowitsch { 8955f80ce2aSJacob Faibussowitsch const char *ltmp = NULL; 8967ba3a57cSBarry Smith 8977ba3a57cSBarry Smith PetscFunctionBegin; 8985f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 8995f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 2); 9005f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp, 3); 9015f80ce2aSJacob Faibussowitsch while (a) { 9025f80ce2aSJacob Faibussowitsch a = (char *)strstr(a, b); 9035f80ce2aSJacob Faibussowitsch if (a) ltmp = a++; 9047ba3a57cSBarry Smith } 9057ba3a57cSBarry Smith *tmp = (char *)ltmp; 9067ba3a57cSBarry Smith PetscFunctionReturn(0); 9077ba3a57cSBarry Smith } 9087ba3a57cSBarry Smith 9097ba3a57cSBarry Smith /*@C 910a5b23f4aSJose E. Roman PetscStrstr - Locates first occurrence of string in another string 9117ba3a57cSBarry Smith 9127ba3a57cSBarry Smith Not Collective 9137ba3a57cSBarry Smith 9147ba3a57cSBarry Smith Input Parameters: 915160f4796SJed Brown + haystack - string to search 916160f4796SJed Brown - needle - string to find 9177ba3a57cSBarry Smith 9187ba3a57cSBarry Smith Output Parameter: 919a5b23f4aSJose E. Roman . tmp - location of occurrence, is a NULL if the string is not found 9207ba3a57cSBarry Smith 921811af0c4SBarry Smith Fortran Note: 92295452b02SPatrick Sanan Not for use in Fortran 9237ba3a57cSBarry Smith 9247ba3a57cSBarry Smith Level: intermediate 9257ba3a57cSBarry Smith 926811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 927811af0c4SBarry Smith `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 9287ba3a57cSBarry Smith @*/ 929d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrstr(const char haystack[], const char needle[], char *tmp[]) 930d71ae5a4SJacob Faibussowitsch { 9317ba3a57cSBarry Smith PetscFunctionBegin; 9325f80ce2aSJacob Faibussowitsch PetscValidCharPointer(haystack, 1); 9335f80ce2aSJacob Faibussowitsch PetscValidCharPointer(needle, 2); 9345f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp, 3); 935160f4796SJed Brown *tmp = (char *)strstr(haystack, needle); 9367ba3a57cSBarry Smith PetscFunctionReturn(0); 9377ba3a57cSBarry Smith } 9387ba3a57cSBarry Smith 9399371c9d4SSatish Balay struct _p_PetscToken { 9409371c9d4SSatish Balay char token; 9419371c9d4SSatish Balay char *array; 9429371c9d4SSatish Balay char *current; 9439371c9d4SSatish Balay }; 9441d1a0024SBarry Smith 945e5c89e4eSSatish Balay /*@C 946e5c89e4eSSatish Balay PetscTokenFind - Locates next "token" in a string 947e5c89e4eSSatish Balay 948e5c89e4eSSatish Balay Not Collective 949e5c89e4eSSatish Balay 950e5c89e4eSSatish Balay Input Parameters: 951e5c89e4eSSatish Balay . a - pointer to token 952e5c89e4eSSatish Balay 953e5c89e4eSSatish Balay Output Parameter: 954a5b23f4aSJose E. Roman . result - location of occurrence, NULL if not found 955e5c89e4eSSatish Balay 956e5c89e4eSSatish Balay Notes: 957e5c89e4eSSatish Balay This version is different from the system version in that 958e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 959e5c89e4eSSatish Balay 9604704e885SBarry Smith This version also treats all characters etc. inside a double quote " 9614704e885SBarry Smith as a single token. 9624704e885SBarry Smith 9633a9c465aSBarry Smith For example if the separator character is + and the string is xxxx+y then the first fine will return a pointer to a null terminated xxxx and the 9643a9c465aSBarry Smith second will return a null terminated y 9653a9c465aSBarry Smith 9663a9c465aSBarry Smith If the separator character is + and the string is xxxx then the first and only token found will be a pointer to a null terminated xxxx 9673a9c465aSBarry Smith 968811af0c4SBarry Smith Fortran Note: 9696f013253SBarry Smith Not for use in Fortran 9706f013253SBarry Smith 971e5c89e4eSSatish Balay Level: intermediate 972e5c89e4eSSatish Balay 973db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenDestroy()` 974e5c89e4eSSatish Balay @*/ 975d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenFind(PetscToken a, char *result[]) 976d71ae5a4SJacob Faibussowitsch { 9775f80ce2aSJacob Faibussowitsch char *ptr, token; 978e5c89e4eSSatish Balay 979e5c89e4eSSatish Balay PetscFunctionBegin; 9805f80ce2aSJacob Faibussowitsch PetscValidPointer(a, 1); 9815f80ce2aSJacob Faibussowitsch PetscValidPointer(result, 2); 9825f80ce2aSJacob Faibussowitsch *result = ptr = a->current; 9839371c9d4SSatish Balay if (ptr && !*ptr) { 9849371c9d4SSatish Balay *result = NULL; 9859371c9d4SSatish Balay PetscFunctionReturn(0); 9869371c9d4SSatish Balay } 9874704e885SBarry Smith token = a->token; 9889371c9d4SSatish Balay if (ptr && (*ptr == '"')) { 9899371c9d4SSatish Balay token = '"'; 9909371c9d4SSatish Balay (*result)++; 9919371c9d4SSatish Balay ptr++; 9929371c9d4SSatish Balay } 993e5c89e4eSSatish Balay while (ptr) { 9944704e885SBarry Smith if (*ptr == token) { 995e5c89e4eSSatish Balay *ptr++ = 0; 996e5c89e4eSSatish Balay while (*ptr == a->token) ptr++; 997e5c89e4eSSatish Balay a->current = ptr; 998e5c89e4eSSatish Balay break; 999e5c89e4eSSatish Balay } 1000e5c89e4eSSatish Balay if (!*ptr) { 100102c9f0b5SLisandro Dalcin a->current = NULL; 1002e5c89e4eSSatish Balay break; 1003e5c89e4eSSatish Balay } 1004e5c89e4eSSatish Balay ptr++; 1005e5c89e4eSSatish Balay } 1006e5c89e4eSSatish Balay PetscFunctionReturn(0); 1007e5c89e4eSSatish Balay } 1008e5c89e4eSSatish Balay 1009e5c89e4eSSatish Balay /*@C 1010811af0c4SBarry Smith PetscTokenCreate - Creates a `PetscToken` used to find tokens in a string 1011e5c89e4eSSatish Balay 1012e5c89e4eSSatish Balay Not Collective 1013e5c89e4eSSatish Balay 1014e5c89e4eSSatish Balay Input Parameters: 1015e5c89e4eSSatish Balay + string - the string to look in 10163a9c465aSBarry Smith - b - the separator character 1017e5c89e4eSSatish Balay 1018e5c89e4eSSatish Balay Output Parameter: 10193a9c465aSBarry Smith . t- the token object 1020e5c89e4eSSatish Balay 1021811af0c4SBarry Smith Note: 1022e5c89e4eSSatish Balay This version is different from the system version in that 1023e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 1024e5c89e4eSSatish Balay 1025811af0c4SBarry Smith Fortran Note: 10266f013253SBarry Smith Not for use in Fortran 10276f013253SBarry Smith 1028e5c89e4eSSatish Balay Level: intermediate 1029e5c89e4eSSatish Balay 1030db781477SPatrick Sanan .seealso: `PetscTokenFind()`, `PetscTokenDestroy()` 1031e5c89e4eSSatish Balay @*/ 1032*98e514b7SJacob Faibussowitsch PetscErrorCode PetscTokenCreate(const char a[], char b, PetscToken *t) 1033d71ae5a4SJacob Faibussowitsch { 1034e5c89e4eSSatish Balay PetscFunctionBegin; 10355f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 10365f80ce2aSJacob Faibussowitsch PetscValidPointer(t, 3); 10379566063dSJacob Faibussowitsch PetscCall(PetscNew(t)); 10389566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &(*t)->array)); 1039a297a907SKarl Rupp 1040e5c89e4eSSatish Balay (*t)->current = (*t)->array; 1041e5c89e4eSSatish Balay (*t)->token = b; 1042e5c89e4eSSatish Balay PetscFunctionReturn(0); 1043e5c89e4eSSatish Balay } 1044e5c89e4eSSatish Balay 1045e5c89e4eSSatish Balay /*@C 1046811af0c4SBarry Smith PetscTokenDestroy - Destroys a `PetscToken` 1047e5c89e4eSSatish Balay 1048e5c89e4eSSatish Balay Not Collective 1049e5c89e4eSSatish Balay 1050e5c89e4eSSatish Balay Input Parameters: 1051e5c89e4eSSatish Balay . a - pointer to token 1052e5c89e4eSSatish Balay 1053e5c89e4eSSatish Balay Level: intermediate 1054e5c89e4eSSatish Balay 1055811af0c4SBarry Smith Fortran Note: 105695452b02SPatrick Sanan Not for use in Fortran 10576f013253SBarry Smith 1058db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()` 1059e5c89e4eSSatish Balay @*/ 1060d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenDestroy(PetscToken *a) 1061d71ae5a4SJacob Faibussowitsch { 1062e5c89e4eSSatish Balay PetscFunctionBegin; 10638c74ee41SBarry Smith if (!*a) PetscFunctionReturn(0); 10649566063dSJacob Faibussowitsch PetscCall(PetscFree((*a)->array)); 10659566063dSJacob Faibussowitsch PetscCall(PetscFree(*a)); 1066e5c89e4eSSatish Balay PetscFunctionReturn(0); 1067e5c89e4eSSatish Balay } 1068e5c89e4eSSatish Balay 10698e81d068SLisandro Dalcin /*@C 1070811af0c4SBarry Smith PetscStrInList - search for string in character-delimited list 10718e81d068SLisandro Dalcin 10728e81d068SLisandro Dalcin Not Collective 10738e81d068SLisandro Dalcin 10748e81d068SLisandro Dalcin Input Parameters: 10758e81d068SLisandro Dalcin + str - the string to look for 10768e81d068SLisandro Dalcin . list - the list to search in 10778e81d068SLisandro Dalcin - sep - the separator character 10788e81d068SLisandro Dalcin 10798e81d068SLisandro Dalcin Output Parameter: 10808e81d068SLisandro Dalcin . found - whether str is in list 10818e81d068SLisandro Dalcin 10828e81d068SLisandro Dalcin Level: intermediate 10838e81d068SLisandro Dalcin 1084811af0c4SBarry Smith Fortran Note: 108595452b02SPatrick Sanan Not for use in Fortran 10868e81d068SLisandro Dalcin 1087db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscStrcmp()` 10888e81d068SLisandro Dalcin @*/ 1089d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found) 1090d71ae5a4SJacob Faibussowitsch { 10918e81d068SLisandro Dalcin PetscToken token; 10928e81d068SLisandro Dalcin char *item; 10938e81d068SLisandro Dalcin 10948e81d068SLisandro Dalcin PetscFunctionBegin; 10955f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 4); 10968e81d068SLisandro Dalcin *found = PETSC_FALSE; 10979566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(list, sep, &token)); 10989566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 10998e81d068SLisandro Dalcin while (item) { 11009566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(str, item, found)); 11018e81d068SLisandro Dalcin if (*found) break; 11029566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 11038e81d068SLisandro Dalcin } 11049566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 11058e81d068SLisandro Dalcin PetscFunctionReturn(0); 11068e81d068SLisandro Dalcin } 1107e5c89e4eSSatish Balay 1108e5c89e4eSSatish Balay /*@C 1109e5c89e4eSSatish Balay PetscGetPetscDir - Gets the directory PETSc is installed in 1110e5c89e4eSSatish Balay 1111e5c89e4eSSatish Balay Not Collective 1112e5c89e4eSSatish Balay 1113e5c89e4eSSatish Balay Output Parameter: 1114e5c89e4eSSatish Balay . dir - the directory 1115e5c89e4eSSatish Balay 1116e5c89e4eSSatish Balay Level: developer 1117e5c89e4eSSatish Balay 1118811af0c4SBarry Smith Fortran Note: 111995452b02SPatrick Sanan Not for use in Fortran 11206f013253SBarry Smith 1121e5c89e4eSSatish Balay @*/ 1122d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetPetscDir(const char *dir[]) 1123d71ae5a4SJacob Faibussowitsch { 1124e5c89e4eSSatish Balay PetscFunctionBegin; 11255f80ce2aSJacob Faibussowitsch PetscValidPointer(dir, 1); 1126e5c89e4eSSatish Balay *dir = PETSC_DIR; 1127e5c89e4eSSatish Balay PetscFunctionReturn(0); 1128e5c89e4eSSatish Balay } 1129e5c89e4eSSatish Balay 1130e5c89e4eSSatish Balay /*@C 1131e5c89e4eSSatish Balay PetscStrreplace - Replaces substrings in string with other substrings 1132e5c89e4eSSatish Balay 1133e5c89e4eSSatish Balay Not Collective 1134e5c89e4eSSatish Balay 1135e5c89e4eSSatish Balay Input Parameters: 1136811af0c4SBarry Smith + comm - `MPI_Comm` of processors that are processing the string 113771573d7dSBarry Smith . aa - the string to look in 1138d8ccf1fbSBarry Smith . b - the resulting copy of a with replaced strings (b can be the same as a) 1139e5c89e4eSSatish Balay - len - the length of b 1140e5c89e4eSSatish Balay 1141e5c89e4eSSatish Balay Notes: 1142e5c89e4eSSatish Balay Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 1143d5649816SBarry Smith ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 1144e5c89e4eSSatish Balay as well as any environmental variables. 1145e5c89e4eSSatish Balay 1146811af0c4SBarry Smith `PETSC_LIB_DIR` uses the environmental variable if it exists. `PETSC_ARCH` and `PETSC_DIR` use what 1147acc6cc86SBarry Smith PETSc was built with and do not use environmental variables. 1148acc6cc86SBarry Smith 1149811af0c4SBarry Smith Fortran Note: 11506f013253SBarry Smith Not for use in Fortran 11516f013253SBarry Smith 1152811af0c4SBarry Smith Level: developer 1153e5c89e4eSSatish Balay 1154e5c89e4eSSatish Balay @*/ 1155d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len) 1156d71ae5a4SJacob Faibussowitsch { 1157e5c89e4eSSatish Balay int i = 0; 1158e5c89e4eSSatish Balay size_t l, l1, l2, l3; 115971573d7dSBarry Smith char *work, *par, *epar, env[1024], *tfree, *a = (char *)aa; 116002c9f0b5SLisandro Dalcin const char *s[] = {"${PETSC_ARCH}", "${PETSC_DIR}", "${PETSC_LIB_DIR}", "${DISPLAY}", "${HOMEDIRECTORY}", "${WORKINGDIRECTORY}", "${USERNAME}", "${HOSTNAME}", NULL}; 116102c9f0b5SLisandro Dalcin char *r[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 1162ace3abfcSBarry Smith PetscBool flag; 1163589a23caSBarry Smith static size_t DISPLAY_LENGTH = 265, USER_LENGTH = 256, HOST_LENGTH = 256; 1164e5c89e4eSSatish Balay 1165e5c89e4eSSatish Balay PetscFunctionBegin; 11665f80ce2aSJacob Faibussowitsch PetscValidCharPointer(aa, 2); 11675f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 3); 11689566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscStrallocpy(aa, (char **)&a)); 11699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len, &work)); 1170e5c89e4eSSatish Balay 1171e5c89e4eSSatish Balay /* get values for replaced variables */ 11729566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_ARCH, &r[0])); 11739566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_DIR, &r[1])); 11749566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_LIB_DIR, &r[2])); 11759566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(DISPLAY_LENGTH, &r[3])); 11769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[4])); 11779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[5])); 11789566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(USER_LENGTH, &r[6])); 11799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(HOST_LENGTH, &r[7])); 11809566063dSJacob Faibussowitsch PetscCall(PetscGetDisplay(r[3], DISPLAY_LENGTH)); 11819566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(r[4], PETSC_MAX_PATH_LEN)); 11829566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(r[5], PETSC_MAX_PATH_LEN)); 11839566063dSJacob Faibussowitsch PetscCall(PetscGetUserName(r[6], USER_LENGTH)); 11849566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(r[7], HOST_LENGTH)); 1185487e5849SBarry Smith 1186487e5849SBarry Smith /* replace that are in environment */ 11879566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_LIB_DIR", env, sizeof(env), &flag)); 1188487e5849SBarry Smith if (flag) { 11899566063dSJacob Faibussowitsch PetscCall(PetscFree(r[2])); 11909566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(env, &r[2])); 1191487e5849SBarry Smith } 1192e5c89e4eSSatish Balay 1193e5c89e4eSSatish Balay /* replace the requested strings */ 11949566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, a, len)); 1195e5c89e4eSSatish Balay while (s[i]) { 11969566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s[i], &l)); 11979566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 1198e5c89e4eSSatish Balay while (par) { 1199e5c89e4eSSatish Balay *par = 0; 1200e5c89e4eSSatish Balay par += l; 1201e5c89e4eSSatish Balay 12029566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b, &l1)); 12039566063dSJacob Faibussowitsch PetscCall(PetscStrlen(r[i], &l2)); 12049566063dSJacob Faibussowitsch PetscCall(PetscStrlen(par, &l3)); 1205cc73adaaSBarry Smith PetscCheck(l1 + l2 + l3 < len, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "b len is not long enough to hold new values"); 12069566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 12079566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, r[i], len)); 12089566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, par, len)); 12099566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 12109566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 1211e5c89e4eSSatish Balay } 1212e5c89e4eSSatish Balay i++; 1213e5c89e4eSSatish Balay } 1214487e5849SBarry Smith i = 0; 1215487e5849SBarry Smith while (r[i]) { 1216e5c89e4eSSatish Balay tfree = (char *)r[i]; 12179566063dSJacob Faibussowitsch PetscCall(PetscFree(tfree)); 1218487e5849SBarry Smith i++; 1219e5c89e4eSSatish Balay } 1220e5c89e4eSSatish Balay 1221e5c89e4eSSatish Balay /* look for any other ${xxx} strings to replace from environmental variables */ 12229566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 1223e5c89e4eSSatish Balay while (par) { 1224e5c89e4eSSatish Balay *par = 0; 1225e5c89e4eSSatish Balay par += 2; 12269566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 12279566063dSJacob Faibussowitsch PetscCall(PetscStrstr(par, "}", &epar)); 1228e5c89e4eSSatish Balay *epar = 0; 1229e5c89e4eSSatish Balay epar += 1; 12309566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, par, env, sizeof(env), &flag)); 123128b400f6SJacob Faibussowitsch PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Substitution string ${%s} not found as environmental variable", par); 12329566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, env, len)); 12339566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, epar, len)); 12349566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 12359566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 1236e5c89e4eSSatish Balay } 12379566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 12389566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscFree(a)); 1239e5c89e4eSSatish Balay PetscFunctionReturn(0); 1240e5c89e4eSSatish Balay } 1241e5c89e4eSSatish Balay 1242a53986e1SJed Brown /*@C 1243a53986e1SJed Brown PetscEListFind - searches list of strings for given string, using case insensitive matching 1244e5c89e4eSSatish Balay 1245a53986e1SJed Brown Not Collective 1246a53986e1SJed Brown 1247a53986e1SJed Brown Input Parameters: 1248a53986e1SJed Brown + n - number of strings in 1249a53986e1SJed Brown . list - list of strings to search 1250a53986e1SJed Brown - str - string to look for, empty string "" accepts default (first entry in list) 1251a53986e1SJed Brown 1252a53986e1SJed Brown Output Parameters: 1253a53986e1SJed Brown + value - index of matching string (if found) 1254a53986e1SJed Brown - found - boolean indicating whether string was found (can be NULL) 1255a53986e1SJed Brown 1256811af0c4SBarry Smith Fortran Note: 1257a53986e1SJed Brown Not for use in Fortran 1258a53986e1SJed Brown 1259a53986e1SJed Brown Level: advanced 1260811af0c4SBarry Smith 1261811af0c4SBarry Smith .seealso: `PetscEnumFind()` 1262a53986e1SJed Brown @*/ 1263d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found) 1264d71ae5a4SJacob Faibussowitsch { 1265a53986e1SJed Brown PetscFunctionBegin; 12665f80ce2aSJacob Faibussowitsch if (found) { 12675f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 5); 12685f80ce2aSJacob Faibussowitsch *found = PETSC_FALSE; 12695f80ce2aSJacob Faibussowitsch } 12705f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 12715f80ce2aSJacob Faibussowitsch PetscBool matched; 12725f80ce2aSJacob Faibussowitsch 12739566063dSJacob Faibussowitsch PetscCall(PetscStrcasecmp(str, list[i], &matched)); 1274a53986e1SJed Brown if (matched || !str[0]) { 1275a53986e1SJed Brown if (found) *found = PETSC_TRUE; 1276a53986e1SJed Brown *value = i; 1277a53986e1SJed Brown break; 1278a53986e1SJed Brown } 1279a53986e1SJed Brown } 1280a53986e1SJed Brown PetscFunctionReturn(0); 1281a53986e1SJed Brown } 1282a53986e1SJed Brown 1283a53986e1SJed Brown /*@C 12848e81d068SLisandro Dalcin PetscEnumFind - searches enum list of strings for given string, using case insensitive matching 1285a53986e1SJed Brown 1286a53986e1SJed Brown Not Collective 1287a53986e1SJed Brown 1288a53986e1SJed Brown Input Parameters: 1289a53986e1SJed Brown + enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL 1290a53986e1SJed Brown - str - string to look for 1291a53986e1SJed Brown 1292a53986e1SJed Brown Output Parameters: 1293a53986e1SJed Brown + value - index of matching string (if found) 1294a53986e1SJed Brown - found - boolean indicating whether string was found (can be NULL) 1295a53986e1SJed Brown 1296811af0c4SBarry Smith Fortran Note: 1297a53986e1SJed Brown Not for use in Fortran 1298a53986e1SJed Brown 1299a53986e1SJed Brown Level: advanced 1300811af0c4SBarry Smith 1301811af0c4SBarry Smith .seealso: `PetscEListFind()` 1302a53986e1SJed Brown @*/ 1303d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found) 1304d71ae5a4SJacob Faibussowitsch { 1305d05ba7d2SLisandro Dalcin PetscInt n = 0, evalue; 1306a53986e1SJed Brown PetscBool efound; 1307a53986e1SJed Brown 1308a53986e1SJed Brown PetscFunctionBegin; 13095f80ce2aSJacob Faibussowitsch PetscValidPointer(enumlist, 1); 13105f80ce2aSJacob Faibussowitsch while (enumlist[n++]) PetscCheck(n <= 50, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument appears to be wrong or have more than 50 entries"); 13115f80ce2aSJacob Faibussowitsch PetscCheck(n >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix"); 1312a53986e1SJed Brown n -= 3; /* drop enum name, prefix, and null termination */ 13139566063dSJacob Faibussowitsch PetscCall(PetscEListFind(n, enumlist, str, &evalue, &efound)); 13145f80ce2aSJacob Faibussowitsch if (efound) { 13155f80ce2aSJacob Faibussowitsch PetscValidPointer(value, 3); 13165f80ce2aSJacob Faibussowitsch *value = (PetscEnum)evalue; 13175f80ce2aSJacob Faibussowitsch } 13185f80ce2aSJacob Faibussowitsch if (found) { 13195f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 4); 13205f80ce2aSJacob Faibussowitsch *found = efound; 13215f80ce2aSJacob Faibussowitsch } 1322a53986e1SJed Brown PetscFunctionReturn(0); 1323a53986e1SJed Brown } 1324660278c0SBarry Smith 1325660278c0SBarry Smith /*@C 1326660278c0SBarry Smith PetscCIFilename - returns the basename of a file name when the PETSc CI portable error output mode is enabled. 1327660278c0SBarry Smith 1328660278c0SBarry Smith Not collective 1329660278c0SBarry Smith 1330660278c0SBarry Smith Input Parameter: 1331660278c0SBarry Smith . file - the file name 1332660278c0SBarry Smith 1333660278c0SBarry Smith Note: 1334660278c0SBarry Smith PETSc CI mode is a mode of running PETSc where output (both error and non-error) is made portable across all systems 1335660278c0SBarry Smith so that comparisons of output between runs are easy to make. 1336660278c0SBarry Smith 1337660278c0SBarry Smith This mode is used for all tests in the test harness, it applies to both debug and optimized builds. 1338660278c0SBarry Smith 1339660278c0SBarry Smith Use the option -petsc_ci to turn on PETSc CI mode. It changes certain output in non-error situations to be portable for 1340660278c0SBarry Smith all systems, mainly the output of options. It is passed to all PETSc programs automatically by the test harness. 1341660278c0SBarry Smith 1342660278c0SBarry Smith Always uses the Unix / as the file separate even on Microsoft Windows systems 1343660278c0SBarry Smith 1344660278c0SBarry Smith The option -petsc_ci_portable_error_output attempts to output the same error messages on all systems for the test harness. 1345660278c0SBarry Smith In particular the output of filenames and line numbers in PETSc stacks. This is to allow (limited) checking of PETSc 1346660278c0SBarry Smith error handling by the test harness. This options also causes PETSc to attempt to return an error code of 0 so that the test 1347660278c0SBarry Smith harness can process the output for differences in the usual manner as for successful runs. It should be provided to the test 1348660278c0SBarry Smith harness in the args: argument for specific examples. It will not neccessarily produce portable output if different errors 1349660278c0SBarry Smith (or no errors) occur on a subset of the MPI ranks. 1350660278c0SBarry Smith 1351660278c0SBarry Smith Level: developer 1352660278c0SBarry Smith 1353660278c0SBarry Smith .seealso: `PetscCILinenumber()` 1354660278c0SBarry Smith @*/ 1355d71ae5a4SJacob Faibussowitsch const char *PetscCIFilename(const char *file) 1356d71ae5a4SJacob Faibussowitsch { 1357660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return file; 1358660278c0SBarry Smith return PetscBasename(file); 1359660278c0SBarry Smith } 1360660278c0SBarry Smith 1361660278c0SBarry Smith /*@C 1362811af0c4SBarry Smith PetscCILinenumber - returns a line number except if `PetscCIEnablePortableErrorOutput` is set when it returns 0 1363660278c0SBarry Smith 1364660278c0SBarry Smith Not collective 1365660278c0SBarry Smith 1366660278c0SBarry Smith Input Parameter: 1367660278c0SBarry Smith . linenumber - the initial line number 1368660278c0SBarry Smith 1369660278c0SBarry Smith Note: 1370660278c0SBarry Smith See `PetscCIFilename()` for details on usage 1371660278c0SBarry Smith 1372660278c0SBarry Smith Level: developer 1373660278c0SBarry Smith 1374660278c0SBarry Smith .seealso: `PetscCIFilename()` 1375660278c0SBarry Smith @*/ 1376d71ae5a4SJacob Faibussowitsch int PetscCILinenumber(int linenumber) 1377d71ae5a4SJacob Faibussowitsch { 1378660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return linenumber; 1379660278c0SBarry Smith return 0; 1380660278c0SBarry Smith } 1381