[229] in BarnOwl Developers

home help back first fref pref prev next nref lref last post

[D-O-H] r405 - trunk/owl

daemon@ATHENA.MIT.EDU (nelhage@MIT.EDU)
Thu Oct 29 18:03:55 2009

Resent-From: nelhage@mit.edu
Resent-To: barnowl-dev-mtg@charon.mit.edu
Date: Thu, 26 Oct 2006 11:14:42 -0400
To: dirty-owl-hackers@MIT.EDU
From: nelhage@MIT.EDU
Reply-To: dirty-owl-hackers@MIT.EDU

Author: nelhage
Date: 2006-10-26 11:14:41 -0400 (Thu, 26 Oct 2006)
New Revision: 405

Modified:
   trunk/owl/cmd.c
   trunk/owl/owl.h
   trunk/owl/perlconfig.c
   trunk/owl/perlglue.xs
   trunk/owl/perlwrap.pm
Log:
Adding the ability to install real commands from perl.

Modified: trunk/owl/cmd.c
===================================================================
--- trunk/owl/cmd.c	2006-10-25 22:59:35 UTC (rev 404)
+++ trunk/owl/cmd.c	2006-10-26 15:14:41 UTC (rev 405)
@@ -56,6 +56,16 @@
   return(0);
 }
 
+int owl_cmddict_add_cmd(owl_cmddict *cd, owl_cmd * cmd) {
+  owl_cmd * newcmd = owl_malloc(sizeof(owl_cmd));
+  if(owl_cmd_create_from_template(newcmd, cmd) < 0) {
+    owl_free(newcmd);
+    return -1;
+  }
+  owl_function_debugmsg("Add cmd %s", cmd->name);
+  return owl_dict_insert_element(cd, newcmd->name, (void*)newcmd, (void(*)(void*))owl_cmd_free);
+}
+
 char *owl_cmddict_execute(owl_cmddict *cd, owl_context *ctx, char *cmdbuff) {
   char **argv;
   int argc;
@@ -117,6 +127,8 @@
   if (cmd->summary) owl_free(cmd->summary);
   if (cmd->usage) owl_free(cmd->usage);
   if (cmd->description) owl_free(cmd->description);
+  if (cmd->cmd_aliased_to) owl_free(cmd->cmd_aliased_to);
+  if (cmd->cmd_perl) owl_perlconfig_cmd_free(cmd);
 }
 
 int owl_cmd_is_context_valid(owl_cmd *cmd, owl_context *ctx) { 
@@ -186,6 +198,8 @@
     cmd->cmd_ctxv_fn(owl_context_get_data(ctx));
   } else if (cmd->cmd_ctxi_fn) {
     cmd->cmd_ctxi_fn(owl_context_get_data(ctx), ival);
+  } else if (cmd->cmd_perl) {
+    return owl_perlconfig_perlcmd(cmd, argc, argv);
   }
 
   return NULL;

Modified: trunk/owl/owl.h
===================================================================
--- trunk/owl/owl.h	2006-10-25 22:59:35 UTC (rev 404)
+++ trunk/owl/owl.h	2006-10-26 15:14:41 UTC (rev 405)
@@ -40,13 +40,6 @@
 #ifndef INC_OWL_H
 #define INC_OWL_H
 
-/* Perl and curses don't play nice. */
-#ifndef OWL_PERL
-#include <curses.h>
-#else
-#define WINDOW void
-#endif
-
 #include <sys/param.h>
 #include <EXTERN.h>
 #include <netdb.h>
@@ -63,6 +56,16 @@
 #include <com_err.h>
 #endif
 
+/* Perl and curses don't play nice. */
+#ifdef OWL_PERL
+typedef void WINDOW;
+#include <perl.h>
+#include "XSUB.h"
+#else
+#include <curses.h>
+typedef void SV;
+#endif
+
 static const char owl_h_fileIdent[] = "$Id$";
 
 #define OWL_VERSION         2.1.11
@@ -304,6 +307,7 @@
 				 * caller must free return value if !NULL */
   void (*cmd_ctxv_fn)(void *ctx);	        /* takes no args */
   void (*cmd_ctxi_fn)(void *ctx, int i);	/* takes an int as an arg */
+  SV *cmd_perl;                                /* Perl closure that takes a list of args */
 } owl_cmd;
 
 

