aio_elin 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+