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: 216497c311SBarry Smith + argc - the number of entries in `args` 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 326497c311SBarry 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 { 386497c311SBarry Smith int n, i, j, *lens, cnt = 0; 39ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 403c311c98SBarry Smith 4140a7e1efSBarry Smith if (!s) n = 0; 426497c311SBarry Smith else n = (int)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; 62*dd460d27SBarry Smith lens = (int *)malloc(((*argc) + 1) * 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: 139aec76313SJacob 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; 157fbccb6d4SPierre Jolivet while (list[n++]); 1589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n + 1, t)); 1599566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 1600298fd71SBarry Smith (*t)[n] = NULL; 1613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16247340559SBarry Smith } 16347340559SBarry Smith 16447340559SBarry Smith /*@C 165811af0c4SBarry Smith PetscStrArrayDestroy - Frees array of strings created with `PetscStrArrayallocpy()`. 16647340559SBarry Smith 167667f096bSBarry Smith Not Collective; No Fortran Support 16847340559SBarry Smith 1692fe279fdSBarry Smith Output Parameter: 17047340559SBarry Smith . list - array of strings 17147340559SBarry Smith 17247340559SBarry Smith Level: intermediate 17347340559SBarry Smith 174db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()` 17547340559SBarry Smith @*/ 176d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrArrayDestroy(char ***list) 177d71ae5a4SJacob Faibussowitsch { 17847340559SBarry Smith PetscInt n = 0; 17947340559SBarry Smith 1806fed8037SJed Brown PetscFunctionBegin; 1813ba16761SJacob Faibussowitsch if (!*list) PetscFunctionReturn(PETSC_SUCCESS); 1826fed8037SJed Brown while ((*list)[n]) { 1839566063dSJacob Faibussowitsch PetscCall(PetscFree((*list)[n])); 1845f80ce2aSJacob Faibussowitsch ++n; 18547340559SBarry Smith } 1869566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18847340559SBarry Smith } 18947340559SBarry Smith 1906991f827SBarry Smith /*@C 1916991f827SBarry Smith PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 1926991f827SBarry Smith 193667f096bSBarry Smith Not Collective; No Fortran Support 1946991f827SBarry Smith 1956991f827SBarry Smith Input Parameters: 1966991f827SBarry Smith + n - the number of string entries 197aec76313SJacob Faibussowitsch - list - pointer to array of strings 1986991f827SBarry Smith 1996991f827SBarry Smith Output Parameter: 2006991f827SBarry Smith . t - the copied array string 2016991f827SBarry Smith 2026991f827SBarry Smith Level: intermediate 2036991f827SBarry Smith 204db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayallocpy()`, `PetscStrNArrayDestroy()` 2056991f827SBarry Smith @*/ 206d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrNArrayallocpy(PetscInt n, const char *const *list, char ***t) 207d71ae5a4SJacob Faibussowitsch { 2086991f827SBarry Smith PetscFunctionBegin; 2099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, t)); 2109566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 2113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2126991f827SBarry Smith } 2136991f827SBarry Smith 2146991f827SBarry Smith /*@C 215811af0c4SBarry Smith PetscStrNArrayDestroy - Frees array of strings created with `PetscStrNArrayallocpy()`. 2166991f827SBarry Smith 217667f096bSBarry Smith Not Collective; No Fortran Support 2186991f827SBarry Smith 2196991f827SBarry Smith Output Parameters: 2206991f827SBarry Smith + n - number of string entries 2216991f827SBarry Smith - list - array of strings 2226991f827SBarry Smith 2236991f827SBarry Smith Level: intermediate 2246991f827SBarry Smith 225811af0c4SBarry Smith .seealso: `PetscStrNArrayallocpy()`, `PetscStrArrayallocpy()` 2266991f827SBarry Smith @*/ 227d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrNArrayDestroy(PetscInt n, char ***list) 228d71ae5a4SJacob Faibussowitsch { 2296991f827SBarry Smith PetscFunctionBegin; 2303ba16761SJacob Faibussowitsch if (!*list) PetscFunctionReturn(PETSC_SUCCESS); 2319566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscFree((*list)[i])); 2329566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 2333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2346991f827SBarry Smith } 2356991f827SBarry Smith 236e5c89e4eSSatish Balay /*@C 237811af0c4SBarry Smith PetscBasename - returns a pointer to the last entry of a / or \ separated directory path 23880b92c66SBarry Smith 239667f096bSBarry Smith Not Collective; No Fortran Support 24080b92c66SBarry Smith 24180b92c66SBarry Smith Input Parameter: 24280b92c66SBarry Smith . a - pointer to string 24380b92c66SBarry Smith 24480b92c66SBarry Smith Level: intermediate 24580b92c66SBarry Smith 24680b92c66SBarry Smith .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`, `PetscStrrchr()`, `PetscStrcmp()`, `PetscStrstr()`, 24780b92c66SBarry Smith `PetscTokenCreate()`, `PetscStrToArray()`, `PetscStrInList()` 24880b92c66SBarry Smith @*/ 249d71ae5a4SJacob Faibussowitsch const char *PetscBasename(const char a[]) 250d71ae5a4SJacob Faibussowitsch { 251bbcf679cSJacob Faibussowitsch const char *ptr = NULL; 25280b92c66SBarry Smith 253bbcf679cSJacob Faibussowitsch (void)PetscStrrchr(a, '/', (char **)&ptr); 254660278c0SBarry Smith if (ptr == a) { 255660278c0SBarry Smith if (PetscStrrchr(a, '\\', (char **)&ptr)) ptr = NULL; 256660278c0SBarry Smith } 25780b92c66SBarry Smith return ptr; 25880b92c66SBarry Smith } 25980b92c66SBarry Smith 26080b92c66SBarry Smith /*@C 261e5c89e4eSSatish Balay PetscStrcasecmp - Returns true if the two strings are the same 262e5c89e4eSSatish Balay except possibly for case. 263e5c89e4eSSatish Balay 264667f096bSBarry Smith Not Collective; No Fortran Support 265e5c89e4eSSatish Balay 266e5c89e4eSSatish Balay Input Parameters: 267e5c89e4eSSatish Balay + a - pointer to first string 268e5c89e4eSSatish Balay - b - pointer to second string 269e5c89e4eSSatish Balay 270e5c89e4eSSatish Balay Output Parameter: 271aec76313SJacob Faibussowitsch . t - if the two strings are the same 272e5c89e4eSSatish Balay 273e5c89e4eSSatish Balay Level: intermediate 274e5c89e4eSSatish Balay 275667f096bSBarry Smith Note: 276667f096bSBarry Smith `NULL` arguments are ok 277667f096bSBarry Smith 278db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrgrt()` 279e5c89e4eSSatish Balay @*/ 280d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrcasecmp(const char a[], const char b[], PetscBool *t) 281d71ae5a4SJacob Faibussowitsch { 282e5c89e4eSSatish Balay int c; 283e5c89e4eSSatish Balay 284e5c89e4eSSatish Balay PetscFunctionBegin; 2854f572ea9SToby Isaac PetscAssertPointer(t, 3); 286e5c89e4eSSatish Balay if (!a && !b) c = 0; 287e5c89e4eSSatish Balay else if (!a || !b) c = 1; 28832b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP) 28932b366c8SSatish Balay else c = strcasecmp(a, b); 29032b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP) 291e5c89e4eSSatish Balay else c = stricmp(a, b); 292e5c89e4eSSatish Balay #else 29332b366c8SSatish Balay else { 29432b366c8SSatish Balay char *aa, *bb; 295bbcf679cSJacob Faibussowitsch 2969566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &aa)); 2979566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(b, &bb)); 2989566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(aa)); 2999566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(bb)); 3009566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(aa, bb, t)); 3019566063dSJacob Faibussowitsch PetscCall(PetscFree(aa)); 3029566063dSJacob Faibussowitsch PetscCall(PetscFree(bb)); 3033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30432b366c8SSatish Balay } 305e5c89e4eSSatish Balay #endif 3065f80ce2aSJacob Faibussowitsch *t = c ? PETSC_FALSE : PETSC_TRUE; 3073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308e5c89e4eSSatish Balay } 309e5c89e4eSSatish Balay 310e5c89e4eSSatish Balay /*@C 3117ba3a57cSBarry Smith PetscStrendswithwhich - Determines if a string ends with one of several possible strings 3127ba3a57cSBarry Smith 313667f096bSBarry Smith Not Collective; No Fortran Support 3147ba3a57cSBarry Smith 3157ba3a57cSBarry Smith Input Parameters: 3167ba3a57cSBarry Smith + a - pointer to string 317667f096bSBarry Smith - bs - strings to end with (last entry must be `NULL`) 3187ba3a57cSBarry Smith 3197ba3a57cSBarry Smith Output Parameter: 320667f096bSBarry Smith . cnt - the index of the string it ends with or the index of `NULL` 3217ba3a57cSBarry Smith 3227ba3a57cSBarry Smith Level: intermediate 3237ba3a57cSBarry Smith 324811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 325aec76313SJacob Faibussowitsch `PetscStrncmp()`, `PetscStrlen()`, `PetscStrcmp()` 3267ba3a57cSBarry Smith @*/ 327d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrendswithwhich(const char a[], const char *const *bs, PetscInt *cnt) 328d71ae5a4SJacob Faibussowitsch { 3297ba3a57cSBarry Smith PetscFunctionBegin; 3304f572ea9SToby Isaac PetscAssertPointer(bs, 2); 3314f572ea9SToby Isaac PetscAssertPointer(cnt, 3); 3327ba3a57cSBarry Smith *cnt = 0; 3337ba3a57cSBarry Smith while (bs[*cnt]) { 3345f80ce2aSJacob Faibussowitsch PetscBool flg; 3355f80ce2aSJacob Faibussowitsch 3369566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(a, bs[*cnt], &flg)); 3373ba16761SJacob Faibussowitsch if (flg) PetscFunctionReturn(PETSC_SUCCESS); 3385f80ce2aSJacob Faibussowitsch ++(*cnt); 3397ba3a57cSBarry Smith } 3403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3417ba3a57cSBarry Smith } 3427ba3a57cSBarry Smith 3439371c9d4SSatish Balay struct _p_PetscToken { 3449371c9d4SSatish Balay char token; 3459371c9d4SSatish Balay char *array; 3469371c9d4SSatish Balay char *current; 3479371c9d4SSatish Balay }; 3481d1a0024SBarry Smith 349e5c89e4eSSatish Balay /*@C 350667f096bSBarry Smith PetscTokenFind - Locates next "token" in a `PetscToken` 351e5c89e4eSSatish Balay 352667f096bSBarry Smith Not Collective; No Fortran Support 353e5c89e4eSSatish Balay 3542fe279fdSBarry Smith Input Parameter: 355e5c89e4eSSatish Balay . a - pointer to token 356e5c89e4eSSatish Balay 357e5c89e4eSSatish Balay Output Parameter: 358667f096bSBarry Smith . result - location of occurrence, `NULL` if not found 3596f013253SBarry Smith 360e5c89e4eSSatish Balay Level: intermediate 361e5c89e4eSSatish Balay 362667f096bSBarry Smith Notes: 363667f096bSBarry Smith Treats all characters etc. inside a double quote " 364667f096bSBarry Smith as a single token. 365667f096bSBarry Smith 366667f096bSBarry 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 367667f096bSBarry Smith second will return a `NULL` terminated y 368667f096bSBarry Smith 369667f096bSBarry 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 370667f096bSBarry Smith 371667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenCreate()`, `PetscTokenDestroy()` 372e5c89e4eSSatish Balay @*/ 373d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenFind(PetscToken a, char *result[]) 374d71ae5a4SJacob Faibussowitsch { 3755f80ce2aSJacob Faibussowitsch char *ptr, token; 376e5c89e4eSSatish Balay 377e5c89e4eSSatish Balay PetscFunctionBegin; 3784f572ea9SToby Isaac PetscAssertPointer(a, 1); 3794f572ea9SToby Isaac PetscAssertPointer(result, 2); 3805f80ce2aSJacob Faibussowitsch *result = ptr = a->current; 3819371c9d4SSatish Balay if (ptr && !*ptr) { 3829371c9d4SSatish Balay *result = NULL; 3833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3849371c9d4SSatish Balay } 3854704e885SBarry Smith token = a->token; 3869371c9d4SSatish Balay if (ptr && (*ptr == '"')) { 3879371c9d4SSatish Balay token = '"'; 3889371c9d4SSatish Balay (*result)++; 3899371c9d4SSatish Balay ptr++; 3909371c9d4SSatish Balay } 391e5c89e4eSSatish Balay while (ptr) { 3924704e885SBarry Smith if (*ptr == token) { 393e5c89e4eSSatish Balay *ptr++ = 0; 394e5c89e4eSSatish Balay while (*ptr == a->token) ptr++; 395e5c89e4eSSatish Balay a->current = ptr; 396e5c89e4eSSatish Balay break; 397e5c89e4eSSatish Balay } 398e5c89e4eSSatish Balay if (!*ptr) { 39902c9f0b5SLisandro Dalcin a->current = NULL; 400e5c89e4eSSatish Balay break; 401e5c89e4eSSatish Balay } 402e5c89e4eSSatish Balay ptr++; 403e5c89e4eSSatish Balay } 4043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 405e5c89e4eSSatish Balay } 406e5c89e4eSSatish Balay 407e5c89e4eSSatish Balay /*@C 408811af0c4SBarry Smith PetscTokenCreate - Creates a `PetscToken` used to find tokens in a string 409e5c89e4eSSatish Balay 410667f096bSBarry Smith Not Collective; No Fortran Support 411e5c89e4eSSatish Balay 412e5c89e4eSSatish Balay Input Parameters: 413aec76313SJacob Faibussowitsch + a - the string to look in 4143a9c465aSBarry Smith - b - the separator character 415e5c89e4eSSatish Balay 416e5c89e4eSSatish Balay Output Parameter: 4173a9c465aSBarry Smith . t - the token object 418e5c89e4eSSatish Balay 419667f096bSBarry Smith Level: intermediate 420667f096bSBarry Smith 421811af0c4SBarry Smith Note: 422e5c89e4eSSatish Balay This version is different from the system version in that 423e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 424e5c89e4eSSatish Balay 425667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenFind()`, `PetscTokenDestroy()` 426e5c89e4eSSatish Balay @*/ 42798e514b7SJacob Faibussowitsch PetscErrorCode PetscTokenCreate(const char a[], char b, PetscToken *t) 428d71ae5a4SJacob Faibussowitsch { 429e5c89e4eSSatish Balay PetscFunctionBegin; 4304f572ea9SToby Isaac PetscAssertPointer(a, 1); 4314f572ea9SToby Isaac PetscAssertPointer(t, 3); 4329566063dSJacob Faibussowitsch PetscCall(PetscNew(t)); 4339566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &(*t)->array)); 434a297a907SKarl Rupp 435e5c89e4eSSatish Balay (*t)->current = (*t)->array; 436e5c89e4eSSatish Balay (*t)->token = b; 4373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 438e5c89e4eSSatish Balay } 439e5c89e4eSSatish Balay 440e5c89e4eSSatish Balay /*@C 441811af0c4SBarry Smith PetscTokenDestroy - Destroys a `PetscToken` 442e5c89e4eSSatish Balay 443667f096bSBarry Smith Not Collective; No Fortran Support 444e5c89e4eSSatish Balay 4452fe279fdSBarry Smith Input Parameter: 446e5c89e4eSSatish Balay . a - pointer to token 447e5c89e4eSSatish Balay 448e5c89e4eSSatish Balay Level: intermediate 449e5c89e4eSSatish Balay 450667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenCreate()`, `PetscTokenFind()` 451e5c89e4eSSatish Balay @*/ 452d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenDestroy(PetscToken *a) 453d71ae5a4SJacob Faibussowitsch { 454e5c89e4eSSatish Balay PetscFunctionBegin; 4553ba16761SJacob Faibussowitsch if (!*a) PetscFunctionReturn(PETSC_SUCCESS); 4569566063dSJacob Faibussowitsch PetscCall(PetscFree((*a)->array)); 4579566063dSJacob Faibussowitsch PetscCall(PetscFree(*a)); 4583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 459e5c89e4eSSatish Balay } 460e5c89e4eSSatish Balay 4618e81d068SLisandro Dalcin /*@C 462667f096bSBarry Smith PetscStrInList - search for a string in character-delimited list 4638e81d068SLisandro Dalcin 464667f096bSBarry Smith Not Collective; No Fortran Support 4658e81d068SLisandro Dalcin 4668e81d068SLisandro Dalcin Input Parameters: 4678e81d068SLisandro Dalcin + str - the string to look for 4688e81d068SLisandro Dalcin . list - the list to search in 4698e81d068SLisandro Dalcin - sep - the separator character 4708e81d068SLisandro Dalcin 4718e81d068SLisandro Dalcin Output Parameter: 472667f096bSBarry Smith . found - whether `str` is in `list` 4738e81d068SLisandro Dalcin 4748e81d068SLisandro Dalcin Level: intermediate 4758e81d068SLisandro Dalcin 476db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscStrcmp()` 4778e81d068SLisandro Dalcin @*/ 478d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found) 479d71ae5a4SJacob Faibussowitsch { 4808e81d068SLisandro Dalcin PetscToken token; 4818e81d068SLisandro Dalcin char *item; 4828e81d068SLisandro Dalcin 4838e81d068SLisandro Dalcin PetscFunctionBegin; 4844f572ea9SToby Isaac PetscAssertPointer(found, 4); 4858e81d068SLisandro Dalcin *found = PETSC_FALSE; 4869566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(list, sep, &token)); 4879566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 4888e81d068SLisandro Dalcin while (item) { 4899566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(str, item, found)); 4908e81d068SLisandro Dalcin if (*found) break; 4919566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 4928e81d068SLisandro Dalcin } 4939566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 4943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4958e81d068SLisandro Dalcin } 496e5c89e4eSSatish Balay 497e5c89e4eSSatish Balay /*@C 498e5c89e4eSSatish Balay PetscGetPetscDir - Gets the directory PETSc is installed in 499e5c89e4eSSatish Balay 500667f096bSBarry Smith Not Collective; No Fortran Support 501e5c89e4eSSatish Balay 502e5c89e4eSSatish Balay Output Parameter: 503e5c89e4eSSatish Balay . dir - the directory 504e5c89e4eSSatish Balay 505e5c89e4eSSatish Balay Level: developer 506e5c89e4eSSatish Balay 50710450e9eSJacob Faibussowitsch .seealso: `PetscGetArchType()` 508e5c89e4eSSatish Balay @*/ 509d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetPetscDir(const char *dir[]) 510d71ae5a4SJacob Faibussowitsch { 511e5c89e4eSSatish Balay PetscFunctionBegin; 5124f572ea9SToby Isaac PetscAssertPointer(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 53810450e9eSJacob Faibussowitsch .seealso: `PetscStrcmp()` 539e5c89e4eSSatish Balay @*/ 540d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len) 541d71ae5a4SJacob Faibussowitsch { 542e5c89e4eSSatish Balay int i = 0; 543e5c89e4eSSatish Balay size_t l, l1, l2, l3; 5447864358aSSatish Balay char *work, *par, *epar = NULL, env[1024], *tfree, *a = (char *)aa; 545f236b2adSBarry Smith const char *s[] = {"${PETSC_ARCH}", "${PETSC_DIR}", "${PETSC_LIB_DIR}", "${DISPLAY}", "${HOMEDIRECTORY}", "${WORKINGDIRECTORY}", "${USERNAME}", "${HOSTNAME}", "${PETSC_MAKE}", NULL}; 546f236b2adSBarry Smith char *r[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 547ace3abfcSBarry Smith PetscBool flag; 548589a23caSBarry Smith static size_t DISPLAY_LENGTH = 265, USER_LENGTH = 256, HOST_LENGTH = 256; 549e5c89e4eSSatish Balay 550e5c89e4eSSatish Balay PetscFunctionBegin; 5514f572ea9SToby Isaac PetscAssertPointer(aa, 2); 5524f572ea9SToby Isaac PetscAssertPointer(b, 3); 5539566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscStrallocpy(aa, (char **)&a)); 5549566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len, &work)); 555e5c89e4eSSatish Balay 556e5c89e4eSSatish Balay /* get values for replaced variables */ 5579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_ARCH, &r[0])); 5589566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_DIR, &r[1])); 5599566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_LIB_DIR, &r[2])); 5609566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(DISPLAY_LENGTH, &r[3])); 5619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[4])); 5629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[5])); 5639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(USER_LENGTH, &r[6])); 5649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(HOST_LENGTH, &r[7])); 5659566063dSJacob Faibussowitsch PetscCall(PetscGetDisplay(r[3], DISPLAY_LENGTH)); 5669566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(r[4], PETSC_MAX_PATH_LEN)); 5679566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(r[5], PETSC_MAX_PATH_LEN)); 5689566063dSJacob Faibussowitsch PetscCall(PetscGetUserName(r[6], USER_LENGTH)); 5699566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(r[7], HOST_LENGTH)); 570f236b2adSBarry Smith PetscCall(PetscStrallocpy(PETSC_OMAKE, &r[8])); 571487e5849SBarry Smith 572487e5849SBarry Smith /* replace that are in environment */ 5739566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_LIB_DIR", env, sizeof(env), &flag)); 574487e5849SBarry Smith if (flag) { 5759566063dSJacob Faibussowitsch PetscCall(PetscFree(r[2])); 5769566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(env, &r[2])); 577487e5849SBarry Smith } 578e5c89e4eSSatish Balay 579e5c89e4eSSatish Balay /* replace the requested strings */ 5809566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, a, len)); 581e5c89e4eSSatish Balay while (s[i]) { 5829566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s[i], &l)); 5839566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 584e5c89e4eSSatish Balay while (par) { 585e5c89e4eSSatish Balay *par = 0; 586e5c89e4eSSatish Balay par += l; 587e5c89e4eSSatish Balay 5889566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b, &l1)); 5899566063dSJacob Faibussowitsch PetscCall(PetscStrlen(r[i], &l2)); 5909566063dSJacob Faibussowitsch PetscCall(PetscStrlen(par, &l3)); 591cc73adaaSBarry Smith PetscCheck(l1 + l2 + l3 < len, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "b len is not long enough to hold new values"); 5929566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 5939566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, r[i], len)); 5949566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, par, len)); 5959566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 5969566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 597e5c89e4eSSatish Balay } 598e5c89e4eSSatish Balay i++; 599e5c89e4eSSatish Balay } 600487e5849SBarry Smith i = 0; 601487e5849SBarry Smith while (r[i]) { 602e5c89e4eSSatish Balay tfree = (char *)r[i]; 6039566063dSJacob Faibussowitsch PetscCall(PetscFree(tfree)); 604487e5849SBarry Smith i++; 605e5c89e4eSSatish Balay } 606e5c89e4eSSatish Balay 607e5c89e4eSSatish Balay /* look for any other ${xxx} strings to replace from environmental variables */ 6089566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 609e5c89e4eSSatish Balay while (par) { 610e5c89e4eSSatish Balay *par = 0; 611e5c89e4eSSatish Balay par += 2; 6129566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 6139566063dSJacob Faibussowitsch PetscCall(PetscStrstr(par, "}", &epar)); 614e5c89e4eSSatish Balay *epar = 0; 615e5c89e4eSSatish Balay epar += 1; 6169566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, par, env, sizeof(env), &flag)); 61728b400f6SJacob Faibussowitsch PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Substitution string ${%s} not found as environmental variable", par); 6189566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, env, len)); 6199566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, epar, len)); 6209566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 6219566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 622e5c89e4eSSatish Balay } 6239566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 6249566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscFree(a)); 6253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 626e5c89e4eSSatish Balay } 627e5c89e4eSSatish Balay 628a53986e1SJed Brown /*@C 629c0d8b5b9SStefano Zampini PetscStrcmpAny - Determines whether a string matches any of a list of strings. 630c0d8b5b9SStefano Zampini 631cc4c1da9SBarry Smith Not Collective, No Fortran Support 632c0d8b5b9SStefano Zampini 633c0d8b5b9SStefano Zampini Input Parameters: 634c0d8b5b9SStefano Zampini + src - pointer to input the string 635c0d8b5b9SStefano Zampini - cmp - list of non-null and non-empty strings to be compared against, pass the empty string "" to terminate the list 636c0d8b5b9SStefano Zampini 637c0d8b5b9SStefano Zampini Output Parameter: 638c0d8b5b9SStefano Zampini . match - `PETSC_TRUE` if the input string matches any in the list, else `PETSC_FALSE` 639c0d8b5b9SStefano Zampini 640c0d8b5b9SStefano Zampini Level: intermediate 641c0d8b5b9SStefano Zampini 64210450e9eSJacob Faibussowitsch .seealso: `PetscStrcmp()` 643c0d8b5b9SStefano Zampini @*/ 644c0d8b5b9SStefano Zampini PetscErrorCode PetscStrcmpAny(const char src[], PetscBool *match, const char cmp[], ...) 645c0d8b5b9SStefano Zampini { 646c0d8b5b9SStefano Zampini va_list Argp; 647c0d8b5b9SStefano Zampini 648c0d8b5b9SStefano Zampini PetscFunctionBegin; 6494f572ea9SToby Isaac PetscAssertPointer(match, 2); 650c0d8b5b9SStefano Zampini *match = PETSC_FALSE; 651c0d8b5b9SStefano Zampini if (!src) PetscFunctionReturn(PETSC_SUCCESS); 652c0d8b5b9SStefano Zampini va_start(Argp, cmp); 653c0d8b5b9SStefano Zampini while (cmp && cmp[0]) { 654c0d8b5b9SStefano Zampini PetscBool found; 655c0d8b5b9SStefano Zampini PetscCall(PetscStrcmp(src, cmp, &found)); 656c0d8b5b9SStefano Zampini if (found) { 657c0d8b5b9SStefano Zampini *match = PETSC_TRUE; 658c0d8b5b9SStefano Zampini break; 659c0d8b5b9SStefano Zampini } 660c0d8b5b9SStefano Zampini cmp = va_arg(Argp, const char *); 661c0d8b5b9SStefano Zampini } 662c0d8b5b9SStefano Zampini va_end(Argp); 663c0d8b5b9SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 664c0d8b5b9SStefano Zampini } 665c0d8b5b9SStefano Zampini 666c0d8b5b9SStefano Zampini /*@C 667a53986e1SJed Brown PetscEListFind - searches list of strings for given string, using case insensitive matching 668e5c89e4eSSatish Balay 669667f096bSBarry Smith Not Collective; No Fortran Support 670a53986e1SJed Brown 671a53986e1SJed Brown Input Parameters: 672a53986e1SJed Brown + n - number of strings in 673a53986e1SJed Brown . list - list of strings to search 674a53986e1SJed Brown - str - string to look for, empty string "" accepts default (first entry in list) 675a53986e1SJed Brown 676a53986e1SJed Brown Output Parameters: 677a53986e1SJed Brown + value - index of matching string (if found) 678667f096bSBarry Smith - found - boolean indicating whether string was found (can be `NULL`) 679811af0c4SBarry Smith 68053c0d4aeSBarry Smith Level: developer 68153c0d4aeSBarry Smith 682811af0c4SBarry Smith .seealso: `PetscEnumFind()` 683a53986e1SJed Brown @*/ 684d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found) 685d71ae5a4SJacob Faibussowitsch { 686a53986e1SJed Brown PetscFunctionBegin; 6875f80ce2aSJacob Faibussowitsch if (found) { 6884f572ea9SToby Isaac PetscAssertPointer(found, 5); 6895f80ce2aSJacob Faibussowitsch *found = PETSC_FALSE; 6905f80ce2aSJacob Faibussowitsch } 6915f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 6925f80ce2aSJacob Faibussowitsch PetscBool matched; 6935f80ce2aSJacob Faibussowitsch 6949566063dSJacob Faibussowitsch PetscCall(PetscStrcasecmp(str, list[i], &matched)); 695a53986e1SJed Brown if (matched || !str[0]) { 696a53986e1SJed Brown if (found) *found = PETSC_TRUE; 697a53986e1SJed Brown *value = i; 698a53986e1SJed Brown break; 699a53986e1SJed Brown } 700a53986e1SJed Brown } 7013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 702a53986e1SJed Brown } 703a53986e1SJed Brown 704a53986e1SJed Brown /*@C 7058e81d068SLisandro Dalcin PetscEnumFind - searches enum list of strings for given string, using case insensitive matching 706a53986e1SJed Brown 707667f096bSBarry Smith Not Collective; No Fortran Support 708a53986e1SJed Brown 709a53986e1SJed Brown Input Parameters: 710667f096bSBarry Smith + enumlist - list of strings to search, followed by enum name, then enum prefix, then `NULL` 711a53986e1SJed Brown - str - string to look for 712a53986e1SJed Brown 713a53986e1SJed Brown Output Parameters: 714a53986e1SJed Brown + value - index of matching string (if found) 715667f096bSBarry Smith - found - boolean indicating whether string was found (can be `NULL`) 716a53986e1SJed Brown 717a53986e1SJed Brown Level: advanced 718811af0c4SBarry Smith 719811af0c4SBarry Smith .seealso: `PetscEListFind()` 720a53986e1SJed Brown @*/ 721d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found) 722d71ae5a4SJacob Faibussowitsch { 723d05ba7d2SLisandro Dalcin PetscInt n = 0, evalue; 724a53986e1SJed Brown PetscBool efound; 725a53986e1SJed Brown 726a53986e1SJed Brown PetscFunctionBegin; 7274f572ea9SToby Isaac PetscAssertPointer(enumlist, 1); 7285f80ce2aSJacob 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"); 7295f80ce2aSJacob Faibussowitsch PetscCheck(n >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix"); 730a53986e1SJed Brown n -= 3; /* drop enum name, prefix, and null termination */ 7319566063dSJacob Faibussowitsch PetscCall(PetscEListFind(n, enumlist, str, &evalue, &efound)); 7325f80ce2aSJacob Faibussowitsch if (efound) { 7334f572ea9SToby Isaac PetscAssertPointer(value, 3); 7345f80ce2aSJacob Faibussowitsch *value = (PetscEnum)evalue; 7355f80ce2aSJacob Faibussowitsch } 7365f80ce2aSJacob Faibussowitsch if (found) { 7374f572ea9SToby Isaac PetscAssertPointer(found, 4); 7385f80ce2aSJacob Faibussowitsch *found = efound; 7395f80ce2aSJacob Faibussowitsch } 7403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 741a53986e1SJed Brown } 742660278c0SBarry Smith 743660278c0SBarry Smith /*@C 744660278c0SBarry Smith PetscCIFilename - returns the basename of a file name when the PETSc CI portable error output mode is enabled. 745660278c0SBarry Smith 74620f4b53cSBarry Smith Not Collective; No Fortran Support 747660278c0SBarry Smith 748660278c0SBarry Smith Input Parameter: 749660278c0SBarry Smith . file - the file name 750660278c0SBarry Smith 751667f096bSBarry Smith Level: developer 752667f096bSBarry Smith 753660278c0SBarry Smith Note: 754660278c0SBarry Smith PETSc CI mode is a mode of running PETSc where output (both error and non-error) is made portable across all systems 755660278c0SBarry Smith so that comparisons of output between runs are easy to make. 756660278c0SBarry Smith 757660278c0SBarry Smith This mode is used for all tests in the test harness, it applies to both debug and optimized builds. 758660278c0SBarry Smith 759667f096bSBarry Smith Use the option `-petsc_ci` to turn on PETSc CI mode. It changes certain output in non-error situations to be portable for 760660278c0SBarry Smith all systems, mainly the output of options. It is passed to all PETSc programs automatically by the test harness. 761660278c0SBarry Smith 762660278c0SBarry Smith Always uses the Unix / as the file separate even on Microsoft Windows systems 763660278c0SBarry Smith 764667f096bSBarry Smith The option `-petsc_ci_portable_error_output` attempts to output the same error messages on all systems for the test harness. 765660278c0SBarry Smith In particular the output of filenames and line numbers in PETSc stacks. This is to allow (limited) checking of PETSc 766660278c0SBarry 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 767660278c0SBarry Smith harness can process the output for differences in the usual manner as for successful runs. It should be provided to the test 768da81f932SPierre Jolivet harness in the args: argument for specific examples. It will not necessarily produce portable output if different errors 769660278c0SBarry Smith (or no errors) occur on a subset of the MPI ranks. 770660278c0SBarry Smith 771660278c0SBarry Smith .seealso: `PetscCILinenumber()` 772660278c0SBarry Smith @*/ 773d71ae5a4SJacob Faibussowitsch const char *PetscCIFilename(const char *file) 774d71ae5a4SJacob Faibussowitsch { 775660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return file; 776660278c0SBarry Smith return PetscBasename(file); 777660278c0SBarry Smith } 778660278c0SBarry Smith 779660278c0SBarry Smith /*@C 780811af0c4SBarry Smith PetscCILinenumber - returns a line number except if `PetscCIEnablePortableErrorOutput` is set when it returns 0 781660278c0SBarry Smith 782667f096bSBarry Smith Not Collective; No Fortran Support 783660278c0SBarry Smith 784660278c0SBarry Smith Input Parameter: 785660278c0SBarry Smith . linenumber - the initial line number 786660278c0SBarry Smith 787667f096bSBarry Smith Level: developer 788667f096bSBarry Smith 789660278c0SBarry Smith Note: 790660278c0SBarry Smith See `PetscCIFilename()` for details on usage 791660278c0SBarry Smith 792660278c0SBarry Smith .seealso: `PetscCIFilename()` 793660278c0SBarry Smith @*/ 794d71ae5a4SJacob Faibussowitsch int PetscCILinenumber(int linenumber) 795d71ae5a4SJacob Faibussowitsch { 796660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return linenumber; 797660278c0SBarry Smith return 0; 798660278c0SBarry Smith } 799d11110bcSJacob Faibussowitsch 800d11110bcSJacob Faibussowitsch /*@C 801d11110bcSJacob Faibussowitsch PetscStrcat - Concatenates a string onto a given string 802d11110bcSJacob Faibussowitsch 803d11110bcSJacob Faibussowitsch Not Collective, No Fortran Support 804d11110bcSJacob Faibussowitsch 805d11110bcSJacob Faibussowitsch Input Parameters: 806d11110bcSJacob Faibussowitsch + s - string to be added to 807d11110bcSJacob Faibussowitsch - t - pointer to string to be added to end 808d11110bcSJacob Faibussowitsch 809d11110bcSJacob Faibussowitsch Level: deprecated (since 3.18.5) 810d11110bcSJacob Faibussowitsch 811d11110bcSJacob Faibussowitsch Notes: 812d11110bcSJacob Faibussowitsch It is recommended you use `PetscStrlcat()` instead of this routine. 813d11110bcSJacob Faibussowitsch 814d11110bcSJacob Faibussowitsch .seealso: `PetscStrlcat()` 815d11110bcSJacob Faibussowitsch @*/ 816d11110bcSJacob Faibussowitsch PetscErrorCode PetscStrcat(char s[], const char t[]) 817d11110bcSJacob Faibussowitsch { 818d11110bcSJacob Faibussowitsch PetscFunctionBegin; 819d11110bcSJacob Faibussowitsch if (!t) PetscFunctionReturn(PETSC_SUCCESS); 8204f572ea9SToby Isaac PetscAssertPointer(s, 1); 821d11110bcSJacob Faibussowitsch strcat(s, t); 822d11110bcSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 823d11110bcSJacob Faibussowitsch } 824d11110bcSJacob Faibussowitsch 825d11110bcSJacob Faibussowitsch /*@C 826d11110bcSJacob Faibussowitsch PetscStrcpy - Copies a string 827d11110bcSJacob Faibussowitsch 828d11110bcSJacob Faibussowitsch Not Collective, No Fortran Support 829d11110bcSJacob Faibussowitsch 8302fe279fdSBarry Smith Input Parameter: 831d11110bcSJacob Faibussowitsch . t - pointer to string 832d11110bcSJacob Faibussowitsch 833d11110bcSJacob Faibussowitsch Output Parameter: 834d11110bcSJacob Faibussowitsch . s - the copied string 835d11110bcSJacob Faibussowitsch 836d11110bcSJacob Faibussowitsch Level: deprecated (since 3.18.5) 837d11110bcSJacob Faibussowitsch 838d11110bcSJacob Faibussowitsch Notes: 839d11110bcSJacob Faibussowitsch It is recommended you use `PetscStrncpy()` (equivalently `PetscArraycpy()` or 840d11110bcSJacob Faibussowitsch `PetscMemcpy()`) instead of this routine. 841d11110bcSJacob Faibussowitsch 842d11110bcSJacob Faibussowitsch `NULL` strings returns a string starting with zero. 843d11110bcSJacob Faibussowitsch 844d11110bcSJacob Faibussowitsch .seealso: `PetscStrncpy()` 845d11110bcSJacob Faibussowitsch @*/ 846d11110bcSJacob Faibussowitsch PetscErrorCode PetscStrcpy(char s[], const char t[]) 847d11110bcSJacob Faibussowitsch { 848d11110bcSJacob Faibussowitsch PetscFunctionBegin; 849d11110bcSJacob Faibussowitsch if (t) { 8504f572ea9SToby Isaac PetscAssertPointer(s, 1); 8514f572ea9SToby Isaac PetscAssertPointer(t, 2); 852d11110bcSJacob Faibussowitsch strcpy(s, t); 853d11110bcSJacob Faibussowitsch } else if (s) { 854d11110bcSJacob Faibussowitsch s[0] = '\0'; 855d11110bcSJacob Faibussowitsch } 856d11110bcSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 857d11110bcSJacob Faibussowitsch } 858