⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsprf.c

📁 一个基于alice开发的机器人
💻 C
📖 第 1 页 / 共 3 页
字号:
{
    int number = 0, cn = 0, i;
    const char* p;
    char  c;
    struct NumArgState* nas;


    /*
    **  first pass:
    **  detemine how many legal % I have got, then allocate space
    */

    p = fmt;
    *rv = 0;
    i = 0;
    while( ( c = *p++ ) != 0 ){
        if( c != '%' )
            continue;
        if( ( c = *p++ ) == '%' )       /* skip %% case */
            continue;

        while( c != 0 ){
            if( c > '9' || c < '0' ){
                if( c == '$' ){         /* numbered argument csae */
                    if( i > 0 ){
                        *rv = -1;
                        return NULL;
                    }
                    number++;
                } else {                /* non-numbered argument case */
                    if( number > 0 ){
                        *rv = -1;
                        return NULL;
                    }
                    i = 1;
                }
                break;
            }

            c = *p++;
        }
    }

    if( number == 0 ){
        return NULL;
    }


    if( number > NAS_DEFAULT_NUM ){
        nas = (struct NumArgState*)malloc( number * sizeof( struct NumArgState ) );
        if( !nas ){
            *rv = -1;
            return NULL;
        }
    } else {
        nas = nasArray;
    }

    for( i = 0; i < number; i++ ){
        nas[i].type = TYPE_UNKNOWN;
    }


    /*
    ** second pass:
    ** set nas[].type
    */

    p = fmt;
    while( ( c = *p++ ) != 0 ){
        if( c != '%' )  continue;
            c = *p++;
        if( c == '%' )  continue;

        cn = 0;
        while( c && c != '$' ){     /* should imporve error check later */
            cn = cn*10 + c - '0';
            c = *p++;
        }

        if( !c || cn < 1 || cn > number ){
            *rv = -1;
            break;
        }

        /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */
        cn--;
        if( nas[cn].type != TYPE_UNKNOWN )
            continue;

        c = *p++;

        /* width */
        if (c == '*') {
            /* not supported feature, for the argument is not numbered */
            *rv = -1;
            break;
        }

        while ((c >= '0') && (c <= '9')) {
            c = *p++;
        }

        /* precision */
        if (c == '.') {
            c = *p++;
            if (c == '*') {
                /* not supported feature, for the argument is not numbered */
                *rv = -1;
                break;
            }

            while ((c >= '0') && (c <= '9')) {
                c = *p++;
            }
        }

        /* size */
        nas[cn].type = TYPE_INTN;
        if (c == 'h') {
            nas[cn].type = TYPE_INT16;
            c = *p++;
        } else if (c == 'L') {
            /* XXX not quite sure here */
            nas[cn].type = TYPE_INT64;
            c = *p++;
        } else if (c == 'l') {
            nas[cn].type = TYPE_INT32;
            c = *p++;
            if (c == 'l') {
                nas[cn].type = TYPE_INT64;
                c = *p++;
            }
        }

        /* format */
        switch (c) {
        case 'd':
        case 'c':
        case 'i':
        case 'o':
        case 'u':
        case 'x':
        case 'X':
            break;

        case 'e':
        case 'f':
        case 'g':
            nas[ cn ].type = TYPE_DOUBLE;
            break;

        case 'p':
            /* XXX should use cpp */
            if (sizeof(void *) == sizeof(JSInt32)) {
                nas[ cn ].type = TYPE_UINT32;
            } else if (sizeof(void *) == sizeof(JSInt64)) {
                nas[ cn ].type = TYPE_UINT64;
            } else if (sizeof(void *) == sizeof(JSIntn)) {
                nas[ cn ].type = TYPE_UINTN;
            } else {
                nas[ cn ].type = TYPE_UNKNOWN;
            }
            break;

        case 'C':
        case 'S':
        case 'E':
        case 'G':
            /* XXX not supported I suppose */
            JS_ASSERT(0);
            nas[ cn ].type = TYPE_UNKNOWN;
            break;

        case 's':
            nas[ cn ].type = TYPE_STRING;
            break;

        case 'n':
            nas[ cn ].type = TYPE_INTSTR;
            break;

        default:
            JS_ASSERT(0);
            nas[ cn ].type = TYPE_UNKNOWN;
            break;
        }

        /* get a legal para. */
        if( nas[ cn ].type == TYPE_UNKNOWN ){
            *rv = -1;
            break;
        }
    }


    /*
    ** third pass
    ** fill the nas[cn].ap
    */

    if( *rv < 0 ){
        if( nas != nasArray )
            JS_DELETE( nas );
        return NULL;
    }

    cn = 0;
    while( cn < number ){
        if( nas[cn].type == TYPE_UNKNOWN ){
            cn++;
            continue;
        }

        VARARGS_ASSIGN(nas[cn].ap, ap);

        switch( nas[cn].type ){
        case TYPE_INT16:
        case TYPE_UINT16:
        case TYPE_INTN:
        case TYPE_UINTN:                (void)va_arg( ap, JSIntn );             break;

        case TYPE_INT32:                (void)va_arg( ap, JSInt32 );            break;

        case TYPE_UINT32:       (void)va_arg( ap, JSUint32 );   break;

        case TYPE_INT64:        (void)va_arg( ap, JSInt64 );            break;

        case TYPE_UINT64:       (void)va_arg( ap, JSUint64 );           break;

        case TYPE_STRING:       (void)va_arg( ap, char* );              break;

        case TYPE_INTSTR:       (void)va_arg( ap, JSIntn* );            break;

        case TYPE_DOUBLE:       (void)va_arg( ap, double );             break;

        default:
            if( nas != nasArray )
                JS_DELETE( nas );
            *rv = -1;
            return NULL;
        }

        cn++;
    }


    return nas;
}

