reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
/* c-arcmt-test.c */

#include "clang-c/Index.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#endif

static int print_remappings(const char *path) {
  CXRemapping remap;
  unsigned i, N;
  CXString origFname;
  CXString transFname;

  remap = clang_getRemappings(path);
  if (!remap)
    return 1;

  N = clang_remap_getNumFiles(remap);
  for (i = 0; i != N; ++i) {
    clang_remap_getFilenames(remap, i, &origFname, &transFname);

    fprintf(stdout, "%s\n", clang_getCString(origFname));
    fprintf(stdout, "%s\n", clang_getCString(transFname));

    clang_disposeString(origFname);
    clang_disposeString(transFname);
  }

  clang_remap_dispose(remap);
  return 0;
}

static int print_remappings_filelist(const char **files, unsigned numFiles) {
  CXRemapping remap;
  unsigned i, N;
  CXString origFname;
  CXString transFname;

  remap = clang_getRemappingsFromFileList(files, numFiles);
  if (!remap)
    return 1;

  N = clang_remap_getNumFiles(remap);
  for (i = 0; i != N; ++i) {
    clang_remap_getFilenames(remap, i, &origFname, &transFname);

    fprintf(stdout, "%s\n", clang_getCString(origFname));
    fprintf(stdout, "%s\n", clang_getCString(transFname));

    clang_disposeString(origFname);
    clang_disposeString(transFname);
  }

  clang_remap_dispose(remap);
  return 0;
}

/******************************************************************************/
/* Command line processing.                                                   */
/******************************************************************************/

static void print_usage(void) {
  fprintf(stderr,
    "usage: c-arcmt-test -mt-migrate-directory <path>\n"
    "       c-arcmt-test <remap-file-path1> <remap-file-path2> ...\n\n\n");
}

/***/

int carcmttest_main(int argc, const char **argv) {
  clang_enableStackTraces();
  if (argc == 3 && strncmp(argv[1], "-mt-migrate-directory", 21) == 0)
    return print_remappings(argv[2]);

  if (argc > 1)
    return print_remappings_filelist(argv+1, argc-1);
  
  print_usage();
  return 1;
}

/***/

/* We intentionally run in a separate thread to ensure we at least minimal
 * testing of a multithreaded environment (for example, having a reduced stack
 * size). */

typedef struct thread_info {
  int argc;
  const char **argv;
  int result;
} thread_info;
void thread_runner(void *client_data_v) {
  thread_info *client_data = client_data_v;
  client_data->result = carcmttest_main(client_data->argc, client_data->argv);
}

static void flush_atexit(void) {
  /* stdout, and surprisingly even stderr, are not always flushed on process
   * and thread exit, particularly when the system is under heavy load. */
  fflush(stdout);
  fflush(stderr);
}

int main(int argc, const char **argv) {
  thread_info client_data;

  atexit(flush_atexit);

#if defined(_WIN32)
  if (getenv("LIBCLANG_LOGGING") == NULL)
    putenv("LIBCLANG_LOGGING=1");
  _setmode( _fileno(stdout), _O_BINARY );
#else
  setenv("LIBCLANG_LOGGING", "1", /*overwrite=*/0);
#endif

  if (getenv("CINDEXTEST_NOTHREADS"))
    return carcmttest_main(argc, argv);

  client_data.argc = argc;
  client_data.argv = argv;
  clang_executeOnThread(thread_runner, &client_data, 0);
  return client_data.result;
}