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