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