TPCCLIB
Loading...
Searching...
No Matches
iftisval.c
Go to the documentation of this file.
1
8/*****************************************************************************/
9#include "tpcclibConfig.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <math.h>
15/*****************************************************************************/
16#include "tpcextensions.h"
17#include "tpcift.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
21static char *info[] = {
22 "Check whether specified Interfile-type (IFT) key and value exist in",
23 "the header file, for example:",
24 " CALIBRATED := Yes",
25 "Key and value are case-insensitive.",
26 "Program returns 0, if key, and optional value, are found,",
27 "code 10, if key is not found, and 11, if key was found but without",
28 "matching value.",
29 " ",
30 "Usage: @P [options] filename [key [value]]",
31 " ",
32 "Options:",
33 "-lt | -gt | -abs=<limit>",
34 " Values are tested numerically (not as text), to be less (-lt) or",
35 " greater (-gt) than the given value, or the absolute difference is not",
36 " allowed to exceed the specified limit (-abs=<limit>)",
37 " -stdoptions", // List standard options like --help, -v, etc
38 " ",
39 "Example 1:",
40 " @P iea345ab.kbq calibrated yes",
41 "Example 2:",
42 " @P -abs=0.02 header.dat halflife 2.05",
43 " ",
44 "See also: iftadd, iftdel, iftlist, iftmatch, iftvalc",
45 " ",
46 "Keywords: header, IFT, tool",
47 0};
48/*****************************************************************************/
49
50/*****************************************************************************/
51/* Turn on the globbing of the command line, since it is disabled by default in
52 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
53 In Unix&Linux wildcard command line processing is enabled by default. */
54/*
55#undef _CRT_glob
56#define _CRT_glob -1
57*/
58int _dowildcard = -1;
59/*****************************************************************************/
60
61/*****************************************************************************/
65int main(int argc, char **argv)
66{
67 int ai, help=0, version=0, verbose=1;
68 int ret, m, li;
69 double test_abs=-1.0, v1, v2;
70 int test_lt=0, test_gt=0;
71 char *cptr, iftfile[FILENAME_MAX];
72 IFT ift;
73 char *key, *value;
74
75 /*
76 * Get arguments
77 */
78 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
79 iftInit(&ift); iftfile[0]=(char)0; key=value=NULL;
80 /* Options */
81 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
82 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
83 cptr=argv[ai]+1;
84 if(strncasecmp(cptr, "ABS=", 4)==0) {
85 test_abs=atofVerified(cptr+4); if(!isnan(test_abs)) continue;
86 } else if(strcasecmp(cptr, "LT")==0) {
87 test_lt=1; continue;
88 } else if(strcasecmp(cptr, "GT")==0) {
89 test_gt=1; continue;
90 }
91 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
92 free(key); free(value);
93 return(1);
94 } else break; // later arguments may start with '-'
95
96 /* Print help or version? */
97 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
98 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
99 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
100
101 TPCSTATUS status; statusInit(&status);
102 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
103 status.verbose=verbose;
104
105 /* Process other arguments, starting from the first non-option */
106 for(; ai<argc; ai++) {
107 if(!iftfile[0]) {
108 strcpy(iftfile, argv[ai]); continue;
109 } else if(key==NULL) {
110 key=strdup(argv[ai]); continue;
111 } else if(value==NULL) {
112 value=strdup(argv[ai]); continue;
113 }
114 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
115 free(key); free(value);
116 return(1);
117 }
118 /* Is something missing? */
119 if(key==NULL) {tpcPrintUsage(argv[0], info, stdout); return(1);}
120
121 /* In verbose mode print arguments and options */
122 if(verbose>1) {
123 for(ai=0; ai<argc; ai++)
124 printf("%s ", argv[ai]);
125 printf("\n");
126 printf("iftfile := %s\n", iftfile);
127 printf("key := %s\n", key);
128 printf("value := %s\n", value);
129 if(test_abs>=0.0) printf("test_abs := %g\n", test_abs);
130 printf("test_lt := %d\n", test_lt);
131 printf("test_gt := %d\n", test_gt);
132 }
133
134 /* If testing for numerical values, then get the test value */
135 ret=0; if(test_abs>=0.0) ret++; if(test_lt) ret++; if(test_gt) ret++;
136 if(ret>1) {
137 fprintf(stderr, "Error: invalid combination of options.\n");
138 free(key); free(value); return(1);
139 }
140 if(ret==1) {
141 if(value==NULL) {
142 fprintf(stderr,
143 "Error: value must be given with options -lt, -gt, and -abs.\n");
144 free(key); return(1);
145 }
146 ret=atofCheck(value, &v1);
147 if(ret!=0) {
148 fprintf(stderr, "Error: invalid numerical value for testing.\n");
149 free(key); free(value); return(1);
150 }
151 if(verbose>1) printf("numerical_value := %g\n", v1);
152 }
153
154 /*
155 * Read IFT file
156 */
157 if(verbose>1) printf("reading %s\n", iftfile);
158 FILE *fp=fopen(iftfile, "r"); if(fp==NULL) {
159 fprintf(stderr, "Error: cannot open file %s\n", iftfile);
160 free(key); free(value); return(2);
161 }
162 ret=iftRead(&ift, fp, 1, 1, &status); fclose(fp);
163 if(ret) {
164 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
165 free(key); free(value); iftFree(&ift); return(2);
166 }
167 if(verbose>2) printf("list size: %d item(s)\n", ift.keyNr);
168
169
170 /*
171 * Try to find the key
172 */
173 if(verbose>1) printf("searching for '%s'\n", key);
174 m=0;
175 do {
176 li=iftFindKey(&ift, key, m);
177 if(li<0) {
178 if(m==0 && verbose>0)
179 fprintf(stderr, " key \"%s\" was not found.\n", key);
180 else break;
181 iftFree(&ift); free(key); free(value); return(10);
182 }
183 m=li+1;
184
185 if(value==NULL) {
186 /* Key was found, value not specified, then everything is fine */
187 if(verbose>0)
188 fprintf(stdout, " key \"%s\" is found in %s\n", key, iftfile);
189 iftFree(&ift); free(key); free(value); return(0);
190 }
191
192 /* If value was specified, then check if they match */
193
194 /* If numerical values are to be tested, then get the number */
195 if(test_abs>=0 || test_lt>0 || test_gt>0) {
196 ret=doubleGetWithUnit(ift.item[li].value, &v2, NULL);
197 /* If key value was not numerical, try to find other matching key */
198 if(ret!=0) continue;
199 if(verbose>1) printf(" keys_numerical_value := %g\n", v2);
200 }
201
202 /* Test for abs difference, if requested */
203 if(test_abs>=0) {
204 if(verbose>2) printf("testing abs difference between %g and %g\n", v1, v2);
205 if(fabs(v1-v2)<=test_abs) {
206 /* Key was found, and value is matching, then everything is fine */
207 if(verbose>0)
208 fprintf(stdout, " key \"%s\" with matching value %g is found in %s\n",
209 key, v2, iftfile);
210 iftFree(&ift); free(key); free(value); return(0);
211 }
212 /* Else, try to find other matching key */
213 continue;
214 }
215 /* Test for less than value, if requested */
216 if(test_lt) {
217 if(verbose>2) printf("testing whether %g < %g\n", v2, v1);
218 if(v2<v1) {
219 /* Key was found, and value is matching, then everything is fine */
220 if(verbose>0) fprintf(stdout,
221 " key \"%s\" with value %g less than %g is found in %s\n",
222 key, v2, v1, iftfile);
223 iftFree(&ift); free(key); free(value); return(0);
224 }
225 /* Else, try to find other matching key */
226 continue;
227 }
228 /* Test for larger than value, if requested */
229 if(test_gt) {
230 if(verbose>2) printf("testing whether %g > %g\n", v2, v1);
231 if(v2>v1) {
232 /* Key was found, and value is matching, then everything is fine */
233 if(verbose>0) fprintf(stdout,
234 " key \"%s\" with value %g greater than %g is found in %s\n",
235 key, v2, v1, iftfile);
236 iftFree(&ift); free(key); free(value); return(0);
237 }
238 /* Else, try to find other matching key */
239 continue;
240 }
241
242 /* Check if strings do match */
243 if(strcasecmp(value, ift.item[li].value)==0) {
244 /* Key was found, and value is matching, then everything is fine */
245 if(verbose>0)
246 fprintf(stdout, " key \"%s\" with matching value \"%s\" is found in %s\n",
247 key, value, iftfile);
248 iftFree(&ift); free(key); free(value); return(0);
249 }
250
251 } while(li>=0); // try if next key would have matching value
252
253 /* We are here only if key was found but value did not match */
254 if(verbose>0) {
255 if(test_lt>0)
256 fprintf(stdout, " key \"%s\" had not value less than \"%s\" in %s\n",
257 key, value, iftfile);
258 else if(test_gt>0)
259 fprintf(stdout, " key \"%s\" had not value larger than \"%s\" in %s\n",
260 key, value, iftfile);
261 else
262 fprintf(stdout, " key \"%s\" with value \"%s\" was not found in %s\n",
263 key, value, iftfile);
264 }
265
266 iftFree(&ift); free(key); free(value);
267 return(11);
268}
269/*****************************************************************************/
270
271/*****************************************************************************/
double atofVerified(const char *s)
Definition decpoint.c:75
int atofCheck(const char *s, double *v)
Definition decpoint.c:94
int doubleGetWithUnit(const char *s, double *v, int *u)
Definition doubleutil.c:272
void iftFree(IFT *ift)
Definition ift.c:37
void iftInit(IFT *ift)
Definition ift.c:21
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int iftRead(IFT *ift, FILE *fp, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:130
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:47
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:169
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:339
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:114
void statusInit(TPCSTATUS *s)
Definition statusmsg.c:104
char * errorMsg(tpcerror e)
Definition statusmsg.c:68
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
char * strdup(const char *s)
Definition stringext.c:185
char * value
Definition tpcift.h:37
Definition tpcift.h:43
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
Header file for library libtpcextensions.
@ TPCERROR_OK
No error.
Header file for library libtpcift.