/* * @copyright Copyright (c) 2016-2020 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 #include #include #include #include #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_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::size_type num_args = m_args.size(); if (num_args > 0) { list::iterator a; a = m_args.begin(); for (list::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::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 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::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::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::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 /* for ntohs() */\n\n"; int api_num = 1; list::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::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 /* for sscanf() */\n"; out << "#include /* for getenv() */\n"; out << "#include /* for strncpy() */\n"; out << "#include /* for ntohs() */\n\n"; int api_num = 1; list::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::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::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 << "\n"; if (CheckAllArraySize() != 0) { return 1; } //cout << "\n"; if (MakeHeaderFiles(1) != 0) { return 1; } //cout << "\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::iterator a; for (a = m_args.begin(); a != m_args.end(); ++a) { a->Print(); } } } void APIDef::Print(int with_args) { list::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; }