Bug Summary

File:src/gnu/usr.bin/texinfo/makeinfo/cmds.c
Warning:line 1692, column 15
Value stored to 'stack' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name cmds.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/texinfo/obj/makeinfo -resource-dir /usr/local/lib/clang/13.0.0 -D HAVE_CONFIG_H -I . -I /usr/src/gnu/usr.bin/texinfo/makeinfo -I .. -I /usr/src/gnu/usr.bin/texinfo/lib -I ../intl -D LOCALEDIR="/usr/share/locale" -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/gnu/usr.bin/texinfo/obj/makeinfo -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/gnu/usr.bin/texinfo/makeinfo/cmds.c
1/* cmds.c -- Texinfo commands.
2 $Id: cmds.c,v 1.4 2019/05/27 07:13:38 otto Exp $
3
4 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
5 Foundation, Inc.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include "system.h"
22#include "cmds.h"
23#include "defun.h"
24#include "files.h"
25#include "footnote.h"
26#include "html.h"
27#include "insertion.h"
28#include "lang.h"
29#include "macro.h"
30#include "makeinfo.h"
31#include "node.h"
32#include "sectioning.h"
33#include "toc.h"
34#include "xml.h"
35
36#ifdef TM_IN_SYS_TIME
37#include <sys/time.h>
38#else
39#include <time.h>
40#endif
41
42/* Options. */
43static void cm_exampleindent (void),
44 cm_firstparagraphindent (void),
45 cm_paragraphindent (void),
46 cm_novalidate (void);
47
48/* Internals. */
49static void cm_obsolete (int arg, int start, int end),
50 not_fixed_width (int arg);
51
52/* The dispatch table. */
53COMMAND command_table[] = {
54 { "\t", insert_space, NO_BRACE_ARGS0 },
55 { "\n", insert_space, NO_BRACE_ARGS0 },
56 { " ", insert_space, NO_BRACE_ARGS0 },
57 { "!", cm_punct, NO_BRACE_ARGS0 },
58 { "\"", cm_accent_umlaut, MAYBE_BRACE_ARGS2 },
59 { "'", cm_accent_acute, MAYBE_BRACE_ARGS2 },
60 { "*", cm_asterisk, NO_BRACE_ARGS0 },
61 { ",", cm_accent_cedilla, MAYBE_BRACE_ARGS2 },
62 { "-", cm_no_op, NO_BRACE_ARGS0 },
63 { ".", cm_punct, NO_BRACE_ARGS0 },
64 { "/", cm_no_op, NO_BRACE_ARGS0 },
65 { ":", cm_colon, NO_BRACE_ARGS0 },
66 { "=", cm_accent, MAYBE_BRACE_ARGS2 },
67 { "?", cm_punct, NO_BRACE_ARGS0 },
68 { "@", insert_self, NO_BRACE_ARGS0 },
69 { "\\", insert_self, NO_BRACE_ARGS0 },
70 { "^", cm_accent_hat, MAYBE_BRACE_ARGS2 },
71 { "`", cm_accent_grave, MAYBE_BRACE_ARGS2 },
72 { "{", insert_self, NO_BRACE_ARGS0 },
73 { "|", cm_no_op, NO_BRACE_ARGS0 },
74 { "}", insert_self, NO_BRACE_ARGS0 },
75 { "~", cm_accent_tilde, MAYBE_BRACE_ARGS2 },
76 { "AA", cm_special_char, BRACE_ARGS1 },
77 { "AE", cm_special_char, BRACE_ARGS1 },
78 { "H", cm_accent, MAYBE_BRACE_ARGS2 },
79 { "L", cm_special_char, BRACE_ARGS1 },
80 { "LaTeX", cm_LaTeX, BRACE_ARGS1 },
81 { "O", cm_special_char, BRACE_ARGS1 },
82 { "OE", cm_special_char, BRACE_ARGS1 },
83 { "TeX", cm_TeX, BRACE_ARGS1 },
84 { "aa", cm_special_char, BRACE_ARGS1 },
85 { "abbr", cm_abbr, BRACE_ARGS1 },
86 { "acronym", cm_acronym, BRACE_ARGS1 },
87 { "ae", cm_special_char, BRACE_ARGS1 },
88 { "afivepaper", cm_ignore_line, NO_BRACE_ARGS0 },
89 { "afourlatex", cm_ignore_line, NO_BRACE_ARGS0 },
90 { "afourpaper", cm_ignore_line, NO_BRACE_ARGS0 },
91 { "afourwide", cm_ignore_line, NO_BRACE_ARGS0 },
92 { "alias", cm_alias, NO_BRACE_ARGS0 },
93 { "anchor", cm_anchor, BRACE_ARGS1 },
94 { "appendix", cm_appendix, NO_BRACE_ARGS0 },
95 { "appendixsection", cm_appendixsec, NO_BRACE_ARGS0 },
96 { "appendixsec", cm_appendixsec, NO_BRACE_ARGS0 },
97 { "appendixsubsec", cm_appendixsubsec, NO_BRACE_ARGS0 },
98 { "appendixsubsubsec", cm_appendixsubsubsec, NO_BRACE_ARGS0 },
99 { "asis", cm_no_op, BRACE_ARGS1 },
100 { "author", cm_author, NO_BRACE_ARGS0 },
101 { "b", cm_b, BRACE_ARGS1 },
102 { "bullet", cm_bullet, BRACE_ARGS1 },
103 { "bye", cm_bye, NO_BRACE_ARGS0 },
104 { "c", cm_comment, NO_BRACE_ARGS0 },
105 { "caption", cm_caption, BRACE_ARGS1 },
106 { "cartouche", cm_cartouche, NO_BRACE_ARGS0 },
107 { "center", cm_center, NO_BRACE_ARGS0 },
108 { "centerchap", cm_unnumbered, NO_BRACE_ARGS0 },
109 { "chapheading", cm_chapheading, NO_BRACE_ARGS0 },
110 { "chapter", cm_chapter, NO_BRACE_ARGS0 },
111 { "cindex", cm_cindex, NO_BRACE_ARGS0 },
112 { "cite", cm_cite, BRACE_ARGS1 },
113 { "clear", cm_clear, NO_BRACE_ARGS0 },
114 { "code", cm_code, BRACE_ARGS1 },
115 { "comma", cm_comma, BRACE_ARGS1 },
116 { "command", cm_code, BRACE_ARGS1 },
117 { "comment", cm_comment, NO_BRACE_ARGS0 },
118 { "contents", cm_contents, NO_BRACE_ARGS0 },
119 { "copying", cm_copying, NO_BRACE_ARGS0 },
120 { "copyright", cm_copyright, BRACE_ARGS1 },
121 { "ctrl", cm_obsolete, BRACE_ARGS1 },
122 { "defcodeindex", cm_defcodeindex, NO_BRACE_ARGS0 },
123 { "defcv", cm_defun, NO_BRACE_ARGS0 },
124 { "defcvx", cm_defun, NO_BRACE_ARGS0 },
125 { "deffn", cm_defun, NO_BRACE_ARGS0 },
126 { "deffnx", cm_defun, NO_BRACE_ARGS0 },
127 { "defindex", cm_defindex, NO_BRACE_ARGS0 },
128 { "definfoenclose", cm_definfoenclose, NO_BRACE_ARGS0 },
129 { "defivar", cm_defun, NO_BRACE_ARGS0 },
130 { "defivarx", cm_defun, NO_BRACE_ARGS0 },
131 { "defmac", cm_defun, NO_BRACE_ARGS0 },
132 { "defmacx", cm_defun, NO_BRACE_ARGS0 },
133 { "defmethod", cm_defun, NO_BRACE_ARGS0 },
134 { "defmethodx", cm_defun, NO_BRACE_ARGS0 },
135 { "defop", cm_defun, NO_BRACE_ARGS0 },
136 { "defopt", cm_defun, NO_BRACE_ARGS0 },
137 { "defoptx", cm_defun, NO_BRACE_ARGS0 },
138 { "defopx", cm_defun, NO_BRACE_ARGS0 },
139 { "defspec", cm_defun, NO_BRACE_ARGS0 },
140 { "defspecx", cm_defun, NO_BRACE_ARGS0 },
141 { "deftp", cm_defun, NO_BRACE_ARGS0 },
142 { "deftpx", cm_defun, NO_BRACE_ARGS0 },
143 { "deftypecv", cm_defun, NO_BRACE_ARGS0 },
144 { "deftypecvx", cm_defun, NO_BRACE_ARGS0 },
145 { "deftypefn", cm_defun, NO_BRACE_ARGS0 },
146 { "deftypefnx", cm_defun, NO_BRACE_ARGS0 },
147 { "deftypefun", cm_defun, NO_BRACE_ARGS0 },
148 { "deftypefunx", cm_defun, NO_BRACE_ARGS0 },
149 { "deftypeivar", cm_defun, NO_BRACE_ARGS0 },
150 { "deftypeivarx", cm_defun, NO_BRACE_ARGS0 },
151 { "deftypemethod", cm_defun, NO_BRACE_ARGS0 },
152 { "deftypemethodx", cm_defun, NO_BRACE_ARGS0 },
153 { "deftypeop", cm_defun, NO_BRACE_ARGS0 },
154 { "deftypeopx", cm_defun, NO_BRACE_ARGS0 },
155 { "deftypevar", cm_defun, NO_BRACE_ARGS0 },
156 { "deftypevarx", cm_defun, NO_BRACE_ARGS0 },
157 { "deftypevr", cm_defun, NO_BRACE_ARGS0 },
158 { "deftypevrx", cm_defun, NO_BRACE_ARGS0 },
159 { "defun", cm_defun, NO_BRACE_ARGS0 },
160 { "defunx", cm_defun, NO_BRACE_ARGS0 },
161 { "defvar", cm_defun, NO_BRACE_ARGS0 },
162 { "defvarx", cm_defun, NO_BRACE_ARGS0 },
163 { "defvr", cm_defun, NO_BRACE_ARGS0 },
164 { "defvrx", cm_defun, NO_BRACE_ARGS0 },
165 { "detailmenu", cm_detailmenu, NO_BRACE_ARGS0 },
166 { "dfn", cm_dfn, BRACE_ARGS1 },
167 { "dircategory", cm_dircategory, NO_BRACE_ARGS0 },
168 { "direntry", cm_direntry, NO_BRACE_ARGS0 },
169 { "display", cm_display, NO_BRACE_ARGS0 },
170 { "dmn", cm_dmn, BRACE_ARGS1 },
171 { "docbook", cm_docbook, NO_BRACE_ARGS0 },
172 { "documentdescription", cm_documentdescription, NO_BRACE_ARGS0 },
173 { "documentencoding", cm_documentencoding, NO_BRACE_ARGS0 },
174 { "documentlanguage", cm_documentlanguage, NO_BRACE_ARGS0 },
175 { "dotaccent", cm_accent, MAYBE_BRACE_ARGS2 },
176 { "dotless", cm_dotless, BRACE_ARGS1 },
177 { "dots", cm_dots, BRACE_ARGS1 },
178 { "email", cm_email, BRACE_ARGS1 },
179 { "emph", cm_emph, BRACE_ARGS1 },
180 { "end", cm_end, NO_BRACE_ARGS0 },
181 { "enddots", cm_enddots, BRACE_ARGS1 },
182 { "enumerate", cm_enumerate, NO_BRACE_ARGS0 },
183 { "env", cm_code, BRACE_ARGS1 },
184 { "equiv", cm_equiv, BRACE_ARGS1 },
185 { "error", cm_error, BRACE_ARGS1 },
186 { "euro", cm_special_char, BRACE_ARGS1 },
187 { "evenfooting", cm_ignore_line, NO_BRACE_ARGS0 },
188 { "evenheading", cm_ignore_line, NO_BRACE_ARGS0 },
189 { "everyfooting", cm_ignore_line, NO_BRACE_ARGS0 },
190 { "everyheading", cm_ignore_line, NO_BRACE_ARGS0 },
191 { "example", cm_example, NO_BRACE_ARGS0 },
192 { "exampleindent", cm_exampleindent, NO_BRACE_ARGS0 },
193 { "exclamdown", cm_special_char, BRACE_ARGS1 },
194 { "exdent", cm_exdent, NO_BRACE_ARGS0 },
195 { "expansion", cm_expansion, BRACE_ARGS1 },
196 { "file", cm_code, BRACE_ARGS1 },
197 { "finalout", cm_no_op, NO_BRACE_ARGS0 },
198 { "findex", cm_findex, NO_BRACE_ARGS0 },
199 { "firstparagraphindent", cm_firstparagraphindent, NO_BRACE_ARGS0 },
200 { "float", cm_float, NO_BRACE_ARGS0 },
201 { "flushleft", cm_flushleft, NO_BRACE_ARGS0 },
202 { "flushright", cm_flushright, NO_BRACE_ARGS0 },
203 { "footnote", cm_footnote, NO_BRACE_ARGS0}, /* self-arg eater */
204 { "footnotestyle", cm_footnotestyle, NO_BRACE_ARGS0 },
205 { "format", cm_format, NO_BRACE_ARGS0 },
206 { "ftable", cm_ftable, NO_BRACE_ARGS0 },
207 { "group", cm_group, NO_BRACE_ARGS0 },
208 { "heading", cm_heading, NO_BRACE_ARGS0 },
209 { "headings", cm_ignore_line, NO_BRACE_ARGS0 },
210 { "headitem", cm_headitem, NO_BRACE_ARGS0 },
211 { "html", cm_html, NO_BRACE_ARGS0 },
212 { "hyphenation", cm_ignore_arg, BRACE_ARGS1 },
213 { "i", cm_i, BRACE_ARGS1 },
214 { "ifclear", cm_ifclear, NO_BRACE_ARGS0 },
215 { "ifeq", cm_ifeq, NO_BRACE_ARGS0 },
216 { "ifdocbook", cm_ifdocbook, NO_BRACE_ARGS0 },
217 { "ifhtml", cm_ifhtml, NO_BRACE_ARGS0 },
218 { "ifinfo", cm_ifinfo, NO_BRACE_ARGS0 },
219 { "ifnotdocbook", cm_ifnotdocbook, NO_BRACE_ARGS0 },
220 { "ifnothtml", cm_ifnothtml, NO_BRACE_ARGS0 },
221 { "ifnotinfo", cm_ifnotinfo, NO_BRACE_ARGS0 },
222 { "ifnotplaintext", cm_ifnotplaintext, NO_BRACE_ARGS0 },
223 { "ifnottex", cm_ifnottex, NO_BRACE_ARGS0 },
224 { "ifnotxml", cm_ifnotxml, NO_BRACE_ARGS0 },
225 { "ifplaintext", cm_ifplaintext, NO_BRACE_ARGS0 },
226 { "ifset", cm_ifset, NO_BRACE_ARGS0 },
227 { "iftex", cm_iftex, NO_BRACE_ARGS0 },
228 { "ifxml", cm_ifxml, NO_BRACE_ARGS0 },
229 { "ignore", command_name_condition, NO_BRACE_ARGS0 },
230 { "image", cm_image, BRACE_ARGS1 },
231 { "include", cm_include, NO_BRACE_ARGS0 },
232 { "indent", cm_indent, NO_BRACE_ARGS0 },
233 { "indicateurl", cm_indicate_url, BRACE_ARGS1 },
234 { "inforef", cm_inforef, BRACE_ARGS1 },
235 { "insertcopying", cm_insert_copying, NO_BRACE_ARGS0 },
236 { "item", cm_item, NO_BRACE_ARGS0 },
237 { "itemize", cm_itemize, NO_BRACE_ARGS0 },
238 { "itemx", cm_itemx, NO_BRACE_ARGS0 },
239 { "kbd", cm_kbd, BRACE_ARGS1 },
240 { "kbdinputstyle", cm_ignore_line, NO_BRACE_ARGS0 },
241 { "key", cm_key, BRACE_ARGS1 },
242 { "kindex", cm_kindex, NO_BRACE_ARGS0 },
243 { "l", cm_special_char, BRACE_ARGS1 },
244 { "lisp", cm_lisp, NO_BRACE_ARGS0 },
245 { "listoffloats", cm_listoffloats, NO_BRACE_ARGS0 },
246 { "lowersections", cm_lowersections, NO_BRACE_ARGS0 },
247 { "macro", cm_macro, NO_BRACE_ARGS0 },
248 { "majorheading", cm_majorheading, NO_BRACE_ARGS0 },
249 { "math", cm_math, BRACE_ARGS1 },
250 { "menu", cm_menu, NO_BRACE_ARGS0 },
251 { "minus", cm_minus, BRACE_ARGS1 },
252 { "multitable", cm_multitable, NO_BRACE_ARGS0 },
253 { "need", cm_ignore_line, NO_BRACE_ARGS0 },
254 { "node", cm_node, NO_BRACE_ARGS0 },
255 { "noindent", cm_noindent_cmd, NO_BRACE_ARGS0 },
256 { "novalidate", cm_novalidate, NO_BRACE_ARGS0 },
257 { "nwnode", cm_node, NO_BRACE_ARGS0 },
258 { "o", cm_special_char, BRACE_ARGS1 },
259 { "oddfooting", cm_ignore_line, NO_BRACE_ARGS0 },
260 { "oddheading", cm_ignore_line, NO_BRACE_ARGS0 },
261 { "oe", cm_special_char, BRACE_ARGS1 },
262 { "option", cm_code, BRACE_ARGS1 },
263 { "ordf", cm_special_char, BRACE_ARGS1 },
264 { "ordm", cm_special_char, BRACE_ARGS1 },
265 { "page", cm_no_op, NO_BRACE_ARGS0 },
266 { "pagesizes", cm_ignore_line, NO_BRACE_ARGS0 },
267 { "paragraphindent", cm_paragraphindent, NO_BRACE_ARGS0 },
268 { "pindex", cm_pindex, NO_BRACE_ARGS0 },
269 { "point", cm_point, BRACE_ARGS1 },
270 { "pounds", cm_special_char, BRACE_ARGS1 },
271 { "print", cm_print, BRACE_ARGS1 },
272 { "printindex", cm_printindex, NO_BRACE_ARGS0 },
273 { "pxref", cm_pxref, BRACE_ARGS1 },
274 { "questiondown", cm_special_char, BRACE_ARGS1 },
275 { "quotation", cm_quotation, NO_BRACE_ARGS0 },
276 { "r", cm_r, BRACE_ARGS1 },
277 { "raisesections", cm_raisesections, NO_BRACE_ARGS0 },
278 { "ref", cm_ref, BRACE_ARGS1 },
279 { "refill", cm_no_op, NO_BRACE_ARGS0 },
280 { "registeredsymbol", cm_registeredsymbol, BRACE_ARGS1 },
281 { "result", cm_result, BRACE_ARGS1 },
282 { "ringaccent", cm_accent, MAYBE_BRACE_ARGS2 },
283 { "rmacro", cm_rmacro, NO_BRACE_ARGS0 },
284 { "samp", cm_code, BRACE_ARGS1 },
285 { "sansserif", cm_sansserif, BRACE_ARGS1 },
286 { "sc", cm_sc, BRACE_ARGS1 },
287 { "section", cm_section, NO_BRACE_ARGS0 },
288 { "set", cm_set, NO_BRACE_ARGS0 },
289 { "setchapternewpage", cm_ignore_line, NO_BRACE_ARGS0 },
290 { "setchapterstyle", cm_obsolete, NO_BRACE_ARGS0 },
291 { "setcontentsaftertitlepage", cm_no_op, NO_BRACE_ARGS0 },
292 { "setfilename", cm_setfilename, NO_BRACE_ARGS0 },
293 { "setshortcontentsaftertitlepage", cm_no_op, NO_BRACE_ARGS0 },
294 { "settitle", cm_settitle, NO_BRACE_ARGS0 },
295 { "shortcaption", cm_caption, BRACE_ARGS1 },
296 { "shortcontents", cm_contents, NO_BRACE_ARGS0 },
297 { "shorttitlepage", cm_ignore_line, NO_BRACE_ARGS0 },
298 { "slanted", cm_slanted, BRACE_ARGS1 },
299 { "smallbook", cm_ignore_line, NO_BRACE_ARGS0 },
300 { "smalldisplay", cm_smalldisplay, NO_BRACE_ARGS0 },
301 { "smallexample", cm_smallexample, NO_BRACE_ARGS0 },
302 { "smallformat", cm_smallformat, NO_BRACE_ARGS0 },
303 { "smalllisp", cm_smalllisp, NO_BRACE_ARGS0 },
304 { "sp", cm_sp, NO_BRACE_ARGS0 },
305 { "ss", cm_special_char, BRACE_ARGS1 },
306 { "strong", cm_strong, BRACE_ARGS1 },
307 { "subheading", cm_subheading, NO_BRACE_ARGS0 },
308 { "subsection", cm_subsection, NO_BRACE_ARGS0 },
309 { "subsubheading", cm_subsubheading, NO_BRACE_ARGS0 },
310 { "subsubsection", cm_subsubsection, NO_BRACE_ARGS0 },
311 { "subtitle", cm_titlepage_cmds, NO_BRACE_ARGS0 },
312 { "summarycontents", cm_contents, NO_BRACE_ARGS0 },
313 { "syncodeindex", cm_synindex, NO_BRACE_ARGS0 },
314 { "synindex", cm_synindex, NO_BRACE_ARGS0 },
315 { "t", cm_tt, BRACE_ARGS1 },
316 { "tab", cm_tab, NO_BRACE_ARGS0 },
317 { "table", cm_table, NO_BRACE_ARGS0 },
318 { "tex", cm_tex, NO_BRACE_ARGS0 },
319 { "tie", cm_tie, BRACE_ARGS1 },
320 { "tieaccent", cm_accent, MAYBE_BRACE_ARGS2 },
321 { "tindex", cm_tindex, NO_BRACE_ARGS0 },
322 { "title", cm_titlepage_cmds, NO_BRACE_ARGS0 },
323 { "titlefont", cm_titlefont, BRACE_ARGS1 },
324 { "titlepage", cm_titlepage, NO_BRACE_ARGS0 },
325 { "today", cm_today, BRACE_ARGS1 },
326 { "top", cm_top, NO_BRACE_ARGS0 },
327 { "u", cm_accent, MAYBE_BRACE_ARGS2 },
328 { "ubaraccent", cm_accent, MAYBE_BRACE_ARGS2 },
329 { "udotaccent", cm_accent, MAYBE_BRACE_ARGS2 },
330 { "unmacro", cm_unmacro, NO_BRACE_ARGS0 },
331 { "unnumbered", cm_unnumbered, NO_BRACE_ARGS0 },
332 { "unnumberedsec", cm_unnumberedsec, NO_BRACE_ARGS0 },
333 { "unnumberedsubsec", cm_unnumberedsubsec, NO_BRACE_ARGS0 },
334 { "unnumberedsubsubsec", cm_unnumberedsubsubsec, NO_BRACE_ARGS0 },
335 { "uref", cm_uref, BRACE_ARGS1 },
336 { "url", cm_uref, BRACE_ARGS1 },
337 { "v", cm_accent, MAYBE_BRACE_ARGS2 },
338 { "value", cm_value, BRACE_ARGS1 },
339 { "var", cm_var, BRACE_ARGS1 },
340 { "verb", cm_verb, NO_BRACE_ARGS0 },
341 { "verbatim", cm_verbatim, NO_BRACE_ARGS0 },
342 { "verbatiminclude", cm_verbatiminclude, NO_BRACE_ARGS0 },
343 { "vindex", cm_vindex, NO_BRACE_ARGS0 },
344 { "vtable", cm_vtable, NO_BRACE_ARGS0 },
345 { "vskip", cm_ignore_line, NO_BRACE_ARGS0 },
346 { "w", cm_w, BRACE_ARGS1 },
347 { "xml", cm_xml, NO_BRACE_ARGS0 },
348 { "xref", cm_xref, BRACE_ARGS1 },
349
350 /* Deprecated commands. These used to be for italics. */
351 { "iappendix", cm_ideprecated, NO_BRACE_ARGS0 },
352 { "iappendixsec", cm_ideprecated, NO_BRACE_ARGS0 },
353 { "iappendixsection", cm_ideprecated, NO_BRACE_ARGS0 },
354 { "iappendixsubsec", cm_ideprecated, NO_BRACE_ARGS0 },
355 { "iappendixsubsubsec", cm_ideprecated, NO_BRACE_ARGS0 },
356 { "ichapter", cm_ideprecated, NO_BRACE_ARGS0 },
357 { "isection", cm_ideprecated, NO_BRACE_ARGS0 },
358 { "isubsection", cm_ideprecated, NO_BRACE_ARGS0 },
359 { "isubsubsection", cm_ideprecated, NO_BRACE_ARGS0 },
360 { "iunnumbered", cm_ideprecated, NO_BRACE_ARGS0 },
361 { "iunnumberedsec", cm_ideprecated, NO_BRACE_ARGS0 },
362 { "iunnumberedsubsec", cm_ideprecated, NO_BRACE_ARGS0 },
363 { "iunnumberedsubsubsec", cm_ideprecated, NO_BRACE_ARGS0 },
364
365 /* Now @include does what this was used to. */
366 { "infoinclude", cm_obsolete, NO_BRACE_ARGS0 },
367 { "titlespec", cm_obsolete, NO_BRACE_ARGS0 },
368
369 { NULL((void *)0), NULL((void *)0), NO_BRACE_ARGS0 }
370};
371
372/* The bulk of the Texinfo commands. */
373
374/* Commands which insert their own names. */
375void
376insert_self (int arg)
377{
378 if (arg == START0)
379 add_word (command);
380}
381
382void
383insert_space (int arg)
384{
385 if (arg == START0)
386 {
387 if (xml && !docbook)
388 xml_insert_entity ("space");
389 else
390 add_char (' ');
391 }
392}
393
394/* Insert a comma. Useful when a literal , would break our parsing of
395 multiple arguments. */
396void
397cm_comma (int arg)
398{
399 if (arg == START0)
400 add_char (',');
401}
402
403
404/* Force a line break in the output. */
405void
406cm_asterisk (void)
407{
408 if (html)
409 add_word ("<br>");
410 else if (xml && !docbook)
411 xml_insert_entity ("linebreak");
412 else if (docbook)
413 xml_asterisk ();
414 else
415 {
416 close_single_paragraph ();
417 cm_noindent ();
418 }
419}
420
421/* Insert ellipsis. */
422void
423cm_dots (int arg)
424{
425 if (arg == START0)
426 {
427 if (xml && !docbook)
428 xml_insert_entity ("dots");
429 else if (docbook)
430 xml_insert_entity ("hellip");
431 else
432 if (html && !in_fixed_width_font)
433 insert_string ("<small class=\"dots\">...</small>");
434 else
435 add_word ("...");
436 }
437}
438
439/* Insert ellipsis for sentence end. */
440void
441cm_enddots (int arg)
442{
443 if (arg == START0)
444 {
445 if (xml && !docbook)
446 xml_insert_entity ("enddots");
447 else if (docbook)
448 {
449 xml_insert_entity ("hellip");
450 add_char ('.');
451 }
452 else
453 if (html && !in_fixed_width_font)
454 insert_string ("<small class=\"enddots\">....</small>");
455 else
456 add_word ("....");
457 }
458}
459
460void
461cm_bullet (int arg)
462{
463 if (arg == START0)
464 {
465 if (html)
466 add_word ("&bull;");
467 else if (xml && !docbook)
468 xml_insert_entity ("bullet");
469 else if (docbook)
470 xml_insert_entity ("bull");
471 else
472 add_char ('*');
473 }
474}
475
476void
477cm_minus (int arg)
478{
479 if (arg == START0)
480 {
481 if (xml)
482 xml_insert_entity ("minus");
483 else if (html)
484 add_word ("&minus;");
485 else
486 add_char ('-');
487 }
488}
489
490/* Formatting a dimension unit. */
491void
492cm_dmn (int arg)
493{
494 if (html)
495 insert_html_tag_with_attribute (arg, "span", "class=\"dmn\"");
496 else if (docbook)
497 /* No units in docbook yet. */
498 ;
499 else if (xml)
500 xml_insert_element (DIMENSION, arg);
501}
502
503/* Insert "TeX". */
504void
505cm_TeX (int arg)
506{
507 static int last_position;
508
509 if (arg == START0)
510 {
511 if (xml)
512 xml_insert_entity ("tex");
513 else
514 add_word ("TeX");
515
516 last_position = output_paragraph_offset;
517 }
518 else if (last_position != output_paragraph_offset)
519 {
520 warning (_("arguments to @%s ignored")((const char *) ("arguments to @%s ignored")), command);
521 output_paragraph_offset = last_position;
522 }
523}
524
525/* Insert "LaTeX". */
526void
527cm_LaTeX (int arg)
528{
529 static int last_position;
530
531 if (arg == START0)
532 {
533 if (xml)
534 xml_insert_entity ("latex");
535 else
536 add_word ("LaTeX");
537
538 last_position = output_paragraph_offset;
539 }
540 else if (last_position != output_paragraph_offset)
541 {
542 warning (_("arguments to @%s ignored")((const char *) ("arguments to @%s ignored")), command);
543 output_paragraph_offset = last_position;
544 }
545}
546
547/* Copyright symbol. */
548void
549cm_copyright (int arg)
550{
551 if (arg == START0)
552 {
553 if (html)
554 add_word ("&copy;");
555 else if (xml && !docbook)
556 xml_insert_entity ("copyright");
557 else if (docbook)
558 xml_insert_entity ("copy");
559 else
560 add_word ("(C)");
561 }
562}
563
564/* Registered symbol. */
565void
566cm_registeredsymbol (int arg)
567{
568 if (arg == START0)
569 {
570 if (html)
571 add_word ("&reg;");
572 else if (docbook)
573 xml_insert_entity ("reg");
574 else if (xml && !docbook)
575 xml_insert_entity ("registered");
576 else
577 add_word ("(R)");
578 }
579}
580
581void
582cm_today (int arg)
583{
584 static char *months[12] =
585 { N_("January")("January"), N_("February")("February"), N_("March")("March"), N_("April")("April"), N_("May")("May"),
586 N_("June")("June"), N_("July")("July"), N_("August")("August"), N_("September")("September"), N_("October")("October"),
587 N_("November")("November"), N_("December")("December") };
588 if (arg == START0)
589 {
590 time_t timer = time (0);
591 struct tm *ts = localtime (&timer);
592 add_word_args ("%d %s %d", ts->tm_mday, _(months[ts->tm_mon])((const char *) (months[ts->tm_mon])),
593 ts->tm_year + 1900);
594 }
595}
596
597void
598cm_comment (void)
599{
600 /* For HTML, do not output comments before HTML header is written,
601 otherwise comments before @settitle cause an empty <title> in the
602 header. */
603 if ((html && html_output_head_p) || xml)
604 {
605 char *line;
606 get_rest_of_line (0, &line);
607
608 if (strlen (line) > 0)
609 {
610 int save_inhibit_indentation = inhibit_paragraph_indentation;
611 int save_paragraph_is_open = paragraph_is_open;
612 int save_escape_html = escape_html;
613 int save_xml_no_para = xml_no_para;
614 int i;
615
616 inhibit_paragraph_indentation = 1;
617 escape_html = 0;
618 xml_no_para = 1;
619
620 /* @c and @comment can appear between @item and @itemx,
621 @deffn and @deffnx. */
622 xml_dont_touch_items_defs++;
623
624 /* Use insert for HTML, and XML when indentation is enabled.
625 For Docbook, use add_char. */
626 if (xml && xml_indentation_increment > 0
627 && output_paragraph_offset > 0
628 && output_paragraph[output_paragraph_offset-1] != '\n')
629 insert ('\n');
630
631 /* Crunch double hyphens in comments. */
632 add_html_block_elt ("<!-- ");
633 for (i = 0; i < strlen (line); i++)
634 if (line[i] != '-' || (i && line[i-1] != '-'))
635 add_char (line[i]);
636 add_word (" -->");
637
638 if (html)
639 add_char ('\n');
640
641 inhibit_paragraph_indentation = save_inhibit_indentation;
642 paragraph_is_open = save_paragraph_is_open;
643 escape_html = save_escape_html;
644 xml_no_para = save_xml_no_para;
645 xml_dont_touch_items_defs--;
646 }
647
648 free (line);
649 }
650 else
651 cm_ignore_line ();
652}
653
654
655
656/* We keep acronyms with two arguments around, to be able to refer to them
657 later with only one argument. */
658static ACRONYM_DESC *acronyms_stack = NULL((void *)0);
659
660static void
661cm_acronym_or_abbr (int arg, int is_abbr)
662{
663 char *aa, *description;
664 unsigned len;
665
666 /* We do everything at START. */
667 if (arg == END1)
668 return;
669
670 get_until_in_braces (",", &aa);
671 if (input_text[input_text_offset] == ',')
672 input_text_offset++;
673 get_until_in_braces ("}", &description);
674
675 canon_white (aa);
676 canon_white (description);
677
678 /* If not enclosed in braces, strip after comma to be compatible
679 with texinfo.tex. */
680 if (description[0] != '{' && strchr (description, ',') != NULL((void *)0))
681 {
682 int i = 0;
683 while (description[i] != ',')
684 i++;
685 /* For now, just terminate the string at comma. */
686 description[i] = 0;
687 }
688
689 /* Get description out of braces. */
690 if (description[0] == '{')
691 description++;
692
693 len = strlen (description);
694 if (len && description[len-1] == '}')
695 description[len-1] = 0;
696
697 /* Save new description. */
698 if (strlen (description) > 0)
699 {
700 ACRONYM_DESC *new = xmalloc (sizeof (ACRONYM_DESC));
701
702 new->acronym = xstrdup (aa);
703 new->description = xstrdup (description);
704 new->next = acronyms_stack;
705 acronyms_stack = new;
706 }
707
708 if (html)
709 {
710 add_word (is_abbr ? "<abbr" : "<acronym");
711
712 if (strlen (description) > 0)
713 add_word_args (" title=\"%s\"", text_expansion (description));
714 else if (acronyms_stack)
715 {
716 /* No second argument, get from previous. Search order is from
717 last to first defined, so we get the most recent version of
718 the description. */
719 ACRONYM_DESC *temp = acronyms_stack;
720
721 while (temp)
722 {
723 if (STREQ (aa, temp->acronym)(strcmp (aa, temp->acronym) == 0)
724 && strlen (temp->description) > 0)
725 {
726 add_word_args (" title=\"%s\"",
727 text_expansion (temp->description));
728 break;
729 }
730 temp = temp->next;
731 }
732 }
733
734 add_char ('>');
735 execute_string ("%s", aa);
736 add_word (is_abbr ? "</abbr>" : "</acronym>");
737 }
738 else if (docbook)
739 {
740 xml_insert_element (is_abbr ? ABBREV : ACRONYM, START0);
741 execute_string ("%s", aa);
742 xml_insert_element (is_abbr ? ABBREV : ACRONYM, END1);
743 }
744 else if (xml)
745 {
746 xml_insert_element (is_abbr ? ABBREV : ACRONYM, START0);
747
748 xml_insert_element (is_abbr ? ABBREVWORD : ACRONYMWORD, START0);
749 execute_string ("%s", aa);
750 xml_insert_element (is_abbr ? ABBREVWORD : ACRONYMWORD, END1);
751
752 if (strlen (description) > 0)
753 {
754 xml_insert_element (is_abbr ? ABBREVDESC : ACRONYMDESC, START0);
755 execute_string ("%s", description);
756 xml_insert_element (is_abbr ? ABBREVDESC : ACRONYMDESC, END1);
757 }
758
759 xml_insert_element (is_abbr ? ABBREV : ACRONYM, END1);
760 }
761 else
762 execute_string ("%s", aa);
763
764 /* Put description into parenthesis after the acronym for all outputs
765 except XML. */
766 if (strlen (description) > 0 && (!xml || docbook))
767 add_word_args (" (%s)", description);
768}
769
770void
771cm_acronym (int arg)
772{
773 cm_acronym_or_abbr (arg, 0);
774}
775
776void
777cm_abbr (int arg)
778{
779 cm_acronym_or_abbr (arg, 1);
780}
781
782void
783cm_tt (int arg)
784{
785 /* @t{} is a no-op in Info. */
786 if (html)
787 insert_html_tag (arg, "tt");
788 else if (xml)
789 xml_insert_element (TT, arg);
790}
791
792void
793cm_code (int arg)
794{
795 if (arg == START0)
796 in_fixed_width_font++;
797
798 if (xml)
799 {
800 if (STREQ (command, "command")(strcmp (command, "command") == 0))
801 xml_insert_element (COMMAND_TAG, arg);
802 else if (STREQ (command, "env")(strcmp (command, "env") == 0))
803 xml_insert_element (ENV, arg);
804 else if (STREQ (command, "file")(strcmp (command, "file") == 0))
805 xml_insert_element (FILE_TAG, arg);
806 else if (STREQ (command, "option")(strcmp (command, "option") == 0))
807 xml_insert_element (OPTION, arg);
808 else if (STREQ (command, "samp")(strcmp (command, "samp") == 0))
809 {
810 if (docbook && arg == START0)
811 {
812 /* Even though @samp is in_fixed_width_font, it
813 should always start a paragraph. Unfortunately,
814 in_fixed_width_font inhibits that. */
815 xml_start_para ();
816 xml_insert_entity ("lsquo");
817 }
818 xml_insert_element (SAMP, arg);
819 if (docbook && arg == END1)
820 xml_insert_entity ("rsquo");
821 }
822 else
823 xml_insert_element (CODE, arg);
824 }
825 else if (html)
826 {
827 if (STREQ (command, "code")(strcmp (command, "code") == 0))
828 insert_html_tag (arg, "code");
829 else
830 { /* Use <samp> tag in general to get typewriter. */
831 if (arg == START0)
832 { /* If @samp specifically, add quotes a la TeX output. */
833 if (STREQ (command, "samp")(strcmp (command, "samp") == 0)) add_char ('`');
834 add_word ("<samp>");
835 }
836 insert_html_tag_with_attribute (arg, "span", "class=\"%s\"",command);
837 if (arg == END1)
838 {
839 add_word ("</samp>");
840 if (STREQ (command, "samp")(strcmp (command, "samp") == 0)) add_char ('\'');
841 }
842 }
843 }
844 else
845 {
846 extern int printing_index;
847
848 if (!printing_index)
849 {
850 if (arg == START0)
851 add_char ('`');
852 else
853 add_meta_char ('\'');
854 }
855 }
856}
857
858void
859cm_kbd (int arg)
860{
861 if (xml)
862 xml_insert_element (KBD, arg);
863 else if (html)
864 { /* Seems like we should increment in_fixed_width_font for Info
865 format too, but then the quote-omitting special case gets
866 confused. Punt. */
867 if (arg == START0)
868 in_fixed_width_font++;
869 insert_html_tag (arg, "kbd");
870 }
871 else
872 { /* People use @kbd in an example to get the "user input" font.
873 We don't want quotes in that case. */
874 if (!in_fixed_width_font)
875 cm_code (arg);
876 }
877}
878
879/* Just show a url (http://example.org/..., for example), don't link to it. */
880void
881cm_indicate_url (int arg, int start, int end)
882{
883 if (xml)
884 xml_insert_element (URL, arg);
885 else if (html)
886 {
887 if (arg == START0)
888 add_word ("&lt;");
889 insert_html_tag (arg, "code");
890 if (arg != START0)
891 add_word ("&gt;");
892 }
893 else
894 if (arg == START0)
895 add_word ("<");
896 else
897 add_word (">");
898}
899
900void
901cm_key (int arg)
902{
903 if (xml)
904 xml_insert_element (KEY, arg);
905 else if (html)
906 add_word (arg == START0 ? "&lt;" : "&gt;");
907 else
908 add_char (arg == START0 ? '<' : '>');
909}
910
911/* Handle a command that switches to a non-fixed-width font. */
912void
913not_fixed_width (int arg)
914{
915 if (arg == START0)
916 in_fixed_width_font = 0;
917}
918
919/* @var in makeinfo just uppercases the text. */
920void
921cm_var (int arg, int start_pos, int end_pos)
922{
923 if (xml)
924 xml_insert_element (VAR, arg);
925 else
926 {
927 not_fixed_width (arg);
928
929 if (html)
930 insert_html_tag (arg, "var");
931 else if (arg == END1)
932 {
933 while (start_pos < end_pos)
934 {
935 unsigned char c = output_paragraph[start_pos];
936 if (strchr ("[](),", c))
937 warning (_("unlikely character %c in @var")((const char *) ("unlikely character %c in @var")), c);
938 output_paragraph[start_pos] = coerce_to_upper (c)((islower(c) ? toupper(c) : (c)));
939 start_pos++;
940 }
941 }
942 }
943}
944
945void
946cm_sc (int arg, int start_pos, int end_pos)
947{
948 if (xml)
949 xml_insert_element (SC, arg);
950 else
951 {
952 not_fixed_width (arg);
953
954 if (arg == START0)
955 {
956 if (html)
957 insert_html_tag_with_attribute (arg, "span", "class=\"sc\"");
958 }
959 else
960 {
961 int all_upper;
962
963 if (html)
964 start_pos += sizeof ("<span class=\"sc\">") - 1; /* skip <span> */
965
966 /* Avoid the warning below if there's no text inside @sc{}, or
967 when processing menus under --no-headers. */
968 all_upper = start_pos < end_pos;
969
970 while (start_pos < end_pos)
971 {
972 unsigned char c = output_paragraph[start_pos];
973 if (!isupper (c)((c) >= 'A' && (c) <= 'Z'))
974 all_upper = 0;
975 if (!html)
976 output_paragraph[start_pos] = coerce_to_upper (c)((islower(c) ? toupper(c) : (c)));
977 start_pos++;
978 }
979 if (all_upper)
980 warning (_("@sc argument all uppercase, thus no effect")((const char *) ("@sc argument all uppercase, thus no effect"
))
);
981
982 if (html)
983 insert_html_tag (arg, "span");
984 }
985 }
986}
987
988void
989cm_dfn (int arg, int position)
990{
991 if (xml)
992 xml_insert_element (DFN, arg);
993 else
994 {
995 if (html)
996 insert_html_tag (arg, "dfn");
997 else if (arg == START0)
998 add_char ('"');
999 else
1000 add_meta_char ('"');
1001 }
1002}
1003
1004void
1005cm_emph (int arg)
1006{
1007 if (xml)
1008 xml_insert_element (EMPH, arg);
1009 else if (html)
1010 insert_html_tag (arg, "em");
1011 else
1012 add_char ('_');
1013}
1014
1015void
1016cm_verb (int arg)
1017{
1018 int character;
1019 int delimiter = 0; /* avoid warning */
1020 int seen_end = 0;
1021
1022 in_fixed_width_font++;
1023 /* are these necessary ? */
1024 last_char_was_newline = 0;
1025
1026 if (html)
1027 add_word ("<tt>");
1028
1029 if (input_text_offset < input_text_length)
1030 {
1031 character = curchar ()input_text[input_text_offset];
1032 if (character == '{')
1033 input_text_offset++;
1034 else
1035 line_error (_("`{' expected, but saw `%c'")((const char *) ("`{' expected, but saw `%c'")), character);
1036 }
1037
1038 if (input_text_offset < input_text_length)
1039 {
1040 delimiter = curchar ()input_text[input_text_offset];
1041 input_text_offset++;
1042 }
1043
1044 while (input_text_offset < input_text_length)
1045 {
1046 character = curchar ()input_text[input_text_offset];
1047
1048 if (character == '\n')
1049 {
1050 line_number++;
1051 if (html)
1052 add_word ("<br>\n");
1053 }
1054
1055 else if (html && character == '<')
1056 add_word ("&lt;");
1057
1058 else if (html && character == '&')
1059 add_word ("&amp;");
1060
1061 else if (character == delimiter && input_text[input_text_offset+1] == '}')
1062 { /* Assume no newlines in END_VERBATIM. */
1063 seen_end = 1;
1064 input_text_offset++;
1065 break;
1066 }
1067
1068 else
1069 add_char (character);
1070
1071 input_text_offset++;
1072 }
1073
1074 if (!seen_end)
1075 warning (_("end of file inside verb block")((const char *) ("end of file inside verb block")));
1076
1077 if (input_text_offset < input_text_length)
1078 {
1079 character = curchar ()input_text[input_text_offset];
1080 if (character == '}')
1081 input_text_offset++;
1082 else
1083 line_error (_("`}' expected, but saw `%c'")((const char *) ("`}' expected, but saw `%c'")), character);
1084 }
1085
1086 if (html)
1087 add_word ("</tt>");
1088
1089 in_fixed_width_font--;
1090}
1091
1092
1093void
1094cm_strong (int arg, int start_pos, int end_pos)
1095{
1096 if (docbook && arg == START0)
1097 xml_insert_element_with_attribute (B, arg, "role=\"bold\"");
1098 else if (xml)
1099 xml_insert_element (STRONG, arg);
1100 else if (html)
1101 insert_html_tag (arg, "strong");
1102 else
1103 add_char ('*');
1104
1105 if (!xml && !html && !docbook && !no_headers
1106 && arg == END1
1107 && end_pos - start_pos >= 6
1108 && (STRNCASEEQ ((char *) output_paragraph + start_pos, "*Note:", 6)(strncasecmp ((char *) output_paragraph + start_pos, "*Note:"
, 6) == 0)
1109 || STRNCASEEQ ((char *) output_paragraph + start_pos, "*Note ", 6)(strncasecmp ((char *) output_paragraph + start_pos, "*Note "
, 6) == 0)
))
1110 {
1111 /* Translators: "Note:" is literal here and should not be
1112 translated. @strong{Nota}, say, does not cause the problem. */
1113 warning (_("@strong{Note...} produces a spurious cross-reference in Info; reword to avoid that")((const char *) ("@strong{Note...} produces a spurious cross-reference in Info; reword to avoid that"
))
);
1114 /* Adjust the output to avoid writing the bad xref. */
1115 output_paragraph[start_pos + 5] = '_';
1116 }
1117}
1118
1119void
1120cm_cite (int arg, int position)
1121{
1122 if (xml)
1123 xml_insert_element (CITE, arg);
1124 else if (html)
1125 insert_html_tag (arg, "cite");
1126 else
1127 {
1128 if (arg == START0)
1129 add_char ('`');
1130 else
1131 add_char ('\'');
1132 }
1133}
1134
1135/* No highlighting, but argument switches fonts. */
1136void
1137cm_not_fixed_width (int arg, int start, int end)
1138{
1139 if (xml)
1140 xml_insert_element (NOTFIXEDWIDTH, arg);
1141 not_fixed_width (arg);
1142}
1143
1144void
1145cm_i (int arg)
1146{
1147 /* Make use of <lineannotation> of Docbook, if we are
1148 inside an @example or similar. */
1149 extern int printing_index;
1150 if (docbook && !filling_enabled && !printing_index)
1151 xml_insert_element (LINEANNOTATION, arg);
1152 else if (xml)
1153 xml_insert_element (I, arg);
1154 else if (html)
1155 insert_html_tag (arg, "i");
1156 else
1157 not_fixed_width (arg);
1158}
1159
1160void
1161cm_slanted (int arg)
1162{
1163 /* Make use of <lineannotation> of Docbook, if we are
1164 inside an @example or similar. */
1165 extern int printing_index;
1166 if (docbook && !filling_enabled && !printing_index)
1167 xml_insert_element (LINEANNOTATION, arg);
1168 else if (xml)
1169 xml_insert_element (SLANTED, arg);
1170 else if (html)
1171 insert_html_tag (arg, "i");
1172 else
1173 not_fixed_width (arg);
1174}
1175
1176void
1177cm_b (int arg)
1178{
1179 /* See cm_i comments. */
1180 extern int printing_index;
1181 if (docbook && !filling_enabled && !printing_index)
1182 xml_insert_element (LINEANNOTATION, arg);
1183 else if (docbook && arg == START0)
1184 xml_insert_element_with_attribute (B, arg, "role=\"bold\"");
1185 else if (xml)
1186 xml_insert_element (B, arg);
1187 else if (html)
1188 insert_html_tag (arg, "b");
1189 else
1190 not_fixed_width (arg);
1191}
1192
1193void
1194cm_r (int arg)
1195{
1196 /* See cm_i comments. */
1197 extern int printing_index;
1198 if (docbook && !filling_enabled && !printing_index)
1199 xml_insert_element (LINEANNOTATION, arg);
1200 else if (xml)
1201 xml_insert_element (R, arg);
1202 else if (html)
1203 insert_html_tag_with_attribute (arg, "span", "class=\"roman\"");
1204 else
1205 not_fixed_width (arg);
1206}
1207
1208void
1209cm_sansserif (int arg)
1210{
1211 /* See cm_i comments. */
1212 extern int printing_index;
1213 if (docbook && !filling_enabled && !printing_index)
1214 xml_insert_element (LINEANNOTATION, arg);
1215 else if (xml)
1216 xml_insert_element (SANSSERIF, arg);
1217 else if (html)
1218 insert_html_tag_with_attribute (arg, "span", "class=\"sansserif\"");
1219 else
1220 not_fixed_width (arg);
1221}
1222
1223void
1224cm_titlefont (int arg)
1225{
1226 if (xml)
1227 xml_insert_element (TITLEFONT, arg);
1228 else
1229 {
1230 not_fixed_width (arg);
1231 if (html)
1232 {
1233 html_title_written = 1; /* suppress title from @settitle */
1234 if (arg == START0)
1235 add_word ("<h1 class=\"titlefont\">");
1236 else
1237 add_word ("</h1>\n");
1238 }
1239 }
1240}
1241
1242
1243/* Unfortunately, we cannot interpret @math{} contents like TeX does. We just
1244 pass them through. */
1245void
1246cm_math (int arg)
1247{
1248 if (xml && !docbook)
1249 xml_insert_element (MATH, arg);
1250}
1251
1252/* Various commands are no-op's. */
1253void
1254cm_no_op (void)
1255{
1256}
1257
1258
1259/* For proofing single chapters, etc. */
1260void
1261cm_novalidate (void)
1262{
1263 validating = 0;
1264}
1265
1266
1267/* Prevent the argument from being split across two lines. */
1268void
1269cm_w (int arg)
1270{
1271 if (arg == START0)
1272 non_splitting_words++;
1273 else
1274 {
1275 if (docbook || html || xml)
1276 /* This is so @w{$}Log$ doesn't end up as <dollar>Log<dollar>
1277 in the output. */
1278 insert_string ("<!-- /@w -->");
1279
1280 non_splitting_words--;
1281 }
1282}
1283
1284
1285/* An unbreakable word space. Same as @w{ } for makeinfo, but different
1286 for TeX (the space stretches and stretches, and does not inhibit
1287 hyphenation). */
1288void
1289cm_tie (int arg)
1290{
1291 if (arg == START0)
1292 {
1293 cm_w (START0);
1294 add_char (' ');
1295 }
1296 else
1297 cm_w (END1);
1298}
1299
1300/* Explain that this command is obsolete, thus the user shouldn't
1301 do anything with it. */
1302static void
1303cm_obsolete (int arg, int start, int end)
1304{
1305 if (arg == START0)
1306 warning (_("%c%s is obsolete")((const char *) ("%c%s is obsolete")), COMMAND_PREFIX'@', command);
1307}
1308
1309
1310/* Inhibit the indentation of the next paragraph, but not of following
1311 paragraphs. */
1312void
1313cm_noindent (void)
1314{
1315 if (!inhibit_paragraph_indentation)
1316 inhibit_paragraph_indentation = -1;
1317}
1318
1319void
1320cm_noindent_cmd (void)
1321{
1322 cm_noindent ();
1323 xml_no_indent = 1;
1324 skip_whitespace_and_newlines()do { while (input_text_offset != input_text_length &&
(((input_text[input_text_offset]) == '\t' || (input_text[input_text_offset
]) == ' ') || (input_text[input_text_offset]) == '\r' || (input_text
[input_text_offset]) == '\n')) { if (input_text[input_text_offset
] == '\n') line_number++; input_text_offset++; } } while (0)
;
1325
1326 if (xml)
1327 xml_start_para ();
1328 else if (html && !paragraph_is_open)
1329 add_html_block_elt ("<p class=\"noindent\">");
1330 else
1331 {
1332 paragraph_is_open = 0;
1333 start_paragraph ();
1334 }
1335}
1336
1337/* Force indentation of the next paragraph. */
1338void
1339cm_indent (void)
1340{
1341 inhibit_paragraph_indentation = 0;
1342 xml_no_indent = 0;
1343 skip_whitespace_and_newlines()do { while (input_text_offset != input_text_length &&
(((input_text[input_text_offset]) == '\t' || (input_text[input_text_offset
]) == ' ') || (input_text[input_text_offset]) == '\r' || (input_text
[input_text_offset]) == '\n')) { if (input_text[input_text_offset
] == '\n') line_number++; input_text_offset++; } } while (0)
;
1344
1345 if (xml)
1346 xml_start_para ();
1347 else if (html && !paragraph_is_open)
1348 add_html_block_elt ("<p class=\"indent\">");
1349 else
1350 start_paragraph ();
1351}
1352
1353/* I don't know exactly what to do with this. Should I allow
1354 someone to switch filenames in the middle of output? Since the
1355 file could be partially written, this doesn't seem to make sense.
1356 Another option: ignore it, since they don't really want to
1357 switch files. Finally, complain, or at least warn. It doesn't
1358 really matter, anyway, since this doesn't get executed. */
1359void
1360cm_setfilename (void)
1361{
1362 char *filename;
1363 get_rest_of_line (1, &filename);
1364 /* warning ("`@%s %s' encountered and ignored", command, filename); */
1365 if (xml)
1366 add_word_args ("<setfilename>%s</setfilename>", filename);
1367 free (filename);
1368}
1369
1370void
1371cm_settitle (void)
1372{
1373 if (xml)
1374 {
1375 xml_begin_document (current_output_filename);
1376 xml_insert_element (SETTITLE, START0);
1377 xml_in_book_title = 1;
1378 get_rest_of_line (0, &title);
1379 execute_string ("%s", title);
1380 xml_in_book_title = 0;
1381 xml_insert_element (SETTITLE, END1);
1382 }
1383 else
1384 get_rest_of_line (0, &title);
1385}
1386
1387
1388/* Ignore argument in braces. */
1389void
1390cm_ignore_arg (int arg, int start_pos, int end_pos)
1391{
1392 if (arg == END1)
1393 output_paragraph_offset = start_pos;
1394}
1395
1396/* Ignore argument on rest of line. */
1397void
1398cm_ignore_line (void)
1399{
1400 discard_until ("\n");
1401}
1402
1403/* Insert the number of blank lines passed as argument. */
1404void
1405cm_sp (void)
1406{
1407 int lines;
1408 char *line;
1409
1410 /* Due to tricky stuff in execute_string(), @value{} can't be expanded.
1411 So there is really no reason to enable expansion for @sp parameters. */
1412 get_rest_of_line (0, &line);
1413
1414 if (sscanf (line, "%d", &lines) != 1 || lines <= 0)
1415 line_error (_("@sp requires a positive numeric argument, not `%s'")((const char *) ("@sp requires a positive numeric argument, not `%s'"
))
, line);
1416 else
1417 {
1418 if (xml)
1419 {
1420 /* @sp can appear between @item and @itemx, @deffn and @deffnx. */
1421 xml_dont_touch_items_defs++;
1422 xml_insert_element_with_attribute (SP, START0, "lines=\"%s\"", line);
1423 /* insert_string (line);*/
1424 xml_insert_element (SP, END1);
1425 xml_dont_touch_items_defs--;
1426 }
1427 else
1428 {
1429 /* Must disable filling since otherwise multiple newlines is like
1430 multiple spaces. Must close paragraph since that's what the
1431 manual says and that's what TeX does. */
1432 int save_filling_enabled = filling_enabled;
1433 filling_enabled = 0;
1434
1435 /* close_paragraph generates an extra blank line. */
1436 close_single_paragraph ();
1437
1438 if (lines && html && !executing_string)
1439 html_output_head ();
1440
1441 if (html)
1442 add_html_block_elt ("<pre class=\"sp\">\n");
1443
1444 while (lines--)
1445 add_char ('\n');
1446
1447 if (html)
1448 add_html_block_elt ("</pre>\n");
1449
1450 filling_enabled = save_filling_enabled;
1451 }
1452 }
1453 free (line);
1454}
1455
1456/* @dircategory LINE outputs INFO-DIR-SECTION LINE, unless --no-headers. */
1457void
1458cm_dircategory (void)
1459{
1460 char *line;
1461
1462 if (html || docbook)
1463 cm_ignore_line ();
1464 else if (xml)
1465 {
1466 xml_insert_element (DIRCATEGORY, START0);
1467 get_rest_of_line (1, &line);
1468 insert_string (line);
1469 free (line);
1470 xml_insert_element (DIRCATEGORY, END1);
1471 }
1472 else
1473 {
1474 get_rest_of_line (1, &line);
1475
1476 if (!no_headers && !html)
1477 {
1478 kill_self_indent (-1); /* make sure there's no indentation */
1479 insert_string ("INFO-DIR-SECTION ");
1480 insert_string (line);
1481 insert ('\n');
1482 }
1483
1484 free (line);
1485 }
1486}
1487
1488/* Start a new line with just this text on it.
1489 Then center the line of text.
1490 */
1491void
1492cm_center (void)
1493{
1494 if (xml)
1495 {
1496 char *line;
1497 xml_insert_element (CENTER, START0);
1498 get_rest_of_line (0, &line);
1499 execute_string ("%s", line);
1500 free (line);
1501 xml_insert_element (CENTER, END1);
1502 }
1503 else
1504 {
1505 int i, start, length;
1506 char *line;
1507 int save_indented_fill = indented_fill;
1508 int save_filling_enabled = filling_enabled;
1509 int fudge_factor = 1;
1510
1511 filling_enabled = indented_fill = 0;
1512 cm_noindent ();
1513 start = output_paragraph_offset;
1514
1515 if (html)
1516 add_html_block_elt ("<div align=\"center\">");
1517
1518 inhibit_output_flushing ();
1519 get_rest_of_line (0, &line);
1520 execute_string ("%s", line);
1521 free (line);
1522 uninhibit_output_flushing ();
1523 if (html)
1524 add_html_block_elt ("</div>");
1525
1526 else
1527 {
1528 i = output_paragraph_offset - 1;
1529 while (i > (start - 1) && output_paragraph[i] == '\n')
1530 i--;
1531
1532 output_paragraph_offset = ++i;
1533 length = output_paragraph_offset - start;
1534
1535 if (length < (fill_column - fudge_factor))
1536 {
1537 line = xmalloc (1 + length);
1538 memcpy (line, (char *)(output_paragraph + start), length);
1539
1540 i = (fill_column - fudge_factor - length) / 2;
1541 output_paragraph_offset = start;
1542
1543 while (i--)
1544 insert (' ');
1545
1546 for (i = 0; i < length; i++)
1547 insert (line[i]);
1548
1549 free (line);
1550 }
1551 }
1552
1553 insert ('\n');
1554 filling_enabled = save_filling_enabled;
1555 indented_fill = save_indented_fill;
1556 close_single_paragraph ();
1557 if (looking_at("\n")(strncmp (input_text + input_text_offset, "\n", strlen ("\n")
) == 0)
)
1558 insert ('\n');
1559 }
1560}
1561
1562/* Show what an expression returns. */
1563void
1564cm_result (int arg)
1565{
1566 if (arg == END1)
1567 add_word (html ? "=&gt;" : "=>");
1568}
1569
1570/* What an expression expands to. */
1571void
1572cm_expansion (int arg)
1573{
1574 if (arg == END1)
1575 add_word (html ? "==&gt;" : "==>");
1576}
1577
1578/* Indicates two expressions are equivalent. */
1579void
1580cm_equiv (int arg)
1581{
1582 if (arg == END1)
1583 add_word ("==");
1584}
1585
1586/* What an expression may print. */
1587void
1588cm_print (int arg)
1589{
1590 if (arg == END1)
1591 add_word ("-|");
1592}
1593
1594/* An error signaled. */
1595void
1596cm_error (int arg)
1597{
1598 if (arg == END1)
1599 add_word (html ? "error--&gt;" : "error-->");
1600}
1601
1602/* The location of point in an example of a buffer. */
1603void
1604cm_point (int arg)
1605{
1606 if (arg == END1)
1607 add_word ("-!-");
1608}
1609
1610/* @exdent: Start a new line with just this text on it.
1611 The text is outdented one level if possible. */
1612void
1613cm_exdent (void)
1614{
1615 char *line;
1616 int save_indent = current_indent;
1617 int save_in_fixed_width_font = in_fixed_width_font;
1618
1619 /* Read argument. */
1620 get_rest_of_line (0, &line);
1621
1622 /* Exdent the output. Actually this may be a no-op. */
1623 if (current_indent)
1624 current_indent -= default_indentation_increment;
1625
1626 /* @exdent arg is supposed to be in roman. */
1627 in_fixed_width_font = 0;
1628
1629 /* The preceding newline already inserted the `current_indent'.
1630 Remove one level's worth. */
1631 kill_self_indent (default_indentation_increment);
1632
1633 if (html)
1634 add_word ("<br>");
1635 else if (docbook)
1636 xml_insert_element (LINEANNOTATION, START0);
1637 else if (xml)
1638 xml_insert_element (EXDENT, START0);
1639
1640 /* Can't close_single_paragraph, then we lose preceding blank lines. */
1641 flush_output ();
1642 execute_string ("%s", line);
1643 free (line);
1644
1645 if (html)
1646 add_word ("<br>");
1647 else if (xml)
1648 {
1649 xml_insert_element (docbook ? LINEANNOTATION : EXDENT, END1);
1650 insert ('\n');
1651 }
1652
1653 close_single_paragraph ();
1654
1655 current_indent = save_indent;
1656 in_fixed_width_font = save_in_fixed_width_font;
1657 if (!xml)
1658 start_paragraph ();
1659}
1660
1661/*
1662 Read include-filename, process the include-file:
1663 verbatim_include == 0: process through reader_loop
1664 verbatim_include != 0: process through handle_verbatim_environment
1665 */
1666static void
1667handle_include (int verbatim_include)
1668{
1669 char *arg, *filename;
1670
1671 if (macro_expansion_output_stream && !executing_string)
1672 me_append_before_this_command ();
1673
1674 if (!insertion_stack)
1675 close_paragraph (); /* No blank lines etc. if not at outer level. */
1676
1677 get_rest_of_line (0, &arg);
1678 /* We really only want to expand @value, but it's easier to just do
1679 everything. TeX will only work with @value. */
1680 filename = text_expansion (arg);
1681 free (arg);
1682
1683 if (macro_expansion_output_stream && !executing_string)
1684 remember_itext (input_text, input_text_offset);
1685
1686 pushfile ();
1687
1688 /* In verbose mode we print info about including another file. */
1689 if (verbose_mode)
1690 {
1691 int i = 0;
1692 FSTACK *stack = filestack;
Value stored to 'stack' during its initialization is never read
1693
1694 for (i = 0, stack = filestack; stack; stack = stack->next, i++);
1695
1696 i *= 2;
1697
1698 printf ("%*s", i, "");
1699 printf ("%c%s `%s'\n", COMMAND_PREFIX'@', command, filename);
1700 fflush (stdout(&__sF[1]));
1701 }
1702
1703 if (!find_and_load (filename, 1))
1704 {
1705 popfile ();
1706 line_number--;
1707
1708 /* /wh/bar:5: @include/@verbatiminclude `foo': No such file or dir */
1709 line_error ("%c%s `%s': %s", COMMAND_PREFIX'@', command, filename,
1710 strerror (errno(*__errno())));
1711
1712 free (filename);
1713 return;
1714 }
1715 else
1716 {
1717 if (macro_expansion_output_stream && !executing_string)
1718 remember_itext (input_text, input_text_offset);
1719
1720 if (!verbatim_include)
1721 reader_loop ();
1722 else
1723 handle_verbatim_environment (0);
1724 }
1725 free (filename);
1726 popfile ();
1727}
1728
1729
1730/* Include file as if put in @verbatim environment */
1731void
1732cm_verbatiminclude (void)
1733{
1734 handle_include (1);
1735}
1736
1737
1738/* Remember this file, and move onto the next. */
1739void
1740cm_include (void)
1741{
1742 handle_include (0);
1743}
1744
1745
1746/* @bye: Signals end of processing. Easy to make this happen. */
1747
1748void
1749cm_bye (void)
1750{
1751 discard_braces (); /* should not have any unclosed braces left */
1752 input_text_offset = input_text_length;
1753}
1754
1755/* @paragraphindent */
1756
1757static void
1758cm_paragraphindent (void)
1759{
1760 char *arg;
1761
1762 get_rest_of_line (1, &arg);
1763 if (set_paragraph_indent (arg) != 0)
1764 line_error (_("Bad argument to %c%s")((const char *) ("Bad argument to %c%s")), COMMAND_PREFIX'@', command);
1765
1766 free (arg);
1767}
1768
1769
1770/* @exampleindent: change indentation of example-like environments. */
1771static int
1772set_example_indentation_increment (char *string)
1773{
1774 if (strcmp (string, "asis") == 0 || strcmp (string, _("asis")((const char *) ("asis"))) == 0)
1775 ;
1776 else if (strcmp (string, "none") == 0 || strcmp (string, _("none")((const char *) ("none"))) == 0)
1777 example_indentation_increment = 0;
1778 else if (sscanf (string, "%d", &example_indentation_increment) != 1)
1779 return -1;
1780 return 0;
1781}
1782
1783static void
1784cm_exampleindent (void)
1785{
1786 char *arg;
1787
1788 get_rest_of_line (1, &arg);
1789 if (set_example_indentation_increment (arg) != 0)
1790 line_error (_("Bad argument to @%s")((const char *) ("Bad argument to @%s")), command);
1791
1792 if (input_text[input_text_offset] == '\n')
1793 close_single_paragraph ();
1794
1795 free (arg);
1796}
1797
1798
1799/* @firstparagraphindent: suppress indentation in first paragraphs after
1800 headings. */
1801static int
1802set_firstparagraphindent (char *string)
1803{
1804 if (STREQ (string, "insert")(strcmp (string, "insert") == 0) || STREQ (string, _("insert"))(strcmp (string, ((const char *) ("insert"))) == 0))
1805 do_first_par_indent = 1;
1806 else if (STREQ (string, "none")(strcmp (string, "none") == 0) || STREQ (string, _("none"))(strcmp (string, ((const char *) ("none"))) == 0))
1807 do_first_par_indent = 0;
1808 else
1809 return -1;
1810 return 0;
1811}
1812
1813static void
1814cm_firstparagraphindent (void)
1815{
1816 char *arg;
1817
1818 get_rest_of_line (1, &arg);
1819 if (set_firstparagraphindent (arg) != 0)
1820 line_error (_("Bad argument to %c%s")((const char *) ("Bad argument to %c%s")), COMMAND_PREFIX'@', command);
1821
1822 free (arg);
1823}
1824
1825/* For DocBook and XML, produce &period; for `.@:'. This gives the processing
1826 software a fighting chance to treat it specially by not adding extra space.
1827
1828 Do this also for ?, !, and :. */
1829void
1830cm_colon (void)
1831{
1832 if (xml)
1833 {
1834 if (strchr (".?!:", input_text[input_text_offset-3]) != NULL((void *)0))
1835 {
1836 /* Erase literal character that's there, except `>', which is
1837 part of the XML tag. */
1838 if (output_paragraph[output_paragraph_offset-1] != '>')
1839 output_paragraph_offset--;
1840
1841 switch (input_text[input_text_offset-3])
1842 {
1843 case '.':
1844 xml_insert_entity ("period");
1845 break;
1846 case '?':
1847 xml_insert_entity ("quest");
1848 break;
1849 case '!':
1850 xml_insert_entity ("excl");
1851 break;
1852 case ':':
1853 xml_insert_entity ("colon");
1854 break;
1855 }
1856 }
1857 }
1858}
1859
1860/* Ending sentences explicitly. Currently, only outputs entities for XML
1861 output, for other formats it calls insert_self. */
1862void
1863cm_punct (int arg)
1864{
1865 if (xml && !docbook)
1866 {
1867 switch (input_text[input_text_offset-1])
1868 {
1869 case '.':
1870 xml_insert_entity ("eosperiod");
1871 break;
1872 case '?':
1873 xml_insert_entity ("eosquest");
1874 break;
1875 case '!':
1876 xml_insert_entity ("eosexcl");
1877 break;
1878 }
1879 }
1880 else
1881 {
1882 insert_self (arg);
1883 }
1884}