source: tags/svn.1.5.4/PERL2ARB/ARB_ext.c

Last change on this file was 8312, checked in by westram, 12 years ago
  • corrected refs wrong since [7781]
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.4 KB
Line 
1/* ================================================================ */
2/*                                                                  */
3/*   File      : ARB_ext.c                                          */
4/*   Purpose   : additional code for perllib                        */
5/*                                                                  */
6/*   Institute of Microbiology (Technical University Munich)        */
7/*   http://www.arb-home.de/                                        */
8/*                                                                  */
9/* ================================================================ */
10
11
12char *static_pntr                 = 0; // see ../PERLTOOLS/arb_proto_2_xsub.cxx@static_pntr
13
14static GB_HASH *gbp_cp_hash_table = 0;
15
16// defined in ../ARBDB/adperl.c@GBP_croak_function
17extern void (*GBP_croak_function)(const char *message);
18
19void GBP_croak(const char *message) {
20    Perl_croak(aTHX_ "ARBDB croaks %s", message);
21}
22
23void GBP_callback(GBDATA *gbd, int *cl, GB_CB_TYPE cb_type) {
24    char *perl_func;
25    char *perl_cl;
26    dSP;
27    I32   i;
28    SV   *sv;
29
30    // cl contains 'func\0cl'
31    perl_func = (char *)cl;
32    perl_cl   = perl_func + strlen(perl_func) + 1;
33
34    PUSHMARK(sp);
35    sv =  sv_newmortal();
36    sv_setref_pv(sv, "GBDATAPtr", (void*)gbd);
37    XPUSHs(sv);
38    XPUSHs(sv_2mortal(newSVpv(perl_cl, 0)));
39    if (cb_type & GB_CB_DELETE) {
40        XPUSHs(sv_2mortal(newSVpv("DELETED", 0)));
41    }
42    else {
43        XPUSHs(sv_2mortal(newSVpv("CHANGED", 0)));
44    }
45
46    PUTBACK;
47    i = perl_call_pv(perl_func, G_DISCARD);
48    if (i) {
49        croak("Your perl function '%s' should not return any values", perl_func);
50    }
51    return;
52}
53
54inline char *gbp_create_callback_hashkey(GBDATA *gbd, const char *perl_func, const char *perl_cl) {
55    return GBS_global_string_copy("%p:%s%c%s", gbd, perl_func, '\1', perl_cl);
56}
57
58GB_ERROR GBP_add_callback(GBDATA *gbd, const char *perl_func, const char *perl_cl) {
59    if (!gbp_cp_hash_table) gbp_cp_hash_table = GBS_create_hash(20, GB_MIND_CASE);
60
61    char     *data  = gbp_create_callback_hashkey(gbd, perl_func, perl_cl);
62    GB_ERROR  error = 0;
63
64    if (GBS_read_hash(gbp_cp_hash_table, data)) {
65        error = GBS_global_string("Error: Callback '%s:%s' is already installed", perl_func, perl_cl);
66    }
67    else {
68        char *arg = GBS_global_string_copy("%s%c%s", perl_func, '\0', perl_cl);
69
70        GBS_write_hash(gbp_cp_hash_table, data, (long)arg);
71        error = GB_add_callback(gbd, GB_CB_TYPE(GB_CB_DELETE|GB_CB_CHANGED), GBP_callback, (int *)arg);
72
73        GBS_optimize_hash(gbp_cp_hash_table);
74    }
75    free(data);
76
77    return error;
78}
79
80GB_ERROR GBP_remove_callback(GBDATA *gbd, const char *perl_func, const char *perl_cl) {
81    GB_ERROR  error = 0;
82    char     *data  = gbp_create_callback_hashkey(gbd, perl_func, perl_cl);
83    char     *arg   = gbp_cp_hash_table ? (char *)GBS_read_hash(gbp_cp_hash_table, data) : (char*)NULL;
84
85    if (!arg) {
86        error = GBS_global_string("Error: You never installed a callback '%s:%s'", perl_func, perl_cl);
87    }
88    else {
89        GBS_write_hash(gbp_cp_hash_table, data, 0); 
90        GB_remove_callback(gbd, GB_CB_TYPE(GB_CB_DELETE|GB_CB_CHANGED), GBP_callback, (int *)arg);
91        free(arg);
92    }
93    free(data);
94
95    return error;
96}
97
98
99class ARB_init_perl_interface {
100 public:
101    ARB_init_perl_interface() {
102        GBP_croak_function = GBP_croak;
103    }
104};
105
106static ARB_init_perl_interface init; /* automatically initialize this module */
107
108
Note: See TracBrowser for help on using the repository browser.