169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis/* c-arcmt-test.c */
269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
397c337c2bdf3ec53073c7e7dd656aa0dd37ee409Argyrios Kyrtzidis#include "clang-c/Index.h"
469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis#include <stdlib.h>
569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis#include <stdio.h>
669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis#include <string.h>
79de09d43f6c42e82cf62402d19a47cbd9ae696f3Francois Pichet#if defined(_WIN32)
89de09d43f6c42e82cf62402d19a47cbd9ae696f3Francois Pichet#include <io.h>
99de09d43f6c42e82cf62402d19a47cbd9ae696f3Francois Pichet#include <fcntl.h>
109de09d43f6c42e82cf62402d19a47cbd9ae696f3Francois Pichet#endif
1169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
1269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisstatic int print_remappings(const char *path) {
1397c337c2bdf3ec53073c7e7dd656aa0dd37ee409Argyrios Kyrtzidis  CXRemapping remap;
1469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  unsigned i, N;
1569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  CXString origFname;
1669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  CXString transFname;
1769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
1897c337c2bdf3ec53073c7e7dd656aa0dd37ee409Argyrios Kyrtzidis  remap = clang_getRemappings(path);
1969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  if (!remap)
2069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis    return 1;
2169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
2297c337c2bdf3ec53073c7e7dd656aa0dd37ee409Argyrios Kyrtzidis  N = clang_remap_getNumFiles(remap);
2369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  for (i = 0; i != N; ++i) {
2497c337c2bdf3ec53073c7e7dd656aa0dd37ee409Argyrios Kyrtzidis    clang_remap_getFilenames(remap, i, &origFname, &transFname);
2569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
2669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis    fprintf(stdout, "%s\n", clang_getCString(origFname));
2769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis    fprintf(stdout, "%s\n", clang_getCString(transFname));
2869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
2969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis    clang_disposeString(origFname);
3069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis    clang_disposeString(transFname);
3169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  }
3269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
3397c337c2bdf3ec53073c7e7dd656aa0dd37ee409Argyrios Kyrtzidis  clang_remap_dispose(remap);
3469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  return 0;
3569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis}
3669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
3730660a898545416f0fea2d717f16f75640001e38Ted Kremenekstatic int print_remappings_filelist(const char **files, unsigned numFiles) {
3830660a898545416f0fea2d717f16f75640001e38Ted Kremenek  CXRemapping remap;
3930660a898545416f0fea2d717f16f75640001e38Ted Kremenek  unsigned i, N;
4030660a898545416f0fea2d717f16f75640001e38Ted Kremenek  CXString origFname;
4130660a898545416f0fea2d717f16f75640001e38Ted Kremenek  CXString transFname;
4230660a898545416f0fea2d717f16f75640001e38Ted Kremenek
4330660a898545416f0fea2d717f16f75640001e38Ted Kremenek  remap = clang_getRemappingsFromFileList(files, numFiles);
4430660a898545416f0fea2d717f16f75640001e38Ted Kremenek  if (!remap)
4530660a898545416f0fea2d717f16f75640001e38Ted Kremenek    return 1;
4630660a898545416f0fea2d717f16f75640001e38Ted Kremenek
4730660a898545416f0fea2d717f16f75640001e38Ted Kremenek  N = clang_remap_getNumFiles(remap);
4830660a898545416f0fea2d717f16f75640001e38Ted Kremenek  for (i = 0; i != N; ++i) {
4930660a898545416f0fea2d717f16f75640001e38Ted Kremenek    clang_remap_getFilenames(remap, i, &origFname, &transFname);
5030660a898545416f0fea2d717f16f75640001e38Ted Kremenek
5130660a898545416f0fea2d717f16f75640001e38Ted Kremenek    fprintf(stdout, "%s\n", clang_getCString(origFname));
5230660a898545416f0fea2d717f16f75640001e38Ted Kremenek    fprintf(stdout, "%s\n", clang_getCString(transFname));
5330660a898545416f0fea2d717f16f75640001e38Ted Kremenek
5430660a898545416f0fea2d717f16f75640001e38Ted Kremenek    clang_disposeString(origFname);
5530660a898545416f0fea2d717f16f75640001e38Ted Kremenek    clang_disposeString(transFname);
5630660a898545416f0fea2d717f16f75640001e38Ted Kremenek  }
5730660a898545416f0fea2d717f16f75640001e38Ted Kremenek
5830660a898545416f0fea2d717f16f75640001e38Ted Kremenek  clang_remap_dispose(remap);
5930660a898545416f0fea2d717f16f75640001e38Ted Kremenek  return 0;
6030660a898545416f0fea2d717f16f75640001e38Ted Kremenek}
6130660a898545416f0fea2d717f16f75640001e38Ted Kremenek
6269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis/******************************************************************************/
6369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis/* Command line processing.                                                   */
6469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis/******************************************************************************/
6569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
6669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisstatic void print_usage(void) {
6769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  fprintf(stderr,
6830660a898545416f0fea2d717f16f75640001e38Ted Kremenek    "usage: c-arcmt-test -mt-migrate-directory <path>\n"
6930660a898545416f0fea2d717f16f75640001e38Ted Kremenek    "       c-arcmt-test <remap-file-path1> <remap-file-path2> ...\n\n\n");
7069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis}
7169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
7269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis/***/
7369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
7469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisint carcmttest_main(int argc, const char **argv) {
7569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  clang_enableStackTraces();
7630660a898545416f0fea2d717f16f75640001e38Ted Kremenek  if (argc == 3 && strncmp(argv[1], "-mt-migrate-directory", 21) == 0)
7769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis    return print_remappings(argv[2]);
7869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
7930660a898545416f0fea2d717f16f75640001e38Ted Kremenek  if (argc > 1)
8030660a898545416f0fea2d717f16f75640001e38Ted Kremenek    return print_remappings_filelist(argv+1, argc-1);
8130660a898545416f0fea2d717f16f75640001e38Ted Kremenek
8269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  print_usage();
8369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  return 1;
8469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis}
8569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
8669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis/***/
8769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
8869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis/* We intentionally run in a separate thread to ensure we at least minimal
8969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis * testing of a multithreaded environment (for example, having a reduced stack
9069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis * size). */
9169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
9269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidistypedef struct thread_info {
9369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  int argc;
9469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  const char **argv;
9569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  int result;
9669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis} thread_info;
9769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisvoid thread_runner(void *client_data_v) {
9869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  thread_info *client_data = client_data_v;
9969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  client_data->result = carcmttest_main(client_data->argc, client_data->argv);
100ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}
101ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
102ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesstatic void flush_atexit(void) {
103ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  /* stdout, and surprisingly even stderr, are not always flushed on process
104ef8225444452a1486bd721f3285301fe84643b00Stephen Hines   * and thread exit, particularly when the system is under heavy load. */
105ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  fflush(stdout);
106ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  fflush(stderr);
10769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis}
10869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
10969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisint main(int argc, const char **argv) {
11069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  thread_info client_data;
11169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
112ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  atexit(flush_atexit);
113ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1140989bf7b7a5abaf5a7764c32921d7eafa316ba58NAKAMURA Takumi#if defined(_WIN32)
1150989bf7b7a5abaf5a7764c32921d7eafa316ba58NAKAMURA Takumi  if (getenv("LIBCLANG_LOGGING") == NULL)
1160989bf7b7a5abaf5a7764c32921d7eafa316ba58NAKAMURA Takumi    putenv("LIBCLANG_LOGGING=1");
1179de09d43f6c42e82cf62402d19a47cbd9ae696f3Francois Pichet  _setmode( _fileno(stdout), _O_BINARY );
1180989bf7b7a5abaf5a7764c32921d7eafa316ba58NAKAMURA Takumi#else
11969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  setenv("LIBCLANG_LOGGING", "1", /*overwrite=*/0);
1200989bf7b7a5abaf5a7764c32921d7eafa316ba58NAKAMURA Takumi#endif
12169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
12269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  if (getenv("CINDEXTEST_NOTHREADS"))
12369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis    return carcmttest_main(argc, argv);
12469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis
12569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  client_data.argc = argc;
12669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  client_data.argv = argv;
12769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  clang_executeOnThread(thread_runner, &client_data, 0);
12869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis  return client_data.result;
12969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis}
130