Browse Source

Fix #13 Sort files given as argument

Now ttail is able to sort logfiles given as arguement.
The sort function _ttail_file_sort place files with no valid date to the
end of the file list and is able to detect if some files overlaps.

No tests written...
Yann Weber 7 years ago
parent
commit
0bd8dd1e1f

+ 1
- 4
docs/man/man1/ttail.1 View File

@@ -1,4 +1,4 @@
1
-.TH "ttail" 1 "Mon May 15 2017" "Version 0.0.2" "ttail" \" -*- nroff -*-
1
+.TH "ttail" 1 "Sun May 21 2017" "Version 0.0.2" "ttail" \" -*- nroff -*-
2 2
 .ad l
3 3
 .nh
4 4
 .SH NAME
@@ -167,9 +167,6 @@ The O modifier specifies that the numerical input may be in an alternative local
167 167
 %OW The week number of the year (Monday as the first day of the week) using the locale's alternative numeric symbols\&.
168 168
 .PP
169 169
 %Oy The year (offset from C) using the locale's alternative numeric symbols\&.
170
-.SH "Known limitations"
171
-.PP
172
-Files given as argument has to be sorted\&.
173 170
 .SH "AUTHOR"
174 171
 .PP
175 172
 Written by Yann Weber <yann.weber@members.fsf.org>

+ 0
- 3
src/include/doxygen.h View File

@@ -161,9 +161,6 @@
161 161
  * 
162 162
  * \%Oy    The year (offset from %C) using the locale's alternative numeric symbols.
163 163
  *
164
- *@section known_limitations Known limitations
165
- *Files given as argument has to be sorted.
166
- *
167 164
  *@section AUTHOR
168 165
  *Written by Yann Weber &lt;yann.weber@members.fsf.org&gt;
169 166
  *

+ 35
- 0
src/include/ttail_search_files.h View File

@@ -87,6 +87,33 @@ struct _ttail_search_file_s
87 87
 /*<!Accessor to getline wrapper buffer */
88 88
 #define ttail_file_getline_buf(TTAIL) (TTAIL->session->file.buf)
89 89
 
90
+/**@brief Move an element to end
91
+ *@param void* v : array
92
+ *@param size_t i : elt to move
93
+ *@param size_t count : v elements count - 1
94
+ *@param type t : v type
95
+ */
96
+#define TTAIL_MVF(v, i, count, t) {\
97
+	t tmp;\
98
+	tmp = v[i];\
99
+	memmove(v+i, v+i+1, (count - i) * sizeof(t));\
100
+	v[count] = tmp;\
101
+}
102
+
103
+/**@brief Move back an element to j position
104
+ *@warning j < i
105
+ *@param void* v
106
+ *@param size_t i : src index
107
+ *@param size_t j : dst index
108
+ *@param type t : v type
109
+ */
110
+#define TTAIL_MVBF(v, i, j, t) {\
111
+	t tmp;\
112
+	tmp = v[i];\
113
+	memmove(v+j+1, v+j, (i - j)*sizeof(t));\
114
+	v[j] = tmp;\
115
+}
116
+
90 117
 /**@brief Init the ttail->session
91 118
  *@note Needed for format autodetection
92 119
  *@return 0 on success -1 on failure
@@ -157,6 +184,14 @@ int _ttail_file_reopen(ttail_t*, size_t);
157 184
  */
158 185
 inline int _ttail_file_minmax(ttail_t*, size_t, struct tm[2]);
159 186
 
187
+/**@brief Sort logfiles list
188
+ *@param ttail_t* ttail
189
+ *@param struct tm** ftm : files min and max date
190
+ *@return 0 on success -1 if error
191
+ *@todo write tests
192
+ */
193
+inline int _ttail_file_sort(ttail_t*, struct tm**);
194
+
160 195
 /**@brief Search next line
161 196
  *
162 197
  *Set f pos to next line begining and return the position

+ 79
- 16
src/ttail_search_files.c View File

@@ -21,9 +21,9 @@
21 21
 int _ttail_search_closest_files(ttail_t* t)
22 22
 {
23 23
 	int ret;
24
-	size_t i, prev;
25
-	struct tm **ftm; /* t->logfile_sz len of struct tm[2] */
26
-	char prev_found;
24
+	size_t i;
25
+	struct tm **ftm; /* an array with t->logfile_sz struct tm[2] */
26
+
27 27
 	/* Storing min & max of each files in ftm and checking that files are 
28 28
 	 * sorted well */
29 29
 	ftm = malloc(sizeof(struct tm*) * t->logfile_sz);
@@ -33,8 +33,6 @@ int _ttail_search_closest_files(ttail_t* t)
33 33
 		goto _ttail_search_closest_files_alloc_err;
34 34
 	}
35 35
 	ret = 0; /* to avoid may be used uninitialized error */
36
-	prev_found = 0;
37
-	prev = 0;
38 36
 	for(i=0; i<t->logfile_sz; i++)
39 37
 	{
40 38
 		if(!t->logfile[i])
@@ -66,18 +64,11 @@ in '%s'\n", t->logfile_name[i]);
66 64
 				ttail_strict_msg();
67 65
 				goto _ttail_search_closest_files_loop_err;
68 66
 			}
