/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
/*
   this file contains the implementation of the C API to CMake. Generally
   these routines just manipulate arguments and then call the associated
   methods on the CMake classes. */

#include "cmCPluginAPI.h"

#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmVersion.h"

#include <stdlib.h>

#ifdef __QNX__
#  include <malloc.h> /* for malloc/free on QNX */
#endif

extern "C" {

void CCONV* cmGetClientData(void* info)
{
  return ((cmLoadedCommandInfo*)info)->ClientData;
}

void CCONV cmSetClientData(void* info, void* cd)
{
  ((cmLoadedCommandInfo*)info)->ClientData = cd;
}

void CCONV cmSetError(void* info, const char* err)
{
  if (((cmLoadedCommandInfo*)info)->Error) {
    free(((cmLoadedCommandInfo*)info)->Error);
  }
  ((cmLoadedCommandInfo*)info)->Error = strdup(err);
}

unsigned int CCONV cmGetCacheMajorVersion(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  cmState* state = mf->GetState();
  return state->GetCacheMajorVersion();
}
unsigned int CCONV cmGetCacheMinorVersion(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  cmState* state = mf->GetState();
  return state->GetCacheMinorVersion();
}

unsigned int CCONV cmGetMajorVersion(void*)
{
  return cmVersion::GetMajorVersion();
}

unsigned int CCONV cmGetMinorVersion(void*)
{
  return cmVersion::GetMinorVersion();
}

void CCONV cmAddDefinition(void* arg, const char* name, const char* value)
{
  if (value) {
    cmMakefile* mf = static_cast<cmMakefile*>(arg);
    mf->AddDefinition(name, value);
  }
}

/* Add a definition to this makefile and the global cmake cache. */
void CCONV cmAddCacheDefinition(void* arg, const char* name, const char* value,
                                const char* doc, int type)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);

  switch (type) {
    case CM_CACHE_BOOL:
      mf->AddCacheDefinition(name, value, doc, cmStateEnums::BOOL);
      break;
    case CM_CACHE_PATH:
      mf->AddCacheDefinition(name, value, doc, cmStateEnums::PATH);
      break;
    case CM_CACHE_FILEPATH:
      mf->AddCacheDefinition(name, value, doc, cmStateEnums::FILEPATH);
      break;
    case CM_CACHE_STRING:
      mf->AddCacheDefinition(name, value, doc, cmStateEnums::STRING);
      break;
    case CM_CACHE_INTERNAL:
      mf->AddCacheDefinition(name, value, doc, cmStateEnums::INTERNAL);
      break;
    case CM_CACHE_STATIC:
      mf->AddCacheDefinition(name, value, doc, cmStateEnums::STATIC);
      break;
  }
}

const char* CCONV cmGetProjectName(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  static std::string name;
  name = mf->GetStateSnapshot().GetProjectName();
  return name.c_str();
}

const char* CCONV cmGetHomeDirectory(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return mf->GetHomeDirectory().c_str();
}
const char* CCONV cmGetHomeOutputDirectory(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return mf->GetHomeOutputDirectory().c_str();
}
const char* CCONV cmGetStartDirectory(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return mf->GetCurrentSourceDirectory().c_str();
}
const char* CCONV cmGetStartOutputDirectory(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return mf->GetCurrentBinaryDirectory().c_str();
}
const char* CCONV cmGetCurrentDirectory(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return mf->GetCurrentSourceDirectory().c_str();
}
const char* CCONV cmGetCurrentOutputDirectory(void* arg)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return mf->GetCurrentBinaryDirectory().c_str();
}
const char* CCONV cmGetDefinition(void* arg, const char* def)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return mf->GetDefinition(def);
}

int CCONV cmIsOn(void* arg, const char* name)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return static_cast<int>(mf->IsOn(name));
}

/** Check if a command exists. */
int CCONV cmCommandExists(void* arg, const char* name)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  return static_cast<int>(mf->GetState()->GetCommand(name) ? 1 : 0);
}

void CCONV cmAddDefineFlag(void* arg, const char* definition)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  mf->AddDefineFlag(definition);
}

void CCONV cmAddLinkDirectoryForTarget(void* arg, const char* tgt,
                                       const char* d)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  cmTarget* t = mf->FindLocalNonAliasTarget(tgt);
  if (!t) {
    cmSystemTools::Error(
      "Attempt to add link directories to non-existent target: " +
      std::string(tgt) + " for directory " + std::string(d));
    return;
  }
  t->InsertLinkDirectory(d, mf->GetBacktrace());
}

