1 /*
2  * $Id: line.c,v 1.6 2000/08/10 21:02:50 danny Exp $
3  *
4  * Copyright � 1990, 1992, 1993 Free Software Foundation, Inc.
5  *
6  * This file is part of Oleo, the GNU Spreadsheet.
7  *
8  * Oleo is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * Oleo is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Oleo; see the file COPYING.  If not, write to
20  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #ifdef	WITH_DMALLOC
27 #include <dmalloc.h>
28 #endif
29 
30 #include <stdio.h>
31 #include "global.h"
32 #include "line.h"
33 #include <stdarg.h>
34 
35 void
set_line(struct line * line,char * string)36 set_line (struct line *line, char *string)
37 {
38   int len;
39 
40   len = strlen (string);
41   if (line->alloc <= len)
42     {
43       if (len < LINE_MIN)
44 	len = LINE_MIN;
45       else
46 	len++;
47       line->alloc = len + 1;
48       if (line->buf)
49 	line->buf = ck_realloc (line->buf, line->alloc);
50       else
51 	line->buf = ck_malloc (line->alloc);
52     }
53   strcpy (line->buf, string);
54 }
55 
56 void
setn_line(struct line * line,char * string,int n)57 setn_line (struct line *line, char *string, int n)
58 {
59   int len = n;
60   if (line->alloc <= len)
61     {
62       if (len < LINE_MIN)
63 	len = LINE_MIN;
64       else
65 	len++;
66       line->alloc = len;
67       line->buf = ck_remalloc (line->buf, line->alloc);
68     }
69   bcopy (string, line->buf, n);
70   line->buf[n] = 0;
71 }
72 
73 #define Max(A,B)  ((A) > (B) ? (A) : (B))
74 
75 void
catn_line(struct line * line,char * string,int n)76 catn_line (struct line *line, char *string, int n)
77 {
78   int len = (line->buf ? strlen (line->buf) : 0);
79   if (line->alloc <= len + n + 1)
80     {
81       line->alloc = Max (len + n + 1, LINE_MIN);
82       line->buf = ck_remalloc (line->buf, line->alloc);
83     }
84   if (n)
85     bcopy (string, line->buf + len, n);
86   line->buf[len + n] = '\0';
87 }
88 
89 
90 void
sprint_line(struct line * line,char * fmt,...)91 sprint_line (struct line *line, char * fmt, ...)
92 {
93   va_list iggy;
94   int len;
95 
96   len = strlen (fmt) + 200;
97   if (!line->alloc)
98     {
99       line->buf = ck_malloc (len);
100       line->alloc = len;
101     }
102   else if (line->alloc < len)
103     {
104       line->buf = ck_realloc (line->buf, len);
105       line->alloc = len;
106     }
107   va_start (iggy, fmt);
108   vsprintf (line->buf, fmt, iggy);
109   va_end (iggy);
110 }
111 
112 void
splicen_line(struct line * line,char * str,int n,int pos)113 splicen_line (struct line * line, char * str, int n, int pos)
114 {
115   int old_len = strlen (line->buf);
116   int len = old_len + n;
117   if (line->alloc <= len)
118     {
119       line->alloc = len;
120       line->buf = ck_remalloc (line->buf, len + 1);
121     }
122   line->buf[len--] = '\0';
123   --old_len;
124   while (old_len >= pos)
125     {
126       line->buf[len] = line->buf[old_len];
127       --len;
128       --old_len;
129     }
130   while (n--)
131     line->buf[pos + n] = str[n];
132 }
133 
134 void
edit_line(struct line * line,int begin,int len)135 edit_line (struct line * line, int begin, int len)
136 {
137   int old_len = strlen (line->buf);
138   int new_len = old_len - len;
139   while (begin < new_len)
140     {
141       line->buf[begin] = line->buf[begin + len];
142       ++begin;
143     }
144   line->buf[begin] = '\0';
145 }
146 
147 
148 void
free_line(struct line * line)149 free_line (struct line * line)
150 {
151   if (line->buf && line->alloc)
152     free (line->buf);
153   line->buf = 0;
154   line->alloc = 0;
155 }
156 
157 
158 
159 
160 int
read_line(struct line * line,FILE * fp,int * linec)161 read_line (struct line * line, FILE * fp, int * linec)
162 {
163   int pos = 0;
164   int c = getc (fp);
165 
166   while ((c != EOF) && (c != '\n'))
167     {
168       if (pos + 2 >= line->alloc)
169 	{
170 	  line->alloc = (line->alloc ? line->alloc * 2 : 1);
171 	  line->buf = ck_remalloc (line->buf, line->alloc);
172 	}
173       if (c != '\\')
174 	line->buf[pos++] = c;
175       else
176 	{
177 	  int next_c = getc (fp);
178 	  if (next_c != '\n')
179 	    {
180 	      line->buf[pos++] = '\\';
181 	      line->buf[pos++] = next_c;
182 	    }
183 	  /* Else the backslash and newline are discarded from the input. */
184 	  else
185 	    ++*linec;
186 	}
187       c = getc (fp);
188     }
189   if (pos + 1 > line->alloc)
190     {
191       ++line->alloc;
192       line->buf = ck_remalloc (line->buf, line->alloc);
193     }
194   line->buf[pos] = 0;
195   if (line->buf[0] || (c != EOF))
196     {
197       ++*linec;
198       return 1;
199     }
200   else
201     return 0;
202 }
203