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

📄 jsprf.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//*** Portable safe sprintf code.**** Author: Kipp E.B. Hickman*/#include "jsstddef.h"#include <stdarg.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include "jsprf.h"#include "jslong.h"#include "jsutil.h" /* Added by JSIFY */#include "jspubtd.h"#include "jsstr.h"/*** Note: on some platforms va_list is defined as an array,** and requires array notation.*/#ifdef HAVE_VA_COPY#define VARARGS_ASSIGN(foo, bar)        VA_COPY(foo,bar)#elif defined(HAVE_VA_LIST_AS_ARRAY)#define VARARGS_ASSIGN(foo, bar)        foo[0] = bar[0]#else#define VARARGS_ASSIGN(foo, bar)        (foo) = (bar)#endif/*** WARNING: This code may *NOT* call JS_LOG (because JS_LOG calls it)*//*** XXX This needs to be internationalized!*/typedef struct SprintfStateStr SprintfState;struct SprintfStateStr {    int (*stuff)(SprintfState *ss, const char *sp, JSUint32 len);    char *base;    char *cur;    JSUint32 maxlen;    int (*func)(void *arg, const char *sp, JSUint32 len);    void *arg;};/*** Numbered Arguement State*/struct NumArgState{    int     type;               /* type of the current ap                    */    va_list ap;                 /* point to the corresponding position on ap */};#define NAS_DEFAULT_NUM 20  /* default number of NumberedArgumentState array */#define TYPE_INT16      0#define TYPE_UINT16     1#define TYPE_INTN       2#define TYPE_UINTN      3#define TYPE_INT32      4#define TYPE_UINT32     5#define TYPE_INT64      6#define TYPE_UINT64     7#define TYPE_STRING     8#define TYPE_DOUBLE     9#define TYPE_INTSTR     10#define TYPE_WSTRING    11#define TYPE_UNKNOWN    20#define FLAG_LEFT       0x1#define FLAG_SIGNED     0x2#define FLAG_SPACED     0x4#define FLAG_ZEROS      0x8#define FLAG_NEG        0x10/*** Fill into the buffer using the data in src*/static int fill2(SprintfState *ss, const char *src, int srclen, int width,                int flags){    char space = ' ';    int rv;    width -= srclen;    if ((width > 0) && ((flags & FLAG_LEFT) == 0)) {    /* Right adjusting */        if (flags & FLAG_ZEROS) {            space = '0';        }        while (--width >= 0) {            rv = (*ss->stuff)(ss, &space, 1);            if (rv < 0) {                return rv;            }        }    }    /* Copy out the source data */    rv = (*ss->stuff)(ss, src, (JSUint32)srclen);    if (rv < 0) {        return rv;    }    if ((width > 0) && ((flags & FLAG_LEFT) != 0)) {    /* Left adjusting */        while (--width >= 0) {            rv = (*ss->stuff)(ss, &space, 1);            if (rv < 0) {                return rv;            }        }    }    return 0;}/*** Fill a number. The order is: optional-sign zero-filling conversion-digits*/static int fill_n(SprintfState *ss, const char *src, int srclen, int width,                  int prec, int type, int flags){    int zerowidth = 0;    int precwidth = 0;    int signwidth = 0;    int leftspaces = 0;    int rightspaces = 0;    int cvtwidth;    int rv;    char sign;    if ((type & 1) == 0) {        if (flags & FLAG_NEG) {            sign = '-';            signwidth = 1;        } else if (flags & FLAG_SIGNED) {            sign = '+';            signwidth = 1;        } else if (flags & FLAG_SPACED) {            sign = ' ';            signwidth = 1;        }    }    cvtwidth = signwidth + srclen;    if (prec > 0) {        if (prec > srclen) {            precwidth = prec - srclen;          /* Need zero filling */            cvtwidth += precwidth;        }    }    if ((flags & FLAG_ZEROS) && (prec < 0)) {        if (width > cvtwidth) {            zerowidth = width - cvtwidth;       /* Zero filling */            cvtwidth += zerowidth;        }    }    if (flags & FLAG_LEFT) {        if (width > cvtwidth) {            /* Space filling on the right (i.e. left adjusting) */            rightspaces = width - cvtwidth;        }    } else {        if (width > cvtwidth) {            /* Space filling on the left (i.e. right adjusting) */            leftspaces = width - cvtwidth;        }    }    while (--leftspaces >= 0) {        rv = (*ss->stuff)(ss, " ", 1);        if (rv < 0) {            return rv;        }    }    if (signwidth) {        rv = (*ss->stuff)(ss, &sign, 1);        if (rv < 0) {            return rv;        }    }    while (--precwidth >= 0) {        rv = (*ss->stuff)(ss, "0", 1);        if (rv < 0) {            return rv;        }    }    while (--zerowidth >= 0) {        rv = (*ss->stuff)(ss, "0", 1);        if (rv < 0) {            return rv;        }    }    rv = (*ss->stuff)(ss, src, (JSUint32)srclen);    if (rv < 0) {        return rv;    }    while (--rightspaces >= 0) {        rv = (*ss->stuff)(ss, " ", 1);        if (rv < 0) {            return rv;        }    }    return 0;}/*** Convert a long into its printable form*/static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix,                 int type, int flags, const char *hexp){    char cvtbuf[100];    char *cvt;    int digits;    /* according to the man page this needs to happen */    if ((prec == 0) && (num == 0)) {        return 0;    }    /*    ** Converting decimal is a little tricky. In the unsigned case we    ** need to stop when we hit 10 digits. In the signed case, we can    ** stop when the number is zero.    */    cvt = cvtbuf + sizeof(cvtbuf);    digits = 0;    while (num) {        int digit = (((unsigned long)num) % radix) & 0xF;        *--cvt = hexp[digit];        digits++;        num = (long)(((unsigned long)num) / radix);    }    if (digits == 0) {        *--cvt = '0';        digits++;    }    /*    ** Now that we have the number converted without its sign, deal with    ** the sign and zero padding.    */    return fill_n(ss, cvt, digits, width, prec, type, flags);}/*** Convert a 64-bit integer into its printable form*/static int cvt_ll(SprintfState *ss, JSInt64 num, int width, int prec, int radix,                  int type, int flags, const char *hexp){    char cvtbuf[100];    char *cvt;    int digits;    JSInt64 rad;    /* according to the man page this needs to happen */    if ((prec == 0) && (JSLL_IS_ZERO(num))) {        return 0;    }    /*    ** Converting decimal is a little tricky. In the unsigned case we    ** need to stop when we hit 10 digits. In the signed case, we can    ** stop when the number is zero.    */    JSLL_I2L(rad, radix);    cvt = cvtbuf + sizeof(cvtbuf);    digits = 0;    while (!JSLL_IS_ZERO(num)) {        JSInt32 digit;        JSInt64 quot, rem;        JSLL_UDIVMOD(&quot, &rem, num, rad);        JSLL_L2I(digit, rem);        *--cvt = hexp[digit & 0xf];        digits++;        num = quot;    }    if (digits == 0) {        *--cvt = '0';        digits++;    }    /*    ** Now that we have the number converted without its sign, deal with    ** the sign and zero padding.    */    return fill_n(ss, cvt, digits, width, prec, type, flags);}/*** Convert a double precision floating point number into its printable** form.**** XXX stop using sprintf to convert floating point*/static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1){    char fin[20];    char fout[300];    int amount = fmt1 - fmt0;    JS_ASSERT((amount > 0) && (amount < (int)sizeof(fin)));    if (amount >= (int)sizeof(fin)) {        /* Totally bogus % command to sprintf. Just ignore it */        return 0;    }    memcpy(fin, fmt0, (size_t)amount);    fin[amount] = 0;    /* Convert floating point using the native sprintf code */#ifdef DEBUG    {        const char *p = fin;        while (*p) {            JS_ASSERT(*p != 'L');            p++;        }    }#endif    sprintf(fout, fin, d);    /*    ** This assert will catch overflow's of fout, when building with    ** debugging on. At least this way we can track down the evil piece    ** of calling code and fix it!    */    JS_ASSERT(strlen(fout) < sizeof(fout));    return (*ss->stuff)(ss, fout, strlen(fout));}/*** Convert a string into its printable form.  "width" is the output** width. "prec" is the maximum number of characters of "s" to output,** where -1 means until NUL.*/static int cvt_s(SprintfState *ss, const char *s, int width, int prec,                 int flags){    int slen;    if (prec == 0)        return 0;    /* Limit string length by precision value */    slen = s ? strlen(s) : 6;    if (prec > 0) {        if (prec < slen) {            slen = prec;        }    }    /* and away we go */    return fill2(ss, s ? s : "(null)", slen, width, flags);}static int cvt_ws(SprintfState *ss, const jschar *ws, int width, int prec,                  int flags){    int result;    /*     * Supply NULL as the JSContext; errors are not reported,     * and malloc() is used to allocate the buffer buffer.     */    if (ws) {        int slen = js_strlen(ws);        char *s = js_DeflateString(NULL, ws, slen);        if (!s)            return -1; /* JSStuffFunc error indicator. */        result = cvt_s(ss, s, width, prec, flags);        free(s);    } else {        result = cvt_s(ss, NULL, width, prec, flags);    }    return result;}/*

⌨️ 快捷键说明

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