Exemplo n.º 1
0
gmx_bool 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)
{
    /* 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, debug_level = 0;
    char       *deffnm    = NULL;
    real        tbegin    = 0, tend = 0, tdelta = 0;
    gmx_bool    bView     = FALSE;

    t_pargs    *all_pa = NULL;

    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 [TT].xvg[tt], [TT].xpm[tt], [TT].eps[tt] and [TT].pdb[tt] 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[] = {
        { "-debug", FALSE, etINT, {&debug_level},
          "HIDDENWrite file with debug information, 1: short, 2: also x and f" },
    };
#define NPCA_PA asize(pca_pa)
    gmx_bool bXvgr;
    int      i, j, k, npall, max_pa;

    // Handle the flags argument, which is a bit field
    // The FF macro returns whether or not the bit is set
#define FF(arg) ((Flags & arg) == arg)

    /* Check for double arguments */
    for (i = 1; (i < *argc); i++)
    {
        if (argv[i] && (strlen(argv[i]) > 1) && (!std::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();

    /* Check ALL the flags ... */
    max_pa = NPCA_PA + EXTRA_PA + npargs+1;
    snew(all_pa, max_pa);

    for (i = npall = 0; (i < static_cast<int>(NPCA_PA)); i++)
    {
        npall = add_parg(npall, all_pa, &(pca_pa[i]));
    }

    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);

    /* set program name, command line, and default values for output options */
    output_env_init(oenv, gmx::getProgramContext(), (time_unit_t)nenum(time_units), bView,
                    (xvg_format_t)nenum(xvg_format), 0, debug_level);

    /* Parse the file args */
    parse_file_args(argc, argv, nfile, fnm, deffnm, !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]));
    }

    bool bExit = false;
    try
    {
        const gmx::CommandLineHelpContext *context =
            gmx::GlobalCommandLineHelpContext::get();
        bExit = (context != NULL);
        if (context != NULL && !(FF(PCA_QUIET)))
        {
            gmx::Options options(NULL, NULL);
            options.setDescription(gmx::constArrayRefFromArray(desc, ndesc));
            for (i = 0; i < nfile; i++)
            {
                gmx::filenmToOptions(&options, &fnm[i]);
            }
            for (i = 0; i < npall; i++)
            {
                gmx::pargsToOptions(&options, &all_pa[i]);
            }
            gmx::CommandLineHelpWriter(options)
                .setShowDescriptions(true)
                .setTimeUnitString(output_env_get_time_unit(*oenv))
                .setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs))
                .writeHelp(*context);
        }
    }
    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;

    /* Set the nice level */
#if defined(HAVE_UNISTD_H) && !defined(__MINGW32__)
#ifndef GMX_NO_NICE
    /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */
    if (nicelevel != 0 && !bExit)
    {
        static gmx_bool            nice_set   = FALSE; /* only set it once */
        static tMPI_Thread_mutex_t init_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
        tMPI_Thread_mutex_lock(&init_mutex);
        if (!nice_set)
        {
            if (nice(nicelevel) == -1)
            {
                /* Do nothing, but use the return value to avoid warnings. */
            }
            nice_set = TRUE;
        }
        tMPI_Thread_mutex_unlock(&init_mutex);
    }
#endif
#endif

    /* convert time options, must be done after printing! */

    for (i = 0; i < npall; i++)
    {
        if (all_pa[i].type == etTIME && all_pa[i].bSet)
        {
            *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 */
    sfree(all_pa);

    if (!FF(PCA_NOEXIT_ON_ARGS))
    {
        if (*argc > 1)
        {
            gmx_cmd(argv[1]);
        }
    }
    return !bExit;
#undef FF
}
Exemplo n.º 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);
  }
}
Exemplo n.º 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
}
Exemplo n.º 4
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
}
Exemplo n.º 5
0
/*!
 * \param[in,out] d     Trajectory analysis data structure.
 * \returns    0 on success, a non-zero error code on error.
 *
 * This function should be called first in the analysis program, much in
 * the same way as parse_common_args() in traditional Gromacs analysis
 * programs. It adds some command-line arguments of its own, and uses
 * parse_common_args() to parse the command-line arguments.
 * It also loads topology information if required or if a topology is
 * provided on the command line.
 * Selection handling is also initialized if it is enabled and
 * the user has selected it on the command line.
 *
 * The rest of the parameters are passed on to the Gromacs routine
 * parse_common_args(), and the use of this function should be identical
 * to parse_common_args(), with the exception that for \p pca_flags,
 * \p PCA_CAN_TIME and \p PCA_BE_NICE flags are automatically added.
 * \param      argc
 * \param      argv
 * \param      pca_flags
 * \param      nfile
 * \param      fnm
 * \param      npargs
 * \param      pa
 * \param      ndesc
 * \param      desc
 * \param      nbugs
 * \param      bugs
 */
