コード例 #1
0
/* Reading the operator name */
static int
lex_op(usenet_parser_t self, int ch)
{
    /* Watch for EOF or linefeed in the middle of the expression */
    if (ch == EOF || ch == '\n') {
        parse_error(self, "unexpected end of line");
        return -1;
    }

    /* Watch for an escape character */
    if (ch == '\\') {
        self->state = lex_op_esc;
        return 0;
    }

    /* Watch for a stray separator */
    if (ch == '/') {
        parse_error(self, "incomplete expression");
        return -1;
    }

    /* Watch for more whitespace */
    if (isspace(ch)) {
        /* Null-terminate the token */
        if (append_char(self, '\0') < 0) {
            return -1;
        }

        /* Look up the operator */
        self->operator = translate_op(self->token);
        if (self->operator == O_NONE) {
            char *buffer = malloc(strlen(OP_ERROR_MSG) + strlen(
                                      self->token) - 1);

            if (buffer != NULL) {
                sprintf(buffer, OP_ERROR_MSG, self->token);
                parse_error(self, buffer);
                free(buffer);
            }

            return -1;
        }

        /* Make sure there's agreement between the field and the operator */
        if (self->field == F_XPOSTS) {
            if (self->operator == O_MATCHES || self->operator == O_NOT) {
                parse_error(self, "illegal field/operator combination");
                return -1;
            }
        } else {
            if (self->operator == O_LT || self->operator == O_GT ||
                self->operator == O_LE || self->operator == O_GE) {
                parse_error(self, "illegal field/operator combination");
                return -1;
            }
        }

        /* Get ready to read the pattern */
        self->token_pointer = self->token;
        self->state = lex_pattern_start;
        return 0;
    }

    /* Anything else is part of the operator */
    return append_char(self, ch);
}
コード例 #2
0
ファイル: UM.C プロジェクト: sudleyplace/QLINK
/*****************************************************************************
 *
 *  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;
}