xcpretty 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,364 @@
1
+ require 'strscan'
2
+
3
+ module JSON
4
+
5
+ def self.parse source
6
+ Pure::Parser.new(source).parse
7
+ end
8
+
9
+ module Pure
10
+ # This class implements the JSON parser that is used to parse a JSON string
11
+ # into a Ruby data structure.
12
+ class Parser < StringScanner
13
+ STRING = /" ((?:[^\x0-\x1f"\\] |
14
+ # escaped special characters:
15
+ \\["\\\/bfnrt] |
16
+ \\u[0-9a-fA-F]{4} |
17
+ # match all but escaped special characters:
18
+ \\[\x20-\x21\x23-\x2e\x30-\x5b\x5d-\x61\x63-\x65\x67-\x6d\x6f-\x71\x73\x75-\xff])*)
19
+ "/nx
20
+ INTEGER = /(-?0|-?[1-9]\d*)/
21
+ FLOAT = /(-?
22
+ (?:0|[1-9]\d*)
23
+ (?:
24
+ \.\d+(?i:e[+-]?\d+) |
25
+ \.\d+ |
26
+ (?i:e[+-]?\d+)
27
+ )
28
+ )/x
29
+ NAN = /NaN/
30
+ INFINITY = /Infinity/
31
+ MINUS_INFINITY = /-Infinity/
32
+ OBJECT_OPEN = /\{/
33
+ OBJECT_CLOSE = /\}/
34
+ ARRAY_OPEN = /\[/
35
+ ARRAY_CLOSE = /\]/
36
+ PAIR_DELIMITER = /:/
37
+ COLLECTION_DELIMITER = /,/
38
+ TRUE = /true/
39
+ FALSE = /false/
40
+ NULL = /null/
41
+ IGNORE = %r(
42
+ (?:
43
+ //[^\n\r]*[\n\r]| # line comments
44
+ /\* # c-style comments
45
+ (?:
46
+ [^*/]| # normal chars
47
+ /[^*]| # slashes that do not start a nested comment
48
+ \*[^/]| # asterisks that do not end this comment
49
+ /(?=\*/) # single slash before this comment's end
50
+ )*
51
+ \*/ # the End of this comment
52
+ |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
53
+ )+
54
+ )mx
55
+
56
+ UNPARSED = Object.new
57
+
58
+ # Creates a new JSON::Pure::Parser instance for the string _source_.
59
+ #
60
+ # It will be configured by the _opts_ hash. _opts_ can have the following
61
+ # keys:
62
+ # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
63
+ # structures. Disable depth checking with :max_nesting => false|nil|0,
64
+ # it defaults to 100.
65
+ # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
66
+ # defiance of RFC 4627 to be parsed by the Parser. This option defaults
67
+ # to false.
68
+ # * *symbolize_names*: If set to true, returns symbols for the names
69
+ # (keys) in a JSON object. Otherwise strings are returned, which is also
70
+ # the default.
71
+ # * *create_additions*: If set to true, the Parser creates
72
+ # additions when if a matching class and create_id was found. This
73
+ # option defaults to false.
74
+ # * *object_class*: Defaults to Hash
75
+ # * *array_class*: Defaults to Array
76
+ # * *quirks_mode*: Enables quirks_mode for parser, that is for example
77
+ # parsing single JSON values instead of documents is possible.
78
+ def initialize(source, opts = {})
79
+ opts ||= {}
80
+ unless @quirks_mode = opts[:quirks_mode]
81
+ source = convert_encoding source
82
+ end
83
+ super source
84
+ if !opts.key?(:max_nesting) # defaults to 100
85
+ @max_nesting = 100
86
+ elsif opts[:max_nesting]
87
+ @max_nesting = opts[:max_nesting]
88
+ else
89
+ @max_nesting = 0
90
+ end
91
+ @allow_nan = !!opts[:allow_nan]
92
+ @symbolize_names = !!opts[:symbolize_names]
93
+ if opts.key?(:create_additions)
94
+ @create_additions = !!opts[:create_additions]
95
+ else
96
+ @create_additions = false
97
+ end
98
+ @create_id = @create_additions ? JSON.create_id : nil
99
+ @object_class = opts[:object_class] || Hash
100
+ @array_class = opts[:array_class] || Array
101
+ @match_string = opts[:match_string]
102
+ end
103
+
104
+ alias source string
105
+
106
+ def quirks_mode?
107
+ !!@quirks_mode
108
+ end
109
+
110
+ def reset
111
+ super
112
+ @current_nesting = 0
113
+ end
114
+
115
+ # Parses the current JSON string _source_ and returns the complete data
116
+ # structure as a result.
117
+ def parse
118
+ reset
119
+ obj = nil
120
+ if @quirks_mode
121
+ while !eos? && skip(IGNORE)
122
+ end
123
+ if eos?
124
+ raise ParserError, "source did not contain any JSON!"
125
+ else
126
+ obj = parse_value
127
+ obj == UNPARSED and raise ParserError, "source did not contain any JSON!"
128
+ end
129
+ else
130
+ until eos?
131
+ case
132
+ when scan(OBJECT_OPEN)
133
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
134
+ @current_nesting = 1
135
+ obj = parse_object
136
+ when scan(ARRAY_OPEN)
137
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
138
+ @current_nesting = 1
139
+ obj = parse_array
140
+ when skip(IGNORE)
141
+ ;
142
+ else
143
+ raise ParserError, "source '#{peek(20)}' not in JSON!"
144
+ end
145
+ end
146
+ obj or raise ParserError, "source did not contain any JSON!"
147
+ end
148
+ obj
149
+ end
150
+
151
+ private
152
+
153
+ def convert_encoding(source)
154
+ if source.respond_to?(:to_str)
155
+ source = source.to_str
156
+ else
157
+ raise TypeError, "#{source.inspect} is not like a string"
158
+ end
159
+ if defined?(::Encoding)
160
+ if source.encoding == ::Encoding::ASCII_8BIT
161
+ b = source[0, 4].bytes.to_a
162
+ source =
163
+ case
164
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
165
+ source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
166
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
167
+ source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
168
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
169
+ source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
170
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
171
+ source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
172
+ else
173
+ source.dup
174
+ end
175
+ else
176
+ source = source.encode(::Encoding::UTF_8)
177
+ end
178
+ source.force_encoding(::Encoding::ASCII_8BIT)
179
+ else
180
+ b = source
181
+ source =
182
+ case
183
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
184
+ JSON.iconv('utf-8', 'utf-32be', b)
185
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
186
+ JSON.iconv('utf-8', 'utf-16be', b)
187
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
188
+ JSON.iconv('utf-8', 'utf-32le', b)
189
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
190
+ JSON.iconv('utf-8', 'utf-16le', b)
191
+ else
192
+ b
193
+ end
194
+ end
195
+ source
196
+ end
197
+
198
+ # Unescape characters in strings.
199
+ UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
200
+ UNESCAPE_MAP.update({
201
+ ?" => '"',
202
+ ?\\ => '\\',
203
+ ?/ => '/',
204
+ ?b => "\b",
205
+ ?f => "\f",
206
+ ?n => "\n",
207
+ ?r => "\r",
208
+ ?t => "\t",
209
+ ?u => nil,
210
+ })
211
+
212
+ EMPTY_8BIT_STRING = ''
213
+ if ::String.method_defined?(:encode)
214
+ EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
215
+ end
216
+
217
+ def parse_string
218
+ if scan(STRING)
219
+ return '' if self[1].empty?
220
+ string = self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
221
+ if u = UNESCAPE_MAP[$&[1]]
222
+ u
223
+ else # \uXXXX
224
+ bytes = EMPTY_8BIT_STRING.dup
225
+ i = 0
226
+ while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
227
+ bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
228
+ i += 1
229
+ end
230
+ JSON.iconv('utf-8', 'utf-16be', bytes)
231
+ end
232
+ end
233
+ if string.respond_to?(:force_encoding)
234
+ string.force_encoding(::Encoding::UTF_8)
235
+ end
236
+ if @create_additions and @match_string
237
+ for (regexp, klass) in @match_string
238
+ klass.json_creatable? or next
239
+ string =~ regexp and return klass.json_create(string)
240
+ end
241
+ end
242
+ string
243
+ else
244
+ UNPARSED
245
+ end
246
+ rescue => e
247
+ raise ParserError, "Caught #{e.class} at '#{peek(20)}': #{e}"
248
+ end
249
+
250
+ def parse_value
251
+ case
252
+ when scan(FLOAT)
253
+ Float(self[1])
254
+ when scan(INTEGER)
255
+ Integer(self[1])
256
+ when scan(TRUE)
257
+ true
258
+ when scan(FALSE)
259
+ false
260
+ when scan(NULL)
261
+ nil
262
+ when (string = parse_string) != UNPARSED
263
+ string
264
+ when scan(ARRAY_OPEN)
265
+ @current_nesting += 1
266
+ ary = parse_array
267
+ @current_nesting -= 1
268
+ ary
269
+ when scan(OBJECT_OPEN)
270
+ @current_nesting += 1
271
+ obj = parse_object
272
+ @current_nesting -= 1
273
+ obj
274
+ when @allow_nan && scan(NAN)
275
+ NaN
276
+ when @allow_nan && scan(INFINITY)
277
+ Infinity
278
+ when @allow_nan && scan(MINUS_INFINITY)
279
+ MinusInfinity
280
+ else
281
+ UNPARSED
282
+ end
283
+ end
284
+
285
+ def parse_array
286
+ raise NestingError, "nesting of #@current_nesting is too deep" if
287
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
288
+ result = @array_class.new
289
+ delim = false
290
+ until eos?
291
+ case
292
+ when (value = parse_value) != UNPARSED
293
+ delim = false
294
+ result << value
295
+ skip(IGNORE)
296
+ if scan(COLLECTION_DELIMITER)
297
+ delim = true
298
+ elsif match?(ARRAY_CLOSE)
299
+ ;
300
+ else
301
+ raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
302
+ end
303
+ when scan(ARRAY_CLOSE)
304
+ if delim
305
+ raise ParserError, "expected next element in array at '#{peek(20)}'!"
306
+ end
307
+ break
308
+ when skip(IGNORE)
309
+ ;
310
+ else
311
+ raise ParserError, "unexpected token in array at '#{peek(20)}'!"
312
+ end
313
+ end
314
+ result
315
+ end
316
+
317
+ def parse_object
318
+ raise NestingError, "nesting of #@current_nesting is too deep" if
319
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
320
+ result = @object_class.new
321
+ delim = false
322
+ until eos?
323
+ case
324
+ when (string = parse_string) != UNPARSED
325
+ skip(IGNORE)
326
+ unless scan(PAIR_DELIMITER)
327
+ raise ParserError, "expected ':' in object at '#{peek(20)}'!"
328
+ end
329
+ skip(IGNORE)
330
+ unless (value = parse_value).equal? UNPARSED
331
+ result[@symbolize_names ? string.to_sym : string] = value
332
+ delim = false
333
+ skip(IGNORE)
334
+ if scan(COLLECTION_DELIMITER)
335
+ delim = true
336
+ elsif match?(OBJECT_CLOSE)
337
+ ;
338
+ else
339
+ raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
340
+ end
341
+ else
342
+ raise ParserError, "expected value in object at '#{peek(20)}'!"
343
+ end
344
+ when scan(OBJECT_CLOSE)
345
+ if delim
346
+ raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
347
+ end
348
+ if @create_additions and klassname = result[@create_id]
349
+ klass = JSON.deep_const_get klassname
350
+ break unless klass and klass.json_creatable?
351
+ result = klass.json_create(result)
352
+ end
353
+ break
354
+ when skip(IGNORE)
355
+ ;
356
+ else
357
+ raise ParserError, "unexpected token in object at '#{peek(20)}'!"
358
+ end
359
+ end
360
+ result
361
+ end
362
+ end
363
+ end
364
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcpretty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marin Usalj
@@ -9,62 +9,62 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-23 00:00:00.000000000 Z
12
+ date: 2014-04-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ~>
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
20
  version: '1.3'
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ~>
25
+ - - "~>"
26
26
  - !ruby/object:Gem::Version
