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 #ident	"%Z%%M%	%I%	%E% SMI"
23 
24 /*
25  * Copyright (c) 1996, by Sun Microsystems, Inc.
26  * All rights reserved.
27  */
28 
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <sys/types.h>
32 
33 /*
34  * More generic than get_u_long. Supports byte, short, long, longlong.
35  * Returns 0 for success, -1 for failure.
36  */
37 int
get_number(char ** src,void * dest,int len)38 get_number(char **src, void *dest, int len)
39 {
40 	register unsigned	base;
41 	register char	c;
42 
43 	if (len != 1 && (len % 2) != 0 || len > 8)
44 		return (-1);	/* not valid */
45 	/*
46 	 * Collect number up to first illegal character.  Values are specified
47 	 * as for C:  0x=hex, 0=octal, other=decimal.
48 	 */
49 	base = 10;
50 	if (**src == '0') {
51 		base = 8;
52 		(*src)++;
53 	}
54 	if (**src == 'x' || **src == 'X') {
55 		base = 16,
56 		(*src)++;
57 	}
58 
59 	while (c = **src) {
60 		if (isdigit(c)) {
61 			switch (len) {
62 			case 1:
63 				*(u_char *) dest =
64 				    (*(u_char *) dest) * base + (c - '0');
65 				break;
66 			case 2:
67 				*(u_short *) dest = (*(u_short *) dest) *
68 				    base + (c - '0');
69 				break;
70 			case 4:
71 				*(u_long *) dest = (*(u_long *) dest) *
72 				    base + (c - '0');
73 				break;
74 			case 8:
75 				*(u_longlong_t *) dest =
76 				    (*(u_longlong_t *) dest) * base +
77 				    (c - '0');
78 				break;
79 			}
80 			(*src)++;
81 			continue;
82 		}
83 		if (base == 16 && isxdigit(c)) {
84 			switch (len) {
85 			case 1:
86 				*(u_char *) dest =
87 				    ((*(u_char *) dest) << 4) + ((c & ~32) +
88 				    10 - 'A');
89 				break;
90 			case 2:
91 				*(u_short *) dest =
92 				    ((*(u_short *) dest) << 4) + ((c & ~32) +
93 				    10 - 'A');
94 				break;
95 			case 4:
96 				*(u_long *) dest =
97 				    ((*(u_long *) dest) << 4) + ((c & ~32) +
98 				    10 - 'A');
99 				break;
100 			case 8:
101 				*(u_longlong_t *) dest =
102 				    ((*(u_longlong_t *) dest) << 4) +
103 				    ((c & ~32) + 10 - 'A');
104 				break;
105 			}
106 		    (*src)++;
107 		    continue;
108 		}
109 		break;
110 	}
111 	return (0);
112 }
main()113 main()
114 {
115 	char *src;
116 	u_char one;
117 	u_short two;
118 	u_long four;
119 	u_longlong_t eight;
120 
121 	/*
122 	 * Try single octet (dec)
123 	 */
124 	src = "a56";
125 	one = 0;
126 	if (get_number(&src, (void *) &one, 1) != 0)
127 		printf("byte failed.\n");
128 	else
129 		printf("byte: %d\n", one);
130 
131 	src = "65535";
132 	two = 0;
133 	if (get_number(&src, (void *) &two, 2) != 0)
134 		printf("short failed.\n");
135 	else
136 		printf("short: %d\n", two);
137 
138 	src = "4294967296";
139 	four = 0;
140 	if (get_number(&src, (void *) &four, 4) != 0)
141 		printf("long failed.\n");
142 	else
143 		printf("long: %d\n", four);
144 
145 	src = "4289672944289672944";
146 	eight = 0;
147 	if (get_number(&src, (void *) &eight, 8) != 0)
148 		printf("longlong failed.\n");
149 	else
150 		printf("longlong: %d\n", eight);
151 
152 
153 
154 	/*
155 	 * Try single octet (hex)
156 	 */
157 	src = "0xff";
158 	one = 0;
159 	if (get_number(&src, (void *) &one, 1) != 0)
160 		printf("byte failed.\n");
161 	else
162 		printf("byte: 0x%x\n", one);
163 
164 	src = "0xffff";
165 	two = 0;
166 	if (get_number(&src, (void *) &two, 2) != 0)
167 		printf("short failed.\n");
168 	else
169 		printf("short: 0x%x\n", two);
170 
171 	src = "0xffffffff";
172 	four = 0;
173 	if (get_number(&src, (void *) &four, 4) != 0)
174 		printf("long failed.\n");
175 	else
176 		printf("long: 0x%x\n", four);
177 
178 	src = "0xffffffffffffffff";
179 	eight = 0;
180 	if (get_number(&src, (void *) &eight, 8) != 0)
181 		printf("longlong failed.\n");
182 	else
183 		printf("longlong: 0x%x\n", eight);
184 
185 	/*
186 	 * Try single octet (Oct)
187 	 */
188 	src = "0376";
189 	one = 0;
190 	if (get_number(&src, (void *) &one, 1) != 0)
191 		printf("byte failed.\n");
192 	else
193 		printf("byte: 0x%x\n", one);
194 
195 	src = "0177776";
196 	two = 0;
197 	if (get_number(&src, (void *) &two, 2) != 0)
198 		printf("short failed.\n");
199 	else
200 		printf("short: 0x%x\n", two);
201 
202 	src = "037777777776";
203 	four = 0;
204 	if (get_number(&src, (void *) &four, 4) != 0)
205 		printf("long failed.\n");
206 	else
207 		printf("long: 0x%x\n", four);
208 
209 	src = "01777777777777777777776";
210 	eight = 0;
211 	if (get_number(&src, (void *) &eight, 8) != 0)
212 		printf("longlong failed.\n");
213 	else
214 		printf("longlong: 0x%x\n", eight);
215 	return (0);
216 }
217