fast_method_source 0.1.1 → 0.2.0

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: 8a8566fbdf9afc48e1122cd29d4ee799a455fd10
4
- data.tar.gz: 3894ea5f9ab5e1b784b8c64078accf4b309323fb
3
+ metadata.gz: 5d4abbc77bfa1ddd3f7d8c335e4ed45de99d1d6f
4
+ data.tar.gz: 412abc3f1f3278f2a25041e3dcfc689e4c00b83d
5
5
  SHA512:
6
- metadata.gz: 7ebf626281536e5d5ec319bc5bf3eb820cfa2e1191f07c5d7d7b94afcc1de95a0be63acafd01bbc93800e53753c399527243a27cd9e372da28b05a5133dc1557
7
- data.tar.gz: f6a255e157ba75498e4b1005d462c9851da0c762cb9b81b096f754051b5e9ba056687c7ccc590e9229fda724928f37b1ba49ab35e42138e2737ac37b78a165a3
6
+ metadata.gz: 15c8a178256a9f168e2a2bf49a0f7a2dcba1a968664c1887d642de15685bf446d0b020eceb8fc322a1bb9e3172c158c2b28c3dc294ac8e46cc8c2406e7e479e6
7
+ data.tar.gz: 2930a5f50f0cf4d7b8745d0b44ca377a312cd06bdde2944ba38686fe782c7ec1fb0d232be6dd535e547aa4214a9f8528734882ed9d9820becf4a255e2c66c20d
@@ -1,6 +1,13 @@
1
1
  Fast Method Source changelog
2
2
  ============================
3
3
 
