commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. mu-1-2-90-separate-argp-cfg


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. mu-1-2-90-separate-argp-cfg-323-g9b0dee5
Date: Fri, 14 Aug 2009 19:54:04 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=9b0dee5fa917d5804aa2ca89a186ea8da64578ca

The branch, master has been updated
       via  9b0dee5fa917d5804aa2ca89a186ea8da64578ca (commit)
      from  f2eb56bb7632e4044173a344964d6739a7ef4b7f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9b0dee5fa917d5804aa2ca89a186ea8da64578ca
Author: Sergey Poznyakoff <address@hidden>
Date:   Fri Aug 14 22:53:52 2009 +0300

    Mail: configurable `headers' output format.
    
    * mail/from.c: Rewrite using format string.
    * mail/mail.c (default_setup): Set default value for `headline'.
    (main): Fix call to util_do_command.
    * mail/mail.h [HAVE_STDARG_H]: Remove conditions.
    (mail_compile_headline): New proto.
    * mail/mailvar.c (mailvar_tab): New variable "headline".
    * mail/util.c: Minor fixes.
    * NEWS, doc/programs.texi: Update.

-----------------------------------------------------------------------

Summary of changes:
 NEWS                      |   10 +-
 doc/texinfo/programs.texi |  120 ++++++++++-
 mail/from.c               |  518 ++++++++++++++++++++++++++++++++++++++-------
 mail/mail.c               |    3 +-
 mail/mail.h               |    8 +-
 mail/mailvar.c            |    4 +
 mail/util.c               |   21 +--
 7 files changed, 583 insertions(+), 101 deletions(-)

diff --git a/NEWS b/NEWS
index 07bbfef..ed4a90e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU mailutils NEWS -- history of user-visible changes. 2009-08-03
+GNU mailutils NEWS -- history of user-visible changes. 2009-08-14
 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 
 2008, 2009 Free Software Foundation, Inc.
 See the end of file for copying conditions.
@@ -83,6 +83,12 @@ described.
 For each variable, this command prints its name, data type, current
 value and a short description.
 
+** headline variable
+
+The headline variable holds a format string to use for the header
+summary. Its format is mostly compatible with that of the `nail'
+mail reader.
+
 ** showenvelope variable
 
 If the `showenvelope' variable is set, print command will include the
@@ -90,7 +96,7 @@ SMTP envelope in its output.
 
 ** fromfield variable
 
