1 /* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: spprint.c,v 1.7 2005/03/31 20:46:30 igor Exp $ */
18 /* Print values in ASCII form on a stream */
19 #include "math_.h" /* for fabs */
20 #include "stdio_.h" /* for stream.h */
21 #include "string_.h" /* for strchr */
22 #include "stream.h"
23 #include "spprint.h"
24
25 /* ------ Output ------ */
26
27 /* Put a byte array on a stream. */
28 int
stream_write(stream * s,const void * ptr,uint count)29 stream_write(stream * s, const void *ptr, uint count)
30 {
31 uint used;
32
33 sputs(s, (const byte *)ptr, count, &used);
34 return (int)used;
35 }
36
37 /* Put a string on a stream. */
38 int
stream_puts(stream * s,const char * str)39 stream_puts(stream * s, const char *str)
40 {
41 uint len = strlen(str);
42 uint used;
43 int status = sputs(s, (const byte *)str, len, &used);
44
45 return (status >= 0 && used == len ? 0 : EOF);
46 }
47
48 /* Print a format string up to the first variable substitution. */
49 /* Return a pointer to the %, or to the terminating 0 if no % found. */
50 private const char *
pprintf_scan(stream * s,const char * format)51 pprintf_scan(stream * s, const char *format)
52 {
53 const char *fp = format;
54
55 for (; *fp != 0; ++fp) {
56 if (*fp == '%') {
57 if (fp[1] != '%')
58 break;
59 ++fp;
60 }
61 sputc(s, *fp);
62 }
63 return fp;
64 }
65
66 /* Print a short string on a stream. */
67 private void
pputs_short(stream * s,const char * str)68 pputs_short(stream *s, const char *str)
69 {
70 const char *p = str;
71
72 for (; *p; ++p)
73 sputc(s, *p);
74 }
75
76 /* Print (an) int value(s) using a format. */
77 const char *
pprintd1(stream * s,const char * format,int v)78 pprintd1(stream * s, const char *format, int v)
79 {
80 const char *fp = pprintf_scan(s, format);
81 char str[25];
82
83 #ifdef DEBUG
84 if (*fp == 0 || fp[1] != 'd') /* shouldn't happen! */
85 lprintf1("Bad format in pprintd1: %s\n", format);
86 #endif
87 sprintf(str, "%d", v);
88 pputs_short(s, str);
89 return pprintf_scan(s, fp + 2);
90 }
91 const char *
pprintd2(stream * s,const char * format,int v1,int v2)92 pprintd2(stream * s, const char *format, int v1, int v2)
93 {
94 return pprintd1(s, pprintd1(s, format, v1), v2);
95 }
96 const char *
pprintd3(stream * s,const char * format,int v1,int v2,int v3)97 pprintd3(stream * s, const char *format, int v1, int v2, int v3)
98 {
99 return pprintd2(s, pprintd1(s, format, v1), v2, v3);
100 }
101 const char *
pprintd4(stream * s,const char * format,int v1,int v2,int v3,int v4)102 pprintd4(stream * s, const char *format, int v1, int v2, int v3, int v4)
103 {
104 return pprintd2(s, pprintd2(s, format, v1, v2), v3, v4);
105 }
106
107 /* Print (a) floating point number(s) using a format. */
108 /* See gdevpdfx.h for why this is needed. */
109 const char *
pprintg1(stream * s,const char * format,floatp v)110 pprintg1(stream * s, const char *format, floatp v)
111 {
112 const char *fp = pprintf_scan(s, format);
113 char str[150];
114
115 #ifdef DEBUG
116 if (*fp == 0 || fp[1] != 'g') /* shouldn't happen! */
117 lprintf1("Bad format in pprintg: %s\n", format);
118 #endif
119 sprintf(str, "%g", v);
120 if (strchr(str, 'e')) {
121 /* Bad news. Try again using f-format. */
122 sprintf(str, (fabs(v) > 1 ? "%1.1f" : "%1.8f"), v);
123 }
124 pputs_short(s, str);
125 return pprintf_scan(s, fp + 2);
126 }
127 const char *
pprintg2(stream * s,const char * format,floatp v1,floatp v2)128 pprintg2(stream * s, const char *format, floatp v1, floatp v2)
129 {
130 return pprintg1(s, pprintg1(s, format, v1), v2);
131 }
132 const char *
pprintg3(stream * s,const char * format,floatp v1,floatp v2,floatp v3)133 pprintg3(stream * s, const char *format, floatp v1, floatp v2, floatp v3)
134 {
135 return pprintg2(s, pprintg1(s, format, v1), v2, v3);
136 }
137 const char *
pprintg4(stream * s,const char * format,floatp v1,floatp v2,floatp v3,floatp v4)138 pprintg4(stream * s, const char *format, floatp v1, floatp v2, floatp v3,
139 floatp v4)
140 {
141 return pprintg2(s, pprintg2(s, format, v1, v2), v3, v4);
142 }
143 const char *
pprintg6(stream * s,const char * format,floatp v1,floatp v2,floatp v3,floatp v4,floatp v5,floatp v6)144 pprintg6(stream * s, const char *format, floatp v1, floatp v2, floatp v3,
145 floatp v4, floatp v5, floatp v6)
146 {
147 return pprintg3(s, pprintg3(s, format, v1, v2, v3), v4, v5, v6);
148 }
149
150 /* Print a long value using a format. */
151 const char *
pprintld1(stream * s,const char * format,long v)152 pprintld1(stream * s, const char *format, long v)
153 {
154 const char *fp = pprintf_scan(s, format);
155 char str[25];
156
157 #ifdef DEBUG
158 if (*fp == 0 || fp[1] != 'l' || fp[2] != 'd') /* shouldn't happen! */
159 lprintf1("Bad format in pprintld: %s\n", format);
160 #endif
161 sprintf(str, "%ld", v);
162 pputs_short(s, str);
163 return pprintf_scan(s, fp + 3);
164 }
165 const char *
pprintld2(stream * s,const char * format,long v1,long v2)166 pprintld2(stream * s, const char *format, long v1, long v2)
167 {
168 return pprintld1(s, pprintld1(s, format, v1), v2);
169 }
170 const char *
pprintld3(stream * s,const char * format,long v1,long v2,long v3)171 pprintld3(stream * s, const char *format, long v1, long v2, long v3)
172 {
173 return pprintld2(s, pprintld1(s, format, v1), v2, v3);
174 }
175
176 /* Print (a) string(s) using a format. */
177 const char *
pprints1(stream * s,const char * format,const char * str)178 pprints1(stream * s, const char *format, const char *str)
179 {
180 const char *fp = pprintf_scan(s, format);
181
182 #ifdef DEBUG
183 if (*fp == 0 || fp[1] != 's') /* shouldn't happen! */
184 lprintf1("Bad format in pprints: %s\n", format);
185 #endif
186 pputs_short(s, str);
187 return pprintf_scan(s, fp + 2);
188 }
189 const char *
pprints2(stream * s,const char * format,const char * str1,const char * str2)190 pprints2(stream * s, const char *format, const char *str1, const char *str2)
191 {
192 return pprints1(s, pprints1(s, format, str1), str2);
193 }
194 const char *
pprints3(stream * s,const char * format,const char * str1,const char * str2,const char * str3)195 pprints3(stream * s, const char *format, const char *str1, const char *str2,
196 const char *str3)
197 {
198 return pprints2(s, pprints1(s, format, str1), str2, str3);
199 }
200