Home | History | Annotate | Download | only in c-arcmt-test
      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 
     12 static 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 
     37 static 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 
     66 static 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 
     74 int 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 
     92 typedef struct thread_info {
     93   int argc;
     94   const char **argv;
     95   int result;
     96 } thread_info;
     97 void 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 }
    101 
    102 static void flush_atexit(void) {
    103   /* stdout, and surprisingly even stderr, are not always flushed on process
    104    * and thread exit, particularly when the system is under heavy load. */
    105   fflush(stdout);
    106   fflush(stderr);
    107 }
    108 
    109 int main(int argc, const char **argv) {
    110   thread_info client_data;
    111 
    112   atexit(flush_atexit);
    113 
    114 #if defined(_WIN32)
    115   if (getenv("LIBCLANG_LOGGING") == NULL)
    116     putenv("LIBCLANG_LOGGING=1");
    117   _setmode( _fileno(stdout), _O_BINARY );
    118 #else
    119   setenv("LIBCLANG_LOGGING", "1", /*overwrite=*/0);
    120 #endif
    121 
    122   if (getenv("CINDEXTEST_NOTHREADS"))
    123     return carcmttest_main(argc, argv);
    124 
    125   client_data.argc = argc;
    126   client_data.argv = argv;
    127   clang_executeOnThread(thread_runner, &client_data, 0);
    128   return client_data.result;
    129 }
    130