home *** CD-ROM | disk | FTP | other *** search
- #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));
- }
-