-The `fromenvelope' boolean variable, if set, instructs mail to obtain
+The `fromfield' boolean variable, if set, instructs mail to obtain
 the sender address from the `From:' header.  This is the default.
 If unset, the sender address is obtained from the SMTP envelope.
 
diff --git a/doc/texinfo/programs.texi b/doc/texinfo/programs.texi
index 20be516..4135911 100644
--- a/doc/texinfo/programs.texi
+++ b/doc/texinfo/programs.texi
@@ -2240,14 +2240,14 @@ but before opening the mailbox.
 @itemx --file
 Operate on the mailbox given by the first non-optional command line
 argument. If there is no such argument, read messages from the
-user's @file{mbox} file. @xref{Reading Mail} for more details about
+user's @file{mbox} file. @xref{Reading Mail}, for more details about
 using this option.
 @item -F
 @itemx --byname
 Record outgoing messages in a file named after the first recipient.
 The name is the login-name portion of the address found first on the
 @samp{To:} line in the mail header. This option sets the @samp{byname}
-variable, which see (@xref{byname}).
+variable, which see (@pxref{byname}).
 @item -H
 @itemx --headers
 Print header summary to stdout and exit.
@@ -3482,6 +3482,7 @@ set
 Following variables control the behavior of GNU @command{mail}:
 
 @table @code
address@hidden append
 @item append
 @*Type: Boolean, Read-Only
 @*Default: True
@@ -3491,6 +3492,7 @@ Messages saved in mbox are appended to the end rather 
than prepended.
 This is the default and cannot be changed. This variable exists only
 for compatibility with other @command{mailx} implementations.
 
address@hidden appenddeadletter
 @item appenddeadletter
 @*Type: Boolean.
 @*Default: False.
@@ -3500,6 +3502,7 @@ If this variable is @code{True}, the contents of canceled 
letter is
 appended to the user's @file{dead.letter} file. Otherwise it overwrites
 its contents.
 
address@hidden askbcc
 @item askbcc
 @*Type: Boolean.
 @*Default: False.
@@ -3508,6 +3511,7 @@ its contents.
 When set to @code{True} the user will be prompted to enter @code{Bcc}
 field before composing the message.
 
address@hidden askcc
 @item askcc
 @*Type: Boolean.
 @*Default: True.
@@ -3516,6 +3520,7 @@ field before composing the message.
 When set to @code{True} the user will be prompted to enter @code{Cc}
 field before composing the message.
 
address@hidden asksub
 @item asksub
 @*Type: Boolean.
 @*Default: True in interactive mode, False otherwise.
@@ -3524,6 +3529,7 @@ field before composing the message.
 When set to @code{True} the user will be prompted to enter @code{Subject}
 field before composing the message.
 
address@hidden autoinc
 @item autoinc
 @*Type: Boolean.
 @*Default: True.
@@ -3531,6 +3537,7 @@ field before composing the message.
 
 Automatically incorporate newly arrived messages.
 
address@hidden autoprint
 @item autoprint
 @*Type: Boolean.
 @*Default: False.
@@ -3539,6 +3546,7 @@ Automatically incorporate newly arrived messages.
 Causes the delete command to behave like dp - thus, after deleting a
 message, the next one will be typed automatically.
 
address@hidden bang
 @item bang
 @*Type: Boolean.
 @*Default: False.
@@ -3548,6 +3556,7 @@ When set, every occurrence of @code{!} in arguments to 
@code{!}
 command is replaced with the last executed command.
 
 @anchor{byname}
address@hidden byname
 @item byname
 @*Type: Boolean
 @*Default: Unset
@@ -3561,6 +3570,7 @@ The name is the login-name portion of the address found 
first on the
 It is set by the @option{--byname} (@option{-F}) command line option.
 
 @anchor{datefield}
address@hidden datefield
 @item datefield
 @*Type: Boolean.
 @*Default: False.
@@ -3574,6 +3584,7 @@ will fall back to using @acronym{SMTP} envelope.
 
 @xref{fromfield}.
 
address@hidden charset
 @item charset
 @*Type: string
 @*Default: @samp{auto}
@@ -3586,6 +3597,7 @@ variable is set to @samp{auto}, @command{mail} tries to 
deduce the
 name of the character set from the value of @code{LC_ALL} environment
 variable. Otherwise, its value is taken as the name of the charset.
 
address@hidden cmd
 @item cmd
 @*Type: String.
 @*Default: Unset.
@@ -3593,6 +3605,7 @@ variable. Otherwise, its value is taken as the name of 
the charset.
 
 Contains default shell command for @code{pipe}.
 
address@hidden columns
 @item columns
 @*Type: Numeric.
 @*Default: Detected at startup by querying the terminal device. If this
@@ -3601,6 +3614,7 @@ fails, the value of environment variable @code{COLUMNS} 
is used.
 
 This variable contains the number of columns on terminal screen.
 
address@hidden crt
 @item crt
 @*Type: Boolean or Numeric
 @*Default: True in interactive mode, False otherwise.
@@ -3614,6 +3628,7 @@ if @code{crt} is set without a value, then the height of 
the terminal
 screen is used to compute the threshold. The number of lines on
 screen is controlled by @code{screen} variable.
 
address@hidden debug
 @item debug
 @*Type: String to boolean
 @*Default: Not set
@@ -3628,6 +3643,7 @@ information.  If set to @samp{true} (i.e. @code{set 
debug}), sets
 maximum debugging (@samp{<trace7}) on mailbox and its underlying
 objects.
 
address@hidden decode-fallback
 @item decode-fallback
 @*Type: String.
 @*Default: @samp{none}.
@@ -3650,6 +3666,7 @@ Unprintable characters are represented by their octal 
codes. Printable
 ones are printed @samp{as is}.
 @end table
 
address@hidden debug
 @item debug
 @*Type: Boolean
 @*Default: Unset
@@ -3658,6 +3675,7 @@ ones are printed @samp{as is}.
 This variable is not used.  It exists for compatibility with other
 @command{mailx} implementations and for future use.
 
address@hidden dot
 @item dot
 @*Type: Boolean.
 @*Default: False.
@@ -3666,6 +3684,7 @@ This variable is not used.  It exists for compatibility 
with other
 If @code{True}, causes @command{mail} to interpret a period alone on a line as 
the
 terminator of a message you are sending.
 
address@hidden emptystart
 @item emptystart
 @*Type: Boolean.
 @*Default: False.
@@ -3675,6 +3694,7 @@ If the mailbox is empty, @command{mail} normally prints 
@samp{No mail for user}
 exits immediately. If this option is set, @command{mail} will start no matter 
is
 the mailbox empty or not.
 
address@hidden editheaders
 @item editheaders
 @*Type: Boolean.
 @*Default: False.
@@ -3684,6 +3704,7 @@ When set, @command{mail} will include message headers in 
the text to
 be the @code{~e} and @code{~v} escapes, thus allowing you to customize
 the headers.
 
address@hidden escape
 @item escape
 @*Type: String.
 @*Default: ~
@@ -3692,6 +3713,7 @@ the headers.
 If defined, the first character of this option gives the character to
 denoting escapes.
 
address@hidden flipr
 @item flipr
 @*Type: Boolean
 @*Default: Unset
@@ -3700,6 +3722,7 @@ denoting escapes.
 If set, the variable @code{flipr} swaps the meanings of @code{reply}
 and @code{Reply} commands (@pxref{Replying}).
 
address@hidden folder
 @item folder
 @*Type: String.
 @*Default: Unset.
@@ -3709,6 +3732,7 @@ The name of the directory to use for storing folders of 
messages. If
 unset, @env{$HOME} is assumed.
 
 @anchor{fromfield}
address@hidden fromfield
 @item fromfield
 @*Type: Boolean.
 @*Default: True.
@@ -3719,6 +3743,7 @@ Unsetting this variable tells @command{mail} to obtain it 
from the
 
 @xref{datefield}.
 
address@hidden header
 @item header
 @*Type: Boolean.
 @*Default: True, unless started with @option{--nosum} (@option{-N}) option.
@@ -3727,6 +3752,56 @@ Unsetting this variable tells @command{mail} to obtain 
it from the
 Whether to run @code{headers} command automatically after entering
 interactive mode.
 
address@hidden headline
address@hidden headline
address@hidden: String
address@hidden: @samp{%>%a%4m %18f %16d %3l/%-5o %s}
+
+A format string to use for the header summary.  The @samp{%} character
+introduces a @dfn{format specifier}.  Valid format specifiers are:
+
address@hidden @columnfractions 0.2 0.8
address@hidden Letter @tab Meaning
address@hidden %a @tab Message attributes.
address@hidden %d @tab The date when the message was received.
address@hidden %f @tab The address of the message sender.
address@hidden %l @tab The number of lines of the message.
address@hidden %m @tab Message number.
address@hidden %o @tab The number of octets (bytes) in the message.
address@hidden %s @tab Message subject (if any).
address@hidden %S @tab Message subject (if any) in double quotes.
address@hidden %> @tab A @samp{>} for the current message, otherwise a space.
address@hidden %< @tab A @samp{<} for the current message, otherwise a space.
address@hidden %% @tab A `%' character.
address@hidden multitable
+
+Some additional symbols are allowed between @samp{%} and the specifier
+letter. The @samp{-} character immediately following @samp{%}
+indicates that this field should be left aligned. Similarly, the
address@hidden character indicates right alignment. Default alignment
+depends on the type of the specifier: the specifiers that produce
+numeric values (@samp{%l}, @samp{%m}, and @samp{%o}) are aligned to
+the right, whereas the ones producing string values are aligned to the
+left.
+
+A number following @samp{%} or the alignment flag, indicates the
+field width. Consider, for example, the following specifiers:
+
address@hidden @asis
address@hidden %m
+Print current message number. Take as much screen columns as necessary
+to output it.
+
address@hidden %4m
address@hidden %+4m
+Print current message number. Occupy 4 screen columns, truncate the
+output if it does not fit that width. Align the output to the right. 
+
address@hidden %-4m
+Same as above, but align to the left.
address@hidden table
+
address@hidden hold
 @item hold
 @*Type: Boolean.
 @*Default: False.
