home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume27
/
conv123
/
part02
/
grph123.c
< prev
Wrap
C/C++ Source or Header
|
1993-09-05
|
30KB
|
1,034 lines
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "lotus.h"
#include "swapb.h"
#define MAXHEADLINES 2
#define MAXROWS 8192 /* dependent on 12-bit maximum value */
#define MAXCOLS 53 /* arbitrary */
#define MAXCOLWD 39 /* used only to calculate max input rec length */
/* and x data value length */
#define MAXINRECLEN (MAXCOLS * MAXCOLWD + 5 * MAXCOLS)
#define COLEXTEND 2 /* amount to widen columns for 123 */
FILE *infile, *outfile;
short current_row, current_graph;
long current_offset; /* output file offset */
short col_width[MAXCOLS], col_pos[MAXCOLS], col_type[MAXCOLS];
short formula_start_row[MAXCOLS], formula_end_row[MAXCOLS];
short formula_start_col, formula_end_col;
short decimals(), dec_pl, col_dec_pl[MAXCOLS], row_dec_pl;
int y_decpl[6];
char *qtstr();
/***********************************/
/* declare lotus record structures */
/***********************************/
BOF BOFr;
RANGE RANGEr;
CALCCOUNT CALCCOUNTr;
CALCMODE CALCMODEr;
CALCORDER CALCORDERr;
SPLIT SPLITr;
SYNC SYNCr;
WINDOW1 WINDOW1r;
COLW1 COLW1r;
NGRAPH NGRAPHr;
TABLE TABLEr;
QRANGE QRANGEr;
PRANGE PRANGEr;
LABEL LABELr;
/* INTEGER INTEGERr; */
NUMBER NUMBERr;
FORMULA FORMULAr;
LEOF LEOFr;
/* now for the main data structure, which has limits -- this */
/* monster is (somewhat) necessary in order to allow the */
/* flexibility of getting all the data (and labels) in before */
/* writing the NGRAPH record... */
struct {
char x_item[MAXCOLWD+1];
double y_item[6];
short number_of_labels;
char y_label[6][20];
} graph_data[MAXCOLS];
/*****************************/
/* finally, we begin */
/*****************************/
main(argc,argv)
int argc;
char *argv[];
{
/**********************/
/* main declarations */
/**********************/
int fstat;
char c;
char *p, *bp, *cp, *fp, *sp, *sstat;
char inbuf[MAXINRECLEN + 1], util_buf[MAXINRECLEN + 1], util_buf2[100];
char infilename[96];
char outfilename[96];
char blank_buf[80];
int i, j, k, l, debug, fs, us, type_ind, label_ready;
unsigned short i1, j1, l1;
short number_of_cols, number_of_rows;
short number_of_graphs, header_lines, max_title;
char str_value[6][41];
double dbl_value[6];
long RANGE_offset;
/**************************************/
/* initialize lotus record structures */
/**************************************/
int2s(swapb(BOF_op),BOFr.opcode);
int2s(swapb(BOF_len),BOFr.record_length);
int2s(swapb((unsigned short)1030),BOFr.ff_version);
int2s(swapb(RANGE_op),RANGEr.opcode);
int2s(swapb(RANGE_len),RANGEr.record_length);
int2s(swapb((unsigned short)0),RANGEr.start_column);
int2s(swapb((unsigned short)0),RANGEr.start_row);
int2s(swapb((unsigned short)0),RANGEr.end_column);
int2s(swapb((unsigned short)0),RANGEr.end_row);
int2s(swapb(CALCCOUNT_op),CALCCOUNTr.opcode);
int2s(swapb(CALCCOUNT_len),CALCCOUNTr.record_length);
*CALCCOUNTr.iteration_count = 1;
int2s(swapb(CALCMODE_op),CALCMODEr.opcode);
int2s(swapb(CALCMODE_len),CALCMODEr.record_length);
*CALCMODEr.recalculation = 0xFF; /* automatic recalc */
int2s(swapb(CALCORDER_op),CALCORDERr.opcode);
int2s(swapb(CALCORDER_len),CALCORDERr.record_length);
*CALCORDERr.calc_order = 0x00; /* natural order */
int2s(swapb(SPLIT_op),SPLITr.opcode);
int2s(swapb(SPLIT_len),SPLITr.record_length);
*SPLITr.window_split = 0x00; /* no window split */
int2s(swapb(SYNC_op),SYNCr.opcode);
int2s(swapb(SYNC_len),SYNCr.record_length);
*SYNCr.window_sync = 0xFF; /* window synchronized */
int2s(swapb(WINDOW1_op),WINDOW1r.opcode);
int2s(swapb(WINDOW1_len),WINDOW1r.record_length);
int2s(swapb((unsigned short)0),WINDOW1r.cc_column);
int2s(swapb((unsigned short)0),WINDOW1r.cc_row);
*WINDOW1r.cell_format = 2; /* two decimal places */
*WINDOW1r.unused1 = 0;
int2s(swapb((unsigned short)9),WINDOW1r.column_width);
int2s(swapb((unsigned short)8),WINDOW1r.ncol_on_screen);
int2s(swapb((unsigned short)20),WINDOW1r.nrow_on_screen);
int2s(swapb((unsigned short)0),WINDOW1r.leftmost_column);
int2s(swapb((unsigned short)0),WINDOW1r.top_row);
int2s(swapb((unsigned short)0),WINDOW1r.ntitle_col);
int2s(swapb((unsigned short)0),WINDOW1r.ntitle_row);
int2s(swapb((unsigned short)0),WINDOW1r.ltitle_col);
int2s(swapb((unsigned short)0),WINDOW1r.ttitle_row);
int2s(swapb((unsigned short)4),WINDOW1r.borderwd_col);
int2s(swapb((unsigned short)4),WINDOW1r.borderwd_row);
int2s(swapb((unsigned short)72),WINDOW1r.window_width);
*WINDOW1r.unused2 = 0;
*WINDOW1r.unused3 = 0;
/* there are multiple of these, so just init basic elements for now */
int2s(swapb(COLW1_op),COLW1r.opcode);
int2s(swapb(COLW1_len),COLW1r.record_length);
/* there are multiple of these, so just init basic elements for now */
int2s(swapb(NGRAPH_op),NGRAPHr.opcode);
int2s(swapb(NGRAPH_len),NGRAPHr.record_length);
int2s(swapb(TABLE_op),TABLEr.opcode);
int2s(swapb(TABLE_len),TABLEr.record_length);
*TABLEr.table_ind = 0x00; /* no table */
int2s(swapb((unsigned short)0xFFFF),TABLEr.table_start_column);
int2s(swapb((unsigned short)0),TABLEr.table_start_row);
int2s(swapb((unsigned short)0xFFFF),TABLEr.table_end_column);
int2s(swapb((unsigned short)0),TABLEr.table_end_row);
int2s(swapb((unsigned short)0xFFFF),TABLEr.cell1_start_column);
int2s(swapb((unsigned short)0),TABLEr.cell1_start_row);
int2s(swapb((unsigned short)0xFFFF),TABLEr.cell1_end_column);
int2s(swapb((unsigned short)0),TABLEr.cell1_end_row);
int2s(swapb((unsigned short)0xFFFF),TABLEr.cell2_start_column);
int2s(swapb((unsigned short)0),TABLEr.cell2_start_row);
int2s(swapb((unsigned short)0xFFFF),TABLEr.cell2_end_column);
int2s(swapb((unsigned short)0),TABLEr.cell2_end_row);
int2s(swapb(QRANGE_op),QRANGEr.opcode);
int2s(swapb(QRANGE_len),QRANGEr.record_length);
int2s(swapb((unsigned short)0xFFFF),QRANGEr.input_start_column);
int2s(swapb((unsigned short)0),QRANGEr.input_start_row);
int2s(swapb((unsigned short)0xFFFF),QRANGEr.input_end_column);
int2s(swapb((unsigned short)0),QRANGEr.input_end_row);
int2s(swapb((unsigned short)0xFFFF),QRANGEr.output_start_column);
int2s(swapb((unsigned short)0),QRANGEr.output_start_row);
int2s(swapb((unsigned short)0xFFFF),QRANGEr.output_end_column);
int2s(swapb((unsigned short)0),QRANGEr.output_end_row);
int2s(swapb((unsigned short)0xFFFF),QRANGEr.criteria_start_column);
int2s(swapb((unsigned short)0),QRANGEr.criteria_start_row);
int2s(swapb((unsigned short)0xFFFF),QRANGEr.criteria_end_column);
int2s(swapb((unsigned short)0),QRANGEr.criteria_end_row);
*QRANGEr.command = 0; /* no command */
int2s(swapb(PRANGE_op),PRANGEr.opcode);
int2s(swapb(PRANGE_len),PRANGEr.record_length);
int2s(swapb((unsigned short)0xFFFF),PRANGEr.start_column);
int2s(swapb((unsigned short)0),PRANGEr.start_row);
int2s(swapb((unsigned short)0xFFFF),PRANGEr.end_column);
int2s(swapb((unsigned short)0),PRANGEr.end_row);
int2s(swapb(LABEL_op),LABELr.opcode);
*LABELr.format = 0xFF; /* lotus default */
*LABELr.position = 0x27; /* single quote ('), left justified */
int2s(swapb(NUMBER_op),NUMBERr.opcode);
int2s(swapb(NUMBER_len),NUMBERr.record_length);
*NUMBERr.format = 0xFF; /* lotus default */
int2s(swapb(FORMULA_op),FORMULAr.opcode);
*FORMULAr.format = 0xFF; /* lotus default */
int2s(swapb(LEOF_op),LEOFr.opcode);
int2s(swapb(LEOF_len),LEOFr.record_length);
/************************************/
/* Now some ordinary initialization */
/************************************/
current_offset = 0L;
current_graph = 0;
type_ind = 0;
number_of_cols = 0;
number_of_rows = 0;
label_ready = 0;
max_title = 18;
/*******************************/
/* assign files */
/*******************************/
infile = stdin; /* typical input is stdin (filter) */
outfile = stdout; /* typical output is stdout (filter) */
debug = 0; /* don't do it */
/* Make sure blank_buf is initialized */
for (i = 0; i < 80; i++)
blank_buf[i] = ' ';
/************************************/
/* if there are input parameters, */
/* deal with them. */
/************************************/
if (argc > 3) {
fprintf(stderr,"Allowed parameters are input and output filenames.\n");
return(1);
}
/* open main data input file as a stream (maybe) */
if (argc > 1) {
fclose(infile);
strcpy(infilename,argv[1]);
if ((infile = fopen(infilename,"r")) == NULL) {
fprintf(stderr,"Open of input data file %s failed.\n",infilename);
return(1);
}
}
/* create and open output file directly (maybe) */
if (argc > 2) {
fclose(outfile);
strcpy(outfilename,argv[2]);
if ((outfile = fopen(outfilename,"w+")) == NULL) {
fprintf(stderr,"open of output data file %s failed.\n",outfilename);
fclose(infile);
return;
}
}
/************************************/
/* now get to work translating it */
/************************************/
if (get_header_info(inbuf,&number_of_graphs,&header_lines))
return(1);
if (number_of_graphs < 1) {
fprintf(stderr,"No graphs were detected...check input file.");
exit(1);
}
current_row = number_of_graphs + 6; /* leave room for titles & stuff */
/* fprintf(stderr,"Number of graphs: %d\n",number_of_graphs); */
/************************************/
/* we've got SOMETHING, so go ahead */
/* and start the 123 output! */
/************************************/
p = (char *)(&BOFr);
fs = output_lotus_record(p);
p = (char *)(&CALCMODEr);
fs = output_lotus_record(p);
#ifdef DEBUG
fprintf(stderr,"Offset after RANGE: %d\n",current_offset);
#endif
/**********************************/
/* create header labels */
/**********************************/
create_lotus_label("Brooktree Corp. Confidential",0,0);
*LABELr.format = 0x7F;
create_lotus_label("Graph Name",0,2);
create_lotus_label("Graph Title",1,2);
create_lotus_label("================",0,3);
create_lotus_label("==============================",1,3);
*LABELr.format = 0xFF;
/**********************************/
/* do the real work, and process */
/* all lines in the file */
/**********************************/
while ((fs = getline(inbuf,MAXINRECLEN,infile)) != EOF) {
/** formula_start_col = -1; /* start out pessimistic */
/** formula_end_col = -1; **/
row_dec_pl = 0;
if (trim(inbuf) > 0) {
type_ind = (int)(*inbuf);
/* fprintf(stderr,"Now doing type: %c\n",*inbuf); */
switch (type_ind) {
case 'N':
case 'n': /* graph name */
/************************************/
/* initialize named graph structure */
/************************************/
sp = (char *)&NGRAPHr;
sp = sp + 4; /* skip over opcode & size */
for (i = 0; i < (sizeof(NGRAPHr) - 4); i++)
*sp++ = '\0';
*NGRAPHr.graph_type = (char)(0x04); /* line graph */
*NGRAPHr.x_format = (char)(0x71);
*NGRAPHr.y_format = (char)(0x71);
int2s(swapb((unsigned short)(0x01)),NGRAPHr.skip_factor);
for (i = 0; i < 6; i++) {
int2s((unsigned short)(0xFFFF),NGRAPHr.yd_range[i].y_start_col);
int2s((unsigned short)(0xFFFF),NGRAPHr.yd_range[i].y_end_col);
int2s((unsigned short)(0xFFFF),NGRAPHr.yl_range[i].y_start_col);
int2s((unsigned short)(0xFFFF),NGRAPHr.yl_range[i].y_end_col);
NGRAPHr.y_lformat[i] = (char)(0x03);
y_decpl[i] = 2;
}
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
sp = qtstr(util_buf,util_buf,15);
strcpy(NGRAPHr.graph_name,util_buf);
}
break;
case 'T': /* First title */
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
sp = qtstr(util_buf,util_buf,39);
strcpy(NGRAPHr.first_title,util_buf);
}
break;
case 't': /* Second title */
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
sp = qtstr(util_buf,util_buf,39);
strcpy(NGRAPHr.second_title,util_buf);
}
break;
case 'B':
case 'b': /* x (bottom) title */
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
sp = qtstr(util_buf,util_buf,39);
strcpy(NGRAPHr.x_title,util_buf);
if (max_title < strlen(util_buf))
max_title = strlen(util_buf);
}
break;
case 'S':
case 's': /* y (side) title */
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
sp = qtstr(util_buf,util_buf,39);
strcpy(NGRAPHr.y_title,util_buf);
}
break;
case 'G':
case 'g':
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
for (i = 0; i < 4; i++)
*str_value[i] = '\0';
us = sscanf(util_buf,"%s%s%s%s",str_value[0],
str_value[1],
str_value[2],
str_value[3]);
if (us > 0) {
c = toupper((char)(*str_value[0]));
if (c == 'L')
*NGRAPHr.graph_type = (char)(0x04); /* line */
else
if (c == 'B')
*NGRAPHr.graph_type = (char)(0x01); /* bar */
else
if (c == 'P')
*NGRAPHr.graph_type = (char)(0x02); /* pie */
else
if (c == 'X')
*NGRAPHr.graph_type = (char)(0x00); /* xy */
else
if (c == 'S')
*NGRAPHr.graph_type = (char)(0x05); /* stacked bar */
}
if (us > 1) {
c = toupper((char)(*str_value[1]));
if (c == 'N')
*NGRAPHr.grid = (char)(0x00); /* none */
else
if (c == 'H')
*NGRAPHr.grid = (char)(0x01); /* horizontal */
else
if (c == 'V')
*NGRAPHr.grid = (char)(0x02); /* vertical */
else
if (c == 'B')
*NGRAPHr.grid = (char)(0x03); /* both horz & vert */
}
if (us > 2) {
c = toupper((char)(*str_value[2]));
if (c == 'B')
*NGRAPHr.color = (char)(0x00); /* black & white */
else
if (c == 'C')
*NGRAPHr.color = (char)(0xFF); /* color */
}
if (us > 3) {
sscanf(str_value[3],"%d",&i);
if (!i)
i = 1;
if (i > 256)
i = 256;
int2s(swapb((unsigned short)i),NGRAPHr.skip_factor);
}
}
break;
case 'l': /* legends */
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
sp = util_buf;
for (i = 0; *sp && (i < 6); i++) {
sp = qtstr(sp,util_buf2,19);
strcpy(NGRAPHr.y_legend[i],util_buf2);
}
}
break;
case 'P':
case 'p':
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us <= 0)
break;
us = sscanf(util_buf,"%d%d%d%d%d%d",&(y_decpl[0]),
&(y_decpl[1]),
&(y_decpl[2]),
&(y_decpl[3]),
&(y_decpl[4]),
&(y_decpl[5]));
for (i = 0; i < us; i++) {
if (y_decpl[i] < 0) y_decpl[i] = 0;
if (y_decpl[6] > 6) y_decpl[i] = 6;
}
/* fprintf(stderr,"decpl: %d %d %d %d %d %d\n",y_decpl[0],y_decpl[1],y_decpl[2],
y_decpl[3],y_decpl[4],y_decpl[5]); */
break;
case 'D':
case 'd':
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us <= 0)
break;
sp = util_buf;
sp = qtstr(sp,util_buf2,39);
if (strlen(util_buf2) > 0) {
number_of_rows++;
if (number_of_rows > MAXCOLS) {
fprintf(stderr,
"Maximum number of data points exceeded.");
exit(3);
}
i = number_of_rows - 1;
strcpy(graph_data[i].x_item,util_buf2);
for (j = 0; j < 6; j++) {
graph_data[i].y_item[j] = -2000000000.0;
*(graph_data[i].y_label[j]) = '\0';
}
us = sscanf(sp,"%lf%lf%lf%lf%lf%lf",
&(graph_data[i].y_item[0]),
&(graph_data[i].y_item[1]),
&(graph_data[i].y_item[2]),
&(graph_data[i].y_item[3]),
&(graph_data[i].y_item[4]),
&(graph_data[i].y_item[5]));
number_of_cols = us > number_of_cols ? us : number_of_cols;
graph_data[i].number_of_labels = 0;
label_ready = 1;
}
break;
case 'L': /* labels */
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us <= 0)
break;
if (!label_ready)
break;
i = number_of_rows - 1;
sp = util_buf;
for (j = 0; *sp && (j < 6); j++) {
sp = qtstr(sp,util_buf2,19);
strcpy(graph_data[i].y_label[j],util_buf2);
(graph_data[i].number_of_labels)++;
}
label_ready = 0;
break;
case 'X':
case 'x':
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
us = sscanf(util_buf,"%lf%lf",&dbl_value[0],&dbl_value[1]);
if (us > 0) stdbl(dbl_value[0],NGRAPHr.x_low_limit);
if (us > 1) stdbl(dbl_value[1],NGRAPHr.x_up_limit);
*NGRAPHr.x_scale = (char)(0xFF);
}
break;
case 'Y':
case 'y':
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
us = sscanf(util_buf,"%lf%lf",&dbl_value[0],&dbl_value[1]);
if (us > 0) stdbl(dbl_value[0],NGRAPHr.y_low_limit);
if (us > 1) stdbl(dbl_value[1],NGRAPHr.y_up_limit);
*NGRAPHr.y_scale = (char)(0xFF);
}
break;
case 'F':
case 'f':
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
us = sscanf(util_buf,"%s%s%s%s%s%s",str_value[0],
str_value[1],
str_value[2],
str_value[3],
str_value[4],
str_value[5]);
for (i = 0; i < us; i++) {
c = toupper((char)(*str_value[i]));
if (c == 'N')
NGRAPHr.y_lformat[i] = (char)(0x00); /* none */
else
if (c == 'L')
NGRAPHr.y_lformat[i] = (char)(0x01); /* line */
else
if (c == 'S')
NGRAPHr.y_lformat[i] = (char)(0x02); /* symbol */
else
if (c == 'B')
NGRAPHr.y_lformat[i] = (char)(0x03); /* both l & s */
}
}
break;
case 'A':
case 'a':
strcpy(util_buf,&inbuf[1]);
us = trim(util_buf);
if (us > 0) {
us = sscanf(util_buf,"%s%s%s%s%s%s",str_value[0],
str_value[1],
str_value[2],
str_value[3],
str_value[4],
str_value[5]);
for (i = 0; i < us; i++) {
c = toupper((char)(*str_value[i]));
if (c == 'C')
NGRAPHr.y_dlalign[i] = (char)(0x00); /* none */
else
if (c == 'R')
NGRAPHr.y_dlalign[i] = (char)(0x01); /* line */
else
if (c == 'B')
NGRAPHr.y_dlalign[i] = (char)(0x02); /* symbol */
else
if (c == 'L')
NGRAPHr.y_dlalign[i] = (char)(0x03); /* both l & s */
else
if (c == 'A')
NGRAPHr.y_dlalign[i] = (char)(0x04); /* both l & s */
}
}
break;
case 'E':
case 'e':
if (number_of_cols <= 0) /* if there's no y-data, */
break; /* just bail out */
/* how about setting the first (0) column width */
p = (char *)(&COLW1r);
int2s(swapb((unsigned short)0),COLW1r.column_number);
int2s(swapb(max_title),COLW1r.column_width);
output_lotus_record(p);
/* now let's put out the table of contents info */
*LABELr.position = 0x27; /* single quote ('), lj */
p = (char *)(&LABELr);
j1 = 0; i1 = ++current_graph + 3;
create_lotus_label(NGRAPHr.graph_name,j1,i1);
j1 = 1;
create_lotus_label(NGRAPHr.first_title,j1,i1);
/* Data values header */
j1 = 0; i1 = current_row++;
sprintf(util_buf,"Data for graph: %s (%s)",
NGRAPHr.graph_name,NGRAPHr.first_title);
*LABELr.format = 0x7F; /* lotus default */
create_lotus_label(util_buf,j1,i1);
*LABELr.format = 0xFF; /* lotus default */
/* the x-value and y-value legends and ranges comes next */
j1 = 0; i1 = current_row;
create_lotus_label(NGRAPHr.x_title,j1,i1);
int2s(swapb((unsigned short)1),NGRAPHr.x_start_col);
int2s(swapb(i1),NGRAPHr.x_start_row);
int2s(swapb(number_of_rows),NGRAPHr.x_end_col);
int2s(swapb(i1),NGRAPHr.x_end_row);
for (j = 0; j < number_of_cols; j++) {
i1 = current_row + j + 1;
create_lotus_label(NGRAPHr.y_legend[j],j1,i1);
}
for (j = 0; j < number_of_cols; j++) {
i1 = current_row + j + 1;
int2s(swapb((unsigned short)1),
NGRAPHr.yd_range[j].y_start_col);
int2s(swapb(i1),NGRAPHr.yd_range[j].y_start_row);
int2s(swapb(number_of_rows),NGRAPHr.yd_range[j].y_end_col);
int2s(swapb(i1),NGRAPHr.yd_range[j].y_end_row);
/* the data-label range comes next; even if no labels */
/* note that this limits a graph to 127 data points */
int2s(swapb((unsigned short)(number_of_rows + 2)),
NGRAPHr.yl_range[j].y_start_col);
int2s(swapb(i1),NGRAPHr.yl_range[j].y_start_row);
int2s(swapb((unsigned short)((2 * number_of_rows) + 2)),
NGRAPHr.yl_range[j].y_end_col);
int2s(swapb(i1),NGRAPHr.yl_range[j].y_end_row);
}
/* let's write that graph record! */
p = (char *)(&NGRAPHr);
output_lotus_record(p);
/*******************************************************/
/* now for the data values (at last!) */
/*******************************************************/
*LABELr.position = 0x22; /* double quote ("), rj */
for (i = 0; i < number_of_rows; i++) {
/* set column width, hard-coded for now */
p = (char *)(&COLW1r);
j1 = i + 1;
i1 = 11 + COLEXTEND;
int2s(swapb(j1),COLW1r.column_number);
int2s(swapb(i1),COLW1r.column_width);
output_lotus_record(p);
/* now for the independent data value (x-value) */
j1 = i + 1; i1 = current_row;
if (*NGRAPHr.graph_type)
create_lotus_label(graph_data[i].x_item,j1,i1);
else {
us = sscanf(graph_data[i].x_item,"%lf",&dbl_value[0]);
if (us && (dbl_value[0] > -2000000000.0))
create_lotus_number(dbl_value[0],j1,i1,2);
}
/* now for the dependent data values (y-values) */
/* put out the numbers, and labels if any */
*LABELr.position = 0x27; /* single quote ('), lj */
j1 = i + 1;
for (j = 0; j < number_of_cols; j++) {
dec_pl = y_decpl[j];
i1 = current_row + j + 1;
if (graph_data[i].y_item[j] > -2000000000.0)
create_lotus_number(graph_data[i].y_item[j],
j1,i1,dec_pl);
if (graph_data[i].number_of_labels >= j) {
l1 = j1 + number_of_rows + 1;
create_lotus_label(graph_data[i].y_label[j],l1,i1);
}
}
*LABELr.position = 0x22; /* double quote ("), rj */
}
current_row += number_of_cols + 2;
number_of_cols = 0;
number_of_rows = 0;
label_ready = 0;
/* max_title = 18; */
break;
case '#':
break;
default:
fprintf(stderr,"Unknown record type!\n");
break;
}
}
} /* end while */
/*********************/
/* end of lotus file */
/*********************/
p = (char *)(&LEOFr);
output_lotus_record(p);
}
/*****************************************/
/* scan input file for number of graphs, */
/* column widths, etc. */
/*****************************************/
int
get_header_info(bufp,graphs,hlines)
char *bufp;
short *graphs, *hlines;
{
int i, j, count = -1;
char c;
*bufp = '\0';
*graphs = 0;
while (getline(bufp,MAXINRECLEN,infile) != EOF) {
j = trim(bufp);
if ('E' == toupper(*bufp))
++(*graphs);
}
rewind(infile);
return(0);
}
/*****************************************/
/* create and output a lotus label */
/*****************************************/
int
create_lotus_label(label,lcol,lrow)
char *label;
short lcol;
short lrow;
{
int i,j;
short c1, r1;
char *p;
p = (char *)(&LABELr);
int2s(swapb(lcol),LABELr.column);
int2s(swapb(lrow),LABELr.row);
*LABELr.string = '\0';
strcat(LABELr.string,label);
/* fprintf(stderr,"x: %s\n",LABELr.string); */
int2s(swapb((unsigned short)(strlen(LABELr.string) + 7)),
LABELr.record_length);
output_lotus_record(p);
return(0);
}
/*****************************************/
/* create and output a lotus number */
/*****************************************/
int
create_lotus_number(number,ncol,nrow,ndp)
double number;
short ncol;
short nrow;
short ndp;
{
int i,j;
short c1, r1;
char *p;
p = (char *)(&NUMBERr);
int2s(swapb(ncol),NUMBERr.column);
int2s(swapb(nrow),NUMBERr.row);
*NUMBERr.format = (char)(0x80 + ndp);
stdbl(number,NUMBERr.value);
output_lotus_record(p);
return(0);
}
/*****************************************/
/* output a lotus record -- note that */
/* the length of the record is contained */
/* in the record itself (bytes 2-3) */
/* minus the 4 bytes of opcode+length */
/*****************************************/
int
output_lotus_record(record_pointer)
char *record_pointer;
{
int i, fstatus;
unsigned short total_length = 0;
total_length = swapb((unsigned short)s2int(record_pointer + 2)) + 4;
for (i = 0; i < total_length; i++)
fstatus = putc(*record_pointer++,outfile);
current_offset += (long)total_length;
return(fstatus);
}
/***********************************/
/* our own getline -- like fgets, */
/* just returns null-term string */
/* instead of newline, and length */
/* instead of pointer */
/***********************************/
int
getline(s,lim,stream)
char s[];
int lim;
register FILE *stream;
{
int c, i;
i = 0;
while (--lim > 0 && (c = getc(stream)) != EOF && c != '\n')
s[i++] = c;
if (c == EOF)
return(c);
s[i] = '\0';
/* current_row++; */
return(i);
}
int
stdbl(value,ptr)
double value;
char *ptr;
{
int i = 7;
char *dp;
dp = (char *)&value;
while (i > -1)
*ptr++ = *(dp + (i--));
}
/*****************************************/
/* return a new string, with the first */
/* character non-whitespace. Look out; */
/* it does clobber the passed contents, */
/* but returns the length of the result .*/
/*****************************************/
int
trim(p)
register char *p;
{
char *hp, *np;
if (*p != ' ' && *p != '\t')
return(strlen(p));
hp = np = p;
while(*p && (*p == ' ' || *p == '\t'))
p++;
while (*p)
*np++ = *p++;
*np = '\0';
return((int)(np - hp));
}
/*****************************************/
/* fix a string, with the double quotes */
/* removed, and to a maximum length (not */
/* including eos) NOTE: this routine */
/* may alter 'instr'. */
/*****************************************/
char *
qtstr(instr,outstr,maxlen)
char *instr;
char *outstr;
int maxlen;
{
int i, q;
char *isp, *osp;
q = 0;
i = trim(instr); /* it may be altered right here */
isp = instr;
osp = outstr;
if (*isp == '"') {
++isp;
q++;
}
for (i = 0; ((i < maxlen) && *isp && ((q && *isp != '"') || (!q && *isp != ' '))); i++)
*osp++ = *isp++;
*osp = '\0';
if (i >= maxlen)
while (*isp && *isp != ' ' && *isp != '\t' && *isp != '"')
isp++;
return(*isp ? ++isp : isp);
}
/**********************************************************************/
/* create a lotus formula range...lotus cell addresses are of two */
/* types, absolute and relative. Absolute address place 0,0 at the *
/* upper left corner of the spreadsheet. Relative address are */
/* "circular" relative, and are all negative. The current cell is */
/* address -32768 (the maximum 16-bit signed negative). The cell */
/* position immediately "above" or "left" of the current cell is */
/* -1, decreasing as you "decrease" your position. The cell position */
/* immediately "below" or "right" of the current cell is -32767, */
/* increasing as you "increase" your position. */
/* */
/* c_col ("current" column) and c_row ("current" row) are actually */
/* just relative starting points for the addresses that follow them. */
/* The "type" parameter is simply a flag to indicate whether the */
/* range is a true range, all four parameters (type = 1), or whether */
/* it is just a column position (type = 0). In the latter case, only */
/* the start column and start row are done. */
/* */
/* Oh, by the way; don't forget to byte-swap each 16-bits if your */
/* computer is a big-endian! */
/**********************************************************************/
int
create_formula_range(range_ptr,c_col,c_row,s_col,s_row,e_col,e_row,type)
char *range_ptr;
short c_col, c_row, s_col, s_row, e_col, e_row;
int type;
{
short rel_ptr;
char *p;
p = range_ptr;
rel_ptr = (s_col < c_col) ? (s_col - c_col - 8192) : (s_col - c_col - 32768);
int2s(swapb((unsigned short)rel_ptr),p);
p += 2;
rel_ptr = (s_row < c_row) ? (s_row - c_row - 8192) : (s_row - c_row - 32768);
int2s(swapb((unsigned short)rel_ptr),p);
if (type) {
p += 2;
rel_ptr = (e_col < c_col) ? (e_col - c_col - 8192) : (e_col - c_col - 32768);
int2s(swapb((unsigned short)rel_ptr),p);
p += 2;
rel_ptr = (e_row < c_row) ? (e_row - c_row - 8192) : (e_row - c_row - 32768);
int2s(swapb((unsigned short)rel_ptr),p);
}
return(0);
}
/**********************************************/
/* Routine to count number of decimal places */
/* assumes that numbuf is already "trimmed" */
/* (i.e., no leading white space). */
/**********************************************/
short
decimals(numbuf)
char *numbuf;
{
char *c, *p;
if ((p = strchr(numbuf,'.')) == NULL)
return((short)0);
c = ++p;
while (*c && isdigit(*c))
c++;
return((short)(c - p));
}