summaryrefslogtreecommitdiffstats
path: root/perform
diff options
context:
space:
mode:
Diffstat (limited to 'perform')
-rw-r--r--perform/pio_perf.c37
-rw-r--r--perform/sio_perf.c35
2 files changed, 41 insertions, 31 deletions
diff --git a/perform/pio_perf.c b/perform/pio_perf.c
index 411fb12..9cbd65d 100644
--- a/perform/pio_perf.c
+++ b/perform/pio_perf.c
@@ -288,14 +288,14 @@ struct options {
unsigned interleaved; /* Interleaved vs. contiguous blocks */
unsigned collective; /* Collective vs. independent I/O */
unsigned dim2d; /* 1D vs. 2D geometry */
- int print_times; /* print times as well as throughputs */
- int print_raw; /* print raw data throughput info */
+ int print_times; /* print times as well as throughputs */
+ int print_raw; /* print raw data throughput info */
off_t h5_alignment; /* alignment in HDF5 file */
off_t h5_threshold; /* threshold for alignment in HDF5 file */
- int h5_use_chunks; /* Make HDF5 dataset chunked */
- int h5_write_only; /* Perform the write tests only */
+ int h5_use_chunks; /* Make HDF5 dataset chunked */
+ int h5_write_only; /* Perform the write tests only */
unsigned h5_use_mpi_posix; /* Use MPI-posix VFD for HDF5 I/O (instead of MPI-I/O VFD) */
- int verify; /* Verify data correctness */
+ int verify; /* Verify data correctness */
};
typedef struct _minmax {
@@ -339,6 +339,11 @@ main(int argc, char **argv)
int exit_value = EXIT_SUCCESS;
struct options *opts = NULL;
+#ifndef STANDALONE
+ /* Initialize h5tools lib */
+ h5tools_init();
+#endif
+
output = stdout;
/* initialize MPI and get the maximum num of processors we started with */
@@ -678,7 +683,7 @@ run_test(iotype iot, parameters parms, struct options *opts)
/*
* Show various statistics
*/
- /* Write statistics */
+ /* Write statistics */
/* Print the raw data throughput if desired */
if (opts->print_raw) {
/* accumulate and output the max, min, and average "raw write" times */
@@ -744,7 +749,7 @@ run_test(iotype iot, parameters parms, struct options *opts)
}
if (!parms.h5_write_only) {
- /* Read statistics */
+ /* Read statistics */
/* Print the raw data throughput if desired */
if (opts->print_raw) {
/* accumulate and output the max, min, and average "raw read" times */
@@ -1098,10 +1103,10 @@ print_indent(register int indent)
MPI_Comm_rank(pio_comm_g, &myrank);
if (myrank == 0) {
- indent *= TAB_SPACE;
+ indent *= TAB_SPACE;
- for (; indent > 0; --indent)
- fputc(' ', output);
+ for (; indent > 0; --indent)
+ fputc(' ', output);
}
}
@@ -1126,11 +1131,11 @@ static void
print_io_api(long io_types)
{
if (io_types & PIO_POSIX)
- HDfprintf(output, "posix ");
+ HDfprintf(output, "posix ");
if (io_types & PIO_MPI)
- HDfprintf(output, "mpiio ");
+ HDfprintf(output, "mpiio ");
if (io_types & PIO_HDF5)
- HDfprintf(output, "phdf5 ");
+ HDfprintf(output, "phdf5 ");
HDfprintf(output, "\n");
}
@@ -1139,7 +1144,7 @@ report_parameters(struct options *opts)
{
int rank = comm_world_rank_g;
- print_version("HDF5 Library"); /* print library version */
+ print_version("HDF5 Library"); /* print library version */
HDfprintf(output, "rank %d: ==== Parameters ====\n", rank);
HDfprintf(output, "rank %d: IO API=", rank);
@@ -1560,7 +1565,7 @@ parse_size_directive(const char *size)
* Return: Nothing
* Programmer: Bill Wendling, 31. October 2001
* Modifications:
- * Added 2D testing (Christian Chilan, 10. August 2005)
+ * Added 2D testing (Christian Chilan, 10. August 2005)
*/
static void
usage(const char *prog)
@@ -1570,7 +1575,7 @@ usage(const char *prog)
MPI_Comm_rank(pio_comm_g, &myrank);
if (myrank == 0) {
- print_version(prog);
+ print_version(prog);
printf("usage: %s [OPTIONS]\n", prog);
printf(" OPTIONS\n");
printf(" -h, --help Print a usage message and exit\n");
diff --git a/perform/sio_perf.c b/perform/sio_perf.c
index d852a45..8900e2e 100644
--- a/perform/sio_perf.c
+++ b/perform/sio_perf.c
@@ -295,15 +295,15 @@ struct options {
int buf_rank; /* Rank */
int order_rank; /* Rank */
int chk_rank; /* Rank */
- int print_times; /* print times as well as throughputs */
- int print_raw; /* print raw data throughput info */
+ int print_times; /* print times as well as throughputs */
+ int print_raw; /* print raw data throughput info */
off_t h5_alignment; /* alignment in HDF5 file */
off_t h5_threshold; /* threshold for alignment in HDF5 file */
- int h5_use_chunks; /* Make HDF5 dataset chunked */
- int h5_write_only; /* Perform the write tests only */
- int h5_extendable; /* Perform the write tests only */
+ int h5_use_chunks; /* Make HDF5 dataset chunked */
+ int h5_write_only; /* Perform the write tests only */
+ int h5_extendable; /* Perform the write tests only */
unsigned h5_use_mpi_posix; /* Use MPI-posix VFD for HDF5 I/O (instead of MPI-I/O VFD) */
- int verify; /* Verify data correctness */
+ int verify; /* Verify data correctness */
vfdtype vfd; /* File driver */
};
@@ -343,6 +343,11 @@ main(int argc, char **argv)
int exit_value = EXIT_SUCCESS;
struct options *opts = NULL;
+#ifndef STANDALONE
+ /* Initialize h5tools lib */
+ h5tools_init();
+#endif
+
output = stdout;
opts = parse_command_line(argc, argv);
@@ -553,7 +558,7 @@ run_test(iotype iot, parameters parms, struct options *opts)
/*
* Show various statistics
*/
- /* Write statistics */
+ /* Write statistics */
/* Print the raw data throughput if desired */
if (opts->print_raw) {
/* accumulate and output the max, min, and average "raw write" times */
@@ -599,7 +604,7 @@ run_test(iotype iot, parameters parms, struct options *opts)
output_results(opts,"Write Open-Close",write_gross_mm_table,parms.num_iters,raw_size);
if (!parms.h5_write_only) {
- /* Read statistics */
+ /* Read statistics */
/* Print the raw data throughput if desired */
if (opts->print_raw) {
/* accumulate and output the max, min, and average "raw read" times */
@@ -810,10 +815,10 @@ output_report(const char *fmt, ...)
static void
print_indent(register int indent)
{
- indent *= TAB_SPACE;
+ indent *= TAB_SPACE;
- for (; indent > 0; --indent)
- fputc(' ', output);
+ for (; indent > 0; --indent)
+ fputc(' ', output);
}
static void
@@ -837,9 +842,9 @@ static void
print_io_api(long io_types)
{
if (io_types & SIO_POSIX)
- HDfprintf(output, "posix ");
+ HDfprintf(output, "posix ");
if (io_types & SIO_HDF5)
- HDfprintf(output, "hdf5 ");
+ HDfprintf(output, "hdf5 ");
HDfprintf(output, "\n");
}
@@ -849,7 +854,7 @@ report_parameters(struct options *opts)
int i, rank;
rank = opts->dset_rank;
- print_version("HDF5 Library"); /* print library version */
+ print_version("HDF5 Library"); /* print library version */
HDfprintf(output, "==== Parameters ====\n");
HDfprintf(output, "IO API=");
@@ -1343,7 +1348,7 @@ parse_size_directive(const char *size)
static void
usage(const char *prog)
{
- print_version(prog);
+ print_version(prog);
printf("usage: %s [OPTIONS]\n", prog);
printf(" OPTIONS\n");
printf(" -h Print an usage message and exit\n");
href='#n620'>620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845
/* 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 <cstdlib>

#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmVersion.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.
  std::vector<std::string> no_byproducts;
  mf->AddUtilityCommand(utilityName, (all ? false : true), nullptr,
                        no_byproducts, 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.
  cmCustomCommandType cctype = cmCustomCommandType::POST_BUILD;
  switch (commandType) {
    case CM_PRE_BUILD:
      cctype = cmCustomCommandType::PRE_BUILD;
      break;
    case CM_PRE_LINK:
      cctype = cmCustomCommandType::PRE_LINK;
      break;
    case CM_POST_BUILD:
      cctype = cmCustomCommandType::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.
using cmCPluginAPISourceFileMap =
  std::map<cmSourceFile*, std::unique_ptr<cmCPluginAPISourceFile>>;
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.
    auto i = cmCPluginAPISourceFiles.find(rsf);
    if (i == cmCPluginAPISourceFiles.end()) {
      // Create a proxy source file object for this source.
      auto sf = cm::make_unique<cmCPluginAPISourceFile>();
      sf->RealSourceFile = rsf;
      sf->FullPath = rsf->ResolveFullPath();
      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.
      i = cmCPluginAPISourceFiles.emplace(rsf, std::move(sf)).first;
    }
    return i->second.get();
  }
  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->SetProperties(osf->Properties);
  for (std::string const& d : osf->Depends) {
    rsf->AddDepend(d);
  }

  // Create the proxy for the real source file.
  auto sf = cm::make_unique<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.
  auto value = sf.get();
  cmCPluginAPISourceFiles[rsf] = std::move(sf);
  return value;
}

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) {
    cmProp p = rsf->GetProperty(prop);
    return p ? p->c_str() : nullptr;
  }
  if (!strcmp(prop, "LOCATION")) {
    return sf->FullPath.c_str();
  }
  cmProp retVal = sf->Properties.GetPropertyValue(prop);
  return retVal ? retVal->c_str() : nullptr;
}

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 cmIsOn(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 = cmStrCat(pathname, '.', 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 = cmStrCat(pathname, '.', 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 ? briefDocs : "",
                                 longDocs ? 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,
};