xref: /illumos-gate/usr/src/cmd/lp/lib/lp/sdn.c (revision a0955b86cd77e22e80846428a5065e871b6d8eb8)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.5	*/
32 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
33 
34 #include "stdio.h"
35 #include "string.h"
36 #include "stdlib.h"
37 
38 #include "lp.h"
39 
40 #define N_COMPRESSED	9999
41 
42 /**
43  ** printsdn() - PRINT A SCALED DECIMAL NUMBER NICELY
44  **/
45 
46 #define	DFLT_PREFIX	0
47 #define	DFLT_SUFFIX	0
48 #define	DFLT_NEWLINE	"\n"
49 
50 static char		*print_prefix	= DFLT_PREFIX,
51 			*print_suffix	= DFLT_SUFFIX,
52 			*print_newline	= DFLT_NEWLINE;
53 
54 void
55 printsdn_setup(char *prefix, char *suffix, char *newline)
56 {
57 	if (prefix)
58 		print_prefix = prefix;
59 	if (suffix)
60 		print_suffix = suffix;
61 	if (newline)
62 		print_newline = newline;
63 	return;
64 }
65 
66 void
67 printsdn_unsetup ()
68 {
69 	print_prefix = DFLT_PREFIX;
70 	print_suffix = DFLT_SUFFIX;
71 	print_newline = DFLT_NEWLINE;
72 	return;
73 }
74 
75 
76 void
77 printsdn(FILE *fp, SCALED sdn)
78 {
79 	fdprintsdn(fileno(fp), sdn);
80 }
81 
82 
83 void
84 fdprintsdn(int fd, SCALED sdn)
85 {
86 	register char		*dec = "9999.999",
87 				*z;
88 
89 	if (sdn.val <= 0)
90 		return;
91 
92 	(void)fdprintf (fd, "%s", NB(print_prefix));
93 
94 	/*
95 	 * Let's try to be a bit clever in dealing with decimal
96 	 * numbers. If the number is an integer, don't print
97 	 * a decimal point. If it isn't an integer, strip trailing
98 	 * zeros from the fraction part, and don't print more
99 	 * than the thousandths place.
100 	 */
101 	if (-1000. < sdn.val && sdn.val < 10000.) {
102 
103 		/*
104 		 * Printing 0 will give us 0.000.
105 		 */
106 		sprintf (dec, "%.3f", sdn.val);
107 
108 		/*
109 		 * Skip zeroes from the end until we hit
110 		 * '.' or not-0. If we hit '.', clobber it;
111 		 * if we hit not-0, it has to be in fraction
112 		 * part, so leave it.
113 		 */
114 		z = dec + strlen(dec) - 1;
115 		while (*z == '0' && *z != '.')
116 			z--;
117 		if (*z == '.')
118 			*z = '\0';
119 		else
120 			*++z = '\0';
121 
122 		(void)fdprintf(fd, "%s", dec);
123 
124 	} else
125 		(void)fdprintf(fd, "%.3f", sdn.val);
126 
127 	if (sdn.sc == 'i' || sdn.sc == 'c')
128 		fdputc(sdn.sc, fd);
129 
130 	(void)fdprintf(fd, "%s%s", NB(print_suffix), NB(print_newline));
131 	return;
132 }
133 
134 
135 /**
136  ** _getsdn() - PARSE SCALED DECIMAL NUMBER
137  **/
138 
139 SCALED
140 _getsdn(char *str, char **p_after, int is_cpi)
141 {
142 	static SCALED		sdn	= { 0.0 , 0 };
143 
144 	char *			rest;
145 
146 
147 	/*
148 	 * A nonzero "errno" is our only method of indicating error.
149 	 */
150 	errno = 0;
151 
152 	if (is_cpi && STREQU(str, NAME_PICA)) {
153 		sdn.val = 10;
154 		sdn.sc = 0;
155 		if (p_after)
156 			*p_after = str + strlen(NAME_PICA);
157 
158 	} else if (is_cpi && STREQU(str, NAME_ELITE)) {
159 		sdn.val = 12;
160 		sdn.sc = 0;
161 		if (p_after)
162 			*p_after = str + strlen(NAME_ELITE);
163 
164 	} else if (is_cpi && STREQU(str, NAME_COMPRESSED)) {
165 		sdn.val = N_COMPRESSED;
166 		sdn.sc = 0;
167 		if (p_after)
168 			*p_after = str + strlen(NAME_COMPRESSED);
169 
170 	} else {
171 		sdn.val = strtod(str, &rest);
172 		if (sdn.val <= 0) {
173 			lp_errno = LP_EBADSDN;
174 			errno = EINVAL;
175 			return (sdn);
176 		}
177 
178 		while (*rest && *rest == ' ')
179 			rest++;
180 
181 		switch (*rest) {
182 		case 0:
183 			sdn.sc = 0;
184 			if (p_after)
185 				*p_after = rest;
186 			break;
187 		case 'i':
188 		case 'c':
189 			sdn.sc = *rest++;
190 			if (p_after)
191 				*p_after = rest;
192 			break;
193 		default:
194 			lp_errno = LP_EBADSDN;
195 			errno = EINVAL;
196 			sdn.sc = 0;
197 			break;
198 		}
199 	}
200 
201 	return (sdn);
202 }
203