* UCW Library -- Logging: Management of Log Streams
*
* (c) 2008 Tomas Gavenciak <gavento@ucw.cz>
- * (c) 2009 Martin Mares <mj@ucw.cz>
+ * (c) 2009--2012 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
*/
-#include "ucw/lib.h"
-#include "ucw/log.h"
-#include "ucw/simple-lists.h"
+#include <ucw/lib.h>
+#include <ucw/log.h>
+#include <ucw/log-internal.h>
+#include <ucw/simple-lists.h>
#include <string.h>
/* The head of the list of freed log_streams indexes in log_streams.ptr (~0U if none free).
* Freed positions in log_streams.ptr are connected into a linked list in the following way:
* log_streams.ptr[log_streams_free].levels is the index of next freed position (or ~0U) */
-static uns log_streams_free = ~0U;
+static uint log_streams_free = ~0U;
/* Initialize the logstream module.
* It is not neccessary to call this explicitely as it is called by
log_add_substream(ls, &log_stream_default);
}
-/* Close all open streams, un-initialize the module, free all memory,
- * and fall back to using only log_stream_default. */
void
log_close_all(void)
{
if (!log_initialized)
return;
+ // Remove substreams of all streams
+ for (int i=0; i < log_streams_after; i++)
+ if (log_streams.ptr[i]->regnum >= 0)
+ log_rm_substream(log_streams.ptr[i], NULL);
+
+ // Close all streams that remain and free all cached structures
for (int i=0; i < log_streams_after; i++)
{
- if (log_streams.ptr[i]->regnum >= 0)
- log_close_stream(log_streams.ptr[i]);
- xfree(log_streams.ptr[i]);
+ struct log_stream *ls = log_streams.ptr[i];
+ if (ls->regnum >= 0)
+ log_close_stream(ls);
+ ASSERT(ls->regnum < 0 || !ls->use_count);
+ xfree(ls);
}
/* Back to the default state */
log_initialized = 0;
}
-/* Add a new substream. The parent stream takes a reference on the substream,
- * preventing it from being closed as long as it is linked. */
void
log_add_substream(struct log_stream *where, struct log_stream *what)
{
clist_add_tail(&where->substreams, &n->n);
}
-/* Remove all occurrences of a substream together with the references they
- * keep. If a substream becomes unreferenced, it is closed. If what is NULL,
- * all substreams are removed. Returns the number of deleted entries. */
int
log_rm_substream(struct log_stream *where, struct log_stream *what)
{
return cnt;
}
-/* Return a pointer to a new stream with no handler and an empty substream list. */
struct log_stream *
log_new_stream(size_t size)
{
/* Initialize the stream */
bzero(l, sizeof(*l));
- l->levels = LS_ALL_LEVELS;
+ l->levels = ~0U;
+ l->types = ~0U;
l->regnum = LS_SET_STRNUM(index);
clist_init(&l->substreams);
return log_ref_stream(l);
}
-/* Remove a reference on a stream and close it if it was the last reference.
- * Closing automatically unlinks all substreams and closes them if they are
- * no longer referenced. Returns 1 if the stream has been really closed. */
int
log_close_stream(struct log_stream *ls)
{
}
void
-log_set_format(struct log_stream *ls, uns mask, uns data)
+log_set_format(struct log_stream *ls, uint mask, uint data)
{
ls->msgfmt = (ls->msgfmt & mask) | data;
CLIST_FOR_EACH(simp_node *, i, ls->substreams)
log_set_format(i->p, mask, data);
}
+
+void
+log_set_default_stream(struct log_stream *ls)
+{
+ struct log_stream *def = log_stream_by_flags(0);
+ log_rm_substream(def, NULL);
+ log_add_substream(def, ls);
+ log_close_stream(ls);
+}
+
+/*** Registry of type names ***/
+
+int log_register_type(const char *name)
+{
+ if (!log_type_names)
+ {
+ log_type_names = xmalloc_zero(LS_NUM_TYPES * sizeof(char *));
+ log_type_names[0] = "default";
+ }
+ uint id;
+ for (id=0; id < LS_NUM_TYPES && log_type_names[id]; id++)
+ if (!strcmp(log_type_names[id], name))
+ return LS_SET_TYPE(id);
+ ASSERT(id < LS_NUM_TYPES);
+ log_type_names[id] = xstrdup(name);
+ return LS_SET_TYPE(id);
+}
+
+/** Find a message type by name and return its ID encoded by `LS_SET_TYPE`. Returns -1 if no such type found. **/
+int log_find_type(const char *name)
+{
+ if (!strcmp(name, "default"))
+ return 0;
+ if (!log_type_names)
+ return -1;
+
+ for (uint id=0; id < LS_NUM_TYPES && log_type_names[id]; id++)
+ if (!strcmp(log_type_names[id], name))
+ return LS_SET_TYPE(id);
+ return -1;
+}