TPCCLIB
Loading...
Searching...
No Matches
iftfile.c File Reference

Reading and writing IFT format files. More...

#include "libtpcmisc.h"

Go to the source code of this file.

Functions

int iftRead (IFT *ift, char *filename, int is_key_required, int verbose)
 
char * iftReadValue (char *filename, char *keystr, int verbose)
 
int iftWriteItem (IFT *ift, int item, FILE *fp, int verbose)
 
int iftWrite (IFT *ift, char *filename, int verbose)
 
int defRead (IFT *ift, char *filename, int verbose)
 

Variables

int IFT_SPACE_BEFORE_EQ_SIGN = 1
 
int IFT_SPACE_AFTER_EQ_SIGN = 1
 

Detailed Description

Reading and writing IFT format files.

Author
Vesa Oikonen

Definition in file iftfile.c.

Function Documentation

◆ defRead()

int defRead ( IFT * ift,
char * filename,
int verbose )

Read definition file, for example microPET header file, into IFT structure.

Returns
Returns 0 if ok. Sets ift->status.
See also
iftWrite, iftRead
Parameters
iftPointer to initiated but empty IFT
filenameInput filename
verboseVerbose level; if zero, then only warnings are printed into stderr

Definition at line 321 of file iftfile.c.

328 {
329 int i, ret, nr=0, line=0, initial_key_nr=0, nonprintable=0;
330 char *allfile, *cptr, *key_ptr, *value_ptr, *cmt_ptr;
331 FILE *fp;
332
333 /* Check function input */
334 if(verbose>0) printf("%s(*ift, %s)\n", __func__, filename);
335 if(ift==NULL) return(1);
336 if(filename==NULL || strlen(filename)<1) {
337 iftSetStatus(ift, IFT_FAULT); return(1);
338 }
339 if(ift->keyNr>0) initial_key_nr=ift->keyNr;
340
341 /* Open file */
342 if(strcasecmp(filename, "stdin")==0) {
343 fp=stdin;
344 } else {
345 fp=fopen(filename, "r");
346 if(fp==NULL) {iftSetStatus(ift, IFT_CANNOTREAD); return(2);}
347 }
348
349 /* Get file size */
350 nr=nonprintable=0; while((ret=fgetc(fp))!=EOF) {
351 if(iscntrl(ret) && ret!=13 && ret!=10 && ret!=9) {
352 nonprintable=1; break;}
353 nr++;
354 }
355 if(nr<2) {
356 if(strcasecmp(filename, "stdin")!=0) fclose(fp);
357 if(nonprintable>0) {
358 /* File contains non-printable characters; maybe binary file */
359 iftSetStatus(ift, IFT_UNKNOWNFORMAT);
360 } else {
361 /* File just din't have any content */
362 iftSetStatus(ift, IFT_NODATA);
363 }
364 return(3);
365 }
366 if(verbose>1) printf(" the size of file is %d bytes\n", nr);
367 if(nr>5000000) {
368 if(strcasecmp(filename, "stdin")!=0) fclose(fp);
369 iftSetStatus(ift, IFT_UNKNOWNFORMAT); return(3);
370 }
371 rewind(fp);
372
373 /* Allocate memory for file contents */
374 allfile=(char*)malloc((nr+1)*sizeof(char));
375 if(allfile==NULL) {
376 if(strcasecmp(filename, "stdin")!=0) fclose(fp);
377 iftSetStatus(ift, IFT_NOMEMORY); return(4);
378 }
379
380 /* Read file contents and close the file */
381 i=0; while((ret=fgetc(fp))!=EOF && i<nr) allfile[i++]=(char)ret;
382 allfile[i]=(char)0;
383 if(strcasecmp(filename, "stdin")!=0) fclose(fp);
384
385 /* and then fill the list */
386 /* separate the first line */
387 cptr=strtok(allfile, "\n\r"); line=0;
388 do {
389 if(verbose>10) printf("line %d: '%s'\n", line, cptr);
390 /* Remove initial spaces and tabs */
391 i=strspn(cptr, " \t"); cptr+=i;
392 if(strlen(cptr)<1) {cptr=strtok(NULL, "\n\r"); continue;}
393 /* Check if line starts with a comment character */
394 if((cmt_ptr=strchr("#!;%", cptr[0]))!=NULL) {
395 /* save the whole line as a key */
396 key_ptr=cptr; value_ptr=NULL;
397 ret=iftPut(ift, key_ptr, value_ptr, " ", verbose-2);
398 if(ret) {
399 free(allfile); iftEmpty(ift); iftSetStatus(ift, IFT_FAULT);
400 return(10+ret);
401 }
402 /* separate the next line */
403 cptr=strtok(NULL, "\n\r"); line++;
404 continue;
405 }
406 if(verbose>11) printf(" line %d: '%s'\n", line, cptr);
407 /* Get the first line string representing key name */
408 key_ptr=cptr; cptr=strchr(cptr, ' ');
409 if(cptr!=NULL) {*cptr=(char)0; cptr++;}
410 /* Rest of the line is the key value */
411 if(cptr==NULL) value_ptr=NULL; else value_ptr=cptr;
412 ret=iftPut(ift, key_ptr, value_ptr, " ", verbose-2);
413 if(ret) {
414 free(allfile); iftEmpty(ift); iftSetStatus(ift, IFT_FAULT);
415 return(10+ret);
416 }
417 /* separate the next line */
418 cptr=strtok(NULL, "\n\r"); line++;
419 } while(cptr!=NULL);
420 free(allfile);
421
422 /* Did we actually get any data? */
423 if(ift->keyNr<=initial_key_nr) {iftSetStatus(ift, IFT_NODATA); return(7);}
424
425 /* Set parameter file type */
426 ift->type=4;
427
428 iftSetStatus(ift, IFT_OK);
429 return(0);
430}
int iftPut(IFT *ift, char *key, char *value, char *cmt_type, int verbose)
Definition ift.c:82
void iftEmpty(IFT *ift)
Definition ift.c:60
void iftSetStatus(IFT *ift, int status)
Definition ift.c:29
int type
Definition libtpcmisc.h:275
int keyNr
Definition libtpcmisc.h:270

