| /* |
| * Copyright 1999-2004 The Apache Software Foundation. |
| * |
| * Licensed 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. |
| */ |
| |
| #include "ICUResHandler.hpp" |
| #include "InMemHandler.hpp" |
| #include "MsgCreator.hpp" |
| #include "NLSHandler.hpp" |
| |
| #include <xercesc/sax2/SAX2XMLReader.hpp> |
| #include <xercesc/sax2/XMLReaderFactory.hpp> |
| #include <xercesc/util/PlatformUtils.hpp> |
| #include <xercesc/util/TransService.hpp> |
| |
| #include <cassert> |
| #if !defined(NDEBUG) && defined(_MSC_VER) |
| #include <crtdbg.h> |
| #endif |
| |
| |
| XALAN_USING_STD(cerr) |
| XALAN_USING_STD(cout) |
| XALAN_USING_STD(endl) |
| |
| static const char* s_xalanMsgFileName ="XalanMsg_"; |
| |
| static const char* s_txtExten = ".txt"; |
| |
| static const char* s_msgExten = ".msg"; |
| |
| static const char* s_en = "en_US"; |
| |
| static const char* DATA_FILE_NAME="LocalMsgData.hpp"; |
| |
| // --------------------------------------------------------------------------- |
| // Local helper methods |
| // --------------------------------------------------------------------------- |
| static void usage() |
| { |
| cout << "\nUsage:\n" |
| " MsgCreator [options] <XML file>\n\n" |
| "This program reads XML message file, and then creates C++ " << endl << |
| " source / data files for message localization (for .dll/.so/.cat build) \n" |
| |
| "Options:\n" |
| " <XML file> XLIFF file with messages. Required. \n" |
| " -TYPE xxx Type of localization [ICU | NLS | InMem*]\n" |
| " -LOCALE Example: [ fr | fr_FR ]; The default value is 'en_US' \n" |
| " * = Default if not provided explicitly.\n\n" |
| " -? Show this help.\n\n" |
| "\n" |
| << endl; |
| } |
| |
| |
| class CmdLineParams |
| { |
| |
| public: |
| |
| typedef enum{ |
| |
| ICU_LOCALMSG = 0, |
| INMEM_LOCALMSG, |
| NLS_LOCALMSG |
| |
| }TypeOfLocaleMsg; |
| |
| const char* inXMLFileName; |
| |
| TypeOfLocaleMsg enTypeOfLocaleMsg; |
| |
| const char* encodingName; |
| |
| char localeName[6]; |
| |
| CmdLineParams(): |
| inXMLFileName(0), |
| enTypeOfLocaleMsg(INMEM_LOCALMSG), |
| encodingName("LATIN1") |
| { |
| localeName[0] = 0; |
| strcpy( localeName, s_en); |
| } |
| |
| ~CmdLineParams() {} |
| }; |
| |
| |
| #if defined(OS390) |
| #include <strings.h> |
| |
| int |
| compareNoCase( |
| const char* str1, |
| const char* str2) |
| { |
| return strcasecmp(str1, str2); |
| } |
| |
| #else |
| |
| int |
| compareNoCase( |
| const char* str1, |
| const char* str2) |
| { |
| return stricmp(str1, str2); |
| } |
| |
| #endif |
| |
| bool |
| getArgs( |
| int argc, |
| char* argv[], |
| CmdLineParams& p, |
| const char** pErrorMsg) |
| { |
| |
| bool fSuccess = true; |
| |
| const char* errorMessage = 0; |
| |
| if ( argc > 7) |
| { |
| fSuccess = false; |
| errorMessage = "Too many parameters\n"; |
| } |
| |
| for (int i = 1; i < argc && fSuccess == true; ++i) |
| { |
| if (!compareNoCase("-h", argv[i]) || !compareNoCase("-?", argv[i])) |
| { |
| fSuccess = false; |
| } |
| else if (!compareNoCase("-LOCALE", argv[i]) ) |
| { |
| ++i; |
| if( i < argc && argv[i][0] != '-' ) |
| { |
| #if defined(XALAN_STRICT_ANSI_HEADERS) |
| using std::size_t; |
| #endif |
| const size_t localeLen = strlen(argv[i]); |
| |
| if ( localeLen != 2 && localeLen !=5) |
| { |
| fSuccess = false; |
| errorMessage = "Unrecognized locale\n"; |
| } |
| |
| if ( fSuccess && localeLen == 5 && argv[i][2] != '_') |
| { |
| fSuccess = false; |
| errorMessage = "Unrecognized form of locale\n"; |
| } |
| if ( fSuccess ) |
| { |
| strcpy(p.localeName,argv[i]); |
| |
| p.localeName[5]='\0'; // just in case |
| } |
| } |
| } |
| else if (!compareNoCase("-TYPE", argv[i]) ) |
| { |
| ++i; |
| |
| if( i < argc && argv[i][0] != '-' ) |
| { |
| if( !compareNoCase("ICU",argv[i] )) |
| { |
| p.enTypeOfLocaleMsg = CmdLineParams::ICU_LOCALMSG; |
| |
| }else if( !compareNoCase("NLS",argv[i] )) |
| { |
| p.enTypeOfLocaleMsg = CmdLineParams::NLS_LOCALMSG; |
| |
| } |
| else if( !compareNoCase("InMem",argv[i] )) |
| { |
| p.enTypeOfLocaleMsg = CmdLineParams::INMEM_LOCALMSG; |
| |
| }else |
| { |
| fSuccess = false; |
| errorMessage = "Unknown TYPE of localization\n"; |
| } |
| } |
| else |
| { |
| fSuccess = false; |
| } |
| }else if ( argv[i][0] != '-' ) |
| { |
| p.inXMLFileName = argv[i]; |
| } |
| } |
| |
| if ( fSuccess && p.inXMLFileName == 0) |
| { |
| fSuccess = false; |
| *pErrorMsg = "Please provide XLIFF file.\n"; |
| } |
| |
| if ( fSuccess ) |
| { |
| *pErrorMsg = 0; |
| } |
| else |
| { |
| *pErrorMsg = errorMessage; |
| } |
| |
| return fSuccess; |
| } |
| |
| |
| static char* buildOutputFileName(const CmdLineParams& p) |
| { |
| char* pOutputFileName = new char[80]; |
| pOutputFileName[0] = '\0'; |
| |
| switch(p.enTypeOfLocaleMsg) |
| { |
| |
| case CmdLineParams::ICU_LOCALMSG: |
| { |
| strcpy(pOutputFileName, p.localeName); |
| |
| strcat(pOutputFileName, s_txtExten); |
| |
| break; |
| } |
| case CmdLineParams::INMEM_LOCALMSG: |
| { |
| strcpy(pOutputFileName, DATA_FILE_NAME); |
| |
| break; |
| } |
| |
| case CmdLineParams::NLS_LOCALMSG: |
| { |
| strcpy(pOutputFileName,s_xalanMsgFileName); |
| |
| strncat(pOutputFileName, p.localeName,6); |
| |
| strcat(pOutputFileName, s_msgExten); |
| |
| break; |
| } |
| default: |
| { |
| // in that stage the local should be defined |
| assert ( 0 ); |
| } |
| } |
| return pOutputFileName; |
| } |
| |
| |
| |
| |
| // --------------------------------------------------------------------------- |
| // Program entry point |
| // --------------------------------------------------------------------------- |
| int main(int argC, char* argV[]) |
| { |
| |
| #if !defined(NDEBUG) && defined(_MSC_VER) |
| _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); |
| |
| _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); |
| _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); |
| #endif |
| |
| CmdLineParams theParams; |
| |
| int iReturnValue = 0; |
| |
| const char* errorMessage = 0; |
| |
| if (getArgs(argC, argV, theParams, &errorMessage) == false) |
| { |
| if ( errorMessage != 0) |
| { |
| cerr << errorMessage; |
| } |
| usage(); |
| iReturnValue = 1; |
| |
| } |
| else |
| { |
| |
| try |
| { |
| XMLPlatformUtils::Initialize(); |
| } |
| |
| catch (const XMLException& toCatch) |
| { |
| cerr << "Error during initialization! : " |
| << StrX(toCatch.getMessage()) << endl; |
| iReturnValue = 2; |
| } |
| if (iReturnValue == 0) |
| { |
| |
| { // Create a SAX parser object. |
| SAX2XMLReader* parser = XMLReaderFactory::createXMLReader(); |
| |
| parser->setFeature(XMLUni::fgSAX2CoreValidation, false); |
| |
| parser->setFeature(XMLUni::fgXercesDynamic, true); |
| |
| parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false); |
| |
| parser->setFeature(XMLUni::fgXercesSchema, true); |
| |
| parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false); |
| |
| parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, false); |
| |
| |
| // Create the handler object and install it as the document and error |
| // handler for the parser. Then parse the file and catch any exceptions |
| // that propogate out |
| // |
| |
| int errorCount = 0; |
| |
| const char* fileName = theParams.inXMLFileName; |
| |
| char * const pOutputFileName = buildOutputFileName(theParams); |
| |
| SAX2Handler* handler = 0; |
| try |
| { |
| switch(theParams.enTypeOfLocaleMsg){ |
| case CmdLineParams::ICU_LOCALMSG: |
| { |
| handler = new ICUResHandler(pOutputFileName); |
| break; |
| } |
| case CmdLineParams::INMEM_LOCALMSG: |
| { |
| handler = new InMemHandler(pOutputFileName); |
| break; |
| } |
| case CmdLineParams::NLS_LOCALMSG: |
| { |
| handler = new NLSHandler(pOutputFileName); |
| break; |
| } |
| default: |
| { |
| assert (0); |
| } |
| } |
| } |
| |
| catch(const XalanFileOutputStream::XalanFileOutputStreamOpenException& e) |
| { |
| cerr << "\nAn error occurred\n Error: "; |
| if (e.m_pMessage != 0) |
| { |
| cerr << e.m_pMessage << endl; |
| } |
| else |
| { |
| cerr << "unknown (XalanFileOutputStreamOpenException) " << endl; |
| |
| } |
| |
| iReturnValue = 4; |
| |
| |
| } |
| catch(const XalanFileOutputStream::XalanFileOutputStreamWriteException& e) |
| { |
| cerr << "\nAn error occurred\n Error: "; |
| if (e.m_pMessage != 0) |
| { |
| cerr << e.m_pMessage << endl; |
| } |
| else |
| { |
| cerr << "unknown (XalanFileOutputStreamWriteException) " << endl; |
| |
| } |
| |
| iReturnValue = 5; |
| |
| } |
| catch (...) |
| { |
| cerr << "Unknown error occured." << endl; |
| iReturnValue = 6; |
| } |
| |
| // run the parser |
| if ( iReturnValue == 0) |
| { |
| try |
| { |
| handler->setLocale(theParams.localeName); |
| |
| parser->setContentHandler(handler); |
| |
| parser->setErrorHandler(handler); |
| |
| parser->parse(fileName); |
| |
| errorCount = parser->getErrorCount(); |
| } |
| |
| catch (const XMLException& toCatch) |
| { |
| cerr << "\nAn error occurred\n Error: " |
| << StrX(toCatch.getMessage()) << endl; |
| |
| iReturnValue = 7; |
| } |
| catch (...) |
| { |
| cerr << endl << "General error occured." << endl; |
| iReturnValue = 8; |
| } |
| } |
| |
| |
| delete handler; |
| |
| delete[] pOutputFileName; |
| |
| // |
| // Delete the parser itself. Must be done prior to calling Terminate, below. |
| // |
| delete parser; |
| |
| if (errorCount != 0) |
| iReturnValue = 9; |
| |
| } |
| // And call the termination method |
| XMLPlatformUtils::Terminate(); |
| |
| |
| |
| } |
| |
| } |
| return iReturnValue; |
| } |
| |