@@ -3737,6 +3812,7 @@ user's mailbox (@file{$HOME/mbox}). Otherwise, they will 
be held in
 system mailbox also. This option is in effect only when operating
 upon user's system mailbox.
 
address@hidden ignore 
 @item ignore
 @*Type: Boolean.
 @*Default: False.
@@ -3746,6 +3822,7 @@ When set to @code{True}, @command{mail} will ignore 
keyboard interrupts
 when composing messages. Otherwise an interrupt will be taken as a
 signal to abort composing.
 
address@hidden ignoreeof
 @item ignoreeof
 @*Type: Boolean.
 @*Default: False.
@@ -3754,6 +3831,7 @@ signal to abort composing.
 Controls whether typing EOF character terminates the letter being
 composed.
 
address@hidden indentprefix
 @item indentprefix
 @*Type: String.
 @*Default: "\t" (a tab character).
@@ -3761,6 +3839,7 @@ composed.
 
 String used by the @code{~m} tilde escape for indenting quoted messages.
 
address@hidden inplacealiases
 @item inplacealiases
 @*Type: Boolean
 @*Default: False
@@ -3770,6 +3849,7 @@ before entering send mode (@pxref{Composing Mail}). By 
default, the
 address header fields are left intact while composing, the alias
 expansion takes place immediately before sending message.
 
address@hidden keep
 @item keep
 @*Type: Boolean, Read-Only
 @*Default: True
@@ -3779,6 +3859,7 @@ Truncate the user's system mailbox when it is empty, 
instead of
 removing it. This is the default and cannot be changed. This variable
 exists only for compatibility with other @command{mailx} implementations.
 
address@hidden keepsave
 @item keepsave
 @*Type: Boolean.
 @*Default: False.
@@ -3788,6 +3869,7 @@ Controls whether saved messages should be kept in system 
mailbox too.
 This variable is in effect only when operating upon a user's system
 mailbox.
 
address@hidden mailx
 @item mailx
 @*Type: Boolean.
 @*Default: False.
@@ -3807,6 +3889,7 @@ will exit with zero status. By default it exits with zero 
status only
 if the message was sent successfully.
 @end itemize
 
address@hidden metamail
 @item metamail
 @*Type: Boolean or String.
 @*Default: True.
@@ -3830,6 +3913,7 @@ set metamail
 set metamail="metamail -m mail -p"
 @end smallexample
 
address@hidden mimenoask
 @item mimenoask
 @*Type: String
 @*Default: Empty
@@ -3850,6 +3934,7 @@ will disable prompting before displaying any textual 
files, no
 matter what their subtype is, and before displaying files with
 type @samp{image/jpeg}.
 
address@hidden metoo
 @item metoo
 @*Type: Boolean.
 @*Default: False.
@@ -3859,6 +3944,7 @@ Usually, when an alias is expanded that contains the 
sender, the sender
 is removed from the expansion. Setting this option causes the sender to
 be included in the group.
 
address@hidden mode
 @item mode
 @*Type: String, Read-Only
 @*Default: The name of current operation mode.
@@ -3888,6 +3974,7 @@ The program operates in send mode. This means it was 
given one or more
 recipient addresses in the command line.
 @end table
 
address@hidden nullbody
 @item nullbody
 @* Type: Boolean
 @* Default: True
@@ -3912,6 +3999,7 @@ outputs something on its standard output or error:
 @end group
 @end smallexample
 
address@hidden showenvelope
 @item showenvelope
 @*Type: Boolean
 @*Default: Unset
@@ -3919,6 +4007,7 @@ outputs something on its standard output or error:
 If this variable is set, the @code{print} command will include the
 @acronym{STMP} envelope in its output.
 
address@hidden nullbodymsg
 @item nullbodymsg
 @*Type: String
 @*Default: Null message body; hope that's ok 
@@ -3930,6 +4019,7 @@ this text, in accordance with the current locale, is 
displayed.
 
 Unsetting this variable disables the warning.
 
address@hidden onehop
 @item onehop
 @*Type: Boolean
 @*Default: Unset
@@ -3938,6 +4028,7 @@ Unsetting this variable disables the warning.
 This variable is not used.  It exists for compatibility with other
 @command{mailx} implementations and for future use.
 
address@hidden outfolder
 @item outfolder
 @*Type: String.
 @*Default: Unset.
@@ -3947,6 +4038,7 @@ Contains the directory in which files created by 
@code{save},
 @code{write}, etc. commands will be stored. When unset, current
 directory is assumed.
 
address@hidden page
 @item page
 @*Type: Boolean.
 @*Default: False.
@@ -3955,6 +4047,7 @@ directory is assumed.
 If set to @code{True}, the @code{pipe} command will emit a linefeed
 character after printing each message.
 
address@hidden prompt
 @item prompt
 @*Type: String.
 @*Default: "? "
@@ -3962,6 +4055,7 @@ character after printing each message.
 
 Contains the command prompt sequence.
 
address@hidden quiet
 @item quiet
 @*Type: Boolean
 @*Default: Unset
@@ -3970,6 +4064,7 @@ Contains the command prompt sequence.
 This variable is not used.  It exists for compatibility with other
 @command{mailx} implementations and for future use.
 
address@hidden quit
 @item quit
 @*Type: Boolean.
 @*Default: False, unless started with @option{--quit} (@option{-q}) option.
@@ -3977,6 +4072,7 @@ This variable is not used.  It exists for compatibility 
with other
 
 When set, causes keyboard interrupts to terminate the program.
 
address@hidden rc
 @item rc
 @*Type: Boolean.
 @*Default: True, unless started with @option{--norc} (@option{-N}) option.
@@ -3985,6 +4081,7 @@ When set, causes keyboard interrupts to terminate the 
program.
 When this variable is set, @command{mail} will read the system-wide
 configuration file upon startup. See @ref{Mail Configuration Files}.
 
address@hidden readonly
 @item readonly
 @*Type: Boolean
 @*Default: False
@@ -3995,6 +4092,7 @@ When set, mailboxes are opened in readonly mode.  In this 
mode, any
 disabled.  These commands include, but are not limited to: 
 @code{delete}, @code{save} and @code{mbox}.
 
address@hidden record
 @item record
 @*Type: String.
 @*Default: Unset.
@@ -4002,12 +4100,14 @@ disabled.  These commands include, but are not limited 
to:
 
 When set, any outgoing message will be saved to the named file.
 
address@hidden recursivealiases
 @item recursivealiases
 @*Type: Boolean
 @*Default: True
 
 When set, @command{mail} will expand aliases recursively.
 
address@hidden regex
 @item regex
 @*Type: Boolean.
 @*Default: True.
@@ -4016,6 +4116,7 @@ When set, @command{mail} will expand aliases recursively.
 Setting this to @code{True} enables use of regular expressions in
 @samp{/.../} message specifications.
 
address@hidden replyprefix
 @item replyprefix
 @*Type: String
 @*Default: @samp{Re: }
@@ -4024,6 +4125,7 @@ Setting this to @code{True} enables use of regular 
expressions in
 Sets the prefix that will be used when constructing the subject line
 of a reply message.
 
address@hidden replyregex
 @item replyregex
 @*Type: String
 @*Default: @samp{^re: *}
@@ -4045,6 +4147,7 @@ set 
replyregex="^(re|odp|aw|ang)(\\[[0-9]+\\])?:[[:blank:]]"
 @noindent
 (Notice the quoting of backslash characters).
 
address@hidden save
 @item save
 @*Type: Boolean.
 @*Default: True.
@@ -4053,6 +4156,7 @@ set 
replyregex="^(re|odp|aw|ang)(\\[[0-9]+\\])?:[[:blank:]]"
 When set, the aborted messages will be stored in the user's
 @file{dead.file}. See also @code{appenddeadletter}.
 
address@hidden screen
 @item screen
 @*Type: Numeric.
 @*Default: Detected at startup by querying the terminal device. If this
@@ -4061,6 +4165,7 @@ fails, the value of environment variable @code{LINES} is 
used.
 
 This variable contains the number of lines on terminal screen.
 
address@hidden sendmail
 @item sendmail
 @*Type: String.
 @*Default: sendmail:/usr/lib/sendmail
@@ -4068,6 +4173,7 @@ This variable contains the number of lines on terminal 
screen.
 
 Contains URL of the mail transport agent.
 
address@hidden sendwait
 @item sendwait
 @*Type: Boolean
 @*Default: Unset
@@ -4076,6 +4182,7 @@ Contains URL of the mail transport agent.
 This variable is not used.  It exists for compatibility with other
 @command{mailx} implementations and for future use.
 
address@hidden showto
 @item showto
 @*Type: Boolean
 @*Default: False
@@ -4084,6 +4191,7 @@ This variable is not used.  It exists for compatibility 
with other
 If the message was sent by the user, print its recipient address in
 the header summary.
 
address@hidden Sign
 @item Sign
 @*Type: String.
 @*Default: Unset.
@@ -4093,6 +4201,7 @@ Contains the filename holding users signature. The 
contents of this
 file is appended to the end of a message being composed by @code{~A}
 escape.
 
address@hidden sign
 @item sign
 @*Type: String.
 @*Default: Unset.
@@ -4102,6 +4211,7 @@ Contains the user's signature. The contents of this 
variable is appended
 to the end of a message being composed by @code{~a} escape. Use
 @code{Sign} variable, if your signature occupies more than one line.
 
address@hidden showto
 @item showto
 @*Type: Boolean
 @*Default: unset
@@ -4111,6 +4221,7 @@ If this variable is set, @command{mail} will show 
@code{To:} addresses
 instead of @code{From:} for all messages that come from the user that
 invoked the program.
 