Referenced by imgReadMicropetFrame(), and imgReadMicropetHeader().

◆ iftRead()

int iftRead ( IFT * ift,
char * filename,
int is_key_required,
int verbose )

Read IFT file keys and values. Previous contents of IFT are preserved.

This function can read the initial ASCII part of files that contain also binary data.

Returns
Returns 0 if ok. Sets ift->status.
See also
iftdup, iftInit, iftEmpty, defRead
Parameters
iftPointer to initiated but empty IFT structure.
filenameInput file name.
is_key_required0=key name is not required, 1=only lines with key and equals sign are read.
verboseVerbose level; if zero, then only warnings are printed into stderr

Definition at line 24 of file iftfile.c.

33 {
34 int i, ret, nr=0, line=0, eq_type=0, initial_key_nr=0, nonprintable=0;
35 char *allfile, *cptr, *key_ptr, *value_ptr, *eq_ptr, *eq_ptr2, *cmt_ptr;
36 char empty_char=(char)0;
37 FILE *fp;
38
39
40 /* Check function input */
41 if(verbose>0) printf("%s(*ift, %s)\n", __func__, filename);
42 if(ift==NULL) return(1);
43 if(filename==NULL || strlen(filename)<1) {
44 iftSetStatus(ift, IFT_FAULT); return(1);
45 }
46 if(ift->keyNr>0) initial_key_nr=ift->keyNr;
47
48 /* Open file */
49 if(strcasecmp(filename, "stdin")==0) {
50 fp=stdin;
51 } else {
52 fp=fopen(filename, "r");
53 if(fp==NULL) {iftSetStatus(ift, IFT_CANNOTREAD); return(2);}
54 }
55
56 /* Get file size */
57 nr=nonprintable=0; while((ret=fgetc(fp))!=EOF) {
58 if(iscntrl(ret) && ret!=13 && ret!=10 && ret!=9) {
59 nonprintable=1; break;}
60 nr++;
61 }
62 if(nr<2) {
63 if(strcasecmp(filename, "stdin")!=0) fclose(fp);
64 if(nonprintable>0) {
65 /* File contains non-printable characters; maybe binary file */
66 iftSetStatus(ift, IFT_UNKNOWNFORMAT);
67 } else {
68 /* File just din't have any content */
69 iftSetStatus(ift, IFT_NODATA);
70 }
71 return(3);
72 }
73 if(verbose>1) printf(" the size of file is %d bytes\n", nr);
74 if(nr>5000000) {
75 if(strcasecmp(filename, "stdin")!=0) fclose(fp);
76 iftSetStatus(ift, IFT_UNKNOWNFORMAT); return(3);
77 }
78 rewind(fp);
79
80 /* Allocate memory for file contents; calloc and extra space to end with 0. */
81 allfile=(char*)calloc((nr+3), sizeof(char));
82 if(allfile==NULL) {
83 if(strcasecmp(filename, "stdin")!=0) fclose(fp);
84 iftSetStatus(ift, IFT_NOMEMORY); return(4);
85 }
86
87 /* Read file contents and close the file */
88 i=0; while((ret=fgetc(fp))!=EOF && i<nr) allfile[i++]=(char)ret;
89 if(strcasecmp(filename, "stdin")!=0) fclose(fp);
90 /* Make sure that file ends with CR or LF */
91 if(allfile[i-1]!=10 && allfile[i-1]!=13) {allfile[i++]=(char)13; allfile[i++]=(char)10;}
92
93 /* and then fill the list */
94 /* separate the first line */
95 cptr=strtok(allfile, "\n\r"); line=0;
96 do {
97 if(verbose>2) printf("line %d: '%s'\n", line, cptr);
98 /* Remove initial spaces and tabs */
99 i=strspn(cptr, " \t"); cptr+=i;
100 if(strlen(cptr)<1) {cptr=strtok(NULL, "\n\r"); line++; continue;}
101 /* Check if line starts with a comment character */
102 if((cmt_ptr=strchr("#!;%", cptr[0]))!=NULL) {
103 cmt_ptr=cptr; cptr++; i=strspn(cptr, " \t"); cptr+=i;
104 if(strlen(cptr)<1) {cptr=strtok(NULL, "\n\r"); line++; continue;}
105 }
106 if(verbose>2) printf(" line %d: '%s'\n", line, cptr);
107 /* Find the 'equals' sign */
108 eq_ptr=strstr_noquotation(cptr, ":=");
109 if(eq_ptr==NULL) eq_ptr=strstr_noquotation(cptr, "=");
110 if(eq_ptr==NULL) {
111 eq_ptr=strstr_noquotation(cptr, ":");
112 /* do not accept time representation */
113 if(eq_ptr!=NULL && strlen(cptr)>=strlen(eq_ptr)+2 && istime(eq_ptr-2)<=0) {
114 /* ... but search for later equals sign */
115 eq_ptr2=strstr_noquotation(eq_ptr+4, ":"); eq_ptr=NULL;
116 if(eq_ptr2!=NULL && strlen(cptr)>=strlen(eq_ptr2)+2) {
117 if(istime(eq_ptr2-2)<=0) eq_ptr2=NULL; else eq_ptr=eq_ptr2;
118 }
119 }
120 }
121 if(eq_ptr==NULL) {
122 /* Equals sign not found; if required, then ignore this line */
123 if(is_key_required) {cptr=strtok(NULL, "\n\r"); line++; continue;}
124 /* If not required, then key="" */
125 key_ptr=eq_ptr=&empty_char; value_ptr=cptr;
126 } else {
127 if(strncmp(eq_ptr, ":=", 2)==0) eq_type=1;
128 else if(strncmp(eq_ptr, "=", 1)==0) eq_type=2;
129 else if(strncmp(eq_ptr, ":", 1)==0) eq_type=3;
130 else eq_type=0;
131 *eq_ptr=(char)0; eq_ptr++; key_ptr=cptr;
132 /* Find the end of the 'equals' sign; that is the start of value */
133 i=strspn(eq_ptr, ":="); value_ptr=eq_ptr+i;
134 /* Remove initial spaces and tabs */
135 i=strspn(value_ptr, " \t"); value_ptr+=i;
136 }
137 /* Remove tail spaces and tabs */
138 i=strlen(key_ptr); while(i>0 && isspace((int)key_ptr[i-1])) i--; key_ptr[i]=(char)0;
139 if(i==0) { /* Length of key name is zero */
140 if(is_key_required) {cptr=strtok(NULL, "\n\r"); line++; continue;}
141 }
142 i=strlen(value_ptr); while(i>0 && isspace((int)value_ptr[i-1])) i--; value_ptr[i]=(char)0;
143 if(verbose>2) printf(" key='%s' value='%s'\n", key_ptr, value_ptr);
144 /* Remove quotation marks */
145 i=strlen(key_ptr)-1; if(i<0) i=0;
146 if((key_ptr[0]=='\'' && key_ptr[i]=='\'') || (key_ptr[0]=='\"' && key_ptr[i]=='\"')) {
147 key_ptr[i]=(char)0; if(i>0) key_ptr++;}
148 if(strlen(key_ptr)<1) { /* Length of key name without comments is zero */
149 if(is_key_required) {cptr=strtok(NULL, "\n\r"); line++; continue;}
150 }
151 i=strlen(value_ptr)-1; if(i<0) i=0;
152 if((value_ptr[0]=='\'' && value_ptr[i]=='\'') || (value_ptr[0]=='\"' && value_ptr[i]=='\"')) {
153 value_ptr[i]=(char)0; if(i>0) value_ptr++;}
154 if(verbose>2) printf(" key='%s' value='%s'\n", key_ptr, value_ptr);
155 /* Put key and value in the list */
156 ret=iftPut(ift, key_ptr, value_ptr, cmt_ptr, verbose-1);
157 if(ret) {
158 free(allfile); iftEmpty(ift); iftSetStatus(ift, IFT_FAULT);
159 return(10+ret);
160 }
161 /* separate the next line */
162 cptr=strtok(NULL, "\n\r"); line++;
163 } while(cptr!=NULL);
164 free(allfile);
165 if(verbose>2) printf("eq_type=%d\n", eq_type);
166 ift->type=eq_type;
167 /* Did we actually get any data? */
168 if(ift->keyNr<=initial_key_nr) {iftSetStatus(ift, IFT_NODATA); return(7);}
169
170 iftSetStatus(ift, IFT_OK);
171 return(0);
172}
int istime(char *str)
Definition datetime.c:259
char * strstr_noquotation(const char *str1, const char *str2)
Definition quots.c:17

