1 /*-
2  * Copyright (c) 2001 David Giffin.
3  * All rights reserved.
4  *
5  * Based on the the Java version: Andrew Khan Copyright (c) 2000.
6  *
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by
23  *     David Giffin <david@giffin.org>."
24  *
25  * 4. Redistributions of any form whatsoever must retain the following
26  *    acknowledgment:
27  *    "This product includes software developed by
28  *     David Giffin <david@giffin.org>."
29  *
30  * THIS SOFTWARE IS PROVIDED BY DAVID GIFFIN ``AS IS'' AND ANY
31  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID GIFFIN OR
34  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41  * OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  *      $Id: main.c,v 1.8.2.19 2000/03/31 00:06:34 david Exp $
44  *
45  */
46 
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <math.h>
50 #include <time.h>
51 #include <sys/types.h>
52 #include "biff.h"
53 #include "cell.h"
54 #include "book.h"
55 #include "sheet.h"
56 #include "interger.h"
57 
58 static char *dateformat = NULL;
59 
60 void
cell_setdateformat(char * d)61 cell_setdateformat(char *d) {
62 	dateformat = d;
63 }
64 
65 int
cell_getprecision(double d)66 cell_getprecision(double d) {
67 	double t;
68 	int i,x;
69 	int count;
70 
71 
72 	// printf("precision: for number: %f\n",d);
73 	if (d < 0) d *= -1;
74 	i = (int)d;
75 	t = d - (double)i;
76 	if (t <= 0) {
77 		return 0;
78 	}
79 	count = 0;
80 	for (x = 6; x > 1; x--) {
81 		i = (int)d;
82 		t = d - (double)i;
83 		t *= pow(10,x - 2);
84 		i = (int)t;
85 		t = t - (double)i;
86 		t *= 10;
87 		i = (int)t;
88 		if (i > 0) break;
89 		count++;
90 	}
91 	return (5 - count);
92 }
93 
94 char *
cell_data_string(book * book,sheet * sh,int row,int col)95 cell_data_string(book *book, sheet *sh, int row, int col) {
96 	time_t date;
97 	struct tm *tmptr;
98 	cell *c;
99 	char *str;
100 	char *format;
101 	int precision;
102 	int utcOffsetDays = 25569;
103 	int sInADay = 24 * 60 * 60;
104 
105 	c = sh->cells[row][col];
106 	if (c == NULL) return NULL;
107 
108 	switch (c->type) {
109 		case CELL_LABEL:
110 			return c->value.c;
111 
112 		case CELL_NUMBER:
113 			str = mymalloc(50);
114 			// printf("\nUsing format: %d\n",c->xfindex);
115 			if (book->xfrecords[c->xfindex] != NULL &&
116 				book->xfrecords[c->xfindex]->type == DATEFORMAT) {
117 
118 				format = (char *) book->xfrecords[c->xfindex]->format;
119 				// printf("format is: %s\n",format);
120 				date = (time_t) ((c->value.d - utcOffsetDays) * sInADay);
121 				tmptr = gmtime(&date);
122 				if (dateformat) {
123 					strftime(str,1024,dateformat,tmptr);
124 				} else {
125 					strftime(str,1024,format,tmptr);
126 				}
127 			} else if (book->xfrecords[c->xfindex] != NULL &&
128 				book->xfrecords[c->xfindex]->type == NUMBERFORMAT) {
129 
130 				format = (char *) book->xfrecords[c->xfindex]->format;
131 				// printf("format is: %s\n",format);
132 				sprintf(str,format,c->value.d);
133 			} else {
134 				precision = cell_getprecision(c->value.d);
135 				sprintf(str,"%.*f",precision,c->value.d);
136 			}
137 			break;
138 
139 		case CELL_DATE:
140 			//c->value.i = (int) val;
141 			break;
142 
143 		case CELL_BOOLEAN:
144 			//c->value.i = (int) val;
145 			break;
146 
147 		case CELL_ERROR:
148 			break;
149 
150 	}
151 	return str;
152 
153 }
154 
155 cell *
cell_number(int col,int row,int index,double d)156 cell_number(int col, int row, int index, double d) {
157 	cell *c;
158 	c = mymalloc(sizeof(*c));
159 	c->row = row;
160 	c->col = col;
161 	c->xfindex = index;
162 	c->type = CELL_NUMBER;
163 	c->value.d = d;
164 	return c;
165 }
166 
167 cell *
cell_label(int col,int row,char * str)168 cell_label(int col, int row, char *str) {
169 	cell *c;
170 	c = mymalloc(sizeof(*c));
171 	c->row = row;
172 	c->col = col;
173 	// c->xfindex = index;
174 	c->type = CELL_LABEL;
175 	c->value.c = str;
176 	return c;
177 }
178 
179 cell *
cell_set(int row,int col,int type,void * val)180 cell_set(int row, int col, int type, void *val) {
181 	cell *c;
182 	c = mymalloc(sizeof(*c));
183 	c->row  = row;
184 	c->col  = col;
185 	c->type = type;
186 	switch (type) {
187 		case CELL_LABEL:
188 			printf("Setting Cell %d,%d: %s\n",c->row,c->col, (char *) val);
189 			c->value.c = (char *) val;
190 			break;
191 
192 		/*
193 		case CELL_NUMBER:
194 			printf("Setting Cell %d,%d: %f\n",c->row,c->col, (double *) val);
195 			c->value.d = (double *) val;
196 			break;
197 		*/
198 		case CELL_DATE:
199 			c->value.i = (int) val;
200 			break;
201 
202 		case CELL_BOOLEAN:
203 			c->value.i = (int) val;
204 			break;
205 
206 		case CELL_ERROR:
207 			break;
208 
209 	}
210 	return c;
211 }
212 
213 void *
cell_get(sheet * sheet,int row,int col)214 cell_get(sheet *sheet, int row, int col) {
215 	cell *c;
216 	c = sheet->cells[row][col];
217 
218 	switch (c->type) {
219 		case CELL_LABEL:
220 			return ((void *) c->value.c);
221 		/*
222 		case CELL_NUMBER:
223 			return ((void *) c->value.d);
224 		*/
225 		case CELL_DATE:
226 			return ((void *) c->value.i);
227 
228 		case CELL_BOOLEAN:
229 			return ((void *) c->value.i);
230 
231 		case CELL_ERROR:
232 			return ((void *) c->value.i);
233 	}
234 	return NULL;
235 }
236