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.
Showing
8 changed files
with
136 additions
and
22 deletions
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 | ||
114 | 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"); | ||
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 | { |
41 | pt->mu_line = 0; | 42 | int rc = mu_locus_point_set_file (pt, filename); |
42 | pt->mu_col = 0; | 43 | if (rc == 0) |
43 | return mu_locus_point_set_file (pt, filename); | 44 | { |
45 | pt->mu_line = 0; | ||
46 | pt->mu_col = 0; | ||
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 | { |
57 | dest->mu_col = src->mu_col; | 62 | int rc = mu_locus_point_set_file (dest, src->mu_file); |
58 | dest->mu_line = src->mu_line; | 63 | if (rc == 0) |
59 | return mu_locus_point_set_file (dest, src->mu_file); | 64 | { |
65 | dest->mu_col = src->mu_col; | ||
66 | dest->mu_line = src->mu_line; | ||
67 | } | ||
68 | return rc; | ||
60 | } | 69 | } |
61 | 70 | ||
62 | int | 71 | int |
... | @@ -65,7 +74,10 @@ mu_locus_range_copy (struct mu_locus_range *dest, | ... | @@ -65,7 +74,10 @@ mu_locus_range_copy (struct mu_locus_range *dest, |
65 | { | 74 | { |
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,7 +85,10 @@ mu_locus_range_copy (struct mu_locus_range *dest, | ... | @@ -73,7 +85,10 @@ 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 |
76 | *dest = tmp; | 88 | { |
89 | mu_locus_range_deinit (dest); | ||
90 | *dest = tmp; | ||
91 | } | ||
77 | } | 92 | } |
78 | return rc; | 93 | return rc; |
79 | } | 94 | } | ... | ... |
... | @@ -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; | ... | ... |
... | @@ -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,17 +690,37 @@ main (int argc, char **argv) | ... | @@ -689,17 +690,37 @@ 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 | { |
700 | mu_stream_printf (log, "%02d. %s\n", i, tp->id); | 718 | if (tp->enabled == ena) |
701 | tp->handler (log); | 719 | { |
702 | log_reset (log); | 720 | mu_stream_printf (log, "%02d. %s\n", i, tp->id); |
721 | tp->handler (log); | ||
722 | log_reset (log); | ||
723 | } | ||
703 | } | 724 | } |
704 | 725 | ||
705 | return 0; | 726 | return 0; | ... | ... |
-
Please register or sign in to post a comment