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
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
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/>. */
23 #include "coretypes.h"
24 #include "pretty-print.h"
25 #include "pretty-print-urlifier.h"
26 #include "gcc-urlifier.h"
33 /* Concrete subclass of urlifier for generating links into
34 GCC's HTML documentation. */
36 class gcc_urlifier
: public urlifier
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
;
50 label_text
get_url_suffix_for_option (const char *p
, size_t sz
) const;
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) }
68 const char *quoted_text
;
69 const char *url_suffix
;
72 #include "gcc-urlifier.def"
76 /* Implementation of urlifier::get_url_for_quoted_text vfunc for GCC
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 ());
88 /* Look for a URL for the quoted string (P, SZ).
89 Return the url suffix if found, or nullptr otherwise. */
92 gcc_urlifier::get_url_suffix_for_quoted_text (const char *p
, size_t sz
) const
97 /* If this is an option, look up the option and see if we have
101 label_text suffix
= get_url_suffix_for_option (p
, sz
);
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. */
111 int max
= ARRAY_SIZE (doc_urls
) - 1;
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
);
121 if (doc_urls
[midpoint
].quoted_text
[sz
] == '\0')
122 return label_text::borrow (doc_urls
[midpoint
].url_suffix
);
133 return label_text ();
136 /* For use in selftests. */
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
146 Return the url suffix if found, or nullptr otherwise. */
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
158 Additionally, we could have one of the e.g. "-Wno-" variants of
159 the option, which find_opt doesn't handle.
161 Hence we need to create input for find_opt in a temporary buffer. */
164 const char *new_prefix
;
165 if (const char *old_prefix
= get_option_prefix_remapping (p
, sz
, &new_prefix
))
167 /* We have one of the variants; generate a buffer containing a copy
168 that maps from the old prefix to the new prefix
169 e.g. given "-Wno-suffix", generate "-Wsuffix". */
170 gcc_assert (old_prefix
[0] == '-');
171 gcc_assert (new_prefix
);
172 gcc_assert (new_prefix
[0] == '-');
174 const size_t old_prefix_len
= strlen (old_prefix
);
175 gcc_assert (old_prefix_len
<= sz
);
176 const size_t suffix_len
= sz
- old_prefix_len
;
177 const size_t new_prefix_len
= strlen (new_prefix
);
178 const size_t new_sz
= new_prefix_len
+ suffix_len
+ 1;
180 option_buffer
= (char *)xmalloc (new_sz
);
181 memcpy (option_buffer
, new_prefix
, new_prefix_len
);
183 memcpy (option_buffer
+ new_prefix_len
, p
+ old_prefix_len
, suffix_len
);
185 option_buffer
[new_prefix_len
+ suffix_len
] = '\0';
189 /* Otherwise we can simply create a 0-terminated clone of the string. */
191 gcc_assert (p
[0] == '-');
192 option_buffer
= xstrndup (p
, sz
);
195 size_t opt
= find_opt (option_buffer
+ 1, m_lang_mask
);
196 free (option_buffer
);
199 /* Option not recognized. */
200 return label_text ();
202 return get_option_url_suffix (opt
, m_lang_mask
);
206 gcc_urlifier::make_doc_url (const char *doc_url_suffix
)
211 return concat (DOCUMENTATION_ROOT_URL
, doc_url_suffix
, nullptr);
214 } // anonymous namespace
217 make_gcc_urlifier (unsigned int lang_mask
)
219 return new gcc_urlifier (lang_mask
);
228 /* Run all of the selftests within this file. */
231 gcc_urlifier_cc_tests ()
233 /* Check that doc_urls.quoted_text is sorted. */
234 for (size_t idx
= 1; idx
< ARRAY_SIZE (doc_urls
); idx
++)
235 gcc_assert (strcmp (doc_urls
[idx
- 1].quoted_text
,
236 doc_urls
[idx
].quoted_text
)
241 ASSERT_EQ (u
.get_url_suffix_for_quoted_text ("").get (), nullptr);
242 ASSERT_EQ (u
.get_url_suffix_for_quoted_text (")").get (), nullptr);
244 ASSERT_STREQ (u
.get_url_suffix_for_quoted_text ("#pragma message").get (),
245 "gcc/Diagnostic-Pragmas.html");
247 // Incomplete prefix of a quoted_text
248 ASSERT_EQ (u
.get_url_suffix_for_quoted_text ("#pragma mess").get (), nullptr);
250 /* Check that every element is findable. */
251 for (size_t idx
= 0; idx
< ARRAY_SIZE (doc_urls
); idx
++)
253 (u
.get_url_suffix_for_quoted_text (doc_urls
[idx
].quoted_text
).get (),
254 doc_urls
[idx
].url_suffix
);
256 /* Check an option. */
257 ASSERT_STREQ (u
.get_url_suffix_for_quoted_text ("-fpack-struct").get (),
258 "gcc/Code-Gen-Options.html#index-fpack-struct");
260 /* Check a "-fno-" variant of an option. */
261 ASSERT_STREQ (u
.get_url_suffix_for_quoted_text ("-fno-inline").get (),
262 "gcc/Optimize-Options.html#index-finline");
265 } // namespace selftest
267 #endif /* #if CHECKING_P */