Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* chardefs.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* System-Dependent Definition of National Specific Characters               */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include <string.h>
  12.  
  13. #include "chardefs.h"
  14.  
  15. static const tNLSCharacterTab Tab8859_1 =
  16. {
  17.   { '\344', '\0' }, /* eCH_ae */
  18.   { '\353', '\0' }, /* eCH_ee */
  19.   { '\357', '\0' }, /* eCH_ie */
  20.   { '\366', '\0' }, /* eCH_oe */
  21.   { '\374', '\0' }, /* eCH_ue */
  22.   { '\304', '\0' }, /* eCH_Ae */
  23.   { '\313', '\0' }, /* eCH_Ee */
  24.   { '\317', '\0' }, /* eCH_Ie */
  25.   { '\326', '\0' }, /* eCH_Oe */
  26.   { '\334', '\0' }, /* eCH_Ue */
  27.   { '\337', '\0' }, /* eCH_sz */
  28.   { '\262', '\0' }, /* eCH_e2 */
  29.   { '\265', '\0' }, /* eCH_mu */
  30.   { '\340', '\0' }, /* eCH_agrave */
  31.   { '\300', '\0' }, /* eCH_Agrave */
  32.   { '\350', '\0' }, /* eCH_egrave */
  33.   { '\310', '\0' }, /* eCH_Egrave */
  34.   { '\354', '\0' }, /* eCH_igrave */
  35.   { '\314', '\0' }, /* eCH_Igrave */
  36.   { '\362', '\0' }, /* eCH_ograve */
  37.   { '\322', '\0' }, /* eCH_Ograve */
  38.   { '\371', '\0' }, /* eCH_ugrave */
  39.   { '\331', '\0' }, /* eCH_Ugrave */
  40.   { '\341', '\0' }, /* eCH_aacute */
  41.   { '\301', '\0' }, /* eCH_Aacute */
  42.   { '\351', '\0' }, /* eCH_eacute */
  43.   { '\311', '\0' }, /* eCH_Eacute */
  44.   { '\355', '\0' }, /* eCH_iacute */
  45.   { '\315', '\0' }, /* eCH_Iacute */
  46.   { '\363', '\0' }, /* eCH_oacute */
  47.   { '\323', '\0' }, /* eCH_Oacute */
  48.   { '\372', '\0' }, /* eCH_uacute */
  49.   { '\332', '\0' }, /* eCH_Uacute */
  50.   { '\342', '\0' }, /* eCH_acirc */
  51.   { '\302', '\0' }, /* eCH_Acirc */
  52.   { '\352', '\0' }, /* eCH_ecirc */
  53.   { '\312', '\0' }, /* eCH_Ecirc */
  54.   { '\356', '\0' }, /* eCH_icirc */
  55.   { '\316', '\0' }, /* eCH_Icirc */
  56.   { '\364', '\0' }, /* eCH_ocirc */
  57.   { '\324', '\0' }, /* eCH_Ocirc */
  58.   { '\373', '\0' }, /* eCH_ucirc */
  59.   { '\333', '\0' }, /* eCH_Ucirc */
  60.   { '\347', '\0' }, /* eCH_ccedil */
  61.   { '\307', '\0' }, /* eCH_Ccedil */
  62.   { '\361', '\0' }, /* eCH_ntilde */
  63.   { '\321', '\0' }, /* eCH_Ntilde */
  64.   { '\345', '\0' }, /* eCH_aring */
  65.   { '\305', '\0' }, /* eCH_Aring */
  66.   { '\346', '\0' }, /* eCH_aelig */
  67.   { '\306', '\0' }, /* eCH_Aelig */
  68.   { '\370', '\0' }, /* eCH_oslash */
  69.   { '\330', '\0' }, /* eCH_Oslash */
  70.   { '\277', '\0' }, /* eCH_iquest */
  71.   { '\241', '\0' }, /* eCH_iexcl */
  72. };
  73.  
  74. static const tNLSCharacterTab Tab437 =
  75. {
  76.   { '\204', '\0' }, /* eCH_ae */
  77.   { '\211', '\0' }, /* eCH_ee */
  78.   { '\213', '\0' }, /* eCH_ie */
  79.   { '\224', '\0' }, /* eCH_oe */
  80.   { '\201', '\0' }, /* eCH_ue */
  81.   { '\216', '\0' }, /* eCH_Ae */
  82.   { 'E'   , 'e'  }, /* eCH_Ee */
  83.   { 'I'   , 'e'  }, /* eCH_Ie */
  84.   { '\231', '\0' }, /* eCH_Oe */
  85.   { '\232', '\0' }, /* eCH_Ue */
  86.   { '\341', '\0' }, /* eCH_sz */
  87.   { '\375', '\0' }, /* eCH_e2 */
  88.   { '\346', '\0' }, /* eCH_mu */
  89.   { '\205', '\0' }, /* eCH_agrave */
  90.   { '`'   , 'A'  }, /* eCH_Agrave */
  91.   { '\212', '\0' }, /* eCH_egrave */
  92.   { '`'   , 'E'  }, /* eCH_Egrave */
  93.   { '\215', '\0' }, /* eCH_igrave */
  94.   { '`'   , 'I'  }, /* eCH_Igrave */
  95.   { '\225', '\0' }, /* eCH_ograve */
  96.   { '`'   , 'O'  }, /* eCH_Ograve */
  97.   { '\227', '\0' }, /* eCH_ugrave */
  98.   { '`'   , 'U'  }, /* eCH_Ugrave */
  99.   { '\240', '\0' }, /* eCH_aacute */
  100.   { '\''  , 'A'  }, /* eCH_Aacute */
  101.   { '\202', '\0' }, /* eCH_eacute */
  102.   { '\220', '\0' }, /* eCH_Eacute */
  103.   { '\241', '\0' }, /* eCH_iacute */
  104.   { '\''  , 'I'  }, /* eCH_Iacute */
  105.   { '\242', '\0' }, /* eCH_oacute */
  106.   { '\''  , 'O'  }, /* eCH_Oacute */
  107.   { '\243', '\0' }, /* eCH_uacute */
  108.   { '\''  , 'U'  }, /* eCH_Uacute */
  109.   { '\203', '\0' }, /* eCH_acirc */
  110.   { '^'   , 'A'  }, /* eCH_Acirc */
  111.   { '\210', '\0' }, /* eCH_ecirc */
  112.   { '^'   , 'E'  }, /* eCH_Ecirc */
  113.   { '\214', '\0' }, /* eCH_icirc */
  114.   { '^'   , 'I'  }, /* eCH_Icirc */
  115.   { '\223', '\0' }, /* eCH_ocirc */
  116.   { '^'   , 'O'  }, /* eCH_Ocirc */
  117.   { '\226', '\0' }, /* eCH_ucirc */
  118.   { '^'   , 'U'  }, /* eCH_Ucirc */
  119.   { '\207', '\0' }, /* eCH_ccedil */
  120.   { '\200', '\0' }, /* eCH_Ccedil */
  121.   { '\244', '\0' }, /* eCH_ntilde */
  122.   { '\245', '\0' }, /* eCH_Ntilde */
  123.   { '\206', '\0' }, /* eCH_aring */
  124.   { '\217', '\0' }, /* eCH_Aring */
  125.   { '\221', '\0' }, /* eCH_aelig */
  126.   { '\222', '\0' }, /* eCH_Aelig */
  127.   { 'o'   , '\0' }, /* eCH_oslash */
  128.   { 'O'   , '\0' }, /* eCH_Oslash */
  129.   { '\250', '\0' }, /* eCH_iquest */
  130.   { '\255', '\0' }, /* eCH_iexcl */
  131. };
  132.  
  133. static const tNLSCharacterTab Tab850 =
  134. {
  135.   { '\204', '\0' }, /* eCH_ae */
  136.   { '\211', '\0' }, /* eCH_ee */
  137.   { '\213', '\0' }, /* eCH_ie */
  138.   { '\224', '\0' }, /* eCH_oe */
  139.   { '\201', '\0' }, /* eCH_ue */
  140.   { '\216', '\0' }, /* eCH_Ae */
  141.   { '\323', '\0' }, /* eCH_Ee */
  142.   { '\330', '\0' }, /* eCH_Ie */
  143.   { '\231', '\0' }, /* eCH_Oe */
  144.   { '\232', '\0' }, /* eCH_Ue */
  145.   { '\341', '\0' }, /* eCH_sz */
  146.   { '\375', '\0' }, /* eCH_e2 */
  147.   { '\346', '\0' }, /* eCH_mu */
  148.   { '\205', '\0' }, /* eCH_agrave */
  149.   { '\267', '\0' }, /* eCH_Agrave */
  150.   { '\212', '\0' }, /* eCH_egrave */
  151.   { '\324', '\0' }, /* eCH_Egrave */
  152.   { '\215', '\0' }, /* eCH_igrave */
  153.   { '\336', '\0' }, /* eCH_Igrave */
  154.   { '\225', '\0' }, /* eCH_ograve */
  155.   { '\343', '\0' }, /* eCH_Ograve */
  156.   { '\227', '\0' }, /* eCH_ugrave */
  157.   { '\353', '\0' }, /* eCH_Ugrave */
  158.   { '\240', '\0' }, /* eCH_aacute */
  159.   { '\265', '\0' }, /* eCH_Aacute */
  160.   { '\202', '\0' }, /* eCH_eacute */
  161.   { '\220', '\0' }, /* eCH_Eacute */
  162.   { '\241', '\0' }, /* eCH_iacute */
  163.   { '\326', '\0' }, /* eCH_Iacute */
  164.   { '\242', '\0' }, /* eCH_oacute */
  165.   { '\340', '\0' }, /* eCH_Oacute */
  166.   { '\243', '\0' }, /* eCH_uacute */
  167.   { '\351', '\0' }, /* eCH_Uacute */
  168.   { '\203', '\0' }, /* eCH_acirc */
  169.   { '\266', '\0' }, /* eCH_Acirc */
  170.   { '\210', '\0' }, /* eCH_ecirc */
  171.   { '\322', '\0' }, /* eCH_Ecirc */
  172.   { '\214', '\0' }, /* eCH_icirc */
  173.   { '\327', '\0' }, /* eCH_Icirc */
  174.   { '\223', '\0' }, /* eCH_ocirc */
  175.   { '\342', '\0' }, /* eCH_Ocirc */
  176.   { '\226', '\0' }, /* eCH_ucirc */
  177.   { '\352', '\0' }, /* eCH_Ucirc */
  178.   { '\207', '\0' }, /* eCH_ccedil */
  179.   { '\200', '\0' }, /* eCH_Ccedil */
  180.   { '\244', '\0' }, /* eCH_ntilde */
  181.   { '\245', '\0' }, /* eCH_Ntilde */
  182.   { '\206', '\0' }, /* eCH_aring */
  183.   { '\217', '\0' }, /* eCH_Aring */
  184.   { '\221', '\0' }, /* eCH_aelig */
  185.   { '\222', '\0' }, /* eCH_Aelig */
  186.   { '\233', '\0' }, /* eCH_oslash */
  187.   { '\235', '\0' }, /* eCH_Oslash */
  188.   { '\250', '\0' }, /* eCH_iquest */
  189.   { '\255', '\0' }, /* eCH_iexcl */
  190. };
  191.  
  192. static const tNLSCharacterTab TabUTF8 =
  193. {
  194.   { '\303', '\244' }, /* eCH_ae 0xe4 */
  195.   { '\303', '\253' }, /* eCH_ee 0xeb */
  196.   { '\303', '\257' }, /* eCH_ie 0xef */
  197.   { '\303', '\266' }, /* eCH_oe 0xf6 */
  198.   { '\303', '\274' }, /* eCH_ue 0xfc */
  199.   { '\303', '\204' }, /* eCH_Ae 0xc4 */
  200.   { '\303', '\213' }, /* eCH_Ee 0xcb */
  201.   { '\303', '\217' }, /* eCH_Ie 0xcf */
  202.   { '\303', '\226' }, /* eCH_Oe 0xd6 */
  203.   { '\303', '\234' }, /* eCH_Ue 0xdc */
  204.   { '\303', '\237' }, /* eCH_sz 0xdf */
  205.   { '\302', '\262' }, /* eCH_e2 0xb2 */
  206.   { '\302', '\265' }, /* eCH_mu 0xb5 */
  207.   { '\303', '\240' }, /* eCH_agrave 0xe0 */
  208.   { '\303', '\200' }, /* eCH_Agrave 0xc0 */
  209.   { '\303', '\250' }, /* eCH_egrave 0xe8 */
  210.   { '\303', '\210' }, /* eCH_Egrave 0xc8 */
  211.   { '\303', '\254' }, /* eCH_igrave 0xec */
  212.   { '\303', '\214' }, /* eCH_Igrave 0xcc */
  213.   { '\303', '\262' }, /* eCH_ograve 0xf2 */
  214.   { '\303', '\222' }, /* eCH_Ograve 0xd2 */
  215.   { '\303', '\271' }, /* eCH_ugrave 0xf9 */
  216.   { '\303', '\231' }, /* eCH_Ugrave 0xd9 */
  217.   { '\303', '\241' }, /* eCH_aacute 0xe1 */
  218.   { '\303', '\201' }, /* eCH_Aacute 0xc1 */
  219.   { '\303', '\251' }, /* eCH_eacute 0xe9 */
  220.   { '\303', '\211' }, /* eCH_Eacute 0xc9 */
  221.   { '\303', '\255' }, /* eCH_iacute 0xed */
  222.   { '\303', '\215' }, /* eCH_Iacute 0xcd */
  223.   { '\303', '\263' }, /* eCH_oacute 0xf3 */
  224.   { '\303', '\223' }, /* eCH_Oacute 0xd3 */
  225.   { '\303', '\272' }, /* eCH_uacute 0xfa */
  226.   { '\303', '\232' }, /* eCH_Uacute 0xda */
  227.   { '\303', '\242' }, /* eCH_acirc 0xe2 */
  228.   { '\303', '\202' }, /* eCH_Acirc 0xc2 */
  229.   { '\303', '\252' }, /* eCH_ecirc 0xea */
  230.   { '\303', '\212' }, /* eCH_Ecirc 0xca */
  231.   { '\303', '\256' }, /* eCH_icirc 0xee */
  232.   { '\303', '\216' }, /* eCH_Icirc 0xce */
  233.   { '\303', '\264' }, /* eCH_ocirc 0xf4 */
  234.   { '\303', '\224' }, /* eCH_Ocirc 0xd4 */
  235.   { '\303', '\273' }, /* eCH_ucirc 0xfb */
  236.   { '\303', '\233' }, /* eCH_Ucirc 0xdb */
  237.   { '\303', '\247' }, /* eCH_ccedil 0xe7 */
  238.   { '\303', '\207' }, /* eCH_Ccedil 0xc7 */
  239.   { '\303', '\261' }, /* eCH_ntilde 0xf1 */
  240.   { '\303', '\221' }, /* eCH_Ntilde 0xd1 */
  241.   { '\303', '\245' }, /* eCH_aring 0xe5 */
  242.   { '\303', '\205' }, /* eCH_Aring 0xc5 */
  243.   { '\303', '\246' }, /* eCH_aelig 0xe6 */
  244.   { '\303', '\206' }, /* eCH_Aelig 0xc6 */
  245.   { '\303', '\270' }, /* eCH_oslash 0xf8 */
  246.   { '\303', '\230' }, /* eCH_Oslash 0xd8 */
  247.   { '\302', '\277' }, /* eCH_iquest 0xbf */
  248.   { '\302', '\241' }, /* eCH_iexcl 0xa1 */
  249. };
  250.  
  251. static const tNLSCharacterTab TabASCII7 =
  252. {
  253.   { 'a', 'e'  }, /* eCH_ae */
  254.   { 'e', 'e'  }, /* eCH_ee */
  255.   { 'i', 'e'  }, /* eCH_ie */
  256.   { 'o', 'e'  }, /* eCH_oe */
  257.   { 'u', 'e'  }, /* eCH_ue */
  258.   { 'A', 'e'  }, /* eCH_Ae */
  259.   { 'E', 'e'  }, /* eCH_Ee */
  260.   { 'I', 'e'  }, /* eCH_Ie */
  261.   { 'O', 'e'  }, /* eCH_Oe */
  262.   { 'U', 'e'  }, /* eCH_Ue */
  263.   { 's', 's'  }, /* eCH_sz */
  264.   { '^', '2'  }, /* eCH_e2 */
  265.   { 'u', '\0' }, /* eCH_mu */
  266.   { '`', 'a'  }, /* eCH_agrave */
  267.   { '`', 'A'  }, /* eCH_Agrave */
  268.   { '`', 'e'  }, /* eCH_egrave */
  269.   { '`', 'E'  }, /* eCH_Egrave */
  270.   { '`', 'i'  }, /* eCH_igrave */
  271.   { '`', 'I'  }, /* eCH_Igrave */
  272.   { '`', 'o'  }, /* eCH_ograve */
  273.   { '`', 'O'  }, /* eCH_Ograve */
  274.   { '`', 'u'  }, /* eCH_ugrave */
  275.   { '`', 'U'  }, /* eCH_Ugrave */
  276.   { '\'','a'  }, /* eCH_aacute */
  277.   { '\'','A'  }, /* eCH_Aacute */
  278.   { '\'','e'  }, /* eCH_eacute */
  279.   { '\'','E'  }, /* eCH_Eacute */
  280.   { '\'','i'  }, /* eCH_iacute */
  281.   { '\'','I'  }, /* eCH_Iacute */
  282.   { '\'','o'  }, /* eCH_oacute */
  283.   { '\'','O'  }, /* eCH_Oacute */
  284.   { '\'','u'  }, /* eCH_uacute */
  285.   { '\'','U'  }, /* eCH_Uacute */
  286.   { '^', 'a'  }, /* eCH_acirc */
  287.   { '^', 'A'  }, /* eCH_Acirc */
  288.   { '^', 'e'  }, /* eCH_ecirc */
  289.   { '^', 'E'  }, /* eCH_Ecirc */
  290.   { '^', 'i'  }, /* eCH_icirc */
  291.   { '^', 'I'  }, /* eCH_Icirc */
  292.   { '^', 'o'  }, /* eCH_ocirc */
  293.   { '^', 'O'  }, /* eCH_Ocirc */
  294.   { '^', 'u'  }, /* eCH_ucirc */
  295.   { '^', 'U'  }, /* eCH_Ucirc */
  296.   { 'c', '\0' }, /* eCH_ccedil */
  297.   { 'C', '\0' }, /* eCH_Ccedil */
  298.   { '~', 'n'  }, /* eCH_ntilde */
  299.   { '~', 'N'  }, /* eCH_Ntilde */
  300.   { 'a', '\0' }, /* eCH_aring */
  301.   { 'A', '\0' }, /* eCH_Aring */
  302.   { 'a', 'e'  }, /* eCH_aelig */
  303.   { 'A', 'E'  }, /* eCH_Aelig */
  304.   { 'o', '\0' }, /* eCH_oslash */
  305.   { 'O', '\0' }, /* eCH_Oslash */
  306.   { '?', '\0' }, /* eCH_iquest */
  307.   { '!', '\0' }, /* eCH_iexcl */
  308. };
  309.  
  310. const char NLS_HtmlCharacterTab[eCH_cnt][9] =
  311. {
  312.   "&auml;"  , /* eCH_ae     */
  313.   "&euml;"  , /* eCH_ee     */
  314.   "&iuml;"  , /* eCH_ie     */
  315.   "&ouml;"  , /* eCH_oe     */
  316.   "&uuml;"  , /* eCH_ue     */
  317.   "&Auml;"  , /* eCH_Ae     */
  318.   "&Euml;"  , /* eCH_Ee     */
  319.   "&Iuml;"  , /* eCH_Ie     */
  320.   "&Ouml;"  , /* eCH_Oe     */
  321.   "&Uuml;"  , /* eCH_Ue     */
  322.   "&szlig;" , /* eCH_sz     */
  323.   "&sup2;"  , /* eCH_e2     */
  324.   "&micro;" , /* eCH_mu     */
  325.   "&agrave;", /* eCH_agrave */
  326.   "&Agrave;", /* eCH_Agrave */
  327.   "&egrave;", /* eCH_egrave */
  328.   "&Egrave;", /* eCH_Egrave */
  329.   "&igrave;", /* eCH_igrave */
  330.   "&Igrave;", /* eCH_Igrave */
  331.   "&ograve;", /* eCH_ograve */
  332.   "&Ograve;", /* eCH_Ograve */
  333.   "&ugrave;", /* eCH_ugrave */
  334.   "&Ugrave;", /* eCH_Ugrave */
  335.   "&aacute;", /* eCH_aacute */
  336.   "&Aacute;", /* eCH_Aacute */
  337.   "&eacute;", /* eCH_eacute */
  338.   "&Eacute;", /* eCH_Eacute */
  339.   "&iacute;", /* eCH_iacute */
  340.   "&Iacute;", /* eCH_Iacute */
  341.   "&oacute;", /* eCH_oacute */
  342.   "&Oacute;", /* eCH_Oacute */
  343.   "&uacute;", /* eCH_uacute */
  344.   "&Uacute;", /* eCH_Uacute */
  345.   "&acirc;" , /* eCH_acirc  */
  346.   "&Acirc;" , /* eCH_Acirc  */
  347.   "&ecirc;" , /* eCH_ecirc  */
  348.   "&Ecirc;" , /* eCH_Ecirc  */
  349.   "&icirc;" , /* eCH_icirc  */
  350.   "&Icirc;" , /* eCH_Icirc  */
  351.   "&ocirc;" , /* eCH_ocirc  */
  352.   "&Ocirc;" , /* eCH_Ocirc  */
  353.   "&ucirc;" , /* eCH_ucirc  */
  354.   "&Ucirc;" , /* eCH_Ucirc  */
  355.   "&ccedil;", /* eCH_ccedil */
  356.   "&Ccedil;", /* eCH_Ccedil */
  357.   "&ntilde;", /* eCH_ntilde */
  358.   "&Ntilde;", /* eCH_Ntilde */
  359.   "&aring;" , /* eCH_aring  */
  360.   "&Aring;" , /* eCH_Aring  */
  361.   "&aelig;" , /* eCH_aelig  */
  362.   "&Aelig;" , /* eCH_Aelig  */
  363.   "&oslash" , /* eCH_oslash */
  364.   "&Oslash" , /* eCH_Oslash */
  365.   "&iquest;", /* eCH_iquest */
  366.   "&iexcl;" , /* eCH_iexcl  */
  367. };
  368.  
  369. /*!------------------------------------------------------------------------
  370.  * \fn     tNLSCharacterTab *GetCharacterTab(tCodepage Codepage)
  371.  * \brief  retrieve character encoding for given code page
  372.  * \param  Codepage code page to query
  373.  * \return * to character list
  374.  * ------------------------------------------------------------------------ */
  375.  
  376. const tNLSCharacterTab *GetCharacterTab(tCodepage Codepage)
  377. {
  378.   switch (Codepage)
  379.   {
  380.     case eCodepageISO8859_1:
  381.     case eCodepageISO8859_15:
  382.     case eCodepage1252:
  383.       return &Tab8859_1;
  384.     case eCodepage437:
  385.       return &Tab437;
  386.     case eCodepage850:
  387.       return &Tab850;
  388.     case eCodepageUTF8:
  389.       return &TabUTF8;
  390.     default:
  391.       return &TabASCII7;
  392.   }
  393. }
  394.  
  395. /*!------------------------------------------------------------------------
  396.  * \fn     CharTab_GetLength(const tNLSCharacterTab *pTab, tNLSCharacter Character)
  397.  * \brief  retrive length of of character string from table
  398.  * \param  pTab table to use
  399.  * \param  Character character to extract
  400.  * \return length of character string
  401.  * ------------------------------------------------------------------------ */
  402.  
  403. int CharTab_GetLength(const tNLSCharacterTab *pTab, tNLSCharacter Character)
  404. {
  405.   if (!(*pTab)[Character][0])
  406.     return 0;
  407.   else if (!(*pTab)[Character][1])
  408.     return 1;
  409.   else
  410.     return 2;
  411. }
  412.  
  413. /*!------------------------------------------------------------------------
  414.  * \fn     CharTab_GetNULTermString(const tNLSCharacterTab *pTab, tNLSCharacter Character, char *pBuffer)
  415.  * \brief  Provide NUL-terminated version of character string from table
  416.  * \param  pTab table to use
  417.  * \param  Character character to extract
  418.  * \param  pBuffer temp buffer to built NUL-terminated version
  419.  * \return * to NUL-termainted version
  420.  * ------------------------------------------------------------------------ */
  421.  
  422. const char *CharTab_GetNULTermString(const tNLSCharacterTab *pTab, tNLSCharacter Character, char *pBuffer)
  423. {
  424.   if ((*pTab)[Character][1] == '\0')
  425.     return (*pTab)[Character];
  426.   else
  427.   {
  428.     memcpy(pBuffer, (*pTab)[Character], 2);
  429.     pBuffer[2] = '\0';
  430.     return pBuffer;
  431.   }
  432. }
  433.  
  434. /*!------------------------------------------------------------------------
  435.  * \fn     UTF8ToUnicode(const char* *ppChr)
  436.  * \brief  convert UTF-8 encoded char to Unicode
  437.  * \param  ppChr * to character (points afterwards to next character)
  438.  * \return Unicode value
  439.  * ------------------------------------------------------------------------ */
  440.  
  441. static int CheckOneUTF8(unsigned char Val, unsigned char Mask, LongWord *pPart)
  442. {
  443.   if ((Val & Mask) == ((Mask << 1) & 0xff))
  444.   {
  445.     *pPart = (Val & ~Mask) & 0xff;
  446.     return 1;
  447.   }
  448.   else
  449.     return 0;
  450. }
  451.  
  452. LongWord UTF8ToUnicode(const char* *ppChr)
  453. {
  454.   LongWord Part1, Part2, Part3, Part4;
  455.  
  456.   if (CheckOneUTF8((*ppChr)[0], 0x80, &Part1))
  457.   {
  458.     (*ppChr)++;
  459.     return Part1;
  460.   }
  461.   else if (CheckOneUTF8((*ppChr)[0], 0xe0, &Part1)
  462.         && CheckOneUTF8((*ppChr)[1], 0xc0, &Part2))
  463.   {
  464.     (*ppChr) += 2;
  465.     return (Part1 << 6) | Part2;
  466.   }
  467.   else if (CheckOneUTF8((*ppChr)[0], 0xf0, &Part1)
  468.         && CheckOneUTF8((*ppChr)[1], 0xc0, &Part2)
  469.         && CheckOneUTF8((*ppChr)[2], 0xc0, &Part3))
  470.   {
  471.     (*ppChr) +=3;
  472.     return (Part1 << 12) | (Part2 << 6) | Part3;
  473.   }
  474.   else if (CheckOneUTF8((*ppChr)[0], 0xf8, &Part1)
  475.         && CheckOneUTF8((*ppChr)[1], 0xc0, &Part2)
  476.         && CheckOneUTF8((*ppChr)[2], 0xc0, &Part3)
  477.         && CheckOneUTF8((*ppChr)[3], 0xc0, &Part4))
  478.   {
  479.     (*ppChr) +=3;
  480.     return (Part1 << 18) | (Part2 << 12) | (Part3 << 6) | Part4;
  481.   }
  482.   else
  483.     return (unsigned char) *((*ppChr)++);
  484. }
  485.  
  486. /*!------------------------------------------------------------------------
  487.  * \fn     UnicodeToUTF8(char* *ppChr, LongWord Unicode)
  488.  * \brief  convert UTF-8 encoded char to Unicode
  489.  * \param  ppChr * to destination (points afterwards to next character)
  490.  * \param  Unicode Unicode value
  491.  * ------------------------------------------------------------------------ */
  492.  
  493. void UnicodeToUTF8(char* *ppChr, LongWord Unicode)
  494. {
  495.   if (Unicode <= 0x7f)
  496.     *(*ppChr)++ = Unicode;
  497.   else if (Unicode <= 0x7ff)
  498.   {
  499.     *(*ppChr)++ = 0xc0 | ((Unicode >> 6) & 0x1f);
  500.     *(*ppChr)++ = 0x80 | ((Unicode >> 0) & 0x3f);
  501.   }
  502.   else if (Unicode <= 0xffff)
  503.   {
  504.     *(*ppChr)++ = 0xc0 | ((Unicode >> 12) & 0x1f);
  505.     *(*ppChr)++ = 0x80 | ((Unicode >> 6) & 0x3f);
  506.     *(*ppChr)++ = 0x80 | ((Unicode >> 0) & 0x3f);
  507.   }
  508.   else if (Unicode <= 0x10fffful)
  509.   {
  510.     *(*ppChr)++ = 0xc0 | ((Unicode >> 18) & 0x1f);
  511.     *(*ppChr)++ = 0x80 | ((Unicode >> 12) & 0x3f);
  512.     *(*ppChr)++ = 0x80 | ((Unicode >> 6) & 0x3f);
  513.     *(*ppChr)++ = 0x80 | ((Unicode >> 0) & 0x3f);
  514.   }
  515. }
  516.  
  517. /*!------------------------------------------------------------------------
  518.  * \fn     as_wcwidth(unsigned codepoint)
  519.  * \brief  return display width of Unicode code point
  520.  * \param  codepoint code point
  521.  * \return width on display (0...)
  522.  * ------------------------------------------------------------------------ */
  523.  
  524. unsigned as_wcwidth(unsigned codepoint)
  525. {
  526.   if (((codepoint >= 0x1100) && (codepoint <= 0x115F)) /* HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER */
  527.    || ((codepoint >= 0x231A) && (codepoint <= 0x231B)) /* WATCH..HOURGLASS */
  528.    || ((codepoint >= 0x2329) && (codepoint <= 0x232A)) /* LEFT/RIGHT-POINTING ANGLE BRACKET */
  529.    || ((codepoint >= 0x23E9) && (codepoint <= 0x23EC)) /* BLACK RIGHT-POINTING DOUBLE TRIANGLE..BLACK DOWN-POINTING DOUBLE TRIANGLE */
  530.    || (codepoint == 0x23F0)                            /* ALARM CLOCK */
  531.    || (codepoint == 0x23F3)                            /* HOURGLASS WITH FLOWING SAND */
  532.    || ((codepoint >= 0x25FD) && (codepoint <= 0x25FE)) /* WHITE MEDIUM SMALL SQUARE..BLACK MEDIUM SMALL SQUARE */
  533.    || ((codepoint >= 0x2614) && (codepoint <= 0x2615)) /* UMBRELLA WITH RAIN DROPS..HOT BEVERAGE */
  534.    || ((codepoint >= 0x2648) && (codepoint <= 0x2653)) /* ARIES..PISCES */
  535.    || (codepoint == 0x267F)                            /* WHEELCHAIR SYMBOL */
  536.    || (codepoint == 0x2693)                            /* ANCHOR */
  537.    || (codepoint == 0x26A1)                            /* HIGH VOLTAGE SIGN */
  538.    || (codepoint == 0x26CE)                            /* OPHIUCHUS */
  539.    || (codepoint == 0x26D4)                            /* NO ENTRY */
  540.    || (codepoint == 0x26EA)                            /* CHURCH */
  541.    || ((codepoint >= 0x26F2) && (codepoint <= 0x26F3)) /* FOUNTAIN..FLAG IN HOLE */
  542.    || (codepoint == 0x26F5)                            /* SAILBOAT */
  543.    || (codepoint == 0x26FA)                            /* TENT */
  544.    || (codepoint == 0x26FD)                            /* FUEL PUMP */
  545.    || (codepoint == 0x2705)                            /* WHITE HEAVY CHECK MARK */
  546.    || (codepoint == 0x2728)                            /* SPARKLES */
  547.    || (codepoint == 0x274C)                            /* CROSS MARK */
  548.    || ((codepoint >= 0x2753) && (codepoint <= 0x2755)) /* BLACK QUESTION MARK ORNAMENT..WHITE EXCLAMATION MARK ORNAMENT */
  549.    || (codepoint == 0x2757)                            /* HEAVY EXCLAMATION MARK SYMBOL */
  550.    || ((codepoint >= 0x2795) && (codepoint <= 0x2797)) /* HEAVY PLUS SIGN..HEAVY DIVISION SIGN */
  551.    || (codepoint == 0x27B0)                            /* CURLY LOOP */
  552.    || (codepoint == 0x27BF)                            /* DOUBLE CURLY LOOP */
  553.    || ((codepoint >= 0x2B1B) && (codepoint <= 0x2B1C)) /* BLACK LARGE SQUARE..WHITE LARGE SQUARE */
  554.    || (codepoint == 0x2B50)                            /* WHITE MEDIUM STAR */
  555.    || (codepoint == 0x2B55)                            /* HEAVY LARGE CIRCLE */
  556.    || ((codepoint >= 0x2E80) && (codepoint <= 0x2FFB)) /* CJK RADICAL REPEAT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID */
  557.    || ((codepoint >= 0x3004) && (codepoint <= 0x303E)) /* JAPANESE INDUSTRIAL STANDARD SYMBOL..IDEOGRAPHIC VARIATION INDICATOR */
  558.    || ((codepoint >= 0x3041) && (codepoint <= 0x3247)) /* HIRAGANA LETTER SMALL A..CIRCLED NUMBER EIGHTY ON BLACK SQUARE */
  559.    || ((codepoint >= 0x3250) && (codepoint <= 0x4DBF)) /* PARTNERSHIP SIGN..<reserved-4DBF> */
  560.    || ((codepoint >= 0x4E00) && (codepoint <= 0xA4C6)) /* CJK UNIFIED IDEOGRAPH-4E00..YI RADICAL KE */
  561.    || ((codepoint >= 0xA960) && (codepoint <= 0xA97C)) /* HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH */
  562.    || ((codepoint >= 0xAC00) && (codepoint <= 0xD7A3)) /* HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH */
  563.    || ((codepoint >= 0xF900) && (codepoint <= 0xFAFF)) /* CJK COMPATIBILITY IDEOGRAPH-F900..<reserved-FAFF> */
  564.    || ((codepoint >= 0xFE10) && (codepoint <= 0xFE19)) /* PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS */
  565.    || ((codepoint >= 0xFE31) && (codepoint <= 0xFE6B)) /* PRESENTATION FORM FOR VERTICAL EM DASH..SMALL COMMERCIAL AT */
  566.   )
  567.     return 2;
  568.   else
  569.     return 1;
  570. }
  571.