/*
 * xx_print - demo print object routines
 *
 * Copyright (C) 1999  Ernest Bowen
 *
 * Calc is open software; you can redistribute it and/or modify it under
 * the terms of the version 2.1 of the GNU Lesser General Public License
 * as published by the Free Software Foundation.
 *
 * Calc is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
 * Public License for more details.
 *
 * A copy of version 2.1 of the GNU Lesser General Public License is
 * distributed with calc under the filename COPYING-LGPL.  You should have
 * received a copy with calc; if not, write to Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * Under source code control:   1997/04/17 00:08:50
 * File existed as early as:    1997
 *
 * Share and enjoy!  :-)        http://www.isthe.com/chongo/tech/comp/calc/
 */


global listmax = 3;
global matrowmax = 3;
global matcolmax = 3;
print "globals listmax, matrowmax, matcolmax defined; all assigned value 3";
print;

global blkmax = 8;
print "global blkmax defined, assigned value 8";
print;

B = blk();
define is_octet(a) = istype(a, B[0]);

define list_print(a) {
        local i;
        print "(":;
        for (i = 0; i < size(a); i++) {
                if (i > 0)
                        print ",":;
                if (i >= listmax) {
                        print "...":;
                        break;
                }
                print a[[i]]:;
        }
        print ")":;
}

define mat_print (a) {
        local i, j;

        if (matdim(a) == 1) {
                for (i = 0; i < size(a); i++) {
                        if (i >= matrowmax) {
                                printf("  ...");
                                break;
                        }
                        printf("%8d", a[i]);
                }
                return;
        }
        if (matdim(a) > 2)
                quit "Dimension for mat_print greater than 2";

        for (i = matmin(a,1); i <= matmax(a,1); i++) {
                if (i >= matmin(a,1) + matcolmax) {
                        print "     ...";
                        break;
                }
                for (j = matmin(a,2); j <= matmax(a,2); j++) {
                        if (j >= matmin(a,2) + matrowmax) {
                                printf("   ...");
                                break;
                        }
                        printf("%8d", a[i,j]);
                }
                print;
        }
}

define octet_print(a) {
        switch(a) {
                case 8: print "BS":;
                        return;
                case 9: print "HT":;
                        return;
                case 10: print "NL":;
                        return;
                case 12: print "FF":;
                        return;
                case 13: print "CR":;
                        return;
                case 27: print "ESC":;
                        return;
        }
        if (a > 31 && a < 127)
                print char(a):;
        else
                print "Non-print":;
}


define blk_print(a) {
        local i, n;

        n = size(a);

        printf("Unnamed block with %d bytes of data\n", n);
        print "First few characters: ":;
        for (i = 0; i < n; i++) {
                if (i >= blkmax) {
                        print "...",;
                        break;
                }
                print a[i],;
        }
}


define nblk_print (a) {
        local n, i;

        n = size(a);

        printf("Block named \"%s\" with %d bytes of data\n", name(a), n);
        print "First few characters: ":;
        for (i = 0; i < n; i++) {
                if (i >= blkmax) {
                        print "...",;
                        break;
                }
                print a[i],;
        }
}


define strchar(a) {

        if (isstr(a))
                a = ord(a);

        else if (is_octet(a))
                a = a;          /* This converts octet to number */

        else if (!isint(a) || a < 0 || a > 255)
                quit "Bad argument for strchar";

        switch (a) {
                case 7: print "\\a":;
                        return;
                case 8: print "\\b":;
                        return;
                case 9: print "\\t":;
                        return;
                case 10: print "\\n":;
                        return;
                case 11: print "\\v":;
                        return;
                case 12: print "\\f":;
                        return;
                case 13: print "\\r":;
                        return;
                case 27: print "\\e":;
                        return;
                case 34: print "\\\"":;
                        return;
                case 39: print "\\\'":;
                        return;
                case 92: print "\\\\":;
                        return;
        }
        if (a > 31 && a < 127) {
                print char(a):;
                return;
        }
        print "\\":;
        if (a >= 64) print a // 64:;
        a = a % 64;
        if (a >= 8) print a // 8:;
        a = a % 8;
        print a:;
}


define file_print(a) {
        local c;

        rewind(a);
        for (;;) {
                c = fgetc(a);
                if (iserror(c))
                        quit "Failure when reading from file";
                if (isnull(c))
                        break;
                strchar(c);
        }
        print;
}


define error_print(a) {
        local n = iserror(a);

        if (n == 10001) {
                print "1/0":;
                return;
        }
        if (n == 10002) {
                print "0/0":;
                return;
        }
        print strerror(a):;
}


L = list(1,2,3,4,5);

mat M1[5] = {1,2,3,4,5};

mat M2[4,4] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

B1 = blk() = {"A", "B", "C", "D"};
B2 = blk("sample") = {77, 102, 29, 13, 126, 8, 100, 27, 0, 1};

dummy = rm("-f", "xx_print.foo");
f = fopen("xx_print.foo", "w+");

fputstr(f, "alpha\nbeta\f\"gamma\"");
fputstr(f, "\x09delta\n");
fputstr(f, "\1\2\3");
fflush(f);

print "Here is a list:";
print L;
print;

print "A one-dimensional matrix:";
print M1;
print;

print "A two-dimensional matrix:";
print M2;
print;

print "An unnamed block:";
print B1;
print;

print "A named block with some special octets:";
print B2;
print;

print "A file:";
print f;
print;

undefine mat_print;

fclose(f);
print "f closed";
print;
dummy = rm("-f", "xx_print.foo");

mat M[7] = {1, 2, 3/0, 0/0, eval(2+3), fgetc(f), 7};
print "Here is a matrix with some \"errors\" as elements":
print M;
print;

define octet_print(a) {
        local b, x;
        x = a;

        for (b = 128; b; b >>= 1)
                print (x >= b ? (x -= b, 1) : 0):;
}

print "Here is the earlier block with a new octet_print()";
print B1;
print;
