From 4c5e7a20a03ddc6feb49ff9d21fcb4c79bc5508d Mon Sep 17 00:00:00 2001 From: westcott Date: Wed, 26 Oct 2011 16:14:31 +0000 Subject: [PATCH] paralellized chimera.uchime for windows for both by group and with a template. --- aligncommand.h | 2 +- chimeraslayercommand.h | 2 +- chimerauchimecommand.cpp | 142 +++++- chimerauchimecommand.h | 700 +++++++++++++++++++++++++ classifyseqscommand.h | 2 +- getoturepcommand.cpp | 81 ++- getoturepcommand.h | 1 + mothurout.cpp | 4 +- myutils.cpp | 1040 +++++++++++++++++++------------------- phylotree.cpp | 5 +- preclustercommand.h | 4 +- shhhercommand.h | 2 +- timing.h | 4 +- trimflowscommand.h | 2 +- 14 files changed, 1430 insertions(+), 561 deletions(-) diff --git a/aligncommand.h b/aligncommand.h index 6236958..fa1bf57 100644 --- a/aligncommand.h +++ b/aligncommand.h @@ -78,7 +78,7 @@ private: //custom data structure for threads to use. // This is passed by void pointer so it can be any data type // that can be passed using a single void pointer (LPVOID). -typedef struct alignData { +struct alignData { string alignFName; string reportFName; string accnosFName; diff --git a/chimeraslayercommand.h b/chimeraslayercommand.h index 815cb36..54b8fa1 100644 --- a/chimeraslayercommand.h +++ b/chimeraslayercommand.h @@ -79,7 +79,7 @@ private: //custom data structure for threads to use. // This is passed by void pointer so it can be any data type // that can be passed using a single void pointer (LPVOID). -typedef struct slayerData { +struct slayerData { string outputFName; string fasta; string accnos; diff --git a/chimerauchimecommand.cpp b/chimerauchimecommand.cpp index caddc27..e08909b 100644 --- a/chimerauchimecommand.cpp +++ b/chimerauchimecommand.cpp @@ -543,12 +543,9 @@ int ChimeraUchimeCommand::execute(){ if (chimealns) { m->openOutputFile(alnsFileName, out2); out2.close(); } int totalSeqs = 0; - #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) if(processors == 1) { totalSeqs = driverGroups(parser, outputFileName, newFasta, accnosFileName, alnsFileName, 0, groups.size(), groups); } else { totalSeqs = createProcessesGroups(parser, outputFileName, newFasta, accnosFileName, alnsFileName, groups); } - #else - totalSeqs = driverGroups(parser, outputFileName, newFasta, accnosFileName, alnsFileName, 0, groups.size(), groups); - #endif + if (m->control_pressed) { for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]); } return 0; } int totalChimeras = deconvoluteResults(parser, outputFileName, accnosFileName, alnsFileName); @@ -563,12 +560,12 @@ int ChimeraUchimeCommand::execute(){ int numSeqs = 0; int numChimeras = 0; - #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) + //#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) if(processors == 1){ numSeqs = driver(outputFileName, fastaFileNames[s], accnosFileName, alnsFileName, numChimeras); } else{ numSeqs = createProcesses(outputFileName, fastaFileNames[s], accnosFileName, alnsFileName, numChimeras); } - #else - numSeqs = driver(outputFileName, fastaFileNames[s], accnosFileName, alnsFileName, numChimeras); - #endif + //#else + // numSeqs = driver(outputFileName, fastaFileNames[s], accnosFileName, alnsFileName, numChimeras); + //#endif if (m->control_pressed) { for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]); } return 0; } //remove file made for uchime @@ -1286,9 +1283,10 @@ int ChimeraUchimeCommand::createProcesses(string outputFileName, string filename processIDS.clear(); int process = 1; int num = 0; + vector files; + #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) //break up file into multiple files - vector files; m->divideFile(filename, processors, files); if (m->control_pressed) { return 0; } @@ -1341,7 +1339,89 @@ int ChimeraUchimeCommand::createProcesses(string outputFileName, string filename } in.close(); m->mothurRemove(tempFile); } +#else + ////////////////////////////////////////////////////////////////////////////////////////////////////// + //Windows version shared memory, so be careful when passing variables through the preClusterData struct. + //Above fork() will clone, so memory is separate, but that's not the case with windows, + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + //divide file + int count = 0; + int spot = 0; + map filehandles; + map::iterator it3; + + ofstream* temp; + for (int i = 0; i < processors; i++) { + temp = new ofstream; + filehandles[i] = temp; + m->openOutputFile(filename+toString(i)+".temp", *(temp)); + files.push_back(filename+toString(i)+".temp"); + } + + ifstream in; + m->openInputFile(filename, in); + + while(!in.eof()) { + + if (m->control_pressed) { in.close(); for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) { (*(it3->second)).close(); delete it3->second; } return 0; } + + Sequence tempSeq(in); m->gobble(in); + + if (tempSeq.getName() != "") { + tempSeq.printSequence(*(filehandles[spot])); + spot++; count++; + if (spot == processors) { spot = 0; } + } + } + in.close(); + + //delete memory + for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) { + (*(it3->second)).close(); + delete it3->second; + } + + //sanity check for number of processors + if (count < processors) { processors = count; } + + vector pDataArray; + DWORD dwThreadIdArray[processors-1]; + HANDLE hThreadArray[processors-1]; + vector dummy; //used so that we can use the same struct for MyUchimeSeqsThreadFunction and MyUchimeThreadFunction + + //Create processor worker threads. + for( int i=1; isetBooleans(useAbskew, chimealns, useMinH, useMindiv, useXn, useDn, useXa, useChunks, useMinchunk, useIdsmoothwindow, useMinsmoothid, useMaxp, skipgaps, skipgaps2, useMinlen, useMaxlen, ucl, useQueryfract); + tempUchime->setVariables(abskew, minh, mindiv, xn, dn, xa, chunks, minchunk, idsmoothwindow, minsmoothid, maxp, minlen, maxlen, queryfract); + + pDataArray.push_back(tempUchime); + processIDS.push_back(i); + + //MySeqSumThreadFunction is in header. It must be global or static to work with the threads. + //default security attributes, thread function name, argument to thread function, use default creation flags, returns the thread identifier + hThreadArray[i-1] = CreateThread(NULL, 0, MyUchimeSeqsThreadFunction, pDataArray[i-1], 0, &dwThreadIdArray[i-1]); + } + + + //using the main process as a worker saves time and memory + num = driver(outputFileName, files[0], accnos, alns, numChimeras); + //Wait until all threads have terminated. + WaitForMultipleObjects(processors-1, hThreadArray, TRUE, INFINITE); + + //Close all thread handles and free memory allocations. + for(int i=0; i < pDataArray.size(); i++){ + num += pDataArray[i]->count; + numChimeras += pDataArray[i]->numChimeras; + CloseHandle(hThreadArray[i]); + delete pDataArray[i]; + } +#endif //append output files for(int i=0;imothurRemove(files[i]); } -#endif return num; } catch(exception& e) { @@ -1424,7 +1503,6 @@ int ChimeraUchimeCommand::createProcessesGroups(SequenceParser& parser, string o int temp = processIDS[i]; wait(&temp); } -#endif for (int i = 0; i < processIDS.size(); i++) { ifstream in; @@ -1433,8 +1511,50 @@ int ChimeraUchimeCommand::createProcessesGroups(SequenceParser& parser, string o if (!in.eof()) { int tempNum = 0; in >> tempNum; num += tempNum; } in.close(); m->mothurRemove(tempFile); } + +#else + ////////////////////////////////////////////////////////////////////////////////////////////////////// + //Windows version shared memory, so be careful when passing variables through the preClusterData struct. + //Above fork() will clone, so memory is separate, but that's not the case with windows, + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + vector pDataArray; + DWORD dwThreadIdArray[processors-1]; + HANDLE hThreadArray[processors-1]; + + //Create processor worker threads. + for( int i=1; isetBooleans(useAbskew, chimealns, useMinH, useMindiv, useXn, useDn, useXa, useChunks, useMinchunk, useIdsmoothwindow, useMinsmoothid, useMaxp, skipgaps, skipgaps2, useMinlen, useMaxlen, ucl, useQueryfract); + tempUchime->setVariables(abskew, minh, mindiv, xn, dn, xa, chunks, minchunk, idsmoothwindow, minsmoothid, maxp, minlen, maxlen, queryfract); + + pDataArray.push_back(tempUchime); + processIDS.push_back(i); + + //MySeqSumThreadFunction is in header. It must be global or static to work with the threads. + //default security attributes, thread function name, argument to thread function, use default creation flags, returns the thread identifier + hThreadArray[i-1] = CreateThread(NULL, 0, MyUchimeThreadFunction, pDataArray[i-1], 0, &dwThreadIdArray[i-1]); + } + + //using the main process as a worker saves time and memory + num = driverGroups(parser, outputFName, filename, accnos, alns, lines[0].start, lines[0].end, groups); + + //Wait until all threads have terminated. + WaitForMultipleObjects(processors-1, hThreadArray, TRUE, INFINITE); + + //Close all thread handles and free memory allocations. + for(int i=0; i < pDataArray.size(); i++){ + num += pDataArray[i]->count; + CloseHandle(hThreadArray[i]); + delete pDataArray[i]; + } +#endif + //append output files for(int i=0;iappendFiles((outputFName + toString(processIDS[i]) + ".temp"), outputFName); diff --git a/chimerauchimecommand.h b/chimerauchimecommand.h index 1f86a98..359b68c 100644 --- a/chimerauchimecommand.h +++ b/chimerauchimecommand.h @@ -64,6 +64,706 @@ private: }; /***********************************************************/ +/**************************************************************************************************/ +//custom data structure for threads to use. +// This is passed by void pointer so it can be any data type +// that can be passed using a single void pointer (LPVOID). +struct uchimeData { + string fastafile; + string namefile; + string groupfile; + string outputFName; + string accnos, alns, filename, templatefile; + MothurOut* m; + int start; + int end; + int threadID, count, numChimeras; + vector groups; + bool useAbskew, chimealns, useMinH, useMindiv, useXn, useDn, useXa, useChunks, useMinchunk, useIdsmoothwindow, useMinsmoothid, useMaxp, skipgaps, skipgaps2, useMinlen, useMaxlen, ucl, useQueryfract; + string abskew, minh, mindiv, xn, dn, xa, chunks, minchunk, idsmoothwindow, minsmoothid, maxp, minlen, maxlen, queryfract; + + uchimeData(){} + uchimeData(string o, string t, string file, string f, string n, string g, string ac, string al, vector gr, MothurOut* mout, int st, int en, int tid) { + fastafile = f; + namefile = n; + groupfile = g; + filename = file; + outputFName = o; + templatefile = t; + accnos = ac; + alns = al; + m = mout; + start = st; + end = en; + threadID = tid; + groups = gr; + count = 0; + numChimeras = 0; + } + void setBooleans(bool Abskew, bool calns, bool MinH, bool Mindiv, bool Xn, bool Dn, bool Xa, bool Chunks, bool Minchunk, bool Idsmoothwindow, bool Minsmoothid, bool Maxp, bool skipgap, bool skipgap2, bool Minlen, bool Maxlen, bool uc, bool Queryfract) { + useAbskew = Abskew; + chimealns = calns; + useMinH = MinH; + useMindiv = Mindiv; + useXn = Xn; + useDn = Dn; + useXa = Xa; + useChunks = Chunks; + useMinchunk = Minchunk; + useIdsmoothwindow = Idsmoothwindow; + useMinsmoothid = Minsmoothid; + useMaxp = Maxp; + skipgaps = skipgap; + skipgaps2 = skipgap2; + useMinlen = Minlen; + useMaxlen = Maxlen; + ucl = uc; + useQueryfract = Queryfract; + } + + void setVariables(string abske, string min, string mindi, string x, string d, string xa2, string chunk, string minchun, string idsmoothwindo, string minsmoothi, string max, string minle, string maxle, string queryfrac) { + abskew = abske; + minh = min; + mindiv = mindi; + xn = x; + dn = d; + xa = xa2; + chunks = chunk; + minchunk = minchun; + idsmoothwindow = idsmoothwindo; + minsmoothid = minsmoothi; + maxp = max; + minlen = minle; + maxlen = maxle; + queryfract = queryfrac; + } +}; + +/**************************************************************************************************/ +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else +static DWORD WINAPI MyUchimeThreadFunction(LPVOID lpParam){ + uchimeData* pDataArray; + pDataArray = (uchimeData*)lpParam; + + try { + + //clears files + ofstream out, out1, out2; + pDataArray->m->openOutputFile(pDataArray->outputFName, out); out.close(); + pDataArray->m->openOutputFile(pDataArray->accnos, out1); out1.close(); + if (pDataArray->chimealns) { pDataArray->m->openOutputFile(pDataArray->alns, out2); out2.close(); } + + //parse fasta and name file by group + SequenceParser* parser; + if (pDataArray->namefile != "") { parser = new SequenceParser(pDataArray->groupfile, pDataArray->fastafile, pDataArray->namefile); } + else { parser = new SequenceParser(pDataArray->groupfile, pDataArray->fastafile); } + + int totalSeqs = 0; + int numChimeras = 0; + + for (int i = pDataArray->start; i < pDataArray->end; i++) { + int start = time(NULL); if (pDataArray->m->control_pressed) { delete parser; return 0; } + + int error = parser->getSeqs(pDataArray->groups[i], pDataArray->filename, true); if ((error == 1) || pDataArray->m->control_pressed) { delete parser; return 0; } + + //int numSeqs = driver((outputFName + groups[i]), filename, (accnos+ groups[i]), (alns+ groups[i]), numChimeras); + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + //to allow for spaces in the path + string outputFName = "\"" + pDataArray->outputFName+pDataArray->groups[i] + "\""; + string filename = "\"" + pDataArray->filename + "\""; + string alns = "\"" + pDataArray->alns+pDataArray->groups[i] + "\""; + string accnos = pDataArray->accnos+pDataArray->groups[i]; + + vector cPara; + + char* tempUchime; + tempUchime= new char[8]; + *tempUchime = '\0'; + strncat(tempUchime, "uchime ", 7); + cPara.push_back(tempUchime); + + char* tempIn = new char[8]; + *tempIn = '\0'; strncat(tempIn, "--input", 7); + //strcpy(tempIn, "--input"); + cPara.push_back(tempIn); + char* temp = new char[filename.length()+1]; + *temp = '\0'; strncat(temp, filename.c_str(), filename.length()); + //strcpy(temp, filename.c_str()); + cPara.push_back(temp); + + char* tempO = new char[12]; + *tempO = '\0'; strncat(tempO, "--uchimeout", 11); + //strcpy(tempO, "--uchimeout"); + cPara.push_back(tempO); + char* tempout = new char[outputFName.length()+1]; + //strcpy(tempout, outputFName.c_str()); + *tempout = '\0'; strncat(tempout, outputFName.c_str(), outputFName.length()); + cPara.push_back(tempout); + + if (pDataArray->chimealns) { + char* tempA = new char[13]; + *tempA = '\0'; strncat(tempA, "--uchimealns", 12); + //strcpy(tempA, "--uchimealns"); + cPara.push_back(tempA); + char* tempa = new char[alns.length()+1]; + //strcpy(tempa, alns.c_str()); + *tempa = '\0'; strncat(tempa, alns.c_str(), alns.length()); + cPara.push_back(tempa); + } + + if (pDataArray->useAbskew) { + char* tempskew = new char[9]; + *tempskew = '\0'; strncat(tempskew, "--abskew", 8); + //strcpy(tempskew, "--abskew"); + cPara.push_back(tempskew); + char* tempSkew = new char[pDataArray->abskew.length()+1]; + //strcpy(tempSkew, abskew.c_str()); + *tempSkew = '\0'; strncat(tempSkew, pDataArray->abskew.c_str(), pDataArray->abskew.length()); + cPara.push_back(tempSkew); + } + + if (pDataArray->useMinH) { + char* tempminh = new char[7]; + *tempminh = '\0'; strncat(tempminh, "--minh", 6); + //strcpy(tempminh, "--minh"); + cPara.push_back(tempminh); + char* tempMinH = new char[pDataArray->minh.length()+1]; + *tempMinH = '\0'; strncat(tempMinH, pDataArray->minh.c_str(), pDataArray->minh.length()); + //strcpy(tempMinH, minh.c_str()); + cPara.push_back(tempMinH); + } + + if (pDataArray->useMindiv) { + char* tempmindiv = new char[9]; + *tempmindiv = '\0'; strncat(tempmindiv, "--mindiv", 8); + //strcpy(tempmindiv, "--mindiv"); + cPara.push_back(tempmindiv); + char* tempMindiv = new char[pDataArray->mindiv.length()+1]; + *tempMindiv = '\0'; strncat(tempMindiv, pDataArray->mindiv.c_str(), pDataArray->mindiv.length()); + //strcpy(tempMindiv, mindiv.c_str()); + cPara.push_back(tempMindiv); + } + + if (pDataArray->useXn) { + char* tempxn = new char[5]; + //strcpy(tempxn, "--xn"); + *tempxn = '\0'; strncat(tempxn, "--xn", 4); + cPara.push_back(tempxn); + char* tempXn = new char[pDataArray->xn.length()+1]; + //strcpy(tempXn, xn.c_str()); + *tempXn = '\0'; strncat(tempXn, pDataArray->xn.c_str(), pDataArray->xn.length()); + cPara.push_back(tempXn); + } + + if (pDataArray->useDn) { + char* tempdn = new char[5]; + //strcpy(tempdn, "--dn"); + *tempdn = '\0'; strncat(tempdn, "--dn", 4); + cPara.push_back(tempdn); + char* tempDn = new char[pDataArray->dn.length()+1]; + *tempDn = '\0'; strncat(tempDn, pDataArray->dn.c_str(), pDataArray->dn.length()); + //strcpy(tempDn, dn.c_str()); + cPara.push_back(tempDn); + } + + if (pDataArray->useXa) { + char* tempxa = new char[5]; + //strcpy(tempxa, "--xa"); + *tempxa = '\0'; strncat(tempxa, "--xa", 4); + cPara.push_back(tempxa); + char* tempXa = new char[pDataArray->xa.length()+1]; + *tempXa = '\0'; strncat(tempXa, pDataArray->xa.c_str(), pDataArray->xa.length()); + //strcpy(tempXa, xa.c_str()); + cPara.push_back(tempXa); + } + + if (pDataArray->useChunks) { + char* tempchunks = new char[9]; + //strcpy(tempchunks, "--chunks"); + *tempchunks = '\0'; strncat(tempchunks, "--chunks", 8); + cPara.push_back(tempchunks); + char* tempChunks = new char[pDataArray->chunks.length()+1]; + *tempChunks = '\0'; strncat(tempChunks, pDataArray->chunks.c_str(), pDataArray->chunks.length()); + //strcpy(tempChunks, chunks.c_str()); + cPara.push_back(tempChunks); + } + + if (pDataArray->useMinchunk) { + char* tempminchunk = new char[11]; + //strcpy(tempminchunk, "--minchunk"); + *tempminchunk = '\0'; strncat(tempminchunk, "--minchunk", 10); + cPara.push_back(tempminchunk); + char* tempMinchunk = new char[pDataArray->minchunk.length()+1]; + *tempMinchunk = '\0'; strncat(tempMinchunk, pDataArray->minchunk.c_str(), pDataArray->minchunk.length()); + //strcpy(tempMinchunk, minchunk.c_str()); + cPara.push_back(tempMinchunk); + } + + if (pDataArray->useIdsmoothwindow) { + char* tempidsmoothwindow = new char[17]; + *tempidsmoothwindow = '\0'; strncat(tempidsmoothwindow, "--idsmoothwindow", 16); + //strcpy(tempidsmoothwindow, "--idsmoothwindow"); + cPara.push_back(tempidsmoothwindow); + char* tempIdsmoothwindow = new char[pDataArray->idsmoothwindow.length()+1]; + *tempIdsmoothwindow = '\0'; strncat(tempIdsmoothwindow, pDataArray->idsmoothwindow.c_str(), pDataArray->idsmoothwindow.length()); + //strcpy(tempIdsmoothwindow, idsmoothwindow.c_str()); + cPara.push_back(tempIdsmoothwindow); + } + + /*if (useMinsmoothid) { + char* tempminsmoothid = new char[14]; + //strcpy(tempminsmoothid, "--minsmoothid"); + *tempminsmoothid = '\0'; strncat(tempminsmoothid, "--minsmoothid", 13); + cPara.push_back(tempminsmoothid); + char* tempMinsmoothid = new char[minsmoothid.length()+1]; + *tempMinsmoothid = '\0'; strncat(tempMinsmoothid, minsmoothid.c_str(), minsmoothid.length()); + //strcpy(tempMinsmoothid, minsmoothid.c_str()); + cPara.push_back(tempMinsmoothid); + }*/ + + if (pDataArray->useMaxp) { + char* tempmaxp = new char[7]; + //strcpy(tempmaxp, "--maxp"); + *tempmaxp = '\0'; strncat(tempmaxp, "--maxp", 6); + cPara.push_back(tempmaxp); + char* tempMaxp = new char[pDataArray->maxp.length()+1]; + *tempMaxp = '\0'; strncat(tempMaxp, pDataArray->maxp.c_str(), pDataArray->maxp.length()); + //strcpy(tempMaxp, maxp.c_str()); + cPara.push_back(tempMaxp); + } + + if (!pDataArray->skipgaps) { + char* tempskipgaps = new char[13]; + //strcpy(tempskipgaps, "--[no]skipgaps"); + *tempskipgaps = '\0'; strncat(tempskipgaps, "--noskipgaps", 12); + cPara.push_back(tempskipgaps); + } + + if (!pDataArray->skipgaps2) { + char* tempskipgaps2 = new char[14]; + //strcpy(tempskipgaps2, "--[no]skipgaps2"); + *tempskipgaps2 = '\0'; strncat(tempskipgaps2, "--noskipgaps2", 13); + cPara.push_back(tempskipgaps2); + } + + if (pDataArray->useMinlen) { + char* tempminlen = new char[9]; + *tempminlen = '\0'; strncat(tempminlen, "--minlen", 8); + //strcpy(tempminlen, "--minlen"); + cPara.push_back(tempminlen); + char* tempMinlen = new char[pDataArray->minlen.length()+1]; + //strcpy(tempMinlen, minlen.c_str()); + *tempMinlen = '\0'; strncat(tempMinlen, pDataArray->minlen.c_str(), pDataArray->minlen.length()); + cPara.push_back(tempMinlen); + } + + if (pDataArray->useMaxlen) { + char* tempmaxlen = new char[9]; + //strcpy(tempmaxlen, "--maxlen"); + *tempmaxlen = '\0'; strncat(tempmaxlen, "--maxlen", 8); + cPara.push_back(tempmaxlen); + char* tempMaxlen = new char[pDataArray->maxlen.length()+1]; + *tempMaxlen = '\0'; strncat(tempMaxlen, pDataArray->maxlen.c_str(), pDataArray->maxlen.length()); + //strcpy(tempMaxlen, maxlen.c_str()); + cPara.push_back(tempMaxlen); + } + + if (pDataArray->ucl) { + char* tempucl = new char[5]; + strcpy(tempucl, "--ucl"); + cPara.push_back(tempucl); + } + + if (pDataArray->useQueryfract) { + char* tempqueryfract = new char[13]; + *tempqueryfract = '\0'; strncat(tempqueryfract, "--queryfract", 12); + //strcpy(tempqueryfract, "--queryfract"); + cPara.push_back(tempqueryfract); + char* tempQueryfract = new char[pDataArray->queryfract.length()+1]; + *tempQueryfract = '\0'; strncat(tempQueryfract, pDataArray->queryfract.c_str(), pDataArray->queryfract.length()); + //strcpy(tempQueryfract, queryfract.c_str()); + cPara.push_back(tempQueryfract); + } + + + char** uchimeParameters; + uchimeParameters = new char*[cPara.size()]; + string commandString = ""; + for (int j = 0; j < cPara.size(); j++) { uchimeParameters[j] = cPara[j]; commandString += toString(cPara[j]) + " "; } + //int numArgs = cPara.size(); + + //uchime_main(numArgs, uchimeParameters); + //cout << "commandString = " << commandString << endl; + system(commandString.c_str()); + + //free memory + for(int j = 0; j < cPara.size(); j++) { delete cPara[j]; } + delete[] uchimeParameters; + + //remove "" from filenames + outputFName = outputFName.substr(1, outputFName.length()-2); + filename = filename.substr(1, filename.length()-2); + alns = alns.substr(1, alns.length()-2); + + if (pDataArray->m->control_pressed) { delete parser; return 0; } + + //create accnos file from uchime results + ifstream in; + pDataArray->m->openInputFile(outputFName, in); + + ofstream out; + pDataArray->m->openOutputFile(accnos, out); + + int num = 0; + numChimeras = 0; + while(!in.eof()) { + + if (pDataArray->m->control_pressed) { break; } + + string name = ""; + string chimeraFlag = ""; + in >> chimeraFlag >> name; + + //fix name + name = name.substr(0, name.length()-1); //rip off last / + name = name.substr(0, name.find_last_of('/')); + + for (int j = 0; j < 15; j++) { in >> chimeraFlag; } + pDataArray->m->gobble(in); + + if (chimeraFlag == "Y") { out << name << endl; numChimeras++; } + num++; + } + in.close(); + out.close(); + + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// + totalSeqs += num; + pDataArray->numChimeras += numChimeras; + + if (pDataArray->m->control_pressed) { delete parser; return 0; } + + //remove file made for uchime + pDataArray->m->mothurRemove(filename); + + //append files + pDataArray->m->appendFiles(outputFName, pDataArray->outputFName); pDataArray->m->mothurRemove(outputFName); + pDataArray->m->appendFiles(accnos, pDataArray->accnos); pDataArray->m->mothurRemove(accnos); + if (pDataArray->chimealns) { pDataArray->m->appendFiles(alns, pDataArray->alns); pDataArray->m->mothurRemove(alns); } + + pDataArray->m->mothurOutEndLine(); pDataArray->m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(num) + " sequences from group " + pDataArray->groups[i] + "."); pDataArray->m->mothurOutEndLine(); + + } + + pDataArray->count = totalSeqs; + delete parser; + return totalSeqs; + + } + catch(exception& e) { + pDataArray->m->errorOut(e, "ChimeraUchimeCommand", "MyUchimeThreadFunction"); + exit(1); + } +} +/**************************************************************************************************/ + +static DWORD WINAPI MyUchimeSeqsThreadFunction(LPVOID lpParam){ + uchimeData* pDataArray; + pDataArray = (uchimeData*)lpParam; + + try { + + int totalSeqs = 0; + int numChimeras = 0; + + int start = time(NULL); if (pDataArray->m->control_pressed) { return 0; } + + //to allow for spaces in the path + string outputFName = "\"" + pDataArray->outputFName + "\""; + string filename = "\"" + pDataArray->filename + "\""; + string alns = "\"" + pDataArray->alns+ "\""; + string templatefile = "\"" + pDataArray->templatefile + "\""; + string accnos = pDataArray->accnos; + + vector cPara; + + char* tempUchime; + tempUchime= new char[8]; + *tempUchime = '\0'; + strncat(tempUchime, "uchime ", 7); + cPara.push_back(tempUchime); + + char* tempIn = new char[8]; + *tempIn = '\0'; strncat(tempIn, "--input", 7); + //strcpy(tempIn, "--input"); + cPara.push_back(tempIn); + char* temp = new char[filename.length()+1]; + *temp = '\0'; strncat(temp, filename.c_str(), filename.length()); + //strcpy(temp, filename.c_str()); + cPara.push_back(temp); + + //add reference file + char* tempRef = new char[5]; + //strcpy(tempRef, "--db"); + *tempRef = '\0'; strncat(tempRef, "--db", 4); + cPara.push_back(tempRef); + char* tempR = new char[templatefile.length()+1]; + //strcpy(tempR, templatefile.c_str()); + *tempR = '\0'; strncat(tempR, templatefile.c_str(), templatefile.length()); + cPara.push_back(tempR); + + char* tempO = new char[12]; + *tempO = '\0'; strncat(tempO, "--uchimeout", 11); + //strcpy(tempO, "--uchimeout"); + cPara.push_back(tempO); + char* tempout = new char[outputFName.length()+1]; + //strcpy(tempout, outputFName.c_str()); + *tempout = '\0'; strncat(tempout, outputFName.c_str(), outputFName.length()); + cPara.push_back(tempout); + + if (pDataArray->chimealns) { + char* tempA = new char[13]; + *tempA = '\0'; strncat(tempA, "--uchimealns", 12); + //strcpy(tempA, "--uchimealns"); + cPara.push_back(tempA); + char* tempa = new char[alns.length()+1]; + //strcpy(tempa, alns.c_str()); + *tempa = '\0'; strncat(tempa, alns.c_str(), alns.length()); + cPara.push_back(tempa); + } + + if (pDataArray->useAbskew) { + char* tempskew = new char[9]; + *tempskew = '\0'; strncat(tempskew, "--abskew", 8); + //strcpy(tempskew, "--abskew"); + cPara.push_back(tempskew); + char* tempSkew = new char[pDataArray->abskew.length()+1]; + //strcpy(tempSkew, abskew.c_str()); + *tempSkew = '\0'; strncat(tempSkew, pDataArray->abskew.c_str(), pDataArray->abskew.length()); + cPara.push_back(tempSkew); + } + + if (pDataArray->useMinH) { + char* tempminh = new char[7]; + *tempminh = '\0'; strncat(tempminh, "--minh", 6); + //strcpy(tempminh, "--minh"); + cPara.push_back(tempminh); + char* tempMinH = new char[pDataArray->minh.length()+1]; + *tempMinH = '\0'; strncat(tempMinH, pDataArray->minh.c_str(), pDataArray->minh.length()); + //strcpy(tempMinH, minh.c_str()); + cPara.push_back(tempMinH); + } + + if (pDataArray->useMindiv) { + char* tempmindiv = new char[9]; + *tempmindiv = '\0'; strncat(tempmindiv, "--mindiv", 8); + //strcpy(tempmindiv, "--mindiv"); + cPara.push_back(tempmindiv); + char* tempMindiv = new char[pDataArray->mindiv.length()+1]; + *tempMindiv = '\0'; strncat(tempMindiv, pDataArray->mindiv.c_str(), pDataArray->mindiv.length()); + //strcpy(tempMindiv, mindiv.c_str()); + cPara.push_back(tempMindiv); + } + + if (pDataArray->useXn) { + char* tempxn = new char[5]; + //strcpy(tempxn, "--xn"); + *tempxn = '\0'; strncat(tempxn, "--xn", 4); + cPara.push_back(tempxn); + char* tempXn = new char[pDataArray->xn.length()+1]; + //strcpy(tempXn, xn.c_str()); + *tempXn = '\0'; strncat(tempXn, pDataArray->xn.c_str(), pDataArray->xn.length()); + cPara.push_back(tempXn); + } + + if (pDataArray->useDn) { + char* tempdn = new char[5]; + //strcpy(tempdn, "--dn"); + *tempdn = '\0'; strncat(tempdn, "--dn", 4); + cPara.push_back(tempdn); + char* tempDn = new char[pDataArray->dn.length()+1]; + *tempDn = '\0'; strncat(tempDn, pDataArray->dn.c_str(), pDataArray->dn.length()); + //strcpy(tempDn, dn.c_str()); + cPara.push_back(tempDn); + } + + if (pDataArray->useXa) { + char* tempxa = new char[5]; + //strcpy(tempxa, "--xa"); + *tempxa = '\0'; strncat(tempxa, "--xa", 4); + cPara.push_back(tempxa); + char* tempXa = new char[pDataArray->xa.length()+1]; + *tempXa = '\0'; strncat(tempXa, pDataArray->xa.c_str(), pDataArray->xa.length()); + //strcpy(tempXa, xa.c_str()); + cPara.push_back(tempXa); + } + + if (pDataArray->useChunks) { + char* tempchunks = new char[9]; + //strcpy(tempchunks, "--chunks"); + *tempchunks = '\0'; strncat(tempchunks, "--chunks", 8); + cPara.push_back(tempchunks); + char* tempChunks = new char[pDataArray->chunks.length()+1]; + *tempChunks = '\0'; strncat(tempChunks, pDataArray->chunks.c_str(), pDataArray->chunks.length()); + //strcpy(tempChunks, chunks.c_str()); + cPara.push_back(tempChunks); + } + + if (pDataArray->useMinchunk) { + char* tempminchunk = new char[11]; + //strcpy(tempminchunk, "--minchunk"); + *tempminchunk = '\0'; strncat(tempminchunk, "--minchunk", 10); + cPara.push_back(tempminchunk); + char* tempMinchunk = new char[pDataArray->minchunk.length()+1]; + *tempMinchunk = '\0'; strncat(tempMinchunk, pDataArray->minchunk.c_str(), pDataArray->minchunk.length()); + //strcpy(tempMinchunk, minchunk.c_str()); + cPara.push_back(tempMinchunk); + } + + if (pDataArray->useIdsmoothwindow) { + char* tempidsmoothwindow = new char[17]; + *tempidsmoothwindow = '\0'; strncat(tempidsmoothwindow, "--idsmoothwindow", 16); + //strcpy(tempidsmoothwindow, "--idsmoothwindow"); + cPara.push_back(tempidsmoothwindow); + char* tempIdsmoothwindow = new char[pDataArray->idsmoothwindow.length()+1]; + *tempIdsmoothwindow = '\0'; strncat(tempIdsmoothwindow, pDataArray->idsmoothwindow.c_str(), pDataArray->idsmoothwindow.length()); + //strcpy(tempIdsmoothwindow, idsmoothwindow.c_str()); + cPara.push_back(tempIdsmoothwindow); + } + + if (pDataArray->useMaxp) { + char* tempmaxp = new char[7]; + //strcpy(tempmaxp, "--maxp"); + *tempmaxp = '\0'; strncat(tempmaxp, "--maxp", 6); + cPara.push_back(tempmaxp); + char* tempMaxp = new char[pDataArray->maxp.length()+1]; + *tempMaxp = '\0'; strncat(tempMaxp, pDataArray->maxp.c_str(), pDataArray->maxp.length()); + //strcpy(tempMaxp, maxp.c_str()); + cPara.push_back(tempMaxp); + } + + if (!pDataArray->skipgaps) { + char* tempskipgaps = new char[13]; + //strcpy(tempskipgaps, "--[no]skipgaps"); + *tempskipgaps = '\0'; strncat(tempskipgaps, "--noskipgaps", 12); + cPara.push_back(tempskipgaps); + } + + if (!pDataArray->skipgaps2) { + char* tempskipgaps2 = new char[14]; + //strcpy(tempskipgaps2, "--[no]skipgaps2"); + *tempskipgaps2 = '\0'; strncat(tempskipgaps2, "--noskipgaps2", 13); + cPara.push_back(tempskipgaps2); + } + + if (pDataArray->useMinlen) { + char* tempminlen = new char[9]; + *tempminlen = '\0'; strncat(tempminlen, "--minlen", 8); + //strcpy(tempminlen, "--minlen"); + cPara.push_back(tempminlen); + char* tempMinlen = new char[pDataArray->minlen.length()+1]; + //strcpy(tempMinlen, minlen.c_str()); + *tempMinlen = '\0'; strncat(tempMinlen, pDataArray->minlen.c_str(), pDataArray->minlen.length()); + cPara.push_back(tempMinlen); + } + + if (pDataArray->useMaxlen) { + char* tempmaxlen = new char[9]; + //strcpy(tempmaxlen, "--maxlen"); + *tempmaxlen = '\0'; strncat(tempmaxlen, "--maxlen", 8); + cPara.push_back(tempmaxlen); + char* tempMaxlen = new char[pDataArray->maxlen.length()+1]; + *tempMaxlen = '\0'; strncat(tempMaxlen, pDataArray->maxlen.c_str(), pDataArray->maxlen.length()); + //strcpy(tempMaxlen, maxlen.c_str()); + cPara.push_back(tempMaxlen); + } + + if (pDataArray->ucl) { + char* tempucl = new char[5]; + strcpy(tempucl, "--ucl"); + cPara.push_back(tempucl); + } + + if (pDataArray->useQueryfract) { + char* tempqueryfract = new char[13]; + *tempqueryfract = '\0'; strncat(tempqueryfract, "--queryfract", 12); + //strcpy(tempqueryfract, "--queryfract"); + cPara.push_back(tempqueryfract); + char* tempQueryfract = new char[pDataArray->queryfract.length()+1]; + *tempQueryfract = '\0'; strncat(tempQueryfract, pDataArray->queryfract.c_str(), pDataArray->queryfract.length()); + //strcpy(tempQueryfract, queryfract.c_str()); + cPara.push_back(tempQueryfract); + } + + + char** uchimeParameters; + uchimeParameters = new char*[cPara.size()]; + string commandString = ""; + for (int j = 0; j < cPara.size(); j++) { uchimeParameters[j] = cPara[j]; commandString += toString(cPara[j]) + " "; } + //int numArgs = cPara.size(); + + //uchime_main(numArgs, uchimeParameters); + //cout << "commandString = " << commandString << endl; + system(commandString.c_str()); + + //free memory + for(int j = 0; j < cPara.size(); j++) { delete cPara[j]; } + delete[] uchimeParameters; + + //remove "" from filenames + outputFName = outputFName.substr(1, outputFName.length()-2); + filename = filename.substr(1, filename.length()-2); + alns = alns.substr(1, alns.length()-2); + + if (pDataArray->m->control_pressed) { return 0; } + + //create accnos file from uchime results + ifstream in; + pDataArray->m->openInputFile(outputFName, in); + + ofstream out; + pDataArray->m->openOutputFile(accnos, out); + + numChimeras = 0; + while(!in.eof()) { + + if (pDataArray->m->control_pressed) { break; } + + string name = ""; + string chimeraFlag = ""; + in >> chimeraFlag >> name; + + for (int j = 0; j < 15; j++) { in >> chimeraFlag; } + pDataArray->m->gobble(in); + + if (chimeraFlag == "Y") { out << name << endl; numChimeras++; } + totalSeqs++; + } + in.close(); + out.close(); + + if (pDataArray->m->control_pressed) { return 0; } + + pDataArray->m->mothurOutEndLine(); pDataArray->m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(totalSeqs) + " sequences."); pDataArray->m->mothurOutEndLine(); + + pDataArray->count = totalSeqs; + pDataArray->numChimeras = numChimeras; + return totalSeqs; + + } + catch(exception& e) { + pDataArray->m->errorOut(e, "ChimeraUchimeCommand", "MyUchimeSeqsThreadFunction"); + exit(1); + } +} + +#endif + +/**************************************************************************************************/ + #endif diff --git a/classifyseqscommand.h b/classifyseqscommand.h index 58de969..eef96ff 100644 --- a/classifyseqscommand.h +++ b/classifyseqscommand.h @@ -89,7 +89,7 @@ private: //custom data structure for threads to use. // This is passed by void pointer so it can be any data type // that can be passed using a single void pointer (LPVOID). -typedef struct classifyData { +struct classifyData { string taxFName; string tempTFName; string filename; diff --git a/getoturepcommand.cpp b/getoturepcommand.cpp index 9742bcb..2f6f810 100644 --- a/getoturepcommand.cpp +++ b/getoturepcommand.cpp @@ -40,7 +40,7 @@ inline bool compareGroup(repStruct left, repStruct right){ vector GetOTURepCommand::setParameters(){ try { CommandParameter plist("list", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(plist); - CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(pfasta); + CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pfasta); CommandParameter pgroup("group", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pgroup); CommandParameter pphylip("phylip", "InputTypes", "", "", "PhylipColumn", "PhylipColumn", "none",false,false); parameters.push_back(pphylip); CommandParameter pname("name", "InputTypes", "", "", "none", "none", "ColumnName",false,false); parameters.push_back(pname); @@ -68,7 +68,7 @@ vector GetOTURepCommand::setParameters(){ string GetOTURepCommand::getHelpString(){ try { string helpString = ""; - helpString += "The get.oturep command parameters are phylip, column, list, fasta, name, group, large, weighted, cutoff, precision, groups, sorted and label. The fasta and list parameters are required, as well as phylip or column and name, unless you have valid current files.\n"; + helpString += "The get.oturep command parameters are phylip, column, list, fasta, name, group, large, weighted, cutoff, precision, groups, sorted and label. The list parameter is required, as well as phylip or column and name, unless you have valid current files.\n"; helpString += "The label parameter allows you to select what distance levels you would like a output files created for, and is separated by dashes.\n"; helpString += "The phylip or column parameter is required, but only one may be used. If you use a column file the name filename is required. \n"; helpString += "If you do not provide a cutoff value 10.00 is assumed. If you do not provide a precision value then 100 is assumed.\n"; @@ -197,11 +197,7 @@ GetOTURepCommand::GetOTURepCommand(string option) { //check for required parameters fastafile = validParameter.validFile(parameters, "fasta", true); - if (fastafile == "not found") { - fastafile = m->getFastaFile(); - if (fastafile != "") { m->mothurOut("Using " + fastafile + " as input file for the fasta parameter."); m->mothurOutEndLine(); } - else { m->mothurOut("You have no current fastafile and the fasta parameter is required."); m->mothurOutEndLine(); abort = true; } - } + if (fastafile == "not found") { fastafile = ""; } else if (fastafile == "not open") { abort = true; } else { m->setFastaFile(fastafile); } @@ -537,21 +533,30 @@ int GetOTURepCommand::execute(){ if (!weighted) { nameFileMap.clear(); } - //read fastafile - fasta = new FastaMap(); - fasta->readFastaFile(fastafile); - - //if user gave a namesfile then use it - if (namefile != "") { readNamesFile(); } - - //output create and output the .rep.fasta files - map::iterator itNameFile; - for (itNameFile = outputNameFiles.begin(); itNameFile != outputNameFiles.end(); itNameFile++) { - processNames(itNameFile->first, itNameFile->second); + + if (fastafile != "") { + //read fastafile + fasta = new FastaMap(); + fasta->readFastaFile(fastafile); + + //if user gave a namesfile then use it + if (namefile != "") { readNamesFile(); } + + //output create and output the .rep.fasta files + map::iterator itNameFile; + for (itNameFile = outputNameFiles.begin(); itNameFile != outputNameFiles.end(); itNameFile++) { + processFastaNames(itNameFile->first, itNameFile->second); + } + }else { + //output create and output the .rep.fasta files + map::iterator itNameFile; + for (itNameFile = outputNameFiles.begin(); itNameFile != outputNameFiles.end(); itNameFile++) { + processNames(itNameFile->first, itNameFile->second); + } } - delete fasta; - if (groupfile != "") { delete groupMap; } + + if (groupfile != "") { delete groupMap; } if (m->control_pressed) { return 0; } @@ -858,7 +863,7 @@ int GetOTURepCommand::process(ListVector* processList) { } } //********************************************************************************************************************** -int GetOTURepCommand::processNames(string filename, string label) { +int GetOTURepCommand::processFastaNames(string filename, string label) { try{ //create output file @@ -962,6 +967,40 @@ int GetOTURepCommand::processNames(string filename, string label) { return 0; } + catch(exception& e) { + m->errorOut(e, "GetOTURepCommand", "processFastaNames"); + exit(1); + } +} +//********************************************************************************************************************** +int GetOTURepCommand::processNames(string filename, string label) { + try{ + + //create output file + if (outputDir == "") { outputDir += m->hasPath(listfile); } + + ofstream out2; + string tempNameFile = filename + ".temp"; + m->openOutputFile(tempNameFile, out2); + + ifstream in; + m->openInputFile(filename, in); + + int i = 0; + string rep, binnames; + while (!in.eof()) { + if (m->control_pressed) { break; } + in >> i >> rep >> binnames; m->gobble(in); + out2 << rep << '\t' << binnames << endl; + } + in.close(); + out2.close(); + + m->mothurRemove(filename); + rename(tempNameFile.c_str(), filename.c_str()); + + return 0; + } catch(exception& e) { m->errorOut(e, "GetOTURepCommand", "processNames"); exit(1); diff --git a/getoturepcommand.h b/getoturepcommand.h index 07cccde..4168000 100644 --- a/getoturepcommand.h +++ b/getoturepcommand.h @@ -81,6 +81,7 @@ private: SeqMap getMap(int); string findRep(vector); // returns the name of the "representative" sequence of given bin or subset of a bin, for groups int processNames(string, string); + int processFastaNames(string, string); }; #endif diff --git a/mothurout.cpp b/mothurout.cpp index 1920221..90d6f37 100644 --- a/mothurout.cpp +++ b/mothurout.cpp @@ -434,7 +434,7 @@ void MothurOut::gobble(istream& f){ char d; while(isspace(d=f.get())) { ;} - f.putback(d); + if(!f.eof()) { f.putback(d); } } catch(exception& e) { errorOut(e, "MothurOut", "gobble"); @@ -446,7 +446,7 @@ void MothurOut::gobble(istringstream& f){ try { char d; while(isspace(d=f.get())) {;} - f.putback(d); + if(!f.eof()) { f.putback(d); } } catch(exception& e) { errorOut(e, "MothurOut", "gobble"); diff --git a/myutils.cpp b/myutils.cpp index 6e10a85..226b0f6 100755 --- a/myutils.cpp +++ b/myutils.cpp @@ -11,19 +11,19 @@ #include #include -#ifdef _MSC_VER -#include -#include -#include -#include -#include -#else +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) #include #include #include #include #include #include +#else +//#include +#include +#include +#include +#include #endif #include "myutils.h" @@ -46,11 +46,11 @@ static double g_PeakMemUseBytes; #if TEST_UTILS void TestUtils() - { +{ const int C = 100000000; for (int i = 0; i < C; ++i) ProgressStep(i, C, "something or other"); - + Progress("\n"); Progress("Longer message\r"); Sleep(1000); @@ -63,30 +63,30 @@ void TestUtils() const unsigned N = 10; unsigned M = 10; for (unsigned i = 0; i < N; ++i) - { + { ProgressStep(i, N, "Allocating 1MB blocks"); for (unsigned j = 0; j < M; ++j) - { + { ProgressStep(j, M, "Inner loop"); malloc(100000); Sleep(500); - } } } +} #endif // TEST_UTILS static void AllocBuffer(FILE *f) - { +{ int fd = fileno(f); if (fd < 0 || fd >= 256) return; if (g_IOBuffers[fd] == 0) g_IOBuffers[fd] = myalloc(char, MY_IO_BUFSIZ); setvbuf(f, g_IOBuffers[fd], _IOFBF, MY_IO_BUFSIZ); - } +} static void FreeBuffer(FILE *f) - { +{ int fd = fileno(f); if (fd < 0 || fd >= 256) return; @@ -94,12 +94,12 @@ static void FreeBuffer(FILE *f) return; myfree(g_IOBuffers[fd]); g_IOBuffers[fd] = 0; - } +} unsigned GetElapsedSecs() - { +{ return (unsigned) (time(0) - g_StartTime); - } +} static unsigned g_NewCalls; static unsigned g_FreeCalls; @@ -110,7 +110,7 @@ static double g_NetBytes; static double g_MaxNetBytes; void LogAllocStats() - { +{ Log("\n"); Log(" Allocs %u\n", g_NewCalls); Log(" Frees %u\n", g_FreeCalls); @@ -120,37 +120,47 @@ void LogAllocStats() Log(" Net bytes %s\n", MemBytesToStr(g_NetBytes)); Log("Max net bytes %s\n", MemBytesToStr(g_MaxNetBytes)); Log(" Peak total %s\n", MemBytesToStr(g_MaxNetBytes + g_InitialMemUseBytes)); - } +} bool StdioFileExists(const string &FileName) - { +{ struct stat SD; int i = stat(FileName.c_str(), &SD); return i == 0; - } +} void myassertfail(const char *Exp, const char *File, unsigned Line) - { +{ Die("%s(%u) assert failed: %s", File, Line, Exp); - } +} bool myisatty(int fd) - { +{ return isatty(fd) != 0; - } +} -#ifdef _MSC_VER -#include +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else +//#ifdef BIT_VERSION +//#include +//int fseeko(FILE *stream, off_t offset, int whence) +//// { +// off_t FilePos = _fseeki64(stream, offset, whence); +// return (FilePos == -1L) ? -1 : 0; +// } +//#define ftello(fm) (off_t) _ftelli64(fm) +//#else int fseeko(FILE *stream, off_t offset, int whence) - { - off_t FilePos = _fseeki64(stream, offset, whence); +{ + off_t FilePos = fseek(stream, offset, whence); return (FilePos == -1L) ? -1 : 0; - } -#define ftello(fm) (off_t) _ftelli64(fm) +} +#define ftello(fm) (off_t) ftell(fm) +//#endif #endif void LogStdioFileState(FILE *f) - { +{ unsigned long tellpos = (unsigned long) ftello(f); long fseek_pos = fseek(f, 0, SEEK_CUR); int fd = fileno(f); @@ -164,95 +174,102 @@ void LogStdioFileState(FILE *f) fpos_t fpos; int fgetpos_retval = fgetpos(f, &fpos); Log("fpos %ld (retval %d)\n", (long) fpos, fgetpos_retval); -// Log("eof %d\n", _eof(fd)); + // Log("eof %d\n", _eof(fd)); #endif -#ifdef _MSC_VER +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else +#ifdef BIT_VERSION __int64 pos64 = _ftelli64(f); Log("_ftelli64 %lld\n", pos64); +#else + __int32 pos32 = ftell(f); + Log("ftell %lld\n", pos32); + #endif - } +#endif +} FILE *OpenStdioFile(const string &FileName) - { +{ const char *Mode = "rb"; FILE *f = fopen(FileName.c_str(), Mode); if (f == 0) - { + { if (errno == EFBIG) - { + { if (sizeof(off_t) == 4) Die("File too big, off_t is 32 bits, recompile needed"); else Die("Cannot open '%s', file too big (off_t=%u bits)", - FileName.c_str(), sizeof(off_t)*8); - } - Die("Cannot open %s, errno=%d %s", - FileName.c_str(), errno, strerror(errno)); + FileName.c_str(), sizeof(off_t)*8); } + Die("Cannot open %s, errno=%d %s", + FileName.c_str(), errno, strerror(errno)); + } AllocBuffer(f); return f; - } +} FILE *CreateStdioFile(const string &FileName) - { +{ FILE *f = fopen(FileName.c_str(), "wb+"); if (0 == f) Die("Cannot create %s, errno=%d %s", - FileName.c_str(), errno, strerror(errno)); + FileName.c_str(), errno, strerror(errno)); AllocBuffer(f); return f; - } +} void SetStdioFilePos(FILE *f, off_t Pos) - { +{ if (0 == f) Die("SetStdioFilePos failed, f=NULL"); int Ok = fseeko(f, Pos, SEEK_SET); off_t NewPos = ftello(f); if (Ok != 0 || Pos != NewPos) - { + { LogStdioFileState(f); Die("SetStdioFilePos(%d) failed, Ok=%d NewPos=%d", - (int) Pos, Ok, (int) NewPos); - } + (int) Pos, Ok, (int) NewPos); } +} void ReadStdioFile(FILE *f, off_t Pos, void *Buffer, unsigned Bytes) - { +{ if (0 == f) Die("ReadStdioFile failed, f=NULL"); SetStdioFilePos(f, Pos); unsigned BytesRead = fread(Buffer, 1, Bytes, f); if (BytesRead != Bytes) - { + { LogStdioFileState(f); Die("ReadStdioFile failed, attempted %d bytes, read %d bytes, errno=%d", - (int) Bytes, (int) BytesRead, errno); - } + (int) Bytes, (int) BytesRead, errno); } +} void ReadStdioFile(FILE *f, void *Buffer, unsigned Bytes) - { +{ if (0 == f) Die("ReadStdioFile failed, f=NULL"); unsigned BytesRead = fread(Buffer, 1, Bytes, f); if (BytesRead != Bytes) - { + { LogStdioFileState(f); Die("ReadStdioFile failed, attempted %d bytes, read %d bytes, errno=%d", - (int) Bytes, (int) BytesRead, errno); - } + (int) Bytes, (int) BytesRead, errno); } +} // Return values from functions like lseek, ftell, fgetpos are // "undefined" for files that cannot seek. Attempt to detect // whether a file can seek by checking for error returns. bool CanSetStdioFilePos(FILE *f) - { -// Common special cases +{ + // Common special cases if (f == stdin || f == stdout || f == stderr) return false; - + fpos_t CurrPos; int ok1 = fgetpos(f, &CurrPos); if (ok1 < 0) @@ -266,14 +283,14 @@ bool CanSetStdioFilePos(FILE *f) if (!ok3 || !ok4) return false; return true; - } +} byte *ReadAllStdioFile(FILE *f, unsigned &FileSize) - { +{ const unsigned BUFF_SIZE = 1024*1024; - + if (CanSetStdioFilePos(f)) - { + { off_t Pos = GetStdioFilePos(f); off_t FileSize = GetStdioFileSize(f); if (FileSize > UINT_MAX) @@ -284,51 +301,51 @@ byte *ReadAllStdioFile(FILE *f, unsigned &FileSize) SetStdioFilePos(f, Pos); FileSize = unsigned(FileSize); return Buffer; - } - -// Can't seek, read one buffer at a time. + } + + // Can't seek, read one buffer at a time. FileSize = 0; - -// Just to initialize so that first call to realloc works. + + // Just to initialize so that first call to realloc works. byte *Buffer = (byte *) malloc(4); if (Buffer == 0) Die("ReadAllStdioFile, out of memory"); for (;;) - { + { Buffer = (byte *) realloc(Buffer, FileSize + BUFF_SIZE); unsigned BytesRead = fread(Buffer + FileSize, 1, BUFF_SIZE, f); FileSize += BytesRead; if (BytesRead < BUFF_SIZE) - { + { Buffer = (byte *) realloc(Buffer, FileSize); return Buffer; - } } } +} byte *ReadAllStdioFile(const std::string &FileName, off_t &FileSize) - { +{ #if WIN32 FILE *f = OpenStdioFile(FileName); FileSize = GetStdioFileSize(f); CloseStdioFile(f); - + HANDLE h = CreateFile(FileName.c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) Die("ReadAllStdioFile:Open(%s) failed", FileName.c_str()); - + unsigned uFileSize = (unsigned) FileSize; if ((off_t) uFileSize != FileSize) Die("File too big (%.1f Gb): %s", double(FileSize)/1e9, FileName.c_str()); - + byte *Buffer = myalloc(byte, uFileSize); DWORD BytesRead; ReadFile(h, Buffer, uFileSize, &BytesRead, NULL); if (FileSize != BytesRead) Die("ReadAllStdioFile:Error reading %s, attempted %u got %u", - FileName.c_str(), FileSize, (unsigned) BytesRead); - + FileName.c_str(), FileSize, (unsigned) BytesRead); + CloseHandle(h); return Buffer; #else @@ -349,56 +366,56 @@ byte *ReadAllStdioFile(const std::string &FileName, off_t &FileSize) size_t n = read(h, Buffer, stBytes); if (n != FileSize) Die("ReadAllStdioFile, Error reading %s, attempted %g got %g", - FileName.c_str(), (double) FileSize, (double) n); + FileName.c_str(), (double) FileSize, (double) n); close(h); return Buffer; #endif - } +} void WriteStdioFile(FILE *f, off_t Pos, const void *Buffer, unsigned Bytes) - { +{ if (0 == f) Die("WriteStdioFile failed, f=NULL"); SetStdioFilePos(f, Pos); unsigned BytesWritten = fwrite(Buffer, 1, Bytes, f); if (BytesWritten != Bytes) - { + { LogStdioFileState(f); Die("WriteStdioFile failed, attempted %d bytes, wrote %d bytes, errno=%d", - (int) Bytes, (int) BytesWritten, errno); - } + (int) Bytes, (int) BytesWritten, errno); } +} void WriteStdioFile(FILE *f, const void *Buffer, unsigned Bytes) - { +{ if (0 == f) Die("WriteStdioFile failed, f=NULL"); unsigned BytesWritten = fwrite(Buffer, 1, Bytes, f); if (BytesWritten != Bytes) - { + { LogStdioFileState(f); Die("WriteStdioFile failed, attempted %d bytes, wrote %d bytes, errno=%d", - (int) Bytes, (int) BytesWritten, errno); - } + (int) Bytes, (int) BytesWritten, errno); } +} // Return false on EOF, true if line successfully read. bool ReadLineStdioFile(FILE *f, char *Line, unsigned Bytes) - { +{ if (feof(f)) return false; if ((int) Bytes < 0) Die("ReadLineStdioFile: Bytes < 0"); char *RetVal = fgets(Line, (int) Bytes, f); if (NULL == RetVal) - { + { if (feof(f)) return false; if (ferror(f)) Die("ReadLineStdioFile: errno=%d", errno); Die("ReadLineStdioFile: fgets=0, feof=0, ferror=0"); - } - + } + if (RetVal != Line) Die("ReadLineStdioFile: fgets != Buffer"); unsigned n = strlen(Line); @@ -409,37 +426,37 @@ bool ReadLineStdioFile(FILE *f, char *Line, unsigned Bytes) if (n > 1 && (Line[n-2] == '\r' || Line[n-2] == '\n')) Line[n-2] = 0; return true; - } +} // Return false on EOF, true if line successfully read. bool ReadLineStdioFile(FILE *f, string &Line) - { +{ Line.clear(); for (;;) - { + { int c = fgetc(f); if (c == -1) - { + { if (feof(f)) - { + { if (!Line.empty()) return true; return false; - } - Die("ReadLineStdioFile, errno=%d", errno); } + Die("ReadLineStdioFile, errno=%d", errno); + } if (c == '\r') continue; if (c == '\n') return true; Line.push_back((char) c); - } } +} // Copies all of fFrom regardless of current // file position, appends to fTo. void AppendStdioFileToFile(FILE *fFrom, FILE *fTo) - { +{ off_t SavedFromPos = GetStdioFilePos(fFrom); off_t FileSize = GetStdioFileSize(fFrom); const off_t BUFF_SIZE = 1024*1024; @@ -447,108 +464,109 @@ void AppendStdioFileToFile(FILE *fFrom, FILE *fTo) SetStdioFilePos(fFrom, 0); off_t BytesRemaining = FileSize; while (BytesRemaining > 0) - { + { off_t BytesToRead = BytesRemaining; if (BytesToRead > BUFF_SIZE) BytesToRead = BUFF_SIZE; ReadStdioFile(fFrom, Buffer, (unsigned) BytesToRead); WriteStdioFile(fTo, Buffer, (unsigned) BytesToRead); BytesRemaining -= BytesToRead; - } - SetStdioFilePos(fFrom, SavedFromPos); } + SetStdioFilePos(fFrom, SavedFromPos); +} void RenameStdioFile(const string &FileNameFrom, const string &FileNameTo) - { +{ int Ok = rename(FileNameFrom.c_str(), FileNameTo.c_str()); if (Ok != 0) Die("RenameStdioFile(%s,%s) failed, errno=%d %s", - FileNameFrom.c_str(), FileNameTo.c_str(), errno, strerror(errno)); - } + FileNameFrom.c_str(), FileNameTo.c_str(), errno, strerror(errno)); +} void FlushStdioFile(FILE *f) - { +{ int Ok = fflush(f); if (Ok != 0) Die("fflush(%p)=%d,", f, Ok); - } +} void CloseStdioFile(FILE *f) - { +{ if (f == 0) return; int Ok = fclose(f); if (Ok != 0) Die("fclose(%p)=%d", f, Ok); FreeBuffer(f); - } +} off_t GetStdioFilePos(FILE *f) - { +{ off_t FilePos = ftello(f); if (FilePos < 0) Die("ftello=%d", (int) FilePos); return FilePos; - } +} off_t GetStdioFileSize(FILE *f) - { +{ off_t CurrentPos = GetStdioFilePos(f); - int Ok = fseeko(f, 0, SEEK_END); + off_t zeroPos = 0; + int Ok = fseeko(f, zeroPos, SEEK_END); if (Ok < 0) Die("fseek in GetFileSize"); - + off_t Length = ftello(f); if (Length < 0) Die("ftello in GetFileSize"); SetStdioFilePos(f, CurrentPos); return Length; - } +} void DeleteStdioFile(const string &FileName) - { +{ int Ok = remove(FileName.c_str()); if (Ok != 0) Die("remove(%s) failed, errno=%d %s", FileName.c_str(), errno, strerror(errno)); - } +} void myvstrprintf(string &Str, const char *Format, va_list ArgList) - { +{ static char szStr[MAX_FORMATTED_STRING_LENGTH]; vsnprintf(szStr, MAX_FORMATTED_STRING_LENGTH-1, Format, ArgList); szStr[MAX_FORMATTED_STRING_LENGTH - 1] = '\0'; Str.assign(szStr); - } +} void myvstrprintf(string &Str, const char *Format, ...) - { +{ va_list ArgList; va_start(ArgList, Format); myvstrprintf(Str, Format, ArgList); va_end(ArgList); - } +} FILE *g_fLog = 0; void SetLogFileName(const string &FileName) - { +{ if (g_fLog != 0) CloseStdioFile(g_fLog); g_fLog = 0; if (FileName.empty()) return; g_fLog = CreateStdioFile(FileName); - } +} void Log(const char *Format, ...) - { +{ if (g_fLog == 0) return; - + static bool InLog = false; if (InLog) return; - + InLog = true; va_list ArgList; va_start(ArgList, Format); @@ -556,97 +574,85 @@ void Log(const char *Format, ...) va_end(ArgList); fflush(g_fLog); InLog = false; - } +} void Die(const char *Format, ...) - { +{ static bool InDie = false; if (InDie) exit(1); InDie = true; string Msg; - + if (g_fLog != 0) setbuf(g_fLog, 0); va_list ArgList; va_start(ArgList, Format); myvstrprintf(Msg, Format, ArgList); va_end(ArgList); - + fprintf(stderr, "\n\n"); Log("\n"); time_t t = time(0); Log("%s", asctime(localtime(&t))); for (unsigned i = 0; i < g_Argv.size(); i++) - { + { fprintf(stderr, (i == 0) ? "%s" : " %s", g_Argv[i].c_str()); Log((i == 0) ? "%s" : " %s", g_Argv[i].c_str()); - } + } fprintf(stderr, "\n"); Log("\n"); - + time_t CurrentTime = time(0); unsigned ElapsedSeconds = unsigned(CurrentTime - g_StartTime); const char *sstr = SecsToStr(ElapsedSeconds); Log("Elapsed time: %s\n", sstr); - + const char *szStr = Msg.c_str(); fprintf(stderr, "\n---Fatal error---\n%s\n", szStr); Log("\n---Fatal error---\n%s\n", szStr); - -#ifdef _MSC_VER - if (IsDebuggerPresent()) - __debugbreak(); - _CrtSetDbgFlag(0); + +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else + //if (IsDebuggerPresent()) + // __debugbreak(); + //_CrtSetDbgFlag(0); #endif - + exit(1); - } +} void Warning(const char *Format, ...) - { +{ string Msg; - + va_list ArgList; va_start(ArgList, Format); myvstrprintf(Msg, Format, ArgList); va_end(ArgList); - + const char *szStr = Msg.c_str(); - + fprintf(stderr, "\nWARNING: %s\n", szStr); if (g_fLog != stdout) - { + { Log("\nWARNING: %s\n", szStr); fflush(g_fLog); - } } +} -#ifdef _MSC_VER -double GetMemUseBytes() - { - HANDLE hProc = GetCurrentProcess(); - PROCESS_MEMORY_COUNTERS PMC; - BOOL bOk = GetProcessMemoryInfo(hProc, &PMC, sizeof(PMC)); - if (!bOk) - return 1000000; - double Bytes = (double) PMC.WorkingSetSize; - if (Bytes > g_PeakMemUseBytes) - g_PeakMemUseBytes = Bytes; - return Bytes; - } -#elif linux || __linux__ +#if defined linux || __linux__ double GetMemUseBytes() - { +{ static char statm[64]; static int PageSize = 1; if (0 == statm[0]) - { + { PageSize = sysconf(_SC_PAGESIZE); pid_t pid = getpid(); sprintf(statm, "/proc/%d/statm", (int) pid); - } - + } + int fd = open(statm, O_RDONLY); if (-1 == fd) return 1000000; @@ -654,19 +660,19 @@ double GetMemUseBytes() int n = read(fd, Buffer, sizeof(Buffer) - 1); close(fd); fd = -1; - + if (n <= 0) return 1000000; - + Buffer[n] = 0; double Pages = atof(Buffer); - + double Bytes = Pages*PageSize; if (Bytes > g_PeakMemUseBytes) g_PeakMemUseBytes = Bytes; return Bytes; - } -#elif defined(__MACH__) +} +#elif defined(__APPLE__) || (__MACH__) #include #include #include @@ -688,7 +694,7 @@ double GetMemUseBytes() #define DEFAULT_MEM_USE 100000000.0 double GetMemUseBytes() - { +{ task_t mytask = mach_task_self(); struct task_basic_info ti; memset((void *) &ti, 0, sizeof(ti)); @@ -696,29 +702,29 @@ double GetMemUseBytes() kern_return_t ok = task_info(mytask, TASK_BASIC_INFO, (task_info_t) &ti, &count); if (ok == KERN_INVALID_ARGUMENT) return DEFAULT_MEM_USE; - + if (ok != KERN_SUCCESS) return DEFAULT_MEM_USE; - + double Bytes = (double ) ti.resident_size; if (Bytes > g_PeakMemUseBytes) g_PeakMemUseBytes = Bytes; return Bytes; - } +} #else double GetMemUseBytes() - { +{ return 0; - } +} #endif double GetPeakMemUseBytes() - { +{ return g_PeakMemUseBytes; - } +} const char *SecsToHHMMSS(int Secs) - { +{ int HH = Secs/3600; int MM = (Secs - HH*3600)/60; int SS = Secs%60; @@ -728,13 +734,13 @@ const char *SecsToHHMMSS(int Secs) else sprintf(Str, "%02d:%02d:%02d", HH, MM, SS); return Str; - } +} const char *SecsToStr(double Secs) - { +{ if (Secs >= 10.0) return SecsToHHMMSS((int) Secs); - + static char Str[16]; if (Secs < 1e-6) sprintf(Str, "%.2gs", Secs); @@ -743,12 +749,12 @@ const char *SecsToStr(double Secs) else sprintf(Str, "%.3fs", Secs); return Str; - } +} const char *MemBytesToStr(double Bytes) - { +{ static char Str[32]; - + if (Bytes < 1e6) sprintf(Str, "%.1fkb", Bytes/1e3); else if (Bytes < 10e6) @@ -762,12 +768,12 @@ const char *MemBytesToStr(double Bytes) else sprintf(Str, "%.3gb", Bytes); return Str; - } +} const char *IntToStr(unsigned i) - { +{ static char Str[32]; - + double d = (double) i; if (i < 10000) sprintf(Str, "%u", i); @@ -784,25 +790,25 @@ const char *IntToStr(unsigned i) else sprintf(Str, "%.3g", d); return Str; - } +} const char *FloatToStr(double d) - { +{ static char Str[32]; - + double a = fabs(d); if (a < 0.01) sprintf(Str, "%.3g", a); else if (a >= 0.01 && a < 1) sprintf(Str, "%.3f", a); else if (a <= 10 && a >= 1) - { + { double intpart; if (modf(a, &intpart) < 0.05) sprintf(Str, "%.0f", d); else sprintf(Str, "%.1f", d); - } + } else if (a > 10 && a < 10000) sprintf(Str, "%.0f", d); else if (a < 1e6) @@ -818,7 +824,7 @@ const char *FloatToStr(double d) else sprintf(Str, "%.3g", d); return Str; - } +} bool opt_quiet = false; bool opt_version = false; @@ -846,48 +852,48 @@ static unsigned g_StepCalls; static time_t g_TimeLastOutputStep; static string &GetProgressPrefixStr(string &s) - { +{ double Bytes = GetMemUseBytes(); unsigned Secs = GetElapsedSecs(); s = string(SecsToHHMMSS(Secs)); if (Bytes > 0) - { + { s.push_back(' '); char Str[32]; sprintf(Str, "%5.5s", MemBytesToStr(Bytes)); s += string(Str); - } + } s.push_back(' '); return s; - } +} void ProgressLog(const char *Format, ...) - { +{ string Str; va_list ArgList; va_start(ArgList, Format); myvstrprintf(Str, Format, ArgList); va_end(ArgList); - + Log("%s", Str.c_str()); Progress("%s", Str.c_str()); - } +} void Progress(const char *Format, ...) - { +{ if (opt_quiet) return; - + string Str; va_list ArgList; va_start(ArgList, Format); myvstrprintf(Str, Format, ArgList); va_end(ArgList); - + #if 0 Log("Progress("); for (unsigned i = 0; i < Str.size(); ++i) - { + { char c = Str[i]; if (c == '\r') Log("\\r"); @@ -895,26 +901,26 @@ void Progress(const char *Format, ...) Log("\\n"); else Log("%c", c); - } + } Log(")\n"); #endif //0 - + for (unsigned i = 0; i < Str.size(); ++i) - { + { if (g_CurrProgressLineLength == 0) - { + { string s; GetProgressPrefixStr(s); for (unsigned j = 0; j < s.size(); ++j) - { + { fputc(s[j], stderr); ++g_CurrProgressLineLength; - } } - + } + char c = Str[i]; if (c == '\n' || c == '\r') - { + { for (unsigned j = g_CurrProgressLineLength; j < g_LastProgressLineLength; ++j) fputc(' ', stderr); if (c == '\n') @@ -923,77 +929,77 @@ void Progress(const char *Format, ...) g_LastProgressLineLength = g_CurrProgressLineLength; g_CurrProgressLineLength = 0; fputc(c, stderr); - } + } else - { + { fputc(c, stderr); ++g_CurrProgressLineLength; - } } } +} void ProgressExit() - { +{ time_t Now = time(0); struct tm *t = localtime(&Now); const char *s = asctime(t); unsigned Secs = GetElapsedSecs(); - + Log("\n"); Log("Finished %s", s); // there is a newline in s Log("Elapsed time %s\n", SecsToHHMMSS((int) Secs)); Log("Max memory %s\n", MemBytesToStr(g_PeakMemUseBytes)); #if WIN32 && DEBUG -// Skip exit(), which can be very slow in DEBUG build -// VERY DANGEROUS practice, because it skips global destructors. -// But if you know the rules, you can break 'em, right? - ExitProcess(0); + // Skip exit(), which can be very slow in DEBUG build + // VERY DANGEROUS practice, because it skips global destructors. + // But if you know the rules, you can break 'em, right? + //ExitProcess(0); #endif - } +} const char *PctStr(double x, double y) - { +{ if (y == 0) - { + { if (x == 0) return "100%"; else return "inf%"; - } + } static char Str[16]; double p = x*100.0/y; sprintf(Str, "%5.1f%%", p); return Str; - } +} string &GetProgressLevelStr(string &s) - { +{ unsigned Index = g_ProgressIndex; unsigned Count = g_ProgressCount; if (Count == UINT_MAX) - { + { if (Index == UINT_MAX) s = "100%"; else - { + { char Tmp[16]; sprintf(Tmp, "%u", Index); s = Tmp; - } } + } else s = string(PctStr(Index+1, Count)); s += string(" ") + g_ProgressDesc; return s; - } +} void ProgressStep(unsigned i, unsigned N, const char *Format, ...) - { +{ if (opt_quiet) return; - + if (i == 0) - { + { string Str; va_list ArgList; va_start(ArgList, Format); @@ -1007,61 +1013,61 @@ void ProgressStep(unsigned i, unsigned N, const char *Format, ...) g_TimeLastOutputStep = 0; if (g_CurrProgressLineLength > 0) Progress("\n"); - } - + } + if (i >= N && i != UINT_MAX) Die("ProgressStep(%u,%u)", i, N); bool IsLastStep = (i == UINT_MAX || i + 1 == N); if (!IsLastStep) - { + { ++g_StepCalls; if (g_StepCalls%g_CountsInterval != 0) return; - + time_t Now = time(0); if (Now == g_TimeLastOutputStep) - { + { if (g_CountsInterval < 128) g_CountsInterval = (g_CountsInterval*3)/2; else g_CountsInterval += 64; return; - } + } else - { + { time_t Secs = Now - g_TimeLastOutputStep; if (Secs > 1) g_CountsInterval = unsigned(g_CountsInterval/(Secs*8)); - } - + } + if (g_CountsInterval < 1) g_CountsInterval = 1; - + g_TimeLastOutputStep = Now; - } - + } + g_ProgressIndex = i; - + if (i > 0) - { + { va_list ArgList; va_start(ArgList, Format); myvstrprintf(g_ProgressDesc, Format, ArgList); - } - + } + string LevelStr; GetProgressLevelStr(LevelStr); Progress(" %s\r", LevelStr.c_str()); - + if (IsLastStep) - { + { g_CountsInterval = 1; fputc('\n', stderr); - } } +} enum OptType - { +{ OT_Flag, OT_Tog, OT_Int, @@ -1069,10 +1075,10 @@ enum OptType OT_Str, OT_Float, OT_Enum - }; +}; struct OptInfo - { +{ void *Value; bool *OptSet; string LongName; @@ -1084,84 +1090,84 @@ struct OptInfo double dMin; double dMax; map EnumValues; - + bool bDefault; int iDefault; unsigned uDefault; double dDefault; string strDefault; - + string Help; - + bool operator<(const OptInfo &rhs) const - { + { return LongName < rhs.LongName; - } - }; + } +}; static set g_Opts; void Help() - { +{ printf("\n"); - + void Usage(); Usage(); - + for (set::const_iterator p = g_Opts.begin(); p != g_Opts.end(); ++p) - { + { const OptInfo &Opt = *p; - + printf("\n"); string LongName = Opt.LongName.c_str(); if (Opt.Type == OT_Tog) LongName = string("[no]") + LongName; printf(" --%s ", LongName.c_str()); - + switch (Opt.Type) - { - case OT_Flag: - break; - case OT_Tog: - break; - case OT_Int: - printf(""); - break; - case OT_Uns: - printf(""); - break; - case OT_Str: - printf(""); - break; - case OT_Float: - printf(""); - break; - case OT_Enum: - printf(""); - break; - default: - printf("??type"); - break; - } - + { + case OT_Flag: + break; + case OT_Tog: + break; + case OT_Int: + printf(""); + break; + case OT_Uns: + printf(""); + break; + case OT_Str: + printf(""); + break; + case OT_Float: + printf(""); + break; + case OT_Enum: + printf(""); + break; + default: + printf("??type"); + break; + } + printf(" "); const string &s = Opt.Help; for (string::const_iterator q = s.begin(); q != s.end(); ++q) - { + { char c = *q; if (c == '\n') printf("\n "); else printf("%c", c); - } - printf("\n"); } + printf("\n"); + } printf("\n"); exit(0); - } +} void CmdLineErr(const char *Format, ...) - { +{ va_list ArgList; va_start(ArgList, Format); string Str; @@ -1173,41 +1179,42 @@ void CmdLineErr(const char *Format, ...) fprintf(stderr, "For list of command-line options use --help.\n"); fprintf(stderr, "\n"); exit(1); - } +} static set::iterator GetOptInfo(const string &LongName, - bool ErrIfNotFound) - { + bool ErrIfNotFound) +{ for (set::iterator p = g_Opts.begin(); - p != g_Opts.end(); ++p) - { + p != g_Opts.end(); ++p) + { const OptInfo &Opt = *p; if (Opt.LongName == LongName) return p; if (Opt.Type == OT_Tog && "no" + Opt.LongName == LongName) return p; - } + } if (ErrIfNotFound) CmdLineErr("Option --%s is invalid", LongName.c_str()); return g_Opts.end(); - } +} static void AddOpt(const OptInfo &Opt) - { +{ if (GetOptInfo(Opt.LongName, false) != g_Opts.end()) Die("Option --%s defined twice", Opt.LongName.c_str()); g_Opts.insert(Opt); - } +} -#ifdef _MSC_VER +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else #pragma warning(disable: 4505) // unreferenced local function #endif static void DefineFlagOpt(const string &LongName, const string &Help, - void *Value, bool *OptSet) - { + void *Value, bool *OptSet) +{ *(bool *) Value = false; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1216,13 +1223,13 @@ static void DefineFlagOpt(const string &LongName, const string &Help, Opt.Help = Help; Opt.Type = OT_Flag; AddOpt(Opt); - } +} static void DefineTogOpt(const string &LongName, bool Default, const string &Help, - void *Value, bool *OptSet) - { + void *Value, bool *OptSet) +{ *(bool *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1231,13 +1238,13 @@ static void DefineTogOpt(const string &LongName, bool Default, const string &Hel Opt.Help = Help; Opt.Type = OT_Tog; AddOpt(Opt); - } +} static void DefineIntOpt(const string &LongName, int Default, int Min, int Max, - const string &Help, void *Value, bool *OptSet) - { + const string &Help, void *Value, bool *OptSet) +{ *(int *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1248,13 +1255,13 @@ static void DefineIntOpt(const string &LongName, int Default, int Min, int Max, Opt.Help = Help; Opt.Type = OT_Int; AddOpt(Opt); - } +} static void DefineUnsOpt(const string &LongName, unsigned Default, unsigned Min, - unsigned Max, const string &Help, void *Value, bool *OptSet) - { + unsigned Max, const string &Help, void *Value, bool *OptSet) +{ *(unsigned *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1265,13 +1272,13 @@ static void DefineUnsOpt(const string &LongName, unsigned Default, unsigned Min, Opt.Help = Help; Opt.Type = OT_Uns; AddOpt(Opt); - } +} static void DefineFloatOpt(const string &LongName, double Default, double Min, - double Max, const string &Help, void *Value, bool *OptSet) - { + double Max, const string &Help, void *Value, bool *OptSet) +{ *(double *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1282,13 +1289,13 @@ static void DefineFloatOpt(const string &LongName, double Default, double Min, Opt.Help = Help; Opt.Type = OT_Float; AddOpt(Opt); - } +} static void DefineStrOpt(const string &LongName, const char *Default, - const string &Help, void *Value, bool *OptSet) - { + const string &Help, void *Value, bool *OptSet) +{ *(string *) Value = (Default == 0 ? "" : string(Default)); - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1297,34 +1304,34 @@ static void DefineStrOpt(const string &LongName, const char *Default, Opt.Help = Help; Opt.Type = OT_Str; AddOpt(Opt); - } +} static void ParseEnumValues(const string &Values, map &EnumValues) - { +{ EnumValues.clear(); string Name; string Value; bool Eq = false; for (string::const_iterator p = Values.begin(); ; ++p) - { + { char c = (p == Values.end() ? '|' : *p); if (isspace(c)) ; else if (c == '|') - { + { if (EnumValues.find(Name) != EnumValues.end()) Die("Invalid enum values, '%s' defined twice: '%s'", - Name.c_str(), Values.c_str()); + Name.c_str(), Values.c_str()); if (Name.empty() || Value.empty()) Die("Invalid enum values, empty name or value: '%s'", - Values.c_str()); - + Values.c_str()); + EnumValues[Name] = atoi(Value.c_str()); Name.clear(); Value.clear(); Eq = false; - } + } else if (c == '=') Eq = true; else if (Eq) @@ -1333,14 +1340,14 @@ static void ParseEnumValues(const string &Values, map &EnumVal Name.push_back(c); if (p == Values.end()) return; - } } +} static void DefineEnumOpt(const string &LongName, const string &ShortName, - int Default, const string &Values, const string &Help, void *Value) - { + int Default, const string &Values, const string &Help, void *Value) +{ *(int *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.LongName = LongName; @@ -1349,7 +1356,7 @@ static void DefineEnumOpt(const string &LongName, const string &ShortName, Opt.Type = OT_Enum; ParseEnumValues(Values, Opt.EnumValues); AddOpt(Opt); - } +} #undef FLAG_OPT #undef TOG_OPT #undef INT_OPT @@ -1367,110 +1374,110 @@ static void DefineEnumOpt(const string &LongName, const string &ShortName, #include "myopts.h" static int EnumStrToInt(const OptInfo &Opt, const string &Value) - { +{ const map &e = Opt.EnumValues; string s; for (map::const_iterator p = e.begin(); p != e.end(); ++p) - { + { if (Value == p->first) return p->second; s += " " + p->first; - } + } CmdLineErr("--%s %s not recognized, valid are: %s", - Opt.LongName.c_str(), Value.c_str(), s.c_str()); + Opt.LongName.c_str(), Value.c_str(), s.c_str()); ureturn(-1); - } +} static void SetOpt(OptInfo &Opt, const string &Value) - { +{ *Opt.OptSet = true; switch (Opt.Type) + { + case OT_Int: { - case OT_Int: - { - *(int *) Opt.Value = atoi(Value.c_str()); - break; + *(int *) Opt.Value = atoi(Value.c_str()); + break; } - case OT_Uns: + case OT_Uns: { - unsigned uValue = 0; - int n = sscanf(Value.c_str(), "%u", &uValue); - if (n != 1) - CmdLineErr("Invalid value '%s' for --%s", - Value.c_str(), Opt.LongName.c_str()); - *(unsigned *) Opt.Value = uValue; - break; + unsigned uValue = 0; + int n = sscanf(Value.c_str(), "%u", &uValue); + if (n != 1) + CmdLineErr("Invalid value '%s' for --%s", + Value.c_str(), Opt.LongName.c_str()); + *(unsigned *) Opt.Value = uValue; + break; } - case OT_Float: + case OT_Float: { - *(double *) Opt.Value = atof(Value.c_str()); - break; + *(double *) Opt.Value = atof(Value.c_str()); + break; } - case OT_Str: + case OT_Str: { - *(string *) Opt.Value = Value; - break; + *(string *) Opt.Value = Value; + break; } - case OT_Enum: + case OT_Enum: { - *(int *) Opt.Value = EnumStrToInt(Opt, Value); - break; - } - default: - asserta(false); + *(int *) Opt.Value = EnumStrToInt(Opt, Value); + break; } + default: + asserta(false); } +} void LogOpts() - { +{ for (set::const_iterator p = g_Opts.begin(); p != g_Opts.end(); ++p) - { + { const OptInfo &Opt = *p; Log("%s = ", Opt.LongName.c_str()); switch (Opt.Type) + { + case OT_Flag: + Log("%s", (*(bool *) Opt.Value) ? "yes" : "no"); + break; + case OT_Tog: + Log("%s", (*(bool *) Opt.Value) ? "on" : "off"); + break; + case OT_Int: + Log("%d", *(int *) Opt.Value); + break; + case OT_Uns: + Log("%u", *(unsigned *) Opt.Value); + break; + case OT_Float: { - case OT_Flag: - Log("%s", (*(bool *) Opt.Value) ? "yes" : "no"); - break; - case OT_Tog: - Log("%s", (*(bool *) Opt.Value) ? "on" : "off"); - break; - case OT_Int: - Log("%d", *(int *) Opt.Value); - break; - case OT_Uns: - Log("%u", *(unsigned *) Opt.Value); - break; - case OT_Float: - { - double Value = *(double *) Opt.Value; - if (Value == FLT_MAX) - Log("*"); - else - Log("%g", Value); - break; - } - case OT_Str: - Log("%s", (*(string *) Opt.Value).c_str()); - break; - case OT_Enum: - Log("%d", *(int *) Opt.Value); - break; - default: - asserta(false); + double Value = *(double *) Opt.Value; + if (Value == FLT_MAX) + Log("*"); + else + Log("%g", Value); + break; } - Log("\n"); + case OT_Str: + Log("%s", (*(string *) Opt.Value).c_str()); + break; + case OT_Enum: + Log("%d", *(int *) Opt.Value); + break; + default: + asserta(false); } + Log("\n"); } +} static void CompilerInfo() - { +{ #ifdef _FILE_OFFSET_BITS printf("_FILE_OFFSET_BITS=%d\n", _FILE_OFFSET_BITS); #else printf("_FILE_OFFSET_BITS not defined\n"); #endif - + #define x(t) printf("sizeof(" #t ") = %d\n", (int) sizeof(t)); x(int) x(long) @@ -1480,60 +1487,61 @@ static void CompilerInfo() x(off_t) #undef x exit(0); - } +} void Split(const string &Str, vector &Fields, char Sep) - { +{ Fields.clear(); const unsigned Length = (unsigned) Str.size(); string s; for (unsigned i = 0; i < Length; ++i) - { + { char c = Str[i]; if ((Sep == 0 && isspace(c)) || c == Sep) - { + { if (!s.empty() || Sep != 0) Fields.push_back(s); s.clear(); - } + } else s.push_back(c); - } + } if (!s.empty()) Fields.push_back(s); - } +} static void GetArgsFromFile(const string &FileName, vector &Args) - { +{ Args.clear(); - + FILE *f = OpenStdioFile(FileName); string Line; while (ReadLineStdioFile(f, Line)) - { + { size_t n = Line.find('#'); if (n != string::npos) Line = Line.substr(0, n); vector Fields; Split(Line, Fields); Args.insert(Args.end(), Fields.begin(), Fields.end()); - } - CloseStdioFile(f); } + CloseStdioFile(f); +} void MyCmdLine(int argc, char **argv) - { +{ + g_Opts.clear(); g_Argv.clear(); static unsigned RecurseDepth = 0; ++RecurseDepth; - + DefineFlagOpt("compilerinfo", "Write info about compiler types and #defines to stdout.", - (void *) &opt_compilerinfo, &optset_compilerinfo); + (void *) &opt_compilerinfo, &optset_compilerinfo); DefineFlagOpt("quiet", "Turn off progress messages.", (void *) &opt_quiet, &optset_quiet); DefineFlagOpt("version", "Show version and exit.", (void *) &opt_version, &optset_version); DefineFlagOpt("logopts", "Log options.", (void *) &opt_logopts, &optset_logopts); DefineFlagOpt("help", "Display command-line options.", (void *) &opt_help, &optset_help); DefineStrOpt("log", "", "Log file name.", (void *) &opt_log, &optset_log); - + #undef FLAG_OPT #undef TOG_OPT #undef INT_OPT @@ -1549,93 +1557,93 @@ void MyCmdLine(int argc, char **argv) #define STR_OPT(LongName, Default) DefineStrOpt(#LongName, Default, "help", (void *) &opt_##LongName, &optset_##LongName); #define ENUM_OPT(LongName, Values, Default) DefineEnumOpt(#LongName, Values, Default, "help", (void *) &opt_##LongName, &optset_##LongName); #include "myopts.h" - + if (RecurseDepth == 0) g_Argv.clear(); - - for (int i = 0; i < argc; ++i) { + + for (int i = 0; i < argc; ++i) g_Argv.push_back(string(argv[i])); - } - + + int i = 1; for (;;) - { + { if (i >= argc) break; const string &Arg = g_Argv[i]; - + if (Arg.empty()) continue; else if (Arg == "file:" && i + 1 < argc) - { + { const string &FileName = g_Argv[i+1]; vector Args; GetArgsFromFile(FileName, Args); for (vector::const_iterator p = Args.begin(); - p != Args.end(); ++p) - { + p != Args.end(); ++p) + { g_Argv.push_back(*p); ++argc; - } + } i += 2; continue; - } + } else if (Arg.size() > 1 && Arg[0] == '-') - { + { string LongName = (Arg.size() > 2 && Arg[1] == '-' ? Arg.substr(2) : Arg.substr(1)); OptInfo Opt = *GetOptInfo(LongName, true); *Opt.OptSet = true; if (Opt.Type == OT_Flag) - { + { g_Opts.erase(Opt); *(bool *) Opt.Value = true; g_Opts.insert(Opt); ++i; continue; - } + } else if (Opt.Type == OT_Tog) - { + { g_Opts.erase(Opt); if (string("no") + Opt.LongName == LongName) *(bool *) Opt.Value = false; else - { + { asserta(Opt.LongName == LongName); *(bool *) Opt.Value = true; - } + } g_Opts.insert(Opt); ++i; continue; - } - + } + ++i; if (i >= argc) CmdLineErr("Missing value for option --%s", LongName.c_str()); - + string Value = g_Argv[i]; SetOpt(Opt, Value); - + ++i; continue; - } + } else CmdLineErr("Expected -option_name or --option_name, got '%s'", Arg.c_str()); - } - + } + --RecurseDepth; if (RecurseDepth > 0) return; - + if (opt_help) Help(); - + if (opt_compilerinfo) CompilerInfo(); - + SetLogFileName(opt_log); - + if (opt_log != "") - { + { for (int i = 0; i < argc; ++i) Log("%s%s", i == 0 ? "" : " ", g_Argv[i].c_str()); Log("\n"); @@ -1645,57 +1653,57 @@ void MyCmdLine(int argc, char **argv) Log("Started %s", s); // there is a newline in s Log("Version " MY_VERSION ".%s\n", SVN_VERSION); Log("\n"); - } - + } + if (opt_logopts) LogOpts(); - } +} double Pct(double x, double y) - { +{ if (y == 0.0f) return 0.0f; return (x*100.0f)/y; - } +} void GetCmdLine(string &s) - { +{ s.clear(); for (unsigned i = 0; i < SIZE(g_Argv); ++i) - { + { if (i > 0) s += " "; s += g_Argv[i]; - } } +} char *mystrsave(const char *s) - { +{ unsigned n = unsigned(strlen(s)); char *t = myalloc(char, n+1); memcpy(t, s, n+1); return t; - } +} void Logu(unsigned u, unsigned w, unsigned prefixspaces) - { +{ for (unsigned i = 0; i < prefixspaces; ++i) Log(" "); if (u == UINT_MAX) Log("%*.*s", w, w, "*"); else Log("%*u", w, u); - } +} void Logf(float x, unsigned w, unsigned prefixspaces) - { +{ for (unsigned i = 0; i < prefixspaces; ++i) Log(" "); if (x == FLT_MAX) Log("%*.*s", w, w, "*"); else Log("%*.2f", w, x); - } +} static uint32 g_SLCG_state = 1; @@ -1707,65 +1715,65 @@ static uint32 g_SLCG_c = 2531011; // Simple Linear Congruential Generator // Bad properties; used just to initialize the better generator. static uint32 SLCG_rand() - { +{ g_SLCG_state = g_SLCG_state*g_SLCG_a + g_SLCG_c; return g_SLCG_state; - } +} static void SLCG_srand(uint32 Seed) - { +{ g_SLCG_state = Seed; for (int i = 0; i < 10; ++i) SLCG_rand(); - } +} /*** -A multiply-with-carry random number generator, see: -http://en.wikipedia.org/wiki/Multiply-with-carry - -The particular multipliers used here were found on -the web where they are attributed to George Marsaglia. -***/ + A multiply-with-carry random number generator, see: + http://en.wikipedia.org/wiki/Multiply-with-carry + + The particular multipliers used here were found on + the web where they are attributed to George Marsaglia. + ***/ static bool g_InitRandDone = false; static uint32 g_X[5]; uint32 RandInt32() - { +{ InitRand(); - + uint64 Sum = 2111111111*(uint64) g_X[3] + 1492*(uint64) g_X[2] + - 1776*(uint64) g_X[1] + 5115*(uint64) g_X[0] + g_X[4]; + 1776*(uint64) g_X[1] + 5115*(uint64) g_X[0] + g_X[4]; g_X[3] = g_X[2]; g_X[2] = g_X[1]; g_X[1] = g_X[0]; g_X[4] = (uint32) (Sum >> 32); g_X[0] = (uint32) Sum; return g_X[0]; - } +} unsigned randu32() - { +{ return (unsigned) RandInt32(); - } +} void InitRand() - { +{ if (g_InitRandDone) return; -// Do this first to avoid recursion + // Do this first to avoid recursion g_InitRandDone = true; - + unsigned Seed = (optset_randseed ? opt_randseed : (unsigned) (time(0)*getpid())); Log("RandSeed=%u\n", Seed); SLCG_srand(Seed); - + for (unsigned i = 0; i < 5; i++) g_X[i] = SLCG_rand(); - + for (unsigned i = 0; i < 100; i++) RandInt32(); - } +} // MUST COME AT END BECAUSE OF #undef #if RCE_MALLOC @@ -1773,72 +1781,72 @@ void InitRand() #undef myfree #undef myfree2 void *mymalloc(unsigned bytes, const char *FileName, int Line) - { +{ void *rce_malloc(unsigned bytes, const char *FileName, int Line); return rce_malloc(bytes, FileName, Line); - } +} void myfree(void *p, const char *FileName, int Line) - { +{ void rce_free(void *p, const char *FileName, int Line); rce_free(p, FileName, Line); - } +} void myfree2(void *p, unsigned bytes, const char *FileName, int Line) - { +{ void rce_free(void *p, const char *FileName, int Line); rce_free(p, FileName, Line); - } +} #else // RCE_MALLOC void *mymalloc(unsigned bytes) - { +{ ++g_NewCalls; if (g_InitialMemUseBytes == 0) g_InitialMemUseBytes = GetMemUseBytes(); - + g_TotalAllocBytes += bytes; g_NetBytes += bytes; if (g_NetBytes > g_MaxNetBytes) - { + { if (g_NetBytes > g_MaxNetBytes + 10000000) GetMemUseBytes();//to force update of peak g_MaxNetBytes = g_NetBytes; - } + } void *p = malloc(bytes); //void *p = _malloc_dbg(bytes, _NORMAL_BLOCK, __FILE__, __LINE__); if (0 == p) - { + { double b = GetMemUseBytes(); fprintf(stderr, "\nOut of memory mymalloc(%u), curr %.3g bytes", - (unsigned) bytes, b); + (unsigned) bytes, b); void LogAllocs(); LogAllocs(); #if DEBUG && defined(_MSC_VER) asserta(_CrtCheckMemory()); #endif Die("Out of memory, mymalloc(%u), curr %.3g bytes\n", - (unsigned) bytes, b); - } - return p; + (unsigned) bytes, b); } + return p; +} void myfree(void *p) - { +{ if (p == 0) return; free(p); //_free_dbg(p, _NORMAL_BLOCK); - } +} void myfree2(void *p, unsigned bytes) - { +{ ++g_FreeCalls; g_TotalFreeBytes += bytes; g_NetBytes -= bytes; - + if (p == 0) return; free(p); - } +} #endif diff --git a/phylotree.cpp b/phylotree.cpp index 6ca3636..5438147 100644 --- a/phylotree.cpp +++ b/phylotree.cpp @@ -618,9 +618,10 @@ bool PhyloTree::ErrorCheck(vector templateFileNames){ okay = false; } - templateFileNames.erase(templateFileNames.begin()+i); - i--; + //templateFileNames.erase(templateFileNames.begin()+i); + //i--; } + templateFileNames.clear(); if (taxonomyFileNames.size() > 0) { //there are names in tax file that are not in template okay = false; diff --git a/preclustercommand.h b/preclustercommand.h index 2868004..6f10618 100644 --- a/preclustercommand.h +++ b/preclustercommand.h @@ -82,7 +82,7 @@ private: //custom data structure for threads to use. // This is passed by void pointer so it can be any data type // that can be passed using a single void pointer (LPVOID). -typedef struct preClusterData { +struct preClusterData { string fastafile; string namefile; string groupfile; @@ -277,7 +277,7 @@ static DWORD WINAPI MyPreclusterThreadFunction(LPVOID lpParam){ } catch(exception& e) { - pDataArray->m->errorOut(e, "AlignCommand", "MyPreclusterThreadFunction"); + pDataArray->m->errorOut(e, "PreClusterCommand", "MyPreclusterThreadFunction"); exit(1); } } diff --git a/shhhercommand.h b/shhhercommand.h index 4d9bcbb..b3a0071 100644 --- a/shhhercommand.h +++ b/shhhercommand.h @@ -129,7 +129,7 @@ private: //custom data structure for threads to use. // This is passed by void pointer so it can be any data type // that can be passed using a single void pointer (LPVOID). -typedef struct flowDistParentForkData { +struct flowDistParentForkData { string distFileName; vector mapUniqueToSeq; vector mapSeqToUnique; diff --git a/timing.h b/timing.h index b566e1b..0a80aee 100644 --- a/timing.h +++ b/timing.h @@ -9,10 +9,10 @@ #define BG_TIMING 0 #endif -//#if UCHIMES +#if UCHIMES #undef TIMING #define TIMING 0 -//#endif +#endif #if TIMING diff --git a/trimflowscommand.h b/trimflowscommand.h index e3a2814..0dc1cd9 100644 --- a/trimflowscommand.h +++ b/trimflowscommand.h @@ -83,7 +83,7 @@ private: //custom data structure for threads to use. // This is passed by void pointer so it can be any data type // that can be passed using a single void pointer (LPVOID). -typedef struct trimFlowData { +struct trimFlowData { string flowFileName; string trimFlowFileName; string scrapFlowFileName; -- 2.39.2