123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- /*
- Copyright (c) 2020 Sogou, Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- #include <stdio.h>
- #include <string.h>
- #include <string>
- #ifdef _WIN32
- #include <direct.h>
- #define MAXPATHLEN 4096
- #else
- #include <unistd.h>
- #include <sys/param.h>
- #include <getopt.h>
- #endif
- #include "generator.h"
- const char *SRPC_VERSION = "0.10.2";
- /* LQ - prototype to determine if the file type is thrift */
- enum
- {
- TYPE_UNKNOWN = -1,
- TYPE_PROTOBUF = 0,
- TYPE_THRIFT = 1,
- };
- static int check_file_idl_type(const char *filename);
- static int parse_origin(int argc, const char *argv[],
- struct GeneratorParams& params,
- int& idl_type);
- #ifndef _WIN32
- static int parse_getopt(int argc, char * const *argv,
- struct GeneratorParams& params,
- int& idl_type);
- #endif
- static int parse_prefix_dir(std::string& file, std::string& dir);
- static int get_idl_type(const char *argv);
- static bool is_root(std::string& file);
- const char *SRPC_GENERATOR_USAGE = "\
- Usage:\n\
- %s [protobuf|thrift] <idl_file> <output_dir>\n\n\
- Available options(linux):\n\
- -f, --idl_file : IDL file name. If multiple files are imported, specify the top one. Will parse recursively.\n\
- -o, --output_dir : Output directory.\n\
- -i, --input_dir : Specify the directory in which to search for imports.\n\
- -s, --skip_skeleton : Skip generating skeleton file. (default: generate)\n\
- -v, --version : Show version.\n\
- -h, --help : Show usage.\n";
- int main(int argc, const char *argv[])
- {
- int idl_type = TYPE_UNKNOWN;
- struct GeneratorParams params;
- #ifndef _WIN32
- if (parse_origin(argc, argv, params, idl_type) == 0)
- {
- if (parse_getopt(argc, (char * const *)argv, params, idl_type) != 0)
- return 0;
- }
- #else
- parse_origin(argc, argv, params, idl_type);
- #endif
- if (params.out_dir == NULL || params.idl_file.empty())
- {
- fprintf(stderr, SRPC_GENERATOR_USAGE, argv[0]);
- return 0;
- }
- if (idl_type == TYPE_UNKNOWN)
- idl_type = check_file_idl_type(params.idl_file.data());
- if (is_root(params.idl_file))
- {
- if (params.input_dir.empty())
- parse_prefix_dir(params.idl_file, params.input_dir);
- else
- {
- fprintf(stderr, "ERROR: input_dir must encompasses the idl_file %s\n",
- params.idl_file.c_str());
- return 0;
- }
- }
- else
- {
- if (params.input_dir.empty() || is_root(params.input_dir) == false)
- {
- char current_dir[MAXPATHLEN] = {};
- getcwd(current_dir, MAXPATHLEN);
- current_dir[strlen(current_dir)] = '/';
- if (params.input_dir.empty())
- params.input_dir = current_dir;
- else
- params.input_dir = current_dir + params.input_dir;
- }
- }
- Generator gen(idl_type == TYPE_THRIFT ? true : false);
- fprintf(stdout, "[Generator Begin]\n");
- gen.generate(params);
- fprintf(stdout, "[Generator Done]\n");
- return 0;
- }
- int parse_origin(int argc, const char *argv[],
- struct GeneratorParams& params, int& idl_type)
- {
- int idl_file_id = 1;
- for (int i = 1; i < argc && i < 4 && argv[i][0] != '-'; i++)
- {
- if (i == 1) // parse [protobuf|thrift]
- {
- idl_type = get_idl_type(argv[1]);
- if (idl_type != TYPE_UNKNOWN)
- {
- idl_file_id++;
- continue;
- }
- }
- if (i == idl_file_id) // parse <idl_file>
- {
- int tmp_type = check_file_idl_type(argv[i]);
- if (tmp_type == TYPE_UNKNOWN)
- {
- fprintf(stderr, "ERROR: Invalid IDL file \"%s\".\n", argv[i]);
- return -1;
- }
- if (idl_type == TYPE_UNKNOWN)
- idl_type = tmp_type;
- params.idl_file = argv[idl_file_id];
- }
- else // parse <output_dir>
- params.out_dir = argv[i];
- }
- return 0;
- }
- #ifndef _WIN32
- int parse_getopt(int argc, char * const *argv,
- struct GeneratorParams& params, int& idl_type)
- {
- int ch;
- static struct option longopts[] = {
- { "version", no_argument, NULL, 'v'},
- { "idl_file", required_argument, NULL, 'f'},
- { "output_dir", required_argument, NULL, 'o'},
- { "input_dir", required_argument, NULL, 'i'},
- { "skip_skeleton", no_argument, NULL, 's'},
- { "help", no_argument, NULL, 'h'}
- };
- while ((ch = getopt_long(argc, argv, "vf:o:i:sh", longopts, NULL)) != -1)
- {
- switch (ch)
- {
- case 'v':
- fprintf(stderr, "srpc_generator version %s\n", SRPC_VERSION);
- return 1;
- case 'f':
- if (!params.idl_file.empty())
- {
- fprintf(stderr, "Error: -i is duplicate with idl_file %s\n",
- params.idl_file.c_str());
- return -1;
- }
- params.idl_file = optarg;
- break;
- case 'o':
- if (params.out_dir != NULL)
- {
- fprintf(stderr, "Error: -o is duplicate with output_dir %s\n",
- params.out_dir);
- return -1;
- }
- params.out_dir = optarg;
- break;
- case 'i':
- params.input_dir = optarg;
- if (params.input_dir.at(params.input_dir.length() - 1) != '/')
- params.input_dir += '/';
- break;
- case 's':
- params.generate_skeleton = false;
- break;
- case 'h':
- break;
- default:
- return 0;
- }
- }
- return 0;
- }
- #endif
- int get_idl_type(const char *type)
- {
- if (strcasecmp(type, "protobuf") == 0)
- return TYPE_PROTOBUF;
- if (strcasecmp(type, "thrift") == 0)
- return TYPE_THRIFT;
- return TYPE_UNKNOWN;
- }
- // idl file will not start with -
- int check_file_idl_type(const char *filename)
- {
- size_t len = strlen(filename);
- if (len > 6 && strcmp(filename + len - 6, ".proto") == 0)
- return TYPE_PROTOBUF;
- else if (len > 7 && strcmp(filename + len - 7, ".thrift") == 0)
- return TYPE_THRIFT;
- return TYPE_UNKNOWN;
- }
- int parse_prefix_dir(std::string& file, std::string& dir)
- {
- auto pos = file.find_last_of('/');
- if (pos == std::string::npos)
- return -1;
- dir = file.substr(0, pos + 1);
- file = file.substr(pos + 1);
- return 0;
- }
- bool is_root(std::string& file)
- {
- if (file[0] == '/' || file[1] == ':')
- return true;
- return false;
- }
|