1 /* Reading PO files, abstract class. 2 Copyright (C) 1995-1996, 1998, 2000-2003, 2005-2006, 2008-2009, 2012, 3 2015 Free Software Foundation, Inc. 4 5 This file was written by Peter Miller <millerp@canb.auug.org.au> 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 19 20 #ifndef _READ_CATALOG_ABSTRACT_H 21 #define _READ_CATALOG_ABSTRACT_H 22 23 #include "po-lex.h" 24 #include "message.h" 25 26 #include <stdbool.h> 27 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 34 /* Note: the _t suffix is reserved by ANSI C, so the _ty suffix is 35 used to indicate a type name. */ 36 37 /* The following pair of structures cooperate to create an "Object" in 38 the OO sense. We are simply doing it manually, rather than with the 39 help of an OO compiler. This implementation allows polymorphism 40 and inheritance - more than enough for the immediate needs. */ 41 42 /* Forward declaration. */ 43 struct abstract_catalog_reader_ty; 44 45 46 /* This first structure, playing the role of the "Class" in OO sense, 47 contains pointers to functions. Each function is a method for the 48 class (base or derived). Use a NULL pointer where no action is 49 required. */ 50 51 typedef struct abstract_catalog_reader_class_ty 52 abstract_catalog_reader_class_ty; 53 struct abstract_catalog_reader_class_ty 54 { 55 /* how many bytes to malloc for an instance of this class */ 56 size_t size; 57 58 /* what to do immediately after the instance is malloc()ed */ 59 void (*constructor) (struct abstract_catalog_reader_ty *pop); 60 61 /* what to do immediately before the instance is free()ed */ 62 void (*destructor) (struct abstract_catalog_reader_ty *pop); 63 64 /* This method is invoked before the parse, but after the file is 65 opened by the lexer. */ 66 void (*parse_brief) (struct abstract_catalog_reader_ty *pop); 67 68 /* This method is invoked after the parse, but before the file is 69 closed by the lexer. The intention is to make consistency checks 70 against the file here, and emit the errors through the lex_error* 71 functions. */ 72 void (*parse_debrief) (struct abstract_catalog_reader_ty *pop); 73 74 /* what to do with a domain directive */ 75 void (*directive_domain) (struct abstract_catalog_reader_ty *pop, char *name); 76 77 /* what to do with a message directive */ 78 void (*directive_message) (struct abstract_catalog_reader_ty *pop, 79 char *msgctxt, 80 char *msgid, lex_pos_ty *msgid_pos, 81 char *msgid_plural, 82 char *msgstr, size_t msgstr_len, 83 lex_pos_ty *msgstr_pos, 84 char *prev_msgctxt, 85 char *prev_msgid, char *prev_msgid_plural, 86 bool force_fuzzy, bool obsolete); 87 88 /* What to do with a plain-vanilla comment - the expectation is that 89 they will be accumulated, and added to the next message 90 definition seen. Or completely ignored. */ 91 void (*comment) (struct abstract_catalog_reader_ty *pop, const char *s); 92 93 /* What to do with a comment that starts with a dot (i.e. extracted 94 by xgettext) - the expectation is that they will be accumulated, 95 and added to the next message definition seen. Or completely 96 ignored. */ 97 void (*comment_dot) (struct abstract_catalog_reader_ty *pop, const char *s); 98 99 /* What to do with a file position seen in a comment (i.e. a message 100 location comment extracted by xgettext) - the expectation is that 101 they will be accumulated, and added to the next message 102 definition seen. Or completely ignored. */ 103 void (*comment_filepos) (struct abstract_catalog_reader_ty *pop, 104 const char *s, size_t line); 105 106 /* What to do with a comment that starts with a ',' or '!' - this is a 107 special comment. One of the possible uses is to indicate a 108 inexact translation. */ 109 void (*comment_special) (struct abstract_catalog_reader_ty *pop, 110 const char *s); 111 }; 112 113 114 /* This next structure defines the base class passed to the methods. 115 Derived methods will often need to cast their first argument before 116 using it (this corresponds to the implicit 'this' argument in C++). 117 118 When declaring derived classes, use the ABSTRACT_CATALOG_READER_TY define 119 at the start of the structure, to declare inherited instance variables, 120 etc. */ 121 122 #define ABSTRACT_CATALOG_READER_TY \ 123 abstract_catalog_reader_class_ty *methods; 124 125 typedef struct abstract_catalog_reader_ty abstract_catalog_reader_ty; 126 struct abstract_catalog_reader_ty 127 { 128 ABSTRACT_CATALOG_READER_TY 129 }; 130 131 132 /* This structure describes a textual catalog input format. */ 133 struct catalog_input_format 134 { 135 /* Parses the contents of FP, invoking the appropriate callbacks. */ 136 void (*parse) (abstract_catalog_reader_ty *pop, FILE *fp, 137 const char *real_filename, const char *logical_filename); 138 139 /* Whether the parse function always produces messages encoded in UTF-8 140 encoding. */ 141 bool produces_utf8; 142 }; 143 144 typedef const struct catalog_input_format * catalog_input_format_ty; 145 146 147 /* Allocate a fresh abstract_catalog_reader_ty (or derived class) instance and 148 call its constructor. */ 149 extern abstract_catalog_reader_ty * 150 catalog_reader_alloc (abstract_catalog_reader_class_ty *method_table); 151 152 /* Read a PO file from a stream, and dispatch to the various 153 abstract_catalog_reader_class_ty methods. */ 154 extern void 155 catalog_reader_parse (abstract_catalog_reader_ty *pop, FILE *fp, 156 const char *real_filename, 157 const char *logical_filename, 158 catalog_input_format_ty input_syntax); 159 160 /* Call the destructor and deallocate a abstract_catalog_reader_ty (or derived 161 class) instance. */ 162 extern void 163 catalog_reader_free (abstract_catalog_reader_ty *pop); 164 165 166 /* Callbacks used by po-gram.y or po-lex.c, indirectly from 167 catalog_reader_parse. */ 168 extern void po_callback_domain (char *name); 169 extern void po_callback_message (char *msgctxt, 170 char *msgid, lex_pos_ty *msgid_pos, 171 char *msgid_plural, 172 char *msgstr, size_t msgstr_len, 173 lex_pos_ty *msgstr_pos, 174 char *prev_msgctxt, 175 char *prev_msgid, char *prev_msgid_plural, 176 bool force_fuzzy, bool obsolete); 177 extern void po_callback_comment (const char *s); 178 extern void po_callback_comment_dot (const char *s); 179 extern void po_callback_comment_filepos (const char *s, size_t line); 180 extern void po_callback_comment_special (const char *s); 181 extern void po_callback_comment_dispatcher (const char *s); 182 183 /* Parse a special comment and put the result in *fuzzyp, formatp, *rangep, 184 *wrapp. */ 185 extern void po_parse_comment_special (const char *s, bool *fuzzyp, 186 enum is_format formatp[NFORMATS], 187 struct argument_range *rangep, 188 enum is_wrap *wrapp, 189 enum is_syntax_check scp[NSYNTAXCHECKS]); 190 191 192 #ifdef __cplusplus 193 } 194 #endif 195 196 197 #endif /* _READ_CATALOG_ABSTRACT_H */ 198