"Fossies" - the Fresh Open Source Software Archive

Member "bc-1.06.95/dc/string.c" (29 Mar 2006, 5380 Bytes) of package /linux/misc/old/bc-1.06.95.tar.gz:


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 "string.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.06.95_vs_1.07.

    1 /* 
    2  * implement string functions for dc
    3  *
    4  * Copyright (C) 1994, 1997, 1998, 2006 Free Software Foundation, Inc.
    5  *
    6  * This program is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; either version 2, or (at your option)
    9  * any later version.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, you can either send email to this
   18  * program's author (see below) or write to:
   19  *
   20  *    The Free Software Foundation, Inc.
   21  *    51 Franklin Street, Fifth Floor
   22  *    Boston, MA 02110-1301  USA
   23  */
   24 
   25 /* This should be the only module that knows the internals of type dc_string */
   26 
   27 #include "config.h"
   28 
   29 #include <stdio.h>
   30 #ifdef HAVE_STDDEF_H
   31 # include <stddef.h>    /* ptrdiff_t */
   32 #else
   33 # define ptrdiff_t  size_t
   34 #endif
   35 #ifdef HAVE_STDLIB_H
   36 # include <stdlib.h>
   37 #endif
   38 #ifdef HAVE_STRING_H
   39 # include <string.h>    /* memcpy */
   40 #else
   41 # ifdef HAVE_MEMORY_H
   42 #  include <memory.h>   /* memcpy, maybe */
   43 # else
   44 #  ifdef HAVE_STRINGS_H
   45 #   include <strings.h> /* memcpy, maybe */
   46 #  endif
   47 # endif
   48 #endif
   49 #include "dc.h"
   50 #include "dc-proto.h"
   51 
   52 /* here is the completion of the dc_string type: */
   53 struct dc_string {
   54     char *s_ptr;  /* pointer to base of string */
   55     size_t s_len; /* length of counted string */
   56     int  s_refs;  /* reference count to cut down on memory use by duplicates */
   57 };
   58 
   59 
   60 /* return a duplicate of the string in the passed value */
   61 /* The mismatched data types forces the caller to deal with
   62  * bad dc_type'd dc_data values, and makes it more convenient
   63  * for the caller to not have to do the grunge work of setting
   64  * up a dc_type result.
   65  */
   66 dc_data
   67 dc_dup_str DC_DECLARG((value))
   68     dc_str value DC_DECLEND
   69 {
   70     dc_data result;
   71 
   72     ++value->s_refs;
   73     result.v.string = value;
   74     result.dc_type = DC_STRING;
   75     return result;
   76 }
   77 
   78 /* free an instance of a dc_str value */
   79 void
   80 dc_free_str DC_DECLARG((value))
   81     dc_str *value DC_DECLEND
   82 {
   83     struct dc_string *string = *value;
   84 
   85     if (--string->s_refs < 1){
   86         free(string->s_ptr);
   87         free(string);
   88     }
   89 }
   90 
   91 /* Output a dc_str value.
   92  * Add a trailing newline if "newline" is set.
   93  * Free the value after use if discard_flag is set.
   94  */
   95 void
   96 dc_out_str DC_DECLARG((value, newline, discard_flag))
   97     dc_str value DC_DECLSEP
   98     dc_newline newline DC_DECLSEP
   99     dc_discard discard_flag DC_DECLEND
  100 {
  101     fwrite(value->s_ptr, value->s_len, sizeof *value->s_ptr, stdout);
  102     if (newline == DC_WITHNL)
  103         putchar('\n');
  104     if (discard_flag == DC_TOSS)
  105         dc_free_str(&value);
  106 }
  107 
  108 /* make a copy of a string (base s, length len)
  109  * into a dc_str value; return a dc_data result
  110  * with this value
  111  */
  112 dc_data
  113 dc_makestring DC_DECLARG((s, len))
  114     const char *s DC_DECLSEP
  115     size_t len DC_DECLEND
  116 {
  117     dc_data result;
  118     struct dc_string *string;
  119 
  120     string = dc_malloc(sizeof *string);
  121     string->s_ptr = dc_malloc(len+1);
  122     memcpy(string->s_ptr, s, len);
  123     string->s_ptr[len] = '\0';  /* nul terminated for those who need it */
  124     string->s_len = len;
  125     string->s_refs = 1;
  126     result.v.string = string;
  127     result.dc_type = DC_STRING;
  128     return result;
  129 }
  130 
  131 /* read a dc_str value from FILE *fp;
  132  * if ldelim == rdelim, then read until a ldelim char or EOF is reached;
  133  * if ldelim != rdelim, then read until a matching rdelim for the
  134  * (already eaten) first ldelim is read.
  135  * Return a dc_data result with the dc_str value as its contents.
  136  */
  137 dc_data
  138 dc_readstring DC_DECLARG((fp, ldelim, rdelim))
  139     FILE *fp DC_DECLSEP
  140     int ldelim DC_DECLSEP
  141     int rdelim DC_DECLEND
  142 {
  143     static char *line_buf = NULL;   /* a buffer to build the string in */ 
  144     static size_t buflen = 0;       /* the current size of line_buf */
  145     int depth=1;
  146     int c;
  147     char *p;
  148     const char *end;
  149 
  150     if (line_buf == NULL){
  151         /* initial buflen should be large enough to handle most cases */
  152         buflen = (size_t) 2016;
  153         line_buf = dc_malloc(buflen);
  154     }
  155     p = line_buf;
  156     end = line_buf + buflen;
  157     for (;;){
  158         c = getc(fp);
  159         if (c == EOF)
  160             break;
  161         else if (c == rdelim && --depth < 1)
  162             break;
  163         else if (c == ldelim)
  164             ++depth;
  165         if (p >= end){
  166             ptrdiff_t offset = p - line_buf;
  167             /* buflen increment should be big enough
  168              * to avoid execessive reallocs:
  169              */
  170             buflen += 2048;
  171             line_buf = realloc(line_buf, buflen);
  172             if (line_buf == NULL)
  173                 dc_memfail();
  174             p = line_buf + offset;
  175             end = line_buf + buflen;
  176         }
  177         *p++ = c;
  178     }
  179     return dc_makestring(line_buf, (size_t)(p-line_buf));
  180 }
  181 
  182 /* return the base pointer of the dc_str value;
  183  * This function is needed because no one else knows what dc_str
  184  * looks like.
  185  */
  186 const char *
  187 dc_str2charp DC_DECLARG((value))
  188     dc_str value DC_DECLEND
  189 {
  190     return value->s_ptr;
  191 }
  192 
  193 /* return the length of the dc_str value;
  194  * This function is needed because no one else knows what dc_str
  195  * looks like, and strlen(dc_str2charp(value)) won't work
  196  * if there's an embedded '\0'.
  197  */
  198 size_t
  199 dc_strlen DC_DECLARG((value))
  200     dc_str value DC_DECLEND
  201 {
  202     return value->s_len;
  203 }
  204 
  205 
  206 /* initialize the strings subsystem */
  207 void
  208 dc_string_init DC_DECLVOID()
  209 {
  210     /* nothing to do for this implementation */
  211 }
  212 
  213 
  214 /*
  215  * Local Variables:
  216  * mode: C
  217  * tab-width: 4
  218  * End:
  219  * vi: set ts=4 :
  220  */