1/* c-arcmt-test.c */ 2 3#include "clang-c/Index.h" 4#include <stdlib.h> 5#include <stdio.h> 6#include <string.h> 7#if defined(_WIN32) 8#include <io.h> 9#include <fcntl.h> 10#endif 11 12static int print_remappings(const char *path) { 13 CXRemapping remap; 14 unsigned i, N; 15 CXString origFname; 16 CXString transFname; 17 18 remap = clang_getRemappings(path); 19 if (!remap) 20 return 1; 21 22 N = clang_remap_getNumFiles(remap); 23 for (i = 0; i != N; ++i) { 24 clang_remap_getFilenames(remap, i, &origFname, &transFname); 25 26 fprintf(stdout, "%s\n", clang_getCString(origFname)); 27 fprintf(stdout, "%s\n", clang_getCString(transFname)); 28 29 clang_disposeString(origFname); 30 clang_disposeString(transFname); 31 } 32 33 clang_remap_dispose(remap); 34 return 0; 35} 36 37static int print_remappings_filelist(const char **files, unsigned numFiles) { 38 CXRemapping remap; 39 unsigned i, N; 40 CXString origFname; 41 CXString transFname; 42 43 remap = clang_getRemappingsFromFileList(files, numFiles); 44 if (!remap) 45 return 1; 46 47 N = clang_remap_getNumFiles(remap); 48 for (i = 0; i != N; ++i) { 49 clang_remap_getFilenames(remap, i, &origFname, &transFname); 50 51 fprintf(stdout, "%s\n", clang_getCString(origFname)); 52 fprintf(stdout, "%s\n", clang_getCString(transFname)); 53 54 clang_disposeString(origFname); 55 clang_disposeString(transFname); 56 } 57 58 clang_remap_dispose(remap); 59 return 0; 60} 61 62/******************************************************************************/ 63/* Command line processing. */ 64/******************************************************************************/ 65 66static void print_usage(void) { 67 fprintf(stderr, 68 "usage: c-arcmt-test -mt-migrate-directory <path>\n" 69 " c-arcmt-test <remap-file-path1> <remap-file-path2> ...\n\n\n"); 70} 71 72/***/ 73 74int carcmttest_main(int argc, const char **argv) { 75 clang_enableStackTraces(); 76 if (argc == 3 && strncmp(argv[1], "-mt-migrate-directory", 21) == 0) 77 return print_remappings(argv[2]); 78 79 if (argc > 1) 80 return print_remappings_filelist(argv+1, argc-1); 81 82 print_usage(); 83 return 1; 84} 85 86/***/ 87 88/* We intentionally run in a separate thread to ensure we at least minimal 89 * testing of a multithreaded environment (for example, having a reduced stack 90 * size). */ 91 92typedef struct thread_info { 93 int argc; 94 const char **argv; 95 int result; 96} thread_info; 97void thread_runner(void *client_data_v) { 98 thread_info *client_data = client_data_v; 99 client_data->result = carcmttest_main(client_data->argc, client_data->argv); 100#ifdef __CYGWIN__ 101 fflush(stdout); /* stdout is not flushed on Cygwin. */ 102#endif 103} 104 105int main(int argc, const char **argv) { 106 thread_info client_data; 107 108#if defined(_WIN32) 109 if (getenv("LIBCLANG_LOGGING") == NULL) 110 putenv("LIBCLANG_LOGGING=1"); 111 _setmode( _fileno(stdout), _O_BINARY ); 112#else 113 setenv("LIBCLANG_LOGGING", "1", /*overwrite=*/0); 114#endif 115 116 if (getenv("CINDEXTEST_NOTHREADS")) 117 return carcmttest_main(argc, argv); 118 119 client_data.argc = argc; 120 client_data.argv = argv; 121 clang_executeOnThread(thread_runner, &client_data, 0); 122 return client_data.result; 123} 124