| /* Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "EXTERN.h" |
| #include "perl.h" |
| #include "XSUB.h" |
| |
| #include "CFC.h" |
| |
| /* Rather than provide an XSUB for each accessor, we can use one multipath |
| * accessor function per class, with several Perl-space aliases. All set |
| * functions have odd-numbered aliases, and all get functions have |
| * even-numbered aliases. These two macros serve as bookends for the switch |
| * function. |
| */ |
| #define START_SET_OR_GET_SWITCH \ |
| SV *retval = &PL_sv_undef; \ |
| /* If called as a setter, make sure the extra arg is there. */ \ |
| if (ix % 2 == 1) { \ |
| if (items != 2) { croak("usage: $object->set_xxxxxx($val)"); } \ |
| } \ |
| else { \ |
| if (items != 1) { croak("usage: $object->get_xxxxx()"); } \ |
| } \ |
| switch (ix) { |
| |
| #define END_SET_OR_GET_SWITCH \ |
| default: croak("Internal error. ix: %d", ix); \ |
| } \ |
| if (ix % 2 == 0) { \ |
| XPUSHs(sv_2mortal(retval)); \ |
| XSRETURN(1); \ |
| } \ |
| else { \ |
| XSRETURN(0); \ |
| } |
| |
| static SV* |
| S_cfcbase_to_perlref(void *thing) { |
| if (thing) { |
| SV *perl_obj = (SV*)CFCBase_get_perl_obj((CFCBase*)thing); |
| return newRV(perl_obj); |
| } |
| else { |
| return newSV(0); |
| } |
| } |
| |
| // Transform a NULL-terminated array of CFCBase* into a Perl arrayref. |
| static SV* |
| S_array_of_cfcbase_to_av(CFCBase **things) { |
| AV *av = newAV(); |
| size_t i; |
| for (i = 0; things[i] != NULL; i++) { |
| SV *val = S_cfcbase_to_perlref(things[i]); |
| av_store(av, i, val); |
| } |
| SV *retval = newRV((SV*)av); |
| SvREFCNT_dec(av); |
| return retval; |
| } |
| |
| MODULE = Clownfish PACKAGE = Clownfish::CBlock |
| |
| SV* |
| _new(klass, contents) |
| const char *klass; |
| const char *contents; |
| CODE: |
| CFCCBlock *self = CFCCBlock_new(contents); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCCBlock *self; |
| PPCODE: |
| CFCCBlock_destroy(self); |
| |
| void |
| _set_or_get(self, ...) |
| CFCCBlock *self; |
| ALIAS: |
| get_contents = 2 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| const char *contents = CFCCBlock_get_contents(self); |
| retval = newSVpvn(contents, strlen(contents)); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Class |
| |
| SV* |
| _create(klass, parcel, exposure_sv, class_name_sv, cnick_sv, micro_sym_sv, docucomment, source_class_sv, parent_class_name_sv, is_final, is_inert) |
| const char *klass; |
| CFCParcel *parcel; |
| SV *exposure_sv; |
| SV *class_name_sv; |
| SV *cnick_sv; |
| SV *micro_sym_sv; |
| CFCDocuComment *docucomment; |
| SV *source_class_sv; |
| SV *parent_class_name_sv; |
| bool is_final; |
| bool is_inert; |
| CODE: |
| const char *exposure = |
| SvOK(exposure_sv) ? SvPV_nolen(exposure_sv) : NULL; |
| const char *class_name = |
| SvOK(class_name_sv) ? SvPV_nolen(class_name_sv) : NULL; |
| const char *cnick = |
| SvOK(cnick_sv) ? SvPV_nolen(cnick_sv) : NULL; |
| const char *micro_sym = |
| SvOK(micro_sym_sv) ? SvPV_nolen(micro_sym_sv) : NULL; |
| const char *source_class = |
| SvOK(source_class_sv) ? SvPV_nolen(source_class_sv) : NULL; |
| const char *parent_class_name = |
| SvOK(parent_class_name_sv) ? SvPV_nolen(parent_class_name_sv) : NULL; |
| CFCClass *self = CFCClass_create(parcel, exposure, class_name, cnick, |
| micro_sym, docucomment, source_class, |
| parent_class_name, is_final, is_inert); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCClass *self; |
| PPCODE: |
| CFCClass_destroy(self); |
| |
| SV* |
| _fetch_singleton(parcel, class_name) |
| CFCParcel *parcel; |
| const char *class_name; |
| CODE: |
| CFCClass *klass = CFCClass_fetch_singleton(parcel, class_name); |
| RETVAL = S_cfcbase_to_perlref(klass); |
| OUTPUT: RETVAL |
| |
| void |
| _register(self) |
| CFCClass *self; |
| PPCODE: |
| CFCClass_register(self); |
| |
| void |
| _clear_registry(...) |
| PPCODE: |
| CFCClass_clear_registry(); |
| |
| void |
| append_autocode(self, autocode) |
| CFCClass *self; |
| const char *autocode; |
| PPCODE: |
| CFCClass_append_autocode(self, autocode); |
| |
| void |
| add_child(self, child) |
| CFCClass *self; |
| CFCClass *child; |
| PPCODE: |
| CFCClass_add_child(self, child); |
| |
| void |
| add_member_var(self, var) |
| CFCClass *self; |
| CFCVariable *var; |
| PPCODE: |
| CFCClass_add_member_var(self, var); |
| |
| void |
| add_function(self, func) |
| CFCClass *self; |
| CFCFunction *func; |
| PPCODE: |
| CFCClass_add_function(self, func); |
| |
| void |
| add_method(self, method) |
| CFCClass *self; |
| CFCMethod *method; |
| PPCODE: |
| CFCClass_add_method(self, method); |
| |
| void |
| add_attribute(self, name, value_sv) |
| CFCClass *self; |
| const char *name; |
| SV *value_sv; |
| PPCODE: |
| char *value = SvOK(value_sv) ? SvPV_nolen(value_sv) : NULL; |
| CFCClass_add_attribute(self, name, value); |
| |
| int |
| has_attribute(self, name) |
| CFCClass *self; |
| const char *name; |
| CODE: |
| RETVAL = CFCClass_has_attribute(self, name); |
| OUTPUT: RETVAL |
| |
| void |
| grow_tree(self) |
| CFCClass *self; |
| PPCODE: |
| CFCClass_grow_tree(self); |
| |
| void |
| add_inert_var(self, var) |
| CFCClass *self; |
| CFCVariable *var; |
| PPCODE: |
| CFCClass_add_inert_var(self, var); |
| |
| SV* |
| function(self, sym) |
| CFCClass *self; |
| const char *sym; |
| CODE: |
| CFCFunction *func = CFCClass_function(self, sym); |
| RETVAL = S_cfcbase_to_perlref(func); |
| OUTPUT: RETVAL |
| |
| SV* |
| method(self, sym) |
| CFCClass *self; |
| const char *sym; |
| CODE: |
| CFCMethod *method = CFCClass_method(self, sym); |
| RETVAL = S_cfcbase_to_perlref(method); |
| OUTPUT: RETVAL |
| |
| SV* |
| novel_method(self, sym) |
| CFCClass *self; |
| const char *sym; |
| CODE: |
| CFCMethod *method = CFCClass_novel_method(self, sym); |
| RETVAL = S_cfcbase_to_perlref(method); |
| OUTPUT: RETVAL |
| |
| void |
| _set_or_get(self, ...) |
| CFCClass *self; |
| ALIAS: |
| get_cnick = 2 |
| set_parent = 5 |
| get_parent = 6 |
| get_autocode = 8 |
| get_source_class = 10 |
| get_parent_class_name = 12 |
| final = 14 |
| inert = 16 |
| get_struct_sym = 18 |
| full_struct_sym = 20 |
| short_vtable_var = 22 |
| full_vtable_var = 24 |
| full_vtable_type = 26 |
| include_h = 28 |
| get_docucomment = 30 |
| children = 32 |
| functions = 34 |
| methods = 36 |
| member_vars = 38 |
| inert_vars = 40 |
| tree_to_ladder = 42 |
| novel_methods = 44 |
| novel_member_vars = 46 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| const char *value = CFCClass_get_cnick(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 5: { |
| CFCClass *parent = NULL; |
| if (SvOK(ST(1)) |
| && sv_derived_from(ST(1), "Clownfish::Class") |
| ) { |
| IV objint = SvIV((SV*)SvRV(ST(1))); |
| parent = INT2PTR(CFCClass*, objint); |
| } |
| CFCClass_set_parent(self, parent); |
| break; |
| } |
| case 6: { |
| CFCClass *parent = CFCClass_get_parent(self); |
| retval = S_cfcbase_to_perlref(parent); |
| break; |
| } |
| case 8: { |
| const char *value = CFCClass_get_autocode(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 10: { |
| const char *value = CFCClass_get_source_class(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 12: { |
| const char *value = CFCClass_get_parent_class_name(self); |
| retval = value ? newSVpvn(value, strlen(value)) : newSV(0); |
| } |
| break; |
| case 14: |
| retval = newSViv(CFCClass_final(self)); |
| break; |
| case 16: |
| retval = newSViv(CFCClass_inert(self)); |
| break; |
| case 18: { |
| const char *value = CFCClass_get_struct_sym(self); |
| retval = value ? newSVpvn(value, strlen(value)) : newSV(0); |
| } |
| break; |
| case 20: { |
| const char *value = CFCClass_full_struct_sym(self); |
| retval = value ? newSVpvn(value, strlen(value)) : newSV(0); |
| } |
| break; |
| case 22: { |
| const char *value = CFCClass_short_vtable_var(self); |
| retval = value ? newSVpvn(value, strlen(value)) : newSV(0); |
| } |
| break; |
| case 24: { |
| const char *value = CFCClass_full_vtable_var(self); |
| retval = value ? newSVpvn(value, strlen(value)) : newSV(0); |
| } |
| break; |
| case 26: { |
| const char *value = CFCClass_full_vtable_type(self); |
| retval = value ? newSVpvn(value, strlen(value)) : newSV(0); |
| } |
| break; |
| case 28: { |
| const char *value = CFCClass_include_h(self); |
| retval = value ? newSVpvn(value, strlen(value)) : newSV(0); |
| } |
| break; |
| case 30: { |
| CFCDocuComment *docucomment = CFCClass_get_docucomment(self); |
| retval = S_cfcbase_to_perlref(docucomment); |
| } |
| break; |
| case 32: |
| retval = S_array_of_cfcbase_to_av( |
| (CFCBase**)CFCClass_children(self)); |
| break; |
| case 34: |
| retval = S_array_of_cfcbase_to_av((CFCBase**)CFCClass_functions(self)); |
| break; |
| case 36: |
| retval = S_array_of_cfcbase_to_av((CFCBase**)CFCClass_methods(self)); |
| break; |
| case 38: |
| retval = S_array_of_cfcbase_to_av((CFCBase**)CFCClass_member_vars(self)); |
| break; |
| case 40: |
| retval = S_array_of_cfcbase_to_av((CFCBase**)CFCClass_inert_vars(self)); |
| break; |
| case 42: { |
| CFCClass **ladder = CFCClass_tree_to_ladder(self); |
| retval = S_array_of_cfcbase_to_av((CFCBase**)ladder); |
| FREEMEM(ladder); |
| break; |
| } |
| case 44: { |
| CFCMethod **novel = CFCClass_novel_methods(self); |
| retval = S_array_of_cfcbase_to_av((CFCBase**)novel); |
| FREEMEM(novel); |
| break; |
| } |
| case 46: { |
| CFCVariable **novel = CFCClass_novel_member_vars(self); |
| retval = S_array_of_cfcbase_to_av((CFCBase**)novel); |
| FREEMEM(novel); |
| break; |
| } |
| END_SET_OR_GET_SWITCH |
| } |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::DocuComment |
| |
| SV* |
| parse(klass, text) |
| const char *klass; |
| const char *text; |
| CODE: |
| CFCDocuComment *self = CFCDocuComment_parse(text); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCDocuComment *self; |
| PPCODE: |
| CFCDocuComment_destroy(self); |
| |
| void |
| _set_or_get(self, ...) |
| CFCDocuComment *self; |
| ALIAS: |
| get_description = 2 |
| get_brief = 4 |
| get_long = 6 |
| get_param_names = 8 |
| get_param_docs = 10 |
| get_retval = 12 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| const char *description = CFCDocuComment_get_description(self); |
| retval = newSVpvn(description, strlen(description)); |
| } |
| break; |
| case 4: { |
| const char *brief = CFCDocuComment_get_brief(self); |
| retval = newSVpvn(brief, strlen(brief)); |
| } |
| break; |
| case 6: { |
| const char *long_description = CFCDocuComment_get_long(self); |
| retval = newSVpvn(long_description, strlen(long_description)); |
| } |
| break; |
| case 8: { |
| AV *av = newAV(); |
| const char **names = CFCDocuComment_get_param_names(self); |
| size_t i; |
| for (i = 0; names[i] != NULL; i++) { |
| SV *val_sv = newSVpvn(names[i], strlen(names[i])); |
| av_store(av, i, val_sv); |
| } |
| retval = newRV((SV*)av); |
| SvREFCNT_dec(av); |
| break; |
| } |
| case 10: { |
| AV *av = newAV(); |
| const char **docs = CFCDocuComment_get_param_docs(self); |
| size_t i; |
| for (i = 0; docs[i] != NULL; i++) { |
| SV *val_sv = newSVpvn(docs[i], strlen(docs[i])); |
| av_store(av, i, val_sv); |
| } |
| retval = newRV((SV*)av); |
| SvREFCNT_dec(av); |
| break; |
| } |
| case 12: { |
| const char *rv = CFCDocuComment_get_retval(self); |
| retval = rv ? newSVpvn(rv, strlen(rv)) : newSV(0); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Dumpable |
| |
| SV* |
| _new(klass) |
| const char *klass; |
| CODE: |
| CFCDumpable *self = CFCDumpable_new(); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCDumpable *self; |
| PPCODE: |
| CFCDumpable_destroy(self); |
| |
| void |
| add_dumpables(self, klass) |
| CFCDumpable *self; |
| CFCClass *klass; |
| PPCODE: |
| CFCDumpable_add_dumpables(self, klass); |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::File |
| |
| SV* |
| _new(klass, source_class) |
| const char *klass; |
| const char *source_class; |
| CODE: |
| CFCFile *self = CFCFile_new(source_class); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| _destroy(self) |
| CFCFile *self; |
| PPCODE: |
| CFCFile_destroy(self); |
| |
| void |
| add_block(self, block) |
| CFCFile *self; |
| CFCBase *block; |
| PPCODE: |
| CFCFile_add_block(self, block); |
| |
| void |
| _set_or_get(self, ...) |
| CFCFile *self; |
| ALIAS: |
| set_modified = 1 |
| get_modified = 2 |
| get_source_class = 4 |
| guard_name = 6 |
| guard_start = 8 |
| guard_close = 10 |
| blocks = 12 |
| classes = 14 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 1: |
| CFCFile_set_modified(self, !!SvTRUE(ST(1))); |
| break; |
| case 2: |
| retval = newSViv(CFCFile_get_modified(self)); |
| break; |
| case 4: { |
| const char *value = CFCFile_get_source_class(self); |
| retval = newSVpv(value, strlen(value)); |
| } |
| break; |
| case 6: { |
| const char *value = CFCFile_guard_name(self); |
| retval = newSVpv(value, strlen(value)); |
| } |
| break; |
| case 8: { |
| const char *value = CFCFile_guard_start(self); |
| retval = newSVpv(value, strlen(value)); |
| } |
| break; |
| case 10: { |
| const char *value = CFCFile_guard_close(self); |
| retval = newSVpv(value, strlen(value)); |
| } |
| break; |
| case 12: |
| retval = S_array_of_cfcbase_to_av(CFCFile_blocks(self)); |
| break; |
| case 14: |
| retval = S_array_of_cfcbase_to_av( |
| (CFCBase**)CFCFile_classes(self)); |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| SV* |
| _gen_path(self, base_dir = NULL) |
| CFCFile *self; |
| const char *base_dir; |
| ALIAS: |
| c_path = 1 |
| h_path = 2 |
| cfh_path = 3 |
| CODE: |
| { |
| size_t buf_size = CFCFile_path_buf_size(self, base_dir); |
| RETVAL = newSV(buf_size); |
| SvPOK_on(RETVAL); |
| char *buf = SvPVX(RETVAL); |
| switch (ix) { |
| case 1: |
| CFCFile_c_path(self, buf, buf_size, base_dir); |
| break; |
| case 2: |
| CFCFile_h_path(self, buf, buf_size, base_dir); |
| break; |
| case 3: |
| CFCFile_cfh_path(self, buf, buf_size, base_dir); |
| break; |
| default: |
| croak("unexpected ix value: %d", ix); |
| } |
| SvCUR_set(RETVAL, strlen(buf)); |
| } |
| OUTPUT: RETVAL |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Function |
| |
| SV* |
| _new(klass, parcel, exposure_sv, class_name_sv, class_cnick_sv, micro_sym_sv, return_type, param_list, docucomment, is_inline) |
| const char *klass; |
| CFCParcel *parcel; |
| SV *exposure_sv; |
| SV *class_name_sv; |
| SV *class_cnick_sv; |
| SV *micro_sym_sv; |
| CFCType *return_type; |
| CFCParamList *param_list; |
| CFCDocuComment *docucomment; |
| int is_inline; |
| CODE: |
| const char *exposure = |
| SvOK(exposure_sv) ? SvPV_nolen(exposure_sv) : NULL; |
| const char *class_name = |
| SvOK(class_name_sv) ? SvPV_nolen(class_name_sv) : NULL; |
| const char *class_cnick = |
| SvOK(class_cnick_sv) ? SvPV_nolen(class_cnick_sv) : NULL; |
| const char *micro_sym = |
| SvOK(micro_sym_sv) ? SvPV_nolen(micro_sym_sv) : NULL; |
| CFCFunction *self = CFCFunction_new(parcel, exposure, class_name, |
| class_cnick, micro_sym, return_type, |
| param_list, docucomment, is_inline); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCFunction *self; |
| PPCODE: |
| CFCFunction_destroy(self); |
| |
| void |
| _set_or_get(self, ...) |
| CFCFunction *self; |
| ALIAS: |
| get_return_type = 2 |
| get_param_list = 4 |
| get_docucomment = 6 |
| inline = 8 |
| void = 10 |
| full_func_sym = 12 |
| short_func_sym = 14 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| CFCType *type = CFCFunction_get_return_type(self); |
| retval = S_cfcbase_to_perlref(type); |
| } |
| break; |
| case 4: { |
| CFCParamList *param_list = CFCFunction_get_param_list(self); |
| retval = S_cfcbase_to_perlref(param_list); |
| } |
| break; |
| case 6: { |
| CFCDocuComment *docucomment |
| = CFCFunction_get_docucomment(self); |
| retval = S_cfcbase_to_perlref(docucomment); |
| } |
| break; |
| case 8: |
| retval = newSViv(CFCFunction_inline(self)); |
| break; |
| case 10: |
| retval = newSViv(CFCFunction_void(self)); |
| break; |
| case 12: { |
| const char *full_sym = CFCFunction_full_func_sym(self); |
| retval = newSVpv(full_sym, strlen(full_sym)); |
| } |
| break; |
| case 14: { |
| const char *short_sym = CFCFunction_short_func_sym(self); |
| retval = newSVpv(short_sym, strlen(short_sym)); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Hierarchy |
| |
| SV* |
| _new(klass, source, dest, parser) |
| const char *klass; |
| const char *source; |
| const char *dest; |
| SV *parser; |
| CODE: |
| CFCHierarchy *self = CFCHierarchy_new(source, dest, parser); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCHierarchy *self; |
| PPCODE: |
| CFCHierarchy_destroy(self); |
| |
| void |
| build(self) |
| CFCHierarchy *self; |
| PPCODE: |
| CFCHierarchy_build(self); |
| |
| int |
| propagate_modified(self, ...) |
| CFCHierarchy *self; |
| CODE: |
| int modified = items > 1 ? !!SvTRUE(ST(1)) : 0; |
| RETVAL = CFCHierarchy_propagate_modified(self, modified); |
| OUTPUT: RETVAL |
| |
| void |
| _set_or_get(self, ...) |
| CFCHierarchy *self; |
| ALIAS: |
| get_source = 2 |
| get_dest = 4 |
| files = 8 |
| ordered_classes = 10 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| const char *value = CFCHierarchy_get_source(self); |
| retval = newSVpv(value, strlen(value)); |
| } |
| break; |
| case 4: { |
| const char *value = CFCHierarchy_get_dest(self); |
| retval = newSVpv(value, strlen(value)); |
| } |
| break; |
| case 8: |
| retval = S_array_of_cfcbase_to_av( |
| (CFCBase**)CFCHierarchy_files(self)); |
| break; |
| case 10: { |
| CFCClass **ladder = CFCHierarchy_ordered_classes(self); |
| retval = S_array_of_cfcbase_to_av((CFCBase**)ladder); |
| FREEMEM(ladder); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Method |
| |
| SV* |
| _new(klass, parcel, exposure_sv, class_name_sv, class_cnick_sv, macro_sym, return_type, param_list, docucomment, is_final, is_abstract) |
| const char *klass; |
| CFCParcel *parcel; |
| SV *exposure_sv; |
| SV *class_name_sv; |
| SV *class_cnick_sv; |
| const char *macro_sym; |
| CFCType *return_type; |
| CFCParamList *param_list; |
| CFCDocuComment *docucomment; |
| int is_final; |
| int is_abstract; |
| CODE: |
| const char *exposure = |
| SvOK(exposure_sv) ? SvPV_nolen(exposure_sv) : NULL; |
| const char *class_name = |
| SvOK(class_name_sv) ? SvPV_nolen(class_name_sv) : NULL; |
| const char *class_cnick = |
| SvOK(class_cnick_sv) ? SvPV_nolen(class_cnick_sv) : NULL; |
| CFCMethod *self = CFCMethod_new(parcel, exposure, class_name, class_cnick, |
| macro_sym, return_type, param_list, |
| docucomment, is_final, is_abstract); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCMethod *self; |
| PPCODE: |
| CFCMethod_destroy(self); |
| |
| int |
| compatible(self, other) |
| CFCMethod *self; |
| CFCMethod *other; |
| CODE: |
| RETVAL = CFCMethod_compatible(self, other); |
| OUTPUT: RETVAL |
| |
| void |
| override(self, other) |
| CFCMethod *self; |
| CFCMethod *other; |
| PPCODE: |
| CFCMethod_override(self, other); |
| |
| SV* |
| finalize(self) |
| CFCMethod *self; |
| CODE: |
| CFCMethod *finalized = CFCMethod_finalize(self); |
| RETVAL = S_cfcbase_to_perlref(finalized); |
| CFCBase_decref((CFCBase*)finalized); |
| OUTPUT: RETVAL |
| |
| SV* |
| _various_method_syms(self, invoker) |
| CFCMethod *self; |
| const char *invoker; |
| ALIAS: |
| short_method_sym = 1 |
| full_method_sym = 2 |
| full_offset_sym = 3 |
| CODE: |
| size_t size = 0; |
| switch (ix) { |
| case 1: |
| size = CFCMethod_short_method_sym(self, invoker, NULL, 0); |
| break; |
| case 2: |
| size = CFCMethod_full_method_sym(self, invoker, NULL, 0); |
| break; |
| case 3: |
| size = CFCMethod_full_offset_sym(self, invoker, NULL, 0); |
| break; |
| default: croak("Unexpected ix: %d", ix); |
| } |
| RETVAL = newSV(size); |
| SvPOK_on(RETVAL); |
| char *buf = SvPVX(RETVAL); |
| switch (ix) { |
| case 1: |
| CFCMethod_short_method_sym(self, invoker, buf, size); |
| break; |
| case 2: |
| CFCMethod_full_method_sym(self, invoker, buf, size); |
| break; |
| case 3: |
| CFCMethod_full_offset_sym(self, invoker, buf, size); |
| break; |
| default: croak("Unexpected ix: %d", ix); |
| } |
| SvCUR_set(RETVAL, strlen(buf)); |
| OUTPUT: RETVAL |
| |
| void |
| _set_or_get(self, ...) |
| CFCMethod *self; |
| ALIAS: |
| get_macro_sym = 2 |
| short_typedef = 4 |
| full_typedef = 6 |
| full_callback_sym = 8 |
| full_override_sym = 10 |
| abstract = 12 |
| novel = 14 |
| final = 16 |
| self_type = 18 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| const char *macro_sym = CFCMethod_get_macro_sym(self); |
| retval = newSVpvn(macro_sym, strlen(macro_sym)); |
| } |
| break; |
| case 4: { |
| const char *short_typedef = CFCMethod_short_typedef(self); |
| retval = newSVpvn(short_typedef, strlen(short_typedef)); |
| } |
| break; |
| case 6: { |
| const char *value = CFCMethod_full_typedef(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 8: { |
| const char *value = CFCMethod_full_callback_sym(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 10: { |
| const char *value = CFCMethod_full_override_sym(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 12: |
| retval = newSViv(CFCMethod_abstract(self)); |
| break; |
| case 14: |
| retval = newSViv(CFCMethod_novel(self)); |
| break; |
| case 16: |
| retval = newSViv(CFCMethod_final(self)); |
| break; |
| case 18: { |
| CFCType *type = CFCMethod_self_type(self); |
| retval = S_cfcbase_to_perlref(type); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::ParamList |
| |
| SV* |
| _new(klass, variadic) |
| const char *klass; |
| int variadic; |
| CODE: |
| CFCParamList *self = CFCParamList_new(variadic); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCParamList *self; |
| PPCODE: |
| CFCParamList_destroy(self); |
| |
| void |
| add_param(self, variable, value_sv) |
| CFCParamList *self; |
| CFCVariable *variable; |
| SV *value_sv; |
| PPCODE: |
| const char *value = SvOK(value_sv) ? SvPV_nolen(value_sv) : NULL; |
| CFCParamList_add_param(self, variable, value); |
| |
| void |
| _set_or_get(self, ...) |
| CFCParamList *self; |
| ALIAS: |
| get_variables = 2 |
| get_initial_values = 4 |
| variadic = 6 |
| num_vars = 8 |
| to_c = 10 |
| name_list = 12 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| AV *av = newAV(); |
| CFCVariable **vars = CFCParamList_get_variables(self); |
| size_t i; |
| size_t num_vars = CFCParamList_num_vars(self); |
| for (i = 0; i < num_vars; i++) { |
| SV *ref = S_cfcbase_to_perlref(vars[i]); |
| av_store(av, i, ref); |
| } |
| retval = newRV((SV*)av); |
| SvREFCNT_dec(av); |
| break; |
| } |
| case 4: { |
| AV *av = newAV(); |
| const char **values = CFCParamList_get_initial_values(self); |
| size_t i; |
| size_t num_vars = CFCParamList_num_vars(self); |
| for (i = 0; i < num_vars; i++) { |
| if (values[i] != NULL) { |
| SV *val_sv = newSVpvn(values[i], strlen(values[i])); |
| av_store(av, i, val_sv); |
| } |
| else { |
| av_store(av, i, newSV(0)); |
| } |
| } |
| retval = newRV((SV*)av); |
| SvREFCNT_dec(av); |
| break; |
| } |
| case 6: |
| retval = newSViv(CFCParamList_variadic(self)); |
| break; |
| case 8: |
| retval = newSViv(CFCParamList_num_vars(self)); |
| break; |
| case 10: { |
| const char *value = CFCParamList_to_c(self); |
| retval = newSVpv(value, strlen(value)); |
| } |
| break; |
| case 12: { |
| const char *value = CFCParamList_name_list(self); |
| retval = newSVpv(value, strlen(value)); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Parcel |
| |
| SV* |
| _singleton(klass, name_sv, cnick_sv) |
| const char *klass; |
| SV *name_sv; |
| SV *cnick_sv; |
| CODE: |
| const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL; |
| const char *cnick = SvOK(cnick_sv) ? SvPV_nolen(cnick_sv) : NULL; |
| CFCParcel *self = CFCParcel_singleton(name, cnick); |
| RETVAL = S_cfcbase_to_perlref(self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCParcel *self; |
| PPCODE: |
| CFCParcel_destroy(self); |
| |
| int |
| equals(self, other) |
| CFCParcel *self; |
| CFCParcel *other; |
| CODE: |
| RETVAL = CFCParcel_equals(self, other); |
| OUTPUT: RETVAL |
| |
| SV* |
| default_parcel(...) |
| CODE: |
| CFCParcel *default_parcel = CFCParcel_default_parcel(); |
| RETVAL = S_cfcbase_to_perlref(default_parcel); |
| OUTPUT: RETVAL |
| |
| void |
| reap_singletons(...) |
| PPCODE: |
| CFCParcel_reap_singletons(); |
| |
| void |
| _set_or_get(self, ...) |
| CFCParcel *self; |
| ALIAS: |
| get_name = 2 |
| get_cnick = 4 |
| get_prefix = 6 |
| get_Prefix = 8 |
| get_PREFIX = 10 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| const char *name = CFCParcel_get_name(self); |
| retval = newSVpvn(name, strlen(name)); |
| } |
| break; |
| case 4: { |
| const char *cnick = CFCParcel_get_cnick(self); |
| retval = newSVpvn(cnick, strlen(cnick)); |
| } |
| break; |
| case 6: { |
| const char *value = CFCParcel_get_prefix(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 8: { |
| const char *value = CFCParcel_get_Prefix(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 10: { |
| const char *value = CFCParcel_get_PREFIX(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Symbol |
| |
| SV* |
| _new(klass, parcel, exposure, class_name_sv, class_cnick_sv, micro_sym_sv) |
| const char *klass; |
| CFCParcel *parcel; |
| const char *exposure; |
| SV *class_name_sv; |
| SV *class_cnick_sv; |
| SV *micro_sym_sv; |
| CODE: |
| const char *class_name = SvOK(class_name_sv) |
| ? SvPV_nolen(class_name_sv) |
| : NULL; |
| const char *class_cnick = SvOK(class_cnick_sv) |
| ? SvPV_nolen(class_cnick_sv) |
| : NULL; |
| const char *micro_sym = SvOK(micro_sym_sv) |
| ? SvPV_nolen(micro_sym_sv) |
| : NULL; |
| CFCSymbol *self = CFCSymbol_new(parcel, exposure, class_name, class_cnick, |
| micro_sym); |
| RETVAL = newSV(0); |
| sv_setref_pv(RETVAL, klass, (void*)self); |
| OUTPUT: RETVAL |
| |
| int |
| equals(self, other) |
| CFCSymbol *self; |
| CFCSymbol *other; |
| CODE: |
| RETVAL = CFCSymbol_equals(self, other); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCSymbol *self; |
| PPCODE: |
| CFCSymbol_destroy(self); |
| |
| void |
| _set_or_get(self, ...) |
| CFCSymbol *self; |
| ALIAS: |
| get_parcel = 2 |
| get_class_name = 4 |
| get_class_cnick = 6 |
| get_exposure = 8 |
| micro_sym = 10 |
| get_prefix = 12 |
| get_Prefix = 14 |
| get_PREFIX = 16 |
| public = 18 |
| private = 20 |
| parcel = 22 |
| local = 24 |
| short_sym = 26 |
| full_sym = 28 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| struct CFCParcel *parcel = CFCSymbol_get_parcel(self); |
| retval = S_cfcbase_to_perlref(parcel); |
| } |
| break; |
| case 4: { |
| const char *class_name = CFCSymbol_get_class_name(self); |
| retval = class_name |
| ? newSVpvn(class_name, strlen(class_name)) |
| : newSV(0); |
| } |
| break; |
| case 6: { |
| const char *class_cnick = CFCSymbol_get_class_cnick(self); |
| retval = class_cnick |
| ? newSVpvn(class_cnick, strlen(class_cnick)) |
| : newSV(0); |
| } |
| break; |
| case 8: { |
| const char *exposure = CFCSymbol_get_exposure(self); |
| retval = newSVpvn(exposure, strlen(exposure)); |
| } |
| break; |
| case 10: { |
| const char *micro_sym = CFCSymbol_micro_sym(self); |
| retval = newSVpvn(micro_sym, strlen(micro_sym)); |
| } |
| break; |
| case 12: { |
| const char *value = CFCSymbol_get_prefix(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 14: { |
| const char *value = CFCSymbol_get_Prefix(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 16: { |
| const char *value = CFCSymbol_get_PREFIX(self); |
| retval = newSVpvn(value, strlen(value)); |
| } |
| break; |
| case 18: |
| retval = newSViv(CFCSymbol_public(self)); |
| break; |
| case 20: |
| retval = newSViv(CFCSymbol_private(self)); |
| break; |
| case 22: |
| retval = newSViv(CFCSymbol_parcel(self)); |
| break; |
| case 24: |
| retval = newSViv(CFCSymbol_local(self)); |
| break; |
| case 26: { |
| const char *short_sym = CFCSymbol_short_sym(self); |
| retval = newSVpvn(short_sym, strlen(short_sym)); |
| } |
| break; |
| case 28: { |
| const char *full_sym = CFCSymbol_full_sym(self); |
| retval = newSVpvn(full_sym, strlen(full_sym)); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Type |
| |
| SV* |
| _new(klass, flags, parcel, specifier, indirection, c_string) |
| const char *klass; |
| int flags; |
| CFCParcel *parcel; |
| const char *specifier; |
| int indirection; |
| const char *c_string; |
| CODE: |
| CFCType *self = CFCType_new(flags, parcel, specifier, indirection, |
| c_string); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| SV* |
| _new_integer(klass, flags, specifier) |
| const char *klass; |
| int flags; |
| const char *specifier; |
| CODE: |
| CFCType *self = CFCType_new_integer(flags, specifier); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| SV* |
| _new_float(klass, flags, specifier) |
| const char *klass; |
| int flags; |
| const char *specifier; |
| CODE: |
| CFCType *self = CFCType_new_float(flags, specifier); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| SV* |
| _new_object(klass, flags, parcel, specifier, indirection) |
| const char *klass; |
| int flags; |
| CFCParcel *parcel; |
| const char *specifier; |
| int indirection; |
| CODE: |
| CFCType *self = CFCType_new_object(flags, parcel, specifier, indirection); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| SV* |
| _new_composite(klass, flags, child_sv, indirection, array) |
| const char *klass; |
| int flags; |
| SV *child_sv; |
| int indirection; |
| const char *array; |
| CODE: |
| CFCType *child = NULL; |
| if (SvOK(child_sv) && sv_derived_from(child_sv, "Clownfish::Type")) { |
| IV objint = SvIV((SV*)SvRV(child_sv)); |
| child = INT2PTR(CFCType*, objint); |
| } |
| else { |
| croak("Param 'child' not a Clownfish::Type"); |
| } |
| CFCType *self = CFCType_new_composite(flags, child, indirection, array); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| SV* |
| _new_void(klass, is_const) |
| const char *klass; |
| int is_const; |
| CODE: |
| CFCType *self = CFCType_new_void(is_const); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| SV* |
| _new_va_list(klass) |
| const char *klass; |
| CODE: |
| CFCType *self = CFCType_new_va_list(); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| SV* |
| _new_arbitrary(klass, parcel, specifier) |
| const char *klass; |
| CFCParcel *parcel; |
| const char *specifier; |
| CODE: |
| CFCType *self = CFCType_new_arbitrary(parcel, specifier); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCType *self; |
| PPCODE: |
| CFCType_destroy(self); |
| |
| int |
| equals(self, other) |
| CFCType *self; |
| CFCType *other; |
| CODE: |
| RETVAL = CFCType_equals(self, other); |
| OUTPUT: RETVAL |
| |
| int |
| similar(self, other) |
| CFCType *self; |
| CFCType *other; |
| CODE: |
| RETVAL = CFCType_similar(self, other); |
| OUTPUT: RETVAL |
| |
| unsigned |
| CONST(...) |
| CODE: |
| RETVAL = CFCTYPE_CONST; |
| OUTPUT: RETVAL |
| |
| unsigned |
| NULLABLE(...) |
| CODE: |
| RETVAL = CFCTYPE_NULLABLE; |
| OUTPUT: RETVAL |
| |
| unsigned |
| INCREMENTED(...) |
| CODE: |
| RETVAL = CFCTYPE_INCREMENTED; |
| OUTPUT: RETVAL |
| |
| unsigned |
| DECREMENTED(...) |
| CODE: |
| RETVAL = CFCTYPE_DECREMENTED; |
| OUTPUT: RETVAL |
| |
| unsigned |
| VOID(...) |
| CODE: |
| RETVAL = CFCTYPE_VOID; |
| OUTPUT: RETVAL |
| |
| unsigned |
| OBJECT(...) |
| CODE: |
| RETVAL = CFCTYPE_OBJECT; |
| OUTPUT: RETVAL |
| |
| unsigned |
| PRIMITIVE(...) |
| CODE: |
| RETVAL = CFCTYPE_PRIMITIVE; |
| OUTPUT: RETVAL |
| |
| unsigned |
| INTEGER(...) |
| CODE: |
| RETVAL = CFCTYPE_INTEGER; |
| OUTPUT: RETVAL |
| |
| unsigned |
| FLOATING(...) |
| CODE: |
| RETVAL = CFCTYPE_FLOATING; |
| OUTPUT: RETVAL |
| |
| unsigned |
| STRING_TYPE(...) |
| CODE: |
| RETVAL = CFCTYPE_STRING_TYPE; |
| OUTPUT: RETVAL |
| |
| unsigned |
| VA_LIST(...) |
| CODE: |
| RETVAL = CFCTYPE_VA_LIST; |
| OUTPUT: RETVAL |
| |
| unsigned |
| ARBITRARY(...) |
| CODE: |
| RETVAL = CFCTYPE_ARBITRARY; |
| OUTPUT: RETVAL |
| |
| unsigned |
| COMPOSITE(...) |
| CODE: |
| RETVAL = CFCTYPE_COMPOSITE; |
| OUTPUT: RETVAL |
| |
| void |
| _set_or_get(self, ...) |
| CFCType *self; |
| ALIAS: |
| set_specifier = 1 |
| get_specifier = 2 |
| get_parcel = 4 |
| get_indirection = 6 |
| set_c_string = 7 |
| to_c = 8 |
| const = 10 |
| set_nullable = 11 |
| nullable = 12 |
| is_void = 14 |
| is_object = 16 |
| is_primitive = 18 |
| is_integer = 20 |
| is_floating = 22 |
| is_string_type = 24 |
| is_va_list = 26 |
| is_arbitrary = 28 |
| is_composite = 30 |
| get_width = 32 |
| incremented = 34 |
| decremented = 36 |
| get_array = 38 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 1: |
| CFCType_set_specifier(self, SvPV_nolen(ST(1))); |
| break; |
| case 2: { |
| const char *specifier = CFCType_get_specifier(self); |
| retval = newSVpvn(specifier, strlen(specifier)); |
| } |
| break; |
| case 4: { |
| CFCParcel *parcel = CFCType_get_parcel(self); |
| retval = S_cfcbase_to_perlref(parcel); |
| } |
| break; |
| case 6: |
| retval = newSViv(CFCType_get_indirection(self)); |
| break; |
| case 7: |
| CFCType_set_c_string(self, SvPV_nolen(ST(1))); |
| case 8: { |
| const char *c_string = CFCType_to_c(self); |
| retval = newSVpvn(c_string, strlen(c_string)); |
| } |
| break; |
| case 10: |
| retval = newSViv(CFCType_const(self)); |
| break; |
| case 11: |
| CFCType_set_nullable(self, !!SvTRUE(ST(1))); |
| break; |
| case 12: |
| retval = newSViv(CFCType_nullable(self)); |
| break; |
| case 14: |
| retval = newSViv(CFCType_is_void(self)); |
| break; |
| case 16: |
| retval = newSViv(CFCType_is_object(self)); |
| break; |
| case 18: |
| retval = newSViv(CFCType_is_primitive(self)); |
| break; |
| case 20: |
| retval = newSViv(CFCType_is_integer(self)); |
| break; |
| case 22: |
| retval = newSViv(CFCType_is_floating(self)); |
| break; |
| case 24: |
| retval = newSViv(CFCType_is_string_type(self)); |
| break; |
| case 26: |
| retval = newSViv(CFCType_is_va_list(self)); |
| break; |
| case 28: |
| retval = newSViv(CFCType_is_arbitrary(self)); |
| break; |
| case 30: |
| retval = newSViv(CFCType_is_composite(self)); |
| break; |
| case 32: |
| retval = newSVuv(CFCType_get_width(self)); |
| break; |
| case 34: |
| retval = newSVuv(CFCType_incremented(self)); |
| break; |
| case 36: |
| retval = newSVuv(CFCType_decremented(self)); |
| break; |
| case 38: { |
| const char *array = CFCType_get_array(self); |
| retval = array |
| ? newSVpvn(array, strlen(array)) |
| : newSV(0); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Util |
| |
| SV* |
| trim_whitespace(text) |
| SV *text; |
| CODE: |
| RETVAL = newSVsv(text); |
| STRLEN len; |
| char *ptr = SvPV(RETVAL, len); |
| CFCUtil_trim_whitespace(ptr); |
| SvCUR_set(RETVAL, strlen(ptr)); |
| OUTPUT: RETVAL |
| |
| SV* |
| slurp_text(path) |
| const char *path; |
| CODE: |
| size_t len; |
| char *contents = CFCUtil_slurp_text(path, &len); |
| RETVAL = newSVpvn(contents, len); |
| FREEMEM(contents); |
| OUTPUT: RETVAL |
| |
| int |
| current(orig, dest) |
| const char *orig; |
| const char *dest; |
| CODE: |
| RETVAL = CFCUtil_current(orig, dest); |
| OUTPUT: RETVAL |
| |
| void |
| write_if_changed(path, content_sv) |
| const char *path; |
| SV *content_sv; |
| PPCODE: |
| STRLEN len; |
| char *content = SvPV(content_sv, len); |
| CFCUtil_write_if_changed(path, content, len); |
| |
| |
| MODULE = Clownfish PACKAGE = Clownfish::Variable |
| |
| SV* |
| _new(klass, parcel, exposure, class_name_sv, class_cnick_sv, micro_sym_sv, type_sv) |
| const char *klass; |
| CFCParcel *parcel; |
| const char *exposure; |
| SV *class_name_sv; |
| SV *class_cnick_sv; |
| SV *micro_sym_sv; |
| SV *type_sv; |
| CODE: |
| const char *class_name = SvOK(class_name_sv) |
| ? SvPV_nolen(class_name_sv) |
| : NULL; |
| const char *class_cnick = SvOK(class_cnick_sv) |
| ? SvPV_nolen(class_cnick_sv) |
| : NULL; |
| const char *micro_sym = SvOK(micro_sym_sv) |
| ? SvPV_nolen(micro_sym_sv) |
| : NULL; |
| CFCType *type = NULL; |
| if (SvOK(type_sv) && sv_derived_from(type_sv, "Clownfish::Type")) { |
| IV objint = SvIV((SV*)SvRV(type_sv)); |
| type = INT2PTR(CFCType*, objint); |
| } |
| else { |
| croak("Param 'type' is not a Clownfish::Type"); |
| } |
| CFCVariable *self = CFCVariable_new(parcel, exposure, class_name, |
| class_cnick, micro_sym, type); |
| RETVAL = S_cfcbase_to_perlref(self); |
| CFCBase_decref((CFCBase*)self); |
| OUTPUT: RETVAL |
| |
| void |
| DESTROY(self) |
| CFCVariable *self; |
| PPCODE: |
| CFCVariable_destroy(self); |
| |
| int |
| equals(self, other) |
| CFCVariable *self; |
| CFCVariable *other; |
| CODE: |
| RETVAL = CFCVariable_equals(self, other); |
| OUTPUT: RETVAL |
| |
| void |
| _set_or_get(self, ...) |
| CFCVariable *self; |
| ALIAS: |
| get_type = 2 |
| local_c = 4 |
| global_c = 6 |
| local_declaration = 8 |
| PPCODE: |
| { |
| START_SET_OR_GET_SWITCH |
| case 2: { |
| CFCType *type = CFCVariable_get_type(self); |
| retval = S_cfcbase_to_perlref(type); |
| } |
| break; |
| case 4: { |
| const char *local_c = CFCVariable_local_c(self); |
| retval = newSVpvn(local_c, strlen(local_c)); |
| } |
| break; |
| case 6: { |
| const char *global_c = CFCVariable_global_c(self); |
| retval = newSVpvn(global_c, strlen(global_c)); |
| } |
| break; |
| case 8: { |
| const char *local_dec = CFCVariable_local_declaration(self); |
| retval = newSVpvn(local_dec, strlen(local_dec)); |
| } |
| break; |
| END_SET_OR_GET_SWITCH |
| } |
| |