boolByte errorReporterShouldCopyPlugins(void) { CharString promptText = newCharStringWithCString(kErrorReportCopyPluginsPromptText); CharString wrappedPromptText; char response; wrappedPromptText = charStringWrap(promptText, 0); printf("%s", wrappedPromptText->data); freeCharString(wrappedPromptText); freeCharString(promptText); response = getchar(); return (response == 'y' || response == 'Y'); }
static void printVersion(void) { CharString versionString = buildInfoGetVersionString(); CharString wrappedLicenseInfo; CharString licenseString = newCharStringWithCString(LICENSE_STRING); printf("%s, build %ld\nCopyright (c) %ld, %s. All rights reserved.\n\n", versionString->data, buildInfoGetDatestamp(), buildInfoGetYear(), VENDOR_NAME); wrappedLicenseInfo = charStringWrap(licenseString, 0); printf("%s\n\n", wrappedLicenseInfo->data); freeCharString(licenseString); freeCharString(wrappedLicenseInfo); freeCharString(versionString); }
void programOptionPrintHelp(const ProgramOption self, boolByte withFullHelp, int indentSize, int initialIndent) { CharString wrappedHelpString; int i; if(self == NULL) { logError("Can't find help for that option. Try running with --help to see all options\n"); return; } // Initial argument indent for(i = 0; i < initialIndent; i ++) { printf(" "); } // All arguments have a long form, so that will always be printed printf("--%s", self->name->data); if(self->hasShortForm) { printf(" (or -%c)", self->name->data[0]); } switch(self->argumentType) { case kProgramOptionArgumentTypeRequired: printf(" <argument>"); break; case kProgramOptionArgumentTypeOptional: printf(" [argument]"); break; case kProgramOptionArgumentTypeNone: default: break; } _programOptionPrintDefaultValue(self); if(withFullHelp) { // Newline and indentation before help wrappedHelpString = charStringWrap(self->help, initialIndent + indentSize); printf("\n%s\n\n", wrappedHelpString->data); freeCharString(wrappedHelpString); } else { printf("\n"); } }
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 snprintf(self->reportDirPath->data, self->reportDirPath->capacity, "%s%c%s", self->desktopPath->data, PATH_DELIMITER, self->reportName->data); makeDirectory(self->reportDirPath); freeCharString(wrappedInfoText); freeCharString(infoText); }
void logCritical(const char *message, ...) { va_list arguments; CharString formattedMessage = newCharString(); CharString wrappedMessage; va_start(arguments, message); // Instead of going through the common logging method, we always dump critical // messages to stderr vsnprintf(formattedMessage->data, formattedMessage->capacity, message, arguments); wrappedMessage = charStringWrap(formattedMessage, 0); fprintf(stderr, "ERROR: %s\n", wrappedMessage->data); if (eventLoggerInstance != NULL && eventLoggerInstance->logFile != NULL) { fprintf(eventLoggerInstance->logFile, "ERROR: %s\n", wrappedMessage->data); } freeCharString(formattedMessage); freeCharString(wrappedMessage); va_end(arguments); }
{ logCritical("Could not parse file '%s'", filename); logCritical("Got error message message: %s", message); logPossibleBug("This file is either corrupt or was parsed incorrectly"); } void logPossibleBug(const char *cause) { CharString extraText = newCharStringWithCString("If you believe this to be a \ bug in MrsWatson, please re-run the program with the --error-report option to \ generate a diagnostic report to send to support."); CharString causeText = newCharStringWithCString(cause); CharString wrappedCause; CharString wrappedExtraText; wrappedCause = charStringWrap(causeText, 0); wrappedExtraText = charStringWrap(extraText, 0); fprintf(stderr, "%s\n", wrappedCause->data); fprintf(stderr, "%s\n", wrappedExtraText->data); freeCharString(wrappedCause); freeCharString(wrappedExtraText); freeCharString(causeText); freeCharString(extraText); } void flushErrorLog(void) { if (eventLoggerInstance != NULL && eventLoggerInstance->logFile != NULL) { fflush(eventLoggerInstance->logFile); }
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); }