1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 /**************************
10 written by Gabor Tatarka
11 **************************/
17 #include "../common/version_internal.h"
20 #include "../common/license.h"
29 #define ERR_INVALID_LOG 2
31 /*filter flag values:*/
34 /*0 is: act as Wothers*/
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*/
43 static const char * const MON
[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
44 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
47 typedef 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
,
55 static const char * const EventTypeNames
[] = {
56 "ERROR","WARNING","PORTEVENT","TIMEROP","VERDICTOP","DEFAULTOP",
57 "ACTION","TESTCASE","FUNCTION","USER","STATISTICS","PARALLEL",
58 "MATCHING","DEBUG","EXECUTOR"
60 static int Wothers
=Write
;
61 static int Wflags
[MaxType
];
63 static int IsSecond(const char *str
)/*Is timestamp format Seconds*/
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)*/
73 static int IsSecond2_6(const char *str
)/*does string contain sec(2).usec(6)*/
76 for(a
=0;a
<SecondLength
;a
++) {
82 if(*str
<'0'||*str
>'9')return False
;
88 static int IsTime(const char *str
)/*Is timestamp format Time*/
91 if(False
==IsSecond2_6(str
+6))return False
;
98 if(*str
<'0'||*str
>'9')return False
;
104 #ifdef YYYYMONDD /*Date format: year/month/day*/
107 #else /*Date format: day/month/year*/
112 static int IsDateTime(const char *str
)/*is timestamp format Date/Time*/
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
;
120 if(*str
!='/')return False
;/* '/' */
122 for(a
=0,b
=0;a
<12;a
++)if(0==strncmp(str
,MON
[a
],3)){b
=1;break;}/*MON*/
125 if(*str
!='/')return False
;/* '/' */
127 for(a
=0;a
<THIRD_LEN
;a
++) {/*DD or YYYY*/
128 if(*str
<'0'||*str
>'9')return False
;
134 static int ValidTS(const char *str
)/*is timestamp of event valid*/
136 if(True
==IsSecond(str
))return True
;
137 if(True
==IsTime(str
))return True
;
138 if(True
==IsDateTime(str
))return True
;
142 static EventTypes
get_event_type(char *buf
)
146 ptr1
=buf
+strlen(buf
);
147 for(a
=0;a
<MaxType
;a
++) {
148 ptr2
=strstr(buf
,EventTypeNames
[a
]);
149 if(ptr2
<ptr1
&&ptr2
!=NULL
) {
151 if(*(ptr2
+strlen(EventTypeNames
[a
]))==' '&& *(ptr2
-1)==' '
152 && *(ptr2
+strlen(EventTypeNames
[a
])+1)!='|')
159 static int ProcessFile(FILE *out
,FILE *in
) /*filter infile to outfile*/
162 char line_buffer
[BufferSize
];
164 EventTypes current_event_type
=ET_Unknown
;
167 if(NULL
==fgets(line_buffer
,sizeof(line_buffer
),in
)) last_event
=1;
168 else if(ValidTS(line_buffer
)) {
169 current_event_type
=get_event_type(line_buffer
);
172 if(current_event_type
==ET_Unknown
&& Wothers
==Write
) {
173 if(0>fprintf(out
,"%s",line_buffer
))return ERR_WRITE
;
174 } else if(Wflags
[current_event_type
]==Write
||
175 (Wflags
[current_event_type
]==0 && Wothers
==Write
)) {
176 if(0>fprintf(out
,"%s",line_buffer
))return ERR_WRITE
;
180 if(!b
)return ERR_INVALID_LOG
;
181 else return ERR_NONE
;
184 static void Usage(const char *progname
)
187 "Usage: %s [-o outfile] [infile.log] [eventtype+|-] [...]\n"
190 " -o outfile: write merged logs into file outfile\n"
191 " -v: print version\n"
192 " -h: print help (usage)\n"
193 " -l: list event types\n"
194 "If there is no outfile specified output is stdout.\n"
195 "If infile is omitted input is stdin.\n"
196 "Including and excluding event types at the same time is not allowed.\n"
197 "\n",progname
,progname
);
200 static void ListTypes(void)
203 fprintf(stderr
,"Event types:\n");
204 for(a
=0;a
<MaxType
;a
++)fprintf(stderr
,"\t%s\n",EventTypeNames
[a
]);
207 int main(int argc
,char *argv
[])
210 FILE *outfile
= NULL
, *infile
= NULL
;
211 char *outfile_name
=NULL
,*infile_name
=NULL
;
213 int vflag
=0,oflag
=0,hflag
=0,lflag
=0,plusflag
=0,minusflag
=0;
217 while ((c
= getopt(argc
, argv
, "lhvo:")) != -1) {
219 case 'o':/*set outfile*/
223 case 'v':/*print version*/
226 case 'h':/*print help (usage)*/
229 case 'l':/*list event types*/
237 if (oflag
+ vflag
+ hflag
+ lflag
> 1) {
241 fputs("Log Filter for the TTCN-3 Test Executor\n"
242 "Product number: " PRODUCT_NUMBER
"\n"
243 "Build date: " __DATE__
" " __TIME__
"\n"
244 "Compiled with: " C_COMPILER_VERSION
"\n\n"
245 COPYRIGHT_STRING
"\n\n", stderr
);
247 print_license_info();
260 if (!verify_license(&lstr
)) {
265 if (!check_feature(&lstr
, FEATURE_LOGFORMAT
)) {
266 fputs("The license key does not allow the filtering of log files.\n",
274 switches: -v -o -h -l
275 filter parameters: parameter+ or parameter-
277 for(a
=0;a
<MaxType
;a
++)Wflags
[a
]=0;
278 for(a
=1;a
<argc
;a
++) {
279 if(*argv
[a
]=='-'){if(*(argv
[a
]+1)=='o')a
++;continue;}/*switch*/
280 if(*(argv
[a
]+strlen(argv
[a
])-1)=='-') {/*type to ignore*/
281 for(b
=0,c
=0;b
<MaxType
;b
++)
282 if(0==strncmp(EventTypeNames
[b
],argv
[a
],
283 strlen(EventTypeNames
[b
]))&&strlen(EventTypeNames
[b
])==
288 if(!c
) {/*Undefined type*/
289 strncpy(tmp
,argv
[a
],sizeof(tmp
)-1);
290 if(strlen(argv
[a
])>sizeof(tmp
)-1)
291 for(c
=2;c
<5;c
++)tmp
[sizeof(tmp
)-c
]='.';
292 else tmp
[strlen(argv
[a
])-1]='\0';
293 tmp
[sizeof(tmp
)-1]='\0';
294 if(strlen(tmp
))fprintf(stderr
,"Warning: %s is not a valid "
295 "event-type name.\n",tmp
);
296 else fprintf(stderr
,"Warning: `-\' without an event-type "
303 if(*(argv
[a
]+strlen(argv
[a
])-1)=='+') {/*type to write out*/
304 for(b
=0,c
=0;b
<MaxType
;b
++)
305 if(0==strncmp(EventTypeNames
[b
],argv
[a
],
306 strlen(EventTypeNames
[b
]))&&strlen(EventTypeNames
[b
])==
311 if(!c
) {/*Undefined type*/
312 strncpy(tmp
,argv
[a
],sizeof(tmp
)-1);
313 if(strlen(argv
[a
])>sizeof(tmp
)-1)
314 for(c
=2;c
<5;c
++)tmp
[sizeof(tmp
)-c
]='.';
315 else tmp
[strlen(argv
[a
])-1]='\0';
316 tmp
[sizeof(tmp
)-1]='\0';
317 if(strlen(tmp
))fprintf(stderr
,"Warning: %s is not a valid "
318 "event-type name.\n",tmp
);
319 else fprintf(stderr
,"Warning: `+\' without an event-type "
326 if(infile_name
!=NULL
) {/*only one input file at once*/
327 fprintf(stderr
,"Error: more than one input file specified.\n");
332 if(minusflag
&&plusflag
) {/*type1+ and type2- at the same time could cause
333 types that are not defined what to do with, to act based on the
334 last filter definition. Thus it is not allowed.*/
335 fprintf(stderr
,"Error: include and exclude at the same time.\n");
338 if(infile_name
==NULL
)infile
=stdin
;/*if no infile specified use stdin*/
340 infile
=fopen(infile_name
,"r");
342 fprintf(stderr
,"Error opening %s : %s\n",infile_name
,
348 outfile
=fopen(outfile_name
,"w");
350 fprintf(stderr
,"Error creating %s : %s\n",outfile_name
,
354 } else outfile
=stdout
;/*if no outfile specified use stdout*/
355 a
=ProcessFile(outfile
,infile
);/*filter infile to outfile*/
356 if(a
==ERR_INVALID_LOG
) {
357 if(infile_name
!=NULL
)fprintf(stderr
,"Error: the file %s is not a valid "
358 "log file.\n",infile_name
);
359 else fprintf(stderr
,"Error: invalid format received from standard "
362 } else if(a
==ERR_WRITE
) {
363 if(errno
)fprintf(stderr
,"Error writing to output: %s\n",
365 else fprintf(stderr
,"Error writing to output\n");