The perl patch is there again because the old one doesn't work with
the new string patch. You have to run autoconf and use the --with-perl
switch with configure. It seems that it requires perl 5.6 or 5.6.1 to
build. This has to be sorted out yet.
diff -ruN ../epic4-1.0.1/acconfig.h ./acconfig.h
--- ../epic4-1.0.1/acconfig.h Tue Dec 5 11:11:56 2000
+++ ./acconfig.h Thu Sep 20 09:56:20 2001
@@ -192,6 +192,11 @@
#undef Rlisten
#undef Rselect
+/*
+ * Perl support.
+ * /
+#undef PERL
+
/* Define this is DIRSIZ takes no argument */
#undef DIRSIZ_TAKES_NO_ARG
diff -ruN ../epic4-1.0.1/configure.in ./configure.in
--- ../epic4-1.0.1/configure.in Tue Dec 5 11:11:56 2000
+++ ./configure.in Thu Sep 20 09:56:20 2001
@@ -366,6 +366,32 @@
)
dnl ----------------------------------------------------------
+dnl
+dnl Perl support?
+dnl
+
+AC_MSG_CHECKING(whether to support Perl)
+AC_ARG_WITH(perl,
+[ --with-perl[=PATH] Compile with perl support.],
+[ case "$withval" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ if test "x$withval" != "xyes"; then
+ LIBS="$LIBS -L$withval"
+ fi
+
+ AC_MSG_RESULT(yes)
+ LIBS="$LIBS `perl -MExtUtils::Embed -e ldopts`"
+ PERLDOTOH="perl.o"
+ AC_DEFINE(PERL)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+
+dnl ----------------------------------------------------------
dnl ----------------------------------------------------------
dnl
dnl closing stuff
@@ -381,6 +407,7 @@
if test -z "$CFLAGS"; then CFLAGS=-g -O; fi
if test -z "$LDFLAGS"; then LDFLAGS= ; fi
+if test -z "$PERLDOTOH"; then PERLDOTOH= ; fi
if test -z "$bindir"; then bindir=\${prefix}/bin; fi
if test -z "$libdir"; then libdir=\${prefix}/lib; fi
if test -z "$irclibdir"; then irclibdir=\${libdir}/irc; fi
@@ -414,6 +441,7 @@
AC_SUBST(CFLAGS)
AC_SUBST(LDFLAGS)
+AC_SUBST(PERLDOTOH)
AC_SUBST(bindir)
AC_SUBST(irclibdir)
AC_SUBST(libexecdir)
diff -ruN ../epic4-1.0.1/include/array.h ./include/array.h
--- ../epic4-1.0.1/include/array.h Tue Dec 5 11:11:57 2000
+++ ./include/array.h Thu Sep 20 09:56:20 2001
@@ -31,3 +31,9 @@
char * function_gettmatch (char *);
#endif
+
+typedef struct an_array_struct {
+ char **item;
+ long *index;
+ long size;
+} an_array;
diff -ruN ../epic4-1.0.1/include/defs.h.in ./include/defs.h.in
--- ../epic4-1.0.1/include/defs.h.in Tue Dec 5 11:11:57 2000
+++ ./include/defs.h.in Thu Sep 20 09:56:20 2001
@@ -181,6 +181,11 @@
#undef Rlisten
#undef Rselect
+/*
+ * Perl support.
+ */
+#undef PERL
+
/* Define this if you have setsid() */
#undef HAVE_SETSID
diff -ruN ../epic4-1.0.1/source/Makefile.in ./source/Makefile.in
--- ../epic4-1.0.1/source/Makefile.in Thu Mar 15 07:01:46 2001
+++ ./source/Makefile.in Thu Sep 20 09:56:20 2001
@@ -17,7 +17,7 @@
ircsig.o keys.o lastlog.o list.o log.o mail.o names.o network.o \
newio.o notice.o notify.o numbers.o output.o parse.o queue.o reg.o \
screen.o server.o status.o term.o timer.o vars.o who.o window.o \
- words.o @ALLOCA@
+ words.o @PERLDOTOH@ @ALLOCA@
INCLUDES = -I@srcdir@/../include -I../include
@@ -73,6 +73,9 @@
screen.o: Makefile ../Makefile
$(CC) $(CFLAGS) $(ANSIFLAGS) $(INCLUDES) -c @srcdir@/screen.c \
-DWSERV_PATH=\"$(INSTALL_WSERV)\"
+
+perl.o: perl.c Makefile ../Makefile
+ $(CC) $(CFLAGS) $(ansiflags) $(INCLUDES) -c perl.c `perl -MExtUtils::Embed -e
+ccopts`
#
diff -ruN ../epic4-1.0.1/source/array.c ./source/array.c
--- ../epic4-1.0.1/source/array.c Tue Dec 5 11:11:56 2000
+++ ./source/array.c Thu Sep 20 09:56:20 2001
@@ -173,11 +173,13 @@
#define ARRAY_THRESHOLD 100
+#if 0
typedef struct an_array_struct {
char **item;
long *index;
long size;
} an_array;
+#endif
static an_array array_info = {
(char **) 0,
@@ -356,6 +358,63 @@
}
/*
+ * This was once the inner loop of SETITEM.
+ * The documentation for it still applies.
+ */
+int set_item (char* name, long item, char* input)
+{
+ long index = 0;
+ long oldindex;
+ an_array *array;
+ int result = -1;
+ if (array_info.size && ((index = find_item(array_info, name)) >= 0))
+ {
+ array = &array_array[array_info.index[index]];
+ result = -2;
+ if (item < array->size)
+ {
+ oldindex = find_index(array, item);
+ index = find_item(*array, input);
+ index = (index >= 0) ? index : (-index) - 1;
+ move_index(array, oldindex, index);
+ new_free(&array->item[item]);
+ malloc_strcpy(&array->item[item], input);
+ result = 0;
+ }
+ else if (item == array->size)
+ {
+ RESIZE(array->item, char *, array->size + 1);
+ array->item[item] = (char *) 0;
+ malloc_strcpy(&array->item[item], input);
+ index = find_item(*array, input);
+ index = (index >= 0) ? index : (-index) - 1;
+ insert_index(&array->index, &array->size, index);
+ result = 2;
+ }
+ }
+ else
+ {
+ if (item == 0)
+ {
+ RESIZE(array_array, an_array, array_info.size + 1);
+ array = &array_array[array_info.size];
+ array->size = 1;
+ array->item = (char **)new_malloc(sizeof(char *));
+ array->index = (long *)new_malloc(sizeof(long));
+ array->item[0] = (char*) 0;
+ array->index[0] = 0;
+ malloc_strcpy(&array->item[0], input);
+ RESIZE(array_info.item, char *, array_info.size + 1);
+ array_info.item[array_info.size] = (char *) 0;
+ malloc_strcpy(&array_info.item[array_info.size], name);
+ insert_index(&array_info.index, &array_info.size, (-index) -
+1);
+ result = 1;
+ }
+ }
+ return result;
+}
+
+/*
* Now for the actual alias functions
* ==================================
*/
@@ -615,9 +674,6 @@
char *name = (char *) 0;
char *itemstr = (char *) 0;
long item;
- long index = 0;
- long oldindex;
- an_array *array;
int result = -1;
if ((name = next_arg(input, &input)))
@@ -628,50 +684,7 @@
if (item >= 0)
{
upper(name);
- if (array_info.size && ((index = find_item(array_info,
name)) >= 0))
- {
- array = &array_array[array_info.index[index]];
- result = -2;
- if (item < array->size)
- {
- oldindex = find_index(array, item);
- index = find_item(*array, input);
- index = (index >= 0) ? index :
(-index) - 1;
- move_index(array, oldindex, index);
- new_free(&array->item[item]);
- malloc_strcpy(&array->item[item],
input);
- result = 0;
- }
- else if (item == array->size)
- {
- RESIZE(array->item, char *,
array->size + 1);
- array->item[item] = (char *) 0;
- malloc_strcpy(&array->item[item],
input);
- index = find_item(*array, input);
- index = (index >= 0) ? index :
(-index) - 1;
- insert_index(&array->index,
&array->size, index);
- result = 2;
- }
- }
- else
- {
- if (item == 0)
- {
- RESIZE(array_array, an_array,
array_info.size + 1);
- array = &array_array[array_info.size];
- array->size = 1;
- array->item = (char
**)new_malloc(sizeof(char *));
- array->index = (long
*)new_malloc(sizeof(long));
- array->item[0] = (char*) 0;
- array->index[0] = 0;
- malloc_strcpy(&array->item[0], input);
- RESIZE(array_info.item, char *,
array_info.size + 1);
- array_info.item[array_info.size] =
(char *) 0;
-
malloc_strcpy(&array_info.item[array_info.size], name);
- insert_index(&array_info.index,
&array_info.size, (-index) - 1);
- result = 1;
- }
- }
+ result = set_item(name, item, input);
}
}
}
diff -ruN ../epic4-1.0.1/source/functions.c ./source/functions.c
--- ../epic4-1.0.1/source/functions.c Wed Mar 21 06:42:58 2001
+++ ./source/functions.c Thu Sep 20 09:56:20 2001
@@ -244,6 +244,11 @@
*function_pad (char *),
*function_pattern (char *),
*function_pass (char *),
+#ifdef PERL
+ *function_perl (char *),
+ *function_perlcall (char *),
+ *function_perlxcall (char *),
+#endif
*function_prefix (char *),
*function_printlen (char *),
*function_querywin (char *),
@@ -472,6 +477,11 @@
{ "PAD", function_pad },
{ "PASS", function_pass },
{ "PATTERN", function_pattern },
+#ifdef PERL
+ { "PERL", function_perl },
+ { "PERLCALL", function_perlcall },
+ { "PERLXCALL", function_perlxcall },
+#endif
{ "PID", function_pid },
{ "POP", function_pop },
{ "PPID", function_ppid },
@@ -5868,3 +5878,32 @@
return m_sprintf("%f", (double)tan(num));
}
+#ifdef PERL
+
+BUILT_IN_FUNCTION(function_perl, input)
+{
+ extern char* perleval ( const char* );
+ return perleval ( input );
+}
+
+BUILT_IN_FUNCTION(function_perlcall, input)
+{
+ char *sub=NULL;
+ extern char* perlcall ( const char*, char*, char*, long, char* );
+ GET_STR_ARG(sub, input);
+ return perlcall ( sub, NULL, NULL, -1, input );
+}
+
+BUILT_IN_FUNCTION(function_perlxcall, input)
+{
+ long item=0;
+ char *sub=NULL, *in=NULL, *out=NULL;
+ extern char* perlcall ( const char*, char*, char*, long, char* );
+ GET_STR_ARG(sub, input);
+ if (input && *input) GET_STR_ARG(in, input);
+ if (input && *input) GET_STR_ARG(out, input);
+ if (input && *input) GET_INT_ARG(item, input);
+ return perlcall ( sub, in, out, item, input );
+}
+
+#endif
diff -ruN ../epic4-1.0.1/source/irc.c ./source/irc.c
--- ../epic4-1.0.1/source/irc.c Wed Apr 18 03:20:30 2001
+++ ./source/irc.c Thu Sep 20 09:56:20 2001
@@ -236,6 +236,9 @@
char buffer[BIG_BUFFER_SIZE];
char * sub_format;
int old_window_display = window_display;
+#ifdef PERL
+ extern void perlstartstop(int);
+#endif
/*
* If we get called recursively, something is hosed.
@@ -276,6 +279,9 @@
/* Do some clean up */
do_hook(EXIT_LIST, "%s", buffer);
+#ifdef PERL
+ perlstartstop(0); /* In case there's perl code in the exit hook. */
+#endif
close_all_servers(buffer);
logger(0);
clean_up_processes();
diff -ruN ../epic4-1.0.1/source/perl.c ./source/perl.c
--- ../epic4-1.0.1/source/perl.c Thu Jan 1 10:00:00 1970
+++ ./source/perl.c Thu Sep 20 09:56:20 2001
@@ -0,0 +1,157 @@
+#include "irc.h"
+#include "ircaux.h"
+#include "array.h"
+#include <EXTERN.h>
+#include <perl.h>
+#include <XSUB.h>
+
+int isperlrunning=0, perlcalldepth=0;
+PerlInterpreter *my_perl;
+
+EXTERN_C void xs_init (pTHXo);
+EXTERN_C void boot_DynaLoader (pTHXo_ CV* cv);
+
+#define RETURN_MSTR(x) return ((x) ? (x) : "");
+#define SV2STR(x,y) (y)=(void*)m_strdup(SvPV_nolen(x))
+
+static XS (XS_cmd) {
+ unsigned foo;
+ dXSARGS;
+ for (foo=0; foo<items; foo++) {
+ parse_line(NULL, "$*", SvPV_nolen(ST(foo)), 0, 0);
+ }
+ XSRETURN(0);
+}
+
+static XS (XS_eval) {
+ unsigned foo;
+ dXSARGS;
+ for (foo=0; foo<items; foo++) {
+ parse_line(NULL, SvPV_nolen(ST(foo)), "", 0, 0);
+ }
+ XSRETURN(0);
+}
+
+static XS (XS_expr) {
+ unsigned foo;
+ char* retval=NULL;
+ dXSARGS;
+ for (foo=0; foo<items; foo++) {
+ retval=(char*)parse_inline(LOCAL_COPY(SvPV_nolen(ST(foo))), "", 0);
+ XST_mPV(foo, retval);
+ new_free(&retval);
+ }
+ XSRETURN(items);
+}
+
+static XS (XS_yell) {
+ unsigned foo;
+ char* retval=NULL;
+ dXSARGS;
+ for (foo=0; foo<items; foo++) {
+ yell("Perl: %s",SvPV_nolen(ST(foo)));
+ }
+ XSRETURN(items);
+}
+
+EXTERN_C void
+xs_init(pTHXo)
+{
+ char *file = __FILE__;
+ dXSUB_SYS;
+
+ /* DynaLoader is a special case */
+ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
+ newXS("EPIC::cmd", XS_cmd, "IRC");
+ newXS("EPIC::eval", XS_eval, "IRC");
+ newXS("EPIC::expr", XS_expr, "IRC");
+ newXS("EPIC::yell", XS_yell, "IRC");
+}
+
+/* Stopping has one big memory leak right now, so it's not used. */
+void perlstartstop (int startnotstop) {
+ if (startnotstop && !isperlrunning) {
+ char *embedding[] = {
+ "", "-e",
+ "$SIG{__DIE__}=$SIG{__WARN__}=\\&EPIC::yell;"
+ };
+ ++isperlrunning;
+ my_perl = perl_alloc();
+ perl_construct( my_perl );
+ perl_parse(my_perl, xs_init, 3, embedding, NULL);
+ if (SvTRUE(ERRSV)) yell("perl_parse: %s", SvPV_nolen(ERRSV));
+ perl_run(my_perl);
+ if (SvTRUE(ERRSV)) yell("perl_run: %s", SvPV_nolen(ERRSV));
+ } else if (!startnotstop && isperlrunning && !perlcalldepth) {
+ perl_destruct(my_perl);
+ if (SvTRUE(ERRSV)) yell("perl_destruct: %s", SvPV_nolen(ERRSV));
+ perl_free(my_perl);
+ if (SvTRUE(ERRSV)) yell("perl_free: %s", SvPV_nolen(ERRSV));
+ isperlrunning=0;
+ }
+}
+
+char* perlcall (const char* sub, char* in, char* out, long item, char* input) {
+ char *retval=NULL;
+ int count, foo;
+ an_array *array;
+ extern an_array* get_array (char *);
+ extern int set_item(char*, long, char*);
+ dSP ;
+ if (!isperlrunning){RETURN_MSTR(retval);}
+ ++perlcalldepth;
+ ENTER; SAVETMPS;
+ PUSHMARK(SP);
+ if (input && *input) XPUSHs(sv_2mortal(newSVpv(input, 0)));
+ if (in && *in && (array=get_array(in))) {
+ for (foo=0; foo<array->size; foo++) {
+ XPUSHs(sv_2mortal(newSVpv(array->item[foo], 0)));
+ }
+ }
+ PUTBACK ;
+ if (out && *out) {
+ long size;
+ upper(out);
+ size=(array=get_array(out))?array->size:0;
+ if (0>item) item=size-~item;
+ if (item>size) item=-1;
+ } else {
+ item=-1;
+ }
+ if (0<=item) {
+ I32 ax;
+ count = call_pv(sub, G_EVAL|G_ARRAY);
+ SPAGAIN ;
+ SP -= count ;
+ ax = (SP - PL_stack_base) + 1 ;
+ for (foo=0; foo<count; foo++) {
+ set_item(out, item+foo, SvPV_nolen(ST(foo)));
+ }
+ retval=(void*)new_realloc((void**)(&retval),32);
+ snprintf(retval,31,"%u",count);
+ } else {
+ SV *sv;
+ count = call_pv(sub, G_EVAL|G_SCALAR);
+ SPAGAIN ; sv=POPs ;
+ SV2STR(sv,retval);
+ }
+ PUTBACK ;
+ FREETMPS; LEAVE;
+ --perlcalldepth;
+ RETURN_MSTR(retval);
+}
+
+char* perleval (const char* input) {
+ char *retval=NULL;
+ if (input && *input) {
+ SV *sv;
+ perlstartstop(1);
+ ++perlcalldepth;
+ ENTER; SAVETMPS;
+ sv=eval_pv(input, FALSE);
+ SV2STR(sv,retval);
+ FREETMPS; LEAVE;
+ --perlcalldepth;
+ };
+ RETURN_MSTR(retval);
+}