1 /* dstring.c - The dynamic string handling routines used by cpio.
2    Copyright (C) 1990-1992, 2004, 2007, 2010, 2014-2015, 2017 Free
3    Software Foundation, Inc.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3, or (at your option)
8    any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public
16    License along with this program; if not, write to the Free
17    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18    Boston, MA 02110-1301 USA.  */
19 
20 #if defined(HAVE_CONFIG_H)
21 # include <config.h>
22 #endif
23 
24 #include <stdio.h>
25 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
26 #include <string.h>
27 #else
28 #include <strings.h>
29 #endif
30 #include "dstring.h"
31 #include <xalloc.h>
32 
33 /* Initialiaze dynamic string STRING with space for SIZE characters.  */
34 
35 void
ds_init(dynamic_string * string,int size)36 ds_init (dynamic_string *string, int size)
37 {
38   string->ds_length = size;
39   string->ds_string = (char *) xmalloc (size);
40 }
41 
42 /* Expand dynamic string STRING, if necessary, to hold SIZE characters.  */
43 
44 void
ds_resize(dynamic_string * string,int size)45 ds_resize (dynamic_string *string, int size)
46 {
47   if (size > string->ds_length)
48     {
49       string->ds_length = size;
50       string->ds_string = (char *) xrealloc ((char *) string->ds_string, size);
51     }
52 }
53 
54 /* Dynamic string S gets a string terminated by the EOS character
55    (which is removed) from file F.  S will increase
56    in size during the function if the string from F is longer than
57    the current size of S.
58    Return NULL if end of file is detected.  Otherwise,
59    Return a pointer to the null-terminated string in S.  */
60 
61 char *
ds_fgetstr(FILE * f,dynamic_string * s,char eos)62 ds_fgetstr (FILE *f, dynamic_string *s, char eos)
63 {
64   int insize;			/* Amount needed for line.  */
65   int strsize;			/* Amount allocated for S.  */
66   int next_ch;
67 
68   /* Initialize.  */
69   insize = 0;
70   strsize = s->ds_length;
71 
72   /* Read the input string.  */
73   next_ch = getc (f);
74   while (next_ch != eos && next_ch != EOF)
75     {
76       if (insize >= strsize - 1)
77 	{
78 	  ds_resize (s, strsize * 2 + 2);
79 	  strsize = s->ds_length;
80 	}
81       s->ds_string[insize++] = next_ch;
82       next_ch = getc (f);
83     }
84   s->ds_string[insize++] = '\0';
85 
86   if (insize == 1 && next_ch == EOF)
87     return NULL;
88   else
89     return s->ds_string;
90 }
91 
92 char *
ds_fgets(FILE * f,dynamic_string * s)93 ds_fgets (FILE *f, dynamic_string *s)
94 {
95   return ds_fgetstr (f, s, '\n');
96 }
97 
98 char *
ds_fgetname(FILE * f,dynamic_string * s)99 ds_fgetname (FILE *f, dynamic_string *s)
100 {
101   return ds_fgetstr (f, s, '\0');
102 }
103