void CCONV cmAddExecutable(void* arg, const char* exename, int numSrcs,
                           const char** srcs, int win32)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  std::vector<std::string> srcs2;
  int i;
  for (i = 0; i < numSrcs; ++i) {
    srcs2.emplace_back(srcs[i]);
  }
  cmTarget* tg = mf->AddExecutable(exename, srcs2);
  if (win32) {
    tg->SetProperty("WIN32_EXECUTABLE", "ON");
  }
}

void CCONV cmAddUtilityCommand(void* arg, const char* utilityName,
                               const char* command, const char* arguments,
                               int all, int numDepends, const char** depends,
                               int, const char**)
{
  // Get the makefile instance.  Perform an extra variable expansion
  // now because the API caller expects it.
  cmMakefile* mf = static_cast<cmMakefile*>(arg);

  // Construct the command line for the command.
  cmCustomCommandLine commandLine;
  std::string expand = command;
  commandLine.push_back(mf->ExpandVariablesInString(expand));
  if (arguments && arguments[0]) {
    // TODO: Parse arguments!
    expand = arguments;
    commandLine.push_back(mf->ExpandVariablesInString(expand));
  }
  cmCustomCommandLines commandLines;
  commandLines.push_back(commandLine);

  // Accumulate the list of dependencies.
  std::vector<std::string> depends2;
  for (int i = 0; i < numDepends; ++i) {
    expand = depends[i];
    depends2.push_back(mf->ExpandVariablesInString(expand));
  }

  // Pass the call to the makefile instance.
  mf->AddUtilityCommand(utilityName, cmMakefile::TargetOrigin::Project,
                        (all ? false : true), nullptr, depends2, commandLines);
}
void CCONV cmAddCustomCommand(void* arg, const char* source,
                              const char* command, int numArgs,
                              const char** args, int numDepends,
                              const char** depends, int numOutputs,
                              const char** outputs, const char* target)
{
  // Get the makefile instance.  Perform an extra variable expansion
  // now because the API caller expects it.
  cmMakefile* mf = static_cast<cmMakefile*>(arg);

  // Construct the command line for the command.
  cmCustomCommandLine commandLine;
  std::string expand = command;
  commandLine.push_back(mf->ExpandVariablesInString(expand));
  for (int i = 0; i < numArgs; ++i) {
    expand = args[i];
    commandLine.push_back(mf->ExpandVariablesInString(expand));
  }
  cmCustomCommandLines commandLines;
  commandLines.push_back(commandLine);

  // Accumulate the list of dependencies.
  std::vector<std::string> depends2;
  for (int i = 0; i < numDepends; ++i) {
    expand = depends[i];
    depends2.push_back(mf->ExpandVariablesInString(expand));
  }

  // Accumulate the list of outputs.
  std::vector<std::string> outputs2;
  for (int i = 0; i < numOutputs; ++i) {
    expand = outputs[i];
    outputs2.push_back(mf->ExpandVariablesInString(expand));
  }

  // Pass the call to the makefile instance.
  const char* no_comment = nullptr;
  mf->AddCustomCommandOldStyle(target, outputs2, depends2, source,
                               commandLines, no_comment);
}

void CCONV cmAddCustomCommandToOutput(void* arg, const char* output,
                                      const char* command, int numArgs,
                                      const char** args,
                                      const char* main_dependency,
                                      int numDepends, const char** depends)
{
  // Get the makefile instance.  Perform an extra variable expansion
  // now because the API caller expects it.
  cmMakefile* mf = static_cast<cmMakefile*>(arg);

  // Construct the command line for the command.
  cmCustomCommandLine commandLine;
  std::string expand = command;
  commandLine.push_back(mf->ExpandVariablesInString(expand));
  for (int i = 0; i < numArgs; ++i) {
    expand = args[i];
    commandLine.push_back(mf->ExpandVariablesInString(expand));
  }
  cmCustomCommandLines commandLines;
  commandLines.push_back(commandLine);

  // Accumulate the list of dependencies.
  std::vector<std::string> depends2;
  for (int i = 0; i < numDepends; ++i) {
    expand = depends[i];
    depends2.push_back(mf->ExpandVariablesInString(expand));
  }

  // Pass the call to the makefile instance.
  const char* no_comment = nullptr;
  const char* no_working_dir = nullptr;
  mf->AddCustomCommandToOutput(output, depends2, main_dependency, commandLines,
                               no_comment, no_working_dir);
}

