/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
/*
   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 "cmMakefile.h"
#include "cmCPluginAPI.h"
#include "cmVersion.h"

#include "cmSourceFile.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);
  return mf->GetCacheMajorVersion();
}
unsigned int CCONV cmGetCacheMinorVersion(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  return mf->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)
{
  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,
                             cmCacheManager::BOOL);
      break;
    case CM_CACHE_PATH:
      mf->AddCacheDefinition(name,value,doc,
                             cmCacheManager::PATH);
      break;
    case CM_CACHE_FILEPATH:
      mf->AddCacheDefinition(name,value,doc,
                             cmCacheManager::FILEPATH);
      break;
    case CM_CACHE_STRING:
      mf->AddCacheDefinition(name,value,doc,
                             cmCacheManager::STRING);
      break;
    case CM_CACHE_INTERNAL:
      mf->AddCacheDefinition(name,value,doc,
                             cmCacheManager::INTERNAL);
      break;
    case CM_CACHE_STATIC:
      mf->AddCacheDefinition(name,value,doc,
                             cmCacheManager::STATIC);
      break;
    }
}

const char* CCONV cmGetProjectName(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  return mf->GetProjectName();
}

const char* CCONV cmGetHomeDirectory(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  return mf->GetHomeDirectory();
}
const char* CCONV cmGetHomeOutputDirectory(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  return mf->GetHomeOutputDirectory();
}
const char* CCONV cmGetStartDirectory(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  return mf->GetStartDirectory();
}
const char* CCONV cmGetStartOutputDirectory(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  return mf->GetStartOutputDirectory();
}
const char* CCONV cmGetCurrentDirectory(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  return mf->GetCurrentDirectory();
}
const char* CCONV cmGetCurrentOutputDirectory(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  return mf->GetCurrentOutputDirectory();
}
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->CommandExists(name));
}

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);
  mf->AddLinkDirectoryForTarget(tgt,d);
}


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.push_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, (all ? false : true),
                        0, 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 = 0;
  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 = 0;
  const char* no_working_dir = 0;
  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_depends;
  const char* no_comment = 0;
  const char* no_working_dir = 0;
  mf->AddCustomCommandToTarget(target, no_depends, commandLines,
                               cctype, no_comment, no_working_dir);
}

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:
      mf->AddLinkLibraryForTarget(tgt,value, cmTarget::GENERAL);
      break;
    case CM_LIBRARY_DEBUG:
      mf->AddLinkLibraryForTarget(tgt,value, cmTarget::DEBUG);
      break;
    case CM_LIBRARY_OPTIMIZED:
      mf->AddLinkLibraryForTarget(tgt,value, cmTarget::OPTIMIZED);
      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.push_back(srcs[i]);
    }
  mf->AddLibrary(libname,
                 (shared? cmTarget::SHARED_LIBRARY : cmTarget::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 result =
    mf->ExpandVariablesInString(barf,
                                (escapeQuotes ? true : false),
                                (atOnly ? true : false));
  char *res = static_cast<char *>(malloc(result.size() + 1));
  if (result.size())
    {
    strcpy(res,result.c_str());
    }
  res[result.size()] = '\0';
  return res;
}


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.push_back(cmListFileArgument(args[i], true,
                                               "[CMake-Plugin]", 0));
    }
  cmExecutionStatus status;
  return mf->ExecuteCommand(lff,status);
}

void CCONV cmExpandSourceListArguments(void *arg,
                                 int numArgs,
                                 const char **args,
                                 int *resArgc,
                                 char ***resArgv,
                                 unsigned int startArgumentIndex)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  std::vector<std::string> result;
  std::vector<std::string> args2;
  int i;
  for (i = 0; i < numArgs; ++i)
    {
    args2.push_back(args[i]);
    }
  mf->ExpandSourceListArguments(args2, result, startArgumentIndex);
  int resargc = static_cast<int>(result.size());
  char **resargv = 0;
  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]);
    }
  if (argv)
    {
    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
{
  cmCPluginAPISourceFile(): RealSourceFile(0) {}
  cmSourceFile* RealSourceFile;
  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()
    {
    for(iterator i=this->begin(); i != this->end(); ++i)
      {
      delete i->second;
      }
    }
};
cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;

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

void * CCONV cmCreateNewSourceFile(void *arg)
{
  cmMakefile *mf = static_cast<cmMakefile *>(arg);
  cmCPluginAPISourceFile *sf = new cmCPluginAPISourceFile;
  sf->Properties.SetCMakeInstance(mf->GetCMakeInstance());
  return (void*)sf;
}

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.c_str());
      sf->SourceExtension =
        cmSystemTools::GetFilenameLastExtension(sf->FullPath.c_str());

      // 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 (void *)i->second;
    }
  else
    {
    return 0;
    }
}

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

  // Create the real cmSourceFile instance and copy over saved information.
  cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath.c_str());
  rsf->GetProperties() = osf->Properties;
  for(std::vector<std::string>::iterator i = osf->Depends.begin();
      i != osf->Depends.end(); ++i)
    {
    rsf->AddDepend(i->c_str());
    }

  // 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 (void *)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);
    }
  else
    {
    if(!strcmp(prop,"LOCATION"))
      {
      return sf->FullPath.c_str();
      }
    bool chain = false;
    // Ignore chain because old code will not expect it and it is a
    // pain to implement here anyway.
    return sf->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE,
                                           chain);
    }
}

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;
    }
  else
    {
    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, cmProperty::SOURCE_FILE);
    }
}

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.push_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.push_back(sourceExtensions[i]);
    }
  for (i = 0; i < numHeaderExtensions; ++i)
    {
    headerExts.push_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.c_str()))
    {
    sf->SourceName = cmSystemTools::GetFilenamePath(name);
    if ( sf->SourceName.size() > 0 )
      {
      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::vector<std::string>::const_iterator ext = sourceExts.begin();
       ext != sourceExts.end(); ++ext )
    {
    hname = pathname;
    hname += ".";
    hname += *ext;
    if(cmSystemTools::FileExists(hname.c_str()))
      {
      sf->SourceExtension = *ext;
      sf->FullPath = hname;
      return;
      }
    }

  // Finally, try the various header extensions
  for( std::vector<std::string>::const_iterator ext = headerExts.begin();
       ext != headerExts.end(); ++ext )
    {
    hname = pathname;
    hname += ".";
    hname += *ext;
    if(cmSystemTools::FileExists(hname.c_str()))
      {
      sf->SourceExtension = *ext;
      sf->FullPath = hname;
      return;
      }
    }

  cmOStringStream e;
  e << "Cannot find source file \"" << pathname << "\"";
  e << "\n\nTried extensions";
  for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
       ext != sourceExts.end(); ++ext )
    {
    e << " ." << *ext;
    }
  for( std::vector<std::string>::const_iterator ext = headerExts.begin();
       ext != headerExts.end(); ++ext )
    {
    e << " ." << *ext;
    }
  cmSystemTools::Error(e.str().c_str());
  return;
}

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",
                               cmProperty::SOURCE_FILE);
    }
  sf->SourceName = name;
  std::string fname = sf->SourceName;
  if(ext && strlen(ext))
    {
    fname += ".";
    fname += ext;
    }
  sf->FullPath = cmSystemTools::CollapseFullPath(fname.c_str(), dir);
  cmSystemTools::ConvertToUnixSlashes(sf->FullPath);
  sf->SourceExtension = ext;
}

char * CCONV cmGetFilenameWithoutExtension(const char *name)
{
  std::string sres = cmSystemTools::GetFilenameWithoutExtension(name);
  char *result = (char *)malloc(sres.size()+1);
  strcpy(result,sres.c_str());
  return result;
}

char * CCONV cmGetFilenamePath(const char *name)
{
  std::string sres = cmSystemTools::GetFilenamePath(name);
  char *result = (char *)malloc(sres.size()+1);
  strcpy(result,sres.c_str());
  return result;
}

char * CCONV cmCapitalized(const char *name)
{
  std::string sres = cmSystemTools::Capitalized(name);
  char *result = (char *)malloc(sres.size()+1);
  strcpy(result,sres.c_str());
  return result;
}

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->GetCMakeInstance()->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,
};

