summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2016-04-19 16:54:52 +0200
committerTor Andersson <tor.andersson@artifex.com>2016-05-13 11:42:00 +0200
commitb994d72069d761c8645cc6a0638bde21109c0b40 (patch)
tree2d95cbdb501d81b49210d6c115b51bb5fa9c62a7
parente67981e781fd087d7cd19e2373b3e054375e82ad (diff)
downloadmupdf-b994d72069d761c8645cc6a0638bde21109c0b40.tar.xz
Introduce a general output context.
This makes it possible to redirect standard out and standard error output streams to output streams of your liking. This means that now you can, in gdb, type: (gdb) call pdf_print_obj(ctx, fz_stdout(ctx), obj, 0) (gdb) call fflush(0) or when dealing with an unresolved indirect reference: (gdb) call pdf_print_obj(ctx, fz_stdout(ctx), pdf_resolve_indirect(ctx, ref), 0) (gdb) call fflush(0)
-rw-r--r--Makefile2
-rw-r--r--include/mupdf/fitz/context.h2
-rw-r--r--include/mupdf/fitz/output.h15
-rw-r--r--scripts/cmapdump.c1
-rw-r--r--source/fitz/context.c4
-rw-r--r--source/fitz/output.c92
-rw-r--r--source/tools/mudraw.c4
-rw-r--r--source/tools/pdfinfo.c2
-rw-r--r--source/tools/pdfpages.c2
-rw-r--r--source/tools/pdfshow.c4
10 files changed, 120 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index 50179f27..9e155d7b 100644
--- a/Makefile
+++ b/Makefile
@@ -250,7 +250,7 @@ $(OUT)/pdf/pdf-cmap-table.o : $(CMAP_GEN)
$(OUT)/pdf/pdf-pkcs7.o : $(ADOBECA_GEN)
$(OUT)/pdf/js/pdf-js.o : $(JAVASCRIPT_GEN)
$(OUT)/pdf/pdf-object.o : source/pdf/pdf-name-table.h
-$(OUT)/cmapdump.o : include/mupdf/pdf/cmap.h source/fitz/context.c source/fitz/error.c source/fitz/memory.c source/fitz/string.c source/fitz/buffer.c source/fitz/stream-open.c source/fitz/stream-read.c source/fitz/strtod.c source/fitz/strtof.c source/fitz/ftoa.c source/fitz/printf.c source/fitz/time.c source/pdf/pdf-lex.c source/pdf/pdf-cmap.c source/pdf/pdf-cmap-parse.c source/pdf/pdf-name-table.h
+$(OUT)/cmapdump.o : include/mupdf/pdf/cmap.h source/fitz/context.c source/fitz/error.c source/fitz/memory.c source/fitz/output.c source/fitz/string.c source/fitz/buffer.c source/fitz/stream-open.c source/fitz/stream-read.c source/fitz/strtod.c source/fitz/strtof.c source/fitz/ftoa.c source/fitz/printf.c source/fitz/time.c source/pdf/pdf-lex.c source/pdf/pdf-cmap.c source/pdf/pdf-cmap-parse.c source/pdf/pdf-name-table.h
# --- Tools and Apps ---
diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h
index 6153e6e1..2d902e62 100644
--- a/include/mupdf/fitz/context.h
+++ b/include/mupdf/fitz/context.h
@@ -23,6 +23,7 @@ typedef struct fz_tuning_context_s fz_tuning_context;
typedef struct fz_store_s fz_store;
typedef struct fz_glyph_cache_s fz_glyph_cache;
typedef struct fz_document_handler_context_s fz_document_handler_context;
+typedef struct fz_output_context_s fz_output_context;
typedef struct fz_context_s fz_context;
struct fz_alloc_context_s
@@ -123,6 +124,7 @@ struct fz_context_s
fz_glyph_cache *glyph_cache;
fz_tuning_context *tuning;
fz_document_handler_context *handler;
+ fz_output_context *output;
};
/*
diff --git a/include/mupdf/fitz/output.h b/include/mupdf/fitz/output.h
index 35f61aa7..8e9ad170 100644
--- a/include/mupdf/fitz/output.h
+++ b/include/mupdf/fitz/output.h
@@ -31,6 +31,17 @@ fz_output *fz_new_output_with_path(fz_context *, const char *filename, int appen
fz_output *fz_new_output_with_buffer(fz_context *, fz_buffer *);
/*
+ fz_stdout: The standard out output stream.
+ fz_stderr: The standard error output stream.
+ fz_set_stdout: Replace default standard output stream with a new stream.
+ fz_set_stderr: Replace default standard error stream with a new stream.
+*/
+fz_output *fz_stdout(fz_context *);
+fz_output *fz_stderr(fz_context *);
+void fz_set_stdout(fz_context *ctx, fz_output *out);
+void fz_set_stderr(fz_context *ctx, fz_output *err);
+
+/*
fz_write: fwrite equivalent for output streams.
fz_printf: fprintf equivalent for output streams. See fz_snprintf.
fz_vprintf: vfprintf equivalent for output streams. See fz_vsnprintf.
@@ -149,4 +160,8 @@ char *fz_tempfilename(fz_context *ctx, const char *base, const char *hint);
*/
void fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename);
+void fz_new_output_context(fz_context *ctx);
+void fz_drop_output_context(fz_context *ctx);
+fz_output_context *fz_keep_output_context(fz_context *ctx);
+
#endif
diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c
index 9cc3523b..6467739b 100644
--- a/scripts/cmapdump.c
+++ b/scripts/cmapdump.c
@@ -14,6 +14,7 @@
#include "../source/fitz/context.c"
#include "../source/fitz/error.c"
#include "../source/fitz/memory.c"
+#include "../source/fitz/output.c"
#include "../source/fitz/string.c"
#include "../source/fitz/buffer.c"
#include "../source/fitz/stream-open.c"
diff --git a/source/fitz/context.c b/source/fitz/context.c
index bfc7a1cd..9a533cff 100644
--- a/source/fitz/context.c
+++ b/source/fitz/context.c
@@ -132,6 +132,7 @@ fz_drop_context(fz_context *ctx)
fz_drop_colorspace_context(ctx);
fz_drop_font_context(ctx);
fz_drop_id_context(ctx);
+ fz_drop_output_context(ctx);
if (ctx->warn)
{
@@ -222,6 +223,7 @@ fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks,
/* Now initialise sections that are shared */
fz_try(ctx)
{
+ fz_new_output_context(ctx);
fz_new_store_context(ctx, max_store);
fz_new_glyph_cache_context(ctx);
fz_new_colorspace_context(ctx);
@@ -266,6 +268,8 @@ fz_clone_context_internal(fz_context *ctx)
fz_copy_aa_context(new_ctx, ctx);
/* Keep thread lock checking happy by copying pointers first and locking under new context */
+ new_ctx->output = ctx->output;
+ new_ctx->output = fz_keep_output_context(new_ctx);
new_ctx->user = ctx->user;
new_ctx->store = ctx->store;
new_ctx->store = fz_keep_store_context(new_ctx);
diff --git a/source/fitz/output.c b/source/fitz/output.c
index 9ea2d169..07422955 100644
--- a/source/fitz/output.c
+++ b/source/fitz/output.c
@@ -1,5 +1,87 @@
#include "mupdf/fitz.h"
+struct fz_output_context_s
+{
+ int refs;
+ fz_output *out;
+ fz_output *err;
+};
+
+static void std_write(fz_context *ctx, void *opaque, const void *buffer, int count);
+
+static fz_output fz_stdout_global = {
+ &fz_stdout_global,
+ std_write,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static fz_output fz_stderr_global = {
+ &fz_stderr_global,
+ std_write,
+ NULL,
+ NULL,
+ NULL,
+};
+
+void
+fz_new_output_context(fz_context *ctx)
+{
+ ctx->output = fz_malloc_struct(ctx, fz_output_context);
+ ctx->output->refs = 1;
+ ctx->output->out = &fz_stdout_global;
+ ctx->output->err = &fz_stderr_global;
+}
+
+fz_output_context *
+fz_keep_output_context(fz_context *ctx)
+{
+ if (!ctx)
+ return NULL;
+ return fz_keep_imp(ctx, ctx->output, &ctx->output->refs);
+}
+
+void
+fz_drop_output_context(fz_context *ctx)
+{
+ if (!ctx || !ctx->output)
+ return;
+
+ if (fz_drop_imp(ctx, ctx->output, &ctx->output->refs))
+ {
+ /* FIXME: should we flush here? closing the streams seems wrong */
+ fz_free(ctx, ctx->output);
+ ctx->output = NULL;
+ }
+}
+
+void
+fz_set_stdout(fz_context *ctx, fz_output *out)
+{
+ fz_drop_output(ctx, ctx->output->out);
+ ctx->output->out = out ? out : &fz_stdout_global;
+}
+
+void
+fz_set_stderr(fz_context *ctx, fz_output *err)
+{
+ fz_drop_output(ctx, ctx->output->err);
+ ctx->output->err = err ? err : &fz_stderr_global;
+}
+
+fz_output *
+fz_stdout(fz_context *ctx)
+{
+ return ctx->output->out;
+}
+
+fz_output *
+fz_stderr(fz_context *ctx)
+{
+ return ctx->output->err;
+}
+
static void
file_write(fz_context *ctx, void *opaque, const void *buffer, int count)
{
@@ -23,6 +105,13 @@ file_write(fz_context *ctx, void *opaque, const void *buffer, int count)
}
static void
+std_write(fz_context *ctx, void *opaque, const void *buffer, int count)
+{
+ FILE *f = opaque == &fz_stdout_global ? stdout : opaque == &fz_stderr_global ? stderr : NULL;
+ file_write(ctx, f, buffer, count);
+}
+
+static void
file_seek(fz_context *ctx, void *opaque, fz_off_t off, int whence)
{
FILE *file = opaque;
@@ -132,7 +221,8 @@ fz_drop_output(fz_context *ctx, fz_output *out)
if (!out) return;
if (out->close)
out->close(ctx, out->opaque);
- fz_free(ctx, out);
+ if (out->opaque != &fz_stdout_global && out->opaque != &fz_stderr_global)
+ fz_free(ctx, out);
}
void
diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c
index 2717b5f0..6523380b 100644
--- a/source/tools/mudraw.c
+++ b/source/tools/mudraw.c
@@ -698,7 +698,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in
fz_output *out;
if (!strcmp(output, "-"))
- out = fz_new_output_with_file_ptr(ctx, stdout, 0);
+ out = fz_stdout(ctx);
else
{
sprintf(buf, output, pagenum);
@@ -1606,7 +1606,7 @@ int mudraw_main(int argc, char **argv)
out = fz_new_output_with_path(ctx, output, 0);
}
else
- out = fz_new_output_with_file_ptr(ctx, stdout, 0);
+ out = fz_stdout(ctx);
timing.count = 0;
timing.total = 0;
diff --git a/source/tools/pdfinfo.c b/source/tools/pdfinfo.c
index da500f04..0d30b22a 100644
--- a/source/tools/pdfinfo.c
+++ b/source/tools/pdfinfo.c
@@ -1073,7 +1073,7 @@ int pdfinfo_main(int argc, char **argv)
ret = 0;
fz_try(ctx)
{
- out = fz_new_output_with_file_ptr(ctx, stdout, 0);
+ out = fz_stdout(ctx);
pdfinfo_info(ctx, out, filename, password, show, &argv[fz_optind], argc-fz_optind);
}
fz_catch(ctx)
diff --git a/source/tools/pdfpages.c b/source/tools/pdfpages.c
index f13b5541..7f3577da 100644
--- a/source/tools/pdfpages.c
+++ b/source/tools/pdfpages.c
@@ -241,7 +241,7 @@ int pdfpages_main(int argc, char **argv)
ret = 0;
fz_try(ctx)
{
- out = fz_new_output_with_file_ptr(ctx, stdout, 0);
+ out = fz_stdout(ctx);
ret = pdfpages_pages(ctx, out, filename, password, &argv[fz_optind], argc-fz_optind);
}
fz_catch(ctx)
diff --git a/source/tools/pdfshow.c b/source/tools/pdfshow.c
index 98a374b1..988663a4 100644
--- a/source/tools/pdfshow.c
+++ b/source/tools/pdfshow.c
@@ -197,7 +197,7 @@ static void showoutline(void)
fz_var(out);
fz_try(ctx)
{
- out = fz_new_output_with_file_ptr(ctx, stdout, 0);
+ out = fz_stdout(ctx);
fz_print_outline(ctx, out, outline);
}
fz_always(ctx)
@@ -245,7 +245,7 @@ int pdfshow_main(int argc, char **argv)
if (output)
out = fz_new_output_with_path(ctx, output, 0);
else
- out = fz_new_output_with_file_ptr(ctx, stdout, 0);
+ out = fz_stdout(ctx);
fz_var(doc);
fz_try(ctx)