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 /* Copyright (c) 1988 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright (c) 1997, by Sun Microsystems, Inc. 28 * All rights reserved. 29 */ 30 31 /*LINTLIBRARY*/ 32 33 #include <sys/types.h> 34 #include <stdlib.h> 35 #include "utility.h" 36 37 /* 38 * TYPE_NUMERIC standard type 39 * 40 * usage: 41 * set_field_type(f, TYPE_NUMERIC, precision, vmin, vmax); 42 * 43 * int precision; digits to right of decimal point 44 * double vmin; minimum acceptable value 45 * double vmax; maximum acceptable value 46 */ 47 static char *make_num(va_list *); 48 static char *copy_num(char *); 49 static void free_num(char *); 50 static int fcheck_num(FIELD *, char *); 51 static int ccheck_num(int, char *); 52 53 typedef struct { 54 55 int prec; 56 double vmin; 57 double vmax; 58 } NUMERIC; 59 60 static FIELDTYPE typeNUMERIC = 61 { 62 ARGS, /* status */ 63 1, /* ref */ 64 (FIELDTYPE *) 0, /* left */ 65 (FIELDTYPE *) 0, /* right */ 66 make_num, /* makearg */ 67 copy_num, /* copyarg */ 68 free_num, /* freearg */ 69 fcheck_num, /* fcheck */ 70 ccheck_num, /* ccheck */ 71 (PTF_int) 0, /* next */ 72 (PTF_int) 0, /* prev */ 73 }; 74 75 FIELDTYPE * TYPE_NUMERIC = &typeNUMERIC; 76 77 static char * 78 make_num(va_list *ap) 79 { 80 NUMERIC * n; 81 82 if (Alloc(n, NUMERIC)) { 83 n -> prec = va_arg(*ap, int); 84 n -> vmin = va_arg(*ap, double); 85 n -> vmax = va_arg(*ap, double); 86 } 87 return ((char *) n); 88 } 89 90 static char * 91 copy_num(char *arg) 92 { 93 NUMERIC *n; 94 95 if (Alloc(n, NUMERIC)) 96 *n = *((NUMERIC *) arg); 97 return ((char *) n); 98 } 99 100 static void 101 free_num(char *arg) 102 { 103 Free(arg); 104 } 105 106 static int 107 fcheck_num(FIELD *f, char *arg) 108 { 109 NUMERIC * n = (NUMERIC *) arg; 110 double vmin = n -> vmin; 111 double vmax = n -> vmax; 112 int prec = n -> prec; 113 char * x = field_buffer(f, 0); 114 char buf[80]; 115 116 while (*x && *x == ' ') 117 ++x; 118 if (*x) { 119 char * t = x; 120 121 if (*x == '-') 122 ++x; 123 while (*x && isdigit(*x)) 124 ++x; 125 if (*x == '.') { 126 ++x; 127 while (*x && isdigit(*x)) 128 ++x; 129 } 130 while (*x && *x == ' ') 131 ++x; 132 if (! *x) { 133 double v = atof(t); 134 135 if (vmin >= vmax || (v >= vmin && v <= vmax)) { 136 (void) sprintf(buf, "%.*f", prec, v); 137 (void) set_field_buffer(f, 0, buf); 138 return (TRUE); 139 } 140 } 141 } 142 return (FALSE); 143 } 144 145 #define charok(c) (isdigit(c) || c == '-' || c == '.') 146 147 /*ARGSUSED*/ 148 149 static int 150 ccheck_num(int c, char *arg) 151 { 152 return (charok(c)); 153 } 154