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