sdl4r 0.9.6 → 0.9.7

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 (45) hide show
  1. data/CHANGELOG +49 -2
  2. data/Rakefile +35 -5
  3. data/TODO +29 -3
  4. data/doc/classes/SDL4R.html +386 -674
  5. data/doc/classes/SDL4R/Parser.html +183 -307
  6. data/doc/classes/SDL4R/ParserTest.html +357 -0
  7. data/doc/classes/SDL4R/SDL4RTest.html +532 -0
  8. data/doc/classes/SDL4R/SDLTest.html +77 -0
  9. data/doc/classes/SDL4R/SdlBinary.html +180 -295
  10. data/doc/classes/SDL4R/SdlParseError.html +105 -180
  11. data/doc/classes/SDL4R/SdlTimeSpan.html +628 -939
  12. data/doc/classes/SDL4R/Tag.html +1236 -2036
  13. data/doc/classes/SDL4R/TagTest.html +292 -0
  14. data/doc/created.rid +1 -1
  15. data/doc/files/CHANGELOG.html +183 -184
  16. data/doc/files/LICENSE.html +496 -755
  17. data/doc/files/README.html +399 -623
  18. data/doc/files/lib/sdl4r/parser/reader_rb.html +53 -106
  19. data/doc/files/lib/sdl4r/parser/time_span_with_zone_rb.html +53 -106
  20. data/doc/files/lib/sdl4r/parser/token_rb.html +53 -106
  21. data/doc/files/lib/sdl4r/parser/tokenizer_rb.html +53 -106
  22. data/doc/files/lib/sdl4r/parser_rb.html +60 -112
  23. data/doc/files/lib/sdl4r/sdl4r_rb.html +62 -114
  24. data/doc/files/lib/sdl4r/sdl_binary_rb.html +53 -106
  25. data/doc/files/lib/sdl4r/sdl_parse_error_rb.html +53 -106
  26. data/doc/files/lib/sdl4r/sdl_time_span_rb.html +53 -106
  27. data/doc/files/lib/sdl4r/tag_rb.html +62 -114
  28. data/doc/files/lib/sdl4r_rb.html +53 -106
  29. data/doc/files/test/sdl4r/parser_test_rb.html +63 -0
  30. data/doc/files/test/sdl4r/sdl4r_test_rb.html +66 -0
  31. data/doc/files/test/sdl4r/sdl_test_rb.html +63 -0
  32. data/doc/files/test/sdl4r/tag_test_rb.html +63 -0
  33. data/doc/fr_class_index.html +19 -32
  34. data/doc/fr_file_index.html +37 -40
  35. data/doc/fr_method_index.html +4707 -114
  36. data/doc/index.html +14 -23
  37. data/doc/rdoc-style.css +323 -203
  38. data/lib/sdl4r/parser/reader.rb +26 -19
  39. data/lib/sdl4r/parser/token.rb +3 -3
  40. data/lib/sdl4r/parser/tokenizer.rb +93 -98
  41. data/lib/sdl4r/sdl_parse_error.rb +2 -2
  42. data/lib/sdl4r/tag.rb +127 -73
  43. data/test/sdl4r/parser_test.rb +109 -11
  44. data/test/sdl4r/tag_test.rb +73 -4
  45. metadata +15 -12
@@ -29,16 +29,24 @@ module SDL4R
29
29
 
30
30
  # +io+ an open IO from which the characters are read.
31
31
  def initialize(io)
32
- raise ArgumentError, "io == nil" if io.nil?
32
+ raise ArgumentError, "io == nil" unless io
33
33
 
34
34
  @io = io
35
35
  @line = nil
36
36
  @line_chars = nil
37
- @line_no = 0
37
+ @line_no = -1
38
38
  @pos = 0
39
39
  end
40
40
 
41
- attr_reader :line_no, :pos, :line;
41
+ # The current line no (zero-based)
42
+ attr_reader :line_no
43
+
44
+ # The position of the char currently pointed by this reader in the current line.
45
+ # This is not necessarily the position of the char you just got from a method, it might be
46
+ # the position of the next char, for instance.
47
+ attr_reader :pos
48
+
49
+ attr_reader :line
42
50
 
43
51
  def line_length
