Merge pull request #70 from balaskoa/master
[deliverable/titan.core.git] / repgen / logmerge.c
CommitLineData
d44e3c4f 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
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Beres, Szabolcs
11 * Delic, Adam
12 * Lovassy, Arpad
13 * Raduly, Csaba
14 * Szabados, Kristof
15 * Szabo, Janos Zoltan – initial implementation
16 * Tatarka, Gabor
17 *
18 ******************************************************************************/
970ed795
EL
19/**************************
20Log-file merger
21written by Gabor Tatarka
22**************************/
23#include <stdio.h>
24#include <stdlib.h>
25#include <unistd.h>
26#include <string.h>
27#include <errno.h>
28#include <time.h>
29#include <signal.h>
30#include "../common/memory.h"
31#include "../common/version_internal.h"
32
33#ifdef LICENSE
34#include "../common/license.h"
35#endif
36
37#ifdef MINGW
38/* On MinGW seeking is not working in files opened in text mode due to a
39 * "feature" in the underlying MSVCRT. So we open all files in binary mode. */
40# define FOPEN_READ "rb"
41# define FOPEN_WRITE "wb"
42#else
43# define FOPEN_READ "r"
44# define FOPEN_WRITE "w"
45#endif
46
47#define Fail -1
48#define False 0
49#define True 1
50
51/* These lengths below represent the number of characters in the log file.
52 * No NUL terminator is included in the length. */
53#define TIMELENGTH 15
54#define SECONDLENGTH 9
55#define DATETIMELENGTH 27
56#define MAXTIMESTAMPLENGTH 27
57
58#define BUFFERSIZE 1024
59#define YYYYMONDD 1 /* format of Date: year/month/day*/
60
61static const char * const MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
62 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
63
64static const char *progname;
65static FILE *outfile = NULL;
66
67enum TimeStampFormats { TSF_Undefined = -1, TSF_Seconds, TSF_Time,
68 TSF_DateTime };
69static int TimeStampLength;
70static enum TimeStampFormats TimeStampUsed = TSF_Undefined;
71
72static int IsSecond(const char *str)/*Is timestamp format Seconds*/
73{
74 int i;
75 if (*str >= '0' && *str <= '9') str++; /* first digit */
76 else return False;
77 while (*str >= '0' && *str <= '9') str++; /* other digits */
78 if (*str == '.') str++;
79 else return False; /* '.' */
80 for (i = 0; i < 6; i++, str++)
81 if (*str < '0' || *str > '9') return False; /* microseconds(6 digits) */
82 return True;
83}
84
85static int IsSecond2_6(const char *str)/*does string contain sec(2).usec(6)*/
86{
87 int a;
88 for(a=0;a<SECONDLENGTH;a++) {
89 if(a==2) {
90 if(*str=='.') {
91 str++;continue;
92 } else return False;
93 }
94 if(*str<'0'||*str>'9')return False;
95 str++;
96 }
97 return True;
98}
99
100static int IsTime(const char *str)/*Is timestamp format Time*/
101{
102 int a;
103 if(False==IsSecond2_6(str+6))return False;
104 for(a=0;a<6;a++){
105 if(a==2||a==5) {
106 if(*str==':') {
107 str++;continue;
108 } else return False;
109 }
110 if(*str<'0'||*str>'9')return False;
111 str++;
112 }
113 return True;
114}
115
116#ifdef YYYYMONDD /*Date format: year/month/day*/
117# define FIRST_LEN 4
118# define THIRD_LEN 2
119#else /*Date format: day/month/year*/
120# define FIRST_LEN 2
121# define THIRD_LEN 4
122#endif
123
124static int IsDateTime(const char *str)/*is timestamp format Date/Time*/
125{
126 int a,b;
127 if(False==IsTime(str+12))return False;
128 for(a=0;a<FIRST_LEN;a++) {/*YYYY or DD*/
129 if(*str<'0'||*str>'9')return False;
130 str++;
131 }
132 if(*str!='/')return False;/* '/' */
133 str++;
134 for(a=0,b=0;a<12;a++)if(0==strncmp(str,MON[a],3)){b=1;break;}/*MON*/
135 if(!b)return False;
136 str+=3;
137 if(*str!='/')return False;/* '/' */
138 str++;
139 for(a=0;a<THIRD_LEN;a++) {/*DD or YYYY*/
140 if(*str<'0'||*str>'9')return False;
141 str++;
142 }
143 return True;
144}
145
146static int FormatMatch(const char *str,int format)/*does format of timestamp match format*/
147{
148 switch(format)
149 {
150 case TSF_Undefined:return False;
151 case TSF_Seconds:if(False==IsSecond(str))return False;else return True;
152 case TSF_Time:if(False==IsTime(str))return False;else return True;
153 case TSF_DateTime:if(False==IsDateTime(str))return False;
154 else return True;
155 default:return False;
156 }
157}
158
159/*
160formats:
161DateTime: yyyy/Mon/dd hh:mm:ss.us
162Time: hh:mm:ss.us
163Second: s.us
164*/
165static enum TimeStampFormats GetTimeStampFormat(const char *filename)
166{
167 /*get timestamp format used in file*/
168 enum TimeStampFormats ret_val = TSF_Undefined;
169 char str[MAXTIMESTAMPLENGTH + 1];
170 FILE *fp = fopen(filename, FOPEN_READ);
171 if (fp == NULL) {
172 fprintf(stderr, "%s: warning: cannot open %s: %s\n", progname,
173 filename, strerror(errno));
174 return TSF_Undefined;
175 }
176 if (fgets(str, sizeof(str), fp) != NULL) {
177 if (IsSecond(str)) ret_val = TSF_Seconds;
178 else if (IsTime(str)) ret_val = TSF_Time;
179 else if (IsDateTime(str)) ret_val = TSF_DateTime;
180 }
181 fclose(fp);
182 return ret_val;
183}
184
185static char *GetComponentIdentifier(const char *path_name)
186{
187 char *ret_val;
188 size_t name_len = strlen(path_name);
189 size_t filename_begin = 0, i;
190 size_t compid_begin, compid_end;
191 int dash_found = 0;
192 /* find the first character of the file name */
193 for (i = 0; i < name_len; i++)
194 if (path_name[i] == '/') filename_begin = i + 1;
195 /* fallback values if neither '-' nor '.' is found */
196 compid_begin = filename_begin;
197 compid_end = name_len;
198 /* find the last '-' character in the file name */
199 for (i = name_len; i > filename_begin; i--)
200 if (path_name[i - 1] == '-') {
201 dash_found = 1;
202 compid_begin = i;
203 break;
204 }
205 if (dash_found) {
206 /* find the first '.' character after the '-' */
207 for (i = compid_begin; i < name_len; i++)
208 if (path_name[i] == '.') {
209 compid_end = i;
210 break;
211 }
212 } else {
213 /* find the last '.' in the file name */
214 for (i = name_len; i > filename_begin; i--)
215 if (path_name[i - 1] == '.') {
216 compid_end = i - 1;
217 break;
218 }
219 /* find the last but one '.' in the file name */
220 for (i = compid_end; i > filename_begin; i--)
221 if (path_name[i - 1] == '.') {
222 compid_begin = i;
223 break;
224 }
225 }
226 if (compid_end > compid_begin) {
227 size_t compid_len = compid_end - compid_begin;
228 ret_val = (char*)Malloc(compid_len + 1);
229 memcpy(ret_val, path_name + compid_begin, compid_len);
230 ret_val[compid_len] = '\0';
231 } else ret_val = NULL;
232 return ret_val;
233}
234
235static FILE *OpenTempFile(char **filename)
236{
237 FILE *fp;
238#ifdef MINGW
239 /* Function mkstemp() is not supported on MinGW */
240 char *temp_name = tempnam(NULL, NULL);
241 if (temp_name == NULL) {
242 fprintf(stderr, "%s: creation of a temporary file failed: %s\n", progname,
243 strerror(errno));
244 exit(EXIT_FAILURE);
245 }
246 fp = fopen(temp_name, FOPEN_WRITE);
247 if (fp == NULL) {
248 fprintf(stderr, "%s: opening of temporary file `%s' failed: %s\n",
249 progname, temp_name, strerror(errno));
250 free(temp_name);
251 exit(EXIT_FAILURE);
252 }
253 *filename = mcopystr(temp_name);
254 free(temp_name);
255#else
256 int fd;
257 *filename = mcopystr("/tmp/logmerge_XXXXXX");
258 fd = mkstemp(*filename);
259 if (fd < 0) {
260 fprintf(stderr, "%s: creation of a temporary file based on template `%s' "
261 "failed: %s\n", progname, *filename, strerror(errno));
262 Free(*filename);
263 exit(EXIT_FAILURE);
264 }
265 fp = fdopen(fd, FOPEN_WRITE);
266 if (fp == NULL) {
267 fprintf(stderr, "%s: system call fdopen() failed on temporary file `%s' "
268 "(file descriptor %d): %s\n", progname, *filename, fd, strerror(errno));
269 Free(*filename);
270 exit(EXIT_FAILURE);
271 }
272#endif
273 return fp;
274}
275
276static FILE **fp_list_in = NULL, *fpout;
277static char **name_list_in = NULL;
278static int fpout_is_closeable = 0,must_use_temp = 0;
279static char **temp_file_list = NULL;
280static int num_tempfiles = 0, num_infiles = 0, num_allfiles = 0,start_file = 0;
281static int infiles_processed = False;
282typedef struct
283{
284 char timestamp[MAXTIMESTAMPLENGTH+1];/*text of timestamp*/
285 time_t sec; /*seconds in timestamp (since 1970)*/
286 unsigned long usec; /*microseconds in timestamp (0L..1000000L)*/
287 int wrap;/*if current timestamp is smaller than prev. timestamp -> wrap++;*/
288 expstring_t data;/*text of logged event*/
289 char *str_to_add;/*part of original filename*/
290 int ignore; /* if true -> EOF */
291 long start_line,line_ctr;/*line of event start (timestamp), line counter*/
292}LogEvent;
293
294static LogEvent **EventList;
295
296static int OpenMaxFiles(int argc,char *argv[])
297{
298 int a=0;
299 while(argc) {
300 fp_list_in=(FILE **)Realloc(fp_list_in,(a+1)*sizeof(FILE *));
301 errno = 0;
302 fp_list_in[a]=fopen(argv[a], FOPEN_READ);
303 if(fp_list_in[a]==NULL) {
304 switch(errno) {
305 case 0:
306 /* Solaris may not set errno if libc cannot create a stdio
307 stream because the underlying fd is greater than 255 */
308 case ENFILE:
309 case EMFILE:
310/*more infiles than can be opened->close one and create a tempfile for output*/
311 if(argc>0) {
312 Free(EventList[--a]->str_to_add);
313 Free(EventList[ a]);
314 fclose(fp_list_in[a]);
315 temp_file_list = (char**)Realloc(temp_file_list,
316 (num_tempfiles + 1) * sizeof(*temp_file_list));
317 fpout = OpenTempFile(temp_file_list + num_tempfiles);
318 num_tempfiles++;
319 fpout_is_closeable=1;
320 }
321 num_infiles=a;
322 return a;
323 default:
324 fprintf(stderr,"%s: error opening input file %s: %s\n",
325 progname, argv[a], strerror(errno));
326 exit(EXIT_FAILURE);
327 }
328 } else {
329 EventList=(LogEvent **)Realloc(EventList,
330 (a+1)*sizeof(LogEvent *));
331 EventList[a]=(LogEvent *)Malloc(sizeof(LogEvent));
332 if (infiles_processed) EventList[a]->str_to_add = NULL;
333 else {
334 /* cutting the component identifier portion out from the
335 * file name */
336 EventList[a]->str_to_add =
337 GetComponentIdentifier(name_list_in[a + start_file]);
338 }
339 EventList[a]->ignore=True;
340 EventList[a]->data=NULL;
341 EventList[a]->wrap=0;
342 EventList[a]->sec=0;
343 EventList[a]->usec=0L;
344 EventList[a]->line_ctr=1L;
345 EventList[a]->start_line=1L;
346 ++a;
347 }
348 argc--;
349 }
350 if (must_use_temp) {
351 temp_file_list = (char**)Realloc(temp_file_list,
352 (num_tempfiles + 1) * sizeof(*temp_file_list));
353 fpout = OpenTempFile(temp_file_list + num_tempfiles);
354 num_tempfiles++;
355 fpout_is_closeable = 1;
356 } else {
357 fpout = outfile;
358 if (outfile!=stdout) fpout_is_closeable = 1;
359 else fpout_is_closeable = 0;
360 }
361 num_infiles=a;
362 return a;/*nr. of opened files*/
363}
364
365static void CloseAllFiles(void)
366{
367 int i;
368 if (fpout_is_closeable) fclose(fpout);
369 for (i = 0; i < num_infiles; i++) {
370 Free(EventList[i]->data);
371 Free(EventList[i]->str_to_add);
372 Free(EventList[i]);
373 }
374 Free(EventList);
375 EventList = NULL;
376 num_infiles = 0;
377}
378
379static int EventCmp(LogEvent *e1,LogEvent *e2)
380/*Returns: if(event1<event2)-1;
381if(event1==event2)0;
382if(event1>event2)1;*/
383{
384 time_t tmpsec1,tmpsec2;
385 tmpsec1=e1->sec;
386 tmpsec2=e2->sec;
387 if(tmpsec1<tmpsec2)return -1;
388 if(tmpsec1>tmpsec2)return 1;
389 if(e1->usec<e2->usec)return -1;
390 if(e1->usec>e2->usec)return 1;
391 return 0;
392}
393
394#ifdef YYYYMONDD
395#define YearOffset 0
396#define MonOffset 5
397#define DayOffset 9
398#else
399#define DayOffset 0
400#define MonOffset 3
401#define YearOffset 7
402#endif
403
404static void TS2long(time_t *sec, unsigned long *usec, const char *TSstr)
405/*converts timestamp string to two long values*/
406{
407 struct tm TM;
408 int a;
409 char *ptr,str[MAXTIMESTAMPLENGTH+1];
410 strncpy(str,TSstr,MAXTIMESTAMPLENGTH);
411 str[MAXTIMESTAMPLENGTH] = '\0';
412 /*->this way only a copy of the timestamp string will be modified*/
413 switch(TimeStampUsed) {
414 case TSF_Seconds:
415 ptr=strpbrk(str,".");
416 *ptr='\0';ptr++;*(ptr+6)='\0';
417 *sec=(time_t)atol(str);
418 *usec=atol(ptr);
419 return;
420 case TSF_Time:
421 TM.tm_year = 70;
422 TM.tm_mon = 0;
423 TM.tm_mday = 1;
424 TM.tm_isdst = -1;
425 *(str+2)='\0';
426 *(str+5)='\0';
427 *(str+8)='\0';
428 *(str+15)='\0';
429 TM.tm_hour = atoi(str);
430 TM.tm_min = atoi(str+3);
431 TM.tm_sec = atoi(str+6);
432 *usec = atol(str+9);
433 break;
434 case TSF_DateTime:
435 *(str+YearOffset+4)='\0';*(str+MonOffset+3)='\0';
436 *(str+DayOffset+2)='\0';
437 TM.tm_year=atoi(str+YearOffset)-1900;
438 for(a=0;a<12;a++)if(!strcmp(MON[a],str+MonOffset)) {
439 TM.tm_mon=a;break;
440 }
441 TM.tm_mday=atoi(str+DayOffset);TM.tm_isdst=-1;
442 ptr=str+12;
443 *(ptr+2)='\0';*(ptr+5)='\0';*(ptr+8)='\0';
444 *(ptr+15)='\0';
445 TM.tm_hour=atoi(ptr);TM.tm_min=atoi(ptr+3);
446 TM.tm_sec=atoi(ptr+6);*usec=atol(ptr+9);
447 break;
448 default:
449 *sec = 0;
450 *usec = 0;
451 return;
452 }
453 *sec = mktime(&TM);
454}
455
456static int GetEvent(FILE *fp, LogEvent *event)
457{
458 time_t prev_sec;
459 unsigned long prev_usec;
460 for ( ; ; ) {
461 /* find and read timestamp */
462 if (fgets(event->timestamp, TimeStampLength + 1, fp) == NULL) {
463 event->ignore = True;
464 return False;
465 }
466 event->start_line=event->line_ctr;
467 if (FormatMatch(event->timestamp, TimeStampUsed)) break;
468 }
469 prev_sec = event->sec;
470 prev_usec = event->usec;
471 TS2long(&event->sec, &event->usec, event->timestamp);
472 if (event->sec < prev_sec ||
473 (event->sec == prev_sec && event->usec < prev_usec)) {
474 event->wrap = 1;
475 }
476 event->ignore = False;
477 for ( ; ; ) {
478 size_t a;
479 char buf[BUFFERSIZE];
480 /* read the log-event */
481 if (fgets(buf, sizeof(buf), fp) == NULL) {
482 /* EOF was detected */
483 if (event->data == NULL) event->data = mcopystr("\n");
484 else if (event->data[mstrlen(event->data) - 1] != '\n')
485 event->data = mputc(event->data, '\n');
486 return False;
487 }
488 a = strlen(buf);
489 if(FormatMatch(buf,TimeStampUsed)) {/*Did we read the next event's timestamp?*/
490 fseek(fp, -1L * a, SEEK_CUR);/*"unread" next event*/
491 break;
492 } else if (buf[a - 1] == '\n') event->line_ctr++;
493 event->data=mputstr(event->data, buf);/*append buffer to event-data*/
494 }
495 return True;
496}
497
498static void WriteError(void)
499{
500 fprintf(stderr, "%s: error: writing to %s file failed: %s\n",
501 progname, fpout == outfile ? "output" : "temporary", strerror(errno));
502 exit(EXIT_FAILURE);
503}
504
505static void FlushEvent(LogEvent *event)
506{
507 if (fputs(event->timestamp, fpout) == EOF) WriteError();
508 if (!infiles_processed && event->str_to_add != NULL) {
509 if (putc(' ', fpout) == EOF) WriteError();
510 if (fputs(event->str_to_add, fpout) == EOF) WriteError();
511 }
512 if (fputs(event->data, fpout) == EOF) WriteError();
513 Free(event->data);
514 event->data = NULL;
515 event->ignore = True;
516}
517
518static void ProcessOpenFiles(void)
519/*merge all opened files to fpout (that is stdout or outfile or a tempfile),
520and clean up*/
521{
522 int i;
523 for (i = 0; i < num_infiles; i++) {
524 /* read first logged event from all opened files */
525 if (!GetEvent(fp_list_in[i], EventList[i])) {
526 /* EOF or read error (e.g. file contained only one log event) */
527 fclose(fp_list_in[i]);
528 fp_list_in[i] = NULL;
529 }
530 }
531 for ( ; ; ) {
532 /* find the earliest timestamp */
533 int min_index = -1;
534 for (i = 0; i < num_infiles; i++) {
535 if (!EventList[i]->ignore && (min_index < 0 ||
536 EventCmp(EventList[min_index], EventList[i]) > 0))
537 min_index = i;
538 }
539 if (min_index < 0) break; /* no more events */
540 FlushEvent(EventList[min_index]);
541 if (fp_list_in[min_index] != NULL) {
542 /* read the next event from that file */
543 EventList[min_index]->wrap = 0;
544 if (!GetEvent(fp_list_in[min_index], EventList[min_index])) {
545 /*EOF or read error*/
546 fclose(fp_list_in[min_index]);
547 fp_list_in[min_index] = NULL;
548 }
549 if (!infiles_processed && EventList[min_index]->wrap > 0) {
550 fprintf(stderr,"%s: warning: timestamp is in wrong order "
551 "in file %s line %ld\n", progname,
552 name_list_in[min_index + start_file],
553 EventList[min_index]->start_line);
554 }
555 }
556 }
557 for (i = 0; i < num_infiles; i++) {
558 if (fp_list_in[i] != NULL) fclose(fp_list_in[i]);
559 }
560 Free(fp_list_in);
561 fp_list_in = NULL;
562}
563
564static void DelTemp(void)
565{
566 int a;
567 for(a=0;a<num_tempfiles;a++) {
568 fprintf(stderr, "%s: deleting temporary file %s\n", progname,
569 temp_file_list[a]);
570 remove(temp_file_list[a]);
571 Free(temp_file_list[a]);
572 }
573 Free(temp_file_list);
574}
575
576static void Usage(void)
577{
578 fprintf(stderr,
579 "Usage: %s [-o outfile] file1.log [file2.log ...]\n"
580 " or %s -v\n"
581 "options:\n"
582 " -o outfile: write merged logs into file outfile\n"
583 " -v: print version\n"
584 "If there is no outfile specified output is stdout.\n\n",
585 progname,progname);
586}
587
588static void ControlChandler(int x)
589{
590 (void)x;
591 /* the temporary files will be deleted by exit() */
592 exit(EXIT_FAILURE);
593}
594
595int main(int argc,char *argv[])
596{
597 int a,b,c,processed_files=0,filename_count=0;
598 char *outfile_name=NULL;
599 int vflag=0,oflag=0;
600#ifdef LICENSE
601 license_struct lstr;
602#endif
603 progname=argv[0];
604 atexit(DelTemp);
605 signal(SIGINT,ControlChandler);
606 while ((c = getopt(argc, argv, "vo:")) != -1) {
607 switch (c) {
608 case 'o':
609 outfile_name=optarg;
610 oflag = 1;
611 break;
612 case 'v':
613 vflag=1;
614 break;
615 default: Usage();return 0;
616 }
617 }
618 if(oflag&&vflag){Usage();return 0;}/*both switches are used*/
619 if(vflag) {
620 fputs("Log Merger for the TTCN-3 Test Executor\n"
621 "Product number: " PRODUCT_NUMBER "\n"
622 "Build date: " __DATE__ " " __TIME__ "\n"
623 "Compiled with: " C_COMPILER_VERSION "\n\n"
624 COPYRIGHT_STRING "\n\n", stderr);
625#ifdef LICENSE
626 print_license_info();
627#endif
628 return 0;
629 }
630#ifdef LICENSE
631 init_openssl();
632 load_license(&lstr);
633 if (!verify_license(&lstr)) {
634 free_license(&lstr);
635 free_openssl();
636 exit(EXIT_FAILURE);
637 }
638 if (!check_feature(&lstr, FEATURE_LOGFORMAT)) {
639 fputs("The license key does not allow the merging of log files.\n",
640 stderr);
641 return 2;
642 }
643 free_license(&lstr);
644 free_openssl();
645#endif
646 argc-=optind-1;argv+=optind-1;
647 if(argc<2){Usage();return 0;}/*executed when no input file is given*/
648 for(a=1;a<argc;a++) {/*find first file with a valid timestamp*/
649 TimeStampUsed=GetTimeStampFormat(argv[a]);
650 if(TimeStampUsed!=TSF_Undefined)break;
651 }
652 switch(TimeStampUsed) {
653 case TSF_Seconds: fputs("Merging logs with timestamp "
654 "format \"seconds\" has no sense.\n", stderr); return 0;
655 case TSF_Time: TimeStampLength=TIMELENGTH;break;
656 case TSF_DateTime: TimeStampLength=DATETIMELENGTH;break;
657 default: fputs("Unsupported timestamp format.\n", stderr); return 1;
658 }
659 for(a=1,c=0;a<argc;a++) {/*get files with valid timestamp format*/
660 b=GetTimeStampFormat(argv[a]);
661 if(TimeStampUsed==b) {/*file conains at least one valid timestamp*/
662 c++;
663 name_list_in=(char **)Realloc(name_list_in,c*sizeof(char *));
664 name_list_in[c-1] = mcopystr(argv[a]);
665 } else if(b==TSF_Undefined)/*file contains no timestamp or uses a
666 different format than the first match*/
667 fprintf(stderr,"Warning: unknown format in %s\n",argv[a]);
668 else fprintf(stderr,"Warning: format mismatch in %s\n",argv[a]);
669 }
670 num_allfiles=c;
671 if(num_allfiles<1){Usage();return 0;}/*no valid log file found*/
672 if(oflag){/*switch [-o outfile] is used -> create outfile*/
673 outfile = fopen(outfile_name, FOPEN_WRITE);
674 if(outfile==NULL) {
675 fprintf(stderr,"Error creating %s %s\n",outfile_name,strerror(errno));
676 return 1;
677 }
678 } else {
679 outfile = stdout;
680 }
681 while(1) {
682 filename_count=num_allfiles;start_file=0;
683 while(num_allfiles>0) {/*process files in name_list_in*/
684 processed_files=OpenMaxFiles(num_allfiles,name_list_in+start_file);
685 must_use_temp=True;/*if there are infiles remaining use tempfiles
686 for all*/
687 if((processed_files<2)&&(num_allfiles>1)){fprintf(stderr,"Error: "
688 "can not open enough files.\nMore descriptors required "
689 "(set with the command `limit descriptors\')\n");return 1;}
690 if(infiles_processed==True)
691 for(a=0;a<processed_files;a++) {
692 Free(EventList[a]->str_to_add);
693 EventList[a]->str_to_add = NULL;
694 }
695 num_allfiles-=processed_files;
696 ProcessOpenFiles();
697 CloseAllFiles();
698 start_file+=processed_files;
699 }
700 must_use_temp=False;/*all infiles processed*/
701 /*remove temporary files used in previous step*/
702 if(infiles_processed==True)
703 for(a=0;a<filename_count;a++)remove(name_list_in[a]);
704 infiles_processed=True;
705 for(a=0;a<filename_count;a++)Free(name_list_in[a]);
706 Free(name_list_in);
707 if(num_tempfiles==0)break;/*no more file to process*/
708 name_list_in=temp_file_list;/*process tempfiles*/
709 num_allfiles=num_tempfiles;
710 num_tempfiles=0;temp_file_list=NULL;
711 }
712 check_mem_leak(progname);
713 return 0;
714}
This page took 0.051639 seconds and 5 git commands to generate.