Referenced by cptReadOne(), dftRead(), hrrtMakeCalHdr(), iftReadValue(), interfileIsHeader(), irdRead(), readEcat931Calibrationfile(), tsvRead(), vrdRead(), and xelRead().

◆ iftReadValue()

char * iftReadValue ( char * filename,
char * keystr,
int verbose )

Read value string from IFT file.

Returns
Returns pointer to a locally allocated copy of the value string, or NULL if none found; free the returned pointer when no more needed.
Parameters
filenameFile name.
keystrString to search for in the key. If NULL, or key containing the string is not found, then if there is only one value in the file, pointer to that is returned.
verboseVerbose level; if zero, then only warnings are printed into stderr

Definition at line 180 of file iftfile.c.

188 {
189 if(filename==NULL || !filename[0]) return(NULL);
190 /* Read the file */
191 IFT ift; iftInit(&ift); if(iftRead(&ift, filename, 0, verbose)!=0) return(NULL);
192 /* If file contains just one value, then return pointer to a copy of that */
193 if(ift.keyNr==1 && strlen(ift.item[0].value)>0) {
194 char *s=strdup(ift.item[0].value);
195 iftEmpty(&ift);
196 return(s);
197 }
198 /* If key string to search for was not given, then we cannot do more */
199 if(keystr==NULL || strlen(keystr)<1) return(NULL);
200 /* Search the list for the key */
201 int i=-1;
202 for(int li=0; li<ift.keyNr; li++) {
203 if(strcasestr(ift.item[li].key, keystr)!=NULL && strlen(ift.item[li].value)>0) {
204 i=li; break;
205 }
206 }
207 if(i<0) return(NULL);
208 /* If found, then return pointer to a copy of that */
209 char *s=strdup(ift.item[i].value);
210 iftEmpty(&ift);
211 return(s);
212}
void iftInit(IFT *ift)
Definition ift.c:45
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
char * strcasestr(const char *haystack, const char *needle)
Definition strext.c:279
IFT_KEY_AND_VALUE * item
Definition libtpcmisc.h:279

