1/* ugtlin.c
2   Read a line with backslash continuations.
3
4   Copyright (C) 1992, 2002 Ian Lance Taylor
5
6   This file is part of the Taylor UUCP uuconf library.
7
8   This library is free software; you can redistribute it and/or
9   modify it under the terms of the GNU Library General Public License
10   as published by the Free Software Foundation; either version 2 of
11   the License, or (at your option) any later version.
12
13   This library is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   Library General Public License for more details.
17
18   You should have received a copy of the GNU Library General Public
19   License along with this library; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
21
22   The author of the program may be contacted at ian@airs.com.
23   */
24
25#include "uucnfi.h"
26
27#if USE_RCS_ID
28const char _uuconf_ugtlin_rcsid[] = "$Id: ugtlin.c,v 1.9 2002/03/05 19:10:43 ian Rel $";
29#endif
30
31/* Read a line from a file with backslash continuations.  This updates
32   the qglobal->ilineno count for each additional line it reads.  */
33
34int
35_uuconf_getline (qglobal, pzline, pcline, e)
36     struct sglobal *qglobal;
37     char **pzline;
38     size_t *pcline;
39     FILE *e;
40{
41  int ctot;
42  char *zline;
43  size_t cline;
44
45  ctot = -1;
46
47  zline = NULL;
48  cline = 0;
49
50  while (TRUE)
51    {
52      int cchars;
53
54      if (ctot < 0)
55	cchars = getline (pzline, pcline, e);
56      else
57	cchars = getline (&zline, &cline, e);
58      if (cchars < 0)
59	{
60	  if (zline != NULL)
61	    free ((pointer) zline);
62	  if (ctot >= 0)
63	    return ctot;
64	  else
65	    return cchars;
66	}
67
68      if (ctot < 0)
69	ctot = cchars;
70      else
71	{
72	  if (*pcline <= (size_t) (ctot + cchars))
73	    {
74	      char *znew;
75
76	      if (*pcline > 0)
77		znew = (char *) realloc ((pointer) *pzline,
78					 (size_t) (ctot + cchars + 1));
79	      else
80		znew = (char *) malloc ((size_t) (ctot + cchars + 1));
81	      if (znew == NULL)
82		{
83		  free ((pointer) zline);
84		  return -1;
85		}
86	      *pzline = znew;
87	      *pcline = ctot + cchars + 1;
88	    }
89
90	  memcpy ((pointer) ((*pzline) + ctot), (pointer) zline,
91		  (size_t) (cchars + 1));
92	  ctot += cchars;
93	}
94
95      if (ctot < 2
96	  || (*pzline)[ctot - 1] != '\n'
97	  || (*pzline)[ctot - 2] != '\\')
98	{
99	  if (zline != NULL)
100	    free ((pointer) zline);
101	  return ctot;
102	}
103
104      ++qglobal->ilineno;
105
106      ctot -= 2;
107      (*pzline)[ctot] = '\0';
108    }
109}
110