summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-09-25 11:11:39 +0000
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-09-25 11:11:39 +0000
commit1c262c8826067b0d240f6db1c4eebf5514ea7475 (patch)
treef7655fc878d6904a7416e50d9280650853feab92 /src
parent37755ffdb63164e768745369a98f06c5ec9d476d (diff)
downloadopenocd_libswd-1c262c8826067b0d240f6db1c4eebf5514ea7475.tar.gz
openocd_libswd-1c262c8826067b0d240f6db1c4eebf5514ea7475.tar.bz2
openocd_libswd-1c262c8826067b0d240f6db1c4eebf5514ea7475.tar.xz
openocd_libswd-1c262c8826067b0d240f6db1c4eebf5514ea7475.zip
Try/catch scheme. Typed up the functionality and regression tested.
Ready for discussion and tiny patches that tries out this scheme. git-svn-id: svn://svn.berlios.de/openocd/trunk@2755 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src')
-rw-r--r--src/helper/log.c100
-rw-r--r--src/helper/log.h9
2 files changed, 100 insertions, 9 deletions
diff --git a/src/helper/log.c b/src/helper/log.c
index 9bfe4d11..f68c9a3e 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -64,6 +64,95 @@ static char *log_strings[5] =
static int count = 0;
+
+static struct store_log_forward * log_head = NULL;
+static int log_forward_count = 0;
+
+struct store_log_forward
+{
+ struct store_log_forward * next;
+ const char * file;
+ int line;
+ const char * function;
+ const char * string;
+};
+
+/* either forward the log to the listeners or store it for possible forwarding later */
+static void log_forward(const char *file, int line, const char *function, const char *string)
+{
+ if (log_forward_count==0)
+ {
+ log_callback_t *cb, *next;
+ cb = log_callbacks;
+ /* DANGER!!!! the log callback can remove itself!!!! */
+ while (cb)
+ {
+ next = cb->next;
+ cb->fn(cb->priv, file, line, function, string);
+ cb = next;
+ }
+ } else
+ {
+ struct store_log_forward *log = malloc(sizeof (struct store_log_forward));
+ log->file = strdup(file);
+ log->line = line;
+ log->function = strdup(function);
+ log->string = strdup(string);
+ log->next = NULL;
+ if (log_head==NULL)
+ log_head = log;
+ else
+ {
+ /* append to tail */
+ struct store_log_forward * t;
+ t = log_head;
+ while (t->next!=NULL)
+ {
+ t = t->next;
+ }
+ t->next = log;
+ }
+ }
+}
+
+void log_try(void)
+{
+ log_forward_count++;
+}
+
+void log_catch(void)
+{
+ assert(log_forward_count>0);
+ log_forward_count--;
+}
+
+void log_rethrow(void)
+{
+ log_catch();
+ if (log_forward_count==0)
+ {
+ struct store_log_forward *log;
+
+ log = log_head;
+ while (log != NULL)
+ {
+ log_forward(log->file, log->line, log->function, log->string);
+
+ struct store_log_forward *t=log;
+ log = log->next;
+
+ free((void *)t->file);
+ free((void *)t->function);
+ free((void *)t->string);
+ free(t);
+
+ }
+
+ log_head = NULL;
+ }
+}
+
+
/* The log_puts() serves to somewhat different goals:
*
* - logging
@@ -131,18 +220,11 @@ static void log_puts(enum log_levels level, const char *file, int line, const ch
/* Never forward LOG_LVL_DEBUG, too verbose and they can be found in the log if need be */
if (level <= LOG_LVL_INFO)
{
- log_callback_t *cb, *next;
- cb = log_callbacks;
- /* DANGER!!!! the log callback can remove itself!!!! */
- while (cb)
- {
- next = cb->next;
- cb->fn(cb->priv, file, line, function, string);
- cb = next;
- }
+ log_forward(file, line, function, string);
}
}
+
void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
{
char *string;
diff --git a/src/helper/log.h b/src/helper/log.h
index c3be0747..7fc5a886 100644
--- a/src/helper/log.h
+++ b/src/helper/log.h
@@ -64,6 +64,15 @@ extern void kept_alive(void);
extern void alive_sleep(int ms);
extern void busy_sleep(int ms);
+
+/* log entries can be paused and replayed roughly according to the try/catch/rethrow
+ * concepts in C++
+ */
+void log_try(void);
+void log_catch(void);
+void log_rethrow(void);
+
+
typedef void (*log_callback_fn)(void *priv, const char *file, int line,
const char *function, const char *string);