| /********************************************************************** |
| // @@@ START COPYRIGHT @@@ |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| // @@@ END COPYRIGHT @@@ |
| **********************************************************************/ |
| |
| /* -*-C++-*- |
| ***************************************************************************** |
| * |
| * File: GetErrorMessage.cpp |
| * Description: |
| * |
| * Created: 2/23/96 |
| * Modified: $ $Date: 2007/10/09 19:40:40 $ (GMT) |
| * Language: C++ |
| * |
| * |
| ***************************************************************************** |
| */ |
| |
| |
| |
| #include "Platform.h" |
| #include <ctype.h> |
| #include <stdio.h> |
| #include <iostream> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <signal.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| |
| |
| #include "GetErrorMessage.h" |
| #include "ErrorMessage.h" |
| #include "NAWinNT.h" |
| |
| #include "sqlmxmsg_msg.h" |
| |
| #include "NLSConversion.h" |
| #include "ExSMCommon.h" |
| |
| #include <fcntl.h> |
| #include <signal.h> |
| #include <nl_types.h> |
| |
| // ---------------------------------------------------- |
| // Definitions common to both _WINDOWS and non-WINDOWS. |
| // ---------------------------------------------------- |
| |
| // UR2 |
| static const NAWchar |
| MsgFile_Not_Found[] = WIDE_("*** ERROR[16000] Error message file not found."), |
| Msg_Not_Found[] = WIDE_("No message found for SQLCODE $0~sqlcode."), |
| Error_Pfx[] = WIDE_("*** ERROR[%d] "), |
| Warning_Pfx[] = WIDE_("*** WARNING[%d] "), |
| Info_Pfx[] = WIDE_("*** INFO[%d] "), |
| Effect_Pfx[] = WIDE_("\nEFFECT:\n"), |
| Success_Msg[] = WIDE_("*** INFO[0] Successful completion.\n"), |
| Cause_Pfx[] = WIDE_("\nCAUSE:\n"), |
| Recovery_Pfx[] = WIDE_("\nRECOVERY:\n"); |
| |
| // UR2. Used by getErrorMessage, NSK version |
| static const char |
| Msg_Not_Found_NSK[] = "No message found for SQLCODE $0~sqlcode."; |
| |
| const Int32 SQLSTATE_LEN = 5; // per Ansi |
| const Int32 HELPID_LEN = 5; // per SQL/MX |
| const Int32 EMS_SEVERITY_LEN = 5; // per SQL/MX |
| const Int32 EMS_EVENT_TARGET_LEN = 7; // per SQL/MX |
| const Int32 EMS_EXPERIENCE_LEVEL_LEN = 8; // per SQL/MX |
| |
| static NABoolean isInfoSQLSTATE(const NAWchar* state) |
| { |
| Int32 i = SQLSTATE_LEN; |
| for (; i--; ) |
| if (*state++ != '0') break; |
| if (i < 0) return TRUE; // SQLSTATE was "00000" |
| // ComASSERT(*--state != ' '); |
| return FALSE; |
| } |
| |
| // Following is the implementation of the SQLSTATE-related functions. |
| class SqlstateInfo |
| { |
| public: |
| SqlstateInfo(Lng32 sqlcode, char * sqlstate, NABoolean fabricatedSqlstate) |
| : sqlcode_(sqlcode), sqlstate_(NULL), |
| fabricatedSqlstate_(fabricatedSqlstate) |
| { |
| if (sqlstate) |
| { |
| sqlstate_ = new char[6]; |
| strcpy(sqlstate_, sqlstate); |
| } |
| }; |
| |
| ~SqlstateInfo() |
| { |
| if (sqlstate_) |
| delete sqlstate_; |
| }; |
| |
| Lng32 sqlcode() { return sqlcode_; }; |
| char * sqlstate() { return sqlstate_; }; |
| NABoolean fabricatedSqlstate() { return fabricatedSqlstate_;}; |
| |
| // ------------------------------------------------------------------------- |
| // Since a SqlstateInfo is an index, it has an automatic conversion operator |
| // to type CollIndex. |
| // ------------------------------------------------------------------------- |
| operator CollIndex () const { return sqlcode_; }; |
| |
| |
| private: |
| Lng32 sqlcode_; |
| char * sqlstate_; |
| NABoolean fabricatedSqlstate_; |
| }; |
| |
| static NAList<SqlstateInfo*> listOfSqlstates_(NULL); |
| static pthread_mutex_t listOfSqlstates_mutex = PTHREAD_MUTEX_INITIALIZER; |
| |
| NABoolean GetSqlstateInfo(Lng32 sqlcode, char * sqlstate, |
| NABoolean &fabricatedSqlstate) |
| { |
| //SqlstateInfo ssi(sqlcode, NULL, TRUE); |
| //CollIndex i = listOfSqlstates_.index(&ssi); |
| |
| NABoolean found = FALSE; |
| CollIndex i = 0; |
| |
| (void) pthread_mutex_lock( &listOfSqlstates_mutex ); |
| while ((i < listOfSqlstates_.entries()) && |
| (NOT found)) |
| { |
| if (listOfSqlstates_[i]->sqlcode() == sqlcode) |
| found = TRUE; |
| else |
| i++; |
| } |
| |
| if (found) //i != NULL_COLL_INDEX) |
| { |
| SqlstateInfo * s = listOfSqlstates_[i]; |
| str_cpy_all(sqlstate, s->sqlstate(), 6); |
| fabricatedSqlstate = s->fabricatedSqlstate(); |
| } |
| (void) pthread_mutex_unlock( &listOfSqlstates_mutex ); |
| return found; |
| } |
| |
| void AddSqlstateInfo(Lng32 sqlcode, char * sqlstate, |
| NABoolean fabricatedSqlstate) |
| { |
| SqlstateInfo * s = NULL; |
| s = new SqlstateInfo(sqlcode, sqlstate, fabricatedSqlstate); |
| |
| (void) pthread_mutex_lock( &listOfSqlstates_mutex ); |
| listOfSqlstates_.insert(s); |
| (void) pthread_mutex_unlock( &listOfSqlstates_mutex ); |
| } |
| |
| // See sqlci/Define.cpp for this |
| static short needToBindToMessageFile = TRUE; |
| void GetErrorMessageRebindMessageFile() { needToBindToMessageFile = TRUE; } |
| |
| // Trivial global function, just hides our message format from caller: |
| // Get past the "...] " and return pointer to rest of the text. |
| char *GetPastHeaderOfErrorMessage(char *text) |
| { |
| while (*text) |
| if (*text++ == ']') |
| break; |
| while (*text && isspace((unsigned char)*text)) // For VS2003 |
| text++; |
| return text; |
| } |
| |
| |
| // Some static data and function followed by the accessor global function |
| static const size_t MAX_MSGFN_LEN = 60; |
| |
| // |
| // NOTE: The variable msgfn_Ptr_ is made THREAD_P because different |
| // Compiler threads might use a different Error Message file name |
| // but it is believed that two Compiler instances within the same |
| // thread would share the same Error Message file name. |
| // |
| static THREAD_P const char *msgfn_Ptr_ = NULL; |
| // |
| // NOTE: The msgfn_Buf_ array is being left as global 'static' because |
| // it holds a filename matching the SQLMX_MESSAGEFILE environment |
| // variable and that should be the same for all Compiler threads. |
| // |
| static char msgfn_Buf_[MAX_MSGFN_LEN]; |
| |
| static void saveErrorMessageFileName(const char *nam, NABoolean fromGetEnv) |
| { |
| if (!fromGetEnv) |
| msgfn_Ptr_ = nam; |
| else { |
| msgfn_Ptr_ = msgfn_Buf_; |
| size_t len = strlen(nam) + 1; // +1 to include the final '\0' |
| strncpy(msgfn_Buf_, nam, MINOF(MAX_MSGFN_LEN, len)); |
| |
| if (len > MAX_MSGFN_LEN) { |
| // Truncate the name in the buffer. Yes, sizeof includes the final '\0'. |
| static const char ellipsis[] = " ..."; |
| strcpy(&msgfn_Buf_[MAX_MSGFN_LEN - sizeof(ellipsis)], ellipsis); |
| } |
| } |
| } |
| |
| const char *GetErrorMessageFileName() // global func |
| { |
| if (!msgfn_Ptr_) { |
| NAWchar *s; |
| GetErrorMessage(1, s); // force a saveErrorMessageFileName() |
| } |
| return msgfn_Ptr_; |
| } |
| |
| // ---------------------------------------------------- |
| |
| NABoolean openMessageCatalog(nl_catd* msgCatalog) |
| { |
| #define MAX_MESSAGE_PATH_LEN 1024 |
| char defaultMessageFile[MAX_MESSAGE_PATH_LEN]; |
| defaultMessageFile[0] = '\0'; |
| |
| char *mySQROOT = getenv("TRAF_HOME"); |
| const char *msgCatPath2 = "/export/bin"; |
| const char *mbType = getenv("SQ_MBTYPE"); |
| const char *msgCatPath4 = "/mxcierrors.cat"; |
| |
| if (mbType == NULL) // happens in older builds |
| mbType = "32"; |
| |
| snprintf(defaultMessageFile, MAX_MESSAGE_PATH_LEN, "%s%s%s%s", |
| mySQROOT, msgCatPath2, mbType, msgCatPath4); |
| |
| // Note that SQLMX_MESSAGEFILE is usually set via ms.env, so the above is not relevant |
| const char *cat = getenv("SQLMX_MESSAGEFILE"); |
| if (!cat) cat = defaultMessageFile; |
| saveErrorMessageFileName(cat, cat != defaultMessageFile); |
| |
| //BEGIN Solution number 10-040729-8360 |
| sigset_t mask_set; /* used to set a signal masking set. */ |
| |
| sigemptyset(&mask_set); |
| sigaddset(&mask_set,SIGINT); |
| sigaddset(&mask_set,SIGQUIT); |
| |
| sigprocmask(SIG_BLOCK, &mask_set , NULL); |
| *msgCatalog = catopen(cat, 0); |
| sigprocmask(SIG_UNBLOCK, &mask_set , NULL); |
| //END Solution number 10-040729-8360 |
| |
| if (!msgCatalog) // The simulated catopen is really fopen... |
| return FALSE; |
| else |
| return TRUE; |
| } |
| |
| NABoolean getErrorMessageFromCatalog(NAErrorCode error_code_abs, |
| MsgTextType M_type, |
| NAWchar* msgBuf, Lng32 msgBufLen |
| , nl_catd* msgCatalog |
| ) |
| { |
| Int32 set_num; |
| |
| set_num = ((error_code_abs/10) * 10); |
| |
| // map M_type to the linenum offset in error.cat file. |
| // ERROR_TEXT, SQL_STATE, HELP_ID are all available at |
| // offset 1 (first line). |
| Lng32 offset = 0; |
| switch (M_type) |
| { |
| case ERROR_TEXT: |
| case SQL_STATE: |
| case HELP_ID: |
| case EMS_SEVERITY: |
| case EMS_EVENT_TARGET: |
| case EMS_EXPERIENCE_LEVEL: |
| offset = 1; |
| break; |
| |
| case CAUSE_TEXT: |
| offset = 2; |
| break; |
| |
| case EFFECT_TEXT: |
| offset = 3; |
| break; |
| |
| case RECOVERY_TEXT: |
| offset = 4; |
| break; |
| } |
| |
| NAErrorCode error_code_ix = (4 * (error_code_abs - set_num)) + offset; |
| |
| |
| |
| //BEGIN Solution number 10-040729-8360 |
| //The second call of catgets dumps if the previous call has been interrupted. |
| sigset_t mask_set; /* used to set a signal masking set. */ |
| |
| sigemptyset(&mask_set); |
| sigaddset(&mask_set,SIGINT); |
| sigaddset(&mask_set,SIGQUIT); |
| |
| sigprocmask(SIG_BLOCK, &mask_set , NULL); |
| char *msg = catgets(*msgCatalog, set_num, error_code_ix, Msg_Not_Found_NSK); |
| |
| sigprocmask(SIG_UNBLOCK, &mask_set , NULL); |
| //END Solution number 10-040729-8360 |
| |
| |
| // The catgets routine returns a pointer to default message if no |
| // message was found for a certain error number. |
| NABoolean result = (msg == Msg_Not_Found_NSK) ? FALSE : TRUE; |
| |
| // convert to Unicode |
| Lng32 wMsgLen = LocaleStringToUnicode(CharInfo::ISO88591, |
| msg, strlen(msg), msgBuf, msgBufLen); |
| |
| |
| if ( wMsgLen == 0 ) |
| result = FALSE; |
| |
| return result ; |
| } |
| |
| short GetErrorMessage (Lng32 error_code, |
| NAWchar *& return_text, |
| MsgTextType M_type, |
| NAWchar* alternate_return_text, |
| Int32 recurse_level, NABoolean prefixNeeded) |
| { |
| |
| short msgNotFound = TRUE; // assume error return |
| |
| NAErrorCode error_code_abs = error_code; |
| if (error_code_abs < 0) |
| error_code_abs = -error_code_abs; // absolute value |
| |
| // |
| // This Gotten_MsgFile_Not_Found variable is made THREAD_P because |
| // different Compiler threads could be for different users. We |
| // should keep track on a per-user basis whether or not we have |
| // previously put out a 'Msg File not found' message. |
| // |
| static THREAD_P short Gotten_MsgFile_Not_Found = FALSE; |
| |
| // |
| // Different Compiler threads may need different msg_buf arrays, but |
| // there should be no chance of invoking another Compiler instance |
| // within the same thread while this buffer's contents are important. |
| // |
| static THREAD_P NAWchar msg_buf[ErrorMessage::MSG_BUF_SIZE]; |
| |
| NAWchar *s = msg_buf; |
| if (alternate_return_text) s = alternate_return_text; |
| |
| switch (M_type) |
| { |
| case ERROR_TEXT: |
| { |
| if ( prefixNeeded == TRUE ) { |
| if (error_code < 0) |
| NAWsprintf(s, Error_Pfx, error_code_abs); |
| else if (error_code > 0) |
| NAWsprintf(s, Warning_Pfx, error_code_abs); |
| else |
| NAWsprintf(s, Info_Pfx, error_code_abs); |
| } else |
| *s = 0; |
| break; |
| } |
| case CAUSE_TEXT: |
| { |
| NAWsprintf(s, Cause_Pfx); |
| break; |
| } |
| case EFFECT_TEXT: |
| { |
| NAWsprintf(s, Effect_Pfx); |
| break; |
| } |
| case RECOVERY_TEXT: |
| { |
| NAWsprintf(s, Recovery_Pfx); |
| break; |
| } |
| case SQL_STATE: |
| case HELP_ID: |
| case EMS_SEVERITY: |
| case EMS_EVENT_TARGET: |
| case EMS_EXPERIENCE_LEVEL: |
| { |
| // Don't need a header for SQLSTATE or HELP_ID.. |
| // However, ensure that msg_buf is empty |
| *s = 0; |
| break; |
| } |
| }; |
| |
| NAWchar *s_orig = s; |
| s += NAWstrlen(s); |
| |
| static NABoolean initialized = FALSE; |
| |
| // |
| // msgCatalog is left as a global 'static' because, once it is initialized, |
| // it is never changed and all threads should be able to share it. |
| // This assumes that all threads will use the same msg catalog. |
| // We use a mutex to prevent more than one thread from trying to initialize |
| // it concurrently and the variable 'initialized' to prevent subsequent |
| // initializations after the first one. |
| // |
| static nl_catd msgCatalog; |
| |
| if (!initialized) // Don't go for the mutex in initialization already done |
| { |
| static pthread_mutex_t openMsgCatMutex = PTHREAD_MUTEX_INITIALIZER; |
| |
| int rc = pthread_mutex_lock(&openMsgCatMutex); |
| exsm_assert_rc( rc, "pthread_mutex_lock" ); |
| |
| // Just in case the initialization happened in another thread while |
| // we were waiting for the mutex, we recheck 'initialized'. |
| // |
| if ( ! initialized ) |
| { |
| if ( openMessageCatalog(&msgCatalog) == FALSE ) |
| { |
| // The message catalog could not be opened. |
| // (Displayed only once per sqlci session.) |
| if (!Gotten_MsgFile_Not_Found) |
| NAWsprintf(s, WIDE_("\n%s"), MsgFile_Not_Found); |
| else |
| NAWsprintf(s, WIDE_("\n")); |
| Gotten_MsgFile_Not_Found = TRUE; |
| } // openMessageCatalog == FALSE |
| else { |
| initialized = TRUE; |
| } |
| } // initialized |
| |
| rc = pthread_mutex_unlock(&openMsgCatMutex); |
| exsm_assert_rc( rc, "pthread_mutex_unlock" ); |
| |
| } // initialized |
| |
| NAWchar msg[ErrorMessage::MSG_BUF_SIZE]; |
| |
| if ( getErrorMessageFromCatalog(error_code_abs, M_type, |
| msg, ErrorMessage::MSG_BUF_SIZE |
| , &msgCatalog |
| ) == FALSE ) |
| { |
| // No message found, just return the default message... |
| // only if we are looking for the error message. |
| if (M_type == ERROR_TEXT) |
| { |
| if (recurse_level == 0) |
| { |
| if (error_code == 0) |
| { |
| s = msg_buf; |
| NAWsprintf(s, Success_Msg); |
| } |
| else |
| { |
| NAWsprintf(s++, WIDE_("\n")); |
| GetErrorMessage(-SQLERRORS_MSG_NOT_FOUND, s, ERROR_TEXT, s, 1); |
| } |
| } |
| else |
| NAWsprintf(s, WIDE_("%s"), Msg_Not_Found); |
| } |
| else |
| NAWsprintf(s, WIDE_("\n")); |
| } |
| else // Message found |
| { |
| NAWchar *msgPtr = msg; |
| |
| if (M_type == SQL_STATE) |
| { |
| // Return text starting at the SQLSTATE |
| NAWstrncpy(s, msgPtr, SQLSTATE_LEN); |
| s[SQLSTATE_LEN] = 0; // Null terminate the buffer. |
| } |
| else if (M_type == HELP_ID) |
| { |
| // Get past the SQLSTATE field |
| // and return text starting at the HELPID |
| msgPtr += SQLSTATE_LEN + 1; // +1 for delimiting space |
| NAWstrncpy(s, msgPtr, HELPID_LEN); |
| s[HELPID_LEN] = 0; |
| } |
| else if (M_type == EMS_EXPERIENCE_LEVEL) |
| { |
| // Get past the SQLSTATE and HELP_ID fields |
| // and return text starting at the EMS_EXPERIENCE_LEVEL |
| msgPtr += SQLSTATE_LEN + 1 + HELPID_LEN + 1; // +1 for delimiting space |
| NAWstrncpy(s, msgPtr, EMS_EXPERIENCE_LEVEL_LEN); |
| s[EMS_EXPERIENCE_LEVEL_LEN] = 0; |
| } |
| else if (M_type == EMS_SEVERITY) |
| { |
| // Get past the SQLSTATE, HELP_ID and EMS_EXPERIENCE_LEVEL fields |
| // and return text starting at the EMS_SEVERITY |
| msgPtr += SQLSTATE_LEN + 1 + HELPID_LEN + 1 + EMS_EXPERIENCE_LEVEL_LEN + 1; // +1 for delimiting space |
| NAWstrncpy(s, msgPtr, EMS_SEVERITY_LEN); |
| s[EMS_SEVERITY_LEN] = 0; |
| } |
| else if (M_type == EMS_EVENT_TARGET) |
| { |
| // Get past the SQLSTATE, HELP_ID, EMS_EXPERIENCE_LEVEL and EMS_SEVERITY fields |
| // and return text starting at the EMS_EVENT_TARGET |
| msgPtr += SQLSTATE_LEN + 1 + HELPID_LEN + 1 + EMS_EXPERIENCE_LEVEL_LEN + 1 |
| + EMS_SEVERITY_LEN + 1; // +1 for delimiting space |
| NAWstrncpy(s, msgPtr, EMS_EVENT_TARGET_LEN); |
| s[EMS_EVENT_TARGET_LEN] = 0; |
| } |
| else |
| { |
| if (s != s_orig && isInfoSQLSTATE(msg)) |
| { |
| s = s_orig; |
| NAWsprintf(s, Info_Pfx, error_code_abs); |
| s += NAWstrlen(s); |
| } |
| |
| // Get past the SQLSTATE, HELP_ID, EMS_EXPERIENCE_LEVEL, EMS_SEVERITY, and |
| // EMS_EVENT_TARGET fields and return only the message text. |
| msgPtr += SQLSTATE_LEN + 1 + HELPID_LEN + 1 + EMS_SEVERITY_LEN + 1 |
| + EMS_EVENT_TARGET_LEN + 1 + EMS_EXPERIENCE_LEVEL_LEN + 1; |
| NAWsprintf(s, WIDE_("%s"), msgPtr); |
| } |
| |
| msgNotFound = FALSE; // success, message found |
| } |
| |
| return_text = msg_buf; |
| |
| if (alternate_return_text) return_text = alternate_return_text; |
| |
| ErrorMessageOverflowCheckW(return_text, ErrorMessage::MSG_BUF_SIZE); |
| |
| return msgNotFound; |
| |
| } // GetErrorMessage |
| |
| |
| // These two platform-dependent clones of GetErrorMessage could be |
| // enormously simplified by using the appropriate #defines from NAWinNT.h ... |
| |
| |
| // |
| // The variable kludgeMessageFileText is a pointer to a 'const' string. |
| // The pointer can change, but only once. It is a global 'static' |
| // because it is believed that all threads can share the same string |
| // once it is set. Also, it is used only in Debug-Mode builds. |
| // |
| static const char *kludgeMessageFileText = NULL; |
| |
| static short kludgeReadStraightFromMessageFile |
| (Lng32 num, NAWchar *msgBuf, Lng32 bufSize) |
| { |
| #ifdef NDEBUG |
| return FALSE; |
| #else |
| // A kludge for when the message DLL is completely gone: |
| // use 100K of system heap to read in as much of SqlciErrors.txt |
| // as we can, and do string lookup on that to find messages. |
| // |
| static const char emptyText = '\0'; |
| if (!kludgeMessageFileText) { // first time in |
| kludgeMessageFileText = &emptyText; |
| const char *env = getenv("SQLMX_MESSAGEFILE"); // /bin/SqlciErrors.txt |
| saveErrorMessageFileName(env, !!env); |
| if (!env) return FALSE; |
| Int32 fd = open(env, O_RDONLY); |
| if (fd < 0) return FALSE; |
| |
| |
| struct stat stbuf; |
| |
| if (fstat(fd, &stbuf) != 0) |
| return FALSE; |
| |
| char *buffer = new char[stbuf.st_size + 2]; // For prefix sentinel and trailing null |
| if (!buffer) return FALSE; |
| buffer[0] = '\n'; // prefix sentinel |
| |
| size_t i = 1; |
| size_t num_left = stbuf.st_size; |
| size_t nread; |
| |
| while ((nread = read(fd, &buffer[i], (num_left < 8192 ? num_left : 8192))) != 0) |
| { |
| i += nread; |
| num_left -= nread; |
| } |
| buffer[i] = '\0'; |
| kludgeMessageFileText = buffer; |
| close(fd); |
| } |
| if (!*kludgeMessageFileText) return FALSE; |
| char numAscii[20]; |
| sprintf(numAscii, "\n%d ", num); |
| const char *msg = strstr(kludgeMessageFileText, numAscii); |
| if (!msg) { *msgBuf = -1; return FALSE; } // nonzero: msgfile fnd |
| msg += strlen(numAscii); |
| UInt32 i = 0; |
| for (; i < bufSize; i++) { // cvt char* to WCHAR* |
| char c = msg[i]; |
| if (c == '\n' || c == '\r') break; |
| msgBuf[i] = c; |
| } |
| msgBuf[i] = '\0'; |
| return TRUE; // message found |
| #endif |
| } // kludgeReadStraightFromMessageFile |
| |
| void GetPreprocessorInstallPath(char *thePath, char *CorCOBOL) |
| { |
| } // GetPreProcessorInstallPath |
| |
| |
| NABoolean openMessageCatalog() |
| { |
| return 0; |
| } |
| |
| short GetErrorMessageRC(Lng32 num, NAWchar* msgBuf, Lng32 bufSize) |
| { |
| return kludgeReadStraightFromMessageFile(num, msgBuf, bufSize); |
| // return TRUE; |
| } // GetErrorMessageRC |
| |
| |
| |
| void ErrorMessageOverflowCheckW (NAWchar *buf, size_t max) |
| { |
| size_t len = NAWstrlen(buf); |
| if (len > max-1) // max-1, to allow for terminal '\0' |
| { |
| cerr << endl << "ERROR: msg overflow " << len << " " << max-1 << endl; |
| |
| char* buf8bit = new char[len+1]; |
| Lng32 l = UnicodeStringToLocale(CharInfo::ISO88591, buf, len, |
| buf8bit, len+1); |
| if ( l != len ) |
| ABORT("Unicode To Locale Translation"); |
| |
| printf("%s\n", buf8bit); |
| ABORT("ErrorMessageOverflowCheck"); // memory overrun/corruption, unsafe to continue |
| } |
| } |