]>
Commit | Line | Data |
---|---|---|
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 |