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; 62dd460d27SBarry 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: 1470b4b7b1cSBarry Smith Use `PetscStrArrayDestroy()` to free the memory. 1480ecf5a55SBarry Smith 149811af0c4SBarry Smith .seealso: `PetscStrallocpy()`, `PetscStrArrayDestroy()`, `PetscStrNArrayallocpy()` 15047340559SBarry Smith @*/ 151d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrArrayallocpy(const char *const *list, char ***t) 152d71ae5a4SJacob Faibussowitsch { 1535f80ce2aSJacob Faibussowitsch PetscInt n = 0; 15447340559SBarry Smith 15547340559SBarry Smith PetscFunctionBegin; 156fbccb6d4SPierre Jolivet while (list[n++]); 1579566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n + 1, t)); 1589566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 1590298fd71SBarry Smith (*t)[n] = NULL; 1603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16147340559SBarry Smith } 16247340559SBarry Smith 16347340559SBarry Smith /*@C 164811af0c4SBarry Smith PetscStrArrayDestroy - Frees array of strings created with `PetscStrArrayallocpy()`. 16547340559SBarry Smith 166667f096bSBarry Smith Not Collective; No Fortran Support 16747340559SBarry Smith 1682fe279fdSBarry Smith Output Parameter: 16947340559SBarry Smith . list - array of strings 17047340559SBarry Smith 17147340559SBarry Smith Level: intermediate 17247340559SBarry Smith 173db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()` 17447340559SBarry Smith @*/ 175d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrArrayDestroy(char ***list) 176d71ae5a4SJacob Faibussowitsch { 17747340559SBarry Smith PetscInt n = 0; 17847340559SBarry Smith 1796fed8037SJed Brown PetscFunctionBegin; 1803ba16761SJacob Faibussowitsch if (!*list) PetscFunctionReturn(PETSC_SUCCESS); 1816fed8037SJed Brown while ((*list)[n]) { 1829566063dSJacob Faibussowitsch PetscCall(PetscFree((*list)[n])); 1835f80ce2aSJacob Faibussowitsch ++n; 18447340559SBarry Smith } 1859566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 1863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18747340559SBarry Smith } 18847340559SBarry Smith 1896991f827SBarry Smith /*@C 1906991f827SBarry Smith PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 1916991f827SBarry Smith 192667f096bSBarry Smith Not Collective; No Fortran Support 1936991f827SBarry Smith 1946991f827SBarry Smith Input Parameters: 1956991f827SBarry Smith + n - the number of string entries 196aec76313SJacob Faibussowitsch - list - pointer to array of strings 1976991f827SBarry Smith 1986991f827SBarry Smith Output Parameter: 1996991f827SBarry Smith . t - the copied array string 2006991f827SBarry Smith 2016991f827SBarry Smith Level: intermediate 2026991f827SBarry Smith 2030b4b7b1cSBarry Smith Note: 2040b4b7b1cSBarry Smith Use `PetscStrNArrayDestroy()` to free the memory. 2050b4b7b1cSBarry Smith 206db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayallocpy()`, `PetscStrNArrayDestroy()` 2076991f827SBarry Smith @*/ 208d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrNArrayallocpy(PetscInt n, const char *const *list, char ***t) 209d71ae5a4SJacob Faibussowitsch { 2106991f827SBarry Smith PetscFunctionBegin; 2119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, t)); 2129566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscStrallocpy(list[i], (*t) + i)); 2133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2146991f827SBarry Smith } 2156991f827SBarry Smith 2166991f827SBarry Smith /*@C 217811af0c4SBarry Smith PetscStrNArrayDestroy - Frees array of strings created with `PetscStrNArrayallocpy()`. 2186991f827SBarry Smith 219667f096bSBarry Smith Not Collective; No Fortran Support 2206991f827SBarry Smith 2216991f827SBarry Smith Output Parameters: 2226991f827SBarry Smith + n - number of string entries 2236991f827SBarry Smith - list - array of strings 2246991f827SBarry Smith 2256991f827SBarry Smith Level: intermediate 2266991f827SBarry Smith 227811af0c4SBarry Smith .seealso: `PetscStrNArrayallocpy()`, `PetscStrArrayallocpy()` 2286991f827SBarry Smith @*/ 229d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrNArrayDestroy(PetscInt n, char ***list) 230d71ae5a4SJacob Faibussowitsch { 2316991f827SBarry Smith PetscFunctionBegin; 2323ba16761SJacob Faibussowitsch if (!*list) PetscFunctionReturn(PETSC_SUCCESS); 2339566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(PetscFree((*list)[i])); 2349566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 2353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2366991f827SBarry Smith } 2376991f827SBarry Smith 238e5c89e4eSSatish Balay /*@C 239811af0c4SBarry Smith PetscBasename - returns a pointer to the last entry of a / or \ separated directory path 24080b92c66SBarry Smith 241667f096bSBarry Smith Not Collective; No Fortran Support 24280b92c66SBarry Smith 24380b92c66SBarry Smith Input Parameter: 24480b92c66SBarry Smith . a - pointer to string 24580b92c66SBarry Smith 24680b92c66SBarry Smith Level: intermediate 24780b92c66SBarry Smith 24880b92c66SBarry Smith .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`, `PetscStrrchr()`, `PetscStrcmp()`, `PetscStrstr()`, 24980b92c66SBarry Smith `PetscTokenCreate()`, `PetscStrToArray()`, `PetscStrInList()` 25080b92c66SBarry Smith @*/ 251d71ae5a4SJacob Faibussowitsch const char *PetscBasename(const char a[]) 252d71ae5a4SJacob Faibussowitsch { 253bbcf679cSJacob Faibussowitsch const char *ptr = NULL; 25480b92c66SBarry Smith 255bbcf679cSJacob Faibussowitsch (void)PetscStrrchr(a, '/', (char **)&ptr); 256660278c0SBarry Smith if (ptr == a) { 257660278c0SBarry Smith if (PetscStrrchr(a, '\\', (char **)&ptr)) ptr = NULL; 258660278c0SBarry Smith } 25980b92c66SBarry Smith return ptr; 26080b92c66SBarry Smith } 26180b92c66SBarry Smith 26280b92c66SBarry Smith /*@C 263e5c89e4eSSatish Balay PetscStrcasecmp - Returns true if the two strings are the same 264e5c89e4eSSatish Balay except possibly for case. 265e5c89e4eSSatish Balay 266667f096bSBarry Smith Not Collective; No Fortran Support 267e5c89e4eSSatish Balay 268e5c89e4eSSatish Balay Input Parameters: 269e5c89e4eSSatish Balay + a - pointer to first string 270e5c89e4eSSatish Balay - b - pointer to second string 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay Output Parameter: 273aec76313SJacob Faibussowitsch . t - if the two strings are the same 274e5c89e4eSSatish Balay 275e5c89e4eSSatish Balay Level: intermediate 276e5c89e4eSSatish Balay 277667f096bSBarry Smith Note: 278667f096bSBarry Smith `NULL` arguments are ok 279667f096bSBarry Smith 280db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrgrt()` 281e5c89e4eSSatish Balay @*/ 282d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrcasecmp(const char a[], const char b[], PetscBool *t) 283d71ae5a4SJacob Faibussowitsch { 284e5c89e4eSSatish Balay int c; 285e5c89e4eSSatish Balay 286e5c89e4eSSatish Balay PetscFunctionBegin; 2874f572ea9SToby Isaac PetscAssertPointer(t, 3); 288e5c89e4eSSatish Balay if (!a && !b) c = 0; 289e5c89e4eSSatish Balay else if (!a || !b) c = 1; 29032b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP) 29132b366c8SSatish Balay else c = strcasecmp(a, b); 29232b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP) 293e5c89e4eSSatish Balay else c = stricmp(a, b); 294e5c89e4eSSatish Balay #else 29532b366c8SSatish Balay else { 29632b366c8SSatish Balay char *aa, *bb; 297bbcf679cSJacob Faibussowitsch 2989566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &aa)); 2999566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(b, &bb)); 3009566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(aa)); 3019566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(bb)); 3029566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(aa, bb, t)); 3039566063dSJacob Faibussowitsch PetscCall(PetscFree(aa)); 3049566063dSJacob Faibussowitsch PetscCall(PetscFree(bb)); 3053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30632b366c8SSatish Balay } 307e5c89e4eSSatish Balay #endif 3085f80ce2aSJacob Faibussowitsch *t = c ? PETSC_FALSE : PETSC_TRUE; 3093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 310e5c89e4eSSatish Balay } 311e5c89e4eSSatish Balay 312e5c89e4eSSatish Balay /*@C 3137ba3a57cSBarry Smith PetscStrendswithwhich - Determines if a string ends with one of several possible strings 3147ba3a57cSBarry Smith 315667f096bSBarry Smith Not Collective; No Fortran Support 3167ba3a57cSBarry Smith 3177ba3a57cSBarry Smith Input Parameters: 3187ba3a57cSBarry Smith + a - pointer to string 319667f096bSBarry Smith - bs - strings to end with (last entry must be `NULL`) 3207ba3a57cSBarry Smith 3217ba3a57cSBarry Smith Output Parameter: 322667f096bSBarry Smith . cnt - the index of the string it ends with or the index of `NULL` 3237ba3a57cSBarry Smith 3247ba3a57cSBarry Smith Level: intermediate 3257ba3a57cSBarry Smith 326811af0c4SBarry Smith .seealso: `PetscStrbeginswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 327aec76313SJacob Faibussowitsch `PetscStrncmp()`, `PetscStrlen()`, `PetscStrcmp()` 3287ba3a57cSBarry Smith @*/ 329d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrendswithwhich(const char a[], const char *const *bs, PetscInt *cnt) 330d71ae5a4SJacob Faibussowitsch { 3317ba3a57cSBarry Smith PetscFunctionBegin; 3324f572ea9SToby Isaac PetscAssertPointer(bs, 2); 3334f572ea9SToby Isaac PetscAssertPointer(cnt, 3); 3347ba3a57cSBarry Smith *cnt = 0; 3357ba3a57cSBarry Smith while (bs[*cnt]) { 3365f80ce2aSJacob Faibussowitsch PetscBool flg; 3375f80ce2aSJacob Faibussowitsch 3389566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(a, bs[*cnt], &flg)); 3393ba16761SJacob Faibussowitsch if (flg) PetscFunctionReturn(PETSC_SUCCESS); 3405f80ce2aSJacob Faibussowitsch ++(*cnt); 3417ba3a57cSBarry Smith } 3423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3437ba3a57cSBarry Smith } 3447ba3a57cSBarry Smith 3459371c9d4SSatish Balay struct _p_PetscToken { 3469371c9d4SSatish Balay char token; 3479371c9d4SSatish Balay char *array; 3489371c9d4SSatish Balay char *current; 3499371c9d4SSatish Balay }; 3501d1a0024SBarry Smith 351e5c89e4eSSatish Balay /*@C 352667f096bSBarry Smith PetscTokenFind - Locates next "token" in a `PetscToken` 353e5c89e4eSSatish Balay 354667f096bSBarry Smith Not Collective; No Fortran Support 355e5c89e4eSSatish Balay 3562fe279fdSBarry Smith Input Parameter: 357e5c89e4eSSatish Balay . a - pointer to token 358e5c89e4eSSatish Balay 359e5c89e4eSSatish Balay Output Parameter: 360667f096bSBarry Smith . result - location of occurrence, `NULL` if not found 3616f013253SBarry Smith 362e5c89e4eSSatish Balay Level: intermediate 363e5c89e4eSSatish Balay 364667f096bSBarry Smith Notes: 365667f096bSBarry Smith Treats all characters etc. inside a double quote " 366667f096bSBarry Smith as a single token. 367667f096bSBarry Smith 368667f096bSBarry 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 369667f096bSBarry Smith second will return a `NULL` terminated y 370667f096bSBarry Smith 371667f096bSBarry 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 372667f096bSBarry Smith 373667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenCreate()`, `PetscTokenDestroy()` 374e5c89e4eSSatish Balay @*/ 375d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenFind(PetscToken a, char *result[]) 376d71ae5a4SJacob Faibussowitsch { 3775f80ce2aSJacob Faibussowitsch char *ptr, token; 378e5c89e4eSSatish Balay 379e5c89e4eSSatish Balay PetscFunctionBegin; 3804f572ea9SToby Isaac PetscAssertPointer(a, 1); 3814f572ea9SToby Isaac PetscAssertPointer(result, 2); 3825f80ce2aSJacob Faibussowitsch *result = ptr = a->current; 3839371c9d4SSatish Balay if (ptr && !*ptr) { 3849371c9d4SSatish Balay *result = NULL; 3853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3869371c9d4SSatish Balay } 3874704e885SBarry Smith token = a->token; 3889371c9d4SSatish Balay if (ptr && (*ptr == '"')) { 3899371c9d4SSatish Balay token = '"'; 3909371c9d4SSatish Balay (*result)++; 3919371c9d4SSatish Balay ptr++; 3929371c9d4SSatish Balay } 393e5c89e4eSSatish Balay while (ptr) { 3944704e885SBarry Smith if (*ptr == token) { 395e5c89e4eSSatish Balay *ptr++ = 0; 396e5c89e4eSSatish Balay while (*ptr == a->token) ptr++; 397e5c89e4eSSatish Balay a->current = ptr; 398e5c89e4eSSatish Balay break; 399e5c89e4eSSatish Balay } 400e5c89e4eSSatish Balay if (!*ptr) { 40102c9f0b5SLisandro Dalcin a->current = NULL; 402e5c89e4eSSatish Balay break; 403e5c89e4eSSatish Balay } 404e5c89e4eSSatish Balay ptr++; 405e5c89e4eSSatish Balay } 4063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 407e5c89e4eSSatish Balay } 408e5c89e4eSSatish Balay 409e5c89e4eSSatish Balay /*@C 410811af0c4SBarry Smith PetscTokenCreate - Creates a `PetscToken` used to find tokens in a string 411e5c89e4eSSatish Balay 412667f096bSBarry Smith Not Collective; No Fortran Support 413e5c89e4eSSatish Balay 414e5c89e4eSSatish Balay Input Parameters: 415aec76313SJacob Faibussowitsch + a - the string to look in 4163a9c465aSBarry Smith - b - the separator character 417e5c89e4eSSatish Balay 418e5c89e4eSSatish Balay Output Parameter: 4193a9c465aSBarry Smith . t - the token object 420e5c89e4eSSatish Balay 421667f096bSBarry Smith Level: intermediate 422667f096bSBarry Smith 423811af0c4SBarry Smith Note: 424e5c89e4eSSatish Balay This version is different from the system version in that 425e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 426e5c89e4eSSatish Balay 427667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenFind()`, `PetscTokenDestroy()` 428e5c89e4eSSatish Balay @*/ 42998e514b7SJacob Faibussowitsch PetscErrorCode PetscTokenCreate(const char a[], char b, PetscToken *t) 430d71ae5a4SJacob Faibussowitsch { 431e5c89e4eSSatish Balay PetscFunctionBegin; 4324f572ea9SToby Isaac PetscAssertPointer(a, 1); 4334f572ea9SToby Isaac PetscAssertPointer(t, 3); 4349566063dSJacob Faibussowitsch PetscCall(PetscNew(t)); 4359566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &(*t)->array)); 436a297a907SKarl Rupp 437e5c89e4eSSatish Balay (*t)->current = (*t)->array; 438e5c89e4eSSatish Balay (*t)->token = b; 4393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 440e5c89e4eSSatish Balay } 441e5c89e4eSSatish Balay 442e5c89e4eSSatish Balay /*@C 443811af0c4SBarry Smith PetscTokenDestroy - Destroys a `PetscToken` 444e5c89e4eSSatish Balay 445667f096bSBarry Smith Not Collective; No Fortran Support 446e5c89e4eSSatish Balay 4472fe279fdSBarry Smith Input Parameter: 448e5c89e4eSSatish Balay . a - pointer to token 449e5c89e4eSSatish Balay 450e5c89e4eSSatish Balay Level: intermediate 451e5c89e4eSSatish Balay 452667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenCreate()`, `PetscTokenFind()` 453e5c89e4eSSatish Balay @*/ 454d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenDestroy(PetscToken *a) 455d71ae5a4SJacob Faibussowitsch { 456e5c89e4eSSatish Balay PetscFunctionBegin; 4573ba16761SJacob Faibussowitsch if (!*a) PetscFunctionReturn(PETSC_SUCCESS); 4589566063dSJacob Faibussowitsch PetscCall(PetscFree((*a)->array)); 4599566063dSJacob Faibussowitsch PetscCall(PetscFree(*a)); 4603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 461e5c89e4eSSatish Balay } 462e5c89e4eSSatish Balay 4638e81d068SLisandro Dalcin /*@C 464667f096bSBarry Smith PetscStrInList - search for a string in character-delimited list 4658e81d068SLisandro Dalcin 466667f096bSBarry Smith Not Collective; No Fortran Support 4678e81d068SLisandro Dalcin 4688e81d068SLisandro Dalcin Input Parameters: 4698e81d068SLisandro Dalcin + str - the string to look for 4708e81d068SLisandro Dalcin . list - the list to search in 4718e81d068SLisandro Dalcin - sep - the separator character 4728e81d068SLisandro Dalcin 4738e81d068SLisandro Dalcin Output Parameter: 474667f096bSBarry Smith . found - whether `str` is in `list` 4758e81d068SLisandro Dalcin 4768e81d068SLisandro Dalcin Level: intermediate 4778e81d068SLisandro Dalcin 478db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscStrcmp()` 4798e81d068SLisandro Dalcin @*/ 480d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found) 481d71ae5a4SJacob Faibussowitsch { 4828e81d068SLisandro Dalcin PetscToken token; 4838e81d068SLisandro Dalcin char *item; 4848e81d068SLisandro Dalcin 4858e81d068SLisandro Dalcin PetscFunctionBegin; 4864f572ea9SToby Isaac PetscAssertPointer(found, 4); 4878e81d068SLisandro Dalcin *found = PETSC_FALSE; 4889566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(list, sep, &token)); 4899566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 4908e81d068SLisandro Dalcin while (item) { 4919566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(str, item, found)); 4928e81d068SLisandro Dalcin if (*found) break; 4939566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item)); 4948e81d068SLisandro Dalcin } 4959566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 4963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4978e81d068SLisandro Dalcin } 498e5c89e4eSSatish Balay 499e5c89e4eSSatish Balay /*@C 500e5c89e4eSSatish Balay PetscGetPetscDir - Gets the directory PETSc is installed in 501e5c89e4eSSatish Balay 502667f096bSBarry Smith Not Collective; No Fortran Support 503e5c89e4eSSatish Balay 504e5c89e4eSSatish Balay Output Parameter: 505e5c89e4eSSatish Balay . dir - the directory 506e5c89e4eSSatish Balay 507e5c89e4eSSatish Balay Level: developer 508e5c89e4eSSatish Balay 50910450e9eSJacob Faibussowitsch .seealso: `PetscGetArchType()` 510e5c89e4eSSatish Balay @*/ 511d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetPetscDir(const char *dir[]) 512d71ae5a4SJacob Faibussowitsch { 513e5c89e4eSSatish Balay PetscFunctionBegin; 5144f572ea9SToby Isaac PetscAssertPointer(dir, 1); 515e5c89e4eSSatish Balay *dir = PETSC_DIR; 5163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 517e5c89e4eSSatish Balay } 518e5c89e4eSSatish Balay 519e5c89e4eSSatish Balay /*@C 520e5c89e4eSSatish Balay PetscStrreplace - Replaces substrings in string with other substrings 521e5c89e4eSSatish Balay 522667f096bSBarry Smith Not Collective; No Fortran Support 523e5c89e4eSSatish Balay 524e5c89e4eSSatish Balay Input Parameters: 525811af0c4SBarry Smith + comm - `MPI_Comm` of processors that are processing the string 52671573d7dSBarry Smith . aa - the string to look in 527667f096bSBarry Smith . b - the resulting copy of a with replaced strings (`b` can be the same as `a`) 528667f096bSBarry Smith - len - the length of `b` 529e5c89e4eSSatish Balay 5302fe279fdSBarry Smith Level: developer 5312fe279fdSBarry Smith 532e5c89e4eSSatish Balay Notes: 533*873f9891SMatthew Knepley Replaces 534*873f9891SMatthew Knepley .vb 535*873f9891SMatthew Knepley ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, ${DISPLAY}, 536*873f9891SMatthew Knepley ${HOMEDIRECTORY}, ${WORKINGDIRECTORY}, ${USERNAME}, ${HOSTNAME}, ${PETSC_MAKE} 537*873f9891SMatthew Knepley .ve 538*873f9891SMatthew Knepley with appropriate values as well as any environmental variables. 539e5c89e4eSSatish Balay 540811af0c4SBarry Smith `PETSC_LIB_DIR` uses the environmental variable if it exists. `PETSC_ARCH` and `PETSC_DIR` use what 541acc6cc86SBarry Smith PETSc was built with and do not use environmental variables. 542acc6cc86SBarry Smith 54310450e9eSJacob Faibussowitsch .seealso: `PetscStrcmp()` 544e5c89e4eSSatish Balay @*/ 545d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len) 546d71ae5a4SJacob Faibussowitsch { 547e5c89e4eSSatish Balay int i = 0; 548e5c89e4eSSatish Balay size_t l, l1, l2, l3; 5497864358aSSatish Balay char *work, *par, *epar = NULL, env[1024], *tfree, *a = (char *)aa; 550f236b2adSBarry Smith const char *s[] = {"${PETSC_ARCH}", "${PETSC_DIR}", "${PETSC_LIB_DIR}", "${DISPLAY}", "${HOMEDIRECTORY}", "${WORKINGDIRECTORY}", "${USERNAME}", "${HOSTNAME}", "${PETSC_MAKE}", NULL}; 551f236b2adSBarry Smith char *r[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 552ace3abfcSBarry Smith PetscBool flag; 553589a23caSBarry Smith static size_t DISPLAY_LENGTH = 265, USER_LENGTH = 256, HOST_LENGTH = 256; 554e5c89e4eSSatish Balay 555e5c89e4eSSatish Balay PetscFunctionBegin; 5564f572ea9SToby Isaac PetscAssertPointer(aa, 2); 5574f572ea9SToby Isaac PetscAssertPointer(b, 3); 5589566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscStrallocpy(aa, (char **)&a)); 5599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len, &work)); 560e5c89e4eSSatish Balay 561e5c89e4eSSatish Balay /* get values for replaced variables */ 5629566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_ARCH, &r[0])); 5639566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_DIR, &r[1])); 5649566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_LIB_DIR, &r[2])); 5659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(DISPLAY_LENGTH, &r[3])); 5669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[4])); 5679566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[5])); 5689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(USER_LENGTH, &r[6])); 5699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(HOST_LENGTH, &r[7])); 5709566063dSJacob Faibussowitsch PetscCall(PetscGetDisplay(r[3], DISPLAY_LENGTH)); 5719566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(r[4], PETSC_MAX_PATH_LEN)); 5729566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(r[5], PETSC_MAX_PATH_LEN)); 5739566063dSJacob Faibussowitsch PetscCall(PetscGetUserName(r[6], USER_LENGTH)); 5749566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(r[7], HOST_LENGTH)); 575f236b2adSBarry Smith PetscCall(PetscStrallocpy(PETSC_OMAKE, &r[8])); 576487e5849SBarry Smith 577487e5849SBarry Smith /* replace that are in environment */ 5789566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_LIB_DIR", env, sizeof(env), &flag)); 579487e5849SBarry Smith if (flag) { 5809566063dSJacob Faibussowitsch PetscCall(PetscFree(r[2])); 5819566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(env, &r[2])); 582487e5849SBarry Smith } 583e5c89e4eSSatish Balay 584e5c89e4eSSatish Balay /* replace the requested strings */ 5859566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, a, len)); 586e5c89e4eSSatish Balay while (s[i]) { 5879566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s[i], &l)); 5889566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 589e5c89e4eSSatish Balay while (par) { 590e5c89e4eSSatish Balay *par = 0; 591e5c89e4eSSatish Balay par += l; 592e5c89e4eSSatish Balay 5939566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b, &l1)); 5949566063dSJacob Faibussowitsch PetscCall(PetscStrlen(r[i], &l2)); 5959566063dSJacob Faibussowitsch PetscCall(PetscStrlen(par, &l3)); 596cc73adaaSBarry Smith PetscCheck(l1 + l2 + l3 < len, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "b len is not long enough to hold new values"); 5979566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 5989566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, r[i], len)); 5999566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, par, len)); 6009566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 6019566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par)); 602e5c89e4eSSatish Balay } 603e5c89e4eSSatish Balay i++; 604e5c89e4eSSatish Balay } 605487e5849SBarry Smith i = 0; 606487e5849SBarry Smith while (r[i]) { 607e5c89e4eSSatish Balay tfree = (char *)r[i]; 6089566063dSJacob Faibussowitsch PetscCall(PetscFree(tfree)); 609487e5849SBarry Smith i++; 610e5c89e4eSSatish Balay } 611e5c89e4eSSatish Balay 612e5c89e4eSSatish Balay /* look for any other ${xxx} strings to replace from environmental variables */ 6139566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 614e5c89e4eSSatish Balay while (par) { 615e5c89e4eSSatish Balay *par = 0; 616e5c89e4eSSatish Balay par += 2; 6179566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len)); 6189566063dSJacob Faibussowitsch PetscCall(PetscStrstr(par, "}", &epar)); 619e5c89e4eSSatish Balay *epar = 0; 620e5c89e4eSSatish Balay epar += 1; 6219566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, par, env, sizeof(env), &flag)); 62228b400f6SJacob Faibussowitsch PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Substitution string ${%s} not found as environmental variable", par); 6239566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, env, len)); 6249566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, epar, len)); 6259566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len)); 6269566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par)); 627e5c89e4eSSatish Balay } 6289566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 6299566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscFree(a)); 6303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 631e5c89e4eSSatish Balay } 632e5c89e4eSSatish Balay 633a53986e1SJed Brown /*@C 634c0d8b5b9SStefano Zampini PetscStrcmpAny - Determines whether a string matches any of a list of strings. 635c0d8b5b9SStefano Zampini 636cc4c1da9SBarry Smith Not Collective, No Fortran Support 637c0d8b5b9SStefano Zampini 638c0d8b5b9SStefano Zampini Input Parameters: 639c0d8b5b9SStefano Zampini + src - pointer to input the string 640c0d8b5b9SStefano Zampini - cmp - list of non-null and non-empty strings to be compared against, pass the empty string "" to terminate the list 641c0d8b5b9SStefano Zampini 642c0d8b5b9SStefano Zampini Output Parameter: 643c0d8b5b9SStefano Zampini . match - `PETSC_TRUE` if the input string matches any in the list, else `PETSC_FALSE` 644c0d8b5b9SStefano Zampini 645c0d8b5b9SStefano Zampini Level: intermediate 646c0d8b5b9SStefano Zampini 64710450e9eSJacob Faibussowitsch .seealso: `PetscStrcmp()` 648c0d8b5b9SStefano Zampini @*/ 649c0d8b5b9SStefano Zampini PetscErrorCode PetscStrcmpAny(const char src[], PetscBool *match, const char cmp[], ...) 650c0d8b5b9SStefano Zampini { 651c0d8b5b9SStefano Zampini va_list Argp; 652c0d8b5b9SStefano Zampini 653c0d8b5b9SStefano Zampini PetscFunctionBegin; 6544f572ea9SToby Isaac PetscAssertPointer(match, 2); 655c0d8b5b9SStefano Zampini *match = PETSC_FALSE; 656c0d8b5b9SStefano Zampini if (!src) PetscFunctionReturn(PETSC_SUCCESS); 657c0d8b5b9SStefano Zampini va_start(Argp, cmp); 658c0d8b5b9SStefano Zampini while (cmp && cmp[0]) { 659c0d8b5b9SStefano Zampini PetscBool found; 660c0d8b5b9SStefano Zampini PetscCall(PetscStrcmp(src, cmp, &found)); 661c0d8b5b9SStefano Zampini if (found) { 662c0d8b5b9SStefano Zampini *match = PETSC_TRUE; 663c0d8b5b9SStefano Zampini break; 664c0d8b5b9SStefano Zampini } 665c0d8b5b9SStefano Zampini cmp = va_arg(Argp, const char *); 666c0d8b5b9SStefano Zampini } 667c0d8b5b9SStefano Zampini va_end(Argp); 668c0d8b5b9SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 669c0d8b5b9SStefano Zampini } 670c0d8b5b9SStefano Zampini 671c0d8b5b9SStefano Zampini /*@C 672a53986e1SJed Brown PetscEListFind - searches list of strings for given string, using case insensitive matching 673e5c89e4eSSatish Balay 674667f096bSBarry Smith Not Collective; No Fortran Support 675a53986e1SJed Brown 676a53986e1SJed Brown Input Parameters: 677a53986e1SJed Brown + n - number of strings in 678a53986e1SJed Brown . list - list of strings to search 679a53986e1SJed Brown - str - string to look for, empty string "" accepts default (first entry in list) 680a53986e1SJed Brown 681a53986e1SJed Brown Output Parameters: 682a53986e1SJed Brown + value - index of matching string (if found) 683667f096bSBarry Smith - found - boolean indicating whether string was found (can be `NULL`) 684811af0c4SBarry Smith 68553c0d4aeSBarry Smith Level: developer 68653c0d4aeSBarry Smith 687811af0c4SBarry Smith .seealso: `PetscEnumFind()` 688a53986e1SJed Brown @*/ 689d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found) 690d71ae5a4SJacob Faibussowitsch { 691a53986e1SJed Brown PetscFunctionBegin; 6925f80ce2aSJacob Faibussowitsch if (found) { 6934f572ea9SToby Isaac PetscAssertPointer(found, 5); 6945f80ce2aSJacob Faibussowitsch *found = PETSC_FALSE; 6955f80ce2aSJacob Faibussowitsch } 6965f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 6975f80ce2aSJacob Faibussowitsch PetscBool matched; 6985f80ce2aSJacob Faibussowitsch 6999566063dSJacob Faibussowitsch PetscCall(PetscStrcasecmp(str, list[i], &matched)); 700a53986e1SJed Brown if (matched || !str[0]) { 701a53986e1SJed Brown if (found) *found = PETSC_TRUE; 702a53986e1SJed Brown *value = i; 703a53986e1SJed Brown break; 704a53986e1SJed Brown } 705a53986e1SJed Brown } 7063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 707a53986e1SJed Brown } 708a53986e1SJed Brown 709a53986e1SJed Brown /*@C 7108e81d068SLisandro Dalcin PetscEnumFind - searches enum list of strings for given string, using case insensitive matching 711a53986e1SJed Brown 712667f096bSBarry Smith Not Collective; No Fortran Support 713a53986e1SJed Brown 714a53986e1SJed Brown Input Parameters: 715667f096bSBarry Smith + enumlist - list of strings to search, followed by enum name, then enum prefix, then `NULL` 716a53986e1SJed Brown - str - string to look for 717a53986e1SJed Brown 718a53986e1SJed Brown Output Parameters: 719a53986e1SJed Brown + value - index of matching string (if found) 720667f096bSBarry Smith - found - boolean indicating whether string was found (can be `NULL`) 721a53986e1SJed Brown 722a53986e1SJed Brown Level: advanced 723811af0c4SBarry Smith 724811af0c4SBarry Smith .seealso: `PetscEListFind()` 725a53986e1SJed Brown @*/ 726d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found) 727d71ae5a4SJacob Faibussowitsch { 728d05ba7d2SLisandro Dalcin PetscInt n = 0, evalue; 729a53986e1SJed Brown PetscBool efound; 730a53986e1SJed Brown 731a53986e1SJed Brown PetscFunctionBegin; 7324f572ea9SToby Isaac PetscAssertPointer(enumlist, 1); 7335f80ce2aSJacob 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"); 7345f80ce2aSJacob Faibussowitsch PetscCheck(n >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix"); 735a53986e1SJed Brown n -= 3; /* drop enum name, prefix, and null termination */ 7369566063dSJacob Faibussowitsch PetscCall(PetscEListFind(n, enumlist, str, &evalue, &efound)); 7375f80ce2aSJacob Faibussowitsch if (efound) { 7384f572ea9SToby Isaac PetscAssertPointer(value, 3); 7395f80ce2aSJacob Faibussowitsch *value = (PetscEnum)evalue; 7405f80ce2aSJacob Faibussowitsch } 7415f80ce2aSJacob Faibussowitsch if (found) { 7424f572ea9SToby Isaac PetscAssertPointer(found, 4); 7435f80ce2aSJacob Faibussowitsch *found = efound; 7445f80ce2aSJacob Faibussowitsch } 7453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 746a53986e1SJed Brown } 747660278c0SBarry Smith 748660278c0SBarry Smith /*@C 749660278c0SBarry Smith PetscCIFilename - returns the basename of a file name when the PETSc CI portable error output mode is enabled. 750660278c0SBarry Smith 75120f4b53cSBarry Smith Not Collective; No Fortran Support 752660278c0SBarry Smith 753660278c0SBarry Smith Input Parameter: 754660278c0SBarry Smith . file - the file name 755660278c0SBarry Smith 756667f096bSBarry Smith Level: developer 757667f096bSBarry Smith 758660278c0SBarry Smith Note: 759660278c0SBarry Smith PETSc CI mode is a mode of running PETSc where output (both error and non-error) is made portable across all systems 760660278c0SBarry Smith so that comparisons of output between runs are easy to make. 761660278c0SBarry Smith 762660278c0SBarry Smith This mode is used for all tests in the test harness, it applies to both debug and optimized builds. 763660278c0SBarry Smith 764667f096bSBarry Smith Use the option `-petsc_ci` to turn on PETSc CI mode. It changes certain output in non-error situations to be portable for 765660278c0SBarry Smith all systems, mainly the output of options. It is passed to all PETSc programs automatically by the test harness. 766660278c0SBarry Smith 767660278c0SBarry Smith Always uses the Unix / as the file separate even on Microsoft Windows systems 768660278c0SBarry Smith 769667f096bSBarry Smith The option `-petsc_ci_portable_error_output` attempts to output the same error messages on all systems for the test harness. 770660278c0SBarry Smith In particular the output of filenames and line numbers in PETSc stacks. This is to allow (limited) checking of PETSc 771660278c0SBarry 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 772660278c0SBarry Smith harness can process the output for differences in the usual manner as for successful runs. It should be provided to the test 773da81f932SPierre Jolivet harness in the args: argument for specific examples. It will not necessarily produce portable output if different errors 774660278c0SBarry Smith (or no errors) occur on a subset of the MPI ranks. 775660278c0SBarry Smith 776660278c0SBarry Smith .seealso: `PetscCILinenumber()` 777660278c0SBarry Smith @*/ 778d71ae5a4SJacob Faibussowitsch const char *PetscCIFilename(const char *file) 779d71ae5a4SJacob Faibussowitsch { 780660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return file; 781660278c0SBarry Smith return PetscBasename(file); 782660278c0SBarry Smith } 783660278c0SBarry Smith 784660278c0SBarry Smith /*@C 785811af0c4SBarry Smith PetscCILinenumber - returns a line number except if `PetscCIEnablePortableErrorOutput` is set when it returns 0 786660278c0SBarry Smith 787667f096bSBarry Smith Not Collective; No Fortran Support 788660278c0SBarry Smith 789660278c0SBarry Smith Input Parameter: 790660278c0SBarry Smith . linenumber - the initial line number 791660278c0SBarry Smith 792667f096bSBarry Smith Level: developer 793667f096bSBarry Smith 794660278c0SBarry Smith Note: 795660278c0SBarry Smith See `PetscCIFilename()` for details on usage 796660278c0SBarry Smith 797660278c0SBarry Smith .seealso: `PetscCIFilename()` 798660278c0SBarry Smith @*/ 799d71ae5a4SJacob Faibussowitsch int PetscCILinenumber(int linenumber) 800d71ae5a4SJacob Faibussowitsch { 801660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return linenumber; 802660278c0SBarry Smith return 0; 803660278c0SBarry Smith } 804d11110bcSJacob Faibussowitsch 805d11110bcSJacob Faibussowitsch /*@C 806d11110bcSJacob Faibussowitsch PetscStrcat - Concatenates a string onto a given string 807d11110bcSJacob Faibussowitsch 808d11110bcSJacob Faibussowitsch Not Collective, No Fortran Support 809d11110bcSJacob Faibussowitsch 810d11110bcSJacob Faibussowitsch Input Parameters: 811d11110bcSJacob Faibussowitsch + s - string to be added to 812d11110bcSJacob Faibussowitsch - t - pointer to string to be added to end 813d11110bcSJacob Faibussowitsch 814d11110bcSJacob Faibussowitsch Level: deprecated (since 3.18.5) 815d11110bcSJacob Faibussowitsch 816d11110bcSJacob Faibussowitsch Notes: 817d11110bcSJacob Faibussowitsch It is recommended you use `PetscStrlcat()` instead of this routine. 818d11110bcSJacob Faibussowitsch 819d11110bcSJacob Faibussowitsch .seealso: `PetscStrlcat()` 820d11110bcSJacob Faibussowitsch @*/ 821d11110bcSJacob Faibussowitsch PetscErrorCode PetscStrcat(char s[], const char t[]) 822d11110bcSJacob Faibussowitsch { 823d11110bcSJacob Faibussowitsch PetscFunctionBegin; 824d11110bcSJacob Faibussowitsch if (!t) PetscFunctionReturn(PETSC_SUCCESS); 8254f572ea9SToby Isaac PetscAssertPointer(s, 1); 826d11110bcSJacob Faibussowitsch strcat(s, t); 827d11110bcSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 828d11110bcSJacob Faibussowitsch } 829d11110bcSJacob Faibussowitsch 830d11110bcSJacob Faibussowitsch /*@C 831d11110bcSJacob Faibussowitsch PetscStrcpy - Copies a string 832d11110bcSJacob Faibussowitsch 833d11110bcSJacob Faibussowitsch Not Collective, No Fortran Support 834d11110bcSJacob Faibussowitsch 8352fe279fdSBarry Smith Input Parameter: 836d11110bcSJacob Faibussowitsch . t - pointer to string 837d11110bcSJacob Faibussowitsch 838d11110bcSJacob Faibussowitsch Output Parameter: 839d11110bcSJacob Faibussowitsch . s - the copied string 840d11110bcSJacob Faibussowitsch 841d11110bcSJacob Faibussowitsch Level: deprecated (since 3.18.5) 842d11110bcSJacob Faibussowitsch 843d11110bcSJacob Faibussowitsch Notes: 844d11110bcSJacob Faibussowitsch It is recommended you use `PetscStrncpy()` (equivalently `PetscArraycpy()` or 845d11110bcSJacob Faibussowitsch `PetscMemcpy()`) instead of this routine. 846d11110bcSJacob Faibussowitsch 847d11110bcSJacob Faibussowitsch `NULL` strings returns a string starting with zero. 848d11110bcSJacob Faibussowitsch 849d11110bcSJacob Faibussowitsch .seealso: `PetscStrncpy()` 850d11110bcSJacob Faibussowitsch @*/ 851d11110bcSJacob Faibussowitsch PetscErrorCode PetscStrcpy(char s[], const char t[]) 852d11110bcSJacob Faibussowitsch { 853d11110bcSJacob Faibussowitsch PetscFunctionBegin; 854d11110bcSJacob Faibussowitsch if (t) { 8554f572ea9SToby Isaac PetscAssertPointer(s, 1); 8564f572ea9SToby Isaac PetscAssertPointer(t, 2); 857d11110bcSJacob Faibussowitsch strcpy(s, t); 858d11110bcSJacob Faibussowitsch } else if (s) { 859d11110bcSJacob Faibussowitsch s[0] = '\0'; 860d11110bcSJacob Faibussowitsch } 861d11110bcSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 862d11110bcSJacob Faibussowitsch } 863