virtual const char* what() const throw()
    {
        if ( message_.empty() )
        {
            std::ostringstream ss;
            ss << test_->name() << " [" << test_->file() << ": " << line_ << "]\n";

            switch ( type_ )
            {

            case UNKNOWN:
                ss << "\t" << what_;
                break;

            case UNARY_CHECK:
                ss << "\t" << check_ << "( " << arg( 0 ) << " ) failed\n\twith ";
                ss << arg( 0 ) << " = " << arg_value( 0 );
                ss << " < " << arg_type( 0 ) << " >\n";
                break;

            case BINARY_CHECK:
                ss << "\t" << check_ << "( " << arg( 0 ) << ", " << arg( 1 )
                   << " ) failed\n\twith:\n\t\t";

                ss << arg( 0 ) << " = " << arg_value( 0 )
                   << " < " << arg_type( 0 ) << " >\n\t\t";

                ss << arg( 1 ) << " = " << arg_value( 1 )
                   << " < " << arg_type( 1 ) << " >\n\t\t";

                break;

            case THROW_CHECK:
                ss << "\t" << check_ << "( " << arg( 0 );
                if ( arg( 1 ) ) {
                    ss << ", " << arg( 1 );
                }
                ss << " ) failed\n\t";
                if ( what_.empty() ) {
                    ss << "No exception was thrown\n";
                } else {
                    ss << "Wrong exception was thrown\n\twhat():  " << what_;
                }

            default:
                break;

            }

            std::string &msg_ = const_cast< std::string& >( message_ );
            msg_ = ss.str();

        }
        return message_.c_str();
    }
Esempio n. 2
0
int main(int argc, char *argv[])
{
  //int int_size = _INTSIZEOF(int);
  //printf("int_size = %d\n",int_size);
  arg_test(0,4);

  arg_cnt(4,1,2,3,4);
  arg_type(2, INT_TYPE, 222, STR_TYPE, "ok,hello world");

  return 0;
}
Esempio n. 3
0
/*****************************************************************************
 *
 *  Given a mangled name in "src", unmangle it if necessary, putting the
 *  result in "dest", copying at most "maxlen" characters, including
 *  trailing null.  It is assumed that dest is bigger than src, and big
 *  enough for any function name + class name.
 *
 *  Returns zero if the name is not a legal mangled name.
 *
 */