44
52
  return @line_chars.nil? ? 0 : @line_chars.length
@@ -65,22 +73,22 @@ module SDL4R
65
73
  end
66
74
 
67
75
  # Indicates whether the end of file has been reached.
68
- def end_of_file?
76
+ def eof?
69
77
  return @line.nil?
70
78
  end
71
79
 
72
- # Indicates whether there are more characters in the current line
80
+ # Indicates whether there are more characters in the current line after the current char
73
81
  def more_chars_in_line?
74
82
  return @pos < line_length - 1
75
83
  end
76
84
 
77
85
  # Returns whether the end of the current +line+ as been reached.
78
- def end_of_line?
86
+ def eol?
79
87
  return @pos >= line_length
80
88
  end
81
89
 
82
90
  # Skips the current line by going just after its end.
83
- def skip_line
91
+ def skip_to_eol
84
92
  @pos = line_length
85
93
  end
86
94
 
@@ -107,24 +115,27 @@ module SDL4R
107
115
  return get_line_char(@pos)
108
116
  end
109
117
 
110
- # Go to the next character in the stream.
118
+ # Go to the next character in the line. This method doesn't skip to the next line once the
119
+ # reached eol.
111
120
  def skip_char
112
121
  @pos += 1 if @pos < line_length
113
122
  end
114
123
 
115
- # Go to the next character and returns it (or nil if end-of-line or -file has been reached).
124
+ # Returns the current char and go to the next.
125
+ # Returns nil if end-of-line or -file has been reached.
116
126
  def read_char
127
+ c = current_char
117
128
  skip_char()
118
- return current_char
129
+ c
119
130
  end
120
131
 
121
132
  # Returns to the previous char if possible.
122
133
  def previous_char
123
- @pos -= 1 if @pos >= -1
134
+ @pos -= 1 if @pos >= 1
124
135
  end
125
136
 
126
- # Returns the next index of the expression (string, regexp, fixnum) in the current line, starting
127
- # from after the current position if no position is specified.
137
+ # Returns the next index of the expression (string, regexp, fixnum) in the current line,
138
+ # starting from after the current position if no position is specified.
128
139
  def find_next_in_line(searched, start_pos = nil)
129
140
  start_pos = @pos + 1 unless start_pos
130
141
  return @line.index(searched, start_pos)
@@ -149,12 +160,8 @@ module SDL4R
149
160
  def read_raw_line
150
161
  @line = @io.gets()
151
162
 
152
- # We ensure that only \n is used as an end-of-line by replacing \r and \r\n.
153
- if @line
154
- if not @line.gsub!(/\r\n/m, "\n")
155
- @line.gsub!(/\r/m, "\n")
156
- end
157
- end
163
+ # Remove a possible \r at the end of line
164
+ @line.gsub!(/\r+$/, "") if @line
158
165
 
159
166
  @pos = 0;
160
167
  @line_chars = nil
@@ -33,7 +33,7 @@ module SDL4R
33
33
  def initialize(text, line = -1, position = -1)
34
34
  @text = text
35
35
  @line = line
36
- @pos = position
36
+ @position = position
37
37
  @size = text.length
38
38
 
39
39
  begin
@@ -92,7 +92,7 @@ module SDL4R
92
92
  end
93
93
 
94
94
  rescue ArgumentError
95
- raise SdlParseError.new($!.message, @line, @pos)
95
+ raise SdlParseError.new($!.message, @line, @position)
96
96
  end
97
97
 
98
98
  @type = :IDENTIFIER if @type.nil? # if all hope is lost, it's an identifier
@@ -116,7 +116,7 @@ module SDL4R
116
116
  end
117
117
 
118
118
  def to_s
119
- @type.to_s + " " + @text + " pos:" + @pos.to_s
119
+ @type.to_s + " " + @text + " pos:" + @position.to_s
120
120
  end
121
121
 
122
122
  # This special parse method is used only by the Token class for
@@ -45,9 +45,9 @@ module SDL4R
45
45
 
46
46
  @reader = Parser::Reader.new(io)
47
47
  @token_start = 0
48
- @startEscapedQuoteLine = false
48
+ @starting_escaped_quote_line = false
49
49
  @tokens = nil
