int main(int argc, char** argv) { char c; unsigned int i, j, k; MMPool *mmPool; dictionary *programInput, *ini; char argumentText[11] = "argument:0"; double startTime; double elapsedTime = 0, totalElapsedTime = 0; BWT *bwt; HSP *hsp; unsigned char charMap[256]; unsigned char *convertedKey; unsigned int *packedKey; unsigned int found; unsigned int numberOfPattern, numberOfPatternFound; unsigned int saIndexLeft, saIndexRight; SaIndexGroupNew *saIndexGroup; SaIndexList *tempSaIndex1, *tempSaIndex2; unsigned int numberOfSaIndexGroup; HitList *hitList; unsigned int textPositionMatched, textPositionRetrieved; unsigned long long totalTextPositionMatched, totalTextPositionRetrieved; BWTSaRetrievalStatistics BWTSaRetrievalStatistics; FILE *logFile; init(textPositionRetrieved); // to avoid compiler warning only init(textPositionMatched); // to avoid compiler warning only programInput = ParseInput(argc, argv); ini = ParseIniFile(); ProcessIni(); ValidateIni(); PrintIni(); if (Confirmation == TRUE) { printf("BWT Search. Press Y to go or N to cancel. "); c = (char)getchar(); while (c != 'y' && c != 'Y' && c != 'n' && c!= 'N') { c = (char)getchar(); } if (c == 'n' || c == 'N') { exit(0); } } startTime = setStartTime(); MMMasterInitialize(1, 0, FALSE, NULL); mmPool = MMPoolCreate(PoolSize); // Load Database printf("Loading Database.."); fflush(stdout); bwt = BWTLoad(mmPool, BWTCodeFileName, BWTOccValueFileName, SaValueFileName, NULL, SaIndexFileName, NULL); HSPFillCharMap(charMap); hsp = HSPLoad(mmPool, PackedDNAFileName, AnnotationFileName, AmbiguityFileName, MAX_SEARCH_PATTERN_LENGTH / CHAR_PER_WORD); if (bwt->textLength != hsp->dnaLength) { fprintf(stderr, "BWT-BLAST: Database length inconsistent!\n"); exit(1); } if (LogFileName[0] != '\0') { logFile = fopen64(LogFileName, "w"); if (logFile == NULL) { fprintf(stderr, "Cannot open log file!\n"); exit(1); } } else { logFile = NULL; } packedKey = MMPoolDispatch(mmPool, WordPackedLengthFromText(MAX_SEARCH_PATTERN_LENGTH, BIT_PER_CHAR)); convertedKey = MMPoolDispatch(mmPool, MAX_SEARCH_PATTERN_LENGTH); saIndexGroup = MMUnitAllocate(MaxNumberOfHitGroups * sizeof(SaIndexGroup)); hitList = MMUnitAllocate(MaxNumberOfTextPosition * sizeof(HitList)); tempSaIndex1 = MMUnitAllocate(MaxNumberOfTextPosition * sizeof(SaIndexList)); tempSaIndex2 = MMUnitAllocate(MaxNumberOfTextPosition * sizeof(SaIndexList)); elapsedTime = getElapsedTime(startTime) - totalElapsedTime; printf("Elapsed time = "); printElapsedTime(stdout, FALSE, FALSE, TRUE, 4, elapsedTime); totalElapsedTime += elapsedTime; printf("\n"); // Process search pattern files for (i=1; i<=NumberOfSearchPatternFile; i++) { argumentText[9] = '0' + (char)(i + 2); iniparser_copystring(programInput, argumentText, PatternFileName, PatternFileName, MAX_FILENAME_LEN); printf("Loading search pattern : %s\n", PatternFileName); numberOfPattern = ProcessSearchPattern(); printf("Finished loading search pattern.\n"); elapsedTime = getElapsedTime(startTime) - totalElapsedTime; printf("Elapsed time = "); printElapsedTime(stdout, FALSE, FALSE, TRUE, 4, elapsedTime); totalElapsedTime += elapsedTime; printf("\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Searching for pattern : %s\n", PatternFileName); } if (SABinarySearch == TRUE) { printf("Start forward search with SA index.\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Forward search with SA index.\n"); } numberOfPatternFound = 0; totalTextPositionMatched = 0; totalTextPositionRetrieved = 0; BWTInitializeSaRetrievalStatistics(&BWTSaRetrievalStatistics); for (j=0; j<numberOfPattern; j++) { //ConvertTextToWordPacked(searchPattern + searchPatternPosition[j], packedKey, charMap, ALPHABET_SIZE, // searchPatternPosition[j+1] - searchPatternPosition[j]); //found = BWTForwardSearchSaIndex(packedKey, searchPatternPosition[j+1] - searchPatternPosition[j], // bwt, hsp->packedDNA, &saIndexLeft, &saIndexRight); ConvertTextToCode(searchPattern + searchPatternPosition[j], convertedKey, charMap, searchPatternPosition[j+1] - searchPatternPosition[j]); found = BWTSaBinarySearch(convertedKey, searchPatternPosition[j+1] - searchPatternPosition[j], bwt, hsp->packedDNA, &saIndexLeft, &saIndexRight, packedKey); if (found) { numberOfPatternFound++; textPositionMatched = saIndexRight - saIndexLeft + 1; totalTextPositionMatched += textPositionMatched; if (FindTextPosition) { saIndexGroup->startSaIndex = saIndexLeft; if (textPositionMatched <= MaxNumberOfTextPosition) { saIndexGroup->numOfMatch = textPositionMatched; } else { saIndexGroup->numOfMatch = MaxNumberOfTextPosition; printf("Max no of text positions reached! Only %u out of %u text positions retrieved.\n", MaxNumberOfTextPosition, textPositionMatched); } saIndexGroup->posQuery = 0; saIndexGroup->info = 0; textPositionRetrieved = BWTTextPosition(bwt, saIndexGroup, 1, hitList, tempSaIndex1, tempSaIndex2, &BWTSaRetrievalStatistics, FALSE); totalTextPositionRetrieved += textPositionRetrieved; } } if (LogFileName[0] != '\0') { if (found) { fprintf(logFile, "Pattern number %u found. SA Index from %u to %u. ", j + 1, saIndexLeft, saIndexRight); if (FindTextPosition) { fprintf(logFile, "%u matches of %u located. ", textPositionRetrieved, textPositionMatched); for (k=0; k<textPositionRetrieved; k++) { fprintf(logFile, "%u ", hitList[k].posText); } } } else { fprintf(logFile, "Pattern number %u not found.", j + 1); } fprintf(logFile, "\n"); } } printf("Finished forward search with SA index.\n"); printf("%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { printf("Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } elapsedTime = getElapsedTime(startTime) - totalElapsedTime; printf("Elapsed time = "); printElapsedTime(stdout, FALSE, FALSE, TRUE, 4, elapsedTime); totalElapsedTime += elapsedTime; printf("\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Finished forward search with SA index.\n"); fprintf(logFile, "%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { fprintf(logFile, "Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } fprintf(logFile, "Elapsed time = "); printElapsedTime(logFile, FALSE, FALSE, TRUE, 4, elapsedTime); fprintf(logFile, "\n"); } } if (BackwardSearch == TRUE) { printf("Start backward search.\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Backward search.\n"); } numberOfPatternFound = 0; totalTextPositionMatched = 0; totalTextPositionRetrieved = 0; BWTInitializeSaRetrievalStatistics(&BWTSaRetrievalStatistics); for (j=0; j<numberOfPattern; j++) { ConvertTextToCode(searchPattern + searchPatternPosition[j], convertedKey, charMap, searchPatternPosition[j+1] - searchPatternPosition[j]); found = BWTBackwardSearch(convertedKey, searchPatternPosition[j+1] - searchPatternPosition[j], bwt, &saIndexLeft, &saIndexRight); if (found) { numberOfPatternFound++; textPositionMatched = saIndexRight - saIndexLeft + 1; totalTextPositionMatched += textPositionMatched; if (FindTextPosition) { saIndexGroup->startSaIndex = saIndexLeft; if (textPositionMatched <= MaxNumberOfTextPosition) { saIndexGroup->numOfMatch = textPositionMatched; } else { saIndexGroup->numOfMatch = MaxNumberOfTextPosition; printf("Max no of text positions reached! Only %u out of %u text positions retrieved.\n", MaxNumberOfTextPosition, textPositionMatched); } saIndexGroup->posQuery = 0; saIndexGroup->info = 0; textPositionRetrieved = BWTTextPosition(bwt, saIndexGroup, 1, hitList, tempSaIndex1, tempSaIndex2, &BWTSaRetrievalStatistics, FALSE); totalTextPositionRetrieved += textPositionRetrieved; } } if (LogFileName[0] != '\0') { if (found) { fprintf(logFile, "Pattern number %u found. SA Index from %u to %u. Total %u occurrences ", j + 1, saIndexLeft, saIndexRight, saIndexRight - saIndexLeft + 1); if (FindTextPosition) { fprintf(logFile, "%u matches of %u located. ", textPositionRetrieved, textPositionMatched); for (k=0; k<textPositionRetrieved; k++) { fprintf(logFile, "%u ", hitList[k].posText); } } } else { fprintf(logFile, "Pattern number %u not found.", j + 1); } fprintf(logFile, "\n"); } } printf("Finished backward search.\n"); printf("%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { printf("Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } elapsedTime = getElapsedTime(startTime) - totalElapsedTime; printf("Elapsed time = "); printElapsedTime(stdout, FALSE, FALSE, TRUE, 4, elapsedTime); totalElapsedTime += elapsedTime; printf("\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Finished backward search.\n"); fprintf(logFile, "%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { fprintf(logFile, "Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } fprintf(logFile, "Elapsed time = "); printElapsedTime(logFile, FALSE, FALSE, TRUE, 4, elapsedTime); fprintf(logFile, "\n"); } } if (BackwardSearchCheck == TRUE) { printf("Start backward search with text.\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Backward search with text.\n"); } numberOfPatternFound = 0; totalTextPositionMatched = 0; totalTextPositionRetrieved = 0; BWTInitializeSaRetrievalStatistics(&BWTSaRetrievalStatistics); for (j=0; j<numberOfPattern; j++) { ConvertTextToCode(searchPattern + searchPatternPosition[j], convertedKey, charMap, searchPatternPosition[j+1] - searchPatternPosition[j]); ConvertTextToWordPacked(searchPattern + searchPatternPosition[j], packedKey, charMap, ALPHABET_SIZE, searchPatternPosition[j+1] - searchPatternPosition[j]); found = BWTBackwardSearchCheckWithText(convertedKey, packedKey, searchPatternPosition[j+1] - searchPatternPosition[j], bwt, hsp->packedDNA, TextCheckCostFactor, MaxNumberOfTextPosition, hitList, &saIndexLeft, &saIndexRight); if (found) { numberOfPatternFound++; textPositionMatched = saIndexRight - saIndexLeft + 1; totalTextPositionMatched += textPositionMatched; // Find text position if text check not used if (FindTextPosition && saIndexLeft != 0) { saIndexGroup->startSaIndex = saIndexLeft; if (textPositionMatched <= MaxNumberOfTextPosition) { saIndexGroup->numOfMatch = textPositionMatched; } else { saIndexGroup->numOfMatch = MaxNumberOfTextPosition; printf("Max no of text positions reached! Only %u out of %u text positions retrieved.\n", MaxNumberOfTextPosition, textPositionMatched); } saIndexGroup->posQuery = 0; saIndexGroup->info = 0; textPositionRetrieved = BWTTextPosition(bwt, saIndexGroup, 1, hitList, tempSaIndex1, tempSaIndex2, &BWTSaRetrievalStatistics, FALSE); totalTextPositionRetrieved += textPositionRetrieved; } else { textPositionRetrieved = textPositionMatched; totalTextPositionRetrieved += textPositionRetrieved; } } if (LogFileName[0] != '\0') { if (found) { fprintf(logFile, "Pattern number %u found. ", j + 1); if (FindTextPosition) { fprintf(logFile, "%u matches of %u located. ", textPositionRetrieved, textPositionMatched); for (k=0; k<textPositionRetrieved; k++) { fprintf(logFile, "%u ", hitList[k].posText); } } } else { fprintf(logFile, "Pattern number %u not found.", j + 1); } fprintf(logFile, "\n"); } } printf("Finished backward search with text.\n"); printf("%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { printf("Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } elapsedTime = getElapsedTime(startTime) - totalElapsedTime; printf("Elapsed time = "); printElapsedTime(stdout, FALSE, FALSE, TRUE, 4, elapsedTime); totalElapsedTime += elapsedTime; printf("\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Finished backward search with text.\n"); fprintf(logFile, "%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { fprintf(logFile, "Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } fprintf(logFile, "Elapsed time = "); printElapsedTime(logFile, FALSE, FALSE, TRUE, 4, elapsedTime); fprintf(logFile, "\n"); } } if (HammingDistSearch == TRUE) { printf("Start hamming distance %u approximate match.\n", MaxErrorAllowed); if (LogFileName[0] != '\0') { fprintf(logFile, "Hamming distance %u approximate match.\n", MaxErrorAllowed); } numberOfPatternFound = 0; totalTextPositionMatched = 0; totalTextPositionRetrieved = 0; BWTInitializeSaRetrievalStatistics(&BWTSaRetrievalStatistics); for (j=0; j<numberOfPattern; j++) { ConvertTextToCode(searchPattern + searchPatternPosition[j], convertedKey, charMap, searchPatternPosition[j+1] - searchPatternPosition[j]); numberOfSaIndexGroup = BWTHammingDistMatchOld(convertedKey, searchPatternPosition[j+1] - searchPatternPosition[j], bwt, MaxErrorAllowed, saIndexGroup, MaxNumberOfHitGroups, 0, 0); if (numberOfSaIndexGroup) { numberOfPatternFound++; textPositionMatched = 0; for (k=0; k<numberOfSaIndexGroup; k++) { textPositionMatched += saIndexGroup[k].numOfMatch; } if (textPositionMatched > MaxNumberOfTextPosition) { textPositionMatched = 0; for (k=0; k<numberOfSaIndexGroup && textPositionMatched < MaxNumberOfTextPosition; k++) { textPositionMatched += saIndexGroup[k].numOfMatch; } numberOfSaIndexGroup = k - 1; saIndexGroup[numberOfSaIndexGroup].numOfMatch -= textPositionMatched - MaxNumberOfTextPosition; for (; k<numberOfSaIndexGroup; k++) { textPositionMatched += saIndexGroup[k].numOfMatch; } printf("Max no of text positions reached! Only %u out of %u text positions retrieved.\n", MaxNumberOfTextPosition, textPositionMatched); } totalTextPositionMatched += textPositionMatched; if (FindTextPosition) { textPositionRetrieved = BWTTextPosition(bwt, saIndexGroup, numberOfSaIndexGroup, hitList, tempSaIndex1, tempSaIndex2, &BWTSaRetrievalStatistics, FALSE); totalTextPositionRetrieved += textPositionRetrieved; } } if (LogFileName[0] != '\0') { if (numberOfSaIndexGroup) { fprintf(logFile, "Pattern number %u found. %u matches", j + 1, textPositionMatched); if (FindTextPosition) { fprintf(logFile, "%u matches of %u located. ", textPositionRetrieved, textPositionMatched); for (k=0; k<textPositionRetrieved; k++) { fprintf(logFile, "%u ", hitList[k].posText); } } } else { fprintf(logFile, "Pattern number %u not found.", j + 1); } fprintf(logFile, "\n"); } } printf("Finished hamming distance search.\n"); printf("%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { printf("Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } elapsedTime = getElapsedTime(startTime) - totalElapsedTime; printf("Elapsed time = "); printElapsedTime(stdout, FALSE, FALSE, TRUE, 4, elapsedTime); totalElapsedTime += elapsedTime; printf("\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Finished hamming distance search.\n"); fprintf(logFile, "%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { fprintf(logFile, "Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } fprintf(logFile, "Elapsed time = "); printElapsedTime(logFile, FALSE, FALSE, TRUE, 4, elapsedTime); fprintf(logFile, "\n"); } } if (EditDistSearch == TRUE) { printf("Start edit distance %u approximate match.\n", MaxErrorAllowed); if (LogFileName[0] != '\0') { fprintf(logFile, "Edit distance %u approximate match.\n", MaxErrorAllowed); } numberOfPatternFound = 0; totalTextPositionMatched = 0; totalTextPositionRetrieved = 0; BWTInitializeSaRetrievalStatistics(&BWTSaRetrievalStatistics); for (j=0; j<numberOfPattern; j++) { ConvertTextToCode(searchPattern + searchPatternPosition[j], convertedKey, charMap, searchPatternPosition[j+1] - searchPatternPosition[j]); numberOfSaIndexGroup = BWTEditDistMatchOld(convertedKey, searchPatternPosition[j+1] - searchPatternPosition[j], bwt, MaxErrorAllowed, (SaIndexGroupWithLengthError*)saIndexGroup, MaxNumberOfHitGroups); if (numberOfSaIndexGroup > MaxNumberOfHitGroups) { fprintf(stderr, "numberOfSaIndexGroup > MaxNumberOfHitGroups!\n"); } if (numberOfSaIndexGroup) { numberOfPatternFound++; textPositionMatched = 0; for (k=0; k<numberOfSaIndexGroup; k++) { textPositionMatched += saIndexGroup[k].numOfMatch; } if (textPositionMatched > MaxNumberOfTextPosition) { textPositionMatched = 0; for (k=0; k<numberOfSaIndexGroup && textPositionMatched < MaxNumberOfTextPosition; k++) { textPositionMatched += saIndexGroup[k].numOfMatch; } numberOfSaIndexGroup = k - 1; saIndexGroup[numberOfSaIndexGroup].numOfMatch -= textPositionMatched - MaxNumberOfTextPosition; for (; k<numberOfSaIndexGroup; k++) { textPositionMatched += saIndexGroup[k].numOfMatch; } printf("Max no of text positions reached! Only %u out of %u text positions retrieved.\n", MaxNumberOfTextPosition, textPositionMatched); } totalTextPositionMatched += textPositionMatched; if (FindTextPosition) { textPositionRetrieved = BWTTextPosition(bwt, saIndexGroup, numberOfSaIndexGroup, hitList, tempSaIndex1, tempSaIndex2, &BWTSaRetrievalStatistics, FALSE); totalTextPositionRetrieved += textPositionRetrieved; } } if (LogFileName[0] != '\0') { if (numberOfSaIndexGroup) { fprintf(logFile, "Pattern number %u found. %u matches. ", j + 1, textPositionMatched); if (FindTextPosition) { fprintf(logFile, "%u matches of %u located. ", textPositionRetrieved, textPositionMatched); for (k=0; k<textPositionRetrieved; k++) { fprintf(logFile, "%u ", hitList[k].posText); } } } else { fprintf(logFile, "Pattern number %u not found.", j + 1); } fprintf(logFile, "\n"); } } printf("Finished edit distance search.\n"); printf("%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { printf("Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } elapsedTime = getElapsedTime(startTime) - totalElapsedTime; printf("Elapsed time = "); printElapsedTime(stdout, FALSE, FALSE, TRUE, 4, elapsedTime); totalElapsedTime += elapsedTime; printf("\n"); if (LogFileName[0] != '\0') { fprintf(logFile, "Finished edit distance search.\n"); fprintf(logFile, "%u patterns out of %u found. %llu of %llu matches located.\n", numberOfPatternFound, numberOfPattern, totalTextPositionRetrieved, totalTextPositionMatched); if (FindTextPosition) { fprintf(logFile, "Hits: BWT/Cached/Diag/Dup : %u/%u/%u/%u\n", BWTSaRetrievalStatistics.bwtSaRetrieved, BWTSaRetrievalStatistics.cachedSaRetrieved, BWTSaRetrievalStatistics.saDiagonalLinked, BWTSaRetrievalStatistics.saDuplicated); } fprintf(logFile, "Elapsed time = "); printElapsedTime(logFile, FALSE, FALSE, TRUE, 4, elapsedTime); fprintf(logFile, "\n"); } } } MMPoolReturn(mmPool, packedKey, WordPackedLengthFromText(MAX_SEARCH_PATTERN_LENGTH, BIT_PER_CHAR)); MMPoolReturn(mmPool, convertedKey, MAX_SEARCH_PATTERN_LENGTH); HSPFree(mmPool, hsp, MAX_SEARCH_PATTERN_LENGTH / CHAR_PER_WORD); BWTFree(mmPool, bwt); if (searchPattern != NULL) { MMUnitFree(searchPattern, searchPatternAllocated); } if (searchPatternPosition != NULL) { MMUnitFree(searchPatternPosition, searchPatternPositionAllocated); } MMUnitFree(saIndexGroup, MaxNumberOfHitGroups * sizeof(unsigned int)); MMUnitFree(hitList, MaxNumberOfTextPosition * sizeof(unsigned int)); MMPoolFree(mmPool); iniparser_freedict(programInput); iniparser_freedict(ini); return 0; }
CROSSCUT_NLS_DATA int main (int argc, char *argv[]) { int memkind, handle; char loop1, loop2; struct dfree free; char buf[BUFFERSIZE]; char cmpbuf[BUFFERSIZE]; unsigned long sector, total, disksize, allocated, beginsector, endsector; unsigned long FilledDiskSize, FilledTotal, FileSize = 0; int Arg1IsFile, Arg2IsFile; int UseImageFile, ImageModus, Overwrite; int i, enable; int audible, verify, fallthrough, askdisk, asktdisk; char sdrive, tdrive; int HardDiskOk; int informative, copyfast; char switchchar; int tocopysectors; unsigned tobuffer; #ifndef ALL_RECOVERY_MODE int recoverymode; #endif int bytespersector; int CopyingToSameDisk = FALSE; int action, success; struct LFNAttribute attr; struct IniParserStruct *ParsedData; struct TwoDriveCopyData tdrvdata; attr.output = TRUE; memkind = UNALLOCATED; UseImageFile = FALSE; SetExePath (argv[0]); /* Remember executable's path. */ CriticalHandlerOn (); /* Install critical handler. */ InitLFNAPI (); /* Initialise LFN API. */ CROSSCUT_NLS_OPEN switchchar = SwitchChar (); /* Check arguments */ if ((argc == 2) && ((argv[1][0] == '/') || (argv[1][0] == switchchar)) && (argv[1][1] == '?') && (argv[1][2] == '\0')) { ShowHelp (switchchar); return COPYSUCCESS; } if (argc > 2) { Arg1IsFile = IsFile (argv[1]); Arg2IsFile = IsFile (argv[2]); } #ifdef DEF_HELP if (argc < 3) { /* The way we do it. */ ShowHelp (switchchar); return INITERROR; } else if ((!HasFloppyForm (argv[1]) && !Arg1IsFile) || (!HasFloppyForm (argv[2]) && !Arg2IsFile)) #else if ((argc < 3) || (!HasFloppyForm (argv[1]) && !Arg1IsFile) || (!HasFloppyForm (argv[2]) && !Arg2IsFile)) #endif { /* The way (DR and MS) DOS does it. */ NLS_PUTSTRING (1, 0, "Invalid drive specification or non removable media."); return INITERROR; } if (ParseIniFile (NULL) < 0) /* Parse .ini file. */ { NLS_PUTSTRING (1, 1, "Error reading configuration file."); return INITERROR; } ParsedData = GetParsedData (); audible = ParsedData->audible; verify = ParsedData->verify; HardDiskOk = ParsedData->UseSWAP; informative = ParsedData->informative; Overwrite = ParsedData->overwrite; fallthrough = ParsedData->autoexit; askdisk = ParsedData->askdisk; asktdisk = ParsedData->asktdisk; copyfast = (ParsedData->speed == FAST); #ifndef ALL_RECOVERY_MODE recoverymode = ParsedData->mode; #endif /* Check arguments. */ for (i = 3; i < argc; i++) { if (strlen (argv[i]) > 3) { NLS_PRINTSTRING (1, 2, "Invalid switch:"); printf (" %s\n", argv[i]); return INITERROR; } enable = TRUE; if (strlen (argv[i]) == 3) { if (argv[i][2] == '-') { enable = FALSE; } else { NLS_PRINTSTRING (1, 2, "Invalid switch"); printf (" %s\n", argv[i]); return INITERROR; } } if ((argv[i][0] == switchchar) || (argv[i][0] == '/')) switch (argv[i][1]) { case 'a': /* DOS is case insensitive. */ case 'A': audible = enable; break; case 'v': case 'V': verify = enable; break; case 'm': case 'M': HardDiskOk = !enable; break; case 'i': case 'I': informative = enable; break; case 'o': case 'O': Overwrite = enable; break; case 'x': case 'X': fallthrough = enable; break; case 'd': case 'D': askdisk = !enable; break; case 'f': case 'F': copyfast = enable; break; #ifndef ALL_RECOVERY_MODE case 'r': case 'R': recoverymode = enable; break; #else case 'r': case 'R': #endif case 't': case 'T': asktdisk = !enable; break; case '1': NLS_PRINTSTRING (2, 0, "Warning: option"); printf (" %s ", argv[i]); NLS_PUTSTRING (2, 1, "doesn't do anything!"); break; default: NLS_PRINTSTRING (1, 2, "Invalid switch"); printf (" %s\n", argv[i]); return INITERROR; } else { NLS_PRINTSTRING (1, 3, "Too many parameters:"); printf (" %s\n", argv[i]); return INITERROR; } } if (Arg1IsFile && Arg2IsFile) { ConvertToSFN (argv[1], INFILE_ID); ConvertToSFN (argv[2], OUTFILE_ID); SetLFNAttribute (&attr, OUTFILE_ID); if ((access (GetSFN (OUTFILE_ID), EXISTS) == 0) && Overwrite && (remove (GetSFN (OUTFILE_ID)) == -1)) { NLS_PUTSTRING (1, 4, "File is write protected!"); return INITERROR; } if (CopyFile (GetSFN (INFILE_ID), GetSFN (OUTFILE_ID))) { printf ("%s ", argv[1]); NLS_PRINTSTRING (1, 5, "copied to"); printf (" %s", argv[2]); if (audible) Beep (); SynchronizeLFNs (); return COPYSUCCESS; } else { NLS_PRINTSTRING (3, 0, "Problem copying"); printf (" %s ", argv[1]); NLS_PRINTSTRING (3, 1, "to"); printf (" %s.\n", argv[2]); return CRITICAL; } } else if (Arg1IsFile) { ConvertToSFN (argv[1], INFILE_ID); if (access (GetSFN (INFILE_ID), READPERMISSION) != 0) { NLS_PRINTSTRING (1, 6, "File not found:"); printf (" %s\n", argv[1]); return INITERROR; } CopyingToSameDisk = IsCopyToSameDisk (argv[1], argv[2]); UseImageFile = TRUE; ImageModus = READIMAGE; } else if (Arg2IsFile) { CopyingToSameDisk = IsCopyToSameDisk (argv[2], argv[1]); ConvertToSFN (argv[2], OUTFILE_ID); SetLFNAttribute (&attr, OUTFILE_ID); if (!CopyingToSameDisk) { if (access (GetSFN (OUTFILE_ID), EXISTS) == 0) { if (Overwrite) { if (remove (GetSFN (OUTFILE_ID)) != 0) { NLS_PRINTSTRING (1, 4, "File is write protected!"); return INITERROR; } } else { NLS_PRINTSTRING (1, 7, "File already exists!"); return INITERROR; } } } if (CopyingToSameDisk) copyfast = TRUE; UseImageFile = TRUE; ImageModus = WRITEIMAGE; } sdrive = (char) toupper (argv[1][0]) - 65; tdrive = (char) toupper (argv[2][0]) - 65; loop1 = CatYES; /* initialize loop1 */ loop2 = CatYES; /* initialize loop2 */ ctrlbrk (OnCBreak); SavedCBreak = getcbrk (); setcbrk (1); /* set control-break to ON */ atexit (OnExit); /* make sure that all allocated memory is released when program stops. */ if ((sdrive != tdrive) && (!UseImageFile) && BiosReportsTwoDrives ()) { tdrvdata.sourcedrv = sdrive; tdrvdata.destdrv = tdrive; tdrvdata.cpybuf = buf; tdrvdata.cmpbuf = cmpbuf; tdrvdata.bufsize = BUFFERSIZE; tdrvdata.bel = audible; tdrvdata.fallthrough = fallthrough; tdrvdata.askdisk = askdisk; tdrvdata.copyfast = copyfast; tdrvdata.verify = verify; #ifndef ALL_RECOVERY_MODE tdrvdata.recoverymode = recoverymode; #endif #ifdef UPDATE_SERIALNUM tdrvdata.updateserial = ParsedData->serialnumber; #endif TwoDriveCopy (&tdrvdata); return COPYSUCCESS; } endsector = 0; while (!NLS_TEST_NO (loop1)) /* loop1 */ { if (!UseImageFile || (ImageModus == WRITEIMAGE)) { if (askdisk) { puts (""); NLS_PRINTSTRING (1, 8, "Insert SOURCE diskette into drive"); printf (" %s\n\n", argv[1]); NLS_PRINTSTRING (1, 9, "Press any key to continue . . ."); WaitForInput (); puts (""); } else askdisk = TRUE; /* Always ask after the first run. */ } if (endsector == 0) { if (!UseImageFile || (ImageModus == WRITEIMAGE)) { if (!DiskReadBootInfo (sdrive, &free) || (DetermineFATType() != FAT12)) { puts (""); NLS_PUTSTRING (1, 10, "Disk not ready!"); return CRITICAL; } } else { /* Remember file size */ handle = open (GetSFN (INFILE_ID), O_RDONLY | O_BINARY); if (handle < 0) { puts (""); NLS_PUTSTRING (1, 11, "Unable to open image file."); return INITERROR; } FileSize = filelength (handle); close (handle); if (!FileReadBootInfo (GetSFN (INFILE_ID), &free)) { puts (""); NLS_PUTSTRING (1, 11, "Unable to open image file."); return INITERROR; } } total = free.df_total * free.df_sclus; bytespersector = free.df_bsec; disksize = total * bytespersector; if (disksize == 0) { puts (""); NLS_PUTSTRING (1, 0, "Invalid drive specification or non removable media."); return INITERROR; } /* Initialize fast copy: - After checking if disk in drive is ok, BUT - before initializing memory */ /* In case of writing an image file to disk. We'd like the program to succeed regardless of wether we used the /f switch or corresponding .ini file entry */ if (((copyfast) || ((UseImageFile && (ImageModus == READIMAGE)) && disksize != FileSize)) && (disksize != FileSize)) { SetCopySpeed (FAST); if (!UseImageFile || (ImageModus == WRITEIMAGE)) { if (!DiskReadFatInfo (sdrive)) SetCopySpeed (FULL); } else if (!FileReadFatInfo (GetSFN (INFILE_ID))) { NLS_PUTSTRING (1, 32, "Can not copy image file"); return INITERROR; } } else SetCopySpeed (FULL); } puts (""); /* Get the size of the meaningfull data on the disk */ FilledDiskSize = GetDiskFilledSize (BUFFERSIZE); FilledTotal = (FilledDiskSize / free.df_bsec) / free.df_sclus; if ((UseImageFile) && (!CopyingToSameDisk)) switch (SetImageFile (GetSFN (ImageModus - 1), ImageModus, FilledDiskSize)) { case EZERO: allocated = disksize; break; case DISKTOSMALL: puts (""); NLS_PUTSTRING (1, 12, "Not enough disk space on target drive!"); return INITERROR; default: NLS_PRINTSTRING (1, 13, "Error accessing image file:"); printf (" %s\n", argv[ImageModus]); return INITERROR; } else { if (CopyingToSameDisk) switch (ImageModus) { case READIMAGE: memkind = InitializeFittingMemory (FilledDiskSize, HardDiskOk, &allocated, '\0', argv[2][0]); break; case WRITEIMAGE: memkind = InitializeFittingMemory (FilledDiskSize, HardDiskOk, &allocated, argv[1][0], '\0'); break; } else memkind = InitializeFittingMemory (FilledDiskSize, HardDiskOk, &allocated, argv[1][0], argv[2][0]); if (memkind == 0) { NLS_PUTSTRING (1, 14, "Insufficient memory for disk copy.\n"); return INITERROR; } } if (CopyingToSameDisk) { if (allocated != FilledDiskSize) { NLS_PUTSTRING (1, 14, "Insufficient memory for disk copy.\n"); return INITERROR; } if (ImageModus == READIMAGE) { PrepareForWriting (); if (!ReadFileIntoMemory (GetSFN (INFILE_ID), buf, BUFFERSIZE)) { NLS_PUTSTRING (1, 33, "Problem reading image file."); return CRITICAL; } } else /* ImageModus == WRITEIMAGE */ if (!asktdisk) { if (!DiskLargeEnough (GetSFN (OUTFILE_ID), FilledDiskSize)) { puts (""); NLS_PUTSTRING (1, 12, "Not enough disk space on target drive!"); return INITERROR; } } } if (!UseImageFile || (ImageModus == WRITEIMAGE)) { beginsector = endsector; endsector += allocated / BYTESPERSECTOR; if ((endsector > total) || (allocated == FilledDiskSize)) endsector = total; } if (!UseImageFile || (ImageModus == WRITEIMAGE)) { NLS_PRINTSTRING (4, 0, "Copying"); printf (" %d ", (int) FilledTotal); NLS_PRINTSTRING (4, 1, "clusters"); printf (", %d ", free.df_sclus); NLS_PRINTSTRING (4, 2, "sectors per cluster"); printf (", %d ", free.df_bsec); NLS_PRINTSTRING (4, 3, "bytes per sector"); puts ("."); NLS_PRINTSTRING (4, 4, "Relevant drive size is"); printf (" %lu ", FilledDiskSize); NLS_PRINTSTRING (4, 5, "bytes"); printf ("."); } if (informative && (!UseImageFile)) { printf (" "); NLS_PRINTSTRING (1, 15, "Using"); printf (" "); switch (memkind) { case EMS: puts ("EMS.\n"); break; case XMS: puts ("XMS.\n"); break; case HARDDISK: NLS_PUTSTRING (1, 16, "temporary file"); puts (""); break; case BUFFERS: NLS_PRINTSTRING (5, 0, "buffer of"); printf (" %ld ", allocated); NLS_PUTSTRING (5, 1, "bytes."); puts (""); break; } } else if (!UseImageFile || (ImageModus == WRITEIMAGE)) puts ("\n"); if (!UseImageFile || (ImageModus == WRITEIMAGE)) { for (action = DISKREADING; (verify) ? (action <= VERIFICATION) : (action < VERIFICATION); action++) { if (action == DISKREADING) { if (!UseImageFile) { NLS_PRINTSTRING (1, 17, "Reading SOURCE diskette . . ."); } else NLS_PRINTSTRING (1, 34, "Creating image file . . ."); PrepareForWriting (); } else { puts (""); NLS_PRINTSTRING (1, 38, "Verifying . . ."); PrepareForReading (); } for (sector = beginsector; sector < endsector; sector = sector + TOCOPYSECTORS) { if (sector < endsector - TOCOPYSECTORS) tocopysectors = TOCOPYSECTORS; else tocopysectors = (int) (endsector - sector); tobuffer = (unsigned) (tocopysectors * BYTESPERSECTOR); if (IsDiskReadRequired (sector, tocopysectors)) /* Fast copy */ { #ifndef ALL_RECOVERY_MODE if (recoverymode) #endif ReadSectors (sdrive, tocopysectors, (int) sector, buf, bytespersector); #ifndef ALL_RECOVERY_MODE else if (absread (sdrive, tocopysectors, (int) sector, buf) != 0) { puts (""); NLS_PRINTSTRING (1, 18, "Media error reading from sector"); printf (" %ld.\n", sector); } #endif if (action == DISKREADING) success = WriteMemoryBlock (buf, tobuffer); else success = ReadMemoryBlock (cmpbuf, tobuffer); if (!success) { puts (""); NLS_PUTSTRING (1, 20, "Unsuspected memory error."); SetErrorStopped (); return CRITICAL; } if (action == VERIFICATION) { if (memcmp (buf, cmpbuf, 5 /*tobuffer */ ) != 0) { puts (""); NLS_PRINTSTRING (1, 37, "Compare error on sector"); printf (" %ld.\n", sector); } } } } } } if (audible && (!UseImageFile)) Beep (); if (!UseImageFile || (ImageModus == READIMAGE)) { while (!NLS_TEST_NO (loop2)) /* loop2 */ { if (askdisk) { if (!UseImageFile) puts ("\n"); NLS_PRINTSTRING (1, 21, "Insert TARGET diskette into drive"); printf (" %s\n\n", argv[2]); NLS_PRINTSTRING (1, 9, "Press any key to continue . . ."); WaitForInput (); } else askdisk = TRUE; /* Check disk capacity is the same as that of the original diskette. */ for (;;) { if (!DiskReadBootInfo (tdrive, &free)) { puts (""); NLS_PUTSTRING (1, 10, "Disk not ready!"); total = 0; } else total = free.df_total * free.df_sclus; if (((UseImageFile) && (FileSize != FilledDiskSize)) || (disksize != total * free.df_bsec)) { puts (""); NLS_PUTSTRING (1, 22, "Diskette does not have the same capacity as the original."); if (fallthrough) return NONFATAL; puts (""); NLS_PRINTSTRING (1, 23, "Put a diskette with the right capacity in drive"); printf (" %s, \n", argv[2]); NLS_PUTSTRING (1, 24, "or press CTRL-C to cancel."); WaitForInput (); /* When the user presses CTRL-C this function does not return */ } else break; } if (UseImageFile) { puts ("\n"); NLS_PRINTSTRING (4, 0, "Copying"); printf (" %d ", (int) FilledTotal); NLS_PRINTSTRING (4, 1, "clusters"); printf (", %d ", free.df_sclus); NLS_PRINTSTRING (4, 2, "sectors per cluster"); printf (", %d ", free.df_bsec); NLS_PRINTSTRING (4, 3, "bytes per sector"); puts ("."); NLS_PRINTSTRING (4, 4, "Relevant drive size is"); printf (" %lu ", FilledDiskSize); NLS_PRINTSTRING (4, 5, "bytes"); puts ("."); beginsector = endsector; endsector += allocated / BYTESPERSECTOR; if (endsector > total) endsector = total; } for (action = DISKWRITING; (verify) ? (action <= VERIFICATION) : (action < VERIFICATION); action++) { if (action == DISKWRITING) { if (UseImageFile) { puts (""); NLS_PRINTSTRING (1, 35, "Writing image file . . ."); } else { puts ("\n"); NLS_PRINTSTRING (1, 25, "Writing to TARGET diskette in drive . . ."); } PrepareForReading (); } else /* VERIFICATION */ { puts (""); NLS_PRINTSTRING (1, 38, "Verifying . . ."); PrepareForReading (); /* Rewind */ } for (sector = beginsector; sector < endsector; sector = sector + TOCOPYSECTORS) { if (sector < endsector - TOCOPYSECTORS) tocopysectors = TOCOPYSECTORS; else tocopysectors = (int) (endsector - sector); tobuffer = (unsigned) (tocopysectors * BYTESPERSECTOR); if (IsDiskReadRequired (sector, tocopysectors)) { if (!ReadMemoryBlock (buf, tobuffer)) { puts (""); NLS_PUTSTRING (1, 20, "Unsuspected memory error."); SetErrorStopped (); return CRITICAL; } if (action == DISKWRITING) { #ifdef UPDATE_SERIALNUM if (sector == 0) { if (ParsedData->serialnumber == UPDATE) UpdateDiskSerialNumber (buf); } #endif if (abswrite (tdrive, tocopysectors, (int) sector, buf) != 0) { if (sector == 0) { if (abswrite(tdrive, 1, 0, buf) != 0) { puts("\n"); NLS_PRINTSTRING(1, 41, "Sector 0 unwritable! Write protected?"); if (FilledDiskSize == allocated) break; else return CRITICAL; } } puts (""); NLS_PRINTSTRING (1, 27, "Media error writing to sector"); printf (" %ld.\n", sector); } } else { if (absread (tdrive, tocopysectors, (int) sector, cmpbuf) != 0) { puts (""); NLS_PRINTSTRING (1, 18, "Media error reading from sector"); printf (" %ld.\n", sector); } if (sector == 0) { if (ParsedData->serialnumber == UPDATE) { ClearDiskSerialNumber (buf); ClearDiskSerialNumber (cmpbuf); } } if (memcmp (buf, cmpbuf, tobuffer) != 0) { puts (""); NLS_PRINTSTRING (1, 37, "Compare error on sector"); printf (" %ld.\n", sector); } } } } } if (!UseImageFile) puts (""); if (UseImageFile || (FilledDiskSize == allocated)) /* If everything fitted in memory */ { loop2 = (fallthrough) ? CatNO : CatNO + 1; if (loop2 == CatYES) loop2++; while (!NLS_TEST_YES_NO (loop2)) { ClrKbd (); if (audible) Beep (); puts (""); if (UseImageFile) puts (""); NLS_PRINTSTRING (1, 28, "Do you want another copy of this "); if (UseImageFile) { endsector = 0; NLS_PRINTSTRING (1, 29, "image file (Y/N)?"); } else NLS_PRINTSTRING (1, 30, "disk (Y/N)?"); loop2 = toupper (getch ()); puts (""); } if (UseImageFile && (NLS_TEST_YES (loop2))) puts (""); } else { puts (""); loop2 = CatNO; } /* Change the serial number of the target disk. */ #ifdef UPDATE_SERIALNUM if (ParsedData->serialnumber == UPDATE) { puts (""); PrintDiskSerialNumber (); puts (""); } #endif } /* loop2 */ loop2 = CatYES; if (loop2 == CatNO) loop2++; ReleaseMemory (); } else { if (CopyingToSameDisk) { PrepareForReading (); if (!WriteFileFromMemory (GetSFN (OUTFILE_ID), buf, BUFFERSIZE, FilledDiskSize, asktdisk, fallthrough, Overwrite)) { NLS_PUTSTRING (1, 36, "Problem writing image file."); return CRITICAL; } } } loop1 = CatYES + 1; if (loop1 == CatNO) loop1++; if (!UseImageFile && !fallthrough && (endsector == total)) { while (!NLS_TEST_YES_NO (loop1)) { ClrKbd (); puts (""); NLS_PRINTSTRING (1, 31, "Copy another disk (Y/N)?"); loop1 = toupper (getch ()); puts (""); endsector = 0; } } else if (UseImageFile || (fallthrough && (endsector == total))) { loop1 = CatNO; if (fallthrough) puts (""); else if (audible && (ImageModus == WRITEIMAGE)) Beep (); } } /* end loop1 */ if ((UseImageFile) && (ImageModus == WRITEIMAGE)) puts (""); return COPYSUCCESS; }