summaryrefslogtreecommitdiffstats
path: root/otherservice/rpc_library/tool
diff options
context:
space:
mode:
Diffstat (limited to 'otherservice/rpc_library/tool')
-rw-r--r--otherservice/rpc_library/tool/Makefile62
-rw-r--r--otherservice/rpc_library/tool/apidef.cc1104
-rw-r--r--otherservice/rpc_library/tool/apidef.h333
-rw-r--r--otherservice/rpc_library/tool/apidef.l136
-rw-r--r--otherservice/rpc_library/tool/apidef.y615
5 files changed, 2250 insertions, 0 deletions
diff --git a/otherservice/rpc_library/tool/Makefile b/otherservice/rpc_library/tool/Makefile
new file mode 100644
index 00000000..d4d09637
--- /dev/null
+++ b/otherservice/rpc_library/tool/Makefile
@@ -0,0 +1,62 @@
+#
+# @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+#
+# 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.
+#
+
+all: rpc_apidef
+
+clean:
+ rm -rf $(CLEAN_FILES)
+
+YACC := bison
+YFLAGS := -d -t
+LEX := flex
+LFLAGS := -d
+
+CPPFLAGS := -I../library/include -include $(SDKTARGETSYSROOT)/usr/agl/include/agl_types_obsoluted.h
+CFLAGS := -Wall -Wno-unused-function -Wno-unused-variable -include $(SDKTARGETSYSROOT)/usr/agl/include/agl_types_obsoluted.h
+
+rpc_apidef: apidef.tab.o lex.yy.o apidef.o
+ $(CXX) $(CPPFLAGS) -o $@ $^
+
+apidef.tab.o: apidef.tab.h apidef.tab.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $^
+
+lex.yy.o: lex.yy.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $^
+
+apidef.o: apidef.cc
+ $(CXX) $(CPPFLAGS) $(CFLAGS) -c $^
+
+apidef.tab.h apidef.tab.c: apidef.y
+ $(YACC) $(YFLAGS) $<
+
+lex.yy.c: apidef.l apidef.tab.h
+ $(LEX) $(LFLAGS) $<
+
+CLEAN_FILES := rpc_apidef *.o apidef.tab.h apidef.tab.c lex.yy.c
+
+CLEAN_TARGET := clean-all clean-all-sub clean-sub
+INSTALL_TARGET := install-header
+EMPTY_TARGET := install-prog install-data install-lib install-arlib install-shlib
+.PHONY: all install clean $(CLEAN_TARGET) $(INSTALL_TARGET) $(EMPTY_TARGET)
+
+$(CLEAN_TARGET): clean
+
+$(INSTALL_TARGET): install
+
+$(EMPTY_TARGET):
+
+include ../../other_service.mk
+
diff --git a/otherservice/rpc_library/tool/apidef.cc b/otherservice/rpc_library/tool/apidef.cc
new file mode 100644
index 00000000..5a5df1c2
--- /dev/null
+++ b/otherservice/rpc_library/tool/apidef.cc
@@ -0,0 +1,1104 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * 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.
+ */
+
+/**
+ * @file apidef.cc
+ * @brief RPC tools--Main processing(Implementations of APIDef classes)
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+
+#include <other_service/rpc.h>
+
+#include "apidef.h"
+#include "apidef.tab.h"
+
+static APIDef *API_Def;
+
+extern "C" { // C interface functions
+
+void
+ApidefDefineId(const char *id) {
+ if (id != NULL) {
+ if (API_Def == NULL) {
+ API_Def = new APIDef();
+ }
+ API_Def->DefineId(id);
+ }
+}
+
+void
+ApidefAddHeader(const char *filename) {
+ if (filename != NULL) {
+ if (API_Def == NULL) {
+ API_Def = new APIDef();
+ }
+ API_Def->AddHeader(filename);
+ }
+}
+
+int
+ApidefPushFunctionArg(int arg_code, int buffer_bytes, int is_pointer,
+ int is_vararray, int is_array_size,
+ const char *var_type_name, int in_out,
+ const char *var_name) {
+ if (API_Def == NULL) {
+ API_Def = new APIDef();
+ }
+ return API_Def->AddFunctionArg(arg_code, buffer_bytes, is_pointer,
+ is_vararray, is_array_size,
+ var_type_name, in_out, var_name);
+}
+
+void
+ApidefProcessFunction(const char *name) {
+ if (API_Def == NULL) {
+ API_Def = new APIDef();
+ }
+ API_Def->NameFunction(name);
+}
+
+void
+ApidefListFunctions(int with_args) {
+ if (API_Def != NULL) {
+ API_Def->Print(with_args);
+ }
+}
+
+void
+ApidefFreeAllocation(void) {
+ if (API_Def != NULL) {
+ delete API_Def;
+ API_Def = NULL;
+ }
+}
+
+int
+ApidefMakeStubs(void) {
+ if (API_Def != NULL) {
+ API_Def->MakeStubs();
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+} // extern "C"
+
+/*
+ * Retrieving Argument Names Without Decorators
+ */
+void
+Arg::GetUndecolatedName(string& name /* OUT */, int num) {
+ name = "v";
+ if (num > 0) {
+ /* Making Variable Names Sequential Numbers */
+ char num_str[5];
+ sprintf(num_str, "%d", num);
+ name += num_str;
+ } else {
+ /* Use a user-supplied pseudo-variable name */
+ name = m_name;
+ }
+}
+
+int
+Arg::PrintUndecoratedName(fstream& out, int num) {
+ /* Pointer argument */
+ if (m_is_pointer) {
+ out << "*";
+ }
+
+ if (num > 0) {
+ /* Making Variable Names Sequential Numbers */
+ out << "v" << num;
+ } else {
+ /* Use a user-supplied pseudo-variable name */
+ out << m_name;
+ }
+
+ return 0;
+}
+
+/*
+ * Outputs one argument in a function prototype declaration
+ * out: Destination file
+ * num: Handling of Formal Argument Names
+ * 0 :Formal argument name specified in the API definition file
+ * Non-zero: Use "v" + specified number(Examples: v1, v2, ...)
+ */
+int
+Arg::PrintPrototype(fstream& out, int num) {
+ const char *type = TypeCodeString(m_code);
+ if (type == NULL) {
+ type = m_type_name.c_str();
+ }
+ if (type == NULL) {
+ cout << "Internal Error Occurrence!!\n";
+ return 1;
+ }
+
+ /* Const non-output pointers */
+ if ((m_in_out & RPC_OUT_ARG) == 0 && (m_bytes != 0 || m_is_pointer != 0)) {
+ out << "const ";
+ }
+ out << type << " ";
+ if (m_is_pointer && m_bytes == 0) {/* Non-string pointer arguments */
+ out << "*";
+ }
+
+ if (num > 0) {/* Making variable names sequential numbers */
+ out << "v" << num;
+ } else {/* Use a user-supplied pseudo-variable name */
+ out << m_name;
+ }
+
+ /* Variable-length arrays */
+ if (m_is_vararray != 0) {
+ out << "/* VAR_ARRAY */";
+ }
+
+ /* Variable-length arrays length */
+ if (m_is_array_size != 0) {
+ out << "/* VAR_SIZE */";
+ }
+
+ /*
+ * Commenting on OUT/INOUT Arguments
+ * Maximum number of bytes of a string argument added to a comment
+ */
+ if ((m_in_out & RPC_OUT_ARG) != 0 || m_bytes != 0) {
+ out << "/* ";
+ if ((m_in_out & RPC_OUT_ARG) != 0) {
+ if ((m_in_out & RPC_IN_ARG) != 0) {
+ out << "IN";
+ }
+ out << "OUT ";
+ }
+ if (m_bytes) {
+ out << m_bytes << "Byte ";
+ }
+ out << "*/";
+ }
+
+ return 0;
+}
+
+int
+Arg::CreateMarshallArgs(fstream& out, int num) {
+ return CreateMarshallArgs(out, num, (RPC_IN_ARG|RPC_OUT_ARG));
+}
+
+int
+Arg::CreateMarshallArgs(fstream& out, int num, string &array_size_name) {
+ return CreateMarshallArgs(out, num, (RPC_IN_ARG|RPC_OUT_ARG), array_size_name);
+}
+
+int
+Arg::CreateMarshallArgs(fstream& out, int num, int in_out) {
+ string dummy = "";
+ return CreateMarshallArgs(out, num, in_out, dummy);
+}
+
+/*
+ * The arguments to rpc_marshall_args() are generated for each API argument.
+ * for each API argument.
+ * out: Destination file
+ * num: Number given to the variable name of the argument (Examples: 1 for v1)
+ * in_out: Specifying the IN or OUT Attributes
+ * Output only if the argument has the specified attribute
+ */
+int
+Arg::CreateMarshallArgs(fstream& out, int num, int in_out, string &array_size_name) {
+ if ((m_in_out & in_out) != 0) {
+ /*
+ * Collectively passes the argument type, pointer/non-pointer, IN/OUT attribute,
+ * and the maximum number of bytes of the argument type to one integer.
+ */
+ RPC_marshall_flag flag;
+ flag.bits.code = m_code & ((1<<RPC_MARSHALL_FLAG_BITS_CODE)-1);
+ flag.bits.is_vararray = ((array_size_name.size() != 0) ? 1: 0) &
+ ((1<<RPC_MARSHALL_FLAG_BITS_IS_VARARRAY)-1);
+ flag.bits.is_pointer = m_is_pointer & ((1<<RPC_MARSHALL_FLAG_BITS_IS_POINTER)-1);
+ flag.bits.in_out = m_in_out & ((1<<RPC_MARSHALL_FLAG_BITS_IN_OUT)-1);
+ flag.bits.bytes = (UINT16)(m_bytes);
+ char str[11];
+ sprintf(str, "0x%x", htonl(flag.all));
+ out << "\t\t\t" << str;
+
+ /*
+ * Add size of user-defined type to argument
+ */
+ if (m_code == rpc_USER_DEFINED) {
+ if (array_size_name.size() != 0) {
+ out << " + ntohs(sizeof(" << m_type_name << ") * " << array_size_name << ")";
+ } else {
+ out << " + ntohs(sizeof(" << m_type_name << "))";
+ }
+ } else if (array_size_name.size() != 0) {
+ out << " + ntohs(sizeof(" << TypeCodeString(m_code) << ") * " << array_size_name << ")";
+ }
+
+ out << ", v" << num;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+int
+Arg::CreateDemarshallArgs(fstream& out, int deliver_pointer, int num) {
+ return CreateDemarshallArgs(out, deliver_pointer, num, (RPC_IN_ARG|RPC_OUT_ARG));
+}
+
+int
+Arg::CreateDemarshallArgs(fstream& out, int deliver_pointer, int num, string &array_size_name) {
+ return CreateDemarshallArgs(out, deliver_pointer, num, (RPC_IN_ARG|RPC_OUT_ARG), array_size_name);
+}
+
+int
+Arg::CreateDemarshallArgs(fstream& out, int deliver_pointer, int num, int in_out) {
+ string dummy = "";
+ return CreateDemarshallArgs(out, deliver_pointer, num, in_out, dummy);
+}
+
+/*
+ * The arguments to rpc_demarshall_args() are generated for each API argument.
+ * for each API argument.
+ * out: Destination file
+ * deliver_pointer: Passing a Variable Pointer(non-0)
+ * num: Number given to the variable name of the argument (Examples: 1 for v1)
+ * in_out: Specifying the IN or OUT Attributes
+ * Output only if the argument has the specified attribute
+ */
+int
+Arg::CreateDemarshallArgs(fstream& out, int deliver_pointer, int num, int in_out, string &array_size_name) {
+ if ((m_in_out & in_out) != 0) {
+ /*
+ * Collectively passes the argument type, pointer/non-pointer, IN/OUT attribute,
+ * and the maximum number of bytes of the argument type to one integer.
+ */
+ RPC_marshall_flag flag;
+ flag.bits.code = m_code & ((1<<RPC_MARSHALL_FLAG_BITS_CODE)-1);
+ flag.bits.is_vararray = ((array_size_name.size() != 0) ? 1: 0) &
+ ((1<<RPC_MARSHALL_FLAG_BITS_IS_VARARRAY)-1);
+ flag.bits.is_pointer = m_is_pointer & ((1<<RPC_MARSHALL_FLAG_BITS_IS_POINTER)-1);
+ flag.bits.in_out = m_in_out & ((1<<RPC_MARSHALL_FLAG_BITS_IN_OUT)-1);
+ flag.bits.bytes = (UINT16)(m_bytes);
+ char str[11];
+ sprintf(str, "0x%x", htonl(flag.all));
+ out << "\t\t\t" << str;
+
+ /*
+ * Add size of user-defined type to argument
+ */
+ if (m_code == rpc_USER_DEFINED) {
+ out << " + ntohs(sizeof(" << m_type_name << "))";
+ }
+
+ out << ", ";
+ if (deliver_pointer) {
+ /* Pass a pointer */
+ out << "&";
+ }
+ out << "v" << num;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+int
+Function::AppendArg(int code, int bytes, int is_pointer,
+ int is_vararray, int is_array_size,
+ const char *var_type_name, int in_out, const char *var_name) {
+ if (NumOfArgs() >= RPC_MAX_API_ARG_NUM) {
+ cout << "Too many API function arguments.\n";
+ return -1;
+ }
+ Arg *a = new Arg(code, bytes, is_pointer, is_vararray, is_array_size,
+ var_type_name, in_out, var_name);
+ m_args.push_back(*a);
+ delete a;
+ return 0;
+}
+
+/*
+ * Generate prototype declarations for a single API function
+ * out: Destination file
+ */
+int
+Function::PrintPrototype(fstream& out, int server) {
+ int ret = 0;
+
+ const char *return_type
+ = server ? RPC_API_SERVER_RETURN : RPC_API_CLIENT_RETURN;
+#ifdef DBG_ENABLE
+ if ((server) || (!rpc_log_enable)) {
+ out << return_type << " " << m_name << "(";
+ } else {
+ out << return_type << " __" << m_name << "(";
+ }
+#else
+ out << return_type << " " << m_name << "(";
+#endif
+
+ list<Arg>::size_type num_args = m_args.size();
+ if (num_args > 0) {
+ list<Arg>::iterator a;
+ a = m_args.begin();
+ for (list<Arg>::size_type i = 1; i <= num_args; ++i, ++a) {
+ a->PrintPrototype(out);
+#ifdef DBG_ENABLE
+ if ((server) || (!rpc_log_enable)) {
+ if (i != num_args) {
+ out << ", ";
+ }
+ } else {
+ out << ", ";
+ }
+#else
+ if (i != num_args) {
+ out << ", ";
+ }
+#endif
+ }
+ } else {
+#ifdef DBG_ENABLE
+ if ((server) || (!rpc_log_enable)) {
+ out << "void";
+ }
+#else
+ out << "void";
+#endif
+ }
+#ifdef DBG_ENABLE
+ /* Debug information */
+ if ((!server) && (rpc_log_enable)) {
+ out << "const char *filename, const char *funcname, int line ";
+ }
+#endif
+ out << ");\n";
+ return ret;
+}
+
+#ifdef DBG_ENABLE
+int
+Function::PrintMacro(fstream& out) {
+ int ret = 0;
+ out << "#define " << m_name << "(";
+
+ int num_args = m_args.size();
+ if (num_args > 0) {
+ int i;
+ char c;
+ for (i = 1, c = 'a'; i <= num_args; i++, c++) {
+ out << c;
+ if (i != num_args) {
+ out << ", ";
+ }
+ }
+ out << ") \\\n\t";
+
+ /* Entity */
+ out << "__" << m_name << "(";
+ for (i = 1, c = 'a'; i <= num_args; i++, c++) {
+ out << c << ", ";
+ }
+ out << "__FILE__, __func__, __LINE__)\n";
+ } else { /* Without arguments */
+ out << ") " << "__" << m_name << "(__FILE__, __func__, __LINE__)\n";
+ }
+
+ return ret;
+}
+#endif
+
+int
+APIDef::MakeHeaderFiles(int server) {
+ char filename[MAX_FILENAME_LEN+1];
+ sprintf(filename, "%s%s", m_lowerid.c_str(),
+ (server ? SERVER_HEADER_FILE : CLIENT_HEADER_FILE));
+ int ret = 0;
+
+ fstream out(filename, ios::out);
+ if (!out.is_open()) {
+ cout << "ERROR: File " << filename << " Could not open.\n";
+ return 1;
+ }
+ cout << "info: Header file " << filename << " Creating.\n";
+
+ const char *define_str =
+ server ? SERVER_HEADER_DEFINE : CLIENT_HEADER_DEFINE;
+ const char *title = server ? SERVER_HEADER_TITLE : CLIENT_HEADER_TITLE;
+
+ out << "#ifndef _" << m_lowerid << define_str << "\n";
+ out << "#define _" << m_lowerid << define_str << "\n";
+ out << "/*\n";
+ out << " * " << m_id << " " << title << " " << filename << "\n";
+ out << " *\n";
+ out << RPCTOOL_WARNING_STRING << "\n";
+ out << " */\n\n";
+
+ list<string>::iterator i;
+ for (i = m_headers.begin(); i != m_headers.end(); ++i) {
+ out << "#include <" << *i << ">\n";
+ }
+ out << "\n";
+
+ if (server) {
+
+ out << EXTERN_C_START << "\n";
+
+ out << RPC_API_DISPATCH_RETURN << " "
+ << m_id << RPC_API_DISPATCH_FUNC_FULL << ";\n";
+
+ out << "#ifdef RPC_DISPATCH_FUNC\n"
+ << "#undef RPC_DISPATCH_FUNC\n"
+ << "#define RPC_DISPATCH_FUNC " << m_id << RPC_API_DISPATCH_FUNC_NAME
+ << "\n#else /* !RPC_DISPATCH_FUNC */\n"
+ << "#error \"Please include <rpc.h> first!!\"\n"
+ << "#endif /* !RPC_DISPATCH_FUNC */\n\n";
+
+ out << EXTERN_C_END << "\n";
+
+ }
+#ifdef DBG_ENABLE
+ else if (rpc_log_enable) {
+ /* DEBUG INFORMATION EMBEDDED MACRO */
+ out << "/* Debug information embedded macro definition */\n";
+ list<Function>::iterator f;
+ for (f = m_funcs.begin(); f != m_funcs.end(); ++f) {
+ if (f->PrintMacro(out) != 0) {
+ ret = 1;
+ break;
+ }
+ }
+ out << "\n";
+ }
+#endif
+
+ out << EXTERN_C_START << "\n";
+
+ out << "/* API definitions */\n";
+ list<Function>::iterator f;
+ for (f = m_funcs.begin(); f != m_funcs.end(); ++f) {
+ if (f->PrintPrototype(out, server) != 0) {
+ ret = 1;
+ break;
+ }
+ }
+ out << "\n";
+
+ out << EXTERN_C_END << "\n";
+
+ out << "#endif /* _" << m_lowerid << define_str << " */\n";
+ out.close();
+ return ret;
+}
+
+int
+Function::PrintServerStub(fstream& out) {
+ int num_args = NumOfArgs();
+
+ out << "\tcase " << RPC_API_NUM_PREFIX << m_name << ": {\n";
+
+ list<Arg>::iterator a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ const char *type = TypeCodeString(a->Code());
+ if (type == NULL) {
+ type = (a->TypeName()).c_str();
+ }
+ if (type == NULL) {
+ return 1;
+ }
+ out << "\t\t" << type << " ";
+ if (a->Bytes() > 0 || a->IsPointer()) {/* Pointer-passing argument */
+ if (a->Bytes() > 0) {
+ out << "v" << i << " = NULL;\n";
+ } else if (a->IsPointer()) {
+ out << "*v" << i << " = NULL;\n";
+ }
+ } else {/* Pass-by-value argument */
+ out << "v" << i << ";\n";
+ }
+ }
+ if (num_args > 0) {
+ out << "\t\tif (" << RPC_DEMARSHALL_FUNCTION
+ << " (args_string, args_size, 1, " << num_args << ",\n";
+ /* In the STUB of servers for all pre-call demarshall */
+ /* Passing Pointers to Local Variables in Server STUB */
+ /* Pointer/ Buffer will alloc the required space in demarshall_arguments() */
+
+ a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (a->IsVararray() != 0) { /* Variable-length arrays */
+ a->CreateDemarshallArgs(out, 1, i, m_array_size_name);
+ } else {
+ a->CreateDemarshallArgs(out, 1, i);
+ }
+ if (i < num_args) {
+ out << ",";
+ }
+ out << "\n";
+ }
+ out << "\t\t ) < 0) {\n";
+ out << "\t\t\tgoto _" << m_name << "_Error;\n";
+ out << "\t\t}\n";
+ }
+
+ out << "\t\tresult = " << m_name << "(";
+ for (int i = 1; i <= num_args; i++) {
+ out << "v" << i;
+ if (i < num_args) {
+ out << ", ";
+ }
+ }
+ out << ");\n";
+
+ int to_process = NumOfInOutArgs(RPC_OUT_ARG);
+ if (to_process > 0) {
+ /* Only OUT-arguments marshall after the server stub is called. */
+ out << "\t\t/*if (result == RPC_OK) {*/\n";
+ out << "\t\t *ret_string = " << RPC_MARSHALL_FUNCTION
+ << "(ret_size, 0, " << to_process << ",\n";
+
+ a = m_args.begin();
+ int processed = 0;
+ int ret;
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (a->IsVararray() != 0) { /* Variable-length arrays */
+ ret = a->CreateMarshallArgs(out, i, RPC_OUT_ARG, m_array_size_name);
+ } else {
+ ret = a->CreateMarshallArgs(out, i, RPC_OUT_ARG);
+ }
+ if (ret) {
+ processed++;
+ if (processed < to_process) {
+ out << ",";
+ }
+ out << "\n";
+ }
+ }
+ out << "\t\t );\n"
+ << "\t\t if (*ret_string == NULL) {\n"
+ << "\t\t\tresult = " << RPC_API_SERVER_ERROR << ";\n"
+ << "\t\t }\n"
+ << "\t\t/*}*/\n";
+ }
+
+ if (num_args > 0) {
+ out << "_" << m_name << "_Error:\n";
+ }
+ int num_pointer_args = 0;
+ a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (a->Bytes() || a->IsPointer()) {
+ num_pointer_args++;
+ }
+ }
+ if (num_pointer_args > 0) {
+ int processed = 0;
+ out << "\t\t" << RPC_MARSHALL_FREE_FUNCTION
+ << "(" << num_pointer_args << ", ";
+ a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (a->Bytes() || a->IsPointer()) {
+ out << "v" << i;
+ processed++;
+ if (processed < num_pointer_args) {
+ out << ", ";
+ }
+ }
+ }
+ out << ");\n";
+ }
+ out << "\t\tbreak;\n\t}\n";
+ return 0;
+}
+
+int
+APIDef::MakeServerStub(void) {
+ char filename[MAX_FILENAME_LEN+1];
+ sprintf(filename, "%s%s", m_lowerid.c_str(), SERVER_STUB_FILE);
+ int ret = 0;
+
+ fstream out(filename, ios::out);
+ if (!out.is_open()) {
+ cout << "File " << filename << " Could not open.\n";
+ return 1;
+ }
+ cout << "info: Stub file " << filename << " Creating.\n";
+
+ const char *title = SERVER_STUB_TITLE;
+
+ out << "/*\n";
+ out << " * " << m_id << " " << title << " " << filename << "\n";
+ out << " *\n";
+ out << RPCTOOL_WARNING_STRING << "\n";
+ out << " */\n";
+ out << "#include <" RPC_GLOBAL_HEADER_FILE << ">\n";
+ out << "#include \"" << m_lowerid << SERVER_HEADER_FILE << "\"\n";
+ out << "#include <netinet/in.h> /* for ntohs() */\n\n";
+
+ int api_num = 1;
+ list<Function>::iterator f;
+
+ for (f = m_funcs.begin(); f != m_funcs.end(); ++f, ++api_num) {
+ if (api_num >= (1<<16)) {
+ cout << "Too many API functions.(Up to 65535)\n";
+ return 1;
+ }
+ out << "#define " << RPC_API_NUM_PREFIX << f->Name()
+ << " " << api_num << "\n";
+ }
+ out << "\n";
+
+ out << "RPC_Result\n";
+ out << m_id << RPC_API_DISPATCH_FUNC_FULL << "\n";
+ out << "{\n";
+ out << "\tRPC_Result result = " << RPC_API_SERVER_ERROR << ";\n";
+ out << "\t*ret_string = NULL;\n";
+ out << "\tswitch(api_num) {\n";
+
+ for (f = m_funcs.begin(); f != m_funcs.end(); ++f) {
+ if (f->PrintServerStub(out) != 0) {
+ ret = 1;
+ break;
+ }
+ }
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ out << "\tdefault:\n\t\tbreak;\n\t}\n";
+ out << "\treturn result;\n";
+ out << "}\n";
+
+ return ret;
+}
+
+int
+Function::PrintClientStub(const char *moduleid, fstream& out) {
+ int ret = 0;
+
+ list<Arg>::iterator a;
+ /* Function Names and Arguments */
+ out << RPC_API_CLIENT_RETURN << "\n";
+#ifdef DBG_ENABLE
+ if (rpc_log_enable) {
+ out << "__" << m_name << "(";
+ } else {
+ out << m_name << "(";
+ }
+#else
+ out << m_name << "(";
+#endif
+ int num_args = (int)(m_args.size());
+ if (num_args > 0) {
+ a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (a->PrintPrototype(out, i)) {
+ return 1;
+ }
+#ifdef DBG_ENABLE
+ if (rpc_log_enable) {
+ out << ", ";
+ } else {
+ if (i < num_args) {
+ out << ", ";
+ }
+ }
+#else
+ if (i < num_args) {
+ out << ", ";
+ }
+#endif
+ }
+ } else {
+#ifndef DBG_ENABLE
+ out << "void";
+#else
+ if (!rpc_log_enable) {
+ out << "void";
+ }
+#endif
+ }
+#ifdef DBG_ENABLE
+ if (rpc_log_enable) {
+ out << "const char *filename, const char *funcname, int line ";
+ }
+#endif
+ out << ")\n";
+
+ out << "{\n";
+
+ /* Contents of stub functions */
+
+ /* If the argument is present and the variable-length array does not exist */
+ if ((num_args > 0) && (m_array_size_pos == 0)) {
+ int is_exist_mytype = 0;
+ /* Restricted specifications */
+ out << "#ifdef RPC_STATIC_ASSERT\n";
+ out << "\tchar RPC_TOTAL_ARGSIZE_ERROR_in_" << m_name << "[\n";
+ out << "\t(((";
+ a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (i > 1) {
+ out << " + ";
+ }
+ out << "sizeof(";
+ a->PrintUndecoratedName(out, i);
+ out << ")";
+ /* For user types */
+ if ((!is_exist_mytype) && (NULL == TypeCodeString(a->Code()))) {
+ is_exist_mytype = 1;
+ }
+ }
+ out << ") > RPC_MAX_API_ARG_TOTAL_SIZE) ? -1: 1)\n";
+ out << "\t]__attribute__((unused));\n";
+
+ /* Have a user type */
+ if (is_exist_mytype) {
+ char c[3];
+ a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (NULL == TypeCodeString(a->Code())) {
+ sprintf(c, "%d", i);
+ out << "\tchar RPC_ARGSIZE_ERROR_in_" << m_name << "_arg" << c;
+ out << "[\n\t(sizeof(";
+ a->PrintUndecoratedName(out, i);
+ out << ") > RPC_MAX_API_ARG_SIZE) ? -1: 1\n";
+ out << "\t]__attribute__((unused));\n";
+ }
+ }
+ }
+
+ out << "#endif /* RPC_STATIC_ASSERT */\n";
+
+ }
+
+ out << "\tRPC_Result result = " << RPC_API_CLIENT_ERROR << ";\n";
+ out << "\tunsigned int args_size = 0, ret_size;\n";
+ out << "\tchar retcode[9];\n";
+
+ if (num_args > 0) {
+ /* Advance preparation==Marshalling of arguments */
+ out << "\tchar *args_string = " << RPC_MARSHALL_FUNCTION
+ << "(&args_size, 1, " << num_args << ",\n";
+ /* In the clients STUB for all pre-call marshall */
+ a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (a->IsVararray() != 0) { /* Variable-length arrays */
+ a->CreateMarshallArgs(out, i, m_array_size_name);
+ } else {
+ a->CreateMarshallArgs(out, i);
+ }
+ if (i < num_args) {
+ out << ",";
+ }
+ out << "\n";
+ }
+ out << "\t);\n";
+ out << "\tif (args_string == NULL) {\n"
+ << "\t\tgoto _" << m_name << "_Error;\n\t}\n";
+ } else {
+ out << "\tchar *args_string = NULL;\n";
+ }
+
+#ifdef DBG_ENABLE
+ if (rpc_log_enable) {
+ out << "\tif (" << moduleid << "_record_dbg_log(filename, funcname, line, \"";
+ out << m_name << "\") != 0) {\n";
+ out << "\t\tgoto _" << m_name << "_Error;\n\t}\n";
+ }
+#endif
+
+ /* RPC API call */
+ out << "\tchar *ret_string = NULL; /* pgr0431 */\n";
+#ifdef RPC_STRING_ID
+ out << "\tresult=RPC_API_call(\"" << moduleid << "\", ";
+#else
+ out << "\tresult=RPC_API_call(" << moduleid << "_RPC_ID, ";
+#endif
+ out << RPC_API_NUM_PREFIX << m_name;
+ out << ", args_string, args_size, &ret_string, &ret_size);\n";
+
+ // 2007.08.25 To avoid over run within the sscanf
+ // Locally copies strings needed for determining return values and uses strtol instead of sscanf
+ // (Since there is no guarantee that the byte sequence to be grabbed by communication is 0-terminated)
+ out << "\n"
+ << "\tif (result == RPC_OK && ret_string != NULL) {\n"
+ << "\t strncpy(retcode, ret_string, 8);\n"
+ << "\t retcode[8] = '\\0';\n"
+ << "\t result = (RPC_Result)strtoul(retcode, NULL, 16);\n";
+
+ /* Post-processing==Arguments de-marshalling, free() */
+ int num_of_out_args = NumOfInOutArgs(RPC_OUT_ARG);
+ if (num_of_out_args > 0) {
+ out << "\t if (" << RPC_DEMARSHALL_FUNCTION
+ << "(ret_string + RPC_RETCODE_LEN, ret_size - RPC_RETCODE_LEN, 0, "
+ << num_of_out_args << ",\n";
+
+ a = m_args.begin();
+ int processed = 0;
+ int ret;
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ if (a->IsVararray() != 0) { /* Variable-length arrays */
+ ret = a->CreateDemarshallArgs(out, 0, i, RPC_OUT_ARG, m_array_size_name);
+ } else {
+ ret = a->CreateDemarshallArgs(out, 0, i, RPC_OUT_ARG);
+ }
+ if (ret) {
+ processed++;
+ if (processed < num_of_out_args) {
+ out << ",";
+ }
+ out << "\n";
+ }
+ }
+ out << "\t ) < 0) {\n"
+ << "\t\tresult = " << RPC_API_CLIENT_ERROR << ";\n"
+ << "\t }\n";
+ }
+
+ out << "\t} else {\n\t //result = " << RPC_API_CLIENT_ERROR << ";\n"
+ << "\t}\n";
+
+ out << "\t" << RPC_RETURN_FREE_FUNCTION << "(ret_string);\n";
+ out << "\t" << RPC_MARSHALL_FREE_FUNCTION << "(1, args_string);\n";
+
+ /* END, RETURN */
+#ifndef DBG_ENABLE
+ if (num_args)
+#else
+ if ((num_args)||(rpc_log_enable))
+#endif
+ {
+ out << "_" << m_name << "_Error:\n";
+ }
+
+ out << "\treturn result;\n}\n";
+
+ return ret;
+}
+
+int
+APIDef::MakeClientStub(void) {
+ char filename[MAX_FILENAME_LEN+1];
+ sprintf(filename, "%s%s", m_lowerid.c_str(), CLIENT_STUB_FILE);
+ int ret = 0;
+
+ fstream out(filename, ios::out);
+ if (!out.is_open()) {
+ cout << "File " << filename << " Could not open.\n";
+ return 1;
+ }
+ cout << "info: Stub file " << filename << " Creating.\n";
+
+ const char *title = CLIENT_STUB_TITLE;
+
+ out << "/*\n";
+ out << " * " << m_id << " " << title << " " << filename << "\n";
+ out << " *\n";
+ out << RPCTOOL_WARNING_STRING << "\n";
+ out << " */\n";
+ out << "#include <" RPC_GLOBAL_HEADER_FILE << ">\n";
+ out << "#include <" << m_lowerid << CLIENT_HEADER_FILE << ">\n\n";
+ out << "#include <stdio.h> /* for sscanf() */\n";
+ out << "#include <stdlib.h> /* for getenv() */\n";
+ out << "#include <string.h> /* for strncpy() */\n";
+ out << "#include <netinet/in.h> /* for ntohs() */\n\n";
+
+ int api_num = 1;
+ list<Function>::iterator f;
+ for (f = m_funcs.begin(); f != m_funcs.end(); ++f, ++api_num) {
+ if (api_num >= (1<<16)) {
+ cout << "Too many API functions.(Up to 65535)\n";
+ return 1;
+ }
+ out << "#define " << RPC_API_NUM_PREFIX << f->Name()
+ << " " << api_num << "\n";
+ }
+ out << "\n";
+
+ /* Specification Restriction Debug Constants */
+ out << "/*#define RPC_STATIC_ASSERT*/\n";
+ out << "\n";
+
+#ifdef DBG_ENABLE
+ if (rpc_log_enable) {
+ int m_id_work_cnt;
+ string m_id_work = m_id;
+ for (m_id_work_cnt = 0; m_id_work_cnt < m_id_work.length(); m_id_work_cnt++) {
+ m_id_work[m_id_work_cnt] = toupper(m_id_work[m_id_work_cnt]);
+ }
+ out << "int\n" << m_id << "_record_dbg_log(const char *filename, " <<
+ "const char *funcname, int line, const char *apiname)\n";
+ out << "{\n\t";
+ out << "if (getenv(\"" << m_id_work << "_RPC_LOG\") != NULL) {\n\t\t";
+ out << "return RPC_record_dbg_log(filename, funcname, line, apiname);\n\t";
+ out << "}\n\t";
+ out << "return 0;\n";
+ out << "}\n\n";
+ }
+#endif
+
+ /* API definitions */
+ for (f = m_funcs.begin(); f != m_funcs.end(); ++f) {
+ if (f->PrintClientStub(m_id.c_str(), out) != 0) {
+ ret = 1;
+ break;
+ }
+ }
+ return ret;
+}
+
+int
+Arg::IsArraySize(void) {
+ if (m_is_array_size != 0) {
+ if (IsTypeCodeNumeric(m_code) == 1) {
+ return 1;
+ } else {
+ cout << "Variable-length array length specification variables must be integers.\n";
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+Function::CheckFuncArraySize(void) {
+ int num_args = (int)(m_args.size());
+ list<Arg>::iterator a;
+ a = m_args.begin();
+ for (int i = 1; i <= num_args; ++i, ++a) {
+ int ret = a->IsArraySize();
+ if (ret > 0) {
+ if (m_array_size_pos != 0)
+ {
+ cout << "Two or more variable array length specification arguments exist.\n";
+ return 1;
+ }
+ m_array_size_pos = i;
+ a->GetUndecolatedName(m_array_size_name, i);
+ } else if (ret < 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+APIDef::CheckAllArraySize(void) {
+ list<Function>::iterator f;
+ for (f = m_funcs.begin(); f != m_funcs.end(); ++f) {
+ if (f->CheckFuncArraySize() != 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+APIDef::MakeStubs(void) {
+ if (m_id.size() == 0) {
+ cout << "The module name is not specified.\n";
+ return 1;
+ }
+
+ if (m_id.size() > MAX_FILENAME_LEN - strlen(SERVER_STUB_FILE)) {
+ cout << "The module name is too long.\n";
+ return 1;
+ }
+
+ /* Pre-examine the ARRAYSIZE specification */
+ //cout << "<check_all_array_size>\n";
+ if (CheckAllArraySize() != 0) {
+ return 1;
+ }
+
+ //cout << "<MakeHeaderFiles(0)>\n";
+ if (MakeHeaderFiles(1) != 0) {
+ return 1;
+ }
+
+ //cout << "<MakeHeaderFiles(1)>\n";
+ if (MakeHeaderFiles(0) != 0) {
+ return 1;
+ }
+
+ if (MakeServerStub() != 0) {
+ return 1;
+ }
+
+ if (MakeClientStub() != 0) {
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+Arg::Print(void) {
+ cout << "\t";
+ if (m_name.size() > 0) {
+ cout << "Variable name=" << m_name << " ";
+ }
+ cout << "Type=" << TypeCodeString(m_code) << "In bytes=" << m_bytes << " ";
+ if (m_is_pointer) {
+ cout << "Pointer ";
+ }
+ if ((m_in_out & RPC_OUT_ARG) != 0) {
+ cout << "Output ";
+ }
+ cout << "\n";
+}
+
+void
+Function::Print(int with_args) {
+ printf("Function name=%s\n", m_name.c_str());
+ if (with_args) {
+ list<Arg>::iterator a;
+ for (a = m_args.begin(); a != m_args.end(); ++a) {
+ a->Print();
+ }
+ }
+}
+
+void
+APIDef::Print(int with_args) {
+ list<Function>::iterator f;
+ for (f = m_funcs.begin(); f != m_funcs.end(); ++f) {
+ f->Print(with_args);
+ }
+}
+
+void
+APIDef::IdTolower(void) {
+ char *lower = new char[m_id.size() + 1];
+ strcpy(lower, m_id.c_str());
+ char *p;
+ for (p = lower; *p; p++) {
+ *p = (char)(tolower(*p));
+ }
+ m_lowerid = lower;
+ delete[] lower;
+}
diff --git a/otherservice/rpc_library/tool/apidef.h b/otherservice/rpc_library/tool/apidef.h
new file mode 100644
index 00000000..a73fc49c
--- /dev/null
+++ b/otherservice/rpc_library/tool/apidef.h
@@ -0,0 +1,333 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * 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.
+ */
+
+/**
+ * @file apidef.h
+ * @brief RPC tools--Function/macro definitions and APIDef class definitions
+ */
+/** @addtogroup RPCtool
+ *
+ * @brief Using the RPC Tool (rpc_apidef)
+ *
+ * rpc_apidef [CPP option...] API definition file name
+ *
+ * - CPP option
+ * The RPC tool calls the C preprocessor (CPP) internally
+ * for processing comments and #if directives.
+ * Here, you can specify options to be given to the CPP, such as symbol definitions
+ * for conditional branch descriptions in the API definition file.
+ * - API definition file name
+ * Pathname to the API definition file.
+ * The file name must be thread ID + ".api".
+ *
+ * The output file is as follows.
+ * "*" is a lowercase version of the API definition file name preceding ".api".
+ * - *_api.h(Client header files)
+ * - *_api_stub.c(Client stub file)
+ * - *_srvr.h(Server header file)
+ * - *_srvr_stub.c(Server stub file)
+ *
+ * Examples:
+ * - Examples1: rpc_apidef -DTEST XXX.api
+ * - Examples2: rpc_apidef XXX.api
+ * - => Xxx_api.h, xxx_api_stub.c, ... To the output
+ */
+#ifndef RPC_LIBRARY_TOOL_APIDEF_H_
+#define RPC_LIBRARY_TOOL_APIDEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef DBG_ENABLE
+extern char rpc_log_enable;
+#endif
+
+/* C++ to C I/F functions */
+const char *TypeCodeString(const int code);
+int IsTypeCodeNumeric(const int code);
+
+/*
+ * C to C++ I/F functions (APIDef class)
+ */
+void ApidefDefineId(const char *id);
+void ApidefAddHeader(const char *filename);
+int ApidefPushFunctionArg(int arg_code, int buffer_bytes, int is_pointer,
+ int is_vararray, int is_array_size,
+ const char *var_type_name, int in_out,
+ const char *var_name);
+void ApidefProcessFunction(const char *funcname);
+void ApidefListFunctions(int with_args);
+void ApidefFreeAllocation(void);
+int ApidefMakeStubs(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#define RPC_IN_ARG 0x01
+#define RPC_OUT_ARG 0x02
+#define RPC_INOUT_ARG (RPC_IN_ARG|RPC_OUT_ARG)
+
+#define MAX_FILENAME_LEN 63
+#define SERVER_HEADER_FILE "_srvr.h"
+#define CLIENT_HEADER_FILE "_api.h"
+#define SERVER_STUB_FILE "_srvr_stub.c"
+#define CLIENT_STUB_FILE "_api_stub.c"
+#define SERVER_HEADER_DEFINE "_srvr_h_"
+#define CLIENT_HEADER_DEFINE "_api_h_"
+
+#define SERVER_HEADER_TITLE "Server header files"
+#define CLIENT_HEADER_TITLE "Client header files"
+#define SERVER_STUB_TITLE "Server stub file"
+#define CLIENT_STUB_TITLE "Client stub file"
+
+#define RPC_MARSHALL_FUNCTION "RPC_marshall_arguments"
+#define RPC_DEMARSHALL_FUNCTION "RPC_demarshall_arguments"
+#define RPC_MARSHALL_FREE_FUNCTION "RPC_marshall_free"
+#define RPC_RETURN_FREE_FUNCTION "RPC_free_return_string"
+
+#define RPC_API_SERVER_RETURN "RPC_Result"
+#define RPC_API_SERVER_ERROR "RPC_ERR_Fatal"
+#define RPC_API_CLIENT_RETURN "RPC_Result"
+#define RPC_API_CLIENT_ERROR "RPC_ERR_Fatal"
+#define RPC_API_DISPATCH_TYPE "RPC_dispatch_func_t"
+#define RPC_API_DISPATCH_RETURN "RPC_Result"
+#define RPC_API_DISPATCH_FUNC_FULL "_API_dispatch(UINT16 api_num, const char *args_string, unsigned int args_size, char **ret_string, unsigned int *ret_size)" // NOLINT (readability/nolint)
+#define RPC_API_DISPATCH_FUNC_NAME "_API_dispatch"
+#define RPC_API_NUM_PREFIX "RPC_API_NUM_"
+#define RPC_GLOBAL_HEADER_FILE "other_service/rpc.h"
+
+#define RPCTOOL_WARNING_STRING \
+" * The file created by the RPC tool.This file should not be edited."
+
+#define EXTERN_C_START \
+"#ifdef __cplusplus\n" \
+"extern \"C\" {\n" \
+"#endif\n"
+
+#define EXTERN_C_END \
+"#ifdef __cplusplus\n" \
+"}\n" \
+"#endif /* __cplusplus */\n"
+
+#ifdef __cplusplus
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <list>
+
+using namespace std; // NOLINT (readability/nolint)
+
+/** @ingroup RPCtool
+ * @class Arg
+ * @brief Class that stores and processes the arguments of functions read from the API definition file
+ */
+class Arg {
+ protected:
+ int m_code;
+ int m_bytes;
+ int m_is_pointer;
+ int m_in_out; /* Bit OR of _IN_ARG and _OUT_ARG */
+ int m_is_vararray;
+ int m_is_array_size;
+ string m_type_name;
+ string m_name;
+
+ public:
+ Arg() {
+ m_code = m_bytes = m_is_pointer = m_in_out = m_is_vararray = m_is_array_size = 0;
+ }
+ Arg(int code, int bytes, int is_pointer,
+ int is_vararray, int is_array_size,
+ const char *type_name, int in_out,
+ const char *var_name) {
+ m_code = code;
+ m_bytes = bytes;
+ m_is_pointer = is_pointer;
+ m_is_vararray = is_vararray;
+ m_is_array_size = is_array_size;
+ m_in_out = in_out;
+ if (type_name) {
+ m_type_name = type_name;
+ }
+ if (var_name) {
+ m_name = var_name;
+ }
+ }
+ ~Arg() {}
+
+ int Code(void) { return m_code; }
+ int Bytes(void) { return m_bytes; }
+ int IsPointer(void) { return m_is_pointer; }
+ int InOut(void) { return m_in_out; }
+ string& TypeName(void) { return m_type_name; }
+ void GetUndecolatedName(string& name, int num); // NOLINT (readability/nolint)
+
+ int PrintUndecoratedName(fstream& out, int num);
+ int PrintPrototype(fstream& out, int num);
+ int PrintPrototype(fstream& out) { return PrintPrototype(out, 0); }
+
+ int CreateMarshallArgs(fstream& out, int num);
+ int CreateMarshallArgs(fstream& out, int num, string &array_size_name); // NOLINT (readability/nolint)
+ int CreateMarshallArgs(fstream& out, int num, int in_out);
+ int CreateMarshallArgs(fstream& out, int num, int in_out, string &array_size_name); // NOLINT (readability/nolint)
+ int CreateDemarshallArgs(fstream& out, int deliver_pointer, int num);
+ int CreateDemarshallArgs(fstream& out, int deliver_pointer, int num, string &array_size_name); // NOLINT (readability/nolint)
+ int CreateDemarshallArgs(fstream& out, int deliver_pointer, int num, int in_out);
+ int CreateDemarshallArgs(fstream& out, int deliver_pointer, int num, int in_out, string &array_size_name); // NOLINT (readability/nolint)
+
+ int IsVararray(void) { return m_is_vararray; }
+ int IsArraySize(void);
+ void Print(void);
+};
+
+/** @ingroup RPCtool
+ * @class Function
+ * @brief Class that stores and processes function definitions read from the API definition file
+ */
+class Function {
+ protected:
+ string m_name;
+ list<Arg> m_args;
+ int m_array_size_pos;
+ string m_array_size_name;
+
+ public:
+ Function():m_array_size_name("") { m_array_size_pos = 0; }
+ ~Function() {
+ list<Arg>::size_type size = m_args.size();
+ for (list<Arg>::size_type i = 0 ; i < size ; i++) {
+ m_args.begin();
+ m_args.pop_front();
+ }
+ }
+
+ const char *Name(void) { return m_name.c_str(); }
+ void SetName(const char *funcname) {
+ m_name = funcname;
+ }
+
+ int NumOfArgs(void) {
+ return (int)(m_args.size()); // NOLINT (readability/nolint)
+ }
+ int NumOfInOutArgs(int in_out) {
+ int count = 0;
+ list<Arg>::iterator a;
+ for (a = m_args.begin(); a != m_args.end(); ++a) {
+ if ((a->InOut() & in_out) != 0) {
+ ++count;
+ }
+ }
+ return count;
+ }
+
+ int AppendArg(int code, int bytes, int is_pointer,
+ int is_vararray, int is_array_size,
+ const char *var_type_name, int in_out, const char *var_name);
+
+ int PrintPrototype(fstream& out);
+ int PrintPrototype(fstream& out, int server);
+#ifdef DBG_ENABLE
+ int PrintMacro(fstream& out);
+#endif
+
+ int PrintServerStub(fstream& out);
+ int PrintClientStub(const char *moduleid, fstream& out);
+
+ int CheckFuncArraySize(void);
+ void Print(int with_args);
+};
+
+/** @ingroup RPCtool
+ * @class APIDef
+ * @brief Class that stores and processes the result of reading the API definition file
+ */
+class APIDef {
+ protected:
+ list<Function> m_funcs;
+ Function *m_work;
+ string m_id;
+ string m_lowerid;
+ list<string> m_headers;
+
+ public:
+ APIDef() { m_work = 0; }
+ ~APIDef() {
+ list<Function>::size_type size = m_funcs.size();
+ for (list<Function>::size_type i = 0; i < size; i++) {
+ m_funcs.begin();
+ m_funcs.pop_front();
+ }
+ if (m_work != NULL) {
+ delete m_work;
+ }
+ size = m_headers.size();
+ for (list<Function>::size_type i = 0; i < size; i++) {
+ m_headers.begin();
+ m_headers.pop_front();
+ }
+ }
+
+ void IdTolower(void);
+ void DefineId(const char *id) {
+ m_id = id;
+ IdTolower();
+ }
+ void AddHeader(const char *filename) {
+ string str = filename;
+ m_headers.push_back(str);
+ }
+
+ int AddFunctionArg(int arg_code, int buffer_bytes, int is_pointer,
+ int is_vararray, int is_array_size,
+ const char *var_type_name, int in_out,
+ const char *var_name) {
+ if (m_work == NULL) {
+ m_work = new Function();
+ }
+ return m_work->AppendArg(arg_code, buffer_bytes, is_pointer,
+ is_vararray, is_array_size,
+ var_type_name, in_out, var_name);
+ }
+ void NameFunction(const char *funcname) {
+ if (m_work == NULL) {
+ m_work = new Function();
+ }
+ m_work->SetName(funcname);
+
+ AppendFunction(m_work);
+ delete m_work;
+ m_work = NULL;
+ }
+
+ void AppendFunction(Function *pfunc) {
+ m_funcs.push_back(*pfunc);
+ }
+
+ int CheckAllArraySize(void);
+
+ int MakeStubs(void);
+ void Print(int with_args);
+
+ private:
+ int MakeHeaderFiles(int server);
+ int MakeServerStub(void);
+ int MakeClientStub(void);
+};
+#endif /* __cplusplus */
+
+#endif // RPC_LIBRARY_TOOL_APIDEF_H_
diff --git a/otherservice/rpc_library/tool/apidef.l b/otherservice/rpc_library/tool/apidef.l
new file mode 100644
index 00000000..c2f246a2
--- /dev/null
+++ b/otherservice/rpc_library/tool/apidef.l
@@ -0,0 +1,136 @@
+/**
+ * @file apidef.l
+ * @brief RPC tools--Defining lexical analysis rules for API definition files
+ *
+ */
+/** @ingroup RPCtool
+ * Defining Lexical Analysis Rules for Use with RPC Tools (apidef)
+ */
+%{
+#include <string.h>
+#include <stdlib.h>
+#include "apidef.tab.h"
+%}
+
+ALPHA [A-Za-z_]
+ALPHANUM [0-9\-A-Za-z_]
+ALPHANUMDOT [0-9.\-A-Za-z_/]
+
+%x include
+%s apidef
+%x str_num
+
+%%
+INCLUDE { BEGIN(include); return rpc_INCLUDE; }
+<include>\< { return '<'; }
+<include>{ALPHANUMDOT}+ {
+ yylval.strval = malloc(strlen(yytext)+1);
+ strcpy(yylval.strval, yytext);
+ return rpc_NAME_DOT;
+ }
+<include>\> { BEGIN(INITIAL); return '>'; }
+<include>. /* ignore */
+
+RPC_Result { BEGIN(apidef); return RPC_RESULT; }
+
+<apidef>STRING/[0-9]+ { BEGIN(str_num);
+ yylval.ival = rpc_STRING; return rpc_STRING; }
+<str_num>[0-9]+ {
+ BEGIN(apidef);
+ sscanf(yytext, "%d", &yylval.ival);
+ return rpc_NUM;
+ }
+<str_num>. /* ignore */
+
+<apidef>{
+char { yylval.ival = rpc_CHAR; return rpc_CHAR; }
+int { yylval.ival = rpc_INT; return rpc_INT; }
+signed[ \t\n]+int { yylval.ival = rpc_SINT; return rpc_SINT; }
+unsigned[ \t\n]+int { yylval.ival = rpc_UINT; return rpc_UINT; }
+INT8 { yylval.ival = rpc_INT8; return rpc_INT8; }
+INT16 { yylval.ival = rpc_INT16; return rpc_INT16; }
+INT32 { yylval.ival = rpc_INT32; return rpc_INT32; }
+INT64 { yylval.ival = rpc_INT64; return rpc_INT64; }
+UINT8 { yylval.ival = rpc_UINT8; return rpc_UINT8; }
+UINT16 { yylval.ival = rpc_UINT16; return rpc_UINT16; }
+UINT32 { yylval.ival = rpc_UINT32; return rpc_UINT32; }
+UINT64 { yylval.ival = rpc_UINT64; return rpc_UINT64; }
+float { yylval.ival = rpc_FLOAT; return rpc_FLOAT; }
+double { yylval.ival = rpc_DOUBLE; return rpc_DOUBLE; }
+void { yylval.ival = rpc_VOID; return rpc_VOID; }
+IN {
+ fprintf(stderr,
+ "Specification change: IN Pointer argument needs to be prefixed \"const\" instead of \"IN\".\n"
+ );
+ return rpc_UNKNOWN;
+ }
+OUT {
+ fprintf(stderr,
+ "Specification change: OUT argument no longer needs to be prefixed with \"OUT\".\n"
+ );
+ /* ignore */
+ }
+INOUT { yylval.ival = rpc_INOUT; return rpc_INOUT; }
+const { yylval.ival = rpc_CONST; return rpc_CONST; }
+VARARRAY { yylval.ival = rpc_VARARRAY; return rpc_VARARRAY; }
+ARRAYSIZE { yylval.ival = rpc_ARRAYSIZE; return rpc_ARRAYSIZE; }
+
+{ALPHA}+{ALPHANUM}* {
+ yylval.strval = malloc(strlen(yytext)+1);
+ strcpy(yylval.strval, yytext);
+ return rpc_NAME;
+ }
+
+\( { return '('; }
+\) { return ')'; }
+\* { return '*'; }
+, { return ','; }
+\; { BEGIN(INITIAL); return ';'; }
+
+} /* end of <apidef> */
+
+#.*\n /* ignore CPP directives */
+
+{ALPHANUMDOT}+ {
+ fprintf(stderr, "Unknown keyword %s\n", yytext);
+ return rpc_UNKNOWN;
+ }
+
+[ \t\n]+ /* eat up whitespace */
+
+%%
+#ifdef OLD_STUFFS
+%x portdef
+%x addr_num
+PORT { BEGIN(portdef); return DEFINE_PORT; }
+<portdef>[0-9]+ {
+ BEGIN(INITIAL);
+ sscanf(yytext, "%d", &yylval.ival);
+ return NUM;
+ }
+
+<apidef>ADDR/[0-9]+ { BEGIN(addr_num); yylval.ival = _ADDR; return _ADDR; }
+<addr_num>[0-9]+ {
+ BEGIN(apidef);
+ sscanf(yytext, "%d", &yylval.ival);
+ return NUM;
+ }
+#endif
+
+/*
+ * function to free the buffer which flex allocates but not frees
+ */
+void
+free_flex_buffer(void)
+{
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+}
+
+/*
+ * dummy function to avoid a warning of not using 'yyunput'
+ */
+void
+dummy(void)
+{
+ yyunput(0, 0);
+}
diff --git a/otherservice/rpc_library/tool/apidef.y b/otherservice/rpc_library/tool/apidef.y
new file mode 100644
index 00000000..ce20c9c1
--- /dev/null
+++ b/otherservice/rpc_library/tool/apidef.y
@@ -0,0 +1,615 @@
+/**
+ * @file apidef.y
+ * @brief RPC tools--API definition file syntax definition and read/front-end processing
+ *
+ */
+
+/*---------------------------------------------------------------------------*/
+/* C declarative statement */
+/*---------------------------------------------------------------------------*/
+%{
+#define YYDEBUG 1
+#define YYERROR_VERBOSE 1
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * YACC to C I/F functions
+ */
+extern int yylex(void); /* LEX I/F */
+extern int yyerror(const char *); /* dummy */
+
+#include "apidef.h"
+
+/* YACC to C I/F functions */
+static void AddHeader(const char *header_file);
+static int push_function_arg(int arg_type, int num_of_bytes,
+ int is_pointer,
+ int is_vararray, int is_array_size,
+ const char *var_type_name,
+ int is_out, const char *var_name);
+static void process_function(const char *funcname);
+static void free_string(char *funcname);
+
+static int var_type;
+static int num_of_bytes;
+static int is_pointer;
+static int in_out;
+static int is_vararray;
+static int is_array_size;
+static char *var_type_name = NULL;
+
+%}
+
+/*---------------------------------------------------------------------------*/
+/* Bison declarations */
+/*---------------------------------------------------------------------------*/
+%union {
+ int ival;
+ char *strval;
+}
+
+%token '"'
+%left ','
+%left '('
+%right ')'
+%left '*'
+%token '{'
+%token '}'
+%token ';'
+%token '\n'
+%token <strval> rpc_INCLUDE 257
+%token <strval> RPC_RESULT 258
+%token <strval> rpc_NAME_DOT 259
+%token <strval> rpc_NAME 260
+%type <strval> funcdefs funcdef args
+%type <strval> nonvoid_args arg var_type
+%type <strval> var_primitive_type var_string_type var_user_defined_type
+/*
+%token <strval> rpc_OUT
+*/
+%token <strval> rpc_INOUT 261
+%token <strval> rpc_CONST 262
+%token <strval> rpc_VARARRAY 263
+%token <strval> rpc_ARRAYSIZE 264
+%token <ival> rpc_NUM 265
+%token <strval> rpc_VOID 266
+%token <ival> rpc_CHAR 267
+%token <ival> rpc_INT 268
+%token <ival> rpc_SINT 269
+%token <ival> rpc_UINT 270
+%token <ival> rpc_INT8 271
+%token <ival> rpc_INT16 272
+%token <ival> rpc_INT32 273
+%token <ival> rpc_INT64 274
+%token <ival> rpc_UINT8 275
+%token <ival> rpc_UINT16 276
+%token <ival> rpc_UINT32 277
+%token <ival> rpc_UINT64 278
+%token <ival> rpc_FLOAT 279
+%token <ival> rpc_DOUBLE 280
+%token <ival> rpc_STRING 281
+%token <ival> rpc_USER_DEFINED 282
+%token <ival> rpc_UNKNOWN 283
+
+/*---------------------------------------------------------------------------*/
+/* Grammar rule */
+/*---------------------------------------------------------------------------*/
+%%
+input: includes funcdefs
+;
+
+includes: /* empty input */
+ | includes include
+;
+
+include: rpc_INCLUDE '<' rpc_NAME_DOT '>'
+ { AddHeader($3); free_string($3); }
+;
+
+funcdefs: funcdef
+ | funcdefs funcdef
+;
+
+funcdef: RPC_RESULT rpc_NAME '(' args ')' ';'
+ { process_function($2); free_string($2);}
+;
+
+args: rpc_VOID
+ | nonvoid_args
+;
+
+nonvoid_args: arg
+ | nonvoid_args ',' arg
+;
+
+arg: var_type rpc_NAME
+ {
+ if (push_function_arg(var_type, num_of_bytes, is_pointer,
+ is_vararray, is_array_size,
+ var_type_name, in_out, $2) < 0) {
+ YYERROR;
+ }
+ if (var_type_name) { free_string(var_type_name); }
+ var_type_name = NULL;
+ free_string($2);
+ }
+ | var_type
+ {
+ if (push_function_arg(var_type, num_of_bytes, is_pointer,
+ is_vararray, is_array_size,
+ var_type_name, in_out, NULL) < 0) {
+ YYERROR;
+ }
+ if (var_type_name) { free_string(var_type_name); }
+ var_type_name = NULL;
+ }
+;
+
+/*
+ * Standard IN pointers are not allowed.
+ * When used as an array address, it is not clear how many bytes to copy.
+ * ->You are asked to declare the type and pass the address.
+ * Otherwise, you can simply pass it by value.
+ */
+var_type: var_primitive_type /* INT8, .. DOUBLE */
+ { is_pointer = 0; is_vararray = 0; is_array_size = 0; in_out =RPC_IN_ARG; }
+ | var_primitive_type '*' /* OUT INT8 *, ... OUT DOUBLE * */
+ { is_pointer = 1; is_vararray = 0; is_array_size = 0; in_out = RPC_OUT_ARG; }
+ /* if allow primitive IN pointer
+ | rpc_CONST var_primitive_type '*'
+ { is_pointer = 1; in_out = RPC_IN_ARG; }
+ */
+ | var_string_type
+ /* OUT STRING128, ... */
+ { is_pointer = 1; is_vararray = 0; is_array_size = 0; in_out = RPC_OUT_ARG; }
+ | rpc_CONST var_string_type
+ /* IN STRING128, ... */
+ { is_pointer = 1; is_vararray = 0; is_array_size = 0; in_out = RPC_IN_ARG; }
+ | var_user_defined_type
+ { is_pointer = 0; is_vararray = 0; is_array_size = 0; in_out = RPC_IN_ARG; }
+ | var_user_defined_type '*'
+ { is_pointer = 1; is_vararray = 0; is_array_size = 0; in_out = RPC_OUT_ARG; }
+ | rpc_CONST var_user_defined_type '*'
+ { is_pointer = 1; is_vararray = 0; is_array_size = 0; in_out = RPC_IN_ARG; }
+
+ /* INOUT specification */
+ | rpc_INOUT var_string_type
+ /* IN STRING128, ... */
+ { is_pointer = 1; is_vararray = 0; is_array_size = 0; in_out = RPC_INOUT_ARG; }
+ | rpc_INOUT var_user_defined_type '*'
+ { is_pointer = 1; is_vararray = 0; is_array_size = 0; in_out = RPC_INOUT_ARG; }
+
+ /* Variable-length arrays */
+ | rpc_CONST rpc_VARARRAY var_primitive_type '*'
+ { is_pointer = 1; is_vararray = 1; is_array_size = 0; in_out = RPC_IN_ARG; }
+ | rpc_VARARRAY var_primitive_type '*'
+ { is_pointer = 1; is_vararray = 1; is_array_size = 0; in_out = RPC_OUT_ARG; }
+ | rpc_INOUT rpc_VARARRAY var_primitive_type '*'
+ { is_pointer = 1; is_vararray = 1; is_array_size = 0; in_out = RPC_INOUT_ARG; }
+ | rpc_CONST rpc_VARARRAY var_user_defined_type '*'
+ { is_pointer = 1; is_vararray = 1; is_array_size = 0; in_out = RPC_IN_ARG; }
+ | rpc_VARARRAY var_user_defined_type '*'
+ { is_pointer = 1; is_vararray = 1; is_array_size = 0; in_out = RPC_OUT_ARG; }
+ | rpc_INOUT rpc_VARARRAY var_user_defined_type '*'
+ { is_pointer = 1; is_vararray = 1; is_array_size = 0; in_out = RPC_INOUT_ARG; }
+
+ /* Variable length array size */
+ | rpc_ARRAYSIZE var_primitive_type
+ { is_pointer = 0; is_vararray = 0; is_array_size = 1; in_out = RPC_IN_ARG; }
+;
+
+var_primitive_type:
+ rpc_CHAR { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_INT { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_SINT { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_UINT { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_INT8 { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_UINT8 { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_INT16 { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_UINT16 { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_INT32 { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_UINT32 { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_INT64 { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_UINT64 { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_FLOAT { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+ | rpc_DOUBLE { var_type = $1; num_of_bytes = 0; var_type_name = NULL; }
+;
+
+var_string_type: rpc_STRING rpc_NUM
+ { var_type = $1; num_of_bytes = $2; var_type_name = NULL; }
+;
+
+var_user_defined_type: rpc_NAME
+ { var_type = rpc_USER_DEFINED; num_of_bytes = 0; var_type_name = $1; }
+;
+
+%%
+
+/*---------------------------------------------------------------------------*/
+/* C additional code */
+/*---------------------------------------------------------------------------*/
+/* Including an older bison results in an error */
+/*#include "apidef.tab.h"*/
+
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+/*
+ * YACC/Lex interface functions/variables
+ */
+extern int yydebug; /* for YACC debug */
+extern int yyparse(void);
+extern FILE *yyin;
+extern int yy_flex_debug; /* for FLEX debug */
+/* my own function to free the buffer flex allocates */
+extern void free_flex_buffer(void);
+
+#ifdef DBG_ENABLE
+char rpc_log_enable;
+#endif
+
+/**/
+static void
+AddHeader(const char *filename)
+{
+ ApidefAddHeader(filename);
+}
+
+static int
+push_function_arg(int arg_type, int num_of_bytes, int is_pointer,
+ int is_vararray, int is_array_size,
+ const char *var_type_name, int in_out, const char *var_name)
+{
+ switch(arg_type) {
+ case rpc_CHAR:
+ case rpc_INT:
+ case rpc_SINT:
+ case rpc_UINT:
+ case rpc_INT8:
+ case rpc_INT16:
+ case rpc_INT32:
+ case rpc_INT64:
+ case rpc_UINT8:
+ case rpc_UINT16:
+ case rpc_UINT32:
+ case rpc_UINT64:
+ case rpc_FLOAT:
+ case rpc_DOUBLE:
+ case rpc_STRING:
+ case rpc_USER_DEFINED:
+ return ApidefPushFunctionArg(arg_type, num_of_bytes, is_pointer,
+ is_vararray, is_array_size,
+ var_type_name, in_out, var_name);
+ break;
+
+ default:
+ return -1;
+ break;
+ }
+}
+
+static void
+process_function(const char *funcname)
+{
+ ApidefProcessFunction(funcname);
+}
+
+static void
+free_string(char *s)
+{
+#ifdef DEBUG
+ fprintf(stderr, "freed %s\n", s);
+#endif
+ free(s);
+}
+
+static void
+extract_id(const char *filename, char **id)
+{
+ char *dotapi;
+ char *slash;
+ const char *start;
+
+ if (id == NULL) {
+ return;
+ }
+ dotapi = strrchr(filename, '.');
+ if (dotapi == NULL) {
+ return;
+ }
+ if (strcmp(dotapi, ".api")) {
+ return;
+ }
+
+ slash = strrchr(filename, '/');
+ start = filename;
+ if (slash != NULL) {
+ start = slash + 1;
+ }
+
+ *id = malloc((size_t)(dotapi - start + 1));
+ if (*id == NULL) {
+ return;
+ }
+ strncpy(*id, start, (size_t)(dotapi - start));
+ (*id)[dotapi - start] = '\0';
+}
+
+static void
+usage(const char *prog)
+{
+ fprintf(stdout,
+ "How to use: %s [CPPFLAGS] ... API definition file name\n",
+ prog);
+ fprintf(stdout, "Examples1: %s XXX.api\n", prog);
+ fprintf(stdout, "Examples2: %s -DSOME_DEFINES XXX.api\n", prog);
+}
+
+#define CPP_PROG "cpp"
+static void free_cpp_argv(char **argv);
+
+static char **
+prepare_cpp_argv(int argc, char *argv[])
+{
+ char **cpp_argv;
+ char **ret;
+
+ cpp_argv = malloc(sizeof(char *) * (long unsigned int)(argc+1));
+ if (cpp_argv == NULL) {
+ return NULL;
+ }
+ memset(cpp_argv, 0, sizeof(char *) * (long unsigned int)(argc+1));
+ ret = cpp_argv;
+
+ cpp_argv[0] = malloc(strlen(CPP_PROG)+1);
+ if (cpp_argv[0] == NULL) {
+ free_cpp_argv(ret);
+ return NULL;
+ }
+ strcpy(cpp_argv[0], CPP_PROG);
+ cpp_argv++;
+
+ for( ; *argv != NULL ; argv++, cpp_argv++) {
+ *cpp_argv = malloc(strlen(*argv)+1);
+ if (*cpp_argv == NULL) {
+ free_cpp_argv(ret);
+ return NULL;
+ }
+ strcpy(*cpp_argv, *argv);
+ }
+ *cpp_argv = NULL;
+ return ret;
+}
+
+static void
+free_cpp_argv(char **argv)
+{
+ char **orig; orig = argv;
+ while(*argv != NULL) {
+ free(*argv);
+ argv++;
+ }
+ free(orig);
+}
+
+/** @ingroup RPCtool
+ * @brief RPCtool main functions
+ *
+ * Perform the following processing.
+ *
+ * - Lexical context analysis of the API definition file(See apidef.y and apidef.l)
+ * - The API function definition read from the definition file is stored in the APIDef class.
+ * - Outputs stub and header files from function definitions stored in APIDef after a successful read
+ */
+int
+main(int argc, char *argv[])
+{
+ int start;
+ char **cpp_argv;
+ int pipefd[2];
+ int pid;
+ int ret;
+
+ if (argc < 2) {
+ usage(argv[0]);
+ return 1;
+ }
+
+ start = 1;
+ yy_flex_debug = 0;
+
+ if (!strcmp(argv[1], "-d")) {
+ yydebug=1;
+ yy_flex_debug = 1;
+ if (argc > 2) {
+ start++;
+ } else {
+ usage(argv[0]);
+ return 1;
+ }
+ }
+
+#ifdef DBG_ENABLE
+ /*
+ * If the second-to-last argument is a log specification
+ */
+ if ( ( argc >= 2 ) && (!strcmp(argv[argc-2], "-log")) ) {
+ rpc_log_enable = 1;
+ } else {
+ rpc_log_enable = 0;
+ }
+#endif
+
+ /*
+ * Extract ID from last argument (API definition file name)
+ */
+ {
+ char *moduleid;
+ moduleid = NULL;
+ extract_id(argv[argc-1], &moduleid);
+ if (moduleid == NULL) {
+ fprintf(stdout, "%s: The API definition file name is invalid.\n", argv[0]);
+ usage(argv[0]);
+ return 1;
+ }
+ ApidefDefineId(moduleid);
+ free(moduleid);
+ }
+
+ /*
+ * Preparing options to exec CPPs
+ */
+ cpp_argv = prepare_cpp_argv(argc, argv + start);
+ if (cpp_argv == NULL) {
+ printf("No Memory!\n");
+ return 1;
+ }
+
+#define PIPE_READ 0
+#define PIPE_WRITE 1
+
+ if (pipe(pipefd) != 0) {
+ perror("pipe");
+ return 1;
+ }
+
+ pid = fork();
+ if (pid < 0) {/* fork error */
+ close(pipefd[PIPE_READ]);
+ close(pipefd[PIPE_WRITE]);
+ perror("fork");
+ return 1;
+ }
+ if (pid == 0) {/* child process */
+ int must_be_1;
+ /*
+ * force stdout to be pipefd[PIPE_WRITE]
+ */
+ close(pipefd[PIPE_READ]);
+ close(1);
+ must_be_1 = dup(pipefd[PIPE_WRITE]);
+ assert(must_be_1 == 1);
+ close(pipefd[PIPE_WRITE]);
+ /*
+ * invoke C preprocessor with flags
+ */
+ execvp(CPP_PROG, cpp_argv);
+ perror("execvp");
+ exit(0);
+ } else {
+ /*
+ * parent process
+ */
+ int must_be_0;
+ free_cpp_argv(cpp_argv);
+
+ /*
+ * force stdin to be pipefd[PIPE_READ]
+ */
+ close(pipefd[PIPE_WRITE]);
+ close(0);
+ must_be_0 = dup(pipefd[PIPE_READ]);
+ assert(must_be_0 == 0);
+ close(pipefd[PIPE_READ]);
+ }
+
+ ret = yyparse();
+
+ free_flex_buffer();
+
+ if (ret == 0) {/* Parsed successfully */
+ //ApidefListFunctions(1);
+ ApidefMakeStubs();
+ } else {/* Parse error occurred */
+ fputs("The APIs that have been analyzed so far are as follows.\n", stdout);
+ fputs("-----start-----\n", stdout);
+ ApidefListFunctions(0);
+ fputs("------end------\n", stdout);
+ fputs("Check this API definition\n", stdout);
+ }
+ ApidefFreeAllocation();
+
+ return ret;
+}
+
+int
+yyerror(const char *s)
+{
+ printf("\nError: %s\n", s);
+ return 0;
+}
+
+int
+yywrap()
+{
+ return 1;
+}
+
+static char const *Types[] = {
+ "char",
+ "int",
+ "signed int",
+ "unsigned int",
+ "INT8",
+ "INT16",
+ "INT32",
+ "INT64",
+ "UINT8",
+ "UINT16",
+ "UINT32",
+ "UINT64",
+ "float",
+ "double",
+ "char *",
+};
+
+static const int TypeCodes[] = {
+ rpc_CHAR,
+ rpc_INT,
+ rpc_SINT,
+ rpc_UINT,
+ rpc_INT8,
+ rpc_INT16,
+ rpc_INT32,
+ rpc_INT64,
+ rpc_UINT8,
+ rpc_UINT16,
+ rpc_UINT32,
+ rpc_UINT64,
+ rpc_FLOAT,
+ rpc_DOUBLE,
+ rpc_STRING,
+};
+
+const char *
+TypeCodeString(const int code)
+{
+ int i;
+ int num;
+ num = sizeof(TypeCodes) / sizeof(int);
+
+ for(i = 0 ; i < num ; i++) {
+ if (code == TypeCodes[i]) {
+ return Types[i];
+ }
+ }
+ return NULL;
+}
+
+int
+IsTypeCodeNumeric( const int code )
+{
+ int i;
+
+ for(i = 0 ; i < sizeof(TypeCodes) / sizeof(TypeCodes[0]) ; i++) {
+ if (TypeCodes[i] == rpc_FLOAT) {
+ break;
+ }
+ if (code == TypeCodes[i]) {
+ return 1;
+ }
+ }
+ return 0;
+}