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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +24 -29
- data/VERSION +1 -1
- data/ext/fast_method_source/extconf.rb +1 -1
- data/ext/fast_method_source/fast_method_source.c +190 -102
- metadata +2 -3
- data/ext/fast_method_source/fast_method_source.h +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d4abbc77bfa1ddd3f7d8c335e4ed45de99d1d6f
|
4
|
+
data.tar.gz: 412abc3f1f3278f2a25041e3dcfc689e4c00b83d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15c8a178256a9f168e2a2bf49a0f7a2dcba1a968664c1887d642de15685bf446d0b020eceb8fc322a1bb9e3172c158c2b28c3dc294ac8e46cc8c2406e7e479e6
|
7
|
+
data.tar.gz: 2930a5f50f0cf4d7b8745d0b44ca377a312cd06bdde2944ba38686fe782c7ec1fb0d232be6dd535e547aa4214a9f8528734882ed9d9820becf4a255e2c66c20d
|
data/CHANGELOG.md
CHANGED
@@ -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:
|
67
|
-
|
68
|
-
FastMethodSource#comment_and_source_for
|
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:
|
83
|
-
Rehearsal
|
84
|
-
FastMethodSource#
|
85
|
-
MethodSource#
|
86
|
-
|
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
|
-
|
89
|
-
FastMethodSource#
|
90
|
-
MethodSource#
|
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:
|
101
|
-
Rehearsal
|
102
|
-
FastMethodSource#
|
103
|
-
MethodSource#
|
104
|
-
|
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
|
-
|
107
|
-
FastMethodSource#
|
108
|
-
MethodSource#
|
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
|
-
|
137
|
-
|
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
|
146
|
-
use Fast Method Source. One way is
|
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
|
+
0.2.0
|
@@ -1,31 +1,96 @@
|
|
1
|
-
|
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
|
6
|
-
read_lines_after(
|
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
|
-
|
77
|
+
read_lines(order, filebuf);
|
11
78
|
}
|
12
79
|
|
13
|
-
static
|
14
|
-
read_lines_before(
|
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
|
-
|
84
|
+
read_lines(order, filebuf);
|
19
85
|
}
|
20
86
|
|
21
|
-
static
|
22
|
-
read_lines(read_order order,
|
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(¤t_line, ¤t_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 = &(
|
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 =
|
147
|
+
char **temp_lines = REALLOC_N(*lines, char *, new_size);
|
89
148
|
|
90
|
-
|
91
|
-
rb_raise(rb_eNoMemError, "failed to allocate memory");
|
92
|
-
} else {
|
93
|
-
*lines = temp_lines;
|
149
|
+
*lines = temp_lines;
|
94
150
|
|
95
|
-
|
96
|
-
|
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(
|
286
|
+
find_source(struct filebuf *filebuf)
|
225
287
|
{
|
226
288
|
VALUE rb_expr;
|
227
289
|
|
228
|
-
const unsigned expr_size =
|
229
|
-
char *expr =
|
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 =
|
293
|
+
char *parseable_expr = ALLOC_N(char, expr_size);
|
232
294
|
parseable_expr[0] = '\0';
|
233
295
|
|
234
296
|
int l = 0;
|
235
|
-
while (
|
297
|
+
while (filebuf->lines[l][0] == '\n') {
|
236
298
|
l++;
|
237
299
|
continue;
|
238
300
|
}
|
239
|
-
char *first_line = (
|
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 <
|
251
|
-
current_line =
|
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
|
-
|
274
|
-
|
335
|
+
xfree(expr);
|
336
|
+
xfree(parseable_expr);
|
275
337
|
return rb_expr;
|
276
338
|
}
|
277
339
|
}
|
278
340
|
}
|
279
341
|
|
280
|
-
|
281
|
-
|
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(
|
301
|
-
const unsigned relevant_lines_n)
|
361
|
+
find_comment(struct filebuf *filebuf)
|
302
362
|
{
|
303
|
-
|
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 (
|
375
|
+
while (filebuf->lines[i][0] == '\n') {
|
309
376
|
i--;
|
310
377
|
continue;
|
311
378
|
}
|
312
379
|
|
313
|
-
if (!is_comment(
|
380
|
+
if (!is_comment(filebuf->lines[i], strlen(filebuf->lines[i]))) {
|
314
381
|
return rb_str_new("", 0);
|
315
382
|
} else {
|
316
|
-
while (
|
317
|
-
|
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
|
-
|
396
|
+
rb_comment = rb_str_new2(comment);
|
397
|
+
xfree(comment);
|
398
|
+
return rb_comment;
|
322
399
|
}
|
323
400
|
|
324
|
-
|
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
|
-
|
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
|
-
|
424
|
+
xfree((*file)[i]);
|
353
425
|
}
|
354
426
|
|
355
|
-
|
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
|
-
|
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(
|
444
|
+
RSTRING_PTR(rb_sym2str(method_name)));
|
364
445
|
}
|
365
446
|
}
|
366
447
|
|
367
|
-
static
|
368
|
-
|
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
|
-
|
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
|
-
|
379
|
-
|
459
|
+
raise_if_nil(rb_filename, name);
|
460
|
+
raise_if_nil(rb_method_location, name);
|
380
461
|
|
381
|
-
|
382
|
-
|
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
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
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
|
-
|
390
|
-
free_memory_for_file(&filebuf,
|
474
|
+
rb_protect(raise_if_nil_safe, (VALUE) &retval, &failed);
|
475
|
+
free_memory_for_file(&filebuf->lines, filebuf->relevant_lines);
|
391
476
|
|
392
|
-
|
477
|
+
if (failed) {
|
478
|
+
rb_jump_tag(failed);
|
479
|
+
}
|
393
480
|
}
|
394
481
|
|
395
482
|
static VALUE
|
396
|
-
|
483
|
+
mMethodExtensions_source(VALUE self)
|
397
484
|
{
|
398
|
-
|
399
|
-
VALUE name = rb_funcall(self, rb_intern("name"), 0);
|
485
|
+
struct filebuf filebuf;
|
400
486
|
|
401
|
-
|
487
|
+
filebuf_init(self, &filebuf);
|
488
|
+
read_lines_after(&filebuf);
|
402
489
|
|
403
|
-
VALUE
|
404
|
-
|
490
|
+
VALUE source = find_source(&filebuf);
|
491
|
+
|
492
|
+
free_filebuf(source, &filebuf);
|
493
|
+
|
494
|
+
return source;
|
495
|
+
}
|
405
496
|
|
406
|
-
|
407
|
-
|
497
|
+
static VALUE
|
498
|
+
mMethodExtensions_comment(VALUE self)
|
499
|
+
{
|
500
|
+
struct filebuf filebuf;
|
408
501
|
|
409
|
-
|
410
|
-
|
502
|
+
filebuf_init(self, &filebuf);
|
503
|
+
read_lines_before(&filebuf);
|
411
504
|
|
412
|
-
|
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
|
-
|
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.
|
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-
|
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'
|