1 /*
2 * $Id: list.c,v 1.13 2000/11/22 19:33:01 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
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #ifdef WITH_DMALLOC
28 #include <dmalloc.h>
29 #endif
30
31 #include "funcdef.h"
32 #include <stdio.h>
33 #include <ctype.h>
34 #include "sysdef.h"
35 #include "global.h"
36 #include "cell.h"
37 #include "io-generic.h"
38 #include "io-abstract.h"
39 #include "regions.h"
40 #include "io-utils.h"
41 #include "cmd.h"
42
43 /* This file reads/writes files containing values in separated lists,
44 sl_sep is the separating character. This isn't really a save-file
45 format, but it is useful for reading and writing tables written by other
46 programs.
47
48 Note that this format loses *most* of the information about the cells,
49 including formulae, formats, column widths, etc
50 */
51 void
list_read_file(fp,ismerge)52 list_read_file (fp, ismerge)
53 FILE *fp;
54 int ismerge;
55 {
56 char cbuf[1024];
57 CELLREF row, col;
58 char *bptr;
59 char *eptr;
60 char *ptr;
61 char tchar;
62 int endit;
63 unsigned lineno;
64 int string, dosstyle = 0;
65
66 lineno = 0;
67 if (!ismerge)
68 clear_spreadsheet ();
69 row = curow;
70 col = cucol;
71
72 while (fgets (&cbuf[1], sizeof (cbuf) - 3, fp))
73 {
74 lineno++;
75
76 /* Remove DOS style CR when present */
77 ptr = strchr(cbuf, '\r');
78 if (ptr) {
79 *ptr = '\n';
80
81 if (*(ptr+1) == '\n') { /* This is good */
82 if (! dosstyle)
83 io_info_msg("Discarding <CR> (DOS line end) in input file\n");
84 dosstyle = 1;
85 } else {
86 /* This isn't; FIX ME */
87 io_info_msg("Discard <CR> (DOS line end) at line %d, "
88 "this discards some input !\n", lineno);
89 }
90 }
91
92 #if 0
93 /* Be loud after every 50 line read. Useless. */
94 if (lineno % 50 == 0)
95 io_info_msg ("Line %d", lineno);
96 #endif
97
98 endit = 0;
99 for (bptr = &cbuf[1];; bptr = eptr + 1)
100 {
101 eptr = (char *)index (bptr, Global->sl_sep);
102 if (!eptr)
103 {
104 eptr = (char *)index (bptr, '\n');
105 endit++;
106 }
107 string = 0;
108 for (ptr = bptr; ptr != eptr; ptr++)
109 if (!isdigit (*ptr) && *ptr != '.' && *ptr != 'e' && *ptr != 'E'
110 && *ptr != '+' && *ptr != '-')
111 {
112 string++;
113 break;
114 }
115 if (string)
116 {
117 if (bptr[0] == '"') {
118 /* Code to deal with "xxx" fields */
119 char *p = strchr(&bptr[1], '"');
120 if (p) {
121 p++;
122 tchar = *p;
123 *p = '\0';
124 new_value (row, col, &bptr[0]);
125 *p = tchar;
126 } else {
127 bptr[-1] = '"';
128 eptr[0] = '"';
129 tchar = eptr[1];
130 eptr[1] = '\0';
131 new_value (row, col, &bptr[-1]);
132 eptr[1] = tchar;
133 }
134 } else if (eptr) {
135 bptr[-1] = '"';
136 eptr[0] = '"';
137 tchar = eptr[1];
138 eptr[1] = '\0';
139 new_value (row, col, &bptr[-1]);
140 eptr[1] = tchar;
141 } else {
142 /* ??? FIX ME */
143 }
144 }
145 else
146 {
147 eptr[0] = '\0';
148 new_value (row, col, bptr);
149 }
150 if (endit)
151 break;
152 col++;
153 }
154 row++;
155 col = cucol;
156 }
157 }
158
159 void
list_write_file(fp,rng)160 list_write_file (fp, rng)
161 FILE *fp;
162 struct rng *rng;
163 {
164 CELLREF row, col;
165 CELLREF rMax, cMax;
166 int repressed;
167 CELL *cp;
168
169 if (!rng)
170 rng = &all_rng;
171 rMax = rng->lr;
172 cMax = rng->lc;
173 find_cells_in_range (rng);
174 while ((cp = next_row_col_in_range (&row, &col))) {
175 if (row > rMax) rMax = row;
176 if (col > cMax) cMax = col;
177 }
178 for (row = rng->lr;; row++)
179 {
180 repressed = 0;
181 for (col = rng->lc;; col++)
182 {
183 if ((cp = find_cell (row, col)) && GET_TYP (cp))
184 {
185 while (repressed > 0)
186 {
187 putc (Global->sl_sep, fp);
188 --repressed;
189 }
190 repressed = 1;
191 switch (GET_TYP (cp))
192 {
193 case TYP_FLT:
194 fputs (flt_to_str (cp->cell_flt), fp);
195 break;
196 case TYP_INT:
197 fprintf (fp, "%ld", cp->cell_int);
198 break;
199 case TYP_STR:
200 fputs (cp->cell_str, fp);
201 break;
202 case TYP_BOL:
203 fputs (bname[cp->cell_bol], fp);
204 break;
205 case TYP_ERR:
206 fputs (ename[cp->cell_err], fp);
207 break;
208 #ifdef TEST
209 default:
210 panic ("Unknown type %d in write_sl_file()", GET_TYP (cp));
211 break;
212 #endif
213 }
214 }
215 else
216 repressed++;
217 if (col == cMax)
218 break;
219 }
220 putc ('\n', fp);
221 if (row == rMax)
222 break;
223 }
224 }
225
226 int
list_set_options(set_opt,option)227 list_set_options (set_opt, option)
228 int set_opt;
229 char *option;
230 {
231 if (set_opt && !strincmp (option, "list ", 5))
232 {
233 option += 5;
234 Global->sl_sep = string_to_char (&option);
235 return 0;
236 }
237 return -1;
238 }
239
list_set_separator(char sep)240 void list_set_separator(char sep)
241 {
242 Global->sl_sep = sep;
243 }
244
list_get_separator(void)245 char list_get_separator(void)
246 {
247 return Global->sl_sep;
248 }
249
250 void
list_show_options()251 list_show_options ()
252 {
253 io_text_line ("File format: list (character separated list of cell values)");
254 io_text_line ("Save file element separator: %s", char_to_string (Global->sl_sep));
255 }
256