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 @*/
PetscStrToArray(const char s[],char sp,int * argc,char *** args)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 @*/
PetscStrToArrayDestroy(int argc,char ** args)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 @*/
PetscStrArrayallocpy(const char * const * list,char *** t)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 @*/
PetscStrArrayDestroy(char *** list)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 @*/
PetscStrNArrayallocpy(PetscInt n,const char * const * list,char *** t)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 @*/
PetscStrNArrayDestroy(PetscInt n,char *** list)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 @*/
PetscBasename(const char a[])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 @*/
PetscStrcasecmp(const char a[],const char b[],PetscBool * t)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 @*/
PetscStrendswithwhich(const char a[],const char * const * bs,PetscInt * cnt)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
345ce78bad3SBarry Smith struct _n_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
373ce78bad3SBarry Smith Do not change or free the value of `result`
374ce78bad3SBarry Smith
375667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenCreate()`, `PetscTokenDestroy()`
376e5c89e4eSSatish Balay @*/
PetscTokenFind(PetscToken a,const char * result[])377ce78bad3SBarry Smith PetscErrorCode PetscTokenFind(PetscToken a, const char *result[])
378d71ae5a4SJacob Faibussowitsch {
3795f80ce2aSJacob Faibussowitsch char *ptr, token;
380e5c89e4eSSatish Balay
381e5c89e4eSSatish Balay PetscFunctionBegin;
3824f572ea9SToby Isaac PetscAssertPointer(a, 1);
3834f572ea9SToby Isaac PetscAssertPointer(result, 2);
3845f80ce2aSJacob Faibussowitsch *result = ptr = a->current;
3859371c9d4SSatish Balay if (ptr && !*ptr) {
3869371c9d4SSatish Balay *result = NULL;
3873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3889371c9d4SSatish Balay }
3894704e885SBarry Smith token = a->token;
3909371c9d4SSatish Balay if (ptr && (*ptr == '"')) {
3919371c9d4SSatish Balay token = '"';
3929371c9d4SSatish Balay (*result)++;
3939371c9d4SSatish Balay ptr++;
3949371c9d4SSatish Balay }
395e5c89e4eSSatish Balay while (ptr) {
3964704e885SBarry Smith if (*ptr == token) {
397e5c89e4eSSatish Balay *ptr++ = 0;
398e5c89e4eSSatish Balay while (*ptr == a->token) ptr++;
399e5c89e4eSSatish Balay a->current = ptr;
400e5c89e4eSSatish Balay break;
401e5c89e4eSSatish Balay }
402e5c89e4eSSatish Balay if (!*ptr) {
40302c9f0b5SLisandro Dalcin a->current = NULL;
404e5c89e4eSSatish Balay break;
405e5c89e4eSSatish Balay }
406e5c89e4eSSatish Balay ptr++;
407e5c89e4eSSatish Balay }
4083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
409e5c89e4eSSatish Balay }
410e5c89e4eSSatish Balay
411e5c89e4eSSatish Balay /*@C
412811af0c4SBarry Smith PetscTokenCreate - Creates a `PetscToken` used to find tokens in a string
413e5c89e4eSSatish Balay
414667f096bSBarry Smith Not Collective; No Fortran Support
415e5c89e4eSSatish Balay
416e5c89e4eSSatish Balay Input Parameters:
417aec76313SJacob Faibussowitsch + a - the string to look in
4183a9c465aSBarry Smith - b - the separator character
419e5c89e4eSSatish Balay
420e5c89e4eSSatish Balay Output Parameter:
4213a9c465aSBarry Smith . t - the token object
422e5c89e4eSSatish Balay
423667f096bSBarry Smith Level: intermediate
424667f096bSBarry Smith
425811af0c4SBarry Smith Note:
426e5c89e4eSSatish Balay This version is different from the system version in that
427e5c89e4eSSatish Balay it allows you to pass a read-only string into the function.
428e5c89e4eSSatish Balay
429667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenFind()`, `PetscTokenDestroy()`
430e5c89e4eSSatish Balay @*/
PetscTokenCreate(const char a[],char b,PetscToken * t)43198e514b7SJacob Faibussowitsch PetscErrorCode PetscTokenCreate(const char a[], char b, PetscToken *t)
432d71ae5a4SJacob Faibussowitsch {
433e5c89e4eSSatish Balay PetscFunctionBegin;
4344f572ea9SToby Isaac PetscAssertPointer(a, 1);
4354f572ea9SToby Isaac PetscAssertPointer(t, 3);
4369566063dSJacob Faibussowitsch PetscCall(PetscNew(t));
4379566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a, &(*t)->array));
438a297a907SKarl Rupp
439e5c89e4eSSatish Balay (*t)->current = (*t)->array;
440e5c89e4eSSatish Balay (*t)->token = b;
4413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
442e5c89e4eSSatish Balay }
443e5c89e4eSSatish Balay
444e5c89e4eSSatish Balay /*@C
445811af0c4SBarry Smith PetscTokenDestroy - Destroys a `PetscToken`
446e5c89e4eSSatish Balay
447667f096bSBarry Smith Not Collective; No Fortran Support
448e5c89e4eSSatish Balay
4492fe279fdSBarry Smith Input Parameter:
450e5c89e4eSSatish Balay . a - pointer to token
451e5c89e4eSSatish Balay
452e5c89e4eSSatish Balay Level: intermediate
453e5c89e4eSSatish Balay
454667f096bSBarry Smith .seealso: `PetscToken`, `PetscTokenCreate()`, `PetscTokenFind()`
455e5c89e4eSSatish Balay @*/
PetscTokenDestroy(PetscToken * a)456d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTokenDestroy(PetscToken *a)
457d71ae5a4SJacob Faibussowitsch {
458e5c89e4eSSatish Balay PetscFunctionBegin;
4593ba16761SJacob Faibussowitsch if (!*a) PetscFunctionReturn(PETSC_SUCCESS);
4609566063dSJacob Faibussowitsch PetscCall(PetscFree((*a)->array));
4619566063dSJacob Faibussowitsch PetscCall(PetscFree(*a));
4623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
463e5c89e4eSSatish Balay }
464e5c89e4eSSatish Balay
4658e81d068SLisandro Dalcin /*@C
466667f096bSBarry Smith PetscStrInList - search for a string in character-delimited list
4678e81d068SLisandro Dalcin
468667f096bSBarry Smith Not Collective; No Fortran Support
4698e81d068SLisandro Dalcin
4708e81d068SLisandro Dalcin Input Parameters:
4718e81d068SLisandro Dalcin + str - the string to look for
4728e81d068SLisandro Dalcin . list - the list to search in
4738e81d068SLisandro Dalcin - sep - the separator character
4748e81d068SLisandro Dalcin
4758e81d068SLisandro Dalcin Output Parameter:
476667f096bSBarry Smith . found - whether `str` is in `list`
4778e81d068SLisandro Dalcin
4788e81d068SLisandro Dalcin Level: intermediate
4798e81d068SLisandro Dalcin
480db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscStrcmp()`
4818e81d068SLisandro Dalcin @*/
PetscStrInList(const char str[],const char list[],char sep,PetscBool * found)482d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found)
483d71ae5a4SJacob Faibussowitsch {
4848e81d068SLisandro Dalcin PetscToken token;
485ce78bad3SBarry Smith const char *item;
4868e81d068SLisandro Dalcin
4878e81d068SLisandro Dalcin PetscFunctionBegin;
4884f572ea9SToby Isaac PetscAssertPointer(found, 4);
4898e81d068SLisandro Dalcin *found = PETSC_FALSE;
4909566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(list, sep, &token));
4919566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item));
4928e81d068SLisandro Dalcin while (item) {
4939566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(str, item, found));
4948e81d068SLisandro Dalcin if (*found) break;
4959566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &item));
4968e81d068SLisandro Dalcin }
4979566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token));
4983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4998e81d068SLisandro Dalcin }
500e5c89e4eSSatish Balay
501e5c89e4eSSatish Balay /*@C
502e5c89e4eSSatish Balay PetscGetPetscDir - Gets the directory PETSc is installed in
503e5c89e4eSSatish Balay
504667f096bSBarry Smith Not Collective; No Fortran Support
505e5c89e4eSSatish Balay
506e5c89e4eSSatish Balay Output Parameter:
507e5c89e4eSSatish Balay . dir - the directory
508e5c89e4eSSatish Balay
509e5c89e4eSSatish Balay Level: developer
510e5c89e4eSSatish Balay
51110450e9eSJacob Faibussowitsch .seealso: `PetscGetArchType()`
512e5c89e4eSSatish Balay @*/
PetscGetPetscDir(const char * dir[])513d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetPetscDir(const char *dir[])
514d71ae5a4SJacob Faibussowitsch {
515e5c89e4eSSatish Balay PetscFunctionBegin;
5164f572ea9SToby Isaac PetscAssertPointer(dir, 1);
517e5c89e4eSSatish Balay *dir = PETSC_DIR;
5183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
519e5c89e4eSSatish Balay }
520e5c89e4eSSatish Balay
521e5c89e4eSSatish Balay /*@C
522e5c89e4eSSatish Balay PetscStrreplace - Replaces substrings in string with other substrings
523e5c89e4eSSatish Balay
524667f096bSBarry Smith Not Collective; No Fortran Support
525e5c89e4eSSatish Balay
526e5c89e4eSSatish Balay Input Parameters:
527811af0c4SBarry Smith + comm - `MPI_Comm` of processors that are processing the string
52871573d7dSBarry Smith . aa - the string to look in
529667f096bSBarry Smith . b - the resulting copy of a with replaced strings (`b` can be the same as `a`)
530667f096bSBarry Smith - len - the length of `b`
531e5c89e4eSSatish Balay
5322fe279fdSBarry Smith Level: developer
5332fe279fdSBarry Smith
534e5c89e4eSSatish Balay Notes:
535873f9891SMatthew Knepley Replaces
536873f9891SMatthew Knepley .vb
537873f9891SMatthew Knepley ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, ${DISPLAY},
538873f9891SMatthew Knepley ${HOMEDIRECTORY}, ${WORKINGDIRECTORY}, ${USERNAME}, ${HOSTNAME}, ${PETSC_MAKE}
539873f9891SMatthew Knepley .ve
540873f9891SMatthew Knepley with appropriate values as well as any environmental variables.
541e5c89e4eSSatish Balay
542811af0c4SBarry Smith `PETSC_LIB_DIR` uses the environmental variable if it exists. `PETSC_ARCH` and `PETSC_DIR` use what
543acc6cc86SBarry Smith PETSc was built with and do not use environmental variables.
544acc6cc86SBarry Smith
54510450e9eSJacob Faibussowitsch .seealso: `PetscStrcmp()`
546e5c89e4eSSatish Balay @*/
PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)547d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len)
548d71ae5a4SJacob Faibussowitsch {
549e5c89e4eSSatish Balay int i = 0;
550e5c89e4eSSatish Balay size_t l, l1, l2, l3;
5517864358aSSatish Balay char *work, *par, *epar = NULL, env[1024], *tfree, *a = (char *)aa;
552f236b2adSBarry Smith const char *s[] = {"${PETSC_ARCH}", "${PETSC_DIR}", "${PETSC_LIB_DIR}", "${DISPLAY}", "${HOMEDIRECTORY}", "${WORKINGDIRECTORY}", "${USERNAME}", "${HOSTNAME}", "${PETSC_MAKE}", NULL};
553f236b2adSBarry Smith char *r[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
554ace3abfcSBarry Smith PetscBool flag;
555589a23caSBarry Smith static size_t DISPLAY_LENGTH = 265, USER_LENGTH = 256, HOST_LENGTH = 256;
556e5c89e4eSSatish Balay
557e5c89e4eSSatish Balay PetscFunctionBegin;
5584f572ea9SToby Isaac PetscAssertPointer(aa, 2);
5594f572ea9SToby Isaac PetscAssertPointer(b, 3);
560835f2295SStefano Zampini if (aa == b) PetscCall(PetscStrallocpy(aa, &a));
5619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len, &work));
562e5c89e4eSSatish Balay
563e5c89e4eSSatish Balay /* get values for replaced variables */
5649566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_ARCH, &r[0]));
5659566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_DIR, &r[1]));
5669566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_LIB_DIR, &r[2]));
5679566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(DISPLAY_LENGTH, &r[3]));
5689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[4]));
5699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN, &r[5]));
5709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(USER_LENGTH, &r[6]));
5719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(HOST_LENGTH, &r[7]));
5729566063dSJacob Faibussowitsch PetscCall(PetscGetDisplay(r[3], DISPLAY_LENGTH));
5739566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(r[4], PETSC_MAX_PATH_LEN));
5749566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(r[5], PETSC_MAX_PATH_LEN));
5759566063dSJacob Faibussowitsch PetscCall(PetscGetUserName(r[6], USER_LENGTH));
5769566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(r[7], HOST_LENGTH));
577f236b2adSBarry Smith PetscCall(PetscStrallocpy(PETSC_OMAKE, &r[8]));
578487e5849SBarry Smith
579487e5849SBarry Smith /* replace that are in environment */
5809566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_LIB_DIR", env, sizeof(env), &flag));
581487e5849SBarry Smith if (flag) {
5829566063dSJacob Faibussowitsch PetscCall(PetscFree(r[2]));
5839566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(env, &r[2]));
584487e5849SBarry Smith }
585e5c89e4eSSatish Balay
586e5c89e4eSSatish Balay /* replace the requested strings */
5879566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, a, len));
588e5c89e4eSSatish Balay while (s[i]) {
589*975f0623SStefano Zampini PetscCall(PetscStrcmp(s[i], r[i], &flag));
590*975f0623SStefano Zampini if (flag) {
591*975f0623SStefano Zampini i++;
592*975f0623SStefano Zampini continue;
593*975f0623SStefano Zampini }
5949566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s[i], &l));
5959566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par));
596e5c89e4eSSatish Balay while (par) {
597e5c89e4eSSatish Balay *par = 0;
598e5c89e4eSSatish Balay par += l;
599e5c89e4eSSatish Balay
6009566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b, &l1));
6019566063dSJacob Faibussowitsch PetscCall(PetscStrlen(r[i], &l2));
6029566063dSJacob Faibussowitsch PetscCall(PetscStrlen(par, &l3));
603cc73adaaSBarry Smith PetscCheck(l1 + l2 + l3 < len, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "b len is not long enough to hold new values");
6049566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len));
6059566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, r[i], len));
6069566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, par, len));
6079566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len));
6089566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, s[i], &par));
609e5c89e4eSSatish Balay }
610e5c89e4eSSatish Balay i++;
611e5c89e4eSSatish Balay }
612487e5849SBarry Smith i = 0;
613487e5849SBarry Smith while (r[i]) {
614835f2295SStefano Zampini tfree = r[i];
6159566063dSJacob Faibussowitsch PetscCall(PetscFree(tfree));
616487e5849SBarry Smith i++;
617e5c89e4eSSatish Balay }
618e5c89e4eSSatish Balay
619e5c89e4eSSatish Balay /* look for any other ${xxx} strings to replace from environmental variables */
6209566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par));
621e5c89e4eSSatish Balay while (par) {
622e5c89e4eSSatish Balay *par = 0;
623e5c89e4eSSatish Balay par += 2;
6249566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work, b, len));
6259566063dSJacob Faibussowitsch PetscCall(PetscStrstr(par, "}", &epar));
626e5c89e4eSSatish Balay *epar = 0;
627e5c89e4eSSatish Balay epar += 1;
6289566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, par, env, sizeof(env), &flag));
62928b400f6SJacob Faibussowitsch PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Substitution string ${%s} not found as environmental variable", par);
6309566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, env, len));
6319566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work, epar, len));
6329566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b, work, len));
6339566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b, "${", &par));
634e5c89e4eSSatish Balay }
6359566063dSJacob Faibussowitsch PetscCall(PetscFree(work));
6369566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscFree(a));
6373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
638e5c89e4eSSatish Balay }
639e5c89e4eSSatish Balay
640a53986e1SJed Brown /*@C
641c0d8b5b9SStefano Zampini PetscStrcmpAny - Determines whether a string matches any of a list of strings.
642c0d8b5b9SStefano Zampini
643cc4c1da9SBarry Smith Not Collective, No Fortran Support
644c0d8b5b9SStefano Zampini
645c0d8b5b9SStefano Zampini Input Parameters:
646c0d8b5b9SStefano Zampini + src - pointer to input the string
647c0d8b5b9SStefano Zampini - cmp - list of non-null and non-empty strings to be compared against, pass the empty string "" to terminate the list
648c0d8b5b9SStefano Zampini
649c0d8b5b9SStefano Zampini Output Parameter:
650c0d8b5b9SStefano Zampini . match - `PETSC_TRUE` if the input string matches any in the list, else `PETSC_FALSE`
651c0d8b5b9SStefano Zampini
652c0d8b5b9SStefano Zampini Level: intermediate
653c0d8b5b9SStefano Zampini
65410450e9eSJacob Faibussowitsch .seealso: `PetscStrcmp()`
655c0d8b5b9SStefano Zampini @*/
PetscStrcmpAny(const char src[],PetscBool * match,const char cmp[],...)656c0d8b5b9SStefano Zampini PetscErrorCode PetscStrcmpAny(const char src[], PetscBool *match, const char cmp[], ...)
657c0d8b5b9SStefano Zampini {
658c0d8b5b9SStefano Zampini va_list Argp;
659c0d8b5b9SStefano Zampini
660c0d8b5b9SStefano Zampini PetscFunctionBegin;
6614f572ea9SToby Isaac PetscAssertPointer(match, 2);
662c0d8b5b9SStefano Zampini *match = PETSC_FALSE;
663c0d8b5b9SStefano Zampini if (!src) PetscFunctionReturn(PETSC_SUCCESS);
664c0d8b5b9SStefano Zampini va_start(Argp, cmp);
665c0d8b5b9SStefano Zampini while (cmp && cmp[0]) {
666c0d8b5b9SStefano Zampini PetscBool found;
667c0d8b5b9SStefano Zampini PetscCall(PetscStrcmp(src, cmp, &found));
668c0d8b5b9SStefano Zampini if (found) {
669c0d8b5b9SStefano Zampini *match = PETSC_TRUE;
670c0d8b5b9SStefano Zampini break;
671c0d8b5b9SStefano Zampini }
672c0d8b5b9SStefano Zampini cmp = va_arg(Argp, const char *);
673c0d8b5b9SStefano Zampini }
674c0d8b5b9SStefano Zampini va_end(Argp);
675c0d8b5b9SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
676c0d8b5b9SStefano Zampini }
677c0d8b5b9SStefano Zampini
678c0d8b5b9SStefano Zampini /*@C
679a53986e1SJed Brown PetscEListFind - searches list of strings for given string, using case insensitive matching
680e5c89e4eSSatish Balay
681667f096bSBarry Smith Not Collective; No Fortran Support
682a53986e1SJed Brown
683a53986e1SJed Brown Input Parameters:
684a53986e1SJed Brown + n - number of strings in
685a53986e1SJed Brown . list - list of strings to search
686a53986e1SJed Brown - str - string to look for, empty string "" accepts default (first entry in list)
687a53986e1SJed Brown
688a53986e1SJed Brown Output Parameters:
689a53986e1SJed Brown + value - index of matching string (if found)
690667f096bSBarry Smith - found - boolean indicating whether string was found (can be `NULL`)
691811af0c4SBarry Smith
69253c0d4aeSBarry Smith Level: developer
69353c0d4aeSBarry Smith
694811af0c4SBarry Smith .seealso: `PetscEnumFind()`
695a53986e1SJed Brown @*/
PetscEListFind(PetscInt n,const char * const * list,const char * str,PetscInt * value,PetscBool * found)696d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found)
697d71ae5a4SJacob Faibussowitsch {
698a53986e1SJed Brown PetscFunctionBegin;
6995f80ce2aSJacob Faibussowitsch if (found) {
7004f572ea9SToby Isaac PetscAssertPointer(found, 5);
7015f80ce2aSJacob Faibussowitsch *found = PETSC_FALSE;
7025f80ce2aSJacob Faibussowitsch }
7035f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) {
7045f80ce2aSJacob Faibussowitsch PetscBool matched;
7055f80ce2aSJacob Faibussowitsch
7069566063dSJacob Faibussowitsch PetscCall(PetscStrcasecmp(str, list[i], &matched));
707a53986e1SJed Brown if (matched || !str[0]) {
708a53986e1SJed Brown if (found) *found = PETSC_TRUE;
709a53986e1SJed Brown *value = i;
710a53986e1SJed Brown break;
711a53986e1SJed Brown }
712a53986e1SJed Brown }
7133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
714a53986e1SJed Brown }
715a53986e1SJed Brown
716a53986e1SJed Brown /*@C
7178e81d068SLisandro Dalcin PetscEnumFind - searches enum list of strings for given string, using case insensitive matching
718a53986e1SJed Brown
719667f096bSBarry Smith Not Collective; No Fortran Support
720a53986e1SJed Brown
721a53986e1SJed Brown Input Parameters:
722667f096bSBarry Smith + enumlist - list of strings to search, followed by enum name, then enum prefix, then `NULL`
723a53986e1SJed Brown - str - string to look for
724a53986e1SJed Brown
725a53986e1SJed Brown Output Parameters:
726a53986e1SJed Brown + value - index of matching string (if found)
727667f096bSBarry Smith - found - boolean indicating whether string was found (can be `NULL`)
728a53986e1SJed Brown
729a53986e1SJed Brown Level: advanced
730811af0c4SBarry Smith
731811af0c4SBarry Smith .seealso: `PetscEListFind()`
732a53986e1SJed Brown @*/
PetscEnumFind(const char * const * enumlist,const char * str,PetscEnum * value,PetscBool * found)733d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found)
734d71ae5a4SJacob Faibussowitsch {
735d05ba7d2SLisandro Dalcin PetscInt n = 0, evalue;
736a53986e1SJed Brown PetscBool efound;
737a53986e1SJed Brown
738a53986e1SJed Brown PetscFunctionBegin;
7394f572ea9SToby Isaac PetscAssertPointer(enumlist, 1);
7405f80ce2aSJacob 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");
7415f80ce2aSJacob Faibussowitsch PetscCheck(n >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
742a53986e1SJed Brown n -= 3; /* drop enum name, prefix, and null termination */
7439566063dSJacob Faibussowitsch PetscCall(PetscEListFind(n, enumlist, str, &evalue, &efound));
7445f80ce2aSJacob Faibussowitsch if (efound) {
7454f572ea9SToby Isaac PetscAssertPointer(value, 3);
7465f80ce2aSJacob Faibussowitsch *value = (PetscEnum)evalue;
7475f80ce2aSJacob Faibussowitsch }
7485f80ce2aSJacob Faibussowitsch if (found) {
7494f572ea9SToby Isaac PetscAssertPointer(found, 4);
7505f80ce2aSJacob Faibussowitsch *found = efound;
7515f80ce2aSJacob Faibussowitsch }
7523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
753a53986e1SJed Brown }
754660278c0SBarry Smith
755660278c0SBarry Smith /*@C
756660278c0SBarry Smith PetscCIFilename - returns the basename of a file name when the PETSc CI portable error output mode is enabled.
757660278c0SBarry Smith
75820f4b53cSBarry Smith Not Collective; No Fortran Support
759660278c0SBarry Smith
760660278c0SBarry Smith Input Parameter:
761660278c0SBarry Smith . file - the file name
762660278c0SBarry Smith
763667f096bSBarry Smith Level: developer
764667f096bSBarry Smith
765660278c0SBarry Smith Note:
766660278c0SBarry Smith PETSc CI mode is a mode of running PETSc where output (both error and non-error) is made portable across all systems
767660278c0SBarry Smith so that comparisons of output between runs are easy to make.
768660278c0SBarry Smith
769660278c0SBarry Smith This mode is used for all tests in the test harness, it applies to both debug and optimized builds.
770660278c0SBarry Smith
771667f096bSBarry Smith Use the option `-petsc_ci` to turn on PETSc CI mode. It changes certain output in non-error situations to be portable for
772660278c0SBarry Smith all systems, mainly the output of options. It is passed to all PETSc programs automatically by the test harness.
773660278c0SBarry Smith
774660278c0SBarry Smith Always uses the Unix / as the file separate even on Microsoft Windows systems
775660278c0SBarry Smith
776667f096bSBarry Smith The option `-petsc_ci_portable_error_output` attempts to output the same error messages on all systems for the test harness.
777660278c0SBarry Smith In particular the output of filenames and line numbers in PETSc stacks. This is to allow (limited) checking of PETSc
778660278c0SBarry 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
779660278c0SBarry Smith harness can process the output for differences in the usual manner as for successful runs. It should be provided to the test
780da81f932SPierre Jolivet harness in the args: argument for specific examples. It will not necessarily produce portable output if different errors
781660278c0SBarry Smith (or no errors) occur on a subset of the MPI ranks.
782660278c0SBarry Smith
783660278c0SBarry Smith .seealso: `PetscCILinenumber()`
784660278c0SBarry Smith @*/
PetscCIFilename(const char * file)785d71ae5a4SJacob Faibussowitsch const char *PetscCIFilename(const char *file)
786d71ae5a4SJacob Faibussowitsch {
787660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return file;
788660278c0SBarry Smith return PetscBasename(file);
789660278c0SBarry Smith }
790660278c0SBarry Smith
791660278c0SBarry Smith /*@C
792811af0c4SBarry Smith PetscCILinenumber - returns a line number except if `PetscCIEnablePortableErrorOutput` is set when it returns 0
793660278c0SBarry Smith
794667f096bSBarry Smith Not Collective; No Fortran Support
795660278c0SBarry Smith
796660278c0SBarry Smith Input Parameter:
797660278c0SBarry Smith . linenumber - the initial line number
798660278c0SBarry Smith
799667f096bSBarry Smith Level: developer
800667f096bSBarry Smith
801660278c0SBarry Smith Note:
802660278c0SBarry Smith See `PetscCIFilename()` for details on usage
803660278c0SBarry Smith
804660278c0SBarry Smith .seealso: `PetscCIFilename()`
805660278c0SBarry Smith @*/
PetscCILinenumber(int linenumber)806d71ae5a4SJacob Faibussowitsch int PetscCILinenumber(int linenumber)
807d71ae5a4SJacob Faibussowitsch {
808660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return linenumber;
809660278c0SBarry Smith return 0;
810660278c0SBarry Smith }
811d11110bcSJacob Faibussowitsch
812d11110bcSJacob Faibussowitsch /*@C
813d11110bcSJacob Faibussowitsch PetscStrcat - Concatenates a string onto a given string
814d11110bcSJacob Faibussowitsch
815d11110bcSJacob Faibussowitsch Not Collective, No Fortran Support
816d11110bcSJacob Faibussowitsch
817d11110bcSJacob Faibussowitsch Input Parameters:
818d11110bcSJacob Faibussowitsch + s - string to be added to
819d11110bcSJacob Faibussowitsch - t - pointer to string to be added to end
820d11110bcSJacob Faibussowitsch
821d11110bcSJacob Faibussowitsch Level: deprecated (since 3.18.5)
822d11110bcSJacob Faibussowitsch
823d11110bcSJacob Faibussowitsch Notes:
824d11110bcSJacob Faibussowitsch It is recommended you use `PetscStrlcat()` instead of this routine.
825d11110bcSJacob Faibussowitsch
826d11110bcSJacob Faibussowitsch .seealso: `PetscStrlcat()`
827d11110bcSJacob Faibussowitsch @*/
PetscStrcat(char s[],const char t[])828d11110bcSJacob Faibussowitsch PetscErrorCode PetscStrcat(char s[], const char t[])
829d11110bcSJacob Faibussowitsch {
830d11110bcSJacob Faibussowitsch PetscFunctionBegin;
831d11110bcSJacob Faibussowitsch if (!t) PetscFunctionReturn(PETSC_SUCCESS);
8324f572ea9SToby Isaac PetscAssertPointer(s, 1);
833d11110bcSJacob Faibussowitsch strcat(s, t);
834d11110bcSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
835d11110bcSJacob Faibussowitsch }
836d11110bcSJacob Faibussowitsch
837d11110bcSJacob Faibussowitsch /*@C
838d11110bcSJacob Faibussowitsch PetscStrcpy - Copies a string
839d11110bcSJacob Faibussowitsch
840d11110bcSJacob Faibussowitsch Not Collective, No Fortran Support
841d11110bcSJacob Faibussowitsch
8422fe279fdSBarry Smith Input Parameter:
843d11110bcSJacob Faibussowitsch . t - pointer to string
844d11110bcSJacob Faibussowitsch
845d11110bcSJacob Faibussowitsch Output Parameter:
846d11110bcSJacob Faibussowitsch . s - the copied string
847d11110bcSJacob Faibussowitsch
848d11110bcSJacob Faibussowitsch Level: deprecated (since 3.18.5)
849d11110bcSJacob Faibussowitsch
850d11110bcSJacob Faibussowitsch Notes:
851d11110bcSJacob Faibussowitsch It is recommended you use `PetscStrncpy()` (equivalently `PetscArraycpy()` or
852d11110bcSJacob Faibussowitsch `PetscMemcpy()`) instead of this routine.
853d11110bcSJacob Faibussowitsch
854d11110bcSJacob Faibussowitsch `NULL` strings returns a string starting with zero.
855d11110bcSJacob Faibussowitsch
856d11110bcSJacob Faibussowitsch .seealso: `PetscStrncpy()`
857d11110bcSJacob Faibussowitsch @*/
PetscStrcpy(char s[],const char t[])858d11110bcSJacob Faibussowitsch PetscErrorCode PetscStrcpy(char s[], const char t[])
859d11110bcSJacob Faibussowitsch {
860d11110bcSJacob Faibussowitsch PetscFunctionBegin;
861d11110bcSJacob Faibussowitsch if (t) {
8624f572ea9SToby Isaac PetscAssertPointer(s, 1);
8634f572ea9SToby Isaac PetscAssertPointer(t, 2);
864d11110bcSJacob Faibussowitsch strcpy(s, t);
865d11110bcSJacob Faibussowitsch } else if (s) {
866d11110bcSJacob Faibussowitsch s[0] = '\0';
867d11110bcSJacob Faibussowitsch }
868d11110bcSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
869d11110bcSJacob Faibussowitsch }
870