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