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函数就到此为止了。