void CCONV cmAddCustomCommandToTarget(void* arg, const char* target,
                                      const char* command, int numArgs,
                                      const char** args, int commandType)
{
  // Get the makefile instance.
  cmMakefile* mf = static_cast<cmMakefile*>(arg);

  // Construct the command line for the command.  Perform an extra
  // variable expansion now because the API caller expects it.
  cmCustomCommandLine commandLine;
  std::string expand = command;
  commandLine.push_back(mf->ExpandVariablesInString(expand));
  for (int i = 0; i < numArgs; ++i) {
    expand = args[i];
    commandLine.push_back(mf->ExpandVariablesInString(expand));
  }
  cmCustomCommandLines commandLines;
  commandLines.push_back(commandLine);

  // Select the command type.
  cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
  switch (commandType) {
    case CM_PRE_BUILD:
      cctype = cmTarget::PRE_BUILD;
      break;
    case CM_PRE_LINK:
      cctype = cmTarget::PRE_LINK;
      break;
    case CM_POST_BUILD:
      cctype = cmTarget::POST_BUILD;
      break;
  }

  // Pass the call to the makefile instance.
  std::vector<std::string> no_byproducts;
  std::vector<std::string> no_depends;
  const char* no_comment = nullptr;
  const char* no_working_dir = nullptr;
  mf->AddCustomCommandToTarget(target, no_byproducts, no_depends, commandLines,
                               cctype, no_comment, no_working_dir);
}

static void addLinkLibrary(cmMakefile* mf, std::string const& target,
                           std::string const& lib, cmTargetLinkLibraryType llt)
{
  cmTarget* t = mf->FindLocalNonAliasTarget(target);
  if (!t) {
    std::ostringstream e;
    e << "Attempt to add link library \"" << lib << "\" to target \"" << target
      << "\" which is not built in this directory.";
    mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
    return;
  }

  cmTarget* tgt = mf->GetGlobalGenerator()->FindTarget(lib);
  if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) &&
      (tgt->GetType() != cmStateEnums::SHARED_LIBRARY) &&
      (tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
      !tgt->IsExecutableWithExports()) {
    std::ostringstream e;
    e << "Target \"" << lib << "\" of type "
      << cmState::GetTargetTypeName(tgt->GetType())
      << " may not be linked into another target.  "
      << "One may link only to STATIC or SHARED libraries, or "
      << "to executables with the ENABLE_EXPORTS property set.";
    mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
  }

  t->AddLinkLibrary(*mf, lib, llt);
}

void CCONV cmAddLinkLibraryForTarget(void* arg, const char* tgt,
                                     const char* value, int libtype)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);

  switch (libtype) {
    case CM_LIBRARY_GENERAL:
      addLinkLibrary(mf, tgt, value, GENERAL_LibraryType);
      break;
    case CM_LIBRARY_DEBUG:
      addLinkLibrary(mf, tgt, value, DEBUG_LibraryType);
      break;
    case CM_LIBRARY_OPTIMIZED:
      addLinkLibrary(mf, tgt, value, OPTIMIZED_LibraryType);
      break;
  }
}

void CCONV cmAddLibrary(void* arg, const char* libname, int shared,
                        int numSrcs, const char** srcs)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  std::vector<std::string> srcs2;
  int i;
  for (i = 0; i < numSrcs; ++i) {
    srcs2.emplace_back(srcs[i]);
  }
  mf->AddLibrary(
    libname,
    (shared ? cmStateEnums::SHARED_LIBRARY : cmStateEnums::STATIC_LIBRARY),
    srcs2);
}

char CCONV* cmExpandVariablesInString(void* arg, const char* source,
                                      int escapeQuotes, int atOnly)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  std::string barf = source;
  std::string const& result =
    mf->ExpandVariablesInString(barf, escapeQuotes != 0, atOnly != 0);
  return strdup(result.c_str());
}

