Changeset dec60b4


Ignore:
Timestamp:
Jun 17, 2010, 9:41:41 AM (11 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, release-1.7, release-1.8, release-1.9
Children:
3c2c7fc
Parents:
68e5464 (diff), 95414bf (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge branch 'perl-tester'
Files:
20 added
2 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r7d03c8d rde18326  
    3535pm_to_blib
    3636stamp-h1
    37 tester
    3837varstubs.c
  • Makefile.am

    rc45e1eb rdec60b4  
    1212zcrypt_SOURCES = zcrypt.c filterproc.c
    1313
    14 check_PROGRAMS = tester perl_tester
     14check_PROGRAMS = tester.bin
    1515
    1616barnowl_bin_SOURCES = $(BASE_SRCS) \
     
    2121barnowl_bin_LDADD = libfaim/libfaim.a
    2222
    23 tester_SOURCES = $(BASE_SRCS) \
     23tester_bin_SOURCES = $(BASE_SRCS) \
    2424     owl.h owl_perl.h config.h \
    2525     $(GEN_C) $(GEN_H) \
    2626     tester.c
    2727
    28 tester_LDADD = libfaim/libfaim.a
    29 
    30 perl_tester_SOURCES = $(BASE_SRCS) \
    31      owl.h owl_perl.h config.h \
    32      $(GEN_C) $(GEN_H) \
    33      perl_tester.c
    34 
    35 perl_tester_LDADD = libfaim/libfaim.a
     28tester_bin_LDADD = libfaim/libfaim.a
    3629
    3730TESTS=runtests.sh
  • barnowl

    r9a7b4f2 rde18326  
    55
    66SRCDIR=`dirname "${0}"`
    7 EXE="$SRCDIR/barnowl.bin"
     7EXE="$0.bin"
    88
    99if ! test -x "$EXE"; then
  • global.c

    r68e5464 rdec60b4  
    10321032  g->interrupted = 0;
    10331033}
     1034
     1035void owl_global_setup_default_filters(owl_global *g)
     1036{
     1037  int i;
     1038  static const struct {
     1039    const char *name;
     1040    const char *desc;
     1041  } filters[] = {
     1042    { "personal",
     1043      "private ^true$ and ( not type ^zephyr$ or "
     1044      "( class ^message and ( instance ^personal$ or instance ^urgent$ ) ) )" },
     1045    { "trash",
     1046      "class ^mail$ or opcode ^ping$ or type ^admin$ or ( not login ^none$ )" },
     1047    { "wordwrap", "not ( type ^admin$ or type ^zephyr$ )" },
     1048    { "ping", "opcode ^ping$" },
     1049    { "auto", "opcode ^auto$" },
     1050    { "login", "not login ^none$" },
     1051    { "reply-lockout", "class ^noc or class ^mail$" },
     1052    { "out", "direction ^out$" },
     1053    { "aim", "type ^aim$" },
     1054    { "zephyr", "type ^zephyr$" },
     1055    { "none", "false" },
     1056    { "all", "true" },
     1057    { NULL, NULL }
     1058  };
     1059
     1060  owl_function_debugmsg("startup: creating default filters");
     1061
     1062  for (i = 0; filters[i].name != NULL; i++)
     1063    owl_global_add_filter(g, owl_filter_new_fromstring(filters[i].name,
     1064                                                       filters[i].desc));
     1065}
  • owl.c

    r3aa0522 rdec60b4  
    149149}
    150150
    151 static void owl_setup_default_filters(void)
    152 {
    153   int i;
    154   static const struct {
    155     const char *name;
    156     const char *desc;
    157   } filters[] = {
    158     { "personal",
    159       "isprivate ^true$ and ( not type ^zephyr$ or ( class ^message  ) )" },
    160     { "trash",
    161       "class ^mail$ or opcode ^ping$ or type ^admin$ or ( not login ^none$ )" },
    162     { "wordwrap", "not ( type ^admin$ or type ^zephyr$ )" },
    163     { "ping", "opcode ^ping$" },
    164     { "auto", "opcode ^auto$" },
    165     { "login", "not login ^none$" },
    166     { "reply-lockout", "class ^noc or class ^mail$" },
    167     { "out", "direction ^out$" },
    168     { "aim", "type ^aim$" },
    169     { "zephyr", "type ^zephyr$" },
    170     { "none", "false" },
    171     { "all", "true" },
    172     { NULL, NULL }
    173   };
    174 
    175   owl_function_debugmsg("startup: creating default filters");
    176 
    177   for (i = 0; filters[i].name != NULL; i++)
    178     owl_global_add_filter(&g, owl_filter_new_fromstring(filters[i].name,
    179                                                         filters[i].desc));
    180 }
    181151
    182152/*
     
    563533  owl_global_complete_setup(&g);
    564534
    565   owl_setup_default_filters();
     535  owl_global_setup_default_filters(&g);
    566536
    567537  /* set the current view */
  • perlconfig.c

    r3aa0522 rdec60b4  
    1212/* extern XS(boot_DBI); */
    1313
    14 static void owl_perl_xs_init(pTHX)
     14void owl_perl_xs_init(pTHX) /* noproto */
    1515{
    1616  const char *file = __FILE__;
     
    363363  perl_construct(p);
    364364
     365  PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
     366
    365367  owl_global_set_no_have_config(&g);
    366368
  • runtests.sh

    r9f026c1 r5aa33fd  
    11#!/bin/sh
    2 HARNESS_PERL=./perl_tester exec prove t/
     2SRCDIR=`dirname "${0}"`
     3
     4export BARNOWL_DATA_DIR="$SRCDIR/perl/"
     5export BARNOWL_BIN_DIR="$SRCDIR/"
     6
     7HARNESS_PERL=./tester exec prove t/
  • t/00-core-tests.t

    r1cf3f8d3 r95414bf  
    11#!/usr/bin/env perl
    22use File::Basename;
    3 system(dirname($0) . "/../tester");
     3system(dirname($0) . "/../tester", "--builtin");
  • t/mock.pl

    r42ad917 r5aa33fd  
    1 use File::Basename;
    2 use lib (dirname($0) . '/../perl/lib');
    3 
    41package BarnOwl;
    52use strict;
    63use warnings;
    7 use Carp;
    84
    9 sub get_data_dir {"."}
    10 sub get_config_dir {"."}
    11 sub create_style {}
    12 
    13 sub debug {
     5no warnings 'redefine';
     6sub debug($) {
    147    warn "[DEBUG] ", shift, "\n" if $ENV{TEST_VERBOSE};
    158}
    169
    17 sub BarnOwl::Internal::new_command {}
    18 sub BarnOwl::Internal::new_variable_bool {}
    19 sub BarnOwl::Internal::new_variable_int {}
    20 sub BarnOwl::Internal::new_variable_string {}
    21 sub BarnOwl::Editwin::save_excursion(&) {}
    22 
    23 use BarnOwl;
    24 
    25101;
  • tester.c

    r3f6555d rdec60b4  
     1#define OWL_PERL
     2#define WINDOW FAKE_WINDOW
    13#include "owl.h"
     4#undef WINDOW
     5
    26#include <unistd.h>
    37#include <stdlib.h>
    48
     9#undef instr
     10#include <curses.h>
     11
    512owl_global g;
    613
    714int numtests;
    815
     16int owl_regtest(void);
    917int owl_util_regtest(void);
    1018int owl_dict_regtest(void);
     
    1422int owl_editwin_regtest(void);
    1523
     24extern void owl_perl_xs_init(pTHX);
     25
    1626int main(int argc, char **argv, char **env)
    1727{
     28  FILE *rnull;
     29  FILE *wnull;
     30  char *perlerr;
     31  int status = 0;
     32
     33  if (argc <= 1) {
     34    fprintf(stderr, "Usage: %s --builtin|TEST.t|-le CODE\n", argv[0]);
     35    return 1;
     36  }
     37
    1838  /* initialize a fake ncurses, detached from std{in,out} */
    19   FILE *rnull = fopen("/dev/null", "r");
    20   FILE *wnull = fopen("/dev/null", "w");
     39  wnull = fopen("/dev/null", "w");
     40  rnull = fopen("/dev/null", "r");
    2141  newterm("xterm", wnull, rnull);
    2242  /* initialize global structures */
    2343  owl_global_init(&g);
    2444
     45  perlerr = owl_perlconfig_initperl(NULL, &argc, &argv, &env);
     46  if (perlerr) {
     47    endwin();
     48    fprintf(stderr, "Internal perl error: %s\n", perlerr);
     49    status = 1;
     50    goto out;
     51  }
     52
     53  owl_global_complete_setup(&g);
     54  owl_global_setup_default_filters(&g);
     55
     56  owl_view_create(owl_global_get_current_view(&g), "main",
     57                  owl_global_get_filter(&g, "all"),
     58                  owl_global_get_style_by_name(&g, "default"));
     59
     60  owl_function_firstmsg();
     61
     62  ENTER;
     63  SAVETMPS;
     64
     65  if (strcmp(argv[1], "--builtin") == 0) {
     66    status = owl_regtest();
     67  } else if (strcmp(argv[1], "-le") == 0 && argc > 2) {
     68    /*
     69     * 'prove' runs its harness perl with '-le CODE' to get some
     70     * information out.
     71     */
     72    moreswitches("l");
     73    eval_pv(argv[2], true);
     74  } else {
     75    sv_setpv(get_sv("0", false), argv[1]);
     76    sv_setpv(get_sv("main::test_prog", TRUE), argv[1]);
     77
     78    eval_pv("do $main::test_prog; die($@) if($@)", true);
     79  }
     80
     81  status = 0;
     82
     83  FREETMPS;
     84  LEAVE;
     85
     86 out:
     87  perl_destruct(owl_global_get_perlinterp(&g));
     88  perl_free(owl_global_get_perlinterp(&g));
     89  /* probably not necessary, but tear down the screen */
     90  endwin();
     91  fclose(rnull);
     92  fclose(wnull);
     93  return status;
     94}
     95
     96int owl_regtest(void) {
    2597  numtests = 0;
    2698  int numfailures=0;
     
    38110  }
    39111  printf("1..%d\n", numtests);
    40 
    41   /* probably not necessary, but tear down the screen */
    42   endwin();
    43   fclose(rnull);
    44   fclose(wnull);
    45112
    46113  return(numfailures);
  • commands.c

    r7ba9e0de r89ce405  
    106106  OWLCMD_ARGS("zwrite", owl_command_zwrite, OWL_CTX_INTERACTIVE,
    107107              "send a zephyr",
    108               "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [<user> ...] [-m <message...>]",
     108              "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcode] [<user> ...] [-m <message...>]",
    109109              "Zwrite send a zephyr to the one or more users specified.\n\n"
    110110              "The following options are available:\n\n"
     
    138138  OWLCMD_ARGS("zcrypt", owl_command_zcrypt, OWL_CTX_INTERACTIVE,
    139139              "send an encrypted zephyr",
    140               "zcrypt [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [-m <message...>]\n",
     140              "zcrypt [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcode] [-m <message...>]\n",
    141141              "Behaves like zwrite but uses encryption.  Not for use with\n"
    142142              "personal messages\n"),
     
    148148              "allow editing.\n\n"
    149149              "If 'sender' is specified, reply to the sender.\n\n"
    150               "If 'all' or no args are specified, reply publically to the\n"
     150              "If 'all' or no args are specified, reply publicly to the\n"
    151151              "same class/instance for non-personal messages and to the\n"
    152152              "sender for personal messages.\n\n"
     
    266266              "zpunt <class> <instance> [recipient]\n"
    267267              "zpunt <instance>",
    268               "The zpunt command will supress message to the specified\n"
     268              "The zpunt command will suppress messages to the specified\n"
    269269              "zephyr triplet.  In the second usage messages are suppressed\n"
    270270              "for class MESSAGE and the named instance.\n\n"
     
    283283              "punt <filter-text>",
    284284              "punt <filter-text (multiple words)>\n"
    285               "The punt command will supress message to the specified\n"
     285              "The punt command will suppress messages to the specified\n"
    286286              "filter\n\n"
    287287              "SEE ALSO:  unpunt, zpunt, show zpunts\n"),
     
    586586              "name style after the -s argument.\n"
    587587              "\n"
    588               "The other usages listed above are abbreivated forms that simply set\n"
     588              "The other usages listed above are abbreviated forms that simply set\n"
    589589              "the filter of the current view. The -d option allows you to write a\n"
    590590              "filter expression that will be dynamically created by owl and then\n"
     
    594594  OWLCMD_ARGS("smartnarrow", owl_command_smartnarrow, OWL_CTX_INTERACTIVE,
    595595              "view only messages similar to the current message",
    596               "smartnarrow [-i | --instance]  [-r | --relatde]",
     596              "smartnarrow [-i | --instance]  [-r | --related]",
    597597              "If the curmsg is a personal message narrow\n"
    598598              "   to the conversation with that user.\n"
     
    614614              "   message, the filter is to that instance.\n"
    615615              "If the curmsg is a class message, the filter is that class.\n"
    616               "If the curmsg is a class message and '-i' is specied\n"
     616              "If the curmsg is a class message and '-i' is specified\n"
    617617              "    the filter is to that class and instance.\n"),
    618618
     
    674674              "for formatting messages.\n\n"
    675675              "Show variables will list the names of all variables.\n\n"
    676               "Show errors will show a list of errors ecountered by Owl.\n\n"
     676              "Show errors will show a list of errors encountered by Owl.\n\n"
    677677              "SEE ALSO: filter, view, alias, bindkey, help\n"),
    678678 
     
    743743              "set the search highlight string without searching",
    744744              "setsearch <string>",
    745               "The setsearch command highlights all occurences of its\n"
     745              "The setsearch command highlights all occurrences of its\n"
    746746          "argument and makes it the default argument for future\n"
    747747          "search commands, but does not move the cursor.  With\n"
     
    21842184      argc--;
    21852185      argv++;
    2186     } else if (!strcmp(argv[0], "-r")) {
    2187       const char *foo;
    2188       foo=owl_function_create_negative_filter(owl_view_get_filtname(owl_global_get_current_view(&g)));
    2189       owl_function_change_currentview_filter(foo);
    21902186    } else if (!strcmp(argv[0], "-s")) {
    21912187      if (argc<2) {
  • doc/code.txt

    r1286893 r44cc9ab  
    8686             Meta.  At any one time, there is exactly one active
    8787             keymap which determines where keybindings are looked for
    88              (along with its submaps).
     88             (along with its parents).
    8989
    9090list:        Simple list abstraction.  (Uses realloc to resize the list.)
  • functions.c

    r7ba9e0de r13ebf92  
    19991999    pclose(p);
    20002000   
    2001     if (type == OWL_OUTPUT_POPUP) {
    2002       owl_function_popless_text(out);
    2003     } else if (type == OWL_OUTPUT_RETURN) {
     2001    if (type == OWL_OUTPUT_RETURN) {
    20042002      owl_free(newbuff);
    20052003      return out;
    20062004    } else if (type == OWL_OUTPUT_ADMINMSG) {
    20072005      owl_function_adminmsg(buff, out);
    2008     } else {
    2009       owl_function_popless_text(out);
    20102006    }
    20112007    owl_free(out);
     
    20402036    } else if (type == OWL_OUTPUT_RETURN) {
    20412037      return perlout;
    2042     } else {
    2043       owl_function_popless_text(perlout);
    20442038    }
    20452039    owl_free(perlout);
     
    25052499
    25062500  owl_mainwin_redisplay(owl_global_get_mainwin(&g)); 
     2501}
     2502
     2503static char *owl_function_smartfilter_cc(const owl_message *m) {
     2504  const char *ccs;
     2505  char *filtname;
     2506  char *text;
     2507  owl_filter *f;
     2508
     2509  ccs = owl_message_get_attribute_value(m, "zephyr_ccs");
     2510
     2511  filtname = owl_sprintf("conversation-%s", ccs);
     2512  owl_text_tr(filtname, ' ', '-');
     2513
     2514  if (owl_global_get_filter(&g, filtname)) {
     2515    return filtname;
     2516  }
     2517
     2518  text = owl_sprintf("type ^zephyr$ and filter personal and "
     2519                     "zephyr_ccs ^%s%s%s$",
     2520                     owl_getquoting(ccs), ccs, owl_getquoting(ccs));
     2521
     2522  f = owl_filter_new_fromstring(filtname, text);
     2523
     2524  owl_global_add_filter(&g, f);
     2525
     2526  owl_free(text);
     2527
     2528  return filtname;
    25072529}
    25082530
     
    25602582  if (owl_message_is_type_zephyr(m)) {
    25612583    if (owl_message_is_personal(m) || owl_message_is_loginout(m)) {
     2584      if (owl_message_get_attribute_value(m, "zephyr_ccs") != NULL) {
     2585        return owl_function_smartfilter_cc(m);
     2586      }
     2587
    25622588      if (owl_message_is_direction_in(m)) {
    25632589        zperson=short_zuser(owl_message_get_sender(m));
     
    28532879    km = owl_keyhandler_get_keymap(kh, kmname);
    28542880    owl_fmtext_append_bold(&fm, "\n\n----------------------------------------------------------------------------------------------------\n\n");
    2855     owl_keymap_get_details(km, &fm);   
     2881    owl_keymap_get_details(km, &fm, 0);
    28562882  }
    28572883  owl_fmtext_append_normal(&fm, "\n");
     
    28792905  km = owl_keyhandler_get_keymap(owl_global_get_keyhandler(&g), name);
    28802906  if (km) {
    2881     owl_keymap_get_details(km, &fm);
     2907    owl_keymap_get_details(km, &fm, 1);
    28822908  } else {
    28832909    owl_fmtext_append_normal(&fm, "No such keymap...\n");
  • keymap.c

    r8a921b5 r44cc9ab  
    11#include <string.h>
    22#include "owl.h"
     3
     4static void _owl_keymap_format_bindings(const owl_keymap *km, owl_fmtext *fm);
     5static void _owl_keymap_format_with_parents(const owl_keymap *km, owl_fmtext *fm);
    36
    47/* returns 0 on success */
     
    912  if ((km->desc = owl_strdup(desc)) == NULL) return(-1);
    1013  if (0 != owl_list_create(&km->bindings)) return(-1);
    11   km->submap = NULL;
     14  km->parent = NULL;
    1215  km->default_fn = default_fn;
    1316  km->prealways_fn = prealways_fn;
     
    2427}
    2528
    26 void owl_keymap_set_submap(owl_keymap *km, const owl_keymap *submap)
    27 {
    28   km->submap = submap;
     29void owl_keymap_set_parent(owl_keymap *km, const owl_keymap *parent)
     30{
     31  km->parent = parent;
    2932}
    3033
     
    8689
    8790/* Appends details about the keymap to fm */
    88 void owl_keymap_get_details(const owl_keymap *km, owl_fmtext *fm)
    89 {
    90   int i, nbindings;
    91   const owl_keybinding *kb;
    92  
     91void owl_keymap_get_details(const owl_keymap *km, owl_fmtext *fm, int recurse)
     92{
    9393  owl_fmtext_append_bold(fm, "KEYMAP - ");
    9494  owl_fmtext_append_bold(fm, km->name);
     
    9999    owl_fmtext_append_normal(fm, "\n");
    100100  }
    101   if (km->submap) {
    102     owl_fmtext_append_normal(fm, OWL_TABSTR "Has submap: ");
    103     owl_fmtext_append_normal(fm, km->submap->name);
     101  if (km->parent) {
     102    owl_fmtext_append_normal(fm, OWL_TABSTR "Has parent: ");
     103    owl_fmtext_append_normal(fm, km->parent->name);
    104104    owl_fmtext_append_normal(fm, "\n");
    105105  }
     
    119119
    120120  owl_fmtext_append_bold(fm, "\nKey bindings:\n\n"); 
     121  if (recurse) {
     122    _owl_keymap_format_with_parents(km, fm);
     123  } else {
     124    _owl_keymap_format_bindings(km, fm);
     125  }
     126}
     127
     128static void _owl_keymap_format_with_parents(const owl_keymap *km, owl_fmtext *fm)
     129{
     130  while (km) {
     131    _owl_keymap_format_bindings(km, fm);
     132    km = km->parent;
     133    if (km) {
     134      owl_fmtext_append_bold(fm, "\nInherited from ");
     135      owl_fmtext_append_bold(fm, km->name);
     136      owl_fmtext_append_bold(fm, ":\n\n");
     137    }
     138  }
     139}
     140
     141static void _owl_keymap_format_bindings(const owl_keymap *km, owl_fmtext *fm)
     142{
     143  int i, nbindings;
     144  const owl_keybinding *kb;
     145 
    121146  nbindings = owl_list_get_size(&km->bindings);
    122147  for (i=0; i<nbindings; i++) {
     
    248273  }
    249274
    250   /* deal with the always_fn for the map and submaps */
    251   for (km=kh->active; km; km=km->submap) {
     275  /* deal with the always_fn for the map and parents */
     276  for (km=kh->active; km; km=km->parent) {
    252277    if (km->prealways_fn) {
    253278      km->prealways_fn(j);
     
    256281
    257282  /* search for a match.  goes through active keymap and then
    258    * through submaps... TODO:  clean this up so we can pull
     283   * through parents... TODO:  clean this up so we can pull
    259284   * keyhandler and keymap apart.  */
    260   for (km=kh->active; km; km=km->submap) {
     285  for (km=kh->active; km; km=km->parent) {
    261286    for (i=owl_list_get_size(&km->bindings)-1; i>=0; i--) {
    262287      kb = owl_list_get_element(&km->bindings, i);
  • keys.c

    r8a5b5a1 r44cc9ab  
    3030       "Text editing and command window",
    3131       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
    32   owl_keymap_set_submap(km_editwin, km_global);
     32  owl_keymap_set_parent(km_editwin, km_global);
    3333  /*
    3434  BIND_CMD("F1",          "help",            "");
     
    9999       "Multi-line text editing",
    100100       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
    101   owl_keymap_set_submap(km_ew_multi, km_editwin);
     101  owl_keymap_set_parent(km_ew_multi, km_editwin);
    102102
    103103  BIND_CMD("UP",      "edit:move-up-line", "");
     
    129129       "Single-line text editing",
    130130       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
    131   owl_keymap_set_submap(km_ew_onel, km_editwin);
     131  owl_keymap_set_parent(km_ew_onel, km_editwin);
    132132
    133133  BIND_CMD("C-u",         "edit:delete-all", "Clears the entire line");
     
    154154       "Single-line response to question",
    155155       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
    156   owl_keymap_set_submap(km_ew_onel, km_editwin);
     156  owl_keymap_set_parent(km_ew_onel, km_editwin);
    157157
    158158  BIND_CMD("C-u",         "edit:delete-all", "Clears the entire line");
     
    169169       "Pop-up window (eg, help)",
    170170       owl_keys_default_invalid, NULL, owl_keys_popless_postalways);
    171   owl_keymap_set_submap(km_viewwin, km_global);
     171  owl_keymap_set_parent(km_viewwin, km_global);
    172172
    173173  BIND_CMD("SPACE",       "popless:scroll-down-page", "");
     
    222222        "Main window / message list",
    223223        owl_keys_default_invalid, owl_keys_recwin_prealways, NULL);
    224   owl_keymap_set_submap(km_mainwin, km_global);
     224  owl_keymap_set_parent(km_mainwin, km_global);
    225225  BIND_CMD("C-x C-c", "start-command quit", "");
    226226  BIND_CMD("F1",      "help",           "");
  • logging.c

    r91634ec r839697d  
    128128  char filename[MAXPATHLEN], *logpath;
    129129  char *to, *temp;
     130  GList *cc;
    130131
    131132  /* expand ~ in path names */
     
    135136  if (owl_message_is_type_zephyr(m)) {
    136137    /* If this has CC's, do all but the "recipient" which we'll do below */
    137     to = owl_message_get_cc_without_recipient(m);
    138     if (to != NULL) {
    139       temp = strtok(to, " ");
    140       while (temp != NULL) {
    141           temp = short_zuser(temp);
    142           snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
    143           owl_log_append(m, filename);
    144           temp = strtok(NULL, " ");
    145       }
    146       owl_free(to);
    147     }
     138    cc = owl_message_get_cc_without_recipient(m);
     139    while (cc != NULL) {
     140      temp = short_zuser(cc->data);
     141      snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
     142      owl_log_append(m, filename);
     143
     144      owl_free(cc->data);
     145      cc = g_list_delete_link(cc, cc);
     146    }
     147
    148148    to = short_zuser(owl_message_get_recipient(m));
    149149  } else if (owl_message_is_type_jabber(m)) {
     
    325325     * the sender, as well.
    326326     */
    327     char *cc, *temp;
     327    char *temp;
     328    GList *cc;
    328329    cc = owl_message_get_cc_without_recipient(m);
    329     if (cc != NULL) {
    330       temp = strtok(cc, " ");
    331       while (temp != NULL) {
    332         temp = short_zuser(temp);
    333         if (strcasecmp(temp, frombuff) != 0) {
    334           snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
    335           owl_log_append(m, filename);
    336         }
    337         temp = strtok(NULL, " ");
     330    while (cc != NULL) {
     331      temp = short_zuser(cc->data);
     332      if (strcasecmp(temp, frombuff) != 0) {
     333        snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
     334        owl_log_append(m, filename);
    338335      }
    339       owl_free(cc);
     336
     337      owl_free(cc->data);
     338      cc = g_list_delete_link(cc, cc);
    340339    }
    341340  }
  • message.c

    r9a7b4f2 r89ab5c8  
    6161  owl_pair *p = NULL, *pair = NULL;
    6262
     63  attrname = g_intern_string(attrname);
     64
    6365  /* look for an existing pair with this key, */
    6466  j=owl_list_get_size(&(m->attributes));
    6567  for (i=0; i<j; i++) {
    6668    p=owl_list_get_element(&(m->attributes), i);
    67     if (!strcmp(owl_pair_get_key(p), attrname)) {
     69    if (owl_pair_get_key(p) == attrname) {
    6870      owl_free(owl_pair_get_value(p));
    6971      pair = p;
     
    7476  if(pair ==  NULL) {
    7577    pair = owl_malloc(sizeof(owl_pair));
    76     owl_pair_create(pair, owl_global_intern(&g, attrname), NULL);
     78    owl_pair_create(pair, attrname, NULL);
    7779    owl_list_append_element(&(m->attributes), pair);
    7880  }
     
    8789  int i, j;
    8890  owl_pair *p;
     91  GQuark quark;
     92
     93  quark = g_quark_try_string(attrname);
     94  if (quark == 0)
     95    /* don't bother inserting into string table */
     96    return NULL;
     97  attrname = g_quark_to_string(quark);
    8998
    9099  j=owl_list_get_size(&(m->attributes));
    91100  for (i=0; i<j; i++) {
    92101    p=owl_list_get_element(&(m->attributes), i);
    93     if (!strcmp(owl_pair_get_key(p), attrname)) {
     102    if (owl_pair_get_key(p) == attrname) {
    94103      return(owl_pair_get_value(p));
    95104    }
     
    496505void owl_message_set_hostname(owl_message *m, const char *hostname)
    497506{
    498   m->hostname=owl_global_intern(&g, hostname);
     507  m->hostname = g_intern_string(hostname);
    499508}
    500509
     
    584593
    585594/* caller must free return value */
    586 char *owl_message_get_cc_without_recipient(const owl_message *m)
    587 {
    588   char *cc, *out, *end, *shortuser, *recip;
     595GList *owl_message_get_cc_without_recipient(const owl_message *m)
     596{
     597  char *cc, *shortuser, *recip;
    589598  const char *user;
     599  GList *out = NULL;
    590600
    591601  cc = owl_message_get_cc(m);
     
    594604
    595605  recip = short_zuser(owl_message_get_recipient(m));
    596   out = owl_malloc(strlen(cc) + 2);
    597   end = out;
    598606
    599607  user = strtok(cc, " ");
     
    601609    shortuser = short_zuser(user);
    602610    if (strcasecmp(shortuser, recip) != 0) {
    603       strcpy(end, user);
    604       end[strlen(user)] = ' ';
    605       end += strlen(user) + 1;
     611      out = g_list_prepend(out, owl_strdup(user));
    606612    }
    607613    owl_free(shortuser);
    608614    user = strtok(NULL, " ");
    609615  }
    610   end[0] = '\0';
    611616
    612617  owl_free(recip);
    613618  owl_free(cc);
    614 
    615   if (strlen(out) == 0) {
    616     owl_free(out);
    617     out = NULL;
    618   }
    619619
    620620  return(out);
     
    732732  owl_message_set_recipient(m, "looprecip");
    733733  owl_message_set_isprivate(m);
     734}
     735
     736void owl_message_save_ccs(owl_message *m) {
     737  GList *cc;
     738  char *tmp;
     739
     740  cc = owl_message_get_cc_without_recipient(m);
     741
     742  if (cc != NULL) {
     743    GString *recips = g_string_new("");
     744    cc = g_list_prepend(cc, short_zuser(owl_message_get_sender(m)));
     745    cc = g_list_prepend(cc, short_zuser(owl_message_get_recipient(m)));
     746    cc = g_list_sort(cc, (GCompareFunc)strcasecmp);
     747
     748    while(cc != NULL) {
     749      /* Collapse any identical entries */
     750      while (cc->next && strcasecmp(cc->data, cc->next->data) == 0) {
     751        owl_free(cc->data);
     752        cc = g_list_delete_link(cc, cc);
     753      }
     754
     755      tmp = short_zuser(cc->data);
     756      g_string_append(recips, tmp);
     757
     758      owl_free(tmp);
     759      owl_free(cc->data);
     760      cc = g_list_delete_link(cc, cc);
     761
     762      if (cc)
     763        g_string_append_c(recips, ' ');
     764    }
     765
     766    owl_message_set_attribute(m, "zephyr_ccs", recips->str);
     767    g_string_free(recips, true);
     768  }
    734769}
    735770
     
    869904    }
    870905  }
     906
     907  owl_message_save_ccs(m);
    871908}
    872909#else
     
    9631000    owl_message_set_isprivate(m);
    9641001  }
     1002
     1003  owl_message_save_ccs(m);
    9651004}
    9661005
  • owl.h

    r7ba9e0de r68e5464  
    476476  char     *desc;               /* description */
    477477  owl_list  bindings;           /* key bindings */
    478   const struct _owl_keymap *submap;     /* submap */
     478  const struct _owl_keymap *parent;     /* parent */
    479479  void (*default_fn)(owl_input j);      /* default action (takes a keypress) */
    480480  void (*prealways_fn)(owl_input  j);   /* always called before a keypress is received */
     
    521521  short **pairs;
    522522} owl_colorpair_mgr;
    523 
    524 typedef struct _owl_obarray {
    525   owl_list strings;
    526 } owl_obarray;
    527523
    528524typedef struct _owl_io_dispatch {
     
    599595  owl_colorpair_mgr cpmgr;
    600596  pid_t newmsgproc_pid;
    601   int malloced, freed;
    602597  owl_regex search_re;
    603598  aim_session_t aimsess;
     
    610605  char *aim_screenname_for_filters;     /* currently logged in AIM screen name */
    611606  owl_buddylist buddylist;  /* list of logged in AIM buddies */
    612   owl_list messagequeue;    /* for queueing up aim and other messages */
     607  GQueue *messagequeue;     /* for queueing up aim and other messages */
    613608  owl_dict styledict;       /* global dictionary of available styles */
    614609  char *response;           /* response to the last question asked */
     
    623618  int pseudologin_notify;
    624619  struct termios startup_tio;
    625   owl_obarray obarray;
    626620  owl_list io_dispatch_list;
    627621  owl_list psa_list;
  • perl/lib/BarnOwl/Hooks.pm

    rb30c256 r3aa0522  
    7979our %EXPORT_TAGS = (all => [@EXPORT_OK]);
    8080
     81use BarnOwl::MainLoopCompatHook;
     82
    8183our $startup = BarnOwl::Hook->new;
    8284our $shutdown = BarnOwl::Hook->new;
    8385our $receiveMessage = BarnOwl::Hook->new;
    8486our $newMessage = BarnOwl::Hook->new;
    85 our $mainLoop = BarnOwl::Hook->new;
     87our $mainLoop = BarnOwl::MainLoopCompatHook->new;
    8688our $getBuddyList = BarnOwl::Hook->new;
    8789our $getQuickstart = BarnOwl::Hook->new;
     
    162164    }
    163165   
     166    $mainLoop->check_owlconf();
    164167    $startup->run(0);
    165168    BarnOwl::startup() if *BarnOwl::startup{CODE};
     
    186189   
    187190    BarnOwl::new_msg($m) if *BarnOwl::new_msg{CODE};
    188 }
    189 
    190 sub _mainloop_hook {
    191     $mainLoop->run;
    192     BarnOwl::mainloop_hook() if *BarnOwl::mainloop_hook{CODE};
    193191}
    194192
  • perl/lib/BarnOwl/Message/Generic.pm

    ree183be r5d1324f  
    66use base qw( BarnOwl::Message );
    77
     8sub body { "" }
     9
    810
    9111;
  • perl/lib/BarnOwl/Style/Default.pm

    r0fe69d2 r08544e0  
    3232    my $m = shift;
    3333    return $m->is_personal && $m->direction eq "in";
     34}
     35
     36sub maybe {
     37    my $x = shift;
     38    return defined($x) ? $x : "";
    3439}
    3540
     
    99104            $header .= ' / ' . $self->humanize($m->subcontext, 1);
    100105        }
    101         $header .= ' / @b{' . $m->pretty_sender . '}';
     106        $header .= ' / @b{' . maybe($m->pretty_sender) . '}';
    102107    }
    103108
  • perl/lib/BarnOwl/Timer.pm

    ree183be r8d16e58  
    2121}
    2222
     23sub stop {
     24    my $self = shift;
     25    if(defined($self->{timer})) {
     26        BarnOwl::Internal::remove_timer($self->{timer});
     27        undef $self->{timer};
     28    }
     29}
     30
    2331sub do_callback {
    2432    my $self = shift;
     
    2836sub DESTROY {
    2937    my $self = shift;
    30     if(defined($self->{timer})) {
    31         BarnOwl::Internal::remove_timer($self->{timer});
    32     }
     38    $self->stop;
    3339}
    3440
  • perl/modules/Jabber/lib/BarnOwl/Message/Jabber.pm

    rc854e74 r2f25537  
    2020sub to { shift->{to} };
    2121sub room { shift->{room} };
     22sub nick { shift->{nick} };
    2223sub subject { shift->{subject} };
    2324sub status { shift->{status} }
     
    4142sub long_sender {
    4243    my $self = shift;
     44    if ($self->jtype eq 'groupchat' && $self->nick) {
     45        my $from_jid = Net::Jabber::JID->new($self->from);
     46        if ($from_jid->GetJID('base') eq $self->room &&
     47            $from_jid->GetResource() eq $self->nick) {
     48            return $self->nick;
     49        }
     50    }
    4351    return $self->from;
    4452}
     
    7785    } elsif ($self->jtype eq 'groupchat') {
    7886        my $room = $self->room;
    79         $filter = "jabber-room-$room";
    80         BarnOwl::command(qw[filter], $filter,
    81                          qw[type ^jabber$ and room], "^\Q$room\E\$");
     87        if ($inst) {
     88            my $subject = $self->subject;
     89            $filter = "jabber-room-$room-subject-$subject";
     90            BarnOwl::command(qw[filter], $filter,
     91                             qw[type ^jabber$ and room], "^\Q$room\E\$",
     92                             qw[and subject], "^\Q$subject\E\$");
     93        } else {
     94            $filter = "jabber-room-$room";
     95            BarnOwl::command(qw[filter], $filter,
     96                             qw[type ^jabber$ and room], "^\Q$room\E\$");
     97        }
    8298        return $filter;
    8399    } elsif ($self->login ne 'none') {
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm

    r8789410 r2f25537  
    285285        {
    286286            summary => "Send a Jabber Message",
    287             usage   => "jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]"
     287            usage   => "jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>] [-m <message>]"
    288288        }
    289289    );
     
    308308            description => "jmuc sends Jabber commands related to MUC.\n\n"
    309309              . "The following commands are available\n\n"
    310               . "join <muc>  Join a MUC.\n\n"
     310              . "join <muc>[/<nick>]\n"
     311              . "            Join a MUC (with a given nickname, or otherwise your JID).\n\n"
    311312              . "part <muc>  Part a MUC.\n"
    312313              . "            The MUC is taken from the current message if not supplied.\n\n"
     
    377378        my $cjidStr = $conn->baseJIDExists($jidStr);
    378379        if ($cjidStr) {
    379             BarnOwl::error("Already logged in as $cjidStr.");
    380             return;
     380            die("Already logged in as $cjidStr.\n");
    381381        }
    382382    }
     
    387387
    388388    if ( !$uid || !$componentname ) {
    389         BarnOwl::error("usage: $cmd JID");
    390         return;
     389        die("usage: $cmd JID\n");
    391390    }
    392391
    393392    if ( $conn->jidActive($jidStr) ) {
    394         BarnOwl::error("Already logged in as $jidStr.");
    395         return;
     393        die("Already logged in as $jidStr.\n");
    396394    } elsif ($conn->jidExists($jidStr)) {
    397395        return $conn->tryReconnect($jidStr, 1);
     
    526524sub cmd_jlist {
    527525    if ( !( scalar $conn->getJIDs() ) ) {
    528         BarnOwl::error("You are not logged in to Jabber.");
    529         return;
     526        die("You are not logged in to Jabber.\n");
    530527    }
    531528    BarnOwl::popless_ztext( onGetBuddyList() );
     
    534531sub cmd_jwrite {
    535532    if ( !$conn->connected() ) {
    536         BarnOwl::error("You are not logged in to Jabber.");
    537         return;
     533        die("You are not logged in to Jabber.\n");
    538534    }
    539535
     
    543539    my $jwrite_thread  = "";
    544540    my $jwrite_subject = "";
     541    my $jwrite_body;
    545542    my ($to, $from);
    546543    my $jwrite_type    = "chat";
     
    554551        'subject=s' => \$jwrite_subject,
    555552        'account=s' => \$from,
    556         'id=s'     =>  \$jwrite_sid,
     553        'id=s'      => \$jwrite_sid,
     554        'message=s' => \$jwrite_body,
    557555    ) or die("Usage: jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]\n");
    558556    $jwrite_type = 'groupchat' if $gc;
    559557
    560558    if ( scalar @ARGV != 1 ) {
    561         BarnOwl::error(
    562             "Usage: jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]");
    563         return;
     559        die("Usage: jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]\n");
    564560    }
    565561    else {
     
    570566
    571567    unless(scalar @candidates) {
    572         die("Unable to resolve JID $to");
     568        die("Unable to resolve JID $to\n");
    573569    }
    574570
     
    577573    unless(scalar @candidates) {
    578574        if(!$from) {
    579             die("You must specify an account with -a");
     575            die("You must specify an account with -a\n");
    580576        } else {
    581             die("Unable to resolve account $from");
     577            die("Unable to resolve account $from\n");
    582578        }
    583579    }
     
    594590        type    => $jwrite_type
    595591    };
     592
     593    if (defined($jwrite_body)) {
     594        process_owl_jwrite($jwrite_body);
     595        return;
     596    }
    596597
    597598    if(scalar @candidates > 1) {
     
    631632    my $func = $jmuc_commands{$cmd};
    632633    if ( !$func ) {
    633         BarnOwl::error("jmuc: Unknown command: $cmd");
    634         return;
     634        die("jmuc: Unknown command: $cmd\n");
    635635    }
    636636
     
    654654        }
    655655        else {
    656             BarnOwl::error('You must specify an account with -a <jid>');
     656            die("You must specify an account with -a <jid>\n");
    657657        }
    658658        return $func->( $jid, $muc, @ARGV );
     
    667667
    668668    $muc = shift @ARGV
    669       or die("Usage: jmuc join <muc> [-p <password>] [-a <account>]");
     669      or die("Usage: jmuc join <muc> [-p <password>] [-a <account>]\n");
    670670
    671671    die("Error: Must specify a fully-qualified MUC name (e.g. barnowl\@conference.mit.edu)\n")
     
    680680                                                   MaxChars => 0
    681681                                                  });
    682     $completion_jids{$muc} = 1;
     682    $completion_jids{$muc->GetJID('base')} = 1;
    683683    return;
    684684}
     
    688688
    689689    $muc = shift @args if scalar @args;
    690     die("Usage: jmuc part [<muc>] [-a <account>]") unless $muc;
     690    die("Usage: jmuc part [<muc>] [-a <account>]\n") unless $muc;
    691691
    692692    if($conn->getConnectionFromJID($jid)->MUCLeave(JID => $muc)) {
    693693        queue_admin_msg("$jid has left $muc.");
    694694    } else {
    695         die("Error: Not joined to $muc");
     695        die("Error: Not joined to $muc\n");
    696696    }
    697697}
     
    703703    $muc = shift @args if scalar @args;
    704704
    705     die('Usage: jmuc invite <jid> [<muc>] [-a <account>]')
     705    die("Usage: jmuc invite <jid> [<muc>] [-a <account>]\n")
    706706      unless $muc && $invite_jid;
    707707
     
    718718    my ( $jid, $muc, @args ) = @_;
    719719    $muc = shift @args if scalar @args;
    720     die("Usage: jmuc configure [<muc>]") unless $muc;
     720    die("Usage: jmuc configure [<muc>]\n") unless $muc;
    721721    my $iq = Net::Jabber::IQ->new();
    722722    $iq->SetTo($muc);
     
    759759
    760760    $muc = shift @args if scalar @args;
    761     die("Usage: jmuc presence [<muc>]") unless $muc;
     761    die("Usage: jmuc presence [<muc>]\n") unless $muc;
    762762
    763763    if ($muc eq '-a') {
     
    774774    else {
    775775        my $m = $conn->getConnectionFromJID($jid)->FindMUC(jid => $muc);
    776         die("No such muc: $muc") unless $m;
     776        die("No such muc: $muc\n") unless $m;
    777777        BarnOwl::popless_ztext(jmuc_presence_single($m));
    778778    }
     
    801801    my $func = $jroster_commands{$cmd};
    802802    if ( !$func ) {
    803         BarnOwl::error("jroster: Unknown command: $cmd");
    804         return;
     803        die("jroster: Unknown command: $cmd\n");
    805804    }
    806805
     
    825824        }
    826825        else {
    827             BarnOwl::error('You must specify an account with -a <jid>');
     826            die("You must specify an account with -a <jid>\n");
    828827        }
    829828        return $func->( $jid, $name, \@groups, $purgeGroups,  @ARGV );
     
    849848    }
    850849    else {
    851         BarnOwl::error('You must specify an account with -a <jid>');
     850        die("You must specify an account with -a <jid>\n");
    852851    }
    853852
     
    12341233        $completion_jids{$room} = 1;
    12351234
     1235        my $muc;
     1236        if ($dir eq 'in') {
     1237            my $connection = $conn->getConnectionFromSid($props{sid});
     1238            $muc = $connection->FindMUC(jid => $from);
     1239        } else {
     1240            my $connection = $conn->getConnectionFromJID($props{from});
     1241            $muc = $connection->FindMUC(jid => $to);
     1242        }
     1243        $props{from} = $muc->GetFullJID($from) || $props{from};
    12361244        $props{sender} = $nick || $room;
    12371245        $props{recipient} = $room;
     
    13311339        return $givenJIDStr if ($conn->jidExists($givenJIDStr) );
    13321340        return resolveConnectedJID($givenJID->GetJID('base')) if $loose;
    1333         die("Invalid account: $givenJIDStr");
     1341        die("Invalid account: $givenJIDStr\n");
    13341342    }
    13351343
     
    13841392        # Not one of ours.
    13851393        else {
    1386             die("Invalid account: $givenJIDStr");
     1394            die("Invalid account: $givenJIDStr\n");
    13871395        }
    13881396
     
    14301438    if($from) {
    14311439        $from_jid = resolveConnectedJID($from, 1);
    1432         die("Unable to resolve account $from") unless $from_jid;
     1440        die("Unable to resolve account $from\n") unless $from_jid;
    14331441        $to_jid = resolveDestJID($to, $from_jid);
    14341442        push @matches, [$from_jid, $to_jid] if $to_jid;
  • perl/modules/Makefile.am

    r636de2a r1fd469d4  
    1 MODULES = Jabber IRC WordWrap
     1MODULES = Jabber IRC WordWrap Twitter
    22
    33EXTRA_DIST = $(MODULES:=/Makefile.PL) $(MODULES:=/inc) $(MODULES:=/lib)
  • variable.c

    r3687413 rd544237  
    110110
    111111  OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
    112                "specifices which kind of messages should be logged",
     112               "specifies which kind of messages should be logged",
    113113               "Can be one of 'both', 'in', or 'out'.  If 'in' is\n"
    114114               "selected, only incoming messages are logged, if 'out'\n"
     
    138138                    "location of users in your .anyone file.  If a user is present\n"
    139139                    "but sent no login message, or a user is not present that sent no\n"
    140                     "logout message, a pseudo login or logout message wil be created\n",
     140                    "logout message, a pseudo login or logout message will be created\n",
    141141                    NULL, owl_variable_pseudologins_set, NULL),
    142142
     
    151151
    152152                 "If non empty, any messages matching the given filter will be logged.\n"
    153                  "This is a completely separate mechanisim from the other logging\n"
     153                 "This is a completely separate mechanism from the other logging\n"
    154154                 "variables like logging, classlogging, loglogins, loggingdirection,\n"
    155155                 "etc.  If you want this variable to control all logging, make sure\n"
     
    198198  OWLVAR_PATH( "newmsgproc" /* %OwlVarStub:newmsgproc */, NULL,
    199199               "name of a program to run when new messages are present",
    200                "The named program will be run when owl recevies new.\n"
     200               "The named program will be run when owl receives new\n"
    201201               "messages.  It will not be run again until the first\n"
    202202               "instance exits"),
     
    213213                 "Called every time you start a zephyrgram without an\n"
    214214                 "explicit zsig.  The default setting implements the policy\n"
    215                  "descripted in the documentation for the 'zsig' variable.\n"),
     215                 "described in the documentation for the 'zsig' variable.\n"),
    216216
    217217  OWLVAR_STRING( "zsig" /* %OwlVarStub */, "",
     
    297297              "number of seconds after AIM login to ignore login messages",
    298298              "This specifies the number of seconds to wait after an\n"
    299               "AIM login before allowing the recipt of AIM login notifications.\n"
     299              "AIM login before allowing the receipt of AIM login notifications.\n"
    300300              "By default this is set to 15.  If you would like to view login\n"
    301301              "notifications of buddies as soon as you login, set it to 0 instead."),
  • zephyr.c

    r3687413 r922f589  
    258258
    259259  if (stat(subsfile, &statbuff) != 0) {
     260    owl_free(subsfile);
    260261    if (error_on_nofile == 1)
    261262      return -1;
     
    373374  subsfile = owl_zephyr_dotfile(".anyone", filename);
    374375
    375   if (stat(subsfile, &statbuff) == -1)
     376  if (stat(subsfile, &statbuff) == -1) {
     377    owl_free(subsfile);
    376378    return 0;
     379  }
    377380
    378381  ZResetAuthentication();
Note: See TracChangeset for help on using the changeset viewer.