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