Index: .gitignore
===================================================================
--- .gitignore	(revision 7d03c8d7261007b87c9466976c6efd8e1a572d76)
+++ .gitignore	(revision de18326f12c18fd92f275bf46bca509343b79063)
@@ -35,4 +35,3 @@
 pm_to_blib
 stamp-h1
-tester
 varstubs.c
Index: Makefile.am
===================================================================
--- Makefile.am	(revision c45e1eb9376a28e40375388e3b11847bf9ea6620)
+++ Makefile.am	(revision 5aa33fd73dce2c8d6c88559e62cd1ae78ef4a36d)
@@ -12,5 +12,5 @@
 zcrypt_SOURCES = zcrypt.c filterproc.c
 
-check_PROGRAMS = tester perl_tester
+check_PROGRAMS = tester.bin
 
 barnowl_bin_SOURCES = $(BASE_SRCS) \
@@ -21,17 +21,10 @@
 barnowl_bin_LDADD = libfaim/libfaim.a
 
-tester_SOURCES = $(BASE_SRCS) \
+tester_bin_SOURCES = $(BASE_SRCS) \
      owl.h owl_perl.h config.h \
      $(GEN_C) $(GEN_H) \
      tester.c
 
-tester_LDADD = libfaim/libfaim.a
-
-perl_tester_SOURCES = $(BASE_SRCS) \
-     owl.h owl_perl.h config.h \
-     $(GEN_C) $(GEN_H) \
-     perl_tester.c
-
-perl_tester_LDADD = libfaim/libfaim.a
+tester_bin_LDADD = libfaim/libfaim.a
 
 TESTS=runtests.sh
Index: barnowl
===================================================================
--- barnowl	(revision 9a7b4f23cba7fc71c4e918b5cb8d5ca6789924e3)
+++ barnowl	(revision de18326f12c18fd92f275bf46bca509343b79063)
@@ -5,5 +5,5 @@
 
 SRCDIR=`dirname "${0}"`
-EXE="$SRCDIR/barnowl.bin"
+EXE="$0.bin"
 
 if ! test -x "$EXE"; then
Index: global.c
===================================================================
--- global.c	(revision 68e5464454e6b10711aea47efecf242cd3c3ef2a)
+++ global.c	(revision 68e5464454e6b10711aea47efecf242cd3c3ef2a)
@@ -1032,2 +1032,34 @@
   g->interrupted = 0;
 }
+
+void owl_global_setup_default_filters(owl_global *g)
+{
+  int i;
+  static const struct {
+    const char *name;
+    const char *desc;
+  } filters[] = {
+    { "personal",
+      "private ^true$ and ( not type ^zephyr$ or "
+      "( class ^message and ( instance ^personal$ or instance ^urgent$ ) ) )" },
+    { "trash",
+      "class ^mail$ or opcode ^ping$ or type ^admin$ or ( not login ^none$ )" },
+    { "wordwrap", "not ( type ^admin$ or type ^zephyr$ )" },
+    { "ping", "opcode ^ping$" },
+    { "auto", "opcode ^auto$" },
+    { "login", "not login ^none$" },
+    { "reply-lockout", "class ^noc or class ^mail$" },
+    { "out", "direction ^out$" },
+    { "aim", "type ^aim$" },
+    { "zephyr", "type ^zephyr$" },
+    { "none", "false" },
+    { "all", "true" },
+    { NULL, NULL }
+  };
+
+  owl_function_debugmsg("startup: creating default filters");
+
+  for (i = 0; filters[i].name != NULL; i++)
+    owl_global_add_filter(g, owl_filter_new_fromstring(filters[i].name,
+                                                       filters[i].desc));
+}
Index: owl.c
===================================================================
--- owl.c	(revision 3aa05226f2c729940957d231891ed429669e255f)
+++ owl.c	(revision 04b16f8ed734b58f776e5aa382d59f78696a3771)
@@ -149,34 +149,4 @@
 }
 