umKind  unmangle(char   *   src,
         char   *   dest,
         unsigned   maxlen,
         char   *   classP,
         char   *   nameP,
         int        doArgs)
{
    char    *   srcP;           /* for scanning src */
    char    *   dstP;           /* for scanning dest */

    char    *   mainName;       /* the main name */
    char    *   className;      /* qualifying name, if present */

    char    *   dstClass;

    unsigned    len;
    int     avail;          /* chars left in dest */

    char        cfunc;          /* it is a const function */
    char        vfunc;          /* it is a volatile function */

    char        argBuff[MAXARGSLEN];    /* for arg tables */
    char        name[MAXNOTRUNC];

    umKind      kind;
    int     thunk;

    if  (src == 0)
        return  UM_NOT_MANGLED;

    if  (*src != '@')
    {
        strcpy(dest, src);
        return  UM_NOT_MANGLED;
    }

    if  (dest)
    {
        char         *  tmpp = dest;
        char    near *  endp = (char near *)tmpp + maxlen;

        do
        {
            *tmpp++ = 0;
        }
        while   ((char near *)tmpp < endp);
    }

    outerClass = 0;

    strncpy(name, src, MAXNOTRUNC-1); name[MAXNOTRUNC-1] = 0;

    /* Setup arg buffer variables */

    argBuffNext = argBuff;
    argBuffFree = MAXARGSLEN;

    /* See if this is a pascal (up-cased) mangled name */

    for (srcP = name+1; *srcP; srcP++)
    {
        if  (*srcP >= 'a' && *srcP <= 'z')
            goto NOT_PASCAL;
    }

    /* Entire name is uppercase, assume it's been pascal-ized */

    for (srcP = name+1; *srcP; srcP++)
        *srcP = tolower(*srcP);

NOT_PASCAL:

    /* Find the second '@' or '$' separator */

    srcP = name + 1;
    if  (srcP[0] == '$' && (srcP[1] == 'b' || srcP[1] == 'o'))
        srcP += 3;

    while   (*srcP)
    {
        if  (*srcP == '@' || *srcP == '$')
            break;

        if  (*srcP == '%')
        {
            srcP = skipTemplateName(srcP);
            continue;
        }

        srcP++;
    }

    /* Can't be mangled if second '@' or '$' is missing */

    if  (*srcP == 0)
    {
        /* Special check: truncated template class name */

        if  (src[0] == '@' && src[1] == '%')
        {
            isTemplateName = 0;

            if  (!setjmp(jmpb))
            {
                if  (dest )
                    copyClassName(dest,  src+1, maxlen);
                if  (nameP)
                    copyClassName(nameP, src+1, maxlen);

                return UM_NOT_MANGLED;
            }

            /* Is this a template name? */

            if  (isTemplateName)
            {
                if  (dest )
                    strcat(dest,  "...>");
                if  (nameP)
                    strcat(nameP, "...>");

                return UM_NOT_MANGLED;
            }
        }

    NOT_MANGLED:

        if  (dest )
            strcpy(dest,  src);
        if  (nameP)
            strcpy(nameP, src);

        return UM_NOT_MANGLED;
    }

    /* See if this is a member function */

    if  (*srcP == '@')
    {
        char    *   tmpP;

        /* See if this is a nested class member */

        for (tmpP = srcP + 1; *tmpP; tmpP++)
        {
            if  (*tmpP == '@')
            {
                /* Remember last '@' separator */

                srcP = tmpP;
            }
            else if (*tmpP == '$')
            {
                break;
            }
            else if (*tmpP == '%')
            {
                /* This is a template class name */

                tmpP = skipTemplateName(tmpP);
            }
        }

        *srcP++ = 0;            /* null-terminate class name */
        className = name + 1;

        while   (isdigit(*srcP))    /* 'huge' class? */
            srcP++;

        /* Now pointing to the main name */

        mainName = srcP;

        /* find '$' separator */

        if  (srcP[0] == '$' && (srcP[1] == 'b' || srcP[1] == 'o'))
            srcP += 3;

        while   (*srcP && *srcP != '$')
            ++srcP;

        if  (*srcP == 0)
        {
            /* Must be a static member */

            kind = UM_STATIC_DM;
            goto COPYIT;
        }
    }
    else
    {
        className = 0;          /* not a member function */
        mainName = name + 1;

        if  (mainName == srcP)
        {
            /* 'main' name appears to be empty - is this a thunk? */

            if  (strncmp(srcP, "$vc1$", 5))
                goto NOT_MANGLED;

            srcP += 5;
            kind  = UM_THUNK;
            thunk = 1;

            goto COPYIT;
        }
    }

    /* null-terminate "main" name and point to encoding of type definition */

    *srcP++ = 0;

    /* Now figure out what kind of beast this is */

    if  (mainName[0] == '$')        /* check for special names */
    {
        mainName += 2;

        if  (mainName[-1] == 'b')   /* ctor, dtor, or operator */
        {
            if  (strcmp(mainName, "ctr") == 0)
                kind = UM_CONSTRUCTOR;
            else if (strcmp(mainName, "dtr") == 0)
                kind = UM_DESTRUCTOR;
            else
                kind = UM_OPERATOR;
        }
        else
            kind = UM_CONVERSION;   /* type conversion */
    }
    else
        kind = UM_MEMBER_FN;        /* "ordinary" name */

    /* Copy class and main name to caller's buffers (if applicable) */

COPYIT:

    dstClass = 0;

    if  (classP)
        copyClassName(classP, className, maxlen);

    if  ( nameP)
    {
        if  (dest == 0)
        {
            dstP   = nameP;
            doArgs = 0;
            avail  = 63;

            if  (setjmp(jmpb))
                goto trunc_exit;

            goto DONAME;
        }

        strcpy( nameP,  mainName);
    }

    if  (dest == 0)
        return  kind;

    /* Setup destination pointer, and remaining dest. buffer length */

    dstP  = dest;
    avail = maxlen - 5;     /* Leave some extra room at the end */

    /* Prepare the quick exit route */

    if  (setjmp(jmpb))
    {
trunc_exit:
        /* Make sure there's room for the "..." */

        if  (maxlen)
            dest[maxlen - 4] = 0;

        strcat(dstP, "...");
        return  kind;
    }

    /* Setup arg buffer variables */

    argBuffNext = argBuff;
    argBuffFree = MAXARGSLEN;

    /* emit qualifying name, if any */

#ifdef  IN_MOJO
    if  (className && !(doArgs & DoArgsNoClassPrefix))
#else
    if  (className)
#endif
    {
        dstClass = dstP;

        len  = copyClassName(dstP, className, avail);
        dstP   += len;
        *dstP++ = ':';
        *dstP++ = ':';
        avail   -= len + 2;
    }

    /* emit the main name */

DONAME:

    switch  (kind)
    {
    case    UM_DESTRUCTOR:
        *dstP++ = '~';

    case    UM_CONSTRUCTOR:
        if  (dstClass)
        {
            char    *   temp = dstP - 2;

            if  (temp[-1] == ':')
                temp--;

            *temp = 0;
            strcpy(dstP, lastClassName(dstClass));
            dstP += strlen(dstP);
            *temp = ':';
        }
        else
        {
            dstP += copyClassName(dstP, className, avail);
        }
        break;

    case    UM_OPERATOR:
        strcpy(dstP, "operator ");
        dstP += 9;
        strcpy(dstP, translate_op(mainName));
        break;

    case    UM_CONVERSION:
        strcpy(dstP, "operator ");
        dstP  += 9;
        avail -= 9;
        arg_type(&mainName, &dstP, &avail, 0);
        kind = UM_CONVERSION;
        break;

    case    UM_MEMBER_FN:
    case    UM_STATIC_DM:
        strcpy(dstP, mainName);
        break;

    case    UM_THUNK:
        convertThunkName(dstP, srcP, thunk);
        break;
    }

#ifdef  IN_MOJO
    if  (!(doArgs & DoArgsArguments))
        return  kind;
#else
    if  (!doArgs)
        return  kind;
#endif

    /* Point to end of destination and figure available space */

    dstP += strlen(dstP);
    avail = dest + maxlen - dstP - 1;
    if  (avail < 0)
        avail = 0;

    /* check for a const/volatile function */

    cfunc = vfunc = 0;

    for (;;)
    {
        if  (*srcP == 'x')
            cfunc = 1;
        else if (*srcP == 'w')
            vfunc = 1;
        else
            break;
        ++srcP;
    }

    /* handle argument list */

    if  (*srcP == 'q')
    {
        ++srcP;
        arg_list(&srcP, &dstP, &avail);
    }

    /* tack on const/volatile function modifier */

    if  (cfunc)
    {
        if  (avail < 6)
            goto trunc_exit;
        strcat(dstP, " const");
    }

    if  (vfunc)
    {
        if  (avail < 9)
            goto trunc_exit;
        strcat(dstP, " volatile");
    }

    return  kind;
}
Esempio n. 4
0
/*****************************************************************************
 *
 *  Process an argument list.
 */
