예제 #1
0
void parse_common_args(int *argc,char *argv[],unsigned long Flags,
		       int nfile,t_filenm fnm[],int npargs,t_pargs *pa,
		       int ndesc,char **desc,int nbugs,char **bugs)
{
  static bool bHelp=FALSE,bHidden=FALSE,bQuiet=FALSE;
  static char *manstr[]      = { NULL, "no", "html", "tex", "nroff", "ascii", "completion", "py", "xml", "wiki", NULL };
  static int  nicelevel=0,mantp=0,npri=0,debug_level=0;
  static char *deffnm=NULL;
  static real tbegin=0,tend=0,tdelta=0;
       
  t_pargs *all_pa=NULL;
  
  t_pargs npri_pa   = { "-npri", FALSE, etINT,   {&npri},
		       "HIDDEN Set non blocking priority (try 128)" };
  t_pargs nice_pa   = { "-nice", FALSE, etINT,   {&nicelevel}, 
		       "Set the nicelevel" };
  t_pargs deffnm_pa = { "-deffnm", FALSE, etSTR, {&deffnm}, 
		       "Set the default filename for all file options" };
  t_pargs begin_pa  = { "-b",    FALSE, etTIME,  {&tbegin},        
		       "First frame (%t) to read from trajectory" };
  t_pargs end_pa    = { "-e",    FALSE, etTIME,  {&tend},        
		       "Last frame (%t) to read from trajectory" };
  t_pargs dt_pa     = { "-dt",   FALSE, etTIME,  {&tdelta},        
		       "Only use frame when t MOD dt = first time (%t)" };
  t_pargs view_pa   = { "-w",    FALSE, etBOOL,  {&bView},
		       "View output xvg, xpm, eps and pdb files" };
  t_pargs code_pa   = { "-xvgr", FALSE, etBOOL,  {&bXvgrCodes},
		       "Add specific codes (legends etc.) in the output xvg files for the xmgrace program" };
  t_pargs time_pa   = { "-tu",   FALSE, etENUM,  {timestr},
			"Time unit" };
  /* Maximum number of extra arguments */
#define EXTRA_PA 16

  t_pargs pca_pa[] = {
    { "-h",    FALSE, etBOOL, {&bHelp},     
      "Print help info and quit" }, 
    { "-hidden", FALSE, etBOOL, {&bHidden},
      "HIDDENPrint hidden options" },
    { "-quiet",FALSE, etBOOL, {&bQuiet},
      "HIDDENDo not print help info" },
    { "-man",  FALSE, etENUM,  {manstr},
      "HIDDENWrite manual and quit" },
    { "-debug",FALSE, etINT, {&debug_level},
      "HIDDENWrite file with debug information, 1: short, 2: also x and f" },
  };
#define NPCA_PA asize(pca_pa)
  FILE *fp;  
  bool bPrint,bExit,bXvgr;
  int  i,j,k,npall,max_pa,cmdlength;
  char *ptr,*newdesc;
  char *envstr;

#define FF(arg) ((Flags & arg)==arg)

  cmdlength = strlen(argv[0]);
  /* Check for double arguments */
  for (i=1; (i<*argc); i++) {
    cmdlength += strlen(argv[i]);
    if (argv[i] && (strlen(argv[i]) > 1) && (!isdigit(argv[i][1]))) {
      for (j=i+1; (j<*argc); j++) {
	if ( (argv[i][0]=='-') && (argv[j][0]=='-') && 
	     (strcmp(argv[i],argv[j])==0) ) {
	  if (FF(PCA_NOEXIT_ON_ARGS))
	    fprintf(stderr,"Double command line argument %s\n",argv[i]);
	  else
	    gmx_fatal(FARGS,"Double command line argument %s\n",argv[i]);
	}
      }
    }
  }
  debug_gmx();

  /* Fill the cmdline string */
  snew(cmdline,cmdlength+*argc+1);
  for (i=0; (i<*argc); i++) {
    strcat(cmdline,argv[i]);
    strcat(cmdline," ");
  }
  
  /* Handle the flags argument, which is a bit field 
   * The FF macro returns whether or not the bit is set
   */
  bPrint        = !FF(PCA_SILENT);
  
  set_program_name(argv[0]);

  /* Check ALL the flags ... */
  max_pa = NPCA_PA + EXTRA_PA + npargs;
  snew(all_pa,max_pa);
  
  for(i=npall=0; (i<NPCA_PA); i++)
    npall = add_parg(npall,all_pa,&(pca_pa[i]));

#ifdef __sgi
  envstr = getenv("GMXNPRIALL");
  if (envstr)
    npri=atoi(envstr);
  if (FF(PCA_BE_NICE)) {
    envstr = getenv("GMXNPRI");
    if (envstr)
      npri=atoi(envstr);
  }
  npall = add_parg(npall,all_pa,&npri_pa);
#endif

  if (FF(PCA_BE_NICE)) 
    nicelevel=19;
  npall = add_parg(npall,all_pa,&nice_pa);

  if (FF(PCA_CAN_SET_DEFFNM)) 
    npall = add_parg(npall,all_pa,&deffnm_pa);   
  if (FF(PCA_CAN_BEGIN)) 
    npall = add_parg(npall,all_pa,&begin_pa);
  if (FF(PCA_CAN_END))
    npall = add_parg(npall,all_pa,&end_pa);
  if (FF(PCA_CAN_DT))
    npall = add_parg(npall,all_pa,&dt_pa);
  if (FF(PCA_TIME_UNIT)) {
    envstr = getenv("GMXTIMEUNIT");
    if ( envstr == NULL )
      envstr="ps";
    set_default_time_unit(envstr);
    npall = add_parg(npall,all_pa,&time_pa);
  } else
    set_default_time_unit("ps");
  if (FF(PCA_CAN_VIEW)) 
    npall = add_parg(npall,all_pa,&view_pa);
    
  bXvgr = FALSE;
  for(i=0; (i<nfile); i++)
    bXvgr = bXvgr ||  (fnm[i].ftp == efXVG);
  if (bXvgr)
    npall = add_parg(npall,all_pa,&code_pa);
  
  /* Now append the program specific arguments */
  for(i=0; (i<npargs); i++)
    npall = add_parg(npall,all_pa,&(pa[i]));

  /* set etENUM options to default */
  for(i=0; (i<npall); i++)
    if (all_pa[i].type==etENUM)
      all_pa[i].u.c[0]=all_pa[i].u.c[1];
  
  /* Now parse all the command-line options */
  get_pargs(argc,argv,npall,all_pa,FF(PCA_KEEP_ARGS));

  if (FF(PCA_CAN_SET_DEFFNM) && (deffnm!=NULL))
    set_default_file_name(deffnm);

  /* Parse the file args */
  parse_file_args(argc,argv,nfile,fnm,FF(PCA_KEEP_ARGS));

  /* Open the debug file */
  if (debug_level > 0) {
    char buf[256];

    if (gmx_mpi_initialized())
      sprintf(buf,"%s%d.log",ShortProgram(),gmx_node_rank());
    else
      sprintf(buf,"%s.log",ShortProgram());
      
    init_debug(debug_level,buf);
    fprintf(stderr,"Opening debug file %s (src code file %s, line %d)\n",
	    buf,__FILE__,__LINE__);
  }

  /* Now copy the results back... */
  for(i=0,k=npall-npargs; (i<npargs); i++,k++) 
    memcpy(&(pa[i]),&(all_pa[k]),(size_t)sizeof(pa[i]));
  
  for(i=0; (i<npall); i++)
    all_pa[i].desc = mk_desc(&(all_pa[i]), time_unit() );

  bExit = bHelp || (strcmp(manstr[0],"no") != 0);

#if (defined __sgi && USE_SGI_FPE)
  doexceptions();
#endif

  /* Set the nice level */
#ifdef __sgi
  if (npri != 0 && !bExit) {
    schedctl(MPTS_RTPRI,0,npri);
  }
#endif 

#ifdef HAVE_UNISTD_H

#ifndef GMX_NO_NICE
  /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */
  if (nicelevel != 0 && !bExit)
    i=nice(nicelevel); /* assign ret value to avoid warnings */
#endif

#endif
  
  if (!(FF(PCA_QUIET) || bQuiet )) {
    if (bHelp)
      write_man(stderr,"help",program,ndesc,desc,nfile,fnm,npall,all_pa,
		nbugs,bugs,bHidden);
    else if (bPrint) {
      pr_fns(stderr,nfile,fnm);
      print_pargs(stderr,npall,all_pa,FALSE);
    }
  }

  if (strcmp(manstr[0],"no") != 0) {
    if(!strcmp(manstr[0],"completion")) {
      /* one file each for csh, bash and zsh if we do completions */
      fp=man_file(program,"completion-zsh");
      write_man(fp,"completion-zsh",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      gmx_fio_fclose(fp);
      fp=man_file(program,"completion-bash");
      write_man(fp,"completion-bash",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      gmx_fio_fclose(fp);
      fp=man_file(program,"completion-csh");
      write_man(fp,"completion-csh",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      gmx_fio_fclose(fp);
    } else {
      fp=man_file(program,manstr[0]);
      write_man(fp,manstr[0],program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      gmx_fio_fclose(fp);
    }
  }
  
  /* convert time options, must be done after printing! */
  init_time_factor();
  for(i=0; i<npall; i++) {
    if ((all_pa[i].type == etTIME) && (*all_pa[i].u.r >= 0)) {
      *all_pa[i].u.r *= timeinvfac;
    }
  }

  /* Extract Time info from arguments */
  if (FF(PCA_CAN_BEGIN) && opt2parg_bSet("-b",npall,all_pa))
    setTimeValue(TBEGIN,opt2parg_real("-b",npall,all_pa));

  if (FF(PCA_CAN_END) && opt2parg_bSet("-e",npall,all_pa))
    setTimeValue(TEND,opt2parg_real("-e",npall,all_pa));
  
  if (FF(PCA_CAN_DT) && opt2parg_bSet("-dt",npall,all_pa))
    setTimeValue(TDELTA,opt2parg_real("-dt",npall,all_pa));
  
  /* clear memory */
  sfree(all_pa);
  
  if (!FF(PCA_NOEXIT_ON_ARGS)) {
    if (*argc > 1) {
      gmx_cmd(argv[1]);
    }
  } 
  if (bExit) {
    if (gmx_parallel_env)
      gmx_abort(gmx_node_rank(),gmx_node_num(),0);
    else
      exit(0);
  }
#undef FF
}
예제 #2
0
void parse_common_args(int *argc,char *argv[],unsigned long Flags,
		       int nfile,t_filenm fnm[],int npargs,t_pargs *pa,
		       int ndesc,char **desc,int nbugs,char **bugs)
{
  static bool bHelp=FALSE,bHidden=FALSE,bQuiet=FALSE;
  static char *manstr[]      = { NULL, "no", "html", "tex", "nroff", "ascii", "completion", NULL };
  static char *not_nicestr[] = { NULL, "0", "4", "10", "19", NULL };
  static char *nicestr[]     = { NULL, "19", "10", "4", "0", NULL };
  static char *not_npristr[] = { NULL, "0", "128", "100", "200", "250", NULL };
  static char *npristr[]     = { NULL, "128", "250", "200", "100", "0", NULL };
  static int  nicelevel=0,mantp=0,npri=0;
  static bool bGUI=FALSE,bDebug=FALSE;
  static char *deffnm=NULL;
     
  FILE *fp;  
  bool bPrint,bExit;
  int  i,j,k,npall;
  char *ptr,*newdesc;
  char *envstr;

  t_pargs *all_pa=NULL;
  
  t_pargs motif_pa  = { "-X",    FALSE, etBOOL,  {&bGUI},
		       "Use dialog box GUI to edit command line options" };
  t_pargs npri_paX  = { "-npri", FALSE, etENUM,  {not_npristr},
		       "Set non blocking priority" };
  t_pargs npri_pa   = { "-npri", FALSE, etINT,   {&npri},
		       "HIDDEN Set non blocking priority (try 128)" };
  t_pargs nice_paX  = { "-nice", FALSE, etENUM,  {not_nicestr}, 
		       "Set the nicelevel" };
  t_pargs nice_pa   = { "-nice", FALSE, etINT,   {&nicelevel}, 
		       "Set the nicelevel" };
  t_pargs deffnm_pa = { "-deffnm", FALSE, etSTR, {&deffnm}, 
		       "Set the default filename for all file options" };
  t_pargs begin_pa  = { "-b",    FALSE, etTIME,  {&tbegin},        
		       "First frame (%t) to read from trajectory" };
  t_pargs end_pa    = { "-e",    FALSE, etTIME,  {&tend},        
		       "Last frame (%t) to read from trajectory" };
  t_pargs dt_pa     = { "-dt",   FALSE, etTIME,  {&tdelta},        
		       "Only use frame when t MOD dt = first time (%t)" };
  t_pargs view_pa   = { "-w",    FALSE, etBOOL,  {&bView},     
		       "View output xvg, xpm, eps and pdb files" };
  t_pargs time_pa   = { "-tu",   FALSE, etENUM,  {timestr},
			"Time unit" };
  
  t_pargs pca_pa[] = {
    { "-h",    FALSE, etBOOL, {&bHelp},     
      "Print help info and quit" }, 
    { "-hidden", FALSE, etBOOL, {&bHidden},
      "HIDDENPrint hidden options" },
    { "-quiet",FALSE, etBOOL, {&bQuiet},
      "HIDDENDo not print help info" },
    { "-man",  FALSE, etENUM,  {manstr},
      "HIDDENWrite manual and quit" },
    { "-debug",FALSE, etBOOL, {&bDebug},
      "HIDDENWrite file with debug information" },
  };
#define NPCA_PA asize(pca_pa)

  debug_gmx();
  if (debug) {
    fprintf(debug,"PID=%d, argc = %d\n",gmx_node_id(),*argc);
    for(i=0; (i<*argc); i++)
      fprintf(debug,"PID=%d, argv[%d] = %s\n",gmx_node_id(),i,argv[i]);
  }

  /* Check for double arguments */
  for (i=1; (i<*argc); i++) {
    if (argv[i] && (strlen(argv[i]) > 1) && (!isdigit(argv[i][1]))) {
      for (j=i+1; (j<*argc); j++) {
	if ( (argv[i][0]=='-') && (argv[j][0]=='-') && 
	     (strcmp(argv[i],argv[j])==0) ) {
	  if (FF(PCA_NOEXIT_ON_ARGS))
	    fprintf(stderr,"Double command line argument %s\n",argv[i]);
	  else
	    fatal_error(0,"Double command line argument %s\n",argv[i]);
	}
      }
    }
  }
  debug_gmx();

  /* Handle the flags argument, which is a bit field 
   * The FF macro returns whether or not the bit is set
   */
  uFlags        = Flags;
  bPrint        = !FF(PCA_SILENT);
  
  /* Check whether we should have GUI or not */
#ifdef HAVE_MOTIF
  bGUI = (getenv("GMXMOTIF") != NULL);
  for(i=1; (i<*argc); i++) {
    if (strcmp(argv[i],"-X") == 0)
      bGUI = TRUE;
    else if (strcmp(argv[i],"-noX") == 0)
      bGUI = FALSE;
  }
  if (bGUI)
    bQuiet = TRUE;
#else
  bGUI = FALSE;
#endif

  set_program_name(argv[0]);

  /* Check ALL the flags ... */
  snew(all_pa,NPCA_PA+npargs);
  for(i=npall=0; (i<NPCA_PA); i++)
    npall = add_parg(npall,&(all_pa),&(pca_pa[i]));

  /* Motif options */
  npall = add_parg(npall,&(all_pa),&motif_pa);

#if (defined __sgi && !defined SPEC_CPU) 
  envstr = getenv("GMXNPRIALL");
  if (envstr)
    npri=atoi(envstr);
  if (FF(PCA_BE_NICE)) {
    envstr = getenv("GMXNPRI");
    if (envstr)
      npri=atoi(envstr);
  }
  if (bGUI) {
    if (npri)
      npri_paX.u.c = npristr;
    npall = add_parg(npall,&(all_pa),&npri_paX);
  }
  else
    npall = add_parg(npall,&(all_pa),&npri_pa);
#endif

  if (bGUI) {
    /* Automatic nice or scheduling options */
    if (FF(PCA_BE_NICE)) 
      nice_paX.u.c = nicestr;
    npall = add_parg(npall,&(all_pa),&nice_paX);
  }
  else {
    if (FF(PCA_BE_NICE)) 
      nicelevel=19;
    npall = add_parg(npall,&(all_pa),&nice_pa);
  }

  if (FF(PCA_CAN_SET_DEFFNM)) 
    npall = add_parg(npall,&(all_pa),&deffnm_pa);   
  if (FF(PCA_CAN_BEGIN)) 
    npall = add_parg(npall,&(all_pa),&begin_pa);
  if (FF(PCA_CAN_END))
    npall = add_parg(npall,&(all_pa),&end_pa);
  if (FF(PCA_CAN_DT))
    npall = add_parg(npall,&(all_pa),&dt_pa);
#ifndef SPEC_CPU
  if (FF(PCA_TIME_UNIT)) {
    envstr = getenv("GMXTIMEUNIT");
    if ( envstr == NULL )
      envstr="ps";
    set_default_time_unit(envstr);
    npall = add_parg(npall,&(all_pa),&time_pa);
  } else
#endif
    set_default_time_unit("ps");
  if (FF(PCA_CAN_VIEW))
    npall = add_parg(npall,&(all_pa),&view_pa);

  /* Now append the program specific arguments */
  for(i=0; (i<npargs); i++)
    npall = add_parg(npall,&(all_pa),&(pa[i]));

  /* set etENUM options to default */
  for(i=0; (i<npall); i++)
    if (all_pa[i].type==etENUM)
      all_pa[i].u.c[0]=all_pa[i].u.c[1];
  
  /* Now parse all the command-line options */
  get_pargs(argc,argv,npall,all_pa,FF(PCA_KEEP_ARGS));

  if (FF(PCA_CAN_SET_DEFFNM) && (deffnm!=NULL))
    set_default_file_name(deffnm);

  /* Parse the file args */
  parse_file_args(argc,argv,nfile,fnm,FF(PCA_KEEP_ARGS));

  /* Open the debug file */
  if (bDebug) {
    char buf[256];

    if (gmx_node_num() > 1)
      sprintf(buf,"%s%d.log",ShortProgram(),gmx_node_id());
    else
      sprintf(buf,"%s.log",ShortProgram());
      
    init_debug(buf);
    fprintf(debug,"%s (this file) opened in file %s, line %d\n",
	    buf,__FILE__,__LINE__);
  }

  /* Now we have parsed the command line arguments. If the user wants it
   * we can now plop up a GUI dialog box to edit options.
   */
  if (bGUI) {
#ifdef HAVE_MOTIF
    gmx_gui(argc,argv,nfile,fnm,npall,all_pa,ndesc,desc,nbugs,bugs);
#else
    fatal_error(0,"GROMACS compiled without MOTIF support - can't use X interface");
#endif
  }

  /* Now copy the results back... */
  for(i=0,k=npall-npargs; (i<npargs); i++,k++) 
    memcpy(&(pa[i]),&(all_pa[k]),(size_t)sizeof(pa[i]));
  
  for(i=0; (i<npall); i++)
    all_pa[i].desc = mk_desc(&(all_pa[i]), time_unit() );

  bExit = bHelp || (strcmp(manstr[0],"no") != 0);

#if (defined __sgi && USE_SGI_FPE)
  doexceptions();
#endif

  /* Set the nice level */
#ifdef __sgi
  if (bGUI)
    if (npri)
      sscanf(npristr[0],"%d",&npri);
    else
      sscanf(not_npristr[0],"%d",&npri);
  if (npri != 0 && !bExit) {
    (void) schedctl(MPTS_RTPRI,0,npri);
  }
  else
#endif 

#ifdef HAVE_UNISTD_H
    if (bGUI) {
      if (FF(PCA_BE_NICE))
	sscanf(nicestr[0],"%d",&nicelevel);
      else
	sscanf(not_nicestr[0],"%d",&nicelevel);
    }
  if (nicelevel != 0 && !bExit)
    nice(nicelevel);
#endif

  if (!(FF(PCA_QUIET) || bQuiet )) {
    if (bHelp)
      write_man(stderr,"help",program,ndesc,desc,nfile,fnm,npall,all_pa,
		nbugs,bugs,bHidden);
    else if (bPrint) {
      pr_fns(stderr,nfile,fnm);
      print_pargs(stderr,npall,all_pa);
    }
  }
  
  if (strcmp(manstr[0],"no") != 0) {
    if(!strcmp(manstr[0],"completion")) {
      /* one file each for csh, bash and zsh if we do completions */
      fp=man_file(program,"completion-zsh");
      write_man(fp,"completion-zsh",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      fclose(fp);
      fp=man_file(program,"completion-bash");
      write_man(fp,"completion-bash",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      fclose(fp);
      fp=man_file(program,"completion-csh");
      write_man(fp,"completion-csh",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      fclose(fp);
    } else {
      fp=man_file(program,manstr[0]);
      write_man(fp,manstr[0],program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      fclose(fp);
    }
  }
    
  /* convert time options, must be done after printing! */
  init_time_factor();
  for(i=0; i<npall; i++) {
    if ((all_pa[i].type == etTIME) && (*all_pa[i].u.r >= 0)) {
      *all_pa[i].u.r /= timefactor;
    }
  }
  
  /* clear memory */
  for(i=0; i<npall; i++)
    sfree(all_pa[i].desc);
  sfree(all_pa);
    
  if (!FF(PCA_NOEXIT_ON_ARGS)) {
    if (*argc > 1) {
      for(i=1; (i<*argc); i++) 
	fprintf(stderr,"Unknown argument: %s\n",argv[i]);
      fatal_error(0,"Program %s halted",Program());
    }
  } 
  if (bExit) {
#ifdef USE_MPI
    if (gmx_parallel)
      gmx_abort(gmx_node_id(),gmx_node_num(),0);
#endif
    exit(0);
  }
}
예제 #3
0
void parse_common_args(int *argc,char *argv[],unsigned long Flags,
		       int nfile,t_filenm fnm[],int npargs,t_pargs *pa,
		       int ndesc,const char **desc,
		       int nbugs,const char **bugs,
                       output_env_t *oenv)
{
    gmx_bool bHelp=FALSE,bHidden=FALSE,bQuiet=FALSE,bVersion=FALSE;
    const char *manstr[] = { NULL, "no", "html", "tex", "nroff", "ascii", 
                            "completion", "py", "xml", "wiki", NULL };
    /* This array should match the order of the enum in oenv.h */
    const char *xvg_format[] = { NULL, "xmgrace", "xmgr", "none", NULL };
    /* This array should match the order of the enum in oenv.h */
    const char *time_units[] = { NULL, "fs", "ps", "ns", "us", "ms", "s", 
                                NULL };
    int  nicelevel=0,mantp=0,npri=0,debug_level=0,verbose_level=0;
    char *deffnm=NULL;
    real tbegin=0,tend=0,tdelta=0;
    gmx_bool bView=FALSE;
    
    t_pargs *all_pa=NULL;
    
    t_pargs npri_pa   = { "-npri", FALSE, etINT,   {&npri},
    "HIDDEN Set non blocking priority (try 128)" };
    t_pargs nice_pa   = { "-nice", FALSE, etINT,   {&nicelevel}, 
    "Set the nicelevel" };
    t_pargs deffnm_pa = { "-deffnm", FALSE, etSTR, {&deffnm}, 
    "Set the default filename for all file options" };
    t_pargs begin_pa  = { "-b",    FALSE, etTIME,  {&tbegin},        
    "First frame (%t) to read from trajectory" };
    t_pargs end_pa    = { "-e",    FALSE, etTIME,  {&tend},        
    "Last frame (%t) to read from trajectory" };
    t_pargs dt_pa     = { "-dt",   FALSE, etTIME,  {&tdelta},        
    "Only use frame when t MOD dt = first time (%t)" };
    t_pargs view_pa   = { "-w",    FALSE, etBOOL,  {&bView},
    "View output xvg, xpm, eps and pdb files" };
    t_pargs xvg_pa    = { "-xvg",  FALSE, etENUM,  {xvg_format},
    "xvg plot formatting" };
    t_pargs time_pa   = { "-tu",   FALSE, etENUM,  {time_units},
    "Time unit" };
    /* Maximum number of extra arguments */
#define EXTRA_PA 16
    
    t_pargs pca_pa[] = {
      { "-h",    FALSE, etBOOL, {&bHelp},     
	"Print help info and quit" }, 
      { "-version",  FALSE, etBOOL, {&bVersion},     
	"Print version info and quit" }, 
      { "-verb",    FALSE,  etINT, {&verbose_level},
	"HIDDENLevel of verbosity for this program" },
      { "-hidden", FALSE, etBOOL, {&bHidden},
	  "HIDDENPrint hidden options" },
      { "-quiet",FALSE, etBOOL, {&bQuiet},
        "HIDDENDo not print help info" },
      { "-man",  FALSE, etENUM,  {manstr},
        "HIDDENWrite manual and quit" },
      { "-debug",FALSE, etINT, {&debug_level},
        "HIDDENWrite file with debug information, 1: short, 2: also x and f" },
    };
#define NPCA_PA asize(pca_pa)
    FILE *fp;  
    gmx_bool bPrint,bExit,bXvgr;
    int  i,j,k,npall,max_pa,cmdlength;
    char *ptr,*newdesc;
    const char *envstr;
    
#define FF(arg) ((Flags & arg)==arg)

    snew(*oenv, 1);
    
    cmdlength = strlen(argv[0]);
    /* Check for double arguments */
    for (i=1; (i<*argc); i++) 
    {
        cmdlength += strlen(argv[i]);
        if (argv[i] && (strlen(argv[i]) > 1) && (!isdigit(argv[i][1]))) 
        {
            for (j=i+1; (j<*argc); j++) 
            {
                if ( (argv[i][0]=='-') && (argv[j][0]=='-') && 
                    (strcmp(argv[i],argv[j])==0) ) 
                {
                    if (FF(PCA_NOEXIT_ON_ARGS))
                        fprintf(stderr,"Double command line argument %s\n",
                                argv[i]);
                    else
                        gmx_fatal(FARGS,"Double command line argument %s\n",
                                  argv[i]);
                }
            }
        }
    }
    debug_gmx();
    set_program_name(argv[0]);
    set_command_line(*argc, argv);
      
    /* Handle the flags argument, which is a bit field 
     * The FF macro returns whether or not the bit is set
     */
    bPrint        = !FF(PCA_SILENT);
    
    /* Check ALL the flags ... */
    max_pa = NPCA_PA + EXTRA_PA + npargs+1;
    snew(all_pa,max_pa);
    
    for(i=npall=0; (i<NPCA_PA); i++)
        npall = add_parg(npall,all_pa,&(pca_pa[i]));
    
#ifdef __sgi
    envstr = getenv("GMXNPRIALL");
    if (envstr)
        npri=strtol(envstr,NULL,10);
    if (FF(PCA_BE_NICE)) {
        envstr = getenv("GMXNPRI");
        if (envstr)
            npri=strtol(envstr,NULL,10);
    }
    npall = add_parg(npall,all_pa,&npri_pa);
#endif
    
    if (FF(PCA_BE_NICE)) 
        nicelevel=19;
    npall = add_parg(npall,all_pa,&nice_pa);
    
    if (FF(PCA_CAN_SET_DEFFNM)) 
        npall = add_parg(npall,all_pa,&deffnm_pa);   
    if (FF(PCA_CAN_BEGIN)) 
        npall = add_parg(npall,all_pa,&begin_pa);
    if (FF(PCA_CAN_END))
        npall = add_parg(npall,all_pa,&end_pa);
    if (FF(PCA_CAN_DT))
    {
        npall = add_parg(npall,all_pa,&dt_pa);
    }
    if (FF(PCA_TIME_UNIT)) {
        npall = add_parg(npall,all_pa,&time_pa);
    } 
    if (FF(PCA_CAN_VIEW)) 
        npall = add_parg(npall,all_pa,&view_pa);
    
    bXvgr = FALSE;
    for(i=0; (i<nfile); i++)
    {
        bXvgr = bXvgr ||  (fnm[i].ftp == efXVG);
    }
    if (bXvgr)
    {
        npall = add_parg(npall,all_pa,&xvg_pa);
    }
    
    /* Now append the program specific arguments */
    for(i=0; (i<npargs); i++)
        npall = add_parg(npall,all_pa,&(pa[i]));
    
    /* set etENUM options to default */
    for(i=0; (i<npall); i++)
    {
        if (all_pa[i].type==etENUM)
        {
            all_pa[i].u.c[0]=all_pa[i].u.c[1];
        }
    }
    set_default_time_unit(time_units,FF(PCA_TIME_UNIT));
    set_default_xvg_format(xvg_format);
  
    /* Now parse all the command-line options */
    get_pargs(argc,argv,npall,all_pa,FF(PCA_KEEP_ARGS));

    /* set program name, command line, and default values for output options */
    output_env_init(*oenv, *argc, argv, (time_unit_t)nenum(time_units), bView, 
                    (xvg_format_t)nenum(xvg_format), verbose_level, debug_level);
 
    if (bVersion) {
      printf("Program: %s\n",output_env_get_program_name(*oenv));
      gmx_print_version_info(stdout);
      exit(0);
    }
    
    if (FF(PCA_CAN_SET_DEFFNM) && (deffnm!=NULL))
        set_default_file_name(deffnm);
    
    /* Parse the file args */
    parse_file_args(argc,argv,nfile,fnm,FF(PCA_KEEP_ARGS),!FF(PCA_NOT_READ_NODE));
    
    /* Open the debug file */
    if (debug_level > 0) {
        char buf[256];
        
        if (gmx_mpi_initialized())
            sprintf(buf,"%s%d.debug",output_env_get_short_program_name(*oenv),
                    gmx_node_rank());
        else
            sprintf(buf,"%s.debug",output_env_get_short_program_name(*oenv));
        
        init_debug(debug_level,buf);
        fprintf(stderr,"Opening debug file %s (src code file %s, line %d)\n",
                buf,__FILE__,__LINE__);
    }
    
    /* Now copy the results back... */
    for(i=0,k=npall-npargs; (i<npargs); i++,k++) 
        memcpy(&(pa[i]),&(all_pa[k]),(size_t)sizeof(pa[i]));


    for(i=0; (i<npall); i++)
        all_pa[i].desc = mk_desc(&(all_pa[i]), output_env_get_time_unit(*oenv));
   
    bExit = bHelp || (strcmp(manstr[0],"no") != 0);
    
#if (defined __sgi && USE_SGI_FPE)
    doexceptions();
#endif
    
    /* Set the nice level */
#ifdef __sgi
    if (npri != 0 && !bExit) {
        schedctl(MPTS_RTPRI,0,npri);
    }
#endif 
    
#ifdef HAVE_UNISTD_H
    
#ifndef GMX_NO_NICE
    /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */
    if (nicelevel != 0 && !bExit)
    {
#ifdef GMX_THREADS
        static gmx_bool nice_set=FALSE; /* only set it once */
        tMPI_Thread_mutex_lock(&init_mutex);
        if (!nice_set)
        {
#endif
            i=nice(nicelevel); /* assign ret value to avoid warnings */
#ifdef GMX_THREADS
            nice_set=TRUE;
        }
        tMPI_Thread_mutex_unlock(&init_mutex);
#endif
    }
#endif
#endif
   
    /* Update oenv for parsed command line options settings. */
    (*oenv)->xvg_format = (xvg_format_t)nenum(xvg_format);
    (*oenv)->time_unit  = (time_unit_t)nenum(time_units);
    
    if (!(FF(PCA_QUIET) || bQuiet )) {
        if (bHelp)
            write_man(stderr,"help",output_env_get_program_name(*oenv),
                      ndesc,desc,nfile, fnm,npall,all_pa, nbugs,bugs,bHidden);
        else if (bPrint) {
            pr_fns(stderr,nfile,fnm);
            print_pargs(stderr,npall,all_pa,FALSE);
        }
    }
    
    if (strcmp(manstr[0],"no") != 0) {
        if(!strcmp(manstr[0],"completion")) {
            /* one file each for csh, bash and zsh if we do completions */
            fp=man_file(*oenv,"completion-zsh");
        
            write_man(fp,"completion-zsh",output_env_get_program_name(*oenv),
                      ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
            gmx_fio_fclose(fp);
            fp=man_file(*oenv,"completion-bash");
            write_man(fp,"completion-bash",output_env_get_program_name(*oenv),
                      ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
            gmx_fio_fclose(fp);
            fp=man_file(*oenv,"completion-csh");
            write_man(fp,"completion-csh",output_env_get_program_name(*oenv),
                      ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
            gmx_fio_fclose(fp);
        } else {
            fp=man_file(*oenv,manstr[0]);
            write_man(fp,manstr[0],output_env_get_program_name(*oenv),
                      ndesc,desc,nfile,fnm, npall, all_pa,nbugs,bugs,bHidden);
            gmx_fio_fclose(fp);
        }
    }
    
    /* convert time options, must be done after printing! */
    
    for(i=0; i<npall; i++) {
        if ((all_pa[i].type == etTIME) && (*all_pa[i].u.r >= 0)) {
            *all_pa[i].u.r *= output_env_get_time_invfactor(*oenv);
        }
    }
    
    /* Extract Time info from arguments */
    if (FF(PCA_CAN_BEGIN) && opt2parg_bSet("-b",npall,all_pa))
        setTimeValue(TBEGIN,opt2parg_real("-b",npall,all_pa));
    
    if (FF(PCA_CAN_END) && opt2parg_bSet("-e",npall,all_pa))
        setTimeValue(TEND,opt2parg_real("-e",npall,all_pa));
    
    if (FF(PCA_CAN_DT) && opt2parg_bSet("-dt",npall,all_pa))
        setTimeValue(TDELTA,opt2parg_real("-dt",npall,all_pa));
    
    /* clear memory */
    for (i = 0; i < npall; ++i)
        sfree((void *)all_pa[i].desc);
    sfree(all_pa);
    
    if (!FF(PCA_NOEXIT_ON_ARGS)) {
        if (*argc > 1) {
            gmx_cmd(argv[1]);
        }
    } 
    if (bExit) {
        if (gmx_parallel_env_initialized())
            /*gmx_abort(gmx_node_rank(),gmx_node_num(),0);*/
            gmx_finalize();
        exit(0);
    }
#undef FF
}