1 /*
2  * $Id: sc.c,v 1.7 2000/08/10 21:02:51 danny Exp $
3  *
4  * Copyright � 1990, 1992, 1993, 1999 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 "io-utils.h"
40 #include "lists.h"
41 #include "ref.h"
42 #include "parse.h"
43 #include "regions.h"
44 #include "cmd.h"
45 
46 
47 
48 /* This reads/writes a subset of the SC public-domain spreadsheet's
49    file-format.  Note that since SC has no way of encoding some information
50    about a cell, writing a spread out in SC format, then reading it back in
51    will result in the loss of some information (most important:  cell formats)
52  */
53 
54 static int
get_range(pp,rp)55 get_range (pp,rp)
56      char ** pp;
57       struct rng * rp;
58 {
59 	int byte;
60 	char *p;
61 	struct var *v;
62 
63 
64 	while(isspace(**pp))
65 		(*pp)++;
66 	byte=parse_cell_or_range(pp,rp);
67 	if(byte)
68 		return 0;
69 	for(p= *pp;*p && !isspace(*p);p++)
70 		;
71 	v=find_var(*pp,p-*pp);
72 	if(!v)
73 		return 1;
74 	*pp=p;
75 	*rp=v->v_rng;
76 	return 0;
77 }
78 
79 void
sc_read_file(fp,ismerge)80 sc_read_file (fp,ismerge)
81      FILE * fp;
82       int ismerge;
83 {
84 	char buf[2048];
85 	int lineno;
86 	char *ptr;
87 	int n;
88 	struct rng rng;
89 	int olda0;
90 
91 	olda0=Global->a0;
92 	Global->a0=1;
93 	lineno=0;
94 	if(!ismerge)
95 		clear_spreadsheet();
96 	while(fgets(buf,sizeof(buf),fp)) {
97 		lineno++;
98 #if 0
99 		if(lineno%50==0)
100 			io_info_msg("Line %d",lineno);
101 #endif
102 		if(buf[0]=='#' || buf[0]=='\n')
103 			continue;
104 		if(!strncmp(buf,"set ",4)) {
105 			/* ... */
106 		} else if(!strncmp(buf,"format ",7)) {
107 			ptr=buf+7;
108 			if(get_range(&ptr,&rng))
109 				continue;
110 			n=astol(&ptr);
111 			set_width(rng.lc,n);
112 		} else if(!strncmp(buf,"hide ",5)) {
113 			ptr=buf+5;
114 			if(get_range(&ptr,&rng))
115 				continue;
116 			set_width(rng.lc,0);
117 		} else if(!strncmp(buf,"mdir ",5)) {
118 			/* ... */
119 		} else if(!strncmp(buf,"define ",7)) {
120 			char *eptr;
121 
122 			ptr=buf+7;
123 			while(isspace(*ptr))
124 				ptr++;
125 			if(*ptr!='"') {
126 				io_error_msg("Line %d: No starting \" in define",lineno);
127 				continue;
128 			}
129 			ptr++;
130 			for(eptr=ptr; *eptr && *eptr!='"';eptr++)
131 				;
132 			if(!*eptr) {
133 				io_error_msg("Line %d: No starting \" in define",lineno);
134 				continue;
135 			}
136 			ptr = old_new_var_value(ptr,eptr-ptr,eptr+1);
137 			if(ptr)
138 				io_error_msg("Line %d: %s",ptr);
139 		} else if(!strncmp(buf,"leftstring ",11) ||
140 			  !strncmp(buf,"rightstring ",12)) {
141 			CELL *cp;
142 
143 			ptr=buf+11;
144 			if(get_range(&ptr,&rng))
145 				continue;
146 			while(isspace(*ptr))
147 				ptr++;
148 			if(*ptr=='=')
149 				ptr++;
150 			new_value(rng.lr,rng.lc,ptr);
151 			cp=find_cell(rng.lr,rng.lc);
152 			if(buf[0]=='l')
153 				SET_JST(cp,JST_LFT);
154 			else
155 				SET_JST(cp,JST_RGT);
156 
157 		} else if(!strncmp(buf,"let ",4)) {
158 			ptr=buf+4;
159 			if(get_range(&ptr,&rng))
160 				continue;
161 			while(isspace(*ptr))
162 				ptr++;
163 			if(*ptr=='=')
164 				ptr++;
165 			new_value(rng.lr,rng.lc,ptr);
166 		} else
167 			io_error_msg("Line %d: Can't parse %s",lineno,buf);
168 	}
169 	Global->a0=olda0;
170 	io_recenter_all_win();
171 }
172 
173 static FILE *sc_fp;
174 static struct rng *sc_rng;
175 static void
sc_write_var(name,var)176 sc_write_var (name,var)
177      char * name;
178       struct var * var;
179 {
180 	if(var->var_flags==VAR_UNDEF && (!var->var_ref_fm || var->var_ref_fm->refs_used==0))
181 		return;
182 	switch(var->var_flags) {
183 	case VAR_UNDEF:
184 		break;
185 	case VAR_CELL:
186 		if(var->v_rng.lr>=sc_rng->lr && var->v_rng.lr<=sc_rng->hr && var->v_rng.lc>=sc_rng->lc && var->v_rng.lc<=sc_rng->hc)
187 			(void)fprintf(sc_fp,"define \"%s\" %s\n",var->var_name,cell_name(var->v_rng.lr,var->v_rng.lc));
188 		break;
189 	case VAR_RANGE:
190 		if(var->v_rng.lr<sc_rng->lr || var->v_rng.hr>sc_rng->hr || var->v_rng.lc<sc_rng->lc || var->v_rng.hc>sc_rng->hc)
191 			break;
192 
193 		(void)fprintf(sc_fp,"define \"%s\" %s\n",var->var_name,range_name(&(var->v_rng)));
194 		break;
195 #ifdef TEST
196 	default:
197 		panic("Unknown var type %d",var->var_flags);
198 		break;
199 #endif
200 	}
201 }
202 
203 void
sc_write_file(fp,rng)204 sc_write_file (fp,rng)
205      FILE * fp;
206       struct rng * rng;
207 {
208 	unsigned short w;
209 	CELLREF r,c;
210 	CELL *cp;
211 	char *ptr;
212 	int olda0;
213 
214 	if(!rng)
215 		rng= &all_rng;
216 
217 	olda0=Global->a0;
218 	Global->a0=1;
219 	(void)fprintf(fp,"# This file was created by Oleo, for use by the Spreadsheet Calculator\n");
220 	(void)fprintf(fp,"# You probably don't want to edit it.\n\n");
221 
222 	find_widths(rng->lc,rng->hc);
223 	while((w=next_width(&c)))
224 		fprintf(fp,"format %s %d ???\n",cell_name(MIN_ROW,c),w);
225 	sc_fp=fp;
226 	sc_rng=rng;
227 	for_all_vars(sc_write_var);
228 	find_cells_in_range(rng);
229 	while((cp=next_row_col_in_range(&r,&c))) {
230 		switch(GET_TYP(cp)) {
231 		case TYP_STR:
232 			if((GET_JST(cp)==JST_DEF && default_jst==JST_RGT) || GET_JST(cp)==JST_RGT)
233 				ptr="right";
234 			else ptr="left";
235 			fprintf(fp,"%sstring %s = %s\n",ptr,cell_name(r,c),decomp(r,c,cp));
236 			decomp_free();
237 			break;
238 		case 0:
239 			break;
240 		default:
241 			fprintf(fp,"let %s = %s\n",cell_name(r,c),decomp(r,c,cp));
242 			decomp_free();
243 			break;
244 		}
245 	}
246 	Global->a0=olda0;
247 }
248 
249 int
sc_set_options(set_opt,option)250 sc_set_options (set_opt,option)
251      int set_opt;
252       char * option;
253 {
254 	return -1;
255 }
256 
257 void
sc_show_options()258 sc_show_options ()
259 {
260 	io_text_line("File format: sc  (Public domain spreadsheet calculator)");
261 }
262