1 /* $OpenBSD: inout.c,v 1.17 2012/11/07 11:06:14 otto Exp $ */
4 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/cdefs.h>
20 __FBSDID("$FreeBSD$");
22 #include <openssl/ssl.h>
29 #define MAX_CHARS_PER_LINE 68
34 static int src_getcharstream(struct source *);
35 static void src_ungetcharstream(struct source *);
36 static char *src_getlinestream(struct source *);
37 static int src_getcharstring(struct source *);
38 static void src_ungetcharstring(struct source *);
39 static char *src_getlinestring(struct source *);
40 static void src_freestring(struct source *);
41 static void flushwrap(FILE *);
42 static void putcharwrap(FILE *, int);
43 static void printwrap(FILE *, const char *);
44 static char *get_digit(u_long, int, u_int);
46 static struct vtable stream_vtable = {
53 static struct vtable string_vtable = {
61 src_setstream(struct source *src, FILE *stream)
64 src->u.stream = stream;
65 src->vtable = &stream_vtable;
69 src_setstring(struct source *src, char *p)
72 src->u.string.buf = (u_char *)p;
73 src->u.string.pos = 0;
74 src->vtable = &string_vtable;
78 src_getcharstream(struct source *src)
81 return (src->lastchar = getc(src->u.stream));
85 src_ungetcharstream(struct source *src)
88 ungetc(src->lastchar, src->u.stream);
92 src_getlinestream(struct source *src)
96 if (fgets(buf, BUFSIZ, src->u.stream) == NULL)
102 src_getcharstring(struct source *src)
105 src->lastchar = src->u.string.buf[src->u.string.pos];
106 if (src->lastchar == '\0')
110 return (src->lastchar);
115 src_ungetcharstring(struct source *src)
118 if (src->u.string.pos > 0) {
119 if (src->lastchar != '\0')
125 src_getlinestring(struct source *src)
131 while (i < BUFSIZ-1) {
132 ch = src_getcharstring(src);
140 return (bstrdup(buf));
144 src_freestring(struct source *src)
147 free(src->u.string.buf);
159 putcharwrap(FILE *f, int ch)
162 if (charcount >= MAX_CHARS_PER_LINE) {
166 if (lastchar != -1) {
174 printwrap(FILE *f, const char *p)
180 strlcpy(buf, p, sizeof(buf));
182 putcharwrap(f, *q++);
186 readnumber(struct source *src, u_int base)
192 bool dot = false, sign = false;
195 bn_check(BN_zero(n->number));
197 while ((ch = (*src->vtable->readchar)(src)) != EOF) {
199 if ('0' <= ch && ch <= '9')
201 else if ('A' <= ch && ch <= 'F')
203 else if (ch == '_') {
206 } else if (ch == '.') {
212 (*src->vtable->unreadchar)(src);
218 bn_check(BN_mul_word(n->number, base));
221 /* work around a bug in BN_add_word: 0 += 0 is buggy.... */
224 bn_check(BN_add_word(n->number, v));
227 scale_number(n->number, n->scale);
228 for (i = 0; i < n->scale; i++)
229 BN_div_word(n->number, base);
237 read_string(struct source *src)
240 int count, ch, i, new_sz, sz;
249 while ((ch = (*src->vtable->readchar)(src)) != EOF) {
258 if (ch == '\\' && !escape)
264 p = brealloc(p, new_sz + 1);
275 get_digit(u_long num, int digits, u_int base)
281 p[0] = num >= 10 ? num + 'A' - 10 : num + '0';
284 if (asprintf(&p, "%0*lu", digits, num) == -1)
291 printnumber(FILE *f, const struct number *b, u_int base)
293 struct number *fract_part, *int_part;
303 if (BN_is_zero(b->number))
306 int_part = new_number();
307 fract_part = new_number();
308 fract_part->scale = b->scale;
313 digits = snprintf(buf, sizeof(buf), "%u", base-1);
315 split_number(b, int_part->number, fract_part->number);
319 while (!BN_is_zero(int_part->number)) {
320 BN_ULONG rem = BN_div_word(int_part->number, base);
321 stack_pushstring(&stack, get_digit(rem, digits, base));
325 if (BN_is_negative(b->number))
327 for (i = 0; i < sz; i++) {
328 p = stack_popstring(&stack);
336 struct number *num_base;
340 num_base = new_number();
341 bn_check(BN_set_word(num_base->number, base));
343 bn_check(BN_one(&mult));
345 bn_check(BN_one(&stop));
346 scale_number(&stop, b->scale);
349 while (BN_cmp(&mult, &stop) < 0) {
356 bmul_number(fract_part, fract_part, num_base,
358 split_number(fract_part, int_part->number, NULL);
359 rem = BN_get_word(int_part->number);
360 p = get_digit(rem, digits, base);
362 normalize(int_part, fract_part->scale);
363 bn_check(BN_sub(fract_part->number, fract_part->number,
367 bn_check(BN_mul_word(&mult, base));
369 free_number(num_base);
374 free_number(int_part);
375 free_number(fract_part);
379 print_value(FILE *f, const struct value *value, const char *prefix, u_int base)
383 switch (value->type) {
385 if (value->array != NULL)
389 printnumber(f, value->u.num, base);
392 fputs(value->u.string, f);
398 print_ascii(FILE *f, const struct number *n)
403 v = BN_dup(n->number);
406 if (BN_is_negative(v))
407 BN_set_negative(v, 0);
409 numbits = BN_num_bytes(v) * 8;
410 while (numbits > 0) {
412 for (i = 0; i < 8; i++)
413 ch |= BN_is_bit_set(v, numbits-i-1) << (7 - i);