address@hidden subject
 @item subject
 @*Type: String.
 @*Default: Unset.
@@ -4119,6 +4230,7 @@ invoked the program.
 Contains default subject line. This will be used when @code{asksub} is
 off.
 
address@hidden toplines
 @item toplines
 @*Type: Numeric.
 @*Default: 5
@@ -4126,6 +4238,7 @@ off.
 
 Number of lines to be displayed by @code{top} and @code{Top} commands.
 
address@hidden variable-strict
 @item variable-strict
 @itemx varstrict
 @*Type: Boolean.
@@ -4138,6 +4251,7 @@ variables. Also, if the user is trying to set an unknown 
variable,
 
 @xref{Setting and Unsetting the Variables}.
 
address@hidden variable-pretty-print
 @item variable-pretty-print
 @itemx varpp
 @*Type: Boolean.
@@ -4146,6 +4260,7 @@ variables. Also, if the user is trying to set an unknown 
variable,
 If this variable is set, the listing ouput by @command{set} contains short
 descriptions before each variable. @xref{Setting and Unsetting the Variables}. 
 
address@hidden verbose
 @item verbose
 @*Type: Boolean.
 @*Default: False.
@@ -4153,6 +4268,7 @@ descriptions before each variable. @xref{Setting and 
Unsetting the Variables}.
 
 When set, the actual delivery of messages is displayed on the user's terminal.
 
address@hidden xmailer
 @item xmailer
 @*Type: Boolean.
 @*Default: Set.
diff --git a/mail/from.c b/mail/from.c
index add2643..31e2a92 100644
--- a/mail/from.c
+++ b/mail/from.c
@@ -18,27 +18,220 @@
    MA 02110-1301 USA */
 
 #include "mail.h"
+#include <mu_umaxtostr.h>
 
-/*
- * f[rom] [msglist]
- */
+#define ALIGN_UNDEF -1
+#define ALIGN_RIGHT 0
+#define ALIGN_LEFT  1
 
