"Fossies" - the Fresh Open Source Software Archive

Member "leafnode-1.12.0/mastring.c" (28 Dec 2021, 5886 Bytes) of package /linux/misc/leafnode-1.12.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mastring.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.11.12_vs_1.12.0.

    1 /* mastring.c -- Implement auto-allocating string functions.
    2  *
    3  * (C) 2001 - 2003 by Matthias Andree <matthias.andree@gmx.de>
    4  *
    5  * This library is free software; you can redistribute it and/or modify
    6  * it under the terms of the GNU Lesser General Public License as
    7  * published by the Free Software Foundation; either version 2 or 2.1 of
    8  * the License. See the file COPYING.LGPL for details.
    9  *
   10  * This library is distributed in the hope that it will be useful, but
   11  * WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13  * Lesser General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU Lesser General Public
   16  * License along with this library; if not, write to the Free Software
   17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   18  * USA
   19  */
   20 
   21 #include "config.h"
   22 
   23 #include <string.h>
   24 #include <stdlib.h>
   25 #include <stdarg.h>
   26 #include <ctype.h>
   27 
   28 #include "wantassert.h"
   29 #include <assert.h>
   30 
   31 #define len PRIVATE__len
   32 #define dat PRIVATE__dat
   33 #define bufsize PRIVATE__bufsize
   34 #include "mastring.h"
   35 
   36 #ifdef WITH_DMALLOC
   37 #include <dmalloc.h>
   38 #endif
   39 
   40 #include "getline.h"
   41 
   42 static inline /*@exits@*/ void
   43 mastr_oom(void)
   44 #if defined(MASTR_OOM_ABORT) && defined(__GNUC__)
   45     __attribute__ ((noreturn))
   46 #endif
   47     ;
   48 
   49 /*@noreturn@*/
   50 static inline void
   51 mastr_oom(void)
   52 {
   53 #ifdef MASTR_OOM_ABORT
   54     abort();
   55 #endif
   56 }
   57 
   58 #undef min
   59 #define min(a,b) ((a < b) ? (a) : (b))
   60 
   61 mastr *
   62 mastr_new(size_t size)
   63 {
   64     mastr *n;
   65 
   66     assert(size != 0);
   67 
   68     n = (mastr *)malloc(sizeof(mastr));
   69     if (!n) {
   70     mastr_oom();
   71     /*@notreached@*/ return NULL;
   72     }
   73     n->bufsize = size + 1;
   74     if (!(n->dat = (char *)malloc(n->bufsize))) {
   75     free(n);
   76     mastr_oom();
   77     /*@notreached@*/ return NULL;
   78     }
   79     n->dat[0] = '\0';
   80     n->len = 0;
   81     return n;
   82 }
   83 
   84 
   85 mastr *
   86 mastr_newstr(const char *s)
   87 {
   88     size_t l;
   89     mastr *n;
   90 
   91     if (!s)
   92     return NULL;
   93     n = mastr_new((l = strlen(s)));
   94     if (!n)
   95     return NULL;
   96     memcpy(n->dat, s, l + 1);
   97     n->len = l;
   98     return n;
   99 }
  100 
  101 int
  102 mastr_cpy(mastr * m, const char *s)
  103 {
  104     size_t l;
  105 
  106     if (!m || !s)
  107     return 0;
  108 
  109     if ((l = strlen(s)) >= m->bufsize)
  110     if (0 == mastr_resizekill(m, l)) {
  111         mastr_oom();
  112         /*@notreached@*/ return 0;
  113     }
  114     memcpy(m->dat, s, l + 1);
  115     m->len = l;
  116     return 1;
  117 }
  118 
  119 int
  120 mastr_cat(mastr * m, /*@unique@*/ /*@observer@*/ const char *const s)
  121 {
  122     size_t li;
  123 
  124     if (!m || !s)
  125     return 0;
  126 
  127     if ((li = strlen(s)) + m->len >= m->bufsize)
  128     if (0 == mastr_resizekeep(m, li + m->len)) {
  129         mastr_oom();
  130         /*@notreached@*/ return 0;
  131     }
  132     memcpy(m->dat + m->len, s, li + 1);
  133     m->len += li;
  134     return 1;
  135 }
  136 
  137 void
  138 mastr_clear(mastr * m)
  139 {
  140     if (!m)
  141     return;
  142     m->len = 0;
  143     m->dat[0] = '\0';
  144 }
  145 
  146 int
  147 mastr_vcat(mastr * m, ...)
  148 {
  149     long addlen = 0;
  150     const char *t;
  151     char *u;
  152     va_list v;
  153 
  154     if (!m)
  155     return 0;
  156 
  157     /* get length */
  158     va_start(v, m);
  159     while ((t = va_arg(v, const char *))) {
  160     addlen += strlen(t);
  161     }
  162     va_end(v);
  163 
  164     if (m->len + addlen >= m->bufsize) {
  165     if (!mastr_resizekeep(m, addlen + m->len)) {
  166         mastr_oom();
  167         /*@notreached@*/ return 0;
  168     }
  169     }
  170     va_start(v, m);
  171     u = m->dat + m->len;
  172     while ((t = va_arg(v, const char *))) {
  173     while ((*u = *t++))
  174         u++;
  175     }
  176     m->len += addlen;
  177     va_end(v);
  178     return 1;
  179 }
  180 
  181 int
  182 mastr_resizekill(mastr * m, size_t l)
  183 {
  184     char *n;
  185 
  186     if (!m)
  187     return 0;
  188     n = (char *)malloc(l + 1);
  189     if (!n) {
  190     mastr_oom();
  191     /*@notreached@*/ return 0;
  192     }
  193     free(m->dat);
  194     m->dat = n;
  195     m->bufsize = l + 1;
  196     m->dat[0] = '\0';
  197     m->len = 0;
  198     return 1;
  199 }
  200 
  201 int
  202 mastr_resizekeep(mastr * m, size_t l)
  203 {
  204     char *n;
  205 
  206     if (!m)
  207     return 0;
  208     n = (char *)realloc(m->dat, l + 1);
  209     if (!n) {
  210     free(m->dat);
  211     mastr_oom();
  212     /*@notreached@*/ return 0;
  213     }
  214     m->dat = n;
  215     m->bufsize = l + 1;
  216     m->dat[l] = '\0';
  217     if (l < m->len)
  218     m->len = l;
  219     return 1;
  220 }
  221 
  222 void
  223 mastr_delete(/*@only@*/ mastr * m)
  224 {
  225     if (m) {
  226     free(m->dat);
  227     free(m);
  228     }
  229 }
  230 
  231 void
  232 mastr_triml(mastr * m)
  233 {
  234     char *p, *q;
  235     if (!m)
  236     return;
  237     p = q = m->dat;
  238     while (*p && isspace((unsigned char)*p))
  239     p++;
  240     if (p != q) {
  241     /*@-whileempty@*/
  242     while ((*q++ = *p++));
  243     /*@=whileempty@*/
  244     m->len -= p - q;
  245     }
  246 }
  247 
  248 void
  249 mastr_trimr(mastr * m)
  250 {
  251     char *p;
  252     if (!m)
  253     return;
  254     p = m->dat + m->len;
  255     /*@-whileempty@*/
  256     while (--p >= m->dat && isspace((unsigned char)*p));
  257     /*@=whileempty@*/
  258     *++p = '\0';
  259     m->len = (size_t)(p - m->dat);
  260 }
  261 
  262 #if LEAFNODE_VERSION > 1
  263 ssize_t
  264 mastr_getln(mastr * m, FILE * f,
  265         ssize_t maxbytes /** if negative: unlimited */ )
  266 {
  267     /* FIXME: make this overflow safe, size_t vs. ssize_t. */
  268     char buf[4096];
  269     ssize_t bufsiz = (ssize_t)sizeof buf;
  270     ssize_t r;
  271 
  272     mastr_clear(m);
  273 
  274     for (;;) {
  275     r = _getline(buf,
  276              (size_t)(maxbytes > 0 ? min(bufsiz, maxbytes+1) : bufsiz),
  277              f);
  278     if (r < 0)
  279         return r;
  280     if (r == 0)
  281         break;
  282     if (r + m->len >= m->bufsize)
  283         if (!mastr_resizekeep(m, r + m->len)) {
  284         mastr_oom();
  285         /*@notreached@*/ return 0;
  286         }
  287     memcpy(m->dat + m->len, buf, (size_t)r); /* FIXME: avoid this copy */
  288     if (maxbytes > 0)
  289         maxbytes -= r;
  290     m->len += r;
  291     m->dat[m->len] = '\0';
  292     if (memchr(buf, '\n', (size_t)r) != NULL)
  293         break;
  294     }
  295     return (ssize_t)(m->len);
  296 }
  297 #endif
  298 
  299 /* chop off last character of string */
  300 static void
  301 choplast(mastr * m)
  302 {
  303     if (m && m->len) {
  304     --m->len;
  305     m->dat[m->len] = '\0';
  306     }
  307 }
  308 
  309 /** chop off trailing LF or CRLF */
  310 void
  311 mastr_chop(mastr * m)
  312 {
  313     if (m && m->len && m->dat[m->len - 1] == '\n')
  314     choplast(m);
  315     if (m && m->len && m->dat[m->len - 1] == '\r')
  316     choplast(m);
  317 }
  318 
  319 /** return size of buffer */
  320 size_t
  321 mastr_size(mastr * m)
  322 {
  323     return m->bufsize - 1;
  324 }
  325 
  326 /** return length of buffer */
  327 size_t
  328 mastr_len(mastr * m)
  329 {
  330     return m->len;
  331 }