i18n.c (3529B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2020, 2021 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file json/i18n.c 18 * @brief helper functions for i18n in JSON processing 19 * @author Christian Grothoff 20 */ 21 #include "platform.h" /* UNNECESSARY? */ 22 #include <gnunet/gnunet_util_lib.h> 23 #include "taler/taler_util.h" 24 #include "taler/taler_json_lib.h" 25 26 27 const json_t * 28 TALER_JSON_extract_i18n (const json_t *object, 29 const char *language_pattern, 30 const char *field) 31 { 32 const json_t *ret; 33 json_t *i18n; 34 double quality = 0.0; 35 36 ret = json_object_get (object, 37 field); 38 if (NULL == ret) 39 return NULL; /* field MUST exist in object */ 40 { 41 char *name; 42 43 GNUNET_asprintf (&name, 44 "%s_i18n", 45 field); 46 i18n = json_object_get (object, 47 name); 48 GNUNET_free (name); 49 } 50 if (NULL == i18n) 51 return ret; 52 { 53 const char *key; 54 json_t *value; 55 56 json_object_foreach (i18n, key, value) { 57 double q = TALER_pattern_matches (language_pattern, 58 key); 59 if (q > quality) 60 { 61 quality = q; 62 ret = value; 63 } 64 } 65 } 66 return ret; 67 } 68 69 70 /** 71 * Check that @a tag is a valid language tag. Accepted are a 72 * two- or three-letter language code (ISO 639-1, 639-2 or 639-3), 73 * optionally followed by '_' or '-' and a two-letter country code 74 * (ISO 3166-1 alpha-2) or a three-digit region code (UN M.49). 75 * We do not care about capitalization. For the syntax, see the 76 * GNU Gettext manual, including appendix A for rare language 77 * codes. 78 * 79 * @param tag language tag to check 80 * @return true if @a tag is well-formed 81 */ 82 static bool 83 check_language_tag (const char *tag) 84 { 85 size_t len = strlen (tag); 86 size_t off = 0; 87 88 while ( (off < len) && 89 (0 != isalpha ((unsigned char) tag[off])) ) 90 off++; 91 if ( (off < 2) || 92 (off > 3) ) 93 return false; /* language code must have 2 or 3 letters */ 94 if (off == len) 95 return true; /* language code without country code */ 96 if ( ('_' != tag[off]) && 97 ('-' != tag[off]) ) 98 return false; 99 off++; 100 if (2 == len - off) 101 { 102 return ( (0 != isalpha ((unsigned char) tag[off])) && 103 (0 != isalpha ((unsigned char) tag[off + 1])) ); 104 } 105 if (3 == len - off) 106 { 107 return ( (0 != isdigit ((unsigned char) tag[off])) && 108 (0 != isdigit ((unsigned char) tag[off + 1])) && 109 (0 != isdigit ((unsigned char) tag[off + 2])) ); 110 } 111 return false; 112 } 113 114 115 bool 116 TALER_JSON_check_i18n (const json_t *i18n) 117 { 118 const char *field; 119 json_t *member; 120 121 if (! json_is_object (i18n)) 122 return false; 123 json_object_foreach ((json_t *) i18n, field, member) 124 { 125 if (! json_is_string (member)) 126 return false; 127 if (! check_language_tag (field)) 128 return false; 129 } 130 return true; 131 } 132 133 134 /* end of i18n.c */