Bumping version to 0.006022
[p5sagit/Devel-Declare.git] / Declare.xs
CommitLineData
cceec84c 1#define PERL_NO_GET_CONTEXT 1
94caac6e 2#include "EXTERN.h"
3#include "perl.h"
4#include "XSUB.h"
b15aa864 5#include "hook_op_check.h"
94caac6e 6#undef printf
e807ee50 7#include "stolen_chunk_of_toke.c"
94caac6e 8#include <stdio.h>
9#include <string.h>
10
023db2fb 11#define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
12#define PERL_DECIMAL_VERSION \
13 PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
14#define PERL_VERSION_GE(r,v,s) \
15 (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
16
9673d7ca 17#ifndef Newx
18# define Newx(v,n,t) New(0,v,n,t)
19#endif /* !Newx */
20
7dd7d008 21#define DD_DEBUGf_UPDATED_LINESTR 1
22#define DD_DEBUGf_TRACE 2
23
24#define DD_DEBUG_UPDATED_LINESTR (dd_debug & DD_DEBUGf_UPDATED_LINESTR)
25#define DD_DEBUG_TRACE (dd_debug & DD_DEBUGf_TRACE)
e81bee92 26static int dd_debug = 0;
c630715a 27
023db2fb 28#define DD_CONST_VIA_RV2CV PERL_VERSION_GE(5,11,2)
29
6ed8c948 30#define DD_GROW_VIA_BLOCKHOOK PERL_VERSION_GE(5,13,3)
31
94caac6e 32#define LEX_NORMAL 10
33#define LEX_INTERPNORMAL 9
34
e8df925b 35/* please try not to have a line longer than this :) */
36
37#define DD_PREFERRED_LINESTR_SIZE 16384
38
94caac6e 39/* flag to trigger removal of temporary declaree sub */
40
41static int in_declare = 0;
42
96f12726 43/* in 5.10, PL_parser will be NULL if we aren't parsing, and PL_lex_stuff
44 is a lookup into it - so if anything else we can use to tell, so we
45 need to be a bit more careful if PL_parser exists */
46
47#define DD_AM_LEXING_CHECK (PL_lex_state == LEX_NORMAL || PL_lex_state == LEX_INTERPNORMAL)
48
f19b3507 49#if defined(PL_parser) || defined(PERL_5_9_PLUS)
96f12726 50#define DD_HAVE_PARSER PL_parser
51#define DD_HAVE_LEX_STUFF (PL_parser && PL_lex_stuff)
52#define DD_AM_LEXING (PL_parser && DD_AM_LEXING_CHECK)
53#else
54#define DD_HAVE_PARSER 1
55#define DD_HAVE_LEX_STUFF PL_lex_stuff
56#define DD_AM_LEXING DD_AM_LEXING_CHECK
57#endif
58
72f20f69 59/* thing that decides whether we're dealing with a declarator */
60
61int dd_is_declarator(pTHX_ char* name) {
62 HV* is_declarator;
63 SV** is_declarator_pack_ref;
64 HV* is_declarator_pack_hash;
65 SV** is_declarator_flag_ref;
66 int dd_flags;
ec25cea7 67 char* curstash_name;
72f20f69 68
69 is_declarator = get_hv("Devel::Declare::declarators", FALSE);
70
71 if (!is_declarator)
72 return -1;
73
569ac469 74 /* $declarators{$current_package_name} */
75
ec25cea7 76 curstash_name = HvNAME(PL_curstash);
77 if (!curstash_name)
f2a41aa1 78 return -1;
9603b8dc 79
ec25cea7 80 is_declarator_pack_ref = hv_fetch(is_declarator, curstash_name,
81 strlen(curstash_name), FALSE);
72f20f69 82
83 if (!is_declarator_pack_ref || !SvROK(*is_declarator_pack_ref))
84 return -1; /* not a hashref */
85
86 is_declarator_pack_hash = (HV*) SvRV(*is_declarator_pack_ref);
87
569ac469 88 /* $declarators{$current_package_name}{$name} */
89
72f20f69 90 is_declarator_flag_ref = hv_fetch(
91 is_declarator_pack_hash, name,
92 strlen(name), FALSE
93 );
94
95 /* requires SvIOK as well as TRUE since flags not being an int is useless */
96
97 if (!is_declarator_flag_ref
48ee5c99 98 || !SvIOK(*is_declarator_flag_ref)
72f20f69 99 || !SvTRUE(*is_declarator_flag_ref))
100 return -1;
101
102 dd_flags = SvIVX(*is_declarator_flag_ref);
103
104 return dd_flags;
105}
106
569ac469 107/* callback thingy */
108
a9bd9b5e 109void dd_linestr_callback (pTHX_ char* type, char* name) {
569ac469 110
111 char* linestr = SvPVX(PL_linestr);
a9bd9b5e 112 int offset = PL_bufptr - linestr;
569ac469 113
569ac469 114 dSP;
115
116 ENTER;
117 SAVETMPS;
118
119 PUSHMARK(SP);
120 XPUSHs(sv_2mortal(newSVpv(type, 0)));
121 XPUSHs(sv_2mortal(newSVpv(name, 0)));
122 XPUSHs(sv_2mortal(newSViv(offset)));
123 PUTBACK;
124
04a8a223 125 call_pv("Devel::Declare::linestr_callback", G_VOID|G_DISCARD);
569ac469 126
569ac469 127 FREETMPS;
128 LEAVE;
129}
130
131char* dd_get_linestr(pTHX) {
5f0b59d5 132 if (!DD_HAVE_PARSER) {
133 return NULL;
134 }
569ac469 135 return SvPVX(PL_linestr);
136}
137
138void dd_set_linestr(pTHX_ char* new_value) {
6f5220b7 139 unsigned int new_len = strlen(new_value);
569ac469 140
ce9a252b 141 if (SvLEN(PL_linestr) < new_len) {
41db92e3 142 croak("PL_linestr not long enough, was Devel::Declare loaded soon enough in %s",
143 CopFILE(&PL_compiling)
144 );
ce9a252b 145 }
146
569ac469 147
148 memcpy(SvPVX(PL_linestr), new_value, new_len+1);
149
150 SvCUR_set(PL_linestr, new_len);
151
152 PL_bufend = SvPVX(PL_linestr) + new_len;
7dd7d008 153
87195072 154 if ( DD_DEBUG_UPDATED_LINESTR && PERLDB_LINE && PL_curstash != PL_debstash) {
ec25cea7 155 /* Cribbed from toke.c */
156 AV *fileav = CopFILEAV(&PL_compiling);
157 if (fileav) {
158 SV * const sv = NEWSV(85,0);
159
160 sv_upgrade(sv, SVt_PVMG);
161 sv_setpvn(sv,PL_bufptr,PL_bufend-PL_bufptr);
162 (void)SvIOK_on(sv);
163 SvIV_set(sv, 0);
164 av_store(fileav,(I32)CopLINE(&PL_compiling),sv);
165 }
7dd7d008 166 }
569ac469 167}
168
04a8a223 169char* dd_get_lex_stuff(pTHX) {
96f12726 170 return (DD_HAVE_LEX_STUFF ? SvPVX(PL_lex_stuff) : "");
04a8a223 171}
172
bd85a06e 173void dd_clear_lex_stuff(pTHX) {
96f12726 174 if (DD_HAVE_PARSER)
f05cbc90 175 PL_lex_stuff = (SV*)NULL;
04a8a223 176}
177
178char* dd_get_curstash_name(pTHX) {
179 return HvNAME(PL_curstash);
180}
181
022eb0cc 182int dd_get_linestr_offset(pTHX) {
0da63271 183 char* linestr;
184 if (!DD_HAVE_PARSER) {
185 return -1;
186 }
187 linestr = SvPVX(PL_linestr);
022eb0cc 188 return PL_bufptr - linestr;
189}
190
840ebcbb 191char* dd_move_past_token (pTHX_ char* s) {
923c07a8 192
193 /*
194 * buffer will be at the beginning of the declarator, -unless- the
195 * declarator is at EOL in which case it'll be the next useful line
196 * so we don't short-circuit out if we don't find the declarator
197 */
198
199 while (s < PL_bufend && isSPACE(*s)) s++;
200 if (memEQ(s, PL_tokenbuf, strlen(PL_tokenbuf)))
201 s += strlen(PL_tokenbuf);
202 return s;
203}
204
840ebcbb 205int dd_toke_move_past_token (pTHX_ int offset) {
04a8a223 206 char* base_s = SvPVX(PL_linestr) + offset;
207 char* s = dd_move_past_token(aTHX_ base_s);
208 return s - base_s;
209}
210
923c07a8 211int dd_toke_scan_word(pTHX_ int offset, int handle_package) {
212 char tmpbuf[sizeof PL_tokenbuf];
213 char* base_s = SvPVX(PL_linestr) + offset;
214 STRLEN len;
215 char* s = scan_word(base_s, tmpbuf, sizeof tmpbuf, handle_package, &len);
216 return s - base_s;
217}
218
f11d21b2 219int dd_toke_scan_ident(pTHX_ int offset) {
220 char tmpbuf[sizeof PL_tokenbuf];
221 char* base_s = SvPVX(PL_linestr) + offset;
f11d21b2 222 char* s = scan_ident(base_s, PL_bufend, tmpbuf, sizeof tmpbuf, 0);
223 return s - base_s;
224}
225
923c07a8 226int dd_toke_scan_str(pTHX_ int offset) {
d3480bb4 227 char* old_pvx = SvPVX(PL_linestr);
08c39634 228 SV* line_copy = sv_2mortal(newSVsv(PL_linestr));
923c07a8 229 char* base_s = SvPVX(PL_linestr) + offset;
230 char* s = scan_str(base_s, FALSE, FALSE);
d3480bb4 231 if(SvPVX(PL_linestr) != old_pvx)
232 croak("PL_linestr reallocated during scan_str, "
233 "Devel::Declare can't continue");
8449c31f 234 if (!s)
235 return 0;
361de2b5 236 if (s <= base_s || memcmp(SvPVX(line_copy), SvPVX(PL_linestr), offset)) {
78bb475d 237 s += SvCUR(line_copy);
86964fb3 238 sv_catsv(line_copy, PL_linestr);
239 dd_set_linestr(aTHX_ SvPV_nolen(line_copy));
86964fb3 240 }
923c07a8 241 return s - base_s;
242}
243
244int dd_toke_skipspace(pTHX_ int offset) {
e8df925b 245 char* old_pvx = SvPVX(PL_linestr);
923c07a8 246 char* base_s = SvPVX(PL_linestr) + offset;
a25db2dc 247 char* s = skipspace_force(base_s);
e8df925b 248 if(SvPVX(PL_linestr) != old_pvx)
249 croak("PL_linestr reallocated during skipspace, "
250 "Devel::Declare can't continue");
923c07a8 251 return s - base_s;
252}
253
023db2fb 254static void call_done_declare(pTHX) {
255 dSP;
256
257 if (DD_DEBUG_TRACE) {
258 printf("Deconstructing declare\n");
259 printf("PL_bufptr: %s\n", PL_bufptr);
d44b3df5 260 printf("bufend at: %i\n", (int)(PL_bufend - PL_bufptr));
023db2fb 261 printf("linestr: %s\n", SvPVX(PL_linestr));
d44b3df5 262 printf("linestr len: %i\n", (int)(PL_bufend - SvPVX(PL_linestr)));
023db2fb 263 }
264
265 ENTER;
266 SAVETMPS;
267
268 PUSHMARK(SP);
269
270 call_pv("Devel::Declare::done_declare", G_VOID|G_DISCARD);
271
272 FREETMPS;
273 LEAVE;
274
275 if (DD_DEBUG_TRACE) {
276 printf("PL_bufptr: %s\n", PL_bufptr);
d44b3df5 277 printf("bufend at: %i\n", (int)(PL_bufend - PL_bufptr));
023db2fb 278 printf("linestr: %s\n", SvPVX(PL_linestr));
d44b3df5 279 printf("linestr len: %i\n", (int)(PL_bufend - SvPVX(PL_linestr)));
280 printf("actual len: %i\n", (int)strlen(PL_bufptr));
023db2fb 281 }
282}
283
284static int dd_handle_const(pTHX_ char *name);
285
e8e7407a 286#ifdef CV_NAME_NOTQUAL /* 5.21.5 */
287# define Gv_or_CvNAME(g) (isGV(g) \
288 ? GvNAME(g) \
289 : SvPV_nolen(cv_name((CV *)SvRV(g), NULL, CV_NAME_NOTQUAL)))
290#elif defined(CvNAMED) /* 5.21.4 */
291# define Gv_or_CvNAME(g) (isGV(g) \
292 ? GvNAME(g) \
293 : CvNAMED(SvRV(g)) \
294 ? HEK_KEY(CvNAME_HEK((CV *)SvRV(g))) \
295 : GvNAME(CvGV(SvRV(g))))
296#else
297# define Gv_or_CvNAME(g) GvNAME(g)
298#endif
299
94caac6e 300/* replacement PL_check rv2cv entry */
301
6e67754a 302STATIC OP *dd_ck_rv2cv(pTHX_ OP *o, void *user_data) {
94caac6e 303 OP* kid;
0ba8c7aa 304 int dd_flags;
e8e7407a 305 char *gvname;
94caac6e 306
6f5220b7 307 PERL_UNUSED_VAR(user_data);
308
499109e0 309 if (!DD_AM_LEXING)
310 return o; /* not lexing? */
311
94caac6e 312 if (in_declare) {
023db2fb 313 call_done_declare(aTHX);
94caac6e 314 return o;
315 }
316
317 kid = cUNOPo->op_first;
318
319 if (kid->op_type != OP_GV) /* not a GV so ignore */
320 return o;
321
e8e7407a 322 if (!isGV(kGVOP_gv)
323 && (!SvROK(kGVOP_gv) || SvTYPE(SvRV(kGVOP_gv)) != SVt_PVCV))
324 return o;
325
326 gvname = Gv_or_CvNAME(kGVOP_gv);
327
7dd7d008 328 if (DD_DEBUG_TRACE) {
e8e7407a 329 printf("Checking GV %s -> %s\n", HvNAME(GvSTASH(kGVOP_gv)), gvname);
e81bee92 330 }
840ebcbb 331
e8e7407a 332 dd_flags = dd_is_declarator(aTHX_ gvname);
94caac6e 333
72f20f69 334 if (dd_flags == -1)
94caac6e 335 return o;
336
7dd7d008 337 if (DD_DEBUG_TRACE) {
e81bee92 338 printf("dd_flags are: %i\n", dd_flags);
339 printf("PL_tokenbuf: %s\n", PL_tokenbuf);
340 }
840ebcbb 341
023db2fb 342#if DD_CONST_VIA_RV2CV
343 if (PL_expect != XOPERATOR) {
e8e7407a 344 if (!dd_handle_const(aTHX_ Gv_or_CvNAME(kGVOP_gv)))
023db2fb 345 return o;
346 CopLINE(PL_curcop) = PL_copline;
347 /* The parser behaviour that we're simulating depends on what comes
348 after the declarator. */
e8e7407a 349 if (*skipspace(PL_bufptr + strlen(gvname)) != '(') {
023db2fb 350 if (in_declare) {
351 call_done_declare(aTHX);
352 } else {
e8e7407a 353 dd_linestr_callback(aTHX_ "rv2cv", gvname);
023db2fb 354 }
355 }
356 return o;
357 }
358#endif /* DD_CONST_VIA_RV2CV */
359
e8e7407a 360 dd_linestr_callback(aTHX_ "rv2cv", gvname);
94caac6e 361
53e3ab32 362 return o;
363}
364
6ed8c948 365#if DD_GROW_VIA_BLOCKHOOK
366
367static void dd_block_start(pTHX_ int full)
368{
369 PERL_UNUSED_VAR(full);
e8df925b 370 if (SvLEN(PL_linestr) < DD_PREFERRED_LINESTR_SIZE)
371 (void) lex_grow_linestr(DD_PREFERRED_LINESTR_SIZE);
6ed8c948 372}
373
374#else /* !DD_GROW_VIA_BLOCKHOOK */
375
b7505981 376OP* dd_pp_entereval(pTHX) {
377 dSP;
b7505981 378 STRLEN len;
379 const char* s;
c93bc23e 380 SV *sv;
381#ifdef PERL_5_9_PLUS
ec25cea7 382 SV *saved_hh = NULL;
c93bc23e 383 if (PL_op->op_private & OPpEVAL_HAS_HH) {
384 saved_hh = POPs;
385 }
386#endif
387 sv = POPs;
b7505981 388 if (SvPOK(sv)) {
7dd7d008 389 if (DD_DEBUG_TRACE) {
e81bee92 390 printf("mangling eval sv\n");
391 }
b7505981 392 if (SvREADONLY(sv))
393 sv = sv_2mortal(newSVsv(sv));
394 s = SvPVX(sv);
395 len = SvCUR(sv);
396 if (!len || s[len-1] != ';') {
397 if (!(SvFLAGS(sv) & SVs_TEMP))
398 sv = sv_2mortal(newSVsv(sv));
399 sv_catpvn(sv, "\n;", 2);
53e3ab32 400 }
e8df925b 401 SvGROW(sv, DD_PREFERRED_LINESTR_SIZE);
53e3ab32 402 }
b7505981 403 PUSHs(sv);
c93bc23e 404#ifdef PERL_5_9_PLUS
405 if (PL_op->op_private & OPpEVAL_HAS_HH) {
406 PUSHs(saved_hh);
407 }
408#endif
b7505981 409 return PL_ppaddr[OP_ENTEREVAL](aTHX);
410}
53e3ab32 411
6e67754a 412STATIC OP *dd_ck_entereval(pTHX_ OP *o, void *user_data) {
6f5220b7 413 PERL_UNUSED_VAR(user_data);
414
d8e65fc8 415 if (o->op_ppaddr == PL_ppaddr[OP_ENTEREVAL])
416 o->op_ppaddr = dd_pp_entereval;
94caac6e 417 return o;
418}
419
12b60feb 420#endif /* !DD_GROW_VIA_BLOCKHOOK */
421
6a0bcf35 422static I32 dd_filter_realloc(pTHX_ int idx, SV *sv, int maxlen)
423{
4e9e26b6 424 SV *filter_datasv;
6a0bcf35 425 const I32 count = FILTER_READ(idx+1, sv, maxlen);
e8df925b 426 SvGROW(sv, DD_PREFERRED_LINESTR_SIZE);
4e9e26b6 427 /* Filters can only be deleted in the correct order (reverse of the
428 order in which they were added). Insisting on deleting the filter
429 here would break if another filter were added after ours and is
430 still around. Not deleting the filter at all would break if another
431 filter were added earlier and attempts to delete itself later.
432 We can play nicely to the maximum possible extent by deleting our
433 filter iff it is currently deletable (i.e., it is on the top of
434 the filter stack). Can still run into trouble in more complex
435 situations, but can't avoid that. */
436 if (PL_rsfp_filters && AvFILLp(PL_rsfp_filters) >= 0 &&
437 (filter_datasv = FILTER_DATA(AvFILLp(PL_rsfp_filters))) &&
438 IoANY(filter_datasv) == FPTR2DPTR(void *, dd_filter_realloc)) {
439 filter_del(dd_filter_realloc);
440 }
6a0bcf35 441 return count;
442}
443
023db2fb 444static int dd_handle_const(pTHX_ char *name) {
c48ac26f 445 switch (PL_lex_inwhat) {
446 case OP_QR:
447 case OP_MATCH:
448 case OP_SUBST:
449 case OP_TRANS:
f2a41aa1 450 case OP_BACKTICK:
451 case OP_STRINGIFY:
023db2fb 452 return 0;
c48ac26f 453 break;
454 default:
455 break;
8d96afb7 456 }
48ee5c99 457
a25db2dc 458 if (strnEQ(PL_bufptr, "->", 2)) {
023db2fb 459 return 0;
954da332 460 }
461
a25db2dc 462 {
463 char buf[256];
464 STRLEN len;
465 char *s = PL_bufptr;
466 STRLEN old_offset = PL_bufptr - SvPVX(PL_linestr);
467
468 s = scan_word(s, buf, sizeof buf, FALSE, &len);
469 if (strnEQ(buf, name, len)) {
470 char *d;
c0439e97 471 SV *inject = newSVpvn(SvPVX(PL_linestr), PL_bufptr - SvPVX(PL_linestr));
a25db2dc 472 sv_catpvn(inject, buf, len);
473
474 d = peekspace(s);
475 sv_catpvn(inject, s, d - s);
476
477 if ((PL_bufend - d) >= 2 && strnEQ(d, "=>", 2)) {
023db2fb 478 return 0;
a25db2dc 479 }
480
481 sv_catpv(inject, d);
482 dd_set_linestr(aTHX_ SvPV_nolen(inject));
483 PL_bufptr = SvPVX(PL_linestr) + old_offset;
484 SvREFCNT_dec (inject);
485 }
486 }
487
a9bd9b5e 488 dd_linestr_callback(aTHX_ "const", name);
bedac9ff 489
023db2fb 490 return 1;
491}
492
493#if !DD_CONST_VIA_RV2CV
494
495STATIC OP *dd_ck_const(pTHX_ OP *o, void *user_data) {
496 int dd_flags;
497 char* name;
498
499 PERL_UNUSED_VAR(user_data);
500
501 if (DD_HAVE_PARSER && PL_expect == XOPERATOR) {
502 return o;
503 }
504
505 /* if this is set, we just grabbed a delimited string or something,
506 not a bareword, so NO TOUCHY */
507
508 if (DD_HAVE_LEX_STUFF)
509 return o;
510
511 /* don't try and look this up if it's not a string const */
512 if (!SvPOK(cSVOPo->op_sv))
513 return o;
514
515 name = SvPVX(cSVOPo->op_sv);
516
517 dd_flags = dd_is_declarator(aTHX_ name);
518
519 if (dd_flags == -1)
520 return o;
521
522 dd_handle_const(aTHX_ name);
523
3ea50944 524 return o;
525}
526
023db2fb 527#endif /* !DD_CONST_VIA_RV2CV */
528
8ec78a85 529STATIC void dd_initialize(pTHX) {
530 static int initialized = 0;
531 if (!initialized) {
532 initialized = 1;
6ed8c948 533#if DD_GROW_VIA_BLOCKHOOK
a36413c5 534 {
535 static BHK bhk;
6ed8c948 536#if PERL_VERSION_GE(5,13,6)
a36413c5 537 BhkENTRY_set(&bhk, bhk_start, dd_block_start);
6ed8c948 538#else /* <5.13.6 */
a36413c5 539 BhkENTRY_set(&bhk, start, dd_block_start);
6ed8c948 540#endif /* <5.13.6 */
a36413c5 541 Perl_blockhook_register(aTHX_ &bhk);
542 }
6ed8c948 543#else /* !DD_GROW_VIA_BLOCKHOOK */
6e67754a 544 hook_op_check(OP_ENTEREVAL, dd_ck_entereval, NULL);
6ed8c948 545#endif /* !DD_GROW_VIA_BLOCKHOOK */
546 hook_op_check(OP_RV2CV, dd_ck_rv2cv, NULL);
023db2fb 547#if !DD_CONST_VIA_RV2CV
6e67754a 548 hook_op_check(OP_CONST, dd_ck_const, NULL);
023db2fb 549#endif /* !DD_CONST_VIA_RV2CV */
94caac6e 550 }
8ec78a85 551}
552
553MODULE = Devel::Declare PACKAGE = Devel::Declare
554
555PROTOTYPES: DISABLE
556
557void
558initialize()
559 CODE:
560 dd_initialize(aTHX);
561
562void
563setup()
564 CODE:
565 dd_initialize(aTHX);
566 filter_add(dd_filter_realloc, NULL);
569ac469 567
568char*
569get_linestr()
570 CODE:
571 RETVAL = dd_get_linestr(aTHX);
572 OUTPUT:
573 RETVAL
923c07a8 574
575void
576set_linestr(char* new_value)
577 CODE:
578 dd_set_linestr(aTHX_ new_value);
579
04a8a223 580char*
581get_lex_stuff()
582 CODE:
583 RETVAL = dd_get_lex_stuff(aTHX);
584 OUTPUT:
585 RETVAL
586
587void
588clear_lex_stuff()
589 CODE:
590 dd_clear_lex_stuff(aTHX);
591
592char*
593get_curstash_name()
594 CODE:
595 RETVAL = dd_get_curstash_name(aTHX);
596 OUTPUT:
597 RETVAL
598
923c07a8 599int
022eb0cc 600get_linestr_offset()
601 CODE:
602 RETVAL = dd_get_linestr_offset(aTHX);
603 OUTPUT:
604 RETVAL
605
606int
923c07a8 607toke_scan_word(int offset, int handle_package)
608 CODE:
609 RETVAL = dd_toke_scan_word(aTHX_ offset, handle_package);
610 OUTPUT:
611 RETVAL
612
613int
04a8a223 614toke_move_past_token(int offset);
615 CODE:
616 RETVAL = dd_toke_move_past_token(aTHX_ offset);
617 OUTPUT:
618 RETVAL
619
8449c31f 620SV*
923c07a8 621toke_scan_str(int offset);
8449c31f 622 PREINIT:
623 int len;
923c07a8 624 CODE:
8449c31f 625 len = dd_toke_scan_str(aTHX_ offset);
626 RETVAL = len ? newSViv(len) : &PL_sv_undef;
923c07a8 627 OUTPUT:
628 RETVAL
629
630int
f11d21b2 631toke_scan_ident(int offset)
632 CODE:
633 RETVAL = dd_toke_scan_ident(aTHX_ offset);
634 OUTPUT:
635 RETVAL
636
637int
923c07a8 638toke_skipspace(int offset)
639 CODE:
640 RETVAL = dd_toke_skipspace(aTHX_ offset);
641 OUTPUT:
642 RETVAL
04a8a223 643
644int
645get_in_declare()
646 CODE:
647 RETVAL = in_declare;
648 OUTPUT:
649 RETVAL
650
651void
652set_in_declare(int value)
653 CODE:
654 in_declare = value;
e81bee92 655
656BOOT:
0a3b37d1 657{
87195072 658 char *endptr;
659 char *debug_str = getenv ("DD_DEBUG");
660 if (debug_str) {
661 dd_debug = strtol (debug_str, &endptr, 10);
662 if (*endptr != '\0') {
663 dd_debug = 0;
664 }
e81bee92 665 }
0a3b37d1 666}