1 /* Format strings. 2 Copyright (C) 2001-2010, 2012-2013, 2015, 2019-2020 Free Software Foundation, Inc. 3 Written by Bruno Haible <haible@clisp.cons.org>, 2001. 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 17 18 #ifndef _FORMAT_H 19 #define _FORMAT_H 20 21 #include <stdbool.h> 22 23 #include "pos.h" /* Get lex_pos_ty. */ 24 #include "message.h" /* Get NFORMATS. */ 25 #include "plural-distrib.h" /* Get struct plural_distribution. */ 26 #include "error.h" /* Get fallback definition of __attribute__. */ 27 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 34 /* These indicators are set by the parse function at the appropriate 35 positions. */ 36 enum 37 { 38 /* Set on the first byte of a format directive. */ 39 FMTDIR_START = 1 << 0, 40 /* Set on the last byte of a format directive. */ 41 FMTDIR_END = 1 << 1, 42 /* Set on the last byte of an invalid format directive, where a parse error 43 was recognized. */ 44 FMTDIR_ERROR = 1 << 2 45 }; 46 47 /* Macro for use inside a parser: 48 Sets an indicator at the position corresponding to PTR. 49 Assumes local variables 'fdi' and 'format_start' are defined. */ 50 #define FDI_SET(ptr, flag) \ 51 if (fdi != NULL) \ 52 fdi[(ptr) - format_start] |= (flag)/*;*/ 53 54 /* This type of callback is responsible for showing an error. */ 55 typedef void (*formatstring_error_logger_t) (const char *format, ...) 56 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) 57 __attribute__ ((__format__ (__printf__, 1, 2))) 58 #endif 59 ; 60 61 /* This structure describes a format string parser for a language. */ 62 struct formatstring_parser 63 { 64 /* Parse the given string as a format string. 65 If translated is true, some extensions available only to msgstr but not 66 to msgid strings are recognized. 67 If fdi is non-NULL, it must be a an array of strlen (string) zero bytes. 68 Return a freshly allocated structure describing 69 1. the argument types/names needed for the format string, 70 2. the total number of format directives. 71 Return NULL if the string is not a valid format string. In this case, 72 also set *invalid_reason to an error message explaining why. 73 In both cases, set FMTDIR_* bits at the appropriate positions in fdi. */ 74 void * (*parse) (const char *string, bool translated, char *fdi, char **invalid_reason); 75 76 /* Free a format string descriptor, returned by parse(). */ 77 void (*free) (void *descr); 78 79 /* Return the number of format directives. 80 A string that can be output literally has 0 format directives. */ 81 int (*get_number_of_directives) (void *descr); 82 83 /* Return true if the format string, although valid, contains directives that 84 make it appear unlikely that the string was meant as a format string. 85 A NULL function is equivalent to a function that always returns false. */ 86 bool (*is_unlikely_intentional) (void *descr); 87 88 /* Verify that the argument types/names in msgid_descr and those in 89 msgstr_descr are the same (if equality=true), or (if equality=false) 90 that those of msgid_descr extend those of msgstr_descr (i.e. 91 msgstr_descr may omit some of the arguments of msgid_descr). 92 If not, signal an error using error_logger (only if error_logger != NULL) 93 and return true. Otherwise return false. */ 94 bool (*check) (void *msgid_descr, void *msgstr_descr, bool equality, formatstring_error_logger_t error_logger, const char *pretty_msgid, const char *pretty_msgstr); 95 }; 96 97 /* Format string parsers, each defined in its own file. */ 98 extern DLL_VARIABLE struct formatstring_parser formatstring_c; 99 extern DLL_VARIABLE struct formatstring_parser formatstring_objc; 100 extern DLL_VARIABLE struct formatstring_parser formatstring_python; 101 extern DLL_VARIABLE struct formatstring_parser formatstring_python_brace; 102 extern DLL_VARIABLE struct formatstring_parser formatstring_java; 103 extern DLL_VARIABLE struct formatstring_parser formatstring_java_printf; 104 extern DLL_VARIABLE struct formatstring_parser formatstring_csharp; 105 extern DLL_VARIABLE struct formatstring_parser formatstring_javascript; 106 extern DLL_VARIABLE struct formatstring_parser formatstring_scheme; 107 extern DLL_VARIABLE struct formatstring_parser formatstring_lisp; 108 extern DLL_VARIABLE struct formatstring_parser formatstring_elisp; 109 extern DLL_VARIABLE struct formatstring_parser formatstring_librep; 110 extern DLL_VARIABLE struct formatstring_parser formatstring_ruby; 111 extern DLL_VARIABLE struct formatstring_parser formatstring_sh; 112 extern DLL_VARIABLE struct formatstring_parser formatstring_awk; 113 extern DLL_VARIABLE struct formatstring_parser formatstring_lua; 114 extern DLL_VARIABLE struct formatstring_parser formatstring_pascal; 115 extern DLL_VARIABLE struct formatstring_parser formatstring_smalltalk; 116 extern DLL_VARIABLE struct formatstring_parser formatstring_qt; 117 extern DLL_VARIABLE struct formatstring_parser formatstring_qt_plural; 118 extern DLL_VARIABLE struct formatstring_parser formatstring_kde; 119 extern DLL_VARIABLE struct formatstring_parser formatstring_kde_kuit; 120 extern DLL_VARIABLE struct formatstring_parser formatstring_boost; 121 extern DLL_VARIABLE struct formatstring_parser formatstring_tcl; 122 extern DLL_VARIABLE struct formatstring_parser formatstring_perl; 123 extern DLL_VARIABLE struct formatstring_parser formatstring_perl_brace; 124 extern DLL_VARIABLE struct formatstring_parser formatstring_php; 125 extern DLL_VARIABLE struct formatstring_parser formatstring_gcc_internal; 126 extern DLL_VARIABLE struct formatstring_parser formatstring_gfc_internal; 127 extern DLL_VARIABLE struct formatstring_parser formatstring_ycp; 128 129 /* Table of all format string parsers. */ 130 extern DLL_VARIABLE struct formatstring_parser *formatstring_parsers[NFORMATS]; 131 132 /* Returns an array of the ISO C 99 <inttypes.h> format directives and other 133 format flags or directives with a system dependent expansion contained in 134 the argument string. *intervalsp is assigned to a freshly allocated array 135 of intervals (startpos pointing to '<', endpos to the character after '>'), 136 and *lengthp is assigned to the number of intervals in this array. */ 137 struct interval 138 { 139 size_t startpos; 140 size_t endpos; 141 }; 142 extern void 143 get_sysdep_c_format_directives (const char *string, bool translated, 144 struct interval **intervalsp, size_t *lengthp); 145 146 /* Returns the number of unnamed arguments consumed by a Python format 147 string. */ 148 extern unsigned int get_python_format_unnamed_arg_count (const char *string); 149 150 /* Check whether both formats strings contain compatible format 151 specifications for format type i (0 <= i < NFORMATS). 152 Return the number of errors that were seen. */ 153 extern int 154 check_msgid_msgstr_format_i (const char *msgid, const char *msgid_plural, 155 const char *msgstr, size_t msgstr_len, 156 size_t i, 157 struct argument_range range, 158 const struct plural_distribution *distribution, 159 formatstring_error_logger_t error_logger); 160 161 /* Check whether both formats strings contain compatible format 162 specifications. 163 Return the number of errors that were seen. */ 164 extern int 165 check_msgid_msgstr_format (const char *msgid, const char *msgid_plural, 166 const char *msgstr, size_t msgstr_len, 167 const enum is_format is_format[NFORMATS], 168 struct argument_range range, 169 const struct plural_distribution *distribution, 170 formatstring_error_logger_t error_logger); 171 172 173 #ifdef __cplusplus 174 } 175 #endif 176 177 178 #endif /* _FORMAT_H */ 179