static  void    near    arg_list(char **srcPP, char **dstPP, unsigned *availP)
{
    char    *   srcP;
    char    *   dstP;
    unsigned    avail;

    unsigned    len;            /* temp string length */
    unsigned    i;          /* counter */

    /*
        We have to save up copies of the strings for each argument
        in case any are referenced with a "Tn" code.  There can be
        at most 35 of these.  Entry n in the array is copy of the
        string for the nth arg.
    */

    unsigned    argcount;
    char    _ss *   argtypes[36];

    unsigned    argBuffFreeSave;
    char    _ss *   argBuffNextSave;

    /* Copy incoming parameters into local variables */

    srcP  = *srcPP;
    dstP  = *dstPP;
    avail = *availP;

    argcount = 0;
    argBuffFreeSave = argBuffFree;
    argBuffNextSave = argBuffNext;

    if  (avail > 0)
    {
        *dstP++ = '(';
        avail--;
        *dstP = 0;
    }

    if  (*srcP == 'v')      /* special case -- no parameters */
    {
        ++srcP;
        goto DONE;
    }

    for (;;)
    {
        argcount++;
        argtypes[argcount] = 0;
        if  (*srcP == 't')      /* repeat a previous type string */
        {
            srcP++;
            if  (isdigit(*srcP))
                i = *srcP - '0';
            else if (islower(*srcP))
                i = *srcP - 'a' + 10;
            else
                longjmp(jmpb, 1);   /* assume truncation error */

            if  (i > argcount)
                longjmp(jmpb, 1);   /* assume truncation error */

            if  (*srcP)
                srcP++;
            if  (argtypes[i])
            {
                len = strlen(argtypes[i]);
                if  (avail >= len)
                {
                    strcpy(dstP, argtypes[i]);
                    dstP  += len;
                    avail -= len;
                }
                else
                    avail = 0;
                }
            else
                longjmp(jmpb, 1);   /* assume truncation error */
        }
        else
        {
            char    *   dd;
            unsigned    len;

            dd = dstP;
            arg_type(&srcP, &dstP, &avail, 0);

            len = strlen(dd) + 1;
            if  (argBuffFree >= len)
            {
                argtypes[argcount] = argBuffNext;
                strcpy(argBuffNext, dd);
                argBuffNext += len;
                argBuffFree -= len;
            }
        }

        /* See if more arguments present */

        if  (!isalnum(*srcP))
            break;

        if  (avail > 0)
        {
            *dstP++ = ',';
            *dstP = 0;
            avail--;
        }
    }

DONE:
    if  (avail > 0)
    {
        *dstP++ = ')';
        avail--;
    }
    *dstP = 0;

    argBuffFree = argBuffFreeSave;
    argBuffNext = argBuffNextSave;

    *srcPP  = srcP;
    *dstPP  = dstP;
    *availP = avail;
}
Esempio n. 5
0
static  void    near    arg_type(char **src, char **dest, unsigned *avail, char *outer)
{
    char    *   p;
    char    *   s = *src;
    char    *   d = *dest;
    unsigned    len;
    char    *   spec_ptr = 0;

    for (;;)                /* emit type qualifiers */
    {
        switch  (*s)
        {
        case 'u':
            if  (s[1] == 'p')
                spec_ptr = " huge ";
            else if (s[1] == 'r')
                spec_ptr = " _seg ";
            else
                p = "unsigned ";
            break;

        case 'z':
            p = "";
            break;

        case 'x':
            p = "const ";
            break;

        case 'w':
            p = "volatile ";
            break;

        default:
            goto    DONE_QUALS;
        }

        s++;                /* skip qualifier char */

        if  (!spec_ptr)
        {
            len = strlen(p);
            if  (*avail >= len)
            {
                strcpy(d, p);
                d += len;
                *avail -= len;
            }
            else
                *avail = 0;
            *d = 0;
        }
    }

DONE_QUALS:

    switch  (*s)                /* check for built-in type */
    {
        case 'v': p = "void";       break;
        case 'c': p = "char";       break;
        case 'b': p = "wchar_t";    break;
        case 's': p = "short";      break;
        case 'i': p = "int";        break;
        case 'l': p = "long";       break;
        case 'f': p = "float";      break;
        case 'd': p = "double";     break;
        case 'g': p = "long double";    break;
        case 'e': p = "...";        break;
        default:
            goto    NOT_BUILT_IN;
    }
    len = strlen(p);
    if  (*avail >= len)
    {
        strcpy(d, p);
        d += len;
        *avail -= len;
    }
    else
        *avail = 0;
    s++;

    goto    DONE;

NOT_BUILT_IN:

    if  (isdigit(*s))           /* enum or class name */
    {
        class_name(&s, &len);

        if  (*avail >= len)
        {
            unsigned    len;

            len = copyClassName(d, s, *avail);
            d += len;
            *avail -= len;
        }
        else
            *avail = 0;

        s += len + 1;
    }
    else if (*s == 'p' || *s == 'r' || *s == 'm' || *s == 'n')
    {
        /* ptr or ref to type */

        short       is_func;
        short       is_ref = 0;
        unsigned    len;

        char        cfunc;      /* it is a const function */
        char        vfunc;      /* it is a volatile function */

        char    *   p;

        if  (!spec_ptr)
        {
            is_ref = (*s == 'r' || *s == 'm');
            if  (*s == 'p' || *s == 'r')
                spec_ptr = " near";
            else
                spec_ptr = " far";
        }

        /* look-ahead to see if this is a const/volatile function */

        p = ++s;
        cfunc = vfunc = 0;

        for (;;)
        {
            if  (*p == 'x')
                cfunc = 1;
            else if (*p == 'w')
                vfunc = 1;
            else
                break;
            ++p;
        }

        is_func = 0;

        if  (*p == 'q')
        {
            is_func++;      /* if not, ignore cfunc/vfunc */
            spec_ptr++;     /* omit leading blank */
            s = p;
        }

        arg_type(&s, &d, avail, spec_ptr);

        if  (is_func)
        {
            if  (cfunc && *avail > 6)
            {
                strcpy(d, " const");
                d      += 6;
                *avail -= 6;
            }

            if  (vfunc && *avail > 9)
            {
                strcpy(d, " volatile");
                d      += 9;
                *avail -= 9;
            }
        }
        else
        {
            if  (! isalnum(d[-1]))
                ++spec_ptr; /* omit leading blank */

            len = strlen(spec_ptr);
            if  (*avail > len)
            {
                strcpy(d, spec_ptr);
                d += len;
                *d++ = is_ref ? '&' : '*';
                *avail -= len + 1;
            }
        }
    }
    else if (*s == 'a')         /* array of type */
    {
        char dims[90];
        int i = 0;
        do
        {
            dims[i++] = '[';
            if  (*++s == '0')
                ++s;        /* 0 size means unpsecified */
            while(*s && *s != '$')  /* collect size, up to '$' */
                dims[i++] = *s++;
            if (*s) ++s;
                dims[i++] = ']';
        }
            while (*s == 'a');  /* collect all dimensions */
        dims[i] = '\0';
        arg_type(&s, &d, avail, 0);
        if  (*avail >= i + 2)
        {
            strcpy(d, dims);
            d += i;
            *avail -= i;
        }
        else if (*avail >= 2)
        {
            *d++ = '[';
            *d++ = ']';
            *d = '\0';
            *avail -= 2;
        }
        else
            *avail = 0;
    }
    else if (*s == 'q')         /* function type */
    {
        /*
         *  We want the return type first, but find it last.
         *  So we emit all but the return type, get the return
         *  type, then shuffle to get them in the right place.
         *
         */

        char    *   start = d;

        ++s;
        if  (*avail >= 3)
        {
            *d++ = '(';
            *avail -= 1;

            if  (outer)
            {
                if  (outerClass)
                {
                    len = copyClassName(d, outer, *avail);

                    d      += len;
                    *avail -= len;

                    if  (*avail >= 2)
                    {
                        strcpy(d, "::");
                        d      += 2;
                        *avail -= 2;
                    }
                }
                else
                {
                    unsigned    len = strlen(outer);

                    if  (*avail >= len+2)
                    {
                        strcpy(d, outer);
                        d      += len;
                        *avail -= len;
                    }
                }
            }

            *d++ = '*';
            *d++ = ')';
            *avail -= 2;
            *d = '\0';
        }
        else
            *avail = 0;
        arg_list(&s, &d, avail);
        if  (*s == '$')     /* flags the return type */
        {
            unsigned    ret_len;
            char    *   ret_type;

            ++s;
            ret_type = d;
            arg_type(&s, &d, avail, 0); /* return type */
            ret_len = strlen(ret_type);
            if  (ret_len < 64)      /* check length */
            {
                char        ret_buff[64];

                strcpy(ret_buff, ret_type);
                memmove(start + ret_len, start, ret_type-start);
                memmove(start, ret_buff, ret_len);
            }
        }
    }
    else if (*s == 'M')         /* member pointer type */
    {
        char    *   classPtr;
        unsigned    classLen;

        int     memberFn;
        char    *   outerPtr;

        /* Extract and save the position of the class name */

        classPtr = ++s;
        class_name(&classPtr, &classLen);
        s += classLen + 1;

        /* Is this a pointer to member function? */

        memberFn = 0;
        outerPtr = 0;

        if  (*s == 'q')
        {
            memberFn++;

            /* Use 'class::' for the 'outer' parameter */

            outerPtr   = classPtr;
            outerClass = 1;
        }

        /* Now decode the 'pointed-to' type */

        arg_type(&s, &d, avail, outerPtr);

        outerClass = 0;

        if  (!memberFn)
        {
            if  (*avail)
            {
                *d++ = ' ';
                *avail -= 2;
            }

            len =  copyClassName(d, classPtr, *avail);

            d      += len;
            *avail -= len;

            if  (*avail >= 3)
            {
                strcpy(d, "::*");
                d      += 3;
                *avail -= 3;
            }
        }
    }
    else if (*s)
    {
        longjmp(jmpb, 1);   /* malformed string, presumably truncated */
    }

DONE:

    *d = '\0';
    *src = s;
    *dest = d;
    return;
}
Esempio n. 6
0
static  int near    copyClassName(char *    destPtr,
                      char *    className,
                      unsigned  avail)
{
    char    near *  begOffs = (char near *)destPtr;
    char    near *  maxOffs = (char near *)destPtr + avail;

    for (; *className; className++)
    {
        if  ((char near *)destPtr >= maxOffs)
            longjmp(jmpb, 1);

        if  (*className == '@')
        {
            *destPtr++ = ':';
            *destPtr++ = ':';
        }
        else if (*className == '%')
        {
            /* Template class name */

            className++;

            /* Copy template name first */

            while   (*className != '$')
            {
                if  (*className == 0)
                    longjmp(jmpb, 1);

                *destPtr++ = *className++;
            }

            *destPtr++ = '<';

            while   (*className == '$')
            {
                int     argtp;

                isTemplateName = 1;

                className++;
                argtp = *className;
                className++;

                avail = maxOffs - (char near *)destPtr;

                if  (argtp == 't')
                {
                    /* This is a type argument */

                    arg_type(&className, &destPtr, &avail, 0);
                }
                else
                {
                    char    *    destSave;
                    unsigned    availSave;

                    /* A value argument -- skip the type */

                     destSave = destPtr;
                    availSave = avail;

                    arg_type(&className, &destPtr, &avail, 0);

                    destPtr  =  destSave;
                    avail    = availSave;

                    /* Type must be followed by '$' */

                    if  (*className != '$')
                        longjmp(jmpb, 1);
                    className++;

                    switch  (argtp)
                    {
                        char    *   classBeg;

                    case    'g':
                        *destPtr++ = '&';

                        /* Fall through ..... */

                    case    'i':
                        while   (*className != '$' &&
                             *className != '%')
                        {
                            if  ((char near *)destPtr >= maxOffs || *className == 0)
                                longjmp(jmpb, 1);

                            *destPtr++ = *className++;
                        }
                        break;

                    case    'm':
                        *destPtr++ = '&';

                        /* Find the '$' delimiter */

                        classBeg = className;
                        while   (*className != '$')
                        {
                            if  ((char near *)destPtr >= maxOffs || *className == 0)
                                longjmp(jmpb, 1);

                            className++;
                        }

                        *className = 0;

                        avail = maxOffs - (char near *)destPtr;

                        destPtr += copyClassName(destPtr, classBeg, avail);

                        *destPtr++ = ':';
                        *destPtr++ = ':';

                        className++;

                        while   (*className != '$' &&
                             *className != '%')
                        {
                            if  ((char near *)destPtr >= maxOffs || *className == 0)
                                longjmp(jmpb, 1);

                            *destPtr++ = *className++;
                        }
                        break;

                    default:
                        /* Malformed string, presumably truncated */

                        longjmp(jmpb, 1);
                    }
                }

                if  (*className == '$')
                    *destPtr++ = ',';
            }

            *destPtr++ = '>';

            if  (className[0] != '%' ||
                 className[1] != '@')
            {
                /* Assume truncation */

                break;
            }
        }
        else
            *destPtr++ = *className;
    }

    *destPtr = 0;

    return  (char near *)destPtr - begOffs;
}