xref: /plan9/sys/src/cmd/gs/src/gslibctx.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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