dafeef0b |
/*********************************************************************
* Clustal Omage - Multiple sequence alignment
*
* Copyright (C) 2010 University College Dublin
*
* Clustal-Omega is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This file is part of Clustal-Omega.
*
********************************************************************/
/*
* RCS $Id: main.cpp 234 2011-04-13 05:26:16Z andreas $
*/
/*
* We are using a mix of C and C++, which means that linking has to be
* done with a C++ compiler. By using this "fake" main c++ function,
* automake is convinced to use a C++ compiler for linking.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern "C" {
#include "mymain.h"
#include "clustal/util.h"
//#include "squid/squid.h"
}
/**
* @brief Convert an old Clustal command line parameter in the form of
* [-/]param[=value] to new parameter if possible
*
* @param[out] iNewArgC_p
* "argc" which will be incremented for each successfully converted option
* @param[out] ppcNewArgV_p
* "argv" to which each successfully converted options will be added
* (caller has to free)
* @param[in] pcOldArg
* The old parameter and value command line option
*
*/
void
ConvertOldCmdLineArg(int *iNewArgC_p, char ***ppcNewArgV_p, char *pcOldArg)
{
char *pcOldParam, *pcOldValue, *pcOldArgCopy;
char zcNotImplementedMsg[] = "WARNING: Invalid old command line option";
pcOldArgCopy = CkStrdup(pcOldArg);
pcOldParam = strtok(pcOldArgCopy, "=");
pcOldValue = strtok(NULL, "=");
/* go through all options in order of appearance in clustalw2 -help
*
*/
/* data
*
*/
if (STR_NC_EQ("INFILE", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-i");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
} else if (STR_NC_EQ("PROFILE1", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("--profile1");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
} else if (STR_NC_EQ("PROFILE2", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("--profile2");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
/* verbs
*
*/
/* missing:
* OPTIONS
*/
} else if (STR_NC_EQ("HELP", &pcOldParam[1])
|| STR_NC_EQ("CHECK", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-h");
} else if (STR_NC_EQ("FULLHELP", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-h");
} else if (STR_NC_EQ("ALIGN", &pcOldParam[1])) {
char msg[] = "WARNING: The ALIGN option is default in Clustal Omega";
fprintf(stderr, "%s\n", msg);
/* missing:
* TREE
* PIM
* BOOTSTRAP
* CONVERT
*/
/* parameters
*
*/
} else if (STR_NC_EQ("INTERACTIVE", &pcOldParam[1])) {
char msg[] = "WARNING: There is no interactive command-line menu in Clustal Omega";
fprintf(stderr, "%s\n", msg);
/* trigger help */
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-h");
} else if (STR_NC_EQ("QUICKTREE", &pcOldParam[1])) {
char msg[] = "WARNING: The QUICKTREE (i.e. k-tuple distance) option is default in Clustal Omega";
fprintf(stderr, "%s\n", msg);
} else if (STR_NC_EQ("TYPE", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-t");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
/* NEGATIVE */
} else if (STR_NC_EQ("OUTFILE", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-o");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
} else if (STR_NC_EQ("OUTPUT", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("--outfmt");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
/* missing:
* OUTORDER
* CASE
* SEQNOS
* SEQNO_RANGE
* RANGE
*/
} else if (STR_NC_EQ("MAXSEQLEN", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("--maxseqlen");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
} else if (STR_NC_EQ("QUIET", &pcOldParam[1])) {
char msg[] = "WARNING: The QUIET option is default in Clustal Omega";
fprintf(stderr, "%s\n", msg);
/* missing:
* STATS
*/
/* fast pariwise alignment
*
*/
/* missing:
* KTUPLE
* TOPDIAGS
* WINDOW
* PAIRGAP
* SCORE
*/
/* slow pairwise alignments
*
*/
/* missing:
* PWMATRIX
* PWDNAMATRIX
* PWGAPOPEN
* PWGAPEXT
*/
/* multiple alignments
*
*/
} else if (STR_NC_EQ("NEWTREE", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("--guidetree-out");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
} else if (STR_NC_EQ("USETREE", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("--guidetree-in");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
/* missing:
* MATRIX
* DNAMATRIX
* GAPOPEN
* GAPEXT
* ENDGAPS
* GAPDIST
* NOGAP
* NOHGAP
* HGAPRESIDUES
* MAXDIV
* TYPE already handled above
* TRANSWEIGHT
* ITERATION
* NUMITER
* NOWEIGHTS
*/
/* profile alignments
*
*/
/* missing:
* PROFILE
* NEWTREE1
* NEWTREE2
* USETREE1
* USETREE2
*/
/* sequence to profile alignments
*
*/
} else if (STR_NC_EQ("SEQUENCES", &pcOldParam[1])) {
fprintf(stderr, "WARNING: %s: %s\n", zcNotImplementedMsg, pcOldArg);
/* SEQUENCES and NEWTREE already handled above */
/* structure alignments
*
*/
/* missing:
* NOSECSTR1
* NOSECSTR2
* SECSTROUT
* HELIXGAP
* STRANDGAP
* LOOPGAP
* TERMINALGAP
* HELIXENDIN
* HELIXENDOUT
* STRANDENDIN
* STRANDENDOUT
*/
/* trees
*
*/
/* missing:
* OUTPUTTREE
* SEED
* KIMURA
* TOSSGAPS
* BOOTLABELS
*/
#if 0
} else if (STR_NC_EQ("CLUSTERING", &pcOldParam[1])) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-c");
if (NULL != pcOldValue)
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(pcOldValue);
#endif
} else {
fprintf(stderr,
"WARNING: Unsupported old command line option '%s' will be ignored\n",
pcOldArg);
}
/* FIXME: if not outfile was given, than the old default was to create a
* filename based on the input filename but with its extension replaced by
* aln. If the input already had the extension aln then the input was
* overwritten. What to do here? Strictly mimic the old behaviour?
*/
free(pcOldArgCopy);
}
/* end ConvertOldCmdLineArg */
/**
* @brief Convert old command line usage to new one. Mix of old and
* new style will be tolerated
*
* @param[out] iNewArgC_p
* The updated "argc"
* @param[out] ppcNewArgV_p
* The updated "argv". Caller has to free.
* @param[in] argc
* Original "argc"
* @param[in] argv
* Original argv
*
* @note old style parameters look like this:
* [/-]param[=value]
* new style parameters:
* -p [value]
* --param [value]
*
*/
void
ConvertOldCmdline(int *iNewArgC_p, char ***ppcNewArgV_p, int argc, char **argv)
{
bool bOldCmdlineDetected = false;
int i; /* aux */
/* we can have at most 2*argc converted arguments, plus the few
* that we set by default (.e.g --force)
*/
(*ppcNewArgV_p) = (char **) CKCALLOC(argc*2+10, sizeof(char*));
/* copy first arg which is program name */
(*ppcNewArgV_p)[0] = CkStrdup(argv[0]);
*iNewArgC_p = 1;
for (i=1; i<argc; i++) {
bool bNewStyle = false;
if (strlen(argv[i])<=2) {
/* e.g. -i (param) or just numbers (value) */
bNewStyle = true;
} else if (strlen(argv[i])>2) {
if (argv[i][0] == '-' && argv[i][1] == '-') {
/* new style long opts */
bNewStyle = true;
} else if (argv[i][0]=='/' && (NULL!=strchr(&argv[i][1], '/'))) {
/* Slash used to be a valid replacement for dash in
* Clustal<=2, but could also be file in new style. If
* we find at least two slashes, one at the beginning,
* it should be a filename and therefore new style */
bNewStyle = true;
} else if (argv[i][0] != '/' && argv[i][0] != '-') {
/* old style opts always start with slash or dash */
bNewStyle = true;
}
}
/* copy and continue if new style arg or attempt to convert
* old style arg
*/
if (bNewStyle) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup(argv[i]);
} else {
ConvertOldCmdLineArg(iNewArgC_p, ppcNewArgV_p, argv[i]);
/*LOG_DEBUG("old command line arg: %s", argv[i]);*/
bOldCmdlineDetected = true;
}
}
if (bOldCmdlineDetected) {
bool bOutfileOptSet = FALSE;
bool bOutFormatOptSet = FALSE;
/* old clustal used to write to a file called in.aln by
* default. set if not
* explicitely requested otherwisee
*/
for (i=0; i<*iNewArgC_p; i++) {
const char *pcOpt = "-o";
if (strlen(pcOpt) <= strlen((*ppcNewArgV_p)[i])) {
if (0 == strncmp((*ppcNewArgV_p)[i], pcOpt, strlen(pcOpt))) {
bOutfileOptSet = TRUE;
break;
}
}
}
if (FALSE == bOutfileOptSet) {
#ifdef TOO_LAZY_TO_IMPLEMENT_JUST_USING_DEFAULT_NAME_INSTEAD
char *pcDotPos = NULL;
char *pcInfileOpt = NULL;
/* get infile arg and find last dot in it. if found replace
* everything after with "aln", otherwise just add "aln"
*/
for (i=0; i<*iNewArgC_p; i++) {
const char *pcOpt = "-i";
if (strlen(pcOpt) <= strlen((*ppcNewArgV_p)[i])) {
if (0 == strncmp((*ppcNewArgV_p)[i], pcOpt, strlen(pcOpt))) {
if (*iNewArgC_p<= i+1) {
fprintf(stderr,
"Oups...error while trying to convert old commandline (%s).\n",
"No more arguments left after -i");
throw 1;
}
pcInfileOpt = (*ppcNewArgV_p)[i+1];
break;
}
}
}
if (NULL == pcInfileOpt) {
fprintf(stderr,
"Oups...error while trying to convert old commandline (%s)\n",
"No infile opt found");
throw 1;
}
fprintf(stderr, "FIXME: unfinished\n");
throw 1;
#endif
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-o");
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("clustal.aln");
}
/* old clustal used the clustal format by default. set if not
* explicitely requested otherwisee
*/
for (i=0; i<*iNewArgC_p; i++) {
const char *pcOpt = "--outfmt";
if (strlen(pcOpt) <= strlen((*ppcNewArgV_p)[i])) {
if (0 == strncmp((*ppcNewArgV_p)[i], pcOpt, strlen(pcOpt))) {
bOutFormatOptSet = TRUE;
break;
}
}
}
if (FALSE == bOutFormatOptSet) {
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("--outfmt=clustal");
}
/* old clustal was verbose by default
*/
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("-v");
/* old clustal used to overwrite files by default
*/
(*ppcNewArgV_p)[(*iNewArgC_p)++] = CkStrdup("--force");
fprintf(stderr,
"WARNING: Your old-style command-line options were converted to: ");
for (i=0; i<*iNewArgC_p; i++) {
fprintf(stderr, " %s", (*ppcNewArgV_p)[i]);
}
fprintf(stderr, "\n");
}
}
/* end ConvertOldCmdline */
int
main(int argc, char **argv)
{
ClustalOmegaInput msaInput;
ClustalOmegaOutput msaOutput;
int i; /* aux */
int new_argc = 0;
char **new_argv = NULL;
ConvertOldCmdline(&new_argc, &new_argv, argc, argv);
executeClustalOmega(new_argc, new_argv, &msaInput, &msaOutput);
for (i=0; i<new_argc; i++) {
free(new_argv[i]);
}
free(new_argv);
return 0;
}
|