◆ iftWrite()

int iftWrite ( IFT * ift,
char * filename,
int verbose )

Write all keys and values.

Returns
0 if ok.
See also
iftInit, iftRead, iftWriteItem
Parameters
iftPointer to IFT structure.
filenameOutput filename, or string "stdout" to print on console.
verboseVerbose level; if zero, then only warnings are printed into stderr

Definition at line 282 of file iftfile.c.

289 {
290 int li, ret;
291 FILE *fp;
292
293 if(verbose>0) printf("%s(*ift, %s)\n", __func__, filename);
294 if(ift==NULL) return(1);
295 if(filename==NULL || strlen(filename)<1) {iftSetStatus(ift, IFT_FAULT); return(1);}
296 if(ift->keyNr<1) return(0);
297
298 /* Open file */
299 if(strcasecmp(filename, "stdout")==0) {
300 fp=stdout;
301 } else {
302 fp=fopen(filename, "w");
303 if(fp==NULL) {iftSetStatus(ift, IFT_CANNOTWRITE); return(2);}
304 }
305
306 /* Write the contents */
307 for(li=0, ret=0; li<ift->keyNr; li++) {
308 ret=iftWriteItem(ift, li, fp, verbose);
309 if(ret) break;
310 }
311 if(strcasecmp(filename, "stdout")!=0) fclose(fp);
312 return(ret);
313}
int iftWriteItem(IFT *ift, int item, FILE *fp, int verbose)
Definition iftfile.c:221