int CCONV cmExecuteCommand(void* arg, const char* name, int numArgs,
                           const char** args)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  cmListFileFunction lff;
  lff.Name = name;
  for (int i = 0; i < numArgs; ++i) {
    // Assume all arguments are quoted.
    lff.Arguments.emplace_back(args[i], cmListFileArgument::Quoted, 0);
  }
  cmExecutionStatus status(*mf);
  return mf->ExecuteCommand(lff, status);
}

void CCONV cmExpandSourceListArguments(void* arg, int numArgs,
                                       const char** args, int* resArgc,
                                       char*** resArgv,
                                       unsigned int startArgumentIndex)
{
  (void)arg;
  (void)startArgumentIndex;
  std::vector<std::string> result;
  int i;
  for (i = 0; i < numArgs; ++i) {
    result.emplace_back(args[i]);
  }
  int resargc = static_cast<int>(result.size());
  char** resargv = nullptr;
  if (resargc) {
    resargv = (char**)malloc(resargc * sizeof(char*));
  }
  for (i = 0; i < resargc; ++i) {
    resargv[i] = strdup(result[i].c_str());
  }
  *resArgc = resargc;
  *resArgv = resargv;
}

void CCONV cmFreeArguments(int argc, char** argv)
{
  int i;
  for (i = 0; i < argc; ++i) {
    free(argv[i]);
  }
  free(argv);
}

int CCONV cmGetTotalArgumentSize(int argc, char** argv)
{
  int i;
  int result = 0;
  for (i = 0; i < argc; ++i) {
    if (argv[i]) {
      result = result + static_cast<int>(strlen(argv[i]));
    }
  }
  return result;
}

// Source file proxy object to support the old cmSourceFile/cmMakefile
// API for source files.
struct cmCPluginAPISourceFile
{
  cmSourceFile* RealSourceFile = nullptr;
  std::string SourceName;
  std::string SourceExtension;
  std::string FullPath;
  std::vector<std::string> Depends;
  cmPropertyMap Properties;
};

// Keep a map from real cmSourceFile instances stored in a makefile to
// the CPluginAPI proxy source file.
class cmCPluginAPISourceFileMap
  : public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
{
public:
  typedef std::map<cmSourceFile*, cmCPluginAPISourceFile*> derived;
  typedef derived::iterator iterator;
  typedef derived::value_type value_type;
  cmCPluginAPISourceFileMap() = default;
  ~cmCPluginAPISourceFileMap()
  {
    for (auto const& i : *this) {
      delete i.second;
    }
  }
  cmCPluginAPISourceFileMap(const cmCPluginAPISourceFileMap&) = delete;
  cmCPluginAPISourceFileMap& operator=(const cmCPluginAPISourceFileMap&) =
    delete;
};
cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;

void* CCONV cmCreateSourceFile(void)
{
  return new cmCPluginAPISourceFile;
}

void* CCONV cmCreateNewSourceFile(void*)
{
  return new cmCPluginAPISourceFile;
}

void CCONV cmDestroySourceFile(void* arg)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  // Only delete if it was created by cmCreateSourceFile or
  // cmCreateNewSourceFile and is therefore not in the map.
  if (!sf->RealSourceFile) {
    delete sf;
  }
}

void CCONV* cmGetSource(void* arg, const char* name)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  if (cmSourceFile* rsf = mf->GetSource(name)) {
    // Lookup the proxy source file object for this source.
    cmCPluginAPISourceFileMap::iterator i = cmCPluginAPISourceFiles.find(rsf);
    if (i == cmCPluginAPISourceFiles.end()) {
      // Create a proxy source file object for this source.
      cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
      sf->RealSourceFile = rsf;
      sf->FullPath = rsf->GetFullPath();
      sf->SourceName =
        cmSystemTools::GetFilenameWithoutLastExtension(sf->FullPath);
      sf->SourceExtension =
        cmSystemTools::GetFilenameLastExtension(sf->FullPath);

      // Store the proxy in the map so it can be re-used and deleted later.
      cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
      i = cmCPluginAPISourceFiles.insert(entry).first;
    }
    return i->second;
  }
  return nullptr;
}

