Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: nspr/pr/src/io/prscanf.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « nspr/pr/src/io/prprf.c ('k') | nspr/pr/src/io/prsocket.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: nspr/pr/src/io/prscanf.c
diff --git a/nspr/pr/src/io/prscanf.c b/nspr/pr/src/io/prscanf.c
deleted file mode 100644
index 9d75d824e8e91365655793216c1e2fe27345ab7a..0000000000000000000000000000000000000000
--- a/nspr/pr/src/io/prscanf.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Scan functions for NSPR types
- *
- * Author: Wan-Teh Chang
- *
- * Acknowledgment: The implementation is inspired by the source code
- * in P.J. Plauger's "The Standard C Library," Prentice-Hall, 1992.
- */
-
-#include <limits.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-#include "prprf.h"
-#include "prdtoa.h"
-#include "prlog.h"
-#include "prerror.h"
-
-/*
- * A function that reads a character from 'stream'.
- * Returns the character read, or EOF if end of stream is reached.
- */
-typedef int (*_PRGetCharFN)(void *stream);
-
-/*
- * A function that pushes the character 'ch' back to 'stream'.
- */
-typedef void (*_PRUngetCharFN)(void *stream, int ch);
-
-/*
- * The size specifier for the integer and floating point number
- * conversions in format control strings.
- */
-typedef enum {
- _PR_size_none, /* No size specifier is given */
- _PR_size_h, /* The 'h' specifier, suggesting "short" */
- _PR_size_l, /* The 'l' specifier, suggesting "long" */
- _PR_size_L, /* The 'L' specifier, meaning a 'long double' */
- _PR_size_ll /* The 'll' specifier, suggesting "long long" */
-} _PRSizeSpec;
-
-/*
- * The collection of data that is passed between the scan function
- * and its subordinate functions. The fields of this structure
- * serve as the input or output arguments for these functions.
- */
-typedef struct {
- _PRGetCharFN get; /* get a character from input stream */
- _PRUngetCharFN unget; /* unget (push back) a character */
- void *stream; /* argument for get and unget */
- va_list ap; /* the variable argument list */
- int nChar; /* number of characters read from 'stream' */
-
- PRBool assign; /* assign, or suppress assignment? */
- int width; /* field width */
- _PRSizeSpec sizeSpec; /* 'h', 'l', 'L', or 'll' */
-
- PRBool converted; /* is the value actually converted? */
-} ScanfState;
-
-#define GET(state) ((state)->nChar++, (state)->get((state)->stream))
-#define UNGET(state, ch) \
- ((state)->nChar--, (state)->unget((state)->stream, ch))
-
-/*
- * The following two macros, GET_IF_WITHIN_WIDTH and WITHIN_WIDTH,
- * are always used together.
- *
- * GET_IF_WITHIN_WIDTH calls the GET macro and assigns its return
- * value to 'ch' only if we have not exceeded the field width of
- * 'state'. Therefore, after GET_IF_WITHIN_WIDTH, the value of
- * 'ch' is valid only if the macro WITHIN_WIDTH evaluates to true.
- */
-
-#define GET_IF_WITHIN_WIDTH(state, ch) \
- if (--(state)->width >= 0) { \
- (ch) = GET(state); \
- }
-#define WITHIN_WIDTH(state) ((state)->width >= 0)
-
-/*
- * _pr_strtoull:
- * Convert a string to an unsigned 64-bit integer. The string
- * 'str' is assumed to be a representation of the integer in
- * base 'base'.
- *
- * Warning:
- * - Only handle base 8, 10, and 16.
- * - No overflow checking.
- */
-
-static PRUint64
-_pr_strtoull(const char *str, char **endptr, int base)
-{
- static const int BASE_MAX = 16;
- static const char digits[] = "0123456789abcdef";
- char *digitPtr;
- PRUint64 x; /* return value */
- PRInt64 base64;
- const char *cPtr;
- PRBool negative;
- const char *digitStart;
-
- PR_ASSERT(base == 0 || base == 8 || base == 10 || base == 16);
- if (base < 0 || base == 1 || base > BASE_MAX) {
- if (endptr) {
- *endptr = (char *) str;
- return LL_ZERO;
- }
- }
-
- cPtr = str;
- while (isspace(*cPtr)) {
- ++cPtr;
- }
-
- negative = PR_FALSE;
- if (*cPtr == '-') {
- negative = PR_TRUE;
- cPtr++;
- } else if (*cPtr == '+') {
- cPtr++;
- }
-
- if (base == 16) {
- if (*cPtr == '0' && (cPtr[1] == 'x' || cPtr[1] == 'X')) {
- cPtr += 2;
- }
- } else if (base == 0) {
- if (*cPtr != '0') {
- base = 10;
- } else if (cPtr[1] == 'x' || cPtr[1] == 'X') {
- base = 16;
- cPtr += 2;
- } else {
- base = 8;
- }
- }
- PR_ASSERT(base != 0);
- LL_I2L(base64, base);
- digitStart = cPtr;
-
- /* Skip leading zeros */
- while (*cPtr == '0') {
- cPtr++;
- }
-
- LL_I2L(x, 0);
- while ((digitPtr = (char*)memchr(digits, tolower(*cPtr), base)) != NULL) {
- PRUint64 d;
-
- LL_I2L(d, (digitPtr - digits));
- LL_MUL(x, x, base64);
- LL_ADD(x, x, d);
- cPtr++;
- }
-
- if (cPtr == digitStart) {
- if (endptr) {
- *endptr = (char *) str;
- }
- return LL_ZERO;
- }
-
- if (negative) {
-#ifdef HAVE_LONG_LONG
- /* The cast to a signed type is to avoid a compiler warning */
- x = -(PRInt64)x;
-#else
- LL_NEG(x, x);
-#endif
- }
-
- if (endptr) {
- *endptr = (char *) cPtr;
- }
- return x;
-}
-
-/*
- * The maximum field width (in number of characters) that is enough
- * (may be more than necessary) to represent a 64-bit integer or
- * floating point number.
- */
-#define FMAX 31
-#define DECIMAL_POINT '.'
-
-static PRStatus
-GetInt(ScanfState *state, int code)
-{
- char buf[FMAX + 1], *p;
- int ch = 0;
- static const char digits[] = "0123456789abcdefABCDEF";
- PRBool seenDigit = PR_FALSE;
- int base;
- int dlen;
-
- switch (code) {
- case 'd': case 'u':
- base = 10;
- break;
- case 'i':
- base = 0;
- break;
- case 'x': case 'X': case 'p':
- base = 16;
- break;
- case 'o':
- base = 8;
- break;
- default:
- return PR_FAILURE;
- }
- if (state->width == 0 || state->width > FMAX) {
- state->width = FMAX;
- }
- p = buf;
- GET_IF_WITHIN_WIDTH(state, ch);
- if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- }
- if (WITHIN_WIDTH(state) && ch == '0') {
- seenDigit = PR_TRUE;
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- if (WITHIN_WIDTH(state)
- && (ch == 'x' || ch == 'X')
- && (base == 0 || base == 16)) {
- base = 16;
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- } else if (base == 0) {
- base = 8;
- }
- }
- if (base == 0 || base == 10) {
- dlen = 10;
- } else if (base == 8) {
- dlen = 8;
- } else {
- PR_ASSERT(base == 16);
- dlen = 16 + 6; /* 16 digits, plus 6 in uppercase */
- }
- while (WITHIN_WIDTH(state) && memchr(digits, ch, dlen)) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- seenDigit = PR_TRUE;
- }
- if (WITHIN_WIDTH(state)) {
- UNGET(state, ch);
- }
- if (!seenDigit) {
- return PR_FAILURE;
- }
- *p = '\0';
- if (state->assign) {
- if (code == 'd' || code == 'i') {
- if (state->sizeSpec == _PR_size_ll) {
- PRInt64 llval = _pr_strtoull(buf, NULL, base);
- *va_arg(state->ap, PRInt64 *) = llval;
- } else {
- long lval = strtol(buf, NULL, base);
-
- if (state->sizeSpec == _PR_size_none) {
- *va_arg(state->ap, PRIntn *) = lval;
- } else if (state->sizeSpec == _PR_size_h) {
- *va_arg(state->ap, PRInt16 *) = (PRInt16)lval;
- } else if (state->sizeSpec == _PR_size_l) {
- *va_arg(state->ap, PRInt32 *) = lval;
- } else {
- return PR_FAILURE;
- }
- }
- } else {
- if (state->sizeSpec == _PR_size_ll) {
- PRUint64 llval = _pr_strtoull(buf, NULL, base);
- *va_arg(state->ap, PRUint64 *) = llval;
- } else {
- unsigned long lval = strtoul(buf, NULL, base);
-
- if (state->sizeSpec == _PR_size_none) {
- *va_arg(state->ap, PRUintn *) = lval;
- } else if (state->sizeSpec == _PR_size_h) {
- *va_arg(state->ap, PRUint16 *) = (PRUint16)lval;
- } else if (state->sizeSpec == _PR_size_l) {
- *va_arg(state->ap, PRUint32 *) = lval;
- } else {
- return PR_FAILURE;
- }
- }
- }
- state->converted = PR_TRUE;
- }
- return PR_SUCCESS;
-}
-
-static PRStatus
-GetFloat(ScanfState *state)
-{
- char buf[FMAX + 1], *p;
- int ch = 0;
- PRBool seenDigit = PR_FALSE;
-
- if (state->width == 0 || state->width > FMAX) {
- state->width = FMAX;
- }
- p = buf;
- GET_IF_WITHIN_WIDTH(state, ch);
- if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- }
- while (WITHIN_WIDTH(state) && isdigit(ch)) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- seenDigit = PR_TRUE;
- }
- if (WITHIN_WIDTH(state) && ch == DECIMAL_POINT) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- while (WITHIN_WIDTH(state) && isdigit(ch)) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- seenDigit = PR_TRUE;
- }
- }
-
- /*
- * This is not robust. For example, "1.2e+" would confuse
- * the code below to read 'e' and '+', only to realize that
- * it should have stopped at "1.2". But we can't push back
- * more than one character, so there is nothing I can do.
- */
-
- /* Parse exponent */
- if (WITHIN_WIDTH(state) && (ch == 'e' || ch == 'E') && seenDigit) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- }
- while (WITHIN_WIDTH(state) && isdigit(ch)) {
- *p++ = ch;
- GET_IF_WITHIN_WIDTH(state, ch);
- }
- }
- if (WITHIN_WIDTH(state)) {
- UNGET(state, ch);
- }
- if (!seenDigit) {
- return PR_FAILURE;
- }
- *p = '\0';
- if (state->assign) {
- PRFloat64 dval = PR_strtod(buf, NULL);
-
- state->converted = PR_TRUE;
- if (state->sizeSpec == _PR_size_l) {
- *va_arg(state->ap, PRFloat64 *) = dval;
- } else if (state->sizeSpec == _PR_size_L) {
-#if defined(OSF1) || defined(IRIX)
- *va_arg(state->ap, double *) = dval;
-#else
- *va_arg(state->ap, long double *) = dval;
-#endif
- } else {
- *va_arg(state->ap, float *) = (float) dval;
- }
- }
- return PR_SUCCESS;
-}
-
-/*
- * Convert, and return the end of the conversion spec.
- * Return NULL on error.
- */
-
-static const char *
-Convert(ScanfState *state, const char *fmt)
-{
- const char *cPtr;
- int ch;
- char *cArg = NULL;
-
- state->converted = PR_FALSE;
- cPtr = fmt;
- if (*cPtr != 'c' && *cPtr != 'n' && *cPtr != '[') {
- do {
- ch = GET(state);
- } while (isspace(ch));
- UNGET(state, ch);
- }
- switch (*cPtr) {
- case 'c':
- if (state->assign) {
- cArg = va_arg(state->ap, char *);
- }
- if (state->width == 0) {
- state->width = 1;
- }
- for (; state->width > 0; state->width--) {
- ch = GET(state);
- if (ch == EOF) {
- return NULL;
- } else if (state->assign) {
- *cArg++ = ch;
- }
- }
- if (state->assign) {
- state->converted = PR_TRUE;
- }
- break;
- case 'p':
- case 'd': case 'i': case 'o':
- case 'u': case 'x': case 'X':
- if (GetInt(state, *cPtr) == PR_FAILURE) {
- return NULL;
- }
- break;
- case 'e': case 'E': case 'f':
- case 'g': case 'G':
- if (GetFloat(state) == PR_FAILURE) {
- return NULL;
- }
- break;
- case 'n':
- /* do not consume any input */
- if (state->assign) {
- switch (state->sizeSpec) {
- case _PR_size_none:
- *va_arg(state->ap, PRIntn *) = state->nChar;
- break;
- case _PR_size_h:
- *va_arg(state->ap, PRInt16 *) = state->nChar;
- break;
- case _PR_size_l:
- *va_arg(state->ap, PRInt32 *) = state->nChar;
- break;
- case _PR_size_ll:
- LL_I2L(*va_arg(state->ap, PRInt64 *), state->nChar);
- break;
- default:
- PR_ASSERT(0);
- }
- }
- break;
- case 's':
- if (state->width == 0) {
- state->width = INT_MAX;
- }
- if (state->assign) {
- cArg = va_arg(state->ap, char *);
- }
- for (; state->width > 0; state->width--) {
- ch = GET(state);
- if ((ch == EOF) || isspace(ch)) {
- UNGET(state, ch);
- break;
- }
- if (state->assign) {
- *cArg++ = ch;
- }
- }
- if (state->assign) {
- *cArg = '\0';
- state->converted = PR_TRUE;
- }
- break;
- case '%':
- ch = GET(state);
- if (ch != '%') {
- UNGET(state, ch);
- return NULL;
- }
- break;
- case '[':
- {
- PRBool complement = PR_FALSE;
- const char *closeBracket;
- size_t n;
-
- if (*++cPtr == '^') {
- complement = PR_TRUE;
- cPtr++;
- }
- closeBracket = strchr(*cPtr == ']' ? cPtr + 1 : cPtr, ']');
- if (closeBracket == NULL) {
- return NULL;
- }
- n = closeBracket - cPtr;
- if (state->width == 0) {
- state->width = INT_MAX;
- }
- if (state->assign) {
- cArg = va_arg(state->ap, char *);
- }
- for (; state->width > 0; state->width--) {
- ch = GET(state);
- if ((ch == EOF)
- || (!complement && !memchr(cPtr, ch, n))
- || (complement && memchr(cPtr, ch, n))) {
- UNGET(state, ch);
- break;
- }
- if (state->assign) {
- *cArg++ = ch;
- }
- }
- if (state->assign) {
- *cArg = '\0';
- state->converted = PR_TRUE;
- }
- cPtr = closeBracket;
- }
- break;
- default:
- return NULL;
- }
- return cPtr;
-}
-
-static PRInt32
-DoScanf(ScanfState *state, const char *fmt)
-{
- PRInt32 nConverted = 0;
- const char *cPtr;
- int ch;
-
- state->nChar = 0;
- cPtr = fmt;
- while (1) {
- if (isspace(*cPtr)) {
- /* white space: skip */
- do {
- cPtr++;
- } while (isspace(*cPtr));
- do {
- ch = GET(state);
- } while (isspace(ch));
- UNGET(state, ch);
- } else if (*cPtr == '%') {
- /* format spec: convert */
- cPtr++;
- state->assign = PR_TRUE;
- if (*cPtr == '*') {
- cPtr++;
- state->assign = PR_FALSE;
- }
- for (state->width = 0; isdigit(*cPtr); cPtr++) {
- state->width = state->width * 10 + *cPtr - '0';
- }
- state->sizeSpec = _PR_size_none;
- if (*cPtr == 'h') {
- cPtr++;
- state->sizeSpec = _PR_size_h;
- } else if (*cPtr == 'l') {
- cPtr++;
- if (*cPtr == 'l') {
- cPtr++;
- state->sizeSpec = _PR_size_ll;
- } else {
- state->sizeSpec = _PR_size_l;
- }
- } else if (*cPtr == 'L') {
- cPtr++;
- state->sizeSpec = _PR_size_L;
- }
- cPtr = Convert(state, cPtr);
- if (cPtr == NULL) {
- return (nConverted > 0 ? nConverted : EOF);
- }
- if (state->converted) {
- nConverted++;
- }
- cPtr++;
- } else {
- /* others: must match */
- if (*cPtr == '\0') {
- return nConverted;
- }
- ch = GET(state);
- if (ch != *cPtr) {
- UNGET(state, ch);
- return nConverted;
- }
- cPtr++;
- }
- }
-}
-
-static int
-StringGetChar(void *stream)
-{
- char *cPtr = *((char **) stream);
-
- if (*cPtr == '\0') {
- return EOF;
- } else {
- *((char **) stream) = cPtr + 1;
- return (unsigned char) *cPtr;
- }
-}
-
-static void
-StringUngetChar(void *stream, int ch)
-{
- char *cPtr = *((char **) stream);
-
- if (ch != EOF) {
- *((char **) stream) = cPtr - 1;
- }
-}
-
-PR_IMPLEMENT(PRInt32)
-PR_sscanf(const char *buf, const char *fmt, ...)
-{
- PRInt32 rv;
- ScanfState state;
-
- state.get = &StringGetChar;
- state.unget = &StringUngetChar;
- state.stream = (void *) &buf;
- va_start(state.ap, fmt);
- rv = DoScanf(&state, fmt);
- va_end(state.ap);
- return rv;
-}
« no previous file with comments | « nspr/pr/src/io/prprf.c ('k') | nspr/pr/src/io/prsocket.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698