TPCCLIB
Loading...
Searching...
No Matches
iftfile.c
Go to the documentation of this file.
1
5/******************************************************************************/
6#include "libtpcmisc.h"
7/************************************************** ***************************/
8
9/*************************************************** **************************/
14/******************************************************************************/
15
16/******************************************************************************/
26 IFT *ift,
28 char *filename,
30 int is_key_required,
32 int verbose
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}
173/*****************************************************************************/
174
175/*****************************************************************************/
182 char *filename,
185 char *keystr,
187 int verbose
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}
213/******************************************************************************/
214
215/******************************************************************************/
223 IFT *ift,
225 int item,
227 FILE *fp,
229 int verbose
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}
275/******************************************************************************/
276
277/******************************************************************************/
284 IFT *ift,
286 char *filename,
288 int verbose
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}
314/******************************************************************************/
315
316/******************************************************************************/
323 IFT *ift,
325 char *filename,
327 int verbose
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}
431/******************************************************************************/
432
433/******************************************************************************/
int istime(char *str)
Definition datetime.c:259
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
void iftInit(IFT *ift)
Definition ift.c:45
int iftWriteItem(IFT *ift, int item, FILE *fp, int verbose)
Definition iftfile.c:221
int IFT_SPACE_BEFORE_EQ_SIGN
Definition iftfile.c:11
int defRead(IFT *ift, char *filename, int verbose)
Definition iftfile.c:321
char * iftReadValue(char *filename, char *keystr, int verbose)
Definition iftfile.c:180
int IFT_SPACE_AFTER_EQ_SIGN
Definition iftfile.c:13
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
int iftWrite(IFT *ift, char *filename, int verbose)
Definition iftfile.c:282
Header file for libtpcmisc.
char * strstr_noquotation(const char *str1, const char *str2)
Definition quots.c:17
char * strcasestr(const char *haystack, const char *needle)
Definition strext.c:279
int type
Definition libtpcmisc.h:275
int keyNr
Definition libtpcmisc.h:270
IFT_KEY_AND_VALUE * item
Definition libtpcmisc.h:279