aio_elin 0.0.1
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 +7 -0
- data/LICENSE.txt +675 -0
- data/README.md +9 -0
- data/config.rb +39 -0
- data/lib/aio/base/debug.rb +30 -0
- data/lib/aio/base/toolkit/array.rb +24 -0
- data/lib/aio/base/toolkit/date.rb +46 -0
- data/lib/aio/base/toolkit/deep_clone.rb +10 -0
- data/lib/aio/base/toolkit/diff.rb +104 -0
- data/lib/aio/base/toolkit/excel_office.rb +421 -0
- data/lib/aio/base/toolkit/excel_wps.rb +437 -0
- data/lib/aio/base/toolkit/excel_wps.rb.bak +299 -0
- data/lib/aio/base/toolkit/ipaddr.rb +28 -0
- data/lib/aio/base/toolkit/os.rb +26 -0
- data/lib/aio/base/toolkit/regexp.rb +32 -0
- data/lib/aio/base/toolkit/string.rb +28 -0
- data/lib/aio/base/toolkit/table.rb +441 -0
- data/lib/aio/base/toolkit/test_diff.rb +9 -0
- data/lib/aio/base/toolkit/test_excel.rb +118 -0
- data/lib/aio/base/toolkit/test_word.rb +58 -0
- data/lib/aio/base/toolkit/word_wps.rb +492 -0
- data/lib/aio/base/toolkit.rb +18 -0
- data/lib/aio/base.rb +10 -0
- data/lib/aio/core/device/cisco.rb +13 -0
- data/lib/aio/core/device/cmd_switch.rb +113 -0
- data/lib/aio/core/device/h3c.rb +12 -0
- data/lib/aio/core/device/huawei.rb +10 -0
- data/lib/aio/core/device/juniper.rb +10 -0
- data/lib/aio/core/device/maipu.rb +11 -0
- data/lib/aio/core/device/methods.rb +233 -0
- data/lib/aio/core/device/methods.rb.bak +199 -0
- data/lib/aio/core/device/parent_device.rb +275 -0
- data/lib/aio/core/device.rb +15 -0
- data/lib/aio/core/device_manager.rb +207 -0
- data/lib/aio/core/module/cmd.rb +160 -0
- data/lib/aio/core/module/description.rb +67 -0
- data/lib/aio/core/module/input_style.rb +98 -0
- data/lib/aio/core/module/output_style.rb +80 -0
- data/lib/aio/core/module/platform.rb +30 -0
- data/lib/aio/core/module/ranking.rb +24 -0
- data/lib/aio/core/module/special_style.rb +30 -0
- data/lib/aio/core/module/template.rb +13 -0
- data/lib/aio/core/module.rb +15 -0
- data/lib/aio/core/module_loader.rb +161 -0
- data/lib/aio/core/module_loader.rb.bak +148 -0
- data/lib/aio/core/module_manager.rb +112 -0
- data/lib/aio/core/module_manager.rb.bak +78 -0
- data/lib/aio/core/parse/file.rb +19 -0
- data/lib/aio/core/parse/parser.rb +91 -0
- data/lib/aio/core/parse/parser_machine/bak/has_cmd_state.rb +14 -0
- data/lib/aio/core/parse/parser_machine/bak/has_context_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/bak/no_cmd_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/bak/no_context_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/full_state.rb +12 -0
- data/lib/aio/core/parse/parser_machine/has_device_state.rb +44 -0
- data/lib/aio/core/parse/parser_machine/no_device_state.rb +12 -0
- data/lib/aio/core/parse/parser_machine/parent_state.rb +26 -0
- data/lib/aio/core/parse/parser_machine.rb +47 -0
- data/lib/aio/core/parse.rb +6 -0
- data/lib/aio/core/text/context.rb +211 -0
- data/lib/aio/core/text/line_string.rb +74 -0
- data/lib/aio/core/text/warning.rb +179 -0
- data/lib/aio/core/text.rb +7 -0
- data/lib/aio/core/warning/description.rb +47 -0
- data/lib/aio/core/warning/warning_summarize.rb +232 -0
- data/lib/aio/core/warning.rb +6 -0
- data/lib/aio/core.rb +32 -0
- data/lib/aio/license.rb +687 -0
- data/lib/aio/resource/cover_picture.png +0 -0
- data/lib/aio/resource/line.png +0 -0
- data/lib/aio/resource/logo.png +0 -0
- data/lib/aio/ui/banner.rb +85 -0
- data/lib/aio/ui/readable_text.rb +75 -0
- data/lib/aio/ui/verbose.rb +29 -0
- data/lib/aio/ui/version.rb +9 -0
- data/lib/aio/ui.rb +138 -0
- data/lib/aio.rb +13 -0
- data/lib/modules/cmd/cisco/show_clock.rb +32 -0
- data/lib/modules/cmd/cisco/show_cpu.rb +32 -0
- data/lib/modules/cmd/cisco/show_env.rb +71 -0
- data/lib/modules/cmd/cisco/show_failover.rb +39 -0
- data/lib/modules/cmd/cisco/show_interface_ip_brief.rb +24 -0
- data/lib/modules/cmd/cisco/show_interfaces.rb +177 -0
- data/lib/modules/cmd/cisco/show_inv.rb +43 -0
- data/lib/modules/cmd/cisco/show_ip_interface_brief.rb +42 -0
- data/lib/modules/cmd/cisco/show_ip_ospf_nei.rb +38 -0
- data/lib/modules/cmd/cisco/show_ip_route_summary.rb +81 -0
- data/lib/modules/cmd/cisco/show_memory.rb +27 -0
- data/lib/modules/cmd/cisco/show_process_cpu.rb +35 -0
- data/lib/modules/cmd/cisco/show_process_memory.rb +63 -0
- data/lib/modules/cmd/cisco/show_version.rb +97 -0
- data/lib/modules/cmd/h3c/display_clock.rb +32 -0
- data/lib/modules/cmd/h3c/display_cpu.rb +51 -0
- data/lib/modules/cmd/h3c/display_device_manuinfo.rb +45 -0
- data/lib/modules/cmd/h3c/display_fan.rb +91 -0
- data/lib/modules/cmd/h3c/display_interface.rb +203 -0
- data/lib/modules/cmd/h3c/display_ip_interface_brief.rb +34 -0
- data/lib/modules/cmd/h3c/display_ip_routing.rb +68 -0
- data/lib/modules/cmd/h3c/display_ip_routing_stat.rb +90 -0
- data/lib/modules/cmd/h3c/display_memory.rb +35 -0
- data/lib/modules/cmd/h3c/display_ospf_peer.rb +38 -0
- data/lib/modules/cmd/h3c/display_power.rb +90 -0
- data/lib/modules/cmd/h3c/display_version.rb +54 -0
- data/lib/modules/cmd/h3c/display_vrrp_verbose.rb +86 -0
- data/lib/modules/cmd/maipu/show_env.rb +34 -0
- data/lib/modules/cmd/maipu/show_ip_route.rb +74 -0
- data/lib/modules/cmd/maipu/show_ip_route_statistic.rb +36 -0
- data/lib/modules/cmd/maipu/show_memory.rb +31 -0
- data/lib/modules/cmd/maipu/show_system_fan.rb +66 -0
- data/lib/modules/cmd/maipu/show_system_power.rb +66 -0
- data/lib/modules/cmd/maipu/show_version.rb +50 -0
- data/lib/modules/description/style/crc.rb +22 -0
- data/lib/modules/description/style/input_errors.rb +22 -0
- data/lib/modules/description/style/overrun.rb +22 -0
- data/lib/modules/description/style/proc_ratio.rb +22 -0
- data/lib/modules/description/style/protocol.rb +22 -0
- data/lib/modules/description/style/register.rb +22 -0
- data/lib/modules/description/style/runts.rb +22 -0
- data/lib/modules/description/style/template.rb +22 -0
- data/lib/modules/description/style/total_output_drops.rb +22 -0
- data/lib/modules/input/style/compare_xml.rb +89 -0
- data/lib/modules/input/style/console.rb +222 -0
- data/lib/modules/input/style/console.rb.bak +114 -0
- data/lib/modules/input/style/xinhua_nat.rb +70 -0
- data/lib/modules/output/style/boc_day.rb +223 -0
- data/lib/modules/output/style/cmds.rb +77 -0
- data/lib/modules/output/style/compare_json.rb +26 -0
- data/lib/modules/output/style/compare_report.rb +31 -0
- data/lib/modules/output/style/compare_xml.rb +86 -0
- data/lib/modules/output/style/excel_table_office.rb +407 -0
- data/lib/modules/output/style/excel_table_wps.rb +400 -0
- data/lib/modules/output/style/summary_report.rb +563 -0
- data/lib/modules/special/style/compare.rb +110 -0
- metadata +176 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# 管理,保存各个加载的模块
|
|
2
|
+
class Aio::ModuleManager
|
|
3
|
+
|
|
4
|
+
# def [](key)
|
|
5
|
+
# end
|
|
6
|
+
|
|
7
|
+
attr_accessor :modules, :modules_count
|
|
8
|
+
|
|
9
|
+
# NOTE modules[reference_name] = {
|
|
10
|
+
# :device_type
|
|
11
|
+
# :full_path
|
|
12
|
+
# :klass
|
|
13
|
+
def initialize
|
|
14
|
+
# self.module_info_by_path = {}
|
|
15
|
+
# self.module_load_error_by_path = {}
|
|
16
|
+
# self.module_paths = []
|
|
17
|
+
self.modules = {}
|
|
18
|
+
self.modules_count = {}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# 加载一个目录下的所有模块
|
|
22
|
+
# @param [String] path 目录的路径
|
|
23
|
+
# @param [Hash] options
|
|
24
|
+
def load_modules(path, options={})
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# 将实例化后的模块类放到 modules 中
|
|
28
|
+
def add_module(path, device_type, reference_name, module_klass)
|
|
29
|
+
|
|
30
|
+
modules[reference_name] = {:device_type => device_type,
|
|
31
|
+
:full_path => path,
|
|
32
|
+
:klass => module_klass
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# 通过设备类型获得模块类
|
|
37
|
+
# 返回类型为: 数组
|
|
38
|
+
def get_module_by_device_type(device_type)
|
|
39
|
+
return_array = []
|
|
40
|
+
|
|
41
|
+
device_type = device_type.to_s
|
|
42
|
+
modules.each do |m|
|
|
43
|
+
type = m[:device_type]
|
|
44
|
+
if device_type == type
|
|
45
|
+
return_array << m[:klass]
|
|
46
|
+
end
|
|
47
|
+
next
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
return return_array
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# 获得所有加载模块的设备类型的字符串型
|
|
54
|
+
# 返回类型为: 数组
|
|
55
|
+
def get_modules_device_type_to_str
|
|
56
|
+
return_array = []
|
|
57
|
+
|
|
58
|
+
modules_counts.keys do |key|
|
|
59
|
+
return_array << key.to_s
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
return return_array
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# 判断此设备类型的模块是否加载
|
|
67
|
+
def device_type_enable?(device_type)
|
|
68
|
+
true
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def notify(opts={})
|
|
72
|
+
if opts[:count_by_device_type]
|
|
73
|
+
@modules_count = opts[:count_by_device_type]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Aio::Parse
|
|
2
|
+
|
|
3
|
+
class File
|
|
4
|
+
|
|
5
|
+
attr_accessor :file_open
|
|
6
|
+
|
|
7
|
+
def initialize(file_path)
|
|
8
|
+
self.file_open = File.open(file_path, "r+")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def each_line
|
|
12
|
+
file_open.each_line do |line|
|
|
13
|
+
# 改进点,加入sefe_string方法
|
|
14
|
+
yield line
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#coding=utf-8
|
|
2
|
+
|
|
3
|
+
module Aio::Parse
|
|
4
|
+
class Parser
|
|
5
|
+
attr_accessor :device_manager
|
|
6
|
+
attr_accessor :parser_machine
|
|
7
|
+
|
|
8
|
+
# 重要!在分析前需要确定input_klass
|
|
9
|
+
# input_klass 的类为input模块的类
|
|
10
|
+
# Aio::Module::InputStyle
|
|
11
|
+
attr_accessor :input_klass
|
|
12
|
+
|
|
13
|
+
include Aio::Ui::Verbose
|
|
14
|
+
|
|
15
|
+
def initialize(device_manager, parser_machine)
|
|
16
|
+
self.device_manager = device_manager
|
|
17
|
+
self.parser_machine = parser_machine
|
|
18
|
+
|
|
19
|
+
@invalid_input = Aio::Base::Toolkit::Regexp.merge([
|
|
20
|
+
Aio::Device::Cisco::InvalidInput,
|
|
21
|
+
Aio::Device::H3C::InvalidInput,
|
|
22
|
+
Aio::Device::Huawei::InvalidInput,
|
|
23
|
+
Aio::Device::Maipu::InvalidInput,
|
|
24
|
+
Aio::Device::Juniper::InvalidInput,
|
|
25
|
+
])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# 通过巡检文件的方式获得关键信息,并按cmd模块逐个解析
|
|
29
|
+
def parse_by_module
|
|
30
|
+
|
|
31
|
+
# 注意这里manager_ip可有可无, 没有的话默认为nil
|
|
32
|
+
print_good "正在加载信息..."
|
|
33
|
+
@input_klass.parse do |device_name, cmd, context, manager_ip|
|
|
34
|
+
device_info = {
|
|
35
|
+
:device_name => device_name,
|
|
36
|
+
:cmd => cmd.strip,
|
|
37
|
+
:context => Aio::Text::Context.new(context),
|
|
38
|
+
:manager_ip => manager_ip
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# 判断 context 是否有效
|
|
42
|
+
next if invalid?(context)
|
|
43
|
+
|
|
44
|
+
# 所有判断交到状态机处理
|
|
45
|
+
self.parser_machine.get_device(device_info)
|
|
46
|
+
self.parser_machine.get_full(device_info)
|
|
47
|
+
end
|
|
48
|
+
print_good "信息加载完成"
|
|
49
|
+
|
|
50
|
+
total = device_manager.devices_number
|
|
51
|
+
print_good "总共 #{total} 台设备"
|
|
52
|
+
print_good "正在对各个设备进行分析..."
|
|
53
|
+
device_manager.each_devices_with_index do |name, klass, i|
|
|
54
|
+
# 将解析命令后,并修改了自身类的实例覆盖掉原来父类
|
|
55
|
+
progress_bar(total, i+1, name)
|
|
56
|
+
|
|
57
|
+
# Debug处
|
|
58
|
+
if name == "B_HBWHA_CAM_DS01"
|
|
59
|
+
#puts "now"
|
|
60
|
+
end
|
|
61
|
+
new_klass = klass.parse
|
|
62
|
+
device_manager[name] = new_klass.instance
|
|
63
|
+
end
|
|
64
|
+
clear_line
|
|
65
|
+
print_good "设备信息分析完成"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# 判断 context 是否有效
|
|
69
|
+
def invalid?(context)
|
|
70
|
+
return true if context.empty?
|
|
71
|
+
return true if @invalid_input.match(context[1])
|
|
72
|
+
return false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# 通过output/compare_xml生成的XML文件解析,直接将结果保存
|
|
76
|
+
# compare_klass 为比较模块
|
|
77
|
+
# 其中只比较useful的值,并不会去比较warning
|
|
78
|
+
# warning 有原本device中以及比较中共同得出
|
|
79
|
+
def parse_by_compare(compare_klass)
|
|
80
|
+
|
|
81
|
+
# device_hash 为提供比较文件的hash
|
|
82
|
+
print_good "正在将比较文件转换为内部Hash表"
|
|
83
|
+
device_hash = @input_klass.parse
|
|
84
|
+
compare_klass.device_manager = device_manager
|
|
85
|
+
compare_klass.input_benchmark = device_hash
|
|
86
|
+
compare_hash = compare_klass.parse
|
|
87
|
+
device_manager.merge_warning(compare_hash)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Aio::Parse
|
|
2
|
+
class HasDeviceState < ParentState
|
|
3
|
+
|
|
4
|
+
def get_device(opts)
|
|
5
|
+
self.device_manager.add_device(opts)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def get_full(opts)
|
|
9
|
+
|
|
10
|
+
if ! check_full(opts)
|
|
11
|
+
no_full
|
|
12
|
+
elsif
|
|
13
|
+
@machine.to_full_state
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def no_full
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# 验证是否有cmd和context了
|
|
22
|
+
def check_full(opts={})
|
|
23
|
+
device_name = opts[:device_name]
|
|
24
|
+
device_klass = self.device_manager.devices[device_name]
|
|
25
|
+
|
|
26
|
+
org_cmd = opts[:cmd]
|
|
27
|
+
org_context = opts[:context]
|
|
28
|
+
org_cmd_reg = Aio::Base::Toolkit::Regexp.to_reg(org_cmd)
|
|
29
|
+
device_klass.cmds_context.each_pair do |cmd, context|
|
|
30
|
+
|
|
31
|
+
# 只有当有cmd, 并且context不为空的时候才算有
|
|
32
|
+
# :NOTE 可以在这里的context类加入.check_avlid? 查看是否有效
|
|
33
|
+
if org_cmd_reg.match(cmd)
|
|
34
|
+
if ! context.empty?
|
|
35
|
+
return true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
return false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#coding=utf-8
|
|
2
|
+
|
|
3
|
+
module Aio::Parse
|
|
4
|
+
class ErrorMachineMethod < StandardError
|
|
5
|
+
def to_s; "请重载此状态机方法"; end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class ParentState
|
|
9
|
+
def initialize(machine)
|
|
10
|
+
@machine = machine
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_device
|
|
14
|
+
raise ErrorMachineMethod.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get_full
|
|
18
|
+
raise ErrorMachineMethod.new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def device_manager
|
|
22
|
+
@machine.device_manager
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Aio::Parse
|
|
2
|
+
|
|
3
|
+
require "aio/core/parse/parser_machine/parent_state"
|
|
4
|
+
require "aio/core/parse/parser_machine/no_device_state"
|
|
5
|
+
require "aio/core/parse/parser_machine/has_device_state"
|
|
6
|
+
require "aio/core/parse/parser_machine/full_state"
|
|
7
|
+
|
|
8
|
+
class ParserMachine
|
|
9
|
+
# 保存状态机的状态
|
|
10
|
+
attr_reader :state
|
|
11
|
+
|
|
12
|
+
# device_manager
|
|
13
|
+
attr_reader :device_manager
|
|
14
|
+
|
|
15
|
+
def initialize(device_manager)
|
|
16
|
+
@device_manager = device_manager
|
|
17
|
+
|
|
18
|
+
@no_device_state = Aio::Parse::NoDeviceState.new(self)
|
|
19
|
+
@has_device_state = Aio::Parse::HasDeviceState.new(self)
|
|
20
|
+
@full_state = Aio::Parse::FullState.new(self)
|
|
21
|
+
|
|
22
|
+
@state = @no_device_state
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_device(opts)
|
|
26
|
+
@state.get_device(opts)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get_full(opts)
|
|
30
|
+
@state.get_full(opts)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# 状态的切换
|
|
34
|
+
def to_no_device_state
|
|
35
|
+
@state = @no_device_state
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_has_device_state
|
|
39
|
+
@state = @has_device_state
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def to_full_state
|
|
43
|
+
@state = @full_state
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
#coding=utf-8
|
|
2
|
+
|
|
3
|
+
module Aio::Text
|
|
4
|
+
class Context < ::Array
|
|
5
|
+
|
|
6
|
+
class OutLineError < StandardError; end
|
|
7
|
+
|
|
8
|
+
include Aio::Ui::Verbose
|
|
9
|
+
|
|
10
|
+
attr_reader :count_line, :backup_line
|
|
11
|
+
|
|
12
|
+
def initialize(*arr)
|
|
13
|
+
super
|
|
14
|
+
self.each_with_index do |str, i|
|
|
15
|
+
self[i] = Aio::Text::LineString.new(str.chomp)
|
|
16
|
+
end
|
|
17
|
+
@backup_line = nil
|
|
18
|
+
@count_line = 0
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# 到下一行
|
|
22
|
+
def next
|
|
23
|
+
@count_line += 1
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# 对每行进行read, 判断是单步运行还是循环运行
|
|
27
|
+
# 修改了此处的backup_line 逻辑
|
|
28
|
+
def readline_match_block(reg, single = false, &block)
|
|
29
|
+
|
|
30
|
+
reg = Aio::Base::Toolkit::Regexp.safe(reg)
|
|
31
|
+
|
|
32
|
+
first = true
|
|
33
|
+
loop do
|
|
34
|
+
line_str = self[@count_line]
|
|
35
|
+
|
|
36
|
+
if first
|
|
37
|
+
@backup_line = @count_line
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# 如果出界,有可能是因为循环导致
|
|
41
|
+
# 跳出循环
|
|
42
|
+
# 此处有问题,无法判断是否为最后一个,并跳出此模块
|
|
43
|
+
if @backup_line > self.size and line_str.nil?
|
|
44
|
+
@count_line = @backup_line
|
|
45
|
+
if Aio::Base::Debug.mismatch?
|
|
46
|
+
puts "[-] Can't match this line: "
|
|
47
|
+
puts caller
|
|
48
|
+
puts " line_string: #{self[@backup_line]}"
|
|
49
|
+
puts " regexp: #{reg}"
|
|
50
|
+
end
|
|
51
|
+
raise OutLineError
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if line_str.nil?
|
|
55
|
+
@count_line = @backup_line
|
|
56
|
+
break
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
first = false
|
|
60
|
+
begin
|
|
61
|
+
res = line_str.match_block(reg) do |b|
|
|
62
|
+
block.call(b) unless block.nil?
|
|
63
|
+
end
|
|
64
|
+
rescue IndexError => e
|
|
65
|
+
print_error "IndexError: 请检查模块block提取信息名称"
|
|
66
|
+
puts "caller"
|
|
67
|
+
puts caller
|
|
68
|
+
exit
|
|
69
|
+
rescue NoMethodError
|
|
70
|
+
if Aio::Base::Debug.module_debug?
|
|
71
|
+
print_error "NoMethodError: 请检查模块block中useful是否定义正确"
|
|
72
|
+
puts caller
|
|
73
|
+
end
|
|
74
|
+
exit
|
|
75
|
+
rescue ArgumentError => e
|
|
76
|
+
if Aio::Base::Debug.module_debug?
|
|
77
|
+
puts "ArgumentError:"
|
|
78
|
+
puts e.message
|
|
79
|
+
puts caller
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
@count_line += 1
|
|
84
|
+
|
|
85
|
+
# 如果匹配到,跳出循环
|
|
86
|
+
break if res
|
|
87
|
+
|
|
88
|
+
# 如果只是单步运行,就返回
|
|
89
|
+
break if single
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# 单行循环
|
|
94
|
+
# stop 为停止出,在停止处之前的每一行都将输出
|
|
95
|
+
def readline_match_block_loop(start, stop, &block)
|
|
96
|
+
stop = Aio::Base::Toolkit::Regexp.safe(stop)
|
|
97
|
+
loop do
|
|
98
|
+
readline_match_block(start, true, &block)
|
|
99
|
+
break if stop.match(self[@count_line])
|
|
100
|
+
break if self[@count_line].nil?
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# 读取一个区间,并返回块
|
|
105
|
+
# 只会执行一次
|
|
106
|
+
# stop 作为分裂符
|
|
107
|
+
# opt 当last为false时,不会对stop一行输出
|
|
108
|
+
# opt 当before为true时,只会分裂stop的前一行,count_line保留
|
|
109
|
+
def readline_range(start, stop, opt={:last=>false}, &block)
|
|
110
|
+
str_context = Context.new
|
|
111
|
+
start = Aio::Base::Toolkit::Regexp.safe(start)
|
|
112
|
+
stop = Aio::Base::Toolkit::Regexp.safe(stop)
|
|
113
|
+
backup_line = @count_line
|
|
114
|
+
|
|
115
|
+
loop do
|
|
116
|
+
line_str = self[@count_line]
|
|
117
|
+
|
|
118
|
+
if line_str.nil?
|
|
119
|
+
@count_line = backup_line
|
|
120
|
+
raise OutLineError
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
if start =~ line_str
|
|
124
|
+
str_context << line_str
|
|
125
|
+
@count_line += 1
|
|
126
|
+
break
|
|
127
|
+
end
|
|
128
|
+
@count_line += 1
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
loop do
|
|
132
|
+
line_str = self[@count_line]
|
|
133
|
+
#raise OutLineError if line_str.nil?
|
|
134
|
+
if stop =~ line_str or line_str.nil?
|
|
135
|
+
str_context << line_str if opt[:last]
|
|
136
|
+
@count_line += 1 unless opt[:before]
|
|
137
|
+
break
|
|
138
|
+
else
|
|
139
|
+
str_context << line_str
|
|
140
|
+
end
|
|
141
|
+
@count_line += 1
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
block.call(str_context)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# 当需要多次循环时使用
|
|
148
|
+
# 此方法用于循环更加安全
|
|
149
|
+
def readline_range_loop(start, stop, opt={:last=>false}, &block)
|
|
150
|
+
loop do
|
|
151
|
+
begin
|
|
152
|
+
readline_range(start, stop, opt, &block)
|
|
153
|
+
rescue OutLineError
|
|
154
|
+
break
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# 读取一个区间并返回块
|
|
160
|
+
# 在起始位置之后的行中,满足条件, 则放入同一区间。否则返回
|
|
161
|
+
def readline_range_if(start, condition, &block)
|
|
162
|
+
str_context = Context.new
|
|
163
|
+
start = Aio::Base::Toolkit::Regexp.safe(start)
|
|
164
|
+
condition = Aio::Base::Toolkit::Regexp.safe(condition)
|
|
165
|
+
|
|
166
|
+
loop do
|
|
167
|
+
line_str = self[@count_line]
|
|
168
|
+
raise OutLineError if line_str.nil?
|
|
169
|
+
if start =~ line_str
|
|
170
|
+
str_context << line_str
|
|
171
|
+
@count_line += 1
|
|
172
|
+
break
|
|
173
|
+
end
|
|
174
|
+
@count_line += 1
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
loop do
|
|
178
|
+
line_str = self[@count_line]
|
|
179
|
+
if condition =~ line_str
|
|
180
|
+
str_context << line_str
|
|
181
|
+
@count_line += 1
|
|
182
|
+
else
|
|
183
|
+
break
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
block.call(str_context)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def readline_range_if_loop(start, condition, &block)
|
|
191
|
+
loop do
|
|
192
|
+
begin
|
|
193
|
+
readline_range_if(start, condition, &block)
|
|
194
|
+
rescue OutLineError
|
|
195
|
+
break
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def count_line
|
|
201
|
+
self[@count_line]
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def method_missing(mid, *arg, &block)
|
|
205
|
+
print_error "#{mid} 方法未定义,请检查方法名拼写"
|
|
206
|
+
puts caller[0]
|
|
207
|
+
super
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
end
|
|
211
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#coding=utf-8
|
|
2
|
+
|
|
3
|
+
module Aio::Text
|
|
4
|
+
class LineString < String
|
|
5
|
+
class Mismatch < StandardError; end
|
|
6
|
+
|
|
7
|
+
include Aio::Ui::Verbose
|
|
8
|
+
|
|
9
|
+
# 获得区块
|
|
10
|
+
def match_block(reg)
|
|
11
|
+
block = reg.match(self)
|
|
12
|
+
#raise Mismatch.new, "reg: #{reg}\nstr: #{self.to_s}" if block.nil?
|
|
13
|
+
if block.nil?
|
|
14
|
+
return false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# 有两种更新的方式,不加str 那么就是从block中的提取
|
|
18
|
+
# 如果有str, 则直接使用str
|
|
19
|
+
def block.update(info, sym, str=nil)
|
|
20
|
+
sym = sym.to_sym
|
|
21
|
+
if info.nil?
|
|
22
|
+
print_error "请检查update中的第一个参数是否定义"
|
|
23
|
+
pp caller
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if str.nil?
|
|
27
|
+
info[sym] = self[sym].strip
|
|
28
|
+
else
|
|
29
|
+
info[sym] = str.strip
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def block.update_arr(info, sym)
|
|
34
|
+
sym = sym.to_sym
|
|
35
|
+
info[sym] ||= []
|
|
36
|
+
info[sym] << self[sym].strip
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def block.update_hash(info, sym, key, val)
|
|
40
|
+
sym = sym.to_sym
|
|
41
|
+
info[sym] ||= {}
|
|
42
|
+
info[sym][key] = val.strip
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# 参数info 放置useful
|
|
46
|
+
# 参数sym 为Symbol类型的标示
|
|
47
|
+
# 参数level 为 :serious 或 :ordinary
|
|
48
|
+
# 参数mod 一般为self
|
|
49
|
+
# 参数opt[:string] 当block中没有sym项时使用
|
|
50
|
+
def block.warning(info, sym, level, mod, opt={})
|
|
51
|
+
sym = sym.to_sym
|
|
52
|
+
self.update(info, sym, opt[:string])
|
|
53
|
+
# Aio::Text::Warning 类中的warning方法
|
|
54
|
+
mod.warning_klass.warning(info, sym, level, mod, opt[:force])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def block.warning_serious(info, sym, mod, opt={})
|
|
58
|
+
sym = sym.to_sym
|
|
59
|
+
self.update(info, sym, opt[:string])
|
|
60
|
+
mod.warning_klass.warning_serious(info, sym, mod, opt[:force])
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def block.warning_ordinary(info, sym, mod, opt={})
|
|
64
|
+
sym = sym.to_sym
|
|
65
|
+
self.update(info, sym, opt[:string])
|
|
66
|
+
mod.warning_klass.warning_ordinary(info, sym, mod, opt[:force])
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
yield block
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|