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

IFT file i/o functions. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "tpcift.h"

Go to the source code of this file.

Functions

int iftWriteItem (IFT *ift, int item, FILE *fp, TPCSTATUS *status)
 
int iftWrite (IFT *ift, FILE *fp, TPCSTATUS *status)
 
int iftRead (IFT *ift, FILE *fp, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
 
int iftPutFromString (IFT *ift, const char *line, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
 
int iftPutFromStringWithSpaceSeparator (IFT *ift, const char *line, int is_comment_accepted, TPCSTATUS *status)
 

Detailed Description

IFT file i/o functions.

Definition in file iftio.c.

Function Documentation

◆ iftPutFromString()

int iftPutFromString ( IFT * ift,
const char * line,
int is_key_required,
int is_comment_accepted,
TPCSTATUS * status )

Process a given string to add key and value to IFT.

Either key or value can be empty, but not both of them.

See also
iftInit, iftDuplicate
Returns
tpcerror (TPCERROR_OK when successful).
Precondition
Before first use initialize the IFT struct with iftInit().
Author
Vesa Oikonen
Parameters
iftPointer to initiated IFT; previous contents are not changed.
linePointer to the string to be processed, e.g. "key := value"; extra space characters are excluded from key and value.
is_key_requiredSpecifies whether key name is required or not. If not required, then line contents without equals sign are assumed to represent a value string and key name in IFT struct is left empty.
  • 0 = key name is not required,
  • 1 = only lines with key and equals sign are read,
  • 2 = only lines with key and value separated by space are read.
is_comment_acceptedSpecifies whether comment lines are processed or not.
  • 0 = comment lines are not read,
  • 1 = also comment lines are read,
  • 2 = only comment lines are read.
statusPointer to status data; enter NULL if not needed.

Definition at line 229 of file iftio.c.

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}
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 iftPutFromStringWithSpaceSeparator(IFT *ift, const char *line, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:339
int asciiCommentLine(const char *line, int *cont)
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
int strClean(char *s)
Definition stringext.c:389
char * strndup(const char *s, size_t n)
Definition stringext.c:205
int verbose
Verbose level, used by statusPrint() etc.
@ TPCERROR_FAIL
General error.
@ TPCERROR_NO_KEY
Key not found.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.

Referenced by iftRead().

◆ iftPutFromStringWithSpaceSeparator()

int iftPutFromStringWithSpaceSeparator ( IFT * ift,
const char * line,
int is_comment_accepted,
TPCSTATUS * status )

Process a given string to add key and value to IFT.

Key and value must be present, with space character as the field separator.

See also
iftInit, iftDuplicate
Returns
tpcerror (TPCERROR_OK when successful).
Precondition
Before first use initialize the IFT struct with iftInit().
Author
Vesa Oikonen
Parameters
iftPointer to initiated IFT; previous contents are not changed.
linePointer to the string to be processed, e.g. "key value"; extra space characters are excluded from key and value.
is_comment_acceptedSpecifies whether comment lines are processed or not.
  • 0 = comment lines are not read,
  • 1 = also comment lines are read,
  • 2 = only comment lines are read.
statusPointer to status data; enter NULL if not needed.

Definition at line 339 of file iftio.c.

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}

Referenced by iftPutFromString(), and iftRead().

◆ iftRead()

int iftRead ( IFT * ift,
FILE * fp,
int is_key_required,
int is_comment_accepted,
TPCSTATUS * status )

Read IFT data into IFT structure.

Any previous contents of IFT are preserved. This function can read the initial ASCII part of files that contain also binary data in the end (from some Interfile images), but not the binary data itself.

See also
iftInit, iftWrite, iftFree
Returns
enum tpcerror (TPCERROR_OK when successful).
Precondition
Before first use initialize the IFT structure with iftInit().
Author
Vesa Oikonen
Parameters
iftPointer to IFT.
fpInput file pointer.
is_key_requiredSpecifies whether key name is required or not. If not required, then line contents without equals sign are assumed to represent a value string and key name in IFT struct is left empty.
  • 0 = key name is not required,
  • 1 = only lines with key and equals sign are read,
  • 2 = only lines with key and value separated by space are read.
is_comment_acceptedSpecifies whether comment lines are processed or not.
  • 0 = comment lines are not read,
  • 1 = also comment lines are read,
  • 2 = only comment lines are read.
statusPointer to status data; enter NULL if not needed.

Definition at line 130 of file iftio.c.

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}
int iftPutFromString(IFT *ift, const char *line, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:229
char * asciiFileRead(FILE *fp, char *data, size_t maxlen)
size_t asciiFileSize(FILE *fp, int *nonprintable)
char * strTokenDup(const char *s1, const char *s2, int *next)
Definition stringext.c:413
int keyNr
Definition tpcift.h:47
@ TPCERROR_TOO_BIG
File is too big.

Referenced by micropetHeaderRead(), parRead(), parReadLimits(), and tacRead().

◆ iftWrite()

int iftWrite ( IFT * ift,
FILE * fp,
TPCSTATUS * status )

Write the contents of IFT to the specified file pointer.

See also
iftWriteItem, iftInit, iftFree
Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
Parameters
iftPointer to IFT.
fpOutput file pointer.
statusPointer to status data; enter NULL if not needed.

Definition at line 98 of file iftio.c.

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}
int iftWriteItem(IFT *ift, int item, FILE *fp, TPCSTATUS *status)
Definition iftio.c:25

Referenced by parReadFIT(), parReadRES(), parWriteCSV(), parWriteIFT(), parWriteLimits(), tacWriteCSV(), tacWriteDFT(), tacWritePMOD(), and tacWriteSimple().

◆ iftWriteItem()

int iftWriteItem ( IFT * ift,
int item,
FILE * fp,
TPCSTATUS * status )

Write one item in IFT to the specified file pointer.

Use iftWrite() to write all IFT items.

See also
iftWrite, iftInit, iftFree
Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
Parameters
iftPointer to IFT.
itemIndex [0..keyNr-1] of key and value to print.
fpOutput file pointer.
statusPointer to status data; enter NULL if not needed.

Definition at line 25 of file iftio.c.

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}
char comment
Definition tpcift.h:27
char * value
Definition tpcift.h:37
char * key
Definition tpcift.h:32
IFT_ITEM * item
Definition tpcift.h:57
int space_after_eq
Definition tpcift.h:55
int type
Definition tpcift.h:51
int space_before_eq
Definition tpcift.h:53
@ TPCERROR_CANNOT_WRITE
Cannot write file.

Referenced by abssWrite(), and iftWrite().