Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / flex / dist / buf.c
blobd4d68bcbdbafdcd6bff92d460c18f19912ae85d8
1 /* $NetBSD$ */
3 /* flex - tool to generate fast lexical analyzers */
5 /* Copyright (c) 1990 The Regents of the University of California. */
6 /* All rights reserved. */
8 /* This code is derived from software contributed to Berkeley by */
9 /* Vern Paxson. */
11 /* The United States Government has rights in this work pursuant */
12 /* to contract no. DE-AC03-76SF00098 between the United States */
13 /* Department of Energy and the University of California. */
15 /* This file is part of flex. */
17 /* Redistribution and use in source and binary forms, with or without */
18 /* modification, are permitted provided that the following conditions */
19 /* are met: */
21 /* 1. Redistributions of source code must retain the above copyright */
22 /* notice, this list of conditions and the following disclaimer. */
23 /* 2. Redistributions in binary form must reproduce the above copyright */
24 /* notice, this list of conditions and the following disclaimer in the */
25 /* documentation and/or other materials provided with the distribution. */
27 /* Neither the name of the University nor the names of its contributors */
28 /* may be used to endorse or promote products derived from this software */
29 /* without specific prior written permission. */
31 /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
32 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
33 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
34 /* PURPOSE. */
36 #include "flexdef.h"
38 /* Take note: The buffer object is sometimes used as a String buffer (one
39 * continuous string), and sometimes used as a list of strings, usually line by
40 * line.
42 * The type is specified in buf_init by the elt_size. If the elt_size is
43 * sizeof(char), then the buffer should be treated as string buffer. If the
44 * elt_size is sizeof(char*), then the buffer should be treated as a list of
45 * strings.
47 * Certain functions are only appropriate for one type or the other.
50 /* global buffers. */
51 struct Buf userdef_buf; /**< for user #definitions triggered by cmd-line. */
52 struct Buf defs_buf; /**< for #define's autogenerated. List of strings. */
53 struct Buf yydmap_buf; /**< string buffer to hold yydmap elements */
54 struct Buf m4defs_buf; /**< m4 definitions. List of strings. */
55 struct Buf top_buf; /**< contains %top code. String buffer. */
57 struct Buf *buf_print_strings(struct Buf * buf, FILE* out)
59 int i;
61 if(!buf || !out)
62 return buf;
64 for (i=0; i < buf->nelts; i++){
65 const char * s = ((char**)buf->elts)[i];
66 if(s)
67 fprintf(out, "%s", s);
69 return buf;
72 /* Append a "%s" formatted string to a string buffer */
73 struct Buf *buf_prints (struct Buf *buf, const char *fmt, const char *s)
75 char *t;
76 size_t tsz;
78 t = flex_alloc (tsz = strlen (fmt) + strlen (s) + 1);
79 snprintf (t, tsz, fmt, s);
80 buf = buf_strappend (buf, t);
81 flex_free (t);
82 return buf;
85 /** Append a line directive to the string buffer.
86 * @param buf A string buffer.
87 * @param filename file name
88 * @param lineno line number
89 * @return buf
91 struct Buf *buf_linedir (struct Buf *buf, const char* filename, int lineno)
93 char *t, *fmt = "#line %d \"%s\"\n";
94 size_t tsz;
96 t = flex_alloc (tsz = strlen (fmt) + strlen (filename) + (int)(1 + log10(lineno>=0?lineno:-lineno)) + 1);
97 snprintf (t, tsz, fmt, lineno, filename);
98 buf = buf_strappend (buf, t);
99 flex_free (t);
100 return buf;
104 /** Append the contents of @a src to @a dest.
105 * @param @a dest the destination buffer
106 * @param @a dest the source buffer
107 * @return @a dest
109 struct Buf *buf_concat(struct Buf* dest, const struct Buf* src)
111 buf_append(dest, src->elts, src->nelts);
112 return dest;
116 /* Appends n characters in str to buf. */
117 struct Buf *buf_strnappend (buf, str, n)
118 struct Buf *buf;
119 const char *str;
120 int n;
122 buf_append (buf, str, n + 1);
124 /* "undo" the '\0' character that buf_append() already copied. */
125 buf->nelts--;
127 return buf;
130 /* Appends characters in str to buf. */
131 struct Buf *buf_strappend (buf, str)
132 struct Buf *buf;
133 const char *str;
135 return buf_strnappend (buf, str, strlen (str));
138 /* appends "#define str def\n" */
139 struct Buf *buf_strdefine (buf, str, def)
140 struct Buf *buf;
141 const char *str;
142 const char *def;
144 buf_strappend (buf, "#define ");
145 buf_strappend (buf, " ");
146 buf_strappend (buf, str);
147 buf_strappend (buf, " ");
148 buf_strappend (buf, def);
149 buf_strappend (buf, "\n");
150 return buf;
153 /** Pushes "m4_define( [[def]], [[val]])m4_dnl" to end of buffer.
154 * @param buf A buffer as a list of strings.
155 * @param def The m4 symbol to define.
156 * @param val The definition; may be NULL.
157 * @return buf
159 struct Buf *buf_m4_define (struct Buf *buf, const char* def, const char* val)
161 const char * fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n";
162 char * str;
163 size_t strsz;
165 val = val?val:"";
166 str = (char*)flex_alloc(strsz = strlen(fmt) + strlen(def) + strlen(val) + 2);
168 snprintf(str, strsz, fmt, def, val);
169 buf_append(buf, &str, 1);
170 return buf;
173 /** Pushes "m4_undefine([[def]])m4_dnl" to end of buffer.
174 * @param buf A buffer as a list of strings.
175 * @param def The m4 symbol to undefine.
176 * @return buf
178 struct Buf *buf_m4_undefine (struct Buf *buf, const char* def)
180 const char * fmt = "m4_undefine( [[%s]])m4_dnl\n";
181 char * str;
182 size_t strsz;
184 str = (char*)flex_alloc(strsz = strlen(fmt) + strlen(def) + 2);
186 snprintf(str, strsz, fmt, def);
187 buf_append(buf, &str, 1);
188 return buf;
191 /* create buf with 0 elements, each of size elem_size. */
192 void buf_init (buf, elem_size)
193 struct Buf *buf;
194 size_t elem_size;
196 buf->elts = (void *) 0;
197 buf->nelts = 0;
198 buf->elt_size = elem_size;
199 buf->nmax = 0;
202 /* frees memory */
203 void buf_destroy (buf)
204 struct Buf *buf;
206 if (buf && buf->elts)
207 flex_free (buf->elts);
208 buf->elts = (void *) 0;
212 /* appends ptr[] to buf, grow if necessary.
213 * n_elem is number of elements in ptr[], NOT bytes.
214 * returns buf.
215 * We grow by mod(512) boundaries.
218 struct Buf *buf_append (buf, ptr, n_elem)
219 struct Buf *buf;
220 const void *ptr;
221 int n_elem;
223 int n_alloc = 0;
225 if (!ptr || n_elem == 0)
226 return buf;
228 /* May need to alloc more. */
229 if (n_elem + buf->nelts > buf->nmax) {
231 /* exact amount needed... */
232 n_alloc = (n_elem + buf->nelts) * buf->elt_size;
234 /* ...plus some extra */
235 if (((n_alloc * buf->elt_size) % 512) != 0
236 && buf->elt_size < 512)
237 n_alloc +=
238 (512 -
239 ((n_alloc * buf->elt_size) % 512)) /
240 buf->elt_size;
242 if (!buf->elts)
243 buf->elts =
244 allocate_array (n_alloc, buf->elt_size);
245 else
246 buf->elts =
247 reallocate_array (buf->elts, n_alloc,
248 buf->elt_size);
250 buf->nmax = n_alloc;
253 memcpy ((char *) buf->elts + buf->nelts * buf->elt_size, ptr,
254 n_elem * buf->elt_size);
255 buf->nelts += n_elem;
257 return buf;
260 /* vim:set tabstop=8 softtabstop=4 shiftwidth=4: */