annotate lib-src/make-msgfile.c @ 452:3d3049ae1304 r21-2-41

Import from CVS: tag r21-2-41
author cvs
date Mon, 13 Aug 2007 11:40:21 +0200
parents abe6d1db359e
children 023b83f4e54b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
1 /*
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
2
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
3
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 PROPOSAL FOR HOW THIS ALL OUGHT TO WORK
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 this isn't implemented yet, but this is the plan-in-progress
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
7
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 In general, it's accepted that the best way to internationalize is for all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 messages to be referred to by a symbolic name (or number) and come out of a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 table or tables, which are easy to change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 However, with Emacs, we've got the task of internationalizing a huge body
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 of existing code, which already contains messages internally.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 For the C code we've got two options:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 - Use a Sun-like gettext() form, which takes an "english" string which
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 appears literally in the source, and uses that as a hash key to find
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 a translated string;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 - Rip all of the strings out and put them in a table.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 In this case, it's desirable to make as few changes as possible to the C
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 code, to make it easier to merge the code with the FSF version of emacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 which won't ever have these changes made to it. So we should go with the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 former option.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 The way it has been done (between 19.8 and 19.9) was to use gettext(), but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 *also* to make massive changes to the source code. The goal now is to use
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 gettext() at run-time and yet not require a textual change to every line
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 in the C code which contains a string constant. A possible way to do this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 is described below.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 (gettext() can be implemented in terms of catgets() for non-Sun systems, so
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 that in itself isn't a problem.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 For the Lisp code, we've got basically the same options: put everything in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 a table, or translate things implicitly.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 Another kink that lisp code introduces is that there are thousands of third-
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 party packages, so changing the source for all of those is simply not an
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 option.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 Is it a goal that if some third party package displays a message which is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 one we know how to translate, then we translate it? I think this is a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 worthy goal. It remains to be seen how well it will work in practice.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 So, we should endeavor to minimize the impact on the lisp code. Certain
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 primitive lisp routines (the stuff in lisp/prim/, and especially in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 cmdloop.el and minibuf.el) may need to be changed to know about translation,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 but that's an ideologically clean thing to do because those are considered
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 a part of the emacs substrate.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 However, if we find ourselves wanting to make changes to, say, RMAIL, then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 something has gone wrong. (Except to do things like remove assumptions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 about the order of words within a sentence, or how pluralization works.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
57 There are two parts to the task of displaying translated strings to the
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 user: the first is to extract the strings which need to be translated from
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 the sources; and the second is to make some call which will translate those
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 strings before they are presented to the user.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
61
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 The old way was to use the same form to do both, that is, GETTEXT() was both
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 the tag that we searched for to build a catalog, and was the form which did
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 the translation. The new plan is to separate these two things more: the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 tags that we search for to build the catalog will be stuff that was in there
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 already, and the translation will get done in some more centralized, lower
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 level place.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
69 This program (make-msgfile.c) addresses the first part, extracting the
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 strings.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
71
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 For the emacs C code, we need to recognize the following patterns:
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
73
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 message ("string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 error ("string")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 report_file_error ("string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 signal_simple_error ("string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 signal_simple_error_2 ("string" ... )
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
79
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 build_translated_string ("string")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 #### add this and use it instead of build_string() in some places.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
82
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 yes_or_no_p ("string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 #### add this instead of funcalling Qyes_or_no_p directly.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 barf_or_query_if_file_exists #### restructure this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 check all callers of Fsignal #### restructure these
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 signal_error (Qerror ... ) #### change all of these to error()
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
89
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 And we also parse out the `interactive' prompts from DEFUN() forms.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
91
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 #### When we've got a string which is a candidate for translation, we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 should ignore it if it contains only format directives, that is, if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 there are no alphabetic characters in it that are not a part of a `%'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 directive. (Careful not to translate either "%s%s" or "%s: ".)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 For the emacs Lisp code, we need to recognize the following patterns:
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
98
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 (message "string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 (error "string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 (format "string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 (read-from-minibuffer "string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 (read-shell-command "string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (y-or-n-p "string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 (yes-or-no-p "string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 (read-file-name "string" ... )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 (temp-minibuffer-message "string")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 (query-replace-read-args "string" ... )
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
109
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 I expect there will be a lot like the above; basically, any function which
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 is a commonly used wrapper around an eventual call to `message' or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 `read-from-minibuffer' needs to be recognized by this program.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 (dgettext "domain-name" "string") #### do we still need this?
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
116
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 things that should probably be restructured:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 `princ' in cmdloop.el
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 `insert' in debug.el
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 face-interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 help.el, syntax.el all messed up
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
122
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 Menu descriptors: one way to extract the strings in menu labels would be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 to teach this program about "^(defvar .*menu\n" forms; that's probably
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 kind of hard, though, so perhaps a better approach would be to make this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 program recognize lines of the form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 "string" ... ;###translate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
131 where the magic token ";###translate" on a line means that the string
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
132 constant on this line should go into the message catalog. This is analogous
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 to the magic ";###autoload" comments, and to the magic comments used in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 EPSF structuring conventions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 -----
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 So this program manages to build up a catalog of strings to be translated.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 To address the second part of the problem, of actually looking up the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 translations, there are hooks in a small number of low level places in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 emacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
142 Assume the existence of a C function gettext(str) which returns the
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 translation of `str' if there is one, otherwise returns `str'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 - message() takes a char* as its argument, and always filters it through
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 gettext() before displaying it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 - errors are printed by running the lisp function `display-error' which
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 doesn't call `message' directly (it princ's to streams), so it must be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 carefully coded to translate its arguments. This is only a few lines
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 of code.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 - Fread_minibuffer_internal() is the lowest level interface to all minibuf
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 interactions, so it is responsible for translating the value that will go
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 into Vminibuf_prompt.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 - Fpopup_menu filters the menu titles through gettext().
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 The above take care of 99% of all messages the user ever sees.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 - The lisp function temp-minibuffer-message translates its arg.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 - query-replace-read-args is funny; it does
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 (setq from (read-from-minibuffer (format "%s: " string) ... ))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 (setq to (read-from-minibuffer (format "%s %s with: " string from) ... ))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 What should we do about this? We could hack query-replace-read-args to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 translate its args, but might this be a more general problem? I don't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 think we ought to translate all calls to format. We could just change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 the calling sequence, since this is odd in that the first %s wants to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 translated but the second doesn't.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 Solving the "translating too much" problem:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 The concern has been raised that in this situation:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 - "Help" is a string for which we know a translation;
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
177 - someone visits a file called Help, and someone does something
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 contrived like (error buffer-file-name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 then we would display the translation of Help, which would not be correct.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 We can solve this by adding a bit to Lisp_String objects which identifies
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 them as having been read as literal constants from a .el or .elc file (as
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
182 opposed to having been constructed at run time as it would in the above
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 case.) To solve this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 - Fmessage() takes a lisp string as its first argument.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 If that string is a constant, that is, was read from a source file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 as a literal, then it calls message() with it, which translates.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 Otherwise, it calls message_no_translate(), which does not translate.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 - Ferror() (actually, Fsignal() when condition is Qerror) works similarly.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 /* Scan specified C and Lisp files, extracting the following messages:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 C files:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 GETTEXT (...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 DEFER_GETTEXT (...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 DEFUN interactive prompts
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 Lisp files:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 (gettext ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 (dgettext "domain-name" ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 (defer-gettext ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 (interactive ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 The arguments given to this program are all the C and Lisp source files
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 of GNU Emacs. .el and .c files are allowed. There is no support for .elc
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 files at this time, but they may be specified; the corresponding .el file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 will be used. Similarly, .o files can also be specified, and the corresponding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 .c file will be used. This helps the makefile pass the correct list of files.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 The results, which go to standard output or to a file specified with -a or -o
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 (-a to append, -o to start from nothing), are quoted strings wrapped in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 gettext(...). The results can be passed to xgettext to produce a .po message
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 #include <stdio.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 #include <string.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 #define LINESIZE 256
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 #define GET_LINE fgets (line, LINESIZE, infile)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 #define CHECK_EOL(p) if (*(p) == '\0') (p) = GET_LINE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 #define SKIP_BLANKS(p) while ((*p) == ' ' || (*p) == '\t') (p)++
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 enum filetype { C_FILE, LISP_FILE, INVALID_FILE };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 /* some brain-dead headers define this ... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 #undef FALSE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 #undef TRUE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 enum boolean { FALSE, TRUE };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 FILE *infile;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 FILE *outfile;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 char line[LINESIZE];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 void scan_file (char *filename);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 void process_C_file (void);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 void process_Lisp_file (void);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 char *copy_up_to_paren (register char *p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 char *copy_quoted_string (register char *p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 enum boolean no_interactive_prompt (register char *q);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 char *skip_blanks (register char *p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 main (int argc, char *argv[])
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 register int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 outfile = stdout;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 /* If first two args are -o FILE, output to FILE. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 i = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 if (argc > i + 1 && strcmp (argv[i], "-o") == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 outfile = fopen (argv[++i], "w");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 ++i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 /* ...Or if args are -a FILE, append to FILE. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 if (argc > i + 1 && strcmp (argv[i], "-a") == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 outfile = fopen (argv[++i], "a");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 ++i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 if (!outfile) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 fprintf (stderr, "Unable to open output file %s\n", argv[--i]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 for (; i < argc; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 scan_file (argv[i]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 void scan_file (char *filename)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 enum filetype type = INVALID_FILE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 register char *p = filename + strlen (filename);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 if (strcmp (p - 4, ".elc") == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 *--p = '\0'; /* Use .el file instead */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 type = LISP_FILE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 } else if (strcmp (p - 3, ".el") == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 type = LISP_FILE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 else if (strcmp (p - 2, ".o") == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 *--p = 'c'; /* Use .c file instead */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 type = C_FILE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 } else if (strcmp (p - 2, ".c") == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 type = C_FILE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 if (type == INVALID_FILE) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 fprintf (stderr, "File %s being ignored\n", filename);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 infile = fopen (filename, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 if (!infile) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 fprintf (stderr, "Unable to open input file %s\n", filename);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 fprintf (outfile, "/* %s */\n", filename);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 if (type == C_FILE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 process_C_file ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 process_Lisp_file ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 fputc ('\n', outfile);
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
309
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 fclose (infile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 void process_C_file (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 register char *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 char *gettext, *defun;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 while (p = GET_LINE) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 gettext = strstr (p, "GETTEXT");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 defun = strstr (p, "DEFUN");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 if (gettext || defun) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 if (gettext) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 p = gettext;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 p += 7; /* Skip over "GETTEXT" */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 else if (defun) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 p = defun;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 p += 5; /* Skip over "DEFUN" */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 p = skip_blanks (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 if (*p++ != '(')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 if (defun) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 register int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 for (i = 0; i < 5; i++) /* Skip over commas to doc string */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 while (*p++ != ',')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 CHECK_EOL (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 if (*p == '\n')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 p = GET_LINE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 p = skip_blanks (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 if (*p != '\"') /* Make sure there is a quoted string */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 if (defun && no_interactive_prompt (p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 fprintf (outfile, "gettext(");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 if (gettext)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 p = copy_up_to_paren (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 p = copy_quoted_string (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 fprintf (outfile, ")\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 void process_Lisp_file (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 register char *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 char *gettext, *interactive;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 enum boolean dgettext = FALSE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 while (p = GET_LINE) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 gettext = strstr (p, "gettext");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 interactive = strstr (p, "(interactive");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 if (gettext || interactive) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 if (!interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 p = gettext;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 else if (!gettext)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 p = interactive;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 else if (gettext < interactive) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 p = gettext;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 interactive = NULL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 } else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 p = interactive;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 gettext = NULL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 if (gettext) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 if (p > line && *(p-1) == 'd')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 dgettext = TRUE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 p += 7; /* Skip over "gettext" */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 } else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 p += 12; /* Skip over "(interactive" */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 p = skip_blanks (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 if (*p != '\"') /* Make sure there is a quoted string */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 if (dgettext) { /* Skip first quoted string (domain name) */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 while (*++p != '"')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 ; /* null statement */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 ++p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 p = skip_blanks (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 if (*p != '\"') /* Check for second quoted string (message) */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 if (interactive && no_interactive_prompt (p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 fprintf (outfile, "gettext(");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 p = copy_up_to_paren (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 fprintf (outfile, ")\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 /* Assuming p points to some character beyond an opening parenthesis, copy
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 everything to outfile up to but not including the closing parenthesis.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 char *copy_up_to_paren (register char *p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 for (;;) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 SKIP_BLANKS (p); /* We don't call skip_blanks() in order to */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 CHECK_EOL (p); /* preserve blanks at the beginning of the line */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 if (*p == ')')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 if (*p == '\"')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 p = copy_quoted_string (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 fputc (*p++, outfile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 return p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 /* Assuming p points to a quote character, copy the quoted string to outfile.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 char *copy_quoted_string (register char *p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 do {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 if (*p == '\\')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 fputc (*p++, outfile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 fputc (*p++, outfile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 CHECK_EOL (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 } while (*p != '\"');
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 fputc (*p++, outfile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 return p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 /* Return TRUE if the interactive specification consists only
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 of code letters and no prompt.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 enum boolean no_interactive_prompt (register char *q)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 while (++q, *q == '*' || *q == '@')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 ; /* null statement */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 if (*q == '\"')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 return TRUE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 skip_code_letter:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 if (*++q == '\"')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 return TRUE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 if (*q == '\\' && *++q == 'n') {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 ++q;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 goto skip_code_letter;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 return FALSE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 char *skip_blanks (register char *p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 while (*p == ' ' || *p == '\t' || *p == '\n') {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 p++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 CHECK_EOL (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 return p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 }