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 }
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); } }
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 }
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 }
/*! * \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; }