[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Sat, 5 Oct 2024 03:34:12 -0400 (EDT) |
branch: master
commit c60007f14ae8fba08e4a6f3c90ed5d066407aed3
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Aug 21 09:07:32 2024 +0200
Implement reading xhtmlxref in C and XS
* tp/Texinfo/Convert/HTML.pm (_parse_htmlxref_files): encode file name
for error message if close failed.
* tp/Texinfo/XS/convert/converter.c (apply_converter_info)
(destroy_converter_initialization_info)
(copy_converter_initialization_info),
tp/Texinfo/XS/convert/get_converter_perl_info.c
(get_converter_info_from_sv), tp/Texinfo/XS/main/converter_types.h
(CONVERTER_INITIALIZATION_INFO, CONVERTER): add
texinfo_language_config_dirs field in CONVERTER and in
texinfo_language_config_dirs in CONVERTER_INITIALIZATION_INFO,
pass information in apply_converter_info and get from Perl.
* tp/Texinfo/XS/main/utils.c (locate_file_in_dirs): add.
* tp/Texinfo/XS/convert/html_prepare_converter.c
(STRING_VARIABLE_INFO, STRING_VARIABLES_LIST, set_variable_value)
(read_var_len, substitute_variables, get_create_htmlxref_manual)
(fill_source_info_file, parse_htmlxref_files, load_htmlxref_files),
tp/Texinfo/XS/main/converter_types.h (HTMLXREF_MANUAL_LIST):
implement reading xhtmlxref files in C.
* tp/Texinfo/XS/convert/ConvertXS.xs
(html_converter_initialize_beginning),
tp/Texinfo/XS/convert/build_html_perl_state.c (build_htmlxref)
(html_pass_xtmlxref), tp/Texinfo/XS/convert/get_html_perl_info.c
(html_converter_get_customization_sv): XS interface to build xhtmlxref
information to Perl. Do not get xhtmlxref information from Perl
anymore.
* tp/Texinfo/XS/Makefile.am (AM_CPPFLAGS),
tp/Texinfo/XS/convert/texinfo.c (txi_converter_setup),
tp/Texinfo/XS/teximakehtml.c (main): pass sysconfidir in AM_CPPFLAGS.
Add texinfo_language_config_dirs argument to txi_converter_setup to
setup texinfo_language_config_dirs, and set the list of
texinfo_language_config_dirs in teximakehtml.c main.
---
ChangeLog | 41 ++
tp/Texinfo/Convert/HTML.pm | 11 +-
tp/Texinfo/XS/Makefile.am | 2 +-
tp/Texinfo/XS/convert/ConvertXS.xs | 5 +-
tp/Texinfo/XS/convert/build_html_perl_state.c | 54 +++
tp/Texinfo/XS/convert/build_html_perl_state.h | 2 +
tp/Texinfo/XS/convert/converter.c | 8 +
tp/Texinfo/XS/convert/get_converter_perl_info.c | 5 +-
tp/Texinfo/XS/convert/get_html_perl_info.c | 9 +-
tp/Texinfo/XS/convert/html_prepare_converter.c | 500 +++++++++++++++++++++++-
tp/Texinfo/XS/convert/texinfo.c | 14 +-
tp/Texinfo/XS/convert/texinfo.h | 7 +-
tp/Texinfo/XS/main/converter_types.h | 3 +
tp/Texinfo/XS/main/utils.c | 105 +++--
tp/Texinfo/XS/main/utils.h | 3 +
tp/Texinfo/XS/teximakehtml.c | 38 +-
16 files changed, 760 insertions(+), 47 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 18c71c35f3..3c49a51359 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,44 @@
+2024-08-21 Patrice Dumas <pertusus@free.fr>
+
+ Implement reading xhtmlxref in C and XS
+
+ * tp/Texinfo/Convert/HTML.pm (_parse_htmlxref_files): encode file name
+ for error message if close failed.
+
+ * tp/Texinfo/XS/convert/converter.c (apply_converter_info)
+ (destroy_converter_initialization_info)
+ (copy_converter_initialization_info),
+ tp/Texinfo/XS/convert/get_converter_perl_info.c
+ (get_converter_info_from_sv), tp/Texinfo/XS/main/converter_types.h
+ (CONVERTER_INITIALIZATION_INFO, CONVERTER): add
+ texinfo_language_config_dirs field in CONVERTER and in
+ texinfo_language_config_dirs in CONVERTER_INITIALIZATION_INFO,
+ pass information in apply_converter_info and get from Perl.
+
+ * tp/Texinfo/XS/main/utils.c (locate_file_in_dirs): add.
+
+ * tp/Texinfo/XS/convert/html_prepare_converter.c
+ (STRING_VARIABLE_INFO, STRING_VARIABLES_LIST, set_variable_value)
+ (read_var_len, substitute_variables, get_create_htmlxref_manual)
+ (fill_source_info_file, parse_htmlxref_files, load_htmlxref_files),
+ tp/Texinfo/XS/main/converter_types.h (HTMLXREF_MANUAL_LIST):
+ implement reading xhtmlxref files in C.
+
+ * tp/Texinfo/XS/convert/ConvertXS.xs
+ (html_converter_initialize_beginning),
+ tp/Texinfo/XS/convert/build_html_perl_state.c (build_htmlxref)
+ (html_pass_xtmlxref), tp/Texinfo/XS/convert/get_html_perl_info.c
+ (html_converter_get_customization_sv): XS interface to build xhtmlxref
+ information to Perl. Do not get xhtmlxref information from Perl
+ anymore.
+
+ * tp/Texinfo/XS/Makefile.am (AM_CPPFLAGS),
+ tp/Texinfo/XS/convert/texinfo.c (txi_converter_setup),
+ tp/Texinfo/XS/teximakehtml.c (main): pass sysconfidir in AM_CPPFLAGS.
+ Add texinfo_language_config_dirs argument to txi_converter_setup to
+ setup texinfo_language_config_dirs, and set the list of
+ texinfo_language_config_dirs in teximakehtml.c main.
+
2024-08-18 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/XS: run
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index a70cd89c02..b0a04b13b1 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -8478,9 +8478,14 @@ sub _parse_htmlxref_files($$)
$htmlxref->{$manual}->{$split_or_mono} = $href;
}
if (!close (HTMLXREF)) {
+ my $htmlxref_file_name = $file;
+ my $encoding = $self->get_conf('COMMAND_LINE_ENCODING');
+ if (defined($encoding)) {
+ $htmlxref_file_name = decode($encoding, $htmlxref_file_name);
+ }
$self->converter_document_warn(sprintf(__(
"error on closing html refs config file %s: %s"),
- $file, $!));
+ $htmlxref_file_name, $!));
}
}
return $htmlxref;
@@ -8745,9 +8750,9 @@ sub converter_initialize($)
$self->force_conf($conf, '');
}
}
- }
- _load_htmlxref_files($self);
+ _load_htmlxref_files($self);
+ }
$self->{'output_units_conversion'} = {};
my $customized_output_units_conversion
diff --git a/tp/Texinfo/XS/Makefile.am b/tp/Texinfo/XS/Makefile.am
index fa39738a4f..abeb53e5e5 100644
--- a/tp/Texinfo/XS/Makefile.am
+++ b/tp/Texinfo/XS/Makefile.am
@@ -33,7 +33,7 @@ EXTRA_DIST+=gnulib/m4/gnulib-cache.m4
################### End Gnulib section #########################
-AM_CPPFLAGS += -DDATADIR=\"$(datadir)\"
+AM_CPPFLAGS += -DDATADIR=\"$(datadir)\" -DSYSCONFDIR=\"$(sysconfdir)\"
######################## Perl ################################
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 686a70dda8..cc90d9e2f4 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -701,7 +701,10 @@ html_converter_initialize_beginning (SV *converter_in)
self = get_sv_converter (converter_in,
"html_converter_initialize_beginning");
if (self)
- html_converter_initialize_beginning (self);
+ {
+ html_converter_initialize_beginning (self);
+ html_pass_xtmlxref (&self->htmlxref, converter_in);
+ }
void
html_converter_get_customization_sv (SV *converter_in, SV
*default_formatting_references, SV *default_css_string_formatting_references,
SV *default_commands_open, SV *default_commands_conversion, SV
*default_css_string_commands_conversion, SV *default_types_open, SV
*default_types_conversion, SV *default_css_string_types_conversion, SV
*default_output_units_conversion, SV *default_special_unit_body, SV
*customized_upper_case_commands, SV *customized_type_formatting, SV
*customized_accent [...]
diff --git a/tp/Texinfo/XS/convert/build_html_perl_state.c
b/tp/Texinfo/XS/convert/build_html_perl_state.c
index e067d49191..c97885a2fd 100644
--- a/tp/Texinfo/XS/convert/build_html_perl_state.c
+++ b/tp/Texinfo/XS/convert/build_html_perl_state.c
@@ -62,6 +62,60 @@
/* See the NOTE in build_perl_info.c on use of functions related to
memory allocation */
+static HV *
+build_htmlxref (HTMLXREF_MANUAL_LIST *htmlxref_list)
+{
+ HV *htmlxref_hv;
+ size_t i;
+
+ dTHX;
+
+ htmlxref_hv = newHV ();
+
+ for (i = 0; i < htmlxref_list->number; i++)
+ {
+ HTMLXREF_MANUAL *htmlxref_manual = &htmlxref_list->list[i];
+ const char *manual_name = htmlxref_manual->manual;
+ SV *manual_name_sv = newSVpv_utf8 (manual_name, 0);
+ HV *htmlxref_manual_hv = newHV ();
+ SV *htmlxref_manual_sv = newRV_noinc ((SV *) htmlxref_manual_hv);
+ enum htmlxref_split_type j;
+
+ hv_store_ent (htmlxref_hv, manual_name_sv, htmlxref_manual_sv, 0);
+
+ for (j = 0; j < htmlxref_split_type_chapter+1; j++)
+ {
+ if (htmlxref_manual->urlprefix[j])
+ {
+ const char *split_type_name = htmlxref_split_type_names[j];
+ const char *href = htmlxref_manual->urlprefix[j];
+
+ hv_store (htmlxref_manual_hv, split_type_name,
+ strlen (split_type_name),
+ newSVpv_utf8 (href, 0), 0);
+ }
+ }
+ }
+
+ return htmlxref_hv;
+}
+
+void
+html_pass_xtmlxref (HTMLXREF_MANUAL_LIST *htmlxref_list, SV *converter_sv)
+{
+ HV *converter_hv;
+ HV *htmlxref_hv;
+
+ dTHX;
+
+ converter_hv = (HV *) SvRV (converter_sv);
+
+ htmlxref_hv = build_htmlxref (htmlxref_list);
+
+ hv_store (converter_hv, "htmlxref", strlen ("htmlxref"),
+ newRV_noinc ((SV *) htmlxref_hv), 0);
+}
+
#define STORE(key, sv) hv_store (html_target_hv, key, strlen (key), sv, 0)
HV *
build_html_target (const HTML_TARGET *html_target)
diff --git a/tp/Texinfo/XS/convert/build_html_perl_state.h
b/tp/Texinfo/XS/convert/build_html_perl_state.h
index c6c40e713d..6e5a5ecdce 100644
--- a/tp/Texinfo/XS/convert/build_html_perl_state.h
+++ b/tp/Texinfo/XS/convert/build_html_perl_state.h
@@ -10,6 +10,8 @@
/* for NAMED_STRING_ELEMENT_LIST */
#include "translations.h"
+void html_pass_xtmlxref (HTMLXREF_MANUAL_LIST *htmlxref_list, SV
*converter_sv);
+
HV *build_html_target (const HTML_TARGET *html_target);
void build_html_translated_names (HV *hv, CONVERTER *converter);
diff --git a/tp/Texinfo/XS/convert/converter.c
b/tp/Texinfo/XS/convert/converter.c
index 2444684fec..0d515b1c30 100644
--- a/tp/Texinfo/XS/convert/converter.c
+++ b/tp/Texinfo/XS/convert/converter.c
@@ -334,6 +334,9 @@ apply_converter_info (CONVERTER *converter,
converter->translated_commands = init_info->translated_commands;
init_info->translated_commands = 0;
}
+
+ copy_strings (&converter->texinfo_language_config_dirs,
+ &init_info->texinfo_language_config_dirs);
}
/* apply format_defaults and user_conf initialization information.
@@ -397,6 +400,8 @@ destroy_converter_initialization_info
(CONVERTER_INITIALIZATION_INFO *init_info)
free (init_info->converted_format);
free (init_info->output_format);
+ free_strings_list (&init_info->texinfo_language_config_dirs);
+
free_options_list (&init_info->conf);
free_strings_list (&init_info->non_valid_customization);
@@ -418,6 +423,9 @@ copy_converter_initialization_info
(CONVERTER_INITIALIZATION_INFO *dst_info,
dst_info->output_format = strdup (src_info->output_format);
}
+ copy_strings (&dst_info->texinfo_language_config_dirs,
+ &src_info->texinfo_language_config_dirs);
+
copy_strings (&dst_info->non_valid_customization,
&src_info->non_valid_customization);
diff --git a/tp/Texinfo/XS/convert/get_converter_perl_info.c
b/tp/Texinfo/XS/convert/get_converter_perl_info.c
index c6ed81e1c1..1921056dd2 100644
--- a/tp/Texinfo/XS/convert/get_converter_perl_info.c
+++ b/tp/Texinfo/XS/convert/get_converter_perl_info.c
@@ -302,8 +302,9 @@ get_converter_info_from_sv (SV *conf_sv, const char
*class_name,
= set_translated_commands (value);
else if (!strcmp (key, "texinfo_language_config_dirs"))
{
- /* TODO add to converter and set. Only used for
- htmlxref, so should wait for that to implement */
+ add_svav_to_string_list (value,
+ &initialization_info->texinfo_language_config_dirs,
+ svt_dir);
}
else if (class_name)
{
diff --git a/tp/Texinfo/XS/convert/get_html_perl_info.c
b/tp/Texinfo/XS/convert/get_html_perl_info.c
index f9a5cbcc55..534f7798c9 100644
--- a/tp/Texinfo/XS/convert/get_html_perl_info.c
+++ b/tp/Texinfo/XS/convert/get_html_perl_info.c
@@ -258,7 +258,7 @@ html_converter_get_customization_sv (SV *converter_sv,
HV *default_types_conversion_hv;
HV *default_css_string_types_conversion_hv;
HV *default_output_units_conversion_hv;
- SV **htmlxref_sv;
+ SV **htmlxref_sv = 0;
SV **formatting_function_sv;
SV **stage_handlers_sv;
SV **special_unit_body_sv;
@@ -892,8 +892,14 @@ html_converter_get_customization_sv (SV *converter_sv,
}
#define FETCH(key) key##_sv = hv_fetch (converter_hv, #key, strlen (#key), 0);
+ /*
FETCH(htmlxref)
+ */
+ /* Get htmlxref from Perl.
+ this is always 0 as it is not fetch so this code is never run, htmlxref
+ information is setup in C.
+ */
if (htmlxref_sv)
{
I32 hv_number;
@@ -906,6 +912,7 @@ html_converter_get_customization_sv (SV *converter_sv,
if (hv_number > 0)
{
+ converter->htmlxref.space = hv_number;
converter->htmlxref.list = new_htmlxref_manual_list (hv_number);
for (i = 0; i < hv_number; i++)
diff --git a/tp/Texinfo/XS/convert/html_prepare_converter.c
b/tp/Texinfo/XS/convert/html_prepare_converter.c
index 4c4c053b71..4817a5a7e6 100644
--- a/tp/Texinfo/XS/convert/html_prepare_converter.c
+++ b/tp/Texinfo/XS/convert/html_prepare_converter.c
@@ -93,6 +93,7 @@ static CSS_SELECTOR_STYLE_LIST
default_css_element_class_styles;
COMMAND_ARGS_SPECIFICATION html_command_args_flags[BUILTIN_CMD_NUMBER];
+/* should match enum htmlxref_split_type */
const char *htmlxref_split_type_names[htmlxref_split_type_chapter + 1] =
{
"mono", "node", "section", "chapter"
@@ -618,9 +619,434 @@ html_format_setup (void)
defaults based on customization variables.
Apply specific customizations (from Perl) */
+/* Also used to get htmlxref info from Perl. Initialize in C */
+HTMLXREF_MANUAL *
+new_htmlxref_manual_list (size_t size)
+{
+ HTMLXREF_MANUAL *result = (HTMLXREF_MANUAL *)
+ malloc (size * sizeof (HTMLXREF_MANUAL));
+ memset (result, 0, size * sizeof (HTMLXREF_MANUAL));
+
+ return result;
+}
+/* This variable setting/substitution is quite generic and could be used
+ in other codes, but it is only needed here for now */
+typedef struct STRING_VARIABLE_INFO {
+ char *name;
+ char *string;
+} STRING_VARIABLE_INFO;
-void
+typedef struct STRING_VARIABLES_LIST {
+ size_t number;
+ size_t space;
+ STRING_VARIABLE_INFO *list;
+} STRING_VARIABLES_LIST;
+
+static void
+set_variable_value (STRING_VARIABLES_LIST *variables,
+ const char *name, const char *value)
+{
+ size_t i;
+
+ for (i = 0; i < variables->number; i++)
+ {
+ STRING_VARIABLE_INFO *variable = &variables->list[i];
+ if (!strcmp (variable->name, name))
+ {
+ free (variable->string);
+ variable->string = strdup (value);
+ return;
+ }
+ }
+
+ if (variables->number == variables->space)
+ {
+ variables->list = (STRING_VARIABLE_INFO *) realloc
+ (variables->list,
+ sizeof (STRING_VARIABLE_INFO) * (variables->space += 5));
+ }
+
+ variables->list[variables->number].name = strdup (name);
+ variables->list[variables->number].string = strdup (value);
+
+ variables->number++;
+}
+
+/* generic, similar to Perl re (\w+) with /a modifier */
+static size_t
+read_var_len (const char *text)
+{
+ const char *q = text;
+
+ while (*q && (isascii_alnum (*q) || *q == '_'))
+ q++;
+
+ return q - text;
+}
+
+static char *
+substitute_variables (const char *input_text,
+ const STRING_VARIABLES_LIST *variables)
+{
+ TEXT substituted;
+ const char *p = input_text;
+
+ text_init (&substituted);
+ text_append (&substituted, "");
+
+ while (*p)
+ {
+ const char *q = strchr (p, '$');
+ if (q)
+ {
+ int found = 0;
+ size_t var_len;
+
+ if (q - p)
+ text_append_n (&substituted, p, q - p);
+ p = q;
+ q++; /* past $ */
+ if (*q == '{')
+ {
+ /* past { */
+ q++;
+ var_len = read_var_len (q);
+ if (var_len)
+ {
+ if (*(q + var_len) == '}')
+ {
+ size_t i;
+ char *flag = strndup (q, var_len);
+
+ /* past } */
+ q += var_len +1;
+ for (i = 0; i < variables->number; i++)
+ {
+ if (!strcmp (variables->list[i].name, flag))
+ {
+ text_append (&substituted,
+ variables->list[i].string);
+ found = 1;
+ break;
+ }
+ }
+ free (flag);
+ }
+ }
+ }
+
+ if (!found)
+ text_append_n (&substituted, p, q - p);
+ p = q;
+ }
+ else
+ {
+ text_append (&substituted, p);
+ break;
+ }
+ }
+
+ return substituted.text;
+}
+
+static HTMLXREF_MANUAL *
+get_create_htmlxref_manual (HTMLXREF_MANUAL_LIST *htmlxref_list,
+ const char *manual_name)
+{
+ size_t i;
+ HTMLXREF_MANUAL *htmlxref_manual;
+
+ for (i = 0; i < htmlxref_list->number; i++)
+ {
+ htmlxref_manual = &htmlxref_list->list[i];
+ if (!strcmp (htmlxref_manual->manual, manual_name))
+ return htmlxref_manual;
+ }
+
+ if (htmlxref_list->number == htmlxref_list->space)
+ {
+ htmlxref_list->list = (HTMLXREF_MANUAL *) realloc
+ (htmlxref_list->list,
+ sizeof (HTMLXREF_MANUAL) * (htmlxref_list->space += 5));
+ }
+
+ htmlxref_manual = &htmlxref_list->list[htmlxref_list->number];
+ memset (htmlxref_manual, 0, sizeof (HTMLXREF_MANUAL));
+ htmlxref_manual->manual = strdup (manual_name);
+
+ htmlxref_list->number++;
+
+ return htmlxref_manual;
+}
+
+static void
+fill_source_info_file (SOURCE_INFO *source_info, CONVERTER *self,
+ size_t line_nr, const char *file)
+{
+ source_info->macro = 0;
+ source_info->line_nr = line_nr;
+
+ if (self->conf->TEST.o.integer > 0)
+ {
+ char *filename_and_directory[2];
+ /* strip directories for out-of-source builds reproducible file names */
+ parse_file_path (file, filename_and_directory);
+ free (filename_and_directory[1]);
+ source_info->file_name = add_string (filename_and_directory[0],
+ &self->small_strings);
+ free (filename_and_directory[0]);
+ }
+ else
+ source_info->file_name = add_string (file, &self->small_strings);
+}
+
+static void
+parse_htmlxref_files (CONVERTER *self, HTMLXREF_MANUAL_LIST *htmlxref_list,
+ STRING_LIST *htmlxref_files)
+{
+ size_t i;
+ int line_nr = 0;
+
+ STRING_VARIABLES_LIST variables;
+ memset (&variables, 0, sizeof (STRING_VARIABLES_LIST));
+
+ for (i = 0; i < htmlxref_files->number; i++)
+ {
+ const char *file = htmlxref_files->list[i];
+ FILE *stream = 0;
+
+ if (self->conf->DEBUG.o.integer > 0)
+ fprintf (stderr, "html refs config file: %s\n", file);
+
+ stream = fopen (file, "r");
+ if (!stream)
+ {
+ char *decoded_file;
+ const char *encoding = self->conf->COMMAND_LINE_ENCODING.o.string;
+
+ if (encoding)
+ {
+ int status;
+ /* cast to remove const */
+ decoded_file = decode_string ((char *)file,
+ encoding, &status, 0);
+ }
+ else
+ decoded_file = strdup (file);
+
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0, "could not open html refs config file %s: %s",
+ decoded_file, strerror (errno));
+
+ free (decoded_file);
+
+ continue;
+ }
+
+ while (1)
+ {
+ const char *p;
+ size_t n;
+ char *line = 0;
+ ssize_t status = getline (&line, &n, stream);
+ size_t len;
+ char *split_or_mono = 0;
+ char *manual;
+ char *href = 0;
+ enum htmlxref_split_type htmlxref_type = htmlxref_split_type_none;
+ const char *q;
+ size_t spaces_len;
+ char *subst_href;
+ HTMLXREF_MANUAL *htmlxref_manual;
+
+ if (status == -1)
+ {
+ free (line);
+ break;
+ }
+ line_nr++;
+
+ /*
+ fprintf (stderr, "LLL %s:%d: %s", file, line_nr, line);
+ */
+
+ p = line;
+
+ p += strspn (p, whitespace_chars);
+ if (*p == '#' || *p == '\0')
+ continue;
+
+ len = read_var_len (p);
+ if (len)
+ {
+ q = p;
+ q += len;
+ q += strspn (q, whitespace_chars);
+ if (*q == '=')
+ {
+ char *name = strndup (p, len);
+ char *definition;
+ char *end_line;
+ q++;
+ q += strspn (q, whitespace_chars);
+ definition = substitute_variables (q, &variables);
+ end_line = strchr (definition, '\n');
+ if (end_line)
+ *end_line = '\0';
+ set_variable_value (&variables, name, definition);
+ /*
+ fprintf (stderr, "VVV %s='%s'\n", name, definition);
+ */
+ free (definition);
+ free (name);
+ continue;
+ }
+ }
+ len = strcspn (p, whitespace_chars);
+ /* should always be true as we already handled a spaces only line */
+ if (len)
+ {
+ q = p + len;
+ spaces_len = strspn (q, whitespace_chars);
+
+ if (spaces_len && *q)
+ {
+ size_t spec_len;
+
+ q += spaces_len;
+ spec_len = strcspn (q, whitespace_chars);
+
+ if (spec_len)
+ {
+ split_or_mono = strndup (q, spec_len);
+ q += spec_len;
+
+ enum htmlxref_split_type i;
+
+ for (i = 0; i < htmlxref_split_type_chapter+1; i++)
+ {
+ if (!strcmp (split_or_mono,
+ htmlxref_split_type_names[i]))
+ {
+ htmlxref_type = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+ /*
+ fprintf (stderr, "SOM %s %d\n", split_or_mono, htmlxref_type);
+ */
+ if (!split_or_mono)
+ {
+ SOURCE_INFO source_info;
+ fill_source_info_file (&source_info, self, line_nr, file);
+
+ message_list_line_error_ext (&self->error_messages,
+ self->conf, MSG_warning, 0, &source_info, "missing type");
+ continue;
+ }
+ else if (htmlxref_type == htmlxref_split_type_none)
+ {
+ SOURCE_INFO source_info;
+ fill_source_info_file (&source_info, self, line_nr, file);
+
+ message_list_line_error_ext (&self->error_messages,
+ self->conf, MSG_warning, 0, &source_info,
+ "unrecognized type: %s", split_or_mono);
+ free (split_or_mono);
+ continue;
+ }
+
+ manual = strndup (p, len);
+
+ spaces_len = strspn (q, whitespace_chars);
+ if (spaces_len && *q)
+ {
+ q += spaces_len;
+ size_t spec_len = strcspn (q, whitespace_chars);
+ if (spec_len)
+ {
+ href = strndup (q, spec_len);
+ }
+ }
+
+ if (!href)
+ {
+ SOURCE_INFO source_info;
+ fill_source_info_file (&source_info, self, line_nr, file);
+
+ message_list_line_error_ext (&self->error_messages,
+ self->conf, MSG_warning, 0, &source_info,
+ "missing %s URL prefix for `%s'", split_or_mono, manual);
+ free (split_or_mono);
+ free (manual);
+ continue;
+ }
+
+ free (split_or_mono);
+
+ htmlxref_manual
+ = get_create_htmlxref_manual (htmlxref_list, manual);
+ free (manual);
+
+ /*
+ fprintf (stderr, "FFF %s '%s' %d '%s'\n", htmlxref_manual->manual,
+ href, htmlxref_type,
htmlxref_manual->urlprefix[htmlxref_type]);
+ */
+ if (htmlxref_manual->urlprefix[htmlxref_type])
+ {
+ free (href);
+ continue;
+ }
+
+ subst_href = substitute_variables (href, &variables);
+
+ free (href);
+
+ if (htmlxref_type != htmlxref_split_type_mono)
+ {
+ size_t j;
+ for (j = strlen (subst_href); j > 0; j--)
+ if (subst_href[j-1] == '/')
+ subst_href[j-1] = '\0';
+ }
+
+ /*
+ fprintf (stderr, "HHH %s '%s' %d\n", htmlxref_manual->manual,
+ subst_href, htmlxref_type);
+ */
+
+ htmlxref_manual->urlprefix[htmlxref_type] = strdup (subst_href);
+ free (subst_href);
+ }
+
+ if (fclose (stream) == EOF)
+ {
+ char *decoded_file;
+ const char *encoding = self->conf->COMMAND_LINE_ENCODING.o.string;
+
+ if (encoding)
+ {
+ int status;
+ /* cast to remove const */
+ decoded_file = decode_string ((char *)file, encoding,
+ &status, 0);
+ }
+ else
+ decoded_file = strdup (file);
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0, "error on closing html refs config file %s:
%s",
+ decoded_file, strerror (errno));
+
+ free (decoded_file);
+ }
+ }
+}
+
+static void
load_htmlxref_files (CONVERTER *self)
{
const char *htmlxref_mode = self->conf->HTMLXREF_MODE.o.string;
@@ -655,6 +1081,67 @@ load_htmlxref_files (CONVERTER *self)
htmlxref_file_name);
free (encoded_htmlxref_file_name);
}
+ else
+ {
+ STRING_LIST htmlxref_dirs;
+ memset (&htmlxref_dirs, 0, sizeof (STRING_LIST));
+
+ add_string (".", &htmlxref_dirs);
+
+ if (self->conf->TEST.o.integer > 0)
+ {
+ /* to have reproducible tests, do not use system or user
+ directories if TEST is set. */
+ if (conversion_paths_info.texinfo_uninstalled)
+ {
+ if (conversion_paths_info.p.uninstalled.top_srcdir)
+ {
+ char *path;
+ xasprintf (&path, "%s/tp/t/input_files",
+ conversion_paths_info.p.uninstalled.top_srcdir);
+ add_string (path, &htmlxref_dirs);
+ free (path);
+ }
+ else
+ add_string ("tp/t/input_files", &htmlxref_dirs);
+ }
+ add_string (".texinfo", &htmlxref_dirs);
+ }
+ else
+ {
+ copy_strings (&htmlxref_dirs, &self->texinfo_language_config_dirs);
+ }
+
+ if (self->conf->TEST.o.integer > 0)
+ htmlxref_file_name = self->conf->HTMLXREF_FILE.o.string;
+ else if (self->conf->HTMLXREF_FILE.o.string)
+ htmlxref_file_name = self->conf->HTMLXREF_FILE.o.string;
+
+ if (htmlxref_file_name)
+ {
+ char *encoded_htmlxref_file_name;
+ char *path_encoding;
+
+ /* cast to remove const */
+ encoded_htmlxref_file_name
+ = encoded_output_file_name (self->conf,
+ &self->document->global_info,
+ (char *)htmlxref_file_name,
+ &path_encoding, 0);
+ free (path_encoding);
+
+ locate_file_in_dirs (encoded_htmlxref_file_name,
+ &htmlxref_dirs, &htmlxref_files);
+ free (encoded_htmlxref_file_name);
+ }
+ free_strings_list (&htmlxref_dirs);
+ }
+
+ if (htmlxref_files.number > 0)
+ {
+ parse_htmlxref_files (self, &self->htmlxref, &htmlxref_files);
+ free_strings_list (&htmlxref_files);
+ }
}
/* this code corresponds to the Perl converter_initialize code, only for
@@ -796,17 +1283,6 @@ new_special_unit_formatting_references (int
special_units_varieties_nr)
return formatting_references;
}
-/* Used to get htmlxref info from Perl. Initialize in C */
-HTMLXREF_MANUAL *
-new_htmlxref_manual_list (size_t size)
-{
- HTMLXREF_MANUAL *result = (HTMLXREF_MANUAL *)
- malloc (size * sizeof (HTMLXREF_MANUAL));
- memset (result, 0, size * sizeof (HTMLXREF_MANUAL));
-
- return result;
-}
-
static HTML_DIRECTION_STRING_TRANSLATED *
new_directions_strings_translated_type (int nr_string_directions)
{
diff --git a/tp/Texinfo/XS/convert/texinfo.c b/tp/Texinfo/XS/convert/texinfo.c
index d09f745f19..a559cc41a8 100644
--- a/tp/Texinfo/XS/convert/texinfo.c
+++ b/tp/Texinfo/XS/convert/texinfo.c
@@ -287,7 +287,9 @@ CONVERTER *
txi_converter_setup (const char *format_str,
const char *output_format,
const char *locale_encoding,
- const char *program_file, OPTIONS_LIST *customizations)
+ const char *program_file,
+ char * const*texinfo_language_config_dirs,
+ OPTIONS_LIST *customizations)
{
enum converter_format converter_format
= find_format_name_converter_format (format_str);
@@ -302,6 +304,16 @@ txi_converter_setup (const char *format_str,
else
conf->output_format = strdup (format_str);
+ if (texinfo_language_config_dirs)
+ {
+ int i;
+ for (i = 0; texinfo_language_config_dirs[i]; i++)
+ {
+ add_string (texinfo_language_config_dirs[i],
+ &conf->texinfo_language_config_dirs);
+ }
+ }
+
initialize_options_list (&conf->conf, 10);
/* similar to options coming from texi2any */
diff --git a/tp/Texinfo/XS/convert/texinfo.h b/tp/Texinfo/XS/convert/texinfo.h
index 5ffd458af3..12558fe28f 100644
--- a/tp/Texinfo/XS/convert/texinfo.h
+++ b/tp/Texinfo/XS/convert/texinfo.h
@@ -41,11 +41,12 @@ void txi_complete_document (DOCUMENT *document, unsigned
long flags,
CONVERTER *txi_converter (enum converter_format format,
CONVERTER_INITIALIZATION_INFO *conf);
-CONVERTER *
-txi_converter_setup (const char *converter_format,
+CONVERTER *txi_converter_setup (const char *converter_format,
const char *output_format,
const char *locale_encoding,
- const char *program_file, OPTIONS_LIST *customizations);
+ const char *program_file,
+ char *const *texinfo_language_config_dirs,
+ OPTIONS_LIST *customizations);
char *txi_html_output (CONVERTER *converter, DOCUMENT *document);
diff --git a/tp/Texinfo/XS/main/converter_types.h
b/tp/Texinfo/XS/main/converter_types.h
index 9d9f8cef98..e93949d7d2 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -676,6 +676,7 @@ typedef struct HTMLXREF_MANUAL {
typedef struct HTMLXREF_MANUAL_LIST {
size_t number;
+ size_t space;
HTMLXREF_MANUAL *list;
} HTMLXREF_MANUAL_LIST;
@@ -763,6 +764,7 @@ typedef struct CONVERTER_INITIALIZATION_INFO {
char *converted_format;
char *output_format;
TRANSLATED_COMMAND *translated_commands;
+ STRING_LIST texinfo_language_config_dirs;
OPTIONS_LIST conf;
/* gather strings that are not customization options */
STRING_LIST non_valid_customization;
@@ -785,6 +787,7 @@ typedef struct CONVERTER {
OPTION **sorted_options;
OPTIONS *init_conf;
OPTIONS *format_defaults_conf;
+ STRING_LIST texinfo_language_config_dirs;
char *output_format;
char *converted_format;
EXPANDED_FORMAT *expanded_formats;
diff --git a/tp/Texinfo/XS/main/utils.c b/tp/Texinfo/XS/main/utils.c
index 4e4314c9a3..623d0e281c 100644
--- a/tp/Texinfo/XS/main/utils.c
+++ b/tp/Texinfo/XS/main/utils.c
@@ -28,6 +28,8 @@
#include "unicase.h"
#include "uniwidth.h"
#include <unictype.h>
+/* for euidaccess. Not portable, use gnulib */
+#include <unistd.h>
#include "conversion_data.h"
/* also for xvasprintf */
@@ -270,7 +272,9 @@ isascii_upper (int c)
}
+
/* operations on strings considered as multibytes. Use libunistring */
+
/* count characters, not bytes. */
size_t
count_multibyte (const char *text)
@@ -360,7 +364,9 @@ word_bytes_len_multibyte (const char *text)
}
+
/* encoding and decoding. Use iconv. */
+
/* conversion to or from utf-8 should always be set before other
conversion */
ENCODING_CONVERSION *
@@ -586,8 +592,10 @@ encode_string (char *input_string, const char *encoding,
int *status,
}
+
/* code related to the EXPANDED_FORMAT structure holding informations on the
expanded formats (html, info, tex...) */
+
void
clear_expanded_formats (EXPANDED_FORMAT *formats)
{
@@ -1032,6 +1040,35 @@ find_string (const STRING_LIST *strings_list, const char
*target)
return 0;
}
+void
+clear_strings_list (STRING_LIST *strings)
+{
+ size_t i;
+ for (i = 0; i < strings->number; i++)
+ {
+ free (strings->list[i]);
+ }
+ strings->number = 0;
+}
+
+void
+free_strings_list (STRING_LIST *strings)
+{
+ size_t i;
+ for (i = 0; i < strings->number; i++)
+ {
+ free (strings->list[i]);
+ }
+ free (strings->list);
+}
+
+void
+destroy_strings_list (STRING_LIST *strings)
+{
+ free_strings_list (strings);
+ free (strings);
+}
+
/* Return value to be freed by caller. */
/* try to locate a file called FILENAME, looking for it in the list of include
directories. */
@@ -1072,33 +1109,57 @@ locate_include_file (const char *filename, const
STRING_LIST *include_dirs_list)
return 0;
}
-void
-clear_strings_list (STRING_LIST *strings)
-{
- size_t i;
- for (i = 0; i < strings->number; i++)
- {
- free (strings->list[i]);
- }
- strings->number = 0;
-}
+/* Return value to be freed by caller. */
+/* Used in main program, tests and HTML Converter.
+
+ FILENAME file name to locate. It can be a file path. Binary string.
+ DIRECTORIES list of directories to search the file in. Binary strings.
+ ALL_FILES if set collect all the files with that name, otherwise stop
+ at first match.
+
+ If ALL_FILES is not set:
+ - if FILENAME is an absolute path: if found, return it;
+ - otherwise return the first file found in the directories;
+ - otherwise return NULL.
+ If ALL_FILES is set return NULL and:
+ - if FILENAME is an absolute path: if found, add to ALL_FILES;
+ - otherwise add all files found to ALL_FILES.
+ */
-void
-free_strings_list (STRING_LIST *strings)
+char *
+locate_file_in_dirs (const char *filename,
+ const STRING_LIST *directories,
+ STRING_LIST *all_files)
{
- size_t i;
- for (i = 0; i < strings->number; i++)
+ if (!memcmp (filename, "/", 1))
{
- free (strings->list[i]);
+ if (euidaccess (filename, R_OK) == 0)
+ {
+ if (all_files)
+ add_string (filename, all_files);
+ else
+ return strdup (filename);
+ }
}
- free (strings->list);
-}
+ else
+ {
+ size_t i;
+ for (i = 0; i < directories->number; i++)
+ {
+ char *fullpath;
-void
-destroy_strings_list (STRING_LIST *strings)
-{
- free_strings_list (strings);
- free (strings);
+ xasprintf (&fullpath, "%s/%s", directories->list[i], filename);
+ if (euidaccess (fullpath, R_OK) == 0)
+ {
+ if (all_files)
+ add_string (fullpath, all_files);
+ else
+ return fullpath;
+ }
+ free (fullpath);
+ }
+ }
+ return 0;
}
diff --git a/tp/Texinfo/XS/main/utils.h b/tp/Texinfo/XS/main/utils.h
index 580fa9b601..7b059cdc00 100644
--- a/tp/Texinfo/XS/main/utils.h
+++ b/tp/Texinfo/XS/main/utils.h
@@ -194,6 +194,9 @@ void add_include_directory (const char *filename,
STRING_LIST *include_dirs_list);
char *locate_include_file (const char *filename,
const STRING_LIST *include_dirs_list);
+char *locate_file_in_dirs (const char *filename,
+ const STRING_LIST *directories,
+ STRING_LIST *all_files);
ENCODING_CONVERSION *get_encoding_conversion (const char *encoding,
ENCODING_CONVERSION_LIST *encodings_list);
diff --git a/tp/Texinfo/XS/teximakehtml.c b/tp/Texinfo/XS/teximakehtml.c
index b7e15e78c4..3d5f4764d2 100644
--- a/tp/Texinfo/XS/teximakehtml.c
+++ b/tp/Texinfo/XS/teximakehtml.c
@@ -100,6 +100,10 @@ main (int argc, char *argv[])
OPTIONS_LIST convert_options;
size_t errors_count = 0;
size_t errors_nr;
+ char *texinfo_language_config_dirs[5] = {".texinfo"};
+ int txi_language_idx = 1;
+ char *home_dir;
+ char *home_texinfo_language_config_dirs = 0;
/*
const char *texinfo_text;
@@ -123,6 +127,33 @@ main (int argc, char *argv[])
txi_setup (LOCALEDIR, 0, 0, 0, 0);
+
+ home_dir = getenv ("HOME");
+ if (home_dir)
+ {
+ xasprintf (&home_texinfo_language_config_dirs, "%s/.texinfo",
+ home_dir);
+ texinfo_language_config_dirs[txi_language_idx]
+ = home_texinfo_language_config_dirs;
+ txi_language_idx++;
+ }
+ if (strlen (SYSCONFDIR))
+ {
+ texinfo_language_config_dirs[txi_language_idx]
+ = SYSCONFDIR "/texinfo";
+ txi_language_idx++;
+ }
+
+ if (strlen (DATADIR))
+ {
+ texinfo_language_config_dirs[txi_language_idx]
+ = DATADIR "/texinfo";
+ txi_language_idx++;
+ }
+
+ texinfo_language_config_dirs[txi_language_idx] = 0;
+
+
parse_file_path (argv[0], program_file_name_and_directory);
program_file = program_file_name_and_directory[0];
free (program_file_name_and_directory[1]);
@@ -194,14 +225,19 @@ main (int argc, char *argv[])
add_new_option_value (&convert_options, GOT_integer,
"PROGRAM_NAME_IN_FOOTER", 1, 0);
/* this is set to help with comparison with previous invokations */
+ /*
add_new_option_value (&convert_options, GOT_integer,
"TEST", 1, 0);
+ */
converter = txi_converter_setup ("html", "html", locale_encoding,
- program_file, &convert_options);
+ program_file,
+ texinfo_language_config_dirs,
+ &convert_options);
free_options_list (&convert_options);
free (program_file);
+ free (home_texinfo_language_config_dirs);
/* conversion */