ios_parser 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6d921da652a8428e281ceb4e6f9d5e944de3290
4
- data.tar.gz: 4abaa4c7a384ecb7bbd26aa7d3a3408d46936d3a
3
+ metadata.gz: b9c3428424b6fff808e5dcd94412c3d1e0d17ada
4
+ data.tar.gz: a5cda3521efcc1c2f7f2826fb9985b9be384a8f1
5
5
  SHA512:
6
- metadata.gz: d282b754f31317249da935221806a5371053a139a717a1185018ea4dbe8025cce184195c4142f273cb2b1d31be06e82a80f529201092605c6f90e288b1425a2b
7
- data.tar.gz: 79587649306262d302e0b4301259479db48f86d68e1f096187189351a99f3e81ae419101753d3c8d26965c3cfd0705b2cf9f1ee0be24d311f396560249267b78
6
+ metadata.gz: aaeda92fb563f4416c18fc26e2118e30c90f9dc45e7e9da9559c7f84a6adf46e9c57ac3e0b9ffe0adfca38cef089d20bcb20cd0e6e4bebdf5afa63d3f939d598
7
+ data.tar.gz: 881b58760c2426e08c49e5cad4db0db21e1fb95f14ddeb31ea465853cd81aa14fca33c5a1d04ec0ee2396b9fec99e27022156b693998eeb666bc664bc54b55af
data/CHANGELOG.md CHANGED
@@ -1,14 +1,10 @@
1
- ## 0.1.1 (2015-03-05)
2
- Bugfixes:
3
-
4
- - Parser throws `ArgumentError` when input is not a string - [PR#1](https://github.rackspace.com/backbone/ios_parser/pull/1)
5
-
6
- ## 0.1.0 (2015-02-17)
1
+ ## 0.3.1 (2016-03-07)
7
2
 
8
3
  Bugfixes:
9
4
 
10
- - `Document#each` and `Command#each` will visit all nodes
5
+ - allow banners to contain the terminating character under some circumstances
6
+ - process `#` as a comment-leader only if no non-whitespace character precedes it
11
7
 
12
- Features:
8
+ ## 0.3.0 (2016-03-04)
13
9
 
14
- - `Command#path` provides nested context
10
+ - Initial public release
data/Guardfile CHANGED
@@ -1,7 +1,12 @@
1
+ guard :rake, task: 'compile' do
2
+ watch(%r{^ext/(.+)\.[ch]$})
3
+ end
4
+
1
5
  guard :rspec, cmd: 'bundle exec rspec --color --fail-fast' do
2
6
  watch(%r{^spec/.+_spec\.rb$}) { |m| m }
3
7
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
8
  watch('spec/spec_helper.rb') { 'spec' }
9
+ watch(%r{^ext/(.+)\.[ch]$}) { 'spec' }
5
10
  end
6
11
 
7
12
  guard :rubocop, cli: '-D -a' do
@@ -32,15 +32,16 @@ typedef struct LexInfo LexInfo;
32
32
 
33
33
  #define IS_SPACE(C) C == ' ' || C == '\t' || C == '\r'
34
34
  #define IS_NEWLINE(C) C == '\n'
35
- #define IS_COMMENT(C) C == '#' || C == '!'
35
+ #define IS_COMMENT(C) C == '!'
36
36
  #define IS_DIGIT(C) '0' <= C && C <= '9'
37
37
  #define IS_DOT(C) C == '.'
38
38
  #define IS_DECIMAL(C) IS_DIGIT(C) || IS_DOT(C)
39
39
  #define IS_LETTER(C) 'a' <= C && C <= 'z' || 'A' <= C && C <= 'Z'
40
- #define IS_PUNCT(C) strchr("-+$:/,()|*#=<>!\"\\&@;%~{}'\"?[]_^", C)
40
+ #define IS_PUNCT(C) strchr("-+$:/,()|*#=<>!\"\\&@;%~{}'\"?[]_^`", C)
41
41
  #define IS_WORD(C) IS_DECIMAL(C) || IS_LETTER(C) || IS_PUNCT(C)
42
42
  #define IS_LEAD_ZERO(C) C == '0'
43
43
  #define IS_QUOTE(C) C == '"' || C == '\''
44
+ #define IS_LEAD_COMMENT(C) C == '#' || C == '!'
44
45
 
45
46
  #define CURRENT_CHAR(LEX) LEX->text[LEX->pos]
46
47
  #define TOKEN_EMPTY(LEX) LEX->token_length <= 0
@@ -302,7 +303,9 @@ static void start_certificate(LexInfo *lex) {
302
303
  static void process_banner(LexInfo *lex) {
303
304
  char c = CURRENT_CHAR(lex);
304
305
 
305
- if (c == lex->banner_delimiter) {
306
+ if (c == lex->banner_delimiter &&
307
+ (0 < lex->pos && '\n' == lex->text[lex->pos - 1] ||
308
+ '\n' == lex->text[lex->pos + 1])) {
306
309
  lex->token_length++;
307
310
  delimit(lex);
308
311
  lex->token_start = lex->pos;
@@ -316,6 +319,7 @@ static void process_banner(LexInfo *lex) {
316
319
  static void start_banner(LexInfo *lex) {
317
320
  lex->banner_delimiter = CURRENT_CHAR(lex);
318
321
  ADD_TOKEN(lex, ID2SYM(rb_intern("BANNER_BEGIN")));
322
+ if ('\n' == lex->text[lex->pos + 2]) lex->pos++;
319
323
  }
320
324
 
321
325
  static void process_start_of_line(LexInfo *lex) {
@@ -339,7 +343,11 @@ static void process_start_of_line(LexInfo *lex) {
339
343
  }
340
344
  }
341
345
 
342
- process_root(lex);
346
+ if (IS_LEAD_COMMENT(c)) {
347
+ lex->token_state = LEX_STATE_COMMENT;
348
+ } else {
349
+ process_root(lex);
350
+ }
343
351
  }
344
352
 
345
353
  static void process_root(LexInfo *lex) {
@@ -0,0 +1,24 @@
1
+ banner exec ^C
2
+
3
+ / /
4
+ (\/_//`)
5
+ / '/
6
+ 0 0 \
7
+ / \
8
+ / __/ \
9
+ /, _/ \ \_
10
+ `-./ ) | ~^~^~^~^~^~^~^~\~.
11
+ ( / \_}
12
+ | / |
13
+ ; | \ /
14
+ \/ ,/ \ |
15
+ / /~~|~|~~~~~~|~|\ |
16
+ / / | | | | `\ \
17
+ / / | | | | \ \
18
+ / ( | | | | \ \
19
+ jgs /,_) /__) /__) /,_/
20
+ '''''"""""'''""""""'''""""""''"""""'''''
21
+
22
+ Welcome to the Goat Rodeo!!
23
+
24
+ ^C
data/ios_parser.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.add_development_dependency 'rspec', '~>3.2'
19
19
  s.add_development_dependency 'rubocop', '~>0.37'
20
20
  s.add_development_dependency 'guard', '~>2.0'
21
+ s.add_development_dependency 'guard-rake', '~>1.0'
21
22
  s.add_development_dependency 'guard-rspec', '~>4.5'
22
23
  s.add_development_dependency 'guard-rubocop', '~>1.2'
23
24
  s.add_development_dependency 'rake-compiler', '~>0.9'
@@ -15,7 +15,7 @@ module IOSParser
15
15
  end
16
16
 
17
17
  def call(input_text)
18
- initialize
18
+ @text = input_text
19
19
 
20
20
  input_text.each_char.with_index do |c, i|
21
21
  @this_char = i
@@ -50,6 +50,14 @@ module IOSParser
50
50
  raise LexError, "Unknown character #{char.inspect}"
51
51
  end
52
52
 
53
+ def root_line_start
54
+ if lead_comment?
55
+ comment
56
+ else
57
+ root
58
+ end
59
+ end
60
+
53
61
  def make_token(value, pos: nil)
54
62
  pos ||= @token_start || @this_char
55
63
  @token_start = nil
@@ -63,6 +71,10 @@ module IOSParser
63
71
  end
64
72
 
65
73
  def comment?
74
+ char == '!'
75
+ end
76
+
77
+ def lead_comment?
66
78
  char == '#' || char == '!'
67
79
  end
68
80
 
@@ -78,7 +90,12 @@ module IOSParser
78
90
  end
79
91
 
80
92
  def banner
81
- char == @banner_delimiter ? banner_end : token << char
93
+ if char == @banner_delimiter && (@text[@this_char - 1] == "\n" ||
94
+ @text[@this_char + 1] == "\n")
95
+ banner_end
96
+ else
97
+ token << char
98
+ end
82
99
  end
83
100
 
84
101
  def banner_end
@@ -91,7 +108,6 @@ module IOSParser
91
108
  def banner_end_clean_token
92
109
  token.slice!(0) if token[0] == 'C'
93
110
  token.slice!(0) if ["\n", ' '].include?(token[0])
94
- token.chomp!("\n")
95
111
  end
96
112
 
97
113
  def scrub_banner_garbage
@@ -200,7 +216,7 @@ module IOSParser
200
216
  ('A'..'Z').cover?(char) ||
201
217
  ['-', '+', '$', ':', '/', ',', '(', ')', '|', '*', '#', '=', '<', '>',
202
218
  '!', '"', '&', '@', ';', '%', '~', '{', '}', "'", '?', '[', ']', '_',
203
- '^', '\\'].include?(char)
219
+ '^', '\\', '`'].include?(char)
204
220
  end
205
221
 
206
222
  def space
@@ -246,7 +262,7 @@ module IOSParser
246
262
  self.indent += 1
247
263
  else
248
264
  update_indentation
249
- root
265
+ root_line_start
250
266
  end
251
267
  end
252
268
 
@@ -1,7 +1,7 @@
1
1
  module IOSParser
2
2
  class << self
3
3
  def version
4
- '0.3.0'
4
+ '0.3.1'
5
5
  end
6
6
  end
7
7
  end
@@ -190,10 +190,14 @@ sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
190
190
 
191
191
 
192
192
  END
193
- banner_command = "banner exec ^C#{banner_text}^C\n"
193
+ banner_command = "banner exec ^C\n#{banner_text}^C\n"
194
194
 
195
195
  result = klass.new.call(banner_command)
196
196
  expect(result[0].args[2]).to eq banner_text
197
+
198
+ pure_result = klass.new(lexer: IOSParser::PureLexer.new)
199
+ .call(banner_command)
200
+ expect(pure_result[0].args[2]).to eq banner_text
197
201
  end
198
202
 
199
203
  it('parses a crypto trustpoint section') do
@@ -111,6 +111,20 @@ END
111
111
  end
112
112
  end
113
113
 
114
+ context 'complex banner' do
115
+ let(:input) do
116
+ text_fixture('complex_banner')
117
+ end
118
+
119
+ let(:output) do
120
+ content = text_fixture('complex_banner').lines[1..-2].join
121
+ ['banner', 'exec', :BANNER_BEGIN, content, :BANNER_END, :EOL]
122
+ end
123
+
124
+ it { expect(subject.map(&:last)).to eq output }
125
+ it { expect(subject_pure.map(&:last)).to eq output }
126
+ end
127
+
114
128
  context 'decimal number' do
115
129
  let(:input) { 'boson levels at 93.2' }
116
130
  let(:output) { ['boson', 'levels', 'at', 93.2] }
@@ -226,6 +240,30 @@ END
226
240
 
227
241
  it { expect(subject_pure.map(&:last)).to eq output }
228
242
  end
243
+
244
+ context '# in the middle of a line is not a comment' do
245
+ let(:input) { "vlan 1\n name #31337" }
246
+ let(:output) { ['vlan', 1, :EOL, :INDENT, 'name', '#31337', :DEDENT] }
247
+
248
+ it { expect(subject_pure.map(&:last)).to eq output }
249
+ it { expect(subject.map(&:last)).to eq output }
250
+ end
251
+
252
+ context '# at the start of a line is a comment' do
253
+ let(:input) { "vlan 1\n# comment\nvlan 2" }
254
+ let(:output) { ['vlan', 1, :EOL, 'vlan', 2] }
255
+
256
+ it { expect(subject_pure.map(&:last)).to eq output }
257
+ it { expect(subject.map(&:last)).to eq output }
258
+ end
259
+
260
+ context '# after indentation is a comment' do
261
+ let(:input) { "vlan 1\n # comment\nvlan 2" }
262
+ let(:output) { ['vlan', 1, :EOL, :INDENT, :DEDENT, 'vlan', 2] }
263
+
264
+ it { expect(subject_pure.map(&:last)).to eq output }
265
+ it { expect(subject.map(&:last)).to eq output }
266
+ end
229
267
  end
230
268
  end
231
269
  end
data/spec/spec_helper.rb CHANGED
@@ -3,3 +3,7 @@ $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
3
3
  def klass
4
4
  described_class
5
5
  end
6
+
7
+ def text_fixture(name)
8
+ File.read(File.expand_path(__dir__ + "/../fixtures/#{name}.txt"))
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ios_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Miller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-05 00:00:00.000000000 Z
11
+ date: 2016-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: guard-rspec
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -117,6 +131,7 @@ files:
117
131
  - doc/state_machine.png
118
132
  - ext/ios_parser/c_lexer/extconf.rb
119
133
  - ext/ios_parser/c_lexer/lexer.c
134
+ - fixtures/complex_banner.txt
120
135
  - ios_parser.gemspec
121
136
  - lib/ios_parser.rb
122
137
  - lib/ios_parser/ios.rb
@@ -161,4 +176,3 @@ test_files:
161
176
  - spec/lib/ios_parser/lexer_spec.rb
162
177
  - spec/lib/ios_parser_spec.rb
163
178
  - spec/spec_helper.rb
164
- has_rdoc: