void errorReporterRemapPath(ErrorReporter self, CharString path) { File pathAsFile = newFileWithPath(path); CharString basename = fileGetBasename(pathAsFile); File parent = newFileWithPath(self->reportDirPath); File remappedPath = newFileWithParent(parent, basename); charStringCopy(path, remappedPath->absolutePath); freeCharString(basename); freeFile(parent); freeFile(pathAsFile); freeFile(remappedPath); }
static int _testLoadPluginWithAbsolutePath(const char *testName, const CharString applicationPath, const CharString resourcesPath) { File resourcesFile = newFileWithPath(resourcesPath); CharString vstDirName = newCharStringWithCString("vst"); File vstFile = newFileWithParent(resourcesFile, vstDirName); freeFile(resourcesFile); freeCharString(vstDirName); PlatformInfo platformInfo = newPlatformInfo(); CharString platformDirName = newCharStringWithCString(_getPlatformVstDirName(platformInfo)); File vstPlatformFile = newFileWithParent(vstFile, platformDirName); freeCharString(platformDirName); freePlatformInfo(platformInfo); freeFile(vstFile); CharString vstPluginName = newCharStringWithCString("again"); charStringAppendCString(vstPluginName, _getVst2xPlatformExtension()); File pluginFile = newFileWithParent(vstPlatformFile, vstPluginName); freeCharString(vstPluginName); freeFile(vstPlatformFile); CharString inputPath = getDefaultInputPath(resourcesPath); int result = runIntegrationTest( testName, buildTestArgumentString("--plugin \"%s\" --input \"%s\"", pluginFile->absolutePath->data, inputPath->data), RETURN_CODE_SUCCESS, kTestOutputPcm, applicationPath, resourcesPath); freeCharString(inputPath); freeFile(pluginFile); return result; }
static SampleSourceType _sampleSourceGuess(const CharString sampleSourceName) { File sourceFile = NULL; CharString sourceFileExtension = NULL; SampleSourceType result = SAMPLE_SOURCE_TYPE_PCM; if (sampleSourceName == NULL || charStringIsEmpty(sampleSourceName)) { result = SAMPLE_SOURCE_TYPE_SILENCE; } else { // Look for stdin/stdout if (strlen(sampleSourceName->data) == 1 && sampleSourceName->data[0] == '-') { result = SAMPLE_SOURCE_TYPE_PCM; } else { sourceFile = newFileWithPath(sampleSourceName); sourceFileExtension = fileGetExtension(sourceFile); freeFile(sourceFile); // If there is no file extension, then automatically assume raw PCM data. Deal with it! if (charStringIsEmpty(sourceFileExtension)) { result = SAMPLE_SOURCE_TYPE_PCM; } // Possible file extensions for raw PCM data else if (charStringIsEqualToCString(sourceFileExtension, "pcm", true) || charStringIsEqualToCString(sourceFileExtension, "raw", true) || charStringIsEqualToCString(sourceFileExtension, "dat", true)) { result = SAMPLE_SOURCE_TYPE_PCM; } #if USE_AUDIOFILE else if (charStringIsEqualToCString(sourceFileExtension, "aif", true) || charStringIsEqualToCString(sourceFileExtension, "aiff", true)) { result = SAMPLE_SOURCE_TYPE_AIFF; } #endif #if USE_FLAC else if (charStringIsEqualToCString(sourceFileExtension, "flac", true)) { result = SAMPLE_SOURCE_TYPE_FLAC; } #endif else if (charStringIsEqualToCString(sourceFileExtension, "wav", true) || charStringIsEqualToCString(sourceFileExtension, "wave", true)) { result = SAMPLE_SOURCE_TYPE_WAVE; } else { logCritical("Sample source '%s' does not match any supported type", sampleSourceName->data); result = SAMPLE_SOURCE_TYPE_INVALID; } } } freeCharString(sourceFileExtension); return result; }
boolByte errorReportCopyFileToReport(ErrorReporter self, CharString path) { boolByte success; // Copy the destination path so that the original is not modified CharString destination = newCharString(); charStringCopy(destination, path); errorReporterRemapPath(self, destination); File reportDirPath = newFileWithPath(self->reportDirPath); File distinationPath = newFileWithPath(path); File result = fileCopyTo(distinationPath, reportDirPath); success = fileExists(result); freeCharString(destination); freeFile(reportDirPath); freeFile(distinationPath); freeFile(result); return success; }
static void _removeOutputFile(const char *argument) { CharString outputFilename = newCharStringWithCString(argument); File outputFile = newFileWithPath(outputFilename); if (fileExists(outputFile)) { fileRemove(outputFile); } freeCharString(outputFilename); freeFile(outputFile); }
boolByte programOptionsParseConfigFile(ProgramOptions self, const CharString filename) { boolByte result = false; File configFile = NULL; LinkedList configFileLines = NULL; CharString* argvCharStrings; int argc; char** argv; int i; if(filename == NULL || charStringIsEmpty(filename)) { logCritical("Cannot read options from empty filename"); return false; } configFile = newFileWithPath(filename); if(configFile == NULL || configFile->fileType != kFileTypeFile) { logCritical("Cannot read options from non-existent file '%s'", filename->data); freeFile(configFile); return false; } configFileLines = fileReadLines(configFile); if(configFileLines == NULL) { logInternalError("Could not split config file lines"); return false; } else if(linkedListLength(configFileLines) == 0) { logInfo("Config file '%s' is empty", filename->data); freeLinkedList(configFileLines); freeFile(configFile); return true; } else { // Don't need the file anymore, it can be freed here freeFile(configFile); } argvCharStrings = (CharString*)linkedListToArray(configFileLines); argc = linkedListLength(configFileLines); argv = (char**)malloc(sizeof(char*) * (argc + 1)); // Normally this would be the application name, don't care about it here argv[0] = NULL; for(i = 0; i < argc; i++) { argv[i + 1] = argvCharStrings[i]->data; } argc++; result = programOptionsParseArgs(self, argc, argv); freeLinkedListAndItems(configFileLines, (LinkedListFreeItemFunc)freeCharString); free(argvCharStrings); free(argv); return result; }
int runIntegrationTest(const char *testName, CharString testArguments, ReturnCode expectedResultCode, const TestOutputType testOutputType, const CharString mrsWatsonExePath, const CharString resourcesPath) { int result = 0; int returnCode; ReturnCode resultCode; ChannelCount failedAnalysisChannel; SampleCount failedAnalysisFrame; #if WINDOWS STARTUPINFOA startupInfo; PROCESS_INFORMATION processInfo; #endif // Remove files from a previous test run File outputFolder = newFileWithPathCString(kApplicationRunnerOutputFolder); if (fileExists(outputFolder)) { _removeOutputFiles(testName); } else { fileCreate(outputFolder, kFileTypeDirectory); } freeFile(outputFolder); if (mrsWatsonExePath == NULL) { return -1; } else { File mrsWatsonExe = newFileWithPath(mrsWatsonExePath); boolByte mrsWatsonExeExists = fileExists(mrsWatsonExe); freeFile(mrsWatsonExe); if (!mrsWatsonExeExists) { freeCharString(testArguments); return -1; } } if (resourcesPath == NULL) { freeCharString(testArguments); return -1; } else { File resourcesFile = newFileWithPath(resourcesPath); boolByte resourcesExists = fileExists(resourcesFile); freeFile(resourcesFile); if (!resourcesExists) { freeCharString(testArguments); return -1; } } // Create the command line argument CharString arguments = newCharStringWithCapacity(kCharStringLengthLong); charStringAppendCString(arguments, "\""); charStringAppend(arguments, mrsWatsonExePath); charStringAppendCString(arguments, "\""); charStringAppendCString(arguments, " "); CharString defaultArguments; CharString outputFilename = getTestOutputFilename(testName, testOutputType); defaultArguments = _getDefaultArguments(testName, resourcesPath, outputFilename); charStringAppend(arguments, defaultArguments); freeCharString(defaultArguments); charStringAppendCString(arguments, " "); charStringAppend(arguments, testArguments); // Although testArguments is passed into this function (and hence, it would // generally not take ownership of it), in this case we free the arguments // here to make writing the test cases simpler and reduce the amount of // boilerplate code. freeCharString(testArguments); #if WINDOWS memset(&startupInfo, 0, sizeof(startupInfo)); memset(&processInfo, 0, sizeof(processInfo)); startupInfo.cb = sizeof(startupInfo); returnCode = CreateProcessA( (LPCSTR)(mrsWatsonExePath->data), (LPSTR)(arguments->data), 0, 0, false, CREATE_DEFAULT_ERROR_MODE, 0, 0, &startupInfo, &processInfo); if (returnCode) { // TODO: Check return codes for these calls WaitForSingleObject(processInfo.hProcess, kApplicationRunnerWaitTimeoutInMs); GetExitCodeProcess(processInfo.hProcess, (LPDWORD)&resultCode); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); } else { logCritical("Could not launch process, got error %s", stringForLastError(GetLastError())); return 1; } #else returnCode = system(arguments->data); resultCode = (ReturnCode)WEXITSTATUS(returnCode); #endif freeCharString(arguments); if (resultCode == RETURN_CODE_FORK_FAILED || resultCode == RETURN_CODE_SHELL_FAILED || resultCode == RETURN_CODE_LAUNCH_FAILED_OTHER) { logCritical("Could not launch shell, got return code %d\n\ Please check the executable path specified in the --mrswatson-path argument.", resultCode); return 1; } else if (resultCode == expectedResultCode) { CharString failedAnalysisFunctionName = newCharString(); if (testOutputType != kTestOutputNone) { if (analyzeFile(outputFilename->data, failedAnalysisFunctionName, &failedAnalysisChannel, &failedAnalysisFrame)) { // TODO: // if (!testEnvironment->results->keepFiles) { // _removeOutputFiles(testName); // } result = 0; } else { fprintf(stderr, "Audio analysis check for %s failed at frame %lu, channel %d. ", failedAnalysisFunctionName->data, failedAnalysisFrame, failedAnalysisChannel); result = 1; } } else { result = 0; // TODO: // if (!testEnvironment->results->keepFiles) { // _removeOutputFiles(testName); // } } freeCharString(failedAnalysisFunctionName); } else { fprintf(stderr, "Expected result code %d (%s), got %d (%s). ", expectedResultCode, _getResultCodeString(expectedResultCode), resultCode, _getResultCodeString(resultCode)); result = 1; } freeCharString(outputFilename); return result; }
void errorReporterInitialize(ErrorReporter self) { CharString infoText = newCharStringWithCString(kErrorReportInfoText); CharString wrappedInfoText; time_t now; size_t length; size_t i; printf("=== Starting error report ===\n"); wrappedInfoText = charStringWrap(infoText, 0); // The second newline here is intentional printf("%s\n", wrappedInfoText->data); time(&now); self->started = true; snprintf(self->reportName->data, self->reportName->capacity, "MrsWatson Report %s", ctime(&now)); // Trim the final newline character from this string if it exists length = strlen(self->reportName->data); if (self->reportName->data[length - 1] == '\n') { self->reportName->data[length - 1] = '\0'; length--; } for (i = 0; i < length; i++) { if (!(charStringIsLetter(self->reportName, i) || charStringIsNumber(self->reportName, i))) { self->reportName->data[i] = '-'; } } #if UNIX snprintf(self->desktopPath->data, self->desktopPath->capacity, "%s/Desktop", getenv("HOME")); #elif WINDOWS SHGetFolderPathA(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, self->desktopPath->data); #endif // Try to place the report on the user's desktop. However, if we cannot find // the desktop (which may occur with localized Linux installations, for instance), // then just dump it in the current directory instead. File desktopPath = newFileWithPath(self->desktopPath); File reportPath; if (!fileExists(desktopPath)) { logWarn("Could not find desktop location, placing error report in current directory instead"); CharString currentDirString = fileGetCurrentDirectory(); File currentDir = newFileWithPath(currentDirString); reportPath = newFileWithParent(currentDir, self->reportName); freeFile(currentDir); freeCharString(currentDirString); } else { reportPath = newFileWithParent(desktopPath, self->reportName); freeFile(desktopPath); } if (fileExists(reportPath)) { logCritical("The path '%s' already contains a previous error report. Please remove the report data and try again."); } else { fileCreate(reportPath, kFileTypeDirectory); } // Now we should have a real error report path charStringCopy(self->reportDirPath, reportPath->absolutePath); freeFile(reportPath); freeCharString(wrappedInfoText); freeCharString(infoText); }