plusarg.c 4.37 KB
#include <stdio.h>
#include "acc_user.h"
#include "vcsuser.h"

#define	VCS

int getstr_plusarg_check(void)
{
    int param_err = FALSE ;
    s_tfnodeinfo string_reg ;

    if (tf_nump() != 2) {
        tf_error("illegal number of arguments") ;
        param_err = TRUE ;
    }
    else {
        if (tf_typep(1) != tf_string) {
            tf_error("<plusarg_string> parameter must be a literal string");
            param_err = TRUE ;
        }
        if (tf_typep(2) != tf_readwrite) {
            tf_error("<string_reg> parameter must be writtable") ;
            param_err = TRUE ;
        }

/* commented out because of incompatibility with vcs 2.0

        else {

            tf_nodeinfo(2, &string_reg) ;
            if (string_reg.node_type != tf_reg_node) {
                tf_error("<string_reg> must be a verilog reg") ;
                param_err = TRUE ;
            }
            if ((string_reg.node_vec_size & 0x7) != 0) {
                tf_error("<string_reg> size must be a multiple of 8 bits (byte)") ;
                param_err = TRUE ;
            }
        }

*/

    }
    if (param_err)
        tf_error("usage: $getstr$plusarg(<startarg_string>,<vararg_string_reg>)") ;

    return(!param_err) ;
}

int getstr_plusarg_call(void)
{
    int status = -1 ;
    char *startarg ;
    char *vararg ;
    s_tfexprinfo e ;
    int reg_chars, not_done, group, i, length, tmp, j ;

#ifdef VCS
    if (!getstr_plusarg_check()) {
        tf_putp(0, status) ;
        return(status) ;
    }
#endif

    startarg = (char *)tf_getp(1) ;
    if ((vararg = mc_scan_plusargs(startarg)) != NULL) {
        tf_exprinfo(2, &e) ;
        reg_chars = (e.expr_vec_size >> 3) ;
        if ((length = strlen(vararg)) > reg_chars)
            tf_warning("$getstr$plusarg: string \"%s\" too long to put into <vararg_string_reg>", vararg) ;
        else {
            bzero((char *)e.expr_value_p, e.expr_ngroups * sizeof(struct t_vecval)) ;
            if (vararg[0] != 0) {
                not_done = 1 ;
                group = 0 ;
                i = length - 1 ;
                while (group < e.expr_ngroups) {
                    tmp = 0 ;
                    j = 0 ;
                    while ((i >= 0) && j++ < 4) {
			tmp |= vararg[i] << (8*(j-1));
                        not_done = (i-- >= 0) ;
                    }
                    if (not_done) {
                        e.expr_value_p[group].avalbits = tmp ;
                    }
                    else {
                        e.expr_value_p[group].avalbits = 0 ;
                    }
                    group += 1 ;
                }
                status = 1 ;
            }
            else
                status = 0 ;
            tf_propagatep(2) ;
        }
    }
    tf_putp(0, status) ;
    return(status) ;
}

#ifndef VCS

int getnum_plusarg_size(void)
{
    return(32) ;
}

#endif

int getnum_plusarg_check(void)
{
    int param_err = FALSE ;
    s_tfnodeinfo vararg_num_reg ;

    if (tf_nump() != 2) {
        tf_error("illegal number of arguments") ;
        param_err = TRUE ;
    }
    else {
        if (tf_typep(1) != tf_string) {
            tf_error("<plusarg_string> parameter must be a literal string");
            param_err = TRUE ;
        }
        if (tf_typep(2) != tf_readwrite) {
            tf_error("<vararg_num_reg> parameter must be writtable") ;
            param_err = TRUE ;
        }

	/* Commented out because of incompatibility with vcs 2.0
        else {
            tf_nodeinfo(2, &vararg_num_reg) ;
            if (vararg_num_reg.node_type != tf_reg_node) {
                tf_error("<vararg_num_reg> must be a verilog reg") ;
                param_err = TRUE ;
            }
        }
	*/

    }
    if (param_err)
        tf_error("usage: $getnum$plusarg(<startarg_string>,<vararg_num_reg>)") ;

    return(!param_err) ;
}

int getnum_plusarg_call(void)
{
    int status = -1 ;
    char *startarg ;
    char *vararg ;
    int num ;

#ifdef VCS
    if (!getnum_plusarg_check()) {
        tf_putp(0, status) ;
        return(status) ;
    }
#endif

    startarg = (char *)tf_getp(1) ;
    if ((vararg = mc_scan_plusargs(startarg)) != NULL) {
        if (vararg[0] == 0)
            status = 0 ;
        else {
            if (sscanf(vararg, "%i", (int *)&num) == 1) {
                tf_putp(2, num) ;
                status = 1 ;
            }
            else
                status = -1 ;
        }
    }
    tf_putp(0, status) ;
    return(status) ;
}