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 27*811af0c4SBarry Smith Note: 2895452b02SPatrick Sanan this may be called before PetscInitialize() or after PetscFinalize() 293c311c98SBarry Smith 30*811af0c4SBarry Smith Fortran Note: 316f013253SBarry Smith Not for use in Fortran 326f013253SBarry Smith 3395452b02SPatrick Sanan Developer Notes: 34*811af0c4SBarry Smith Uses raw `malloc()` and does not call error handlers since this may be used before PETSc is initialized. 35*811af0c4SBarry Smith 36*811af0c4SBarry Smith Used to generate argc, args arguments passed to `MPI_Init()` 37301d30feSBarry Smith 38db781477SPatrick Sanan .seealso: `PetscStrToArrayDestroy()`, `PetscToken`, `PetscTokenCreate()` 393c311c98SBarry Smith @*/ 409371c9d4SSatish Balay PetscErrorCode PetscStrToArray(const char s[], char sp, int *argc, char ***args) { 41c3bcdc7eSBarry Smith int i, j, n, *lens, cnt = 0; 42ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 433c311c98SBarry Smith 4440a7e1efSBarry Smith if (!s) n = 0; 4540a7e1efSBarry Smith else n = strlen(s); 463c311c98SBarry Smith *argc = 0; 4761528463SBarry Smith *args = NULL; 48acf7dc08SSatish Balay for (; n > 0; n--) { /* remove separator chars at the end - and will empty the string if all chars are separator chars */ 49acf7dc08SSatish Balay if (s[n - 1] != sp) break; 50acf7dc08SSatish Balay } 515f80ce2aSJacob Faibussowitsch if (!n) return 0; 523c311c98SBarry Smith for (i = 0; i < n; i++) { 53d67fe73bSBarry Smith if (s[i] != sp) break; 543c311c98SBarry Smith } 553c311c98SBarry Smith for (; i < n + 1; i++) { 569371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 579371c9d4SSatish Balay flg = PETSC_TRUE; 589371c9d4SSatish Balay (*argc)++; 599371c9d4SSatish Balay } else if (s[i] != sp) { 609371c9d4SSatish Balay flg = PETSC_FALSE; 613c311c98SBarry Smith } 629371c9d4SSatish Balay } 639371c9d4SSatish Balay (*args) = (char **)malloc(((*argc) + 1) * sizeof(char *)); 649371c9d4SSatish Balay if (!*args) return PETSC_ERR_MEM; 659371c9d4SSatish Balay lens = (int *)malloc((*argc) * sizeof(int)); 669371c9d4SSatish Balay if (!lens) return PETSC_ERR_MEM; 673c311c98SBarry Smith for (i = 0; i < *argc; i++) lens[i] = 0; 683c311c98SBarry Smith 693c311c98SBarry Smith *argc = 0; 703c311c98SBarry Smith for (i = 0; i < n; i++) { 71d67fe73bSBarry Smith if (s[i] != sp) break; 723c311c98SBarry Smith } 737dd9f305SSatish Balay for (; i < n + 1; i++) { 749371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 759371c9d4SSatish Balay flg = PETSC_TRUE; 769371c9d4SSatish Balay (*argc)++; 779371c9d4SSatish Balay } else if (s[i] != sp) { 789371c9d4SSatish Balay lens[*argc]++; 799371c9d4SSatish Balay flg = PETSC_FALSE; 809371c9d4SSatish Balay } 813c311c98SBarry Smith } 823c311c98SBarry Smith 833c311c98SBarry Smith for (i = 0; i < *argc; i++) { 84c3bcdc7eSBarry Smith (*args)[i] = (char *)malloc((lens[i] + 1) * sizeof(char)); 85c3bcdc7eSBarry Smith if (!(*args)[i]) { 86c3bcdc7eSBarry Smith free(lens); 87c3bcdc7eSBarry Smith for (j = 0; j < i; j++) free((*args)[j]); 88c3bcdc7eSBarry Smith free(*args); 89c3bcdc7eSBarry Smith return PETSC_ERR_MEM; 90c3bcdc7eSBarry Smith } 913c311c98SBarry Smith } 92a2ea699eSBarry Smith free(lens); 9302c9f0b5SLisandro Dalcin (*args)[*argc] = NULL; 943c311c98SBarry Smith 953c311c98SBarry Smith *argc = 0; 963c311c98SBarry Smith for (i = 0; i < n; i++) { 97d67fe73bSBarry Smith if (s[i] != sp) break; 983c311c98SBarry Smith } 993c311c98SBarry Smith for (; i < n + 1; i++) { 1009371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 1019371c9d4SSatish Balay flg = PETSC_TRUE; 1029371c9d4SSatish Balay (*args)[*argc][cnt++] = 0; 1039371c9d4SSatish Balay (*argc)++; 1049371c9d4SSatish Balay cnt = 0; 1059371c9d4SSatish Balay } else if (s[i] != sp && s[i] != 0) { 1069371c9d4SSatish Balay (*args)[*argc][cnt++] = s[i]; 1079371c9d4SSatish Balay flg = PETSC_FALSE; 1089371c9d4SSatish Balay } 1093c311c98SBarry Smith } 1103c311c98SBarry Smith return 0; 1113c311c98SBarry Smith } 1123c311c98SBarry Smith 113301d30feSBarry Smith /*@C 114*811af0c4SBarry Smith PetscStrToArrayDestroy - Frees array created with `PetscStrToArray()`. 115301d30feSBarry Smith 116301d30feSBarry Smith Not Collective 117301d30feSBarry Smith 118301d30feSBarry Smith Output Parameters: 119301d30feSBarry Smith + argc - the number of arguments 120301d30feSBarry Smith - args - the array of arguments 121301d30feSBarry Smith 122301d30feSBarry Smith Level: intermediate 123301d30feSBarry Smith 124*811af0c4SBarry Smith Note: 125*811af0c4SBarry Smith This may be called before `PetscInitialize()` or after `PetscFinalize()` 126301d30feSBarry Smith 127*811af0c4SBarry Smith Fortran Note: 1286f013253SBarry Smith Not for use in Fortran 1296f013253SBarry Smith 130db781477SPatrick Sanan .seealso: `PetscStrToArray()` 131301d30feSBarry Smith @*/ 1329371c9d4SSatish Balay PetscErrorCode PetscStrToArrayDestroy(int argc, char **args) { 1335f80ce2aSJacob Faibussowitsch for (int i = 0; i < argc; ++i) free(args[i]); 134a297a907SKarl Rupp if (args) free(args); 135301d30feSBarry Smith return 0; 136301d30feSBarry Smith } 137301d30feSBarry Smith 138e5c89e4eSSatish Balay /*@C 139e5c89e4eSSatish Balay PetscStrlen - Gets length of a string 140e5c89e4eSSatish Balay 141e5c89e4eSSatish Balay Not Collective 142e5c89e4eSSatish Balay 143e5c89e4eSSatish Balay Input Parameters: 144e5c89e4eSSatish Balay . s - pointer to string 145e5c89e4eSSatish Balay 146e5c89e4eSSatish Balay Output Parameter: 147e5c89e4eSSatish Balay . len - length in bytes 148e5c89e4eSSatish Balay 149e5c89e4eSSatish Balay Level: intermediate 150e5c89e4eSSatish Balay 151e5c89e4eSSatish Balay Note: 152*811af0c4SBarry Smith This routine is analogous to `strlen()`. 153e5c89e4eSSatish Balay 154e5c89e4eSSatish Balay Null string returns a length of zero 155e5c89e4eSSatish Balay 156*811af0c4SBarry Smith Fortran Note: 1576f013253SBarry Smith Not for use in Fortran 1586f013253SBarry Smith 159*811af0c4SBarry Smith .seealso: `PetscStrallocpy()` 160e5c89e4eSSatish Balay @*/ 1619371c9d4SSatish Balay PetscErrorCode PetscStrlen(const char s[], size_t *len) { 162e5c89e4eSSatish Balay PetscFunctionBegin; 1635f80ce2aSJacob Faibussowitsch *len = s ? strlen(s) : 0; 164e5c89e4eSSatish Balay PetscFunctionReturn(0); 165e5c89e4eSSatish Balay } 166e5c89e4eSSatish Balay 167e5c89e4eSSatish Balay /*@C 168*811af0c4SBarry Smith PetscStrallocpy - Allocates space to hold a copy of a string then copies the string in the new space 169e5c89e4eSSatish Balay 170e5c89e4eSSatish Balay Not Collective 171e5c89e4eSSatish Balay 172e5c89e4eSSatish Balay Input Parameters: 173e5c89e4eSSatish Balay . s - pointer to string 174e5c89e4eSSatish Balay 175e5c89e4eSSatish Balay Output Parameter: 176e5c89e4eSSatish Balay . t - the copied string 177e5c89e4eSSatish Balay 178e5c89e4eSSatish Balay Level: intermediate 179e5c89e4eSSatish Balay 180*811af0c4SBarry Smith Notes: 181e5c89e4eSSatish Balay Null string returns a new null string 182e5c89e4eSSatish Balay 183*811af0c4SBarry Smith If t has previously been allocated then that memory is lost, you may need to PetscFree() 1840ecf5a55SBarry Smith the array before calling this routine. 1850ecf5a55SBarry Smith 186*811af0c4SBarry Smith Fortran Note: 187*811af0c4SBarry Smith Not for use in Fortran 1880ecf5a55SBarry Smith 189*811af0c4SBarry Smith .seealso: `PetscStrArrayallocpy()`, `PetscStrcpy()`, `PetscStrNArrayallocpy()` 190e5c89e4eSSatish Balay @*/ 1919371c9d4SSatish Balay PetscErrorCode PetscStrallocpy(const char s[], char *t[]) { 19202c9f0b5SLisandro Dalcin char *tmp = NULL; 193e5c89e4eSSatish Balay 194e5c89e4eSSatish Balay PetscFunctionBegin; 195e5c89e4eSSatish Balay if (s) { 1965f80ce2aSJacob Faibussowitsch size_t len; 1975f80ce2aSJacob Faibussowitsch 1989566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s, &len)); 1999566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1 + len, &tmp)); 2009566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(tmp, s)); 201e5c89e4eSSatish Balay } 20271573d7dSBarry Smith *t = tmp; 203e5c89e4eSSatish Balay PetscFunctionReturn(0); 204e5c89e4eSSatish Balay } 205e5c89e4eSSatish Balay 20647340559SBarry Smith /*@C 20747340559SBarry Smith PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 20847340559SBarry Smith 20947340559SBarry Smith Not Collective 21047340559SBarry Smith 21147340559SBarry Smith Input Parameters: 21247340559SBarry Smith . s - pointer to array of strings (final string is a null) 21347340559SBarry Smith 21447340559SBarry Smith Output Parameter: 21547340559SBarry Smith . t - the copied array string 21647340559SBarry Smith 21747340559SBarry Smith Level: intermediate 21847340559SBarry Smith 21947340559SBarry Smith Note: 220*811af0c4SBarry Smith If t has previously been allocated then that memory is lost, you may need to PetscStrArrayDestroy() 2210ecf5a55SBarry Smith the array before calling this routine. 2220ecf5a55SBarry Smith 223*811af0c4SBarry Smith Fortran Note: 224*811af0c4SBarry Smith Not for use in Fortran 22547340559SBarry Smith 226*811af0c4SBarry Smith .seealso: `PetscStrallocpy()`, `PetscStrArrayDestroy()`, `PetscStrNArrayallocpy()` 22747340559SBarry Smith @*/ 2289371c9d4SSatish Balay PetscErrorCode PetscStrArrayallocpy(const char *const *list, char ***t) { 2295f80ce2aSJacob Faibussowitsch PetscInt n = 0; 23047340559SBarry Smith 23147340559SBarry Smith PetscFunctionBegin; 2329371c9d4SSatish Balay while (list[n++]) 2339371c9d4SSatish Balay ; 2349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n + 1, t)); 2359566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 2360298fd71SBarry Smith (*t)[n] = NULL; 23747340559SBarry Smith PetscFunctionReturn(0); 23847340559SBarry Smith } 23947340559SBarry Smith 24047340559SBarry Smith /*@C 241*811af0c4SBarry Smith PetscStrArrayDestroy - Frees array of strings created with `PetscStrArrayallocpy()`. 24247340559SBarry Smith 24347340559SBarry Smith Not Collective 24447340559SBarry Smith 24547340559SBarry Smith Output Parameters: 24647340559SBarry Smith . list - array of strings 24747340559SBarry Smith 24847340559SBarry Smith Level: intermediate 24947340559SBarry Smith 250*811af0c4SBarry Smith Fortran Note: 25195452b02SPatrick Sanan Not for use in Fortran 25247340559SBarry Smith 253db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()` 25447340559SBarry Smith @*/ 2559371c9d4SSatish Balay PetscErrorCode PetscStrArrayDestroy(char ***list) { 25647340559SBarry Smith PetscInt n = 0; 25747340559SBarry Smith 2586fed8037SJed Brown PetscFunctionBegin; 2596fed8037SJed Brown if (!*list) PetscFunctionReturn(0); 2606fed8037SJed Brown while ((*list)[n]) { 2619566063dSJacob Faibussowitsch PetscCall(PetscFree((*list)[n])); 2625f80ce2aSJacob Faibussowitsch ++n; 26347340559SBarry Smith } 2649566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 2656fed8037SJed Brown PetscFunctionReturn(0); 26647340559SBarry Smith } 26747340559SBarry Smith 2686991f827SBarry Smith /*@C 2696991f827SBarry Smith PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 2706991f827SBarry Smith 2716991f827SBarry Smith Not Collective 2726991f827SBarry Smith 2736991f827SBarry Smith Input Parameters: 2746991f827SBarry Smith + n - the number of string entries 2756991f827SBarry Smith - s - pointer to array of strings 2766991f827SBarry Smith 2776991f827SBarry Smith Output Parameter: 2786991f827SBarry Smith . t - the copied array string 2796991f827SBarry Smith 2806991f827SBarry Smith Level: intermediate 2816991f827SBarry Smith 282*811af0c4SBarry Smith Fortran Note: 2836991f827SBarry Smith Not for use in Fortran 2846991f827SBarry Smith 285db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayallocpy()`, `PetscStrNArrayDestroy()` 2866991f827SBarry Smith @*/ 2879371c9d4SSatish Balay PetscErrorCode PetscStrNArrayallocpy(PetscInt n, const char *const *list, char ***t) { 2886991f827SBarry Smith PetscFunctionBegin; 2899566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, t)); 2909566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 2916991f827SBarry Smith PetscFunctionReturn(0); 2926991f827SBarry Smith } 2936991f827SBarry Smith 2946991f827SBarry Smith /*@C 295*811af0c4SBarry Smith PetscStrNArrayDestroy - Frees array of strings created with `PetscStrNArrayallocpy()`. 2966991f827SBarry Smith 2976991f827SBarry Smith Not Collective 2986991f827SBarry Smith 2996991f827SBarry Smith Output Parameters: 3006991f827SBarry Smith + n - number of string entries 3016991f827SBarry Smith - list - array of strings 3026991f827SBarry Smith 3036991f827SBarry Smith Level: intermediate 3046991f827SBarry Smith 305*811af0c4SBarry Smith Fortran Note: 30695452b02SPatrick Sanan Not for use in Fortran 3076991f827SBarry Smith 308*811af0c4SBarry Smith .seealso: `PetscStrNArrayallocpy()`, `PetscStrArrayallocpy()` 3096991f827SBarry Smith @*/ 3109371c9d4SSatish Balay PetscErrorCode PetscStrNArrayDestroy(PetscInt n, char ***list) { 3116991f827SBarry Smith PetscFunctionBegin; 3126991f827SBarry Smith if (!*list) PetscFunctionReturn(0); 3139566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscFree((*list)[i])); 3149566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 3156991f827SBarry Smith PetscFunctionReturn(0); 3166991f827SBarry Smith } 3176991f827SBarry Smith 318e5c89e4eSSatish Balay /*@C 319e5c89e4eSSatish Balay PetscStrcpy - Copies a string 320e5c89e4eSSatish Balay 321e5c89e4eSSatish Balay Not Collective 322e5c89e4eSSatish Balay 323e5c89e4eSSatish Balay Input Parameters: 324e5c89e4eSSatish Balay . t - pointer to string 325e5c89e4eSSatish Balay 326e5c89e4eSSatish Balay Output Parameter: 327e5c89e4eSSatish Balay . s - the copied string 328e5c89e4eSSatish Balay 329e5c89e4eSSatish Balay Level: intermediate 330e5c89e4eSSatish Balay 3316f013253SBarry Smith Notes: 332e5c89e4eSSatish Balay Null string returns a string starting with zero 333e5c89e4eSSatish Balay 334*811af0c4SBarry Smith It is recommended you use `PetscStrncpy()` instead of this routine 335*811af0c4SBarry Smith 336*811af0c4SBarry Smith Fortran Note: 3376f013253SBarry Smith Not for use in Fortran 3386f013253SBarry Smith 339*811af0c4SBarry Smith .seealso: `PetscStrncpy()`, `PetscStrcat()`, `PetscStrlcat()`, `PetscStrallocpy()` 340e5c89e4eSSatish Balay @*/ 341acc6cc86SBarry Smith 3429371c9d4SSatish Balay PetscErrorCode PetscStrcpy(char s[], const char t[]) { 343e5c89e4eSSatish Balay PetscFunctionBegin; 3445f80ce2aSJacob Faibussowitsch if (t) { 3455f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s, 1); 3465f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t, 2); 3475f80ce2aSJacob Faibussowitsch strcpy(s, t); 3485f80ce2aSJacob Faibussowitsch } else if (s) s[0] = 0; 349e5c89e4eSSatish Balay PetscFunctionReturn(0); 350e5c89e4eSSatish Balay } 351e5c89e4eSSatish Balay 352e5c89e4eSSatish Balay /*@C 353e5c89e4eSSatish Balay PetscStrncpy - Copies a string up to a certain length 354e5c89e4eSSatish Balay 355e5c89e4eSSatish Balay Not Collective 356e5c89e4eSSatish Balay 357e5c89e4eSSatish Balay Input Parameters: 358e5c89e4eSSatish Balay + t - pointer to string 359e5c89e4eSSatish Balay - n - the length to copy 360e5c89e4eSSatish Balay 361e5c89e4eSSatish Balay Output Parameter: 362e5c89e4eSSatish Balay . s - the copied string 363e5c89e4eSSatish Balay 364e5c89e4eSSatish Balay Level: intermediate 365e5c89e4eSSatish Balay 366e5c89e4eSSatish Balay Note: 367e5c89e4eSSatish Balay Null string returns a string starting with zero 368e5c89e4eSSatish Balay 369ff32304bSBarry Smith If the string that is being copied is of length n or larger then the entire string is not 3701b6ef838SBarry Smith copied and the final location of s is set to NULL. This is different then the behavior of 371*811af0c4SBarry Smith `strncpy()` which leaves s non-terminated if there is not room for the entire string. 372ff32304bSBarry Smith 373*811af0c4SBarry Smith Developers Note: 374*811af0c4SBarry Smith Should this be `PetscStrlcpy()` to reflect its behavior which is like `strlcpy()` not `strncpy()` 37562a5de14SBarry Smith 376*811af0c4SBarry Smith .seealso: `PetscStrcpy()`, `PetscStrcat()`, `PetscStrlcat()`, `PetscStrallocpy()` 377e5c89e4eSSatish Balay @*/ 3789371c9d4SSatish Balay PetscErrorCode PetscStrncpy(char s[], const char t[], size_t n) { 379e5c89e4eSSatish Balay PetscFunctionBegin; 3805f80ce2aSJacob 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"); 381ff32304bSBarry Smith if (t) { 3825f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s, 1); 3838dc57659SBarry Smith if (n > 1) { 3842c26941aSBarry Smith strncpy(s, t, n - 1); 385ff32304bSBarry Smith s[n - 1] = '\0'; 3868dc57659SBarry Smith } else { 3878dc57659SBarry Smith s[0] = '\0'; 3888dc57659SBarry Smith } 389ff32304bSBarry Smith } else if (s) s[0] = 0; 390e5c89e4eSSatish Balay PetscFunctionReturn(0); 391e5c89e4eSSatish Balay } 392e5c89e4eSSatish Balay 393e5c89e4eSSatish Balay /*@C 394e5c89e4eSSatish Balay PetscStrcat - Concatenates a string onto a given string 395e5c89e4eSSatish Balay 396e5c89e4eSSatish Balay Not Collective 397e5c89e4eSSatish Balay 398e5c89e4eSSatish Balay Input Parameters: 399e5e2177aSMatthew Knepley + s - string to be added to 400e5e2177aSMatthew Knepley - t - pointer to string to be added to end 401e5c89e4eSSatish Balay 402e5c89e4eSSatish Balay Level: intermediate 403e5c89e4eSSatish Balay 404*811af0c4SBarry Smith Note: 405*811af0c4SBarry Smith It is recommended you use `PetscStrlcat()` instead of this routine 406*811af0c4SBarry Smith 407*811af0c4SBarry Smith Fortran Note: 40895452b02SPatrick Sanan Not for use in Fortran 4096f013253SBarry Smith 410db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrncpy()`, `PetscStrlcat()` 411e5c89e4eSSatish Balay @*/ 4129371c9d4SSatish Balay PetscErrorCode PetscStrcat(char s[], const char t[]) { 413e5c89e4eSSatish Balay PetscFunctionBegin; 4149b754dc9SBarry Smith if (!t) PetscFunctionReturn(0); 4155f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s, 1); 4165f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t, 2); 417e5c89e4eSSatish Balay strcat(s, t); 418e5c89e4eSSatish Balay PetscFunctionReturn(0); 419e5c89e4eSSatish Balay } 420e5c89e4eSSatish Balay 421e5c89e4eSSatish Balay /*@C 422a126751eSBarry Smith PetscStrlcat - Concatenates a string onto a given string, up to a given length 423e5c89e4eSSatish Balay 424e5c89e4eSSatish Balay Not Collective 425e5c89e4eSSatish Balay 426e5c89e4eSSatish Balay Input Parameters: 427e0ffd71fSBarry Smith + s - pointer to string to be added to at end 42872fa4726SStefano Zampini . t - string to be added 42924a58d73SPatrick Sanan - n - length of the original allocated string 430e5c89e4eSSatish Balay 431e5c89e4eSSatish Balay Level: intermediate 432e5c89e4eSSatish Balay 433*811af0c4SBarry Smith Note: 434*811af0c4SBarry Smith Unlike the system call `strncat()`, the length passed in is the length of the 435*811af0c4SBarry Smith original allocated space, not the length of the left-over space. This is 436*811af0c4SBarry Smith similar to the BSD system call `strlcat()`. 437*811af0c4SBarry Smith 438*811af0c4SBarry Smith Fortran Note: 43924a58d73SPatrick Sanan Not for use in Fortran 4406f013253SBarry Smith 441db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrncpy()`, `PetscStrcat()` 442e5c89e4eSSatish Balay @*/ 4439371c9d4SSatish Balay PetscErrorCode PetscStrlcat(char s[], const char t[], size_t n) { 444153a8027SBarry Smith size_t len; 445153a8027SBarry Smith 446e5c89e4eSSatish Balay PetscFunctionBegin; 447e0ffd71fSBarry Smith if (!t) PetscFunctionReturn(0); 4485f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s, 1); 4495f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t, 2); 4505f80ce2aSJacob Faibussowitsch PetscCheck(n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "String buffer length must be positive"); 4519566063dSJacob Faibussowitsch PetscCall(PetscStrlen(t, &len)); 452153a8027SBarry Smith strncat(s, t, n - len); 453681eeb0aSBarry Smith s[n - 1] = 0; 454e5c89e4eSSatish Balay PetscFunctionReturn(0); 455e5c89e4eSSatish Balay } 456e5c89e4eSSatish Balay 4579371c9d4SSatish Balay void PetscStrcmpNoError(const char a[], const char b[], PetscBool *flg) { 458573b0fb4SBarry Smith if (!a && !b) *flg = PETSC_TRUE; 459573b0fb4SBarry Smith else if (!a || !b) *flg = PETSC_FALSE; 4605f80ce2aSJacob Faibussowitsch else *flg = strcmp(a, b) ? PETSC_FALSE : PETSC_TRUE; 461573b0fb4SBarry Smith } 462573b0fb4SBarry Smith 463e5c89e4eSSatish Balay /*@C 464*811af0c4SBarry Smith PetscBasename - returns a pointer to the last entry of a / or \ separated directory path 46580b92c66SBarry Smith 46680b92c66SBarry Smith Not Collective 46780b92c66SBarry Smith 46880b92c66SBarry Smith Input Parameter: 46980b92c66SBarry Smith . a - pointer to string 47080b92c66SBarry Smith 47180b92c66SBarry Smith Level: intermediate 47280b92c66SBarry Smith 473*811af0c4SBarry Smith Fortran Note: 47480b92c66SBarry Smith Not for use in Fortran 47580b92c66SBarry Smith 47680b92c66SBarry Smith .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`, `PetscStrrchr()`,`PetscStrcmp()`,`PetscStrstr()`, 47780b92c66SBarry Smith `PetscTokenCreate()`, `PetscStrToArray()`, `PetscStrInList()` 47880b92c66SBarry Smith @*/ 4799371c9d4SSatish Balay const char *PetscBasename(const char a[]) { 48080b92c66SBarry Smith const char *ptr; 48180b92c66SBarry Smith 48280b92c66SBarry Smith if (PetscStrrchr(a, '/', (char **)&ptr)) ptr = NULL; 483660278c0SBarry Smith if (ptr == a) { 484660278c0SBarry Smith if (PetscStrrchr(a, '\\', (char **)&ptr)) ptr = NULL; 485660278c0SBarry Smith } 48680b92c66SBarry Smith return ptr; 48780b92c66SBarry Smith } 48880b92c66SBarry Smith 48980b92c66SBarry Smith /*@C 490e5c89e4eSSatish Balay PetscStrcmp - Compares two strings, 491e5c89e4eSSatish Balay 492e5c89e4eSSatish Balay Not Collective 493e5c89e4eSSatish Balay 494e5c89e4eSSatish Balay Input Parameters: 495e5c89e4eSSatish Balay + a - pointer to string first string 496e5c89e4eSSatish Balay - b - pointer to second string 497e5c89e4eSSatish Balay 498e5c89e4eSSatish Balay Output Parameter: 499*811af0c4SBarry Smith . flg - `PETSC_TRUE` if the two strings are equal 500e5c89e4eSSatish Balay 501e5c89e4eSSatish Balay Level: intermediate 502e5c89e4eSSatish Balay 503*811af0c4SBarry Smith Fortran Note: 50495452b02SPatrick Sanan Not for use in Fortran 5056f013253SBarry Smith 506db781477SPatrick Sanan .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()` 507e5c89e4eSSatish Balay @*/ 5089371c9d4SSatish Balay PetscErrorCode PetscStrcmp(const char a[], const char b[], PetscBool *flg) { 509e5c89e4eSSatish Balay PetscFunctionBegin; 5105f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg, 3); 511a297a907SKarl Rupp if (!a && !b) *flg = PETSC_TRUE; 512a297a907SKarl Rupp else if (!a || !b) *flg = PETSC_FALSE; 513b45e3bf4SStefano Zampini else *flg = (PetscBool)!strcmp(a, b); 514e5c89e4eSSatish Balay PetscFunctionReturn(0); 515e5c89e4eSSatish Balay } 516e5c89e4eSSatish Balay 517e5c89e4eSSatish Balay /*@C 518e5c89e4eSSatish Balay PetscStrgrt - If first string is greater than the second 519e5c89e4eSSatish Balay 520e5c89e4eSSatish Balay Not Collective 521e5c89e4eSSatish Balay 522e5c89e4eSSatish Balay Input Parameters: 523e5c89e4eSSatish Balay + a - pointer to first string 524e5c89e4eSSatish Balay - b - pointer to second string 525e5c89e4eSSatish Balay 526e5c89e4eSSatish Balay Output Parameter: 527e5c89e4eSSatish Balay . flg - if the first string is greater 528e5c89e4eSSatish Balay 529*811af0c4SBarry Smith Note: 530e5c89e4eSSatish Balay Null arguments are ok, a null string is considered smaller than 531e5c89e4eSSatish Balay all others 532e5c89e4eSSatish Balay 533*811af0c4SBarry Smith Fortran Note: 5346f013253SBarry Smith Not for use in Fortran 5356f013253SBarry Smith 536e5c89e4eSSatish Balay Level: intermediate 537e5c89e4eSSatish Balay 538db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrcasecmp()` 539e5c89e4eSSatish Balay @*/ 5409371c9d4SSatish Balay PetscErrorCode PetscStrgrt(const char a[], const char b[], PetscBool *t) { 541e5c89e4eSSatish Balay PetscFunctionBegin; 5425f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t, 3); 543a297a907SKarl Rupp if (!a && !b) *t = PETSC_FALSE; 544a297a907SKarl Rupp else if (a && !b) *t = PETSC_TRUE; 545a297a907SKarl Rupp else if (!a && b) *t = PETSC_FALSE; 546a297a907SKarl Rupp else { 5475f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 5485f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 2); 5495f80ce2aSJacob Faibussowitsch *t = strcmp(a, b) > 0 ? PETSC_TRUE : PETSC_FALSE; 550e5c89e4eSSatish Balay } 551e5c89e4eSSatish Balay PetscFunctionReturn(0); 552e5c89e4eSSatish Balay } 553e5c89e4eSSatish Balay 554e5c89e4eSSatish Balay /*@C 555e5c89e4eSSatish Balay PetscStrcasecmp - Returns true if the two strings are the same 556e5c89e4eSSatish Balay except possibly for case. 557e5c89e4eSSatish Balay 558e5c89e4eSSatish Balay Not Collective 559e5c89e4eSSatish Balay 560e5c89e4eSSatish Balay Input Parameters: 561e5c89e4eSSatish Balay + a - pointer to first string 562e5c89e4eSSatish Balay - b - pointer to second string 563e5c89e4eSSatish Balay 564e5c89e4eSSatish Balay Output Parameter: 565e5c89e4eSSatish Balay . flg - if the two strings are the same 566e5c89e4eSSatish Balay 567*811af0c4SBarry Smith Note: 568e5c89e4eSSatish Balay Null arguments are ok 569e5c89e4eSSatish Balay 570*811af0c4SBarry Smith Fortran Note: 5716f013253SBarry Smith Not for use in Fortran 5726f013253SBarry Smith 573e5c89e4eSSatish Balay Level: intermediate 574e5c89e4eSSatish Balay 575db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrgrt()` 576e5c89e4eSSatish Balay @*/ 5779371c9d4SSatish Balay PetscErrorCode PetscStrcasecmp(const char a[], const char b[], PetscBool *t) { 578e5c89e4eSSatish Balay int c; 579e5c89e4eSSatish Balay 580e5c89e4eSSatish Balay PetscFunctionBegin; 5815f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t, 3); 582e5c89e4eSSatish Balay if (!a && !b) c = 0; 583e5c89e4eSSatish Balay else if (!a || !b) c = 1; 58432b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP) 58532b366c8SSatish Balay else c = strcasecmp(a, b); 58632b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP) 587e5c89e4eSSatish Balay else c = stricmp(a, b); 588e5c89e4eSSatish Balay #else 58932b366c8SSatish Balay else { 59032b366c8SSatish Balay char *aa, *bb; 5919566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &aa)); 5929566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(b, &bb)); 5939566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(aa)); 5949566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(bb)); 5959566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(aa, bb, t)); 5969566063dSJacob Faibussowitsch PetscCall(PetscFree(aa)); 5979566063dSJacob Faibussowitsch PetscCall(PetscFree(bb)); 59832b366c8SSatish Balay PetscFunctionReturn(0); 59932b366c8SSatish Balay } 600e5c89e4eSSatish Balay #endif 6015f80ce2aSJacob Faibussowitsch *t = c ? PETSC_FALSE : PETSC_TRUE; 602e5c89e4eSSatish Balay PetscFunctionReturn(0); 603e5c89e4eSSatish Balay } 604e5c89e4eSSatish Balay 605e5c89e4eSSatish Balay /*@C 606e5c89e4eSSatish Balay PetscStrncmp - Compares two strings, up to a certain length 607e5c89e4eSSatish Balay 608e5c89e4eSSatish Balay Not Collective 609e5c89e4eSSatish Balay 610e5c89e4eSSatish Balay Input Parameters: 611e5c89e4eSSatish Balay + a - pointer to first string 612e5c89e4eSSatish Balay . b - pointer to second string 613e5c89e4eSSatish Balay - n - length to compare up to 614e5c89e4eSSatish Balay 615e5c89e4eSSatish Balay Output Parameter: 616e5c89e4eSSatish Balay . t - if the two strings are equal 617e5c89e4eSSatish Balay 618e5c89e4eSSatish Balay Level: intermediate 619e5c89e4eSSatish Balay 620*811af0c4SBarry Smith Fortran Note: 62195452b02SPatrick Sanan Not for use in Fortran 6226f013253SBarry Smith 623db781477SPatrick Sanan .seealso: `PetscStrgrt()`, `PetscStrcmp()`, `PetscStrcasecmp()` 624e5c89e4eSSatish Balay @*/ 6259371c9d4SSatish Balay PetscErrorCode PetscStrncmp(const char a[], const char b[], size_t n, PetscBool *t) { 626e5c89e4eSSatish Balay PetscFunctionBegin; 6275f80ce2aSJacob Faibussowitsch if (n) { 6285f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 6295f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 2); 6305f80ce2aSJacob Faibussowitsch } 6315f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t, 4); 6325f80ce2aSJacob Faibussowitsch *t = strncmp(a, b, n) ? PETSC_FALSE : PETSC_TRUE; 633e5c89e4eSSatish Balay PetscFunctionReturn(0); 634e5c89e4eSSatish Balay } 635e5c89e4eSSatish Balay 636e5c89e4eSSatish Balay /*@C 637a5b23f4aSJose E. Roman PetscStrchr - Locates first occurrence of a character in a string 638e5c89e4eSSatish Balay 639e5c89e4eSSatish Balay Not Collective 640e5c89e4eSSatish Balay 641e5c89e4eSSatish Balay Input Parameters: 642e5c89e4eSSatish Balay + a - pointer to string 643e5c89e4eSSatish Balay - b - character 644e5c89e4eSSatish Balay 645e5c89e4eSSatish Balay Output Parameter: 646a5b23f4aSJose E. Roman . c - location of occurrence, NULL if not found 647e5c89e4eSSatish Balay 648e5c89e4eSSatish Balay Level: intermediate 649e5c89e4eSSatish Balay 650*811af0c4SBarry Smith Fortran Note: 65195452b02SPatrick Sanan Not for use in Fortran 6526f013253SBarry Smith 653*811af0c4SBarry Smith .seealso: `PetscStrrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()` 654e5c89e4eSSatish Balay @*/ 6559371c9d4SSatish Balay PetscErrorCode PetscStrchr(const char a[], char b, char *c[]) { 656e5c89e4eSSatish Balay PetscFunctionBegin; 6575f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 6585f80ce2aSJacob Faibussowitsch PetscValidPointer(c, 3); 659e5c89e4eSSatish Balay *c = (char *)strchr(a, b); 660e5c89e4eSSatish Balay PetscFunctionReturn(0); 661e5c89e4eSSatish Balay } 662e5c89e4eSSatish Balay 663e5c89e4eSSatish Balay /*@C 664a5b23f4aSJose E. Roman PetscStrrchr - Locates one location past the last occurrence of a character in a string, 665e5c89e4eSSatish Balay if the character is not found then returns entire string 666e5c89e4eSSatish Balay 667e5c89e4eSSatish Balay Not Collective 668e5c89e4eSSatish Balay 669e5c89e4eSSatish Balay Input Parameters: 670e5c89e4eSSatish Balay + a - pointer to string 671e5c89e4eSSatish Balay - b - character 672e5c89e4eSSatish Balay 673e5c89e4eSSatish Balay Output Parameter: 674a5b23f4aSJose E. Roman . tmp - location of occurrence, a if not found 675e5c89e4eSSatish Balay 676e5c89e4eSSatish Balay Level: intermediate 677e5c89e4eSSatish Balay 678*811af0c4SBarry Smith Fortran Note: 67995452b02SPatrick Sanan Not for use in Fortran 6806f013253SBarry Smith 681*811af0c4SBarry Smith .seealso: `PetscStrchr()`, `PetscTokenCreate()`, `PetscStrendswith()`, `PetscStrbeginsswith()` 682e5c89e4eSSatish Balay @*/ 6839371c9d4SSatish Balay PetscErrorCode PetscStrrchr(const char a[], char b, char *tmp[]) { 684e5c89e4eSSatish Balay PetscFunctionBegin; 6855f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 6865f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp, 3); 687e5c89e4eSSatish Balay *tmp = (char *)strrchr(a, b); 688a297a907SKarl Rupp if (!*tmp) *tmp = (char *)a; 689a297a907SKarl Rupp else *tmp = *tmp + 1; 690e5c89e4eSSatish Balay PetscFunctionReturn(0); 691e5c89e4eSSatish Balay } 692e5c89e4eSSatish Balay 693e5c89e4eSSatish Balay /*@C 694e5c89e4eSSatish Balay PetscStrtolower - Converts string to lower case 695e5c89e4eSSatish Balay 696e5c89e4eSSatish Balay Not Collective 697e5c89e4eSSatish Balay 698e5c89e4eSSatish Balay Input Parameters: 699e5c89e4eSSatish Balay . a - pointer to string 700e5c89e4eSSatish Balay 701e5c89e4eSSatish Balay Level: intermediate 702e5c89e4eSSatish Balay 703*811af0c4SBarry Smith Fortran Note: 70495452b02SPatrick Sanan Not for use in Fortran 7056f013253SBarry Smith 706*811af0c4SBarry Smith .seealso: `PetscStrtoupper()` 707e5c89e4eSSatish Balay @*/ 7089371c9d4SSatish Balay PetscErrorCode PetscStrtolower(char a[]) { 709e5c89e4eSSatish Balay PetscFunctionBegin; 7105f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 711e5c89e4eSSatish Balay while (*a) { 712e5c89e4eSSatish Balay if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 713e5c89e4eSSatish Balay a++; 714e5c89e4eSSatish Balay } 715e5c89e4eSSatish Balay PetscFunctionReturn(0); 716e5c89e4eSSatish Balay } 717e5c89e4eSSatish Balay 7182f234a98SBarry Smith /*@C 7196e3a5469SBarry Smith PetscStrtoupper - Converts string to upper case 7202f234a98SBarry Smith 7212f234a98SBarry Smith Not Collective 7222f234a98SBarry Smith 7232f234a98SBarry Smith Input Parameters: 7242f234a98SBarry Smith . a - pointer to string 7252f234a98SBarry Smith 7262f234a98SBarry Smith Level: intermediate 7272f234a98SBarry Smith 728*811af0c4SBarry Smith Fortran Note: 72995452b02SPatrick Sanan Not for use in Fortran 7302f234a98SBarry Smith 731*811af0c4SBarry Smith .seealso: `PetscStrtolower()` 7322f234a98SBarry Smith @*/ 7339371c9d4SSatish Balay PetscErrorCode PetscStrtoupper(char a[]) { 7342f234a98SBarry Smith PetscFunctionBegin; 7355f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 7362f234a98SBarry Smith while (*a) { 7372f234a98SBarry Smith if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a'; 7382f234a98SBarry Smith a++; 7392f234a98SBarry Smith } 7402f234a98SBarry Smith PetscFunctionReturn(0); 7412f234a98SBarry Smith } 7422f234a98SBarry Smith 7437ba3a57cSBarry Smith /*@C 7447ba3a57cSBarry Smith PetscStrendswith - Determines if a string ends with a certain string 7451d1a0024SBarry Smith 7467ba3a57cSBarry Smith Not Collective 7477ba3a57cSBarry Smith 7487ba3a57cSBarry Smith Input Parameters: 7497ba3a57cSBarry Smith + a - pointer to string 7507ba3a57cSBarry Smith - b - string to endwith 7517ba3a57cSBarry Smith 7527ba3a57cSBarry Smith Output Parameter: 753*811af0c4SBarry Smith . flg - `PETSC_TRUE` or `PETSC_FALSE` 7547ba3a57cSBarry Smith 755*811af0c4SBarry Smith Fortran Note: 75695452b02SPatrick Sanan Not for use in Fortran 7577ba3a57cSBarry Smith 7587ba3a57cSBarry Smith Level: intermediate 7597ba3a57cSBarry Smith 760*811af0c4SBarry Smith .seealso: `PetscStrendswithwhich()`, `PetscStrbeginswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 761*811af0c4SBarry Smith `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 7627ba3a57cSBarry Smith @*/ 7639371c9d4SSatish Balay PetscErrorCode PetscStrendswith(const char a[], const char b[], PetscBool *flg) { 7647ba3a57cSBarry Smith char *test; 7657ba3a57cSBarry Smith 7667ba3a57cSBarry Smith PetscFunctionBegin; 7675f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg, 3); 7687ba3a57cSBarry Smith *flg = PETSC_FALSE; 7699566063dSJacob Faibussowitsch PetscCall(PetscStrrstr(a, b, &test)); 7707ba3a57cSBarry Smith if (test) { 7715f80ce2aSJacob Faibussowitsch size_t na, nb; 7725f80ce2aSJacob Faibussowitsch 7739566063dSJacob Faibussowitsch PetscCall(PetscStrlen(a, &na)); 7749566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b, &nb)); 7757ba3a57cSBarry Smith if (a + na - nb == test) *flg = PETSC_TRUE; 7767ba3a57cSBarry Smith } 7777ba3a57cSBarry Smith PetscFunctionReturn(0); 7787ba3a57cSBarry Smith } 7797ba3a57cSBarry Smith 7802c9581d2SBarry Smith /*@C 7812c9581d2SBarry Smith PetscStrbeginswith - Determines if a string begins with a certain string 7822c9581d2SBarry Smith 7832c9581d2SBarry Smith Not Collective 7842c9581d2SBarry Smith 7852c9581d2SBarry Smith Input Parameters: 7862c9581d2SBarry Smith + a - pointer to string 7872c9581d2SBarry Smith - b - string to begin with 7882c9581d2SBarry Smith 7892c9581d2SBarry Smith Output Parameter: 7902c9581d2SBarry Smith . flg - PETSC_TRUE or PETSC_FALSE 7912c9581d2SBarry Smith 792*811af0c4SBarry Smith Fortran Note: 79395452b02SPatrick Sanan Not for use in Fortran 7942c9581d2SBarry Smith 7952c9581d2SBarry Smith Level: intermediate 7962c9581d2SBarry Smith 797db781477SPatrick Sanan .seealso: `PetscStrendswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 798db781477SPatrick Sanan `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 7992c9581d2SBarry Smith @*/ 8009371c9d4SSatish Balay PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg) { 8012c9581d2SBarry Smith char *test; 8022c9581d2SBarry Smith 8032c9581d2SBarry Smith PetscFunctionBegin; 8045f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 8055f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 2); 8065f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg, 3); 8072c9581d2SBarry Smith *flg = PETSC_FALSE; 8089566063dSJacob Faibussowitsch PetscCall(PetscStrrstr(a, b, &test)); 809a297a907SKarl Rupp if (test && (test == a)) *flg = PETSC_TRUE; 8102c9581d2SBarry Smith PetscFunctionReturn(0); 8112c9581d2SBarry Smith } 8122c9581d2SBarry Smith 8137ba3a57cSBarry Smith /*@C 8147ba3a57cSBarry Smith PetscStrendswithwhich - Determines if a string ends with one of several possible strings 8157ba3a57cSBarry Smith 8167ba3a57cSBarry Smith Not Collective 8177ba3a57cSBarry Smith 8187ba3a57cSBarry Smith Input Parameters: 8197ba3a57cSBarry Smith + a - pointer to string 820fa4b66f2SVaclav Hapla - bs - strings to end with (last entry must be NULL) 8217ba3a57cSBarry Smith 8227ba3a57cSBarry Smith Output Parameter: 823fa4b66f2SVaclav Hapla . cnt - the index of the string it ends with or the index of NULL 8247ba3a57cSBarry Smith 825*811af0c4SBarry Smith Fortran Note: 82695452b02SPatrick Sanan Not for use in Fortran 8277ba3a57cSBarry Smith 8287ba3a57cSBarry Smith Level: intermediate 8297ba3a57cSBarry Smith 830*811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 831*811af0c4SBarry Smith `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 8327ba3a57cSBarry Smith @*/ 8339371c9d4SSatish Balay PetscErrorCode PetscStrendswithwhich(const char a[], const char *const *bs, PetscInt *cnt) { 8347ba3a57cSBarry Smith PetscFunctionBegin; 8355f80ce2aSJacob Faibussowitsch PetscValidPointer(bs, 2); 8365f80ce2aSJacob Faibussowitsch PetscValidIntPointer(cnt, 3); 8377ba3a57cSBarry Smith *cnt = 0; 8387ba3a57cSBarry Smith while (bs[*cnt]) { 8395f80ce2aSJacob Faibussowitsch PetscBool flg; 8405f80ce2aSJacob Faibussowitsch 8419566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(a, bs[*cnt], &flg)); 8427ba3a57cSBarry Smith if (flg) PetscFunctionReturn(0); 8435f80ce2aSJacob Faibussowitsch ++(*cnt); 8447ba3a57cSBarry Smith } 8457ba3a57cSBarry Smith PetscFunctionReturn(0); 8467ba3a57cSBarry Smith } 8477ba3a57cSBarry Smith 8487ba3a57cSBarry Smith /*@C 849a5b23f4aSJose E. Roman PetscStrrstr - Locates last occurrence of string in another string 8507ba3a57cSBarry Smith 8517ba3a57cSBarry Smith Not Collective 8527ba3a57cSBarry Smith 8537ba3a57cSBarry Smith Input Parameters: 8547ba3a57cSBarry Smith + a - pointer to string 8557ba3a57cSBarry Smith - b - string to find 8567ba3a57cSBarry Smith 8577ba3a57cSBarry Smith Output Parameter: 858a5b23f4aSJose E. Roman . tmp - location of occurrence 8597ba3a57cSBarry Smith 860*811af0c4SBarry Smith Fortran Note: 86195452b02SPatrick Sanan Not for use in Fortran 8627ba3a57cSBarry Smith 8637ba3a57cSBarry Smith Level: intermediate 8647ba3a57cSBarry Smith 865*811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 866*811af0c4SBarry Smith `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 8677ba3a57cSBarry Smith @*/ 8689371c9d4SSatish Balay PetscErrorCode PetscStrrstr(const char a[], const char b[], char *tmp[]) { 8695f80ce2aSJacob Faibussowitsch const char *ltmp = NULL; 8707ba3a57cSBarry Smith 8717ba3a57cSBarry Smith PetscFunctionBegin; 8725f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 8735f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 2); 8745f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp, 3); 8755f80ce2aSJacob Faibussowitsch while (a) { 8765f80ce2aSJacob Faibussowitsch a = (char *)strstr(a, b); 8775f80ce2aSJacob Faibussowitsch if (a) ltmp = a++; 8787ba3a57cSBarry Smith } 8797ba3a57cSBarry Smith *tmp = (char *)ltmp; 8807ba3a57cSBarry Smith PetscFunctionReturn(0); 8817ba3a57cSBarry Smith } 8827ba3a57cSBarry Smith 8837ba3a57cSBarry Smith /*@C 884a5b23f4aSJose E. Roman PetscStrstr - Locates first occurrence of string in another string 8857ba3a57cSBarry Smith 8867ba3a57cSBarry Smith Not Collective 8877ba3a57cSBarry Smith 8887ba3a57cSBarry Smith Input Parameters: 889160f4796SJed Brown + haystack - string to search 890160f4796SJed Brown - needle - string to find 8917ba3a57cSBarry Smith 8927ba3a57cSBarry Smith Output Parameter: 893a5b23f4aSJose E. Roman . tmp - location of occurrence, is a NULL if the string is not found 8947ba3a57cSBarry Smith 895*811af0c4SBarry Smith Fortran Note: 89695452b02SPatrick Sanan Not for use in Fortran 8977ba3a57cSBarry Smith 8987ba3a57cSBarry Smith Level: intermediate 8997ba3a57cSBarry Smith 900*811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 901*811af0c4SBarry Smith `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 9027ba3a57cSBarry Smith @*/ 9039371c9d4SSatish Balay PetscErrorCode PetscStrstr(const char haystack[], const char needle[], char *tmp[]) { 9047ba3a57cSBarry Smith PetscFunctionBegin; 9055f80ce2aSJacob Faibussowitsch PetscValidCharPointer(haystack, 1); 9065f80ce2aSJacob Faibussowitsch PetscValidCharPointer(needle, 2); 9075f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp, 3); 908160f4796SJed Brown *tmp = (char *)strstr(haystack, needle); 9097ba3a57cSBarry Smith PetscFunctionReturn(0); 9107ba3a57cSBarry Smith } 9117ba3a57cSBarry Smith 9129371c9d4SSatish Balay struct _p_PetscToken { 9139371c9d4SSatish Balay char token; 9149371c9d4SSatish Balay char *array; 9159371c9d4SSatish Balay char *current; 9169371c9d4SSatish Balay }; 9171d1a0024SBarry Smith 918e5c89e4eSSatish Balay /*@C 919e5c89e4eSSatish Balay PetscTokenFind - Locates next "token" in a string 920e5c89e4eSSatish Balay 921e5c89e4eSSatish Balay Not Collective 922e5c89e4eSSatish Balay 923e5c89e4eSSatish Balay Input Parameters: 924e5c89e4eSSatish Balay . a - pointer to token 925e5c89e4eSSatish Balay 926e5c89e4eSSatish Balay Output Parameter: 927a5b23f4aSJose E. Roman . result - location of occurrence, NULL if not found 928e5c89e4eSSatish Balay 929e5c89e4eSSatish Balay Notes: 930e5c89e4eSSatish Balay This version is different from the system version in that 931e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 932e5c89e4eSSatish Balay 9334704e885SBarry Smith This version also treats all characters etc. inside a double quote " 9344704e885SBarry Smith as a single token. 9354704e885SBarry Smith 9363a9c465aSBarry 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 9373a9c465aSBarry Smith second will return a null terminated y 9383a9c465aSBarry Smith 9393a9c465aSBarry 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 9403a9c465aSBarry Smith 941*811af0c4SBarry Smith Fortran Note: 9426f013253SBarry Smith Not for use in Fortran 9436f013253SBarry Smith 944e5c89e4eSSatish Balay Level: intermediate 945e5c89e4eSSatish Balay 946db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenDestroy()` 947e5c89e4eSSatish Balay @*/ 9489371c9d4SSatish Balay PetscErrorCode PetscTokenFind(PetscToken a, char *result[]) { 9495f80ce2aSJacob Faibussowitsch char *ptr, token; 950e5c89e4eSSatish Balay 951e5c89e4eSSatish Balay PetscFunctionBegin; 9525f80ce2aSJacob Faibussowitsch PetscValidPointer(a, 1); 9535f80ce2aSJacob Faibussowitsch PetscValidPointer(result, 2); 9545f80ce2aSJacob Faibussowitsch *result = ptr = a->current; 9559371c9d4SSatish Balay if (ptr && !*ptr) { 9569371c9d4SSatish Balay *result = NULL; 9579371c9d4SSatish Balay PetscFunctionReturn(0); 9589371c9d4SSatish Balay } 9594704e885SBarry Smith token = a->token; 9609371c9d4SSatish Balay if (ptr && (*ptr == '"')) { 9619371c9d4SSatish Balay token = '"'; 9629371c9d4SSatish Balay (*result)++; 9639371c9d4SSatish Balay ptr++; 9649371c9d4SSatish Balay } 965e5c89e4eSSatish Balay while (ptr) { 9664704e885SBarry Smith if (*ptr == token) { 967e5c89e4eSSatish Balay *ptr++ = 0; 968e5c89e4eSSatish Balay while (*ptr == a->token) ptr++; 969e5c89e4eSSatish Balay a->current = ptr; 970e5c89e4eSSatish Balay break; 971e5c89e4eSSatish Balay } 972e5c89e4eSSatish Balay if (!*ptr) { 97302c9f0b5SLisandro Dalcin a->current = NULL; 974e5c89e4eSSatish Balay break; 975e5c89e4eSSatish Balay } 976e5c89e4eSSatish Balay ptr++; 977e5c89e4eSSatish Balay } 978e5c89e4eSSatish Balay PetscFunctionReturn(0); 979e5c89e4eSSatish Balay } 980e5c89e4eSSatish Balay 981e5c89e4eSSatish Balay /*@C 982*811af0c4SBarry Smith PetscTokenCreate - Creates a `PetscToken` used to find tokens in a string 983e5c89e4eSSatish Balay 984e5c89e4eSSatish Balay Not Collective 985e5c89e4eSSatish Balay 986e5c89e4eSSatish Balay Input Parameters: 987e5c89e4eSSatish Balay + string - the string to look in 9883a9c465aSBarry Smith - b - the separator character 989e5c89e4eSSatish Balay 990e5c89e4eSSatish Balay Output Parameter: 9913a9c465aSBarry Smith . t- the token object 992e5c89e4eSSatish Balay 993*811af0c4SBarry Smith Note: 994e5c89e4eSSatish Balay This version is different from the system version in that 995e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 996e5c89e4eSSatish Balay 997*811af0c4SBarry Smith Fortran Note: 9986f013253SBarry Smith Not for use in Fortran 9996f013253SBarry Smith 1000e5c89e4eSSatish Balay Level: intermediate 1001e5c89e4eSSatish Balay 1002db781477SPatrick Sanan .seealso: `PetscTokenFind()`, `PetscTokenDestroy()` 1003e5c89e4eSSatish Balay @*/ 10049371c9d4SSatish Balay PetscErrorCode PetscTokenCreate(const char a[], const char b, PetscToken *t) { 1005e5c89e4eSSatish Balay PetscFunctionBegin; 10065f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 10075f80ce2aSJacob Faibussowitsch PetscValidPointer(t, 3); 10089566063dSJacob Faibussowitsch PetscCall(PetscNew(t)); 10099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &(*t)->array)); 1010a297a907SKarl Rupp 1011e5c89e4eSSatish Balay (*t)->current = (*t)->array; 1012e5c89e4eSSatish Balay (*t)->token = b; 1013e5c89e4eSSatish Balay PetscFunctionReturn(0); 1014e5c89e4eSSatish Balay } 1015e5c89e4eSSatish Balay 1016e5c89e4eSSatish Balay /*@C 1017*811af0c4SBarry Smith PetscTokenDestroy - Destroys a `PetscToken` 1018e5c89e4eSSatish Balay 1019e5c89e4eSSatish Balay Not Collective 1020e5c89e4eSSatish Balay 1021e5c89e4eSSatish Balay Input Parameters: 1022e5c89e4eSSatish Balay . a - pointer to token 1023e5c89e4eSSatish Balay 1024e5c89e4eSSatish Balay Level: intermediate 1025e5c89e4eSSatish Balay 1026*811af0c4SBarry Smith Fortran Note: 102795452b02SPatrick Sanan Not for use in Fortran 10286f013253SBarry Smith 1029db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()` 1030e5c89e4eSSatish Balay @*/ 10319371c9d4SSatish Balay PetscErrorCode PetscTokenDestroy(PetscToken *a) { 1032e5c89e4eSSatish Balay PetscFunctionBegin; 10338c74ee41SBarry Smith if (!*a) PetscFunctionReturn(0); 10349566063dSJacob Faibussowitsch PetscCall(PetscFree((*a)->array)); 10359566063dSJacob Faibussowitsch PetscCall(PetscFree(*a)); 1036e5c89e4eSSatish Balay PetscFunctionReturn(0); 1037e5c89e4eSSatish Balay } 1038e5c89e4eSSatish Balay 10398e81d068SLisandro Dalcin /*@C 1040*811af0c4SBarry Smith PetscStrInList - search for string in character-delimited list 10418e81d068SLisandro Dalcin 10428e81d068SLisandro Dalcin Not Collective 10438e81d068SLisandro Dalcin 10448e81d068SLisandro Dalcin Input Parameters: 10458e81d068SLisandro Dalcin + str - the string to look for 10468e81d068SLisandro Dalcin . list - the list to search in 10478e81d068SLisandro Dalcin - sep - the separator character 10488e81d068SLisandro Dalcin 10498e81d068SLisandro Dalcin Output Parameter: 10508e81d068SLisandro Dalcin . found - whether str is in list 10518e81d068SLisandro Dalcin 10528e81d068SLisandro Dalcin Level: intermediate 10538e81d068SLisandro Dalcin 1054*811af0c4SBarry Smith Fortran Note: 105595452b02SPatrick Sanan Not for use in Fortran 10568e81d068SLisandro Dalcin 1057db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscStrcmp()` 10588e81d068SLisandro Dalcin @*/ 10599371c9d4SSatish Balay PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found) { 10608e81d068SLisandro Dalcin PetscToken token; 10618e81d068SLisandro Dalcin char *item; 10628e81d068SLisandro Dalcin 10638e81d068SLisandro Dalcin PetscFunctionBegin; 10645f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 4); 10658e81d068SLisandro Dalcin *found = PETSC_FALSE; 10669566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(list, sep, &token)); 10679566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 10688e81d068SLisandro Dalcin while (item) { 10699566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(str, item, found)); 10708e81d068SLisandro Dalcin if (*found) break; 10719566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 10728e81d068SLisandro Dalcin } 10739566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 10748e81d068SLisandro Dalcin PetscFunctionReturn(0); 10758e81d068SLisandro Dalcin } 1076e5c89e4eSSatish Balay 1077e5c89e4eSSatish Balay /*@C 1078e5c89e4eSSatish Balay PetscGetPetscDir - Gets the directory PETSc is installed in 1079e5c89e4eSSatish Balay 1080e5c89e4eSSatish Balay Not Collective 1081e5c89e4eSSatish Balay 1082e5c89e4eSSatish Balay Output Parameter: 1083e5c89e4eSSatish Balay . dir - the directory 1084e5c89e4eSSatish Balay 1085e5c89e4eSSatish Balay Level: developer 1086e5c89e4eSSatish Balay 1087*811af0c4SBarry Smith Fortran Note: 108895452b02SPatrick Sanan Not for use in Fortran 10896f013253SBarry Smith 1090e5c89e4eSSatish Balay @*/ 10919371c9d4SSatish Balay PetscErrorCode PetscGetPetscDir(const char *dir[]) { 1092e5c89e4eSSatish Balay PetscFunctionBegin; 10935f80ce2aSJacob Faibussowitsch PetscValidPointer(dir, 1); 1094e5c89e4eSSatish Balay *dir = PETSC_DIR; 1095e5c89e4eSSatish Balay PetscFunctionReturn(0); 1096e5c89e4eSSatish Balay } 1097e5c89e4eSSatish Balay 1098e5c89e4eSSatish Balay /*@C 1099e5c89e4eSSatish Balay PetscStrreplace - Replaces substrings in string with other substrings 1100e5c89e4eSSatish Balay 1101e5c89e4eSSatish Balay Not Collective 1102e5c89e4eSSatish Balay 1103e5c89e4eSSatish Balay Input Parameters: 1104*811af0c4SBarry Smith + comm - `MPI_Comm` of processors that are processing the string 110571573d7dSBarry Smith . aa - the string to look in 1106d8ccf1fbSBarry Smith . b - the resulting copy of a with replaced strings (b can be the same as a) 1107e5c89e4eSSatish Balay - len - the length of b 1108e5c89e4eSSatish Balay 1109e5c89e4eSSatish Balay Notes: 1110e5c89e4eSSatish Balay Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 1111d5649816SBarry Smith ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 1112e5c89e4eSSatish Balay as well as any environmental variables. 1113e5c89e4eSSatish Balay 1114*811af0c4SBarry Smith `PETSC_LIB_DIR` uses the environmental variable if it exists. `PETSC_ARCH` and `PETSC_DIR` use what 1115acc6cc86SBarry Smith PETSc was built with and do not use environmental variables. 1116acc6cc86SBarry Smith 1117*811af0c4SBarry Smith Fortran Note: 11186f013253SBarry Smith Not for use in Fortran 11196f013253SBarry Smith 1120*811af0c4SBarry Smith Level: developer 1121e5c89e4eSSatish Balay 1122e5c89e4eSSatish Balay @*/ 11239371c9d4SSatish Balay PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len) { 1124e5c89e4eSSatish Balay int i = 0; 1125e5c89e4eSSatish Balay size_t l, l1, l2, l3; 112671573d7dSBarry Smith char *work, *par, *epar, env[1024], *tfree, *a = (char *)aa; 112702c9f0b5SLisandro Dalcin const char *s[] = {"${PETSC_ARCH}", "${PETSC_DIR}", "${PETSC_LIB_DIR}", "${DISPLAY}", "${HOMEDIRECTORY}", "${WORKINGDIRECTORY}", "${USERNAME}", "${HOSTNAME}", NULL}; 112802c9f0b5SLisandro Dalcin char *r[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 1129ace3abfcSBarry Smith PetscBool flag; 1130589a23caSBarry Smith static size_t DISPLAY_LENGTH = 265, USER_LENGTH = 256, HOST_LENGTH = 256; 1131e5c89e4eSSatish Balay 1132e5c89e4eSSatish Balay PetscFunctionBegin; 11335f80ce2aSJacob Faibussowitsch PetscValidCharPointer(aa, 2); 11345f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 3); 11359566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscStrallocpy(aa, (char **)&a)); 11369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len, &work)); 1137e5c89e4eSSatish Balay 1138e5c89e4eSSatish Balay /* get values for replaced variables */ 11399566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_ARCH, &r[0])); 11409566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_DIR, &r[1])); 11419566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_LIB_DIR, &r[2])); 11429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(DISPLAY_LENGTH, &r[3])); 11439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[4])); 11449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[5])); 11459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(USER_LENGTH, &r[6])); 11469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(HOST_LENGTH, &r[7])); 11479566063dSJacob Faibussowitsch PetscCall(PetscGetDisplay(r[3], DISPLAY_LENGTH)); 11489566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(r[4], PETSC_MAX_PATH_LEN)); 11499566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(r[5], PETSC_MAX_PATH_LEN)); 11509566063dSJacob Faibussowitsch PetscCall(PetscGetUserName(r[6], USER_LENGTH)); 11519566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(r[7], HOST_LENGTH)); 1152487e5849SBarry Smith 1153487e5849SBarry Smith /* replace that are in environment */ 11549566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_LIB_DIR", env, sizeof(env), &flag)); 1155487e5849SBarry Smith if (flag) { 11569566063dSJacob Faibussowitsch PetscCall(PetscFree(r[2])); 11579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(env, &r[2])); 1158487e5849SBarry Smith } 1159e5c89e4eSSatish Balay 1160e5c89e4eSSatish Balay /* replace the requested strings */ 11619566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, a, len)); 1162e5c89e4eSSatish Balay while (s[i]) { 11639566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s[i], &l)); 11649566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 1165e5c89e4eSSatish Balay while (par) { 1166e5c89e4eSSatish Balay *par = 0; 1167e5c89e4eSSatish Balay par += l; 1168e5c89e4eSSatish Balay 11699566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b, &l1)); 11709566063dSJacob Faibussowitsch PetscCall(PetscStrlen(r[i], &l2)); 11719566063dSJacob Faibussowitsch PetscCall(PetscStrlen(par, &l3)); 1172cc73adaaSBarry Smith PetscCheck(l1 + l2 + l3 < len, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "b len is not long enough to hold new values"); 11739566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 11749566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, r[i], len)); 11759566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, par, len)); 11769566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 11779566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 1178e5c89e4eSSatish Balay } 1179e5c89e4eSSatish Balay i++; 1180e5c89e4eSSatish Balay } 1181487e5849SBarry Smith i = 0; 1182487e5849SBarry Smith while (r[i]) { 1183e5c89e4eSSatish Balay tfree = (char *)r[i]; 11849566063dSJacob Faibussowitsch PetscCall(PetscFree(tfree)); 1185487e5849SBarry Smith i++; 1186e5c89e4eSSatish Balay } 1187e5c89e4eSSatish Balay 1188e5c89e4eSSatish Balay /* look for any other ${xxx} strings to replace from environmental variables */ 11899566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 1190e5c89e4eSSatish Balay while (par) { 1191e5c89e4eSSatish Balay *par = 0; 1192e5c89e4eSSatish Balay par += 2; 11939566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 11949566063dSJacob Faibussowitsch PetscCall(PetscStrstr(par, "}", &epar)); 1195e5c89e4eSSatish Balay *epar = 0; 1196e5c89e4eSSatish Balay epar += 1; 11979566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, par, env, sizeof(env), &flag)); 119828b400f6SJacob Faibussowitsch PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Substitution string ${%s} not found as environmental variable", par); 11999566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, env, len)); 12009566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, epar, len)); 12019566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 12029566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 1203e5c89e4eSSatish Balay } 12049566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 12059566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscFree(a)); 1206e5c89e4eSSatish Balay PetscFunctionReturn(0); 1207e5c89e4eSSatish Balay } 1208e5c89e4eSSatish Balay 1209a53986e1SJed Brown /*@C 1210a53986e1SJed Brown PetscEListFind - searches list of strings for given string, using case insensitive matching 1211e5c89e4eSSatish Balay 1212a53986e1SJed Brown Not Collective 1213a53986e1SJed Brown 1214a53986e1SJed Brown Input Parameters: 1215a53986e1SJed Brown + n - number of strings in 1216a53986e1SJed Brown . list - list of strings to search 1217a53986e1SJed Brown - str - string to look for, empty string "" accepts default (first entry in list) 1218a53986e1SJed Brown 1219a53986e1SJed Brown Output Parameters: 1220a53986e1SJed Brown + value - index of matching string (if found) 1221a53986e1SJed Brown - found - boolean indicating whether string was found (can be NULL) 1222a53986e1SJed Brown 1223*811af0c4SBarry Smith Fortran Note: 1224a53986e1SJed Brown Not for use in Fortran 1225a53986e1SJed Brown 1226a53986e1SJed Brown Level: advanced 1227*811af0c4SBarry Smith 1228*811af0c4SBarry Smith .seealso: `PetscEnumFind()` 1229a53986e1SJed Brown @*/ 12309371c9d4SSatish Balay PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found) { 1231a53986e1SJed Brown PetscFunctionBegin; 12325f80ce2aSJacob Faibussowitsch if (found) { 12335f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 5); 12345f80ce2aSJacob Faibussowitsch *found = PETSC_FALSE; 12355f80ce2aSJacob Faibussowitsch } 12365f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 12375f80ce2aSJacob Faibussowitsch PetscBool matched; 12385f80ce2aSJacob Faibussowitsch 12399566063dSJacob Faibussowitsch PetscCall(PetscStrcasecmp(str, list[i], &matched)); 1240a53986e1SJed Brown if (matched || !str[0]) { 1241a53986e1SJed Brown if (found) *found = PETSC_TRUE; 1242a53986e1SJed Brown *value = i; 1243a53986e1SJed Brown break; 1244a53986e1SJed Brown } 1245a53986e1SJed Brown } 1246a53986e1SJed Brown PetscFunctionReturn(0); 1247a53986e1SJed Brown } 1248a53986e1SJed Brown 1249a53986e1SJed Brown /*@C 12508e81d068SLisandro Dalcin PetscEnumFind - searches enum list of strings for given string, using case insensitive matching 1251a53986e1SJed Brown 1252a53986e1SJed Brown Not Collective 1253a53986e1SJed Brown 1254a53986e1SJed Brown Input Parameters: 1255a53986e1SJed Brown + enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL 1256a53986e1SJed Brown - str - string to look for 1257a53986e1SJed Brown 1258a53986e1SJed Brown Output Parameters: 1259a53986e1SJed Brown + value - index of matching string (if found) 1260a53986e1SJed Brown - found - boolean indicating whether string was found (can be NULL) 1261a53986e1SJed Brown 1262*811af0c4SBarry Smith Fortran Note: 1263a53986e1SJed Brown Not for use in Fortran 1264a53986e1SJed Brown 1265a53986e1SJed Brown Level: advanced 1266*811af0c4SBarry Smith 1267*811af0c4SBarry Smith .seealso: `PetscEListFind()` 1268a53986e1SJed Brown @*/ 12699371c9d4SSatish Balay PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found) { 1270d05ba7d2SLisandro Dalcin PetscInt n = 0, evalue; 1271a53986e1SJed Brown PetscBool efound; 1272a53986e1SJed Brown 1273a53986e1SJed Brown PetscFunctionBegin; 12745f80ce2aSJacob Faibussowitsch PetscValidPointer(enumlist, 1); 12755f80ce2aSJacob 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"); 12765f80ce2aSJacob Faibussowitsch PetscCheck(n >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix"); 1277a53986e1SJed Brown n -= 3; /* drop enum name, prefix, and null termination */ 12789566063dSJacob Faibussowitsch PetscCall(PetscEListFind(n, enumlist, str, &evalue, &efound)); 12795f80ce2aSJacob Faibussowitsch if (efound) { 12805f80ce2aSJacob Faibussowitsch PetscValidPointer(value, 3); 12815f80ce2aSJacob Faibussowitsch *value = (PetscEnum)evalue; 12825f80ce2aSJacob Faibussowitsch } 12835f80ce2aSJacob Faibussowitsch if (found) { 12845f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 4); 12855f80ce2aSJacob Faibussowitsch *found = efound; 12865f80ce2aSJacob Faibussowitsch } 1287a53986e1SJed Brown PetscFunctionReturn(0); 1288a53986e1SJed Brown } 1289660278c0SBarry Smith 1290660278c0SBarry Smith /*@C 1291660278c0SBarry Smith PetscCIFilename - returns the basename of a file name when the PETSc CI portable error output mode is enabled. 1292660278c0SBarry Smith 1293660278c0SBarry Smith Not collective 1294660278c0SBarry Smith 1295660278c0SBarry Smith Input Parameter: 1296660278c0SBarry Smith . file - the file name 1297660278c0SBarry Smith 1298660278c0SBarry Smith Note: 1299660278c0SBarry Smith PETSc CI mode is a mode of running PETSc where output (both error and non-error) is made portable across all systems 1300660278c0SBarry Smith so that comparisons of output between runs are easy to make. 1301660278c0SBarry Smith 1302660278c0SBarry Smith This mode is used for all tests in the test harness, it applies to both debug and optimized builds. 1303660278c0SBarry Smith 1304660278c0SBarry Smith Use the option -petsc_ci to turn on PETSc CI mode. It changes certain output in non-error situations to be portable for 1305660278c0SBarry Smith all systems, mainly the output of options. It is passed to all PETSc programs automatically by the test harness. 1306660278c0SBarry Smith 1307660278c0SBarry Smith Always uses the Unix / as the file separate even on Microsoft Windows systems 1308660278c0SBarry Smith 1309660278c0SBarry Smith The option -petsc_ci_portable_error_output attempts to output the same error messages on all systems for the test harness. 1310660278c0SBarry Smith In particular the output of filenames and line numbers in PETSc stacks. This is to allow (limited) checking of PETSc 1311660278c0SBarry 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 1312660278c0SBarry Smith harness can process the output for differences in the usual manner as for successful runs. It should be provided to the test 1313660278c0SBarry Smith harness in the args: argument for specific examples. It will not neccessarily produce portable output if different errors 1314660278c0SBarry Smith (or no errors) occur on a subset of the MPI ranks. 1315660278c0SBarry Smith 1316660278c0SBarry Smith Level: developer 1317660278c0SBarry Smith 1318660278c0SBarry Smith .seealso: `PetscCILinenumber()` 1319660278c0SBarry Smith @*/ 13209371c9d4SSatish Balay const char *PetscCIFilename(const char *file) { 1321660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return file; 1322660278c0SBarry Smith return PetscBasename(file); 1323660278c0SBarry Smith } 1324660278c0SBarry Smith 1325660278c0SBarry Smith /*@C 1326*811af0c4SBarry Smith PetscCILinenumber - returns a line number except if `PetscCIEnablePortableErrorOutput` is set when it returns 0 1327660278c0SBarry Smith 1328660278c0SBarry Smith Not collective 1329660278c0SBarry Smith 1330660278c0SBarry Smith Input Parameter: 1331660278c0SBarry Smith . linenumber - the initial line number 1332660278c0SBarry Smith 1333660278c0SBarry Smith Note: 1334660278c0SBarry Smith See `PetscCIFilename()` for details on usage 1335660278c0SBarry Smith 1336660278c0SBarry Smith Level: developer 1337660278c0SBarry Smith 1338660278c0SBarry Smith .seealso: `PetscCIFilename()` 1339660278c0SBarry Smith @*/ 13409371c9d4SSatish Balay int PetscCILinenumber(int linenumber) { 1341660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return linenumber; 1342660278c0SBarry Smith return 0; 1343660278c0SBarry Smith } 1344