main
1#include "spandx.h"
2
3#define NEWLINE 10
4
5VALUE rb_mSpandx;
6VALUE rb_mCore;
7VALUE rb_mCsvParser;
8
9// "name","version","license"
10// "name","version","license"\n
11// "name","version","license"\r
12// "name","version","license"\r\n
13// "name","version",""\r\n
14VALUE parse(VALUE self, VALUE line)
15{
16 if (NIL_P(line)) return Qnil;
17
18 char *p;
19
20 p = RSTRING_PTR(line);
21 if (*p != '"') return Qnil;
22
23 const VALUE items = rb_ary_new2(3);
24 const char *s, *n;
25 const long len = RSTRING_LEN(line);
26 enum { open, closed } state = closed;
27
28 for (int i = 0; i < len && *p; i++) {
29 if (*p == '"') {
30 n = p;
31 if (i < (len - 1)) *n++;
32
33 if (state == closed) {
34 s = n;
35 state = open;
36 } else if (state == open) {
37 if (!*n || n == p || *n == ',' || *n == NEWLINE) {
38 rb_ary_push(items, rb_str_new(s, p - s));
39 state = closed;
40 }
41 }
42 }
43 *(p++);
44 }
45
46 return items;
47}
48
49void Init_spandx(void)
50{
51 rb_mSpandx = rb_define_module("Spandx");
52 rb_mCore = rb_define_module_under(rb_mSpandx, "Core");
53 rb_mCsvParser = rb_define_module_under(rb_mCore, "CsvParser");
54 rb_define_module_function(rb_mCsvParser, "parse", parse, 1);
55
56 rb_gc_register_mark_object(rb_mCsvParser);
57}