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