Commit 75b1c55e 75b1c55e4db1c0b90e898b1375f1489e72719127 by Sergey Poznyakoff

Fix id reference counting

* include/mailutils/locus.h: Add copyleft.
(mu_ident_stat): New proto.
* include/mailutils/types.hin (mu_locus_DEPRECATED): Update commit.
Include link to the wiki article.
* include/mailutils/yyloc.h: Add copyleft.
* libmailutils/locus/ident.c (mu_ident_stat): New function.
* libmailutils/locus/locus.c (mu_locus_point_init)
(mu_locus_point_copy): Don't touch destination unless setting
mu_file member succeeds.
(mu_locus_range_copy): deinitialize dest before assignment.
* libmailutils/stream/logstream.c (_log_write): Use mu_locus_range_copy
to save locus.
(mu_ioctl_logstream_get_locus_deprecated)
(mu_ioctl_logstream_set_locus_deprecated): Include link to the
wiki article.
* libmailutils/tests/linetrack.c (main): Destroy tracker before exiting.
* libmailutils/tests/logstr.c: Make it possible to run selected tests.
1 parent 74e285e7
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2017 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
1 #ifndef _MAILUTILS_LOCUS_H 18 #ifndef _MAILUTILS_LOCUS_H
2 #define _MAILUTILS_LOCUS_H 19 #define _MAILUTILS_LOCUS_H
3 20
...@@ -34,6 +51,7 @@ struct mu_linetrack_stat ...@@ -34,6 +51,7 @@ struct mu_linetrack_stat
34 51
35 int mu_ident_ref (char const *name, char const **refname); 52 int mu_ident_ref (char const *name, char const **refname);
36 int mu_ident_deref (char const *); 53 int mu_ident_deref (char const *);
54 void mu_ident_stat (mu_stream_t str);
37 55
38 int mu_locus_point_set_file (struct mu_locus_point *pt, const char *filename); 56 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); 57 int mu_locus_point_init (struct mu_locus_point *pt, const char *filename);
...@@ -60,9 +78,6 @@ mu_locus_point_same_line (struct mu_locus_point const *a, ...@@ -60,9 +78,6 @@ mu_locus_point_same_line (struct mu_locus_point const *a,
60 return mu_locus_point_same_file (a, b) && a->mu_line == b->mu_line; 78 return mu_locus_point_same_file (a, b) && a->mu_line == b->mu_line;
61 } 79 }
62 80
63 void mu_lrange_debug (struct mu_locus_range const *loc,
64 char const *fmt, ...);
65
66 int mu_linetrack_create (mu_linetrack_t *ret, 81 int mu_linetrack_create (mu_linetrack_t *ret,
67 char const *file_name, size_t max_lines); 82 char const *file_name, size_t max_lines);
68 int mu_linetrack_rebase (mu_linetrack_t trk, struct mu_locus_point const *pt); 83 int mu_linetrack_rebase (mu_linetrack_t trk, struct mu_locus_point const *pt);
......
...@@ -155,7 +155,11 @@ typedef unsigned int mu_debug_level_t; ...@@ -155,7 +155,11 @@ typedef unsigned int mu_debug_level_t;
155 <mailutils/locus.h>. 155 <mailutils/locus.h>.
156 156
157 This definition is provided for backward compatibility. Authors are 157 This definition is provided for backward compatibility. Authors are
158 urged to switch to the new API as soon as their time permits. */ 158 urged to switch to the new API as soon as their time permits.
159
160 Please see http://mailutils.org/wiki/Source_location_API#Deprecated_interface
161 for detailed guidelines.
162 */
159 struct mu_locus_DEPRECATED 163 struct mu_locus_DEPRECATED
160 { 164 {
161 char *mu_file; 165 char *mu_file;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2017 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifndef _MAILUTILS_YYLOC_H
19 #define _MAILUTILS_YYLOC_H
20
1 void mu_file_print_locus_point (FILE *, 21 void mu_file_print_locus_point (FILE *,
2 struct mu_locus_point const *lpt); 22 struct mu_locus_point const *lpt);
3 void mu_file_print_locus_range (FILE *, 23 void mu_file_print_locus_range (FILE *,
...@@ -18,8 +38,9 @@ void mu_file_print_locus_range (FILE *, ...@@ -18,8 +38,9 @@ void mu_file_print_locus_range (FILE *,
18 (Current).end = (Current).beg; \ 38 (Current).end = (Current).beg; \
19 } \ 39 } \
20 } while (0) 40 } while (0)
41
21 #define YY_LOCATION_PRINT(File, Loc) \ 42 #define YY_LOCATION_PRINT(File, Loc) \
22 mu_file_print_locus_range (File, &(Loc)) 43 mu_file_print_locus_range (File, &(Loc))
23 44
24 45 #endif
25 46
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
23 #include <mailutils/errno.h> 23 #include <mailutils/errno.h>
24 #include <mailutils/diag.h> 24 #include <mailutils/diag.h>
25 #include <mailutils/list.h> 25 #include <mailutils/list.h>
26 #include <mailutils/io.h>
27 #include <mailutils/stream.h>
28 #include <mailutils/iterator.h>
26 29
27 struct mu_ident_ref 30 struct mu_ident_ref
28 { 31 {
...@@ -111,5 +114,39 @@ mu_ident_deref (char const *name) ...@@ -111,5 +114,39 @@ mu_ident_deref (char const *name)
111 return 0; 114 return 0;
112 } 115 }
113 116
117 void
118 mu_ident_stat (mu_stream_t str)
119 {
120 size_t count, i;
121 mu_iterator_t itr;
122
123 mu_stream_printf (str, "BEGIN IDENT STAT\n");
114 124
125 mu_assoc_count (nametab, &count);
126 mu_stream_printf (str, "N=%zu\n", count);
127
128 if (count > 0)
129 {
130 int rc = mu_assoc_get_iterator (nametab, &itr);
131 if (rc)
132 mu_stream_printf (str, "mu_assoc_get_iterator: %s\n",
133 mu_strerror (rc));
134 else
135 {
136 i = 0;
137 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
138 mu_iterator_next (itr), i)
139 {
140 const char *key;
141 struct mu_ident_ref *ref;
142
143 mu_iterator_current_kv (itr,
144 (const void **)&key, (void **)&ref);
145 mu_stream_printf (str, "%04zu: %s: %zu\n", i, key, ref->count);
146 }
147 }
148 mu_iterator_destroy (&itr);
149 }
150 mu_stream_printf (str, "END IDENT STAT\n");
151 }
115 152
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 #include <mailutils/types.h> 20 #include <mailutils/types.h>
21 #include <mailutils/locus.h> 21 #include <mailutils/locus.h>
22 #include <mailutils/error.h> 22 #include <mailutils/error.h>
23 #include <mailutils/errno.h>
23 24
24 int 25 int
25 mu_locus_point_set_file (struct mu_locus_point *pt, const char *filename) 26 mu_locus_point_set_file (struct mu_locus_point *pt, const char *filename)
...@@ -38,9 +39,13 @@ mu_locus_point_set_file (struct mu_locus_point *pt, const char *filename) ...@@ -38,9 +39,13 @@ mu_locus_point_set_file (struct mu_locus_point *pt, const char *filename)
38 int 39 int
39 mu_locus_point_init (struct mu_locus_point *pt, const char *filename) 40 mu_locus_point_init (struct mu_locus_point *pt, const char *filename)
40 { 41 {
42 int rc = mu_locus_point_set_file (pt, filename);
43 if (rc == 0)
44 {
41 pt->mu_line = 0; 45 pt->mu_line = 0;
42 pt->mu_col = 0; 46 pt->mu_col = 0;
43 return mu_locus_point_set_file (pt, filename); 47 }
48 return rc;
44 } 49 }
45 50
46 void 51 void
...@@ -54,9 +59,13 @@ int ...@@ -54,9 +59,13 @@ int
54 mu_locus_point_copy (struct mu_locus_point *dest, 59 mu_locus_point_copy (struct mu_locus_point *dest,
55 struct mu_locus_point const *src) 60 struct mu_locus_point const *src)
56 { 61 {
62 int rc = mu_locus_point_set_file (dest, src->mu_file);
63 if (rc == 0)
64 {
57 dest->mu_col = src->mu_col; 65 dest->mu_col = src->mu_col;
58 dest->mu_line = src->mu_line; 66 dest->mu_line = src->mu_line;
59 return mu_locus_point_set_file (dest, src->mu_file); 67 }
68 return rc;
60 } 69 }
61 70
62 int 71 int
...@@ -66,6 +75,9 @@ mu_locus_range_copy (struct mu_locus_range *dest, ...@@ -66,6 +75,9 @@ mu_locus_range_copy (struct mu_locus_range *dest,
66 int rc; 75 int rc;
67 struct mu_locus_range tmp = MU_LOCUS_RANGE_INITIALIZER; 76 struct mu_locus_range tmp = MU_LOCUS_RANGE_INITIALIZER;
68 77
78 if (!dest)
79 return MU_ERR_OUT_PTR_NULL;
80
69 rc = mu_locus_point_copy (&tmp.beg, &src->beg); 81 rc = mu_locus_point_copy (&tmp.beg, &src->beg);
70 if (rc == 0) 82 if (rc == 0)
71 { 83 {
...@@ -73,8 +85,11 @@ mu_locus_range_copy (struct mu_locus_range *dest, ...@@ -73,8 +85,11 @@ mu_locus_range_copy (struct mu_locus_range *dest,
73 if (rc) 85 if (rc)
74 mu_locus_point_deinit (&tmp.beg); 86 mu_locus_point_deinit (&tmp.beg);
75 else 87 else
88 {
89 mu_locus_range_deinit (dest);
76 *dest = tmp; 90 *dest = tmp;
77 } 91 }
92 }
78 return rc; 93 return rc;
79 } 94 }
80 95
......
...@@ -258,11 +258,7 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, ...@@ -258,11 +258,7 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
258 severity = MU_LOG_EMERG; 258 severity = MU_LOG_EMERG;
259 259
260 if (save_locus) 260 if (save_locus)
261 { 261 mu_locus_range_copy (&sp->locrange, &loc);
262 sp->locrange = loc;
263 mu_ident_ref (sp->locrange.beg.mu_file, &sp->locrange.beg.mu_file);
264 mu_ident_ref (sp->locrange.end.mu_file, &sp->locrange.end.mu_file);
265 }
266 262
267 if (severity < sp->threshold) 263 if (severity < sp->threshold)
268 rc = 0; 264 rc = 0;
...@@ -649,6 +645,8 @@ mu_log_stream_create (mu_stream_t *pstr, mu_stream_t transport) ...@@ -649,6 +645,8 @@ mu_log_stream_create (mu_stream_t *pstr, mu_stream_t transport)
649 return 0; 645 return 0;
650 } 646 }
651 647
648 static char wiki_url[] = "http://mailutils.org/wiki/Source_location_API#Deprecated_interface";
649
652 int 650 int
653 mu_ioctl_logstream_get_locus_deprecated (void) 651 mu_ioctl_logstream_get_locus_deprecated (void)
654 { 652 {
...@@ -656,6 +654,7 @@ mu_ioctl_logstream_get_locus_deprecated (void) ...@@ -656,6 +654,7 @@ mu_ioctl_logstream_get_locus_deprecated (void)
656 if (!warned) 654 if (!warned)
657 { 655 {
658 mu_error (_("the program uses MU_IOCTL_LOGSTREAM_GET_LOCUS, which is deprecated")); 656 mu_error (_("the program uses MU_IOCTL_LOGSTREAM_GET_LOCUS, which is deprecated"));
657 mu_error (_("please see %s, for detailed guidelines"), wiki_url);
659 warned = 1; 658 warned = 1;
660 } 659 }
661 return MU_IOCTL_LOGSTREAM_GET_LOCUS_DEPRECATED; 660 return MU_IOCTL_LOGSTREAM_GET_LOCUS_DEPRECATED;
...@@ -668,6 +667,7 @@ mu_ioctl_logstream_set_locus_deprecated (void) ...@@ -668,6 +667,7 @@ mu_ioctl_logstream_set_locus_deprecated (void)
668 if (!warned) 667 if (!warned)
669 { 668 {
670 mu_error (_("program uses MU_IOCTL_LOGSTREAM_SET_LOCUS, which is deprecated")); 669 mu_error (_("program uses MU_IOCTL_LOGSTREAM_SET_LOCUS, which is deprecated"));
670 mu_error (_("please see %s, for detailed guidelines"), wiki_url);
671 warned = 1; 671 warned = 1;
672 } 672 }
673 return MU_IOCTL_LOGSTREAM_SET_LOCUS_DEPRECATED; 673 return MU_IOCTL_LOGSTREAM_SET_LOCUS_DEPRECATED;
......
...@@ -59,6 +59,7 @@ main (int argc, char **argv) ...@@ -59,6 +59,7 @@ main (int argc, char **argv)
59 } 59 }
60 mu_locus_range_deinit (&lr); 60 mu_locus_range_deinit (&lr);
61 } 61 }
62 mu_linetrack_destroy (&trk);
62 return 0; 63 return 0;
63 } 64 }
64 65
......
...@@ -629,6 +629,7 @@ struct testcase ...@@ -629,6 +629,7 @@ struct testcase
629 { 629 {
630 char const *id; 630 char const *id;
631 void (*handler) (mu_stream_t); 631 void (*handler) (mu_stream_t);
632 int enabled;
632 }; 633 };
633 634
634 struct testcase testcases[] = { 635 struct testcase testcases[] = {
...@@ -689,18 +690,38 @@ main (int argc, char **argv) ...@@ -689,18 +690,38 @@ main (int argc, char **argv)
689 mu_stream_t log; 690 mu_stream_t log;
690 struct testcase *tp; 691 struct testcase *tp;
691 int i; 692 int i;
693 int ena = 0;
692 694
693 mu_set_program_name (argv[0]); 695 mu_set_program_name (argv[0]);
694 mu_stdstream_setup (MU_STDSTREAM_RESET_NONE); 696 mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
695 697
698 if (argc > 1)
699 {
700 ena = 1;
701 for (i = 1; i < argc; i++)
702 {
703 char *p;
704 int n = strtol (argv[i], &p, 10);
705 if (! (*p == 0 && n >= 0) )
706 {
707 mu_error ("erroneous argument %s\n", argv[i]);
708 return 1;
709 }
710 testcases[n].enabled = ena;
711 }
712 }
713
696 log = create_log (); 714 log = create_log ();
697 715
698 for (i = 0, tp = testcases; tp->id; tp++, i++) 716 for (i = 0, tp = testcases; tp->id; tp++, i++)
699 { 717 {
718 if (tp->enabled == ena)
719 {
700 mu_stream_printf (log, "%02d. %s\n", i, tp->id); 720 mu_stream_printf (log, "%02d. %s\n", i, tp->id);
701 tp->handler (log); 721 tp->handler (log);
702 log_reset (log); 722 log_reset (log);
703 } 723 }
724 }
704 725
705 return 0; 726 return 0;
706 } 727 }
......