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.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +675 -0
  3. data/README.md +9 -0
  4. data/config.rb +39 -0
  5. data/lib/aio/base/debug.rb +30 -0
  6. data/lib/aio/base/toolkit/array.rb +24 -0
  7. data/lib/aio/base/toolkit/date.rb +46 -0
  8. data/lib/aio/base/toolkit/deep_clone.rb +10 -0
  9. data/lib/aio/base/toolkit/diff.rb +104 -0
  10. data/lib/aio/base/toolkit/excel_office.rb +421 -0
  11. data/lib/aio/base/toolkit/excel_wps.rb +437 -0
  12. data/lib/aio/base/toolkit/excel_wps.rb.bak +299 -0
  13. data/lib/aio/base/toolkit/ipaddr.rb +28 -0
  14. data/lib/aio/base/toolkit/os.rb +26 -0
  15. data/lib/aio/base/toolkit/regexp.rb +32 -0
  16. data/lib/aio/base/toolkit/string.rb +28 -0
  17. data/lib/aio/base/toolkit/table.rb +441 -0
  18. data/lib/aio/base/toolkit/test_diff.rb +9 -0
  19. data/lib/aio/base/toolkit/test_excel.rb +118 -0
  20. data/lib/aio/base/toolkit/test_word.rb +58 -0
  21. data/lib/aio/base/toolkit/word_wps.rb +492 -0
  22. data/lib/aio/base/toolkit.rb +18 -0
  23. data/lib/aio/base.rb +10 -0
  24. data/lib/aio/core/device/cisco.rb +13 -0
  25. data/lib/aio/core/device/cmd_switch.rb +113 -0
  26. data/lib/aio/core/device/h3c.rb +12 -0
  27. data/lib/aio/core/device/huawei.rb +10 -0
  28. data/lib/aio/core/device/juniper.rb +10 -0
  29. data/lib/aio/core/device/maipu.rb +11 -0
  30. data/lib/aio/core/device/methods.rb +233 -0
  31. data/lib/aio/core/device/methods.rb.bak +199 -0
  32. data/lib/aio/core/device/parent_device.rb +275 -0
  33. data/lib/aio/core/device.rb +15 -0
  34. data/lib/aio/core/device_manager.rb +207 -0
  35. data/lib/aio/core/module/cmd.rb +160 -0
  36. data/lib/aio/core/module/description.rb +67 -0
  37. data/lib/aio/core/module/input_style.rb +98 -0
  38. data/lib/aio/core/module/output_style.rb +80 -0
  39. data/lib/aio/core/module/platform.rb +30 -0
  40. data/lib/aio/core/module/ranking.rb +24 -0
  41. data/lib/aio/core/module/special_style.rb +30 -0
  42. data/lib/aio/core/module/template.rb +13 -0
  43. data/lib/aio/core/module.rb +15 -0
  44. data/lib/aio/core/module_loader.rb +161 -0
  45. data/lib/aio/core/module_loader.rb.bak +148 -0
  46. data/lib/aio/core/module_manager.rb +112 -0
  47. data/lib/aio/core/module_manager.rb.bak +78 -0
  48. data/lib/aio/core/parse/file.rb +19 -0
  49. data/lib/aio/core/parse/parser.rb +91 -0
  50. data/lib/aio/core/parse/parser_machine/bak/has_cmd_state.rb +14 -0
  51. data/lib/aio/core/parse/parser_machine/bak/has_context_state.rb +11 -0
  52. data/lib/aio/core/parse/parser_machine/bak/no_cmd_state.rb +11 -0
  53. data/lib/aio/core/parse/parser_machine/bak/no_context_state.rb +11 -0
  54. data/lib/aio/core/parse/parser_machine/full_state.rb +12 -0
  55. data/lib/aio/core/parse/parser_machine/has_device_state.rb +44 -0
  56. data/lib/aio/core/parse/parser_machine/no_device_state.rb +12 -0
  57. data/lib/aio/core/parse/parser_machine/parent_state.rb +26 -0
  58. data/lib/aio/core/parse/parser_machine.rb +47 -0
  59. data/lib/aio/core/parse.rb +6 -0
  60. data/lib/aio/core/text/context.rb +211 -0
  61. data/lib/aio/core/text/line_string.rb +74 -0
  62. data/lib/aio/core/text/warning.rb +179 -0
  63. data/lib/aio/core/text.rb +7 -0
  64. data/lib/aio/core/warning/description.rb +47 -0
  65. data/lib/aio/core/warning/warning_summarize.rb +232 -0
  66. data/lib/aio/core/warning.rb +6 -0
  67. data/lib/aio/core.rb +32 -0
  68. data/lib/aio/license.rb +687 -0
  69. data/lib/aio/resource/cover_picture.png +0 -0
  70. data/lib/aio/resource/line.png +0 -0
  71. data/lib/aio/resource/logo.png +0 -0
  72. data/lib/aio/ui/banner.rb +85 -0
  73. data/lib/aio/ui/readable_text.rb +75 -0
  74. data/lib/aio/ui/verbose.rb +29 -0
  75. data/lib/aio/ui/version.rb +9 -0
  76. data/lib/aio/ui.rb +138 -0
  77. data/lib/aio.rb +13 -0
  78. data/lib/modules/cmd/cisco/show_clock.rb +32 -0
  79. data/lib/modules/cmd/cisco/show_cpu.rb +32 -0
  80. data/lib/modules/cmd/cisco/show_env.rb +71 -0
  81. data/lib/modules/cmd/cisco/show_failover.rb +39 -0
  82. data/lib/modules/cmd/cisco/show_interface_ip_brief.rb +24 -0
  83. data/lib/modules/cmd/cisco/show_interfaces.rb +177 -0
  84. data/lib/modules/cmd/cisco/show_inv.rb +43 -0
  85. data/lib/modules/cmd/cisco/show_ip_interface_brief.rb +42 -0
  86. data/lib/modules/cmd/cisco/show_ip_ospf_nei.rb +38 -0
  87. data/lib/modules/cmd/cisco/show_ip_route_summary.rb +81 -0
  88. data/lib/modules/cmd/cisco/show_memory.rb +27 -0
  89. data/lib/modules/cmd/cisco/show_process_cpu.rb +35 -0
  90. data/lib/modules/cmd/cisco/show_process_memory.rb +63 -0
  91. data/lib/modules/cmd/cisco/show_version.rb +97 -0
  92. data/lib/modules/cmd/h3c/display_clock.rb +32 -0
  93. data/lib/modules/cmd/h3c/display_cpu.rb +51 -0
  94. data/lib/modules/cmd/h3c/display_device_manuinfo.rb +45 -0
  95. data/lib/modules/cmd/h3c/display_fan.rb +91 -0
  96. data/lib/modules/cmd/h3c/display_interface.rb +203 -0
  97. data/lib/modules/cmd/h3c/display_ip_interface_brief.rb +34 -0
  98. data/lib/modules/cmd/h3c/display_ip_routing.rb +68 -0
  99. data/lib/modules/cmd/h3c/display_ip_routing_stat.rb +90 -0
  100. data/lib/modules/cmd/h3c/display_memory.rb +35 -0
  101. data/lib/modules/cmd/h3c/display_ospf_peer.rb +38 -0
  102. data/lib/modules/cmd/h3c/display_power.rb +90 -0
  103. data/lib/modules/cmd/h3c/display_version.rb +54 -0
  104. data/lib/modules/cmd/h3c/display_vrrp_verbose.rb +86 -0
  105. data/lib/modules/cmd/maipu/show_env.rb +34 -0
  106. data/lib/modules/cmd/maipu/show_ip_route.rb +74 -0
  107. data/lib/modules/cmd/maipu/show_ip_route_statistic.rb +36 -0
  108. data/lib/modules/cmd/maipu/show_memory.rb +31 -0
  109. data/lib/modules/cmd/maipu/show_system_fan.rb +66 -0
  110. data/lib/modules/cmd/maipu/show_system_power.rb +66 -0
  111. data/lib/modules/cmd/maipu/show_version.rb +50 -0
  112. data/lib/modules/description/style/crc.rb +22 -0
  113. data/lib/modules/description/style/input_errors.rb +22 -0
  114. data/lib/modules/description/style/overrun.rb +22 -0
  115. data/lib/modules/description/style/proc_ratio.rb +22 -0
  116. data/lib/modules/description/style/protocol.rb +22 -0
  117. data/lib/modules/description/style/register.rb +22 -0
  118. data/lib/modules/description/style/runts.rb +22 -0
  119. data/lib/modules/description/style/template.rb +22 -0
  120. data/lib/modules/description/style/total_output_drops.rb +22 -0
  121. data/lib/modules/input/style/compare_xml.rb +89 -0
  122. data/lib/modules/input/style/console.rb +222 -0
  123. data/lib/modules/input/style/console.rb.bak +114 -0
  124. data/lib/modules/input/style/xinhua_nat.rb +70 -0
  125. data/lib/modules/output/style/boc_day.rb +223 -0
  126. data/lib/modules/output/style/cmds.rb +77 -0
  127. data/lib/modules/output/style/compare_json.rb +26 -0
  128. data/lib/modules/output/style/compare_report.rb +31 -0
  129. data/lib/modules/output/style/compare_xml.rb +86 -0
  130. data/lib/modules/output/style/excel_table_office.rb +407 -0
  131. data/lib/modules/output/style/excel_table_wps.rb +400 -0
  132. data/lib/modules/output/style/summary_report.rb +563 -0
  133. data/lib/modules/special/style/compare.rb +110 -0
  134. 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,14 @@
