1/* Format strings. 2 Copyright (C) 2001-2007 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 <http://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 "error.h" /* Get fallback definition of __attribute__. */ 26 27 28#ifdef __cplusplus 29extern "C" { 30#endif 31 32 33/* These indicators are set by the parse function at the appropriate 34 positions. */ 35enum 36{ 37 /* Set on the first byte of a format directive. */ 38 FMTDIR_START = 1 << 0, 39 /* Set on the last byte of a format directive. */ 40 FMTDIR_END = 1 << 1, 41 /* Set on the last byte of an invalid format directive, where a parse error 42 was recognized. */ 43 FMTDIR_ERROR = 1 << 2 44}; 45 46/* Macro for use inside a parser: 47 Sets an indicator at the position corresponding to PTR. 48 Assumes local variables 'fdi' and 'format_start' are defined. */ 49#define FDI_SET(ptr, flag) \ 50 if (fdi != NULL) \ 51 fdi[(ptr) - format_start] |= (flag)/*;*/ 52 53/* This type of callback is responsible for showing an error. */ 54typedef void (*formatstring_error_logger_t) (const char *format, ...) 55#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) 56 __attribute__ ((__format__ (__printf__, 1, 2))) 57#endif 58; 59 60/* This structure describes a format string parser for a language. */ 61struct formatstring_parser 62{ 63 /* Parse the given string as a format string. 64 If translated is true, some extensions available only to msgstr but not 65 to msgid strings are recognized. 66 If fdi is non-NULL, it must be a an array of strlen (string) zero bytes. 67 Return a freshly allocated structure describing 68 1. the argument types/names needed for the format string, 69 2. the total number of format directives. 70 Return NULL if the string is not a valid format string. In this case, 71 also set *invalid_reason to an error message explaining why. 72 In both cases, set FMTDIR_* bits at the appropriate positions in fdi. */ 73 void * (*parse) (const char *string, bool translated, char *fdi, char **invalid_reason); 74 75 /* Free a format string descriptor, returned by parse(). */ 76 void (*free) (void *descr); 77 78 /* Return the number of format directives. 79 A string that can be output literally has 0 format directives. */ 80 int (*get_number_of_directives) (void *descr); 81 82 /* Return true if the format string, although valid, contains directives that 83 make it appear unlikely that the string was meant as a format string. 84 A NULL function is equivalent to a function that always returns false. */ 85 bool (*is_unlikely_intentional) (void *descr); 86 87 /* Verify that the argument types/names in msgid_descr and those in 88 msgstr_descr are the same (if equality=true), or (if equality=false) 89 that those of msgid_descr extend those of msgstr_descr (i.e. 90 msgstr_descr may omit some of the arguments of msgid_descr). 91 If not, signal an error using error_logger (only if error_logger != NULL) 92 and return true. Otherwise return false. */ 93 bool (*check) (void *msgid_descr, void *msgstr_descr, bool equality, formatstring_error_logger_t error_logger, const char *pretty_msgstr); 94}; 95 96/* Format string parsers, each defined in its own file. */ 97extern DLL_VARIABLE struct formatstring_parser formatstring_c; 98extern DLL_VARIABLE struct formatstring_parser formatstring_objc; 99extern DLL_VARIABLE struct formatstring_parser formatstring_sh; 100extern DLL_VARIABLE struct formatstring_parser formatstring_python; 101extern DLL_VARIABLE struct formatstring_parser formatstring_lisp; 102extern DLL_VARIABLE struct formatstring_parser formatstring_elisp; 103extern DLL_VARIABLE struct formatstring_parser formatstring_librep; 104extern DLL_VARIABLE struct formatstring_parser formatstring_scheme; 105extern DLL_VARIABLE struct formatstring_parser formatstring_smalltalk; 106extern DLL_VARIABLE struct formatstring_parser formatstring_java; 107extern DLL_VARIABLE struct formatstring_parser formatstring_csharp; 108extern DLL_VARIABLE struct formatstring_parser formatstring_awk; 109extern DLL_VARIABLE struct formatstring_parser formatstring_pascal; 110extern DLL_VARIABLE struct formatstring_parser formatstring_ycp; 111extern DLL_VARIABLE struct formatstring_parser formatstring_tcl; 112extern DLL_VARIABLE struct formatstring_parser formatstring_perl; 113extern DLL_VARIABLE struct formatstring_parser formatstring_perl_brace; 114extern DLL_VARIABLE struct formatstring_parser formatstring_php; 115extern DLL_VARIABLE struct formatstring_parser formatstring_gcc_internal; 116extern DLL_VARIABLE struct formatstring_parser formatstring_qt; 117extern DLL_VARIABLE struct formatstring_parser formatstring_kde; 118extern DLL_VARIABLE struct formatstring_parser formatstring_boost; 119 120/* Table of all format string parsers. */ 121extern DLL_VARIABLE struct formatstring_parser *formatstring_parsers[NFORMATS]; 122 123/* Returns an array of the ISO C 99 <inttypes.h> format directives and other 124 format flags or directives with a system dependent expansion contained in 125 the argument string. *intervalsp is assigned to a freshly allocated array 126 of intervals (startpos pointing to '<', endpos to the character after '>'), 127 and *lengthp is assigned to the number of intervals in this array. */ 128struct interval 129{ 130 size_t startpos; 131 size_t endpos; 132}; 133extern void 134 get_sysdep_c_format_directives (const char *string, bool translated, 135 struct interval **intervalsp, size_t *lengthp); 136 137/* Returns the number of unnamed arguments consumed by a Python format 138 string. */ 139extern unsigned int get_python_format_unnamed_arg_count (const char *string); 140 141/* Check whether both formats strings contain compatible format 142 specifications for format type i (0 <= i < NFORMATS). 143 PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements, 144 PLURAL_DISTRIBUTION[j] being true if the value j appears to be assumed 145 infinitely often by the plural formula. 146 Return the number of errors that were seen. */ 147extern int 148 check_msgid_msgstr_format_i (const char *msgid, const char *msgid_plural, 149 const char *msgstr, size_t msgstr_len, 150 size_t i, 151 const unsigned char *plural_distribution, 152 unsigned long plural_distribution_length, 153 formatstring_error_logger_t error_logger); 154 155/* Check whether both formats strings contain compatible format 156 specifications. 157 PLURAL_DISTRIBUTION is either NULL or an array of nplurals elements, 158 PLURAL_DISTRIBUTION[j] being true if the value j appears to be assumed 159 infinitely often by the plural formula. 160 PLURAL_DISTRIBUTION_LENGTH is the length of the PLURAL_DISTRIBUTION array. 161 Return the number of errors that were seen. */ 162extern int 163 check_msgid_msgstr_format (const char *msgid, const char *msgid_plural, 164 const char *msgstr, size_t msgstr_len, 165 const enum is_format is_format[NFORMATS], 166 const unsigned char *plural_distribution, 167 unsigned long plural_distribution_length, 168 formatstring_error_logger_t error_logger); 169 170 171#ifdef __cplusplus 172} 173#endif 174 175 176#endif /* _FORMAT_H */ 177