xref: /illumos-gate/usr/src/cmd/lp/lib/lp/sdn.c (revision 2a8bcb4e)
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 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
31 
32 #include "stdio.h"
33 #include "string.h"
34 #include "stdlib.h"
35 
36 #include "lp.h"
37 
38 #define N_COMPRESSED	9999
39 
40 /**
41  ** printsdn() - PRINT A SCALED DECIMAL NUMBER NICELY
42  **/
43 
44 #define	DFLT_PREFIX	0
45 #define	DFLT_SUFFIX	0
46 #define	DFLT_NEWLINE	"\n"
47 
48 static char		*print_prefix	= DFLT_PREFIX,
49 			*print_suffix	= DFLT_SUFFIX,
50 			*print_newline	= DFLT_NEWLINE;
51 
52 void
printsdn_setup(char * prefix,char * suffix,char * newline)53 printsdn_setup(char *prefix, char *suffix, char *newline)
54 {
55 	if (prefix)
56 		print_prefix = prefix;
57 	if (suffix)
58 		print_suffix = suffix;
59 	if (newline)
60 		print_newline = newline;
61 	return;
62 }
63 
64 void
printsdn_unsetup()65 printsdn_unsetup ()
66 {
67 	print_prefix = DFLT_PREFIX;
68 	print_suffix = DFLT_SUFFIX;
69 	print_newline = DFLT_NEWLINE;
70 	return;
71 }
72 
73 
74 void
printsdn(FILE * fp,SCALED sdn)75 printsdn(FILE *fp, SCALED sdn)
76 {
77 	fdprintsdn(fileno(fp), sdn);
78 }
79 
80 
81 void
fdprintsdn(int fd,SCALED sdn)82 fdprintsdn(int fd, SCALED sdn)
83 {
84 	register char		*dec = "9999.999",
85 				*z;
86 
87 	if (sdn.val <= 0)
88 		return;
89 
90 	(void)fdprintf (fd, "%s", NB(print_prefix));
91 
92 	/*
93 	 * Let's try to be a bit clever in dealing with decimal
94 	 * numbers. If the number is an integer, don't print
95 	 * a decimal point. If it isn't an integer, strip trailing
96 	 * zeros from the fraction part, and don't print more
97 	 * than the thousandths place.
98 	 */
99 	if (-1000. < sdn.val && sdn.val < 10000.) {
100 
101 		/*
102 		 * Printing 0 will give us 0.000.
103 		 */
104 		sprintf (dec, "%.3f", sdn.val);
105 
106 		/*
107 		 * Skip zeroes from the end until we hit
108 		 * '.' or not-0. If we hit '.', clobber it;
109 		 * if we hit not-0, it has to be in fraction
110 		 * part, so leave it.
111 		 */
112 		z = dec + strlen(dec) - 1;
113 		while (*z == '0' && *z != '.')
114 			z--;
115 		if (*z == '.')
116 			*z = '\0';
117 		else
118 			*++z = '\0';
119 
120 		(void)fdprintf(fd, "%s", dec);
121 
122 	} else
123 		(void)fdprintf(fd, "%.3f", sdn.val);
124 
125 	if (sdn.sc == 'i' || sdn.sc == 'c')
126 		fdputc(sdn.sc, fd);
127 
128 	(void)fdprintf(fd, "%s%s", NB(print_suffix), NB(print_newline));
129 	return;
130 }
131 
132 
133 /**
134  ** _getsdn() - PARSE SCALED DECIMAL NUMBER
135  **/
136 
137 SCALED
_getsdn(char * str,char ** p_after,int is_cpi)138 _getsdn(char *str, char **p_after, int is_cpi)
139 {
140 	static SCALED		sdn	= { 0.0 , 0 };
141 
142 	char *			rest;
143 
144 
145 	/*
146 	 * A nonzero "errno" is our only method of indicating error.
147 	 */
148 	errno = 0;
149 
150 	if (is_cpi && STREQU(str, NAME_PICA)) {
151 		sdn.val = 10;
152 		sdn.sc = 0;
153 		if (p_after)
154 			*p_after = str + strlen(NAME_PICA);
155 
156 	} else if (is_cpi && STREQU(str, NAME_ELITE)) {
157 		sdn.val = 12;
158 		sdn.sc = 0;
159 		if (p_after)
160 			*p_after = str + strlen(NAME_ELITE);
161 
162 	} else if (is_cpi && STREQU(str, NAME_COMPRESSED)) {
163 		sdn.val = N_COMPRESSED;
164 		sdn.sc = 0;
165 		if (p_after)
166 			*p_after = str + strlen(NAME_COMPRESSED);
167 
168 	} else {
169 		sdn.val = strtod(str, &rest);
170 		if (sdn.val <= 0) {
171 			lp_errno = LP_EBADSDN;
172 			errno = EINVAL;
173 			return (sdn);
174 		}
175 
176 		while (*rest && *rest == ' ')
177 			rest++;
178 
179 		switch (*rest) {
180 		case 0:
181 			sdn.sc = 0;
182 			if (p_after)
183 				*p_after = rest;
184 			break;
185 		case 'i':
186 		case 'c':
187 			sdn.sc = *rest++;
188 			if (p_after)
189 				*p_after = rest;
190 			break;
191 		default:
192 			lp_errno = LP_EBADSDN;
193 			errno = EINVAL;
194 			sdn.sc = 0;
195 			break;
196 		}
197 	}
198 
199 	return (sdn);
200 }
201