You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
6.4 KiB

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /*
  18. * $Id: Xlat_Win32RC.cpp 698557 2008-09-24 13:19:01Z amassari $
  19. */
  20. // ---------------------------------------------------------------------------
  21. // Includes
  22. // ---------------------------------------------------------------------------
  23. #include "Xlat.hpp"
  24. // ---------------------------------------------------------------------------
  25. // Win32RCFormatter: Public Constructors and Destructor
  26. // ---------------------------------------------------------------------------
  27. Win32RCFormatter::Win32RCFormatter() :
  28. fCurDomainName(0)
  29. , fMsgOffset(0)
  30. , fOutFl(0)
  31. {
  32. }
  33. Win32RCFormatter::~Win32RCFormatter()
  34. {
  35. XMLString::release(&fCurDomainName);
  36. }
  37. // ---------------------------------------------------------------------------
  38. // Win32RCFormatter: Implementation of the formatter interface
  39. // ---------------------------------------------------------------------------
  40. void Win32RCFormatter::endDomain(const XMLCh* const domainName
  41. , const unsigned int msgCount)
  42. {
  43. // And close out the message table declaration
  44. fwprintf(fOutFl, L"END\n");
  45. }
  46. void Win32RCFormatter::endMsgType(const MsgTypes type)
  47. {
  48. // No-op for us
  49. }
  50. void Win32RCFormatter::endOutput()
  51. {
  52. // Close the output file
  53. fclose(fOutFl);
  54. }
  55. void
  56. Win32RCFormatter::nextMessage( const XMLCh* const msgText
  57. , const XMLCh* const msgId
  58. , const unsigned int messageId
  59. , const unsigned int curId)
  60. {
  61. //
  62. // We do not transcode to the output format in this case. Instead we
  63. // just store the straight Unicode format. Because we cannot assume 'L'
  64. // type prefix support, we have to put them out as numeric character
  65. // values.
  66. //
  67. fwprintf(fOutFl, L" %-16d L\"", messageId + fMsgOffset);
  68. bool isOnlyASCII=true;
  69. const XMLCh* rawData = msgText;
  70. while (*rawData)
  71. {
  72. // don't allow " or \ in the message
  73. if(*rawData >= 0x80 || strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}[]()',-+ &.;:<>?!|*=/#_", *rawData)==NULL)
  74. {
  75. isOnlyASCII=false;
  76. break;
  77. }
  78. rawData++;
  79. }
  80. if(isOnlyASCII)
  81. fwprintf(fOutFl, msgText);
  82. else
  83. {
  84. const XMLCh* rawData = msgText;
  85. while (*rawData)
  86. fwprintf(fOutFl, L"\\x%04lX", *rawData++);
  87. }
  88. fwprintf(fOutFl, L"\"\n");
  89. }
  90. void Win32RCFormatter::startDomain( const XMLCh* const domainName
  91. , const XMLCh* const)
  92. {
  93. //
  94. // We have a different array name for each domain, so store that for
  95. // later use and for use below.
  96. //
  97. XMLString::release(&fCurDomainName);
  98. if (!XMLString::compareString(XMLUni::fgXMLErrDomain, domainName))
  99. {
  100. fCurDomainName = XMLString::transcode("gXMLErrArray");
  101. fMsgOffset = 0;
  102. }
  103. else if (!XMLString::compareString(XMLUni::fgExceptDomain, domainName))
  104. {
  105. fCurDomainName = XMLString::transcode("gXMLExceptArray");
  106. fMsgOffset = 0x2000;
  107. }
  108. else if (!XMLString::compareString(XMLUni::fgValidityDomain, domainName))
  109. {
  110. fCurDomainName = XMLString::transcode("gXMLValidityArray");
  111. fMsgOffset = 0x4000;
  112. }
  113. else if (!XMLString::compareString(XMLUni::fgXMLDOMMsgDomain, domainName))
  114. {
  115. fCurDomainName = XMLString::transcode("gXMLDOMMsgArray");
  116. fMsgOffset = 0x6000;
  117. }
  118. else
  119. {
  120. wprintf(L"Unknown message domain: %s\n", domainName);
  121. throw ErrReturn_SrcFmtError;
  122. }
  123. //
  124. // Output the leading part of the array declaration. Its just an
  125. // array of pointers to Unicode chars.
  126. //
  127. fwprintf
  128. (
  129. fOutFl
  130. , L"STRINGTABLE DISCARDABLE\nBEGIN\n"
  131. );
  132. }
  133. void Win32RCFormatter::startMsgType(const MsgTypes type)
  134. {
  135. // No-op for us
  136. }
  137. void Win32RCFormatter::startOutput( const XMLCh* const locale
  138. , const XMLCh* const outPath)
  139. {
  140. //
  141. // Ok, lets try to open the the output file. All of the messages for all
  142. // the domains are put into a single message tabble in a single RC file,
  143. // which can be linked into the program.
  144. //
  145. // CppErrMsgs_xxxx.RC
  146. //
  147. // where xxx is the locale suffix passed in.
  148. //
  149. const unsigned int bufSize = 4095;
  150. XMLCh tmpBuf[bufSize + 1];
  151. // make sure the append will work
  152. tmpBuf[0] = 0;
  153. XMLCh *tmpXMLStr = XMLString::transcode("CppErrMsgs_");
  154. XMLCh *tmpXMLStr2 = XMLString::transcode(".RC");
  155. XMLString::catString(tmpBuf, outPath);
  156. XMLString::catString(tmpBuf, tmpXMLStr );
  157. XMLString::catString(tmpBuf, locale);
  158. XMLString::catString(tmpBuf, tmpXMLStr2 );
  159. XMLString::release(&tmpXMLStr);
  160. XMLString::release(&tmpXMLStr2);
  161. char *tmpStr = XMLString::transcode(tmpBuf);
  162. fOutFl = fopen(tmpStr, "wt");
  163. XMLString::release(&tmpStr);
  164. if ((!fOutFl) || (fwide(fOutFl,1) < 0))
  165. {
  166. wprintf(L"Could not open the output file: %s\n\n", xmlStrToPrintable(tmpBuf) );
  167. releasePrintableStr
  168. throw ErrReturn_OutFileOpenFailed;
  169. }
  170. //
  171. // Ok, lets output the grunt data at the start of the file. We put out a
  172. // comment that indicates its a generated file, and the title string.
  173. //
  174. fwprintf
  175. (
  176. fOutFl
  177. , L"// ----------------------------------------------------------------\n"
  178. L"// This file was generated from the XML error message source.\n"
  179. L"// so do not edit this file directly!!\n"
  180. L"// ----------------------------------------------------------------\n\n"
  181. );
  182. }