Home | History | Annotate | Line # | Download | only in gdb
producer.c revision 1.1.1.2
      1      1.1  christos /* Producer string parsers for GDB.
      2      1.1  christos 
      3  1.1.1.2  christos    Copyright (C) 2012-2020 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20      1.1  christos #include "defs.h"
     21      1.1  christos #include "producer.h"
     22  1.1.1.2  christos #include "gdbsupport/selftest.h"
     23      1.1  christos 
     24      1.1  christos /* See producer.h.  */
     25      1.1  christos 
     26      1.1  christos int
     27      1.1  christos producer_is_gcc_ge_4 (const char *producer)
     28      1.1  christos {
     29      1.1  christos   int major, minor;
     30      1.1  christos 
     31      1.1  christos   if (! producer_is_gcc (producer, &major, &minor))
     32      1.1  christos     return -1;
     33      1.1  christos   if (major < 4)
     34      1.1  christos     return -1;
     35      1.1  christos   if (major > 4)
     36      1.1  christos     return INT_MAX;
     37      1.1  christos   return minor;
     38      1.1  christos }
     39      1.1  christos 
     40      1.1  christos /* See producer.h.  */
     41      1.1  christos 
     42      1.1  christos int
     43      1.1  christos producer_is_gcc (const char *producer, int *major, int *minor)
     44      1.1  christos {
     45      1.1  christos   const char *cs;
     46      1.1  christos 
     47      1.1  christos   if (producer != NULL && startswith (producer, "GNU "))
     48      1.1  christos     {
     49      1.1  christos       int maj, min;
     50      1.1  christos 
     51      1.1  christos       if (major == NULL)
     52      1.1  christos 	major = &maj;
     53      1.1  christos       if (minor == NULL)
     54      1.1  christos 	minor = &min;
     55      1.1  christos 
     56      1.1  christos       /* Skip any identifier after "GNU " - such as "C11" "C++" or "Java".
     57      1.1  christos 	 A full producer string might look like:
     58      1.1  christos 	 "GNU C 4.7.2"
     59      1.1  christos 	 "GNU Fortran 4.8.2 20140120 (Red Hat 4.8.2-16) -mtune=generic ..."
     60      1.1  christos 	 "GNU C++14 5.0.0 20150123 (experimental)"
     61      1.1  christos       */
     62      1.1  christos       cs = &producer[strlen ("GNU ")];
     63      1.1  christos       while (*cs && !isspace (*cs))
     64      1.1  christos         cs++;
     65      1.1  christos       if (*cs && isspace (*cs))
     66      1.1  christos         cs++;
     67      1.1  christos       if (sscanf (cs, "%d.%d", major, minor) == 2)
     68      1.1  christos 	return 1;
     69      1.1  christos     }
     70      1.1  christos 
     71      1.1  christos   /* Not recognized as GCC.  */
     72      1.1  christos   return 0;
     73      1.1  christos }
     74      1.1  christos 
     75      1.1  christos 
     76      1.1  christos /* See producer.h.  */
     77      1.1  christos 
     78      1.1  christos bool
     79      1.1  christos producer_is_icc (const char *producer, int *major, int *minor)
     80      1.1  christos {
     81      1.1  christos   if (producer == NULL || !startswith (producer, "Intel(R)"))
     82      1.1  christos     return false;
     83      1.1  christos 
     84      1.1  christos   /* Prepare the used fields.  */
     85      1.1  christos   int maj, min;
     86      1.1  christos   if (major == NULL)
     87      1.1  christos     major = &maj;
     88      1.1  christos   if (minor == NULL)
     89      1.1  christos     minor = &min;
     90      1.1  christos 
     91      1.1  christos   *minor = 0;
     92      1.1  christos   *major = 0;
     93      1.1  christos 
     94      1.1  christos   /* Consumes the string till a "Version" is found.  */
     95      1.1  christos   const char *cs = strstr (producer, "Version");
     96      1.1  christos   if (cs != NULL)
     97      1.1  christos     {
     98      1.1  christos       cs = skip_to_space (cs);
     99      1.1  christos 
    100      1.1  christos       int intermediate = 0;
    101      1.1  christos       int nof = sscanf (cs, "%d.%d.%d.%*d", major, &intermediate, minor);
    102      1.1  christos 
    103      1.1  christos       /* Internal versions are represented only as MAJOR.MINOR, where
    104      1.1  christos 	 minor is usually 0.
    105      1.1  christos 	 Public versions have 3 fields as described with the command
    106      1.1  christos 	 above.  */
    107      1.1  christos       if (nof == 3)
    108      1.1  christos 	return true;
    109      1.1  christos 
    110      1.1  christos       if (nof == 2)
    111      1.1  christos 	{
    112      1.1  christos 	  *minor = intermediate;
    113      1.1  christos 	  return true;
    114      1.1  christos 	}
    115      1.1  christos     }
    116      1.1  christos 
    117      1.1  christos   static bool warning_printed = false;
    118      1.1  christos   /* Not recognized as Intel, let the user know.  */
    119      1.1  christos   if (!warning_printed)
    120      1.1  christos     {
    121      1.1  christos       warning (_("Could not recognize version of Intel Compiler in: \"%s\""),
    122      1.1  christos 	       producer);
    123      1.1  christos       warning_printed = true;
    124      1.1  christos     }
    125      1.1  christos   return false;
    126      1.1  christos }
    127      1.1  christos 
    128  1.1.1.2  christos /* See producer.h.  */
    129  1.1.1.2  christos 
    130  1.1.1.2  christos bool
    131  1.1.1.2  christos producer_is_llvm (const char *producer)
    132  1.1.1.2  christos {
    133  1.1.1.2  christos   return ((producer != NULL) && (startswith (producer, "clang ")
    134  1.1.1.2  christos                                  || startswith (producer, " F90 Flang ")));
    135  1.1.1.2  christos }
    136  1.1.1.2  christos 
    137      1.1  christos #if defined GDB_SELF_TEST
    138      1.1  christos namespace selftests {
    139      1.1  christos namespace producer {
    140      1.1  christos 
    141      1.1  christos static void
    142      1.1  christos producer_parsing_tests ()
    143      1.1  christos {
    144      1.1  christos   {
    145      1.1  christos     /* Check that we don't crash if "Version" is not found in what
    146      1.1  christos        looks like an ICC producer string.  */
    147      1.1  christos     static const char icc_no_version[] = "Intel(R) foo bar";
    148      1.1  christos 
    149      1.1  christos     int major = 0, minor = 0;
    150      1.1  christos     SELF_CHECK (!producer_is_icc (icc_no_version, &major, &minor));
    151      1.1  christos     SELF_CHECK (!producer_is_gcc (icc_no_version, &major, &minor));
    152      1.1  christos   }
    153      1.1  christos 
    154      1.1  christos   {
    155      1.1  christos     static const char extern_f_14_1[] = "\
    156      1.1  christos Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on \
    157      1.1  christos Intel(R) 64, \
    158      1.1  christos Version 14.0.1.074 Build 20130716";
    159      1.1  christos 
    160      1.1  christos     int major = 0, minor = 0;
    161      1.1  christos     SELF_CHECK (producer_is_icc (extern_f_14_1, &major, &minor)
    162      1.1  christos 		&& major == 14 && minor == 1);
    163      1.1  christos     SELF_CHECK (!producer_is_gcc (extern_f_14_1, &major, &minor));
    164      1.1  christos   }
    165      1.1  christos 
    166      1.1  christos   {
    167      1.1  christos     static const char intern_f_14[] = "\
    168      1.1  christos Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on \
    169      1.1  christos Intel(R) 64, \
    170      1.1  christos Version 14.0";
    171      1.1  christos 
    172      1.1  christos     int major = 0, minor = 0;
    173      1.1  christos     SELF_CHECK (producer_is_icc (intern_f_14, &major, &minor)
    174      1.1  christos 		&& major == 14 && minor == 0);
    175      1.1  christos     SELF_CHECK (!producer_is_gcc (intern_f_14, &major, &minor));
    176      1.1  christos   }
    177      1.1  christos 
    178      1.1  christos   {
    179      1.1  christos     static const char intern_c_14[] = "\
    180      1.1  christos Intel(R) C++ Intel(R) 64 Compiler XE for applications running on \
    181      1.1  christos Intel(R) 64, \
    182      1.1  christos Version 14.0";
    183      1.1  christos     int major = 0, minor = 0;
    184      1.1  christos     SELF_CHECK (producer_is_icc (intern_c_14, &major, &minor)
    185      1.1  christos 		&& major == 14 && minor == 0);
    186      1.1  christos     SELF_CHECK (!producer_is_gcc (intern_c_14, &major, &minor));
    187      1.1  christos   }
    188      1.1  christos 
    189      1.1  christos   {
    190      1.1  christos     static const char intern_c_18[] = "\
    191      1.1  christos Intel(R) C++ Intel(R) 64 Compiler for applications running on \
    192      1.1  christos Intel(R) 64, \
    193      1.1  christos Version 18.0 Beta";
    194      1.1  christos     int major = 0, minor = 0;
    195      1.1  christos     SELF_CHECK (producer_is_icc (intern_c_18, &major, &minor)
    196      1.1  christos 		&& major == 18 && minor == 0);
    197      1.1  christos   }
    198      1.1  christos 
    199      1.1  christos   {
    200      1.1  christos     static const char gnu[] = "GNU C 4.7.2";
    201      1.1  christos     SELF_CHECK (!producer_is_icc (gnu, NULL, NULL));
    202      1.1  christos 
    203      1.1  christos     int major = 0, minor = 0;
    204      1.1  christos     SELF_CHECK (producer_is_gcc (gnu, &major, &minor)
    205      1.1  christos 		&& major == 4 && minor == 7);
    206      1.1  christos   }
    207      1.1  christos 
    208      1.1  christos   {
    209      1.1  christos     static const char gnu_exp[] = "GNU C++14 5.0.0 20150123 (experimental)";
    210      1.1  christos     int major = 0, minor = 0;
    211      1.1  christos     SELF_CHECK (!producer_is_icc (gnu_exp, NULL, NULL));
    212      1.1  christos     SELF_CHECK (producer_is_gcc (gnu_exp, &major, &minor)
    213      1.1  christos 		&& major == 5 && minor == 0);
    214      1.1  christos   }
    215  1.1.1.2  christos 
    216  1.1.1.2  christos   {
    217  1.1.1.2  christos     static const char clang_llvm_exp[] = "clang version 12.0.0 (CLANG: bld#8)";
    218  1.1.1.2  christos     int major = 0, minor = 0;
    219  1.1.1.2  christos     SELF_CHECK (!producer_is_icc (clang_llvm_exp, NULL, NULL));
    220  1.1.1.2  christos     SELF_CHECK (!producer_is_gcc (clang_llvm_exp, &major, &minor));
    221  1.1.1.2  christos     SELF_CHECK (producer_is_llvm (clang_llvm_exp));
    222  1.1.1.2  christos   }
    223  1.1.1.2  christos 
    224  1.1.1.2  christos   {
    225  1.1.1.2  christos     static const char flang_llvm_exp[] = " F90 Flang - 1.5 2017-05-01";
    226  1.1.1.2  christos     int major = 0, minor = 0;
    227  1.1.1.2  christos     SELF_CHECK (!producer_is_icc (flang_llvm_exp, NULL, NULL));
    228  1.1.1.2  christos     SELF_CHECK (!producer_is_gcc (flang_llvm_exp, &major, &minor));
    229  1.1.1.2  christos     SELF_CHECK (producer_is_llvm (flang_llvm_exp));
    230  1.1.1.2  christos   }
    231      1.1  christos }
    232      1.1  christos }
    233      1.1  christos }
    234      1.1  christos #endif
    235      1.1  christos 
    236  1.1.1.2  christos void _initialize_producer ();
    237      1.1  christos void
    238      1.1  christos _initialize_producer ()
    239      1.1  christos {
    240      1.1  christos #if defined GDB_SELF_TEST
    241      1.1  christos   selftests::register_test
    242      1.1  christos     ("producer-parser", selftests::producer::producer_parsing_tests);
    243      1.1  christos #endif
    244      1.1  christos }
    245