2 * implement string functions for dc
4 * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc.
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)
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.
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:
20 * The Free Software Foundation, Inc.
21 * 59 Temple Place, Suite 330
22 * Boston, MA 02111 USA
25 /* This should be the only module that knows the internals of type dc_string */
31 # include <stddef.h> /* ptrdiff_t */
33 # define ptrdiff_t size_t
39 # include <string.h> /* memcpy */
42 # include <memory.h> /* memcpy, maybe */
44 # ifdef HAVE_STRINGS_H
45 # include <strings.h> /* memcpy, maybe */
52 /* here is the completion of the dc_string type: */
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 */
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.
67 dc_dup_str
DC_DECLARG((value
))
68 dc_str value DC_DECLEND
73 result
.v
.string
= value
;
74 result
.dc_type
= DC_STRING
;
78 /* free an instance of a dc_str value */
80 dc_free_str
DC_DECLARG((value
))
81 dc_str
*value DC_DECLEND
83 struct dc_string
*string
= *value
;
85 if (--string
->s_refs
< 1){
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.
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
101 fwrite(value
->s_ptr
, value
->s_len
, sizeof *value
->s_ptr
, stdout
);
102 if (newline
== DC_WITHNL
)
104 if (discard_flag
== DC_TOSS
)
108 /* make a copy of a string (base s, length len)
109 * into a dc_str value; return a dc_data result
113 dc_makestring
DC_DECLARG((s
, len
))
114 const char *s DC_DECLSEP
115 size_t len DC_DECLEND
118 struct dc_string
*string
;
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 */
126 result
.v
.string
= string
;
127 result
.dc_type
= DC_STRING
;
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.
138 dc_readstring
DC_DECLARG((fp
, ldelim
, rdelim
))
140 int ldelim DC_DECLSEP
141 int rdelim DC_DECLEND
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 */
151 /* initial buflen should be large enough to handle most cases */
153 line_buf
= dc_malloc(buflen
);
156 end
= line_buf
+ buflen
;
161 else if (c
== rdelim
&& --depth
< 1)
163 else if (c
== ldelim
)
166 ptrdiff_t offset
= p
- line_buf
;
167 /* buflen increment should be big enough
168 * to avoid execessive reallocs:
171 line_buf
= realloc(line_buf
, buflen
);
174 p
= line_buf
+ offset
;
175 end
= line_buf
+ buflen
;
179 return dc_makestring(line_buf
, (size_t)(p
-line_buf
));
182 /* return the base pointer of the dc_str value;
183 * This function is needed because no one else knows what dc_str
187 dc_str2charp
DC_DECLARG((value
))
188 dc_str value DC_DECLEND
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'.
199 dc_strlen
DC_DECLARG((value
))
200 dc_str value DC_DECLEND
206 /* initialize the strings subsystem */
208 dc_string_init
DC_DECLVOID()
210 /* nothing to do for this implementation */