home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1990 Free Software Foundation, Inc.
-
- This file is part of Oleo, the GNU Spreadsheet.
-
- Oleo is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- Oleo is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Oleo; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "funcdef.h"
- #include <stdio.h>
- #include "sysdef.h"
-
- #ifdef TEST
- extern void panic EXT1N(const char *);
- #endif
-
- #include "global.h"
- #include "cell.h"
-
- extern long astol EXT1(char **);
-
- extern void set_width EXT2(CELLREF, unsigned short);
- extern unsigned short next_widths EXT2(CELLREF *,CELLREF *);
-
- extern CELLREF highest_row EXT0();
- extern CELLREF highest_col EXT0();
-
- extern void write_mp_usr_fmt EXT1(FILE *);
-
- extern void read_mp_options EXT1(char *);
- extern void write_mp_options EXT1(FILE *);
-
- extern void read_mp_windows EXT1(char *);
- extern void write_mp_windows EXT1(FILE *);
-
- extern void clear_spreadsheet EXT0();
-
- extern char *new_var_value EXT3(char *, int, char *);
-
- extern char *read_new_value EXT4(CELLREF, CELLREF, char *, char *);
-
- extern void push_cell EXT2(CELLREF, CELLREF);
-
- extern char *flt_to_str EXT1(double);
-
- extern char *cell_name EXT2(CELLREF, CELLREF);
- extern char *range_name EXT1(struct rng *);
-
- extern char *bname[];
- extern default_jst;
- extern default_fmt;
- extern default_lock;
- extern unsigned short default_width;
-
- extern struct rng all_rng;
-
- static void read_mp_usr_fmt EXT1(char *);
-
- /* These functions read and write Microsoft Multiplan SYLK style files.
- They documented their file format, and I just happened to have a file or two
- in that format floating around, so. . .
-
- Unfortunatly, it is quite slow to read/write.
- */
- void
- sylk_read_file FUN2(FILE *, fp, int,ismerge)
- {
- char *ptr;
- CELLREF crow=0,ccol=0,czrow=0,czcol=0;
- int lineno;
- char cbuf[1024];
- char expbuf[1024];
- char *vname,*vval;
- int vlen = 0;
- int cprot;
- char *cexp,*cval;
- CELL *cp;
- struct rng rng;
- int fmt = 0;
- int jst = 0;
- long mx_row =MAX_ROW, mx_col = MAX_COL;
-
- lineno=0;
- if(!ismerge)
- clear_spreadsheet();
- while(fgets(cbuf,sizeof(cbuf),fp)) {
- lineno++;
- if(lineno%50==0)
- info_msg("Line %d",lineno);
- if(ptr=index(cbuf,'\n'))
- *ptr='\0';
- ptr=cbuf;
- switch(*ptr) {
- case 'I': /* ID field, ignored */
- if(ptr[1]!='D' || ptr[2]!=';')
- goto bad_field;
- break;
- case 'F': /* Format field */
- vlen=0;
- ptr++;
- while(*ptr) {
- if(*ptr!=';')
- goto bad_field;
- ptr++;
- switch(*ptr++) {
- int clo,chi,cwid;
- case 'C': /* Column from rows 1 to 255 */
- czcol=astol(&ptr);
- vlen=2;
- break;
-
- case 'D': /* Default format */
- switch(*ptr++) {
- case 'G':
- default_fmt=FMT_GEN-PRC_FLT;
- break;
- case 'E':
- default_fmt=FMT_EXP-PRC_FLT;
- break;
- case 'F':
- default_fmt=FMT_FXT-PRC_FLT;
- break;
- case '$':
- default_fmt=FMT_DOL-PRC_FLT;
- break;
- case '*': /* * format implemented as +- format */
- default_fmt=FMT_GPH;
- break;
- case ',': /* JF */
- default_fmt=FMT_CMA-PRC_FLT;
- break;
- case 'U':
- default_fmt=FMT_USR-PRC_FLT;
- break;
- case '%':
- default_fmt=FMT_PCT-PRC_FLT;
- break;
- case 'H':
- default_fmt=FMT_HID;
- break;
- /* End of JF */
- case 'C': /* Continuous not supported */
- default:
- error_msg("Line %d: format %c not supported",lineno,ptr[-1]);
- break;
- }
- if(*ptr=='F') {
- default_fmt+=PRC_FLT;
- ptr++;
- } else
- default_fmt+=astol(&ptr);
- switch(*ptr++) {
- case 'C':
- default_jst=JST_CNT;
- break;
- case 'L':
- default_jst=JST_LFT;
- break;
- case 'R':
- default_jst=JST_RGT;
- break;
- case 'G': /* General format not supported */
- default:
- error_msg("Line %d: Alignment %c not supported",lineno,ptr[-1]);
- break;
- }
- default_width=astol(&ptr);
- break;
-
- case 'F':
- switch(*ptr++) {
- case 'D':
- fmt=FMT_DEF;
- break;
- case 'G':
- fmt=FMT_GEN-PRC_FLT;
- break;
- case 'E':
- fmt=FMT_EXP-PRC_FLT;
- break;
- case 'F':
- fmt=FMT_FXT-PRC_FLT;
- break;
- case '$':
- fmt=FMT_DOL-PRC_FLT;
- break;
- case '*': /* JF implemented as +- format */
- fmt=FMT_GPH;
- break;
- case ',': /* JF */
- fmt=FMT_CMA-PRC_FLT;
- break;
- case 'U':
- fmt=FMT_USR-PRC_FLT;
- break;
- case '%':
- fmt=FMT_PCT-PRC_FLT;
- break;
- case 'H':
- fmt=FMT_HID;
- break; /* END of JF */
- case 'C':
- default:
- error_msg("Line %d: format %c not supported",lineno,ptr[-1]);
- fmt=FMT_DEF;
- break;
- }
- if(*ptr=='F') {
- fmt+=PRC_FLT;
- ptr++;
- } else
- fmt+=astol(&ptr);
- switch(*ptr++) {
- case 'C':
- jst=JST_CNT;
- break;
- case 'L':
- jst=JST_LFT;
- break;
- case 'R':
- jst=JST_RGT;
- break;
- case 'D':
- jst=JST_DEF;
- break;
- default:
- error_msg("Line %d: Alignment %c not supported",lineno,ptr[-1]);
- jst=JST_DEF;
- break;
- }
- vlen=1;
- break;
- case 'R': /* Row from cols 1 to 63 */
- czrow=astol(&ptr);
- vlen=4;
- break;
-
- case 'W': /* Width of clo to chi is cwid */
- clo=astol(&ptr);
- chi=astol(&ptr);
- cwid=astol(&ptr)+1;
- for(;clo<=chi;clo++)
- set_width(clo,cwid);
- break;
- case 'X':
- ccol=astol(&ptr);
- break;
- case 'Y':
- crow=astol(&ptr);
- break;
-
- default:
- goto bad_field;
- }
- }
- switch(vlen) {
- case 1:
- cp=find_or_make_cell(crow,ccol);
- SET_FMT(cp,fmt);
- SET_JST(cp,jst);
- break;
- case 2:
- rng.lr=MIN_ROW;
- rng.lc=czcol;
- rng.hr=mx_row;
- rng.hc=czcol;
- make_cells_in_range(&rng);
- while(cp=next_cell_in_range()) {
- SET_FMT(cp,fmt);
- SET_JST(cp,jst);
- }
- break;
- case 4:
- rng.lr=czrow;
- rng.lc=MIN_COL;
- rng.hr=czrow;
- rng.hc=mx_col;
- make_cells_in_range(&rng);
- while(cp=next_cell_in_range()) {
- SET_FMT(cp,fmt);
- SET_JST(cp,jst);
- }
- break;
- default:
- break;
- }
- break;
-
- case 'B': /* Boundry field, ignored */
- ptr++;
- while(*ptr) {
- if(*ptr!=';')
- /* if(*ptr+=';') -- used to be this pass travis*/
- goto bad_field;
- ptr++;
- switch(*ptr++) {
- case 'X':
- mx_col=astol(&ptr);
- if(mx_col>MAX_COL) {
- error_msg("Boundry column %lu too large!",mx_col);
- mx_col=MAX_COL;
- }
- break;
- case 'Y':
- mx_row=astol(&ptr);
- if(mx_row>MAX_ROW) {
- error_msg("Boundry row %lu too large!",mx_row);
- mx_row=MAX_ROW;
- }
- break;
- default:
- goto bad_field;
- }
- }
- break;
-
- case 'N': /* A Name field */
- if(ptr[1]!='N')
- goto bad_field;
- ptr+=2;
- vname=0;
- vval=0;
- while(*ptr) {
- if(*ptr!=';')
- goto bad_field;
- *ptr++='\0';
- switch(*ptr++) {
- case 'N': /* Name is */
- vname=ptr;
- while(*ptr && *ptr!=';')
- ptr++;
- vlen=ptr-vname;
- break;
- case 'E': /* Expression is */
- vval=ptr;
- while(*ptr && *ptr!=';')
- ptr++;
- break;
- default:
- --ptr;
- goto bad_field;
- }
- }
- if(!vname || !vval)
- goto bad_field;
- *ptr='\0';
- ptr=new_var_value(vname,vlen,vval);
- if(ptr)
- error_msg("Line %d: Couldn't set %.*s to %s: %s",lineno,vlen,vname,vval,ptr);
- break;
-
- case 'C': /* A Cell entry */
- cprot=0;
- cval=0;
- cexp=0;
- cval=0;
- ptr++;
- while(*ptr) {
- int quotes;
-
- if(*ptr!=';')
- goto bad_field;
- *ptr++='\0';
- switch(*ptr++) {
- case 'X':
- ccol=astol(&ptr);
- break;
- case 'Y':
- crow=astol(&ptr);
- break;
- case 'R':
- czrow=astol(&ptr);
- break;
- case 'C':
- czcol=astol(&ptr);
- break;
- case 'P': /* This cell is Protected */
- cprot++;
- break;
- case 'K': /* This cell's Konstant value */
- cval=ptr;
- quotes=0;
- while(*ptr && (*ptr!=';' || quotes>0))
- if(*ptr++=='"')
- quotes= !quotes;
- break;
- case 'E': /* This cell's Expression */
- cexp=ptr;
- quotes=0;
- while(*ptr && (*ptr!=';' || quotes>0))
- if(*ptr++=='"')
- quotes= !quotes;
-
- break;
- case 'G':
- strcpy(expbuf,cval);
- break;
- case 'D':
- strcpy(expbuf,cexp);
- break;
- case 'S':
- cexp=expbuf;
- break;
- default:
- --ptr;
- goto bad_field;
- }
- }
- *ptr='\0';
- if(cexp && cval && strcmp(cexp,cval)) {
- ptr=read_new_value(crow,ccol,cexp,cval);
- if(ptr) {
- error_msg("Line %d: %d,%d: Read '%s' %s",lineno,crow,ccol,cexp,ptr);
- break;
- }
- } else if(cval) {
- ptr=read_new_value(crow,ccol,0,cval);
- if(ptr) {
- error_msg("Line %d: %d,%d: Val '%s' %s",lineno,crow,ccol,cexp,ptr);
- break;
- }
- } else if(cexp) {
- ptr=read_new_value(crow,ccol,cexp,0);
- if(ptr) {
- error_msg("Line %d: %d,%d: Exp '%s' %s",lineno,crow,ccol,cexp,ptr);
- break;
- }
- }
- if(ismerge)
- push_cell(crow,ccol);
- /* ... */
- break;
- case 'E':
- break;
- case 'W':
- read_mp_windows(ptr+2);
- break;
- case 'U':
- /* JF extension: read user-defined formats */
- read_mp_usr_fmt(ptr+1);
- break;
- /* JF extension: read uset-settable options */
- case 'O':
- read_mp_options(ptr+2);
- break;
- default:
- bad_field:
- error_msg("Line %d: Unknown SYLK line \"%s\"",lineno,cbuf);
- break;
- }
- }
- recenter_all_win();
- }
-
-
- static void
- read_mp_usr_fmt FUN1(char *,ptr)
- {
- int usr_n = -1;
- int n_chrs = 0;
- char *p;
- char *buf[9];
- int i;
-
- for(i=0;i<9;i++)
- buf[i]="";
- p=ptr;
- while(*p==';') {
- *p++='\0';
- switch(*p++) {
- case 'N':
- usr_n=astol(&p)-1;
- break;
- case 'H':
- switch(*p++) {
- case 'P': i=0; break;
- case 'N': i=1; break;
- default: goto badline;
- }
- goto count_chars;
- case 'T':
- switch(*p++) {
- case 'P': i=2; break;
- case 'N': i=3; break;
- default: goto badline;
- }
- goto count_chars;
-
- case 'Z':
- i=4;
- goto count_chars;
-
- case 'C':
- i=5;
- goto count_chars;
-
- case 'D':
- i=6;
- goto count_chars;
-
- case 'P':
- i=7;
- goto count_chars;
-
- case 'S':
- i=8;
- goto count_chars;
-
- count_chars:
- buf[i]=p;
- n_chrs++;
- while(*p && *p!=';') {
- p++;
- n_chrs++;
- }
- break;
-
- default:
- badline:
- error_msg("Unknown SYLK line %s",ptr);
- return;
- }
- }
- if(*p || usr_n<0 || usr_n>15)
- goto badline;
-
- set_usr_stats(usr_n,buf);
- }
-
- static char *
- fmt_to_str FUN1(int, f1)
- {
- static char p_buf[40];
- int p1;
-
- p_buf[1]='\0';
- switch(f1) {
- case FMT_DEF:
- p_buf[0]='D';
- break;
- case FMT_HID:
- p_buf[0]='H';
- break;
- case FMT_GPH:
- p_buf[0]='*';
- break;
- default:
- p1=GET_PRC(f1);
- if(p1==PRC_FLT) {
- p_buf[1]='F';
- p_buf[2]='\0';
- } else
- sprintf(&p_buf[1],"%d",p1);
- switch(f1|PRC_FLT) {
- case FMT_USR: p_buf[0]='U'; break;
- case FMT_GEN: p_buf[0]='G'; break;
- case FMT_DOL: p_buf[0]='$'; break;
- case FMT_PCT: p_buf[0]='%'; break;
- case FMT_FXT: p_buf[0]='F'; break;
- case FMT_CMA: p_buf[0]=','; break;
- case FMT_EXP: p_buf[0]='E'; break;
- default: p_buf[0]='?'; break;
- }
- break;
- }
- return p_buf;
- }
-
- static char
- jst_to_chr FUN1(int,just)
- {
- switch(just) {
- case JST_DEF: return 'D';
- case JST_LFT: return 'L';
- case JST_RGT: return 'R';
- case JST_CNT: return 'C';
- default: return '?';
- }
- }
-
- static FILE *sylk_fp;
- static struct rng *sylk_rng;
-
- static void
- sylk_write_var FUN2(char *,name, struct var *,var)
- {
- if(var->var_flags==VAR_UNDEF && (!var->var_ref_fm || var->var_ref_fm->refs_used==0))
- return;
- switch(var->var_flags) {
- case VAR_UNDEF:
- break;
- case VAR_CELL:
- if(var->v_rng.lr>=sylk_rng->lr && var->v_rng.lr<=sylk_rng->hr && var->v_rng.lc>=sylk_rng->lc && var->v_rng.lc<=sylk_rng->hc)
- (void)fprintf(sylk_fp,"NN;N%s;E%s\n",var->var_name,cell_name(var->v_rng.lr,var->v_rng.lc));
- break;
- case VAR_RANGE:
- if(var->v_rng.lr<sylk_rng->lr || var->v_rng.hr>sylk_rng->hr || var->v_rng.lc<sylk_rng->lc || var->v_rng.hc>sylk_rng->hc)
- break;
-
- (void)fprintf(sylk_fp,"NN;N%s;E%s\n",var->var_name,range_name(&(var->v_rng)));
- break;
- #ifdef TEST
- default:
- panic("Unknown var type %d",var->var_flags);
- #endif
- }
- }
-
- void
- sylk_write_file FUN2(FILE *,fp, struct rng *,rng)
- {
- CELLREF r,c;
- CELL *cp;
- CELLREF crow=0,ccol=0;
- unsigned short w;
- extern void for_all_vars();
- /* struct var *var; */
-
- (void)fprintf(fp,"ID;POLEO\n");
-
- /* If no range given, write the entire file */
- if(!rng) {
- int n;
- int fmts;
- char *data[9];
-
- rng= &all_rng;
-
- (void)fprintf(fp,"F;D%s%c%u\n",fmt_to_str(default_fmt),jst_to_chr(default_jst),default_width);
-
- fmts=usr_set_fmts();
- for(n=0;n<16;n++) {
- if(fmts&(1<<n)) {
- get_usr_stats(n,data);
- fprintf(fp,"U;N%u;P%s;S%s",n+1,data[7],data[8]);
- if(data[0][0])
- fprintf(fp,";HP%s",data[0]);
- if(data[1][0])
- fprintf(fp,";HN%s",data[1]);
- if(data[2][0])
- fprintf(fp,";TP%s",data[2]);
- if(data[3][0])
- fprintf(fp,";TN%s",data[3]);
- if(data[4][0])
- fprintf(fp,";Z%s",data[4]);
- if(data[5][0])
- fprintf(fp,";C%s",data[5]);
- if(data[6])
- fprintf(fp,";D%s",data[6]);
- putc('\n',fp);
- }
- }
- write_mp_options(fp);
-
- (void)fprintf(fp,"B;Y%u;X%u\n",highest_row(),highest_col());
-
- }
-
- (void)next_widths((CELLREF *)0,(CELLREF *)0);
- while(w=next_widths(&r,&c)) {
- if(r>rng->hc || c<rng->lc)
- continue;
- if(r<rng->lc)
- r=rng->lc;
- if(c>rng->hc)
- c=rng->hc;
- (void)fprintf(fp,"F;W%u %u %u\n",r,c,w-1);
- }
-
- sylk_fp=fp;
- sylk_rng=rng;
- for_all_vars(sylk_write_var);
- find_cells_in_range(rng);
- while(cp=next_row_col_in_range(&r,&c)) {
- char *ptr;
- int f1,j1;
- char p_buf[40];
-
- f1=GET_FMT(cp);
- j1=GET_JST(cp);
- if(f1!=FMT_DEF || j1!=JST_DEF) {
- (void)fprintf(fp,"F;");
- if(c!=ccol) {
- (void)fprintf(fp,"X%u;",c);
- ccol=c;
- }
- if(r!=crow) {
- (void)fprintf(fp,"Y%u;",r);
- crow=r;
- }
- (void)fprintf(fp,"F%s%c\n",fmt_to_str(f1),jst_to_chr(j1));
- }
-
- if(!GET_TYP(cp) && !cp->cell_formula)
- continue;
-
- (void)fprintf(fp,"C;");
- if(c!=ccol) {
- (void)fprintf(fp,"X%u;",c);
- ccol=c;
- }
- if(r!=crow) {
- (void)fprintf(fp,"Y%u;",r);
- crow=r;
- }
-
- if(cp->cell_formula) {
- (void)fprintf(fp,"E%s",decomp(r,c,cp));
- decomp_free();
- }
-
- switch(GET_TYP(cp)) {
- case 0:
- ptr=0;
- break;
- case TYP_STR:
- ptr=0;
- if(cp->cell_formula)
- putc(';',fp);
- (void)fprintf(fp,"K\"%s\"",cp->cell_str);
- break;
- case TYP_FLT:
- ptr=flt_to_str(cp->cell_flt);
- break;
- case TYP_INT:
- sprintf(p_buf,"%ld",cp->cell_int);
- ptr=p_buf;
- break;
- case TYP_BOL:
- ptr=bname[cp->cell_bol];
- break;
- case TYP_ERR:
- ptr=ename[cp->cell_err];
- break;
- #ifdef TEST
- default:
- ptr=0;
- panic("What cell type %d",GET_TYP(cp));
- #endif
- }
-
- if(ptr) {
- if(cp->cell_formula)
- putc(';',fp);
- (void)fprintf(fp,"K%s",ptr);
- }
-
- putc('\n',fp);
- }
-
- if(rng== &all_rng)
- write_mp_windows(fp);
-
- (void)fprintf(fp,"E\n");
- }
-
- int
- sylk_set_options FUN2(int,set_opt, char *,option)
- {
- return -1;
- }
-
- void
- sylk_show_options FUN0()
- {
- text_line("File format: sylk (Microsoft Multiplan interchange format)");
- }
-