27
27
  version: '1.3'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - '>='
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '0'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - '>='
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rspec
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - '>='
46
+ - - ">="
47
47
  - !ruby/object:Gem::Version
48
48
  version: '0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - '>='
53
+ - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: cucumber
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - '>='
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - '>='
67
+ - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  description: "\n Xcodebuild formatter designed to be piped with `xcodebuild`,\n and
@@ -78,9 +78,9 @@ executables:
78
78
  extensions: []
79
79
  extra_rdoc_files: []
80
80
  files:
81
- - .gitignore
82
- - .kick
83
- - .travis.yml
81
+ - ".gitignore"
82
+ - ".kick"
83
+ - ".travis.yml"
84
84
  - CHANGELOG.md
85
85
  - CONTRIBUTING.md
86
86
  - Gemfile
@@ -92,11 +92,13 @@ files:
92
92
  - features/custom_formatter.feature
93
93
  - features/fixtures/xcodebuild.log
94
94
  - features/html_report.feature
95
+ - features/json_compilation_database_report.feature
95
96
  - features/junit_report.feature
96
97
  - features/knock_format.feature
97
98
  - features/simple_format.feature
98
99
  - features/steps/formatting_steps.rb
99
100
  - features/steps/html_steps.rb
101
+ - features/steps/json_steps.rb
100
102
  - features/steps/junit_steps.rb
