Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dashen
graphengine
提交
5ba85c0f
G
graphengine
项目概览
dashen
/
graphengine
与 Fork 源项目一致
Fork自
MindSpore / graphengine
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
graphengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5ba85c0f
编写于
8月 04, 2020
作者:
Z
zhangzhenghai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
remove stubs
上级
1becd81e
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
0 addition
and
1162 deletion
+0
-1162
src/common/graph/stub/Makefile
src/common/graph/stub/Makefile
+0
-6
src/common/graph/stub/gen_stubapi.py
src/common/graph/stub/gen_stubapi.py
+0
-573
src/ge/stub/Makefile
src/ge/stub/Makefile
+0
-6
src/ge/stub/README
src/ge/stub/README
+0
-4
src/ge/stub/gen_stubapi.py
src/ge/stub/gen_stubapi.py
+0
-573
未找到文件。
src/common/graph/stub/Makefile
已删除
100644 → 0
浏览文件 @
1becd81e
inc_path
:=
$(
shell
pwd
)
/inc/external/
out_path
:=
$(
shell
pwd
)
/out/atc/lib64/stub/
stub_path
:=
$(
shell
pwd
)
/common/graph/stub/
mkdir_stub
:=
$(
shell
mkdir
-p
$(out_path)
)
graph_local_stub
:=
$(
shell
$(HI_PYTHON)
$(stub_path)
/gen_stubapi.py
$(inc_path)
$(out_path)
)
src/common/graph/stub/gen_stubapi.py
已删除
100644 → 0
浏览文件 @
1becd81e
import
os
import
re
import
sys
import
logging
logging
.
basicConfig
(
stream
=
sys
.
stdout
,
format
=
'[%(asctime)s] [%(lineno)s] %(levelname)s: %(message)s'
,
level
=
logging
.
INFO
)
"""
this attr is used for symbol table visible
"""
GE_ATTR
=
'GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY'
"""
generate stub func body by return type
"""
RETURN_STATEMENTS
=
{
'graphStatus'
:
' return GRAPH_SUCCESS;'
,
'Status'
:
' return SUCCESS;'
,
'Graph'
:
' return Graph();'
,
'Graph&'
:
' return *this;'
,
'Format'
:
' return Format();'
,
'Format&'
:
' return *this;'
,
'Shape'
:
' return Shape();'
,
'Shape&'
:
' return *this;'
,
'TensorDesc'
:
' return TensorDesc();'
,
'TensorDesc&'
:
' return *this;'
,
'Tensor'
:
' return Tensor();'
,
'Tensor&'
:
' return *this;'
,
'Operator'
:
' return Operator();'
,
'Operator&'
:
' return *this;'
,
'Ptr'
:
' return nullptr;'
,
'std::string'
:
' return "";'
,
'std::string&'
:
' return "";'
,
'string'
:
' return "";'
,
'int'
:
' return 0;'
,
'DataType'
:
' return DT_FLOAT;'
,
'InferenceContextPtr'
:
' return nullptr;'
,
'SubgraphBuilder'
:
' return nullptr;'
,
'OperatorImplPtr'
:
' return nullptr;'
,
'OutHandler'
:
' return nullptr;'
,
'std::vector<std::string>'
:
' return {};'
,
'std::vector<int64_t>'
:
' return {};'
,
'std::map'
:
' return {};'
,
'uint32_t'
:
' return 0;'
,
'int64_t'
:
' return 0;'
,
'uint64_t'
:
' return 0;'
,
'size_t'
:
' return 0;'
,
'float'
:
' return 0.0f;'
,
'bool'
:
' return false;'
,
}
"""
max code len per line in hua_wei software programming specifications
"""
max_code_len_per_line
=
100
"""
white_list_for_debug, include_dir_key_words is to
determines which header files to generate cc files from
when DEBUG on
"""
white_list_for_debug
=
[
"operator.h"
,
"tensor.h"
,
"graph.h"
,
"operator_factory.h"
,
"ge_ir_build.h"
]
include_dir_key_words
=
[
"ge"
,
"graph"
]
DEBUG
=
True
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
def
file_endswith_white_list_suffix
(
file
):
"""
:param file:
:return:
"""
if
DEBUG
:
for
suffix
in
white_list_for_debug
:
if
file
.
endswith
(
suffix
):
return
True
return
False
else
:
return
True
"""
belows are patterns used for analyse .h file
"""
# pattern function
pattern_func
=
re
.
compile
(
r
"""(^[\s]*) #leading with space,we will find and delete after
([a-zA-Z~_] # void int likely
.*
[)] #we find )
(?!.*{) # we do not want the case int abc() const { return 1;}
.*)
(;.*) #we want to find ; and after for we will replace these later
\n$
"""
,
re
.
VERBOSE
|
re
.
MULTILINE
|
re
.
DOTALL
)
# pattern comment
pattern_comment
=
re
.
compile
(
r
'^\s*//'
)
pattern_comment_2_start
=
re
.
compile
(
r
'^\s*/[*]'
)
pattern_comment_2_end
=
re
.
compile
(
r
'[*]/\s*$'
)
# pattern define
pattern_define
=
re
.
compile
(
r
'^\s*#define'
)
pattern_define_return
=
re
.
compile
(
r
'\\\s*$'
)
# blank line
pattern_blank_line
=
re
.
compile
(
r
'^\s*$'
)
# virtual,explicit,friend,static
pattern_keyword
=
re
.
compile
(
r
'(virtual\s+|explicit\s+|friend\s+|static\s+)'
)
# lead space
pattern_leading_space
=
re
.
compile
(
r
'(^[\s]*)[a-zA-Z~_]'
)
# functions will have patterns such as func ( or func(
# but operator is an exception; the class name is preceded by an operator, and the above mode does not exist
# format like :"operator = ()"
pattern_func_name
=
re
.
compile
(
r
'([a-zA-Z0-9~_\-]+\s*|operator?.*)[(]'
)
# template
pattern_template
=
re
.
compile
(
r
'^\s*template'
)
pattern_template_end
=
re
.
compile
(
r
'>\s*$'
)
# namespace
pattern_namespace
=
re
.
compile
(
r
'namespace.*{'
)
# class : which can handle classA a and {not on the same line, but if found ';' after class,then don't deal with
pattern_class
=
re
.
compile
(
r
'^[\s]*(class|struct)\s+(%s\s+)?([a-zA-Z0-9_\-]+<?)(?!.*;)'
%
GE_ATTR
)
# {}
pattern_start
=
re
.
compile
(
'{'
)
pattern_end
=
re
.
compile
(
'}'
)
line_index
=
0
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
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'
)
# The state may be normal_now(in the middle of {}),class_now,namespace_now
self
.
stack
=
[]
self
.
stack_class
=
[]
self
.
stack_template
=
[]
# record funcs generated by h2cc func
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
):
# skip blank line or comment
if
pattern_blank_line
.
search
(
self
.
input_content
[
self
.
line_index
])
or
pattern_comment
.
search
(
self
.
input_content
[
self
.
line_index
]):
# /n or comment using //
self
.
line_index
+=
1
if
pattern_comment_2_start
.
search
(
self
.
input_content
[
self
.
line_index
]):
# comment using /*
while
not
pattern_comment_2_end
.
search
(
self
.
input_content
[
self
.
line_index
]):
# */
self
.
line_index
+=
1
self
.
line_index
+=
1
# skip define
if
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
def
write_inc_content
(
self
):
for
shared_include_content
in
self
.
shared_includes_content
:
self
.
output_fd
.
write
(
shared_include_content
)
def
h2cc
(
self
):
"""
:return:
"""
logging
.
info
(
"start generate cc_file[%s] from h_file[%s]"
,
self
.
output_file
,
self
.
input_file
)
global
pattern_comment
global
pattern_comment_2_start
global
pattern_comment_2_end
global
pattern_blank_line
global
pattern_func
global
pattern_keyword
global
pattern_leading_space
global
pattern_func_name
global
pattern_template
global
pattern_template_end
global
pattern_namespace
global
pattern_class
global
pattern_start
global
pattern_end
global
line_index
# write inc content
self
.
write_inc_content
()
# core processing cycle, process the input .h file by line
while
self
.
line_index
<
len
(
self
.
input_content
):
# handle comment and blank line
self
.
just_skip
()
# match namespace
self
.
handle_namespace
()
# match template
template_string
=
self
.
handle_template
()
# match class
line
=
self
.
input_content
[
self
.
line_index
]
match_class
=
pattern_class
.
search
(
line
)
match_start
=
pattern_start
.
search
(
line
)
handle_class_result
=
self
.
handle_class
(
template_string
,
line
,
match_start
,
match_class
)
if
handle_class_result
==
"continue"
:
continue
# match "}"
handle_stack_result
=
self
.
handle_stack
(
match_start
)
if
handle_stack_result
==
"continue"
:
continue
# handle func
handle_func1_result
,
line
,
start_i
=
self
.
handle_func1
(
line
)
if
handle_func1_result
==
"continue"
:
continue
# here means func is found
# delete key word
line
=
pattern_keyword
.
sub
(
''
,
line
)
logging
.
info
(
"line[%s]"
,
line
)
# Class member function
# if friend we will not add class name
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
)
# Normal functions
else
:
line
,
func_name
=
self
.
handle_normal_func
(
line
,
template_string
)
need_generate
=
need_generate_func
(
line
)
# func body
line
+=
self
.
implement_function
(
line
)
# comment
line
=
self
.
gen_comment
(
start_i
)
+
line
# write to out file
self
.
write_func_content
(
line
,
func_name
,
need_generate
)
# next loop
self
.
line_index
+=
1
logging
.
info
(
'Added %s functions'
,
len
(
self
.
func_list_exist
))
logging
.
info
(
'Successfully converted,please see '
+
self
.
output_file
)
def
handle_func1
(
self
,
line
):
"""
:param line:
:return:
"""
find1
=
re
.
search
(
'[(]'
,
line
)
if
not
find1
:
self
.
line_index
+=
1
return
"continue"
,
line
,
None
find2
=
re
.
search
(
'[)]'
,
line
)
start_i
=
self
.
line_index
space_match
=
pattern_leading_space
.
search
(
line
)
# deal with
# int abc(int a,
# int b)
if
find1
and
(
not
find2
):
self
.
line_index
+=
1
line2
=
self
.
input_content
[
self
.
line_index
]
if
space_match
:
line2
=
re
.
sub
(
'^'
+
space_match
.
group
(
1
),
''
,
line2
)
line
+=
line2
while
self
.
line_index
<
len
(
self
.
input_content
)
and
(
not
re
.
search
(
'[)]'
,
line2
)):
self
.
line_index
+=
1
line2
=
self
.
input_content
[
self
.
line_index
]
line2
=
re
.
sub
(
'^'
+
space_match
.
group
(
1
),
''
,
line2
)
line
+=
line2
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
:
# like ) { or ) {} int the last line
if
not
match_end
:
self
.
stack
.
append
(
'normal_now'
)
ii
=
start_i
while
ii
<=
self
.
line_index
:
ii
+=
1
self
.
line_index
+=
1
return
"continue"
,
line
,
start_i
logging
.
info
(
"line[%s]"
,
line
)
# ' int abc();'->'int abc()'
(
line
,
match
)
=
pattern_func
.
subn
(
r
'\2\n'
,
line
)
logging
.
info
(
"line[%s]"
,
line
)
# deal with case:
# 'int \n abc(int a, int b)'
if
re
.
search
(
r
'^\s*(inline)?\s*[a-zA-Z0-9_]+\s*$'
,
self
.
input_content
[
start_i
-
1
]):
line
=
self
.
input_content
[
start_i
-
1
]
+
line
line
=
line
.
lstrip
()
if
not
match
:
self
.
line_index
+=
1
return
"continue"
,
line
,
start_i
return
"pass"
,
line
,
start_i
def
handle_stack
(
self
,
match_start
):
"""
:param match_start:
:return:
"""
line
=
self
.
input_content
[
self
.
line_index
]
match_end
=
pattern_end
.
search
(
line
)
if
match_start
:
self
.
stack
.
append
(
'normal_now'
)
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
,
match_class
):
"""
:param template_string:
:param line:
:param match_start:
:param match_class:
:return:
"""
if
match_class
:
# we face a class
self
.
stack_template
.
append
(
template_string
)
self
.
stack
.
append
(
'class_now'
)
class_name
=
match_class
.
group
(
3
)
# class template specializations: class A<u,Node<u> >
if
'<'
in
class_name
:
k
=
line
.
index
(
'<'
)
fit
=
1
for
ii
in
range
(
k
+
1
,
len
(
line
)):
if
line
[
ii
]
==
'<'
:
fit
+=
1
if
line
[
ii
]
==
'>'
:
fit
-=
1
if
fit
==
0
:
break
class_name
+=
line
[
k
+
1
:
ii
+
1
]
logging
.
info
(
'class_name[%s]'
,
class_name
)
self
.
stack_class
.
append
(
class_name
)
while
not
match_start
:
self
.
line_index
+=
1
line
=
self
.
input_content
[
self
.
line_index
]
match_start
=
pattern_start
.
search
(
line
)
self
.
line_index
+=
1
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
:
match_template_end
=
pattern_template_end
.
search
(
line
)
template_string
=
line
while
not
match_template_end
:
self
.
line_index
+=
1
line
=
self
.
input_content
[
self
.
line_index
]
template_string
+=
line
match_template_end
=
pattern_template_end
.
search
(
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
:
# we face namespace
self
.
output_fd
.
write
(
line
+
'
\n
'
)
self
.
stack
.
append
(
'namespace_now'
)
self
.
line_index
+=
1
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
])
# change '< class T = a, class U = A(3)>' to '<class T, class U>'
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
=
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*>'
,
stack_template
[
-
1
])):
template_line
=
re
.
sub
(
r
'^\s*template'
,
'template'
,
stack_template
[
-
1
])
if
not
(
re
.
search
(
r
'<.*>'
,
self
.
stack_class
[
-
1
])):
# for x we get like template<class T, typename U> -> <T,U>
x
=
re
.
sub
(
r
'template\s*<'
,
'<'
,
template_line
)
# remove template -> <class T, typename U>
x
=
re
.
sub
(
r
'\n'
,
''
,
x
)
x
=
re
.
sub
(
r
'\s*=.*,'
,
','
,
x
)
x
=
re
.
sub
(
r
'\s*=.*\>'
,
'>'
,
x
)
x
=
x
.
rstrip
()
# remove \n
x
=
re
.
sub
(
r
'(class|typename)\s+|(<class>|<typename>\s*class)'
,
''
,
x
)
# remove class,typename -> <T, U>
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]
\n
line[%s]"
,
x
,
line
)
# if the function is long, void ABC::foo()
# breaks into two lines void ABC::\n foo()
temp_line
=
pattern_func_name
.
sub
(
self
.
stack_class
[
-
1
]
+
x
+
'::'
+
r
'\1('
,
line
,
count
=
1
)
if
len
(
temp_line
)
>
max_code_len_per_line
:
line
=
pattern_func_name
.
sub
(
self
.
stack_class
[
-
1
]
+
x
+
'::
\n
'
+
r
'\1('
,
line
,
count
=
1
)
else
:
line
=
temp_line
logging
.
info
(
"line[%s]"
,
line
)
# add template as the above if there is one
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
()
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
not
(
func_name
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
=
''
# Function comments are on top of function declarations, copy them over
k
=
start_i
-
1
# one line before this func start
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
implement_function
(
func
):
function_def
=
''
function_def
+=
'{
\n
'
all_items
=
func
.
split
()
start
=
0
return_type
=
all_items
[
start
]
if
return_type
==
"const"
:
start
+=
1
return_type
=
all_items
[
start
]
if
return_type
.
startswith
((
'std::map'
,
'std::set'
,
'std::vector'
)):
return_type
=
"std::map"
if
return_type
.
endswith
(
'*'
)
or
(
len
(
all_items
)
>
start
+
1
and
all_items
[
start
+
1
].
startswith
(
'*'
)):
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
.
warning
(
"Unhandled return type[%s]"
,
return_type
)
function_def
+=
'
\n
'
function_def
+=
'}
\n
'
function_def
+=
'
\n
'
return
function_def
def
collect_header_files
(
path
):
"""
:param path:
:return:
"""
header_files
=
[]
shared_includes_content
=
[]
for
root
,
dirs
,
files
in
os
.
walk
(
path
):
files
.
sort
()
for
file
in
files
:
if
file
.
find
(
"git"
)
>=
0
:
continue
if
not
file
.
endswith
(
'.h'
):
continue
file_path
=
os
.
path
.
join
(
root
,
file
)
file_path
=
file_path
.
replace
(
'
\\
'
,
'/'
)
header_files
.
append
(
file_path
)
include_str
=
'#include "{}"
\n
'
.
format
(
file_path
[
path
.
rindex
(
'/'
)
+
1
:])
shared_includes_content
.
append
(
include_str
)
return
header_files
,
shared_includes_content
def
generate_stub_file
(
inc_dir
,
out_cc_dir
):
"""
:param inc_dir:
:param out_cc_dir:
:return:
"""
target_header_files
,
shared_includes_content
=
collect_header_files
(
inc_dir
)
for
header_file
in
target_header_files
:
if
not
file_endswith_white_list_suffix
(
header_file
):
continue
cc_file
=
re
.
sub
(
'.h*$'
,
'.cc'
,
header_file
)
h_2_cc
=
H2CC
(
header_file
,
out_cc_dir
+
cc_file
[
cc_file
.
rindex
(
'/'
)
+
1
:],
shared_includes_content
)
h_2_cc
.
h2cc
()
def
gen_code
(
inc_dir
,
out_cc_dir
):
"""
:param inc_dir:
:param out_cc_dir:
:return:
"""
if
not
inc_dir
.
endswith
(
'/'
):
inc_dir
+=
'/'
if
not
out_cc_dir
.
endswith
(
'/'
):
out_cc_dir
+=
'/'
for
include_dir_key_word
in
include_dir_key_words
:
generate_stub_file
(
inc_dir
+
include_dir_key_word
,
out_cc_dir
)
if
__name__
==
'__main__'
:
inc_dir
=
sys
.
argv
[
1
]
out_cc_dir
=
sys
.
argv
[
2
]
gen_code
(
inc_dir
,
out_cc_dir
)
src/ge/stub/Makefile
已删除
100644 → 0
浏览文件 @
1becd81e
inc_path
:=
$(
shell
pwd
)
/inc/external/
out_path
:=
$(
shell
pwd
)
/out/atc/lib64/stub/
stub_path
:=
$(
shell
pwd
)
/framework/domi/stub/
mkdir_stub
:=
$(
shell
mkdir
-p
$(out_path)
)
local_stub
:=
$(
shell
$(HI_PYTHON)
$(stub_path)
/gen_stubapi.py
$(inc_path)
$(out_path)
)
src/ge/stub/README
已删除
100644 → 0
浏览文件 @
1becd81e
###################################################################################
the directory (stub) saves the stub file
gen_stubapi.py is using for retrieving API and generating stub functions
###################################################################################
src/ge/stub/gen_stubapi.py
已删除
100644 → 0
浏览文件 @
1becd81e
import
os
import
re
import
sys
import
logging
logging
.
basicConfig
(
stream
=
sys
.
stdout
,
format
=
'[%(asctime)s] [%(lineno)s] %(levelname)s: %(message)s'
,
level
=
logging
.
INFO
)
"""
this attr is used for symbol table visible
"""
GE_ATTR
=
'GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY'
"""
generate stub func body by return type
"""
RETURN_STATEMENTS
=
{
'graphStatus'
:
' return GRAPH_SUCCESS;'
,
'Status'
:
' return SUCCESS;'
,
'Graph'
:
' return Graph();'
,
'Graph&'
:
' return *this;'
,
'Format'
:
' return Format();'
,
'Format&'
:
' return *this;'
,
'Shape'
:
' return Shape();'
,
'Shape&'
:
' return *this;'
,
'TensorDesc'
:
' return TensorDesc();'
,
'TensorDesc&'
:
' return *this;'
,
'Tensor'
:
' return Tensor();'
,
'Tensor&'
:
' return *this;'
,
'Operator'
:
' return Operator();'
,
'Operator&'
:
' return *this;'
,
'Ptr'
:
' return nullptr;'
,
'std::string'
:
' return "";'
,
'std::string&'
:
' return "";'
,
'string'
:
' return "";'
,
'int'
:
' return 0;'
,
'DataType'
:
' return DT_FLOAT;'
,
'InferenceContextPtr'
:
' return nullptr;'
,
'SubgraphBuilder'
:
' return nullptr;'
,
'OperatorImplPtr'
:
' return nullptr;'
,
'OutHandler'
:
' return nullptr;'
,
'std::vector<std::string>'
:
' return {};'
,
'std::vector<int64_t>'
:
' return {};'
,
'std::map'
:
' return {};'
,
'uint32_t'
:
' return 0;'
,
'int64_t'
:
' return 0;'
,
'uint64_t'
:
' return 0;'
,
'size_t'
:
' return 0;'
,
'float'
:
' return 0.0f;'
,
'bool'
:
' return false;'
,
}
"""
max code len per line in hua_wei software programming specifications
"""
max_code_len_per_line
=
100
"""
white_list_for_debug, include_dir_key_words is to
determines which header files to generate cc files from
when DEBUG on
"""
white_list_for_debug
=
[
"operator.h"
,
"tensor.h"
,
"graph.h"
,
"operator_factory.h"
,
"ge_ir_build.h"
]
include_dir_key_words
=
[
"ge"
,
"graph"
]
DEBUG
=
True
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
def
file_endswith_white_list_suffix
(
file
):
"""
:param file:
:return:
"""
if
DEBUG
:
for
suffix
in
white_list_for_debug
:
if
file
.
endswith
(
suffix
):
return
True
return
False
else
:
return
True
"""
belows are patterns used for analyse .h file
"""
# pattern function
pattern_func
=
re
.
compile
(
r
"""(^[\s]*) #leading with space,we will find and delete after
([a-zA-Z~_] # void int likely
.*
[)] #we find )
(?!.*{) # we do not want the case int abc() const { return 1;}
.*)
(;.*) #we want to find ; and after for we will replace these later
\n$
"""
,
re
.
VERBOSE
|
re
.
MULTILINE
|
re
.
DOTALL
)
# pattern comment
pattern_comment
=
re
.
compile
(
r
'^\s*//'
)
pattern_comment_2_start
=
re
.
compile
(
r
'^\s*/[*]'
)
pattern_comment_2_end
=
re
.
compile
(
r
'[*]/\s*$'
)
# pattern define
pattern_define
=
re
.
compile
(
r
'^\s*#define'
)
pattern_define_return
=
re
.
compile
(
r
'\\\s*$'
)
# blank line
pattern_blank_line
=
re
.
compile
(
r
'^\s*$'
)
# virtual,explicit,friend,static
pattern_keyword
=
re
.
compile
(
r
'(virtual\s+|explicit\s+|friend\s+|static\s+)'
)
# lead space
pattern_leading_space
=
re
.
compile
(
r
'(^[\s]*)[a-zA-Z~_]'
)
# functions will have patterns such as func ( or func(
# but operator is an exception; the class name is preceded by an operator, and the above mode does not exist
# format like :"operator = ()"
pattern_func_name
=
re
.
compile
(
r
'([a-zA-Z0-9~_\-]+\s*|operator?.*)[(]'
)
# template
pattern_template
=
re
.
compile
(
r
'^\s*template'
)
pattern_template_end
=
re
.
compile
(
r
'>\s*$'
)
# namespace
pattern_namespace
=
re
.
compile
(
r
'namespace.*{'
)
# class : which can handle classA a and {not on the same line, but if found ';' after class,then don't deal with
pattern_class
=
re
.
compile
(
r
'^[\s]*(class|struct)\s+(%s\s+)?([a-zA-Z0-9_\-]+<?)(?!.*;)'
%
GE_ATTR
)
# {}
pattern_start
=
re
.
compile
(
'{'
)
pattern_end
=
re
.
compile
(
'}'
)
line_index
=
0
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
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'
)
# The state may be normal_now(in the middle of {}),class_now,namespace_now
self
.
stack
=
[]
self
.
stack_class
=
[]
self
.
stack_template
=
[]
# record funcs generated by h2cc func
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
):
# skip blank line or comment
if
pattern_blank_line
.
search
(
self
.
input_content
[
self
.
line_index
])
or
pattern_comment
.
search
(
self
.
input_content
[
self
.
line_index
]):
# /n or comment using //
self
.
line_index
+=
1
if
pattern_comment_2_start
.
search
(
self
.
input_content
[
self
.
line_index
]):
# comment using /*
while
not
pattern_comment_2_end
.
search
(
self
.
input_content
[
self
.
line_index
]):
# */
self
.
line_index
+=
1
self
.
line_index
+=
1
# skip define
if
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
def
write_inc_content
(
self
):
for
shared_include_content
in
self
.
shared_includes_content
:
self
.
output_fd
.
write
(
shared_include_content
)
def
h2cc
(
self
):
"""
:return:
"""
logging
.
info
(
"start generate cc_file[%s] from h_file[%s]"
,
self
.
output_file
,
self
.
input_file
)
global
pattern_comment
global
pattern_comment_2_start
global
pattern_comment_2_end
global
pattern_blank_line
global
pattern_func
global
pattern_keyword
global
pattern_leading_space
global
pattern_func_name
global
pattern_template
global
pattern_template_end
global
pattern_namespace
global
pattern_class
global
pattern_start
global
pattern_end
global
line_index
# write inc content
self
.
write_inc_content
()
# core processing cycle, process the input .h file by line
while
self
.
line_index
<
len
(
self
.
input_content
):
# handle comment and blank line
self
.
just_skip
()
# match namespace
self
.
handle_namespace
()
# match template
template_string
=
self
.
handle_template
()
# match class
line
=
self
.
input_content
[
self
.
line_index
]
match_class
=
pattern_class
.
search
(
line
)
match_start
=
pattern_start
.
search
(
line
)
handle_class_result
=
self
.
handle_class
(
template_string
,
line
,
match_start
,
match_class
)
if
handle_class_result
==
"continue"
:
continue
# match "}"
handle_stack_result
=
self
.
handle_stack
(
match_start
)
if
handle_stack_result
==
"continue"
:
continue
# handle func
handle_func1_result
,
line
,
start_i
=
self
.
handle_func1
(
line
)
if
handle_func1_result
==
"continue"
:
continue
# here means func is found
# delete key word
line
=
pattern_keyword
.
sub
(
''
,
line
)
logging
.
info
(
"line[%s]"
,
line
)
# Class member function
# if friend we will not add class name
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
)
# Normal functions
else
:
line
,
func_name
=
self
.
handle_normal_func
(
line
,
template_string
)
need_generate
=
need_generate_func
(
line
)
# func body
line
+=
self
.
implement_function
(
line
)
# comment
line
=
self
.
gen_comment
(
start_i
)
+
line
# write to out file
self
.
write_func_content
(
line
,
func_name
,
need_generate
)
# next loop
self
.
line_index
+=
1
logging
.
info
(
'Added %s functions'
,
len
(
self
.
func_list_exist
))
logging
.
info
(
'Successfully converted,please see '
+
self
.
output_file
)
def
handle_func1
(
self
,
line
):
"""
:param line:
:return:
"""
find1
=
re
.
search
(
'[(]'
,
line
)
if
not
find1
:
self
.
line_index
+=
1
return
"continue"
,
line
,
None
find2
=
re
.
search
(
'[)]'
,
line
)
start_i
=
self
.
line_index
space_match
=
pattern_leading_space
.
search
(
line
)
# deal with
# int abc(int a,
# int b)
if
find1
and
(
not
find2
):
self
.
line_index
+=
1
line2
=
self
.
input_content
[
self
.
line_index
]
if
space_match
:
line2
=
re
.
sub
(
'^'
+
space_match
.
group
(
1
),
''
,
line2
)
line
+=
line2
while
self
.
line_index
<
len
(
self
.
input_content
)
and
(
not
re
.
search
(
'[)]'
,
line2
)):
self
.
line_index
+=
1
line2
=
self
.
input_content
[
self
.
line_index
]
line2
=
re
.
sub
(
'^'
+
space_match
.
group
(
1
),
''
,
line2
)
line
+=
line2
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
:
# like ) { or ) {} int the last line
if
not
match_end
:
self
.
stack
.
append
(
'normal_now'
)
ii
=
start_i
while
ii
<=
self
.
line_index
:
ii
+=
1
self
.
line_index
+=
1
return
"continue"
,
line
,
start_i
logging
.
info
(
"line[%s]"
,
line
)
# ' int abc();'->'int abc()'
(
line
,
match
)
=
pattern_func
.
subn
(
r
'\2\n'
,
line
)
logging
.
info
(
"line[%s]"
,
line
)
# deal with case:
# 'int \n abc(int a, int b)'
if
re
.
search
(
r
'^\s*(inline)?\s*[a-zA-Z0-9_]+\s*$'
,
self
.
input_content
[
start_i
-
1
]):
line
=
self
.
input_content
[
start_i
-
1
]
+
line
line
=
line
.
lstrip
()
if
not
match
:
self
.
line_index
+=
1
return
"continue"
,
line
,
start_i
return
"pass"
,
line
,
start_i
def
handle_stack
(
self
,
match_start
):
"""
:param match_start:
:return:
"""
line
=
self
.
input_content
[
self
.
line_index
]
match_end
=
pattern_end
.
search
(
line
)
if
match_start
:
self
.
stack
.
append
(
'normal_now'
)
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
,
match_class
):
"""
:param template_string:
:param line:
:param match_start:
:param match_class:
:return:
"""
if
match_class
:
# we face a class
self
.
stack_template
.
append
(
template_string
)
self
.
stack
.
append
(
'class_now'
)
class_name
=
match_class
.
group
(
3
)
# class template specializations: class A<u,Node<u> >
if
'<'
in
class_name
:
k
=
line
.
index
(
'<'
)
fit
=
1
for
ii
in
range
(
k
+
1
,
len
(
line
)):
if
line
[
ii
]
==
'<'
:
fit
+=
1
if
line
[
ii
]
==
'>'
:
fit
-=
1
if
fit
==
0
:
break
class_name
+=
line
[
k
+
1
:
ii
+
1
]
logging
.
info
(
'class_name[%s]'
,
class_name
)
self
.
stack_class
.
append
(
class_name
)
while
not
match_start
:
self
.
line_index
+=
1
line
=
self
.
input_content
[
self
.
line_index
]
match_start
=
pattern_start
.
search
(
line
)
self
.
line_index
+=
1
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
:
match_template_end
=
pattern_template_end
.
search
(
line
)
template_string
=
line
while
not
match_template_end
:
self
.
line_index
+=
1
line
=
self
.
input_content
[
self
.
line_index
]
template_string
+=
line
match_template_end
=
pattern_template_end
.
search
(
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
:
# we face namespace
self
.
output_fd
.
write
(
line
+
'
\n
'
)
self
.
stack
.
append
(
'namespace_now'
)
self
.
line_index
+=
1
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
])
# change '< class T = a, class U = A(3)>' to '<class T, class U>'
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
=
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*>'
,
stack_template
[
-
1
])):
template_line
=
re
.
sub
(
r
'^\s*template'
,
'template'
,
stack_template
[
-
1
])
if
not
(
re
.
search
(
r
'<.*>'
,
self
.
stack_class
[
-
1
])):
# for x we get like template<class T, typename U> -> <T,U>
x
=
re
.
sub
(
r
'template\s*<'
,
'<'
,
template_line
)
# remove template -> <class T, typename U>
x
=
re
.
sub
(
r
'\n'
,
''
,
x
)
x
=
re
.
sub
(
r
'\s*=.*,'
,
','
,
x
)
x
=
re
.
sub
(
r
'\s*=.*\>'
,
'>'
,
x
)
x
=
x
.
rstrip
()
# remove \n
x
=
re
.
sub
(
r
'(class|typename)\s+|(<class>|<typename>\s*class)'
,
''
,
x
)
# remove class,typename -> <T, U>
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]
\n
line[%s]"
,
x
,
line
)
# if the function is long, void ABC::foo()
# breaks into two lines void ABC::\n foo()
temp_line
=
pattern_func_name
.
sub
(
self
.
stack_class
[
-
1
]
+
x
+
'::'
+
r
'\1('
,
line
,
count
=
1
)
if
len
(
temp_line
)
>
max_code_len_per_line
:
line
=
pattern_func_name
.
sub
(
self
.
stack_class
[
-
1
]
+
x
+
'::
\n
'
+
r
'\1('
,
line
,
count
=
1
)
else
:
line
=
temp_line
logging
.
info
(
"line[%s]"
,
line
)
# add template as the above if there is one
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
()
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
not
(
func_name
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
=
''
# Function comments are on top of function declarations, copy them over
k
=
start_i
-
1
# one line before this func start
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
implement_function
(
func
):
function_def
=
''
function_def
+=
'{
\n
'
all_items
=
func
.
split
()
start
=
0
return_type
=
all_items
[
start
]
if
return_type
==
"const"
:
start
+=
1
return_type
=
all_items
[
start
]
if
return_type
.
startswith
((
'std::map'
,
'std::set'
,
'std::vector'
)):
return_type
=
"std::map"
if
return_type
.
endswith
(
'*'
)
or
(
len
(
all_items
)
>
start
+
1
and
all_items
[
start
+
1
].
startswith
(
'*'
)):
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
.
warning
(
"Unhandled return type[%s]"
,
return_type
)
function_def
+=
'
\n
'
function_def
+=
'}
\n
'
function_def
+=
'
\n
'
return
function_def
def
collect_header_files
(
path
):
"""
:param path:
:return:
"""
header_files
=
[]
shared_includes_content
=
[]
for
root
,
dirs
,
files
in
os
.
walk
(
path
):
files
.
sort
()
for
file
in
files
:
if
file
.
find
(
"git"
)
>=
0
:
continue
if
not
file
.
endswith
(
'.h'
):
continue
file_path
=
os
.
path
.
join
(
root
,
file
)
file_path
=
file_path
.
replace
(
'
\\
'
,
'/'
)
header_files
.
append
(
file_path
)
include_str
=
'#include "{}"
\n
'
.
format
(
file_path
[
path
.
rindex
(
'/'
)
+
1
:])
shared_includes_content
.
append
(
include_str
)
return
header_files
,
shared_includes_content
def
generate_stub_file
(
inc_dir
,
out_cc_dir
):
"""
:param inc_dir:
:param out_cc_dir:
:return:
"""
target_header_files
,
shared_includes_content
=
collect_header_files
(
inc_dir
)
for
header_file
in
target_header_files
:
if
not
file_endswith_white_list_suffix
(
header_file
):
continue
cc_file
=
re
.
sub
(
'.h*$'
,
'.cc'
,
header_file
)
h_2_cc
=
H2CC
(
header_file
,
out_cc_dir
+
cc_file
[
cc_file
.
rindex
(
'/'
)
+
1
:],
shared_includes_content
)
h_2_cc
.
h2cc
()
def
gen_code
(
inc_dir
,
out_cc_dir
):
"""
:param inc_dir:
:param out_cc_dir:
:return:
"""
if
not
inc_dir
.
endswith
(
'/'
):
inc_dir
+=
'/'
if
not
out_cc_dir
.
endswith
(
'/'
):
out_cc_dir
+=
'/'
for
include_dir_key_word
in
include_dir_key_words
:
generate_stub_file
(
inc_dir
+
include_dir_key_word
,
out_cc_dir
)
if
__name__
==
'__main__'
:
inc_dir
=
sys
.
argv
[
1
]
out_cc_dir
=
sys
.
argv
[
2
]
gen_code
(
inc_dir
,
out_cc_dir
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录