fast_method_source 0.1.1 → 0.2.0
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.
- 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'
|