50
- @tokenText = nil
50
+ @token_text = nil
51
51
  end
52
52
 
53
53
  # Closes this Tokenizer and its underlying +Reader+.
@@ -55,19 +55,12 @@ module SDL4R
55
55
  @reader.close
56
56
  end
57
57
 
58
- # Close the reader and throw a SdlParseError.
58
+ # Raises a SdlParseError.
59
59
  def parse_error(description, line_no = nil, position = nil)
60
- begin
61
- @reader.close()
62
- rescue IOError
63
- # no recourse
64
- end
60
+ line_no = @reader.line_no unless line_no
61
+ position = @reader.pos - 1 unless position # @reader.pos points to the *next* position
65
62
 
66
- line_no = @reader.line_no if line_no.nil?
67
- position = @reader.pos if position.nil?
68
-
69
- # We add one because editors typically start with line 1 and position 1
70
- # rather than 0...
63
+ # We add one because editors typically start with line 1 rather than 0...
71
64
  raise SdlParseError.new(description, line_no + 1, position + 1, @reader.line)
72
65
  end
73
66
 
@@ -111,26 +104,31 @@ module SDL4R
111
104
  #
112
105
  # Returns a logical line as a list of Tokens.
113
106
  # Returns an empty array if the line was empty.
107
+ # Returns +nil+ if the end of the stream has been reached.
114
108
  #
115
109
  def read_line_tokens_even_if_empty
110
+ # Reset of the token-related fields
116
111
  @tokens = nil
117
- @tokenText = nil
112
+ @token_text = nil
118
113
  @token_start = nil
119
114
 
120
- @reader.read_line() if @reader.end_of_line?
121
- return @tokens unless @reader.line
115
+ if @reader.eol? and not @reader.read_line()
116
+ return nil
117
+ end
122
118
 
123
119
  @tokens = []
124
120
  @token_start = @reader.pos
125
121
 
126
- while not @reader.end_of_line?
127
- if @tokenText
128
- @tokens << Token.new(@tokenText, @reader.line_no, @token_start)
129
- @tokenText = nil
122
+ until @reader.eol?
123
+ if @token_text
124
+ @tokens << Token.new(@token_text, @reader.line_no, @token_start)
125
+ @token_text = nil
126
+ @token_start = @reader.pos
130
127
  end
131
128
 
132
129
  c = @reader.current_char
133
130
  next_c = @reader.get_line_char(@reader.pos + 1)
131
+
134
132
  case c
135
133
  when "\""
136
134
  # handle "" style strings including line continuations
@@ -142,7 +140,7 @@ module SDL4R
142
140
  when "{", "}", "=", ":", ";"
143
141
  # handle punctuation
144
142
  punctuation_token = Token.new(c, @reader.line_no, @reader.pos)
145
- @tokenText = nil
143
+ @token_text = nil
146
144
 
147
145
  if punctuation_token.type == :SEMICOLON
148
146
  @reader.skip_char()
@@ -153,13 +151,13 @@ module SDL4R
153
151
 
154
152
  when "#"
155
153
  # skip : hash comment at end of line
156
- @reader.skip_line()
154
+ @reader.skip_to_eol()
157
155
 
158
156
  when "/"
159
157
  # handle // and /**/ style comments
160
158
  if next_c == "/"
161
159
  # skip : // comment
162
- @reader.skip_line()
160
+ @reader.skip_to_eol()
163
161
  else
164
162
  handle_slash_comment()
165
163
  end
@@ -177,12 +175,13 @@ module SDL4R
177
175
 
178
176
  when "\\"
179
177
  # line continuations (outside a string literal)
180
- handle_line_continuation();
178
+ handle_line_continuation()
179
+ next # otherwise 1st char of the continuation line is skipped by skip_char()
181
180
 
182
181
  when /^[0-9\-\.]$/
183
182
  if c == "-" and next_c == "-"
184
183
  # -- comments : ignore
185
- @reader.skip_line()
184
+ @reader.skip_to_eol()
186
185
  else
187
186
  # handle numbers, dates, and time spans
188
187
  handle_number_date_or_time_span()
@@ -194,9 +193,8 @@ module SDL4R
194
193
  # So, we implement a subset of these characters.
