1/* sts.c -- Implementation File (module.c template V1.0)
2   Copyright (C) 1995 Free Software Foundation, Inc.
3   Contributed by James Craig Burley.
4
5This file is part of GNU Fortran.
6
7GNU Fortran is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Fortran is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Fortran; see the file COPYING.  If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.
21
22   Related Modules:
23      None (despite the name, it doesn't really depend on ffest*)
24
25   Description:
26      Provides an arbitrary-length string facility for the limited needs of
27      GNU Fortran FORMAT statement generation.
28
29   Modifications:
30*/
31
32/* Include files. */
33
34#include "proj.h"
35#include "sts.h"
36#include "com.h"
37#include "malloc.h"
38
39/* Externals defined here. */
40
41
42/* Simple definitions and enumerations. */
43
44
45/* Internal typedefs. */
46
47
48/* Private include files. */
49
50
51/* Internal structure definitions. */
52
53
54/* Static objects accessed by functions in this module. */
55
56
57/* Static functions (internal). */
58
59
60/* Internal macros. */
61
62
63/* ffests_kill -- Kill a varying-length string
64
65   ffests s;
66   ffests_kill(s);
67
68   The storage associated with the string <s> is freed.	 */
69
70void
71ffests_kill (ffests s)
72{
73  if (s->text_ != NULL)
74    malloc_kill_ksr (s->pool_, s->text_, s->max_);
75}
76
77/* ffests_new -- Make a varying-length string
78
79   ffests s;
80   ffests_new(s,malloc_pool_image(),0);
81
82   The string is initialized to hold, in this case, 0 characters, and
83   current and future heap manipulations to hold the string will use
84   the image pool.  */
85
86void
87ffests_new (ffests s, mallocPool pool, ffestsLength size)
88{
89  s->pool_ = pool;
90  s->len_ = 0;
91  s->max_ = size;
92
93  if (size == 0)
94    s->text_ = NULL;
95  else
96    s->text_ = malloc_new_ksr (pool, "ffests", size);
97}
98
99/* ffests_printf -- printf ("...%ld...",(long)) to a string
100
101   ffests s;
102   ffests_printf (s,"...%ld...",1);
103
104   Like printf, but into a string.  */
105
106void
107ffests_printf (ffests s, const char *ctl, ...)
108{
109  char *string;
110  va_list ap;
111
112  va_start (ap, ctl);
113  if (vasprintf (&string, ctl, ap) == 0)
114    abort ();
115  va_end (ap);
116  ffests_puts (s, string);
117  free (string);
118}
119
120/* ffests_putc -- Put a single character into string
121
122   ffests s;
123   ffests_putc(s,'*');	*/
124
125void
126ffests_putc (ffests s, char c)
127{
128  ffests_puttext (s, &c, 1);
129}
130
131/* ffests_puts -- Put a zero-terminated (C-style) string into string
132
133   ffests s;
134   ffests_puts(s,"append me");	*/
135
136void
137ffests_puts (ffests s, const char *string)
138{
139  ffests_puttext (s, string, strlen (string));
140}
141
142/* ffests_puttext -- Put a number of characters into string
143
144   ffests s;
145   ffests_puttext(s,"hi there",8);
146
147   The string need not be 0-terminated, because the passed length is used,
148   and may be 0.  */
149
150void
151ffests_puttext (ffests s, const char *text, ffestsLength length)
152{
153  ffestsLength newlen;
154  ffestsLength newmax;
155
156  if (length <= 0)
157    return;
158
159  newlen = s->len_ + length;
160  if (newlen > s->max_)
161    {
162      if (s->text_ == NULL)
163	{
164	  s->max_ = 40;
165	  s->text_ = malloc_new_ksr (s->pool_, "ffests", s->max_);
166	}
167      else
168	{
169	  newmax = s->max_ << 1;
170	  while (newmax < newlen)
171	    newmax <<= 1;
172	  s->text_ = malloc_resize_ksr (s->pool_, s->text_, newmax, s->max_);
173	  s->max_ = newmax;
174	}
175    }
176
177  memcpy (s->text_ + s->len_, text, length);
178  s->len_ = newlen;
179}
180