]> granicus.if.org Git - neomutt/commitdiff
move the buffer functions to the library
authorRichard Russon <rich@flatcap.org>
Wed, 2 Aug 2017 15:03:38 +0000 (16:03 +0100)
committerRichard Russon <rich@flatcap.org>
Wed, 2 Aug 2017 16:24:32 +0000 (17:24 +0100)
29 files changed:
Makefile.am
buffer.c [deleted file]
buffy.c
color.c
commands.c
hcache/Makefile.am
hcache/hcache.c
hdrline.c
hook.c
imap/command.c
imap/imap.c
imap/message.c
imap/util.c
init.c
keymap.c
lib/Makefile.am
lib/lib.h
lib/lib_buffer.c [new file with mode: 0644]
lib/lib_buffer.h [moved from buffer.h with 64% similarity]
mbyte.c
mutt.h
mutt_lua.c
muttlib.c
parse.c
pattern.c
po/POTFILES.in
protos.h
score.c
sort.c

index 5ca4975b755cab0c11e50e0551b6fb2ba8218059..8fd077541f9982a9f670da0d2c6b9a8edf09e478 100644 (file)
@@ -45,7 +45,7 @@ BUILT_SOURCES = conststrings.c git_ver.h keymap_alldefs.h keymap_defs.h
 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 \
@@ -82,7 +82,7 @@ EXTRA_mutt_SOURCES = browser.h mbyte.h mutt_idna.c mutt_idna.h \
        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 \
diff --git a/buffer.c b/buffer.c
deleted file mode 100644 (file)
index fb2603c..0000000
--- a/buffer.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/**
- * @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;
-}
diff --git a/buffy.c b/buffy.c
index e68685803b79810476c85be8a030ef5ac41c12eb..ec92b53abc72535210013e2b71cfd44864780539 100644 (file)
--- a/buffy.c
+++ b/buffy.c
 #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"
diff --git a/color.c b/color.c
index a36114e9259e8217ca6eebfe4038d9a96eaaac2c..ec35c57ebfc5cc634d9bb18849f1d390f6f1b6ba 100644 (file)
--- a/color.c
+++ b/color.c
@@ -27,7 +27,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include "mutt.h"
-#include "buffer.h"
 #include "context.h"
 #include "globals.h"
 #include "header.h"
index bbabb499e728b9593b056457b4a7bd22912d1b4a..f8993be2d3eb2059c7fac80ec5f70b77b1d20c9e 100644 (file)
@@ -35,7 +35,6 @@
 #include "mutt.h"
 #include "alias.h"
 #include "body.h"
-#include "buffer.h"
 #include "buffy.h"
 #include "context.h"
 #include "copy.h"
index b53952a95ab156aeaba21b8364a35babcb0913aa..034c5cc3a6ea0d69d6b8798889412579b91709ed 100644 (file)
@@ -45,12 +45,12 @@ $(top_srcdir)/keymap_defs.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
index 1d60badd982291e2040bcbe3da3b04e728cb4988..c4c1c3fa24a11af7d010ce24ab445df756ef3d22 100644 (file)
@@ -42,7 +42,6 @@
 #include "address.h"
 #include "backend.h"
 #include "body.h"
-#include "buffer.h"
 #include "charset.h"
 #include "envelope.h"
 #include "globals.h"
index 0cb3ea4632a169d6777823a369c2316f4138a887..bcff24d2847defad1668636d18cbca16217b3024 100644 (file)
--- a/hdrline.c
+++ b/hdrline.c
@@ -33,7 +33,6 @@
 #include "mutt.h"
 #include "address.h"
 #include "body.h"
-#include "buffer.h"
 #include "context.h"
 #include "envelope.h"
 #include "format_flags.h"
diff --git a/hook.c b/hook.c
index cc8a1e703b4efb40fa28fe97d6c76db4176ec6b7..c6c1e4b7de365ba59d86371028e7726a881e7aff 100644 (file)
--- a/hook.c
+++ b/hook.c
@@ -30,7 +30,6 @@
 #include <unistd.h>
 #include "mutt.h"
 #include "address.h"
-#include "buffer.h"
 #include "context.h"
 #include "envelope.h"
 #include "globals.h"
@@ -39,6 +38,7 @@
 #include "lib/lib.h"
 #include "list.h"
 #include "mailbox.h"
+#include "mutt.h"
 #include "mutt_regex.h"
 #include "ncrypt/ncrypt.h"
 #include "options.h"
index ae547f6c9e52b3bf665287ad47ced1a6eedfca60..66c29ed677dbd262d219c0f036648c9e321af8b3 100644 (file)
@@ -34,7 +34,6 @@
 #include <time.h>
 #include "imap_private.h"
 #include "account.h"
-#include "buffer.h"
 #include "buffy.h"
 #include "context.h"
 #include "globals.h"
index 11d3479210b16213a0c8d46972fd0c831b18a2d1..e38cd137918eadd03904182c3e9483e4e2b1defb 100644 (file)
@@ -39,7 +39,6 @@
 #include "account.h"
 #include "bcache.h"
 #include "body.h"
-#include "buffer.h"
 #include "buffy.h"
 #include "context.h"
 #include "envelope.h"
index a709c56f5e06bb5ee50140ffd74c55d2f719faf2..a7fcc8e3248848237208212a567ebc417b12457e 100644 (file)
@@ -36,7 +36,6 @@
 #include "account.h"
 #include "bcache.h"
 #include "body.h"
-#include "buffer.h"
 #include "context.h"
 #include "envelope.h"
 #include "globals.h"
index c12da5777a3f0be1ae95f31ad331de99b5db3c86..a424465b5de9ca3c8f06d6803d97d0a73cc4304d 100644 (file)
@@ -40,7 +40,6 @@
 #include "mutt.h"
 #include "account.h"
 #include "bcache.h"
-#include "buffer.h"
 #include "context.h"
 #include "globals.h"
 #include "header.h"
diff --git a/init.c b/init.c
index 9243ce89a9ee97ee6a2221cd191cd0a68258e49c..4bed4ef9e3778dfefa8d52be2a5fba6575fd1968 100644 (file)
--- a/init.c
+++ b/init.c
@@ -41,7 +41,6 @@
 #include "init.h"
 #include "address.h"
 #include "alias.h"
-#include "buffer.h"
 #include "charset.h"
 #include "context.h"
 #include "envelope.h"
@@ -59,6 +58,7 @@
 #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"
@@ -513,6 +513,205 @@ int mutt_option_set(const struct Option *val, struct Buffer *err)
 }
 #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;
index f643bc9bb0f2526e8068152296680ae9e2d08b01..e5da8fa587f24d597d28290c793a0c64f547e1cd 100644 (file)
--- a/keymap.c
+++ b/keymap.c
 #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"
index 83526af1cf47a13719c84a6fcb8cfca6873d50c9..cc36caa6c9e2ef17df11fac6a6027dabc9c4355d 100644 (file)
@@ -3,12 +3,12 @@ include $(top_srcdir)/flymake.am
 
 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
 
index 4986a69e48d3dc0fe62a742ecb0773c4b06bca4c..f68d0f1b915d55d4e6f6b9afff8f78a9ac84baa7 100644 (file)
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -30,6 +30,7 @@
  *
  * -# @subpage ascii
  * -# @subpage base64
+ * -# @subpage buffer
  * -# @subpage date
  * -# @subpage debug
  * -# @subpage exit
@@ -46,6 +47,7 @@
 
 #include "lib_ascii.h"
 #include "lib_base64.h"
+#include "lib_buffer.h"
 #include "lib_date.h"
 #include "lib_debug.h"
 #include "lib_exit.h"
diff --git a/lib/lib_buffer.c b/lib/lib_buffer.c
new file mode 100644 (file)
index 0000000..e45e2f4
--- /dev/null
@@ -0,0 +1,209 @@
+/**
+ * @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);
+}
similarity index 64%
rename from buffer.h
rename to lib/lib_buffer.h
index 9480374b290576abf3277f5bb2f5d3815b9277b9..d4e80809c0376c825c19672cee8e26fd64678e15 100644 (file)
--- a/buffer.h
@@ -18,8 +18,8 @@
  * 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>
 
@@ -31,18 +31,9 @@ struct Buffer
   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);
@@ -50,6 +41,5 @@ void mutt_buffer_free(struct Buffer **p);
 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 */
diff --git a/mbyte.c b/mbyte.c
index d00c606847c3986724b463b160e4a4a014d391bf..bfc98139fa15da8869a9f3f6da799c46ab5be909 100644 (file)
--- a/mbyte.c
+++ b/mbyte.c
@@ -31,7 +31,6 @@
 #include <string.h>
 #include <wchar.h>
 #include "mbyte.h"
-#include "buffer.h"
 #include "charset.h"
 #include "lib.h"
 #include "lib/lib.h"
diff --git a/mutt.h b/mutt.h
index fcb615932f559b8c6f8e1215959d6362bc5dc9e9..d63f5b23bd201011c79ae994c8d9c98a22ad715f 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -77,6 +77,15 @@ struct State;
 #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 */
 
index 95e3ad3cae658703f8e4f24a266f51e8cde6a0ce..f945e59bf82f47360093adbf55a2913fcfb63852 100644 (file)
@@ -31,7 +31,6 @@
 #include <string.h>
 #include "mutt.h"
 #include "mutt_lua.h"
-#include "buffer.h"
 #include "globals.h"
 #include "lib.h"
 #include "lib/lib.h"
index 526a902ba5a7ff0f6aff0a613e9829838a8ae2ca..7bd4375e2893dbcbd1c17e7a366e4d3b2c062b98 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -46,7 +46,6 @@
 #include "address.h"
 #include "alias.h"
 #include "body.h"
-#include "buffer.h"
 #include "charset.h"
 #include "envelope.h"
 #include "filter.h"
@@ -58,6 +57,7 @@
 #include "list.h"
 #include "mailbox.h"
 #include "mime.h"
+#include "mutt.h"
 #include "mutt_curses.h"
 #include "mutt_regex.h"
 #include "mx.h"
diff --git a/parse.c b/parse.c
index 33420d6fe433aa942992cf79af27891bb79af09e..d04633bc1da26797f77f66afc47e067cec3b2cba 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -30,7 +30,6 @@
 #include <time.h>
 #include "mutt.h"
 #include "body.h"
-#include "buffer.h"
 #include "charset.h"
 #include "envelope.h"
 #include "globals.h"
index 03bc44df5123df01f57b24cf56e3df68db98313b..c6a929457d109270443f426acbcaef5dc5f5380a 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -40,7 +40,6 @@
 #include "pattern.h"
 #include "address.h"
 #include "body.h"
-#include "buffer.h"
 #include "context.h"
 #include "copy.h"
 #include "envelope.h"
@@ -52,6 +51,7 @@
 #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"
index 821ed95b236c0cbfaacbcf2639c0b279b7cfa4a9..d5962854ead52600f00aac3bdbd858b48fad3d0b 100644 (file)
@@ -4,7 +4,6 @@ alias.c
 attach.c
 bcache.c
 browser.c
-buffer.c
 buffy.c
 charset.c
 color.c
@@ -60,6 +59,7 @@ keymap_alldefs.h
 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
index 6700d16980597a9e48ae0e77d1f141477e81b190..34fea868d27bba59121241d9b24c74ab4a43b193 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -78,6 +78,8 @@ enum XdgType
   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);
 
diff --git a/score.c b/score.c
index a676097d15443e9db556e2d2270c28956d3cc30b..617ce0711ba82237d4a9b030cb5159212730b478 100644 (file)
--- a/score.c
+++ b/score.c
@@ -24,7 +24,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include "mutt.h"
-#include "buffer.h"
 #include "context.h"
 #include "globals.h"
 #include "header.h"
diff --git a/sort.c b/sort.c
index bb8cb7c2d670e404607cb98ee83a62f9fa10171a..13e9f9909f0f4fd3ab6685c6a1d91dd0df0dfb8d 100644 (file)
--- a/sort.c
+++ b/sort.c
@@ -27,7 +27,6 @@
 #include "sort.h"
 #include "address.h"
 #include "body.h"
-#include "buffer.h"
 #include "context.h"
 #include "envelope.h"
 #include "globals.h"