123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982 |
- /* Copyright 2010, 2011, 2012, 2013, 2014, 2015
- Free Software Foundation, Inc.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- /* Avoid namespace conflicts. */
- #define context perl_context
- #define PERL_NO_GET_CONTEXT
- #include "EXTERN.h"
- #include "perl.h"
- #include "XSUB.h"
- #undef context
- #include <stdlib.h>
- #include <stdio.h>
- #include "parser.h"
- #include "input.h"
- #include "labels.h"
- #include "indices.h"
- #include "api.h"
- #include "errors.h"
- ELEMENT *Root;
- static void
- reset_floats ()
- {
- floats_number = 0;
- }
- void
- reset_parser (void)
- {
- debug ("!!!!!!!!!!!!!!!! RESETTING THE PARSER !!!!!!!!!!!!!!!!!!!!!");
- wipe_user_commands ();
- wipe_values ();
- wipe_macros ();
- init_index_commands ();
- wipe_errors ();
- reset_context_stack ();
- reset_region_stack ();
- reset_floats ();
- clear_expanded_formats ();
- wipe_global_info ();
- reset_internal_xrefs ();
- reset_labels ();
- input_reset_input_stack ();
- reset_conf ();
- current_node = current_section = 0;
- }
- /* Set ROOT to root of tree obtained by parsing FILENAME. */
- void
- parse_file (char *filename)
- {
- debug_output = 0;
- parse_texi_file (filename);
- }
- ELEMENT *
- get_root (void)
- {
- return Root;
- }
- /* Set ROOT to root of tree obtained by parsing the Texinfo code in STRING.
- Used for parse_texi_line. */
- void
- parse_string (char *string)
- {
- ELEMENT *root;
- root = new_element (ET_root_line);
- input_push_text (strdup (string), 0);
- Root = parse_texi (root);
- }
- /* Used for parse_texi_text. */
- void
- parse_text (char *string)
- {
- ELEMENT *root;
- root = new_element (ET_text_root);
- input_push_text_with_line_nos (strdup (string), 1);
- Root = parse_texi (root);
- }
- char *
- element_type_name (ELEMENT *e)
- {
- return element_type_names[(e)->type];
- }
- int
- num_contents_children (ELEMENT *e)
- {
- return e->contents.number;
- }
- int
- num_args_children (ELEMENT *e)
- {
- return e->args.number;
- }
- static void element_to_perl_hash (ELEMENT *e);
- /* Return reference to Perl array built from e. If any of
- the elements in E don't have 'hv' set, set it to an empty
- hash table, or create it if route_not_in_tree. */
- static SV *
- build_perl_array (ELEMENT_LIST *e)
- {
- SV *sv;
- AV *av;
- int i;
- dTHX;
- av = newAV ();
- sv = newRV_inc ((SV *) av);
- for (i = 0; i < e->number; i++)
- {
- if (!e->list[i]) /* For arrays only, allow elements to be undef. */
- av_push (av, newSV (0));
- if (!e->list[i]->hv)
- {
- if (e->list[i]->parent_type != route_not_in_tree)
- e->list[i]->hv = newHV ();
- else
- {
- /* WARNING: This is possibly recursive. */
- element_to_perl_hash (e->list[i]);
- }
- }
- av_push (av, newRV_inc ((SV *) e->list[i]->hv));
- }
- return sv;
- }
- /* Return reference to hash corresponding to VALUE. */
- static SV *
- build_node_spec (NODE_SPEC_EXTRA *value)
- {
- HV *hv;
- dTHX;
- if (!value->manual_content && !value->node_content)
- return newSV(0); /* Perl 'undef' */
- hv = newHV ();
- if (value->manual_content)
- {
- hv_store (hv, "manual_content", strlen ("manual_content"),
- build_perl_array (&value->manual_content->contents), 0);
- }
- if (value->node_content)
- {
- hv_store (hv, "node_content", strlen ("node_content"),
- build_perl_array (&value->node_content->contents), 0);
- }
- return newRV_inc ((SV *)hv);
- }
- /* Set E->hv and 'hv' on E's descendants. e->parent->hv is assumed
- to already exist. */
- static void
- element_to_perl_hash (ELEMENT *e)
- {
- SV *sv;
- dTHX;
- /* e->hv may already exist if there was an extra value elsewhere
- referring to e. */
- if (!e->hv)
- {
- e->hv = newHV ();
- }
- if (e->parent) // && e->parent_type != route_not_in_tree)
- {
- if (!e->parent->hv)
- e->parent->hv = newHV ();
- sv = newRV_inc ((SV *) e->parent->hv);
- hv_store (e->hv, "parent", strlen ("parent"), sv, 0);
- }
- /* FIXME: this assumes we don't have nested out-of-tree subtrees,
- i.e. the only out-of-tree elements are simple text elements
- (or other elements with no children) - otherwise we shall fail
- to set "parent" properly. */
- /* FIXME: Sometimes extra values have parent set - try to remove this
- in the Perl code as well. */
- sv = 0;
- if (e->cmd == CM_verb)
- {
- char c = (char) e->type;
- if (c)
- sv = newSVpv (&c, 1);
- else
- sv = newSVpv ("", 0);
- }
- else if (e->type)
- {
- sv = newSVpv (element_type_names[e->type], 0);
- }
- if (sv)
- hv_store (e->hv, "type", strlen ("type"), sv, 0);
- if (e->cmd)
- {
- sv = newSVpv (command_name(e->cmd), 0);
- hv_store (e->hv, "cmdname", strlen ("cmdname"), sv, 0);
- /* TODO: Same optimizations as for 'type'. */
- }
- /* FIXME sort out all these special cases */
- if (e->contents.number > 0
- || e->type == ET_text_root
- || e->type == ET_root_line
- || e->type == ET_bracketed
- || e->type == ET_bracketed_def_content
- || e->type == ET_misc_line_arg
- || e->cmd == CM_image // why image?
- || e->cmd == CM_item && e->parent && e->parent->type == ET_row
- || e->cmd == CM_tab && e->parent && e->parent->type == ET_row
- || e->cmd == CM_anchor
- || e->cmd == CM_macro
- || e->cmd == CM_multitable
- || e->type == ET_menu_entry_name
- || e->type == ET_brace_command_arg
- || e->type == ET_brace_command_context
- || e->type == ET_before_item
- || e->type == ET_inter_item
- || e->cmd == CM_TeX
- || e->type == ET_elided
- || e->type == ET_elided_block
- || e->type == ET_preformatted
- || (command_flags(e) & CF_root)
- || (command_data(e->cmd).flags & CF_brace
- && (command_data(e->cmd).data >= 0
- || command_data(e->cmd).data == BRACE_style
- || command_data(e->cmd).data == BRACE_context
- || command_data(e->cmd).data == BRACE_other
- || command_data(e->cmd).data == BRACE_accent
- ))
- || e->cmd == CM_node) // FIXME special case
- // FIXME: Makes no sense to have 'contents' created for glyph commands like
- // @arrow{} or for accent commands.
- {
- AV *av;
- int i;
- av = newAV ();
- sv = newRV_inc ((SV *) av);
- hv_store (e->hv, "contents", strlen ("contents"), sv, 0);
- for (i = 0; i < e->contents.number; i++)
- {
- element_to_perl_hash (e->contents.list[i]);
- sv = newRV_inc ((SV *) e->contents.list[i]->hv);
- av_push (av, sv);
- }
- }
- if (e->args.number > 0)
- {
- AV *av;
- int i;
- av = newAV ();
- sv = newRV_inc ((SV *) av);
- hv_store (e->hv, "args", strlen ("args"), sv, 0);
- for (i = 0; i < e->args.number; i++)
- {
- element_to_perl_hash (e->args.list[i]);
- sv = newRV_inc ((SV *) e->args.list[i]->hv);
- av_push (av, sv);
- }
- }
- if (e->text.space > 0)
- {
- sv = newSVpv (e->text.text, e->text.end);
- if (e->cmd != CM_value)
- hv_store (e->hv, "text", strlen ("text"), sv, 0);
- else
- hv_store (e->hv, "type", strlen ("type"), sv, 0);
- SvUTF8_on (sv);
- /* FIXME: Check that the strings we have are in UTF-8 to start with.
- This would lead to an unnecessary round trip with "@documentencoding
- ISO-8859-1" for Info and plain text output, when we first convert the
- characters in the input file to UTF-8, and convert them back again for
- the output.
-
- The alternative is to leave the UTF-8 flag off, and hope that Perl
- interprets 8-bit encodings like ISO-8859-1 correctly. See
- "How does Perl store UTF-8 strings?" in "man perlguts". */
- }
- if (e->extra_number > 0)
- {
- HV *extra;
- int i;
- int all_deleted = 1;
- extra = newHV ();
- for (i = 0; i < e->extra_number; i++)
- {
- #define STORE(sv) hv_store (extra, key, strlen (key), sv, 0)
- char *key = e->extra[i].key;
- ELEMENT *f = e->extra[i].value;
- if (e->extra[i].type == extra_deleted)
- continue;
- all_deleted = 0;
- switch (e->extra[i].type)
- {
- case extra_element:
- /* For references to other parts of the tree, create the hash so
- we can point to it. */
- if (!f->hv)
- {
- if (f->parent_type != route_not_in_tree)
- {
- /* TODO: Are there any extra values which are
- extra_element that are route_not_in_tree? Consider
- eliminating use of 'parent_type' to differentiate types
- of extra value. */
- f->hv = newHV ();
- }
- else
- element_to_perl_hash (f);
- }
- STORE(newRV_inc ((SV *)f->hv));
- break;
- case extra_element_contents:
- {
- int j;
- if (f)
- STORE(build_perl_array (&f->contents));
- break;
- }
- case extra_element_contents_array:
- {
- /* Like extra_element_contents, but this time output an array
- of arrays (instead of an array). */
- int j, k;
- AV *av;
- av = newAV ();
- STORE(newRV_inc ((SV *)av));
- for (j = 0; j < f->contents.number; j++)
- {
- SV *array;
- ELEMENT *g;
- g = f->contents.list[j];
- if (g)
- array = build_perl_array (&g->contents);
- else
- array = newSV (0); /* undef */
- av_push (av, array);
- }
- break;
- }
- case extra_string:
- { /* A simple string. */
- char *value = (char *) f;
- if (strcmp (key, "level"))
- STORE(newSVpv (value, 0));
- else
- {
- // FIXME: don't use level as a separate key
- hv_store (e->hv, key, strlen (key),
- newSVpv(value, 0), 0);
- }
- break;
- }
- case extra_misc_args:
- {
- int j;
- AV *av;
- av = newAV ();
- STORE(newRV_inc ((SV *)av));
- /* An array of strings. */
- for (j = 0; j < f->contents.number; j++)
- {
- if (f->contents.list[j]->text.end > 0)
- {
- av_push (av,
- newSVpv (f->contents.list[j]->text.text,
- f->contents.list[j]->text.end));
- }
- else
- {
- /* Empty strings permitted. */
- av_push (av,
- newSVpv ("", 0));
- }
- }
- break;
- }
- case extra_node_spec:
- /* A complex structure - see "parse_node_manual" function
- in end_line.c */
- if (f)
- STORE(build_node_spec ((NODE_SPEC_EXTRA *) f));
- break;
- case extra_node_spec_array:
- {
- int j;
- AV *av;
- NODE_SPEC_EXTRA **array;
- av = newAV ();
- STORE(newRV_inc ((SV *)av));
- array = (NODE_SPEC_EXTRA **) f;
- while (*array)
- {
- av_push (av, build_node_spec (*array));
- array++;
- }
- break;
- }
- case extra_index_entry:
- /* A "index_entry" extra key on a command defining an index
- entry. Unlike the other keys, the value is not in the
- main parse tree, but in the indices_information. It would
- be much nicer if we could get rid of the need for this key.
- We set this afterwards in build_index_data. */
- break;
- case extra_def_args:
- {
- /* Value is an array of two-element arrays. */
- AV *av, *av2;
- HV *def_parsed_hash;
- int j;
- DEF_ARGS_EXTRA *d = (DEF_ARGS_EXTRA *) f;
- av = newAV ();
- STORE(newRV_inc ((SV *)av));
- /* Also create a "def_parsed_hash" extra value. The key name
- for this is hard-coded here. */
- def_parsed_hash = newHV ();
- hv_store (extra, "def_parsed_hash",
- strlen ("def_parsed_hash"),
- newRV_inc ((SV *)def_parsed_hash), 0);
- for (j = 0; j < d->nelements; j++)
- {
- ELEMENT *elt = d->elements[j];
- char *label = d->labels[j];
- av2 = newAV ();
- av_push (av, newRV_inc ((SV *)av2));
- av_push (av2, newSVpv (label, 0));
- if (!elt->hv)
- {
- /* TODO: Same problem as "extra_element" cross-tree
- references. */
- if (elt->parent_type != route_not_in_tree)
- abort ();
- element_to_perl_hash (elt);
- }
- if (!elt->hv)
- abort ();
- av_push (av2, newRV_inc ((SV *)elt->hv));
- /* Set keys of "def_parsed_hash". */
- // 2793
- if (strcmp (label, "spaces")
- && strcmp (label, "arg") && strcmp (label, "typearg")
- && strcmp (label, "delimiter"))
- {
- hv_store (def_parsed_hash, label, strlen (label),
- newRV_inc ((SV *)elt->hv), 0);
- }
- }
- break;
- }
- case extra_float_type:
- {
- EXTRA_FLOAT_TYPE *eft = (EXTRA_FLOAT_TYPE *) f;
- HV *type = newHV ();
- if (eft->content)
- hv_store (type, "content", strlen ("content"),
- build_perl_array (&eft->content->contents), 0);
- if (eft->normalized)
- hv_store (type, "normalized", strlen ("normalized"),
- newSVpv (eft->normalized, 0), 0);
- STORE(newRV_inc ((SV *)type));
- break;
- }
- default:
- abort ();
- break;
- }
- }
- #undef STORE
- if (!all_deleted)
- hv_store (e->hv, "extra", strlen ("extra"),
- newRV_inc((SV *)extra), 0);
- }
- if (e->line_nr.line_nr
- && !(command_flags(e) & CF_INFOENCLOSE))
- {
- #define STORE(key, sv) hv_store (hv, key, strlen (key), sv, 0)
- LINE_NR *line_nr = &e->line_nr;
- HV *hv = newHV ();
- hv_store (e->hv, "line_nr", strlen ("line_nr"),
- newRV_inc((SV *)hv), 0);
- if (line_nr->file_name)
- {
- STORE("file_name", newSVpv (line_nr->file_name, 0));
- }
- else
- STORE("file_name", newSVpv ("", 0));
- if (line_nr->line_nr)
- {
- STORE("line_nr", newSViv (line_nr->line_nr));
- }
- if (line_nr->macro)
- {
- STORE("macro", newSVpv (line_nr->macro, 0));
- }
- else
- STORE("macro", newSVpv ("", 0));
- #undef STORE
- }
- }
- HV *
- build_texinfo_tree (void)
- {
- element_to_perl_hash (Root);
- return Root->hv;
- }
- /* Return array of target elements. build_texinfo_tree must
- be called first. */
- AV *
- build_label_list (void)
- {
- AV *target_array;
- SV *sv;
- int i;
- dTHX;
- target_array = newAV ();
- for (i = 0; i < labels_number; i++)
- {
- sv = newRV_inc (labels_list[i].target->hv);
- av_push (target_array, sv);
- }
- return target_array;
- }
- AV *
- build_internal_xref_list (void)
- {
- AV *list_av;
- SV *sv;
- int i;
- dTHX;
- list_av = newAV ();
- for (i = 0; i < internal_xref_number; i++)
- {
- sv = newRV_inc (internal_xref_list[i]->hv);
- av_push (list_av, sv);
- }
- return list_av;
- }
- /* Return hash for list of @float's that appeared in the file. */
- HV *
- build_float_list (void)
- {
- HV *float_hash;
- SV **type_array;
- SV *sv;
- AV *av;
- int i;
- dTHX;
- float_hash = newHV ();
- for (i = 0; i < floats_number; i++)
- {
- type_array = hv_fetch (float_hash,
- floats_list[i].type,
- strlen (floats_list[i].type),
- 0);
- if (!type_array)
- {
- av = newAV ();
- hv_store (float_hash,
- floats_list[i].type,
- strlen (floats_list[i].type),
- newRV_inc ((SV *)av),
- 0);
- }
- else
- {
- av = (AV *)SvRV (*type_array);
- }
- sv = newRV_inc ((SV *)floats_list[i].element->hv);
- av_push (av, sv);
- }
- return float_hash;
- }
- /* Ensure that I->hv is a hash value for a single entry in
- $self->{'index_names'}, containing information about a single index. */
- static void
- build_single_index_data (INDEX *i)
- {
- #define STORE(key, value) hv_store (hv, key, strlen (key), value, 0)
- HV *hv;
- AV *entries;
- int j;
- dTHX;
- if (!i->hv)
- {
- hv = newHV ();
- i->hv = (void *) hv;
- }
- else
- {
- hv = (HV *) i->hv;
- }
- STORE("name", newSVpv (i->name, 0));
- STORE("in_code", i->in_code ? newSViv(1) : newSViv(0));
- if (i->merged_in)
- {
- /* This index is merged in another one. */
- INDEX *ultimate = ultimate_index (i);
- if (!ultimate->hv)
- {
- ultimate->hv = (void *) newHV ();
- ultimate->contained_hv = (void *) newHV ();
- hv_store (ultimate->hv,
- "contained_indices",
- strlen ("contained_indices"),
- newRV_inc ((SV *)(HV *) ultimate->contained_hv),
- 0);
- }
- hv_store (ultimate->contained_hv, i->name, strlen (i->name),
- newSViv (1), 0);
- STORE("merged_in", newSVpv (ultimate->name, 0));
- if (i->contained_hv)
- {
- hv_delete (i->hv,
- "contained_indices", strlen ("contained_indices"),
- G_DISCARD);
- i->contained_hv = 0;
- }
- /* See also code in end_line.c (parse_line_command_args) <CM_synindex>.
- FIXME: Do we need to keep the original values of contained_indices?
- I don't think so. */
- }
- else
- {
- if (!i->contained_hv)
- {
- i->contained_hv = newHV ();
- STORE("contained_indices", newRV_inc ((SV *)(HV *) i->contained_hv));
- }
- /* Record that this index "contains itself". */
- hv_store (i->contained_hv, i->name, strlen (i->name), newSViv(1), 0);
- }
- if (i->index_number > 0)
- {
- entries = newAV ();
- STORE("index_entries", newRV_inc ((SV *) entries));
- }
- #undef STORE
- if (i->index_number > 0)
- for (j = 0; j < i->index_number; j++)
- {
- #define STORE2(key, value) hv_store (entry, key, strlen (key), value, 0)
- HV *entry;
- INDEX_ENTRY *e;
- e = &i->index_entries[j];
- entry = newHV ();
- av_push (entries, newRV_inc ((SV *)entry));
- STORE2("index_name", newSVpv (i->name, 0));
- STORE2("index_at_command",
- newSVpv (command_name(e->index_at_command), 0));
- STORE2("index_type_command",
- newSVpv (command_name(e->index_type_command), 0));
- STORE2("command",
- newRV_inc ((SV *)e->command->hv));
- STORE2("number", newSViv (j + 1));
- if (e->region)
- {
- STORE2("region", newRV_inc ((SV *)e->region->hv));
- }
- if (e->content)
- {
- SV **contents_array;
- if (!e->content->hv)
- {
- if (e->content->parent_type != route_not_in_tree)
- abort ();
- element_to_perl_hash (e->content);
- }
- contents_array = hv_fetch (e->content->hv,
- "contents", strlen ("contents"), 0);
- if (!contents_array)
- {
- element_to_perl_hash (e->content);
- contents_array = hv_fetch (e->content->hv,
- "contents", strlen ("contents"), 0);
- }
- if (contents_array)
- {
- /* Copy the reference to the array. */
- STORE2("content", newRV_inc ((SV *)(AV *)SvRV(*contents_array)));
- /* FIXME: Allow to be different. */
- STORE2("content_normalized",
- newRV_inc ((SV *)(AV *)SvRV(*contents_array)));
- }
- else
- {
- STORE2("content", newRV_inc ((SV *)newAV ()));
- STORE2("content_normalized", newRV_inc ((SV *)newAV ()));
- }
- }
- if (e->node)
- STORE2("node", newRV_inc ((SV *)e->node->hv));
- /* We set this now because the index data structures don't
- exist at the time that the main tree is built. */
- {
- SV **extra_hash;
- extra_hash = hv_fetch (e->command->hv, "extra", strlen ("extra"), 0);
- if (!extra_hash)
- {
- /* There's no guarantee that the "extra" value was set on
- the element. */
- extra_hash = hv_store (e->command->hv, "extra", strlen ("extra"),
- newRV_inc ((SV *)newHV ()), 0);
- }
- hv_store ((HV *)SvRV(*extra_hash), "index_entry", strlen ("index_entry"),
- newRV_inc ((SV *)entry), 0);
- }
- #undef STORE2
- }
- }
- /* Return object to be used as $self->{'index_names'} in the perl code.
- build_texinfo_tree must be called before this so all the 'hv' fields
- are set on the elements in the tree. */
- HV *
- build_index_data (void)
- {
- HV *hv;
- INDEX **i, *idx;
- dTHX;
- hv = newHV ();
- for (i = index_names; (idx = *i); i++)
- {
- HV *hv2;
- build_single_index_data (idx);
- hv2 = idx->hv;
- hv_store (hv, idx->name, strlen (idx->name), newRV_inc ((SV *)hv2), 0);
- }
- return hv;
- }
- /* Return object to be used as $self->{'info'} in the Perl code, retrievable
- with the 'global_informations' function. */
- HV *
- build_global_info (void)
- {
- HV *hv;
- dTHX;
- hv = newHV ();
- if (global_info.input_encoding_name)
- hv_store (hv, "input_encoding_name", strlen ("input_encoding_name"),
- newSVpv (global_info.input_encoding_name, 0), 0);
- if (global_info.novalidate)
- {
- hv_store (hv, "novalidate", strlen ("novalidate"),
- newSVpv ("1", 0), 0);
- }
- return hv;
- }
- /* Return object to be used as $self->{'extra'} in the Perl code, which
- are mostly references to tree elements. */
- HV *
- build_global_info2 (void)
- {
- HV *hv;
- AV *av;
- int i;
- ELEMENT *e;
- dTHX;
- hv = newHV ();
- /* These should be unique elements. */
- #define BUILD_GLOBAL_UNIQ(cmd) \
- if (global_info.cmd && global_info.cmd->hv) \
- { \
- hv_store (hv, #cmd, strlen (#cmd), \
- newRV_inc ((SV *) global_info.cmd->hv), 0); \
- }
- BUILD_GLOBAL_UNIQ(setfilename);
- BUILD_GLOBAL_UNIQ(settitle);
- BUILD_GLOBAL_UNIQ(copying);
- BUILD_GLOBAL_UNIQ(titlepage);
- BUILD_GLOBAL_UNIQ(top);
- BUILD_GLOBAL_UNIQ(documentdescription);
- BUILD_GLOBAL_UNIQ(setcontentsaftertitlepage);
- BUILD_GLOBAL_UNIQ(setshortcontentsaftertitlepage);
- BUILD_GLOBAL_UNIQ(novalidate);
- BUILD_GLOBAL_UNIQ(validatemenus);
- BUILD_GLOBAL_UNIQ(pagesizes);
- BUILD_GLOBAL_UNIQ(fonttextsize);
- BUILD_GLOBAL_UNIQ(footnotestyle);
- BUILD_GLOBAL_UNIQ(setchapternewpage);
- BUILD_GLOBAL_UNIQ(everyheading);
- BUILD_GLOBAL_UNIQ(everyfooting);
- BUILD_GLOBAL_UNIQ(evenheading);
- BUILD_GLOBAL_UNIQ(evenfooting);
- BUILD_GLOBAL_UNIQ(oddheading);
- BUILD_GLOBAL_UNIQ(oddfooting);
- BUILD_GLOBAL_UNIQ(everyheadingmarks);
- BUILD_GLOBAL_UNIQ(everyfootingmarks);
- BUILD_GLOBAL_UNIQ(evenheadingmarks);
- BUILD_GLOBAL_UNIQ(oddheadingmarks);
- BUILD_GLOBAL_UNIQ(evenfootingmarks);
- BUILD_GLOBAL_UNIQ(oddfootingmarks);
- BUILD_GLOBAL_UNIQ(shorttitlepage);
- BUILD_GLOBAL_UNIQ(title);
- #undef BUILD_GLOBAL_UNIQ
- /* NOTE: Same list in handle_commands.c:register_global_command. */
- /* The following are arrays of elements. */
-
- if (global_info.footnotes.contents.number > 0)
- {
- av = newAV ();
- hv_store (hv, "footnote", strlen ("footnote"),
- newRV_inc ((SV *) av), 0);
- for (i = 0; i < global_info.footnotes.contents.number; i++)
- {
- e = contents_child_by_index (&global_info.footnotes, i);
- if (e->hv)
- av_push (av, newRV_inc ((SV *) e->hv));
- }
- }
- #define BUILD_GLOBAL_ARRAY(cmd) \
- if (global_info.cmd.contents.number > 0) \
- { \
- av = newAV (); \
- hv_store (hv, #cmd, strlen (#cmd), \
- newRV_inc ((SV *) av), 0); \
- for (i = 0; i < global_info.cmd.contents.number; i++) \
- { \
- e = contents_child_by_index (&global_info.cmd, i); \
- if (e->hv) \
- av_push (av, newRV_inc ((SV *) e->hv)); \
- } \
- }
- BUILD_GLOBAL_ARRAY(hyphenation);
- BUILD_GLOBAL_ARRAY(insertcopying);
- BUILD_GLOBAL_ARRAY(printindex);
- BUILD_GLOBAL_ARRAY(subtitle);
- BUILD_GLOBAL_ARRAY(titlefont);
- BUILD_GLOBAL_ARRAY(listoffloats);
- BUILD_GLOBAL_ARRAY(detailmenu);
- BUILD_GLOBAL_ARRAY(part);
- /* from Common.pm %document_settable_at_commands */
- BUILD_GLOBAL_ARRAY(allowcodebreaks);
- BUILD_GLOBAL_ARRAY(clickstyle);
- BUILD_GLOBAL_ARRAY(codequotebacktick);
- BUILD_GLOBAL_ARRAY(codequoteundirected);
- BUILD_GLOBAL_ARRAY(contents);
- BUILD_GLOBAL_ARRAY(deftypefnnewline);
- BUILD_GLOBAL_ARRAY(documentencoding);
- BUILD_GLOBAL_ARRAY(documentlanguage);
- BUILD_GLOBAL_ARRAY(exampleindent);
- BUILD_GLOBAL_ARRAY(firstparagraphindent);
- BUILD_GLOBAL_ARRAY(frenchspacing);
- BUILD_GLOBAL_ARRAY(headings);
- BUILD_GLOBAL_ARRAY(kbdinputstyle);
- BUILD_GLOBAL_ARRAY(paragraphindent);
- BUILD_GLOBAL_ARRAY(shortcontents);
- BUILD_GLOBAL_ARRAY(urefbreakstyle);
- BUILD_GLOBAL_ARRAY(xrefautomaticsectiontitle);
- return hv;
- }
- /* Configuration values. */
- CONF conf;
- void
- conf_set_show_menu (int i)
- {
- conf.show_menu = i;
- }
- void
- reset_conf (void)
- {
- memset (&conf, 0, sizeof (conf));
- conf.show_menu = 1;
- }
|