Actual source code: aoptions.c

  1: /*$Id: aoptions.c,v 1.27 2001/03/23 23:20:42 balay Exp bsmith $*/
  2: /*
  3:    These routines simplify the use of command line, file options, etc.,
  4:    and are used to manipulate the options database.

  6:   This file uses regular malloc and free because it cannot know 
  7:   what malloc is being used until it has already processed the input.
  8: */

 10:  #include petsc.h
 11:  #include petscsys.h
 12: #if defined(PETSC_HAVE_STDLIB_H)
 13: #include <stdlib.h>
 14: #endif

 16: #if defined(PETSC_HAVE_AMS)
 17: /*
 18:     We keep a linked list of options that have been posted and we are waiting for 
 19:    user selection

 21:     Eventually we'll attach this beast to a MPI_Comm
 22: */
 23: typedef enum {OPTION_INT,OPTION_LOGICAL,OPTION_DOUBLE,OPTION_LIST,OPTION_STRING,OPTION_DOUBLE_ARRAY,OPTION_HEAD} OptionType;
 24: typedef struct _p_OptionsAMS* PetscOptionsAMS;
 25: struct _p_OptionsAMS {
 26:   char            *option;
 27:   char            *text;
 28:   void            *data;
 29:   void            *edata;
 30:   int             arraylength;
 31:   PetscTruth      set;
 32:   OptionType      type;
 33:   PetscOptionsAMS next;
 34:   char            *man;
 35: };
 36: #endif

 38: typedef struct {
 39: #if defined(PETSC_HAVE_AMS)
 40:   AMS_Memory amem;
 41:   PetscOptionsAMS next;
 42: #endif
 43:   char       *prefix,*mprefix;  /* publish mprefix, not prefix cause the AMS will change it BUT we need to free it*/
 44:   char       *title;
 45:   MPI_Comm   comm;
 46:   PetscTruth printhelp;
 47:   PetscTruth changedmethod;
 48: } PetscOptionsPublishObject;
 49: static PetscOptionsPublishObject amspub;
 50: int PetscOptionsPublishCount;

 52: int PetscOptionsBegin_Private(MPI_Comm comm,char *prefix,char *title,char *mansec)
 53: {
 54:   int        ierr;

 57:   PetscStrallocpy(prefix,&amspub.prefix);
 58:   PetscStrallocpy(title,&amspub.title);
 59:   amspub.comm   = comm;
 60:   PetscOptionsHasName(PETSC_NULL,"-help",&amspub.printhelp);
 61:   if (amspub.printhelp && PetscOptionsPublishCount) {
 62:     (*PetscHelpPrintf)(comm,"%s -------------------------------------------------n",title);
 63:   }
 64: 
 65: #if defined(PETSC_HAVE_AMS)
 66:   if (!PetscOptionsPublishCount) {
 67:     AMS_Comm   acomm;
 68:     static int count = 0;
 69:     char       options[16];
 70:     /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */
 71:     PetscViewerAMSGetAMSComm(PETSC_VIEWER_AMS_(PETSC_COMM_WORLD),&acomm);
 72:     sprintf(options,"Options_%d",count++);
 73:     AMS_Memory_create(acomm,options,&amspub.amem);
 74:     AMS_Memory_take_access(amspub.amem);
 75:     amspub.mprefix = amspub.prefix;
 76:     AMS_Memory_add_field(amspub.amem,title,&amspub.mprefix,1,AMS_STRING,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);
 77:     AMS_Memory_add_field(amspub.amem,mansec,&amspub.mprefix,1,AMS_STRING,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);
 78:     amspub.changedmethod = PETSC_FALSE;
 79:     AMS_Memory_add_field(amspub.amem,"ChangedMethod",&amspub.changedmethod,1,AMS_BOOLEAN,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
 80:   }
 81: #endif
 82:   return(0);
 83: }

 85: int PetscOptionsEnd_Private(void)
 86: {

 90: #if defined(PETSC_HAVE_AMS)
 91:   if (!PetscOptionsPublishCount) {
 92:     PetscOptionsAMS last;
 93:     char       option[256],value[1024],tmp[32];
 94:     int        j;

 96:     if (amspub.amem < 0) SETERRQ(1,"Called without a call to PetscOptionsBegin()");
 97:     AMS_Memory_publish(amspub.amem);
 98:     AMS_Memory_grant_access(amspub.amem);
 99:     /* wait until accessor has unlocked the memory */
100:     AMS_Memory_lock(amspub.amem,0);
101:     AMS_Memory_take_access(amspub.amem);

103:     /* reset counter to -2; this updates the screen with the new options for the selected method */
104:     if (amspub.changedmethod) PetscOptionsPublishCount = -2;

106:     /*
107:         Free all the PetscOptions in the linked list and add any changed ones to the database
108:     */
109:     while (amspub.next) {
110:       if (amspub.next->set) {
111:         if (amspub.prefix) {
112:           PetscStrcpy(option,"-");
113:           PetscStrcat(option,amspub.prefix);
114:           PetscStrcat(option,amspub.next->option+1);
115:         } else {
116:           PetscStrcpy(option,amspub.next->option);
117:         }

119:         switch (amspub.next->type) {
120:           case OPTION_HEAD:
121:             break;
122:           case OPTION_INT:
123:             sprintf(value,"%d",*(int*)amspub.next->data);
124:             break;
125:           case OPTION_DOUBLE:
126:             sprintf(value,"%g",*(double*)amspub.next->data);
127:             break;
128:           case OPTION_DOUBLE_ARRAY:
129:             sprintf(value,"%g",((double*)amspub.next->data)[0]);
130:             for (j=1; j<amspub.next->arraylength; j++) {
131:               sprintf(tmp,"%g",((double*)amspub.next->data)[j]);
132:               PetscStrcat(value,",");
133:               PetscStrcat(value,tmp);
134:             }
135:             break;
136:           case OPTION_LOGICAL:
137:             sprintf(value,"%d",*(int*)amspub.next->data);
138:             break;
139:           case OPTION_LIST:
140:             PetscStrcpy(value,*(char**)amspub.next->data);
141:             break;
142:           case OPTION_STRING: /* also handles string arrays */
143:             PetscStrcpy(value,*(char**)amspub.next->data);
144:             break;
145:         }
146:         PetscOptionsSetValue(option,value);
147:       }
148:       ierr   = PetscStrfree(amspub.next->text);
149:       ierr   = PetscStrfree(amspub.next->option);
150:       ierr   = PetscFree(amspub.next->man);
151:       if (amspub.next->data)  {PetscFree(amspub.next->data);}
152:       if (amspub.next->edata) {PetscFree(amspub.next->edata);}
153:       last        = amspub.next;
154:       amspub.next = amspub.next->next;
155:       ierr        = PetscFree(last);
156:     }
157:     AMS_Memory_grant_access(amspub.amem);
158:     AMS_Memory_destroy(amspub.amem);
159:   }
160: #endif
161:   PetscStrfree(amspub.title); amspub.title  = 0;
162:   PetscStrfree(amspub.prefix); amspub.prefix = 0;
163:   return(0);
164: }

166: #if defined(PETSC_HAVE_AMS)
167: /*
168:      Publishes the "lock" for an option; with a name that is the command line
169:    option name. This is the first item that is always published for an option
170: */
171: static int PetscOptionsCreate_Private(char *opt,char *text,char *man,PetscOptionsAMS *amsopt)
172: {
173:   int             ierr;
174:   static int      mancount = 0;
175:   PetscOptionsAMS next;
176:   char            manname[16];

179:   ierr             = PetscNew(struct _p_OptionsAMS,amsopt);
180:   (*amsopt)->next  = 0;
181:   (*amsopt)->set   = PETSC_FALSE;
182:   (*amsopt)->data  = 0;
183:   (*amsopt)->edata = 0;
184:   ierr             = PetscStrallocpy(text,&(*amsopt)->text);
185:   ierr             = PetscStrallocpy(opt,&(*amsopt)->option);
186:   AMS_Memory_add_field(amspub.amem,opt,&(*amsopt)->set,1,AMS_INT,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
187:   sprintf(manname,"man_%d",mancount++);
188:   ierr                     = PetscMalloc(sizeof(char*),&(*amsopt)->man);
189:   *(char **)(*amsopt)->man = man;
190:   AMS_Memory_add_field(amspub.amem,manname,(*amsopt)->man,1,AMS_STRING,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);

192:   if (!amspub.next) {
193:     amspub.next = *amsopt;
194:   } else {
195:     next = amspub.next;
196:     while (next->next) next = next->next;
197:     next->next = *amsopt;
198:   }
199:   return(0);
200: }
201: #endif

203: /* -------------------------------------------------------------------------------------------------------------*/
204: /*
205:      Publishes an AMS int field (with the default value in it) and with a name
206:    given by the text string
207: */
208: int PetscOptionsInt(char *opt,char *text,char *man,int defaultv,int *value,PetscTruth *set)
209: {
210:   int             ierr;

213: #if defined(PETSC_HAVE_AMS)
214:   if (!PetscOptionsPublishCount) {
215:     PetscOptionsAMS amsopt;
216:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
217:     amsopt->type        = OPTION_INT;
218:     PetscMalloc(sizeof(int),&amsopt->data);
219:     *(int*)amsopt->data = defaultv;
220:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,1,AMS_INT,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
221:     if (set) *set = PETSC_FALSE;
222:     return(0);
223:   }
224: #endif
225:   PetscOptionsGetInt(amspub.prefix,opt,value,set);
226:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
227:     (*PetscHelpPrintf)(amspub.comm,"  -%s%s <%d>: %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,defaultv,text,man);
228:   }
229:   return(0);
230: }

232: int PetscOptionsString(char *opt,char *text,char *man,char *defaultv,char *value,int len,PetscTruth *set)
233: {
234:   int             ierr;

237: #if defined(PETSC_HAVE_AMS)
238:   if (!PetscOptionsPublishCount) {
239:     PetscOptionsAMS amsopt;
240:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
241:     amsopt->type          = OPTION_STRING;
242:     PetscMalloc(sizeof(char*),&amsopt->data);
243:     *(char**)amsopt->data = defaultv;
244:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,1,AMS_STRING,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
245:     if (set) *set = PETSC_FALSE;
246:     return(0);
247:   }
248: #endif
249:   PetscOptionsGetString(amspub.prefix,opt,value,len,set);
250:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
251:     (*PetscHelpPrintf)(amspub.comm,"  -%s%s <%s>: %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,defaultv,text,man);
252:   }
253:   return(0);
254: }

256: /*
257:      Publishes an AMS double field (with the default value in it) and with a name
258:    given by the text string
259: */
260: int PetscOptionsDouble(char *opt,char *text,char *man,double defaultv,double *value,PetscTruth *set)
261: {
262:   int             ierr;

265: #if defined(PETSC_HAVE_AMS)
266:   if (!PetscOptionsPublishCount) {
267:     PetscOptionsAMS amsopt;
268:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
269:     amsopt->type           = OPTION_DOUBLE;
270:     PetscMalloc(sizeof(double),&amsopt->data);
271:     *(double*)amsopt->data = defaultv;
272:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,1,AMS_DOUBLE,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
273:     if (set) *set = PETSC_FALSE;
274:     return(0);
275:   }
276: #endif
277:   PetscOptionsGetDouble(amspub.prefix,opt,value,set);
278:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
279:     (*PetscHelpPrintf)(amspub.comm,"  -%s%s <%g>: %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,defaultv,text,man);
280:   }
281:   return(0);
282: }

284: int PetscOptionsScalar(char *opt,char *text,char *man,Scalar defaultv,Scalar *value,PetscTruth *set)
285: {

289: #if !defined(PETSC_USE_COMPLEX)
290:   PetscOptionsDouble(opt,text,man,defaultv,value,set);
291: #else
292:   PetscOptionsGetScalar(amspub.prefix,opt,value,set);
293: #endif
294:   return(0);
295: }

297: /*
298:      Publishes an AMS logical field (with the default value in it) and with a name
299:    given by the text string
300: */
301: int PetscOptionsName(char *opt,char *text,char *man,PetscTruth *flg)
302: {
303:   int             ierr;

306: #if defined(PETSC_HAVE_AMS)
307:   if (!PetscOptionsPublishCount) {
308:     PetscOptionsAMS amsopt;
309:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
310:     amsopt->type        = OPTION_LOGICAL;
311:     PetscMalloc(sizeof(int),&amsopt->data);
312:     *(int*)amsopt->data = 0;
313:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,1,AMS_BOOLEAN,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
314:     if (flg) *flg = PETSC_FALSE;
315:     return(0);
316:   }
317: #endif
318:   PetscOptionsHasName(amspub.prefix,opt,flg);
319:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
320:     (*PetscHelpPrintf)(amspub.comm,"  -%s%s: %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,text,man);
321:   }

323:   return(0);
324: }

326: /*
327:      Publishes a single string (the default) with a name given by the DEFAULT: + text
328:   and an AMS array of strings which are to be ed from with a name given by the text

330: */
331: int PetscOptionsList(char *opt,char *ltext,char *man,PetscFList list,char *defaultv,char *value,int len,PetscTruth *set)
332: {
333:   int        ierr;
334: #if defined(PETSC_HAVE_AMS)
335:   PetscFList next = list;
336: #endif

339: #if defined(PETSC_HAVE_AMS)
340:   if (!PetscOptionsPublishCount) {
341:     PetscOptionsAMS amsopt;
342:     int        ntext,i;
343:     char       ldefault[128],**vtext;

345:     PetscOptionsCreate_Private(opt,ltext,man,&amsopt);
346:     amsopt->type             = OPTION_LIST;
347:     PetscMalloc(sizeof(char*),&amsopt->data);
348:     *(char **)(amsopt->data) = defaultv;
349:     PetscStrcpy(ldefault,"DEFAULT:");
350:     PetscStrcat(ldefault,ltext);
351:     AMS_Memory_add_field(amspub.amem,ldefault,amsopt->data,1,AMS_STRING,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);

353:     PetscFListGet(list,(char***)&amsopt->edata,&ntext);
354:     AMS_Memory_add_field(amspub.amem,ltext,amsopt->edata,ntext,AMS_STRING,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
355:     if (set) *set = PETSC_FALSE;
356:     return(0);
357:   }
358: #endif
359:   PetscOptionsGetString(amspub.prefix,opt,value,len,set);
360:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
361:     PetscFListPrintTypes(amspub.comm,stdout,amspub.prefix,opt,ltext,man,list);
362:   }

364:   return(0);
365: }

367: /*
368:      Publishes a single string (the default) with a name given by the DEFAULT: + text
369:   and an AMS array of strings which are to be ed from with a name given by the text

371: */
372: int PetscOptionsEList(char *opt,char *ltext,char *man,char **list,int ntext,char *defaultv,char *value,int len,PetscTruth *set)
373: {
374:   int i,ierr;

377: #if defined(PETSC_HAVE_AMS)
378:   if (!PetscOptionsPublishCount) {
379:     PetscOptionsAMS amsopt;
380:     char       ldefault[128],**vtext;

382:     PetscOptionsCreate_Private(opt,ltext,man,&amsopt);
383:     amsopt->type             = OPTION_LIST;
384:     PetscMalloc(sizeof(char*),&amsopt->data);
385:     *(char **)(amsopt->data) = defaultv;
386:     PetscStrcpy(ldefault,"DEFAULT:");
387:     PetscStrcat(ldefault,ltext);
388:     AMS_Memory_add_field(amspub.amem,ldefault,amsopt->data,1,AMS_STRING,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);

390:     PetscMalloc((ntext+1)*sizeof(char**),&amsopt->edata);
391:     PetscMemcpy(amsopt->edata,list,ntext*sizeof(char*));
392:     AMS_Memory_add_field(amspub.amem,ltext,amsopt->edata,ntext,AMS_STRING,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
393:     if (set) *set = PETSC_FALSE;
394:     return(0);
395:   }
396: #endif
397:   PetscOptionsGetString(amspub.prefix,opt,value,len,set);
398:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
399:     (*PetscHelpPrintf)(amspub.comm,"  -%s%s <%s> (one of)",amspub.prefix?amspub.prefix:"",opt+1,defaultv);
400:     for (i=0; i<ntext; i++){
401:       (*PetscHelpPrintf)(amspub.comm," %s",list[i]);
402:     }
403:     (*PetscHelpPrintf)(amspub.comm,"n");
404:   }

406:   return(0);
407: }

409: /*
410:      Publishes an AMS logical field, only one in a group can be on
411: */
412: int PetscOptionsLogicalGroupBegin(char *opt,char *text,char *man,PetscTruth *flg)
413: {
414:   int             ierr;

417: #if defined(PETSC_HAVE_AMS)
418:   if (!PetscOptionsPublishCount) {
419:     PetscOptionsAMS amsopt;
420:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
421:     amsopt->type        = OPTION_LOGICAL;
422:     PetscMalloc(sizeof(int),&amsopt->data);
423:     *(int*)amsopt->data = 1; /* the first one listed is always the default */
424:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,1,AMS_BOOLEAN,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
425:     if (flg) *flg = PETSC_FALSE;
426:     return(0);
427:   }
428: #endif
429:   PetscOptionsHasName(amspub.prefix,opt,flg);
430:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
431:     (*PetscHelpPrintf)(amspub.comm,"  Pick at most one of -------------n");
432:     (*PetscHelpPrintf)(amspub.comm,"    -%s%s: %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,text,man);
433:   }

435:   return(0);
436: }

438: int PetscOptionsLogicalGroup(char *opt,char *text,char *man,PetscTruth *flg)
439: {
440:   int             ierr;

443: #if defined(PETSC_HAVE_AMS)
444:   if (!PetscOptionsPublishCount) {
445:     PetscOptionsAMS amsopt;
446:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
447:     amsopt->type        = OPTION_LOGICAL;
448:     PetscMalloc(sizeof(int),&amsopt->data);
449:     *(int*)amsopt->data = 0;
450:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,1,AMS_BOOLEAN,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
451:     if (flg) *flg = PETSC_FALSE;
452:     return(0);
453:   }
454: #endif
455:   PetscOptionsHasName(amspub.prefix,opt,flg);
456:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
457:     (*PetscHelpPrintf)(amspub.comm,"    -%s%s: %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,text,man);
458:   }

460:   return(0);
461: }

463: int PetscOptionsLogicalGroupEnd(char *opt,char *text,char *man,PetscTruth *flg)
464: {
465:   int             ierr;

468: #if defined(PETSC_HAVE_AMS)
469:   if (!PetscOptionsPublishCount) {
470:     PetscOptionsAMS amsopt;
471:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
472:     amsopt->type        = OPTION_LOGICAL;
473:     PetscMalloc(sizeof(int),&amsopt->data);
474:     *(int*)amsopt->data = 0;
475:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,1,AMS_BOOLEAN,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
476:     if (flg) *flg = PETSC_FALSE;
477:     return(0);
478:   }
479: #endif
480:   PetscOptionsHasName(amspub.prefix,opt,flg);
481:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
482:     (*PetscHelpPrintf)(amspub.comm,"    -%s%s: %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,text,man);
483:   }

485:   return(0);
486: }

488: int PetscOptionsLogical(char *opt,char *text,char *man,PetscTruth deflt,PetscTruth *flg,PetscTruth *set)
489: {
490:   int             ierr;

493: #if defined(PETSC_HAVE_AMS)
494:   if (!PetscOptionsPublishCount) {
495:     PetscOptionsAMS amsopt;
496:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
497:     amsopt->type        = OPTION_LOGICAL;
498:     PetscMalloc(sizeof(int),&amsopt->data);
499:     *(int*)amsopt->data = (int)deflt;
500:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,1,AMS_BOOLEAN,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
501:     if (flg) *flg = PETSC_FALSE;
502:     return(0);
503:   }
504: #endif
505:   PetscOptionsGetLogical(amspub.prefix,opt,flg,set);
506:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
507:     const char *v = (deflt ? "true" : "false");
508:     (*PetscHelpPrintf)(amspub.comm,"    -%s%s: <%s> %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,v,text,man);
509:   }

511:   return(0);
512: }

514: /*
515:      Publishes an AMS double field (with the default value in it) and with a name
516:    given by the text string
517: */
518: int PetscOptionsDoubleArray(char *opt,char *text,char *man,double *value,int *n,PetscTruth *set)
519: {
520:   int             ierr,i;

523: #if defined(PETSC_HAVE_AMS)
524:   if (!PetscOptionsPublishCount) {
525:     PetscOptionsAMS amsopt;
526:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
527:     amsopt->type           = OPTION_DOUBLE_ARRAY;
528:     amsopt->arraylength    = *n;
529:     PetscMalloc((*n)*sizeof(double),&amsopt->data);
530:     ierr                   = PetscMemcpy(amsopt->data,value,(*n)*sizeof(double));
531:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,*n,AMS_DOUBLE,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
532:     if (set) *set = PETSC_FALSE;
533:     return(0);
534:   }
535: #endif
536:   PetscOptionsGetDoubleArray(amspub.prefix,opt,value,n,set);
537:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
538:     (*PetscHelpPrintf)(amspub.comm,"  -%s%s <%g",amspub.prefix?amspub.prefix:"",opt+1,value[0]);
539:     for (i=1; i<*n; i++) {
540:       (*PetscHelpPrintf)(amspub.comm,",%g",value[i]);
541:     }
542:     (*PetscHelpPrintf)(amspub.comm,">: %s (%s)n",text,man);
543:   }
544:   return(0);
545: }

547: int PetscOptionsStringArray(char *opt,char *text,char *man,char **value,int *nmax,PetscTruth *set)
548: {
549:   int             ierr;

552: #if defined(PETSC_HAVE_AMS)
553:   if (!PetscOptionsPublishCount) {
554:     PetscOptionsAMS amsopt;
555:     PetscOptionsCreate_Private(opt,text,man,&amsopt);
556:     amsopt->type          = OPTION_STRING;
557:     PetscMalloc((*nmax)*sizeof(char*),&amsopt->data);
558:     ierr                  = PetscMemzero(amsopt->data,(*nmax)*sizeof(char*));
559:     AMS_Memory_add_field(amspub.amem,text,amsopt->data,*nmax,AMS_STRING,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
560:     if (set) *set = PETSC_FALSE;
561:     return(0);
562:   }
563: #endif
564:   PetscOptionsGetStringArray(amspub.prefix,opt,value,nmax,set);
565:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
566:     (*PetscHelpPrintf)(amspub.comm,"  -%s%s <string1,string2,...>: %s (%s)n",amspub.prefix?amspub.prefix:"",opt+1,text,man);
567:   }
568:   return(0);
569: }

571: /*
572:     Put a subheading into the GUI list of PetscOptions
573: */
574: int PetscOptionsHead(char *head)
575: {
576:   int             ierr;

579: #if defined(PETSC_HAVE_AMS)
580:   if (!PetscOptionsPublishCount) {
581:     PetscOptionsAMS amsopt;
582:     PetscOptionsCreate_Private("-amshead",head,"None",&amsopt);
583:     amsopt->type = OPTION_HEAD;
584:     PetscMalloc(sizeof(int),&amsopt->data);
585:     *(int*)amsopt->data = 0;
586:     AMS_Memory_add_field(amspub.amem,head,amsopt->data,1,AMS_BOOLEAN,AMS_WRITE,AMS_COMMON,AMS_REDUCT_UNDEF);
587:   }
588: #endif
589:   if (amspub.printhelp && PetscOptionsPublishCount == 1) {
590:     (*PetscHelpPrintf)(amspub.comm,"  %sn",head);
591:   }

593:   return(0);
594: }