[880] in BarnOwl Developers
[D-O-H] r869 - branches/barnowl_sqlite/owl
daemon@ATHENA.MIT.EDU (nelhage@MIT.EDU)
Thu Oct 29 18:10:42 2009
Resent-From: nelhage@mit.edu
Resent-To: barnowl-dev-mtg@charon.mit.edu
To: dirty-owl-hackers@mit.edu
From: nelhage@MIT.EDU
Reply-to: dirty-owl-hackers@MIT.EDU
Date: Mon, 14 Jan 2008 05:04:34 -0500 (EST)
Author: nelhage
Date: 2008-01-14 05:04:33 -0500 (Mon, 14 Jan 2008)
New Revision: 869
Added:
branches/barnowl_sqlite/owl/owl_perl.h
Modified:
branches/barnowl_sqlite/owl/Makefile.in
branches/barnowl_sqlite/owl/global.c
branches/barnowl_sqlite/owl/mainwin.c
branches/barnowl_sqlite/owl/message.c
branches/barnowl_sqlite/owl/messagelist.c
branches/barnowl_sqlite/owl/owl.c
branches/barnowl_sqlite/owl/owl.h
branches/barnowl_sqlite/owl/perlconfig.c
branches/barnowl_sqlite/owl/perlwrap.pm
Log:
First pass at moving the messagelist into C land. This is not very
tested or stable yet.
Modified: branches/barnowl_sqlite/owl/Makefile.in
===================================================================
--- branches/barnowl_sqlite/owl/Makefile.in 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/Makefile.in 2008-01-14 10:04:33 UTC (rev 869)
@@ -44,7 +44,7 @@
AUTOGEN=$(GEN_C) $(GEN_H)
#AUTOGEN=$(GEN_C)
-HEADERS=$(GEN_H) owl.h config.h test.h
+HEADERS=$(GEN_H) owl.h owl_perl.h config.h test.h
%.o: %.c $(HEADERS)
$(CC) -c $(CFLAGS) $< -o $@
Modified: branches/barnowl_sqlite/owl/global.c
===================================================================
--- branches/barnowl_sqlite/owl/global.c 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/global.c 2008-01-14 10:04:33 UTC (rev 869)
@@ -92,7 +92,6 @@
owl_global_set_confdir(g, cd);
owl_free(cd);
- owl_messagelist_create(&(g->msglist));
owl_mainwin_init(&(g->mw));
owl_popwin_init(&(g->pw));
@@ -211,7 +210,7 @@
/* msglist */
owl_messagelist *owl_global_get_msglist(owl_global *g) {
- return(&(g->msglist));
+ return g->msglist;
}
/* keyhandler */
Modified: branches/barnowl_sqlite/owl/mainwin.c
===================================================================
--- branches/barnowl_sqlite/owl/mainwin.c 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/mainwin.c 2008-01-14 10:04:33 UTC (rev 869)
@@ -113,7 +113,7 @@
getyx(recwin, y, x);
wattrset(recwin, A_NORMAL);
if (owl_global_get_rightshift(&g)==0) { /* this lame and should be fixed */
- if (m==owl_view_get_element(v, curmsg)) {
+ if (owl_message_get_id(m)==owl_message_get_id(owl_view_get_element(v, curmsg))) {
wmove(recwin, savey, 0);
wattron(recwin, A_BOLD);
if (owl_global_get_curmsg_vert_offset(&g)>0) {
Modified: branches/barnowl_sqlite/owl/message.c
===================================================================
--- branches/barnowl_sqlite/owl/message.c 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/message.c 2008-01-14 10:04:33 UTC (rev 869)
@@ -17,34 +17,7 @@
static owl_fmtext_cache * fmtext_cache_next = fmtext_cache;
owl_message *owl_message_new() {
- dSP;
- SV *msg;
- int count;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- XPUSHs(sv_2mortal(newSVpv("BarnOwl::Message", 0)));
- PUTBACK;
-
- count = call_method("new", G_SCALAR|G_EVAL);
-
- SPAGAIN;
-
- if (SvTRUE(ERRSV)) {
- printf("Ooops: %s\n", SvPV_nolen(ERRSV));
- exit(-1);
- }
-
- msg = POPs;
- SvREFCNT_inc(msg);
-
- PUTBACK;
- FREETMPS;
- LEAVE;
-
- return (owl_message*)msg;
+ return (owl_message*)owl_perl_new("BarnOwl::Message");
}
void owl_message_init(owl_message *m)
Modified: branches/barnowl_sqlite/owl/messagelist.c
===================================================================
--- branches/barnowl_sqlite/owl/messagelist.c 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/messagelist.c 2008-01-14 10:04:33 UTC (rev 869)
@@ -1,97 +1,94 @@
+#define OWL_PERL
#include "owl.h"
-#include <stdlib.h>
-#include <string.h>
static const char fileIdent[] = "$Id$";
-int owl_messagelist_create(owl_messagelist *ml)
-{
- owl_list_create(&(ml->list));
- return(0);
+owl_messagelist * owl_messagelist_new() {
+ return (owl_messagelist*)owl_perl_new("BarnOwl::MessageList");
}
int owl_messagelist_get_size(owl_messagelist *ml)
{
- return(owl_list_get_size(&(ml->list)));
+ int size;
+ OWL_PERL_CALL_METHOD(ml, "get_size",
+ , // No arguments
+ // Error message
+ "Error in get_size: %s",
+ // Errors are fatal
+ 1,
+ // Success code
+ size = POPi;
+ );
+ return size;
}
void owl_messagelist_start_iterate(owl_messagelist *ml) {
- ml->iterator = 0;
+ OWL_PERL_CALL_METHOD(ml, "start_iterate",
+ , // No arguments
+ // Error
+ "Error in start_iterate: %s",
+ 1, //Fatal errors
+ OWL_PERL_VOID_CALL
+ );
}
owl_message *owl_messagelist_iterate_next(owl_messagelist *ml) {
- owl_message *m = NULL;
- if(ml->iterator >= 0 && ml->iterator < owl_list_get_size(&(ml->list))) {
- m = owl_list_get_element(&(ml->list), ml->iterator);
- ml->iterator++;
- }
- return m;
+ SV *msg;
+ OWL_PERL_CALL_METHOD(ml, "iterate_next",
+ , // No arguments
+ // Error
+ "Error in iterate_next: %s",
+ 1, //Fatal errors
+ msg = POPs;
+ if(SvROK(msg)) SvREFCNT_inc(msg);
+ );
+ if(SvROK(msg)) return msg;
+ return NULL;
}
owl_message *owl_messagelist_get_by_id(owl_messagelist *ml, int target_id)
{
- /* return the message with id == 'id'. If it doesn't exist return NULL. */
- int first, last, mid, msg_id;
- owl_message *m;
-
- first = 0;
- last = owl_list_get_size(&(ml->list)) - 1;
- while (first <= last) {
- mid = (first + last) / 2;
- m = owl_list_get_element(&(ml->list), mid);
- msg_id = owl_message_get_id(m);
- if (msg_id == target_id) {
- return(m);
- } else if (msg_id < target_id) {
- first = mid + 1;
- } else {
- last = mid - 1;
- }
- }
- return(NULL);
+ SV *msg;
+ OWL_PERL_CALL_METHOD(ml, "get_by_id",
+ mXPUSHi(target_id); ,
+ // Error
+ "Error in get_by_id: %s",
+ 1, //Fatal errors
+ msg = POPs;
+ SvREFCNT_inc(msg);
+ );
+ return msg;
}
-int owl_messagelist_append_element(owl_messagelist *ml, void *element)
+void owl_messagelist_append_element(owl_messagelist *ml, void *element)
{
- return(owl_list_append_element(&(ml->list), element));
+ OWL_PERL_CALL_METHOD(ml, "add_message",
+ XPUSHs((SV*)element); ,
+ // Error
+ "Error in add_message: %s",
+ 1, // Fatal
+ OWL_PERL_VOID_CALL
+ );
}
-int owl_messagelist_expunge(owl_messagelist *ml)
+void owl_messagelist_expunge(owl_messagelist *ml)
{
- /* expunge deleted messages */
- int i, j;
- owl_list newlist;
- owl_message *m;
-
- owl_list_create(&newlist);
- /*create a new list without messages marked as deleted */
- j=owl_list_get_size(&(ml->list));
- for (i=0; i<j; i++) {
- m=owl_list_get_element(&(ml->list), i);
- if (owl_message_is_delete(m)) {
- owl_message_free(m);
- } else {
- owl_list_append_element(&newlist, m);
- }
- }
-
- /* free the old list */
- owl_list_free_simple(&(ml->list));
-
- /* copy the new list to the old list */
- memcpy(&(ml->list), &newlist, sizeof(owl_list));
-
- return(0);
+ OWL_PERL_CALL_METHOD(ml, "expunge",
+ , // No args
+ // Error
+ "Error in expunge: %s",
+ 1, // Fatal
+ OWL_PERL_VOID_CALL
+ );
}
void owl_messagelist_invalidate_formats(owl_messagelist *ml)
{
- int i, j;
owl_message *m;
- j=owl_list_get_size(&(ml->list));
- for (i=0; i<j; i++) {
- m=owl_list_get_element(&(ml->list), i);
+ owl_messagelist_iterate_next(ml);
+
+ while((m = owl_messagelist_iterate_next(ml)) != NULL) {
owl_message_invalidate_format(m);
}
}
Modified: branches/barnowl_sqlite/owl/owl.c
===================================================================
--- branches/barnowl_sqlite/owl/owl.c 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/owl.c 2008-01-14 10:04:33 UTC (rev 869)
@@ -247,6 +247,9 @@
exit(1);
}
+ /* Now that we have perl, we can initialize the msssage list*/
+ g.msglist = owl_messagelist_new();
+
/* setup the built-in styles */
owl_function_debugmsg("startup: creating built-in styles");
Modified: branches/barnowl_sqlite/owl/owl.h
===================================================================
--- branches/barnowl_sqlite/owl/owl.h 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/owl.h 2008-01-14 10:04:33 UTC (rev 869)
@@ -67,6 +67,7 @@
/* aim.h defines bool */
#define HAS_BOOL
#include <perl.h>
+#include "owl_perl.h"
#undef logout
#include "XSUB.h"
#else
@@ -403,10 +404,7 @@
int rfd;
} owl_popexec;
-typedef struct _owl_messagelist {
- owl_list list;
- int iterator;
-} owl_messagelist;
+typedef SV owl_messagelist;
typedef struct _owl_regex {
int negate;
@@ -556,7 +554,7 @@
int curmsg, topmsg;
int curmsg_vert_offset;
owl_view current_view;
- owl_messagelist msglist;
+ owl_messagelist *msglist;
WINDOW *recwin, *sepwin, *msgwin, *typwin;
int needrefresh;
int rightshift;
Added: branches/barnowl_sqlite/owl/owl_perl.h
===================================================================
--- branches/barnowl_sqlite/owl/owl_perl.h (rev 0)
+++ branches/barnowl_sqlite/owl/owl_perl.h 2008-01-14 10:04:33 UTC (rev 869)
@@ -0,0 +1,55 @@
+#ifndef INC_OWL_PERL_H
+#define INC_OWL_PERL_H
+
+#define OWL_PERL_VOID_CALL (void)POPs;
+
+/*
+ * This macro defines a convenience wrapper around the boilerplate of
+ * calling a method on a perl object (SV*) from C.
+ *
+ * Arguments are
+ * * obj - the SV* to call the method on
+ * * meth - a char* method name
+ * * args - a code block responsible for pushing args (other than the object)
+ * * err - a string with a %s format specifier to log in case of error
+ * * fatalp - if true, perl errors terminate barnowl
+ * * ret - a code block executed if the call succeeded
+ *
+ * See also: `perldoc perlcall', `perldoc perlapi'
+ */
+#define OWL_PERL_CALL_METHOD(obj, meth, args, err, fatalp, ret) { \
+ int count; \
+ dSP; \
+ ENTER; \
+ SAVETMPS; \
+ PUSHMARK(SP); \
+ XPUSHs(obj); \
+ {args} \
+ PUTBACK; \
+ \
+ count = call_method(meth, G_SCALAR|G_EVAL); \
+ \
+ SPAGAIN; \
+ \
+ if(count != 1) { \
+ fprintf(stderr, "perl returned wrong count: %d\n", count); \
+ abort(); \
+ } \
+ if (SvTRUE(ERRSV)) { \
+ if(fatalp) { \
+ printf(err, SvPV_nolen(ERRSV)); \
+ exit(-1); \
+ } else { \
+ owl_function_error(err, SvPV_nolen(ERRSV)); \
+ (void)POPs; \
+ sv_setsv(ERRSV, &PL_sv_undef); \
+ } \
+ } else { \
+ ret; \
+ } \
+ PUTBACK; \
+ FREETMPS; \
+ LEAVE; \
+}
+
+#endif //INC_PERL_PERL_H
Modified: branches/barnowl_sqlite/owl/perlconfig.c
===================================================================
--- branches/barnowl_sqlite/owl/perlconfig.c 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/perlconfig.c 2008-01-14 10:04:33 UTC (rev 869)
@@ -397,3 +397,17 @@
}
return;
}
+
+SV * owl_perl_new(char *class)
+{
+ SV *obj;
+ OWL_PERL_CALL_METHOD(sv_2mortal(newSVpv(class, 0)), "new",
+ // No args
+ ,
+ "Error in perl: %s\n",
+ 1,
+ obj = POPs;
+ SvREFCNT_inc(obj);
+ );
+ return obj;
+}
Modified: branches/barnowl_sqlite/owl/perlwrap.pm
===================================================================
--- branches/barnowl_sqlite/owl/perlwrap.pm 2008-01-14 07:46:51 UTC (rev 868)
+++ branches/barnowl_sqlite/owl/perlwrap.pm 2008-01-14 10:04:33 UTC (rev 869)
@@ -288,6 +288,57 @@
#####################################################################
#####################################################################
+package BarnOwl::MessageList;
+
+sub new {
+ my $class = shift;
+ my $self = {messages => {}};
+ return bless $self, $class;
+}
+
+sub get_size {
+ my $self = shift;
+ return scalar keys %{$self->{messages}};
+}
+
+sub start_iterate {
+ my $self = shift;
+ $self->{keys} = [sort {$a <=> $b} keys %{$self->{messages}}];
+ $self->{iterator} = 0;
+}
+
+sub iterate_next {
+ my $self = shift;
+ if($self->{iterator} >= scalar @{$self->{keys}}) {
+ return undef;
+ }
+ return $self->get_by_id($self->{keys}->[$self->{iterator}++]);
+}
+
+sub get_by_id {
+ my $self = shift;
+ my $id = shift;
+ return $self->{messages}{$id};
+}
+
+sub add_message {
+ my $self = shift;
+ my $m = shift;
+ $self->{messages}->{$m->id} = $m;
+}
+
+sub expunge {
+ my $self = shift;
+ for my $message (values %{$self->{messages}}) {
+ if($message->is_deleted) {
+ delete $self->{messages}->{$message->id};
+ }
+ }
+}
+
+#####################################################################
+#####################################################################
+
package BarnOwl::Message;
use POSIX qw(ctime);