1 /******************************************************************************
2 * Copyright (c) 2000-2016 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
14 * Szabo, Janos Zoltan – initial implementation
17 ******************************************************************************/
18 /**************************
20 written by Gabor Tatarka
21 **************************/
27 #include "../common/version_internal.h"
30 #include "../common/license.h"
39 #define ERR_INVALID_LOG 2
41 /*filter flag values:*/
44 /*0 is: act as Wothers*/
47 #define SecondLength 9
48 #define DateTimeLength 27
49 #define MaxTimeStampLength 27
50 #define BufferSize 512
51 #define YYYYMONDD 1 /*format of Date: year/month/day*/
53 static const char * const MON
[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
54 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
57 typedef enum {/*If you add new types, add it to the end of the list, and
58 also add it to EventTypeNames! ET_Unknown has no representation
59 in text, and it must not be changed.Also change MaxType!*/
60 ET_Unknown
=-1,ET_Error
,ET_Warning
,ET_Portevent
,ET_Timerop
,
61 ET_Verdictop
,ET_Defaultop
,ET_Action
,ET_Testcase
,ET_Function
,
62 ET_User
,ET_Statictics
,ET_Parallel
,ET_Matching
,ET_Debug
,
65 static const char * const EventTypeNames
[] = {
66 "ERROR","WARNING","PORTEVENT","TIMEROP","VERDICTOP","DEFAULTOP",
67 "ACTION","TESTCASE","FUNCTION","USER","STATISTICS","PARALLEL",
68 "MATCHING","DEBUG","EXECUTOR"
70 static int Wothers
=Write
;
71 static int Wflags
[MaxType
];
73 static int IsSecond(const char *str
)/*Is timestamp format Seconds*/
76 if(*str
<'0'||*str
>'9')return False
;/*first digit*/
77 while(*str
>='0'&&*str
<='9')str
++;/*other digits*/
78 if(*str
!='.')return False
;/* '.' */
79 for(a
=0;a
<6;a
++)if(*str
<'0'||*str
>'9')return False
;/*microseconds(6 digits)*/
83 static int IsSecond2_6(const char *str
)/*does string contain sec(2).usec(6)*/
86 for(a
=0;a
<SecondLength
;a
++) {
92 if(*str
<'0'||*str
>'9')return False
;
98 static int IsTime(const char *str
)/*Is timestamp format Time*/
101 if(False
==IsSecond2_6(str
+6))return False
;
108 if(*str
<'0'||*str
>'9')return False
;
114 #ifdef YYYYMONDD /*Date format: year/month/day*/
117 #else /*Date format: day/month/year*/
122 static int IsDateTime(const char *str
)/*is timestamp format Date/Time*/
125 if(False
==IsTime(str
+12))return False
;
126 for(a
=0;a
<FIRST_LEN
;a
++) {/*YYYY or DD*/
127 if(*str
<'0'||*str
>'9')return False
;
130 if(*str
!='/')return False
;/* '/' */
132 for(a
=0,b
=0;a
<12;a
++)if(0==strncmp(str
,MON
[a
],3)){b
=1;break;}/*MON*/
135 if(*str
!='/')return False
;/* '/' */
137 for(a
=0;a
<THIRD_LEN
;a
++) {/*DD or YYYY*/
138 if(*str
<'0'||*str
>'9')return False
;
144 static int ValidTS(const char *str
)/*is timestamp of event valid*/
146 if(True
==IsSecond(str
))return True
;
147 if(True
==IsTime(str
))return True
;
148 if(True
==IsDateTime(str
))return True
;
152 static EventTypes
get_event_type(char *buf
)
156 ptr1
=buf
+strlen(buf
);
157 for(a
=0;a
<MaxType
;a
++) {
158 ptr2
=strstr(buf
,EventTypeNames
[a
]);
159 if(ptr2
<ptr1
&&ptr2
!=NULL
) {
161 if(*(ptr2
+strlen(EventTypeNames
[a
]))==' '&& *(ptr2
-1)==' '
162 && *(ptr2
+strlen(EventTypeNames
[a
])+1)!='|')
169 static int ProcessFile(FILE *out
,FILE *in
) /*filter infile to outfile*/
172 char line_buffer
[BufferSize
];
174 EventTypes current_event_type
=ET_Unknown
;
177 if(NULL
==fgets(line_buffer
,sizeof(line_buffer
),in
)) last_event
=1;
178 else if(ValidTS(line_buffer
)) {
179 current_event_type
=get_event_type(line_buffer
);
182 if(current_event_type
==ET_Unknown
&& Wothers
==Write
) {
183 if(0>fprintf(out
,"%s",line_buffer
))return ERR_WRITE
;
184 } else if(Wflags
[current_event_type
]==Write
||
185 (Wflags
[current_event_type
]==0 && Wothers
==Write
)) {
186 if(0>fprintf(out
,"%s",line_buffer
))return ERR_WRITE
;
190 if(!b
)return ERR_INVALID_LOG
;
191 else return ERR_NONE
;
194 static void Usage(const char *progname
)
197 "Usage: %s [-o outfile] [infile.log] [eventtype+|-] [...]\n"
200 " -o outfile: write merged logs into file outfile\n"
201 " -v: print version\n"
202 " -h: print help (usage)\n"
203 " -l: list event types\n"
204 "If there is no outfile specified output is stdout.\n"
205 "If infile is omitted input is stdin.\n"
206 "Including and excluding event types at the same time is not allowed.\n"
207 "\n",progname
,progname
);
210 static void ListTypes(void)
213 fprintf(stderr
,"Event types:\n");
214 for(a
=0;a
<MaxType
;a
++)fprintf(stderr
,"\t%s\n",EventTypeNames
[a
]);
217 int main(int argc
,char *argv
[])
220 FILE *outfile
= NULL
, *infile
= NULL
;
221 char *outfile_name
=NULL
,*infile_name
=NULL
;
223 int vflag
=0,oflag
=0,hflag
=0,lflag
=0,plusflag
=0,minusflag
=0;
227 while ((c
= getopt(argc
, argv
, "lhvo:")) != -1) {
229 case 'o':/*set outfile*/
233 case 'v':/*print version*/
236 case 'h':/*print help (usage)*/
239 case 'l':/*list event types*/
247 if (oflag
+ vflag
+ hflag
+ lflag
> 1) {
251 fputs("Log Filter for the TTCN-3 Test Executor\n"
252 "Product number: " PRODUCT_NUMBER
"\n"
253 "Build date: " __DATE__
" " __TIME__
"\n"
254 "Compiled with: " C_COMPILER_VERSION
"\n\n"
255 COPYRIGHT_STRING
"\n\n", stderr
);
257 print_license_info();
270 if (!verify_license(&lstr
)) {
275 if (!check_feature(&lstr
, FEATURE_LOGFORMAT
)) {
276 fputs("The license key does not allow the filtering of log files.\n",
284 switches: -v -o -h -l
285 filter parameters: parameter+ or parameter-
287 for(a
=0;a
<MaxType
;a
++)Wflags
[a
]=0;
288 for(a
=1;a
<argc
;a
++) {
289 if(*argv
[a
]=='-'){if(*(argv
[a
]+1)=='o')a
++;continue;}/*switch*/
290 if(*(argv
[a
]+strlen(argv
[a
])-1)=='-') {/*type to ignore*/
291 for(b
=0,c
=0;b
<MaxType
;b
++)
292 if(0==strncmp(EventTypeNames
[b
],argv
[a
],
293 strlen(EventTypeNames
[b
]))&&strlen(EventTypeNames
[b
])==
298 if(!c
) {/*Undefined type*/
299 strncpy(tmp
,argv
[a
],sizeof(tmp
)-1);
300 if(strlen(argv
[a
])>sizeof(tmp
)-1)
301 for(c
=2;c
<5;c
++)tmp
[sizeof(tmp
)-c
]='.';
302 else tmp
[strlen(argv
[a
])-1]='\0';
303 tmp
[sizeof(tmp
)-1]='\0';
304 if(strlen(tmp
))fprintf(stderr
,"Warning: %s is not a valid "
305 "event-type name.\n",tmp
);
306 else fprintf(stderr
,"Warning: `-\' without an event-type "
313 if(*(argv
[a
]+strlen(argv
[a
])-1)=='+') {/*type to write out*/
314 for(b
=0,c
=0;b
<MaxType
;b
++)
315 if(0==strncmp(EventTypeNames
[b
],argv
[a
],
316 strlen(EventTypeNames
[b
]))&&strlen(EventTypeNames
[b
])==
321 if(!c
) {/*Undefined type*/
322 strncpy(tmp
,argv
[a
],sizeof(tmp
)-1);
323 if(strlen(argv
[a
])>sizeof(tmp
)-1)
324 for(c
=2;c
<5;c
++)tmp
[sizeof(tmp
)-c
]='.';
325 else tmp
[strlen(argv
[a
])-1]='\0';
326 tmp
[sizeof(tmp
)-1]='\0';
327 if(strlen(tmp
))fprintf(stderr
,"Warning: %s is not a valid "
328 "event-type name.\n",tmp
);
329 else fprintf(stderr
,"Warning: `+\' without an event-type "
336 if(infile_name
!=NULL
) {/*only one input file at once*/
337 fprintf(stderr
,"Error: more than one input file specified.\n");
342 if(minusflag
&&plusflag
) {/*type1+ and type2- at the same time could cause
343 types that are not defined what to do with, to act based on the
344 last filter definition. Thus it is not allowed.*/
345 fprintf(stderr
,"Error: include and exclude at the same time.\n");
348 if(infile_name
==NULL
)infile
=stdin
;/*if no infile specified use stdin*/
350 infile
=fopen(infile_name
,"r");
352 fprintf(stderr
,"Error opening %s : %s\n",infile_name
,
358 outfile
=fopen(outfile_name
,"w");
360 fprintf(stderr
,"Error creating %s : %s\n",outfile_name
,
364 } else outfile
=stdout
;/*if no outfile specified use stdout*/
365 a
=ProcessFile(outfile
,infile
);/*filter infile to outfile*/
366 if(a
==ERR_INVALID_LOG
) {
367 if(infile_name
!=NULL
)fprintf(stderr
,"Error: the file %s is not a valid "
368 "log file.\n",infile_name
);
369 else fprintf(stderr
,"Error: invalid format received from standard "
372 } else if(a
==ERR_WRITE
) {
373 if(errno
)fprintf(stderr
,"Error writing to output: %s\n",
375 else fprintf(stderr
,"Error writing to output\n");