options: wire up options-urls.cc into gcc_urlifier
Changed in v2: - split out from the code that generates options-urls.cc - call the generated function, rather than use a generated array - pass around lang_mask gcc/ChangeLog: * diagnostic.h (diagnostic_make_option_url_cb): Add lang_mask param. (diagnostic_context::make_option_url): Update for lang_mask param. * gcc-urlifier.cc: Include "opts.h" and "options.h". (gcc_urlifier::gcc_urlifier): Add lang_mask param. (gcc_urlifier::m_lang_mask): New field. (doc_urls): Make static. (gcc_urlifier::get_url_for_quoted_text): Use label_text. (gcc_urlifier::get_url_suffix_for_quoted_text): Use label_text. Look for an option by name before trying a binary search in doc_urls. (gcc_urlifier::get_url_suffix_for_quoted_text): Use label_text. (gcc_urlifier::get_url_suffix_for_option): New. (make_gcc_urlifier): Add lang_mask param. (selftest::gcc_urlifier_cc_tests): Update for above changes. Verify that a URL is found for "-fpack-struct". * gcc-urlifier.def: Drop options "--version" and "-fpack-struct". * gcc-urlifier.h (make_gcc_urlifier): Add lang_mask param. * gcc.cc (driver::global_initializations): Pass 0 for lang_mask to make_gcc_urlifier. * opts-diagnostic.h (get_option_url): Add lang_mask param. * opts.cc (get_option_html_page): Remove special-casing for analyzer and LTO. (get_option_url_suffix): New. (get_option_url): Reimplement. (selftest::test_get_option_html_page): Rename to... (selftest::test_get_option_url_suffix): ...this and update for above changes. (selftest::opts_cc_tests): Update for renaming. * opts.h: Include "rich-location.h". (get_option_url_suffix): New decl. gcc/testsuite/ChangeLog: * lib/gcc-dg.exp: Set TERM to xterm. gcc/ChangeLog: * toplev.cc (general_init): Pass lang_mask to urlifier. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
6ecc1e3235
commit
4ded42c2c5
10 changed files with 168 additions and 61 deletions
|
@ -186,7 +186,8 @@ typedef char *(*diagnostic_make_option_name_cb) (const diagnostic_context *,
|
|||
diagnostic_t,
|
||||
diagnostic_t);
|
||||
typedef char *(*diagnostic_make_option_url_cb) (const diagnostic_context *,
|
||||
int);
|
||||
int,
|
||||
unsigned);
|
||||
|
||||
class edit_context;
|
||||
namespace json { class value; }
|
||||
|
@ -526,7 +527,8 @@ public:
|
|||
{
|
||||
if (!m_option_callbacks.m_make_option_url_cb)
|
||||
return nullptr;
|
||||
return m_option_callbacks.m_make_option_url_cb (this, option_index);
|
||||
return m_option_callbacks.m_make_option_url_cb (this, option_index,
|
||||
get_lang_mask ());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -24,6 +24,8 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "pretty-print.h"
|
||||
#include "pretty-print-urlifier.h"
|
||||
#include "gcc-urlifier.h"
|
||||
#include "opts.h"
|
||||
#include "options.h"
|
||||
#include "selftest.h"
|
||||
|
||||
namespace {
|
||||
|
@ -34,23 +36,34 @@ namespace {
|
|||
class gcc_urlifier : public urlifier
|
||||
{
|
||||
public:
|
||||
gcc_urlifier (unsigned int lang_mask)
|
||||
: m_lang_mask (lang_mask)
|
||||
{}
|
||||
|
||||
char *get_url_for_quoted_text (const char *p, size_t sz) const final override;
|
||||
|
||||
const char *get_url_suffix_for_quoted_text (const char *p, size_t sz) const;
|
||||
label_text get_url_suffix_for_quoted_text (const char *p, size_t sz) const;
|
||||
/* We use ATTRIBUTE_UNUSED as this helper is called only from ASSERTs. */
|
||||
const char *get_url_suffix_for_quoted_text (const char *p) const ATTRIBUTE_UNUSED;
|
||||
label_text get_url_suffix_for_quoted_text (const char *p) const ATTRIBUTE_UNUSED;
|
||||
|
||||
private:
|
||||
label_text get_url_suffix_for_option (const char *p, size_t sz) const;
|
||||
|
||||
static char *
|
||||
make_doc_url (const char *doc_url_suffix);
|
||||
|
||||
unsigned int m_lang_mask;
|
||||
};
|
||||
|
||||
/* class gcc_urlifier : public urlifier. */
|
||||
|
||||
/* Manage a hard-coded mapping from quoted string to URL suffixes
|
||||
in gcc-urlifier.def */
|
||||
|
||||
#define DOC_URL(QUOTED_TEXT, URL_SUFFIX) \
|
||||
{ (QUOTED_TEXT), (URL_SUFFIX) }
|
||||
|
||||
const struct
|
||||
static const struct
|
||||
{
|
||||
const char *quoted_text;
|
||||
const char *url_suffix;
|
||||
|
@ -60,32 +73,53 @@ const struct
|
|||
|
||||
};
|
||||
|
||||
/* Implementation of urlifier::get_url_for_quoted_text vfunc for GCC
|
||||
diagnostics. */
|
||||
|
||||
char *
|
||||
gcc_urlifier::get_url_for_quoted_text (const char *p, size_t sz) const
|
||||
{
|
||||
if (const char *url_suffix = get_url_suffix_for_quoted_text (p, sz))
|
||||
return make_doc_url (url_suffix);
|
||||
label_text url_suffix = get_url_suffix_for_quoted_text (p, sz);
|
||||
if (url_suffix.get ())
|
||||
return make_doc_url (url_suffix.get ());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *
|
||||
/* Look for a URL for the quoted string (P, SZ).
|
||||
Return the url suffix if found, or nullptr otherwise. */
|
||||
|
||||
label_text
|
||||
gcc_urlifier::get_url_suffix_for_quoted_text (const char *p, size_t sz) const
|
||||
{
|
||||
/* Binary search. This assumes that the quoted_text fields of doc_urls
|
||||
if (sz == 0)
|
||||
return label_text ();
|
||||
|
||||
/* If this is an option, look up the option and see if we have
|
||||
a URL for it. */
|
||||
if (p[0] == '-')
|
||||
{
|
||||
label_text suffix = get_url_suffix_for_option (p, sz);
|
||||
if (suffix.get ())
|
||||
return suffix;
|
||||
}
|
||||
|
||||
/* Otherwise, look within the hard-coded data table in gcc-urlifier.def.
|
||||
|
||||
Binary search. This assumes that the quoted_text fields of doc_urls
|
||||
are in sorted order. */
|
||||
int min = 0;
|
||||
int max = ARRAY_SIZE (doc_urls) - 1;
|
||||
while (true)
|
||||
{
|
||||
if (min > max)
|
||||
return nullptr;
|
||||
return label_text ();
|
||||
int midpoint = (min + max) / 2;
|
||||
gcc_assert ((size_t)midpoint < ARRAY_SIZE (doc_urls));
|
||||
int cmp = strncmp (p, doc_urls[midpoint].quoted_text, sz);
|
||||
if (cmp == 0)
|
||||
{
|
||||
if (doc_urls[midpoint].quoted_text[sz] == '\0')
|
||||
return doc_urls[midpoint].url_suffix;
|
||||
return label_text::borrow (doc_urls[midpoint].url_suffix);
|
||||
else
|
||||
max = midpoint - 1;
|
||||
}
|
||||
|
@ -94,15 +128,45 @@ gcc_urlifier::get_url_suffix_for_quoted_text (const char *p, size_t sz) const
|
|||
else
|
||||
min = midpoint + 1;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
/* Not found. */
|
||||
return label_text ();
|
||||
}
|
||||
|
||||
const char *
|
||||
/* For use in selftests. */
|
||||
|
||||
label_text
|
||||
gcc_urlifier::get_url_suffix_for_quoted_text (const char *p) const
|
||||
{
|
||||
return get_url_suffix_for_quoted_text (p, strlen (p));
|
||||
}
|
||||
|
||||
/* Look for a URL for the quoted string (P, SZ) that appears to be
|
||||
an option.
|
||||
Return the url suffix if found, or nullptr otherwise. */
|
||||
|
||||
label_text
|
||||
gcc_urlifier::get_url_suffix_for_option (const char *p, size_t sz) const
|
||||
{
|
||||
/* Look up this option
|
||||
|
||||
find_opt does a binary search, taking a 0-terminated string,
|
||||
and skipping the leading '-'.
|
||||
|
||||
We have a (pointer,size) pair that doesn't necessarily have a
|
||||
terminator, so create a 0-terminated clone of the string. */
|
||||
gcc_assert (sz > 0);
|
||||
char *tmp = xstrndup (p + 1, sz - 1); // skip the leading '-'
|
||||
size_t opt = find_opt (tmp, m_lang_mask);
|
||||
free (tmp);
|
||||
|
||||
if (opt >= N_OPTS)
|
||||
/* Option not recognized. */
|
||||
return label_text ();
|
||||
|
||||
return get_option_url_suffix (opt, m_lang_mask);
|
||||
}
|
||||
|
||||
char *
|
||||
gcc_urlifier::make_doc_url (const char *doc_url_suffix)
|
||||
{
|
||||
|
@ -115,9 +179,9 @@ gcc_urlifier::make_doc_url (const char *doc_url_suffix)
|
|||
} // anonymous namespace
|
||||
|
||||
urlifier *
|
||||
make_gcc_urlifier ()
|
||||
make_gcc_urlifier (unsigned int lang_mask)
|
||||
{
|
||||
return new gcc_urlifier ();
|
||||
return new gcc_urlifier (lang_mask);
|
||||
}
|
||||
|
||||
#if CHECKING_P
|
||||
|
@ -137,22 +201,26 @@ gcc_urlifier_cc_tests ()
|
|||
doc_urls[idx].quoted_text)
|
||||
< 0);
|
||||
|
||||
gcc_urlifier u;
|
||||
gcc_urlifier u (0);
|
||||
|
||||
ASSERT_EQ (u.get_url_suffix_for_quoted_text (""), nullptr);
|
||||
ASSERT_EQ (u.get_url_suffix_for_quoted_text (")"), nullptr);
|
||||
ASSERT_EQ (u.get_url_suffix_for_quoted_text ("").get (), nullptr);
|
||||
ASSERT_EQ (u.get_url_suffix_for_quoted_text (")").get (), nullptr);
|
||||
|
||||
ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("#pragma message"),
|
||||
ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("#pragma message").get (),
|
||||
"gcc/Diagnostic-Pragmas.html");
|
||||
|
||||
// Incomplete prefix of a quoted_text
|
||||
ASSERT_EQ (u.get_url_suffix_for_quoted_text ("#pragma mess"), nullptr);
|
||||
ASSERT_EQ (u.get_url_suffix_for_quoted_text ("#pragma mess").get (), nullptr);
|
||||
|
||||
/* Check that every element is findable. */
|
||||
for (size_t idx = 0; idx < ARRAY_SIZE (doc_urls); idx++)
|
||||
ASSERT_STREQ
|
||||
(u.get_url_suffix_for_quoted_text (doc_urls[idx].quoted_text),
|
||||
(u.get_url_suffix_for_quoted_text (doc_urls[idx].quoted_text).get (),
|
||||
doc_urls[idx].url_suffix);
|
||||
|
||||
/* Check an option. */
|
||||
ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("-fpack-struct").get (),
|
||||
"gcc/Code-Gen-Options.html#index-fpack-struct");
|
||||
}
|
||||
|
||||
} // namespace selftest
|
||||
|
|
|
@ -16,5 +16,3 @@ DOC_URL ("#pragma pack", "gcc/Structure-Layout-Pragmas.html"),
|
|||
DOC_URL ("#pragma redefine_extname", "gcc/Symbol-Renaming-Pragmas.html"),
|
||||
DOC_URL ("#pragma scalar_storage_order", "gcc/Structure-Layout-Pragmas.html"),
|
||||
DOC_URL ("#pragma weak", "gcc/Weak-Pragmas.html"),
|
||||
DOC_URL ("--version", "gcc/Overall-Options.html#index-version"),
|
||||
DOC_URL ("-fpack-struct", "gcc/Code-Gen-Options.html#index-fpack-struct"),
|
||||
|
|
|
@ -21,6 +21,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
#ifndef GCC_GCC_URLIFIER_H
|
||||
#define GCC_GCC_URLIFIER_H
|
||||
|
||||
extern urlifier *make_gcc_urlifier ();
|
||||
extern urlifier *make_gcc_urlifier (unsigned int lang_mask);
|
||||
|
||||
#endif /* GCC_GCC_URLIFIER_H */
|
||||
|
|
|
@ -8340,7 +8340,7 @@ driver::global_initializations ()
|
|||
diagnostic_initialize (global_dc, 0);
|
||||
diagnostic_color_init (global_dc);
|
||||
diagnostic_urls_init (global_dc);
|
||||
global_dc->set_urlifier (make_gcc_urlifier ());
|
||||
global_dc->set_urlifier (make_gcc_urlifier (0));
|
||||
|
||||
#ifdef GCC_DRIVER_HOST_INITIALIZATION
|
||||
/* Perform host dependent initialization when needed. */
|
||||
|
|
|
@ -24,6 +24,7 @@ extern char *option_name (const diagnostic_context *context, int option_index,
|
|||
diagnostic_t orig_diag_kind, diagnostic_t diag_kind);
|
||||
|
||||
extern char *get_option_url (const diagnostic_context *context,
|
||||
int option_index);
|
||||
int option_index,
|
||||
unsigned lang_mask);
|
||||
|
||||
#endif
|
||||
|
|
93
gcc/opts.cc
93
gcc/opts.cc
|
@ -3710,14 +3710,6 @@ get_option_html_page (int option_index)
|
|||
{
|
||||
const cl_option *cl_opt = &cl_options[option_index];
|
||||
|
||||
/* Analyzer options are on their own page. */
|
||||
if (strstr (cl_opt->opt_text, "analyzer-"))
|
||||
return "gcc/Static-Analyzer-Options.html";
|
||||
|
||||
/* Handle -flto= option. */
|
||||
if (strstr (cl_opt->opt_text, "flto"))
|
||||
return "gcc/Optimize-Options.html";
|
||||
|
||||
#ifdef CL_Fortran
|
||||
if ((cl_opt->flags & CL_Fortran) != 0
|
||||
/* If it is option common to both C/C++ and Fortran, it is documented
|
||||
|
@ -3730,32 +3722,49 @@ get_option_html_page (int option_index)
|
|||
return "gfortran/Error-and-Warning-Options.html";
|
||||
#endif
|
||||
|
||||
return "gcc/Warning-Options.html";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Get the url within the documentation for this option, or NULL. */
|
||||
|
||||
label_text
|
||||
get_option_url_suffix (int option_index, unsigned lang_mask)
|
||||
{
|
||||
if (const char *url = get_opt_url_suffix (option_index, lang_mask))
|
||||
|
||||
return label_text::borrow (url);
|
||||
|
||||
/* Fallback code for some options that aren't handled byt opt_url_suffixes
|
||||
e.g. links below "gfortran/". */
|
||||
if (const char *html_page = get_option_html_page (option_index))
|
||||
return label_text::take
|
||||
(concat (html_page,
|
||||
/* Expect an anchor of the form "index-Wfoo" e.g.
|
||||
<a name="index-Wformat"></a>, and thus an id within
|
||||
the page of "#index-Wformat". */
|
||||
"#index",
|
||||
cl_options[option_index].opt_text,
|
||||
NULL));
|
||||
|
||||
return label_text ();
|
||||
}
|
||||
|
||||
/* Return malloced memory for a URL describing the option OPTION_INDEX
|
||||
which enabled a diagnostic (context CONTEXT). */
|
||||
|
||||
char *
|
||||
get_option_url (const diagnostic_context *, int option_index)
|
||||
get_option_url (const diagnostic_context *,
|
||||
int option_index,
|
||||
unsigned lang_mask)
|
||||
{
|
||||
if (option_index)
|
||||
return concat (/* DOCUMENTATION_ROOT_URL should be supplied via
|
||||
#include "config.h" (see --with-documentation-root-url),
|
||||
and should have a trailing slash. */
|
||||
DOCUMENTATION_ROOT_URL,
|
||||
{
|
||||
label_text url_suffix = get_option_url_suffix (option_index, lang_mask);
|
||||
if (url_suffix.get ())
|
||||
return concat (DOCUMENTATION_ROOT_URL, url_suffix.get (), nullptr);
|
||||
}
|
||||
|
||||
/* get_option_html_page will return something like
|
||||
"gcc/Warning-Options.html". */
|
||||
get_option_html_page (option_index),
|
||||
|
||||
/* Expect an anchor of the form "index-Wfoo" e.g.
|
||||
<a name="index-Wformat"></a>, and thus an id within
|
||||
the URL of "#index-Wformat". */
|
||||
"#index", cl_options[option_index].opt_text,
|
||||
NULL);
|
||||
else
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Return a heap allocated producer with command line options. */
|
||||
|
@ -3886,17 +3895,35 @@ gen_producer_string (const char *language_string, cl_decoded_option *options,
|
|||
|
||||
namespace selftest {
|
||||
|
||||
/* Verify that get_option_html_page works as expected. */
|
||||
/* Verify that get_option_url_suffix works as expected. */
|
||||
|
||||
static void
|
||||
test_get_option_html_page ()
|
||||
test_get_option_url_suffix ()
|
||||
{
|
||||
ASSERT_STREQ (get_option_html_page (OPT_Wcpp), "gcc/Warning-Options.html");
|
||||
ASSERT_STREQ (get_option_html_page (OPT_Wanalyzer_double_free),
|
||||
"gcc/Static-Analyzer-Options.html");
|
||||
ASSERT_STREQ (get_option_url_suffix (OPT_Wcpp, 0).get (),
|
||||
"gcc/Warning-Options.html#index-Wcpp");
|
||||
ASSERT_STREQ (get_option_url_suffix (OPT_Wanalyzer_double_free, 0).get (),
|
||||
"gcc/Static-Analyzer-Options.html#index-Wanalyzer-double-free");
|
||||
|
||||
/* Test of a D-specific option. */
|
||||
#ifdef CL_D
|
||||
ASSERT_EQ (get_option_url_suffix (OPT_fbounds_check_, 0).get (), nullptr);
|
||||
ASSERT_STREQ (get_option_url_suffix (OPT_fbounds_check_, CL_D).get (),
|
||||
"gdc/Runtime-Options.html#index-fbounds-check");
|
||||
|
||||
/* Test of a D-specific override to an option URL. */
|
||||
/* Generic URL. */
|
||||
ASSERT_STREQ (get_option_url_suffix (OPT_fmax_errors_, 0).get (),
|
||||
"gcc/Warning-Options.html#index-fmax-errors");
|
||||
/* D-specific URL. */
|
||||
ASSERT_STREQ (get_option_url_suffix (OPT_fmax_errors_, CL_D).get (),
|
||||
"gdc/Warnings.html#index-fmax-errors");
|
||||
#endif
|
||||
|
||||
#ifdef CL_Fortran
|
||||
ASSERT_STREQ (get_option_html_page (OPT_Wline_truncation),
|
||||
"gfortran/Error-and-Warning-Options.html");
|
||||
ASSERT_STREQ
|
||||
(get_option_url_suffix (OPT_Wline_truncation, CL_Fortran).get (),
|
||||
"gfortran/Error-and-Warning-Options.html#index-Wline-truncation");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3959,7 +3986,7 @@ test_enum_sets ()
|
|||
void
|
||||
opts_cc_tests ()
|
||||
{
|
||||
test_get_option_html_page ();
|
||||
test_get_option_url_suffix ();
|
||||
test_enum_sets ();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#ifndef GCC_OPTS_H
|
||||
#define GCC_OPTS_H
|
||||
|
||||
#include "rich-location.h"
|
||||
#include "obstack.h"
|
||||
|
||||
/* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR. */
|
||||
|
@ -569,4 +570,7 @@ struct switchstr
|
|||
bool ordering;
|
||||
};
|
||||
|
||||
extern label_text
|
||||
get_option_url_suffix (int option_index, unsigned lang_mask);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,12 @@ if { [ishost "*-*-cygwin*"] } {
|
|||
setenv LANG C.ASCII
|
||||
}
|
||||
|
||||
# Set TERM to xterm to ensure that URL escapes are disabled.
|
||||
# This avoids issues where a diagnostic which could embed a URL
|
||||
# is emitted before -fdiagnostics-plain-output is handled, where
|
||||
# otherwise the output could be affected by the environment.
|
||||
setenv TERM xterm
|
||||
|
||||
# Avoid sporadic data-losses with expect
|
||||
match_max -d 10000
|
||||
|
||||
|
|
|
@ -1044,12 +1044,13 @@ general_init (const char *argv0, bool init_signals)
|
|||
global_dc->m_show_column
|
||||
= global_options_init.x_flag_show_column;
|
||||
global_dc->m_internal_error = internal_error_function;
|
||||
const unsigned lang_mask = lang_hooks.option_lang_mask ();
|
||||
global_dc->set_option_hooks (option_enabled,
|
||||
&global_options,
|
||||
option_name,
|
||||
get_option_url,
|
||||
lang_hooks.option_lang_mask ());
|
||||
global_dc->set_urlifier (make_gcc_urlifier ());
|
||||
lang_mask);
|
||||
global_dc->set_urlifier (make_gcc_urlifier (lang_mask));
|
||||
|
||||
if (init_signals)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue