CppUmlClass 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +86 -43
- data/exe/create_cpp_uml_class.rb +4 -2
- data/img/CppUMLClass.mp4 +0 -0
- data/img/class_color.png +0 -0
- data/img/setting.png +0 -0
- data/lib/CppUmlClass/version.rb +1 -1
- data/lib/config/setting.json +12 -2
- data/lib/config.ru +1 -1
- data/lib/cpp_uml_class.rb +6 -3
- data/lib/create_uml_class.rb +33 -74
- data/lib/css/index.css +297 -125
- data/lib/html/index.html +54 -57
- data/lib/ifdef_process.rb +160 -0
- data/lib/js/main.js +51 -12
- data/lib/wsserver.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e2cce57ea7d1f32941bb2bb012fe8a3c7786b1fa943aefb84a6060bf61aa934
|
4
|
+
data.tar.gz: 2df23ba7d848da1c4b57c1d1d2f44feacd648880934def6abba4cc25014bca77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f446514ce61a3722ff9db2311e088c547506099fef34e3a85283892d0c301924511f0db6be00f36a0f71bf02c75eaa15bac4eb7b8e386ea9147c05bbd3d80473
|
7
|
+
data.tar.gz: 8f4fcf4f7784e87b1bd67e5c1d416033bbd97b0811ef535e1f0723574b30a9531595c759930fd5fd2509dbb6c40f5e4241bff0c472dc9012b102020093605b29
|
data/README.md
CHANGED
@@ -1,75 +1,115 @@
|
|
1
1
|
# CppUmlClass
|
2
2
|
|
3
|
-
CppUmlClass
|
4
|
-
PlantUML and rufo commands
|
5
|
-
The created class diagram is displayed on the browser screen.
|
3
|
+
CppUmlClass generates C++ class diagrams from your source code.
|
4
|
+
It uses PlantUML and rufo commands to create the diagrams, which are displayed in your browser.
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
---
|
7
|
+
|
8
|
+
## Version 1.0.0 Highlights
|
9
|
+
|
10
|
+
- **Full support for ifdef/ifndef/if/else/elif/endif preprocessor directives**
|
11
|
+
- New: `lib/ifdef_process.rb` allows flexible interpretation of C/C++ preprocessors, reflected in UML analysis.
|
12
|
+
- **Flexible define management with `define_hash`**
|
13
|
+
- You can control defines and their values for analysis via the `define_hash` in the settings file (`setting.json`). This can be edited from the GUI as well.
|
14
|
+
- **Enhanced settings dialog and configuration management**
|
15
|
+
- Improved settings dialog with more intuitive editing, saving, and loading.
|
16
|
+
- **Modernized UI/UX**
|
17
|
+
- Major updates to CSS, HTML, and JS provide a modern look, responsive design, and improved usability.
|
18
|
+
- **WebSocket server and log output improvements**
|
19
|
+
- Flexible port settings and real-time, improved logging/progress display.
|
20
|
+
|
21
|
+
---
|
22
|
+
|
23
|
+
## Ruby Setup
|
24
|
+
|
25
|
+
For Ubuntu:
|
26
|
+
```sh
|
27
|
+
$ sudo apt install ruby ruby-all-dev
|
28
|
+
```
|
10
29
|
|
11
30
|
## CppUmlClass Setup
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
31
|
+
|
32
|
+
For Ubuntu:
|
33
|
+
```sh
|
34
|
+
$ sudo apt install chromium-browser
|
35
|
+
$ sudo apt install plantuml
|
36
|
+
$ sudo apt install clang-format
|
37
|
+
$ sudo apt install gcc
|
38
|
+
```
|
17
39
|
|
18
40
|
## Installation
|
19
41
|
|
20
|
-
|
42
|
+
Add the gem to your application's Gemfile by running:
|
43
|
+
|
44
|
+
```sh
|
45
|
+
$ bundle add CppUmlClass
|
46
|
+
```
|
21
47
|
|
22
|
-
|
48
|
+
If you are not using bundler, install the gem directly:
|
23
49
|
|
24
|
-
|
50
|
+
```sh
|
51
|
+
$ sudo gem install CppUmlClass
|
52
|
+
```
|
25
53
|
|
26
|
-
|
54
|
+
## Usage (GUI)
|
27
55
|
|
28
|
-
|
29
|
-
A browser-based GUI opens.
|
56
|
+
A browser-based GUI will open:
|
30
57
|
|
31
|
-
|
32
|
-
|
33
|
-
|
58
|
+
```sh
|
59
|
+
$ start_cpp_uml_class.rb
|
60
|
+
```
|
61
|
+
|
62
|
+
https://github.com/user-attachments/assets/d30ff495-5cee-4431-b35b-4c22f630ca22
|
63
|
+
|
64
|
+
## Usage (Command Line)
|
65
|
+
|
66
|
+
You can also use the command line interface:
|
34
67
|
|
35
|
-
## Usage(command line)
|
36
|
-
command line interface
|
37
68
|
```
|
38
69
|
Usage: create_cpp_uml_class.rb [options] cpp_source_directory out_file
|
39
70
|
-c config_file
|
40
71
|
```
|
41
|
-
config_file defaults to CppUmlClass/config/setting.json in your home directory.
|
72
|
+
The config_file defaults to `CppUmlClass/config/setting.json` in your home directory.
|
42
73
|
|
43
|
-
Example
|
74
|
+
Example:
|
44
75
|
|
45
|
-
|
76
|
+
```sh
|
77
|
+
$ create_cpp_uml_class.rb ~/tool/cpp_test /tmp/test.pu
|
78
|
+
```
|
46
79
|
|
80
|
+
---
|
47
81
|
|
48
|
-
##
|
82
|
+
## Class Color Support
|
49
83
|
|
50
84
|