101
103
  - features/steps/report_steps.rb
102
104
  - features/steps/xcpretty_steps.rb
@@ -114,6 +116,7 @@ files:
114
116
  - lib/xcpretty/parser.rb
115
117
  - lib/xcpretty/printer.rb
116
118
  - lib/xcpretty/reporters/html.rb
119
+ - lib/xcpretty/reporters/json_compilation_database.rb
117
120
  - lib/xcpretty/reporters/junit.rb
118
121
  - lib/xcpretty/syntax.rb
119
122
  - lib/xcpretty/version.rb
@@ -131,6 +134,10 @@ files:
131
134
  - spec/xcpretty/parser_spec.rb
132
135
  - spec/xcpretty/printer_spec.rb
133
136
  - spec/xcpretty/syntax_spec.rb
137
+ - vendor/json_pure/COPYING
138
+ - vendor/json_pure/LICENSE
139
+ - vendor/json_pure/generator.rb
140
+ - vendor/json_pure/parser.rb
134
141
  - xcpretty.gemspec
135
142
  homepage: https://github.com/mneorr/xcpretty
136
143
  licenses:
@@ -142,17 +149,17 @@ require_paths:
142
149
  - lib
143
150
  required_ruby_version: !ruby/object:Gem::Requirement
144
151
  requirements:
145
- - - '>='
152
+ - - ">="
146
153
  - !ruby/object:Gem::Version
147
154
  version: 1.8.7
148
155
  required_rubygems_version: !ruby/object:Gem::Requirement
149
156
  requirements:
150
- - - '>='
157
+ - - ">="
151
158
  - !ruby/object:Gem::Version
152
159
  version: '0'
153
160
  requirements: []
154
161
  rubyforge_project:
155
- rubygems_version: 2.0.3
162
+ rubygems_version: 2.2.0
156
163
  signing_key:
157
164
  specification_version: 4
158
165
  summary: xcodebuild formatter done right
@@ -160,11 +167,13 @@ test_files:
160
167
  - features/custom_formatter.feature
161
168
  - features/fixtures/xcodebuild.log
162
169
  - features/html_report.feature
170
+ - features/json_compilation_database_report.feature
163
171
  - features/junit_report.feature
164
172
  - features/knock_format.feature
165
173
  - features/simple_format.feature
166
174
  - features/steps/formatting_steps.rb
167
175
  - features/steps/html_steps.rb
176
+ - features/steps/json_steps.rb
168
177
  - features/steps/junit_steps.rb
169
178
  - features/steps/report_steps.rb
170
179
  - features/steps/xcpretty_steps.rb