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