Commit 8ee676ca 8ee676ca15768d386ec3596235968e40abee2ae1 by Sergey Poznyakoff

Start switching lexers to the new line tracker facility

* include/mailutils/locus.h (MU_LOCUS_POINT_INITIALIZER): New define
(MU_LOCUS_RANGE_INITIALIZER): New define
(mu_locus_point_set_file, mu_locus_point_init)
(mu_locus_point_deinit, mu_locus_point_copy)
(mu_locus_range_deinit): New protos
* libmailutils/locus/locus.c: New file.
* libmailutils/locus/Makefile.am: Add new file.
* libmailutils/locus/linetrack.c (mu_linetrack_at_bol): New function.
(mu_linetrack_locus): New function.
(mu_linetrack_advance): Use mu_locus_point_set_file to set the mu_file
field.
* libmailutils/tests/linetrack.c: Initialize and deinitialize locus
range.
* mimeview/mimetypes.l: switch to line tracker
* mimeview/mimeview.h: Use defines from yyloc.h
1 parent 1ba98c36
...@@ -11,12 +11,17 @@ struct mu_locus_point ...@@ -11,12 +11,17 @@ struct mu_locus_point
11 unsigned mu_col; 11 unsigned mu_col;
12 }; 12 };
13 13
14 #define MU_LOCUS_POINT_INITIALIZER { NULL, 0, 0 }
15
14 struct mu_locus_range 16 struct mu_locus_range
15 { 17 {
16 struct mu_locus_point beg; 18 struct mu_locus_point beg;
17 struct mu_locus_point end; 19 struct mu_locus_point end;
18 }; 20 };
19 21
22 #define MU_LOCUS_RANGE_INITIALIZER \
23 { MU_LOCUS_POINT_INITIALIZER, MU_LOCUS_POINT_INITIALIZER }
24
20 typedef struct mu_linetrack *mu_linetrack_t; 25 typedef struct mu_linetrack *mu_linetrack_t;
21 26
22 struct mu_linetrack_stat 27 struct mu_linetrack_stat
...@@ -30,6 +35,14 @@ struct mu_linetrack_stat ...@@ -30,6 +35,14 @@ struct mu_linetrack_stat
30 int mu_ident_ref (char const *name, char const **refname); 35 int mu_ident_ref (char const *name, char const **refname);
31 int mu_ident_deref (char const *); 36 int mu_ident_deref (char const *);
32 37
38 int mu_locus_point_set_file (struct mu_locus_point *pt, const char *filename);
39 int mu_locus_point_init (struct mu_locus_point *pt, const char *filename);
40 void mu_locus_point_deinit (struct mu_locus_point *pt);
41 int mu_locus_point_copy (struct mu_locus_point *dest,
42 struct mu_locus_point const *src);
43
44 void mu_locus_range_deinit (struct mu_locus_range *lr);
45
33 static inline int 46 static inline int
34 mu_locus_point_same_file (struct mu_locus_point const *a, 47 mu_locus_point_same_file (struct mu_locus_point const *a,
35 struct mu_locus_point const *b) 48 struct mu_locus_point const *b)
...@@ -56,7 +69,10 @@ void mu_linetrack_advance (mu_linetrack_t trk, ...@@ -56,7 +69,10 @@ void mu_linetrack_advance (mu_linetrack_t trk,
56 struct mu_locus_range *loc, 69 struct mu_locus_range *loc,
57 char const *text, size_t leng); 70 char const *text, size_t leng);
58 int mu_linetrack_retreat (mu_linetrack_t trk, size_t n); 71 int mu_linetrack_retreat (mu_linetrack_t trk, size_t n);
72
73 int mu_linetrack_locus (struct mu_linetrack *trk, struct mu_locus_point *lp);
59 int mu_linetrack_stat (mu_linetrack_t trk, struct mu_linetrack_stat *st); 74 int mu_linetrack_stat (mu_linetrack_t trk, struct mu_linetrack_stat *st);
75 int mu_linetrack_at_bol (struct mu_linetrack *trk);
60 76
61 77
62 void mu_stream_print_locus_range (mu_stream_t stream, 78 void mu_stream_print_locus_range (mu_stream_t stream,
......
...@@ -20,7 +20,8 @@ noinst_LTLIBRARIES = liblocus.la ...@@ -20,7 +20,8 @@ noinst_LTLIBRARIES = liblocus.la
20 liblocus_la_SOURCES = \ 20 liblocus_la_SOURCES = \
21 ident.c\ 21 ident.c\
22 debug.c\ 22 debug.c\
23 linetrack.c 23 linetrack.c\
24 locus.c
24 25
25 AM_CPPFLAGS = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils 26 AM_CPPFLAGS = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
26 27
......
...@@ -146,6 +146,12 @@ mu_linetrack_stat (struct mu_linetrack *trk, struct mu_linetrack_stat *st) ...@@ -146,6 +146,12 @@ mu_linetrack_stat (struct mu_linetrack *trk, struct mu_linetrack_stat *st)
146 return 0; 146 return 0;
147 } 147 }
148 148
149 int
150 mu_linetrack_at_bol (struct mu_linetrack *trk)
151 {
152 return *cols_tos_ptr (trk) == 0;
153 }
154
149 void 155 void
150 mu_linetrack_advance (struct mu_linetrack *trk, 156 mu_linetrack_advance (struct mu_linetrack *trk,
151 struct mu_locus_range *loc, 157 struct mu_locus_range *loc,
...@@ -156,7 +162,8 @@ mu_linetrack_advance (struct mu_linetrack *trk, ...@@ -156,7 +162,8 @@ mu_linetrack_advance (struct mu_linetrack *trk,
156 if (text == NULL || leng == 0) 162 if (text == NULL || leng == 0)
157 return; 163 return;
158 164
159 loc->beg.mu_file = loc->end.mu_file = trk->file_name; 165 mu_locus_point_set_file (&loc->beg, trk->file_name);
166 mu_locus_point_set_file (&loc->end, trk->file_name);
160 loc->beg.mu_line = trk->hline + trk->tos; 167 loc->beg.mu_line = trk->hline + trk->tos;
161 ptr = cols_tos_ptr (trk); 168 ptr = cols_tos_ptr (trk);
162 loc->beg.mu_col = *ptr + 1; 169 loc->beg.mu_col = *ptr + 1;
...@@ -174,7 +181,7 @@ mu_linetrack_advance (struct mu_linetrack *trk, ...@@ -174,7 +181,7 @@ mu_linetrack_advance (struct mu_linetrack *trk,
174 } 181 }
175 else 182 else
176 { 183 {
177 /* Text ends with a newline. Keep the previos line number. */ 184 /* Text ends with a newline. Keep the previous line number. */
178 loc->end.mu_line = trk->hline + trk->tos - 1; 185 loc->end.mu_line = trk->hline + trk->tos - 1;
179 loc->end.mu_col = cols_peek (trk, trk->tos - 1) - 1; 186 loc->end.mu_col = cols_peek (trk, trk->tos - 1) - 1;
180 if (loc->end.mu_col + 1 == loc->beg.mu_col) 187 if (loc->end.mu_col + 1 == loc->beg.mu_col)
...@@ -186,6 +193,13 @@ mu_linetrack_advance (struct mu_linetrack *trk, ...@@ -186,6 +193,13 @@ mu_linetrack_advance (struct mu_linetrack *trk,
186 } 193 }
187 194
188 int 195 int
196 mu_linetrack_locus (struct mu_linetrack *trk, struct mu_locus_point *lp)
197 {
198 lp->mu_line = trk->hline + trk->tos;
199 return mu_locus_point_init (lp, trk->file_name);
200 }
201
202 int
189 mu_linetrack_retreat (struct mu_linetrack *trk, size_t n) 203 mu_linetrack_retreat (struct mu_linetrack *trk, size_t n)
190 { 204 {
191 struct mu_linetrack_stat st; 205 struct mu_linetrack_stat st;
......
1 #include <stdlib.h>
2 #include <errno.h>
3 #include <mailutils/types.h>
4 #include <mailutils/locus.h>
5 #include <mailutils/error.h>
6
7 int
8 mu_locus_point_set_file (struct mu_locus_point *pt, const char *filename)
9 {
10 int rc;
11 char const *ref;
12
13 rc = mu_ident_ref (filename, &ref);
14 if (rc)
15 return rc;
16 mu_ident_deref (pt->mu_file);
17 pt->mu_file = ref;
18 return 0;
19 }
20
21 int
22 mu_locus_point_init (struct mu_locus_point *pt, const char *filename)
23 {
24 pt->mu_line = 0;
25 pt->mu_col = 0;
26 return mu_locus_point_set_file (pt, filename);
27 }
28
29 void
30 mu_locus_point_deinit (struct mu_locus_point *pt)
31 {
32 mu_ident_deref (pt->mu_file);
33 memset (pt, 0, sizeof *pt);
34 }
35
36 int
37 mu_locus_point_copy (struct mu_locus_point *dest,
38 struct mu_locus_point const *src)
39 {
40 dest->mu_col = src->mu_col;
41 dest->mu_line = src->mu_line;
42 return mu_locus_point_init (dest, src->mu_file);
43 }
44
45 void
46 mu_locus_range_deinit (struct mu_locus_range *lr)
47 {
48 mu_locus_point_deinit (&lr->beg);
49 mu_locus_point_deinit (&lr->end);
50 }
...@@ -29,7 +29,7 @@ main (int argc, char **argv) ...@@ -29,7 +29,7 @@ main (int argc, char **argv)
29 MU_ASSERT (mu_linetrack_create (&trk, argv[1], max_lines)); 29 MU_ASSERT (mu_linetrack_create (&trk, argv[1], max_lines));
30 while ((rc = mu_stream_getline (mu_strin, &buf, &size, &n)) == 0 && n > 0) 30 while ((rc = mu_stream_getline (mu_strin, &buf, &size, &n)) == 0 && n > 0)
31 { 31 {
32 struct mu_locus_range lr; 32 struct mu_locus_range lr = MU_LOCUS_RANGE_INITIALIZER;
33 char *tok; 33 char *tok;
34 34
35 n = mu_rtrim_class (buf, MU_CTYPE_SPACE); 35 n = mu_rtrim_class (buf, MU_CTYPE_SPACE);
...@@ -57,6 +57,7 @@ main (int argc, char **argv) ...@@ -57,6 +57,7 @@ main (int argc, char **argv)
57 free (tok); 57 free (tok);
58 mu_stream_lprintf (mu_strout, &lr, "%s\n", buf); 58 mu_stream_lprintf (mu_strout, &lr, "%s\n", buf);
59 } 59 }
60 mu_locus_range_deinit (&lr);
60 } 61 }
61 return 0; 62 return 0;
62 } 63 }
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
29 #include <mimetypes-decl.h> 29 #include <mimetypes-decl.h>
30 #include <mailutils/io.h> 30 #include <mailutils/io.h>
31 31
32 static struct mu_locus loc; 32 static mu_linetrack_t trk;
33 static int newline; 33 struct mu_locus_point string_beg;
34 34
35 static mu_opool_t pool; 35 static mu_opool_t pool;
36 36
...@@ -42,53 +42,18 @@ digit_to_number (char c) ...@@ -42,53 +42,18 @@ digit_to_number (char c)
42 c-'a'+10); 42 c-'a'+10);
43 } 43 }
44 44
45 static struct mu_locus prev_loc;
46 static struct mu_locus string_beg;
47 static int prev_newline;
48
49 static void
50 advance_locus (void)
51 {
52 prev_loc = loc;
53 prev_newline = newline;
54
55 if (newline)
56 {
57 loc.mu_line++;
58 loc.mu_col = 1;
59 }
60 yylloc.beg = loc;
61 loc.mu_col += yyleng;
62 yylloc.end = loc;
63 yylloc.end.mu_col--;
64
65 #if 0
66 printf ("+%2d> %u:%u-%u:%u: %s\n",
67 yyleng,
68 yylloc.beg.mu_line, yylloc.beg.mu_col,
69 yylloc.end.mu_line, yylloc.end.mu_col, yytext);
70 #endif
71 newline = yytext[yyleng-1] == '\n';
72 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
73 MU_IOCTL_LOGSTREAM_SET_LOCUS, &loc);
74 }
75
76 static void
77 retreat_locus (void)
78 {
79 loc = prev_loc;
80 newline = prev_newline;
81 }
82
83 static void 45 static void
84 finish_string (void) 46 finish_string (void)
85 { 47 {
86 mu_opool_append_char (pool, 0); 48 mu_opool_append_char (pool, 0);
87 yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len); 49 yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len);
88 yylval.string.len--; 50 yylval.string.len--;
89 yylloc.end = yylloc.beg; 51
52 mu_locus_point_copy (&yylloc.end, &yylloc.beg);
90 yylloc.end.mu_col--; 53 yylloc.end.mu_col--;
91 yylloc.beg = string_beg; 54 mu_locus_point_copy (&yylloc.beg, &string_beg);
55 mu_locus_point_deinit (&string_beg);
56
92 if (mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE5)) 57 if (mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE5))
93 { 58 {
94 size_t i; 59 size_t i;
...@@ -106,7 +71,15 @@ finish_string (void) ...@@ -106,7 +71,15 @@ finish_string (void)
106 #endif 71 #endif
107 } 72 }
108 73
109 #define YY_USER_ACTION advance_locus (); 74 #define YY_USER_ACTION \
75 do \
76 { \
77 mu_linetrack_advance (trk, &yylloc, yytext, yyleng); \
78 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, \
79 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &yylloc); \
80 } \
81 while (0);
82
110 %} 83 %}
111 84
112 %x RULE ARGS ASTRING 85 %x RULE ARGS ASTRING
...@@ -178,8 +151,8 @@ WS [ \t][ \t]* ...@@ -178,8 +151,8 @@ WS [ \t][ \t]*
178 return EOL; 151 return EOL;
179 } 152 }
180 . { 153 . {
181 string_beg = yylloc.beg; 154 mu_locus_point_copy (&string_beg, &yylloc.beg);
182 retreat_locus (); 155 mu_linetrack_retreat (trk, 1);
183 yyless (0); 156 yyless (0);
184 BEGIN (ASTRING); 157 BEGIN (ASTRING);
185 } 158 }
...@@ -218,7 +191,7 @@ WS [ \t][ \t]* ...@@ -218,7 +191,7 @@ WS [ \t][ \t]*
218 } 191 }
219 192
220 . { 193 . {
221 retreat_locus (); 194 mu_linetrack_retreat (trk, 1);
222 yyless (0); 195 yyless (0);
223 BEGIN (ARGS); 196 BEGIN (ARGS);
224 finish_string (); 197 finish_string ();
...@@ -232,6 +205,7 @@ mimetypes_open (const char *name) ...@@ -232,6 +205,7 @@ mimetypes_open (const char *name)
232 { 205 {
233 struct stat st; 206 struct stat st;
234 int mode; 207 int mode;
208 char *filename;
235 209
236 yy_flex_debug = mu_debug_level_p (MU_DEBCAT_MIME, MU_DEBUG_TRACE4); 210 yy_flex_debug = mu_debug_level_p (MU_DEBCAT_MIME, MU_DEBUG_TRACE4);
237 211
...@@ -242,28 +216,26 @@ mimetypes_open (const char *name) ...@@ -242,28 +216,26 @@ mimetypes_open (const char *name)
242 } 216 }
243 217
244 if (S_ISDIR (st.st_mode)) 218 if (S_ISDIR (st.st_mode))
245 loc.mu_file = mu_make_file_name (name, "mime.types"); 219 filename = mu_make_file_name (name, "mime.types");
246 else 220 else
247 loc.mu_file = mu_strdup (name); 221 filename = mu_strdup (name);
248 loc.mu_line = 1;
249 loc.mu_col = 1;
250 newline = 0;
251 222
252 yyin = fopen (loc.mu_file, "r"); 223 yyin = fopen (filename, "r");
253 if (!yyin) 224 if (!yyin)
254 { 225 {
255 mu_error (_("cannot open `%s': %s"), loc.mu_file, mu_strerror (errno)); 226 mu_error (_("cannot open `%s': %s"), filename, mu_strerror (errno));
256 free (loc.mu_file); 227 free (filename);
257 return -1; 228 return -1;
258 } 229 }
259 230
231 MU_ASSERT (mu_linetrack_create (&trk, filename, 3));
232 free (filename);
233
260 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 234 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
261 MU_IOCTL_LOGSTREAM_GET_MODE, &mode); 235 MU_IOCTL_LOGSTREAM_GET_MODE, &mode);
262 mode |= MU_LOGMODE_LOCUS; 236 mode |= MU_LOGMODE_LOCUS;
263 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 237 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
264 MU_IOCTL_LOGSTREAM_SET_MODE, &mode); 238 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
265 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
266 MU_IOCTL_LOGSTREAM_SET_LOCUS, &loc);
267 239
268 mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT); 240 mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
269 return 0; 241 return 0;
...@@ -275,16 +247,14 @@ mimetypes_close () ...@@ -275,16 +247,14 @@ mimetypes_close ()
275 int mode; 247 int mode;
276 248
277 fclose (yyin); 249 fclose (yyin);
278 /* FIXME: Don't free (loc.mu_file), because it is referenced by 250 mu_linetrack_destroy (&trk);
279 mu_locus structures in the parse tree */
280
281 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 251 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
282 MU_IOCTL_LOGSTREAM_GET_MODE, &mode); 252 MU_IOCTL_LOGSTREAM_GET_MODE, &mode);
283 mode &= ~MU_LOGMODE_LOCUS; 253 mode &= ~MU_LOGMODE_LOCUS;
284 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 254 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
285 MU_IOCTL_LOGSTREAM_SET_MODE, &mode); 255 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
286 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 256 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
287 MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL); 257 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, NULL);
288 } 258 }
289 259
290 int 260 int
...@@ -319,17 +289,8 @@ mimetypes_malloc (size_t size) ...@@ -319,17 +289,8 @@ mimetypes_malloc (size_t size)
319 void 289 void
320 lex_next_rule (void) 290 lex_next_rule (void)
321 { 291 {
322 int bol = 0;
323 int c; 292 int c;
324 293
325 if (newline)
326 {
327 loc.mu_col = 0;
328 loc.mu_line++;
329 newline = 0;
330 bol = 1;
331 }
332
333 if (yy_flex_debug) 294 if (yy_flex_debug)
334 { 295 {
335 YY_LOCATION_PRINT (stderr, yylloc); 296 YY_LOCATION_PRINT (stderr, yylloc);
...@@ -337,31 +298,27 @@ lex_next_rule (void) ...@@ -337,31 +298,27 @@ lex_next_rule (void)
337 } 298 }
338 while ((c = input ()) != EOF) 299 while ((c = input ()) != EOF)
339 { 300 {
340 loc.mu_col++; 301 char ch = c;
302 mu_linetrack_advance (trk, &yylloc, &ch, 1);
341 if (c == '\n') 303 if (c == '\n')
342 { 304 {
343 loc.mu_line++; 305 continue;
344 loc.mu_col = 0;
345 bol = 1;
346 } 306 }
347 else if (bol) 307 else if (mu_linetrack_at_bol (trk) && !(c == ' ' || c == '\t'))
348 {
349 bol = 0;
350 if (!(c == ' ' || c == '\t'))
351 { 308 {
309 mu_linetrack_retreat (trk, 1);
352 unput (c); 310 unput (c);
353 break; 311 break;
354 } 312 }
355 } 313 }
356 }
357 if (yy_flex_debug) 314 if (yy_flex_debug)
358 { 315 {
359 yylloc.beg = yylloc.end = loc; 316 struct mu_locus_range lr = MU_LOCUS_RANGE_INITIALIZER;
360 YY_LOCATION_PRINT (stderr, yylloc); 317 mu_linetrack_locus (trk, &lr.beg);
318 YY_LOCATION_PRINT (stderr, lr);
361 fprintf (stderr, ": finished error recovery\n"); 319 fprintf (stderr, ": finished error recovery\n");
320 mu_locus_point_deinit (&lr.beg);
362 } 321 }
363 BEGIN (RULE); 322 BEGIN (RULE);
364 unput ('\n'); 323 unput ('\n');
365 loc.mu_col = 0; 324 }
366 loc.mu_line--;
367 }
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
22 # include <strings.h> 22 # include <strings.h>
23 #endif 23 #endif
24 #include <mailutils/mailutils.h> 24 #include <mailutils/mailutils.h>
25 #include <mailutils/locus.h>
26 #include <mailutils/yyloc.h>
25 #include <fnmatch.h> 27 #include <fnmatch.h>
26 28
27 struct mimetypes_string 29 struct mimetypes_string
...@@ -48,29 +50,3 @@ const char *get_file_type (void); ...@@ -48,29 +50,3 @@ const char *get_file_type (void);
48 extern char const *mimeview_file; 50 extern char const *mimeview_file;
49 extern mu_stream_t mimeview_stream; 51 extern mu_stream_t mimeview_stream;
50 52
51 struct mu_locus_range
52 {
53 struct mu_locus beg;
54 struct mu_locus end;
55 };
56
57 #define YYLTYPE struct mu_locus_range
58 #define YYLLOC_DEFAULT(Current, Rhs, N) \
59 do \
60 { \
61 if (N) \
62 { \
63 (Current).beg = YYRHSLOC(Rhs, 1).beg; \
64 (Current).end = YYRHSLOC(Rhs, N).end; \
65 } \
66 else \
67 { \
68 (Current).beg = YYRHSLOC(Rhs, 0).end; \
69 (Current).end = (Current).beg; \
70 } \
71 } while (0)
72 #define YY_LOCATION_PRINT(File, Loc) \
73 fprintf(File, "%s:%u.%u-%u.%u", \
74 (Loc).beg.mu_file, \
75 (Loc).beg.mu_line, (Loc).beg.mu_col, \
76 (Loc).end.mu_line, (Loc).end.mu_col)
......