int
parse_trjana_args(gmx_ana_traj_t *d,
                  int *argc, char *argv[], unsigned long pca_flags,
                  int nfile, t_filenm fnm[], int npargs, t_pargs *pa,
                  int ndesc, const char **desc,
		  int nbugs, const char **bugs)
{
    t_filenm           *all_fnm = NULL;
    int                 max_fnm, nfall;
    int                *fnm_map;
    t_pargs            *all_pa = NULL;
    int                 max_pa, npall;
    size_t              i;
    int                 k;
    int                 rc;

    t_filenm            def_fnm[] = {
        {efTRX, NULL,  NULL,        ffREAD},
        {efTPS, NULL,  NULL,        ffREAD},
        {efDAT, "-sf", "selection", ffOPTRD},
        {efNDX, NULL,  NULL,        ffOPTRD},
    };
    bool                bPBC = TRUE;
    t_pargs             pbc_pa[] = {
        {"-pbc",      FALSE, etBOOL, {&bPBC},
         "Use periodic boundary conditions for distance calculation"},
    };
    bool                bRmPBC = TRUE;
    t_pargs             rmpbc_pa[] = {
        {"-rmpbc",    FALSE, etBOOL, {&bRmPBC},
         "Make molecules whole for each frame"},
    };
    char               *selection = NULL;
    const char        **rpost     = NULL;
    bool                bSelDump  = FALSE;
    t_pargs             sel_pa[] = {
        {"-select",   FALSE, etSTR,  {&selection},
         "Selection string"},
        {"-seldebug", FALSE, etBOOL, {&bSelDump},
         "HIDDENPrint out the parsed and compiled selection trees"},
    };
    t_pargs             dsel_pa[] = {
        {"-selrpos",  FALSE, etENUM, {NULL},
         "Selection reference position"},
    };
    const char        **spost = NULL;
    t_pargs             selpt_pa[] = {
        {"-seltype",  FALSE, etENUM, {NULL},
         "Default analysis positions"},
    };
#define MAX_PA asize(sel_pa)+asize(dsel_pa)+5

    if (d->nrefgrps < 0)
    {
        gmx_incons("number of reference groups is negative");
        return EINVAL;
    }

    if (d->flags & ANA_DEBUG_SELECTION)
    {
        bSelDump = TRUE;
    }

    rpost = gmx_ana_poscalc_create_type_enum(!(d->flags & ANA_REQUIRE_WHOLE));
    if (rpost == NULL)
    {
        return ENOMEM;
    }
    spost = gmx_ana_poscalc_create_type_enum(TRUE);
    if (spost == NULL)
    {
        sfree(rpost);
        return ENOMEM;
    }

    /* Construct the file name argument array */
    max_fnm = nfile + asize(def_fnm);
    snew(all_fnm, max_fnm);
    nfall = 0;
    if (!(d->flags & ANA_REQUIRE_TOP))
    {
        def_fnm[1].flag |= ffOPT;
    }
    snew(fnm_map, nfile);
    for (k = 0; k < nfile; ++k)
    {
        fnm_map[k] = -1;
    }

    for (i = 0; i < asize(def_fnm); ++i)
    {
        for (k = 0; k < nfile; ++k)
        {
            if (fnm_map[k] == -1 && def_fnm[i].opt == NULL &&
                fnm[k].ftp == def_fnm[i].ftp)
            {
                break;
            }
        }
        if (k < nfile)
        {
            fnm_map[k] = nfall;
            nfall = add_fnmarg(nfall, all_fnm, &(fnm[k]));
        }
        else
        {
            nfall = add_fnmarg(nfall, all_fnm, &(def_fnm[i]));
        }
    }

    for (k = 0; k < nfile; ++k)
    {
        if (fnm_map[k] == -1)
        {
            fnm_map[k] = nfall;
            nfall = add_fnmarg(nfall, all_fnm, &(fnm[k]));
        }
    }

    /* Construct the argument array */
    max_pa = npargs + MAX_PA;
    snew(all_pa, max_pa);
    npall = 0;

    if (!(d->flags & ANA_NOUSER_RMPBC))
    {
        for (i = 0; i < asize(rmpbc_pa); ++i)
        {
            npall = add_parg(npall, all_pa, &(rmpbc_pa[i]));
        }
    }
    if (!(d->flags & ANA_NOUSER_PBC))
    {
        for (i = 0; i < asize(pbc_pa); ++i)
        {
            npall = add_parg(npall, all_pa, &(pbc_pa[i]));
        }
    }

    for (i = 0; i < asize(sel_pa); ++i)
    {
        npall = add_parg(npall, all_pa, &(sel_pa[i]));
    }
    if (!(d->flags & ANA_NO_DYNSEL))
    {
        dsel_pa[0].u.c = rpost;
        for (i = 0; i < asize(dsel_pa); ++i)
        {
            npall = add_parg(npall, all_pa, &(dsel_pa[i]));
        }
    }

    if (!(d->flags & ANA_ONLY_ATOMPOS))
    {
        selpt_pa[0].u.c = spost;
        for (i = 0; i < asize(selpt_pa); ++i)
        {
            npall = add_parg(npall, all_pa, &(selpt_pa[i]));
        }
    }

    for (k = 0; k < npargs; ++k)
    {
        npall = add_parg(npall, all_pa, &(pa[k]));
    }

    pca_flags |= PCA_CAN_TIME | PCA_BE_NICE;
    parse_common_args(argc, argv, pca_flags, nfall, all_fnm, npall, all_pa,
                      ndesc, desc, nbugs, bugs);

    /* Copy the results back */
    for (k = 0; k < nfile; ++k)
    {
        memcpy(&(fnm[k]), &(all_fnm[fnm_map[k]]), sizeof(fnm[k]));
    }
    for (i = 0, k = npall - npargs; i < (size_t)npargs; ++i, ++k)
    {
        memcpy(&(pa[i]), &(all_pa[k]), sizeof(pa[i]));
    }

    d->trjfile         = ftp2fn(efTRX, nfall, all_fnm);
    d->topfile         = ftp2fn_null(efTPS, nfall, all_fnm);
    d->topfile_notnull = ftp2fn(efTPS, nfall, all_fnm);
    d->ndxfile         = ftp2fn_null(efNDX, nfall, all_fnm);
    if (!(d->flags & ANA_NOUSER_RMPBC))
    {
        d->bRmPBC      = bRmPBC;
    }
    if (!(d->flags & ANA_NOUSER_PBC))
    {
        d->bPBC        = bPBC;
    }
    d->selection       = selection;
    d->selfile         = opt2fn_null("-sf", nfall, all_fnm);

    sfree(all_fnm);
    sfree(fnm_map);
    sfree(all_pa);

    if (!(d->flags & ANA_NO_DYNSEL))
    {
        gmx_ana_selcollection_set_refpostype(d->sc, rpost[0]);
    }
    else
    {
        gmx_ana_selcollection_set_refpostype(d->sc, rpost[1]);
    }
    sfree(rpost);
    if (bSelDump)
    {
        d->flags |= ANA_DEBUG_SELECTION;
    }
    else
    {
        d->flags &= ~ANA_DEBUG_SELECTION;
    }

    if (!(d->flags & ANA_ONLY_ATOMPOS))
    {
        gmx_ana_selcollection_set_outpostype(d->sc, spost[0], d->flags & ANA_USE_POSMASK);
    }
    else
    {
        gmx_ana_selcollection_set_outpostype(d->sc, spost[1], d->flags & ANA_USE_POSMASK);
    }
    sfree(spost);

    /* Load the topology if so requested. */
    rc = load_topology(d, (d->flags & ANA_REQUIRE_TOP));
    if (rc != 0)
    {
        return rc;
    }

    /* Initialize the selections/index groups */
    if (!(d->flags & ANA_USER_SELINIT))
    {
        rc = gmx_ana_init_selections(d);
    }

    return rc;
}