[testsuite] [i386] work around fails with --enable-frame-pointer
[official-gcc.git] / gcc / gcc-urlifier.cc
blobff8c3f65ac569882255817ab62c79ce4b76d8f5d
1 /* Automatic generation of links into GCC's documentation.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "pretty-print.h"
25 #include "pretty-print-urlifier.h"
26 #include "gcc-urlifier.h"
27 #include "opts.h"
28 #include "options.h"
29 #include "diagnostic-core.h"
30 #include "selftest.h"
32 namespace {
34 /* Concrete subclass of urlifier for generating links into
35 GCC's HTML documentation. */
37 class gcc_urlifier : public urlifier
39 public:
40 gcc_urlifier (unsigned int lang_mask)
41 : m_lang_mask (lang_mask)
44 char *get_url_for_quoted_text (const char *p, size_t sz) const final override;
46 label_text get_url_suffix_for_quoted_text (const char *p, size_t sz) const;
47 /* We use ATTRIBUTE_UNUSED as this helper is called only from ASSERTs. */
48 label_text get_url_suffix_for_quoted_text (const char *p) const ATTRIBUTE_UNUSED;
50 private:
51 label_text get_url_suffix_for_option (const char *p, size_t sz) const;
53 static char *
54 make_doc_url (const char *doc_url_suffix);
56 unsigned int m_lang_mask;
59 /* class gcc_urlifier : public urlifier. */
61 /* Manage a hard-coded mapping from quoted string to URL suffixes
62 in gcc-urlifier.def */
64 #define DOC_URL(QUOTED_TEXT, URL_SUFFIX) \
65 { (QUOTED_TEXT), (URL_SUFFIX) }
67 static const struct
69 const char *quoted_text;
70 const char *url_suffix;
71 } doc_urls[] = {
73 #include "gcc-urlifier.def"
77 /* Implementation of urlifier::get_url_for_quoted_text vfunc for GCC
78 diagnostics. */
80 char *
81 gcc_urlifier::get_url_for_quoted_text (const char *p, size_t sz) const
83 label_text url_suffix = get_url_suffix_for_quoted_text (p, sz);
84 if (url_suffix.get ())
85 return make_doc_url (url_suffix.get ());
86 return nullptr;
89 /* Look for a URL for the quoted string (P, SZ).
90 Return the url suffix if found, or nullptr otherwise. */
92 label_text
93 gcc_urlifier::get_url_suffix_for_quoted_text (const char *p, size_t sz) const
95 if (sz == 0)
96 return label_text ();
98 /* If this is an option, look up the option and see if we have
99 a URL for it. */
100 if (p[0] == '-')
102 label_text suffix = get_url_suffix_for_option (p, sz);
103 if (suffix.get ())
104 return suffix;
107 /* Otherwise, look within the hard-coded data table in gcc-urlifier.def.
109 Binary search. This assumes that the quoted_text fields of doc_urls
110 are in sorted order. */
111 int min = 0;
112 int max = ARRAY_SIZE (doc_urls) - 1;
113 while (true)
115 if (min > max)
116 return label_text ();
117 int midpoint = (min + max) / 2;
118 gcc_assert ((size_t)midpoint < ARRAY_SIZE (doc_urls));
119 int cmp = strncmp (p, doc_urls[midpoint].quoted_text, sz);
120 if (cmp == 0)
122 if (doc_urls[midpoint].quoted_text[sz] == '\0')
123 return label_text::borrow (doc_urls[midpoint].url_suffix);
124 else
125 max = midpoint - 1;
127 else if (cmp < 0)
128 max = midpoint - 1;
129 else
130 min = midpoint + 1;
133 /* Not found. */
134 return label_text ();
137 /* For use in selftests. */
139 label_text
140 gcc_urlifier::get_url_suffix_for_quoted_text (const char *p) const
142 return get_url_suffix_for_quoted_text (p, strlen (p));
145 /* Look for a URL for the quoted string (P, SZ) that appears to be
146 an option.
147 Return the url suffix if found, or nullptr otherwise. */
149 label_text
150 gcc_urlifier::get_url_suffix_for_option (const char *p, size_t sz) const
152 /* Look up this option
154 find_opt does a binary search, taking a 0-terminated string,
155 and skipping the leading '-'.
157 We have a (pointer,size) pair that doesn't necessarily have a
158 terminator.
159 Additionally, we could have one of the e.g. "-Wno-" variants of
160 the option, which find_opt doesn't handle.
162 Hence we need to create input for find_opt in a temporary buffer. */
163 char *option_buffer;
165 const char *new_prefix;
166 if (const char *old_prefix = get_option_prefix_remapping (p, sz, &new_prefix))
168 /* We have one of the variants; generate a buffer containing a copy
169 that maps from the old prefix to the new prefix
170 e.g. given "-Wno-suffix", generate "-Wsuffix". */
171 gcc_assert (old_prefix[0] == '-');
172 gcc_assert (new_prefix);
173 gcc_assert (new_prefix[0] == '-');
175 const size_t old_prefix_len = strlen (old_prefix);
176 gcc_assert (old_prefix_len <= sz);
177 const size_t suffix_len = sz - old_prefix_len;
178 const size_t new_prefix_len = strlen (new_prefix);
179 const size_t new_sz = new_prefix_len + suffix_len + 1;
181 option_buffer = (char *)xmalloc (new_sz);
182 memcpy (option_buffer, new_prefix, new_prefix_len);
183 /* Copy suffix. */
184 memcpy (option_buffer + new_prefix_len, p + old_prefix_len, suffix_len);
185 /* Terminate. */
186 option_buffer[new_prefix_len + suffix_len] = '\0';
188 else
190 /* Otherwise we can simply create a 0-terminated clone of the string. */
191 gcc_assert (sz > 0);
192 gcc_assert (p[0] == '-');
193 option_buffer = xstrndup (p, sz);
196 size_t opt = find_opt (option_buffer + 1, m_lang_mask);
197 free (option_buffer);
199 if (opt >= N_OPTS)
200 /* Option not recognized. */
201 return label_text ();
203 return get_option_url_suffix (opt, m_lang_mask);
206 char *
207 gcc_urlifier::make_doc_url (const char *doc_url_suffix)
209 if (!doc_url_suffix)
210 return nullptr;
212 char infix[32];
213 /* On release branches, append to DOCUMENTATION_ROOT_URL the
214 subdirectory with documentation of the latest release made
215 from the branch. */
216 if (BUILDING_GCC_MINOR != 0 && BUILDING_GCC_PATCHLEVEL <= 1U)
217 sprintf (infix, "gcc-%u.%u.0/",
218 BUILDING_GCC_MAJOR, BUILDING_GCC_MINOR);
219 else
220 infix[0] = '\0';
221 return concat (DOCUMENTATION_ROOT_URL, infix, doc_url_suffix, nullptr);
224 } // anonymous namespace
226 urlifier *
227 make_gcc_urlifier (unsigned int lang_mask)
229 return new gcc_urlifier (lang_mask);
232 #if CHECKING_P
234 namespace selftest {
236 /* Selftests. */
238 /* Run all of the selftests within this file. */
240 void
241 gcc_urlifier_cc_tests ()
243 /* Check that doc_urls.quoted_text is sorted. */
244 for (size_t idx = 1; idx < ARRAY_SIZE (doc_urls); idx++)
245 gcc_assert (strcmp (doc_urls[idx - 1].quoted_text,
246 doc_urls[idx].quoted_text)
247 < 0);
249 gcc_urlifier u (0);
251 ASSERT_EQ (u.get_url_suffix_for_quoted_text ("").get (), nullptr);
252 ASSERT_EQ (u.get_url_suffix_for_quoted_text (")").get (), nullptr);
254 ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("#pragma message").get (),
255 "gcc/Diagnostic-Pragmas.html");
257 // Incomplete prefix of a quoted_text
258 ASSERT_EQ (u.get_url_suffix_for_quoted_text ("#pragma mess").get (), nullptr);
260 /* Check that every element is findable. */
261 for (size_t idx = 0; idx < ARRAY_SIZE (doc_urls); idx++)
262 ASSERT_STREQ
263 (u.get_url_suffix_for_quoted_text (doc_urls[idx].quoted_text).get (),
264 doc_urls[idx].url_suffix);
266 /* Check an option. */
267 ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("-fpack-struct").get (),
268 "gcc/Code-Gen-Options.html#index-fpack-struct");
270 /* Check a "-fno-" variant of an option. */
271 ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("-fno-inline").get (),
272 "gcc/Optimize-Options.html#index-finline");
275 } // namespace selftest
277 #endif /* #if CHECKING_P */