ID acdExpList TY list MO ajacd LB acd XX DE Functions for processing expressions in ACD dependencies XX // static AcdOExpList explist[] = { {"plus", &acdExpPlus}, {"minus", &acdExpMinus}, {"star", &acdExpStar}, {"div", &acdExpDiv}, {"not", &acdExpNot}, {"equal", &acdExpEqual}, {"notequal", &acdExpNotEqual}, {"greater", &acdExpGreater}, {"lesser", &acdExpLesser}, {"or", &acdExpOr}, {"and", &acdExpAnd}, {"cond", &acdExpCond}, {"oneof", &acdExpOneof}, {"case", &acdExpCase}, {"filename", &acdExpFilename}, {"exists", &acdExpExists}, {"value", &acdExpValue}, {NULL, NULL} }; ID acdKeywords TY list MO ajacd LB acd XX DE Processing predefined ACD keywords (application, variable, section, DE endsection) XX // AcdOKey acdKeywords[] = { {"qualifier", QUAL_STAGE, 0, NULL, NULL}, {"application", APPL_STAGE, 0, acdAttrAppl, acdSetAppl}, {"variable", VAR_STAGE, 0, acdAttrVar, acdSetVar}, {"relations", REL_STAGE, 0, acdAttrRel, acdSetRel}, {"section", SEC_STAGE, 0, acdAttrSec, acdSetSec}, {"endsection", ENDSEC_STAGE, 0, acdAttrEndsec, acdSetEndsec}, {NULL, BAD_STAGE, 0, NULL, NULL} }; ID acdOuttype TY list MO ajacd LB acd XX DE Processing output types and their formats XX // AcdOOuttype acdOuttype[] = { /* Name Format Type Padding Prompt Outformat */ {"outassembly", "bam", ajEOutfileTypeAssembly, 0, acdPromptOutassembly, ajAssemoutformatFind}, {"outcodon", "cut", ajEOutfileTypeCodon, 0, acdPromptOutcodon, ajCodoutformatFind}, {"outcpdb", "cpdb", ajEOutfileTypeCPDB, 0, acdPromptOutcpdb, acdOutFormatCpdb}, {"outdata", "text", ajEOutfileTypeUnknown, 0, acdPromptOutdata, acdOutFormatData}, {"outdiscrete", "phylip", ajEOutfileTypeDiscrete, 0, acdPromptOutdiscrete, acdOutFormatDiscrete}, {"outdistance", "phylip", ajEOutfileTypeDistance, 0, acdPromptOutdistance, acdOutFormatDistance}, {"outfreq", "phylip", ajEOutfileTypeFrequency, 0, acdPromptOutfreq, acdOutFormatFreq}, {"outmatrix", "emboss", ajEOutfileTypeMatrix, 0, acdPromptOutmatrix, acdOutFormatMatrix}, {"outmatrixf", "emboss", ajEOutfileTypeMatrixF, 0, acdPromptOutmatrix, acdOutFormatMatrixf}, {"outobo", "obo", ajEOutfileTypeOBO, 0, acdPromptOutobo, ajObooutformatFind}, {"outproperties", "phylip", ajEOutfileTypeProperties, 0, acdPromptOutproperties, acdOutFormatProperties}, {"outrefseq", "embl", ajEOutfileTypeRefseq, 0, acdPromptOutrefseq, ajRefseqoutformatFind}, {"outresource", "drcat", ajEOutfileTypeResource, 0, acdPromptOutresource, ajResourceoutformatFind}, {"outscop", "scop", ajEOutfileTypeSCOP, 0, acdPromptOutscop, acdOutFormatScop}, {"outtaxon", "tax", ajEOutfileTypeTaxon, 0, acdPromptOuttaxon, ajTaxoutformatFind}, {"outtext", "text", ajEOutfileTypeText, 0, acdPromptOuttext, ajTextoutformatFind}, {"outtree", "phylip", ajEOutfileTypeTree, 0, acdPromptOuttree, acdOutFormatTree}, {"outurl", "url", ajEOutfileTypeURL, 0, acdPromptOuturl, ajUrloutformatFind}, {"outvariation", "vcf", ajEOutfileTypeVariation, 0, acdPromptOutvariation, ajVaroutformatFind}, {NULL, NULL, ajEOutfileTypeUnknown, 0, NULL, NULL} }; ID acdType TY list MO ajacd LB acd XX DE Processing for ACD types DE DE Includes the acdSet functions for each ACD type XX // AcdOType acdType[] = { /* Name Group Section ** Attributes Qualifiers ** SetFunction HelpFunction Destructor ** PassRef StdPrompt PromptFunction UseCount UseClassCount ** Description of valid string for help */ {"align", "output", acdSecOutput, acdAttrAlign, acdQualAlign, &acdSetAlign, NULL, &acdDelAlign, AJTRUE, AJTRUE, &acdPromptAlign, &acdUseAlign, &acdUseOut, "Alignment output file" }, {"array", "simple", NULL, acdAttrArray, NULL, &acdSetArray, NULL, &acdDelFloat, AJTRUE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "List of floating point numbers" }, {"assembly", "input", acdSecInput, acdAttrAssembly, acdQualAssembly, &acdSetAssembly, NULL, &acdDelAssembly, AJTRUE, AJTRUE, &acdPromptAssembly, &acdUseData, &acdUseIn, "Assembly of sequence reads" }, {"boolean", "simple", NULL, acdAttrBool, NULL, &acdSetBoolean, NULL, &acdFree, AJFALSE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "Boolean value Yes/No" }, {"codon", "input", acdSecInput, acdAttrCodon, acdQualCodon, &acdSetCodon, NULL, &acdDelCod, AJTRUE, AJTRUE, &acdPromptCodon, &acdUseData, &acdUseIn, "Codon usage file in EMBOSS data path" }, {"cpdb", "input", acdSecInput, acdAttrCpdb, acdQualCpdb, &acdSetCpdb, NULL, &acdDelFile, AJTRUE, AJTRUE, acdPromptCpdb, &acdUseInfile, &acdUseIn, "Clean PDB file" }, {"datafile", "input", acdSecInput, acdAttrDatafile, NULL, &acdSetDatafile, NULL, &acdDelFile, AJTRUE, AJTRUE, &acdPromptDatafile, &acdUseData, &acdUseIn, "Data file" }, {"directory", "input", acdSecInput, acdAttrDirectory, acdQualDirectory, &acdSetDirectory, NULL, &acdDelDir, AJTRUE, AJTRUE, &acdPromptDirectory,&acdUseMisc, &acdUseIn, "Directory" }, {"dirlist", "input", acdSecInput, acdAttrDirlist, acdQualDirlist, &acdSetDirlist, NULL, &acdDelList, AJTRUE, AJTRUE, &acdPromptDirlist, &acdUseMisc, &acdUseIn, "Directory with files" }, {"discretestates", "input", acdSecInput, acdAttrDiscretestates, NULL, &acdSetDiscretestates, NULL, &acdDelPhyloState, AJTRUE, AJTRUE, &acdPromptDiscretestates, &acdUseData, &acdUseIn, "Discrete states file" }, {"distances", "input", acdSecInput, acdAttrDistances, NULL, &acdSetDistances, NULL, &acdDelPhyloDist, AJTRUE, AJTRUE, &acdPromptDistances, &acdUseData, &acdUseIn, "Distance matrix" }, {"featout", "output", acdSecOutput, acdAttrFeatout, acdQualFeatout, &acdSetFeatout, NULL, &acdDelFeattabOut, AJTRUE, AJTRUE, &acdPromptFeatout, &acdUseFeatout, &acdUseOut, "Writeable feature table" }, {"features", "input", acdSecInput, acdAttrFeatures, acdQualFeatures, &acdSetFeatures, NULL, &acdDelFeattable, AJTRUE, AJTRUE, &acdPromptFeatures, &acdUseFeatures, &acdUseIn, "Readable feature table" }, {"filelist", "input", acdSecInput, acdAttrFilelist, NULL, &acdSetFilelist, NULL, &acdDelList, AJTRUE, AJTRUE, &acdPromptFilelist, &acdUseMisc, &acdUseIn, "Comma-separated file list" }, {"float", "simple", NULL, acdAttrFloat, NULL, &acdSetFloat, NULL, &acdFree, AJFALSE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "Floating point number" }, {"frequencies", "input", acdSecInput, acdAttrFrequencies, NULL, &acdSetFrequencies, NULL, &acdDelPhyloFreq, AJTRUE, AJTRUE, &acdPromptFrequencies, &acdUseData, &acdUseIn, "Frequency value(s)" }, {"graph", "graph", acdSecOutput, acdAttrGraph, acdQualGraph, &acdSetGraph, NULL, &acdFree, AJTRUE, AJTRUE, &acdPromptGraph, &acdUseGraph, &acdUseOut, "Graph device for a general graph" }, {"infile", "input", acdSecInput, acdAttrInfile, NULL, &acdSetInfile, NULL, &acdDelFile, AJTRUE, AJTRUE, &acdPromptInfile, &acdUseInfile, &acdUseIn, "Input file" }, {"integer", "simple", NULL, acdAttrInt, NULL, &acdSetInt, NULL, &acdFree, AJFALSE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "Integer" }, {"list", "selection", NULL, acdAttrList, NULL, acdSetList, NULL, acdDelStrArray, AJTRUE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "Choose from menu list of values" }, {"matrix", "input", acdSecInput, acdAttrMatrix, NULL, &acdSetMatrix, NULL, &acdDelMatrix, AJTRUE, AJFALSE, &acdPromptMatrix, &acdUseData, &acdUseIn, "Comparison matrix file in EMBOSS data path" }, {"matrixf", "input", acdSecInput, acdAttrMatrixf, NULL, &acdSetMatrixf, NULL, &acdDelMatrixf, AJTRUE, AJFALSE, &acdPromptMatrix, &acdUseData, &acdUseIn, "Comparison matrix file in EMBOSS data path" }, {"obo", "input", acdSecInput, acdAttrObo, acdQualObo, &acdSetObo, &acdHelpTextObo, &acdDelObo, AJTRUE, AJTRUE, &acdPromptObo, &acdUseData, &acdUseIn, "OBO bio-ontology term(s)" }, {"outassembly", "output", acdSecOutput, acdAttrOutassembly, acdQualOutassembly, &acdSetOutassembly, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutassembly, &acdUseOutfile, &acdUseOut, "Assembly of sequence reads" }, {"outcodon", "output", acdSecOutput, acdAttrOutcodon, acdQualOutcodon, &acdSetOutcodon, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutcodon, &acdUseOutfile, &acdUseOut, "Codon usage file" }, {"outcpdb", "output", acdSecOutput, acdAttrOutcpdb, NULL, &acdSetOutcpdb, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutcpdb, &acdUseOutfile, &acdUseOut, "Cleaned PDB file" }, {"outdata", "output", acdSecOutput, acdAttrOutdata, acdQualOutdata, &acdSetOutdata, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutdata, &acdUseOutfile, &acdUseOut, "Formatted output file" }, {"outdir", "output", acdSecOutput, acdAttrOutdir, acdQualOutdir, &acdSetOutdir, NULL, &acdDelDirout, AJTRUE, AJTRUE, &acdPromptOutdir, &acdUseMisc, &acdUseOut, "Output directory" }, {"outdiscrete", "output", acdSecOutput, acdAttrOutdiscrete, acdQualOutdiscrete, &acdSetOutdiscrete, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutdiscrete, &acdUseOutfile, &acdUseOut, "Discrete states file" }, {"outdistance", "output", acdSecOutput, acdAttrOutdistance, NULL, &acdSetOutdistance, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutdistance, &acdUseOutfile, &acdUseOut, "Distance matrix" }, {"outfile", "output", acdSecOutput, acdAttrOutfile, acdQualOutfile, &acdSetOutfile, NULL, &acdDelFile, AJTRUE, AJTRUE, &acdPromptOutfile, &acdUseOutfile, &acdUseOut, "Output file" }, {"outfreq", "output", acdSecOutput, acdAttrOutfreq, acdQualOutfreq, &acdSetOutfreq, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutfreq, &acdUseOutfile, &acdUseOut, "Frequency value(s)" }, {"outmatrix", "output", acdSecOutput, acdAttrOutmatrix, acdQualOutmatrix, &acdSetOutmatrix, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutmatrix, &acdUseOutfile, &acdUseOut, "Comparison matrix file" }, {"outmatrixf", "output", acdSecOutput, acdAttrOutmatrixf, acdQualOutmatrixf, &acdSetOutmatrixf, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutmatrix, &acdUseOutfile, &acdUseOut, "Comparison matrix file" }, {"outobo", "output", acdSecOutput, acdAttrOutobo, acdQualOutobo, &acdSetOutobo, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutobo, &acdUseOutfile, &acdUseOut, "OBO ontology term(s)" }, {"outproperties", "output", acdSecOutput, acdAttrOutproperties, acdQualOutproperties, &acdSetOutproperties, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutproperties, &acdUseOutfile, &acdUseOut, "Property value(s)" }, {"outrefseq", "output", acdSecOutput, acdAttrOutrefseq, acdQualOutrefseq, &acdSetOutrefseq, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutrefseq, &acdUseOutfile, &acdUseOut, "Reference sequence" }, {"outresource", "output", acdSecOutput, acdAttrOutresource, acdQualOutresource, &acdSetOutresource, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutresource, &acdUseOutfile, &acdUseOut, "Data resource entry" }, {"outscop", "output", acdSecOutput, acdAttrOutscop, acdQualOutscop, &acdSetOutscop, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutscop, &acdUseOutfile, &acdUseOut, "Scop entry" }, {"outtaxon", "output", acdSecOutput, acdAttrOuttaxon, acdQualOuttaxon, &acdSetOuttaxon, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOuttaxon, &acdUseOutfile, &acdUseOut, "NCBI taxonomy entries" }, {"outtext", "output", acdSecOutput, acdAttrOuttext, acdQualOuttext, &acdSetOuttext, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOuttext, &acdUseOutfile, &acdUseOut, "Text entries" }, {"outtree", "output", acdSecOutput, acdAttrOuttree, acdQualOuttree, &acdSetOuttree, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOuttree, &acdUseOutfile, &acdUseOut, "Phylogenetic tree" }, {"outurl", "output", acdSecOutput, acdAttrOuturl, acdQualOuturl, &acdSetOuturl, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOuturl, &acdUseOutfile, &acdUseOut, "URL entries" }, {"outvariation", "output", acdSecOutput, acdAttrOutvariation, acdQualOutvariation, &acdSetOutvariation, NULL, &acdDelOutfile, AJTRUE, AJTRUE, &acdPromptOutvariation, &acdUseOutfile, &acdUseOut, "Variation entries" }, {"pattern", "input", acdSecInput, acdAttrPattern, acdQualPattern, &acdSetPattern, NULL, &acdDelPatlist, AJTRUE, AJTRUE, &acdPromptPattern, &acdUseData, &acdUseIn, "Property value(s)" }, {"properties", "input", acdSecInput, acdAttrProperties, NULL, &acdSetProperties, NULL, &acdDelPhyloProp, AJTRUE, AJTRUE, &acdPromptProperties, &acdUseData, &acdUseIn, "Property value(s)" }, {"range", "simple", NULL, acdAttrRange, NULL, &acdSetRange, NULL, &acdDelRange, AJTRUE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "Sequence range" }, {"refseq", "input", acdSecInput, acdAttrRefseq, acdQualRefseq, &acdSetRefseq, NULL, &acdDelRefseq, AJTRUE, AJTRUE, &acdPromptRefseq, &acdUseData, &acdUseIn, "Reference sequence" }, {"regexp", "input", acdSecInput, acdAttrRegexp, acdQualRegexp, &acdSetRegexp, NULL, &acdDelReg, AJTRUE, AJTRUE, &acdPromptRegexp, &acdUseMisc, &acdUseIn, "Regular expression pattern" }, {"report", "output", acdSecOutput, acdAttrReport, acdQualReport, &acdSetReport, NULL, &acdDelReport, AJTRUE, AJTRUE, &acdPromptReport, &acdUseReport, &acdUseOut, "Report output file" }, {"resource", "input", acdSecInput, acdAttrResource, acdQualResource, &acdSetResource, &acdHelpTextResource, &acdDelResource, AJTRUE, AJTRUE, &acdPromptResource, &acdUseData, &acdUseIn, "Data resource catalogue entry(s)" }, {"scop", "input", acdSecInput, acdAttrScop, acdQualScop, &acdSetScop, NULL, &acdDelFile, AJTRUE, AJTRUE, &acdPromptScop, &acdUseInfile, &acdUseIn, "Clean PDB file" }, {"selection", "selection", NULL, acdAttrSelect, NULL, &acdSetSelect, NULL, &acdDelStrArray, AJTRUE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "Choose from selection list of values" }, {"sequence", "input", acdSecInput, acdAttrSeq, acdQualSeq, &acdSetSeq, &acdHelpTextSeq, &acdDelSeq, AJTRUE, AJTRUE, &acdPromptSeq, &acdUseSeq, &acdUseIn, "Readable sequence" }, {"seqall", "input", acdSecInput, acdAttrSeqall, acdQualSeqall, &acdSetSeqall, &acdHelpTextSeq, &acdDelSeqall, AJTRUE, AJTRUE, &acdPromptSeq, &acdUseSeq, &acdUseIn, "Readable sequence(s)" }, {"seqout", "output", acdSecOutput, acdAttrSeqout, acdQualSeqout, &acdSetSeqout, &acdHelpTextSeqout, &acdDelSeqout, AJTRUE, AJTRUE, &acdPromptSeqout, &acdUseSeqout, &acdUseOut, "Writeable sequence" }, {"seqoutall", "output", acdSecOutput, acdAttrSeqoutall, acdQualSeqoutall, &acdSetSeqoutall, &acdHelpTextSeqout, &acdDelSeqout, AJTRUE, AJTRUE, &acdPromptSeqout, &acdUseSeqout, &acdUseOut, "Writeable sequence(s)" }, {"seqoutset", "output", acdSecOutput, acdAttrSeqoutset, acdQualSeqoutset, &acdSetSeqoutset, &acdHelpTextSeqout, &acdDelSeqout, AJTRUE, AJTRUE, &acdPromptSeqout, &acdUseSeqout, &acdUseOut, "Writeable sequences" }, {"seqset", "input", acdSecInput, acdAttrSeqset, acdQualSeqset, &acdSetSeqset, &acdHelpTextSeq, &acdDelSeqset, AJTRUE, AJTRUE, &acdPromptSeq, &acdUseSeq, &acdUseIn, "Readable set of sequences" }, {"seqsetall", "input", acdSecInput, acdAttrSeqsetall, acdQualSeqsetall, &acdSetSeqsetall, &acdHelpTextSeq, &acdDelSeqsetArray, AJTRUE, AJTRUE, &acdPromptSeq, &acdUseSeq, &acdUseIn, "Readable sets of sequences" }, {"string", "simple", NULL, acdAttrString, NULL, acdSetString, NULL, acdDelStr, AJTRUE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "String value" }, {"taxon", "input", acdSecInput, acdAttrTaxon, acdQualTaxon, &acdSetTaxon, &acdHelpTextTaxon, &acdDelTaxon, AJTRUE, AJTRUE, &acdPromptTaxon, &acdUseData, &acdUseIn, "NCBI taxonomy entries" }, {"text", "input", acdSecInput, acdAttrText, acdQualText, &acdSetText, &acdHelpTextText, &acdDelText, AJTRUE, AJTRUE, &acdPromptText, &acdUseData, &acdUseIn, "Text entries" }, {"toggle", "simple", NULL, acdAttrToggle, NULL, &acdSetToggle, NULL, &acdFree, AJFALSE, AJFALSE, NULL, &acdUseMisc, &acdUseMisc, "Toggle value Yes/No" }, {"tree", "input", acdSecInput, acdAttrTree, NULL, &acdSetTree, NULL, &acdDelPhyloTree, AJTRUE, AJTRUE, &acdPromptTree, &acdUseData, &acdUseIn, "Phylogenetic tree" }, {"url", "input", acdSecInput, acdAttrUrl, acdQualUrl, &acdSetUrl, &acdHelpTextUrl, &acdDelUrl, AJTRUE, AJTRUE, &acdPromptUrl, &acdUseData, &acdUseIn, "URL entries" }, {"variation", "input", acdSecInput, acdAttrVariation, acdQualVariation, &acdSetVariation, &acdHelpTextVariation, &acdDelVariation, AJTRUE, AJTRUE, &acdPromptVariation, &acdUseData, &acdUseIn, "Variation entries" }, {"xygraph", "graph", acdSecOutput, acdAttrGraphxy, acdQualGraphxy, &acdSetGraphxy, NULL, &acdFree, AJTRUE, AJTRUE, &acdPromptGraph, &acdUseGraph, &acdUseOut, "Graph device for a 2D graph" }, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, AJFALSE, AJFALSE, 0, NULL, NULL, NULL} }; ID acdValue TY list MO ajacd LB acd XX DE ACD type help processing, includes functions to describe valid DE values and expected values in -help output and -acdtable output XX // AcdOValid acdValue[] = { {"align", acdHelpValidAlign, acdHelpExpectOut}, {"codon", acdHelpValidCodon, acdHelpExpectCodon}, {"datafile", acdHelpValidData, acdHelpExpectData}, {"dirlist", acdHelpValidDirlist, acdHelpExpectDirlist}, {"featout", acdHelpValidFeatout, acdHelpExpectFeatout}, {"features", acdHelpValidFeatures, acdHelpExpectFeatures}, {"filelist", acdHelpValidFilelist, acdHelpExpectFilelist}, {"float", acdHelpValidFloat, acdHelpExpectFloat}, {"graph", acdHelpValidGraph, acdHelpExpectGraph}, {"infile", acdHelpValidIn, acdHelpExpectIn}, {"integer", acdHelpValidInt, acdHelpExpectInt}, {"list", acdHelpValidList, NULL}, {"matrix", acdHelpValidMatrix, acdHelpExpectMatrix}, {"matrixf", acdHelpValidMatrix, acdHelpExpectMatrix}, {"outfile", acdHelpValidOut, acdHelpExpectOut}, {"outobo", acdHelpValidOut, acdHelpExpectOut}, {"outresource", acdHelpValidOut, acdHelpExpectOut}, {"regexp", acdHelpValidRegexp, acdHelpExpectRegexp}, {"report", acdHelpValidReport, acdHelpExpectOut}, {"select", acdHelpValidSelect, NULL}, {"seqall", acdHelpValidSeq, acdHelpExpectSeq}, {"seqset", acdHelpValidSeq, acdHelpExpectSeq}, {"seqsetall", acdHelpValidSeq, acdHelpExpectSeq}, {"sequence", acdHelpValidSeq, acdHelpExpectSeq}, {"seqout", acdHelpValidSeqout, acdHelpExpectSeqout}, {"seqoutall", acdHelpValidSeqout, acdHelpExpectSeqout}, {"seqoutset", acdHelpValidSeqout, acdHelpExpectSeqout}, {"string", acdHelpValidString, acdHelpExpectString}, {"range", acdHelpValidRange, acdHelpExpectRange}, {"xygraph", acdHelpValidGraph, acdHelpExpectGraph}, {NULL, NULL, NULL} }; ID ajAcdInit TY public MO ajacd LB acd XX DE Initialises everything. Reads an ACD (AJAX Command Definition) file DE prompts the user for any missing information, reads all sequences DE and other input into local structures which applications can request. XX PN [1] PA r pgm const char* PD Application name, used as the name PD of the ACD file PX PN [2] PA r argc ajint PD Number of arguments provided on the command line, PD usually passed as-is by the calling application. PX PN [3] PA r argv char* const[] PD Actual arguments as an array of text. PX RT void RD RX // void ajAcdInit(const char *pgm, ajint argc, char * const argv[]) { ajAcdInitPV(pgm, argc, argv, "", ""); return; } ID ajAcdInitPV TY public MO ajacd LB acd XX DE Initialises everything. Reads an ACD (AJAX Command Definition) file DE prompts the user for any missing information, reads all sequences DE and other input into local structures which applications can request. XX PN [1] PA r pgm const char* PD Application name, used as the name PD of the ACD file PX PN [2] PA r argc ajint PD Number of arguments provided on the command line, PD usually passed as-is by the calling application. PX PN [3] PA r argv char* const[] PD Actual arguments as an array of text. PX PN [4] PA r package const char* PD Package name, used to find the ACD file PX PN [5] PA r packversion const char* PD Package version PX RT void RD RX // void ajAcdInitPV(const char *pgm, ajint argc, char * const argv[], const char *package, const char *packversion) { static AjPFile acdFile = NULL; static AjPStr acdLine = NULL; static AjPStr acdRoot = NULL; static AjPStr acdRootInst = NULL; static AjPStr acdPack = NULL; static AjPStr acdPackRoot = NULL; static AjPStr acdPackRootName = NULL; static AjPStr acdUtilRoot = NULL; AjPStr applversion = NULL; AjPStr versionstr = NULL; AjPStr comment = NULL; AjPStrTok tokenhandle = NULL; char white[] = " \t\n\r"; AjPList acdListWords = NULL; AjPList acdListCount = NULL; AjPStr tmpword = NULL; /* words to add to acdListWords */ ajint i; ajint *k = NULL; ajint *kc = NULL; ajuint *kp = NULL; size_t pos; acdProgram = ajStrNewC(pgm); acdSecList = ajListstrNew(); acdSecTable = ajTablestrNewCase(50); acdLog("testing acdprompts"); if(ajNamGetValueC("acdprompts", &acdTmpStr)) { acdLog("acdprompts '%S'", acdTmpStr); if(ajStrToInt(acdTmpStr, &i)) acdPromptTry = i; if(acdPromptTry < 1) acdPromptTry = 1; acdLog("acdPromptTry %d", acdPromptTry); } if(ajNamGetValueC("acdlog", &acdTmpStr)) ajStrToBool(acdTmpStr, &acdDoLog); if(ajNamGetValueC("acdwarnrange", &acdTmpStr)) ajStrToBool(acdTmpStr, &acdDoWarnRange); /* pre-parse the command line for special options */ acdArgsScan(argc, argv); ajDebug("ajAcdInitPV pgm '%s' package '%s'\n", pgm, package); ajDebug(" version '%S' system '%S'\n", ajNamValueVersion(), ajNamValueSystem()); /* open the command definition file */ if(*package) ajStrAssignC(&acdPackName, package); if(*packversion) ajStrAssignC(&acdPackVersion, packversion); ajStrAssignS(&acdPack, ajNamValuePackage()); ajStrAssignS(&acdRootInst, ajNamValueInstalldir()); ajDirnameFix(&acdRootInst); if(ajNamGetValueC("acdroot", &acdRoot)) { /* _acdroot variable defined */ ajDirnameFix(&acdRoot); ajFmtPrintS(&acdFName, "%S%s.acd", acdRoot, pgm); acdLog("Trying acdfile '%S' (acdroot)\n", acdFName); acdFile = ajFileNewInNameS(acdFName); } else if(*package) { /* separate package */ /* ajFmtPrintS(&acdFName, "%Sshare/%S/acd/%s.acd", acdRootInst, acdPack, pgm);*/ ajFmtPrintS(&acdFName, "%Sshare/EMBOSS/acd/%s.acd", acdRootInst, pgm); acdLog("Trying acdfile '%S' (package '%s' installed)\n", acdFName, package); acdFile = ajFileNewInNameS(acdFName); if(!acdFile) { acdLog("acdfile '%S' not opened\n", acdFName); ajStrAssignC(&acdPack, package); /* package name for acdInitPV */ ajStrFmtLower(&acdPack); ajStrAssignS(&acdPackRootName, acdPack); ajStrAppendC(&acdPackRootName, "acdroot"); if(ajNamGetValueS(acdPackRootName, &acdPackRoot)) { ajDirnameFix(&acdPackRoot); ajFmtPrintS(&acdFName, "%S%s.acd", acdPackRoot, pgm); acdLog("Trying acdfile '%S' (package %sacdroot)\n", acdFName, package); } else { ajStrAssignS(&acdPackRoot, ajNamValueRootdir()); ajDirnameUp(&acdPackRoot); ajFmtPrintS(&acdFName, "%Sembassy/%S/emboss_acd/%s.acd", acdPackRoot, acdPack, pgm); acdLog("Trying acdfile '%S' (package %s source)\n", acdFName, package); } acdFile = ajFileNewInNameS(acdFName); } } else { /* main package */ ajFmtPrintS(&acdFName, "%Sshare/%S/acd/%s.acd", acdRootInst, acdPack, pgm); acdLog("Trying acdfile '%S' (installed)\n", acdFName); acdFile = ajFileNewInNameS(acdFName); if(!acdFile) { acdLog("acdfile '%S' not opened\n", acdFName); ajStrAssignC(&acdPack, "emboss"); if(ajNamGetValueC("acdutilroot", &acdUtilRoot)) { ajDirnameFix(&acdUtilRoot); ajFmtPrintS(&acdFName, "%S%s.acd", acdUtilRoot, pgm); acdLog("Trying acdfile '%S' (acdutilroot)\n", acdFName); acdFile = ajFileNewInNameS(acdFName); } } if(!acdFile) { acdLog("acdfile '%S' not opened\n", acdFName); ajStrAssignS(&acdRoot, ajNamValueRootdir()); ajDirnameFix(&acdRoot); ajFmtPrintS(&acdFName, "%Sacd/%s.acd", acdRoot, pgm); acdLog("Trying acdfile '%S' (original main source)\n", acdFName); acdFile = ajFileNewInNameS(acdFName); if(!acdFile) { acdLog("acdfile '%S' not opened\n", acdFName); } } } if(!acdFile) /* test by nofile.acd */ acdError("ACD file not opened\n"); /* read the whole file into a string [change to use a list later] */ acdListWords = ajListstrNew(); acdListCount = ajListNew(); acdListComments = ajListstrNew(); acdListCommentsCount = ajListNew(); acdListCommentsColumn = ajListNew(); while(ajReadlineTrim(acdFile, &acdLine)) { AJNEW0(k); *k = (ajuint) ajListGetLength(acdListWords); ajListPushAppend(acdListCount, k); if(ajStrCutCommentsRestpos(&acdLine, &comment, &pos)) { tokenhandle = ajStrTokenNewC(acdLine, white); while(ajStrTokenNextParse(&tokenhandle, &tmpword)) { if(ajStrGetLen(tmpword)) /* nothing before first whitespace */ { ajListstrPushAppend(acdListWords, tmpword); tmpword = NULL; } else { ajStrDel(&tmpword); } } ajStrTokenDel(&tokenhandle); ajStrDel(&tmpword); /* empty token at the end */ } if (ajStrGetLen(comment)) { ajListstrPushAppend(acdListComments, comment); comment = NULL; AJNEW(kc); *kc = (ajuint) ajListGetLength(acdListWords); ajListPushAppend(acdListCommentsCount, kc); kc = NULL; AJNEW(kp); *kp = pos; ajListPushAppend(acdListCommentsColumn, kp); kp = NULL; } } ajFileClose(&acdFile); ajStrDel(&acdLine); AJNEW0(k); *k = (ajuint) ajListGetLength(acdListWords); ajListPushAppend(acdListCount, k); acdCodeInit(); acdKnowntypeInit(); /* Parse the input to set the initial definitions */ acdParse(acdListWords, acdListCount); ajListstrFreeData(&acdListWords); ajListFreeData(&acdListCount); if(acdDoVersion) { ajFmtPrintS(&versionstr, "EMBOSS:%s", VERSION); if(ajStrGetLen(versionstr) < 14) ajStrAppendC(&versionstr, ".0"); if(ajStrGetLen(acdPackVersion)) ajFmtPrintAppS(&versionstr, " %S:%S", acdPackName, acdPackVersion); acdAttrResolve(acdApplAcd, "versionnumber", &applversion); if(ajStrGetLen(applversion)) { ajFmtPrintAppS(&versionstr, " %s:%S", pgm, applversion); ajStrDel(&applversion); } ajUserDumpS(versionstr); ajStrDel(&versionstr); ajExit(); } if(acdDoPretty || acdDoValid) ajExit(); /* Fill in incomplete information like parameter numbers */ acdProcess(); AJCNEW0(acdParamSet, acdNParam+1); /* report on what we have so far */ acdListReport("Definitions in ACD file"); /* parse the command line and update the values */ acdArgsParse(argc, argv); /* report on what we have so far */ acdListReport("Results of parsing command line arguments"); /* set the true values and prompt for missing standard values */ if(acdDoTable || acdDoXsd || acdDoGalaxy) acdHelp(); acdSetAll(); /* report on what we have now */ acdListReport("Final results after setting values and prompting the user"); /* all done */ ajStrDel(&acdRoot); ajStrDel(&acdRootInst); ajStrDel(&acdPack); ajStrDel(&acdPackRoot); ajStrDel(&acdPackRootName); ajStrDel(&acdFName); ajStrDel(&comment); return; } ID acdStage TY static MO ajacd LB acd XX DE Tests next token to set the next parsing stage. XX PN [1] PA r token const AjPStr PD Current token PX RT AcdEStage RD Stage enumerated code RX // static AcdEStage acdStage(const AjPStr token) { ajint i; ajint ifound=0; AcdEStage j=BAD_STAGE; AjPStr ambigList = NULL; ambigList = ajStrNew(); if(!ajStrGetLen(token)) return BAD_STAGE; i = QUAL_STAGE + 1; while(acdKeywords[i].Name) /* ACD keywords */ { if(ajStrMatchC(token, acdKeywords[i].Name)) return acdKeywords[i].Stage; if(ajCharPrefixS(acdKeywords[i].Name, token)) { ifound++; j = acdKeywords[i].Stage; acdAmbigAppC(&ambigList, acdKeywords[i].Name); } i++; } i = 0; while(acdType[i].Name) /* ACD types as qualifiers */ { if(ajStrMatchC(token, acdType[i].Name)) return QUAL_STAGE; if(ajCharPrefixS(acdType[i].Name, token)) { ifound++; j = QUAL_STAGE; acdAmbigAppC(&ambigList, acdType[i].Name); } i++; } if(ifound == 1) { if (acdDoValid) acdWarn("Abbreviated stage '%S' (%S)", token, ambigList); return j; } if(ifound > 1) { /* test ambigtype.acd */ acdError("ambiguous acd type %S (%S)", token, ambigList); ajStrDel(&ambigList); } ajStrDel(&ambigList); return BAD_STAGE; } ID acdParse TY static MO ajacd LB acd XX DE Parse the command line definition and build data structures from it. XX PN [1] PA u listwords AjPList PD List of words (as strings) PD from ACD file. List empty on completion PX PN [2] PA u listcount AjPList PD List of word count before each line. PD List empty on completion PX RT void RD RX // static void acdParse(AjPList listwords, AjPList listcount) { AjPStr acdStrType = NULL; AjPStr acdStrAlias = NULL; AjPStr acdStrValue = NULL; AjPStr secname = NULL; ajint linecount = 0; ajint lineword = 0; ajint *iword = NULL; ajint *icword = NULL; ajint *icpos = NULL; AjPStr cmtstr = NULL; AjPTime today = NULL; /* initialise the global line number counter to zero */ acdLineNum = 0; if(acdDoValid) { if(ajNamGetValueC("edam", &acdEdamPath)) { acdEdamFile = ajFileNewInNameS(acdEdamPath); if(acdEdamFile) acdEdam = ajObodataParseObofile(acdEdamFile, "none"); } } while(ajListGetLength(acdListCommentsCount) && !acdCmtWord) { ajListPeek(acdListCommentsCount, (void**) &icword); acdCmtWord = *icword; if(!acdCmtWord) { ajStrDel(&cmtstr); ajListPop(acdListCommentsCount, (void**) &icword); ajListPop(acdListCommentsColumn, (void**) &icpos); ajListstrPop(acdListComments, &cmtstr); acdPrettyComment(cmtstr); AJFREE(icword); AJFREE(icpos); } } if(ajStrGetLen(cmtstr)) { acdPretty("\n"); ajStrDel(&cmtstr); } while(ajListGetLength(listcount) && (!lineword)) { ajListPeek(listcount, (void**) &iword); if(*iword) lineword = *iword; else { ajListPop(listcount, (void**) &iword); linecount++; acdLineNum = linecount - 1; AJFREE(iword); } } lineword = 0; acdWordNum = 0; while(ajListGetLength(listwords)) { acdWordNextName(listwords, &acdStrType); while(ajListGetLength(listcount) && (lineword < acdWordNum)) { ajListPop(listcount, (void**) &iword); lineword = *iword; linecount++; acdLineNum = linecount - 1; AJFREE(iword); } acdCurrentStage = acdStage(acdStrType); if(acdWordNum == 1) if(acdCurrentStage != APPL_STAGE) /* test noappl.acd */ acdError("Application definition required at start"); switch(acdCurrentStage) { case APPL_STAGE: if(acdWordNum != 1) acdError("Application definition allowed only at start"); /* application: then the appl name */ acdParseName(listwords, &acdStrName); if (!ajStrMatchS(acdStrName, acdProgram)) acdError("Application name '%S' does not match filename '%S'", acdStrName, acdProgram); acdNewCurr = acdNewAppl(acdStrName); acdApplAcd = acdNewCurr; acdWordNum++; /* add one for '[' */ acdPretty("%s: %S [\n", acdKeywords[acdCurrentStage].Name, acdStrName); acdWordNum--; /* not yet parsed '[' */ acdParseAttributes(acdNewCurr, listwords); acdAttrToBool(acdNewCurr, "wrapper", ajFalse, &acdWrapper); acdValidAppl(acdNewCurr); /* automatic $(today) variable */ ajStrAssignC(&acdStrName, "today"); today = ajTimeNewToday(); ajFmtPrintS(&acdStrValue, "%D", today); ajTimeDel(&today); acdNewCurr = acdNewVar(acdStrName); acdSetVarDef(acdNewCurr, acdStrValue); break; /* type: qualname alias[ attr: value ] ** ** The alias name is optional (defaults to the qualifier name) ** The [] are required so the token can be detected. Attributes ** are defined for each "type", as are associated ** qualifiers. There is no distinction between them here. The ** difference is that the qualifier values are defaults which ** can be overridden on the command line */ case QUAL_STAGE: acdParseAlpha(listwords, &acdStrName); if(acdNotLeftB(listwords)) { /* test badalias.acd */ if(!acdWordNextLower(listwords, &acdStrAlias) || !ajStrIsAlpha(acdStrAlias)) acdError("Bad syntax qualifier alias name '%S'", acdStrAlias); } else /* we have an alternate name before the '[' */ ajStrAssignS(&acdStrAlias, acdStrName); acdNewCurr = acdNewQual(acdStrName, acdStrAlias, &acdStrType); acdWordNum++; /* add one for '[' */ if(!ajStrMatchS(acdStrName, acdStrAlias)) acdPretty("\n%S: %S %S [\n", acdStrType, acdStrName, acdStrAlias); else acdPretty("\n%S: %S [\n", acdStrType, acdStrName); acdWordNum--; /* not yet parsed '[' */ acdParseAttributes(acdNewCurr, listwords); acdValidQual(acdNewCurr); break; case SEC_STAGE: /* section: name [ attrlist ] */ acdParseName(listwords, &acdStrName); acdNewCurr = acdNewSec(acdStrName); acdWordNum++; /* add one for '[' */ acdPretty("\n%s: %S [\n", acdKeywords[acdCurrentStage].Name, acdStrName); acdWordNum--; /* not yet parsed '[' */ acdParseAttributes(acdNewCurr, listwords); acdValidSection(acdNewCurr); acdPrettyShift(); break; case ENDSEC_STAGE: /* endsection: name */ /* remove from list of current sections */ acdParseName(listwords, &acdStrName); acdNewCurr = acdNewEndsec(acdStrName); acdValidSection(acdNewCurr); acdPrettyUnShift(); acdPretty("\n%s: %S\n", acdKeywords[acdCurrentStage].Name, acdStrName); break; /* catch-all for failed parsing */ case VAR_STAGE: /* then the variable name and the value */ acdParseName(listwords, &acdStrName); ajStrAssignS(&acdStrValue, acdParseValue(listwords)); acdNewCurr = acdNewVar(acdStrName); acdSetVarDef(acdNewCurr, acdStrValue); acdPretty("\n%s: %S \"%S\"\n", acdKeywords[acdCurrentStage].Name, acdStrName, acdStrValue); break; case REL_STAGE: /* relation: name [ attrlist ] */ acdParseName(listwords, &acdStrName); acdNewCurr = acdNewRel(acdStrName); acdWordNum++; /* add one for '[' */ acdPretty("\n%s: %S [\n", acdKeywords[acdCurrentStage].Name, acdStrName); acdWordNum--; /* not yet parsed '[' */ acdParseAttributes(acdNewCurr, listwords); acdValidRelation(acdNewCurr); acdPrettyShift(); break; case BAD_STAGE: /* test badstage.acd */ default: /* Fatal - should never happen */ acdError("Unrecognized token '%S'\n", acdStrType); break; } } acdLog("-- All Done --\n"); acdLog("-- All Done : acdSecList length %d\n", ajListstrGetLength(acdSecList)); acdLineNum = linecount; if(ajListstrGetLength(acdSecList)) /* fatal error, unclosed section(s) */ { while(ajListstrPop(acdSecList, &secname)) { ajDebug("Section '%S' has no endsection\n", secname); ajErr("Section '%S' has no endsection", secname); /* fails below */ ajStrDel(&secname); } acdLog("Unclosed sections in ACD file\n"); acdError("Unclosed sections in ACD file"); /* test noendsec.acd */ } acdPrettyClose(); ajStrDel(&acdStrName); /* the global string ... no longer needed */ ajStrDel(&acdStrAlias); ajStrDel(&acdStrType); ajStrDel(&acdStrValue); ajListstrFreeData(&acdSecList); acdLineNum = 0; while(ajListGetLength(listcount)) { ajListPop(listcount, (void**) &iword); AJFREE(iword); } return; } ID acdParseValue TY static MO ajacd LB acd XX DE Uses ajStrTok to complete a (possibly) quoted value. DE Note that ajStrTok has a stored internal copy of the text string DE which is set up at the start of acdParse and is being used here. DE DE Quotes can be single or double. DE DE The early versions also allowed any kind of parentheses, DE depending on the first character of the next token examined. DE This is now obsolete, to simplify the syntax and to allow DE future reuse of parentheses. XX PN [1] PA u listwords AjPList PD List of strings for each word PD to be parsed PX RT AjPStr RD String containing next value from list RX // static AjPStr acdParseValue(AjPList listwords) { AjPStr strp=NULL; char endq[]=" "; ajint iquote; char *cq; AjBool done = ajFalse; const char *quotes = "\"'"; const char *endquotes = "\"'"; acdParseQuotes = ajFalse; if(!acdWordNext(listwords, &strp)) /* test: novalue.acd */ acdErrorAcd(acdNewCurr, "Unexpected end of file, attribute value not found\n"); cq = strchr(quotes, ajStrGetCharFirst(strp)); if(!cq) /* no quotes, simple return */ { ajStrAssignS(&acdParseReturn, strp); ajStrDel(&strp); return acdParseReturn; } acdParseQuotes = ajTrue; /* quote found: parse up to closing quote then strip white space */ iquote = cq - quotes; endq[0] = endquotes[iquote]; ajStrCutStart(&strp, 1); ajStrDel(&acdParseReturn); while(!done) { if(ajStrSuffixC(strp, endq)) { /* check for trailing quotes */ ajStrCutEnd(&strp, 1); done = ajTrue; } if(ajStrGetLen(strp)) { if(ajStrGetLen(acdParseReturn)) { ajStrAppendC(&acdParseReturn, " "); ajStrAppendS(&acdParseReturn, strp); } else ajStrAssignS(&acdParseReturn, strp); } if(!done) if(!acdWordNext(listwords, &strp)) /* test noquote.acd */ acdErrorAcd(acdNewCurr, "Unexpected end of file, no closing quote\n"); } ajStrDel(&strp); return acdParseReturn; } ID acdWordNext TY static MO ajacd LB acd XX DE Returns the next word from a list XX PN [1] PA u listwords AjPList PD List of words parsed from ACD file PX PN [2] PA w pword AjPStr* PD Next word from the list PX RT AjBool RD ajTrue on success RX // static AjBool acdWordNext(AjPList listwords, AjPStr* pword) { ajStrDel(pword); if(ajListstrPop(listwords, pword)) { acdWordNum++; return ajTrue; } ajStrAssignClear(pword); return ajFalse; } ID acdWordNextLower TY static MO ajacd LB acd XX DE Returns the next word from a list, in lower case. XX PN [1] PA u listwords AjPList PD List of words parsed from ACD file PX PN [2] PA w pword AjPStr* PD Next word from the list PX RT AjBool RD ajTrue on success RX // static AjBool acdWordNextLower(AjPList listwords, AjPStr* pword) { if(acdWordNext(listwords, pword)) { if(!ajStrIsLower(*pword)) { acdWarn("Automatically converting '%S' to lower case", *pword); ajStrFmtLower(pword); } return ajTrue; } return ajFalse; } ID acdWordNextName TY static MO ajacd LB acd XX DE Returns the next word from a list, in lower case DE DE This must be an ACD name (type or attribute) alphabetic only, DE with a trailing ':' XX PN [1] PA u listwords AjPList PD List of words parsed from ACD file PX PN [2] PA w pword AjPStr* PD Next word from the list PX RT AjBool RD ajTrue on success RX // static AjBool acdWordNextName(AjPList listwords, AjPStr* pword) { if(acdWordNext(listwords, pword)) { if(ajStrGetCharLast(*pword) != ':') { if(ajStrGetCharFirst(*pword) == ':')/* test nocolon.acd */ acdError("Found ':' at start of word '%S'", *pword); else if(ajStrFindAnyK(*pword, ':') > 0) acdError("Expected space missing after ':' in '%S'", *pword); else acdError("Expected ':' not found after '%S'", *pword); return ajFalse; } ajStrCutEnd(pword, 1); if(!ajStrIsAlpha(*pword)) return ajFalse; ajStrFmtLower(pword); return ajTrue; } return ajFalse; } ID acdParseName TY static MO ajacd LB acd XX DE Returns the next word from a list, in lower case. DE DE This must be an ACD name (alphanumeric allowed as this is not used DE for qualifier names) XX PN [1] PA u listwords AjPList PD List of words parsed from ACD file PX PN [2] PA w pword AjPStr* PD Next word from the list PX RT void RD RX // static void acdParseName(AjPList listwords, AjPStr* pword) { if(acdWordNextLower(listwords, pword)) if(ajStrIsAlnum(*pword)) return; /* test noapplname.acd badapplname.acd */ acdError("Bad or missing %s name '%S'", acdKeywords[acdCurrentStage].Name, *pword); return; } ID acdParseAlpha TY static MO ajacd LB acd XX DE Returns the next word from a list, in lower case. DE DE This must be an alphabetic word, no numbers or underscores allowed. XX PN [1] PA u listwords AjPList PD List of words parsed from ACD file PX PN [2] PA w pword AjPStr* PD Next word from the list PX RT void RD RX // static void acdParseAlpha(AjPList listwords, AjPStr* pword) { if(acdWordNextLower(listwords, pword)) if(ajStrIsAlpha(*pword)) return; /* test noqualname.acd badqualname.acd */ acdError("Bad or missing %s alphabetic name '%S'", acdKeywords[acdCurrentStage].Name, *pword); return; } ID acdNotLeftB TY static MO ajacd LB acd XX DE Tests the start of the next word in the list for '[' at the start DE DE Does not remove the '[' XX PN [1] PA r listwords const AjPList PD List of words parsed from ACD file PX RT AjBool RD ajTrue if start of string does not match '[' RX // static AjBool acdNotLeftB(const AjPList listwords) { char ch; AjPStr pstr = NULL; if(!ajListstrPeek(listwords, &pstr)) return ajFalse; ch = ajStrGetCharFirst(pstr); if(ch == '[') return ajFalse; /* do not delete pstr - we only peeked */ return ajTrue; } ID acdIsLeftB TY static MO ajacd LB acd XX DE Tests the start of the next word in the list for '[' at the start XX PN [1] PA u listwords AjPList PD List of words parsed from ACD file PX RT AjBool RD ajTrue if start of string matches '[' RX // static AjBool acdIsLeftB(AjPList listwords) { char ch; AjPStr teststr = NULL; AjPStr pstr = NULL; if(!ajListstrPeek(listwords, &teststr)) return ajFalse; ch = ajStrGetCharFirst(teststr); if(ch == '[') { ajStrCutStart(&teststr, 1); /* trim the leading '[' in the list */ if(!ajStrGetLen(teststr)) { /* only the '[' so remove from the list */ acdWordNext(listwords, &pstr); /* must succeed - Peeked */ ajStrDel(&pstr); /* empty - ignored - so delete */ teststr = NULL; } return ajTrue; } /* do not delete teststr - it was only peeked - deleted as pstr */ return ajFalse; } ID acdIsRightB TY static MO ajacd LB acd XX DE Tests for ']' to look for ascent to a higher level of parsing. DE DE Tests the end of the current string DE If that fails, tests the start of the next word in the list. DE DE Afterwards, the value of pstr is the last word with any ']' removed XX PN [1] PA w pstr AjPStr* PD String which has a trailing ']' removed if found PX PN [2] PA u listwords AjPList PD List of remaining words to be parsed PX RT AjBool RD ajTrue if end of string matches ']' RX // static AjBool acdIsRightB(AjPStr* pstr, AjPList listwords) { AjPStr teststr = NULL; char ch; if(*pstr && !acdParseQuotes) { ch = ajStrGetCharLast(*pstr); if(ch == ']') /* test input pstr value for ']' at end */ { ajStrCutEnd(pstr, 1); return ajTrue; } } /* go on to the next word in the list */ if(!ajListstrPeek(listwords, &teststr)) /* leftend.acd valend.acd */ acdErrorAcd(acdNewCurr, "End of file looking for ']'"); ch = ajStrGetCharFirst(teststr); if(ch == ']') /* next word starts with ']' */ { ajStrCutStart(&teststr, 1); /* trim the word - in the list */ if(!ajStrGetLen(teststr)) /* only "]" so delete it */ { acdWordNext(listwords, &acdTmpStr); /* works - used ajListstrPeek */ teststr = NULL; } return ajTrue; } return ajFalse; } ID acdParseAttributes TY static MO ajacd LB acd XX DE Parse the attribute list for an ACD type XX PN [1] PA r acd const AcdPAcd PD Acd object PX PN [2] PA u listwords AjPList PD List of parsed words PX RT void RD RX // static void acdParseAttributes(const AcdPAcd acd, AjPList listwords) { AjPStr strAttr = NULL; AjPStr strValue = NULL; AjPStr strFixValue = NULL; AjBool done=ajFalse; ajint i=0; if(!acdIsLeftB(listwords)) /* test noleftappl.acd noleftsec.acd */ /* noleftq.acd */ acdErrorAcd(acdNewCurr, "Failed to find '[' for %s %S\n", acdKeywords[acdCurrentStage].Name, acdStrName); acdPrettyShift(); done = acdIsRightB(&strAttr, listwords); /* could be [ ] */ /* continue parsing until we reach a true closing ']' character */ while(!done) { if(!acdWordNextName(listwords, &strAttr)) /* test: noattname.acd */ acdErrorAcd(acdNewCurr, "Bad or missing attribute name '%S'", strAttr); for (i=0;acdAttrAlias[i].OldName;i++) if (ajStrMatchC(strAttr, acdAttrAlias[i].OldName)) { ajStrAssignC(&strAttr, acdAttrAlias[i].NewName); break; } ajStrAssignS(&strValue, acdParseValue(listwords)); done = acdIsRightB(&strValue, listwords); /* will this be last pair? */ ajStrAssignS(&strFixValue, strValue); acdTextFormat(&strFixValue); if(acdCurrentStage == QUAL_STAGE) acdSet(acd, &strAttr, strFixValue); else acdSetKey(acd, &strAttr, strFixValue); if(done) acdWordNum--; acdPrettyWrap(ajStrGetLen(strAttr)+3, "%S: \"%S\"", strAttr, strValue); if(done) acdWordNum++; } acdPrettyUnShift(); acdPretty("]\n"); ajStrDel(&strAttr); ajStrDel(&strValue); ajStrDel(&strFixValue); return; } ID acdNewAppl TY static MO ajacd LB acd XX DE Constructor front end for an application ACD object. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX RT AcdPAcd RD ACD application object for name. RX // static AcdPAcd acdNewAppl(const AjPStr name) { AcdPAcd acd; AcdPAcd qacd; AcdPAcd saveqacd = NULL; AcdPQual quals; AjPStr qname = NULL; AjPStr qtype = NULL; static ajint firstcall = 1; static ajint ikey; ajint i; if(firstcall) { ikey = acdFindKeyC("application"); firstcall = 0; } i = 0; quals = acdQualAppl; if(quals) { while(quals[i].Name) { ajStrAssignC(&qname, quals[i].Name); ajStrAssignC(&qtype, quals[i].Type); /* qacd = acdNewQual(qname, qname, &qtype);*/ qacd = acdNewQualQual(qname, &qtype); if(*quals[i].Default) acdSetDefC(qacd, quals[i].Default); if(!i) saveqacd = qacd; /* save the location of the first one */ i++; } } acd = acdNewAcdKey(name, name, ikey); acd->Level = ACD_APPL; if(saveqacd) acd->AssocQuals = saveqacd; ajStrDel(&qname); ajStrDel(&qtype); return acd; } ID acdNewVar TY static MO ajacd LB acd XX DE Constructor front end for a variable ACD object. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX RT AcdPAcd RD ACD variable object for name. RX // static AcdPAcd acdNewVar(const AjPStr name) { AcdPAcd acd; static ajint firstcall = 1; static ajint ikey; if(firstcall) { ikey = acdFindKeyC("variable"); firstcall = 0; } acd = acdNewAcdKey(name, name, ikey); acd->Level = ACD_VAR; return acd; } ID acdNewRel TY static MO ajacd LB acd XX DE Constructor front end for a relation ACD object. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX RT AcdPAcd RD ACD variable object for name. RX // static AcdPAcd acdNewRel(const AjPStr name) { AcdPAcd acd; static ajint firstcall = 1; static ajint ikey; if(firstcall) { ikey = acdFindKeyC("relation"); firstcall = 0; } acdLog("acdNewRel '%S'\n", name); acd = acdNewAcdKey(name, name, ikey); acd->Level = ACD_RELATION; return acd; } ID acdNewSec TY static MO ajacd LB acd XX DE Constructor front end for a section ACD object. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX RT AcdPAcd RD ACD variable object for name. RX // static AcdPAcd acdNewSec(const AjPStr name) { AcdPAcd acd; static ajint firstcall = 1; static ajint ikey; AjPStr secname=NULL; AjPStr secfull=NULL; AjPStr secfullvalue=NULL; if(firstcall) { ikey = acdFindKeyC("section"); firstcall = 0; } acdLog("acdNewSec '%S' acdSecList length %d\n", name, ajListstrGetLength(acdSecList)); acd = acdNewAcdKey(name, name, ikey); acd->Level = ACD_SEC; ajStrAssignS(&secname, name); ajListstrPush(acdSecList, secname); acdValidSectionFull(&secfull); ajStrAssignS(&secfullvalue, name); acdLog("Full section '%S'\n", secfull); if (ajTablePut(acdSecTable, secfull, secfullvalue)) acdError("Duplicate section '%S'", name); acdLog("acdNewSec acdSecList push '%S' new length %d\n", secname, ajListstrGetLength(acdSecList)); return acd; } ID acdNewEndsec TY static MO ajacd LB acd XX DE Constructor front end for an end of section ACD object. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX RT AcdPAcd RD ACD variable object for name. RX // static AcdPAcd acdNewEndsec(const AjPStr name) { AcdPAcd acd; static ajint firstcall = 1; static ajint ikey; AjPStr secname=NULL; if(firstcall) { ikey = acdFindKeyC("endsection"); firstcall = 0; } acdLog("acdNewEndsec '%S' acdSecList length %d\n", name, ajListstrGetLength(acdSecList)); if(!ajListstrGetLength(acdSecList)) /* test endsecextra.acd */ { acdLog("Bad endsection '%S', not in a section\n", name); acdError("Bad endsection '%S', not in a section", name); } else { ajListstrPop(acdSecList, &secname); acdLog("Pop from acdSecList '%S' new length %d\n", secname, ajListstrGetLength(acdSecList)); if(!ajStrMatchS(name, secname)) /* test badendsec.acd */ { acdLog("Bad endsection '%S', current section is '%S\n'", name, secname); acdError("Bad endsection '%S', current section is '%S'", name, secname); } ajStrDel(&secname); } acd = acdNewAcdKey(name, name, ikey); acd->Level = ACD_ENDSEC; return acd; } ID acdNewQual TY static MO ajacd LB acd XX DE Constructor front end for a qualifier ACD object. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX PN [2] PA r token const AjPStr PD Qualifier name to be used on command line PX PN [3] PA u type AjPStr* PD Type of value to be defined. Expanded to full PD type name. PX RT AcdPAcd RD ACD parameter object for name. RX // static AcdPAcd acdNewQual(const AjPStr name, const AjPStr token, AjPStr* type) { AcdPAcd acd; AcdPAcd qacd; AcdPAcd vacd; AcdPAcd saveqacd = NULL; AcdPQual quals; AjPStr protName = NULL; AjPStr qname = NULL; AjPStr qtype = NULL; ajint itype; ajint i; itype = acdFindType(*type); ajStrAssignC(type, acdType[itype].Name); /* do any associated qualifiers first so they are already complete when we come to the parameter later in processing */ i = 0; quals = acdType[itype].Quals; /* any associated qualifiers for itype? */ if(quals) while(quals[i].Name) { ajStrAssignC(&acdQNameTmp, quals[i].Name); ajStrAssignC(&acdQTypeTmp, quals[i].Type); qacd = acdNewQualQual(acdQNameTmp, &acdQTypeTmp); if(*quals[i].Default) acdSetDefC(qacd, quals[i].Default); if(!i) saveqacd = qacd; /* save the location of the first one */ i++; } /* ** now set up the new parameter, and link in the list of qualifiers ** (if any) from earlier */ acdTestUnknown(name, token); acd = acdNewAcd(name, token, itype); acd->Level = ACD_QUAL; if(saveqacd) acd->AssocQuals = saveqacd; ajStrDel(&qname); ajStrDel(&qtype); /* ** For the first sequence, set the sequence type variable */ if(!ajStrGetLen(acdVarAcdProtein)) if((acdType[itype].Attr == acdAttrSeq) || (acdType[itype].Attr == acdAttrSeqall) || (acdType[itype].Attr == acdAttrSeqset) || (acdType[itype].Attr == acdAttrSeqsetall) || (acdType[itype].Attr == acdAttrFeatures)) { ajStrAssignC(&protName, "acdprotein"); ajFmtPrintS(&acdVarAcdProtein, "$(%S.protein)", name); vacd = acdNewVar(protName); acdSetVarDef(vacd, acdVarAcdProtein); ajDebug("Set acdprotein value '%S'\n", acdVarAcdProtein); ajStrDel(&protName); } ajStrDel(&protName); return acd; } ID acdNewQualQual TY static MO ajacd LB acd XX DE Constructor front end for an associated qualifier ACD object. XX PN [1] PA r name const AjPStr PD Qualifier name to be used on command line PX PN [2] PA u type AjPStr* PD Type of value to be defined. Expanded to full PD type name. PX RT AcdPAcd RD ACD parameter object for name. RX // static AcdPAcd acdNewQualQual(const AjPStr name, AjPStr* type) { AcdPAcd acd; ajint itype; itype = acdFindType(*type); ajStrAssignC(type, acdType[itype].Name); acdTestAssocUnknown(name); acd = acdNewAcd(name, name, itype); acd->Level = ACD_QUAL; acd->Assoc = ajTrue; return acd; } ID acdNewAcd TY static MO ajacd LB acd XX DE General constructor for a new ACD qualifier object. Initialises all values DE in the ACD structure as appropriate. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX PN [2] PA r token const AjPStr PD Qualifier name to be used on command line PX PN [3] PA r itype ajint PD Integer type of value to be defined PD as defined in acdFindType PX RT AcdPAcd RD ACD parameter object for name. RX // static AcdPAcd acdNewAcd(const AjPStr name, const AjPStr token, ajint itype) { ajint i; if(acdListLast) acdListLast = AJNEW0(acdListLast->Next); else acdListLast = AJNEW0(acdList); acdListLast->LineNum = acdLineNum; ajStrAssignS(&acdListLast->Name, name); ajStrAssignS(&acdListLast->Token, token); acdListLast->Type = itype; ++(*acdType[itype].UseCount); ++(*acdType[itype].UseClassCount); /* we do NAttr and AttrStr explicitly for clarity, */ /* though they are 0 and NULL from the AJNEW0 */ switch(acdCurrentStage) { case QUAL_STAGE: acdListLast->NAttr = acdAttrCount(itype); break; default: acdListLast->NAttr = 0; break; } if(acdListLast->NAttr) { acdListLast->AttrStr = AJCALLOC(acdListLast->NAttr, sizeof(AjPStr)); for(i = 0; i < acdListLast->NAttr; i++) acdListLast->AttrStr[i] = ajStrNew(); } else acdListLast->AttrStr = NULL; acdListLast->DefStr = AJCALLOC(nDefAttr, sizeof(AjPStr)); for(i = 0; i < nDefAttr; i++) acdListLast->DefStr[i] = ajStrNew(); acdListLast->Defined = ajFalse; acdListLast->Assoc = ajFalse; acdListLast->ValStr = NULL; return acdListLast; } ID acdNewAcdKey TY static MO ajacd LB acd XX DE General constructor for a new ACD general object. Initialises all values DE in the ACD structure as appropriate. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX PN [2] PA r token const AjPStr PD Qualifier name to be used on command line PX PN [3] PA r ikey ajint PD Integer type of value to be defined PD as defined in acdFindKey PX RT AcdPAcd RD ACD parameter object for name. RX // static AcdPAcd acdNewAcdKey(const AjPStr name, const AjPStr token, ajint ikey) { ajint i; if(acdListLast) acdListLast = AJNEW0(acdListLast->Next); else acdListLast = AJNEW0(acdList); acdListLast->Next = NULL; acdListLast->LineNum = acdLineNum; ajStrAssignS(&acdListLast->Name, name); ajStrAssignS(&acdListLast->Token, token); acdListLast->PNum = 0; acdListLast->Level = ACD_APPL; acdListLast->Type = ikey; switch(acdCurrentStage) { case APPL_STAGE: acdListLast->NAttr = acdAttrKeyCount(ikey); break; case VAR_STAGE: acdListLast->NAttr = acdAttrKeyCount(ikey); break; case SEC_STAGE: acdListLast->NAttr = acdAttrKeyCount(ikey); break; default: acdListLast->NAttr = 0; break; } if(acdListLast->NAttr) { acdListLast->AttrStr = AJCALLOC(acdListLast->NAttr, sizeof(AjPStr)); for(i = 0; i < acdListLast->NAttr; i++) acdListLast->AttrStr[i] = ajStrNew(); } else acdListLast->AttrStr = NULL; acdListLast->DefStr = NULL; acdListLast->SAttr = 0; acdListLast->SetAttr = NULL; acdListLast->SetStr = NULL; acdListLast->Defined = ajFalse; acdListLast->Assoc = ajFalse; acdListLast->AssocQuals = NULL; acdListLast->ValStr = NULL; acdListLast->Value = NULL; return acdListLast; } ID acdDel TY static MO ajacd LB acd XX DE General destructor for any ACD object. XX PN [1] PA d Pacd AcdPAcd* PD Acd object PX RT void RD RX // static void acdDel(AcdPAcd *Pacd) { AcdPAcd pa = *Pacd; ajint i; if(pa->AttrStr) { for(i = 0; i < pa->NAttr; i++) ajStrDel(&pa->AttrStr[i]); AJFREE(pa->AttrStr); } if(pa->DefStr) { for(i = 0; i < nDefAttr; i++) ajStrDel(&pa->DefStr[i]); AJFREE(pa->DefStr); } if(pa->SetStr) { for(i = 0; i < pa->SAttr; i++) ajStrDel(&pa->SetStr[i]); AJFREE(pa->SetStr); } /* for variables and relations, clear the value */ /*if(pa->Level ==ACD_VAR || pa->Level == ACD_RELATION ) ajStrDel(&pa->Value); else if(!pa->PassByRef)*/ if(pa->Assoc && ajCharMatchC(acdType[pa->Type].Name,"string")) { ajStrDel((AjPStr*)&pa->Value); } else if(pa->Level == ACD_QUAL || pa->Level == ACD_PARAM) { if(!acdType[pa->Type].PassByRef) { AJFREE(pa->Value); } else if(pa->RefPassed != REF_ALL) /* pass-by-ref but never passed */ { if(pa->RefPassed == REF_NONE) { (*acdType[pa->Type].TypeDel)(&pa->Value); } else { AJFREE(pa->Value); } } } ajStrDel(&pa->Name); ajStrDel(&pa->Token); ajStrDel(&pa->StdPrompt); ajStrDel(&pa->OrigStr); ajStrDel(&pa->ValStr); AJFREE(*Pacd); return; } ID acdTestUnknown TY static MO ajacd LB acd XX DE Makes sure that a name, token and pnum do not match any DE current ACD object. DE DE Aborts the program with a fatal error in case of problems. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX PN [2] PA r alias const AjPStr PD Qualifier name to be used on command line PX RT void RD RX // static void acdTestUnknown(const AjPStr name, const AjPStr alias) { AcdPAcd pa; pa = acdFindAcdTest(name, alias); if(!pa) return; if(ajStrMatchS(name, alias)) acdErrorAcd(pa, "Name '%S' not unique at line %d\n", name, acdLineNum); else acdErrorAcd(pa, "Name/Alias '%S'/'%S' not unique at line %d\n", name, alias, acdLineNum); return; } ID acdCountType TY static MO ajacd LB acd XX DE Counts number of qualifiers with a given type. XX PN [1] PA r type const char* PD ACD type PX RT ajint RD Number of qualifiers of this type RX // static ajint acdCountType(const char* type) { ajint ret = 0; AcdPAcd pa; ajint itype = 0; itype = acdFindTypeC(type); for(pa=acdList; pa; pa=pa->Next) { if(pa->Type == itype) ret++; } return ret; } ID acdTestAssocUnknown TY static MO ajacd LB acd XX DE Makes sure that a name does not match any known ACD object name or token DE for all associated qualifiers. DE DE Aborts the program with a fatal error in case of problems. XX PN [1] PA r name const AjPStr PD Name or token name PX RT void RD RX // static void acdTestAssocUnknown(const AjPStr name) { AcdPAcd pa; for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; if(!pa->Assoc &&(ajStrMatchS(pa->Name, name) || ajStrMatchS(pa->Token, name))) { if(ajStrMatchS(pa->Name, pa->Token)) /* test: dupassoc.acd */ acdErrorAcd(pa, "Associated qualifier '%S' clashes with '%S' " "in ACD file\n", name, pa->Name); else acdErrorAcd(pa, /* test: dupassoc2.acd */ "Associated qualifier '%S' clashes with '%S'/'%S' " "in ACD file\n", name, pa->Name, pa->Token); break; } } return; } ID acdFindAcd TY static MO ajacd LB acd XX DE Locates an ACD object by name, token and parameter number. XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX PN [2] PA r token const AjPStr PD Qualifier name to be used on command line PX RT AcdPAcd RD ACD object or NULL if not found RX // static AcdPAcd acdFindAcd(const AjPStr name, const AjPStr token) { AcdPAcd pa; AjBool sametoken = ajFalse; sametoken = ajStrMatchS(name, token); acdLog("acdFindAcd ('%S', '%S', %d)\n", name, token); for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; if(ajStrMatchS(pa->Name, name)) { acdLog("..found '%S' %d\n", pa->Name, pa->PNum); return pa; } if(ajStrMatchS(pa->Token, name)) { acdLog("..found '%S' %d\n", pa->Name, pa->PNum); return pa; } if(!sametoken) continue; if(ajStrMatchS(pa->Name, token)) { acdLog("..found '%S' %d\n", pa->Name, pa->PNum); return pa; } if(ajStrMatchS(pa->Token, token)) { acdLog("..found '%S' %d\n", pa->Name, pa->PNum); return pa; } } return NULL; } ID acdFindAcdTest TY static MO ajacd LB acd XX DE Locates an ACD object by name, and (if different) by token. DE DE Tests for unique 6 character prefix and issues a warning if DE a clash is found with any already defined qualifier. DE DE All other tests are the same as in acdFindAcd XX PN [1] PA r name const AjPStr PD Token name to be used by applications PX PN [2] PA r token const AjPStr PD Qualifier name to be used on command line PX RT AcdPAcd RD ACD object or NULL if not found RX // static AcdPAcd acdFindAcdTest(const AjPStr name, const AjPStr token) { AcdPAcd savepa = NULL; AcdPAcd pa; AjBool usetoken = ajFalse; ajuint minunique=7; ajStrAssignSubS(&acdPrefName, name, 0, minunique-1); usetoken = !ajStrMatchS(name, token); if(usetoken) { ajStrAssignSubS(&acdPrefToken, token, 0, minunique-1); acdLog("acdFindAcdTest ('%S' ['%S'], '%S' ['%S'])\n", name, acdPrefName, token, acdPrefToken); } else { acdLog("acdFindAcdTest ('%S' ['%S'])\n", name, acdPrefName); } for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) { if(ajStrMatchS(pa->Name, name)) acdWarn("Qualifier '%S' matches known section '%S'", name, pa->Name); continue; } if(acdIsAtype(pa)) { if(ajStrMatchS(pa->Name, name)) acdWarn("Qualifier '%S' matches application name '%S'", name, pa->Name); continue; } if(acdIsVtype(pa)) { if(ajStrMatchS(pa->Name, name)) acdWarn("Qualifier '%S' matches variable name '%S'", name, pa->Name); continue; } if(ajStrMatchS(pa->Name, name)) { acdLog("..found '%S' %d\n", pa->Name, pa->PNum); savepa = pa; } else if(ajStrPrefixS(pa->Name, acdPrefName)) { if(!acdWrapper) acdWarn("Qualifier '%S' matches start of known '%S'", name, pa->Name); } else if(ajStrPrefixS(acdPrefName, pa->Name)) { if(!acdWrapper) acdWarn("Known qualifier '%S' matches start of '%S'", pa->Name, name); } if(!ajStrMatchS(pa->Token, pa->Name)) /* qualifier has a token */ { if(ajStrMatchS(pa->Token, name)) { acdLog("..found '%S' %d\n", pa->Name, pa->PNum); savepa = pa; } else if(ajStrPrefixS(pa->Token, acdPrefName)) { if(!acdWrapper) acdWarn("Qualifier '%S' matches start of known token '%S'", name, pa->Token); } } if(!usetoken) continue; if(ajStrMatchS(pa->Name, token)) { acdLog("..found '%S' %d\n", pa->Name, pa->PNum); savepa = pa; } else if(ajStrPrefixS(acdPrefToken, pa->Name)) { if(!acdWrapper) acdWarn("Qualifier token '%S' matches start of known '%S'", token, pa->Name); } else if(ajStrPrefixS(pa->Name, acdPrefToken)) { if(!acdWrapper) acdWarn("Known qualifier '%S' matches start of token '%S'", pa->Name, token); } if(!ajStrMatchS(pa->Token, pa->Name)) /* qualifier has a token */ { if(ajStrMatchS(pa->Token, token)) { acdLog("..found '%S' %d\n", pa->Name, pa->PNum); savepa = pa; } else if(ajStrPrefixS(pa->Token, acdPrefToken)) { if(!acdWrapper) acdWarn("Qualifier token '%S' matches start of " "known token '%S'", token, pa->Token); } } } return savepa; } ID acdFindAssoc TY static MO ajacd LB acd XX DE Locates an ACD object for an associated qualifier by name. DE DE Aborts the program with a fatal error in case of problems. DE DE Used in defining ACD objects and in processing the commandline. XX PN [1] PA r thys const AcdPAcd PD ACD object for the parameter PX PN [2] PA r name const AjPStr PD Token name to be used by applications PX PN [3] PA r noname const AjPStr PD Alternative token name (e.g. qualifier PD with "no" prefix removed) PX RT AcdPAcd RD ACD object for the selected qualifier RX // static AcdPAcd acdFindAssoc(const AcdPAcd thys, const AjPStr name, const AjPStr noname) { AcdPAcd pa; ajint ifound=0; AcdPAcd ret=NULL; AjPStr ambigList = NULL; ambigList = ajStrNew(); for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next) if(ajStrPrefixS(pa->Name, name) || ajStrPrefixS(pa->Name, noname)) { if(ajStrMatchS(pa->Name, name) || ajStrMatchS(pa->Name, noname)) return pa; ifound++; ret = pa; acdAmbigApp(&ambigList, pa->Name); } if(ifound == 1) { if (acdDoValid) acdWarn("Abbreviated associated qualifier '%S' (%S)", name, ambigList); ajStrDel(&ambigList); return ret; } if(ifound > 1) { ajWarn("Ambiguous name/token '%S' (%S)", name, ambigList); acdErrorAcd(thys, /* ambigdefattr.acd */ "Attribute or qualifier '%S' ambiguous (%S)\n", name, ambigList); ajStrDel(&ambigList); } ajStrDel(&ambigList); return NULL; } ID acdTestAssoc TY static MO ajacd LB acd XX DE Locates an ACD object for an associated qualifier by name. DE DE Only tests silently for a possible qualifier. DE DE If this fails, we check properly later. DE DE Used in defining ACD objects and in processing the commandline. XX PN [1] PA r thys const AcdPAcd PD ACD object for the parameter PX PN [2] PA r name const AjPStr PD Token name to be used by applications PX PN [3] PA r noname const AjPStr PD Alternative token name (e.g. qualifier PD with "no" prefix removed) PX RT AcdPAcd RD ACD object for the selected qualifier RX // static AcdPAcd acdTestAssoc(const AcdPAcd thys, const AjPStr name, const AjPStr noname) { AcdPAcd pa; ajint ifound=0; AcdPAcd ret=NULL; AjPStr ambigList = NULL; ambigList = ajStrNew(); for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next) if(ajStrPrefixS(pa->Name, name) || ajStrPrefixS(pa->Name, noname)) { if(ajStrMatchS(pa->Name, name) || ajStrMatchS(pa->Name, noname)) { ajStrDel(&ambigList); return pa; } ifound++; ret = pa; } if(ifound == 1) { if (acdDoValid) acdWarn("Abbreviated associated qualifier '%S' (%S)", name, ambigList); ajStrDel(&ambigList); return ret; } ajStrDel(&ambigList); return NULL; } ID acdTestQualC TY static MO ajacd LB acd XX DE Tests whether "name" is a valid qualifier name. DE To be valid, it must begin with "-" or '/'. DE If not, it can be taken as a value for the previous qualifier DE DE Used after a boolean option to check for a possible value DE DE Should run silently - if not valid, we will test it next anyway XX PN [1] PA r name const char* PD Qualifier name PX RT AjBool RD ajTrue if RX // static AjBool acdTestQualC(const char *name) { static AjPStr qstr = NULL; static AjPStr qnostr = NULL; static AjPStr qmaster = NULL; AcdPAcd pa; AcdPAcd qa; AcdPAcd savepa=NULL; ajint qnum = 0; ajlong i; ajint ifound=0; AjPStr ambigList = NULL; acdLog("acdTestQualC '%s'\n", name); if(*name != '-' && *name != '/' && !strstr(name, "=")) return ajFalse; /* not a qualifier name */ ambigList = ajStrNew(); ajStrAssignC(&qstr, name+1); /* lose the - or / prefix */ i = ajStrFindC(qstr, "="); /* qualifier with value */ if(i > 0) ajStrKeepRange(&qstr, 0, i-1); /* strip any value and keep testing */ if(ajStrPrefixC(qstr, "no")) /* check for -no qualifiers */ ajStrAssignSubS(&qnostr, qstr, 2, -1); else ajStrAssignClear(&qnostr); acdQualParse(&qstr, &qnostr, &qmaster, &qnum); if(ajStrGetLen(qmaster)) /* master specified as -qstr_qmaster */ { for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; if(ajStrMatchS(pa->Name, qmaster)) { acdLog(" *master matched* '%S'\n", pa->Name); qa = acdTestAssoc(pa, qstr, qnostr); ajStrDel(&ambigList); if(qa) return ajTrue; else return ajFalse; } } if(ajStrPrefixS(pa->Name, qstr)) { ifound++; savepa = pa; acdAmbigApp(&ambigList, pa->Name); } acdLog(" ifound: %d\n", ifound); if(ifound == 1) { qa = acdTestAssoc(savepa, qstr, qnostr); ajStrDel(&ambigList); ajStrDel(&qstr); ajStrDel(&qnostr); ajStrDel(&qmaster); if(qa) return ajTrue; else return ajFalse; } if(ifound > 1) /* master should be checked earlier */ { /* ajWarn("Ambiguous associated qualifier '%s' (%S)", name, ambigList); ajStrDel(&ambigList); */ ajStrDel(&ambigList); ajStrDel(&qstr); ajStrDel(&qnostr); ajStrDel(&qmaster); return ajFalse; } } else /* just qualifier name -qstr */ { for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; if(ajStrMatchS(pa->Name, qstr)) { acdLog(" *matched* '%S'\n", pa->Name); ajStrDel(&ambigList); ajStrDel(&qstr); ajStrDel(&qnostr); ajStrDel(&qmaster); return ajTrue; } if(ajStrPrefixS(pa->Name, qstr)) { ifound++; acdAmbigApp(&ambigList, pa->Name); } } acdLog(" ifound: %d\n", ifound); if(ifound == 1) { ajStrDel(&ambigList); ajStrDel(&qstr); ajStrDel(&qnostr); ajStrDel(&qmaster); return ajTrue; } if(ifound > 1) { /* ajWarn("Ambiguous qualifier '%s' (%S)", name, ambigList); ajStrDel(&ambigList); */ ajStrDel(&ambigList); ajStrDel(&qstr); ajStrDel(&qnostr); ajStrDel(&qmaster); return ajFalse; } } ajStrDel(&ambigList); ajStrDel(&qstr); ajStrDel(&qnostr); ajStrDel(&qmaster); return ajFalse; } ID acdFindType TY static MO ajacd LB acd XX DE Looks for a Type by name, and returns the number in acdType XX PN [1] PA r type const AjPStr PD String containing the type name PX RT ajint RD Integer representing the type (if know). Can be RD used as position in the acdType array. RX // static ajint acdFindType(const AjPStr type) { ajint i; ajint ifound = 0; ajint j = 0; AjPStr ambigList = NULL; ambigList = ajStrNew(); for(i=0; acdType[i].Name; i++) { if(ajStrMatchC(type, acdType[i].Name)) { ajStrDel(&ambigList); return i; } if(ajCharPrefixS(acdType[i].Name, type)) { ifound++; j = i; acdAmbigAppC(&ambigList, acdType[i].Name); } } if(ifound > 1) { /* warn now with the list, fail below */ ajWarn("ambiguous type %S (%S)", type, ambigList); } if(ifound != 1) /* Fatal: but covered by other tests */ acdError("unknown type: '%S'\n", type); ajStrDel(&ambigList); return j; } ID acdFindTypeC TY static MO ajacd LB acd XX DE Looks for a Type by name, and returns the number in acdType XX PN [1] PA r type const char* PD Text string containing the type name PX RT ajint RD Integer representing the type (if known). Can be RD used as position in the acdType array. RX // static ajint acdFindTypeC(const char* type) { ajint i; ajint ifound=0; ajint j=-1; ajint ilen = strlen(type); AjPStr ambigList = NULL; ambigList = ajStrNew(); for(i=0; acdType[i].Name; i++) { if(!strcmp(type, acdType[i].Name)) { ajStrDel(&ambigList); return i; } if(!strncmp(acdType[i].Name, type, ilen)) { ifound++; j = i; acdAmbigAppC(&ambigList, acdType[i].Name); } } if(ifound > 1) { /* warn now with the list, fail below */ ajWarn("ambiguous type %s (%S)", type, ambigList); ajStrDel(&ambigList); } if(ifound != 1) /* Fatal: but covered by other tests */ acdError("unknown type: '%s'\n", type); ajStrDel(&ambigList); return j; } ID acdFindKeyC TY static MO ajacd LB acd XX DE Looks for a Keyword by name, and returns the number in acdKeywords XX PN [1] PA r key const char* PD Text string containing the keyword name PX RT ajint RD Integer representing the keyword (if known). Can be RD used as position in the acdKeywords array. RX // static ajint acdFindKeyC(const char* key) { ajint i; ajint ifound=0; ajint j=0; ajint ilen = strlen(key); AjPStr ambigList = NULL; ajStrAssignClear(&ambigList); for(i=QUAL_STAGE+1; acdKeywords[i].Name; i++) { if(!strcmp(key, acdKeywords[i].Name)) { ajStrDel(&ambigList); return i; } if(strncmp(acdKeywords[i].Name, key, ilen)) { ifound++; j = i; acdAmbigAppC(&ambigList, acdKeywords[i].Name); } } if(ifound > 1) { ajWarn("ambiguous keyword %s (%S)", key, ambigList); } if(ifound != 1) /* Fatal: but strings are hard coded */ acdError("unknown keyword: '%s'\n", key); ajStrDel(&ambigList); return j; } ID acdReplyInitC TY static MO ajacd LB acd XX DE Builds a default value for the reply first time around. Uses a default DE specially set in the ACD, or (if none) uses the default string passed in DE parameter "defval" and also sets this as the default in the ACD. XX PN [1] PA r thys const AcdPAcd PD ACD object for current item. PX PN [2] PA r defval const char* PD Default value, as a C string PX PN [3] PA w reply AjPStr* PD String containing default reply PX RT AjBool RD ajTrue if a value in the ACD was used. RX // static AjBool acdReplyInitC(const AcdPAcd thys, const char *defval, AjPStr* reply) { AjPStr def; if(thys->DefStr) { def = thys->DefStr[DEF_DEFAULT]; acdLog("acdReplyInitC '%S' : '%S'\n", thys->Name, def); if(ajStrGetLen(def) || thys->Defined) { ajStrAssignS(reply, def); acdVarResolve(reply); return ajTrue; } } ajStrAssignC(reply, defval); ajStrAssignC(&thys->DefStr[DEF_DEFAULT], defval); return ajFalse; } ID acdReplyInitS TY static MO ajacd LB acd XX DE Builds a default value for the reply first time around. Uses a default DE specially set in the ACD, or (if none) uses the default string passed in DE parameter "defval" and also sets this as the default in the ACD. XX PN [1] PA r thys const AcdPAcd PD ACD object for current item. PX PN [2] PA r defval const AjPStr PD Default value, as a string object PX PN [3] PA w reply AjPStr* PD String containing default reply PX RT AjBool RD ajTrue if a value in the ACD was used. RX // static AjBool acdReplyInitS(const AcdPAcd thys, const AjPStr defval, AjPStr* reply) { AjPStr def; if(thys->DefStr) { def = thys->DefStr[DEF_DEFAULT]; acdLog("acdReplyInitS '%S' : '%S'\n", thys->Name, def); if(ajStrGetLen(def) || thys->Defined) { ajStrAssignS(reply, def); acdVarResolve(reply); return ajTrue; } } ajStrAssignS(reply, defval); ajStrAssignS(&thys->DefStr[DEF_DEFAULT], defval); return ajFalse; } ID acdDefinedEmpty TY static MO ajacd LB acd XX DE Tests for a defined ACD value of an empty string XX PN [1] PA r thys const AcdPAcd PD ACD object for current item. PX RT AjBool RD ajTrue if a value in the ACD was used but is empty RX // static AjBool acdDefinedEmpty (const AcdPAcd thys) { AjPStr def; if(thys->DefStr) { def = thys->DefStr[DEF_DEFAULT]; if(thys->Defined && !thys->UserSetNull && !ajStrGetLen(def)) return ajTrue; } return ajFalse; } ID acdUserGet TY static MO ajacd LB acd XX DE Given an ACD containing a defined prompt, a help string, DE or a default (string) value, prompts DE the user for a string value and returns it. DE DE If prompt is set, it is used. Otherwise, info can be used. DE If neither are defined, the item name and type are used to make a DE meaningful prompt. DE DE The default value is offered if it is set. DE DE The user response is returned in "reply" DE DE If -auto is in effect, fails if there is no value. XX PN [1] PA u thys AcdPAcd PD ACD object for current item. PX PN [2] PA w reply AjPStr* PD The user response, or PD the default value if accepted. PX RT AjBool RD ajTrue if reply contains any text. RX // static AjBool acdUserGet(AcdPAcd thys, AjPStr* reply) { AjBool ret = ajFalse; AjPStr prompt; AjPStr info; AjPStr code; AjPStr help; acdLog("acdUserGet '%S' reply '%S'\n", thys->Name, *reply); if(thys->DefStr && !acdAuto) { prompt = thys->DefStr[DEF_PROMPT]; info = thys->DefStr[DEF_INFO]; code = thys->DefStr[DEF_CODE]; help = thys->DefStr[DEF_HELP]; ajStrAssignS(&acdUserReplyDef, *reply); if(ajStrGetLen(code)) acdCodeGet(code, &acdUserMsg); else if(ajStrGetLen(prompt)) ajStrAssignS(&acdUserMsg, prompt); else if(ajStrGetLen(info)) ajStrAssignS(&acdUserMsg, info); else if(ajStrGetLen(thys->StdPrompt)) ajStrAssignS(&acdUserMsg, thys->StdPrompt); else if(ajStrGetLen(help)) ajStrAssignS(&acdUserMsg, help); else { if(!acdCodeDef(thys, &acdUserMsg)) { ajStrAssignResC(&acdUserMsg, 512, ""); ajFmtPrintS(&acdUserMsg, "-%S : enter %s value", thys->Name, acdType[thys->Type].Name); } } acdVarResolve(&acdUserMsg); acdLog("acdUserGet '%S' replydef '%S' msg '%S'\n", thys->Name, acdUserReplyDef, acdUserMsg); if(ajStrGetLen(acdUserReplyDef)) ret = ajUserGet(reply, "%S [%S]: ", acdUserMsg, acdUserReplyDef); else ret = ajUserGet(reply, "%S: ", acdUserMsg); if(!ret) ajStrAssignS(reply, acdUserReplyDef); if(ret) thys->UserDefined = ajTrue; acdUserSavereply(thys, NULL, ret, *reply); } if(ajStrGetLen(*reply)) ret = ajTrue; ajStrDelStatic(&acdUserMsg); ajStrDelStatic(&acdUserReplyDef); return ret; } ID acdUserGetPrompt TY static MO ajacd LB acd XX DE Given a defined prompt, prompts DE the user for a string value and returns it. DE DE The default value is offered if it is set. DE DE The user response is returned in "reply" DE DE If -auto is in effect, fails if there is no value. XX PN [1] PA r thys const AcdPAcd PD ACD object for current item PX PN [2] PA r assocqual const char* PD Associated qualifier PX PN [3] PA r prompt const char* PD prompt string PX PN [4] PA w reply AjPStr* PD The user response, or PD the default value if accepted. PX RT AjBool RD ajTrue if reply contains any text. RX // static AjBool acdUserGetPrompt(const AcdPAcd thys, const char* assocqual, const char* prompt, AjPStr* reply) { AjBool ret = ajFalse; if(!acdAuto) { ajStrAssignS(&acdUserReplyDef, *reply); if(ajStrGetLen(acdUserReplyDef)) ret = ajUserGet(reply, " %s [%S]: ", prompt, acdUserReplyDef); else ret = ajUserGet(reply, " %s: ", prompt); if(!ret) ajStrAssignS(reply, acdUserReplyDef); acdUserSavereply(thys, assocqual, ret, *reply); } if(ajStrGetLen(*reply)) ret = ajTrue; ajStrDelStatic(&acdUserReplyDef); return ret; } ID acdUserSavereply TY static MO ajacd LB acd XX DE Save the reply from prompting the user XX PN [1] PA r thys const AcdPAcd PD ACD object for current item. PX PN [2] PA r assocqual const char* PD Associated qualifier PX PN [3] PA r userset AjBool PD Reply set by user PX PN [4] PA r reply const AjPStr PD Reply string PX RT void RD RX // static void acdUserSavereply(const AcdPAcd thys, const char* assocqual, AjBool userset, const AjPStr reply) { AjPStr qualname = NULL; if(assocqual) { ajStrAssignC(&qualname, assocqual); ajStrAppendK(&qualname, '_'); ajStrAppendS(&qualname, thys->Name); } else ajStrAssignS(&qualname, thys->Name); if(ajStrMatchS(acdInputName, qualname)) ajStrTruncateLen(&acdInputSave, acdInputLen); else { ajStrAssignS(&acdInputName, qualname); acdInputLen = ajStrGetLen(acdInputSave); } if(userset) { if(acdInputLen) ajStrAppendK(&acdInputSave, '\n'); ajStrAppendK(&acdInputSave, '-'); ajStrAppendS(&acdInputSave, qualname); ajStrAppendK(&acdInputSave, ' '); if(ajStrIsWord(reply) && (ajStrFindAnyC(reply, "*?[]{}|!&^") < 0)) ajStrAppendS(&acdInputSave, reply); else { ajStrAppendK(&acdInputSave, '\"'); ajStrAppendS(&acdInputSave, reply); ajStrAppendK(&acdInputSave, '\"'); } } ajStrDel(&qualname); return; } ID acdBadRetry TY static MO ajacd LB acd XX DE Writes a message to stderr, and kills the application. XX PN [1] PA r thys const AcdPAcd PD ACD object. PX RT void RD RX // static void acdBadRetry(const AcdPAcd thys) { /* test acdc-retry */ ajDie("%S terminated: Bad value for '-%S' and no more retries", acdProgram, thys->Name); } ID acdBadVal TY static MO ajacd LB acd XX DE Writes a message to stderr, returns only if this is a standard value DE and we are prompting for values. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r required AjBool PD If true, prompting for the value PD was possible. PX PN [3] PA r fmt const char* PD Format with ajFmt extensions PX PN [4] PA v vararg ... PD Optional arguments PX RT void RD RX // static void acdBadVal(const AcdPAcd thys, AjBool required, const char *fmt, ...) { va_list args; static AjPStr msg = NULL; /* ** replaced line below with following 2 to make msg more obvious to ** the user **/ acdLog("Failure for option '%S'\n",thys->Name); ajFmtPrintS(&msg, "%s", fmt); va_start(args, fmt) ; ajVErr(ajStrGetPtr(msg), args); va_end(args) ; if(!required && !acdAuto) /* test acdc-badadvanced */ ajDie("%S terminated: Bad value for '-%S' and no prompt", acdProgram, thys->Name); if(acdAuto) /* test acdc-badauto */ ajDie("%S terminated: Bad value for '-%S' with -auto defined", acdProgram, thys->Name); return; } ID acdSetXxxx TY static MO ajacd LB acd XX DE Dummy function to handle prompting and validation for an ACD item type. DE A similar routine is needed for any new item type. See the other acdSet DE functions for ideas on what to include. DE DE This functions knows all the attributes, defaults, associated qualifiers DE and validation rules for type Xxxx. If any attributes (etc) are added, DE this is where the processing will be done. DE DE The final value (of type Xxxx) is set in thys as Value DE and a string equivalent for easy printing is set in thys as Valstr DE DE The function does not need to return a value. It either succeeds in filling DE in all values, or aborts with a suitable error messages. XX PN [1] PA u thys AcdPAcd PD ACD for current item (which is PD always of type Xxxx) PX RT void RD RX // static void acdSetXxxx(AcdPAcd thys) { AjPStr val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; /* ** create storage for val if needed, e.g. with AJNEW0(val) */ val = NULL; /* set a default value */ required = acdIsRequired(thys); acdReplyInitC(thys, "", &acdReply); for(itry=acdPromptTry; itry && !ok; itry--) { if(required) /* need to prompt? */ acdUserGet(thys, &acdReply); ok = ajTrue; /* test the value somehow */ } if(!ok) acdBadRetry(thys); ajStrAssignS(&val, acdReply); /* use the validated reply */ thys->Value = val; /* set the value */ ajStrAssignS(&thys->ValStr, val); /* set the string value */ return; } ID acdSetAppl TY static MO ajacd LB acd XX DE Makes sure all application ACD item values have been set. DE DE Called when an "appl" type ACD item is checked. Should not be called DE for any other item. The "appl" item may not be the first, as there DE are some 'standard' qualifiers set in advance for debugging, help and DE so on. DE DE At present there is nothing to prompt for here, though there could DE be, for example, a report of what the program does which would appear DE before any user prompts. XX PN [1] PA u thys AcdPAcd PD ACD for the application item. PX RT void RD RX // static void acdSetAppl(AcdPAcd thys) { AjPStr appldoc = NULL; AjPStr applobsolete = NULL; AjPStr applexternal = NULL; AjPStrTok handle = NULL; AjPStr token = NULL; AjPStr message = NULL; AjPStr appname = NULL; /* saved to table */ AjPStr appfullname = NULL; /* saved to table */ acdAttrResolve(thys, "documentation", &appldoc); acdAttrResolve(thys, "obsolete", &applobsolete); acdAttrResolve(thys, "external", &applexternal); acdAppldoc = ajStrNewS(appldoc); if(!acdExternalTable) acdExternalTable = ajTablestrNewCase(50); if(!acdAuto && ajStrGetLen(appldoc)) { ajStrFmtWrap(&appldoc, 75); ajUserDumpS(appldoc); } ajStrAssignS(&thys->ValStr, thys->Name); if(ajStrGetLen(applobsolete)) { acdWarnObsolete(applobsolete); } if(ajStrGetLen(applexternal)) { ajStrTokenAssignC(&handle, applexternal, "|"); while(ajStrTokenNextParse(&handle, &token)) { ajStrExtractFirst(token, &message, &appname); ajStrAssignS(&appfullname, appname); if(!ajSysFileWhich(&appfullname)) { ajStrFmtWrapLeft(&message, 70, 5, 0); ajDie("%S uses external program '%S' " "which is not in the PATH or defined as %S_%US\n%S", acdProgram, appname, ajNamValuePackage(), appname, message); } ajTablePut(acdExternalTable, appname, appfullname); appname = NULL; appfullname = NULL; } } ajStrDel(&appldoc); ajStrDel(&applobsolete); ajStrDel(&applexternal); ajStrDel(&message); ajStrDel(&token); ajStrTokenDel(&handle); return; } ID acdSetEndsec TY static MO ajacd LB acd XX DE Ends the current ACD section DE DE Called when an "endsection" type ACD item is checked. Should not be called DE for any other item. DE DE At present there is nothing to prompt for here, though there could DE be, for example, a blank line at the end of a section where DE something was prompted for. XX PN [1] PA u thys AcdPAcd PD ACD for the endsection item. PX RT void RD RX // static void acdSetEndsec(AcdPAcd thys) { if(thys->DefStr) ajStrAssignS(&thys->ValStr, thys->DefStr[DEF_DEFAULT]); acdVarResolve(&thys->ValStr); return; } ID acdSetSec TY static MO ajacd LB acd XX DE Starts a new ACD section. DE DE Called when a "section" type ACD item is checked. Should not be called DE for any other item. DE DE At present there is nothing to prompt for here, though there could DE be, for example, a prompt issued before the first prompt for the section. DE This would be stored (the 'info' attribute) and used in the standard DE prompting functions. XX PN [1] PA u thys AcdPAcd PD ACD for the section item. PX RT void RD RX // static void acdSetSec(AcdPAcd thys) { ajint border = 1; AjPStr comment = NULL; AjPStr folder = NULL; AjPStr info = NULL; AjPStr side = NULL; AjPStr type = NULL; const char* sideVal[] = {"top", "bottom", "left", "right", NULL}; const char* typeVal[] = {"frame", "page", NULL}; if(acdAttrToStr(thys, "type", "", &type)) if(!acdVocabCheck(type, typeVal)) acdErrorAcd(thys, "section %S, bad attribute value type: %S", thys->Name, type); if(acdAttrToInt(thys, "border", 1, &border)) { if(!ajStrMatchCaseC(type, "frame")) ajWarn("section %S, border only used by type: frame", thys->Name); if(border < 1) { acdAttrToStr(thys, "border", "", &acdTmpStr); acdErrorAcd(thys, "section %S, bad attribute value type: %S", acdTmpStr); } } acdAttrToStr(thys, "comment", "", &comment); if(acdAttrToStr(thys, "folder", "", &folder)) { if(!ajStrMatchCaseC(type, "page")) ajWarn("section %S, folder only used by type: page", thys->Name); } acdAttrToStr(thys, "information", "", &info); if(acdAttrToStr(thys, "side", "", &side)) { if(!acdVocabCheck(side, sideVal)) acdErrorAcd(thys, "section %S, bad attribute value side: %S", thys->Name, side); if(!ajStrMatchCaseC(type, "frame")) ajWarn("section %S, side only used by type: frame", thys->Name); } ajStrDel(&comment); ajStrDel(&folder); ajStrDel(&info); ajStrDel(&side); ajStrDel(&type); return; } ID acdSetVar TY static MO ajacd LB acd XX DE Defines an ACD variable. DE DE Called when a "variable" type ACD item is checked. Should not be called DE for any other item. DE DE At present there is nothing to prompt for here, though there could DE be, for example, a report of what the program does which would appear DE before any user prompts. XX PN [1] PA u thys AcdPAcd PD ACD for the application item. PX RT void RD RX // static void acdSetVar(AcdPAcd thys) { if(thys->DefStr) ajStrAssignS(&thys->ValStr, thys->DefStr[DEF_DEFAULT]); acdVarResolve(&thys->ValStr); return; } ID ajAcdGetAlign TY public MO ajacd LB acd XX DE Returns an item of type Align as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPAlign RD Alignment output object. Already opened RD by ajAlignOpent so this just returns the object RX // AjPAlign ajAcdGetAlign(const char *token) { return acdGetValueRef(token, "align"); } ID acdSetAlign TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD alignment output item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifier "-aformat" DE is applied when writing the sequences. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetAlign(AcdPAcd thys) { AjPAlign val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjBool nulldefault; AjPStr name = NULL; AjPStr ext = NULL; AjPStr fmt = NULL; AjPStr dir = NULL; val = NULL; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); acdGetValueAssoc(thys, "aformat", &fmt); acdGetValueAssoc(thys, "aextension", &ext); acdGetValueAssoc(thys, "aname", &name); acdGetValueAssoc(thys, "adirectory", &dir); acdOutDirectory(&dir); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdOutFilename(&acdReplyDef, name, ext); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { acdOutFilename(&acdTmpOutFName, name, ext); acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef); } acdPromptAlign(thys); ajStrDel(&name); ajStrDel(&ext); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajAlignNew(); ajStrAssignEmptyS(&val->Formatstr, fmt); acdAttrToStr(thys, "type", "", &val->Type); acdAttrToInt(thys, "minseqs", 0, &val->Nmin); acdAttrToInt(thys, "maxseqs", 0, &val->Nmax); acdAttrToBool(thys, "multiple", ajFalse, &val->Multi); acdQualToInt(thys, "awidth", 50, &val->Width, &acdTmpStr); acdQualToBool(thys, "aglobal", ajFalse, &val->Global, &acdTmpStr); acdQualToBool(thys, "aaccshow", ajFalse, &val->Showacc, &acdTmpStr); acdQualToBool(thys, "adesshow", ajFalse, &val->Showdes, &acdTmpStr); acdQualToBool(thys, "ausashow", ajFalse, &val->Showusa, &acdTmpStr); if(!ajAlignValid(val)) { /* test acdc-alignbadformat */ ajDie("Alignment option -%S: Validation failed", thys->Name); } ajStrAssignS(&acdOutFullFName, acdReply); ajFilenameReplacePathS(&acdOutFullFName, dir); ok = ajAlignOpen(val, acdOutFullFName); if(!ok) { acdBadVal(thys, required, "Unable to open alignment file '%S'", acdOutFullFName); ajAlignDel(&val); } } else if(!nullok) { acdBadVal(thys, required, "Alignment file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdOutFullFName); ajStrDel(&fmt); ajStrDel(&dir); return; } ID ajAcdGetArray TY public MO ajacd LB acd XX DE Returns an item of type array as defined in a named ACD item. Called by the DE application after all ACD values have been set, and simply returns DE what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFloat RD Floating point array object RX // AjPFloat ajAcdGetArray(const char *token) { return acdGetValueRef(token, "array"); } ID acdSetArray TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD floating point array item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is "0.0" with a size of 1. DE DE Min and max limits, if set, are applied without comment. DE Precision is provided for logging purposes but otherwise not (yet) used. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetArray(AcdPAcd thys) { AjPFloat val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool warnrange; AjBool failrange; AjBool sumtest; AjBool truemin; float vfmin; float vfmax; ajint precision; ajuint size; float sum; float tolerance; float fdef; float ftol; float ftot; AjPStr deflist = NULL; ajuint i; float* array; AjPStr failmsg = NULL; acdRangeTestCalc(thys); acdAttrToFloat(thys, "minimum", -FLT_MAX, &vfmin); acdLog("minimum: %e\n", vfmin); acdAttrToFloat(thys, "maximum", FLT_MAX, &vfmax); acdLog("maximum: %e\n", vfmax); acdAttrToFloat(thys, "sum", (float)1.0, &sum); acdLog("sum: %e\n", sum); acdAttrToFloat(thys, "tolerance", (float)0.01, &tolerance); acdLog("tolerance: %e\n", tolerance); acdAttrToInt(thys, "precision", 3, &precision); acdLog("precision: %d\n", precision); acdAttrToBool(thys, "failrange", ajTrue, &failrange); acdLog("failrange: %B\n", failrange); if(failrange && (vfmin > vfmax)) { acdAttrResolve(thys, "rangemessage", &failmsg); if(ajStrGetLen(failmsg)) acdErrorAcd(thys, "Invalid range: %S", failmsg); else acdErrorAcd(thys, "Invalid range: " "minimum value %.3f more than maximum %.3f", vfmin, vfmax); } acdAttrToBool(thys, "warnrange", acdDoWarnRange, &warnrange); acdLog("warnrange: %B\n", warnrange); acdAttrToBool(thys, "sumtest", ajTrue, &sumtest); acdLog("sumtest: %B\n", sumtest); acdAttrToBool(thys, "trueminimum", ajFalse, &truemin); acdLog("trueminimum: %B\n", truemin); acdAttrToUint(thys, "size", 1, &size); acdLog("size: %d\n", size); if(size < 1) acdErrorAcd(thys, "Array attribute size: %d less than 1", size); fdef = sum / ((float) size); for(i=0; i < size; i++) { if(i) ajStrAppendK(&deflist, ' '); ajFmtPrintAppS(&deflist, "%.*f", precision, fdef); } val = ajFloatNewRes(size); /* create storage for the result */ required = acdIsRequired(thys); acdReplyInitS(thys, deflist, &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); ok = ajFloatParse(acdReply, &val); if(ok && ajFloatLen(val) != size) { ajErr("Bad array value, expected %d values, found %d", size, ajFloatLen(val)); ok = ajFalse; } if(!ok) acdBadVal(thys, required, "Invalid array value '%S', please try again", acdReply); array = ajFloatFloat(val); ftot = 0.0; for(i=0; i< size; i++) { if(!truemin && array[i] < vfmin) { /* reset within limits */ if(warnrange) ajWarn("floating point value [%d] out of range %.*f " "less than (reset to) %.*f", i+1, precision, array[i], precision, vfmin); array[i] = vfmin; } if(array[i] > vfmax) { if(warnrange) ajWarn("floating point value [%d] out of range %.*f " "more than (reset to) %.*f", i+1, precision, array[i], precision, vfmax); array[i] = vfmax; } if(truemin && array[i] < vfmin) { /* reset within limits */ if(warnrange) ajWarn("floating point value [%d] out of range %.*f " "less than (reset to) %.*f", i+1, precision, array[i], precision, vfmin); array[i] = vfmin; } ftot += array[i]; } ftol = (float) fabs(ftot -sum); if(sumtest && ftol > tolerance) { ajWarn("Bad total %.*f, required total is %.*f with " "tolerance %.*f", precision, ftot, precision, sum,precision, tolerance); acdBadVal(thys, required, "Invalid array value '%S', please try again", acdReply); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajFloatStr(val, precision, &thys->ValStr); ajStrDel(&deflist); return; } ID ajAcdGetAssembly TY public MO ajacd LB acd XX DE Returns an item of type assembly as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPAssemload RD Assembly object RX // AjPAssemload ajAcdGetAssembly(const char *token) { AjPAssemload val = acdGetValueRef(token, "assembly"); return val; } ID acdSetAssembly TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD assembly input DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetAssembly(AcdPAcd thys) { AjPAssemload val; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok = ajFalse; ajint itry; AjPStr infname = NULL; AjPStr tmp = NULL; val = ajAssemloadNew(); /* set the default value */ acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); acdAttrToBool(thys, "entry", ajFalse, &val->Assemin->Input->Text); acdGetValueAssoc(thys, "cbegin", &tmp); ajStrToInt(tmp, &val->Assemin->cbegin); acdGetValueAssoc(thys, "cend", &tmp); ajStrToInt(tmp, &val->Assemin->cend); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajAssemloadDel(&val); break; } ajAsseminQryS(val->Assemin, acdReply); acdGetValueAssoc(thys, "iformat", &val->Assemin->Input->Formatstr); acdGetValueAssoc(thys, "iquery", &val->Assemin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &val->Assemin->Input->Fpos, &acdTmpStr); ok = ajAsseminLoad(val->Assemin, val->Assem); } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, ajAssemGetId(val->Assem), ajTrue); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&tmp); return; } ID ajAcdGetBoolean TY public MO ajacd LB acd XX DE Returns an item of type Bool as defined in a named ACD item. Called by the DE application after all ACD values have been set, and simply returns DE what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjBool RD Boolean value from ACD item RX // AjBool ajAcdGetBoolean(const char *token) { AjBool* val; val = acdGetValue(token, "boolean"); return *val; } ID acdSetBoolean TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD boolean item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is "N" for ajFalse. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetBoolean(AcdPAcd thys) { AjBool* val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AJNEW0(val); /* create storage for the result */ *val = ajFalse; /* set the default value */ required = acdIsRequired(thys); acdReplyInitC(thys, "N", &acdReplyDef); acdLog("acdSetBool -%S def: %S\n", thys->Name, acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); ok = ajStrToBool(acdReply, val); if(!ok) acdBadVal(thys, required, "Invalid Y/N value '%S'", acdReply); } if(!ok) acdBadRetry(thys); thys->Value = val; ajFmtPrintS(&thys->ValStr, "%B", *val); acdSetQualAppl(thys, *val); /* check special application booleans */ acdLog("acdSetBool -%S val: %B\n", thys->Name, *val); if(ajStrMatchC(thys->Name, "help")) acdHelp(); return; } ID ajAcdGetCodon TY public MO ajacd LB acd XX DE Returns an item of type Codon as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPCod RD Codon object. RX // AjPCod ajAcdGetCodon(const char *token) { return acdGetValueRef(token, "codon"); } ID acdSetCodon TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outfile item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetCodon(AcdPAcd thys) { AjPCod val; AjPStr name = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjPStr fmt = NULL; val = ajCodNew(); /* set the default value */ acdAttrResolve(thys, "name", &name); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdLog("nullok: %B\n", nullok); if (!acdGetValueAssoc(thys, "format", &fmt)) ajStrAssignClear(&fmt); required = acdIsRequired(thys); acdReplyInitS(thys, name, &acdReplyDef); acdPromptCodon(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { if(!ajCodRead(val, acdReply, fmt)) { acdBadVal(thys, required, "Unable to read codon usage '%S'", acdReply); ok = ajFalse; } } else { if(nullok) { ajCodDel(&val); } else { acdBadVal(thys, required, "Codon file is required"); ok = ajFalse; } } } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, NULL, ajFalse); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&name); ajStrDel(&fmt); return; } ID ajAcdGetCpdb TY public MO ajacd LB acd XX DE Returns an item of type Cpdb as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFile RD Cpdb input file. RX // AjPFile ajAcdGetCpdb(const char *token) { return acdGetValueRef(token, "cpdb"); } ID acdSetCpdb TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD clean pdb file item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetCpdb(AcdPAcd thys) { AjPFile val; AjPStr name = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjPStr fmt = NULL; val = NULL; /* set the default value */ acdAttrResolve(thys, "name", &name); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdLog("nullok: %B\n", nullok); if (!acdGetValueAssoc(thys, "format", &fmt)) ajStrAssignClear(&fmt); required = acdIsRequired(thys); acdReplyInitS(thys, name, &acdReplyDef); acdPromptCpdb(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajFileNewInNameS(acdReply); if(!val) { acdBadVal(thys, required, "Unable to read cleaned PDB data '%S'", acdReply); ok = ajFalse; } } else if(!nullok) { acdBadVal(thys, required, "Cleaned PDB data file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&name); ajStrDel(&fmt); return; } ID ajAcdGetDatafile TY public MO ajacd LB acd XX DE Returns an item of type Datafile as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFile RD File object. The file was already opened by RD ajDatafileNewInNameS so this just returns the pointer. RX // AjPFile ajAcdGetDatafile(const char *token) { return acdGetValueRef(token, "datafile"); } ID acdSetDatafile TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD datafile item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value is "programname.dat" XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetDatafile(AcdPAcd thys) { AjPFile val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjPStr name = NULL; AjPStr ext = NULL; AjPStr dir = NULL; AjPStr datafname = NULL; val = NULL; /* set the default value */ acdAttrResolve(thys, "name", &name); acdAttrResolve(thys, "extension", &ext); acdAttrResolve(thys, "directory", &dir); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdLog("nullok: %B\n", nullok); acdDataFilename(&datafname, name, ext, nullok); required = acdIsRequired(thys); acdReplyInitS(thys, datafname, &acdReplyDef); /* acdPromptInfile(thys);*/ ajStrDel(&datafname); ajStrDel(&name); ajStrDel(&ext); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajDatafileNewInNamePathS(acdReply, dir); if(!val) { acdBadVal(thys, required, "Unable to open data file '%S' for input", acdReply); ok = ajFalse; } } else if(!nullok) { acdBadVal(thys, required, "Input file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&dir); return; } ID ajAcdGetDirectory TY public MO ajacd LB acd XX DE Returns an item of type AjPDir which has been validated as a DE directory. DE DE Optionally can be forced to have a fully qualified path when returned. XX PN [1] PA r token const char* PD Text token name PX RT AjPDir RD Directory object RX // AjPDir ajAcdGetDirectory(const char *token) { return acdGetValueRef(token, "directory"); } ID ajAcdGetDirectoryName TY public MO ajacd LB acd XX DE Returns an item of type AjPStr which has been validated as a DE directory name DE DE Optionally can be forced to have a fully qualified path when returned. XX PN [1] PA r token const char* PD Text token name PX RT AjPStr RD Directory path RX // AjPStr ajAcdGetDirectoryName(const char *token) { AjPStr ret = NULL; AjPDir dir; dir = acdGetValue(token, "directory"); ret = ajStrNewS(ajDirGetPath(dir)); return ret; } ID acdSetDirectory TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD directory item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value is "." the current directory. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetDirectory(AcdPAcd thys) { AjPDir val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok = ajFalse; AjBool nulldefault = ajFalse; AjBool dopath = ajFalse; AjPStr ext = NULL; val = NULL; /* set the default value */ acdAttrToBool(thys, "fullpath", ajFalse, &dopath); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); acdGetValueAssoc(thys, "extension", &ext); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdReplyInitC(thys, ".", &acdReplyDef); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else acdReplyInitC(thys, ".", &acdReplyDef); acdPromptDirectory(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { if(dopath) ok = ajDirnameFillPath(&acdReply); else ok = ajDirnameFixExists(&acdReply); if (ok) { val = ajDirNewPathExt(acdReply, ext); if (!val) ok = ajFalse; } if(!ok) acdBadVal(thys, required, "Unable to open directory '%S'", acdReply); } else if(!nullok) { acdBadVal(thys, required, "Directory path is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&ext); return; } ID ajAcdGetDirlist TY public MO ajacd LB acd XX DE Returns a list of files in a given directory. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPList RD List of files. RX // AjPList ajAcdGetDirlist(const char *token) { return acdGetValueRef(token, "dirlist"); } ID acdSetDirlist TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD directory item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value is "." the current directory. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetDirlist(AcdPAcd thys) { AjPList val; AjPStr t; AjPStr v; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok = ajFalse; AjBool dopath; AjPStr ext = NULL; ajint n; ajint i; val = NULL; acdAttrToBool(thys, "fullpath", ajFalse, &dopath); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdGetValueAssoc(thys, "extension", &ext); required = acdIsRequired(thys); acdReplyInitC(thys, ".", &acdReplyDef); acdPromptDirlist(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { if(dopath) ok = ajDirnameFillPath(&acdReply); else ok = ajDirnameFixExists(&acdReply); if(!ok) acdBadVal(thys, required, "Unable to open directories '%S' for input", acdReply); } else if(!nullok) { acdBadVal(thys, required, "Input file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); val = ajListstrNew(); /* set the default value */ t = ajStrNewC("*"); if(MAJSTRGETLEN(ext)) { if(ajStrGetCharFirst(ext) != '.') ajStrInsertC(&ext, 0, "."); ajStrAppendS(&t, ext); } ajFilelistAddPathWild(val, acdReply, t); /* Sort list so that list of files is system-independent */ ajListSort(val, &ajStrVcmp); n = (ajuint) ajListGetLength(val); ajDebug("acdSetDirlist '%S' listlength %d\n", acdReply, n); for(i=0;iValue = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&t); ajStrDel(&ext); return; } ID ajAcdGetDiscretestates TY public MO ajacd LB acd XX DE Returns an item of type Discrete states as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPhyloState* RD Discrete states object. RD The string was already set by RD acdSetDiscretestates so this just returns the pointer. RX // AjPPhyloState* ajAcdGetDiscretestates(const char *token) { return acdGetValueRef(token, "discretestates"); } ID ajAcdGetDiscretestatesSingle TY public MO ajacd LB acd XX DE Returns an from an array item of type Discrete states as defined in a named DE ACD item, which is an array of objects terminated by a null value. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPhyloState RD Discrete states object. The data was already set by RD acdSetDiscretestates so this just returns the pointer. RX // AjPPhyloState ajAcdGetDiscretestatesSingle(const char *token) { AjPPhyloState* val; ajint i; val = acdGetValueSingle(token, "discretestates"); for(i=0; val[i]; i++) continue; if(i > 1) ajWarn("Single list value %s, but can choose %d values", token, i); if(i < 1) ajWarn("Single list value %s, no value found: returning NULL value", token); return val[0]; } ID acdSetDiscretestates TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD weights file item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is an empty string. DE DE Attributes for length and maximum property character are applied with error DE messages if exceeded. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetDiscretestates(AcdPAcd thys) { AjPPhyloState* val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; AjPStr infname = NULL; ajint itry; AjBool nullok = ajFalse; ajint size; ajint len; AjPStr statechars = NULL; ajint i; val = NULL; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "size", 1, &size); acdAttrToInt(thys, "length", 1, &len); acdAttrToStr(thys, "characters", "", &statechars); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptInfile(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajPhyloStateRead(acdReply, statechars); if(!val) { acdBadVal(thys, required, "Unable to read discrete states from '%S'", acdReply); ok = ajFalse; } } else if(!nullok) { acdBadVal(thys, required, "Input discrete states file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, NULL, ajTrue); /* properties have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcDiscrete); thys->SetAttr = &acdCalcDiscrete[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); if(val) { for(i=0;val[i];i++) continue; ajStrFromInt(&thys->SetStr[0],val[0]->Len); /* string length */ ajStrFromInt(&thys->SetStr[1],val[0]->Size); /* string count */ ajStrFromInt(&thys->SetStr[2],i); /* number of sets */ ajStrAssignS(&thys->ValStr, acdReply); ajDebug("acdSetDiscretestates calc len: %d size: %d sets: %d\n", val[0]->Len, val[0]->Size, i); } else { ajStrFromInt(&thys->SetStr[0],0); /* string length */ ajStrFromInt(&thys->SetStr[1],0); /* string count */ ajStrFromInt(&thys->SetStr[2],0); /* number of sets */ ajStrAssignClear(&thys->ValStr); } ajStrDel(&statechars); thys->Value = val; return; } ID ajAcdGetDistances TY public MO ajacd LB acd XX DE Returns an item of type Distances as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPhyloDist* RD Distances object. The string was already set by RD acdSetDistances so this just returns the pointer. RX // AjPPhyloDist* ajAcdGetDistances(const char *token) { return acdGetValueRef(token, "distances"); } ID ajAcdGetDistancesSingle TY public MO ajacd LB acd XX DE Returns an item of type Distances as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPhyloDist RD Distances object. The string was already set by RD acdSetDistances so this just returns the pointer. RX // AjPPhyloDist ajAcdGetDistancesSingle(const char *token) { AjPPhyloDist *val; ajint i; val = acdGetValueSingle(token, "distances"); for(i=0; val[i]; i++) continue; if(i > 1) ajWarn("Single list value %s, but can choose %d values", token, i); if(i < 1) ajWarn("Single list value %s, no value found: returning NULL value", token); return val[0]; } ID acdSetDistances TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD weights file item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is an empty string. DE DE Attributes for length and maximum property character are applied with error DE messages if exceeded. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetDistances(AcdPAcd thys) { AjPPhyloDist* val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; AjPStr infname = NULL; ajint itry; AjBool nullok = ajFalse; ajint size; AjBool missing; ajint i; val = NULL; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "size", 0, &size); acdAttrToBool(thys, "missval", ajFalse, &missing); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptInfile(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajPhyloDistRead(acdReply, size, missing); if(!val) { acdBadVal(thys, required, "Unable to read distances file '%S'", acdReply); ok = ajFalse; } } else if(!nullok) { acdBadVal(thys, required, "Distances file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, NULL, ajTrue); /* properties have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcDistances); thys->SetAttr = &acdCalcDistances[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); if(val) { for(i=0;val[i];i++) continue; ajStrFromInt(&thys->SetStr[0],i); /* matrix count */ ajStrFromInt(&thys->SetStr[1],val[0]->Size); /* string count */ ajStrFromBool(&thys->SetStr[2],val[0]->HasReplicates); ajStrFromBool(&thys->SetStr[3],val[0]->HasMissing); ajStrAssignS(&thys->ValStr, acdReply); } else { ajStrFromInt(&thys->SetStr[0],0); /* matrix count */ ajStrFromInt(&thys->SetStr[1],0); /* string count */ ajStrFromBool(&thys->SetStr[2],ajFalse); ajStrFromBool(&thys->SetStr[3],ajFalse); ajStrAssignClear(&thys->ValStr); } thys->Value = val; return; } ID ajAcdGetFeatout TY public MO ajacd LB acd XX DE Returns an item of type FeatOut as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFeattabOut RD Feature Table output object. Already opened RD by acdSetFeatout so this just returns the object RX // AjPFeattabOut ajAcdGetFeatout(const char *token) { return acdGetValueRef(token, "featout"); } ID acdSetFeatout TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD feature table item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-offormat", "-ofopenfile" DE are applied to the UFO before opening the output file. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetFeatout(AcdPAcd thys) { AjPFeattabOut val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjBool nulldefault; AjPStr name = NULL; AjPStr ext = NULL; AjPStr fmt = NULL; AjPStr type = NULL; val = NULL; if(!acdGetValueAssoc(thys, "ofname", &name)) acdAttrResolve(thys, "name", &name); if(acdGetValueAssoc(thys, "offormat", &fmt)) ajStrAssignS(&ext, fmt); else acdAttrResolve(thys, "extension", &ext); if(!ajStrGetLen(ext)) ajFeatOutFormatDefault(&ext); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); ajDebug("acdSetFeatout checking type\n"); if(!acdAttrToStr(thys, "type", "", &type)) { ajDebug("no type, try '%S'\n", type); if(!acdInTypeFeat(&type)) ajWarn("No output type specified for '%S'", thys->Name); } required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdOutFilename(&acdReplyDef, name, ext); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { acdOutFilename(&acdTmpOutFName, name, ext); acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef); } ajStrDel(&name); ajStrDel(&ext); acdPromptFeatout(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajFeattabOutNew(); ajDebug("Type '%S' try ajFeattabOutSetType\n", type); if(!ajFeattabOutSetType(val, type)) acdError("Invalid type for feature output"); acdGetValueAssoc(thys, "ofopenfile", &val->Filename); acdGetValueAssoc(thys, "ofdirectory", &val->Directory); acdOutDirectory(&val->Directory); ajStrAssignEmptyS(&val->Formatstr, fmt); ok = ajFeattabOutOpen(val, acdReply); if(!ok) { if(ajStrGetLen(val->Directory)) acdBadVal(thys, required, "Unable to open features output '%S%S'", val->Directory, acdReply); else acdBadVal(thys, required, "Unable to open features output '%S'", acdReply); ajFeattabOutDel(&val); } } else if(!nullok) { acdBadVal(thys, required, "Output UFO is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&fmt); ajStrDel(&type); return; } ID ajAcdGetFeatures TY public MO ajacd LB acd XX DE Returns an item of type Features as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFeattable RD Feature Table object. The table was already loaded by RD acdSetFeat so this just returns the pointer. RX // AjPFeattable ajAcdGetFeatures(const char *token) { AjPFeattaball val = acdGetValue(token, "features"); if(val->Multi) ajWarn("ajAcdGetFeatures request single feature table " "but maxreads > 1"); val->Returned = ajTrue; return val->Feattable; } ID ajAcdGetFeaturesall TY public MO ajacd LB acd XX DE Returns an input stream of an item of type Features as defined in a DE named ACD item. DE DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFeattaball RD Features input stream RX // AjPFeattaball ajAcdGetFeaturesall(const char *token) { AjPFeattaball val = acdGetValueRef(token, "features"); if(!val->Multi) ajWarn("ajAcdGetFeattaball request features input stream " "but maxreads is 1"); return val; } ID acdSetFeatures TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD feature table item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-fformat", "-fopenfile" DE are applied to the UFO before reading the feature table. DE DE Associated qualifiers "-fbegin", "-fend" and "-freverse" DE are applied as appropriate, with prompting for values, DE after the feature table has been read. DE They are applied to the feature table, DE and the resulting table is what is set in the ACD item. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetFeatures(AcdPAcd thys) { AjPFeattaball val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjPStr infname = NULL; static AjPStr type = NULL; ajint fbegin = 0; ajint fend = 0; AjBool freverse = ajFalse; AjBool fprompt = ajFalse; ajint iattr; ajint maxreads; val = ajFeattaballNew(); /* set the default value */ acdQualToBool(thys, "fask", ajFalse, &fprompt, &acdReplyDef); acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads); acdAttrToBool(thys, "entry", ajFalse, &val->Feattabin->Input->Text); if(acdAttrToStr(thys, "type", "", &type)) { if(!ajFeattabinSetTypeS(val->Feattabin, type)) acdError("Invalid type for feature input"); acdInTypeFeatSave(type); } else { acdInTypeFeatSave(NULL); } acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptFeatures(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); acdGetValueAssoc(thys, "fformat", &val->Feattabin->Formatstr); acdGetValueAssoc(thys, "fopenfile", &val->Feattabin->Filename); acdGetValueAssoc(thys, "iquery", &val->Feattabin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &val->Feattabin->Input->Fpos, &acdTmpStr); ajFeattabinQryS(val->Feattabin, acdReply); ok = ajFeattabinRead(val->Feattabin, val->Feattable); } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, ajFeattableGetName(val->Feattable), ajTrue); /* save sequence name */ /* now process the begin, end and reverse options */ ok = acdQualToInt(thys, "fbegin", 1, &fbegin, &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ajStrAssignS(&acdReply, acdReplyDef); if(fprompt) acdUserGetPrompt(thys, "fbegin", " Begin at position", &acdReply); ok = ajStrToInt(acdReply, &fbegin); if(!ok) acdBadVal(thys, ajTrue, "Invalid integer value '%S'", acdReply); } if(!ok) acdBadRetry(thys); ok = acdQualToInt(thys, "fend", ajFeattableGetLen(val->Feattable), &fend, &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ajStrAssignS(&acdReply, acdReplyDef); if(fprompt) acdUserGetPrompt(thys, "fend", " End at position", &acdReply); ok = ajStrToInt(acdReply, &fend); if(!ok) acdBadVal(thys, ajTrue, "Invalid integer value '%S'", acdReply); } if(!ok) acdBadRetry(thys); ok = acdQualToBool(thys, "freverse", ajFalse, &freverse, &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ajStrAssignS(&acdReply, acdReplyDef); if(fprompt) acdUserGetPrompt(thys, "freverse", " Reverse strand", &acdReply); ok = ajStrToBool(acdReply, &freverse); if(!ok) acdBadVal(thys, ajTrue, "Invalid Y/N value '%S'", acdReply); } if(!ok) acdBadRetry(thys); acdLog("sbegin: %d, send: %d, freverse: %B\n", fbegin, fend, freverse); if(freverse) { val->Feattabin->Rev = freverse; ajFeattableReverse(val->Feattable); } ajFeattabinSetRange(val->Feattabin, fbegin, fend); ajFeattableSetRange(val->Feattable, fbegin, fend); if(maxreads > 1) val->Multi = ajTrue; /* features tables have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcFeat); thys->SetAttr = &acdCalcFeat[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); iattr = 0; ajStrFromInt(&thys->SetStr[iattr++], ajFeattableGetBegin(val->Feattable)); ajStrFromInt(&thys->SetStr[iattr++], ajFeattableGetEnd(val->Feattable)); ajStrFromInt(&thys->SetStr[iattr++], ajFeattableGetLen(val->Feattable)); ajStrFromBool(&thys->SetStr[iattr++], ajFeattableIsProt(val->Feattable)); ajStrFromBool(&thys->SetStr[iattr++], ajFeattableIsNuc(val->Feattable)); ajStrAssignS(&thys->SetStr[iattr++], ajFeattableGetName(val->Feattable)); ajStrFromInt(&thys->SetStr[iattr++], ajFeattableGetSize(val->Feattable)); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&type); return; } ID ajAcdGetFilelist TY public MO ajacd LB acd XX DE Returns a list of files given a comma-separated list. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPList RD List of files. RX // AjPList ajAcdGetFilelist(const char *token) { return acdGetValueRef(token, "filelist"); } ID acdSetFilelist TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD file list item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE There is no default value XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetFilelist(AcdPAcd thys) { AjPList val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok = ajFalse; val = ajListNew(); acdAttrToBool(thys, "nullok", ajFalse, &nullok); required = acdIsRequired(thys); acdReplyInitC(thys, "", &acdReplyDef); acdPromptFilelist(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply)) if(!nullok) { acdBadVal(thys, required, "File list is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); ajFilelistAddListname(val, acdReply); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID ajAcdGetFloat TY public MO ajacd LB acd XX DE Returns an item of type Float as defined in a named ACD item. Called by the DE application after all ACD values have been set, and simply returns DE what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT float RD Floating point value from ACD item RX // float ajAcdGetFloat(const char *token) { double *val; val = acdGetValue(token, "float"); return (float) *val; } ID ajAcdGetFloatDouble TY public MO ajacd LB acd XX DE Returns an item of type Float as defined in a named ACD item. Called by the DE application after all ACD values have been set, and simply returns DE what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT double RD Floating point value from ACD item RX // double ajAcdGetFloatDouble(const char *token) { double *val; val = acdGetValue(token, "float"); return *val; } ID acdSetFloat TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD floating point item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is "0.0". DE DE Min and max limits, if set, are applied without comment. DE Precision is provided for logging purposes but otherwise not (yet) used. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetFloat(AcdPAcd thys) { double* val; float fval; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool warnrange; AjBool failrange; AjBool isdouble; AjBool truemin; double vfmin; double vfmax; ajint precision; AjPStr failmsg = NULL; acdRangeTestCalc(thys); acdAttrToDouble(thys, "minimum", -FLT_MAX, &vfmin); acdLog("minimum: %e\n", vfmin); acdAttrToDouble(thys, "maximum", FLT_MAX, &vfmax); acdLog("maximum: %e\n", vfmax); acdAttrToInt(thys, "precision", 3, &precision); acdLog("precision: %d\n", precision); acdAttrToBool(thys, "failrange", ajTrue, &failrange); acdLog("failrange: %B\n", failrange); acdAttrToBool(thys, "warnrange", acdDoWarnRange, &warnrange); acdLog("warnrange: %B\n", warnrange); acdAttrToBool(thys, "large", AJFALSE, &isdouble); acdLog("large: %B\n", isdouble); acdAttrToBool(thys, "trueminimum", AJFALSE, &truemin); acdLog("trueminimum: %B\n", truemin); if(failrange && (vfmin > vfmax)) { acdAttrResolve(thys, "rangemessage", &failmsg); if(ajStrGetLen(failmsg)) acdErrorAcd(thys, "Invalid range: %S", failmsg); else acdErrorAcd(thys, "Invalid range: " "minimum value %.3f more than maximum %.3f", vfmin, vfmax); } AJNEW0(val); /* create storage for the result */ *val = 0.0; /* set the default value */ required = acdIsRequired(thys); acdReplyInitC(thys, "0.0", &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(isdouble) ok = ajStrToDouble(acdReply, val); else { ok = ajStrToFloat(acdReply, &fval); *val = fval; } if(!ok) acdBadVal(thys, required, "Invalid decimal value '%S', please try again", acdReply); } if(!ok) acdBadRetry(thys); if(isdouble && vfmin == FLT_MIN) vfmin = DBL_MIN; if(isdouble && vfmax == FLT_MAX) vfmax = DBL_MAX; if(!truemin && *val < vfmin) { /* reset within limits */ if(warnrange) ajWarn("floating point value out of range %.*f " "less than (reset to) %.*f", precision, *val, precision, vfmin); *val = vfmin; } if(*val > vfmax) { if(warnrange) ajWarn("floating point value out of range %.*f " "more than (reset to) %.*f", precision, *val, precision, vfmax); *val = vfmax; } if(truemin && *val < vfmin) { /* reset within limits */ if(warnrange) ajWarn("floating point value out of range %.*f " "less than (reset to) %.*f", precision, *val, precision, vfmin); *val = vfmin; } thys->Value = val; ajStrFromFloat(&thys->ValStr, (float) *val, precision); return; } ID ajAcdGetFrequencies TY public MO ajacd LB acd XX DE Returns an item of type Frequencies as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPhyloFreq RD Frequencies object. The string was already set by RD acdSetFrequencies so this just returns the pointer. RX // AjPPhyloFreq ajAcdGetFrequencies(const char *token) { return acdGetValueRef(token, "frequencies"); } ID acdSetFrequencies TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD weights file item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is an empty string. DE DE Attributes for length and maximum property character are applied with error DE messages if exceeded. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetFrequencies(AcdPAcd thys) { AjPPhyloFreq val; AjBool required = ajFalse; AjBool ok = ajFalse; AjPStr infname = NULL; ajint itry; AjBool nullok = ajFalse; AjBool contchar = ajFalse; AjBool genedata = ajFalse; AjBool within = ajFalse; ajint size; val = NULL; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "size", 1, &size); acdAttrToBool(thys, "continuous", ajFalse, &contchar); acdAttrToBool(thys, "genedata", ajFalse, &genedata); acdAttrToBool(thys, "within", ajFalse, &within); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptInfile(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajPhyloFreqRead(acdReply, contchar, genedata, within); if(!val) { acdBadVal(thys, required, "Unable to read frequencies file '%S'", acdReply); ok = ajFalse; } } else if(!nullok) { acdBadVal(thys, required, "Input frequencies file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, NULL, ajTrue); /* properties have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcFrequencies); thys->SetAttr = &acdCalcFrequencies[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); if(val) { ajStrFromInt(&thys->SetStr[0],val->Len); /* string count */ ajStrFromInt(&thys->SetStr[1],val->Size); /* string count */ ajStrFromInt(&thys->SetStr[2],val->Loci); /* string count */ ajStrFromBool(&thys->SetStr[3],!val->ContChar); /* genes */ ajStrFromBool(&thys->SetStr[4],val->ContChar); /* contin */ ajStrFromBool(&thys->SetStr[5],val->Within); /* indivs */ ajStrAssignS(&thys->ValStr, acdReply); } else { ajStrFromInt(&thys->SetStr[0],0); /* string count */ ajStrFromInt(&thys->SetStr[1],0); /* string count */ ajStrFromInt(&thys->SetStr[2],0); /* string count */ ajStrFromBool(&thys->SetStr[3],0); /* genes */ ajStrFromBool(&thys->SetStr[4],0); /* contin */ ajStrFromBool(&thys->SetStr[5],0); /* indivs */ ajStrAssignClear(&thys->ValStr); } thys->Value = val; return; } ID ajAcdGetGraph TY public MO ajacd LB acd XX DE Returns a graph object which hold user graphics options. XX PN [1] PA r token const char* PD Text token name PX RT AjPGraph RD Graph object. RX // AjPGraph ajAcdGetGraph(const char *token) { return acdGetValueRef(token, "graph"); } ID acdSetGraph TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD graph item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetGraph(AcdPAcd thys) { AjPGraph val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; AjPStr title = NULL; AjPStr gdev = NULL; ajint itry; AjBool nullok; AjBool nulldefault; AjBool hasseq = ajFalse; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ { if(ajNamGetValueC("GRAPHICS",&gdev)) acdReplyInitS(thys, gdev, &acdReplyDef); else #ifndef WIN32 #ifndef X_DISPLAY_MISSING /* X11 is available */ acdReplyInitC(thys, "x11", &acdReplyDef); #else #ifdef PLD_png /* if png/gd/zlib libraries available for png driver */ acdReplyInitC(thys, "png", &acdReplyDef); #else acdReplyInitC(thys, "ps", &acdReplyDef); #endif #endif #else acdReplyInitC(thys, "win3", &acdReplyDef); #endif } else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { if(ajNamGetValueC("GRAPHICS",&gdev)) acdReplyInitS(thys, gdev, &acdReplyDef); else #ifndef WIN32 #ifndef X_DISPLAY_MISSING /* X11 is available */ acdReplyInitC(thys, "x11", &acdReplyDef); #else #ifdef PLD_png /* if png/gd/zlib libraries available for png driver */ acdReplyInitC(thys, "png", &acdReplyDef); #else acdReplyInitC(thys, "ps", &acdReplyDef); #endif #endif #else acdReplyInitC(thys, "win3", &acdReplyDef); #endif } ajStrDel(&gdev); acdPromptGraph(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) /* valid no graph type */ { if(!val) val = ajGraphNew(); ok = ajGraphSetDevicetype(val, acdReply); if(!ok) { ajGraphicsDumpDevices(); acdBadVal(thys, required, "Invalid graph value '%S'", acdReply); } } else if(!nullok) { acdBadVal(thys, required, "Graph is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignC(&thys->ValStr, "graph definition"); if(val) { acdAttrToBool(thys, "sequence", ajFalse, &hasseq); if(acdGetValueAssoc(thys, "gdesc", &title)) ajGraphSetDescS(val,title); if(acdGetValueAssoc(thys, "gtitle", &title)) ajGraphSetTitleS(val,title); if(acdGetValueAssoc(thys, "gsubtitle", &title)) ajGraphSetSubtitleS(val,title); if(acdGetValueAssoc(thys, "gxtitle", &title)) ajGraphSetXlabelS(val,title); else if(hasseq) ajGraphSetXlabelS(val, acdInFName); if(acdGetValueAssoc(thys, "gytitle", &title)) ajGraphSetYlabelS(val,title); if(acdGetValueAssoc(thys, "goutfile", &title)) ajGraphSetOutfileS(val,title); if(acdGetValueAssoc(thys, "gdirectory", &title)) ajGraphSetOutdirS(val,title); else { ajStrAssignClear(&title); if(acdOutDirectory(&title)) ajGraphSetOutdirS(val,title); } ajStrDel(&title); ajGraphTrace(val); } return; } ID ajAcdGetGraphxy TY public MO ajacd LB acd XX DE Returns a graph object which hold user graphics options. XX PN [1] PA r token const char* PD Text token name PX RT AjPGraph RD Graph object. RX // AjPGraph ajAcdGetGraphxy(const char *token) { return acdGetValueRef(token, "xygraph"); } ID acdSetGraphxy TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD XY graph item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetGraphxy(AcdPAcd thys) { AjPGraph val; AjPStr gdev = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; AjPStr title = NULL; ajint itry; AjBool nullok; AjBool nulldefault; ajint multi; AjBool hasseq = ajFalse; val = NULL; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); acdAttrToInt(thys, "multi", 1, &multi); if(multi < 1) multi = 1; acdLog("multi: %d\n", multi); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ { if(ajNamGetValueC("GRAPHICS",&gdev)) acdReplyInitS(thys, gdev, &acdReplyDef); else #ifndef WIN32 #ifndef X_DISPLAY_MISSING /* X11 is available */ acdReplyInitC(thys, "x11", &acdReplyDef); #else #ifdef PLD_png /* if png/gd/zlib libraries available for png driver */ acdReplyInitC(thys, "png", &acdReplyDef); #else acdReplyInitC(thys, "ps", &acdReplyDef); #endif #endif #else acdReplyInitC(thys, "win3", &acdReplyDef); #endif } else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { if(ajNamGetValueC("GRAPHICS",&gdev)) acdReplyInitS(thys, gdev, &acdReplyDef); else #ifndef WIN32 #ifndef X_DISPLAY_MISSING /* X11 is available */ acdReplyInitC(thys, "x11", &acdReplyDef); #else #ifdef PLD_png /* if png/gd/zlib libraries available for png driver */ acdReplyInitC(thys, "png", &acdReplyDef); #else acdReplyInitC(thys, "ps", &acdReplyDef); #endif #endif #else acdReplyInitC(thys, "win3", &acdReplyDef); #endif } ajStrDel(&gdev); acdPromptGraph(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) /* valid no graph type */ { if(!val) val = ajGraphxyNewI(multi); ok = ajGraphxySetDevicetype(val, acdReply); if(!ok) { ajGraphicsDumpDevices(); acdBadVal(thys, required, "Invalid XY graph value '%S'", acdReply); } } else if(!nullok) { acdBadVal(thys, required, "Graph is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignC(&thys->ValStr, "XY graph definition"); if(val) { acdAttrToBool(thys, "sequence", ajFalse, &hasseq); if(hasseq) ajGraphSetDatanameS(val, acdInFName); if(acdGetValueAssoc(thys, "gdesc", &title)) ajGraphSetDescS(val,title); if(acdGetValueAssoc(thys, "gtitle", &title)) ajGraphSetTitleS(val,title); if(acdGetValueAssoc(thys, "gsubtitle", &title)) ajGraphSetSubtitleS(val,title); if(acdGetValueAssoc(thys, "gxtitle", &title)) ajGraphSetXlabelS(val,title); else if(hasseq) ajGraphSetXlabelS(val, acdInFName); if(acdGetValueAssoc(thys, "gytitle", &title)) ajGraphSetYlabelS(val,title); if(acdGetValueAssoc(thys, "goutfile", &title)) ajGraphSetOutfileS(val,title); if(acdGetValueAssoc(thys, "gdirectory", &title)) ajGraphSetOutdirS(val,title); else { ajStrAssignClear(&title); if(acdOutDirectory(&title)) ajGraphSetOutdirS(val,title); } ajStrDel(&title); ajGraphTrace(val); } return; } ID ajAcdGetInfile TY public MO ajacd LB acd XX DE Returns an item of type file as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFile RD File object. The file was already opened by RD acdSetInfile so this just returns the pointer. RX // AjPFile ajAcdGetInfile(const char *token) { return acdGetValueRef(token, "infile"); } ID acdSetInfile TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD infile item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if filtering is on) is "stdin", but then DE prompting is turned off. DE DE Otherwise there is no default value unless the ACD file has one. DE DE Various file naming options are defined, but not yet implemented here. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetInfile(AcdPAcd thys) { AjPFile val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjBool trydefault; AjPStr infname = NULL; AjPStr inpath = NULL; val = NULL; /* set the default value */ acdAttrToStr(thys, "directory", "", &inpath); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "trydefault", ajFalse, &trydefault); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptInfile(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { if(!ajFilenameHasPath(acdReply)) val = ajFileNewInNamePathS(acdReply,inpath); else val = ajFileNewInNameS(acdReply); if(!val) { if(!nullok || !trydefault || !ajStrMatchS(acdReply, acdReplyDef)) { if(ajStrGetLen(inpath) && !ajFilenameHasPath(acdReply)) acdBadVal(thys, required, "Unable to open file '%S/%S' for input", inpath, acdReply); else acdBadVal(thys, required, "Unable to open file '%S' for input", acdReply); ok = ajFalse; } } } else if(!nullok) { acdBadVal(thys, required, "Input file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, NULL, ajTrue); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&inpath); return; } ID ajAcdGetInt TY public MO ajacd LB acd XX DE Returns an item of type ajint as defined in a named ACD item. Called by the DE application after all ACD values have been set, and simply returns DE what the ACD item already has. DE DE The ACD item is expected to have the large attribute set to false. XX PN [1] PA r token const char* PD Text token name PX RT ajint RD Integer value from ACD item RX // ajint ajAcdGetInt(const char *token) { ajlong *val; val = acdGetValue(token, "integer"); return (ajint) *val; } ID ajAcdGetIntLong TY public MO ajacd LB acd XX DE Returns an item of type ajlong as defined in a named ACD item. Called by the DE application after all ACD values have been set, and simply returns DE what the ACD item already has. DE DE The ACD item is expected to have the large attribute set to true. XX PN [1] PA r token const char* PD Text token name PX RT ajlong RD Integer value from ACD item RX // ajlong ajAcdGetIntLong(const char *token) { ajlong *val; val = acdGetValue(token, "integer"); return *val; } ID acdSetInt TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD integer item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is "0". DE DE Min and max limits, if set, are applied without comment. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetInt(AcdPAcd thys) { ajlong* val; ajint ival; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool failrange; AjBool warnrange; AjBool islong; AjBool truemin; ajlong imin; ajlong imax; AjPStr failmsg = NULL; AjBool iscalc = ajFalse; acdRangeTestCalc(thys); acdAttrToLong(thys, "minimum", INT_MIN, &imin); acdLog("minimum: %Ld\n", imin); acdAttrToLong(thys, "maximum", INT_MAX, &imax); acdLog("maximum: %Ld\n", imax); acdAttrToBool(thys, "failrange", ajTrue, &failrange); acdLog("failrange: %B\n", failrange); acdAttrToBool(thys, "warnrange", acdDoWarnRange, &warnrange); acdLog("warnrange: %B\n", warnrange); acdAttrToBool(thys, "large", AJFALSE, &islong); acdLog("large: %B\n", islong); acdAttrToBool(thys, "trueminimum", AJFALSE, &truemin); acdLog("trueminimum: %B\n", truemin); if(failrange && (imin > imax)) { acdAttrResolve(thys, "rangemessage", &failmsg); if(ajStrGetLen(failmsg)) acdErrorAcd(thys, "Invalid range: %S", failmsg); else acdErrorAcd(thys, "Invalid range: " "minimum value %d more than maximum %d", imin, imax); } AJNEW0(val); /* create storage for the result */ *val = 0; /* set the default value */ required = acdIsRequired(thys); acdReplyInitC(thys, "0", &acdReplyDef); acdLog("acdSetInt %S default '%S' Required: %B\n", thys->Name, acdReplyDef, required); for(itry=acdPromptTry; itry && !ok; itry--) { ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); acdLog(" reply: '%S' \n", acdReply); if(ajStrMatchC(acdReply, "default")) ajStrAssignC(&acdReply, "0"); if(islong) ok = ajStrToLong(acdReply, val); else { ok = ajStrToInt(acdReply, &ival); *val = ival; } acdLog(" modified reply: '%S' val: %Ld ok: %B\n", acdReply, *val, ok); if(!ok) acdBadVal(thys, required, "Invalid integer value '%S'", acdReply); } if(!ok) acdBadRetry(thys); if(islong && imin == INT_MIN) imin = LONG_MIN; if(islong && imax == INT_MAX) imax = LONG_MAX; if(iscalc) { if(!truemin && *val < imin) { /* reset within limits */ if(warnrange) ajWarn("integer value out of range %Ld less than " "(reset to) %Ld", *val, imin); *val = imin; } if(*val > imax) { if(warnrange) ajWarn("integer value out of range %Ld more than " "(reset to) %Ld", *val, imax); *val = imax; } if(truemin && *val < imin) { /* reset within limits */ if(warnrange) ajWarn("integer value out of range %Ld less than " "(reset to) %Ld", *val, imin); *val = imin; } } else { if(*val < imin) { /* reset within limits */ if(warnrange) ajWarn("integer value out of range %Ld less than " "(reset to) %Ld", *val, imin); *val = imin; } if(*val > imax) { if(warnrange) ajWarn("integer value out of range %Ld more than " "(reset to) %Ld", *val, imax); *val = imax; } } thys->Value = val; ajStrFromLong(&thys->ValStr, *val); return; } ID ajAcdGetList TY public MO ajacd LB acd XX DE Returns an item of type List as defined in a named ACD item, DE which is an array of strings terminated by a null value. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPStr* RD String array of values with NULL for last element. RX // AjPStr* ajAcdGetList(const char *token) { return acdGetValueRef(token, "list"); } ID ajAcdGetListSingle TY public MO ajacd LB acd XX DE Returns a single item from an array of type List as defined in a named DE ACD item, which is an array of strings terminated by a null value. DE Called by the application after all ACD values have been set, and DE simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPStr RD String array of values with NULL for last element. RX // AjPStr ajAcdGetListSingle(const char *token) { AjPStr *val; ajint i; val = acdGetValueSingle(token, "list"); for(i=0; val[i]; i++) continue; if(i > 1) ajWarn("Single list value %s, but can choose %d values", token, i); if(i < 1) ajWarn("Single list value %s, no value found: returning NULL value", token); return val[0]; } ID acdSetList TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outfile item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE If a value is required and not yet given, prints out a header DE and the list of options, then asks for a selection or (if max is DE more than 1) a list of selections. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetList(AcdPAcd thys) { AjPStr *val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; ajint i; ajint min, max; val = NULL; /* set the default value */ required = acdIsRequired(thys); acdReplyInitC(thys, "", &acdReplyDef); acdAttrToInt(thys, "minimum", 1, &min); acdAttrToInt(thys, "maximum", 1, &max); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) { acdListPrompt(thys); acdUserGet(thys, &acdReply); } val = acdListValue(thys, min, max, acdReply); if(!val) { acdBadVal(thys, required, "Bad menu option '%S'", acdReply); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; for(i=0; val[i]; i++) { acdLog("Storing val[%d] '%S'\n", i,val[i]); if(i) ajStrAppendC(&thys->ValStr, ";"); ajStrAppendS(&thys->ValStr, val[i]); } return; } ID ajAcdGetMatrix TY public MO ajacd LB acd XX DE Returns an item of type Matrix as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPMatrix RD Matrix object. RX // AjPMatrix ajAcdGetMatrix(const char *token) { return acdGetValueRef(token, "matrix"); } ID ajAcdGetMatrixf TY public MO ajacd LB acd XX DE Returns an item of type Matrix as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPMatrixf RD Float Matrix object. RX // AjPMatrixf ajAcdGetMatrixf(const char *token) { return acdGetValueRef(token, "matrixf"); } ID acdSetMatrix TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD matrix item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetMatrix(AcdPAcd thys) { AjPMatrix val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool isprot; AjPStr infname = NULL; val = NULL; /* set the default value */ acdAttrToBool(thys, "protein", ajTrue, &isprot); if(isprot) { acdAttrResolve(thys, "pname", &infname); if(!ajStrGetLen(infname)) ajStrAssignC(&infname, DEFBLOSUM); } else { acdAttrResolve(thys, "nname", &infname); if(!ajStrGetLen(infname)) ajStrAssignC(&infname, DEFDNA); } required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajMatrixNewFile(acdReply); if(!val) { acdBadVal(thys, required, "Unable to read matrix '%S'", acdReply); ok = ajFalse; } } else { acdBadVal(thys, required, "Matrix is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID acdSetMatrixf TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD matrix item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetMatrixf(AcdPAcd thys) { AjPMatrixf val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool isprot; AjPStr infname = NULL; val = NULL; /* set the default value */ acdAttrToBool(thys, "protein", ajTrue, &isprot); if(isprot) { acdAttrResolve(thys, "pname", &infname); if(!ajStrGetLen(infname)) ajStrAssignC(&infname, DEFBLOSUM); } else { acdAttrResolve(thys, "nname", &infname); if(!ajStrGetLen(infname)) ajStrAssignC(&infname, DEFDNA); } required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajMatrixfNewFile(acdReply); if(!val) { acdBadVal(thys, required, "Unable to read matrix '%S'", acdReply); ok = ajFalse; } } else { acdBadVal(thys, required, "Matrix is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID ajAcdGetObo TY public MO ajacd LB acd XX DE Returns an item of type Obo as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPObo RD Obo term object RX // AjPObo ajAcdGetObo(const char *token) { AjPOboall val = acdGetValue(token, "obo"); if(val->Multi) ajWarn("ajAcdGetObo request single obo term but maxreads > 1"); val->Returned = ajTrue; return val->Obo; } ID ajAcdGetOboall TY public MO ajacd LB acd XX DE Returns an input stream of an item of type Obo as defined in a DE named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOboall RD Obo input stream RX // AjPOboall ajAcdGetOboall(const char *token) { AjPOboall val = acdGetValueRef(token, "obo"); if(!val->Multi) ajWarn("ajAcdGetOboall request obo input stream but maxreads is 1"); return val; } ID acdSetObo TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD obo term input DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetObo(AcdPAcd thys) { AjPOboall val; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok = ajFalse; ajint itry; ajint maxreads; AjPStr infname = NULL; val = ajOboallNew(); /* set the default value */ acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); acdAttrToBool(thys, "entry", ajFalse, &val->Oboin->Input->Text); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajOboallDel(&val); break; } ajOboinQryS(val->Oboin, acdReply); acdGetValueAssoc(thys, "iformat", &val->Oboin->Input->Formatstr); acdGetValueAssoc(thys, "iquery", &val->Oboin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &val->Oboin->Input->Fpos, &acdTmpStr); ok = ajOboinRead(val->Oboin, val->Obo); } if(!ok) acdBadRetry(thys); if(maxreads > 1) val->Multi = ajTrue; acdInFileSave(acdReply, ajOboallGetoboId(val), ajTrue); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID acdSetOutType TY static MO ajacd LB acd XX DE Generic definition for any of the ACD formatted output types. DE May be replaced by a specific acdSet function if additional attributes DE or qualifiers are to be processed. DE DE Understands all attributes and associated qualifiers for these item types. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX PN [2] PA r type const char* PD Standard output type name. PX RT AjPOutfile RD Output file object of the specified type RX // static AjPOutfile acdSetOutType(AcdPAcd thys, const char* type) { AjPOutfile val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjBool nulldefault; AjPStr name = NULL; AjPStr ext = NULL; AjPStr fmt = NULL; AjPStr dir = NULL; ajint itype = -1; ajint i; val = NULL; for (i=0; acdOuttype[i].Name; i++) if (ajCharMatchC(acdOuttype[i].Name, type)) { itype = i; break; } if (itype < 0) acdError("Unknown output type '%s'", type); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); acdAttrResolve(thys, "name", &name); if (!acdGetValueAssoc(thys, "oformat", &fmt)) ajStrAssignC(&fmt, acdOuttype[itype].Format); if(!acdAttrResolve(thys, "extension", &ext)) ajStrAssignS(&ext, fmt); acdGetValueAssoc(thys, "odirectory", &dir); acdOutDirectory(&dir); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdOutFilename(&acdReplyDef, name, ext); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { acdOutFilename(&acdTmpOutFName, name, ext); acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef); } ajStrDel(&name); ajStrDel(&ext); if(acdOuttype[itype].Prompt) (*acdOuttype[itype].Prompt)(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { ajStrAssignS(&acdOutFullFName, acdReply); ajFilenameReplacePathS(&acdOutFullFName, dir); val = ajOutfileNewNameS(acdOutFullFName); if(!ok) { acdBadVal(thys, required, "Unable to open output file '%S'", acdOutFullFName); ajOutfileClose(&val); } ajStrAssignEmptyS(&val->Formatstr, fmt); ajStrAssignEmptyC(&val->Type, type); if(acdOuttype[itype].Outformat) { if(!(*acdOuttype[itype].Outformat)(val->Formatstr, &val->Format)) { /* test acdc-outbadformat */ ajDie("Output option -%S: " "Format validation failed for type '%s'", thys->Name, type); } } } else if(!nullok) { acdBadVal(thys, required, "Output file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdOutFullFName); ajStrDel(&fmt); ajStrDel(&dir); return val; } ID ajAcdGetOutassembly TY public MO ajacd LB acd XX DE Returns an item of type Outassembly as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutassembly(const char *token) { return acdGetValueRef(token, "outassembly"); } ID acdSetOutassembly TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outassembly item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutassembly(AcdPAcd thys) { acdSetOutType(thys, "outassembly"); return; } ID ajAcdGetOutcodon TY public MO ajacd LB acd XX DE Returns an item of type Outcodon as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutcodon(const char *token) { return acdGetValueRef(token, "outcodon"); } ID acdSetOutcodon TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outcodon item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutcodon(AcdPAcd thys) { acdSetOutType(thys, "outcodon"); return; } ID ajAcdGetOutcpdb TY public MO ajacd LB acd XX DE Returns an item of type Outcpdb as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutcpdb(const char *token) { return acdGetValueRef(token, "outcpdb"); } ID acdSetOutcpdb TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outcpdb item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutcpdb(AcdPAcd thys) { acdSetOutType(thys, "outcpdb"); return; } ID ajAcdGetOutdata TY public MO ajacd LB acd XX DE Returns an item of type Outdata as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutdata(const char *token) { return acdGetValueRef(token, "outdata"); } ID acdSetOutdata TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outdata item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutdata(AcdPAcd thys) { acdSetOutType(thys, "outdata"); return; } ID ajAcdGetOutdir TY public MO ajacd LB acd XX DE Returns an item of type AjPDirout which has been validated as an output DE directory. DE DE Optionally can be forced to have a fully qualified path when returned. XX PN [1] PA r token const char* PD Text token name PX RT AjPDirout RD Output directory object RX // AjPDirout ajAcdGetOutdir(const char *token) { return acdGetValueRef(token, "outdir"); } ID ajAcdGetOutdirName TY public MO ajacd LB acd XX DE Returns an item of type AjPStr which has been validated as an output DE directory. DE DE Optionally can be forced to have a fully qualified path when returned. XX PN [1] PA r token const char* PD Text token name PX RT AjPStr RD String containing a directory name RX // AjPStr ajAcdGetOutdirName(const char *token) { AjPStr ret = NULL; AjPDirout dirout; dirout = acdGetValue(token, "outdir"); ret = ajStrNewS(ajDiroutGetPath(dirout)); return ret; } ID acdSetOutdir TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD output directory item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value is "." the current directory. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutdir(AcdPAcd thys) { AjPDirout val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok = ajFalse; AjBool dopath = ajFalse; AjBool create = ajFalse; AjPStr ext = NULL; val = NULL; /* set the default value */ acdAttrToBool(thys, "fullpath", ajFalse, &dopath); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "create", ajFalse, &create); acdGetValueAssoc(thys, "extension", &ext); required = acdIsRequired(thys); acdReplyInitC(thys, ".", &acdReplyDef); acdPromptOutdir(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { ajDebug("acdSetOutdir start reply '%S' dopath:%B ok:%B\n", acdReply, dopath,ok); if(dopath) ok = ajDirnameFillPath(&acdReply); ajDebug("acdSetOutdir dir done reply '%S' dopath:%B ok:%B\n", acdReply, dopath,ok); if (ok) { val = ajDiroutNewPathExt(acdReply, ext); if (!val) ok = ajFalse; else { if(create) ok = ajDiroutOpen(val); else ok = ajDiroutExists(val); } } if(!ok) acdBadVal(thys, required, "Unable to open output directory '%S'", acdReply); } else if(!nullok) { acdBadVal(thys, required, "Directory path is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&ext); return; } ID ajAcdGetOutdiscrete TY public MO ajacd LB acd XX DE Returns an item of type Outdiscrete as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutdiscrete(const char *token) { return acdGetValueRef(token, "outdiscrete"); } ID acdSetOutdiscrete TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outdiscrete item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutdiscrete(AcdPAcd thys) { acdSetOutType(thys, "outdiscrete"); return; } ID ajAcdGetOutdistance TY public MO ajacd LB acd XX DE Returns an item of type Outdistance as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutdistance(const char *token) { return acdGetValueRef(token, "outdistance"); } ID acdSetOutdistance TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outdistance item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutdistance(AcdPAcd thys) { acdSetOutType(thys, "outdistance"); return; } ID ajAcdGetOutfile TY public MO ajacd LB acd XX DE Returns an item of type Outfile as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFile RD File object. The file was already opened by RD acdSetOutfile so this just returns the pointer. RX // AjPFile ajAcdGetOutfile(const char *token) { return acdGetValueRef(token, "outfile"); } ID ajAcdGetOutfileName TY public MO ajacd LB acd XX DE Returns the filename of an item of type Outfile as defined in a DE named ACD item. The file is closed and can be reused. If the file DE had the append attribute set it still has the original contents. DE DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPStr RD Filename. RX // AjPStr ajAcdGetOutfileName(const char *token) { AjPStr ret; AjPFile outfile; outfile = acdGetValueRef(token, "outfile"); if(!outfile) return NULL; ret = ajStrNewS(ajFileGetPrintnameS(outfile)); ajFileClose(&outfile); return ret; } ID acdSetOutfile TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outfile item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value, if stdout or filtering is on is "stdout" for the DE first file. DE DE Otherwise an output file name is constructed. DE DE Various file naming options are defined, but not yet implemented here. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutfile(AcdPAcd thys) { AjPFile val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjBool nulldefault; AjBool append; AjPStr name = NULL; AjPStr ext = NULL; AjPStr dir = NULL; val = NULL; /* set the default value */ acdAttrResolve(thys, "name", &name); acdAttrResolve(thys, "extension", &ext); acdGetValueAssoc(thys, "odirectory", &dir); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); acdAttrToBool(thys, "append", ajFalse, &append); acdOutDirectory(&dir); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdOutFilename(&acdReplyDef, name, ext); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { acdOutFilename(&acdTmpOutFName, name, ext); acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef); } ajStrDel(&name); ajStrDel(&ext); acdPromptOutfile(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); ajStrAssignS(&acdOutFullFName, acdReply); if(ajStrGetLen(acdReply)) { ajFilenameReplacePathS(&acdOutFullFName, dir); if(append) val = ajFileNewOutappendNameS(acdOutFullFName); else val = ajFileNewOutNameS(acdOutFullFName); if(!val) { acdBadVal(thys, required, "Unable to open file '%S' for output", acdOutFullFName); ok = ajFalse; } } else if(!nullok) { acdBadVal(thys, required, "Output file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdOutFullFName); ajStrDel(&dir); return; } ID ajAcdGetOutfreq TY public MO ajacd LB acd XX DE Returns an item of type Outfreq as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutfreq(const char *token) { return acdGetValueRef(token, "outfreq"); } ID acdSetOutfreq TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outfreq item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutfreq(AcdPAcd thys) { acdSetOutType(thys, "outfreq"); return; } ID ajAcdGetOutmatrix TY public MO ajacd LB acd XX DE Returns an item of type Outmatrix as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutmatrix(const char *token) { return acdGetValueRef(token, "outmatrix"); } ID acdSetOutmatrix TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outmatrix item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutmatrix(AcdPAcd thys) { acdSetOutType(thys, "outmatrix"); return; } ID ajAcdGetOutmatrixf TY public MO ajacd LB acd XX DE Returns an item of type Outmatrixf as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutmatrixf(const char *token) { return acdGetValueRef(token, "outmatrixf"); } ID acdSetOutmatrixf TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outmatrixf item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutmatrixf(AcdPAcd thys) { acdSetOutType(thys, "outmatrixf"); return; } ID ajAcdGetOutobo TY public MO ajacd LB acd XX DE Returns an item of type Outobo as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutobo(const char *token) { return acdGetValueRef(token, "outobo"); } ID acdSetOutobo TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outobo item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutobo(AcdPAcd thys) { acdSetOutType(thys, "outobo"); return; } ID ajAcdGetOutproperties TY public MO ajacd LB acd XX DE Returns an item of type Outproperties as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutproperties(const char *token) { return acdGetValueRef(token, "outproperties"); } ID acdSetOutproperties TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outproperties item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutproperties(AcdPAcd thys) { acdSetOutType(thys, "properties"); return; } ID ajAcdGetOutrefseq TY public MO ajacd LB acd XX DE Returns an item of type Outrefseq as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutrefseq(const char *token) { return acdGetValueRef(token, "outrefseq"); } ID acdSetOutrefseq TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outrefseq item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutrefseq(AcdPAcd thys) { acdSetOutType(thys, "outrefseq"); return; } ID ajAcdGetOutresource TY public MO ajacd LB acd XX DE Returns an item of type Outresource as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutresource(const char *token) { return acdGetValueRef(token, "outresource"); } ID acdSetOutresource TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD data resource output item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutresource(AcdPAcd thys) { acdSetOutType(thys, "outresource"); return; } ID ajAcdGetOutscop TY public MO ajacd LB acd XX DE Returns an item of type Outscop as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutscop(const char *token) { return acdGetValueRef(token, "outscop"); } ID acdSetOutscop TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outscop item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutscop(AcdPAcd thys) { acdSetOutType(thys, "outscop"); return; } ID ajAcdGetOuttaxon TY public MO ajacd LB acd XX DE Returns an item of type Outtaxon as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOuttaxon(const char *token) { return acdGetValueRef(token, "outtaxon"); } ID acdSetOuttaxon TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outtaxon item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOuttaxon(AcdPAcd thys) { acdSetOutType(thys, "outtaxon"); return; } ID ajAcdGetOuttext TY public MO ajacd LB acd XX DE Returns an item of type Outtext as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOuttext(const char *token) { return acdGetValueRef(token, "outtext"); } ID acdSetOuttext TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outtext item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOuttext(AcdPAcd thys) { acdSetOutType(thys, "outtext"); return; } ID ajAcdGetOuttree TY public MO ajacd LB acd XX DE Returns an item of type Outtree as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOuttree(const char *token) { return acdGetValueRef(token, "outtree"); } ID acdSetOuttree TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outtree item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOuttree(AcdPAcd thys) { acdSetOutType(thys, "outtree"); return; } ID ajAcdGetOuturl TY public MO ajacd LB acd XX DE Returns an item of type Outurl as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOuturl(const char *token) { return acdGetValueRef(token, "outurl"); } ID acdSetOuturl TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outurl item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOuturl(AcdPAcd thys) { acdSetOutType(thys, "outurl"); return; } ID ajAcdGetOutvariation TY public MO ajacd LB acd XX DE Returns an item of type Outvariation as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPOutfile RD File object. The file was already opened by RD acdSetOut so this just returns the pointer. RX // AjPOutfile ajAcdGetOutvariation(const char *token) { return acdGetValueRef(token, "outvariation"); } ID acdSetOutvariation TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD outvariation item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-oformat" DE are stored in the object and applied to the data on output. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetOutvariation(AcdPAcd thys) { acdSetOutType(thys, "outvariation"); return; } ID ajAcdGetPattern TY public MO ajacd LB acd XX DE Returns an item of type Pattern as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPatlistSeq RD Compiled pattern list of sequence patterns. RD The original pattern string is available RD through a call to ajAcdGetValue RX // AjPPatlistSeq ajAcdGetPattern(const char *token) { return acdGetValueRef(token, "pattern"); } ID acdSetPattern TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD sequence pattern item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is NULL. DE DE Attributes for minimum and maximum length are applied with error DE messages if exceeded. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetPattern(AcdPAcd thys) { AjPPatlistSeq val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool upper; AjBool lower; ajint itry; ajint minlen; ajint maxlen; ajint maxsize; ajint len; AjPStr type = NULL; AjPStr patname = NULL; AjPStr fmt = NULL; ajint mismatch = 0; AjBool isprotein = ajTrue; acdAttrToInt(thys, "minlength", 1, &minlen); acdAttrToInt(thys, "maxlength", INT_MAX, &maxlen); acdAttrToBool(thys, "upper", ajFalse, &upper); acdAttrToBool(thys, "lower", ajFalse, &lower); acdAttrToStr(thys, "type", "protein", &type); acdAttrToInt(thys, "maxsize", INT_MAX, &maxsize); acdQualToInt(thys, "pmismatch", 0, &mismatch, &acdTmpStr); acdGetValueAssoc(thys, "pname", &patname); acdGetValueAssoc(thys, "pformat", &fmt); ajStrFmtLower(&type); if(ajStrGetCharFirst(type) != 'p') isprotein = ajFalse; if(mismatch < 0) mismatch = 0; ajDebug("acdSetPattern name '%S' mismatch %d type '%S' protein %B\n", patname, mismatch, type, isprotein); required = acdIsRequired(thys); acdReplyInitC(thys, "", &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ if(val) ajPatlistSeqDel(&val); ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); len = ajStrGetLen(acdReply); if(len < minlen) { acdBadVal(thys, required, "Too short (%S) - minimum length is %d characters", thys->Name, minlen); ok = ajFalse; } if(len > maxlen) { acdBadVal(thys, required, "Too long (%S) - maximum length is %d characters", thys->Name,maxlen); ok = ajFalse; } if(ok) val = ajPatlistSeqRead(acdReply, patname, fmt, isprotein, mismatch); if(ok && !val) { acdBadVal(thys, required, "Bad pattern definition:\n '%S'", acdReply); ok = ajFalse; } } if(!ok) acdBadRetry(thys); ajStrDel(&patname); ajStrDel(&fmt); ajStrDel(&type); /* regexps have special set attributes the same as strings */ thys->SAttr = acdAttrListCount(acdCalcRegexp); thys->SetAttr = &acdCalcRegexp[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[0], ajStrGetLen(acdReply)); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID ajAcdGetProperties TY public MO ajacd LB acd XX DE Returns an item of type Properties as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPhyloProp RD Properties array. The data was already set by RD acdSetProperties so this just returns the pointer. RX // AjPPhyloProp ajAcdGetProperties(const char *token) { return acdGetValueRef(token, "properties"); } ID acdSetProperties TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD proerties file item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is an empty string. DE DE Attributes for length and maximum property character are applied with error DE messages if exceeded. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetProperties(AcdPAcd thys) { AjPPhyloProp val; AjBool required = ajFalse; AjBool ok = ajFalse; AjPStr infname = NULL; ajint itry; AjBool nullok = ajFalse; ajint size; ajint len; AjPStr propchars = NULL; val = NULL; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "length", 0, &len); acdAttrToInt(thys, "size", 1, &size); acdAttrToStr(thys, "characters", "", &propchars); ajDebug("acdSetProperties len: %d size: %d\n", len, size); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptInfile(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajPhyloPropRead(acdReply, propchars, len, size); if(!val) { acdBadVal(thys, required, "Unable to read properties from '%S'", acdReply); ok = ajFalse; } } else if(!nullok) { acdBadVal(thys, required, "Input file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, NULL, ajTrue); /* properties have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcProperties); thys->SetAttr = &acdCalcProperties[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); if(val) { ajStrFromInt(&thys->SetStr[0],val->Len); /* string length */ ajStrFromInt(&thys->SetStr[1],val->Size); /* string count */ ajStrAssignS(&thys->ValStr, val->Str[0]); } else { ajStrFromInt(&thys->SetStr[0],0); /* string length */ ajStrFromInt(&thys->SetStr[1],0); /* string count */ ajStrAssignClear(&thys->ValStr); } thys->Value = val; ajStrDel(&propchars); return; } ID ajAcdGetRange TY public MO ajacd LB acd XX DE Returns an item of type Range as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPRange RD Range object. RX // AjPRange ajAcdGetRange(const char *token) { return acdGetValueRef(token, "range"); } ID acdSetRange TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD range item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetRange(AcdPAcd thys) { AjPRange val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool warnrange; AjBool failrange; ajint itry; ajuint imin; ajuint imax; ajuint isize; ajuint iminsize; AjPStr failmsg = NULL; acdRangeTestCalc(thys); acdAttrToUint(thys, "minimum", 1, &imin); acdLog("minimum: %d\n", imin); acdAttrToUint(thys, "maximum", UINT_MAX, &imax); acdLog("maximum: %d\n", imax); acdAttrToUint(thys, "minsize", 0, &iminsize); acdLog("minsize: %d\n", iminsize); acdAttrToUint(thys, "size", 0, &isize); acdLog("size: %d\n", isize); acdAttrToBool(thys, "failrange", ajTrue, &failrange); acdLog("failrange: %B\n", failrange); acdAttrToBool(thys, "warnrange", acdDoWarnRange, &warnrange); acdLog("warnrange: %B\n", warnrange); if(failrange && (imin > imax)) { acdAttrResolve(thys, "rangemessage", &failmsg); if(ajStrGetLen(failmsg)) acdErrorAcd(thys, "Invalid range: %S", failmsg); else acdErrorAcd(thys, "Invalid range: " "minimum value %d more than maximum %d", imin, imax); } required = acdIsRequired(thys); acdReplyInitC(thys, "", &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); val = ajRangeNewStringLimits(acdReply, imin, imax, iminsize, isize); if(!val) { acdBadVal(thys, required, "Bad range specification '%S'", acdReply); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID ajAcdGetRefseq TY public MO ajacd LB acd XX DE Returns an item of type reference sequence as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPRefseq RD Reference sequence object RX // AjPRefseq ajAcdGetRefseq(const char *token) { AjPRefseq val = acdGetValueRef(token, "refseq"); return val; } ID acdSetRefseq TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD reference sequence input DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetRefseq(AcdPAcd thys) { AjPRefseq val; AjPRefseqin refseqin; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok = ajFalse; ajint itry; AjPStr infname = NULL; val = ajRefseqNew(); /* set the default value */ refseqin = ajRefseqinNew(); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); acdAttrToBool(thys, "entry", ajFalse, &refseqin->Input->Text); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajRefseqinDel(&refseqin); break; } ajRefseqinQryS(refseqin, acdReply); acdGetValueAssoc(thys, "iformat", &refseqin->Input->Formatstr); acdGetValueAssoc(thys, "iquery", &refseqin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &refseqin->Input->Fpos, &acdTmpStr); ok = ajRefseqinRead(refseqin, val); } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, ajRefseqGetId(val), ajTrue); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajRefseqinDel(&refseqin); return; } ID ajAcdGetRegexp TY public MO ajacd LB acd XX DE Returns an item of type Regexp as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPatlistRegex RD Compiled regular expression pattern. RD The original pattern string is available RD through a call to ajAcdGetValue RX // AjPPatlistRegex ajAcdGetRegexp(const char *token) { return acdGetValueRef(token, "regexp"); } ID ajAcdGetRegexpSingle TY public MO ajacd LB acd XX DE Returns an item of type Regexp as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPRegexp RD Compiled regular expression. RD The original pattern string is available RD through a call to ajAcdGetValue RX // AjPRegexp ajAcdGetRegexpSingle(const char *token) { AjPPatlistRegex val; AjPPatternRegex patreg = NULL; ajint i = 0; val = acdGetValueSingle(token, "regexp"); while (ajPatlistRegexGetNext(val, &patreg)) i++; if(i > 1) ajWarn("Single list value %s, but can choose %d values", token, i); if(i < 1) ajWarn("Single list value %s, no value found: returning NULL value", token); return ajPatternRegexGetCompiled(patreg); } ID acdSetRegexp TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD regular expression item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is NULL. DE DE Attributes for minimum and maximum length are applied with error DE messages if exceeded. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetRegexp(AcdPAcd thys) { AjPPatlistRegex val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool upper; AjBool lower; ajint itry; ajint minlen; ajint maxlen; ajint maxsize; ajint len; AjPStr type = NULL; AjPStr patname = NULL; AjPStr fmt = NULL; ajint itype = 0; acdAttrToInt(thys, "minlength", 1, &minlen); acdAttrToInt(thys, "maxlength", INT_MAX, &maxlen); acdAttrToBool(thys, "upper", ajFalse, &upper); acdAttrToBool(thys, "lower", ajFalse, &lower); acdAttrToStr(thys, "type", "string", &type); acdAttrToInt(thys, "maxsize", INT_MAX, &maxsize); acdGetValueAssoc(thys, "pname", &patname); acdGetValueAssoc(thys, "pformat", &fmt); ajStrFmtLower(&type); itype = ajPatternRegexType(type); required = acdIsRequired(thys); acdReplyInitC(thys, "", &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ if(val) ajPatlistRegexDel(&val); ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); len = ajStrGetLen(acdReply); if(len < minlen) { acdBadVal(thys, required, "Too short (%S) - minimum length is %d characters", thys->Name, minlen); ok = ajFalse; } if(len > maxlen) { acdBadVal(thys, required, "Too long (%S) - maximum length is %d characters", thys->Name,maxlen); ok = ajFalse; } /* if(upper) ajStrFmtUpper(&acdReply); if(lower) ajStrFmtLower(&acdReply); */ if(ok) val = ajPatlistRegexRead(acdReply, patname, fmt, itype, upper, lower); if(ok && !val) { acdBadVal(thys, required, "Bad regular expression pattern:\n '%S'", acdReply); ok = ajFalse; } } if(!ok) acdBadRetry(thys); ajStrDel(&patname); ajStrDel(&fmt); ajStrDel(&type); /* regexps have special set attributes the same as strings */ thys->SAttr = acdAttrListCount(acdCalcRegexp); thys->SetAttr = &acdCalcRegexp[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[0], ajStrGetLen(acdReply)); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID acdSetRel TY static MO ajacd LB acd XX DE Defines an ACD relation. DE DE Called when a "variable" type ACD item is checked. Should not be called DE for any other item. DE DE At present there is nothing to prompt for here, though there could DE be, for example, a report of what the program does which would appear DE before any user prompts. XX PN [1] PA u thys AcdPAcd PD ACD for the application item. PX RT void RD RX // static void acdSetRel(AcdPAcd thys) { acdAttrToStr(thys, "relations", "", &thys->ValStr); return; } ID ajAcdGetReport TY public MO ajacd LB acd XX DE Returns an item of type Report as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPReport RD Report output object. Already opened RD by ajReportOpen so this just returns the object RX // AjPReport ajAcdGetReport(const char *token) { return acdGetValueRef(token, "report"); } ID acdSetReport TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD report item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-rformat", "-ropenfile" DE are applied to the URO before opening the output file. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetReport(AcdPAcd thys) { AjPReport val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjBool nulldefault; AjPStr name = NULL; AjPStr ext = NULL; AjPStr fmt = NULL; AjPStr dir = NULL; AjPStr taglist = NULL; val = NULL; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); acdGetValueAssoc(thys, "rdirectory", &dir); acdGetValueAssoc(thys, "rextension", &ext); acdGetValueAssoc(thys, "rname", &name); acdGetValueAssoc(thys, "rformat", &fmt); acdOutDirectory(&dir); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdOutFilename(&acdReplyDef, name, ext); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { acdOutFilename(&acdTmpOutFName, name, ext); acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef); } acdPromptReport(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajReportNew(); ajStrAssignEmptyS(&val->Formatstr, fmt); acdAttrToStr(thys, "type", "", &val->Type); acdAttrToStr(thys, "taglist", "", &taglist); acdAttrToBool(thys, "multiple", ajFalse, &val->Multi); acdAttrToInt(thys, "precision", 3, &val->Precision); acdQualToBool(thys, "raccshow", ajFalse, &val->Showacc, &acdReplyDef); acdQualToBool(thys, "rdesshow", ajFalse, &val->Showdes, &acdReplyDef); acdQualToBool(thys, "rscoreshow", ajTrue, &val->Showscore, &acdReplyDef); acdQualToBool(thys, "rstrandshow", ajTrue, &val->Showstrand, &acdReplyDef); acdQualToBool(thys, "rusashow", ajFalse, &val->Showusa, &acdReplyDef); acdQualToInt(thys, "rmaxall", 0, &val->MaxHitAll, &acdReplyDef); acdQualToInt(thys, "rmaxseq", 0, &val->MaxHitSeq, &acdReplyDef); /* test acdc-reportbadtaglist */ if(!ajReportSetTagsS(val, taglist)) acdErrorAcd(thys, "Bad tag list for report"); /* test acdc-reportbadtags */ if(!ajReportValid(val)) ajDie("Report option -%S: Validation failed", thys->Name); ajStrAssignS(&acdOutFullFName, acdReply); ajFilenameReplacePathS(&acdOutFullFName, dir); ok = ajReportOpen(val, acdOutFullFName); if(!ok) { acdBadVal(thys, required, "Unable to open report file '%S'", acdOutFullFName); ajReportDel(&val); } } else if(!nullok) { acdBadVal(thys, required, "Report file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdOutFullFName); ajStrDel(&acdReply); ajStrDel(&acdReplyDef); ajStrDel(&name); ajStrDel(&ext); ajStrDel(&fmt); ajStrDel(&dir); ajStrDel(&taglist); return; } ID ajAcdGetResource TY public MO ajacd LB acd XX DE Returns an item of type resource as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPResource RD Data resource object RX // AjPResource ajAcdGetResource(const char *token) { AjPResourceall val = acdGetValue(token, "resource"); if(val->Multi) ajWarn("ajAcdGetResource request single resource but maxreads > 1"); val->Returned = ajTrue; return val->Resource; } ID ajAcdGetResourceall TY public MO ajacd LB acd XX DE Returns an input stream of an item of type Resource as defined in a DE named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPResourceall RD Data resource input stream RX // AjPResourceall ajAcdGetResourceall(const char *token) { AjPResourceall val = acdGetValueRef(token, "resource"); if(!val->Multi) ajWarn("ajAcdGetResourceall request data resource input stream " "but maxreads is 1"); return val; } ID acdSetResource TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD data resource input DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetResource(AcdPAcd thys) { AjPResourceall val; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok = ajFalse; ajint itry; ajint maxreads; AjPStr infname = NULL; val = ajResourceallNew(); /* set the default value */ acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads); acdAttrToBool(thys, "entry", ajFalse, &val->Resourcein->Input->Text); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajResourceallDel(&val); break; } ajResourceinQryS(val->Resourcein, acdReply); acdGetValueAssoc(thys, "iformat", &val->Resourcein->Input->Formatstr); acdGetValueAssoc(thys, "iquery", &val->Resourcein->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &val->Resourcein->Input->Fpos, &acdTmpStr); ok = ajResourceinRead(val->Resourcein, val->Resource); } if(!ok) acdBadRetry(thys); if(maxreads > 1) val->Multi = ajTrue; acdInFileSave(acdReply, ajResourceallGetresourceId(val), ajTrue); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID ajAcdGetScop TY public MO ajacd LB acd XX DE Returns an item of type Scop as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPFile RD Scop input file. RX // AjPFile ajAcdGetScop(const char *token) { return acdGetValueRef(token, "scop"); } ID acdSetScop TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD clean pdb file item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetScop(AcdPAcd thys) { AjPFile val; AjPStr name = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjPStr fmt = NULL; val = NULL; /* set the default value */ acdAttrResolve(thys, "name", &name); if (!acdGetValueAssoc(thys, "format", &fmt)) ajStrAssignClear(&fmt); required = acdIsRequired(thys); acdReplyInitS(thys, name, &acdReplyDef); acdPromptScop(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajFileNewInNameS(acdReply); if(!val) { acdBadVal(thys, required, "Unable to read scop data '%S'", acdReply); ok = ajFalse; } } else { acdBadVal(thys, required, "Scop data file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&name); ajStrDel(&fmt); return; } ID ajAcdGetSelect TY public MO ajacd LB acd XX DE Returns an item of type Select as defined in a named ACD item, DE which is an array of strings terminated by a null value. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPStr* RD String array of values with NULL as last element. RX // AjPStr* ajAcdGetSelect(const char *token) { return acdGetValueRef(token, "selection"); } ID ajAcdGetSelectSingle TY public MO ajacd LB acd XX DE Returns one item from an array of type Select as defined in a named DE ACD item, which is an array of strings terminated by a null value. DE Called by the application after all ACD values have been set, and DE simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPStr RD String array of values with NULL as last element. RX // AjPStr ajAcdGetSelectSingle(const char *token) { AjPStr* val; ajint i; val = acdGetValueSingle(token, "select"); for(i=0; val[i]; i++) continue; if(i > 1) ajWarn("Single list value %s, but can choose %d values", token, i); if(i < 1) ajWarn("Single list value %s, no value found: returning NULL value", token); return val[0]; } ID acdSetSelect TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD select menu item. DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetSelect(AcdPAcd thys) { AjPStr* val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; ajint i; ajint min=0, max=5; val = NULL; /* set the default value */ required = acdIsRequired(thys); acdReplyInitC(thys, "", &acdReplyDef); acdAttrToInt(thys, "minimum", 1, &min); acdAttrToInt(thys, "maximum", 1, &max); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) { acdSelectPrompt(thys); acdUserGet(thys, &acdReply); } val = acdSelectValue(thys, min, max, acdReply); if(!val) { acdBadVal(thys, required, "Bad select option '%S'", acdReply); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; for(i=0; val[i]; i++) { if(i) ajStrAppendC(&thys->ValStr, ";"); ajStrAppendS(&thys->ValStr, val[i]); } return; } ID ajAcdGetSeq TY public MO ajacd LB acd XX DE Returns an item of type Seq as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPSeq RD Sequence object. The sequence was already loaded by RD acdSetSeq so this just returns the pointer. RX // AjPSeq ajAcdGetSeq(const char *token) { return acdGetValueRef(token, "sequence"); } ID acdSetSeq TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD sequence item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-sformat", "-sdbname", "-sopenfile", "-sid" DE are applied to the USA before reading the sequence. DE DE Associated qualifiers "-supper", "-slower" and "-sask" are applied DE after reading. DE DE Associated qualifiers "-sbegin", "-send" and "-sreverse" DE are applied as appropriate, with prompting for values, DE after the sequence has been read. They are applied to the sequence, DE and the resulting sequence is what is set in the ACD item. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetSeq(AcdPAcd thys) { AjPSeq val = NULL; AjPSeqin seqin; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool okbeg = ajFalse; AjBool okend = ajFalse; AjBool okrev = ajFalse; ajint itry; ajint i; AjPStr infname = NULL; ajint sqbegin = 0; ajint sqend = 0; AjBool sreverse = ajFalse; AjBool sprompt = ajFalse; AjBool snuc = ajFalse; AjBool sprot = ajFalse; AjBool nullok = ajFalse; AjPStr typestr = NULL; val = ajSeqNew(); /* set the default value */ seqin = ajSeqinNew(); /* set the default value */ acdQualToBool(thys, "snucleotide", ajFalse, &snuc, &acdReplyDef); acdQualToBool(thys, "sprotein", ajFalse, &sprot, &acdReplyDef); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToStr(thys, "type", "", &typestr); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptSeq(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajSeqDel(&val); break; } ajSeqinUsa(&seqin, acdReply); if(ajStrGetLen(typestr)) { ajStrAssignS(&seqin->Inputtype, typestr); acdInTypeSeqSave(seqin->Inputtype); } else acdInTypeSeqSave(NULL); acdAttrToBool(thys, "features", ajFalse, &seqin->Features); acdAttrToBool(thys, "entry", ajFalse, &seqin->Input->Text); acdGetValueAssoc(thys, "sformat", &seqin->Input->Formatstr); acdGetValueAssoc(thys, "sdbname", &seqin->Input->Db); /* acdGetValueAssoc(thys, "sopenfile", &seqin->Filename);*/ /* obsolete */ acdGetValueAssoc(thys, "sid", &seqin->Entryname); acdGetValueAssoc(thys, "iquery", &seqin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &seqin->Input->Fpos, &acdTmpStr); acdGetValueAssoc(thys, "ufo", &seqin->Ufo); acdGetValueAssoc(thys, "fformat", &seqin->Ftquery->Formatstr); acdGetValueAssoc(thys, "fopenfile", &seqin->Ftquery->Filename); acdQualToBool(thys, "scircular", ajFalse, &seqin->Circular, &acdTmpStr); acdQualToBool(thys, "supper", ajFalse, &seqin->Upper, &acdTmpStr); acdQualToBool(thys, "slower", ajFalse, &seqin->Lower, &acdTmpStr); okbeg = acdQualToSeqbegin(thys, "sbegin", 0, &sqbegin, &acdTmpStr); okend = acdQualToSeqend(thys, "send", 0, &sqend, &acdTmpStr); okrev = acdQualToBool(thys, "sreverse", ajFalse, &sreverse, &acdTmpStr); if(snuc) ajSeqinSetNuc(seqin); if(sprot) ajSeqinSetProt(seqin); i = ajStrGetLen(seqin->Ufo) + ajStrGetLen(seqin->Ftquery->Formatstr) + ajStrGetLen(seqin->Ftquery->Filename); if(i && !seqin->Features) ajWarn("Feature table ignored"); if(seqin->Features) acdLog("acdSetSeq with features UFO '%S'\n", seqin->Ufo); /* (try to) read the sequence */ ok = ajSeqRead(val, seqin); if(!ok) { acdBadVal(thys, required, "Unable to read sequence '%S'", acdReply); } } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, ajSeqGetNameS(val), ajTrue); /* save sequence name */ /* some standard options using associated qualifiers */ acdQualToBool(thys, "sask", ajFalse, &sprompt, &acdReplyDef); if(val) { /* now process the begin, end and reverse options */ if(seqin->Begin) okbeg = ajTrue; for(itry=acdPromptTry; itry && !okbeg; itry--) { ajStrAssignC(&acdReplyPrompt, "start"); if(sprompt) acdUserGetPrompt(thys, "sbegin", " Begin at position", &acdReplyPrompt); if(ajStrMatchCaseC(acdReplyPrompt, "start")) ajStrAssignC(&acdReplyPrompt, "0"); okbeg = ajStrToInt(acdReplyPrompt, &sqbegin); if(!okbeg) acdBadVal(thys, sprompt, "Invalid sequence position '%S'", acdReplyPrompt); } if(!okbeg) acdBadRetry(thys); if(sqbegin) { seqin->Begin = sqbegin; val->Begin = sqbegin; acdSetQualDefInt(thys, "sbegin", sqbegin); } if(seqin->End) okend = ajTrue; for(itry=acdPromptTry; itry && !okend; itry--) { ajStrAssignC(&acdReplyPrompt, "end"); if(sprompt) acdUserGetPrompt(thys, "send", " End at position", &acdReplyPrompt); if(ajStrMatchCaseC(acdReplyPrompt, "end")) ajStrAssignC(&acdReplyPrompt, "0"); okend = ajStrToInt(acdReplyPrompt, &sqend); if(!okend) acdBadVal(thys, sprompt, "Invalid sequence position '%S'", acdReplyPrompt); } if(!okend) acdBadRetry(thys); if(sqend) { seqin->End = sqend; val->End = sqend; acdSetQualDefInt(thys, "send", sqend); } if(ajSeqIsNuc(val)) { for(itry=acdPromptTry; itry && !okrev; itry--) { ajStrAssignC(&acdReplyPrompt, "N"); if(sprompt) acdUserGetPrompt(thys, "sreverse", " Reverse strand", &acdReplyPrompt); okrev = ajStrToBool(acdReplyPrompt, &sreverse); if(!okrev) acdBadVal(thys, sprompt, "Invalid Y/N value '%S'", acdReplyPrompt); } if(!okrev) acdBadRetry(thys); if(sreverse) { seqin->Rev = sreverse; val->Rev = sreverse; acdSetQualDefBool(thys, "sreverse", sreverse); } } acdLog("sbegin: %d, send: %d, sreverse: %B\n", sqbegin, sqend, sreverse); if(val->Rev) ajSeqReverseDo(val); /* sequences have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcSeq); thys->SetAttr = &acdCalcSeq[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], ajSeqGetBegin(val)); ajStrFromInt(&thys->SetStr[ACD_SEQ_END], ajSeqGetEnd(val)); ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], ajSeqGetLen(val)); ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajSeqIsNuc(val)); ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajSeqIsProt(val)); ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME], val->Name); ajStrAssignS(&thys->SetStr[ACD_SEQ_USA], ajSeqGetUsaS(val)); } else { /* sequences have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcSeq); thys->SetAttr = &acdCalcSeq[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_END], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], 0); ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajFalse); ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajFalse); ajStrAssignC(&thys->SetStr[ACD_SEQ_NAME], ""); ajStrAssignC(&thys->SetStr[ACD_SEQ_USA], ""); } thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajSeqinDel(&seqin); ajStrDel(&typestr); return; } ID ajAcdGetSeqall TY public MO ajacd LB acd XX DE Returns an item of type Seq as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPSeqall RD Sequence stream object. The sequence was already RD loaded by acdSetSeqall so this just returns the pointer. RX // AjPSeqall ajAcdGetSeqall(const char *token) { return acdGetValueRef(token, "seqall"); } ID acdSetSeqall TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD sequence item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-sformat", "-sdbname", "-sopenfile", "-sid" DE are applied to the USA before reading the sequence. DE DE Associated qualifier "-sask" is applied DE after reading. DE DE Associated qualifiers "-supper", "-slower" are applied DE globally DE DE Associated qualifiers "-sbegin", "-send" and "-sreverse" DE are applied as appropriate, with prompting for values, DE after the sequence has been read. They are applied to the sequence, DE and the resulting sequence is what is set in the ACD item. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetSeqall(AcdPAcd thys) { AjPSeqall val = NULL; AjPSeqin seqin; AjPSeq seq; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool okbeg = ajFalse; AjBool okend = ajFalse; AjBool okrev = ajFalse; ajint itry; AjBool nullok = ajFalse; AjPStr infname = NULL; ajint sqbegin = 0; ajint sqend = 0; AjBool sreverse = ajFalse; AjBool sprompt = ajFalse; AjBool snuc = ajFalse; AjBool sprot = ajFalse; AjPStr typestr = NULL; val = ajSeqallNew(); /* set the default value */ seqin = val->Seqin; seqin->Input->Multi = ajTrue; seq = val->Seq; acdQualToBool(thys, "snucleotide", ajFalse, &snuc, &acdReplyDef); acdQualToBool(thys, "sprotein", ajFalse, &sprot, &acdReplyDef); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToStr(thys, "type", "", &typestr); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptSeq(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajSeqallDel(&val); break; } ajSeqinUsa(&seqin, acdReply); if(ajStrGetLen(typestr)) { ajStrAssignS(&seqin->Inputtype, typestr); acdInTypeSeqSave(seqin->Inputtype); } else acdInTypeSeqSave(NULL); acdAttrToBool(thys, "features", ajFalse, &seqin->Features); acdAttrToBool(thys, "entry", ajFalse, &seqin->Input->Text); acdGetValueAssoc(thys, "sformat", &seqin->Input->Formatstr); acdGetValueAssoc(thys, "sdbname", &seqin->Input->Db); /* acdGetValueAssoc(thys, "sopenfile", &seqin->Filename);*/ /* obsolete */ acdGetValueAssoc(thys, "sid", &seqin->Entryname); acdGetValueAssoc(thys, "iquery", &seqin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &seqin->Input->Fpos, &acdTmpStr); acdGetValueAssoc(thys, "ufo", &seqin->Ufo); acdGetValueAssoc(thys, "fformat", &seqin->Ftquery->Formatstr); acdGetValueAssoc(thys, "fopenfile", &seqin->Ftquery->Filename); acdQualToBool(thys, "scircular", ajFalse, &seqin->Circular, &acdTmpStr); acdQualToBool(thys, "supper", ajFalse, &seqin->Upper, &acdTmpStr); acdQualToBool(thys, "slower", ajFalse, &seqin->Lower, &acdTmpStr); okbeg = acdQualToSeqbegin(thys, "sbegin", 0, &seqin->Begin, &acdTmpStr); okend = acdQualToSeqend(thys, "send", 0, &seqin->End, &acdTmpStr); okrev = acdQualToBool(thys, "sreverse", ajFalse, &sreverse, &acdTmpStr); if(snuc) ajSeqinSetNuc(seqin); if(sprot) ajSeqinSetProt(seqin); if(ajStrGetLen(seqin->Ufo)) seqin->Features = ajTrue; ok = ajSeqAllRead(seq, seqin); if(!ok) acdBadVal(thys, required, "Unable to read sequence '%S'", acdReply); } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, ajSeqallGetseqName(val), ajTrue); /* commentedout__ajSeqinDel(&seqin);*/ acdQualToBool(thys, "sask", ajFalse, &sprompt, &acdReplyDef); /* now process the begin, end and reverse options */ if(val) { if(seqin->Begin) { okbeg = ajTrue; val->Begin = seq->Begin = seqin->Begin; } for(itry=acdPromptTry; itry && !okbeg; itry--) { ajStrAssignC(&acdReplyPrompt, "start"); if(sprompt) acdUserGetPrompt(thys, "sbegin", " Begin at position", &acdReplyPrompt); if(ajStrMatchCaseC(acdReplyPrompt, "start")) ajStrAssignC(&acdReplyPrompt, "0"); okbeg = ajStrToInt(acdReplyPrompt, &sqbegin); if(!okbeg) acdBadVal(thys, sprompt, "Invalid integer value '%S'", acdReplyPrompt); } if(!okbeg) acdBadRetry(thys); if(sqbegin) { seqin->Begin = sqbegin; seq->Begin = sqbegin; val->Begin = sqbegin; acdSetQualDefInt(thys, "sbegin", sqbegin); } if(seqin->End) { okend = ajTrue; val->End = seq->End = seqin->End; } for(itry=acdPromptTry; itry && !okend; itry--) { ajStrAssignC(&acdReplyPrompt, "end"); if(sprompt) acdUserGetPrompt(thys, "send", " End at position", &acdReplyPrompt); if(ajStrMatchCaseC(acdReplyPrompt, "end")) ajStrAssignC(&acdReplyPrompt, "0"); okend = ajStrToInt(acdReplyPrompt, &sqend); if(!okend) acdBadVal(thys, sprompt, "Invalid integer value '%S'", acdReplyPrompt); } if(!okend) acdBadRetry(thys); if(sqend) { seqin->End = sqend; seq->End = sqend; val->End = sqend; acdSetQualDefInt(thys, "send", sqend); } if(ajSeqIsNuc(seq)) { for(itry=acdPromptTry; itry && !okrev; itry--) { ajStrAssignC(&acdReplyPrompt, "N"); if(sprompt) acdUserGetPrompt(thys, "sreverse", " Reverse strand", &acdReplyPrompt); okrev = ajStrToBool(acdReplyPrompt, &sreverse); if(!okrev) acdBadVal(thys, sprompt, "Invalid Y/N value '%S'", acdReplyPrompt); } if(!okrev) acdBadRetry(thys); if(sreverse) { seqin->Rev = sreverse; seq->Rev = sreverse; val->Rev = sreverse; acdSetQualDefBool(thys, "sreverse", sreverse); } } acdLog("sbegin: %d, send: %d, sreverse: %B\n", sqbegin, sqend, sreverse); /* sequences have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcSeqall); thys->SetAttr = &acdCalcSeqall[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], ajSeqallGetseqBegin(val)); ajStrFromInt(&thys->SetStr[ACD_SEQ_END], ajSeqallGetseqEnd(val)); ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], ajSeqGetLen(seq)); ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajSeqIsNuc(seq)); ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajSeqIsProt(seq)); ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME], seq->Name); ajStrAssignS(&thys->SetStr[ACD_SEQ_USA], ajSeqallGetUsa(val)); } else { /* sequences have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcSeqall); thys->SetAttr = &acdCalcSeq[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_END], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], 0); ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajFalse); ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajFalse); ajStrAssignC(&thys->SetStr[ACD_SEQ_NAME], ""); ajStrAssignC(&thys->SetStr[ACD_SEQ_USA], ""); } thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&typestr); return; } ID acdSetSeqsetall TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD sequence item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-sformat", "-sdbname", "-sopenfile", "-sid" DE are applied to the USA before reading the sequence. DE DE Associated qualifiers "-supper", "-slower" and "-sask" are applied DE after reading. DE DE Associated qualifiers "-sbegin", "-send" and "-sreverse" DE are applied as appropriate, with prompting for values, DE after the sequence has been read. They are applied to the sequence, DE and the resulting sequence is what is set in the ACD item. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetSeqsetall(AcdPAcd thys) { AjPSeqset *val = NULL; AjPSeqin seqin; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool okbeg = ajFalse; AjBool okend = ajFalse; AjBool okrev = ajFalse; ajint itry; ajint iattr; AjPStr infname = NULL; ajint sqbegin = 0; ajint sqend = 0; AjBool sreverse = ajFalse; AjBool sprompt = ajFalse; AjBool snuc = ajFalse; AjBool sprot = ajFalse; AjBool nullok = ajFalse; AjBool aligned = ajFalse; AjPStr typestr = NULL; void **sets = NULL; AjPList seqlist; ajint iset = 0; ajint nsets; seqlist = ajListNew(); seqin = ajSeqinNew(); /* set the default value */ seqin->Input->Multi = ajTrue; acdQualToBool(thys, "snucleotide", ajFalse, &snuc, &acdReplyDef); acdQualToBool(thys, "sprotein", ajFalse, &sprot, &acdReplyDef); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "aligned", ajFalse, &aligned); acdAttrToStr(thys, "type", "", &typestr); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptSeq(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) break; ajSeqinUsa(&seqin, acdReply); if(ajStrGetLen(typestr)) { ajStrAssignS(&seqin->Inputtype, typestr); acdInTypeSeqSave(seqin->Inputtype); } else acdInTypeSeqSave(NULL); acdAttrToBool(thys, "features", ajFalse, &seqin->Features); acdGetValueAssoc(thys, "sformat", &seqin->Input->Formatstr); acdGetValueAssoc(thys, "sdbname", &seqin->Input->Db); /* acdGetValueAssoc(thys, "sopenfile", &seqin->Filename);*/ /* obsolete */ acdGetValueAssoc(thys, "sid", &seqin->Entryname); acdGetValueAssoc(thys, "iquery", &seqin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &seqin->Input->Fpos, &acdTmpStr); acdGetValueAssoc(thys, "ufo", &seqin->Ufo); acdGetValueAssoc(thys, "fformat", &seqin->Ftquery->Formatstr); acdGetValueAssoc(thys, "fopenfile", &seqin->Ftquery->Filename); acdQualToBool(thys, "scircular", ajFalse, &seqin->Circular, &acdTmpStr); acdQualToBool(thys, "supper", ajFalse, &seqin->Upper, &acdTmpStr); acdQualToBool(thys, "slower", ajFalse, &seqin->Lower, &acdTmpStr); okbeg = acdQualToSeqbegin(thys, "sbegin", 0, &seqin->Begin, &acdTmpStr); okend = acdQualToSeqend(thys, "send", 0, &seqin->End, &acdTmpStr); okrev = acdQualToBool(thys, "sreverse", ajFalse, &sreverse, &acdTmpStr); if(snuc) ajSeqinSetNuc(seqin); if(sprot) ajSeqinSetProt(seqin); if(ajStrGetLen(seqin->Ufo)) seqin->Features = ajTrue; ok = ajSeqsetallRead(seqlist, seqin); if(!ok) acdBadVal(thys, required, "Unable to read sequence '%S'", acdReply); } if(!ok) acdBadRetry(thys); nsets = (ajuint) ajListToarray(seqlist,(void***) &sets); if(!nsets) { acdInFileSave(acdReply, ajStrConstEmpty(), ajTrue); /* sequences have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcSeqsetall); thys->SetAttr = &acdCalcSeq[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_END], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], 0); ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajFalse); ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajFalse); ajStrAssignC(&thys->SetStr[ACD_SEQ_NAME], ""); ajStrAssignC(&thys->SetStr[ACD_SEQ_USA], ""); ajStrFromFloat(&thys->SetStr[ACD_SEQ_WEIGHT], 0.0, 3); ajStrFromInt(&thys->SetStr[ACD_SEQ_COUNT], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_MULTICOUNT], 0); } else { val = (AjPSeqset*) sets; ajListFree(&seqlist); acdInFileSave(acdReply, ajSeqsetGetNameS(val[0]), ajTrue); /* save sequence name */ acdQualToBool(thys, "sask", ajFalse, &sprompt, &acdReplyDef); /* now process the begin, end and reverse options */ if(seqin->Begin) { okbeg = ajTrue; for(iset=0;isetBegin = seqin->Begin; } for(itry=acdPromptTry; itry && !okbeg; itry--) { ajStrAssignC(&acdReplyPrompt, "start"); if(sprompt) acdUserGetPrompt(thys, "sbegin", " Begin at position", &acdReplyPrompt); if(ajStrMatchCaseC(acdReplyPrompt, "start")) ajStrAssignC(&acdReplyPrompt, "0"); okbeg = ajStrToInt(acdReplyPrompt, &sqbegin); if(!okbeg) acdBadVal(thys, sprompt, "Invalid integer value '%S'", acdReplyPrompt); } if(!okbeg) acdBadRetry(thys); if(sqbegin) { seqin->Begin = sqbegin; for(iset=0;isetBegin = sqbegin; acdSetQualDefInt(thys, "sbegin", sqbegin); } if(seqin->End) { okend = ajTrue; for(iset=0;isetEnd = seqin->End; } for(itry=acdPromptTry; itry && !okend; itry--) { ajStrAssignC(&acdReplyPrompt, "end"); if(sprompt) acdUserGetPrompt(thys, "send", " End at position", &acdReplyPrompt); if(ajStrMatchCaseC(acdReplyPrompt, "end")) ajStrAssignC(&acdReplyPrompt, "0"); okend = ajStrToInt(acdReplyPrompt, &sqend); if(!okend) acdBadVal(thys, sprompt, "Invalid integer value '%S'", acdReplyPrompt); } if(!okend) acdBadRetry(thys); if(sqend) { seqin->End = sqend; for(iset=0;isetEnd = sqend; acdSetQualDefInt(thys, "send", sqend); } if(ajSeqsetIsNuc(val[0])) { for(itry=acdPromptTry; itry && !okrev; itry--) { ajStrAssignC(&acdReplyPrompt, "N"); if(sprompt) acdUserGetPrompt(thys, "sreverse", " Reverse strand", &acdReplyPrompt); okrev = ajStrToBool(acdReplyPrompt, &sreverse); if(!okrev) acdBadVal(thys, sprompt, "Invalid Y/N value '%S'", acdReplyPrompt); } if(!okrev) acdBadRetry(thys); if(sreverse) { seqin->Rev = sreverse; for(iset=0;isetRev = sreverse; acdSetQualDefBool(thys, "sreverse", sreverse); } } acdLog("sbegin: %d, send: %d, sreverse: Bs\n", sqbegin, sqend, sreverse); if(aligned) for(iset=0;isetRev) ajSeqsetReverse(val[iset]); /* sequences have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcSeqsetall); thys->SetAttr = &acdCalcSeqsetall[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], ajSeqsetGetBegin(val[0])); ajStrFromInt(&thys->SetStr[ACD_SEQ_END], ajSeqsetGetEnd(val[0])); ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], ajSeqsetGetLen(val[0])); ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajSeqsetIsProt(val[0])); ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajSeqsetIsNuc(val[0])); ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME], val[0]->Name); ajStrAssignS(&thys->SetStr[ACD_SEQ_USA], ajSeqsetGetUsa(val[0])); ajStrFromFloat(&thys->SetStr[ACD_SEQ_WEIGHT], ajSeqsetGetTotweight(val[0]), 3); ajStrFromInt(&thys->SetStr[ACD_SEQ_COUNT], ajSeqsetGetSize(val[0])); ajStrFromInt(&thys->SetStr[ACD_SEQ_MULTICOUNT], nsets); acdInFileSave(acdReply, ajSeqsetGetNameS(val[0]), ajTrue); for(iattr=0; iattr < thys->SAttr; iattr++) ajDebug("CalcAttr %s: '%S'\n", acdCalcSeqset[iattr].Name, thys->SetStr[iattr]); } thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajSeqinDel(&seqin); ajStrDel(&typestr); return; } ID ajAcdGetSeqout TY public MO ajacd LB acd XX DE Returns an item of type Seqout as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPSeqout RD Sequence output object. The file was already opened by RD acdSetSeqout so this just returns the pointer. RX // AjPSeqout ajAcdGetSeqout(const char *token) { return acdGetValueRef(token, "seqout"); } ID acdSetSeqout TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD sequence output item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is "stdout". DE DE Associated qualifier "-osformat" DE is applied to the USA before opening the output file. DE DE Associated qualifiers are defined but not yet implemented. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetSeqout(AcdPAcd thys) { AjPSeqout val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjBool nulldefault; AjPStr name = NULL; AjPStr ext = NULL; AjPStr fmt = NULL; AjPStr typestr = NULL; AjBool osfeat; val = NULL; if(!acdGetValueAssoc(thys, "osname", &name)) acdAttrResolve(thys, "name", &name); if(!acdGetValueAssoc(thys, "osextension", &ext)) acdAttrResolve(thys, "extension", &ext); acdGetValueAssoc(thys, "osformat", &fmt); ajStrAssignEmptyS(&ext, fmt); if(!ajStrGetLen(ext)) ajSeqoutstrGetFormatDefault(&ext); acdAttrToBool(thys, "features", ajFalse, &osfeat); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); if(!acdAttrToStr(thys, "type", "", &typestr)) acdInTypeSeq(&typestr); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdOutFilename(&acdReplyDef, name, ext); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { acdOutFilename(&acdTmpOutFName, name, ext); acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef); } ajStrDel(&name); acdPromptSeqout(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajSeqoutNew(); /* set the default value */ ajSeqoutClearUsa(val, acdReply); /* resets the AjPSeqout */ val->Features = osfeat; acdGetValueAssoc(thys, "osdirectory", &val->Directory); acdGetValueAssoc(thys, "osdbname", &val->Setoutdb); acdOutDirectory(&val->Directory); acdLog("acdSetSeqout features: %B dir '%S'\n", val->Features, val->Directory); ajStrAssignEmptyS(&val->Formatstr, fmt); if(!ajStrGetLen(val->Formatstr)) ajSeqoutstrGetFormatDefault(&val->Formatstr); ajStrAssignEmptyS(&val->Extension, ext); ajStrAssignEmptyS(&val->Extension, val->Formatstr); acdGetValueAssoc(thys, "oufo", &val->Ufo); acdGetValueAssoc(thys, "offormat", &val->Ftquery->Formatstr); if(!ajStrGetLen(val->Ftquery->Formatstr)) ajFeatOutFormatDefault(&val->Ftquery->Formatstr); acdGetValueAssoc(thys, "ofname", &val->Ftquery->Filename); acdGetValueAssoc(thys, "ofdirectory", &val->Ftquery->Directory); acdOutDirectory(&val->Ftquery->Directory); acdQualToBool(thys, "ossingle", ajFalse, &val->Single, &acdTmpStr); if(ajStrGetLen(typestr)) ajStrAssignS(&val->Outputtype, typestr); else { if(!acdInTypeSeq(&val->Outputtype)) ajWarn("No output type specified for '%S'", thys->Name); } if(!ajSeqoutOpen(val)) { if(ajStrGetLen(val->Directory)) acdBadVal(thys, required, "Unable to write sequence to '%S%S'", val->Directory, acdReply); else acdBadVal(thys, required, "Unable to write sequence to '%S'", acdReply); ok = ajFalse; ajSeqoutDel(&val); } } else if(!nullok) { acdBadVal(thys, required, "Output USA is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); if (val) { acdLog("acdSetSeqout features: %B\n", val->Features); if(val->Features) acdLog("acdSetSeqout with features UFO '%S'\n", val->Ufo); } ajStrDel(&typestr); ajStrDel(&fmt); ajStrDel(&ext); return; } ID ajAcdGetSeqoutall TY public MO ajacd LB acd XX DE Returns an item of type Seqoutall as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPSeqout RD Sequence output object. The file was already RD opened by acdSetSeqoutall so this just returns the pointer. RX // AjPSeqout ajAcdGetSeqoutall(const char *token) { return acdGetValueRef(token, "seqoutall"); } ID acdSetSeqoutall TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD sequence output item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is "stdout". DE DE Associated qualifier "-osformat" DE is applied to the USA before opening the output file. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetSeqoutall(AcdPAcd thys) { AjPSeqout val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AjBool nullok; AjBool nulldefault; AjPStr name = NULL; AjPStr ext = NULL; AjPStr fmt = NULL; AjPStr typestr = NULL; AjBool osfeat; val = NULL; if(!acdGetValueAssoc(thys, "osname", &name)) acdAttrResolve(thys, "name", &name); if(!acdGetValueAssoc(thys, "osextension", &ext)) acdAttrResolve(thys, "extension", &ext); acdGetValueAssoc(thys, "osformat", &fmt); ajStrAssignEmptyS(&ext, fmt); if(!ajStrGetLen(ext)) ajSeqoutstrGetFormatDefault(&ext); acdAttrToBool(thys, "features", ajFalse, &osfeat); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); if(!acdAttrToStr(thys, "type", "", &typestr)) acdInTypeSeq(&typestr); required = acdIsRequired(thys); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdOutFilename(&acdReplyDef, name, ext); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { acdOutFilename(&acdTmpOutFName, name, ext); acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef); } ajStrDel(&name); acdPromptSeqout(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajSeqoutNew(); /* set the default value */ ajSeqoutClearUsa(val, acdReply); val->Features = osfeat; acdGetValueAssoc(thys, "osdirectory", &val->Directory); acdGetValueAssoc(thys, "osdbname", &val->Setoutdb); acdOutDirectory(&val->Directory); acdLog("acdSetSeqoutall features: %B\n", val->Features); ajStrAssignEmptyS(&val->Formatstr, fmt); if(!ajStrGetLen(val->Formatstr)) ajSeqoutstrGetFormatDefault(&val->Formatstr); ajStrAssignEmptyS(&val->Extension, ext); ajStrAssignEmptyS(&val->Extension, val->Formatstr); acdGetValueAssoc(thys, "oufo", &val->Ufo); acdGetValueAssoc(thys, "offormat", &val->Ftquery->Formatstr); if(!ajStrGetLen(val->Ftquery->Formatstr)) ajFeatOutFormatDefault(&val->Ftquery->Formatstr); acdGetValueAssoc(thys, "ofname", &val->Ftquery->Filename); acdGetValueAssoc(thys, "ofdirectory", &val->Ftquery->Directory); acdOutDirectory(&val->Ftquery->Directory); acdLog("acdSetSeqoutall ossingle default: %B\n", ajSeqoutstrIsFormatSingle(val->Formatstr)); acdQualToBool(thys, "ossingle", ajSeqoutstrIsFormatSingle(val->Formatstr), &val->Single, &acdTmpStr); acdLog("acdSetSeqoutall ossingle value %B '%S'\n", val->Single, acdTmpStr); if(ajStrGetLen(typestr)) ajStrAssignS(&val->Outputtype, typestr); else { if(!acdInTypeSeq(&val->Outputtype)) ajWarn("No output type specified for '%S'", thys->Name); } if(!ajSeqoutOpen(val)) { if(ajStrGetLen(val->Directory)) acdBadVal(thys, required, "Unable to write sequence to '%S%S'", val->Directory, acdReply); else acdBadVal(thys, required, "Unable to write sequence to '%S'", acdReply); ok = ajFalse; ajSeqoutDel(&val); } } else if(!nullok) { acdBadVal(thys, required, "Output USA is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&typestr); ajStrDel(&fmt); ajStrDel(&ext); return; } ID ajAcdGetSeqoutset TY public MO ajacd LB acd XX DE Returns an item of type Seqoutset as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPSeqout RD Sequence output object. The file was already RD opened by acdSetSeqoutset so this just returns the pointer. RX // AjPSeqout ajAcdGetSeqoutset(const char *token) { return acdGetValueRef(token, "seqoutset"); } ID acdSetSeqoutset TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD sequence output item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is "stdout". DE DE Associated qualifier "-osformat" DE is applied to the USA before opening the output file. DE DE Associated qualifiers are defined but not yet implemented. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetSeqoutset(AcdPAcd thys) { AjPSeqout val = NULL; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok; AjBool nulldefault; ajint itry; AjPStr name = NULL; AjPStr ext = NULL; AjPStr fmt = NULL; AjPStr typestr = NULL; AjBool osfeat; val = NULL; if(!acdGetValueAssoc(thys, "osname", &name)) acdAttrResolve(thys, "name", &name); if(!acdGetValueAssoc(thys, "osextension", &ext)) acdAttrResolve(thys, "extension", &ext); acdGetValueAssoc(thys, "osformat", &fmt); ajStrAssignEmptyS(&ext, fmt); if(!ajStrGetLen(ext)) ajSeqoutstrGetFormatDefault(&ext); acdAttrToBool(thys, "features", ajFalse, &osfeat); required = acdIsRequired(thys); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "nulldefault", ajFalse, &nulldefault); if(!acdAttrToStr(thys, "type", "", &typestr)) acdInTypeSeq(&typestr); if(nullok && nulldefault) { if (acdDefinedEmpty(thys)) /* user set to empty - make default name */ acdOutFilename(&acdReplyDef, name, ext); else /* leave empty */ acdReplyInitC(thys, "", &acdReplyDef); } else { acdOutFilename(&acdTmpOutFName, name, ext); acdReplyInitS(thys, acdTmpOutFName, &acdReplyDef); } ajStrDel(&name); acdPromptSeqout(thys); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajSeqoutNew(); /* set the default value */ ajSeqoutClearUsa(val, acdReply); acdGetValueAssoc(thys, "osdbname", &val->Setoutdb); val->Features = osfeat; acdGetValueAssoc(thys, "osdirectory", &val->Directory); acdOutDirectory(&val->Directory); acdLog("acdSetSeqoutset features: %B\n", val->Features); ajStrAssignEmptyS(&val->Formatstr, fmt); if(!ajStrGetLen(val->Formatstr)) ajSeqoutstrGetFormatDefault(&val->Formatstr); ajStrAssignEmptyS(&val->Extension, ext); ajStrAssignEmptyS(&val->Extension, val->Formatstr); acdGetValueAssoc(thys, "oufo", &val->Ufo); acdGetValueAssoc(thys, "offormat", &val->Ftquery->Formatstr); if(!ajStrGetLen(val->Ftquery->Formatstr)) ajFeatOutFormatDefault(&val->Ftquery->Formatstr); acdGetValueAssoc(thys, "ofname", &val->Ftquery->Filename); acdGetValueAssoc(thys, "ofdirectory", &val->Ftquery->Directory); acdOutDirectory(&val->Ftquery->Directory); acdQualToBool(thys, "ossingle", ajSeqoutstrIsFormatSingle(val->Formatstr), &val->Single, &acdTmpStr); if(ajStrGetLen(typestr)) ajStrAssignS(&val->Outputtype, typestr); else { if(!acdInTypeSeq(&val->Outputtype)) ajWarn("No output type specified for '%S'", thys->Name); } if(!ajSeqoutOpen(val)) { if(ajStrGetLen(val->Directory)) acdBadVal(thys, required, "Unable to write sequence to '%S%S'", val->Directory, acdReply); else acdBadVal(thys, required, "Unable to write sequence to '%S'", acdReply); ok = ajFalse; ajSeqoutDel(&val); } } else if(!nullok) { acdBadVal(thys, required, "Output USA is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&typestr); ajStrDel(&fmt); ajStrDel(&ext); return; } ID ajAcdGetSeqset TY public MO ajacd LB acd XX DE Returns an item of type Seqset as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPSeqset RD Sequence set object. The sequence was already loaded by RD acdSetSeqset so this just returns the pointer. RX // AjPSeqset ajAcdGetSeqset(const char *token) { return acdGetValueRef(token, "seqset"); } ID acdSetSeqset TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD sequence item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is a null string, which DE is invalid. DE DE Associated qualifiers "-sformat", "-sdbname", "-sopenfile", "-sid" DE are applied to the USA before reading the sequence. DE DE Associated qualifiers "-supper", "-slower" and "-sask" are applied DE after reading. DE DE Associated qualifiers "-sbegin", "-send" and "-sreverse" DE are applied as appropriate, with prompting for values, DE after the sequence has been read. They are applied to the sequence, DE and the resulting sequence is what is set in the ACD item. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetSeqset(AcdPAcd thys) { AjPSeqset val = NULL; AjPSeqin seqin; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool okbeg = ajFalse; AjBool okend = ajFalse; AjBool okrev = ajFalse; AjBool aligned = ajFalse; ajint itry; AjPStr infname = NULL; ajint sqbegin = 0; ajint sqend = 0; AjBool sreverse = ajFalse; AjBool sprompt = ajFalse; AjBool snuc = ajFalse; AjBool sprot = ajFalse; AjBool nullok = ajFalse; AjPStr typestr = NULL; val = ajSeqsetNew(); /* set the default value */ seqin = ajSeqinNew(); /* set the default value */ seqin->Input->Multi = ajTrue; acdQualToBool(thys, "snucleotide", ajFalse, &snuc, &acdReplyDef); acdQualToBool(thys, "sprotein", ajFalse, &sprot, &acdReplyDef); acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToBool(thys, "aligned", ajFalse, &aligned); acdAttrToStr(thys, "type", "", &typestr); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptSeq(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajSeqsetDel(&val); break; } ajSeqinUsa(&seqin, acdReply); if(ajStrGetLen(typestr)) { ajStrAssignS(&seqin->Inputtype, typestr); acdInTypeSeqSave(seqin->Inputtype); } else acdInTypeSeqSave(NULL); acdAttrToBool(thys, "features", ajFalse, &seqin->Features); acdGetValueAssoc(thys, "sformat", &seqin->Input->Formatstr); acdGetValueAssoc(thys, "sdbname", &seqin->Input->Db); /* acdGetValueAssoc(thys, "sopenfile", &seqin->Filename);*/ /* obsolete */ acdGetValueAssoc(thys, "sid", &seqin->Entryname); acdGetValueAssoc(thys, "iquery", &seqin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &seqin->Input->Fpos, &acdTmpStr); acdGetValueAssoc(thys, "ufo", &seqin->Ufo); acdGetValueAssoc(thys, "fformat", &seqin->Ftquery->Formatstr); acdGetValueAssoc(thys, "fopenfile", &seqin->Ftquery->Filename); acdQualToBool(thys, "scircular", ajFalse, &seqin->Circular, &acdTmpStr); acdQualToBool(thys, "supper", ajFalse, &seqin->Upper, &acdTmpStr); acdQualToBool(thys, "slower", ajFalse, &seqin->Lower, &acdTmpStr); okbeg = acdQualToSeqbegin(thys, "sbegin", 0, &seqin->Begin, &acdTmpStr); okend = acdQualToSeqend(thys, "send", 0, &seqin->End, &acdTmpStr); okrev = acdQualToBool(thys, "sreverse", ajFalse, &sreverse, &acdTmpStr); if(snuc) ajSeqinSetNuc(seqin); if(sprot) ajSeqinSetProt(seqin); if(ajStrGetLen(seqin->Ufo)) seqin->Features = ajTrue; ok = ajSeqsetRead(val, seqin); if(!ok) acdBadVal(thys, required, "Unable to read sequence '%S'", acdReply); } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, ajSeqsetGetNameS(val), ajTrue); /* save sequence name */ acdQualToBool(thys, "sask", ajFalse, &sprompt, &acdReplyDef); if(val) { /* now process the begin, end and reverse options */ if(seqin->Begin) { okbeg = ajTrue; val->Begin = seqin->Begin; } for(itry=acdPromptTry; itry && !okbeg; itry--) { ajStrAssignC(&acdReplyPrompt, "start"); if(sprompt) acdUserGetPrompt(thys, "sbegin", " Begin at position", &acdReplyPrompt); if(ajStrMatchCaseC(acdReplyPrompt, "start")) ajStrAssignC(&acdReplyPrompt, "0"); okbeg = ajStrToInt(acdReplyPrompt, &sqbegin); if(!okbeg) acdBadVal(thys, sprompt, "Invalid integer value '%S'", acdReplyPrompt); } if(!okbeg) acdBadRetry(thys); if(sqbegin) { seqin->Begin = sqbegin; val->Begin = sqbegin; acdSetQualDefInt(thys, "sbegin", sqbegin); } if(seqin->End) { okend = ajTrue; val->End = seqin->End; } for(itry=acdPromptTry; itry && !okend; itry--) { ajStrAssignC(&acdReplyPrompt, "end"); if(sprompt) acdUserGetPrompt(thys, "send", " End at position", &acdReplyPrompt); if(ajStrMatchCaseC(acdReplyPrompt, "end")) ajStrAssignC(&acdReplyPrompt, "0"); okend = ajStrToInt(acdReplyPrompt, &sqend); if(!okend) acdBadVal(thys, sprompt, "Invalid integer value '%S'", acdReplyPrompt); } if(!okend) acdBadRetry(thys); if(sqend) { seqin->End = sqend; val->End = sqend; acdSetQualDefInt(thys, "send", sqend); } if(ajSeqsetGetSize(val) && ajSeqsetIsNuc(val)) { for(itry=acdPromptTry; itry && !okrev; itry--) { ajStrAssignC(&acdReplyPrompt, "N"); if(sprompt) acdUserGetPrompt(thys, "sreverse", " Reverse strand", &acdReplyPrompt); okrev = ajStrToBool(acdReplyPrompt, &sreverse); if(!okrev) acdBadVal(thys, sprompt, "Invalid Y/N value '%S'", acdReplyPrompt); } if(!okrev) acdBadRetry(thys); if(sreverse) { seqin->Rev = sreverse; val->Rev = sreverse; acdSetQualDefBool(thys, "sreverse", sreverse); } } acdLog("sbegin: %d, send: %d, sreverse: %B\n", sqbegin, sqend, sreverse); if(val && aligned) ajSeqsetFill(val); if(val && val->Rev) ajSeqsetReverse(val); /* sequences have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcSeqset); thys->SetAttr = &acdCalcSeqset[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], ajSeqsetGetBegin(val)); ajStrFromInt(&thys->SetStr[ACD_SEQ_END], ajSeqsetGetEnd(val)); ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], ajSeqsetGetLen(val)); ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajSeqsetIsProt(val)); ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajSeqsetIsNuc(val)); if(ajStrGetLen(val->Name)) ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME], val->Name); else ajStrAssignS(&thys->SetStr[ACD_SEQ_NAME], ajSeqsetGetseqNameS(val,0)); ajStrAssignS(&thys->SetStr[ACD_SEQ_USA], ajSeqsetGetUsa(val)); ajStrFromFloat(&thys->SetStr[ACD_SEQ_WEIGHT], ajSeqsetGetTotweight(val), 3); ajStrFromInt(&thys->SetStr[ACD_SEQ_COUNT], ajSeqsetGetSize(val)); acdInFileSave(acdReply, ajSeqsetGetNameS(val), ajTrue); } else { /* sequences have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcSeqset); thys->SetAttr = &acdCalcSeq[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[ACD_SEQ_BEGIN], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_END], 0); ajStrFromInt(&thys->SetStr[ACD_SEQ_LENGTH], 0); ajStrFromBool(&thys->SetStr[ACD_SEQ_NUCLEIC], ajFalse); ajStrFromBool(&thys->SetStr[ACD_SEQ_PROTEIN], ajFalse); ajStrAssignC(&thys->SetStr[ACD_SEQ_NAME], ""); ajStrAssignC(&thys->SetStr[ACD_SEQ_USA], ""); ajStrFromFloat(&thys->SetStr[ACD_SEQ_WEIGHT], 0.0, 3); ajStrFromInt(&thys->SetStr[ACD_SEQ_COUNT], 0); } thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajSeqinDel(&seqin); ajStrDel(&typestr); return; } ID ajAcdGetSeqsetall TY public MO ajacd LB acd XX DE Returns an item of type Seqset array as defined in a named ACD item. DE The array is terminated by a NULL. DE DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPSeqset* RD Sequence setall object. RD The sequence was already loaded by RD acdSetSeqset so this just returns the pointer. RX // AjPSeqset* ajAcdGetSeqsetall(const char *token) { return acdGetValueRef(token, "seqsetall"); } ID ajAcdGetSeqsetallSingle TY public MO ajacd LB acd XX DE Returns an item of type Seqset as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPSeqset RD Sequence set object. The sequence was already loaded by RD acdSetSeqset so this just returns the pointer. RX // AjPSeqset ajAcdGetSeqsetallSingle(const char *token) { AjPSeqset *val; ajint i; val = acdGetValueSingle(token, "seqsetall"); for(i=0; val[i]; i++) continue; if(i > 1) ajWarn("Single list value %s, but can choose %d values", token, i); if(i < 1) ajWarn("Single list value %s, no value found: returning NULL value", token); return val[0]; } ID ajAcdGetString TY public MO ajacd LB acd XX DE Returns an item of type String as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPStr RD String object. The string was already set by RD acdSetString so this just returns the pointer. RX // AjPStr ajAcdGetString(const char *token) { return acdGetValueRef(token, "string"); } ID acdSetString TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD string item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is an empty string. DE DE Attributes for minimum and maximum length are applied with error DE messages if exceeded. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetString(AcdPAcd thys) { AjPStr val; AjBool required = ajFalse; AjBool ok = ajFalse; AjPStr pattern = NULL; AjBool upper; AjBool lower; AjBool word; ajint itry; AjPRegexp patexp = NULL; ajint minlen; ajint maxlen; ajint len; val = ajStrNew(); /* set the default value */ acdAttrToInt(thys, "minlength", 0, &minlen); acdAttrToInt(thys, "maxlength", INT_MAX, &maxlen); acdAttrToStr(thys, "pattern", "", &pattern); acdAttrToBool(thys, "upper", ajFalse, &upper); acdAttrToBool(thys, "lower", ajFalse, &lower); acdAttrToBool(thys, "word", ajFalse, &word); if(ajStrGetLen(pattern)) patexp = ajRegComp(pattern); required = acdIsRequired(thys); acdReplyInitC(thys, "", &acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); len = ajStrGetLen(acdReply); if(len < minlen) { acdBadVal(thys, required, "Too short (%S) - minimum length is %d characters", thys->Name, minlen); ok = ajFalse; } if(len > maxlen) { acdBadVal(thys, required, "Too long (%S) - maximum length is %d characters", thys->Name, maxlen); ok = ajFalse; } if(patexp && !ajRegExec(patexp, acdReply)) { acdBadVal(thys, required, "String does not match pattern '%S'", pattern); ok = ajFalse; } if(word && !(ajStrIsWord(acdReply))) { acdBadVal(thys, required, "String contains disallowed whitespace characters"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); if(patexp) ajRegFree(&patexp); if(upper) ajStrFmtUpper(&val); if(lower) ajStrFmtLower(&val); /* strings have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcString); thys->SetAttr = &acdCalcString[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); ajStrFromInt(&thys->SetStr[0], ajStrGetLen(acdReply)); ajStrAssignS(&val, acdReply); thys->Value = val; ajStrAssignS(&thys->ValStr, val); ajStrDel(&pattern); return; } ID ajAcdGetTaxon TY public MO ajacd LB acd XX DE Returns an item of type Taxon as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPTax RD Taxon object RX // AjPTax ajAcdGetTaxon(const char *token) { AjPTaxall val = acdGetValue(token, "taxon"); if(val->Multi) ajWarn("ajAcdGetTaxon request single taxon but maxreads > 1"); val->Returned = ajTrue; return val->Tax; } ID ajAcdGetTaxonall TY public MO ajacd LB acd XX DE Returns an input stream of an item of type Taxon as defined in a DE named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPTaxall RD Taxon input stream RX // AjPTaxall ajAcdGetTaxonall(const char *token) { AjPTaxall val = acdGetValueRef(token, "taxon"); if(!val->Multi) ajWarn("ajAcdGetTaxonall request taxon input stream but maxreads is 1"); return val; } ID acdSetTaxon TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD taxon input DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetTaxon(AcdPAcd thys) { AjPTaxall val; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok = ajFalse; ajint itry; ajint maxreads; AjPStr infname = NULL; AjPStr tmp = NULL; val = ajTaxallNew(); /* set the default value */ acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajTaxallDel(&val); break; } ajTaxinQryS(val->Taxin, acdReply); acdGetValueAssoc(thys, "iformat", &val->Taxin->Input->Formatstr); acdGetValueAssoc(thys, "iquery", &val->Taxin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &val->Taxin->Input->Fpos, &acdTmpStr); ok = ajTaxinRead(val->Taxin, val->Tax); } if(!ok) acdBadRetry(thys); if(maxreads > 1) val->Multi = ajTrue; acdAttrToBool(thys, "entry", ajFalse, &val->Taxin->Input->Text); acdInFileSave(acdReply, ajTaxallGettaxId(val), ajTrue); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&tmp); return; } ID ajAcdGetText TY public MO ajacd LB acd XX DE Returns an item of type Text as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPText RD Text object RX // AjPText ajAcdGetText(const char *token) { AjPTextall val = acdGetValue(token, "text"); if(val->Multi) ajWarn("ajAcdGetText request single text entry but maxreads > 1"); val->Returned = ajTrue; return val->Text; } ID ajAcdGetTextall TY public MO ajacd LB acd XX DE Returns an input stream of an item of type Text as defined in a DE named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPTextall RD Text input stream RX // AjPTextall ajAcdGetTextall(const char *token) { AjPTextall val = acdGetValueRef(token, "text"); if(!val->Multi) ajWarn("ajAcdGetTextall request text input stream but maxreads is 1"); return val; } ID acdSetText TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD text input DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetText(AcdPAcd thys) { AjPTextall val; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok = ajFalse; ajint itry; ajint maxreads; AjPStr infname = NULL; AjPStr tmp = NULL; val = ajTextallNew(); /* set the default value */ acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajTextallDel(&val); break; } ajTextinQryS(val->Textin, acdReply); acdGetValueAssoc(thys, "iformat", &val->Textin->Formatstr); acdGetValueAssoc(thys, "iquery", &val->Textin->QryFields); acdQualToLong(thys, "ioffset", 0L, &val->Textin->Fpos, &acdTmpStr); ok = ajTextinRead(val->Textin, val->Text); } if(!ok) acdBadRetry(thys); if(maxreads > 1) val->Multi = ajTrue; acdAttrToBool(thys, "entry", ajFalse, &val->Textin->Text); /* acdInFileSave(acdReply, ajTextallGettextId(val), ajTrue); */ thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&tmp); return; } ID ajAcdGetToggle TY public MO ajacd LB acd XX DE Returns an item of type Toggle as defined in a named ACD item. Called by the DE application after all ACD values have been set, and simply returns DE what the ACD item already has. DE DE Toggle is an AjBool that is used to switch (toggle) other ACD types. XX PN [1] PA r token const char* PD Text token name PX RT AjBool RD Boolean value from ACD item RX // AjBool ajAcdGetToggle(const char *token) { AjBool* val; val = acdGetValue(token, "toggle"); return *val; } ID acdSetToggle TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD toggle item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other available) is "N" for ajFalse. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetToggle(AcdPAcd thys) { AjBool* val; AjBool required = ajFalse; AjBool ok = ajFalse; ajint itry; AJNEW0(val); /* create storage for the result */ *val = ajFalse; /* set the default value */ required = acdIsRequired(thys); acdReplyInitC(thys, "N", &acdReplyDef); acdLog("acdSetToggle -%S def: %S\n", thys->Name, acdReplyDef); for(itry=acdPromptTry; itry && !ok; itry--) { ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); ok = ajStrToBool(acdReply, val); if(!ok) acdBadVal(thys, required, "Invalid Y/N value '%S'", acdReply); } if(!ok) acdBadRetry(thys); thys->Value = val; ajFmtPrintS(&thys->ValStr, "%B", *val); acdLog("acdSetToggle -%S val: %B\n", thys->Name, *val); if(ajStrMatchC(thys->Name, "help")) acdHelp(); return; } ID ajAcdGetTree TY public MO ajacd LB acd XX DE Returns an item of type Tree as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPhyloTree* RD Tree object. The data was already set by RD acdSetTree so this just returns the pointer. RX // AjPPhyloTree* ajAcdGetTree(const char *token) { return acdGetValueRef(token, "tree"); } ID ajAcdGetTreeSingle TY public MO ajacd LB acd XX DE Returns an item of type Tree as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPPhyloTree RD Tree object. The data was already set by RD acdSetTree so this just returns the pointer. RX // AjPPhyloTree ajAcdGetTreeSingle(const char *token) { AjPPhyloTree *val; ajint i; val = acdGetValueSingle(token, "tree"); for(i=0; val[i]; i++) continue; if(i > 1) ajWarn("Single list value %s, but can choose %d values", token, i); if(i < 1) ajWarn("Single list value %s, no value found: returning NULL value", token); return val[0]; } ID acdSetTree TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD tree file item. DE DE Understands all attributes and associated qualifiers for this item type. DE DE The default value (if no other is available) is an empty string. DE DE Attributes for number of trees (size) are applied with error DE messages if exceeded. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetTree(AcdPAcd thys) { AjPPhyloTree *val; AjBool required = ajFalse; AjBool ok = ajFalse; AjPStr infname = NULL; ajint itry; ajint i; ajint size; AjBool nullok = ajFalse; val = NULL; acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "size", 0, &size); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); acdPromptTree(thys); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(ajStrGetLen(acdReply)) { val = ajPhyloTreeRead(acdReply, size); if(!val) { acdBadVal(thys, required, "Unable to read tree data from '%S'", acdReply); ok = ajFalse; } } else if(!nullok) { acdBadVal(thys, required, "Input file is required"); ok = ajFalse; } } if(!ok) acdBadRetry(thys); acdInFileSave(acdReply, NULL, ajTrue); /* trees have special set attributes */ thys->SAttr = acdAttrListCount(acdCalcTree); thys->SetAttr = &acdCalcTree[0]; thys->SetStr = AJCALLOC0(thys->SAttr, sizeof(AjPStr)); if(val) { for(i=0;val[i];i++) continue; ajStrFromInt(&thys->SetStr[0],i); /* number of trees */ ajStrFromInt(&thys->SetStr[1],val[0]->Size); ajStrFromBool(&thys->SetStr[2],val[0]->HasLengths); ajStrAssignS(&thys->ValStr, val[0]->Tree); } else { ajStrFromInt(&thys->SetStr[0],0); /* number of trees */ ajStrFromInt(&thys->SetStr[1],0); ajStrFromBool(&thys->SetStr[2],ajFalse); ajStrAssignClear(&thys->ValStr); } thys->Value = val; return; } ID ajAcdGetUrl TY public MO ajacd LB acd XX DE Returns an item of type URL as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPUrl RD URL object RX // AjPUrl ajAcdGetUrl(const char *token) { AjPUrlall val = acdGetValue(token, "url"); if(val->Multi) ajWarn("ajAcdGetUrl request single URL but maxreads > 1"); val->Returned = ajTrue; return val->Url; } ID ajAcdGetUrlall TY public MO ajacd LB acd XX DE Returns an input stream of an item of type Taxon as defined in a DE named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPUrlall RD URL input stream RX // AjPUrlall ajAcdGetUrlall(const char *token) { AjPUrlall val = acdGetValueRef(token, "url"); if(!val->Multi) ajWarn("ajAcdGetUrlall request url input stream but maxreads is 1"); return val; } ID acdSetUrl TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD URL input DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetUrl(AcdPAcd thys) { AjPUrlall val; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok = ajFalse; ajint itry; ajint maxreads; AjPStr infname = NULL; val = ajUrlallNew(); /* set the default value */ acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdAttrToInt(thys, "maxreads", INT_MAX, &maxreads); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajUrlallDel(&val); break; } ajUrlinQryS(val->Urlin, acdReply); /* these are reset by ajUrlinQryS - can safely set now */ acdQualToBool(thys, "swiss", ajFalse, &val->Urlin->IsSwiss, &acdTmpStr); acdQualToBool(thys, "embl", ajFalse, &val->Urlin->IsEmbl, &acdTmpStr); acdGetValueAssoc(thys, "accession", &val->Urlin->Accession); acdGetValueAssoc(thys, "identifier", &val->Urlin->IdTypes); acdGetValueAssoc(thys, "iformat", &val->Urlin->Input->Formatstr); ok = ajUrlinRead(val->Urlin, val->Url); } if(!ok) acdBadRetry(thys); if(maxreads > 1) val->Multi = ajTrue; acdAttrToBool(thys, "entry", ajFalse, &val->Urlin->Input->Text); acdInFileSave(acdReply, ajUrlallGeturlId(val), ajTrue); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); return; } ID ajAcdGetValue TY public MO ajacd LB acd XX DE Returns the string value of any ACD item XX PN [1] PA r token const char* PD Text token name PX RT const AjPStr RD String object. The string was already set by RD acdSetString so this just returns the pointer. RX // const AjPStr ajAcdGetValue(const char *token) { return acdGetValStr(token); } ID ajAcdGetValueDefault TY public MO ajacd LB acd XX DE Returns the default value of any ACD item XX PN [1] PA r token const char* PD Text token name PX RT const AjPStr RD Default value. RX // const AjPStr ajAcdGetValueDefault(const char *token) { return acdGetValDefault(token); } ID ajAcdGetVariation TY public MO ajacd LB acd XX DE Returns an item of type variation loader as defined in a named ACD item. DE Called by the application after all ACD values have been set, DE and simply returns what the ACD item already has. XX PN [1] PA r token const char* PD Text token name PX RT AjPVarload RD Variation loader object RX // AjPVarload ajAcdGetVariation(const char *token) { AjPVarload val = acdGetValueRef(token, "variation"); /*if(val->Multi) ajWarn("ajAcdGetVariation request single variation but maxreads > 1"); */ val->Returned = ajTrue; return val; } ID acdSetVariation TY static MO ajacd LB acd XX DE Using the definition in the ACD file, and any values for the DE item or its associated qualifiers provided on the command line, DE prompts the user if necessary (and possible) and DE sets the actual value for an ACD variation input DE DE Understands all attributes and associated qualifiers for this item type. XX PN [1] PA u thys AcdPAcd PD ACD item. PX RT void RD RX // static void acdSetVariation(AcdPAcd thys) { AjPVarload val; AjBool required = ajFalse; AjBool ok = ajFalse; AjBool nullok = ajFalse; ajint itry; AjPStr infname = NULL; AjPStr tmp = NULL; val = ajVarloadNew(); /* set the default value */ acdAttrToBool(thys, "nullok", ajFalse, &nullok); acdInFilename(&infname); required = acdIsRequired(thys); acdReplyInitS(thys, infname, &acdReplyDef); ajStrDel(&infname); for(itry=acdPromptTry; itry && !ok; itry--) { ok = ajTrue; /* accept the default if nothing changes */ ajStrAssignS(&acdReply, acdReplyDef); if(required) acdUserGet(thys, &acdReply); if(!ajStrGetLen(acdReply) && nullok) { ajVarloadDel(&val); break; } ajVarinQryS(val->Varin, acdReply); acdGetValueAssoc(thys, "iformat", &val->Varin->Input->Formatstr); acdGetValueAssoc(thys, "iquery", &val->Varin->Input->QryFields); acdQualToLong(thys, "ioffset", 0L, &val->Varin->Input->Fpos, &acdTmpStr); ok = ajVarinLoad(val->Varin, val->Var); } if(!ok) acdBadRetry(thys); acdAttrToBool(thys, "entry", ajFalse, &val->Varin->Input->Text); acdInFileSave(acdReply, ajVarloadGetvarId(val), ajTrue); thys->Value = val; ajStrAssignS(&thys->ValStr, acdReply); ajStrDel(&tmp); return; } ID ajAcdGetpathC TY public MO ajacd LB acd XX DE Returns the full path of an application defined in an external: attribute DE within the application definition. If the application was defined by an DE EMBOSS_appname environment variable this will use the substitution made DE when the external attribute was validated. XX PN [1] PA r token const char* PD External application name PX RT const AjPStr RD Executable application name RX // const AjPStr ajAcdGetpathC(const char* token) { const AjPStr value; /* not static - copy of a table text */ AjPStr tmpname = NULL; ajStrAssignC(&tmpname, token); value = ajAcdGetpathS(tmpname); ajStrDel(&tmpname); return value; } ID ajAcdGetpathS TY public MO ajacd LB acd XX DE Returns the full path of an application defined in an external: attribute DE within the application definition. If the application was defined by an DE EMBOSS_appname environment variable this will use the substitution made DE when the external attribute was validated. XX PN [1] PA r strtoken const AjPStr PD External application name PX RT const AjPStr RD Executable application name RX // const AjPStr ajAcdGetpathS(const AjPStr strtoken) { const AjPStr value; value = ajTableFetchS(acdExternalTable, strtoken); if(!value) ajWarn("Cannot find '%S', no ACD external definition found", strtoken); return value; } ID ajAcdIsUserdefinedC TY public MO ajacd LB acd XX DE Tests whether an ACD item has a value set by the user. XX PN [1] PA r token const char* PD Text token name PX RT AjBool RD True if token is not found as an ACD object name RX // AjBool ajAcdIsUserdefinedC(const char *token) { AcdPAcd acd; ajint pnum = 0; /* need to get from end of token */ AjPStr tmpstr = NULL; tmpstr = ajStrNewC(token); acdTokenToLowerS(&tmpstr, &pnum); acd = acdFindAcd(tmpstr, tmpstr); if(!acd) { ajErr("Qualifier '-%s' not found", token); return ajFalse; } ajStrDel(&tmpstr); return acd->UserDefined; } ID ajAcdIsUserdefinedS TY public MO ajacd LB acd XX DE Tests whether an ACD item has a value set by the user. XX PN [1] PA r strtoken const AjPStr PD Text token name PX RT AjBool RD True if token is not found as an ACD object name RX // AjBool ajAcdIsUserdefinedS(const AjPStr strtoken) { AcdPAcd acd; ajint pnum = 0; /* need to get from end of token */ AjPStr tmpstr = NULL; tmpstr = ajStrNewS(strtoken); acdTokenToLowerS(&tmpstr, &pnum); acd = acdFindAcd(tmpstr, tmpstr); if(!acd) { ajErr("Qualifier '-%S' not found", strtoken); return ajFalse; } ajStrDel(&tmpstr); return acd->UserDefined; } ID acdAttrCount TY static MO ajacd LB acd XX DE Simply counts all attributes for a numbered ACD type, XX PN [1] PA r itype ajint PD Numbered type as returned by acdFindType PX RT ajint RD number of attributes defined. RX // static ajint acdAttrCount(ajint itype) { AcdPAttr attr = acdType[itype].Attr; return acdAttrListCount(attr); } ID acdAttrKeyCount TY static MO ajacd LB acd XX DE Simply counts all attributes for a numbered ACD keyword, XX PN [1] PA r ikey ajint PD Numbered type as returned by acdFindKey PX RT ajint RD number of attributes defined. RX // static ajint acdAttrKeyCount(ajint ikey) { AcdPAttr attr = acdKeywords[ikey].Attr; return acdAttrListCount(attr); } ID acdAttrListCount TY static MO ajacd LB acd XX DE Simply counts all attributes for an attribute list. XX PN [1] PA r attr const AcdPAttr PD Attribute list PX RT ajint RD number of attributes defined. RX // static ajint acdAttrListCount(const AcdPAttr attr) { static ajint i; i = 0; while(attr[i].Name) i++; return i; } ID acdGetValue TY static MO ajacd LB acd XX DE Picks up a token by name and tests the type. DE The value is returned as type "void*", to be cast by the calling DE routine which is supposed to know what to expect. For example, only DE ajAcdGetInt should call with a type of "integer". XX PN [1] PA r token const char* PD Token name, optionally including a PD numeric suffix. PX PN [2] PA r type const char* PD Type. PX RT void* RD Value. RX // static void* acdGetValue(const char *token, const char* type) { void *ret; ajint pnum = 0; /* need to get from end of token */ AjPStr tmpstr = NULL; tmpstr = ajStrNewC(token); acdLog("acdGetValue '%s' (%s)\n", token, type); acdTokenToLowerS(&tmpstr, &pnum); ret = acdGetValueNumS(tmpstr, type, pnum, REF_NONE); acdLog("acdGetValue '%s' result %x\n", token, ret); ajStrDel(&tmpstr); return ret; } ID acdGetValueRef TY static MO ajacd LB acd XX DE Picks up a token by name and tests the type. DE The value is returned as type "void*", to be cast by the calling DE routine which is supposed to know what to expect. For example, only DE ajAcdGetInt should call with a type of "integer". DE DE The value reference is passed up to the original caller who now DE 'owns' the pointer. Some values will remain owned by ACD. Examples DE include integers and booleans, but also lists of options where only DE the first option is returned. XX PN [1] PA r token const char* PD Token name, optionally including a PD numeric suffix. PX PN [2] PA r type const char* PD Type. PX RT void* RD Value. RX // static void* acdGetValueRef(const char *token, const char* type) { void *ret; ajint pnum = 0; /* need to get from end of token */ AjPStr tmpstr = NULL; tmpstr = ajStrNewC(token); acdLog("acdGetValue '%s' (%s)\n", token, type); acdTokenToLowerS(&tmpstr, &pnum); ret = acdGetValueNumS(tmpstr, type, pnum, REF_ALL); acdLog("acdGetValueRef '%s' result %x\n", token, ret); ajStrDel(&tmpstr); return ret; } ID acdGetValueSingle TY static MO ajacd LB acd XX DE Picks up a token by name and tests the type. DE The value is returned as type "void*", to be cast by the calling DE routine which is supposed to know what to expect. For example, only DE ajAcdGetInt should call with a type of "integer". DE DE The value reference is passed up to the original caller who now DE 'owns' the pointer to the first data value, but the value array will DE need to be freed on exit. XX PN [1] PA r token const char* PD Token name, optionally including a PD numeric suffix. PX PN [2] PA r type const char* PD Type. PX RT void* RD Value. RX // static void* acdGetValueSingle(const char *token, const char* type) { void *ret; ajint pnum = 0; /* need to get from end of token */ AjPStr tmpstr = NULL; tmpstr = ajStrNewC(token); acdLog("acdGetValue '%s' (%s)\n", token, type); acdTokenToLowerS(&tmpstr, &pnum); ret = acdGetValueNumS(tmpstr, type, pnum, REF_SINGLE); acdLog("acdGetValueSingle '%s' result %x\n", token, ret); ajStrDel(&tmpstr); return ret; } ID acdGetValStr TY static MO ajacd LB acd XX DE Picks up a token by name and tests the type. DE The string value is returned for any data type. XX PN [1] PA r token const char* PD Token name, optionally including PD a numeric suffix. PX RT const AjPStr RD String. RX // static const AjPStr acdGetValStr(const char *token) { AcdPAcd acd; ajint pnum = 0; /* need to get from end of token */ AjPStr tmpstr = NULL; tmpstr = ajStrNewC(token); acdLog("acdGetValStr '%s' (%s)\n", token); acdTokenToLowerS(&tmpstr, &pnum); acd = acdFindAcd(tmpstr, tmpstr); ajStrDel(&tmpstr); if(!acd) return NULL; return acd->ValStr; } ID acdGetValDefault TY static MO ajacd LB acd XX DE Picks up a token by name and tests the type. DE The default string value is returned for any data type. XX PN [1] PA r token const char* PD Token name, optionally including PD a numeric suffix. PX RT const AjPStr RD String. RX // static const AjPStr acdGetValDefault(const char *token) { AcdPAcd acd; ajint pnum = 0; /* need to get from end of token */ AjPStr tmpstr = NULL; tmpstr = ajStrNewC(token); acdLog("acdGetValStr '%s' (%s)\n", token); acdTokenToLowerS(&tmpstr, &pnum); acd = acdFindAcd(tmpstr, tmpstr); ajStrDel(&tmpstr); if(!acd) return NULL; return acd->DefStr[DEF_DEFAULT]; } ID acdGetValueAssoc TY static MO ajacd LB acd XX DE Picks up the value for an associated qualifier as a string. XX PN [1] PA r thys const AcdPAcd PD ACD item for the master parameter/qualifier PX PN [2] PA r token const char* PD Token name, optionally including a PD numeric suffix. PX PN [3] PA w result AjPStr* PD String for the resulting value. PX RT AjBool RD ajTrue if found. RX // static AjBool acdGetValueAssoc(const AcdPAcd thys, const char *token, AjPStr *result) { ajint pnum = 0; /* need to get from end of token */ AcdPAcd pa; AjPStr tmpstr = NULL; tmpstr = ajStrNewC(token); acdLog("acdGetValueAssocDefault '%s' (%S)\n", token, thys->Name); acdTokenToLowerS(&tmpstr, &pnum); ajStrDel(&tmpstr); if(pnum) acdErrorAcd(thys, "associated token '%s' is numbered - not allowed\n", token); for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next) if(ajStrMatchC(pa->Token, token)) { ajStrAssignS(result, pa->ValStr); return pa->Defined; } acdErrorAcd(thys, "Token '%s' not found\n", token); return ajFalse; } ID acdGetValueAssocDefault TY static MO ajacd LB acd XX DE Picks up the default value for an associated qualifier as a string. XX PN [1] PA r thys const AcdPAcd PD ACD item for the master parameter/qualifier PX PN [2] PA r token const char* PD Token name, optionally including a PD numeric suffix. PX PN [3] PA w result AjPStr* PD String for the resulting value. PX RT AjBool RD ajTrue if found. RX // static AjBool acdGetValueAssocDefault(const AcdPAcd thys, const char *token, AjPStr *result) { ajint pnum = 0; /* need to get from end of token */ AcdPAcd pa; AjPStr tmpstr = NULL; tmpstr = ajStrNewC(token); acdLog("acdGetValueAssocDefault '%s' (%S)\n", token, thys->Name); acdTokenToLowerS(&tmpstr, &pnum); ajStrDel(&tmpstr); if(pnum) acdErrorAcd(thys, "associated token '%s' is numbered - not allowed\n", token); for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next) if(ajStrMatchC(pa->Token, token)) { ajStrAssignS(result, pa->DefStr[DEF_DEFAULT]); return pa->Defined; } acdErrorAcd(thys, "Token '%s' not found\n", token); return ajFalse; } ID acdGetValueNumC TY static MO ajacd LB acd XX DE Picks up the value by name, type and number. XX PN [1] PA r token const char* PD Token name PX PN [2] PA r type const char* PD ACD type PX PN [3] PA r pnum ajint PD parameter number, or 0 for a general qualifier. PX PN [4] PA r reftype ajint PD Reference passing type. PD REF_NONE means ACD still owns the value, PD REF_ALL means the caller owns the value, PD REF_SINGLE means the caller owns one value, PD but ACD owns the array PX RT void* RD Value of unknown type. RX // static void* acdGetValueNumC(const char *token, const char* type, ajint pnum, ajint reftype) { AcdPAcd pa; AcdPAcd ret = NULL; ajint itype = 0; ajint ifound = 0; AjPStr ambigList = NULL; ambigList = ajStrNew(); if(type) itype = acdFindTypeC(type); for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; if(ajStrMatchC(pa->Token, token)) { acdLog("Found pa->Token '%S' pa->Type %d itype: %d\n", pa->Token, pa->Type, itype); if(pa->Level != ACD_QUAL && pa->Level != ACD_PARAM ) ajDie("Unknown qualifier '-%S'", pa->Token); if((itype>=0) && (pa->Type != itype)) /* program source error */ ajDie("Value for '-%S' is not of type %s (found type %s)", pa->Token, type, acdType[pa->Type].Name); if(pa->PNum == pnum) { acdLog("found %S [%d] '%S'\n", pa->Name, pa->PNum, pa->ValStr); if(pa->Used & USED_GET) ajWarn("Value for '-%S' used more than once", pa->Token); pa->Used |= USED_GET; ajStrDel(&ambigList); pa->RefPassed = reftype; return pa->Value; } else if(!pnum) /* matches any if no number, so count them */ { ifound++; ret = pa; acdAmbigApp(&ambigList, pa->Token); } } } if(ifound > 1) { ajWarn("Ambiguous qualifier '-%s' (%S)", token, ambigList); ajStrDel(&ambigList); } if(ifound == 1) { acdLog("found %S [%d] '%S'\n", ret->Name, ret->PNum, ret->ValStr); ret->Used |= USED_GET; if (acdDoValid) acdWarn("Abbreviated qualifier '%S' (%S)", token, ambigList); ajStrDel(&ambigList); ret->RefPassed = reftype; return ret->Value; } ajStrDel(&ambigList); /* program source error */ ajDie("Qualifier '-%s' not found", token); return NULL; } ID acdGetValueNumS TY static MO ajacd LB acd XX DE Picks up the value by name, type and number. XX PN [1] PA r token const AjPStr PD Token name PX PN [2] PA r type const char* PD ACD type PX PN [3] PA r pnum ajint PD parameter number, or 0 for a general qualifier. PX PN [4] PA r reftype ajint PD Reference passing type. PD REF_NONE means ACD still owns the value, PD REF_ALL means the caller owns the value, PD REF_SINGLE means the caller owns one value, PD but ACD owns the array PX RT void* RD Value of unknown type. RX // static void* acdGetValueNumS(const AjPStr token, const char* type, ajint pnum, ajint reftype) { return acdGetValueNumC(ajStrGetPtr(token), type, pnum, reftype); } ID acdHelp TY static MO ajacd LB acd XX DE Reports on program options if acdDoHelp is set, either by DE -help on the command line or by the prefix_HELP variable.. XX RT void RD RX // static void acdHelp(void) { AcdPAcd pa; static AjPStr helpReq = NULL; static AjPStr helpOpt = NULL; static AjPStr helpAdv = NULL; static AjPStr helpAss = NULL; static AjPStr helpGen = NULL; static AjPStr helpStr = NULL; enum { HELP_UNK, HELP_APP, HELP_REQ, HELP_OPT, HELP_ADV, HELP_ASS, HELP_GEN } helpType; AjPStr* def; AjBool tmpBool; char hlpFlag; ajint iattr = 0; ajlong igrp = 0; AjPStr groupname = NULL; AjPStr tmpstr = NULL; AjPStr applversion = NULL; AjBool flagReq = ajFalse; AjBool flagOpt = ajFalse; AjPList reqlist = NULL; AjPList optlist = NULL; AjPList advlist = NULL; AjPList genlist = NULL; AjPList asslist = NULL; AjPList inlist = NULL; AjPList outlist = NULL; acdLog("acdHelp %B\n", acdDoHelp); if(!acdDoHelp) return; if(acdDoTable) { reqlist = ajListNew(); optlist = ajListNew(); advlist = ajListNew(); genlist = ajListNew(); if(acdVerbose) asslist = ajListNew(); ajUserDumpC(""); /* was #f5f5ff */ } if(acdDoXsd || acdDoGalaxy) { inlist = ajListNew(); outlist = ajListNew(); } acdLog("++ acdHelp\n"); for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; hlpFlag = ' '; acdLog("++ Name %S Level %d Assoc %B AssocQuals %x\n", pa->Name, pa->Level, pa->Assoc, pa->AssocQuals); helpType = HELP_ADV; if(pa->Level == ACD_APPL) helpType = HELP_APP; else if(!acdIsQtype(pa)) continue; def = pa->DefStr; if(def && ajStrGetLen(def[DEF_ADDITIONAL])) { if(acdHelpVarResolve(&helpStr, def[DEF_ADDITIONAL])) { if(!ajStrToBool(helpStr, &tmpBool)) acdErrorAcd(pa, "Bad additional flag %S\n", def[DEF_ADDITIONAL]); } else { tmpBool = ajTrue; hlpFlag = '*'; flagOpt = ajTrue; } if(tmpBool) helpType = HELP_OPT; } if(def && ajStrGetLen(def[DEF_STANDARD])) { if(acdHelpVarResolve(&helpStr, def[DEF_STANDARD])) { if(!ajStrToBool( helpStr, &tmpBool)) acdErrorAcd(pa, "Bad standard flag %S\n", def[DEF_STANDARD]); } else { tmpBool = ajTrue; hlpFlag = '*'; flagReq = ajTrue; } if(tmpBool) helpType = HELP_REQ; } if(pa->Assoc) helpType = HELP_ASS; acdLog("++ helpType %d\n", helpType); switch(helpType) { case HELP_APP: /* application, do nothing */ iattr = acdFindAttrC(acdAttrAppl, "groups"); ajStrAssignS(&groupname, pa->AttrStr[iattr]); iattr = acdFindAttrC(acdAttrAppl, "documentation"); ajStrAssignS(&acdAppldoc, pa->AttrStr[iattr]); igrp = ajStrFindAnyC(groupname, ",|"); if(igrp != -1) ajStrTruncateLen(&groupname, (size_t) igrp); ajStrFmtLower(&groupname); ajStrExchangeKK(&groupname, ':', '_'); ajStrExchangeKK(&groupname, ' ', '_'); if(acdDoGalaxy) { ajUser("\n" " %S\n" " " "" "emboss\n" " embossversion -auto" "", acdProgram, acdProgram, ajNamValueVersion(), acdAppldoc, ajNamValueVersion()); } if(acdDoXsd) { ajUserDumpC(""); ajUser(""); } break; case HELP_REQ: acdHelpAppend(pa, &helpReq, hlpFlag); acdHelpTable(pa, reqlist); break; case HELP_OPT: acdHelpAppend(pa, &helpOpt, hlpFlag); acdHelpTable(pa, optlist); break; case HELP_ADV: acdHelpAppend(pa, &helpAdv, hlpFlag); acdHelpTable(pa, advlist); break; case HELP_ASS: /* associated - process after the master */ break; case HELP_GEN: /* associated - process after the app */ break; default: acdErrorAcd(pa, "unknown qualifier type %d in acdHelp", helpType); } if(acdType[pa->Type].Section == acdSecOutput) { if(acdDoXsd) acdHelpXsd(pa, outlist); else if(acdDoGalaxy) acdHelpGalaxy(pa, outlist); } else if(pa->Level != ACD_APPL) { if(acdDoXsd) acdHelpXsd(pa, inlist); else if(acdDoGalaxy) acdHelpGalaxy(pa, inlist); } if(pa->AssocQuals) { if(helpType == HELP_APP) { if(acdVerbose) acdHelpAssoc(pa, &helpGen, NULL); else acdHelpAssoc(pa, &helpGen, "help"); acdHelpAssocTable(pa, genlist); } else { if(acdVerbose) { acdHelpAssoc(pa, &helpAss, NULL); acdHelpAssocTable(pa, asslist); } } } } if(!acdDoXsd && !acdDoGalaxy) { /* ** report 1-line documentation ** report version (s) */ acdAttrResolve(acdApplAcd, "documentation", &tmpstr); if(!acdAuto && !acdDoTable && ajStrGetLen(tmpstr)) { ajStrFmtWrap(&tmpstr, 75); ajUserDumpS(tmpstr); } ajFmtPrintS(&tmpstr, "EMBOSS:%s", VERSION); if(ajStrGetLen(tmpstr) < 14) ajStrAppendC(&tmpstr, ".0"); if(ajStrGetLen(acdPackVersion)) ajFmtPrintAppS(&tmpstr, " %S:%S", acdPackName, acdPackVersion); acdAttrResolve(acdApplAcd, "versionnumber", &applversion); if(ajStrGetLen(applversion)) { ajFmtPrintAppS(&tmpstr, " %S:%S", acdApplAcd->Name, applversion); ajStrDel(&applversion); } if(!acdDoTable) ajUser("Version: %S\n", tmpstr); ajStrDel(&tmpstr); ajStrDel(&applversion); if(flagReq) acdHelpShow(helpReq, "Standard (Mandatory) qualifiers " "(* if not always prompted)"); else acdHelpShow(helpReq, "Standard (Mandatory) qualifiers"); acdHelpTableShow(NULL, ""); acdHelpTableShow(reqlist, "Standard (Mandatory) qualifiers"); if(flagOpt) acdHelpShow(helpOpt, "Additional (Optional) qualifiers " "(* if not always prompted)"); else acdHelpShow(helpOpt, "Additional (Optional) qualifiers"); acdHelpTableShow(optlist, "Additional (Optional) qualifiers"); acdHelpShow(helpAdv, "Advanced (Unprompted) qualifiers"); acdHelpTableShow(advlist, "Advanced (Unprompted) qualifiers"); if(acdVerbose) acdHelpShow (helpAss, "Associated qualifiers"); acdHelpShow(helpGen, "General qualifiers"); if(acdVerbose && acdDoTable) acdHelpTableShow(asslist, "Associated qualifiers"); if(acdVerbose && acdDoTable) acdHelpTableShow(genlist, "General qualifiers"); } if(acdDoXsd) { acdHelpXsdShow(inlist, outlist); ajUserDumpC(""); } else if(acdDoGalaxy) { acdHelpGalaxyShow(inlist, outlist); ajUserDumpC(""); } else if(acdDoTable) ajUserDumpC("
"); ajExit(); return; } ID acdHelpAssoc TY static MO ajacd LB acd XX DE Processes all associated qualifiers for a qualifier or for the application. DE DE If a qualifier name is given (e.g. "help") then only that qualifier DE is processed. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA u str AjPStr* PD Help text being built PX PN [3] PA r name const char* PD Single name to process PX RT void RD RX // static void acdHelpAssoc(const AcdPAcd thys, AjPStr *str, const char* name) { static AjPStr line = NULL; static AjPStr qname = NULL; static AjPStr qtype = NULL; static AjPStr text = NULL; AcdPQual quals; ajint i; acdLog("++ acdHelpAssoc %S\n", thys->Name); if(thys->Level == ACD_APPL) quals = acdQualAppl; else { ajFmtPrintS(&line, "\n \"-%S\" associated qualifiers\n", thys->Name); ajStrAppendS(str, line); quals = acdType[thys->Type].Quals; } acdLog("++ type %d quals %x\n", thys->Type, quals); if(quals) { for(i=0; quals[i].Name; i++) { acdLog("++ quals[%d].Name %s\n", i, quals[i].Name); if(name && strcmp(name, quals[i].Name)) continue; if(thys->PNum) ajFmtPrintS(&qname, " -%s%d", quals[i].Name, thys->PNum); else ajFmtPrintS(&qname, " -%s", quals[i].Name); ajStrAssignC(&qtype, quals[i].Type); ajFmtPrintS(&line, " %-20S %-10S ", qname, qtype); ajStrAssignC(&text, quals[i].Help); acdTextFormat(&text); ajStrFmtWrapLeft(&text, 45, 34, 0); ajStrCutStart(&text, 34); ajStrAppendS(&line, text); ajStrAppendC(&line, "\n"); ajStrAppendS(str, line); } } return; } ID acdHelpAppend TY static MO ajacd LB acd XX DE Appends a qualifier and its help text to a help category string. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA u str AjPStr* PD Help text being built PX PN [3] PA r flag char PD Flag character. Usually blank, but an asterisk PD is used if the status (optional/required) is PD uncertain. PX RT void RD RX // static void acdHelpAppend(const AcdPAcd thys, AjPStr *str, char flag) { static AjPStr name = NULL; static AjPStr valstr = NULL; static AjPStr nostr = NULL; static AjPStr nullstr = NULL; static AjPStr text = NULL; static AjPStr line = NULL; static AjPStr type = NULL; AjBool boolval; AjPStr defstr; nullstr = ajStrNew(); if(ajCharMatchC("list", acdType[thys->Type].Name)) ajStrAssignC(&type, "menu"); else ajStrAssignC(&type, acdType[thys->Type].Name); if(thys->DefStr) defstr = thys->OrigStr; else defstr = nullstr; ajStrAssignClear(&nostr); if(acdIsQtype(thys) && (ajCharMatchC("boolean", acdType[thys->Type].Name) || ajCharMatchC("toggle", acdType[thys->Type].Name) )) { if(ajStrToBool(defstr, &boolval) && boolval) ajStrAssignC(&nostr, "[no]"); defstr = nullstr; } ajStrAssignS(&valstr, defstr); /* ** warning - don't try acdVarResolve here because we have not yet ** read in the data and things like calculated attributes do not exist */ if(thys->Level == ACD_PARAM) ajFmtPrintS(&name, "[-%S%S]", nostr, thys->Name); else ajFmtPrintS(&name, " -%S%S", nostr, thys->Name); ajFmtPrintS(&line, "%c %-20S %-10S ", flag, name, type); if(!acdDoTable) { acdHelpExpect(thys, ajFalse, &text); if(ajStrGetLen(text)) { ajStrInsertC(&text, 0, "["); ajStrAppendC(&text, "] "); } } acdHelpText(thys, &text); if(ajStrGetLen(text)) ajStrAppendC(&text, " "); if(!acdDoTable) acdHelpValid(thys, ajFalse, &text); ajStrRemoveWhiteSpaces(&text); acdTextFormat(&text); ajStrFmtWrapLeft(&text, 45, 34, 0); ajStrCutStart(&text, 34); ajStrAppendS(&line, text); ajStrAppendC(&line, "\n"); ajStrAppendS(str, line); ajStrDel(&name); ajStrDel(&valstr); ajStrDel(&nostr); ajStrDel(&nullstr); ajStrDel(&text); ajStrDel(&line); ajStrDel(&type); return; } ID acdHelpValidAlign TY static MO ajacd LB acd XX DE Generates valid description for a alignment output XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidAlign(const AcdPAcd thys, AjBool table, AjPStr* str) { AjPStr fmt = NULL; if(!thys) return; acdGetValueAssocDefault(thys, "aformat", &fmt); if(ajStrGetLen(fmt)) ajFmtPrintAppS(str, "(default -aformat %S)", fmt); else if(table) ajStrAssignClear(str); ajStrDel(&fmt); return; } ID acdHelpValidReport TY static MO ajacd LB acd XX DE Generates valid description for a report output XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidReport(const AcdPAcd thys, AjBool table, AjPStr* str) { AjPStr fmt = NULL; if(!thys) return; acdGetValueAssocDefault(thys, "rformat", &fmt); if(ajStrGetLen(fmt)) ajFmtPrintAppS(str, "(default -rformat %S)", fmt); else if(table) ajStrAssignClear(str); ajStrDel(&fmt); return; } ID acdHelpValidSeq TY static MO ajacd LB acd XX DE Generates valid description for an input sequence type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidSeq(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidSeqout TY static MO ajacd LB acd XX DE Generates valid description for an output sequence type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidSeqout(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidOut TY static MO ajacd LB acd XX DE Generates valid description for an outfile type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidOut(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidIn TY static MO ajacd LB acd XX DE Generates valid description for an infile type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidIn(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidData TY static MO ajacd LB acd XX DE Generates valid description for a datafile type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidData(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidInt TY static MO ajacd LB acd XX DE Generates valid description for an integer type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidInt(const AcdPAcd thys, AjBool table, AjPStr* str) { ajint imin; ajint imax; acdAttrValueStr(thys, "minimum", "$", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &imin)) imin = INT_MIN; acdAttrValueStr(thys, "maximum", "$", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &imax)) imax = INT_MAX; if(table) ajStrAssignClear(str); else ajStrAppendC(str, " ("); if(imax != INT_MAX) { if(imin != INT_MIN) ajFmtPrintAppS(str, "Integer from %d to %d", imin, imax); else ajFmtPrintAppS(str, "Integer up to %d", imax); } else { if(imin != INT_MIN) ajFmtPrintAppS(str, "Integer %d or more", imin); else ajFmtPrintAppS(str, "Any integer value"); } if(!table) ajStrAppendC(str, ")"); return; } ID acdHelpValidFloat TY static MO ajacd LB acd XX DE Generates valid description for a floating point type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidFloat(const AcdPAcd thys, AjBool table, AjPStr* str) { float vfmin; float vfmax; ajint iprec; acdAttrValueStr(thys, "minimum", "$", &acdTmpStr); if(!ajStrToFloat(acdTmpStr, &vfmin)) vfmin = -FLT_MAX; acdAttrValueStr(thys, "maximum", "$", &acdTmpStr); if(!ajStrToFloat(acdTmpStr, &vfmax)) vfmax = FLT_MAX; acdAttrValueStr(thys, "precision", "$", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &iprec)) iprec = 3; if(table) ajStrAssignClear(str); else ajStrAppendC(str, " ("); if(vfmax != FLT_MAX) { if(vfmin != -FLT_MAX) ajFmtPrintAppS(str, "Number from %.*f to %.*f", iprec, vfmin, iprec, vfmax); else ajFmtPrintAppS(str, "Number up to %.*f", iprec, vfmax); } else { if(vfmin != -FLT_MAX) ajFmtPrintAppS(str, "Number %.*f or more", iprec, vfmin); else ajFmtPrintAppS(str, "Any numeric value"); } if(!table) ajStrAppendC(str, ")"); return; } ID acdHelpValidCodon TY static MO ajacd LB acd XX DE Generates valid description for a codon usage table type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidCodon(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidDirlist TY static MO ajacd LB acd XX DE Generates valid description for a dirlist type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidDirlist(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidFilelist TY static MO ajacd LB acd XX DE Generates valid description for a filelist type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidFilelist(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidMatrix TY static MO ajacd LB acd XX DE Generates valid description for a comparison matrix type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidMatrix(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidFeatout TY static MO ajacd LB acd XX DE Generates valid description for a feature output type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidFeatout(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidFeatures TY static MO ajacd LB acd XX DE Generates valid description for an input feature type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidFeatures(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidRange TY static MO ajacd LB acd XX DE Generates valid description for a sequence range. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidRange(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAssignClear(str); return; } ID acdHelpValidGraph TY static MO ajacd LB acd XX DE Generates valid description for a graphics device type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidGraph(const AcdPAcd thys, AjBool table, AjPStr* str) { AjPList list; AjPStr name = NULL; ajint i = 0; if(!thys) return; list = ajListstrNew(); ajGraphicsListDevices(list); if(table) ajFmtPrintAppS(str, "EMBOSS has a list of known devices, including "); else ajFmtPrintAppS(str, " ("); while(ajListstrPop(list, &name)) { if(i) ajFmtPrintAppS(str, ", "); ajFmtPrintAppS(str, "%S", name); ajStrDel(&name); i++; } if(!table) ajFmtPrintAppS(str, ")"); ajListFree(&list); return; } ID acdHelpValidString TY static MO ajacd LB acd XX DE Generates valid description for a string type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidString(const AcdPAcd thys, AjBool table, AjPStr* str) { ajint minlen; ajint maxlen; AjBool word; acdAttrValueStr(thys, "minlength", "0", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &minlen)) minlen = 0; acdAttrValueStr(thys, "maxlength", "0", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &maxlen)) maxlen = 0; acdAttrValueStr(thys, "word", "0", &acdTmpStr); if(!ajStrToBool(acdTmpStr, &word)) ajFatal("Bad boolean value"); if(table) ajStrAssignClear(str); else ajStrAppendC(str, " ("); if(word) ajFmtPrintAppS(str, "Any word"); else ajFmtPrintAppS(str, "Any string"); if(maxlen > 0) { if(minlen > 0) ajFmtPrintAppS(str, " from %d to %d characters", minlen, maxlen); else ajFmtPrintAppS(str, " up to %d characters", maxlen); } else { if(minlen > 0) ajFmtPrintAppS(str, " of at least %d characters", minlen); } acdAttrValueStr(thys, "pattern", "", &acdTmpStr); if(ajStrGetLen(acdTmpStr)) ajFmtPrintAppS(str, ", matching regular expression /%S/", acdTmpStr); if(!table) ajStrAppendC(str, ")"); return; } ID acdHelpValidRegexp TY static MO ajacd LB acd XX DE Generates valid description for a regular expression type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidRegexp(const AcdPAcd thys, AjBool table, AjPStr* str) { ajint minlen; ajint maxlen; acdAttrValueStr(thys, "minlength", "0", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &minlen)) minlen = 0; acdAttrValueStr(thys, "maxlength", "0", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &maxlen)) maxlen = 0; if(table) ajStrAssignClear(str); else ajStrAppendC(str, " ("); if(maxlen > 0) { if(minlen > 0) ajFmtPrintS(str, "A regular expression pattern from %d to " "%d characters", minlen, maxlen); else ajFmtPrintS(str, "A regular expression pattern up to %d characters", maxlen); } else { if(minlen > 0) ajFmtPrintS(str, "A regular expression pattern of at least " "%d characters", minlen); else ajStrAssignC(str, "Any regular expression pattern is accepted"); } if(!table) ajStrAppendC(str, ")"); return; } ID acdHelpValidList TY static MO ajacd LB acd XX DE Generates valid description for a list type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidList(const AcdPAcd thys, AjBool table, AjPStr* str) { AjPStr codedelim = NULL; AjPStr delim = NULL; AjPStr value = NULL; AjPStrTok handle; AjPStrTok codehandle; static AjPStr code = NULL; static AjPStr desc = NULL; static AjPStr line = NULL; acdAttrValueStr(thys, "delimiter", ";", &delim); acdAttrValueStr(thys, "value", "", &value); if(!ajStrGetLen(value)) if(!acdKnownValueList(thys, &value)) acdError("No value defined for list"); handle = ajStrTokenNewS(value, delim); if(table) ajFmtPrintAppS(str, ""); else ajFmtPrintAppS(str, " (Values: "); acdAttrValueStr(thys, "codedelimiter", ":", &codedelim); while(ajStrTokenNextFind(&handle, &line)) { codehandle = ajStrTokenNewS(line, codedelim); ajStrTokenNextParse(&codehandle, &code); ajStrTokenNextParseS(&codehandle, delim, &desc); acdTextTrim(&code); acdTextTrim(&desc); if(table) ajFmtPrintAppS(str, "", code, desc); else ajFmtPrintAppS(str, "%S (%S); ", code, desc); ajStrTokenDel(&codehandle); } if(table) ajFmtPrintAppS(str, "
%S (%S)
"); else { ajStrCutEnd(str, 2); ajStrAppendC(str, ")"); } ajStrTokenDel(&handle); return; } ID acdHelpValidSelect TY static MO ajacd LB acd XX DE Generates valid description for a select type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpValidSelect(const AcdPAcd thys, AjBool table, AjPStr* str) { AjPStr delim = NULL; AjPStr value = NULL; AjPStrTok handle; static AjPStr desc = NULL; static const char* white = " \t\n\r"; acdAttrValueStr(thys, "delimiter", ";", &delim); acdAttrValueStr(thys, "value", "", &value); if(!ajStrGetLen(value)) if(!acdKnownValueSelect(thys, &value)) acdError("No value defined for selection"); handle = ajStrTokenNewS(value, delim); while(ajStrTokenNextFind(&handle, &desc)) { ajStrTrimC(&desc, white); if(table) ajFmtPrintAppS(str, "%S
", desc); else { if(ajStrGetLen(*str)) ajStrAppendK(str, ' '); ajFmtPrintAppS(str, "%S", desc); } } ajStrTokenDel(&handle); return; } ID acdHelpValid TY static MO ajacd LB acd XX DE Generates help text for an ACD object using the help, info, prompt DE and code settings. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated. Only written to if PD initially empty PX RT void RD RX // static void acdHelpValid(const AcdPAcd thys, AjBool table, AjPStr* str) { ajint i; AjPStr tmpstr = NULL; if(table && ajStrGetLen(*str)) return; if(acdAttrValueStr(thys, "valid", "", &tmpstr)) { if(table) ajStrAppendS(str, tmpstr); else ajFmtPrintAppS(str, "(%S)", tmpstr); return; } /* special processing for sequences, outseq, outfile */ for(i=0; acdValue[i].Name; i++) if(ajCharMatchC(acdType[thys->Type].Name, acdValue[i].Name)) { /* Calling funclist acdValue() */ if(acdValue[i].Valid) (*acdValue[i].Valid)(thys, table, str); break; } if(ajStrGetLen(*str)) return; ajStrAppendC(str, acdType[thys->Type].Valid); return; } ID acdHelpExpectSeq TY static MO ajacd LB acd XX DE Generates expected value description for an input sequence type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectSeq(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajFmtPrintAppS(str, "Required"); return; } ID acdHelpExpectSeqout TY static MO ajacd LB acd XX DE Generates expected value description for an output sequence type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectSeqout(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajFmtPrintAppS(str, "<*>.format"); else ajFmtPrintAppS(str, "."); return; } ID acdHelpExpectOut TY static MO ajacd LB acd XX DE Generates expected value description for an outfile type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectOut(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajFmtPrintAppS(str, "<*>.%S", acdProgram); else ajFmtPrintAppS(str, "*.%S", acdProgram); return; } ID acdHelpExpectInt TY static MO ajacd LB acd XX DE Generates expected value description for an integer type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectInt(const AcdPAcd thys, AjBool table, AjPStr* str) { ajint i; acdAttrValueStr(thys, "default", "0", &acdTmpStr); if(ajStrToInt(acdTmpStr, &i)) ajFmtPrintAppS(str, "%d", i); else { if(table) ajFmtPrintAppS(str, "calculated value"); } return; } ID acdHelpExpectFloat TY static MO ajacd LB acd XX DE Generates expected value description for a floating point type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectFloat(const AcdPAcd thys, AjBool table, AjPStr* str) { float f; ajint iprec; acdAttrValueStr(thys, "default", "0.0", &acdTmpStr); if(!ajStrToFloat(acdTmpStr, &f)) f = 0.0; acdAttrValueStr (thys, "precision", "3", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &iprec)) iprec = 3; if(table) ajFmtPrintAppS(str, "%.*f", iprec, f); else ajFmtPrintAppS(str, "%.*f", iprec, f); return; } ID acdHelpExpectIn TY static MO ajacd LB acd XX DE Generates expected value description for an infile type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectIn(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajFmtPrintS(str, "Required"); return; } ID acdHelpExpectData TY static MO ajacd LB acd XX DE Generates expected value description for a datafile type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectData(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajFmtPrintS(str, "File in the data file path"); return; } ID acdHelpExpectCodon TY static MO ajacd LB acd XX DE Generates expected value description for a codon usage table type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectCodon(const AcdPAcd thys, AjBool table, AjPStr* str) { AjPStr tmpstr = NULL; if(!thys) return; acdAttrResolve(thys, "name", &tmpstr); if(ajStrGetLen(tmpstr)) { if(table) ajStrAppendS(str, tmpstr); else ajStrAppendS(str, tmpstr); ajStrDel(&tmpstr); return; } return; } ID acdHelpExpectDirlist TY static MO ajacd LB acd XX DE Generates expected value description for a dirlist type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectDirlist(const AcdPAcd thys, AjBool table, AjPStr* str) { AjPStr tmpstr = NULL; if(!thys) return; acdAttrResolve(thys, "default", &tmpstr); if(ajStrGetLen(tmpstr)) { if(table) ajStrAppendS(str, tmpstr); else ajStrAppendS(str, tmpstr); ajStrDel(&tmpstr); return; } if(table) ajStrAssignC(str, DEFDLIST); else ajStrAssignC(str, DEFDLIST); return; } ID acdHelpExpectFilelist TY static MO ajacd LB acd XX DE Generates expected value description for a filelist type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectFilelist(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAppendC(str, "comma-separated file list"); return; } ID acdHelpExpectMatrix TY static MO ajacd LB acd XX DE Generates expected value description for a comparison matrix type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectMatrix(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAppendC(str, "EBLOSUM62 for protein
EDNAFULL for DNA"); else ajStrAppendC(str, "EBLOSUM62 for protein, EDNAFULL for DNA"); return; } ID acdHelpExpectFeatout TY static MO ajacd LB acd XX DE Generates expected value description for a feature output type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectFeatout(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAppendC(str, "unknown.gff"); else ajStrAppendC(str, "unknown.gff"); return; } ID acdHelpExpectFeatures TY static MO ajacd LB acd XX DE Generates expected value description for an input feature type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectFeatures(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajFmtPrintAppS(str, "Required"); return; } ID acdHelpExpectRange TY static MO ajacd LB acd XX DE Generates expected value description for a sequence range type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectRange(const AcdPAcd thys, AjBool table, AjPStr* str) { if(!thys) return; if(table) ajStrAppendC(str, "full sequence"); else ajStrAppendC(str, "(full sequence)"); return; } ID acdHelpExpectGraph TY static MO ajacd LB acd XX DE Generates expected value description for a graphics device type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectGraph(const AcdPAcd thys, AjBool table, AjPStr* str) { #ifndef WIN32 #ifndef X_DISPLAY_MISSING /* X11 is available */ const char* defdev = "x11"; #else #ifdef PLD_png /* if png/gd/zlib libraries available for png driver */ const char* defdev = "png"; #else const char* defdev = "ps"; #endif #endif #else const char* defdev = "win3"; #endif if(!thys) return; if(table) ajFmtPrintAppS(str, "EMBOSS_GRAPHICS value, or %s", defdev); else ajFmtPrintAppS(str, "$EMBOSS_GRAPHICS value, or %s", defdev); return; } ID acdHelpExpectRegexp TY static MO ajacd LB acd XX DE Generates expected value description for a regular expression type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectRegexp(const AcdPAcd thys, AjBool table, AjPStr* str) { ajint minlen; acdAttrValueStr(thys, "min", "1", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &minlen)) minlen = 0; if(minlen > 0) { if(table) ajStrAppendC(str, "Required"); } else { if(table) ajStrAppendC(str, "An empty regular expression is accepted"); } return; } ID acdHelpExpectString TY static MO ajacd LB acd XX DE Generates expected value description for a string type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpectString(const AcdPAcd thys, AjBool table, AjPStr* str) { ajint minlen; acdAttrValueStr(thys, "min", "0", &acdTmpStr); if(!ajStrToInt(acdTmpStr, &minlen)) minlen = 0; if(minlen > 0) { if(table) ajStrAppendC(str, "Required"); } else { if(table) ajStrAppendC(str, " "); } return; } ID acdHelpExpect TY static MO ajacd LB acd XX DE Generates expected value text for an ACD object code settings. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r table AjBool PD True if writing acdtable HTML table PX PN [3] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpExpect(const AcdPAcd thys, AjBool table, AjPStr* str) { ajint i; AjPStr tmpstr = NULL; if(ajStrGetLen(*str)) return; if(!thys->AssocQuals && !acdDoGalaxy) if(acdAttrValueStr(thys, "expected", "", str)) return; if(acdAttrValueStr(thys, "default", "", str)) { if(acdDoGalaxy) { tmpstr = ajStrNewS(*str); if(!acdVarSimpleResolve(tmpstr, str)) ajStrAssignS(str, tmpstr); ajStrDel(&tmpstr); } return; } /* special processing for sequences, outseq, outfile */ for(i=0; acdValue[i].Name; i++) if(ajCharMatchC(acdType[thys->Type].Name, acdValue[i].Name)) { /* Calling funclist acdValue() */ if(acdValue[i].Expect) (*acdValue[i].Expect)(thys, table, str); break; } if(ajStrGetLen(*str)) return; ajStrAppendS(str, thys->DefStr[DEF_DEFAULT]); if(ajStrGetLen(*str)) return; if(table) ajStrAppendC(str, " "); return; } ID acdHelpText TY static MO ajacd LB acd XX DE Generates help text for an ACD object using the help, info, prompt DE and code settings. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA w str AjPStr* PD Help text (if any) generated PX RT void RD RX // static void acdHelpText(const AcdPAcd thys, AjPStr* str) { AjPStr prompt; AjPStr info; AjPStr code; AjPStr help; static AjPStr msg = NULL; if(thys->DefStr) { prompt = thys->DefStr[DEF_PROMPT]; info = thys->DefStr[DEF_INFO]; code = thys->DefStr[DEF_CODE]; help = thys->DefStr[DEF_HELP]; if(ajStrGetLen(help)) ajStrAssignS(&msg, help); else if(ajStrGetLen(code)) acdCodeGet(code, &msg); else if(ajStrGetLen(info)) ajStrAssignS(&msg, info); else if(ajStrGetLen(prompt)) ajStrAssignS(&msg, prompt); else if(acdType[thys->Type].HelpSet) (*acdType[thys->Type].HelpSet)(thys, &msg); else { if(!acdHelpCodeDef(thys, &msg)) { ajStrAssignResC(&msg, 512, ""); if(thys->Assoc) ajFmtPrintS(&msg, "%s value", acdType[thys->Type].Name); else ajFmtPrintS(&msg, "(no help text) %s value", acdType[thys->Type].Name); } } acdVarResolve(&msg); ajStrAppendS(str, msg); ajStrDel(&msg); } return; } ID acdHelpShow TY static MO ajacd LB acd XX DE Prints the qualifier category and the help for any DE qualifiers in that category (or "(none)" if there are none). XX PN [1] PA r str const AjPStr PD Help text (if any) PX PN [2] PA r title const char* PD Title line for this call PX RT void RD RX // static void acdHelpShow(const AjPStr str, const char* title) { if(acdDoTable) return; if(!ajStrGetLen(str)) { ajUser(" %s: (none)", title); return; } ajUser(" %s:", title); ajUserDumpS(str); return; } ID acdHelpTableShow TY static MO ajacd LB acd XX DE Prints the qualifier category and the help for any DE qualifiers in that category (or "(none)" if there are none). XX PN [1] PA r tablist const AjPList PD Help text (if any). PX PN [2] PA r title const char* PD Title line for this call PX RT void RD RX // static void acdHelpTableShow(const AjPList tablist, const char* title) { AcdPTableItem item; AjIList iter = NULL; ajuint nitem = 0; if(!acdDoTable) return; if(!tablist) { ajUserDumpC(""); /* was #FFFFD0 */ ajUserDumpC("Qualifier"); ajUserDumpC("Type"); ajUserDumpC("Description"); ajUserDumpC("Allowed values"); ajUserDumpC("Default"); ajUserDumpC("\n"); return; } /* new section */ if(title){ ajUserDumpC(""); /* was #FFFFD0 */ ajUser("%s", title); ajUserDumpC("\n"); } iter = ajListIterNewread(tablist); while((item = ajListIterGet(iter))) { ajUserDumpC(""); if(ajStrGetLen(item->Title)) { ajUser("%S", item->Title); } else { nitem++; acdTextTrim(&item->Help); ajUser("%S", item->Qual); ajUser("%S", item->Type); ajUser("%S", item->Help); ajUser("%S", item->Valid); ajUser("%S", item->Expect); } ajUserDumpC("\n"); } if(!nitem || !ajListGetLength(tablist)) { ajUserDumpC(""); ajUserDumpC("(none)"); ajUserDumpC("\n"); } ajListIterDel(&iter); return; } ID acdHelpXsdShow TY static MO ajacd LB acd XX DE Prints the qualifier category and the help for any DE qualifiers in that category (or "(none)" if there are none). XX PN [1] PA r inlist const AjPList PD Help text (if any). PX PN [2] PA r outlist const AjPList PD Help text (if any). PX RT void RD RX // static void acdHelpXsdShow(const AjPList inlist, const AjPList outlist) { AcdPXsdItem item; AjIList iter = NULL; AjPStrTok handle = NULL; AjPStr rest = NULL; AjPStr word = NULL; AjPStr tmpstr = NULL; if(!acdDoXsd) return; ajUserDumpC(" "); ajUserDumpC(" "); ajUserDumpC(" "); if(ajListGetLength(inlist)) { iter = ajListIterNewread(inlist); while((item = ajListIterGet(iter))) { acdTextTrim(&item->Annotation); /* Need specific strings for each datatype */ /* add a block here as a temporary solution */ /* ** Later create a functions for each datatype ** and a default function for general datatypes */ /* ** Datatypes with more than one value - sequences see above, others ** may explicitly write their choices */ #if 0 /* //ajUser(" ", // item->Qual); //ajUser(" "); */ #endif /* ** sequences: 1 for required values - e.g. parameters - 0 for ** others */ if (ajStrMatchC(item->Type, "long")) { ajUser(" Qual); if(ajStrGetLen(item->Relation)) { handle = ajStrTokenNewC(item->Relation, "|"); while(ajStrTokenNextParse(&handle, &tmpstr)) { ajStrExtractWord(tmpstr, &rest, &word); ajUser(" sawsdl:modelReference=" "\"http://purl.org%S\"", word); } ajStrTokenDel(&handle); } ajUser(" minOccurs=\"1\">"); ajUser(" "); ajUser(" "); ajUser(" %S", item->Annotation); ajUser(" "); ajUser(" "); ajUser(" "); ajUser(" "); ajUser(" "); /* TODO actual min value */ ajUser(" "); ajUser(" "); ajUser(" "); } else if (ajStrMatchC(item->Type, "seqall")){ ajUser(" Qual); if(ajStrGetLen(item->Relation)) { handle = ajStrTokenNewC(item->Relation, "|"); while(ajStrTokenNextParse(&handle, &tmpstr)) { ajStrExtractWord(tmpstr, &rest, &word); ajUser(" sawsdl:modelReference=" "\"http://purl.org%S\"", word); } ajStrTokenDel(&handle); } ajUser(" minOccurs=\"1\">"); ajUser(" "); ajUser(" "); ajUser(" %S", item->Annotation); ajUser(" "); ajUser(" "); } else { ajUser(" Qual, item->Type); if(ajStrGetLen(item->Relation)) { handle = ajStrTokenNewC(item->Relation, "|"); while(ajStrTokenNextParse(&handle, &tmpstr)) { ajStrExtractWord(tmpstr, &rest, &word); ajUser(" sawsdl:modelReference=" "\"http://purl.org%S\"", word); } ajStrTokenDel(&handle); } ajUser(" minOccurs=\"1\">"); ajUser(" "); ajUser(" "); ajUser(" %S", item->Annotation); ajUser(" "); ajUser(" "); } ajUser(" "); } } ajListIterDel(&iter); ajUserDumpC(" "); ajUserDumpC(" "); ajUserDumpC(" "); ajUserDumpC(" "); if(ajListGetLength(outlist)) { iter = ajListIterNewread(outlist); while((item = ajListIterGet(iter))) { if (ajStrMatchC(item->Type, "seqoutall")) { ajUser(" Qual, item->Type); } else { ajUser(" Qual, item->Type); } if(ajStrGetLen(item->Relation)) { ajUser("relation: '%S'", item->Relation); handle = ajStrTokenNewC(item->Relation, "|"); while(ajStrTokenNextParse(&handle, &tmpstr)) { ajStrExtractWord(tmpstr, &rest, &word); ajUser(" sawsdl:modelReference=\"http://purl.org%S\"", word); } ajStrTokenDel(&handle); } ajUser(" minOccurs=\"1\">"); ajUser(" "); ajUser(" "); ajUser(" %S", item->Annotation); ajUser(" "); ajUser(" "); ajUser(" "); } } ajUserDumpC(" "); ajUserDumpC(" "); ajListIterDel(&iter); ajStrDel(&tmpstr); ajStrDel(&rest); ajStrDel(&word); return; } ID acdHelpGalaxyShow TY static MO ajacd LB acd XX DE Prints the qualifier category and the help for any DE qualifiers in that category (or "(none)" if there are none). XX PN [1] PA r inlist const AjPList PD Help text (if any). PX PN [2] PA r outlist const AjPList PD Help text (if any). PX RT void RD RX // static void acdHelpGalaxyShow(const AjPList inlist, const AjPList outlist) { AcdPGalaxyItem item; AjIList iter = NULL; /* AjPStrTok handle = NULL;*/ AjPStr rest = NULL; AjPStr word = NULL; AjPStr tmpstr = NULL; AjPStr galaxyvar = NULL; ajuint ninputs = 0; ajuint noutputs = 0; ajuint i; AjPStrTok handle = NULL; AjPStr galaxyin = NULL; AjPStr galaxyout = NULL; AjPStr fmtname = NULL; AjPStr fmtdesc = NULL; const char* acdinputs[] = { "sequence", "seqall", "seqset", "seqsetall", "features", NULL }; const char* acdoutputs[] = { "seqout", "seqoutall", "seqoutset", "align", "report", "featout", "graph", "xygraph", NULL }; const char* acdoutformats[] = { "seqout", "seqoutall", "seqoutset", "align", "gff:GFF,pir:PIR,swiss:SWISS,excel:Excel (TAB Delimited)", "featout", "png:PNG", "png:PNG", NULL }; const char* acdoutfmtqual[] = { "format", "format", "format", "aformat", "rformat", "fformat", "", "", NULL }; if(!acdDoGalaxy) return; if(!acdGalaxyCmdStr) acdGalaxyCmdStr = ajStrNewS(acdProgram); if(ajListGetLength(inlist)) { iter = ajListIterNewread(inlist); while((item = ajListIterGet(iter))) { acdTextTrim(&item->Annotation); /* ajUser("AcdSGalaxyItem input"); ajUser(" qual: '%S'", item->Qual); ajUser(" type: '%S'", item->Type); ajUser(" annotation: '%S'", item->Annotation); ajUser(" relation: '%S'", item->Relation); ajUser(" valid: '%S'", item->Valid); ajUser(" expect: '%S'", item->Expect); ajUser(" required: '%B'", item->Required); ajUser(" optional: '%B'", item->Optional); */ /* ** test Type ** use to select format, input1/output1 name, type ** need for output format (note: this is an input!) ** set size=4 for int or float ** type text for string, integer for int, float for float */ for(i=0; acdinputs[i]; i++) if(ajStrMatchC(item->Type, acdinputs[i])) break; if(acdinputs[i]) { ajFmtPrintAppS(&galaxyin, " \n", ++ninputs); ajFmtPrintAppS(&galaxyin, " \n"); ajFmtPrintAppS(&galaxyin, " \n"); ajFmtPrintAppS(&acdGalaxyCmdStr, " -%S $input%u", item->Qual, ninputs); } else if(ajStrMatchC(item->Expect, "Required")) { ajFmtPrintAppS(&galaxyin, " \n", item->Qual); ajFmtPrintAppS(&galaxyin, " \n"); ajFmtPrintAppS(&galaxyin, " \n"); ajFmtPrintAppS(&acdGalaxyCmdStr, " -%S $%S", item->Qual, item->Qual); } else { if(ajStrMatchC(item->Type, "string")) ajFmtPrintAppS(&galaxyin, " \n", item->Qual, item->Expect); else if(ajStrMatchC(item->Type, "boolean") || ajStrMatchC(item->Type, "toggle")) { ajFmtPrintAppS(&galaxyin, " \n", item->Qual, item->Expect); } else if(ajStrMatchC(item->Type, "float") || ajStrMatchC(item->Type, "double")) ajFmtPrintAppS(&galaxyin, " \n", item->Qual, item->Expect); else if(ajStrMatchC(item->Type, "integer") || ajStrMatchC(item->Type, "long")) ajFmtPrintAppS(&galaxyin, " \n", item->Qual, item->Expect); else if(ajStrMatchC(item->Type, "select") || ajStrMatchC(item->Type, "list")) ajFmtPrintAppS(&galaxyin, " \n", item->Qual, item->Expect); else ajFmtPrintAppS(&galaxyin, " \n", item->Qual, item->Expect); ajFmtPrintAppS(&galaxyin, " \n", item->Prompt); ajFmtPrintAppS(&galaxyin, " \n"); ajStrDel(&galaxyvar); if(!ajStrGetLen(galaxyvar)) galaxyvar = item->Qual; ajFmtPrintAppS(&acdGalaxyCmdStr, " -%S $%S", item->Qual, galaxyvar); } /* Need specific strings for each datatype */ /* add a block here as a temporary solution */ /* ** sequences: 1 for required values - e.g. parameters - 0 for ** others */ /* if (ajStrMatchC(item->Type, "long")) { ajUserDumpC("long"); } else if (ajStrMatchC(item->Type, "seqall")){ ajUserDumpC("seqall"); } else { ajUserDumpC("other"); } ajUserDumpC("...initemdone"); */ } } ajListIterDel(&iter); if(ajListGetLength(outlist)) { iter = ajListIterNewread(outlist); while((item = ajListIterGet(iter))) { for(i=0; acdoutputs[i]; i++) if(ajStrMatchC(item->Type, acdoutputs[i])) break; if(acdoutputs[i]) { if(ajCharMatchC(acdoutputs[i], "graph") || ajCharMatchC(acdoutputs[i], "xygraph")) { ajFmtPrintAppS(&acdGalaxyCmdStr, " -%S png -goutfile $goutfile", item->Qual); ajFmtPrintAppS(&galaxyout, " \n", acdoutformats[i], acdProgram, ++noutputs); } else if(ajCharMatchC(acdoutputs[i], "report")) { ajFmtPrintAppS(&galaxyout, " \n", acdProgram, ++noutputs); if(ajCharMatchC(acdoutputs[i], "report")) { ajFmtPrintAppS(&galaxyin, " \n", noutputs); ajFmtPrintAppS(&galaxyin, " \n"); ajStrTokenAssigncharC(&handle, acdoutformats[i], ":,"); while(ajStrTokenNextParse(&handle, &fmtname)) { ajStrTokenNextParse(&handle, &fmtdesc); if(ajStrMatchC(fmtname, "gff2")) ajFmtPrintAppS(&galaxyin, " " "\n", fmtname, fmtdesc); else ajFmtPrintAppS(&galaxyin, " \n", fmtname, fmtdesc); } ajFmtPrintAppS(&galaxyin, " "); ajFmtPrintAppS(&acdGalaxyCmdStr, " -rformat $out_format%u", noutputs); } } else { ajFmtPrintAppS(&galaxyout, " \n", acdProgram, ++noutputs); if(ajCharMatchC(acdoutputs[i], "report")) { ajFmtPrintAppS(&galaxyin, " \n", noutputs); ajFmtPrintAppS(&galaxyin, " \n"); ajStrTokenAssigncharC(&handle, acdoutformats[i], ":,"); while(ajStrTokenNextParse(&handle, &fmtname)) { ajStrTokenNextParse(&handle, &fmtdesc); if(ajStrMatchS(fmtname, item->Expect)) ajFmtPrintAppS(&galaxyin, " " "\n", fmtname, fmtdesc); else ajFmtPrintAppS(&galaxyin, " \n", fmtname, fmtdesc); } ajFmtPrintAppS(&galaxyin, " "); ajFmtPrintAppS(&acdGalaxyCmdStr, " -%s $out_format%u", acdoutfmtqual[i], noutputs); } } } else { /* use type=file or type=data (which?) */ ajFmtPrintAppS(&galaxyout, " \n" " \n" " \n", item->Qual, item->Qual, item->Annotation); } /* ajUser("AcdSGalaxyItem output\n"); ajUser(" qual: '%S'", item->Qual); ajUser(" type: '%S'", item->Type); ajUser(" annotation: '%S'", item->Annotation); ajUser(" relation: '%S'", item->Relation); ajUser(" valid: '%S'", item->Valid); ajUser(" expect: '%S'", item->Expect); ajUser(" required: '%B'", item->Required); ajUser(" optional: '%B'", item->Optional); */ /* if (ajStrMatchC(item->Type, "seqoutall")) { ajUserDumpC("seqoutall"); } else { ajUserDumpC("other"); } if(ajStrGetLen(item->Relation)) { handle = ajStrTokenNewC(item->Relation, "|"); while(ajStrTokenNextParse(&handle, &tmpstr)) { ajStrExtractWord(tmpstr, &rest, &word); ajUserDumpC(""); } ajStrTokenDel(&handle); } ajUserDumpC("...outitemdone"); */ } } ajUser(" %S -auto", acdGalaxyCmdStr); ajUserDumpC(" "); ajUserDumpS(galaxyin); ajUserDumpC(" "); ajUserDumpC(" "); ajUserDumpS(galaxyout); ajUserDumpC(" "); /* ajUser(" "); */ /* for each QA test: */ /*ajUser(" \n" " \n" " \n" " \n" " \n" " " ); */ /* end of QA tests */ /* ajUser(" \n"); */ ajUser(" \n" " \n" "\n" " You can view the original documentation here_.\n" "\n" " .. _here: http://emboss.sourceforge.net/apps/release/6.4/" "emboss/apps/%S.html\n" " \n" "", acdProgram); ajListIterDel(&iter); ajStrDel(&tmpstr); ajStrDel(&rest); ajStrDel(&word); ajStrDel(&fmtname); ajStrDel(&fmtdesc); ajStrTokenDel(&handle); return; } ID acdHelpAssocTable TY static MO ajacd LB acd XX DE Appends an associated qualifier and its help text to the table list. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA u tablist AjPList PD Help text list being built PX RT void RD RX // static void acdHelpAssocTable(const AcdPAcd thys, AjPList tablist) { AcdPTableItem item; AcdPQual quals; ajint i; AcdPAcd pa; if(!acdDoTable) return; acdLog("++ acdHelpAssocTable %S\n", thys->Name); if(thys->Level == ACD_APPL) { quals = acdQualAppl; } else { AJNEW0(item); ajFmtPrintS(&item->Title, "\"-%S\" associated %s qualifiers\n", thys->Name,acdType[thys->Type].Name); ajListPushAppend(tablist, item); quals = acdType[thys->Type].Quals; } acdLog("++ type %d quals %x\n", thys->Type, quals); if(quals) { i=0; for(pa=thys->AssocQuals; pa && pa->Assoc; pa=pa->Next) { acdLog("++ assoc[%d].Name %s\n", i, quals[i].Name); AJNEW0(item); if(thys->PNum) ajFmtPrintS(&item->Qual, " -%s%d
-%s_%S", quals[i].Name, pa->PNum, quals[i].Name, thys->Name); else ajFmtPrintS(&item->Qual, " -%s", quals[i].Name); ajStrAssignC(&item->Type, quals[i].Type); ajStrAssignC(&item->Help, quals[i].Help); acdHelpValid(pa, ajTrue, &item->Valid); acdHelpExpect(pa, ajTrue, &item->Expect); ajListPushAppend(tablist, item); i++; } } return; } ID acdHelpTable TY static MO ajacd LB acd XX DE Appends a qualifier and its help text to the table list. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA u tablist AjPList PD Help text list being built PX RT void RD RX // static void acdHelpTable(const AcdPAcd thys, AjPList tablist) { AcdPTableItem item; static AjPStr nostr = NULL; static AjPStr nullstr = NULL; static AjPStr type = NULL; AjBool boolval; AjPStr defstr; if(!acdDoTable) return; AJNEW0(item); if(!nullstr) nullstr = ajStrNew(); if(thys->DefStr) defstr = thys->OrigStr; else defstr = nullstr; ajStrAssignClear(&nostr); if(acdIsQtype(thys) && (ajCharMatchC("boolean", acdType[thys->Type].Name) || ajCharMatchC("toggle", acdType[thys->Type].Name) )) { if(ajStrToBool(defstr, &boolval)) { if(boolval) ajStrAssignC(&nostr, "[no]"); ajFmtPrintS(&item->Expect, "%B", boolval); } else if(!ajStrGetLen(defstr)) ajFmtPrintS(&item->Expect, "%B", ajFalse); defstr = nullstr; } if(thys->Level == ACD_PARAM) ajFmtPrintS(&item->Qual, "[-%S%S]
(Parameter %d)", nostr, thys->Name, thys->PNum); else ajFmtPrintS(&item->Qual, "-%S%S", nostr, thys->Name); ajStrAssignC(&type, acdType[thys->Type].Name); acdHelpExpect(thys, ajTrue, &item->Expect); /* ** warning - don't try acdVarResolve here because we have not yet ** read in the data and things like calculated attributes do not exist */ ajStrAssignC(&item->Type, acdType[thys->Type].Name); acdHelpValid(thys, ajTrue, &item->Valid); acdHelpText(thys, &item->Help); ajListPushAppend(tablist, item); return; } ID acdHelpXsd TY static MO ajacd LB acd XX DE Appends a qualifier and its help text to the XSD list. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA u tablist AjPList PD Xsd list being built PX RT void RD RX // static void acdHelpXsd(const AcdPAcd thys, AjPList tablist) { AcdPXsdItem item; static AjPStr nostr = NULL; static AjPStr nullstr = NULL; AjBool boolval; AjBool tmpBool; AjPStr helpStr = NULL; AjPStr defstr = NULL; AjPStr* def = NULL; if(!acdDoXsd) return; /* skip associated qualifiers: ** handled separatedly in XSD for types that use them ** Note: this also excludes application associated general qualifiers ** -auto -verbose -filter and so on */ if(thys->Assoc) return; AJNEW0(item); if(!nullstr) nullstr = ajStrNew(); if(thys->DefStr) defstr = thys->OrigStr; else defstr = nullstr; ajStrAssignClear(&nostr); if(acdIsQtype(thys)) { if((ajCharMatchC("boolean", acdType[thys->Type].Name) || ajCharMatchC("toggle", acdType[thys->Type].Name) )) { if(ajStrToBool(defstr, &boolval)) { if(boolval) ajStrAssignC(&nostr, "no"); ajFmtPrintS(&item->Expect, "%B", boolval); } else if(!ajStrGetLen(defstr)) ajFmtPrintS(&item->Expect, "%B", ajFalse); } def = thys->DefStr; if(def && ajStrGetLen(def[DEF_ADDITIONAL])) { if(acdHelpVarResolve(&helpStr, def[DEF_ADDITIONAL])) { if(!ajStrToBool(helpStr, &tmpBool)) acdErrorAcd(thys, "Bad additional flag %S\n", def[DEF_ADDITIONAL]); } else { tmpBool = ajTrue; } if(tmpBool) item->Optional = ajTrue; } if(def && ajStrGetLen(def[DEF_STANDARD])) { if(acdHelpVarResolve(&helpStr, def[DEF_STANDARD])) { if(!ajStrToBool( helpStr, &tmpBool)) acdErrorAcd(thys, "Bad standard flag %S\n", def[DEF_STANDARD]); } else tmpBool = ajTrue; if(tmpBool) item->Required = ajTrue; } } ajStrAssignC(&item->Type, acdType[thys->Type].Name); ajStrAssignS(&item->Qual, thys->Name); acdHelpExpect(thys, ajTrue, &item->Expect); /* ** warning - don't try acdVarResolve here because we have not yet ** read in the data and things like calculated attributes do not exist */ acdHelpValid(thys, ajTrue, &item->Valid); acdHelpText(thys, &item->Annotation); acdAttrToStr(thys, "relation", "", &item->Relation); ajListPushAppend(tablist, item); ajStrDel (&helpStr); return; } ID acdHelpGalaxy TY static MO ajacd LB acd XX DE Appends a qualifier and its help text to the Galaxy list. XX PN [1] PA u thys AcdPAcd PD ACD object, may have prompt set PX PN [2] PA u tablist AjPList PD Galaxy list being built PX RT void RD RX // static void acdHelpGalaxy(AcdPAcd thys, AjPList tablist) { AcdPGalaxyItem item; static AjPStr nostr = NULL; static AjPStr nullstr = NULL; AjBool boolval; AjBool tmpBool; AjPStr helpStr = NULL; const AjPStr prompt = NULL; AjPStr defstr = NULL; AjPStr* def = NULL; ajuint itype; AjPStr galaxyExpectStr = NULL; ajint ipos; ajint cpos; ajint bpos; ajint qpos; if(!acdDoGalaxy) return; /* associated qualifiers:*/ if(thys->Assoc) return; AJNEW0(item); if(!nullstr) nullstr = ajStrNew(); if(thys->DefStr) defstr = thys->OrigStr; else defstr = nullstr; ajStrAssignClear(&nostr); if(acdIsQtype(thys)) { if((ajCharMatchC("boolean", acdType[thys->Type].Name) || ajCharMatchC("toggle", acdType[thys->Type].Name) )) { if(ajStrToBool(defstr, &boolval)) { if(boolval) ajStrAssignC(&item->Expect, "Yes"); else ajStrAssignC(&item->Expect, "No"); } else if(!ajStrGetLen(defstr)) ajFmtPrintS(&item->Expect, "%B", ajFalse); } def = thys->DefStr; if(def && ajStrGetLen(def[DEF_ADDITIONAL])) { if(acdHelpVarResolve(&helpStr, def[DEF_ADDITIONAL])) { if(!ajStrToBool(helpStr, &tmpBool)) acdErrorAcd(thys, "Bad additional flag %S\n", def[DEF_ADDITIONAL]); } else { tmpBool = ajTrue; } if(tmpBool) item->Optional = ajTrue; } if(def && ajStrGetLen(def[DEF_STANDARD])) { if(acdHelpVarResolve(&helpStr, def[DEF_STANDARD])) { if(!ajStrToBool( helpStr, &tmpBool)) acdErrorAcd(thys, "Bad standard flag %S\n", def[DEF_STANDARD]); } else tmpBool = ajTrue; if(tmpBool) item->Required = ajTrue; } } ajStrAssignC(&item->Type, acdType[thys->Type].Name); ajStrAssignS(&item->Qual, thys->Name); acdHelpExpect(thys, ajTrue, &item->Expect); ipos = (ajint) ajStrFindC(item->Expect, " for protein
"); if(ipos >= 0) /* matrix expected value */ { ajStrExchangeCC(&item->Expect, " for DNA", ""); if(acdDoGalaxyProt) { ajStrAssignSubS(&galaxyExpectStr, item->Expect, 0, ipos-1); } else if(acdDoGalaxyNuc) { ajStrAssignSubS(&galaxyExpectStr, item->Expect, ipos+16, -1); } else { ajStrAssignSubS(&galaxyExpectStr, item->Expect, ipos+16, -1); } ajStrTrimWhite(&galaxyExpectStr); ajStrAssignS(&item->Expect, galaxyExpectStr); } ajStrExchangeCC(&item->Expect, " ", ""); ajStrExchangeCC(&item->Expect, " for any sequence type", ""); ajStrExchangeCC(&item->Expect, " for any sequence", ""); ajStrExchangeCC(&item->Expect, "full sequence", ""); if(ajStrFindC(item->Expect, ".end)") >= 0) ajStrAssignC(&item->Expect, "-1"); if(ajStrFindC(item->Expect, ".begin)") >= 0) ajStrAssignC(&item->Expect, "00"); if(ajStrFindC(item->Expect, "@($(acdprotein)") >= 0) { qpos = (ajint) ajStrFindAnyK(item->Expect, '?'); cpos = (ajint) ajStrFindAnyK(item->Expect, ':'); bpos = (ajint) ajStrFindlastK(item->Expect, ')'); if(acdDoGalaxyProt) { ajStrAssignSubS(&galaxyExpectStr, item->Expect, qpos+1, cpos-1); } else if(acdDoGalaxyNuc) { ajStrAssignSubS(&galaxyExpectStr, item->Expect, cpos+1, bpos-1); } else { ajStrAssignSubS(&galaxyExpectStr, item->Expect, cpos+1, bpos-1); } ajStrTrimWhite(&galaxyExpectStr); ajStrAssignS(&item->Expect, galaxyExpectStr); } else if(ajStrFindC(item->Expect, "@(!$(acdprotein)") >= 0) { qpos = (ajint) ajStrFindAnyK(item->Expect, '?'); cpos = (ajint) ajStrFindAnyK(item->Expect, ':'); bpos = (ajint) ajStrFindlastK(item->Expect, ')'); if(acdDoGalaxyProt) { ajStrAssignSubS(&galaxyExpectStr, item->Expect, cpos+1, bpos-1); } else if(acdDoGalaxyNuc) { ajStrAssignSubS(&galaxyExpectStr, item->Expect, qpos+1, cpos-1); } else { ajStrAssignSubS(&galaxyExpectStr, item->Expect, qpos+1, cpos-1); } ajStrTrimWhite(&galaxyExpectStr); ajStrAssignS(&item->Expect, galaxyExpectStr); } prompt = acdAttrValue(thys, "code"); if(!ajStrGetLen(prompt)) prompt = acdAttrValue(thys, "prompt"); if(!ajStrGetLen(prompt)) prompt = acdAttrValue(thys, "information"); if(!ajStrGetLen(prompt)) { for (itype=0; acdType[itype].Name; itype++) if (ajStrMatchC(item->Type, acdType[itype].Name)) break; if(acdType[itype].Prompt) (*acdType[itype].Prompt)(thys); prompt = thys->StdPrompt; } if(!ajStrGetLen(prompt)) prompt = acdAttrValue(thys, "help"); ajStrAssignS(&item->Prompt, prompt); /* ** warning - don't try acdVarResolve here because we have not yet ** read in the data and things like calculated attributes do not exist */ acdHelpValid(thys, ajTrue, &item->Valid); acdHelpText(thys, &item->Annotation); acdAttrToStr(thys, "relation", "", &item->Relation); ajListPushAppend(tablist, item); ajStrDel (&helpStr); return; } ID acdListReport TY static MO ajacd LB acd XX DE Reports the current status of the ACD internal structures, converting DE values to a printable form as appropriate. XX PN [1] PA r title const char* PD Title line for this call PX RT void RD RX // static void acdListReport(const char* title) { AcdPAcd pa; ajint i = 0; ajint j = 0; char underline[256]; if(!acdDoLog) return; j = strlen(title); if(j > 255) j = 255; memset(underline, '=', j); underline[j] = '\0'; acdLog("\n"); acdLog("%s\n", title); acdLog("%s\n", underline); acdLog("\n"); for(pa=acdList; pa; pa=pa->Next) { acdLog("ACD %d\n", i); if(pa->PNum) { acdLog(" Name: '%S[%d]'\n", pa->Name, pa->PNum); acdLog(" Token: '%S[%d]'\n", pa->Token, pa->PNum); } else { acdLog(" Name: '%S'\n", pa->Name); acdLog(" Token: '%S'\n", pa->Token); } acdLog(" Param: %d\n", pa->PNum); acdLog(" Level: %d (%s)\n", pa->Level, acdLevel[pa->Level]); if(acdIsQtype(pa)) acdLog(" Qual Type: %d (%s)\n", pa->Type, acdType[pa->Type].Name); else acdLog(" Key Type: %d (%s)\n", pa->Type, acdKeywords[pa->Type].Name); acdLog(" NAttr: %d\n", pa->NAttr); acdLog(" Assoc: %B\n", pa->Assoc); if(pa->AssocQuals) acdLog(" AssocQuals: %S\n", pa->AssocQuals->Name); else acdLog(" AssocQuals: \n"); acdLog(" Defined: %B\n", pa->Defined); acdLog(" Userdefined: %B\n", pa->UserDefined); acdLog("Orig. Value: '%S'\n", pa->OrigStr); if(pa->ValStr) acdLog(" Value: '%S'\n", pa->ValStr); else acdLog(" Value: \n"); acdLog("\n"); if(pa->DefStr) { acdLog(" Default Attributes:\n"); acdListAttr(acdAttrDef, pa->DefStr, nDefAttr); acdLog("\n"); } acdLog(" Attributes:\n"); if(acdIsQtype(pa)) acdListAttr(acdType[pa->Type].Attr, pa->AttrStr, pa->NAttr); else acdListAttr(acdKeywords[pa->Type].Attr, pa->AttrStr, pa->NAttr); acdLog("\n"); i++; } return; } ID acdListAttr TY static MO ajacd LB acd XX DE Reports all attributes for an ACD attribute list. XX PN [1] PA r attr const AcdPAttr PD Attribute list PX PN [2] PA r valstr const AjPPStr PD Array of string attribute values PX PN [3] PA r nattr ajint PD Number of attributes in list PX RT void RD RX // static void acdListAttr(const AcdPAttr attr, const AjPPStr valstr, ajint nattr) { ajint i; if(!valstr) return; for(i=0; i < nattr; i++) { if(valstr[i]) acdLog(" %15.15s: '%S'\n", attr[i].Name, valstr[i] ); else acdLog(" %15.15s: \n", attr[i].Name); } return; } ID acdSet TY static MO ajacd LB acd XX DE Sets an attribute or associated qualifier value for an ACD item. DE DE All attributes, of whatever type, are treated as strings at this stage. XX PN [1] PA r thys const AcdPAcd PD ACD item. PX PN [2] PA u attrib AjPStr* PD Attribute name - converted to full name PX PN [3] PA r value const AjPStr PD Attribute value PX RT AjBool RD ajTrue if attribute is valid. RX // static AjBool acdSet(const AcdPAcd thys, AjPStr* attrib, const AjPStr value) { ajint iattr = -1; ajint idef = -1; AcdPAttr attr = acdType[thys->Type].Attr; AjPStr *attrstr = thys->AttrStr; AcdPAcd aqual; acdLog("acdSet attr '%S' val '%S' type '%S'\n", thys->Name, *attrib, value); /* recursion with associated qualifiers */ aqual = NULL; if(thys->AssocQuals) aqual = acdFindAssoc(thys, *attrib, NULL); iattr = acdFindAttr(attr, *attrib); if(thys->DefStr) /* try again with default attributes */ idef = acdFindAttr(acdAttrDef, *attrib); if(iattr >= 0 && idef >= 0) /* should never happen */ acdErrorAcd(thys, "Duplicate type and default attribute '%S'", *attrib); if(aqual) { if(iattr >= 0) acdErrorAcd(thys, /* no known case */ "'%S' matches attribute '%s' and " "associated qualifier '%S'", *attrib, attr[iattr].Name, aqual->Name); if(idef >= 0) acdErrorAcd(thys, /* no known case */ "'%S' matches default attribute '%s' and " "associated qualifier '%S'", *attrib, acdAttrDef[idef].Name, aqual->Name); } if(iattr >= 0) { ajStrAssignC(attrib, attr[iattr].Name); if(attr[iattr].Multiple) { if(ajStrGetLen(attrstr[iattr])) ajStrAppendK(&attrstr[iattr], '|'); ajStrAppendS(&attrstr[iattr], value); } else { if(acdDoValid && ajStrGetLen(attrstr[iattr])) acdWarn("duplicate attribute '%S'", *attrib); ajStrAssignS(&attrstr[iattr], value); } return ajTrue; } if(idef >= 0) { ajStrAssignC(attrib, acdAttrDef[idef].Name); if(acdAttrDef[idef].Multiple) { if(ajStrGetLen(thys->DefStr[idef])) ajStrAppendK(&thys->DefStr[idef], '|'); ajStrAppendS(&thys->DefStr[idef], value); } else { if(acdDoValid && ajStrGetLen(thys->DefStr[idef])) acdWarn("duplicate attribute '%S'", *attrib); ajStrAssignS(&thys->DefStr[idef], value); } return ajTrue; } if(aqual) return acdDef(aqual, value); /* test: wrongattr.acd */ acdErrorAcd(thys, "Attribute '%S' unknown\n", *attrib ); return ajFalse; } ID acdSetKey TY static MO ajacd LB acd XX DE Sets an attribute for an ACD key item. DE DE All attributes, of whatever type, are treated as strings at this stage. XX PN [1] PA r thys const AcdPAcd PD ACD item. PX PN [2] PA u attrib AjPStr* PD Attribute name, converted to full name PX PN [3] PA r value const AjPStr PD Attribute value PX RT AjBool RD ajTrue if attribute is valid. RX // static AjBool acdSetKey(const AcdPAcd thys, AjPStr* attrib, const AjPStr value) { ajint iattr = -1; AcdPAttr attr = acdKeywords[thys->Type].Attr; AjPStr* attrstr = thys->AttrStr; AcdPAcd aqual; /* recursion with associated qualifiers - e.g.for application */ aqual = NULL; if(thys->AssocQuals) aqual = acdFindAssoc(thys, *attrib, NULL); iattr = acdFindAttr(attr, *attrib); if(aqual) if(iattr >= 0) acdErrorAcd(thys, /* no known case */ "'%S' matches attribute '%s' and qualifier '%S'", *attrib, attr[iattr].Name, aqual->Name); if(iattr >= 0) { ajStrAssignC(attrib, attr[iattr].Name); if(attr[iattr].Multiple) { if(ajStrGetLen(attrstr[iattr])) ajStrAppendK(&attrstr[iattr], '|'); ajStrAppendS(&attrstr[iattr], value); } else { if(acdDoValid && ajStrGetLen(attrstr[iattr])) acdWarn("duplicate attribute '%S'", *attrib); ajStrAssignS(&attrstr[iattr], value); } return ajTrue; } if(aqual) return acdDef(aqual, value); /* test: wrongattr.acd */ acdErrorAcd(thys, "Attribute '%S' unknown\n", *attrib ); return ajFalse; } ID acdDef TY static MO ajacd LB acd XX DE Sets the default value for an ACD item, and flags in thys as Defined. XX PN [1] PA u thys AcdPAcd PD ACD item PX PN [2] PA r value const AjPStr PD Default value PX RT AjBool RD ajTrue always. RX // static AjBool acdDef(AcdPAcd thys, const AjPStr value) { AjPStr* attrstr = thys->DefStr; acdLog("acdDef %S '%S' %x\n", thys->Name, value, attrstr); acdSetDef(thys, value); thys->Defined = ajTrue; return ajTrue; } ID acdSetDef TY static MO ajacd LB acd XX DE Sets the default value for an ACD item. XX PN [1] PA u thys AcdPAcd PD ACD item PX PN [2] PA r value const AjPStr PD Default value PX RT AjBool RD ajTrue always. RX // static AjBool acdSetDef(AcdPAcd thys, const AjPStr value) { AjPStr* attrstr = thys->DefStr; acdLog("acdSetDef %S '%S' %x\n", thys->Name, value, attrstr); if(!thys->DefStr) return ajFalse; ajStrAssignS(&attrstr[DEF_DEFAULT], value); return ajTrue; } ID acdSetDefC TY static MO ajacd LB acd XX DE Sets the default value for an ACD item. XX PN [1] PA u thys AcdPAcd PD ACD item PX PN [2] PA r value const char* PD Default value PX RT AjBool RD ajTrue always. RX // static AjBool acdSetDefC(AcdPAcd thys, const char* value) { AjPStr *attrstr = thys->DefStr; acdLog("acdSetDefC %S '%s' %x\n", thys->Name, value, attrstr); if(!thys->DefStr) return ajFalse; ajStrAssignC(&attrstr[DEF_DEFAULT], value); return ajTrue; } ID acdSetQualDefBool TY static MO ajacd LB acd XX DE Sets the default value for an ACD item or one of its associated qualifiers XX PN [1] PA u thys AcdPAcd PD ACD item PX PN [2] PA r name const char* PD Qualifier name PX PN [3] PA r value AjBool PD Default value PX RT AjBool RD ajTrue always. RX // static AjBool acdSetQualDefBool(AcdPAcd thys, const char* name, AjBool value) { AjPStr *attrstr; AjPStr qname = NULL; AcdPAcd acd; ajStrAssignC(&qname, name); acd = acdFindQualAssoc(thys, qname, NULL, NULL, 0); ajStrDel(&qname); if(!acd) return ajFalse; attrstr = acd->DefStr; acdLog("acdSetQualDefBool %S [%d] '%s' %B\n", thys->Name, thys->PNum, name, value); if(!thys->DefStr) return ajFalse; ajFmtPrintS(&attrstr[DEF_DEFAULT], "%b", value); return ajTrue; } ID acdSetQualDefInt TY static MO ajacd LB acd XX DE Sets the default value for an ACD item or one of its associated qualifiers XX PN [1] PA u thys AcdPAcd PD ACD item PX PN [2] PA r name const char* PD Qualifier name PX PN [3] PA r value ajint PD Default value PX RT AjBool RD ajTrue always. RX // static AjBool acdSetQualDefInt(AcdPAcd thys, const char* name, ajint value) { AjPStr *attrstr; AjPStr qname = NULL; AcdPAcd acd; ajStrAssignC(&qname, name); acd = acdFindQualAssoc(thys, qname, NULL, NULL, 0); if(!acd) return ajFalse; attrstr = acd->DefStr; acdLog("acdSetQualDefInt %S [%d] '%s' %S [%d] %d\n", thys->Name, thys->PNum, name, acd->Name, acd->PNum, value); if(!thys->DefStr) return ajFalse; ajFmtPrintS(&attrstr[DEF_DEFAULT], "%d", value); ajStrDel(&qname); return ajTrue; } ID acdSetVarDef TY static MO ajacd LB acd XX DE Sets the default value for a variable ACD item. XX PN [1] PA u thys AcdPAcd PD ACD item PX PN [2] PA r value const AjPStr PD Default value PX RT AjBool RD ajTrue always. RX // static AjBool acdSetVarDef(AcdPAcd thys, const AjPStr value) { acdLog("acdSetVarDef %S '%S' %x\n", thys->Name, value, thys->ValStr); ajStrAssignS(&thys->ValStr, value); return ajTrue; } ID acdFindAttr TY static MO ajacd LB acd XX DE Locates an attribute by name in an attribute list. XX PN [1] PA r attr const AcdPAttr PD Attribute list PX PN [2] PA r attrib const AjPStr PD Attribute name to be found PX RT ajint RD offset in "attr" if found RX // static ajint acdFindAttr(const AcdPAttr attr, const AjPStr attrib) { static ajint i; static ajint j; ajint ifound = 0; AjPStr ambigList = NULL; ambigList = ajStrNew(); for(i=0; attr[i].Name; i++) { if(ajStrMatchC(attrib, attr[i].Name)) { ajStrDel(&ambigList); return i; } if(ajCharPrefixS(attr[i].Name, attrib)) { ifound++; j = i; acdAmbigAppC(&ambigList, attr[i].Name); } } if(ifound == 1) { if (acdDoValid) acdWarn("Abbreviated attribute '%S' (%S)", attrib, ambigList); ajStrDel(&ambigList); return j; } if(ifound > 1) { ajWarn("Ambiguous attribute %S (%S)", attrib, ambigList); } ajStrDel(&ambigList); return -1; } ID acdFindAttrC TY static MO ajacd LB acd XX DE Locates an attribute by name in an attribute list. XX PN [1] PA r attr const AcdPAttr PD Attribute list PX PN [2] PA r attrib const char* PD Attribute name to be found PX RT ajint RD offset in "attr" if found RX // static ajint acdFindAttrC(const AcdPAttr attr, const char* attrib) { static ajint i; static ajint j; ajint k; ajint ifound = 0; AjPStr ambigList = NULL; k = strlen(attrib); ambigList = ajStrNew(); for(i=0; attr[i].Name; i++) if(!strncmp(attr[i].Name, attrib, k)) { if(!strcmp(attr[i].Name, attrib)) { ajStrDel(&ambigList); return i; } ifound++; j = i; acdAmbigAppC(&ambigList, attr[i].Name); } if(ifound == 1) { if (acdDoValid) acdWarn("Abbreviated attribute '%s', %S", attrib, ambigList); ajStrDel(&ambigList); return j; } if(ifound > 1) { ajWarn("ambiguous attribute %s (%S)", attrib, ambigList); } ajStrDel(&ambigList); return -1; } ID acdProcess TY static MO ajacd LB acd XX DE Steps through all the ACD items, filling in missing information. DE Parameters are defined in the default attributes. The parameter DE number is generated here in the order they are found. DE DE Associated qualifiers (if any) also get a copy of the parameter number. XX RT void RD RX // static void acdProcess(void) { AcdPAcd pa; AcdPAcd qa = NULL; AjPStr reqstr = NULL; AjPStr yesstr = NULL; AjBool isreq; AjBool isparam; if(!reqstr) { ajStrAssignC(&reqstr, "standard"); ajStrAssignC(&yesstr, "Y"); } for(acdProcCurr=acdList; acdProcCurr; acdProcCurr=acdProcCurr->Next) { pa = acdProcCurr; if(pa->DefStr) ajStrAssignS(&pa->OrigStr, pa->DefStr[DEF_DEFAULT]); acdLog("acdProcess '%S' defstr '%x' test parameter\n", pa->Name, pa->DefStr); if(!pa->Assoc && pa->DefStr && acdAttrToBoolTest(pa, "parameter", ajFalse, &isparam)) { if(isparam) { acdNParam++; pa->PNum = acdNParam; pa->Level = ACD_PARAM; acdLog("acdProcess '%S' required\n", pa->Name); /* no unresolvable variables */ if(!(acdVarTest(acdAttrValue(pa, "standard")))) if(!(acdAttrToBool(pa, "standard", ajFalse, &isreq))) { acdSet(pa, &reqstr, yesstr); } qa = pa->AssocQuals; if(qa) while(qa->Assoc) { qa->PNum = acdNParam; qa = qa->Next; } } } } ajStrDel(&reqstr); ajStrDel(&yesstr); return; } ID acdSetAll TY static MO ajacd LB acd XX DE Steps through all the ACD items, calling the acdSet... function DE for each in turn to prompt the user for any missing values and DE to check that all is OK. XX RT void RD RX // static void acdSetAll(void) { AcdPAcd pa; AjBool isstd; AjBool isadd; const char* stdstring = "std"; const char* addstring = "opt"; const char* advstring = " "; const char* nostring = " "; const char* level = NULL; ajint iendsec = 0; if (acdDoTrace) { iendsec = acdFindKeyC("endsection"); ajUserDumpC("Trace:"); ajUserDumpC("Trace: Line Std ACD_Type Name and 'value'"); ajUserDumpC("Trace: ---- --- --------------- ----------------"); } for(acdSetCurr=acdList; acdSetCurr; acdSetCurr = acdSetCurr->Next) { pa = acdSetCurr; if(!pa->Assoc) acdMasterQual = pa; if(!acdIsStype(pa)) { if (acdIsQtype(pa)) (*acdType[pa->Type].TypeSet)(pa); else (*acdKeywords[pa->Type].KeySet)(pa); } if (acdDoTrace) { if(acdIsQtype(pa)) { acdAttrToBool(pa, "standard", ajFalse, &isstd); acdAttrToBool(pa, "parameter", isstd, &isstd); acdAttrToBool(pa, "additional", ajFalse, &isadd); if (isstd) level = stdstring; else if (isadd) level = addstring; else level = advstring; if (pa->Assoc) continue; else ajUser("Trace: %4d %s %15s: %15S '%S'", pa->LineNum, level, acdType[pa->Type].Name, pa->Name, pa->ValStr); } else if(acdIsStype(pa)) { ajUser("Trace: %4d %s %15s: %15S", pa->LineNum, level, acdKeywords[pa->Type].Name, pa->Name); if (pa->Type == iendsec) ajUserDumpC("Trace:"); } else { ajUser("Trace: %4d %s %15s: %15S '%S'", pa->LineNum, nostring, acdKeywords[pa->Type].Name, pa->Name, pa->ValStr); } } } return; } ID acdQualToBool TY static MO ajacd LB acd XX DE Converts an associated qualifier value into a boolean. DE Any variable references are resolved at this stage. XX PN [1] PA r thys const AcdPAcd PD ACD item of master parameter or qualifier. PX PN [2] PA r qual const char* PD Qualifier name PX PN [3] PA r defval AjBool PD default value PX PN [4] PA w result AjBool* PD Resulting value. PX PN [5] PA w valstr AjPStr* PD Resulting value as a string PX RT AjBool RD ajTrue on success RX // static AjBool acdQualToBool(const AcdPAcd thys, const char *qual, AjBool defval, AjBool *result, AjPStr* valstr) { AjBool ret; ret = acdGetValueAssoc(thys, qual, valstr); acdLog("acdQualToBool item: %S qual: %s defval: %B str: '%S', ret: %B\n", thys->Name, qual, defval, *valstr, ret); if(ret) { acdVarResolve(valstr); acdLog("resolved to: '%S'\n", *valstr); if(ajStrGetLen(*valstr)) { if(!ajStrToBool(*valstr, result)) { acdErrorAcd(thys, "Bad associated qualifier " "boolean value -%s = %S\n", thys->Name , qual, *valstr) ; } return ajTrue; } } *result = defval; ajFmtPrintS(valstr, "%b", defval); return ajFalse; } ID acdQualToFloat TY static MO ajacd LB acd XX DE Converts an associated qualifier value into a floating point number. DE Any variable references are resolved at this stage. XX PN [1] PA r thys const AcdPAcd PD ACD item of master parameter or qualifier. PX PN [2] PA r qual const char* PD Qualifier name PX PN [3] PA r defval float PD default value PX PN [4] PA r precision ajint PD floating point precision PX PN [5] PA w result float* PD Resulting value. PX PN [6] PA w valstr AjPStr* PD Resulting value as a string PX RT AjBool RD ajTrue on success RX // static AjBool acdQualToFloat(const AcdPAcd thys, const char *qual, float defval, ajint precision, float *result, AjPStr* valstr) { AjBool ret; ret = acdGetValueAssoc(thys, qual, valstr); acdLog("acdQualToFloat item: %S qual: %s defval: %.3f " "str: '%S' ret: %B\n", thys->Name, qual, defval, *valstr, ret); if(ret) { acdVarResolve(valstr); acdLog("resolved to: '%S'\n", *valstr); if(ajStrGetLen(*valstr)) { if(!ajStrToFloat(*valstr, result)) { acdErrorAcd(thys, "%S: Bad associated qualifier " "float value -%s = %S\n", qual, *valstr) ; } return ajTrue; } } *result = defval; ajStrFromFloat(valstr, defval, precision); return ajFalse; } ID acdQualToInt TY static MO ajacd LB acd XX DE Converts an associated qualifier value into an integer. DE Any variable references are resolved at this stage. XX PN [1] PA r thys const AcdPAcd PD ACD item of master parameter or qualifier. PX PN [2] PA r qual const char* PD Qualifier name PX PN [3] PA r defval ajint PD default value PX PN [4] PA w result ajint* PD Resulting value. PX PN [5] PA w valstr AjPStr* PD Qualifier value as a string PX RT AjBool RD ajTrue on success RX // static AjBool acdQualToInt(const AcdPAcd thys, const char *qual, ajint defval, ajint *result, AjPStr* valstr) { AjBool ret; ret = acdGetValueAssoc(thys, qual, valstr); acdLog("acdQualToInt item: %S qual: %s defval: %d str: '%S' ret: %B\n", thys->Name, qual, defval, *valstr, ret); if(ret) { acdVarResolve(valstr); acdLog("resolved to: '%S'\n", *valstr); if(ajStrGetLen(*valstr)) { if(ajStrMatchC(*valstr, "default")) ajStrAssignC(valstr, "0"); if(!ajStrToInt(*valstr, result)) acdErrorAcd(thys, "%S: Bad associated qualifier " "integer value -%s = %S\n", qual, *valstr); return ajTrue; } } *result = defval; ajStrFromInt(valstr, defval); return ajFalse; } ID acdQualToLong TY static MO ajacd LB acd XX DE Converts an associated qualifier value into a long integer. DE Any variable references are resolved at this stage. XX PN [1] PA r thys const AcdPAcd PD ACD item of master parameter or qualifier. PX PN [2] PA r qual const char* PD Qualifier name PX PN [3] PA r defval ajlong PD default value PX PN [4] PA w result ajlong* PD Resulting value. PX PN [5] PA w valstr AjPStr* PD Qualifier value as a string PX RT AjBool RD ajTrue on success RX // static AjBool acdQualToLong(const AcdPAcd thys, const char *qual, ajlong defval, ajlong *result, AjPStr* valstr) { AjBool ret; ret = acdGetValueAssoc(thys, qual, valstr); acdLog("acdQualToLong item: %S qual: %s defval: %Ld str: '%S' ret: %B\n", thys->Name, qual, defval, *valstr, ret); if(ret) { acdVarResolve(valstr); acdLog("resolved to: '%S'\n", *valstr); if(ajStrGetLen(*valstr)) { if(ajStrMatchC(*valstr, "default")) ajStrAssignC(valstr, "0"); if(!ajStrToLong(*valstr, result)) acdErrorAcd(thys, "%S: Bad associated qualifier " "long integer value -%s = %S\n", qual, *valstr); return ajTrue; } } *result = defval; ajStrFromLong(valstr, defval); return ajFalse; } ID acdQualToSeqbegin TY static MO ajacd LB acd XX DE Converts an associated qualifier value into an integer, or the DE string "start". DE DE Any variable references are resolved at this stage. XX PN [1] PA r thys const AcdPAcd PD ACD item of master parameter or qualifier. PX PN [2] PA r qual const char* PD Qualifier name PX PN [3] PA r defval ajint PD default value PX PN [4] PA w result ajint* PD Resulting value. PX PN [5] PA w valstr AjPStr* PD Qualifier value as a string PX RT AjBool RD ajTrue on success RX // static AjBool acdQualToSeqbegin(const AcdPAcd thys, const char *qual, ajint defval, ajint *result, AjPStr* valstr) { AjBool ret; ret = acdGetValueAssoc(thys, qual, valstr); acdLog("acdQualToSeqpos item: %S qual: %s defval: %d str: '%S' ret: %B\n", thys->Name, qual, defval, *valstr, ret); if(ret) { acdVarResolve(valstr); acdLog("resolved to: '%S'\n", *valstr); if(ajStrGetLen(*valstr)) { if(!ajStrMatchCaseC(*valstr, "default")) if(!ajStrToInt(*valstr, result)) { acdErrorAcd(thys, "Bad associated qualifier " "integer value -%s = %S\n", qual, *valstr); } acdLog("return value %B '%S'\n", ajTrue, *valstr); return ajTrue; } } *result = defval; if(!defval) ajStrAssignC(valstr, "start"); else ajStrFromInt(valstr, defval); acdLog("return default %B '%S'\n", ajFalse, *valstr); return ajFalse; } ID acdQualToSeqend TY static MO ajacd LB acd XX DE Converts an associated qualifier value into an integer, or the DE string "end". DE DE Any variable references are resolved at this stage. XX PN [1] PA r thys const AcdPAcd PD ACD item of master parameter or qualifier. PX PN [2] PA r qual const char* PD Qualifier name PX PN [3] PA r defval ajint PD default value PX PN [4] PA w result ajint* PD Resulting value. PX PN [5] PA w valstr AjPStr* PD Qualifier value as a string PX RT AjBool RD ajTrue on success RX // static AjBool acdQualToSeqend(const AcdPAcd thys, const char *qual, ajint defval, ajint *result, AjPStr* valstr) { AjBool ret; ret = acdGetValueAssoc(thys, qual, valstr); acdLog("acdQualToSeqpos item: %S qual: %s defval: %d str: '%S' ret: %B\n", thys->Name, qual, defval, *valstr, ret); if(ret) { acdVarResolve(valstr); acdLog("resolved to: '%S'\n", *valstr); if(ajStrGetLen(*valstr)) { if(!ajStrMatchCaseC(*valstr, "default")) if(!ajStrToInt(*valstr, result)) { acdErrorAcd(thys, "Bad associated qualifier " "integer value -%s = %S\n", qual, *valstr); } acdLog("return value %B '%S'\n", ajTrue, *valstr); return ajTrue; } } *result = defval; if(!defval) ajStrAssignC(valstr, "end"); else ajStrFromInt(valstr, defval); acdLog("return default %B '%S'\n", ajFalse, *valstr); return ajFalse; } ID acdAttrToBoolTest TY static MO ajacd LB acd XX DE Resolves and tests an attribute string. If it has a boolean value, returns DE true and sets the value. Otherwise returns false and the default value. DE DE Has to take care to test for variables, as their values are not yet DE set when this is called. XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval AjBool PD Default value PX PN [4] PA w result AjBool* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToBoolTest(const AcdPAcd thys, const char *attr, AjBool defval, AjBool *result) { if(acdVarTest(acdAttrValue(thys, attr))) /* test calcparam.acd */ acdErrorAcd(thys, "'%s' attribute cannot use a variable. " "It is used to define " "the command line before values have been set", attr); return acdAttrToBool(thys, attr, defval, result); } ID acdAttrToBool TY static MO ajacd LB acd XX DE Resolves and tests an attribute string. If it has a boolean value, returns DE true and sets the value. Otherwise returns false and the default value. XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval AjBool PD Default value PX PN [4] PA w result AjBool* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToBool(const AcdPAcd thys, const char *attr, AjBool defval, AjBool *result) { ajint i; acdAttrResolve(thys, attr, &acdAttrValTmp); if(ajStrGetLen(acdAttrValTmp)) { if(ajStrToBool(acdAttrValTmp, result)) { ajStrDelStatic(&acdAttrValTmp); return ajTrue; } if(ajStrToInt(acdAttrValTmp, &i)) { if(i) *result = ajTrue; else *result = ajFalse; ajStrDelStatic(&acdAttrValTmp); return ajTrue; } else { acdErrorAcd(thys, "%S: Bad attribute boolean value %s = %S\n", thys->Name, attr, acdAttrValTmp); } } *result = defval; ajStrDelStatic(&acdAttrValTmp); return ajFalse; } ID acdAttrToDouble TY static MO ajacd LB acd XX DE Resolves and tests an attribute string. If it has a float value, returns DE true and sets the value. Otherwise returns false and the default value. XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval double PD Default value PX PN [4] PA w result double* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToDouble(const AcdPAcd thys, const char *attr, double defval, double *result) { acdAttrResolve(thys, attr, &acdAttrValTmp); if(ajStrGetLen(acdAttrValTmp)) { if(ajStrToDouble(acdAttrValTmp, result)) { ajStrDelStatic(&acdAttrValTmp); return ajTrue; } else { acdErrorAcd(thys, "Bad attribute double value %s = %S\n", attr, acdAttrValTmp); } } *result = defval; ajStrDelStatic(&acdAttrValTmp); return ajFalse; } ID acdAttrToFloat TY static MO ajacd LB acd XX DE Resolves and tests an attribute string. If it has a float value, returns DE true and sets the value. Otherwise returns false and the default value. XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval float PD Default value PX PN [4] PA w result float* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToFloat(const AcdPAcd thys, const char *attr, float defval, float *result) { acdAttrResolve(thys, attr, &acdAttrValTmp); if(ajStrGetLen(acdAttrValTmp)) { if(ajStrToFloat(acdAttrValTmp, result)) { ajStrDelStatic(&acdAttrValTmp); return ajTrue; } else { acdErrorAcd(thys, "Bad attribute float value %s = %S\n", attr, acdAttrValTmp); } } *result = defval; ajStrDelStatic(&acdAttrValTmp); return ajFalse; } ID acdAttrToInt TY static MO ajacd LB acd XX DE Resolves and tests an attribute string. If it has an integer value, returns DE true and sets the value. Otherwise returns false and the default value. XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval ajint PD Default value PX PN [4] PA w result ajint* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToInt(const AcdPAcd thys, const char *attr, ajint defval, ajint *result) { acdAttrResolve(thys, attr, &acdAttrValTmp); if(ajStrGetLen(acdAttrValTmp)) { if(ajStrToInt(acdAttrValTmp, result)) { ajStrDelStatic(&acdAttrValTmp); return ajTrue; } else acdErrorAcd(thys, "Bad attribute integer value %s = %S\n", attr, acdAttrValTmp); } *result = defval; ajStrDelStatic(&acdAttrValTmp); return ajFalse; } ID acdAttrToLong TY static MO ajacd LB acd XX DE Resolves and tests an attribute string. If it has an integer value, returns DE true and sets the value. Otherwise returns false and the default value. XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval ajlong PD Default value PX PN [4] PA w result ajlong* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToLong(const AcdPAcd thys, const char *attr, ajlong defval, ajlong *result) { acdAttrResolve(thys, attr, &acdAttrValTmp); if(ajStrGetLen(acdAttrValTmp)) { if(ajStrToLong(acdAttrValTmp, result)) { ajStrDelStatic(&acdAttrValTmp); return ajTrue; } else acdErrorAcd(thys, "Bad attribute long integer value %s = %S\n", attr, acdAttrValTmp); } *result = defval; ajStrDelStatic(&acdAttrValTmp); return ajFalse; } ID acdAttrToStr TY static MO ajacd LB acd XX DE Resolves an attribute to a string with translation of variable name(s). XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval const char* PD Default value PX PN [4] PA w result AjPStr* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToStr(const AcdPAcd thys, const char *attr, const char* defval, AjPStr *result) { if(acdAttrResolve(thys, attr, result)) return ajTrue; ajStrAssignC(result, defval); return ajFalse; } ID acdAttrToChar TY static MO ajacd LB acd XX DE Resolves an attribute to a character with translation of variable name(s). XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval char PD Default value PX PN [4] PA w result char* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToChar(const AcdPAcd thys, const char *attr, char defval, char* result) { static AjPStr str = NULL; acdAttrResolve(thys, attr, &str); if(ajStrGetLen(str)) { *result = ajStrGetCharFirst(str); return ajTrue; } *result = defval; return ajFalse; } ID acdAttrToUint TY static MO ajacd LB acd XX DE Resolves and tests an attribute string. If it has an integer value, returns DE true and sets the value. Otherwise returns false and the default value. XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA r defval ajuint PD Default value PX PN [4] PA w result ajuint* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, ajFalse if the RD default value was used. RX // static AjBool acdAttrToUint(const AcdPAcd thys, const char *attr, ajuint defval, ajuint *result) { acdAttrResolve(thys, attr, &acdAttrValTmp); if(ajStrGetLen(acdAttrValTmp)) { if(ajStrToUint(acdAttrValTmp, result)) { ajStrDelStatic(&acdAttrValTmp); return ajTrue; } else acdErrorAcd(thys, "Bad attribute unsigned integer value %s = %S\n", attr, acdAttrValTmp); } *result = defval; ajStrDelStatic(&acdAttrValTmp); return ajFalse; } ID acdAttrResolve TY static MO ajacd LB acd XX DE Resolves an attribute to a string with translation of variable name(s). XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attr const char* PD Attribute name PX PN [3] PA w result AjPStr* PD Resulting value. PX RT AjBool RD ajTrue if a value was defined, RD ajFalse if an empty string is returned. RX // static AjBool acdAttrResolve(const AcdPAcd thys, const char *attr, AjPStr *result) { ajStrAssignS(result, acdAttrValue(thys, attr)); acdVarResolve(result); if(ajStrGetLen(*result)) return ajTrue; return ajFalse; } ID acdVarTest TY static MO ajacd LB acd XX DE tests for any variable (but not function) references in a string. DE DE Used to check whether variables might be used before we have set DE their values.. XX PN [1] PA r var const AjPStr PD String value PX RT AjBool RD ajTrue if a variable was found RX // static AjBool acdVarTest(const AjPStr var) { if(!acdRegVarInit) acdRegVarDefine(); if(ajRegExec(acdRegVarname, var)) return ajTrue; return ajFalse; } ID acdVarTestValid TY static MO ajacd LB acd XX DE Tests for any variable (but not function) references in a string. DE DE Used by acdvalid to check for dependencies that are too complex XX PN [1] PA r var const AjPStr PD String value PX PN [2] PA w toggle AjBool* PD ajTrue if the value is a simple true or false PD test of a toggle variable PX RT AjBool RD ajTrue if a variable was found RX // static AjBool acdVarTestValid(const AjPStr var, AjBool* toggle) { AjPStr varref = NULL; AjPStr varname = NULL; AcdPAcd acd = NULL; if(!acdRegVarInit) acdRegVarDefine(); *toggle = ajFalse; if(!ajRegExec(acdRegVarname, var)) return ajFalse; /* ** A variable - is it a simple (toggle) dependency? ** Toggles can be $(varname) or \@($(varname)) or \@(!$(varname)) ** Also allowed is automatic variable acdprotein */ acdLog("acdVarTestValid variable '%S'\n", var); if(ajRegExec(acdRegToggle, var)) { ajRegSubI(acdRegToggle, 2, &varref); /* returns $(varname) */ if(acdVarSimple(varref, &varname)) { acd = acdFindAcd(varname, varname); if (acd) { acdLog("acdVarTestValid varname %S acd %S type %s\n", varname, acd->Name, acdType[acd->Type].Name); if(!strcmp(acdType[acd->Type].Name, "toggle")) *toggle = ajTrue; if(ajStrMatchCaseC(varname, "acdprotein")) *toggle = ajTrue; } else acdLog("acdVarTestValid varname %S not found\n", varname); } acdLog("varname '%S' toggle %B\n", varname, *toggle); ajStrDel(&varref); ajStrDel(&varname); } return ajTrue; } ID acdVarSimple TY static MO ajacd LB acd XX DE Tests a variable reference is non recursive XX PN [1] PA r var const AjPStr PD String value to be tested PX PN [2] PA w varname AjPStr* PD Variable name if found, else unchanged PX RT AjBool RD ajTrue if no further variable or function is found RX // static AjBool acdVarSimple(const AjPStr var, AjPStr* varname) { AjPStr attrname = NULL; AjPStr result = NULL; AjPStr token = NULL; AjPStr newvar = NULL; AjPStr restvar = NULL; AjBool ret = ajTrue; if(!acdRegVarInit) acdRegVarDefine(); if(ajRegExec(acdRegVarname, var)) { ajRegSubI(acdRegVarname, 2, &token); /* variable name */ acdVarSplit(token, varname, &attrname); if(!ajStrGetLen(attrname)) ajStrAssignC(&attrname, "default"); if(!acdGetAttr(&result, *varname, attrname)) { acdLog("acdVarSimple failed to resolve '%S.%S\n", *varname, attrname); ajStrAssignClear(&result); } ajRegSubI(acdRegVarname, 1, &newvar); ajStrAppendS(&newvar, result); if(ajRegPost(acdRegVarname, &restvar)) /* any more? */ ajStrAppendS(&newvar, restvar); acdLog("acdVarSimple name %S resolved to '%S'\n", *varname, newvar); if(ajRegExec(acdRegVarname, newvar)) ret = ajFalse; else if(ajRegExec(acdRegFunction, newvar)) ret = ajFalse; } /* else no variable reference at found */ ajStrDel(&token); ajStrDel(&attrname); ajStrDel(&result); ajStrDel(&newvar); ajStrDel(&restvar); return ret; } ID acdVarSimpleResolve TY static MO ajacd LB acd XX DE Tests a variable reference is a simple copy and resolves XX PN [1] PA r var const AjPStr PD String value to be tested PX PN [2] PA w newvar AjPStr* PD Substituted value if found, else unchanged PX RT AjBool RD ajTrue if no further variable or function is found RX // static AjBool acdVarSimpleResolve(const AjPStr var, AjPStr* newvar) { AjPStr attrname = NULL; AjPStr result = NULL; AjPStr token = NULL; AjPStr varname = NULL; AjPStr restvar = NULL; AjBool ret = ajTrue; AjPStr tmpvar = NULL; if(!acdRegVarInit) acdRegVarDefine(); if(ajRegExec(acdRegVarname, var)) { tmpvar = ajStrNewS(*newvar); ajRegSubI(acdRegVarname, 2, &token); /* variable name */ acdVarSplit(token, &varname, &attrname); if(!ajStrGetLen(attrname)) ajStrAssignC(&attrname, "default"); if(!acdGetAttr(&result, varname, attrname)) { acdLog("acdVarSimpleResolve failed to resolve '%S.%S\n", varname, attrname); if(ajStrMatchC(attrname, "begin")) ajStrAssignC(&result, "0"); else if(ajStrMatchC(attrname, "end")) ajStrAssignC(&result, "0"); else ajStrAssignClear(&result); } ajRegSubI(acdRegVarname, 1, newvar); ajStrAppendS(newvar, result); if(ajRegPost(acdRegVarname, &restvar)) /* any more? */ ajStrAppendS(newvar, restvar); acdLog("acdVarSimpleResolve name %S resolved to '%S'\n", varname, *newvar); if(ajRegExec(acdRegVarname, *newvar)) ret = ajFalse; else if(ajRegExec(acdRegFunction, *newvar)) ret = ajFalse; if(!ret) ajStrAssignS(newvar, tmpvar); ajStrDel(&tmpvar); } /* else no variable reference at found */ ajStrDel(&token); ajStrDel(&attrname); ajStrDel(&result); ajStrDel(&varname); ajStrDel(&restvar); return ret; } ID acdVarResolve TY static MO ajacd LB acd XX DE Resolves any variable or function references in a string. DE DE First resolves variables in the form $(name) or $(name.attribute). DE This cunningly resolves internal () pairs. DE DE Then looks for function references and resolves them. XX PN [1] PA w var AjPStr* PD String value PX RT AjBool RD Always ajTrue so far RX // static AjBool acdVarResolve(AjPStr* var) { AjPStr varname = NULL; AjPStr attrname = NULL; AjPStr result = NULL; AjPStr token = NULL; AjPStr newvar = NULL; AjPStr restvar = NULL; AjPStr savein = NULL; ajint ivar = 0; ajint ifun = 0; if(!acdRegResolveVar) acdRegResolveVar = ajRegCompC("^(.*)\\$\\(([a-zA-Z0-9_.]+)\\)"); if(!acdRegResolveFun) acdRegResolveFun = ajRegCompC("^(.*)\\@\\(([^()]+)\\)"); /* resolve variable references first to resolve internal parentheses */ if(!var) { ajStrAssignClear(var); return ajTrue; } if(!ajStrGetLen(*var)) return ajTrue; ajStrAssignS(&savein, *var); acdLog("acdVarResolve '%S'\n", savein); while(ajRegExec(acdRegResolveVar, *var)) { ivar++; ajRegSubI(acdRegResolveVar, 2, &token); /* variable name */ acdVarSplit(token, &varname, &attrname); if(!acdGetAttr(&result, varname, attrname)) ajStrAssignClear(&result); ajRegSubI(acdRegResolveVar, 1, &newvar); ajStrAppendS(&newvar, result); if(ajRegPost(acdRegResolveVar, &restvar)) /* any more? */ ajStrAppendS(&newvar, restvar); ajStrAssignS(var, newvar); acdLog("... name %S resolved to '%S'\n", varname, newvar); } /* now resolve any function */ while(ajRegExec(acdRegResolveFun, *var)) { ifun++; ajRegSubI(acdRegResolveFun, 2, &token); /* function statement */ acdFunResolve(&result, token); ajRegSubI(acdRegResolveFun, 1, &newvar); ajStrAppendS(&newvar, result); if(ajRegPost(acdRegResolveFun, &restvar)) /* any more? */ ajStrAppendS(&newvar, restvar); ajStrAssignS(var, newvar); acdLog("... function %S resolved to '%S'\n", token, newvar); } if(ivar > 1) acdLog("Recursive variables in '%S'\n", savein); if(ifun > 1) acdLog("Recursive expressions in '%S'\n", savein); if(acdDoTrace) { if(ifun || ivar) ajUser("Trace: resolved '%S' => '%S'", savein, *var); } ajStrDel(&savein); ajStrDel(&result); ajStrDel(&varname); ajStrDel(&newvar); ajStrDel(&restvar); ajStrDel(&token); ajStrDel(&attrname); return ajTrue; } ID acdHelpVarResolve TY static MO ajacd LB acd XX DE Resolves any variable or function references in a string if clearly DE defined, otherwise returns ajFalse and sets the string to "". For DE use with strings that cannot be resolved in help processing DE because of functions, variable dependencies etc. XX PN [1] PA w str AjPStr* PD String value PX PN [2] PA r var const AjPStr PD Source string value PX RT AjBool RD ajTrue if it could be resolved cleanly RX // static AjBool acdHelpVarResolve(AjPStr* str, const AjPStr var) { if(!acdRegVarInit) acdRegVarDefine(); if(!var) { ajStrAssignClear(str); return ajTrue; } /* reject variable references first to resolve internal parentheses */ if(ajRegExec(acdRegVarname, var)) { ajStrAssignClear(str); return ajFalse; } /* reject any function */ if(ajRegExec(acdRegFunction, var)) { ajStrAssignClear(str); return ajFalse; } ajStrAssignS(str, var); return ajTrue; } ID acdFunResolve TY static MO ajacd LB acd XX DE Resolves a function reference. DE DE Has a list of all accepted function syntax. XX PN [1] PA w result AjPStr* PD Result returned PX PN [2] PA r str const AjPStr PD Function statement input PX RT AjBool RD Always ajTrue so far RX // static AjBool acdFunResolve(AjPStr* result, const AjPStr str) { ajint i; acdLog("acdFunResolve '%S'\n", str); for(i = 0; explist[i].Name; i++) { /* Calling funclist acdexplist() */ if((*explist[i].Func)(result, str)) { acdLog("resolved '%S' using '%s'\n", str, explist[i].Name); acdLog(" result '%S'\n", *result); return ajTrue; } } ajWarn("ACD expression invalid @(%S)", str); acdLog("@(%S) *failed**\n", str); ajStrAssignS(result, str); return ajFalse; } ID acdExpPlus TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpPlus(AjPStr* result, const AjPStr str) { ajint ia, ib; double da, db; if(!acdRegExpPlusI) /* ajint + ajint */ acdRegExpPlusI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[+][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpPlusI, str)) { acdLog("acdRegExpPlusI matched '%S'\n", str); ajRegSubI(acdRegExpPlusI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpPlusI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); ajFmtPrintS(result, "%d", ia+ib); acdLog("ia: %d + ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpPlusD) /* float + float */ acdRegExpPlusD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[+][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpPlusD, str)) { acdLog("dexp matched '%S'\n", str); ajRegSubI(acdRegExpPlusD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpPlusD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); ajFmtPrintS(result, "%f", da+db); acdLog("da: %f + db: %f = '%S'\n", da, db, *result); return ajTrue; } return ajFalse; } ID acdExpMinus TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpMinus(AjPStr* result, const AjPStr str) { ajint ia, ib; double da, db; if(!acdRegExpMinusI) /* ajint + ajint */ acdRegExpMinusI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[-][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpMinusI, str)) { acdLog("acdRegExpMinusI matched '%S'\n", str); ajRegSubI(acdRegExpMinusI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpMinusI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); ajFmtPrintS(result, "%d", ia-ib); acdLog("ia: %d - ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpMinusD) /* float + float */ acdRegExpMinusD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[-][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpMinusD, str)) { acdLog("acdRegExpMinusD matched '%S'\n", str); ajRegSubI(acdRegExpMinusD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpMinusD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); ajFmtPrintS(result, "%f", da-db); acdLog("da: %f - db: %f = '%S'\n", da, db, *result); return ajTrue; } return ajFalse; } ID acdExpStar TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpStar(AjPStr* result, const AjPStr str) { ajint ia, ib; double da, db; if(!acdRegExpStarI) /* ajint + ajint */ acdRegExpStarI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[*][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpStarI, str)) { acdLog("acdRegExpStarI matched '%S'\n", str); ajRegSubI(acdRegExpStarI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpStarI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); ajFmtPrintS(result, "%d", ia*ib); acdLog("ia: %d * ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpStarD) /* float + float */ acdRegExpStarD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[*][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpStarD, str)) { acdLog("acdRegExpStarD matched '%S'\n", str); ajRegSubI(acdRegExpStarD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpStarD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); ajFmtPrintS(result, "%f", da*db); acdLog("da: %f * db: %f = '%S'\n", da, db, *result); return ajTrue; } return ajFalse; } ID acdExpDiv TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpDiv(AjPStr* result, const AjPStr str) { ajint ia; ajint ib; double da; double db; if(!acdRegExpDivI) /* ajint + ajint */ acdRegExpDivI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[/][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpDivI, str)) { acdLog("acdRegExpDivI matched '%S'\n", str); ajRegSubI(acdRegExpDivI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpDivI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); ajFmtPrintS(result, "%d", ia/ib); acdLog("ia: %d / ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpDivD) /* float + float */ acdRegExpDivD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[/][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpDivD, str)) { acdLog("acdRegExpDivD matched '%S'\n", str); ajRegSubI(acdRegExpDivD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpDivD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); ajFmtPrintS(result, "%f", da/db); acdLog("da: %f / db: %f = '%S'\n", da, db, *result); return ajTrue; } return ajFalse; } ID acdExpNot TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpNot(AjPStr* result, const AjPStr str) { AjBool ba; if(!acdRegExpNot) /* ajint + ajint */ acdRegExpNot = ajRegCompC("^[ \t]*(!|[Nn][Oo][Tt])" "[ \t]*([A-Za-z0-9]+)[ \t]*$"); if(ajRegExec(acdRegExpNot, str)) { acdLog("nexp matched '%S'\n", str); ajRegSubI(acdRegExpNot, 2, &acdTmpStr); if(!ajStrToBool(acdTmpStr, &ba)) { acdLog("invalid bool value '%S' in acdExpNot\n", acdTmpStr); ba = ajFalse; } if(ba) ajFmtPrintS(result, "%b", ajFalse); else ajFmtPrintS(result, "%b", ajTrue); acdLog("ta: ! '%S' = '%S'\n", acdTmpStr, *result); return ajTrue; } return ajFalse; } ID acdExpEqual TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpEqual(AjPStr* result, const AjPStr str) { ajint ia; ajint ib; double da; double db; if(!acdRegExpEqualI) /* ajint + ajint */ acdRegExpEqualI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[=][=][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpEqualI, str)) { acdLog("acdRegExpEqualI matched '%S'\n", str); ajRegSubI(acdRegExpEqualI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpEqualI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); if(ia == ib) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ia: %d == ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpEqualD) /* float == float */ acdRegExpEqualD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[=][=][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpEqualD, str)) { acdLog("acdRegExpEqualD matched '%S'\n", str); ajRegSubI(acdRegExpEqualD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpEqualD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); if(da == db) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("da: %f == db: %f = '%S'\n", da, db, *result); return ajTrue; } if(!acdRegExpEqualT) /* string == string */ acdRegExpEqualT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[=][=][ \t]*" "([^ \t{}]+)[ \t]*$"); /* for {} see acdExpOneof */ if(ajRegExec(acdRegExpEqualT, str)) { acdLog("acdRegExpEqualT matched '%S'\n", str); ajRegSubI(acdRegExpEqualT, 1, &acdTmpStr); ajRegSubI(acdRegExpEqualT, 2, &acdTmpStr2); if(ajStrMatchCaseS(acdTmpStr, acdTmpStr2)) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ta: '%S' == tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2, *result); return ajTrue; } return ajFalse; } ID acdExpNotEqual TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpNotEqual(AjPStr* result, const AjPStr str) { ajint ia; ajint ib; double da; double db; if(!acdRegExpNeI) /* int != int */ acdRegExpNeI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[!][=][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpNeI, str)) { acdLog("acdRegExpNeI matched '%S'\n", str); ajRegSubI(acdRegExpNeI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpNeI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); if(ia != ib) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ia: %d != ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpNeD) /* float != float */ acdRegExpNeD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[!][=][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpNeD, str)) { acdLog("acdRegExpNeD matched '%S'\n", str); ajRegSubI(acdRegExpNeD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpNeD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); if(da != db) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("da: %f != db: %f = '%S'\n", da, db, *result); return ajTrue; } if(!acdRegExpNeT) /* string != string*/ acdRegExpNeT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[!][=][ \t]*" "([^ \t{}]+)[ \t]*$"); /* for {} see acdExpOneof */ if(ajRegExec(acdRegExpNeT, str)) { acdLog("acdRegExpNeT matched '%S'\n", str); ajRegSubI(acdRegExpNeT, 1, &acdTmpStr); ajRegSubI(acdRegExpNeT, 2, &acdTmpStr2); if(!ajStrMatchCaseS(acdTmpStr, acdTmpStr2)) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ta: '%S' != tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2, *result); return ajTrue; } return ajFalse; } ID acdExpGreater TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpGreater(AjPStr* result, const AjPStr str) { ajint ia; ajint ib; double da; double db; if(!acdRegExpGtI) /* ajint + ajint */ acdRegExpGtI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[>][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpGtI, str)) { acdLog("acdRegExpGtI matched '%S'\n", str); ajRegSubI(acdRegExpGtI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpGtI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); if(ia > ib) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ia: %d > ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpGtD) /* float + float */ acdRegExpGtD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[>][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpGtD, str)) { acdLog("acdRegExpGtD matched '%S'\n", str); ajRegSubI(acdRegExpGtD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpGtD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); if(da > db) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("da: %f > db: %f = '%S'\n", da, db, *result); return ajTrue; } if(!acdRegExpGtT) /* float + float */ acdRegExpGtT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[>][ \t]*" "([^ \t]+)[ \t]*$"); if(ajRegExec(acdRegExpGtT, str)) { acdLog("acdRegExpGtT matched '%S'\n", str); ajRegSubI(acdRegExpGtT, 1, &acdTmpStr); ajRegSubI(acdRegExpGtT, 2, &acdTmpStr2); if(0 > ajStrCmpCaseS(acdTmpStr2, acdTmpStr)) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ta: '%S' > tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2, *result); return ajTrue; } return ajFalse; } ID acdExpLesser TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpLesser(AjPStr* result, const AjPStr str) { ajint ia; ajint ib; double da; double db; if(!acdRegExpLtI) /* ajint + ajint */ acdRegExpLtI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[<][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpLtI, str)) { acdLog("acdRegExpLtI matched '%S'\n", str); ajRegSubI(acdRegExpLtI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpLtI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); if(ia < ib) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ia: %d < ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpLtD) /* float + float */ acdRegExpLtD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[<][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpLtD, str)) { acdLog("acdRegExpLtD matched '%S'\n", str); ajRegSubI(acdRegExpLtD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpLtD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); if(da < db) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("da: %f < db: %f = '%S'\n", da, db, *result); return ajTrue; } if(!acdRegExpLtT) /* float + float */ acdRegExpLtT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[<][ \t]*" "([^ \t]+)[ \t]*$"); if(ajRegExec(acdRegExpLtT, str)) { acdLog("acdRegExpLtT matched '%S'\n", str); ajRegSubI(acdRegExpLtT, 1, &acdTmpStr); ajRegSubI(acdRegExpLtT, 2, &acdTmpStr2); if(0 < ajStrCmpCaseS(acdTmpStr2, acdTmpStr)) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ta: '%S' < tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2, *result); return ajTrue; } return ajFalse; } ID acdExpOr TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpOr(AjPStr* result, const AjPStr str) { ajint ia; ajint ib; double da; double db; AjBool ba; AjBool bb; if(!acdRegExpOrI) /* ajint + ajint */ acdRegExpOrI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[|][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpOrI, str)) { acdLog("acdRegExpOrI matched '%S'\n", str); ajRegSubI(acdRegExpOrI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpOrI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); if(ia || ib) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ia: %d | ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpOrD) /* float + float */ acdRegExpOrD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[|][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpOrD, str)) { acdLog("acdRegExpOrD matched '%S'\n", str); ajRegSubI(acdRegExpOrD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpOrD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); if(da || db) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("da: %f | db: %f = '%S'\n", da, db, *result); return ajTrue; } if(!acdRegExpOrT) /* char + char */ acdRegExpOrT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[|][ \t]*" "([^ \t]+)[ \t]*$"); if(ajRegExec(acdRegExpOrT, str)) { acdLog("acdRegExpOrT matched '%S'\n", str); ajRegSubI(acdRegExpOrT, 1, &acdTmpStr); ajRegSubI(acdRegExpOrT, 2, &acdTmpStr2); ajStrToBool(acdTmpStr2,&ba); ajStrToBool(acdTmpStr, &bb); if( ba || bb ) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ta: '%S' | tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2, *result); return ajTrue; } return ajFalse; } ID acdExpAnd TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpAnd(AjPStr* result, const AjPStr str) { ajint ia; ajint ib; double da; double db; AjBool ba; AjBool bb; if(!acdRegExpAndI) /* ajint + ajint */ acdRegExpAndI = ajRegCompC("^[ \t]*([0-9+-]+)[ \t]*[&][ \t]*" "([0-9+-]+)[ \t]*$"); if(ajRegExec(acdRegExpAndI, str)) { acdLog("acdRegExpAndI matched '%S'\n", str); ajRegSubI(acdRegExpAndI, 1, &acdTmpStr); ajStrToInt(acdTmpStr, &ia); ajRegSubI(acdRegExpAndI, 2, &acdTmpStr); ajStrToInt(acdTmpStr, &ib); if(ia && ib) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ia: %d & ib: %d = '%S'\n", ia, ib, *result); return ajTrue; } if(!acdRegExpAndD) /* float + float */ acdRegExpAndD = ajRegCompC("^[ \t]*([0-9.+-]+)[ \t]*[&][ \t]*" "([0-9.+-]+)[ \t]*$"); if(ajRegExec(acdRegExpAndD, str)) { acdLog("acdRegExpAndD matched '%S'\n", str); ajRegSubI(acdRegExpAndD, 1, &acdTmpStr); ajStrToDouble(acdTmpStr, &da); ajRegSubI(acdRegExpAndD, 2, &acdTmpStr); ajStrToDouble(acdTmpStr, &db); if(da && db) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("da: %f & db: %f = '%S'\n", da, db, *result); return ajTrue; } if(!acdRegExpAndT) /* char + char */ acdRegExpAndT = ajRegCompC("^[ \t]*([^ \t]+)[ \t]*[&][ \t]*" "([^ \t]+)[ \t]*$"); if(ajRegExec(acdRegExpAndT, str)) { acdLog("acdRegExpAndT matched '%S'\n", str); ajRegSubI(acdRegExpAndT, 1, &acdTmpStr); ajRegSubI(acdRegExpAndT, 2, &acdTmpStr2); ajStrToBool(acdTmpStr2,&ba); ajStrToBool(acdTmpStr, &bb); if( ba && bb ) ajFmtPrintS(result, "%b", ajTrue); else ajFmtPrintS(result, "%b", ajFalse); acdLog("ta: '%S' & tb: '%S' = '%S'\n", acdTmpStr, acdTmpStr2, *result); return ajTrue; } return ajFalse; } ID acdExpCond TY static MO ajacd LB acd XX DE Looks for and resolves an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpCond(AjPStr* result, const AjPStr str) { AjBool ba; if(!acdRegExpCond) /* bool ? iftrue : iffalse */ acdRegExpCond = ajRegCompC("^[ \t]*([.A-Za-z0-9+-]*)[ \t]*[?]" "[ \t]*([^: \t]+)[ \t]*[:]" "[ \t]*([^: \t]+)[ \t]*$"); if(ajRegExec(acdRegExpCond, str)) { ajRegSubI(acdRegExpCond, 1, &acdTmpStr); ajStrToBool(acdTmpStr, &ba); if(ba) ajRegSubI(acdRegExpCond, 2, result); else ajRegSubI(acdRegExpCond, 3, result); acdLog("ba: %B = '%S'\n", ba, *result); return ajTrue; } return ajFalse; } ID acdExpOneof TY static MO ajacd LB acd XX DE Looks for and resolves an expression as a test for a list of values DE \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpOneof(AjPStr* result, const AjPStr str) { AjBool todo; AjPStr testvar = NULL; AjPStr notvar = NULL; AjPStr restvar = NULL; AjPStr elsevar = NULL; if(!acdRegExpOneofCase) /* value = ( vala | valb | valc} ) */ acdRegExpOneofCase = ajRegCompC("^[ \t]*([A-Za-z0-9+-]+)[ \t]*" "([!=])[=][ \t]*[{]"); if(!acdRegExpOneofList) /* case : value */ acdRegExpOneofList = ajRegCompC("^[ \t]*([^| \t]+)[ \t]*[|}]"); if(ajRegExec(acdRegExpOneofCase, str)) { ajRegSubI(acdRegExpOneofCase, 1, &testvar); ajRegSubI(acdRegExpOneofCase, 2, ¬var); /* "!" or empty */ if(!ajRegPost(acdRegExpOneofCase, &restvar)) /* any more? */ { ajStrDel(&testvar); ajStrDel(¬var); return ajFalse; } ajStrAssignClear(&elsevar); todo = ajTrue; while(todo && ajRegExec(acdRegExpOneofList, restvar)) { ajRegSubI(acdRegExpOneofList, 1, &acdTmpStr); if(ajStrMatchS(acdTmpStr, testvar)) /* match, but did we want to find it? */ { if (ajStrGetCharFirst(notvar) == '=') ajStrAssignC(result, "Y"); else ajStrAssignC(result, "N"); ajStrDel(&testvar); ajStrDel(¬var); ajStrDel(&elsevar); ajStrDel(&restvar); return ajTrue; } todo = ajRegPost(acdRegExpOneofList, &restvar); } /* no match, but did we not want to find it? */ if (ajStrGetCharFirst(notvar) == '=') ajStrAssignC(result, "N"); else ajStrAssignC(result, "Y"); ajStrDel(&testvar); ajStrDel(¬var); ajStrDel(&elsevar); ajStrDel(&restvar); return ajTrue; } ajStrDel(&testvar); ajStrDel(¬var); ajStrDel(&elsevar); ajStrDel(&restvar); return ajFalse; } ID acdExpCase TY static MO ajacd LB acd XX DE Looks for and resolves an expression as a switch/case statement DE \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpCase(AjPStr* result, const AjPStr str) { ajint ifound; AjBool todo; static AjPStr testvar = NULL; static AjPStr restvar = NULL; static AjPStr elsevar = NULL; if(!acdRegExpCaseCase) /* value = (case : value, ...) */ acdRegExpCaseCase = ajRegCompC("^[ \t]*([A-Za-z0-9+-]+)[ \t]*[=]"); if(!acdRegExpCaseList) /* case : value */ acdRegExpCaseList = ajRegCompC("^[ \t]*([^: \t]+)[ \t]*[:]+" "[ \t]*([^: \t,]+)[ \t,]*"); if(ajRegExec(acdRegExpCaseCase, str)) { ajRegSubI(acdRegExpCaseCase, 1, &testvar); if(!ajRegPost(acdRegExpCaseCase, &restvar)) /* any more? */ { ajStrDel(&testvar); ajStrDel(&elsevar); ajStrDel(&restvar); return ajFalse; } ajStrAssignClear(&elsevar); todo = ajTrue; ifound = 0; while(todo && ajRegExec(acdRegExpCaseList, restvar)) { ajRegSubI(acdRegExpCaseList, 1, &acdTmpStr); if(ajStrMatchC(acdTmpStr, "else")) /* default */ ajRegSubI(acdRegExpCaseList, 2, &elsevar); if(ajStrMatchS(acdTmpStr, testvar)) /* match, take the value */ { ajRegSubI(acdRegExpCaseList, 2, result); acdLog("%S == %S : '%S'\n", testvar, acdTmpStr, *result); ajStrDel(&testvar); ajStrDel(&elsevar); ajStrDel(&restvar); return ajTrue; } if(ajStrPrefixS(testvar, acdTmpStr)) { ifound++; ajRegSubI(acdRegExpCaseList, 2, result); } todo = ajRegPost(acdRegExpCaseList, &restvar); } if(ifound) /* let ambiguous matches through */ { if(ifound > 1) { acdLog("@(=) ambiguous match, last match accepted %S\n", testvar); acdLog("@(=) ambiguous match, last match accepted %S\n", testvar); } acdLog("%S ~= %S : '%S'\n", testvar, acdTmpStr, *result); if (acdDoValid) acdWarn("Ambiguous case expression '%S' (%S)", testvar, *result); ajStrDel(&testvar); ajStrDel(&elsevar); ajStrDel(&restvar); return ajTrue; } if(ifound == 0) { ajStrAssignS(result, elsevar); acdLog("%S != else : '%S'\n", testvar, *result); ajStrDel(&testvar); ajStrDel(&elsevar); ajStrDel(&restvar); return ajTrue; } } ajStrDel(&testvar); ajStrDel(&elsevar); ajStrDel(&restvar); return ajFalse; } ID acdExpFilename TY static MO ajacd LB acd XX DE Looks for an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpFilename(AjPStr* result, const AjPStr str) { if(!acdRegExpFilename) /* file: name */ acdRegExpFilename = ajRegCompC("^[ \t]*[Ff][Ii][Ll][Ee]:[ \t]*([^ \t]+)[ \t]*$"); if(ajRegExec(acdRegExpFilename, str)) { acdLog("acdRegExpFilename matched '%S'\n", str); ajRegSubI(acdRegExpFilename, 1, &acdTmpStr); ajStrAssignS(result, acdTmpStr); ajFilenameTrimAll(result); ajStrFmtLower(result); acdLog("file: %S = '%S'\n", acdTmpStr, *result); return ajTrue; } return ajFalse; } ID acdExpExists TY static MO ajacd LB acd XX DE Looks for an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpExists(AjPStr* result, const AjPStr str) { AjBool test; if(!acdRegExpFileExists) /* file: name */ acdRegExpFileExists = ajRegCompC("^[ \t]*[Ii][Ss]:[ \t]*([^ \t]*)[ \t]*$"); if(ajRegExec(acdRegExpFileExists, str)) { acdLog("acdRegExpFileExists matched '%S'\n", str); ajRegSubI(acdRegExpFileExists, 1, &acdTmpStr); if(ajStrGetLen(acdTmpStr)) test = ajTrue; else test = ajFalse; ajFmtPrintS(result, "%b", test); acdLog("test: '%S' = '%S'\n", acdTmpStr, *result); return ajTrue; } return ajFalse; } ID acdExpValue TY static MO ajacd LB acd XX DE Looks for an expression \ XX PN [1] PA w result AjPStr* PD Expression result PX PN [2] PA r str const AjPStr PD String with possible expression PX RT AjBool RD ajTrue if successfully resolved RX // static AjBool acdExpValue(AjPStr* result, const AjPStr str) { if(!acdRegExpValue) /* file: name */ acdRegExpValue = ajRegCompC("^[ \t]*[Vv][Aa][Ll][Uu][Ee]:[ \t]*([^ \t]*)[ \t]*$"); if(ajRegExec(acdRegExpValue, str)) { acdLog("acdRegExpValue matched '%S'\n", str); ajRegSubI(acdRegExpValue, 1, &acdTmpStr); if(!ajNamGetValueS(acdTmpStr, result)) ajNamGetenvS(acdTmpStr, result); acdLog("test: '%S' = '%S'\n", acdTmpStr, *result); return ajTrue; } return ajFalse; } ID acdVarSplit TY static MO ajacd LB acd XX DE Splits a variable reference into name and attribute. DE Attribute is "default" if not specified XX PN [1] PA r var const AjPStr PD Variable reference PX PN [2] PA w name AjPStr* PD Variable name PX PN [3] PA w pattrname AjPStr* PD Attribute name, or "default" if not set. PX RT AjBool RD ajTrue if successfully split RX // static AjBool acdVarSplit(const AjPStr var, AjPStr* name, AjPStr* pattrname) { ajlong i; ajStrAssignS(name, var); i = ajStrFindC(*name, "."); /* qualifier with value */ if(i > 0) { ajStrAssignS(pattrname, var); ajStrKeepRange(name, 0, i-1); /* strip any value and keep testing */ ajStrCutStart(pattrname, (size_t) (i+1)); } else ajStrDelStatic(pattrname); return ajTrue; } ID acdAttrTest TY static MO ajacd LB acd XX DE Tests for the existence of a named attribute XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attrib const char* PD Attribute name PX RT AjBool RD ajTrue if the named attribute exists RX // static AjBool acdAttrTest(const AcdPAcd thys,const char *attrib) { AcdPAttr attr; AcdPAttr defattr = acdAttrDef; ajint i; if(acdIsQtype(thys)) attr = acdType[thys->Type].Attr; else attr = acdKeywords[thys->Type].Attr; i = acdFindAttrC(attr, attrib); if(i >= 0) return ajTrue; if(thys->DefStr) { i = acdFindAttrC(defattr, attrib); if(i >= 0) return ajTrue; } return ajFalse; } ID acdAttrTestDefined TY static MO ajacd LB acd XX DE Tests for the existence of a named attribute with a value XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attrib const char* PD Attribute name PX RT AjBool RD ajTrue if the named attribute exists RX // static AjBool acdAttrTestDefined(const AcdPAcd thys,const char *attrib) { AcdPAttr attr; AjPStr *attrstr; AcdPAttr defattr = acdAttrDef; AjPStr *defstr; ajint i; attrstr = thys->AttrStr; defstr = thys->DefStr; if(acdIsQtype(thys)) attr = acdType[thys->Type].Attr; else attr = acdKeywords[thys->Type].Attr; i = acdFindAttrC(attr, attrib); if(i >= 0) { if (ajStrGetLen(attrstr[i])) return ajTrue; else return ajFalse; } if(thys->DefStr) { i = acdFindAttrC(defattr, attrib); if(i >= 0) { if (ajStrGetLen(defstr[i])) return ajTrue; else return ajFalse; } } return ajFalse; } ID acdAttrTestValue TY static MO ajacd LB acd XX DE Tests for the existence of a named attribute with a simple value XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attrib const char* PD Attribute name PX RT AjBool RD ajTrue if the named attribute exists RX // static AjBool acdAttrTestValue(const AcdPAcd thys,const char *attrib) { AcdPAttr attr; AjPStr *attrstr; AcdPAttr defattr = acdAttrDef; AjPStr *defstr; ajint i; attrstr = thys->AttrStr; defstr = thys->DefStr; if(acdIsQtype(thys)) attr = acdType[thys->Type].Attr; else attr = acdKeywords[thys->Type].Attr; i = acdFindAttrC(attr, attrib); if(i >= 0) { if (ajStrGetLen(attrstr[i]) && ajStrFindAnyK(attrstr[i], '$') < 0) return ajTrue; else return ajFalse; } if(thys->DefStr) { i = acdFindAttrC(defattr, attrib); if(i >= 0) { if (ajStrGetLen(defstr[i]) && ajStrFindAnyK(defstr[i], '$') < 0) return ajTrue; else return ajFalse; } } return ajFalse; } ID acdAttrValue TY static MO ajacd LB acd XX DE Returns the string value for a named attribute XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attrib const char* PD Attribute name PX RT const AjPStr RD Attribute value. RX // static const AjPStr acdAttrValue(const AcdPAcd thys, const char *attrib) { AcdPAttr attr; AjPStr *attrstr; AcdPAttr defattr; AjPStr *defstr; ajint i; attrstr = thys->AttrStr; defattr = acdAttrDef; defstr = thys->DefStr; if(acdIsQtype(thys)) attr = acdType[thys->Type].Attr; else attr = acdKeywords[thys->Type].Attr; i = acdFindAttrC(attr, attrib); if(i >= 0) return attrstr[i]; if(thys->DefStr) { i = acdFindAttrC(defattr, attrib); if(i >= 0) return defstr[i]; } if(i < 0) acdErrorAcd(thys, "Unknown attribute '%s'\n", attrib); return NULL; } ID acdAttrValueStr TY static MO ajacd LB acd XX DE Returns the string value for a named attribute XX PN [1] PA r thys const AcdPAcd PD ACD item PX PN [2] PA r attrib const char* PD Attribute name PX PN [3] PA r def const char* PD Default value PX PN [4] PA w str AjPStr* PD Attribute value PX RT AjBool RD ajTrue if success. RX // static AjBool acdAttrValueStr(const AcdPAcd thys, const char *attrib, const char* def, AjPStr *str) { AcdPAttr attr; AjPStr *attrstr; AcdPAttr defattr; AjPStr *defstr; ajint i; attrstr = thys->AttrStr; defattr = acdAttrDef; defstr = thys->DefStr; if(acdIsQtype(thys)) attr = acdType[thys->Type].Attr; else attr = acdKeywords[thys->Type].Attr; i = acdFindAttrC(attr, attrib); if(i >= 0) { ajStrAssignS(str, attrstr[i]); if(ajStrGetLen(*str)) return ajTrue; ajStrAssignC(str, def); return ajFalse; } if(thys->DefStr) { i = acdFindAttrC(defattr, attrib); if(i >= 0) { ajStrAssignS(str, defstr[i]); if(ajStrGetLen(*str)) return ajTrue; ajStrAssignC(str, def); return ajFalse; } } if(i < 0) acdErrorAcd(thys, "Unknown attribute %s\n", attrib); return ajFalse; } ID ajAcdSetControl TY public MO ajacd LB acd XX DE Sets special qualifiers which were originally provided via the DE command line. DE DE Sets special internal variables to reflect their presence. DE DE Currently these are "acdhelp", "acdlog", "acdpretty", "acdtable", DE "acdtrace", "acdvalid", "acdverbose", "acdxsd" and "acdnocommandline" XX PN [1] PA r optionName const char* PD option name PX RT AjBool RD ajTrue if option was recognised RX // AjBool ajAcdSetControl(const char* optionName) { AcdPAcd vacd; AjPStr varname = NULL; if(!ajCharCmpCase(optionName, "acdhelp")) { acdDoHelp = ajTrue; return ajTrue; } if(!ajCharCmpCase(optionName, "acdlog")) { acdDoLog = ajTrue; return ajTrue; } if(!ajCharCmpCase(optionName, "acdnocommandline")) { acdCommandLine = ajFalse; return ajTrue; } if(!ajCharCmpCase(optionName, "acdpretty")) { acdDoPretty = ajTrue; return ajTrue; } if(!ajCharCmpCase(optionName, "acdtable")) { acdDoTable = ajTrue; return ajTrue; } if(!ajCharCmpCase(optionName, "acdtrace")) { acdDoTrace = ajTrue; return ajTrue; } if(!ajCharCmpCase(optionName, "acdvalid")) { acdDoValid = ajTrue; return ajTrue; } if(!ajCharCmpCase(optionName, "acdverbose")) { acdVerbose = ajTrue; return ajTrue; } if(!ajCharCmpCase(optionName, "acdgalaxy")) { acdDoGalaxy = ajTrue; return ajTrue; } if(!ajCharCmpCase(optionName, "acdgalaxynucleotide")) { acdDoGalaxyNuc = ajTrue; ajStrAssignC(&varname, "acdprotein"); ajStrAssignC(&acdVarAcdProtein, "N"); vacd = acdNewVar(varname); acdSetVarDef(vacd, acdVarAcdProtein); ajStrDel(&varname); return ajTrue; } if(!ajCharCmpCase(optionName, "acdgalaxyprotein")) { acdDoGalaxyProt = ajTrue; ajStrAssignC(&varname, "acdprotein"); ajStrAssignC(&acdVarAcdProtein, "Y"); vacd = acdNewVar(varname); acdSetVarDef(vacd, acdVarAcdProtein); ajStrDel(&varname); return ajTrue; } if(!ajCharCmpCase(optionName, "acdxsd")) { acdDoXsd = ajTrue; return ajTrue; } /* program source error */ ajDie("Unknown ajAcdSetControl control option '%s'", optionName); return ajFalse; } ID acdArgsScan TY static MO ajacd LB acd XX DE Steps through the command line and checks for special qualifiers. DE Sets special internal variables to reflect their presence. DE DE Currently these are "-debug", "-stdout", "-filter", "-options" DE "-help" and "-auto", plus the message controls DE "-warning", "-error", "-fatal", "-die" XX PN [1] PA r argc ajint PD Number of arguments PX PN [2] PA r argv char* const[] PD Actual arguments as a text array. PX RT void RD RX // static void acdArgsScan(ajint argc, char * const argv[]) { ajint i; char* cp; for(i=0; i < argc; i++) { cp = argv[i]; if(*cp && strchr("-/", *cp)) /* first character vs. qualifier starts */ { cp++; if(*cp == '-') /* allow --qualifier */ cp++; } else continue; if(!*cp) continue; if(!strcmp(cp, "debug")) { acdDebug = ajTrue; acdDebugSet = ajTrue; } if(!strcmp(cp, "nodebug")) { acdDebug = ajFalse; acdDebugSet = ajTrue; } if(!strcmp(cp, "stdout")) acdStdout = ajTrue; if(!strcmp(cp, "filter")) acdFilter = ajTrue; if(!strcmp(cp, "options")) acdOptions = ajTrue; if(!strcmp(cp, "verbose")) acdVerbose = ajTrue; if(!strcmp(cp, "version")) acdDoVersion = ajTrue; if(!strcmp(cp, "help")) acdDoHelp = ajTrue; if(!strcmp(cp, "auto")) acdAuto = ajTrue; if(!strcmp(cp, "warning")) AjErrorLevel.warning = ajTrue; if(!strcmp(cp, "nowarning")) AjErrorLevel.warning = ajFalse; if(!strcmp(cp, "error")) AjErrorLevel.error = ajTrue; if(!strcmp(cp, "noerror")) AjErrorLevel.error = ajFalse; if(!strcmp(cp, "-fatal")) AjErrorLevel.fatal = ajTrue; if(!strcmp(cp, "nofatal")) AjErrorLevel.fatal = ajFalse; if(!strcmp(cp, "die")) AjErrorLevel.die = ajTrue; if(!strcmp(cp, "nodie")) AjErrorLevel.die = ajFalse; if(!strcmp(cp, "help")) acdLog("acdArgsScan -help argv[%d]\n", i); } acdLog("acdArgsScan acdDebug %B acdDoHelp %B\n", acdDebug, acdDoHelp); return; } ID acdArgsParse TY static MO ajacd LB acd XX DE Steps through the command line and compares to the stored command structure. DE Capable of cunning tricks such as matching values to qualifiers if they fit, DE and otherwise treating them as parameters. XX PN [1] PA r argc ajint PD Number of arguments PX PN [2] PA r argv char* const[] PD Actual arguments as a text array. PX RT void RD RX // static void acdArgsParse(ajint argc, char * const argv[]) { ajint i; ajint j; ajint number; ajint iparam = 0; /* expected next param */ ajint jparam = 0; /* param found */ ajint itestparam = 0; ajint jtestparam = 0; AcdPAcd acd; AcdPAcd acd2; const char *cp; const char *cq; AjPStr qual = NULL; AjPStr noqual = NULL; AjPStr value = NULL; AjPStr param = NULL; AjPStr token = NULL; AjPStr master = NULL; AjPStr argvalstr = NULL; acdLog("ArgsParse\n=========\n"); acdLog("\n"); acdMasterQual = NULL; /* acdQualTestSkip = ajFalse; */ i = 1; while(i < argc) { acdLog("%s ", argv[i]); i++; } acdLog("\n"); acdLog("\n"); i = 1; /* skip the program name */ while(i < argc) { cp = argv[i]; if((i+1) < argc) cq = argv[i+1]; else cq = NULL; if(acdArgSave) ajStrAppendK(&acdArgSave, '\n'); acdLog("\n"); acdLog("argv[%d] <%s>", i, cp); if(cq) acdLog(" + argv[%d] <%s>", i+1, cq); acdLog("\n"); jparam = 0; if((j = acdIsQual(cp, cq, &jparam, &qual, &noqual, &value, &number, &master, &acd))) { if(jparam) { acdLog("Parameter (%d) ", jparam); acdParamSet[jparam-1] = ajTrue; if(iparam == (jparam-1)) { iparam = acdNextParam(iparam); acdLog("reset iparam = %d\n", iparam); } else acdLog("keep iparam = %d\n", iparam); } else acdLog("Qualifier "); acdLog("-%S ", noqual); if(number) acdLog("[%d] ", number); if(ajStrGetLen(value)) acdLog("= '%S'", value); acdLog("\n"); /* ** acdFindQualDetail dies (Unknown qualifier) if acd is not set, ** so we are safe here */ acdDef(acd, value); acdLog("set qualifier -%S[%d] (param %d) = %S\n", acd->Name, acd->PNum, jparam, value); /* loop over any associated qualifiers for the rest */ acdLog("number: %d jparam: %d acd->PNum: %d acdNParam: %d\n", number, jparam, acd->PNum, acdNParam); if(!ajStrGetLen(master) && !number && !jparam && acd->PNum) { for(itestparam = acd->PNum+1; itestparam <= acdNParam; itestparam++) { acdLog("test [%d] '%S'\n", itestparam, qual); acd2 = acdFindQualDetail(qual, NULL, NULL, itestparam, &jtestparam); if(acd2) { acdDef(acd2, value); acdLog("set next qualifier -%S[%d] (param %d) = %S\n", acd2->Name, acd2->PNum, jparam, value); } else acdLog("no -%S[%d]\n", qual, itestparam); } } acd->UserDefined = ajTrue; ajStrAppendK(&acdArgSave, '-'); ajStrAppendS(&acdArgSave, noqual); if(number) ajFmtPrintAppS(&acdArgSave, "%d", number); else if(ajStrGetLen(master)) ajFmtPrintAppS(&acdArgSave, "_%S", master); if(j==2) { i++; } ajStrAssignS(&argvalstr, value); if(!strcmp(acdType[acd->Type].Name, "boolean") || !strcmp(acdType[acd->Type].Name, "toggle")) { if(ajStrMatchS(qual, noqual)) /* -boolqual */ { if(ajStrMatchC(value, "Y")) ajStrAssignClear(&argvalstr); } else if(ajStrMatchC(value, "N")) /* -noboolqual */ ajStrAssignClear(&argvalstr); if(ajStrGetLen(argvalstr)) /* non-trivial boolean values */ { ajStrAppendK(&acdArgSave, ' '); ajStrAppendS(&acdArgSave, argvalstr); } } else if(ajStrIsWord(value) && (ajStrFindAnyC(value, "*?[]{}|!&^") < 0)) { ajStrAppendK(&acdArgSave, ' '); ajStrAppendS(&acdArgSave, value); } else if(ajStrMatchS(qual, noqual)) /* not -nomissfile */ { ajStrAppendK(&acdArgSave, ' '); ajStrAppendK(&acdArgSave, '\"'); ajStrAppendS(&acdArgSave, value); ajStrAppendK(&acdArgSave, '\"'); } } else /* not a qualifier - assume a parameter */ { iparam = acdNextParam(0); /* first free parameter */ acdIsParam(cp, ¶m, &iparam, &acd); /* die if too many */ acd->UserDefined = ajTrue; ajStrAppendC(&acdArgSave, "[-"); ajStrAppendS(&acdArgSave, acd->Name); ajStrAppendC(&acdArgSave, "] "); if(acdIsParamValue(param)) { acdLog("Parameter %d: %S = %S\n", iparam, acd->Name, param); acdDef(acd, param); acdParamSet[iparam-1] = ajTrue; ajStrAssignC(&argvalstr, cp); if(ajStrIsWord(argvalstr) && (ajStrFindAnyC(argvalstr, "*?[]{}|!&^") < 0)) ajStrAppendS(&acdArgSave, argvalstr); else { ajStrAppendK(&acdArgSave, '\"'); ajStrAppendS(&acdArgSave, argvalstr); ajStrAppendK(&acdArgSave, '\"'); } } else /* missing value "" ignored */ { acdLog("Parameter %d: %S = '%S' ** missing value **\n", iparam, acd->Name, param); ajStrAssignClear(¶m); acdDef(acd, param); acdParamSet[iparam-1] = ajTrue; ajStrAppendC(&acdArgSave, "\"\""); } } i++; } ajStrDel(&qual); ajStrDel(&noqual); ajStrDel(&value); ajStrDel(¶m); ajStrDel(&token); ajStrDel(&argvalstr); return; } ID acdIsParamValue TY static MO ajacd LB acd XX DE Tests whether a parameter value is 'missing', in which case DE it will be ignored for now. XX PN [1] PA r pval const AjPStr PD Parameter value PX RT AjBool RD ajFalse for a missing value. RX // static AjBool acdIsParamValue(const AjPStr pval) { if(!ajStrGetLen(pval)) return ajFalse; return ajTrue; } ID acdNextParam TY static MO ajacd LB acd XX DE Returns the next unknown parameter. Used for cases where parameters DE are specified by qualifier before their turn on the command line XX PN [1] PA r pnum ajint PD Current parameter number PX RT ajint RD next undefined parameter RX // static ajint acdNextParam(ajint pnum) { ajint i; if(pnum > acdNParam) return pnum+1; /* all done */ for(i=pnum;i= acdNParam) /* test acdc-toomanyparam */ { ajErr("Argument '%s' : Too many parameters %d/%d", arg, (*iparam), acdNParam); ajExitBad(); } (*iparam)++; *acd = acdFindParam(*iparam); if(!*cp) /* missing value */ { ajStrAssignClear(param); /* clear the parameter */ return ajTrue; } ajStrAssignC(param, arg); /* copy the argument value */ if(*acd) { if((*acd)->AssocQuals) { acdLog("acdMasterQual [param] set to -%S\n", (*acd)->Name); acdMasterQual = *acd; } else if(acdMasterQual) { acdLog("acdMasterQual cleared, was -%S\n", acdMasterQual->Name); acdMasterQual = NULL; } return ajTrue; } return ajFalse; } ID acdIsQual TY static MO ajacd LB acd XX DE Tests an argument to see whether it is a qualifier DE Qualifiers start with "-". DE Qualifiers are assumed to take a value, which is either DE delimited by an "=" sign or is the next argument. DE Qualifiers can also have a numbered suffix if matching one of the parameters DE or a specific master qualifier as a suffix after an underscore. XX PN [1] PA r arg const char* PD Argument PX PN [2] PA r arg2 const char* PD Next argument PX PN [3] PA w iparam ajint* PD Parameter number PX PN [4] PA w pqual AjPStr* PD Qualifier name copied on success PX PN [5] PA w pnoqual AjPStr* PD Qualifier name with possible 'no' prefix PX PN [6] PA w pvalue AjPStr* PD Qualifier value copied on success PX PN [7] PA w number ajint* PD Qualifier number PX PN [8] PA w pmaster AjPStr* PD Named master qualifier PX PN [9] PA w acd AcdPAcd* PD Qualifier data PX RT ajint RD Number of arguments consumed RX // static ajint acdIsQual(const char* arg, const char* arg2, ajint *iparam, AjPStr *pqual, AjPStr *pnoqual, AjPStr *pvalue, ajint* number, AjPStr *pmaster, AcdPAcd* acd) { ajint ret=0; const char *cp; ajlong i; AjBool gotvalue = ajFalse; AjBool ismissing = ajFalse; AjBool qstart = ajFalse; AjBool nullok = ajFalse; AjBool attrok = ajFalse; AjPStr noqual = NULL; acdLog("acdIsQual '%s' '%s'\n", arg, arg2); cp = arg; *number = 0; *acd = NULL; ajStrDel(pmaster); if(!strcmp(cp, "-")) /* stdin or stdout parameter */ return 0; if(!*cp) /* dummy parameter */ return 0; if(!strcmp(cp, "--")) /* special -- to turn off processing */ { /* acdQualTestSkip = ajTrue; */ return 0; } if(*cp && strchr("-/", *cp)) /* first character vs. qualifier starts */ { cp++; qstart = ajTrue; if(*cp == '-') /* allow --qualifier */ { cp++; } } ajStrAssignClear(pqual); ajStrAssignClear(pnoqual); if(!*cp) return 0; /* qualifier: now play hunt the value */ ret = 1; ajStrAssignC(pqual, cp); /* qualifier with '-' or '/' removed */ /* ** pqual could be ** qualname (unless boolean, look for next arg as the value) ** qualname=value (value as part of arg) ** noqualname (boolean negative, or nullok set to empty string */ /* ** First check whether we have a value (set gotvalue) in the first arg */ i = ajStrFindC(*pqual, "="); if(i >= 0) { if((i+1) == (ajint) ajStrGetLen(*pqual)) /* ended with '=' */ ajStrAssignC(pvalue, ""); else ajStrAssignSubS(pvalue, *pqual, (i+1), -1); acdLog("qualifier value '%S' '%S' %d .. %d\n", *pvalue, *pqual, (i+1), -1); ajStrKeepRange(pqual, 0, (i-1)); gotvalue = ajTrue; } else { if(!qstart) /* no start, no "=" assume it's a parameter */ return 0; if(!ajStrIsAlnum(*pqual)) /* funny characters, fail */ return 0; } acdQualParse(pqual, &noqual, pmaster, number); if(ajStrGetLen(*pmaster)) /* specific master, turn off auto processing */ acdMasterQual = NULL; /* pmaster resets this in acdFindQualDetail */ if(acdMasterQual) /* we are still working with a master */ { acdLog("(a) master, try associated with acdFindQualAssoc\n"); *acd = acdFindQualAssoc(acdMasterQual, *pqual, noqual, *pmaster, *number); if(!*acd) { acdLog("acdMasterQual cleared, was -%S\n", acdMasterQual->Name); acdMasterQual = NULL; } else { *number = acdMasterQual->PNum; acdLog("Qualifier -%S associated with -%S\n", *pqual, acdMasterQual->Name); } } if(!acdMasterQual) { acdLog("(b) no master, general test with acdFindQualDetail\n"); *acd = acdFindQualDetail(*pqual, noqual, *pmaster, *number, iparam); } if(!*acd) /* test acdc-badqual */ ajDie("Unknown qualifier %s", arg); ajStrAssignS(pqual, (*acd)->Name); ajStrAssignS(pnoqual, (*acd)->Name); if((*acd)->AssocQuals) /* this one is a new master */ { acdLog("acdMasterQual set to -%S\n", (*acd)->Name); acdMasterQual = *acd; } if(gotvalue) { /* test acdc-noprefixvalue */ if(ajStrPrefixS((*acd)->Name, noqual)) ajDie("'no' prefix used with value for '%s'", arg); } else { acdLog("testing for a value\n"); /* ** Bool qualifiers can have no value ** or can be followed by a valid Bool value */ if(ajStrPrefixS((*acd)->Name, noqual)) { /* we have a -noqual matched */ acdLog("we matched with -no\n"); ajStrAssignC(pnoqual, "no"); ajStrAppendS(pnoqual, (*acd)->Name); if(!strcmp(acdType[acdListCurr->Type].Name, "boolean") || !strcmp(acdType[acdListCurr->Type].Name, "toggle")) { acdLog("-no%S=N boolean or toggle accepted\n", noqual); gotvalue = ajTrue; ret = 1; ajStrAssignC(pvalue, "N"); ajStrDel(&noqual); return ret; } if(acdAttrTest(*acd, "nullok")) { if(acdAttrTestValue(*acd, "nullok")) attrok = acdAttrToBool(*acd, /* -no for null value */ "nullok", ajFalse, &nullok); else /* assume it can be true */ { attrok = ajTrue; nullok = ajTrue; } acdLog("check for nullok, found:%B value:%B\n", attrok, nullok); } else nullok = ajFalse; if(nullok) { acdLog("-no%S='' nullOK accepted\n", noqual); gotvalue = ajTrue; ret = 1; (*acd)->UserSetNull = ajTrue; ajStrAssignClear(pvalue); ajStrDel(&noqual); return ret; } else /* test acdc-noprefixbad acdc-noprefixbad2 */ ajDie("'no' prefix invalid for '%s'", arg); } /* ** just the qualifier name with no value */ if(!strcmp(acdType[acdListCurr->Type].Name, "boolean") || !strcmp(acdType[acdListCurr->Type].Name, "toggle")) { if(acdValIsBool(arg2)) /* bool value, accept */ { acdLog("acdValIsBool -%s '%s'\n", arg, arg2); gotvalue = ajTrue; ret = 2; ajStrAssignC(pvalue, arg2); } else /* we must mean true */ ajStrAssignC(pvalue, "Y"); } else { if(!arg2) /* no value - can be missing? */ { ajStrToBool((*acd)->DefStr[DEF_MISSING], &ismissing); if(!ismissing) /* test acdc-novalue */ ajDie("Value required for '%s'", arg); } /* test for known qualifiers */ else { if(*arg2 == '-') { if(!acdTestQualC(arg2)) /* not known qualifier */ /* must be value */ gotvalue = ajTrue; else { ajStrToBool((*acd)->DefStr[DEF_MISSING], &ismissing); if(!ismissing) /* test acdc-novalue2 */ ajDie("Value required for '%s' before '%s'", arg, arg2); } } else gotvalue = ajTrue; } if(gotvalue) { ret = 2; ajStrAssignC(pvalue, arg2); } else ajStrAssignClear(pvalue); } } ajStrDel(&noqual); return ret; } ID acdValIsBool TY static MO ajacd LB acd XX DE Tests whether a value on the command line is a valid Boolean value XX PN [1] PA r arg const char* PD COmmand live argument value PX RT AjBool RD ajTrue if the value is boolean, RD but not whether it is true or false. RX // static AjBool acdValIsBool(const char* arg) { if(!arg) return ajFalse; switch(*arg) { case 'n': case 'N': if(!arg[1]) return ajTrue; return ajCharMatchCaseC(arg, "no"); case 'y': case 'Y': if(!arg[1]) return ajTrue; return ajCharMatchCaseC(arg, "yes"); case 't': case 'T': if(!arg[1]) return ajTrue; return ajCharMatchCaseC(arg, "true"); case 'f': case 'F': if(!arg[1]) return ajTrue; return ajCharMatchCaseC(arg, "false"); case '0': if(!arg[1]) return ajTrue; return ajCharMatchCaseC(arg, "0"); case '1': if(!arg[1]) return ajTrue; return ajCharMatchCaseC(arg, "1"); default: break; } return ajFalse; } ID acdFindItem TY static MO ajacd LB acd XX DE Returns the ACD definition for a named item and DE (optionally) a given qualifier number. If the qualifier number DE is given, it is checked. If not, the first hit is used. DE DE Section and Endsection do not count XX PN [1] PA r item const AjPStr PD Item name PX PN [2] PA r number ajint PD Item number (zero if a general item) PX RT AcdPAcd RD ACD item required RX // static AcdPAcd acdFindItem(const AjPStr item, ajint number) { AcdPAcd ret = NULL; AcdPAcd pa; AjBool found = ajFalse; ajint ifound = 0; AjPStr ambigList = NULL; ambigList = ajStrNew(); for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; found = ajFalse; if(ajStrPrefixS(pa->Name, item)) if(!number || number == pa->PNum) found = ajTrue; if(found) { if(ajStrMatchS(pa->Name, item)) { ajStrDel(&ambigList); return pa; } ifound++; ret = pa; acdAmbigApp(&ambigList, pa->Name); } } if(ifound == 1) { if (acdDoValid) acdWarn("Abbreviated item '%S' (%S)", item, ambigList); ajStrDel(&ambigList); return ret; } if(ifound > 1) { ajWarn("ambiguous item %S (%S)", item, ambigList); } ajStrDel(&ambigList); return NULL; } ID acdFindQual TY static MO ajacd LB acd XX DE Finds a qualifier by name, and returns the full name XX PN [1] PA u pqual AjPStr* PD Qualifier name PX RT AcdPAcd RD ACD item for qualifier RX // static AcdPAcd acdFindQual(AjPStr *pqual) { AcdPAcd ret = NULL; AcdPAcd pa; ajint ifound = 0; AjBool found = ajFalse; if(!ajStrGetLen(*pqual)) return NULL; for(pa=acdList; pa; pa=pa->Next) { found = ajFalse; if(acdIsStype(pa)) continue; found = ajFalse; if(pa->Level == ACD_QUAL || pa->Level == ACD_PARAM) { if(ajStrPrefixS(pa->Name, *pqual)) found = ajTrue; if(found) { if(ajStrMatchS(pa->Name, *pqual)) return pa; ifound++; ret = pa; } } } if(ifound == 1) { ajStrAssignS(pqual, ret->Name); return ret; } return NULL; } ID acdFindQualDetail TY static MO ajacd LB acd XX DE Returns the parameter definition for a named qualifier and DE (optionally) a given qualifier number. If the qualifier number DE is given, it is checked. If not, the current parameter number is checked. DE General qualifiers have no specified number and can match at any time. XX PN [1] PA r qual const AjPStr PD Qualifier name PX PN [2] PA r noqual const AjPStr PD Alternative qualifier name PD (qual with "no" prefix removed, or empty, or NULL) PX PN [3] PA rN master const AjPStr PD Master qualifier name PX PN [4] PA r PNum ajint PD Qualifier number (zero if a general qualifier) PX PN [5] PA u iparam ajint* PD Current parameter number PX RT AcdPAcd RD ACD item for qualifier RX // static AcdPAcd acdFindQualDetail(const AjPStr qual, const AjPStr noqual, const AjPStr master, ajint PNum, ajint *iparam) { /* test for match of parameter number and type */ /* PNum : number encoded in qualifier name ==> forced match */ /* iparam : current parameter number ==> possible match */ /* when both are zero, could be a generic match, like "-begin" for all sequences. Just return the first and let caller find the rest */ AcdPAcd ret = NULL; AcdPAcd pa; AjBool found = ajFalse; AjBool isparam = ajFalse; ajint ifound = 0; AjPStr ambigList = NULL; if(ajStrGetLen(master)) { acdLog("acdFindQualDetail ... call acdFindQualMaster\n", qual, noqual, PNum, *iparam); *iparam = 0; return acdFindQualMaster(qual, noqual, master, PNum); } ambigList = ajStrNew(); acdLog("acdFindQualDetail '%S' (%S) PNum: %d iparam: %d\n", qual, noqual, PNum, *iparam); for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; found = ajFalse; if(pa->Level == ACD_QUAL) { if(ajStrPrefixS(pa->Name, qual) || ajStrPrefixS(pa->Name, noqual)) { acdLog("..matched qualifier '%S' [%d]\n", pa->Name, pa->PNum); if(PNum) /* -begin2 forces match to #2 */ { if(PNum == pa->PNum) { acdLog("..matched PNum '%S' [%d]\n", pa->Name, pa->PNum); found = ajTrue; } } else if(pa->PNum) /* defined for parameter pa->PNum */ { acdLog("..hit PNum '%S' [%d] (ambigList '%S')\n", pa->Name, pa->PNum, ambigList); if(!ifound || !ajStrMatchS(pa->Name, ambigList)) found = ajTrue; } else /* general match */ found = ajTrue; if(found) { if(ajStrMatchS(pa->Name, qual) || ajStrMatchS(pa->Name, noqual)) { acdListCurr = pa; ajStrDel(&ambigList); return pa; } acdAmbigApp(&ambigList, pa->Name); ifound++; ret = pa; acdLog("..prefix only '%S', ifound %d\n", pa->Name, ifound); } } } else if(pa->Level == ACD_PARAM) { if(ajStrPrefixS(pa->Name, qual) || ajStrPrefixS(pa->Name, noqual)) { acdLog("..matched param '%S' [%d]\n", pa->Name, pa->PNum); if(ajStrMatchS(pa->Name, qual) || ajStrMatchS(pa->Name, noqual)) { acdListCurr = pa; *iparam = pa->PNum; ajStrDel(&ambigList); return pa; } acdAmbigApp(&ambigList, pa->Name); ifound++; isparam = ajTrue; ret = pa; acdLog("..prefix only '%S', ifound %d\n", pa->Name, ifound); } } } if(ifound == 1) { acdListCurr = ret; if(isparam) *iparam = ret->PNum; if (acdDoValid) acdWarn("Abbreviated qualifier '%S' (%S)", qual, ambigList); ajStrDel(&ambigList); return ret; } if(ifound > 1) { ajWarn("ambiguous qualifier '%S' (%S)", qual, ambigList); } ajStrDel(&ambigList); return NULL; } ID acdFindQualMaster TY static MO ajacd LB acd XX DE Returns the parameter definition for a named qualifier and DE (optionally) a given qualifier number. If the qualifier number DE is given, it is checked. If not, the current parameter number is checked. DE General qualifiers have no specified number and can match at any time. XX PN [1] PA r qual const AjPStr PD Qualifier name PX PN [2] PA r noqual const AjPStr PD Alternative qualifier name PD (qual with "no" prefix removed, or empty, or NULL) PX PN [3] PA rN master const AjPStr PD Master qualifier name PX PN [4] PA r PNum ajint PD Qualifier number (zero if a general qualifier) PX RT AcdPAcd RD ACD item for qualifier RX // static AcdPAcd acdFindQualMaster(const AjPStr qual, const AjPStr noqual, const AjPStr master, ajint PNum) { /* test for match of parameter number and type */ /* ** PNum : number encoded in qualifier name ==> forced match ** iparam : current parameter number ==> possible match ** when both are zero, could be a generic match, like "-begin" for ** all sequences. Just return the first and let caller find the rest */ AcdPAcd ret = NULL; AcdPAcd pa; AjBool found = ajFalse; ajint ifound =0; AjPStr ambigList = NULL; ambigList = ajStrNew(); acdLog("acdFindQualMaster '%S_%S' (%S) PNum: %d\n", qual, master, noqual, PNum); for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; found = ajFalse; if(pa->Level == ACD_QUAL) { if(ajStrPrefixS(pa->Name, master)) { acdLog("..matched qualifier '%S' [%d]\n", pa->Name, pa->PNum); if(PNum) /* -begin2 forces match to #2 */ { if(PNum == pa->PNum) { acdLog("..matched PNum '%S' [%d]\n", pa->Name, pa->PNum); found = ajTrue; } } else if(pa->PNum) /* defined for parameter pa->PNum */ { acdLog("..hit PNum '%S' [%d] (ambigList '%S')\n", pa->Name, pa->PNum, ambigList); if(!ifound || !ajStrMatchS(pa->Name, ambigList)) found = ajTrue; } else /* general match */ found = ajTrue; if(found) { if(ajStrMatchS(pa->Name, master)) { ret = pa; ifound = 1; break; } acdAmbigApp(&ambigList, pa->Name); ifound++; ret = pa; acdLog("..prefix only, ifound %d\n", ifound); } } } else if(pa->Level == ACD_PARAM) { if(ajStrPrefixS(pa->Name, master)) { acdLog("..matched param '%S' [%d]\n", pa->Name, pa->PNum); if(ajStrMatchS(pa->Name, master)) { ret = pa; ifound = 1; break; } acdAmbigApp(&ambigList, pa->Name); ifound++; ret = pa; acdLog("..prefix only, ifound %d\n", ifound); } } } if(ifound > 1) { acdLog("..ambiguous master qualifier for %S_%S (%S)", qual, master, ambigList); ajWarn("Ambiguous master qualifier '%S' in %S_%S (%S)", master, qual, master, ambigList); ajStrDel(&ambigList); return NULL; } if(!ifound) { acdLog("..master qualifier for %S_%S not found\n", qual, master); ajStrDel(&ambigList); return NULL; } acdLog("..master qualifier found '%S' %d\n", ret->Name, ret->PNum); ifound = 0; for(pa=ret->AssocQuals; pa && pa->Assoc; pa=pa->Next) { found = ajFalse; if(ajStrPrefixS(pa->Name, qual) || ajStrPrefixS(pa->Name, noqual)) { acdLog("..matched qualifier '%S' [%d]\n", pa->Name, pa->PNum); if(PNum) /* -begin2 forces match to #2 */ { if(PNum == pa->PNum) { acdLog("..matched PNum '%S' [%d]\n", pa->Name, pa->PNum); found = ajTrue; } } else if(pa->PNum) /* defined for parameter pa->PNum */ { acdLog("..hit PNum '%S' [%d] (ambigList '%S')\n", pa->Name, pa->PNum, ambigList); if(!ifound || !ajStrMatchS(pa->Name, ambigList)) { found = ajTrue; } } else /* general match */ found = ajTrue; if(found) { if(ajStrMatchS(pa->Name, qual) || ajStrMatchS(pa->Name, noqual)) { acdListCurr = pa; ajStrDel(&ambigList); return pa; } acdAmbigApp(&ambigList, pa->Name); ifound++; ret = pa; acdLog("..prefix only, ifound %d\n", ifound); } } } if(ifound == 1) { acdListCurr = ret; if (acdDoValid) acdWarn("Abbreviated associated qualifier '%S_%S' (%S)", qual, master, ambigList); ajStrDel(&ambigList); return ret; } if(ifound > 1) { acdLog("..ambiguous associated qualifier %S_%S (%S)", qual, master, ambigList); ajWarn("ambiguous associated qualifier %S_%S (%S)", qual, master, ambigList); } ajStrDel(&ambigList); acdLog("..associated qualifier %S_%S not found", qual, master); return NULL; } ID acdFindQualAssoc TY static MO ajacd LB acd XX DE Returns the definition for a named associated qualifier. DE If the qualifier number DE is given, it is checked. If not, the current parameter number is checked. DE General qualifiers have no specified number and can match at any time. XX PN [1] PA r thys const AcdPAcd PD Master ACD item PX PN [2] PA r qual const AjPStr PD Qualifier name PX PN [3] PA r noqual const AjPStr PD Alternative qualifier name PD (qual with "no" prefix removed, or empty, or NULL) PX PN [4] PA rN master const AjPStr PD Master qualifier name PX PN [5] PA r PNum ajint PD Qualifier number (zero if a general qualifier) PX RT AcdPAcd RD ACD item for associated qualifier RX // static AcdPAcd acdFindQualAssoc(const AcdPAcd thys, const AjPStr qual, const AjPStr noqual, const AjPStr master, ajint PNum) { /* test for match of parameter number and type */ /* ** PNum : number encoded in qualifier name ==> forced match ** iparam : current parameter number ==> possible match ** when both are zero, could be a generic match, like "-sbegin" for ** all sequences. Just return the first and let caller find the rest */ AcdPAcd pa = thys->AssocQuals; ajint ifound = 0; AcdPAcd ret = NULL; AjPStr ambigList = NULL; ajint iparam; /* acdLog("acdFindQualAssoc '%S' pnum: %d\n", qual, pnum); */ if(PNum && (pa->PNum != PNum)) /* must be for same number (if any) */ return NULL; ambigList = ajStrNew(); for(; pa && pa->Assoc; pa=pa->Next) { if(ajStrPrefixS(pa->Name, qual) || ajStrPrefixS(pa->Name, noqual)) { if(ajStrMatchS(pa->Name, qual) || ajStrMatchS(pa->Name, noqual)) { /* acdLog(" *matched* '%S'\n", pa->Name); */ acdListCurr = pa; ajStrDel(&ambigList); return acdListCurr; } ifound++; ret = pa; acdAmbigApp(&ambigList, pa->Name); } } /* acdLog(" ifound: %d\n", ifound); */ if(ifound == 1) { acdListCurr = ret; pa = acdFindQualDetail(qual,noqual,master,PNum, &iparam); if(pa == ret) { if (acdDoValid) acdWarn("Abbreviated associated qualifier '%S' (%S)", qual, ambigList); ajStrDel(&ambigList); return acdListCurr; } } if(ifound > 1) ajWarn("ambiguous qualifier %S (%S)", qual, ambigList); ajStrDel(&ambigList); return NULL; } ID acdFindParam TY static MO ajacd LB acd XX DE Returns the paremeter definition for a given parameter number XX PN [1] PA r PNum ajint PD Parameter number PX RT AcdPAcd RD ACD item for parameter number PNum RX // static AcdPAcd acdFindParam(ajint PNum) { /* test for match of parameter number and type */ AcdPAcd pa; for(pa=acdList; pa; pa=pa->Next) { if(acdIsStype(pa)) continue; if((pa->Level == ACD_PARAM) && (pa->PNum == PNum)) { acdListCurr = pa; return pa; } } return NULL; } ID acdGetAttr TY static MO ajacd LB acd XX DE Pick up a defined attribute for variable handling. DE The ACD item must be defined (already processed). DE Attributes include any specially calculated by the acdSet function DE for that type. XX PN [1] PA u presult AjPStr* PD Resulting attribute value PX PN [2] PA r name const AjPStr PD ACD item name PX PN [3] PA r attrib const AjPStr PD attribute name PX RT AjBool RD ajTrue on success RX // static AjBool acdGetAttr(AjPStr* presult, const AjPStr name, const AjPStr attrib) { const char *cp; const char *cq; ajint ilen; ajint number = 0; AjPStr tempstr=NULL; AcdPAcd pa = NULL; AcdPAttr attr = NULL; ajint i; acdLog("acdGetAttr name '%S' attrib '%S'\n", name, attrib); ajStrDelStatic(presult); ajStrAssignS(&tempstr, name); ajStrFmtLower(&tempstr); cp = ajStrGetPtr(tempstr); cq = &cp[ajStrGetLen(tempstr)]; if(isdigit((ajint)*--cq)) { while(isdigit((ajint)*--cq)); ++cq; number = (ajint) strtol(cq, NULL, 0); ilen = cq - cp - 1; ajStrKeepRange(&tempstr, 0, ilen); } pa = acdFindItem(tempstr, number); if(!pa) /* test ambigvar.acd */ acdError("Failed to resolve variable '%S'\n", name); ajStrDel(&tempstr); if(!pa->ValStr) { if (!acdDoValid && !acdDoGalaxy) { if(!acdDoHelp) /* test undefvar.acd */ acdError("Variable '%S' not yet defined\n", name); acdAttrValueStr(pa, "default", "...", presult); return ajTrue; } } if(!ajStrGetLen(attrib)) /* just use valstr */ { if (!acdDoValid && !acdDoGalaxy) { ajStrAssignS(presult, pa->ValStr); acdLog("no attribute name, use valstr for %S '%S'\n", pa->Name, *presult); pa->Used |= USED_ACD; return ajTrue; } } if(pa->DefStr) { attr = acdAttrDef; i = acdFindAttr(attr, attrib); if(i >= 0) { ajStrAssignS(presult, pa->DefStr[i]); acdLog("default attribute %S found for %S '%S'\n", attrib, pa->Name, *presult); return ajTrue; } } if(pa->NAttr) { attr = acdType[pa->Type].Attr; i = acdFindAttr(attr, attrib); if(i >= 0) { ajStrAssignS(presult, pa->AttrStr[i]); acdLog("type attribute %S found for %S '%S'\n", attrib, pa->Name, *presult); return ajTrue; } } if(pa->SAttr) { acdLog("++calc++ Testing SAttr %d\n", pa->SAttr); attr = pa->SetAttr; for(i=0; i < pa->SAttr; i++) acdLog("calcattr[%d] '%s'\n", i, attr[i].Name); i = acdFindAttr(attr, attrib); if(i >= 0) { ajStrAssignS(presult, pa->SetStr[i]); acdLog("calculated attribute %S found for %S '%S'\n", attrib, pa->Name, *presult); return ajTrue; } } if(ajStrMatchCaseC(attrib, "isdefined")) { acdLog("++isdefined++ Testing\n"); if (ajStrGetLen(pa->ValStr)) { ajStrAssignC(presult, "Y"); } else { ajStrAssignC(presult, "N"); } acdLog("isdefined attribute found for %S '%S'\n", pa->Name, *presult); return ajTrue; } acdLog("*attribute %S not found for %S*\n", attrib, pa->Name); return ajFalse; } ID acdQualParse TY static MO ajacd LB acd XX DE Converts a qualifier name to lower case and looks for a DE master qualifier name and a trailing number. XX PN [1] PA w pqual AjPStr* PD Qualifier name set to lower case PD with number suffix removed PX PN [2] PA w pnoqual AjPStr* PD Qualifier name as pqual, with "no" prefix PD removed, or empty string id pqual doesn't start with "no" PX PN [3] PA w pqmaster AjPStr* PD Master name for associated qualifier PX PN [4] PA w number ajint* PD Qualifier number suffix if any PX RT void RD RX // static void acdQualParse(AjPStr* pqual, AjPStr* pnoqual, AjPStr* pqmaster, ajint* number) { if(!acdRegQualParse) acdRegQualParse = ajRegCompC("^([a-z]+)(_([a-z]+))?([0-9]+)?$"); ajStrFmtLower(pqual); ajStrAssignS(&acdQualNameTmp, *pqual); if(!ajRegExec(acdRegQualParse, acdQualNameTmp)) { ajStrAssignClear(pqual); ajStrAssignClear(pnoqual); ajStrAssignClear(pqmaster); *number = 0; return; } ajRegSubI(acdRegQualParse, 1, pqual); ajRegSubI(acdRegQualParse, 3, pqmaster); ajRegSubI(acdRegQualParse, 4, &acdQualNumTmp); if(ajStrPrefixC(*pqual, "no")) ajStrAssignSubS(pnoqual, *pqual, 2, -1); else ajStrAssignClear(pnoqual); *number = 0; if(ajStrGetLen(acdQualNumTmp)) ajStrToInt(acdQualNumTmp, number); if(ajStrGetLen(*pqmaster)) acdFindQual(pqmaster); return; } ID acdTokenToLowerS TY static MO ajacd LB acd XX DE Converts a token name to lower case and looks for a trailing number. XX PN [1] PA u ptoken AjPStr* PD Qualifier name set to lower case PD with number suffix removed PX PN [2] PA w number ajint* PD Qualifier number suffix if any. PX RT void RD RX // static void acdTokenToLowerS(AjPStr *ptoken, ajint* number) { const char *cp; const char *cq; ajint ilen; ajStrFmtLower(ptoken); cp = ajStrGetPtr(*ptoken); cq = cp+ajStrGetLen(*ptoken); if(!isdigit((ajint)*--cq)) { *number = 0; return; } while(isdigit((ajint)*--cq)) ; ++cq; *number = (ajint) strtol(cq, NULL, 0); ilen = cq - cp; ajStrCutEnd(ptoken, ajStrGetLen(*ptoken) - ilen); return; } ID acdIsRequired TY static MO ajacd LB acd XX DE Returns true if an ACD item is required but not yet defined. DE Required means the standard attribute is set (which it is by DE default for a parameter), DE or the additional flag is set and -options was specified. XX PN [1] PA r thys const AcdPAcd PD ACD item PX RT AjBool RD ajTrue if "thys" is required but no value set yet. RX // static AjBool acdIsRequired(const AcdPAcd thys) { AjPStr *def = thys->DefStr; AjBool required = ajFalse; if (thys->DefStr) acdLog("acdIsRequired '%S' Defined %B DefStr '%x' std '%S' " "add '%S' def '%S'\n", thys->Name, thys->Defined, thys->DefStr, def[DEF_STANDARD], def[DEF_ADDITIONAL], def[DEF_DEFAULT]); else acdLog("acdIsRequired '%S' Defined %B\n", thys->Name, thys->Defined); if(thys->Defined) return ajFalse; if(!thys->DefStr) return ajFalse; if(ajStrGetLen(def[DEF_STANDARD])) { acdVarResolve(&def[DEF_STANDARD]); if(!ajStrToBool(def[DEF_STANDARD], &required)) acdErrorAcd(thys, "Bad standard flag %S\n", def[DEF_STANDARD]); return required; } if(acdOptions && ajStrGetLen(def[DEF_ADDITIONAL])) { acdVarResolve(&def[DEF_ADDITIONAL]); if(!ajStrToBool(def[DEF_ADDITIONAL], &required)) acdErrorAcd(thys, "Bad additional flag %S\n", def[DEF_ADDITIONAL]); return required; } return ajFalse; } ID acdPromptCodon TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a codon usage file XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptCodon(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandard(thys, "Codon usage file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptDirectory TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a directory XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptDirectory(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " directory")) acdPromptStandardAppend(thys, " directory"); } else acdPromptStandard(thys, "Directory of input files", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptDirlist TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a dirlist XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptDirlist(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " directories")) acdPromptStandardAppend(thys, " directories"); } else acdPromptStandard(thys, "Directories with files", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptFilelist TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a filelist XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptFilelist(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file list")) acdPromptStandardAppend(thys, " file list"); } else acdPromptStandard(thys, "Comma-separated file list", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptFeatures TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a feature table DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptFeatures(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; ajint maxreads = 0; acdAttrToInt(thys, "maxreads", 1, &maxreads); knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " feature table")) acdPromptStandardAppend(thys, " feature table"); } else acdPromptStandard(thys, "input feature table", &count); if(maxreads > 1) acdPromptStandardAppend(thys, "(s)"); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptCpdb TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a clean PDB file XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptCpdb(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandard(thys, "clean PDB file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptScop TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a scop entry XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptScop(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandard(thys, "Scop entry vile", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdHelpTextSeq TY static MO ajacd LB acd XX DE Sets the help text for this ACD object to be a sequence DE description with the type included. XX PN [1] PA r thys const AcdPAcd PD Current ACD object. PX PN [2] PA w Pstr AjPStr* PD Help text PX RT void RD RX // static void acdHelpTextSeq(const AcdPAcd thys, AjPStr* Pstr) { const AjPStr typestr = NULL; AjPStr tmptype = NULL; AjBool gaps = AJFALSE; typestr = acdAttrValue(thys, "type"); ajSeqTypeSummary(typestr, &tmptype, &gaps); ajStrAssignClear(Pstr); if(ajStrGetLen(tmptype)) { ajStrAssignS(Pstr, tmptype); ajStrAppendC(Pstr, " "); ajStrDel(&tmptype); } ajStrAppendC(Pstr, "sequence"); if(ajCharMatchC(acdType[thys->Type].Name, "seqset")) { acdAttrToBool(thys, "aligned", gaps, &gaps); ajStrAppendC(Pstr, " set"); if(gaps) ajStrInsertC(Pstr, 0, "(aligned) "); } else if(ajCharMatchC(acdType[thys->Type].Name, "seqsetall")) { acdAttrToBool(thys, "aligned", gaps, &gaps); ajStrAppendC(Pstr, " set(s)"); if(gaps) ajStrInsertC(Pstr, 0, "(aligned) "); } else if(ajCharMatchC(acdType[thys->Type].Name, "seqall")) { ajStrAppendC(Pstr, "(s)"); if(gaps) ajStrInsertC(Pstr, 0, "(gapped) "); } else { if(gaps) ajStrInsertC(Pstr, 0, "(gapped) "); } ajStrFmtTitle(Pstr); ajStrAppendC(Pstr, " filename and optional format, or reference (input USA)"); return; } ID acdHelpTextSeqout TY static MO ajacd LB acd XX DE Sets the help text for this ACD object to be an output sequence DE description with the type included. XX PN [1] PA r thys const AcdPAcd PD Current ACD object. PX PN [2] PA w Pstr AjPStr* PD Help text PX RT void RD RX // static void acdHelpTextSeqout(const AcdPAcd thys, AjPStr* Pstr) { const AjPStr typestr = NULL; AjPStr tmptype = NULL; AjBool gaps = AJFALSE; typestr = acdAttrValue(thys, "type"); ajSeqTypeSummary(typestr, &tmptype, &gaps); ajStrAssignClear(Pstr); if(ajStrGetLen(tmptype)) { ajStrAssignS(Pstr, tmptype); ajStrAppendC(Pstr, " "); ajStrDel(&tmptype); } ajStrAppendC(Pstr, "sequence"); if(ajCharMatchC(acdType[thys->Type].Name, "seqoutset")) { ajStrAppendC(Pstr, " set"); if(gaps) ajStrInsertC(Pstr, 0, "(aligned) "); } else if(ajCharMatchC(acdType[thys->Type].Name, "seqoutall")) { ajStrAppendC(Pstr, " set(s)"); if(gaps) ajStrInsertC(Pstr, 0, "(aligned) "); } else { if(gaps) ajStrInsertC(Pstr, 0, "(gapped) "); } ajStrFmtTitle(Pstr); ajStrAppendC(Pstr, " filename and optional format (output USA)"); return; } ID acdPromptSeq TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a sequence DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptSeq(AcdPAcd thys) { static ajint count=0; AjPStr tmptype = NULL; AjBool gaps = AJFALSE; AjPStr seqPrompt = NULL; AjPStr seqPromptAlt = NULL; const AjPStr knowntype; const AjPStr type = NULL; AjBool aligned=ajFalse; knowntype = acdKnowntypeDesc(thys); type = acdAttrValue(thys, "type"); if(ajCharPrefixC(acdType[thys->Type].Name,"seqset")) acdAttrToBool(thys, "aligned", ajFalse, &aligned); ajSeqTypeSummary(type, &tmptype, &gaps); seqPrompt = ajStrNewRes(32); seqPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&seqPromptAlt, "%S ", knowntype); if(ajStrGetLen(tmptype)) ajFmtPrintAppS(&seqPromptAlt, "%S ", tmptype); ajFmtPrintAppS(&seqPromptAlt, "sequence"); if(ajCharMatchC(acdType[thys->Type].Name, "seqset")) { ajStrAppendC(&seqPromptAlt, " set"); if(aligned) ajStrInsertC(&seqPromptAlt, 0, "(aligned) "); } else if(ajCharMatchC(acdType[thys->Type].Name, "seqsetall")) { ajStrAppendC(&seqPromptAlt, " set(s)"); if(aligned) ajStrInsertC(&seqPromptAlt, 0, "(aligned) "); } else if(ajCharMatchC(acdType[thys->Type].Name, "seqall")) { ajStrAppendC(&seqPromptAlt, "(s)"); if(gaps) ajStrInsertC(&seqPromptAlt, 0, "(gapped) "); } else { if(gaps) ajStrInsertC(&seqPromptAlt, 0, "(gapped) "); } ajFmtPrintS(&seqPrompt, "Input %S", seqPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, seqPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(seqPrompt), ajStrGetPtr(seqPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&tmptype); ajStrDel(&seqPrompt); ajStrDel(&seqPromptAlt); return thys->StdPrompt; } ID acdPromptTree TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a tree file DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptTree(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandardAlt(thys, "Input tree file", "tree file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptGraph TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a sequence DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptGraph(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " graph")) acdPromptStandardAppend(thys, " graph"); } else acdPromptStandard(thys, "graph type", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptFeatout TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a features output DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptFeatout(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(ajStrSuffixC(knowntype, " features")) acdPromptStandardAppend(thys, " features"); acdPromptStandardAppend(thys, " output"); } else acdPromptStandard(thys, "features output", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptAlign TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a report output DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptAlign(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(ajStrSuffixC(knowntype, " output")) acdPromptStandardAppend(thys, " alignment"); else acdPromptStandardAppend(thys, " output alignment"); } else acdPromptStandard(thys, "output alignment", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptReport TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a report output DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptReport(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(ajStrSuffixC(knowntype, " output")) acdPromptStandardAppend(thys, " report"); else acdPromptStandardAppend(thys, " output report"); } else acdPromptStandard(thys, "output report", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptSeqout TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a sequence output DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptSeqout(AcdPAcd thys) { static ajint count=0; AjPStr tmptype = NULL; AjBool gaps = AJFALSE; AjPStr seqPrompt = NULL; AjPStr seqPromptAlt = NULL; const AjPStr knowntype; const AjPStr type = NULL; AjBool aligned=ajFalse; knowntype = acdKnowntypeDesc(thys); type = acdAttrValue(thys, "type"); if(ajCharPrefixC(acdType[thys->Type].Name,"seqoutset")) acdAttrToBool(thys, "aligned", ajFalse, &aligned); ajSeqTypeSummary(type, &tmptype, &gaps); seqPrompt = ajStrNewRes(32); seqPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&seqPromptAlt, "%S ", knowntype); if(ajStrGetLen(tmptype)) ajFmtPrintAppS(&seqPromptAlt, "%S ", tmptype); ajFmtPrintAppS(&seqPromptAlt, "output sequence"); if(ajCharMatchC(acdType[thys->Type].Name, "seqoutset")) { ajStrAppendC(&seqPromptAlt, " set"); if(aligned) ajStrInsertC(&seqPromptAlt, 0, "(aligned) "); } else if(ajCharMatchC(acdType[thys->Type].Name, "seqoutsetall")) { ajStrAppendC(&seqPromptAlt, " set(s)"); if(aligned) ajStrInsertC(&seqPromptAlt, 0, "(aligned) "); } else if(ajCharMatchC(acdType[thys->Type].Name, "seqoutall")) { ajStrAppendC(&seqPromptAlt, "(s)"); if(gaps) ajStrInsertC(&seqPromptAlt, 0, "(gapped) "); } else { if(gaps) ajStrInsertC(&seqPromptAlt, 0, "(gapped) "); } ajFmtPrintS(&seqPrompt, "%S", seqPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, seqPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(seqPrompt), ajStrGetPtr(seqPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&tmptype); ajStrDel(&seqPrompt); ajStrDel(&seqPromptAlt); return thys->StdPrompt; } ID acdHelpTextObo TY static MO ajacd LB acd XX DE Sets the help text for this ACD object to be an obo term description XX PN [1] PA r thys const AcdPAcd PD Current ACD object. PX PN [2] PA w Pstr AjPStr* PD Help text PX RT void RD RX // static void acdHelpTextObo(const AcdPAcd thys, AjPStr* Pstr) { ajint maxreads; ajStrAssignClear(Pstr); acdAttrToInt(thys, "maxreads", 1, &maxreads); if(maxreads <= 1) ajStrAssignC(Pstr, "obo term"); else ajStrAssignC(Pstr, "obo term(s)"); ajStrFmtTitle(Pstr); ajStrAppendC(Pstr, " filename and optional format, or reference (input query)"); return; } ID acdHelpTextTaxon TY static MO ajacd LB acd XX DE Sets the help text for this ACD object to be an NCBI taxonomy entry XX PN [1] PA r thys const AcdPAcd PD Current ACD object. PX PN [2] PA w Pstr AjPStr* PD Help text PX RT void RD RX // static void acdHelpTextTaxon(const AcdPAcd thys, AjPStr* Pstr) { ajint maxreads; ajStrAssignClear(Pstr); acdAttrToInt(thys, "maxreads", 1, &maxreads); if(maxreads <= 1) ajStrAssignC(Pstr, "taxon"); else ajStrAssignC(Pstr, "taxon(s)"); ajStrFmtTitle(Pstr); ajStrAppendC(Pstr, " filename and optional format, or reference (input query)"); return; } ID acdHelpTextText TY static MO ajacd LB acd XX DE Sets the help text for this ACD object to be a text entry XX PN [1] PA r thys const AcdPAcd PD Current ACD object. PX PN [2] PA w Pstr AjPStr* PD Help text PX RT void RD RX // static void acdHelpTextText(const AcdPAcd thys, AjPStr* Pstr) { ajint maxreads; ajStrAssignClear(Pstr); acdAttrToInt(thys, "maxreads", 1, &maxreads); if(maxreads <= 1) ajStrAssignC(Pstr, "text"); else ajStrAssignC(Pstr, "text(s)"); ajStrFmtTitle(Pstr); ajStrAppendC(Pstr, " filename and optional format, or reference (input query)"); return; } ID acdHelpTextUrl TY static MO ajacd LB acd XX DE Sets the help text for this ACD object to be a URL data entry XX PN [1] PA r thys const AcdPAcd PD Current ACD object. PX PN [2] PA w Pstr AjPStr* PD Help text PX RT void RD RX // static void acdHelpTextUrl(const AcdPAcd thys, AjPStr* Pstr) { ajint maxreads; ajStrAssignClear(Pstr); acdAttrToInt(thys, "maxreads", 1, &maxreads); if(maxreads <= 1) ajStrAssignC(Pstr, "url"); else ajStrAssignC(Pstr, "url(s)"); ajStrFmtTitle(Pstr); ajStrAppendC(Pstr, " filename and optional format, or reference (input query)"); return; } ID acdHelpTextVariation TY static MO ajacd LB acd XX DE Sets the help text for this ACD object to be a variation data entry XX PN [1] PA r thys const AcdPAcd PD Current ACD object. PX PN [2] PA w Pstr AjPStr* PD Help text PX RT void RD RX // static void acdHelpTextVariation(const AcdPAcd thys, AjPStr* Pstr) { ajint maxreads; ajStrAssignClear(Pstr); acdAttrToInt(thys, "maxreads", 1, &maxreads); if(maxreads <= 1) ajStrAssignC(Pstr, "variation"); else ajStrAssignC(Pstr, "variation(s)"); ajStrFmtTitle(Pstr); ajStrAppendC(Pstr, " filename and optional format, or reference (input query)"); return; } ID acdPromptAssembly TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an assembly DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptAssembly(AcdPAcd thys) { static ajint count=0; AjPStr assemPrompt = NULL; AjPStr assemPromptAlt = NULL; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); assemPrompt = ajStrNewRes(32); assemPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&assemPromptAlt, "%S ", knowntype); ajFmtPrintAppS(&assemPromptAlt, "assembly"); ajFmtPrintS(&assemPrompt, "Input %S", assemPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, assemPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(assemPrompt), ajStrGetPtr(assemPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&assemPrompt); ajStrDel(&assemPromptAlt); return thys->StdPrompt; } ID acdPromptObo TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an obo term DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptObo(AcdPAcd thys) { static ajint count=0; AjPStr oboPrompt = NULL; AjPStr oboPromptAlt = NULL; const AjPStr knowntype; ajint maxreads = 0; acdAttrToInt(thys, "maxreads", 1, &maxreads); knowntype = acdKnowntypeDesc(thys); oboPrompt = ajStrNewRes(32); oboPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&oboPromptAlt, "%S ", knowntype); ajFmtPrintAppS(&oboPromptAlt, "obo term"); if(maxreads > 1) ajStrAppendC(&oboPromptAlt, "(s)"); ajFmtPrintS(&oboPrompt, "Input %S", oboPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, oboPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(oboPrompt), ajStrGetPtr(oboPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&oboPrompt); ajStrDel(&oboPromptAlt); return thys->StdPrompt; } ID acdPromptOutassembly TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutassembly(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " output file"); } else acdPromptStandard(thys, "assembly output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutcodon TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutcodon(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " output file"); } else acdPromptStandard(thys, "codon usage output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutcpdb TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutcpdb(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " output file"); } else acdPromptStandard(thys, "clean PDB output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutdata TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutdata(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " output file"); } else acdPromptStandard(thys, "output data file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutdir TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutdir(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); acdPromptStandardAppend(thys, " output directory"); } else acdPromptStandard(thys, "output directory", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutdiscrete TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutdiscrete(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " output discrete data file"); } else acdPromptStandard(thys, "discrete data output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutdistance TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutdistance(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " distance data output file"); } else acdPromptStandard(thys, "output distance data file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutfreq TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutfreq(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " frequency data output file"); } else acdPromptStandard(thys, "frequency data output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutmatrix TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutmatrix(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " matrix output file"); } else acdPromptStandard(thys, "matrix output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutobo TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutobo(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " obo output file"); } else acdPromptStandard(thys, "obo output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutproperties TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutproperties(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " properties data output file"); } else acdPromptStandard(thys, "properties data output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutrefseq TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutrefseq(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " output file"); } else acdPromptStandard(thys, "reference sequence output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutresource TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutresource(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " data resource output file"); } else acdPromptStandard(thys, "data resource output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutscop TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutscop(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " scop output file"); } else acdPromptStandard(thys, "scop output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOuttaxon TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOuttaxon(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " taxon output file"); } else acdPromptStandard(thys, "taxon output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOuttext TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOuttext(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " text output file"); } else acdPromptStandard(thys, "text output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOuttree TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOuttree(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " tree output file"); } else acdPromptStandard(thys, "tree output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOuturl TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOuturl(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " URL output file"); } else acdPromptStandard(thys, "URL output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptOutvariation TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a simple DE prompt with "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutvariation(AcdPAcd thys) { static ajint count=0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); acdPromptStandardAppend(thys, " variation output file"); } else acdPromptStandard(thys, "variation output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptRefseq TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a reference sequence DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptRefseq(AcdPAcd thys) { static ajint count=0; AjPStr refseqPrompt = NULL; AjPStr refseqPromptAlt = NULL; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); refseqPrompt = ajStrNewRes(32); refseqPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&refseqPromptAlt, "%S ", knowntype); ajFmtPrintAppS(&refseqPromptAlt, "reference sequence"); ajFmtPrintS(&refseqPrompt, "Input %S", refseqPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, refseqPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(refseqPrompt), ajStrGetPtr(refseqPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&refseqPrompt); ajStrDel(&refseqPromptAlt); return thys->StdPrompt; } ID acdPromptTaxon TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an NCBI taxonomy entry DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptTaxon(AcdPAcd thys) { static ajint count=0; AjPStr taxPrompt = NULL; AjPStr taxPromptAlt = NULL; const AjPStr knowntype; ajint maxreads = 0; acdAttrToInt(thys, "maxreads", 1, &maxreads); knowntype = acdKnowntypeDesc(thys); taxPrompt = ajStrNewRes(32); taxPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&taxPromptAlt, "%S ", knowntype); ajFmtPrintAppS(&taxPromptAlt, "taxon"); if(maxreads > 1) ajStrAppendC(&taxPromptAlt, "(s)"); ajFmtPrintS(&taxPrompt, "Input %S", taxPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, taxPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(taxPrompt), ajStrGetPtr(taxPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&taxPrompt); ajStrDel(&taxPromptAlt); return thys->StdPrompt; } ID acdPromptText TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a text entry DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptText(AcdPAcd thys) { static ajint count=0; AjPStr taxPrompt = NULL; AjPStr taxPromptAlt = NULL; const AjPStr knowntype; ajint maxreads = 0; acdAttrToInt(thys, "maxreads", 1, &maxreads); knowntype = acdKnowntypeDesc(thys); taxPrompt = ajStrNewRes(32); taxPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&taxPromptAlt, "%S ", knowntype); ajFmtPrintAppS(&taxPromptAlt, "text"); if(maxreads > 1) ajStrAppendC(&taxPromptAlt, "(s)"); ajFmtPrintS(&taxPrompt, "Input %S", taxPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, taxPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(taxPrompt), ajStrGetPtr(taxPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&taxPrompt); ajStrDel(&taxPromptAlt); return thys->StdPrompt; } ID acdPromptUrl TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a URL data entry DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptUrl(AcdPAcd thys) { static ajint count=0; AjPStr urlPrompt = NULL; AjPStr urlPromptAlt = NULL; const AjPStr knowntype; ajint maxreads = 0; acdAttrToInt(thys, "maxreads", 1, &maxreads); knowntype = acdKnowntypeDesc(thys); urlPrompt = ajStrNewRes(32); urlPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&urlPromptAlt, "%S ", knowntype); ajFmtPrintAppS(&urlPromptAlt, "url"); if(maxreads > 1) ajStrAppendC(&urlPromptAlt, "(s)"); ajFmtPrintS(&urlPrompt, "Input %S", urlPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, urlPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(urlPrompt), ajStrGetPtr(urlPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&urlPrompt); ajStrDel(&urlPromptAlt); return thys->StdPrompt; } ID acdPromptVariation TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a variation entry DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptVariation(AcdPAcd thys) { static ajint count=0; AjPStr varPrompt = NULL; AjPStr varPromptAlt = NULL; const AjPStr knowntype; ajint maxreads = 0; acdAttrToInt(thys, "maxreads", 1, &maxreads); knowntype = acdKnowntypeDesc(thys); varPrompt = ajStrNewRes(32); varPromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&varPromptAlt, "%S ", knowntype); ajFmtPrintAppS(&varPromptAlt, "variation"); if(maxreads > 1) ajStrAppendC(&varPromptAlt, "(s)"); ajFmtPrintS(&varPrompt, "Input %S", varPromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, varPromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(varPrompt), ajStrGetPtr(varPromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&varPrompt); ajStrDel(&varPromptAlt); return thys->StdPrompt; } ID acdPromptStandard TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an output DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX PN [2] PA r type const char* PD Data type for prompt PX PN [3] PA w count ajint* PD count for number of calls PX RT void RD RX // static void acdPromptStandard(AcdPAcd thys, const char* type, ajint* count) { AjPStr *prompt; (*count)++; acdLog("acdPromptStandard '%s' count %d\n", type, *count); if(!thys->DefStr) { acdLog("acdPromptStandard '%s' thys->DefStr NULL\n", type); return; } prompt = &thys->DefStr[DEF_PROMPT]; if(ajStrGetLen(*prompt)) { acdLog("acdPromptStandard '%s' found thys->DefStr[DEF_PROMPT] '%S'\n", type, *prompt); /*ajStrTrace(*prompt);*/ /*ajStrTrace(thys->DefStr[DEF_PROMPT]);*/ return; } switch(*count) { case 1: ajFmtPrintS(&thys->StdPrompt, "%s", type); ajStrFmtTitle(&thys->StdPrompt); break; case 2: ajFmtPrintS(&thys->StdPrompt, "Second %s", type); break; case 3: ajFmtPrintS(&thys->StdPrompt, "Third %s", type); break; case 11: case 12: case 13: ajFmtPrintS(&thys->StdPrompt, "%dth %s", count, type); break; default: switch(*count % 10) { case 1: ajFmtPrintS(&thys->StdPrompt, "%dst %s", count, type); break; case 2: ajFmtPrintS(&thys->StdPrompt, "%dnd %s", count, type); break; case 3: ajFmtPrintS(&thys->StdPrompt, "%drd %s", count, type); break; default: ajFmtPrintS(&thys->StdPrompt, "%dth %s", count, type); break; } break; } return; } ID acdPromptStandardAlt TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to as specified, with DE "second", "third" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX PN [2] PA r firsttype const char* PD Data type for prompt first time PX PN [3] PA r type const char* PD Data type for prompt subsequent times PX PN [4] PA w count ajint* PD count for number of calls PX RT void RD RX // static void acdPromptStandardAlt(AcdPAcd thys, const char* firsttype, const char* type, ajint* count) { AjPStr *prompt; (*count)++; acdLog("acdPromptStandardAlt '%s' count %d\n", type, *count); if(!thys->DefStr) { acdLog("acdPromptStandardAlt '%s' thys->DefStr NULL\n", type); return; } prompt = &thys->DefStr[DEF_PROMPT]; if(ajStrGetLen(*prompt)) { acdLog("acdPromptStandardAlt '%s' " "found thys->DefStr[DEF_PROMPT] '%S'\n", type, *prompt); /*ajStrTrace(*prompt);*/ /*ajStrTrace(thys->DefStr[DEF_PROMPT]);*/ return; } switch(*count) { case 1: ajFmtPrintS(&thys->StdPrompt, "%s", firsttype); break; case 2: ajFmtPrintS(&thys->StdPrompt, "Second %s", type); break; case 3: ajFmtPrintS(&thys->StdPrompt, "Third %s", type); break; case 11: case 12: case 13: ajFmtPrintS(&thys->StdPrompt, "%dth %s", count, type); break; default: switch(*count % 10) { case 1: ajFmtPrintS(&thys->StdPrompt, "%dst %s", count, type); break; case 2: ajFmtPrintS(&thys->StdPrompt, "%dnd %s", count, type); break; case 3: ajFmtPrintS(&thys->StdPrompt, "%drd %s", count, type); break; default: ajFmtPrintS(&thys->StdPrompt, "%dth %s", count, type); break; } break; } return; } ID acdPromptStandardAppend TY static MO ajacd LB acd XX DE Appends to the default prompt for this ACD object XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX PN [2] PA r str const char* PD Suffix to append to prompt PX RT void RD RX // static void acdPromptStandardAppend(AcdPAcd thys, const char* str) { ajStrAppendC(&thys->StdPrompt, str); } ID acdPromptStandardS TY static MO ajacd LB acd XX DE Appends to the default prompt for this ACD object XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX PN [2] PA r str const AjPStr PD Data type for prompt PX RT void RD RX // static void acdPromptStandardS(AcdPAcd thys, const AjPStr str) { ajStrAssignS(&thys->StdPrompt, str); } ID acdPromptOutfile TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an output DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptOutfile(AcdPAcd thys) { static ajint count = 0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(ajStrSuffixC(knowntype, " output")) acdPromptStandardAppend(thys, " file"); else acdPromptStandardAppend(thys, " output file"); } else acdPromptStandard(thys, "output file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptInfile TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an input DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptInfile(AcdPAcd thys) { static ajint count = 0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandard(thys, "input file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptDatafile TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an input data DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptDatafile(AcdPAcd thys) { static ajint count = 0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(ajStrSuffixC(knowntype, " data")) acdPromptStandardAppend(thys, " file"); else acdPromptStandardAppend(thys, " data file"); } else acdPromptStandard(thys, "data file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptMatrix TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an input data DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptMatrix(AcdPAcd thys) { static ajint count = 0; AjBool protein = ajFalse; const AjPStr knowntype; acdAttrToBool(thys, "protein", ajFalse, &protein); knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else { if(acdDoValid) acdPromptStandard(thys, "comparison matrix file", &count); else { if(protein) acdPromptStandard(thys, "(protein) comparison matrix file", &count); else acdPromptStandard(thys, "(nucleotide) comparison matrix file", &count); } } if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptDiscretestates TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an input discrete states DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptDiscretestates(AcdPAcd thys) { static ajint count = 0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandard(thys, "discrete states file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptDistances TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an input distances DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptDistances(AcdPAcd thys) { static ajint count = 0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandard(thys, "distances file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptFrequencies TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an input frequencies DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptFrequencies(AcdPAcd thys) { static ajint count = 0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandard(thys, "frequencies file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptProperties TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be an input properties DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptProperties(AcdPAcd thys) { static ajint count = 0; const AjPStr knowntype; knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " file")) acdPromptStandardAppend(thys, " file"); } else acdPromptStandard(thys, "properties file", &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptPattern TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a pattern string or DE file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptPattern(AcdPAcd thys) { static ajint count = 0; AjPStr type = NULL; const AjPStr knowntype; acdAttrToStr(thys, "type", "", &type); knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " pattern")) acdPromptStandardAppend(thys, " pattern"); } else { if(ajStrPrefixCaseC(type, "p")) acdPromptStandard(thys, "protein pattern string or @file", &count); else if(ajStrPrefixCaseC(type, "n")) acdPromptStandard(thys, "nucleotide pattern string or @file", &count); else acdPromptStandard(thys, "pattern string or @file", &count); } if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdPromptRegexp TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a regular expression DE string or file with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptRegexp(AcdPAcd thys) { static ajint count = 0; AjPStr type = NULL; const AjPStr knowntype; acdAttrToStr(thys, "type", "", &type); knowntype = acdKnowntypeDesc(thys); if(ajStrGetLen(knowntype)) { count++; acdPromptStandardS(thys, knowntype); if(!ajStrSuffixC(knowntype, " regular expression")) acdPromptStandardAppend(thys, " regular expression"); } else { if(ajStrPrefixCaseC(type, "p")) acdPromptStandard(thys, "protein regular expression string or @file", &count); else if(ajStrPrefixCaseC(type, "n")) acdPromptStandard(thys, "nucleotide regular expression string or @file", &count); else acdPromptStandard(thys, "regular expression string or @file", &count); } if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); return thys->StdPrompt; } ID acdHelpTextResource TY static MO ajacd LB acd XX DE Sets the help text for this ACD object to be a data resource description XX PN [1] PA r thys const AcdPAcd PD Current ACD object. PX PN [2] PA w Pstr AjPStr* PD Help text PX RT void RD RX // static void acdHelpTextResource(const AcdPAcd thys, AjPStr* Pstr) { ajint maxreads = 0; ajStrAssignClear(Pstr); acdAttrToInt(thys, "maxreads", 1, &maxreads); if(maxreads <= 1) ajStrAssignC(Pstr, "data resource"); else ajStrAssignC(Pstr, "data resource(s)"); ajStrFmtTitle(Pstr); ajStrAppendC(Pstr, " filename and optional format, or reference (input query)"); return; } ID acdPromptResource TY static MO ajacd LB acd XX DE Sets the default prompt for this ACD object to be a data resource DE prompt with "first", "second" etc. added. XX PN [1] PA u thys AcdPAcd PD Current ACD object. PX RT const AjPStr RD Generated standard prompt RX // static const AjPStr acdPromptResource(AcdPAcd thys) { static ajint count=0; AjPStr resourcePrompt = NULL; AjPStr resourcePromptAlt = NULL; const AjPStr knowntype; ajint maxreads = 0; acdAttrToInt(thys, "maxreads", 1, &maxreads); knowntype = acdKnowntypeDesc(thys); resourcePrompt = ajStrNewRes(32); resourcePromptAlt = ajStrNewRes(32); if(ajStrGetLen(knowntype)) ajFmtPrintAppS(&resourcePromptAlt, "%S ", knowntype); ajFmtPrintAppS(&resourcePromptAlt, "data resource"); if(maxreads > 1) ajStrAppendC(&resourcePromptAlt, "(s)"); ajFmtPrintS(&resourcePrompt, "Input %S", resourcePromptAlt); if(knowntype) { count++; acdPromptStandardS(thys, resourcePromptAlt); } else acdPromptStandardAlt(thys, ajStrGetPtr(resourcePrompt), ajStrGetPtr(resourcePromptAlt), &count); if(!acdAttrTestDefined(thys, "default") && acdAttrTestDefined(thys, "nullok")) acdPromptStandardAppend(thys, " (optional)"); ajStrDel(&resourcePrompt); ajStrDel(&resourcePromptAlt); return thys->StdPrompt; } ID acdCodeGet TY static MO ajacd LB acd XX DE Translates a code into a message text using the code table DE for the current language. XX PN [1] PA r code const AjPStr PD Code name PX PN [2] PA w msg AjPStr* PD Message text for this code in current language PX RT AjBool RD ajTrue on success RX // static AjBool acdCodeGet(const AjPStr code, AjPStr *msg) { const AjPStr value; /* not static - copy of a table text */ AjBool ret = ajFalse; acdLog("acdCodeGet ('%S')\n", code); if(!acdCodeSet) acdCodeInit(); value = ajTableFetchS(acdCodeTable, code); if(value) { ajStrAssignS(msg, value); acdLog("%S value '%S'\n", code, *msg); ret = ajTrue; } return ret; } ID acdCodeDef TY static MO ajacd LB acd XX DE Generates a default code name of 'def' + qualifier type. DE Translates into a message text using the code table DE for the current language. XX PN [1] PA r thys const AcdPAcd PD Current ACD object PX PN [2] PA w msg AjPStr* PD Message text for default message PD in current language PX RT AjBool RD ajTrue on success RX // static AjBool acdCodeDef(const AcdPAcd thys, AjPStr *msg) { AjPStr code = NULL; AjPStr value = NULL; AjBool ret = ajFalse; acdLog("acdCodeDef '%s'\n", acdType[thys->Type].Name); if(!acdCodeSet) acdCodeInit(); code = ajStrNewC("def"); ajStrAppendC(&code, acdType[thys->Type].Name); ajStrFmtLower(&code); acdLog("look for defcode '%S'\n", code); if(acdCodeGet(code, &value)) { ajFmtPrintS(msg, "-%S : %S", thys->Name, value); ajStrDel(&value); ret = ajTrue; } else acdLog("defcode not found '%S'\n", code); ajStrDel(&code); return ret; } ID acdHelpCodeDef TY static MO ajacd LB acd XX DE Generates a default code name of 'help' + qualifier type. DE Translates into a message text using the code table DE for the current language. XX PN [1] PA r thys const AcdPAcd PD Current ACD object PX PN [2] PA w msg AjPStr* PD Help text in current language PX RT AjBool RD ajTrue on success RX // static AjBool acdHelpCodeDef(const AcdPAcd thys, AjPStr *msg) { AjPStr code = NULL; AjPStr value = NULL; AjBool ret = ajFalse; acdLog("acdHelpCodeDef '%s'\n", acdType[thys->Type].Name); if(!acdCodeSet) acdCodeInit(); code = ajStrNewC("help"); ajStrAppendC(&code, acdType[thys->Type].Name); ajStrFmtLower(&code); acdLog("look for helpcode '%S'\n", code); if(acdCodeGet(code, &value)) { ajFmtPrintS(msg, "%S", value); ajStrDel(&value); ret = ajTrue; } else acdLog("helpcode not found '%S'\n", code); ajStrDel(&code); return ret; } ID acdCodeInit TY static MO ajacd LB acd XX DE Sets up the code file data for the current language when needed XX RT void RD RX // static void acdCodeInit(void) { AjPFile codeFile = NULL; AjPStr codeFName = NULL; AjPStr codeRoot = NULL; AjPStr codeRootInst = NULL; AjPStr codePack = NULL; AjPStr codeCode = NULL; AjPStr codeValue = NULL; AjPStr codeLine = NULL; AjPStr codeText = NULL; AjPStr codeLanguage = NULL; AjPStr tmpstr = NULL; AjPRegexp codexp = NULL; if(acdCodeSet) return; ajStrAssignS(&codePack, ajNamValuePackage()); ajStrAssignS(&codeRootInst,ajNamValueInstalldir()); ajDirnameFix(&codeRootInst); if(!ajNamGetValueC("language", &codeLanguage)) ajStrAssignC(&codeLanguage, "english"); if(ajNamGetValueC("acdroot", &codeRoot)) { ajDirnameFix(&codeRoot); ajFmtPrintS(&codeFName, "%Scodes.%S", codeRoot, codeLanguage); codeFile = ajFileNewInNameS(codeFName); acdLog("Code file in acdroot: '%S'\n", codeFName); } else { ajFmtPrintS(&codeFName, "%Sshare/%S/acd/codes.%S", codeRootInst, codePack, codeLanguage); acdLog("Code file installed: '%S'\n", codeFName); codeFile = ajFileNewInNameS(codeFName); if(!codeFile) { acdLog("Code file '%S' not opened\n", codeFName); ajStrAssignS(&codeRoot, ajNamValueRootdir()); ajDirnameFix(&codeRoot); ajFmtPrintS(&codeFName, "%Sacd/codes.%S", codeRoot, codeLanguage); acdLog("Code file from source dir: '%S'\n", codeFName); codeFile = ajFileNewInNameS(codeFName); } } if(!codeFile) /* test acdc-codemissing */ ajWarn("Code file %S not found", codeFName); else acdLog("Code file %F used\n", codeFile); codeText = ajStrNew(); /* fix by Nicolas Joly */ while(codeFile && ajReadlineTrim(codeFile, &codeLine)) if(ajStrCutComments(&codeLine)) { ajStrAppendS(&codeText, codeLine); ajStrAppendC(&codeText, " "); } ajFileClose(&codeFile); ajStrDel(&codeLine); acdCodeTable = ajTablestrNewCase(100); codexp = ajRegCompC("^ *([^ ]+) +\"([^\"]*)\""); while(ajRegExec(codexp, codeText)) { codeCode = codeValue = NULL; /* need to save in table each time */ ajRegSubI(codexp, 1, &codeCode); ajRegSubI(codexp, 2, &codeValue); ajStrFmtLower(&codeCode); ajTablePut(acdCodeTable, codeCode, codeValue); acdLog("add to table %S '%S'\n", codeCode, codeValue); ajRegPost(codexp, &tmpstr); ajStrAssignS(&codeText, tmpstr); } if(!ajStrIsWhite(codeText)) /* test acdc-codebad */ ajDie("Bad format in codes file %S after '%S \"%S\"'", codeFName, codeCode, codeValue); codeCode = codeValue = NULL; /* saved in the table */ ajRegFree(&codexp); ajStrDel(&codeText); ajStrDel(&codeFName); ajStrDel(&codeRoot); ajStrDel(&codeRootInst); ajStrDel(&codePack); ajStrDel(&codeLanguage); ajStrDel(&tmpstr); acdCodeSet = ajTrue; return; } ID acdKnowntypeInit TY static MO ajacd LB acd XX DE Sets up the known type data XX RT void RD RX // static void acdKnowntypeInit(void) { if(acdKnowntypeSet) return; acdReadKnowntype(&acdKnowntypeDescTable, &acdKnowntypeTypeTable); acdKnowntypeSet = ajTrue; return; } ID acdSetQualAppl TY static MO ajacd LB acd XX DE Sets internal variables for the application booleans -debug etc. XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r val AjBool PD Value PX RT AjBool RD ajTrue if this was an application-wide variable. RX // static AjBool acdSetQualAppl(const AcdPAcd thys, AjBool val) { ajint i = 0; AjBool setval; AjPStr setstr = NULL; static AjPStr valstr = NULL; static AjPStr bufstr = NULL; acdLog("acdSetQualAppl '%S'\n", thys->Name); for(i=0; acdQualAppl[i].Name; i++) { if(ajStrMatchC(thys->Name, acdQualAppl[i].Name)) { if(thys->Defined) /* User put it on the command line */ { setval = val; acdLog("Appl qualifier defined %S = %b\n", thys->Name, setval); } else /* look for a variable */ { ajFmtPrintS(&setstr, "%S", thys->Name); if(ajNamGetValueS(setstr, &valstr)) { ajStrToBool(valstr, &setval); acdLog("Appl qualifier variable %S = %b\n", setstr, setval); } else /* nothing found, use the default value */ setval = val; ajStrDel(&setstr); } switch(i) /* see acdQualAppl for the correct order */ { case 0: acdAuto = setval; break; case 1: acdStdout = setval; break; case 2: acdFilter = setval; if(acdFilter) { acdAuto = ajTrue; acdStdout = ajTrue; } break; case 3: acdOptions = setval; break; case 4: acdDebug = setval; /* acdLog("acdSetQualAppl acdDebug %B\n", acdDebug); */ acdDebugSet = ajTrue; if(ajNamGetValueC("debugbuffer", &bufstr)) { ajStrToBool(bufstr, &acdDebugBuffer); } break; case 5: acdVerbose = setval; break; case 6: acdDoHelp = setval; break; case 7: AjErrorLevel.warning = setval; break; case 8: AjErrorLevel.error = setval; break; case 9: AjErrorLevel.fatal = setval; break; case 10: AjErrorLevel.die = setval; break; } return ajTrue; } } return ajFalse; } ID acdSelectPrompt TY static MO ajacd LB acd XX DE Present the options as a simple numbered list XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT void RD RX // static void acdSelectPrompt(const AcdPAcd thys) { const AjPStr hdrstr; AjPStr delim = NULL; AjPStr value = NULL; AjPStrTok handle; AjPStr line = NULL; static const char* white = " \t\n\r"; ajint i = 0; if(acdAuto) return; hdrstr = acdAttrValue(thys, "header"); if(ajStrGetLen(hdrstr)) ajUserDumpS(hdrstr); ajStrAssignS(&delim,acdAttrValue(thys, "delimiter")); if(!ajStrGetLen(delim)) ajStrAssignC(&delim, ";"); ajStrAssignS(&value, acdAttrValue(thys, "values")); acdVarResolve(&value); if(!ajStrGetLen(value)) if(!acdKnownValueSelect(thys, &value)) acdError("No value defined for selection"); handle = ajStrTokenNewS(value, delim); while(ajStrTokenNextFind(&handle, &line)) { ajStrTrimC(&line, white); ajUser(" %5d : %S", ++i, line); } ajStrTokenDel(&handle); ajStrDel(&line); ajStrDel(&value); ajStrDel(&delim); return; } ID acdListPrompt TY static MO ajacd LB acd XX DE Present the options as a list with option codes selectable by the user XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT void RD RX // static void acdListPrompt(const AcdPAcd thys) { const AjPStr hdrstr; AjPStr codedelim = NULL; AjPStr delim = NULL; AjPStr value = NULL; AjPStrTok handle; AjPStrTok codehandle; AjPStr line = NULL; AjPStr code = NULL; AjPStr desc = NULL; ajuint margin = 8; static const char* white = " \t\n\r"; if(acdAuto) return; hdrstr = acdAttrValue(thys, "header"); if(ajStrGetLen(hdrstr)) ajUserDumpS(hdrstr); ajStrAssignS(&delim,acdAttrValue(thys, "delimiter")); if(!ajStrGetLen(delim)) { ajStrAssignC(&delim, ";"); } ajStrAssignS(&codedelim,acdAttrValue(thys, "codedelimiter")); if(!ajStrGetLen(codedelim)) { ajStrAssignC(&codedelim, ":"); } ajStrAssignS(&value, acdAttrValue(thys, "values")); acdVarResolve(&value); if(!ajStrGetLen(value)) if(!acdKnownValueList(thys, &value)) acdError("No value defined for list"); handle = ajStrTokenNewS(value, delim); while(ajStrTokenNextFind(&handle, &line)) { codehandle = ajStrTokenNewS(line, codedelim); ajStrTokenNextParse(&codehandle, &code); ajStrTrimC(&code, white); if(ajStrGetLen(code) > margin) margin = ajStrGetLen(code); ajStrTokenDel(&codehandle); } ajStrTokenAssignS(&handle, value, delim); while(ajStrTokenNextFind(&handle, &line)) { codehandle = ajStrTokenNewS(line, codedelim); ajStrTokenNextParse(&codehandle, &code); ajStrTokenNextParseS(&codehandle, delim, &desc); ajStrTrimC(&code, white); ajStrTrimC(&desc, white); ajUser(" %*S : %S", margin, code, desc); ajStrTokenDel(&codehandle); } ajStrTokenDel(&handle); ajStrDel(&line); ajStrDel(&code); ajStrDel(&desc); ajStrDel(&delim); ajStrDel(&codedelim); ajStrDel(&value); return; } ID acdListValue TY static MO ajacd LB acd XX DE Checks the user setting against the menu list of codes and descriptions. DE DE An unambiguous match to the codes counts as valid. DE If this fails, an unambiguous match to the descriptions counts. XX PN [1] PA r thys const AcdPAcd PD ACD Object PX PN [2] PA r min ajint PD Minimum number of values required PX PN [3] PA r max ajint PD Maximum number of values required PX PN [4] PA r reply const AjPStr PD Default value PX RT AjPStr* RD Array of accepted matches, ending with a NULL. RX // static AjPStr* acdListValue(const AcdPAcd thys, ajint min, ajint max, const AjPStr reply) { AjPStr* val = NULL; AjPStr codedelim = NULL; AjPStr delim = NULL; AjPStr value = NULL; AjBool exactcase; AjPStrTok handle; AjPStrTok rephandle; AjPStrTok codehandle; AjPStr line = NULL; AjPStr code = NULL; AjPStr desc = NULL; AjPList list = NULL; AjPStr repstr = NULL; AjPStr hitstr = NULL; AjPStr validstr = NULL; AjPStr hitstr1 = NULL; AjPStr hitstr2 = NULL; AjPStr ambigList = NULL; AjPStr repdelim = NULL; static const char* white = " \t\n\r"; ajint k = 0; ajint ifound = 0; ajint jfound = 0; ajint ilen; ajint itoken = 0; AjBool ok = ajTrue; list = ajListstrNew(); acdAttrToBool(thys, "casesensitive", ajFalse, &exactcase); acdAttrValueStr(thys, "delimiter", ";", &delim); acdAttrValueStr(thys, "codedelimiter", ":", &codedelim); if(!repdelim) { repdelim = ajStrNewRes(10); ajStrAssignC(&repdelim, ","); } ajStrAssignS(&value,acdAttrValue(thys, "values")); acdVarResolve(&value); if(!ajStrGetLen(value)) if(!acdKnownValueList(thys, &value)) acdError("No value defined for list"); ambigList = ajStrNew(); ajStrAssignClear(&validstr); rephandle = ajStrTokenNewS(reply, repdelim); while(ajStrTokenNextParse(&rephandle, &repstr)) { itoken++; acdLog("testing '%S'\n", repstr); handle = ajStrTokenNewS(value, delim); ifound = jfound = 0; ajStrAssignClear(&validstr); if(ajStrMatchC(repstr, "*")) { while(ajStrTokenNextFind(&handle, &line)) { codehandle = ajStrTokenNewS(line, codedelim); ajStrTokenNextParse(&codehandle, &code); ajStrTrimC(&code, white); ajStrAssignS(&hitstr, code); ajListstrPushAppend(list, hitstr); hitstr = NULL; ajStrTokenDel(&codehandle); } } else { while(ajStrTokenNextFind(&handle, &line)) { codehandle = ajStrTokenNewS(line, codedelim); ajStrTokenNextParse(&codehandle, &code); ajStrTokenNextParseS(&codehandle, delim, &desc); ajStrTrimC(&code, white); ajStrTrimC(&desc, white); if(ajStrGetLen(validstr)) ajStrAppendK(&validstr, ','); ajStrAppendS(&validstr, code); if(ajStrMatchS(code, repstr) || (!exactcase && ajStrMatchCaseS(code, repstr))) { ifound = 1; ajStrAssignS(&hitstr1, code); break; } if(ajStrMatchS(desc, repstr) || (!exactcase && ajStrMatchCaseS(desc, repstr))) { jfound = 1; ajStrAssignS(&hitstr2, code); break; } if(ajStrPrefixS(code, repstr) || (!exactcase && ajStrPrefixCaseS(code, repstr))) { ifound++; ajStrAssignS(&hitstr1, code); acdAmbigApp(&ambigList, code); } if(ajStrPrefixS(desc, repstr) || (!exactcase && ajStrPrefixCaseS(desc, repstr))) { jfound++; ajStrAssignS(&hitstr2, code); acdAmbigApp(&ambigList, desc); } ajStrTokenDel(&codehandle); codehandle = NULL; } /* end of while */ ajStrTokenDel(&codehandle); if(ifound == 1) { ajStrAssignS(&hitstr,hitstr1); ajListstrPushAppend(list, hitstr); hitstr = NULL; } else if(jfound == 1) { ajStrAssignS(&hitstr, hitstr2); ajListstrPushAppend(list, hitstr); hitstr = NULL; } else { if(ifound || jfound) /* test acdc-listambig1 acdc-listambig2 */ ajErr("'%S' is ambiguous (%S)", repstr, ambigList); else /* test acdc-listbad */ ajErr("'%S' is not a valid menu option\n" "Accepted short codes are: %S", repstr, validstr); ok = ajFalse; break; } ajStrTokenDel(&handle); } } ajStrTokenDel(&rephandle); ajStrDel(&repstr); ilen = (ajuint) ajListstrGetLength(list); acdLog("Found %d matches OK: %b min: %d max: %d\n", ilen, ok, min, max); if(ok) { if(ilen < min) { /* test acdc-listmin */ if(min <= 1) ajErr("Menu needs %d value", min); else ajErr("Menu needs %d values", min); ok = ajFalse; } if(ilen > max) /* test acdc-listmax */ { if(max <= 1) ajErr("Menu allows no more than %d value", max); else ajErr("Menu allows no more than %d values", max); ok = ajFalse; } } if(ok) { AJCNEW0(val, ilen+1); for(k = 0; k < ilen; k++) { ajListstrPop(list, &val[k]); acdLog("Accept[%d]: '%S'\n", k,val[k]); } } acdLog("Found %d matches\n", ilen); acdLog("Menu length now %d\n", ajListstrGetLength(list)); if(ok) acdLog("Before return val[0] '%S'\n", val[0]); ajListstrFreeData(&list); ajStrDel(&delim); ajStrDel(&codedelim); ajStrDel(&repdelim); ajStrDel(&line); ajStrDel(&code); ajStrDel(&desc); ajStrDel(&ambigList); ajStrDel(&hitstr1); ajStrDel(&hitstr2); ajStrDel(&repstr); ajStrDel(&validstr); ajStrDel(&value); if(!ok) return NULL; return val; } ID acdSelectValue TY static MO ajacd LB acd XX DE Checks the user setting against the selection list set of codes DE DE An unambiguous match to the codes counts as valid. DE If this fails, an unambiguous match to the descriptions counts. XX PN [1] PA r thys const AcdPAcd PD ACD Object PX PN [2] PA r min ajint PD Minimum number of values required PX PN [3] PA r max ajint PD Maximum number of values required PX PN [4] PA r reply const AjPStr PD Default value PX RT AjPStr* RD Array of accepted matches, ending with a NULL. RX // static AjPStr* acdSelectValue(const AcdPAcd thys, ajint min, ajint max, const AjPStr reply) { AjPStr *val = NULL; AjPStr delim=NULL; const AjPStr tmpstr = NULL; AjPStr value = NULL; AjBool exactcase; AjPStrTok handle = NULL; AjPStrTok rephandle = NULL; AjPStr line = NULL; AjPStr code = NULL; AjPStr desc = NULL; AjPList list = NULL; AjPStr repstr = NULL; AjPStr hitstr = NULL; AjPStr validstr = NULL; AjPStr hitstr2 = NULL; AjPStr ambigList = NULL; AjPStr repdelim = NULL; static const char* white = " \t\n\r"; ajint i = 0; ajint k = 0; ajint jfound = 0; ajint icnt = 0; ajint ilen; ajint itoken = 0; AjBool ok = ajTrue; list = ajListstrNew(); acdAttrToBool(thys, "casesensitive", ajFalse, &exactcase); tmpstr = acdAttrValue(thys, "delimiter"); if(ajStrGetLen(tmpstr)) ajStrAssignS(&delim, tmpstr); else ajStrAssignC(&delim, ";"); if(!repdelim) { repdelim = ajStrNewRes(10); ajStrAssignC(&repdelim, ","); } ajStrAssignS(&value, acdAttrValue(thys, "values")); acdVarResolve(&value); if(!ajStrGetLen(value)) if(!acdKnownValueSelect(thys, &value)) acdError("No value defined for selection"); ajStrAssignClear(&ambigList); ajStrAssignClear(&validstr); rephandle = ajStrTokenNewS(reply, repdelim); while(ajStrTokenNextParse(&rephandle, &repstr)) { itoken++; acdLog("testing '%S'\n", repstr); handle = ajStrTokenNewS(value, delim); i = jfound = 0; if(ajStrMatchC(repstr, "*")) { for(icnt = 1; ajStrTokenNextFind(&handle, &desc); icnt++) { ajStrAssignS(&hitstr, desc); ajListstrPushAppend(list, hitstr); hitstr = NULL; } } else { for(icnt = 1; ajStrTokenNextFind(&handle, &desc); icnt++) { ajStrTrimC(&desc, white); if(itoken == 1) { if(ajStrGetLen(validstr)) ajStrAppendK(&validstr, ','); ajStrAppendS(&validstr, desc); } if(ajStrMatchS(desc, repstr) || (!exactcase && ajStrMatchCaseS(desc, repstr))) { jfound = 1; ajStrAssignS(&hitstr2, desc); break; } if(ajStrPrefixS(desc, repstr) || (!exactcase && ajStrPrefixCaseS(desc,repstr))) { jfound++; ajStrAssignS(&hitstr2, desc); acdAmbigApp(&ambigList, desc); } if(ajStrToInt(repstr, &i) && i == icnt) { jfound++; ajStrAssignS(&hitstr2, desc); acdAmbigApp(&ambigList, repstr); } } /* end of while */ if(jfound == 1) { ajStrAssignS(&hitstr, hitstr2); ajListstrPushAppend(list, hitstr); hitstr = NULL; } else { if(jfound) /* test acdc-selectambig */ ajErr("'%S' is ambiguous (%S)", repstr, ambigList); else /* test acdc-selectbad */ ajErr("'%S' is not a valid selection list option\n" "Accepted values are: %S", repstr, validstr); ok = ajFalse; break; } ajStrTokenDel(&handle); } } ajStrTokenDel(&rephandle); ajStrDel(&repstr); ilen = (ajuint) ajListstrGetLength(list); if(ok) { if(ilen < min) /* test acdc-selectmin */ { if(min <= 1) ajErr("Selection list needs %d value", min); else ajErr("Selection list needs %d values", min); ok = ajFalse; } if(ilen > max) /* test acdc-selectmax */ { if(max <= 1) ajErr("Selection list allows no more than %d value", max); else ajErr("Selection list allows no more than %d values", max); ok = ajFalse; } } if(ok) { AJCNEW0(val, ilen+1); for(k = 0; k < ilen; k++) ajListstrPop(list, &val[k]); } acdLog("Found %d matches\n", ilen); ajListstrFreeData(&list); ajStrDel(&value); ajStrDel(&line); ajStrDel(&code); ajStrDel(&desc); ajStrDel(&ambigList); ajStrDel(&hitstr2); ajStrDel(&delim); ajStrDel(&repdelim); ajStrDel(&validstr); if(!ok) return NULL; return val; } ID acdAmbigApp TY static MO ajacd LB acd XX DE Appends a token to a list, with commas as delimiters. Used to DE build a list of ambiguous matches for messages. XX PN [1] PA w pambigList AjPStr* PD List of tokens with ',' delimiter PX PN [2] PA r str const AjPStr PD Latest token to add PX RT void RD RX // static void acdAmbigApp(AjPStr* pambigList, const AjPStr str) { if(ajStrGetLen(*pambigList)) ajStrAppendC(pambigList, ","); ajStrAppendS(pambigList, str); return; } ID acdAmbigAppC TY static MO ajacd LB acd XX DE Appends a token to a list, with commas as delimiters. Used to DE build a list of ambiguous matches for messages. XX PN [1] PA w pambigList AjPStr* PD List of tokens with ',' delimiter PX PN [2] PA r txt const char* PD Latest token to add PX RT void RD RX // static void acdAmbigAppC(AjPStr* pambigList, const char* txt) { if(ajStrGetLen(*pambigList)) ajStrAppendC(pambigList, ","); ajStrAppendC(pambigList, txt); return; } ID acdDataFilename TY static MO ajacd LB acd XX DE Sets a default data file name. If no values are provided, it will be DE programname.dat XX PN [1] PA w infname AjPStr* PD Resulting file name PX PN [2] PA r name const AjPStr PD File name PX PN [3] PA r ext const AjPStr PD File extension PX PN [4] PA r nullok AjBool PD Can set as an empty string if true PX RT AjBool RD ajTrue if a name was successfully set RX // static AjBool acdDataFilename(AjPStr* infname, const AjPStr name, const AjPStr ext, AjBool nullok) { AjBool ret = ajTrue; if(ajStrGetLen(name)) ajStrAssignS(infname, name); else if(!nullok) ajStrAssignS(infname, acdProgram); else ajStrAssignClear(infname); if(ajStrGetLen(ext)) ajFilenameReplaceExtS(infname, ext); else if (!nullok) ajFilenameReplaceExtC(infname, "dat"); return ret; } ID acdInFilename TY static MO ajacd LB acd XX DE Sets a default input file name. If filtering is on, this will be stdin. DE Otherwise it is blank. XX PN [1] PA w infname AjPStr* PD Input file name PX RT AjBool RD ajTrue if a name was successfully set RX // static AjBool acdInFilename(AjPStr* infname) { AjBool ret = ajFalse; if(!acdInFile && acdFilter) { ajStrAssignC(infname, "stdin"); ret = ajTrue; } else ajStrAssignClear(infname); acdInFile++; return ret; } ID acdOutDirectory TY static MO ajacd LB acd XX DE Sets a default output file directory. Uses the _OUTDIRECTORY variable DE as a default value, but any input string overrides it. DE DE The recommendation is that the directory should always be provided DE in the emboss.defaults file or by an environment variable. DE DE As for all associated qualifiers, it is also possible to set a value DE in the ACD file. XX PN [1] PA w dir AjPStr* PD Specified directory PX RT AjBool RD ajTrue if a directory was successfully set RX // static AjBool acdOutDirectory(AjPStr* dir) { AjBool ret = ajFalse; AjPStr mydir = NULL; acdLog("acdOutDirectory ('%S')\n", *dir); if(!acdDirectoryDef) if(!ajNamGetValueC("outdirectory", &acdDirectoryDef)) ajStrAssignClear(&acdDirectoryDef); if(dir && ajStrGetLen(*dir)) ajStrAssignS(&mydir, *dir); else ajStrAssignS(&mydir, acdDirectoryDef); if(ajStrGetLen(mydir)) { ajDirnameFix(&mydir); ajStrAssignS(dir, mydir); ret = ajTrue; } else { ajStrAssignClear(dir); ret = ajFalse; } acdLog(". . . dir '%S' ret: %B\n", *dir, ret); ajStrDel(&mydir); return ret; } ID acdOutFilename TY static MO ajacd LB acd XX DE Sets a default output file name. If stdout or filtering are on, DE this will be stdout for the first output file. DE Otherwise it is built from the defaults provided. DE DE The base file name is usually specified in the ACD file as name: DE and passed in by the calling acdSet function. The default will DE be the base file name saved from the first input file, or "outfile" DE DE The extension is usually specified in the ACD file as extension: DE and passed in by the calling acdSet function. The default will DE be the program name for the first file, and "out2", "out3" and so DE on for later files. DE DE The recommendation is that the extension should always be provided DE in the ACD file, but that the base file name should be taken from DE the input file in most cases. XX PN [1] PA w outfname AjPStr* PD Input file name PX PN [2] PA r name const AjPStr PD Specified base file name PX PN [3] PA r ext const AjPStr PD Specified extension PX RT AjBool RD ajTrue if a name was successfully set RX // static AjBool acdOutFilename(AjPStr* outfname, const AjPStr name, const AjPStr ext) { AjBool ret = ajFalse; acdLog("acdOutFilename ('%S', '%S', '%S') acdStdout: %B\n", *outfname, name, ext, acdStdout); if(!acdOutFile && acdStdout) /* first outfile, running as a filter */ { ajStrAssignC(outfname, "stdout"); acdLog("outfile '%S'\n", *outfname); acdOutFile++; return ajTrue; } ajStrAssignEmptyS(&acdOutFName, name); /* use name if given */ ajStrFmtWord(&acdOutFName); ajStrAssignEmptyS(&acdOutFName, acdInFName); /* else use saved name */ ajStrAssignEmptyC(&acdOutFName, "outfile"); /* else, use "outfile" */ ajStrAssignEmptyS(&acdOutFExt, ext); /* use extension if given */ if(!acdOutFile) ajStrAssignEmptyS(&acdOutFExt, acdProgram); /* else try program name for first file */ if(!ajStrGetLen(acdOutFExt)) /* if all else fails, use out2 etc. */ ajFmtPrintS(&acdOutFExt, "out%d", acdOutFile+1); acdLog(". . . acdOutFName '%S', acdOutFExt '%S'\n", acdOutFName, acdOutFExt); if(ext && ajStrGetLen(acdOutFExt)) /* NULL ext means add no extension */ ajFmtPrintS(outfname, "%S.%S", acdOutFName, acdOutFExt); else ajStrAppendS(outfname, acdOutFName); acdOutFile++; acdLog("outfile %d %S.%S\n", acdOutFile, acdOutFName, acdOutFExt); ajStrDelStatic(&acdOutFName); ajStrDelStatic(&acdOutFExt); return ret; } ID acdInFileSave TY static MO ajacd LB acd XX DE For the first call, saves the input filename for use in building output DE file name(s). XX PN [1] PA r infname const AjPStr PD Input file name PX PN [2] PA r objname const AjPStr PD Input object name (or NULL) PX PN [3] PA r reset AjBool PD Reset the saved name if this is the first time PD a true value has been passed. PX RT AjBool RD ajTrue if a name was successfully set RX // static AjBool acdInFileSave(const AjPStr infname, const AjPStr objname, AjBool reset) { static AjBool usefile = AJFALSE; static ajint called = 0; AjBool useobj = ajTrue; if(!called) { if(ajNamGetValueC("acdfilename", &acdTmpStr)) ajStrToBool(acdTmpStr, &usefile); called = 1; } if(acdInFileSet) /* already have a name */ return ajFalse; if(!reset && ajStrGetLen(acdInFName)) /* have a name, no reset forced */ return ajFalse; if(usefile) { useobj = ajFalse; if(ajStrMatchC(infname, "stdin")) useobj = ajTrue; } acdLog("acdInFileSave (%S,%S) reset: %B usefile: %B, saved name '%S'\n", infname, objname, reset, usefile, acdInFName); if(useobj && ajStrGetLen(objname)) { if(!ajStrGetLen(objname)) return ajFalse; ajStrAssignS(&acdInFName, objname); ajFilenameTrimAll(&acdInFName); ajStrFmtLower(&acdInFName); } else { if(!ajStrGetLen(infname)) return ajFalse; ajStrAssignS(&acdInFName, infname); ajFilenameTrimAll(&acdInFName); if(useobj) ajStrFmtLower(&acdInFName); } if(reset) acdInFileSet = ajTrue; acdLog("acdInFileSave (%S, %S) input file set to '%S'\n", infname, objname, acdInFName); return ajTrue; } ID acdInTypeSeqSave TY static MO ajacd LB acd XX DE For the first call, saves the input filename for use in building output DE file name(s). XX PN [1] PA r intype const AjPStr PD Input sequence type PX RT AjBool RD ajTrue if a type was successfully set RX // static AjBool acdInTypeSeqSave(const AjPStr intype) { if(acdInTypeSeqName) return ajFalse; acdLog("acdInTypeSeqSave (%S)\n", intype); if(!ajStrGetLen(intype)) { ajStrAssignClear(&acdInTypeSeqName); acdLog("Input sequence type defaults to ''\n", acdInTypeSeqName); acdInTypeFeatSave(NULL); } else { ajStrAssignS(&acdInTypeSeqName, intype); ajStrFmtLower(&acdInTypeSeqName); if(ajSeqTypeIsAny(intype)) acdInTypeFeatSaveC(""); else if(ajSeqTypeIsProt(intype)) acdInTypeFeatSaveC("protein"); else if(ajSeqTypeIsNuc(intype)) acdInTypeFeatSaveC("nucleotide"); else acdInTypeFeatSaveC(""); } acdLog("acdInTypeSeqSave (%S) input type set to '%S'\n", intype, acdInTypeSeqName); return ajTrue; } ID acdInTypeSeq TY static MO ajacd LB acd XX DE Returns the input sequence type (if known) XX PN [1] PA w typename AjPStr* PD Input sequence type PX RT AjBool RD ajTrue if a type was successfully set RX // static AjBool acdInTypeSeq(AjPStr* typename) { AjBool ret = ajFalse; acdLog("acdInTypeSeq saved acdInTypeSeqName '%S'\n", acdInTypeSeqName); if(acdInTypeSeqName) /* could be an empty string */ { ajStrAssignS(typename, acdInTypeSeqName); ret = ajTrue; } else { ajStrAssignClear(typename); /* allow anything, return ajFalse */ ret = ajFalse; } return ret; } ID acdInTypeFeatSave TY static MO ajacd LB acd XX DE Saves the input feature type for use in setting the default output type XX PN [1] PA r intype const AjPStr PD Input feature type PX RT AjBool RD ajTrue if a type was successfully set RX // static AjBool acdInTypeFeatSave(const AjPStr intype) { if(acdInTypeFeatName) return ajFalse; acdLog("acdInTypeFeatSave (%S)\n", intype); if(!ajStrGetLen(intype)) { ajStrAssignClear(&acdInTypeFeatName); acdLog("Input feature type defaults to '%S'\n", acdInTypeFeatName); } else ajStrAssignS(&acdInTypeFeatName, intype); ajStrFmtLower(&acdInTypeFeatName); acdLog("acdInTypeFeatSave (%S) input feature type set to '%S'\n", intype, acdInTypeFeatName); return ajTrue; } ID acdInTypeFeatSaveC TY static MO ajacd LB acd XX DE Saves the input feature type for use in setting the default output type XX PN [1] PA r intype const char* PD Input feature type PX RT AjBool RD ajTrue if a type was successfully set RX // static AjBool acdInTypeFeatSaveC(const char* intype) { AjBool ret; AjPStr tmpstr = NULL; tmpstr = ajStrNewC(intype); ret = acdInTypeFeatSave(tmpstr); ajStrDel(&tmpstr); return ret; } ID acdInTypeFeat TY static MO ajacd LB acd XX DE Returns the input feature type (if known) XX PN [1] PA w typename AjPStr* PD Input feature type PX RT AjBool RD ajTrue if a type was successfully set RX // static AjBool acdInTypeFeat(AjPStr* typename) { AjBool ret = ajFalse; acdLog("acdInTypeFeat saved acdInTypeFeatName '%S'\n", acdInTypeFeatName); if(acdInTypeFeatName) /* could be an empty string */ { ajStrAssignS(typename, acdInTypeFeatName); ret = ajTrue; } else { ajStrAssignClear(typename); /* allow anything, return ajFalse */ ret = ajFalse; } return ret; } ID acdLog TY static MO ajacd LB acd XX DE Writes a message to the .acdlog file XX PN [1] PA r fmt const char* PD Format with ajFmt extensions PX PN [2] PA v vararg ... PD Optional arguments PX RT void RD RX // static void acdLog(const char *fmt, ...) { va_list args; if(!acdDoLog) return; if(!acdLogFName) { ajFmtPrintS(&acdLogFName, "%S.acdlog", acdProgram); acdLogFile = ajFileNewOutNameS(acdLogFName); ajFileSetUnbuffer(acdLogFile); } va_start(args, fmt) ; ajFmtVPrintF(acdLogFile, fmt, args); va_end(args) ; return; } ID acdPretty TY static MO ajacd LB acd XX DE Writes a pretty formatted version of the .acd syntax DE message to the .acdpretty file XX PN [1] PA r fmt const char* PD Format with ajFmt extensions PX PN [2] PA v vararg ... PD Optional arguments PX RT void RD RX // static void acdPretty(const char *fmt, ...) { va_list args ; static AjPStr tmpstr = NULL; ajint *icword = NULL; ajint *icpos = NULL; AjPStr cmtstr = NULL; ajint lastword; ajint wordcount; ajuint ipos; ajint i = 0; ajint j = 0; ajint ccnt=0; if(!acdDoPretty) return; if(!acdPrettyFName) { if(acdStdout) acdPrettyFile = ajFileNewFromCfile(stdout); else { ajFmtPrintS(&acdPrettyFName, "%S.acdpretty", acdProgram); acdPrettyFile = ajFileNewOutNameS(acdPrettyFName); ajFileSetUnbuffer(acdPrettyFile); ajFmtPrint("Created %S\n", acdPrettyFName); } } va_start(args, fmt); ajFmtVPrintS(&tmpstr, fmt, args); va_end(args); /* ** test for comment block before this line */ while(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= acdWordSave)) { ajListPeek(acdListCommentsCount, (void**) &icword); ajListPeek(acdListCommentsColumn, (void**) &icpos); acdCmtWord = *icword; if((acdCmtWord == acdWordSave && !*icpos) || (acdCmtWord<=acdWordSave)) { if(!ajStrGetLen(cmtstr)) ajFmtPrintF(acdPrettyFile, "\n"); ajListPop(acdListCommentsCount, (void**) &icword); ajListPop(acdListCommentsColumn, (void**) &icpos); ajListstrPop(acdListComments, &cmtstr); acdPrettyComment(cmtstr); ajStrDel(&cmtstr); AJFREE(icword); AJFREE(icpos); ccnt++; } } if(ccnt && ajStrGetCharFirst(tmpstr) != '\n') ajFmtPrintF(acdPrettyFile, "\n"); while(ajStrGetCharFirst(tmpstr) == '\n') { ajFmtPrintF(acdPrettyFile, "\n"); ajStrCutStart(&tmpstr, 1); } wordcount = ajStrParseCount(tmpstr); lastword = acdWordSave + wordcount; /* ** now check for inline comment on this line of text */ if(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= lastword)) { ajListPeek(acdListCommentsCount, (void**) &icword); ajListPeek(acdListCommentsColumn, (void**) &icpos); acdCmtWord = *icword; if((acdCmtWord == lastword && *icpos) | (acdCmtWord < lastword)) { ajListPop(acdListCommentsCount, (void**) &icword); ajListPop(acdListCommentsColumn, (void**) &icpos); ajListstrPop(acdListComments, &cmtstr); ajStrRemoveWhiteExcess(&cmtstr); if(!ajStrPrefixC(cmtstr, "#")) ajStrInsertC(&cmtstr, 0, "#"); if((ajStrGetLen(cmtstr) > 1) && !ajStrPrefixC(cmtstr, "# ")) ajStrInsertC(&cmtstr, 1, " "); i=0; while(ajStrGetCharLast(tmpstr) == '\n') { ajStrCutEnd(&tmpstr, 1); i++; } ipos = 75; if(ajStrGetLen(cmtstr) > (79 - ipos)) ipos = 79 - ajStrGetLen(cmtstr); if(ipos <= (ajStrGetLen(tmpstr)+acdPrettyMargin)) ipos = ajStrGetLen(tmpstr)+acdPrettyMargin+1; j = ipos-ajStrGetLen(tmpstr)-acdPrettyMargin; ajStrAppendCountK(&tmpstr, ' ', j); ajStrAppendS(&tmpstr, cmtstr); if(i) ajStrAppendCountK(&tmpstr, '\n', i); ajStrDel(&cmtstr); AJFREE(icword); AJFREE(icpos); } } if(acdPrettyMargin) ajFmtPrintF(acdPrettyFile, "%.*s", acdPrettyMargin, " "); ajFmtPrintF(acdPrettyFile, "%S", tmpstr); acdWordSave += wordcount; return; } ID acdPrettyClose TY static MO ajacd LB acd XX DE Writes any remaining comments and closes the pretty output file XX RT void RD RX // static void acdPrettyClose(void) { ajint *icword = NULL; ajint *icpos = NULL; AjPStr cmtstr = NULL; if(!acdDoPretty) return; if(!acdPrettyFName) { if(acdStdout) acdPrettyFile = ajFileNewFromCfile(stdout); else { ajFmtPrintS(&acdPrettyFName, "%S.acdpretty", acdProgram); acdPrettyFile = ajFileNewOutNameS(acdPrettyFName); ajFileSetUnbuffer(acdPrettyFile); ajFmtPrint("Created %S\n", acdPrettyFName); } } while(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= acdWordSave)) { ajListPeek(acdListCommentsCount, (void**) &icword); acdCmtWord = *icword; if(acdCmtWord <= acdWordSave) { if(!ajStrGetLen(cmtstr)) ajFmtPrintF(acdPrettyFile, "\n"); ajStrDel(&cmtstr); ajListPop(acdListCommentsCount, (void**) &icword); ajListPop(acdListCommentsColumn, (void**) &icpos); ajListstrPop(acdListComments, &cmtstr); acdPrettyComment(cmtstr); AJFREE(icword); AJFREE(icpos); } } ajStrDel(&cmtstr); ajFileClose(&acdPrettyFile); return; } ID acdPrettyComment TY static MO ajacd LB acd XX DE Writes an indented one-line comment XX PN [1] PA r comment const AjPStr PD OComment to be printer PX RT void RD RX // static void acdPrettyComment(const AjPStr comment) { AjPStr tmpstr = NULL; if(!acdDoPretty) return; if(!acdPrettyFName) { if(acdStdout) acdPrettyFile = ajFileNewFromCfile(stdout); else { ajFmtPrintS(&acdPrettyFName, "%S.acdpretty", acdProgram); acdPrettyFile = ajFileNewOutNameS(acdPrettyFName); ajFileSetUnbuffer(acdPrettyFile); ajFmtPrint("Created %S\n", acdPrettyFName); } } ajStrAssignS(&tmpstr, comment); ajStrRemoveWhiteExcess(&tmpstr); if(!ajStrPrefixC(tmpstr, "#")) ajStrInsertC(&tmpstr, 0, "#"); if((ajStrGetLen(tmpstr) > 1) && !ajStrPrefixC(tmpstr, "# ")) ajStrInsertC(&tmpstr, 1, " "); /* ** margin is set for attributes ** reduce by 2 to align with definitions */ if(acdPrettyMargin) ajFmtPrintF(acdPrettyFile, "%.*s", acdPrettyMargin, " "); ajFmtPrintF(acdPrettyFile, "%S\n", tmpstr); ajStrDel(&tmpstr); return; } ID acdPrettyWrap TY static MO ajacd LB acd XX DE Writes a pretty formatted version of the .acd syntax DE line to the .acdpretty file XX PN [1] PA r left ajint PD Extra left margin for follow-on lines PX PN [2] PA r fmt const char* PD Format with ajFmt extensions PX PN [3] PA v vararg ... PD Optional arguments PX RT void RD RX // static void acdPrettyWrap(ajint left, const char *fmt, ...) { va_list args; static AjPStr tmpstr = NULL; ajint leftmargin = left + acdPrettyMargin; ajint width = 78 - leftmargin; ajint *icword = NULL; ajint *icpos = NULL; AjPStr cmtstr = NULL; ajint lastword; ajint wordcount; ajuint ipos; ajint ccnt = 0; ajlong jpos; ajlong kpos; ajlong ilen; AjIList itercmt; AjIList iterpos; AjIList iterword; if(!acdDoPretty) return; if(!acdPrettyFName) { if(acdStdout) acdPrettyFile = ajFileNewFromCfile(stdout); else { ajFmtPrintS(&acdPrettyFName, "%S.acdpretty", acdProgram); acdPrettyFile = ajFileNewOutNameS(acdPrettyFName); ajFileSetUnbuffer(acdPrettyFile); } } /* ** whole line comments before wrapped text */ while(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= acdWordSave)) { ajListPeek(acdListCommentsCount, (void**) &icword); acdCmtWord = *icword; if(acdCmtWord <= acdWordSave) { if(!ajStrGetLen(cmtstr)) ajFmtPrintF(acdPrettyFile, "\n"); ajListPop(acdListCommentsCount, (void**) &icword); ajListPop(acdListCommentsColumn, (void**) &icpos); ajListstrPop(acdListComments, &cmtstr); acdPrettyComment(cmtstr); ajStrDel(&cmtstr); AJFREE(icword); AJFREE(icpos); } } va_start(args, fmt); ajFmtVPrintS(&tmpstr, fmt, args); va_end(args); ajStrExchangeCC(&tmpstr, " \\ ", " \\\n"); /* force newlines at '\' */ wordcount = ajStrParseCount(tmpstr); lastword = acdWordSave + wordcount; /* ** Now check for inline comments in these lines of text */ /* ** First iterate to get comment max length */ ipos = 75; if(ajListGetLength(acdListCommentsCount) && (acdCmtWord <= lastword)) { ajListPeek(acdListCommentsCount, (void**) &icword); acdCmtWord = *icword; itercmt = ajListIterNewread(acdListComments); iterpos = ajListIterNewread(acdListCommentsColumn); iterword = ajListIterNewread(acdListCommentsCount); while(!ajListIterDone(iterword) && (*icword <= lastword)) { icword = ajListIterGet(iterword); icpos = ajListIterGet(iterpos); cmtstr = ajListIterGet(itercmt); if(*icword <= lastword && *icpos > (acdPrettyMargin+3)) { ccnt++; if(ajStrGetLen(cmtstr) > (79 - ipos)) ipos = 79 - ajStrGetLen(cmtstr); /*if(*icpos < (ajint) ipos) ipos = *icpos;*/ } } ajListIterDel(&itercmt); ajListIterDel(&iterpos); ajListIterDel(&iterword); } if((ajint) ipos <= (leftmargin + 20)) ipos = leftmargin + 20; width = ipos - leftmargin - 1; ajStrFmtWrapLeft(&tmpstr, width, acdPrettyMargin, left); /* ** Insert any comments at ends of lines */ jpos=-1; while(ccnt--) { ajListPop(acdListCommentsCount, (void**) &icword); ajListPop(acdListCommentsColumn, (void**) &icpos); ajListstrPop(acdListComments, &cmtstr); ajStrRemoveWhiteExcess(&cmtstr); if(!ajStrPrefixC(cmtstr, "#")) ajStrInsertC(&cmtstr, 0, "#"); if((ajStrGetLen(cmtstr) > 1) && !ajStrPrefixC(cmtstr, "# ")) ajStrInsertC(&cmtstr, 1, " "); kpos = ajStrFindNextK(tmpstr, jpos+1, '\n'); if(kpos < 0) { if(jpos == (ajint) ajStrGetLen(tmpstr)) { ajStrAppendK(&tmpstr, '\n'); ilen = 0; } else ilen = ajStrGetLen(tmpstr) - jpos - 1; while(ilen < (ajlong) ipos) { ajStrAppendK(&tmpstr, ' '); ilen++; } ajStrAppendS(&tmpstr, cmtstr); jpos = ajStrGetLen(tmpstr); } else { ilen = kpos - jpos - 1; jpos = kpos; while(ilen < (ajlong) ipos) { ajStrInsertK(&tmpstr, jpos, ' '); ilen++; jpos++; } ajStrInsertS(&tmpstr, jpos, cmtstr); jpos += ajStrGetLen(cmtstr); } ajStrDel(&cmtstr); AJFREE(icword); AJFREE(icpos); } ajFmtPrintF(acdPrettyFile, "%S\n", tmpstr); acdWordSave += wordcount; return; } ID acdPrettyShift TY static MO ajacd LB acd XX DE Right shifts (indents) acdpretty printing XX RT void RD RX // static void acdPrettyShift(void) { acdPrettyMargin += acdPrettyIndent; return; } ID acdPrettyUnShift TY static MO ajacd LB acd XX DE Left shifts acdpretty printing XX RT void RD RX // static void acdPrettyUnShift(void) { acdPrettyMargin -= acdPrettyIndent; if(acdPrettyMargin < 0) { ajWarn("acdpretty printing indent error - too many left shifts"); acdPrettyMargin = 0; } return; } ID acdIsQtype TY static MO ajacd LB acd XX DE Tests whether an ACD object is a qualifier or parameter type. If not we DE assume it is a keyword type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT AjBool RD ajTrue if the object is a qualifier or parameter RX // static AjBool acdIsQtype(const AcdPAcd thys) { if((thys->Level == ACD_QUAL) || (thys->Level == ACD_PARAM)) return ajTrue; return ajFalse; } ID acdIsStype TY static MO ajacd LB acd XX DE Tests whether an ACD object is a section or endsection type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT AjBool RD ajTrue if the object is a section or endsection RD type definition RX // static AjBool acdIsStype(const AcdPAcd thys) { if((thys->Level == ACD_SEC) || (thys->Level == ACD_ENDSEC)) return ajTrue; return ajFalse; } ID acdIsAtype TY static MO ajacd LB acd XX DE Tests whether an ACD object is an application type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT AjBool RD ajTrue if the object is an application type definition RX // static AjBool acdIsAtype(const AcdPAcd thys) { if(thys->Level == ACD_APPL) return ajTrue; return ajFalse; } ID acdIsVtype TY static MO ajacd LB acd XX DE Tests whether an ACD object is a variable type. XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT AjBool RD ajTrue if the object is a variable type definition RX // static AjBool acdIsVtype(const AcdPAcd thys) { if(thys->Level == ACD_VAR) return ajTrue; return ajFalse; } ID acdTextFormat TY static MO ajacd LB acd XX DE Converts backslash codes in a string into special characters XX PN [1] PA u text AjPStr* PD Text with backslash codes PX RT AjBool RD ajTrue if successful RX // static AjBool acdTextFormat(AjPStr* text) { ajStrExchangeCC(text, " \\ ", "\n"); return ajTrue; } ID acdTextTrim TY static MO ajacd LB acd XX DE Trims white space. For HTML output, replaces angled brackets XX PN [1] PA u text AjPStr* PD Text to be processed PX RT void RD RX // static void acdTextTrim(AjPStr* text) { ajStrTrimC(text, " \t\n\r"); if(acdDoTable) { ajStrExchangeCC(text, "<", "<"); ajStrExchangeCC(text, ">", ">"); } return; } ID ajAcdPrintAppl TY public MO ajacd LB acd XX DE Report details of all known ACD attributes for all applications. DE For use by EMBOSS entrails. XX PN [1] PA u outf AjPFile PD Output file PX PN [2] PA r full AjBool PD Full report - currently no extra details printed PX RT void RD RX // void ajAcdPrintAppl(AjPFile outf, AjBool full) { ajint i; AcdPAttr attr; AjPStr tmpstr = NULL; ajuint maxtmp = 0; if(full) ajFmtPrintF(outf, "\n"); else ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "# ACD Application Attributes\n"); ajFmtPrintF(outf, "# Attribute Type Default Helptext\n"); ajFmtPrintF(outf, "AttrAppl {\n"); for(i=0; acdAttrAppl[i].Name; i++) { attr = &acdAttrAppl[i]; ajFmtPrintF(outf, " %-15s", attr->Name); ajFmtPrintF(outf, " %-10s", acdValNames[attr->Type]); ajFmtPrintS(&tmpstr, "\"%s\"", attr->Default); if(ajStrGetLen(tmpstr) > maxtmp) maxtmp = ajStrGetLen(tmpstr); ajFmtPrintF(outf, " %-12S", tmpstr); ajFmtPrintF(outf, " \"%s\"", attr->Help); ajFmtPrintF(outf, "\n"); } ajFmtPrintF(outf, "}\n\n"); if(maxtmp > 12) ajWarn("ajAcdPrintAppl max tmpstr len %d", maxtmp); ajStrDel(&tmpstr); return; } ID ajAcdPrintQual TY public MO ajacd LB acd XX DE Report details of all known ACD qualifiers for all applications. DE For use by EMBOSS entrails. XX PN [1] PA u outf AjPFile PD Output file PX PN [2] PA r full AjBool PD Full report - currently no extra details printed PX RT void RD RX // void ajAcdPrintQual(AjPFile outf, AjBool full) { ajint i; AcdPQual qual; AjPStr tmpstr = NULL; ajuint maxtmp = 0; if(full) ajFmtPrintF(outf, "\n"); else ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "# ACD Application Qualifiers\n"); ajFmtPrintF(outf, "# Qualifier Type Default Helptext\n"); ajFmtPrintF(outf, "QualAppl {\n"); for(i=0; acdQualAppl[i].Name; i++) { qual = &acdQualAppl[i]; ajFmtPrintF(outf, " %-15s", qual->Name); ajFmtPrintF(outf, " %-10s", qual->Type); ajFmtPrintS(&tmpstr, " \"%s\"", qual->Default); if(ajStrGetLen(tmpstr) > maxtmp) maxtmp = ajStrGetLen(tmpstr); ajFmtPrintF(outf, " %-12S", tmpstr); ajFmtPrintF(outf, " \"%s\"", qual->Help); ajFmtPrintF(outf, "\n"); } ajFmtPrintF(outf, "}\n\n"); if(maxtmp > 12) ajWarn("ajAcdPrintQual max tmpstr len %d", maxtmp); ajStrDel(&tmpstr); return; } ID ajAcdPrintType TY public MO ajacd LB acd XX DE Report details of all known ACD types. DE For use by EMBOSS entrails. XX PN [1] PA u outf AjPFile PD Output file PX PN [2] PA r full AjBool PD Full report PX RT void RD RX // void ajAcdPrintType(AjPFile outf, AjBool full) { AcdPType pat; AcdPAttr attr; AcdPQual qual; ajint i; AjPStr tmpstr = NULL; ajuint maxtmp = 0; ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "# ACD Types\n"); ajFmtPrintF(outf, "# Name Group Description\n"); ajFmtPrintF(outf, "# Attribute Type " "Default Comment\n"); ajFmtPrintF(outf, "# Qualifier Type " "Default Helptext\n"); ajFmtPrintF(outf, "AcdType {\n"); for(i=0; acdType[i].Name; i++) { pat = &acdType[i]; ajFmtPrintF(outf, " %-14s", pat->Name); ajFmtPrintF(outf, " %-10s", pat->Group); ajFmtPrintF(outf, " \"%s\"", pat->Valid); ajFmtPrintF(outf, "\n"); if(full && pat->Attr) { ajFmtPrintF(outf, " attributes {\n"); for(attr=pat->Attr; attr->Name; attr++) { ajFmtPrintF(outf, " %-15s", attr->Name); ajFmtPrintF(outf, " %-10s", acdValNames[attr->Type]); ajFmtPrintS(&tmpstr, "\"%s\"", attr->Default); if(ajStrGetLen(tmpstr) > maxtmp) maxtmp = ajStrGetLen(tmpstr); ajFmtPrintF(outf, " %-12S", tmpstr); ajFmtPrintF(outf, " \"%s\"", attr->Help); ajFmtPrintF(outf, "\n"); } ajFmtPrintF(outf, " }\n"); } if(pat->Quals) { ajFmtPrintF(outf, " qualifiers {\n"); for(qual=pat->Quals; qual->Name; qual++) { ajFmtPrintF(outf, " %-15s", qual->Name); ajFmtPrintF(outf, " %-10s", qual->Type); ajFmtPrintS(&tmpstr, "\"%s\"", qual->Default); if(ajStrGetLen(tmpstr) > maxtmp) maxtmp = ajStrGetLen(tmpstr); ajFmtPrintF(outf, " %-12S", tmpstr); ajFmtPrintF(outf, " \"%s\"", qual->Help); ajFmtPrintF(outf, "\n"); } ajFmtPrintF(outf, " }\n"); } } ajFmtPrintF(outf, "}\n"); ajFmtPrintF(outf, "# ACD Default attributes\n"); ajFmtPrintF(outf, "# Name Type Default Comment\n"); for(i=0; acdAttrDef[i].Name; i++) { ajFmtPrintF(outf, " %-15s", acdAttrDef[i].Name); ajFmtPrintF(outf, " %-10s", acdValNames[acdAttrDef[i].Type]); ajFmtPrintS(&tmpstr, "\"%s\"", acdAttrDef[i].Default); if(ajStrGetLen(tmpstr) > maxtmp) maxtmp = ajStrGetLen(tmpstr); ajFmtPrintF(outf, " %-12S", tmpstr); ajFmtPrintF(outf, " \"%s\"", acdAttrDef[i].Help); ajFmtPrintF(outf, "\n"); } ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "# ACD Calculated attributes\n"); ajFmtPrintF(outf, "# Name\n"); ajFmtPrintF(outf, "# Attribute Type " "Default Comment\n"); acdPrintCalcattr(outf, "distances", acdCalcDistances); acdPrintCalcattr(outf, "features", acdCalcFeat); acdPrintCalcattr(outf, "frequencies", acdCalcFrequencies); acdPrintCalcattr(outf, "properties", acdCalcProperties); acdPrintCalcattr(outf, "regexp", acdCalcRegexp); acdPrintCalcattr(outf, "sequence", acdCalcSeq); acdPrintCalcattr(outf, "seqall", acdCalcSeqall); acdPrintCalcattr(outf, "seqset", acdCalcSeqset); acdPrintCalcattr(outf, "seqsetall", acdCalcSeqsetall); acdPrintCalcattr(outf, "string", acdCalcString); acdPrintCalcattr(outf, "tree", acdCalcTree); ajFmtPrintF(outf, "\n"); if(maxtmp > 12) ajWarn("ajAcdPrintType max tmpstr len %d", maxtmp); ajStrDel(&tmpstr); return; } ID acdPrintCalcattr TY static MO ajacd LB acd XX DE Report calculated attributes set DE For use by EMBOSS entrails. XX PN [1] PA u outf AjPFile PD Output file PX PN [2] PA r acdtype const char* PD ACD type name PX PN [3] PA r calcattr const AcdOAttr[] PD Acd calculated attributes PX RT void RD RX // static void acdPrintCalcattr(AjPFile outf, const char* acdtype, const AcdOAttr calcattr[]) { ajint i; AjPStr tmpstr = NULL; ajuint maxtmp = 0; ajFmtPrintF(outf, " %s",acdtype); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, " attributes {\n"); for(i=0; calcattr[i].Name; i++) { ajFmtPrintF(outf, " %-14s", calcattr[i].Name); ajFmtPrintF(outf, " %-10s", acdValNames[calcattr[i].Type]); ajFmtPrintS(&tmpstr, "\"%s\"", calcattr[i].Default); if(ajStrGetLen(tmpstr) > maxtmp) maxtmp = ajStrGetLen(tmpstr); ajFmtPrintF(outf, " %-20S", tmpstr); ajFmtPrintF(outf, " \"%s\"", calcattr[i].Help); ajFmtPrintF(outf, "\n"); } ajFmtPrintF(outf, " }\n"); if(maxtmp > 20) ajWarn("acdPrintCalcAttr max tmpstr len %d", maxtmp); ajStrDel(&tmpstr); return; } ID acdVocabCheck TY static MO ajacd LB acd XX DE Checks for a string in a controlled vocabulary of character strings, DE ended with a NULL. XX PN [1] PA r str const AjPStr PD Test string PX PN [2] PA r vocab const char** PD Controlled vocabulary PX RT AjBool RD ajTrue if the string matched on of the words RX // static AjBool acdVocabCheck(const AjPStr str, const char** vocab) { ajint i = 0; while(vocab[i]) { if(ajStrMatchCaseC(str, vocab[i])) return ajTrue; i++; } return ajFalse; } ID acdError TY static MO ajacd LB acd XX DE Formatted write as an error message, then exits with ajExitBad XX PN [1] PA r fmt const char* PD Format string PX PN [2] PA v vararg ... PD Format arguments. PX RT void RD RX // __noreturn static void acdError(const char* fmt, ...) { va_list args ; AjPStr errstr = NULL; ajint linenum; acdErrorCount++; va_start(args, fmt) ; ajFmtVPrintS(&errstr, fmt, args); va_end(args) ; if(acdLineNum > 0) linenum = acdLineNum; else if(acdSetCurr) linenum = acdSetCurr->LineNum; else if(acdProcCurr) linenum = acdProcCurr->LineNum; else if(acdListCurr) linenum = acdListCurr->LineNum; else linenum = 0; ajErr("File %S line %d: %S", acdFName, linenum, errstr); ajStrDel(&errstr); ajExitBad(); } ID acdErrorValid TY static MO ajacd LB acd XX DE Formatted write as an error message, then continues (acdError exits) XX PN [1] PA r fmt const char* PD Format string PX PN [2] PA v vararg ... PD Format arguments. PX RT void RD RX // static void acdErrorValid(const char* fmt, ...) { va_list args; AjPStr errstr=NULL; ajint linenum; acdErrorCount++; va_start(args, fmt) ; ajFmtVPrintS(&errstr, fmt, args); va_end(args) ; if(acdLineNum > 0) linenum = acdLineNum; else if(acdSetCurr) linenum = acdSetCurr->LineNum; else if(acdProcCurr) linenum = acdProcCurr->LineNum; else if(acdListCurr) linenum = acdListCurr->LineNum; else linenum = 0; ajErr("File %S line %d: %S", acdFName, linenum, errstr); ajStrDel(&errstr); return; } ID acdWarnObsolete TY static MO ajacd LB acd XX DE Warning about obsolete status of an application XX PN [1] PA r str const AjPStr PD Format string PX RT void RD RX // static void acdWarnObsolete(const AjPStr str) { AjPStr outstr = NULL; AjPStr tmpstr = NULL; AjBool warnobsolete = ajTrue; if(ajNamGetValueC("warnobsolete", &tmpstr)) ajStrToBool(tmpstr, &warnobsolete); ajStrDel(&tmpstr); if(!warnobsolete) return; ajFmtPrintS(&outstr, "Application %S is marked as obsolete.\n%S", acdProgram, str); ajStrFmtWrap(&outstr, 75); ajWarn("%S", outstr); ajStrDel(&outstr); return; } ID acdWarn TY static MO ajacd LB acd XX DE Formatted write as an error message. XX PN [1] PA r fmt const char* PD Format string PX PN [2] PA v vararg ... PD Format arguments. PX RT void RD RX // static void acdWarn(const char* fmt, ...) { va_list args; AjPStr errstr = NULL; ajint linenum; acdErrorCount++; va_start(args, fmt) ; ajFmtVPrintS(&errstr, fmt, args); va_end(args) ; if(acdLineNum > 0) linenum = acdLineNum; else if(acdSetCurr) linenum = acdSetCurr->LineNum; else if(acdProcCurr) linenum = acdProcCurr->LineNum; else if(acdListCurr) linenum = acdListCurr->LineNum; else linenum = 0; ajWarn("File %S line %d: %S", acdFName, linenum, errstr); ajStrDel(&errstr); return; } ID acdErrorAcd TY static MO ajacd LB acd XX DE Formatted write as an error message, for a specified ACD object XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r fmt const char* PD Format string PX PN [3] PA v vararg ... PD Format arguments. PX RT void RD RX // __noreturn static void acdErrorAcd(const AcdPAcd thys, const char* fmt, ...) { va_list args; AjPStr errstr = NULL; acdErrorCount++; ajUtilCatch(); va_start(args, fmt) ; ajFmtVPrintS(&errstr, fmt, args); va_end(args) ; ajErr("File %S line %d: (%S) %S", acdFName, thys->LineNum, thys->Name, errstr); ajStrDel(&errstr); ajExitBad(); } ID ajAcdExit TY public MO ajacd LB acd XX DE Reports any unused ACD values DE DE Cleans up ACD processing internal memory XX PN [1] PA r silent AjBool PD Turn off messages (used when some messages PD are expected but can be ignored). PX RT void RD RX // void ajAcdExit(AjBool silent) { AcdPAcd pa; static AjBool staySilent = AJFALSE; AjPFile cmdlogfile = NULL; AjPStr cmdlog = NULL; AjPStr cmdstr = NULL; if(silent) staySilent = ajTrue; if(acdDoHelp) staySilent = ajTrue; if(acdDoPretty) staySilent = ajTrue; if(!staySilent) { /* turn off the warnings for now ... comment out this line to ** enable them. ** the problem is that some programs have conditionals around the ** ajAcdGet calls so they can sometimes fail to use values, even where ** the test cases say they are fine. ** also some ACD files (showdb for example) use values, ** but in some cases (showdb with all booleans on the command line) ** the value is not needed */ /* ajDebug("ajAcdExit Name................ Assoc Level Used\n");*/ for(pa=acdList; pa; pa=pa->Next) { /*ajDebug("ajAcdExit %20S %3B %3d %3B\n", pa->Name, pa->Assoc, pa->Level, pa->Used); */ if(pa->Assoc) continue; if(pa->Level != ACD_PARAM && pa->Level != ACD_QUAL) continue; if(!pa->Used) acdLog("ACD qualifier never used: %S = '%S' (assoc %B)", pa->Name, pa->ValStr, pa->Assoc); } } /* report the command line to a log if requested. ** added mainly to log command lines for the QA tests ** so they can also be used in memory leak tests ** ** Need to test acdProgram is still set - acdc calls this twice */ if(acdCommandLine && ajStrGetLen(acdProgram) && ajNamGetValueC("acdcommandlinelog", &cmdlog)) { cmdlogfile = ajFileNewOutappendNameS(cmdlog); ajStrAssignS(&cmdstr, acdArgSave); if(ajStrGetLen(acdInputSave)) { ajStrAppendK(&cmdstr, ' '); ajStrAppendS(&cmdstr, acdInputSave); } ajStrRemoveWhiteExcess(&cmdstr); ajFmtPrintF(cmdlogfile, "%S %S\n", acdProgram, cmdstr); ajFileClose(&cmdlogfile); ajStrDel(&cmdlog); ajStrDel(&cmdstr); } /* ** clean up memory: ** */ acdReset(); return; } ID acdPrintUsed TY static MO ajacd LB acd XX DE Quick printoout of all qualifiers believed to have been used XX RT void RD RX // static void acdPrintUsed(void) { AcdPAcd pa; ajUserDumpS(acdArgSave); for(pa=acdList; pa; pa=pa->Next) if(pa->UserDefined) ajUser("ACD qual defined: '%S'", pa->Name); return; } ID acdReset TY static MO ajacd LB acd XX DE Cleans up all memory allocated to ACD internals. DE DE All ACD objects are assumed to have been passed to the calling program DE and are no longer "owned" by ACD. DE DE In future, we could consider removing them once they have been fetched. XX RT void RD RX // static void acdReset(void) { AcdPAcd pa; AcdPAcd qa = NULL; /* acdPrintUsed(); */ for(pa=acdList; pa; pa=qa) { qa = pa->Next; acdDel(&pa); } ajStrDel(&acdPackName); ajStrDel(&acdPackVersion); ajTablestrFree(&acdKnowntypeTypeTable); ajTablestrFree(&acdKnowntypeDescTable); ajTablestrFree(&acdCodeTable); ajTablestrFree(&acdGrpTable); ajStrDel(&acdTmpStr); ajStrDel(&acdTmpStr2); ajStrDel(&acdPrefName); ajStrDel(&acdPrefToken); ajStrDel(&acdArgSave); ajStrDel(&acdInputSave); ajStrDel(&acdInputName); ajStrDel(&acdInFName); ajStrDel(&acdOutFName); ajStrDel(&acdOutFExt); ajStrDel(&acdInTypeFeatName); ajStrDel(&acdInTypeSeqName); ajStrDel(&acdTmpOutFName); ajStrDel(&acdLogFName); ajFileClose(&acdLogFile); ajListstrFreeData(&acdSecList); ajTablestrFree(&acdSecTable); ajTablestrFree(&acdExternalTable); ajStrDel(&acdPrettyFName); ajFileClose(&acdPrettyFile); ajStrDel(&acdFName); ajStrDel(&acdOutFullFName); ajStrDel(&acdVarAcdProtein); acdParseQuotes = ajFalse; ajStrDel(&acdParseReturn); ajStrDel(&acdReply); ajStrDel(&acdReplyDef); ajStrDel(&acdReplyPrompt); ajStrDel(&acdUserMsg); ajStrDel(&acdUserReplyDef); ajStrDel(&acdDirectoryDef); ajStrDel(&acdQNameTmp); ajStrDel(&acdQTypeTmp); ajStrDel(&acdAttrValTmp); ajStrDel(&acdQualNameTmp); ajStrDel(&acdQualNumTmp); ajRegFree(&acdRegQualParse); ajRegFree(&acdRegVarname); ajRegFree(&acdRegFunction); ajRegFree(&acdRegToggle); ajRegFree(&acdRegResolveVar); ajRegFree(&acdRegResolveFun); ajRegFree(&acdRegExpPlusI); ajRegFree(&acdRegExpPlusD); ajRegFree(&acdRegExpMinusI); ajRegFree(&acdRegExpMinusD); ajRegFree(&acdRegExpStarI); ajRegFree(&acdRegExpStarD); ajRegFree(&acdRegExpDivI); ajRegFree(&acdRegExpDivD); ajRegFree(&acdRegExpEqualI); ajRegFree(&acdRegExpEqualD); ajRegFree(&acdRegExpEqualT); ajRegFree(&acdRegExpNeI); ajRegFree(&acdRegExpNeD); ajRegFree(&acdRegExpNeT); ajRegFree(&acdRegExpGtI); ajRegFree(&acdRegExpGtD); ajRegFree(&acdRegExpGtT); ajRegFree(&acdRegExpLtI); ajRegFree(&acdRegExpLtD); ajRegFree(&acdRegExpLtT); ajRegFree(&acdRegExpOrI); ajRegFree(&acdRegExpOrD); ajRegFree(&acdRegExpOrT); ajRegFree(&acdRegExpAndI); ajRegFree(&acdRegExpAndD); ajRegFree(&acdRegExpAndT); ajRegFree(&acdRegExpCond); ajRegFree(&acdRegExpNot); ajRegFree(&acdRegExpOneofCase); ajRegFree(&acdRegExpOneofList); ajRegFree(&acdRegExpCaseCase); ajRegFree(&acdRegExpCaseList); ajRegFree(&acdRegExpFilename); ajRegFree(&acdRegExpFileExists); ajRegFree(&acdRegExpValue); ajListFreeData(&acdListCommentsCount); ajListFreeData(&acdListCommentsColumn); ajListstrFreeData(&acdListComments); ajStrDel(&acdProgram); ajStrDel(&acdAppldoc); AJFREE(acdParamSet); acdDoHelp = AJFALSE; acdDoLog = AJFALSE; acdDoWarnRange =AJTRUE; acdDoPretty = AJFALSE; acdDoTable = AJFALSE; acdDoValid = AJFALSE; acdVerbose = AJFALSE; acdAuto = AJFALSE; acdFilter = AJFALSE; acdOptions = AJFALSE; acdStdout = AJFALSE; acdCodeSet = AJFALSE; acdKnowntypeSet = AJFALSE; acdWrapper = AJFALSE; /* acdQualTestSkip = AJFALSE; */ acdInFile = 0; acdInFileSet = AJFALSE; acdOutFile = 0; acdPromptTry = 2; acdPrettyMargin = 0; acdPrettyIndent = 2; acdLineNum = 0; acdWordNum = 0; acdErrorCount = 0; acdUseData = 0; acdUseFeatures = 0; acdUseInfile = 0; acdUseSeq = 0; acdUseAlign = 0; acdUseFeatout = 0; acdUseOutfile = 0; acdUseReport = 0; acdUseSeqout = 0; acdUseGraph = 0; acdUseMisc = 0; acdCurrentStage = NO_STAGE; acdNParam=0; acdNewCurr = NULL; acdMasterQual = NULL; acdList = NULL; acdListLast = NULL; acdListCurr = NULL; acdProcCurr = NULL; acdSetCurr = NULL; return; } ID acdValidAppl TY static MO ajacd LB acd XX DE Validation for an application definition XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT void RD RX // static void acdValidAppl(const AcdPAcd thys) { ajint i; ajuint idocmax = 70; /* maximum length of documentation string */ AjPStrTok tokenhandle = NULL; AjPStr relation = NULL; const AjPStr namespace; ajuint ireloper = 0; ajuint ireltopic = 0; if(!acdDoValid) return; /* must have a documentation attribute */ i = acdFindAttrC(acdAttrAppl, "documentation"); if(!ajStrGetLen(thys->AttrStr[i])) acdErrorValid("Application has no documentation defined"); else { if(!isupper((int)ajStrGetCharFirst(thys->AttrStr[i]))) { if (islower((int)ajStrGetCharFirst(thys->AttrStr[i]))) acdWarn("Documentation string starts in lower case"); else acdWarn("Documentation string starts non-alphabetic"); } if (ajStrGetLen(thys->AttrStr[i]) > idocmax) acdWarn("Documentation string %d exceeds %d characters", ajStrGetLen(thys->AttrStr[i]), idocmax); } /* must have a group attribute */ i = acdFindAttrC(acdAttrAppl, "groups"); if(!ajStrGetLen(thys->AttrStr[i])) acdErrorValid("Application has no groups defined"); /* group must be a known group (and subgroup) */ acdValidApplGroup(thys->AttrStr[i]); i = acdFindAttrC(acdAttrAppl, "keywords"); acdValidApplKeywords(thys->AttrStr[i]); /* for now, skip EMBASSY applications */ /* if(acdEdam) { i = acdFindAttrC(acdAttrAppl, "embassy"); if(ajStrGetLen(thys->AttrStr[i])) acdEdam = NULL; } */ if(acdEdam) { i = acdFindAttrC(acdAttrAppl, "relations"); tokenhandle = ajStrTokenNewC(thys->AttrStr[i], "|"); while(ajStrTokenNextParse(&tokenhandle, &relation)) { namespace = acdEdamTest(relation); if(!namespace) acdErrorValid("Application relation '%S' not found", relation); else if(ajStrMatchC(namespace, "operation")) ireloper++; else if(ajStrMatchC(namespace, "topic")) ireltopic++; else acdErrorValid("Application has relation with namespace '%S'", namespace); } if(!ireltopic) acdErrorValid("Application has no 'topic' relation"); if(!ireloper) acdErrorValid("Application has no 'operation' relation"); ajStrDel(&relation); ajStrTokenDel(&tokenhandle); } /* ** test for wrapper attribute ** if true, we use the original command line ** so we turn off EMBOSS validation of qualifier names */ return; } ID acdValidRelation TY static MO ajacd LB acd XX DE Validation for a relation definition XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT void RD RX // static void acdValidRelation(const AcdPAcd thys) { const AjPStr tmpstr = NULL; if(!acdDoValid) return; tmpstr = acdAttrValue(thys, "relations"); if(!ajStrGetLen(tmpstr)) return; return; } ID acdValidSection TY static MO ajacd LB acd XX DE Validation for a section definition XX PN [1] PA r thys const AcdPAcd PD ACD object PX RT void RD RX // static void acdValidSection(const AcdPAcd thys) { static AjPTable typeTable = NULL; static AjPTable infoTable = NULL; static ajint sectLevel = 0; static ajint sectNumber= -1; const AjPStr sectType = NULL; /* string from table - no delete */ const AjPStr sectInfo = NULL; /* string from table - no delete */ const AjPStr tmpstr = NULL; static AjPStr sectNameTop; ajint i; if(!acdDoValid) return; if(!typeTable) acdReadSections(&typeTable, &infoTable); if(ajCharMatchC(acdKeywords[thys->Type].Name, "endsection")) { --sectLevel; if(sectLevel < 0) acdErrorValid("Too many endsections"); return; } ++sectLevel; if(sectLevel == 1) { ajStrAssignS(§NameTop, thys->Name); for(i=0; acdSections[i]; i++) { if(ajStrMatchC(thys->Name, acdSections[i]->Name)) { if(i < sectNumber) acdWarn("Section '%S' follows section '%s'", thys->Name, acdSections[sectNumber]->Name); else sectNumber = i; break; } } if(!acdSections[i]) acdWarn("No defined order for primary section '%S'", thys->Name); } /* should have a known name */ sectType = ajTableFetchS(typeTable, thys->Name); tmpstr = acdAttrValue(thys, "type"); if(!sectType) { if(sectLevel == 1) acdErrorValid("Section '%S' not defined in sections.standard file", thys->Name); else acdWarn("Sub level section '%S' not defined in " "sections.standard file", thys->Name); /* if unknown, must be distinctive - check for common words? */ return; } else { /* if known, must have a standard type */ if(sectLevel == 1) { if(!ajStrMatchC(tmpstr, "page")) acdErrorValid("Top level section '%S' not of type 'page'", thys->Name); else if(!ajStrMatchC(sectType, "page")) acdErrorValid("Top level section '%S' defined as " "sub type of '%S' in sections.standard", thys->Name, sectType); } else { if(ajStrMatchC(tmpstr, "page")) acdErrorValid("Sub level section '%S' not of type 'frame'", thys->Name); else if(ajStrPrefixC(sectType, "page")) acdErrorValid("Sub level section '%S' not defined " "as type 'frame' in sections.standard", thys->Name); else if(!ajStrMatchS(sectType, sectNameTop)) acdErrorValid("Sub level section '%S' should be under '%S'", thys->Name, sectType); } } sectInfo = ajTableFetchS(infoTable, thys->Name); tmpstr = acdAttrValue(thys, "information"); /* must have an information attribute */ if(!ajStrGetLen(tmpstr)) acdWarn("Section has no information string"); /* if known, must have a standard info string */ else { if(!ajStrMatchS(sectInfo, tmpstr)) { if(ajStrMatchCaseS(sectInfo, tmpstr)) acdWarn("Section info '%S' expected, case mismatch", sectInfo); else acdErrorValid("Section info '%S' expected, found '%S'", sectInfo, tmpstr); } } return; } ID acdValidQual TY static MO ajacd LB acd XX DE Validation for a qualifier definition XX PN [1] PA u thys AcdPAcd PD ACD object PX RT void RD RX // static void acdValidQual(AcdPAcd thys) { ajint itype; AjBool isparam = ajFalse; AjBool boolval; AjBool toggle; AjBool isParameter = ajFalse; AjBool isStandard = ajFalse; AjBool isAdditional = ajFalse; AjBool isToggle = ajFalse; static AjPStr secname = NULL; const AjPStr relstr = NULL; const AjPStr tmpstr = NULL; const AjPStr tmpinfo = NULL; const AjPStr tmpprompt = NULL; const AjPStr tmphelp = NULL; const AjPStr tmpstandard = NULL; static ajint qualCountSeq = 0; static ajint qualCountSeqout = 0; static ajint qualCountInfile = 0; static ajint qualCountOutfile = 0; static ajint qualCountIn = 0; static ajint qualCountOut = 0; static ajint qualCountFeat = 0; static ajint qualCountFeatout = 0; static AjPStr qualName = NULL; static AjPStr qualSeqFirst = NULL; static AjPStr qualSeqoutFirst = NULL; static AjPStr seqTypeIn = NULL; static AjPStr qualFeatFirst = NULL; static AjPStr qualFeatoutFirst = NULL; static AjBool seqMulti = AJFALSE; static AjBool seqoutMulti = AJFALSE; static AjBool featMulti = AJFALSE; static AjBool featoutMulti = AJFALSE; const AjPStr namespace = NULL; AjPStr relation = NULL; AjPStrTok tokenhandle = NULL; ajuint ireldata = 0; if(!acdDoValid) return; if(acdEdam) { relstr = acdAttrValue(thys, "relations"); tokenhandle = ajStrTokenNewC(relstr, "|"); while(ajStrTokenNextParse(&tokenhandle, &relation)) { namespace = acdEdamTest(relation); if(!namespace) acdErrorValid("Qualifier relation '%S' not found", relation); else if(ajStrMatchC(namespace, "data")) ireldata++; else if(ajStrMatchC(namespace, "format")) ireldata++; else if(ajStrMatchC(namespace, "identifier")) ireldata++; else acdErrorValid("Qualifier has relation '%S' with namespace '%S'", relation, namespace); } ajStrDel(&relation); ajStrTokenDel(&tokenhandle); } if(ajListGetLength(acdSecList)) { acdValidSectionFull(&secname); } else { acdErrorValid("No section defined for qualifier '%S'", thys->Name); ajStrAssignC(&secname, ""); } if (acdType[thys->Type].Section) { if (!acdValidSectionMatch(acdType[thys->Type].Section->Name)) acdErrorValid("Qualifier '%S' type '%s' not in section '%s'", thys->Name, acdType[thys->Type].Name, acdType[thys->Type].Section->Name); } if(ajCharMatchC(acdType[thys->Type].Name, "toggle")) isToggle = ajTrue; /* parameter, standard, additional only once, with 'Y' */ itype = 0; tmpstr = acdAttrValue(thys, "parameter"); if(ajStrGetLen(tmpstr)) { itype++; if(acdVarTestValid(tmpstr, &toggle)) { isParameter = ajTrue; acdErrorValid("Calculated parameter value for '%S'", thys->Name); } else { if(ajStrToBool(tmpstr,&isparam)) { if(isparam) { isParameter = ajTrue; } else { acdErrorValid("Parameter defined as false '%S'", tmpstr); itype--; } } } } tmpstr = acdAttrValue(thys, "standard"); if(ajStrGetLen(tmpstr)) { itype++; if(acdVarTestValid(tmpstr, &toggle)) { isStandard = ajTrue; if (!toggle) acdWarn("Calculated standard value for '%S'", thys->Name); if (acdValidSectionMatch("advanced")) acdWarn("Calculated standard value for qualifier '%S' " "in section '%S'", thys->Name, secname); } else { if(ajStrToBool(tmpstr,&boolval)) { if(boolval) { isStandard = ajTrue; } else { acdErrorValid("Standard defined as false '%S'", tmpstr); itype--; } } } } tmpstr = acdAttrValue(thys, "additional"); if(ajStrGetLen(tmpstr)) { itype++; if(acdVarTestValid(tmpstr, &toggle)) { isAdditional = ajTrue; if (!toggle) acdWarn("Calculated additional value for '%S'", thys->Name); if (acdValidSectionMatch("advanced")) acdWarn("Calculated additional value for qualifier '%S' " "in section '%S'", thys->Name, secname); } else { if(ajStrToBool(tmpstr,&boolval)) { if(boolval) isAdditional = ajTrue; else { acdErrorValid("Additional defined as false '%S'", tmpstr); itype--; } } } } if(itype > 1) acdErrorValid("Multiple definition of parameter/standard/additional"); if (isParameter) { if (acdValidSectionMatch("advanced") || acdValidSectionMatch("additional")) acdErrorValid("Parameter '%S' in section '%S'", thys->Name, secname); } else if (isStandard) { if (acdValidSectionMatch("advanced") || acdValidSectionMatch("additional")) acdWarn("Standard qualifier '%S' " "in section '%S'", thys->Name, secname); } else if (isAdditional) { if (acdValidSectionMatch("advanced") || (!isToggle && acdValidSectionMatch("required"))) acdWarn("Additional qualifier '%S' " "in section '%S'", thys->Name, secname); } else /* must be advanced */ { if (!isToggle) { if (acdValidSectionMatch("additional") || acdValidSectionMatch("required")) acdWarn("Advanced qualifier '%S' " "in section '%S'", thys->Name, secname); } } tmpinfo = acdAttrValue(thys, "information"); tmpprompt = acdAttrValue(thys, "prompt"); tmphelp = acdAttrValue(thys, "help"); if(acdType[thys->Type].Prompt) { tmpstandard = (*acdType[thys->Type].Prompt)(thys); if(ajStrGetLen(tmpstandard) && acdKnowntypeDesc(thys)) { if(ajStrGetLen(tmpinfo)) { if(!ajStrMatchS(tmpinfo, tmpstandard)) acdWarn("Information string for '%S' '%S' not standard '%S'", thys->Name, tmpinfo, tmpstandard); } else { acdWarn("Missing standard information '%S' expected '%S'", thys->Name, tmpstandard); } } /* else if(ajStrGetLen(tmpinfo)) { acdWarn("Standard prompt for '%S' is '%S' information '%S'", thys->Name, tmpstandard, tmpinfo); } */ } if(ajStrGetLen(tmpprompt) && !ajStrGetLen(tmpinfo)) acdErrorValid("Prompt specified but no information"); if(ajStrGetLen(tmpinfo) && !isupper((int)ajStrGetCharFirst(tmpinfo))) { if (islower((int)ajStrGetCharFirst(tmpinfo))) acdWarn("Information string for '%S' starts in lower case", thys->Name); else acdWarn("Information string for '%S' starts non-alphabetic", thys->Name); } if(ajStrGetLen(tmpprompt) && !isupper((int)ajStrGetCharFirst(tmpprompt))) { if (islower((int)ajStrGetCharFirst(tmpprompt))) acdWarn("Prompt string for '%S' starts in lower case", thys->Name); else acdWarn("Prompt string for '%S' starts non-alphabetic", thys->Name); } if(ajStrGetLen(tmphelp) && !isupper((int)ajStrGetCharFirst(tmphelp))) { if (islower((int)ajStrGetCharFirst(tmphelp))) acdWarn("Help string for '%S' starts in lower case", thys->Name); else acdWarn("Help string for '%S' starts non-alphabetic", thys->Name); } /* ** if known, must have a standard info string ** but we can make allowances for possibly confusing 2nd occurrence ** and beyond ** and also allow for those with a default value that are usually not ** prompted for */ if(acdType[thys->Type].Stdprompt && (ajStrGetLen(tmpinfo) || ajStrGetLen(tmpprompt)) && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "knowntype") && *acdType[thys->Type].UseClassCount == 1) { acdWarn("Unexpected information value for type '%s'", acdType[thys->Type].Name); } /* else it must have an info attribute or a knowntype */ if(!acdType[thys->Type].Stdprompt && !ajStrGetLen(tmpinfo) && !ajStrGetLen(tmpprompt) && !acdAttrTestDefined(thys, "knowntype")) { acdErrorValid("Missing information value for type '%s'", acdType[thys->Type].Name); } /* if known, must have a standard type */ /* expected types should have a known name */ /* sequence seqset seqall see below - need to do seqout, infile, outfile */ if(ajCharMatchC(acdType[thys->Type].Name, "sequence") || ajCharMatchC(acdType[thys->Type].Name, "seqall") || ajCharMatchC(acdType[thys->Type].Name, "seqsetall") || ajCharMatchC(acdType[thys->Type].Name, "seqset")) { if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First sequence input '%S' is not a parameter", thys->Token); else acdWarn("Subsequent sequence input '%S' is not a parameter", thys->Token); } qualCountIn++; qualCountSeq++; if(qualCountSeq == 1) ajStrAssignS(&qualSeqFirst, thys->Token); ajFmtPrintS(&qualName, "%csequence", (char) ('a' - 1 + qualCountSeq)); if(!(ajStrSuffixC(thys->Token, "sequence") || (ajCharMatchC(acdType[thys->Type].Name, "seqall") && ajStrSuffixC(thys->Token, "seqall")) || (ajCharMatchC(acdType[thys->Type].Name, "seqset") && ajStrSuffixC(thys->Token, "sequences")) || (ajCharMatchC(acdType[thys->Type].Name, "seqsetall") && ajStrSuffixC(thys->Token, "sequences")) )) { if(ajCharMatchC(acdType[thys->Type].Name, "seqall")) acdWarn("Sequence qualifier '%S' is not 'sequence' " "or '*sequence' or 'seqall' " "(should be '%Ssequence')", thys->Token, thys->Token); else if(ajCharMatchC(acdType[thys->Type].Name, "seqset")) acdWarn("Sequence qualifier '%S' is not 'sequence' " "or '*sequence' or 'sequences' " "(should be '%Ssequence')", thys->Token, thys->Token); else if(ajCharMatchC(acdType[thys->Type].Name, "seqsetall")) acdWarn("Sequence qualifier '%S' is not 'sequence' " "or '*sequence' or 'sequences' " "(should be '%Ssequence')", thys->Token, thys->Token); else acdWarn("Sequence qualifier '%S' is not 'sequence' " "or '*sequence' " "(should be '%Ssequence')", thys->Token, thys->Token); } else { if((qualCountSeq > 1) || !(ajStrMatchC(thys->Token, "sequence") || (ajCharMatchC(acdType[thys->Type].Name, "seqall") && ajStrSuffixC(thys->Token, "seqall")) || (ajCharMatchC(acdType[thys->Type].Name, "seqsetall") && ajStrSuffixC(thys->Token, "sequences")) || (ajCharMatchC(acdType[thys->Type].Name, "seqset") && ajStrSuffixC(thys->Token, "sequences")) )) seqMulti = ajTrue; if(seqMulti) { if ((ajStrGetLen(thys->Token) == ajStrGetLen(qualName)) && ajStrSuffixC(thys->Token, "sequence")) { if(!ajStrMatchS(thys->Token, qualName)) acdWarn("Expected sequence qualifier is '%S' " "found '%S'", qualName, thys->Token); } } } tmpstr = acdAttrValue(thys, "type"); if(!ajStrGetLen(tmpstr)) acdErrorValid("No type specified for input sequence"); else if(qualCountSeq == 1) ajStrAssignS(&seqTypeIn, tmpstr); if(ajCharMatchC(acdType[thys->Type].Name, "seqset") || ajCharMatchC(acdType[thys->Type].Name, "seqsetall")) { if(!acdAttrTestDefined(thys, "aligned")) acdErrorValid("Sequence set '%S' has no 'aligned' attribute", thys->Token); } } if(ajCharMatchC(acdType[thys->Type].Name, "feature")) { if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First feature input '%S' is not a parameter", thys->Token); else acdWarn("Subsequent feature input '%S' is not a parameter", thys->Token); } qualCountFeat++; if(qualCountFeat == 1) ajStrAssignS(&qualFeatFirst, thys->Token); ajFmtPrintS(&qualName, "%cfeature", (char) ('a' - 1 + qualCountFeat)); if(!(ajStrSuffixC(thys->Token, "feature"))) { acdWarn("Feature qualifier '%S' is not 'feature' " "or '*feature' " "(should be '%Sfeature')", thys->Token, thys->Token); } else { if((qualCountFeat > 1) || !(ajStrMatchC(thys->Token, "feature"))) featMulti = ajTrue; if(featMulti) if ((ajStrGetLen(thys->Token) == ajStrGetLen(qualName)) && ajStrSuffixC(thys->Token, "feature")) { if(!ajStrMatchS(thys->Token, qualName)) acdWarn("Expected feature qualifier is '%S' " "found '%S'", qualName, thys->Token); } } /* still to do - check for type */ tmpstr = acdAttrValue(thys, "type"); if(!ajStrGetLen(tmpstr) && !ajStrGetLen(seqTypeIn)) acdErrorValid("No type specified for input feature, " "and no input sequence type as a default"); } /* infile - assume parameter -infile */ /* check for type */ if(ajCharMatchC(acdType[thys->Type].Name, "infile") || ajCharMatchC(acdType[thys->Type].Name, "filelist") || ajCharMatchC(acdType[thys->Type].Name, "directory") || ajCharMatchC(acdType[thys->Type].Name, "dirlist")) { if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(ajCharMatchC(acdType[thys->Type].Name, "directory") || ajCharMatchC(acdType[thys->Type].Name, "dirlist")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First input directory '%S' is not a " "parameter", thys->Token); else acdWarn("Subsequent input directory '%S' is not a " "parameter", thys->Token); } else { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First input file '%S' is not a parameter", thys->Token); else acdWarn("Subsequent input file '%S' is not a parameter", thys->Token); } } qualCountIn++; qualCountInfile++; if(ajCharMatchC(acdType[thys->Type].Name, "infile")) { if(!ajStrSuffixC(thys->Token, "file")) acdWarn("Infile qualifier '%S' is not 'infile' or '*file' " "(should be '%Sfile')", thys->Token, thys->Token); else { if((qualCountIn == 1) && !ajStrMatchC(thys->Token, "infile") && !ajStrSuffixC(thys->Token, "file")) acdWarn("First input file qualifier '%S' is not " "'infile' or '*file' " "(should be '%Sfile')", thys->Token, thys->Token); } } else if(ajCharMatchC(acdType[thys->Type].Name, "filelist")) { if(!ajStrSuffixC(thys->Token, "files")) acdWarn("Filelist qualifier '%S' is not '*files'", thys->Token); /* no fixed qualifier name for first input filelist */ } else if(ajCharMatchC(acdType[thys->Type].Name, "directory") || ajCharMatchC(acdType[thys->Type].Name, "dirlist")) { if(ajStrSuffixC(thys->Token, "outdir")) acdWarn("Directory qualifier '%S' has outdir style name " "'*outdir'", thys->Token); else if(!ajStrSuffixC(thys->Token, "dir") && !ajStrSuffixC(thys->Token, "path") && !ajStrSuffixC(thys->Token, "directory")) acdWarn("Directory qualifier '%S' is not '*directory or *dir'" " or *path' " "(should be '%Sdir')", thys->Token, thys->Token); /* no fixed qualifier name for first input directory */ } tmpstr = acdAttrValue(thys, "knowntype"); if(!ajStrGetLen(tmpstr)) acdWarn("No knowntype specified for input file"); } /* datafile - no standard qualifier name yet */ /* check for knowntype */ if(ajCharMatchC(acdType[thys->Type].Name, "datafile")) { tmpstr = acdAttrValue(thys, "knowntype"); if(!ajStrGetLen(tmpstr)) acdWarn("No knowntype specified for data file"); } /* outfile - assume parameter unless default is stdout -outfile */ /* check for type */ if(ajCharMatchC(acdType[thys->Type].Name, "outfile")) { /* Skip this test - there is a good default for output files */ /* if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First output file '%S' is not a parameter", thys->Token); else acdWarn("Subsequent output file '%S' is not a parameter", thys->Token); } */ qualCountOut++; qualCountOutfile++; if(ajCharMatchC(acdType[thys->Type].Name, "outfile") && !ajStrSuffixC(thys->Token, "file")) acdWarn("Outfile qualifier '%S' is not 'outfile' or '*file' " "(should be '%Sfile')", thys->Token, thys->Token); else { if((qualCountOut == 1) && !ajStrMatchC(thys->Token, "outfile")) { acdWarn("First output file qualifier '%S' is not 'outfile'", thys->Token); } } /* still to do - check for type */ tmpstr = acdAttrValue(thys, "knowntype"); if(!ajStrGetLen(tmpstr)) acdWarn("No knowntype specified for output file"); } /* outdirectory - assume parameter unless default is stdout -outfile */ /* check for type */ if(ajCharMatchC(acdType[thys->Type].Name, "outdir")) { if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First output directory '%S' is not a parameter", thys->Token); else acdWarn("Subsequent output directory '%S' is not a parameter", thys->Token); } qualCountOut++; qualCountOutfile++; if(ajCharMatchC(acdType[thys->Type].Name, "outdir") && !ajStrSuffixC(thys->Token, "outdir")) acdWarn("Outdir qualifier '%S' is not 'outdir' or '*outdir'", thys->Token); else { if((qualCountOut == 1) && !ajStrMatchC(thys->Token, "outdir") && !ajStrSuffixC(thys->Token, "outdir")) acdWarn("First output directory qualifier '%S' " "is not 'outdir' or '*outdir' " "(should be '%Sfile')", thys->Token, thys->Token); } /* still to do - check for type */ tmpstr = acdAttrValue(thys, "knowntype"); if(!ajStrGetLen(tmpstr)) acdWarn("No knowntype specified for output directory"); } /* align - as for outfile? */ if(ajCharMatchC(acdType[thys->Type].Name, "align")) { if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First alignment file '%S' is not a parameter", thys->Token); else acdWarn("Subsequent alignment file '%S' is not a parameter", thys->Token); } qualCountOut++; qualCountOutfile++; if(!ajStrSuffixC(thys->Token, "file")) acdWarn("Align qualifier '%S' is not 'outfile' or '*file' " "(should be '%Sfile')", thys->Token, thys->Token); else { if((qualCountOut == 1) && !ajStrMatchC(thys->Token, "outfile")) acdWarn("First alignment file qualifier '%S' is not 'outfile'", thys->Token); } } /* report - as for outfile? */ if(ajCharMatchC(acdType[thys->Type].Name, "report")) { if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First report file '%S' is not a parameter", thys->Token); else acdWarn("Subsequent report file '%S' is not a parameter", thys->Token); } qualCountOut++; qualCountOutfile++; if(!ajStrSuffixC(thys->Token, "file")) acdWarn("Report qualifier '%S' is not 'outfile' or '*file' " "(should be '%Sfile')", thys->Token, thys->Token); else { if((qualCountOut == 1) && !ajStrMatchC(thys->Token, "outfile")) acdWarn("First report file qualifier '%S' is not 'outfile'", thys->Token); } } /* seqout* - assume parameter - what names? -outseq? */ /* type only if there is no sequence input */ if(ajCharMatchC(acdType[thys->Type].Name, "seqout") || ajCharMatchC(acdType[thys->Type].Name, "seqoutall") || ajCharMatchC(acdType[thys->Type].Name, "seqoutset")) { /* skip this test - there is a good default for sequence output */ /* if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First sequence output '%S' is not a parameter", thys->Token); else acdWarn("Subsequent sequence output '%S' is not a parameter", thys->Token); } */ qualCountOut++; qualCountSeqout++; if(qualCountSeqout == 1) ajStrAssignS(&qualSeqoutFirst, thys->Token); ajFmtPrintS(&qualName, "%coutseq", (char) ('a' - 1 + qualCountSeqout)); if(!ajStrSuffixC(thys->Token, "outseq") && !ajStrSuffixC(thys->Token, "outfile")) acdWarn("Sequence output qualifier '%S' is not 'outseq' " "or '*outseq' or '*outfile'" "(should be '%Soutseq')", thys->Token, thys->Token); else { if((qualCountOut > 1) || (!ajStrMatchC(thys->Token, "outseq") && !ajStrMatchC(thys->Token, "outfile"))) seqoutMulti = ajTrue; if(seqoutMulti) { if ((ajStrGetLen(thys->Token) == ajStrGetLen(qualName)) && ajStrSuffixC(thys->Token, "outseq")) { if(!ajStrMatchS(thys->Token, qualName)) acdWarn("Expected sequence output qualifier is '%S' " "found '%S'", qualName, thys->Token); } } } /* still to do - check for type */ tmpstr = acdAttrValue(thys, "type"); if(!ajStrGetLen(tmpstr) && !ajStrGetLen(seqTypeIn)) acdErrorValid("No type specified for output sequence, " "and no input sequence type as a default"); } /* featout - assume parameter - what names? -outfeat? */ /* type only if there is no sequence input */ if(ajCharMatchC(acdType[thys->Type].Name, "featout")) { if(!isparam && !acdAttrTestDefined(thys, "default") && !acdAttrTestDefined(thys, "nullok")) { if(*acdType[thys->Type].UseClassCount == 1) acdErrorValid("First feature output '%S' is not a parameter", thys->Token); else acdWarn("Subsequent feature output '%S' is not a parameter", thys->Token); } qualCountFeatout++; if(qualCountFeatout == 1) ajStrAssignS(&qualFeatoutFirst, thys->Token); ajFmtPrintS(&qualName, "%coutfeat", (char) ('a' - 1 + qualCountFeatout)); if(!ajStrMatchC(thys->Token, "outfeat") && !ajStrSuffixC(thys->Token, "outfeat")) acdWarn("Feature output qualifier '%S' is not 'outfeat' " "or '*outfeat'" "(should be '%Soutfeat')", thys->Token, thys->Token); else { if((qualCountFeatout > 1) || (!ajStrMatchC(thys->Token, "outfeat"))) featoutMulti = ajTrue; if(featoutMulti) { if ((ajStrGetLen(thys->Token) == ajStrGetLen(qualName)) && ajStrSuffixC(thys->Token, "outfeat")) { if(!ajStrMatchS(thys->Token, qualName)) acdWarn("Expected feature output qualifier is '%S' " "found '%S'", qualName, thys->Token); } } } /* still to do - check for type */ tmpstr = acdAttrValue(thys, "type"); if(!ajStrGetLen(tmpstr) && !ajStrGetLen(seqTypeIn)) acdErrorValid("No type specified for output feature, " "and no input sequence type as a default"); } /* string - we don't ask much, but we do prefer strings to have a known type that does not suggest some other datatype can be used */ if(ajCharMatchC(acdType[thys->Type].Name, "string")) { tmpstr = acdAttrValue(thys, "knowntype"); if(!ajStrGetLen(tmpstr)) { tmpstr = acdAttrValue(thys, "pattern"); if (!ajStrGetLen(tmpstr)) acdWarn("No knowntype specified for string"); else acdWarn("Pattern but no knowntype specified for string"); } } acdValidKnowntype(thys); return; } ID acdValidKnowntype TY static MO ajacd LB acd XX DE Validation for Known type XX PN [1] PA r thys const AcdPAcd PD Current ACD object PX RT void RD RX // static void acdValidKnowntype(const AcdPAcd thys) { const AjPStr typestr = NULL; const AjPStr acdKnownType = NULL; static AjPStr defType = NULL; AjBool typeok = ajFalse; if(!acdDoValid) return; typestr = acdAttrValue(thys, "knowntype"); if (!ajStrGetLen(typestr)) return; if (!defType) ajFmtPrintS(&defType, "%S output", acdProgram); acdKnownType = ajTableFetchS(acdKnowntypeTypeTable, typestr); if (!acdKnownType) { if(ajStrFindAnyK(typestr, '_') >= 0) { acdWarn("Knowntype '%S' replace underscore(s) with spaces", typestr); } else { if (!ajStrMatchS(typestr, defType)) acdWarn("Knowntype '%S' not defined in knowntypes.standard", typestr); } return; } if (ajStrMatchC(acdKnownType, "file")) { if (!ajCharMatchC(acdType[thys->Type].Name, "infile") && !ajCharMatchC(acdType[thys->Type].Name, "datafile") && !ajCharMatchC(acdType[thys->Type].Name, "directory") && !ajCharMatchC(acdType[thys->Type].Name, "dirlist") && !ajCharMatchC(acdType[thys->Type].Name, "outfile") && !ajCharMatchC(acdType[thys->Type].Name, "outdir") && !ajCharMatchC(acdType[thys->Type].Name, "filelist")) { acdWarn("Knowntype '%S' defined for type '%S', used for '%s'", typestr, acdKnownType, acdType[thys->Type].Name); } } else if (ajStrMatchC(acdKnownType, "sequence")) { if (!ajCharMatchC(acdType[thys->Type].Name, "sequence") && !ajCharMatchC(acdType[thys->Type].Name, "seqall") && !ajCharMatchC(acdType[thys->Type].Name, "seqset") && !ajCharMatchC(acdType[thys->Type].Name, "seqsetall") && !ajCharMatchC(acdType[thys->Type].Name, "seqout") && !ajCharMatchC(acdType[thys->Type].Name, "seqoutall") && !ajCharMatchC(acdType[thys->Type].Name, "seqoutset") && !ajCharMatchC(acdType[thys->Type].Name, "seqoutsetall")) { acdWarn("Knowntype '%S' defined for type '%S', used for '%s'", typestr, acdKnownType, acdType[thys->Type].Name); } } else if (ajStrMatchC(acdKnownType, "codon") || ajStrMatchC(acdKnownType, "cpdb") || ajStrMatchC(acdKnownType, "matrix") || ajStrMatchC(acdKnownType, "discretestates") || ajStrMatchC(acdKnownType, "distances") || ajStrMatchC(acdKnownType, "frequencies") || ajStrMatchC(acdKnownType, "properties") || ajStrMatchC(acdKnownType, "scop") || ajStrMatchC(acdKnownType, "tree")) { typeok = ajFalse; if (ajStrMatchC(acdKnownType, "codon")) if(ajCharMatchC(acdType[thys->Type].Name, "codon") || ajCharMatchC(acdType[thys->Type].Name, "outcodon")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "cpdb")) if(ajCharMatchC(acdType[thys->Type].Name, "cpdb") || ajCharMatchC(acdType[thys->Type].Name, "outcpdb")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "discretestates")) if(ajCharMatchC(acdType[thys->Type].Name, "discretestates") || ajCharMatchC(acdType[thys->Type].Name, "outdiscrete")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "distances")) if(ajCharMatchC(acdType[thys->Type].Name, "distances") || ajCharMatchC(acdType[thys->Type].Name, "outdistances")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "frequencies")) if(ajCharMatchC(acdType[thys->Type].Name, "frequencies") || ajCharMatchC(acdType[thys->Type].Name, "outfreq")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "obo")) if(ajCharMatchC(acdType[thys->Type].Name, "obo") || ajCharMatchC(acdType[thys->Type].Name, "outobo")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "properties")) if(ajCharMatchC(acdType[thys->Type].Name, "properties") || ajCharMatchC(acdType[thys->Type].Name, "outproperties")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "resource")) if(ajCharMatchC(acdType[thys->Type].Name, "resource") || ajCharMatchC(acdType[thys->Type].Name, "outresource")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "scop")) if(ajCharMatchC(acdType[thys->Type].Name, "scop") || ajCharMatchC(acdType[thys->Type].Name, "outscop")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "tree")) if(ajCharMatchC(acdType[thys->Type].Name, "tree") || ajCharMatchC(acdType[thys->Type].Name, "outtree")) typeok = ajTrue; if (ajStrMatchC(acdKnownType, "matrix")) if(ajCharMatchC(acdType[thys->Type].Name, "matrix") || ajCharMatchC(acdType[thys->Type].Name, "matrixf") || ajCharMatchC(acdType[thys->Type].Name, "outmatrix") || ajCharMatchC(acdType[thys->Type].Name, "outmatrixf")) typeok = ajTrue; if (!ajCharMatchC(acdType[thys->Type].Name, "infile") && !ajCharMatchC(acdType[thys->Type].Name, "datafile") && !ajCharMatchC(acdType[thys->Type].Name, "directory") && !ajCharMatchC(acdType[thys->Type].Name, "dirlist") && !ajCharMatchC(acdType[thys->Type].Name, "outfile") && !ajCharMatchC(acdType[thys->Type].Name, "outdir") && !ajCharMatchC(acdType[thys->Type].Name, "filelist")) { if(!typeok) acdWarn("Knowntype '%S' defined for type '%S', used for '%s'", typestr, acdKnownType, acdType[thys->Type].Name); } } else if (!ajStrMatchC(acdKnownType, acdType[thys->Type].Name)) { acdWarn("Knowntype '%S' defined for type '%S', used for '%s'", typestr, acdKnownType, acdType[thys->Type].Name); } return; } ID acdKnowntypeDesc TY static MO ajacd LB acd XX DE Return description of known type XX PN [1] PA r thys const AcdPAcd PD Acd object PX RT const AjPStr RD Known type description or NULL if not defined. RX // static const AjPStr acdKnowntypeDesc(const AcdPAcd thys) { const AjPStr knowntype = NULL; const AjPStr knowndesc; knowntype = acdAttrValue(thys, "knowntype"); if(!ajStrGetLen(knowntype)) return NULL; knowndesc = ajTableFetchS(acdKnowntypeDescTable, knowntype); return knowndesc; } ID acdReadKnowntype TY static MO ajacd LB acd XX DE Read standard file of ACD sections and store in new AjPTable objects XX PN [1] PA wN desctable AjPTable* PD String table of section names and types PX PN [2] PA wN typetable AjPTable* PD String table of section names and PD descriptions PX RT void RD RX // static void acdReadKnowntype(AjPTable* desctable, AjPTable* typetable) { AjPFile knownFile = NULL; AjPStr knownFName = NULL; AjPStr knownRoot = NULL; AjPStr knownRootInst = NULL; AjPStr knownPack = NULL; AjPStr knownLine = NULL; AjBool ok = ajFalse; AjPStrTok handle = NULL; AjPStr knownName = NULL; AjPStr knownName2 = NULL; AjPStr knownType = NULL; AjPStr knownDesc = NULL; AjPStr knownEdam = NULL; AjPStr knownRest = NULL; ajint iline = 0; ajStrAssignS(&knownPack, ajNamValuePackage()); ajStrAssignS(&knownRootInst, ajNamValueInstalldir()); ajDirnameFix(&knownRootInst); *desctable = ajTablestrNewCase(2048); *typetable = ajTablestrNewCase(2048); if(ajNamGetValueC("acdroot", &knownRoot)) { ajDirnameFix(&knownRoot); ajFmtPrintS(&knownFName, "%Sknowntypes.standard", knownRoot); knownFile = ajFileNewInNameS(knownFName); acdLog("Knowntypes file in acdroot: '%S'\n", knownFName); } else { ajFmtPrintS(&knownFName, "%Sshare/%S/acd/knowntypes.standard", knownRootInst, knownPack); acdLog("Knowntypes file installed: '%S'\n", knownFName); knownFile = ajFileNewInNameS(knownFName); if(!knownFile) { acdLog("Knowntypes file '%S' not opened\n", knownFName); ajStrAssignS(&knownRoot, ajNamValueRootdir()); ajDirnameFix(&knownRoot); ajFmtPrintS(&knownFName, "%Sacd/knowntypes.standard", knownRoot); acdLog("Knowntypes file from source dir: '%S'\n", knownFName); knownFile = ajFileNewInNameS(knownFName); } } if(!knownFile) /* test acdc-knownmissing */ ajDie("Knowntypes file %S not found", knownFName); else acdLog("Knowntypes file %F used\n", knownFile); while(knownFile && ajReadlineTrim(knownFile, &knownLine)) { iline++; if(ajStrCutComments(&knownLine)) { handle = ajStrTokenNewC(knownLine, "|"); ok = ajStrTokenNextParse(&handle, &knownName); if(ok) ok = ajStrTokenNextParse(&handle, &knownType); if(ok) ok = ajStrTokenNextParse(&handle, &knownEdam); if(ok) ajStrTokenRestParse(&handle, &knownDesc); ajStrTokenDel(&handle); if(ok) { ajStrRemoveWhiteExcess(&knownName); ajStrExchangeKK(&knownName, '_', ' '); ajStrRemoveWhiteExcess(&knownType); if(ajStrMatchCaseC(knownType, "infile") || ajStrMatchCaseC(knownType, "filelist") || ajStrMatchCaseC(knownType, "datafile") || ajStrMatchCaseC(knownType, "outfile")) { ajWarn("Knowntype '%S' in file %S line %d - use 'file'", knownType, knownFName, iline); } if(ajTablePut(*typetable, knownName, knownType)) ajWarn("Duplicate knowntype name '%S' in file %S line %d", knownName, knownFName, iline); ajStrAssignS(&knownName2, knownName); ajStrRemoveWhiteExcess(&knownEdam); ajStrQuoteStrip(&knownEdam); if(ajStrPrefixC(knownEdam, "EDAM_data: ")) { ajStrCutStart(&knownEdam, 11); } else if(ajStrPrefixC(knownEdam, "EDAM_data:")) { ajStrCutStart(&knownEdam, 14); } else if(ajStrGetLen(knownEdam)) ajWarn("Knowntype '%S' in file %S line %d - EDAM badly formatted '%S'", knownType, knownFName, iline, knownEdam); ajStrRemoveWhiteExcess(&knownDesc); ajTablePut(*desctable, knownName2, knownDesc); /* ajUser("name '%S' type '%S' desc '%S' edam '%S'", knownName, knownType, knownDesc, knownEdam);*/ knownName = NULL; knownName2 = NULL; knownType = NULL; knownDesc = NULL; } else ajErr("Bad record in file %S:\n%S", knownFName, knownLine); } } ajFileClose(&knownFile); ajStrDel(&knownFName); ajStrDel(&knownRoot); ajStrDel(&knownRootInst); ajStrDel(&knownPack); ajStrDel(&knownLine); ajStrDel(&knownName); ajStrDel(&knownType); ajStrDel(&knownEdam); ajStrDel(&knownDesc); ajStrDel(&knownRest); return; } ID acdValidApplGroup TY static MO ajacd LB acd XX DE Validation for application groups XX PN [1] PA r groups const AjPStr PD Group name(s) PX RT void RD RX // static void acdValidApplGroup(const AjPStr groups) { AjPRegexp grpexp = NULL; AjPStr tmpGroups = NULL; AjPStr grpName = NULL; const AjPStr grpDesc = NULL; if(!acdDoValid) return; acdGrpTable = acdReadGroups(); ajStrAssignS(&tmpGroups, groups); /* step through each group */ grpexp = ajRegCompC("([^,|]+),?"); while(ajRegExec(grpexp, tmpGroups)) { ajRegSubI(grpexp, 1, &grpName); ajStrRemoveWhiteExcess(&grpName); grpDesc = ajTableFetchS(acdGrpTable, grpName); if(!grpDesc) acdErrorValid("Unknown group '%S' for application", grpName); ajRegPost(grpexp, &tmpGroups); } ajStrDel(&grpName); ajStrDel(&tmpGroups); ajRegFree(&grpexp); return; } ID acdValidApplKeywords TY static MO ajacd LB acd XX DE Validation for application keywords XX PN [1] PA r keys const AjPStr PD Keyword(s) PX RT void RD RX // static void acdValidApplKeywords(const AjPStr keys) { static AjPTable keyTable = NULL; AjPRegexp keyexp = NULL; AjPStr tmpKeys = NULL; AjPStr keyName = NULL; const AjPStr keyDesc = NULL; if(!acdDoValid) return; keyTable = acdReadKeywords(); ajStrAssignS(&tmpKeys, keys); /* step through each group */ keyexp = ajRegCompC("([^,|]+),?"); while(ajRegExec(keyexp, tmpKeys)) { ajRegSubI(keyexp, 1, &keyName); ajStrRemoveWhiteExcess(&keyName); keyDesc = ajTableFetchS(keyTable, keyName); if(!keyDesc) acdErrorValid("Unknown keyword '%S' for application", keyName); ajRegPost(keyexp, &tmpKeys); } ajStrDel(&keyName); ajStrDel(&tmpKeys); ajRegFree(&keyexp); return; } ID acdReadGroups TY static MO ajacd LB acd XX DE Read standard table of application groups XX RT AjPTable RD String table of group names and descriptions RX // static AjPTable acdReadGroups(void) { AjPTable ret = ajTablestrNewCase(50); AjPFile grpFile = NULL; AjPStr grpFName = NULL; AjPStr grpRoot = NULL; AjPStr grpRootInst = NULL; AjPStr grpPack = NULL; AjPStr grpLine = NULL; AjPRegexp grpxp = NULL; AjPStr grpName = NULL; AjPStr grpDesc = NULL; ajStrAssignS(&grpPack, ajNamValuePackage()); ajStrAssignS(&grpRootInst, ajNamValueInstalldir()); ajDirnameFix(&grpRootInst); if(ajNamGetValueC("acdroot", &grpRoot)) { ajDirnameFix(&grpRoot); ajFmtPrintS(&grpFName, "%Sgroups.standard", grpRoot); grpFile = ajFileNewInNameS(grpFName); acdLog("Group file in acdroot: '%S'\n", grpFName); } else { ajFmtPrintS(&grpFName, "%Sshare/%S/acd/groups.standard", grpRootInst, grpPack); acdLog("Group file installed: '%S'\n", grpFName); grpFile = ajFileNewInNameS(grpFName); if(!grpFile) { acdLog("Grp file '%S' not opened\n", grpFName); ajStrAssignS(&grpRoot, ajNamValueRootdir()); ajDirnameFix(&grpRoot); ajFmtPrintS(&grpFName, "%Sacd/groups.standard", grpRoot); acdLog("Grp file from source dir: '%S'\n", grpFName); grpFile = ajFileNewInNameS(grpFName); } } if(!grpFile) /* test acdc-grpmissing */ ajDie("Group file %S not found", grpFName); else acdLog("Group file %F used\n", grpFile); grpxp = ajRegCompC("^EDAM_[a-z]+:\\d+\\s+([^ ]+) +([^ ].*)"); while(grpFile && ajReadlineTrim(grpFile, &grpLine)) { if(ajStrCutComments(&grpLine)) { ajStrRemoveWhiteExcess(&grpLine); if(ajRegExec(grpxp, grpLine)) { ajRegSubI(grpxp, 1, &grpName); ajRegSubI(grpxp, 2, &grpDesc); ajStrExchangeKK(&grpName, '_', ' '); if(ajTablePut(ret, grpName, grpDesc)) ajWarn("Duplicate group name '%S' in file %S", grpName, grpFName); grpName = NULL; grpDesc = NULL; } else ajErr("Bad record in file %S:\n%S", grpFName, grpLine); } } ajFileClose(&grpFile); ajStrDel(&grpFName); ajStrDel(&grpRoot); ajStrDel(&grpRootInst); ajStrDel(&grpPack); ajStrDel(&grpLine); ajStrDel(&grpName); ajStrDel(&grpDesc); ajRegFree(&grpxp); return ret; } ID acdReadKeywords TY static MO ajacd LB acd XX DE Read standard table of application keywords XX RT AjPTable RD String table of keyword names and descriptions RX // static AjPTable acdReadKeywords(void) { AjPTable ret = ajTablestrNewCase(50); AjPFile keyFile = NULL; AjPStr keyFName = NULL; AjPStr keyRoot = NULL; AjPStr keyRootInst = NULL; AjPStr keyPack = NULL; AjPStr keyLine = NULL; AjPRegexp keyxp = NULL; AjPStr keyName = NULL; AjPStr keyDesc = NULL; if(!acdGrpTable) acdGrpTable = acdReadGroups(); ajStrAssignS(&keyPack, ajNamValuePackage()); ajStrAssignS(&keyRootInst, ajNamValueInstalldir()); ajDirnameFix(&keyRootInst); if(ajNamGetValueC("acdroot", &keyRoot)) { ajDirnameFix(&keyRoot); ajFmtPrintS(&keyFName, "%Skeywords.standard", keyRoot); keyFile = ajFileNewInNameS(keyFName); acdLog("Keyword file in acdroot: '%S'\n", keyFName); } else { ajFmtPrintS(&keyFName, "%Sshare/%S/acd/keywords.standard", keyRootInst, keyPack); acdLog("Keyword file installed: '%S'\n", keyFName); keyFile = ajFileNewInNameS(keyFName); if(!keyFile) { acdLog("keyword file '%S' not opened\n", keyFName); ajStrAssignS(&keyRoot, ajNamValueRootdir()); ajDirnameFix(&keyRoot); ajFmtPrintS(&keyFName, "%Sacd/keywords.standard", keyRoot); acdLog("Keywords file from source dir: '%S'\n", keyFName); keyFile = ajFileNewInNameS(keyFName); } } if(!keyFile) /* test acdc-keymissing */ ajDie("Keyword file %S not found", keyFName); else acdLog("Keyword file %F used\n", keyFile); keyxp = ajRegCompC("([^ ]+) +([^ ].*)"); while(keyFile && ajReadlineTrim(keyFile, &keyLine)) { if(ajStrCutComments(&keyLine)) { ajStrRemoveWhiteExcess(&keyLine); if(ajRegExec(keyxp, keyLine)) { ajRegSubI(keyxp, 1, &keyName); ajRegSubI(keyxp, 2, &keyDesc); ajStrExchangeKK(&keyName, '_', ' '); if(ajTableFetchS(acdGrpTable, keyName)) ajWarn("Keyword %S in file %S is a known group", keyName, keyFName); if(ajTablePut(ret, keyName, keyDesc)) ajWarn("Duplicate keyword in file %S", keyFName); keyName = NULL; keyDesc = NULL; } else ajErr("Bad record in file %S:\n%S", keyFName, keyLine); } } ajFileClose(&keyFile); ajStrDel(&keyFName); ajStrDel(&keyRoot); ajStrDel(&keyRootInst); ajStrDel(&keyPack); ajStrDel(&keyLine); ajStrDel(&keyName); ajStrDel(&keyDesc); ajRegFree(&keyxp); return ret; } ID acdReadSections TY static MO ajacd LB acd XX DE Read standard file of ACD sections and store in AjPTable objects XX PN [1] PA wN typetable AjPTable* PD String table of section names and types PX PN [2] PA wN infotable AjPTable* PD String table of section names and PD descriptions PX RT void RD RX // static void acdReadSections(AjPTable* typetable, AjPTable* infotable) { AjPFile sectFile = NULL; AjPStr sectFName = NULL; AjPStr sectRoot = NULL; AjPStr sectRootInst = NULL; AjPStr sectPack = NULL; AjPStr sectLine = NULL; AjPRegexp sectxp = NULL; AjPStr sectName = NULL; AjPStr sectType = NULL; AjPStr sectDesc = NULL; ajStrAssignS(§Pack, ajNamValuePackage()); ajStrAssignS(§RootInst, ajNamValueInstalldir()); ajDirnameFix(§RootInst); *typetable = ajTablestrNewCase(50); *infotable = ajTablestrNewCase(50); if(ajNamGetValueC("acdroot", §Root)) { ajDirnameFix(§Root); ajFmtPrintS(§FName, "%Ssections.standard", sectRoot); sectFile = ajFileNewInNameS(sectFName); acdLog("Section file in acdroot: '%S'\n", sectFName); } else { ajFmtPrintS(§FName, "%Sshare/%S/acd/sections.standard", sectRootInst, sectPack); acdLog("Section file installed: '%S'\n", sectFName); sectFile = ajFileNewInNameS(sectFName); if(!sectFile) { acdLog("Sect file '%S' not opened\n", sectFName); ajStrAssignS(§Root, ajNamValueRootdir()); ajDirnameFix(§Root); ajFmtPrintS(§FName, "%Sacd/sections.standard", sectRoot); acdLog("Sect file from source dir: '%S'\n", sectFName); sectFile = ajFileNewInNameS(sectFName); } } if(!sectFile) /* test acdc-sectmissing */ ajDie("Section file %S not found", sectFName); else acdLog("Section file %F used\n", sectFile); sectxp = ajRegCompC("([^ ]+) +([^ ]+) +([^ ].*)"); while(sectFile && ajReadlineTrim(sectFile, §Line)) { if(ajStrCutComments(§Line)) { ajStrRemoveWhiteExcess(§Line); if(ajRegExec(sectxp, sectLine)) { ajRegSubI(sectxp, 1, §Name); ajRegSubI(sectxp, 2, §Type); ajRegSubI(sectxp, 3, §Desc); ajStrExchangeKK(§Name, '_', ' '); if(ajTablePut(*typetable, sectName, sectType)) ajWarn("Duplicate section name in file %S", sectFName); if(ajTablePut(*infotable, sectName, sectDesc)) ajWarn("Duplicate section name in file %S", sectFName); sectName = NULL; sectType = NULL; sectDesc = NULL; } else ajErr("Bad record in file %S:\n%S", sectFName, sectLine); } } ajFileClose(§File); ajStrDel(§FName); ajStrDel(§Root); ajStrDel(§RootInst); ajStrDel(§Pack); ajStrDel(§Line); ajStrDel(§Name); ajStrDel(§Type); ajStrDel(§Desc); ajRegFree(§xp); return; } ID acdValidSectionMatch TY static MO ajacd LB acd XX DE Tests whether a named section appears in the current section list XX PN [1] PA r secname const char* PD Section name PX RT AjBool RD ajTrue if the named section was found RX // static AjBool acdValidSectionMatch(const char* secname) { AjIList iter = NULL; AjPStr listsecname; AjBool ret = ajFalse; if(!ajListGetLength(acdSecList)) return ajFalse; iter = ajListIterNewread(acdSecList); while (!ajListIterDone(iter)) { listsecname = ajListIterGet(iter); if(ajStrMatchC(listsecname, secname)) { ret = ajTrue; break; } } ajListIterDel(&iter); return ret; } ID acdValidSectionFull TY static MO ajacd LB acd XX DE Returns the full section name with the top level and any frame DE sub-sections XX PN [1] PA w secname AjPStr* PD Section name PX RT void RD RX // static void acdValidSectionFull(AjPStr* secname) { AjIList iter = NULL; AjPStr listsecname; ajStrAssignClear(secname); if(!ajListGetLength(acdSecList)) return; iter = ajListIterNewread(acdSecList); while (!ajListIterDone(iter)) { listsecname = ajListIterGet(iter); if (ajStrGetLen(*secname)) ajStrAppendK(secname,':'); ajStrAppendS(secname, listsecname); } ajListIterDel(&iter); return; } ID acdOutFormatCpdb TY static MO ajacd LB acd XX DE Tests the output format for an outcpdb ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatCpdb(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "cpdb", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatData TY static MO ajacd LB acd XX DE Tests the output format for an out ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatData(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "text", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatDiscrete TY static MO ajacd LB acd XX DE Tests the output format for an out ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatDiscrete(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "phylip", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatDistance TY static MO ajacd LB acd XX DE Tests the output format for an outdistance ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatDistance(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "phylip", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatFreq TY static MO ajacd LB acd XX DE Tests the output format for an outfreq ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatFreq(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "phylip", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatMatrix TY static MO ajacd LB acd XX DE Tests the output format for an outmatrix ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatMatrix(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "emboss", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatMatrixf TY static MO ajacd LB acd XX DE Tests the output format for an outmatrixf ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatMatrixf(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "emboss", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatProperties TY static MO ajacd LB acd XX DE Tests the output format for an outproperties ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatProperties(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "phylip", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatScop TY static MO ajacd LB acd XX DE Tests the output format for an outscop ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatScop(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "scop", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdOutFormatTree TY static MO ajacd LB acd XX DE Tests the output format for an outtree ACD type XX PN [1] PA r name const AjPStr PD Format name PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // static AjBool acdOutFormatTree(const AjPStr name, ajint* iformat) { ajint i; const char* format[] = { "phylip", "newick", NULL }; for (i=0; format[i]; i++) if(ajStrMatchCaseC(name, format[i])) { *iformat = i; return ajTrue; } return ajFalse; } ID acdKnownValueList TY static MO ajacd LB acd XX DE Finds a list value associated with a known type XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA w value AjPStr* PD Standard value PX RT AjBool RD ajTrue if a value was set RX // static AjBool acdKnownValueList(const AcdPAcd thys, AjPStr* value) { const AjPStr type = NULL; AjPStr resource = NULL; AjPStr list = NULL; ajint i; type = acdAttrValue(thys, "knowntype"); if(!type) return ajFalse; for(i=0; acdResource[i]; i++) if(ajStrMatchCaseC(type, acdResource[i])) { resource = ajStrNewS(type); ajStrExchangeKK(&resource, ' ', '_'); if(ajNamRsListValue(resource, &list)) { if(acdResourceList(thys, list, value)) return ajTrue; } } return ajFalse; } ID acdKnownValueSelect TY static MO ajacd LB acd XX DE Finds a selection value associated with a known type XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA w value AjPStr* PD Standard value PX RT AjBool RD ajTrue if a value was set RX // static AjBool acdKnownValueSelect(const AcdPAcd thys, AjPStr* value) { const AjPStr type = NULL; AjPStr resource = NULL; AjPStr list = NULL; ajint i; type = acdAttrValue(thys, "knowntype"); if(!type) return ajFalse; for(i=0; acdResource[i]; i++) if(ajStrMatchCaseC(type, acdResource[i])) { resource = ajStrNewS(type); ajStrExchangeKK(&resource, ' ', '_'); if(ajNamRsListValue(resource, &list)) { if(acdResourceList(thys, list, value)) return ajTrue; } } return ajFalse; } ID acdResourceList TY static MO ajacd LB acd XX DE Finds a list value associated with a known type XX PN [1] PA r thys const AcdPAcd PD ACD object PX PN [2] PA r list const AjPStr PD Resource value PX PN [3] PA w value AjPStr* PD Standard list value PX RT AjBool RD ajTrue if a value was set RX // static AjBool acdResourceList(const AcdPAcd thys, const AjPStr list, AjPStr* value) { AjPStr delim = NULL; AjPStr codedelim = NULL; AjPFile infile = NULL; AjPStr line = NULL; AjPStr tok1 = NULL; AjPStr tok2 = NULL; AjPStrTok handle = NULL; AjPStr liststr = NULL; if (!ajStrGetLen(list)) return ajFalse; liststr = ajStrNewS(list); acdAttrValueStr(thys, "delimiter", ";", &delim); acdAttrValueStr(thys, "codedelimiter", ":", &codedelim); if(ajStrGetCharFirst(list) == '@') { ajStrAssignClear(value); ajStrCutStart(&liststr, 1); infile = ajDatafileNewInNameS(liststr); if(!infile) return ajFalse; while(ajReadlineTrim(infile, &line)) { ajStrTrimWhite(&line); if(ajStrGetCharFirst(line) == '#') continue; ajStrTokenAssignC(&handle, line, " "); ajStrTokenNextParse(&handle, &tok1); ajStrTokenRestParse(&handle, &tok2); if(ajStrGetLen(*value)) ajStrAppendS(value, delim); ajStrAppendS(value, tok1); ajStrAppendS(value, codedelim); ajStrAppendS(value, tok2); } ajFileClose(&infile); return ajTrue; } /* value will use : and ; as delimiters */ ajStrAssignS(value, liststr); ajStrExchangeKK(value, ';', '\1'); ajStrExchangeKK(value, ':', '\2'); ajStrExchangeKK(value, '\1', ajStrGetCharFirst(delim)); ajStrExchangeKK(value, '\2', ajStrGetCharFirst(codedelim)); return ajTrue; } ID acdDelAlign TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD alignment data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelAlign(void** PPval) { if(!*PPval) return; ajAlignDel((AjPAlign*)PPval); return; } ID acdDelAssembly TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD assembly input data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelAssembly(void** PPval) { if(!*PPval) return; ajAssemDel((AjPAssem*)PPval); return; } ID acdDelCod TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD codon usage data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelCod(void** PPval) { if(!*PPval) return; ajCodDel((AjPCod*)PPval); return; } ID acdDelDir TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD directory data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelDir(void** PPval) { if(!*PPval) return; ajDirDel((AjPDir*)PPval); return; } ID acdDelDirout TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD directory data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelDirout(void** PPval) { if(!*PPval) return; ajDiroutDel((AjPDirout*)PPval); return; } ID acdDelFeattable TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD feature table data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelFeattable(void** PPval) { if(!*PPval) return; ajFeattaballDel((AjPFeattaball*)PPval); return; } ID acdDelFeattabOut TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD output feature table data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelFeattabOut(void** PPval) { if(!*PPval) return; ajFeattabOutDel((AjPFeattabOut*)PPval); return; } ID acdDelFile TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD input file data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelFile(void** PPval) { if(!*PPval) return; ajFileClose((AjPFile*)PPval); return; } ID acdDelFloat TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD floating point array data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelFloat(void** PPval) { if(!*PPval) return; ajFloatDel((AjPFloat*)PPval); return; } ID acdDelList TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD list/selection data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelList(void** PPval) { if(!*PPval) return; ajListstrFreeData((AjPList*)PPval); return; } ID acdDelMatrix TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD integer comparison matrix data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelMatrix(void** PPval) { if(!*PPval) return; ajMatrixDel((AjPMatrix*)PPval); return; } ID acdDelMatrixf TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD floating point comparison DE matrix data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelMatrixf(void** PPval) { if(!*PPval) return; ajMatrixfDel((AjPMatrixf*)PPval); return; } ID acdDelObo TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD obo term input data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelObo(void** PPval) { if(!*PPval) return; ajOboallDel((AjPOboall*)PPval); return; } ID acdDelOutfile TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD output file data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelOutfile(void** PPval) { if(!*PPval) return; ajOutfileClose((AjPOutfile*)PPval); return; } ID acdDelPatlist TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD pattern list data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelPatlist(void** PPval) { if(!*PPval) return; ajPatlistSeqDel((AjPPatlistSeq*)PPval); return; } ID acdDelPhyloDist TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD phylogenetic distance data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelPhyloDist(void** PPval) { if(!*PPval) return; ajPhyloDistDel((AjPPhyloDist*)PPval); return; } ID acdDelPhyloFreq TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD phylogenetic frequency data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelPhyloFreq(void** PPval) { ajUser("acdDelPhyloFreq '%x'", *PPval); if(!*PPval) return; ajPhyloFreqDel((AjPPhyloFreq*)PPval); return; } ID acdDelPhyloProp TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD phylogenetic properties data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelPhyloProp(void** PPval) { if(!*PPval) return; ajPhyloPropDel((AjPPhyloProp*)PPval); return; } ID acdDelPhyloState TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD phylogenetic state data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelPhyloState(void** PPval) { if(!*PPval) return; ajPhyloStateDel((AjPPhyloState*)PPval); return; } ID acdDelPhyloTree TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD phylogenetic tree data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelPhyloTree(void** PPval) { if(!*PPval) return; ajPhyloTreeDelarray((AjPPhyloTree**)PPval); return; } ID acdDelRange TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD range data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelRange(void** PPval) { if(!*PPval) return; ajRangeDel((AjPRange*)PPval); return; } ID acdDelRefseq TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD reference sequence input data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelRefseq(void** PPval) { if(!*PPval) return; ajRefseqDel((AjPRefseq*)PPval); return; } ID acdDelReg TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD regular expression data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelReg(void** PPval) { if(!*PPval) return; ajPatlistRegexDel((AjPPatlistRegex*)PPval); return; } ID acdDelReport TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD report data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelReport(void** PPval) { if(!*PPval) return; ajReportDel((AjPReport*)PPval); return; } ID acdDelResource TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD data resource input data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelResource(void** PPval) { if(!*PPval) return; ajResourceallDel((AjPResourceall*)PPval); return; } ID acdDelSeq TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD sequence data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelSeq(void** PPval) { if(!*PPval) return; ajSeqDel((AjPSeq*)PPval); return; } ID acdDelSeqall TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD sequence stream data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelSeqall(void** PPval) { if(!*PPval) return; ajSeqallDel((AjPSeqall*)PPval); return; } ID acdDelSeqout TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD sequence output data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelSeqout(void** PPval) { if(!*PPval) return; ajSeqoutDel((AjPSeqout*)PPval); return; } ID acdDelSeqset TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD sequence set data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelSeqset(void** PPval) { if(!*PPval) return; ajSeqsetDel((AjPSeqset*)PPval); return; } ID acdDelSeqsetArray TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD sequence sets data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelSeqsetArray(void** PPval) { if(!*PPval) return; ajSeqsetDelarray((AjPSeqset**)PPval); return; } ID acdDelStr TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD string data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelStr(void** PPval) { if(!*PPval) return; ajStrDel((AjPStr*)PPval); return; } ID acdDelStrArray TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD string array data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelStrArray(void** PPval) { if(!*PPval) return; ajStrDelarray((AjPStr**)PPval); return; } ID acdDelTaxon TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD taxonomy input data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelTaxon(void** PPval) { if(!*PPval) return; ajTaxallDel((AjPTaxall*)PPval); return; } ID acdDelText TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD text input data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelText(void** PPval) { if(!*PPval) return; ajTextallDel((AjPTextall*)PPval); return; } ID acdDelUrl TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD URL input data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelUrl(void** PPval) { if(!*PPval) return; ajUrlallDel((AjPUrlall*)PPval); return; } ID acdDelVariation TY static MO ajacd LB acd XX DE Function with void** prototype to delete ACD variation input data XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdDelVariation(void** PPval) { if(!*PPval) return; ajVarloadDel((AjPVarload*)PPval); return; } ID acdFree TY static MO ajacd LB acd XX DE Function to delete ACD data using the standard free function XX PN [1] PA d PPval void** PD Value to be deleted PX RT void RD RX // static void acdFree(void** PPval) { if(!*PPval) return; AJFREE(*PPval); return; } ID ajAcdUnused TY public MO ajacd LB acd XX DE Dummy function to catch all unused functions defined in the ajacd DE source file. XX RT void RD RX // void ajAcdUnused(void) { AjPStr ajpstr=NULL; AcdPAcd acdpacd=NULL; float f=0.0; char c; acdSetXxxx(acdpacd); /* template function for acdSet */ acdAttrToChar(acdpacd, "attr", '.', &c); acdQualToFloat(acdpacd, "", 0.0, 0, &f, &ajpstr); acdCountType("outfile"); acdPrintUsed(); return; } ID acdRangeTestCalc TY static MO ajacd LB acd XX DE Tests for calculated minimum and maximum attributes. If found, requires DE other attributes to be defined to control the bahviour if the range DE is impossible in the current case XX PN [1] PA r thys const AcdPAcd PD Acd object PX RT AjBool RD True if a calculated value was found RX // static AjBool acdRangeTestCalc(const AcdPAcd thys) { const AjPStr tmpstr; AjBool toggle = ajFalse; AjBool iscalcmin = ajFalse; AjBool iscalcmax = ajFalse; AjBool iscalc = ajFalse; AjBool failrange = ajFalse; AjBool truemin = ajFalse; tmpstr = acdAttrValue(thys, "minimum"); if(!MAJSTRGETLEN(tmpstr)) return ajFalse; if(acdVarTestValid(tmpstr, &toggle)) iscalcmin = ajTrue; tmpstr = acdAttrValue(thys, "maximum"); if(!MAJSTRGETLEN(tmpstr)) return ajFalse; if(acdVarTestValid(tmpstr, &toggle)) iscalcmax = ajTrue; if(iscalcmin || iscalcmax) { iscalc = ajTrue; if(!acdAttrToBool(thys, "failrange", ajFalse, &failrange)) { acdErrorAcd(thys, "Attribute %s: required with any calculated min/max", "failrange", acdType[thys->Type].Name); } else { if(failrange) { tmpstr = acdAttrValue(thys, "rangemessage"); if(!tmpstr) acdErrorAcd(thys, "Attribute %s: required for failrange: \"Y\"", "rangemessage", acdType[thys->Type].Name); } else { if(!acdAttrToBool(thys, "trueminimum",ajFalse, &truemin)) acdErrorAcd(thys, "Attribute %s: required for failrange: \"N\"", "trueminimum", acdType[thys->Type].Name); } } } return iscalc; } ID acdRegVarDefine TY static MO ajacd LB acd XX DE Define regular expressions for parsing variables and functions XX RT void RD RX // static void acdRegVarDefine(void) { if(!acdRegVarname) acdRegVarname = ajRegCompC("^(.*)\\$\\(([a-zA-Z0-9_.]+)\\)"); if(!acdRegToggle) acdRegToggle = ajRegCompC("^(@\\([!])?(\\$\\([a-zA-Z0-9_.]+\\))\\)?$"); if(!acdRegFunction) acdRegFunction = ajRegCompC("^(.*)\\@\\(([^()]+)\\)"); return; } ID acdEdamTest TY static MO ajacd LB acd XX DE Test an EDAM term from a relations attribute XX PN [1] PA r relation const AjPStr PD Relation single attribute value PX RT const AjPStr RD Namespace RX // static const AjPStr acdEdamTest(const AjPStr relation) { AjPStr term = NULL; AjPStr name = NULL; AjPStr id = NULL; AjPStrTok handle = NULL; AjPStr token = NULL; AjPStr namespace = NULL; AjPObo oboterm = NULL; AjPObo obonameterm = NULL; AjPStr namequery = NULL; AjBool obonamefound = ajFalse; if(!acdEdam) return NULL; if(!ajStrPrefixC(relation, "EDAM")) { ajFmtPrintS(&namequery, "data:%S", relation); obonameterm = ajObodataFetchName(acdEdam, namequery); if(obonameterm) { obonamefound = ajTrue; acdErrorValid("Relation '%S' matches EDAM term EDAM_data:%S %S", relation, oboterm->Namespace, oboterm->Id); } ajFmtPrintS(&namequery, "topic:%S", relation); obonameterm = ajObodataFetchName(acdEdam, namequery); if(obonameterm) { obonamefound = ajTrue; acdErrorValid("Relation '%S' matches EDAM term EDAM_topic:%S %S", relation, oboterm->Id, oboterm->Namespace); } ajFmtPrintS(&namequery, "operation:%S", relation); obonameterm = ajObodataFetchName(acdEdam, namequery); if(obonameterm) { obonamefound = ajTrue; acdErrorValid("Relation '%S' matches EDAM term EDAM_operation:%S %S", relation, oboterm->Id, oboterm->Namespace); } if(!obonamefound) acdErrorValid("Not an EDAM term in relation '%S'", relation); return NULL; } ajStrExtractFirst(relation, &name, &term); handle = ajStrTokenNewC(term, ":"); if(!ajStrTokenNextParse(&handle, &namespace)) /* EDAM */ acdErrorValid("Bad relation term '%S'", term); else if(!ajStrTokenNextParse(&handle, &token)) /* ID */ acdErrorValid("Bad relation term '%S'", term); if(ajStrPrefixC(namespace, "EDAM_")) ajStrCutStart(&namespace, 5); if(!ajStrGetLen(namespace)) acdErrorValid("Bad relation no namespace"); ajFmtPrintS(&id, "EDAM_%S:%S", namespace, token); oboterm = ajObodataFetchId(acdEdam, id); if(!oboterm) { acdErrorValid("Unknown relation term '%S' fetch failed for '%S'", term, id); return NULL; } if(ajOboIsObsolete(oboterm)) { if(ajOboGetReplaced(oboterm)) { obonameterm = ajObodataFetchId(acdEdam, ajOboGetReplaced(oboterm)); if(obonameterm) acdErrorValid("Relation term '%S' obsolete, " "possible replacement %S %S %S", term, ajOboGetReplaced(oboterm), obonameterm->Namespace, obonameterm->Name); else acdErrorValid("Relation term '%S' obsolete, " "possible replacement '%S'", term, ajOboGetReplaced(oboterm)); } else { acdErrorValid("Relation term '%S' obsolete", term); } } if(!ajStrMatchS(id, oboterm->Id)) acdErrorValid("Relation term '%S' bad id, expected '%S' (%S)", term, oboterm->Id, id); if(!ajStrMatchS(name, oboterm->Name)) { obonamefound = ajFalse; ajFmtPrintS(&namequery, "%S:%S", namespace, name); obonameterm = ajObodataFetchName(acdEdam, namequery); if(obonameterm) { obonamefound = ajTrue; if(ajStrMatchS(id, obonameterm->Id)) acdErrorValid("Relation term '%S' bad name, expected '%S' " "but matches synonym", term, oboterm->Name); else acdErrorValid("Relation term '%S' bad name, expected '%S' " "but matches name for %S %S %S", term, oboterm->Name, obonameterm->Id, obonameterm->Namespace, obonameterm->Name); } if(!ajStrMatchC(namespace, "topic")){ ajFmtPrintS(&namequery, "topic:%S", name); obonameterm = ajObodataFetchName(acdEdam, namequery); if(obonameterm) { obonamefound = ajTrue; acdErrorValid("Relation term '%S' bad name, expected '%S' " "but matches name for %S %S %S", term, oboterm->Name, obonameterm->Id, obonameterm->Namespace, obonameterm->Name); } } if(!ajStrMatchC(namespace, "operation")){ ajFmtPrintS(&namequery, "operation:%S", name); obonameterm = ajObodataFetchName(acdEdam, namequery); if(obonameterm) { obonamefound = ajTrue; acdErrorValid("Relation term '%S' bad name, expected '%S' " "but matches name for %S %S %S", term, oboterm->Name, obonameterm->Id, obonameterm->Namespace, obonameterm->Name); } } if(!obonamefound) acdErrorValid("Relation term '%S' bad name, expected '%S'", term, oboterm->Name); } if(!ajStrMatchS(namespace, oboterm->Namespace)) acdErrorValid("Relation term '%S' bad namespace, expected '%S'", term, oboterm->Namespace); return oboterm->Namespace; } ID ajAcdedamParse TY public MO ajacd LB acd XX DE Parse an EDAM term from a relations attribute XX PN [1] PA r relation const AjPStr PD Relation single attribute value PX PN [2] PA w id AjPStr* PD EDAM term numeric id PX PN [3] PA w namespace AjPStr* PD EDAM term namespace PX PN [4] PA w name AjPStr* PD EDAM term name PX RT AjBool RD True on success RX // AjBool ajAcdedamParse(const AjPStr relation, AjPStr* id, AjPStr* namespace, AjPStr* name) { AjPStr token = NULL; AjPStr term = NULL; AjPStr rest = NULL; AjPStrTok handle = NULL; if(!ajStrPrefixC(relation, "EDAM_")) return ajFalse; ajStrExtractFirst(relation, &rest, &term); handle = ajStrTokenNewC(term, ":_"); if(!ajStrTokenNextParse(&handle, &token)) /* EDAM */ return ajFalse; else if(!ajStrTokenNextParse(&handle, namespace)) /* namespace */ return ajFalse; else if(!ajStrTokenNextParse(&handle, id)) /* ID */ { ajStrSetClear(namespace); return ajFalse; } ajStrAssignS(name, rest); ajStrDel(&token); ajStrDel(&term); ajStrDel(&rest); ajStrTokenDel(&handle); return ajTrue; } ID ajAcdtypeGetGroup TY public MO ajacd LB acd XX DE Return the ACD group for an ACD datatype XX PN [1] PA r type const AjPStr PD ACD type name PX RT const char* RD Group name RX // const char* ajAcdtypeGetGroup(const AjPStr type) { ajuint i; i = 0; while(acdType[i].Name) /* ACD types as qualifiers */ { if(ajStrMatchC(type, acdType[i].Name)) return acdType[i].Group; i++; } return NULL; } ID acdTestDebugIsSet TY static MO ajacd LB acd XX DE Tests whether the command line switch for debug messages has been set DE by testing internal variable 'acdDebugSet' XX RT AjBool RD Debugging status. RX // static AjBool acdTestDebugIsSet(void) { ajDebug("acdTestDebugIsSet returning %B\n", acdDebugSet); return acdDebugSet; } ID acdTestDebug TY static MO ajacd LB acd XX DE Tests whether debug messages are required by checking DE internal variable 'acdDebug' XX RT AjBool RD Debugging status. RX // static AjBool acdTestDebug(void) { ajDebug("acdDebug returning %B\n", acdDebug); return acdDebug; } ID acdTestFilter TY static MO ajacd LB acd XX DE Tests whether input and output use stdin and stdout as a filter DE by returning internal variable 'acdFilter' XX RT AjBool RD Filter status. RX // static AjBool acdTestFilter(void) { return acdFilter; } ID acdTestStdout TY static MO ajacd LB acd XX DE Tests whether output uses stdout for output by default DE by returning internal variable 'acdStdout' XX RT AjBool RD Stdout status. RX // static AjBool acdTestStdout(void) { return acdStdout; } ID alignFormat TY list MO ajalign LB core XX DE Functions to write alignments XX // static AlignOFormat alignFormat[] = { /* name description function */ /* Alias nucleic protein header min max zero */ /* standard sequence formats */ {"unknown", "Unknown format", AJFALSE, AJFALSE, AJFALSE, AJTRUE, AJTRUE, 0, 0, 0, &alignWriteSimple}, {"fasta", "Fasta format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteFasta}, {"a2m", "A2M (fasta) format sequence", /* same as fasta */ AJTRUE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteFasta}, {"msf", "MSF format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteMsf}, {"clustal", "clustalw format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteClustal}, {"mega", "Mega format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteMega}, {"meganon", "Mega non-interleaved format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteMeganon}, {"nexus", "nexus/paup format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteNexus}, {"paup", "nexus/paup format sequence (alias)", AJTRUE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteNexus}, {"nexusnon", "nexus/paup non-interleaved format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteNexusnon}, {"paupnon", "nexus/paup non-interleaved format sequence (alias)", AJTRUE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteNexusnon}, {"phylip", "phylip format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWritePhylip}, {"phylipnon", "phylip non-interleaved format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWritePhylipnon}, {"selex", "SELEX format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteSelex}, {"treecon", "Treecon format sequence", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteTreecon}, /* trace for debug */ {"debug", "Debugging trace of full internal data content", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 0, 0, &alignWriteTrace}, /* alignment formats */ {"markx0", "Pearson MARKX0 format", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 2, 2, &alignWriteMarkX0}, {"markx1", "Pearson MARKX1 format", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 2, 2, &alignWriteMarkX1}, {"markx2", "Pearson MARKX2 format", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 2, 2, &alignWriteMarkX2}, {"markx3", "Pearson MARKX3 format", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 2, 2, &alignWriteMarkX3}, {"markx10", "Pearson MARKX10 format", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 2, 2, &alignWriteMarkX10}, {"match","Start and end of matches between sequence pairs", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJFALSE, 0, 2, 2, &alignWriteMatch}, {"multiple", "Simple multiple alignment", AJTRUE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 0, 0, &alignWriteSimple}, {"pair", "Simple pairwise alignment", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 2, 2, &alignWriteSimple}, {"simple", "Simple multiple alignment", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 0, 0, &alignWriteSimple}, {"sam", "Sequence alignent/map (SAM) format", AJFALSE, AJTRUE, AJFALSE, AJFALSE, AJTRUE, 0, 2, 2, &alignWriteSam}, /* {"bam", "Binary sequence alignent/map (BAM) format", AJFALSE, AJTRUE, AJFALSE, AJFALSE, AJTRUE, 0, 2, 2, &alignWriteBam}, */ {"score", "Score values for pairs of sequences", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJFALSE, 0, 2, 2, &alignWriteScore}, {"srs", "Simple multiple sequence format for SRS", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 0, 0, &alignWriteSrs}, {"srspair", "Simple pairwise sequence format for SRS", AJFALSE, AJTRUE, AJTRUE, AJTRUE, AJTRUE, 0, 2, 2, &alignWriteSrsPair}, {"tcoffee", "TCOFFEE program format", AJFALSE, AJTRUE, AJTRUE, AJFALSE, AJTRUE, 0, 0, 0, &alignWriteTCoffee}, {NULL, NULL, AJFALSE, AJFALSE, AJFALSE, AJFALSE, AJTRUE, 0, 0, 0, NULL} }; ID alignWriteTrace TY static MO ajalign LB core XX DE Writes an alignment in Trace format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteTrace(AjPAlign thys) { const AjPSeq seq = NULL; ajint nali; ajint iali; ajint iseq; ajint nseq; ajint identity = 0; ajint similarity = 0; ajint gaps = 0; ajint seqlen = 0; AlignPData* pdata = NULL; AlignPData data = NULL; AjPStr tmpstr = NULL; AjPFile outf = NULL; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); ajFmtPrintF(thys->File, "Trace output\n"); ajFmtPrintF(thys->File, "============\n"); ajFmtPrintF(thys->File, "a: Type:'%S' Formatstr:'%S' Format:%d\n", thys->Type, thys->Formatstr, thys->Format); ajFmtPrintF(thys->File, "b: File:%F\n", thys->File); ajFmtPrintF(thys->File, "Show: ShowAcc:%B ShowDes:%B ShowUsa:%B\n", thys->Showacc, thys->Showdes, thys->Showusa); ajFmtPrintF(thys->File, "Booleans: Multi:%B Global:%B SeqOnly:%B SeqExternal:%B\n", thys->Multi, thys->Global, thys->SeqOnly, thys->SeqExternal); ajFmtPrintF(thys->File, "Numbers: NMin:%d NMax:%d Nseqs:%d Count:%d Width:%d\n", thys->Nmin, thys->Nmax, thys->Nseqs, thys->Count, thys->Width); ajFmtPrintF(thys->File, "Matrices: IMatrix:'%S'(%d) FMatrix:'%S'(%d)\n", ajMatrixGetName(thys->IMatrix), ajMatrixGetSize(thys->IMatrix), ajMatrixfGetName(thys->FMatrix), ajMatrixfGetSize(thys->FMatrix)); ajFmtPrintF(thys->File, "Strings: Matrix:'%S' GapPen:'%S' ExtPen:'%S'\n", thys->Matrix, thys->GapPen, thys->ExtPen); ajFmtPrintF(thys->File, "Header: '%S'\n", thys->Header); ajFmtPrintF(thys->File, "SubHeader: '%S'\n", thys->SubHeader); ajFmtPrintF(thys->File, "Tail: '%S'\n", thys->Tail); ajFmtPrintF(thys->File, "SubTail: '%S'\n", thys->Tail); ajFmtPrintF(thys->File, "Key: seqlen/len offset> start..end File, "\nalign%d: Nseqs:%d LenAli:%d " "NumId:%d NumSim:%d NumGap:%d Score:'%S'\n", iali, data->Nseqs, data->LenAli, data->NumId, data->NumSim, data->NumGap, data->Score); alignConsStats(thys, iali, &tmpstr, &identity, &similarity, &gaps, &seqlen); ajAlignSetStats(thys, iali, seqlen, identity, similarity, gaps, NULL); ajFmtPrintF(thys->File, "fixed%d: Nseqs:%d LenAli:%d " "NumId:%d NumSim:%d NumGap:%d Score:'%S'\n", iali, data->Nseqs, data->LenAli, data->NumId, data->NumSim, data->NumGap, data->Score); ajAlignSetSubStandard(thys, iali); outf = thys->File; /* turn off printing of the header, keep the calculation */ thys->File = NULL; alignWriteHeaderNum(thys,iali); thys->File = outf; nseq = thys->Nseqs; for(iseq=0; iseq < nseq; iseq++) { seq = alignSeq(thys, iseq, iali); ajFmtPrintF(thys->File, "Num%d.%d: %d/%d %d> %d..%d <%d (%d) Rev:%B %d..%d " "%d..%d\n", iali, iseq, (ajSeqGetLen(seq) - ajSeqCountGaps(seq)), data->Len[iseq], data->Offset[iseq], data->Start[iseq], data->End[iseq], data->Offend[iseq], data->SubOffset[iseq], data->Rev[iseq], alignSeqBegin(data, iseq), alignSeqEnd(data, iseq), alignSeqGapBegin(data, iseq), alignSeqGapEnd(data, iseq)); if(ajSeqGetLen(seq) <= 40) ajFmtPrintF(thys->File, "Seq%d.%d: %d '%S'\n", iali, iseq, ajSeqGetLen(seq), ajSeqGetSeqS(seq)); else { ajStrAssignSubS(&tmpstr, ajSeqGetSeqS(seq), -20, -1); ajFmtPrintF(thys->File, "Seq%d.%d: %d '%20.20S...%20S'\n", iali, iseq, ajSeqGetLen(seq), ajSeqGetSeqS(seq), tmpstr); } } } ajStrDel(&tmpstr); AJFREE(pdata); return; } ID alignWriteClustal TY static MO ajalign LB core XX DE Writes an alignment in ClustalW format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteClustal(AjPAlign thys) { alignWriteSeqformat(thys, 0, "clustal"); return; } ID alignWriteMega TY static MO ajalign LB core XX DE Writes an alignment in Mega format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMega(AjPAlign thys) { alignWriteSeqformat(thys, 0, "mega"); return; } ID alignWriteMeganon TY static MO ajalign LB core XX DE Writes an alignment in Mega non-interleaved format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMeganon(AjPAlign thys) { alignWriteSeqformat(thys, 0, "meganon"); return; } ID alignWriteMsf TY static MO ajalign LB core XX DE Writes an alignment in MSF format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMsf(AjPAlign thys) { alignWriteSeqformat(thys, 0, "msf"); return; } ID alignWriteNexus TY static MO ajalign LB core XX DE Writes an alignment in Nexus/PAUP interleaved format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteNexus(AjPAlign thys) { alignWriteSeqformat(thys, 0, "nexus"); return; } ID alignWriteNexusnon TY static MO ajalign LB core XX DE Writes an alignment in Nexus/PAUP non-interleaved format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteNexusnon(AjPAlign thys) { alignWriteSeqformat(thys, 0, "nexusnon"); return; } ID alignWritePhylip TY static MO ajalign LB core XX DE Writes an alignment in Phylip interleaved format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWritePhylip(AjPAlign thys) { alignWriteSeqformat(thys, 0, "phylip"); return; } ID alignWritePhylipnon TY static MO ajalign LB core XX DE Writes an alignment in Phylip non-interleaved format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWritePhylipnon(AjPAlign thys) { alignWriteSeqformat(thys, 0, "phylipnon"); return; } ID alignWriteSelex TY static MO ajalign LB core XX DE Writes an alignment in SELEX format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteSelex(AjPAlign thys) { alignWriteSeqformat(thys, 0, "selex"); return; } ID alignWriteTreecon TY static MO ajalign LB core XX DE Writes an alignment in Treecon format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteTreecon(AjPAlign thys) { alignWriteSeqformat(thys, 0, "treecon"); return; } ID alignWriteFasta TY static MO ajalign LB core XX DE Writes an alignment in MSF format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteFasta(AjPAlign thys) { alignWriteSeqformat(thys, 0, "fasta"); return; } ID alignWriteSeqformat TY static MO ajalign LB core XX DE Writes an alignment in a sequence format. DE Usually called for only one alignment, ignoring any DE sub-alignments as they would overwrite. XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD Alignment number PX PN [3] PA r sqfmt const char* PD Sequence output format PX RT void RD RX // static void alignWriteSeqformat(AjPAlign thys, ajint iali, const char* sqfmt) { AlignPData data = NULL; AjPSeq seq = NULL; AjPSeqout seqout; ajint iseq; ajint istart; ajint iend; ajint ilen; AjPStr tmpstr = NULL; seqout = ajSeqoutNewFile(thys->File); thys->SeqOnly = ajTrue; ajStrAssignC(&seqout->Formatstr, sqfmt); seqout->File = thys->File; ajSeqoutOpen(seqout); ajListPeekNumber(thys->Data, 0, (void**) &data); ilen = data->LenAli; for(iseq=0; iseq < thys->Nseqs; iseq++) { seq = ajSeqNewSeq(alignSeq(thys, iseq, iali)); istart = data->SubOffset[iseq]; iend = istart + ilen - 1; ajStrAssignSubS(&tmpstr, ajSeqGetSeqS(seq), istart, iend); ajSeqAssignSeqS(seq, tmpstr); ajSeqoutWriteSeq(seqout, seq); ajSeqDel(&seq); ajStrDel(&tmpstr); } ajSeqoutClose(seqout); seqout->File = NULL; ajSeqoutDel(&seqout); return; } ID alignWriteMarkX0 TY static MO ajalign LB core XX DE Writes an alignment in Fasta MarkX 0 format. DE DE This is the standard default output format for FASTA programs. XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMarkX0(AjPAlign thys) { ajint iali; ajint nali; nali = (ajuint) ajListGetLength(thys->Data); for(iali=0; iali < nali; iali++) alignWriteMark(thys, iali, 0); return; } ID alignWriteMarkX1 TY static MO ajalign LB core XX DE Writes an alignment in Fasta MarkX 1 format. DE DE This is an alternative output format for FASTA programs in which DE identities are not marked. DE Instead conservative replacements are denoted by 'x' DE and non-conservative substitutions by 'X'. XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMarkX1(AjPAlign thys) { ajint iali; ajint nali; nali = (ajuint) ajListGetLength(thys->Data); for(iali=0; iali < nali; iali++) alignWriteMark(thys, iali, 1); return; } ID alignWriteMarkX2 TY static MO ajalign LB core XX DE Writes an alignment in Fasta MarkX 2 format DE DE This is an alternative output format for FASTA programs in which DE the residues in the second sequence are only shown if they are DE different from the first. XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMarkX2(AjPAlign thys) { ajint iali; ajint nali; nali = (ajuint) ajListGetLength(thys->Data); for(iali=0; iali < nali; iali++) alignWriteMark(thys, iali, 2); return; } ID alignWriteMarkX3 TY static MO ajalign LB core XX DE Writes an alignment in Fasta MarkX 3 format DE DE This is an alternative output format for FASTA programs in which DE the aligned library sequences are displayed in FASTA format DE These can be used to build a primitive multiple alignment. XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMarkX3(AjPAlign thys) { ajint iali; ajint nali; nali = (ajuint) ajListGetLength(thys->Data); for(iali=0; iali < nali; iali++) alignWriteMark(thys, iali, 3); return; } ID alignWriteMarkX10 TY static MO ajalign LB core XX DE Writes an alignment in Fasta MarkX 10 format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMarkX10(AjPAlign thys) { ajint iali; ajint nali; nali = (ajuint) ajListGetLength(thys->Data); for(iali=0; iali < nali; iali++) alignWriteMark(thys, iali, 10); return; } ID alignWriteMark TY static MO ajalign LB core XX DE Writes a pairwise alignment in a Fasta MarkX format. DE DE For now, seems to work with 0, 1, 2, 3 or 10. DE FASTA 3.4 has 4, 5, 6 and 9 as possible options DE but most seem to make no difference on pairwise comparisons. DE DE 0: identities marked with ':' similarities with '.' DE DE 1: differences marked with 'X' DE DE 2: identities marked with '.', differences with seq2 character DE DE 3: fasta format sequences with no description DE DE 10: aligned regions with associated data XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD Alignment number PX PN [3] PA r markx ajint PD Markup type (as defined in Bill Pearson's PD FASTA suite PX RT void RD RX // static void alignWriteMark(AjPAlign thys, ajint iali, ajint markx) { AjPFile outf; int nseq; const AjPStr seq = NULL; const AjPSeq seqp = NULL; AlignPData data = NULL; ajint iseq; ajint i; ajint j; ajint jj; ajint kk; ajint istart; ajint iend; ajint ilen; ajint jstart; ajint jend; ajint iwidth = 50; const char* cp; AjPStr tmpstr = NULL; AjPStr mrkstr = NULL; AjPStr mrkcons = NULL; AjPStr cons = NULL; ajint identity = 0; ajint similarity = 0; ajint gaps = 0; ajint seqlen = 0; ajint* ipos = NULL; ajint* incs = NULL; AjBool* num = NULL; ajint jpos; ajint icnt; ajint increment = 1; AjPStr tmphdr = NULL; AjPStr tmpnum = NULL; AjBool lastline = ajFalse; AjBool isnuc = ajFalse; static ajint icount = 0; float ident = 0.0; ajDebug("alignWriteMark iali:%d markx:%d\n", iali, markx); icount++; nseq = thys->Nseqs; outf = thys->File; if(thys->Width) iwidth = thys->Width; ajListPeekNumber(thys->Data, iali, (void**) &data); AJCNEW0(ipos, nseq); AJCNEW0(incs, nseq); AJCNEW0(num, nseq); ajStrDel(&cons); ajStrDel(&tmphdr); ilen = data->LenAli; alignConsStats(thys, iali, &cons, &identity, &similarity, &gaps, &seqlen); ajAlignSetStats(thys, iali, seqlen, identity, similarity, gaps, NULL); ajAlignSetSubStandard(thys, iali); alignWriteHeaderNum(thys,iali); isnuc = ajSeqIsNuc(data->Seq[0]); ident = (float) data->NumId / (float) data->LenAli; /*ajDebug("# Consens: '%S'\n\n", cons);*/ if(markx == 1) alignSim(&cons, ' ', ' ', 'X', ' '); else if(markx == 2) { seq = ajSeqGetSeqS(data->Seq[0]); alignConsSet(thys, iali, 1, &cons); ajDebug("alignWriteMark(%d)\nseq0:%S\ncons:%S\nseq1:%S\n", markx, seq, cons, ajSeqGetSeqS(data->Seq[1])); alignDiff(&cons, seq, '.'); ajDebug("alignWriteMark(%d)\nseq0:%S\ncons:%S\nseq1:%S\n", markx, seq, cons, ajSeqGetSeqS(data->Seq[1])); } else alignSim(&cons, ':', '.', ' ', ' '); /*ajDebug("# Modcons: '%S'\n\n", cons);*/ ajDebug("# nseq:%d\n", nseq); ajDebug("# AliData [%d] len %d \n", iali, ilen); for(iseq=0; iseq < nseq; iseq++) { incs[iseq] = alignSeqIncrement(data, iseq); ipos[iseq] = alignSeqBegin(data, iseq)-incs[iseq]; /*ajDebug("# Seq[%d]'%S'\n", iseq, ajSeqGetSeqS(data->Seq[iseq]));*/ } /* for(iseq=0; iseq < nseq; iseq++) { ajDebug("# Seq[%d] Len:%d Start:%d End:%d Rev:%B Off:%d\n", iseq, data->Len[iseq], data->Start[iseq], data->End[iseq], data->Rev[iseq], data->Offset[iseq]); } */ if(markx==10) { if(isnuc) ajFmtPrintF(outf,">>>%s, %d nt vs %s, %d nt\n", ajSeqGetNameC(data->Seq[0]), data->Len[0], ajSeqGetNameC(data->Seq[1]), data->Len[1]); else ajFmtPrintF(outf,">>>%s, %d aa vs %s, %d aa\n", ajSeqGetNameC(data->Seq[0]), data->Len[0], ajSeqGetNameC(data->Seq[1]), data->Len[1]); ajFmtPrintF(outf,"; mp_name: EMBOSS\n"); ajFmtPrintF(outf,"; mp_ver: %S\n", ajNamValueVersion()); ajFmtPrintF(outf,"; pg_name: %S\n", ajUtilGetProgram()); ajFmtPrintF(outf,"; pg_ver: %S\n", ajNamValueVersion()); ajFmtPrintF(outf,"; pg_matrix: %S\n", thys->Matrix); ajFmtPrintF(outf,"; pg_gap-pen: -%S -%S\n", thys->GapPen, thys->ExtPen); ajFmtPrintF(outf,">>#%d\n", icount); ajFmtPrintF(outf,"; sw_score: %S\n", data->Score); ident = (float) data->NumId / (float) data->LenAli; ajFmtPrintF(outf,"; sw_ident: %5.3f\n", ident); ajFmtPrintF(outf,"; sw_overlap: %d\n", data->LenAli); } if(markx <= 2) { for(i=0; i < ilen; i += iwidth) { for(iseq=0; iseq < nseq; iseq++) { seqp = data->Seq[iseq]; seq = ajSeqGetSeqS(seqp); istart = i + data->SubOffset[iseq]; iend = (istart+iwidth-1); if(iend >= (data->SubOffset[iseq]+ilen-1)) { iend = data->SubOffset[iseq]+ilen-1; lastline = ajTrue; } increment = incs[iseq]; ajStrAssignSubS(&tmpstr, seq, istart, iend); ajStrAssignSubS(&mrkcons, cons, istart - data->SubOffset[iseq], iend - data->SubOffset[iseq]); ajStrExchangeCC(&tmpstr, ".", "-"); icnt = ajStrGetLen(tmpstr) - (size_t) ajStrCalcCountK(tmpstr, '-') - (size_t) ajStrCalcCountK(tmpstr, ' '); /* number the top sequence */ if(!iseq) { jpos = ipos[iseq]; ajStrAssignClear(&tmpnum); jj=7; cp = ajStrGetPtr(tmpstr); while(*cp) { jj ++; if((*cp != '-') && (*cp != ' ')) { jpos += increment; if(jpos%10 == 0) { ajFmtPrintAppS(&tmpnum,"%*d",jj,jpos); jj=0; num[iseq] = ajTrue; } } cp++; } if(lastline && !num[iseq]) { ajFmtPrintAppS(&tmpnum,"%*d",jj,jpos); jj=0; } if(jj) ajStrAppendCountK(&tmpnum, ' ', jj); ajFmtPrintF(outf, "%S\n", tmpnum); } if(!iseq) ajStrAssignS(&mrkstr, tmpstr); else alignSame(&mrkstr, tmpstr, ' '); if(markx==2 && nseq==2 && iseq==1) { ajFmtPrintF(outf, "%6.6S %S\n", alignSeqName(thys, seqp), mrkcons); } else { if(nseq==2 && iseq==1) ajFmtPrintF(outf, " %S\n", mrkcons); if(ajStrGetLen(tmpstr)) { ajFmtPrintF(outf, "%6.6S %S\n", alignSeqName(thys, seqp), tmpstr); } else ajFmtPrintF(outf, "%6.6S\n", alignSeqName(thys, seqp)); /* number the bottom sequence */ if(iseq+1 == nseq) { jpos = ipos[iseq]; ajStrAssignClear(&tmpnum); jj=7; kk=7; cp = ajStrGetPtr(tmpstr); while(*cp) { jj++; if((*cp != '-') && (*cp != ' ')) { kk = jj; jpos += increment; if(jpos%10 == 0) { ajFmtPrintAppS(&tmpnum,"%*d",jj,jpos); jj=0; kk=0; num[iseq] = ajTrue; } } cp++; } if(lastline && !num[iseq]) { ajFmtPrintAppS(&tmpnum,"%*d",kk,jpos); jj = jj - kk; } if(jj) ajStrAppendCountK(&tmpnum, ' ', jj); ajFmtPrintF(outf, "%S\n", tmpnum); } if(increment > 0) ipos[iseq] += icnt; else ipos[iseq] -= icnt; } } if(nseq > 2) /* 3 or more seqs, markup under */ ajFmtPrintF(outf, " %S\n", mrkcons); ajFmtPrintF(outf, "\n"); } } else { for(iseq=0; iseq < nseq; iseq++) { seqp = data->Seq[iseq]; seq = ajSeqGetSeqS(seqp); istart = data->SubOffset[iseq]; iend = istart + ilen - 1; ajStrAssignSubS(&tmpstr, seq, istart, iend); ajStrAssignSubS(&mrkcons, cons, istart - data->SubOffset[iseq], iend - data->SubOffset[iseq]); ajStrExchangeCC(&tmpstr, ".", "-"); icnt = ajStrGetLen(tmpstr) - (size_t) ajStrCalcCountK(tmpstr, '-') - (size_t) ajStrCalcCountK(tmpstr, ' '); if(!iseq) ajStrAssignS(&mrkstr, tmpstr); else alignSame(&mrkstr, tmpstr, ' '); if(markx==3) { ajFmtPrintF(outf, ">%S ..\n", alignSeqName(thys, seqp)); } else if(markx==10) { ajFmtPrintF(outf,">%S ..\n", alignSeqName(thys, seqp)); ajFmtPrintF(outf,"; sq_len: %d\n", data->Len[iseq]); if(ajSeqIsNuc(data->Seq[iseq])) ajFmtPrintF(outf,"; sq_type: D\n"); else ajFmtPrintF(outf,"; sq_type: p\n"); ajFmtPrintF(outf,"; al_start: %d\n", data->Offset[iseq] + data->Start[iseq]); ajFmtPrintF(outf,"; al_stop: %d\n", data->Offset[iseq] + data->Start[iseq] + icnt - 1); ajFmtPrintF(outf,"; al_display_start: %d\n", data->Offset[iseq] + data->Start[iseq]); } else { } for(j=0; j < ilen; j += iwidth) { jstart = j + data->SubOffset[iseq]; jend = AJMIN(data->SubOffset[iseq]+ilen-1, jstart+iwidth-1); ajStrAssignSubS(&tmpstr, seq, jstart, jend); if(ajStrGetLen(tmpstr)) { ajFmtPrintF(outf, "%S\n", tmpstr); } } ipos[iseq] += icnt; } } ajStrDel(&cons); ajStrDel(&mrkcons); ajStrDel(&mrkstr); ajStrDel(&tmpstr); ajStrDel(&tmphdr); ajStrDel(&tmpnum); AJFREE(ipos); AJFREE(incs); AJFREE(num); return; } ID alignWriteMatch TY static MO ajalign LB core XX DE Writes an alignment in Match format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteMatch(AjPAlign thys) { AjPFile outf; const AjPSeq seq1; const AjPSeq seq2; ajint nali; ajint iali; ajint len0; char fwd0 = '+'; char fwd1 = '+'; ajint endgaps = 0; ajint begingaps = 0; AlignPData* pdata = NULL; AlignPData data = NULL; outf = thys->File; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); ajAlignWriteHeader(thys); for(iali=0; ialiEnd[0] - data->Start[0] + 1; if(alignSeqRev(data, 0)) fwd0 = '-'; if(alignSeqRev(data, 1)) fwd1 = '-'; begingaps = alignSeqGapBegin(data,0) + alignSeqGapBegin(data,1); endgaps = alignSeqGapEnd(data,0) + alignSeqGapEnd(data,1); seq1 = alignSeq(thys, 0, iali); seq2 = alignSeq(thys, 1, iali); if(thys->Global) { len0 = len0 - endgaps - begingaps; ajFmtPrintF(outf, "%6d %-15.15S %c %8d..%-8d %-15.15S %c %8d..%d\n", len0, alignSeqName(thys, seq1), fwd0, alignSeqBegin(data,0) + alignSeqGapBegin(data,1), alignSeqEnd(data,0) - endgaps - alignSeqGapBegin(data,0), alignSeqName(thys, seq2), fwd1, alignSeqBegin(data,1) + alignSeqGapBegin(data,0), alignSeqEnd(data,1) - endgaps - alignSeqGapBegin(data,1)); } else { ajFmtPrintF(outf, "%6d %-15.15S %c %8d..%-8d %-15.15S %c %8d..%d\n", len0, alignSeqName(thys, seq1), fwd0, alignSeqBegin(data,0), alignSeqEnd(data,0), alignSeqName(thys, seq2), fwd1, alignSeqBegin(data,1), alignSeqEnd(data,1)); } } AJFREE(pdata); return; } ID alignWriteSimple TY static MO ajalign LB core XX DE Writes an alignment in Simple format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteSimple(AjPAlign thys) { AjPFile outf; int nseq; int nali; const AjPStr seq = NULL; AlignPData* pdata = NULL; AlignPData data = NULL; ajint iali; ajint iseq; ajint i; ajint istart; ajint iend; ajint ilen; ajint iwidth = 50; AjPStr tmpstr = NULL; AjPStr mrkstr = NULL; AjPStr mrkcons = NULL; AjPStr cons = NULL; ajint identity = 0; ajint similarity = 0; ajint gaps = 0; ajint seqlen = 0; ajint icnt; ajint* ipos = NULL; ajint* incs = NULL; AjPStr tmphdr = NULL; ajDebug("alignWriteSimple\n"); nseq = thys->Nseqs; outf = thys->File; if(thys->Width) iwidth = thys->Width; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); AJCNEW0(ipos, nseq); AJCNEW0(incs, nseq); for(iali=0; ialiLenAli; alignConsStats(thys, iali, &cons, &identity, &similarity, &gaps, &seqlen); ajAlignSetStats(thys, iali, seqlen, identity, similarity, gaps, NULL); ajAlignSetSubStandard(thys, iali); alignWriteHeaderNum(thys, iali); /*ajDebug("# Consens: '%S'\n\n", cons);*/ alignSim(&cons, '|', ':', '.', ' '); /*ajDebug("# Modcons: '%S'\n\n", cons);*/ ajDebug("# Nali:%d nseq:%d\n", nali, nseq); ajDebug("# AliData [%d] len %d \n", iali, ilen); for(iseq=0; iseq < nseq; iseq++) { incs[iseq] = alignSeqIncrement(data, iseq); ipos[iseq] = alignSeqBegin(data, iseq)-incs[iseq]; /* ajDebug("# Seq[%d]'%S'\n", iseq, ajSeqGetSeqS(data->Seq[iseq]));*/ } /* for(iseq=0; iseq < nseq; iseq++) { ajDebug("# Seq[%d] Len:%d Start:%d End:%d Rev:%B\n", iseq, data->Len[iseq], data->Start[iseq], data->End[iseq], data->Rev[iseq]); } */ for(i=0; i < ilen; i += iwidth) { for(iseq=0; iseq < nseq; iseq++) { seq = ajSeqGetSeqS(data->Seq[iseq]); istart = i + data->SubOffset[iseq]; iend = AJMIN(data->SubOffset[iseq]+ilen-1, istart+iwidth-1); ajStrAssignSubS(&tmpstr, seq, istart, iend); ajStrAssignSubS(&mrkcons, cons, istart - data->SubOffset[iseq], iend - data->SubOffset[iseq]); ajStrExchangeCC(&tmpstr, ".", "-"); icnt = incs[iseq] * (ajStrGetLen(tmpstr) - (size_t)ajStrCalcCountK(tmpstr, '-') - (size_t)ajStrCalcCountK(tmpstr, ' ')); if(!iseq) ajStrAssignS(&mrkstr, tmpstr); else alignSame(&mrkstr, tmpstr, ' '); if(nseq==2 && iseq==1) /* 2 seqs, markup between them */ ajFmtPrintF(outf, " %S\n", mrkcons); if(ajStrGetLen(tmpstr)) { ajFmtPrintF(outf, "%-13.13S %6d %S %6d\n", alignSeqName(thys, data->Seq[iseq]), ipos[iseq]+incs[iseq], tmpstr, ipos[iseq]+icnt); } else ajFmtPrintF(outf, "%-13.13S\n", alignSeqName(thys, data->Seq[iseq])); ipos[iseq] += icnt; } if(nseq > 2) /* 3 or more seqs, markup under */ ajFmtPrintF(outf, " %S\n", mrkcons); ajFmtPrintF(outf, "\n"); } } ajStrDel(&cons); ajStrDel(&mrkcons); ajStrDel(&mrkstr); ajStrDel(&tmpstr); AJFREE(ipos); AJFREE(incs); AJFREE(pdata); return; } ID alignWriteScore TY static MO ajalign LB core XX DE Writes an alignment in Score-only format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteScore(AjPAlign thys) { AjPFile outf; ajint nali; ajint iali; AlignPData* pdata = NULL; AlignPData data = NULL; const AjPSeq seq1; const AjPSeq seq2; outf = thys->File; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); for(iali=0; ialiSeq[0]; seq2 = data->Seq[1]; if(ajStrGetLen(data->Score)) ajFmtPrintF(outf, "%S %S %d (%S)\n", alignSeqName(thys, seq1), alignSeqName(thys, seq2), data->LenAli, data->Score); else ajFmtPrintF(outf, "%S %S %d\n", alignSeqName(thys, seq1), alignSeqName(thys, seq2), data->LenAli); } AJFREE(pdata); return; } ID alignWriteSam TY static MO ajalign LB core XX DE Writes an alignment in sequence alignment/map (SAM) format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteSam(AjPAlign thys) { AjPFile outf; ajint nali; ajint iali; ajint iseq; ajuint j; ajuint qrystart; ajuint qryend; ajuint qualstart; ajuint qualend; ajint refstart; ajint nmismatches; AlignPData* pdata = NULL; AlignPData data = NULL; ajint refpos = 0; /* 1-based leftmost position on the reference sequence */ const AjPSeq refseq; const AjPSeq qryseq; AjPStr seqacc = NULL; ajuint flag = 0; /* bitwise flag, section 2.2.2 in SAM specification */ ajuint mapq = 255; /* mapping quality, 255 means not available */ AjPStr cigar = NULL; /* extended CIGAR string */ AjPStr mrnm = NULL; /* mate reference sequence name */ ajuint mpos = 0; /* leftmost mate position of the clipped sequence */ ajuint isize = 0; /* inferred insert size */ AjPStr argstr; AjPStr mseq = NULL; /* match region of the query sequence */ mseq = ajStrNew(); mrnm = ajStrNewC("*");/* TODO: mate sequences not yet supported */ outf = thys->File; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); if(!thys->Count++) { ajFmtPrintF(outf, "@HD\tVN:1.3\n"); /* Program record */ argstr = ajStrNewS(ajUtilGetCmdline()); ajStrExchangeKK(&argstr, '\n', ' '); ajFmtPrintF(outf, "@PG\tID:%S\tVN:%S\tCL:%S\n", ajUtilGetProgram(), ajNamValueVersion(), argstr); ajStrDel(&argstr); } for(iali=0; ialiSeq[thys->RefSeq]; refpos = alignSeqBegin(data, thys->RefSeq) + 1 - alignSeqIncrement(data, thys->RefSeq); for(iseq=0; iseq < data->Nseqs; iseq++) { if(iseq==thys->RefSeq) continue; qryseq = data->Seq[iseq]; if(ajSeqIsReversed(qryseq)) flag |= 0x0010; if(thys->Global ||thys->SeqExternal) { qrystart = alignSeqBegin(data,iseq) - alignSeqIncrement(data,iseq); qryend = alignSeqEnd(data,iseq); refstart = refpos-1; } else { qrystart = 0; qryend = data->LenAli; refstart = 0; } qualstart = qrystart; qualend = AJMIN(qryend, qryseq->Qualsize); if(qryseq->Accuracy) { ajStrAssignClear(&seqacc); /* ASCII-33 gives the Phred base quality */ for(j=qualstart;j< qualend;j++) ajStrAppendK(&seqacc, (char) (33 + qryseq->Accuracy[j])); } else ajStrAssignC(&seqacc,"*"); ajStrAssignClear(&mseq); ajStrAssignClear(&cigar); /* get CIGAR, match region of the query sequence and #mismatches */ nmismatches = alignCigar(qryseq, refseq, qrystart, qryend, refstart, &mseq, &cigar, thys->SeqExternal); ajFmtPrintF(outf, "%S\t%u\t%S\t%d\t%d\t%S\t%S\t%u\t%u\t%S\t%S\t" "AS:i:%S\tNM:i:%d\n", alignSeqName(thys, qryseq), flag, alignSeqName(thys, refseq), refpos, mapq, cigar, mrnm, mpos, isize, mseq, seqacc, data->Score, nmismatches); } } AJFREE(pdata); ajStrDel(&cigar); ajStrDel(&mrnm); ajStrDel(&seqacc); ajStrDel(&mseq); return; } ID alignWriteSrs TY static MO ajalign LB core XX DE Writes an alignment in SRS format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteSrs(AjPAlign thys) { alignWriteSrsAny(thys, 0, ajFalse); return; } ID alignWriteSrsPair TY static MO ajalign LB core XX DE Writes an alignment in SrsPair format XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteSrsPair(AjPAlign thys) { alignWriteSrsAny(thys, 2, ajTrue); return; } ID alignWriteSrsAny TY static MO ajalign LB core XX DE Writes an alignment in SRS format (with switches for pairwise and general DE formatting) XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r imax ajint PD Maximum number of sequences (0 for unknown) PX PN [3] PA r mark AjBool PD Markup the alignment PX RT void RD RX // static void alignWriteSrsAny(AjPAlign thys, ajint imax, AjBool mark) { AjPFile outf; int nseq; int nali; const AjPStr seq = NULL; AlignPData* pdata = NULL; AlignPData data = NULL; ajint iali; ajint iseq; ajint i; ajint istart; ajint iend; ajint ilen; AjPStr tmpstr = NULL; AjPStr mrkstr = NULL; AjPStr mrkcons = NULL; AjPStr cons = NULL; ajint iwidth = 50; ajint identity = 0; ajint similarity = 0; ajint gaps=0; ajint seqlen=0; ajint icnt; ajint* ipos = NULL; ajint* incs = NULL; AjBool pair = ajFalse; AjPStr tmphdr = NULL; outf = thys->File; nseq = thys->Nseqs; if(nseq < 1) { ajAlignWriteHeader(thys); return; } if(thys->Width) iwidth = thys->Width; /* ** pair: if true, change consensus into |:. markup ** and put markup line between sequences */ if(imax == 2 && nseq == 2 && mark) pair = ajTrue; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); AJCNEW0(ipos, nseq); AJCNEW0(incs, nseq); for(iali=0; ialiLenAli; ajStrDel(&cons); ajStrDel(&tmphdr); alignConsStats(thys, iali, &cons, &identity, &similarity, &gaps, &seqlen); ajAlignSetStats(thys, iali, seqlen, identity, similarity, gaps, NULL); ajAlignSetSubStandard(thys, iali); alignWriteHeaderNum(thys, iali); /*ajDebug("# Consens: '%S'\n\n", cons);*/ if(pair) alignSim(&cons, '|', ':', '.', ' '); /*ajDebug("# Modcons: '%S'\n\n", cons);*/ ajDebug("# Nali:%d nseq:%d\n", nali, nseq); ajDebug("# AliData [%d] len %d \n", iali, ilen); for(iseq=0; iseq < nseq; iseq++) { incs[iseq] = alignSeqIncrement(data, iseq); ipos[iseq] = alignSeqBegin(data, iseq)-incs[iseq]; /*ajDebug("# Seq[%d] Off:%d Sta:%d End:%d '%S'\n", iseq, data->Offset[iseq], data->Start[iseq], data->End[iseq], ajSeqGetSeqS(data->Seq[iseq]));*/ } /* for(iseq=0; iseq < nseq; iseq++) ajDebug("# Seq[%d] Start:%d End:%d Rev:%B\n", iseq, data->Start[iseq], data->End[iseq], data->Rev[iseq]); */ for(i=0; i < ilen; i += iwidth) { for(iseq=0; iseq < nseq; iseq++) { seq = ajSeqGetSeqS(data->Seq[iseq]); istart = i + data->SubOffset[iseq]; iend = AJMIN(data->SubOffset[iseq]+ilen-1, istart+iwidth-1); ajStrAssignSubS(&tmpstr, seq, istart, iend); ajStrAssignSubS(&mrkcons, cons, istart - data->SubOffset[iseq], iend - data->SubOffset[iseq]); ajStrExchangeCC(&tmpstr, ".", "-"); icnt = incs[iseq] * (ajStrGetLen(tmpstr) - (size_t)ajStrCalcCountK(tmpstr, '-') - (size_t)ajStrCalcCountK(tmpstr, ' ')); if(!iseq) ajStrAssignS(&mrkstr, tmpstr); else alignSame(&mrkstr, tmpstr, ' '); if(pair && iseq==1) /* 2 seqs, markup between them */ ajFmtPrintF(outf, " %S\n", mrkcons); if(ajStrGetLen(tmpstr)) { if(icnt) ajFmtPrintF(outf, "%-13.13S %6d %S %6d\n", alignSeqName(thys, data->Seq[iseq]), ipos[iseq]+incs[iseq], tmpstr, ipos[iseq]+icnt); else ajFmtPrintF(outf, "%-13.13S %6d %S %6d\n", alignSeqName(thys, data->Seq[iseq]), ipos[iseq], tmpstr, ipos[iseq]); } else ajFmtPrintF(outf, "%-13.13S\n", alignSeqName(thys, data->Seq[iseq])); ipos[iseq] += icnt; } if(mark && !pair) /* 3 or more seqs, markup under */ ajFmtPrintF(outf, " %S\n", mrkcons); ajFmtPrintF(outf, "\n"); } } ajStrDel(&mrkcons); ajStrDel(&tmpstr); ajStrDel(&mrkstr); ajStrDel(&cons); AJFREE(ipos); AJFREE(incs); AJFREE(pdata); return; } ID alignWriteTCoffee TY static MO ajalign LB core XX DE Writes an alignment as a T-COFFEE library XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // static void alignWriteTCoffee (AjPAlign thys) { AjPFile outf = thys->File; int nseq; int nali; AlignPData* pdata = NULL; AlignPData data = NULL; ajint iali; ajint iseq; ajint i; ajint s1,s2; ajint n1,n2; ajint ilen; AjPStr sseq= NULL; const AjPStr sseq1= NULL; const AjPStr sseq2= NULL; ajint pidentity=0; ajDebug("alignWriteTCoffee\n"); nseq = thys->Nseqs; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); thys->SeqOnly = ajTrue; /* suppress output of tail */ /* print header */ ajFmtPrintF(outf, "%d\n", nseq); /* number of sequences */ for(iseq=0; iseq < nseq; iseq++) { ajStrAssignS(&sseq,ajSeqGetSeqS(pdata[0]->Seq[iseq])); ajStrRemoveWhite(&sseq); ajStrExchangeCC(&sseq, "-",""); /* */ ajFmtPrintF(outf, "%S %d %S\n", alignSeqName(thys, pdata[0]->Seq[iseq]), ajStrGetLen(sseq), sseq); ajStrDel(&sseq); } for(iali = 0; ialiLenAli; pidentity = (int)(0.5 + 100.0 * (float) data->NumId / (float) data->LenAli); ajFmtPrintF(outf, "! score=%S\n",data->Score); ajFmtPrintF(outf, "! matrix=%S\n",thys->Matrix); ajFmtPrintF(outf, "! gapopen=%S gapext=%S\n", thys->GapPen,thys->ExtPen); /* go through all pairwise alignments */ for(s1=0; s1Seq[s1]); for(s2=s1+1; s2Seq[s2]); for(i=0; i='A' && ajStrGetCharPos(sseq2,i)>='A') { /* output aligned pair, sequence weight, residue weight, match weight (format as guessed from the T-coffee docs) */ ajFmtPrintF(outf, "%d %d %d %d %d\n", n1, n2, pidentity, 1, 0); } if(ajStrGetCharPos(sseq1,i)>='A') n1++; if(ajStrGetCharPos(sseq2,i)>='A') n2++; } } } } /* write footer */ ajFmtPrintF(outf, "! SEQ_1_TO_N\n"); AJFREE(pdata); return; } ID ajAlignDefine TY public MO ajalign LB core XX DE Defines a sequence set as an alignment. The sequences are stored internally DE and may be edited by alignment processing. XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA u seqset AjPSeqset PD Sequence set object PX RT AjBool RD ajTrue on success RX // AjBool ajAlignDefine(AjPAlign thys, AjPSeqset seqset) { AlignPData data = NULL; ajint i; const AjPSeq seq = NULL; if(!thys->Nseqs) thys->Nseqs = ajSeqsetGetSize(seqset); data = alignDataNew(thys->Nseqs, thys->SeqExternal); for(i=0; i < thys->Nseqs; i++) { seq = ajSeqsetGetseqSeq(seqset, i); alignDataSetSequence(data, seq, i, thys->SeqExternal); } data->LenAli = ajSeqsetGetLen(seqset); ajListPushAppend(thys->Data, data); return ajTrue; } ID ajAlignDefineSS TY public MO ajalign LB core XX DE Defines a sequence pair as an alignment. Either new copies of the DE sequences or direct references to them are made depending on the value DE of the SeqExternal attribute of the alignment object. XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r seqa const AjPSeq PD Sequence object PX PN [3] PA r seqb const AjPSeq PD Second sequence object PX RT AjBool RD ajTrue on success RX // AjBool ajAlignDefineSS(AjPAlign thys, const AjPSeq seqa, const AjPSeq seqb) { AlignPData data = NULL; if(!thys->Nseqs) thys->Nseqs = 2; if(thys->Nseqs != 2) { ajErr("ajAlignDefineSS called with %d sequences in alignment", thys->Nseqs); } data = alignDataNew(2, thys->SeqExternal); ajDebug("ajAlignDefineSS '%S' '%S'\n", ajSeqGetNameS(seqa), ajSeqGetNameS(seqb)); alignDataSetSequence(data, seqa, 0, thys->SeqExternal); if(!thys->SeqExternal && !ajSeqIsTrimmed(data->RealSeq[0])) { ajSeqTrim(data->RealSeq[0]); } alignDataSetSequence(data, seqb, 1, thys->SeqExternal); if(!thys->SeqExternal && !ajSeqIsTrimmed(data->RealSeq[1])) { ajSeqTrim(data->RealSeq[1]); } data->LenAli = AJMIN(ajSeqGetLen(seqa), ajSeqGetLen(seqb)); ajListPushAppend(thys->Data, data); return ajTrue; } ID ajAlignDefineCC TY public MO ajalign LB core XX DE Defines a pair of char* strings as an alignment XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r seqa const char* PD First sequence PX PN [3] PA r seqb const char* PD Second sequence PX PN [4] PA r namea const char* PD Name of first sequence PX PN [5] PA r nameb const char* PD Name of second sequence PX RT AjBool RD ajTrue on success RX // AjBool ajAlignDefineCC(AjPAlign thys, const char* seqa, const char* seqb, const char* namea, const char* nameb) { AlignPData data = NULL; AjPStr tmpstr = NULL; if(!thys->Nseqs) thys->Nseqs = 2; data = alignDataNew(2, AJFALSE); ajStrAssignC(&tmpstr, seqa); data->Start[0] = 1; data->End[0] = ajStrGetLen(tmpstr); data->Len[0] = ajStrGetLen(tmpstr) - ajSeqstrCountGaps(tmpstr); data->Offset[0] = 0; data->Offend[0] = 0; data->SubOffset[0] = 0; data->Rev[0] = ajFalse; /* no external option - we do need to create the AjPSeqs */ data->RealSeq[0] = ajSeqNewNameC(seqa, namea); ajSeqGapStandard(data->RealSeq[0], '-'); data->Seq[0] = data->RealSeq[0]; ajStrAssignC(&tmpstr, seqb); data->Start[1] = 1; data->End[1] = ajStrGetLen(tmpstr); data->Len[1] = ajStrGetLen(tmpstr) - ajSeqstrCountGaps(tmpstr); data->Offset[1] = 0; data->Offend[1] = 0; data->SubOffset[1] = 0; data->Rev[1] = ajFalse; data->RealSeq[1] = ajSeqNewNameC(seqb, nameb); ajSeqGapStandard(data->RealSeq[1], '-'); data->Seq[1] = data->RealSeq[1]; data->LenAli = AJMIN(strlen(seqa), strlen(seqb)); ajDebug("ajAlignDefineCC %s %d %s %d\n", namea, ajSeqGetLen(data->Seq[0]), nameb, ajSeqGetLen(data->Seq[1])); ajListPushAppend(thys->Data, data); ajStrDel(&tmpstr); return ajTrue; } ID ajAlignDel TY public MO ajalign LB core XX DE Destructor for Alignment objects XX PN [1] PA d pthys AjPAlign* PD Alignment object reference PX RT void RD RX CA delete CT AjPAlign CD Default destructor CX // void ajAlignDel(AjPAlign* pthys) { AlignPData data = NULL; AjPAlign thys; thys = *pthys; if(!thys) return; ajDebug("ajAlignDel %d seqs\n", thys->Nseqs); ajStrDel(&thys->Formatstr); ajStrDel(&thys->Type); ajStrDel(&thys->Header); ajStrDel(&thys->SubHeader); ajStrDel(&thys->Tail); ajStrDel(&thys->SubTail); ajStrDel(&thys->Matrix); ajStrDel(&thys->GapPen); ajStrDel(&thys->ExtPen); ajMatrixDel(&thys->IMatrix); ajMatrixfDel(&thys->FMatrix); while(ajListPop(thys->Data, (void**) &data)) alignDataDel(&data, thys->SeqExternal); ajListFree(&thys->Data); AJFREE(*pthys); return; } ID ajAlignReset TY public MO ajalign LB core XX DE Reset for Alignment objects XX PN [1] PA w thys AjPAlign PD Alignment object reference PX RT void RD RX CA modify CT AjPAlign CD Resets ready for reuse. CX // void ajAlignReset(AjPAlign thys) { AlignPData data = NULL; while(ajListPop(thys->Data, (void**) &data)) alignDataDel(&data, thys->SeqExternal); ajListFree(&thys->Data); thys->Data = ajListNew(); thys->Nseqs = 0; return; } ID ajAlignOpen TY public MO ajalign LB core XX DE Opens a new align file XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r name const AjPStr PD File name PX RT AjBool RD ajTrue on success RX // AjBool ajAlignOpen(AjPAlign thys, const AjPStr name) { if(!ajAlignValid(thys)) return ajFalse; thys->File = ajFileNewOutNameS(name); if(thys->File) return ajTrue; return ajFalse; } ID ajAlignFormatDefault TY public MO ajalign LB core XX DE Sets the default format for an alignment XX PN [1] PA w pformat AjPStr* PD Default format returned PX RT AjBool RD ajTrue if format was returned RX // AjBool ajAlignFormatDefault(AjPStr* pformat) { if(ajStrGetLen(*pformat)) ajDebug("... output format '%S'\n", *pformat); else { /* ajStrAssignEmptyC(pformat, alignFormat[0].Name);*/ ajStrAssignEmptyC(pformat, "gff"); /* use the real name */ ajDebug("... output format not set, default to '%S'\n", *pformat); } return ajTrue; } ID ajAlignGetLen TY public MO ajalign LB core XX DE Returns the filename for an alignment. If the alignment has more than one DE sub-alignment, returns the total. XX PN [1] PA r thys const AjPAlign PD Alignment object. PX RT ajint RD Alignment length. RX // ajint ajAlignGetLen(const AjPAlign thys) { ajint ret = 0; ajint i; ajint nali; AlignPData* pdata = NULL; AlignPData data = NULL; if(!thys) return 0; if(!thys->Data) return 0; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); for(i=0; iLenAli; } AJFREE(pdata); return ret; } ID ajAlignGetFilename TY public MO ajalign LB core XX DE Returns the filename for an alignment. XX PN [1] PA r thys const AjPAlign PD Alignment object. PX RT const char* RD Filename. RX // const char * ajAlignGetFilename(const AjPAlign thys) { if(!thys) return NULL; if(!thys->File) return NULL; return ajFileGetPrintnameC(thys->File); } ID ajAlignGetFormat TY public MO ajalign LB core XX DE Returns the sequence format for an alignment. XX PN [1] PA r thys const AjPAlign PD Alignment object. PX RT const AjPStr RD Alignment format RX // const AjPStr ajAlignGetFormat(const AjPAlign thys) { if(!thys) return NULL; return thys->Formatstr; } ID ajAlignFormatShowsSequences TY public MO ajalign LB core XX DE Returns whether current alignment format includes sequences in output XX PN [1] PA r thys const AjPAlign PD Alignment object PX RT AjBool RD true if sequences appear in output RX // AjBool ajAlignFormatShowsSequences(const AjPAlign thys) { if(!thys) return AJTRUE; return alignFormat[thys->Format].Showseqs; } ID ajAlignFindFormat TY public MO ajalign LB core XX DE Looks for the specified align format in the internal definitions and DE returns the index. XX PN [1] PA r format const AjPStr PD Format required. PX PN [2] PA w iformat ajint* PD Index PX RT AjBool RD ajTrue on success. RX // AjBool ajAlignFindFormat(const AjPStr format, ajint* iformat) { AjPStr tmpformat = NULL; ajint i = 0; ajDebug("ajAlignFindFormat '%S'\n", format); if(!ajStrGetLen(format)) return ajFalse; ajStrAssignS(&tmpformat, format); ajStrFmtLower(&tmpformat); while(alignFormat[i].Name) { if(ajStrMatchCaseC(tmpformat, alignFormat[i].Name)) { *iformat = i; ajStrDel(&tmpformat); ajDebug("... found at %d\n", i); return ajTrue; } i++; } ajDebug("... not found\n"); ajStrDel(&tmpformat); return ajFalse; } ID ajAlignValid TY public MO ajalign LB core XX DE Test for an alignment object. DE DE Checks the format works with the number of sequences. DE Checks the format works with the type (protein or nucleotide). XX PN [1] PA u thys AjPAlign PD Alignment object PX RT AjBool RD ajTrue on success RX // AjBool ajAlignValid(AjPAlign thys) { ajDebug("ajAlignValid format '%S' %d Nmin %d Nmax %d\n", thys->Formatstr, thys->Format, thys->Nmin, thys->Nmax); if(!thys->Format) /* test acdc-alignbadformat */ { if(ajStrGetLen(thys->Formatstr)) { if(!ajAlignFindFormat(thys->Formatstr, &thys->Format)) { ajErr("Unknown alignment format '%S'", thys->Formatstr); return ajFalse; } } else { ajStrAssignC(&thys->Formatstr,alignDefformat); ajAlignFindFormat(thys->Formatstr, &thys->Format); } } if( alignFormat[thys->Format].Minseq && thys->Nmin < alignFormat[thys->Format].Minseq) { ajErr("Alignment format %s specifies at least %d sequences, " "alignment has only %d", alignFormat[thys->Format].Name, alignFormat[thys->Format].Minseq, thys->Nmin); return ajFalse; } if( alignFormat[thys->Format].Maxseq && thys->Nmax > alignFormat[thys->Format].Maxseq) { ajErr("Alignment format %s specifies at most %d sequences, " "alignment has %d", alignFormat[thys->Format].Name, alignFormat[thys->Format].Maxseq, thys->Nmax); return ajFalse; } if(thys->Width < 10) { ajWarn("Alignment width (-awidth=%d) too narrow, reset to 10", thys->Width); thys->Width=10; } return ajTrue; } ID ajAlignNew TY public MO ajalign LB core XX DE Constructor for an alignment object XX RT AjPAlign RD New Alignment object RX CA new CT AjPAlign CD Default constructor CX // AjPAlign ajAlignNew(void) { AjPAlign pthis; AJNEW0(pthis); pthis->Count = 0; pthis->Formatstr = ajStrNew(); pthis->Format = 0; pthis->File = NULL; pthis->Data = ajListNew(); pthis->RefSeq = 0; return pthis; } ID ajAlignWrite TY public MO ajalign LB core XX DE Writes an alignment file XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX CA output CT AjPAlign CD Master alignment output routine CX // void ajAlignWrite(AjPAlign thys) { ajDebug("ajAlignWrite\n"); ajAlignTraceT(thys, "ajAlignWrite start"); if(!thys->Format) if(!ajAlignFindFormat(thys->Formatstr, &thys->Format)) ajErr("unknown align format '%S'", thys->Formatstr); ajDebug("ajAlignWrite %d '%s'\n", thys->Format, alignFormat[thys->Format].Name); ajAlignSetType(thys); /* Calling funclist alignFormat() */ (*alignFormat[thys->Format].Write)(thys); return; } ID ajAlignClose TY public MO ajalign LB core XX DE Closes an alignment XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // void ajAlignClose(AjPAlign thys) { ajDebug("ajAlignClose '%F'\n", thys->File); if(!thys->SeqOnly) ajAlignWriteTail(thys); ajFileClose(&thys->File); return; } ID ajAlignWriteHeader TY public MO ajalign LB core XX DE Writes an alignment header. XX PN [1] PA u thys AjPAlign PD Alignment object. Internal count is updated PD to avoid duplicate headers PX RT void RD RX CA output CT AjPAlign CD Master header output routine CX // void ajAlignWriteHeader(AjPAlign thys) { alignWriteHeaderNum(thys, 0); return; } ID alignWriteHeaderNum TY static MO ajalign LB core XX DE Writes an alignment header. XX PN [1] PA u thys AjPAlign PD Alignment object. Internal count is updated PD to avoid duplicate headers PX PN [2] PA r iali ajint PD Alignment number PX RT void RD RX CA output CT AjPAlign CD Master header output routine CX // static void alignWriteHeaderNum(AjPAlign thys, ajint iali) { AjPFile outf; AjPStr tmpstr = NULL; AjBool doSingle; ajint i; const AjPSeq seq; if(!alignFormat[thys->Format].Showheader) return; outf = thys->File; doSingle = ajFalse; /* turned off for now - always multi format */ if(!thys->Count) { ajFmtPrintF(outf, "########################################\n"); ajFmtPrintF(outf, "# Program: %S\n", ajUtilGetProgram()); ajFmtPrintF(outf, "# Rundate: %D\n", ajTimeRefTodayFmt("report")); ajFmtPrintF(outf, "# Commandline: %S\n", ajUtilGetProgram()); ajStrAssignS(&tmpstr, ajUtilGetCmdline()); if(ajStrGetLen(tmpstr)) { ajStrExchangeCC(&tmpstr, "\n", "\1# "); ajStrExchangeCC(&tmpstr, "\1", "\n"); ajFmtPrintF(outf, "# %S\n", tmpstr); } ajStrAssignS(&tmpstr, ajUtilGetInputs()); if(ajStrGetLen(tmpstr)) { ajStrExchangeCC(&tmpstr, "\n", "\1# "); ajStrExchangeCC(&tmpstr, "\1", "\n"); ajFmtPrintF(outf, "# %S\n", tmpstr); } ajFmtPrintF(outf, "# Align_format: %S\n", thys->Formatstr); ajFmtPrintF(outf, "# Report_file: %F\n", outf); if(!doSingle || thys->Multi) ajFmtPrintF(outf, "########################################\n"); else ajFmtPrintF(outf, "#\n"); } if(!doSingle || thys->Multi) ajFmtPrintF(outf, "\n#=======================================\n#\n"); ajFmtPrintF(outf, "# Aligned_sequences: %d\n", thys->Nseqs); for(i=0; i < thys->Nseqs; i++) { ajStrAssignClear(&tmpstr); seq = alignSeq(thys,i, iali); if(thys->Showacc) ajFmtPrintAppS(&tmpstr, " (%S)", ajSeqGetAccS(seq)); if(thys->Showdes) ajFmtPrintAppS(&tmpstr, " %S", ajSeqGetDescS(seq)); ajFmtPrintF(outf, "# %d: %S%S\n", i+1, alignSeqName(thys, seq), tmpstr); } if(ajStrGetLen(thys->Matrix)) ajFmtPrintF(outf, "# Matrix: %S\n", thys->Matrix); if(ajStrGetLen(thys->GapPen)) ajFmtPrintF(outf, "# Gap_penalty: %S\n", thys->GapPen); if(ajStrGetLen(thys->ExtPen)) ajFmtPrintF(outf, "# Extend_penalty: %S\n", thys->ExtPen); if(ajStrGetLen(thys->Header)) { ajStrAssignS(&tmpstr, thys->Header); ajStrExchangeCC(&tmpstr, "\n", "\1# "); ajStrExchangeCC(&tmpstr, "\1", "\n"); ajFmtPrintF(outf, "#\n"); ajFmtPrintF(outf, "# %S\n", tmpstr); ajFmtPrintF(outf, "#\n"); } if(ajStrGetLen(thys->SubHeader)) { ajStrAssignS(&tmpstr, thys->SubHeader); ajStrExchangeCC(&tmpstr, "\n", "\1# "); ajStrExchangeCC(&tmpstr, "\1", "\n"); ajFmtPrintF(outf, "#\n"); ajFmtPrintF(outf, "# %S\n", tmpstr); ajFmtPrintF(outf, "#\n"); ajStrDel(&thys->SubHeader); } if(!doSingle || thys->Multi) ajFmtPrintF(outf, "#=======================================\n\n"); else ajFmtPrintF(outf, "########################################\n\n"); ++thys->Count; ajStrDel(&tmpstr); return; } ID ajAlignWriteTail TY public MO ajalign LB core XX DE Writes an alignment tail XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX CA output CT AjPAlign CD Master footer output routine CX // void ajAlignWriteTail(AjPAlign thys) { AjPFile outf; AjPStr tmpstr = NULL; AjBool doSingle; if(!alignFormat[thys->Format].Showheader) return; outf = thys->File; doSingle = ajFalse; /* turned off for now - always multi format */ ajFmtPrintF(outf, "\n"); if(!doSingle || thys->Multi) ajFmtPrintF(outf, "#---------------------------------------\n"); else ajFmtPrintF(outf, "\n########################################\n"); if(ajStrGetLen(thys->SubTail)) { ajStrAssignS(&tmpstr, thys->SubTail); ajStrExchangeCC(&tmpstr, "\n", "\1# "); ajStrExchangeCC(&tmpstr, "\1", "\n"); ajFmtPrintF(outf, "#\n"); ajFmtPrintF(outf, "# %S\n", tmpstr); ajFmtPrintF(outf, "#\n"); ajStrDel(&thys->SubTail); } if(ajStrGetLen(thys->Tail)) { ajStrAssignS(&tmpstr, thys->Tail); ajStrExchangeCC(&tmpstr, "\n", "\1# "); ajStrExchangeCC(&tmpstr, "\1", "\n"); ajFmtPrintF(outf, "#\n"); ajFmtPrintF(outf, "# %S\n", tmpstr); ajFmtPrintF(outf, "#\n"); } if(!doSingle || thys->Multi) ajFmtPrintF(outf, "#---------------------------------------\n"); else ajFmtPrintF(outf, "########################################\n"); ajStrDel(&tmpstr); return; } ID ajAlignSetHeader TY public MO ajalign LB core XX DE Defines an alignment header XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r header const AjPStr PD Align header with embedded newlines PX RT void RD RX // void ajAlignSetHeader(AjPAlign thys, const AjPStr header) { ajStrAssignS(&thys->Header, header); ajDebug("ajAlignSetHeader len %d '%S'\n", ajStrGetLen(thys->Header), header); return; } ID ajAlignSetHeaderC TY public MO ajalign LB core XX DE Defines an alignment header XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r header const char* PD Align header with embedded newlines PX RT void RD RX // void ajAlignSetHeaderC(AjPAlign thys, const char* header) { ajStrAssignC(&thys->Header, header); ajDebug("ajAlignSetHeaderC len %d '%S'\n", ajStrGetLen(thys->Header), header); return; } ID ajAlignSetHeaderApp TY public MO ajalign LB core XX DE Appends to an alignment header XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r header const AjPStr PD Align header with embedded newlines PX RT void RD RX // void ajAlignSetHeaderApp(AjPAlign thys, const AjPStr header) { if(ajStrGetLen(thys->Header) && ajStrGetCharLast(thys->Header) != '\n') ajStrAppendC(&thys->Header, "\n"); ajStrAppendS(&thys->Header, header); ajDebug("ajAlignSetHeaderApp len %d '%S'\n", ajStrGetLen(thys->Header), header); return; } ID ajAlignSetTail TY public MO ajalign LB core XX DE Defines an alignment tail XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r tail const AjPStr PD Align tail with embedded newlines PX RT void RD RX // void ajAlignSetTail(AjPAlign thys, const AjPStr tail) { ajStrAssignS(&thys->Tail, tail); ajDebug("ajAlignSetTail len %d '%S'\n", ajStrGetLen(thys->Tail), tail); return; } ID ajAlignSetTailC TY public MO ajalign LB core XX DE Defines an alignment tail XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r tail const char* PD Align tail with embedded newlines PX RT void RD RX // void ajAlignSetTailC(AjPAlign thys, const char* tail) { ajStrAssignC(&thys->Tail, tail); ajDebug("ajAlignSetTailC len %d '%S'\n", ajStrGetLen(thys->Tail), tail); return; } ID ajAlignSetTailApp TY public MO ajalign LB core XX DE Appends to an alignment tail XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r tail const AjPStr PD Align tail with embedded newlines PX RT void RD RX // void ajAlignSetTailApp(AjPAlign thys, const AjPStr tail) { if(ajStrGetLen(thys->Tail) && ajStrGetCharLast(thys->Tail) != '\n') ajStrAppendC(&thys->Tail, "\n"); ajStrAppendS(&thys->Tail, tail); ajDebug("ajAlignSetTailApp len %d '%S'\n", ajStrGetLen(thys->Tail), tail); return; } ID ajAlignSetSubTail TY public MO ajalign LB core XX DE Defines an alignment tail XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r tail const AjPStr PD Align tail with embedded newlines PX RT void RD RX // void ajAlignSetSubTail(AjPAlign thys, const AjPStr tail) { ajStrAssignS(&thys->SubTail, tail); ajDebug("ajAlignSetSubTail len %d '%S'\n", ajStrGetLen(thys->SubTail), tail); return; } ID ajAlignSetSubTailC TY public MO ajalign LB core XX DE Defines an alignment tail XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r tail const char* PD Align tail with embedded newlines PX RT void RD RX // void ajAlignSetSubTailC(AjPAlign thys, const char* tail) { ajStrAssignC(&thys->SubTail, tail); ajDebug("ajAlignSetSubTailC len %d '%S'\n", ajStrGetLen(thys->SubTail), tail); return; } ID ajAlignSetSubTailApp TY public MO ajalign LB core XX DE Appends to an alignment tail XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r tail const AjPStr PD Align tail with embedded newlines PX RT void RD RX // void ajAlignSetSubTailApp(AjPAlign thys, const AjPStr tail) { if(ajStrGetLen(thys->SubTail) && ajStrGetCharLast(thys->SubTail) != '\n') ajStrAppendC(&thys->SubTail, "\n"); ajStrAppendS(&thys->SubTail, tail); ajDebug("ajAlignSetSubTailApp len %d '%S'\n", ajStrGetLen(thys->SubTail), tail); return; } ID ajAlignSetSubHeader TY public MO ajalign LB core XX DE Defines an alignment subheader (cleared after printing so it can DE be set again for the next alignment) XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r subheader const AjPStr PD Align subheader with embedded newlines PX RT void RD RX // void ajAlignSetSubHeader(AjPAlign thys, const AjPStr subheader) { ajStrAssignS(&thys->SubHeader, subheader); ajDebug("ajAlignSetSubHeader len %d '%S'\n", ajStrGetLen(thys->SubHeader), subheader); return; } ID ajAlignSetSubHeaderC TY public MO ajalign LB core XX DE Defines an alignment header (cleared after printing so it can DE be set again for the next alignment) XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r subheader const char* PD Align subheader with embedded newlines PX RT void RD RX // void ajAlignSetSubHeaderC(AjPAlign thys, const char* subheader) { ajStrAssignC(&thys->Header, subheader); ajDebug("ajAlignSetSubHeaderC len %d '%S'\n", ajStrGetLen(thys->SubHeader), subheader); return; } ID ajAlignSetSubHeaderApp TY public MO ajalign LB core XX DE Appends to an alignment subheader (cleared after printing so it can DE be set again for the next alignment) XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r subheader const AjPStr PD Align subheader with embedded newlines PX RT void RD RX // void ajAlignSetSubHeaderApp(AjPAlign thys, const AjPStr subheader) { if(ajStrGetLen(thys->SubHeader) && ajStrGetCharLast(thys->SubHeader) != '\n') ajStrAppendC(&thys->SubHeader, "\n"); ajStrAppendS(&thys->SubHeader, subheader); ajDebug("ajAlignSetSubHeaderApp len %d '%S'\n", ajStrGetLen(thys->SubHeader), subheader); return; } ID ajAlignSetSubHeaderPre TY public MO ajalign LB core XX DE Prepends to an alignment subheader (cleared after printing so it can DE be set again for the next alignment) XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r subheader const AjPStr PD Align subheader with embedded newlines PX RT void RD RX // void ajAlignSetSubHeaderPre(AjPAlign thys, const AjPStr subheader) { if(ajStrGetLen(thys->SubHeader) && ajStrGetCharLast(subheader) != '\n') ajStrInsertC(&thys->SubHeader, 0, "\n"); ajStrInsertS(&thys->SubHeader, 0, subheader); ajDebug("ajAlignSetSubHeaderPre len %d '%S'\n", ajStrGetLen(thys->SubHeader), subheader); return; } ID ajAlignSetMatrixName TY public MO ajalign LB core XX DE Defines an alignment matrix XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r matrix const AjPStr PD Matrix name PX RT void RD RX // void ajAlignSetMatrixName(AjPAlign thys, const AjPStr matrix) { ajAlignSetMatrixNameC(thys, ajStrGetPtr(matrix)); return; } ID ajAlignSetMatrixNameC TY public MO ajalign LB core XX DE Defines an alignment matrix XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r matrix const char* PD Matrix name PX RT void RD RX // void ajAlignSetMatrixNameC(AjPAlign thys, const char* matrix) { ajStrAssignC(&thys->Matrix, matrix); return; } ID ajAlignSetMatrixInt TY public MO ajalign LB core XX DE Defines an alignment matrix XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA u matrix AjPMatrix PD Matrix object PX RT void RD RX // void ajAlignSetMatrixInt(AjPAlign thys, AjPMatrix matrix) { if(!thys->IMatrix) { thys->IMatrix = matrix; ajAlignSetMatrixName(thys, ajMatrixGetName(matrix)); } if(thys->FMatrix) ajMatrixfDel(&thys->FMatrix); return; } ID ajAlignSetMatrixFloat TY public MO ajalign LB core XX DE Defines an alignment matrix XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA u matrix AjPMatrixf PD Matrix (floating point version) object PX RT void RD RX // void ajAlignSetMatrixFloat(AjPAlign thys, AjPMatrixf matrix) { if(!thys->FMatrix) { thys->FMatrix = matrix; ajAlignSetMatrixName(thys, ajMatrixfGetName(matrix)); } if(thys->IMatrix) ajMatrixDel(&thys->IMatrix); return; } ID ajAlignSetGapI TY public MO ajalign LB core XX DE Defines alignment gap penalties XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r gappen ajint PD Gap penalty PX PN [3] PA r extpen ajint PD Gap extension penalty PX RT void RD RX // void ajAlignSetGapI(AjPAlign thys, ajint gappen, ajint extpen) { AjPStr tmpstr = NULL; ajFmtPrintS(&tmpstr, "%d", gappen); ajStrAssignS(&thys->GapPen, tmpstr); ajFmtPrintS(&tmpstr, "%d", extpen); ajStrAssignS(&thys->ExtPen, tmpstr); ajStrDel(&tmpstr); return; } ID ajAlignSetGapR TY public MO ajalign LB core XX DE Defines alignment gap penalties XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r gappen float PD Gap penalty PX PN [3] PA r extpen float PD Gap extension penalty PX RT void RD RX // void ajAlignSetGapR(AjPAlign thys, float gappen, float extpen) { AjPStr tmpstr = NULL; ajint precision = 3; ajint i; ajFmtPrintS(&tmpstr, "%.*f", precision, gappen); for(i=1; iGapPen, tmpstr); ajFmtPrintS(&tmpstr, "%.*f", precision, extpen); for(i=1; iExtPen, tmpstr); ajStrDel(&tmpstr); return; } ID ajAlignSetScoreI TY public MO ajalign LB core XX DE Defines alignment score XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r score ajint PD score PX RT void RD RX // void ajAlignSetScoreI(AjPAlign thys, ajint score) { AjPStr tmpstr = NULL; AlignPData data = NULL; ajListPeekLast(thys->Data, (void**) &data); ajFmtPrintS(&tmpstr, "%d", score); ajStrAssignS(&data->Score, tmpstr); ajDebug("ajAlignSetScoreI: %d '%S' %d\n", score, data->Score, data->LenAli); ajStrDel(&tmpstr); return; } ID ajAlignSetScoreL TY public MO ajalign LB core XX DE Defines alignment score XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r score ajlong PD score PX RT void RD RX // void ajAlignSetScoreL(AjPAlign thys, ajlong score) { AjPStr tmpstr = NULL; AlignPData data = NULL; ajListPeekLast(thys->Data, (void**) &data); ajFmtPrintS(&tmpstr, "%Ld", score); ajStrAssignS(&data->Score, tmpstr); ajDebug("ajAlignSetScoreI: %Ld '%S' %d\n", score, data->Score, data->LenAli); ajStrDel(&tmpstr); return; } ID ajAlignSetScoreR TY public MO ajalign LB core XX DE Defines alignment score XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r score float PD score PX RT void RD RX // void ajAlignSetScoreR(AjPAlign thys, float score) { AjPStr tmpstr = NULL; ajint precision = 3; ajint i; AlignPData data = NULL; ajListPeekLast(thys->Data, (void**) &data); ajFmtPrintS(&tmpstr, "%.*f", precision, score); for(i=1; iScore, tmpstr); ajStrDel(&tmpstr); return; } ID ajAlignSetStats TY public MO ajalign LB core XX DE Sets standard properties for an alignment subheader. These are: DE Length, Identity, Gaps, Similarity, Score XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD Alignment number PX PN [3] PA r len ajint PD Alignment length PX PN [4] PA r ident ajint PD Number of identities PX PN [5] PA r sim ajint PD Number of similarities PX PN [6] PA r gaps ajint PD Number of gaps PX PN [7] PA r score const AjPStr PD Alignment score (as saved by PD ajAlignSetScoreI or ajAlignSetScoreR) PX RT void RD RX // void ajAlignSetStats(AjPAlign thys, ajint iali, ajint len, ajint ident, ajint sim, ajint gaps, const AjPStr score) { AlignPData* pdata = NULL; AlignPData data = NULL; ajint nali; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); if(iali < 0) data = pdata[nali-1]; else data = pdata[iali]; /* ajDebug("ajAlignSetStats iali:%d len:%d id:%d " "sim:%d gap:%d score:'%S'\n", iali, len, ident, sim, gaps, score); */ data->LenAli = len; if(len > 0) { if(ident >= 0) data->NumId = ident; else data->NumId = -1; if(sim >= 0) data->NumSim = sim; else data->NumSim = -1; if(gaps >= 0) data->NumGap = gaps; else data->NumGap = -1; } if(ajStrGetLen(score)) ajStrAssignS(&data->Score, score); AJFREE(pdata); return; } ID ajAlignSetSubStandard TY public MO ajalign LB core XX DE Sets standard subheader using the properties for an alignment. DE These are: DE Length, Identity, Gaps, Similarity, Score XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD Alignment number (or -1 for the latest) PX RT void RD RX // void ajAlignSetSubStandard(AjPAlign thys, ajint iali) { AjPStr tmphdr = NULL; AlignPData* pdata = NULL; AlignPData data = NULL; ajint nali; float pct; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); if(iali < 0) data = pdata[nali-1]; else data = pdata[iali]; ajFmtPrintAppS(&tmphdr, "Length: %d\n", data->LenAli); if(data->LenAli > 0) { if(data->NumId >= 0) { pct = (float)100. * (float) data->NumId / (float) data->LenAli; ajFmtPrintAppS(&tmphdr, "Identity: %5d/%d (%4.1f%%)\n", data->NumId, data->LenAli, pct); } if(data->NumSim >= 0) { pct = (float)100. * (float) data->NumSim / (float) data->LenAli; ajFmtPrintAppS(&tmphdr, "Similarity: %5d/%d (%4.1f%%)\n", data->NumSim, data->LenAli, pct); } if(data->NumGap >= 0) { pct = (float)100. * (float) data->NumGap / (float) data->LenAli; ajFmtPrintAppS(&tmphdr, "Gaps: %5d/%d (%4.1f%%)\n", data->NumGap, data->LenAli, pct); } } if(ajStrGetLen(data->Score)) ajFmtPrintAppS(&tmphdr, "Score: %S\n", data->Score); ajAlignSetSubHeaderPre(thys, tmphdr); ajStrDel(&tmphdr); AJFREE(pdata); return; } ID alignSeqs TY static MO ajalign LB core XX DE Returns the sequences for the nth alignment XX PN [1] PA r thys const AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD Alignment number PX RT const AjPSeq* RD Pointer to the internal sequence array RX // static const AjPSeq* alignSeqs(const AjPAlign thys, ajint iali) { AlignPData data = NULL; ajListPeekNumber(thys->Data, iali, (void**) &data); return data->Seq; } ID alignSeq TY static MO ajalign LB core XX DE Returns the nth sequence for an alignment XX PN [1] PA r thys const AjPAlign PD Alignment object PX PN [2] PA r iseq ajint PD Sequence number PX PN [3] PA r iali ajint PD Alignment number PX RT const AjPSeq RD Pointer to the internal sequence RX // static const AjPSeq alignSeq(const AjPAlign thys, ajint iseq, ajint iali) { AlignPData data = NULL; ajListPeekNumber(thys->Data, iali, (void **) &data); return data->Seq[iseq]; } ID alignSeqBegin TY static MO ajalign LB core XX DE Returns the start position for the nth sequence for an alignment. DE DE Reverse direction is tested and the reverse complement numbering is used. XX PN [1] PA r data const AlignPData PD Alignment data object PX PN [2] PA r iseq ajint PD Sequence number PX RT ajint RD Start position RX // static ajint alignSeqBegin(const AlignPData data, ajint iseq) { ajint ret = 0; if(data->Rev[iseq]) { ret = data->Len[iseq] - data->Offend[iseq] - data->Start[iseq] + 1; ajDebug(" alignSeqBegin %d rev:%B len:%d Offend:%d Start:%d ret:%d\n", iseq, data->Rev[iseq], data->Len[iseq], data->Offend[iseq], data->Start[iseq], ret); } else { ret = data->Offset[iseq] + data->Start[iseq]; ajDebug(" alignSeqBegin %d rev:%B Offset:%d Start:%d ret:%d\n", iseq, data->Rev[iseq], data->Offset[iseq], data->Start[iseq], ret); } return ret; } ID alignSeqEnd TY static MO ajalign LB core XX DE Returns the end position for the nth sequence for an alignment. DE DE Reverse direction is tested and the reverse complement numbering is used. XX PN [1] PA r data const AlignPData PD Alignment data object PX PN [2] PA r iseq ajint PD Sequence number PX RT ajint RD Start position RX // static ajint alignSeqEnd(const AlignPData data, ajint iseq) { ajint ret = 0; ajint iend; if(data->End[iseq]) iend = data->End[iseq]; else iend = data->Len[iseq]; if(data->Rev[iseq]) ret = data->Len[iseq] - data->Offend[iseq] - iend + 1; else ret = data->Offset[iseq] + iend; return ret; } ID alignSeqIncrement TY static MO ajalign LB core XX DE Returns the position increment for the nth sequence for an alignment. DE DE Reverse direction gives a value of -1 for counting down. DE DE Forward direction gives +1. XX PN [1] PA r data const AlignPData PD Alignment data object PX PN [2] PA r iseq ajint PD Sequence number PX RT ajint RD Increment for position counting RX // static ajint alignSeqIncrement(const AlignPData data, ajint iseq) { ajint ret = 0; if(data->Rev[iseq]) ret = -1; else ret = 1; return ret; } ID alignSeqGapBegin TY static MO ajalign LB core XX DE Counts the gaps at the start of the nth sequence for an alignment. DE DE Reverse direction is tested and the reverse complement numbering is used. XX PN [1] PA r data const AlignPData PD Alignment data object PX PN [2] PA r iseq ajint PD Sequence number PX RT ajint RD Start position RX // static ajint alignSeqGapBegin(const AlignPData data, ajint iseq) { ajint ret = 0; static char testchars[] = "-~.? "; /* all known gap characters */ const char* cp; ajint i; if(data->Rev[iseq]) ret = data->Offend[iseq]; else ret = data->Offset[iseq]; cp = ajSeqGetSeqC(data->Seq[iseq]); i = strspn(cp+data->Start[iseq]-1, testchars); return ret+i; } ID alignSeqGapEnd TY static MO ajalign LB core XX DE Counts the gaps at the end of the nth sequence for an alignment. DE DE Reverse direction is tested and the reverse complement numbering is used. XX PN [1] PA r data const AlignPData PD Alignment data object PX PN [2] PA r iseq ajint PD Sequence number PX RT ajint RD End position RX // static ajint alignSeqGapEnd(const AlignPData data, ajint iseq) { ajint ret = 0; static char testchars[] = "-~.? "; /* all known gap characters */ const char* cp; const char* cpstart; ajint i; if(data->Rev[iseq]) ret = data->Offset[iseq]; else ret = data->Offend[iseq]; cpstart = ajSeqGetSeqC(data->Seq[iseq]); cp = cpstart + data->End[iseq]; for(i=0; cp > cpstart; cp--) { if(!strchr(testchars, *cp)) return ret+i-1; i++; } return ret+data->End[iseq]; } ID alignSeqRev TY static MO ajalign LB core XX DE Returns the direction for the nth sequence for an alignment. XX PN [1] PA r data const AlignPData PD Alignment data object PX PN [2] PA r iseq ajint PD Sequence number PX RT AjBool RD ajTrue if sequence is reversed RX // static AjBool alignSeqRev(const AlignPData data, ajint iseq) { AjBool ret = ajFalse; if(data->Rev[iseq]) ret = ajTrue; else ret = ajFalse; return ret; } ID alignData TY static MO ajalign LB core XX DE Returns the nth data structure for an alignment XX PN [1] PA r thys const AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD Alignment number PX RT AlignPData RD Pointer to the internal alignment structure RX // static AlignPData alignData(const AjPAlign thys, ajint iali) { AlignPData data = NULL; ajListPeekNumber(thys->Data, iali, (void**) &data); return data; } ID alignLen TY static MO ajalign LB core XX DE Returns the length of the nth sequence for an alignment XX PN [1] PA r thys const AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD Alignment number PX RT ajint RD Length of the internal sequence RX // static ajint alignLen(const AjPAlign thys, ajint iali) { AlignPData data = NULL; ajListPeekNumber(thys->Data, iali, (void**) &data); return data->LenAli; } ID ajAlignSetType TY public MO ajalign LB core XX DE Sets the align type (if it is not set already) XX PN [1] PA u thys AjPAlign PD Alignment object PX RT void RD RX // void ajAlignSetType(AjPAlign thys) { const AjPSeq seq; ajint i; ajDebug("ajAlignSetType '%S'\n", thys->Type); if(ajStrGetLen(thys->Type)) return; if(!thys->Nseqs) return; for(i=0; i < thys->Nseqs; i++) { ajDebug("Calling alignSeq d 0\n", i); seq = alignSeq(thys, i, 0); if(ajStrGetLen(seq->Type)) { ajStrAssignS(&thys->Type, seq->Type); return; } } ajDebug("testing alignSeq 0 0\n", i); if(ajSeqIsNuc(alignSeq(thys, 0, 0))) ajStrAssignC(&thys->Type, "N"); else ajStrAssignC(&thys->Type, "P"); return; } ID ajAlignSetExternal TY public MO ajalign LB core XX DE Sets the align object to use external sequence references, which are DE to be copied pointers rather than clones of the whole sequence. DE DE Intended for alignments of large sequences where there is no need to DE keep many copies. An example is the EMBOSS application wordmatch. XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r external AjBool PD If true, do not make copies of sequence data PD and do not delete internal sequence data PX RT void RD RX // void ajAlignSetExternal(AjPAlign thys, AjBool external) { ajDebug("ajAlignSetExternal old:%B new:%B\n", thys->SeqExternal, external); thys->SeqExternal = external; return; } ID ajAlignSetRefSeqIndx TY public MO ajalign LB core XX DE Sets the index of the reference sequence. XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r refseq ajint PD index of the reference sequence PX RT void RD RX // void ajAlignSetRefSeqIndx(AjPAlign thys, ajint refseq) { thys->RefSeq = refseq; return; } ID ajAlignSetRange TY public MO ajalign LB core XX DE Sets the alignment range in each sequence, but only for a DE pairwise alignment XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r start1 ajint PD Start in sequence 1 PX PN [3] PA r end1 ajint PD End in sequence 1 PX PN [4] PA r len1 ajint PD Length of sequence 1 PX PN [5] PA r off1 ajint PD Offset of sequence 1 PX PN [6] PA r start2 ajint PD Start in sequence 2 PX PN [7] PA r end2 ajint PD End in sequence 2 PX PN [8] PA r len2 ajint PD Length of sequence 2 PX PN [9] PA r off2 ajint PD Offset of sequence 2 PX RT AjBool RD ajTrue on success. Failure also writes an error message. RX // AjBool ajAlignSetRange(AjPAlign thys, ajint start1, ajint end1, ajint len1, ajint off1, ajint start2, ajint end2, ajint len2, ajint off2) { AlignPData data = NULL; ajint nali; ajDebug("ajAlignSetRange %d..%d (%d) %d..%d (%d)\n", start1, end1, len1, start2, end2, len2); if(thys->Nseqs != 2) { ajErr("ajAlignSetRange requires alignment of 2 sequences only"); return ajFalse; } ajListPeekLast(thys->Data, (void**) &data); nali = (ajuint) ajListGetLength(thys->Data); ajDebug("nali:%d set range %d\n", nali, nali-1); data->Start[0] = start1; data->End[0] = end1; data->Len[0] = len1; data->Offset[0] = off1; data->Rev[0] = ajFalse; data->Start[1] = start2; data->End[1] = end2; data->Len[1] = len2; data->Offset[1] = off2; data->Rev[1] = ajFalse; if(thys->SeqExternal) { data->LenAli = (end1 - start1) + 1; if(data->LenAli < (end2 - start2 + 1)) data->LenAli = (end2 - start2) + 1; ajDebug("len: %d\n", data->LenAli); } return ajTrue; } ID ajAlignSetSubRange TY public MO ajalign LB core XX DE Sets the local alignment sub range in each sequence, but only for a DE pairwise alignment. DE DE This sets the SubOffset in addition to the Start and End values, DE for use where the alignment has a large sequence, but only part of DE it is to be reported. DE DE The usual example is where there are many matches in a long sequence, DE defined with SeqExternal so we use pointers to one original to avoid DE making multiple copies in memory while building the AjPAlign and AlignPData DE structure. DE DE Resets the alignment length to be the length of the longest subsequence XX PN [1] PA u thys AjPAlign PD Alignment object PX PN [2] PA r substart1 ajint PD Subsequence offset in sequence 1 PX PN [3] PA r start1 ajint PD Subsequence start in sequence 1 PX PN [4] PA r end1 ajint PD Subsequence end in sequence 1 PX PN [5] PA r rev1 AjBool PD ajTrue if sequence 1 is reversed PX PN [6] PA r len1 ajint PD Length of sequence 1 PX PN [7] PA r substart2 ajint PD Subsequence offset in sequence 2 PX PN [8] PA r start2 ajint PD Subsequence start in sequence 2 PX PN [9] PA r end2 ajint PD Subsequence end in sequence 2 PX PN [10] PA r rev2 AjBool PD ajTrue if sequence 2 is reversed PX PN [11] PA r len2 ajint PD Length of sequence 2 PX RT AjBool RD ajTrue on success. Failure also writes an error message. RX // AjBool ajAlignSetSubRange(AjPAlign thys, ajint substart1, ajint start1, ajint end1, AjBool rev1, ajint len1, ajint substart2, ajint start2, ajint end2, AjBool rev2, ajint len2) { AlignPData data = NULL; ajint nali; ajDebug("ajAlignSetSubRange %d(%d)..%d (%d) %d(%d)..%d (%d)\n", start1, substart1, end1, len1, start2, substart2, end2, len2); if(thys->Nseqs != 2) { ajErr("ajAlignSetSubRange requires alignment of 2 sequences only"); return ajFalse; } ajListPeekLast(thys->Data, (void**) &data); nali = (ajuint) ajListGetLength(thys->Data); ajDebug("nali:%d set range %d\n", nali, nali-1); data->SubOffset[0] = substart1; data->Start[0] = start1; data->End[0] = end1; data->Len[0] = len1; data->Offset[0] = substart1; data->Offend[0] = len1 - (substart1 + end1 - start1 + 1); data->Rev[0] = rev1; data->SubOffset[1] = substart2; data->Start[1] = start2; data->End[1] = end2; data->Len[1] = len2; data->Offset[1] = substart2; data->Offend[1] = len2 - (substart2 + end2 - start2 + 1); data->Rev[1] = rev2; data->LenAli = (end1 - start1) + 1; if(data->LenAli < (end2 - start2 + 1)) { data->LenAli = (end2 - start2) + 1; } ajDebug("len: %d\n", data->LenAli); return ajTrue; } ID alignSeqName TY static MO ajalign LB core XX DE Returns the sequence name or USA depending on the setting in the DE Alignment object (derived from the ACD and command line -ausa option) XX PN [1] PA r thys const AjPAlign PD Alignment object PX PN [2] PA r seq const AjPSeq PD Sequence object PX RT const AjPStr RD Sequence name for this alignment RX // static const AjPStr alignSeqName(const AjPAlign thys, const AjPSeq seq) { if(thys->Showusa) return ajSeqGetUsaS(seq); return ajSeqGetNameS(seq); } ID alignDataDel TY static MO ajalign LB core XX DE Deletes an alignment data structure XX PN [1] PA d pthys AlignPData* PD Alignment data structure PX PN [2] PA r external AjBool PD Sequence is a pointer to an external PD object, do not delete. PX RT void RD RX // static void alignDataDel(AlignPData* pthys, AjBool external) { AlignPData thys; ajint i; void *freeptr = NULL; thys = *pthys; AJFREE(thys->Start); AJFREE(thys->End); AJFREE(thys->Len); AJFREE(thys->Offset); AJFREE(thys->Offend); AJFREE(thys->SubOffset); AJFREE(thys->Rev); ajStrDel(&thys->Score); ajDebug("alignDataDel NSeqs: %d External: %B\n", thys->Nseqs, external); if(!external) for(i=0;iNseqs;++i) { ajDebug("alignDataDel seq[%d] %S %d\n", i, ajSeqGetNameS(thys->Seq[i]), ajSeqGetLen(thys->Seq[i])); ajSeqDel(&thys->RealSeq[i]); } AJFREE(thys->RealSeq); freeptr = (void *)thys->Seq; AJFREE(freeptr); AJFREE(*pthys); return; } ID alignDataNew TY static MO ajalign LB core XX DE Creates and initialises an alignment data object DE with a specified number of sequences XX PN [1] PA r nseqs ajint PD Number of sequences alignment data object will PD store PX PN [2] PA r external AjBool PD Sequence is a pointer to an external PD object, no need for an own copy. PX RT AlignPData RD Pointer to the new alignment data object RX // static AlignPData alignDataNew(ajint nseqs, AjBool external) { AlignPData data = NULL; AJNEW0(data); data->Nseqs = nseqs; AJCNEW0(data->Start, nseqs); AJCNEW0(data->End, nseqs); AJCNEW0(data->Len, nseqs); AJCNEW0(data->Offset, nseqs); AJCNEW0(data->Offend, nseqs); AJCNEW0(data->SubOffset, nseqs); AJCNEW0(data->Rev, nseqs); AJCNEW0(data->Seq, nseqs); if(!external) AJCNEW0(data->RealSeq, nseqs); return data; } ID alignDataSetSequence TY static MO ajalign LB core XX DE Sets specified sequence in the alignment data object DE DE Note: In pre EMBOSS-6.3 the external option is set only by wordmatch DE and seqmatchall, both producing exact multiple matches and calling DE ajAlignSetSubRange after calling ajAlignDefineSS which repeats the settings DE made in this function when called via ajAlignDefineSS. DE Since ajSeqCountGaps function is time consuming for long sequences, DE function was modified to return quickly when the external option is true. DE After release 6.3 this function call hierarchy should be revised. XX PN [1] PA u thys AlignPData PD Alignment data object PX PN [2] PA r seq const AjPSeq PD Input sequence, either a new copy is made PD or a direct reference is made depending on PD the external parameter PX PN [3] PA r iseq ajint PD Index of the sequence PX PN [4] PA r external AjBool PD Sequence is a pointer to an external PD object PX RT void RD RX // static void alignDataSetSequence(AlignPData thys, const AjPSeq seq, ajint iseq, AjBool external) { if(external) { thys->Seq[iseq] = seq; return; } thys->Start[iseq] = ajSeqGetBegin(seq); thys->End[iseq] = ajSeqGetEnd(seq); thys->Len[iseq] = ajSeqGetLen(seq) + ajSeqGetOffset(seq) + ajSeqGetOffend(seq) - ajSeqCountGaps(seq); thys->Offset[iseq] = ajSeqGetOffset(seq); thys->Offend[iseq] = ajSeqGetOffend(seq); thys->SubOffset[iseq] = 0; thys->Rev[iseq] = ajSeqIsReversed(seq); thys->RealSeq[iseq] = ajSeqNewSeq(seq); ajSeqGapStandard(thys->RealSeq[iseq], '-'); thys->Seq[iseq] = thys->RealSeq[iseq]; return; } ID alignDiff TY static MO ajalign LB core XX DE Blank out identities between two strings XX PN [1] PA w pmark AjPStr* PD Mark string with spaces for identities PX PN [2] PA r seq const AjPStr PD String (sequence) to compare PX PN [3] PA r idchar char PD Character for identities PX RT void RD RX // static void alignDiff(AjPStr* pmark, const AjPStr seq, char idchar) { ajuint i; ajuint ilen; char c; char d; ilen = ajStrGetLen(seq); ajStrGetuniqueStr(pmark); if(ajStrGetLen(*pmark) < ilen) ilen = ajStrGetLen(*pmark); for(i=0; i < ilen; i++) { c = ajStrGetCharPos(*pmark, i); if(c == ' ') continue; if(c == '-') continue; d = ajStrGetCharPos(seq, i); if(d == ' ') continue; if(d == '-') continue; if(toupper((int)c) == toupper((int)d)) ajStrPasteCountK(pmark, i, idchar, 1); } return; } ID alignSame TY static MO ajalign LB core XX DE Blank out differences between two strings XX PN [1] PA w pmark AjPStr* PD Mark string with spaces for differences PX PN [2] PA r seq const AjPStr PD String (sequence) to compare PX PN [3] PA r diffchar char PD Character for differences PX RT void RD RX // static void alignSame(AjPStr* pmark, const AjPStr seq, char diffchar) { ajuint i; ajuint ilen; char c; char d; ilen = ajStrGetLen(seq); ajStrGetuniqueStr(pmark); if(ajStrGetLen(*pmark) < ilen) ilen = ajStrGetLen(*pmark); for(i=0; i < ilen; i++) { c = ajStrGetCharPos(*pmark, i); if(c == ' ') continue; d = ajStrGetCharPos(seq, i); if(toupper((int)c) == toupper((int)d)) continue; ajStrPasteCountK(pmark, i, diffchar, 1); } return; } ID alignSim TY static MO ajalign LB core XX DE Convert upper case (identical) positions to an identity character, DE and lower case (similar) positions to a similarity character XX PN [1] PA w pmark AjPStr* PD Mark string with spaces for differences PX PN [2] PA r idch const char PD Identity character PX PN [3] PA r simch const char PD Similarity character PX PN [4] PA r misch const char PD Mismatch character PX PN [5] PA r gapch const char PD Gap character PX RT void RD RX // static void alignSim(AjPStr* pmark, const char idch, const char simch, const char misch, const char gapch) { ajint i; ajint ilen; char c; /*ajDebug("alignSim '%S'\n", *pmark);*/ ajStrGetuniqueStr(pmark); ilen = ajStrGetLen(*pmark); for(i=0; i < ilen; i++) { c = ajStrGetCharPos(*pmark, i); if(tolower((int)c) == '#') ajStrPasteCountK(pmark, i, misch, 1); else if(isupper((int)c)) ajStrPasteCountK(pmark, i, idch, 1); else if(islower((int)c)) ajStrPasteCountK(pmark, i, simch, 1); else ajStrPasteCountK(pmark, i,gapch, 1); } /*ajDebug(" result '%S'\n", *pmark);*/ return; } ID alignConsStats TY static MO ajalign LB core XX DE Calculates alignment statistics (and a consensus). XX PN [1] PA u thys AjPAlign PD Alignment object. Matrix will be defined PD if not already set. PX PN [2] PA r iali ajint PD alignment number PX PN [3] PA w cons AjPStr* PD the created consensus sequence PX PN [4] PA w retident ajint* PD number of residues identical in all sequences PX PN [5] PA w retsim ajint* PD number of residues similar in all sequences PX PN [6] PA w retgap ajint* PD number of residues with a gap in 1 sequence PX PN [7] PA w retlen ajint* PD length of the alignment PX RT void RD RX // static void alignConsStats(AjPAlign thys, ajint iali, AjPStr *cons, ajint* retident, ajint* retsim, ajint* retgap, ajint* retlen) { ajint imat; /* iterate over identical and matching arrays */ ajint iseq; /* iterate over sequences (outer loop) */ ajint jseq; /* iterate over sequences (inner loop) */ ajint **matrix = NULL; float **fmatrix = NULL; ajint m1 = 0; ajint m2 = 0; ajint matsize; ajint matchingmaxindex; ajint identicalmaxindex; ajint nseqs; ajint mlen; float max; float contri = 0; float contrj = 0; AjPSeqCvt cvt = 0; AjPFloat posScore = NULL; /* cumulative similarity scores by sequence */ /* for matching all other sequences */ float *identical; /* cum. weight for each valid character */ float *matching; /* cum. weight for matching this character */ ajint highindex; /* position of highest score in posScore */ ajint kkpos; /* alignment position loop variable */ ajint kipos; /* alignment position kkpos + iseq start */ ajint kjpos; /* alignment position kkpos + jseq start */ ajint khpos; /* alignment position in highindex */ float himatch = 0.0; /* highest match score (often used) */ const char **seqcharptr; char res; char nocon; char gapch; float fplural; float fplurality = 51.0; float ident; AjBool isident; AjBool issim; AjBool isgap; const AjPSeq* seqs; ajint numres; /* number of residues (not spaces) */ AlignPData data = NULL; void *freeptr; data = alignData(thys, iali); if(!thys->IMatrix && !thys->FMatrix) { if(ajSeqIsNuc(alignSeq(thys, 0, iali))) ajStrAssignC(&thys->Matrix, "EDNAFULL"); else ajStrAssignC(&thys->Matrix, "EBLOSUM62"); thys->IMatrix = ajMatrixNewFile(thys->Matrix); } *retident=0; *retsim=0; *retgap=0; seqs = alignSeqs(thys, iali); nseqs = thys->Nseqs; mlen = alignLen(thys, iali); fplural = alignTotweight(thys, 0) * fplurality / (float)100.; ident = alignTotweight(thys, 0); ajDebug("alignConsStats ali:%d mlen:%d\n", iali, mlen); /* ajDebug("fplural:%.1f ident:%.1f mlen: %d\n", fplural, ident, mlen); */ if(thys->IMatrix) { matrix = ajMatrixGetMatrix(thys->IMatrix); cvt = ajMatrixGetCvt(thys->IMatrix); /* return conversion table */ matsize = ajMatrixGetSize(thys->IMatrix); } else { fmatrix = ajMatrixfGetMatrix(thys->FMatrix); cvt = ajMatrixfGetCvt(thys->FMatrix); /* return conversion table */ matsize = ajMatrixfGetSize(thys->FMatrix); } AJCNEW(seqcharptr,nseqs); AJCNEW(identical,matsize); AJCNEW(matching,matsize); posScore = ajFloatNew(); gapch = '-'; nocon = '#'; for(iseq=0;iseqSubOffset[iseq]; m1 = ajSeqcvtGetCodeK(cvt,seqcharptr[iseq][kipos]); if(m1 < 0) { ajUser("Bad character for matrix iseq:%d kipos:%d %x\n", iseq, kipos, (int) seqcharptr[iseq][kipos]); m1 = 0; } if(m1) identical[m1] += seqs[iseq]->Weight; for(jseq=iseq+1;jseqSubOffset[jseq]; m2 = ajSeqcvtGetCodeK(cvt,seqcharptr[jseq][kjpos]); if(m2 < 0) { ajDebug("Bad character for matrix jseq:%d kjpos:%d %x\n", jseq, kjpos, (int) seqcharptr[jseq][kjpos]); m2 = 0; } if(m1 && m2) { if(matrix) { contri = (float)matrix[m1][m2]*seqs[jseq]->Weight +ajFloatGet(posScore,iseq); contrj = (float)matrix[m1][m2]*seqs[iseq]->Weight +ajFloatGet(posScore,jseq); } else { contri = fmatrix[m1][m2]*seqs[jseq]->Weight +ajFloatGet(posScore,iseq); contrj = fmatrix[m1][m2]*seqs[iseq]->Weight +ajFloatGet(posScore,jseq); } ajFloatPut(&posScore,iseq,contri); ajFloatPut(&posScore,jseq,contrj); } } } /* ** highindex is the highest scoring position (seq no.) in posScore ** for 2 sequences this appears to be usually 0 */ highindex = -1; max = -FLT_MAX; numres = 0; for(iseq=0;iseqSubOffset[iseq]; if(seqcharptr[iseq][kipos] != ' ' && seqcharptr[iseq][kipos] != '-') numres++; if(ajFloatGet(posScore,iseq) > max) { highindex = iseq; max = ajFloatGet(posScore,iseq); } } /* highindex is now set */ /* ** find +ve matches in the column ** m1 is non-zero for a valid character in iseq ** m2 is non-zero for a valid character in jseq */ for(iseq=0;iseqSubOffset[iseq]; m1 = ajSeqcvtGetCodeK(cvt, seqcharptr[iseq][kipos]); if(m1 < 0) { ajDebug("Bad character for matrix iseq:%d kipos:%d %x\n", iseq, kipos, (int) seqcharptr[iseq][kipos]); m1 = 0; } if(E_FPZERO(matching[m1],U_FEPS)) { /* first time we have met this character */ for(jseq=0;jseqSubOffset[jseq]; m2 = ajSeqcvtGetCodeK(cvt, seqcharptr[jseq][kjpos]); if(m2 < 0) { ajDebug("Bad character for matrix jseq:%d kjpos:%d " "%x\n", jseq, kjpos, (int) seqcharptr[jseq][kjpos]); m2 = 0; } if(matrix) { /* 'matching' if positive */ if(m1 && m2 && matrix[m1][m2] > 0) matching[m1] += seqs[jseq]->Weight; } else if(m1 && m2 && fmatrix[m1][m2] > 0.0) matching[m1] += seqs[jseq]->Weight; /* if( iseq != jseq) /# skip the sequence we are on #/ { m2 = ajSeqcvtGetCodeK(cvt, seqcharptr[jseq][kjpos]); if(matrix) { if(m1 && m2 && matrix[m1][m2] > 0) /# 'matching' if positive #/ { matching[m1] += seqs[jseq]->Weight; } } else { if(m1 && m2 && fmatrix[m1][m2] > 0.0) { matching[m1] += seqs[jseq]->Weight; } } } */ } } } matchingmaxindex = 0; /* get max matching and identical */ identicalmaxindex = 0; for(iseq=0;iseqSubOffset[iseq]; m1 = ajSeqcvtGetCodeK(cvt,seqcharptr[iseq][kipos]); if(identical[m1] > identical[identicalmaxindex]) identicalmaxindex= m1; } for(iseq=0;iseqSubOffset[iseq]; m1 = ajSeqcvtGetCodeK(cvt,seqcharptr[iseq][kipos]); if(matching[m1] > matching[matchingmaxindex]) matchingmaxindex= m1; else if(E_FPEQ(matching[m1],matching[matchingmaxindex],U_FEPS)) { if(identical[m1] > identical[matchingmaxindex]) matchingmaxindex= m1; } if(seqcharptr[iseq][kipos] == '-' || seqcharptr[iseq][kipos] == ' ') isgap=ajTrue; } /* ajDebug("index[%d] ident:%d matching:%d high:%d\n", kpos, identicalmaxindex, matchingmaxindex, highindex); */ khpos = kkpos + data->SubOffset[highindex]; himatch = matching[ajSeqcvtGetCodeK(cvt,seqcharptr[highindex][khpos])]; if(thys->IMatrix) { /* debugstr1 = ajMatrixGetLabelNum(thys->IMatrix, identicalmaxindex-1); debugstr2 = ajMatrixGetLabelNum(thys->IMatrix, matchingmaxindex-1); */ /*ajDebug("index[%d] ident:%d '%S' %.1f matching:%d '%S' %.1f %.1f " "high:%d '%c' %.1f\n", kkpos, identicalmaxindex, debugstr1, identical[identicalmaxindex], matchingmaxindex, debugstr2, matching[matchingmaxindex], himatch, highindex, seqcharptr[highindex][khpos], seqs[highindex]->Weight); */ } else { /*debugstr1 = ajMatrixfGetLabelNum(thys->FMatrix, identicalmaxindex-1); debugstr2 = ajMatrixfGetLabelNum(thys->FMatrix, matchingmaxindex-1);*/ /* ajDebug("index[%d] ident:%d '%S' %.1f matching:%d '%S' %.1f " "%.1f " "high:%d '%c' %.1f\n", kkpos, identicalmaxindex, debugstr1, identical[identicalmaxindex], matchingmaxindex, debugstr2, matching[matchingmaxindex], himatch, highindex, seqcharptr[highindex][khpos], seqs[highindex]->Weight); */ } if(identical[identicalmaxindex] >= ident) isident=ajTrue; if(matching[matchingmaxindex] >= fplural) issim=ajTrue; /* plurality check */ if(himatch >= fplural) if(seqcharptr[highindex][khpos] != '-') res = toupper((int)seqcharptr[highindex][khpos]); if(E_FPEQ(himatch,seqs[highindex]->Weight,U_FEPS)) { if(numres > 1) res = nocon; else res = gapch; } if(issim && ! isident) res = tolower((int)res); ajStrAppendK(cons,res); if(isident) ++*retident; if(issim) ++*retsim; if(isgap) ++*retgap; /* ajDebug("id:%b sim:%b gap:%b res:%c '", isident, issim, isgap, res); */ for(iseq=0; iseqSubOffset[iseq]; /* ajDebug("%c", seqcharptr[iseq][kipos]); */ } /* ajDebug("\n"); */ } *retlen = alignLen(thys, iali); /* ajDebug("ret ident:%d sim:%d gap:%d len:%d\n", *retident, *retsim, *retgap, *retlen); */ freeptr = (void *) seqcharptr; AJFREE(freeptr); AJFREE(matching); AJFREE(identical); ajFloatDel(&posScore); return; } ID alignTotweight TY static MO ajalign LB core XX DE Returns the total weight for all sequences in an alignment. XX PN [1] PA r thys const AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD Alignment number PX RT float RD Total weight for all sequences RX // static float alignTotweight(const AjPAlign thys, ajint iali) { ajint i; const AjPSeq seq = NULL; float ret = 0.0; for(i=0; i < thys->Nseqs; i++) { seq = alignSeq(thys, i, iali); ret += seq->Weight; } return ret; } ID ajAlignTraceT TY public MO ajalign LB core XX DE Reports an AjPAlign object to debug output XX PN [1] PA r thys const AjPAlign PD alignment object PX PN [2] PA r title const char* PD Trace report title PX RT void RD RX // void ajAlignTraceT(const AjPAlign thys, const char* title) { ajDebug("%s\n",title); ajAlignTrace(thys); return; } ID ajAlignTrace TY public MO ajalign LB core XX DE Reports an AjPAlign object to debug output XX PN [1] PA r thys const AjPAlign PD alignment object PX RT void RD RX // void ajAlignTrace(const AjPAlign thys) { ajDebug("AjAlignTrace\n"); ajDebug("============\n"); ajDebug("Type: '%S'\n", thys->Type); ajDebug("Formatstr: '%S'\n", thys->Formatstr); ajDebug("Format: %d\n", thys->Format); ajDebug("File: '%F'\n", thys->File); ajDebug("Header: '%S'\n", thys->Header); ajDebug("SubHeader: '%S'\n", thys->SubHeader); ajDebug("Tail: '%S'\n", thys->Tail); ajDebug("SubTail: '%S'\n", thys->SubTail); ajDebug("Showusa: %B\n", thys->Showusa); ajDebug("Multi: %B\n", thys->Multi); ajDebug("Global: %B\n", thys->Global); alignTraceData(thys); ajDebug("Nseqs: %d\n", thys->Nseqs); ajDebug("WidthNmin: %d\n", thys->Nmin); ajDebug("Nmax: %d\n", thys->Nmax); ajDebug("Width: %d\n", thys->Width); ajDebug("Count: %d\n", thys->Count); ajDebug("IMatrix: %x\n", thys->IMatrix); ajDebug("FMatrix: %x\n", thys->FMatrix); ajDebug("Matrix: '%S'\n", thys->Matrix); ajDebug("GapPen: '%S'\n", thys->GapPen); ajDebug("ExtPen: '%S'\n", thys->ExtPen); ajDebug("SeqOnly: %B\n", thys->SeqOnly); ajDebug("SeqExternal: %B\n", thys->SeqExternal); return; } ID alignTraceData TY static MO ajalign LB core XX DE Report alignment internal list data to debug output XX PN [1] PA r thys const AjPAlign PD Alignment object PX RT void RD RX // static void alignTraceData(const AjPAlign thys) { AlignPData* pdata = NULL; AlignPData data = NULL; ajint nali; ajint iali; ajint i; ajint nseq; AjPStr tmpstr = NULL; nseq = thys->Nseqs; nali = (ajuint) ajListToarray(thys->Data, (void***) &pdata); ajDebug("Data list length: %d\n", nali); if(!nali) return; for(iali=0; ialiLenAli); ajDebug("%d NumId: %d\n", iali, data->NumId); ajDebug("%d NumSim: %d\n", iali, data->NumSim); ajDebug("%d NumGap: %d\n", iali, data->NumGap); ajDebug("%d Score: '%S'\n", iali, data->Score); ajDebug("%d Start: {", iali); for(i=0; i < nseq; i++) ajDebug(" %d", data->Start[i]); ajDebug(" }\n"); ajDebug("%d End: {", iali); for(i=0; i < nseq; i++) ajDebug(" %d", data->End[i]); ajDebug(" }\n"); ajDebug("%d Len: {", iali); for(i=0; i < nseq; i++) ajDebug(" %d", data->Len[i]); ajDebug(" }\n"); ajDebug("%d Offset: {", iali); for(i=0; i < nseq; i++) ajDebug(" %d", data->Offset[i]); ajDebug(" }\n"); ajDebug("%d SubOffset: {", iali); for(i=0; i < nseq; i++) ajDebug(" %d", data->SubOffset[i]); ajDebug(" }\n"); ajDebug("%d Rev: {", iali); for(i=0; i < nseq; i++) ajDebug(" %b", data->Rev[i]); ajDebug(" }\n"); ajDebug("%d Seq: {\n", iali); for(i=0; i < nseq; i++) if(ajSeqGetLen(data->Seq[i]) > 40) { ajStrAssignSubS(&tmpstr, ajSeqGetSeqS(data->Seq[i]), -20, -1); ajDebug("%6d [%d] '%20.20S...%20S'\n", ajSeqGetLen(data->Seq[i]), i, ajSeqGetSeqS(data->Seq[i]), tmpstr); } else ajDebug(" %d '%S'\n", i, ajSeqGetSeqS(data->Seq[i])); ajDebug(" }\n"); } AJFREE(pdata); ajStrDel(&tmpstr); return; } ID ajAlignPrintFormat TY public MO ajalign LB core XX DE Reports the internal data structures XX PN [1] PA u outf AjPFile PD Output file PX PN [2] PA r full AjBool PD Full report (usually ajFalse) PX RT void RD RX // void ajAlignPrintFormat(AjPFile outf, AjBool full) { ajint i = 0; ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "# Alignment output formats\n"); ajFmtPrintF(outf, "# Name Format name (or alias)\n"); ajFmtPrintF(outf, "# Minseq Minimum number of sequences\n"); ajFmtPrintF(outf, "# Maxseq Minimum number of sequences\n"); ajFmtPrintF(outf, "# Nuc Valid for nucleotide sequences\n"); ajFmtPrintF(outf, "# Pro Valid for protein sequences\n"); ajFmtPrintF(outf, "# Header Include standard header/footer blocks\n"); ajFmtPrintF(outf, "# Desc Format description\n"); ajFmtPrintF(outf, "# Name Alias Nuc Nuc Pro Minseq Maxseq " "Description\n"); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "AFormat {\n"); for(i=0; alignFormat[i].Name; i++) { if(full || !alignFormat[i].Alias) ajFmtPrintF(outf, " %-12s %5B %3B %3B %3B %6d %6d \"%s\"\n", alignFormat[i].Name, alignFormat[i].Alias, alignFormat[i].Nucleotide, alignFormat[i].Protein, alignFormat[i].Showheader, alignFormat[i].Minseq, alignFormat[i].Maxseq, alignFormat[i].Desc); } ajFmtPrintF(outf, "}\n\n"); return; } ID ajAlignPrintbookFormat TY public MO ajalign LB core XX DE Reports the alignment format internals as Docbook text XX PN [1] PA u outf AjPFile PD Output file PX RT void RD RX // void ajAlignPrintbookFormat(AjPFile outf) { ajint i = 0; ajint j = 0; AjPStr namestr = NULL; AjPList fmtlist; AjPStr* names; fmtlist = ajListstrNew(); ajFmtPrintF(outf, "The supported alignment formats are summarised " "in the table below. The columns are as follows: " "Output format (format name), " "Nuc (\"true\" indicates nucleotide " "sequence data may be represented), " "Pro (\"true\" indicates protein " "sequence data may be represented, " "Header (whether the standard EMBOSS " "alignment header is included), " "Minseq " "(minimum sequences in alignment), " "Maxseq " "(maximum sequences in alignment) and " "Description (short description of " "the format). \n\n"); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n"); for(i=1; alignFormat[i].Name; i++) { if(!alignFormat[i].Alias) { namestr = ajStrNewC(alignFormat[i].Name); ajListPush(fmtlist, namestr); namestr = NULL; } } ajListSort(fmtlist, &ajStrVcmp); ajListstrToarray(fmtlist, &names); for(i=0; names[i]; i++) { for(j=0; alignFormat[j].Name; j++) { if(ajStrMatchC(names[i],alignFormat[j].Name)) { ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, " \n", alignFormat[j].Name); ajFmtPrintF(outf, " \n", alignFormat[j].Nucleotide); ajFmtPrintF(outf, " \n", alignFormat[j].Protein); ajFmtPrintF(outf, " \n", alignFormat[j].Showheader); ajFmtPrintF(outf, " \n", alignFormat[j].Minseq); ajFmtPrintF(outf, " \n", alignFormat[j].Maxseq); ajFmtPrintF(outf, " \n", alignFormat[j].Desc); ajFmtPrintF(outf, " \n"); } } } ajFmtPrintF(outf, " \n"); ajFmtPrintF(outf, "
Alignment formats
Output FormatNucProHeaderMinseqMaxseqDescription
%s%B%B%B%d%d%s
\n"); ajStrDel(&namestr); names = NULL; ajListstrFreeData(&fmtlist); return; } ID ajAlignPrinthtmlFormat TY public MO ajalign LB core XX DE Reports the internal data structures XX PN [1] PA u outf AjPFile PD Output file PX RT void RD RX // void ajAlignPrinthtmlFormat(AjPFile outf) { ajint i = 0; ajFmtPrintF(outf, ""); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "# alignment output formats\n"); ajFmtPrintF(outf, "# Name Format name (or alias)\n"); ajFmtPrintF(outf, "# Minseq Minimum number of sequences\n"); ajFmtPrintF(outf, "# Maxseq Minimum number of sequences\n"); ajFmtPrintF(outf, "# Nuc Valid for nucleotide sequences\n"); ajFmtPrintF(outf, "# Pro Valid for protein sequences\n"); ajFmtPrintF(outf, "# Header Include standard header/footer blocks\n"); ajFmtPrintF(outf, "# Desc Format description\n"); ajFmtPrintF(outf, "# Name Alias Nuc Nuc Pro Minseq Maxseq " "Description\n"); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "AFormat {\n"); for(i=0; alignFormat[i].Name; i++) { if(!alignFormat[i].Alias) ajFmtPrintF(outf, "" "" "\n", alignFormat[i].Name, alignFormat[i].Alias, alignFormat[i].Nucleotide, alignFormat[i].Protein, alignFormat[i].Showheader, alignFormat[i].Minseq, alignFormat[i].Maxseq, alignFormat[i].Desc); } ajFmtPrintF(outf, "}\n\n"); return; } ID ajAlignPrintwikiFormat TY public MO ajalign LB core XX DE Reports the alignment format internals as wikitext XX PN [1] PA u outf AjPFile PD Output file PX RT void RD RX // void ajAlignPrintwikiFormat(AjPFile outf) { ajint i = 0; ajint j = 0; AjPStr namestr = NULL; ajFmtPrintF(outf, "{| class=\"wikitable sortable\" border=\"2\"\n"); ajFmtPrintF(outf, "|-\n"); ajFmtPrintF(outf, "!Format!!Nuc!!Pro!!Header!!Min||Max!!" "class=\"unsortable\"|Description\n"); for(i=1; alignFormat[i].Name; i++) { if(!alignFormat[i].Alias) { ajFmtPrintF(outf, "|-\n"); ajStrAssignC(&namestr, alignFormat[i].Name); for(j=i+1; alignFormat[j].Name; j++) { if(alignFormat[j].Write == alignFormat[i].Write) { ajFmtPrintAppS(&namestr, "
%s", alignFormat[j].Name); if(!alignFormat[j].Alias) { ajWarn("Align output format '%s' same as '%s' " "but not alias", alignFormat[j].Name, alignFormat[i].Name); } } } ajFmtPrintF(outf, "|%S||%B||%B||%B||%d||%d||%s\n", namestr, alignFormat[i].Nucleotide, alignFormat[i].Protein, alignFormat[i].Showheader, alignFormat[i].Minseq, alignFormat[i].Maxseq, alignFormat[i].Desc); } } ajFmtPrintF(outf, "|}\n"); ajStrDel(&namestr); return; } ID alignConsSet TY static MO ajalign LB core XX DE Sets consensus to be a copy of a numbered sequence XX PN [1] PA r thys const AjPAlign PD Alignment object PX PN [2] PA r iali ajint PD alignment number PX PN [3] PA r numseq ajint PD Sequence number to use as the consensus PX PN [4] PA w cons AjPStr* PD the created consensus sequence PX RT AjBool RD True on success RX // static AjBool alignConsSet(const AjPAlign thys, ajint iali, ajint numseq, AjPStr *cons) { ajint nseqs; ajint mlen; ajint kkpos; /* alignment position loop variable */ const char *seqcharptr; char gapch; AlignPData data = NULL; const AjPSeq* seqs; const AjPSeq seq; data = alignData(thys, iali); seqs = alignSeqs(thys, iali); nseqs = thys->Nseqs; mlen = data->LenAli; ajDebug("alignConsSet iali:%d numseq:%d nseqs:%d mlen:%d\n", iali, numseq, nseqs, mlen); gapch = '-'; seq = seqs[numseq]; seqcharptr = ajSeqGetSeqC(seq); ajStrAssignClear(cons); /* For each position in the alignment, calculate consensus character */ for(kkpos=0; kkposSubOffset[0]; kkpos++) ajStrAppendK(cons, gapch); for(kkpos=0; kkpos< mlen; kkpos++) ajStrAppendK(cons,seqcharptr[kkpos+data->SubOffset[numseq]]); /* ajDebug("ret ident:%d sim:%d gap:%d len:%d\n", *retident, *retsim, *retgap, *retlen); */ return ajTrue; } ID ajAlignConsAmbig TY public MO ajalign LB core XX DE Calculates alignment consensus of ambiguity characters from a sequence set. XX PN [1] PA r thys const AjPSeqset PD Sequence set. PX PN [2] PA w cons AjPStr* PD the created consensus sequence PX RT AjBool RD ajTrue on success RX // AjBool ajAlignConsAmbig(const AjPSeqset thys, AjPStr *cons) { if(ajSeqsetIsNuc(thys)) return ajAlignConsAmbigNuc(thys, cons); return ajAlignConsAmbigProt(thys, cons); } ID ajAlignConsAmbigNuc TY public MO ajalign LB core XX DE Calculates alignment consensus of ambiguity characters from a sequence set. XX PN [1] PA r thys const AjPSeqset PD Sequence set. PX PN [2] PA w cons AjPStr* PD the created consensus sequence PX RT AjBool RD ajTrue on success RX // AjBool ajAlignConsAmbigNuc(const AjPSeqset thys, AjPStr *cons) { ajint iseq; /* iterate over sequences (outer loop) */ ajint nseqs; ajint mlen; AjBool isgap; ajint kipos; /* alignment position */ const char **seqcharptr; char res; ajuint binres; void *freeptr = NULL; nseqs = thys->Size; mlen = thys->Len; AJCNEW(seqcharptr,nseqs); /* ajDebug("fplural:%.2f ident:%.1f mlen: %d\n", fplural, ident, mlen); */ for(iseq=0;iseqSize; mlen = thys->Len; AJCNEW(seqcharptr,nseqs); /* ajDebug("fplural:%.2f ident:%.1f mlen: %d\n", fplural, ident, mlen); */ for(iseq=0;iseqSize; mlen = thys->Len; fplural = ajSeqsetGetTotweight(thys) * fplurality / (float)100.; ident = ajSeqsetGetTotweight(thys); /* ajDebug("fplural:%.2f ident:%.1f mlen: %d\n", fplural, ident, mlen); */ matrix = ajMatrixGetMatrix(imatrix); cvt = ajMatrixGetCvt(imatrix); /* return conversion table */ matsize = ajMatrixGetSize(imatrix); AJCNEW(seqs,nseqs); AJCNEW(seqcharptr,nseqs); AJCNEW(identical,matsize); AJCNEW(matching,matsize); posScore = ajFloatNew(); gapch = '-'; nocon = 'x'; for(iseq=0;iseqWeight; for(jseq=iseq+1;jseqWeight +ajFloatGet(posScore,iseq); contrj = (float)matrix[m1][m2]*seqs[iseq]->Weight +ajFloatGet(posScore,jseq); } else { contri = fmatrix[m1][m2]*seqs[jseq]->Weight +ajFloatGet(posScore,iseq); contrj = fmatrix[m1][m2]*seqs[iseq]->Weight +ajFloatGet(posScore,jseq); } ajFloatPut(&posScore,iseq,contri); ajFloatPut(&posScore,jseq,contrj); } } } /* ** highindex is the highest scoring position (seq no.) in posScore ** for 2 sequences this appears to be usually 0 */ highindex = -1; max = -FLT_MAX; numres = 0; for(iseq=0;iseq max) { highindex = iseq; max = ajFloatGet(posScore,iseq); } } /* highindex is now set */ /* ** find +ve matches in the column ** m1 is non-zero for a valid character in iseq ** m2 is non-zero for a valid character in jseq */ for(iseq=0;iseq 0) { /* 'matching' if positive */ matching[m1] += seqs[jseq]->Weight; } } else { if(m1 && m2 && fmatrix[m1][m2] > 0.0) { matching[m1] += seqs[jseq]->Weight; } } } } } matchingmaxindex = 0; /* get max matching and identical */ identicalmaxindex = 0; for(iseq=0;iseq identical[identicalmaxindex]) identicalmaxindex= m1; } for(iseq=0;iseq matching[matchingmaxindex]) { matchingmaxindex= m1; } else if(E_FPEQ(matching[m1],matching[matchingmaxindex],U_FEPS)) { if(identical[m1] > identical[matchingmaxindex]) matchingmaxindex= m1; } if(seqcharptr[iseq][kipos] == '-' || seqcharptr[iseq][kipos] == ' ') isgap=ajTrue; } khpos = kkpos; himatch = matching[ajSeqcvtGetCodeK(cvt,seqcharptr[highindex][khpos])]; if(identical[identicalmaxindex] >= ident) isident=ajTrue; if(matching[matchingmaxindex] >= fplural) issim=ajTrue; /* plurality check */ res = gapch; if(himatch >= fplural) if(seqcharptr[highindex][khpos] != '-') res = toupper((int)seqcharptr[highindex][khpos]); if(nseqs > 1 && E_FPEQ(himatch,seqs[highindex]->Weight,U_FEPS)) { if(numres > 1) res = nocon; else res = gapch; } if(issim && ! isident) res = tolower((int)res); ajStrAppendK(cons,res); if(isident) ++*retident; if(issim) ++*retsim; if(isgap) ++*retgap; /* ajDebug("id:%b sim:%b gap:%b res:%c '", isident, issim, isgap, res); */ for(iseq=0; iseq0) ajFmtPrintAppS(cigar, "%dH",qoffend); else if(qoffset>0) ajFmtPrintAppS(cigar, "%dH",qoffset); for(; qstart0) { ajFmtPrintAppS(cigar, "%uM",m); m=0; } if(i>0) { ajFmtPrintAppS(cigar, "%uI",d); i=0; } } else if(strchr(gapchars,refseqc[rstart])) { i++; if(m>0) { ajFmtPrintAppS(cigar, "%uM",m); m=0; } if(d>0) { ajFmtPrintAppS(cigar, "%uD",i); d=0; } ajStrAppendK(qseq,qryseqc[qstart]); } else /* match */ { m++; ajStrAppendK(qseq,qryseqc[qstart]); if(toupper((int)qryseqc[qstart])!=toupper((int)refseqc[rstart])) nmismatches ++; if(d>0) { ajFmtPrintAppS(cigar, "%uD",d); d=0; } if(i>0) { ajFmtPrintAppS(cigar, "%uI",i); i=0; } } } if(m>0) ajFmtPrintAppS(cigar, "%uM",m); else if(d>0) ajFmtPrintAppS(cigar, "%uD",d); else if(i>0) ajFmtPrintAppS(cigar, "%uI",i); if(ajSeqIsReversed(qryseq)&&qend>qseqlen) ajFmtPrintAppS(cigar, "%dH",qseqlen-qend); else if(qendPtr = AJALLOC0(RESERVED_SIZE*sizeof(char)); thys->Len = 0; thys->Res = RESERVED_SIZE; arrTotal++; arrAlloc += RESERVED_SIZE*sizeof(char); return thys; } ID ajChararrNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size PX RT AjPChar RD Pointer to an empty character array struct RD of specified size. RX CA new CT AjPChar CD Constructor with reserved size CX // AjPChar ajChararrNewRes(ajuint size) { AjPChar thys; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(char)); thys->Len = 0; thys->Res = size; arrTotal++; arrAlloc += size*sizeof(char); return thys; } ID ajChararrDel TY public MO ajarr LB core XX DE Default destructor for AJAX character arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPChar* PD Pointer to the char array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPChar CD Default destructor CX // void ajChararrDel(AjPChar *thys) { if(!thys || !*thys) return; /*ajDebug("ajChararrDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arrFreeCount++; return; } ID ajChararrGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX character array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPChar PD Pointer to the char array. PX PN [2] PA r elem ajuint PD array element. PX RT char RD contents of array element RX CA cast CT AjPChar CD Retrieve a character from an array CX // char ajChararrGet(const AjPChar thys, ajuint elem) { if(!thys || elem>=thys->Len) ajErr("Attempt to access bad char array index %d\n",elem); return thys->Ptr[elem]; } ID ajChararrPut TY public MO ajarr LB core XX DE Load a character array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPChar* PD Pointer to the char array. PX PN [2] PA r elem ajuint PD array element. PX PN [3] PA r v char PD value to load. PX RT AjBool RD true if the array was extended. RX CA modify CT AjPChar CD Load a character array element CX // AjBool ajChararrPut(AjPChar *thys, ajuint elem, char v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value %d\n",elem); if(elem < (*thys)->Res) { if(elem>=(*thys)->Len) (*thys)->Len = elem+1; (*thys)->Ptr[elem] = v; return ajFalse; } arrChararrResize(thys, elem); (*thys)->Ptr[elem] = v; return ajTrue; } ID ajChararrChararr TY public MO ajarr LB core XX DE Returns the current char* pointer. This will remain valid until DE the array is resized or deleted. XX PN [1] PA r thys const AjPChar PD Source array PX RT char* RD Current array pointer, or a null string if undefined. RX CA cast CT AjPChar CD Retrieve internal pointer CX // char* ajChararrChararr(const AjPChar thys) { if(!thys || !thys->Len) return NULL; return thys->Ptr; } ID ajChararrLen TY public MO ajarr LB core XX DE Get length of dynamic character array XX PN [1] PA r thys const AjPChar PD Source array PX RT ajuint RD length RX // ajuint ajChararrLen(const AjPChar thys) { return thys->Len; } ID ajIntNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX integer arrays. XX RT AjPInt RD Pointer to an empty integer array structure RX CA new CT AjPInt CD Default constructor CX // AjPInt ajIntNew(void) { AjPInt thys; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(ajint)); thys->Len = 0; thys->Res = RESERVED_SIZE; arrTotal++; arrAlloc += RESERVED_SIZE*sizeof(ajint); return thys; } ID ajIntNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size PX RT AjPInt RD Pointer to an empty integer array struct of specified size. RX CA new CT AjPInt CD Constructor with reserved size CX // AjPInt ajIntNewRes(ajuint size) { AjPInt thys; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(ajint)); thys->Len = 0; thys->Res = size; arrTotal++; arrAlloc += size*sizeof(ajint); /*ajDebug("ajIntNewRes size %d*%d %d\n", size, sizeof(ajint), size*sizeof(ajint));*/ return thys; } ID ajIntDel TY public MO ajarr LB core XX DE Default destructor for AJAX integer arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPInt* PD Pointer to the ajint array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPInt CD Default destructor CX // void ajIntDel(AjPInt *thys) { if(!thys || !*thys) return; /*ajDebug("ajIntDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arrFreeCount++; return; } ID ajIntGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX integer array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPInt PD Pointer to the ajint array. PX PN [2] PA r elem ajuint PD array element. PX RT ajint RD contents of array element RX CA cast CT AjPInt CD Retrieve an integer from an array CX // ajint ajIntGet(const AjPInt thys, ajuint elem) { if(!thys || elem>=thys->Len) ajErr("Attempt to access bad ajint array index %d\n",elem); return thys->Ptr[elem]; } ID ajIntPut TY public MO ajarr LB core XX DE Load an integer array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPInt* PD Pointer to the ajint array. PX PN [2] PA r elem ajuint PD array element. PX PN [3] PA r v ajint PD value to load. PX RT AjBool RD true if the array was extended. RX CA modify CT AjPInt CD Load an integer array element CX // AjBool ajIntPut(AjPInt *thys, ajuint elem, ajint v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value %d\n",elem); if(elem < (*thys)->Res) { if(elem>=(*thys)->Len) (*thys)->Len = elem+1; (*thys)->Ptr[elem] = v; return ajFalse; } arrIntResize(thys, elem); (*thys)->Ptr[elem] = v; return ajTrue; } ID ajIntInc TY public MO ajarr LB core XX DE Increment an integer array element. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPInt* PD Pointer to the ajint array. PX PN [2] PA r elem ajuint PD array element. PX RT void RD RX // void ajIntInc(AjPInt *thys, ajuint elem) { if(!thys || !*thys || elem>(*thys)->Len) ajErr("Attempt to write to illegal array value %d\n",elem); ++(*thys)->Ptr[elem]; return; } ID ajIntDec TY public MO ajarr LB core XX DE Decrement an integer array element. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPInt* PD Pointer to the ajint array. PX PN [2] PA r elem ajuint PD array element. PX RT void RD RX // void ajIntDec(AjPInt *thys, ajuint elem) { if(!thys || !*thys || elem>(*thys)->Len) ajErr("Attempt to write to illegal array value %d\n",elem); --(*thys)->Ptr[elem]; return; } ID ajUintNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX unsigned integer arrays. XX RT AjPUint RD Pointer to an empty unsigned integer array structure RX CA new CT AjPUint CD Default constructor CX // AjPUint ajUintNew(void) { AjPUint thys; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(ajuint)); thys->Len = 0; thys->Res = RESERVED_SIZE; arrTotal++; arrAlloc += RESERVED_SIZE*sizeof(ajuint); return thys; } ID ajUintNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size PX RT AjPUint RD Pointer to an empty unsigned integer array struct RD of specified size. RX CA new CT AjPUint CD Constructor with reserved size CX // AjPUint ajUintNewRes(ajuint size) { AjPUint thys; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(ajuint)); thys->Len = 0; thys->Res = size; arrTotal++; arrAlloc += size*sizeof(ajuint); /*ajDebug("ajUintNewL size %d*%d %d\n", size, sizeof(ajuint), size*sizeof(ajuint));*/ return thys; } ID ajUintDel TY public MO ajarr LB core XX DE Default destructor for AJAX integer integer arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPUint* PD Pointer to the ajuint array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPUint CD Default destructor CX // void ajUintDel(AjPUint *thys) { if(!thys || !*thys) return; /*ajDebug("ajUintDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arrFreeCount++; return; } ID ajUintGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX unsigned integer array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPUint PD Pointer to the ajuint array. PX PN [2] PA r elem ajuint PD array element. PX RT ajuint RD contents of array element RX CA cast CT AjPUint CD Retrieve an integer from an array CX // ajuint ajUintGet(const AjPUint thys, ajuint elem) { if(!thys || elem>=thys->Len) ajErr("Attempt to access bad ajuint array index %d\n",elem); return thys->Ptr[elem]; } ID ajUintPut TY public MO ajarr LB core XX DE Load an unsigned integer array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPUint* PD Pointer to the ajuint array. PX PN [2] PA r elem ajuint PD array element. PX PN [3] PA r v ajuint PD value to load. PX RT AjBool RD true if the array was extended. RX CA modify CT AjPUint CD Load an integer array element CX // AjBool ajUintPut(AjPUint *thys, ajuint elem, ajuint v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value %d\n",elem); if(elem < (*thys)->Res) { if(elem>=(*thys)->Len) (*thys)->Len = elem+1; (*thys)->Ptr[elem] = v; return ajFalse; } arrUintResize(thys, elem); (*thys)->Ptr[elem] = v; return ajTrue; } ID ajUintInc TY public MO ajarr LB core XX DE Increment an unsigned integer array element. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPUint* PD Pointer to the ajuint array. PX PN [2] PA r elem ajuint PD array element. PX RT void RD RX // void ajUintInc(AjPUint *thys, ajuint elem) { if(!thys || !*thys || elem>(*thys)->Len) ajErr("Attempt to write to illegal array value %d\n",elem); ++(*thys)->Ptr[elem]; return; } ID ajUintDec TY public MO ajarr LB core XX DE Decrement an unsigned integer array element. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPUint* PD Pointer to the ajuint array. PX PN [2] PA r elem ajuint PD array element. PX RT void RD RX // void ajUintDec(AjPUint *thys, ajuint elem) { if(!thys || !*thys || elem>(*thys)->Len) ajErr("Attempt to write to illegal array value %d\n",elem); --(*thys)->Ptr[elem]; return; } ID arrChararrResize TY static MO ajarr LB core XX DE Resize a character array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPChar* PD Pointer to the char array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrChararrResize(AjPChar *thys, ajuint size) { AjPChar p = NULL; ajuint s; ajuint clen; ajuint limit; if(!thys || !*thys) ajErr("Illegal attempt to resize character array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajChararrResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; *thys = ajChararrNewRes(s); if(size < p->Len) limit = size+1; else limit = p->Len; memmove((*thys)->Ptr,p->Ptr,limit*sizeof(char)); (*thys)->Len = size+1; ajChararrDel(&p); arrResize++; return ajTrue; } ID arrIntResize TY static MO ajarr LB core XX DE Resize an integer array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPInt* PD Pointer to the ajint array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrIntResize(AjPInt *thys, ajuint size) { AjPInt p = NULL; ajuint s; ajuint clen; ajuint limit; if(!thys || !*thys) ajErr("Illegal attempt to resize integer array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajIntResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; *thys = ajIntNewRes(s); if(size < p->Len) limit = size+1; else limit = p->Len; memmove((*thys)->Ptr,p->Ptr,limit*sizeof(ajint)); (*thys)->Len = size+1; ajIntDel(&p); arrResize++; return ajTrue; } ID ajIntInt TY public MO ajarr LB core XX DE Returns the current ajint* pointer. This will remain valid until DE the array is resized or deleted. XX PN [1] PA r thys const AjPInt PD Source array PX RT ajint* RD Current array pointer, or a null string if undefined. RX CA cast CT AjPInt CD Retrieve internal pointer CX // ajint* ajIntInt(const AjPInt thys) { if(!thys || !thys->Len) return NULL; return thys->Ptr; } ID ajIntLen TY public MO ajarr LB core XX DE Get length of dynamic 1d ajint array XX PN [1] PA r thys const AjPInt PD Source array PX RT ajuint RD length RX // ajuint ajIntLen(const AjPInt thys) { return thys->Len; } ID arrUintResize TY static MO ajarr LB core XX DE Resize an unsigned integer array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPUint* PD Pointer to the ajuint array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrUintResize(AjPUint *thys, ajuint size) { AjPUint p = NULL; ajuint s; ajuint clen; ajuint limit; if(!thys || !*thys) ajErr("Illegal attempt to resize unsigned integer array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajIntResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; *thys = ajUintNewRes(s); if(size < p->Len) limit = size+1; else limit = p->Len; memmove((*thys)->Ptr,p->Ptr,limit*sizeof(ajuint)); (*thys)->Len = size+1; ajUintDel(&p); arrResize++; return ajTrue; } ID ajUintUint TY public MO ajarr LB core XX DE Returns the current ajuint* pointer. This will remain valid until DE the array is resized or deleted. XX PN [1] PA r thys const AjPUint PD Source array PX RT ajuint* RD Current array pointer, or a null string if undefined. RX CA cast CT AjPUint CD Retrieve internal pointer CX // ajuint* ajUintUint(const AjPUint thys) { if(!thys || !thys->Len) return NULL; return thys->Ptr; } ID ajUintLen TY public MO ajarr LB core XX DE Get length of dynamic 1d ajuint array XX PN [1] PA r thys const AjPUint PD Source array PX RT ajuint RD length RX // ajuint ajUintLen(const AjPUint thys) { return thys->Len; } ID ajFloatNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX float arrays. XX RT AjPFloat RD Pointer to an empty float array structure RX CA new CT AjPFloat CD Default constructor CX // AjPFloat ajFloatNew(void) { AjPFloat thys; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(float)); thys->Len = 0; thys->Res = RESERVED_SIZE; arrTotal++; arrAlloc += RESERVED_SIZE*sizeof(float); return thys; } ID ajFloatNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size PX RT AjPFloat RD Pointer to an empty float array struct of specified size. RX CA new CT AjPFloat CD Constructor with reserved size CX // AjPFloat ajFloatNewRes(ajuint size) { AjPFloat thys; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(float)); thys->Len = 0; thys->Res = size; arrTotal++; arrAlloc += size*sizeof(float); return thys; } ID ajFloatDel TY public MO ajarr LB core XX DE Default destructor for AJAX float arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPFloat* PD Pointer to the float array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPFloat CD Default destructor CX // void ajFloatDel(AjPFloat *thys) { if(!thys || !*thys) return; /*ajDebug("ajFloatDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arrFreeCount++; return; } ID ajFloatGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX float array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPFloat PD Pointer to the float array. PX PN [2] PA r elem ajuint PD array element. PX RT float RD contents of array element RX CA cast CT AjPFloat CD Retrieve a float from an array CX // float ajFloatGet(const AjPFloat thys, ajuint elem) { if(!thys || elem>=thys->Len) ajErr("Attempt to access bad float array index %d\n",elem); return thys->Ptr[elem]; } ID ajFloatPut TY public MO ajarr LB core XX DE Load a float array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPFloat* PD Pointer to the float array. PX PN [2] PA r elem ajuint PD array element. PX PN [3] PA r v float PD value to load. PX RT AjBool RD true if the array was extended. RX CA modify CT AjPFloat CD Load a float array element CX // AjBool ajFloatPut(AjPFloat *thys, ajuint elem, float v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value %d\n",elem); if(elem < (*thys)->Res) { if(elem>=(*thys)->Len) (*thys)->Len = elem+1; (*thys)->Ptr[elem] = v; return ajFalse; } arrFloatResize(thys, elem); (*thys)->Ptr[elem] = v; return ajTrue; } ID arrFloatResize TY static MO ajarr LB core XX DE Resize a float array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPFloat* PD Pointer to the float array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrFloatResize(AjPFloat *thys, ajuint size) { AjPFloat p = NULL; ajuint s; ajuint clen; ajuint limit; if(!thys || !*thys) ajErr("Illegal attempt to resize float array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajFloatResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; *thys = ajFloatNewRes(s); if(size < p->Len) limit = size+1; else limit = p->Len; memmove((*thys)->Ptr,p->Ptr,limit*sizeof(float)); (*thys)->Len = size+1; ajFloatDel(&p); arrResize++; return ajTrue; } ID ajFloatFloat TY public MO ajarr LB core XX DE Returns the current float* pointer. This will remain valid until DE the array is resized or deleted. XX PN [1] PA r thys const AjPFloat PD Source array PX RT float* RD Current array pointer, or a null string if undefined. RX CA cast CT AjPFloat CD Retrieve internal pointer CX // float* ajFloatFloat(const AjPFloat thys) { if(!thys || !thys->Len) return NULL; return thys->Ptr; } ID ajFloatLen TY public MO ajarr LB core XX DE Get length of dynamic 1d float array XX PN [1] PA r thys const AjPFloat PD Source array PX RT ajuint RD length RX // ajuint ajFloatLen(const AjPFloat thys) { return thys->Len; } ID ajDoubleNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX double arrays. XX RT AjPDouble RD Pointer to an empty double array structure RX CA new CT AjPDouble CD Default constructor CX // AjPDouble ajDoubleNew(void) { AjPDouble thys; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(double)); thys->Len = 0; thys->Res = RESERVED_SIZE; arrTotal++; arrAlloc += RESERVED_SIZE*sizeof(double); return thys; } ID ajDoubleNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size PX RT AjPDouble RD Pointer to an empty double array struct RD of specified size. RX CA new CT AjPDouble CD Constructor with reserved size CX // AjPDouble ajDoubleNewRes(ajuint size) { AjPDouble thys; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(double)); thys->Len = 0; thys->Res = size; arrTotal++; arrAlloc += size*sizeof(double); return thys; } ID ajDoubleDel TY public MO ajarr LB core XX DE Default destructor for AJAX double arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPDouble* PD Pointer to the double array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPDouble CD Default destructor CX // void ajDoubleDel(AjPDouble *thys) { if(!thys || !*thys) return; /*ajDebug("ajDoubleDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arrFreeCount++; return; } ID ajDoubleGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX double array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPDouble PD Pointer to the double array. PX PN [2] PA r elem ajuint PD array element. PX RT double RD contents of array element RX CA cast CT AjPDouble CD Retrieve a double from an array CX // double ajDoubleGet(const AjPDouble thys, ajuint elem) { if(!thys || elem>=thys->Len) ajErr("Attempt to access bad double array index %d\n",elem); return thys->Ptr[elem]; } ID ajDoublePut TY public MO ajarr LB core XX DE Load a double array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPDouble* PD Pointer to the double array. PX PN [2] PA r elem ajuint PD array element. PX PN [3] PA r v double PD value to load. PX RT AjBool RD true if the array was extended. RX CA modify CT AjPDouble CD Load a double array element CX // AjBool ajDoublePut(AjPDouble *thys, ajuint elem, double v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value %d\n",elem); if(elem < (*thys)->Res) { if(elem>=(*thys)->Len) (*thys)->Len = elem+1; (*thys)->Ptr[elem] = v; return ajFalse; } arrDoubleResize(thys, elem); (*thys)->Ptr[elem] = v; return ajTrue; } ID arrDoubleResize TY static MO ajarr LB core XX DE Resize a double array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPDouble* PD Pointer to the double array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrDoubleResize(AjPDouble *thys, ajuint size) { AjPDouble p = NULL; ajuint s; ajuint clen; ajuint limit; if(!thys || !*thys) ajErr("Illegal attempt to resize double array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajDoubleResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; *thys = ajDoubleNewRes(s); if(size < p->Len) limit = size+1; else limit = p->Len; memmove((*thys)->Ptr,p->Ptr,limit*sizeof(double)); (*thys)->Len = size+1; ajDoubleDel(&p); arrResize++; return ajTrue; } ID ajDoubleDouble TY public MO ajarr LB core XX DE Returns the current double* pointer. This will remain valid until DE the array is resized or deleted. XX PN [1] PA r thys const AjPDouble PD Source array PX RT double* RD Current array pointer, or a null string if undefined. RX CA cast CT AjPDouble CD Retrieve internal pointer CX // double* ajDoubleDouble(const AjPDouble thys) { if(!thys || !thys->Len) return NULL; return thys->Ptr; } ID ajDoubleLen TY public MO ajarr LB core XX DE Get length of dynamic 1d double array XX PN [1] PA r thys const AjPDouble PD Source array PX RT ajuint RD length RX // ajuint ajDoubleLen(const AjPDouble thys) { return thys->Len; } ID ajShortNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX short arrays. XX RT AjPShort RD Pointer to an empty short array structure RX CA new CT AjPShort CD Default constructor CX // AjPShort ajShortNew(void) { AjPShort thys; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(short)); thys->Len = 0; thys->Res = RESERVED_SIZE; arrTotal++; arrAlloc += RESERVED_SIZE*sizeof(short); return thys; } ID ajShortNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size PX RT AjPShort RD Pointer to an empty short array struct of specified size. RX CA new CT AjPShort CD Constructor with reserved size CX // AjPShort ajShortNewRes(ajuint size) { AjPShort thys; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(short)); thys->Len = 0; thys->Res = size; arrTotal++; arrAlloc += size*sizeof(short); return thys; } ID ajShortDel TY public MO ajarr LB core XX DE Default destructor for AJAX short arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPShort* PD Pointer to the short array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPShort CD Default destructor CX // void ajShortDel(AjPShort *thys) { if(!thys || !*thys) return; /*ajDebug("ajShortDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arrFreeCount++; return; } ID ajShortGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX short array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPShort PD Pointer to the short array. PX PN [2] PA r elem ajuint PD array element. PX RT short RD contents of array element RX CA cast CT AjPShort CD Retrieve a short from an array CX // short ajShortGet(const AjPShort thys, ajuint elem) { if(!thys || elem>=thys->Len) ajErr("Attempt to access bad short array index %d\n",elem); return thys->Ptr[elem]; } ID ajShortPut TY public MO ajarr LB core XX DE Load a short array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPShort* PD Pointer to the short integer array. PX PN [2] PA r elem ajuint PD array element. PX PN [3] PA r v short PD value to load. PX RT AjBool RD true if the array was extended. RX CA modify CT AjPShort CD Load a short array element CX // AjBool ajShortPut(AjPShort *thys, ajuint elem, short v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value %d\n",elem); if(elem < (*thys)->Res) { if(elem>=(*thys)->Len) (*thys)->Len = elem+1; (*thys)->Ptr[elem] = v; return ajFalse; } arrShortResize(thys, elem); (*thys)->Ptr[elem] = v; return ajTrue; } ID arrShortResize TY static MO ajarr LB core XX DE Resize a short array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPShort* PD Pointer to the short integer array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrShortResize(AjPShort *thys, ajuint size) { AjPShort p = NULL; ajuint s; ajuint clen; ajuint limit; if(!thys || !*thys) ajErr("Illegal attempt to resize short array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajShortResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; *thys = ajShortNewRes(s); if(size < p->Len) limit = size+1; else limit = p->Len; memmove((*thys)->Ptr,p->Ptr,limit*sizeof(short)); (*thys)->Len = size+1; ajShortDel(&p); arrResize++; return ajTrue; } ID ajShortShort TY public MO ajarr LB core XX DE Returns the current short* pointer. This will remain valid until DE the array is resized or deleted. XX PN [1] PA r thys const AjPShort PD Source array PX RT short* RD Current array pointer, or a null string if undefined. RX CA cast CT AjPShort CD Retrieve internal pointer CX // short* ajShortShort(const AjPShort thys) { if(!thys || !thys->Len) return NULL; return thys->Ptr; } ID ajShortLen TY public MO ajarr LB core XX DE Get length of dynamic 1d short array XX PN [1] PA r thys const AjPShort PD Source array PX RT ajuint RD length RX // ajuint ajShortLen(const AjPShort thys) { return thys->Len; } ID ajLongNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX ajlong arrays. XX RT AjPLong RD Pointer to an empty ajlong array structure RX CA new CT AjPLong CD Default constructor CX // AjPLong ajLongNew(void) { AjPLong thys; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(ajlong)); thys->Len = 0; thys->Res = RESERVED_SIZE; arrTotal++; arrAlloc += RESERVED_SIZE*sizeof(ajlong); return thys; } ID ajLongNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size PX RT AjPLong RD Pointer to an empty ajlong array struct of specified size. RX CA new CT AjPLong CD Constructor with reserved size CX // AjPLong ajLongNewRes(ajuint size) { AjPLong thys; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(ajlong)); thys->Len = 0; thys->Res = size; arrTotal++; arrAlloc += size*sizeof(ajlong); return thys; } ID ajLongDel TY public MO ajarr LB core XX DE Default destructor for AJAX ajlong arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPLong* PD Pointer to the ajlong array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPLong CD Default destructor CX // void ajLongDel(AjPLong *thys) { if(!thys || !*thys) return; /*ajDebug("ajLongDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arrFreeCount++; return; } ID ajLongGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX ajlong array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPLong PD Pointer to the ajlong array. PX PN [2] PA r elem ajuint PD array element. PX RT ajlong RD contents of array element RX CA cast CT AjPLong CD Retrieve a ajlong from an array CX // ajlong ajLongGet(const AjPLong thys, ajuint elem) { if(!thys || elem>=thys->Len) ajErr("Attempt to access bad ajlong array index %d\n",elem); return thys->Ptr[elem]; } ID ajLongPut TY public MO ajarr LB core XX DE Load a long integer array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPLong* PD Pointer to the long integer array. PX PN [2] PA r elem ajuint PD array element. PX PN [3] PA r v ajlong PD value to load. PX RT AjBool RD true if the array was extended. RX CA modify CT AjPLong CD Load a ajlong array element CX // AjBool ajLongPut(AjPLong *thys, ajuint elem, ajlong v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value %d\n",elem); if(elem < (*thys)->Res) { if(elem>=(*thys)->Len) (*thys)->Len = elem+1; (*thys)->Ptr[elem] = v; return ajFalse; } arrLongResize(thys, elem); (*thys)->Ptr[elem] = v; return ajTrue; } ID arrLongResize TY static MO ajarr LB core XX DE Resize a long integer array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPLong* PD Pointer to the long integer array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrLongResize(AjPLong *thys, ajuint size) { AjPLong p = NULL; ajuint s; ajuint clen; ajuint limit; if(!thys || !*thys) ajErr("Illegal attempt to resize ajlong array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajLongResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; *thys = ajLongNewRes(s); if(size < p->Len) limit = size+1; else limit = p->Len; memmove((*thys)->Ptr,p->Ptr,limit*sizeof(ajlong)); (*thys)->Len = size+1; ajLongDel(&p); arrResize++; return ajTrue; } ID ajLongLong TY public MO ajarr LB core XX DE Returns the current ajlong* pointer. This will remain valid until DE the array is resized or deleted. XX PN [1] PA r thys const AjPLong PD Source array PX RT ajlong* RD Current array pointer, or a null string if undefined. RX CA cast CT AjPLong CD Retrieve internal pointer CX // ajlong* ajLongLong(const AjPLong thys) { if(!thys || !thys->Len) return NULL; return thys->Ptr; } ID ajLongLen TY public MO ajarr LB core XX DE Get length of dynamic 1d ajlong array XX PN [1] PA r thys const AjPLong PD Source array PX RT ajuint RD length RX // ajuint ajLongLen(const AjPLong thys) { return thys->Len; } ID ajFloatParse TY public MO ajarr LB core XX DE Parses a string into a floating point array. DE DE The array size is already set. XX PN [1] PA r str const AjPStr PD Input string PX PN [2] PA w array AjPFloat* PD Array PX RT AjBool RD ajTrue on success. RX // AjBool ajFloatParse (const AjPStr str, AjPFloat* array) { ajuint i = 0; float t = 0.0; AjPStr tmpstr = NULL; AjPStr tmpstr2 = NULL; AjPStr numstr = NULL; if (!floatRegNum) floatRegNum = ajRegCompC ("[+-]?[0-9.]+"); ajStrAssignS(&tmpstr, str); while (ajRegExec (floatRegNum, tmpstr)) { ajRegSubI (floatRegNum, 0, &numstr); ajRegPost (floatRegNum, &tmpstr2); ajStrAssignS(&tmpstr, tmpstr2); ajStrToFloat (numstr, &t); ajFloatPut(array,i,t); i++; } ajStrDel(&numstr); ajStrDel(&tmpstr); ajStrDel(&tmpstr2); if(!i) return ajFalse; return ajTrue; } ID ajFloatStr TY public MO ajarr LB core XX DE Writes a floating point array as a string XX PN [1] PA r array const AjPFloat PD Array PX PN [2] PA r precision ajint PD floating point precision PX PN [3] PA w str AjPStr* PD Output string PX RT void RD RX // void ajFloatStr (const AjPFloat array, ajint precision, AjPStr* str) { ajuint i; for (i=0; i < array->Len; i++) { if (i) ajStrAppendK(str, ' '); ajFmtPrintAppS (str, "%.*f", precision, ajFloatGet(array,i)); } return; } ID ajFloatTrace TY public MO ajarr LB core XX DE Writes a floating point array to the debug file XX PN [1] PA r array const AjPFloat PD Array PX PN [2] PA r precision ajint PD floating point precision PX PN [3] PA r text const char* PD Report title PX RT void RD RX // void ajFloatTrace (const AjPFloat array, ajint precision, const char* text) { ajuint i; ajDebug ("%s\n", text); for (i=0; i < array->Len; i++) ajDebug ("%3d: %.*f\n", i, precision, ajFloatGet(array,i)); ajDebug ("\n"); return; } ID ajArrCommaList TY public MO ajarr LB core XX DE Creates an AjPStr array from a string of comma separated tokens XX PN [1] PA r s const AjPStr PD Line containing comma separated strings PX PN [2] PA w a AjPStr** PD array pointer to create and load PX RT ajuint RD number of array elements created RX // ajuint ajArrCommaList(const AjPStr s, AjPStr **a) { AjPStr x; AjPStrTok t; ajuint n; ajuint i; n = ajStrParseCountC(s,",\n"); if(!n) return 0; AJCNEW(*a, n); x = ajStrNew(); t = ajStrTokenNewC(s,",\n"); for(i=0;iPtr = AJALLOC0(RESERVED_SIZE*sizeof(AjPInt)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; arr2dTotal++; arr2dAlloc += RESERVED_SIZE; return thys; } ID ajInt2dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPInt2d RD Pointer to an empty integer 2d array struct of RD specified size. RX CA new CT AjPInt2d CD Constructor with reserved size CX // AjPInt2d ajInt2dNewRes(ajuint size) { AjPInt2d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPInt)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; arr2dAlloc++; return thys; } ID ajInt2dNewResRes2 TY public MO ajarr LB core XX DE Constructor given an initial reserved size in both dimensions XX PN [1] PA r size ajuint PD Reserved size 1st dim PX PN [2] PA r size2 ajuint PD Reserved size 2nd dim PX RT AjPInt2d RD Pointer to an empty integer 2d array struct of RD specified size. RX CA new CT AjPInt2d CD Constructor with reserved size CX // AjPInt2d ajInt2dNewResRes2(ajuint size, ajuint size2) { AjPInt2d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPInt)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = ajIntNewRes(size2); arr2dAlloc++; /*ajDebug("ajInt2dNewLL %d*%d %d; %d*%d*%d %d\n", size, sizeof(AjPInt*), size*sizeof(AjPInt*), size, size2, sizeof(ajint), size*size2*sizeof(ajint));*/ return thys; } ID ajInt2dDel TY public MO ajarr LB core XX DE Default destructor for AJAX integer arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPInt2d* PD Pointer to the ajint array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPInt2d CD Default destructor CX // void ajInt2dDel(AjPInt2d *thys) { ajint i; if(!thys || !*thys) return; /*ajDebug("ajInt2dDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajIntDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr2dFreeCount++; return; } ID ajInt2dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 2d integer array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPInt2d PD Pointer to the ajint array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX RT ajint RD contents of array element RX CA cast CT AjPInt2d CD Retrieve an integer from an array CX // ajint ajInt2dGet(const AjPInt2d thys, ajuint elem1, ajuint elem2) { AjPInt t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad ajint array index [%d][%d]\n",elem1, elem2); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][]\n",elem1); return ajIntGet(t,elem2); } ID ajInt2dPut TY public MO ajarr LB core XX DE Load an integer 2d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPInt2d* PD Pointer to the ajint array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r v ajint PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPInt2d CD Load an integer array element CX // AjBool ajInt2dPut(AjPInt2d *thys, ajuint elem1, ajuint elem2, ajint v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d]\n",elem1, elem2); if(elem1 < (*thys)->Res) { /*ajDebug("ajInt2dPut [%u][%u] %d ([%u] %x)\n", elem1, elem2, v, (*thys)->Len, (*thys)->Ptr[elem1]);*/ if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajIntNew(); return ajIntPut(&(*thys)->Ptr[elem1],elem2,v); } arrInt2dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajIntNew(); ajIntPut(&(*thys)->Ptr[elem1],elem2,v); return ajTrue; } ID arrInt2dResize TY static MO ajarr LB core XX DE Resize an integer array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPInt2d* PD Pointer to the ajint array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrInt2dResize(AjPInt2d *thys, ajuint size) { AjPInt2d nthys; AjPInt2d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize integer array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajInt2dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPInt)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPInt)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajIntDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr2dResize++; return ajTrue; } ID ajInt2dLen TY public MO ajarr LB core XX DE Get lengths of 2d ajint array XX PN [1] PA r thys const AjPInt2d PD Pointer to the ajint array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX RT void RD RX // void ajInt2dLen(const AjPInt2d thys, ajuint* len1, ajuint* len2) { AjPInt t; ajuint i; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t=thys->Ptr[i])) *len2 = (*len2 > t->Len) ? *len2 : t->Len; return; } ID ajInt2dInt TY public MO ajarr LB core XX DE Convert AjPInt2d to ajint XX PN [1] PA r thys const AjPInt2d PD Pointer to the ajint array. PX RT ajint** RD converted value. RX CA cast CT AjPInt2d CD Retrieve internal pointer CX // ajint** ajInt2dInt(const AjPInt2d thys) { AjPInt t = NULL; ajint **array; ajuint d1; ajuint d2; ajuint i; ajInt2dLen(thys,&d1,&d2); AJCNEW(array,d1); for(i=0;iPtr[i])) memmove(array[i],t->Ptr,t->Len*sizeof(ajint)); } return array; } ID ajInt3dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 3D integer arrays. XX RT AjPInt3d RD Pointer to an empty integer array structure RX CA new CT AjPInt3d CD Default constructor CX // AjPInt3d ajInt3dNew(void) { AjPInt3d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPInt2d)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajInt3dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPInt3d RD Pointer to an empty integer 3d array struct of RD specified size. RX CA new CT AjPInt3d CD Constructor with reserved size CX // AjPInt3d ajInt3dNewRes(ajuint size) { AjPInt3d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPInt2d)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajInt3dDel TY public MO ajarr LB core XX DE Default destructor for AJAX integer arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPInt3d* PD Pointer to the ajint array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPInt3d CD Default destructor CX // void ajInt3dDel(AjPInt3d *thys) { ajint i; if(!thys || !*thys) return; /*ajDebug("ajInt3dDel Len %u Res %u\n", (*thys)->Len, (*thys)->Res);*/ for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajInt2dDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr3dFreeCount++; return; } ID ajInt3dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 3d integer array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPInt3d PD Pointer to the ajint array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX RT ajint RD contents of array element RX CA cast CT AjPInt3d CD Retrieve an integer from an array CX // ajint ajInt3dGet(const AjPInt3d thys, ajuint elem1, ajuint elem2, ajuint elem3) { AjPInt2d t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad ajint array index [%d][%d][%d]\n",elem1, elem2,elem3); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][][]\n",elem1); return ajInt2dGet(t,elem2,elem3); } ID ajInt3dPut TY public MO ajarr LB core XX DE Load an integer 3d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPInt3d* PD Pointer to the ajint array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX PN [5] PA r v ajint PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPInt3d CD Load an integer array element CX // AjBool ajInt3dPut(AjPInt3d *thys, ajuint elem1, ajuint elem2, ajuint elem3, ajint v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d][%d]\n",elem1, elem2,elem3); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajInt2dNew(); return ajInt2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); } arrInt3dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajInt2dNew(); ajInt2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); return ajTrue; } ID arrInt3dResize TY static MO ajarr LB core XX DE Resize an integer array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPInt3d* PD Pointer to the ajint array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrInt3dResize(AjPInt3d *thys, ajuint size) { AjPInt3d nthys; AjPInt3d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize integer array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajInt3dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPInt2d)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPInt2d)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajInt2dDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr3dResize++; return ajTrue; } ID ajInt3dLen TY public MO ajarr LB core XX DE Get lengths of 3d ajint array XX PN [1] PA r thys const AjPInt3d PD Pointer to the ajint array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX PN [4] PA w len3 ajuint* PD Length of 3rd dim PX RT void RD RX // void ajInt3dLen(const AjPInt3d thys, ajuint* len1, ajuint* len2, ajuint* len3) { AjPInt2d t2; AjPInt t1; ajuint i; ajuint j; ajuint v; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) *len2 = (*len2 > t2->Len) ? *len2 : t2->Len; *len3=0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) { v = t2->Len; for(j=0;jPtr[j])) *len3 = (*len3 > t1->Len) ? *len3 : t1->Len; } return; } ID ajInt3dInt TY public MO ajarr LB core XX DE Convert AjPInt3d to ajint XX PN [1] PA r thys const AjPInt3d PD Pointer to the ajint array. PX RT ajint*** RD converted values. RX CA cast CT AjPInt3d CD Retrieve internal pointer CX // ajint*** ajInt3dInt(const AjPInt3d thys) { AjPInt2d t2 = NULL; AjPInt t1 = NULL; ajint ***array; ajuint d1; ajuint d2; ajuint d3; ajuint i; ajuint j; ajInt3dLen(thys,&d1,&d2,&d3); AJCNEW0(array,d1); for(i=0;iPtr[i]; for(j=0;j=t2->Len) continue; if((t1=t2->Ptr[j])) memmove(array[i][j],t1->Ptr, t1->Len*sizeof(ajint)); } } } return array; } ID ajUint2dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 2D integer arrays. XX RT AjPUint2d RD Pointer to an empty integer array structure RX CA new CT AjPUint2d CD Default constructor CX // AjPUint2d ajUint2dNew(void) { AjPUint2d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPUint)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; arr2dTotal++; arr2dAlloc += RESERVED_SIZE; return thys; } ID ajUint2dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPUint2d RD Pointer to an empty integer 2d array struct of RD specified size. RX CA new CT AjPUint2d CD Constructor with reserved size CX // AjPUint2d ajUint2dNewRes(ajuint size) { AjPUint2d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPUint)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; arr2dAlloc++; return thys; } ID ajUint2dNewResRes2 TY public MO ajarr LB core XX DE Constructor given an initial reserved size in both dimensions XX PN [1] PA r size ajuint PD Reserved size 1st dim PX PN [2] PA r size2 ajuint PD Reserved size 2nd dim PX RT AjPUint2d RD Pointer to an empty integer 2d array struct of RD specified size. RX CA new CT AjPUint2d CD Constructor with reserved size CX // AjPUint2d ajUint2dNewResRes2(ajuint size, ajuint size2) { AjPUint2d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPUint)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = ajUintNewRes(size2); arr2dAlloc++; /*ajDebug("ajUint2dNewLL %d*%d %d; %d*%d*%d %d\n", size, sizeof(AjPUint*), size*sizeof(AjPUint*), size, size2, sizeof(ajuint), size*size2*sizeof(ajuint));*/ return thys; } ID ajUint2dDel TY public MO ajarr LB core XX DE Default destructor for AJAX unsigned integer arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPUint2d* PD Pointer to the ajuint array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPUint2d CD Default destructor CX // void ajUint2dDel(AjPUint2d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajUintDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr2dFreeCount++; return; } ID ajUint2dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 2d unsigned integer array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPUint2d PD Pointer to the ajuint array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX RT ajuint RD contents of array element RX CA cast CT AjPUint2d CD Retrieve an integer from an array CX // ajuint ajUint2dGet(const AjPUint2d thys, ajuint elem1, ajuint elem2) { AjPUint t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad ajuint array index [%d][%d]\n",elem1, elem2); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][]\n",elem1); return ajUintGet(t,elem2); } ID ajUint2dPut TY public MO ajarr LB core XX DE Load an unsigned integer 2d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPUint2d* PD Pointer to the ajuint array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r v ajuint PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPUint2d CD Load an integer array element CX // AjBool ajUint2dPut(AjPUint2d *thys, ajuint elem1, ajuint elem2, ajuint v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d]\n",elem1, elem2); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajUintNew(); return ajUintPut(&(*thys)->Ptr[elem1],elem2,v); } arrUint2dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajUintNew(); ajUintPut(&(*thys)->Ptr[elem1],elem2,v); return ajTrue; } ID arrUint2dResize TY static MO ajarr LB core XX DE Resize an unsigned integer array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPUint2d* PD Pointer to the ajuint array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrUint2dResize(AjPUint2d *thys, ajuint size) { AjPUint2d nthys; AjPUint2d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize integer array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajUint2dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPUint)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPUint)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajUintDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr2dResize++; return ajTrue; } ID ajUint2dLen TY public MO ajarr LB core XX DE Get lengths of 2d ajuint array XX PN [1] PA r thys const AjPUint2d PD Pointer to the ajuint array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX RT void RD RX // void ajUint2dLen(const AjPUint2d thys, ajuint* len1, ajuint* len2) { AjPUint t; ajuint i; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t=thys->Ptr[i])) *len2 = (*len2 > t->Len) ? *len2 : t->Len; return; } ID ajUint2dUint TY public MO ajarr LB core XX DE Convert AjPUint2d to ajuint XX PN [1] PA r thys const AjPUint2d PD Pointer to the ajuint array. PX RT ajuint** RD converted value. RX CA cast CT AjPUint2d CD Retrieve internal pointer CX // ajuint** ajUint2dUint(const AjPUint2d thys) { AjPUint t = NULL; ajuint **array; ajuint d1; ajuint d2; ajuint i; ajUint2dLen(thys,&d1,&d2); AJCNEW(array,d1); for(i=0;iPtr[i])) memmove(array[i],t->Ptr,t->Len*sizeof(ajuint)); } return array; } ID ajUint3dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 3D unsigned integer arrays. XX RT AjPUint3d RD Pointer to an empty unsigned integer array structure RX CA new CT AjPUint3d CD Default constructor CX // AjPUint3d ajUint3dNew(void) { AjPUint3d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPUint2d)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajUint3dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPUint3d RD Pointer to an empty unsigned integer 3d array struct of RD specified size. RX CA new CT AjPUint3d CD Constructor with reserved size CX // AjPUint3d ajUint3dNewRes(ajuint size) { AjPUint3d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPInt2d)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajUint3dDel TY public MO ajarr LB core XX DE Default destructor for AJAX unsigned integer arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPUint3d* PD Pointer to the ajuint array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPUint3d CD Default destructor CX // void ajUint3dDel(AjPUint3d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajUint2dDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr3dFreeCount++; return; } ID ajUint3dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 3d integer array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPUint3d PD Pointer to the ajuint array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX RT ajuint RD contents of array element RX CA cast CT AjPUint3d CD Retrieve an integer from an array CX // ajuint ajUint3dGet(const AjPUint3d thys, ajuint elem1, ajuint elem2, ajuint elem3) { AjPUint2d t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad ajuint array index [%d][%d][%d]\n",elem1, elem2,elem3); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][][]\n",elem1); return ajUint2dGet(t,elem2,elem3); } ID ajUint3dPut TY public MO ajarr LB core XX DE Load an unsigned integer 3d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPUint3d* PD Pointer to the ajint array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX PN [5] PA r v ajuint PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPUint3d CD Load an integer array element CX // AjBool ajUint3dPut(AjPUint3d *thys, ajuint elem1, ajuint elem2, ajuint elem3, ajuint v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d][%d]\n",elem1, elem2,elem3); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajUint2dNew(); return ajUint2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); } arrUint3dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajUint2dNew(); ajUint2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); return ajTrue; } ID arrUint3dResize TY static MO ajarr LB core XX DE Resize an unsigned integer array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPUint3d* PD Pointer to the ajuint array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrUint3dResize(AjPUint3d *thys, ajuint size) { AjPUint3d nthys; AjPUint3d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize unsigned integer array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajUint3dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPUint2d)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPUint2d)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajUint2dDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr3dResize++; return ajTrue; } ID ajUint3dLen TY public MO ajarr LB core XX DE Get lengths of 3d ajuint array XX PN [1] PA r thys const AjPUint3d PD Pointer to the ajuint array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX PN [4] PA w len3 ajuint* PD Length of 3rd dim PX RT void RD RX // void ajUint3dLen(const AjPUint3d thys, ajuint* len1, ajuint* len2, ajuint* len3) { AjPUint2d t2; AjPUint t1; ajuint i; ajuint j; ajuint v; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) *len2 = (*len2 > t2->Len) ? *len2 : t2->Len; *len3=0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) { v = t2->Len; for(j=0;jPtr[j])) *len3 = (*len3 > t1->Len) ? *len3 : t1->Len; } return; } ID ajUint3dUint TY public MO ajarr LB core XX DE Convert AjPUint3d to ajuint XX PN [1] PA r thys const AjPUint3d PD Pointer to the ajuint array. PX RT ajuint*** RD converted values. RX CA cast CT AjPUint3d CD Retrieve internal pointer CX // ajuint*** ajUint3dUint(const AjPUint3d thys) { AjPUint2d t2 = NULL; AjPUint t1 = NULL; ajuint ***array; ajuint d1; ajuint d2; ajuint d3; ajuint i; ajuint j; ajUint3dLen(thys,&d1,&d2,&d3); AJCNEW0(array,d1); for(i=0;iPtr[i]; for(j=0;j=t2->Len) continue; if((t1=t2->Ptr[j])) memmove(array[i][j],t1->Ptr, t1->Len*sizeof(ajuint)); } } } return array; } ID ajFloat2dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 2D float arrays. XX RT AjPFloat2d RD Pointer to an empty float array structure RX CA new CT AjPFloat2d CD Default constructor CX // AjPFloat2d ajFloat2dNew(void) { AjPFloat2d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPFloat)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajFloat2dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPFloat2d RD Pointer to an empty float 2d array struct of RD specified size. RX CA new CT AjPFloat2d CD Constructor with reserved size CX // AjPFloat2d ajFloat2dNewRes(ajuint size) { AjPFloat2d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPFloat)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajFloat2dDel TY public MO ajarr LB core XX DE Default destructor for AJAX float arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPFloat2d* PD Pointer to the float array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPFloat2d CD Default destructor CX // void ajFloat2dDel(AjPFloat2d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajFloatDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr2dFreeCount++; return; } ID ajFloat2dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 2d float array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPFloat2d PD Pointer to the float array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX RT float RD contents of array element RX CA cast CT AjPFloat2d CD Retrieve a float from an array CX // float ajFloat2dGet(const AjPFloat2d thys, ajuint elem1, ajuint elem2) { AjPFloat t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad float array index [%d][%d]\n",elem1, elem2); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][]\n",elem1); return ajFloatGet(t,elem2); } ID ajFloat2dPut TY public MO ajarr LB core XX DE Load a float 2d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPFloat2d* PD Pointer to the float array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r v float PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPFloat2d CD Load a float array element CX // AjBool ajFloat2dPut(AjPFloat2d *thys, ajuint elem1, ajuint elem2, float v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d]\n",elem1, elem2); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajFloatNew(); return ajFloatPut(&(*thys)->Ptr[elem1],elem2,v); } arrFloat2dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajFloatNew(); ajFloatPut(&(*thys)->Ptr[elem1],elem2,v); return ajTrue; } ID arrFloat2dResize TY static MO ajarr LB core XX DE Resize a float array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPFloat2d* PD Pointer to the float array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrFloat2dResize(AjPFloat2d *thys, ajuint size) { AjPFloat2d nthys; AjPFloat2d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize float array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajFloat2dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPFloat)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPFloat)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajFloatDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr2dResize++; return ajTrue; } ID ajFloat2dLen TY public MO ajarr LB core XX DE Get lengths of 2d float array XX PN [1] PA r thys const AjPFloat2d PD Pointer to the float array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX RT void RD RX // void ajFloat2dLen(const AjPFloat2d thys, ajuint* len1, ajuint* len2) { AjPFloat t; ajuint i; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t=thys->Ptr[i])) *len2 = (*len2 > t->Len) ? *len2 : t->Len; return; } ID ajFloat2dFloat TY public MO ajarr LB core XX DE Convert AjPFloat2d to float XX PN [1] PA r thys const AjPFloat2d PD Pointer to the float array. PX RT float** RD converted values. RX CA cast CT AjPFloat2d CD Retrieve internal pointer CX // float** ajFloat2dFloat(const AjPFloat2d thys) { AjPFloat t = NULL; float **array; ajuint d1; ajuint d2; ajuint i; ajFloat2dLen(thys,&d1,&d2); AJCNEW(array,d1); for(i=0;iPtr[i])) memmove(array[i],t->Ptr,t->Len*sizeof(float)); } return array; } ID ajFloat3dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 3D float arrays. XX RT AjPFloat3d RD Pointer to an empty float array structure RX CA new CT AjPFloat3d CD Default constructor CX // AjPFloat3d ajFloat3dNew(void) { AjPFloat3d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPFloat2d)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajFloat3dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPFloat3d RD Pointer to an empty float 3d array struct of RD specified size. RX CA new CT AjPFloat3d CD Constructor with reserved size CX // AjPFloat3d ajFloat3dNewRes(ajuint size) { AjPFloat3d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPFloat2d)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajFloat3dDel TY public MO ajarr LB core XX DE Default destructor for AJAX float arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPFloat3d* PD Pointer to the float array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPFloat3d CD Default destructor CX // void ajFloat3dDel(AjPFloat3d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajFloat2dDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr3dFreeCount++; return; } ID ajFloat3dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 3d float array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPFloat3d PD Pointer to the float array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX RT float RD contents of array element RX CA cast CT AjPFloat3d CD Retrieve a float from an array CX // float ajFloat3dGet(const AjPFloat3d thys, ajuint elem1, ajuint elem2, ajuint elem3) { AjPFloat2d t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad float array index [%d][%d][%d]\n",elem1, elem2,elem3); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][][]\n",elem1); return ajFloat2dGet(t,elem2,elem3); } ID ajFloat3dPut TY public MO ajarr LB core XX DE Load a float 3d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPFloat3d* PD Pointer to the float array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX PN [5] PA r v float PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPFloat3d CD Load a float array element CX // AjBool ajFloat3dPut(AjPFloat3d *thys, ajuint elem1, ajuint elem2, ajuint elem3, float v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d][%d]\n",elem1, elem2,elem3); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajFloat2dNew(); return ajFloat2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); } arrFloat3dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajFloat2dNew(); ajFloat2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); return ajTrue; } ID arrFloat3dResize TY static MO ajarr LB core XX DE Resize a float array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPFloat3d* PD Pointer to the float array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrFloat3dResize(AjPFloat3d *thys, ajuint size) { AjPFloat3d nthys; AjPFloat3d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize float array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajFloat3dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPFloat2d)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPFloat2d)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajFloat2dDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr3dResize++; return ajTrue; } ID ajFloat3dLen TY public MO ajarr LB core XX DE Get lengths of 3d float array XX PN [1] PA r thys const AjPFloat3d PD Pointer to the float array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX PN [4] PA w len3 ajuint* PD Length of 3rd dim PX RT void RD RX // void ajFloat3dLen(const AjPFloat3d thys, ajuint* len1, ajuint* len2, ajuint* len3) { AjPFloat2d t2; AjPFloat t1; ajuint i; ajuint j; ajuint v; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) *len2 = (*len2 > t2->Len) ? *len2 : t2->Len; *len3 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) { v = t2->Len; for(j=0;jPtr[j])) *len3 = (*len3 > t1->Len) ? *len3 : t1->Len; } return; } ID ajFloat3dFloat TY public MO ajarr LB core XX DE Convert AjPFloat3d to float XX PN [1] PA r thys const AjPFloat3d PD Pointer to the float array. PX RT float*** RD converted values. RX CA cast CT AjPFloat3d CD Retrieve internal pointer CX // float*** ajFloat3dFloat(const AjPFloat3d thys) { AjPFloat2d t2 = NULL; AjPFloat t1 = NULL; float ***array; ajuint d1; ajuint d2; ajuint d3; ajuint i; ajuint j; ajFloat3dLen(thys,&d1,&d2,&d3); AJCNEW0(array,d1); for(i=0;iPtr[i]; for(j=0;j=t2->Len) continue; if((t1=t2->Ptr[j])) memmove(array[i][j],t1->Ptr, t1->Len*sizeof(float)); } } } return array; } ID ajDouble2dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 2D double arrays. XX RT AjPDouble2d RD Pointer to an empty double array structure RX CA new CT AjPDouble2d CD Default constructor CX // AjPDouble2d ajDouble2dNew(void) { AjPDouble2d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPDouble)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajDouble2dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPDouble2d RD Pointer to an empty double 2d array struct of RD specified size. RX CA new CT AjPDouble2d CD Constructor with reserved size CX // AjPDouble2d ajDouble2dNewRes(ajuint size) { AjPDouble2d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPDouble)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajDouble2dDel TY public MO ajarr LB core XX DE Default destructor for AJAX double arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPDouble2d* PD Pointer to the double array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPDouble2d CD Default destructor CX // void ajDouble2dDel(AjPDouble2d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajDoubleDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr2dFreeCount++; return; } ID ajDouble2dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 2d double array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPDouble2d PD Pointer to the double array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX RT double RD contents of array element RX CA cast CT AjPDouble2d CD Retrieve a double from an array CX // double ajDouble2dGet(const AjPDouble2d thys, ajuint elem1, ajuint elem2) { AjPDouble t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad double array index [%d][%d]\n",elem1, elem2); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][]\n",elem1); return ajDoubleGet(t,elem2); } ID ajDouble2dPut TY public MO ajarr LB core XX DE Load a double 2d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPDouble2d* PD Pointer to the double array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r v double PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPDouble2d CD Load a double array element CX // AjBool ajDouble2dPut(AjPDouble2d *thys, ajuint elem1, ajuint elem2, double v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d]\n",elem1, elem2); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajDoubleNew(); return ajDoublePut(&(*thys)->Ptr[elem1],elem2,v); } arrDouble2dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajDoubleNew(); ajDoublePut(&(*thys)->Ptr[elem1],elem2,v); return ajTrue; } ID arrDouble2dResize TY static MO ajarr LB core XX DE Resize a double array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPDouble2d* PD Pointer to the double array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrDouble2dResize(AjPDouble2d *thys, ajuint size) { AjPDouble2d nthys; AjPDouble2d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize double array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajDouble2dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPDouble)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPDouble)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajDoubleDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr2dResize++; return ajTrue; } ID ajDouble2dLen TY public MO ajarr LB core XX DE Get lengths of 2d double array XX PN [1] PA r thys const AjPDouble2d PD Pointer to the double array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX RT void RD RX // void ajDouble2dLen(const AjPDouble2d thys, ajuint* len1, ajuint* len2) { AjPDouble t; ajuint i; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t=thys->Ptr[i])) *len2 = (*len2 > t->Len) ? *len2 : t->Len; return; } ID ajDouble2dDouble TY public MO ajarr LB core XX DE Convert AjPDouble2d to double XX PN [1] PA r thys const AjPDouble2d PD Pointer to the double array. PX RT double** RD converted values. RX CA cast CT AjPDouble2d CD Retrieve internal pointer CX // double** ajDouble2dDouble(const AjPDouble2d thys) { AjPDouble t = NULL; double **array; ajuint d1; ajuint d2; ajuint i; ajDouble2dLen(thys,&d1,&d2); AJCNEW(array,d1); for(i=0;iPtr[i])) memmove(array[i],t->Ptr,t->Len*sizeof(double)); } return array; } ID ajDouble3dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 3D double arrays. XX RT AjPDouble3d RD Pointer to an empty double array structure RX CA new CT AjPDouble3d CD Default constructor CX // AjPDouble3d ajDouble3dNew(void) { AjPDouble3d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPDouble2d)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajDouble3dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPDouble3d RD Pointer to an empty double 3d array struct of RD specified size. RX CA new CT AjPDouble3d CD Constructor with reserved size CX // AjPDouble3d ajDouble3dNewRes(ajuint size) { AjPDouble3d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPDouble2d)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajDouble3dDel TY public MO ajarr LB core XX DE Default destructor for AJAX double arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPDouble3d* PD Pointer to the double array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPDouble3d CD Default destructor CX // void ajDouble3dDel(AjPDouble3d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajDouble2dDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr3dFreeCount++; return; } ID ajDouble3dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 3d double array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPDouble3d PD Pointer to the double array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX RT double RD contents of array element RX CA cast CT AjPDouble3d CD Retrieve a double from an array CX // double ajDouble3dGet(const AjPDouble3d thys, ajuint elem1, ajuint elem2, ajuint elem3) { AjPDouble2d t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad double array index [%d][%d][%d]\n",elem1, elem2,elem3); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][][]\n",elem1); return ajDouble2dGet(t,elem2,elem3); } ID ajDouble3dPut TY public MO ajarr LB core XX DE Load a double 3d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPDouble3d* PD Pointer to the double array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX PN [5] PA r v double PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPDouble3d CD Load a double array element CX // AjBool ajDouble3dPut(AjPDouble3d *thys, ajuint elem1, ajuint elem2, ajuint elem3, double v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d][%d]\n",elem1, elem2,elem3); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajDouble2dNew(); return ajDouble2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); } arrDouble3dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajDouble2dNew(); ajDouble2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); return ajTrue; } ID arrDouble3dResize TY static MO ajarr LB core XX DE Resize a double array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPDouble3d* PD Pointer to the double array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrDouble3dResize(AjPDouble3d *thys, ajuint size) { AjPDouble3d nthys; AjPDouble3d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize double array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajDouble3dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPDouble2d)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPDouble2d)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajDouble2dDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr3dResize++; return ajTrue; } ID ajDouble3dLen TY public MO ajarr LB core XX DE Get lengths of 3d double array XX PN [1] PA r thys const AjPDouble3d PD Pointer to the double array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX PN [4] PA w len3 ajuint* PD Length of 3rd dim PX RT void RD RX // void ajDouble3dLen(const AjPDouble3d thys, ajuint* len1, ajuint* len2, ajuint* len3) { AjPDouble2d t2; AjPDouble t1; ajuint i; ajuint j; ajuint v; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) *len2 = (*len2 > t2->Len) ? *len2 : t2->Len; *len3 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) { v = t2->Len; for(j=0;jPtr[j])) *len3 = (*len3 > t1->Len) ? *len3 : t1->Len; } return; } ID ajDouble3dDouble TY public MO ajarr LB core XX DE Convert AjPDouble3d to double XX PN [1] PA r thys const AjPDouble3d PD Pointer to the double array. PX RT double*** RD converted values. RX CA cast CT AjPDouble3d CD Retrieve internal pointer CX // double*** ajDouble3dDouble(const AjPDouble3d thys) { AjPDouble2d t2 = NULL; AjPDouble t1 = NULL; double ***array; ajuint d1; ajuint d2; ajuint d3; ajuint i; ajuint j; ajDouble3dLen(thys,&d1,&d2,&d3); AJCNEW0(array,d1); for(i=0;iPtr[i]; for(j=0;j=t2->Len) continue; if((t1=t2->Ptr[j])) memmove(array[i][j],t1->Ptr, t1->Len*sizeof(double)); } } } return array; } ID ajShort2dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 2D short arrays. XX RT AjPShort2d RD Pointer to an empty short array structure RX CA new CT AjPShort2d CD Default constructor CX // AjPShort2d ajShort2dNew(void) { AjPShort2d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPShort)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajShort2dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPShort2d RD Pointer to an empty short 2d array struct of RD specified size. RX CA new CT AjPShort2d CD Constructor with reserved size CX // AjPShort2d ajShort2dNewRes(ajuint size) { AjPShort2d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPShort)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajShort2dDel TY public MO ajarr LB core XX DE Default destructor for AJAX short arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPShort2d* PD Pointer to the short array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPShort2d CD Default destructor CX // void ajShort2dDel(AjPShort2d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajShortDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr2dFreeCount++; return; } ID ajShort2dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 2d short array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPShort2d PD Pointer to the short array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX RT short RD contents of array element RX CA cast CT AjPShort2d CD Retrieve a short from an array CX // short ajShort2dGet(const AjPShort2d thys, ajuint elem1, ajuint elem2) { AjPShort t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad short array index [%d][%d]\n",elem1, elem2); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][]\n",elem1); return ajShortGet(t,elem2); } ID ajShort2dPut TY public MO ajarr LB core XX DE Load a short 2d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPShort2d* PD Pointer to the short array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r v short PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPShort2d CD Load a short array element CX // AjBool ajShort2dPut(AjPShort2d *thys, ajuint elem1, ajuint elem2, short v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d]\n",elem1, elem2); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajShortNew(); return ajShortPut(&(*thys)->Ptr[elem1],elem2,v); } arrShort2dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajShortNew(); ajShortPut(&(*thys)->Ptr[elem1],elem2,v); return ajTrue; } ID arrShort2dResize TY static MO ajarr LB core XX DE Resize a short array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPShort2d* PD Pointer to the short array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrShort2dResize(AjPShort2d *thys, ajuint size) { AjPShort2d nthys; AjPShort2d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize short array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajShort2dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPShort)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPShort)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajShortDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr2dResize++; return ajTrue; } ID ajShort2dLen TY public MO ajarr LB core XX DE Get lengths of 2d short array XX PN [1] PA r thys const AjPShort2d PD Pointer to the short array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX RT void RD RX // void ajShort2dLen(const AjPShort2d thys, ajuint* len1, ajuint* len2) { AjPShort t; ajuint i; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t=thys->Ptr[i])) *len2 = (*len2 > t->Len) ? *len2 : t->Len; return; } ID ajShort2dShort TY public MO ajarr LB core XX DE Convert AjPShort2d to short XX PN [1] PA r thys const AjPShort2d PD Pointer to the short array. PX RT short** RD converted values RX CA cast CT AjPShort2d CD Retrieve internal pointer CX // short** ajShort2dShort(const AjPShort2d thys) { AjPShort t = NULL; short **array; ajuint d1; ajuint d2; ajuint i; ajShort2dLen(thys,&d1,&d2); AJCNEW(array,d1); for(i=0;iPtr[i])) memmove(array[i],t->Ptr,t->Len*sizeof(short)); } return array; } ID ajShort3dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 3D short arrays. XX RT AjPShort3d RD Pointer to an empty short array structure RX CA new CT AjPShort3d CD Default constructor CX // AjPShort3d ajShort3dNew(void) { AjPShort3d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPShort2d)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajShort3dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPShort3d RD Pointer to an empty short 3d array struct of RD specified size. RX CA new CT AjPShort3d CD Constructor with reserved size CX // AjPShort3d ajShort3dNewRes(ajuint size) { AjPShort3d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPShort2d)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajShort3dDel TY public MO ajarr LB core XX DE Default destructor for AJAX short arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPShort3d* PD Pointer to the short array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPShort3d CD Default destructor CX // void ajShort3dDel(AjPShort3d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajShort2dDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr3dFreeCount++; return; } ID ajShort3dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 3d short array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPShort3d PD Pointer to the short array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX RT short RD contents of array element RX CA cast CT AjPShort3d CD Retrieve a short from an array CX // short ajShort3dGet(const AjPShort3d thys, ajuint elem1, ajuint elem2, ajuint elem3) { AjPShort2d t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad short array index [%d][%d][%d]\n",elem1, elem2,elem3); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][][]\n",elem1); return ajShort2dGet(t,elem2,elem3); } ID ajShort3dPut TY public MO ajarr LB core XX DE Load a short 3d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPShort3d* PD Pointer to the short array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX PN [5] PA r v short PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPShort3d CD Load a short array element CX // AjBool ajShort3dPut(AjPShort3d *thys, ajuint elem1, ajuint elem2, ajuint elem3, short v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d][%d]\n",elem1, elem2,elem3); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajShort2dNew(); return ajShort2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); } arrShort3dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajShort2dNew(); ajShort2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); return ajTrue; } ID arrShort3dResize TY static MO ajarr LB core XX DE Resize a short array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPShort3d* PD Pointer to the short array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrShort3dResize(AjPShort3d *thys, ajuint size) { AjPShort3d nthys; AjPShort3d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize short array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajShort3dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPShort2d)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPShort2d)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajShort2dDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr3dResize++; return ajTrue; } ID ajShort3dLen TY public MO ajarr LB core XX DE Get lengths of 3d short array XX PN [1] PA r thys const AjPShort3d PD Pointer to the short array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX PN [4] PA w len3 ajuint* PD Length of 3rd dim PX RT void RD RX // void ajShort3dLen(const AjPShort3d thys, ajuint* len1, ajuint* len2, ajuint* len3) { AjPShort2d t2; AjPShort t1; ajuint i; ajuint j; ajuint v; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) *len2 = (*len2 > t2->Len) ? *len2 : t2->Len; *len3 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) { v = t2->Len; for(j=0;jPtr[j])) *len3 = (*len3 > t1->Len) ? *len3 : t1->Len; } return; } ID ajShort3dShort TY public MO ajarr LB core XX DE Convert AjPShort3d to short XX PN [1] PA r thys const AjPShort3d PD Pointer to the short array. PX RT short*** RD converted values. RX CA cast CT AjPShort3d CD Retrieve internal pointer CX // short*** ajShort3dShort(const AjPShort3d thys) { AjPShort2d t2 = NULL; AjPShort t1 = NULL; short ***array; ajuint d1; ajuint d2; ajuint d3; ajuint i; ajuint j; ajShort3dLen(thys,&d1,&d2,&d3); AJCNEW0(array,d1); for(i=0;iPtr[i]; for(j=0;j=t2->Len) continue; if((t1=t2->Ptr[j])) memmove(array[i][j],t1->Ptr, t1->Len*sizeof(short)); } } } return array; } ID ajLong2dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 2D ajlong arrays. XX RT AjPLong2d RD Pointer to an empty ajlong array structure RX CA new CT AjPLong2d CD Default constructor CX // AjPLong2d ajLong2dNew(void) { AjPLong2d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPLong)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajLong2dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPLong2d RD Pointer to an empty ajlong 2d array struct of RD specified size. RX CA new CT AjPLong2d CD Constructor with reserved size CX // AjPLong2d ajLong2dNewRes(ajuint size) { AjPLong2d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPLong)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajLong2dDel TY public MO ajarr LB core XX DE Default destructor for AJAX ajlong arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPLong2d* PD Pointer to the ajlong array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPLong2d CD Default destructor CX // void ajLong2dDel(AjPLong2d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajLongDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr2dFreeCount++; return; } ID ajLong2dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 2d ajlong array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPLong2d PD Pointer to the ajlong array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX RT ajlong RD contents of array element RX CA cast CT AjPLong2d CD Retrieve a ajlong from an array CX // ajlong ajLong2dGet(const AjPLong2d thys, ajuint elem1, ajuint elem2) { AjPLong t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad ajlong array index [%d][%d]\n",elem1, elem2); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][]\n",elem1); return ajLongGet(t,elem2); } ID ajLong2dPut TY public MO ajarr LB core XX DE Load a ajlong 2d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPLong2d* PD Pointer to the ajlong array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r v ajlong PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPLong2d CD Load a ajlong array element CX // AjBool ajLong2dPut(AjPLong2d *thys, ajuint elem1, ajuint elem2, ajlong v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d]\n",elem1, elem2); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajLongNew(); return ajLongPut(&(*thys)->Ptr[elem1],elem2,v); } arrLong2dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajLongNew(); ajLongPut(&(*thys)->Ptr[elem1],elem2,v); return ajTrue; } ID arrLong2dResize TY static MO ajarr LB core XX DE Resize a ajlong array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPLong2d* PD Pointer to the ajlong array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrLong2dResize(AjPLong2d *thys, ajuint size) { AjPLong2d nthys; AjPLong2d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize ajlong array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajLong2dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPLong)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPLong)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajLongDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr2dResize++; return ajTrue; } ID ajLong2dLen TY public MO ajarr LB core XX DE Get lengths of 2d ajlong array XX PN [1] PA r thys const AjPLong2d PD Pointer to the ajlong array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX RT void RD RX // void ajLong2dLen(const AjPLong2d thys, ajuint* len1, ajuint* len2) { AjPLong t; ajuint i; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t=thys->Ptr[i])) *len2 = (*len2 > t->Len) ? *len2 : t->Len; return; } ID ajLong2dLong TY public MO ajarr LB core XX DE Convert AjPLong2d to ajlong XX PN [1] PA r thys const AjPLong2d PD Pointer to the ajlong array. PX RT ajlong** RD converted values. RX CA cast CT AjPLong2d CD Retrieve internal pointer CX // ajlong** ajLong2dLong(const AjPLong2d thys) { AjPLong t = NULL; ajlong **array; ajuint d1; ajuint d2; ajuint i; ajLong2dLen(thys,&d1,&d2); AJCNEW(array,d1); for(i=0;iPtr[i])) memmove(array[i],t->Ptr,t->Len*sizeof(ajlong)); } return array; } ID ajLong3dNew TY public MO ajarr LB core XX DE Default constructor for empty AJAX 3D ajlong arrays. XX RT AjPLong3d RD Pointer to an empty ajlong array structure RX CA new CT AjPLong3d CD Default constructor CX // AjPLong3d ajLong3dNew(void) { AjPLong3d thys; ajuint i; AJNEW0(thys); thys->Ptr = AJALLOC0(RESERVED_SIZE*sizeof(AjPLong2d)); thys->Len = 0; thys->Res = RESERVED_SIZE; for(i=0;iPtr[i] = NULL; return thys; } ID ajLong3dNewRes TY public MO ajarr LB core XX DE Constructor given an initial reserved size. XX PN [1] PA r size ajuint PD Reserved size 1st dim PX RT AjPLong3d RD Pointer to an empty ajlong 3d array struct of RD specified size. RX CA new CT AjPLong3d CD Constructor with reserved size CX // AjPLong3d ajLong3dNewRes(ajuint size) { AjPLong3d thys; ajuint i; size = ajRound(size,RESERVED_SIZE); AJNEW0(thys); thys->Ptr = AJALLOC0(size*sizeof(AjPLong2d)); thys->Len = 0; thys->Res = size; for(i=0;iPtr[i] = NULL; return thys; } ID ajLong3dDel TY public MO ajarr LB core XX DE Default destructor for AJAX ajlong arrays. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA d thys AjPLong3d* PD Pointer to the ajlong array to be deleted. PD The pointer is always deleted. PX RT void RD RX CA delete CT AjPLong3d CD Default destructor CX // void ajLong3dDel(AjPLong3d *thys) { ajint i; if(!thys || !*thys) return; for(i=(*thys)->Res-1;i>-1;--i) if((*thys)->Ptr[i]) ajLong2dDel(&((*thys)->Ptr[i])); AJFREE((*thys)->Ptr); AJFREE(*thys); *thys = NULL; arr3dFreeCount++; return; } ID ajLong3dGet TY public MO ajarr LB core XX DE Retrieve an element from an AJAX 3d ajlong array. DE DE If the given array is a NULL pointer, simply returns. XX PN [1] PA r thys const AjPLong3d PD Pointer to the ajlong array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX RT ajlong RD contents of array element RX CA cast CT AjPLong3d CD Retrieve a ajlong from an array CX // ajlong ajLong3dGet(const AjPLong3d thys, ajuint elem1, ajuint elem2, ajuint elem3) { AjPLong2d t; if(!thys || elem1>=thys->Len) ajErr("Attempt to access bad ajlong array index [%d][%d][%d]\n",elem1, elem2,elem3); t = thys->Ptr[elem1]; if(!t) ajErr("Attempt to access bad 1st dimension [%d][][]\n",elem1); return ajLong2dGet(t,elem2,elem3); } ID ajLong3dPut TY public MO ajarr LB core XX DE Load a ajlong 3d array element. DE DE If the given array is a NULL pointer an error is generated. DE If the array is of insufficient size then the array is extended. DE Negative indices generate an error. XX PN [1] PA w thys AjPLong3d* PD Pointer to the ajlong array. PX PN [2] PA r elem1 ajuint PD array element. PX PN [3] PA r elem2 ajuint PD array element. PX PN [4] PA r elem3 ajuint PD array element. PX PN [5] PA r v ajlong PD value to load. PX RT AjBool RD true if any array was extended. RX CA modify CT AjPLong3d CD Load a ajlong array element CX // AjBool ajLong3dPut(AjPLong3d *thys, ajuint elem1, ajuint elem2, ajuint elem3, ajlong v) { if(!thys || !*thys) ajErr("Attempt to write to illegal array value [%d][%d][%d]\n",elem1, elem2,elem3); if(elem1 < (*thys)->Res) { if(elem1>=(*thys)->Len) (*thys)->Len = elem1+1; if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajLong2dNew(); return ajLong2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); } arrLong3dResize(thys, elem1); if(!(*thys)->Ptr[elem1]) (*thys)->Ptr[elem1] = ajLong2dNew(); ajLong2dPut(&(*thys)->Ptr[elem1],elem2,elem3,v); return ajTrue; } ID arrLong3dResize TY static MO ajarr LB core XX DE Resize a ajlong array. DE DE If the given array is a NULL pointer an error is generated. DE Negative indices generate an error. XX PN [1] PA w thys AjPLong3d* PD Pointer to the ajlong array. PX PN [2] PA r size ajuint PD new size. PX RT AjBool RD true if the array was extended. RX // static AjBool arrLong3dResize(AjPLong3d *thys, ajuint size) { AjPLong3d nthys; AjPLong3d p = NULL; ajuint s; ajuint clen; ajuint limit; ajuint i; if(!thys || !*thys) ajErr("Illegal attempt to resize ajlong array"); clen = ajRound((*thys)->Len-1,RESERVED_SIZE); s = ajRound(size+1,RESERVED_SIZE); if(s <= clen) return ajFalse; /*ajDebug("ajLong3dResize %d (%d) -> %d (%d)\n", (*thys)->Len, clen, size, s);*/ p = *thys; AJNEW0(nthys); nthys->Ptr = AJALLOC0(s*sizeof(AjPLong2d)); nthys->Res = s; if(size < p->Len) limit = size+1; else limit = p->Len; memmove(nthys->Ptr,p->Ptr,limit*sizeof(AjPLong2d)); i = nthys->Len = size+1; for(;iRes;++i) if(p->Ptr[i]) ajLong2dDel(&p->Ptr[i]); AJFREE(p->Ptr); AJFREE(p); *thys = nthys; arr3dResize++; return ajTrue; } ID ajLong3dLen TY public MO ajarr LB core XX DE Get lengths of 3d ajlong array XX PN [1] PA r thys const AjPLong3d PD Pointer to the ajlong array. PX PN [2] PA w len1 ajuint* PD Length of 1st dim PX PN [3] PA w len2 ajuint* PD Length of 2nd dim PX PN [4] PA w len3 ajuint* PD Length of 3rd dim PX RT void RD RX // void ajLong3dLen(const AjPLong3d thys, ajuint* len1, ajuint* len2, ajuint* len3) { AjPLong2d t2; AjPLong t1; ajuint i; ajuint j; ajuint v; *len1 = thys->Len; *len2 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) *len2 = (*len2 > t2->Len) ? *len2 : t2->Len; *len3 = 0; for(i=0;i<*len1;++i) if((t2=thys->Ptr[i])) { v = t2->Len; for(j=0;jPtr[j])) *len3 = (*len3 > t1->Len) ? *len3 : t1->Len; } return; } ID ajLong3dLong TY public MO ajarr LB core XX DE Convert AjPLong3d to ajlong XX PN [1] PA r thys const AjPLong3d PD Pointer to the ajlong array. PX RT ajlong*** RD converted values. RX CA cast CT AjPLong3d CD Retrieve internal pointer CX // ajlong*** ajLong3dLong(const AjPLong3d thys) { AjPLong2d t2 = NULL; AjPLong t1 = NULL; ajlong ***array; ajuint d1; ajuint d2; ajuint d3; ajuint i; ajuint j; ajLong3dLen(thys,&d1,&d2,&d3); AJCNEW0(array,d1); for(i=0;iPtr[i]; for(j=0;j=t2->Len) continue; if((t1=t2->Ptr[j])) memmove(array[i][j],t1->Ptr, t1->Len*sizeof(ajlong)); } } } return array; } ID ajArrExit TY public MO ajarr LB core XX DE Cleanup of array handling internals, and debug report of memory use XX RT void RD RX // void ajArrExit(void) { ajRegFree(&floatRegNum); ajDebug("Array usage (bytes): %Ld allocated, %Ld freed, %Ld in use\n", arrAlloc, arrFree, (arrAlloc - arrFree)); ajDebug("Array usage (number): %Ld allocated, %Ld freed, %Ld resized," " %Ld in use\n", arrTotal, arrFreeCount, arrResize, arrCount); ajDebug("Array usage 2D (bytes): %Ld allocated, %Ld freed, %Ld in use\n", arr2dAlloc, arr2dFree, (arr2dAlloc - arr2dFree)); ajDebug("Array usage 2D (number): %Ld allocated, %Ld freed, %Ld resized," " %Ld in use\n", arr2dTotal, arr2dFreeCount, arr2dResize, arr2dCount); ajDebug("Array usage 3D (bytes): %Ld allocated, %Ld freed, %Ld in use\n", arr3dAlloc, arr3dFree, (arr3dAlloc - arr3dFree)); ajDebug("Array usage 3D (number): %Ld allocated, %Ld freed, %Ld resized," " %Ld in use\n", arr3dTotal, arr3dFreeCount, arr3dResize, arr3dCount); return; } ID ajAssemNew TY public MO ajassem LB core XX DE Assem data constructor XX RT AjPAssem RD New object RX // AjPAssem ajAssemNew(void) { AjPAssem ret; AJNEW0(ret); ret->Contigs = ajTablestrNewCaseConst(16); ret->ContigsIgnored = ajTablestrNew(10); ret->ContigsOrder = ajListNew(); ret->Reads = ajListNew(); ret->Readgroups = ajTablestrNewConst(16); ajTableSetDestroyvalue(ret->Readgroups, (void(*)(void**))&assemReadgroupDel); return ret; } ID ajAssemDel TY public MO ajassem LB core XX DE Assem data destructor XX PN [1] PA d Passem AjPAssem* PD Assem data object to delete PX RT void RD RX // void ajAssemDel(AjPAssem *Passem) { AjPAssem assem = NULL; AjPAssemContig contig = NULL; AjPAssemRead r = NULL; AjPAssemTag tag = NULL; AjPAssemContig* contigs = NULL; ajint i = 0; if(!Passem) return; if(!(*Passem)) return; assem = *Passem; ajStrDel(&assem->Id); ajStrDel(&assem->Db); ajStrDel(&assem->Setdb); ajStrDel(&assem->Full); ajStrDel(&assem->Qry); ajStrDel(&assem->Formatstr); ajStrDel(&assem->Filename); ajStrDel(&assem->Textptr); ajSeqBamHeaderDel(&assem->BamHeader); while(ajListPop(assem->Reads, (void**) &r)) { ajAssemreadDel(&r); } ajListFree(&assem->Reads); ajTableToarrayValues(assem->Contigs, (void***)&contigs); while (contigs[i]) /* contigs */ { contig = contigs[i++]; ajStrDel(&contig->Name); ajStrDel(&contig->Consensus); ajStrDel(&contig->ConsensusQ); ajStrDel(&contig->AssemblyID); ajStrDel(&contig->URI); ajStrDel(&contig->Species); ajStrDel(&contig->MD5); while(ajListPop(contig->Tags, (void**) &tag)) { ajStrDel(&tag->Comment); ajStrDel(&tag->Name); AJFREE(tag); } ajListFree(&contig->Tags); AJFREE(contig); } AJFREE(assem->ContigArray); ajTableDel(&assem->Contigs); ajTableFree(&assem->ContigsIgnored); ajListFree(&assem->ContigsOrder); ajTableDel(&assem->Readgroups); AJFREE(*Passem); AJFREE(contigs); *Passem = NULL; return; } ID ajAssemGetId TY public MO ajassem LB core XX DE Return the identifier XX PN [1] PA r assem const AjPAssem PD Assembly PX RT const AjPStr RD Returned id RX // const AjPStr ajAssemGetId(const AjPAssem assem) { return assem->Id; } ID ajAssemGetQryC TY public MO ajassem LB core XX DE Returns the query string of an assembly data object. DE Because this is a pointer to the real internal string DE the caller must take care not to change the character string in any way. DE If the string is to be changed (case for example) then it must first DE be copied. XX PN [1] PA r assem const AjPAssem PD Assem data object. PX RT const char* RD Query as a character string. RX // const char* ajAssemGetQryC(const AjPAssem assem) { return MAJSTRGETPTR(ajAssemGetQryS(assem)); } ID ajAssemGetQryS TY public MO ajassem LB core XX DE Returns the query string of an assembly data object. DE Because this is a pointer to the real internal string DE the caller must take care not to change the character string in any way. DE If the string is to be changed (case for example) then it must first DE be copied. XX PN [1] PA r assem const AjPAssem PD Assem data object. PX RT const AjPStr RD Query as a string. RX // const AjPStr ajAssemGetQryS(const AjPAssem assem) { ajDebug("ajAssemGetQryS '%S'\n", assem->Qry); if(ajStrGetLen(assem->Qry)) return assem->Qry; assemMakeQry(assem, &assemTempQry); return assemTempQry; } ID ajAssemGetSortorderC TY public MO ajassem LB core XX DE Returns sort-order name of the given assembly XX PN [1] PA r assem const AjPAssem PD assembly PX RT const char* RD sort-order name RX // const char* ajAssemGetSortorderC(const AjPAssem assem) { if(!assem) return NULL; return sortorderNames[assem->SO]; } ID assemMakeQry TY static MO ajassem LB core XX DE Sets the query for an assembly data object. XX PN [1] PA r thys const AjPAssem PD Assem data object PX PN [2] PA w qry AjPStr* PD Query string in full PX RT void RD RX // static void assemMakeQry(const AjPAssem thys, AjPStr* qry) { ajDebug("assemMakeQry (Id <%S> Formatstr <%S> Db <%S> " "Filename <%S>)\n", thys->Id, thys->Formatstr, thys->Db, thys->Filename); /* ajAssemTrace(thys); */ if(ajStrGetLen(thys->Db)) ajFmtPrintS(qry, "%S-id:%S", thys->Db, thys->Id); else { ajFmtPrintS(qry, "%S::%S:%S", thys->Formatstr, thys->Filename,thys->Id); } ajDebug(" result: <%S>\n", *qry); return; } ID ajAssemClear TY public MO ajassem LB core XX DE Resets all data for an assembly data object so that it can be reused. XX PN [1] PA u assem AjPAssem PD assem data PX RT void RD RX // void ajAssemClear(AjPAssem assem) { AjPAssemRead r = NULL; if(MAJSTRGETLEN(assem->Id)) ajStrSetClear(&assem->Id); if(MAJSTRGETLEN(assem->Db)) ajStrSetClear(&assem->Db); if(MAJSTRGETLEN(assem->Setdb)) ajStrSetClear(&assem->Setdb); if(MAJSTRGETLEN(assem->Full)) ajStrSetClear(&assem->Full); if(MAJSTRGETLEN(assem->Qry)) ajStrSetClear(&assem->Qry); if(MAJSTRGETLEN(assem->Formatstr)) ajStrSetClear(&assem->Formatstr); if(MAJSTRGETLEN(assem->Filename)) ajStrSetClear(&assem->Filename); ajStrDel(&assem->Textptr); while(ajListPop(assem->Reads, (void**) &r)) { ajAssemreadDel(&r); } assem->Count = 0; assem->Fpos = 0L; assem->Format = 0; assem->Hasdata = ajFalse; return; } ID ajAssemReset TY public MO ajassem LB core XX DE Resets read data for an assembly data object so that it can be reused. XX PN [1] PA u assem AjPAssem PD assem data PX RT void RD RX // void ajAssemReset(AjPAssem assem) { AjPAssemRead r = NULL; while(ajListPop(assem->Reads, (void**) &r)) { ajAssemreadDel(&r); } return; } ID ajAssemSetContigattributes TY public MO ajassem LB core XX DE Set contig attributes uri, md5, species and assemblyid DE using the values provided in contigtags table. XX PN [1] PA u assem AjPAssem PD Assembly object PX PN [2] PA r tags const AjPTable PD Table of tables for contig tags. PD Main table have an entry for each contig. PD Sub-tables include tag values for a contig. PX RT void RD RX // void ajAssemSetContigattributes(AjPAssem assem, const AjPTable tags) { char** refseqnames=NULL; char* refseq; AjPTable* tagtables=NULL; AjPAssemContig c = NULL; AjPTable hline; AjPTable contigs; int i=0; if(tags == 0 || assem==0) return; ajDebug("assemSetContigAttributes\n"); contigs = assem->Contigs; ajTableToarrayKeysValues(tags, (void***)&refseqnames, (void***)&tagtables); while(refseqnames[i]) { refseq = refseqnames[i]; hline = tagtables[i++]; c = ajTableFetchmodC(contigs, refseq); if(!c) { ajDebug("ref seq '%s' listed in contigstags table " "but not in actual contig list of the assembly", refseq); continue; } if(ajTableFetchC(hline,"UR")) c->URI = ajStrNewC(ajTableFetchmodC(hline,"UR")); if(ajTableFetchC(hline,"M5")) c->MD5 = ajStrNewC(ajTableFetchmodC(hline,"M5")); if(ajTableFetchC(hline,"SP")) c->Species = ajStrNewC(ajTableFetchmodC(hline,"SP")); if(ajTableFetchC(hline,"AS")) c->AssemblyID = ajStrNewC(ajTableFetchmodC(hline,"AS")); } AJFREE(refseqnames); AJFREE(tagtables); return; } ID ajAssemSetReadgroups TY public MO ajassem LB core XX DE Set assembly readgroups using the values in readgrouptags table XX PN [1] PA u assem AjPAssem PD Assembly object PX PN [2] PA r tags const AjPTable PD Table of tables for readgroup tags. PD Main table have an entry for each read-group. PD Sub-tables include tag values for a read-group. PX RT void RD RX // void ajAssemSetReadgroups(AjPAssem assem, const AjPTable tags) { char** rgids=NULL; AjPTable* tagtables=NULL; AjPAssemReadgroup rg = NULL; AjPTable hline = NULL; AjPStr tmp = NULL; int i=0; if(tags == 0 || assem==0) return; ajDebug("assemSetReadgroups\n"); ajTableToarrayKeysValues(tags, (void***)&rgids, (void***)&tagtables); while(rgids[i]) { AJNEW0(rg); rg->ID = ajStrNewC(rgids[i]); hline = tagtables[i++]; if(ajTableFetchC(hline,"CN")) rg->CN = ajStrNewC(ajTableFetchmodC(hline,"CN")); if(ajTableFetchC(hline,"DS")) rg->Desc = ajStrNewC(ajTableFetchmodC(hline,"DS")); if(ajTableFetchC(hline,"DT")) rg->Date = ajStrNewC(ajTableFetchmodC(hline,"DT")); if(ajTableFetchC(hline,"FO")) rg->FlowOrder = ajStrNewC(ajTableFetchmodC(hline,"FO")); if(ajTableFetchC(hline,"KS")) rg->KeySeq = ajStrNewC(ajTableFetchmodC(hline,"KS")); if(ajTableFetchC(hline,"LB")) rg->Library = ajStrNewC(ajTableFetchmodC(hline,"LB")); if(ajTableFetchC(hline,"PG")) rg->Programs = ajStrNewC(ajTableFetchmodC(hline,"PG")); if(ajTableFetchC(hline,"PI")) { tmp = ajStrNewC(ajTableFetchmodC(hline,"PI")); ajStrToInt(tmp, &rg->Isize); ajStrDel(&tmp); } if(ajTableFetchC(hline,"PL")) rg->Platform = ajAssemplatformGetType( ajTableFetchmodC(hline,"PL")); if(ajTableFetchC(hline,"PU")) rg->Unit = ajStrNewC(ajTableFetchmodC(hline,"PU")); if(ajTableFetchC(hline,"SM")) rg->Sample = ajStrNewC(ajTableFetchmodC(hline,"SM")); ajTablePut(assem->Readgroups, rg->ID, rg); } AJFREE(rgids); AJFREE(tagtables); return; } ID ajAssemreadDel TY public MO ajassem LB core XX DE Delete assembly read/alignment records XX PN [1] PA d Passemread AjPAssemRead* PD Assembly read object to delete PX RT void RD RX // void ajAssemreadDel(AjPAssemRead *Passemread) { AjPAssemRead r = NULL; AjPAssemTag tag = NULL; if(!Passemread) return; if(!(*Passemread)) return; r = *Passemread; ajStrDel(&r->File); ajStrDel(&r->Name); ajStrDel(&r->Cigar); ajStrDel(&r->Seq); ajStrDel(&r->SeqQ); ajStrDel(&r->Technology); ajStrDel(&r->Template); while(ajListPop(r->Tags, (void**) &tag)) { ajStrDel(&tag->Comment); ajStrDel(&tag->Name); AJFREE(tag); } ajListFree(&r->Tags); AJFREE(r); *Passemread = NULL; return; } ID ajAssemreadGetAlignmentend TY public MO ajassem LB core XX DE 1-based inclusive rightmost position of the clipped sequence, DE or 0 if read unmapped XX PN [1] PA r r const AjPAssemRead PD read PX RT ajint RD end position of the alignment on the reference sequence RX // ajint ajAssemreadGetAlignmentend(const AjPAssemRead r) { AjPCigar cigar = NULL; ajint ret=0; if(ajAssemreadGetFlagUnmapped(r)) return 0; cigar = ajCigarNewS(r->Cigar); ret = r->y1 + ajCigarGetReferenceLength(cigar); ajCigarDel(&cigar); return ret; } ID ajAssemreadGetAlignmentstart TY public MO ajassem LB core XX DE Return alignment start (1-based) XX PN [1] PA r r const AjPAssemRead PD read PX RT ajint RD start position of the alignment on the reference sequence RX // ajint ajAssemreadGetAlignmentstart(const AjPAssemRead r) { if(ajAssemreadGetFlagUnmapped(r)) return 0; if(r->Reversed) return r->y1; return r->x1; } ID ajAssemreadGetFlagFirstofpair TY public MO ajassem LB core XX DE Return whether the read is the first read in a pair XX PN [1] PA r r const AjPAssemRead PD read PX RT AjBool RD true if the read is the first read in a pair RX // AjBool ajAssemreadGetFlagFirstofpair(const AjPAssemRead r) { return (r->Flag & BAM_FREAD1) != 0; } ID ajAssemreadGetFlagNegativestrand TY public MO ajassem LB core XX DE Return strand of the query (false for forward; true for reverse strand) XX PN [1] PA r r const AjPAssemRead PD read PX RT AjBool RD true if the read is reverse strand RX // AjBool ajAssemreadGetFlagNegativestrand(const AjPAssemRead r) { return (r->Flag & BAM_FREVERSE) != 0; } ID ajAssemreadGetFlagPaired TY public MO ajassem LB core XX DE Return whether the read is paired in sequencing, DE no matter whether it is mapped in a pair XX PN [1] PA r r const AjPAssemRead PD read PX RT AjBool RD true if the read is paired RX // AjBool ajAssemreadGetFlagPaired(const AjPAssemRead r) { return (r->Flag & BAM_FPAIRED) != 0; } ID ajAssemreadGetFlagUnmapped TY public MO ajassem LB core XX DE Return whether the read is unmapped XX PN [1] PA r r const AjPAssemRead PD read PX RT AjBool RD true if the read is unmapped RX // AjBool ajAssemreadGetFlagUnmapped(const AjPAssemRead r) { return (r->Flag & BAM_FUNMAP) != 0; } ID ajAssemreadSetAlignblocks TY public MO ajassem LB core XX DE Returns blocks of the read sequence that have been aligned directly to the DE reference sequence. Clipped portions of the read and inserted and deleted DE bases (vs. the reference) are not represented in the alignment blocks. DE DE Results are stored in the AlignmentBlocks attribute for reuse. XX PN [1] PA u r AjPAssemRead PD read/alignment PD 8 PX RT AjPList RD list of alignment blocks RX // AjPList ajAssemreadSetAlignblocks(AjPAssemRead r) { AjPCigar cigar = NULL; AjPList alignmentBlocks=NULL; int readBase=0; int refBase=0; int i=0; int length=0; AjPAssemReadalignmentblock ablock=NULL; if (r->AlignmentBlocks != NULL) return r->AlignmentBlocks; /* todo: we should store the cigar object as part of the read? */ cigar = ajCigarNewS(r->Cigar); if (cigar == NULL) return NULL; alignmentBlocks = ajListNew(); readBase = 1; refBase = ajAssemreadGetAlignmentstart(r); for (i=0; in; i++) { switch (cigar->cigoperator[i]) { case 'H' : break; /* ignore hard clips */ case 'P' : break; /* ignore pads */ case 'S' : readBase += cigar->length[i]; break; /* soft clip read bases */ case 'N' : refBase += cigar->length[i]; break; /* reference skip */ case 'D' : refBase += cigar->length[i]; break; case 'I' : readBase += cigar->length[i]; break; case 'M' : case '=' : case 'X' : length = cigar->length[i]; AJNEW0(ablock); ablock->readStart = readBase; if(refBase<=0) ajErr("referenceBlockStart: %d is <= 0", refBase); ablock->referenceStart = refBase; ablock->length = length; ajListPushAppend(alignmentBlocks, ablock); ablock=NULL; readBase += length; refBase += length; break; default : ajErr("unrecognised cigar op: " + cigar->cigoperator[i]); } } ajCigarDel(&cigar); r->AlignmentBlocks = alignmentBlocks; return alignmentBlocks; } ID assemReadgroupDel TY static MO ajassem LB core XX DE Delete assembly read-group data XX PN [1] PA d Prg AjPAssemReadgroup* PD read-group object to delete PX RT void RD RX // static void assemReadgroupDel(AjPAssemReadgroup *Prg) { AjPAssemReadgroup rg = NULL; if(!Prg || !(*Prg)) return; rg = *Prg; ajStrDel(&rg->CN); ajStrDel(&rg->Date); ajStrDel(&rg->Desc); ajStrDel(&rg->FlowOrder); ajStrDel(&rg->ID); ajStrDel(&rg->KeySeq); ajStrDel(&rg->Library); ajStrDel(&rg->Programs); ajStrDel(&rg->Sample); ajStrDel(&rg->Unit); AJFREE(rg); *Prg = NULL; return; } ID ajAssemreadgroupGetPlatformname TY public MO ajassem LB core XX DE Returns platform name of the given read-group XX PN [1] PA r rg const AjPAssemReadgroup PD read group PX RT const char* RD platform name RX // const char* ajAssemreadgroupGetPlatformname(const AjPAssemReadgroup rg) { if(!rg) return NULL; return platfNames[rg->Platform]; } ID ajAssemplatformGetType TY public MO ajassem LB core XX DE Returns platform type enumeration for the given platform XX PN [1] PA r name const char* PD platform name PX RT AjEAssemPlatform RD platform type RX // AjEAssemPlatform ajAssemplatformGetType(const char* name) { int i=0; while(platfNames[i]) { if(ajCharCmpCase(platfNames[i], name)==0) return i; i++; } return 0; } ID ajAssemsortorderGetType TY public MO ajassem LB core XX DE Returns sort-order type for the given sort-order-name XX PN [1] PA r name const char* PD sort order name PX RT AjEAssemSortOrder RD sort order type RX // AjEAssemSortOrder ajAssemsortorderGetType(const char* name) { int i=0; if(!name) return 0; while(sortorderNames[i]) { if(ajCharCmpCase(sortorderNames[i], name)==0) return i; i++; } return 0; } ID ajAssemExit TY public MO ajassem LB core XX DE Cleans up assembly processing internal memory XX RT void RD RX // void ajAssemExit(void) { ajAsseminExit(); ajAssemoutExit(); return; } ID assemAccess TY list MO ajassemdb LB ajaxdb XX DE Functions to access each database or assembly access method XX // static AjOAssemAccess assemAccess[] = { /* Name AccessFunction FreeFunction Qlink Description Alias Entry Query All Chunk Padding */ {NULL, NULL, NULL, NULL, NULL, AJFALSE, AJFALSE, AJFALSE, AJFALSE, AJFALSE, AJFALSE}, {NULL, NULL, NULL, NULL, NULL, AJFALSE, AJFALSE, AJFALSE, AJFALSE, AJFALSE, AJFALSE} }; ID ajAssemdbInit TY public MO ajassemdb LB ajaxdb XX DE Initialise assembly database internals XX RT void RD RX // void ajAssemdbInit(void) { AjPTable table; ajuint i = 0; table = ajAssemaccessGetDb(); while(assemAccess[i].Name) { ajCallTableRegister(table, assemAccess[i].Name, (void*) &assemAccess[i]); i++; } return; } ID ajAssemdbPrintAccess TY public MO ajassemdb LB ajaxdb XX DE Reports the internal data structures XX PN [1] PA u outf AjPFile PD Output file PX PN [2] PA r full AjBool PD Full report (usually ajFalse) PX RT void RD RX // void ajAssemdbPrintAccess(AjPFile outf, AjBool full) { ajint i = 0; ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "# Assembly access methods\n"); ajFmtPrintF(outf, "# Name Alias Entry Query All Description\n"); ajFmtPrintF(outf, "\n"); ajFmtPrintF(outf, "method {\n"); for(i=0; assemAccess[i].Name; i++) if(full || !assemAccess[i].Alias) ajFmtPrintF(outf, " %-10s %5B %5B %5B %5B \"%s\"\n", assemAccess[i].Name, assemAccess[i].Alias, assemAccess[i].Entry, assemAccess[i].Query, assemAccess[i].All, assemAccess[i].Desc); ajFmtPrintF(outf, "}\n\n"); return; } ID ajAssemdbExit TY public MO ajassemdb LB ajaxdb XX DE Cleans up assembly database processing internal memory XX RT void RD RX // void ajAssemdbExit(void) { return; } ID ajAsseminNew TY public MO ajassemread LB core XX DE Creates a new assembly input object. XX RT AjPAssemin RD New assembly input object. RX CA new CT AjPAssemin CD Default constructor CX // AjPAssemin ajAsseminNew(void) { AjPAssemin pthis; AJNEW0(pthis); pthis->Input = ajTextinNewDatatype(AJDATATYPE_ASSEMBLY); return pthis; } ID ajAsseminDel TY public MO ajassemread LB core XX DE Deletes an assembly input object. XX PN [1] PA d pthis AjPAssemin* PD Assembly input PX RT void RD RX CA delete CT AjPAssemin CD Default destructor CX // void ajAsseminDel(AjPAssemin* pthis) { AjPAssemin thys; AjPSeqBamBgzf gzfile = NULL; if(!pthis) return; if(!*pthis) return; thys = *pthis; ajDebug("ajAsseminDel called qry:'%S'\n", thys->Input->Qry); if(thys->BamInput) { gzfile = thys->Input->TextData; ajSeqBamBgzfClose(gzfile); } ajTextinDel(&thys->Input); AJFREE(*pthis); return; } ID ajAsseminClear TY public MO ajassemread LB core XX DE Clears an assembly input object back to "as new" condition, except DE for the query list which must be preserved. XX PN [1] PA w thys AjPAssemin PD Assembly input PX RT void RD RX CA modify CT AjPAssemin CD Resets ready for reuse. CX // void ajAsseminClear(AjPAssemin thys) { ajDebug("ajAsseminClear called\n"); if(!thys) return; ajTextinClear(thys->Input); thys->Loading = ajFalse; return; } ID ajAsseminQryC TY public MO ajassemread LB core XX DE Resets an assembly input object using a new Universal DE Query Address XX PN [1] PA u thys AjPAssemin PD Assembly input object. PX PN [2] PA r txt const char* PD Query PX RT void RD RX // void ajAsseminQryC(AjPAssemin thys, const char* txt) { ajAsseminClear(thys); ajStrAssignC(&thys->Input->Qry, txt); return; } ID ajAsseminQryS TY public MO ajassemread LB core XX DE Resets an assembly input object using a new Universal DE Query Address XX PN [1] PA u thys AjPAssemin PD Assembly input object. PX PN [2] PA r str const AjPStr PD Query PX RT void RD RX // void ajAsseminQryS(AjPAssemin thys, const AjPStr str) { ajAsseminClear(thys); ajStrAssignS(&thys->Input->Qry, str); return; } ID ajAsseminTrace TY public MO ajassemread LB core XX DE Debug calls to trace the data in an assembly input object. XX PN [1] PA r thys const AjPAssemin PD Assembly input object. PX RT void RD RX // void ajAsseminTrace(const AjPAssemin thys) { ajDebug("assembly input trace\n"); ajDebug("====================\n\n"); ajTextinTrace(thys->Input); return; } ID ajAsseminLoad TY public MO ajassemread LB core XX DE If the file is not yet open, calls asseminQryProcess to convert the query DE into an open file stream. DE DE Uses asseminLoad for the actual file reading. DE DE Returns the results in the AjPAssem object. XX PN [1] PA u assemin AjPAssemin PD assembly data input definitions PX PN [2] PA w assem AjPAssem PD assembly data returned. PX RT AjBool RD ajTrue on success. RX CA input CT AjPAssem CD Master assembly data input, calls specific functions for file access type and assembly data format. CX // AjBool ajAsseminLoad(AjPAssemin assemin, AjPAssem assem) { AjBool ret = ajFalse; AjPQueryList node = NULL; AjBool listdata = ajFalse; AjPTextin input = assemin->Input; AjPFilebuff buff = input->Filebuff; ajDebug("ajAsseminLoad '%F' EOF: %B " "records: %u dataread: %B datadone: %B\n", ajFilebuffGetFile(buff), ajFilebuffIsEof(buff), input->Records, input->Dataread, input->Datadone); if(buff) { /* (a) if file still open, keep reading */ ajDebug("ajAsseminLoad: input file '%F' still there, try again\n", assemin->Input->Filebuff->File); ret = asseminLoad(assemin, assem); ajDebug("ajAsseminLoad: open buffer qry: '%S' returns: %B\n", assemin->Input->Qry, ret); } else { /* (b) if we have a list, try the next query in the list */ if(ajListGetLength(assemin->Input->List)) { listdata = ajTrue; ajListPop(assemin->Input->List, (void**) &node); ajDebug("++pop from list '%S'\n", node->Qry); ajAsseminQryS(assemin, node->Qry); ajDebug("++SAVE ASSEMIN '%S' '%S' %d\n", assemin->Input->Qry, assemin->Input->Formatstr, assemin->Input->Format); asseminQryRestore(assemin, node); ajStrDel(&node->Qry); ajStrDel(&node->Formatstr); AJFREE(node); ajDebug("ajAsseminLoad: open list, try '%S'\n", assemin->Input->Qry); if(!asseminQryProcess(assemin, assem) && !ajListGetLength(assemin->Input->List)) return ajFalse; ret = asseminLoad(assemin, assem); ajDebug("ajAsseminLoad: list qry: '%S' returns: %B\n", assemin->Input->Qry, ret); } else { ajDebug("ajAsseminLoad: no file yet - test query '%S'\n", assemin->Input->Qry); /* (c) Must be a query - decode it */ if(!asseminQryProcess(assemin, assem) && !ajListGetLength(assemin->Input->List)) { return ajFalse; } if(ajListGetLength(assemin->Input->List)) /* could be a new list */ listdata = ajTrue; ret = asseminLoad(assemin, assem); ajDebug("ajAsseminLoad: new qry: '%S' returns: %B\n", assemin->Input->Qry, ret); } } /* Now read whatever we got */ while(!ret && ajListGetLength(assemin->Input->List)) { /* Failed, but we have a list still - keep trying it */ if(listdata) ajErr("Failed to read assembly data '%S'", assemin->Input->Qry); listdata = ajTrue; ajListPop(assemin->Input->List,(void**) &node); ajDebug("++try again: pop from list '%S'\n", node->Qry); ajAsseminQryS(assemin, node->Qry); ajDebug("++SAVE (AGAIN) ASSEMIN '%S' '%S' %d\n", assemin->Input->Qry, assemin->Input->Formatstr, assemin->Input->Format); asseminQryRestore(assemin, node); ajStrDel(&node->Qry); ajStrDel(&node->Formatstr); AJFREE(node); if(!asseminQryProcess(assemin, assem)) continue; ret = asseminLoad(assemin, assem); ajDebug("ajAsseminLoad: list retry qry: '%S' returns: %B\n", assemin->Input->Qry, ret); } if(!ret) { if(listdata) ajErr("Failed to read assembly data '%S'", assemin->Input->Qry); return ajFalse; } assemDefine(assem, assemin); return ajTrue; } ID assemQueryMatch TY static MO ajassemread LB core XX DE Compares an assembly data item to a query and returns true if they match. XX PN [1] PA r thys const AjPQuery PD query. PX PN [2] PA r assem const AjPAssem PD Assembly data. PX RT AjBool RD ajTrue if the assembly data matches the query. RX // static AjBool assemQueryMatch(const AjPQuery thys, const AjPAssem assem) { AjBool tested = ajFalse; AjIList iterfield = NULL; AjIList iter = NULL; AjPQueryField field = NULL; AjBool ok = ajFalse; const AjPAssemContig c = NULL; ajDebug("assemQueryMatch '%S' fields: %Lu Case %B Done %B\n", assem->Id, ajListGetLength(thys->QueryFields), thys->CaseId, thys->QryDone); if(!thys) /* no query to test, that's fine */ return ajTrue; if(thys->QryDone) /* do we need to test here? */ return ajTrue; /* test the query field(s) */ iterfield = ajListIterNewread(thys->QueryFields); while(!ajListIterDone(iterfield)) { field = ajListIterGet(iterfield); ajDebug(" field: '%S' Query: '%S'\n", field->Field, field->Wildquery); if(ajStrMatchC(field->Field, "id")) { ajDebug(" id test: %Lu\n", ajListGetLength(assem->ContigsOrder)); iter = ajListIterNewread(assem->ContigsOrder); while(!ajListIterDone(iter)) { c = ajListIterGet(iter); ajDebug("test case %B '%S'\n", thys->CaseId, c->Name); if(thys->CaseId) { if(ajStrMatchWildS(c->Name, field->Wildquery)) { ajListIterDel(&iterfield); ajListIterDel(&iter); return ajTrue; } } else { if(ajStrMatchWildCaseS(c->Name, field->Wildquery)) { ajListIterDel(&iterfield); ajListIterDel(&iter); return ajTrue; } } } ajListIterDel(&iter); tested = ajTrue; } } ajListIterDel(&iterfield); if(!tested) /* nothing to test, so accept it anyway */ { ajDebug(" no tests: assume OK\n"); return ajTrue; } ajDebug("result: %B\n", ok); return ok; } ID assemDefine TY static MO ajassemread LB core XX DE Make sure all assembly data object attributes are defined DE using values from the assembly input object if needed XX PN [1] PA w thys AjPAssem PD Assembly data returned. PX PN [2] PA u assemin AjPAssemin PD Assembly data input definitions PX RT AjBool RD ajTrue on success. RX // static AjBool assemDefine(AjPAssem thys, AjPAssemin assemin) { /* if values are missing in the assembly object, we can use defaults from assemin or calculate where possible */ /* assign the dbname if defined in the assemin object */ if(ajStrGetLen(assemin->Input->Db)) ajStrAssignS(&thys->Db, assemin->Input->Db); return ajTrue; } ID asseminLoadFmt TY static MO ajassemread LB core XX DE Tests whether assembly data can be read using the specified format. DE Then tests whether the assembly data matches assembly data query criteria DE and checks any specified type. Applies upper and lower case. XX PN [1] PA u assemin AjPAssemin PD Assembly data input object PX PN [2] PA w assem AjPAssem PD Assembly data object PX PN [3] PA r format ajuint PD input format code PX RT ajuint RD 0 if successful. RD 1 if the query match failed. RD 2 if the assembly data type failed RD 3 if it failed to read a assembly data RX // static ajuint asseminLoadFmt(AjPAssemin assemin, AjPAssem assem, ajuint format) { AjPTextin input = assemin->Input; AjPFilebuff buff = input->Filebuff; ajDebug("++asseminLoadFmt format %d (%s) '%S'\n", format, asseminFormatDef[format].Name, input->Qry); if(!input->Dataread) input->Records = 0; /* Calling funclist asseminFormatDef() */ if((*asseminFormatDef[format].Load)(assemin, assem)) { input->Dataread = ajTrue; ajDebug("asseminLoadFmt success with format %d (%s)\n", format, asseminFormatDef[format].Name); ajDebug("id: '%S'\n", assem->Id); input->Format = format; ajStrAssignC(&input->Formatstr, asseminFormatDef[format].Name); ajStrAssignC(&assem->Formatstr, asseminFormatDef[format].Name); ajStrAssignEmptyS(&assem->Db, input->Db); ajStrAssignS(&assem->Filename, input->Filename); if(assemQueryMatch(input->Query, assem)) { /* ajAsseminTrace(assemin); */ return FMT_OK; } ajDebug("query match failed, continuing ...\n"); ajAssemClear(assem); return FMT_NOMATCH; } else { ajDebug("Testing input buffer: IsBuff: %B Eof: %B\n", ajFilebuffIsBuffered(buff), ajFilebuffIsEof(buff)); if (!ajFilebuffIsBuffered(buff) && ajFilebuffIsEof(buff)) return FMT_EOF; ajFilebuffReset(buff); ajDebug("Format %d (%s) failed, file buffer reset by asseminLoadFmt\n", format, asseminFormatDef[format].Name); /* ajFilebuffTraceFull(assemin->Filebuff, 10, 10);*/ } ajDebug("++asseminLoadFmt failed - nothing read\n"); return FMT_FAIL; } ID asseminLoad TY static MO ajassemread LB core XX DE Given data in a assemin structure, tries to read everything needed DE using the specified format or by trial and error. XX PN [1] PA u assemin AjPAssemin PD Assembly data input object PX PN [2] PA w assem AjPAssem PD Assembly data object PX RT AjBool RD ajTrue on success RX // static AjBool asseminLoad(AjPAssemin assemin, AjPAssem assem) { ajuint i; ajuint istat = 0; ajuint jstat = 0; AjPTextin input = assemin->Input; AjPFilebuff buff = input->Filebuff; AjBool ok; AjPTextAccess textaccess = input->Query->TextAccess; AjPAssemAccess assemaccess = input->Query->Access; if(!input->Records) { ajAssemClear(assem); ajDebug("asseminLoad: cleared\n"); } if(input->Single && input->Count && !input->Datacount) { /* ** One assembly data item at a time is read. ** The first assembly data item was read by ACD ** for the following ones we need to reset the AjPAssemin ** ** Single is set by the access method */ ajDebug("asseminLoad: single access - count %d - call access" " routine again\n", input->Count); /* Calling funclist asseminAccess() */ if(textaccess) { if(!(*textaccess->Access)(input)) { ajDebug("asseminLoad: (*textaccess->Access)(assemin->Input) " "*failed*\n"); return ajFalse; } } if(assemaccess) { if(!(*assemaccess->Access)(assemin)) { ajDebug("asseminLoad: (*assemaccess->Access)(assemin) " "*failed*\n"); return ajFalse; } } buff = input->Filebuff; } ajDebug("asseminLoad: assemin format %d '%S'\n", input->Format, input->Formatstr); input->Count++; if(!input->Filebuff) return ajFalse; ok = ajFilebuffIsBuffered(input->Filebuff); while(ok) { /* skip blank lines */ ok = ajBuffreadLine(input->Filebuff, &asseminReadLine); if(!ajStrIsWhite(asseminReadLine)) { ajFilebuffClear(input->Filebuff,1); break; } } if(!input->Format) { /* no format specified, try all defaults */ /*regfile = ajFileIsFile(ajFilebuffGetFile(assemin->Input->Filebuff));*/ for(i = 1; asseminFormatDef[i].Name; i++) { if(!asseminFormatDef[i].Try) /* skip if Try is ajFalse */ continue; ajDebug("asseminLoad:try format %d (%s)\n", i, asseminFormatDef[i].Name); istat = asseminLoadFmt(assemin, assem, i); switch(istat) { case FMT_OK: ajDebug("++asseminLoad OK, set format %d\n", input->Format); assemDefine(assem, assemin); return ajTrue; case FMT_BADTYPE: ajDebug("asseminload: (a1) " "asseminLoadFmt stat == BADTYPE *failed*\n"); return ajFalse; case FMT_FAIL: ajDebug("asseminLoad: (b1) " "asseminLoadFmt stat == FAIL *failed*\n"); break; /* we can try next format */ case FMT_NOMATCH: ajDebug("asseminLoad: (c1) " "asseminLoadFmt stat==NOMATCH try again\n"); break; case FMT_EOF: ajDebug("asseminLoad: (d1) " "asseminLoadFmt stat == EOF *failed*\n"); return ajFalse; /* EOF and unbuffered */ case FMT_EMPTY: ajWarn("assembly data '%S' has zero length, ignored", ajAssemGetQryS(assem)); ajDebug("asseminLoad: (e1) " "asseminLoadFmt stat==EMPTY try again\n"); break; default: ajDebug("unknown code %d from asseminLoadFmt\n", stat); } ajAssemClear(assem); if(input->Format) break; /* we read something */ ajFilebuffTrace(input->Filebuff); } if(!input->Format) { /* all default formats failed, give up */ ajDebug("asseminLoad:all default formats failed, give up\n"); return ajFalse; } ajDebug("++asseminLoad set format %d\n", input->Format); } else { /* one format specified */ ajDebug("asseminLoad: one format specified\n"); ajFilebuffSetUnbuffered(input->Filebuff); ajDebug("++asseminLoad known format %d\n", input->Format); istat = asseminLoadFmt(assemin, assem, input->Format); switch(istat) { case FMT_OK: assemDefine(assem, assemin); return ajTrue; case FMT_BADTYPE: ajDebug("asseminLoad: (a2) " "asseminLoadFmt stat == BADTYPE *failed*\n"); return ajFalse; case FMT_FAIL: ajDebug("asseminLoad: (b2) " "asseminLoadFmt stat == FAIL *failed*\n"); return ajFalse; case FMT_NOMATCH: ajDebug("asseminLoad: (c2) " "asseminLoadFmt stat == NOMATCH *try again*\n"); break; case FMT_EOF: ajDebug("asseminLoad: (d2) " "asseminLoadFmt stat == EOF *try again*\n"); if(assemin->Input->Records) ajErr("Error reading file '%F' with format '%s': " "end-of-file before end of data " "(read %u records)", ajFilebuffGetFile(input->Filebuff), asseminFormatDef[input->Format].Name, input->Records); break; /* simply end-of-file */ case FMT_EMPTY: ajWarn("assmebly data '%S' has zero length, ignored", ajAssemGetQryS(assem)); ajDebug("asseminLoad: (e2) " "asseminLoadFmt stat == EMPTY *try again*\n"); break; default: ajDebug("unknown code %d from asseminLoadFmt\n", stat); } ajAssemClear(assem); /* 1 : read, failed to match id/acc/query */ } /* failed - probably entry/accession query failed. Can we try again? */ ajDebug("asseminLoad failed - try again with format %d '%s' code %d\n", input->Format, asseminFormatDef[input->Format].Name, istat); ajDebug("Search:%B Chunk:%B Data:%x ajFileBuffEmpty:%B\n", input->Search, input->ChunkEntries, input->TextData, ajFilebuffIsEmpty(buff)); if(ajFilebuffIsEmpty(buff) && input->ChunkEntries) { if(textaccess && !(*textaccess->Access)(input)) return ajFalse; else if(assemaccess && !(*assemaccess->Access)(assemin)) return ajFalse; buff = input->Filebuff; } /* need to check end-of-file to avoid repeats */ while(input->Search && (input->TextData || !ajFilebuffIsEmpty(buff))) { jstat = asseminLoadFmt(assemin, assem, input->Format); switch(jstat) { case FMT_OK: assemDefine(assem, assemin); return ajTrue; case FMT_BADTYPE: ajDebug("asseminLoad: (a3) " "asseminLoadFmt stat == BADTYPE *failed*\n"); return ajFalse; case FMT_FAIL: ajDebug("asseminLoad: (b3) " "asseminLoadFmt stat == FAIL *failed*\n"); return ajFalse; case FMT_NOMATCH: ajDebug("asseminLoad: (c3) " "asseminLoadFmt stat == NOMATCH *try again*\n"); break; case FMT_EOF: ajDebug("asseminLoad: (d3) " "asseminLoadFmt stat == EOF *failed*\n"); return ajFalse; /* we already tried again */ case FMT_EMPTY: if(istat != FMT_EMPTY) ajWarn("assmebly data '%S' has zero length, ignored", ajAssemGetQryS(assem)); ajDebug("asseminLoad: (e3) " "asseminLoadFmt stat == EMPTY *try again*\n"); break; default: ajDebug("unknown code %d from asseminLoadFmt\n", stat); } ajAssemClear(assem); /* 1 : read, failed to match id/acc/query */ } if(input->Format) ajDebug("asseminLoad: *failed* to read assembly data %S " "using format %s\n", input->Qry, asseminFormatDef[input->Format].Name); else ajDebug("asseminLoad: *failed* to read assembly data %S " "using any format\n", assemin->Input->Qry); return ajFalse; } ID asseminReadBamHeader TY static MO ajassemread LB core XX DE Read header information from BAM files XX PN [1] PA u assemin AjPAssemin PD Assembly input object PX PN [2] PA w assem AjPAssem PD Assembly object PX RT AjPSeqBamHeader RD BAM header object on success RX // static AjPSeqBamHeader asseminReadBamHeader(AjPAssemin assemin, AjPAssem assem) { AjPFilebuff buff = NULL; AjPFile infile = NULL; AjPAssemContig contig = NULL; AjPAssemContig* contigs = NULL; AjPSeqBamBgzf gzfile = NULL; AjPSeqBamHeader header = NULL; AjPBamIndex idx = NULL; char* targetname = NULL; ajint tid; ajint filestat = 0; ajint tid_new = 0; AjPTextin input; AjIList iterfield = NULL; AjPQuery qry = NULL; AjPQueryField field = NULL; AjBool ok = ajFalse; input = assemin->Input; buff = input->Filebuff; infile = ajFilebuffGetFile(buff); qry = input->Query; ajDebug("asseminReadBamHeader ...\n"); if(!infile) return NULL; ajFileTrace(infile); ajFilebuffTrace(buff); /* reset to beginning of file - ** has at least been tested for blank lines */ filestat = ajFileSeek(infile, 0L, SEEK_SET); if(filestat != 0) { ajDebug("asseminReadBamHeader rewind failed errno %d: %s\n", errno, strerror(errno)); return NULL; } assemin->BamInput = ajTrue; gzfile = ajSeqBamBgzfNew(ajFilebuffGetFileptr(buff), "r"); assemin->Input->TextData = gzfile; header = ajSeqBamHeaderRead(gzfile); if (!header) { ajDebug("ajSeqBamHeaderReadHeader failed\n"); ajSeqBamBgzfClose(gzfile); ajFileSeek(infile,filestat,0); ajFilebuffResetPos(buff); ajFileTrace(infile); ajFilebuffTrace(buff); return NULL; } input->Records++; if (ajListGetLength(qry->QueryFields)) assemin->BamIdx = ajBamIndexLoad(ajFileGetNameC(infile)); idx = assemin->BamIdx; /* read reference sequence names and lengths */ contigs = AJCALLOC(header->n_targets, sizeof(AjPAssemContig)); for(tid=0; tid < header->n_targets; tid++) { targetname = header->target_name[tid]; ajDebug("bam target[%d] '%s'\n", tid, targetname); if(idx) { ok = ajFalse; iterfield = ajListIterNewread(qry->QueryFields); while(!ajListIterDone(iterfield)) { field = ajListIterGet(iterfield); if(ajStrMatchC(field->Field, "id")) { if(qry->CaseId) { if(ajCharMatchWildS(targetname, field->Wildquery)) ok = ajTrue; } else { if(ajCharMatchWildCaseS(targetname, field->Wildquery)) ok = ajTrue; } } } ajListIterDel(&iterfield); if(!ok) continue; assem->Count = tid_new; tid_new++; ajBamFetch(gzfile, idx, tid, assemin->cbegin, assemin->cend, assem, asseminAppendAlignmentRecs); } AJNEW0(contig); contig->Name = ajStrNewC(targetname); ajDebug("reference sequence:%S\n", contig->Name); ajTablePut(assem->Contigs, contig->Name, contig); ajListPushAppend(assem->ContigsOrder, contig); contig->Length = header->target_len[tid]; ajDebug("ref seq length:%d\n", contig->Length); contigs[tid] = contig; } assem->SO = ajAssemsortorderGetType(ajSeqBamHeaderGetSortorder(header)); ajListToarray(assem->ContigsOrder, (void***)&assem->ContigArray); AJFREE(contigs); return header; } ID asseminLoadBam TY static MO ajassemread LB core XX DE Given data in an assembly structure, tries to read everything needed DE using binary alignment/map (BAM) format. XX PN [1] PA u assemin AjPAssemin PD Assembly input object PX PN [2] PA w assem AjPAssem PD Assembly object PX RT AjBool RD ajTrue on success RX // static AjBool asseminLoadBam(AjPAssemin assemin, AjPAssem assem) { AjPTextin input = assemin->Input; AjPFilebuff buff = input->Filebuff; AjPFile infile = NULL; AjPSeqBamBgzf gzfile = NULL; AjPSeqBam b = NULL; AjPSeqBamHeader header = NULL; AjPTable contigtags = NULL; AjPTable readgroups = NULL; ajuint iread = 0; ajuint maxread = 1; ajDebug("asseminLoadBam '%F' EOF: %B records: %u " "dataread: %B datadone: %B hasdata: %B\n", ajFilebuffGetFile(buff), ajFilebuffIsEof(buff), input->Records, input->Dataread, input->Datadone, assem->Hasdata); if(input->Datadone) { return ajFalse; } infile = ajFilebuffGetFile(buff); if(!infile) return ajFalse; ajFileTrace(infile); ajFilebuffTrace(buff); if(!input->Records) { ajAssemClear(assem); assem->BamHeader = asseminReadBamHeader(assemin, assem); if(!assem->BamHeader) return ajFalse; readgroups = ajSeqBamHeaderGetReadgroupTags(assem->BamHeader); ajAssemSetReadgroups(assem, readgroups); contigtags = ajSeqBamHeaderGetRefseqTags(assem->BamHeader); ajAssemSetContigattributes(assem, contigtags); assem->SO = ajAssemsortorderGetType( ajSeqBamHeaderGetSortorder(assem->BamHeader)); ajTableSetDestroyvalue(readgroups, (void(*)(void**))&ajTableDel); ajTableDel(&readgroups); ajTableSetDestroyvalue(contigtags, (void(*)(void**))&ajTableDel); ajTableDel(&contigtags); return ajTrue; } /* ** On later calls, read a chunk of data */ /* clear current chunk */ ajDebug("continue processing: maxread %u Datacount %u\n", maxread, input->Datacount); ajAssemReset(assem); assem->Hasdata = ajTrue; iread = 0; header = assem->BamHeader; gzfile = input->TextData; if(!assemin->BamIdx) { AJNEW0(b); /* todo: should store b in an iter obj so won't need to be allocated each time before reading a bam record here */ assem->rec = asseminReadBamAlignments(gzfile, header, b); AJFREE(b->data); AJFREE(b); if(assem->rec) { ajListPushAppend(assem->Reads, assem->rec); iread++; input->Records++; input->Datacount += iread; return ajTrue; } } ajSeqBamBgzfClose(gzfile); ajSeqBamHeaderDel(&assem->BamHeader); ajBamIndexDel(&assemin->BamIdx); input->Datadone = ajTrue; ajFilebuffClear(buff, -1); buff->File->End = ajTrue; input->TextData = NULL; return ajTrue; } ID asseminReadBamAlignments TY static MO ajassemread LB core XX DE Read BAM alignment records, when a query was not made DE DE TODO: should we update this function to append only the alignments in DE the query contigs? DE samtools simply rejects any queries when there is no index found XX PN [1] PA u gzfile AjPSeqBamBgzf PD Bam file handler PX PN [2] PA u header AjPSeqBamHeader PD Bam header PX PN [3] PA u b AjPSeqBam PD Bam data PX RT AjPAssemRead RD Read data object RX // static AjPAssemRead asseminReadBamAlignments(AjPSeqBamBgzf gzfile, AjPSeqBamHeader header, AjPSeqBam b) { ajint ret = 0; AjPAssemRead r = NULL; const char* library = NULL; const char* querylib = NULL; /* TODO: not yet implemented" */ /* next BAM record */ ret = ajSeqBamRead(gzfile, b); if(ret < -1) ajErr("seqReadBamAlignments truncated file return %d\n", ret); if(ret == -1) return NULL; if (querylib) { library = ajSeqBamGetLibrary(header, b); if(strcmp(library,querylib)) { return NULL; /* fixme: should try reading the next record until a match*/ } } r = asseminBamAlignmentRec2Emboss(b); return r; } ID asseminAppendAlignmentRecs TY static MO ajassemread LB core XX DE Append BAM alignment records to the assembly object after reformatting DE the alignment data. XX PN [1] PA u b AjPSeqBam PD BAM record PX PN [2] PA u data void* PD Assembly object PX RT AjBool RD True on success RX // static AjBool asseminAppendAlignmentRecs(AjPSeqBam b, void*data) { AjPAssemRead r = NULL; AjPAssem assem = NULL; assem = (AjPAssem)data; r = asseminBamAlignmentRec2Emboss(b); if(r->Rnext == r->Reference) { r->Reference = ajTableGetLength(assem->Contigs); r->Rnext = r->Reference; } else { r->Reference = ajTableGetLength(assem->Contigs); r->Rnext = -1; /* FIXME: proper mapping needed */ } ajListPushAppend(assem->Reads, r); return ajTrue; } ID asseminBamAlignmentRec2Emboss TY static MO ajassemread LB core XX DE Load alignment records into assembly object XX PN [1] PA u b AjPSeqBam PD BAM record PX RT AjPAssemRead RD Assembly object RX // static AjPAssemRead asseminBamAlignmentRec2Emboss(AjPSeqBam b) { AjPStr cigarstr = NULL; AjPStr seqstr = NULL; AjPStr qualstr = NULL; AjPStr tagstr = NULL; unsigned char dp; unsigned char* d; AjPAssemRead r = NULL; AjPSeqBamCore c = NULL; AjPAssemTag tag = NULL; ajuint i=0; ajuint dpos=0; ajint cigop=0; ajuint cigend=0; ajuint cigint=0; c = &b->core; ajDebug("rID: %d pos: %d bin: %hd mapQual: %d read_name_len: %d" " flag_nc: %hd cigar_len: %hd read_len: %d" " mate_rID: %d mate_pos: %d ins_size: %d\n", c->tid, c->pos, c->bin, c->qual, c->l_qname, c->flag, c->n_cigar, c->l_qseq, c->mtid, c->mpos, c->isize); ajDebug("l_aux: %d data_len:%d m_data:%d\n", b->l_aux, b->data_len, b->m_data); AJNEW0(r); r->Flag = c->flag; if(r->Flag & BAM_FREVERSE) { r->y1 = c->pos+1; r->Reversed = ajTrue; } else r->x1 = c->pos+1; r->Reference = c->tid; r->MapQ = c->qual; r->Tlen = c->isize; r->Rnext = c->mtid; r->Pnext = c->mpos+1; d = b->data; dpos = 0; ajStrAssignC(&r->Name, (const char*) &d[dpos]); ajDebug("read name: %p '%S'\n", dpos, r->Name); dpos += (c->l_qname); /* l_qname includes trailing null */ ajStrAssignC(&cigarstr, ""); for(i=0; i < c->n_cigar; i++) { memcpy(&cigint, &d[dpos], 4); cigop = cigint & BAM_CIGAR_MASK; cigend = cigint >> BAM_CIGAR_SHIFT; ajFmtPrintAppS(&cigarstr, "%u%c", cigend, cigarcode[cigop]); dpos += 4; } ajDebug("cigar: %p %S\n", dpos, cigarstr); ajStrAssignRef(&r->Cigar, cigarstr); ajStrDel(&cigarstr); ajStrAssignC(&seqstr, ""); for(i=0; i < (ajuint) c->l_qseq; i++) { ajStrAppendK(&seqstr, bam_nt16_rev_table[MAJSEQBAMSEQI(&d[dpos], i)]); } dpos += (c->l_qseq+1)/2; ajDebug("seq: %p '%S'\n", dpos, seqstr); ajStrAssignRef(&r->Seq, seqstr); ajStrDel(&seqstr); if(c->flag & BAM_FREVERSE) r->Reversed = ajTrue; if(d[dpos] == 0xFF) { ajDebug("qual: MISSING\n"); dpos += c->l_qseq; ajStrAssignK(&r->SeqQ, '*'); } else { qualstr = ajStrNewRes(c->l_qseq+1); for(i=0; i < (ajuint) c->l_qseq; i++) ajStrAppendK(&qualstr, (char)(33 + d[dpos++])); ajStrAssignRef(&r->SeqQ, qualstr); ajDebug("qual: %p %S\n", dpos, qualstr); ajStrDel(&qualstr); } /* tag values */ while (dpos < (ajuint) b->data_len) { ajStrAssignC(&tagstr, ""); AJNEW0(tag); ajStrAppendK(&tagstr, d[dpos++]); ajStrAppendK(&tagstr, d[dpos++]); ajStrAssignS(&tag->Name, tagstr); dp = d[dpos++]; tag->type = dp; ajStrSetClear(&tagstr); if (dp == 'Z' || dp == 'H') { ajFmtPrintAppS(&tagstr,"%s", &d[dpos]); while(d[dpos]) dpos++; dpos++; } else if (dp == 'f') { ajFmtPrintAppS(&tagstr,"%f", (float) *(&d[dpos])); dpos += 4; } else if (dp == 'd') { ajFmtPrintAppS(&tagstr,"%lf", (double) *(&d[dpos])); dpos += 8; } else if (dp == 'A') { ajStrAssignK(&tagstr, d[dpos++]); } else if (dp == 'c') { ajFmtPrintAppS(&tagstr,"%d", (ajint) (signed char) d[dpos++]); } else if (dp == 's') { ajFmtPrintAppS(&tagstr,"%hd", (ajshort) *(&d[dpos])); dpos += 2; } else if (dp == 'i') { ajFmtPrintAppS(&tagstr,"%d", (ajint) *(&d[dpos])); dpos += 4; } else if (dp == 'C') { ajFmtPrintAppS(&tagstr,"%u", (ajuint) d[dpos++]); } else if (dp == 'S') { ajFmtPrintAppS(&tagstr,"%hu", (ajushort) *(&d[dpos])); dpos += 2; } else if (dp == 'I') { ajFmtPrintAppS(&tagstr,"%u", (ajuint) d[dpos]); dpos += 4; } else { ajWarn("Unknown BAM aux type hex(%x) uint(%u) '%c'\n", (ajuint) dp, (ajuint) dp, dp); } ajStrAssignS(&tag->Comment, tagstr); if(!r->Tags) r->Tags = ajListNew(); ajListPushAppend(r->Tags, tag); ajDebug("tags: %p '%S'\n", dpos, tagstr); ajStrDel(&tagstr); } return r; } ID asseminLoadMaf TY static MO ajassemread LB core XX DE Reads assemblies in MAF format, used by the MIRA assembly software. XX PN [1] PA u assemin AjPAssemin PD Assembly input object PX PN [2] PA w assem AjPAssem PD Assembly object PX RT AjBool RD ajTrue on success RX // static AjBool asseminLoadMaf(AjPAssemin assemin, AjPAssem assem) { AjPTextin input = assemin->Input; AjPFilebuff buff = input->Filebuff; AjPFile infile = NULL; AjPStrTok handle = NULL; AjPStr keyword = NULL; AjPStr token = NULL; AjPAssemContig contig = NULL; AjPAssemRead r = NULL; AjPAssemTag tag = NULL; AjBool ok = ajTrue; ajlong fpos = 0; ajint contigid = -1; AjBool endofaReadorContig = ajFalse; ajuint iread = 0; ajuint maxread = 1000; ajDebug("asseminLoadMaf '%F' EOF: %B records: %u " "dataread: %B datadone: %B hasdata: %B\n", ajFilebuffGetFile(buff), ajFilebuffIsEof(buff), input->Records, input->Dataread, input->Datadone, assem->Hasdata); /* ajFilebuffTrace(buff); */ if(input->Datadone) { return ajFalse; } infile = ajFilebuffGetFile(buff); if(!infile) return ajFalse; /* ** On first call, we read the header only */ if(!input->Records) { ajAssemClear(assem); ajListPeekLast(assem->ContigsOrder, (void**)&contig); contigid = (ajuint) ajListGetLength(assem->ContigsOrder)-1; while (ajBuffreadLinePos(buff, &asseminReadLine, &fpos)) { input->Records++; ajStrTokenAssignC(&handle, asseminReadLine, " \n\r\t"); ajStrTokenNextParse(&handle, &keyword); ajStrTokenNextParse(&handle, &token); switch(CASE2(ajStrGetCharFirst(asseminReadLine), ajStrGetCharPos(asseminReadLine, 1))) { case CASE2('\\','\\'): ajDebug("start of read data for the contig\n"); // means end-of-contig-definition endofaReadorContig=ajTrue; break; case CASE2('C','O'): ajDebug("new contig: %S", token); AJNEW0(contig); ajStrAssignS(&contig->Name, token); ajTablePut(assem->Contigs, contig->Name, contig); ajListPushAppend(assem->ContigsOrder, contig); contigid = (ajuint) ajListGetLength(assem->ContigsOrder)-1; contig->Tags = ajListNew(); break; case CASE2('N', 'R'): ajStrToInt(token, &contig->Nreads); ajDebug("number of reads in contig %d\n", contig->Nreads); break; case CASE2('L','C'): ajStrToInt(token, &contig->Length); break; case CASE2('C','S'): ajStrAssignRef(&contig->Consensus, token); break; case CASE2('C','Q'): ajStrAssignS(&contig->ConsensusQ, token); break; case CASE2('C','T'): AJNEW0(tag); ajStrAssignS(&tag->Name, token); ajStrTokenNextParse(&handle, &token); ajStrToUint(token, &tag->x1); ajStrTokenNextParse(&handle, &token); ajStrToUint(token, &tag->y1); ajStrTokenRestParse(&handle, &token); ajStrTrimEndC(&token, "\r\n"); ajStrAssignS(&tag->Comment, token); ajListPushAppend(contig->Tags, tag); tag = NULL; break; default: ajWarn("unknown MAF contig tag: %S - %S\n", keyword, asseminReadLine); } ajStrDel(&keyword); ajStrDel(&token); ajStrDel(&asseminReadLine); ajStrTokenDel(&handle); if(endofaReadorContig) { return ajTrue; } } } ajAssemReset(assem); assem->Hasdata = ajTrue; ajListPeekLast(assem->ContigsOrder, (void**)&contig); contigid = (ajuint) ajListGetLength(assem->ContigsOrder)-1; ok = ajTrue; while (ok && (iread < maxread)) { ok = ajBuffreadLinePos(buff, &asseminReadLine, &fpos); if(!ok) break; ajStrTokenAssignC(&handle, asseminReadLine, " \n\r\t"); ajStrTokenNextParse(&handle, &keyword); ajStrTokenNextParse(&handle, &token); input->Records++; switch(CASE2(ajStrGetCharFirst(asseminReadLine), ajStrGetCharPos(asseminReadLine, 1))) { case CASE2('R','D'): AJNEW0(r); r->Flag = 0x0; ajStrAssignS(&r->Name, token); r->Reference = contigid; iread++; break; case CASE2('R','S'): ajStrAssignS(&r->Seq, token); break; case CASE2('R','Q'): ajStrAssignS(&r->SeqQ, token); break; case CASE2('T','N'): ajStrAssignS(&r->Template, token); break; case CASE2('D','I'): r->Direction = ajStrGetCharFirst(token); break; case CASE2 ('T', 'F'): ajStrToInt(token, &r->TemplateSizeMin); break; case CASE2('T','T'): ajStrToInt(token, &r->TemplateSizeMax); break; case CASE2('S', 'F'): ajStrAssignS(&r->File, token); break; case CASE2('C','L'): ajStrToInt(token, &r->ClipLeft); break; case CASE2('C','R'): ajStrToInt(token, &r->ClipRight); break; case CASE2('S','L'): ajStrToInt(token, &r->VectorLeft); break; case CASE2('S', 'R'): ajStrToInt(token, &r->VectorRight); break; case CASE2('Q','L'): ajStrToInt(token, &r->QualLeft); break; case CASE2('Q','R'): ajStrToInt(token, &r->QualRight); break; case CASE2('S','T'): ajStrAssignS(&r->Technology, token); break; case CASE2('E','R'): ajDebug("end of the read"); break; case CASE2('R','T'): AJNEW0(tag); ajStrAssignS(&tag->Name, token); ajStrTokenNextParseC(&handle, " \t", &token); ajStrToUint(token, &tag->x1); ajStrTokenNextParseC(&handle, " \t", &token); ajStrToUint(token, &tag->y1); if(!r->Tags) r->Tags = ajListNew(); ajListPushAppend(r->Tags, tag); tag = NULL; break; case CASE2('L','R'): { /* TODO: read length * MIRA writes LR lines for reads with more than 2000 bases */ break; } case CASE2('A','O'): { /* TODO */ break; } case CASE2('/','/'): ajDebug("end of the read data for the contig\n"); break; case CASE2('E','C'): ajDebug("end of contig\n"); break; case CASE2('A','T'): /* placement of the read */ ajStrToInt(token, &r->x1); ajStrTokenNextParse(&handle, &token); ajStrToInt(token, &r->y1); ajStrTokenNextParse(&handle, &token); ajStrToInt(token, &r->x2); ajStrTokenNextParse(&handle, &token); ajStrToInt(token, &r->y2); if (r->x1 > r->y1) r->Flag |= BAM_FREVERSE; assem->rec = r; endofaReadorContig=ajTrue; break; default: ajWarn("unknown MAF read tag: %S - %S\n", keyword, asseminReadLine); } if(endofaReadorContig) { if(assem->rec) { ajListPushAppend(assem->Reads, assem->rec); assem->rec = NULL; r = NULL; } input->Datacount += iread; ajStrDel(&keyword); ajStrDel(&token); ajStrTokenDel(&handle); return ajTrue; } } ajStrDel(&keyword); ajStrDel(&token); ajStrTokenDel(&handle); if(assem->rec) { ajListPushAppend(assem->Reads, assem->rec); assem->rec = NULL; r = NULL; } input->Datacount += iread; ajDebug("data done ok: %B Datacount: %u iread: %u/%u\n", ok, input->Datacount, iread, maxread); if(!ok) { input->Datadone = ajTrue; ajFilebuffClear(buff, 0); } return ajTrue; } ID
Alignment FormatAliasNucProShowheaderMinseqMaxseqDescription
\n%-12s\n%5B%3B%3B%3B%6d%6d\"%s\"