annotate lib-src/make-msgfile.c @ 269:b2472a1930f2 r20-5b33

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