Home | History | Annotate | Line # | Download | only in gdb
producer.c revision 1.1
      1  1.1  christos /* Producer string parsers for GDB.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2012-2019 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  christos #include "common/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  christos #if defined GDB_SELF_TEST
    129  1.1  christos namespace selftests {
    130  1.1  christos namespace producer {
    131  1.1  christos 
    132  1.1  christos static void
    133  1.1  christos producer_parsing_tests ()
    134  1.1  christos {
    135  1.1  christos   {
    136  1.1  christos     /* Check that we don't crash if "Version" is not found in what
    137  1.1  christos        looks like an ICC producer string.  */
    138  1.1  christos     static const char icc_no_version[] = "Intel(R) foo bar";
    139  1.1  christos 
    140  1.1  christos     int major = 0, minor = 0;
    141  1.1  christos     SELF_CHECK (!producer_is_icc (icc_no_version, &major, &minor));
    142  1.1  christos     SELF_CHECK (!producer_is_gcc (icc_no_version, &major, &minor));
    143  1.1  christos   }
    144  1.1  christos 
    145  1.1  christos   {
    146  1.1  christos     static const char extern_f_14_1[] = "\
    147  1.1  christos Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on \
    148  1.1  christos Intel(R) 64, \
    149  1.1  christos Version 14.0.1.074 Build 20130716";
    150  1.1  christos 
    151  1.1  christos     int major = 0, minor = 0;
    152  1.1  christos     SELF_CHECK (producer_is_icc (extern_f_14_1, &major, &minor)
    153  1.1  christos 		&& major == 14 && minor == 1);
    154  1.1  christos     SELF_CHECK (!producer_is_gcc (extern_f_14_1, &major, &minor));
    155  1.1  christos   }
    156  1.1  christos 
    157  1.1  christos   {
    158  1.1  christos     static const char intern_f_14[] = "\
    159  1.1  christos Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on \
    160  1.1  christos Intel(R) 64, \
    161  1.1  christos Version 14.0";
    162  1.1  christos 
    163  1.1  christos     int major = 0, minor = 0;
    164  1.1  christos     SELF_CHECK (producer_is_icc (intern_f_14, &major, &minor)
    165  1.1  christos 		&& major == 14 && minor == 0);
    166  1.1  christos     SELF_CHECK (!producer_is_gcc (intern_f_14, &major, &minor));
    167  1.1  christos   }
    168  1.1  christos 
    169  1.1  christos   {
    170  1.1  christos     static const char intern_c_14[] = "\
    171  1.1  christos Intel(R) C++ Intel(R) 64 Compiler XE for applications running on \
    172  1.1  christos Intel(R) 64, \
    173  1.1  christos Version 14.0";
    174  1.1  christos     int major = 0, minor = 0;
    175  1.1  christos     SELF_CHECK (producer_is_icc (intern_c_14, &major, &minor)
    176  1.1  christos 		&& major == 14 && minor == 0);
    177  1.1  christos     SELF_CHECK (!producer_is_gcc (intern_c_14, &major, &minor));
    178  1.1  christos   }
    179  1.1  christos 
    180  1.1  christos   {
    181  1.1  christos     static const char intern_c_18[] = "\
    182  1.1  christos Intel(R) C++ Intel(R) 64 Compiler for applications running on \
    183  1.1  christos Intel(R) 64, \
    184  1.1  christos Version 18.0 Beta";
    185  1.1  christos     int major = 0, minor = 0;
    186  1.1  christos     SELF_CHECK (producer_is_icc (intern_c_18, &major, &minor)
    187  1.1  christos 		&& major == 18 && minor == 0);
    188  1.1  christos   }
    189  1.1  christos 
    190  1.1  christos   {
    191  1.1  christos     static const char gnu[] = "GNU C 4.7.2";
    192  1.1  christos     SELF_CHECK (!producer_is_icc (gnu, NULL, NULL));
    193  1.1  christos 
    194  1.1  christos     int major = 0, minor = 0;
    195  1.1  christos     SELF_CHECK (producer_is_gcc (gnu, &major, &minor)
    196  1.1  christos 		&& major == 4 && minor == 7);
    197  1.1  christos   }
    198  1.1  christos 
    199  1.1  christos   {
    200  1.1  christos     static const char gnu_exp[] = "GNU C++14 5.0.0 20150123 (experimental)";
    201  1.1  christos     int major = 0, minor = 0;
    202  1.1  christos     SELF_CHECK (!producer_is_icc (gnu_exp, NULL, NULL));
    203  1.1  christos     SELF_CHECK (producer_is_gcc (gnu_exp, &major, &minor)
    204  1.1  christos 		&& major == 5 && minor == 0);
    205  1.1  christos   }
    206  1.1  christos }
    207  1.1  christos }
    208  1.1  christos }
    209  1.1  christos #endif
    210  1.1  christos 
    211  1.1  christos void
    212  1.1  christos _initialize_producer ()
    213  1.1  christos {
    214  1.1  christos #if defined GDB_SELF_TEST
    215  1.1  christos   selftests::register_test
    216  1.1  christos     ("producer-parser", selftests::producer::producer_parsing_tests);
    217  1.1  christos #endif
    218  1.1  christos }
    219