LCOV - code coverage report
Current view: top level - gcc - gcc-attribute-urlifier.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 59 59
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 9 9
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Automatic generation of links into GCC's documentation.
       2              :    Copyright (C) 2023-2026 Free Software Foundation, Inc.
       3              :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4              : 
       5              : This file is part of GCC.
       6              : 
       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.
      11              : 
      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.
      16              : 
      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/>.  */
      20              : 
      21              : #define INCLUDE_MEMORY
      22              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "pretty-print.h"
      26              : #include "pretty-print-urlifier.h"
      27              : #include "gcc-urlifier.h"
      28              : #include "opts.h"
      29              : #include "options.h"
      30              : #include "diagnostic.h"
      31              : #include "selftest.h"
      32              : #include "target.h"
      33              : 
      34              : /* class attribute_urlifier : public urlifier.  */
      35              : 
      36              : /* By default, use the target's documentation name.  */
      37              : 
      38   1942308837 : attribute_urlifier::attribute_urlifier ()
      39   1942308837 : : m_target_docs_name (targetm.documentation_name)
      40              : {
      41   1942308837 : }
      42              : 
      43              : /* Explicitly specify a target's documentation name, for use in selftests.  */
      44              : 
      45           12 : attribute_urlifier::attribute_urlifier (const char *target_docs_name)
      46           12 : : m_target_docs_name (target_docs_name)
      47              : {
      48           12 : }
      49              : 
      50              : struct attr_url_entry
      51              : {
      52              :   const char *m_name;
      53              :   const char *m_url_suffix;
      54              :   const char *m_target_docs_name;
      55              :   size_t m_name_len;
      56              : };
      57              : 
      58              : #include "attr-urls.def"
      59              : 
      60              : /* We look in two passes: first for an exact match on target name (if any).
      61              :    Otherwise, we look for one with an empty target name.  */
      62              : 
      63              : /* Search for STR, LEN in the given TABLE.
      64              :    If TARGET_DOCS_NAME is non-null, then look for an exact match on target name.
      65              :    If TARGET_DOCS_NAME is null, then look for an empty string for the
      66              :    target name.  */
      67              : 
      68              : 
      69              : static const attr_url_entry *
      70        34502 : find_attr_url_entry (const char *str,
      71              :                      size_t str_len,
      72              :                      const char *target_docs_name,
      73              :                      const attr_url_entry *table,
      74              :                      size_t table_sz)
      75              : {
      76              :   /* This is linear search, but TABLE_SZ ought not to be very large.  */
      77      9132980 :   for (size_t i = 0; i < table_sz; i++)
      78      9102978 :     if (str_len == table[i].m_name_len)
      79       520413 :       if (0 == strncmp (str, table[i].m_name, str_len))
      80              :         {
      81        10137 :           if (target_docs_name)
      82              :             {
      83              :               /* Reject entries with m_target_docs_name that doesn't match.  */
      84         5828 :               if (strcmp (target_docs_name, table[i].m_target_docs_name))
      85         5606 :                 continue;
      86              :             }
      87              :           else
      88              :             {
      89              :               /* Reject entries for which m_target_docs_name is non-empty.  */
      90         4309 :               if (table[i].m_target_docs_name[0])
      91           31 :                 continue;
      92              :             }
      93              :           return &table[i];
      94              :         }
      95              : 
      96              :   return nullptr;
      97              : }
      98              : 
      99              : /* Search for STR, LEN in all of the attribute tables, in order.
     100              :    TARGET_DOCS_NAME works as above.  */
     101              : 
     102              : static const attr_url_entry *
     103        34502 : find_attr_url_entry (const char *str,
     104              :                      size_t str_len,
     105              :                      const char *target_docs_name)
     106              : {
     107        64504 :   for (size_t table_idx = 0; table_idx < ARRAY_SIZE (attr_url_tables);
     108              :        table_idx++)
     109        34502 :     if (const attr_url_entry *entry
     110        34502 :           = find_attr_url_entry (str, str_len, target_docs_name,
     111              :                                  attr_url_tables[table_idx].m_table,
     112              :                                  attr_url_tables[table_idx].m_table_sz))
     113              :       return entry;
     114              : 
     115              :   return nullptr;
     116              : }
     117              : 
     118              : char *
     119        17314 : attribute_urlifier::get_url_for_quoted_text (const char *p,
     120              :                                              size_t sz) const
     121              : {
     122        17314 :   label_text url_suffix = get_url_suffix_for_quoted_text (p, sz);
     123        17314 :   if (url_suffix.get ())
     124         4460 :     return make_doc_url (url_suffix.get ());
     125              :   return nullptr;
     126        17314 : }
     127              : 
     128              : label_text
     129        17362 : attribute_urlifier::get_url_suffix_for_quoted_text (const char *p,
     130              :                                                     size_t sz) const
     131              : {
     132              :   /* Skip any text after a non-identifier character, so that
     133              :      e.g. given "access(read_write, 2, 3)" we only compare
     134              :      against "access".  */
     135       148108 :   for (size_t i = 0; i < sz; i++)
     136       135297 :     if (!ISIDNUM (p[i]))
     137              :       {
     138              :         /* Truncate to p[0..i).  */
     139              :         sz = i;
     140              :         break;
     141              :       }
     142              : 
     143        17362 :   if (m_target_docs_name)
     144        17362 :     if (const attr_url_entry *entry
     145        17362 :           = find_attr_url_entry (p, sz, m_target_docs_name))
     146          222 :       return label_text::borrow (entry->m_url_suffix);
     147              : 
     148        17140 :   if (const attr_url_entry *entry = find_attr_url_entry (p, sz, nullptr))
     149         4278 :     return label_text::borrow (entry->m_url_suffix);
     150              : 
     151        12862 :   return label_text ();
     152              : }
     153              : 
     154              : label_text
     155           48 : attribute_urlifier::get_url_suffix_for_quoted_text (const char *p) const
     156              : {
     157           48 :   return get_url_suffix_for_quoted_text (p, strlen (p));
     158              : }
     159              : 
     160              : #if CHECKING_P
     161              : 
     162              : namespace selftest {
     163              : 
     164              : /* Selftests.  */
     165              : 
     166              : static void
     167            4 : test_attribute_urlifier ()
     168              : {
     169            4 :   attribute_urlifier u;
     170              : 
     171            4 :   ASSERT_EQ (u.get_url_suffix_for_quoted_text ("").get (), nullptr);
     172            4 :   ASSERT_EQ (u.get_url_suffix_for_quoted_text (")").get (), nullptr);
     173              : 
     174              :   /* Examples of function attributes.  */
     175            4 :   ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("alias").get (),
     176              :                 "gcc/Common-Attributes.html#index-alias");
     177              : 
     178            4 :   ASSERT_STREQ (u.get_url_suffix_for_quoted_text
     179              :                   ("access(read_write, 2, 3)").get (),
     180              :                 "gcc/Common-Attributes.html#index-access");
     181              : 
     182              :   /* Example of enumerator attribute.  */
     183            4 :   ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("deprecated").get (),
     184              :                 "gcc/Common-Attributes.html#index-deprecated");
     185              : 
     186              :   /* Example of statement attribute.  */
     187            4 :   ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("assume").get (),
     188              :                 "gcc/Common-Attributes.html#index-assume");
     189              : 
     190              :   /* Examples of type attributes.  */
     191            4 :   ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("hardbool").get (),
     192              :                 "gcc/Common-Attributes.html#index-hardbool");
     193            4 :   ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("packed").get (),
     194              :                 "gcc/Common-Attributes.html#index-packed");
     195              : 
     196              :   /* Example of variable attribute.  */
     197            4 :   ASSERT_STREQ (u.get_url_suffix_for_quoted_text ("nonstring").get (),
     198              :                 "gcc/Common-Attributes.html#index-nonstring");
     199              : 
     200              :   /* Example of target-specific attributes.
     201              :      For example, "interrupt" has many target-specific documentation URLs.  */
     202            4 :   {
     203            4 :     attribute_urlifier u_rl78 ("RL78");
     204            4 :     attribute_urlifier u_x86 ("x86");
     205            4 :     attribute_urlifier u_unrecognized ("not-a-target");
     206              : 
     207            4 :     ASSERT_STREQ (u_rl78.get_url_suffix_for_quoted_text ("interrupt").get (),
     208              :                   "gcc/RL78-Attributes.html#index-interrupt_002c-RL78");
     209            4 :     ASSERT_STREQ (u_x86.get_url_suffix_for_quoted_text ("interrupt").get (),
     210              :                   "gcc/x86-Attributes.html#index-interrupt_002c-x86");
     211            4 :     ASSERT_STREQ (u_unrecognized.get_url_suffix_for_quoted_text
     212              :                     ("interrupt").get (),
     213              :                   "gcc/Common-Attributes.html#index-interrupt");
     214            4 :   }
     215            4 : }
     216              : 
     217              : /* Run all of the selftests within this file.  */
     218              : 
     219              : void
     220            4 : gcc_attribute_urlifier_cc_tests ()
     221              : {
     222            4 :   test_attribute_urlifier ();
     223            4 : }
     224              : 
     225              : } // namespace selftest
     226              : 
     227              : #endif /* #if CHECKING_P */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.