void* CCONV cmAddSource(void* arg, void* arg2)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  cmCPluginAPISourceFile* osf = static_cast<cmCPluginAPISourceFile*>(arg2);
  if (osf->FullPath.empty()) {
    return nullptr;
  }

  // Create the real cmSourceFile instance and copy over saved information.
  cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath);
  rsf->GetProperties() = osf->Properties;
  for (std::string const& d : osf->Depends) {
    rsf->AddDepend(d);
  }

  // Create the proxy for the real source file.
  cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
  sf->RealSourceFile = rsf;
  sf->FullPath = osf->FullPath;
  sf->SourceName = osf->SourceName;
  sf->SourceExtension = osf->SourceExtension;

  // Store the proxy in the map so it can be re-used and deleted later.
  cmCPluginAPISourceFiles[rsf] = sf;
  return sf;
}

const char* CCONV cmSourceFileGetSourceName(void* arg)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  return sf->SourceName.c_str();
}

const char* CCONV cmSourceFileGetFullPath(void* arg)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  return sf->FullPath.c_str();
}

const char* CCONV cmSourceFileGetProperty(void* arg, const char* prop)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  if (cmSourceFile* rsf = sf->RealSourceFile) {
    return rsf->GetProperty(prop);
  }
  if (!strcmp(prop, "LOCATION")) {
    return sf->FullPath.c_str();
  }
  return sf->Properties.GetPropertyValue(prop);
}

int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  if (cmSourceFile* rsf = sf->RealSourceFile) {
    return rsf->GetPropertyAsBool(prop) ? 1 : 0;
  }
  return cmSystemTools::IsOn(cmSourceFileGetProperty(arg, prop)) ? 1 : 0;
}

void CCONV cmSourceFileSetProperty(void* arg, const char* prop,
                                   const char* value)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  if (cmSourceFile* rsf = sf->RealSourceFile) {
    rsf->SetProperty(prop, value);
  } else if (prop) {
    if (!value) {
      value = "NOTFOUND";
    }
    sf->Properties.SetProperty(prop, value);
  }
}

void CCONV cmSourceFileAddDepend(void* arg, const char* depend)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  if (cmSourceFile* rsf = sf->RealSourceFile) {
    rsf->AddDepend(depend);
  } else {
    sf->Depends.emplace_back(depend);
  }
}

void CCONV cmSourceFileSetName(void* arg, const char* name, const char* dir,
                               int numSourceExtensions,
                               const char** sourceExtensions,
                               int numHeaderExtensions,
                               const char** headerExtensions)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  if (sf->RealSourceFile) {
    // SetName is allowed only on temporary source files created by
    // the command for building and passing to AddSource.
    return;
  }
  std::vector<std::string> sourceExts;
  std::vector<std::string> headerExts;
  int i;
  for (i = 0; i < numSourceExtensions; ++i) {
    sourceExts.emplace_back(sourceExtensions[i]);
  }
  for (i = 0; i < numHeaderExtensions; ++i) {
    headerExts.emplace_back(headerExtensions[i]);
  }

  // Save the original name given.
  sf->SourceName = name;

  // Convert the name to a full path in case the given name is a
  // relative path.
  std::string pathname = cmSystemTools::CollapseFullPath(name, dir);

  // First try and see whether the listed file can be found
  // as is without extensions added on.
  std::string hname = pathname;
  if (cmSystemTools::FileExists(hname)) {
    sf->SourceName = cmSystemTools::GetFilenamePath(name);
    if (!sf->SourceName.empty()) {
      sf->SourceName += "/";
    }
    sf->SourceName += cmSystemTools::GetFilenameWithoutLastExtension(name);
    std::string::size_type pos = hname.rfind('.');
    if (pos != std::string::npos) {
      sf->SourceExtension = hname.substr(pos + 1, hname.size() - pos);
      if (cmSystemTools::FileIsFullPath(name)) {
        std::string::size_type pos2 = hname.rfind('/');
        if (pos2 != std::string::npos) {
          sf->SourceName = hname.substr(pos2 + 1, pos - pos2 - 1);
        }
      }
    }

    sf->FullPath = hname;
    return;
  }

  // Next, try the various source extensions
  for (std::string const& ext : sourceExts) {
    hname = pathname;
    hname += ".";
    hname += ext;
    if (cmSystemTools::FileExists(hname)) {
      sf->SourceExtension = ext;
      sf->FullPath = hname;
      return;
    }
  }

  // Finally, try the various header extensions
  for (std::string const& ext : headerExts) {
    hname = pathname;
    hname += ".";
    hname += ext;
    if (cmSystemTools::FileExists(hname)) {
      sf->SourceExtension = ext;
      sf->FullPath = hname;
      return;
    }
  }

  std::ostringstream e;
  e << "Cannot find source file \"" << pathname << "\"";
  e << "\n\nTried extensions";
  for (std::string const& ext : sourceExts) {
    e << " ." << ext;
  }
  for (std::string const& ext : headerExts) {
    e << " ." << ext;
  }
  cmSystemTools::Error(e.str());
}

