1e5c89e4eSSatish Balay /* 2e5c89e4eSSatish Balay We define the string operations here. The reason we just do not use 3e5c89e4eSSatish Balay the standard string routines in the PETSc code is that on some machines 4e5c89e4eSSatish Balay they are broken or have the wrong prototypes. 5e5c89e4eSSatish Balay 6e5c89e4eSSatish Balay */ 75f80ce2aSJacob Faibussowitsch #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 83964eb88SJed Brown #if defined(PETSC_HAVE_STRINGS_H) 93964eb88SJed Brown # include <strings.h> /* strcasecmp */ 103964eb88SJed Brown #endif 113964eb88SJed Brown 123c311c98SBarry Smith /*@C 1351a1f156SVaclav Hapla PetscStrToArray - Separates a string by a character (for example ' ' or '\n') and creates an array of strings 143c311c98SBarry Smith 153c311c98SBarry Smith Not Collective 163c311c98SBarry Smith 173c311c98SBarry Smith Input Parameters: 18d67fe73bSBarry Smith + s - pointer to string 1951a1f156SVaclav Hapla - sp - separator character 203c311c98SBarry Smith 21d8d19677SJose E. Roman Output Parameters: 223c311c98SBarry Smith + argc - the number of entries in the array 233c311c98SBarry Smith - args - an array of the entries with a null at the end 243c311c98SBarry Smith 253c311c98SBarry Smith Level: intermediate 263c311c98SBarry Smith 2795452b02SPatrick Sanan Notes: 2895452b02SPatrick Sanan this may be called before PetscInitialize() or after PetscFinalize() 293c311c98SBarry Smith 306f013253SBarry Smith Not for use in Fortran 316f013253SBarry Smith 3295452b02SPatrick Sanan Developer Notes: 3395452b02SPatrick Sanan Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used 34b4cd4cebSBarry Smith to generate argc, args arguments passed to MPI_Init() 35301d30feSBarry Smith 36db781477SPatrick Sanan .seealso: `PetscStrToArrayDestroy()`, `PetscToken`, `PetscTokenCreate()` 373c311c98SBarry Smith 383c311c98SBarry Smith @*/ 39d67fe73bSBarry Smith PetscErrorCode PetscStrToArray(const char s[], char sp, int *argc, char ***args) 403c311c98SBarry Smith { 41c3bcdc7eSBarry Smith int i,j,n,*lens,cnt = 0; 42ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 433c311c98SBarry Smith 4440a7e1efSBarry Smith if (!s) n = 0; 4540a7e1efSBarry Smith else n = strlen(s); 463c311c98SBarry Smith *argc = 0; 4761528463SBarry Smith *args = NULL; 48acf7dc08SSatish Balay for (; n>0; n--) { /* remove separator chars at the end - and will empty the string if all chars are separator chars */ 49acf7dc08SSatish Balay if (s[n-1] != sp) break; 50acf7dc08SSatish Balay } 515f80ce2aSJacob Faibussowitsch if (!n) return 0; 523c311c98SBarry Smith for (i=0; i<n; i++) { 53d67fe73bSBarry Smith if (s[i] != sp) break; 543c311c98SBarry Smith } 553c311c98SBarry Smith for (;i<n+1; i++) { 56d67fe73bSBarry Smith if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 57d67fe73bSBarry Smith else if (s[i] != sp) {flg = PETSC_FALSE;} 583c311c98SBarry Smith } 59a2ea699eSBarry Smith (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM; 6053e6e2c4SHong Zhang lens = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM; 613c311c98SBarry Smith for (i=0; i<*argc; i++) lens[i] = 0; 623c311c98SBarry Smith 633c311c98SBarry Smith *argc = 0; 643c311c98SBarry Smith for (i=0; i<n; i++) { 65d67fe73bSBarry Smith if (s[i] != sp) break; 663c311c98SBarry Smith } 677dd9f305SSatish Balay for (;i<n+1; i++) { 68d67fe73bSBarry Smith if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 69d67fe73bSBarry Smith else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;} 703c311c98SBarry Smith } 713c311c98SBarry Smith 723c311c98SBarry Smith for (i=0; i<*argc; i++) { 73c3bcdc7eSBarry Smith (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); 74c3bcdc7eSBarry Smith if (!(*args)[i]) { 75c3bcdc7eSBarry Smith free(lens); 76c3bcdc7eSBarry Smith for (j=0; j<i; j++) free((*args)[j]); 77c3bcdc7eSBarry Smith free(*args); 78c3bcdc7eSBarry Smith return PETSC_ERR_MEM; 79c3bcdc7eSBarry Smith } 803c311c98SBarry Smith } 81a2ea699eSBarry Smith free(lens); 8202c9f0b5SLisandro Dalcin (*args)[*argc] = NULL; 833c311c98SBarry Smith 843c311c98SBarry Smith *argc = 0; 853c311c98SBarry Smith for (i=0; i<n; i++) { 86d67fe73bSBarry Smith if (s[i] != sp) break; 873c311c98SBarry Smith } 883c311c98SBarry Smith for (;i<n+1; i++) { 89d67fe73bSBarry Smith if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;} 90d67fe73bSBarry Smith else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;} 913c311c98SBarry Smith } 923c311c98SBarry Smith return 0; 933c311c98SBarry Smith } 943c311c98SBarry Smith 95301d30feSBarry Smith /*@C 96301d30feSBarry Smith PetscStrToArrayDestroy - Frees array created with PetscStrToArray(). 97301d30feSBarry Smith 98301d30feSBarry Smith Not Collective 99301d30feSBarry Smith 100301d30feSBarry Smith Output Parameters: 101301d30feSBarry Smith + argc - the number of arguments 102301d30feSBarry Smith - args - the array of arguments 103301d30feSBarry Smith 104301d30feSBarry Smith Level: intermediate 105301d30feSBarry Smith 10695452b02SPatrick Sanan Notes: 10795452b02SPatrick Sanan This may be called before PetscInitialize() or after PetscFinalize() 108301d30feSBarry Smith 1096f013253SBarry Smith Not for use in Fortran 1106f013253SBarry Smith 111db781477SPatrick Sanan .seealso: `PetscStrToArray()` 112301d30feSBarry Smith 113301d30feSBarry Smith @*/ 1147087cfbeSBarry Smith PetscErrorCode PetscStrToArrayDestroy(int argc, char **args) 115301d30feSBarry Smith { 1165f80ce2aSJacob Faibussowitsch for (int i = 0; i < argc; ++i) free(args[i]); 117a297a907SKarl Rupp if (args) free(args); 118301d30feSBarry Smith return 0; 119301d30feSBarry Smith } 120301d30feSBarry Smith 121e5c89e4eSSatish Balay /*@C 122e5c89e4eSSatish Balay PetscStrlen - Gets length of a string 123e5c89e4eSSatish Balay 124e5c89e4eSSatish Balay Not Collective 125e5c89e4eSSatish Balay 126e5c89e4eSSatish Balay Input Parameters: 127e5c89e4eSSatish Balay . s - pointer to string 128e5c89e4eSSatish Balay 129e5c89e4eSSatish Balay Output Parameter: 130e5c89e4eSSatish Balay . len - length in bytes 131e5c89e4eSSatish Balay 132e5c89e4eSSatish Balay Level: intermediate 133e5c89e4eSSatish Balay 134e5c89e4eSSatish Balay Note: 135e5c89e4eSSatish Balay This routine is analogous to strlen(). 136e5c89e4eSSatish Balay 137e5c89e4eSSatish Balay Null string returns a length of zero 138e5c89e4eSSatish Balay 1396f013253SBarry Smith Not for use in Fortran 1406f013253SBarry Smith 141e5c89e4eSSatish Balay @*/ 1427087cfbeSBarry Smith PetscErrorCode PetscStrlen(const char s[], size_t *len) 143e5c89e4eSSatish Balay { 144e5c89e4eSSatish Balay PetscFunctionBegin; 1455f80ce2aSJacob Faibussowitsch *len = s ? strlen(s) : 0; 146e5c89e4eSSatish Balay PetscFunctionReturn(0); 147e5c89e4eSSatish Balay } 148e5c89e4eSSatish Balay 149e5c89e4eSSatish Balay /*@C 150e5c89e4eSSatish Balay PetscStrallocpy - Allocates space to hold a copy of a string then copies the string 151e5c89e4eSSatish Balay 152e5c89e4eSSatish Balay Not Collective 153e5c89e4eSSatish Balay 154e5c89e4eSSatish Balay Input Parameters: 155e5c89e4eSSatish Balay . s - pointer to string 156e5c89e4eSSatish Balay 157e5c89e4eSSatish Balay Output Parameter: 158e5c89e4eSSatish Balay . t - the copied string 159e5c89e4eSSatish Balay 160e5c89e4eSSatish Balay Level: intermediate 161e5c89e4eSSatish Balay 162e5c89e4eSSatish Balay Note: 163e5c89e4eSSatish Balay Null string returns a new null string 164e5c89e4eSSatish Balay 1656f013253SBarry Smith Not for use in Fortran 1666f013253SBarry Smith 1670ecf5a55SBarry Smith Warning: If t has previously been allocated then that memory is lost, you may need to PetscFree() 1680ecf5a55SBarry Smith the array before calling this routine. 1690ecf5a55SBarry Smith 170db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()`, `PetscStrcpy()`, `PetscStrNArrayallocpy()` 1710ecf5a55SBarry Smith 172e5c89e4eSSatish Balay @*/ 1737087cfbeSBarry Smith PetscErrorCode PetscStrallocpy(const char s[], char *t[]) 174e5c89e4eSSatish Balay { 17502c9f0b5SLisandro Dalcin char *tmp = NULL; 176e5c89e4eSSatish Balay 177e5c89e4eSSatish Balay PetscFunctionBegin; 178e5c89e4eSSatish Balay if (s) { 1795f80ce2aSJacob Faibussowitsch size_t len; 1805f80ce2aSJacob Faibussowitsch 1819566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s,&len)); 1829566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1+len,&tmp)); 1839566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(tmp,s)); 184e5c89e4eSSatish Balay } 18571573d7dSBarry Smith *t = tmp; 186e5c89e4eSSatish Balay PetscFunctionReturn(0); 187e5c89e4eSSatish Balay } 188e5c89e4eSSatish Balay 18947340559SBarry Smith /*@C 19047340559SBarry Smith PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 19147340559SBarry Smith 19247340559SBarry Smith Not Collective 19347340559SBarry Smith 19447340559SBarry Smith Input Parameters: 19547340559SBarry Smith . s - pointer to array of strings (final string is a null) 19647340559SBarry Smith 19747340559SBarry Smith Output Parameter: 19847340559SBarry Smith . t - the copied array string 19947340559SBarry Smith 20047340559SBarry Smith Level: intermediate 20147340559SBarry Smith 20247340559SBarry Smith Note: 20347340559SBarry Smith Not for use in Fortran 20447340559SBarry Smith 2050ecf5a55SBarry Smith Warning: If t has previously been allocated then that memory is lost, you may need to PetscStrArrayDestroy() 2060ecf5a55SBarry Smith the array before calling this routine. 2070ecf5a55SBarry Smith 208db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayDestroy()`, `PetscStrNArrayallocpy()` 20947340559SBarry Smith 21047340559SBarry Smith @*/ 21147340559SBarry Smith PetscErrorCode PetscStrArrayallocpy(const char *const *list, char ***t) 21247340559SBarry Smith { 2135f80ce2aSJacob Faibussowitsch PetscInt n = 0; 21447340559SBarry Smith 21547340559SBarry Smith PetscFunctionBegin; 21647340559SBarry Smith while (list[n++]) ; 2179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n+1,t)); 2189566063dSJacob Faibussowitsch for (PetscInt i=0; i<n; i++) PetscCall(PetscStrallocpy(list[i],(*t)+i)); 2190298fd71SBarry Smith (*t)[n] = NULL; 22047340559SBarry Smith PetscFunctionReturn(0); 22147340559SBarry Smith } 22247340559SBarry Smith 22347340559SBarry Smith /*@C 22447340559SBarry Smith PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy(). 22547340559SBarry Smith 22647340559SBarry Smith Not Collective 22747340559SBarry Smith 22847340559SBarry Smith Output Parameters: 22947340559SBarry Smith . list - array of strings 23047340559SBarry Smith 23147340559SBarry Smith Level: intermediate 23247340559SBarry Smith 23395452b02SPatrick Sanan Notes: 23495452b02SPatrick Sanan Not for use in Fortran 23547340559SBarry Smith 236db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()` 23747340559SBarry Smith 23847340559SBarry Smith @*/ 2396fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list) 24047340559SBarry Smith { 24147340559SBarry Smith PetscInt n = 0; 24247340559SBarry Smith 2436fed8037SJed Brown PetscFunctionBegin; 2446fed8037SJed Brown if (!*list) PetscFunctionReturn(0); 2456fed8037SJed Brown while ((*list)[n]) { 2469566063dSJacob Faibussowitsch PetscCall(PetscFree((*list)[n])); 2475f80ce2aSJacob Faibussowitsch ++n; 24847340559SBarry Smith } 2499566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 2506fed8037SJed Brown PetscFunctionReturn(0); 25147340559SBarry Smith } 25247340559SBarry Smith 2536991f827SBarry Smith /*@C 2546991f827SBarry Smith PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 2556991f827SBarry Smith 2566991f827SBarry Smith Not Collective 2576991f827SBarry Smith 2586991f827SBarry Smith Input Parameters: 2596991f827SBarry Smith + n - the number of string entries 2606991f827SBarry Smith - s - pointer to array of strings 2616991f827SBarry Smith 2626991f827SBarry Smith Output Parameter: 2636991f827SBarry Smith . t - the copied array string 2646991f827SBarry Smith 2656991f827SBarry Smith Level: intermediate 2666991f827SBarry Smith 2676991f827SBarry Smith Note: 2686991f827SBarry Smith Not for use in Fortran 2696991f827SBarry Smith 270db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayallocpy()`, `PetscStrNArrayDestroy()` 2716991f827SBarry Smith 2726991f827SBarry Smith @*/ 2736991f827SBarry Smith PetscErrorCode PetscStrNArrayallocpy(PetscInt n, const char *const *list, char ***t) 2746991f827SBarry Smith { 2756991f827SBarry Smith PetscFunctionBegin; 2769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,t)); 2779566063dSJacob Faibussowitsch for (PetscInt i=0; i<n; i++) PetscCall(PetscStrallocpy(list[i],(*t)+i)); 2786991f827SBarry Smith PetscFunctionReturn(0); 2796991f827SBarry Smith } 2806991f827SBarry Smith 2816991f827SBarry Smith /*@C 2826991f827SBarry Smith PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy(). 2836991f827SBarry Smith 2846991f827SBarry Smith Not Collective 2856991f827SBarry Smith 2866991f827SBarry Smith Output Parameters: 2876991f827SBarry Smith + n - number of string entries 2886991f827SBarry Smith - list - array of strings 2896991f827SBarry Smith 2906991f827SBarry Smith Level: intermediate 2916991f827SBarry Smith 29295452b02SPatrick Sanan Notes: 29395452b02SPatrick Sanan Not for use in Fortran 2946991f827SBarry Smith 295db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()` 2966991f827SBarry Smith 2976991f827SBarry Smith @*/ 2986991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n, char ***list) 2996991f827SBarry Smith { 3006991f827SBarry Smith PetscFunctionBegin; 3016991f827SBarry Smith if (!*list) PetscFunctionReturn(0); 3029566063dSJacob Faibussowitsch for (PetscInt i=0; i<n; i++) PetscCall(PetscFree((*list)[i])); 3039566063dSJacob Faibussowitsch PetscCall(PetscFree(*list)); 3046991f827SBarry Smith PetscFunctionReturn(0); 3056991f827SBarry Smith } 3066991f827SBarry Smith 307e5c89e4eSSatish Balay /*@C 308e5c89e4eSSatish Balay PetscStrcpy - Copies a string 309e5c89e4eSSatish Balay 310e5c89e4eSSatish Balay Not Collective 311e5c89e4eSSatish Balay 312e5c89e4eSSatish Balay Input Parameters: 313e5c89e4eSSatish Balay . t - pointer to string 314e5c89e4eSSatish Balay 315e5c89e4eSSatish Balay Output Parameter: 316e5c89e4eSSatish Balay . s - the copied string 317e5c89e4eSSatish Balay 318e5c89e4eSSatish Balay Level: intermediate 319e5c89e4eSSatish Balay 3206f013253SBarry Smith Notes: 321e5c89e4eSSatish Balay Null string returns a string starting with zero 322e5c89e4eSSatish Balay 3236f013253SBarry Smith Not for use in Fortran 3246f013253SBarry Smith 3250ecf5a55SBarry Smith It is recommended you use PetscStrncpy() instead of this routine 3260ecf5a55SBarry Smith 327db781477SPatrick Sanan .seealso: `PetscStrncpy()`, `PetscStrcat()`, `PetscStrlcat()` 328e5c89e4eSSatish Balay 329e5c89e4eSSatish Balay @*/ 330acc6cc86SBarry Smith 3317087cfbeSBarry Smith PetscErrorCode PetscStrcpy(char s[], const char t[]) 332e5c89e4eSSatish Balay { 333e5c89e4eSSatish Balay PetscFunctionBegin; 3345f80ce2aSJacob Faibussowitsch if (t) { 3355f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s,1); 3365f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t,2); 3375f80ce2aSJacob Faibussowitsch strcpy(s,t); 3385f80ce2aSJacob Faibussowitsch } else if (s) s[0] = 0; 339e5c89e4eSSatish Balay PetscFunctionReturn(0); 340e5c89e4eSSatish Balay } 341e5c89e4eSSatish Balay 342e5c89e4eSSatish Balay /*@C 343e5c89e4eSSatish Balay PetscStrncpy - Copies a string up to a certain length 344e5c89e4eSSatish Balay 345e5c89e4eSSatish Balay Not Collective 346e5c89e4eSSatish Balay 347e5c89e4eSSatish Balay Input Parameters: 348e5c89e4eSSatish Balay + t - pointer to string 349e5c89e4eSSatish Balay - n - the length to copy 350e5c89e4eSSatish Balay 351e5c89e4eSSatish Balay Output Parameter: 352e5c89e4eSSatish Balay . s - the copied string 353e5c89e4eSSatish Balay 354e5c89e4eSSatish Balay Level: intermediate 355e5c89e4eSSatish Balay 356e5c89e4eSSatish Balay Note: 357e5c89e4eSSatish Balay Null string returns a string starting with zero 358e5c89e4eSSatish Balay 359ff32304bSBarry Smith If the string that is being copied is of length n or larger then the entire string is not 3601b6ef838SBarry Smith copied and the final location of s is set to NULL. This is different then the behavior of 3611b6ef838SBarry Smith strncpy() which leaves s non-terminated if there is not room for the entire string. 362ff32304bSBarry Smith 36362a5de14SBarry Smith Developers Note: Should this be PetscStrlcpy() to reflect its behavior which is like strlcpy() not strncpy() 36462a5de14SBarry Smith 365db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrcat()`, `PetscStrlcat()` 366e5c89e4eSSatish Balay 367e5c89e4eSSatish Balay @*/ 3687087cfbeSBarry Smith PetscErrorCode PetscStrncpy(char s[], const char t[], size_t n) 369e5c89e4eSSatish Balay { 370e5c89e4eSSatish Balay PetscFunctionBegin; 3715f80ce2aSJacob Faibussowitsch if (s) PetscCheck(n,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Requires an output string of length at least 1 to hold the termination character"); 372ff32304bSBarry Smith if (t) { 3735f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s,1); 3748dc57659SBarry Smith if (n > 1) { 3752c26941aSBarry Smith strncpy(s,t,n-1); 376ff32304bSBarry Smith s[n-1] = '\0'; 3778dc57659SBarry Smith } else { 3788dc57659SBarry Smith s[0] = '\0'; 3798dc57659SBarry Smith } 380ff32304bSBarry Smith } else if (s) s[0] = 0; 381e5c89e4eSSatish Balay PetscFunctionReturn(0); 382e5c89e4eSSatish Balay } 383e5c89e4eSSatish Balay 384e5c89e4eSSatish Balay /*@C 385e5c89e4eSSatish Balay PetscStrcat - Concatenates a string onto a given string 386e5c89e4eSSatish Balay 387e5c89e4eSSatish Balay Not Collective 388e5c89e4eSSatish Balay 389e5c89e4eSSatish Balay Input Parameters: 390e5e2177aSMatthew Knepley + s - string to be added to 391e5e2177aSMatthew Knepley - t - pointer to string to be added to end 392e5c89e4eSSatish Balay 393e5c89e4eSSatish Balay Level: intermediate 394e5c89e4eSSatish Balay 39595452b02SPatrick Sanan Notes: 39695452b02SPatrick Sanan Not for use in Fortran 3976f013253SBarry Smith 3980ecf5a55SBarry Smith It is recommended you use PetscStrlcat() instead of this routine 3990ecf5a55SBarry Smith 400db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrncpy()`, `PetscStrlcat()` 401e5c89e4eSSatish Balay 402e5c89e4eSSatish Balay @*/ 4037087cfbeSBarry Smith PetscErrorCode PetscStrcat(char s[], const char t[]) 404e5c89e4eSSatish Balay { 405e5c89e4eSSatish Balay PetscFunctionBegin; 4069b754dc9SBarry Smith if (!t) PetscFunctionReturn(0); 4075f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s,1); 4085f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t,2); 409e5c89e4eSSatish Balay strcat(s,t); 410e5c89e4eSSatish Balay PetscFunctionReturn(0); 411e5c89e4eSSatish Balay } 412e5c89e4eSSatish Balay 413e5c89e4eSSatish Balay /*@C 414a126751eSBarry Smith PetscStrlcat - Concatenates a string onto a given string, up to a given length 415e5c89e4eSSatish Balay 416e5c89e4eSSatish Balay Not Collective 417e5c89e4eSSatish Balay 418e5c89e4eSSatish Balay Input Parameters: 419e0ffd71fSBarry Smith + s - pointer to string to be added to at end 42072fa4726SStefano Zampini . t - string to be added 42124a58d73SPatrick Sanan - n - length of the original allocated string 422e5c89e4eSSatish Balay 423e5c89e4eSSatish Balay Level: intermediate 424e5c89e4eSSatish Balay 42524a58d73SPatrick Sanan Notes: 42624a58d73SPatrick Sanan Not for use in Fortran 4276f013253SBarry Smith 42824a58d73SPatrick Sanan Unlike the system call strncat(), the length passed in is the length of the 42924a58d73SPatrick Sanan original allocated space, not the length of the left-over space. This is 43024a58d73SPatrick Sanan similar to the BSD system call strlcat(). 431153a8027SBarry Smith 432db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrncpy()`, `PetscStrcat()` 433e5c89e4eSSatish Balay 434e5c89e4eSSatish Balay @*/ 435a126751eSBarry Smith PetscErrorCode PetscStrlcat(char s[], const char t[], size_t n) 436e5c89e4eSSatish Balay { 437153a8027SBarry Smith size_t len; 438153a8027SBarry Smith 439e5c89e4eSSatish Balay PetscFunctionBegin; 440e0ffd71fSBarry Smith if (!t) PetscFunctionReturn(0); 4415f80ce2aSJacob Faibussowitsch PetscValidCharPointer(s,1); 4425f80ce2aSJacob Faibussowitsch PetscValidCharPointer(t,2); 4435f80ce2aSJacob Faibussowitsch PetscCheck(n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"String buffer length must be positive"); 4449566063dSJacob Faibussowitsch PetscCall(PetscStrlen(t,&len)); 445153a8027SBarry Smith strncat(s,t,n - len); 446681eeb0aSBarry Smith s[n-1] = 0; 447e5c89e4eSSatish Balay PetscFunctionReturn(0); 448e5c89e4eSSatish Balay } 449e5c89e4eSSatish Balay 450573b0fb4SBarry Smith void PetscStrcmpNoError(const char a[], const char b[], PetscBool *flg) 451573b0fb4SBarry Smith { 452573b0fb4SBarry Smith if (!a && !b) *flg = PETSC_TRUE; 453573b0fb4SBarry Smith else if (!a || !b) *flg = PETSC_FALSE; 4545f80ce2aSJacob Faibussowitsch else *flg = strcmp(a,b) ? PETSC_FALSE : PETSC_TRUE; 455573b0fb4SBarry Smith } 456573b0fb4SBarry Smith 457e5c89e4eSSatish Balay /*@C 458*660278c0SBarry Smith PetscBasename - returns a pointer to the last entry of a / or \ seperated directory path 45980b92c66SBarry Smith 46080b92c66SBarry Smith Not Collective 46180b92c66SBarry Smith 46280b92c66SBarry Smith Input Parameter: 46380b92c66SBarry Smith . a - pointer to string 46480b92c66SBarry Smith 46580b92c66SBarry Smith Level: intermediate 46680b92c66SBarry Smith 46780b92c66SBarry Smith Notes: 46880b92c66SBarry Smith Not for use in Fortran 46980b92c66SBarry Smith 470*660278c0SBarry Smith Works for both Unix and Windows path separators 471*660278c0SBarry Smith 47280b92c66SBarry Smith .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`, `PetscStrrchr()`,`PetscStrcmp()`,`PetscStrstr()`, 47380b92c66SBarry Smith `PetscTokenCreate()`, `PetscStrToArray()`, `PetscStrInList()` 47480b92c66SBarry Smith @*/ 47580b92c66SBarry Smith const char *PetscBasename(const char a[]) 47680b92c66SBarry Smith { 47780b92c66SBarry Smith const char *ptr; 47880b92c66SBarry Smith 47980b92c66SBarry Smith if (PetscStrrchr(a,'/',(char **)&ptr)) ptr = NULL; 480*660278c0SBarry Smith if (ptr == a) { 481*660278c0SBarry Smith if (PetscStrrchr(a,'\\',(char **)&ptr)) ptr = NULL; 482*660278c0SBarry Smith } 48380b92c66SBarry Smith return ptr; 48480b92c66SBarry Smith } 48580b92c66SBarry Smith 48680b92c66SBarry Smith /*@C 487e5c89e4eSSatish Balay PetscStrcmp - Compares two strings, 488e5c89e4eSSatish Balay 489e5c89e4eSSatish Balay Not Collective 490e5c89e4eSSatish Balay 491e5c89e4eSSatish Balay Input Parameters: 492e5c89e4eSSatish Balay + a - pointer to string first string 493e5c89e4eSSatish Balay - b - pointer to second string 494e5c89e4eSSatish Balay 495e5c89e4eSSatish Balay Output Parameter: 4968c74ee41SBarry Smith . flg - PETSC_TRUE if the two strings are equal 497e5c89e4eSSatish Balay 498e5c89e4eSSatish Balay Level: intermediate 499e5c89e4eSSatish Balay 50095452b02SPatrick Sanan Notes: 50195452b02SPatrick Sanan Not for use in Fortran 5026f013253SBarry Smith 503db781477SPatrick Sanan .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()` 504e5c89e4eSSatish Balay @*/ 5057087cfbeSBarry Smith PetscErrorCode PetscStrcmp(const char a[],const char b[],PetscBool *flg) 506e5c89e4eSSatish Balay { 507e5c89e4eSSatish Balay PetscFunctionBegin; 5085f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg,3); 509a297a907SKarl Rupp if (!a && !b) *flg = PETSC_TRUE; 510a297a907SKarl Rupp else if (!a || !b) *flg = PETSC_FALSE; 511b45e3bf4SStefano Zampini else *flg = (PetscBool)!strcmp(a,b); 512e5c89e4eSSatish Balay PetscFunctionReturn(0); 513e5c89e4eSSatish Balay } 514e5c89e4eSSatish Balay 515e5c89e4eSSatish Balay /*@C 516e5c89e4eSSatish Balay PetscStrgrt - If first string is greater than the second 517e5c89e4eSSatish Balay 518e5c89e4eSSatish Balay Not Collective 519e5c89e4eSSatish Balay 520e5c89e4eSSatish Balay Input Parameters: 521e5c89e4eSSatish Balay + a - pointer to first string 522e5c89e4eSSatish Balay - b - pointer to second string 523e5c89e4eSSatish Balay 524e5c89e4eSSatish Balay Output Parameter: 525e5c89e4eSSatish Balay . flg - if the first string is greater 526e5c89e4eSSatish Balay 527e5c89e4eSSatish Balay Notes: 528e5c89e4eSSatish Balay Null arguments are ok, a null string is considered smaller than 529e5c89e4eSSatish Balay all others 530e5c89e4eSSatish Balay 5316f013253SBarry Smith Not for use in Fortran 5326f013253SBarry Smith 533e5c89e4eSSatish Balay Level: intermediate 534e5c89e4eSSatish Balay 535db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrcasecmp()` 536e5c89e4eSSatish Balay 537e5c89e4eSSatish Balay @*/ 5387087cfbeSBarry Smith PetscErrorCode PetscStrgrt(const char a[], const char b[], PetscBool *t) 539e5c89e4eSSatish Balay { 540e5c89e4eSSatish Balay PetscFunctionBegin; 5415f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t,3); 542a297a907SKarl Rupp if (!a && !b) *t = PETSC_FALSE; 543a297a907SKarl Rupp else if (a && !b) *t = PETSC_TRUE; 544a297a907SKarl Rupp else if (!a && b) *t = PETSC_FALSE; 545a297a907SKarl Rupp else { 5465f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 5475f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b,2); 5485f80ce2aSJacob Faibussowitsch *t = strcmp(a,b) > 0 ? PETSC_TRUE : PETSC_FALSE; 549e5c89e4eSSatish Balay } 550e5c89e4eSSatish Balay PetscFunctionReturn(0); 551e5c89e4eSSatish Balay } 552e5c89e4eSSatish Balay 553e5c89e4eSSatish Balay /*@C 554e5c89e4eSSatish Balay PetscStrcasecmp - Returns true if the two strings are the same 555e5c89e4eSSatish Balay except possibly for case. 556e5c89e4eSSatish Balay 557e5c89e4eSSatish Balay Not Collective 558e5c89e4eSSatish Balay 559e5c89e4eSSatish Balay Input Parameters: 560e5c89e4eSSatish Balay + a - pointer to first string 561e5c89e4eSSatish Balay - b - pointer to second string 562e5c89e4eSSatish Balay 563e5c89e4eSSatish Balay Output Parameter: 564e5c89e4eSSatish Balay . flg - if the two strings are the same 565e5c89e4eSSatish Balay 566e5c89e4eSSatish Balay Notes: 567e5c89e4eSSatish Balay Null arguments are ok 568e5c89e4eSSatish Balay 5696f013253SBarry Smith Not for use in Fortran 5706f013253SBarry Smith 571e5c89e4eSSatish Balay Level: intermediate 572e5c89e4eSSatish Balay 573db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrgrt()` 574e5c89e4eSSatish Balay 575e5c89e4eSSatish Balay @*/ 5767087cfbeSBarry Smith PetscErrorCode PetscStrcasecmp(const char a[], const char b[], PetscBool *t) 577e5c89e4eSSatish Balay { 578e5c89e4eSSatish Balay int c; 579e5c89e4eSSatish Balay 580e5c89e4eSSatish Balay PetscFunctionBegin; 5815f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t,3); 582e5c89e4eSSatish Balay if (!a && !b) c = 0; 583e5c89e4eSSatish Balay else if (!a || !b) c = 1; 58432b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP) 58532b366c8SSatish Balay else c = strcasecmp(a,b); 58632b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP) 587e5c89e4eSSatish Balay else c = stricmp(a,b); 588e5c89e4eSSatish Balay #else 58932b366c8SSatish Balay else { 59032b366c8SSatish Balay char *aa,*bb; 5919566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a,&aa)); 5929566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(b,&bb)); 5939566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(aa)); 5949566063dSJacob Faibussowitsch PetscCall(PetscStrtolower(bb)); 5959566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(aa,bb,t)); 5969566063dSJacob Faibussowitsch PetscCall(PetscFree(aa)); 5979566063dSJacob Faibussowitsch PetscCall(PetscFree(bb)); 59832b366c8SSatish Balay PetscFunctionReturn(0); 59932b366c8SSatish Balay } 600e5c89e4eSSatish Balay #endif 6015f80ce2aSJacob Faibussowitsch *t = c ? PETSC_FALSE : PETSC_TRUE; 602e5c89e4eSSatish Balay PetscFunctionReturn(0); 603e5c89e4eSSatish Balay } 604e5c89e4eSSatish Balay 605e5c89e4eSSatish Balay /*@C 606e5c89e4eSSatish Balay PetscStrncmp - Compares two strings, up to a certain length 607e5c89e4eSSatish Balay 608e5c89e4eSSatish Balay Not Collective 609e5c89e4eSSatish Balay 610e5c89e4eSSatish Balay Input Parameters: 611e5c89e4eSSatish Balay + a - pointer to first string 612e5c89e4eSSatish Balay . b - pointer to second string 613e5c89e4eSSatish Balay - n - length to compare up to 614e5c89e4eSSatish Balay 615e5c89e4eSSatish Balay Output Parameter: 616e5c89e4eSSatish Balay . t - if the two strings are equal 617e5c89e4eSSatish Balay 618e5c89e4eSSatish Balay Level: intermediate 619e5c89e4eSSatish Balay 62095452b02SPatrick Sanan Notes: 62195452b02SPatrick Sanan Not for use in Fortran 6226f013253SBarry Smith 623db781477SPatrick Sanan .seealso: `PetscStrgrt()`, `PetscStrcmp()`, `PetscStrcasecmp()` 624e5c89e4eSSatish Balay 625e5c89e4eSSatish Balay @*/ 6267087cfbeSBarry Smith PetscErrorCode PetscStrncmp(const char a[], const char b[], size_t n, PetscBool *t) 627e5c89e4eSSatish Balay { 628e5c89e4eSSatish Balay PetscFunctionBegin; 6295f80ce2aSJacob Faibussowitsch if (n) { 6305f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 6315f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b,2); 6325f80ce2aSJacob Faibussowitsch } 6335f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(t,4); 6345f80ce2aSJacob Faibussowitsch *t = strncmp(a,b,n) ? PETSC_FALSE : PETSC_TRUE; 635e5c89e4eSSatish Balay PetscFunctionReturn(0); 636e5c89e4eSSatish Balay } 637e5c89e4eSSatish Balay 638e5c89e4eSSatish Balay /*@C 639a5b23f4aSJose E. Roman PetscStrchr - Locates first occurrence of a character in a string 640e5c89e4eSSatish Balay 641e5c89e4eSSatish Balay Not Collective 642e5c89e4eSSatish Balay 643e5c89e4eSSatish Balay Input Parameters: 644e5c89e4eSSatish Balay + a - pointer to string 645e5c89e4eSSatish Balay - b - character 646e5c89e4eSSatish Balay 647e5c89e4eSSatish Balay Output Parameter: 648a5b23f4aSJose E. Roman . c - location of occurrence, NULL if not found 649e5c89e4eSSatish Balay 650e5c89e4eSSatish Balay Level: intermediate 651e5c89e4eSSatish Balay 65295452b02SPatrick Sanan Notes: 65395452b02SPatrick Sanan Not for use in Fortran 6546f013253SBarry Smith 655e5c89e4eSSatish Balay @*/ 6567087cfbeSBarry Smith PetscErrorCode PetscStrchr(const char a[], char b, char *c[]) 657e5c89e4eSSatish Balay { 658e5c89e4eSSatish Balay PetscFunctionBegin; 6595f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 6605f80ce2aSJacob Faibussowitsch PetscValidPointer(c,3); 661e5c89e4eSSatish Balay *c = (char*)strchr(a,b); 662e5c89e4eSSatish Balay PetscFunctionReturn(0); 663e5c89e4eSSatish Balay } 664e5c89e4eSSatish Balay 665e5c89e4eSSatish Balay /*@C 666a5b23f4aSJose E. Roman PetscStrrchr - Locates one location past the last occurrence of a character in a string, 667e5c89e4eSSatish Balay if the character is not found then returns entire string 668e5c89e4eSSatish Balay 669e5c89e4eSSatish Balay Not Collective 670e5c89e4eSSatish Balay 671e5c89e4eSSatish Balay Input Parameters: 672e5c89e4eSSatish Balay + a - pointer to string 673e5c89e4eSSatish Balay - b - character 674e5c89e4eSSatish Balay 675e5c89e4eSSatish Balay Output Parameter: 676a5b23f4aSJose E. Roman . tmp - location of occurrence, a if not found 677e5c89e4eSSatish Balay 678e5c89e4eSSatish Balay Level: intermediate 679e5c89e4eSSatish Balay 68095452b02SPatrick Sanan Notes: 68195452b02SPatrick Sanan Not for use in Fortran 6826f013253SBarry Smith 683e5c89e4eSSatish Balay @*/ 6847087cfbeSBarry Smith PetscErrorCode PetscStrrchr(const char a[], char b, char *tmp[]) 685e5c89e4eSSatish Balay { 686e5c89e4eSSatish Balay PetscFunctionBegin; 6875f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 6885f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp,3); 689e5c89e4eSSatish Balay *tmp = (char*)strrchr(a,b); 690a297a907SKarl Rupp if (!*tmp) *tmp = (char*)a; 691a297a907SKarl Rupp else *tmp = *tmp + 1; 692e5c89e4eSSatish Balay PetscFunctionReturn(0); 693e5c89e4eSSatish Balay } 694e5c89e4eSSatish Balay 695e5c89e4eSSatish Balay /*@C 696e5c89e4eSSatish Balay PetscStrtolower - Converts string to lower case 697e5c89e4eSSatish Balay 698e5c89e4eSSatish Balay Not Collective 699e5c89e4eSSatish Balay 700e5c89e4eSSatish Balay Input Parameters: 701e5c89e4eSSatish Balay . a - pointer to string 702e5c89e4eSSatish Balay 703e5c89e4eSSatish Balay Level: intermediate 704e5c89e4eSSatish Balay 70595452b02SPatrick Sanan Notes: 70695452b02SPatrick Sanan Not for use in Fortran 7076f013253SBarry Smith 708e5c89e4eSSatish Balay @*/ 7097087cfbeSBarry Smith PetscErrorCode PetscStrtolower(char a[]) 710e5c89e4eSSatish Balay { 711e5c89e4eSSatish Balay PetscFunctionBegin; 7125f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 713e5c89e4eSSatish Balay while (*a) { 714e5c89e4eSSatish Balay if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 715e5c89e4eSSatish Balay a++; 716e5c89e4eSSatish Balay } 717e5c89e4eSSatish Balay PetscFunctionReturn(0); 718e5c89e4eSSatish Balay } 719e5c89e4eSSatish Balay 7202f234a98SBarry Smith /*@C 7216e3a5469SBarry Smith PetscStrtoupper - Converts string to upper case 7222f234a98SBarry Smith 7232f234a98SBarry Smith Not Collective 7242f234a98SBarry Smith 7252f234a98SBarry Smith Input Parameters: 7262f234a98SBarry Smith . a - pointer to string 7272f234a98SBarry Smith 7282f234a98SBarry Smith Level: intermediate 7292f234a98SBarry Smith 73095452b02SPatrick Sanan Notes: 73195452b02SPatrick Sanan Not for use in Fortran 7322f234a98SBarry Smith 7332f234a98SBarry Smith @*/ 7342f234a98SBarry Smith PetscErrorCode PetscStrtoupper(char a[]) 7352f234a98SBarry Smith { 7362f234a98SBarry Smith PetscFunctionBegin; 7375f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 7382f234a98SBarry Smith while (*a) { 7392f234a98SBarry Smith if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a'; 7402f234a98SBarry Smith a++; 7412f234a98SBarry Smith } 7422f234a98SBarry Smith PetscFunctionReturn(0); 7432f234a98SBarry Smith } 7442f234a98SBarry Smith 7457ba3a57cSBarry Smith /*@C 7467ba3a57cSBarry Smith PetscStrendswith - Determines if a string ends with a certain string 7471d1a0024SBarry Smith 7487ba3a57cSBarry Smith Not Collective 7497ba3a57cSBarry Smith 7507ba3a57cSBarry Smith Input Parameters: 7517ba3a57cSBarry Smith + a - pointer to string 7527ba3a57cSBarry Smith - b - string to endwith 7537ba3a57cSBarry Smith 7547ba3a57cSBarry Smith Output Parameter: 7557ba3a57cSBarry Smith . flg - PETSC_TRUE or PETSC_FALSE 7567ba3a57cSBarry Smith 75795452b02SPatrick Sanan Notes: 75895452b02SPatrick Sanan Not for use in Fortran 7597ba3a57cSBarry Smith 7607ba3a57cSBarry Smith Level: intermediate 7617ba3a57cSBarry Smith 7627ba3a57cSBarry Smith @*/ 7637ba3a57cSBarry Smith PetscErrorCode PetscStrendswith(const char a[], const char b[], PetscBool *flg) 7647ba3a57cSBarry Smith { 7657ba3a57cSBarry Smith char *test; 7667ba3a57cSBarry Smith 7677ba3a57cSBarry Smith PetscFunctionBegin; 7685f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg,3); 7697ba3a57cSBarry Smith *flg = PETSC_FALSE; 7709566063dSJacob Faibussowitsch PetscCall(PetscStrrstr(a,b,&test)); 7717ba3a57cSBarry Smith if (test) { 7725f80ce2aSJacob Faibussowitsch size_t na,nb; 7735f80ce2aSJacob Faibussowitsch 7749566063dSJacob Faibussowitsch PetscCall(PetscStrlen(a,&na)); 7759566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b,&nb)); 7767ba3a57cSBarry Smith if (a+na-nb == test) *flg = PETSC_TRUE; 7777ba3a57cSBarry Smith } 7787ba3a57cSBarry Smith PetscFunctionReturn(0); 7797ba3a57cSBarry Smith } 7807ba3a57cSBarry Smith 7812c9581d2SBarry Smith /*@C 7822c9581d2SBarry Smith PetscStrbeginswith - Determines if a string begins with a certain string 7832c9581d2SBarry Smith 7842c9581d2SBarry Smith Not Collective 7852c9581d2SBarry Smith 7862c9581d2SBarry Smith Input Parameters: 7872c9581d2SBarry Smith + a - pointer to string 7882c9581d2SBarry Smith - b - string to begin with 7892c9581d2SBarry Smith 7902c9581d2SBarry Smith Output Parameter: 7912c9581d2SBarry Smith . flg - PETSC_TRUE or PETSC_FALSE 7922c9581d2SBarry Smith 79395452b02SPatrick Sanan Notes: 79495452b02SPatrick Sanan Not for use in Fortran 7952c9581d2SBarry Smith 7962c9581d2SBarry Smith Level: intermediate 7972c9581d2SBarry Smith 798db781477SPatrick Sanan .seealso: `PetscStrendswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`, 799db781477SPatrick Sanan `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()` 8006e3a5469SBarry Smith 8012c9581d2SBarry Smith @*/ 8022c9581d2SBarry Smith PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg) 8032c9581d2SBarry Smith { 8042c9581d2SBarry Smith char *test; 8052c9581d2SBarry Smith 8062c9581d2SBarry Smith PetscFunctionBegin; 8075f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 8085f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b,2); 8095f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(flg,3); 8102c9581d2SBarry Smith *flg = PETSC_FALSE; 8119566063dSJacob Faibussowitsch PetscCall(PetscStrrstr(a,b,&test)); 812a297a907SKarl Rupp if (test && (test == a)) *flg = PETSC_TRUE; 8132c9581d2SBarry Smith PetscFunctionReturn(0); 8142c9581d2SBarry Smith } 8152c9581d2SBarry Smith 8167ba3a57cSBarry Smith /*@C 8177ba3a57cSBarry Smith PetscStrendswithwhich - Determines if a string ends with one of several possible strings 8187ba3a57cSBarry Smith 8197ba3a57cSBarry Smith Not Collective 8207ba3a57cSBarry Smith 8217ba3a57cSBarry Smith Input Parameters: 8227ba3a57cSBarry Smith + a - pointer to string 823fa4b66f2SVaclav Hapla - bs - strings to end with (last entry must be NULL) 8247ba3a57cSBarry Smith 8257ba3a57cSBarry Smith Output Parameter: 826fa4b66f2SVaclav Hapla . cnt - the index of the string it ends with or the index of NULL 8277ba3a57cSBarry Smith 82895452b02SPatrick Sanan Notes: 82995452b02SPatrick Sanan Not for use in Fortran 8307ba3a57cSBarry Smith 8317ba3a57cSBarry Smith Level: intermediate 8327ba3a57cSBarry Smith 8337ba3a57cSBarry Smith @*/ 8347ba3a57cSBarry Smith PetscErrorCode PetscStrendswithwhich(const char a[], const char *const *bs, PetscInt *cnt) 8357ba3a57cSBarry Smith { 8367ba3a57cSBarry Smith PetscFunctionBegin; 8375f80ce2aSJacob Faibussowitsch PetscValidPointer(bs,2); 8385f80ce2aSJacob Faibussowitsch PetscValidIntPointer(cnt,3); 8397ba3a57cSBarry Smith *cnt = 0; 8407ba3a57cSBarry Smith while (bs[*cnt]) { 8415f80ce2aSJacob Faibussowitsch PetscBool flg; 8425f80ce2aSJacob Faibussowitsch 8439566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(a,bs[*cnt],&flg)); 8447ba3a57cSBarry Smith if (flg) PetscFunctionReturn(0); 8455f80ce2aSJacob Faibussowitsch ++(*cnt); 8467ba3a57cSBarry Smith } 8477ba3a57cSBarry Smith PetscFunctionReturn(0); 8487ba3a57cSBarry Smith } 8497ba3a57cSBarry Smith 8507ba3a57cSBarry Smith /*@C 851a5b23f4aSJose E. Roman PetscStrrstr - Locates last occurrence of string in another string 8527ba3a57cSBarry Smith 8537ba3a57cSBarry Smith Not Collective 8547ba3a57cSBarry Smith 8557ba3a57cSBarry Smith Input Parameters: 8567ba3a57cSBarry Smith + a - pointer to string 8577ba3a57cSBarry Smith - b - string to find 8587ba3a57cSBarry Smith 8597ba3a57cSBarry Smith Output Parameter: 860a5b23f4aSJose E. Roman . tmp - location of occurrence 8617ba3a57cSBarry Smith 86295452b02SPatrick Sanan Notes: 86395452b02SPatrick Sanan Not for use in Fortran 8647ba3a57cSBarry Smith 8657ba3a57cSBarry Smith Level: intermediate 8667ba3a57cSBarry Smith 8677ba3a57cSBarry Smith @*/ 8687ba3a57cSBarry Smith PetscErrorCode PetscStrrstr(const char a[], const char b[], char *tmp[]) 8697ba3a57cSBarry Smith { 8705f80ce2aSJacob Faibussowitsch const char *ltmp = NULL; 8717ba3a57cSBarry Smith 8727ba3a57cSBarry Smith PetscFunctionBegin; 8735f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 8745f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b,2); 8755f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp,3); 8765f80ce2aSJacob Faibussowitsch while (a) { 8775f80ce2aSJacob Faibussowitsch a = (char*)strstr(a,b); 8785f80ce2aSJacob Faibussowitsch if (a) ltmp = a++; 8797ba3a57cSBarry Smith } 8807ba3a57cSBarry Smith *tmp = (char*)ltmp; 8817ba3a57cSBarry Smith PetscFunctionReturn(0); 8827ba3a57cSBarry Smith } 8837ba3a57cSBarry Smith 8847ba3a57cSBarry Smith /*@C 885a5b23f4aSJose E. Roman PetscStrstr - Locates first occurrence of string in another string 8867ba3a57cSBarry Smith 8877ba3a57cSBarry Smith Not Collective 8887ba3a57cSBarry Smith 8897ba3a57cSBarry Smith Input Parameters: 890160f4796SJed Brown + haystack - string to search 891160f4796SJed Brown - needle - string to find 8927ba3a57cSBarry Smith 8937ba3a57cSBarry Smith Output Parameter: 894a5b23f4aSJose E. Roman . tmp - location of occurrence, is a NULL if the string is not found 8957ba3a57cSBarry Smith 89695452b02SPatrick Sanan Notes: 89795452b02SPatrick Sanan Not for use in Fortran 8987ba3a57cSBarry Smith 8997ba3a57cSBarry Smith Level: intermediate 9007ba3a57cSBarry Smith 9017ba3a57cSBarry Smith @*/ 902160f4796SJed Brown PetscErrorCode PetscStrstr(const char haystack[],const char needle[],char *tmp[]) 9037ba3a57cSBarry Smith { 9047ba3a57cSBarry Smith PetscFunctionBegin; 9055f80ce2aSJacob Faibussowitsch PetscValidCharPointer(haystack,1); 9065f80ce2aSJacob Faibussowitsch PetscValidCharPointer(needle,2); 9075f80ce2aSJacob Faibussowitsch PetscValidPointer(tmp,3); 908160f4796SJed Brown *tmp = (char*)strstr(haystack,needle); 9097ba3a57cSBarry Smith PetscFunctionReturn(0); 9107ba3a57cSBarry Smith } 9117ba3a57cSBarry Smith 9127ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;}; 9131d1a0024SBarry Smith 914e5c89e4eSSatish Balay /*@C 915e5c89e4eSSatish Balay PetscTokenFind - Locates next "token" in a string 916e5c89e4eSSatish Balay 917e5c89e4eSSatish Balay Not Collective 918e5c89e4eSSatish Balay 919e5c89e4eSSatish Balay Input Parameters: 920e5c89e4eSSatish Balay . a - pointer to token 921e5c89e4eSSatish Balay 922e5c89e4eSSatish Balay Output Parameter: 923a5b23f4aSJose E. Roman . result - location of occurrence, NULL if not found 924e5c89e4eSSatish Balay 925e5c89e4eSSatish Balay Notes: 926e5c89e4eSSatish Balay 927e5c89e4eSSatish Balay This version is different from the system version in that 928e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 929e5c89e4eSSatish Balay 9304704e885SBarry Smith This version also treats all characters etc. inside a double quote " 9314704e885SBarry Smith as a single token. 9324704e885SBarry Smith 9333a9c465aSBarry 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 9343a9c465aSBarry Smith second will return a null terminated y 9353a9c465aSBarry Smith 9363a9c465aSBarry 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 9373a9c465aSBarry Smith 9386f013253SBarry Smith Not for use in Fortran 9396f013253SBarry Smith 940e5c89e4eSSatish Balay Level: intermediate 941e5c89e4eSSatish Balay 942db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenDestroy()` 943e5c89e4eSSatish Balay @*/ 9447087cfbeSBarry Smith PetscErrorCode PetscTokenFind(PetscToken a, char *result[]) 945e5c89e4eSSatish Balay { 9465f80ce2aSJacob Faibussowitsch char *ptr,token; 947e5c89e4eSSatish Balay 948e5c89e4eSSatish Balay PetscFunctionBegin; 9495f80ce2aSJacob Faibussowitsch PetscValidPointer(a,1); 9505f80ce2aSJacob Faibussowitsch PetscValidPointer(result,2); 9515f80ce2aSJacob Faibussowitsch *result = ptr = a->current; 95202c9f0b5SLisandro Dalcin if (ptr && !*ptr) {*result = NULL; PetscFunctionReturn(0);} 9534704e885SBarry Smith token = a->token; 95490fdf44cSMatthew Knepley if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;} 955e5c89e4eSSatish Balay while (ptr) { 9564704e885SBarry Smith if (*ptr == token) { 957e5c89e4eSSatish Balay *ptr++ = 0; 958e5c89e4eSSatish Balay while (*ptr == a->token) ptr++; 959e5c89e4eSSatish Balay a->current = ptr; 960e5c89e4eSSatish Balay break; 961e5c89e4eSSatish Balay } 962e5c89e4eSSatish Balay if (!*ptr) { 96302c9f0b5SLisandro Dalcin a->current = NULL; 964e5c89e4eSSatish Balay break; 965e5c89e4eSSatish Balay } 966e5c89e4eSSatish Balay ptr++; 967e5c89e4eSSatish Balay } 968e5c89e4eSSatish Balay PetscFunctionReturn(0); 969e5c89e4eSSatish Balay } 970e5c89e4eSSatish Balay 971e5c89e4eSSatish Balay /*@C 972e5c89e4eSSatish Balay PetscTokenCreate - Creates a PetscToken used to find tokens in a string 973e5c89e4eSSatish Balay 974e5c89e4eSSatish Balay Not Collective 975e5c89e4eSSatish Balay 976e5c89e4eSSatish Balay Input Parameters: 977e5c89e4eSSatish Balay + string - the string to look in 9783a9c465aSBarry Smith - b - the separator character 979e5c89e4eSSatish Balay 980e5c89e4eSSatish Balay Output Parameter: 9813a9c465aSBarry Smith . t- the token object 982e5c89e4eSSatish Balay 983e5c89e4eSSatish Balay Notes: 984e5c89e4eSSatish Balay 985e5c89e4eSSatish Balay This version is different from the system version in that 986e5c89e4eSSatish Balay it allows you to pass a read-only string into the function. 987e5c89e4eSSatish Balay 9886f013253SBarry Smith Not for use in Fortran 9896f013253SBarry Smith 990e5c89e4eSSatish Balay Level: intermediate 991e5c89e4eSSatish Balay 992db781477SPatrick Sanan .seealso: `PetscTokenFind()`, `PetscTokenDestroy()` 993e5c89e4eSSatish Balay @*/ 9947087cfbeSBarry Smith PetscErrorCode PetscTokenCreate(const char a[], const char b, PetscToken *t) 995e5c89e4eSSatish Balay { 996e5c89e4eSSatish Balay PetscFunctionBegin; 9975f80ce2aSJacob Faibussowitsch PetscValidCharPointer(a,1); 9985f80ce2aSJacob Faibussowitsch PetscValidPointer(t,3); 9999566063dSJacob Faibussowitsch PetscCall(PetscNew(t)); 10009566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(a,&(*t)->array)); 1001a297a907SKarl Rupp 1002e5c89e4eSSatish Balay (*t)->current = (*t)->array; 1003e5c89e4eSSatish Balay (*t)->token = b; 1004e5c89e4eSSatish Balay PetscFunctionReturn(0); 1005e5c89e4eSSatish Balay } 1006e5c89e4eSSatish Balay 1007e5c89e4eSSatish Balay /*@C 1008e5c89e4eSSatish Balay PetscTokenDestroy - Destroys a PetscToken 1009e5c89e4eSSatish Balay 1010e5c89e4eSSatish Balay Not Collective 1011e5c89e4eSSatish Balay 1012e5c89e4eSSatish Balay Input Parameters: 1013e5c89e4eSSatish Balay . a - pointer to token 1014e5c89e4eSSatish Balay 1015e5c89e4eSSatish Balay Level: intermediate 1016e5c89e4eSSatish Balay 101795452b02SPatrick Sanan Notes: 101895452b02SPatrick Sanan Not for use in Fortran 10196f013253SBarry Smith 1020db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()` 1021e5c89e4eSSatish Balay @*/ 10228c74ee41SBarry Smith PetscErrorCode PetscTokenDestroy(PetscToken *a) 1023e5c89e4eSSatish Balay { 1024e5c89e4eSSatish Balay PetscFunctionBegin; 10258c74ee41SBarry Smith if (!*a) PetscFunctionReturn(0); 10269566063dSJacob Faibussowitsch PetscCall(PetscFree((*a)->array)); 10279566063dSJacob Faibussowitsch PetscCall(PetscFree(*a)); 1028e5c89e4eSSatish Balay PetscFunctionReturn(0); 1029e5c89e4eSSatish Balay } 1030e5c89e4eSSatish Balay 10318e81d068SLisandro Dalcin /*@C 10328e81d068SLisandro Dalcin PetscStrInList - search string in character-delimited list 10338e81d068SLisandro Dalcin 10348e81d068SLisandro Dalcin Not Collective 10358e81d068SLisandro Dalcin 10368e81d068SLisandro Dalcin Input Parameters: 10378e81d068SLisandro Dalcin + str - the string to look for 10388e81d068SLisandro Dalcin . list - the list to search in 10398e81d068SLisandro Dalcin - sep - the separator character 10408e81d068SLisandro Dalcin 10418e81d068SLisandro Dalcin Output Parameter: 10428e81d068SLisandro Dalcin . found - whether str is in list 10438e81d068SLisandro Dalcin 10448e81d068SLisandro Dalcin Level: intermediate 10458e81d068SLisandro Dalcin 104695452b02SPatrick Sanan Notes: 104795452b02SPatrick Sanan Not for use in Fortran 10488e81d068SLisandro Dalcin 1049db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscStrcmp()` 10508e81d068SLisandro Dalcin @*/ 10518e81d068SLisandro Dalcin PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found) 10528e81d068SLisandro Dalcin { 10538e81d068SLisandro Dalcin PetscToken token; 10548e81d068SLisandro Dalcin char *item; 10558e81d068SLisandro Dalcin 10568e81d068SLisandro Dalcin PetscFunctionBegin; 10575f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found,4); 10588e81d068SLisandro Dalcin *found = PETSC_FALSE; 10599566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(list,sep,&token)); 10609566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token,&item)); 10618e81d068SLisandro Dalcin while (item) { 10629566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(str,item,found)); 10638e81d068SLisandro Dalcin if (*found) break; 10649566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token,&item)); 10658e81d068SLisandro Dalcin } 10669566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 10678e81d068SLisandro Dalcin PetscFunctionReturn(0); 10688e81d068SLisandro Dalcin } 1069e5c89e4eSSatish Balay 1070e5c89e4eSSatish Balay /*@C 1071e5c89e4eSSatish Balay PetscGetPetscDir - Gets the directory PETSc is installed in 1072e5c89e4eSSatish Balay 1073e5c89e4eSSatish Balay Not Collective 1074e5c89e4eSSatish Balay 1075e5c89e4eSSatish Balay Output Parameter: 1076e5c89e4eSSatish Balay . dir - the directory 1077e5c89e4eSSatish Balay 1078e5c89e4eSSatish Balay Level: developer 1079e5c89e4eSSatish Balay 108095452b02SPatrick Sanan Notes: 108195452b02SPatrick Sanan Not for use in Fortran 10826f013253SBarry Smith 1083e5c89e4eSSatish Balay @*/ 10847087cfbeSBarry Smith PetscErrorCode PetscGetPetscDir(const char *dir[]) 1085e5c89e4eSSatish Balay { 1086e5c89e4eSSatish Balay PetscFunctionBegin; 10875f80ce2aSJacob Faibussowitsch PetscValidPointer(dir,1); 1088e5c89e4eSSatish Balay *dir = PETSC_DIR; 1089e5c89e4eSSatish Balay PetscFunctionReturn(0); 1090e5c89e4eSSatish Balay } 1091e5c89e4eSSatish Balay 1092e5c89e4eSSatish Balay /*@C 1093e5c89e4eSSatish Balay PetscStrreplace - Replaces substrings in string with other substrings 1094e5c89e4eSSatish Balay 1095e5c89e4eSSatish Balay Not Collective 1096e5c89e4eSSatish Balay 1097e5c89e4eSSatish Balay Input Parameters: 1098e5c89e4eSSatish Balay + comm - MPI_Comm of processors that are processing the string 109971573d7dSBarry Smith . aa - the string to look in 1100d8ccf1fbSBarry Smith . b - the resulting copy of a with replaced strings (b can be the same as a) 1101e5c89e4eSSatish Balay - len - the length of b 1102e5c89e4eSSatish Balay 1103e5c89e4eSSatish Balay Notes: 1104e5c89e4eSSatish Balay Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 1105d5649816SBarry Smith ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 1106e5c89e4eSSatish Balay as well as any environmental variables. 1107e5c89e4eSSatish Balay 11086f013253SBarry Smith PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what 1109acc6cc86SBarry Smith PETSc was built with and do not use environmental variables. 1110acc6cc86SBarry Smith 11116f013253SBarry Smith Not for use in Fortran 11126f013253SBarry Smith 1113e5c89e4eSSatish Balay Level: intermediate 1114e5c89e4eSSatish Balay 1115e5c89e4eSSatish Balay @*/ 11167087cfbeSBarry Smith PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len) 1117e5c89e4eSSatish Balay { 1118e5c89e4eSSatish Balay int i = 0; 1119e5c89e4eSSatish Balay size_t l,l1,l2,l3; 112071573d7dSBarry Smith char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa; 112102c9f0b5SLisandro Dalcin const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",NULL}; 112202c9f0b5SLisandro Dalcin char *r[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; 1123ace3abfcSBarry Smith PetscBool flag; 1124589a23caSBarry Smith static size_t DISPLAY_LENGTH = 265,USER_LENGTH = 256, HOST_LENGTH = 256; 1125e5c89e4eSSatish Balay 1126e5c89e4eSSatish Balay PetscFunctionBegin; 11275f80ce2aSJacob Faibussowitsch PetscValidCharPointer(aa,2); 11285f80ce2aSJacob Faibussowitsch PetscValidCharPointer(b,3); 11299566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscStrallocpy(aa,(char**)&a)); 11309566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len,&work)); 1131e5c89e4eSSatish Balay 1132e5c89e4eSSatish Balay /* get values for replaced variables */ 11339566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_ARCH,&r[0])); 11349566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_DIR,&r[1])); 11359566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(PETSC_LIB_DIR,&r[2])); 11369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(DISPLAY_LENGTH,&r[3])); 11379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4])); 11389566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5])); 11399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(USER_LENGTH,&r[6])); 11409566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(HOST_LENGTH,&r[7])); 11419566063dSJacob Faibussowitsch PetscCall(PetscGetDisplay(r[3],DISPLAY_LENGTH)); 11429566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN)); 11439566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN)); 11449566063dSJacob Faibussowitsch PetscCall(PetscGetUserName(r[6],USER_LENGTH)); 11459566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(r[7],HOST_LENGTH)); 1146487e5849SBarry Smith 1147487e5849SBarry Smith /* replace that are in environment */ 11489566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,sizeof(env),&flag)); 1149487e5849SBarry Smith if (flag) { 11509566063dSJacob Faibussowitsch PetscCall(PetscFree(r[2])); 11519566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(env,&r[2])); 1152487e5849SBarry Smith } 1153e5c89e4eSSatish Balay 1154e5c89e4eSSatish Balay /* replace the requested strings */ 11559566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b,a,len)); 1156e5c89e4eSSatish Balay while (s[i]) { 11579566063dSJacob Faibussowitsch PetscCall(PetscStrlen(s[i],&l)); 11589566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b,s[i],&par)); 1159e5c89e4eSSatish Balay while (par) { 1160e5c89e4eSSatish Balay *par = 0; 1161e5c89e4eSSatish Balay par += l; 1162e5c89e4eSSatish Balay 11639566063dSJacob Faibussowitsch PetscCall(PetscStrlen(b,&l1)); 11649566063dSJacob Faibussowitsch PetscCall(PetscStrlen(r[i],&l2)); 11659566063dSJacob Faibussowitsch PetscCall(PetscStrlen(par,&l3)); 1166cc73adaaSBarry Smith PetscCheck(l1 + l2 + l3 < len,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values"); 11679566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work,b,len)); 11689566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work,r[i],len)); 11699566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work,par,len)); 11709566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b,work,len)); 11719566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b,s[i],&par)); 1172e5c89e4eSSatish Balay } 1173e5c89e4eSSatish Balay i++; 1174e5c89e4eSSatish Balay } 1175487e5849SBarry Smith i = 0; 1176487e5849SBarry Smith while (r[i]) { 1177e5c89e4eSSatish Balay tfree = (char*)r[i]; 11789566063dSJacob Faibussowitsch PetscCall(PetscFree(tfree)); 1179487e5849SBarry Smith i++; 1180e5c89e4eSSatish Balay } 1181e5c89e4eSSatish Balay 1182e5c89e4eSSatish Balay /* look for any other ${xxx} strings to replace from environmental variables */ 11839566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b,"${",&par)); 1184e5c89e4eSSatish Balay while (par) { 1185e5c89e4eSSatish Balay *par = 0; 1186e5c89e4eSSatish Balay par += 2; 11879566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(work,b,len)); 11889566063dSJacob Faibussowitsch PetscCall(PetscStrstr(par,"}",&epar)); 1189e5c89e4eSSatish Balay *epar = 0; 1190e5c89e4eSSatish Balay epar += 1; 11919566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm,par,env,sizeof(env),&flag)); 119228b400f6SJacob Faibussowitsch PetscCheck(flag,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par); 11939566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work,env,len)); 11949566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(work,epar,len)); 11959566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(b,work,len)); 11969566063dSJacob Faibussowitsch PetscCall(PetscStrstr(b,"${",&par)); 1197e5c89e4eSSatish Balay } 11989566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 11999566063dSJacob Faibussowitsch if (aa == b) PetscCall(PetscFree(a)); 1200e5c89e4eSSatish Balay PetscFunctionReturn(0); 1201e5c89e4eSSatish Balay } 1202e5c89e4eSSatish Balay 1203a53986e1SJed Brown /*@C 1204a53986e1SJed Brown PetscEListFind - searches list of strings for given string, using case insensitive matching 1205e5c89e4eSSatish Balay 1206a53986e1SJed Brown Not Collective 1207a53986e1SJed Brown 1208a53986e1SJed Brown Input Parameters: 1209a53986e1SJed Brown + n - number of strings in 1210a53986e1SJed Brown . list - list of strings to search 1211a53986e1SJed Brown - str - string to look for, empty string "" accepts default (first entry in list) 1212a53986e1SJed Brown 1213a53986e1SJed Brown Output Parameters: 1214a53986e1SJed Brown + value - index of matching string (if found) 1215a53986e1SJed Brown - found - boolean indicating whether string was found (can be NULL) 1216a53986e1SJed Brown 1217a53986e1SJed Brown Notes: 1218a53986e1SJed Brown Not for use in Fortran 1219a53986e1SJed Brown 1220a53986e1SJed Brown Level: advanced 1221a53986e1SJed Brown @*/ 1222a53986e1SJed Brown PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found) 1223a53986e1SJed Brown { 1224a53986e1SJed Brown PetscFunctionBegin; 12255f80ce2aSJacob Faibussowitsch if (found) { 12265f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found,5); 12275f80ce2aSJacob Faibussowitsch *found = PETSC_FALSE; 12285f80ce2aSJacob Faibussowitsch } 12295f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 12305f80ce2aSJacob Faibussowitsch PetscBool matched; 12315f80ce2aSJacob Faibussowitsch 12329566063dSJacob Faibussowitsch PetscCall(PetscStrcasecmp(str,list[i],&matched)); 1233a53986e1SJed Brown if (matched || !str[0]) { 1234a53986e1SJed Brown if (found) *found = PETSC_TRUE; 1235a53986e1SJed Brown *value = i; 1236a53986e1SJed Brown break; 1237a53986e1SJed Brown } 1238a53986e1SJed Brown } 1239a53986e1SJed Brown PetscFunctionReturn(0); 1240a53986e1SJed Brown } 1241a53986e1SJed Brown 1242a53986e1SJed Brown /*@C 12438e81d068SLisandro Dalcin PetscEnumFind - searches enum list of strings for given string, using case insensitive matching 1244a53986e1SJed Brown 1245a53986e1SJed Brown Not Collective 1246a53986e1SJed Brown 1247a53986e1SJed Brown Input Parameters: 1248a53986e1SJed Brown + enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL 1249a53986e1SJed Brown - str - string to look for 1250a53986e1SJed Brown 1251a53986e1SJed Brown Output Parameters: 1252a53986e1SJed Brown + value - index of matching string (if found) 1253a53986e1SJed Brown - found - boolean indicating whether string was found (can be NULL) 1254a53986e1SJed Brown 1255a53986e1SJed Brown Notes: 1256a53986e1SJed Brown Not for use in Fortran 1257a53986e1SJed Brown 1258a53986e1SJed Brown Level: advanced 1259a53986e1SJed Brown @*/ 1260a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found) 1261a53986e1SJed Brown { 1262d05ba7d2SLisandro Dalcin PetscInt n = 0,evalue; 1263a53986e1SJed Brown PetscBool efound; 1264a53986e1SJed Brown 1265a53986e1SJed Brown PetscFunctionBegin; 12665f80ce2aSJacob Faibussowitsch PetscValidPointer(enumlist,1); 12675f80ce2aSJacob 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"); 12685f80ce2aSJacob Faibussowitsch PetscCheck(n >= 3,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix"); 1269a53986e1SJed Brown n -= 3; /* drop enum name, prefix, and null termination */ 12709566063dSJacob Faibussowitsch PetscCall(PetscEListFind(n,enumlist,str,&evalue,&efound)); 12715f80ce2aSJacob Faibussowitsch if (efound) { 12725f80ce2aSJacob Faibussowitsch PetscValidPointer(value,3); 12735f80ce2aSJacob Faibussowitsch *value = (PetscEnum)evalue; 12745f80ce2aSJacob Faibussowitsch } 12755f80ce2aSJacob Faibussowitsch if (found) { 12765f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(found,4); 12775f80ce2aSJacob Faibussowitsch *found = efound; 12785f80ce2aSJacob Faibussowitsch } 1279a53986e1SJed Brown PetscFunctionReturn(0); 1280a53986e1SJed Brown } 1281*660278c0SBarry Smith 1282*660278c0SBarry Smith /*@C 1283*660278c0SBarry Smith PetscCIFilename - returns the basename of a file name when the PETSc CI portable error output mode is enabled. 1284*660278c0SBarry Smith 1285*660278c0SBarry Smith Not collective 1286*660278c0SBarry Smith 1287*660278c0SBarry Smith Input Parameter: 1288*660278c0SBarry Smith . file - the file name 1289*660278c0SBarry Smith 1290*660278c0SBarry Smith Note: 1291*660278c0SBarry Smith PETSc CI mode is a mode of running PETSc where output (both error and non-error) is made portable across all systems 1292*660278c0SBarry Smith so that comparisons of output between runs are easy to make. 1293*660278c0SBarry Smith 1294*660278c0SBarry Smith This mode is used for all tests in the test harness, it applies to both debug and optimized builds. 1295*660278c0SBarry Smith 1296*660278c0SBarry Smith Use the option -petsc_ci to turn on PETSc CI mode. It changes certain output in non-error situations to be portable for 1297*660278c0SBarry Smith all systems, mainly the output of options. It is passed to all PETSc programs automatically by the test harness. 1298*660278c0SBarry Smith 1299*660278c0SBarry Smith Always uses the Unix / as the file separate even on Microsoft Windows systems 1300*660278c0SBarry Smith 1301*660278c0SBarry Smith The option -petsc_ci_portable_error_output attempts to output the same error messages on all systems for the test harness. 1302*660278c0SBarry Smith In particular the output of filenames and line numbers in PETSc stacks. This is to allow (limited) checking of PETSc 1303*660278c0SBarry 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 1304*660278c0SBarry Smith harness can process the output for differences in the usual manner as for successful runs. It should be provided to the test 1305*660278c0SBarry Smith harness in the args: argument for specific examples. It will not neccessarily produce portable output if different errors 1306*660278c0SBarry Smith (or no errors) occur on a subset of the MPI ranks. 1307*660278c0SBarry Smith 1308*660278c0SBarry Smith Level: developer 1309*660278c0SBarry Smith 1310*660278c0SBarry Smith .seealso: `PetscCILinenumber()` 1311*660278c0SBarry Smith 1312*660278c0SBarry Smith @*/ 1313*660278c0SBarry Smith const char *PetscCIFilename(const char *file) 1314*660278c0SBarry Smith { 1315*660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return file; 1316*660278c0SBarry Smith return PetscBasename(file); 1317*660278c0SBarry Smith } 1318*660278c0SBarry Smith 1319*660278c0SBarry Smith /*@C 1320*660278c0SBarry Smith PetscCILinenumber - returns a line number except if PetscCIEnablePortableErrorOutput) is set when it returns 0 1321*660278c0SBarry Smith 1322*660278c0SBarry Smith Not collective 1323*660278c0SBarry Smith 1324*660278c0SBarry Smith Input Parameter: 1325*660278c0SBarry Smith . linenumber - the initial line number 1326*660278c0SBarry Smith 1327*660278c0SBarry Smith Note: 1328*660278c0SBarry Smith See `PetscCIFilename()` for details on usage 1329*660278c0SBarry Smith 1330*660278c0SBarry Smith Level: developer 1331*660278c0SBarry Smith 1332*660278c0SBarry Smith .seealso: `PetscCIFilename()` 1333*660278c0SBarry Smith 1334*660278c0SBarry Smith @*/ 1335*660278c0SBarry Smith int PetscCILinenumber(int linenumber) 1336*660278c0SBarry Smith { 1337*660278c0SBarry Smith if (!PetscCIEnabledPortableErrorOutput) return linenumber; 1338*660278c0SBarry Smith return 0; 1339*660278c0SBarry Smith } 1340