PAPI  5.3.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
libbif.c
Go to the documentation of this file.
1 /*
2  * Here is a very simple set of routines to write an Excel worksheet
3  * Microsoft BIFF format. The Excel version is set to 2.0 so that it
4  * will work with all versions of Excel.
5  *
6  * Author: Don Capps
7  */
8 
9 /*
10  * Note: rows and colums should not exceed 255 or this code will
11  * act poorly
12  */
13 
14 #ifdef Windows
15 #include <Windows.h>
16 #endif
17 #include <sys/types.h>
18 #include <stdio.h>
19 #include <sys/file.h>
20 #if defined(__AIX__) || defined(__FreeBSD__) || defined(__DragonFly__)
21 #include <fcntl.h>
22 #else
23 #include <sys/fcntl.h>
24 #endif
25 
26 #if defined(OSV5) || defined(linux) || defined (__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__DragonFly__)
27 #include <string.h>
28 #endif
29 
30 #if defined(linux) || defined(__DragonFly__) || defined(macosx)
31 #include <unistd.h>
32 #include <stdlib.h>
33 #endif
34 
35 #if (defined(solaris) && defined( __LP64__ )) || defined(__s390x__) || defined(FreeBSD)
36 /* If we are building for 64-bit Solaris, all functions that return pointers
37  * must be declared before they are used; otherwise the compiler will assume
38  * that they return ints and the top 32 bits of the pointer will be lost,
39  * causing segmentation faults. The following includes take care of this.
40  * It should be safe to add these for all other OSs too, but we're only
41  * doing it for Solaris now in case another OS turns out to be a special case.
42  */
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <unistd.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #endif
49 /* Little Endian */
50 #define ENDIAN_1 1
51 /* Big Endian */
52 #define ENDIAN_2 2
53 /* Middle Endian */
54 #define ENDIAN_3 3
55 /* Middle Endian */
56 #define ENDIAN_4 4
57 
58 int junk, *junkp;
59 
60 
61 #ifdef HAVE_ANSIC_C
62 /************************************************************************/
63 /* Here is the API... Enjoy */
64 /************************************************************************/
65 /* Create worksheet */
66 int create_xls(char *);
67 /* Args: Filename */
68 /* */
69 /* Close worksheet */
70 void close_xls(int);
71 /* Args: file descriptor */
72 /* */
73 /* Put a 16 bit integer in worksheet */
74 void do_int(int,int,int,int);
75 /* Args: file descriptor, */
76 /* value, */
77 /* row, */
78 /* column */
79 
80 /* Put a double in 8 byte float */
81 void do_float(int,double,int,int);
82 /* Args: file descriptor, */
83 /* value, */
84 /* row, */
85 /* column */
86 /* Put a string in worksheet */
87 void do_label(int,char *,int,int);
88 /* Args: file descriptor, */
89 /* string, */
90 /* row, */
91 /* column */
92 /************************************************************************/
93 
94 char libbif_version[] = "Libbif Version $Revision$";
95 void do_eof(int ); /* Used internally */
96 void do_header(int ); /* Used internally */
97 int endian(void);
98 #endif
99 
100 #define BOF 0x9
101 #define INTEGER 0x2
102 #define FLOAT 0x3
103 #define LABEL 0x4
104 #define EXCEL_VERS 0x2
105 #define WORKSHEET 0x10
106 
107 struct bof_record{ /* Beginning of file */
108  char hi_opcode;
109  char lo_opcode;
110  char hi_length;
111  char lo_length;
112  char hi_version; /* Excel version */
116  };
117 struct int_record {
118  char hi_opcode; /* Type 2 of record */
119  char lo_opcode;
120  char hi_length;
121  char lo_length;
122  char hi_row;
123  char lo_row;
124  char hi_column;
125  char lo_column;
126  char rgbhi;
127  char rgbmed;
128  char rgblo;
129  char hi_data;
130  char lo_data;
131  };
132 struct label_record {
133  char hi_opcode; /* Type 4 of record */
134  char lo_opcode;
135  char hi_length;
136  char lo_length;
137  char hi_row;
138  char lo_row;
139  char hi_column;
140  char lo_column;
141  char rgbhi;
142  char rgbmed;
143  char rgblo;
145  char str_array[256];
146  };
147 struct float_record { /* Type 3 record */
148  char hi_opcode;
149  char lo_opcode;
150  char hi_length;
151  char lo_length;
152  char hi_row;
153  char lo_row;
154  char hi_column;
155  char lo_column;
156  char rgbhi;
157  char rgbmed;
158  char rgblo;
159  double data;
160  };
161 /*
162  * Write the EOF and close the file
163  */
164 #ifdef HAVE_ANSIC_C
165 void
166 close_xls(int fd)
167 {
168 #else
169 close_xls(fd)
170 int fd;
171 {
172 #endif
173  do_eof(fd);
174  close(fd);
175 }
176 
177 /*
178  * Create xls worksheet. Create file and put the BOF record in it.
179  */
180 #ifdef HAVE_ANSIC_C
181 int
182 create_xls(char *name)
183 {
184 #else
185 create_xls(name)
186 char *name;
187 {
188 #endif
189  int fd;
190  unlink(name);
191 #ifdef Windows
192  fd=open(name,O_BINARY|O_CREAT|O_RDWR,0666);
193 #else
194  fd=open(name,O_CREAT|O_RDWR,0666);
195 #endif
196  if(fd<0)
197  {
198  printf("Error opening file %s\n",name);
199  exit(-1);
200  }
201  do_header(fd);
202  return(fd);
203 }
204 
205 #ifdef HAVE_ANSIC_C
206 void
207 do_header(int fd) /* Stick the BOF at the beginning of the file */
208 {
209 #else
210 do_header(fd)
211 int fd;
212 {
213 #endif
214  struct bof_record bof;
216  bof.lo_opcode = 0x0;
217  bof.hi_length=0x4;
218  bof.lo_length=0x0;
219  bof.hi_version=EXCEL_VERS;
220  bof.lo_version=0x0;
221  bof.hi_filetype=WORKSHEET;
222  bof.lo_filetype=0x0;
223  junk=write(fd,&bof,sizeof(struct bof_record));
224 }
225 
226 /*
227  * Put an integer (16 bit) in the worksheet
228  */
229 #ifdef HAVE_ANSIC_C
230 void
231 do_int(int fd,int val, int row, int column)
232 {
233 #else
234 do_int(fd,val,row,column)
235 int fd,val,row,column;
236 {
237 #endif
238  struct int_record intrec;
239  short s_row,s_column;
240  s_row=(short)row;
241  s_column=(short)column;
242  intrec.hi_opcode=INTEGER;
243  intrec.lo_opcode=0x00;
244  intrec.hi_length=0x09;
245  intrec.lo_length=0x00;
246  intrec.rgbhi=0x0;
247  intrec.rgbmed=0x0;
248  intrec.rgblo=0x0;
249  intrec.hi_row=(char)s_row&0xff;
250  intrec.lo_row=(char)(s_row>>8)&0xff;
251  intrec.hi_column=(char)(s_column&0xff);
252  intrec.lo_column=(char)(s_column>>8)&0xff;
253  intrec.hi_data=(val & 0xff);
254  intrec.lo_data=(val & 0xff00)>>8;
255  junk=write(fd,&intrec,13);
256 }
257 
258 /* Note: This routine converts Big Endian to Little Endian
259  * and writes the record out.
260  */
261 
262 /*
263  * Put a double in the worksheet as 8 byte float in IEEE format.
264  */
265 #ifdef HAVE_ANSIC_C
266 void
267 do_float(int fd, double value, int row, int column)
268 {
269 #else
270 do_float(fd, value, row, column)
271 int fd;
272 double value;
273 int row,column;
274 {
275 #endif
276  struct float_record floatrec;
277  short s_row,s_column;
278  unsigned char *sptr,*dptr;
279  s_row=(short)row;
280  s_column=(short)column;
281  floatrec.hi_opcode=FLOAT;
282  floatrec.lo_opcode=0x00;
283  floatrec.hi_length=0xf;
284  floatrec.lo_length=0x00;
285  floatrec.rgbhi=0x0;
286  floatrec.rgbmed=0x0;
287  floatrec.rgblo=0x0;
288  floatrec.hi_row=(char)(s_row&0xff);
289  floatrec.lo_row=(char)((s_row>>8)&0xff);
290  floatrec.hi_column=(char)(s_column&0xff);
291  floatrec.lo_column=(char)((s_column>>8)&0xff);
292  sptr =(unsigned char *) &value;
293  dptr =(unsigned char *) &floatrec.data;
294 
295  if(endian()==ENDIAN_2) /* Big Endian */
296  {
297  dptr[0]=sptr[7]; /* Convert to Little Endian */
298  dptr[1]=sptr[6];
299  dptr[2]=sptr[5];
300  dptr[3]=sptr[4];
301  dptr[4]=sptr[3];
302  dptr[5]=sptr[2];
303  dptr[6]=sptr[1];
304  dptr[7]=sptr[0];
305  }
306  if(endian()==ENDIAN_3) /* Middle Endian */
307  {
308  dptr[0]=sptr[4]; /* 16 bit swapped ARM */
309  dptr[1]=sptr[5];
310  dptr[2]=sptr[6];
311  dptr[3]=sptr[7];
312  dptr[4]=sptr[0];
313  dptr[5]=sptr[1];
314  dptr[6]=sptr[2];
315  dptr[7]=sptr[3];
316  }
317 
318  if(endian()==ENDIAN_1) /* Little Endian */
319  {
320  dptr[0]=sptr[0]; /* Do not convert to Little Endian */
321  dptr[1]=sptr[1];
322  dptr[2]=sptr[2];
323  dptr[3]=sptr[3];
324  dptr[4]=sptr[4];
325  dptr[5]=sptr[5];
326  dptr[6]=sptr[6];
327  dptr[7]=sptr[7];
328  }
329  if(endian()==-1) /* Unsupported architecture */
330  {
331  dptr[0]=0;
332  dptr[1]=0;
333  dptr[2]=0;
334  dptr[3]=0;
335  dptr[4]=0;
336  dptr[5]=0;
337  dptr[6]=0;
338  dptr[7]=0;
339  printf("Excel output not supported on this architecture.\n");
340  }
341  junk=write(fd,&floatrec,11); /* Don't write floatrec. Padding problems */
342  junk=write(fd,&floatrec.data,8); /* Write value seperately */
343 }
344 
345 /*
346  * Put a string as a label in the worksheet.
347  */
348 #ifdef HAVE_ANSIC_C
349 void
350 do_label(int fd, char *string, int row, int column)
351 {
352 #else
353 do_label(fd, string, row, column)
354 int fd;
355 char *string;
356 int row,column;
357 {
358 #endif
359  struct label_record labelrec;
360  short s_row,s_column;
361  int i;
362  for(i=0;i<255;i++)
363  labelrec.str_array[i]=0;
364  s_row=(short)row;
365  s_column=(short)column;
366  i=strlen(string);
367  labelrec.hi_opcode=LABEL;
368  labelrec.lo_opcode=0x00;
369  labelrec.hi_length=0x08; /* 264 total bytes */
370  labelrec.lo_length=0x01;
371  labelrec.rgblo=0x0;
372  labelrec.rgbmed=0x0;
373  labelrec.rgbhi=0x0;
374  labelrec.hi_row=(char)(s_row&0xff);
375  labelrec.lo_row=(char)((s_row>>8)&0xff);
376  labelrec.hi_column=(char)(s_column&0xff);
377  labelrec.lo_column=(char)((s_column>>8)&0xff);
378  labelrec.string_length=i;
379  if(i > 255) /* If too long then terminate it early */
380  string[254]=0;
381  i=strlen(string);
382  strcpy(labelrec.str_array,string);
383 
384  junk=write(fd,&labelrec,sizeof(struct label_record));
385 
386 }
387 
388 /*
389  * Write the EOF in the file
390  */
391 #ifdef HAVE_ANSIC_C
392 void
393 do_eof(int fd)
394 {
395 #else
396 do_eof(fd)
397 int fd;
398 {
399 #endif
400  char buf[]={0x0a,0x00,0x00,0x00};
401  junk=write(fd,buf,4);
402 }
403 
404 /*
405  * Routine to determine the Endian-ness of the system. This
406  * is needed for Iozone to convert doubles (floats) into
407  * Little-endian format. This is needed for Excel to be
408  * able to interpret the file
409  */
410 int
411 endian(void)
412 {
413  long long foo = 0x0102030405060708LL;
414  long foo1 = 0x012345678;
415  unsigned char *c,c1,c2,c3,c4,c5,c6,c7,c8;
416  c=(unsigned char *)&foo;
417  c1=*c++;
418  c2=*c++;
419  c3=*c++;
420  c4=*c++;
421  c5=*c++;
422  c6=*c++;
423  c7=*c++;
424  c8=*c;
425 
426  /*--------------------------------------------------------------*/
427  /* printf("%x %x %x %x %x %x %x %x\n",c1,c2,c3,c4,c5,c6,c7,c8); */
428  /*--------------------------------------------------------------*/
429 
430  /* Little Endian format ? ( Intel ) */
431  if( (c1==0x08) && (c2==0x07) && (c3==0x06) && (c4==0x05) &&
432  (c5==0x04) && (c6==0x03) && (c7==0x02) && (c8==0x01) )
433  return(ENDIAN_1);
434  /* Big Endian format ? ( Sparc, Risc... */
435  if( (c1==0x01) && (c2==0x02) && (c3==0x03) && (c4==0x04) &&
436  (c5==0x05) && (c6==0x06) && (c7==0x07) && (c8==0x08) )
437  return(ENDIAN_2);
438  /* Middle Endian format ? ( ARM ... ) */
439  if( (c1==0x04) && (c2==0x03) && (c3==0x02) && (c4==0x01) &&
440  (c5==0x08) && (c6==0x07) && (c7==0x06) && (c8==0x05) )
441  return(ENDIAN_3);
442  c=(unsigned char *)&foo1;
443  c1=*c++;
444  c2=*c++;
445  c3=*c++;
446  c4=*c++;
447  /* Another middle endian format ? ( PDP-11 ... ) */
448  if( (c1==0x34) && (c2==0x12) && (c3==0x78) && (c4==0x56))
449  return(ENDIAN_4);
450 
451  return(-1);
452 }
char hi_length
Definition: libbif.c:135
int * junkp
Definition: fileop.c:77
char rgbmed
Definition: libbif.c:127
int val
Definition: libbif.c:235
char lo_opcode
Definition: libbif.c:149
char lo_opcode
Definition: libbif.c:134
int close(int fd)
Definition: appio.c:175
char hi_row
Definition: libbif.c:152
char lo_filetype
Definition: libbif.c:115
#define FLOAT
Definition: libbif.c:102
char lo_row
Definition: libbif.c:153
void do_label()
char hi_data
Definition: libbif.c:129
char rgbmed
Definition: libbif.c:157
char lo_version
Definition: libbif.c:113
unsigned char * dptr
Definition: libbif.c:278
char lo_length
Definition: libbif.c:121
char rgbhi
Definition: libbif.c:156
char lo_column
Definition: libbif.c:155
int fd
Definition: iozone.c:1291
short s_column
Definition: libbif.c:236
char hi_opcode
Definition: libbif.c:148
#define BOF
Definition: libbif.c:100
char hi_length
Definition: libbif.c:150
#define WORKSHEET
Definition: libbif.c:105
char hi_filetype
Definition: libbif.c:114
char hi_column
Definition: libbif.c:124
char lo_column
Definition: libbif.c:125
char lo_length
Definition: libbif.c:136
#define printf
Definition: papi_test.h:125
double c
Definition: multiplex.c:22
void double value
Definition: iozone.c:18781
void do_float()
char hi_opcode
Definition: libbif.c:118
unsigned char * sptr
Definition: libbif.c:278
char hi_column
Definition: libbif.c:139
char rgblo
Definition: libbif.c:158
int open(const char *pathname, int flags, mode_t mode)
Definition: appio.c:184
int i
Definition: fileop.c:140
char lo_opcode
Definition: libbif.c:109
char buf[200]
Definition: iozone.c:19609
ssize_t write(int fd, const void *buf, size_t count)
Definition: appio.c:298
#define ENDIAN_4
Definition: libbif.c:56
char lo_column
Definition: libbif.c:140
char rgblo
Definition: libbif.c:128
char hi_row
Definition: libbif.c:122
int junk
Definition: fileop.c:77
char string_length
Definition: libbif.c:144
char hi_length
Definition: libbif.c:120
char rgbhi
Definition: libbif.c:126
do_header(fd)
pthread_attr_t foo
Definition: iozone.c:18592
int column
Definition: libbif.c:235
int row
Definition: libbif.c:235
#define ENDIAN_3
Definition: libbif.c:54
double data
Definition: libbif.c:159
char lo_length
Definition: libbif.c:151
#define ENDIAN_1
Definition: libbif.c:50
#define INTEGER
Definition: libbif.c:101
char lo_data
Definition: libbif.c:130
char rgblo
Definition: libbif.c:143
char hi_opcode
Definition: libbif.c:108
strcpy(filename, default_filename)
#define ENDIAN_2
Definition: libbif.c:52
char hi_opcode
Definition: libbif.c:133
char lo_row
Definition: libbif.c:138
#define EXCEL_VERS
Definition: libbif.c:104
char * name
Definition: iozone.c:23648
char str_array[256]
Definition: libbif.c:145
void close_xls()
int
Definition: iozone.c:18528
char lo_row
Definition: libbif.c:123
char hi_length
Definition: libbif.c:110
char rgbhi
Definition: libbif.c:141
char hi_version
Definition: libbif.c:112
char lo_length
Definition: libbif.c:111
short s_row
Definition: libbif.c:236
char lo_opcode
Definition: libbif.c:119
int unlink()
void exit()
char rgbmed
Definition: libbif.c:142
int create_xls()
int endian(void)
Definition: libbif.c:411
char hi_row
Definition: libbif.c:137
#define LABEL
Definition: libbif.c:103
char hi_column
Definition: libbif.c:154