4
+ ### v0.2.0 (June 11, 2015)
5
+
6
+ * Significantly reduced memory consumption
7
+ * The time of calculations has increased by 6%
8
+ * Fixed memory not being freed on exceptions
9
+ * Fixed exit code value for shells [→](https://github.com/kyrylo/fast_method_source/pull/2)
10
+
4
11
  ### v0.1.1 (June 9, 2015)
5
12
 
6
13
  * Fixed segfault on any C method query
data/README.md CHANGED
@@ -63,13 +63,9 @@ This is a utility method and method_source doesn't feature it.
63
63
  Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
64
64
  Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
65
65
  Counting the number of sample methods...
66
- Sample methods: 19439
67
- Rehearsal ---------------------------------------------------------------------------
68
- FastMethodSource#comment_and_source_for 24.080000 1.900000 25.980000 ( 28.425889)
69
- ----------------------------------------------------------------- total: 25.980000sec
70
-
71
- user system total real
72
- FastMethodSource#comment_and_source_for 23.130000 1.710000 24.840000 ( 27.097578)
66
+ Sample methods: 19438
67
+ user system total real
68
+ FastMethodSource#comment_and_source_for 26.050000 1.420000 27.470000 ( 30.528066)
73
69
  ```
74
70
 
75
71
  #### #source
@@ -79,15 +75,15 @@ FastMethodSource#comment_and_source_for 23.130000 1.710000 24.840000 ( 27.09
79
75
  Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
80
76
  Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
81
77
  Counting the number of sample methods...
82
- Sample methods: 19438
83
- Rehearsal -----------------------------------------------------------
84
- FastMethodSource#source 18.760000 1.290000 20.050000 ( 21.802014)
85
- MethodSource#source 100.100000 0.440000 100.540000 (122.748676)
86
- ------------------------------------------------ total: 120.590000sec
78
+ Sample methods: 19596
79
+ Rehearsal ------------------------------------------------------------
80
+ FastMethodSource#comment 4.730000 0.300000 5.030000 ( 5.590186)
81
+ MethodSource#comment 73.660000 0.340000 74.000000 ( 89.475399)
82
+ -------------------------------------------------- total: 79.030000sec
87
83
 
88
- user system total real
89
- FastMethodSource#source 19.040000 1.170000 20.210000 ( 22.079805)
90
- MethodSource#source 92.740000 0.300000 93.040000 (103.833941)
84
+ user system total real
85
+ FastMethodSource#comment 4.450000 0.300000 4.750000 ( 5.278761)
86
+ MethodSource#comment 69.880000 0.110000 69.990000 ( 77.663383)
91
87
  ```
92
88
 
93
89
  #### #comment
@@ -97,15 +93,15 @@ MethodSource#source 92.740000 0.300000 93.040000 (103.833941)
97
93
  Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
98
94
  Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
99
95
  Counting the number of sample methods...
100
- Sample methods: 19595
101
- Rehearsal ------------------------------------------------------------
102
- FastMethodSource#comment 4.120000 0.520000 4.640000 ( 5.188443)
103
- MethodSource#comment 82.480000 0.330000 82.810000 (103.135012)
104
- -------------------------------------------------- total: 87.450000sec
96
+ Sample methods: 19438
97
+ Rehearsal -----------------------------------------------------------
98
+ FastMethodSource#source 20.610000 1.290000 21.900000 ( 24.341358)
99
+ MethodSource#source 92.730000 0.470000 93.200000 (111.384362)
100
+ ------------------------------------------------ total: 115.100000sec
105
101
 
106
- user system total real
107
- FastMethodSource#comment 3.580000 0.370000 3.950000 ( 4.398557)
108
- MethodSource#comment 73.390000 0.150000 73.540000 ( 81.880220)
102
+ user system total real
103
+ FastMethodSource#source 20.990000 1.150000 22.140000 ( 24.612721)
104
+ MethodSource#source 86.390000 0.290000 86.680000 ( 96.241494)
109
105
  ```
110
106
 
111
107
  ### Correctness of output
@@ -133,18 +129,17 @@ Output.
133
129
 
134
130
  ### RAM consumption
135
131
 
136
- Memory consumption is considerably higher for Fast Method Source (for the
137
- benchmarks it used about 800-1500 MB of RES RAM). In fact, since the library is
138
- very young, it *may* have memory leaks.
132
+ The [`comment_and_source`](/benchmarks/comment_and_source_for.rb) benchmark
133
+ shows that at this moment the library uses about 450 MB of RAM.
139
134
 
140
135
  API
141
136
  ---
142
137
 
143
138
  ### General description
144
139
 
145
- The library provides two methods `#source` and `#comment`. There are two ways to
146
- use Fast Method Source. One way is to monkey-patch relevant core Ruby classes
147
- and use the methods directly.
140
+ The library provides the following methods: `#comment`, `#source` and
141
+ `#comment_and_source`. There are two ways to use Fast Method Source. One way is
142
+ to monkey-patch relevant core Ruby classes and use the methods directly.
148
143
 
149
144
  ```ruby
150
145
  require 'fast_method_source'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
@@ -1,5 +1,5 @@
1
1
  require 'mkmf'
2
2
 
3
- $CFLAGS << ' -std=c99 -Wno-declaration-after-statement'
3
+ $CFLAGS << ' -std=c99 -Wno-declaration-after-statement -O3'
4
4
 
5
5
  create_makefile('fast_method_source/fast_method_source')
@@ -1,31 +1,96 @@
1
- #include "fast_method_source.h"
1
+ // For getline(), fileno() and friends
2
+ #define _XOPEN_SOURCE 700
3
+
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <ruby.h>
7
+
8
+ #include "node.h"
9
+
10
+ #ifdef _WIN32
11
+ #include <io.h>
12
+ static const char *null_filename = "NUL";
13
+ #define DUP(fd) _dup(fd)
14
+ #define DUP2(fd, newfd) _dup2(fd, newfd)
15
+ #else
16
+ #include <unistd.h>
17
+ static const char *null_filename = "/dev/null";
18
+ #define DUP(fd) dup(fd)
19
+ #define DUP2(fd, newfd) dup2(fd, newfd)
20
+ #endif
21
+
22
+ #define MAXLINES 600
23
+ #define MAXLINELEN 90
24
+ #define COMMENT_SIZE 1000
25
+ #define SAFE_CHAR 'z'
26
+
27
+ typedef struct {
28
+ int forward : 1;
29
+ int backward : 1;
30
+ } read_order;
31
+
32
+ struct filebuf {
33
+ unsigned method_location;
34
+ const char *filename;
35
+ VALUE method_name;
36
+ char **lines;
37
+ unsigned relevant_lines;
38
+ };
39
+
40
+ struct retval {
41
+ VALUE val;
42
+ VALUE method_name;
43
+ };
44
+
45
+ static void read_lines(read_order order, struct filebuf *filebuf);
46
+ static void read_lines_before(struct filebuf *filebuf);
47
+ static void read_lines_after(struct filebuf *filebuf);
48
+ static void reallocate_filebuf(char **lines[], unsigned rl_len);
49
+ static void reallocate_linebuf(char **linebuf, const unsigned cl_len);
50
+ static VALUE find_source(struct filebuf *filebuf);
51
+ static VALUE find_comment(struct filebuf *filebuf);
52
+ static VALUE mMethodExtensions_source(VALUE self);
53
+ static NODE *parse_expr(VALUE rb_str);
54
+ static NODE *parse_with_silenced_stderr(VALUE rb_str);
55
+ static void filter_interp(char *line);
56
+ static char **allocate_memory_for_file(void);
57
+ static void free_memory_for_file(char **file[], const unsigned relevant_lines_n);
58
+ static int contains_end_kw(const char *line);
59
+ static int is_comment(const char *line, const size_t line_len);
60
+ static int is_static_definition(const char *line);
61
+ static int is_accessor(const char *line);
62
+ static int is_dangling_literal_end(const char *line);
63
+ static int is_dangling_literal_begin(const char *line);
64
+ static void strnprep(char *s, const char *t, size_t len);
65
+ static void raise_if_nil(VALUE val, VALUE method_name);
66
+ static VALUE raise_if_nil_safe(VALUE args);
67
+ static void realloc_comment(char **comment, unsigned len);
68
+ static void filebuf_init(VALUE self, struct filebuf *filebuf);
69
+ static void free_filebuf(VALUE retval, struct filebuf *filebuf);
2
70
 
3
71
  static VALUE rb_eSourceNotFoundError;
4
72
 
5
- static unsigned
6
- read_lines_after(const unsigned method_location,
7
- const char *filename, char **filebuf[])
73
+ static void
74
+ read_lines_after(struct filebuf *filebuf)
8
75
  {
9
76
  read_order order = {1, 0};
10
- return read_lines(order, method_location, filename, filebuf);
77
+ read_lines(order, filebuf);
11
78
  }
12
79
 
13
- static unsigned
14
- read_lines_before(const unsigned method_location,
15
- const char *filename, char **filebuf[])
80
+ static void
81
+ read_lines_before(struct filebuf *filebuf)
16
82
  {
17
83
  read_order order = {0, 1};
18
- return read_lines(order, method_location, filename, filebuf);
84
+ read_lines(order, filebuf);
19
85
  }
20
86
 
21
- static unsigned
22
- read_lines(read_order order, const unsigned method_location,
23
- const char *filename, char **filebuf[])
87
+ static void
88
+ read_lines(read_order order, struct filebuf *filebuf)
24
89
  {
25
90
  FILE *fp;
26
91
 
27
- if ((fp = fopen(filename, "r")) == NULL) {
28
- rb_raise(rb_eIOError, "No such file or directory - %s", filename);
92
+ if ((fp = fopen(filebuf->filename, "r")) == NULL) {
93
+ rb_raise(rb_eIOError, "No such file or directory - %s", filebuf->filename);
29
94
  }
30
95
 
31
96
  ssize_t cl_len;
@@ -39,20 +104,20 @@ read_lines(read_order order, const unsigned method_location,
39
104
  while ((cl_len = getline(&current_line, &current_linebuf_size, fp)) != -1) {
40
105
  line_count++;
41
106
  if (order.forward) {
42
- if (line_count < method_location) {
107
+ if (line_count < filebuf->method_location) {
43
108
  continue;
44
109
  }
45
110
  } else if (order.backward) {
46
- if (line_count > method_location) {
111
+ if (line_count > filebuf->method_location) {
47
112
  break;
48
113
  }
49
114
  }
50
115
 
51
116
  if ((rl_n != 0) && (rl_n % (MAXLINES-1) == 0)) {
52
- reallocate_filebuf(filebuf, rl_n);
117
+ reallocate_filebuf(&filebuf->lines, rl_n);
53
118
  }
54
119
 
55
- current_linebuf = &(*filebuf)[rl_n];
120
+ current_linebuf = &(filebuf->lines)[rl_n];
56
121
 
57
122
  if (cl_len >= MAXLINELEN) {
58
123
  reallocate_linebuf(current_linebuf, cl_len);
@@ -65,19 +130,13 @@ read_lines(read_order order, const unsigned method_location,
65
130
 
66
131
  free(current_line);
67
132
  fclose(fp);
68
-
69
- return rl_n;
133
+ filebuf->relevant_lines = rl_n;
70
134
  }
71
135
 
72
136
  static void
73
137
  reallocate_linebuf(char **linebuf, const unsigned cl_len)
74
138
  {
75
- char *tmp_line;
76
-
77
- if ((tmp_line = realloc(*linebuf, cl_len + 1)) == NULL) {
78
- rb_raise(rb_eNoMemError, "failed to allocate memory");
79
- }
80
-
139
+ char *tmp_line = REALLOC_N(*linebuf, char, cl_len + 1);
81
140
  *linebuf = tmp_line;
82
141
  }
83
142
 
@@ -85,26 +144,28 @@ static void
85
144
  reallocate_filebuf(char **lines[], unsigned rl_len)
86
145
  {
87
146
  unsigned new_size = rl_len + MAXLINES + 1;
88
- char **temp_lines = realloc(*lines, sizeof(*temp_lines) * new_size);
147
+ char **temp_lines = REALLOC_N(*lines, char *, new_size);
89
148
 
90
- if (temp_lines == NULL) {
91
- rb_raise(rb_eNoMemError, "failed to allocate memory");
92
- } else {
93
- *lines = temp_lines;
149
+ *lines = temp_lines;
94
150
 
95
- for (int i = 0; i < MAXLINES; i++) {
96
- if (((*lines)[rl_len + i] = malloc(sizeof(char) * MAXLINELEN)) == NULL) {
97
- rb_raise(rb_eNoMemError, "failed to allocate memory");
98
- }
99
- }
151
+ for (int i = 0; i < MAXLINES; i++) {
152
+ (*lines)[rl_len + i] = ALLOC_N(char, MAXLINELEN);
100
153
  }
101
154
  }
102
155
 
156
+ static void
157
+ realloc_comment(char **comment, unsigned len)
158
+ {
159
+ char *tmp_comment = REALLOC_N(*comment, char, len);
160
+ *comment = tmp_comment;
161
+ }
162
+
103
163
  static NODE *
104
164
  parse_with_silenced_stderr(VALUE rb_str)
105
165
  {
106
166
  int old_stderr;
107
167
  FILE *null_fd;
168
+ VALUE last_exception = rb_errinfo();
108
169
 
109
170
  old_stderr = DUP(STDERR_FILENO);
110
171
  fflush(stderr);
@@ -114,6 +175,7 @@ parse_with_silenced_stderr(VALUE rb_str)
114
175
  volatile VALUE vparser = rb_parser_new();
115
176
  NODE *node = rb_parser_compile_string(vparser, "-", rb_str, 1);
116
177
  rb_str_free(rb_str);
178
+ rb_set_errinfo(last_exception);
117
179
 
118
180
  fflush(stderr);
119
181
  fclose(null_fd);
@@ -221,22 +283,22 @@ is_dangling_literal_begin(const char *line)
221
283
  }
222
284
 
223
285
  static VALUE
224
- find_source(char **filebuf[], const unsigned relevant_lines_n)
286
+ find_source(struct filebuf *filebuf)
225
287
  {
226
288
  VALUE rb_expr;
227
289
 
228
- const unsigned expr_size = relevant_lines_n * MAXLINELEN;
229
- char *expr = malloc(expr_size);
290
+ const unsigned expr_size = filebuf->relevant_lines * MAXLINELEN;
291
+ char *expr = ALLOC_N(char, expr_size);
230
292
  expr[0] = '\0';
231
- char *parseable_expr = malloc(expr_size);
293
+ char *parseable_expr = ALLOC_N(char, expr_size);
232
294
  parseable_expr[0] = '\0';
233
295
 
234
296
  int l = 0;
235
- while ((*filebuf)[l][0] == '\n') {
297
+ while (filebuf->lines[l][0] == '\n') {
236
298
  l++;
237
299
  continue;
238
300
  }
239
- char *first_line = (*filebuf)[l];
301
+ char *first_line = (filebuf->lines)[l];
240
302
 
241
303
  char *current_line = NULL;
242
304
  int should_parse = 0;
@@ -247,8 +309,8 @@ find_source(char **filebuf[], const unsigned relevant_lines_n)
247
309
  should_parse = 1;
248
310
  }
249
311
 
250
- for (unsigned i = l; i < relevant_lines_n; i++) {
251
- current_line = (*filebuf)[i];
312
+ for (unsigned i = l; i < filebuf->relevant_lines; i++) {
313
+ current_line = filebuf->lines[i];
252
314
  current_line_len = strlen(current_line);
253
315
 
254
316
  strncat(expr, current_line, current_line_len);
@@ -270,16 +332,15 @@ find_source(char **filebuf[], const unsigned relevant_lines_n)
270
332
  if (should_parse || contains_end_kw(current_line)) {
271
333
  if (parse_expr(rb_str_new2(parseable_expr)) != NULL) {
272
334
  rb_expr = rb_str_new2(expr);
273
- free(expr);
274
- free(parseable_expr);
335
+ xfree(expr);
336
+ xfree(parseable_expr);
275
337
  return rb_expr;
276
338
  }
277
339
  }
278
340
  }
279
341
 
280
- free(expr);
281
- free(parseable_expr);
282
- free_memory_for_file(filebuf, relevant_lines_n);
342
+ xfree(expr);
343
+ xfree(parseable_expr);
283
344
 
284
345
  return Qnil;
285
346
  }
@@ -297,47 +358,58 @@ strnprep(char *s, const char *t, size_t len)
297
358
  }
298
359
 
299
360
  static VALUE
300
- find_comment(char **filebuf[], const unsigned method_location,
301
- const unsigned relevant_lines_n)
361
+ find_comment(struct filebuf *filebuf)
302
362
  {
303
- char comment[COMMENT_SIZE];
363
+ size_t comment_len;
364
+ size_t current_line_len;
365
+ size_t future_bufsize;
366
+ char *current_line = NULL;
367
+ VALUE rb_comment;
368
+
369
+ unsigned long bufsize = COMMENT_SIZE;
370
+ char *comment = ALLOC_N(char, COMMENT_SIZE);
304
371
  comment[0] = '\0';
305
372
 
306
- int i = method_location - 2;
373
+ int i = filebuf->method_location - 2;
307
374
 
308
- while ((*filebuf)[i][0] == '\n') {
375
+ while (filebuf->lines[i][0] == '\n') {
309
376
  i--;
310
377
  continue;
311
378
  }
312
379
 
313
- if (!is_comment((*filebuf)[i], strlen((*filebuf)[i]))) {
380
+ if (!is_comment(filebuf->lines[i], strlen(filebuf->lines[i]))) {
314
381
  return rb_str_new("", 0);
315
382
  } else {
316
- while (is_comment((*filebuf)[i], strlen((*filebuf)[i]))) {
317
- strnprep(comment, (*filebuf)[i], strlen((*filebuf)[i]));
383
+ while ((current_line = filebuf->lines[i]) &&
384
+ is_comment(current_line, (current_line_len = strlen(current_line)))) {
385
+ comment_len = strlen(comment);
386
+ future_bufsize = comment_len + current_line_len;
387
+
388
+ if (future_bufsize >= bufsize) {
389
+ bufsize = future_bufsize + COMMENT_SIZE + 1;
390
+ realloc_comment(&comment, bufsize);
391
+ }
392
+ strnprep(comment, current_line, current_line_len);
318
393
  i--;
319
394
  }
320
395
 
321
- return rb_str_new2(comment);
396
+ rb_comment = rb_str_new2(comment);
397
+ xfree(comment);
398
+ return rb_comment;
322
399
  }
323
400
 
324
- free_memory_for_file(filebuf, relevant_lines_n);
401
+ xfree(comment);
402
+ free_memory_for_file(&filebuf->lines, filebuf->relevant_lines);
325
403
  return Qnil;
326
404
  }
327
405
 
328
406
  static char **
329
407
  allocate_memory_for_file(void)
330
408
  {
331
- char **file;
332
-
333
- if ((file = malloc(sizeof(*file) * MAXLINES)) == NULL) {
334
- rb_raise(rb_eNoMemError, "failed to allocate memory");
335
- }
409
+ char **file = ALLOC_N(char *, MAXLINES);
336
410
 
337
411
  for (int i = 0; i < MAXLINES; i++) {
338
- if ((file[i] = malloc(sizeof(char) * MAXLINELEN)) == NULL) {
339
- rb_raise(rb_eNoMemError, "failed to allocate memory");
340
- };
412
+ file[i] = ALLOC_N(char, MAXLINELEN);
341
413
  }
342
414
 
343
415
  return file;
@@ -349,78 +421,94 @@ free_memory_for_file(char **file[], const unsigned relevant_lines_n)
349
421
  int lines_to_free = relevant_lines_n >= MAXLINES ? relevant_lines_n : MAXLINES;
350
422
 
351
423
  for (int i = 0; i < lines_to_free; i++) {
352
- free((*file)[i]);
424
+ xfree((*file)[i]);
353
425
  }
354
426
 
355
- free(*file);
427
+ xfree(*file);
428
+ }
429
+
430
+ static VALUE
431
+ raise_if_nil_safe(VALUE args)
432
+ {
433
+ struct retval *retval = (struct retval *) args;
434
+ raise_if_nil(retval->val, retval->method_name);
435
+
436
+ return Qnil;
356
437
  }
357
438
 
358
439
  static void
359
- check_if_nil(VALUE val, VALUE name)
440
+ raise_if_nil(VALUE val, VALUE method_name)
360
441
  {
361
442
  if (NIL_P(val)) {
362
443
  rb_raise(rb_eSourceNotFoundError, "could not locate source for %s",
363
- RSTRING_PTR(rb_sym2str(name)));
444
+ RSTRING_PTR(rb_sym2str(method_name)));
364
445
  }
365
446
  }
366
447
 
367
- static VALUE
368
- mMethodExtensions_source(VALUE self)
448
+ static void
449
+ filebuf_init(VALUE self, struct filebuf *filebuf)
369
450
  {
370
451
  VALUE source_location = rb_funcall(self, rb_intern("source_location"), 0);
371
452
  VALUE name = rb_funcall(self, rb_intern("name"), 0);
372
453
 
373
- check_if_nil(source_location, name);
454
+ raise_if_nil(source_location, name);
374
455
 
375
456
  VALUE rb_filename = RARRAY_AREF(source_location, 0);
376
457
  VALUE rb_method_location = RARRAY_AREF(source_location, 1);
377
458
 
378
- check_if_nil(rb_filename, name);
379
- check_if_nil(rb_method_location, name);
459
+ raise_if_nil(rb_filename, name);
460
+ raise_if_nil(rb_method_location, name);
380
461
 
381
- const char *filename = RSTRING_PTR(rb_filename);
382
- const unsigned method_location = FIX2INT(rb_method_location);
462
+ filebuf->filename = RSTRING_PTR(rb_filename);
463
+ filebuf->method_location = FIX2INT(rb_method_location);
464
+ filebuf->method_name = name;
465
+ filebuf->lines = allocate_memory_for_file();
466
+ }
383
467
 
384
- char **filebuf = allocate_memory_for_file();
385
- const unsigned relevant_lines_n = read_lines_after(method_location,
386
- filename, &filebuf);
387
- VALUE source = find_source(&filebuf, relevant_lines_n);
468
+ static void
469
+ free_filebuf(VALUE val, struct filebuf *filebuf)
470
+ {
471
+ int failed;
472
+ struct retval retval = {val, filebuf->method_name};
388
473
 
389
- check_if_nil(source, name);
390
- free_memory_for_file(&filebuf, relevant_lines_n);
474
+ rb_protect(raise_if_nil_safe, (VALUE) &retval, &failed);
475
+ free_memory_for_file(&filebuf->lines, filebuf->relevant_lines);
391
476
 
392
- return source;
477
+ if (failed) {
478
+ rb_jump_tag(failed);
479
+ }
393
480
  }
394
481
 
395
482
  static VALUE
396
- mMethodExtensions_comment(VALUE self)
483
+ mMethodExtensions_source(VALUE self)
397
484
  {
398
- VALUE source_location = rb_funcall(self, rb_intern("source_location"), 0);
399
- VALUE name = rb_funcall(self, rb_intern("name"), 0);
485
+ struct filebuf filebuf;
400
486
 
401
- check_if_nil(source_location, name);
487
+ filebuf_init(self, &filebuf);
488
+ read_lines_after(&filebuf);
402
489
 
403
- VALUE rb_filename = RARRAY_AREF(source_location, 0);
404
- VALUE rb_method_location = RARRAY_AREF(source_location, 1);
490
+ VALUE source = find_source(&filebuf);
491
+
492
+ free_filebuf(source, &filebuf);
493
+
494
+ return source;
495
+ }
405
496
 
406
- check_if_nil(rb_filename, name);
407
- check_if_nil(rb_method_location, name);
497
+ static VALUE
498
+ mMethodExtensions_comment(VALUE self)
499
+ {
500
+ struct filebuf filebuf;
408
501
 
409
- const char *filename = RSTRING_PTR(rb_filename);
410
- const unsigned method_location = FIX2INT(rb_method_location);
502
+ filebuf_init(self, &filebuf);
503
+ read_lines_before(&filebuf);
411
504
 
412
- char **filebuf = allocate_memory_for_file();
413
- const unsigned relevant_lines_n = read_lines_before(method_location,
414
- filename, &filebuf);
415
- VALUE comment = find_comment(&filebuf, method_location, relevant_lines_n);
505
+ VALUE comment = find_comment(&filebuf);
416
506
 
417
- check_if_nil(comment, name);
418
- free_memory_for_file(&filebuf, relevant_lines_n);
507
+ free_filebuf(comment, &filebuf);
419
508
 
420
509
  return comment;
421
510
  }
422
511
 
423
-
424
512
  void Init_fast_method_source(void)
425
513
  {
426
514
  VALUE rb_mFastMethodSource = rb_define_module_under(rb_cObject, "FastMethodSource");
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast_method_source
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyrylo Silin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-09 00:00:00.000000000 Z
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,7 +80,6 @@ files:
80
80
  - VERSION
81
81
  - ext/fast_method_source/extconf.rb
82
82
  - ext/fast_method_source/fast_method_source.c
83
- - ext/fast_method_source/fast_method_source.h
84
83
  - ext/fast_method_source/node.h
85
84
  - lib/fast_method_source.rb
86
85
  - lib/fast_method_source/core_ext.rb
@@ -1,53 +0,0 @@
1
- #define _XOPEN_SOURCE 700
2
- #include <stdio.h>
3
- #include <stdlib.h>
4
- #include <ruby.h>
5
- #include "node.h"
6
-
7
- #ifdef _WIN32
8
- #include <io.h>
9
- static const char *null_filename = "NUL";
10
- #define DUP(fd) _dup(fd)
11
- #define DUP2(fd, newfd) _dup2(fd, newfd)
12
- #else
13
- #include <unistd.h>
14
- static const char *null_filename = "/dev/null";
15
- #define DUP(fd) dup(fd)
16
- #define DUP2(fd, newfd) dup2(fd, newfd)
17
- #endif
18
-
19
- #define MAXLINES 1000
20
- #define MAXLINELEN 300
21
- #define COMMENT_SIZE 15000
22
-
23
- typedef struct {
24
- int forward : 1;
25
- int backward : 1;
26
- } read_order;
27
-
28
- static unsigned read_lines(read_order order, const unsigned method_location,
29
- const char *filename, char **filebuf[]);
30
- static unsigned read_lines_before(const unsigned method_location,
31
- const char *filename, char **filebuf[]);
32
- static unsigned read_lines_after(const unsigned method_location,
33
- const char *filename, char **filebuf[]);
34
- static void reallocate_filebuf(char **lines[], unsigned rl_len);
35
- static void reallocate_linebuf(char **linebuf, const unsigned cl_len);
36
- static VALUE find_source(char **filebuf[], const unsigned relevant_lines_n);
37
- static VALUE find_comment(char **filebuf[], const unsigned relevant_lines_n,
38
- const unsigned method_location);
39
- static VALUE mMethodExtensions_source(VALUE self);
40
- static NODE *parse_expr(VALUE rb_str);
41
- static NODE *parse_with_silenced_stderr(VALUE rb_str);
42
- static void filter_interp(char *line);
43
- static char **allocate_memory_for_file(void);
44
- static void free_memory_for_file(char **file[], const unsigned relevant_lines_n);
45
- static int contains_end_kw(const char *line);
46
- static int is_comment(const char *line, const size_t line_len);
47
- static int is_static_definition(const char *line);
48
- static int is_accessor(const char *line);
49
- static int is_dangling_literal_end(const char *line);
50
- static int is_dangling_literal_begin(const char *line);
51
- static void strnprep(char *s, const char *t, size_t len);
52
-
53
- #define SAFE_CHAR 'z'