bin_PROGRAMS = mutt $(PGPAUX_TARGET)
mutt_SOURCES = account.c addrbook.c address.h alias.c alias.h attach.c \
- bcache.c body.h browser.c buffer.c buffy.c charset.c color.c \
+ bcache.c body.h browser.c buffy.c charset.c color.c \
commands.c complete.c compose.c compress.c content.h context.h copy.c \
curs_lib.c curs_main.c edit.c editmsg.c enter.c enter_state.h \
envelope.h filter.c flags.c format_flags.h from.c getdomain.c group.c \
mutt_lua.c mutt_sasl.c mutt_notmuch.c mutt_ssl.c mutt_ssl_gnutls.c \
remailer.c remailer.h resize.c url.h utf8.c wcwidth.c
-EXTRA_DIST = account.h attach.h bcache.h browser.h buffer.h buffy.h \
+EXTRA_DIST = account.h attach.h bcache.h browser.h buffy.h \
ChangeLog.md charset.h CODE_OF_CONDUCT.md compress.h copy.h \
COPYRIGHT filter.h functions.h gen_defs globals.h \
group.h hash.h history.h init.h keymap.h lib.h LICENSE.md mailbox.h \
+++ /dev/null
-/**
- * @file
- * General purpose object for storing and parsing strings
- *
- * @authors
- * @copyright
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include "buffer.h"
-#include "filter.h"
-#include "lib.h"
-#include "lib/lib.h"
-#include "myvar.h"
-
-/**
- * mutt_buffer_new - creates and initializes a Buffer
- */
-struct Buffer *mutt_buffer_new(void)
-{
- struct Buffer *b = NULL;
-
- b = safe_malloc(sizeof(struct Buffer));
-
- mutt_buffer_init(b);
-
- return b;
-}
-
-/**
- * mutt_buffer_init - initialize a new Buffer
- */
-struct Buffer *mutt_buffer_init(struct Buffer *b)
-{
- memset(b, 0, sizeof(struct Buffer));
- return b;
-}
-
-/**
- * mutt_buffer_from - Create Buffer from an existing Buffer
- *
- * Creates and initializes a Buffer*. If passed an existing Buffer*,
- * just initializes. Frees anything already in the buffer. Copies in
- * the seed string.
- *
- * Disregards the 'destroy' flag, which seems reserved for caller.
- * This is bad, but there's no apparent protocol for it.
- */
-struct Buffer *mutt_buffer_from(char *seed)
-{
- struct Buffer *b = NULL;
-
- if (!seed)
- return NULL;
-
- b = mutt_buffer_new();
- b->data = safe_strdup(seed);
- b->dsize = mutt_strlen(seed);
- b->dptr = (char *) b->data + b->dsize;
- return b;
-}
-
-void mutt_buffer_free(struct Buffer **p)
-{
- if (!p || !*p)
- return;
-
- FREE(&(*p)->data);
- /* dptr is just an offset to data and shouldn't be freed */
- FREE(p);
-}
-
-int mutt_buffer_printf(struct Buffer *buf, const char *fmt, ...)
-{
- va_list ap, ap_retry;
- int len, blen, doff;
-
- va_start(ap, fmt);
- va_copy(ap_retry, ap);
-
- if (!buf->dptr)
- buf->dptr = buf->data;
-
- doff = buf->dptr - buf->data;
- blen = buf->dsize - doff;
- /* solaris 9 vsnprintf barfs when blen is 0 */
- if (!blen)
- {
- blen = 128;
- buf->dsize += blen;
- safe_realloc(&buf->data, buf->dsize);
- buf->dptr = buf->data + doff;
- }
- if ((len = vsnprintf(buf->dptr, blen, fmt, ap)) >= blen)
- {
- blen = ++len - blen;
- if (blen < 128)
- blen = 128;
- buf->dsize += blen;
- safe_realloc(&buf->data, buf->dsize);
- buf->dptr = buf->data + doff;
- len = vsnprintf(buf->dptr, len, fmt, ap_retry);
- }
- if (len > 0)
- buf->dptr += len;
-
- va_end(ap);
- va_end(ap_retry);
-
- return len;
-}
-
-/**
- * mutt_buffer_add - Add a string to a Buffer, expanding it if necessary
- *
- * dynamically grows a Buffer to accommodate s, in increments of 128 bytes.
- * Always one byte bigger than necessary for the null terminator, and the
- * buffer is always null-terminated
- */
-static void mutt_buffer_add(struct Buffer *buf, const char *s, size_t len)
-{
- if (!buf || !s)
- return;
-
- if ((buf->dptr + len + 1) > (buf->data + buf->dsize))
- {
- size_t offset = buf->dptr - buf->data;
- buf->dsize += (len < 128) ? 128 : len + 1;
- safe_realloc(&buf->data, buf->dsize);
- buf->dptr = buf->data + offset;
- }
- if (!buf->dptr)
- return;
- memcpy(buf->dptr, s, len);
- buf->dptr += len;
- *(buf->dptr) = '\0';
-}
-
-void mutt_buffer_addstr(struct Buffer *buf, const char *s)
-{
- mutt_buffer_add(buf, s, mutt_strlen(s));
-}
-
-void mutt_buffer_addch(struct Buffer *buf, char c)
-{
- mutt_buffer_add(buf, &c, 1);
-}
-
-int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags)
-{
- if (!dest || !tok)
- return -1;
-
- char ch;
- char qc = 0; /* quote char */
- char *pc = NULL;
-
- /* reset the destination pointer to the beginning of the buffer */
- dest->dptr = dest->data;
-
- SKIPWS(tok->dptr);
- while ((ch = *tok->dptr))
- {
- if (!qc)
- {
- if ((ISSPACE(ch) && !(flags & MUTT_TOKEN_SPACE)) ||
- (ch == '#' && !(flags & MUTT_TOKEN_COMMENT)) ||
- (ch == '=' && (flags & MUTT_TOKEN_EQUAL)) ||
- (ch == ';' && !(flags & MUTT_TOKEN_SEMICOLON)) ||
- ((flags & MUTT_TOKEN_PATTERN) && strchr("~%=!|", ch)))
- break;
- }
-
- tok->dptr++;
-
- if (ch == qc)
- qc = 0; /* end of quote */
- else if (!qc && (ch == '\'' || ch == '"') && !(flags & MUTT_TOKEN_QUOTE))
- qc = ch;
- else if (ch == '\\' && qc != '\'')
- {
- if (!*tok->dptr)
- return -1; /* premature end of token */
- switch (ch = *tok->dptr++)
- {
- case 'c':
- case 'C':
- if (!*tok->dptr)
- return -1; /* premature end of token */
- mutt_buffer_addch(dest, (toupper((unsigned char) *tok->dptr) - '@') & 0x7f);
- tok->dptr++;
- break;
- case 'r':
- mutt_buffer_addch(dest, '\r');
- break;
- case 'n':
- mutt_buffer_addch(dest, '\n');
- break;
- case 't':
- mutt_buffer_addch(dest, '\t');
- break;
- case 'f':
- mutt_buffer_addch(dest, '\f');
- break;
- case 'e':
- mutt_buffer_addch(dest, '\033');
- break;
- default:
- if (isdigit((unsigned char) ch) && isdigit((unsigned char) *tok->dptr) &&
- isdigit((unsigned char) *(tok->dptr + 1)))
- {
- mutt_buffer_addch(dest, (ch << 6) + (*tok->dptr << 3) + *(tok->dptr + 1) - 3504);
- tok->dptr += 2;
- }
- else
- mutt_buffer_addch(dest, ch);
- }
- }
- else if (ch == '^' && (flags & MUTT_TOKEN_CONDENSE))
- {
- if (!*tok->dptr)
- return -1; /* premature end of token */
- ch = *tok->dptr++;
- if (ch == '^')
- mutt_buffer_addch(dest, ch);
- else if (ch == '[')
- mutt_buffer_addch(dest, '\033');
- else if (isalpha((unsigned char) ch))
- mutt_buffer_addch(dest, toupper((unsigned char) ch) - '@');
- else
- {
- mutt_buffer_addch(dest, '^');
- mutt_buffer_addch(dest, ch);
- }
- }
- else if (ch == '`' && (!qc || qc == '"'))
- {
- FILE *fp = NULL;
- pid_t pid;
- char *cmd = NULL, *ptr = NULL;
- size_t expnlen;
- struct Buffer expn;
- int line = 0;
-
- pc = tok->dptr;
- do
- {
- if ((pc = strpbrk(pc, "\\`")))
- {
- /* skip any quoted chars */
- if (*pc == '\\')
- pc += 2;
- }
- } while (pc && *pc != '`');
- if (!pc)
- {
- mutt_debug(1, "mutt_get_token: mismatched backticks\n");
- return -1;
- }
- cmd = mutt_substrdup(tok->dptr, pc);
- if ((pid = mutt_create_filter(cmd, NULL, &fp, NULL)) < 0)
- {
- mutt_debug(1, "mutt_get_token: unable to fork command: %s\n", cmd);
- FREE(&cmd);
- return -1;
- }
- FREE(&cmd);
-
- tok->dptr = pc + 1;
-
- /* read line */
- mutt_buffer_init(&expn);
- expn.data = mutt_read_line(NULL, &expn.dsize, fp, &line, 0);
- safe_fclose(&fp);
- mutt_wait_filter(pid);
-
- /* if we got output, make a new string consisting of the shell output
- plus whatever else was left on the original line */
- /* BUT: If this is inside a quoted string, directly add output to
- * the token */
- if (expn.data && qc)
- {
- mutt_buffer_addstr(dest, expn.data);
- FREE(&expn.data);
- }
- else if (expn.data)
- {
- expnlen = mutt_strlen(expn.data);
- tok->dsize = expnlen + mutt_strlen(tok->dptr) + 1;
- ptr = safe_malloc(tok->dsize);
- memcpy(ptr, expn.data, expnlen);
- strcpy(ptr + expnlen, tok->dptr);
- if (tok->destroy)
- FREE(&tok->data);
- tok->data = ptr;
- tok->dptr = ptr;
- tok->destroy = 1; /* mark that the caller should destroy this data */
- ptr = NULL;
- FREE(&expn.data);
- }
- }
- else if (ch == '$' && (!qc || qc == '"') &&
- (*tok->dptr == '{' || isalpha((unsigned char) *tok->dptr)))
- {
- const char *env = NULL;
- char *var = NULL;
- int idx;
-
- if (*tok->dptr == '{')
- {
- tok->dptr++;
- if ((pc = strchr(tok->dptr, '}')))
- {
- var = mutt_substrdup(tok->dptr, pc);
- tok->dptr = pc + 1;
- }
- }
- else
- {
- for (pc = tok->dptr; isalnum((unsigned char) *pc) || *pc == '_'; pc++)
- ;
- var = mutt_substrdup(tok->dptr, pc);
- tok->dptr = pc;
- }
- if (var)
- {
- if ((env = getenv(var)) || (env = myvar_get(var)))
- mutt_buffer_addstr(dest, env);
- else if ((idx = mutt_option_index(var)) != -1)
- {
- /* expand settable mutt variables */
- char val[LONG_STRING];
-
- if (var_to_string(idx, val, sizeof(val)))
- mutt_buffer_addstr(dest, val);
- }
- FREE(&var);
- }
- }
- else
- mutt_buffer_addch(dest, ch);
- }
- mutt_buffer_addch(dest, 0); /* terminate the string */
- SKIPWS(tok->dptr);
- return 0;
-}
#include <sys/stat.h>
#include <utime.h>
#include "buffy.h"
-#include "buffer.h"
#include "context.h"
#include "globals.h"
#include "header.h"
#include "lib.h"
#include "lib/lib.h"
#include "mailbox.h"
+#include "mutt.h"
#include "mutt_curses.h"
#include "mutt_menu.h"
#include "mx.h"
#include <stdlib.h>
#include <string.h>
#include "mutt.h"
-#include "buffer.h"
#include "context.h"
#include "globals.h"
#include "header.h"
#include "mutt.h"
#include "alias.h"
#include "body.h"
-#include "buffer.h"
#include "buffy.h"
#include "context.h"
#include "copy.h"
+$(MAKE) -C $(top_srcdir) keymap_defs.h
hcversion.h: $(top_srcdir)/mutt.h $(top_srcdir)/address.h $(top_srcdir)/list.h \
- $(top_srcdir)/buffer.h $(top_srcdir)/parameter.h \
+ $(top_srcdir)/lib/lib_buffer.h $(top_srcdir)/parameter.h \
$(top_srcdir)/body.h $(top_srcdir)/envelope.h \
$(top_srcdir)/header.h $(srcdir)/hcachever.sh ../$(MUTT_MD5)
( echo '#include "config.h"'; echo '#include "mutt.h"'; \
echo '#include "address.h"'; echo '#include "list.h"'; \
- echo '#include "buffer.h"'; echo '#include "parameter.h"'; \
+ echo '#include "lib/lib_buffer.h"'; echo '#include "parameter.h"'; \
echo '#include "body.h"'; echo '#include "envelope.h"'; \
echo '#include "header.h"'; \
) | $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) - | sh $(srcdir)/hcachever.sh hcversion.h
#include "address.h"
#include "backend.h"
#include "body.h"
-#include "buffer.h"
#include "charset.h"
#include "envelope.h"
#include "globals.h"
#include "mutt.h"
#include "address.h"
#include "body.h"
-#include "buffer.h"
#include "context.h"
#include "envelope.h"
#include "format_flags.h"
#include <unistd.h>
#include "mutt.h"
#include "address.h"
-#include "buffer.h"
#include "context.h"
#include "envelope.h"
#include "globals.h"
#include "lib/lib.h"
#include "list.h"
#include "mailbox.h"
+#include "mutt.h"
#include "mutt_regex.h"
#include "ncrypt/ncrypt.h"
#include "options.h"
#include <time.h>
#include "imap_private.h"
#include "account.h"
-#include "buffer.h"
#include "buffy.h"
#include "context.h"
#include "globals.h"
#include "account.h"
#include "bcache.h"
#include "body.h"
-#include "buffer.h"
#include "buffy.h"
#include "context.h"
#include "envelope.h"
#include "account.h"
#include "bcache.h"
#include "body.h"
-#include "buffer.h"
#include "context.h"
#include "envelope.h"
#include "globals.h"
#include "mutt.h"
#include "account.h"
#include "bcache.h"
-#include "buffer.h"
#include "context.h"
#include "globals.h"
#include "header.h"
#include "init.h"
#include "address.h"
#include "alias.h"
-#include "buffer.h"
#include "charset.h"
#include "context.h"
#include "envelope.h"
#include "mapping.h"
#include "mbyte.h"
#include "mbyte_table.h"
+#include "mutt.h"
#include "mutt_curses.h"
#include "mutt_idna.h"
#include "mutt_menu.h"
}
#endif
+int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags)
+{
+ if (!dest || !tok)
+ return -1;
+
+ char ch;
+ char qc = 0; /* quote char */
+ char *pc = NULL;
+
+ /* reset the destination pointer to the beginning of the buffer */
+ dest->dptr = dest->data;
+
+ SKIPWS(tok->dptr);
+ while ((ch = *tok->dptr))
+ {
+ if (!qc)
+ {
+ if ((ISSPACE(ch) && !(flags & MUTT_TOKEN_SPACE)) ||
+ (ch == '#' && !(flags & MUTT_TOKEN_COMMENT)) ||
+ (ch == '=' && (flags & MUTT_TOKEN_EQUAL)) ||
+ (ch == ';' && !(flags & MUTT_TOKEN_SEMICOLON)) ||
+ ((flags & MUTT_TOKEN_PATTERN) && strchr("~%=!|", ch)))
+ break;
+ }
+
+ tok->dptr++;
+
+ if (ch == qc)
+ qc = 0; /* end of quote */
+ else if (!qc && (ch == '\'' || ch == '"') && !(flags & MUTT_TOKEN_QUOTE))
+ qc = ch;
+ else if (ch == '\\' && qc != '\'')
+ {
+ if (!*tok->dptr)
+ return -1; /* premature end of token */
+ switch (ch = *tok->dptr++)
+ {
+ case 'c':
+ case 'C':
+ if (!*tok->dptr)
+ return -1; /* premature end of token */
+ mutt_buffer_addch(dest, (toupper((unsigned char) *tok->dptr) - '@') & 0x7f);
+ tok->dptr++;
+ break;
+ case 'r':
+ mutt_buffer_addch(dest, '\r');
+ break;
+ case 'n':
+ mutt_buffer_addch(dest, '\n');
+ break;
+ case 't':
+ mutt_buffer_addch(dest, '\t');
+ break;
+ case 'f':
+ mutt_buffer_addch(dest, '\f');
+ break;
+ case 'e':
+ mutt_buffer_addch(dest, '\033');
+ break;
+ default:
+ if (isdigit((unsigned char) ch) && isdigit((unsigned char) *tok->dptr) &&
+ isdigit((unsigned char) *(tok->dptr + 1)))
+ {
+ mutt_buffer_addch(dest, (ch << 6) + (*tok->dptr << 3) + *(tok->dptr + 1) - 3504);
+ tok->dptr += 2;
+ }
+ else
+ mutt_buffer_addch(dest, ch);
+ }
+ }
+ else if (ch == '^' && (flags & MUTT_TOKEN_CONDENSE))
+ {
+ if (!*tok->dptr)
+ return -1; /* premature end of token */
+ ch = *tok->dptr++;
+ if (ch == '^')
+ mutt_buffer_addch(dest, ch);
+ else if (ch == '[')
+ mutt_buffer_addch(dest, '\033');
+ else if (isalpha((unsigned char) ch))
+ mutt_buffer_addch(dest, toupper((unsigned char) ch) - '@');
+ else
+ {
+ mutt_buffer_addch(dest, '^');
+ mutt_buffer_addch(dest, ch);
+ }
+ }
+ else if (ch == '`' && (!qc || qc == '"'))
+ {
+ FILE *fp = NULL;
+ pid_t pid;
+ char *cmd = NULL, *ptr = NULL;
+ size_t expnlen;
+ struct Buffer expn;
+ int line = 0;
+
+ pc = tok->dptr;
+ do
+ {
+ if ((pc = strpbrk(pc, "\\`")))
+ {
+ /* skip any quoted chars */
+ if (*pc == '\\')
+ pc += 2;
+ }
+ } while (pc && *pc != '`');
+ if (!pc)
+ {
+ mutt_debug(1, "mutt_get_token: mismatched backticks\n");
+ return -1;
+ }
+ cmd = mutt_substrdup(tok->dptr, pc);
+ if ((pid = mutt_create_filter(cmd, NULL, &fp, NULL)) < 0)
+ {
+ mutt_debug(1, "mutt_get_token: unable to fork command: %s\n", cmd);
+ FREE(&cmd);
+ return -1;
+ }
+ FREE(&cmd);
+
+ tok->dptr = pc + 1;
+
+ /* read line */
+ mutt_buffer_init(&expn);
+ expn.data = mutt_read_line(NULL, &expn.dsize, fp, &line, 0);
+ safe_fclose(&fp);
+ mutt_wait_filter(pid);
+
+ /* if we got output, make a new string consisting of the shell output
+ plus whatever else was left on the original line */
+ /* BUT: If this is inside a quoted string, directly add output to
+ * the token */
+ if (expn.data && qc)
+ {
+ mutt_buffer_addstr(dest, expn.data);
+ FREE(&expn.data);
+ }
+ else if (expn.data)
+ {
+ expnlen = mutt_strlen(expn.data);
+ tok->dsize = expnlen + mutt_strlen(tok->dptr) + 1;
+ ptr = safe_malloc(tok->dsize);
+ memcpy(ptr, expn.data, expnlen);
+ strcpy(ptr + expnlen, tok->dptr);
+ if (tok->destroy)
+ FREE(&tok->data);
+ tok->data = ptr;
+ tok->dptr = ptr;
+ tok->destroy = 1; /* mark that the caller should destroy this data */
+ ptr = NULL;
+ FREE(&expn.data);
+ }
+ }
+ else if (ch == '$' && (!qc || qc == '"') &&
+ (*tok->dptr == '{' || isalpha((unsigned char) *tok->dptr)))
+ {
+ const char *env = NULL;
+ char *var = NULL;
+ int idx;
+
+ if (*tok->dptr == '{')
+ {
+ tok->dptr++;
+ if ((pc = strchr(tok->dptr, '}')))
+ {
+ var = mutt_substrdup(tok->dptr, pc);
+ tok->dptr = pc + 1;
+ }
+ }
+ else
+ {
+ for (pc = tok->dptr; isalnum((unsigned char) *pc) || *pc == '_'; pc++)
+ ;
+ var = mutt_substrdup(tok->dptr, pc);
+ tok->dptr = pc;
+ }
+ if (var)
+ {
+ if ((env = getenv(var)) || (env = myvar_get(var)))
+ mutt_buffer_addstr(dest, env);
+ else if ((idx = mutt_option_index(var)) != -1)
+ {
+ /* expand settable mutt variables */
+ char val[LONG_STRING];
+
+ if (var_to_string(idx, val, sizeof(val)))
+ mutt_buffer_addstr(dest, val);
+ }
+ FREE(&var);
+ }
+ }
+ else
+ mutt_buffer_addch(dest, ch);
+ }
+ mutt_buffer_addch(dest, 0); /* terminate the string */
+ SKIPWS(tok->dptr);
+ return 0;
+}
+
static void free_opt(struct Option *p)
{
struct Regex *pp = NULL;
#include <stdlib.h>
#include <string.h>
#include "keymap.h"
-#include "buffer.h"
#include "functions.h"
#include "globals.h"
#include "keymap_defs.h"
#include "lib.h"
#include "lib/lib.h"
#include "mapping.h"
+#include "mutt.h"
#include "mutt_curses.h"
#include "ncrypt/ncrypt.h"
#include "options.h"
AUTOMAKE_OPTIONS = 1.6 foreign
-EXTRA_DIST = lib.h lib_ascii.h lib_base64.h lib_date.h lib_debug.h lib_exit.h lib_file.h lib_md5.h lib_memory.h lib_message.h lib_sha1.h lib_string.h
+EXTRA_DIST = lib.h lib_ascii.h lib_base64.h lib_buffer.h lib_date.h lib_debug.h lib_exit.h lib_file.h lib_md5.h lib_memory.h lib_message.h lib_sha1.h lib_string.h
AM_CPPFLAGS = -I$(top_srcdir)
noinst_LIBRARIES = liblib.a
noinst_HEADERS =
-liblib_a_SOURCES = lib_ascii.c lib_base64.c lib_date.c lib_debug.c lib_exit.c lib_file.c lib_md5.c lib_memory.c lib_message.c lib_sha1.c lib_string.c
+liblib_a_SOURCES = lib_ascii.c lib_base64.c lib_buffer.c lib_date.c lib_debug.c lib_exit.c lib_file.c lib_md5.c lib_memory.c lib_message.c lib_sha1.c lib_string.c
*
* -# @subpage ascii
* -# @subpage base64
+ * -# @subpage buffer
* -# @subpage date
* -# @subpage debug
* -# @subpage exit
#include "lib_ascii.h"
#include "lib_base64.h"
+#include "lib_buffer.h"
#include "lib_date.h"
#include "lib_debug.h"
#include "lib_exit.h"
--- /dev/null
+/**
+ * @file
+ * General purpose object for storing and parsing strings
+ *
+ * @authors
+ * Copyright (C) 2017 Richard Russon <rich@flatcap.org>
+ *
+ * @copyright
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @page buffer General purpose object for storing and parsing strings
+ *
+ * The Buffer object make parsing and manipulating strings easier.
+ *
+ * | Function | Description
+ * | :------------------- | :--------------------------------------------------
+ * | mutt_buffer_addch() | Add a single character to a Buffer
+ * | mutt_buffer_addstr() | Add a string to a Buffer
+ * | mutt_buffer_free() | Release a Buffer and its contents
+ * | mutt_buffer_from() | Create Buffer from an existing string
+ * | mutt_buffer_init() | Initialise a new Buffer
+ * | mutt_buffer_new() | Create and initialise a Buffer
+ * | mutt_buffer_printf() | Format a string into a Buffer
+ */
+
+#include "config.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include "lib_buffer.h"
+#include "lib_memory.h"
+#include "lib_string.h"
+
+/**
+ * mutt_buffer_new - Create and initialise a Buffer
+ * @retval ptr New Buffer
+ *
+ * Call mutt_buffer_free() to release the Buffer.
+ */
+struct Buffer *mutt_buffer_new(void)
+{
+ struct Buffer *b = NULL;
+
+ b = safe_malloc(sizeof(struct Buffer));
+
+ mutt_buffer_init(b);
+
+ return b;
+}
+
+/**
+ * mutt_buffer_init - Initialise a new Buffer
+ * @param b Buffer to initialise
+ * @retval ptr Initialised Buffer
+ *
+ * This must not be called on a Buffer that already contains data.
+ */
+struct Buffer *mutt_buffer_init(struct Buffer *b)
+{
+ memset(b, 0, sizeof(struct Buffer));
+ return b;
+}
+
+/**
+ * mutt_buffer_from - Create Buffer from an existing string
+ * @param seed String to put in the Buffer
+ * @retval ptr New Buffer
+ */
+struct Buffer *mutt_buffer_from(char *seed)
+{
+ struct Buffer *b = NULL;
+
+ if (!seed)
+ return NULL;
+
+ b = mutt_buffer_new();
+ b->data = safe_strdup(seed);
+ b->dsize = mutt_strlen(seed);
+ b->dptr = (char *) b->data + b->dsize;
+ return b;
+}
+
+/**
+ * mutt_buffer_add - Add a string to a Buffer, expanding it if necessary
+ * @param buf Buffer to add to
+ * @param s String to add
+ * @param len Length of the string
+ *
+ * Dynamically grow a Buffer to accommodate s, in increments of 128 bytes.
+ * Always one byte bigger than necessary for the null terminator, and the
+ * buffer is always NUL-terminated
+ */
+static void mutt_buffer_add(struct Buffer *buf, const char *s, size_t len)
+{
+ if (!buf || !s)
+ return;
+
+ if ((buf->dptr + len + 1) > (buf->data + buf->dsize))
+ {
+ size_t offset = buf->dptr - buf->data;
+ buf->dsize += (len < 128) ? 128 : len + 1;
+ safe_realloc(&buf->data, buf->dsize);
+ buf->dptr = buf->data + offset;
+ }
+ if (!buf->dptr)
+ return;
+ memcpy(buf->dptr, s, len);
+ buf->dptr += len;
+ *(buf->dptr) = '\0';
+}
+
+/**
+ * mutt_buffer_free - Release a Buffer and its contents
+ * @param p Buffer pointer to free and NULL
+ */
+void mutt_buffer_free(struct Buffer **p)
+{
+ if (!p || !*p)
+ return;
+
+ FREE(&(*p)->data);
+ /* dptr is just an offset to data and shouldn't be freed */
+ FREE(p);
+}
+
+/**
+ * mutt_buffer_printf - Format a string into a Buffer
+ * @param buf Buffer
+ * @param fmt printf-style format string
+ * @param ... Arguments to be formatted
+ * @retval num Characters written
+ */
+int mutt_buffer_printf(struct Buffer *buf, const char *fmt, ...)
+{
+ va_list ap, ap_retry;
+ int len, blen, doff;
+
+ va_start(ap, fmt);
+ va_copy(ap_retry, ap);
+
+ if (!buf->dptr)
+ buf->dptr = buf->data;
+
+ doff = buf->dptr - buf->data;
+ blen = buf->dsize - doff;
+ /* solaris 9 vsnprintf barfs when blen is 0 */
+ if (!blen)
+ {
+ blen = 128;
+ buf->dsize += blen;
+ safe_realloc(&buf->data, buf->dsize);
+ buf->dptr = buf->data + doff;
+ }
+ len = vsnprintf(buf->dptr, blen, fmt, ap);
+ if (len >= blen)
+ {
+ blen = ++len - blen;
+ if (blen < 128)
+ blen = 128;
+ buf->dsize += blen;
+ safe_realloc(&buf->data, buf->dsize);
+ buf->dptr = buf->data + doff;
+ len = vsnprintf(buf->dptr, len, fmt, ap_retry);
+ }
+ if (len > 0)
+ buf->dptr += len;
+
+ va_end(ap);
+ va_end(ap_retry);
+
+ return len;
+}
+
+/**
+ * mutt_buffer_addstr - Add a string to a Buffer
+ * @param buf Buffer to add to
+ * @param s String to add
+ *
+ * If necessary, the Buffer will be expanded.
+ */
+void mutt_buffer_addstr(struct Buffer *buf, const char *s)
+{
+ mutt_buffer_add(buf, s, mutt_strlen(s));
+}
+
+/**
+ * mutt_buffer_addch - Add a single character to a Buffer
+ * @param buf Buffer to add to
+ * @param c Character to add
+ *
+ * If necessary, the Buffer will be expanded.
+ */
+void mutt_buffer_addch(struct Buffer *buf, char c)
+{
+ mutt_buffer_add(buf, &c, 1);
+}
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _MUTT_BUFFER_H
-#define _MUTT_BUFFER_H
+#ifndef _LIB_BUFFER_H
+#define _LIB_BUFFER_H
#include <stddef.h>
char *data; /**< pointer to data */
char *dptr; /**< current read/write position */
size_t dsize; /**< length of data */
- int destroy; /**< destroy `data' when done? */
+ int destroy; /**< destroy 'data' when done? */
};
-/* flags for mutt_extract_token() */
-#define MUTT_TOKEN_EQUAL (1 << 0) /**< treat '=' as a special */
-#define MUTT_TOKEN_CONDENSE (1 << 1) /**< ^(char) to control chars (macros) */
-#define MUTT_TOKEN_SPACE (1 << 2) /**< don't treat whitespace as a term */
-#define MUTT_TOKEN_QUOTE (1 << 3) /**< don't interpret quotes */
-#define MUTT_TOKEN_PATTERN (1 << 4) /**< !)|~ are terms (for patterns) */
-#define MUTT_TOKEN_COMMENT (1 << 5) /**< don't reap comments */
-#define MUTT_TOKEN_SEMICOLON (1 << 6) /**< don't treat ; as special */
-
struct Buffer *mutt_buffer_new(void);
struct Buffer *mutt_buffer_init(struct Buffer *b);
struct Buffer *mutt_buffer_from(char *seed);
int mutt_buffer_printf(struct Buffer *buf, const char *fmt, ...);
void mutt_buffer_addstr(struct Buffer *buf, const char *s);
void mutt_buffer_addch(struct Buffer *buf, char c);
-int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags);
-#endif /* _MUTT_BUFFER_H */
+#endif /* _LIB_BUFFER_H */
#include <string.h>
#include <wchar.h>
#include "mbyte.h"
-#include "buffer.h"
#include "charset.h"
#include "lib.h"
#include "lib/lib.h"
#define MUTT_NM_TAG (1 << 10) /**< Notmuch tag +/- mode. */
#endif
+/* flags for mutt_get_token() */
+#define MUTT_TOKEN_EQUAL 1 /* treat '=' as a special */
+#define MUTT_TOKEN_CONDENSE (1<<1) /* ^(char) to control chars (macros) */
+#define MUTT_TOKEN_SPACE (1<<2) /* don't treat whitespace as a term */
+#define MUTT_TOKEN_QUOTE (1<<3) /* don't interpret quotes */
+#define MUTT_TOKEN_PATTERN (1<<4) /* !)|~ are terms (for patterns) */
+#define MUTT_TOKEN_COMMENT (1<<5) /* don't reap comments */
+#define MUTT_TOKEN_SEMICOLON (1<<6) /* don't treat ; as special */
+
/* flags for _mutt_system() */
#define MUTT_DETACH_PROCESS 1 /**< detach subprocess from group */
#include <string.h>
#include "mutt.h"
#include "mutt_lua.h"
-#include "buffer.h"
#include "globals.h"
#include "lib.h"
#include "lib/lib.h"
#include "address.h"
#include "alias.h"
#include "body.h"
-#include "buffer.h"
#include "charset.h"
#include "envelope.h"
#include "filter.h"
#include "list.h"
#include "mailbox.h"
#include "mime.h"
+#include "mutt.h"
#include "mutt_curses.h"
#include "mutt_regex.h"
#include "mx.h"
#include <time.h>
#include "mutt.h"
#include "body.h"
-#include "buffer.h"
#include "charset.h"
#include "envelope.h"
#include "globals.h"
#include "pattern.h"
#include "address.h"
#include "body.h"
-#include "buffer.h"
#include "context.h"
#include "copy.h"
#include "envelope.h"
#include "lib/lib.h"
#include "list.h"
#include "mailbox.h"
+#include "mutt.h"
#include "mutt_curses.h"
#include "mutt_menu.h"
#include "mutt_regex.h"
attach.c
bcache.c
browser.c
-buffer.c
buffy.c
charset.c
color.c
lib.c
lib/lib_ascii.c
lib/lib_base64.c
+lib/lib_buffer.c
lib/lib_date.c
lib/lib_debug.c
lib/lib_exit.c
XDG_CONFIG_DIRS,
};
+int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags);
+
void mutt_make_string_info(char *dst, size_t dstlen, int cols, const char *s,
struct HdrFormatInfo *hfi, enum FormatFlag flags);
#include <stdlib.h>
#include <string.h>
#include "mutt.h"
-#include "buffer.h"
#include "context.h"
#include "globals.h"
#include "header.h"
#include "sort.h"
#include "address.h"
#include "body.h"
-#include "buffer.h"
#include "context.h"
#include "envelope.h"
#include "globals.h"