/*
** The workhorse sprintf code.
*/
static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
{
    char c;
    int flags, width, prec, radix, type;
    union {
        char ch;
        int i;
        long l;
        JSInt64 ll;
        double d;
        const char *s;
        int *ip;
    } u;
    const char *fmt0;
    static char *hex = "0123456789abcdef";
    static char *HEX = "0123456789ABCDEF";
    char *hexp;
    int rv, i;
    struct NumArgState* nas = NULL;
    struct NumArgState  nasArray[ NAS_DEFAULT_NUM ];
    char  pattern[20];
    const char* dolPt = NULL;  /* in "%4$.2f", dolPt will poiont to . */


    /*
    ** build an argument array, IF the fmt is numbered argument
    ** list style, to contain the Numbered Argument list pointers
    */

    nas = BuildArgArray( fmt, ap, &rv, nasArray );
    if( rv < 0 ){
        /* the fmt contains error Numbered Argument format, jliu@netscape.com */
        JS_ASSERT(0);
        return rv;
    }

    while ((c = *fmt++) != 0) {
        if (c != '%') {
            rv = (*ss->stuff)(ss, fmt - 1, 1);
            if (rv < 0) {
                return rv;
            }
            continue;
        }
        fmt0 = fmt - 1;

        /*
        ** Gobble up the % format string. Hopefully we have handled all
        ** of the strange cases!
        */
        flags = 0;
        c = *fmt++;
        if (c == '%') {
            /* quoting a % with %% */
            rv = (*ss->stuff)(ss, fmt - 1, 1);
            if (rv < 0) {
                return rv;
            }
            continue;
        }

        if( nas != NULL ){
            /* the fmt contains the Numbered Arguments feature */
            i = 0;
            while( c && c != '$' ){         /* should imporve error check later */
                i = ( i * 10 ) + ( c - '0' );
                c = *fmt++;
            }

            if( nas[i-1].type == TYPE_UNKNOWN ){
                if( nas && ( nas != nasArray ) )
                    JS_DELETE( nas );
                return -1;
            }

            ap = nas[i-1].ap;
            dolPt = fmt;
            c = *fmt++;
        }

        /*
         * Examine optional flags.  Note that we do not implement the
         * '#' flag of sprintf().  The ANSI C spec. of the '#' flag is
         * somewhat ambiguous and not ideal, which is perhaps why
         * the various sprintf() implementations are inconsistent
         * on this feature.
         */
        while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) {
            if (c == '-') flags |= FLAG_LEFT;
            if (c == '+') flags |= FLAG_SIGNED;
            if (c == ' ') flags |= FLAG_SPACED;
            if (c == '0') flags |= FLAG_ZEROS;
            c = *fmt++;
        }
        if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED;
        if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS;

        /* width */
        if (c == '*') {
            c = *fmt++;
            width = va_arg(ap, int);
        } else {
            width = 0;
            while ((c >= '0') && (c <= '9')) {
                width = (width * 10) + (c - '0');
                c = *fmt++;
            }
        }

        /* precision */
        prec = -1;
        if (c == '.') {
            c = *fmt++;
            if (c == '*') {
                c = *fmt++;
                prec = va_arg(ap, int);
            } else {
                prec = 0;
                while ((c >= '0') && (c <= '9')) {
                    prec = (prec * 10) + (c - '0');
                    c = *fmt++;
                }
            }
        }

        /* size */
        type = TYPE_INTN;
        if (c == 'h') {
            type = TYPE_INT16;
            c = *fmt++;
        } else if (c == 'L') {
            /* XXX not quite sure here */
            type = TYPE_INT64;
            c = *fmt++;
        } else if (c == 'l') {
            type = TYPE_INT32;
            c = *fmt++;
            if (c == 'l') {
                type = TYPE_INT64;
                c = *fmt++;
            }
        }

        /* format */
        hexp = hex;
        switch (c) {
          case 'd': case 'i':                   /* decimal/integer */
            radix = 10;
            goto fetch_and_convert;

          case 'o':                             /* octal */
            radix = 8;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -