From 9aae63e2d1cce39bb0928362416a8d17b953ca5e Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 29 Oct 2006 16:19:40 +0100 Subject: [PATCH] reindent and optimizations in BUFFER* struct. put the BUFFER type decl in buffer.h where it belongs. --- buffer.c | 408 +++++++++++++++++++++++++++++-------------------------- buffer.h | 50 +++++-- mutt.h | 8 +- protos.h | 2 + 4 files changed, 258 insertions(+), 210 deletions(-) diff --git a/buffer.c b/buffer.c index e16b590..14ae894 100644 --- a/buffer.c +++ b/buffer.c @@ -1,3 +1,22 @@ +/* + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Copyright © 2006 Pierre Habouzit + */ + /* * Copyright notice from original mutt: * Copyright (C) 1996-2000 Michael R. Elkins @@ -16,8 +35,10 @@ #include #include +#include #include "buffer.h" +#include "mutt.h" #include "lib/debug.h" @@ -46,227 +67,224 @@ BUFFER *mutt_buffer_init(BUFFER *b) * Disregards the 'destroy' flag, which seems reserved for caller. * This is bad, but there's no apparent protocol for it. */ -BUFFER *mutt_buffer_from (BUFFER * b, const char *seed) -{ - if (!seed) - return NULL; - - b = mutt_buffer_init (b); - b->data = m_strdup(seed); - b->dsize = m_strlen(seed); - b->dptr = (char *) b->data + b->dsize; - return b; -} - -void mutt_buffer_addstr (BUFFER * buf, const char *s) +BUFFER *mutt_buffer_from(BUFFER * b, const char *seed) { - mutt_buffer_add (buf, s, m_strlen(s)); -} + if (!seed) + return NULL; -void mutt_buffer_addch (BUFFER * buf, char c) -{ - mutt_buffer_add (buf, &c, 1); + b = mutt_buffer_init(b); + b->dsize = m_strlen(seed); + b->data = m_strdup(seed); + b->dptr = (char *)b->data + b->dsize; + return b; } -void mutt_buffer_free (BUFFER ** p) +void mutt_buffer_free(BUFFER **p) { - if (!p || !*p) - return; - - p_delete(&(*p)->data); - /* dptr is just an offset to data and shouldn't be freed */ - p_delete(p); + if (p && *p) { + p_delete(&(*p)->data); + p_delete(p); + } } /* dynamically grows a BUFFER to accomodate s, in increments of 128 bytes. * Always one byte bigger than necessary for the null terminator, and * the buffer is always null-terminated */ -void mutt_buffer_add (BUFFER *buf, const char *s, size_t len) +void mutt_buffer_add(BUFFER *buf, const char *s, size_t len) { - size_t offset; + size_t offset; - if (buf->dptr + len + 1 > buf->data + buf->dsize) { - offset = buf->dptr - buf->data; - buf->dsize += len < 128 ? 128 : len + 1; - p_realloc(&buf->data, buf->dsize); - buf->dptr = buf->data + offset; - } - memcpy (buf->dptr, s, len); - buf->dptr += len; - *(buf->dptr) = '\0'; + if (buf->dptr + len + 1 > buf->data + buf->dsize) { + offset = buf->dptr - buf->data; + buf->dsize += ((len + 1 + 127) & ~127); + p_realloc(&buf->data, buf->dsize); + buf->dptr = buf->data + offset; + } + memcpy(buf->dptr, s, len); + buf->dptr += len; + *buf->dptr = '\0'; } -int mutt_extract_token (BUFFER * dest, BUFFER * tok, int flags) +int mutt_extract_token(BUFFER *dest, BUFFER *tok, int flags) { - char ch; - char qc = 0; /* quote char */ - char *pc; + char ch; + char qc = 0; /* quote char */ + char *pc; - /* 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 & M_TOKEN_SPACE)) || - (ch == '#' && !(flags & M_TOKEN_COMMENT)) || - (ch == '=' && (flags & M_TOKEN_EQUAL)) || - (ch == ';' && !(flags & M_TOKEN_SEMICOLON)) || - ((flags & M_TOKEN_PATTERN) && strchr ("~=!|", ch))) - break; - } + /* reset the destination pointer to the beginning of the buffer */ + dest->dptr = dest->data; - tok->dptr++; + SKIPWS(tok->dptr); + while ((ch = *tok->dptr)) { + if (!qc) { + if ((ISSPACE(ch) && !(flags & M_TOKEN_SPACE)) + || (ch == '#' && !(flags & M_TOKEN_COMMENT)) + || (ch == '=' && (flags & M_TOKEN_EQUAL)) + || (ch == ';' && !(flags & M_TOKEN_SEMICOLON)) + || ((flags & M_TOKEN_PATTERN) && strchr("~=!|", ch))) + { + break; + } + } - if (ch == qc) - qc = 0; /* end of quote */ - else if (!qc && (ch == '\'' || ch == '"') && !(flags & M_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 & M_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; - pid_t pid; - char *cmd, *ptr; - size_t expnlen; - BUFFER expn; - int line = 0; + if (ch == qc) { + qc = 0; /* end of quote */ + } else + if (!qc && (ch == '\'' || ch == '"') && !(flags & M_TOKEN_QUOTE)) { + qc = ch; + } else + if (ch == '\\' && qc != '\'') { + if (!*tok->dptr) + return -1; /* premature end of token */ - pc = tok->dptr; - do { - if ((pc = strpbrk (pc, "\\`"))) { - /* skip any quoted chars */ - if (*pc == '\\') - pc += 2; - } - } while (pc && *pc != '`'); - if (!pc) { - debug_print (1, ("mismatched backtics\n")); - return (-1); - } - cmd = str_substrdup (tok->dptr, pc); - if ((pid = mutt_create_filter (cmd, NULL, &fp, NULL)) < 0) { - debug_print (1, ("unable to fork command: %s\n", cmd)); - p_delete(&cmd); - return (-1); - } - p_delete(&cmd); + switch (ch = *tok->dptr++) { + case 'c': + case 'C': + if (!*tok->dptr) + return -1; /* premature end of token */ + mutt_buffer_addch(dest, + (ascii_toupper(*tok->dptr) - 'A' + 1) & 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 & M_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, ascii_toupper(ch) - 'A' + 1); + } else { + mutt_buffer_addch(dest, '^'); + mutt_buffer_addch(dest, ch); + } + } else + if (ch == '`' && (!qc || qc == '"')) { + FILE *fp; + pid_t pid; + char *cmd, *ptr; + size_t expnlen; + BUFFER expn; + int line = 0; - tok->dptr = pc + 1; + pc = tok->dptr; + do { + if ((pc = strpbrk(pc, "\\`"))) { + /* skip any quoted chars */ + if (*pc == '\\') + pc += 2; + } + } while (pc && *pc != '`'); + if (!pc) { + debug_print (1, ("mismatched backtics\n")); + return (-1); + } - /* read line */ - p_clear(&expn, 1); - expn.data = mutt_read_line (NULL, &expn.dsize, fp, &line); - fclose (fp); - mutt_wait_filter (pid); + cmd = p_dupstr(tok->dptr, pc - tok->dptr); + if ((pid = mutt_create_filter(cmd, NULL, &fp, NULL)) < 0) { + debug_print(1, ("unable to fork command: %s\n", cmd)); + p_delete(&cmd); + return -1; + } + p_delete(&cmd); - /* if we got output, make a new string consiting of the shell ouptput - 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); - p_delete(&expn.data); - } - else if (expn.data) { - expnlen = m_strlen(expn.data); - tok->dsize = expnlen + m_strlen(tok->dptr) + 1; - ptr = xmalloc(tok->dsize); - memcpy (ptr, expn.data, expnlen); - strcpy (ptr + expnlen, tok->dptr); /* __STRCPY_CHECKED__ */ - if (tok->destroy) - p_delete(&tok->data); - tok->data = ptr; - tok->dptr = ptr; - tok->destroy = 1; /* mark that the caller should destroy this data */ - ptr = NULL; - p_delete(&expn.data); - } - } - else if (ch == '$' && (!qc || qc == '"') - && (*tok->dptr == '{' || isalpha ((unsigned char) *tok->dptr))) { - char *env = NULL, *var = NULL; + tok->dptr = pc + 1; - if (*tok->dptr == '{') { - tok->dptr++; - if ((pc = strchr (tok->dptr, '}'))) { - var = str_substrdup (tok->dptr, pc); - tok->dptr = pc + 1; + /* read line */ + p_clear(&expn, 1); + expn.data = mutt_read_line(NULL, &expn.dsize, fp, &line); + fclose(fp); + mutt_wait_filter(pid); + + /* if we got output, make a new string consiting of the shell ouptput + 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); + p_delete(&expn.data); + } else + if (expn.data) { + expnlen = m_strlen(expn.data); + tok->dsize = expnlen + m_strlen(tok->dptr) + 1; + ptr = xmalloc(tok->dsize); + memcpy(ptr, expn.data, expnlen); + strcpy(ptr + expnlen, tok->dptr); /* __STRCPY_CHECKED__ */ + if (tok->destroy) + p_delete(&tok->data); + tok->data = ptr; + tok->dptr = ptr; + tok->destroy = 1; /* mark that the caller should destroy this data */ + ptr = NULL; + p_delete(&expn.data); + } + } else + if (ch == '$' && (!qc || qc == '"') + && (*tok->dptr == '{' || isalpha((unsigned char)*tok->dptr))) + { + char *env = NULL, *var = NULL; + + if (*tok->dptr == '{') { + tok->dptr++; + if ((pc = strchr (tok->dptr, '}'))) { + var = str_substrdup (tok->dptr, pc); + tok->dptr = pc + 1; + } + } else { + for (pc = tok->dptr; isalnum((unsigned char)*pc) || *pc == '_'; + pc++); + var = p_dupstr(tok->dptr, pc - tok->dptr); + tok->dptr = pc; + } + if (var) { + char tmp[STRING]; + if ((env = getenv (var)) + || (mutt_option_value (var, tmp, sizeof (tmp)) && (env = tmp))) + { + mutt_buffer_addstr (dest, env); + } + } + p_delete(&var); + } else { + mutt_buffer_addch(dest, ch); } - } - else { - for (pc = tok->dptr; isalnum ((unsigned char) *pc) || *pc == '_'; - pc++); - var = str_substrdup (tok->dptr, pc); - tok->dptr = pc; - } - if (var) { - char tmp[STRING]; - if ((env = getenv (var)) || - (mutt_option_value (var, tmp, sizeof (tmp)) && (env = tmp))) - mutt_buffer_addstr (dest, env); - } - p_delete(&var); } - else - mutt_buffer_addch (dest, ch); - } - mutt_buffer_addch (dest, 0); /* terminate the string */ - SKIPWS (tok->dptr); - return 0; + mutt_buffer_addch(dest, 0); /* terminate the string */ + SKIPWS(tok->dptr); + return 0; } diff --git a/buffer.h b/buffer.h index 877b1ec..bd3499d 100644 --- a/buffer.h +++ b/buffer.h @@ -1,3 +1,22 @@ +/* + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Copyright © 2006 Pierre Habouzit + */ + /* * Copyright notice from original mutt: * Copyright (C) 1996-2000 Michael R. Elkins @@ -6,17 +25,32 @@ * It's licensed under the GNU General Public License, * please see the file GPL in the top level source directory. */ + #ifndef _MUTT_BUFFER_H #define _MUTT_BUFFER_H -#include "mutt.h" +#include + +typedef struct { + char *data; /* pointer to data */ + char *dptr; /* current read/write position */ + size_t dsize; /* length of data */ + int destroy; /* destroy `data' when done? */ +} BUFFER; + +BUFFER *mutt_buffer_init(BUFFER *); +void mutt_buffer_free(BUFFER **); + +BUFFER *mutt_buffer_from(BUFFER *, const char *); +int mutt_extract_token(BUFFER *, BUFFER *, int); + +void mutt_buffer_add(BUFFER *, const char *, size_t); +static inline void mutt_buffer_addstr(BUFFER *b, const char *s) { + mutt_buffer_add(b, s, m_strlen(s)); +} -int mutt_extract_token (BUFFER *, BUFFER *, int); -BUFFER *mutt_buffer_init (BUFFER *); -BUFFER *mutt_buffer_from (BUFFER *, const char *); -void mutt_buffer_free (BUFFER **); -void mutt_buffer_add (BUFFER *, const char *, size_t); -void mutt_buffer_addstr (BUFFER *, const char *); -void mutt_buffer_addch (BUFFER *, char); +static inline void mutt_buffer_addch(BUFFER *b, char c) { + mutt_buffer_add(b, &c, 1); +} #endif /* !_MUTT_BUFFER_H */ diff --git a/mutt.h b/mutt.h index c3a3801..fc4844b 100644 --- a/mutt.h +++ b/mutt.h @@ -41,6 +41,7 @@ #include #include +#include "buffer.h" #include "rfc822.h" #include "list.h" #include "hash.h" @@ -74,13 +75,6 @@ #define M_TOKEN_COMMENT (1<<5) /* don't reap comments */ #define M_TOKEN_SEMICOLON (1<<6) /* don't treat ; as special */ -typedef struct { - char *data; /* pointer to data */ - char *dptr; /* current read/write position */ - size_t dsize; /* length of data */ - int destroy; /* destroy `data' when done? */ -} BUFFER; - typedef struct { int ch; /* raw key pressed */ int op; /* function op */ diff --git a/protos.h b/protos.h index c650c62..46532d0 100644 --- a/protos.h +++ b/protos.h @@ -19,6 +19,8 @@ #include "mbyte.h" +#include "buffer.h" + #define MoreArgs(p) (*p->dptr && *p->dptr != ';' && *p->dptr != '#') #define mutt_make_string(A,B,C,D,E) _mutt_make_string(A,B,C,D,E,0) -- 2.20.1