Titan Core Initial Contribution
[deliverable/titan.core.git] / repgen / logfilter.c
CommitLineData
970ed795
EL
1///////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2000-2014 Ericsson Telecom AB
3// All rights reserved. This program and the accompanying materials
4// are made available under the terms of the Eclipse Public License v1.0
5// which accompanies this distribution, and is available at
6// http://www.eclipse.org/legal/epl-v10.html
7///////////////////////////////////////////////////////////////////////////////
8/**************************
9Log filter for TTCNv3
10written by Gabor Tatarka
11**************************/
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <string.h>
16#include <errno.h>
17#include "../common/version_internal.h"
18
19#ifdef LICENSE
20#include "../common/license.h"
21#endif
22
23#define Fail -1
24#define False 0
25#define True 1
26
27#define ERR_NONE 0
28#define ERR_WRITE 1
29#define ERR_INVALID_LOG 2
30
31/*filter flag values:*/
32#define Write 1
33#define DontWrite 2
34/*0 is: act as Wothers*/
35
36#define TimeLength 15
37#define SecondLength 9
38#define DateTimeLength 27
39#define MaxTimeStampLength 27
40#define BufferSize 512
41#define YYYYMONDD 1 /*format of Date: year/month/day*/
42
43static const char * const MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
44 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
45
46#define MaxType 15
47typedef enum {/*If you add new types, add it to the end of the list, and
48 also add it to EventTypeNames! ET_Unknown has no representation
49 in text, and it must not be changed.Also change MaxType!*/
50 ET_Unknown=-1,ET_Error,ET_Warning,ET_Portevent,ET_Timerop,
51 ET_Verdictop,ET_Defaultop,ET_Action,ET_Testcase,ET_Function,
52 ET_User,ET_Statictics,ET_Parallel,ET_Matching,ET_Debug,
53 ET_Executor
54 } EventTypes;
55static const char * const EventTypeNames[] = {
56 "ERROR","WARNING","PORTEVENT","TIMEROP","VERDICTOP","DEFAULTOP",
57 "ACTION","TESTCASE","FUNCTION","USER","STATISTICS","PARALLEL",
58 "MATCHING","DEBUG","EXECUTOR"
59 };
60static int Wothers=Write;
61static int Wflags[MaxType];
62
63static int IsSecond(const char *str)/*Is timestamp format Seconds*/
64{
65 int a;
66 if(*str<'0'||*str>'9')return False;/*first digit*/
67 while(*str>='0'&&*str<='9')str++;/*other digits*/
68 if(*str!='.')return False;/* '.' */
69 for(a=0;a<6;a++)if(*str<'0'||*str>'9')return False;/*microseconds(6 digits)*/
70 return True;
71}
72
73static int IsSecond2_6(const char *str)/*does string contain sec(2).usec(6)*/
74{
75 int a;
76 for(a=0;a<SecondLength;a++) {
77 if(a==2) {
78 if(*str=='.') {
79 str++;continue;
80 } else return False;
81 }
82 if(*str<'0'||*str>'9')return False;
83 str++;
84 }
85 return True;
86}
87
88static int IsTime(const char *str)/*Is timestamp format Time*/
89{
90 int a;
91 if(False==IsSecond2_6(str+6))return False;
92 for(a=0;a<6;a++){
93 if(a==2||a==5) {
94 if(*str==':') {
95 str++;continue;
96 } else return False;
97 }
98 if(*str<'0'||*str>'9')return False;
99 str++;
100 }
101 return True;
102}
103
104#ifdef YYYYMONDD /*Date format: year/month/day*/
105# define FIRST_LEN 4
106# define THIRD_LEN 2
107#else /*Date format: day/month/year*/
108# define FIRST_LEN 2
109# define THIRD_LEN 4
110#endif
111
112static int IsDateTime(const char *str)/*is timestamp format Date/Time*/
113{
114 int a,b;
115 if(False==IsTime(str+12))return False;
116 for(a=0;a<FIRST_LEN;a++) {/*YYYY or DD*/
117 if(*str<'0'||*str>'9')return False;
118 str++;
119 }
120 if(*str!='/')return False;/* '/' */
121 str++;
122 for(a=0,b=0;a<12;a++)if(0==strncmp(str,MON[a],3)){b=1;break;}/*MON*/
123 if(!b)return False;
124 str+=3;
125 if(*str!='/')return False;/* '/' */
126 str++;
127 for(a=0;a<THIRD_LEN;a++) {/*DD or YYYY*/
128 if(*str<'0'||*str>'9')return False;
129 str++;
130 }
131 return True;
132}
133
134static int ValidTS(const char *str)/*is timestamp of event valid*/
135{
136 if(True==IsSecond(str))return True;
137 if(True==IsTime(str))return True;
138 if(True==IsDateTime(str))return True;
139 return False;
140}
141
142static EventTypes get_event_type(char *buf)
143{
144 int a;
145 char *ptr1,*ptr2;
146 ptr1=buf+strlen(buf);
147 for(a=0;a<MaxType;a++) {
148 ptr2=strstr(buf,EventTypeNames[a]);
149 if(ptr2<ptr1&&ptr2!=NULL) {
150 ptr1=ptr2;
151 if(*(ptr2+strlen(EventTypeNames[a]))==' '&& *(ptr2-1)==' ')
152 return a;
153 }
154 }
155 return ET_Unknown;
156}
157
158static int ProcessFile(FILE *out,FILE *in) /*filter infile to outfile*/
159{
160 int b=0;
161 char line_buffer[BufferSize];
162 int last_event=0;
163 EventTypes current_event_type=ET_Unknown;
164 while(1) {
165 line_buffer[0]='\0';
166 if(NULL==fgets(line_buffer,sizeof(line_buffer),in)) last_event=1;
167 else if(ValidTS(line_buffer)) {
168 current_event_type=get_event_type(line_buffer);
169 b++;
170 }
171 if(current_event_type==ET_Unknown && Wothers==Write) {
172 if(0>fprintf(out,"%s",line_buffer))return ERR_WRITE;
173 } else if(Wflags[current_event_type]==Write ||
174 (Wflags[current_event_type]==0 && Wothers==Write)) {
175 if(0>fprintf(out,"%s",line_buffer))return ERR_WRITE;
176 }
177 if(last_event)break;
178 }
179 if(!b)return ERR_INVALID_LOG;
180 else return ERR_NONE;
181}
182
183static void Usage(const char *progname)
184{
185 fprintf(stderr,
186 "Usage: %s [-o outfile] [infile.log] [eventtype+|-] [...]\n"
187 " or %s option\n"
188 "options:\n"
189 " -o outfile: write merged logs into file outfile\n"
190 " -v: print version\n"
191 " -h: print help (usage)\n"
192 " -l: list event types\n"
193 "If there is no outfile specified output is stdout.\n"
194 "If infile is omitted input is stdin.\n"
195 "Including and excluding event types at the same time is not allowed.\n"
196 "\n",progname,progname);
197}
198
199static void ListTypes(void)
200{
201 int a;
202 fprintf(stderr,"Event types:\n");
203 for(a=0;a<MaxType;a++)fprintf(stderr,"\t%s\n",EventTypeNames[a]);
204}
205
206int main(int argc,char *argv[])
207{
208 int a,b,c;
209 FILE *outfile = NULL, *infile = NULL;
210 char *outfile_name=NULL,*infile_name=NULL;
211 char tmp[20];
212 int vflag=0,oflag=0,hflag=0,lflag=0,plusflag=0,minusflag=0;
213#ifdef LICENSE
214 license_struct lstr;
215#endif
216 while ((c = getopt(argc, argv, "lhvo:")) != -1) {
217 switch (c) {
218 case 'o':/*set outfile*/
219 outfile_name=optarg;
220 oflag = 1;
221 break;
222 case 'v':/*print version*/
223 vflag=1;
224 break;
225 case 'h':/*print help (usage)*/
226 hflag=1;
227 break;
228 case 'l':/*list event types*/
229 lflag=1;
230 break;
231 default:
232 Usage(argv[0]);
233 return EXIT_FAILURE;
234 }
235 }
236 if (oflag + vflag + hflag + lflag > 1) {
237 Usage(argv[0]);
238 return EXIT_FAILURE;
239 } else if (vflag) {
240 fputs("Log Filter for the TTCN-3 Test Executor\n"
241 "Product number: " PRODUCT_NUMBER "\n"
242 "Build date: " __DATE__ " " __TIME__ "\n"
243 "Compiled with: " C_COMPILER_VERSION "\n\n"
244 COPYRIGHT_STRING "\n\n", stderr);
245#ifdef LICENSE
246 print_license_info();
247#endif
248 return EXIT_SUCCESS;
249 } else if (hflag) {
250 Usage(argv[0]);
251 return EXIT_SUCCESS;
252 } else if(lflag) {
253 ListTypes();
254 return EXIT_SUCCESS;
255 }
256#ifdef LICENSE
257 init_openssl();
258 load_license(&lstr);
259 if (!verify_license(&lstr)) {
260 free_license(&lstr);
261 free_openssl();
262 exit(EXIT_FAILURE);
263 }
264 if (!check_feature(&lstr, FEATURE_LOGFORMAT)) {
265 fputs("The license key does not allow the filtering of log files.\n",
266 stderr);
267 return 2;
268 }
269 free_license(&lstr);
270 free_openssl();
271#endif
272/*
273switches: -v -o -h -l
274filter parameters: parameter+ or parameter-
275*/
276 for(a=0;a<MaxType;a++)Wflags[a]=0;
277 for(a=1;a<argc;a++) {
278 if(*argv[a]=='-'){if(*(argv[a]+1)=='o')a++;continue;}/*switch*/
279 if(*(argv[a]+strlen(argv[a])-1)=='-') {/*type to ignore*/
280 for(b=0,c=0;b<MaxType;b++)
281 if(0==strncmp(EventTypeNames[b],argv[a],
282 strlen(EventTypeNames[b]))&&strlen(EventTypeNames[b])==
283 strlen(argv[a])-1) {
284 Wflags[b]=DontWrite;
285 c=1;
286 }
287 if(!c) {/*Undefined type*/
288 strncpy(tmp,argv[a],sizeof(tmp)-1);
289 if(strlen(argv[a])>sizeof(tmp)-1)
290 for(c=2;c<5;c++)tmp[sizeof(tmp)-c]='.';
291 else tmp[strlen(argv[a])-1]='\0';
292 tmp[sizeof(tmp)-1]='\0';
293 if(strlen(tmp))fprintf(stderr,"Warning: %s is not a valid "
294 "event-type name.\n",tmp);
295 else fprintf(stderr,"Warning: `-\' without an event-type "
296 "name.\n");
297 }
298 Wothers=Write;
299 minusflag=1;
300 continue;
301 }
302 if(*(argv[a]+strlen(argv[a])-1)=='+') {/*type to write out*/
303 for(b=0,c=0;b<MaxType;b++)
304 if(0==strncmp(EventTypeNames[b],argv[a],
305 strlen(EventTypeNames[b]))&&strlen(EventTypeNames[b])==
306 strlen(argv[a])-1) {
307 Wflags[b]=Write;
308 c=1;
309 }
310 if(!c) {/*Undefined type*/
311 strncpy(tmp,argv[a],sizeof(tmp)-1);
312 if(strlen(argv[a])>sizeof(tmp)-1)
313 for(c=2;c<5;c++)tmp[sizeof(tmp)-c]='.';
314 else tmp[strlen(argv[a])-1]='\0';
315 tmp[sizeof(tmp)-1]='\0';
316 if(strlen(tmp))fprintf(stderr,"Warning: %s is not a valid "
317 "event-type name.\n",tmp);
318 else fprintf(stderr,"Warning: `+\' without an event-type "
319 "name.\n");
320 }
321 Wothers=DontWrite;
322 plusflag=1;
323 continue;
324 }
325 if(infile_name!=NULL) {/*only one input file at once*/
326 fprintf(stderr,"Error: more than one input file specified.\n");
327 return EXIT_FAILURE;
328 }
329 infile_name=argv[a];
330 }
331 if(minusflag&&plusflag) {/*type1+ and type2- at the same time could cause
332 types that are not defined what to do with, to act based on the
333 last filter definition. Thus it is not allowed.*/
334 fprintf(stderr,"Error: include and exclude at the same time.\n");
335 return EXIT_FAILURE;
336 }
337 if(infile_name==NULL)infile=stdin;/*if no infile specified use stdin*/
338 else {
339 infile=fopen(infile_name,"r");
340 if(infile==NULL) {
341 fprintf(stderr,"Error opening %s : %s\n",infile_name,
342 strerror(errno));
343 return EXIT_FAILURE;
344 }
345 }
346 if(oflag) {
347 outfile=fopen(outfile_name,"w");
348 if(outfile==NULL) {
349 fprintf(stderr,"Error creating %s : %s\n",outfile_name,
350 strerror(errno));
351 return EXIT_FAILURE;
352 }
353 } else outfile=stdout;/*if no outfile specified use stdout*/
354 a=ProcessFile(outfile,infile);/*filter infile to outfile*/
355 if(a==ERR_INVALID_LOG) {
356 if(infile_name!=NULL)fprintf(stderr,"Error: the file %s is not a valid "
357 "log file.\n",infile_name);
358 else fprintf(stderr,"Error: invalid format received from standard "
359 "input.\n");
360 return EXIT_FAILURE;
361 } else if(a==ERR_WRITE) {
362 if(errno)fprintf(stderr,"Error writing to output: %s\n",
363 strerror(errno));
364 else fprintf(stderr,"Error writing to output\n");
365 return EXIT_FAILURE;
366 }
367 return EXIT_SUCCESS;
368}
369
This page took 0.037856 seconds and 5 git commands to generate.