Actual source code: aoptions.c

  1: /*$Id: aoptions.c,v 1.27 2001/03/23 23:20:42 balay Exp $*/
  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"        /*I  "petsc.h"   I*/
 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;

335: #if defined(PETSC_HAVE_AMS)
336:   PetscFList next = list;
337: #endif

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

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

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

365:   return(0);
366: }

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

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

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

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

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

407:   return(0);
408: }

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

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

436:   return(0);
437: }

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

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

461:   return(0);
462: }

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

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

486:   return(0);
487: }

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

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

512:   return(0);
513: }

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

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

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

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

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

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

594:   return(0);
595: }