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
printsdn_setup(char * prefix,char * suffix,char * newline)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
printsdn_unsetup()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
printsdn(FILE * fp,SCALED sdn)77 printsdn(FILE *fp, SCALED sdn)
78 {
79 fdprintsdn(fileno(fp), sdn);
80 }
81
82
83 void
fdprintsdn(int fd,SCALED sdn)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
_getsdn(char * str,char ** p_after,int is_cpi)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