void CCONV cmSourceFileSetName2(void* arg, const char* name, const char* dir,
                                const char* ext, int headerFileOnly)
{
  cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  if (sf->RealSourceFile) {
    // SetName is allowed only on temporary source files created by
    // the command for building and passing to AddSource.
    return;
  }

  // Implement the old SetName method code here.
  if (headerFileOnly) {
    sf->Properties.SetProperty("HEADER_FILE_ONLY", "1");
  }
  sf->SourceName = name;
  std::string fname = sf->SourceName;
  if (ext && strlen(ext)) {
    fname += ".";
    fname += ext;
  }
  sf->FullPath = cmSystemTools::CollapseFullPath(fname, dir);
  cmSystemTools::ConvertToUnixSlashes(sf->FullPath);
  sf->SourceExtension = ext;
}

char* CCONV cmGetFilenameWithoutExtension(const char* name)
{
  std::string sres = cmSystemTools::GetFilenameWithoutExtension(name);
  return strdup(sres.c_str());
}

char* CCONV cmGetFilenamePath(const char* name)
{
  std::string sres = cmSystemTools::GetFilenamePath(name);
  return strdup(sres.c_str());
}

char* CCONV cmCapitalized(const char* name)
{
  std::string sres = cmSystemTools::Capitalized(name);
  return strdup(sres.c_str());
}

void CCONV cmCopyFileIfDifferent(const char* name1, const char* name2)
{
  cmSystemTools::CopyFileIfDifferent(name1, name2);
}

void CCONV cmRemoveFile(const char* name)
{
  cmSystemTools::RemoveFile(name);
}

void CCONV cmDisplayStatus(void* arg, const char* message)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  mf->DisplayStatus(message, -1);
}

void CCONV cmFree(void* data)
{
  free(data);
}

void CCONV DefineSourceFileProperty(void* arg, const char* name,
                                    const char* briefDocs,
                                    const char* longDocs, int chained)
{
  cmMakefile* mf = static_cast<cmMakefile*>(arg);
  mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE, briefDocs,
                                 longDocs, chained != 0);
}

} // close the extern "C" scope

cmCAPI cmStaticCAPI = {
  cmGetClientData,
  cmGetTotalArgumentSize,
  cmFreeArguments,
  cmSetClientData,
  cmSetError,
  cmAddCacheDefinition,
  cmAddCustomCommand,
  cmAddDefineFlag,
  cmAddDefinition,
  cmAddExecutable,
  cmAddLibrary,
  cmAddLinkDirectoryForTarget,
  cmAddLinkLibraryForTarget,
  cmAddUtilityCommand,
  cmCommandExists,
  cmExecuteCommand,
  cmExpandSourceListArguments,
  cmExpandVariablesInString,
  cmGetCacheMajorVersion,
  cmGetCacheMinorVersion,
  cmGetCurrentDirectory,
  cmGetCurrentOutputDirectory,
  cmGetDefinition,
  cmGetHomeDirectory,
  cmGetHomeOutputDirectory,
  cmGetMajorVersion,
  cmGetMinorVersion,
  cmGetProjectName,
  cmGetStartDirectory,
  cmGetStartOutputDirectory,
  cmIsOn,

  cmAddSource,
  cmCreateSourceFile,
  cmDestroySourceFile,
  cmGetSource,
  cmSourceFileAddDepend,
  cmSourceFileGetProperty,
  cmSourceFileGetPropertyAsBool,
  cmSourceFileGetSourceName,
  cmSourceFileGetFullPath,
  cmSourceFileSetName,
  cmSourceFileSetName2,
  cmSourceFileSetProperty,

  cmCapitalized,
  cmCopyFileIfDifferent,
  cmGetFilenameWithoutExtension,
  cmGetFilenamePath,
  cmRemoveFile,
  cmFree,

  cmAddCustomCommandToOutput,
  cmAddCustomCommandToTarget,
  cmDisplayStatus,
  cmCreateNewSourceFile,
  DefineSourceFileProperty,
};