-int
-mail_from0 (msgset_t *mspec, mu_message_t msg, void *data)
+struct header_call_args
+{
+  msgset_t *mspec;
+  mu_message_t msg;
+  size_t cols_rest;
+  char *buf;
+  size_t size;
+};
+  
+struct header_segm
+{
+  struct header_segm *next;
+  int align;
+  size_t width;
+  void *data;
+  char *(*get) (struct header_call_args *args, void *data);
+};
+
+void
+header_ensure_space (struct header_call_args *args, size_t size)
+{
+  if (size > args->size)
+    {
+      args->buf = xrealloc (args->buf, size);
+      args->size = size;
+    }
+}
+
+static char *
+header_buf_string_len (struct header_call_args *args, const char *str,
+                      size_t len)
+{
+  header_ensure_space (args, len + 1);
+  memcpy (args->buf, str, len);
+  args->buf[len] = 0;
+  return args->buf;
+}
+
+static char *
+header_buf_string (struct header_call_args *args, const char *str)
+{
+  if (!str)
+    return header_buf_string_len (args, "", 0);
+  return header_buf_string_len (args, str, strlen (str));
+}
+
+static void
+format_pad (size_t n)
+{
+  for (; n; n--)
+    fputc (' ', ofile);
+}
+
+static void
+format_headline (struct header_segm *seg, msgset_t *mspec, mu_message_t msg)
+{
+  int screen_cols = util_getcols () - 2;
+  int out_cols = 0;
+  struct header_call_args args;
+
+  args.mspec = mspec;
+  args.msg = msg;
+  args.buf = NULL;
+  args.size = 0;
+  
+  for (; seg; seg = seg->next)
+    {
+      size_t width, len;
+      size_t cols_rest = screen_cols - out_cols;
+      char *p;
+
+      args.cols_rest = cols_rest;
+      p = seg->get (&args, seg->data);
+
+      if (!p)
+       p = "";
+      len = strlen (p);
+      
+      if (seg->width)
+       width = seg->width;
+      else
+       width = len;
+      if (width > cols_rest)
+       width = cols_rest;
+
+      if (len > width)
+       len = width;
+      
+      if (seg->align == ALIGN_RIGHT)
+       {
+         format_pad (width - len);
+         fprintf (ofile, "%*.*s", len, len, p);
+       }
+      else
+       {
+         fprintf (ofile, "%*.*s", len, len, p);
+         format_pad (width - len);
+       }
+      out_cols += width;
+    }
+
+  fprintf (ofile, "\n");
+  free (args.buf);
+}    
+
+static void
+free_headline (struct header_segm *seg)
+{
+  while (seg)
+    {
+      struct header_segm *next = seg->next;
+      if (seg->data)
+       free (seg->data);
+      free (seg);
+      seg = next;
+    }
+}
+
+
+static char *
+hdr_text (struct header_call_args *args, void *data)
+{
+  return data;
+}
+
+static char *
+hdr_cur (struct header_call_args *args, void *data)
+{
+  if (is_current_message (args->mspec->msg_part[0]))
+    return (char*) data;
+  return " ";
+}
+
+/* %a */
+static char *
+hdr_attr (struct header_call_args *args, void *data)
 {
-  mu_header_t hdr = NULL;
-  mu_envelope_t env;
   mu_attribute_t attr;
-  char *from = NULL, *subj = NULL, *fromp, *subjp;
-  int froml, subjl;
-  char date[80], st[10];
-  int cols = util_getcols () - 6;
-  int cflag;
-  size_t m_size = 0, m_lines = 0;
+  char cflag;
+  
+  mu_message_get_attribute (args->msg, &attr);
+  
+  if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_MBOXED))
+    cflag = 'M';
+  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED))
+    cflag = 'P';
+  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED))
+    cflag = '*';
+  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED))
+    cflag = 'T';
+  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SHOWN))
+    cflag = 'R';
+  else if (mu_attribute_is_recent (attr))
+    cflag = 'N';
+  else if (!mu_attribute_is_read (attr))
+    cflag = 'U';
+  else
+    cflag = ' ';
+  return header_buf_string_len (args, &cflag, 1);
+}
+    
+/* %d */
+static char *
+hdr_date (struct header_call_args *args, void *data)
+{
+  char date[80];
+  mu_header_t hdr;
 
+  mu_message_get_header (args->msg, &hdr);
+  
+  date[0] = 0;
+  if (mailvar_get (NULL, "datefield", mailvar_type_boolean, 0) == 0
+      && mu_header_get_value (hdr, MU_HEADER_DATE,
+                             date, sizeof (date), NULL) == 0)
+    {
+      time_t t;
+      if (mu_parse_date (date, &t, NULL) == 0)
+       strftime (date, sizeof(date), "%a %b %e %H:%M", localtime (&t));
+      else
+       date[0] = 0;
+    }
+
+  if (date[0] == 0)
+    {
+      const char *p;
+      struct tm tm;
+      mu_timezone tz;
+      mu_envelope_t env;
+      
+      mu_message_get_envelope (args->msg, &env);
+      if (mu_envelope_sget_date (env, &p) == 0
+          && mu_parse_ctime_date_time (&p, &tm, &tz) == 0)
+       strftime (date, sizeof(date), "%a %b %e %H:%M", &tm);
+    }
+  return header_buf_string (args, date);
+}
+
+/* %f */
+static char *
+hdr_from (struct header_call_args *args, void *data)
+{
+  char *from = NULL;
+  
   if (mailvar_get (NULL, "fromfield", mailvar_type_boolean, 0) == 0)
     {  
-      mu_message_get_header (msg, &hdr);
+      mu_header_t hdr;
+      
+      mu_message_get_header (args->msg, &hdr);
       if (mu_header_aget_value_unfold (hdr, MU_HEADER_FROM, &from) == 0)
        {
          mu_address_t address = NULL;
@@ -49,7 +242,8 @@ mail_from0 (msgset_t *mspec, mu_message_t msg, void *data)
          
              if (mu_address_sget_email (address, 1, &email) == 0)
                {
-                 if (mailvar_get (NULL, "showto", mailvar_type_boolean, 0) == 0
+                 if (mailvar_get (NULL, "showto",
+                                  mailvar_type_boolean, 0) == 0
                      && mail_is_my_name (email))
                    {
                      char *tmp;
@@ -86,87 +280,263 @@ mail_from0 (msgset_t *mspec, mu_message_t msg, void *data)
       mu_envelope_t env = NULL;
       const char *sender = "";
       
-      if (mu_message_get_envelope (msg, &env) == 0)
+      if (mu_message_get_envelope (args->msg, &env) == 0)
        mu_envelope_sget_sender (env, &sender);
       from = strdup (sender);
     }
 
+  header_buf_string (args, from);
+  free (from);
+  return args->buf;
+}
+
+/* %l */
+static char *
+hdr_lines (struct header_call_args *args, void *data)
+{
+  size_t m_lines;
+  char buf[UINTMAX_STRSIZE_BOUND];
+  mu_message_lines (args->msg, &m_lines);
+  
+  return header_buf_string (args, umaxtostr (m_lines, buf));
+}
+
+/* %m */
+static char *
+hdr_number (struct header_call_args *args, void *data)
+{
+  char buf[UINTMAX_STRSIZE_BOUND];
+  return header_buf_string (args, umaxtostr (args->mspec->msg_part[0], buf));
+}
+
+/* %o */
+static char *
+hdr_size (struct header_call_args *args, void *data)
+{
+  size_t m_size;
+  char buf[UINTMAX_STRSIZE_BOUND];
+  mu_message_size (args->msg, &m_size);
+  
+  return header_buf_string (args, umaxtostr (m_size, buf));
+}
+
+/* %s */
+static char *
+hdr_subject (struct header_call_args *args, void *data)
+{
+  mu_header_t hdr;
+  char *subj = NULL;
+  
+  mu_message_get_header (args->msg, &hdr);
   mu_header_aget_value_unfold (hdr, MU_HEADER_SUBJECT, &subj);
   util_rfc2047_decode (&subj);
   
-  mu_message_get_attribute (msg, &attr);
+  header_buf_string (args, subj);
+  free (subj);
+  return args->buf;
+}
+
+/* %S */
+static char *
+hdr_q_subject (struct header_call_args *args, void *data)
+{
+  mu_header_t hdr;
+  char *subj = NULL;
+  size_t len;
+
+  if (args->cols_rest <= 2)
+    return "\"\"";
   
-  if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_MBOXED))
-    cflag = 'M';
-  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED))
-    cflag = 'P';
-  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED))
-    cflag = '*';
-  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED))
-    cflag = 'T';
-  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SHOWN))
-    cflag = 'R';
-  else if (mu_attribute_is_recent (attr))
-    cflag = 'N';
-  else if (!mu_attribute_is_read (attr))
-    cflag = 'U';
-  else
-    cflag = ' ';
+  mu_message_get_header (args->msg, &hdr);
+  mu_header_aget_value_unfold (hdr, MU_HEADER_SUBJECT, &subj);
+  if (!subj)
+    return "";
+  util_rfc2047_decode (&subj);
 
