1 /* Copyright 2010-2021 Free Software Foundation, Inc.
2
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>. */
15
16 #include <config.h>
17
18 /* Avoid namespace conflicts. */
19 #define context perl_context
20
21 #define PERL_NO_GET_CONTEXT
22 #include "EXTERN.h"
23 #include "perl.h"
24 #include "XSUB.h"
25
26 #undef context
27
28 #ifdef ENABLE_NLS
29 #include <libintl.h>
30 #endif
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <dirent.h>
35 #include <string.h>
36
37 #include "parser.h"
38 #include "input.h"
39 #include "labels.h"
40 #include "indices.h"
41 #include "api.h"
42
43 ELEMENT *Root;
44
45 #ifdef ENABLE_NLS
46
47 #define LOCALEDIR DATADIR "/locale"
48
49 /* Use the uninstalled locales dir.
50 NB the texinfo.mo files are not actually created here, only the
51 texinfo_document.mo files, which aren't used by parsetexi.
52 Hence, error messages will be translated only when the program is
53 installed. */
54 static void
find_locales_dir(char * builddir)55 find_locales_dir (char *builddir)
56 {
57 DIR *dir;
58 char *s;
59
60 dTHX;
61
62 /* Can't use asprintf here, because it might come from Gnulib, and
63 will then use malloc that is different from Perl's malloc, whereas
64 free below is redirected to Perl's implementation. This could
65 cause crashes if the two malloc/free implementations were different. */
66 s = malloc (strlen (builddir) + strlen ("/LocaleData") + 1);
67 sprintf (s, "%s/LocaleData", builddir);
68 dir = opendir (s);
69 if (!dir)
70 {
71 free (s);
72 fprintf (stderr, "Locales dir for document strings not found: %s\n",
73 strerror (errno));
74 }
75 else
76 {
77 bindtextdomain (PACKAGE, s);
78 free (s);
79 closedir (dir);
80 }
81 }
82
83 int
init(int texinfo_uninstalled,char * builddir)84 init (int texinfo_uninstalled, char *builddir)
85 {
86 setlocale (LC_ALL, "");
87
88 /* Use installed or uninstalled translation files for gettext. */
89 if (texinfo_uninstalled)
90 find_locales_dir (builddir);
91 else
92 bindtextdomain (PACKAGE, LOCALEDIR);
93
94 textdomain (PACKAGE);
95
96 return 1;
97 }
98
99 #else
100
101 int
init(int texinfo_uninstalled,char * builddir)102 init (int texinfo_uninstalled, char *builddir)
103 {
104 return 1;
105 }
106
107 #endif
108
109 static void
reset_floats()110 reset_floats ()
111 {
112 floats_number = 0;
113 }
114
115 void
reset_parser_except_conf(void)116 reset_parser_except_conf (void)
117 {
118 /* do before destroying tree because index entries usually refer to in-tree
119 elements. */
120 wipe_indices ();
121 if (Root)
122 {
123 destroy_element_and_children (Root);
124 Root = 0;
125 }
126 wipe_user_commands ();
127 wipe_macros ();
128 init_index_commands ();
129 wipe_errors ();
130 reset_context_stack ();
131 reset_region_stack ();
132 reset_floats ();
133 wipe_global_info ();
134 set_input_encoding ("utf-8");
135 reset_internal_xrefs ();
136 reset_labels ();
137 input_reset_input_stack ();
138 free_small_strings ();
139
140 current_node = current_section = current_part = 0;
141 }
142
143 void
reset_parser(void)144 reset_parser (void)
145 {
146 debug ("!!!!!!!!!!!!!!!! RESETTING THE PARSER !!!!!!!!!!!!!!!!!!!!!");
147
148 reset_parser_except_conf ();
149 wipe_values ();
150 clear_expanded_formats ();
151 reset_conf ();
152 }
153
154 /* Set ROOT to root of tree obtained by parsing FILENAME. */
155 int
parse_file(char * filename)156 parse_file (char *filename)
157 {
158 debug_output = 0;
159 Root = parse_texi_file (filename);
160 if (Root)
161 return 0;
162 return 1;
163 }
164
165 /* Set ROOT to root of tree obtained by parsing the Texinfo code in STRING.
166 STRING should be a UTF-8 buffer. Used for parse_texi_line. */
167 void
parse_string(char * string)168 parse_string (char *string)
169 {
170 reset_parser_except_conf ();
171 input_push_text (strdup (string), 0);
172 Root = parse_texi (new_element (ET_root_line));
173 }
174
175 /* Used for parse_texi_text. STRING should be a UTF-8 buffer. */
176 void
parse_text(char * string)177 parse_text (char *string)
178 {
179 reset_parser_except_conf ();
180 input_push_text_with_line_nos (strdup (string), 1);
181 Root = parse_texi (new_element (ET_text_root));
182 }
183
184
185 static void element_to_perl_hash (ELEMENT *e);
186
187 /* Return reference to Perl array built from e. If any of
188 the elements in E don't have 'hv' set, set it to an empty
189 hash table, or create it if there is no parent element, indicating the
190 element is not in the tree. */
191 static SV *
build_perl_array(ELEMENT_LIST * e)192 build_perl_array (ELEMENT_LIST *e)
193 {
194 SV *sv;
195 AV *av;
196 int i;
197
198 dTHX;
199
200 av = newAV ();
201 sv = newRV_inc ((SV *) av);
202 for (i = 0; i < e->number; i++)
203 {
204 if (!e->list[i]) /* For arrays only, allow elements to be undef. */
205 av_push (av, newSV (0));
206 if (!e->list[i]->hv)
207 {
208 if (e->list[i]->parent)
209 e->list[i]->hv = newHV ();
210 else
211 {
212 /* Out-of-tree element */
213 /* WARNING: This is possibly recursive. */
214 element_to_perl_hash (e->list[i]);
215 }
216 }
217 av_push (av, newRV_inc ((SV *) e->list[i]->hv));
218 }
219 return sv;
220 }
221
222 /* Return reference to hash corresponding to VALUE. */
223 static SV *
build_node_spec(NODE_SPEC_EXTRA * value)224 build_node_spec (NODE_SPEC_EXTRA *value)
225 {
226 HV *hv;
227
228 dTHX;
229
230 if (!value->manual_content && !value->node_content)
231 return newSV(0); /* Perl 'undef' */
232
233 hv = newHV ();
234
235 if (value->manual_content)
236 {
237 hv_store (hv, "manual_content", strlen ("manual_content"),
238 build_perl_array (&value->manual_content->contents), 0);
239 }
240
241 if (value->node_content)
242 {
243 hv_store (hv, "node_content", strlen ("node_content"),
244 build_perl_array (&value->node_content->contents), 0);
245 }
246
247 return newRV_inc ((SV *)hv);
248 }
249
250 /* Set E->hv and 'hv' on E's descendants. e->parent->hv is assumed
251 to already exist. */
252 static void
element_to_perl_hash(ELEMENT * e)253 element_to_perl_hash (ELEMENT *e)
254 {
255 SV *sv;
256
257 dTHX;
258
259 /* e->hv may already exist if there was an extra value elsewhere
260 referring to e. */
261 if (!e->hv)
262 {
263 e->hv = newHV ();
264 }
265
266 if (e->parent)
267 {
268 if (!e->parent->hv)
269 e->parent->hv = newHV ();
270 sv = newRV_inc ((SV *) e->parent->hv);
271 hv_store (e->hv, "parent", strlen ("parent"), sv, 0);
272 }
273
274 if (e->type)
275 {
276 sv = newSVpv (element_type_names[e->type], 0);
277 hv_store (e->hv, "type", strlen ("type"), sv, 0);
278 }
279
280 if (e->cmd)
281 {
282 sv = newSVpv (command_name(e->cmd), 0);
283 hv_store (e->hv, "cmdname", strlen ("cmdname"), sv, 0);
284
285 /* TODO: Same optimizations as for 'type'. */
286 }
287
288 /* A lot of special cases for when an empty contents array should be
289 created. Largely by trial and error to match the Perl code. Some of
290 them don't make sense, like @arrow{}, @image, or for accent commands. */
291 if (e->contents.number > 0
292 || e->type == ET_text_root
293 || e->type == ET_root_line
294 || e->type == ET_bracketed
295 || e->type == ET_bracketed_def_content
296 || e->type == ET_line_arg
297 || e->cmd == CM_image
298 || e->cmd == CM_item && e->parent && e->parent->type == ET_row
299 || e->cmd == CM_headitem && e->parent && e->parent->type == ET_row
300 || e->cmd == CM_tab && e->parent && e->parent->type == ET_row
301 || e->cmd == CM_anchor
302 || e->cmd == CM_macro
303 || e->cmd == CM_multitable
304 || e->type == ET_menu_entry_name
305 || e->type == ET_menu_entry_description
306 || e->type == ET_brace_command_arg
307 || e->type == ET_brace_command_context
308 || e->type == ET_block_line_arg
309 || e->type == ET_before_item
310 || e->type == ET_inter_item
311 || e->cmd == CM_TeX
312 || e->type == ET_elided
313 || e->type == ET_elided_block
314 || e->type == ET_preformatted
315 || e->type == ET_paragraph
316 || (command_flags(e) & CF_root)
317 || (command_data(e->cmd).flags & CF_brace
318 && (command_data(e->cmd).data >= 0
319 || command_data(e->cmd).data == BRACE_style
320 || command_data(e->cmd).data == BRACE_context
321 || command_data(e->cmd).data == BRACE_other
322 || command_data(e->cmd).data == BRACE_accent
323 ))
324 || e->cmd == CM_node)
325 {
326 AV *av;
327 int i;
328
329 av = newAV ();
330 sv = newRV_inc ((SV *) av);
331 hv_store (e->hv, "contents", strlen ("contents"), sv, 0);
332 for (i = 0; i < e->contents.number; i++)
333 {
334 element_to_perl_hash (e->contents.list[i]);
335 sv = newRV_inc ((SV *) e->contents.list[i]->hv);
336 av_push (av, sv);
337 }
338 }
339
340 if (e->args.number > 0)
341 {
342 AV *av;
343 int i;
344
345 av = newAV ();
346 sv = newRV_inc ((SV *) av);
347 hv_store (e->hv, "args", strlen ("args"), sv, 0);
348 for (i = 0; i < e->args.number; i++)
349 {
350 element_to_perl_hash (e->args.list[i]);
351 sv = newRV_inc ((SV *) e->args.list[i]->hv);
352 av_push (av, sv);
353 }
354 }
355
356 if (e->text.space > 0)
357 {
358 sv = newSVpv (e->text.text, e->text.end);
359 if (e->cmd != CM_value)
360 hv_store (e->hv, "text", strlen ("text"), sv, 0);
361 else
362 hv_store (e->hv, "type", strlen ("type"), sv, 0);
363
364 SvUTF8_on (sv);
365 /* The strings here have to be in UTF-8 to start with.
366 This leads to an unnecessary round trip with "@documentencoding
367 ISO-8859-1" for Info and plain text output, when we first convert the
368 characters in the input file to UTF-8, and convert them back again for
369 the output.
370
371 The alternative is to leave the UTF-8 flag off, and hope that Perl
372 interprets 8-bit encodings like ISO-8859-1 correctly. See
373 "How does Perl store UTF-8 strings?" in "man perlguts". */
374 }
375
376 if (e->extra_number > 0)
377 {
378 HV *extra;
379 int i;
380 int all_deleted = 1;
381 extra = newHV ();
382
383 for (i = 0; i < e->extra_number; i++)
384 {
385 #define STORE(sv) hv_store (extra, key, strlen (key), sv, 0)
386 char *key = e->extra[i].key;
387 ELEMENT *f = e->extra[i].value;
388
389 if (e->extra[i].type == extra_deleted)
390 continue;
391 all_deleted = 0;
392
393 switch (e->extra[i].type)
394 {
395 case extra_element:
396 /* For references to other parts of the tree, create the hash so
397 we can point to it. */
398 if (!f->hv)
399 f->hv = newHV ();
400 STORE(newRV_inc ((SV *)f->hv));
401 break;
402 case extra_element_oot:
403 if (!f->hv)
404 element_to_perl_hash (f);
405 STORE(newRV_inc ((SV *)f->hv));
406 break;
407 case extra_contents:
408 case extra_contents_oot:
409 {
410 if (f)
411 STORE(build_perl_array (&f->contents));
412 break;
413 }
414 case extra_contents_array:
415 {
416 /* Like extra_contents, but this time output an array
417 of arrays (instead of an array). */
418 int j;
419 AV *av;
420 av = newAV ();
421 STORE(newRV_inc ((SV *)av));
422 for (j = 0; j < f->contents.number; j++)
423 {
424 SV *array;
425 ELEMENT *g;
426
427 g = f->contents.list[j];
428 if (g)
429 array = build_perl_array (&g->contents);
430 else
431 array = newSV (0); /* undef */
432 av_push (av, array);
433 }
434 break;
435 }
436 case extra_string:
437 { /* A simple string. */
438 char *value = (char *) f;
439 STORE(newSVpv (value, 0));
440 break;
441 }
442 case extra_integer:
443 { /* A simple integer. The intptr_t cast here prevents
444 a warning on MinGW ("cast from pointer to integer of
445 different size"). */
446 IV value = (IV) (intptr_t) f;
447 STORE(newSViv (value));
448 break;
449 }
450 case extra_misc_args:
451 {
452 int j;
453 AV *av;
454 av = newAV ();
455 STORE(newRV_inc ((SV *)av));
456 /* An array of strings. */
457 for (j = 0; j < f->contents.number; j++)
458 {
459 if (f->contents.list[j]->text.end > 0)
460 {
461 av_push (av,
462 newSVpv (f->contents.list[j]->text.text,
463 f->contents.list[j]->text.end));
464 }
465 else
466 {
467 /* Empty strings permitted. */
468 av_push (av,
469 newSVpv ("", 0));
470 }
471 }
472 break;
473 }
474 case extra_node_spec:
475 /* A complex structure - see "parse_node_manual" function
476 in end_line.c */
477 if (f)
478 STORE(build_node_spec ((NODE_SPEC_EXTRA *) f));
479 break;
480 case extra_node_spec_array:
481 {
482 AV *av;
483 NODE_SPEC_EXTRA **array;
484 av = newAV ();
485 STORE(newRV_inc ((SV *)av));
486 array = (NODE_SPEC_EXTRA **) f;
487 while (*array)
488 {
489 av_push (av, build_node_spec (*array));
490 array++;
491 }
492 break;
493 }
494 case extra_index_entry:
495 /* A "index_entry" extra key on a command defining an index
496 entry. Unlike the other keys, the value is not in the
497 main parse tree, but in the indices_information. It would
498 be much nicer if we could get rid of the need for this key.
499 We set this afterwards in build_index_data. */
500 break;
501 case extra_def_info:
502 {
503 DEF_INFO *d = (DEF_INFO *) f;
504 HV *def_parsed_hash;
505
506 /* Create a "def_parsed_hash" extra value. */
507 def_parsed_hash = newHV ();
508 STORE(newRV_inc ((SV *)def_parsed_hash));
509
510 #define SAVE_DEF(X) { if (!d->X->hv) \
511 element_to_perl_hash (d->X); \
512 hv_store (def_parsed_hash, #X, strlen (#X), \
513 newRV_inc ((SV *)d->X->hv), 0) ; }
514
515 if (d->category)
516 SAVE_DEF(category)
517 if (d->class)
518 SAVE_DEF(class)
519 if (d->type)
520 SAVE_DEF(type)
521 if (d->name)
522 SAVE_DEF(name)
523 break;
524 }
525 case extra_float_type:
526 {
527 EXTRA_FLOAT_TYPE *eft = (EXTRA_FLOAT_TYPE *) f;
528 HV *type = newHV ();
529 if (eft->content)
530 hv_store (type, "content", strlen ("content"),
531 build_perl_array (&eft->content->contents), 0);
532 if (eft->normalized)
533 hv_store (type, "normalized", strlen ("normalized"),
534 newSVpv (eft->normalized, 0), 0);
535 STORE(newRV_inc ((SV *)type));
536 break;
537 }
538 default:
539 fatal ("unknown extra type");
540 break;
541 }
542 }
543 #undef STORE
544
545 if (!all_deleted)
546 hv_store (e->hv, "extra", strlen ("extra"),
547 newRV_inc((SV *)extra), 0);
548 }
549
550 if (e->line_nr.line_nr
551 && !(command_flags(e) & CF_INFOENCLOSE))
552 {
553 #define STORE(key, sv) hv_store (hv, key, strlen (key), sv, 0)
554 LINE_NR *line_nr = &e->line_nr;
555 HV *hv = newHV ();
556 hv_store (e->hv, "line_nr", strlen ("line_nr"),
557 newRV_inc((SV *)hv), 0);
558
559 if (line_nr->file_name)
560 {
561 STORE("file_name", newSVpv (line_nr->file_name, 0));
562 }
563 else
564 STORE("file_name", newSVpv ("", 0));
565
566 if (line_nr->line_nr)
567 {
568 STORE("line_nr", newSViv (line_nr->line_nr));
569 }
570
571 if (line_nr->macro)
572 {
573 STORE("macro", newSVpv (line_nr->macro, 0));
574 }
575 else
576 STORE("macro", newSVpv ("", 0));
577 #undef STORE
578 }
579 }
580
581 HV *
build_texinfo_tree(void)582 build_texinfo_tree (void)
583 {
584 element_to_perl_hash (Root);
585 return Root->hv;
586 }
587
588 /* Return array of target elements. build_texinfo_tree must
589 be called first. */
590 AV *
build_label_list(void)591 build_label_list (void)
592 {
593 AV *target_array;
594 SV *sv;
595 int i;
596
597 dTHX;
598
599 target_array = newAV ();
600
601 for (i = 0; i < labels_number; i++)
602 {
603 sv = newRV_inc (labels_list[i].target->hv);
604 av_push (target_array, sv);
605 }
606
607 return target_array;
608 }
609
610 AV *
build_internal_xref_list(void)611 build_internal_xref_list (void)
612 {
613 AV *list_av;
614 SV *sv;
615 int i;
616
617 dTHX;
618
619 list_av = newAV ();
620
621 for (i = 0; i < internal_xref_number; i++)
622 {
623 sv = newRV_inc (internal_xref_list[i]->hv);
624 av_push (list_av, sv);
625 }
626
627 return list_av;
628 }
629
630 /* Return hash for list of @float's that appeared in the file. */
631 HV *
build_float_list(void)632 build_float_list (void)
633 {
634 HV *float_hash;
635 SV **type_array;
636 SV *sv;
637 AV *av;
638 int i;
639
640 dTHX;
641
642 float_hash = newHV ();
643
644 for (i = 0; i < floats_number; i++)
645 {
646 type_array = hv_fetch (float_hash,
647 floats_list[i].type,
648 strlen (floats_list[i].type),
649 0);
650 if (!type_array)
651 {
652 av = newAV ();
653 hv_store (float_hash,
654 floats_list[i].type,
655 strlen (floats_list[i].type),
656 newRV_inc ((SV *)av),
657 0);
658 }
659 else
660 {
661 av = (AV *)SvRV (*type_array);
662 }
663 sv = newRV_inc ((SV *)floats_list[i].element->hv);
664 av_push (av, sv);
665 }
666
667 return float_hash;
668 }
669
670 /* Ensure that I->hv is a hash value for a single entry in
671 $self->{'index_names'}, containing information about a single index. */
672 static void
build_single_index_data(INDEX * i)673 build_single_index_data (INDEX *i)
674 {
675 #define STORE(key, value) hv_store (hv, key, strlen (key), value, 0)
676
677 HV *hv;
678 AV *entries;
679 int j;
680 int entry_number;
681
682 dTHX;
683
684 if (!i->hv)
685 {
686 hv = newHV ();
687 i->hv = (void *) hv;
688 }
689 else
690 {
691 hv = (HV *) i->hv;
692 }
693
694 STORE("name", newSVpv (i->name, 0));
695 STORE("in_code", i->in_code ? newSViv(1) : newSViv(0));
696
697 if (i->merged_in)
698 {
699 /* This index is merged in another one. */
700 INDEX *ultimate = ultimate_index (i);
701
702 if (!ultimate->hv)
703 {
704 ultimate->hv = (void *) newHV ();
705 ultimate->contained_hv = (void *) newHV ();
706 hv_store (ultimate->hv,
707 "contained_indices",
708 strlen ("contained_indices"),
709 newRV_inc ((SV *)(HV *) ultimate->contained_hv),
710 0);
711 }
712
713 hv_store (ultimate->contained_hv, i->name, strlen (i->name),
714 newSViv (1), 0);
715
716 STORE("merged_in", newSVpv (ultimate->name, 0));
717
718 if (i->contained_hv)
719 {
720 /* This is unlikely to happen, as if this index is merged into
721 another one, any indices merged into this index would have been
722 recorded under that one, and not this one. */
723 hv_delete (i->hv,
724 "contained_indices", strlen ("contained_indices"),
725 G_DISCARD);
726 i->contained_hv = 0;
727 }
728 }
729 else
730 {
731 if (!i->contained_hv)
732 {
733 i->contained_hv = newHV ();
734 STORE("contained_indices", newRV_inc ((SV *)(HV *) i->contained_hv));
735 }
736 /* Record that this index "contains itself". */
737 hv_store (i->contained_hv, i->name, strlen (i->name), newSViv(1), 0);
738 }
739
740 if (i->index_number > 0)
741 {
742 entries = newAV ();
743 STORE("index_entries", newRV_inc ((SV *) entries));
744 }
745 #undef STORE
746
747 entry_number = 1;
748 if (i->index_number > 0)
749 for (j = 0; j < i->index_number; j++)
750 {
751 #define STORE2(key, value) hv_store (entry, key, strlen (key), value, 0)
752 HV *entry;
753 INDEX_ENTRY *e;
754
755 e = &i->index_entries[j];
756 entry = newHV ();
757
758 STORE2("index_name", newSVpv (i->name, 0));
759 STORE2("index_at_command",
760 newSVpv (command_name(e->index_at_command), 0));
761 STORE2("index_type_command",
762 newSVpv (command_name(e->index_type_command), 0));
763 STORE2("command",
764 newRV_inc ((SV *)e->command->hv));
765 STORE2("number", newSViv (entry_number));
766 if (e->region)
767 {
768 STORE2("region", newRV_inc ((SV *)e->region->hv));
769 }
770 if (e->content)
771 {
772 SV **contents_array;
773 if (!e->content->hv)
774 {
775 if (e->content->parent)
776 fatal ("index element should not be in-tree");
777 element_to_perl_hash (e->content);
778 }
779 contents_array = hv_fetch (e->content->hv,
780 "contents", strlen ("contents"), 0);
781
782 if (!contents_array)
783 {
784 element_to_perl_hash (e->content);
785 contents_array = hv_fetch (e->content->hv,
786 "contents", strlen ("contents"), 0);
787 }
788
789 if (contents_array)
790 {
791 /* Copy the reference to the array. */
792 STORE2("content", newRV_inc ((SV *)(AV *)SvRV(*contents_array)));
793
794 STORE2("content_normalized",
795 newRV_inc ((SV *)(AV *)SvRV(*contents_array)));
796 }
797 else
798 {
799 STORE2("content", newRV_inc ((SV *)newAV ()));
800 STORE2("content_normalized", newRV_inc ((SV *)newAV ()));
801 }
802 }
803 else
804 ; /* will be set in Texinfo::Common::complete_indices */
805
806 if (e->node)
807 STORE2("node", newRV_inc ((SV *)e->node->hv));
808 if (e->sortas)
809 STORE2("sortas", newSVpv (e->sortas, 0));
810
811 /* Skip these as these entries do not refer to the place in the document
812 where the index commands occurred. */
813 if (!lookup_extra (e->command, "seeentry")
814 && !lookup_extra (e->command, "seealso"))
815 {
816 av_push (entries, newRV_inc ((SV *)entry));
817 entry_number++;
818 }
819
820 /* We set this now because the index data structures don't
821 exist at the time that the main tree is built. */
822 {
823 SV **extra_hash;
824 extra_hash = hv_fetch (e->command->hv, "extra", strlen ("extra"), 0);
825 if (!extra_hash)
826 {
827 /* There's no guarantee that the "extra" value was set on
828 the element. */
829 extra_hash = hv_store (e->command->hv, "extra", strlen ("extra"),
830 newRV_inc ((SV *)newHV ()), 0);
831 }
832
833 hv_store ((HV *)SvRV(*extra_hash), "index_entry", strlen ("index_entry"),
834 newRV_inc ((SV *)entry), 0);
835 }
836 #undef STORE2
837 }
838 }
839
840 /* Return object to be used as $self->{'index_names'} in the perl code.
841 build_texinfo_tree must be called before this so all the 'hv' fields
842 are set on the elements in the tree. */
843 HV *
build_index_data(void)844 build_index_data (void)
845 {
846 HV *hv;
847 INDEX **i, *idx;
848
849 dTHX;
850
851 hv = newHV ();
852
853 for (i = index_names; (idx = *i); i++)
854 {
855 HV *hv2;
856 build_single_index_data (idx);
857 hv2 = idx->hv;
858 hv_store (hv, idx->name, strlen (idx->name), newRV_inc ((SV *)hv2), 0);
859 }
860
861 return hv;
862 }
863
864
865 /* Return object to be used as $self->{'info'} in the Perl code, retrievable
866 with the 'global_informations' function. */
867 HV *
build_global_info(void)868 build_global_info (void)
869 {
870 HV *hv;
871 int i;
872 ELEMENT *e;
873
874 dTHX;
875
876 hv = newHV ();
877 if (global_info.input_encoding_name)
878 hv_store (hv, "input_encoding_name", strlen ("input_encoding_name"),
879 newSVpv (global_info.input_encoding_name, 0), 0);
880 if (global_info.input_perl_encoding)
881 hv_store (hv, "input_perl_encoding", strlen ("input_perl_encoding"),
882 newSVpv (global_info.input_perl_encoding, 0), 0);
883
884 if (global_info.dircategory_direntry.contents.number > 0)
885 {
886 AV *av = newAV ();
887 hv_store (hv, "dircategory_direntry", strlen ("dircategory_direntry"),
888 newRV_inc ((SV *) av), 0);
889 for (i = 0; i < global_info.dircategory_direntry.contents.number; i++)
890 {
891 e = contents_child_by_index (&global_info.dircategory_direntry, i);
892 if (e->hv)
893 av_push (av, newRV_inc ((SV *) e->hv));
894 }
895 }
896
897 if (global_info.novalidate)
898 {
899 hv_store (hv, "novalidate", strlen ("novalidate"),
900 newSVpv ("1", 0), 0);
901 }
902
903 char *txi_flags[] = { "txiindexatsignignore", "txiindexbackslashignore",
904 "txiindexhyphenignore", "txiindexlessthanignore", 0};
905 char **p;
906
907 for (p = txi_flags; (*p); p++)
908 {
909 if (fetch_value (*p))
910 hv_store (hv, *p, strlen (*p), newSVpv ("1", 0), 0);
911 }
912
913 return hv;
914 }
915
916 /* Return object to be used as $self->{'extra'} in the Perl code, which
917 are mostly references to tree elements. */
918 HV *
build_global_info2(void)919 build_global_info2 (void)
920 {
921 HV *hv;
922 AV *av;
923 int i;
924 ELEMENT *e;
925
926 dTHX;
927
928 hv = newHV ();
929
930 /* These should be unique elements. */
931
932 #define BUILD_GLOBAL_UNIQ(cmd) \
933 if (global_info.cmd && global_info.cmd->hv) \
934 { \
935 hv_store (hv, #cmd, strlen (#cmd), \
936 newRV_inc ((SV *) global_info.cmd->hv), 0); \
937 }
938
939 BUILD_GLOBAL_UNIQ(setfilename);
940 BUILD_GLOBAL_UNIQ(settitle);
941 BUILD_GLOBAL_UNIQ(copying);
942 BUILD_GLOBAL_UNIQ(titlepage);
943 BUILD_GLOBAL_UNIQ(top);
944 BUILD_GLOBAL_UNIQ(documentdescription);
945 BUILD_GLOBAL_UNIQ(pagesizes);
946 BUILD_GLOBAL_UNIQ(fonttextsize);
947 BUILD_GLOBAL_UNIQ(footnotestyle);
948 BUILD_GLOBAL_UNIQ(setchapternewpage);
949 BUILD_GLOBAL_UNIQ(everyheading);
950 BUILD_GLOBAL_UNIQ(everyfooting);
951 BUILD_GLOBAL_UNIQ(evenheading);
952 BUILD_GLOBAL_UNIQ(evenfooting);
953 BUILD_GLOBAL_UNIQ(oddheading);
954 BUILD_GLOBAL_UNIQ(oddfooting);
955 BUILD_GLOBAL_UNIQ(everyheadingmarks);
956 BUILD_GLOBAL_UNIQ(everyfootingmarks);
957 BUILD_GLOBAL_UNIQ(evenheadingmarks);
958 BUILD_GLOBAL_UNIQ(oddheadingmarks);
959 BUILD_GLOBAL_UNIQ(evenfootingmarks);
960 BUILD_GLOBAL_UNIQ(oddfootingmarks);
961 BUILD_GLOBAL_UNIQ(shorttitlepage);
962 BUILD_GLOBAL_UNIQ(title);
963 #undef BUILD_GLOBAL_UNIQ
964
965 /* NOTE: Same list in handle_commands.c:register_global_command. */
966
967 /* The following are arrays of elements. */
968
969
970 if (global_info.footnotes.contents.number > 0)
971 {
972 av = newAV ();
973 hv_store (hv, "footnote", strlen ("footnote"),
974 newRV_inc ((SV *) av), 0);
975 for (i = 0; i < global_info.footnotes.contents.number; i++)
976 {
977 e = contents_child_by_index (&global_info.footnotes, i);
978 if (e->hv)
979 av_push (av, newRV_inc ((SV *) e->hv));
980 }
981 }
982
983 #define BUILD_GLOBAL_ARRAY(cmd) \
984 if (global_info.cmd.contents.number > 0) \
985 { \
986 av = newAV (); \
987 hv_store (hv, #cmd, strlen (#cmd), \
988 newRV_inc ((SV *) av), 0); \
989 for (i = 0; i < global_info.cmd.contents.number; i++) \
990 { \
991 e = contents_child_by_index (&global_info.cmd, i); \
992 if (e->hv) \
993 av_push (av, newRV_inc ((SV *) e->hv)); \
994 } \
995 }
996
997 BUILD_GLOBAL_ARRAY(hyphenation);
998 BUILD_GLOBAL_ARRAY(insertcopying);
999 BUILD_GLOBAL_ARRAY(printindex);
1000 BUILD_GLOBAL_ARRAY(subtitle);
1001 BUILD_GLOBAL_ARRAY(titlefont);
1002 BUILD_GLOBAL_ARRAY(listoffloats);
1003 BUILD_GLOBAL_ARRAY(detailmenu);
1004 BUILD_GLOBAL_ARRAY(part);
1005
1006 /* from Common.pm %document_settable_at_commands */
1007 BUILD_GLOBAL_ARRAY(allowcodebreaks);
1008 BUILD_GLOBAL_ARRAY(clickstyle);
1009 BUILD_GLOBAL_ARRAY(codequotebacktick);
1010 BUILD_GLOBAL_ARRAY(codequoteundirected);
1011 BUILD_GLOBAL_ARRAY(contents);
1012 BUILD_GLOBAL_ARRAY(deftypefnnewline);
1013 BUILD_GLOBAL_ARRAY(documentencoding);
1014 BUILD_GLOBAL_ARRAY(documentlanguage);
1015 BUILD_GLOBAL_ARRAY(exampleindent);
1016 BUILD_GLOBAL_ARRAY(firstparagraphindent);
1017 BUILD_GLOBAL_ARRAY(frenchspacing);
1018 BUILD_GLOBAL_ARRAY(headings);
1019 BUILD_GLOBAL_ARRAY(kbdinputstyle);
1020 BUILD_GLOBAL_ARRAY(paragraphindent);
1021 BUILD_GLOBAL_ARRAY(shortcontents);
1022 BUILD_GLOBAL_ARRAY(urefbreakstyle);
1023 BUILD_GLOBAL_ARRAY(xrefautomaticsectiontitle);
1024 return hv;
1025 }
1026
1027 /* for debugging */
1028 void
set_debug(int value)1029 set_debug (int value)
1030 {
1031 debug_output = value;
1032 }
1033
1034