Initial Revision
[ohcount] / ext / ohcount_native / ruby_binding.c
1 #include "ruby.h"
2 #include "common.h"
3
4 static VALUE rb_module_ohcount;
5 static VALUE rb_class_language_breakdown;
6
7
8 /*****************************************************************************
9                                LanguageBreakdown
10 *****************************************************************************/
11
12 static void _language_breakdown_free(LanguageBreakdown *language_breakdown) {
13         language_breakdown_free(language_breakdown);
14         free(language_breakdown);
15 }
16
17 static VALUE _language_breakdown_allocate(VALUE klass) {
18         int _my_language_id;
19         int _my_buffer_size;
20         _my_language_id = 0;
21         _my_buffer_size = 100;
22         LanguageBreakdown *language_breakdown = (LanguageBreakdown *) malloc(sizeof(LanguageBreakdown));
23         language_breakdown_initialize(language_breakdown, "", _my_buffer_size);
24
25         /* bs initializers */
26         strcpy(language_breakdown->name, "");
27         strcpy(language_breakdown->code, "");
28         strcpy(language_breakdown->comment, "");
29         return Data_Wrap_Struct(klass, 0, _language_breakdown_free, language_breakdown);
30 }
31
32 static VALUE _language_breakdown_initialize(VALUE self, VALUE name, VALUE code, VALUE comment, VALUE blanks) {
33         /* validation */
34         Check_Type(name, T_STRING);
35         Check_Type(code, T_STRING);
36         Check_Type(comment, T_STRING);
37         Check_Type(blanks, T_FIXNUM);
38
39         LanguageBreakdown *lb;
40         Data_Get_Struct (self, LanguageBreakdown, lb);
41
42         /* name */
43         strncpy(lb->name, rb_string_value_ptr(&name), MAX_LANGUAGE_NAME);
44
45         /* code */
46         if (lb->code != NULL) {
47                 free(lb->code);
48         }
49         lb->code = (char*)malloc(RSTRING(code)->len);
50         strcpy(lb->code, rb_string_value_ptr(&code));
51
52         /* comment */
53         if (lb->comment != NULL) {
54                 free(lb->comment);
55         }
56         lb->comment = (char*)malloc(RSTRING(comment)->len);
57         strcpy(lb->comment, rb_string_value_ptr(&comment));
58
59         /* blanks */
60         lb->blank_count = NUM2INT(blanks);
61
62         return self;
63 }
64
65 static VALUE _language_breakdown_name(VALUE self) {
66         LanguageBreakdown *lb;
67         Data_Get_Struct (self, LanguageBreakdown, lb);
68         return rb_str_new2(lb->name);
69 }
70
71 static VALUE _language_breakdown_code(VALUE self) {
72         LanguageBreakdown *lb;
73         Data_Get_Struct (self, LanguageBreakdown, lb);
74         return rb_str_new2(lb->code);
75 }
76
77 static VALUE _language_breakdown_comment(VALUE self) {
78         LanguageBreakdown *lb;
79         Data_Get_Struct (self, LanguageBreakdown, lb);
80         return rb_str_new2(lb->comment);
81 }
82
83 static VALUE _language_breakdown_blanks(VALUE self) {
84         LanguageBreakdown *lb;
85         Data_Get_Struct (self, LanguageBreakdown, lb);
86         return INT2NUM(lb->blank_count);
87 }
88
89
90 /*****************************************************************************
91                                 Ohcount (Module)
92 *****************************************************************************/
93 static VALUE _ohcount_parse(VALUE self, VALUE buffer, VALUE polyglot_name_value) {
94
95         // find the polyglot to parse with
96         char *polyglot_name = RSTRING(polyglot_name_value)->ptr;
97         int i_polyglot;
98         for (i_polyglot = 0; POLYGLOTS[i_polyglot] != NULL; i_polyglot++) {
99                 if (strcmp(POLYGLOTS[i_polyglot]->name, polyglot_name) == 0) {
100                         Polyglot *polyglot = POLYGLOTS[i_polyglot];
101
102                         ParseResult pr;
103                         parser_parse(&pr, RSTRING(buffer)->ptr, RSTRING(buffer)->len, polyglot);
104
105                         // create array we'll return all the language_breakdowns in
106                         VALUE ary = rb_ary_new2(pr.language_breakdown_count);
107
108                         int i_pr;
109                         for(i_pr = 0; i_pr < pr.language_breakdown_count; i_pr++) {
110                                 LanguageBreakdown *lb = (LanguageBreakdown *) malloc(sizeof(LanguageBreakdown));
111                                 LanguageBreakdown *src_lb = &(pr.language_breakdowns[i_pr]);
112                                 strcpy(lb->name,src_lb->name);
113                                 lb->code = src_lb->code;
114                                 lb->comment = src_lb->comment;
115                                 lb->blank_count = src_lb->blank_count;
116                                 rb_ary_store(ary, i_pr, Data_Wrap_Struct(rb_class_language_breakdown, 0, _language_breakdown_free, lb));
117                         }
118
119                         return ary;
120                 }
121         }
122   rb_raise(rb_eStandardError,"Polyglot name invalid");
123         return Qnil;
124 }
125
126
127 static VALUE _ohcount_polyglots(VALUE self) {
128
129         // how many are they?
130         int poly_count = 0;
131         Polyglot **p = POLYGLOTS;
132         while ((*p++) != NULL) {
133                 poly_count++;
134         }
135
136         // create the array
137         VALUE ary = rb_ary_new2(poly_count);
138
139         // fill it in
140         int i_poly;
141         for (i_poly = 0; POLYGLOTS[i_poly] != NULL; i_poly++) {
142                 VALUE poly_name = rb_str_new2(POLYGLOTS[i_poly]->name);
143                 rb_ary_store(ary, i_poly, poly_name);
144         }
145
146         return ary;
147 }
148
149
150 /*****************************************************************************
151                                 Initialize Ruby
152 *****************************************************************************/
153 void Init_ohcount_native () {
154         rb_module_ohcount = rb_define_module("Ohcount");
155         rb_define_module_function(rb_module_ohcount, "parse", _ohcount_parse, 2);
156         rb_define_module_function(rb_module_ohcount, "polyglots", _ohcount_polyglots, 0);
157
158         // define language_breakdown
159         rb_class_language_breakdown = rb_define_class_under( rb_module_ohcount, "LanguageBreakdown", rb_cObject);
160         rb_define_alloc_func (rb_class_language_breakdown, _language_breakdown_allocate);
161         rb_define_method (rb_class_language_breakdown, "initialize", _language_breakdown_initialize, 4);
162         rb_define_method (rb_class_language_breakdown, "name", _language_breakdown_name, 0);
163         rb_define_method (rb_class_language_breakdown, "code", _language_breakdown_code, 0);
164         rb_define_method (rb_class_language_breakdown, "comment", _language_breakdown_comment, 0);
165         rb_define_method (rb_class_language_breakdown, "blanks", _language_breakdown_blanks, 0);
166 }
167