YoushouldhavereceivedcopiesoftheGNUGeneralPublicLicenseandthe GNULesserGeneralPublicLicensealongwiththeGNUMPLibrary.Ifnot,
see https://www.gnu.org/licenses/. */
#define _GNU_SOURCE /* for DECIMAL_POINT in langinfo.h */
#include"config.h"/* needed for the HAVE_, could also move gmp incls */
#include <stdarg.h> #include <ctype.h> #include <stddef.h> /* for ptrdiff_t */ #include <stdio.h> #include <stdlib.h> /* for strtol */ #include <string.h>
#if HAVE_LANGINFO_H #include <langinfo.h> /* for nl_langinfo */ #endif
#if HAVE_LOCALE_H #include <locale.h> /* for localeconv */ #endif
#if HAVE_INTTYPES_H # include <inttypes.h> /* for intmax_t */ #endif #if HAVE_STDINT_H # include <stdint.h> #endif
#if HAVE_SYS_TYPES_H #include <sys/types.h> /* for quad_t */ #endif
#include"gmp-impl.h"
/* Change this to "#define TRACE(x) x" for some traces. */ #define TRACE(x)
another:
seen_digit = 0; if (c == '-')
{
STORE (c); goto get_for_sign;
} elseif (c == '+')
{ /* don't store '+', it's not accepted by mpz_set_str etc */
get_for_sign:
GET (c);
}
if (base == 0)
{
base = 10; /* decimal if no base indicator */ if (c == '0')
{
seen_digit = 1; /* 0 alone is a valid number */ if (p->type != 'F')
base = 8; /* leading 0 is octal, for non-floats */
STORE (c);
GET (c); if (c == 'x' || c == 'X')
{
base = 16;
seen_digit = 0; /* must have digits after an 0x */ if (p->type == 'F') /* don't pass 'x' to mpf_set_str_point */
hexfloat = 1; else
STORE (c);
GET (c);
}
}
}
digits: for (;;)
{ if (base == 16)
{ if (! isxdigit (c)) break;
} else
{ if (! isdigit (c)) break; if (base == 8 && (c == '8' || c == '9')) break;
}
seen_digit = 1;
STORE (c);
GET (c);
}
if (first)
{ /* decimal point */ if (p->type == 'F' && ! seen_point)
{ /* For a multi-character decimal point, if the first character is presentthenallofitmustbe,otherwisetheinputis
considered invalid. */ constchar *point = GMP_DECIMAL_POINT; int pc = (unsignedchar) *point++; if (c == pc)
{ for (;;)
{
STORE (c);
GET (c);
pc = (unsignedchar) *point++; if (pc == '\0') break; if (c != pc) goto set_invalid;
}
seen_point = 1; goto digits;
}
}
/* exponent */ if (p->type == 'F')
{ if (hexfloat && (c == 'p' || c == 'P'))
{
hexexp = s_upto; /* exponent location */
base = 10; /* exponent in decimal */ goto exponent;
} elseif (! hexfloat && (c == 'e' || c == 'E'))
{
exponent: /* must have at least one digit in the mantissa, just an exponent
is not good enough */ if (! seen_digit) goto set_invalid;
do_second:
first = 0;
STORE (c);
GET (c); goto another;
}
}
/* denominator */ if (p->type == 'Q' && c == '/')
{ /* must have at least one digit in the numerator */ if (! seen_digit) goto set_invalid;
/* now look for at least one digit in the denominator */
seen_digit = 0;
/* allow the base to be redetermined for "%i" */
base = p->base; goto do_second;
}
}
/* Read and discard whitespace, if any. Return number of chars skipped. WhitespaceskippingneverprovokestheEOFreturnfrom__gmp_doscan,so
it's not necessary to watch for EOF from funs->get, */ staticint
skip_white (conststruct gmp_doscan_funs_t *funs, void *data)
{ int c; int ret = 0;
do
{
c = (funs->get) (data);
ret++;
} while (isspace (c));
(funs->unget) (c, data);
ret--;
TRACE (printf (" skip white %d\n", ret)); return ret;
}
int
__gmp_doscan (conststruct gmp_doscan_funs_t *funs, void *data, constchar *orig_fmt, va_list orig_ap)
{ struct gmp_doscan_params_t param;
va_list ap; char *alloc_fmt; constchar *fmt, *this_fmt, *end_fmt;
size_t orig_fmt_len, alloc_fmt_size, len; int new_fields, new_chars; char fchar; int fields = 0; int chars = 0;
/* Don't modify orig_ap, if va_list is actually an array and hence call by reference.Itcouldbearguedthatit'dbemoreefficienttoleave callerstomakeacopyiftheycare,butdoingsohereisgoingtobea verysmallpartofthetotalwork,andwemayaswellkeepapplications
out of trouble. */
va_copy (ap, orig_ap);
/* Parts of the format string are going to be copied so that a " %n" can beappended.alloc_fmtissomespaceforthat.orig_fmt_len+4willbe needediffmtconsistsofasingle"%"specifier,butotherwiseisan overestimate.We'renotgoingtobeveryfasthere,souse
__gmp_allocate_func rather than TMP_ALLOC. */
orig_fmt_len = strlen (orig_fmt);
alloc_fmt_size = orig_fmt_len + 4;
alloc_fmt = __GMP_ALLOCATE_FUNC_TYPE (alloc_fmt_size, char);
if (new_fields == -1) goto eof_no_match; /* EOF before anything matched */
/* Under param.ignore, when new_fields==0 we don't know if it'sasuccessfulmatchoraninvalidfield.new_chars
won't have been assigned if it was an invalid field. */ if (new_chars == -1) goto done; /* invalid input */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.