-static void owl_setup_default_filters(void)
-{
-  int i;
-  static const struct {
-    const char *name;
-    const char *desc;
-  } filters[] = {
-    { "personal",
-      "isprivate ^true$ and ( not type ^zephyr$ or ( class ^message  ) )" },
-    { "trash",
-      "class ^mail$ or opcode ^ping$ or type ^admin$ or ( not login ^none$ )" },
-    { "wordwrap", "not ( type ^admin$ or type ^zephyr$ )" },
-    { "ping", "opcode ^ping$" },
-    { "auto", "opcode ^auto$" },
-    { "login", "not login ^none$" },
-    { "reply-lockout", "class ^noc or class ^mail$" },
-    { "out", "direction ^out$" },
-    { "aim", "type ^aim$" },
-    { "zephyr", "type ^zephyr$" },
-    { "none", "false" },
-    { "all", "true" },
-    { NULL, NULL }
-  };
-
-  owl_function_debugmsg("startup: creating default filters");
-
-  for (i = 0; filters[i].name != NULL; i++)
-    owl_global_add_filter(&g, owl_filter_new_fromstring(filters[i].name,
-                                                        filters[i].desc));
-}
 
 /*
@@ -563,5 +533,5 @@
   owl_global_complete_setup(&g);
 
-  owl_setup_default_filters();
+  owl_global_setup_default_filters(&g);
 
   /* set the current view */
Index: rl_tester.c
===================================================================
--- perl_tester.c	(revision 737b8f16912a0ac4905cb24609e3980fc2378717)
+++ 	(revision )
@@ -1,36 +1,0 @@
-#define OWL_PERL
-#include "owl.h"
-
-owl_global g;
-
-extern XS(boot_BarnOwl);
-extern XS(boot_DynaLoader);
-/* extern XS(boot_DBI); */
-
-static void owl_perl_xs_init(pTHX)
-{
-  const char *file = __FILE__;
-  dXSUB_SYS;
-  {
-    newXS("BarnOwl::bootstrap", boot_BarnOwl, file);
-    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
-  }
-}
-
-static PerlInterpreter *my_perl;  /***    The Perl interpreter    ***/
-
-int main(int argc, char **argv, char **env)
-{
-  /* Code from perldoc perlembed */
-  PERL_SYS_INIT3(&argc,&argv,&env);
-  my_perl = perl_alloc();
-  perl_construct(my_perl);
-  PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
-  perl_parse(my_perl, owl_perl_xs_init, argc, argv, (char **)NULL);
-  perl_run(my_perl);
-  perl_destruct(my_perl);
-  perl_free(my_perl);
-  PERL_SYS_TERM();
-  return 0;
-}
-
Index: perlconfig.c
===================================================================
--- perlconfig.c	(revision 3aa05226f2c729940957d231891ed429669e255f)
+++ perlconfig.c	(revision 5aa33fd73dce2c8d6c88559e62cd1ae78ef4a36d)
@@ -12,5 +12,5 @@
 /* extern XS(boot_DBI); */
 