69
-			continue;
70 67
 		}
71
-		if(i && prev_found &&
72
-			ttail_tm_cmp(&(ftm[prev][1]), &(ftm[i][0])) > 0)
73
-		{
74
-			/* files are not sorted */
75
-			fprintf(stderr, "Files do not seems to be sorted. \
76
-File sorting not implemented yet\n");
77
-			goto _ttail_search_closest_files_loop_err;
78
-		}
79
-		prev_found = 1;
80
-		prev = i;
68
+	}
69
+	if(_ttail_file_sort(t, ftm) < 0)
70
+	{
71
+		goto _ttail_search_closest_files_err;
81 72
 	}
82 73
 	if(t->flag & TTAIL_FLAG_DATE_MIN)
83 74
 	{
@@ -744,6 +735,78 @@ int _ttail_file_reopen(ttail_t* t, size_t id)
744 735
 	return t->logfile[id]?0:-1;
745 736
 }
746 737
 
738
+inline int _ttail_file_sort(ttail_t* t, struct tm** ftm)
739
+{
740
+	size_t i, j, count;
741
+	short sorted, warn;
742
+
743
+	count = t->logfile_sz;
744
+	i=0;
745
+	warn = 0;
746
+	for(i=0;i<count;i++)
747
+	{
748
+		while(!ftm[i] && i<count)
749
+		{
750
+			//move invalid dates to the end
751
+			count--;
752
+			TTAIL_MVF(t->logfile_name, i, count, char*);
753
+			TTAIL_MVF(t->logfile, i, count, FILE*);
754
+			TTAIL_MVF(t->session->file.file_sz, i, count,
755
+				off_t);
756
+			TTAIL_MVF(t->session->file.vfile, i, count,
757
+				off_t);
758
+			TTAIL_MVF(ftm, i, count, struct tm*);
759
+		}
760
+		if(!i ||i == count|| ttail_tm_cmp(&(ftm[i-1][1]), &(ftm[i][0])) < 0)
761
+		{
762
+			continue;
763
+		}
764
+		sorted=0;
765
+		for(j=0; j<i;j++)
766
+		{
767
+			if(ttail_tm_cmp(&(ftm[i][1]), &(ftm[j][0])) < 0
768
+			   || (j > 0 && ttail_tm_cmp(&(ftm[i][0]), &(ftm[j-1][1])) > 0))
769
+			{
770
+				TTAIL_MVBF(t->logfile_name, i, j, char*);
771
+				TTAIL_MVBF(t->logfile, i, j, FILE*);
772
+				TTAIL_MVBF(t->session->file.file_sz, i, j,
773
+					off_t);
774
+				TTAIL_MVBF(t->session->file.vfile, i, j,
775
+					off_t);
776
+				TTAIL_MVBF(ftm, i, j, struct tm*);
777
+				sorted=1;
778
+				if(!warn && t->verbose > 1)
779
+				{
780
+					fprintf(stderr, "Warning : Files list \
781
+given as argument has to be sorted.\n");
782
+				}
783
+				break;
784
+			}
785
+			if((ttail_tm_cmp(&(ftm[i][0]), &(ftm[j][0])) < 0
786
+			   && ttail_tm_cmp(&(ftm[i][1]), &(ftm[j][0])) > 0) ||
787
+			   (j > 0 &&(
788
+			   ttail_tm_cmp(&(ftm[i][1]), &(ftm[j][1])) > 0 &&
789
+			   ttail_tm_cmp(&(ftm[i][0]), &ftm[j][1]) < 0)))
790
+			{
791
+				fprintf(stderr, "Files list not sortable : \
792
+file %s and %s overlaps.\n", t->logfile_name[i], t->logfile_name[j]);
793
+				fprintf(stderr,"\
794
+meaning file1 date min < file2 date min < file1 date max \n\
795
+or file1 date min < file2 date max < file1 date max\n");
796
+				return -1;
797
+			}
798
+		}
799
+		if(sorted) { continue; }
800
+
801
+		fprintf(stderr,"Files list not sortable : file %s contains \
802
+or is inside another file\n", t->logfile_name[i]);
803
+		fprintf(stderr,"meaning that filex1 date min < file2 date min \
804
+and file1 date max > file2 date max\n");
805
+		return -1;
806
+	}
807
+	return 0;
808
+}
809
+
747 810
 inline long _ttail_file_next_line(ttail_t *t, size_t id)
748 811
 {
749 812
 	FILE *f;

+ 1
- 1
tests/ttail_search_files.c View File

@@ -101,7 +101,7 @@ START_TEST (test_search_files3)
101 101
 
102 102
 	ret = _ttail_search_closest_files(ttail);
103 103
 	ck_assert_int_eq(ret, 0);
104
-	ck_assert_int_eq(ttail->session->file.off_min.id, 5);
104
+	ck_assert_int_eq(ttail->session->file.off_min.id, 1);
105 105
 	ck_assert_int_eq(ttail->session->file.off_min.off, 0);
106 106
 }
107 107
 END_TEST

Loading…
Cancel
Save