From 302bf1b523012e11b60425d6eee1221ebc2724eb Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Sun, 3 Nov 2019 00:17:46 -0400 Subject: Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1 --- mailnews/base/util/nsMsgUtils.h | 589 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 589 insertions(+) create mode 100644 mailnews/base/util/nsMsgUtils.h (limited to 'mailnews/base/util/nsMsgUtils.h') diff --git a/mailnews/base/util/nsMsgUtils.h b/mailnews/base/util/nsMsgUtils.h new file mode 100644 index 000000000..97f5010ae --- /dev/null +++ b/mailnews/base/util/nsMsgUtils.h @@ -0,0 +1,589 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _NSMSGUTILS_H +#define _NSMSGUTILS_H + +#include "nsIURL.h" +#include "nsStringGlue.h" +#include "msgCore.h" +#include "nsCOMPtr.h" +#include "MailNewsTypes2.h" +#include "nsTArray.h" +#include "nsInterfaceRequestorAgg.h" +#include "nsILoadGroup.h" +// Disable deprecation warnings generated by nsISupportsArray and associated +// classes. +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning (disable : 4996) +#endif +#include "nsISupportsArray.h" +#include "nsIAtom.h" +#include "nsINetUtil.h" +#include "nsIRequest.h" +#include "nsILoadInfo.h" +#include "nsServiceManagerUtils.h" +#include "nsUnicharUtils.h" +#include "nsIFile.h" + +class nsIChannel; +class nsIFile; +class nsIPrefBranch; +class nsIMsgFolder; +class nsIMsgMessageService; +class nsIUrlListener; +class nsIOutputStream; +class nsIInputStream; +class nsIMsgDatabase; +class nsIMutableArray; +class nsIProxyInfo; +class nsIMsgWindow; +class nsISupportsArray; +class nsIStreamListener; + +#define FILE_IO_BUFFER_SIZE (16*1024) +#define MSGS_URL "chrome://messenger/locale/messenger.properties" + +//These are utility functions that can used throughout the mailnews code + +NS_MSG_BASE nsresult GetMessageServiceContractIDForURI(const char *uri, nsCString &contractID); + +NS_MSG_BASE nsresult GetMessageServiceFromURI(const nsACString& uri, nsIMsgMessageService **aMessageService); + +NS_MSG_BASE nsresult GetMsgDBHdrFromURI(const char *uri, nsIMsgDBHdr **msgHdr); + +NS_MSG_BASE nsresult CreateStartupUrl(const char *uri, nsIURI** aUrl); + +NS_MSG_BASE nsresult NS_MsgGetPriorityFromString( + const char * const priority, + nsMsgPriorityValue & outPriority); + +NS_MSG_BASE nsresult NS_MsgGetPriorityValueString( + const nsMsgPriorityValue p, + nsACString & outValueString); + +NS_MSG_BASE nsresult NS_MsgGetUntranslatedPriorityName( + const nsMsgPriorityValue p, + nsACString & outName); + +NS_MSG_BASE nsresult NS_MsgHashIfNecessary(nsAutoString &name); +NS_MSG_BASE nsresult NS_MsgHashIfNecessary(nsAutoCString &name); + +NS_MSG_BASE nsresult FormatFileSize(int64_t size, bool useKB, nsAString &formattedSize); + + +/** + * given a folder uri, return the path to folder in the user profile directory. + * + * @param aFolderURI uri of folder we want the path to, without the scheme + * @param[out] aPathString result path string + * @param aScheme scheme of the uri + * @param[optional] aIsNewsFolder is this a news folder? + */ +NS_MSG_BASE nsresult +NS_MsgCreatePathStringFromFolderURI(const char *aFolderURI, + nsCString& aPathString, + const nsCString &aScheme, + bool aIsNewsFolder=false); + +/** + * Given a string and a length, removes any "Re:" strings from the front. + * It also deals with that dumbass "Re[2]:" thing that some losing mailers do. + * + * If mailnews.localizedRe is set, it will also remove localized "Re:" strings. + * + * @return true if it made a change (in which case the caller should look to + * modifiedSubject for the result) and false otherwise (in which + * case the caller should look at subject for the result) + */ +NS_MSG_BASE bool NS_MsgStripRE(const nsCString& subject, nsCString& modifiedSubject); + +NS_MSG_BASE char * NS_MsgSACopy(char **destination, const char *source); + +NS_MSG_BASE char * NS_MsgSACat(char **destination, const char *source); + +NS_MSG_BASE nsresult NS_MsgEscapeEncodeURLPath(const nsAString& aStr, + nsCString& aResult); + +NS_MSG_BASE nsresult NS_MsgDecodeUnescapeURLPath(const nsACString& aPath, + nsAString& aResult); + +NS_MSG_BASE bool WeAreOffline(); + +// Check if a folder with aFolderUri exists +NS_MSG_BASE nsresult GetExistingFolder(const nsCString& aFolderURI, nsIMsgFolder **aFolder); + +// Escape lines starting with "From ", ">From ", etc. in a buffer. +NS_MSG_BASE nsresult EscapeFromSpaceLine(nsIOutputStream *ouputStream, char *start, const char *end); +NS_MSG_BASE bool IsAFromSpaceLine(char *start, const char *end); + +NS_MSG_BASE nsresult NS_GetPersistentFile(const char *relPrefName, + const char *absPrefName, + const char *dirServiceProp, // Can be NULL + bool& gotRelPref, + nsIFile **aFile, + nsIPrefBranch *prefBranch = nullptr); + +NS_MSG_BASE nsresult NS_SetPersistentFile(const char *relPrefName, + const char *absPrefName, + nsIFile *aFile, + nsIPrefBranch *prefBranch = nullptr); + +NS_MSG_BASE nsresult IsRFC822HeaderFieldName(const char *aHdr, bool *aResult); + +NS_MSG_BASE nsresult NS_GetUnicharPreferenceWithDefault(nsIPrefBranch *prefBranch, //can be null, if so uses the root branch + const char *prefName, + const nsAString& defValue, + nsAString& prefValue); + +NS_MSG_BASE nsresult NS_GetLocalizedUnicharPreferenceWithDefault(nsIPrefBranch *prefBranch, //can be null, if so uses the root branch + const char *prefName, + const nsAString& defValue, + nsAString& prefValue); + +NS_MSG_BASE nsresult NS_GetLocalizedUnicharPreference(nsIPrefBranch *prefBranch, //can be null, if so uses the root branch + const char *prefName, + nsAString& prefValue); + + /** + * this needs a listener, because we might have to create the folder + * on the server, and that is asynchronous + */ +NS_MSG_BASE nsresult GetOrCreateFolder(const nsACString & aURI, nsIUrlListener *aListener); + +// Returns true if the nsIURI is a message under an RSS account +NS_MSG_BASE nsresult IsRSSArticle(nsIURI * aMsgURI, bool *aIsRSSArticle); + +// digest needs to be a pointer to a 16 byte buffer +#define DIGEST_LENGTH 16 + +NS_MSG_BASE nsresult MSGCramMD5(const char *text, int32_t text_len, const char *key, int32_t key_len, unsigned char *digest); +NS_MSG_BASE nsresult MSGApopMD5(const char *text, int32_t text_len, const char *password, int32_t password_len, unsigned char *digest); + +// helper functions to convert a 64bits PRTime into a 32bits value (compatible time_t) and vice versa. +NS_MSG_BASE void PRTime2Seconds(PRTime prTime, uint32_t *seconds); +NS_MSG_BASE void PRTime2Seconds(PRTime prTime, int32_t *seconds); +NS_MSG_BASE void Seconds2PRTime(uint32_t seconds, PRTime *prTime); +// helper function to generate current date+time as a string +NS_MSG_BASE void MsgGenerateNowStr(nsACString &nowStr); + +// Appends the correct summary file extension onto the supplied fileLocation +// and returns it in summaryLocation. +NS_MSG_BASE nsresult GetSummaryFileLocation(nsIFile* fileLocation, + nsIFile** summaryLocation); + +// Gets a special directory and appends the supplied file name onto it. +NS_MSG_BASE nsresult GetSpecialDirectoryWithFileName(const char* specialDirName, + const char* fileName, + nsIFile** result); + +// cleanup temp files with the given filename and extension, including +// the consecutive -NNNN ones that we can find. If there are holes, e.g., +// -1-10,12. exist, but -11. does not +// we'll clean up 1-10. If the leaks are common, I think the gaps will tend to +// be filled. +NS_MSG_BASE nsresult MsgCleanupTempFiles(const char *fileName, const char *extension); + +NS_MSG_BASE nsresult MsgGetFileStream(nsIFile *file, nsIOutputStream **fileStream); + +NS_MSG_BASE nsresult MsgReopenFileStream(nsIFile *file, nsIInputStream *fileStream); + +// Automatically creates an output stream with a suitable buffer +NS_MSG_BASE nsresult MsgNewBufferedFileOutputStream(nsIOutputStream **aResult, nsIFile *aFile, int32_t aIOFlags = -1, int32_t aPerm = -1); + +// Automatically creates an output stream with a suitable buffer, but write to a temporary file first, then rename to aFile +NS_MSG_BASE nsresult MsgNewSafeBufferedFileOutputStream(nsIOutputStream **aResult, nsIFile *aFile, int32_t aIOFlags = -1, int32_t aPerm = -1); + +// fills in the position of the passed in keyword in the passed in keyword list +// and returns false if the keyword isn't present +NS_MSG_BASE bool MsgFindKeyword(const nsCString &keyword, nsCString &keywords, int32_t *aStartOfKeyword, int32_t *aLength); + +NS_MSG_BASE bool MsgHostDomainIsTrusted(nsCString &host, nsCString &trustedMailDomains); + +// gets an nsIFile from a UTF-8 file:// path +NS_MSG_BASE nsresult MsgGetLocalFileFromURI(const nsACString &aUTF8Path, nsIFile **aFile); + +NS_MSG_BASE void MsgStripQuotedPrintable (unsigned char *src); + +/* + * Utility function copied from nsReadableUtils + */ +NS_MSG_BASE bool MsgIsUTF8(const nsACString& aString); + +/* + * Utility functions that call functions from nsINetUtil + */ + +NS_MSG_BASE nsresult MsgEscapeString(const nsACString &aStr, + uint32_t aType, nsACString &aResult); + +NS_MSG_BASE nsresult MsgUnescapeString(const nsACString &aStr, + uint32_t aFlags, nsACString &aResult); + +NS_MSG_BASE nsresult MsgEscapeURL(const nsACString &aStr, uint32_t aFlags, + nsACString &aResult); + +// Converts an nsTArray of nsMsgKeys plus a database, to an array of nsIMsgDBHdrs. +NS_MSG_BASE nsresult MsgGetHeadersFromKeys(nsIMsgDatabase *aDB, + const nsTArray &aKeys, + nsIMutableArray *aHeaders); +// Converts an array of nsMsgKeys plus a database, to an array of nsIMsgDBHdrs. +NS_MSG_BASE nsresult MsgGetHdrsFromKeys(nsIMsgDatabase *aDB, + nsMsgKey *aKeys, + uint32_t aNumKeys, + nsIMutableArray **aHeaders); + +NS_MSG_BASE nsresult MsgExamineForProxy(nsIChannel *channel, + nsIProxyInfo **proxyInfo); + +NS_MSG_BASE int32_t MsgFindCharInSet(const nsCString &aString, + const char* aChars, uint32_t aOffset = 0); +NS_MSG_BASE int32_t MsgFindCharInSet(const nsString &aString, + const char* aChars, uint32_t aOffset = 0); + + +// advances bufferOffset to the beginning of the next line, if we don't +// get to maxBufferOffset first. Returns false if we didn't get to the +// next line. +NS_MSG_BASE bool MsgAdvanceToNextLine(const char *buffer, uint32_t &bufferOffset, + uint32_t maxBufferOffset); + +/** + * Alerts the user that the login to the server failed. Asks whether the + * connection should: retry, cancel, or request a new password. + * + * @param aMsgWindow The message window associated with this action (cannot + * be null). + * @param aHostname The hostname of the server for which the login failed. + * @param aResult The button pressed. 0 for retry, 1 for cancel, + * 2 for enter a new password. + * @return NS_OK for success, NS_ERROR_* if there was a failure in + * creating the dialog. + */ +NS_MSG_BASE nsresult MsgPromptLoginFailed(nsIMsgWindow *aMsgWindow, + const nsCString &aHostname, + int32_t *aResult); + +/** + * Calculate a PRTime value used to determine if a date is XX + * days ago. This is used by various retention setting algorithms. + */ +NS_MSG_BASE PRTime MsgConvertAgeInDaysToCutoffDate(int32_t ageInDays); + +/** + * Converts the passed in term list to its string representation. + * + * @param aTermList Array of nsIMsgSearchTerms + * @param[out] aOutString result representation of search terms. + * + */ +NS_MSG_BASE nsresult MsgTermListToString(nsISupportsArray *aTermList, nsCString &aOutString); + +NS_MSG_BASE nsresult +MsgStreamMsgHeaders(nsIInputStream *aInputStream, nsIStreamListener *aConsumer); + +/** + * convert string to uint64_t + * + * @param str conveted string + * @returns uint64_t vaule for success, 0 for parse failure + */ +NS_MSG_BASE uint64_t ParseUint64Str(const char *str); + +/** + * Detect charset of file + * + * @param aFile The target of nsIFile + * @param[out] aCharset The charset string + */ +NS_MSG_BASE nsresult MsgDetectCharsetFromFile(nsIFile *aFile, nsACString &aCharset); + +/* + * Converts a buffer to plain text. Some conversions may + * or may not work with certain end charsets which is why we + * need that as an argument to the function. If charset is + * unknown or deemed of no importance NULL could be passed. + * @param[in/out] aConBuf Variable with the text to convert + * @param formatFlowed Use format flowed? + * @param delsp Use delsp=yes when flowed + * @param formatOutput Reformat the output? + & @param disallowBreaks Disallow breaks when formatting + */ +NS_MSG_BASE nsresult +ConvertBufToPlainText(nsString &aConBuf, bool formatFlowed, bool delsp, + bool formatOutput, bool disallowBreaks); + +/** + * The following definitons exist for compatibility between the internal and + * external APIs. Where possible they just forward to the existing API. + */ + +#ifdef MOZILLA_INTERNAL_API +#include "nsEscape.h" + +/** + * The internal API expects nsCaseInsensitiveC?StringComparator() and true. + * Redefine CaseInsensitiveCompare so that Find works. + */ +#define CaseInsensitiveCompare true +/** + * The following methods are not exposed to the external API, but when we're + * using the internal API we can simply redirect the calls appropriately. + */ +#define MsgLowerCaseEqualsLiteral(str, l) \ + (str).LowerCaseEqualsLiteral(l) +#define MsgRFindChar(str, ch, len) \ + (str).RFindChar(ch, len) +#define MsgCompressWhitespace(str) \ + (str).CompressWhitespace() +#define MsgEscapeHTML(str) \ + nsEscapeHTML(str) +#define MsgEscapeHTML2(buffer, len) \ + nsEscapeHTML2(buffer, len) +#define MsgReplaceSubstring(str, what, replacement) \ + (str).ReplaceSubstring(what, replacement) +#define MsgIsUTF8(str) \ + IsUTF8(str) +#define MsgNewInterfaceRequestorAggregation(aFirst, aSecond, aResult) \ + NS_NewInterfaceRequestorAggregation(aFirst, aSecond, aResult) +#define MsgNewNotificationCallbacksAggregation(aCallbacks, aLoadGroup, aResult) \ + NS_NewNotificationCallbacksAggregation(aCallbacks, aLoadGroup, aResult) +#define MsgGetAtom(aString) \ + NS_Atomize(aString) +#define MsgNewAtom(aString) \ + NS_Atomize(aString) +#define MsgReplaceChar(aString, aNeedle, aReplacement) \ + (aString).ReplaceChar(aNeedle, aReplacement) +#define MsgFind(str, what, ignore_case, offset) \ + (str).Find(what, ignore_case, offset) +#define MsgCountChar(aString, aChar) \ + (aString).CountChar(aChar) + +#else + +/** + * The external API expects CaseInsensitiveCompare. Redefine + * nsCaseInsensitiveC?StringComparator() so that Equals works. + */ +#define nsCaseInsensitiveCStringComparator() \ + CaseInsensitiveCompare +#define nsCaseInsensitiveStringComparator() \ + CaseInsensitiveCompare +/// The external API does not provide kNotFound. +#define kNotFound -1 +/** + * The external API does not provide the following methods. While we can + * reasonably easily define them in terms of existing methods, we only want + * to do this when using the external API. + */ +#define AppendASCII \ + AppendLiteral +#define AppendUTF16toUTF8(source, dest) \ + (dest).Append(NS_ConvertUTF16toUTF8(source)) +#define AppendUTF8toUTF16(source, dest) \ + (dest).Append(NS_ConvertUTF8toUTF16(source)) +#define AppendASCIItoUTF16(source, dest) \ + (dest).Append(NS_ConvertASCIItoUTF16(source)) +#define Compare(str1, str2, comp) \ + (str1).Compare(str2, comp) +#define CaseInsensitiveFindInReadable(what, str) \ + ((str).Find(what, CaseInsensitiveCompare) != kNotFound) +#define LossyAppendUTF16toASCII(source, dest) \ + (dest).Append(NS_LossyConvertUTF16toASCII(source)) +#define Last() \ + EndReading()[-1] +#define SetCharAt(ch, index) \ + Replace(index, 1, ch) +#define NS_NewISupportsArray(result) \ + CallCreateInstance(NS_SUPPORTSARRAY_CONTRACTID, static_cast(result)) +/** + * The internal and external methods expect the parameters in a different order. + * The internal API also always expects a flag rather than a comparator. + */ +inline int32_t MsgFind(nsAString &str, const char *what, bool ignore_case, uint32_t offset) +{ + return str.Find(what, offset, ignore_case); +} + +inline int32_t MsgFind(nsACString &str, const char *what, bool ignore_case, int32_t offset) +{ + /* See Find_ComputeSearchRange from nsStringObsolete.cpp */ + if (offset < 0) { + offset = 0; + } + if (ignore_case) + return str.Find(nsDependentCString(what), offset, CaseInsensitiveCompare); + return str.Find(nsDependentCString(what), offset); +} + +inline int32_t MsgFind(nsACString &str, const nsACString &what, bool ignore_case, int32_t offset) +{ + /* See Find_ComputeSearchRange from nsStringObsolete.cpp */ + if (offset < 0) { + offset = 0; + } + if (ignore_case) + return str.Find(what, offset, CaseInsensitiveCompare); + return str.Find(what, offset); +} + +/** + * The following methods are not exposed to the external API so we define + * equivalent versions here. + */ +/// Equivalent of LowerCaseEqualsLiteral(literal) +#define MsgLowerCaseEqualsLiteral(str, literal) \ + (str).Equals(literal, CaseInsensitiveCompare) +/// Equivalent of RFindChar(ch, len) +#define MsgRFindChar(str, ch, len) \ + StringHead(str, len).RFindChar(ch) +/// Equivalent of aString.CompressWhitespace() +NS_MSG_BASE void MsgCompressWhitespace(nsCString& aString); +/// Equivalent of nsEscapeHTML(aString) +NS_MSG_BASE char *MsgEscapeHTML(const char *aString); +/// Equivalent of nsEscapeHTML2(aBuffer, aLen) +NS_MSG_BASE char16_t *MsgEscapeHTML2(const char16_t *aBuffer, int32_t aLen); +// Existing replacement for IsUTF8 +NS_MSG_BASE bool MsgIsUTF8(const nsACString& aString); +/// Equivalent of NS_Atomize(aUTF8String) +NS_MSG_BASE already_AddRefed MsgNewAtom(const char* aString); +/// Equivalent of NS_Atomize(aUTF8String) +inline already_AddRefed MsgGetAtom(const char* aUTF8String) +{ + return MsgNewAtom(aUTF8String); +} +/// Equivalent of ns(C)String::ReplaceSubstring(what, replacement) +NS_MSG_BASE void MsgReplaceSubstring(nsAString &str, const nsAString &what, const nsAString &replacement); +NS_MSG_BASE void MsgReplaceSubstring(nsACString &str, const char *what, const char *replacement); +/// Equivalent of ns(C)String::ReplaceChar(what, replacement) +NS_MSG_BASE void MsgReplaceChar(nsString& str, const char *set, const char16_t replacement); +NS_MSG_BASE void MsgReplaceChar(nsCString& str, const char needle, const char replacement); +// Equivalent of NS_NewInterfaceRequestorAggregation(aFirst, aSecond, aResult) +NS_MSG_BASE nsresult MsgNewInterfaceRequestorAggregation(nsIInterfaceRequestor *aFirst, + nsIInterfaceRequestor *aSecond, + nsIInterfaceRequestor **aResult); + +/** + * This function is based on NS_NewNotificationCallbacksAggregation from + * nsNetUtil.h + * + * This function returns a nsIInterfaceRequestor instance that returns the + * same result as NS_QueryNotificationCallbacks when queried. + */ +inline nsresult +MsgNewNotificationCallbacksAggregation(nsIInterfaceRequestor *callbacks, + nsILoadGroup *loadGroup, + nsIInterfaceRequestor **result) +{ + nsCOMPtr cbs; + if (loadGroup) + loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs)); + return MsgNewInterfaceRequestorAggregation(callbacks, cbs, result); +} + +/** + * Count occurences of specified character in string. + * + */ +inline +uint32_t MsgCountChar(nsACString &aString, char16_t aChar) { + const char *begin, *end; + uint32_t num_chars = 0; + aString.BeginReading(&begin, &end); + for (const char *current = begin; current < end; ++current) { + if (*current == aChar) + ++num_chars; + } + return num_chars; +} + +inline +uint32_t MsgCountChar(nsAString &aString, char16_t aChar) { + const char16_t *begin, *end; + uint32_t num_chars = 0; + aString.BeginReading(&begin, &end); + for (const char16_t *current = begin; current < end; ++current) { + if (*current == aChar) + ++num_chars; + } + return num_chars; +} + +#endif + +/** + * Converts a hex string into an integer. + * Processes up to aNumChars characters or the first non-hex char. + * It is not an error if less than aNumChars valid hex digits are found. + */ +NS_MSG_BASE uint64_t MsgUnhex(const char *aHexString, size_t aNumChars); + +/** + * Checks if a string is a valid hex literal containing at least aNumChars digits. + */ +NS_MSG_BASE bool MsgIsHex(const char *aHexString, size_t aNumChars); + +/** + * Convert an uint32_t to a nsMsgKey. + * Currently they are mostly the same but we need to preserve the notion that + * nsMsgKey is an opaque value that can't be treated as a generic integer + * (except when storing it into the database). It enables type safety checks and + * may prevent coding errors. + */ +NS_MSG_BASE nsMsgKey msgKeyFromInt(uint32_t aValue); + +NS_MSG_BASE nsMsgKey msgKeyFromInt(uint64_t aValue); + +/** + * Helper function to extract query part from URL spec. + */ +nsAutoCString MsgExtractQueryPart(nsAutoCString spec, const char* queryToExtract); + +/** + * Helper macro for defining getter/setters. Ported from nsISupportsObsolete.h + */ +#define NS_IMPL_GETSET(clazz, attr, type, member) \ + NS_IMETHODIMP clazz::Get##attr(type *result) \ + { \ + NS_ENSURE_ARG_POINTER(result); \ + *result = member; \ + return NS_OK; \ + } \ + NS_IMETHODIMP clazz::Set##attr(type aValue) \ + { \ + member = aValue; \ + return NS_OK; \ + } + +#endif + + /** + * Macro and helper function for reporting an error, warning or + * informational message to the Error Console + * + * This will require the inclusion of the following files in the source file + * #include "nsIScriptError.h" + * #include "nsIConsoleService.h" + * + */ + +NS_MSG_BASE +void MsgLogToConsole4(const nsAString &aErrorText, const nsAString &aFilename, + uint32_t aLine, uint32_t flags); + +// Macro with filename and line number +#define MSG_LOG_TO_CONSOLE(_text, _flag) MsgLogToConsole4(NS_LITERAL_STRING(_text), NS_LITERAL_STRING(__FILE__), __LINE__, _flag) +#define MSG_LOG_ERR_TO_CONSOLE(_text) MSG_LOG_TO_CONSOLE(_text, nsIScriptError::errorFlag) +#define MSG_LOG_WARN_TO_CONSOLE(_text) MSG_LOG_TO_CONSOLE(_text, nsIScriptError::warningFlag) +#define MSG_LOG_INFO_TO_CONSOLE(_text) MSG_LOG_TO_CONSOLE(_text, nsIScriptError::infoFlag) + +// Helper macros to cope with shoddy I/O error reporting (or lack thereof) +#define MSG_NS_ERROR(_txt) do { NS_ERROR(_txt); MSG_LOG_ERR_TO_CONSOLE(_txt); } while(0) +#define MSG_NS_WARNING(_txt) do { NS_WARNING(_txt); MSG_LOG_WARN_TO_CONSOLE(_txt); } while (0) +#define MSG_NS_WARN_IF_FALSE(_val, _txt) do { if (!(_val)) { NS_WARNING(_txt); MSG_LOG_WARN_TO_CONSOLE(_txt); } } while (0) +#define MSG_NS_INFO(_txt) do { MSG_LOCAL_INFO_TO_CONSOLE(_txt); \ + fprintf(stderr,"(info) %s (%s:%d)\n", _txt, __FILE__, __LINE__); } while(0) -- cgit v1.2.3