195
194
  handle_identifier()
196
195
 
197
- when "\n", "\r"
198
- # end of line
199
- @reader.skip_line()
196
+ when "\n", "\r" # end of line
197
+ @reader.skip_to_eol()
200
198
 
201
199
  else
202
200
  parse_error("Unexpected character '#{c}'")
@@ -205,45 +203,44 @@ module SDL4R
205
203
  @reader.skip_char()
206
204
  end
207
205
 
208
- if @tokenText
209
- @tokens << Token.new(@tokenText, @reader.line_no, @token_start)
206
+ if @token_text
207
+ @tokens << Token.new(@token_text, @reader.line_no, @token_start)
210
208
  end
211
209
 
212
210
  return @tokens
213
211
  end
214
212
 
215
- # Adds the current escaped character (represented by ((|c|))) to @tokenText.
213
+ # Adds the current escaped character (represented by ((|c|))) to @token_text.
216
214
  # This method assumes the previous char was a backslash.
217
215
  #
218
216
  def add_escaped_char_in_string(c)
219
217
  case c
220
218
  when "\\", "\""
221
- @tokenText << c
219
+ @token_text << c
222
220
  when "n"
223
- @tokenText << ?\n
221
+ @token_text << ?\n
224
222
  when "r"
225
- @tokenText << ?\r
223
+ @token_text << ?\r
226
224
  when "t"
227
- @tokenText << ?\t
225
+ @token_text << ?\t
228
226
  else
229
- parse_error("Illegal escape character in string literal: '#{c.chr}'.")
227
+ parse_error("Illegal escape character in string literal: '#{c}'.")
230
228
  end
231
229
  end
232
230
 
233
231
  def handle_double_quote_string
234
232
  escaped = false
235
- @startEscapedQuoteLine = false
233
+ @starting_escaped_quote_line = false
236
234
 
237
- @tokenText = "\""
238
- @reader.skip_char()
235
+ @token_text = @reader.read_char()
239
236
 
240
- while not @reader.end_of_line?
237
+ until @reader.eol?
241
238
  c = @reader.current_char
242
239
 
243
- if "\s\t".include?(c) and @startEscapedQuoteLine
244
- # we continue
240
+ if "\s\t".include?(c) and @starting_escaped_quote_line
241
+ # skip the heading spaces (indentation) of a continued line
245
242
  else
246
- @startEscapedQuoteLine = false;
243
+ @starting_escaped_quote_line = false
247
244
 
248
245
  if escaped
249
246
  add_escaped_char_in_string(c)
@@ -255,15 +252,15 @@ module SDL4R
255
252
  handle_escaped_double_quoted_string()
256
253
  next # as we are at the beginning of a new line
257
254
  else
258
- escaped = true;
255
+ escaped = true
259
256
  end
260
257
 
261
258
  else
262
- @tokenText << c
263
- if c == "\""
259
+ @token_text << c
260
+ if c == '"'
264
261
  # end of double-quoted string detected
265
- @tokens << Token.new(@tokenText, @reader.line_no, @token_start)
266
- @tokenText = nil
262
+ @tokens << Token.new(@token_text, @reader.line_no, @token_start)
263
+ @token_text = nil
267
264
  return
268
265
  end
269
266
  end
@@ -273,21 +270,24 @@ module SDL4R
273
270
  end
274
271
 
275
272
  # detection of ill-terminated literals
276
- if @tokenText =~ /^".*[^"]$/
273
+ if @token_text =~ /^".*[^"]$/
277
274
  parse_error(
278
- "String literal \"#{@tokenText}\" not terminated by end quote.", @reader.line_no, @reader.line_length);
279
- elsif @tokenText == "\""
280
- parse_error("Orphan quote (unterminated string)", @reader.line_no, @reader.line_length);
275
+ "String literal \"#{@token_text}\" not terminated by end quote.",
276
+ @reader.line_no,
277
+ @reader.line_length)
278
+ else#if @token_text == '"'
279
+ parse_error("Orphan quote (unterminated string)", @reader.line_no, @reader.line_length)
281
280
  end
281
+ puts "end of chars"
282
282
  end
283
283
 
284
284
  def handle_escaped_double_quoted_string
