xref: /petsc/src/sys/objects/options.c (revision dbbe0bcd3f3a8fbab5a45420dc06f8387e5764c6)
1 /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
2 #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */
3 
4 /*
5    These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
6    This provides the low-level interface, the high level interface is in aoptions.c
7 
8    Some routines use regular malloc and free because it cannot know  what malloc is requested with the
9    options database until it has already processed the input.
10 */
11 
12 #include <petsc/private/petscimpl.h>        /*I  "petscsys.h"   I*/
13 #include <petscviewer.h>
14 #include <ctype.h>
15 #if defined(PETSC_HAVE_MALLOC_H)
16 #include <malloc.h>
17 #endif
18 #if defined(PETSC_HAVE_STRINGS_H)
19 #  include <strings.h>          /* strcasecmp */
20 #endif
21 
22 #if defined(PETSC_HAVE_STRCASECMP)
23 #define PetscOptNameCmp(a,b) strcasecmp(a,b)
24 #elif defined(PETSC_HAVE_STRICMP)
25 #define PetscOptNameCmp(a,b) stricmp(a,b)
26 #else
27 #define PetscOptNameCmp(a,b) Error_strcasecmp_not_found
28 #endif
29 
30 #include <petsc/private/hashtable.h>
31 
32 /* This assumes ASCII encoding and ignores locale settings */
33 /* Using tolower() is about 2X slower in microbenchmarks   */
34 static inline int PetscToLower(int c)
35 {
36   return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
37 }
38 
39 /* Bob Jenkins's one at a time hash function (case-insensitive) */
40 static inline unsigned int PetscOptHash(const char key[])
41 {
42   unsigned int hash = 0;
43   while (*key) {
44     hash += PetscToLower(*key++);
45     hash += hash << 10;
46     hash ^= hash >>  6;
47   }
48   hash += hash <<  3;
49   hash ^= hash >> 11;
50   hash += hash << 15;
51   return hash;
52 }
53 
54 static inline int PetscOptEqual(const char a[],const char b[])
55 {
56   return !PetscOptNameCmp(a,b);
57 }
58 
59 KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
60 
61 /*
62     This table holds all the options set by the user. For simplicity, we use a static size database
63 */
64 #define MAXOPTNAME PETSC_MAX_OPTION_NAME
65 #define MAXOPTIONS 512
66 #define MAXALIASES  25
67 #define MAXPREFIXES 25
68 #define MAXOPTIONSMONITORS 5
69 
70 struct  _n_PetscOptions {
71   PetscOptions   previous;
72   int            N;                    /* number of options */
73   char           *names[MAXOPTIONS];   /* option names */
74   char           *values[MAXOPTIONS];  /* option values */
75   PetscBool      used[MAXOPTIONS];     /* flag option use */
76   PetscBool      precedentProcessed;
77 
78   /* Hash table */
79   khash_t(HO)    *ht;
80 
81   /* Prefixes */
82   int            prefixind;
83   int            prefixstack[MAXPREFIXES];
84   char           prefix[MAXOPTNAME];
85 
86   /* Aliases */
87   int            Naliases;                   /* number or aliases */
88   char           *aliases1[MAXALIASES];      /* aliased */
89   char           *aliases2[MAXALIASES];      /* aliasee */
90 
91   /* Help */
92   PetscBool      help;       /* flag whether "-help" is in the database */
93   PetscBool      help_intro; /* flag whether "-help intro" is in the database */
94 
95   /* Monitors */
96   PetscBool      monitorFromOptions, monitorCancel;
97   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[],const char[],void*); /* returns control to user after */
98   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**);         /* */
99   void           *monitorcontext[MAXOPTIONSMONITORS];                  /* to pass arbitrary user data into monitor */
100   PetscInt       numbermonitors;                                       /* to, for instance, detect options being set */
101 };
102 
103 static PetscOptions defaultoptions = NULL;  /* the options database routines query this object for options */
104 
105 /* list of options which preceed others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
106 /* these options can only take boolean values, the code will crash if given a non-boolean value */
107 static const char *precedentOptions[] = {"-petsc_ci","-options_monitor","-options_monitor_cancel","-help","-skip_petscrc"};
108 enum PetscPrecedentOption {PO_CI_ENABLE,PO_OPTIONS_MONITOR,PO_OPTIONS_MONITOR_CANCEL,PO_HELP,PO_SKIP_PETSCRC,PO_NUM};
109 
110 static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions,const char[],const char[],int*);
111 
112 /*
113     Options events monitor
114 */
115 static PetscErrorCode PetscOptionsMonitor(PetscOptions options,const char name[],const char value[])
116 {
117   PetscFunctionBegin;
118   if (!value) value = "";
119   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name,value,NULL));
120   for (PetscInt i=0; i<options->numbermonitors; i++) PetscCall((*options->monitor[i])(name,value,options->monitorcontext[i]));
121   PetscFunctionReturn(0);
122 }
123 
124 /*@
125    PetscOptionsCreate - Creates an empty options database.
126 
127    Logically collective
128 
129    Output Parameter:
130 .  options - Options database object
131 
132    Level: advanced
133 
134    Developer Note: We may want eventually to pass a MPI_Comm to determine the ownership of the object
135 
136 .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
137 @*/
138 PetscErrorCode PetscOptionsCreate(PetscOptions *options)
139 {
140   PetscFunctionBegin;
141   PetscValidPointer(options,1);
142   *options = (PetscOptions)calloc(1,sizeof(**options));
143   PetscCheck(*options,PETSC_COMM_SELF,PETSC_ERR_MEM,"Failed to allocate the options database");
144   PetscFunctionReturn(0);
145 }
146 
147 /*@
148     PetscOptionsDestroy - Destroys an option database.
149 
150     Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
151 
152   Input Parameter:
153 .  options - the PetscOptions object
154 
155    Level: advanced
156 
157 .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
158 @*/
159 PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
160 {
161   PetscFunctionBegin;
162   if (!*options) PetscFunctionReturn(0);
163   PetscCheck(!(*options)->previous,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"You are destroying an option that has been used with PetscOptionsPush() but does not have a corresponding PetscOptionsPop()");
164   PetscCall(PetscOptionsClear(*options));
165   /* XXX what about monitors ? */
166   free(*options);
167   *options = NULL;
168   PetscFunctionReturn(0);
169 }
170 
171 /*
172     PetscOptionsCreateDefault - Creates the default global options database
173 */
174 PetscErrorCode PetscOptionsCreateDefault(void)
175 {
176   PetscFunctionBegin;
177   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
178   PetscFunctionReturn(0);
179 }
180 
181 /*@
182       PetscOptionsPush - Push a new PetscOptions object as the default provider of options
183                          Allows using different parts of a code to use different options databases
184 
185   Logically Collective
186 
187   Input Parameter:
188 .   opt - the options obtained with PetscOptionsCreate()
189 
190   Notes:
191   Use PetscOptionsPop() to return to the previous default options database
192 
193   The collectivity of this routine is complex; only the MPI processes that call this routine will
194   have the affect of these options. If some processes that create objects call this routine and others do
195   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
196   on different ranks.
197 
198    Level: advanced
199 
200 .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
201 
202 @*/
203 PetscErrorCode PetscOptionsPush(PetscOptions opt)
204 {
205   PetscFunctionBegin;
206   PetscCall(PetscOptionsCreateDefault());
207   opt->previous  = defaultoptions;
208   defaultoptions = opt;
209   PetscFunctionReturn(0);
210 }
211 
212 /*@
213       PetscOptionsPop - Pop the most recent PetscOptionsPush() to return to the previous default options
214 
215       Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
216 
217   Notes:
218   Use PetscOptionsPop() to return to the previous default options database
219   Allows using different parts of a code to use different options databases
220 
221    Level: advanced
222 
223 .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
224 
225 @*/
226 PetscErrorCode PetscOptionsPop(void)
227 {
228   PetscOptions current = defaultoptions;
229 
230   PetscFunctionBegin;
231   PetscCheck(defaultoptions,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing default options");
232   PetscCheck(defaultoptions->previous,PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscOptionsPop() called too many times");
233   defaultoptions    = defaultoptions->previous;
234   current->previous = NULL;
235   PetscFunctionReturn(0);
236 }
237 
238 /*
239     PetscOptionsDestroyDefault - Destroys the default global options database
240 */
241 PetscErrorCode PetscOptionsDestroyDefault(void)
242 {
243   PetscFunctionBegin;
244   if (!defaultoptions) PetscFunctionReturn(0);
245   /* Destroy any options that the user forgot to pop */
246   while (defaultoptions->previous) {
247     PetscOptions tmp = defaultoptions;
248 
249     PetscCall(PetscOptionsPop());
250     PetscCall(PetscOptionsDestroy(&tmp));
251   }
252   PetscCall(PetscOptionsDestroy(&defaultoptions));
253   PetscFunctionReturn(0);
254 }
255 
256 /*@C
257    PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
258 
259    Not collective
260 
261    Input Parameter:
262 .  key - string to check if valid
263 
264    Output Parameter:
265 .  valid - PETSC_TRUE if a valid key
266 
267    Level: intermediate
268 @*/
269 PetscErrorCode PetscOptionsValidKey(const char key[],PetscBool *valid)
270 {
271   char *ptr;
272 
273   PetscFunctionBegin;
274   if (key) PetscValidCharPointer(key,1);
275   PetscValidBoolPointer(valid,2);
276   *valid = PETSC_FALSE;
277   if (!key) PetscFunctionReturn(0);
278   if (key[0] != '-') PetscFunctionReturn(0);
279   if (key[1] == '-') key++;
280   if (!isalpha((int)key[1])) PetscFunctionReturn(0);
281   (void) strtod(key,&ptr);
282   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(0);
283   *valid = PETSC_TRUE;
284   PetscFunctionReturn(0);
285 }
286 
287 /*@C
288    PetscOptionsInsertString - Inserts options into the database from a string
289 
290    Logically Collective
291 
292    Input Parameters:
293 +  options - options object
294 -  in_str - string that contains options separated by blanks
295 
296    Level: intermediate
297 
298   The collectivity of this routine is complex; only the MPI processes that call this routine will
299   have the affect of these options. If some processes that create objects call this routine and others do
300   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
301   on different ranks.
302 
303    Contributed by Boyana Norris
304 
305 .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
306           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
307           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
308           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
309           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
310           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
311 @*/
312 PetscErrorCode PetscOptionsInsertString(PetscOptions options,const char in_str[])
313 {
314   MPI_Comm       comm = PETSC_COMM_SELF;
315   char           *first,*second;
316   PetscToken     token;
317 
318   PetscFunctionBegin;
319   PetscCall(PetscTokenCreate(in_str,' ',&token));
320   PetscCall(PetscTokenFind(token,&first));
321   while (first) {
322     PetscBool isfile,isfileyaml,isstringyaml,ispush,ispop,key;
323     PetscCall(PetscStrcasecmp(first,"-options_file",&isfile));
324     PetscCall(PetscStrcasecmp(first,"-options_file_yaml",&isfileyaml));
325     PetscCall(PetscStrcasecmp(first,"-options_string_yaml",&isstringyaml));
326     PetscCall(PetscStrcasecmp(first,"-prefix_push",&ispush));
327     PetscCall(PetscStrcasecmp(first,"-prefix_pop",&ispop));
328     PetscCall(PetscOptionsValidKey(first,&key));
329     if (!key) {
330       PetscCall(PetscTokenFind(token,&first));
331     } else if (isfile) {
332       PetscCall(PetscTokenFind(token,&second));
333       PetscCall(PetscOptionsInsertFile(comm,options,second,PETSC_TRUE));
334       PetscCall(PetscTokenFind(token,&first));
335     } else if (isfileyaml) {
336       PetscCall(PetscTokenFind(token,&second));
337       PetscCall(PetscOptionsInsertFileYAML(comm,options,second,PETSC_TRUE));
338       PetscCall(PetscTokenFind(token,&first));
339     } else if (isstringyaml) {
340       PetscCall(PetscTokenFind(token,&second));
341       PetscCall(PetscOptionsInsertStringYAML(options,second));
342       PetscCall(PetscTokenFind(token,&first));
343     } else if (ispush) {
344       PetscCall(PetscTokenFind(token,&second));
345       PetscCall(PetscOptionsPrefixPush(options,second));
346       PetscCall(PetscTokenFind(token,&first));
347     } else if (ispop) {
348       PetscCall(PetscOptionsPrefixPop(options));
349       PetscCall(PetscTokenFind(token,&first));
350     } else {
351       PetscCall(PetscTokenFind(token,&second));
352       PetscCall(PetscOptionsValidKey(second,&key));
353       if (!key) {
354         PetscCall(PetscOptionsSetValue(options,first,second));
355         PetscCall(PetscTokenFind(token,&first));
356       } else {
357         PetscCall(PetscOptionsSetValue(options,first,NULL));
358         first = second;
359       }
360     }
361   }
362   PetscCall(PetscTokenDestroy(&token));
363   PetscFunctionReturn(0);
364 }
365 
366 /*
367     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
368 */
369 static char *Petscgetline(FILE * f)
370 {
371   size_t size  = 0;
372   size_t len   = 0;
373   size_t last  = 0;
374   char   *buf  = NULL;
375 
376   if (feof(f)) return NULL;
377   do {
378     size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
379     buf   = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
380     /* Actually do the read. Note that fgets puts a terminal '\0' on the
381     end of the string, so we make sure we overwrite this */
382     if (!fgets(buf+len,1024,f)) buf[len]=0;
383     PetscStrlen(buf,&len);
384     last = len - 1;
385   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
386   if (len) return buf;
387   free(buf);
388   return NULL;
389 }
390 
391 static PetscErrorCode PetscOptionsFilename(MPI_Comm comm,const char file[],char filename[PETSC_MAX_PATH_LEN],PetscBool *yaml)
392 {
393   char           fname[PETSC_MAX_PATH_LEN+8],path[PETSC_MAX_PATH_LEN+8],*tail;
394 
395   PetscFunctionBegin;
396   *yaml = PETSC_FALSE;
397   PetscCall(PetscStrreplace(comm,file,fname,sizeof(fname)));
398   PetscCall(PetscFixFilename(fname,path));
399   PetscCall(PetscStrendswith(path,":yaml",yaml));
400   if (*yaml) {
401     PetscCall(PetscStrrchr(path,':',&tail));
402     tail[-1] = 0; /* remove ":yaml" suffix from path */
403   }
404   PetscCall(PetscStrncpy(filename,path,PETSC_MAX_PATH_LEN));
405   /* check for standard YAML and JSON filename extensions */
406   if (!*yaml) PetscCall(PetscStrendswith(filename,".yaml",yaml));
407   if (!*yaml) PetscCall(PetscStrendswith(filename,".yml", yaml));
408   if (!*yaml) PetscCall(PetscStrendswith(filename,".json",yaml));
409   if (!*yaml) { /* check file contents */
410     PetscMPIInt rank;
411     PetscCallMPI(MPI_Comm_rank(comm,&rank));
412     if (rank == 0) {
413       FILE *fh = fopen(filename,"r");
414       if (fh) {
415         char buf[6] = "";
416         if (fread(buf,1,6,fh) > 0) {
417           PetscCall(PetscStrncmp(buf,"%YAML ",6,yaml));  /* check for '%YAML' tag */
418           if (!*yaml) PetscCall(PetscStrncmp(buf,"---",3,yaml));  /* check for document start */
419         }
420         (void)fclose(fh);
421       }
422     }
423     PetscCallMPI(MPI_Bcast(yaml,1,MPIU_BOOL,0,comm));
424   }
425   PetscFunctionReturn(0);
426 }
427 
428 static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
429 {
430   char           *string,*vstring = NULL,*astring = NULL,*packed = NULL;
431   char           *tokens[4];
432   size_t         i,len,bytes;
433   FILE           *fd;
434   PetscToken     token=NULL;
435   int            err;
436   char           *cmatch;
437   const char     cmt='#';
438   PetscInt       line=1;
439   PetscMPIInt    rank,cnt=0,acnt=0,counts[2];
440   PetscBool      isdir,alias=PETSC_FALSE,valid;
441 
442   PetscFunctionBegin;
443   PetscCall(PetscMemzero(tokens,sizeof(tokens)));
444   PetscCallMPI(MPI_Comm_rank(comm,&rank));
445   if (rank == 0) {
446     char fpath[PETSC_MAX_PATH_LEN];
447     char fname[PETSC_MAX_PATH_LEN];
448 
449     PetscCall(PetscStrreplace(PETSC_COMM_SELF,file,fpath,sizeof(fpath)));
450     PetscCall(PetscFixFilename(fpath,fname));
451 
452     fd   = fopen(fname,"r");
453     PetscCall(PetscTestDirectory(fname,'r',&isdir));
454     PetscCheck(!isdir || !require,PETSC_COMM_SELF,PETSC_ERR_USER,"Specified options file %s is a directory",fname);
455     if (fd && !isdir) {
456       PetscSegBuffer vseg,aseg;
457       PetscCall(PetscSegBufferCreate(1,4000,&vseg));
458       PetscCall(PetscSegBufferCreate(1,2000,&aseg));
459 
460       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
461       PetscCall(PetscInfo(NULL,"Opened options file %s\n",file));
462 
463       while ((string = Petscgetline(fd))) {
464         /* eliminate comments from each line */
465         PetscCall(PetscStrchr(string,cmt,&cmatch));
466         if (cmatch) *cmatch = 0;
467         PetscCall(PetscStrlen(string,&len));
468         /* replace tabs, ^M, \n with " " */
469         for (i=0; i<len; i++) {
470           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
471             string[i] = ' ';
472           }
473         }
474         PetscCall(PetscTokenCreate(string,' ',&token));
475         PetscCall(PetscTokenFind(token,&tokens[0]));
476         if (!tokens[0]) {
477           goto destroy;
478         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
479           PetscCall(PetscTokenFind(token,&tokens[0]));
480         }
481         for (i=1; i<4; i++) {
482           PetscCall(PetscTokenFind(token,&tokens[i]));
483         }
484         if (!tokens[0]) {
485           goto destroy;
486         } else if (tokens[0][0] == '-') {
487           PetscCall(PetscOptionsValidKey(tokens[0],&valid));
488           PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %" PetscInt_FMT ": invalid option %s",fname,line,tokens[0]);
489           PetscCall(PetscStrlen(tokens[0],&len));
490           PetscCall(PetscSegBufferGet(vseg,len+1,&vstring));
491           PetscCall(PetscArraycpy(vstring,tokens[0],len));
492           vstring[len] = ' ';
493           if (tokens[1]) {
494             PetscCall(PetscOptionsValidKey(tokens[1],&valid));
495             PetscCheck(!valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %" PetscInt_FMT ": cannot specify two options per line (%s %s)",fname,line,tokens[0],tokens[1]);
496             PetscCall(PetscStrlen(tokens[1],&len));
497             PetscCall(PetscSegBufferGet(vseg,len+3,&vstring));
498             vstring[0] = '"';
499             PetscCall(PetscArraycpy(vstring+1,tokens[1],len));
500             vstring[len+1] = '"';
501             vstring[len+2] = ' ';
502           }
503         } else {
504           PetscCall(PetscStrcasecmp(tokens[0],"alias",&alias));
505           if (alias) {
506             PetscCall(PetscOptionsValidKey(tokens[1],&valid));
507             PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %" PetscInt_FMT ": invalid aliased option %s",fname,line,tokens[1]);
508             PetscCheck(tokens[2],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %" PetscInt_FMT ": alias missing for %s",fname,line,tokens[1]);
509             PetscCall(PetscOptionsValidKey(tokens[2],&valid));
510             PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %" PetscInt_FMT ": invalid aliasee option %s",fname,line,tokens[2]);
511             PetscCall(PetscStrlen(tokens[1],&len));
512             PetscCall(PetscSegBufferGet(aseg,len+1,&astring));
513             PetscCall(PetscArraycpy(astring,tokens[1],len));
514             astring[len] = ' ';
515 
516             PetscCall(PetscStrlen(tokens[2],&len));
517             PetscCall(PetscSegBufferGet(aseg,len+1,&astring));
518             PetscCall(PetscArraycpy(astring,tokens[2],len));
519             astring[len] = ' ';
520           } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown first token in options file %s line %" PetscInt_FMT ": %s",fname,line,tokens[0]);
521         }
522         {
523           const char *extraToken = alias ? tokens[3] : tokens[2];
524           PetscCheck(!extraToken,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %" PetscInt_FMT ": extra token %s",fname,line,extraToken);
525         }
526 destroy:
527         free(string);
528         PetscCall(PetscTokenDestroy(&token));
529         alias = PETSC_FALSE;
530         line++;
531       }
532       err = fclose(fd);
533       PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file %s",fname);
534       PetscCall(PetscSegBufferGetSize(aseg,&bytes)); /* size without null termination */
535       PetscCall(PetscMPIIntCast(bytes,&acnt));
536       PetscCall(PetscSegBufferGet(aseg,1,&astring));
537       astring[0] = 0;
538       PetscCall(PetscSegBufferGetSize(vseg,&bytes)); /* size without null termination */
539       PetscCall(PetscMPIIntCast(bytes,&cnt));
540       PetscCall(PetscSegBufferGet(vseg,1,&vstring));
541       vstring[0] = 0;
542       PetscCall(PetscMalloc1(2+acnt+cnt,&packed));
543       PetscCall(PetscSegBufferExtractTo(aseg,packed));
544       PetscCall(PetscSegBufferExtractTo(vseg,packed+acnt+1));
545       PetscCall(PetscSegBufferDestroy(&aseg));
546       PetscCall(PetscSegBufferDestroy(&vseg));
547     } else PetscCheck(!require,PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open options file %s",fname);
548   }
549 
550   counts[0] = acnt;
551   counts[1] = cnt;
552   err = MPI_Bcast(counts,2,MPI_INT,0,comm);
553   PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in first MPI collective call, could be caused by using an incorrect mpiexec or a network problem, it can be caused by having VPN running: see https://petsc.org/release/faq/");
554   acnt = counts[0];
555   cnt = counts[1];
556   if (rank) {
557     PetscCall(PetscMalloc1(2+acnt+cnt,&packed));
558   }
559   if (acnt || cnt) {
560     PetscCallMPI(MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm));
561     astring = packed;
562     vstring = packed + acnt + 1;
563   }
564 
565   if (acnt) {
566     PetscCall(PetscTokenCreate(astring,' ',&token));
567     PetscCall(PetscTokenFind(token,&tokens[0]));
568     while (tokens[0]) {
569       PetscCall(PetscTokenFind(token,&tokens[1]));
570       PetscCall(PetscOptionsSetAlias(options,tokens[0],tokens[1]));
571       PetscCall(PetscTokenFind(token,&tokens[0]));
572     }
573     PetscCall(PetscTokenDestroy(&token));
574   }
575 
576   if (cnt) PetscCall(PetscOptionsInsertString(options,vstring));
577   PetscCall(PetscFree(packed));
578   PetscFunctionReturn(0);
579 }
580 
581 /*@C
582      PetscOptionsInsertFile - Inserts options into the database from a file.
583 
584      Collective
585 
586   Input Parameters:
587 +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
588 .   options - options database, use NULL for default global database
589 .   file - name of file,
590            ".yml" and ".yaml" filename extensions are inserted as YAML options,
591            append ":yaml" to filename to force YAML options.
592 -   require - if PETSC_TRUE will generate an error if the file does not exist
593 
594   Notes:
595    Use  # for lines that are comments and which should be ignored.
596    Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
597    such as -log_view or -malloc_debug are processed properly. This routine only sets options into the options database that will be processed by later
598    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
599    The collectivity of this routine is complex; only the MPI processes in comm will
600    have the affect of these options. If some processes that create objects call this routine and others do
601    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
602    on different ranks.
603 
604   Level: developer
605 
606 .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
607           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
608           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
609           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
610           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
611           `PetscOptionsFList()`, `PetscOptionsEList()`
612 
613 @*/
614 PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
615 {
616   char           filename[PETSC_MAX_PATH_LEN];
617   PetscBool      yaml;
618 
619   PetscFunctionBegin;
620   PetscCall(PetscOptionsFilename(comm,file,filename,&yaml));
621   if (yaml) {
622     PetscCall(PetscOptionsInsertFileYAML(comm,options,filename,require));
623   } else {
624     PetscCall(PetscOptionsInsertFilePetsc(comm,options,filename,require));
625   }
626   PetscFunctionReturn(0);
627 }
628 
629 /*@C
630    PetscOptionsInsertArgs - Inserts options into the database from a array of strings
631 
632    Logically Collective
633 
634    Input Parameters:
635 +  options - options object
636 .  argc - the array length
637 -  args - the string array
638 
639    Level: intermediate
640 
641 .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
642 @*/
643 PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[])
644 {
645   MPI_Comm       comm = PETSC_COMM_WORLD;
646   int            left          = PetscMax(argc,0);
647   char           *const *eargs = args;
648 
649   PetscFunctionBegin;
650   while (left) {
651     PetscBool isfile,isfileyaml,isstringyaml,ispush,ispop,key;
652     PetscCall(PetscStrcasecmp(eargs[0],"-options_file",&isfile));
653     PetscCall(PetscStrcasecmp(eargs[0],"-options_file_yaml",&isfileyaml));
654     PetscCall(PetscStrcasecmp(eargs[0],"-options_string_yaml",&isstringyaml));
655     PetscCall(PetscStrcasecmp(eargs[0],"-prefix_push",&ispush));
656     PetscCall(PetscStrcasecmp(eargs[0],"-prefix_pop",&ispop));
657     PetscCall(PetscOptionsValidKey(eargs[0],&key));
658     if (!key) {
659       eargs++; left--;
660     } else if (isfile) {
661       PetscCheck(left > 1 && eargs[1][0] != '-',PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
662       PetscCall(PetscOptionsInsertFile(comm,options,eargs[1],PETSC_TRUE));
663       eargs += 2; left -= 2;
664     } else if (isfileyaml) {
665       PetscCheck(left > 1 && eargs[1][0] != '-',PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file_yaml filename option");
666       PetscCall(PetscOptionsInsertFileYAML(comm,options,eargs[1],PETSC_TRUE));
667       eargs += 2; left -= 2;
668     } else if (isstringyaml) {
669       PetscCheck(left > 1 && eargs[1][0] != '-',PETSC_COMM_SELF,PETSC_ERR_USER,"Missing string for -options_string_yaml string option");
670       PetscCall(PetscOptionsInsertStringYAML(options,eargs[1]));
671       eargs += 2; left -= 2;
672     } else if (ispush) {
673       PetscCheck(left > 1,PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
674       PetscCheck(eargs[1][0] != '-',PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
675       PetscCall(PetscOptionsPrefixPush(options,eargs[1]));
676       eargs += 2; left -= 2;
677     } else if (ispop) {
678       PetscCall(PetscOptionsPrefixPop(options));
679       eargs++; left--;
680     } else {
681       PetscBool nextiskey = PETSC_FALSE;
682       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1],&nextiskey));
683       if (left < 2 || nextiskey) {
684         PetscCall(PetscOptionsSetValue(options,eargs[0],NULL));
685         eargs++; left--;
686       } else {
687         PetscCall(PetscOptionsSetValue(options,eargs[0],eargs[1]));
688         eargs += 2; left -= 2;
689       }
690     }
691   }
692   PetscFunctionReturn(0);
693 }
694 
695 static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt,const char *val[],PetscBool set[],PetscBool *flg)
696 {
697   PetscFunctionBegin;
698   if (set[opt]) {
699     PetscCall(PetscOptionsStringToBool(val[opt],flg));
700   } else *flg = PETSC_FALSE;
701   PetscFunctionReturn(0);
702 }
703 
704 /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
705 static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options,int argc,char *args[],PetscBool *skip_petscrc,PetscBool *skip_petscrc_set)
706 {
707   const char* const *opt = precedentOptions;
708   const size_t      n = PO_NUM;
709   size_t            o;
710   int               a;
711   const char        **val;
712   char              **cval;
713   PetscBool         *set,unneeded;
714 
715   PetscFunctionBegin;
716   PetscCall(PetscCalloc2(n,&cval,n,&set));
717   val = (const char**) cval;
718 
719   /* Look for options possibly set using PetscOptionsSetValue beforehand */
720   for (o=0; o<n; o++) {
721     PetscCall(PetscOptionsFindPair(options,NULL,opt[o],&val[o],&set[o]));
722   }
723 
724   /* Loop through all args to collect last occurring value of each option */
725   for (a=1; a<argc; a++) {
726     PetscBool valid, eq;
727 
728     PetscCall(PetscOptionsValidKey(args[a],&valid));
729     if (!valid) continue;
730     for (o=0; o<n; o++) {
731       PetscCall(PetscStrcasecmp(args[a],opt[o],&eq));
732       if (eq) {
733         set[o] = PETSC_TRUE;
734         if (a == argc-1 || !args[a+1] || !args[a+1][0] || args[a+1][0] == '-') val[o] = NULL;
735         else val[o] = args[a+1];
736         break;
737       }
738     }
739   }
740 
741   /* Process flags */
742   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
743   if (options->help_intro) options->help = PETSC_TRUE;
744   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP,             val,set,&options->help));
745   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE,             val,set,&unneeded));
746   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
747   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options,opt[PO_CI_ENABLE],val[PO_CI_ENABLE],&a));
748   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL,val,set,&options->monitorCancel));
749   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR,       val,set,&options->monitorFromOptions));
750   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC,          val,set,skip_petscrc));
751   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
752 
753   /* Store precedent options in database and mark them as used */
754   for (o=1; o<n; o++) {
755     if (set[o]) {
756       PetscCall(PetscOptionsSetValue_Private(options,opt[o],val[o],&a));
757       options->used[a] = PETSC_TRUE;
758     }
759   }
760   PetscCall(PetscFree2(cval,set));
761   options->precedentProcessed = PETSC_TRUE;
762   PetscFunctionReturn(0);
763 }
764 
765 static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options,const char name[],PetscBool *flg)
766 {
767   PetscFunctionBegin;
768   PetscValidBoolPointer(flg,3);
769   *flg = PETSC_FALSE;
770   if (options->precedentProcessed) {
771     for (int i = 0; i < PO_NUM; ++i) {
772       if (!PetscOptNameCmp(precedentOptions[i],name)) {
773         /* check if precedent option has been set already */
774         PetscCall(PetscOptionsFindPair(options,NULL,name,NULL,flg));
775         if (*flg) break;
776       }
777     }
778   }
779   PetscFunctionReturn(0);
780 }
781 
782 /*@C
783    PetscOptionsInsert - Inserts into the options database from the command line,
784                         the environmental variable and a file.
785 
786    Collective on PETSC_COMM_WORLD
787 
788    Input Parameters:
789 +  options - options database or NULL for the default global database
790 .  argc - count of number of command line arguments
791 .  args - the command line arguments
792 -  file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
793           Use NULL or empty string to not check for code specific file.
794           Also checks ~/.petscrc, .petscrc and petscrc.
795           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
796 
797    Note:
798    Since PetscOptionsInsert() is automatically called by PetscInitialize(),
799    the user does not typically need to call this routine. PetscOptionsInsert()
800    can be called several times, adding additional entries into the database.
801 
802    Options Database Keys:
803 +   -options_file <filename> - read options from a file
804 -   -options_file_yaml <filename> - read options from a YAML file
805 
806    See PetscInitialize() for options related to option database monitoring.
807 
808    Level: advanced
809 
810 .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
811           `PetscInitialize()`
812 @*/
813 PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[])
814 {
815   MPI_Comm       comm = PETSC_COMM_WORLD;
816   PetscMPIInt    rank;
817   PetscBool      hasArgs = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
818   PetscBool      skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
819 
820   PetscFunctionBegin;
821   PetscCheck(!hasArgs || (args && *args),comm,PETSC_ERR_ARG_NULL,"*argc > 1 but *args not given");
822   PetscCallMPI(MPI_Comm_rank(comm,&rank));
823 
824   if (!options) {
825     PetscCall(PetscOptionsCreateDefault());
826     options = defaultoptions;
827   }
828   if (hasArgs) {
829     /* process options with absolute precedence */
830     PetscCall(PetscOptionsProcessPrecedentFlags(options,*argc,*args,&skipPetscrc,&skipPetscrcSet));
831     PetscCall(PetscOptionsGetBool(NULL,NULL,"-petsc_ci",&PetscCIEnabled,NULL));
832   }
833   if (file && file[0]) {
834     PetscCall(PetscOptionsInsertFile(comm,options,file,PETSC_TRUE));
835     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
836     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options,NULL,"-skip_petscrc",&skipPetscrc,NULL));
837   }
838   if (!skipPetscrc) {
839     char filename[PETSC_MAX_PATH_LEN];
840     PetscCall(PetscGetHomeDirectory(filename,sizeof(filename)));
841     PetscCallMPI(MPI_Bcast(filename,(int)sizeof(filename),MPI_CHAR,0,comm));
842     if (filename[0]) PetscCall(PetscStrcat(filename,"/.petscrc"));
843     PetscCall(PetscOptionsInsertFile(comm,options,filename,PETSC_FALSE));
844     PetscCall(PetscOptionsInsertFile(comm,options,".petscrc",PETSC_FALSE));
845     PetscCall(PetscOptionsInsertFile(comm,options,"petscrc",PETSC_FALSE));
846   }
847 
848   /* insert environment options */
849   {
850     char   *eoptions = NULL;
851     size_t len       = 0;
852     if (rank == 0) {
853       eoptions = (char*)getenv("PETSC_OPTIONS");
854       PetscCall(PetscStrlen(eoptions,&len));
855     }
856     PetscCallMPI(MPI_Bcast(&len,1,MPIU_SIZE_T,0,comm));
857     if (len) {
858       if (rank) PetscCall(PetscMalloc1(len+1,&eoptions));
859       PetscCallMPI(MPI_Bcast(eoptions,len,MPI_CHAR,0,comm));
860       if (rank) eoptions[len] = 0;
861       PetscCall(PetscOptionsInsertString(options,eoptions));
862       if (rank) PetscCall(PetscFree(eoptions));
863     }
864   }
865 
866   /* insert YAML environment options */
867   {
868     char   *eoptions = NULL;
869     size_t len       = 0;
870     if (rank == 0) {
871       eoptions = (char*)getenv("PETSC_OPTIONS_YAML");
872       PetscCall(PetscStrlen(eoptions,&len));
873     }
874     PetscCallMPI(MPI_Bcast(&len,1,MPIU_SIZE_T,0,comm));
875     if (len) {
876       if (rank) PetscCall(PetscMalloc1(len+1,&eoptions));
877       PetscCallMPI(MPI_Bcast(eoptions,len,MPI_CHAR,0,comm));
878       if (rank) eoptions[len] = 0;
879       PetscCall(PetscOptionsInsertStringYAML(options,eoptions));
880       if (rank) PetscCall(PetscFree(eoptions));
881     }
882   }
883 
884   /* insert command line options here because they take precedence over arguments in petscrc/environment */
885   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options,*argc-1,*args+1));
886   PetscCall(PetscOptionsGetBool(NULL,NULL,"-petsc_ci_portable_error_output",&PetscCIEnabledPortableErrorOutput,NULL));
887   PetscFunctionReturn(0);
888 }
889 
890 /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
891 /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
892 static const char *PetscCIOptions[] = {"malloc_debug",
893                                        "malloc_dump",
894                                        "malloc_test",
895                                        "nox",
896                                        "nox_warning",
897                                        "display",
898                                        "saws_port_auto_select",
899                                        "saws_port_auto_select_silent",
900                                        "vecscatter_mpi1",
901                                        "check_pointer_intensity",
902                                        "cuda_initialize",
903                                        "error_output_stdout",
904                                        "use_gpu_aware_mpi",
905                                        "checkfunctionlist",
906                                        "petsc_ci",
907                                        "petsc_ci_portable_error_output",
908                                       };
909 
910 static PetscBool PetscCIOption(const char *name)
911 {
912   PetscInt  idx;
913   PetscBool found;
914 
915   if (!PetscCIEnabled) return PETSC_FALSE;
916   PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions),PetscCIOptions,name,&idx,&found);
917   return found;
918 }
919 
920 /*@C
921    PetscOptionsView - Prints the options that have been loaded. This is
922    useful for debugging purposes.
923 
924    Logically Collective on PetscViewer
925 
926    Input Parameters:
927 +  options - options database, use NULL for default global database
928 -  viewer - must be an PETSCVIEWERASCII viewer
929 
930    Options Database Key:
931 .  -options_view - Activates PetscOptionsView() within PetscFinalize()
932 
933    Notes:
934    Only the rank zero process of MPI_Comm used to create view prints the option values. Other processes
935    may have different values but they are not printed.
936 
937    Level: advanced
938 
939 .seealso: `PetscOptionsAllUsed()`
940 @*/
941 PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer)
942 {
943   PetscInt       i, N = 0;
944   PetscBool      isascii;
945 
946   PetscFunctionBegin;
947   if (viewer) PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
948   options = options ? options : defaultoptions;
949   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
950   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
951   PetscCheck(isascii,PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
952 
953   for (i=0; i<options->N; i++) {
954     if (PetscCIOption(options->names[i])) continue;
955     N++;
956   }
957 
958   if (!N) {
959     PetscCall(PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n"));
960     PetscFunctionReturn(0);
961   }
962 
963   PetscCall(PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n"));
964   for (i=0; i<options->N; i++) {
965     if (PetscCIOption(options->names[i])) continue;
966     if (options->values[i]) {
967       PetscCall(PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]));
968     } else {
969       PetscCall(PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]));
970     }
971   }
972   PetscCall(PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n"));
973   PetscFunctionReturn(0);
974 }
975 
976 /*
977    Called by error handlers to print options used in run
978 */
979 PetscErrorCode PetscOptionsLeftError(void)
980 {
981   PetscInt i, nopt = 0;
982 
983   for (i=0; i<defaultoptions->N; i++) {
984     if (!defaultoptions->used[i]) {
985       if (PetscCIOption(defaultoptions->names[i])) continue;
986       nopt++;
987     }
988   }
989   if (nopt) {
990     (*PetscErrorPrintf)("WARNING! There are option(s) set that were not used! Could be the program crashed before they were used or a spelling mistake, etc!\n");
991     for (i=0; i<defaultoptions->N; i++) {
992       if (!defaultoptions->used[i]) {
993         if (PetscCIOption(defaultoptions->names[i])) continue;
994         if (defaultoptions->values[i]) (*PetscErrorPrintf)("Option left: name:-%s value: %s\n",defaultoptions->names[i],defaultoptions->values[i]);
995         else (*PetscErrorPrintf)("Option left: name:-%s (no value)\n",defaultoptions->names[i]);
996       }
997     }
998   }
999   return 0;
1000 }
1001 
1002 PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1003 {
1004   PetscInt     i, N = 0;
1005   PetscOptions options = defaultoptions;
1006 
1007   for (i=0; i<options->N; i++) {
1008     if (PetscCIOption(options->names[i])) continue;
1009     N++;
1010   }
1011 
1012   if (N) {
1013     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
1014   } else {
1015     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
1016   }
1017   for (i=0; i<options->N; i++) {
1018     if (PetscCIOption(options->names[i])) continue;
1019     if (options->values[i]) {
1020       (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
1021     } else {
1022       (*PetscErrorPrintf)("-%s\n",options->names[i]);
1023     }
1024   }
1025   return 0;
1026 }
1027 
1028 /*@C
1029    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
1030 
1031    Logically Collective
1032 
1033    Input Parameters:
1034 +  options - options database, or NULL for the default global database
1035 -  prefix - The string to append to the existing prefix
1036 
1037    Options Database Keys:
1038 +   -prefix_push <some_prefix_> - push the given prefix
1039 -   -prefix_pop - pop the last prefix
1040 
1041    Notes:
1042    It is common to use this in conjunction with -options_file as in
1043 
1044 $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
1045 
1046    where the files no longer require all options to be prefixed with -system2_.
1047 
1048    The collectivity of this routine is complex; only the MPI processes that call this routine will
1049    have the affect of these options. If some processes that create objects call this routine and others do
1050    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1051    on different ranks.
1052 
1053 Level: advanced
1054 
1055 .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
1056 @*/
1057 PetscErrorCode PetscOptionsPrefixPush(PetscOptions options,const char prefix[])
1058 {
1059   size_t         n;
1060   PetscInt       start;
1061   char           key[MAXOPTNAME+1];
1062   PetscBool      valid;
1063 
1064   PetscFunctionBegin;
1065   PetscValidCharPointer(prefix,2);
1066   options = options ? options : defaultoptions;
1067   PetscCheck(options->prefixind < MAXPREFIXES,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum depth of prefix stack %d exceeded, recompile \n src/sys/objects/options.c with larger value for MAXPREFIXES",MAXPREFIXES);
1068   key[0] = '-'; /* keys must start with '-' */
1069   PetscCall(PetscStrncpy(key+1,prefix,sizeof(key)-1));
1070   PetscCall(PetscOptionsValidKey(key,&valid));
1071   if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */
1072   PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_USER,"Given prefix \"%s\" not valid (the first character must be a letter%s, do not include leading '-')",prefix,options->prefixind?" or digit":"");
1073   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
1074   PetscCall(PetscStrlen(prefix,&n));
1075   PetscCheck(n+1 <= sizeof(options->prefix)-start,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %zu exceeded",sizeof(options->prefix));
1076   PetscCall(PetscArraycpy(options->prefix+start,prefix,n+1));
1077   options->prefixstack[options->prefixind++] = start+n;
1078   PetscFunctionReturn(0);
1079 }
1080 
1081 /*@C
1082    PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details
1083 
1084    Logically Collective on the MPI_Comm that called PetscOptionsPrefixPush()
1085 
1086   Input Parameters:
1087 .  options - options database, or NULL for the default global database
1088 
1089    Level: advanced
1090 
1091 .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
1092 @*/
1093 PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1094 {
1095   PetscInt offset;
1096 
1097   PetscFunctionBegin;
1098   options = options ? options : defaultoptions;
1099   PetscCheck(options->prefixind >= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
1100   options->prefixind--;
1101   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
1102   options->prefix[offset] = 0;
1103   PetscFunctionReturn(0);
1104 }
1105 
1106 /*@C
1107     PetscOptionsClear - Removes all options form the database leaving it empty.
1108 
1109     Logically Collective
1110 
1111   Input Parameters:
1112 .  options - options database, use NULL for the default global database
1113 
1114    The collectivity of this routine is complex; only the MPI processes that call this routine will
1115    have the affect of these options. If some processes that create objects call this routine and others do
1116    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1117    on different ranks.
1118 
1119    Level: developer
1120 
1121 .seealso: `PetscOptionsInsert()`
1122 @*/
1123 PetscErrorCode PetscOptionsClear(PetscOptions options)
1124 {
1125   PetscInt i;
1126 
1127   PetscFunctionBegin;
1128   options = options ? options : defaultoptions;
1129   if (!options) PetscFunctionReturn(0);
1130 
1131   for (i=0; i<options->N; i++) {
1132     if (options->names[i])  free(options->names[i]);
1133     if (options->values[i]) free(options->values[i]);
1134   }
1135   options->N = 0;
1136 
1137   for (i=0; i<options->Naliases; i++) {
1138     free(options->aliases1[i]);
1139     free(options->aliases2[i]);
1140   }
1141   options->Naliases = 0;
1142 
1143   /* destroy hash table */
1144   kh_destroy(HO,options->ht);
1145   options->ht = NULL;
1146 
1147   options->prefixind = 0;
1148   options->prefix[0] = 0;
1149   options->help      = PETSC_FALSE;
1150   PetscFunctionReturn(0);
1151 }
1152 
1153 /*@C
1154    PetscOptionsSetAlias - Makes a key and alias for another key
1155 
1156    Logically Collective
1157 
1158    Input Parameters:
1159 +  options - options database, or NULL for default global database
1160 .  newname - the alias
1161 -  oldname - the name that alias will refer to
1162 
1163    Level: advanced
1164 
1165    The collectivity of this routine is complex; only the MPI processes that call this routine will
1166    have the affect of these options. If some processes that create objects call this routine and others do
1167    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1168    on different ranks.
1169 
1170 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1171           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1172           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1173           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1174           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1175           `PetscOptionsFList()`, `PetscOptionsEList()`
1176 @*/
1177 PetscErrorCode PetscOptionsSetAlias(PetscOptions options,const char newname[],const char oldname[])
1178 {
1179   PetscInt       n;
1180   size_t         len;
1181   PetscBool      valid;
1182 
1183   PetscFunctionBegin;
1184   PetscValidCharPointer(newname,2);
1185   PetscValidCharPointer(oldname,3);
1186   options = options ? options : defaultoptions;
1187   PetscCall(PetscOptionsValidKey(newname,&valid));
1188   PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliased option %s",newname);
1189   PetscCall(PetscOptionsValidKey(oldname,&valid));
1190   PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliasee option %s",oldname);
1191 
1192   n = options->Naliases;
1193   PetscCheck(n < MAXALIASES,PETSC_COMM_SELF,PETSC_ERR_MEM,"You have defined to many PETSc options aliases, limit %d recompile \n  src/sys/objects/options.c with larger value for MAXALIASES",MAXALIASES);
1194 
1195   newname++; oldname++;
1196   PetscCall(PetscStrlen(newname,&len));
1197   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
1198   PetscCall(PetscStrcpy(options->aliases1[n],newname));
1199   PetscCall(PetscStrlen(oldname,&len));
1200   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
1201   PetscCall(PetscStrcpy(options->aliases2[n],oldname));
1202   options->Naliases++;
1203   PetscFunctionReturn(0);
1204 }
1205 
1206 /*@C
1207    PetscOptionsSetValue - Sets an option name-value pair in the options
1208    database, overriding whatever is already present.
1209 
1210    Logically Collective
1211 
1212    Input Parameters:
1213 +  options - options database, use NULL for the default global database
1214 .  name - name of option, this SHOULD have the - prepended
1215 -  value - the option value (not used for all options, so can be NULL)
1216 
1217    Level: intermediate
1218 
1219    Note:
1220    This function can be called BEFORE PetscInitialize()
1221 
1222    The collectivity of this routine is complex; only the MPI processes that call this routine will
1223    have the affect of these options. If some processes that create objects call this routine and others do
1224    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1225    on different ranks.
1226 
1227    Developers Note: Uses malloc() directly because PETSc may not be initialized yet.
1228 
1229 .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1230 @*/
1231 PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[])
1232 {
1233   PetscFunctionBegin;
1234   PetscCall(PetscOptionsSetValue_Private(options,name,value,NULL));
1235   PetscFunctionReturn(0);
1236 }
1237 
1238 static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options,const char name[],const char value[],int *pos)
1239 {
1240   size_t      len;
1241   int         N,n,i;
1242   char      **names;
1243   char        fullname[MAXOPTNAME] = "";
1244   PetscBool   flg;
1245 
1246   PetscFunctionBegin;
1247   if (!options) {
1248     PetscCall(PetscOptionsCreateDefault());
1249     options = defaultoptions;
1250   }
1251   PetscCheck(name[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"name %s must start with '-'",name);
1252 
1253   PetscCall(PetscOptionsSkipPrecedent(options,name,&flg));
1254   if (flg) PetscFunctionReturn(0);
1255 
1256   name++; /* skip starting dash */
1257 
1258   if (options->prefixind > 0) {
1259     strncpy(fullname,options->prefix,sizeof(fullname));
1260     fullname[sizeof(fullname)-1] = 0;
1261     strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1);
1262     fullname[sizeof(fullname)-1] = 0;
1263     name = fullname;
1264   }
1265 
1266   /* check against aliases */
1267   N = options->Naliases;
1268   for (i=0; i<N; i++) {
1269     int result = PetscOptNameCmp(options->aliases1[i],name);
1270     if (!result) { name = options->aliases2[i]; break; }
1271   }
1272 
1273   /* slow search */
1274   N = n = options->N;
1275   names = options->names;
1276   for (i=0; i<N; i++) {
1277     int result = PetscOptNameCmp(names[i],name);
1278     if (!result) {
1279       n = i; goto setvalue;
1280     } else if (result > 0) {
1281       n = i; break;
1282     }
1283   }
1284   PetscCheck(N < MAXOPTIONS,PETSC_COMM_SELF,PETSC_ERR_MEM,"Number of options %d < max number of options %d, can not allocate enough space",N,MAXOPTIONS);
1285 
1286   /* shift remaining values up 1 */
1287   for (i=N; i>n; i--) {
1288     options->names[i]  = options->names[i-1];
1289     options->values[i] = options->values[i-1];
1290     options->used[i]   = options->used[i-1];
1291   }
1292   options->names[n]  = NULL;
1293   options->values[n] = NULL;
1294   options->used[n]   = PETSC_FALSE;
1295   options->N++;
1296 
1297   /* destroy hash table */
1298   kh_destroy(HO,options->ht);
1299   options->ht = NULL;
1300 
1301   /* set new name */
1302   len = strlen(name);
1303   options->names[n] = (char*)malloc((len+1)*sizeof(char));
1304   PetscCheck(options->names[n],PETSC_COMM_SELF,PETSC_ERR_MEM,"Failed to allocate option name");
1305   strcpy(options->names[n],name);
1306 
1307 setvalue:
1308   /* set new value */
1309   if (options->values[n]) free(options->values[n]);
1310   len = value ? strlen(value) : 0;
1311   if (len) {
1312     options->values[n] = (char*)malloc((len+1)*sizeof(char));
1313     if (!options->values[n]) return PETSC_ERR_MEM;
1314     strcpy(options->values[n],value);
1315   } else {
1316     options->values[n] = NULL;
1317   }
1318 
1319   /* handle -help so that it can be set from anywhere */
1320   if (!PetscOptNameCmp(name,"help")) {
1321     options->help = PETSC_TRUE;
1322     options->help_intro = (value && !PetscOptNameCmp(value,"intro")) ? PETSC_TRUE : PETSC_FALSE;
1323     options->used[n] = PETSC_TRUE;
1324   }
1325 
1326   PetscCall(PetscOptionsMonitor(options,name,value));
1327   if (pos) *pos = n;
1328   PetscFunctionReturn(0);
1329 }
1330 
1331 /*@C
1332    PetscOptionsClearValue - Clears an option name-value pair in the options
1333    database, overriding whatever is already present.
1334 
1335    Logically Collective
1336 
1337    Input Parameters:
1338 +  options - options database, use NULL for the default global database
1339 -  name - name of option, this SHOULD have the - prepended
1340 
1341    Level: intermediate
1342 
1343    The collectivity of this routine is complex; only the MPI processes that call this routine will
1344    have the affect of these options. If some processes that create objects call this routine and others do
1345    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1346    on different ranks.
1347 
1348 .seealso: `PetscOptionsInsert()`
1349 @*/
1350 PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[])
1351 {
1352   int            N,n,i;
1353   char           **names;
1354 
1355   PetscFunctionBegin;
1356   options = options ? options : defaultoptions;
1357   PetscCheck(name[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1358   if (!PetscOptNameCmp(name,"-help")) options->help = options->help_intro = PETSC_FALSE;
1359 
1360   name++; /* skip starting dash */
1361 
1362   /* slow search */
1363   N = n = options->N;
1364   names = options->names;
1365   for (i=0; i<N; i++) {
1366     int result = PetscOptNameCmp(names[i],name);
1367     if (!result) {
1368       n = i; break;
1369     } else if (result > 0) {
1370       n = N; break;
1371     }
1372   }
1373   if (n == N) PetscFunctionReturn(0); /* it was not present */
1374 
1375   /* remove name and value */
1376   if (options->names[n])  free(options->names[n]);
1377   if (options->values[n]) free(options->values[n]);
1378   /* shift remaining values down 1 */
1379   for (i=n; i<N-1; i++) {
1380     options->names[i]  = options->names[i+1];
1381     options->values[i] = options->values[i+1];
1382     options->used[i]   = options->used[i+1];
1383   }
1384   options->N--;
1385 
1386   /* destroy hash table */
1387   kh_destroy(HO,options->ht);
1388   options->ht = NULL;
1389 
1390   PetscCall(PetscOptionsMonitor(options,name,NULL));
1391   PetscFunctionReturn(0);
1392 }
1393 
1394 /*@C
1395    PetscOptionsFindPair - Gets an option name-value pair from the options database.
1396 
1397    Not Collective
1398 
1399    Input Parameters:
1400 +  options - options database, use NULL for the default global database
1401 .  pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
1402 -  name - name of option, this SHOULD have the "-" prepended
1403 
1404    Output Parameters:
1405 +  value - the option value (optional, not used for all options)
1406 -  set - whether the option is set (optional)
1407 
1408    Notes:
1409    Each process may find different values or no value depending on how options were inserted into the database
1410 
1411    Level: developer
1412 
1413 .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1414 @*/
1415 PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set)
1416 {
1417   char           buf[MAXOPTNAME];
1418   PetscBool      usehashtable = PETSC_TRUE;
1419   PetscBool      matchnumbers = PETSC_TRUE;
1420 
1421   PetscFunctionBegin;
1422   options = options ? options : defaultoptions;
1423   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'),PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1424   PetscCheck(name[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1425 
1426   name++; /* skip starting dash */
1427 
1428   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1429   if (pre && pre[0]) {
1430     char *ptr = buf;
1431     if (name[0] == '-') { *ptr++ = '-';  name++; }
1432     PetscCall(PetscStrncpy(ptr,pre,buf+sizeof(buf)-ptr));
1433     PetscCall(PetscStrlcat(buf,name,sizeof(buf)));
1434     name = buf;
1435   }
1436 
1437   if (PetscDefined(USE_DEBUG)) {
1438     PetscBool valid;
1439     char      key[MAXOPTNAME+1] = "-";
1440     PetscCall(PetscStrncpy(key+1,name,sizeof(key)-1));
1441     PetscCall(PetscOptionsValidKey(key,&valid));
1442     PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1443   }
1444 
1445   if (!options->ht && usehashtable) {
1446     int i,ret;
1447     khiter_t it;
1448     khash_t(HO) *ht;
1449     ht = kh_init(HO);
1450     PetscCheck(ht,PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1451     ret = kh_resize(HO,ht,options->N*2); /* twice the required size to reduce risk of collisions */
1452     PetscCheck(!ret,PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1453     for (i=0; i<options->N; i++) {
1454       it = kh_put(HO,ht,options->names[i],&ret);
1455       PetscCheck(ret == 1,PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1456       kh_val(ht,it) = i;
1457     }
1458     options->ht = ht;
1459   }
1460 
1461   if (usehashtable)
1462   { /* fast search */
1463     khash_t(HO) *ht = options->ht;
1464     khiter_t it = kh_get(HO,ht,name);
1465     if (it != kh_end(ht)) {
1466       int i = kh_val(ht,it);
1467       options->used[i]  = PETSC_TRUE;
1468       if (value) *value = options->values[i];
1469       if (set)   *set   = PETSC_TRUE;
1470       PetscFunctionReturn(0);
1471     }
1472   } else
1473   { /* slow search */
1474     int i, N = options->N;
1475     for (i=0; i<N; i++) {
1476       int result = PetscOptNameCmp(options->names[i],name);
1477       if (!result) {
1478         options->used[i]  = PETSC_TRUE;
1479         if (value) *value = options->values[i];
1480         if (set)   *set   = PETSC_TRUE;
1481         PetscFunctionReturn(0);
1482       } else if (result > 0) {
1483         break;
1484       }
1485     }
1486   }
1487 
1488   /*
1489    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
1490    Maybe this special lookup mode should be enabled on request with a push/pop API.
1491    The feature of matching _%d_ used sparingly in the codebase.
1492    */
1493   if (matchnumbers) {
1494     int i,j,cnt = 0,locs[16],loce[16];
1495     /* determine the location and number of all _%d_ in the key */
1496     for (i=0; name[i]; i++) {
1497       if (name[i] == '_') {
1498         for (j=i+1; name[j]; j++) {
1499           if (name[j] >= '0' && name[j] <= '9') continue;
1500           if (name[j] == '_' && j > i+1) { /* found a number */
1501             locs[cnt]   = i+1;
1502             loce[cnt++] = j+1;
1503           }
1504           i = j-1;
1505           break;
1506         }
1507       }
1508     }
1509     for (i=0; i<cnt; i++) {
1510       PetscBool found;
1511       char      opt[MAXOPTNAME+1] = "-", tmp[MAXOPTNAME];
1512       PetscCall(PetscStrncpy(tmp,name,PetscMin((size_t)(locs[i]+1),sizeof(tmp))));
1513       PetscCall(PetscStrlcat(opt,tmp,sizeof(opt)));
1514       PetscCall(PetscStrlcat(opt,name+loce[i],sizeof(opt)));
1515       PetscCall(PetscOptionsFindPair(options,NULL,opt,value,&found));
1516       if (found) {if (set) *set = PETSC_TRUE; PetscFunctionReturn(0);}
1517     }
1518   }
1519 
1520   if (set) *set = PETSC_FALSE;
1521   PetscFunctionReturn(0);
1522 }
1523 
1524 /* Check whether any option begins with pre+name */
1525 PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set)
1526 {
1527   char           buf[MAXOPTNAME];
1528   int            numCnt = 0, locs[16],loce[16];
1529 
1530   PetscFunctionBegin;
1531   options = options ? options : defaultoptions;
1532   PetscCheck(!pre || pre[0] != '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1533   PetscCheck(name[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1534 
1535   name++; /* skip starting dash */
1536 
1537   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1538   if (pre && pre[0]) {
1539     char *ptr = buf;
1540     if (name[0] == '-') { *ptr++ = '-';  name++; }
1541     PetscCall(PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf)));
1542     PetscCall(PetscStrlcat(buf,name,sizeof(buf)));
1543     name = buf;
1544   }
1545 
1546   if (PetscDefined(USE_DEBUG)) {
1547     PetscBool valid;
1548     char      key[MAXOPTNAME+1] = "-";
1549     PetscCall(PetscStrncpy(key+1,name,sizeof(key)-1));
1550     PetscCall(PetscOptionsValidKey(key,&valid));
1551     PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1552   }
1553 
1554   /* determine the location and number of all _%d_ in the key */
1555   {
1556     int i,j;
1557     for (i=0; name[i]; i++) {
1558       if (name[i] == '_') {
1559         for (j=i+1; name[j]; j++) {
1560           if (name[j] >= '0' && name[j] <= '9') continue;
1561           if (name[j] == '_' && j > i+1) { /* found a number */
1562             locs[numCnt]   = i+1;
1563             loce[numCnt++] = j+1;
1564           }
1565           i = j-1;
1566           break;
1567         }
1568       }
1569     }
1570   }
1571 
1572   { /* slow search */
1573     int       c, i;
1574     size_t    len;
1575     PetscBool match;
1576 
1577     for (c = -1; c < numCnt; ++c) {
1578       char opt[MAXOPTNAME+1] = "", tmp[MAXOPTNAME];
1579 
1580       if (c < 0) {
1581         PetscCall(PetscStrcpy(opt,name));
1582       } else {
1583         PetscCall(PetscStrncpy(tmp,name,PetscMin((size_t)(locs[c]+1),sizeof(tmp))));
1584         PetscCall(PetscStrlcat(opt,tmp,sizeof(opt)));
1585         PetscCall(PetscStrlcat(opt,name+loce[c],sizeof(opt)));
1586       }
1587       PetscCall(PetscStrlen(opt,&len));
1588       for (i=0; i<options->N; i++) {
1589         PetscCall(PetscStrncmp(options->names[i],opt,len,&match));
1590         if (match) {
1591           options->used[i]  = PETSC_TRUE;
1592           if (value) *value = options->values[i];
1593           if (set)   *set   = PETSC_TRUE;
1594           PetscFunctionReturn(0);
1595         }
1596       }
1597     }
1598   }
1599 
1600   if (set) *set = PETSC_FALSE;
1601   PetscFunctionReturn(0);
1602 }
1603 
1604 /*@C
1605    PetscOptionsReject - Generates an error if a certain option is given.
1606 
1607    Not Collective
1608 
1609    Input Parameters:
1610 +  options - options database, use NULL for default global database
1611 .  pre - the option prefix (may be NULL)
1612 .  name - the option name one is seeking
1613 -  mess - error message (may be NULL)
1614 
1615    Level: advanced
1616 
1617 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1618           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1619           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1620           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1621           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1622           `PetscOptionsFList()`, `PetscOptionsEList()`
1623 @*/
1624 PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[])
1625 {
1626   PetscBool      flag = PETSC_FALSE;
1627 
1628   PetscFunctionBegin;
1629   PetscCall(PetscOptionsHasName(options,pre,name,&flag));
1630   if (flag) {
1631     PetscCheck(!mess || !mess[0],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s with %s",pre?pre:"",name+1,mess);
1632     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1);
1633   }
1634   PetscFunctionReturn(0);
1635 }
1636 
1637 /*@C
1638    PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
1639 
1640    Not Collective
1641 
1642    Input Parameters:
1643 .  options - options database, use NULL for default global database
1644 
1645    Output Parameters:
1646 .  set - PETSC_TRUE if found else PETSC_FALSE.
1647 
1648    Level: advanced
1649 
1650 .seealso: `PetscOptionsHasName()`
1651 @*/
1652 PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
1653 {
1654   PetscFunctionBegin;
1655   PetscValidBoolPointer(set,2);
1656   options = options ? options : defaultoptions;
1657   *set = options->help;
1658   PetscFunctionReturn(0);
1659 }
1660 
1661 PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options,PetscBool *set)
1662 {
1663   PetscFunctionBegin;
1664   PetscValidBoolPointer(set,2);
1665   options = options ? options : defaultoptions;
1666   *set = options->help_intro;
1667   PetscFunctionReturn(0);
1668 }
1669 
1670 /*@C
1671    PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or Boolean, even
1672                       if its value is set to false.
1673 
1674    Not Collective
1675 
1676    Input Parameters:
1677 +  options - options database, use NULL for default global database
1678 .  pre - string to prepend to the name or NULL
1679 -  name - the option one is seeking
1680 
1681    Output Parameters:
1682 .  set - PETSC_TRUE if found else PETSC_FALSE.
1683 
1684    Level: beginner
1685 
1686    Notes:
1687    In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.
1688 
1689 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1690           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1691           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1692           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1693           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1694           `PetscOptionsFList()`, `PetscOptionsEList()`
1695 @*/
1696 PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set)
1697 {
1698   const char     *value;
1699   PetscBool      flag;
1700 
1701   PetscFunctionBegin;
1702   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
1703   if (set) *set = flag;
1704   PetscFunctionReturn(0);
1705 }
1706 
1707 /*@C
1708    PetscOptionsGetAll - Lists all the options the program was run with in a single string.
1709 
1710    Not Collective
1711 
1712    Input Parameter:
1713 .  options - the options database, use NULL for the default global database
1714 
1715    Output Parameter:
1716 .  copts - pointer where string pointer is stored
1717 
1718    Notes:
1719     The array and each entry in the array should be freed with PetscFree()
1720     Each process may have different values depending on how the options were inserted into the database
1721 
1722    Level: advanced
1723 
1724 .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
1725 @*/
1726 PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[])
1727 {
1728   PetscInt       i;
1729   size_t         len = 1,lent = 0;
1730   char           *coptions = NULL;
1731 
1732   PetscFunctionBegin;
1733   PetscValidPointer(copts,2);
1734   options = options ? options : defaultoptions;
1735   /* count the length of the required string */
1736   for (i=0; i<options->N; i++) {
1737     PetscCall(PetscStrlen(options->names[i],&lent));
1738     len += 2 + lent;
1739     if (options->values[i]) {
1740       PetscCall(PetscStrlen(options->values[i],&lent));
1741       len += 1 + lent;
1742     }
1743   }
1744   PetscCall(PetscMalloc1(len,&coptions));
1745   coptions[0] = 0;
1746   for (i=0; i<options->N; i++) {
1747     PetscCall(PetscStrcat(coptions,"-"));
1748     PetscCall(PetscStrcat(coptions,options->names[i]));
1749     PetscCall(PetscStrcat(coptions," "));
1750     if (options->values[i]) {
1751       PetscCall(PetscStrcat(coptions,options->values[i]));
1752       PetscCall(PetscStrcat(coptions," "));
1753     }
1754   }
1755   *copts = coptions;
1756   PetscFunctionReturn(0);
1757 }
1758 
1759 /*@C
1760    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
1761 
1762    Not Collective
1763 
1764    Input Parameters:
1765 +  options - options database, use NULL for default global database
1766 -  name - string name of option
1767 
1768    Output Parameter:
1769 .  used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database
1770 
1771    Level: advanced
1772 
1773    Notes:
1774    The value returned may be different on each process and depends on which options have been processed
1775    on the given process
1776 
1777 .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
1778 @*/
1779 PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used)
1780 {
1781   PetscInt       i;
1782 
1783   PetscFunctionBegin;
1784   PetscValidCharPointer(name,2);
1785   PetscValidBoolPointer(used,3);
1786   options = options ? options : defaultoptions;
1787   *used = PETSC_FALSE;
1788   for (i=0; i<options->N; i++) {
1789     PetscCall(PetscStrcasecmp(options->names[i],name,used));
1790     if (*used) {
1791       *used = options->used[i];
1792       break;
1793     }
1794   }
1795   PetscFunctionReturn(0);
1796 }
1797 
1798 /*@
1799    PetscOptionsAllUsed - Returns a count of the number of options in the
1800    database that have never been selected.
1801 
1802    Not Collective
1803 
1804    Input Parameter:
1805 .  options - options database, use NULL for default global database
1806 
1807    Output Parameter:
1808 .  N - count of options not used
1809 
1810    Level: advanced
1811 
1812    Notes:
1813    The value returned may be different on each process and depends on which options have been processed
1814    on the given process
1815 
1816 .seealso: `PetscOptionsView()`
1817 @*/
1818 PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N)
1819 {
1820   PetscInt     i,n = 0;
1821 
1822   PetscFunctionBegin;
1823   PetscValidIntPointer(N,2);
1824   options = options ? options : defaultoptions;
1825   for (i=0; i<options->N; i++) {
1826     if (!options->used[i]) n++;
1827   }
1828   *N = n;
1829   PetscFunctionReturn(0);
1830 }
1831 
1832 /*@
1833    PetscOptionsLeft - Prints to screen any options that were set and never used.
1834 
1835    Not Collective
1836 
1837    Input Parameter:
1838 .  options - options database; use NULL for default global database
1839 
1840    Options Database Key:
1841 .  -options_left - activates PetscOptionsAllUsed() within PetscFinalize()
1842 
1843    Notes:
1844       This is rarely used directly, it is called by PetscFinalize() in debug more or if -options_left
1845       is passed otherwise to help users determine possible mistakes in their usage of options. This
1846       only prints values on process zero of PETSC_COMM_WORLD. Other processes depending the objects
1847       used may have different options that are left unused.
1848 
1849    Level: advanced
1850 
1851 .seealso: `PetscOptionsAllUsed()`
1852 @*/
1853 PetscErrorCode PetscOptionsLeft(PetscOptions options)
1854 {
1855   PetscInt       i;
1856   PetscInt       cnt = 0;
1857   PetscOptions   toptions;
1858 
1859   PetscFunctionBegin;
1860   toptions = options ? options : defaultoptions;
1861   for (i=0; i<toptions->N; i++) {
1862     if (!toptions->used[i]) {
1863       if (PetscCIOption(toptions->names[i])) continue;
1864       if (toptions->values[i]) {
1865         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",toptions->names[i],toptions->values[i]));
1866       } else {
1867         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",toptions->names[i]));
1868       }
1869     }
1870   }
1871   if (!options) {
1872     toptions = defaultoptions;
1873     while (toptions->previous) {
1874       cnt++;
1875       toptions = toptions->previous;
1876     }
1877     if (cnt) {
1878       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Option left: You may have forgotten some calls to PetscOptionsPop(),\n             PetscOptionsPop() has been called %" PetscInt_FMT " less times than PetscOptionsPush()\n",cnt));
1879     }
1880   }
1881   PetscFunctionReturn(0);
1882 }
1883 
1884 /*@C
1885    PetscOptionsLeftGet - Returns all options that were set and never used.
1886 
1887    Not Collective
1888 
1889    Input Parameter:
1890 .  options - options database, use NULL for default global database
1891 
1892    Output Parameters:
1893 +  N - count of options not used
1894 .  names - names of options not used
1895 -  values - values of options not used
1896 
1897    Level: advanced
1898 
1899    Notes:
1900    Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine
1901    Notes: The value returned may be different on each process and depends on which options have been processed
1902    on the given process
1903 
1904 .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
1905 @*/
1906 PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[])
1907 {
1908   PetscInt       i,n;
1909 
1910   PetscFunctionBegin;
1911   if (N) PetscValidIntPointer(N,2);
1912   if (names) PetscValidPointer(names,3);
1913   if (values) PetscValidPointer(values,4);
1914   options = options ? options : defaultoptions;
1915 
1916   /* The number of unused PETSc options */
1917   n = 0;
1918   for (i=0; i<options->N; i++) {
1919     if (PetscCIOption(options->names[i])) continue;
1920     if (!options->used[i]) n++;
1921   }
1922   if (N) { *N = n; }
1923   if (names)  PetscCall(PetscMalloc1(n,names));
1924   if (values) PetscCall(PetscMalloc1(n,values));
1925 
1926   n = 0;
1927   if (names || values) {
1928     for (i=0; i<options->N; i++) {
1929       if (!options->used[i]) {
1930         if (PetscCIOption(options->names[i])) continue;
1931         if (names)  (*names)[n]  = options->names[i];
1932         if (values) (*values)[n] = options->values[i];
1933         n++;
1934       }
1935     }
1936   }
1937   PetscFunctionReturn(0);
1938 }
1939 
1940 /*@C
1941    PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using PetscOptionsLeftGet.
1942 
1943    Not Collective
1944 
1945    Input Parameters:
1946 +  options - options database, use NULL for default global database
1947 .  names - names of options not used
1948 -  values - values of options not used
1949 
1950    Level: advanced
1951 
1952 .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
1953 @*/
1954 PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[])
1955 {
1956   PetscFunctionBegin;
1957   if (N) PetscValidIntPointer(N,2);
1958   if (names) PetscValidPointer(names,3);
1959   if (values) PetscValidPointer(values,4);
1960   if (N) { *N = 0; }
1961   if (names)  PetscCall(PetscFree(*names));
1962   if (values) PetscCall(PetscFree(*values));
1963   PetscFunctionReturn(0);
1964 }
1965 
1966 /*@C
1967    PetscOptionsMonitorDefault - Print all options set value events using the supplied PetscViewer.
1968 
1969    Logically Collective on ctx
1970 
1971    Input Parameters:
1972 +  name  - option name string
1973 .  value - option value string
1974 -  ctx - an ASCII viewer or NULL
1975 
1976    Level: intermediate
1977 
1978    Notes:
1979      If ctx=NULL, PetscPrintf() is used.
1980      The first MPI rank in the PetscViewer viewer actually prints the values, other
1981      processes may have different values set
1982 
1983      If PetscCIEnabled then do not print the test harness options
1984 
1985 .seealso: `PetscOptionsMonitorSet()`
1986 @*/
1987 PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx)
1988 {
1989   PetscFunctionBegin;
1990   if (PetscCIOption(name)) PetscFunctionReturn(0);
1991 
1992   if (ctx) {
1993     PetscViewer viewer = (PetscViewer)ctx;
1994     if (!value) {
1995       PetscCall(PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name));
1996     } else if (!value[0]) {
1997       PetscCall(PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name));
1998     } else {
1999       PetscCall(PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value));
2000     }
2001   } else {
2002     MPI_Comm comm = PETSC_COMM_WORLD;
2003     if (!value) {
2004       PetscCall(PetscPrintf(comm,"Removing option: %s\n",name));
2005     } else if (!value[0]) {
2006       PetscCall(PetscPrintf(comm,"Setting option: %s (no value)\n",name));
2007     } else {
2008       PetscCall(PetscPrintf(comm,"Setting option: %s = %s\n",name,value));
2009     }
2010   }
2011   PetscFunctionReturn(0);
2012 }
2013 
2014 /*@C
2015    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
2016    modified the PETSc options database.
2017 
2018    Not Collective
2019 
2020    Input Parameters:
2021 +  monitor - pointer to function (if this is NULL, it turns off monitoring
2022 .  mctx    - [optional] context for private data for the
2023              monitor routine (use NULL if no context is desired)
2024 -  monitordestroy - [optional] routine that frees monitor context
2025           (may be NULL)
2026 
2027    Calling Sequence of monitor:
2028 $     monitor (const char name[], const char value[], void *mctx)
2029 
2030 +  name - option name string
2031 .  value - option value string
2032 -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()
2033 
2034    Options Database Keys:
2035    See PetscInitialize() for options related to option database monitoring.
2036 
2037    Notes:
2038    The default is to do nothing.  To print the name and value of options
2039    being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
2040    with a null monitoring context.
2041 
2042    Several different monitoring routines may be set by calling
2043    PetscOptionsMonitorSet() multiple times; all will be called in the
2044    order in which they were set.
2045 
2046    Level: intermediate
2047 
2048 .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
2049 @*/
2050 PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
2051 {
2052   PetscOptions options = defaultoptions;
2053 
2054   PetscFunctionBegin;
2055   if (options->monitorCancel) PetscFunctionReturn(0);
2056   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
2057   options->monitor[options->numbermonitors]          = monitor;
2058   options->monitordestroy[options->numbermonitors]   = monitordestroy;
2059   options->monitorcontext[options->numbermonitors++] = (void*)mctx;
2060   PetscFunctionReturn(0);
2061 }
2062 
2063 /*
2064    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
2065      Empty string is considered as true.
2066 */
2067 PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a)
2068 {
2069   PetscBool istrue,isfalse;
2070   size_t    len;
2071 
2072   PetscFunctionBegin;
2073   /* PetscStrlen() returns 0 for NULL or "" */
2074   PetscCall(PetscStrlen(value,&len));
2075   if (!len)  {*a = PETSC_TRUE; PetscFunctionReturn(0);}
2076   PetscCall(PetscStrcasecmp(value,"TRUE",&istrue));
2077   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
2078   PetscCall(PetscStrcasecmp(value,"YES",&istrue));
2079   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
2080   PetscCall(PetscStrcasecmp(value,"1",&istrue));
2081   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
2082   PetscCall(PetscStrcasecmp(value,"on",&istrue));
2083   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
2084   PetscCall(PetscStrcasecmp(value,"FALSE",&isfalse));
2085   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
2086   PetscCall(PetscStrcasecmp(value,"NO",&isfalse));
2087   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
2088   PetscCall(PetscStrcasecmp(value,"0",&isfalse));
2089   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
2090   PetscCall(PetscStrcasecmp(value,"off",&isfalse));
2091   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
2092   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
2093 }
2094 
2095 /*
2096    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
2097 */
2098 PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a)
2099 {
2100   size_t    len;
2101   PetscBool decide,tdefault,mouse;
2102 
2103   PetscFunctionBegin;
2104   PetscCall(PetscStrlen(name,&len));
2105   PetscCheck(len,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
2106 
2107   PetscCall(PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault));
2108   if (!tdefault) {
2109     PetscCall(PetscStrcasecmp(name,"DEFAULT",&tdefault));
2110   }
2111   PetscCall(PetscStrcasecmp(name,"PETSC_DECIDE",&decide));
2112   if (!decide) {
2113     PetscCall(PetscStrcasecmp(name,"DECIDE",&decide));
2114   }
2115   PetscCall(PetscStrcasecmp(name,"mouse",&mouse));
2116 
2117   if (tdefault)    *a = PETSC_DEFAULT;
2118   else if (decide) *a = PETSC_DECIDE;
2119   else if (mouse)  *a = -1;
2120   else {
2121     char *endptr;
2122     long strtolval;
2123 
2124     strtolval = strtol(name,&endptr,10);
2125     PetscCheck((size_t) (endptr - name) == len,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);
2126 
2127 #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
2128     (void) strtolval;
2129     *a = atoll(name);
2130 #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
2131     (void) strtolval;
2132     *a = _atoi64(name);
2133 #else
2134     *a = (PetscInt)strtolval;
2135 #endif
2136   }
2137   PetscFunctionReturn(0);
2138 }
2139 
2140 #if defined(PETSC_USE_REAL___FLOAT128)
2141 #include <quadmath.h>
2142 #endif
2143 
2144 static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr)
2145 {
2146   PetscFunctionBegin;
2147 #if defined(PETSC_USE_REAL___FLOAT128)
2148   *a = strtoflt128(name,endptr);
2149 #else
2150   *a = (PetscReal)strtod(name,endptr);
2151 #endif
2152   PetscFunctionReturn(0);
2153 }
2154 
2155 static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary)
2156 {
2157   PetscBool      hasi = PETSC_FALSE;
2158   char           *ptr;
2159   PetscReal      strtoval;
2160 
2161   PetscFunctionBegin;
2162   PetscCall(PetscStrtod(name,&strtoval,&ptr));
2163   if (ptr == name) {
2164     strtoval = 1.;
2165     hasi = PETSC_TRUE;
2166     if (name[0] == 'i') {
2167       ptr++;
2168     } else if (name[0] == '+' && name[1] == 'i') {
2169       ptr += 2;
2170     } else if (name[0] == '-' && name[1] == 'i') {
2171       strtoval = -1.;
2172       ptr += 2;
2173     }
2174   } else if (*ptr == 'i') {
2175     hasi = PETSC_TRUE;
2176     ptr++;
2177   }
2178   *endptr = ptr;
2179   *isImaginary = hasi;
2180   if (hasi) {
2181 #if !defined(PETSC_USE_COMPLEX)
2182     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name);
2183 #else
2184     *a = PetscCMPLX(0.,strtoval);
2185 #endif
2186   } else {
2187     *a = strtoval;
2188   }
2189   PetscFunctionReturn(0);
2190 }
2191 
2192 /*
2193    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
2194 */
2195 PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a)
2196 {
2197   size_t     len;
2198   PetscBool  match;
2199   char      *endptr;
2200 
2201   PetscFunctionBegin;
2202   PetscCall(PetscStrlen(name,&len));
2203   PetscCheck(len,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"String of length zero has no numerical value");
2204 
2205   PetscCall(PetscStrcasecmp(name,"PETSC_DEFAULT",&match));
2206   if (!match) PetscCall(PetscStrcasecmp(name,"DEFAULT",&match));
2207   if (match) {*a = PETSC_DEFAULT; PetscFunctionReturn(0);}
2208 
2209   PetscCall(PetscStrcasecmp(name,"PETSC_DECIDE",&match));
2210   if (!match) PetscCall(PetscStrcasecmp(name,"DECIDE",&match));
2211   if (match) {*a = PETSC_DECIDE; PetscFunctionReturn(0);}
2212 
2213   PetscCall(PetscStrtod(name,a,&endptr));
2214   PetscCheck((size_t) (endptr - name) == len,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name);
2215   PetscFunctionReturn(0);
2216 }
2217 
2218 PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a)
2219 {
2220   PetscBool    imag1;
2221   size_t       len;
2222   PetscScalar  val = 0.;
2223   char        *ptr = NULL;
2224 
2225   PetscFunctionBegin;
2226   PetscCall(PetscStrlen(name,&len));
2227   PetscCheck(len,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
2228   PetscCall(PetscStrtoz(name,&val,&ptr,&imag1));
2229 #if defined(PETSC_USE_COMPLEX)
2230   if ((size_t) (ptr - name) < len) {
2231     PetscBool   imag2;
2232     PetscScalar val2;
2233 
2234     PetscCall(PetscStrtoz(ptr,&val2,&ptr,&imag2));
2235     if (imag1) PetscCheck(imag2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name);
2236     val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2));
2237   }
2238 #endif
2239   PetscCheck((size_t) (ptr - name) == len,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
2240   *a = val;
2241   PetscFunctionReturn(0);
2242 }
2243 
2244 /*@C
2245    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
2246             option in the database.
2247 
2248    Not Collective
2249 
2250    Input Parameters:
2251 +  options - options database, use NULL for default global database
2252 .  pre - the string to prepend to the name or NULL
2253 -  name - the option one is seeking
2254 
2255    Output Parameters:
2256 +  ivalue - the logical value to return
2257 -  set - PETSC_TRUE  if found, else PETSC_FALSE
2258 
2259    Level: beginner
2260 
2261    Notes:
2262        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2263        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
2264 
2265       If the option is given, but no value is provided, then ivalue and set are both given the value PETSC_TRUE. That is -requested_bool
2266      is equivalent to -requested_bool true
2267 
2268        If the user does not supply the option at all ivalue is NOT changed. Thus
2269      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2270 
2271 .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2272           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2273           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2274           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2275           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2276           `PetscOptionsFList()`, `PetscOptionsEList()`
2277 @*/
2278 PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set)
2279 {
2280   const char     *value;
2281   PetscBool      flag;
2282 
2283   PetscFunctionBegin;
2284   PetscValidCharPointer(name,3);
2285   if (ivalue) PetscValidBoolPointer(ivalue,4);
2286   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2287   if (flag) {
2288     if (set) *set = PETSC_TRUE;
2289     PetscCall(PetscOptionsStringToBool(value, &flag));
2290     if (ivalue) *ivalue = flag;
2291   } else {
2292     if (set) *set = PETSC_FALSE;
2293   }
2294   PetscFunctionReturn(0);
2295 }
2296 
2297 /*@C
2298    PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2299 
2300    Not Collective
2301 
2302    Input Parameters:
2303 +  options - options database, use NULL for default global database
2304 .  pre - the string to prepend to the name or NULL
2305 .  opt - option name
2306 .  list - the possible choices (one of these must be selected, anything else is invalid)
2307 -  ntext - number of choices
2308 
2309    Output Parameters:
2310 +  value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2311 -  set - PETSC_TRUE if found, else PETSC_FALSE
2312 
2313    Level: intermediate
2314 
2315    Notes:
2316     If the user does not supply the option value is NOT changed. Thus
2317      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2318 
2319    See PetscOptionsFList() for when the choices are given in a PetscFunctionList()
2320 
2321 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2322           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2323           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2324           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2325           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2326           `PetscOptionsFList()`, `PetscOptionsEList()`
2327 @*/
2328 PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set)
2329 {
2330   size_t         alen,len = 0, tlen = 0;
2331   char           *svalue;
2332   PetscBool      aset,flg = PETSC_FALSE;
2333   PetscInt       i;
2334 
2335   PetscFunctionBegin;
2336   PetscValidCharPointer(opt,3);
2337   for (i=0; i<ntext; i++) {
2338     PetscCall(PetscStrlen(list[i],&alen));
2339     if (alen > len) len = alen;
2340     tlen += len + 1;
2341   }
2342   len += 5; /* a little extra space for user mistypes */
2343   PetscCall(PetscMalloc1(len,&svalue));
2344   PetscCall(PetscOptionsGetString(options,pre,opt,svalue,len,&aset));
2345   if (aset) {
2346     PetscCall(PetscEListFind(ntext,list,svalue,value,&flg));
2347     if (!flg) {
2348       char *avail,*pavl;
2349 
2350       PetscCall(PetscMalloc1(tlen,&avail));
2351       pavl = avail;
2352       for (i=0; i<ntext; i++) {
2353         PetscCall(PetscStrlen(list[i],&alen));
2354         PetscCall(PetscStrcpy(pavl,list[i]));
2355         pavl += alen;
2356         PetscCall(PetscStrcpy(pavl," "));
2357         pavl += 1;
2358       }
2359       PetscCall(PetscStrtolower(avail));
2360       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s. Available options: %s",svalue,pre ? pre : "",opt+1,avail);
2361     }
2362     if (set) *set = PETSC_TRUE;
2363   } else if (set) *set = PETSC_FALSE;
2364   PetscCall(PetscFree(svalue));
2365   PetscFunctionReturn(0);
2366 }
2367 
2368 /*@C
2369    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2370 
2371    Not Collective
2372 
2373    Input Parameters:
2374 +  options - options database, use NULL for default global database
2375 .  pre - option prefix or NULL
2376 .  opt - option name
2377 -  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2378 
2379    Output Parameters:
2380 +  value - the  value to return
2381 -  set - PETSC_TRUE if found, else PETSC_FALSE
2382 
2383    Level: beginner
2384 
2385    Notes:
2386     If the user does not supply the option value is NOT changed. Thus
2387      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2388 
2389           List is usually something like PCASMTypes or some other predefined list of enum names
2390 
2391 .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2392           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2393           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2394           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2395           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2396           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2397           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2398 @*/
2399 PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
2400 {
2401   PetscInt       ntext = 0,tval;
2402   PetscBool      fset;
2403 
2404   PetscFunctionBegin;
2405   PetscValidCharPointer(opt,3);
2406   while (list[ntext++]) {
2407     PetscCheck(ntext <= 50,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
2408   }
2409   PetscCheck(ntext >= 3,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
2410   ntext -= 3;
2411   PetscCall(PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset));
2412   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2413   if (fset) *value = (PetscEnum)tval;
2414   if (set) *set = fset;
2415   PetscFunctionReturn(0);
2416 }
2417 
2418 /*@C
2419    PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2420 
2421    Not Collective
2422 
2423    Input Parameters:
2424 +  options - options database, use NULL for default global database
2425 .  pre - the string to prepend to the name or NULL
2426 -  name - the option one is seeking
2427 
2428    Output Parameters:
2429 +  ivalue - the integer value to return
2430 -  set - PETSC_TRUE if found, else PETSC_FALSE
2431 
2432    Level: beginner
2433 
2434    Notes:
2435    If the user does not supply the option ivalue is NOT changed. Thus
2436    you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2437 
2438 .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2439           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2440           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2441           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2442           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2443           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2444           `PetscOptionsFList()`, `PetscOptionsEList()`
2445 @*/
2446 PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
2447 {
2448   const char     *value;
2449   PetscBool      flag;
2450 
2451   PetscFunctionBegin;
2452   PetscValidCharPointer(name,3);
2453   PetscValidIntPointer(ivalue,4);
2454   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2455   if (flag) {
2456     if (!value) {
2457       if (set) *set = PETSC_FALSE;
2458     } else {
2459       if (set) *set = PETSC_TRUE;
2460       PetscCall(PetscOptionsStringToInt(value,ivalue));
2461     }
2462   } else {
2463     if (set) *set = PETSC_FALSE;
2464   }
2465   PetscFunctionReturn(0);
2466 }
2467 
2468 /*@C
2469    PetscOptionsGetReal - Gets the double precision value for a particular
2470    option in the database.
2471 
2472    Not Collective
2473 
2474    Input Parameters:
2475 +  options - options database, use NULL for default global database
2476 .  pre - string to prepend to each name or NULL
2477 -  name - the option one is seeking
2478 
2479    Output Parameters:
2480 +  dvalue - the double value to return
2481 -  set - PETSC_TRUE if found, PETSC_FALSE if not found
2482 
2483    Notes:
2484     If the user does not supply the option dvalue is NOT changed. Thus
2485      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2486 
2487    Level: beginner
2488 
2489 .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2490           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2491           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2492           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2493           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2494           `PetscOptionsFList()`, `PetscOptionsEList()`
2495 @*/
2496 PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
2497 {
2498   const char     *value;
2499   PetscBool      flag;
2500 
2501   PetscFunctionBegin;
2502   PetscValidCharPointer(name,3);
2503   PetscValidRealPointer(dvalue,4);
2504   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2505   if (flag) {
2506     if (!value) {
2507       if (set) *set = PETSC_FALSE;
2508     } else {
2509       if (set) *set = PETSC_TRUE;
2510       PetscCall(PetscOptionsStringToReal(value,dvalue));
2511     }
2512   } else {
2513     if (set) *set = PETSC_FALSE;
2514   }
2515   PetscFunctionReturn(0);
2516 }
2517 
2518 /*@C
2519    PetscOptionsGetScalar - Gets the scalar value for a particular
2520    option in the database.
2521 
2522    Not Collective
2523 
2524    Input Parameters:
2525 +  options - options database, use NULL for default global database
2526 .  pre - string to prepend to each name or NULL
2527 -  name - the option one is seeking
2528 
2529    Output Parameters:
2530 +  dvalue - the double value to return
2531 -  set - PETSC_TRUE if found, else PETSC_FALSE
2532 
2533    Level: beginner
2534 
2535    Usage:
2536    A complex number 2+3i must be specified with NO spaces
2537 
2538    Notes:
2539     If the user does not supply the option dvalue is NOT changed. Thus
2540      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2541 
2542 .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2543           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2544           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2545           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2546           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2547           `PetscOptionsFList()`, `PetscOptionsEList()`
2548 @*/
2549 PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
2550 {
2551   const char     *value;
2552   PetscBool      flag;
2553 
2554   PetscFunctionBegin;
2555   PetscValidCharPointer(name,3);
2556   PetscValidScalarPointer(dvalue,4);
2557   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2558   if (flag) {
2559     if (!value) {
2560       if (set) *set = PETSC_FALSE;
2561     } else {
2562 #if !defined(PETSC_USE_COMPLEX)
2563       PetscCall(PetscOptionsStringToReal(value,dvalue));
2564 #else
2565       PetscCall(PetscOptionsStringToScalar(value,dvalue));
2566 #endif
2567       if (set) *set = PETSC_TRUE;
2568     }
2569   } else { /* flag */
2570     if (set) *set = PETSC_FALSE;
2571   }
2572   PetscFunctionReturn(0);
2573 }
2574 
2575 /*@C
2576    PetscOptionsGetString - Gets the string value for a particular option in
2577    the database.
2578 
2579    Not Collective
2580 
2581    Input Parameters:
2582 +  options - options database, use NULL for default global database
2583 .  pre - string to prepend to name or NULL
2584 .  name - the option one is seeking
2585 -  len - maximum length of the string including null termination
2586 
2587    Output Parameters:
2588 +  string - location to copy string
2589 -  set - PETSC_TRUE if found, else PETSC_FALSE
2590 
2591    Level: beginner
2592 
2593    Fortran Note:
2594    The Fortran interface is slightly different from the C/C++
2595    interface (len is not used).  Sample usage in Fortran follows
2596 .vb
2597       character *20    string
2598       PetscErrorCode   ierr
2599       PetscBool        set
2600       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2601 .ve
2602 
2603    Notes:
2604     if the option is given but no string is provided then an empty string is returned and set is given the value of PETSC_TRUE
2605 
2606            If the user does not use the option then the string is not changed. Thus
2607            you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
2608 
2609     Note:
2610       Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls).
2611 
2612 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2613           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2614           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2615           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2616           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2617           `PetscOptionsFList()`, `PetscOptionsEList()`
2618 @*/
2619 PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set)
2620 {
2621   const char     *value;
2622   PetscBool      flag;
2623 
2624   PetscFunctionBegin;
2625   PetscValidCharPointer(name,3);
2626   PetscValidCharPointer(string,4);
2627   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2628   if (!flag) {
2629     if (set) *set = PETSC_FALSE;
2630   } else {
2631     if (set) *set = PETSC_TRUE;
2632     if (value) PetscCall(PetscStrncpy(string,value,len));
2633     else PetscCall(PetscArrayzero(string,len));
2634   }
2635   PetscFunctionReturn(0);
2636 }
2637 
2638 char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
2639 {
2640   const char *value;
2641   PetscBool   flag;
2642 
2643   PetscFunctionBegin;
2644   if (PetscOptionsFindPair(options,pre,name,&value,&flag)) PetscFunctionReturn(NULL);
2645   if (flag) PetscFunctionReturn((char*)value);
2646   PetscFunctionReturn(NULL);
2647 }
2648 
2649 /*@C
2650   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2651   option in the database.  The values must be separated with commas with no intervening spaces.
2652 
2653   Not Collective
2654 
2655   Input Parameters:
2656 + options - options database, use NULL for default global database
2657 . pre - string to prepend to each name or NULL
2658 - name - the option one is seeking
2659 
2660   Output Parameters:
2661 + dvalue - the integer values to return
2662 . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2663 - set - PETSC_TRUE if found, else PETSC_FALSE
2664 
2665   Level: beginner
2666 
2667   Notes:
2668   TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE. FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
2669 
2670 .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2671           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2672           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2673           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2674           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2675           `PetscOptionsFList()`, `PetscOptionsEList()`
2676 @*/
2677 PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
2678 {
2679   const char     *svalue;
2680   char           *value;
2681   PetscInt       n = 0;
2682   PetscBool      flag;
2683   PetscToken     token;
2684 
2685   PetscFunctionBegin;
2686   PetscValidCharPointer(name,3);
2687   PetscValidBoolPointer(dvalue,4);
2688   PetscValidIntPointer(nmax,5);
2689 
2690   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
2691   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
2692   if (set) *set = PETSC_TRUE;
2693   PetscCall(PetscTokenCreate(svalue,',',&token));
2694   PetscCall(PetscTokenFind(token,&value));
2695   while (value && n < *nmax) {
2696     PetscCall(PetscOptionsStringToBool(value,dvalue));
2697     PetscCall(PetscTokenFind(token,&value));
2698     dvalue++;
2699     n++;
2700   }
2701   PetscCall(PetscTokenDestroy(&token));
2702   *nmax = n;
2703   PetscFunctionReturn(0);
2704 }
2705 
2706 /*@C
2707   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
2708 
2709   Not Collective
2710 
2711   Input Parameters:
2712 + options - options database, use NULL for default global database
2713 . pre - option prefix or NULL
2714 . name - option name
2715 - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2716 
2717   Output Parameters:
2718 + ivalue - the  enum values to return
2719 . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2720 - set - PETSC_TRUE if found, else PETSC_FALSE
2721 
2722   Level: beginner
2723 
2724   Notes:
2725   The array must be passed as a comma separated list.
2726 
2727   There must be no intervening spaces between the values.
2728 
2729   list is usually something like PCASMTypes or some other predefined list of enum names.
2730 
2731 .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2732           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2733           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, `PetscOptionsName()`,
2734           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2735           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2736           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2737 @*/
2738 PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
2739 {
2740   const char     *svalue;
2741   char           *value;
2742   PetscInt       n = 0;
2743   PetscEnum      evalue;
2744   PetscBool      flag;
2745   PetscToken     token;
2746 
2747   PetscFunctionBegin;
2748   PetscValidCharPointer(name,3);
2749   PetscValidPointer(list,4);
2750   PetscValidPointer(ivalue,5);
2751   PetscValidIntPointer(nmax,6);
2752 
2753   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
2754   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
2755   if (set) *set = PETSC_TRUE;
2756   PetscCall(PetscTokenCreate(svalue,',',&token));
2757   PetscCall(PetscTokenFind(token,&value));
2758   while (value && n < *nmax) {
2759     PetscCall(PetscEnumFind(list,value,&evalue,&flag));
2760     PetscCheck(flag,PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
2761     ivalue[n++] = evalue;
2762     PetscCall(PetscTokenFind(token,&value));
2763   }
2764   PetscCall(PetscTokenDestroy(&token));
2765   *nmax = n;
2766   PetscFunctionReturn(0);
2767 }
2768 
2769 /*@C
2770   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
2771 
2772   Not Collective
2773 
2774   Input Parameters:
2775 + options - options database, use NULL for default global database
2776 . pre - string to prepend to each name or NULL
2777 - name - the option one is seeking
2778 
2779   Output Parameters:
2780 + ivalue - the integer values to return
2781 . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2782 - set - PETSC_TRUE if found, else PETSC_FALSE
2783 
2784   Level: beginner
2785 
2786   Notes:
2787   The array can be passed as
2788 .vb
2789   a comma separated list:                                 0,1,2,3,4,5,6,7
2790   a range (start-end+1):                                  0-8
2791   a range with given increment (start-end+1:inc):         0-7:2
2792   a combination of values and ranges separated by commas: 0,1-8,8-15:2
2793 .ve
2794 
2795   There must be no intervening spaces between the values.
2796 
2797 .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2798           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2799           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2800           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2801           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2802           `PetscOptionsFList()`, `PetscOptionsEList()`
2803 @*/
2804 PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set)
2805 {
2806   const char     *svalue;
2807   char           *value;
2808   PetscInt       n = 0,i,j,start,end,inc,nvalues;
2809   size_t         len;
2810   PetscBool      flag,foundrange;
2811   PetscToken     token;
2812 
2813   PetscFunctionBegin;
2814   PetscValidCharPointer(name,3);
2815   PetscValidIntPointer(ivalue,4);
2816   PetscValidIntPointer(nmax,5);
2817 
2818   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
2819   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
2820   if (set) *set = PETSC_TRUE;
2821   PetscCall(PetscTokenCreate(svalue,',',&token));
2822   PetscCall(PetscTokenFind(token,&value));
2823   while (value && n < *nmax) {
2824     /* look for form  d-D where d and D are integers */
2825     foundrange = PETSC_FALSE;
2826     PetscCall(PetscStrlen(value,&len));
2827     if (value[0] == '-') i=2;
2828     else i=1;
2829     for (;i<(int)len; i++) {
2830       if (value[i] == '-') {
2831         PetscCheck(i != (int)len-1,PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %" PetscInt_FMT "-th array entry %s",n,value);
2832         value[i] = 0;
2833 
2834         PetscCall(PetscOptionsStringToInt(value,&start));
2835         inc  = 1;
2836         j    = i+1;
2837         for (;j<(int)len; j++) {
2838           if (value[j] == ':') {
2839             value[j] = 0;
2840 
2841             PetscCall(PetscOptionsStringToInt(value+j+1,&inc));
2842             PetscCheck(inc > 0,PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %" PetscInt_FMT "-th array entry,%s cannot have negative increment",n,value+j+1);
2843             break;
2844           }
2845         }
2846         PetscCall(PetscOptionsStringToInt(value+i+1,&end));
2847         PetscCheck(end > start,PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list",n,value,value+i+1);
2848         nvalues = (end-start)/inc + (end-start)%inc;
2849         PetscCheck(n + nvalues  <= *nmax,PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %" PetscInt_FMT "-th array entry, not enough space left in array (%" PetscInt_FMT ") to contain entire range from %" PetscInt_FMT " to %" PetscInt_FMT,n,*nmax-n,start,end);
2850         for (;start<end; start+=inc) {
2851           *ivalue = start; ivalue++;n++;
2852         }
2853         foundrange = PETSC_TRUE;
2854         break;
2855       }
2856     }
2857     if (!foundrange) {
2858       PetscCall(PetscOptionsStringToInt(value,ivalue));
2859       ivalue++;
2860       n++;
2861     }
2862     PetscCall(PetscTokenFind(token,&value));
2863   }
2864   PetscCall(PetscTokenDestroy(&token));
2865   *nmax = n;
2866   PetscFunctionReturn(0);
2867 }
2868 
2869 /*@C
2870   PetscOptionsGetRealArray - Gets an array of double precision values for a
2871   particular option in the database.  The values must be separated with commas with no intervening spaces.
2872 
2873   Not Collective
2874 
2875   Input Parameters:
2876 + options - options database, use NULL for default global database
2877 . pre - string to prepend to each name or NULL
2878 - name - the option one is seeking
2879 
2880   Output Parameters:
2881 + dvalue - the double values to return
2882 . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2883 - set - PETSC_TRUE if found, else PETSC_FALSE
2884 
2885   Level: beginner
2886 
2887 .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2888           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2889           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2890           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2891           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2892           `PetscOptionsFList()`, `PetscOptionsEList()`
2893 @*/
2894 PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
2895 {
2896   const char     *svalue;
2897   char           *value;
2898   PetscInt       n = 0;
2899   PetscBool      flag;
2900   PetscToken     token;
2901 
2902   PetscFunctionBegin;
2903   PetscValidCharPointer(name,3);
2904   PetscValidRealPointer(dvalue,4);
2905   PetscValidIntPointer(nmax,5);
2906 
2907   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
2908   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
2909   if (set) *set = PETSC_TRUE;
2910   PetscCall(PetscTokenCreate(svalue,',',&token));
2911   PetscCall(PetscTokenFind(token,&value));
2912   while (value && n < *nmax) {
2913     PetscCall(PetscOptionsStringToReal(value,dvalue++));
2914     PetscCall(PetscTokenFind(token,&value));
2915     n++;
2916   }
2917   PetscCall(PetscTokenDestroy(&token));
2918   *nmax = n;
2919   PetscFunctionReturn(0);
2920 }
2921 
2922 /*@C
2923   PetscOptionsGetScalarArray - Gets an array of scalars for a
2924   particular option in the database.  The values must be separated with commas with no intervening spaces.
2925 
2926   Not Collective
2927 
2928   Input Parameters:
2929 + options - options database, use NULL for default global database
2930 . pre - string to prepend to each name or NULL
2931 - name - the option one is seeking
2932 
2933   Output Parameters:
2934 + dvalue - the scalar values to return
2935 . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2936 - set - PETSC_TRUE if found, else PETSC_FALSE
2937 
2938   Level: beginner
2939 
2940 .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2941           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2942           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2943           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2944           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2945           `PetscOptionsFList()`, `PetscOptionsEList()`
2946 @*/
2947 PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
2948 {
2949   const char     *svalue;
2950   char           *value;
2951   PetscInt       n = 0;
2952   PetscBool      flag;
2953   PetscToken     token;
2954 
2955   PetscFunctionBegin;
2956   PetscValidCharPointer(name,3);
2957   PetscValidScalarPointer(dvalue,4);
2958   PetscValidIntPointer(nmax,5);
2959 
2960   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
2961   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
2962   if (set) *set = PETSC_TRUE;
2963   PetscCall(PetscTokenCreate(svalue,',',&token));
2964   PetscCall(PetscTokenFind(token,&value));
2965   while (value && n < *nmax) {
2966     PetscCall(PetscOptionsStringToScalar(value,dvalue++));
2967     PetscCall(PetscTokenFind(token,&value));
2968     n++;
2969   }
2970   PetscCall(PetscTokenDestroy(&token));
2971   *nmax = n;
2972   PetscFunctionReturn(0);
2973 }
2974 
2975 /*@C
2976   PetscOptionsGetStringArray - Gets an array of string values for a particular
2977   option in the database. The values must be separated with commas with no intervening spaces.
2978 
2979   Not Collective
2980 
2981   Input Parameters:
2982 + options - options database, use NULL for default global database
2983 . pre - string to prepend to name or NULL
2984 - name - the option one is seeking
2985 
2986   Output Parameters:
2987 + strings - location to copy strings
2988 . nmax - On input maximum number of strings, on output the actual number of strings found
2989 - set - PETSC_TRUE if found, else PETSC_FALSE
2990 
2991   Level: beginner
2992 
2993   Notes:
2994   The nmax parameter is used for both input and output.
2995 
2996   The user should pass in an array of pointers to char, to hold all the
2997   strings returned by this function.
2998 
2999   The user is responsible for deallocating the strings that are
3000   returned. The Fortran interface for this routine is not supported.
3001 
3002 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3003           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3004           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3005           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3006           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3007           `PetscOptionsFList()`, `PetscOptionsEList()`
3008 @*/
3009 PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
3010 {
3011   const char     *svalue;
3012   char           *value;
3013   PetscInt       n = 0;
3014   PetscBool      flag;
3015   PetscToken     token;
3016 
3017   PetscFunctionBegin;
3018   PetscValidCharPointer(name,3);
3019   PetscValidPointer(strings,4);
3020   PetscValidIntPointer(nmax,5);
3021 
3022   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
3023   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
3024   if (set) *set = PETSC_TRUE;
3025   PetscCall(PetscTokenCreate(svalue,',',&token));
3026   PetscCall(PetscTokenFind(token,&value));
3027   while (value && n < *nmax) {
3028     PetscCall(PetscStrallocpy(value,&strings[n]));
3029     PetscCall(PetscTokenFind(token,&value));
3030     n++;
3031   }
3032   PetscCall(PetscTokenDestroy(&token));
3033   *nmax = n;
3034   PetscFunctionReturn(0);
3035 }
3036 
3037 /*@C
3038    PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one
3039 
3040    Prints a deprecation warning, unless an option is supplied to suppress.
3041 
3042    Logically Collective
3043 
3044    Input Parameters:
3045 +  pre - string to prepend to name or NULL
3046 .  oldname - the old, deprecated option
3047 .  newname - the new option, or NULL if option is purely removed
3048 .  version - a string describing the version of first deprecation, e.g. "3.9"
3049 -  info - additional information string, or NULL.
3050 
3051    Options Database Keys:
3052 . -options_suppress_deprecated_warnings - do not print deprecation warnings
3053 
3054    Notes:
3055    Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd().
3056    Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or
3057    PetscObjectOptionsBegin() prints the information
3058    If newname is provided, the old option is replaced. Otherwise, it remains
3059    in the options database.
3060    If an option is not replaced, the info argument should be used to advise the user
3061    on how to proceed.
3062    There is a limit on the length of the warning printed, so very long strings
3063    provided as info may be truncated.
3064 
3065    Level: developer
3066 
3067 .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
3068 
3069 @*/
3070 PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
3071 {
3072   PetscBool          found,quiet;
3073   const char         *value;
3074   const char * const quietopt="-options_suppress_deprecated_warnings";
3075   char               msg[4096];
3076   char               *prefix = NULL;
3077   PetscOptions       options = NULL;
3078   MPI_Comm           comm = PETSC_COMM_SELF;
3079 
3080   PetscFunctionBegin;
3081   PetscValidCharPointer(oldname,2);
3082   PetscValidCharPointer(version,4);
3083   if (PetscOptionsObject) {
3084     prefix  = PetscOptionsObject->prefix;
3085     options = PetscOptionsObject->options;
3086     comm    = PetscOptionsObject->comm;
3087   }
3088   PetscCall(PetscOptionsFindPair(options,prefix,oldname,&value,&found));
3089   if (found) {
3090     if (newname) {
3091       if (prefix) PetscCall(PetscOptionsPrefixPush(options,prefix));
3092       PetscCall(PetscOptionsSetValue(options,newname,value));
3093       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
3094       PetscCall(PetscOptionsClearValue(options,oldname));
3095     }
3096     quiet = PETSC_FALSE;
3097     PetscCall(PetscOptionsGetBool(options,NULL,quietopt,&quiet,NULL));
3098     if (!quiet) {
3099       PetscCall(PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option "));
3100       PetscCall(PetscStrcat(msg,oldname));
3101       PetscCall(PetscStrcat(msg," is deprecated as of version "));
3102       PetscCall(PetscStrcat(msg,version));
3103       PetscCall(PetscStrcat(msg," and will be removed in a future release."));
3104       if (newname) {
3105         PetscCall(PetscStrcat(msg," Please use the option "));
3106         PetscCall(PetscStrcat(msg,newname));
3107         PetscCall(PetscStrcat(msg," instead."));
3108       }
3109       if (info) {
3110         PetscCall(PetscStrcat(msg," "));
3111         PetscCall(PetscStrcat(msg,info));
3112       }
3113       PetscCall(PetscStrcat(msg," (Silence this warning with "));
3114       PetscCall(PetscStrcat(msg,quietopt));
3115       PetscCall(PetscStrcat(msg,")\n"));
3116       PetscCall(PetscPrintf(comm,"%s",msg));
3117     }
3118   }
3119   PetscFunctionReturn(0);
3120 }
3121