20-apr-2005 NvE Id of owning device added to the output of AliSignal::Data().
[u/mrichter/AliRoot.git] / RALICE / icepack / iceconvert / f2k_utl.c
1
2 /* implement functions that help with the f2k format */
3
4 #include <stdlib.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <math.h>
8
9 #include "rdmc.h"
10 #include "amanda.h"
11 #include "f2k.h"
12
13 /* copies the string src to dest and removes inline coments, leading blanks */
14 /* returns the number of characters copied */
15 static int rdmc_f2k_strcleancpy(char *dest, char *src);
16
17
18
19 /****************************************************************************/
20 int rdmc_f2k_dummy_parser(mcfile *fp, array *a, mevt *e, void *misc){ 
21   return RDMC_IO_OK;
22 }
23 /****************************************************************************/
24 int rdmc_f2k_dummy_event_writer(const mcfile *fp, const array *a, const mevt *e){ 
25   return RDMC_IO_OK;
26 }
27 /****************************************************************************/
28
29 /****************************************************************************/
30 /* returns 1 if the format version is supportet */
31 int rdmc_is_f2000_supported(int major, int minor){
32   static struct {
33     int major ;
34     int minor ;
35   } supportet[] = 
36     { {1,1} ,{1,2} , {2004,1},  {0,0} };
37   int i=0;
38
39   while (( supportet[i].major != 0) && ( supportet[i].minor != 0)){
40     if (supportet[i].major == major){
41       if (supportet[i].minor == minor){
42         return 1;
43       }
44     }
45     i++;
46   }
47   return 0;
48 }
49
50 /* stores specific error information int f2k file pointer for print */
51 void rdmc_f2k_errorlog(mcfile *fp){
52   rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
53   int iline= f2k_buff->iline;
54   char *token_pt = f2k_buff->line_pt[iline];
55   char *target_pt = fp->info.f2000.parse_line;
56   char *end_pt=NULL;
57
58   if (*target_pt)
59     return; /* already one error */
60   *target_pt='\0';
61   fp->info.f2000.errline  = fp->fpos - f2k_buff->lines + iline +1;
62   /* try to recover the tokenized line  arghhhh */
63   if (iline+1 >= f2k_buff->lines) 
64     end_pt = &(f2k_buff->buff[f2k_buff->used-1]);
65   else
66     end_pt = f2k_buff->line_pt[iline+1];
67   while (token_pt < end_pt ){
68     if(*token_pt == '\0')
69       *target_pt=' ';
70     else
71       *target_pt = *token_pt;
72     target_pt++;      
73     token_pt++;
74   }
75   *target_pt = '\0';
76   return;
77 }
78
79 /****************************************************************************/
80 /****************************************************************************/
81 /* text buffer functions *********************/
82 void rdmc_push_f2k_buffer(rdmc_f2k_buffer_t *b, char *s, 
83                           const f2000_line_t * type_def){
84   int nnew;
85
86   /* check the size and increase it if necessary */
87   while ( (b->used + RDMC_MAXLINE + 1) >= b->ntot){
88     register int i;
89     long int pedestal;
90     char* bsave = b->buff; /* is needed to save the former location */
91
92 #if 0
93     fprintf(stderr,"bused=%i lused=%i btot=%i ltot=%i %.10s\n",b->used, b->lines, b->ntot,b->lines_tot,s); 
94 #endif
95
96     b->ntot += F2K_BUFFERSIZE;
97     b->buff = realloc(b->buff,b->ntot*sizeof(char));
98
99     /* now correct the line_pointer pointers */
100     pedestal = (long int ) (b->buff - bsave); /* amount buffer was mooved */
101 #if 0
102     fprintf(stderr," %p %p %p %i %p\n",bsave,b->buff,b->line_pt[0],pedestal,b->line_pt[0]+pedestal);
103 #endif
104     for(i=0 ; i< b-> lines; i++){
105        b->line_pt[i] += pedestal; /* only line pointers have to be cotrected */
106
107     }
108   }
109
110   while( (b->lines+1) >= b->lines_tot){
111     b->lines_tot += F2K_LINE_BUFFERSIZE;
112     b->line_pt = realloc(b->line_pt,b->lines_tot*sizeof(char *));
113     b->type_def = realloc(b->type_def
114                           ,b->lines_tot*sizeof(const f2000_line_t *));
115   }
116
117   /* copy the string */
118     nnew = rdmc_f2k_strcleancpy(&(b->buff[b->used]),s);
119     if(nnew){
120       b->type_def[b->lines] = type_def;
121       b->line_pt[b->lines] = &(b->buff[b->used]);
122       b->used += nnew;
123       b->lines += 1;
124       b->line_pt[b->lines] = NULL; /* flag the last line to NULL */
125     }
126 }
127
128 void rdmc_init_f2k_buffer(rdmc_f2k_buffer_t *b){
129   b->buff = NULL; b->line_pt = NULL ; b->type_def = NULL;
130   b->ntot = b->lines_tot = 0;
131   rdmc_reset_f2k_buffer(b);
132 }
133
134 void rdmc_reset_f2k_buffer(rdmc_f2k_buffer_t *b){
135   b->used = b->lines = b->iline = 0;
136
137   b->ntot=F2K_BUFFERSIZE;
138   b->buff = realloc(b->buff,b->ntot*sizeof(char));
139
140   b->lines_tot = F2K_LINE_BUFFERSIZE;
141   b->line_pt = realloc(b->line_pt,b->lines_tot*sizeof(char *));
142   b->type_def = realloc(b->type_def,b->lines_tot*sizeof(f2000_line_t *));
143
144 }
145
146 void rdmc_clear_f2k_buffer(rdmc_f2k_buffer_t *b){
147   b->used = b->lines = b->iline = 0;
148 }
149
150 void rdmc_unlink_f2k_buffer(rdmc_f2k_buffer_t *b){
151   free(b->buff);
152   free(b->type_def);
153   free(b->line_pt);
154   b->ntot = b->lines_tot = 0;
155   b->buff = NULL; b->line_pt = NULL ; b->type_def = NULL;
156 }
157
158 /*********************************************/
159 static int rdmc_f2k_strcleancpy(char *dest, char *src){
160   int ncp=0;                           /* number of chars copied to dest */
161   char *spt=src;
162   char *dpt=dest;
163   int leading_space=1;              /* flag to mark the begining of parsing */
164
165   /* copy the string */
166   while (*spt) {
167     if (leading_space){ /* scip leading spaces */ 
168       if (isspace(*spt)){
169         ++(spt);
170         continue;
171       }else{
172         leading_space = 0;
173       }
174     }
175     /* now we are pointing to the first non-white */
176     /* kill inline comments */
177     *dpt = *spt;
178     ++(dpt);
179     ++(spt);
180     ++ncp;
181   }
182   
183   /* append a \0 terminator */
184   *dpt='\0';
185   ++ncp;
186   return ncp;
187 }
188
189
190 /***************************************************************************/
191
192 /**********************************************************************
193  * scans a nonempty line into tokens
194  **********************************************************************/
195 char ** rdmc_f2k_tokenize(char *s, int *nargs) {
196   static char ** f2k_tokens = NULL; /* buffer for tokens */
197   static int f2k_maxtoken =0;       /* buffer for tokens */
198   const char delim[]=" \t\n";
199   char *tok_pt;
200   
201   *nargs=0;
202   tok_pt = strtok(s,delim); /* find first non-whitespace char */
203   while (tok_pt){
204     if (*nargs >= f2k_maxtoken ){
205       f2k_maxtoken += RDMC_MAXTOKEN_PER_LINE + 1; 
206       f2k_tokens = realloc(f2k_tokens,f2k_maxtoken*sizeof(char *));
207     }
208     f2k_tokens[*nargs] = tok_pt;
209     *nargs += 1;
210     tok_pt = strtok(NULL,delim); /* find first non-whitespace char */
211   }
212   f2k_tokens[*nargs + 1] = NULL;
213
214   return f2k_tokens;
215 } /* amanda_tokenize() */
216
217
218
219 /****************************************************************************/
220 /****************************************************************************/
221 /** string conversion functions                    */
222
223 /****************************************************************************
224  * return the OM id, with the experiment prefix (see siegmund format 
225  *  description about these ids)
226  ****************************************************************************/
227 int rdmc_amanda_iomid(const char *str,int array_id){
228   return rdmc_amanda_ipmtid(str) 
229     + 100000*(array_id / 100);
230 }
231
232 const char * rdmc_amanda_somid(int id){
233   return rdmc_amanda_spmtid(id);
234 }
235
236 /****************************************************************************
237  * return the OM id, with the experiment prefix (see siegmund format 
238  *  description about these ids)
239  ****************************************************************************/
240 const char *rdmc_amanda_spmtid(int type)
241 {
242   int pmtid, sphereid, dataid;
243   int i;
244   static char typestring[RDMC_MAXTOKENLENGTH];
245   char *sphere, *pmt, *data;
246
247   pmtid = type%100;
248   dataid = (type/100)%100;
249   sphereid = (type/10000)%10;
250
251   pmt = "std";
252   for (i = 0; rdmc_pmt_idtable[i].name != NULL; i++)
253     if (rdmc_pmt_idtable[i].id == pmtid) {
254       pmt =  rdmc_pmt_idtable[i].name;
255       break;
256     }
257
258   sphere = "std";
259   for (i = 0; rdmc_sphere_idtable[i].name != NULL; i++)
260     if (rdmc_sphere_idtable[i].id == sphereid) {
261       sphere =  rdmc_sphere_idtable[i].name;
262       break;
263     }
264
265   data = "std";
266   for (i = 0; rdmc_datatrans_idtable[i].name != NULL; i++)
267     if (rdmc_datatrans_idtable[i].id == dataid) {
268       data =  rdmc_datatrans_idtable[i].name;
269       break;
270     }
271
272   sprintf(typestring, "%s-%s-%s", pmt, sphere, data);
273
274   return typestring;
275
276 } /* rdmc_amanda_spmtid */
277
278
279 /****************************************************************************
280  * return the OM id, without the experiment prefix (see siegmund format 
281  *  description about these ids)
282  ****************************************************************************/
283 int rdmc_amanda_ipmtid(const char *str)
284 {
285   char *tok;
286   char *c;
287   int pmtid, dataid, sphereid;
288   int i;
289   char s1[RDMC_MAXTOKENLENGTH];
290
291   strcpy(s1,str);
292
293   tok = strtok(s1, "-");
294   if (tok == NULL) return 0;
295   for (c=tok ; *c ; c++)
296     *c=tolower((int) *c);
297
298   pmtid = 0;
299   for (i = 0; rdmc_pmt_idtable[i].name != NULL; i++)
300     if (strcmp(rdmc_pmt_idtable[i].name, tok) == 0) {
301       pmtid =  rdmc_pmt_idtable[i].id;
302       break;
303     }
304   
305   tok = strtok(NULL, "-");
306   if (tok == NULL) return pmtid;
307   for (c=tok ; *c ; c++)
308     *c=tolower((int) *c);
309   
310   sphereid = 0;
311   for (i = 0; rdmc_sphere_idtable[i].name != NULL; i++)
312     if (strcmp(rdmc_sphere_idtable[i].name, tok) == 0) {
313       sphereid =  rdmc_sphere_idtable[i].id;
314       break;
315     }
316
317   tok = strtok(NULL, "-");
318   if (tok == NULL) return 10000*sphereid + pmtid;
319   for (c=tok ; *c ; c++)
320     *c=tolower((int) *c);
321
322   dataid = 0;
323   for (i = 0; rdmc_datatrans_idtable[i].name != NULL; i++)
324     if (strcmp(rdmc_datatrans_idtable[i].name, tok) == 0) {
325       dataid =  rdmc_datatrans_idtable[i].id;
326       break;
327     }
328   
329   return 10000*sphereid + 100*dataid + pmtid;
330
331 } /* rdmc_amanda_ipmtid() */
332
333 /****************************************************************************
334  * build a string containing the Detector name, or "Neutrino_telescope" if
335  * unknown
336  ****************************************************************************/
337
338 const char *rdmc_amanda_sdet(int geoid)
339 {
340   int i;
341   for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
342     if (rdmc_detector_idtable[i].id == geoid) 
343       return  rdmc_detector_idtable[i].name;
344   return rdmc_detector_idtable[0].name;
345 } /* rdmc_amanda_sdet() */
346
347 int rdmc_amanda_idet(const char *detnam)
348 {
349   int i;
350   char tmp_detnam[RDMC_MAXTOKENLENGTH];
351   char *c;
352   
353   strncpy(tmp_detnam,detnam,RDMC_MAXTOKENLENGTH-1);
354   tmp_detnam[RDMC_MAXTOKENLENGTH-1]='\0';
355
356   c=tmp_detnam;
357   while(*c){
358     *c = tolower((int) *c);
359     c++;
360   }
361
362   for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
363     if (strcmp(rdmc_detector_idtable[i].name, tmp_detnam) == 0)
364       return  rdmc_detector_idtable[i].id;
365
366   /* maybe, we find a substring? */
367   for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
368     if (strstr(rdmc_detector_idtable[i].name, tmp_detnam) != NULL)
369       return  rdmc_detector_idtable[i].id;
370   return rdmc_detector_idtable[0].id;
371
372 } /* rdmc_amanda_detid() */
373
374
375 /****************************************************************************
376  * build a string containing the particle name
377  ****************************************************************************/
378 const char *rdmc_amanda_spartid(int id)
379 {
380   int i;
381   static char a_primary[]="Axxx";
382   static char z_primary[]="Zxxx";
383
384   if ((id>=Z_PRIMARY) && (id < (Z_PRIMARY+200))){ /* primary Zxx */
385     int idd=id-Z_PRIMARY;
386 #if 0
387     if(idd <10)
388       sprintf(z_primary,"Z00%1i",idd);
389     else if(idd <100)
390       sprintf(z_primary,"Z0%2i",idd);
391     else
392       sprintf(z_primary,"Z%3i",idd);
393 #else
394       sprintf(z_primary,"Z%i",idd);
395 #endif
396
397     return z_primary;
398   }else if ((id>=A_PRIMARY) && (id < A_PRIMARY+500)){ /* primary Axxx undocumented !! */ 
399     int idd=id-A_PRIMARY;
400 #if 0
401     if(idd <10)
402       sprintf(a_primary,"A00%1i",idd);
403     else if(idd <100)
404       sprintf(a_primary,"A0%2i",idd);
405     else
406       sprintf(a_primary,"A%3i",idd);
407 #else
408     sprintf(a_primary,"A%i",idd);
409 #endif
410     return a_primary;
411   }
412
413   for (i = 0; rdmc_particle_idtable[i].name != NULL; i++)
414     if (rdmc_particle_idtable[i].id == id) 
415       return  rdmc_particle_idtable[i].name;
416
417   return rdmc_amanda_spartid(0); /* return unknown */
418
419 } /* rdmc_amanda_spartid */
420
421
422 int rdmc_amanda_ipartid(const char *s)
423 {
424   int i;
425   int idd;
426   char name[RDMC_MAXTOKENLENGTH];
427
428   {
429     char *c=name;
430 #if 1
431     const char *sp=s;
432     while ( *sp ){
433       *c=tolower((int) *sp);  
434       sp++; 
435       c++;
436     }
437     *(c++)='\0';
438 #else
439     strcpy(name,s);
440     for ( ; *c ; c++)
441       *c=tolower(*c);
442 #endif
443   }
444
445   for (i = 0; rdmc_particle_idtable[i].name != NULL; i++)
446     if (strcmp(rdmc_particle_idtable[i].name, name) == 0)
447       return  rdmc_particle_idtable[i].id;
448
449   if (name[0] == 'z'){ /* CR primary charge Z */
450     idd=0;
451     if( 1 != sscanf(name,"z%d",&idd))
452       return 0;
453     if (isnan(idd))
454       return 0;
455     idd += Z_PRIMARY;
456     if ( (idd <  Z_PRIMARY) && (idd >=  Z_PRIMARY+200) )
457       return 0;
458     else
459       return idd;
460   }else if (name[0] == 'a'){ /* CR primary mass A */
461     idd=0;
462     if( 1 != sscanf(name,"a%d",&idd))
463       return 0;
464     if (isnan(idd))
465       return 0;
466     idd += A_PRIMARY;
467     if ( (idd <  A_PRIMARY) && (idd >=  A_PRIMARY+500) )
468       return 0;
469     else
470       return idd;
471   }
472   return 0;
473
474 } /* rdmc_amanda_ipartid() */
475
476 int rdmc_amanda_mhit_stat(mhit_stat_t *hstat, char *stat_s){
477   char *cpt=stat_s;
478   long int iedges;
479
480   if (*cpt == '\0')
481     return RDMC_IO_OK;
482   if( *cpt == '>'){
483     hstat->tdc_flag = 1;
484     cpt++;
485   }
486   iedges = strtol(cpt, (char **)NULL, 10);
487   if ((iedges == LONG_MIN )|| (iedges == LONG_MAX ))
488     return RDMC_ILF;
489   else
490     hstat->n_tdc_edges = iedges;
491
492   return RDMC_IO_OK;
493 }
494
495
496 /****************************************************************************/
497 /****************************************************************************/
498 /** value conversion functions                    */
499 /****************************************************************************
500  * make an integer from a string. If "na" or "?" return RDMC_NA
501  ****************************************************************************/
502
503 int rdmc_amanda_strtoi(const char *str, int default_na)
504 {
505   int r;
506   /* f2000 writes  not na, but ? for NA */   
507   if (strstr(str,"?") != NULL)  
508     return default_na;
509   if (strstr(str,"na") != NULL) /* old rdmc specific value */
510     return default_na;
511   if (strstr(str,"*") !=NULL)
512     return  RDMC_REPEAT_CH;
513   if  (strstr(str,"-inf") !=NULL)
514     return -RDMC_IINFTY;
515   if  (strstr(str,"inf") !=NULL)
516     return RDMC_IINFTY;
517   if  (strstr(str,"N") !=NULL)
518     return RDMC_PARENT_NOISE;
519   if  (strstr(str,"A") !=NULL)
520     return RDMC_PARENT_AFPULS;
521
522
523   r = atoi(str);
524   if (isnan( (float) r ))
525     return  default_na;
526   else
527     return r;
528
529 } /* rdmc_amanda_strtoi() */
530
531 /****************************************************************************
532  * make a float from a string. If "na" return default_na
533  ****************************************************************************/
534 double  rdmc_amanda_strtof(char *str, double default_na)
535 {
536   double r;
537   /* f2000 writes  not na, but ? for NA */   
538   if (strstr(str,"?") != NULL)  
539     return  default_na;
540   if (strstr(str,"na") != NULL) /* old rdmc specific value */
541     return default_na;
542   if (strstr(str,"*") !=NULL)
543     return  RDMC_REPEAT_CH;
544   if  (strstr(str,"-inf") !=NULL)
545     return -RDMC_FINFTY;
546   if  (strstr(str,"inf") !=NULL)
547     return RDMC_FINFTY;
548 #if 0 /* parent is never a float but an int */
549   if  (strstr(str,"N") !=NULL)
550     return RDMC_PARENT_NOISE;
551   if  (strstr(str,"A") !=NULL)
552     return RDMC_PARENT_AFPULS;
553 #endif
554 //  r=strtof(str,NULL);
555   r = atof(str);
556   if (isnan( (float) r ))
557     return  default_na;
558   else
559     return r;
560
561 } /* rdmc_amanda_strtof() */
562
563 /****************************************************************************
564  * make a float to a string.
565  ****************************************************************************/
566 char * rdmc_amanda_ftostr(double f, double default_na)
567 {
568   static char str[RDMC_MAXTOKENLENGTH];
569   /* f2000 writes  not na, but ? for NA */   
570   if (isnan(f)) return  "NaN";
571   if ( fabs(f - default_na) < 1.e-5 )  
572     return  "?";
573   if (f >= RDMC_FINFTY/2)
574     return "inf";
575   if (f <= -RDMC_FINFTY/2)
576     return "-inf";
577   sprintf(str,"%g",f);
578   return str;
579 } /* rdmc_amanda_ftostr() */
580
581 /****************************************************************************
582  * make a int to a string. 
583  ****************************************************************************/
584 char * rdmc_amanda_itostr(int i, int default_na)
585 {
586   static char str[RDMC_MAXTOKENLENGTH];
587   /* f2000 writes  not na, but ? for NA */   
588
589   if (isnan(i)) return  "NaN";
590
591   if (i == default_na)  
592     return  "?";
593   if (i >= RDMC_IINFTY)
594     return "inf";
595   if (i <= -RDMC_IINFTY)
596     return "-inf";
597   sprintf(str,"%i",i);
598   return str;
599
600 } /* rdmc_amanda_itostr() */
601
602 /****************************************************************************
603  * make a time string sec.nsec. 
604  ****************************************************************************/
605 char * rdmc_amanda_itimetostr(int sec, int nsec){
606   static char str[RDMC_MAXTOKENLENGTH];
607   static char s1[RDMC_MAXTOKENLENGTH];
608   static char s2[RDMC_MAXTOKENLENGTH];
609
610   if (isnan(sec)  || (sec<0)   ) 
611     strcpy(s1,"?.");
612   else
613     sprintf(s1,"%i.",sec);
614
615   if (isnan(nsec) || (nsec<0) || (nsec>= 1e9 )   ) 
616     strcpy(s2,"?");
617   else
618     sprintf(s2,"%09i",nsec);
619
620   strcpy(str,s1);
621   strcat(str,s2);
622   return str;
623 } /* rdmc_amanda_timestr() */
624
625 /* returns 0 on succes */
626 int rdmc_amanda_strtimetoi(const char *stime, int *sec, int *nsec){
627   char *spt;
628   int slen;
629   if ( (spt = strchr(stime,'.')) != NULL){
630     
631     *sec = rdmc_amanda_strtoi(stime,0); /* test only if a valid number */
632     *nsec = rdmc_amanda_strtoi(spt+1,0); /* test only if a valid number */
633     if (*nsec >0 ){
634       slen = strlen(spt+1) - 9;
635       if (slen < 0){
636         while (slen){
637           *nsec *= 10;
638           slen++;
639         }
640       }
641     }
642   }else{
643     *sec = rdmc_amanda_strtoi(stime,0); /* test only if a valid number */
644     *sec %= 86400 ;  /* seconds of begin of day only is mod(sec,86400)*/
645     *nsec = rdmc_amanda_strtoi("?",0); /* test only if a valid number */
646   }
647   return 0;
648 }
649
650 int rdmc_f2k_y2k(int year){
651   year = (year > 0 ) ? year : 1970;
652   if (year < 70 )
653     year += 2000;
654   if (year < 100 )
655     year += 1900;
656   return year;
657 }
658
659 /****************************************************************************
660  * return the orientation (cosinus theta) as a float
661  ****************************************************************************/
662 static const struct {
663   char* str;
664   float fori;
665   float upper;
666   float lower;
667 } rdmc_updown_table[] = {
668   {"hr", 0.0 , 0.5 , -0.5 },
669   {"HR", 0.0 , 0.5 , -0.5 },
670   {"Hr", 0.0 , 0.5 , -0.5 },
671   {"up", 1.0 , 1.1 , 0.5 },
672   {"UP", 1.0 , 1.1 , 0.5 },
673   {"Up", 1.0 , 1.1 , 0.5 },
674   {"dn", -1.0, -0.5 , -1.1 },
675   {"DN", -1.0, -0.5 , -1.1 },
676   {"Dn", -1.0, -0.5 , -1.1 },
677   {"down", -1.0, -0.5 , -1.1 },
678   {"DOWN", -1.0, -0.5 , -1.1 },
679   {"Down", -1.0, -0.5 , -1.1 },
680   {NULL , 0.0 , 0.0 , 0.0 }
681 };
682
683 char *rdmc_amanda_sori(float ori){
684   int i;
685   for (i=0 ; rdmc_updown_table[i].str != NULL ; i++ ){
686     if ( (ori  > rdmc_updown_table[i].lower)
687          &&  ( ori  < rdmc_updown_table[i].upper) ){
688       return rdmc_updown_table[i].str;
689     }
690   }
691   return rdmc_updown_table[0].str;
692 }
693
694 float rdmc_amanda_fori(char *ori)
695 {
696   int i;
697   for (i=0 ; rdmc_updown_table[i].str != NULL ; i++ ){
698     if (strcmp(ori,rdmc_updown_table[i].str) == 0) 
699       return rdmc_updown_table[i].fori;
700   }
701   return rdmc_updown_table[0].fori;
702 } /* rdmc_amanda_ori() */
703
704
705 static const struct {
706   int ival;
707   double val;
708   char *name;
709 } rdmc_sp_ftable[] = {
710   { 1, 1.0, "yes" },
711   { 0, 0.0, "no" },
712   { 1, 1.0, "true" },
713   { 0, 0.0, "false" },
714   { RDMC_NA, RDMC_NA, "nan" },
715   { RDMC_NA, RDMC_NA, "na" },
716   { -1,  -1.0 , NULL }
717 };
718
719 /* catch some special values */
720 double rdmc_amanda_sptof(char *str){
721   double r=RDMC_NA;
722   int ir=RDMC_NA,i,slen;
723
724   /* now check for hex numbers */
725   if (strstr(str,"0x") == str){
726     if ( 1 == sscanf(str,"%i",&ir)){
727       r = ir;
728       return r;
729     }
730   }
731
732   /* try to decode directly first */
733   if (sscanf(str,"%lg",&r) == 1){
734     /*    rdmc_msgprintf("%.18g %s %i",r,str,DBL_DIG); */
735     return r;
736   }
737
738   /* make a local copy and tronspose to lower */
739   {  
740     char t[RDMC_MAXTOKENLENGTH];
741     slen = strlen(str);
742     slen = (slen < (RDMC_MAXTOKENLENGTH-1)) ? slen : RDMC_MAXTOKENLENGTH-1;
743     for (i=0 ; i <= slen ; i++){
744       t[i] = tolower((int) str[i]);
745     } 
746     t[slen]='\0';
747     
748     /* check special values */
749     for (i=0; rdmc_sp_ftable[i].name != NULL  ; i++){
750       if( strcmp(rdmc_sp_ftable[i].name,t) == 0){
751         return rdmc_sp_ftable[i].val;
752       }
753     }
754   } /* check for special values */
755
756   /* now try a last decode: */
757   
758   return RDMC_SPECIAL_NA;
759 }
760
761
762 /* create a string the USES lines for itoken */
763 char * rdmc_amanda_uses_to_str(int n_uses, mevt_uses_t *uses, int id){
764   static char *buffer =  NULL;
765   static int bsize = 0;
766   int bused = 0;
767   int i_uses;
768   int char_in_line,token_in_line,last_hid;
769   char tbuff[RDMC_MAXTOKENLENGTH];
770   int cont_flag;
771   int t_len;
772
773 #if 1
774   rdmc_sort_uses(uses, n_uses);
775 #endif
776
777   /* init the buffer */
778   if (!bsize) {
779     bsize += RDMC_MAXLINE;
780     buffer = malloc(bsize*sizeof(char));
781   }
782   buffer[0] = '\0';
783   bused = char_in_line = token_in_line = 0 ;
784   tbuff[0] = '\0';
785   last_hid =  RDMC_NA; /* the last seen OM */
786   cont_flag=0;
787
788   /* now loop and look */
789   for (i_uses = 0 ; i_uses < n_uses ; i_uses++){
790     if ( uses[i_uses].useid == id ){ /*** ahh there is one ***/
791
792       /* check buffersize  large enough */
793       /* 2* -> save space for USES and \n */
794       while ( (bused + 2*RDMC_MAXTOKENLENGTH) > bsize){ 
795         bsize += RDMC_MAXLINE;
796         buffer =  (char *) realloc(buffer,bsize*sizeof(char));
797       }
798
799       /* check the current lenght */
800       if ( ( (char_in_line+RDMC_MAXTOKENLENGTH) >= F2000_MAXLINE )
801            || (token_in_line >= RDMC_MAXTOKEN_PER_LINE ) ){
802         if (cont_flag){
803           bused += sprintf(&(buffer[bused]),"-%i",last_hid);
804           cont_flag=0;
805         }
806         bused += sprintf(&(buffer[bused]),"\n");
807         char_in_line = token_in_line = 0 ;
808         last_hid =  RDMC_NA;
809         cont_flag=0;
810       }
811       if (char_in_line == 0 ){
812         char_in_line = strlen("USES");
813         bused += sprintf(&(buffer[bused]),"USES");
814       }
815
816       /* now print this channel */
817       if ((last_hid == RDMC_NA ) ||
818           (uses[i_uses].hitid > last_hid+1 )){
819         if (cont_flag){
820           t_len = sprintf(&(buffer[bused]),"-%i",last_hid);
821           last_hid=RDMC_NA;
822           bused += t_len;
823           char_in_line += t_len;
824           token_in_line++;
825           cont_flag=0;
826         }
827         t_len = sprintf(&(buffer[bused])," %i",uses[i_uses].hitid);
828         last_hid=uses[i_uses].hitid;
829         bused += t_len;
830         char_in_line += t_len;
831         token_in_line++;
832         cont_flag=0;
833       }else{
834         last_hid=uses[i_uses].hitid;
835         cont_flag=1;
836       }
837         
838     } else if ( uses[i_uses].useid > id ){
839 #if 1
840       break; /* break to improve speed  since the uses array is sorted */
841 #endif
842     }
843   }
844
845   if (bused){
846     if(buffer[bused-1] != '\n'){
847       if (cont_flag){
848         bused += sprintf(&(buffer[bused]),"-%i",last_hid);
849         cont_flag=0;
850       }
851       strcpy(&(buffer[bused]),"\n");
852       bused++;
853     }
854   }
855
856 #if 0 /* desireble later */
857   if (buffer[0] == '\0')
858     strcpy(buffer,"USES all\n");
859 #endif
860   return buffer;
861 }
862
863
864 /****************************************************************************
865  ********************************** E O F ***********************************
866  ****************************************************************************/
867
868
869
870
871
872
873
874
875