diff options
Diffstat (limited to 'usr/src/lib/efcode/engine/print.c')
-rw-r--r-- | usr/src/lib/efcode/engine/print.c | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/usr/src/lib/efcode/engine/print.c b/usr/src/lib/efcode/engine/print.c new file mode 100644 index 0000000000..0db6d6bf49 --- /dev/null +++ b/usr/src/lib/efcode/engine/print.c @@ -0,0 +1,265 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1999 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcode/private.h> + +#define DIGIT(x) (((x) > 9) ? ((x) + 'a' - 10) : ((x) + '0')) + +void +to_digit(fcode_env_t *env) +{ + CHECK_DEPTH(env, 1, ">digit"); + TOS = DIGIT(TOS); +} + +void +pic_hold(fcode_env_t *env) +{ + CHECK_DEPTH(env, 1, "hold"); + *(--env->picturebufpos) = (char) POP(DS); +} + +void +pic_start(fcode_env_t *env) +{ + env->picturebufpos = env->picturebuf + env->picturebuflen - 1; + *env->picturebufpos = 0; +} + +void +pic_ustop(fcode_env_t *env) +{ + CHECK_DEPTH(env, 1, "u#>"); + (void) POP(DS); + push_string(env, env->picturebufpos, strlen(env->picturebufpos)); +} + +void +pic_unsigned(fcode_env_t *env) +{ + ufstack_t a, b; + + CHECK_DEPTH(env, 1, "u#"); + a = (ufstack_t) TOS; + b = a % env->num_base; + TOS = (fstack_t) (a / env->num_base); + *(--env->picturebufpos) = DIGIT(b); +} + +void +pic_sign(fcode_env_t *env) +{ + fstack_t s; + + CHECK_DEPTH(env, 1, "sign"); + s = POP(DS); + if (s < 0) { + PUSH(DS, '-'); + pic_hold(env); + } +} + +static void +pic_uremainder(fcode_env_t *env) +{ + CHECK_DEPTH(env, 1, "u#s"); + do { + pic_unsigned(env); + } while (TOS); +} + +void +format_number(fcode_env_t *env, int neg, int width) +{ + pic_start(env); + if (width == 0) { + PUSH(DS, ' '); + pic_hold(env); + } + pic_uremainder(env); + if (env->num_base == 10 && neg) { + PUSH(DS, '-'); + pic_hold(env); + } + width -= strlen(env->picturebufpos); + while (width > 0) { + PUSH(DS, ' '); + pic_hold(env); + width--; + } + pic_ustop(env); +} + +static void +convert_num(fcode_env_t *env) +{ + int n; + + CHECK_DEPTH(env, 1, "(.)"); + n = 0; + if (env->num_base == 10 && TOS < 0) { + TOS = -TOS; + n = 1; + } + format_number(env, n, 0); +} + +void +do_dot_r(fcode_env_t *env) +{ + int w, n; + + CHECK_DEPTH(env, 2, ".r"); + n = 0; + w = (int) POP(DS); + if (env->num_base == 10 && TOS < 0) { + TOS = -TOS; + n = 1; + } + format_number(env, n, w); + type(env); +} + +void +do_udot_r(fcode_env_t *env) +{ + int w; + + CHECK_DEPTH(env, 2, "u.r"); + w = (int) POP(DS); + format_number(env, 0, w); + type(env); +} + +void +do_dot(fcode_env_t *env) +{ + CHECK_DEPTH(env, 1, "."); + PUSH(DS, 0); + do_dot_r(env); +} + +void +do_dot_d(fcode_env_t *env) +{ + int base; + + CHECK_DEPTH(env, 1, ".d"); + base = env->num_base; + env->num_base = 10; + do_dot(env); + env->num_base = base; +} + +void +do_dot_x(fcode_env_t *env) +{ + int base; + + CHECK_DEPTH(env, 1, ".x"); + base = env->num_base; + env->num_base = 16; + do_dot(env); + env->num_base = base; +} + +void +do_udot(fcode_env_t *env) +{ + CHECK_DEPTH(env, 1, "u."); + PUSH(DS, 0); + do_udot_r(env); +} + +void +pic_dunsigned(fcode_env_t *env) +{ + ufstack_t b; + u_dforth_t a; + + CHECK_DEPTH(env, 2, "#"); + a = pop_double(env); + b = a % env->num_base; + a /= env->num_base; + push_double(env, a); + *(--env->picturebufpos) = DIGIT(b); +} + +void +pic_dremainder(fcode_env_t *env) +{ + CHECK_DEPTH(env, 2, "#s"); + do { + pic_dunsigned(env); + } while (peek_double(env)); +} + +void +pic_dstop(fcode_env_t *env) +{ + CHECK_DEPTH(env, 2, "#>"); + (void) pop_double(env); + push_string(env, env->picturebufpos, strlen(env->picturebufpos)); +} + + +#pragma init(_init) + +static void +_init(void) +{ + fcode_env_t *env = initial_env; + ASSERT(env); + NOTICE; + + env->picturebuflen = 0x100; + env->picturebuf = MALLOC(env->picturebuflen); + + ANSI(0x095, 0, "hold", pic_hold); + ANSI(0x096, 0, "<#", pic_start); + ANSI(0x097, 0, "u#>", pic_ustop); + ANSI(0x098, 0, "sign", pic_sign); + ANSI(0x099, 0, "u#", pic_unsigned); + ANSI(0x09a, 0, "u#s", pic_uremainder); + ANSI(0x09b, 0, "u.", do_udot); + P1275(0x09c, 0, "u.r", do_udot_r); + P1275(0x09d, 0, ".", do_dot); + ANSI(0x09e, 0, ".r", do_dot_r); + + ANSI(0x0c7, 0, "#", pic_dunsigned); + ANSI(0x0c8, 0, "#s", pic_dremainder); + ANSI(0x0c9, 0, "#>", pic_dstop); + + FORTH(0, ">digit", to_digit); + FORTH(0, "(.)", convert_num); + FORTH(0, ".d", do_dot_d); + FORTH(0, ".x", do_dot_x); +} |