4 static VALUE rb_module_ohcount;
5 static VALUE rb_class_language_breakdown;
8 /*****************************************************************************
10 *****************************************************************************/
12 static void _language_breakdown_free(LanguageBreakdown *language_breakdown) {
13 language_breakdown_free(language_breakdown);
14 free(language_breakdown);
17 static VALUE _language_breakdown_allocate(VALUE klass) {
21 _my_buffer_size = 100;
22 LanguageBreakdown *language_breakdown = (LanguageBreakdown *) malloc(sizeof(LanguageBreakdown));
23 language_breakdown_initialize(language_breakdown, "", _my_buffer_size);
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);
32 static VALUE _language_breakdown_initialize(VALUE self, VALUE name, VALUE code, VALUE comment, VALUE blanks) {
34 Check_Type(name, T_STRING);
35 Check_Type(code, T_STRING);
36 Check_Type(comment, T_STRING);
37 Check_Type(blanks, T_FIXNUM);
39 LanguageBreakdown *lb;
40 Data_Get_Struct (self, LanguageBreakdown, lb);
43 strncpy(lb->name, rb_string_value_ptr(&name), MAX_LANGUAGE_NAME);
46 if (lb->code != NULL) {
49 lb->code = (char*)malloc(RSTRING(code)->len);
50 strcpy(lb->code, rb_string_value_ptr(&code));
53 if (lb->comment != NULL) {
56 lb->comment = (char*)malloc(RSTRING(comment)->len);
57 strcpy(lb->comment, rb_string_value_ptr(&comment));
60 lb->blank_count = NUM2INT(blanks);
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);
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);
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);
83 static VALUE _language_breakdown_blanks(VALUE self) {
84 LanguageBreakdown *lb;
85 Data_Get_Struct (self, LanguageBreakdown, lb);
86 return INT2NUM(lb->blank_count);
91 * Ohcount::parse is the main entry point to Ohcount.
93 * It takes two parameters: a string buffer, and a string Monoglot or Polyglot name.
94 * The buffer will be parsed using the specified glot.
96 * The method returns an array of LanguageBreakdown objects. One
97 * LanguageBreakdown will be returned for each language found in the buffer.
99 * You may optionally pass a block of Ruby code. As each line in the buffer
100 * is parsed, it will be yielded to the block, along with the language name
101 * and code semantic determined for that line.
105 * # Print each line to the console, labeled as code or comments
106 * buffer = File.read("helloworld.c")
107 * results = Ohcount::parse(buffer, 'c') do |language, semantic, line|
108 * puts "#{semantic.to_s} #{line}"
113 * # Print total lines of code
114 * buffer = File.read("helloworld.c")
115 * results = Ohcount::parse(buffer, 'c')
116 * results.each do |result|
117 * puts "Lines of #{result.name} code: #{ result.code.split("\n").size }"
120 * You must pass the name of a glot appropriate to the buffer you want to parse.
121 * If you are not sure which glot is correct, use the Detector to pick a glot.
123 static VALUE _ohcount_parse(VALUE self, VALUE buffer, VALUE polyglot_name_value) {
125 // find the polyglot to parse with
126 char *polyglot_name = RSTRING(polyglot_name_value)->ptr;
128 for (i_polyglot = 0; POLYGLOTS[i_polyglot] != NULL; i_polyglot++) {
129 if (strcmp(POLYGLOTS[i_polyglot]->name, polyglot_name) == 0) {
130 Polyglot *polyglot = POLYGLOTS[i_polyglot];
133 parser_parse(&pr, RSTRING(buffer)->ptr, RSTRING(buffer)->len, polyglot);
135 // create array we'll return all the language_breakdowns in
136 VALUE ary = rb_ary_new2(pr.language_breakdown_count);
139 for(i_pr = 0; i_pr < pr.language_breakdown_count; i_pr++) {
140 LanguageBreakdown *lb = (LanguageBreakdown *) malloc(sizeof(LanguageBreakdown));
141 LanguageBreakdown *src_lb = &(pr.language_breakdowns[i_pr]);
142 strcpy(lb->name,src_lb->name);
143 lb->code = src_lb->code;
144 lb->comment = src_lb->comment;
145 lb->blank_count = src_lb->blank_count;
146 rb_ary_store(ary, i_pr, Data_Wrap_Struct(rb_class_language_breakdown, 0, _language_breakdown_free, lb));
152 rb_raise(rb_eStandardError,"Polyglot name invalid");
157 static VALUE _ohcount_polyglots(VALUE self) {
159 // how many are they?
161 Polyglot **p = POLYGLOTS;
162 while ((*p++) != NULL) {
167 VALUE ary = rb_ary_new2(poly_count);
171 for (i_poly = 0; POLYGLOTS[i_poly] != NULL; i_poly++) {
172 VALUE poly_name = rb_str_new2(POLYGLOTS[i_poly]->name);
173 rb_ary_store(ary, i_poly, poly_name);
180 void Init_ohcount_native () {
181 rb_module_ohcount = rb_define_module("Ohcount");
182 rb_define_module_function(rb_module_ohcount, "parse", _ohcount_parse, 2);
183 rb_define_module_function(rb_module_ohcount, "polyglots", _ohcount_polyglots, 0);
185 // define language_breakdown
186 rb_class_language_breakdown = rb_define_class_under( rb_module_ohcount, "LanguageBreakdown", rb_cObject);
187 rb_define_alloc_func (rb_class_language_breakdown, _language_breakdown_allocate);
188 rb_define_method (rb_class_language_breakdown, "initialize", _language_breakdown_initialize, 4);
189 rb_define_method (rb_class_language_breakdown, "name", _language_breakdown_name, 0);
190 rb_define_method (rb_class_language_breakdown, "code", _language_breakdown_code, 0);
191 rb_define_method (rb_class_language_breakdown, "comment", _language_breakdown_comment, 0);
192 rb_define_method (rb_class_language_breakdown, "blanks", _language_breakdown_blanks, 0);