-  date[0] = 0;
-  if (mailvar_get (NULL, "datefield", mailvar_type_boolean, 0) == 0
-      && mu_header_get_value (hdr, MU_HEADER_DATE, date, sizeof (date), NULL) 
== 0)
+  len = strlen (subj);
+  if (len + 2 > args->cols_rest)
+    len = args->cols_rest - 2;
+  header_ensure_space (args, len + 3);
+  args->buf[0] = '"';
+  memcpy (args->buf + 1, subj, len);
+  args->buf[len+1] = '"';
+  args->buf[len+2] = 0;
+  free (subj);
+  return args->buf;
+}
+
+
+static struct header_segm *
+new_header_segment (int align, size_t width,
+                   void *data,
+                   char *(*get) (struct header_call_args *, void *))
+{
+  struct header_segm *seg = xmalloc (sizeof (*seg));
+  seg->next = NULL;
+  seg->align = align;
+  seg->width = width;
+  seg->data = data;
+  seg->get = get;
+  return seg;
+}
+
+struct header_segm *
+compile_headline (const char *str)
+{
+  struct header_segm *head = NULL, *tail = NULL;
+  char *text;
+  int align;
+  size_t width;
+  
+#define ALIGN_STRING (align == ALIGN_UNDEF ? ALIGN_LEFT : ALIGN_RIGHT)
+#define ALIGN_NUMBER (align == ALIGN_UNDEF ? ALIGN_RIGHT : ALIGN_LEFT)
+#define ATTACH(p)                              \
+  do                                           \
+    {                                          \
+      if (!head)                               \
+       head = p;                               \
+      else                                     \
+       tail->next = p;                         \
+      tail = p;                                        \
+    }                                          \
+  while (0)
+      
+  while (*str)
     {
-      time_t t;
-      if (mu_parse_date (date, &t, NULL) == 0)
+      struct header_segm *seg;
+      size_t len;
+      char *p = strchr (str, '%');
+      if (!p)
+       len = strlen (str);
+      else
+       len = p - str;
+      if (len)
        {
-         strftime (date, sizeof(date), "%a %b %e %H:%M", localtime (&t));
+         text = xmalloc (len + 1);
+         memcpy (text, str, len);
+         text[len] = 0;
+         seg = new_header_segment (ALIGN_LEFT, 0, text, hdr_text);
+         ATTACH (seg);
+       }
+      if (!p)
+       break;
+
+      str = ++p;
+
+      if (*str == '-')
+       {
+         str++;
+         align = ALIGN_LEFT;
+       }
+      else if (*str == '+')
+       {
+         str++;
+         align = ALIGN_RIGHT;
        }
       else
-       date[0] = 0;
-    }
+       align = ALIGN_UNDEF;
+      
+      if (mu_isdigit (*str))
+       width = strtoul (str, (char**)&str, 10);
+      else
+       width = 0;
 
-  if (date[0] == 0)
-    {
-      const char *p;
-      struct tm tm;
-      mu_timezone tz;
+      switch (*str++)
+       {
+       case '%':
+         seg = new_header_segment (ALIGN_LEFT, 0, xstrdup ("%"), hdr_text);
+         break;
+         
+       case 'a': /* Message attributes. */
+         seg = new_header_segment (ALIGN_STRING, width, NULL, hdr_attr);
+         break;
 
-      mu_message_get_envelope (msg, &env);
-      if (mu_envelope_sget_date (env, &p) == 0
-          && mu_parse_ctime_date_time (&p, &tm, &tz) == 0)
-       strftime (date, sizeof(date), "%a %b %e %H:%M", &tm);
+         /* FIXME: %c    The score of the message. */
+         
+       case 'd': /* Message date */
+         seg = new_header_segment (ALIGN_STRING, width, NULL, hdr_date);
+         break;
+         
+         /* FIXME: %e    The indenting level in threaded mode. */
+         
+       case 'f': /* Message sender */
+         seg = new_header_segment (ALIGN_STRING, width, NULL, hdr_from);
+         break;
+
+         /* FIXME: %i    The message thread structure. */
+         
+       case 'l': /* The number of lines of the message */
+         seg = new_header_segment (ALIGN_NUMBER, width, NULL, hdr_lines);
+         break;
+         
+       case 'm': /* Message number */
+         seg = new_header_segment (ALIGN_NUMBER, width, NULL, hdr_number);
+         break;
+         
+       case 'o': /* The number of octets (bytes) in the message */
+         seg = new_header_segment (ALIGN_NUMBER, width, NULL, hdr_size);
+         break;
+         
+       case 's': /* Message subject (if any) */
+         seg = new_header_segment (ALIGN_STRING, width, NULL, hdr_subject);
+         break;
+
+       case 'S': /* Message subject (if any) in double quotes */
+         seg = new_header_segment (ALIGN_STRING, width, NULL, hdr_q_subject);
+         break;
+         
+         /* FIXME: %t    The position in threaded/sorted order. */
+         
+       case '>': /* A `>' for the current message, otherwise ` ' */
+         seg = new_header_segment (ALIGN_STRING, width, xstrdup (">"), 
hdr_cur);
+         break;
+         
+       case '<': /* A `<' for the current message, otherwise ` ' */
+         seg = new_header_segment (ALIGN_STRING, width, xstrdup ("<"), 
hdr_cur);
+         break;
+
+       default:
+         mu_error (_("unknown escape: %%%c"), str[-1]);
+         len = str - p;
+         text = xmalloc (len);
+         memcpy (text, p, len-1);
+         text[len-1] = 0;
+         seg = new_header_segment (ALIGN_STRING, width, text, hdr_text);
+       }
+      ATTACH (seg);
     }
-  
-  mu_message_size (msg, &m_size);
-  mu_message_lines (msg, &m_lines);
-  
-  snprintf (st, sizeof (st), "%3d/%-5d", m_lines, m_size);
-  
-  /* The "From" field will take a third of the screen.
-     Subject will take the rest.
-     FIXME: This is not quite correct that we use fixed sizes
-     18, 16 for the other fields.
-  */
-  froml = cols / 3;
-  subjl = cols - froml - strlen (st) - 16;
-  
-  fromp = from ? from : "";
-  subjp = subj ? subj : fromp;
-  fprintf (ofile, "%c%c%4d %-18.18s %-16.16s %s %.*s\n",
-          is_current_message (mspec->msg_part[0]) ? '>' : ' ', cflag,
-          mspec->msg_part[0],
-          fromp, date, st, (subjl < 0) ? 0 : subjl, subjp);
-  
-  free (from);
-  free (subj);
+  return head;
+#undef ALIGN_STRING
+#undef ALIGN_NUMBER
+#undef ATTACH
+}
+
+/* FIXME: Should it be part of struct mailvar_variable for "headline"? */
+static struct header_segm *mail_header_line;
+
+void
+mail_compile_headline (struct mailvar_variable *var)
+{
+  free_headline (mail_header_line);
+  mail_header_line = compile_headline (var->value.string);
+}
+
+
+/*
+ * f[rom] [msglist]
+ */
 