-static void owl_perl_xs_init(pTHX)
+void owl_perl_xs_init(pTHX) /* noproto */
 {
   const char *file = __FILE__;
@@ -363,4 +363,6 @@
   perl_construct(p);
 
+  PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
+
   owl_global_set_no_have_config(&g);
 
Index: runtests.sh
===================================================================
--- runtests.sh	(revision 9f026c14abe876082d0f781b81a150548e4b0783)
+++ runtests.sh	(revision 5aa33fd73dce2c8d6c88559e62cd1ae78ef4a36d)
@@ -1,2 +1,7 @@
 #!/bin/sh
-HARNESS_PERL=./perl_tester exec prove t/
+SRCDIR=`dirname "${0}"`
+
+export BARNOWL_DATA_DIR="$SRCDIR/perl/"
+export BARNOWL_BIN_DIR="$SRCDIR/"
+
+HARNESS_PERL=./tester exec prove t/
Index: t/00-core-tests.t
===================================================================
--- t/00-core-tests.t	(revision 1cf3f8d3cf08ed3fb38d1c83459a1db140cb0d17)
+++ t/00-core-tests.t	(revision 95414bfd3960e215dd54e6916a12f56abbf0c820)
@@ -1,3 +1,3 @@
 #!/usr/bin/env perl
 use File::Basename;
-system(dirname($0) . "/../tester");
+system(dirname($0) . "/../tester", "--builtin");
Index: t/mock.pl
===================================================================
--- t/mock.pl	(revision 42ad91716a0f429f02385235acffa71546e28caa)
+++ t/mock.pl	(revision 5aa33fd73dce2c8d6c88559e62cd1ae78ef4a36d)
@@ -1,25 +1,10 @@
-use File::Basename;
-use lib (dirname($0) . '/../perl/lib');
-
 package BarnOwl;
 use strict;
 use warnings;
-use Carp;
 
-sub get_data_dir {"."}
-sub get_config_dir {"."}
-sub create_style {}
-
-sub debug {
+no warnings 'redefine';
+sub debug($) {
     warn "[DEBUG] ", shift, "\n" if $ENV{TEST_VERBOSE};
 }
 
-sub BarnOwl::Internal::new_command {}
-sub BarnOwl::Internal::new_variable_bool {}
-sub BarnOwl::Internal::new_variable_int {}
-sub BarnOwl::Internal::new_variable_string {}
-sub BarnOwl::Editwin::save_excursion(&) {}
-
-use BarnOwl;
-
 1;
Index: tester
===================================================================
--- tester	(revision de18326f12c18fd92f275bf46bca509343b79063)
+++ tester	(revision de18326f12c18fd92f275bf46bca509343b79063)
@@ -0,0 +1,1 @@
+barnowl
Index: tester.c
===================================================================
--- tester.c	(revision 3f6555d9e7121e9d0551b2f945cfd93e4a2b5040)
+++ tester.c	(revision 95414bfd3960e215dd54e6916a12f56abbf0c820)
@@ -1,10 +1,18 @@
+#define OWL_PERL
+#define WINDOW FAKE_WINDOW
 #include "owl.h"
+#undef WINDOW
+
 #include <unistd.h>
 #include <stdlib.h>
 
+#undef instr
+#include <curses.h>
+
 owl_global g;
 
 int numtests;
 
+int owl_regtest(void);
 int owl_util_regtest(void);
 int owl_dict_regtest(void);
@@ -14,13 +22,77 @@
 int owl_editwin_regtest(void);
 
+extern void owl_perl_xs_init(pTHX);
+
 int main(int argc, char **argv, char **env)
 {
+  FILE *rnull;
+  FILE *wnull;
+  char *perlerr;
+  int status = 0;
+
+  if (argc <= 1) {
+    fprintf(stderr, "Usage: %s --builtin|TEST.t|-le CODE\n", argv[0]);
+    return 1;
+  }
+
   /* initialize a fake ncurses, detached from std{in,out} */
-  FILE *rnull = fopen("/dev/null", "r");
-  FILE *wnull = fopen("/dev/null", "w");
+  wnull = fopen("/dev/null", "w");
+  rnull = fopen("/dev/null", "r");
   newterm("xterm", wnull, rnull);
   /* initialize global structures */
   owl_global_init(&g);
 
+  perlerr = owl_perlconfig_initperl(NULL, &argc, &argv, &env);
+  if (perlerr) {
+    endwin();
+    fprintf(stderr, "Internal perl error: %s\n", perlerr);
+    status = 1;
+    goto out;
+  }
+
+  owl_global_complete_setup(&g);
+  owl_global_setup_default_filters(&g);
+
+  owl_view_create(owl_global_get_current_view(&g), "main",
+                  owl_global_get_filter(&g, "all"),
+                  owl_global_get_style_by_name(&g, "default"));
+
+  owl_function_firstmsg();
+
+  ENTER;
+  SAVETMPS;
+
+  if (strcmp(argv[1], "--builtin") == 0) {
+    status = owl_regtest();
+  } else if (strcmp(argv[1], "-le") == 0 && argc > 2) {
+    /*
+     * 'prove' runs its harness perl with '-le CODE' to get some
+     * information out.
+     */
+    moreswitches("l");
+    eval_pv(argv[2], true);
+  } else {
+    sv_setpv(get_sv("0", false), argv[1]);
+    sv_setpv(get_sv("main::test_prog", TRUE), argv[1]);
+
+    eval_pv("do $main::test_prog; die($@) if($@)", true);
+  }
+
+  status = 0;
+
+  FREETMPS;
+  LEAVE;
+
+ out:
+  perl_destruct(owl_global_get_perlinterp(&g));
+  perl_free(owl_global_get_perlinterp(&g));
+  /* probably not necessary, but tear down the screen */
+  endwin();
+  fclose(rnull);
+  fclose(wnull);
+  return status;
+}
+
+int owl_regtest(void) {
   numtests = 0;
   int numfailures=0;
@@ -38,9 +110,4 @@
   }
   printf("1..%d\n", numtests);
-
-  /* probably not necessary, but tear down the screen */
-  endwin();
-  fclose(rnull);
-  fclose(wnull);
 
   return(numfailures);
