summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-09-14 19:48:17 +0100
committerRobin Watts <robin.watts@artifex.com>2016-09-14 19:53:35 +0100
commitbf63314097c7c37a950550f78237c091ecba1417 (patch)
tree76e002849c0ce9b32eda6182bc20074b96f88e1e
parentee714b548cbe43c3337bbf7fcba79a751b609151 (diff)
downloadmupdf-bf63314097c7c37a950550f78237c091ecba1417.tar.xz
Redirect fprintf to android logcat in debug builds.
This makes debugging much simpler.
-rw-r--r--include/mupdf/fitz/system.h13
-rw-r--r--source/fitz/error.c75
2 files changed, 77 insertions, 11 deletions
diff --git a/include/mupdf/fitz/system.h b/include/mupdf/fitz/system.h
index cb5c2a4a..1723824f 100644
--- a/include/mupdf/fitz/system.h
+++ b/include/mupdf/fitz/system.h
@@ -215,12 +215,13 @@ typedef int fz_off_t;
#ifdef __ANDROID__
#include <android/log.h>
-#define LOG_TAG "libmupdf"
-#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
-#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
-#else
-#define LOGI(...) do {} while(0)
-#define LOGE(...) do {} while(0)
+int fz_android_fprintf(FILE *file, const char *fmt, ...);
+#ifdef DEBUG
+/* Capture fprintf for stdout/stderr to the android logging
+ * stream. Only do this in debug builds as this implies a
+ * delay */
+#define fprintf fz_android_fprintf
+#endif
#endif
/* inline is standard in C++. For some compilers we can enable it within C too. */
diff --git a/source/fitz/error.c b/source/fitz/error.c
index 773f747a..2ac091e7 100644
--- a/source/fitz/error.c
+++ b/source/fitz/error.c
@@ -16,7 +16,6 @@ void fz_flush_warnings(fz_context *ctx)
if (ctx->warn->count > 1)
{
fprintf(stderr, "warning: ... repeated %d times ...\n", ctx->warn->count);
- LOGE("warning: ... repeated %d times ...\n", ctx->warn->count);
}
ctx->warn->message[0] = 0;
ctx->warn->count = 0;
@@ -41,7 +40,6 @@ void fz_vwarn(fz_context *ctx, const char *fmt, va_list ap)
{
fz_flush_warnings(ctx);
fprintf(stderr, "warning: %s\n", buf);
- LOGE("warning: %s\n", buf);
fz_strlcpy(ctx->warn->message, buf, sizeof ctx->warn->message);
ctx->warn->count = 1;
}
@@ -96,7 +94,6 @@ FZ_NORETURN static void throw(fz_context *ctx)
else
{
fprintf(stderr, "uncaught exception: %s\n", ctx->error->message);
- LOGE("uncaught exception: %s\n", ctx->error->message);
#ifdef USE_OUTPUT_DEBUG_STRING
OutputDebugStringA("uncaught exception: ");
OutputDebugStringA(ctx->error->message);
@@ -121,7 +118,6 @@ static int fz_fake_throw(fz_context *ctx, int code, const char *fmt, ...)
{
fz_flush_warnings(ctx);
fprintf(stderr, "error: %s\n", ctx->error->message);
- LOGE("error: %s\n", ctx->error->message);
#ifdef USE_OUTPUT_DEBUG_STRING
OutputDebugStringA("error: ");
OutputDebugStringA(ctx->error->message);
@@ -172,7 +168,6 @@ void fz_vthrow(fz_context *ctx, int code, const char *fmt, va_list ap)
{
fz_flush_warnings(ctx);
fprintf(stderr, "error: %s\n", ctx->error->message);
- LOGE("error: %s\n", ctx->error->message);
#ifdef USE_OUTPUT_DEBUG_STRING
OutputDebugStringA("error: ");
OutputDebugStringA(ctx->error->message);
@@ -203,3 +198,73 @@ void fz_rethrow_if(fz_context *ctx, int err)
if (ctx->error->errcode == err)
fz_rethrow(ctx);
}
+
+/* Android specific code to take fprintf to LOG */
+
+#ifdef __ANDROID__
+#include <android/log.h>
+
+#define LOG_TAG "libmupdf"
+
+static char android_log_buffer[4096];
+static int android_log_fill = 0;
+
+static char android_log_buffer2[4096];
+
+int fz_android_fprintf(FILE *file, const char *fmt, ...)
+{
+ va_list args;
+ char *p, *q;
+
+ /* Just in case someone has some magic fprintf redirection code working */
+ va_start(args, fmt);
+ vfprintf(file, fmt, args);
+ va_end(args);
+
+ if (file != stdout && file != stderr)
+ return 0;
+
+ va_start(args, fmt);
+ vsnprintf(android_log_buffer2, sizeof(android_log_buffer2)-1, fmt, args);
+ va_end(args);
+
+ /* Ensure we are always null terminated */
+ android_log_buffer2[sizeof(android_log_buffer2)-1] = 0;
+
+ p = android_log_buffer2;
+ q = p;
+ do
+ {
+ /* Find the end of the string, or the next \n */
+ while (*p && *p != '\n')
+ p++;
+
+ /* We need to output from q to p. Limit ourselves to what
+ * will fit in the existing buffer. */
+ if (p - q >= sizeof(android_log_buffer)-1 - android_log_fill)
+ p = q + sizeof(android_log_buffer)-1 - android_log_fill;
+
+ memcpy(&android_log_buffer[android_log_fill], q, p-q);
+ android_log_fill += p-q;
+ if (*p == '\n')
+ {
+ android_log_buffer[android_log_fill] = 0;
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", android_log_buffer);
+ usleep(1); /* Hack to avoid the logcat buffer losing data */
+ android_log_fill = 0;
+ p++; /* Skip over the \n */
+ }
+ else if (android_log_fill >= sizeof(android_log_buffer)-1)
+ {
+ android_log_buffer[sizeof(android_log_buffer2)-1] = 0;
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", android_log_buffer);
+ usleep(1); /* Hack to avoid the logcat buffer losing data */
+ android_log_fill = 0;
+ }
+ q = p;
+ }
+ while (*p);
+
+ return 0;
+}
+#endif