+int
+mail_from0 (msgset_t *mspec, mu_message_t msg, void *data)
+{
+  format_headline (mail_header_line, mspec, msg);
   return 0;
 }
 
 int
 mail_from (int argc, char **argv)
 {
-  return util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT, mail_from0, 
NULL);
+  return util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT,
+                          mail_from0, NULL);
 }
 
diff --git a/mail/mail.c b/mail/mail.c
index d633b03..805b0e3 100644
--- a/mail/mail.c
+++ b/mail/mail.c
@@ -287,6 +287,7 @@ static char *default_setup[] = {
   "set recursivealiases",
   "set noinplacealiases",
   "set fromfield",
+  "set headline=\"%>%a%4m %18f %16d %3l/%-5o %s\"",
   
   /* Start in mail reading mode */
   "setq mode=read",
@@ -364,7 +365,7 @@ main (int argc, char **argv)
 
   /* set defaults for execution */
   for (i = 0; i < sizeof (default_setup)/sizeof (default_setup[0]); i++)
-    util_do_command (default_setup[i]);
+    util_do_command ("%s", default_setup[i]);
   util_do_command ("set screen=%d", util_getlines ());
   util_do_command ("set columns=%d", util_getcols ());
   
diff --git a/mail/mail.h b/mail/mail.h
index a600d46..7eeb600 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -45,11 +45,7 @@
 #endif
 #include <sys/wait.h>
 #include <sys/types.h>
-#ifdef HAVE_STDARG_H
-# include <stdarg.h>
-#else
-# include <varargs.h>
-#endif
+#include <stdarg.h>
 #include <signal.h>
 
 #include <confpaths.h>
@@ -200,6 +196,8 @@ extern int mail_folders (int argc, char **argv);
 extern int mail_followup (int argc, char **argv);
 extern int mail_from (int argc, char **argv);
 extern int mail_from0 (msgset_t *mspec, mu_message_t msg, void *data);
+extern void mail_compile_headline (struct mailvar_variable *var);
+
 extern int mail_headers (int argc, char **argv);
 extern int mail_hold (int argc, char **argv);
 extern int mail_help (int argc, char **argv);
diff --git a/mail/mailvar.c b/mail/mailvar.c
index d101ec8..e5cc5ce 100644
--- a/mail/mailvar.c
+++ b/mail/mailvar.c
@@ -130,6 +130,10 @@ struct mailvar_symbol mailvar_tab[] =
     { { "header", },
       MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("run the `headers' command after entering interactive mode") },
+    { { "headline", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
+      N_("format string to use for the header summary"),
+      mail_compile_headline },
     { { "hold", },
       MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("hold the read or saved messages in the system mailbox") },
diff --git a/mail/util.c b/mail/util.c
index 95ec9b6..2f485ca 100644
--- a/mail/util.c
+++ b/mail/util.c
@@ -468,7 +468,7 @@ util_get_homedir ()
 char *
 util_fullpath (const char *inpath)
 {
-  return mu_tilde_expansion(inpath, "/", NULL);
+  return mu_tilde_expansion (inpath, "/", NULL);
 }
 
 char *
@@ -661,7 +661,7 @@ util_slist_to_string (mu_list_t list, const char *delim)
 }
 
 void
-util_strcat(char **dest, const char *str)
+util_strcat (char **dest, const char *str)
 {
   if (!*dest)
     *dest = strdup (str);
@@ -754,26 +754,13 @@ util_save_outgoing (mu_message_t msg, char *savefile)
     }
 }
 
-#ifdef HAVE_STDARG_H
 void
 util_error (const char *format, ...)
-#else
-void
-util_error (va_alist)
-     va_dcl
-#endif
 {
   va_list ap;
 
-#ifdef HAVE_STDARG_H
-  va_start(ap, format);
-#else
-  char *format;
-
-  va_start (ap);
-  format = va_arg (ap, char *);
-#endif
-
+  va_start (ap, format);
+  
   vfprintf (stderr, format, ap);
   fprintf (stderr, "\n");
 


hooks/post-receive
-- 
GNU Mailutils




reply via email to

[Prev in Thread] Current Thread [Next in Thread]