thrift的编译器作用是把thrift文件编译成各种目标语言的代码,编译器的代码目录在thrift-0.8.0/compiler/cpp/src/下。
main函数一开始解析各种参数,主要的是编译的目标语言及输出的目录和thrift文件的path。没有用到库函数,自己解析的。
以下代码就是解析参数,记录目标语言和输出的目录,其它的一些参数就省略了
for (i = 1; i < argc-1; i++) { char* arg; arg = strtok(argv[i], " "); while (arg != NULL) { // Treat double dashes as single dashes if (arg[0] == '-' && arg[1] == '-') { ++arg; } if (strcmp(arg, "-version") == 0) { version(); exit(1); } ....... else if (strcmp(arg, "-cpp") == 0) { gen_cpp = true; } ......... else if ((strcmp(arg, "-o") == 0) || (strcmp(arg, "-out") == 0)) { out_path_is_absolute = (strcmp(arg, "-out") == 0) ? true : false; arg = argv[++i]; if (arg == NULL) { fprintf(stderr, "-o: missing output directory\n"); usage(); } out_path = arg; struct stat sb; if (stat(out_path.c_str(), &sb) < 0) { fprintf(stderr, "Output directory %s is unusable: %s\n", out_path.c_str(), strerror(errno)); return -1; } if (! S_ISDIR(sb.st_mode)) { fprintf(stderr, "Output directory %s exists but is not a directory\n", out_path.c_str()); return -1; } } else { fprintf(stderr, "!!! Unrecognized option: %s\n", arg); usage(); } // Tokenize more arg = strtok(NULL, " "); } }
最后一个参数是thrift文件的path,并且把路径转成绝对路径。// Real-pathify it char rp[PATH_MAX]; if (argv[i] == NULL) { fprintf(stderr, "!!! Missing file name\n"); usage(); } if (saferealpath(argv[i], rp) == NULL) { failure("Could not open input file with realpath: %s", argv[i]); } string input_file(rp);接下来定义了一堆thrift中支持的数据类型。// Initialize global types g_type_void = new t_base_type("void", t_base_type::TYPE_VOID); g_type_string = new t_base_type("string", t_base_type::TYPE_STRING); g_type_binary = new t_base_type("string", t_base_type::TYPE_STRING); ((t_base_type*)g_type_binary)->set_binary(true); g_type_slist = new t_base_type("string", t_base_type::TYPE_STRING); ((t_base_type*)g_type_slist)->set_string_list(true); g_type_bool = new t_base_type("bool", t_base_type::TYPE_BOOL); g_type_byte = new t_base_type("byte", t_base_type::TYPE_BYTE); g_type_i16 = new t_base_type("i16", t_base_type::TYPE_I16); g_type_i32 = new t_base_type("i32", t_base_type::TYPE_I32); g_type_i64 = new t_base_type("i64", t_base_type::TYPE_I64); g_type_double = new t_base_type("double", t_base_type::TYPE_DOUBLE);
最后解析这个thrfit文件,并且生成目标语言的代码。编译器实用flex和bison作词法分析和语法分析。
// Parse it! parse(program, NULL); // The current path is not really relevant when we are doing generation. // Reset the variable to make warning messages clearer. g_curpath = "generation"; // Reset yylineno for the heck of it. Use 1 instead of 0 because // That is what shows up during argument parsing. yylineno = 1; // Generate it! generate(program, generator_strings);
main函数就到此为止了。