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