static void check_uni _((void));
static void force_next _((I32 type));
+static char *force_version _((char *start));
static char *force_word _((char *start, int token, int check_keyword, int allow_pack, int allow_tick));
static SV *q _((SV *sv));
static char *scan_const _((char *start));
#endif
static char * filter_gets _((SV *sv, FILE *fp));
static void restore_rsfp _((void *f));
+static SV * sub_const _((CV *cv));
/* The following are arranged oddly so that the guard on the switch statement
* can get by with a single comparison (if the compiler is smart enough).
}
}
+static char *
+force_version(s)
+char *s;
+{
+ OP *version = Nullop;
+
+ s = skipspace(s);
+
+ /* default VERSION number -- GBARR */
+
+ if(isDIGIT(*s)) {
+ char *d;
+ int c;
+ for( d=s, c = 1; isDIGIT(*d) || (*d == '.' && c--); d++);
+ if((*d == ';' || isSPACE(*d)) && *(skipspace(d)) != ',') {
+ s = scan_num(s);
+ /* real VERSION number -- GBARR */
+ version = yylval.opval;
+ }
+ }
+
+ /* NOTE: The parser sees the package name and the VERSION swapped */
+ nextval[nexttoke].opval = version;
+ force_next(WORD);
+
+ return (s);
+}
+
static SV *
q(sv)
SV *sv;
if (indirgv && GvCV(indirgv))
return 0;
/* filehandle or package name makes it a method */
- if (!gv || GvIO(indirgv) || gv_stashpv(tmpbuf, FALSE)) {
+ if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, FALSE)) {
s = skipspace(s);
nextval[nexttoke].opval =
(OP*)newSVOP(OP_CONST, 0,
return ')';
}
if (lex_casemods > 10) {
- char* newlb = (char*)realloc(lex_casestack, lex_casemods + 2);
+ char* newlb = Renew(lex_casestack, lex_casemods + 2, char);
if (newlb != lex_casestack) {
SAVEFREEPV(newlb);
lex_casestack = newlb;
int oldp = minus_p;
while (*d && !isSPACE(*d)) d++;
- while (*d == ' ') d++;
+ while (*d == ' ' || *d == '\t') d++;
if (*d++ == '-') {
while (d = moreswitches(d)) ;
leftbracket:
s++;
if (lex_brackets > 100) {
- char* newlb = (char*)realloc(lex_brackstack, lex_brackets + 1);
+ char* newlb = Renew(lex_brackstack, lex_brackets + 1, char);
if (newlb != lex_brackstack) {
SAVEFREEPV(newlb);
lex_brackstack = newlb;
case XOPERATOR:
while (s < bufend && (*s == ' ' || *s == '\t'))
s++;
- if (s < bufend && isALPHA(*s)) {
+ if (s < bufend && (isALPHA(*s) || *s == '_')) {
d = scan_word(s, tokenbuf, FALSE, &len);
while (d < bufend && (*d == ' ' || *d == '\t'))
d++;
tokenbuf, tokenbuf);
last_lop = oldbufptr;
last_lop_op = OP_ENTERSUB;
+ /* Check for a constant sub */
+ if (SvPOK(cv) && !SvCUR(cv)) {
+ SV *sv = sub_const(cv);
+ if (sv) {
+ SvREFCNT_dec(((SVOP*)yylval.opval)->op_sv);
+ ((SVOP*)yylval.opval)->op_sv = SvREFCNT_inc(sv);
+ yylval.opval->op_private = 0;
+ TOKEN(WORD);
+ }
+ }
+
/* Resolve to GV now. */
op_free(yylval.opval);
yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv));
if (expect != XSTATE)
yyerror("\"no\" not allowed in expression");
s = force_word(s,WORD,FALSE,TRUE,FALSE);
+ s = force_version(s);
yylval.ival = 0;
OPERATOR(USE);
*tokenbuf = '\0';
s = force_word(s,WORD,TRUE,TRUE,FALSE);
if (isIDFIRST(*tokenbuf))
- gv_stashpv(tokenbuf, TRUE);
+ gv_stashpvn(tokenbuf, strlen(tokenbuf), TRUE);
else if (*s == '<')
yyerror("<> should be quotes");
UNI(OP_REQUIRE);
case KEY_use:
if (expect != XSTATE)
yyerror("\"use\" not allowed in expression");
- s = force_word(s,WORD,FALSE,TRUE,FALSE);
+ s = skipspace(s);
+ if(isDIGIT(*s)) {
+ s = force_version(s);
+ if(*s == ';' || (s = skipspace(s), *s == ';')) {
+ nextval[nexttoke].opval = Nullop;
+ force_next(WORD);
+ }
+ }
+ else {
+ s = force_word(s,WORD,FALSE,TRUE,FALSE);
+ s = force_version(s);
+ }
yylval.ival = 1;
OPERATOR(USE);
CV* outsidecv = compcv;
AV* comppadlist;
+#ifndef __QNX__
if (compcv) {
assert(SvTYPE(compcv) == SVt_PVCV);
}
+#endif
save_I32(&subline);
save_item(subname);
SAVEINT(padix);
return oldsavestack_ix;
}
+SV *
+sub_const(cv)
+CV *cv;
+{
+ OP *o;
+ SV *sv = Nullsv;
+
+ for (o = CvSTART(cv); o; o = o->op_next) {
+ OPCODE type = o->op_type;
+
+ if (type == OP_NEXTSTATE || type == OP_NULL || type == OP_PUSHMARK)
+ continue;
+ if (type == OP_LEAVESUB || type == OP_RETURN)
+ break;
+ if (type != OP_CONST || sv)
+ return Nullsv;
+ sv = ((SVOP*)o)->op_sv;
+ }
+ return sv;
+}
+
int
yywarn(s)
char *s;