resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmGetFilenameComponentCommand.cxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include "cmGetFilenameComponentCommand.h"
4
5 #include "cmExecutionStatus.h"
6 #include "cmMakefile.h"
7 #include "cmStateTypes.h"
8 #include "cmStringAlgorithms.h"
9 #include "cmSystemTools.h"
10 #include "cmValue.h"
11
12 // cmGetFilenameComponentCommand
13 bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
14                                    cmExecutionStatus& status)
15 {
16   if (args.size() < 3) {
17     status.SetError("called with incorrect number of arguments");
18     cmSystemTools::SetFatalErrorOccurred();
19     return false;
20   }
21
22   // Check and see if the value has been stored in the cache
23   // already, if so use that value
24   if (args.size() >= 4 && args.back() == "CACHE") {
25     cmValue cacheValue = status.GetMakefile().GetDefinition(args.front());
26     if (cacheValue && !cmIsNOTFOUND(*cacheValue)) {
27       return true;
28     }
29   }
30
31   std::string result;
32   std::string filename = args[1];
33   if (filename.find("[HKEY") != std::string::npos) {
34     // Check the registry as the target application would view it.
35     cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
36     cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
37     if (status.GetMakefile().PlatformIs64Bit()) {
38       view = cmSystemTools::KeyWOW64_64;
39       other_view = cmSystemTools::KeyWOW64_32;
40     }
41     cmSystemTools::ExpandRegistryValues(filename, view);
42     if (filename.find("/registry") != std::string::npos) {
43       std::string other = args[1];
44       cmSystemTools::ExpandRegistryValues(other, other_view);
45       if (other.find("/registry") == std::string::npos) {
46         filename = other;
47       }
48     }
49   }
50   std::string storeArgs;
51   std::string programArgs;
52   if (args[2] == "DIRECTORY" || args[2] == "PATH") {
53     result = cmSystemTools::GetFilenamePath(filename);
54   } else if (args[2] == "NAME") {
55     result = cmSystemTools::GetFilenameName(filename);
56   } else if (args[2] == "PROGRAM") {
57     for (unsigned int i = 2; i < args.size(); ++i) {
58       if (args[i] == "PROGRAM_ARGS") {
59         i++;
60         if (i < args.size()) {
61           storeArgs = args[i];
62         }
63       }
64     }
65
66     // First assume the path to the program was specified with no
67     // arguments and with no quoting or escaping for spaces.
68     // Only bother doing this if there is non-whitespace.
69     if (!cmTrimWhitespace(filename).empty()) {
70       result = cmSystemTools::FindProgram(filename);
71     }
72
73     // If that failed then assume a command-line string was given
74     // and split the program part from the rest of the arguments.
75     if (result.empty()) {
76       std::string program;
77       if (cmSystemTools::SplitProgramFromArgs(filename, program,
78                                               programArgs)) {
79         if (cmSystemTools::FileExists(program)) {
80           result = program;
81         } else {
82           result = cmSystemTools::FindProgram(program);
83         }
84       }
85       if (result.empty()) {
86         programArgs.clear();
87       }
88     }
89   } else if (args[2] == "EXT") {
90     result = cmSystemTools::GetFilenameExtension(filename);
91   } else if (args[2] == "NAME_WE") {
92     result = cmSystemTools::GetFilenameWithoutExtension(filename);
93   } else if (args[2] == "LAST_EXT") {
94     result = cmSystemTools::GetFilenameLastExtension(filename);
95   } else if (args[2] == "NAME_WLE") {
96     result = cmSystemTools::GetFilenameWithoutLastExtension(filename);
97   } else if (args[2] == "ABSOLUTE" || args[2] == "REALPATH") {
98     // If the path given is relative, evaluate it relative to the
99     // current source directory unless the user passes a different
100     // base directory.
101     std::string baseDir = status.GetMakefile().GetCurrentSourceDirectory();
102     for (unsigned int i = 3; i < args.size(); ++i) {
103       if (args[i] == "BASE_DIR") {
104         ++i;
105         if (i < args.size()) {
106           baseDir = args[i];
107         }
108       }
109     }
110     // Collapse the path to its simplest form.
111     result = cmSystemTools::CollapseFullPath(filename, baseDir);
112     if (args[2] == "REALPATH") {
113       // Resolve symlinks if possible
114       result = cmSystemTools::GetRealPath(result);
115     }
116   } else {
117     std::string err = "unknown component " + args[2];
118     status.SetError(err);
119     cmSystemTools::SetFatalErrorOccurred();
120     return false;
121   }
122
123   if (args.size() >= 4 && args.back() == "CACHE") {
124     if (!programArgs.empty() && !storeArgs.empty()) {
125       status.GetMakefile().AddCacheDefinition(
126         storeArgs, programArgs, "",
127         args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
128     }
129     status.GetMakefile().AddCacheDefinition(
130       args.front(), result, "",
131       args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
132   } else {
133     if (!programArgs.empty() && !storeArgs.empty()) {
134       status.GetMakefile().AddDefinition(storeArgs, programArgs);
135     }
136     status.GetMakefile().AddDefinition(args.front(), result);
137   }
138
139   return true;
140 }