summaryrefslogtreecommitdiff
path: root/usr/src/lib/efcode/engine/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/efcode/engine/print.c')
-rw-r--r--usr/src/lib/efcode/engine/print.c265
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);
+}