CppUmlClass 0.2.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.
@@ -0,0 +1,459 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << File.dirname(File.expand_path(__FILE__))
3
+ require "tempfile"
4
+ require "facter"
5
+ require "check_word"
6
+
7
+ CStruct = Struct.new(:type,
8
+ :name,
9
+ :block_count,
10
+ :var_list,
11
+ :method_list,
12
+ :inherit_list,
13
+ :composition_list)
14
+
15
+ def get_gcc_path
16
+ kernel = Facter.value(:kernel)
17
+ if kernel == "windows"
18
+ ENV["PATH"].split(";").each do |path|
19
+ gcc_path = "#{path}\\gcc"
20
+ if File.exists? gcc_path
21
+ return "rubyw " + gcc_path + " -fpreprocessed -dD -E "
22
+ end
23
+ end
24
+ return ""
25
+ else
26
+ return "gcc -fpreprocessed -dD -E "
27
+ end
28
+ end
29
+
30
+ def get_unifdef_path
31
+ kernel = Facter.value(:kernel)
32
+ if kernel == "windows"
33
+ ENV["PATH"].split(";").each do |path|
34
+ gcc_path = "#{path}\\unifdef"
35
+ if File.exists? gcc_path
36
+ return "rubyw " + gcc_path + " -k "
37
+ end
38
+ end
39
+ return ""
40
+ else
41
+ return "unifdef -k "
42
+ end
43
+ end
44
+
45
+ def get_clang_format_path
46
+ kernel = Facter.value(:kernel)
47
+ if kernel == "windows"
48
+ ENV["PATH"].split(";").each do |path|
49
+ clang_format_path = "#{path}\\clang-format"
50
+ if File.exists? clang_format_path
51
+ return "rubyw " + clang_format_path + " --style=file:'.clang-format' "
52
+ end
53
+ end
54
+ return ""
55
+ else
56
+ end
57
+ return "clang-format --style=file:'.clang-format' "
58
+ end
59
+
60
+ # ソースコードの整形
61
+ # フォーマット変更(clang-format)
62
+ # コメント削除(gcc)
63
+ # ifdefの処理(unifdef)
64
+ def update_source(file)
65
+ # コメント削除
66
+ gcc_out_file = Tempfile.open(["gcc", File.extname(file)])
67
+ #puts gcc_out_file.path
68
+ #puts "|#{get_gcc_path} #{file} > #{gcc_out_file.path}"
69
+ open("|#{get_gcc_path} #{file} > #{gcc_out_file.path}") do |f|
70
+ if f.read =~ /error/
71
+ puts "gcc error #{f}"
72
+ return ""
73
+ end
74
+ end
75
+ #puts File.binread gcc_out_file.path
76
+ # clang-format
77
+ format_out_file = Tempfile.open(["clang_format", File.extname(file)])
78
+ #puts format_out_file.path
79
+ #puts "|#{get_clang_format_path} #{gcc_out_file.path} > #{format_out_file.path}"
80
+ open("|#{get_clang_format_path} #{gcc_out_file.path} > #{format_out_file.path}") do |f|
81
+ if f.read =~ /No such/
82
+ puts "gcc error #{f}"
83
+ return ""
84
+ end
85
+ end
86
+ buf = File.binread format_out_file.path
87
+ return buf
88
+ # ifdef処理
89
+ unifdef_out_file = Tempfile.open(["gcc", File.extname(file)])
90
+ #puts unifdef_out_file.path
91
+ #puts "|#{get_unifdef_path} #{format_out_file.path} > #{unifdef_out_file.path}"
92
+ open("|#{get_unifdef_path} #{gcc_out_file.path} > #{unifdef_out_file.path}") do |f|
93
+ if f.read =~ /No such/
94
+ puts "gcc error #{f}"
95
+ return ""
96
+ end
97
+ end
98
+ buf = File.binread unifdef_out_file.path
99
+ puts buf
100
+ return buf
101
+ end
102
+
103
+ def print_uml(out, out_list)
104
+ out_list.each do |o_list|
105
+ if o_list.type == :class_start
106
+ # nop
107
+ elsif o_list.type == :module_start
108
+ out.push "namespace #{o_list.name} {"
109
+ elsif o_list.type == :class_end
110
+ pp o_list if o_list.name == ""
111
+ out.push "class #{o_list.name} {"
112
+ # インスタンス変数の出力
113
+ o_list.var_list.uniq.each do |iv|
114
+ out.push iv
115
+ end
116
+ # メソッドの出力
117
+ o_list.method_list.each do |ml|
118
+ out.push ml
119
+ end
120
+ out.push "}"
121
+ # 継承リストの出力
122
+ o_list.inherit_list.each do |ih|
123
+ out.push "#{o_list.name} -[#blue]-|> #{ih}"
124
+ end
125
+ # compo
126
+ o_list.composition_list.uniq.each do |co|
127
+ out.push "#{o_list.name} *-[#green]- #{co}"
128
+ end
129
+ elsif o_list.type == :module_end
130
+ # インスタンス変数がある場合はモジュール名と同じクラスを定義
131
+ if o_list.var_list.size != 0 or
132
+ o_list.method_list.size != 0 or
133
+ o_list.inherit_list.size != 0 or
134
+ o_list.composition_list.size != 0
135
+ pp o_list if o_list.name == ""
136
+ out.push "class #{o_list.name} {"
137
+ # インスタンス変数の出力
138
+ o_list.var_list.uniq.each do |iv|
139
+ out.push iv
140
+ end
141
+ # メソッドの出力
142
+ o_list.method_list.each do |ml|
143
+ out.push ml
144
+ end
145
+ out.push "}"
146
+ # 継承リストの出力
147
+ o_list.inherit_list.each do |ih|
148
+ out.push "#{o_list.name} -[#blue]-|> #{ih}"
149
+ end
150
+ # compo
151
+ o_list.composition_list.uniq.each do |co|
152
+ out.push "#{o_list.name} *-[#green]- #{co}"
153
+ end
154
+ end
155
+ out.push "}"
156
+ else
157
+ # error
158
+ puts "error!"
159
+ end
160
+ end
161
+ return out
162
+ end
163
+
164
+ def composition_list_create(in_dir, out_list)
165
+ # composition_list
166
+ Dir.glob("#{in_dir}/**/*.{cpp,hpp}") do |file|
167
+ if file =~ Regexp.new(@config["exclude_path"])
168
+ puts "skip #{file}"
169
+ next
170
+ end
171
+ puts file
172
+ # ソースコードの整形
173
+ buf = update_source(file)
174
+ # ソースを解析
175
+ cstruct_list = []
176
+ block_count = 0
177
+ buf.each_line do |line|
178
+ next if line =~ /^[\r\n]*$/ # 空行は対象外
179
+ next if line =~ /^#/ # #から始まる行は対象外
180
+ puts line
181
+
182
+ # ブロックの開始/終了
183
+ if line.match(/\{/)
184
+ block_count += 1
185
+ end
186
+ if line.match(/\}/)
187
+ block_count -= 1
188
+ end
189
+ puts "block_count=#{block_count}"
190
+
191
+ # classの開始
192
+ #if line =~ /^\s*(class)\s/ and File.extname(file) == ".h"
193
+ if line =~ /^\s*(class|struct)\s/ and File.extname(file) == ".h"
194
+ next if line =~ /;$/
195
+ work = line.gsub(/(class|struct)/, "")
196
+ class_name = work.split(" : ")[0].to_s.chomp.match(/ [A-Za-z0-9_:]+/).to_s.split(" ")[0]
197
+ base_name = work.split(" : ")[1].to_s.split(" ")[1].to_s.gsub(/<.*>/, "")
198
+ puts "start class #{class_name}"
199
+ cstruct_list.push CStruct.new(:class_end, class_name, block_count, [], [], [], [])
200
+ end
201
+
202
+ # 関数の開始
203
+ #if line =~ /^\S+::\S+/
204
+ if line.gsub(/<.*>/, "") =~ /^\S.*(\S+)::(\S+).*\(.*{$/ and
205
+ (File.extname(file) == ".cpp" or File.extname(file) == ".hpp")
206
+ puts "method start"
207
+ #class_name = line.match(/(\w+)(?=<\w*,?\s*\w*>?::\w+\(\))/).to_s
208
+ #class_name = line.match(/(\w+)(?=::\S+\(\))/).to_s if class_name == ""
209
+ #class_name = line.match(/(\w+(?:::\w+)*)(?=::\w+\(.*\))/).to_s if class_name == ""
210
+ #class_name = class_name.split("::")[1] if class_name =~ /::/
211
+ line.gsub(/<.*>/, "").match(/(\w+)(?=\S+\()/) do |m|
212
+ puts "class_name=#{m}"
213
+ cstruct_list.push CStruct.new(:method_start, m.to_s, block_count, [], [], [], [])
214
+ break
215
+ end
216
+
217
+ #puts "class_name=[#{class_name}]"
218
+ #if class_name != ""
219
+ # cstruct_list.push CStruct.new(:method_start, class_name, block_count, [], [], [], [])
220
+ # next
221
+ #end
222
+ end
223
+
224
+ if cstruct_list.size != 0
225
+ class_block_count = cstruct_list[-1].block_count
226
+ if block_count == (class_block_count - 1) # block_countが一致
227
+ # 関数の終了
228
+ puts "method end #{cstruct_list[-1].name}"
229
+ cstruct_list.slice!(-1) # 最後の要素を削除
230
+ else
231
+ puts "#{File.basename(file)}:#{block_count}:line3=#{line}"
232
+ my_class_name = cstruct_list[-1].name
233
+ my_cstruct = out_list.select { |m| m.name == my_class_name }[1]
234
+ #pp my_cstruct
235
+ if my_cstruct
236
+ # 使用しているクラスの検索
237
+ out_list.each do |clist|
238
+ next if clist.name == my_cstruct.name
239
+ use_class_name = clist.name
240
+ puts "my_class_name=#{my_class_name} : use_class_name=#{use_class_name}"
241
+ if check_word(line, use_class_name)
242
+ #if line.include?(use_class_name)
243
+ my_cstruct.composition_list.push use_class_name
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end
251
+ #pp out_list
252
+ return out_list
253
+ end
254
+
255
+ def create_uml_class(in_dir, out_file)
256
+ out = []
257
+ out.push "@startuml"
258
+
259
+ puts "in_dir = #{in_dir}"
260
+ main_composition_list = []
261
+ main_method_list = []
262
+ global_var = []
263
+
264
+ out_list = []
265
+ #Dir.glob("#{in_dir}/**/*.{cpp,hpp,h}") do |file|
266
+ Dir.glob("#{in_dir}/**/*.{h}") do |file|
267
+ if file =~ Regexp.new(@config["exclude_path"])
268
+ puts "skip #{file}"
269
+ next
270
+ end
271
+ puts file
272
+ # ソースコードの整形
273
+ buf = update_source(file)
274
+
275
+ cstruct_list = []
276
+ block_count = 0
277
+ method_type = :public
278
+ class_name = ""
279
+ # ソースを解析
280
+ buf.each_line do |line|
281
+ next if line =~ /^[\r\n]*$/ # 空行は対象外
282
+ next if line =~ /^#/ # #から始まる行は対象外
283
+ puts line
284
+
285
+ # ブロックの開始/終了
286
+ if line.match(/\{/)
287
+ block_count += line.each_char.select { |c| c == "{" }.size
288
+ start_block = true
289
+ else
290
+ start_block = false
291
+ end
292
+ # ブロックの終了
293
+ if line.match(/\}/)
294
+ block_count -= line.each_char.select { |c| c == "}" }.size
295
+ end
296
+ puts "block_count=#{block_count}"
297
+
298
+ # classの開始
299
+ #if line =~ /^\s*(class)\s/
300
+ if line =~ /^\s*(class|struct)\s/
301
+ next if line =~ /;$/
302
+ work = line.gsub(/(class|struct)/, "")
303
+ class_name = work.split(" : ")[0].to_s.chomp.match(/ [A-Za-z0-9_:]+/).to_s.split(" ")[0]
304
+ base_name = work.split(" : ")[1].to_s.gsub(/(public |private |protected )/, "").to_s.gsub(/<.*>/, "").split(" ")[0]
305
+ puts "start class [#{class_name}]"
306
+ if class_name == ""
307
+ puts file
308
+ exit
309
+ end
310
+ #if out_list.size != 0 and out_list[-1].type == :class_start # classが連続している
311
+ # class_name = out_list[-1].name + "." + class_name
312
+ # out_list[-1].name = class_name
313
+ # cstruct_list[-1].name = class_name
314
+ #else
315
+ out_list.push CStruct.new(:class_start, class_name, block_count, [], [], [], [])
316
+ cstruct_list.push CStruct.new(:class_end, class_name, block_count, [], [], [], [])
317
+ #end
318
+ #pp line if class_name == ""
319
+ if base_name.to_s != ""
320
+ #base_name.gsub!(/::/, ".")
321
+ puts "base_name=#{base_name}"
322
+ cstruct_list[-1].inherit_list.push base_name
323
+ end
324
+ end
325
+
326
+ if line =~ /^\s*private:$/
327
+ method_type = :private
328
+ elsif line =~ /^\s*protected:$/
329
+ method_type = :protected
330
+ elsif line =~ /^\s*public:$/
331
+ method_type = :public
332
+ end
333
+
334
+ if cstruct_list.size != 0 and
335
+ (block_count == cstruct_list[-1].block_count or
336
+ (start_block == true and block_count - 1 == cstruct_list[-1].block_count))
337
+ if line =~ /\(.*\)/
338
+ #puts "#{block_count}:line2=#{line}"
339
+ # 関数名を取り出す
340
+ method = line.split(" : ")[0].gsub(/^\s+/, "")
341
+ method = method.split(";")[0].split("{")[0]
342
+ puts "method=#{method}"
343
+ method_list = cstruct_list[-1].method_list
344
+ case method_type
345
+ when :public
346
+ method_list.push "+ #{method}"
347
+ when :private
348
+ method_list.push "- #{method}"
349
+ when :protected
350
+ method_list.push "# #{method}"
351
+ end
352
+ end
353
+ end
354
+
355
+ # class変数
356
+ # 括弧を含まない、かつtemplateを含まない文字列
357
+ if cstruct_list.size != 0 and block_count == cstruct_list[-1].block_count
358
+ if line =~ /^[^(){}]*$/ and
359
+ line =~ /^((?!\/tmp\/).)*$/ and
360
+ line =~ /^((?!namespace).)*$/ and
361
+ line =~ /^((?!template).)*$/ and
362
+ line =~ /^((?!public:).)*$/ and
363
+ line =~ /^((?!private:).)*$/ and
364
+ line =~ /^((?!protected:).)*$/
365
+ puts "class member=#{line}"
366
+ #val = line.split("=")[0].split(" ")[-1]
367
+ val = line.split("=")[0]
368
+ val = val.split(";")[0]
369
+ instance_var = cstruct_list[-1].var_list
370
+ case method_type
371
+ when :public
372
+ instance_var.push "+ #{val}"
373
+ when :private
374
+ instance_var.push "- #{val}"
375
+ when :protected
376
+ instance_var.push "# #{val}"
377
+ end
378
+ end
379
+ end
380
+
381
+ # クラスの終了
382
+ if cstruct_list.size != 0
383
+ class_block_count = cstruct_list[-1].block_count
384
+ if block_count == (class_block_count - 1) # block_countが一致
385
+ puts "class end #{cstruct_list[-1].name}"
386
+ out_list.push cstruct_list[-1]
387
+ cstruct_list.slice!(-1) # 最後の要素を削除
388
+ end
389
+ end
390
+ #puts "#{block_count} #{line.chomp}"
391
+ end
392
+ if block_count != 0
393
+ # エラー
394
+ puts file
395
+ return ""
396
+ end
397
+ end
398
+ # compositon_listの作成
399
+ out_list = composition_list_create(in_dir, out_list)
400
+ # UMLの出力
401
+ out = print_uml(out, out_list)
402
+
403
+ if main_method_list.size != 0 or
404
+ main_composition_list.size != 0 or
405
+ main_method_list.size != 0
406
+ out.push "class main {"
407
+ main_method_list.each do |mml|
408
+ out.push mml
409
+ end
410
+ # グローバル変数の出力
411
+ global_var.uniq.each do |gv|
412
+ out.push gv
413
+ end
414
+ out.push "}"
415
+ main_composition_list.uniq.each do |mcl|
416
+ out.push mcl
417
+ end
418
+ end
419
+
420
+ out.push "@enduml"
421
+ return out.join("\n")
422
+ end
423
+
424
+ def search_func(file)
425
+ puts file
426
+ # ソースコードの整形
427
+ buf = update_source(file)
428
+ # ソースを解析
429
+ buf.each_line do |line|
430
+ next if line =~ /^[\r\n]*$/ # 空行は対象外
431
+ next if line =~ /^#/ # #から始まる行は対象外
432
+ #puts line
433
+ if line.gsub(/<.*>/, "") =~ /^\S.*(\S+)::(\S+).*\(.*{$/
434
+ puts line.gsub!(/<.*>/, "")
435
+ line.match(/(\w+)(?=\S+\()/) do |m|
436
+ puts "class_name=#{m}"
437
+ end
438
+ end
439
+ end
440
+ end
441
+
442
+ if $0 == __FILE__
443
+ #search_func(ARGV[0])
444
+ #exit
445
+ #buf = update_source(ARGV[0])
446
+ #puts buf
447
+ @config = { "exclude_path" => "test" }
448
+
449
+ if true
450
+ puts create_uml_class(ARGV[0], ARGV[1])
451
+ else
452
+ out_list = []
453
+ out_list.push CStruct.new(:method_start, "DefaultVehicleHal", 1, [], [], [], [])
454
+ out_list.push CStruct.new(:method_start, "SubscriptionManager", 1, [], [], [], [])
455
+ out_list.push CStruct.new(:method_start, "ContSubConfigs", 1, [], [], [], [])
456
+ out_list.push CStruct.new(:method_start, "GetSetValuesClient", 1, [], [], [], [])
457
+ puts composition_list_create(ARGV[0], out_list)
458
+ end
459
+ end
data/lib/css/index.css ADDED
@@ -0,0 +1,178 @@
1
+ body {
2
+ color: #000000;
3
+ background-color: #cac3ec4f;
4
+ overflow: hidden;
5
+ font-size: 12px;
6
+ }
7
+
8
+ hr {
9
+ color: #ffffff;
10
+ background-color: #000000;
11
+ height: 1px;
12
+ /* 線の太さ */
13
+ border: 1px;
14
+ /* 枠の太さ */
15
+ border-style: solid;
16
+ /* 枠の種類 */
17
+ }
18
+
19
+ .error {
20
+ color: red;
21
+ }
22
+
23
+ .outarea {
24
+ background-color: #FFFFFF;
25
+ margin: 5px;
26
+ padding: 5px;
27
+ width: 95vw;
28
+ height: 50vh;
29
+ overflow: auto;
30
+ }
31
+
32
+ .inarea {
33
+ border: thin solid #000000;
34
+ margin: 5px;
35
+ padding: 5px;
36
+ width: 95%;
37
+ }
38
+
39
+ input.long {
40
+ width: 90%;
41
+ background-color: #FAFAFA;
42
+ margin: 5px;
43
+ padding: 5px;
44
+ }
45
+
46
+ textarea.long {
47
+ width: 95vw;
48
+ height: 50vh;
49
+ }
50
+
51
+ .ui-widget {
52
+ font-size: 12px;
53
+ }
54
+
55
+ .ui-autocomplete {
56
+ max-height: 45vh;
57
+ max-width: 90wh;
58
+ overflow-y: auto;
59
+ overflow-x: auto;
60
+ padding-right: 10px;
61
+ }
62
+
63
+ #jquery-ui-autocomplete label {
64
+ float: left;
65
+ margin-right: 0.5em;
66
+ color: black;
67
+ }
68
+
69
+ .ui-autocomplete.ui-front {
70
+ max-height: 250px;
71
+ overflow-y: auto;
72
+ /* prevent horizontal scrollbar */
73
+ overflow-x: hidden;
74
+ /* add padding to account for vertical scrollbar */
75
+ z-index: 1000 !important;
76
+ }
77
+
78
+ .ui-dialog {
79
+ position: absolute;
80
+ top: 0;
81
+ left: 0;
82
+ padding: .2em;
83
+ outline: 0;
84
+ }
85
+
86
+ .long {
87
+ width: 90%;
88
+ }
89
+
90
+ #setting_dialog {
91
+ color: #796fe9;
92
+ background-color: #000000;
93
+ }
94
+
95
+ .setting_name {
96
+ width: 200px;
97
+ color: #796fe9;
98
+ background-color: #000000;
99
+ }
100
+
101
+ .setting_value {
102
+ width: 300px;
103
+ color: #796fe9;
104
+ background-color: #000000;
105
+ }
106
+
107
+ .setting_checkbox {
108
+ color: #796fe9;
109
+ background-color: #000000;
110
+ }
111
+
112
+ ul.log {
113
+ list-style-type: decimal;
114
+ font-size: 12px;
115
+ color: #5d0a94;
116
+ }
117
+
118
+ input[type="search"] {
119
+ -webkit-appearance: searchfield;
120
+ }
121
+
122
+ input[type="search"]::-webkit-search-cancel-button {
123
+ -webkit-appearance: searchfield-cancel-button;
124
+ }
125
+
126
+ /* menu */
127
+ .menu {
128
+ display: flex;
129
+ justify-content: flex-start;
130
+ list-style-type: none;
131
+ color: #393737;
132
+ padding: 0;
133
+ font-size: 12px;
134
+ font-weight: bold;
135
+ }
136
+
137
+ .menu li {
138
+ position: relative;
139
+ width: 100px;
140
+ margin-left: 1px;
141
+ padding: 5px;
142
+ background: #d8dada;
143
+ list-style-type: none;
144
+ }
145
+
146
+ .menu li a {
147
+ color: rgb(20, 114, 192);
148
+ }
149
+
150
+ .menu li a:hover {
151
+ background: #eba399;
152
+ }
153
+
154
+ .menuSub {
155
+ position: absolute;
156
+ margin-left: -6px;
157
+ padding: 0;
158
+ display: none;
159
+ }
160
+
161
+ /*.openが付与された時、表示の設定*/
162
+ .menuSub.open {
163
+ display: block;
164
+ }
165
+
166
+ .menuSub li a {
167
+ padding: 5px;
168
+ margin-left: -5px;
169
+ margin-right: -5px;
170
+ margin-bottom: -5px;
171
+ display: block;
172
+ color: rgb(20, 114, 192);
173
+ text-decoration: none;
174
+ }
175
+
176
+ .menuSub li a:hover {
177
+ background: #eba399;
178
+ }
@@ -0,0 +1,80 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>CppUMLClass</title>
8
+ <!-- jQuery -->
9
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
10
+ <!-- jQuery UI -->
11
+ <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
12
+ <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
13
+
14
+ <script src="js/main.js"></script>
15
+ <link rel="stylesheet" href="css/index.css" type="text/css">
16
+ </head>
17
+
18
+ <body>
19
+ <div id="msg_dialog" style="display:none;">
20
+ <div id="msg_text">message</div>
21
+ </div>
22
+ <hr>
23
+ <!-- menu -->
24
+ <div id="setting_dialog" style="display:none;">
25
+ <dl id="wrap"></dl>
26
+ </div>
27
+ <div>
28
+ <ul class="menu">
29
+ <Li><a href="#" id="exec" name="exec">実行</a></li>
30
+ <li><a href="#" id="stop" name="stop">停止</a></li>
31
+ <li>
32
+ 設定
33
+ <ul class="menuSub">
34
+ <li><a href="#" id="setting">設定</a></li>
35
+ <li><a href="#" id="save_setting">設定保存</a></li>
36
+ <li><a href="#" id="load_setting">設定読み込み</a></li>
37
+ </ul>
38
+ </li>
39
+ <!--
40
+ <li>
41
+ menu3
42
+ <ul class="menuSub">
43
+ <li><a href="#">menu3-1</a></li>
44
+ <li><a href="#">menu3-2</a></li>
45
+ </ul>
46
+ </li>
47
+ -->
48
+ </ul>
49
+ </div>
50
+
51
+ <table>
52
+ <tr>
53
+ <td>
54
+ <div id="dialog1" style="display:none;">
55
+ <input class="inarea" type="search" name="search_str" id="search_str">
56
+ </div>
57
+ </td>
58
+ <td class="long"><input class="inarea" type="search" id="inDir" name="inDir"></td>
59
+ <td><input type="button" id="select_dir" value="対象フォルダ" /></td>
60
+ </tr>
61
+ <tr>
62
+ <td>
63
+ <div id="dialog2" style="display:none;">
64
+ <input class="inarea" type="search" name="search_str2" id="search_str2">
65
+ </div>
66
+ </td>
67
+ <td class="long"><input class="inarea" type="search" id="outFile" name="outFile"></td>
68
+ <td><input type="button" id="select_file" value="出力ファイル" /></td>
69
+ <td><input type="button" id="open_file" value="開く" /></td>
70
+ </tr>
71
+ </table>
72
+
73
+ <div class="outarea">
74
+ <ul name="log" id="log" class="log">
75
+ </ul>
76
+ </div>
77
+
78
+ </body>
79
+
80
+ </html>