/*
 * c_argv - a custom function display info about its args
 *
 * Copyright (C) 1999-2006,2021,2023  Landon Curt Noll
 *
 * 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/03/09 20:27:37
 * File existed as early as:    1997
 *
 * chongo <was here> /\oo/\     http://www.isthe.com/chongo/
 * Share and enjoy!  :-)        http://www.isthe.com/chongo/tech/comp/calc/
 */


/*
 * ISO C requires a translation unit to contain at least one declaration,
 * so we declare a global variable whose value is based on if CUSTOM is defined.
 */
#if defined(CUSTOM)
int c_argv_allowed = 1;         /* CUSTOM defined */
#else /* CUSTOM */
int c_argv_allowed = 0;         /* CUSTOM undefined */
#endif /* CUSTOM */


#if defined(CUSTOM)

#include <stdio.h>

#include "../have_const.h"
#include "../value.h"
#include "../custom.h"

#include "../config.h"
#include "../calc.h"

#include "../have_unused.h"


#include "../banned.h"  /* include after system header <> includes */


/*
 * c_argv - a custom function display info about its args
 *
 * given:
 *      vals[i]   and arg to display information about
 *
 * returns:
 *      count
 */
/*ARGSUSED*/
VALUE
c_argv(char *UNUSED(name), int count, VALUE **vals)
{
        VALUE result;           /* what we will return */
        ZVALUE zfilelen;        /* length of a file as a ZVALUE */
        NUMBER *filelen;        /* pointer to length of a file as a NUMBER */
        char *type;             /* the name of the arg type */
        int i;

        /*
         * print info on each arg
         */
        for (i=0; i < count; ++i) {

                /*
                 * print arg number with leading tab as configured
                 */
                printf("%sarg[%d]", (conf->tab_ok ? "\t" : ""), i);

                /*
                 * print the arg type
                 */
                switch (vals[i]->v_type) {
                case V_NULL:    /* null value */
                        type = "null";
                        break;
                case V_INT:     /* normal integer */
                        type = "int";
                        break;
                case V_NUM:     /* number */
                        type = "rational_value";
                        break;
                case V_COM:     /* complex number */
                        type = "complex_value";
                        break;
                case V_ADDR:    /* address of variable value */
                        type = "address";
                        break;
                case V_STR:     /* address of string */
                        type = "string";
                        break;
                case V_MAT:     /* address of matrix structure */
                        type = "matrix";
                        break;
                case V_LIST:    /* address of list structure */
                        type = "list";
                        break;
                case V_ASSOC:   /* address of association structure */
                        type = "assoc";
                        break;
                case V_OBJ:     /* address of object structure */
                        type = "object";
                        break;
                case V_FILE:    /* opened file id */
                        type = "file";
                        break;
                case V_RAND:    /* subtractive 100 random state */
                        type = "rand_state";
                        break;
                case V_RANDOM:  /* address of Blum random state */
                        type = "random_state";
                        break;
                case V_CONFIG:  /* configuration state */
                        type = "config_state";
                        break;
                case V_HASH:    /* hash state */
                        type = "hash_state";
                        break;
                case V_BLOCK:   /* memory block */
                        type = "octet_block";
                        break;
                case V_OCTET:   /* octet (unsigned char) */
                        type = "octet";
                        break;
                default:
                        type = "unknown";
                        break;
                }
                printf("\t%-16s", type);

                /*
                 * print size and sizeof information
                 *
                 * We have to treat files in a special way
                 * because their length can be very long.
                 */
                if (vals[i]->v_type == V_FILE) {
                        /* get the file length */
                        if (getsize(vals[i]->v_file, &zfilelen) == 0) {
                                filelen = qalloc();
                                filelen->num = zfilelen;
                                qprintfd(filelen, 0L);
                                qfree(filelen);
                        } else {
                                /* getsize error */
                                printf("\tsize=unknown");
                        }
                        printf("\tsizeof=%ld\n", (long int)lsizeof(vals[i]));
                } else {
                        printf("\tsize=%ld\tsizeof=%ld\n",
                            elm_count(vals[i]), (long int)lsizeof(vals[i]));
                }
        }

        /*
         * return count
         */
        result.v_type = V_NUM;
        result.v_num = itoq(count);
        return result;
}

#endif /* CUSTOM */
