1 /* Portions Copyright (C) 2003 artofcode LLC.
2 Portions Copyright (C) 2003 Artifex Software Inc.
3 This software is based in part on the work of the Independent JPEG Group.
4 All Rights Reserved.
5
6 This software is distributed under license and may not be copied, modified
7 or distributed except as expressly authorized under the terms of that
8 license. Refer to licensing information at http://www.artifex.com/ or
9 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
10 San Rafael, CA 94903, (415)492-9861, for further information. */
11
12 /*$Id: gslibctx.c,v 1.7 2004/12/08 21:35:13 stefan Exp $ */
13
14 /* library context functionality for ghostscript
15 * api callers get a gs_main_instance
16 */
17
18 /* Capture stdin/out/err before gs.h redefines them. */
19 #include "stdio_.h"
20
21 static void
gs_lib_ctx_get_real_stdio(FILE ** in,FILE ** out,FILE ** err)22 gs_lib_ctx_get_real_stdio(FILE **in, FILE **out, FILE **err)
23 {
24 *in = stdin;
25 *out = stdout;
26 *err = stderr;
27 }
28
29
30 #include "gslibctx.h"
31 #include "gsmemory.h"
32
33 static gs_memory_t *mem_err_print = NULL;
34
35
36 const gs_memory_t *
gs_lib_ctx_get_non_gc_memory_t()37 gs_lib_ctx_get_non_gc_memory_t()
38 {
39 return mem_err_print ? mem_err_print->non_gc_memory : NULL;
40 }
41
42
gs_lib_ctx_init(gs_memory_t * mem)43 int gs_lib_ctx_init( gs_memory_t *mem )
44 {
45 gs_lib_ctx_t *pio = 0;
46
47 if ( mem == 0 )
48 return -1; /* assert mem != 0 */
49
50 mem_err_print = mem;
51
52 if (mem->gs_lib_ctx) /* one time initialization */
53 return 0;
54
55 pio = mem->gs_lib_ctx =
56 (gs_lib_ctx_t*)gs_alloc_bytes_immovable(mem,
57 sizeof(gs_lib_ctx_t),
58 "gs_lib_ctx_init");
59 if( pio == 0 )
60 return -1;
61 pio->memory = mem;
62
63 gs_lib_ctx_get_real_stdio(&pio->fstdin, &pio->fstdout, &pio->fstderr );
64
65 pio->fstdout2 = NULL;
66 pio->stdout_is_redirected = false;
67 pio->stdout_to_stderr = false;
68 pio->stdin_is_interactive = true;
69 pio->stdin_fn = 0;
70 pio->stdout_fn = 0;
71 pio->stderr_fn = 0;
72 pio->poll_fn = 0;
73
74 pio->gs_next_id = 1; /* this implies that each thread has its own complete state */
75
76 pio->dict_auto_expand = false;
77 return 0;
78 }
79
80 /* Provide a single point for all "C" stdout and stderr.
81 */
82
outwrite(const gs_memory_t * mem,const char * str,int len)83 int outwrite(const gs_memory_t *mem, const char *str, int len)
84 {
85 int code;
86 FILE *fout;
87 gs_lib_ctx_t *pio = mem->gs_lib_ctx;
88
89 if (len == 0)
90 return 0;
91 if (pio->stdout_is_redirected) {
92 if (pio->stdout_to_stderr)
93 return errwrite(str, len);
94 fout = pio->fstdout2;
95 }
96 else if (pio->stdout_fn) {
97 return (*pio->stdout_fn)(pio->caller_handle, str, len);
98 }
99 else {
100 fout = pio->fstdout;
101 }
102 code = fwrite(str, 1, len, fout);
103 fflush(fout);
104 return code;
105 }
106
errwrite(const char * str,int len)107 int errwrite(const char *str, int len)
108 {
109 int code;
110 if (len == 0)
111 return 0;
112 if (mem_err_print->gs_lib_ctx->stderr_fn)
113 return (*mem_err_print->gs_lib_ctx->stderr_fn)(mem_err_print->gs_lib_ctx->caller_handle, str, len);
114
115 code = fwrite(str, 1, len, mem_err_print->gs_lib_ctx->fstderr);
116 fflush(mem_err_print->gs_lib_ctx->fstderr);
117 return code;
118 }
119
outflush(const gs_memory_t * mem)120 void outflush(const gs_memory_t *mem)
121 {
122 if (mem->gs_lib_ctx->stdout_is_redirected) {
123 if (mem->gs_lib_ctx->stdout_to_stderr) {
124 if (!mem->gs_lib_ctx->stderr_fn)
125 fflush(mem->gs_lib_ctx->fstderr);
126 }
127 else
128 fflush(mem->gs_lib_ctx->fstdout2);
129 }
130 else if (!mem->gs_lib_ctx->stdout_fn)
131 fflush(mem->gs_lib_ctx->fstdout);
132 }
133
errflush(void)134 void errflush(void)
135 {
136 if (!mem_err_print->gs_lib_ctx->stderr_fn)
137 fflush(mem_err_print->gs_lib_ctx->fstderr);
138 /* else nothing to flush */
139 }
140
141
142