1/* Reading PO files, abstract class.
2   Copyright (C) 1995-1996, 1998, 2000-2003, 2005-2006 Free Software Foundation, Inc.
3
4   This file was written by Peter Miller <millerp@canb.auug.org.au>
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software Foundation,
18   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
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
30extern "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.  */
43struct 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
51typedef struct abstract_catalog_reader_class_ty
52        abstract_catalog_reader_class_ty;
53struct 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
125typedef struct abstract_catalog_reader_ty abstract_catalog_reader_ty;
126struct abstract_catalog_reader_ty
127{
128  ABSTRACT_CATALOG_READER_TY
129};
130
131
132/* This structure describes a textual catalog input format.  */
133struct 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
144typedef 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.  */
149extern 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.  */
154extern 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.  */
162extern 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.  */
168extern void po_callback_domain (char *name);
169extern 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);
177extern void po_callback_comment (const char *s);
178extern void po_callback_comment_dot (const char *s);
179extern void po_callback_comment_filepos (const char *s, size_t line);
180extern void po_callback_comment_special (const char *s);
181extern void po_callback_comment_dispatcher (const char *s);
182
183/* Parse a special comment and put the result in *fuzzyp, formatp, *wrapp.  */
184extern void po_parse_comment_special (const char *s, bool *fuzzyp,
185				      enum is_format formatp[NFORMATS],
186				      enum is_wrap *wrapp);
187
188
189#ifdef __cplusplus
190}
191#endif
192
193
194#endif /* _READ_CATALOG_ABSTRACT_H */
195