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
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2017 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MAILUTILS_LOCUS_H
#define _MAILUTILS_LOCUS_H
......@@ -34,6 +51,7 @@ struct mu_linetrack_stat
int mu_ident_ref (char const *name, char const **refname);
int mu_ident_deref (char const *);
void mu_ident_stat (mu_stream_t str);
int mu_locus_point_set_file (struct mu_locus_point *pt, const char *filename);
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,
return mu_locus_point_same_file (a, b) && a->mu_line == b->mu_line;
}
void mu_lrange_debug (struct mu_locus_range const *loc,
char const *fmt, ...);
int mu_linetrack_create (mu_linetrack_t *ret,
char const *file_name, size_t max_lines);
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;
<mailutils/locus.h>.
This definition is provided for backward compatibility. Authors are
urged to switch to the new API as soon as their time permits. */
urged to switch to the new API as soon as their time permits.
Please see http://mailutils.org/wiki/Source_location_API#Deprecated_interface
for detailed guidelines.
*/
struct mu_locus_DEPRECATED
{
char *mu_file;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2017 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MAILUTILS_YYLOC_H
#define _MAILUTILS_YYLOC_H
void mu_file_print_locus_point (FILE *,
struct mu_locus_point const *lpt);
void mu_file_print_locus_range (FILE *,
......@@ -18,8 +38,9 @@ void mu_file_print_locus_range (FILE *,
(Current).end = (Current).beg; \
} \
} while (0)
#define YY_LOCATION_PRINT(File, Loc) \
mu_file_print_locus_range (File, &(Loc))
#endif
......
......@@ -23,6 +23,9 @@
#include <mailutils/errno.h>
#include <mailutils/diag.h>
#include <mailutils/list.h>
#include <mailutils/io.h>
#include <mailutils/stream.h>
#include <mailutils/iterator.h>
struct mu_ident_ref
{
......@@ -111,5 +114,39 @@ mu_ident_deref (char const *name)
return 0;
}
void
mu_ident_stat (mu_stream_t str)
{
size_t count, i;
mu_iterator_t itr;
mu_stream_printf (str, "BEGIN IDENT STAT\n");
mu_assoc_count (nametab, &count);
mu_stream_printf (str, "N=%zu\n", count);
if (count > 0)
{
int rc = mu_assoc_get_iterator (nametab, &itr);
if (rc)
mu_stream_printf (str, "mu_assoc_get_iterator: %s\n",
mu_strerror (rc));
else
{
i = 0;
for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr), i)
{
const char *key;
struct mu_ident_ref *ref;
mu_iterator_current_kv (itr,
(const void **)&key, (void **)&ref);
mu_stream_printf (str, "%04zu: %s: %zu\n", i, key, ref->count);
}
}
mu_iterator_destroy (&itr);
}
mu_stream_printf (str, "END IDENT STAT\n");
}
......
......@@ -20,6 +20,7 @@
#include <mailutils/types.h>
#include <mailutils/locus.h>
#include <mailutils/error.h>
#include <mailutils/errno.h>
int
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)
int
mu_locus_point_init (struct mu_locus_point *pt, const char *filename)
{
pt->mu_line = 0;
pt->mu_col = 0;
return mu_locus_point_set_file (pt, filename);
int rc = mu_locus_point_set_file (pt, filename);
if (rc == 0)
{
pt->mu_line = 0;
pt->mu_col = 0;
}
return rc;
}
void
......@@ -54,9 +59,13 @@ int
mu_locus_point_copy (struct mu_locus_point *dest,
struct mu_locus_point const *src)
{
dest->mu_col = src->mu_col;
dest->mu_line = src->mu_line;
return mu_locus_point_set_file (dest, src->mu_file);
int rc = mu_locus_point_set_file (dest, src->mu_file);
if (rc == 0)
{
dest->mu_col = src->mu_col;
dest->mu_line = src->mu_line;
}
return rc;
}
int
......@@ -65,7 +74,10 @@ mu_locus_range_copy (struct mu_locus_range *dest,
{
int rc;
struct mu_locus_range tmp = MU_LOCUS_RANGE_INITIALIZER;
if (!dest)
return MU_ERR_OUT_PTR_NULL;
rc = mu_locus_point_copy (&tmp.beg, &src->beg);
if (rc == 0)
{
......@@ -73,7 +85,10 @@ mu_locus_range_copy (struct mu_locus_range *dest,
if (rc)
mu_locus_point_deinit (&tmp.beg);
else
*dest = tmp;
{
mu_locus_range_deinit (dest);
*dest = tmp;
}
}
return rc;
}
......
......@@ -258,11 +258,7 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
severity = MU_LOG_EMERG;
if (save_locus)
{
sp->locrange = loc;
mu_ident_ref (sp->locrange.beg.mu_file, &sp->locrange.beg.mu_file);
mu_ident_ref (sp->locrange.end.mu_file, &sp->locrange.end.mu_file);
}
mu_locus_range_copy (&sp->locrange, &loc);
if (severity < sp->threshold)
rc = 0;
......@@ -649,6 +645,8 @@ mu_log_stream_create (mu_stream_t *pstr, mu_stream_t transport)
return 0;
}
static char wiki_url[] = "http://mailutils.org/wiki/Source_location_API#Deprecated_interface";
int
mu_ioctl_logstream_get_locus_deprecated (void)
{
......@@ -656,6 +654,7 @@ mu_ioctl_logstream_get_locus_deprecated (void)
if (!warned)
{
mu_error (_("the program uses MU_IOCTL_LOGSTREAM_GET_LOCUS, which is deprecated"));
mu_error (_("please see %s, for detailed guidelines"), wiki_url);
warned = 1;
}
return MU_IOCTL_LOGSTREAM_GET_LOCUS_DEPRECATED;
......@@ -668,6 +667,7 @@ mu_ioctl_logstream_set_locus_deprecated (void)
if (!warned)
{
mu_error (_("program uses MU_IOCTL_LOGSTREAM_SET_LOCUS, which is deprecated"));
mu_error (_("please see %s, for detailed guidelines"), wiki_url);
warned = 1;
}
return MU_IOCTL_LOGSTREAM_SET_LOCUS_DEPRECATED;
......
......@@ -59,6 +59,7 @@ main (int argc, char **argv)
}
mu_locus_range_deinit (&lr);
}
mu_linetrack_destroy (&trk);
return 0;
}
......
......@@ -629,6 +629,7 @@ struct testcase
{
char const *id;
void (*handler) (mu_stream_t);
int enabled;
};
struct testcase testcases[] = {
......@@ -689,17 +690,37 @@ main (int argc, char **argv)
mu_stream_t log;
struct testcase *tp;
int i;
int ena = 0;
mu_set_program_name (argv[0]);
mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
if (argc > 1)
{
ena = 1;
for (i = 1; i < argc; i++)
{
char *p;
int n = strtol (argv[i], &p, 10);
if (! (*p == 0 && n >= 0) )
{
mu_error ("erroneous argument %s\n", argv[i]);
return 1;
}
testcases[n].enabled = ena;
}
}
log = create_log ();
for (i = 0, tp = testcases; tp->id; tp++, i++)
{
mu_stream_printf (log, "%02d. %s\n", i, tp->id);
tp->handler (log);
log_reset (log);
if (tp->enabled == ena)
{
mu_stream_printf (log, "%02d. %s\n", i, tp->id);
tp->handler (log);
log_reset (log);
}
}
return 0;
......