Imported Upstream version 3.7
[platform/upstream/ccache.git] / src / language.c
1 // Copyright (C) 2010-2018 Joel Rosdahl
2 //
3 // This program is free software; you can redistribute it and/or modify it
4 // under the terms of the GNU General Public License as published by the Free
5 // Software Foundation; either version 3 of the License, or (at your option)
6 // any later version.
7 //
8 // This program is distributed in the hope that it will be useful, but WITHOUT
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 // more details.
12 //
13 // You should have received a copy of the GNU General Public License along with
14 // this program; if not, write to the Free Software Foundation, Inc., 51
15 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17 #include "ccache.h"
18
19 #include "language.h"
20
21 // Supported file extensions and corresponding languages (as in parameter to
22 // the -x option).
23 static const struct {
24         const char *extension;
25         const char *language;
26 } extensions[] = {
27         {".c",   "c"},
28         {".C",   "c++"},
29         {".cc",  "c++"},
30         {".CC",  "c++"},
31         {".cp",  "c++"},
32         {".CP",  "c++"},
33         {".cpp", "c++"},
34         {".CPP", "c++"},
35         {".cxx", "c++"},
36         {".CXX", "c++"},
37         {".c++", "c++"},
38         {".C++", "c++"},
39         {".m",   "objective-c"},
40         {".M",   "objective-c++"},
41         {".mm",  "objective-c++"},
42         {".sx",  "assembler-with-cpp"},
43         {".S",   "assembler-with-cpp"},
44         // Preprocessed:
45         {".i",   "cpp-output"},
46         {".ii",  "c++-cpp-output"},
47         {".mi",  "objective-c-cpp-output"},
48         {".mii", "objective-c++-cpp-output"},
49         {".s",   "assembler"},
50         // Header file (for precompilation):
51         {".h",   "c-header"},
52         {".H",   "c++-header"},
53         {".h++", "c++-header"},
54         {".H++", "c++-header"},
55         {".hh",  "c++-header"},
56         {".HH",  "c++-header"},
57         {".hp",  "c++-header"},
58         {".HP",  "c++-header"},
59         {".hpp", "c++-header"},
60         {".HPP", "c++-header"},
61         {".hxx", "c++-header"},
62         {".HXX", "c++-header"},
63         {".tcc", "c++-header"},
64         {".TCC", "c++-header"},
65         {".cu",  "cuda"},
66         {".ic",  "cuda-output"},
67         {NULL,  NULL}
68 };
69
70 // Supported languages and corresponding preprocessed languages.
71 static const struct {
72         const char *language;
73         const char *p_language;
74 } languages[] = {
75         {"c",                        "cpp-output"},
76         {"cpp-output",               "cpp-output"},
77         {"c-header",                 "cpp-output"},
78         {"c++",                      "c++-cpp-output"},
79         {"c++-cpp-output",           "c++-cpp-output"},
80         {"c++-header",               "c++-cpp-output"},
81         {"objective-c",              "objective-c-cpp-output"},
82         {"objective-c-header",       "objective-c-cpp-output"},
83         {"objc-cpp-output",          "objective-c-cpp-output"},
84         {"objective-c-cpp-output",   "objective-c-cpp-output"},
85         {"objective-c++",            "objective-c++-cpp-output"},
86         {"objc++-cpp-output",        "objective-c++-cpp-output"},
87         {"objective-c++-header",     "objective-c++-cpp-output"},
88         {"objective-c++-cpp-output", "objective-c++-cpp-output"},
89         {"cuda",                     "cuda-output"},
90         {"assembler-with-cpp",       "assembler"},
91         {"assembler",                "assembler"},
92         {NULL,  NULL}
93 };
94
95 // Guess the language of a file based on its extension. Returns NULL if the
96 // extension is unknown.
97 const char *
98 language_for_file(const char *fname)
99 {
100         const char *p = get_extension(fname);
101         for (int i = 0; extensions[i].extension; i++) {
102                 if (str_eq(p, extensions[i].extension)) {
103                         return extensions[i].language;
104                 }
105         }
106         return NULL;
107 }
108
109 // Return the preprocessed language for a given language, or NULL if unknown.
110 const char *
111 p_language_for_language(const char *language)
112 {
113         if (!language) {
114                 return NULL;
115         }
116         for (int i = 0; languages[i].language; ++i) {
117                 if (str_eq(language, languages[i].language)) {
118                         return languages[i].p_language;
119                 }
120         }
121         return NULL;
122 }
123
124 // Return the default file extension (including dot) for a language, or NULL if
125 // unknown.
126 const char *
127 extension_for_language(const char *language)
128 {
129         if (!language) {
130                 return NULL;
131         }
132         for (int i = 0; extensions[i].extension; i++) {
133                 if (str_eq(language, extensions[i].language)) {
134                         return extensions[i].extension;
135                 }
136         }
137         return NULL;
138 }
139
140 bool
141 language_is_supported(const char *language)
142 {
143         return p_language_for_language(language) != NULL;
144 }
145
146 bool
147 language_is_preprocessed(const char *language)
148 {
149         const char *p_language = p_language_for_language(language);
150         assert(p_language);
151         return str_eq(language, p_language);
152 }