2 #ifndef EL__INTL_GETTEXT_LIBINTL_H
3 #define EL__INTL_GETTEXT_LIBINTL_H
5 /* This header file provides an interface between ELinks and GNU libintl. I was
6 * astonished that there is no libintl.h but libgnuintl.h (and that name seemed
7 * ugly ;-), and I also decided that it will be better to introduce a clean
8 * interface instead of digging to libgnuintl.h too much. */
10 /* Contrary to a standard gettext interface, we pass destination charset and
11 * language (in form of struct terminal) directly with each call, allowing to
12 * easily multiplex between several terminals. */
14 #include "intl/gettext/libgettext.h"
16 #include "config/options.h"
17 #include "intl/charsets.h"
18 #include "terminal/terminal.h"
20 /* no-op - just for marking */
21 #define N_(msg) (gettext_noop(msg))
24 #define N__(msg) (gettext_noop(msg))
26 #define N__(msg) (NULL)
30 /* The intl/gettext/libgettext.h header nukes gettext functions but not the _()
31 * function so make sure it is also just a noop when NLS is disabled. */
34 /* In order to make it able to compile using -Werror this has to be a function
35 * so that local @term variables will not be reported as unused. */
36 static inline unsigned char *
37 _(unsigned char *msg
, struct terminal
*term
)
39 return gettext_noop(msg
);
42 static inline unsigned char *
43 n_(unsigned char *msg1
, unsigned char *msg2
, unsigned long int n
, struct terminal
*term
)
45 return gettext_noop(msg1
);
51 /* The number of the charset to which the "elinks" domain was last
52 * bound with bind_textdomain_codeset(), or -1 if none yet. This
53 * cannot be a static variable in _(), because then it would get
54 * duplicated in every translation unit, even though the actual
55 * binding is global. */
56 extern int current_charset
;
58 /* Define it to find redundant useless calls */
59 /* #define DEBUG_IT */
62 intl_set_charset(struct terminal
*term
)
64 int new_charset
= get_terminal_codepage(term
);
66 /* Prevent useless switching. */
67 if (current_charset
!= new_charset
) {
68 bind_textdomain_codeset( /* PACKAGE */ "elinks",
69 get_cp_mime_name(new_charset
));
70 current_charset
= new_charset
;
74 /* TODO: Ideally, we should internally work only in Unicode - then the need for
75 * charsets multiplexing would cease. That'll take some work yet, though.
80 /* Wraps around gettext(), employing charset multiplexing. If you don't care
81 * about charset (usually during initialization or when you don't use terminals
82 * at all), use gettext() directly. */
83 static inline unsigned char *
84 _(unsigned char *msg
, struct terminal
*term
)
86 /* Prevent useless (and possibly dangerous) calls. */
90 if (term
) intl_set_charset(term
);
92 return (unsigned char *) gettext(msg
);
97 #include "util/error.h"
99 /* This one will emit errors on null/empty msgs and when multiple calls are
100 * done for the same result in the same function. Some noise is possible,
101 * when a function is called twice or more, but then we should cache msg,
102 * in function caller. --Zas */
104 /* __FUNCTION__ isn't supported by all, but it's debugging code. */
105 #define _(m, t) __(__FILE__, __LINE__, __FUNCTION__, m, t)
107 /* Overflows are theorically possible here. Debug purpose only. */
108 static inline unsigned char *
109 __(unsigned char *file
, unsigned int line
, unsigned char *func
,
110 unsigned char *msg
, struct terminal
*term
)
112 static unsigned char last_file
[512] = "";
113 static unsigned int last_line
= 0;
114 static unsigned char last_func
[1024] = "";
115 static unsigned char last_result
[16384] = "";
116 unsigned char *result
;
118 /* Prevent useless (and possibly dangerous) calls. */
120 ERROR("%s:%u %s msg parameter", file
, line
, msg
? "empty": "NULL");
124 if (term
) intl_set_charset(term
);
126 result
= (unsigned char *) gettext(msg
);
128 if (!strcmp(result
, last_result
)
129 && !strcmp(file
, last_file
)
130 && !strcmp(func
, last_func
)) {
131 ERROR("%s:%u Duplicate call to _() in %s() (previous at line %u)",
132 file
, line
, func
, last_line
);
136 strcpy(last_file
, file
);
137 strcpy(last_func
, func
);
138 strcpy(last_result
, result
);
146 /* For plural handling. */
147 /* Wraps around ngettext(), employing charset multiplexing. If you don't care
148 * about charset (usually during initialization or when you don't use terminals
149 * at all), use ngettext() directly. */
150 static inline unsigned char *
151 n_(unsigned char *msg1
, unsigned char *msg2
, unsigned long int n
, struct terminal
*term
)
153 /* Prevent useless (and possibly dangerous) calls. */
157 if (term
) intl_set_charset(term
);
159 return (unsigned char *) ngettext(msg1
, msg2
, n
);
163 /* Languages table lookups. */
167 unsigned char *iso639
;
170 extern struct language languages
[];
172 /* These two calls return 1 (english) if the code/name wasn't found. */
173 extern int name_to_language(const unsigned char *name
);
174 extern int iso639_to_language(unsigned char *iso639
);
176 extern unsigned char *language_to_name(int language
);
177 extern unsigned char *language_to_iso639(int language
);
179 extern int get_system_language_index(void);
181 /* The current state. The state should be initialized by a set_language(0)
184 extern int current_language
, system_language
;
185 extern void set_language(int language
);
187 #endif /* CONFIG_NLS */