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