Changeset db0ac7e


Ignore:
Timestamp:
May 3, 2008, 12:52:32 PM (12 years ago)
Author:
Alejandro R. Sedeño <asedeno@mit.edu>
Branches:
master, barnowl_perlaim, debian, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
feabce2
Parents:
d9337637 (diff), 811ad93 (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:
Merged revisions 983-1032 via svnmerge from 
file:///afs/sipb.mit.edu/project/barnowl/src/svn/trunk

........
  r985 | nelhage | 2008-03-11 12:38:20 -0400 (Tue, 11 Mar 2008) | 2 lines
  
  Generate less ugly error spew if a module fails to load
........
  r986 | geofft | 2008-03-13 15:56:20 -0400 (Thu, 13 Mar 2008) | 1 line
  
  Added :webzephyr command with keybinding W.
........
  r987 | asedeno | 2008-03-18 23:57:24 -0400 (Tue, 18 Mar 2008) | 2 lines
  
  Fix a race condition in which zephyrs received during init
  are not noticed until the next zephyr after entering the mainloop.
........
  r988 | geofft | 2008-03-19 15:46:43 -0400 (Wed, 19 Mar 2008) | 6 lines
  
  IRC: explicitly include the network (-a $alias) in reply commands.
  
  This may be unnecessary because :irc-msg looks at getcurmsg() if it cannot
  automatically determine the network.
........
  r989 | geofft | 2008-03-21 14:47:51 -0400 (Fri, 21 Mar 2008) | 1 line
  
  syntax error.
........
  r990 | nelhage | 2008-03-26 02:24:26 -0400 (Wed, 26 Mar 2008) | 2 lines
  
  Fix sending jabbers to JIDs beginning with `+'
........
  r994 | nelhage | 2008-03-29 17:02:05 -0400 (Sat, 29 Mar 2008) | 3 lines
  
  Compile zcrypt.c with -w so I don't get all these warnings in my
  compile output whenever I change any headers
........
  r998 | geofft | 2008-03-31 01:59:47 -0400 (Mon, 31 Mar 2008) | 1 line
  
  Implement /me for outgoing IRC messages
........
  r999 | geofft | 2008-03-31 09:58:56 -0400 (Mon, 31 Mar 2008) | 1 line
  
  I think this fixes the resizing bug.
........
  r1000 | nelhage | 2008-03-31 11:29:29 -0400 (Mon, 31 Mar 2008) | 2 lines
  
  Make `svkversion' handle exported trees better
........
  r1001 | nelhage | 2008-03-31 11:52:39 -0400 (Mon, 31 Mar 2008) | 2 lines
  
  Add a makefile rule to support emacs flymake-mode
........
  r1015 | nelhage | 2008-04-04 14:58:45 -0400 (Fri, 04 Apr 2008) | 3 lines
  
  Bind the combinations the iPhone sends for arrow keys [probably other
  terminals, too]
........
  r1018 | shadow | 2008-04-08 13:57:49 -0400 (Tue, 08 Apr 2008) | 2 lines
  
  avoid null pointer dereference if msg is NULL (or a 0 length is claimed)
........
  r1019 | nelhage | 2008-04-09 18:08:26 -0400 (Wed, 09 Apr 2008) | 2 lines
  
  Fix some stupid typos
........
  r1020 | chmrr | 2008-04-09 18:16:02 -0400 (Wed, 09 Apr 2008) | 3 lines
  
   r29300@kohr-ah:  chmrr | 2008-04-09 18:14:37 -0400
    * It's apparently a popular typo
........
  r1022 | asedeno | 2008-04-16 17:05:36 -0400 (Wed, 16 Apr 2008) | 2 lines
  
  Jabber reply bugfix.
  Reported by several people, resolved by arolfe.
........
  r1023 | nelhage | 2008-04-28 23:33:03 -0400 (Mon, 28 Apr 2008) | 3 lines
  
  Initialized merge tracking via "svnmerge" with revisions "735" from 
  svn+ssh://lunatique.mit.edu/mit/barnowl/src/svn/branches/barnowl_unicode
........
  r1024 | nelhage | 2008-04-28 23:33:12 -0400 (Mon, 28 Apr 2008) | 3 lines
  
  Initialized merge tracking via "svnmerge" with revisions "735" from 
  svn+ssh://lunatique.mit.edu/mit/barnowl/src/svn/branches/barnowl_sqlite
........
  r1025 | nelhage | 2008-04-29 01:21:12 -0400 (Tue, 29 Apr 2008) | 2 lines
  
  Clone owl_perl from the sqlite branch because I'm about to make use of it.
........
  r1026 | nelhage | 2008-04-29 01:21:13 -0400 (Tue, 29 Apr 2008) | 4 lines
  
  Initial step of moving styles from the current mishmash of different
  options to a unified object interface.
  No backwards-compatibility support yet.
........
  r1027 | nelhage | 2008-04-29 01:21:15 -0400 (Tue, 29 Apr 2008) | 2 lines
  
  Implement back-compat with old-style owl::format_msg() styles
........
  r1028 | nelhage | 2008-04-29 01:21:16 -0400 (Tue, 29 Apr 2008) | 2 lines
  
  Remove nearly all references to the "basic" style.
........
  r1029 | nelhage | 2008-04-29 01:21:17 -0400 (Tue, 29 Apr 2008) | 2 lines
  
  Support the `style' command again. Note that it is deprecated.
........
  r1031 | nelhage | 2008-04-30 13:29:45 -0400 (Wed, 30 Apr 2008) | 2 lines
  
  Refactor default style code somewhat to be more easily extensible
........
Files:
3 added
1 deleted
38 edited
1 moved

Legend:

Unmodified
Added
Removed
  • Makefile.in

    r5f3168a rdb0ac7e  
    2525     regex.c history.c view.c dict.c variable.c filterelement.c pair.c \
    2626     keypress.c keymap.c keybinding.c cmd.c context.c zcrypt.c \
    27      aim.c buddy.c buddylist.c timer.c style.c stylefunc.c errqueue.c \
     27     aim.c buddy.c buddylist.c timer.c style.c errqueue.c \
    2828     zbuddylist.c muxevents.c popexec.c obarray.c select.c wcwidth.c \
    2929     glib_compat.c
     
    4848HEADERS=$(GEN_H) owl.h config.h test.h
    4949
    50 %.o: %.c $(HEADERS)
    51         $(CC) -c $(CFLAGS) $< -o $@
    52 
    5350$(EXE): $(AUTOGEN) $(OBJS) owl.o libfaim
    5451        $(ATHSTATIC) $(CC) -o $(EXE) owl.o $(OBJS) $(LDFLAGS) $(LIBS)
     
    5653tester: $(AUTOGEN) $(OBJS) tester.o
    5754        $(ATHSTATIC) $(CC) -o tester tester.o $(OBJS) $(LDFLAGS) $(LIBS)
     55
     56%.o: %.c $(HEADERS)
     57        $(CC) -c $(CFLAGS) $< -o $@
     58
     59# zcrypt is old crufty DES code I don't want to touch
     60# Disable all warnings when compiling it
     61zcrypt.o: zcrypt.c $(HEADERS)
     62        $(CC) -c $(CFLAGS) $< -w -o $@
    5863
    5964test: tester
     
    100105#owl_prototypes.h:
    101106
    102 .PHONY: tags clean distclean proto test
     107.PHONY: tags clean distclean proto test check-syntax
    103108
    104109tags: TAGS
     
    107112        etags $(BASE_SRCS) $(OWL_SRC) $(TESTER_SRC) $(GEN_C) owl.h $(GEN_H)
    108113
    109 $(BASE_OBJS) varstubs.h:: owl.h config.h owl_prototypes.h
    110 #$(BASE_OBJS) varstubs.h:: owl.h config.h
     114$(BASE_OBJS) varstubs.h: owl.h config.h owl_prototypes.h
    111115
    112116libfaim: libfaim/libfaim.a
     
    135139installdirs: mkinstalldirs
    136140        ${srcdir}/mkinstalldirs ${DESTDIR}${bindir} ${DESTDIR}${mandir}/man1 ${DESTDIR}${datadir}
     141
     142# For emacs flymake-mode
     143check-syntax: proto
     144        $(CC) $(CFLAGS) -Wall -Wextra -pedantic -fsyntax-only $(CHK_SOURCES)
  • aim.c

    r34509d5 rdb0ac7e  
    14521452     *
    14531453     */
    1454     strncpy(realmsg, args->msg, sizeof(realmsg));
     1454    if (args->msg && args->msglen)
     1455      strncpy(realmsg, args->msg, sizeof(realmsg));
    14551456  }
    14561457
  • commands.c

    r3617286 r864ed35  
    101101              "Use 'show keymaps' to see the existing keymaps.\n"
    102102              "Key sequences may be things like M-C-t or NPAGE.\n"),
    103 
    104   OWLCMD_ARGS("style", owl_command_style, OWL_CTX_ANY,
    105               "creates a new style",
    106               "style <name> perl <function_name>",
    107               "Creates a new style for formatting messages.\n"
    108               "A style named <name> will be created that will\n"
    109               "format messages using the perl function <function_name>.\n\n"
    110               "SEE ALSO: show styles, view -s, filter -s\n"),
    111103
    112104  OWLCMD_ARGS("zwrite", owl_command_zwrite, OWL_CTX_INTERACTIVE,
     
    180172              "print <variable>\n"
    181173              "print",
    182               "Print the value of the named variable.  If no arugments\n"
     174              "Print the value of the named variable.  If no arguments\n"
    183175              "are used print the value of all variables.\n"),
    184176
     
    599591              "smartnarrow [-i | --instance]",
    600592              "If the curmsg is a personal message narrow\n"
    601               "   to the converstaion with that user.\n"
     593              "   to the conversation with that user.\n"
    602594              "If the curmsg is a class message, instance foo, recip *\n"
    603595              "   message, narrow to the class, inst.\n"
     
    611603              "smartfilter [-i | --instance]",
    612604              "If the curmsg is a personal message, the filter is\n"
    613               "   the converstaion with that user.\n"
     605              "   the conversation with that user.\n"
    614606              "If the curmsg is a class message, instance foo, recip *\n"
    615607              "   message, the filter is the class, inst.\n"
     
    963955                  "", ""),
    964956
     957  OWLCMD_ALIAS("webzephyr", "zwrite daemon.webzephyr -c webzephyr -i"),
     958
    965959  /* This line MUST be last! */
    966960  { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
     
    16731667  return NULL;
    16741668}
    1675 
    1676 char *owl_command_style(int argc, char **argv, char *buff) {
    1677   owl_style *s;
    1678 
    1679   /* Usage: style <name> perl <function> */
    1680   if (argc != 4 || strcmp(argv[2], "perl")) {
    1681     owl_function_makemsg("Usage: style <name> perl <function>");
    1682     return NULL;
    1683   }
    1684   if (!owl_perlconfig_is_function(argv[3])) {
    1685     owl_function_makemsg("Unable to create style '%s': no perl function '%s'",
    1686                          argv[1], argv[3]);
    1687     return NULL;
    1688   }
    1689   s=owl_malloc(sizeof(owl_style));
    1690   owl_style_create_perl(s, argv[1], argv[3], NULL);
    1691   owl_global_add_style(&g, s);
    1692 
    1693   return NULL;
    1694 }
    1695 
    16961669
    16971670void owl_command_quit()
  • functions.c

    r5f3168a rdb0ac7e  
    258258  ret=owl_zwrite_create_from_line(&z, line);
    259259  if (ret) {
    260     owl_function_error("Error in zwrite arugments");
     260    owl_function_error("Error in zwrite arguments");
    261261    owl_zwrite_free(&z);
    262262    return;
     
    19251925  owl_fmtext_append_normal(&fm, "\n");
    19261926
    1927   owl_fmtext_append_normal(&fm, "  Startup Arugments: ");
     1927  owl_fmtext_append_normal(&fm, "  Startup Arguments: ");
    19281928  owl_fmtext_append_normal(&fm, owl_global_get_startupargs(&g));
    19291929  owl_fmtext_append_normal(&fm, "\n");
  • global.c

    r9d59118 rdb0ac7e  
    453453  sepbar(NULL);
    454454  owl_editwin_redisplay(&(g->tw), 0);
     455  owl_function_full_redisplay(&g);
    455456
    456457  /* TODO: this should handle other forms of popwins */
  • keys.c

    r5f3168a rdb0ac7e  
    230230
    231231  BIND_CMD("LEFT",   "recv:shiftleft", "");
     232  BIND_CMD("M-[ D",  "recv:shiftleft", "");
    232233  BIND_CMD("RIGHT",  "recv:shiftright","");
     234  BIND_CMD("M-[ C",  "recv:shiftleft", "");
    233235  BIND_CMD("DOWN",   "recv:next",      "");
    234236  BIND_CMD("C-n",    "recv:next",      "");
     237  BIND_CMD("M-[ B",  "recv:next",      "");
    235238  BIND_CMD("M-C-n",  "recv:next --smart-filter", "move to next message matching the current one");
    236239  BIND_CMD("UP",     "recv:prev",      "");
     240  BIND_CMD("M-[ A",  "recv:prev",      "");
    237241  BIND_CMD("n",      "recv:next-notdel", "");
    238242  BIND_CMD("p",      "recv:prev-notdel", "");
     
    281285  BIND_CMD("w",   "openurl",          "open a URL using a webbrowser");
    282286
     287  BIND_CMD("W",   "start-command webzephyr ", "start a webzephyr command");
     288
    283289  BIND_CMD("C-c",  "",                "no effect in this mode");
    284290  BIND_CMD("C-g",  "",                "no effect in this mode");
  • owl.c

    r07bfbc2 rdb0ac7e  
    274274  }
    275275
    276   /* setup the built-in styles */
    277   owl_function_debugmsg("startup: creating built-in styles");
    278 
    279   s=owl_malloc(sizeof(owl_style));
    280   owl_style_create_internal(s, "basic", &owl_stylefunc_basic, "Basic message formatting.");
    281   owl_global_add_style(&g, s);
    282 
    283276  /* setup the default filters */
    284277  /* the personal filter will need to change again when AIM chat's are
     
    409402  if (0 != strcmp(owl_global_get_default_style(&g), "__unspecified__")) {
    410403    /* the style was set by the user: leave it alone */
    411   } else if (owl_global_is_config_format(&g)) {
    412     owl_global_set_default_style(&g, "perl");
    413   } else if (owl_global_is_userclue(&g, OWL_USERCLUE_CLASSES)) {
     404  } else {
    414405    owl_global_set_default_style(&g, "default");
    415   } else {
    416     owl_global_set_default_style(&g, "basic");
    417406  }
    418407
     
    436425  nexttime=time(NULL);
    437426
     427#ifdef HAVE_LIBZEPHYR
     428  /* Check for any zephyrs that have come in while we've done init. */
     429  owl_zephyr_process_events();
     430#endif
     431 
    438432  owl_function_debugmsg("startup: entering main loop");
    439433  /* main loop */
     
    595589  if(owl_message_is_direction_in(m)) {
    596590    /* let perl know about it*/
    597     owl_perlconfig_getmsg(m, 0, NULL);
     591    owl_perlconfig_getmsg(m, NULL);
    598592
    599593    /* do we need to autoreply? */
  • owl.h

    r5f3168a rdb0ac7e  
    7070#define HAS_BOOL
    7171#include <perl.h>
     72#include "owl_perl.h"
    7273#undef logout
    7374#include "XSUB.h"
     
    162163#define OWL_SCROLLMODE_PAGED       4
    163164#define OWL_SCROLLMODE_PAGEDCENTER 5
    164 
    165 #define OWL_STYLE_TYPE_INTERNAL  0
    166 #define OWL_STYLE_TYPE_PERL      1
    167165
    168166#define OWL_TAB               3  /* This *HAS* to be the size of TABSTR below */
     
    386384typedef struct _owl_style {
    387385  char *name;
    388   char *description;
    389   int type;
    390   char *perlfuncname;
    391   void (*formatfunc) (owl_fmtext *fm, owl_message *m);
     386  SV *perlobj;
    392387} owl_style;
    393388
  • perl/lib/BarnOwl/ModuleLoader.pm

    re005862 r965e14d  
    4040        if(!defined eval "use BarnOwl::Module::$class") {
    4141            # BarnOwl::error("Unable to load module $class: $!") if $!;
    42             BarnOwl::error("Unable to load module $class: $@") if $@;
     42            BarnOwl::error("Unable to load module $class: \n$@\n") if $@;
    4343        }
    4444    }
  • perl/modules/IRC/lib/BarnOwl/Module/IRC.pm

    r9c7a701 r919535f  
    199199        process_msg($conn, $to, join(" ", @_));
    200200    } else {
    201         BarnOwl::start_edit_win("/msg $to -a " . $conn->alias, sub {process_msg($conn, $to, @_)});
     201        BarnOwl::start_edit_win("/msg -a " . $conn->alias . " $to", sub {process_msg($conn, $to, @_)});
    202202    }
    203203}
     
    209209    # Strip whitespace. In the future -- send one message/line?
    210210    $body =~ tr/\n\r/  /;
    211     $conn->conn->privmsg($to, $body);
     211    if ($body =~ /^\/me (.*)/) {
     212        $conn->conn->me($to, $1);
     213        $body = BarnOwl::Style::boldify($conn->nick.' '.$1);
     214    } else {
     215        $conn->conn->privmsg($to, $body);
     216    }
    212217    my $msg = BarnOwl::Message->new(
    213218        type        => 'IRC',
     
    220225        is_private($to) ?
    221226          (isprivate  => 'true') : (channel => $to),
    222         replycmd    => "irc-msg $to",
    223         replysendercmd => "irc-msg $to"
     227        replycmd    => "irc-msg -a " . $conn->alias . " $to",
     228        replysendercmd => "irc-msg -a " . $conn->alias . " $to"
    224229       );
    225230    BarnOwl::queue_message($msg);
  • perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm

    r661d2eb r8faab0c  
    108108        is_private($recipient) ?
    109109          (isprivate  => 'true') : (channel => $recipient),
    110         replycmd    => 'irc-msg ' .
     110        replycmd    => 'irc-msg -a ' . $self->alias . ' ' .
    111111            (is_private($recipient) ? $evt->nick : $recipient),
    112         replysendercmd => 'irc-msg ' . $evt->nick
     112        replysendercmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick
    113113       );
    114114
     
    158158        loginout   => 'login',
    159159        channel    => $evt->to,
     160        replycmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick,
     161        replysendercmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick
    160162        );
    161163    BarnOwl::queue_message($msg);
     
    167169        loginout   => 'logout',
    168170        channel    => $evt->to,
     171        replycmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick,
     172        replysendercmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick
    169173        );
    170174    BarnOwl::queue_message($msg);
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm

    r5f3168a rdb0ac7e  
    2525use Net::DNS;
    2626use Getopt::Long;
     27Getopt::Long::Configure(qw(no_getopt_compat prefix_pattern=-|--));
    2728
    2829use utf8;
     
    479480        'account=s' => \$from,
    480481        'id=s'     =>  \$jwrite_sid,
    481     );
     482    ) or die("Usage: jwrite JID [-t thread] [-s 'subject'] [-a account]\n");
    482483    $jwrite_type = 'groupchat' if $gc;
    483484
     
    570571
    571572        my $getopt = Getopt::Long::Parser->new;
    572         $getopt->configure('pass_through');
     573        $getopt->configure('pass_through', 'no_getopt_compat');
    573574        $getopt->getoptions( 'account=s' => \$jid );
    574575        $jid ||= defaultJID();
     
    734735        my $purgeGroups;
    735736        my $getopt = Getopt::Long::Parser->new;
    736         $getopt->configure('pass_through');
     737        $getopt->configure('pass_through', 'no_getopt_compat');
    737738        $getopt->getoptions(
    738739            'account=s' => \$jid,
  • perl/modules/Jabber/lib/Net/Jabber/Data.pm

    rc2bed55 rcdd3959  
    120120to go into full detail on each of these functions.  Rather I will
    121121present the functions in a list with a type in the first column to
    122 show what they return, or take as arugments.  Here is the list of
     122show what they return, or take as arguments.  Here is the list of
    123123types I will use:
    124124
  • perl/modules/Jabber/lib/Net/Jabber/Protocol.pm

    rc2bed55 rcdd3959  
    940940        if (!exists($funcHash{set}) && exists($funcHash{get}))
    941941        {
    942             croak("The DefineNamespace arugments have changed, and I cannot determine the\nnew values automatically for name($name).  Please read the man page\nfor Net::Jabber::Namespaces.  I apologize for this incompatability.\n");
     942            croak("The DefineNamespace arguments have changed, and I cannot determine the\nnew values automatically for name($name).  Please read the man page\nfor Net::Jabber::Namespaces.  I apologize for this incompatability.\n");
    943943        }
    944944
  • perlconfig.c

    r5f3168a rdb0ac7e  
    411411}
    412412
    413 char *owl_perlconfig_getmsg(owl_message *m, int mode, char *subname)
    414 {
    415   /* if mode==1 we are doing message formatting.  The returned
    416    * formatted message needs to be freed by the caller.
    417    *
    418    * if mode==0 we are just doing the message-has-been-received
    419    * thing.
    420    */
    421   if (!owl_global_have_config(&g)) return(NULL);
    422  
    423   /* run the procedure corresponding to the mode */
    424   if (mode==1) {
    425     char *ret = NULL;
    426     ret = owl_perlconfig_call_with_message(subname?subname
    427                                            :"BarnOwl::_format_msg_legacy_wrap", m);
    428     if (!ret) {
    429       ret = owl_sprintf("@b([Perl Message Formatting Failed!])\n");
    430     }
    431     return ret;
    432   } else {
    433     char *ptr = NULL;
    434     if (owl_perlconfig_is_function("BarnOwl::Hooks::_receive_msg")) {
    435       ptr = owl_perlconfig_call_with_message(subname?subname
    436                                        :"BarnOwl::_receive_msg_legacy_wrap", m);
    437     }
    438     if (ptr) owl_free(ptr);
    439     return(NULL);
    440   }
     413void owl_perlconfig_getmsg(owl_message *m, char *subname)
     414{
     415  char *ptr = NULL;
     416  if (owl_perlconfig_is_function("BarnOwl::Hooks::_receive_msg")) {
     417    ptr = owl_perlconfig_call_with_message(subname?subname
     418                                           :"BarnOwl::_receive_msg_legacy_wrap", m);
     419  }
     420  if (ptr) owl_free(ptr);
    441421}
    442422
  • perlglue.xs

    r9c7a701 rb67ab6b  
    256256
    257257void
    258 _create_style(name, function, description)
     258create_style(name, object)
    259259     char *name
    260      char *function
    261      char *description
     260     SV  *object
    262261     PREINIT:
    263                 /* This is to allow us to bootstrap the default style before the
    264                 command architecture has been initialized */
    265262                owl_style *s;
    266263     CODE:
    267264        {
    268265                s = owl_malloc(sizeof(owl_style));
    269                 owl_style_create_perl(s, name, function, description);
     266                owl_style_create_perl(s, name, object);
    270267                owl_global_add_style(&g, s);
    271268        }
  • perlwrap.pm

    r9815e2e r811ad93  
    153153}
    154154$configfile ||= $ENV{HOME}."/.owlconf";
    155 
    156 # populate global variable space for legacy owlconf files
    157 sub _format_msg_legacy_wrap {
    158     my ($m) = @_;
    159     $m->legacy_populate_global();
    160     return &BarnOwl::format_msg($m);
    161 }
    162155
    163156# populate global variable space for legacy owlconf files
     
    692685# Internal startup/shutdown routines called by the C code
    693686
     687sub _load_perl_commands {
     688    # Load builtin perl commands
     689    BarnOwl::new_command(style => \&BarnOwl::Style::style_command,
     690                       {
     691                           summary => "creates a new style",
     692                           usage   => "style <name> perl <function_name>",
     693                           description =>
     694                           "A style named <name> will be created that will\n" .
     695                           "format messages using the perl function <function_name>.\n\n" .
     696                           "SEE ALSO: show styles, view -s, filter -s\n\n" .
     697                           "DEPRECATED in favor of BarnOwl::create_style(NAME, OBJECT)",
     698                          });
     699}
     700
    694701sub _load_owlconf {
    695702    # load the config  file
     
    702709        if(*BarnOwl::format_msg{CODE}) {
    703710            # if the config defines a legacy formatting function, add 'perl' as a style
    704             BarnOwl::_create_style("perl", "BarnOwl::_format_msg_legacy_wrap",
    705                                    "User-defined perl style that calls BarnOwl::format_msg"
    706                                    . " with legacy global variable support");
    707             BarnOwl::set("-q default_style perl");
     711            BarnOwl::create_style("perl", BarnOwl::Style::Legacy->new(
     712                "BarnOwl::format_msg",
     713                "User-defined perl style that calls BarnOwl::format_msg"
     714                . " with legacy global variable support",
     715                1));
     716             BarnOwl::set("-q default_style perl");
    708717        }
    709718    }
     
    715724
    716725sub _startup {
     726    _load_perl_commands();
    717727    _load_owlconf();
    718728
     
    763773sub format_message($)
    764774{
    765     my $m = shift;
     775    my $self = shift;
     776    my $m    = shift;
     777    my $fmt;
    766778
    767779    if ( $m->is_loginout) {
    768         return format_login($m);
     780        $fmt = $self->format_login($m);
    769781    } elsif($m->is_ping && $m->is_personal) {
    770         return ( "\@b(PING) from \@b(" . $m->pretty_sender . ")\n" );
     782        $fmt = $self->format_ping($m);
    771783    } elsif($m->is_admin) {
    772         return "\@bold(OWL ADMIN)\n" . indentBody($m);
     784        $fmt = $self->format_admin($m);
    773785    } else {
    774         return format_chat($m);
    775     }
    776 }
    777 
    778 BarnOwl::_create_style("default", "BarnOwl::Style::Default::format_message", "Default style");
     786        $fmt = $self->format_chat($m);
     787    }
     788    $fmt = BarnOwl::Style::boldify($fmt) if $self->should_bold($m);
     789    return $fmt;
     790}
     791
     792sub should_bold {
     793    my $self = shift;
     794    my $m = shift;
     795    return $m->is_personal && $m->direction eq "in";
     796}
     797
     798sub description {"Default style";}
     799
     800BarnOwl::create_style("default", "BarnOwl::Style::Default");
    779801
    780802################################################################################
     
    787809
    788810sub format_login($) {
     811    my $self = shift;
    789812    my $m = shift;
    790813    return sprintf(
     
    798821}
    799822
     823sub format_ping {
     824    my $self = shift;
     825    my $m = shift;
     826    return "\@b(PING) from \@b(" . $m->pretty_sender . ")\n";
     827}
     828
     829sub format_admin {
     830    my $self = shift;
     831    my $m = shift;
     832    return "\@bold(OWL ADMIN)\n" . $self->indent_body($m);
     833}
     834
    800835sub format_chat($) {
     836    my $self = shift;
     837    my $m = shift;
     838    my $header = $self->chat_header($m);
     839    return $header . "\n". $self->indent_body($m);
     840}
     841
     842sub chat_header {
     843    my $self = shift;
    801844    my $m = shift;
    802845    my $header;
     
    819862    }
    820863    $header .= "  " . time_hhmm($m);
     864    $header .= $self->format_sender($m);
     865    return $header;
     866}
     867
     868sub format_sender {
     869    my $self = shift;
     870    my $m = shift;
    821871    my $sender = $m->long_sender;
    822872    $sender =~ s/\n.*$//s;
    823     $header .= " " x (4 - ((length $header) % 4));
    824     $header .= "(" . $sender . '@color[default]' . ")";
    825     my $message = $header . "\n". indentBody($m);
    826     if($m->is_personal && $m->direction eq "in") {
    827         $message = BarnOwl::Style::boldify($message);
    828     }
    829     return $message;
    830 }
    831 
    832 sub indentBody($)
     873    return "  (" . $sender . '@color[default]' . ")";
     874}
     875
     876sub indent_body($)
    833877{
     878    my $self = shift;
    834879    my $m = shift;
    835880
     
    846891}
    847892
     893package BarnOwl::Style::Basic;
     894our @ISA=qw(BarnOwl::Style::Default);
     895
     896sub description {"Compatability alias for the default style";}
     897
     898BarnOwl::create_style("basic", "BarnOwl::Style::Basic");
     899
    848900package BarnOwl::Style::OneLine;
     901# Inherit format_message to dispatch
     902our @ISA = qw(BarnOwl::Style::Default);
     903
     904use constant BASE_FORMAT => '%s %-13.13s %-11.11s %-12.12s ';
     905
     906sub description {"Formats for one-line-per-message"}
     907
     908BarnOwl::create_style("oneline", "BarnOwl::Style::OneLine");
     909
    849910################################################################################
    850 # Branching point for various formatting functions in this style.
    851 ################################################################################
    852 use constant BASE_FORMAT => '%s %-13.13s %-11.11s %-12.12s ';
    853 sub format_message($) {
    854   my $m = shift;
    855 
    856 #  if ( $m->is_zephyr ) {
    857 #    return format_zephyr($m);
    858 #  }
    859   if ( $m->is_loginout ) {
    860     return format_login($m);
    861   }
    862   elsif ( $m->is_ping) {
    863     return format_ping($m);
    864   }
    865   elsif ( $m->is_admin || $m->is_loopback) {
    866     return format_local($m);
    867   }
    868   else {
    869     return format_chat($m);
    870   }
    871 }
    872 
    873 BarnOwl::_create_style("oneline", "BarnOwl::Style::OneLine::format_message", "Formats for one-line-per-message");
    874 
    875 ################################################################################
    876911
    877912sub format_login($) {
     913  my $self = shift;
    878914  my $m = shift;
    879915  return sprintf(
     
    898934sub format_chat($)
    899935{
     936  my $self = shift;
    900937  my $m = shift;
    901938  my $dir = lc($m->{direction});
     
    911948  if ($m->is_personal) {
    912949    $line= sprintf(BASE_FORMAT,
    913                    $dirsym,
    914                    $m->type,
    915                    '',
    916                    ($dir eq 'out'
    917                       ? $m->pretty_recipient
    918                       : $m->pretty_sender));
     950                   $dirsym,
     951                   $m->type,
     952                   '',
     953                   ($dir eq 'out'
     954                    ? $m->pretty_recipient
     955                    : $m->pretty_sender));
    919956  }
    920957  else {
    921958    $line = sprintf(BASE_FORMAT,
    922                     $dirsym,
    923                     $m->context,
    924                     $m->subcontext,
    925                     ($dir eq 'out'
    926                        ? $m->pretty_recipient
    927                        : $m->pretty_sender));
     959                    $dirsym,
     960                    $m->context,
     961                    $m->subcontext,
     962                    ($dir eq 'out'
     963                     ? $m->pretty_recipient
     964                     : $m->pretty_sender));
    928965  }
    929966
     
    931968  $body =~ tr/\n/ /;
    932969  $line .= $body;
    933   $line = BarnOwl::Style::boldify($line) if ($m->is_personal && lc($m->direction) eq 'in');
    934970  return $line;
    935971}
    936972
    937 # Format locally generated messages
    938 sub format_local($)
     973# Format owl admin messages
     974sub format_admin($)
    939975{
     976  my $self = shift;
    940977  my $m = shift;
    941   my $type = uc($m->{type});
    942   my $line = sprintf(BASE_FORMAT, '<', $type, '', '');
     978  my $line = sprintf(BASE_FORMAT, '<', 'ADMIN', '', '');
    943979  my $body = $m->{body};
    944980  $body =~ tr/\n/ /;
     
    9681004}
    9691005
     1006sub style_command {
     1007    my $command = shift;
     1008    if(scalar @_ != 3 || $_[1] ne 'perl') {
     1009        die("Usage: style <name> perl <function>\n");
     1010    }
     1011    my $name = shift;
     1012    my $perl = shift;
     1013    my $fn   = shift;
     1014    {
     1015        no strict 'refs';
     1016        unless(*{$fn}{CODE}) {
     1017            die("Unable to create style '$name': no perl function '$fn'\n");
     1018        }
     1019    }
     1020    BarnOwl::create_style($name, BarnOwl::Style::Legacy->new($fn));
     1021}
     1022
     1023package BarnOwl::Style::Legacy;
     1024
     1025sub new {
     1026    my $class = shift;
     1027    my $func  = shift;
     1028    my $desc  = shift;
     1029    my $useglobals = shift;
     1030    $useglobals = 0 unless defined($useglobals);
     1031    return bless {function    => $func,
     1032                  description => $desc,
     1033                  useglobals  => $useglobals}, $class;
     1034}
     1035
     1036sub description {
     1037    my $self = shift;
     1038    return $self->{description} ||
     1039    ("User-defined perl style that calls " . $self->{function});
     1040};
     1041
     1042sub format_message {
     1043    my $self = shift;
     1044    if($self->{useglobals}) {
     1045        $_[0]->legacy_populate_global();
     1046    }
     1047    no strict 'refs';
     1048    goto \&{$self->{function}};
     1049}
     1050
    9701051
    9711052# switch to package main when we're done
  • style.c

    r5a9f6fe r864ed35  
     1#define OWL_PERL
    12#include "owl.h"
    23
    34static const char fileIdent[] = "$Id$";
    45
    5 void owl_style_create_internal(owl_style *s, char *name, void (*formatfunc) (owl_fmtext *fm, owl_message *m), char *description)
     6void owl_style_create_perl(owl_style *s, char *name, SV *obj)
    67{
    7   s->type=OWL_STYLE_TYPE_INTERNAL;
    88  s->name=owl_strdup(name);
    9   if (description) {
    10     s->description=owl_strdup(description);
    11   } else {
    12     s->description=owl_sprintf("Owl internal style %s", name);
    13   }
    14   s->perlfuncname=NULL;
    15   s->formatfunc=formatfunc;
    16 }
    17 
    18 void owl_style_create_perl(owl_style *s, char *name, char *perlfuncname, char *description)
    19 {
    20   s->type=OWL_STYLE_TYPE_PERL;
    21   s->name=owl_strdup(name);
    22   s->perlfuncname=owl_strdup(perlfuncname);
    23   if (description) {
    24     s->description=owl_strdup(description);
    25   } else {
    26     s->description=owl_sprintf("User-defined perl style that calls %s",
    27                                perlfuncname);
    28   }
    29   s->formatfunc=NULL;
     9  s->perlobj = SvREFCNT_inc(obj);
    3010}
    3111
     
    4323char *owl_style_get_description(owl_style *s)
    4424{
    45   return(s->description);
     25  SV *sv = NULL;
     26  OWL_PERL_CALL_METHOD(s->perlobj,
     27                       "description",
     28                       /* no args */,
     29                       "Error in style_get_description: %s",
     30                       0,
     31                       sv = SvREFCNT_inc(POPs);
     32                       );
     33  if(sv) {
     34    return SvPV_nolen(sv_2mortal(sv));
     35  } else {
     36    return "[error getting description]";
     37  }
    4638}
    4739
     
    5143void owl_style_get_formattext(owl_style *s, owl_fmtext *fm, owl_message *m)
    5244{
    53   if (s->type==OWL_STYLE_TYPE_INTERNAL) {
    54     (* s->formatfunc)(fm, m);
    55   } else if (s->type==OWL_STYLE_TYPE_PERL) {
    56     char *body, *indent;
    57     int curlen;
     45  char *body, *indent;
     46  int curlen;
    5847
    59     /* run the perl function */
    60     body=owl_perlconfig_getmsg(m, 1, s->perlfuncname);
    61     if (!strcmp(body, "")) {
    62       owl_free(body);
    63       body=owl_strdup("<unformatted message>");
    64     }
    65    
    66     /* indent and ensure ends with a newline */
    67     indent=owl_malloc(strlen(body)+(owl_text_num_lines(body))*OWL_TAB+10);
    68     owl_text_indent(indent, body, OWL_TAB);
    69     curlen = strlen(indent);
    70     if (curlen==0 || indent[curlen-1] != '\n') {
    71       indent[curlen] = '\n';
    72       indent[curlen+1] = '\0';
    73     }
     48  SV *sv = NULL;
     49 
     50  /* Call the perl object */
     51  OWL_PERL_CALL_METHOD(s->perlobj,
     52                       "format_message",
     53                       XPUSHs(owl_perlconfig_message2hashref(m));,
     54                       "Error in format_message: %s",
     55                       0,
     56                       sv = SvREFCNT_inc(POPs);
     57                       );
    7458
    75     /* fmtext_append.  This needs to change */
    76     owl_fmtext_append_ztext(fm, indent);
    77    
    78     owl_free(indent);
    79     owl_free(body);
     59  if(sv) {
     60    body = SvPV_nolen(sv);
     61  } else {
     62    body = "<unformatted message>";
    8063  }
     64
     65  /* indent and ensure ends with a newline */
     66  indent=owl_malloc(strlen(body)+(owl_text_num_lines(body))*OWL_TAB+10);
     67  owl_text_indent(indent, body, OWL_TAB);
     68  curlen = strlen(indent);
     69  if (curlen==0 || indent[curlen-1] != '\n') {
     70    indent[curlen] = '\n';
     71    indent[curlen+1] = '\0';
     72  }
     73
     74  /* fmtext_append.  This needs to change */
     75  owl_fmtext_append_ztext(fm, indent);
     76
     77  owl_free(indent);
     78  if(sv)
     79    SvREFCNT_dec(body);
    8180}
    8281
    8382int owl_style_validate(owl_style *s) {
    84   if (!s) {
    85     return -1;
    86   } else if (s->type==OWL_STYLE_TYPE_INTERNAL) {
    87     return 0;
    88   } else if (s->type==OWL_STYLE_TYPE_PERL
    89              && s->perlfuncname
    90              && owl_perlconfig_is_function(s->perlfuncname)) {
    91     return 0;
    92   } else {
     83  if (!s || !s->perlobj || !SvOK(s->perlobj)) {
    9384    return -1;
    9485  }
     86  return 0;
    9587}
    9688
     
    9890{
    9991  if (s->name) owl_free(s->name);
    100   if (s->description) owl_free(s->description);
    101   if (s->type==OWL_STYLE_TYPE_PERL && s->perlfuncname) {
    102     owl_free(s->perlfuncname);
    103   }
     92  SvREFCNT_dec(s->perlobj);
    10493}
  • svkversion

    r95e60d6 r51f45d1  
    1515$p ||= ".";
    1616
    17 my @lines = `svk info $p`;
     17my @lines = `svk info $p 2>&1`;
     18if($! || $lines[0] =~ "not a checkout path") {
     19    print "exported$newline";
     20    exit;
     21}
    1822my @merged = grep {/^Merged From: /} @lines;
    1923
  • variable.c

    r247cbc9 r52f8dd6  
    273273                 "Some built-in styles include:\n"
    274274                 "   default  - the default owl formatting\n"
    275                  "   basic    - simple formatting\n"
    276275                 "   oneline  - one line per-message\n"
    277276                 "   perl     - legacy perl interface\n"
  • cmd.c

    r6922edd r34509d5  
    7474  owl_cmd *cmd;
    7575
    76   tmpbuff=strdup(cmdbuff);
     76  tmpbuff=owl_strdup(cmdbuff);
    7777  argv=owl_parseline(tmpbuff, &argc);
    7878  if (argc < 0) {
  • config.h.in

    r03cf6b9 re23eb2b  
    2222#undef HAVE_LIBCOM_ERR
    2323
    24 /* Define to 1 if you have the `curses' library (-lcurses). */
    25 #undef HAVE_LIBCURSES
    26 
    2724/* Define to 1 if you have the `des425' library (-ldes425). */
    2825#undef HAVE_LIBDES425
     
    3936/* Define to 1 if you have the `krb5' library (-lkrb5). */
    4037#undef HAVE_LIBKRB5
    41 
    42 /* Define to 1 if you have the `ncurses' library (-lncurses). */
    43 #undef HAVE_LIBNCURSES
    4438
    4539/* Define to 1 if you have the `ncursesw' library (-lncursesw). */
  • configure.ac

    r18e28a4 rd9337637  
    1212fi
    1313
     14m4_include(/usr/share/aclocal/pkg.m4)
     15dnl m4_include(pkg.m4)
    1416
    1517dnl Check for Athena
     
    4446fi
    4547
    46 AC_CHECK_LIB(ncursesw, initscr,,
    47   AC_CHECK_LIB(ncurses, initscr,,
    48     AC_CHECK_LIB(curses, initscr,, AC_MSG_ERROR(No curses library found.))))
     48AC_CHECK_LIB(ncursesw, initscr,, AC_MSG_ERROR(No curses library found.))
    4949AC_CHECK_LIB(com_err, com_err)
    5050AC_CHECK_LIB(nsl, gethostbyname)
     
    109109LDFLAGS=${LDFLAGS}\ ${FOO}
    110110
     111dnl Add CFLAGS and LDFLAGS for glib-2.0
     112PKG_CHECK_MODULES(GLIB,glib-2.0)
     113
     114echo Adding glib-2.0 CFLAGS ${GLIB_CFLAGS}
     115CFLAGS="${GLIB_CFLAGS} ${CFLAGS}"
     116echo Adding glib-2.0 LDFLAGS ${GLIB_LIBS}
     117LDFLAGS="${GLIB_LIBS} ${LDFLAGS}"
     118
     119
    111120dnl Checks for typedefs, structures, and compiler characteristics.
    112121
  • editwin.c

    raf1920fd r2d4ff14  
    143143  e->buffy=0;
    144144  owl_editwin_overwrite_string(e, text);
     145  owl_editwin_overwrite_char(e, '\0');
    145146  e->lock=strlen(text);
    146147  /* if (text[e->lock-1]=='\n') e->lock--; */
    147   e->buffx=x;
    148   e->buffy=y;
    149   owl_editwin_adjust_for_locktext(e);
     148  /*  e->buffx=x; */
     149  /*  e->buffy=y; */
     150  _owl_editwin_set_xy_by_index(e, e->lock);
    150151  owl_editwin_redisplay(e, 0);
    151152}
     
    255256
    256257  /* start at topline */
    257   ptr1=e->buff;
    258   for (i=0; i<e->topline; i++) {
    259     ptr2=strchr(ptr1, '\n');
     258  ptr1 = e->buff;
     259  for (i = 0; i < e->topline; i++) {
     260    ptr2 = strchr(ptr1, '\n');
    260261    if (!ptr2) {
    261262      /* we're already on the last line */
    262263      break;
    263264    }
    264     ptr1=ptr2+1;
     265    ptr1 = ptr2 + 1;
    265266  }
    266267  /* ptr1 now stores the starting point */
    267268
    268269  /* find the ending point and store it in ptr3 */
    269   ptr2=ptr1;
    270   ptr3=ptr1;
    271   for (i=0; i<e->winlines; i++) {
    272     ptr3=strchr(ptr2, '\n');
     270  ptr2 = ptr1;
     271  ptr3 = ptr1;
     272  for (i = 0; i < e->winlines; i++) {
     273    ptr3 = strchr(ptr2, '\n');
    273274    if (!ptr3) {
    274275      /* we've hit the last line */
    275276      /* print everything to the end */
    276       ptr3=e->buff+e->bufflen-1;
     277      ptr3 = e->buff + e->bufflen - 1;
    277278      ptr3--;
    278279      break;
    279280    }
    280     ptr2=ptr3+1;
    281   }
    282   ptr3+=2;
    283 
    284   buff=owl_malloc(ptr3-ptr1+50);
    285   strncpy(buff, ptr1, ptr3-ptr1);
    286   buff[ptr3-ptr1]='\0';
    287   if (e->echochar=='\0') {
     281    ptr2 = ptr3 + 1;
     282  }
     283  ptr3 += 2;
     284
     285  buff = owl_malloc(ptr3 - ptr1 + 50);
     286  strncpy(buff, ptr1, ptr3 - ptr1);
     287  buff[ptr3 - ptr1] = '\0';
     288  if (e->echochar == '\0') {
    288289    waddstr(e->curswin, buff);
    289290  } else {
    290291    /* translate to echochar, *except* for the locktext */
    291292    int len;
    292     int dolocklen=e->lock-(ptr1-e->buff);
    293 
    294     for (i=0; i<dolocklen; i++) {
    295       waddch(e->curswin, buff[i]);
    296     }
    297     len=strlen(buff);
    298     for (i=0; i<len-dolocklen; i++) {
     293    int dolocklen = e->lock - (ptr1 - e->buff);
     294    char *locktext;
     295    char tmp = e->buff[dolocklen];
     296
     297    e->buff[dolocklen] = '\0';
     298    locktext = owl_strdup(e->buff);
     299    e->buff[dolocklen] = tmp;
     300
     301    waddstr(e->curswin, locktext);
     302   
     303    len = strlen(buff);
     304    for (i = 0; i < len-dolocklen; i++) {
    299305      waddch(e->curswin, e->echochar);
    300306    }
    301307  }
    302   wmove(e->curswin, e->buffy-e->topline, e->buffx);
     308  wmove(e->curswin, e->buffy-e->topline, e->buffx + _owl_editwin_cursor_adjustment(e));
    303309  wnoutrefresh(e->curswin);
    304   if (update==1) {
     310  if (update == 1) {
    305311    doupdate();
    306312  }
    307313  owl_free(buff);
     314}
     315
     316/* Remove n bytes at cursor. */
     317void _owl_editwin_remove_bytes(owl_editwin *e, int n) /*noproto*/
     318{
     319  int i = _owl_editwin_get_index_from_xy(e) + n;
     320  for (; i < e->bufflen; i++) {
     321    e->buff[i-n] = e->buff[i];
     322  }
     323 
     324  e->bufflen -= n;
     325  e->buff[e->bufflen] = '\0';
     326}
     327
     328/* Insert n bytes at cursor.*/
     329void _owl_editwin_insert_bytes(owl_editwin *e, int n) /*noproto*/
     330{
     331  int i, z;
     332 
     333  if ((e->bufflen + n) > (e->allocated - 5)) {
     334    _owl_editwin_addspace(e);
     335  }
     336
     337  e->bufflen += n;
     338  e->buff[e->bufflen] = '\0';
     339 
     340  z = _owl_editwin_get_index_from_xy(e);
     341  for (i = e->bufflen - 1; i > z; i--) {
     342    e->buff[i] = e->buff[i - n];
     343  }
    308344}
    309345
     
    315351int _owl_editwin_linewrap_word(owl_editwin *e)
    316352{
    317   int i, z;
    318 
    319   z=_owl_editwin_get_index_from_xy(e);
    320   /* move back and line wrap the previous word */
    321   for (i=z-1; ; i--) {
    322     /* move back until you find a space or hit the beginning of the line */
    323     if (e->buff[i]==' ') {
    324       /* replace the space with a newline */
    325       e->buff[i]='\n';
    326       e->buffy++;
    327       e->buffx=z-i-1;
    328       /* were we on the last line */
    329       return(0);
    330     } else if (e->buff[i]=='\n' || i<=e->lock) {
    331       /* we hit the begginning of the line or the buffer, we cannot
    332        * wrap.
    333        */
    334       return(-1);
    335     }
    336   }
     353  int x, y;
     354  int i;
     355  char *ptr1, *start;
     356  gunichar c;
     357
     358  /* saving values */
     359  x = e->buffx;
     360  y = e->buffy;
     361  start = e->buff + e->lock;
     362
     363  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     364  ptr1 = g_utf8_find_prev_char(start, ptr1);
     365
     366  while (ptr1) {
     367    c = g_utf8_get_char(ptr1);
     368    if (owl_util_can_break_after(c)) {
     369      if (c != ' ') {
     370        i = ptr1 - e->buff;
     371        _owl_editwin_set_xy_by_index(e, i);
     372        _owl_editwin_insert_bytes(e, 1);
     373        /* _owl_editwin_insert_bytes may move e->buff. */
     374        ptr1 = e->buff + i;
     375      }
     376      *ptr1 = '\n';
     377      return 0;
     378    }
     379    else if (c == '\n') {
     380      return 0;
     381    }
     382    ptr1 = g_utf8_find_prev_char(start, ptr1);
     383  }
     384  return -1;
    337385}
    338386
     
    340388 * characters over)
    341389 */
    342 void owl_editwin_insert_char(owl_editwin *e, char c)
    343 {
    344  
    345   int z, i, ret;
     390void owl_editwin_insert_char(owl_editwin *e, gunichar c)
     391{
     392  int z, i, ret, len;
     393  char tmp[6];
     394  memset(tmp, '\0', 6);
    346395
    347396  /* \r is \n */
    348   if (c=='\r') {
    349     c='\n';
    350   }
    351 
    352   if (c=='\n' && e->style==OWL_EDITWIN_STYLE_ONELINE) {
     397  if (c == '\r') {
     398    c = '\n';
     399  }
     400
     401  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
    353402    /* perhaps later this will change some state that allows the string
    354403       to be read */
     
    356405  }
    357406
     407  g_unichar_to_utf8(c, tmp);
     408  len = strlen(tmp);
     409
    358410  /* make sure there is enough memory for the new text */
    359   if ((e->bufflen+1) > (e->allocated-5)) {
     411  if ((e->bufflen + len) > (e->allocated - 5)) {
    360412    _owl_editwin_addspace(e);
    361413  }
    362414
    363415  /* get the insertion point */
    364   z=_owl_editwin_get_index_from_xy(e);
     416  z = _owl_editwin_get_index_from_xy(e);
    365417
    366418  /* If we're going to insert at the last column do word wrapping, unless it's a \n */
    367   if ((e->buffx+1==e->wrapcol) && (c!='\n')) {
    368     ret=_owl_editwin_linewrap_word(e);
    369     if (ret==-1) {
     419  if ((e->buffx + 1 == e->wrapcol) && (c != '\n')) {
     420    ret = _owl_editwin_linewrap_word(e);
     421    if (ret == -1) {
    370422      /* we couldn't wrap, insert a hard newline instead */
    371423      owl_editwin_insert_char(e, '\n');
     
    373425  }
    374426
    375   z=_owl_editwin_get_index_from_xy(e);
    376427  /* shift all the other characters right */
    377   for (i=e->bufflen; i>z; i--) {
    378     e->buff[i]=e->buff[i-1];
    379   }
    380 
    381   /* insert the new one */
    382   e->buff[z]=c;
     428  if (z != e->bufflen) {
     429    _owl_editwin_insert_bytes(e, len);
     430  }
     431
     432  /* insert the new character */
     433  for(i = 0; i < len; i++) {
     434    e->buff[z + i] = tmp[i];
     435  }
    383436
    384437  /* housekeeping */
    385   e->bufflen++;
    386   e->buff[e->bufflen]='\0';
    387 
     438  e->bufflen += len;
     439  e->buff[e->bufflen] = '\0';
     440 
    388441  /* advance the cursor */
    389   if (c=='\n') {
    390     e->buffx=0;
    391     e->buffy++;
    392   } else {
    393     e->buffx++;
    394   }
     442  z += len;
     443  _owl_editwin_set_xy_by_index(e, z);
    395444}
    396445
    397446/* overwrite the character at the current point with 'c' */
    398 void owl_editwin_overwrite_char(owl_editwin *e, char c)
    399 {
    400   int z;
    401  
     447void owl_editwin_overwrite_char(owl_editwin *e, gunichar c)
     448{
     449  int z, oldlen, newlen, i;
     450  char tmp[6];
     451  memset(tmp, '\0', 6);
     452
    402453  /* \r is \n */
    403   if (c=='\r') {
    404     c='\n';
    405   }
    406 
    407   if (c=='\n' && e->style==OWL_EDITWIN_STYLE_ONELINE) {
     454  if (c == '\r') {
     455    c = '\n';
     456  }
     457 
     458  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
    408459    /* perhaps later this will change some state that allows the string
    409460       to be read */
     
    411462  }
    412463
    413   z=_owl_editwin_get_index_from_xy(e);
    414 
    415   /* only if we are at the end of the buffer do we create new space */
    416   if (z==e->bufflen) {
    417     if ((e->bufflen+1) > (e->allocated-5)) {
     464  g_unichar_to_utf8(c, tmp);
     465  newlen = strlen(tmp);
     466
     467  z = _owl_editwin_get_index_from_xy(e);
     468  {
     469    char *t = g_utf8_find_next_char(e->buff + z, NULL);
     470    oldlen = (t ? (t - (e->buff + z)) : 0);
     471  }
     472
     473  /* only if we are at the end of the buffer do we create new space here */
     474  if (z == e->bufflen) {
     475    if ((e->bufflen+newlen) > (e->allocated-5)) {
    418476      _owl_editwin_addspace(e);
    419477    }
    420478  }
    421  
    422   e->buff[z]=c;
    423 
    424   /* housekeeping if we are at the end of the buffer */
    425   if (z==e->bufflen) {
    426     e->bufflen++;
    427     e->buff[e->bufflen]='\0';
    428   }
    429 
     479  /* if not at the end of the buffer, adjust based in char size difference. */
     480  else if (oldlen > newlen) {
     481    _owl_editwin_remove_bytes(e, oldlen-newlen);
     482  }
     483  else /* oldlen < newlen */ {
     484    _owl_editwin_insert_bytes(e, newlen-oldlen);
     485  }
     486  /* Overwrite the old char*/
     487  for (i = 0; i < newlen; i++) {
     488    e->buff[z+i] = tmp[i];
     489  }
     490       
     491  /* housekeeping */
     492  if (z == e->bufflen) {
     493    e->bufflen += newlen;
     494    e->buff[e->bufflen] = '\0';
     495  }
     496 
    430497  /* advance the cursor */
    431   if (c=='\n') {
    432     e->buffx=0;
    433     e->buffy++;
    434   } else {
    435     e->buffx++;
    436   }
    437 
     498  z += newlen;
     499  _owl_editwin_set_xy_by_index(e, z);
    438500}
    439501
     
    443505void owl_editwin_delete_char(owl_editwin *e)
    444506{
    445   int z, i;
    446 
    447   if (e->bufflen==0) return;
     507  int z;
     508  char *p1, *p2;
     509  gunichar c;
     510
     511  if (e->bufflen == 0) return;
    448512 
    449513  /* get the deletion point */
    450   z=_owl_editwin_get_index_from_xy(e);
    451 
    452   if (z==e->bufflen) return;
    453 
    454   for (i=z; i<e->bufflen; i++) {
    455     e->buff[i]=e->buff[i+1];
    456   }
    457   e->bufflen--;
    458   e->buff[e->bufflen]='\0';
     514  z = _owl_editwin_get_index_from_xy(e);
     515
     516  if (z == e->bufflen) return;
     517
     518  p1 = e->buff + z;
     519  p2 = g_utf8_next_char(p1);
     520  c = g_utf8_get_char(p2);
     521  while (g_unichar_ismark(c)) {
     522    p2 = g_utf8_next_char(p2);
     523    c = g_utf8_get_char(p2);
     524  }
     525  _owl_editwin_remove_bytes(e, p2-p1);
    459526}
    460527
     
    467534{
    468535  int z;
    469   char tmp;
    470 
    471   if (e->bufflen==0) return;
     536  char *p1, *p2, *p3, *tmp;
     537
     538  if (e->bufflen == 0) return;
    472539 
    473540  /* get the cursor point */
    474   z=_owl_editwin_get_index_from_xy(e);
    475 
    476   if (z==e->bufflen) {
     541  z = _owl_editwin_get_index_from_xy(e);
     542
     543  if (z == e->bufflen) {
    477544    /* point is after last character */
    478545    z--;
    479546  } 
    480547
    481   if (z-1 < e->lock) {
     548  if (z - 1 < e->lock) {
    482549    /* point is at beginning of buffer, do nothing */
    483550    return;
    484551  }
    485552
    486   tmp=e->buff[z];
    487   e->buff[z]=e->buff[z-1];
    488   e->buff[z-1]=tmp;
    489   owl_editwin_key_right(e);
     553  /* Transpose two utf-8 unicode glyphs. */
     554  p1 = e->buff + z;
     555
     556  p2 = g_utf8_find_next_char(p1, NULL);
     557  while (p2 != NULL && g_unichar_ismark(g_utf8_get_char(p2))) {
     558    p2 = g_utf8_find_next_char(p2, NULL);
     559  }
     560  if (p2 == NULL) return;
     561
     562  p3 = g_utf8_find_prev_char(e->buff, p1);
     563  while (p3 != NULL && g_unichar_ismark(g_utf8_get_char(p3))) {
     564    p3 = g_utf8_find_prev_char(p3, NULL);
     565  }
     566  if (p3 == NULL) return;
     567
     568  tmp = owl_malloc(p2 - p3 + 5);
     569  *tmp = '\0';
     570  strncat(tmp, p1, p2 - p1);
     571  strncat(tmp, p3, p1 - p3);
     572  strncpy(p3, tmp, p2 - p3);
     573  owl_free(tmp);
     574  _owl_editwin_set_xy_by_index(e, p3 - e->buff);
    490575}
    491576
     
    495580void owl_editwin_insert_string(owl_editwin *e, char *string)
    496581{
    497   int i, j;
    498 
    499   j=strlen(string);
    500   for (i=0; i<j; i++) {
    501     owl_editwin_insert_char(e, string[i]);
     582  char *p;
     583  gunichar c;
     584  if (!g_utf8_validate(string, -1, NULL)) {
     585    owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
     586    return;
     587  }
     588  p = string;
     589  c = g_utf8_get_char(p);
     590  while (c) {
     591    _owl_editwin_process_char(e, c);
     592    p = g_utf8_next_char(p);
     593    c = g_utf8_get_char(p);
    502594  }
    503595}
     
    509601void owl_editwin_overwrite_string(owl_editwin *e, char *string)
    510602{
    511   int i, j;
    512 
    513   j=strlen(string);
    514   for (i=0; i<j; i++) {
    515     owl_editwin_overwrite_char(e, string[i]);
     603  char *p;
     604  gunichar c;
     605
     606  if (!g_utf8_validate(string, -1, NULL)) {
     607    owl_function_debugmsg("owl_editwin_overwrite_string: received non-utf-8 string.");
     608    return;
     609  }
     610  p = string;
     611  c = g_utf8_get_char(p);
     612  while (c) {
     613    owl_editwin_overwrite_char(e, c);
     614    p = g_utf8_next_char(p);
     615    c = g_utf8_get_char(p);
    516616  }
    517617}
     
    524624  int i;
    525625  char *ptr1, *ptr2;
    526 
    527   if (e->bufflen==0) return(0);
     626  gunichar c;
     627
     628  if (e->bufflen == 0) return(0);
    528629 
    529630  /* first go to the yth line */
    530   ptr1=e->buff;
    531   for (i=0; i<e->buffy; i++) {
    532     ptr2=strchr(ptr1, '\n');
     631  ptr1 = e->buff;
     632  for (i = 0; i < e->buffy; i++) {
     633    ptr2= strchr(ptr1, '\n');
    533634    if (!ptr2) {
    534635      /* we're already on the last line */
    535636      break;
    536637    }
    537     ptr1=ptr2+1;
    538   }
    539 
    540   /* now go to the xth character */
    541   ptr2=strchr(ptr1, '\n');
    542   if (!ptr2) {
    543     ptr2=e->buff+e->bufflen;
    544   }
    545 
    546   if ((ptr2-ptr1) < e->buffx) {
    547     ptr1=ptr2-1;
    548   } else {
    549     ptr1+=e->buffx;
    550   }
    551 
    552   /* printf("DEBUG: index is %i\r\n", ptr1-e->buff); */
    553   return(ptr1-e->buff);
    554 }
     638    ptr1 = ptr2 + 1;
     639  }
     640
     641  /* now go to the xth cell */
     642  ptr2 = ptr1;
     643  i = 0;
     644  while (ptr2 != NULL && i < e->buffx && (ptr2 - e->buff) < e->bufflen) {
     645    c = g_utf8_get_char(ptr2);
     646    i += (c == '\n' ? 1 : mk_wcwidth(c));
     647    ptr2 = g_utf8_next_char(ptr2);
     648  }
     649  while(ptr2 != NULL && g_unichar_ismark(g_utf8_get_char(ptr2))) {
     650    ptr2 = g_utf8_next_char(ptr2);
     651  }
     652  if (ptr2 == NULL) return e->bufflen;
     653  return(ptr2 - e->buff);
     654}
     655
     656/* We assume x,y are not set to point to a mid-char */
     657gunichar _owl_editwin_get_char_at_xy(owl_editwin *e)
     658{
     659  return g_utf8_get_char(e->buff + _owl_editwin_get_index_from_xy(e));
     660}
     661
    555662
    556663void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
    557664{
    558   int z, i;
    559 
    560   z=_owl_editwin_get_index_from_xy(e);
    561   if (index>z) {
    562     for (i=0; i<index-z; i++) {
    563       owl_editwin_key_right(e);
    564     }
    565   } else if (index<z) {
    566     for (i=0; i<z-index; i++) {
    567       owl_editwin_key_left(e);
    568     }
    569   }
     665  char *ptr1, *ptr2, *target;
     666  gunichar c;
     667
     668  e->buffx = 0;
     669  e->buffy = 0;
     670
     671  ptr1 = e->buff;
     672  target = ptr1 + index;
     673  /* target sanitizing */
     674  if ((target[0] & 0x80) && (~target[0] & 0x40)) {
     675    /* middle of a utf-8 character, back up to previous character. */
     676    target = g_utf8_find_prev_char(e->buff, target);
     677  }
     678  c = g_utf8_get_char(target);
     679  while (g_unichar_ismark(c) && target > e->buff) {
     680    /* Adjust the target off of combining characters and the like. */
     681    target = g_utf8_find_prev_char(e->buff, target);
     682    c = g_utf8_get_char(target);
     683  }
     684  /* If we start with a mark, something is wrong.*/
     685  if (g_unichar_ismark(c)) return;
     686
     687  /* Now our target should be acceptable. */
     688  ptr2 = strchr(ptr1, '\n');
     689  while (ptr2 != NULL && ptr2 < target) {
     690    e->buffy++;
     691    ptr1 = ptr2 + 1;
     692    ptr2 = strchr(ptr1, '\n');
     693  }
     694  ptr2 = ptr1;
     695  while (ptr2 != NULL && ptr2 < target) {
     696    c = g_utf8_get_char(ptr2);
     697    e->buffx += mk_wcwidth(c);
     698    ptr2 = g_utf8_next_char(ptr2);
     699  }
     700}
     701
     702int _owl_editwin_cursor_adjustment(owl_editwin *e)
     703{
     704  char *ptr1, *ptr2;
     705  gunichar c;
     706  int x, i;
     707
     708  /* Find line */
     709  ptr1 = e->buff;
     710  ptr2 = strchr(ptr1, '\n');
     711  for (i = 0; ptr2 != NULL && i < e->buffy; i++) {
     712    ptr1 = ptr2 + 1;
     713    ptr2 = strchr(ptr1, '\n');
     714  }
     715  ptr2 = ptr1;
     716
     717  /* Find char */
     718  x = 0;
     719  while (ptr2 != NULL && x < e->buffx) {
     720    if (*ptr2 == '\n') return 0;
     721    c = g_utf8_get_char(ptr2);
     722    x += mk_wcwidth(c);
     723    ptr2 = g_utf8_next_char(ptr2);
     724  }
     725 
     726  /* calculate x offset */
     727  return x - e->buffx;
    570728}
    571729
     
    574732  /* if we happen to have the cursor over locked text
    575733   * move it to be out of the locktext region */
    576   if (_owl_editwin_get_index_from_xy(e)<e->lock) {
     734  if (_owl_editwin_get_index_from_xy(e) < e->lock) {
    577735    _owl_editwin_set_xy_by_index(e, e->lock);
    578736  }
     
    594752{
    595753  if (e->buffy > 0) e->buffy--;
    596   if (e->buffx >= owl_editwin_get_numchars_on_line(e, e->buffy)) {
    597     e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
     754  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
     755    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    598756  }
    599757
     
    612770
    613771  /* if we're past the last character move back */
    614   if (e->buffx >= owl_editwin_get_numchars_on_line(e, e->buffy)) {
    615     e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
     772  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
     773    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    616774  }
    617775
     
    627785void owl_editwin_key_left(owl_editwin *e)
    628786{
    629   /* move left if we can, and maybe up a line */
    630   if (e->buffx>0) {
    631     e->buffx--;
    632   } else if (e->buffy>0) {
    633     e->buffy--;
    634     e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
    635   }
    636 
    637   /* do we need to scroll up? */
    638   if (e->buffy-e->topline < 0) {
    639     e->topline-=e->winlines/2;
     787  int i;
     788  char * p;
     789  i = _owl_editwin_get_index_from_xy(e);
     790  p = e->buff + i;
     791  p = g_utf8_find_prev_char(e->buff, p);
     792  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
     793    p = g_utf8_find_prev_char(e->buff, p);
     794  }
     795  if (p == NULL) p = e->buff;
     796  _owl_editwin_set_xy_by_index(e, p - e->buff);
     797
     798  if (e->buffy - e->topline < 0) {
     799    e->topline -= e->winlines / 2;
    640800  }
    641801
     
    647807{
    648808  int i;
    649 
    650   /* move right if we can, and skip down a line if needed */
    651   i=owl_editwin_get_numchars_on_line(e, e->buffy);
    652   if (e->buffx < i) {
    653     e->buffx++;
    654     /*  } else if (e->buffy+1 < owl_editwin_get_numlines(e)) { */
    655   } else if (_owl_editwin_get_index_from_xy(e) < e->bufflen) {
    656     if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
    657       e->buffx=0;
    658       e->buffy++;
    659     }
     809  char * p;
     810  i = _owl_editwin_get_index_from_xy(e);
     811  p = e->buff + i;
     812  p = g_utf8_find_next_char(p, NULL);
     813  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
     814    p = g_utf8_find_next_char(p, NULL);
     815  }
     816  if (p == NULL) {
     817    _owl_editwin_set_xy_by_index(e, e->bufflen);
     818  }
     819  else {
     820    _owl_editwin_set_xy_by_index(e, p - e->buff);
    660821  }
    661822
    662823  /* do we need to scroll down? */
    663   if (e->buffy-e->topline >= e->winlines) {
    664     e->topline+=e->winlines/2;
     824  if (e->buffy - e->topline >= e->winlines) {
     825    e->topline += e->winlines / 2;
    665826  }
    666827}
     
    669830{
    670831  int i, x;
     832  gunichar c = '\0';
    671833
    672834  /* if we're starting on a space, find the first non-space */
     
    681843  }
    682844
    683   /* find the next space, newline or end of line and go there, if
    684      already at the end of the line, continue on to the next */
    685   i=owl_editwin_get_numchars_on_line(e, e->buffy);
     845  /* find the next space, newline or end of line and go
     846     there, if already at the end of the line, continue on to the next */
     847  i=owl_editwin_get_numcells_on_line(e, e->buffy);
     848  c = _owl_editwin_get_char_at_xy(e);
    686849  if (e->buffx < i) {
    687850    /* move right till end of line */
    688851    while (e->buffx < i) {
    689       e->buffx++;
    690       if (e->buff[_owl_editwin_get_index_from_xy(e)]==' ') return;
     852      owl_editwin_key_right(e);
     853      c = _owl_editwin_get_char_at_xy(e);
     854      if (c == ' ') return;
    691855      if (e->buffx == i) return;
    692856    }
     
    694858    /* try to move down */
    695859    if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
    696       if (e->buffy+1 <  owl_editwin_get_numlines(e)) {
     860      if (e->buffy+1 < owl_editwin_get_numlines(e)) {
    697861        e->buffx=0;
    698862        e->buffy++;
     
    707871void owl_editwin_move_to_previousword(owl_editwin *e)
    708872{
    709   int i, x;
     873  int i;
     874  gunichar c;
     875  char *ptr1, *ptr2;
    710876
    711877  /* are we already at the beginning of the word? */
    712   i=_owl_editwin_get_index_from_xy(e);
    713   if ( (e->buff[i]!=' ' && e->buff[i]!='\n' && e->buff[i]!='\0') &&
    714        (e->buff[i-1]==' ' || e->buff[i-1]=='\n') ) {
     878  c = _owl_editwin_get_char_at_xy(e);
     879  i = _owl_editwin_get_index_from_xy(e);
     880  ptr1 = e->buff + i;
     881  if (*ptr1 != ' ' && *ptr1 != '\n' && *ptr1 != '\0' ) {
     882    ptr1 = g_utf8_find_prev_char(e->buff, ptr1);
     883    c = g_utf8_get_char(ptr1);
     884    if (c == ' ' || c == '\n') {
     885      owl_editwin_key_left(e);     
     886    }
     887  }
     888
     889  /* are we starting on a space character? */
     890  i = _owl_editwin_get_index_from_xy(e);
     891  while (i > e->lock && (e->buff[i] == ' ' || e->buff[i] == '\n' || e->buff[i] == '\0')) {
     892    /* find the first non-space */
     893    owl_editwin_key_left(e);     
     894    i = _owl_editwin_get_index_from_xy(e);
     895  }
     896
     897  /* find the last non-space */
     898  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     899  while (ptr1 >= e->buff + e->lock) {
     900    ptr2 = g_utf8_find_prev_char(e->buff, ptr1);
     901    if (!ptr2) break;
     902   
     903    c = g_utf8_get_char(ptr2);
     904    if (c == ' ' || c == '\n'){
     905      break;
     906    }
    715907    owl_editwin_key_left(e);
    716   }
    717    
    718   /* are we starting on a space character? */
    719   i=_owl_editwin_get_index_from_xy(e);
    720   if (e->buff[i]==' ' || e->buff[i]=='\n' || e->buff[i]=='\0') {
    721     /* find the first non-space */
    722     for (x=i; x>=e->lock; x--) {
    723       if (e->buff[x]!=' ' && e->buff[x]!='\n' && e->buff[x]!='\0') {
    724         _owl_editwin_set_xy_by_index(e, x);
    725         break;
    726       }
    727     }
    728   }
    729 
    730   /* find the last non-space */
    731   i=_owl_editwin_get_index_from_xy(e);
    732   for (x=i; x>=e->lock; x--) {
    733     if (e->buff[x-1]==' ' || e->buff[x-1]=='\n') {
    734       _owl_editwin_set_xy_by_index(e, x);
    735       break;
    736     }
    737   }
    738   _owl_editwin_set_xy_by_index(e, x);
     908    ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     909  }
    739910}
    740911
     
    742913void owl_editwin_delete_nextword(owl_editwin *e)
    743914{
    744   int z;
     915  char *ptr1, *start;
     916  gunichar c;
    745917
    746918  if (e->bufflen==0) return;
    747919
    748   /* if we start out on a space character then gobble all the spaces
    749      up first */
    750   while (1) {
    751     z=_owl_editwin_get_index_from_xy(e);
    752     if (e->buff[z]==' ' || e->buff[z]=='\n') {
    753       owl_editwin_delete_char(e);
    754     } else {
    755       break;
    756     }
    757   }
    758 
    759   /* then nuke the next word */
    760   while (1) {
    761     z=_owl_editwin_get_index_from_xy(e);
    762     /* z == e->bufflen check added to prevent a hang I (nelhage) have
    763        seen repeatedly while using owl. I'm not sure precisely what
    764        conditions lead to it. */
    765     if (z == e->bufflen
    766         || e->buff[z+1]==' ' || e->buff[z+1]=='\n' || e->buff[z+1]=='\0') break;
    767     owl_editwin_delete_char(e);
    768   }
    769   owl_editwin_delete_char(e);
     920  start = ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     921  /* if we start out on a space character then jump past all the
     922     spaces up first */
     923  while (*ptr1 == ' ' || *ptr1 == '\n') {
     924    ++ptr1;
     925  }
     926
     927  /* then jump past the next word */
     928 
     929  while (ptr1 && ptr1 - e->buff < e->bufflen) {
     930    c = g_utf8_get_char(ptr1);
     931    if (c == ' ' || c == '\n' || c == '\0') break;
     932    ptr1 = g_utf8_find_next_char(ptr1, NULL);
     933  }
     934
     935  if (ptr1) { /* We broke on a space, */
     936    ptr1 = g_utf8_find_next_char(ptr1, NULL);
     937    if (ptr1) { /* and there's a character after it, */
     938      /* nuke everything back to our starting point. */
     939      _owl_editwin_remove_bytes(e, ptr1 - start);
     940      return;
     941    }
     942  }
     943 
     944  /* If we get here, we ran out of string, drop what's left. */
     945  *start = '\0';
     946  e->bufflen = start - e->buff;
    770947}
    771948
     
    773950{
    774951  /* go backwards to the last non-space character, then delete chars */
    775   int i, startpos, endpos;
     952  int startpos, endpos;
    776953
    777954  startpos = _owl_editwin_get_index_from_xy(e);
    778955  owl_editwin_move_to_previousword(e);
    779956  endpos = _owl_editwin_get_index_from_xy(e);
    780   for (i=0; i<startpos-endpos; i++) {
    781     owl_editwin_delete_char(e);
    782   }
     957  _owl_editwin_remove_bytes(e, startpos-endpos);
    783958}
    784959
     
    787962  int i;
    788963
    789   if (owl_editwin_get_numchars_on_line(e, e->buffy)>e->buffx) {
     964  if (owl_editwin_get_numchars_on_line(e, e->buffy) > e->buffx) {
    790965    /* normal line */
    791966    i=_owl_editwin_get_index_from_xy(e);
     
    808983void owl_editwin_move_to_line_end(owl_editwin *e)
    809984{
    810   e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
     985  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    811986}
    812987
     
    821996  /* go to last char */
    822997  e->buffy=owl_editwin_get_numlines(e)-1;
    823   e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
     998  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    824999  owl_editwin_key_right(e);
    8251000
     
    8611036  /* main loop */
    8621037  while (1) {
    863     i=_owl_editwin_get_index_from_xy(e);
     1038    i = _owl_editwin_get_index_from_xy(e);
    8641039
    8651040    /* bail if we hit the end of the buffer */
    866     if (i>=e->bufflen) break;
     1041    if (i >= e->bufflen || e->buff[i] == '\0') break;
    8671042
    8681043    /* bail if we hit the end of the paragraph */
    869     if (e->buff[i]=='\n' && e->buff[i+1]=='\n') break;
     1044    if (e->buff[i] == '\n' && e->buff[i+1] == '\n') break;
    8701045
    8711046    /* if we've travelled too far, linewrap */
    8721047    if ((e->buffx) >= e->fillcol) {
     1048      int len = e->bufflen;
    8731049      _owl_editwin_linewrap_word(e);
     1050      /* we may have added a character. */
     1051      if (i < save) save += e->bufflen - len;
     1052      _owl_editwin_set_xy_by_index(e, i);
    8741053    }
    8751054
    8761055    /* did we hit the end of a line too soon? */
    877     i=_owl_editwin_get_index_from_xy(e);
    878     if (e->buff[i]=='\n' && e->buffx<e->fillcol-1) {
     1056    /* asedeno: Here we replace a newline with a space. We may want to
     1057       consider removing the space if the characters to either side
     1058       are CJK ideograms.*/
     1059    i = _owl_editwin_get_index_from_xy(e);
     1060    if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
    8791061      /* ********* we need to make sure we don't pull in a word that's too long ***********/
    8801062      e->buff[i]=' ';
    8811063    }
    882    
     1064
    8831065    /* fix spacing */
    884     i=_owl_editwin_get_index_from_xy(e);
    885     if (e->buff[i]==' ' && e->buff[i+1]==' ') {
    886       if (e->buff[i-1]=='.' || e->buff[i-1]=='!' || e->buff[i-1]=='?') {
     1066    i = _owl_editwin_get_index_from_xy(e);
     1067    if (e->buff[i] == ' ' && e->buff[i+1] == ' ') {
     1068      if (e->buff[i-1] == '.' || e->buff[i-1] == '!' || e->buff[i-1] == '?') {
    8871069        owl_editwin_key_right(e);
    8881070      } else {
    8891071        owl_editwin_delete_char(e);
    890         /* if we did this ahead of the save point, adjust it */
    891         if (i<save) save--;
     1072        /* if we did this ahead of the save point, adjust it. Changing
     1073           by one is fine here because we're only removing an ASCII
     1074           space. */
     1075        if (i < save) save--;
    8921076      }
    8931077    } else {
    8941078      owl_editwin_key_right(e);
    8951079    }
    896 
    8971080  }
    8981081
     
    9151098int owl_editwin_check_dotsend(owl_editwin *e)
    9161099{
    917   int i;
     1100  char *p, *p_n, *p_p;
     1101  gunichar c;
    9181102
    9191103  if (!e->dotsend) return(0);
    920   for (i=e->bufflen-1; i>0; i--) {
    921     if (e->buff[i] == '.'
    922         && (e->buff[i-1] == '\n' || e->buff[i-1] == '\r')
    923         && (e->buff[i+1] == '\n' || e->buff[i+1] == '\r')) {
    924       e->bufflen = i;
    925       e->buff[i] = '\0';
     1104
     1105  p = g_utf8_find_prev_char(e->buff, e->buff + e->bufflen);
     1106  p_n = g_utf8_find_next_char(p, NULL);
     1107  p_p = g_utf8_find_prev_char(e->buff, p);
     1108  c = g_utf8_get_char(p);
     1109  while (p != NULL) {
     1110    if (*p == '.'
     1111        && p_p != NULL && (*p_p == '\n' || *p_p == '\r')
     1112        && p_n != NULL && (*p_n == '\n' || *p_n == '\r')) {
     1113      e->bufflen = p - e->buff;
     1114      e->buff[e->bufflen] = '\0';
    9261115      return(1);
    9271116    }
    928     if (!isspace((int) e->buff[i])) {
    929       return(0);
    930     }
     1117    if (c != '\0' && !g_unichar_isspace(c)) return(0);
     1118    p_n = p;
     1119    p = p_p;
     1120    c = g_utf8_get_char(p);
     1121    p_p = g_utf8_find_prev_char(e->buff, p);
    9311122  }
    9321123  return(0);
    9331124}
    9341125
    935 void owl_editwin_post_process_char(owl_editwin *e, int j)
     1126void owl_editwin_post_process_char(owl_editwin *e, owl_input j)
    9361127{
    9371128  /* check if we need to scroll down */
     
    9391130    e->topline+=e->winlines/2;
    9401131  }
    941   if ((j==13 || j==10) && owl_editwin_check_dotsend(e)) {
     1132  if ((j.ch==13 || j.ch==10) && owl_editwin_check_dotsend(e)) {
    9421133    owl_command_editmulti_done(e);
    9431134    return;
     
    9461137}
    9471138
    948 void owl_editwin_process_char(owl_editwin *e, int j)
    949 {
    950   if (j == ERR) return;
    951   if (j>127 || ((j<32) && (j!=10) && (j!=13))) {
    952     return;
    953   } else {
     1139void _owl_editwin_process_char(owl_editwin *e, gunichar j)
     1140{
     1141  if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13))) {
    9541142    owl_editwin_insert_char(e, j);
     1143  }
     1144}
     1145
     1146
     1147void owl_editwin_process_char(owl_editwin *e, owl_input j)
     1148{
     1149  if (j.ch == ERR) return;
     1150  /* Ignore ncurses control characters. */
     1151  if (j.ch < 0x100) {
     1152    _owl_editwin_process_char(e, j.uch);
    9551153  }
    9561154}
     
    9791177  }
    9801178
    981   /* now go to the xth character */
    982   ptr2=strchr(ptr1, '\n');
    983   if (!ptr2) {
    984     return(e->buff + e->bufflen - ptr1);
    985   }
    986   return(ptr2-ptr1); /* don't count the newline for now */
     1179  /* now count characters */
     1180  i = 0;
     1181  ptr2 = ptr1;
     1182  while (ptr2 - e->buff < e->bufflen
     1183         && *ptr2 != '\n') {
     1184    ++i;
     1185    ptr2 = g_utf8_next_char(ptr2);
     1186  }
     1187  return i;
     1188}
     1189
     1190int owl_editwin_get_numcells_on_line(owl_editwin *e, int line)
     1191{
     1192  int i;
     1193  char *ptr1, *ptr2;
     1194  gunichar c;
     1195
     1196  if (e->bufflen==0) return(0);
     1197 
     1198  /* first go to the yth line */
     1199  ptr1=e->buff;
     1200  for (i=0; i<line; i++) {
     1201    ptr2=strchr(ptr1, '\n');
     1202    if (!ptr2) {
     1203      /* we're already on the last line */
     1204      return(0);
     1205    }
     1206    ptr1=ptr2+1;
     1207  }
     1208
     1209  /* now count cells */
     1210  i = 0;
     1211  ptr2 = ptr1;
     1212  while (ptr2 - e->buff < e->bufflen
     1213         && *ptr2 != '\n') {
     1214    c = g_utf8_get_char(ptr2);
     1215    i += mk_wcwidth(c);
     1216    ptr2 = g_utf8_next_char(ptr2);
     1217  }
     1218  return i;
    9871219}
    9881220
  • fmtext.c

    r005fc22 r6f6330b  
    88void owl_fmtext_init_null(owl_fmtext *f)
    99{
    10   f->textlen=0;
    11   f->bufflen=5;
    12   f->textbuff=owl_malloc(5);
    13   f->fmbuff=owl_malloc(5);
    14   f->fgcolorbuff=owl_malloc(5 * sizeof(short));
    15   f->bgcolorbuff=owl_malloc(5 * sizeof(short));
    16   f->textbuff[0]=0;
    17   f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
    18   f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
    19   f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
     10  f->textlen = 0;
     11  f->bufflen = 5;
     12  f->textbuff = owl_malloc(5);
     13  f->textbuff[0] = 0;
     14  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
     15  f->default_fgcolor = OWL_COLOR_DEFAULT;
     16  f->default_bgcolor = OWL_COLOR_DEFAULT;
    2017}
    2118
     
    2421void owl_fmtext_clear(owl_fmtext *f)
    2522{
    26     f->textlen = 0;
    27     f->textbuff[0] = 0;
    28     f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
    29     f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
    30     f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
    31 }
    32 
    33 /* Internal function.  Set the attribute 'attr' from index 'first' to
    34  * index 'last'
    35  */
    36 void _owl_fmtext_set_attr(owl_fmtext *f, int attr, int first, int last)
    37 {
    38   int i;
    39   for (i=first; i<=last; i++) {
    40     f->fmbuff[i]=(unsigned char) attr;
    41   }
    42 }
    43 
    44 /* Internal function.  Add the attribute 'attr' to the existing
    45  * attributes from index 'first' to index 'last'
    46  */
    47 void _owl_fmtext_add_attr(owl_fmtext *f, int attr, int first, int last)
    48 {
    49   int i;
    50   for (i=first; i<=last; i++) {
    51     f->fmbuff[i]|=(unsigned char) attr;
    52   }
    53 }
    54 
    55 /* Internal function.  Set the color to be 'color' from index 'first'
    56  * to index 'last
    57  */
    58 void _owl_fmtext_set_fgcolor(owl_fmtext *f, int color, int first, int last)
    59 {
    60   int i;
    61   for (i=first; i<=last; i++) {
    62     f->fgcolorbuff[i]=(short)color;
    63   }
    64 }
    65 
    66 void _owl_fmtext_set_bgcolor(owl_fmtext *f, int color, int first, int last)
    67 {
    68   int i;
    69   for (i=first; i<=last; i++) {
    70     f->bgcolorbuff[i]=(short)color;
    71   }
     23  f->textlen = 0;
     24  f->textbuff[0] = 0;
     25  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
     26  f->default_fgcolor = OWL_COLOR_DEFAULT;
     27  f->default_bgcolor = OWL_COLOR_DEFAULT;
    7228}
    7329
     
    7531{
    7632    if(newlen + 1 > f->bufflen) {
    77       f->textbuff=owl_realloc(f->textbuff, newlen+1);
    78       f->fmbuff=owl_realloc(f->fmbuff, newlen+1);
    79       f->fgcolorbuff=owl_realloc(f->fgcolorbuff, (newlen+1) * sizeof(short));
    80       f->bgcolorbuff=owl_realloc(f->bgcolorbuff, (newlen+1) * sizeof(short));
     33      f->textbuff = owl_realloc(f->textbuff, newlen + 1);
    8134      f->bufflen = newlen+1;
    8235  }
    8336}
    8437
     38int owl_fmtext_is_format_char(gunichar c)
     39{
     40  if ((c & ~OWL_FMTEXT_UC_ATTR_MASK) == OWL_FMTEXT_UC_ATTR) return 1;
     41  if ((c & ~(OWL_FMTEXT_UC_ALLCOLOR_MASK)) == OWL_FMTEXT_UC_COLOR_BASE) return 1;
     42  return 0;
     43}
    8544/* append text to the end of 'f' with attribute 'attr' and color
    8645 * 'color'
    8746 */
    88 void owl_fmtext_append_attr(owl_fmtext *f, char *text, int attr, int fgcolor, int bgcolor)
    89 {
    90   int newlen;
    91   newlen=strlen(f->textbuff)+strlen(text);
     47void owl_fmtext_append_attr(owl_fmtext *f, char *text, char attr, short fgcolor, short bgcolor)
     48{
     49  char attrbuff[6];
     50  int newlen, a = 0, fg = 0, bg = 0;
     51 
     52  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
     53  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
     54  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
     55
     56  /* Plane-16 characters in UTF-8 are 4 bytes long. */
     57  newlen = strlen(f->textbuff) + strlen(text) + (8 * (a + fg + bg));
    9258  _owl_fmtext_realloc(f, newlen);
     59
     60  /* Set attributes */
     61  if (a) {
     62    memset(attrbuff,0,6);
     63    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
     64    strcat(f->textbuff, attrbuff);     
     65  }
     66  if (fg) {
     67    memset(attrbuff,0,6);
     68    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
     69    strcat(f->textbuff, attrbuff);     
     70  }
     71  if (bg) {
     72    memset(attrbuff,0,6);
     73    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
     74    strcat(f->textbuff, attrbuff);     
     75  }
    9376 
    9477  strcat(f->textbuff, text);
    95   _owl_fmtext_set_attr(f, attr, f->textlen, newlen);
    96   _owl_fmtext_set_fgcolor(f, fgcolor, f->textlen, newlen);
    97   _owl_fmtext_set_bgcolor(f, bgcolor, f->textlen, newlen);
     78
     79  /* Reset attributes */
     80  if (bg) strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
     81  if (fg) strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
     82  if (a)  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
    9883  f->textlen=newlen;
    9984}
     
    129114}
    130115
    131 /* Add the attribute 'attr' to all text in 'f' */
    132 void owl_fmtext_addattr(owl_fmtext *f, int attr)
     116/* Add the attribute 'attr' to the default atts for the text in 'f' */
     117void owl_fmtext_addattr(owl_fmtext *f, char attr)
    133118{
    134119  /* add the attribute to all text */
    135   int i, j;
    136 
    137   j=f->textlen;
    138   for (i=0; i<j; i++) {
    139     f->fmbuff[i] |= attr;
    140   }
    141 }
    142 
    143 /* Anywhere the color is NOT ALREDY SET, set the color to 'color'.
    144  * Other colors are left unchanged
     120  f->default_attrs |= attr;
     121}
     122
     123/* Set the default foreground color for this fmtext to 'color'.
     124 * Only affects text that is colored default.
    145125 */
    146126void owl_fmtext_colorize(owl_fmtext *f, int color)
    147127{
    148   /* everywhere the fgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
    149   int i, j;
    150 
    151   j=f->textlen;
    152   for(i=0; i<j; i++) {
    153     if (f->fgcolorbuff[i]==OWL_COLOR_DEFAULT) f->fgcolorbuff[i] = (short)color;
    154   }
    155 }
    156 
     128  f->default_fgcolor = color;
     129}
     130
     131/* Set the default foreground color for this fmtext to 'color'.
     132 * Only affects text that is colored default.
     133 */
    157134void owl_fmtext_colorizebg(owl_fmtext *f, int color)
    158135{
    159   /* everywhere the bgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
    160   int i, j;
    161 
    162   j=f->textlen;
    163   for(i=0; i<j; i++) {
    164     if (f->bgcolorbuff[i]==OWL_COLOR_DEFAULT) f->bgcolorbuff[i] = (short)color;
    165   }
    166 }
     136  f->default_bgcolor = color;
     137}
     138
     139/* Internal function. Parse attrbute character. */
     140void _owl_fmtext_update_attributes(gunichar c, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
     141{
     142  if ((c & OWL_FMTEXT_UC_ATTR) == OWL_FMTEXT_UC_ATTR) {
     143    *attr = c & OWL_FMTEXT_UC_ATTR_MASK;
     144  }
     145  else if ((c & OWL_FMTEXT_UC_COLOR_BASE) == OWL_FMTEXT_UC_COLOR_BASE) {
     146    if ((c & OWL_FMTEXT_UC_BGCOLOR) == OWL_FMTEXT_UC_BGCOLOR) {
     147      *bgcolor = (c == OWL_FMTEXT_UC_BGDEFAULT
     148                  ? OWL_COLOR_DEFAULT
     149                  : c & OWL_FMTEXT_UC_COLOR_MASK);
     150    }
     151    else if ((c & OWL_FMTEXT_UC_FGCOLOR) == OWL_FMTEXT_UC_FGCOLOR) {
     152      *fgcolor = (c == OWL_FMTEXT_UC_FGDEFAULT
     153                  ? OWL_COLOR_DEFAULT
     154                  : c & OWL_FMTEXT_UC_COLOR_MASK);
     155    }
     156  }
     157}
     158
     159/* Internal function. Scan for attribute characters. */
     160void _owl_fmtext_scan_attributes(owl_fmtext *f, int start, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
     161{
     162  char *p;
     163  p = strchr(f->textbuff, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     164  while (p && p < f->textbuff + start) {
     165    _owl_fmtext_update_attributes(g_utf8_get_char(p), attr, fgcolor, bgcolor);
     166    p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     167  }
     168
    167169
    168170/* Internal function.  Append text from 'in' between index 'start' and
    169171 * 'stop' to the end of 'f'
    170172 */
    171 void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop)
    172 {
    173   int newlen, i;
    174 
    175   newlen=strlen(f->textbuff)+(stop-start+1);
     173void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop) /*noproto*/
     174{
     175  char attrbuff[6];
     176  int newlen, a = 0, fg = 0, bg = 0;
     177  char attr = 0;
     178  short fgcolor = OWL_COLOR_DEFAULT;
     179  short bgcolor = OWL_COLOR_DEFAULT;
     180
     181  _owl_fmtext_scan_attributes(in, start, &attr, &fgcolor, &bgcolor);
     182  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
     183  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
     184  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
     185
     186  /* We will reset to defaults after appending the text. We may need
     187     to set initial attributes. */
     188  newlen=strlen(f->textbuff)+(stop-start+1) + (4 * (a + fg + bg)) + 12;
    176189  _owl_fmtext_realloc(f, newlen);
    177190
     191  if (a) {
     192    memset(attrbuff,0,6);
     193    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
     194    strcat(f->textbuff, attrbuff);     
     195  }
     196  if (fg) {
     197    memset(attrbuff,0,6);
     198    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
     199    strcat(f->textbuff, attrbuff);     
     200  }
     201  if (bg) {
     202    memset(attrbuff,0,6);
     203    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
     204    strcat(f->textbuff, attrbuff);     
     205  }
     206
    178207  strncat(f->textbuff, in->textbuff+start, stop-start+1);
     208
     209  /* Reset attributes */
     210  strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
     211  strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
     212  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
     213
    179214  f->textbuff[newlen]='\0';
    180   for (i=start; i<=stop; i++) {
    181     f->fmbuff[f->textlen+(i-start)]=in->fmbuff[i];
    182     f->fgcolorbuff[f->textlen+(i-start)]=in->fgcolorbuff[i];
    183     f->bgcolorbuff[f->textlen+(i-start)]=in->bgcolorbuff[i];
    184   }
    185215  f->textlen=newlen;
    186216}
     
    207237char *owl_fmtext_print_plain(owl_fmtext *f)
    208238{
    209   return(owl_strdup(f->textbuff));
     239  return owl_strip_format_chars(f->textbuff);
     240}
     241
     242void _owl_fmtext_wattrset(WINDOW *w, int attrs) /*noproto*/
     243{
     244  wattrset(w, A_NORMAL);
     245  if (attrs & OWL_FMTEXT_ATTR_BOLD) wattron(w, A_BOLD);
     246  if (attrs & OWL_FMTEXT_ATTR_REVERSE) wattron(w, A_REVERSE);
     247  if (attrs & OWL_FMTEXT_ATTR_UNDERLINE) wattron(w, A_UNDERLINE);
     248}
     249
     250void _owl_fmtext_update_colorpair(short fg, short bg, short *pair) /*noproto*/
     251{
     252  if (owl_global_get_hascolors(&g)) {
     253    *pair = owl_fmtext_get_colorpair(fg, bg);
     254  }
     255}
     256
     257void _owl_fmtext_wcolor_set(WINDOW *w, short pair) /*noproto*/
     258{
     259  if (owl_global_get_hascolors(&g)) {
     260      wcolor_set(w,pair,NULL);
     261  }
    210262}
    211263
     
    213265 * must already be initiatlized with curses
    214266 */
    215 void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
    216 {
    217   char *tmpbuff;
    218   int position, trans1, trans2, trans3, len, lastsame;
    219 
     267void _owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w, int do_search) /*noproto*/
     268{
     269  /* char *tmpbuff; */
     270  /* int position, trans1, trans2, trans3, len, lastsame; */
     271  char *s, *p;
     272  char attr;
     273  short fg, bg, pair;
     274  int search_results, search_len;
     275 
    220276  if (w==NULL) {
    221277    owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
     
    223279  }
    224280
    225   tmpbuff=owl_malloc(f->textlen+10);
    226 
    227   position=0;
    228   len=f->textlen;
    229   while (position<=len) {
    230     /* find the last char with the current format and color */
    231     trans1=owl_util_find_trans(f->fmbuff+position, len-position);
    232     trans2=owl_util_find_trans_short(f->fgcolorbuff+position, len-position);
    233     trans3=owl_util_find_trans_short(f->bgcolorbuff+position, len-position);
    234 
    235     lastsame = (trans1 < trans2) ? trans1 : trans2;
    236     lastsame = (lastsame < trans3) ? lastsame : trans3;
    237     lastsame += position;
    238 
    239     /* set the format */
    240     wattrset(w, A_NORMAL);
    241     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_BOLD) {
    242       wattron(w, A_BOLD);
    243     }
    244     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_REVERSE) {
    245       wattron(w, A_REVERSE);
    246     }
    247     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_UNDERLINE) {
    248       wattron(w, A_UNDERLINE);
    249     }
    250 
    251     /* set the color */
    252     /* warning, this is sort of a hack */
    253     if (owl_global_get_hascolors(&g)) {
    254       short fg, bg, pair;
    255       fg = f->fgcolorbuff[position];
    256       bg = f->bgcolorbuff[position];
    257 
    258       pair = owl_fmtext_get_colorpair(fg, bg);
    259       if (pair != -1) {
    260         wcolor_set(w,pair,NULL);
    261       }
    262     }
    263 
    264     /* add the text */
    265     strncpy(tmpbuff, f->textbuff + position, lastsame-position+1);
    266     tmpbuff[lastsame-position+1]='\0';
    267     waddstr(w, tmpbuff);
    268 
    269     position=lastsame+1;
    270   }
    271   owl_free(tmpbuff);
    272 }
    273 
     281  search_results = (do_search
     282                    ? owl_fmtext_search(f, owl_global_get_search_string(&g))
     283                    : 0);
     284  search_len = (search_results
     285                ? strlen(owl_global_get_search_string(&g))
     286                : 0);
     287  s = f->textbuff;
     288  /* Set default attributes. */
     289  attr = f->default_attrs;
     290  fg = f->default_fgcolor;
     291  bg = f->default_bgcolor;
     292  _owl_fmtext_wattrset(w, attr);
     293  _owl_fmtext_update_colorpair(fg, bg, &pair);
     294  _owl_fmtext_wcolor_set(w, pair);
     295
     296  /* Find next possible format character. */
     297  p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     298  while(p) {
     299    if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     300      /* Deal with all text from last insert to here. */
     301      char tmp;
     302   
     303      tmp = p[0];
     304      p[0] = '\0';
     305      if (search_results) {
     306        /* Search is active, so highlight search results. */
     307        char tmp2, *ss;
     308        ss = stristr(s, owl_global_get_search_string(&g));
     309        while (ss) {
     310          /* Found search string, highlight it. */
     311
     312          tmp2 = ss[0];
     313          ss[0] = '\0';
     314          waddstr(w, s);
     315          ss[0] = tmp2;
     316
     317          _owl_fmtext_wattrset(w, attr ^ OWL_FMTEXT_ATTR_REVERSE);
     318          _owl_fmtext_wcolor_set(w, pair);
     319         
     320          tmp2 = ss[search_len];
     321          ss[search_len] = '\0';
     322          waddstr(w, ss);
     323          ss[search_len] = tmp2;
     324
     325          _owl_fmtext_wattrset(w, attr);
     326          _owl_fmtext_wcolor_set(w, pair);
     327
     328          s = ss + search_len;
     329          ss = stristr(s, owl_global_get_search_string(&g));
     330        }
     331      }
     332      /* Deal with remaining part of string. */
     333      waddstr(w, s);
     334      p[0] = tmp;
     335
     336      /* Deal with new attributes. Initialize to defaults, then
     337         process all consecutive formatting characters. */
     338      attr = f->default_attrs;
     339      fg = f->default_fgcolor;
     340      bg = f->default_bgcolor;
     341      while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     342        _owl_fmtext_update_attributes(g_utf8_get_char(p), &attr, &fg, &bg);
     343        p = g_utf8_next_char(p);
     344      }
     345      _owl_fmtext_wattrset(w, attr | f->default_attrs);
     346      if (fg == OWL_COLOR_DEFAULT) fg = f->default_fgcolor;
     347      if (bg == OWL_COLOR_DEFAULT) bg = f->default_bgcolor;
     348      _owl_fmtext_update_colorpair(fg, bg, &pair);
     349      _owl_fmtext_wcolor_set(w, pair);
     350
     351      /* Advance to next non-formatting character. */
     352      s = p;
     353      p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     354    }
     355    else {
     356      p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     357    }
     358  }
     359  if (s) {
     360    waddstr(w, s);
     361  }
     362}
     363
     364void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
     365{
     366  _owl_fmtext_curs_waddstr(f, w, owl_global_is_search_active(&g));
     367}
     368
     369void owl_fmtext_curs_waddstr_without_search(owl_fmtext *f, WINDOW *w)
     370{
     371  _owl_fmtext_curs_waddstr(f, w, 0);
     372}
    274373
    275374/* start with line 'aline' (where the first line is 0) and print
     
    282381 
    283382  /* find the starting line */
    284   ptr1=in->textbuff;
    285   if (aline!=0) {
    286     for (i=0; i<aline; i++) {
    287       ptr1=strchr(ptr1, '\n');
    288       if (!ptr1) return(-1);
    289       ptr1++;
    290     }
    291   }
     383  ptr1 = in->textbuff;
     384  for (i = 0; i < aline; i++) {
     385    ptr1 = strchr(ptr1, '\n');
     386    if (!ptr1) return(-1);
     387    ptr1++;
     388  }
     389 
    292390  /* ptr1 now holds the starting point */
    293391
     392  /* copy the default attributes */
     393  out->default_attrs = in->default_attrs;
     394  out->default_fgcolor = in->default_fgcolor;
     395  out->default_bgcolor = in->default_bgcolor;
     396   
    294397  /* copy in the next 'lines' lines */
    295   if (lines<1) return(-1);
    296 
    297   for (i=0; i<lines; i++) {
    298     offset=ptr1-in->textbuff;
    299     ptr2=strchr(ptr1, '\n');
     398  if (lines < 1) return(-1);
     399
     400  for (i = 0; i < lines; i++) {
     401    offset = ptr1 - in->textbuff;
     402    ptr2 = strchr(ptr1, '\n');
    300403    if (!ptr2) {
    301       _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
     404      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen) - 1);
    302405      return(-1);
    303406    }
    304     _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
    305     ptr1=ptr2+1;
     407    _owl_fmtext_append_fmtext(out, in, offset, (ptr2 - ptr1) + offset);
     408    ptr1 = ptr2 + 1;
    306409  }
    307410  return(0);
     
    311414 * ends at 'bcol' or sooner.  The first column is number 0.  The new
    312415 * message is placed in 'out'.  The message is * expected to end in a
    313  * new line for now
     416 * new line for now. NOTE: This needs to be modified to deal with
     417 * backing up if we find a SPACING COMBINING MARK at the end of a
     418 * line. If that happens, we should back up to the last non-mark
     419 * character and stop there.
    314420 */
    315421void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
    316422{
    317   char *ptr1, *ptr2, *last;
    318   int len, offset;
     423  char *ptr_s, *ptr_e, *ptr_c, *last;
     424  int col, st, padding, chwidth;
     425
     426  /* copy the default attributes */
     427  out->default_attrs = in->default_attrs;
     428  out->default_fgcolor = in->default_fgcolor;
     429  out->default_bgcolor = in->default_bgcolor;
    319430
    320431  last=in->textbuff+in->textlen-1;
    321   ptr1=in->textbuff;
    322   while (ptr1<=last) {
    323     ptr2=strchr(ptr1, '\n');
    324     if (!ptr2) {
     432  ptr_s=in->textbuff;
     433  while (ptr_s <= last) {
     434    ptr_e=strchr(ptr_s, '\n');
     435    if (!ptr_e) {
    325436      /* but this shouldn't happen if we end in a \n */
    326437      break;
    327438    }
    328439   
    329     if (ptr2==ptr1) {
     440    if (ptr_e == ptr_s) {
    330441      owl_fmtext_append_normal(out, "\n");
    331       ptr1++;
     442      ++ptr_s;
    332443      continue;
    333444    }
    334445
    335     /* we need to check that we won't run over here */
    336     len=bcol-acol;
    337     if (len > (ptr2-(ptr1+acol))) {
    338       /* the whole line fits with room to spare, don't take a full 'len' */
    339       len=ptr2-(ptr1+acol);
    340     }
    341     if (len>last-ptr1) {
    342       /* the whole rest of the text fits with room to spare, adjust for it */
    343       len-=(last-ptr1);
    344     }
    345     if (len<=0) {
    346       /* saftey check */
     446    col = 0;
     447    st = 0;
     448    padding = 0;
     449    chwidth = 0;
     450    ptr_c = ptr_s;
     451    while(ptr_c < ptr_e) {
     452      gunichar c = g_utf8_get_char(ptr_c);
     453      if (!owl_fmtext_is_format_char(c)) {
     454        chwidth = mk_wcwidth(c);
     455        if (col + chwidth > bcol) break;
     456       
     457        if (col >= acol) {
     458          if (st == 0) {
     459            ptr_s = ptr_c;
     460            padding = col - acol;
     461            ++st;
     462          }
     463        }
     464        col += chwidth;
     465        chwidth = 0;
     466      }
     467      ptr_c = g_utf8_next_char(ptr_c);
     468    }
     469    if (st) {
     470      /* lead padding */
     471      owl_fmtext_append_spaces(out, padding);
     472      if (ptr_c == ptr_e) {
     473        /* We made it to the newline. */
     474        _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
     475      }
     476      else {
     477        if (chwidth > 1) {
     478          /* Last char is wide, truncate. */
     479          _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff - 1);
     480          owl_fmtext_append_normal(out, "\n");
     481        }
     482        else {
     483          /* Last char fits perfectly, leave alone.*/
     484          _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
     485        }
     486      }
     487    }
     488    else {
    347489      owl_fmtext_append_normal(out, "\n");
    348       ptr1=ptr2+1;
    349       continue;
    350     }
    351 
    352     offset=ptr1-in->textbuff;
    353     _owl_fmtext_append_fmtext(out, in, offset+acol, offset+acol+len);
    354 
    355     ptr1=ptr2+1;
     490    }
     491    ptr_s = g_utf8_next_char(ptr_e);
    356492  }
    357493}
     
    381517
    382518/* set the charater at 'index' to be 'char'.  If index is out of
    383  * bounds don't do anything */
    384 void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
     519 * bounds don't do anything. If c or char at index is not ASCII, don't
     520 * do anything because it's not UTF-8 safe. */
     521void owl_fmtext_set_char(owl_fmtext *f, int index, char ch)
    385522{
    386523  if ((index < 0) || (index > f->textlen-1)) return;
     524  /* NOT ASCII*/
     525  if (f->textbuff[index] & 0x80 || ch & 0x80) return;
    387526  f->textbuff[index]=ch;
    388527}
     
    401540  dst->bufflen=mallocsize;
    402541  dst->textbuff=owl_malloc(mallocsize);
    403   dst->fmbuff=owl_malloc(mallocsize);
    404   dst->fgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    405   dst->bgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    406542  memcpy(dst->textbuff, src->textbuff, src->textlen+1);
    407   memcpy(dst->fmbuff, src->fmbuff, src->textlen);
    408   memcpy(dst->fgcolorbuff, src->fgcolorbuff, src->textlen * sizeof(short));
    409   memcpy(dst->bgcolorbuff, src->bgcolorbuff, src->textlen * sizeof(short));
    410 }
    411 
    412 /* highlight all instances of "string".  Return the number of
    413  * instances found.  This is a case insensitive search.
    414  */
    415 int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
    416 {
    417 
    418   int found, len;
    419   char *ptr1, *ptr2;
    420 
    421   len=strlen(string);
    422   found=0;
    423   ptr1=f->textbuff;
    424   while (ptr1-f->textbuff <= f->textlen) {
    425     ptr2=stristr(ptr1, string);
    426     if (!ptr2) return(found);
    427 
    428     found++;
    429     _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
    430                          ptr2 - f->textbuff,
    431                          ptr2 - f->textbuff + len - 1);
    432 
    433     ptr1=ptr2+len;
    434   }
    435   return(found);
     543  dst->default_attrs = src->default_attrs;
     544  dst->default_fgcolor = src->default_fgcolor;
     545  dst->default_bgcolor = src->default_bgcolor;
    436546}
    437547
     
    441551int owl_fmtext_search(owl_fmtext *f, char *string)
    442552{
    443 
    444553  if (stristr(f->textbuff, string)) return(1);
    445554  return(0);
     
    682791{
    683792  if (f->textbuff) owl_free(f->textbuff);
    684   if (f->fmbuff) owl_free(f->fmbuff);
    685   if (f->fgcolorbuff) owl_free(f->fgcolorbuff);
    686   if (f->bgcolorbuff) owl_free(f->bgcolorbuff);
    687793}
    688794
  • keymap.c

    rcf83b7a r428834d  
    55
    66/* returns 0 on success */
    7 int owl_keymap_init(owl_keymap *km, char *name, char *desc, void (*default_fn)(int), void (*prealways_fn)(int), void (*postalways_fn)(int))
     7int owl_keymap_init(owl_keymap *km, char *name, char *desc, void (*default_fn)(owl_input), void (*prealways_fn)(owl_input), void (*postalways_fn)(owl_input))
    88{
    99  if (!name || !desc) return(-1);
     
    151151}
    152152
    153 owl_keymap *owl_keyhandler_create_and_add_keymap(owl_keyhandler *kh, char *name, char *desc, void (*default_fn)(int), void (*prealways_fn)(int), void (*postalways_fn)(int))
     153owl_keymap *owl_keyhandler_create_and_add_keymap(owl_keyhandler *kh, char *name, char *desc, void (*default_fn)(owl_input), void (*prealways_fn)(owl_input), void (*postalways_fn)(owl_input))
    154154{
    155155  owl_keymap *km;
     
    202202/* processes a keypress.  returns 0 if the keypress was handled,
    203203 * 1 if not handled, -1 on error, and -2 if j==ERR. */
    204 int owl_keyhandler_process(owl_keyhandler *kh, int j)
     204int owl_keyhandler_process(owl_keyhandler *kh, owl_input j)
    205205{
    206206  owl_keymap     *km;
     
    214214
    215215  /* temporarily disallow C-`/C-SPACE until we fix associated bugs */
    216   if (j==ERR || j==0) {
     216  if (j.ch == ERR || j.ch == 0) {
    217217        return(-1);
    218218  }
     
    224224
    225225  /* deal with ESC prefixing */
    226   if (!kh->in_esc && j==27) {
     226  if (!kh->in_esc && j.ch == 27) {
    227227    kh->in_esc = 1;
    228228    return(0);
    229229  }
    230230  if (kh->in_esc) {
    231     j = OWL_META(j);
     231    j.ch = OWL_META(j.ch);
    232232    kh->in_esc = 0;
    233233  }
    234234 
    235   kh->kpstack[++(kh->kpstackpos)] = j;
     235  kh->kpstack[++(kh->kpstackpos)] = j.ch;
    236236  if (kh->kpstackpos >= OWL_KEYMAP_MAXSTACK) {
    237237    owl_keyhandler_reset(kh);
     
    260260      } else if (match == 2) {  /* exact match */
    261261        /* owl_function_debugmsg("processkey: found exact match in %s", km->name); */
    262         owl_keybinding_execute(kb, j);
     262        owl_keybinding_execute(kb, j.ch);
    263263        owl_keyhandler_reset(kh);
    264264        if (km->postalways_fn) {
  • keypress.c

    r948b942 r428834d  
    148148  }
    149149  if (!*kb) {
    150     if (j&OWL_META(0)) {
     150    if (j & OWL_META(0)) {
    151151      strcat(kb, "M-");
    152152      j &= ~OWL_META(0);
     
    163163      strcat(kb, kb2);   
    164164    }
     165   
    165166  } 
    166167  if (!*kb) {
  • logging.c

    raf1920fd ree310eb  
    155155    to = owl_sprintf("jabber:%s", owl_message_get_recipient(m));
    156156  } else if (owl_message_is_type_aim(m)) {
     157    char *temp2;
    157158    temp = owl_aim_normalize_screenname(owl_message_get_recipient(m));
    158     downstr(temp);
    159     to = owl_sprintf("aim:%s", temp);
     159    temp2 = g_utf8_strdown(temp,-1);
     160    to = owl_sprintf("aim:%s", temp2);
     161    owl_free(temp2);
    160162    owl_free(temp);
    161163  } else {
     
    267269  } else if (owl_message_is_type_aim(m)) {
    268270    /* we do not yet handle chat rooms */
    269     char *normalto;
    270     normalto=owl_aim_normalize_screenname(owl_message_get_sender(m));
    271     downstr(normalto);
     271    char *normalto, *temp;
     272    temp = owl_aim_normalize_screenname(owl_message_get_sender(m));
     273    normalto = g_utf8_strdown(temp, -1);
    272274    from=frombuff=owl_sprintf("aim:%s", normalto);
    273275    owl_free(normalto);
     276    owl_free(temp);
    274277  } else if (owl_message_is_type_loopback(m)) {
    275278    from=frombuff=owl_strdup("loopback");
     
    290293
    291294  ch=frombuff[0];
    292   if (!isalnum(ch)) from="weird";
     295  if (!g_ascii_isalnum(ch)) from="weird";
    293296
    294297  for (i=0; i<len; i++) {
     
    299302
    300303  if (!personal) {
    301     if (strcmp(from, "weird")) downstr(from);
     304    if (strcmp(from, "weird")) {
     305      char* temp = g_utf8_strdown(frombuff, -1);
     306      if (temp) {
     307        owl_free(frombuff);
     308        from = frombuff = temp;
     309      }
     310    }
    302311  }
    303312
  • message.c

    r18108b1e r07bfbc2  
    7979    owl_list_append_element(&(m->attributes), pair);
    8080  }
    81   owl_pair_set_value(pair, owl_strdup(attrvalue));
     81  owl_pair_set_value(pair, owl_validate_or_convert(attrvalue));
    8282}
    8383
     
    493493{
    494494  if(m->zwriteline) owl_free(m->zwriteline);
    495   m->zwriteline=strdup(line);
     495  m->zwriteline=owl_strdup(line);
    496496}
    497497
     
    535535  owl_fmtext_init_null(&b);
    536536 
    537   owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline+1, &a);
     537  owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline, &a);
    538538  owl_fmtext_truncate_cols(&a, acol, bcol, &b);
    539   if (fgcolor!=OWL_COLOR_DEFAULT) {
    540     owl_fmtext_colorize(&b, fgcolor);
    541   }
    542   if (bgcolor!=OWL_COLOR_DEFAULT) {
    543     owl_fmtext_colorizebg(&b, bgcolor);
    544   }
    545 
    546   if (owl_global_is_search_active(&g)) {
    547     owl_fmtext_search_and_highlight(&b, owl_global_get_search_string(&g));
    548   }
    549      
     539  owl_fmtext_colorize(&b, fgcolor);
     540  owl_fmtext_colorizebg(&b, bgcolor);
     541
    550542  owl_fmtext_curs_waddstr(&b, win);
    551543
     
    892884  }
    893885
    894   m->zwriteline=strdup("");
     886  m->zwriteline=owl_strdup("");
    895887
    896888  /* save the hostname */
     
    974966  }
    975967
    976   m->zwriteline=strdup("");
     968  m->zwriteline=owl_strdup("");
    977969
    978970  owl_message_set_body(m, "<uninitialized>");
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm

    r6b580b0 r5f3168a  
    11use warnings;
    22use strict;
     3use utf8;
    34
    45=head1 NAME
  • perl/modules/Jabber/lib/Net/XMPP/Debug.pm

    rc2bed55 rb7b2a76  
    189189                        {
    190190                            $self->{HANDLE}->autoflush(1);
     191                            binmode $self->{HANDLE}, ":utf8";
    191192                            $Net::XMPP::Debug::HANDLES{$args{file}} = $self->{HANDLE};
    192193                        }
  • perl/modules/Jabber/lib/Net/XMPP/Message.pm

    rc2bed55 r8574801  
    135135                            $Mess->SetMessage(TO=>"bob\@jabber.org",
    136136                                              Subject=>"Lunch",
    137                                               BoDy=>"Let's do lunch!");
     137                                              Body=>"Let's do lunch!");
    138138                            $Mess->SetMessage(to=>"bob\@jabber.org",
    139139                                              from=>"jabber.org",
  • perl/modules/Jabber/lib/XML/Stream.pm

    r5073972 ra8d5a39  
    16591659    {
    16601660        $self->debug(3,"Send: can_write");
    1661        
     1661
    16621662        $self->{SENDSTRING} = Encode::encode_utf8(join("",@_));
    16631663
  • text.c

    r3bcf125 rf8d9df1  
    5050void owl_text_truncate_cols(char *out, char *in, int acol, int bcol)
    5151{
    52   char *ptr1, *ptr2, *tmpbuff, *last;
    53   int len;
    54 
     52  char *ptr_s, *ptr_e, *ptr_c, *tmpbuff, *last;
     53  int col, cnt, padding;
     54 
    5555  tmpbuff=owl_malloc(strlen(in)+20);
    5656
    5757  strcpy(tmpbuff, "");
    5858  last=in+strlen(in)-1;
    59   ptr1=in;
    60   while (ptr1<last) {
    61     ptr2=strchr(ptr1, '\n');
    62     if (!ptr2) {
     59  ptr_s=in;
     60  while (ptr_s<last) {
     61    ptr_e=strchr(ptr_s, '\n');
     62    if (!ptr_e) {
    6363      /* but this shouldn't happen if we end in a \n */
    6464      break;
    6565    }
    6666   
    67     if (ptr2==ptr1) {
     67    if (ptr_e==ptr_s) {
    6868      strcat(tmpbuff, "\n");
    69       ptr1++;
    70       continue;
    71     }
    72 
     69      ptr_s++;
     70      continue;
     71    }
     72
     73    col = 0;
     74    cnt = 0;
     75    padding = 0;
     76    ptr_c = ptr_s;
     77    while(col < bcol && ptr_c < ptr_e) {
     78      gunichar c = g_utf8_get_char(ptr_c);
     79      if (col + mk_wcwidth(c) > bcol) break;
     80      col += mk_wcwidth(c);
     81      ptr_c = g_utf8_next_char(ptr_c);
     82      if (col >= acol) {
     83        if (cnt == 0) {
     84          ptr_s = ptr_c;
     85          padding = col - acol;
     86        }
     87        ++cnt;
     88      }
     89    }
     90    if (cnt) {
     91      while(padding-- > 0) {
     92        strcat(tmpbuff, " ");
     93      }
     94      strncat(tmpbuff, ptr_s, ptr_c - ptr_s - 1);
     95    }
     96    strcat(tmpbuff, "\n");
     97    ptr_s = ptr_e + 1;
     98#if 0
    7399    /* we need to check that we won't run over here */
    74     if ( (ptr2-ptr1) < (bcol-acol) ) {
    75       len=ptr2-(ptr1+acol);
     100    if ( (ptr_e-ptr_s) < (bcol-acol) ) {
     101      len=ptr_e-(ptr_s+acol);
    76102    } else {
    77103      len=bcol-acol;
    78104    }
    79     if ((ptr1+len)>=last) {
    80       len-=last-(ptr1+len);
    81     }
    82 
    83     strncat(tmpbuff, ptr1+acol, len);
     105    if ((ptr_s+len)>=last) {
     106      len-=last-(ptr_s+len);
     107    }
     108
     109    strncat(tmpbuff, ptr_s+acol, len);
    84110    strcat(tmpbuff, "\n");
    85111
    86     ptr1=ptr2+1;
     112    ptr_s=ptr_e+1;
     113#endif
    87114  }
    88115  strcpy(out, tmpbuff);
     
    275302char *stristr(char *a, char *b)
    276303{
    277   char *x, *y, *ret;
    278 
    279   if ((x=owl_strdup(a))==NULL) return(NULL);
    280   if ((y=owl_strdup(b))==NULL) return(NULL);
    281   downstr(x);
    282   downstr(y);
    283   ret=strstr(x, y);
    284   if (ret==NULL) {
    285     owl_free(x);
    286     owl_free(y);
    287     return(NULL);
    288   }
    289   ret=ret-x+a;
    290   owl_free(x);
    291   owl_free(y);
     304  char *x, *y;
     305  char *ret = NULL;
     306  if ((x = g_utf8_casefold(a, -1)) != NULL) {
     307    if ((y = g_utf8_casefold(b, -1)) != NULL) {
     308      ret = strstr(x, y);
     309      if (ret != NULL) {
     310        ret = ret - x + a;
     311      }
     312      g_free(y);
     313    }
     314    g_free(x);
     315  }
    292316  return(ret);
    293317}
     
    296320int only_whitespace(char *s)
    297321{
    298   int i;
    299   for (i=0; s[i]; i++) {
    300     if (!isspace((int) s[i])) return(0);
     322  if (g_utf8_validate(s,-1,NULL)) {
     323    char *p;
     324    for(p = s; p[0]; p=g_utf8_next_char(p)) {
     325      if (!g_unichar_isspace(g_utf8_get_char(p))) return 0;
     326    }
     327  }
     328  else {
     329    int i;
     330    for (i=0; s[i]; i++) {
     331      if (!isspace((int) s[i])) return(0);
     332    }
    301333  }
    302334  return(1);
     
    327359  tolen  = strlen(to);
    328360  fromlen  = strlen(from);
    329   out = malloc(outlen);
     361  out = owl_malloc(outlen);
    330362
    331363  while (in[inpos]) {
  • util.c

    raf1920fd ree310eb  
    399399}
    400400
    401 /* downcase the string 'foo' */
    402 void downstr(char *foo)
    403 {
    404   int i;
    405   for (i=0; foo[i]!='\0'; i++) {
    406     foo[i]=tolower(foo[i]);
    407   }
    408 }
    409 
    410401/* Caller must free response.
    411402 * Takes in strings which are space-separated lists of tokens
     
    446437void *owl_malloc(size_t size)
    447438{
    448   return(malloc(size));
     439  return(g_malloc(size));
    449440}
    450441
    451442void owl_free(void *ptr)
    452443{
    453   free(ptr);
     444  g_free(ptr);
    454445}
    455446
    456447char *owl_strdup(const char *s1)
    457448{
    458   return(strdup(s1));
     449  return(g_strdup(s1));
    459450}
    460451
    461452void *owl_realloc(void *ptr, size_t size)
    462453{
    463   return(realloc(ptr, size));
     454  return(g_realloc(ptr, size));
    464455}
    465456
    466457/* allocates memory and returns the string or null.
    467458 * caller must free the string.
    468  * from Linux sprintf man page.
    469459 */
    470460char *owl_sprintf(const char *fmt, ...)
    471461{
    472   int n, size = 100;
    473   char *p;
    474462  va_list ap;
    475   if ((p = owl_malloc (size)) == NULL) return (NULL);
    476   while (1) {
    477     /* Try to print in the allocated space. */
    478     va_start(ap, fmt);
    479     n = vsnprintf (p, size, fmt, ap);
    480     va_end(ap);
    481     /* If that worked, return the string. */
    482     if (n > -1 && n < size)
    483       return p;
    484     /* Else try again with more space. */
    485     if (n > -1)    /* glibc 2.1 */
    486       size = n+1; /* precisely what is needed */
    487     else           /* glibc 2.0 */
    488       size *= 2;  /* twice the old size */
    489     if ((p = owl_realloc (p, size)) == NULL)
    490       return NULL;
    491   }
    492 }
     463  char *ret = NULL;
     464  va_start(ap, fmt);
     465  ret = g_strdup_vprintf(fmt, ap);
     466  va_end(ap);
     467  return ret;
     468}
     469
    493470
    494471/* Return the owl color associated with the named color.  Return -1
     
    776753}
    777754
    778 char * owl_get_datadir() {
    779     char * datadir = getenv("BARNOWL_DATA_DIR");
    780     if(datadir != NULL)
    781         return strchr(datadir, '=') + 1;
    782     return DATADIR;
     755char * owl_get_datadir()
     756{
     757  char * datadir = getenv("BARNOWL_DATA_DIR");
     758  if(datadir != NULL)
     759    return strchr(datadir, '=') + 1;
     760  return DATADIR;
     761}
     762
     763/* Strips format characters from a valid utf-8 string. Returns the
     764   empty string if 'in' does not validate. */
     765char * owl_strip_format_chars(char *in)
     766{
     767  char *r;
     768  if (g_utf8_validate(in, -1, NULL)) {
     769    char *s, *p;
     770    r = owl_malloc(strlen(in)+1);
     771    r[0] = '\0';
     772    s = in;
     773    p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     774    while(p) {
     775      /* If it's a format character, copy up to it, and skip all
     776         immediately following format characters. */
     777      if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     778        strncat(r, s, p-s);
     779        p = g_utf8_next_char(p);
     780        while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     781          p = g_utf8_next_char(p);
     782        }
     783        s = p;
     784        p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     785      }
     786      else {
     787        p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     788      }
     789    }
     790    if (s) strcat(r,s);
     791  }
     792  else {
     793    r = owl_strdup("");
     794  }
     795  return r;
     796}
     797
     798/* If in is not UTF-8, convert from ISO-8859-1. We may want to allow
     799 * the caller to specify an alternative in the future. We also strip
     800 * out characters in Unicode Plane 16, as we use that plane internally
     801 * for formatting.
     802 */
     803char * owl_validate_or_convert(char *in)
     804{
     805  if (g_utf8_validate(in, -1, NULL)) {
     806    return owl_strip_format_chars(in);
     807  }
     808  else {
     809    return g_convert(in, -1,
     810                     "UTF-8", "ISO-8859-1",
     811                     NULL, NULL, NULL);
     812  }
     813}
     814/* Attempts to convert 'in' to ISO-8859-1. Returns that if possible,
     815   else returns UTF-8.
     816 */
     817char * owl_get_iso_8859_1_if_possible(char *in)
     818{
     819  char *out;
     820  if (g_utf8_validate(in, -1, NULL)) {
     821    out = g_convert(in, -1,
     822                    "ISO-8859-1", "UTF-8",
     823                    NULL, NULL, NULL);
     824    if (!out) {
     825      out = owl_strdup(in);
     826    }
     827  }
     828  else {
     829    out = owl_strdup("");
     830  }
     831  return out;
     832}
     833
     834/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
     835int owl_util_can_break_after(gunichar c)
     836{
     837 
     838  if (c == ' ') return 1;
     839  if (c >= 0x3000 && c <= 0x312f) {
     840    /* CJK punctuations, Hiragana, Katakana, Bopomofo */
     841    if (c == 0x300a || c == 0x300c || c == 0x300e ||
     842        c == 0x3010 || c == 0x3014 || c == 0x3016 ||
     843        c == 0x3018 || c == 0x301a)
     844      return 0;
     845    return 1;
     846  }
     847  if (c >= 0x31a0 && c <= 0x31bf) {return 1;}  /* Bopomofo */
     848  if (c >= 0x31f0 && c <= 0x31ff) {return 1;}  /* Katakana extension */
     849  if (c >= 0x3400 && c <= 0x9fff) {return 1;}  /* Han Ideogram */
     850  if (c >= 0xf900 && c <= 0xfaff) {return 1;}  /* Han Ideogram */
     851  if (c >= 0x20000 && c <= 0x2ffff) {return 1;}  /* Han Ideogram */
     852  return 0;
    783853}
    784854
  • viewwin.c

    r8721756 r47519e1b  
    7373  owl_fmtext_truncate_cols(&fm1, v->rightshift, v->wincols-1+v->rightshift, &fm2);
    7474
    75   owl_fmtext_curs_waddstr(&fm2, v->curswin);
     75  owl_fmtext_curs_waddstr_without_search(&fm2, v->curswin);
    7676
    7777  /* print the message at the bottom */
  • zcrypt.c

    r9ceee9d r34509d5  
    385385
    386386/* Build a space-separated string from argv from elements between start  *
    387  * and end - 1.  malloc()'s the returned string. */
     387 * and end - 1.  owl_malloc()'s the returned string. */
    388388char *BuildArgString(char **argv, int start, int end) {
    389389  int len = 1;
     
    397397
    398398  /* Allocate memory */
    399   result = (char *)malloc(len);
     399  result = (char *)owl_malloc(len);
    400400  if (result) {
    401401    /* Build the string */
     
    482482      /* Prepare result to be returned */
    483483      char *temp = keyfile;
    484       keyfile = (char *)malloc(strlen(temp) + 1);
     484      keyfile = (char *)owl_malloc(strlen(temp) + 1);
    485485      if (keyfile) {
    486486        strcpy(keyfile, temp);
     
    611611      }
    612612      use_buffer = TRUE;
    613       if ((inptr = inbuff = (char *)malloc(MAX_RESULT)) == NULL) {
     613      if ((inptr = inbuff = (char *)owl_malloc(MAX_RESULT)) == NULL) {
    614614        printf("Memory allocation error\n");
    615615        return FALSE;
     
    639639      printf("Could not run zwrite\n");
    640640      if (freein && inbuff) {
    641         free(inbuff);
     641        owl_free(inbuff);
    642642      }
    643643      return(FALSE);
     
    685685
    686686  /* Free the input buffer, if necessary */
    687   if (freein && inbuff) free(inbuff);
     687  if (freein && inbuff) owl_free(inbuff);
    688688
    689689  return(!error);
  • zephyr.c

    r9c7a701 r5577606  
    353353  return(owl_strdup(""));
    354354}
     355
     356char *owl_zephyr_get_field_as_utf8(ZNotice_t *n, int j)
     357{
     358  int i, count, save;
     359
     360  /* If there's no message here, just run along now */
     361  if (n->z_message_len == 0)
     362    return(owl_strdup(""));
     363
     364  count=save=0;
     365  for (i = 0; i < n->z_message_len; i++) {
     366    if (n->z_message[i]=='\0') {
     367      count++;
     368      if (count == j) {
     369        /* just found the end of the field we're looking for */
     370        return(owl_validate_or_convert(n->z_message + save));
     371      } else {
     372        save = i + 1;
     373      }
     374    }
     375  }
     376  /* catch the last field, which might not be null terminated */
     377  if (count == j - 1) {
     378    char *tmp, *out;
     379    tmp = owl_malloc(n->z_message_len-save+5);
     380    memcpy(tmp, n->z_message+save, n->z_message_len-save);
     381    tmp[n->z_message_len-save]='\0';
     382    out = owl_validate_or_convert(tmp);
     383    owl_free(tmp);
     384    return out;
     385  }
     386
     387  return(owl_strdup(""));
     388}
    355389#else
    356390char *owl_zephyr_get_field(void *n, int j)
    357391{
    358392  return(owl_strdup(""));
     393}
     394char *owl_zephyr_get_field_as_utf8(void *n, int j)
     395{
     396  return owl_zephyr_get_field(n, j);
    359397}
    360398#endif
  • zwrite.c

    r1fe100c r7b1d048  
    4444        break;
    4545      }
    46       z->class=owl_strdup(myargv[1]);
     46      z->class=owl_get_iso_8859_1_if_possible(myargv[1]);
    4747      myargv+=2;
    4848      myargc-=2;
     
    5252        break;
    5353      }
    54       z->inst=owl_strdup(myargv[1]);
     54      z->inst=owl_get_iso_8859_1_if_possible(myargv[1]);
    5555      myargv+=2;
    5656      myargc-=2;
     
    6060        break;
    6161      }
    62       z->realm=owl_strdup(myargv[1]);
     62      z->realm=owl_get_iso_8859_1_if_possible(myargv[1]);
    6363      myargv+=2;
    6464      myargc-=2;
     
    6868        break;
    6969      }
    70       z->zsig=owl_strdup(myargv[1]);
     70      z->zsig=owl_get_iso_8859_1_if_possible(myargv[1]);
    7171      myargv+=2;
    7272      myargc-=2;
     
    7676        break;
    7777      }
    78       z->opcode=owl_strdup(myargv[1]);
     78      z->opcode=owl_get_iso_8859_1_if_possible(myargv[1]);
    7979      myargv+=2;
    8080      myargc-=2;
     
    9393      myargv++;
    9494      myargc--;
    95       z->message=owl_strdup("");
     95      z->message=owl_get_iso_8859_1_if_possible("");
    9696      while (myargc) {
    97         z->message=realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
     97        z->message=owl_realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
    9898        strcat(z->message, myargv[0]);
    9999        strcat(z->message, " ");
     
    113113    } else {
    114114      /* anything unattached is a recipient */
    115       owl_list_append_element(&(z->recips), strdup(myargv[0]));
     115      owl_list_append_element(&(z->recips), owl_get_iso_8859_1_if_possible(myargv[0]));
    116116      myargv++;
    117117      myargc--;
     
    146146
    147147    if (zsigowlvar && *zsigowlvar) {
    148       z->zsig=owl_strdup(zsigowlvar);
     148      z->zsig=owl_get_iso_8859_1_if_possible(zsigowlvar);
    149149    } else if (zsigproc && *zsigproc) {
    150150      FILE *file;
     
    161161      if (!file) {
    162162        if (zsigzvar && *zsigzvar) {
    163           z->zsig=owl_strdup(zsigzvar);
     163          z->zsig=owl_get_iso_8859_1_if_possible(zsigzvar);
    164164        }
    165165      } else {
     
    175175      }
    176176    } else if (zsigzvar) {
    177       z->zsig=owl_strdup(zsigzvar);
     177      z->zsig=owl_get_iso_8859_1_if_possible(zsigzvar);
    178178    } else if (((pw=getpwuid(getuid()))!=NULL) && (pw->pw_gecos)) {
    179       z->zsig=strdup(pw->pw_gecos);
     179      z->zsig=owl_get_iso_8859_1_if_possible(pw->pw_gecos);
    180180      ptr=strchr(z->zsig, ',');
    181181      if (ptr) {
     
    218218  int i, j;
    219219  char toline[LINE];
     220  char *tmp = NULL;
    220221
    221222  if (z->message) owl_free(z->message);
     
    231232      }
    232233    }
    233     z->message=owl_sprintf("%s\n%s", toline, msg);
     234    tmp = owl_get_iso_8859_1_if_possible(msg);
     235    z->message=owl_sprintf("%s\n%s", toline, tmp);
    234236  } else {
    235     z->message=owl_strdup(msg);
    236   }
     237    z->message=owl_get_iso_8859_1_if_possible(msg);
     238  }
     239  if (tmp) owl_free(tmp);
    237240}
    238241
     
    305308{
    306309  if (z->opcode) owl_free(z->opcode);
    307   z->opcode=owl_strdup(opcode);
     310  z->opcode=owl_get_iso_8859_1_if_possible(opcode);
    308311}
    309312
Note: See TracChangeset for help on using the changeset viewer.