5e993f12 |
1 | --- busybox/miscutils/less.c 2006-04-22 08:20:29.000000000 +0100 |
2 | +++ busybox/miscutils/less.c 2006-04-23 11:28:08.000000000 +0100 |
3 | @@ -104,10 +104,11 @@ |
4 | |
5 | #ifdef CONFIG_FEATURE_LESS_REGEXP |
6 | static int match_found; |
7 | -static int match_lines[100]; |
8 | +static int *match_lines; |
9 | static int match_pos; |
10 | static int num_matches; |
11 | static int match_backwards; |
12 | +static regex_t old_pattern; |
13 | #endif |
14 | |
15 | /* Needed termios structures */ |
16 | @@ -235,14 +236,6 @@ |
17 | add_linenumbers(); |
18 | } |
19 | |
20 | -/* Turn a percentage into a line number */ |
21 | -static int reverse_percent(int percentage) |
22 | -{ |
23 | - double linenum = percentage; |
24 | - linenum = ((linenum / 100) * num_flines) - 1; |
25 | - return(linenum); |
26 | -} |
27 | - |
28 | #ifdef CONFIG_FEATURE_LESS_FLAGS |
29 | |
30 | /* Interestingly, writing calc_percent as a function and not a prototype saves around 32 bytes |
31 | @@ -463,12 +456,11 @@ |
32 | static void buffer_line(int linenum) |
33 | { |
34 | int i; |
35 | - |
36 | past_eof = 0; |
37 | |
38 | - if (linenum < 1 || linenum > num_flines) { |
39 | + if (linenum < 0 || linenum > num_flines) { |
40 | clear_line(); |
41 | - printf("%s%s%i%s", HIGHLIGHT, "Cannot seek to line number ", linenum, NORMAL); |
42 | + printf("%s%s%i%s", HIGHLIGHT, "Cannot seek to line number ", linenum + 1, NORMAL); |
43 | } |
44 | else if (linenum < (num_flines - height - 2)) { |
45 | for (i = 0; i < (height - 1); i++) { |
46 | @@ -476,6 +468,7 @@ |
47 | buffer[i] = bb_xstrdup(flines[linenum + i]); |
48 | } |
49 | line_pos = linenum; |
50 | + buffer_print(); |
51 | } |
52 | else { |
53 | for (i = 0; i < (height - 1); i++) { |
54 | @@ -488,6 +481,7 @@ |
55 | line_pos = linenum; |
56 | /* Set past_eof so buffer_down and buffer_up act differently */ |
57 | past_eof = 1; |
58 | + buffer_print(); |
59 | } |
60 | } |
61 | |
62 | @@ -610,46 +604,44 @@ |
63 | /* Get a regular expression from the user, and then go through the current |
64 | file line by line, running a processing regex function on each one. */ |
65 | |
66 | -static char *insert_highlights(char *line, int start, int end) |
67 | -{ |
68 | - return bb_xasprintf("%.*s%s%.*s%s%s", start, line, HIGHLIGHT, |
69 | - end - start, line + start, NORMAL, line + end); |
70 | -} |
71 | - |
72 | -static char *process_regex_on_line(char *line, regex_t *pattern) |
73 | +static char *process_regex_on_line(char *line, regex_t *pattern, int action) |
74 | { |
75 | /* This function takes the regex and applies it to the line. |
76 | Each part of the line that matches has the HIGHLIGHT |
77 | and NORMAL escape sequences placed around it by |
78 | - insert_highlights, and then the line is returned. */ |
79 | - |
80 | + insert_highlights if action = 1, or has the escape sequences |
81 | + removed if action = 0, and then the line is returned. */ |
82 | int match_status; |
83 | char *line2 = (char *) xmalloc((sizeof(char) * (strlen(line) + 1)) + 64); |
84 | - char sub_line[256]; |
85 | - int prev_eo = 0; |
86 | + char *growline = ""; |
87 | regmatch_t match_structs; |
88 | |
89 | - strcpy(line2, line); |
90 | + line2 = bb_xstrdup(line); |
91 | |
92 | match_found = 0; |
93 | match_status = regexec(pattern, line2, 1, &match_structs, 0); |
94 | - |
95 | + |
96 | while (match_status == 0) { |
97 | - |
98 | - memset(sub_line, 0, sizeof(sub_line)); |
99 | - |
100 | if (match_found == 0) |
101 | match_found = 1; |
102 | - |
103 | - line2 = insert_highlights(line2, match_structs.rm_so + prev_eo, match_structs.rm_eo + prev_eo); |
104 | - if ((size_t)match_structs.rm_eo + 11 + prev_eo < strlen(line2)) |
105 | - strcat(sub_line, line2 + match_structs.rm_eo + 11 + prev_eo); |
106 | - |
107 | - prev_eo += match_structs.rm_eo + 11; |
108 | - match_status = regexec(pattern, sub_line, 1, &match_structs, REG_NOTBOL); |
109 | + |
110 | + if (action) { |
111 | + growline = bb_xasprintf("%s%.*s%s%.*s%s", growline, match_structs.rm_so, line2, HIGHLIGHT, match_structs.rm_eo - match_structs.rm_so, line2 + match_structs.rm_so, NORMAL); |
112 | + } |
113 | + else { |
114 | + growline = bb_xasprintf("%s%.*s%.*s", growline, match_structs.rm_so - 4, line2, match_structs.rm_eo - match_structs.rm_so, line2 + match_structs.rm_so); |
115 | + } |
116 | + |
117 | + line2 += match_structs.rm_eo; |
118 | + match_status = regexec(pattern, line2, 1, &match_structs, REG_NOTBOL); |
119 | } |
120 | - |
121 | - return line2; |
122 | + |
123 | + growline = bb_xasprintf("%s%s", growline, line2); |
124 | + |
125 | + return (match_found ? growline : line); |
126 | + |
127 | + free(growline); |
128 | + free(line2); |
129 | } |
130 | |
131 | static void goto_match(int match) |
132 | @@ -665,11 +657,10 @@ |
133 | static void regex_process(void) |
134 | { |
135 | char uncomp_regex[100]; |
136 | - char current_line[256]; |
137 | + char *current_line; |
138 | int i; |
139 | int j = 0; |
140 | regex_t pattern; |
141 | - |
142 | /* Get the uncompiled regular expression from the user */ |
143 | clear_line(); |
144 | putchar((match_backwards) ? '?' : '/'); |
145 | @@ -677,32 +668,43 @@ |
146 | fgets(uncomp_regex, sizeof(uncomp_regex), inp); |
147 | |
148 | if (strlen(uncomp_regex) == 1) { |
149 | - goto_match(match_backwards ? match_pos - 1 : match_pos + 1); |
150 | - buffer_print(); |
151 | + if (num_matches) |
152 | + goto_match(match_backwards ? match_pos - 1 : match_pos + 1); |
153 | + else |
154 | + buffer_print(); |
155 | return; |
156 | } |
157 | - |
158 | uncomp_regex[strlen(uncomp_regex) - 1] = '\0'; |
159 | |
160 | /* Compile the regex and check for errors */ |
161 | xregcomp(&pattern, uncomp_regex, 0); |
162 | |
163 | + if (num_matches) { |
164 | + /* Get rid of all the highlights we added previously */ |
165 | + for (i = 0; i <= num_flines; i++) { |
166 | + current_line = process_regex_on_line(flines[i], &old_pattern, 0); |
167 | + flines[i] = bb_xstrdup(current_line); |
168 | + } |
169 | + } |
170 | + old_pattern = pattern; |
171 | + |
172 | /* Reset variables */ |
173 | + match_lines = xrealloc(match_lines, sizeof(int)); |
174 | match_lines[0] = -1; |
175 | match_pos = 0; |
176 | num_matches = 0; |
177 | match_found = 0; |
178 | - |
179 | /* Run the regex on each line of the current file here */ |
180 | for (i = 0; i <= num_flines; i++) { |
181 | - strcpy(current_line, process_regex_on_line(flines[i], &pattern)); |
182 | + current_line = process_regex_on_line(flines[i], &pattern, 1); |
183 | flines[i] = bb_xstrdup(current_line); |
184 | if (match_found) { |
185 | + match_lines = xrealloc(match_lines, (j + 1) * sizeof(int)); |
186 | match_lines[j] = i; |
187 | j++; |
188 | } |
189 | } |
190 | - |
191 | + |
192 | num_matches = j; |
193 | if ((match_lines[0] != -1) && (num_flines > height - 2)) { |
194 | if (match_backwards) { |
195 | @@ -764,7 +766,7 @@ |
196 | buffer_line(num - 1); |
197 | break; |
198 | case 'p': case '%': |
199 | - buffer_line(reverse_percent(num)); |
200 | + buffer_line(((num / 100) * num_flines) - 1); |
201 | break; |
202 | #ifdef CONFIG_FEATURE_LESS_REGEXP |
203 | case 'n': |
204 | @@ -852,7 +854,6 @@ |
205 | data_readlines(); |
206 | buffer_init(); |
207 | buffer_line(temp_line_pos); |
208 | - buffer_print(); |
209 | } |
210 | |
211 | |
212 | @@ -866,7 +867,7 @@ |
213 | printf("Log file: "); |
214 | fgets(current_line, 256, inp); |
215 | current_line[strlen(current_line) - 1] = '\0'; |
216 | - if (strlen(current_line)) { |
217 | + if (strlen(current_line) > 1) { |
218 | fp = bb_xfopen(current_line, "w"); |
219 | for (i = 0; i < num_flines; i++) |
220 | fprintf(fp, "%s", flines[i]); |
221 | @@ -973,7 +974,6 @@ |
222 | printf("%s%s%s", HIGHLIGHT, "No matching bracket found", NORMAL); |
223 | |
224 | buffer_line(bracket_line - height + 2); |
225 | - buffer_print(); |
226 | } |
227 | } |
228 | |
229 | @@ -1001,7 +1001,6 @@ |
230 | printf("%s%s%s", HIGHLIGHT, "No matching bracket found", NORMAL); |
231 | |
232 | buffer_line(bracket_line); |
233 | - buffer_print(); |
234 | } |
235 | } |
236 | |
237 | @@ -1035,12 +1034,10 @@ |
238 | buffer_print(); |
239 | break; |
240 | case 'g': case 'p': case '<': case '%': |
241 | - buffer_up(num_flines + 1); |
242 | - buffer_print(); |
243 | + buffer_line(0); |
244 | break; |
245 | case 'G': case '>': |
246 | - buffer_down(num_flines + 1); |
247 | - buffer_print(); |
248 | + buffer_line(num_flines - height + 2); |
249 | break; |
250 | case 'q': case 'Q': |
251 | tless_exit(0); |
252 | @@ -1078,20 +1075,16 @@ |
253 | case '/': |
254 | match_backwards = 0; |
255 | regex_process(); |
256 | - buffer_print(); |
257 | break; |
258 | case 'n': |
259 | goto_match(match_pos + 1); |
260 | - buffer_print(); |
261 | break; |
262 | case 'N': |
263 | goto_match(match_pos - 1); |
264 | - buffer_print(); |
265 | break; |
266 | case '?': |
267 | match_backwards = 1; |
268 | regex_process(); |
269 | - buffer_print(); |
270 | break; |
271 | #endif |
272 | #ifdef CONFIG_FEATURE_LESS_FLAGCS |