| /* sts.c -- Implementation File (module.c template V1.0) |
| Copyright (C) 1995 Free Software Foundation, Inc. |
| Contributed by James Craig Burley (burley@gnu.org). |
| |
| This file is part of GNU Fortran. |
| |
| GNU Fortran is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Fortran is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Fortran; see the file COPYING. If not, write to |
| the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA |
| 02111-1307, USA. |
| |
| Related Modules: |
| None (despite the name, it doesn't really depend on ffest*) |
| |
| Description: |
| Provides an arbitrary-length string facility for the limited needs of |
| GNU Fortran FORMAT statement generation. |
| |
| Modifications: |
| */ |
| |
| /* Include files. */ |
| |
| #include "proj.h" |
| #include "sts.h" |
| #include "com.h" |
| #include "malloc.h" |
| |
| /* Externals defined here. */ |
| |
| |
| /* Simple definitions and enumerations. */ |
| |
| |
| /* Internal typedefs. */ |
| |
| |
| /* Private include files. */ |
| |
| |
| /* Internal structure definitions. */ |
| |
| |
| /* Static objects accessed by functions in this module. */ |
| |
| |
| /* Static functions (internal). */ |
| |
| |
| /* Internal macros. */ |
| |
| |
| /* ffests_kill -- Kill a varying-length string |
| |
| ffests s; |
| ffests_kill(s); |
| |
| The storage associated with the string <s> is freed. */ |
| |
| void |
| ffests_kill (ffests s) |
| { |
| if (s->text_ != NULL) |
| malloc_kill_ksr (s->pool_, s->text_, s->max_); |
| } |
| |
| /* ffests_new -- Make a varying-length string |
| |
| ffests s; |
| ffests_new(s,malloc_pool_image(),0); |
| |
| The string is initialized to hold, in this case, 0 characters, and |
| current and future heap manipulations to hold the string will use |
| the image pool. */ |
| |
| void |
| ffests_new (ffests s, mallocPool pool, ffestsLength size) |
| { |
| s->pool_ = pool; |
| s->len_ = 0; |
| s->max_ = size; |
| |
| if (size == 0) |
| s->text_ = NULL; |
| else |
| s->text_ = malloc_new_ksr (pool, "ffests", size); |
| } |
| |
| /* ffests_printf_1D -- printf("...%ld...",(long)) to a string |
| |
| ffests s; |
| ffests_printf_1D(s,"...%ld...",1); |
| |
| Like printf, but into a string. */ |
| |
| void |
| ffests_printf_1D (ffests s, char *ctl, long arg1) |
| { |
| char quickbuf[40]; |
| char *buff; |
| ffestsLength len; |
| |
| if ((len = strlen (ctl) + 21) < ARRAY_SIZE (quickbuf)) |
| /* No # bigger than 20 digits. */ |
| { |
| sprintf (&quickbuf[0], ctl, arg1); |
| ffests_puttext (s, &quickbuf[0], strlen (quickbuf)); |
| } |
| else |
| { |
| buff = malloc_new_ks (malloc_pool_image (), "ffests_printf_1D", len); |
| sprintf (buff, ctl, arg1); |
| ffests_puttext (s, buff, strlen (buff)); |
| malloc_kill_ks (malloc_pool_image (), buff, len); |
| } |
| } |
| |
| /* ffests_printf_1U -- printf("...%lu...",(unsigned long)) to a string |
| |
| ffests s; |
| ffests_printf_1U(s,"...%lu...",1); |
| |
| Like printf, but into a string. */ |
| |
| void |
| ffests_printf_1U (ffests s, char *ctl, unsigned long arg1) |
| { |
| char quickbuf[40]; |
| char *buff; |
| ffestsLength len; |
| |
| if ((len = strlen (ctl) + 21) < ARRAY_SIZE (quickbuf)) |
| /* No # bigger than 20 digits. */ |
| { |
| sprintf (&quickbuf[0], ctl, arg1); |
| ffests_puttext (s, &quickbuf[0], strlen (quickbuf)); |
| } |
| else |
| { |
| buff = malloc_new_ks (malloc_pool_image (), "ffests_printf_1U", len); |
| sprintf (buff, ctl, arg1); |
| ffests_puttext (s, buff, strlen (buff)); |
| malloc_kill_ks (malloc_pool_image (), buff, len); |
| } |
| } |
| |
| /* ffests_printf_1s -- printf("...%s...",(char *)) to a string |
| |
| ffests s; |
| ffests_printf_1s(s,"...%s...","hi there!"); |
| |
| Like printf, but into a string. */ |
| |
| void |
| ffests_printf_1s (ffests s, char *ctl, char *arg1) |
| { |
| char quickbuf[40]; |
| char *buff; |
| ffestsLength len; |
| |
| if ((len = strlen (ctl) + strlen (arg1) - 1) < ARRAY_SIZE (quickbuf)) |
| { |
| sprintf (&quickbuf[0], ctl, arg1); |
| ffests_puttext (s, &quickbuf[0], strlen (quickbuf)); |
| } |
| else |
| { |
| buff = malloc_new_ks (malloc_pool_image (), "ffests_printf_1s", len); |
| sprintf (buff, ctl, arg1); |
| ffests_puttext (s, buff, strlen (buff)); |
| malloc_kill_ks (malloc_pool_image (), buff, len); |
| } |
| } |
| |
| /* ffests_printf_2Us -- printf("...%lu...%s...",...) to a string |
| |
| ffests s; |
| ffests_printf_2Us(s,"...%lu...%s...",1,"hi there!"); |
| |
| Like printf, but into a string. */ |
| |
| void |
| ffests_printf_2Us (ffests s, char *ctl, unsigned long arg1, char *arg2) |
| { |
| char quickbuf[60]; |
| char *buff; |
| ffestsLength len; |
| |
| if ((len = strlen (ctl) + 21 + strlen (arg2) - 1) < ARRAY_SIZE (quickbuf)) |
| /* No # bigger than 20 digits. */ |
| { |
| sprintf (&quickbuf[0], ctl, arg1, arg2); |
| ffests_puttext (s, &quickbuf[0], strlen (quickbuf)); |
| } |
| else |
| { |
| buff = malloc_new_ks (malloc_pool_image (), "ffests_printf_2Us", len); |
| sprintf (buff, ctl, arg1, arg2); |
| ffests_puttext (s, buff, strlen (buff)); |
| malloc_kill_ks (malloc_pool_image (), buff, len); |
| } |
| } |
| |
| /* ffests_putc -- Put a single character into string |
| |
| ffests s; |
| ffests_putc(s,'*'); */ |
| |
| void |
| ffests_putc (ffests s, char c) |
| { |
| ffests_puttext (s, &c, 1); |
| } |
| |
| /* ffests_puts -- Put a zero-terminated (C-style) string into string |
| |
| ffests s; |
| ffests_puts(s,"append me"); */ |
| |
| void |
| ffests_puts (ffests s, char *string) |
| { |
| ffests_puttext (s, string, strlen (string)); |
| } |
| |
| /* ffests_puttext -- Put a number of characters into string |
| |
| ffests s; |
| ffests_puttext(s,"hi there",8); |
| |
| The string need not be 0-terminated, because the passed length is used, |
| and may be 0. */ |
| |
| void |
| ffests_puttext (ffests s, char *text, ffestsLength length) |
| { |
| ffestsLength newlen; |
| ffestsLength newmax; |
| |
| if (length <= 0) |
| return; |
| |
| newlen = s->len_ + length; |
| if (newlen > s->max_) |
| { |
| if (s->text_ == NULL) |
| { |
| s->max_ = 40; |
| s->text_ = malloc_new_ksr (s->pool_, "ffests", s->max_); |
| } |
| else |
| { |
| newmax = s->max_ << 1; |
| while (newmax < newlen) |
| newmax <<= 1; |
| s->text_ = malloc_resize_ksr (s->pool_, s->text_, newmax, s->max_); |
| s->max_ = newmax; |
| } |
| } |
| |
| memcpy (s->text_ + s->len_, text, length); |
| s->len_ = newlen; |
| } |