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 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 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 75 printsdn(FILE *fp, SCALED sdn) 76 { 77 fdprintsdn(fileno(fp), sdn); 78 } 79 80 81 void 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 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