|
51
85
|
|
52
|
-
##
|
53
|
-
|
54
|
-
-
|
55
|
-
-
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
59
|
-
-
|
60
|
-
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
86
|
+
## Settings
|
87
|
+
|
88
|
+
- PlantUML command
|
89
|
+
- Editor command for PlantUML files
|
90
|
+
- Default class color 1 and source path for color 1
|
91
|
+
- Default class color 2 and source path for color 2
|
92
|
+
- Default class color 3 and source path for color 3
|
93
|
+
- Exclude path
|
94
|
+
- define_hash
|
95
|
+
|
96
|
+
The settings file is stored at `CppUmlClass/config/setting.json` in your home directory.
|
97
|
+
|
98
|
+
**Example for define_hash:**
|
99
|
+
```json
|
100
|
+
{
|
101
|
+
"TEST3": true,
|
102
|
+
"DEBUG": 1,
|
103
|
+
"TEST_FUNC": true
|
104
|
+
}
|
105
|
+
```
|
65
106
|
|
66
107
|

|
67
108
|
|
68
|
-
|
69
|
-
|
70
109
|
## Development
|
71
110
|
|
72
|
-
To install this gem
|
111
|
+
To install this gem locally, run `bundle exec rake install`.
|
112
|
+
To release a new version, update the version in `version.rb`, then run `bundle exec rake release` (this creates a git tag, pushes commits and tags, and uploads the `.gem` file to [rubygems.org](https://rubygems.org)).
|
73
113
|
|
74
114
|
## Contributing
|
75
115
|
|
@@ -77,4 +117,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/kuwaya
|
|
77
117
|
|
78
118
|
## License
|
79
119
|
|
80
|
-
|
120
|
+
This gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
121
|
+
|
122
|
+
---
|
123
|
+
|
data/exe/create_cpp_uml_class.rb
CHANGED
@@ -37,11 +37,13 @@ end
|
|
37
37
|
json_config = config_json_hash(json)
|
38
38
|
|
39
39
|
file = "#{dir}/lib/create_uml_class.rb"
|
40
|
-
|
40
|
+
load file
|
41
|
+
file = "#{dir}/lib/ifdef_process.rb"
|
41
42
|
load file
|
42
43
|
|
43
44
|
@config = json_config
|
44
|
-
|
45
|
+
pifdef = IfdefProcess.new
|
46
|
+
uml = create_uml_class(pifdef, in_dir, out_file)
|
45
47
|
|
46
48
|
File.open(out_file, "w") do |f|
|
47
49
|
f.puts uml
|
data/img/CppUMLClass.mp4
CHANGED
Binary file
|
data/img/class_color.png
CHANGED
Binary file
|
data/img/setting.png
CHANGED
Binary file
|
data/lib/CppUmlClass/version.rb
CHANGED
data/lib/config/setting.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"version": 0.
|
2
|
+
"version": 0.3,
|
3
3
|
"setting_list": [
|
4
4
|
{
|
5
5
|
"name": "plantuml",
|
@@ -66,10 +66,20 @@
|
|
66
66
|
},
|
67
67
|
{
|
68
68
|
"name": "exclude_path",
|
69
|
-
"value": "(
|
69
|
+
"value": "(build)",
|
70
70
|
"type": "input",
|
71
71
|
"select": "",
|
72
72
|
"description": "除外するパス(正規表現)"
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"name": "define_hash",
|
76
|
+
"value": {
|
77
|
+
"DEBUG": true,
|
78
|
+
"DEBUG_PRINT2": true
|
79
|
+
},
|
80
|
+
"type": "textarea",
|
81
|
+
"select": "",
|
82
|
+
"description": "定義するdefineのリスト<br>例:<br>{<br> \"DEBUG\":true <br> \"VERSION\":1<br>}"
|
73
83
|
}
|
74
84
|
]
|
75
85
|
}
|
data/lib/config.ru
CHANGED
data/lib/cpp_uml_class.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require "server_app_base.rb"
|
3
3
|
require "kconv"
|
4
|
-
|
4
|
+
require "create_uml_class.rb"
|
5
|
+
require "ifdef_process"
|
5
6
|
|
6
7
|
class CppUmlClass < AppMainBase
|
7
8
|
def start(argv)
|
@@ -22,9 +23,9 @@ class CppUmlClass < AppMainBase
|
|
22
23
|
out_svg = out_file.gsub(File.extname(out_file), "") + ".svg"
|
23
24
|
|
24
25
|
# uml作成
|
25
|
-
|
26
|
+
pifdef = IfdefProcess.new
|
26
27
|
|
27
|
-
uml = create_uml_class(in_dir, out_file)
|
28
|
+
uml = create_uml_class(pifdef, in_dir, out_file)
|
28
29
|
|
29
30
|
File.open(out_file, "w") do |f|
|
30
31
|
f.puts uml
|
@@ -41,6 +42,8 @@ class CppUmlClass < AppMainBase
|
|
41
42
|
yield "exec error"
|
42
43
|
yield cmd
|
43
44
|
end
|
45
|
+
|
46
|
+
app_send("popup:0:終了しました。<br><hr>#{in_dir}<br>で使用されているifdefのリスト<br><hr> #{pifdef.define_list.sort.join("<br>")}")
|
44
47
|
rescue
|
45
48
|
puts $!
|
46
49
|
puts $@
|
data/lib/create_uml_class.rb
CHANGED
@@ -3,6 +3,7 @@ $LOAD_PATH << File.dirname(File.expand_path(__FILE__))
|
|
3
3
|
require "tempfile"
|
4
4
|
require "facter"
|
5
5
|
require "check_word"
|
6
|
+
require "ifdef_process"
|
6
7
|
|
7
8
|
CStruct = Struct.new(:type,
|
8
9
|
:name,
|
@@ -19,12 +20,12 @@ def get_gcc_path
|
|
19
20
|
ENV["PATH"].split(";").each do |path|
|
20
21
|
gcc_path = "#{path}\\gcc"
|
21
22
|
if File.exists? gcc_path
|
22
|
-
return "rubyw " + gcc_path + "
|
23
|
+
return "rubyw " + gcc_path + "w1 "
|
23
24
|
end
|
24
25
|
end
|
25
26
|
return ""
|
26
27
|
else
|
27
|
-
return "gcc -fpreprocessed -
|
28
|
+
return "gcc -fpreprocessed -E "
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
@@ -64,43 +65,29 @@ end
|
|
64
65
|
# フォーマット変更(clang-format)
|
65
66
|
# コメント削除(gcc)
|
66
67
|
# ifdefの処理(unifdef)
|
67
|
-
def update_source(file)
|
68
|
-
#
|
69
|
-
gcc_out_file = Tempfile.open(["gcc", File.extname(file)])
|
70
|
-
#puts gcc_out_file.path
|
71
|
-
#puts "|#{get_gcc_path} #{file} > #{gcc_out_file.path}"
|
72
|
-
open("|#{get_gcc_path} #{file} > #{gcc_out_file.path}") do |f|
|
73
|
-
if f.read =~ /error/
|
74
|
-
puts "gcc error #{f}"
|
75
|
-
return ""
|
76
|
-
end
|
77
|
-
end
|
78
|
-
#puts File.binread gcc_out_file.path
|
68
|
+
def update_source(pifdef, file)
|
69
|
+
#puts "update_source=#{file}"
|
79
70
|
# clang-format
|
80
71
|
format_out_file = Tempfile.open(["clang_format", File.extname(file)])
|
81
|
-
#
|
82
|
-
#puts "|#{get_clang_format_path} #{gcc_out_file.path} > #{format_out_file.path}"
|
83
|
-
open("|#{get_clang_format_path} #{gcc_out_file.path} > #{format_out_file.path}") do |f|
|
72
|
+
open("|#{get_clang_format_path} #{file} > #{format_out_file.path}") do |f|
|
84
73
|
if f.read =~ /No such/
|
85
|
-
puts "
|
74
|
+
puts "clang-format error #{f}"
|
86
75
|
return ""
|
87
76
|
end
|
88
77
|
end
|
89
|
-
|
90
|
-
|
91
|
-
#
|
92
|
-
|
93
|
-
#puts unifdef_out_file.path
|
94
|
-
#puts "|#{get_unifdef_path} #{format_out_file.path} > #{unifdef_out_file.path}"
|
95
|
-
open("|#{get_unifdef_path} #{gcc_out_file.path} > #{unifdef_out_file.path}") do |f|
|
96
|
-
if f.read =~ /No such/
|
78
|
+
# コメント削除
|
79
|
+
gcc_out_file = Tempfile.open(["gcc", File.extname(file)])
|
80
|
+
open("|#{get_gcc_path} #{format_out_file.path} > #{gcc_out_file.path}") do |f|
|
81
|
+
if f.read =~ /error/
|
97
82
|
puts "gcc error #{f}"
|
98
83
|
return ""
|
99
84
|
end
|
100
85
|
end
|
101
|
-
buf = File.binread
|
102
|
-
puts buf
|
103
|
-
|
86
|
+
buf = File.binread gcc_out_file.path
|
87
|
+
#puts buf
|
88
|
+
# ifdef処理
|
89
|
+
out_buf = pifdef.process_ifdef(buf, @config["define_hash"])
|
90
|
+
return out_buf.join("\n")
|
104
91
|
end
|
105
92
|
|
106
93
|
def print_uml(out, out_list)
|
@@ -110,7 +97,7 @@ def print_uml(out, out_list)
|
|
110
97
|
elsif o_list.type == :module_start
|
111
98
|
out.push "namespace #{o_list.name} {"
|
112
99
|
elsif o_list.type == :class_end
|
113
|
-
pp o_list if o_list.name == ""
|
100
|
+
#pp o_list if o_list.name == ""
|
114
101
|
out.push "class #{o_list.name} #{o_list.class_color}{"
|
115
102
|
# インスタンス変数の出力
|
116
103
|
o_list.var_list.uniq.each do |iv|
|
@@ -135,7 +122,7 @@ def print_uml(out, out_list)
|
|
135
122
|
o_list.method_list.size != 0 or
|
136
123
|
o_list.inherit_list.size != 0 or
|
137
124
|
o_list.composition_list.size != 0
|
138
|
-
pp o_list if o_list.name == ""
|
125
|
+
#pp o_list if o_list.name == ""
|
139
126
|
out.push "class #{o_list.name} {"
|
140
127
|
# インスタンス変数の出力
|
141
128
|
o_list.var_list.uniq.each do |iv|
|
@@ -164,16 +151,16 @@ def print_uml(out, out_list)
|
|
164
151
|
return out
|
165
152
|
end
|
166
153
|
|
167
|
-
def composition_list_create(in_dir, out_list)
|
154
|
+
def composition_list_create(pifdef,in_dir, out_list)
|
168
155
|
# composition_list
|
169
|
-
Dir.glob("#{in_dir}/**/*.{h,cpp,hpp}") do |file|
|
156
|
+
Dir.glob("#{in_dir}/**/*.{h,cpp,hpp,cc}") do |file|
|
170
157
|
if @config["exclude_path"].to_s != "" and file =~ Regexp.new(@config["exclude_path"])
|
171
158
|
#puts "skip #{file}"
|
172
159
|
next
|
173
160
|
end
|
174
|
-
#puts file
|
161
|
+
#puts "file=#{file}"
|
175
162
|
# ソースコードの整形
|
176
|
-
buf = update_source(file)
|
163
|
+
buf = update_source(pifdef, file)
|
177
164
|
# ソースを解析
|
178
165
|
cstruct_list = []
|
179
166
|
block_count = 0
|
@@ -260,7 +247,7 @@ def composition_list_create(in_dir, out_list)
|
|
260
247
|
return out_list
|
261
248
|
end
|
262
249
|
|
263
|
-
def create_uml_class(in_dir, out_file)
|
250
|
+
def create_uml_class(pifdef, in_dir, out_file)
|
264
251
|
out = []
|
265
252
|
out.push "@startuml"
|
266
253
|
|
@@ -278,7 +265,7 @@ def create_uml_class(in_dir, out_file)
|
|
278
265
|
end
|
279
266
|
#puts file
|
280
267
|
# ソースコードの整形
|
281
|
-
buf = update_source(file)
|
268
|
+
buf = update_source(pifdef, file)
|
282
269
|
|
283
270
|
cstruct_list = []
|
284
271
|
block_count = 0
|
@@ -328,7 +315,7 @@ def create_uml_class(in_dir, out_file)
|
|
328
315
|
elsif @config["class_color_path2"].to_s != "" and file =~ Regexp.new(@config["class_color_path2"])
|
329
316
|
cstruct_list.push CStruct.new(:class_end, class_name, block_count, [], [], [], [], @config["class_color2"])
|
330
317
|
elsif @config["class_color_path3"].to_s != "" and file =~ Regexp.new(@config["class_color_path3"])
|
331
|
-
pp file
|
318
|
+
#pp file
|
332
319
|
cstruct_list.push CStruct.new(:class_end, class_name, block_count, [], [], [], [], @config["class_color3"])
|
333
320
|
else
|
334
321
|
cstruct_list.push CStruct.new(:class_end, class_name, block_count, [], [], [], [], @config["default_class_color"])
|
@@ -406,16 +393,17 @@ def create_uml_class(in_dir, out_file)
|
|
406
393
|
cstruct_list.slice!(-1) # 最後の要素を削除
|
407
394
|
end
|
408
395
|
end
|
409
|
-
puts "#{block_count} #{line.chomp}"
|
396
|
+
#puts "#{block_count} #{line.chomp}"
|
410
397
|
end
|
411
398
|
if block_count != 0
|
412
399
|
# エラー
|
400
|
+
puts "error block_count=#{block_count}"
|
413
401
|
puts file
|
414
402
|
return ""
|
415
403
|
end
|
416
404
|
end
|
417
405
|
# compositon_listの作成
|
418
|
-
out_list = composition_list_create(in_dir, out_list)
|
406
|
+
out_list = composition_list_create(pifdef, in_dir, out_list)
|
419
407
|
# UMLの出力
|
420
408
|
out = print_uml(out, out_list)
|
421
409
|
|
@@ -440,39 +428,10 @@ def create_uml_class(in_dir, out_file)
|
|
440
428
|
return out.join("\n")
|
441
429
|
end
|
442
430
|
|
443
|
-
def search_func(file)
|
444
|
-
#puts file
|
445
|
-
# ソースコードの整形
|
446
|
-
buf = update_source(file)
|
447
|
-
# ソースを解析
|
448
|
-
buf.each_line do |line|
|
449
|
-
next if line =~ /^[\r\n]*$/ # 空行は対象外
|
450
|
-
next if line =~ /^#/ # #から始まる行は対象外
|
451
|
-
#puts line
|
452
|
-
if line.gsub(/<.*>/, "") =~ /^\S.*(\S+)::(\S+).*\(.*{$/
|
453
|
-
#puts line.gsub!(/<.*>/, "")
|
454
|
-
line.match(/(\w+)(?=\S+\()/) do |m|
|
455
|
-
#puts "class_name=#{m}"
|
456
|
-
end
|
457
|
-
end
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
431
|
if $0 == __FILE__
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
if true
|
469
|
-
puts create_uml_class(ARGV[0], ARGV[1])
|
470
|
-
else
|
471
|
-
out_list = []
|
472
|
-
out_list.push CStruct.new(:method_start, "DefaultVehicleHal", 1, [], [], [], [])
|
473
|
-
out_list.push CStruct.new(:method_start, "SubscriptionManager", 1, [], [], [], [])
|
474
|
-
out_list.push CStruct.new(:method_start, "ContSubConfigs", 1, [], [], [], [])
|
475
|
-
out_list.push CStruct.new(:method_start, "GetSetValuesClient", 1, [], [], [], [])
|
476
|
-
puts composition_list_create(ARGV[0], out_list)
|
477
|
-
end
|
432
|
+
@config = { "exclude_path" => "",
|
433
|
+
"define_hash" => {} }
|
434
|
+
pifdef = IfdefProcess.new
|
435
|
+
puts create_uml_class(pifdef, ARGV[0], ARGV[1])
|
436
|
+
puts pifdef.define_list
|
478
437
|
end
|