Referenced by cptReadOne(), ecat7MainheaderFromIFT(), ecat7ReadHeaders(), hrrtMakeCalHdr(), and niftiHeaderFromIFT().

◆ iftWriteItem()

int iftWriteItem ( IFT * ift,
int item,
FILE * fp,
int verbose )

Write one item in IFT to the specified file pointer.

See also
iftInit, iftEmpty, iftRead, iftWrite
Returns
0 if ok.
Parameters
iftPointer to initiated but empty IFT structure.
itemIndex [0..keyNr-1] of key and value to write.
fpOutput file pointer.
verboseVerbose level; if zero, then only warnings are printed into stderr

Definition at line 221 of file iftfile.c.

230 {
231 char eq_sign[3];
232 int ret;
233
234 if(verbose>0) printf("%s(*ift, %d, fp)\n", __func__, item);
235 if(ift==NULL) {return(1);}
236 iftSetStatus(ift, IFT_FAULT);
237 if(fp==NULL) {return(2);}
238 if(item<0 || item>=ift->keyNr) {return(3);}
239
240 iftSetStatus(ift, IFT_OK);
241 switch(ift->type) {
242 case 1: strcpy(eq_sign, ":="); break;
243 case 2: strcpy(eq_sign, "="); break;
244 case 3: strcpy(eq_sign, ":"); break;
245 case 4: strcpy(eq_sign, " "); break;
246 case 5: strcpy(eq_sign, "\t"); break;
247 case 6: strcpy(eq_sign, ","); break;
248 case 7: strcpy(eq_sign, ";"); break;
249 default: strcpy(eq_sign, ":="); break;
250 }
251 if(ift->item[item].type!=' ' && ift->item[item].type!=(char)0) {
252 ret=fprintf(fp, "%c ", ift->item[item].type);
253 if(ret<1) {iftSetStatus(ift, IFT_CANNOTWRITE); return(6);}
254 }
255 if(ift->item[item].key==NULL || strlen(ift->item[item].key)<1) {
256 ret=fprintf(fp, "%s\n", ift->item[item].value);
257 } else {
259 ift->type==4 || ift->type==5 || ift->type==6 || ift->type==7)
260 ret=fprintf(fp, "%s%s%s\n",
261 ift->item[item].key, eq_sign, ift->item[item].value);
263 ret=fprintf(fp, "%s %s%s\n",
264 ift->item[item].key, eq_sign, ift->item[item].value);
266 ret=fprintf(fp, "%s%s %s\n",
267 ift->item[item].key, eq_sign, ift->item[item].value);
268 else
269 ret=fprintf(fp, "%s %s %s\n",
270 ift->item[item].key, eq_sign, ift->item[item].value);
271 }
272 if(ret<1) {iftSetStatus(ift, IFT_CANNOTWRITE); return(6);}
273 return(0);
274}
int IFT_SPACE_BEFORE_EQ_SIGN
Definition iftfile.c:11
int IFT_SPACE_AFTER_EQ_SIGN
Definition iftfile.c:13

Referenced by iftWrite().

Variable Documentation

◆ IFT_SPACE_AFTER_EQ_SIGN

int IFT_SPACE_AFTER_EQ_SIGN = 1

Use space after equal sign in IFT

Definition at line 13 of file iftfile.c.

Referenced by iftWriteItem().

◆ IFT_SPACE_BEFORE_EQ_SIGN

int IFT_SPACE_BEFORE_EQ_SIGN = 1

Use space before equal sign in IFT

Definition at line 11 of file iftfile.c.

Referenced by iftWriteItem().