import logging
import os
import re
import sys
"""
generate stub func body by return type
"""
RETURN_STATEMENTS = {
"int32_t": " return 0;",
"int": " return 0;",
"int&": " return __LINE__",
"uint8_t": " return 0;",
"uint32_t": " return 0U;",
"int64_t": " return 0;",
"uint64_t": " return 0U;",
"size_t": " return 0U;",
"std::size_t": " return 0U;",
"float": " return 0.0f;",
"bool": " return false;",
"void*": " return nullptr;",
"char*": " return nullptr;",
"char_t*": " return nullptr;",
"ge::char_t*": " return nullptr;",
"std::string": ' return "";',
"std::string&": " static std::string s;\n return s;",
"DataType": " return DT_FLOAT;",
"ge::DataType": " return ge::DT_FLOAT;",
"graphStatus": " return ge::GRAPH_SUCCESS;",
"ge::graphStatus": " return ge::GRAPH_SUCCESS;",
"ge::Status": " return ge::SUCCESS;",
"ArgsRefreshStrategy": " return ArgsRefreshStrategy::kNone;",
"ge::ArgsRefreshStrategy": " return ge::ArgsRefreshStrategy::kNone;",
"Status": " return 0U;",
"Format": " return Format();",
"ge::Format": " return ge::Format();",
"Graph": " return Graph();",
"Graph&": " return *this;",
"TensorDesc": " return TensorDesc();",
"TensorDesc&": " return *this;",
"Tensor": " return Tensor();",
"Operator&": " return *this;",
"GNode": " return GNode();",
"GNodePtr": " return nullptr;",
"ConstGraphPtr": " return nullptr;",
"GraphPtr": " return nullptr;",
"Placement": " return static_cast<Placement>(0);",
"Ptr": " return nullptr;",
"InitValueNum": "",
"Option": " return IGNORE;",
"InferenceContextPtr": " return nullptr;",
"SubgraphBuilder": " return nullptr;",
"OperatorImplPtr": " return nullptr;",
"CustomOpRegistryPtr": " return nullptr;",
"CustomOpInferMetaFunc": " return nullptr;",
"OutHandler": " return nullptr;",
"std::vector<int64_t>": " return {};",
"std::vector<std::string>": " return {};",
"std::vector<std::string>&": " static std::vector<std::string> vec;\n return vec;",
"std::vector<OpParamDef>": " return {};",
"std::vector<void*>": " return {};",
"std::vector<ge::DataType>&": " return this->impl_->types;",
"std::vector<ge::Format>&": " return this->impl_->formats;",
"ge::AscendString": ' return "";',
"ge::AscendString& OpParamDef::": " return this->impl_->name;",
"ge::AscendString& OpAttrDef::": " return this->impl_->name;",
"ge::AscendString& OpAICoreConfig::": " return this->impl_->cfg_info[key];",
"ge::AscendString& OpDef::": " return this->impl_->op_type;",
"std::vector<ge::AscendString>& OpMC2Def::": " return this->impl_->group_list;",
"std::vector<ge::AscendString>& OpAICoreConfig::": " return this->impl_->cfg_keys;",
"std::vector<ge::AscendString>& OpDefFactory::": " static std::vector<ge::AscendString> g_ops_list;\n"
" return g_ops_list;",
"InitValueType&": " return this->impl_->init_value_type;",
"InitValueNum&": " return this->impl_->init_value;",
"std::vector<ScalarVar>& OpParamDef::": " return this->impl_->init_value_list;",
"OpAttrDef& OpAttrDef::": " return *this;",
"OpDef& OpDef::": " return *this;",
"OpAICPUDef& OpAICPUDef::": " return *this;",
"std::vector<ge::AscendString>& OpAICPUDef::": " return this->impl_->cfg_keys;",
"std::map<ge::AscendString, ge::AscendString>& OpAICPUDef::": " return this->impl_->cfg_info;",
"ge::AscendString& OpAICPUDef::": " return this->impl_->cfg_info[key];",
"OpHostCPUDef& OpHostCPUDef::": " return *this;",
"std::vector<ge::AscendString>& OpHostCPUDef::": " return this->impl_->cfg_keys;",
"std::map<ge::AscendString, ge::AscendString>& OpHostCPUDef::": " return this->impl_->cfg_info;",
"ge::AscendString& OpHostCPUDef::": " return this->impl_->cfg_info[key];",
"OpMC2Def& OpMC2Def::": " return *this;",
"OpParamDef& OpParamDef::": " return *this;",
"OpMC2Def& OpDef::": " return this->impl_->op_mc2;",
"OpAICoreConfig& OpAICoreConfig::": " return *this;",
"OptionRegister& OptionRegister::": " return *this;",
"PassOptionRegister& PassOptionRegister::": " return *this;",
"std::map<ge::AscendString, ge::AscendString>& OpAICoreConfig::": " return this->impl_->cfg_info;",
"std::map<ge::AscendString, OpAICoreConfig>& OpAICoreDef::": " return this->impl_->aicore_configs;",
"OpAICoreDef& OpAICoreDef::": " return *this;",
"OpAICoreDef& OpDef::": " return this->impl_->op_aicore;",
"OpAICPUDef& OpDef::": " return this->impl_->op_aicpu;",
"OpHostCPUDef& OpDef::": " return this->impl_->op_hostcpu;",
"gert::OpImplKernelRegistry::TilingKernelFunc&": " return this->impl_->tiling_func;",
"OpParamDef& OpAICoreConfig::": ' static OpParamDef def("");\n return def;',
"std::vector<OpParamDef>& OpAICoreConfig::": " static std::vector<OpParamDef> vec;\n return vec;",
"std::vector<OpParamDef>& OpDef::": " static std::vector<OpParamDef> vec;\n return vec;",
"optiling::OP_CHECK_FUNC&": " return this->impl_->op_chk_support;",
"std::vector<std::vector<OpParamDef>>": " return {};",
"OpAttrDef& OpDef::": " return this->impl_->attrs.back();",
"optiling::PARAM_GENERALIZE_FUNC&": " return this->impl_->op_generlize_func;",
"OpParamDef& OpDef::": ' static OpParamDef def("");\n return def;',
"gert::OpImplKernelRegistry::InferShapeRangeKernelFunc&": " return this->impl_->infer_shape_range;",
"gert::OpImplKernelRegistry::InferShapeKernelFunc&": " return this->impl_->infer_shape;",
"gert::OpImplKernelRegistry::InferDataTypeKernelFunc&": " return this->impl_->infer_data_type;",
"std::vector<OpAttrDef>& OpDef::": " return this->impl_->attrs;",
"OpDef": ' return OpDef("default");',
"ItemFindStatus": " return ItemFindStatus::ITEM_FIND;",
"OpImplRegisterV2& OpImplRegisterV2::": " return *this;",
"OpRunInfo& OpRunInfo::": " return *this;",
"uint8_t*": " return nullptr;",
"OpCompileInfo& OpCompileInfo::": " return *this;",
"OpImplKernelRegistry::OpImplFunctions*": " return nullptr;",
"OpImplRegistry& OpImplRegistry::": " static OpImplRegistry instance;\n return instance;",
"DefaultOpImplSpaceRegistry& DefaultOpImplSpaceRegistry::": (
" static DefaultOpImplSpaceRegistry instance;\n return instance;"
),
"StreamMngFuncRegistry& StreamMngFuncRegistry::": (
" static StreamMngFuncRegistry instance;\n return instance;"
),
"OpImplRegistryHolderManager&": " static OpImplRegistryHolderManager instance;\n return instance;",
"HiddenInputFuncRegistry&": " static HiddenInputFuncRegistry instance;\n return instance;",
"CTilingDataClassFactory& CTilingDataClassFactory::GetInstance": (
" static CTilingDataClassFactory instance;\n return instance;"
),
"FrameworkRegistry& FrameworkRegistry::": " static FrameworkRegistry instance;\n return instance;",
"ScreenPrinter& ScreenPrinter::": " static ScreenPrinter instance;\n return instance;",
"ErrorTracking& ErrorTracking::": " static ErrorTracking instance;\n return instance;",
"HostCpuEngine& HostCpuEngine::": " static HostCpuEngine instance;\n return instance;",
"OppSoManager& OppSoManager::": " static OppSoManager instance;\n return instance;",
"OptionRegistry& OptionRegistry::": " static OptionRegistry instance;\n return instance;",
"PassOptionRegistry& PassOptionRegistry::": " static PassOptionRegistry instance;\n return instance;",
"RuntimePluginLoader& RuntimePluginLoader::": " static RuntimePluginLoader instance;\n return instance;",
"OpImplRegister& OpImplRegister": " return PrivateAttrImpl(private_attr, ge::AnyValue());",
"OpImplKernelRegistry::OpImplFunctions& OpImplRegistry::": "return types_to_impl_[op_type];",
"OpImplRegistry::PrivateAttrList& OpImplRegistry::": (
" static OpImplRegistry::PrivateAttrList emptyPrivateAttr;\n return emptyPrivateAttr;"
),
"OpImplKernelRegistry::PrivateAttrList& OpImplSpaceRegistry::": (
" static OpImplKernelRegistry::PrivateAttrList emptyPrivateAttr;\n return emptyPrivateAttr;"
),
"std::map<OpImplRegistry::OpType, OpImplRegistry::OpImplFunctions>&": " return types_to_impl_;",
"OpImplRegister& OpImplRegister::": " return *this;",
"std::map<OpImplKernelRegistry::OpType, OpImplKernelRegistry::OpImplFunctions>&": " return types_to_impl_;",
"OpCtImplKernelRegistry::OpCtImplFunctions*": " return nullptr;",
"StreamMngFunc": " return nullptr;",
"OpImplRegistryHolderPtr": " return nullptr;",
"GetHiddenAddr": " return nullptr;",
"std::map<ge::AscendString, TuningTilingDefConstructor>&": (
" static std::map<ge::AscendString, TuningTilingDefConstructor> instance;\n return instance;"
),
"std::shared_ptr<TuningTilingDef>": " return nullptr;",
"OpBankKeyConvertFun&": " return convert_func_;",
"OpBankParseFun&": " return parse_func_;",
"OpBankLoadFun&": " return load_func_;",
"std::unordered_map<ge::AscendString, OpBankKeyFuncInfoV2>&": (
" static std::unordered_map<ge::AscendString, OpBankKeyFuncInfoV2> op_func_mapV2;\n return op_func_mapV2;"
),
"std::unordered_map<ge::AscendString, OpBankKeyFuncInfo>&": (
" static std::unordered_map<ge::AscendString, OpBankKeyFuncInfo> op_func_map; return op_func_map;"
),
"OpBankLoadFunV2&": " return load_funcV2_;",
"OpBankParseFunV2&": " return parse_funcV2_;",
"OpBankKeyConvertFunV2&": " return convert_funcV2_;",
"StructSizeInfoBase& StructSizeInfoBase::": " return *this;",
"CTilingDataClassFactory& CTilingDataClassFactory::": " return *this;",
"TilingDataStructBase& TilingDataStructBase::": " return *this;",
"std::shared_ptr<TilingDef>": " return nullptr;",
"ByteBuffer&": " return buf;",
"ByteBuffer& OpRunInfo::": " static ByteBuffer byte_buffer;\n return byte_buffer;",
"std::unordered_map<std::string, OpTilingFunc>& OpTilingRegistryInterf::": (
" static std::unordered_map<std::string, OpTilingFunc> interf;\n return interf;"
),
"std::unordered_map<std::string, OpTilingFuncInfo>& OpTilingFuncRegistry::": (
" static std::unordered_map<std::string, OpTilingFuncInfo> op_func_map;\n return op_func_map;"
),
"void* OpRunInfo::": " return nullptr;",
"ge::AscendString& OpCompileInfo::": " static ge::AscendString compile_info;\n return compile_info;",
"std::unordered_map<std::string, OpTilingFuncV2>& OpTilingRegistryInterf_V2::": (
" static std::unordered_map<std::string, OpTilingFuncV2> interf;\n return interf;"
),
"OpTilingFunc& OpTilingFuncInfo::": " return this->tiling_func_;",
"OpTilingFuncV2& OpTilingFuncInfo::": " return this->tiling_func_v2_;",
"OpTilingFuncV3& OpTilingFuncInfo::": " return this->tiling_func_v3_;",
"OpTilingFuncV4& OpTilingFuncInfo::": " return this->tiling_func_v4_;",
"OpParseFuncV3& OpTilingFuncInfo::": " return this->parse_func_v3_;",
"OpParseFuncV4& OpTilingFuncInfo::": " return this->parse_func_v4_;",
"ParseOpToGraphFunc": " return nullptr;",
"ParseSubgraphFunc": " return nullptr;",
"FusionParseParamByOpFunc": " return nullptr;",
"FusionParseParamFunc": " return nullptr;",
"ParseParamByOpFunc": " return nullptr;",
"AutoMappingSubgraphIOIndexFunc": " return nullptr;",
"ParseParamFunc": " return nullptr;",
"domi::FrameworkType": " return FRAMEWORK_RESERVED;",
"std::set<std::string> OpRegistrationData::": " return {};",
"domi::ImplyType": " return domi::ImplyType::BUILDIN;",
"OpRegistrationData& OpRegistrationData::": " return *this;",
"Promote& Promote::": " return *this;",
"Promote& PromoteImpl::": " return obj;",
"std::pair<GNodePtr, int32_t> GNode::": (
" const std::pair<GNodePtr, int32_t> gnode_idx = {nullptr, 0xFF};\n return gnode_idx;"
),
"std::vector<int64_t>& OpRunInfo::": " static std::vector<int64_t> vec;\n return vec;",
"std::vector<const char *>": " return {};",
"std::vector<FieldInfo>": " return {};",
"std::vector<GNodePtr>": " return {};",
"std::vector<std::pair<GNodePtr, int32_t>>": " return {};",
"std::vector<ge::NodePtr>": " return {};",
"std::vector<NodeToOutAnchor>": " return {};",
"std::vector<ConstGeTensorPtr>": " return {};",
"std::vector<GeTensorPtr>": " return {};",
"std::vector<ge::GeTensorDesc>": " return {};",
"std::vector<GNode>": " return {};",
"std::vector<GraphPtr>": " return {};",
"std::vector<std::vector<ShapeAndType>>&": (
" static std::vector<std::vector<ShapeAndType>> sat;\n return sat;"
),
"std::vector<std::pair<int64_t, int64_t>>": " return {};",
"OpsProtoManager* OpsProtoManager::": " static OpsProtoManager instance;\n return &instance;",
"Operator": " return Operator();",
"std::unique_ptr<BaseCustomOp>": "return nullptr;",
"BaseCustomOp*": " return nullptr;",
"CustomOpRegistry& CustomOpFactory::": " static CustomOpRegistry registry;\n return registry;",
"std::map<size_t, std::pair<size_t, size_t>>": " return {};",
"GeTensor": " return GeTensor();",
"GeTensorPtr": " return nullptr;",
"ConstGeTensorPtr": " return nullptr;",
"ConstNodePtr": " return nullptr;",
"ComputeGraphPtr": " return nullptr;",
"ge::ComputeGraphPtr": " return nullptr;",
"ConstGeTensorBarePtr": " return nullptr;",
"GeTensorDesc": " return GeTensorDesc();",
"HcomTopoInfo& HcomTopoInfo::": " static HcomTopoInfo hcom_topo_info;\n return hcom_topo_info;",
"HcomTopoInfo::TopoDescs*": " return nullptr;",
"AnchorInstanceInfo*": " return nullptr;",
"CompileTimeTensorDesc*": " return nullptr;",
"RuntimeAttrs*": " return nullptr;",
"DeviceTilingContextBuilder& DeviceTilingContextBuilder::": " return *this;",
"KernelContextHolder KernelRunContextBuilder::": (
"static KernelContextHolder default_holder;\n return std::move(default_holder);"
),
"ge::NodePtr KernelRunContextBuilder::": " return nullptr;",
"OpDescPtr": " return nullptr;",
"std::set<ge::AscendString>&": " static std::set<ge::AscendString> as;\n return as;",
"ResourceContext*": " return nullptr;",
"std::unique_ptr<InferenceContext>": " return nullptr;",
"Shape ShapeAndType::": " return Shape();",
"NpuMemoryAllocator*": " return nullptr;",
"MemBlock*": " return nullptr;",
"rtStream_t": " return nullptr;",
"aclrtStream": " return nullptr;",
"SingleOp*": " return nullptr;",
"DynamicSingleOp*": " return nullptr;",
"StreamResource*": " return nullptr;",
"std::unique_ptr<HybridDavinciModel>": " return nullptr;",
"ExecutorSubscribersScheduler& ModelV2Executor::": " return subscribers_;",
"ModelDesc& ModelV2Executor::": " static ModelDesc default_model_desc;\n return default_model_desc;",
"std::unique_ptr<ge::Allocator>": " return nullptr;",
"ExecutorSubscriber& ExecutorSubscribersScheduler::": " return subscriber_wrapper_;",
"ge::Allocator*": " return nullptr;",
"ModelV2Executor*": " return nullptr;",
"Shape& ShapeRange::": " return min_;",
"Shape& ModelIoDesc::": " return aipp_shape_;",
"ShapeRange& ModelIoDesc::": " return storage_shape_range_;",
"OpImplSpaceRegistryArray*": " return nullptr;",
"OpImplSpaceRegistryV2Array*": " return nullptr;",
"OpImplKernelRegistry::OpImplFunctionsV2*": " return nullptr;",
"DefaultOpImplSpaceRegistryV2&": "static DefaultOpImplSpaceRegistryV2 instance;\n return instance;",
"OpImplSpaceRegistryPtr&": " static OpImplSpaceRegistryPtr null_ptr = nullptr;\n return null_ptr;",
"OpImplSpaceRegistryArray&": " static OpImplSpaceRegistryArray space_registries;\n return space_registries;",
"ModelIoDesc*": " return nullptr;",
"OpLibRegistry& OpLibRegistry::": " static OpLibRegistry instance;\n return instance;",
"SmallVector<int64_t, kDefaultDimsNum>& GeShape::GetMutableDims": (
" static SmallVector<int64_t, 8U> vec;\n return vec;"
),
"GeShape& GeShape::operator=": " return *this;",
"GeShape& GeTensorDesc::": " static GeShape ge_shape;\n return ge_shape;",
"std::vector<uint32_t> GeTensorDesc::": " return {};",
"GeTensorDesc& GeTensorDesc::operator=": " return *this;",
"ProtoAttrMap& GeTensorDesc::MutableAttrMap": " static ProtoAttrMap attr;\n return attr;",
"ConstProtoAttrMap& GeTensorDesc::GetAttrMap": " static ProtoAttrMap attr;\n return attr;",
"std::uint8_t*": " return nullptr;",
"std::shared_ptr<AlignedPtr>&": " static std::shared_ptr<AlignedPtr> ap = nullptr; return ap;",
"TensorData& TensorData::operator=": " return *this;",
"GeTensorDesc& GeTensor::": " static GeTensorDesc desc;\n return desc;",
"std::shared_ptr<AlignedPtr> GeTensor::": " return nullptr;",
"TensorData& GeTensor::": " static TensorData data;\n return data;",
"GeTensor& GeTensor::operator=": " return *this;",
"std::unique_ptr<Graph>": " return nullptr;",
"std::vector<NodePtr>": " return {};",
"std::map<std::string, std::string>": " return {};",
"std::shared_ptr<const Node>": " return nullptr;",
"Shape TensorDesc::": " return Shape();",
"std::unique_ptr<uint8_t[], Tensor::DeleteFunc>": " return nullptr;",
"ge::Placement Tensor::": " return static_cast<Placement>(0);",
"ge::Placement TensorImpl::": " return static_cast<Placement>(0);",
"GeTensor* TensorAdapter::": " return nullptr;",
"HiddenInputsFuncRegistry& HiddenInputsFuncRegistry::GetInstance": (
" static HiddenInputsFuncRegistry instance;\n return instance;"
),
"GetHiddenAddrs HiddenInputsFuncRegistry::": " return nullptr;",
"FollowType& OpParamDef::": " static FollowType value = FollowType::INVALID_TYPE;\n return value;",
"DependScope& OpParamDef::": " static DependScope value = DependScope::INVALID_SCOPE;\n return value;",
"gert::OpImplRegisterV2::TilingKernelFunc& OpAICoreDef::": (
" static gert::OpImplRegisterV2::TilingKernelFunc func;\n return func;"
),
"gert::OpImplRegisterV2::InferShapeKernelFunc& OpDef::": (
" static gert::OpImplRegisterV2::InferShapeKernelFunc func;\n return func;"
),
"gert::OpImplRegisterV2::InferShapeRangeKernelFunc& OpDef::": (
" static gert::OpImplRegisterV2::InferShapeRangeKernelFunc func;\n return func;"
),
"gert::OpImplRegisterV2::InferDataTypeKernelFunc& OpDef::": (
" static gert::OpImplRegisterV2::InferDataTypeKernelFunc func;\n return func;"
),
"std::vector<ge::AscendString>& OpDef::": " static std::vector<ge::AscendString> vec;\n return vec;",
"std::map<ge::AscendString, OpDef::PortFollowInfo> OpDef::": " return {};",
"std::map<ge::AscendString, std::vector<std::pair<ge::AscendString, OpDef::PortStat>>> OpDef::": " return {};",
"OpImplRegistry::OpImplFunctionsV2& OpImplRegistry::": (
" static OpImplRegistry::OpImplFunctionsV2 func;\n return func;"
),
"OpImplRegistry::OpImplFunctionsV2* OpImplRegistry::": " return nullptr;",
"OpImplRegisterV2::PrivateAttrList& OpImplRegistry::": (
" static OpImplRegisterV2::PrivateAttrList list;\n return list;"
),
"std::map<OpImplRegisterV2::OpType, OpImplRegistry::OpImplFunctionsV2>& OpImplRegistry::": (
" static std::map<OpImplRegisterV2::OpType, OpImplRegistry::OpImplFunctionsV2> m;\n return m;"
),
"OpImplKernelRegistry::OpImplFunctionsV2* OpImplSpaceRegistry::": " return nullptr;",
"OpImplRegisterV2::PrivateAttrList& OpImplSpaceRegistry::": (
" static OpImplRegisterV2::PrivateAttrList list;\n return list;"
),
"OpLibRegister& OpLibRegister::": " return *this;",
"std::unordered_map<std::string, OoInfo> OptionRegistry::": " return {};",
"OpParamDef OpDef::": ' static OpParamDef param("test");\n return param;',
"FormatCheckOption OpDef::": " return FormatCheckOption::DEFAULT;",
"OoInfo* OptionRegistry::": " return nullptr;",
"AscendString::AscendString(const char_t *const name)": r"""
if (name != nullptr) {
name_ = MakeShared<std::string>(name);
}
""",
"AscendString::AscendString(const char_t *const name, size_t length)": r"""
if (name != nullptr) {
name_ = MakeShared<std::string>(name, length);
}
""",
"const char_t* AscendString::GetString() const": r"""
if (name_ == nullptr) {
const static char *empty_value = "";
return empty_value;
}
return (*name_).c_str();
""",
"TensorDescValue& TensorDescValue::operator=": " return *this;",
"Shape": " return Shape();",
"AscendString TypeUtilsImpl::": ' return "";',
"enum HcclServerType type, const char* soc = nullptr": "enum HcclServerType type, const char* soc",
'ge::AscendString soc_version = ""': "ge::AscendString soc_version",
"ops::HcclServerType": " return HcclServerType::MAX;",
"OppSoDesc& OppSoDesc::operator=": " return *this;",
"std::vector<ge::AscendString>": " return {};",
"gert::Allocators*": " return nullptr;",
}
SKIP_METHODS = [
"MergeParam",
"GetParamName",
"GetParamType",
"GetOriginDataTypes",
"LoadOpsProtoSo",
"LoadOpMasterSo",
"LoadUpgradedOpsProtoSo",
"LoadUpgradedOpMasterSo",
"CreateOmOppDir",
"RmOmOppDir",
"OpTilingSinkRegister",
"OpIsTilingSink",
"GetHcclGroups",
"GetHcclServerType",
"GetIgnoreContiguous",
"TilingParse",
"LoadSoAndInitDefault",
"AddCfgItem",
"AddRegistry",
"CreateOrGetOpImpl",
"MergeTypesToImpl",
"MergeFunctions",
"MergeTypesToCtImpl",
"MergeCtFunctions",
"CopyGraphImpl",
"PrintInOutTensorShape",
"PostProcessAfterInfershape",
"FeedStreamCtrlMap",
"GenerateStreamCtrlMap",
"ConvertPartitionCalledOp",
"StridedOptimize",
"GetAllCustomOpApiSoPaths",
"CallInitFunc",
"UpdateFormatImpl",
"GetGlobalRegistry",
"CreateOrGetCustomOpLocked",
"CallInferFuncV1",
"CallInferFuncV2",
"InferShapeByOutputShapesAttr",
"CallInferFormatFuncV1",
"CallInferFormatFuncV2",
"InferCustomOpShape",
]
"""
this attr is used for symbol table visible
"""
GE_ATTR = "GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY"
VISIBILITY_ATTR = "VISIBILITY_EXPORT"
"""
max code len per line in hua_wei software programming specifications
"""
MAX_CODE_LEN_PER_LINE = 120
DEBUG = True
logging.basicConfig(
stream=sys.stdout,
format="[%(asctime)s] [%(lineno)s] %(levelname)s: %(message)s",
level=logging.INFO,
)
def need_generate_func(func_line):
"""
:param func_line:
:return:
"""
if (
func_line.strip().endswith("default")
or func_line.strip().endswith("delete")
or func_line.strip().startswith("typedef")
or func_line.strip().startswith("using")
):
return False
return True
"""
belows are patterns used for analyse .h file
"""
pattern_func = re.compile(
r"""(^\s*)([a-zA-Z~_].*[)](?!.*{).*)(;.*)\n$""",
re.VERBOSE | re.MULTILINE | re.DOTALL,
)
pattern_virtual_func = re.compile(
r"""^\s*virtual\s+(?:const\s+)?[:\w]+[ &*]+[:\w]+\([^()]*\)\s+(?:const\s+)?=\s+0;$""",
re.VERBOSE,
)
pattern_comment = re.compile(r"^\s*//")
pattern_comment_2_start = re.compile(r"^\s*/[*]")
pattern_comment_2_end = re.compile(r"[*]/\s*$")
pattern_visibility = re.compile(
r"(FMK_FUNC_HOST_VISIBILITY|FMK_FUNC_DEV_VISIBILITY|VISIBILITY_EXPORT|"
r"PARSER_FUNC_VISIBILITY|ACL_FUNC_VISIBILITY|GE_FUNC_VISIBILITY|"
r"ASCEND_FUNC_VISIBILITY|GE_OBJECT_VISIBILITY|GE_FUNC_DEV_VISIBILITY|"
r"GE_FUNC_HOST_VISIBILITY|FUNC_VISIBILITY) *"
)
pattern_override = re.compile(r" +override\b")
pattern_weak = re.compile(r" +__attribute__\(\(weak\)\)")
pattern_define = re.compile(r"^\s*#define")
pattern_define_return = re.compile(r"\\\s*$")
pattern_using = re.compile(r"^\s*using")
pattern_using_return = re.compile(r";\s*$")
pattern_include = re.compile(r"^\s*#include")
pattern_blank_line = re.compile(r"^\s*$")
pattern_keyword = re.compile(r"(virtual\s+|explicit\s+|friend\s+|static\s+)")
pattern_leading_space = re.compile(r"(^\s*)[a-zA-Z~_]")
pattern_func_name = re.compile(r"([a-zA-Z0-9~_\-]+\s*|operator?.*)[(]")
pattern_template = re.compile(r"^\s*template")
pattern_template_end = re.compile(r">\s*$")
pattern_namespace = re.compile(r"namespace.*{")
pattern_class = re.compile(
r"^\s*(class|struct)\s+((?:%s|%s)\s+)?([a-zA-Z0-9_\-]+<?)(?!.*;)"
% (GE_ATTR, VISIBILITY_ATTR)
)
pattern_start = re.compile("(?!namespace|class).+{")
pattern_end = re.compile("}")
pat_format_func = re.compile(
r"""^((?:const\s+)?
(?:[:\w]+
|std::(?:vector|set|shared_ptr|unique_ptr)<[:\w* ]+>
|std::(?:vector|set|shared_ptr|unique_ptr)<std::(?:vector|pair)<[:\w, ]+>>
|std::(?:unique_ptr)<[:\w, \[\]]+>
|std::(?:vector|set|shared_ptr)<std::string>
|std::(?:map|unordered_map|pair)<[:\w]+[, ]+[:\w]+>
|std::(?:map|unordered_map|pair)<[:\w]+,\s+std::pair<\w+,\s\w+>>
|std::(?:map)<[:\w]+[, ]+std::(?:vector)<std::(?:pair)<[:\w, ]+>>>
|(?:SmallVector)<[:\w]+[, ]+[:\w]+>
))
(\s+)
([&*]?)""",
re.VERBOSE,
)
pat_search_func = re.compile(
r"""^(?:const\s+)?
(?P<ret_type>(?:[:\w]+
|std::(?:vector|set|shared_ptr|unique_ptr)<[:\w* ]+>
|std::(?:vector|set|shared_ptr|unique_ptr)<std::(?:vector|pair)<[:\w, ]+>>
|std::(?:unique_ptr)<[:\w, \[\]]+>
|std::(?:vector|set|shared_ptr)<std::string>
|std::(?:map|unordered_map|pair)<[:\w]+[, ]+[:\w]+>
|std::(?:map|unordered_map|pair)<[:\w]+,\s+std::pair<\w+,\s\w+>>
|std::(?:map)<[:\w]+[, ]+std::(?:vector)<std::(?:pair)<[:\w, ]+>>>
|(?:SmallVector)<[:\w]+[, ]+[:\w]+>
)
(?:[&*]+)?)\s+
(?P<class_name>\w+)::\n?
(?P<func_name>\w+|operator=)\s*\(""",
re.VERBOSE,
)
class H2CC(object):
def __init__(self, input_file, output_file, shared_includes_content):
"""
:param input_file:
:param output_file:
:param shared_includes_content:
"""
self.input_file = input_file
file_dir = output_file[0 : output_file.rindex("/")]
if not os.path.exists(file_dir):
os.makedirs(file_dir)
self.output_file = output_file
self.shared_includes_content = shared_includes_content
self.line_index = 0
self.input_fd = open(self.input_file, "r")
self.input_content = self.input_fd.readlines()
self.output_fd = open(self.output_file, "w")
self.stack = []
self.stack_class = []
self.stack_template = []
self.func_list_exist = []
def __del__(self):
self.input_fd.close()
self.output_fd.close()
del self.stack
del self.stack_class
del self.stack_template
del self.func_list_exist
def just_skip(self):
if pattern_blank_line.search(
self.input_content[self.line_index]
) or pattern_comment.search(self.input_content[self.line_index]):
self.line_index += 1
return "continue"
elif pattern_comment_2_start.search(self.input_content[self.line_index]):
while self.line_index < len(
self.input_content
) and not pattern_comment_2_end.search(self.input_content[self.line_index]):
self.line_index += 1
self.line_index += 1
return "continue"
elif pattern_include.search(self.input_content[self.line_index]):
self.line_index += 1
return "continue"
elif pattern_define.search(self.input_content[self.line_index]):
while pattern_blank_line.search(
self.input_content[self.line_index]
) or pattern_define_return.search(self.input_content[self.line_index]):
self.line_index += 1
self.line_index += 1
return "continue"
elif pattern_using.search(self.input_content[self.line_index]):
while pattern_blank_line.search(
self.input_content[self.line_index]
) or not pattern_using_return.search(self.input_content[self.line_index]):
self.line_index += 1
self.line_index += 1
return "continue"
elif re.compile(r"^.*\b(constexpr|const)\b.*(?= = ).*;$").search(
self.input_content[self.line_index]
):
self.line_index += 1
return "continue"
elif re.compile(r"^\s*static_assert").search(
self.input_content[self.line_index]
):
self.line_index += 1
return "continue"
elif pattern_virtual_func.search(self.input_content[self.line_index]):
self.line_index += 1
return "continue"
return "pass"
def handle_extern_variable(self):
line = self.input_content[self.line_index]
if re.search(r"^\s*extern\s+const.+(?!=).+;$", line):
line = re.sub(r"^\s*extern\s*", "", line)
default_value = 0
if re.search(r"(std::)?(map|set|vector)", line):
default_value = "{}"
elif re.search(r"(std::)?string\b", line):
default_value = '""'
line = re.sub(r"^([^;]+)(;)$", rf"\1 = {default_value}\2\n", line)
self.output_fd.write(line)
self.line_index += 1
return "continue"
return "pass"
def write_inc_content(self):
for shared_include_content in self.shared_includes_content:
self.output_fd.write(shared_include_content)
self.output_fd.write("\n")
def should_skip_func(self, func_line):
return any(skip_method in func_line for skip_method in SKIP_METHODS)
def h2cc(self):
logging.info(
"start generate cc_file[%s] from h_file[%s]",
self.output_file,
self.input_file,
)
self.write_inc_content()
while self.line_index < len(self.input_content):
if self.just_skip() == "continue":
continue
if self.handle_namespace() == "continue":
continue
if self.handle_extern_variable() == "continue":
continue
if self.handle_declaration_class() == "continue":
continue
template_string = self.handle_template()
line = self.input_content[self.line_index]
if pattern_visibility.search(line):
line = pattern_visibility.sub("", line)
if pattern_override.search(line):
line = pattern_override.sub("", line)
if pattern_weak.search(line):
line = pattern_weak.sub("", line)
match_start = pattern_start.search(line)
if self.handle_class(template_string, line, match_start) == "continue":
continue
if self.handle_stack(match_start) == "continue":
continue
handle_func_result, line, start_i = self.handle_func(line)
if handle_func_result == "continue":
continue
if self.should_skip_func(line):
self.line_index += 1
continue
line = pattern_keyword.sub("", line)
friend_match = re.search("friend ", line)
if len(self.stack_class) > 0 and not friend_match:
line, func_name = self.handle_class_member_func(line, template_string)
else:
line, func_name = self.handle_normal_func(line, template_string)
need_generate = need_generate_func(line)
line += self.implement_function(line)
self.write_func_content(line, func_name, need_generate)
self.line_index += 1
logging.info("Added %s functions", len(self.func_list_exist))
logging.info("Successfully converted,please see " + self.output_file)
@staticmethod
def _remove_template_content(line):
result = []
depth = 0
for char in line:
if char == "<":
depth += 1
elif char == ">":
depth -= 1
elif depth == 0:
result.append(char)
return "".join(result)
def handle_func(self, line):
match_left_bracket = re.search(r"(?<!.{7}\)|decltype)\((?!\*)", line)
if not match_left_bracket:
self.line_index += 1
return "continue", line, None
stripped_line = H2CC._remove_template_content(line)
if "(" not in stripped_line:
self.line_index += 1
return "continue", line, None
match_right_bracket = re.search(r"\)", line)
start_i = self.line_index
space_match = pattern_leading_space.search(line)
if match_left_bracket and (not match_right_bracket):
self.line_index += 1
break_line = self.input_content[self.line_index]
if space_match:
break_line = re.sub("^" + space_match.group(1), "", break_line)
line += break_line
while self.line_index < len(self.input_content):
if re.search(r"\)", break_line) and not re.search(
r"std::function<.+?> &input,", break_line
):
break
self.line_index += 1
break_line = self.input_content[self.line_index]
break_line = re.sub("^" + space_match.group(1), "", break_line)
line += break_line
match_start = pattern_start.search(self.input_content[self.line_index])
match_end = pattern_end.search(self.input_content[self.line_index])
if match_start:
if not match_end:
self.stack.append("normal_now")
self.line_index += 1
return "continue", line, start_i
logging.info("line[%s]", line)
(line, match) = pattern_func.subn(r"\2\n", line)
logging.info("line[%s]", line)
if not match:
self.line_index += 1
return "continue", line, start_i
pre_line = self.input_content[start_i - 1]
stripped_pre_line = pattern_visibility.sub("", pre_line)
if re.search(r"^\s*(inline)?\s*[a-zA-Z0-9_]+\s*$", stripped_pre_line):
line = stripped_pre_line.rstrip() + " " + line
line = line.lstrip()
return "pass", line, start_i
def handle_stack(self, match_start):
if match_start:
self.stack.append("normal_now")
line = self.input_content[self.line_index]
match_end = pattern_end.search(line)
if match_end:
top_status = self.stack.pop()
if top_status == "namespace_now":
self.output_fd.write(line + "\n")
elif top_status == "class_now":
self.stack_class.pop()
self.stack_template.pop()
if match_start or match_end:
self.line_index += 1
return "continue"
if len(self.stack) > 0 and self.stack[-1] == "normal_now":
self.line_index += 1
return "continue"
return "pass"
def handle_class(self, template_string, line, match_start):
"""
:param template_string:
:param line:
:param match_start:
:return:
"""
match_class = pattern_class.search(line)
if not match_class:
return "pass"
self.stack_template.append(template_string)
self.stack.append("class_now")
class_name = match_class.group(3)
if "<" in class_name:
k = line.index("<")
fit = 1
for ii in range(k + 1, len(line)):
if line[ii] == "<":
fit += 1
elif line[ii] == ">":
fit -= 1
if fit == 0:
class_name += line[k + 1 : ii + 1]
break
logging.info("class_name[%s]", class_name)
self.stack_class.append(class_name)
while not match_start:
self.line_index += 1
match_start = pattern_start.search(self.input_content[self.line_index])
self.line_index += 1
return "continue"
def handle_declaration_class(self):
line = self.input_content[self.line_index]
match_result = re.search(r"^\s*class\s+(\w+);\s*$", line)
if match_result:
self.line_index += 1
class_name = match_result.group(1)
logging.info("declaration class:[%s]", class_name)
if class_name in [
"Graph",
"GNode",
"OpParamDefImpl",
"OpParamTrunk",
"OpAttrDefImpl",
"OpAICoreConfigImpl",
"OpAICoreDefImpl",
"OpAICPUDefImpl",
"OpHostCPUDefImpl",
"OpMC2DefImpl",
"OpDefImpl",
"Operator",
"GeTensorSerializeUtils",
"OpImplSpaceRegistryV2",
]:
return "pass"
context = (
"class %s {\n public:\n %s() = default;\n ~%s() = default;\n};\n\n"
% (
class_name,
class_name,
class_name,
)
)
self.output_fd.write(context)
return "continue"
return "pass"
def handle_template(self):
line = self.input_content[self.line_index]
match_template = pattern_template.search(line)
template_string = ""
if match_template:
template_string = line
while not pattern_template_end.search(line):
self.line_index += 1
line = self.input_content[self.line_index]
template_string += line
self.line_index += 1
return template_string
def handle_namespace(self):
line = self.input_content[self.line_index]
match_namespace = pattern_namespace.search(line)
if match_namespace:
self.output_fd.write(line + "\n")
self.stack.append("namespace_now")
self.line_index += 1
return "continue"
return "pass"
def handle_normal_func(self, line, template_string):
template_line = ""
self.stack_template.append(template_string)
if self.stack_template[-1] != "":
template_line = re.sub(r"\s*template", "template", self.stack_template[-1])
template_line = re.sub(r"\s*=.*>(\s*)$", r">\1", template_line)
template_line = re.sub(r"\s*=.*,", ",", template_line)
line = re.sub(r"\s*=.*,", ",", line)
line = re.sub(r"\s*=.*\)", ")", line)
line = template_line + line
self.stack_template.pop()
func_name = re.search(r"^.*\)", line, re.MULTILINE | re.DOTALL).group()
logging.info("line[%s]", line)
logging.info("func_name[%s]", func_name)
return line, func_name
def handle_class_member_func(self, line, template_string):
template_line = ""
x = ""
if template_string != "":
template_string = re.sub(r"\s*template", "template", template_string)
template_string = re.sub(r"\s*=.*>(\s*)$", r">\1", template_string)
template_string = re.sub(r"\s*=.*,", ",", template_string)
template_string = re.sub(r"\s*=.*", "", template_string)
if self.stack_template[-1] != "":
if not (re.search(r"<\s*>", self.stack_template[-1])):
template_line = re.sub(
r"^\s*template", "template", self.stack_template[-1]
)
if not (re.search(r"<.*>", self.stack_class[-1])):
x = re.sub(
r"template\s*<", "<", template_line
)
x = re.sub(r"\n", "", x)
x = re.sub(r"\s*=.*,", ",", x)
x = re.sub(r"\s*=.*>", ">", x)
x = x.rstrip()
x = re.sub(
r"(class|typename)\s+|(<class>|<typename>\s*class)", "", x
)
x = re.sub(r"<\s+", "<", x)
x = re.sub(r"\s+>", ">", x)
x = re.sub(r"\s+,", ",", x)
x = re.sub(r",\s+", ", ", x)
line = re.sub(r"\s*=\s+0", "", line)
line = re.sub(r"\s*=\s+.*,", ",", line)
line = re.sub(r"\s*=\s+.*\)", ")", line)
logging.info("x[%s]\nline[%s]", x, line)
rep_fmt = "%s%s::{}%s" % (self.stack_class[-1], x, r"\1(")
temp_line = pattern_func_name.sub(rep_fmt.format(""), line, count=1)
if len(temp_line) > MAX_CODE_LEN_PER_LINE:
line = pattern_func_name.sub(rep_fmt.format("\n"), line, count=1)
else:
line = temp_line
logging.info("line[%s]", line)
template_line = re.sub(r"\s*=.*>(\s*)$", r">\1", template_line)
template_line = re.sub(r"\s*=.*,", ",", template_line)
template_line = re.sub(r"\s*=.*", "", template_line)
line = template_line + template_string + line
func_name = re.search(r"^.*\)", line, re.MULTILINE | re.DOTALL).group()
line = re.sub(r"\b(KernelInfo)\b", r"KernelRegistry::\1", line)
line = re.sub(r"\b(KernelFuncs)\b", r"KernelRegistry::\1", line)
line = re.sub(
r"(?<!::)\b(OpImplFunctions)\b", r"OpImplKernelRegistry::\1", line
)
line = re.sub(r"(?<!::)\b(OpType)\b", r"OpImplKernelRegistry::\1", line)
line = re.sub(
r"\b(PrivateAttrList &OpImplKernelRegistry::)",
r"OpImplKernelRegistry::\1",
line,
)
line = re.sub(r"\b(TopoDescs)\b", r"HcomTopoInfo::\1", line)
logging.info("line[%s]", line)
logging.info("func_name[%s]", func_name)
return line, func_name
def write_func_content(self, content, func_name, need_generate):
if func_name not in self.func_list_exist and need_generate:
self.output_fd.write(content)
self.func_list_exist.append(func_name)
logging.info("add func:[%s]", func_name)
def gen_comment(self, start_i):
comment_line = ""
k = start_i - 1
if pattern_template.search(self.input_content[k]):
k -= 1
if pattern_comment_2_end.search(self.input_content[k]):
comment_line = self.input_content[k].lstrip()
while not pattern_comment_2_start.search(self.input_content[k]):
k -= 1
comment_line = self.input_content[k].lstrip() + comment_line
else:
for j in range(k, 0, -1):
c_line = self.input_content[j]
if pattern_comment.search(c_line):
c_line = re.sub(r"\s*//", "//", c_line)
comment_line = c_line + comment_line
else:
break
return comment_line
@staticmethod
def get_return_statements(func):
func = pat_format_func.sub(r"\1\3\2", func)
if func.strip() in RETURN_STATEMENTS:
logging.info("func:[%s] matched!", func.strip())
return re.sub(
r"^ {8}",
"",
RETURN_STATEMENTS[func.strip()],
count=0,
flags=re.MULTILINE,
).strip("\n")
m = pat_search_func.search(func)
if not m:
return None
logging.info(
"ret_type: %s, class_name: %s, func_name: %s",
*m.group("ret_type", "class_name", "func_name"),
)
type_cls_func_name = "%s %s::%s" % m.group(
"ret_type", "class_name", "func_name"
)
if type_cls_func_name in RETURN_STATEMENTS:
logging.info("type_cls_func_name:[%s] matched!", type_cls_func_name)
return RETURN_STATEMENTS[type_cls_func_name]
type_cls_name = "%s %s::" % m.group("ret_type", "class_name")
if type_cls_name in RETURN_STATEMENTS:
logging.info("type_cls_name:[%s] matched!", type_cls_name)
return RETURN_STATEMENTS[type_cls_name]
type_only = m.group("ret_type")
if type_only in RETURN_STATEMENTS:
logging.info("type_only:[%s] matched!", type_only)
return RETURN_STATEMENTS[type_only]
return None
@staticmethod
def handle_template_func_def(func, function_def):
if not func.strip().startswith("template<"):
return False, function_def
has_been_handled = False
lines = func.split("\n")
for line in lines:
line = line.strip()
if line.startswith("template<"):
continue
if re.search(r"^\w+\s+\w+::", line):
parts = line.split()
if len(parts) >= 2:
return_type = parts[0]
if RETURN_STATEMENTS.__contains__(return_type):
function_def += RETURN_STATEMENTS[return_type]
logging.info("Template func get return type:%s", return_type)
has_been_handled = True
break
if not has_been_handled:
if "graphStatus" in func:
function_def += RETURN_STATEMENTS["graphStatus"]
logging.info("Template func using default return type: graphStatus")
has_been_handled = True
else:
logging.info("Unhandled template func:%s", func)
logging.warning("Cannot determine return type for template function")
return has_been_handled, function_def
@staticmethod
def implement_function(func):
function_def = ""
if func.strip() == "OpImplRegister::OpImplRegister(const ge::char_t *op_type)":
function_def += " : functions_(OpImplRegistry::GetInstance().CreateOrGetOpImpl(op_type))\n"
function_def += "{\n"
return_statements = H2CC.get_return_statements(func)
if return_statements is not None:
function_def += return_statements
else:
template_result = H2CC.handle_template_func_def(func, function_def)
if template_result[0]:
function_def = template_result[1]
elif not re.search(r"::\w+(?=\()", func):
all_items = func.split()
start = 0
return_type = all_items[start]
if return_type == "extern":
return_type = all_items[2]
if return_type == "const":
start += 1
return_type = all_items[start]
if return_type.startswith(("std::map", "std::set", "std::vector")):
return_type = return_type[0 : return_type.index("<")]
if (
return_type.endswith("*")
or (
len(all_items) > start + 1
and all_items[start + 1].startswith("*")
)
or return_type.startswith("std::unique_ptr")
or return_type.startswith("std::shared_ptr")
):
return_type = "Ptr"
if len(all_items) > start + 1 and all_items[start + 1].startswith("&"):
return_type += "&"
if RETURN_STATEMENTS.__contains__(return_type):
function_def += RETURN_STATEMENTS[return_type]
else:
logging.info("Unhandled func:%s", func)
logging.warning("Unhandled return type:%s", return_type)
function_def += "\n"
function_def += "}\n"
function_def += "\n"
return function_def
def collect_header_files(inc_file):
shared_includes_content = []
inc_dirs = [
"inc/external/",
"inc/framework/",
"inc/",
"runtime/v1/",
"metadef/base/",
"base/",
"metadef/register/",
"metadef/third_party/transformer/src/",
"include/register/",
"graph_metadef/",
]
for inc_dir in inc_dirs:
if inc_file.find(inc_dir) != -1:
include_str = '#include "{}"\n'.format(
inc_file[inc_file.index(inc_dir) + len(inc_dir) :]
)
shared_includes_content.append(include_str)
break
else:
logging.error("please check inc_dirs")
pattern = r"/cann[0-9\.\-]{0,10}/include/(.*)$"
match = re.search(pattern, inc_file)
if match:
captured_path = match.group(1)
include_str = '#include "{}"\n'.format(captured_path)
shared_includes_content.append(include_str)
shared_includes_content.append("#include <iostream>\n")
need_any_value_headers = [
"op_impl_registry_base.h",
"op_impl_registry_holder_manager.h",
]
if inc_file.endswith("op_def.h"):
shared_includes_content.append('#include "opdef/op_def_impl.h"\n')
elif inc_file.endswith("operator.h"):
shared_includes_content.append('#include "graph/graph.h"\n')
elif inc_file.endswith("ascend_string.h"):
shared_includes_content.append('#include "common/util/mem_utils.h"\n')
shared_includes_content.append('#include "graph/ascend_string.h"\n')
elif inc_file.endswith("tensor.h"):
shared_includes_content.append('#include "graph/tensor.h"\n')
elif inc_file.endswith("types.h"):
shared_includes_content.append('#include "graph/types.h"\n')
elif len([var for var in need_any_value_headers if inc_file.endswith(var)]) > 0:
shared_includes_content.append('#include "graph/any_value.h"\n')
return shared_includes_content
def generate_stub_file(inc_file, out_cc_dir):
"""
:param inc_file:
:param out_cc_dir:
:return:
"""
shared_includes_content = collect_header_files(inc_file)
cc_file = re.sub(r"([^/]+)\.h$", r"stub_\1.cc", inc_file)
h_2_cc = H2CC(
inc_file,
out_cc_dir + cc_file[cc_file.rindex("/") + 1 :],
shared_includes_content,
)
h_2_cc.h2cc()
def gen_code(inc_files, out_cc_dir):
"""
:param inc_files:
:param out_cc_dir:
:return:
"""
if not out_cc_dir.endswith("/"):
out_cc_dir += "/"
for inc_file in inc_files:
if not os.path.isabs(inc_file):
logging.warning(
"inc_file:[%s] not absolute path, and will be ignored.", inc_file
)
continue
generate_stub_file(inc_file, out_cc_dir)
def main():
if len(sys.argv) < 3:
logging.error("script %s must have 2 input parameters!", sys.argv[0])
return
out_cc_dir = sys.argv[1]
inc_files = sys.argv[2:]
gen_code(inc_files, out_cc_dir)
if __name__ == "__main__":
main()