285
285
  # '\' can be followed by whitespaces
286
286
  if @reader.rest_of_line =~ /^\\\s*$/
287
287
  @reader.read_line()
288
- parse_error("Escape at end of file.") if @reader.end_of_file?
288
+ parse_error("Escape at end of file.") if @reader.eof?
289
289
 
290
- @startEscapedQuoteLine = true
290
+ @starting_escaped_quote_line = true
291
291
 
292
292
  else
293
293
  parse_error(
@@ -297,22 +297,18 @@ module SDL4R
297
297
  end
298
298
 
299
299
  def handle_character_literal
300
- if not @reader.more_chars_in_line?
301
- parse_error("Got ' at end of line")
302
- end
300
+ @reader.skip_char # skip the starting quote
301
+
302
+ parse_error("Got ' at end of line") if @reader.eol?
303
303
 
304
304
  c2 = @reader.read_char()
305
305
 
306
306
  if c2 == "\\"
307
- if @reader.end_of_line?
308
- parse_error("Got '\\ at end of line")
309
- end
307
+ parse_error("Got '\\ at end of line") if @reader.eol?
310
308
 
311
309
  c3 = @reader.read_char()
312
310
 
313
- if not @reader.more_chars_in_line?
314
- parse_error("Got '\\#{c3} at end of line")
315
- end
311
+ parse_error("Got '\\#{c3} at end of line") if @reader.eol?
316
312
 
317
313
  case c3
318
314
  when "\\"
@@ -329,17 +325,16 @@ module SDL4R
329
325
  parse_error("Illegal escape character #{@reader.current_char}")
330
326
  end
331
327
 
332
- @reader.skip_char()
333
- if @reader.current_char != "'"
328
+ if @reader.read_char != "'"
334
329
  expecting_but_got("single quote (')", "\"#{@reader.current_char}\"")
335
330
  end
331
+
336
332
  else
337
333
  @tokens << Token.new("'#{c2}'", @reader.line_no, @reader.pos)
338
- if not @reader.more_chars_in_line?
339
- parse_error("Got '#{c2} at end of line")
340
- end
341
- @reader.skip_char()
342
- if @reader.current_char != "'"
334
+
335
+ parse_error("Got '#{c2} at end of line") if @reader.eol?
336
+
337
+ if @reader.read_char != "'"
343
338
  expecting_but_got(
344
339
  "quote (')", "\"#{@reader.current_char}\"", @reader.line_no, @reader.pos)
345
340
  end
@@ -360,7 +355,7 @@ module SDL4R
360
355
  # handle multiline comments
361
356
  loop do
362
357
  @reader.read_raw_line()
363
- if @reader.end_of_file?
358
+ if @reader.eof?
364
359
  parse_error("/* comment not terminated.", @reader.line_no, -2)
365
360
  end
366
361
 
@@ -383,31 +378,31 @@ module SDL4R
383
378
  if end_index
384
379
  # handle end quote on same line
385
380
  @tokens << Token.new(@reader.substring(@reader.pos, end_index), @reader.line_no, @reader.pos)
386
- @tokenText = nil
381
+ @token_text = nil
387
382
  @reader.skip_to(end_index)
388
383
 
389
384
  else
390
- @tokenText = @reader.rest_of_line
385
+ @token_text = @reader.rest_of_line
391
386
  @token_start = @reader.pos
392
387
  # handle multiline quotes
393
388
  loop do
394
389
  @reader.read_raw_line()
395
- if @reader.end_of_file?
390
+ if @reader.eof?
396
391
  parse_error("` quote not terminated.", @reader.line_no, -2)
397
392
  end
398
393
 
399
394
  end_index = @reader.find_next_in_line("`", 0)
400
395
  if end_index
401
- @tokenText << @reader.substring(0, end_index)
396
+ @token_text << @reader.substring(0, end_index)
402
397
  @reader.skip_to(end_index)
403
398
  break
404
399
  else
405
- @tokenText << @reader.line
400
+ @token_text << @reader.line
406
401
  end
407
402
  end
408
403
 
409
- @tokens << Token.new(@tokenText, @reader.line_no, @token_start)
410
- @tokenText = nil
404
+ @tokens << Token.new(@token_text, @reader.line_no, @token_start)
405
+ @token_text = nil
411
406
  end
412
407
  end
413
408
 
@@ -417,30 +412,30 @@ module SDL4R
417
412
  if end_index
418
413
  # handle end quote on same line
419
414
  @tokens << Token.new(@reader.substring(@reader.pos, end_index), @reader.line_no, @reader.pos)
420
- @tokenText = nil
415
+ @token_text = nil
421
416
  @reader.skip_to(end_index)
422
417
  else
423
- @tokenText = @reader.substring(@reader.pos)
418
+ @token_text = @reader.substring(@reader.pos)
424
419
  @token_start = @reader.pos
425
420
  # handle multiline quotes
426
421
  loop do
427
422
  @reader.read_raw_line()
428
- if @reader.end_of_file?
423
+ if @reader.eof?
429
424
  parse_error("[base64] binary literal not terminated.", @reader.line_no, -2)
430
425
  end
431
426
 
432
427
  end_index = @reader.find_next_in_line("]", 0)
433
428
  if end_index
434
- @tokenText << @reader.substring(0, end_index)
429
+ @token_text << @reader.substring(0, end_index)
435
430
  @reader.skip_to(end_index)
436
431
  break
437
432
  else
438
- @tokenText << @reader.line
433
+ @token_text << @reader.line
439
434
  end
440
435
  end
441
436
 
442
- @tokens << Token.new(@tokenText, @reader.line_no, @token_start)
443
- @tokenText = nil
437
+ @tokens << Token.new(@token_text, @reader.line_no, @token_start)
438
+ @token_text = nil
444
439
  end
445
440
  end
446
441
 
@@ -452,7 +447,7 @@ module SDL4R
452
447
  parse_error("Line continuation (\\) before end of line")
453
448
  else
454
449
  @line = @reader.read_line()
455
- if @line.nil?
450
+ unless @line
456
451
  parse_error("Line continuation at end of file.", @reader.line_no, @reader.pos)
457
452
  end
458
453
  end
@@ -460,15 +455,15 @@ module SDL4R
460
455
 
461
456
  def handle_number_date_or_time_span
462
457
  @token_start = @reader.pos
463
- @tokenText = ""
458
+ @token_text = ""
464
459
 
465
- while not @reader.end_of_line?
460
+ until @reader.eol?
466
461
  c = @reader.current_char
467
462
 
468
463
  if c =~ /[\w\.\-+:]/
469
- @tokenText << c
464
+ @token_text << c
470
465
  elsif c == "/" and not @reader.get_line_char(@reader.pos + 1) == "*"
471
- @tokenText << c
466
+ @token_text << c
472
467
  else
473
468
  @reader.previous_char()
474
469
  break
@@ -477,21 +472,21 @@ module SDL4R
477
472
  @reader.skip_char()
478
473
  end
479
474
 
480
- @tokens << Token.new(@tokenText, @reader.line_no, @token_start)
481
- @tokenText = nil
475
+ @tokens << Token.new(@token_text, @reader.line_no, @token_start)
476
+ @token_text = nil
482
477
  end
483
478
 
484
479
  def handle_identifier
485
- @token_start = @reader.pos;
486
- @tokenText = ""
480
+ @token_start = @reader.pos
481
+ @token_text = ""
487
482
 
488
- while not @reader.end_of_line?
483
+ until @reader.eol?
489
484
  c = @reader.current_char
490
485
 
491
486
  # FIXME here we are stricter than the Java version because there is no
492
487
  # easy way to implement Character.isJavaIdentifierPart() in Ruby :)
493
488
  if c =~ /[\w_$-\.]/
494
- @tokenText << c
489
+ @token_text << c
495
490
  else
496
491
  @reader.previous_char()
497
492
  break
@@ -500,8 +495,8 @@ module SDL4R
500
495
  @reader.skip_char()
501
496
  end
502
497
 
503
- @tokens << Token.new(@tokenText, @reader.line_no, @token_start)
504
- @tokenText = nil
498
+ @tokens << Token.new(@token_text, @reader.line_no, @token_start)
499
+ @token_text = nil
505
500
  end
506
501
 
507
502
  end