libstdc++: Remove std::__unicode::__null_sentinel
[official-gcc.git] / gcc / gcc-urlifier.cc
blob6bd176fc24834b4d3801a77601335b179dc4c198
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 "selftest.h"
31 namespace {
33 /* Concrete subclass of urlifier for generating links into
34 GCC's HTML documentation. */
36 class gcc_urlifier : public urlifier
38 public:
39 gcc_urlifier (unsigned int lang_mask)
40 : m_lang_mask (lang_mask)
43 char *get_url_for_quoted_text (const char *p, size_t sz) const final override;
45 label_text get_url_suffix_for_quoted_text (const char *p, size_t sz) const;
46 /* We use ATTRIBUTE_UNUSED as this helper is called only from ASSERTs. */
47 label_text get_url_suffix_for_quoted_text (const char *p) const ATTRIBUTE_UNUSED;
49 private:
50 label_text get_url_suffix_for_option (const char *p, size_t sz) const;
52 static char *
53 make_doc_url (const char *doc_url_suffix);
55 unsigned int m_lang_mask;
58 /* class gcc_urlifier : public urlifier. */
60 /* Manage a hard-coded mapping from quoted string to URL suffixes
61 in gcc-urlifier.def */
63 #define DOC_URL(QUOTED_TEXT, URL_SUFFIX) \
64 { (QUOTED_TEXT), (URL_SUFFIX) }
66 static const struct
68 const char *quoted_text;
69 const char *url_suffix;
70 } doc_urls[] = {
72 #include "gcc-urlifier.def"
76 /* Implementation of urlifier::get_url_for_quoted_text vfunc for GCC
77 diagnostics. */
79 char *
80 gcc_urlifier::get_url_for_quoted_text (const char *p, size_t sz) const
82 label_text url_suffix = get_url_suffix_for_quoted_text (p, sz);
83 if (url_suffix.get ())
84 return make_doc_url (url_suffix.get ());
85 return nullptr;
88 /* Look for a URL for the quoted string (P, SZ).
89 Return the url suffix if found, or nullptr otherwise. */
91 label_text
92 gcc_urlifier::get_url_suffix_for_quoted_text (const char *p, size_t sz) const
94 if (sz == 0)
95 return label_text ();
97 /* If this is an option, look up the option and see if we have
98 a URL for it. */
99 if (p[0] == '-')
101 label_text suffix = get_url_suffix_for_option (p, sz);
102 if (suffix.get ())
103 return suffix;
106 /* Otherwise, look within the hard-coded data table in gcc-urlifier.def.
108 Binary search. This assumes that the quoted_text fields of doc_urls
109 are in sorted order. */
110 int min = 0;
111 int max = ARRAY_SIZE (doc_urls) - 1;
112 while (true)
114 if (min > max)
115 return label_text ();
116 int midpoint = (min + max) / 2;
117 gcc_assert ((size_t)midpoint < ARRAY_SIZE (doc_urls));
118 int cmp = strncmp (p, doc_urls[midpoint].quoted_text, sz);
119 if (cmp == 0)
121 if (doc_urls[midpoint].quoted_text[sz] == '\0')
122 return label_text::borrow (doc_urls[midpoint].url_suffix);
123 else
124 max = midpoint - 1;
126 else if (cmp < 0)
127 max = midpoint - 1;
128 else
129 min = midpoint + 1;
132 /* Not found. */
133 return label_text ();
136 /* For use in selftests. */
138 label_text
139 gcc_urlifier::get_url_suffix_for_quoted_text (const char *p) const
141 return get_url_suffix_for_quoted_text (p, strlen (p));
144 /* Look for a URL for the quoted string (P, SZ) that appears to be
145 an option.
146 Return the url suffix if found, or nullptr otherwise. */
148 label_text
149 gcc_urlifier::get_url_suffix_for_option (const char *p, size_t sz) const
151 /* Look up this option
153 find_opt does a binary search, taking a 0-terminated string,
154 and skipping the leading '-'.
156 We have a (pointer,size) pair that doesn't necessarily have a
157 terminator, so create a 0-terminated clone of the string. */
158 gcc_assert (sz > 0);
159 char *tmp = xstrndup (p + 1, sz - 1); // skip the leading '-'
160 size_t opt = find_opt (tmp, m_lang_mask);
161 free (tmp);
163 if (opt >= N_OPTS)
164 /* Option not recognized. */
165 return label_text ();
167 return get_option_url_suffix (opt, m_lang_mask);
170 char *
171 gcc_urlifier::make_doc_url (const char *doc_url_suffix)
173 if (!doc_url_suffix)
174 return nullptr;
176 return concat (DOCUMENTATION_ROOT_URL, doc_url_suffix, nullptr);
179 } // anonymous namespace
181 urlifier *
182 make_gcc_urlifier (unsigned int lang_mask)
184 return new gcc_urlifier (lang_mask);
187 #if CHECKING_P
189 namespace selftest {
191 /* Selftests. */
193 /* Run all of the selftests within this file. */
195 void
196 gcc_urlifier_cc_tests ()
198 /* Check that doc_urls.quoted_text is sorted. */
199 for (size_t idx = 1; idx < ARRAY_SIZE (doc_urls); idx++)
200 gcc_assert (strcmp (doc_urls[idx - 1].quoted_text,
201 doc_urls[idx].quoted_text)
202 < 0);
204 gcc_urlifier u (0);
206 ASSERT_EQ (u.get_url_suffix_for_quoted_text ("").get (), nullptr);
207 ASSERT_EQ (u.get_url_suffix_for_quoted_text (")").get (), nullptr);
209 ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("#pragma message").get (),
210 "gcc/Diagnostic-Pragmas.html");
212 // Incomplete prefix of a quoted_text
213 ASSERT_EQ (u.get_url_suffix_for_quoted_text ("#pragma mess").get (), nullptr);
215 /* Check that every element is findable. */
216 for (size_t idx = 0; idx < ARRAY_SIZE (doc_urls); idx++)
217 ASSERT_STREQ
218 (u.get_url_suffix_for_quoted_text (doc_urls[idx].quoted_text).get (),
219 doc_urls[idx].url_suffix);
221 /* Check an option. */
222 ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("-fpack-struct").get (),
223 "gcc/Code-Gen-Options.html#index-fpack-struct");
226 } // namespace selftest
228 #endif /* #if CHECKING_P */