Modified: trunk/owl/perlconfig.c
===================================================================
--- trunk/owl/perlconfig.c	2006-10-25 22:59:35 UTC (rev 404)
+++ trunk/owl/perlconfig.c	2006-10-26 15:14:41 UTC (rev 405)
@@ -6,8 +6,6 @@
 #include <errno.h>
 #define OWL_PERL
 #include "owl.h"
-#include <perl.h>
-#include "XSUB.h"
 
 static const char fileIdent[] = "$Id$";
 
@@ -15,7 +13,7 @@
 
 extern XS(boot_owl);
 extern XS(boot_DynaLoader);
-extern XS(boot_DBI);
+// extern XS(boot_DBI);
 
 static void owl_perl_xs_init(pTHX)
 {
@@ -336,3 +334,46 @@
     return(NULL);
   }
 }
+
+char *owl_perlconfig_perlcmd(owl_cmd *cmd, int argc, char **argv)
+{
+  int i, count;
+  char * ret = NULL;
+  STRLEN n_a;
+  dSP;
+
+  ENTER;
+  SAVETMPS;
+
+  PUSHMARK(SP);
+  for(i=0;i<argc;i++) {
+    XPUSHs(sv_2mortal(newSVpv(argv[i], 0)));
+  }
+  PUTBACK;
+
+  count = call_sv(cmd->cmd_perl, G_SCALAR|G_EVAL);
+
+  SPAGAIN;
+
+  if(SvTRUE(ERRSV)) {
+    owl_function_error("Error: %s", SvPV(ERRSV, n_a));
+    POPs;
+  } else {
+    if(count != 1)
+      croak("Perl command %s returned more than one value!", cmd->name);
+    SV * rv = POPs;
+    if(SvTRUE(rv)) {
+      ret = owl_strdup(SvPV(rv, n_a));
+    }
+  }
+
+  FREETMPS;
+  LEAVE;
+
+  return ret;
+}
+
+void owl_perlconfig_cmd_free(owl_cmd *cmd)
+{
+  SvREFCNT_dec(cmd);
+}

Modified: trunk/owl/perlglue.xs
===================================================================
--- trunk/owl/perlglue.xs	2006-10-25 22:59:35 UTC (rev 404)
+++ trunk/owl/perlglue.xs	2006-10-26 15:14:41 UTC (rev 405)
@@ -4,8 +4,6 @@
 #include <zephyr/zephyr.h>
 #endif
 #include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
 
 #define OWL_PERL
 #include "owl.h"
@@ -74,3 +72,30 @@
 	CLEANUP:
 		if (rv) owl_free(rv);
 
+void
+new_command_internal(name, func, summary, usage, description)
+	char *name
+	SV *func
+	char *summary
+	char *usage
+	char *description
+	PREINIT:
+		owl_cmd cmd;
+	CODE:
+		SvREFCNT_inc(func);
+		cmd.name = name;
+		cmd.cmd_perl = func;
+		cmd.summary = summary;
+		cmd.usage = usage;
+		cmd.description = description;
+		cmd.validctx = OWL_CTX_ANY;
+
+		cmd.cmd_aliased_to = NULL;
+		cmd.cmd_args_fn = NULL;
+		cmd.cmd_v_fn = NULL;
+		cmd.cmd_i_fn = NULL;
+		cmd.cmd_ctxargs_fn = NULL;
+		cmd.cmd_ctxv_fn = NULL;
+		cmd.cmd_ctxi_fn = NULL;
+
+		owl_cmddict_add_cmd(owl_global_get_cmddict(&g), &cmd);

Modified: trunk/owl/perlwrap.pm
===================================================================
--- trunk/owl/perlwrap.pm	2006-10-25 22:59:35 UTC (rev 404)
+++ trunk/owl/perlwrap.pm	2006-10-26 15:14:41 UTC (rev 405)
@@ -31,6 +31,31 @@
     return &owl::command("$called ".join(" ",@_));
 }
 
+=head2 new_command NAME FUNC [{ARGS}]
+
+Add a new owl command. When owl executes the command NAME, FUNC will
+be called with the arguments passed to the command, with NAME as the
+first argument.
+
+ARGS should be a hashref containing any or all of C<summary>,
+C<usage>, or C<description> keys.
+
+=cut
+
+sub new_command {
+    my $name = shift;
+    my $func = shift;
+    my $args = shift || {};
+    my %args = (
+        summary     => undef,
+        usage       => undef,
+        description => undef,
+        %{$args}
+    );
+
+    owl::new_command_internal($name, $func, $args{summary}, $args{usage}, $args{description});
+}
+
 #####################################################################
 #####################################################################
 


home help back first fref pref prev next nref lref last post