TPCCLIB
Loading...
Searching...
No Matches
iftio.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpcift.h"
14/*****************************************************************************/
15
16/*****************************************************************************/
27 IFT *ift,
29 int item,
31 FILE *fp,
33 TPCSTATUS *status
34) {
35 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
36 if(ift==NULL) return TPCERROR_FAIL;
37 int verbose=0; if(status!=NULL) verbose=status->verbose-1;
38 if(verbose>10) printf("%s(*ift, %d, fp)\n", __func__, item);
39 if(fp==NULL) {
40 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
42 }
43 if(item<0 || item>=ift->keyNr) {
44 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
45 return TPCERROR_NO_DATA;
46 }
47
48 /* Set interfile-type key/value separator */
49 char eq_sign[3];
50 switch(ift->type) {
51 case 1: strcpy(eq_sign, ":="); break;
52 case 2: strcpy(eq_sign, "="); break;
53 case 3: strcpy(eq_sign, ":"); break;
54 case 4: strcpy(eq_sign, " "); break;
55 case 5: strcpy(eq_sign, "\t"); break;
56 case 6: strcpy(eq_sign, ","); break;
57 case 7: strcpy(eq_sign, ";"); break;
58 default: strcpy(eq_sign, ":="); break;
59 }
60
61 int n=5; if(ift->item[item].key!=NULL) n+=strlen(ift->item[item].key);
62 if(ift->item[item].value!=NULL) n+=strlen(ift->item[item].value);
63 if(ift->item[item].comment!=0) n+=2;
64 if(verbose>100) printf(" n := %d\n", n);
65 char line[n], cmt[3];
66 /* 'Print' comment character, if required */
67 if(ift->item[item].comment!=0) strcpy(cmt, "# "); else strcpy(cmt, "");
68 /* 'Print' key and/or value */
69 if(ift->item[item].key==NULL || strlen(ift->item[item].key)<1) {
70 sprintf(line, "%s%s", cmt, ift->item[item].value);
71 } else {
72 if((ift->space_before_eq==0 && ift->space_after_eq==0) ||
73 ift->type==4 || ift->type==5 || ift->type==6 || ift->type==7)
74 sprintf(line, "%s%s%s%s", cmt, ift->item[item].key, eq_sign, ift->item[item].value);
75 else if(ift->space_before_eq==1 && ift->space_after_eq==0)
76 sprintf(line, "%s%s %s%s", cmt, ift->item[item].key, eq_sign, ift->item[item].value);
77 else if(ift->space_before_eq==0 && ift->space_after_eq==1)
78 sprintf(line, "%s%s%s %s", cmt, ift->item[item].key, eq_sign, ift->item[item].value);
79 else
80 sprintf(line, "%s%s %s %s", cmt, ift->item[item].key, eq_sign, ift->item[item].value);
81 }
82 /* Write line into file */
83 if(fprintf(fp, "%s\n", line) < (int)strlen(line)) {
84 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
86 }
87 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
88 return TPCERROR_OK;
89}
90/******************************************************************************/
91
92/******************************************************************************/
100 IFT *ift,
102 FILE *fp,
104 TPCSTATUS *status
105) {
106 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
107 if(ift==NULL || fp==NULL) return TPCERROR_FAIL;
108 if(status!=NULL && status->verbose>100) printf("keyNr := %d\n", ift->keyNr);
109 /* Write the contents */
110 int li, ret;
111 for(li=0, ret=0; li<ift->keyNr; li++) {
112 ret=iftWriteItem(ift, li, fp, status); if(ret!=TPCERROR_OK) break;
113 }
114 return(ret);
115}
116/*****************************************************************************/
117
118/*****************************************************************************/
132 IFT *ift,
134 FILE *fp,
140 int is_key_required,
145 int is_comment_accepted,
147 TPCSTATUS *status
148) {
149 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
150 if(ift==NULL || fp==NULL) return TPCERROR_FAIL;
151 int verbose=0; if(status!=NULL) verbose=status->verbose-1;
152 if(verbose>0) {
153 printf("%s(*ift, fp, %d, %d)\n", __func__, is_key_required, is_comment_accepted);
154 fflush(stdout);
155 }
156 int initial_key_nr=0; if(ift->keyNr>0) initial_key_nr=ift->keyNr;
157 if(verbose>11) {
158 printf(" initial_key_nr := %d\n", initial_key_nr);
159 fflush(stdout);
160 }
161
162 /* Get the size of the ASCII part of the file */
163 size_t fsize=asciiFileSize(fp, NULL);
164 if(verbose>11) {printf(" ASCII size := %d\n", (int)fsize); fflush(stdout);}
165 /* If ASCII part is too small, then lets consider that an error */
166 if( fsize<1 || (is_key_required && fsize<3) ) {
167 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
168 return TPCERROR_NO_DATA;
169 }
170 /* If ASCII part is too large, then lets consider that an error */
171 if(fsize>5000000) {
172 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_BIG);
173 return TPCERROR_TOO_BIG;
174 }
175 /* Read that to a string */
176 char *data;
177 data=asciiFileRead(fp, NULL, fsize+1); rewind(fp);
178 if(data==NULL) {
179 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
180 return TPCERROR_NO_DATA;
181 }
182 /* Read one line at a time from the string and fill IFT */
183 int i=0, j, ret;
184 char *cptr, *line;
185 cptr=data;
186 while((line=strTokenDup(cptr, "\n\r", &j))!=NULL) {
187 if(verbose>15) {printf(" '%s'\n", line); fflush(stdout);}
188 ret=iftPutFromString(ift, line, is_key_required, is_comment_accepted, status);
189 if(verbose>1 && ret!=0) {
190 fprintf(stderr, "Warning: cannot read line %d: '%s'.\n", i, line);
191 fflush(stderr);
192 }
193 free(line); cptr+=j; i++;
194 }
195#if(0) // this would mess up the functions that read other data formats as ift
196 /* If none found, and key is required, we will try with space as separator */
197 if(initial_key_nr==ift->keyNr && is_key_required) {
198 cptr=data; i=0;
199 while((line=strTokenDup(cptr, "\n\r", &j))!=NULL) {
200 ret=iftPutFromStringWithSpaceSeparator(ift, line, is_comment_accepted, status);
201 if(verbose>1 && ret!=0)
202 fprintf(stderr, "Warning: cannot read line %d: '%s'.\n", i, line);
203 free(line); cptr+=j; i++;
204 }
205 }
206#endif
207 /* Ready */
208 free(data);
209 if(i==0) {
210 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
211 return TPCERROR_NO_DATA;
212 }
213
214 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
215 return TPCERROR_OK;
216}
217/*****************************************************************************/
218
219/*****************************************************************************/
231 IFT *ift,
234 const char *line,
240 int is_key_required,
245 int is_comment_accepted,
247 TPCSTATUS *status
248) {
249 if(ift==NULL) return TPCERROR_FAIL;
250 if(line==NULL || strlen(line)<1) {
251 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
252 return TPCERROR_NO_DATA;
253 }
254 int verbose=0; if(status!=NULL) verbose=status->verbose-1;
255 if(verbose>10) {
256 printf("%s(ift, ", __func__);
257 if(line!=NULL) printf("\"%s\", ", line); else printf("NULL, ");
258 printf("%d, %d)\n", is_key_required, is_comment_accepted);
259 fflush(stdout);
260 }
261 if(is_key_required==2) { // If space is used as separator
262 return(iftPutFromStringWithSpaceSeparator(ift, line, is_comment_accepted, status));
263 }
264
265 /* Check if line is a comment line */
266 char *lptr=(char*)line; int i; char cmt;
267 if(asciiCommentLine(lptr, &i)) {cmt=(char)1; lptr+=i;} else cmt=(char)0;
268 /* If comment line requirement is not met, then return here */
269 if((is_comment_accepted==0 && cmt) || (is_comment_accepted==2 && !cmt)) {
270 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
271 return TPCERROR_OK;
272 }
273
274 /* Find the 'equals' sign, ':=', '=', or ':' */
275 char *eq_ptr;
276 eq_ptr=strstrNoQuotation(lptr, ":=");
277 if(eq_ptr==NULL) eq_ptr=strstrNoQuotation(lptr, "=");
278 /* If not yet found, try ':' but it must not be part of time or Windows path, for example 'C:\tmp' */
279 char *cptr2=lptr;
280 while(eq_ptr==NULL) {
281 if(verbose>100) printf("cptr2 := '%s'\n", cptr2);
282 eq_ptr=strstrNoQuotation(cptr2, ":"); if(eq_ptr==NULL) break;
283 if(eq_ptr[1]=='\\') {
284 /* ok ':' was part of windows path ... but search for later equals sign */
285 cptr2=eq_ptr+2; eq_ptr=NULL; continue;
286 }
287 if(verbose>100) printf("eq_ptr := '%s'\n", eq_ptr);
288 if(strlen(cptr2)-strlen(eq_ptr)<2) break; // cannot be time
289 if(verbose>100) printf("is this time '%s'\n", eq_ptr-2);
290 if(strTimeValid(eq_ptr-2)>0) break; // was not time
291 /* ok ':' was part of time ... but search for later equals sign */
292 if(verbose>100) printf("yes it was\n");
293 cptr2=eq_ptr+6; eq_ptr=NULL;
294 }
295
296 /* We must have equals sign if key is required */
297 if(is_key_required!=0 && eq_ptr==NULL) {
298 if(verbose>50) printf("key required but equals sign not found\n");
299 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
300 return TPCERROR_NO_KEY;
301 }
302
303 char *key=NULL, *value=NULL;
304 if(eq_ptr==NULL) {
305 /* No key */
306 key=strndup("", 0);
307 /* then value is the whole string, excluding comment */
308 value=strndup(lptr, strlen(lptr)); strClean(value);
309 } else {
310 /* key starts after comment */
311 key=strndup(lptr, strlen(lptr)-strlen(eq_ptr));
312 if(verbose>100) printf("key before cleaning is '%s'\n", key);
313 strClean(key);
314 if(verbose>100) printf("key after cleaning is '%s'\n", key);
315 /* Find the end of the 'equals' sign; that is the start of value */
316 int j=strspn(eq_ptr, ":="); value=strdup(eq_ptr+j);
317 if(verbose>100) printf("value before cleaning is '%s'\n", value);
318 strClean(value);
319 if(verbose>100) printf("value after cleaning is '%s'\n", value);
320 }
321
322 int ret=iftPut(ift, key, value, cmt, status);
323 free(key); free(value);
324 if(ret==0) statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
325 return ret;
326}
327/*****************************************************************************/
328
329/*****************************************************************************/
341 IFT *ift,
344 const char *line,
349 int is_comment_accepted,
351 TPCSTATUS *status
352) {
353 if(ift==NULL) return TPCERROR_FAIL;
354 if(line==NULL || strlen(line)<1) {
355 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
356 return TPCERROR_NO_DATA;
357 }
358 int verbose=0; if(status!=NULL) verbose=status->verbose-1;
359 if(verbose>10) {
360 printf("%s(ift, ", __func__);
361 if(line!=NULL) printf("\"%s\", ", line); else printf("NULL, ");
362 printf("%d)\n", is_comment_accepted);
363 }
364
365 /* Check if line is a comment line */
366 char *lptr=(char*)line; int i; char cmt;
367 if(asciiCommentLine(lptr, &i)) {cmt=(char)1; lptr+=i;} else cmt=(char)0;
368 /* If comment line requirement is not met, then return here */
369 if((is_comment_accepted==0 && cmt) || (is_comment_accepted==2 && !cmt)) {
370 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
371 return TPCERROR_OK;
372 }
373
374 /* Find the 'equals' sign, ' ' or '\t' */
375 char *eq_ptr;
376 eq_ptr=strstrNoQuotation(lptr, " ");
377 if(eq_ptr==NULL) eq_ptr=strstrNoQuotation(lptr, "\t");
378
379 /* key is required */
380 if(eq_ptr==NULL) {
381 if(verbose>50) printf("key required but space not found\n");
382 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
383 return TPCERROR_NO_KEY;
384 }
385
386 char *key=NULL, *value=NULL;
387 /* key starts after comment */
388 key=strndup(lptr, strlen(lptr)-strlen(eq_ptr));
389 if(verbose>100) printf("key before cleaning is '%s'\n", key);
390 strClean(key);
391 if(verbose>100) printf("key after cleaning is '%s'\n", key);
392 /* Find the end of the 'equals' sign; that is the start of value */
393 int j=strspn(eq_ptr, " \t"); value=strdup(eq_ptr+j);
394 if(verbose>100) printf("value before cleaning is '%s'\n", value);
395 strClean(value);
396 if(verbose>100) printf("value after cleaning is '%s'\n", value);
397
398 int ret=iftPut(ift, key, value, cmt, status);
399 free(key); free(value);
400 if(ret==0) statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
401 return ret;
402}
403/*****************************************************************************/
404
405/*****************************************************************************/
int strTimeValid(const char *str)
Definition datetime.c:284
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int iftPutFromString(IFT *ift, const char *line, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:229
int iftPutFromStringWithSpaceSeparator(IFT *ift, const char *line, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:339
int iftWriteItem(IFT *ift, int item, FILE *fp, TPCSTATUS *status)
Definition iftio.c:25
int iftWrite(IFT *ift, FILE *fp, TPCSTATUS *status)
Definition iftio.c:98
int iftRead(IFT *ift, FILE *fp, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:130
char * asciiFileRead(FILE *fp, char *data, size_t maxlen)
int asciiCommentLine(const char *line, int *cont)
size_t asciiFileSize(FILE *fp, int *nonprintable)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
char * strstrNoQuotation(const char *haystack, const char *needle)
Definition stringext.c:225
char * strdup(const char *s)
Definition stringext.c:185
char * strTokenDup(const char *s1, const char *s2, int *next)
Definition stringext.c:413
int strClean(char *s)
Definition stringext.c:389
char * strndup(const char *s, size_t n)
Definition stringext.c:205
char comment
Definition tpcift.h:27
char * value
Definition tpcift.h:37
char * key
Definition tpcift.h:32
Definition tpcift.h:43
IFT_ITEM * item
Definition tpcift.h:57
int space_after_eq
Definition tpcift.h:55
int type
Definition tpcift.h:51
int keyNr
Definition tpcift.h:47
int space_before_eq
Definition tpcift.h:53
int verbose
Verbose level, used by statusPrint() etc.
@ TPCERROR_FAIL
General error.
@ TPCERROR_TOO_BIG
File is too big.
@ TPCERROR_NO_KEY
Key not found.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
Header file for library libtpcift.