[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] GNU Mailutils branch, master, updated. mu-1-2-90-separate-argp-cfg-323-g9b0dee5,
Sergey Poznyakoff <=