1
+ module Aio::Parse::ParserMachine
2
+ class HasCmdState < ParentState
3
+
4
+ def get_cmd
5
+ end
6
+
7
+ def get_context
8
+ end
9
+
10
+ def no_context
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module Aio::Parse::ParserMachine
2
+ class HasContextState < ParentState
3
+
4
+ def get_context
5
+ end
6
+
7
+ def parse_context_ok
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Aio::Parse::ParserMachine
2
+ class NoCmdState < ParentState
3
+
4
+ def no_cmd
5
+ end
6
+
7
+ def get_cmd
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Aio::Parse::ParserMachine
2
+ class NoContextState < ParentState
3
+
4
+ def no_context
5
+ end
6
+
7
+ def get_context
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Aio::Parse
2
+ class FullState < ParentState
3
+
4
+ def get_device(opts)
5
+ @machine.to_has_device_state
6
+ @machine.state.get_device(opts)
7
+ end
8
+
9
+ end
10
+ end
11
+
12
+
@@ -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,12 @@
1
+ module Aio::Parse
2
+ class NoDeviceState < ParentState
3
+
4
+ def get_device(opts={})
5
+ # 首先判断是否已经存在,但是这是初始状态,所以一定没有
6
+ self.device_manager.add_device(opts)
7
+
8
+ @machine.to_has_device_state
9
+ end
10
+
11
+ end
12
+ 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,6 @@
1
+ module Aio::Parse
2
+
3
+ require "aio/core/parse/parser_machine"
4
+ require "aio/core/parse/parser"
5
+
6
+ end
@@ -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
+