+static int
+intuit_method(start,gv)
+char *start;
+GV *gv;
+{
+ char *s = start + (*start == '$');
+ char tmpbuf[sizeof tokenbuf];
+ STRLEN len;
+ GV* indirgv;
+
+ if (gv) {
+ if (GvIO(gv))
+ return 0;
+ if (!GvCVu(gv))
+ gv = 0;
+ }
+ s = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
+ if (*start == '$') {
+ if (gv || last_lop_op == OP_PRINT || isUPPER(*tokenbuf))
+ return 0;
+ s = skipspace(s);
+ bufptr = start;
+ expect = XREF;
+ return *s == '(' ? FUNCMETH : METHOD;
+ }
+ if (!keyword(tmpbuf, len)) {
+ indirgv = gv_fetchpv(tmpbuf,FALSE, SVt_PVCV);
+ if (indirgv && GvCVu(indirgv))
+ return 0;
+ /* filehandle or package name makes it a method */
+ if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, FALSE)) {
+ s = skipspace(s);
+ if ((bufend - s) >= 2 && *s == '=' && *(s+1) == '>')
+ return 0; /* no assumptions -- "=>" quotes bearword */
+ nextval[nexttoke].opval =
+ (OP*)newSVOP(OP_CONST, 0,
+ newSVpv(tmpbuf,0));
+ nextval[nexttoke].opval->op_private =
+ OPpCONST_BARE;
+ expect = XTERM;
+ force_next(WORD);
+ bufptr = s;
+ return *s == '(' ? FUNCMETH : METHOD;
+ }
+ }
+ return 0;
+}
+
+static char*
+incl_perldb()
+{
+ if (perldb) {
+ char *pdb = getenv("PERL5DB");
+
+ if (pdb)
+ return pdb;
+ return "BEGIN { require 'perl5db.pl' }";
+ }
+ return "";
+}
+
+
+/* Encoded script support. filter_add() effectively inserts a
+ * 'pre-processing' function into the current source input stream.
+ * Note that the filter function only applies to the current source file
+ * (e.g., it will not affect files 'require'd or 'use'd by this one).
+ *
+ * The datasv parameter (which may be NULL) can be used to pass
+ * private data to this instance of the filter. The filter function
+ * can recover the SV using the FILTER_DATA macro and use it to
+ * store private buffers and state information.
+ *
+ * The supplied datasv parameter is upgraded to a PVIO type
+ * and the IoDIRP field is used to store the function pointer.
+ * Note that IoTOP_NAME, IoFMT_NAME, IoBOTTOM_NAME, if set for
+ * private use must be set using malloc'd pointers.
+ */
+static int filter_debug = 0;
+
+SV *
+filter_add(funcp, datasv)
+ filter_t funcp;
+ SV *datasv;
+{
+ if (!funcp){ /* temporary handy debugging hack to be deleted */
+ filter_debug = atoi((char*)datasv);
+ return NULL;
+ }
+ if (!rsfp_filters)
+ rsfp_filters = newAV();
+ if (!datasv)
+ datasv = newSV(0);
+ if (!SvUPGRADE(datasv, SVt_PVIO))
+ die("Can't upgrade filter_add data to SVt_PVIO");
+ IoDIRP(datasv) = (DIR*)funcp; /* stash funcp into spare field */
+ if (filter_debug)
+ warn("filter_add func %p (%s)", funcp, SvPV(datasv,na));
+ av_unshift(rsfp_filters, 1);
+ av_store(rsfp_filters, 0, datasv) ;
+ return(datasv);
+}
+
+
+/* Delete most recently added instance of this filter function. */
+void
+filter_del(funcp)
+ filter_t funcp;
+{
+ if (filter_debug)
+ warn("filter_del func %p", funcp);
+ if (!rsfp_filters || AvFILL(rsfp_filters)<0)
+ return;
+ /* if filter is on top of stack (usual case) just pop it off */
+ if (IoDIRP(FILTER_DATA(0)) == (void*)funcp){
+ /* sv_free(av_pop(rsfp_filters)); */
+ sv_free(av_shift(rsfp_filters));
+
+ return;
+ }
+ /* we need to search for the correct entry and clear it */
+ die("filter_del can only delete in reverse order (currently)");
+}