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