Bug Summary

File:src/gnu/usr.bin/texinfo/makeinfo/sectioning.c
Warning:line 413, column 33
1st function call argument is an uninitialized value

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 sectioning.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/sectioning.c
1/* sectioning.c -- for @chapter, @section, ..., @contents ...
2 $Id: sectioning.c,v 1.1.1.3 2006/07/17 16:03:48 espie Exp $
3
4 Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 Originally written by Karl Heinz Marbaise <kama@hippo.fido.de>. */
21
22#include "system.h"
23#include "cmds.h"
24#include "macro.h"
25#include "makeinfo.h"
26#include "node.h"
27#include "toc.h"
28#include "sectioning.h"
29#include "xml.h"
30
31/* See comment in sectioning.h. */
32section_alist_type section_alist[] = {
33 { "unnumberedsubsubsec", 5, ENUM_SECT_NO0, TOC_YES1 },
34 { "unnumberedsubsec", 4, ENUM_SECT_NO0, TOC_YES1 },
35 { "unnumberedsec", 3, ENUM_SECT_NO0, TOC_YES1 },
36 { "unnumbered", 2, ENUM_SECT_NO0, TOC_YES1 },
37 { "centerchap", 2, ENUM_SECT_NO0, TOC_YES1 },
38
39 { "appendixsubsubsec", 5, ENUM_SECT_APP2, TOC_YES1 }, /* numbered like A.X.X.X */
40 { "appendixsubsec", 4, ENUM_SECT_APP2, TOC_YES1 },
41 { "appendixsec", 3, ENUM_SECT_APP2, TOC_YES1 },
42 { "appendixsection", 3, ENUM_SECT_APP2, TOC_YES1 },
43 { "appendix", 2, ENUM_SECT_APP2, TOC_YES1 },
44
45 { "subsubsec", 5, ENUM_SECT_YES1, TOC_YES1 },
46 { "subsubsection", 5, ENUM_SECT_YES1, TOC_YES1 },
47 { "subsection", 4, ENUM_SECT_YES1, TOC_YES1 },
48 { "section", 3, ENUM_SECT_YES1, TOC_YES1 },
49 { "chapter", 2, ENUM_SECT_YES1, TOC_YES1 },
50
51 { "subsubheading", 5, ENUM_SECT_NO0, TOC_NO0 },
52 { "subheading", 4, ENUM_SECT_NO0, TOC_NO0 },
53 { "heading", 3, ENUM_SECT_NO0, TOC_NO0 },
54 { "chapheading", 2, ENUM_SECT_NO0, TOC_NO0 },
55 { "majorheading", 2, ENUM_SECT_NO0, TOC_NO0 },
56
57 { "top", 1, ENUM_SECT_NO0, TOC_YES1 },
58 { NULL((void *)0), 0, 0, 0 }
59};
60
61/* The argument of @settitle, used for HTML. */
62char *title = NULL((void *)0);
63
64
65#define APPENDIX_MAGIC1024 1024
66#define UNNUMBERED_MAGIC2048 2048
67
68/* Number memory for every level @chapter, @section,
69 @subsection, @subsubsection. */
70static int numbers [] = { 0, 0, 0, 0 };
71
72/* enum_marker == APPENDIX_MAGIC then we are counting appendencies
73 enum_marker == UNNUMBERED_MAGIC then we are within unnumbered area.
74 Handling situations like this:
75 @unnumbered ..
76 @section ... */
77static int enum_marker = 0;
78
79/* Organized by level commands. That is, "*" == chapter, "=" == section. */
80static char *scoring_characters = "*=-.";
81
82/* Amount to offset the name of sectioning commands to levels by. */
83static int section_alist_offset = 0;
84
85/* These two variables are for @float, @cindex like commands that need to know
86 in which section they are used. */
87/* Last value returned by get_sectioning_number. */
88static char *last_sectioning_number = "";
89/* Last title used by sectioning_underscore, etc. */
90static char *last_sectioning_title = "";
91
92/* num == ENUM_SECT_NO means unnumbered (should never call this)
93 num == ENUM_SECT_YES means numbered
94 num == ENUM_SECT_APP means numbered like A.1 and so on */
95static char *
96get_sectioning_number (int level, int num)
97{
98 static char s[100]; /* should ever be enough for 99.99.99.99
99 Appendix A.1 */
100
101 char *p;
102 int i;
103
104 s[0] = 0;
105
106 /* create enumeration in front of chapter, section, subsection and so on. */
107 for (i = 0; i < level; i++)
108 {
109 p = s + strlen (s);
110 if ((i == 0) && (enum_marker == APPENDIX_MAGIC1024))
111 sprintf (p, "%c.", numbers[i] + 64); /* Should be changed to
112 be more portable */
113 else
114 sprintf (p, "%d.", numbers[i]);
115 }
116
117 /* the last number is never followed by a dot */
118 p = s + strlen (s);
119 if ((num == ENUM_SECT_APP2)
120 && (i == 0)
121 && (enum_marker == APPENDIX_MAGIC1024))
122 sprintf (p, _("Appendix %c")((const char *) ("Appendix %c")), numbers[i] + 64);
123 else
124 sprintf (p, "%d", numbers[i]);
125
126 /* Poor man's cache :-) */
127 if (strlen (last_sectioning_number))
128 free (last_sectioning_number);
129 last_sectioning_number = xstrdup (s);
130
131 return s;
132}
133
134
135/* Set the level of @top to LEVEL. Return the old level of @top. */
136int
137set_top_section_level (int level)
138{
139 int i, result = -1;
140
141 for (i = 0; section_alist[i].name; i++)
142 if (strcmp (section_alist[i].name, "top") == 0)
143 {
144 result = section_alist[i].level;
145 section_alist[i].level = level;
146 break;
147 }
148 return result;
149}
150
151
152/* return the index of the given sectioning command in section_alist */
153static int
154search_sectioning (char *text)
155{
156 int i;
157 char *t;
158
159 /* ignore the optional command prefix */
160 if (text[0] == COMMAND_PREFIX'@')
161 text++;
162
163 for (i = 0; (t = section_alist[i].name); i++)
164 {
165 if (strcmp (t, text) == 0)
166 {
167 return i;
168 }
169 }
170 return -1;
171}
172
173/* Return an integer which identifies the type of section present in
174 TEXT -- 1 for @top, 2 for chapters, ..., 5 for subsubsections (as
175 specified in section_alist). We take into account any @lowersections
176 and @raisesections. If SECNAME is non-NULL, also return the
177 corresponding section name. */
178int
179what_section (char *text, char **secname)
180{
181 int index, j;
182 char *temp;
183 int return_val;
184
185 find_section_command:
186 for (j = 0; text[j] && cr_or_whitespace (text[j])(((text[j]) == '\t' || (text[j]) == ' ') || (text[j]) == '\r'
|| (text[j]) == '\n')
; j++);
6
Assuming the condition is false
187 if (text[j] != COMMAND_PREFIX'@')
7
Taking true branch
188 return -1;
8
Returning without writing to '*secname'
189
190 text = text + j + 1;
191
192 /* We skip @c, @comment, and @?index commands. */
193 if ((strncmp (text, "comment", strlen ("comment")) == 0) ||
194 (text[0] == 'c' && cr_or_whitespace (text[1])(((text[1]) == '\t' || (text[1]) == ' ') || (text[1]) == '\r'
|| (text[1]) == '\n')
) ||
195 (strcmp (text + 1, "index") == 0))
196 {
197 while (*text++ != '\n');
198 goto find_section_command;
199 }
200
201 /* Handle italicized sectioning commands. */
202 if (*text == 'i')
203 text++;
204
205 for (j = 0; text[j] && !cr_or_whitespace (text[j])(((text[j]) == '\t' || (text[j]) == ' ') || (text[j]) == '\r'
|| (text[j]) == '\n')
; j++);
206
207 temp = xmalloc (1 + j);
208 strncpy (temp, text, j);
209 temp[j] = 0;
210
211 index = search_sectioning (temp);
212 free (temp);
213 if (index >= 0)
214 {
215 return_val = section_alist[index].level + section_alist_offset;
216 if (return_val < 0)
217 return_val = 0;
218 else if (return_val > 5)
219 return_val = 5;
220
221 if (secname)
222 {
223 int i;
224 int alist_size = sizeof (section_alist) / sizeof(section_alist_type);
225 /* Find location of offset sectioning entry, but don't go off
226 either end of the array. */
227 int index_offset = MAX (index - section_alist_offset, 0)((index - section_alist_offset) > (0) ? (index - section_alist_offset
) : (0))
;
228 index_offset = MIN (index_offset, alist_size - 1)((index_offset) < (alist_size - 1) ? (index_offset) : (alist_size
- 1))
;
229
230 /* Also make sure we don't go into the next "group" of
231 sectioning changes, e.g., change from an @appendix to an
232 @heading or some such. */
233#define SIGN(expr)((expr) < 0 ? -1 : 1) ((expr) < 0 ? -1 : 1)
234 for (i = index; i != index_offset; i -= SIGN (section_alist_offset)((section_alist_offset) < 0 ? -1 : 1))
235 {
236 /* As it happens, each group has unique .num/.toc values. */
237 if (section_alist[i].num != section_alist[index_offset].num
238 || section_alist[i].toc != section_alist[index_offset].toc)
239 break;
240 }
241 *secname = section_alist[i].name;
242 }
243 return return_val;
244 }
245 return -1;
246}
247
248/* Returns current top level division (ie. chapter, unnumbered) number.
249 - For chapters, returns the number.
250 - For unnumbered sections, returns empty string.
251 - For appendices, returns A, B, etc. */
252char *
253current_chapter_number (void)
254{
255 if (enum_marker == UNNUMBERED_MAGIC2048)
256 return xstrdup ("");
257 else if (enum_marker == APPENDIX_MAGIC1024)
258 {
259 char s[1];
260 sprintf (s, "%c", numbers[0] + 64);
261 return xstrdup (s);
262 }
263 else
264 {
265 char s[5];
266 sprintf (s, "%d", numbers[0]);
267 return xstrdup (s);
268 }
269}
270
271/* Returns number of the last sectioning command used. */
272char *
273current_sectioning_number (void)
274{
275 if (enum_marker == UNNUMBERED_MAGIC2048 || !number_sections)
276 return xstrdup ("");
277 else
278 return xstrdup (last_sectioning_number);
279}
280
281/* Returns arguments of the last sectioning command used. */
282char *
283current_sectioning_name (void)
284{
285 return xstrdup (last_sectioning_title);
286}
287
288/* insert_and_underscore, sectioning_underscore and sectioning_html call this. */
289
290static char *
291handle_enum_increment (int level, int index)
292{
293 /* Here is how TeX handles enumeration:
294 - Anything starting with @unnumbered is not enumerated.
295 - @majorheading and the like are not enumberated. */
296 int i;
297
298 /* First constraint above. */
299 if (enum_marker == UNNUMBERED_MAGIC2048 && level == 0)
300 return xstrdup ("");
301
302 /* Second constraint. */
303 if (section_alist[index].num == ENUM_SECT_NO0)
304 return xstrdup ("");
305
306 /* reset all counters which are one level deeper */
307 for (i = level; i < 3; i++)
308 numbers [i + 1] = 0;
309
310 numbers[level]++;
311 if (section_alist[index].num == ENUM_SECT_NO0 || enum_marker == UNNUMBERED_MAGIC2048
312 || !number_sections)
313 return xstrdup ("");
314 else
315 return xstrdup (get_sectioning_number (level, section_alist[index].num));
316}
317
318
319void
320sectioning_underscore (char *cmd)
321{
322 char *temp, *secname;
2
'secname' declared without an initial value
323 int level;
324
325 /* If we're not indenting the first paragraph, we shall make it behave
326 like @noindent is called directly after the section heading. */
327 if (! do_first_par_indent)
3
Assuming 'do_first_par_indent' is not equal to 0
4
Taking false branch
328 cm_noindent ();
329
330 temp = xmalloc (2 + strlen (cmd));
331 temp[0] = COMMAND_PREFIX'@';
332 strcpy (&temp[1], cmd);
333 level = what_section (temp, &secname);
5
Calling 'what_section'
9
Returning from 'what_section'
334 level -= 2;
335 if (level
9.1
'level' is < 0
< 0)
10
Taking true branch
336 level = 0;
337 free (temp);
338
339 /* If the argument to @top is empty, we try using the one from @settitle.
340 Warn if both are unusable. */
341 if (STREQ (command, "top")(strcmp (command, "top") == 0))
11
Assuming the condition is false
12
Taking false branch
342 {
343 int save_input_text_offset = input_text_offset;
344
345 get_rest_of_line (0, &temp);
346
347 /* Due to get_rest_of_line ... */
348 line_number--;
349
350 if (strlen (temp) == 0 && (!title || strlen (title) == 0))
351 warning ("Must specify a title with least one of @settitle or @top");
352
353 input_text_offset = save_input_text_offset;
354 }
355
356 if (xml)
13
Assuming 'xml' is not equal to 0
14
Taking true branch
357 {
358 /* If the section appears in the toc, it means it's a real section
359 unlike majorheading, chapheading etc. */
360 if (section_alist[search_sectioning (cmd)].toc == TOC_YES1)
15
Assuming field 'toc' is not equal to TOC_YES
16
Taking false branch
361 {
362 xml_close_sections (level);
363 /* Mark the beginning of the section
364 If the next command is printindex, we will remove
365 the section and put an Index instead */
366 flush_output ();
367 xml_last_section_output_position = output_paragraph_offset;
368
369 get_rest_of_line (0, &temp);
370
371 /* Use @settitle value if @top parameter is empty. */
372 if (STREQ (command, "top")(strcmp (command, "top") == 0) && strlen(temp) == 0)
373 temp = xstrdup (title ? title : "");
374
375 /* Docbook does not support @unnumbered at all. So we provide numbers
376 that other formats use. @appendix seems to be fine though, so we let
377 Docbook handle that as usual. */
378 if (docbook && enum_marker != APPENDIX_MAGIC1024)
379 {
380 if (section_alist[search_sectioning (cmd)].num == ENUM_SECT_NO0
381 && section_alist[search_sectioning (cmd)].toc == TOC_YES1)
382 xml_insert_element_with_attribute (xml_element (secname),
383 START0, "label=\"%s\" xreflabel=\"%s\"",
384 handle_enum_increment (level, search_sectioning (cmd)),
385 text_expansion (temp));
386 else
387 xml_insert_element_with_attribute (xml_element (secname),
388 START0, "label=\"%s\"",
389 handle_enum_increment (level, search_sectioning (cmd)));
390 }
391 else
392 xml_insert_element (xml_element (secname), START0);
393
394 xml_insert_element (TITLE, START0);
395 xml_open_section (level, secname);
396 execute_string ("%s", temp);
397 xml_insert_element (TITLE, END1);
398
399 free (temp);
400 }
401 else
402 {
403 if (docbook)
17
Assuming 'docbook' is 0
18
Taking false branch
404 {
405 if (level > 0)
406 xml_insert_element_with_attribute (xml_element (secname), START0,
407 "renderas=\"sect%d\"", level);
408 else
409 xml_insert_element_with_attribute (xml_element (secname), START0,
410 "renderas=\"other\"");
411 }
412 else
413 xml_insert_element (xml_element (secname), START0);
19
1st function call argument is an uninitialized value
414
415 get_rest_of_line (0, &temp);
416 execute_string ("%s", temp);
417 free (temp);
418
419 xml_insert_element (xml_element (secname), END1);
420 }
421 }
422 else if (html)
423 sectioning_html (level, secname);
424 else
425 insert_and_underscore (level, secname);
426}
427
428
429/* Insert the text following input_text_offset up to the end of the line
430 in a new, separate paragraph. Directly underneath it, insert a
431 line of WITH_CHAR, the same length of the inserted text. */
432void
433insert_and_underscore (int level, char *cmd)
434{
435 int i, len;
436 int index;
437 int old_no_indent;
438 unsigned char *starting_pos, *ending_pos;
439 char *temp;
440 char with_char = scoring_characters[level];
441
442 close_paragraph ();
443 filling_enabled = indented_fill = 0;
444 old_no_indent = no_indent;
445 no_indent = 1;
446
447 if (macro_expansion_output_stream && !executing_string)
448 append_to_expansion_output (input_text_offset + 1);
449
450 get_rest_of_line (0, &temp);
451
452 /* Use @settitle value if @top parameter is empty. */
453 if (STREQ (command, "top")(strcmp (command, "top") == 0) && strlen(temp) == 0)
454 temp = xstrdup (title ? title : "");
455
456 starting_pos = output_paragraph + output_paragraph_offset;
457
458 /* Poor man's cache for section title. */
459 if (strlen (last_sectioning_title))
460 free (last_sectioning_title);
461 last_sectioning_title = xstrdup (temp);
462
463 index = search_sectioning (cmd);
464 if (index < 0)
465 {
466 /* should never happen, but a poor guy, named Murphy ... */
467 warning (_("Internal error (search_sectioning) `%s'!")((const char *) ("Internal error (search_sectioning) `%s'!")), cmd);
468 return;
469 }
470
471 /* This is a bit tricky: we must produce "X.Y SECTION-NAME" in the
472 Info output and in TOC, but only SECTION-NAME in the macro-expanded
473 output. */
474
475 /* Step 1: produce "X.Y" and add it to Info output. */
476 add_word_args ("%s ", handle_enum_increment (level, index));
477
478 /* Step 2: add "SECTION-NAME" to both Info and macro-expanded output. */
479 if (macro_expansion_output_stream && !executing_string)
480 {
481 char *temp1 = xmalloc (2 + strlen (temp));
482 sprintf (temp1, "%s\n", temp);
483 remember_itext (input_text, input_text_offset);
484 me_execute_string (temp1);
485 free (temp1);
486 }
487 else
488 execute_string ("%s\n", temp);
489
490 /* Step 3: pluck "X.Y SECTION-NAME" from the output buffer and
491 insert it into the TOC. */
492 ending_pos = output_paragraph + output_paragraph_offset;
493 if (section_alist[index].toc == TOC_YES1)
494 toc_add_entry (substring (starting_pos, ending_pos - 1),
495 level, current_node, NULL((void *)0));
496
497 free (temp);
498
499 len = (ending_pos - starting_pos) - 1;
500 for (i = 0; i < len; i++)
501 add_char (with_char);
502 insert ('\n');
503 close_paragraph ();
504 filling_enabled = 1;
505 no_indent = old_no_indent;
506}
507
508/* Insert the text following input_text_offset up to the end of the
509 line as an HTML heading element of the appropriate `level' and
510 tagged as an anchor for the current node.. */
511
512void
513sectioning_html (int level, char *cmd)
514{
515 static int toc_ref_count = 0;
516 int index;
517 int old_no_indent;
518 unsigned char *starting_pos, *ending_pos;
519 char *temp, *toc_anchor = NULL((void *)0);
520
521 close_paragraph ();
522 filling_enabled = indented_fill = 0;
523 old_no_indent = no_indent;
524 no_indent = 1;
525
526 /* level 0 (chapter) is <h2>, and we go down from there. */
527 add_html_block_elt_args ("<h%d class=\"%s\">", level + 2, cmd);
528
529 /* If we are outside of any node, produce an anchor that
530 the TOC could refer to. */
531 if (!current_node || !*current_node)
532 {
533 static const char a_name[] = "<a name=\"";
534
535 starting_pos = output_paragraph + output_paragraph_offset;
536 add_word_args ("%sTOC%d\">", a_name, toc_ref_count++);
537 toc_anchor = substring (starting_pos + sizeof (a_name) - 1,
538 output_paragraph + output_paragraph_offset);
539 /* This must be added after toc_anchor is extracted, since
540 toc_anchor cannot include the closing </a>. For details,
541 see toc.c:toc_add_entry and toc.c:contents_update_html.
542
543 Also, the anchor close must be output before the section name
544 in case the name itself contains an anchor. */
545 add_word ("</a>");
546 }
547 starting_pos = output_paragraph + output_paragraph_offset;
548
549 if (macro_expansion_output_stream && !executing_string)
550 append_to_expansion_output (input_text_offset + 1);
551
552 get_rest_of_line (0, &temp);
553
554 /* Use @settitle value if @top parameter is empty. */
555 if (STREQ (command, "top")(strcmp (command, "top") == 0) && strlen(temp) == 0)
556 temp = xstrdup (title ? title : "");
557
558 index = search_sectioning (cmd);
559 if (index < 0)
560 {
561 /* should never happen, but a poor guy, named Murphy ... */
562 warning (_("Internal error (search_sectioning) \"%s\"!")((const char *) ("Internal error (search_sectioning) \"%s\"!"
))
, cmd);
563 return;
564 }
565
566 /* Produce "X.Y" and add it to HTML output. */
567 {
568 char *title_number = handle_enum_increment (level, index);
569 if (strlen (title_number) > 0)
570 add_word_args ("%s ", title_number);
571 }
572
573 /* add the section name to both HTML and macro-expanded output. */
574 if (macro_expansion_output_stream && !executing_string)
575 {
576 remember_itext (input_text, input_text_offset);
577 me_execute_string (temp);
578 write_region_to_macro_output ("\n", 0, 1);
579 }
580 else
581 execute_string ("%s", temp);
582
583 ending_pos = output_paragraph + output_paragraph_offset;
584
585 /* Pluck ``X.Y SECTION-NAME'' from the output buffer and insert it
586 into the TOC. */
587 if (section_alist[index].toc == TOC_YES1)
588 toc_add_entry (substring (starting_pos, ending_pos),
589 level, current_node, toc_anchor);
590
591 free (temp);
592
593 if (outstanding_node)
594 outstanding_node = 0;
595
596 add_word_args ("</h%d>", level + 2);
597 close_paragraph();
598 filling_enabled = 1;
599 no_indent = old_no_indent;
600}
601
602
603/* Shift the meaning of @section to @chapter. */
604void
605cm_raisesections (void)
606{
607 discard_until ("\n");
608 section_alist_offset--;
609}
610
611/* Shift the meaning of @chapter to @section. */
612void
613cm_lowersections (void)
614{
615 discard_until ("\n");
616 section_alist_offset++;
617}
618
619/* The command still works, but prints a warning message in addition. */
620void
621cm_ideprecated (int arg, int start, int end)
622{
623 warning (_("%c%s is obsolete; use %c%s instead")((const char *) ("%c%s is obsolete; use %c%s instead")),
624 COMMAND_PREFIX'@', command, COMMAND_PREFIX'@', command + 1);
625 sectioning_underscore (command + 1);
626}
627
628
629/* Treat this just like @unnumbered. The only difference is
630 in node defaulting. */
631void
632cm_top (void)
633{
634 /* It is an error to have more than one @top. */
635 if (top_node_seen && strcmp (current_node, "Top") != 0)
636 {
637 TAG_ENTRY *tag = tag_table;
638
639 line_error (_("Node with %ctop as a section already exists")((const char *) ("Node with %ctop as a section already exists"
))
,
640 COMMAND_PREFIX'@');
641
642 while (tag)
643 {
644 if (tag->flags & TAG_FLAG_IS_TOP16)
645 {
646 file_line_error (tag->filename, tag->line_no,
647 _("Here is the %ctop node")((const char *) ("Here is the %ctop node")), COMMAND_PREFIX'@');
648 return;
649 }
650 tag = tag->next_ent;
651 }
652 }
653 else
654 {
655 top_node_seen = 1;
656
657 /* It is an error to use @top before using @node. */
658 if (!tag_table)
659 {
660 char *top_name;
661
662 get_rest_of_line (0, &top_name);
663 line_error (_("%ctop used before %cnode, defaulting to %s")((const char *) ("%ctop used before %cnode, defaulting to %s"
))
,
664 COMMAND_PREFIX'@', COMMAND_PREFIX'@', top_name);
665 execute_string ("@node Top, , (dir), (dir)\n@top %s\n", top_name);
666 free (top_name);
667 return;
668 }
669
670 cm_unnumbered ();
671
672 /* The most recently defined node is the top node. */
673 tag_table->flags |= TAG_FLAG_IS_TOP16;
674
675 /* Now set the logical hierarchical level of the Top node. */
676 {
677 int orig_offset = input_text_offset;
678
679 input_text_offset = search_forward (node_search_string, orig_offset);
680
681 if (input_text_offset > 0)
682 {
683 int this_section;
684
685 /* We have encountered a non-top node, so mark that one exists. */
686 non_top_node_seen = 1;
687
688 /* Move to the end of this line, and find out what the
689 sectioning command is here. */
690 while (input_text[input_text_offset] != '\n')
691 input_text_offset++;
692
693 if (input_text_offset < input_text_length)
694 input_text_offset++;
695
696 this_section = what_section (input_text + input_text_offset,
697 NULL((void *)0));
698
699 /* If we found a sectioning command, then give the top section
700 a level of this section - 1. */
701 if (this_section != -1)
702 set_top_section_level (this_section - 1);
703 }
704 input_text_offset = orig_offset;
705 }
706 }
707}
708
709/* The remainder of the text on this line is a chapter heading. */
710void
711cm_chapter (void)
712{
713 enum_marker = 0;
714 sectioning_underscore ("chapter");
715}
716
717/* The remainder of the text on this line is a section heading. */
718void
719cm_section (void)
720{
721 sectioning_underscore ("section");
722}
723
724/* The remainder of the text on this line is a subsection heading. */
725void
726cm_subsection (void)
727{
728 sectioning_underscore ("subsection");
729}
730
731/* The remainder of the text on this line is a subsubsection heading. */
732void
733cm_subsubsection (void)
734{
735 sectioning_underscore ("subsubsection");
736}
737
738/* The remainder of the text on this line is an unnumbered heading. */
739void
740cm_unnumbered (void)
741{
742 enum_marker = UNNUMBERED_MAGIC2048;
743 sectioning_underscore ("unnumbered");
744}
745
746/* The remainder of the text on this line is an unnumbered section heading. */
747void
748cm_unnumberedsec (void)
749{
750 sectioning_underscore ("unnumberedsec");
751}
752
753/* The remainder of the text on this line is an unnumbered
754 subsection heading. */
755void
756cm_unnumberedsubsec (void)
757{
758 sectioning_underscore ("unnumberedsubsec");
759}
760
761/* The remainder of the text on this line is an unnumbered
762 subsubsection heading. */
763void
764cm_unnumberedsubsubsec (void)
765{
766 sectioning_underscore ("unnumberedsubsubsec");
767}
768
769/* The remainder of the text on this line is an appendix heading. */
770void
771cm_appendix (void)
772{
773 /* Reset top level number so we start from Appendix A */
774 if (enum_marker != APPENDIX_MAGIC1024)
775 numbers [0] = 0;
776 enum_marker = APPENDIX_MAGIC1024;
777 sectioning_underscore ("appendix");
778}
779
780/* The remainder of the text on this line is an appendix section heading. */
781void
782cm_appendixsec (void)
783{
784 sectioning_underscore ("appendixsec");
785}
786
787/* The remainder of the text on this line is an appendix subsection heading. */
788void
789cm_appendixsubsec (void)
790{
791 sectioning_underscore ("appendixsubsec");
792}
793
794/* The remainder of the text on this line is an appendix
795 subsubsection heading. */
796void
797cm_appendixsubsubsec (void)
798{
799 sectioning_underscore ("appendixsubsubsec");
800}
801
802/* Compatibility functions substitute for chapter, section, etc. */
803void
804cm_majorheading (void)
805{
806 sectioning_underscore ("majorheading");
807}
808
809void
810cm_chapheading (void)
811{
812 sectioning_underscore ("chapheading");
813}
814
815void
816cm_heading (void)
817{
818 sectioning_underscore ("heading");
819}
820
821void
822cm_subheading (void)
823{
824 sectioning_underscore ("subheading");
825}
826
827void
828cm_subsubheading (void)
829{
830 sectioning_underscore ("subsubheading");
1
Calling 'sectioning_underscore'
831}