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