Fork me on GitHub

source: svn/trunk/Utilities/mcfio/mcf_NTuIOFiles.c@ 633

Last change on this file since 633 was 3, checked in by Xavier Rouby, 16 years ago

first commit

File size: 33.3 KB
RevLine 
[3]1/*******************************************************************************
2* *
3* mcf_NTuIOFiles.c -- Utilities to manipulate files within the MCFIO Gen. *
4* Ntuple schema *
5* *
6* P. Lebrun, September 1995. *
7* *
8*******************************************************************************/
9#include <stdio.h>
10#include <string.h>
11#include <stdlib.h>
12#include <sys/param.h>
13#include <limits.h>
14#include <time.h>
15#include <rpc/types.h>
16#include <sys/types.h>
17#include <rpc/xdr.h>
18#include <unistd.h>
19#include <ctype.h>
20#include "mcf_nTupleDescript.h"
21#include "mcf_xdr.h"
22#include "mcfio_Dict.h"
23#include "mcfio_Direct.h"
24#include "mcfio_Util1.h"
25#include "mcf_NTuIOFiles.h"
26#include "mcf_NTuIOUtils.h"
27#include "mcf_ntubld_db.h"
28#include "mcf_ntuBldDbinc.h"
29#ifndef False
30#define False 0
31#endif
32#ifndef True
33#define True 1
34#endif
35
36extern char *VarTypesNamesF77[N_VAR_TYPES];
37extern char *VarTypesNamesC[N_VAR_TYPES];
38
39extern struct line_title_c line_title_c_;
40extern struct header_c header_c_;
41extern struct variable_c variable_c_;
42
43/*
44** Ntuple identifiers list, initialized here and in mcfio_Util1
45*/
46nTuDDL **NTuDDLList = NULL;
47int NumOfNTuples = 0;
48bool_t McfNTuPleSaveDecoding = True;
49
50static char *makeStructName(char *title, int orgStyle);
51static size_t nDatVariable(varGenNtuple *varTmp);
52static size_t sizeVariable(varGenNtuple *varTmp);
53static char *mcf_copyNtrim(char *fromString);
54
55int mcfioC_DeclareNtuple(int uid, char *title, char *category,
56 int stream, char *filename)
57{
58 nTuDDL *ddl, *ddlRef;
59 int i, j, jstr, dejaVu, id, **ip;
60
61
62 if ((stream < 1) || (stream > MCF_STREAM_NUM_MAX)) {
63 fprintf(stderr,
64 " mcfio_NtupleDDLRead: Illegal MCFIO stream number.\n");
65 return -1;
66 }
67 jstr = stream-1;
68 if (McfStreamPtrList[jstr] == NULL) {
69 fprintf(stderr,
70 " mcfio_DeclareNtuple: First, declare the stream by calling mcfio_Open...\n");
71 return -1;
72 }
73
74 if (McfStreamPtrList[jstr]->row != MCFIO_WRITE) {
75 fprintf(stderr,
76 " mcfio_DeclareNtuple: You must declare an Ntuple for an Output Stream\n");
77 return -1;
78 }
79
80 if (!mcf_CheckValidCat(category, False)) return 0;
81
82 /* Check that this item characterized by uid/Category has not already been
83 created. If so, do not create a new one. If associated to the same
84 stream, flag this as an error. */
85
86 id = mcf_NTuId(uid, category);
87 if (id != -1) {
88 ddl = mcf_GetNTuByPtrID(id);
89 if (ddl->streamId == stream) {
90 fprintf(stderr,
91 "Mcfio Declare Ntuple: An item with this uid/Category already exists.\n");
92 fprintf(stderr, " uid = %d, Category = %s, ", uid, category);
93 fprintf(stderr, "Ntuple not created.\n");
94 return -1;
95 }
96 }
97 /*
98 ** May be this dbin template has already been digested. If so, refer
99 ** to it, to avoid re-computing all the offsets.
100 */
101 ip = (int **) NTuDDLList;
102 for (i=0, dejaVu=False; i< NumOfNTuples; i++, ip++) {
103 ddlRef = (nTuDDL *) *ip;
104 if ((ddlRef->dbinFileName != NULL) &&
105 (strcmp(filename, ddlRef->dbinFileName) == 0)) {
106 dejaVu = True;
107 /* Create a holder for this Ntuple Description */
108 ddl = (nTuDDL * ) malloc(sizeof(nTuDDL));
109 /*
110 ** back up in the linked list if need be, until we
111 ** a fully documented descriptor.
112 */
113 while (ddlRef->descrNtu == NULL) ddlRef = ddlRef->reference;
114 ddl->reference = ddlRef;
115 ddl->descrNtu = NULL;
116 ddl->dbinFileName = NULL;
117 break;
118 }
119 }
120 if (dejaVu == False) {
121 ddl = mcf_GetFileNTuDDL(filename);
122 if (ddl == NULL) {
123 fprintf(stderr,
124 " mcfio_NtupleDDLRead: Error reading %s\n", filename );
125 return -1;
126 }
127 ddl->reference = NULL;
128 }
129 ddl->title = mcf_copyNtrim(mcf_ValidStr(title, NTU_MAX_TITLE_LENGTH,
130 "title"));
131 if (category == NULL)
132 ddl->category =
133 mcf_copyNtrim(mcf_ValidStr(category, NTU_MAX_CATEGORY_LENGTH,
134 "category"));
135 else {
136 ddl->category = mcf_copyNtrim(category);
137 }
138 AddNTuDDLtoList(ddl);
139/*
140** Now we compute the offssets.
141*/
142 if (dejaVu == False) {
143 mcf_ComputeNTuOffsets(ddl);
144/*
145** Now we compute the lengths..
146*/
147 mcf_ComputeNTuLengths(ddl);
148 }
149 ddl->uid = uid;
150 ddl->streamId = stream;
151 /*
152 ** Set the sequential id for this particular stream
153 */
154 for (i=0, j=0; i<NumOfNTuples; i++)
155 if (NTuDDLList[i]->streamId == ddl->streamId) j++;
156 ddl->seqNTuId = j;
157 (McfStreamPtrList[jstr]->fhead->nNTuples)++;
158 return ddl->seqNTuId;
159}
160
161int mcfioC_EndDeclNTuples(int stream)
162/*
163** Routine to end theNtuple delcaration and rewrite the beginning of the
164** file.
165*/
166{
167 int i, jstr;
168 u_int p1;
169 FILE *ff;
170 mcfStream *str;
171
172 if (McfStreamPtrList == NULL) {
173 fprintf(stderr,
174 " mcfio_EndDeclNtuple: No stream open, No inialization.\n");
175 return -1;
176 }
177 jstr = stream-1;
178 if (McfStreamPtrList[jstr] == NULL) {
179 fprintf(stderr,
180 " mcfio_EndDeclNtuple: First, declare the stream by calling mcfio_Open...\n");
181 return -1;
182 }
183 str = McfStreamPtrList[jstr];
184 if (str->row != MCFIO_WRITE) {
185 fprintf(stderr,
186 " mcfio_EndDeclNtuple: This routine is not applicable to Input streams...\n");
187 return -1;
188 }
189 if (str->fhead->nNTuples < 1) {
190 fprintf(stderr,
191 " mcfio_EndDeclNtuple: No Ntuple declared for this stream...\n");
192 return 0;
193 }
194 /*
195 ** Now we can try toto complete the file header. As it is now bigger,
196 ** and it is the first structure written, it is easier to start over.
197 ** Destroy the XDR stream, close the file, and reopen it.
198 */
199 xdr_destroy(str->xdr);
200 fclose(str->filePtr);
201 remove(str->filename);
202 ff = fopen(str->filename, "w");
203 if (ff == NULL) {
204 fprintf(stderr,
205 " mcfio_EndDeclNtuple: Problem re-opening file %s, message \n",
206 str->filename);
207 return -1;
208 }
209 xdrstdio_create(str->xdr, ff, XDR_ENCODE);
210 p1 = xdr_getpos(str->xdr);
211 str->firstPos = p1;
212 str->currentPos = p1;
213 /*
214 ** In the file header, we do not store the NTuple Ids, as they are
215 ** not necessarily valid in an other context, where we have different
216 ** streams/NTuples combinations. The SeqNTuId are trivial,
217 ** within a stream, at the file header (1,2,3,..)
218 ** But, of course, we must provide an array for the event header..
219 */
220 str->ehead->dimNTuples = str->fhead->nNTuples;
221 str->ehead->nNTuples = 0;
222 str->ehead->nTupleIds =
223 (int *) malloc(sizeof(int) * str->fhead->nNTuples);
224
225 str->ehead->ptrNTuples =
226 (u_int *) malloc(sizeof(u_int) * str->fhead->nNTuples);
227 for (i=0; i<str->ehead->dimNTuples; i++) str->ehead->ptrNTuples[i]=0;
228
229 str->status = MCFIO_BOF;
230 if (mcfioC_Wrtfhead(str, INITIATE) == FALSE){
231 mcfioC_FreeStream(&McfStreamPtrList[jstr]);
232 fclose(ff);
233 return -1;
234 }
235 /*
236 ** Write the first dummy table
237 */
238 if (mcfioC_Wrttable(str, INITIATE) == FALSE) return -1;
239 /*
240 ** Write the first dummy event header
241 */
242 if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
243 str->ehead->evtnum = 0;
244 str->status = MCFIO_RUNNING;
245 return (str->fhead->nNTuples);
246}
247
248nTuDDL *mcf_GetFileNTuDDL(char*filename)
249{
250 nTuDDL *ddl;
251 int i, l, j;
252 char *text, *tc;
253 varGenNtuple *varTmp;
254 descrGenNtuple *dNTu;
255
256 /* Create a holder for this Ntuple Description */
257 ddl = (nTuDDL * ) malloc(sizeof(nTuDDL));
258 ddl->dbinFileName = (char *) malloc(sizeof(char) * (strlen(filename) +1));
259 strcpy(ddl->dbinFileName, filename);
260 ddl->descrNtu = (descrGenNtuple *) malloc(sizeof(descrGenNtuple));
261 dNTu = ddl->descrNtu;
262
263 header_c_.n_obj_header = 0;
264 line_title_c_.n_obj_line_title = 0;
265 mcf_ntubldRead(filename);
266 if ((line_title_c_.n_obj_line_title < 1) ||
267 (header_c_.n_obj_header != 1)) {
268 fprintf(stderr,
269 " This file was not created by the ntuBuild aplication!");
270 return NULL;
271 }
272 if (strcmp(line_title_c_.line_title[0].line,
273 "ntuBuild Database, v1.0") != 0) {
274 fprintf(stderr,
275 " This file was not created by a wrong version of ntuBuild!");
276 return NULL;
277 }
278 /*
279 ** There are 80 character per lines in dbin..
280 */
281 text = (char *)
282 malloc(sizeof(char) * 80 * (line_title_c_.n_obj_line_title -1));
283 for (i=1, tc=text; i<line_title_c_.n_obj_line_title; i++) {
284 strcpy(tc, line_title_c_.line_title[i].line);
285 tc += strlen(line_title_c_.line_title[i].line);
286 *tc = '\n'; tc++;
287 }
288 *tc = '\0';
289 dNTu->description = text;
290
291 l = strlen(header_c_.header[0].title);
292 dNTu->title = (char *) malloc(sizeof(char) * (l+1));
293 strcpy(dNTu->title, header_c_.header[0].title);
294
295 strcpy(dNTu->version, header_c_.header[0].version);
296
297 strcpy(dNTu->nameIndex, header_c_.header[0].namemaxindex);
298
299 dNTu->maxMultiplicity = header_c_.header[0].maxmult;
300
301 dNTu->orgStyle = header_c_.header[0].orgstyle;
302 dNTu->numVariables = header_c_.header[0].nvar;
303 dNTu->numAvailable = dNTu->numVariables;
304 dNTu->variables =
305 (varGenNtuple **) malloc(sizeof(varGenNtuple *) * dNTu->numVariables);
306 /*
307 ** Now the variables
308 */
309 for (i=0; i<variable_c_.n_obj_variable; i++) {
310 dNTu->variables[i] =
311 (varGenNtuple *) malloc(sizeof(varGenNtuple));
312 varTmp = dNTu->variables[i];
313 varTmp->nameBlank = False;
314 varTmp->name = (char *)
315 malloc(sizeof(char) * (strlen(variable_c_.variable[i].name) + 1));
316 strcpy(varTmp->name, variable_c_.variable[i].name);
317
318 if ((strlen(variable_c_.variable[i].description) > 1) ||
319 variable_c_.variable[i].description[0] != ' ') {
320 varTmp->description = (char *) malloc(sizeof(char) *
321 (strlen(variable_c_.variable[i].description) + 1));
322 strcpy(varTmp->description, variable_c_.variable[i].description);
323 } else varTmp->description = NULL;
324 varTmp->type = variable_c_.variable[i].type;
325 varTmp->isFixedSize = True;
326 if (strncmp(variable_c_.variable[i].isfixedsize,"Yes",3))
327 varTmp->isFixedSize = False;
328 varTmp->numDim = variable_c_.variable[i].numdim;
329 if (varTmp->numDim > 0)
330 for (j=0; j< varTmp->numDim; j++)
331 varTmp->dimensions[j] = variable_c_.variable[i].dimensions[j];
332
333 }
334 /*
335 ** Set the ordering. Trivial in this case, it has been ordered in
336 ** the save routine.
337 */
338 dNTu->varOrdering = (int *) malloc(sizeof(int) * dNTu->numAvailable);
339 for (i=0; i<dNTu->numVariables; i++)
340 dNTu->varOrdering[i] = i;
341 dNTu->subOffset = NULL;
342 dNTu->subXDROffset = NULL;
343 return ddl;
344
345}
346
347/*
348** Compute the offsets by writing a simple program, stand alone, that uses
349** the d/s
350*/
351void mcf_ComputeNTuOffsets(nTuDDL *ddl)
352{
353 char tmpName[128], *tc, *tc1, *nameCom;
354 int i, j, l, fd, firstIndexed, nDat;
355 char filenameInclude[128], filenameProgram[128], filenameExec[128];
356 char filenameData[128], nameMaxIndex[32];
357 char line[256];
358 void **ptrBegVar;
359 varGenNtuple *varTmp;
360 descrGenNtuple *dNTu;
361 FILE *Ffp;
362
363 dNTu =ddl->descrNtu;
364 for (i=0; i< dNTu->numVariables; i++) {
365 varTmp = dNTu->variables[i];
366 varTmp->offset = 0;
367 }
368
369 memset(tmpName, 0, 127);
370 tc = tmpName;
371 sprintf(tc, "tmp_%s_XXXXXX", ddl->descrNtu->title);
372/* this is a kludge - we create a temporary file, close it, and use the name */
373 fd = mkstemp(tmpName);
374 if ( fd < 0 ) {
375 fprintf(stderr,
376 " Can not compose a tempoary name in mcf_ComputeOffsets!");
377 return;
378 }
379 tc1 = tc;
380 close(fd);
381 sprintf(filenameInclude, "%s.h", tc1);
382 sprintf(filenameProgram, "%s.c", tc1);
383 sprintf(filenameData, "%s.dat", tc1);
384 strcpy(filenameExec, tc1);
385 mcf_ComposeDoth(ddl->descrNtu, filenameInclude);
386/*
387** Compose a little moronic program that establishes the addresses of all
388** variables. There might be a better way, though.. However, this ought to be
389** safe.
390*/
391 Ffp = fopen( filenameProgram, "w");
392 fprintf(Ffp, "#include <stdio.h>\n");
393 fprintf(Ffp, "#include \"%s\"\n",filenameInclude);
394 if (dNTu->orgStyle == PARALLEL_ARRAY_NTU)
395 fprintf(Ffp, "#define NUM_VAR %d\n", (dNTu->numVariables+3));
396 else
397 fprintf(Ffp, "#define NUM_VAR %d\n",
398 (dNTu->numVariables + 3 + dNTu->maxMultiplicity) );
399
400 nameCom = makeStructName(dNTu->title, dNTu->orgStyle);
401
402 fprintf(Ffp, "%s_struct tmpStruct; \n", nameCom);
403 fprintf(Ffp, "main(int argc, char **argv)\n");
404 fprintf(Ffp, "{\n");
405 fprintf(Ffp, " void *ptrBegVar[NUM_VAR];\n");
406 fprintf(Ffp, " FILE *Ffp;\n");
407 fprintf(Ffp, " int i;\n");
408 fprintf(Ffp, "\n");
409 fprintf(Ffp, " ptrBegVar[0] = (void *) &tmpStruct.version[0];\n");
410 fprintf(Ffp,
411 " ptrBegVar[1] = (void *) &tmpStruct.%s;\n",dNTu->nameIndex);
412 for(i=0, firstIndexed=-1; i<dNTu->numVariables; i++) {
413 if (dNTu->variables[i]->isFixedSize == False) {
414 firstIndexed = i; break;
415 }
416 }
417 dNTu->firstIndexed = firstIndexed;
418 if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
419 for(i=0; i<dNTu->numVariables; i++) {
420 varTmp = dNTu->variables[i];
421 /*
422 ** Assume that all the variables are properly
423 ** defined at this stage (e..g, coming from a valid DDL dbin file)
424 ** and in order
425 */
426 tc = line;
427 if ((varTmp->numDim == 0) && (varTmp->isFixedSize == True))
428 sprintf(tc,
429 " ptrBegVar[%d] = (void *) &tmpStruct.%s%n",
430 (i+2), varTmp->name, &l);
431 else
432 sprintf(tc,
433 " ptrBegVar[%d] = (void *) tmpStruct.%s%n",
434 (i+2), varTmp->name, &l);
435 tc+=l;
436 fprintf(Ffp, "%s;\n", line);
437 }
438 fprintf(Ffp,
439 " ptrBegVar[%d] = (void *) tmpStruct.fence;\n",dNTu->numVariables+2);
440 } else {
441 for(i=0; i<dNTu->numVariables; i++) {
442 varTmp = dNTu->variables[i];
443 tc = line;
444 if (varTmp->isFixedSize == True) {
445 if (varTmp->numDim == 0)
446 sprintf(tc,
447 " ptrBegVar[%d] = (void *) &tmpStruct.%s%n",
448 (i+2), varTmp->name, &l);
449 else
450 sprintf(tc,
451 " ptrBegVar[%d] = (void *) tmpStruct.%s%n",
452 (i+2), varTmp->name, &l);
453 } else {
454 if (varTmp->numDim == 0)
455 sprintf(tc,
456 " ptrBegVar[%d] = (void *) &tmpStruct.var[0].%s%n",
457 (i+2), varTmp->name, &l);
458 else
459 sprintf(tc,
460 " ptrBegVar[%d] = (void *) tmpStruct.var[0].%s%n",
461 (i+2), varTmp->name, &l);
462 }
463 fprintf(Ffp, "%s;\n", line);
464 }
465 tc1 = dNTu->nameIndex;
466 strcpy(nameMaxIndex, tc1);
467 l = strlen(tc1);
468 if (l > 26) {
469 strncpy(nameMaxIndex, tc1, 26);
470 sprintf(&nameMaxIndex[26],"_max");
471 } else
472 sprintf(nameMaxIndex, "%s_max", tc1);
473 fprintf(Ffp," for (i=0; i<%s; i++) \n", nameMaxIndex);
474 tc = line;
475 if (firstIndexed != -1) {
476 varTmp = dNTu->variables[firstIndexed];
477 sprintf(tc,
478 " ptrBegVar[i+%d] = (void *) &tmpStruct.var[i].%s%n",
479 (2+dNTu->numVariables), varTmp->name, &l); tc+=l;
480 if (varTmp->numDim > 0) for (j=0; j<varTmp->numDim; j++, tc+=l)
481 sprintf(tc, "[0]%n", &l);
482 fprintf(Ffp, "%s;\n", line);
483 }
484 fprintf(Ffp,
485 " ptrBegVar[%d] = (void *) tmpStruct.fence;\n",
486 dNTu->numVariables+2+dNTu->maxMultiplicity);
487 }
488 fprintf(Ffp, " ");
489 fprintf(Ffp," Ffp = fopen(\"%s\",\"w\");\n",filenameData);
490 fprintf(Ffp," fwrite((void *) ptrBegVar, sizeof(void *),\
491(size_t) NUM_VAR, Ffp);\n");
492 fprintf(Ffp," fclose(Ffp);\n");
493 fprintf(Ffp,"}\n");
494 fclose(Ffp);
495 free(nameCom);
496 /*
497 ** Now compile, link and load this exec, read the result
498 */
499 sprintf(line,"rm -f %s", filenameExec);
500 system(line);
501#ifdef _HPUX_SOURCE
502 sprintf(line,"cc -Aa -D_HPUX_SOURCE -o %s %s",
503 filenameExec, filenameProgram);
504#else
505 sprintf(line,"cc -o %s %s", filenameExec, filenameProgram);
506#endif
507 system(line);
508 sprintf(line,"./%s", filenameExec);
509 system(line);
510 if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) nDat = dNTu->numVariables+3;
511 else nDat = dNTu->numVariables+3+dNTu->maxMultiplicity;
512 if (firstIndexed == -1) nDat = dNTu->numVariables+3;
513 ptrBegVar = (void **) malloc (sizeof(void *) * (nDat));
514 Ffp = fopen(filenameData, "r");
515 fread((void *) ptrBegVar, sizeof(void *), (size_t) nDat, Ffp);
516 fclose(Ffp);
517 /*
518 ** remove garbage files..
519 */
520 remove(filenameData); remove(filenameProgram); remove(filenameExec);
521 remove(filenameInclude);
522 /*
523 ** Convert these addresses to offsets
524 */
525 dNTu->multOffset = ((long) ptrBegVar[1] - (long) ptrBegVar[0]);
526 if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
527 dNTu->fenceOffset =
528 ((long) ptrBegVar[dNTu->numVariables+2] - (long) ptrBegVar[0]);
529 for (i=0; i< dNTu->numVariables; i++)
530 dNTu->variables[i]->offset =
531 ((long) ptrBegVar[i+2] - (long) ptrBegVar[0]);
532 } else {
533 for (i=0; i< dNTu->numVariables; i++) {
534 varTmp = dNTu->variables[i];
535 if (varTmp->isFixedSize)
536 varTmp->offset =
537 ((long) ptrBegVar[i+2] - (long) ptrBegVar[0]);
538 else
539 varTmp->offset =
540 ((long) ptrBegVar[i+2] - (long)ptrBegVar[firstIndexed+2]);
541 }
542 if (dNTu->subOffset != NULL) free(dNTu->subOffset);
543 dNTu->subOffset =
544 (long *) malloc(sizeof(long) * dNTu->maxMultiplicity);
545 if (firstIndexed != -1) {
546 for (i=0; i<dNTu->maxMultiplicity; i++)
547 dNTu->subOffset[i] =
548 ((long) ptrBegVar[i+2+dNTu->numVariables] -
549 (long) ptrBegVar[0]);
550 }
551 dNTu->fenceOffset =
552 ((long) ptrBegVar[dNTu->numVariables+2+dNTu->maxMultiplicity]
553 - (long) ptrBegVar[0]);
554 }
555 free(ptrBegVar);
556}
557
558/*
559** Compute the lengths for the XDR Array statements. It is assumed that the
560** NTUple descriptor is sorted, no blank variables.
561*/
562void mcf_ComputeNTuLengths(nTuDDL *ddl)
563{
564 int i, j, lastTmp, sameType;
565 size_t nDat, sizeItem;
566 varGenNtuple *var1, *var2;
567 descrGenNtuple *dNTu;
568
569 dNTu =ddl->descrNtu;
570 if (dNTu->firstIndexed != -1) lastTmp = dNTu->firstIndexed;
571 else lastTmp = dNTu->numVariables;
572 /*
573 ** fixed size first..
574 */
575 for (i=0; i<lastTmp; i++)
576 dNTu->variables[i]->lengthW = nDatVariable(dNTu->variables[i]);
577/*
578** This, in principle, is the optimized version, where we collaps single
579** fields of the same type into an array. However, this is machine
580** dependant.
581*/
582 for (i=0; i<lastTmp; i++) {
583 var1 = dNTu->variables[i];
584 if (var1->lengthW != 0) {
585 nDat = nDatVariable(var1);
586 j=i+1;
587 sizeItem = sizeVariable(var1);
588 sameType = True;
589 while ((j<lastTmp) && (sameType)) {
590 var2 = dNTu->variables[j];
591 if (var2->type != var1->type) sameType = False;
592 if (sameType && ((( var2->offset -
593 var1->offset)/sizeItem) ==
594 nDat)) {
595 nDat += nDatVariable(var2);
596 var2->lengthW = 0; j++;
597 }
598 }
599 var1->lengthW = nDat;
600 var1->lengthB = nDat*sizeItem;
601 }
602 }
603 /*
604 ** The variable size, similar code. This fill is very simple if the
605 ** if the organisation is parallel arrays, as we can not implmenent
606 ** compaction
607 */
608 if (dNTu->firstIndexed == -1) return;
609 if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
610 for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) {
611 dNTu->variables[i]->lengthW
612 = nDatVariable(dNTu->variables[i]);
613 dNTu->variables[i]->lengthB = dNTu->variables[i]->lengthW
614 * sizeVariable(dNTu->variables[i]);
615 }
616 } else {
617 for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++)
618 dNTu->variables[i]->lengthW = nDatVariable(dNTu->variables[i]);
619 for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) {
620 var1 = dNTu->variables[i];
621 if (var1->lengthW != 0) {
622 nDat = nDatVariable(var1);
623 j=i+1;
624 sizeItem = sizeVariable(var1);
625 sameType = True;
626 while ((j<dNTu->numVariables) && (sameType)) {
627 var2 = dNTu->variables[j];
628 if (var2->type != var1->type) sameType = False;
629 if (sameType && (((var2->offset -
630 var1->offset)/sizeItem) ==
631 nDat)) {
632 nDat += nDatVariable(var2);
633 var2->lengthW = 0; j++;
634 }
635 }
636 var1->lengthW = nDat;
637 var1->lengthB = nDat*sizeItem;
638 }
639 }
640 }
641
642}
643/*
644** Compute, in size_t units (bytes, I hope) the length of a particular
645** variable. Only the fixed size part, we will have to multiplity
646** by the multiplicty in the XDR filter.
647*/
648
649static size_t nDatVariable(varGenNtuple *var)
650{
651 size_t n;
652 int i;
653
654 n=1;
655 for (i=0; i<var->numDim; i++) n = n * var->dimensions[i];
656 return n;
657}
658static size_t sizeVariable(varGenNtuple *var)
659{
660 size_t n;
661
662 switch (var->type) {
663 case BYTE_NTU: case CHARACTER_NTU:
664 n = sizeof(char);
665 break;
666 case INTEGER2_NTU:
667 n = sizeof(short);
668 break;
669 case LOGICAL_NTU: case INTEGER_NTU:
670 n = sizeof(int);
671 break;
672 case REAL_NTU:
673 n = sizeof(float);
674 break;
675 case DBL_PRECISION_NTU:
676 n = sizeof(double);
677 break;
678 case COMPLEX_NTU:
679 n = 2 * sizeof(float);
680 break;
681 case DBL_COMPLEX_NTU:
682 n = 2 * sizeof(double);
683 break;
684 case POINTER_NTU:
685 n = sizeof(void *);
686 break;
687 default :
688 fprintf(stderr, " mcf_ComputNTuLength, internal error \n");
689 n = 0;
690 break;
691 }
692 return n;
693}
694
695/*
696** Compose the .h file. Called from NTuBldMenu and this file. The structure
697** is assumed valid.
698*/
699void mcf_ComposeDoth(descrGenNtuple *dNTu, char *filename)
700{
701 char *nameCom, line[FILENAME_MAX+500], *tmp, *version, *text, *tc, *tc2;
702 char nameMaxIndex[32], nameTmpIndex[32];
703 char nullDescr[4], *descrTmp;
704 int i, j, l, kmode, nc, ncTot, nl, iv;
705 time_t clock;
706 FILE *Ffp;
707 varGenNtuple *var;
708
709 nameCom = makeStructName(dNTu->title, dNTu->orgStyle);
710 strcpy(nullDescr, "? ");
711 strcpy(line, filename);
712 tc = strchr(line, '.');
713 if (tc == NULL) {
714 l = strlen(filename);
715 tc = line; tc+=l;
716 }
717 strcpy(tc,".h");
718 Ffp = fopen(line, "w");
719 fprintf(Ffp,"/* ntuBuild\n");
720 time(&clock);
721 tmp = line; sprintf(tmp,"** Creation Date : %n", &l); tmp += l;
722 strncpy(tmp,ctime(&clock), 24); tmp += 24; *tmp='\n'; tmp++; *tmp = '\0';
723 fprintf(Ffp,line);
724 fprintf(Ffp,"** User Comments\n");
725 text = dNTu->description;
726 tc = text;
727 if (*tc == '\0')
728 fprintf(Ffp,"** no user comments\n");
729 else {
730 ncTot = strlen(tc); nc =0;
731 while (nc < ncTot) {
732 tc2 = strchr(tc,'\n');
733 nl = (int) (tc2-tc)/sizeof(char);
734 if ((tc2 == NULL) || (nl > 75)) nl = 75;
735 strncpy(line, tc, nl); line[nl] = '\0';
736 fprintf (Ffp,"** %s\n", line);
737 tc += nl; nc += nl;
738 if (*tc == '\n') {
739 tc++;
740 nc++;
741 }
742 }
743 }
744 fprintf(Ffp,"*/ \n");
745 version = dNTu->version;
746 text = dNTu->nameIndex;
747 strcpy(nameTmpIndex, text);
748 l = strlen(text);
749 if (l > 26) {
750 strncpy(nameMaxIndex, text, 26);
751 sprintf(&nameMaxIndex[26],"_max");
752 } else
753 sprintf(nameMaxIndex, "%s_max", text);
754 fprintf(Ffp,"#define %s %d\n", nameMaxIndex, dNTu->maxMultiplicity);
755 if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
756 fprintf(Ffp, "typedef struct _%s_struct {\n", nameCom);
757 /*
758 ** The first 64 bits contain the version token, as a char[8] string
759 ** floowed by the multiplicty variable, followed by an integer pad
760 */
761 fprintf(Ffp," char version[8]; /* Version token */\n");
762 fprintf(Ffp,
763 " int %s; /* Generalized Ntuple Multiplicity value */ \n",
764 nameTmpIndex);
765 fprintf(Ffp,
766 " int padding; /* Padding for 64 bit architecture */ \n");
767 for (iv=0; iv< dNTu->numVariables; iv++) {
768 for (j=0; j<dNTu->numAvailable; j++)
769 if (dNTu->varOrdering[j] == iv) i = j;
770 var = dNTu->variables[i];
771 kmode = 0; if (var->isFixedSize != True) kmode = 1;
772 if (var->description == NULL) descrTmp = nullDescr;
773 else descrTmp = var->description;
774 tc = line;
775 if ((var->type != COMPLEX_NTU) &&
776 (var->type != DBL_COMPLEX_NTU)) {
777 sprintf(tc," %s %n", VarTypesNamesC[var->type], &l);
778 tc +=l;
779 if ((var->numDim == 0) && (kmode ==0))
780 sprintf(tc," %s; /* %s */",
781 var->name, descrTmp);
782 else if (var->numDim == 0) {
783 sprintf(tc," %s[%s]; /* %s */",
784 var->name, nameMaxIndex, descrTmp);
785 } else {
786 sprintf(tc," %s%n",var->name, &l); tc+=l;
787 if (kmode == 1) {
788 sprintf(tc, "[%s]%n", nameMaxIndex, &l);
789 tc +=l;
790 }
791 for (j=var->numDim-1; j>-1; j--, tc+=l)
792 sprintf(tc,"[%d]%n", var->dimensions[j], &l);
793
794 sprintf (tc,"; /* %s */", descrTmp);
795 }
796 } else { /* got to convert to float or dbl */
797 if (var->type == COMPLEX_NTU)
798 sprintf(tc," float %n", &l);
799
800 else if (var->type == DBL_COMPLEX_NTU)
801 sprintf(tc," double %n", &l);
802
803 tc +=l;
804 if ((var->numDim == 0) && (kmode ==0))
805 sprintf(tc," %s[2]; /* %s */", var->name, descrTmp);
806 else if (var->numDim == 0) {
807 sprintf(tc," %s[%s][2]; /* %s */",
808 var->name, nameMaxIndex, descrTmp);
809 } else {
810 sprintf(tc," %s%n",var->name, &l); tc+=l;
811 if (kmode == 1) {
812 sprintf(tc, "[%s]%n", nameMaxIndex, &l);
813 tc +=l;
814 }
815 for (j=var->numDim-1; j>-1; j--, tc+=l)
816 sprintf(tc,"[%d]%n", var->dimensions[j], &l);
817 sprintf (tc,"[2]; /* %s */", descrTmp);
818 }
819 }
820 fprintf(Ffp,"%s\n", line);
821 }
822 fprintf(Ffp," int fence[2]; \n");
823 fprintf(Ffp,"} %s_struct; \n", nameCom);
824 }else {
825 /*
826 ** The other type of organisation, using structure
827 */
828 fprintf(Ffp, "typedef struct _%s_v_struct{\n", nameCom);
829 for (iv=0; iv< dNTu->numVariables; iv++) {
830 for (j=0; j<dNTu->numAvailable; j++)
831 if (dNTu->varOrdering[j] == iv) i = j;
832 var = dNTu->variables[i];
833 if (var->isFixedSize == False) {
834 tc = line;
835 if (var->type == COMPLEX_NTU)
836 sprintf(tc," float %n", &l);
837 else if (var->type == DBL_COMPLEX_NTU)
838 sprintf(tc," double %n", &l);
839 else
840 sprintf(tc," %s %n", VarTypesNamesC[var->type], &l);
841 tc +=l;
842 sprintf(tc," %s%n",var->name, &l); tc+=l;
843 if (var->numDim != 0) {
844 for (j=var->numDim-1; j>-1; j--, tc+=l)
845 sprintf(tc,"[%d]%n", var->dimensions[j], &l);
846 }
847 if ((var->type == COMPLEX_NTU) ||
848 (var->type == DBL_COMPLEX_NTU)) {
849 sprintf (tc,"[2]%n",&l);
850 tc += l;
851 }
852 if (var->description == NULL) descrTmp = nullDescr;
853 else descrTmp = var->description;
854 sprintf(tc,"; /* %s */%n", descrTmp, &l); tc += l;
855 fprintf(Ffp,"%s\n", line);
856 }
857 }
858 fprintf(Ffp,"} %s_v_struct; \n", nameCom);
859 fprintf(Ffp,"/* ----- */ \n");
860 /*
861 ** the mother structure now
862 */
863 fprintf(Ffp, "typedef struct _%s_struct{\n", nameCom);
864 fprintf(Ffp," char version[8]; /* Version token */\n");
865 fprintf(Ffp,
866 " int %s; /* Generalized Ntuple Multiplicity value */ \n",
867 nameTmpIndex);
868 fprintf(Ffp,
869 " int padding; /* Padding for 64 bit architecture */ \n");
870 for (iv=0; iv< dNTu->numVariables; iv++) {
871 for (j=0; j<dNTu->numAvailable; j++)
872 if (dNTu->varOrdering[j] == iv) i = j;
873 var = dNTu->variables[i];
874 if (var->isFixedSize == True) {
875 tc = line;
876 if (var->type == COMPLEX_NTU)
877 sprintf(tc," float %n", &l);
878 else if (var->type == DBL_COMPLEX_NTU)
879 sprintf(tc," double %n", &l);
880 else
881 sprintf(tc," %s %n", VarTypesNamesC[var->type], &l);
882 tc +=l;
883 sprintf(tc," %s%n",var->name, &l); tc+=l;
884 if (var->numDim != 0) {
885 for (j=var->numDim-1; j>-1; j--, tc+=l)
886 sprintf(tc,"[%d]%n", var->dimensions[j], &l);
887 }
888 if ((var->type == COMPLEX_NTU) ||
889 (var->type == DBL_COMPLEX_NTU)) {
890 sprintf (tc,"[2]%n",&l);
891 tc += l;
892 }
893 if (var->description == NULL) descrTmp = nullDescr;
894 else descrTmp = var->description;
895 sprintf(tc,"; /* %s */%n", descrTmp, &l); tc += l;
896 fprintf(Ffp,"%s\n", line);
897 }
898 }
899 fprintf(Ffp,
900 " %s_v_struct var[%s]; /* The array of substructures */\n",
901 nameCom, nameMaxIndex);
902 fprintf(Ffp," int fence[2]; \n");
903 fprintf(Ffp,"} %s_struct; \n", nameCom);
904 }
905 free(nameCom);
906 fclose(Ffp);
907
908}
909
910void mcfioC_SetForSaveDecoding(int val)
911{
912 if(val != 0) McfNTuPleSaveDecoding = True;
913 else McfNTuPleSaveDecoding = False;
914}
915
916static char *makeStructName(char *title, int orgStyle)
917{
918 char *out;
919 int i, l, nMax;
920
921 l = strlen(title);
922 if (orgStyle == PARALLEL_ARRAY_NTU) nMax = 23;
923 else nMax = 21;
924 if (l > nMax) l = nMax;
925 out = (char *) malloc(sizeof(char) * (l+1));
926 strncpy(out, title, l); out[l]='\0';
927 for (i=0; i<l; i++) if (out[i] == ' ') out[i] = '_';
928 return out;
929}
930/*
931** CopyNtrim - Copy "fromString" to a malloc'd new string,
932** trimming off leading and trailing spaces & tabs.
933** The newly malloc'd string is returned.
934** If fromString is NULL, NULL is returned.
935*/
936static char *mcf_copyNtrim(char *fromString)
937{
938 char *c, *toString;
939 int len, i;
940
941 if (fromString == NULL)
942 return NULL;
943 toString = (char *) malloc(strlen(fromString)+1);
944
945 /* Find the first non-white character */
946 for (c=fromString; *c == ' ' || *c == '\t'; c++);
947
948 /* Copy the remainder of fromString to toString */
949 strcpy(toString, c);
950
951 /* Remove trailing spaces and tabs by converting to nulls */
952 len = strlen(toString);
953 if (len == 0) /* special case for empty strings */
954 return toString;
955 for (i = len-1; i >= 0; --i) {
956 if (isspace(toString[i]))
957 toString[i] = '\0';
958 else
959 break;
960 }
961 return toString;
962}
963
964
965
Note: See TracBrowser for help on using the repository browser.