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 */ 65f80ce2aSJacob Faibussowitsch #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 73964eb88SJed Brown #if defined(PETSC_HAVE_STRINGS_H) 83964eb88SJed Brown #include <strings.h> /* strcasecmp */ 93964eb88SJed Brown #endif 103964eb88SJed Brown 113c311c98SBarry Smith /*@C 1251a1f156SVaclav Hapla PetscStrToArray - Separates a string by a character (for example ' ' or '\n') and creates an array of strings 133c311c98SBarry Smith 14667f096bSBarry Smith Not Collective; No Fortran Support 153c311c98SBarry Smith 163c311c98SBarry Smith Input Parameters: 17d67fe73bSBarry Smith + s - pointer to string 1851a1f156SVaclav Hapla - sp - separator character 193c311c98SBarry Smith 20d8d19677SJose E. Roman Output Parameters: 213c311c98SBarry Smith + argc - the number of entries in the array 22667f096bSBarry Smith - args - an array of the entries with a `NULL` at the end 233c311c98SBarry Smith 243c311c98SBarry Smith Level: intermediate 253c311c98SBarry Smith 26811af0c4SBarry Smith Note: 27667f096bSBarry Smith This may be called before `PetscInitialize()` or after `PetscFinalize()` 286f013253SBarry Smith 2995452b02SPatrick Sanan Developer Notes: 30811af0c4SBarry Smith Uses raw `malloc()` and does not call error handlers since this may be used before PETSc is initialized. 31811af0c4SBarry Smith 32811af0c4SBarry Smith Used to generate argc, args arguments passed to `MPI_Init()` 33301d30feSBarry Smith 34db781477SPatrick Sanan .seealso: `PetscStrToArrayDestroy()`, `PetscToken`, `PetscTokenCreate()` 353c311c98SBarry Smith @*/ 36d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrToArray(const char s[], char sp, int *argc, char ***args) 37d71ae5a4SJacob Faibussowitsch { 38c3bcdc7eSBarry Smith int i, j, n, *lens, cnt = 0; 39ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 403c311c98SBarry Smith 4140a7e1efSBarry Smith if (!s) n = 0; 4240a7e1efSBarry Smith else n = strlen(s); 433c311c98SBarry Smith *argc = 0; 4461528463SBarry Smith *args = NULL; 45acf7dc08SSatish Balay for (; n > 0; n--) { /* remove separator chars at the end - and will empty the string if all chars are separator chars */ 46acf7dc08SSatish Balay if (s[n - 1] != sp) break; 47acf7dc08SSatish Balay } 483ba16761SJacob Faibussowitsch if (!n) return PETSC_SUCCESS; 493c311c98SBarry Smith for (i = 0; i < n; i++) { 50d67fe73bSBarry Smith if (s[i] != sp) break; 513c311c98SBarry Smith } 523c311c98SBarry Smith for (; i < n + 1; i++) { 539371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 549371c9d4SSatish Balay flg = PETSC_TRUE; 559371c9d4SSatish Balay (*argc)++; 569371c9d4SSatish Balay } else if (s[i] != sp) { 579371c9d4SSatish Balay flg = PETSC_FALSE; 583c311c98SBarry Smith } 599371c9d4SSatish Balay } 609371c9d4SSatish Balay (*args) = (char **)malloc(((*argc) + 1) * sizeof(char *)); 619371c9d4SSatish Balay if (!*args) return PETSC_ERR_MEM; 629371c9d4SSatish Balay lens = (int *)malloc((*argc) * sizeof(int)); 639371c9d4SSatish Balay if (!lens) return PETSC_ERR_MEM; 643c311c98SBarry Smith for (i = 0; i < *argc; i++) lens[i] = 0; 653c311c98SBarry Smith 663c311c98SBarry Smith *argc = 0; 673c311c98SBarry Smith for (i = 0; i < n; i++) { 68d67fe73bSBarry Smith if (s[i] != sp) break; 693c311c98SBarry Smith } 707dd9f305SSatish Balay for (; i < n + 1; i++) { 719371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 729371c9d4SSatish Balay flg = PETSC_TRUE; 739371c9d4SSatish Balay (*argc)++; 749371c9d4SSatish Balay } else if (s[i] != sp) { 759371c9d4SSatish Balay lens[*argc]++; 769371c9d4SSatish Balay flg = PETSC_FALSE; 779371c9d4SSatish Balay } 783c311c98SBarry Smith } 793c311c98SBarry Smith 803c311c98SBarry Smith for (i = 0; i < *argc; i++) { 81c3bcdc7eSBarry Smith (*args)[i] = (char *)malloc((lens[i] + 1) * sizeof(char)); 82c3bcdc7eSBarry Smith if (!(*args)[i]) { 83c3bcdc7eSBarry Smith free(lens); 84c3bcdc7eSBarry Smith for (j = 0; j < i; j++) free((*args)[j]); 85c3bcdc7eSBarry Smith free(*args); 86c3bcdc7eSBarry Smith return PETSC_ERR_MEM; 87c3bcdc7eSBarry Smith } 883c311c98SBarry Smith } 89a2ea699eSBarry Smith free(lens); 9002c9f0b5SLisandro Dalcin (*args)[*argc] = NULL; 913c311c98SBarry Smith 923c311c98SBarry Smith *argc = 0; 933c311c98SBarry Smith for (i = 0; i < n; i++) { 94d67fe73bSBarry Smith if (s[i] != sp) break; 953c311c98SBarry Smith } 963c311c98SBarry Smith for (; i < n + 1; i++) { 979371c9d4SSatish Balay if ((s[i] == sp || s[i] == 0) && !flg) { 989371c9d4SSatish Balay flg = PETSC_TRUE; 999371c9d4SSatish Balay (*args)[*argc][cnt++] = 0; 1009371c9d4SSatish Balay (*argc)++; 1019371c9d4SSatish Balay cnt = 0; 1029371c9d4SSatish Balay } else if (s[i] != sp && s[i] != 0) { 1039371c9d4SSatish Balay (*args)[*argc][cnt++] = s[i]; 1049371c9d4SSatish Balay flg = PETSC_FALSE; 1059371c9d4SSatish Balay } 1063c311c98SBarry Smith } 1073ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 1083c311c98SBarry Smith } 1093c311c98SBarry Smith 110301d30feSBarry Smith /*@C 111811af0c4SBarry Smith PetscStrToArrayDestroy - Frees array created with `PetscStrToArray()`. 112301d30feSBarry Smith 113667f096bSBarry Smith Not Collective; No Fortran Support 114301d30feSBarry Smith 115301d30feSBarry Smith Output Parameters: 116301d30feSBarry Smith + argc - the number of arguments 117301d30feSBarry Smith - args - the array of arguments 118301d30feSBarry Smith 119301d30feSBarry Smith Level: intermediate 120301d30feSBarry Smith 121811af0c4SBarry Smith Note: 122811af0c4SBarry Smith This may be called before `PetscInitialize()` or after `PetscFinalize()` 123301d30feSBarry Smith 124db781477SPatrick Sanan .seealso: `PetscStrToArray()` 125301d30feSBarry Smith @*/ 126d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrToArrayDestroy(int argc, char **args) 127d71ae5a4SJacob Faibussowitsch { 1285f80ce2aSJacob Faibussowitsch for (int i = 0; i < argc; ++i) free(args[i]); 129a297a907SKarl Rupp if (args) free(args); 1303ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 131301d30feSBarry Smith } 132301d30feSBarry Smith 133e5c89e4eSSatish Balay /*@C 13447340559SBarry Smith PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 13547340559SBarry Smith 136667f096bSBarry Smith Not Collective; No Fortran Support 13747340559SBarry Smith 1382fe279fdSBarry Smith Input Parameter: 139*aec76313SJacob Faibussowitsch . list - pointer to array of strings (final string is a `NULL`) 14047340559SBarry Smith 14147340559SBarry Smith Output Parameter: 14247340559SBarry Smith . t - the copied array string 14347340559SBarry Smith 14447340559SBarry Smith Level: intermediate 14547340559SBarry Smith 14647340559SBarry Smith Note: 147667f096bSBarry Smith If `t` has previously been allocated then that memory is lost, you may need to `PetscStrArrayDestroy()` 1480ecf5a55SBarry Smith the array before calling this routine. 1490ecf5a55SBarry Smith 150811af0c4SBarry Smith .seealso: `PetscStrallocpy()`, `PetscStrArrayDestroy()`, `PetscStrNArrayallocpy()` 15147340559SBarry Smith @*/ 152d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrArrayallocpy(const char *const *list, char ***t) 153d71ae5a4SJacob Faibussowitsch { 1545f80ce2aSJacob Faibussowitsch PetscInt n = 0; 15547340559SBarry Smith 15647340559SBarry Smith PetscFunctionBegin; 1579371c9d4SSatish Balay while (list[n++]) 1589371c9d4SSatish Balay ; 1599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n + 1, t)); 1609566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 1610298fd71SBarry Smith (*t)[n] = NULL; 1623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16347340559SBarry Smith } 16447340559SBarry Smith 16547340559SBarry Smith /*@C 166811af0c4SBarry Smith PetscStrArrayDestroy - Frees array of strings created with `PetscStrArrayallocpy()`. 16747340559SBarry Smith 168667f096bSBarry Smith Not Collective; No Fortran Support 16947340559SBarry Smith 1702fe279fdSBarry Smith Output Parameter: 17147340559SBarry Smith . list - array of strings 17247340559SBarry Smith 17347340559SBarry Smith Level: intermediate 17447340559SBarry Smith 175db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()` 17647340559SBarry Smith @*/ 177d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrArrayDestroy(char ***list) 178d71ae5a4SJacob Faibussowitsch { 17947340559SBarry Smith PetscInt n = 0; 18047340559SBarry Smith 1816fed8037SJed Brown PetscFunctionBegin; 1823ba16761SJacob Faibussowitsch if (!*list) PetscFunctionReturn(PETSC_SUCCESS); 1836fed8037SJed Brown while ((*list)[n]) { 1849566063dSJacob Faibussowitsch PetscCall(PetscFree((*list)[n])); 1855f80ce2aSJacob Faibussowitsch ++n; 18647340559SBarry Smith } 1879566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 1883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18947340559SBarry Smith } 19047340559SBarry Smith 1916991f827SBarry Smith /*@C 1926991f827SBarry Smith PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 1936991f827SBarry Smith 194667f096bSBarry Smith Not Collective; No Fortran Support 1956991f827SBarry Smith 1966991f827SBarry Smith Input Parameters: 1976991f827SBarry Smith + n - the number of string entries 198*aec76313SJacob Faibussowitsch - list - pointer to array of strings 1996991f827SBarry Smith 2006991f827SBarry Smith Output Parameter: 2016991f827SBarry Smith . t - the copied array string 2026991f827SBarry Smith 2036991f827SBarry Smith Level: intermediate 2046991f827SBarry Smith 205db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayallocpy()`, `PetscStrNArrayDestroy()` 2066991f827SBarry Smith @*/ 207d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrNArrayallocpy(PetscInt n, const char *const *list, char ***t) 208d71ae5a4SJacob Faibussowitsch { 2096991f827SBarry Smith PetscFunctionBegin; 2109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, t)); 2119566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 2123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2136991f827SBarry Smith } 2146991f827SBarry Smith 2156991f827SBarry Smith /*@C 216811af0c4SBarry Smith PetscStrNArrayDestroy - Frees array of strings created with `PetscStrNArrayallocpy()`. 2176991f827SBarry Smith 218667f096bSBarry Smith Not Collective; No Fortran Support 2196991f827SBarry Smith 2206991f827SBarry Smith Output Parameters: 2216991f827SBarry Smith + n - number of string entries 2226991f827SBarry Smith - list - array of strings 2236991f827SBarry Smith 2246991f827SBarry Smith Level: intermediate 2256991f827SBarry Smith 226811af0c4SBarry Smith .seealso: `PetscStrNArrayallocpy()`, `PetscStrArrayallocpy()` 2276991f827SBarry Smith @*/ 228d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrNArrayDestroy(PetscInt n, char ***list) 229d71ae5a4SJacob Faibussowitsch { 2306991f827SBarry Smith PetscFunctionBegin; 2313ba16761SJacob Faibussowitsch if (!*list) PetscFunctionReturn(PETSC_SUCCESS); 2329566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscFree((*list)[i])); 2339566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 2343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2356991f827SBarry Smith } 2366991f827SBarry Smith 237e5c89e4eSSatish Balay /*@C 238811af0c4SBarry Smith PetscBasename - returns a pointer to the last entry of a / or \ separated directory path 23980b92c66SBarry Smith 240667f096bSBarry Smith Not Collective; No Fortran Support 24180b92c66SBarry Smith 24280b92c66SBarry Smith Input Parameter: 24380b92c66SBarry Smith . a - pointer to string 24480b92c66SBarry Smith 24580b92c66SBarry Smith Level: intermediate 24680b92c66SBarry Smith 24780b92c66SBarry Smith .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`, `PetscStrrchr()`, `PetscStrcmp()`, `PetscStrstr()`, 24880b92c66SBarry Smith `PetscTokenCreate()`, `PetscStrToArray()`, `PetscStrInList()` 24980b92c66SBarry Smith @*/ 250d71ae5a4SJacob Faibussowitsch const char *PetscBasename(const char a[]) 251d71ae5a4SJacob Faibussowitsch { 252bbcf679cSJacob Faibussowitsch const char *ptr = NULL; 25380b92c66SBarry Smith 254bbcf679cSJacob Faibussowitsch (void)PetscStrrchr(a, '/', (char **)&ptr); 255660278c0SBarry Smith if (ptr == a) { 256660278c0SBarry Smith if (PetscStrrchr(a, '\\', (char **)&ptr)) ptr = NULL; 257660278c0SBarry Smith } 25880b92c66SBarry Smith return ptr; 25980b92c66SBarry Smith } 26080b92c66SBarry Smith 26180b92c66SBarry Smith /*@C 262e5c89e4eSSatish Balay PetscStrcasecmp - Returns true if the two strings are the same 263e5c89e4eSSatish Balay except possibly for case. 264e5c89e4eSSatish Balay 265667f096bSBarry Smith Not Collective; No Fortran Support 266e5c89e4eSSatish Balay 267e5c89e4eSSatish Balay Input Parameters: 268e5c89e4eSSatish Balay + a - pointer to first string 269e5c89e4eSSatish Balay - b - pointer to second string 270e5c89e4eSSatish Balay 271e5c89e4eSSatish Balay Output Parameter: 272*aec76313SJacob Faibussowitsch . t - if the two strings are the same 273e5c89e4eSSatish Balay 274e5c89e4eSSatish Balay Level: intermediate 275e5c89e4eSSatish Balay 276667f096bSBarry Smith Note: 277667f096bSBarry Smith `NULL` arguments are ok 278667f096bSBarry Smith 279db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrgrt()` 280e5c89e4eSSatish Balay @*/ 281d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrcasecmp(const char a[], const char b[], PetscBool *t) 282d71ae5a4SJacob Faibussowitsch { 283e5c89e4eSSatish Balay int c; 284e5c89e4eSSatish Balay 285e5c89e4eSSatish Balay PetscFunctionBegin; 2865f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t, 3); 287e5c89e4eSSatish Balay if (!a && !b) c = 0; 288e5c89e4eSSatish Balay else if (!a || !b) c = 1; 28932b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP) 29032b366c8SSatish Balay else c = strcasecmp(a, b); 29132b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP) 292e5c89e4eSSatish Balay else c = stricmp(a, b); 293e5c89e4eSSatish Balay #else 29432b366c8SSatish Balay else { 29532b366c8SSatish Balay char *aa, *bb; 296bbcf679cSJacob Faibussowitsch 2979566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &aa)); 2989566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(b, &bb)); 2999566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(aa)); 3009566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(bb)); 3019566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(aa, bb, t)); 3029566063dSJacob Faibussowitsch PetscCall(PetscFree(aa)); 3039566063dSJacob Faibussowitsch PetscCall(PetscFree(bb)); 3043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30532b366c8SSatish Balay } 306e5c89e4eSSatish Balay #endif 3075f80ce2aSJacob Faibussowitsch *t = c ? PETSC_FALSE : PETSC_TRUE; 3083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 309e5c89e4eSSatish Balay } 310e5c89e4eSSatish Balay 311e5c89e4eSSatish Balay /*@C 3127ba3a57cSBarry Smith PetscStrendswithwhich - Determines if a string ends with one of several possible strings 3137ba3a57cSBarry Smith 314667f096bSBarry Smith Not Collective; No Fortran Support 3157ba3a57cSBarry Smith 3167ba3a57cSBarry Smith Input Parameters: 3177ba3a57cSBarry Smith + a - pointer to string 318667f096bSBarry Smith - bs - strings to end with (last entry must be `NULL`) 3197ba3a57cSBarry Smith 3207ba3a57cSBarry Smith Output Parameter: 321667f096bSBarry Smith . cnt - the index of the string it ends with or the index of `NULL` 3227ba3a57cSBarry Smith 3237ba3a57cSBarry Smith Level: intermediate 3247ba3a57cSBarry Smith 325811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 326*aec76313SJacob Faibussowitsch `PetscStrncmp()`, `PetscStrlen()`, `PetscStrcmp()` 3277ba3a57cSBarry Smith @*/ 328d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrendswithwhich(const char a[], const char *const *bs, PetscInt *cnt) 329d71ae5a4SJacob Faibussowitsch { 3307ba3a57cSBarry Smith PetscFunctionBegin; 3315f80ce2aSJacob Faibussowitsch PetscValidPointer(bs, 2); 3325f80ce2aSJacob Faibussowitsch PetscValidIntPointer(cnt, 3); 3337ba3a57cSBarry Smith *cnt = 0; 3347ba3a57cSBarry Smith while (bs[*cnt]) { 3355f80ce2aSJacob Faibussowitsch PetscBool flg; 3365f80ce2aSJacob Faibussowitsch 3379566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(a, bs[*cnt], &flg)); 3383ba16761SJacob Faibussowitsch if (flg) PetscFunctionReturn(PETSC_SUCCESS); 3395f80ce2aSJacob Faibussowitsch ++(*cnt); 3407ba3a57cSBarry Smith } 3413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3427ba3a57cSBarry Smith } 3437ba3a57cSBarry Smith 3449371c9d4SSatish Balay struct _p_PetscToken { 3459371c9d4SSatish Balay char token; 3469371c9d4SSatish Balay char *array; 3479371c9d4SSatish Balay char *current; 3489371c9d4SSatish Balay }; 3491d1a0024SBarry Smith 350e5c89e4eSSatish Balay /*@C 351667f096bSBarry Smith PetscTokenFind - Locates next "token" in a `PetscToken` 352e5c89e4eSSatish Balay 353667f096bSBarry Smith Not Collective; No Fortran Support 354e5c89e4eSSatish Balay 3552fe279fdSBarry Smith Input Parameter: 356e5c89e4eSSatish Balay . a - pointer to token 357e5c89e4eSSatish Balay 358e5c89e4eSSatish Balay Output Parameter: 359667f096bSBarry Smith . result - location of occurrence, `NULL` if not found 3606f013253SBarry Smith 361e5c89e4eSSatish Balay Level: intermediate 362e5c89e4eSSatish Balay 363667f096bSBarry Smith Notes: 364667f096bSBarry Smith Treats all characters etc. inside a double quote " 365667f096bSBarry Smith as a single token. 366667f096bSBarry Smith 367667f096bSBarry 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 368667f096bSBarry Smith second will return a `NULL` terminated y 369667f096bSBarry Smith 370667f096bSBarry 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 371667f096bSBarry Smith 372667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenCreate()`, `PetscTokenDestroy()` 373e5c89e4eSSatish Balay @*/ 374d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenFind(PetscToken a, char *result[]) 375d71ae5a4SJacob Faibussowitsch { 3765f80ce2aSJacob Faibussowitsch char *ptr, token; 377e5c89e4eSSatish Balay 378e5c89e4eSSatish Balay PetscFunctionBegin; 3795f80ce2aSJacob Faibussowitsch PetscValidPointer(a, 1); 3805f80ce2aSJacob Faibussowitsch PetscValidPointer(result, 2); 3815f80ce2aSJacob Faibussowitsch *result = ptr = a->current; 3829371c9d4SSatish Balay if (ptr && !*ptr) { 3839371c9d4SSatish Balay *result = NULL; 3843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3859371c9d4SSatish Balay } 3864704e885SBarry Smith token = a->token; 3879371c9d4SSatish Balay if (ptr && (*ptr == '"')) { 3889371c9d4SSatish Balay token = '"'; 3899371c9d4SSatish Balay (*result)++; 3909371c9d4SSatish Balay ptr++; 3919371c9d4SSatish Balay } 392e5c89e4eSSatish Balay while (ptr) { 3934704e885SBarry Smith if (*ptr == token) { 394e5c89e4eSSatish Balay *ptr++ = 0; 395e5c89e4eSSatish Balay while (*ptr == a->token) ptr++; 396e5c89e4eSSatish Balay a->current = ptr; 397e5c89e4eSSatish Balay break; 398e5c89e4eSSatish Balay } 399e5c89e4eSSatish Balay if (!*ptr) { 40002c9f0b5SLisandro Dalcin a->current = NULL; 401e5c89e4eSSatish Balay break; 402e5c89e4eSSatish Balay } 403e5c89e4eSSatish Balay ptr++; 404e5c89e4eSSatish Balay } 4053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 406e5c89e4eSSatish Balay } 407e5c89e4eSSatish Balay 408e5c89e4eSSatish Balay /*@C 409811af0c4SBarry Smith PetscTokenCreate - Creates a `PetscToken` used to find tokens in a string 410e5c89e4eSSatish Balay 411667f096bSBarry Smith Not Collective; No Fortran Support 412e5c89e4eSSatish Balay 413e5c89e4eSSatish Balay Input Parameters: 414*aec76313SJacob Faibussowitsch + a - the string to look in 4153a9c465aSBarry Smith - b - the separator character 416e5c89e4eSSatish Balay 417e5c89e4eSSatish Balay Output Parameter: 4183a9c465aSBarry Smith . t - the token object 419e5c89e4eSSatish Balay 420667f096bSBarry Smith Level: intermediate 421667f096bSBarry Smith 422811af0c4SBarry Smith Note: 423e5c89e4eSSatish Balay This version is different from the system version in that 424e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 425e5c89e4eSSatish Balay 426667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenFind()`, `PetscTokenDestroy()` 427e5c89e4eSSatish Balay @*/ 42898e514b7SJacob Faibussowitsch PetscErrorCode PetscTokenCreate(const char a[], char b, PetscToken *t) 429d71ae5a4SJacob Faibussowitsch { 430e5c89e4eSSatish Balay PetscFunctionBegin; 4315f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a, 1); 4325f80ce2aSJacob Faibussowitsch PetscValidPointer(t, 3); 4339566063dSJacob Faibussowitsch PetscCall(PetscNew(t)); 4349566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &(*t)->array)); 435a297a907SKarl Rupp 436e5c89e4eSSatish Balay (*t)->current = (*t)->array; 437e5c89e4eSSatish Balay (*t)->token = b; 4383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 439e5c89e4eSSatish Balay } 440e5c89e4eSSatish Balay 441e5c89e4eSSatish Balay /*@C 442811af0c4SBarry Smith PetscTokenDestroy - Destroys a `PetscToken` 443e5c89e4eSSatish Balay 444667f096bSBarry Smith Not Collective; No Fortran Support 445e5c89e4eSSatish Balay 4462fe279fdSBarry Smith Input Parameter: 447e5c89e4eSSatish Balay . a - pointer to token 448e5c89e4eSSatish Balay 449e5c89e4eSSatish Balay Level: intermediate 450e5c89e4eSSatish Balay 451667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenCreate()`, `PetscTokenFind()` 452e5c89e4eSSatish Balay @*/ 453d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenDestroy(PetscToken *a) 454d71ae5a4SJacob Faibussowitsch { 455e5c89e4eSSatish Balay PetscFunctionBegin; 4563ba16761SJacob Faibussowitsch if (!*a) PetscFunctionReturn(PETSC_SUCCESS); 4579566063dSJacob Faibussowitsch PetscCall(PetscFree((*a)->array)); 4589566063dSJacob Faibussowitsch PetscCall(PetscFree(*a)); 4593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 460e5c89e4eSSatish Balay } 461e5c89e4eSSatish Balay 4628e81d068SLisandro Dalcin /*@C 463667f096bSBarry Smith PetscStrInList - search for a string in character-delimited list 4648e81d068SLisandro Dalcin 465667f096bSBarry Smith Not Collective; No Fortran Support 4668e81d068SLisandro Dalcin 4678e81d068SLisandro Dalcin Input Parameters: 4688e81d068SLisandro Dalcin + str - the string to look for 4698e81d068SLisandro Dalcin . list - the list to search in 4708e81d068SLisandro Dalcin - sep - the separator character 4718e81d068SLisandro Dalcin 4728e81d068SLisandro Dalcin Output Parameter: 473667f096bSBarry Smith . found - whether `str` is in `list` 4748e81d068SLisandro Dalcin 4758e81d068SLisandro Dalcin Level: intermediate 4768e81d068SLisandro Dalcin 477db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscStrcmp()` 4788e81d068SLisandro Dalcin @*/ 479d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found) 480d71ae5a4SJacob Faibussowitsch { 4818e81d068SLisandro Dalcin PetscToken token; 4828e81d068SLisandro Dalcin char *item; 4838e81d068SLisandro Dalcin 4848e81d068SLisandro Dalcin PetscFunctionBegin; 4855f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 4); 4868e81d068SLisandro Dalcin *found = PETSC_FALSE; 4879566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(list, sep, &token)); 4889566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 4898e81d068SLisandro Dalcin while (item) { 4909566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(str, item, found)); 4918e81d068SLisandro Dalcin if (*found) break; 4929566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 4938e81d068SLisandro Dalcin } 4949566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 4953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4968e81d068SLisandro Dalcin } 497e5c89e4eSSatish Balay 498e5c89e4eSSatish Balay /*@C 499e5c89e4eSSatish Balay PetscGetPetscDir - Gets the directory PETSc is installed in 500e5c89e4eSSatish Balay 501667f096bSBarry Smith Not Collective; No Fortran Support 502e5c89e4eSSatish Balay 503e5c89e4eSSatish Balay Output Parameter: 504e5c89e4eSSatish Balay . dir - the directory 505e5c89e4eSSatish Balay 506e5c89e4eSSatish Balay Level: developer 507e5c89e4eSSatish Balay 508e5c89e4eSSatish Balay @*/ 509d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetPetscDir(const char *dir[]) 510d71ae5a4SJacob Faibussowitsch { 511e5c89e4eSSatish Balay PetscFunctionBegin; 5125f80ce2aSJacob Faibussowitsch PetscValidPointer(dir, 1); 513e5c89e4eSSatish Balay *dir = PETSC_DIR; 5143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 515e5c89e4eSSatish Balay } 516e5c89e4eSSatish Balay 517e5c89e4eSSatish Balay /*@C 518e5c89e4eSSatish Balay PetscStrreplace - Replaces substrings in string with other substrings 519e5c89e4eSSatish Balay 520667f096bSBarry Smith Not Collective; No Fortran Support 521e5c89e4eSSatish Balay 522e5c89e4eSSatish Balay Input Parameters: 523811af0c4SBarry Smith + comm - `MPI_Comm` of processors that are processing the string 52471573d7dSBarry Smith . aa - the string to look in 525667f096bSBarry Smith . b - the resulting copy of a with replaced strings (`b` can be the same as `a`) 526667f096bSBarry Smith - len - the length of `b` 527e5c89e4eSSatish Balay 5282fe279fdSBarry Smith Level: developer 5292fe279fdSBarry Smith 530e5c89e4eSSatish Balay Notes: 531e5c89e4eSSatish Balay Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 532f236b2adSBarry Smith ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME}, ${PETSC_MAKE} with appropriate values 533e5c89e4eSSatish Balay as well as any environmental variables. 534e5c89e4eSSatish Balay 535811af0c4SBarry Smith `PETSC_LIB_DIR` uses the environmental variable if it exists. `PETSC_ARCH` and `PETSC_DIR` use what 536acc6cc86SBarry Smith PETSc was built with and do not use environmental variables. 537acc6cc86SBarry Smith 538e5c89e4eSSatish Balay @*/ 539d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len) 540d71ae5a4SJacob Faibussowitsch { 541e5c89e4eSSatish Balay int i = 0; 542e5c89e4eSSatish Balay size_t l, l1, l2, l3; 5437864358aSSatish Balay char *work, *par, *epar = NULL, env[1024], *tfree, *a = (char *)aa; 544f236b2adSBarry Smith const char *s[] = {"${PETSC_ARCH}", "${PETSC_DIR}", "${PETSC_LIB_DIR}", "${DISPLAY}", "${HOMEDIRECTORY}", "${WORKINGDIRECTORY}", "${USERNAME}", "${HOSTNAME}", "${PETSC_MAKE}", NULL}; 545f236b2adSBarry Smith char *r[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 546ace3abfcSBarry Smith PetscBool flag; 547589a23caSBarry Smith static size_t DISPLAY_LENGTH = 265, USER_LENGTH = 256, HOST_LENGTH = 256; 548e5c89e4eSSatish Balay 549e5c89e4eSSatish Balay PetscFunctionBegin; 5505f80ce2aSJacob Faibussowitsch PetscValidCharPointer(aa, 2); 5515f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b, 3); 5529566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscStrallocpy(aa, (char **)&a)); 5539566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len, &work)); 554e5c89e4eSSatish Balay 555e5c89e4eSSatish Balay /* get values for replaced variables */ 5569566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_ARCH, &r[0])); 5579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_DIR, &r[1])); 5589566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_LIB_DIR, &r[2])); 5599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(DISPLAY_LENGTH, &r[3])); 5609566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[4])); 5619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[5])); 5629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(USER_LENGTH, &r[6])); 5639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(HOST_LENGTH, &r[7])); 5649566063dSJacob Faibussowitsch PetscCall(PetscGetDisplay(r[3], DISPLAY_LENGTH)); 5659566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(r[4], PETSC_MAX_PATH_LEN)); 5669566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(r[5], PETSC_MAX_PATH_LEN)); 5679566063dSJacob Faibussowitsch PetscCall(PetscGetUserName(r[6], USER_LENGTH)); 5689566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(r[7], HOST_LENGTH)); 569f236b2adSBarry Smith PetscCall(PetscStrallocpy(PETSC_OMAKE, &r[8])); 570487e5849SBarry Smith 571487e5849SBarry Smith /* replace that are in environment */ 5729566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_LIB_DIR", env, sizeof(env), &flag)); 573487e5849SBarry Smith if (flag) { 5749566063dSJacob Faibussowitsch PetscCall(PetscFree(r[2])); 5759566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(env, &r[2])); 576487e5849SBarry Smith } 577e5c89e4eSSatish Balay 578e5c89e4eSSatish Balay /* replace the requested strings */ 5799566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, a, len)); 580e5c89e4eSSatish Balay while (s[i]) { 5819566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s[i], &l)); 5829566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 583e5c89e4eSSatish Balay while (par) { 584e5c89e4eSSatish Balay *par = 0; 585e5c89e4eSSatish Balay par += l; 586e5c89e4eSSatish Balay 5879566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b, &l1)); 5889566063dSJacob Faibussowitsch PetscCall(PetscStrlen(r[i], &l2)); 5899566063dSJacob Faibussowitsch PetscCall(PetscStrlen(par, &l3)); 590cc73adaaSBarry Smith PetscCheck(l1 + l2 + l3 < len, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "b len is not long enough to hold new values"); 5919566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 5929566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, r[i], len)); 5939566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, par, len)); 5949566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 5959566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 596e5c89e4eSSatish Balay } 597e5c89e4eSSatish Balay i++; 598e5c89e4eSSatish Balay } 599487e5849SBarry Smith i = 0; 600487e5849SBarry Smith while (r[i]) { 601e5c89e4eSSatish Balay tfree = (char *)r[i]; 6029566063dSJacob Faibussowitsch PetscCall(PetscFree(tfree)); 603487e5849SBarry Smith i++; 604e5c89e4eSSatish Balay } 605e5c89e4eSSatish Balay 606e5c89e4eSSatish Balay /* look for any other ${xxx} strings to replace from environmental variables */ 6079566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 608e5c89e4eSSatish Balay while (par) { 609e5c89e4eSSatish Balay *par = 0; 610e5c89e4eSSatish Balay par += 2; 6119566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 6129566063dSJacob Faibussowitsch PetscCall(PetscStrstr(par, "}", &epar)); 613e5c89e4eSSatish Balay *epar = 0; 614e5c89e4eSSatish Balay epar += 1; 6159566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, par, env, sizeof(env), &flag)); 61628b400f6SJacob Faibussowitsch PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Substitution string ${%s} not found as environmental variable", par); 6179566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, env, len)); 6189566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, epar, len)); 6199566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 6209566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 621e5c89e4eSSatish Balay } 6229566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 6239566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscFree(a)); 6243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 625e5c89e4eSSatish Balay } 626e5c89e4eSSatish Balay 627a53986e1SJed Brown /*@C 628c0d8b5b9SStefano Zampini PetscStrcmpAny - Determines whether a string matches any of a list of strings. 629c0d8b5b9SStefano Zampini 630c0d8b5b9SStefano Zampini Not Collective 631c0d8b5b9SStefano Zampini 632c0d8b5b9SStefano Zampini Input Parameters: 633c0d8b5b9SStefano Zampini + src - pointer to input the string 634c0d8b5b9SStefano Zampini - cmp - list of non-null and non-empty strings to be compared against, pass the empty string "" to terminate the list 635c0d8b5b9SStefano Zampini 636c0d8b5b9SStefano Zampini Output Parameter: 637c0d8b5b9SStefano Zampini . match - `PETSC_TRUE` if the input string matches any in the list, else `PETSC_FALSE` 638c0d8b5b9SStefano Zampini 639c0d8b5b9SStefano Zampini Level: intermediate 640c0d8b5b9SStefano Zampini 641c0d8b5b9SStefano Zampini .seealso: `PetscStrcmp` 642c0d8b5b9SStefano Zampini @*/ 643c0d8b5b9SStefano Zampini PetscErrorCode PetscStrcmpAny(const char src[], PetscBool *match, const char cmp[], ...) 644c0d8b5b9SStefano Zampini { 645c0d8b5b9SStefano Zampini va_list Argp; 646c0d8b5b9SStefano Zampini 647c0d8b5b9SStefano Zampini PetscFunctionBegin; 648c0d8b5b9SStefano Zampini PetscValidBoolPointer(match, 2); 649c0d8b5b9SStefano Zampini *match = PETSC_FALSE; 650c0d8b5b9SStefano Zampini if (!src) PetscFunctionReturn(PETSC_SUCCESS); 651c0d8b5b9SStefano Zampini va_start(Argp, cmp); 652c0d8b5b9SStefano Zampini while (cmp && cmp[0]) { 653c0d8b5b9SStefano Zampini PetscBool found; 654c0d8b5b9SStefano Zampini PetscCall(PetscStrcmp(src, cmp, &found)); 655c0d8b5b9SStefano Zampini if (found) { 656c0d8b5b9SStefano Zampini *match = PETSC_TRUE; 657c0d8b5b9SStefano Zampini break; 658c0d8b5b9SStefano Zampini } 659c0d8b5b9SStefano Zampini cmp = va_arg(Argp, const char *); 660c0d8b5b9SStefano Zampini } 661c0d8b5b9SStefano Zampini va_end(Argp); 662c0d8b5b9SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 663c0d8b5b9SStefano Zampini } 664c0d8b5b9SStefano Zampini 665c0d8b5b9SStefano Zampini /*@C 666a53986e1SJed Brown PetscEListFind - searches list of strings for given string, using case insensitive matching 667e5c89e4eSSatish Balay 668667f096bSBarry Smith Not Collective; No Fortran Support 669a53986e1SJed Brown 670a53986e1SJed Brown Input Parameters: 671a53986e1SJed Brown + n - number of strings in 672a53986e1SJed Brown . list - list of strings to search 673a53986e1SJed Brown - str - string to look for, empty string "" accepts default (first entry in list) 674a53986e1SJed Brown 675a53986e1SJed Brown Output Parameters: 676a53986e1SJed Brown + value - index of matching string (if found) 677667f096bSBarry Smith - found - boolean indicating whether string was found (can be `NULL`) 678811af0c4SBarry Smith 67953c0d4aeSBarry Smith Level: developer 68053c0d4aeSBarry Smith 681811af0c4SBarry Smith .seealso: `PetscEnumFind()` 682a53986e1SJed Brown @*/ 683d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found) 684d71ae5a4SJacob Faibussowitsch { 685a53986e1SJed Brown PetscFunctionBegin; 6865f80ce2aSJacob Faibussowitsch if (found) { 6875f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 5); 6885f80ce2aSJacob Faibussowitsch *found = PETSC_FALSE; 6895f80ce2aSJacob Faibussowitsch } 6905f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 6915f80ce2aSJacob Faibussowitsch PetscBool matched; 6925f80ce2aSJacob Faibussowitsch 6939566063dSJacob Faibussowitsch PetscCall(PetscStrcasecmp(str, list[i], &matched)); 694a53986e1SJed Brown if (matched || !str[0]) { 695a53986e1SJed Brown if (found) *found = PETSC_TRUE; 696a53986e1SJed Brown *value = i; 697a53986e1SJed Brown break; 698a53986e1SJed Brown } 699a53986e1SJed Brown } 7003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 701a53986e1SJed Brown } 702a53986e1SJed Brown 703a53986e1SJed Brown /*@C 7048e81d068SLisandro Dalcin PetscEnumFind - searches enum list of strings for given string, using case insensitive matching 705a53986e1SJed Brown 706667f096bSBarry Smith Not Collective; No Fortran Support 707a53986e1SJed Brown 708a53986e1SJed Brown Input Parameters: 709667f096bSBarry Smith + enumlist - list of strings to search, followed by enum name, then enum prefix, then `NULL` 710a53986e1SJed Brown - str - string to look for 711a53986e1SJed Brown 712a53986e1SJed Brown Output Parameters: 713a53986e1SJed Brown + value - index of matching string (if found) 714667f096bSBarry Smith - found - boolean indicating whether string was found (can be `NULL`) 715a53986e1SJed Brown 716a53986e1SJed Brown Level: advanced 717811af0c4SBarry Smith 718811af0c4SBarry Smith .seealso: `PetscEListFind()` 719a53986e1SJed Brown @*/ 720d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found) 721d71ae5a4SJacob Faibussowitsch { 722d05ba7d2SLisandro Dalcin PetscInt n = 0, evalue; 723a53986e1SJed Brown PetscBool efound; 724a53986e1SJed Brown 725a53986e1SJed Brown PetscFunctionBegin; 7265f80ce2aSJacob Faibussowitsch PetscValidPointer(enumlist, 1); 7275f80ce2aSJacob 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"); 7285f80ce2aSJacob Faibussowitsch PetscCheck(n >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix"); 729a53986e1SJed Brown n -= 3; /* drop enum name, prefix, and null termination */ 7309566063dSJacob Faibussowitsch PetscCall(PetscEListFind(n, enumlist, str, &evalue, &efound)); 7315f80ce2aSJacob Faibussowitsch if (efound) { 7325f80ce2aSJacob Faibussowitsch PetscValidPointer(value, 3); 7335f80ce2aSJacob Faibussowitsch *value = (PetscEnum)evalue; 7345f80ce2aSJacob Faibussowitsch } 7355f80ce2aSJacob Faibussowitsch if (found) { 7365f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found, 4); 7375f80ce2aSJacob Faibussowitsch *found = efound; 7385f80ce2aSJacob Faibussowitsch } 7393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 740a53986e1SJed Brown } 741660278c0SBarry Smith 742660278c0SBarry Smith /*@C 743660278c0SBarry Smith PetscCIFilename - returns the basename of a file name when the PETSc CI portable error output mode is enabled. 744660278c0SBarry Smith 74520f4b53cSBarry Smith Not Collective; No Fortran Support 746660278c0SBarry Smith 747660278c0SBarry Smith Input Parameter: 748660278c0SBarry Smith . file - the file name 749660278c0SBarry Smith 750667f096bSBarry Smith Level: developer 751667f096bSBarry Smith 752660278c0SBarry Smith Note: 753660278c0SBarry Smith PETSc CI mode is a mode of running PETSc where output (both error and non-error) is made portable across all systems 754660278c0SBarry Smith so that comparisons of output between runs are easy to make. 755660278c0SBarry Smith 756660278c0SBarry Smith This mode is used for all tests in the test harness, it applies to both debug and optimized builds. 757660278c0SBarry Smith 758667f096bSBarry Smith Use the option `-petsc_ci` to turn on PETSc CI mode. It changes certain output in non-error situations to be portable for 759660278c0SBarry Smith all systems, mainly the output of options. It is passed to all PETSc programs automatically by the test harness. 760660278c0SBarry Smith 761660278c0SBarry Smith Always uses the Unix / as the file separate even on Microsoft Windows systems 762660278c0SBarry Smith 763667f096bSBarry Smith The option `-petsc_ci_portable_error_output` attempts to output the same error messages on all systems for the test harness. 764660278c0SBarry Smith In particular the output of filenames and line numbers in PETSc stacks. This is to allow (limited) checking of PETSc 765660278c0SBarry 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 766660278c0SBarry Smith harness can process the output for differences in the usual manner as for successful runs. It should be provided to the test 767da81f932SPierre Jolivet harness in the args: argument for specific examples. It will not necessarily produce portable output if different errors 768660278c0SBarry Smith (or no errors) occur on a subset of the MPI ranks. 769660278c0SBarry Smith 770660278c0SBarry Smith .seealso: `PetscCILinenumber()` 771660278c0SBarry Smith @*/ 772d71ae5a4SJacob Faibussowitsch const char *PetscCIFilename(const char *file) 773d71ae5a4SJacob Faibussowitsch { 774660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return file; 775660278c0SBarry Smith return PetscBasename(file); 776660278c0SBarry Smith } 777660278c0SBarry Smith 778660278c0SBarry Smith /*@C 779811af0c4SBarry Smith PetscCILinenumber - returns a line number except if `PetscCIEnablePortableErrorOutput` is set when it returns 0 780660278c0SBarry Smith 781667f096bSBarry Smith Not Collective; No Fortran Support 782660278c0SBarry Smith 783660278c0SBarry Smith Input Parameter: 784660278c0SBarry Smith . linenumber - the initial line number 785660278c0SBarry Smith 786667f096bSBarry Smith Level: developer 787667f096bSBarry Smith 788660278c0SBarry Smith Note: 789660278c0SBarry Smith See `PetscCIFilename()` for details on usage 790660278c0SBarry Smith 791660278c0SBarry Smith .seealso: `PetscCIFilename()` 792660278c0SBarry Smith @*/ 793d71ae5a4SJacob Faibussowitsch int PetscCILinenumber(int linenumber) 794d71ae5a4SJacob Faibussowitsch { 795660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return linenumber; 796660278c0SBarry Smith return 0; 797660278c0SBarry Smith } 798d11110bcSJacob Faibussowitsch 799d11110bcSJacob Faibussowitsch /*@C 800d11110bcSJacob Faibussowitsch PetscStrcat - Concatenates a string onto a given string 801d11110bcSJacob Faibussowitsch 802d11110bcSJacob Faibussowitsch Not Collective, No Fortran Support 803d11110bcSJacob Faibussowitsch 804d11110bcSJacob Faibussowitsch Input Parameters: 805d11110bcSJacob Faibussowitsch + s - string to be added to 806d11110bcSJacob Faibussowitsch - t - pointer to string to be added to end 807d11110bcSJacob Faibussowitsch 808d11110bcSJacob Faibussowitsch Level: deprecated (since 3.18.5) 809d11110bcSJacob Faibussowitsch 810d11110bcSJacob Faibussowitsch Notes: 811d11110bcSJacob Faibussowitsch It is recommended you use `PetscStrlcat()` instead of this routine. 812d11110bcSJacob Faibussowitsch 813d11110bcSJacob Faibussowitsch .seealso: `PetscStrlcat()` 814d11110bcSJacob Faibussowitsch @*/ 815d11110bcSJacob Faibussowitsch PetscErrorCode PetscStrcat(char s[], const char t[]) 816d11110bcSJacob Faibussowitsch { 817d11110bcSJacob Faibussowitsch PetscFunctionBegin; 818d11110bcSJacob Faibussowitsch if (!t) PetscFunctionReturn(PETSC_SUCCESS); 819d11110bcSJacob Faibussowitsch PetscValidCharPointer(s, 1); 820d11110bcSJacob Faibussowitsch strcat(s, t); 821d11110bcSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 822d11110bcSJacob Faibussowitsch } 823d11110bcSJacob Faibussowitsch 824d11110bcSJacob Faibussowitsch /*@C 825d11110bcSJacob Faibussowitsch PetscStrcpy - Copies a string 826d11110bcSJacob Faibussowitsch 827d11110bcSJacob Faibussowitsch Not Collective, No Fortran Support 828d11110bcSJacob Faibussowitsch 8292fe279fdSBarry Smith Input Parameter: 830d11110bcSJacob Faibussowitsch . t - pointer to string 831d11110bcSJacob Faibussowitsch 832d11110bcSJacob Faibussowitsch Output Parameter: 833d11110bcSJacob Faibussowitsch . s - the copied string 834d11110bcSJacob Faibussowitsch 835d11110bcSJacob Faibussowitsch Level: deprecated (since 3.18.5) 836d11110bcSJacob Faibussowitsch 837d11110bcSJacob Faibussowitsch Notes: 838d11110bcSJacob Faibussowitsch It is recommended you use `PetscStrncpy()` (equivalently `PetscArraycpy()` or 839d11110bcSJacob Faibussowitsch `PetscMemcpy()`) instead of this routine. 840d11110bcSJacob Faibussowitsch 841d11110bcSJacob Faibussowitsch `NULL` strings returns a string starting with zero. 842d11110bcSJacob Faibussowitsch 843d11110bcSJacob Faibussowitsch .seealso: `PetscStrncpy()` 844d11110bcSJacob Faibussowitsch @*/ 845d11110bcSJacob Faibussowitsch PetscErrorCode PetscStrcpy(char s[], const char t[]) 846d11110bcSJacob Faibussowitsch { 847d11110bcSJacob Faibussowitsch PetscFunctionBegin; 848d11110bcSJacob Faibussowitsch if (t) { 849d11110bcSJacob Faibussowitsch PetscValidCharPointer(s, 1); 850d11110bcSJacob Faibussowitsch PetscValidCharPointer(t, 2); 851d11110bcSJacob Faibussowitsch strcpy(s, t); 852d11110bcSJacob Faibussowitsch } else if (s) { 853d11110bcSJacob Faibussowitsch s[0] = '\0'; 854d11110bcSJacob Faibussowitsch } 855d11110bcSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 856d11110bcSJacob Faibussowitsch } 857