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