/* -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2 c-style: "BSD" -*- */ /* * _template.c - a template file for LangScan modules * * Copyright (C) 2004-2005 Akira Tanaka * All rights reserved. * This is free software with ABSOLUTELY NO WARRANTY. * * You can redistribute it and/or modify it under the terms of * the GNU General Public License version 2. */ #include #include "php.h" static VALUE token_symbol_list[ #define LANGSCAN_PHP_TOKEN(token) 1 + 1 + LANGSCAN_PHP_TOKEN_LIST 0 #undef LANGSCAN_PHP_TOKEN ]; #ifndef RSTRING_PTR # define RSTRING_PTR(str) (RSTRING(str)->ptr) #endif #ifndef RSTRING_LEN # define RSTRING_LEN(str) (RSTRING(str)->len) #endif #ifndef RARRAY_PTR # define RARRAY_PTR(str) (RARRAY(str)->ptr) #endif #ifndef RARRAY_LEN # define RARRAY_LEN(str) (RARRAY(str)->len) #endif static size_t user_read_str(void **user_data_p, char *buf, size_t maxlen) { VALUE user_data = (VALUE)*user_data_p; VALUE user_str = RARRAY_PTR(user_data)[0]; VALUE user_off = RARRAY_PTR(user_data)[1]; long off = NUM2LONG(user_off); if (RSTRING_LEN(user_str)-off < maxlen) { maxlen = RSTRING_LEN(user_str)-off; } memcpy(buf, RSTRING_PTR(user_str)+off, maxlen); RARRAY_PTR(user_data)[1] = LONG2NUM(off+maxlen); return maxlen; } static void tokenizer_mark(langscan_php_tokenizer_t *tokenizer) { if (tokenizer == NULL) return; rb_gc_mark((VALUE)langscan_php_tokenizer_get_user_data(tokenizer)); } static void tokenizer_free(langscan_php_tokenizer_t *tokenizer) { if (tokenizer == NULL) return; langscan_php_free_tokenizer(tokenizer); } static VALUE tokenizer_s_allocate(VALUE klass) { return Data_Wrap_Struct(klass, tokenizer_mark, tokenizer_free, NULL); } static VALUE tokenizer_initialize(VALUE self, VALUE user_data) { VALUE tmp; user_read_t user_read; langscan_php_tokenizer_t *tokenizer; Data_Get_Struct(self, langscan_php_tokenizer_t, tokenizer); StringValue(user_data); user_read = user_read_str; user_data = rb_ary_new3(2, rb_str_new4(user_data), INT2FIX(0)); RBASIC(user_data)->klass = 0; DATA_PTR(self) = langscan_php_make_tokenizer(user_read, (void *)user_data); return self; } static VALUE tokenizer_get_token(VALUE self) { langscan_php_tokenizer_t *tokenizer; langscan_php_token_t token; Data_Get_Struct(self, langscan_php_tokenizer_t, tokenizer); if (tokenizer == NULL) { return Qnil; } token = langscan_php_get_token(tokenizer); if (token == langscan_php_eof) { DATA_PTR(self) = NULL; langscan_php_free_tokenizer(tokenizer); return Qnil; } return rb_ary_new3(8, token_symbol_list[token], rb_str_new(langscan_php_curtoken_text(tokenizer), langscan_php_curtoken_leng(tokenizer)), INT2NUM(langscan_php_curtoken_beg_lineno(tokenizer)), INT2NUM(langscan_php_curtoken_beg_columnno(tokenizer)), INT2NUM(langscan_php_curtoken_beg_byteno(tokenizer)), INT2NUM(langscan_php_curtoken_end_lineno(tokenizer)), INT2NUM(langscan_php_curtoken_end_columnno(tokenizer)), INT2NUM(langscan_php_curtoken_end_byteno(tokenizer))); } static VALUE tokenizer_close(VALUE self) { langscan_php_tokenizer_t *tokenizer; Data_Get_Struct(self, langscan_php_tokenizer_t, tokenizer); if (tokenizer == NULL) { return Qnil; } DATA_PTR(self) = NULL; langscan_php_free_tokenizer(tokenizer); return Qnil; } void Init_php() { VALUE LangScan = rb_define_module("LangScan"); VALUE LangScan_PHP = rb_define_module_under(LangScan, "PHP"); VALUE Tokenizer = rb_define_class_under(LangScan_PHP, "Tokenizer", rb_cData); langscan_php_token_t token_id; token_id = 0; token_symbol_list[token_id++] = Qnil; #define LANGSCAN_PHP_TOKEN(token) token_symbol_list[token_id++] = ID2SYM(rb_intern(#token)); LANGSCAN_PHP_TOKEN_LIST #undef LANGSCAN_PHP_TOKEN rb_define_alloc_func(Tokenizer, tokenizer_s_allocate); rb_define_method(Tokenizer, "initialize", tokenizer_initialize, 1); rb_define_method(Tokenizer, "get_token", tokenizer_get_token, 0); rb_define_method(Tokenizer, "close", tokenizer_close, 0); }