📄 t-scanf.c
字号:
/* Test gmp_scanf and related functions.Copyright 2001, 2002, 2003 Free Software Foundation, Inc.This file is part of the GNU MP Library.The GNU MP Library is free software; you can redistribute it and/or modifyit under the terms of the GNU Lesser General Public License as published bythe Free Software Foundation; either version 2.1 of the License, or (at youroption) any later version.The GNU MP Library is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General PublicLicense for more details.You should have received a copy of the GNU Lesser General Public Licensealong with the GNU MP Library; see the file COPYING.LIB. If not, write tothe Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,MA 02111-1307, USA. *//* Usage: t-scanf [-s] -s Check the data against the system scanf, where possible. This is only an option since we don't want to fail if the system scanf is faulty or strange. There's some fairly unattractive repetition between check_z, check_q and check_f, but enough differences to make a common loop or a set of macros seem like too much trouble. */#include "config.h"#if HAVE_STDARG#include <stdarg.h>#else#include <varargs.h>#endif#include <stddef.h> /* for ptrdiff_t */#include <stdio.h>#include <stdlib.h>#include <string.h>#if HAVE_INTTYPES_H# include <inttypes.h> /* for intmax_t */#else# if HAVE_STDINT_H# include <stdint.h># endif#endif#if HAVE_UNISTD_H#include <unistd.h> /* for unlink */#endif#include "gmp.h"#include "gmp-impl.h"#include "tests.h"#define TEMPFILE "t-scanf.tmp"int option_libc_scanf = 0;typedef int (*fun_t) _PROTO ((const char *, const char *, void *, void *));/* This problem was seen on powerpc7450-apple-darwin7.0.0, sscanf returns 0 where it should return EOF. A workaround in gmp_sscanf would be a bit tedious, and since this is a rather obvious libc bug, quite likely affecting other programs, we'll just suppress affected tests for now. */inttest_sscanf_eof_ok (void){ static int result = -1; if (result == -1) { int x; if (sscanf ("", "%d", &x) == EOF) { result = 1; } else { printf ("Warning, sscanf(\"\",\"%%d\",&x) doesn't return EOF.\n"); printf ("This affects gmp_sscanf, tests involving it will be suppressed.\n"); printf ("You should try to get a fix for your libc.\n"); result = 0; } } return result;}/* Convert fmt from a GMP scanf format string to an equivalent for a plain libc scanf, for example "%Zd" becomes "%ld". Return 1 if this succeeds, 0 if it cannot (or should not) be done. */intlibc_scanf_convert (char *fmt){ char *p = fmt; if (! option_libc_scanf) return 0; for ( ; *fmt != '\0'; fmt++) { switch (*fmt) { case 'F': case 'Q': case 'Z': /* transmute */ *p++ = 'l'; break; default: *p++ = *fmt; break; } } *p = '\0'; return 1;}long got_ftell;int fromstring_next_c;/* Call gmp_fscanf, reading the "input" string data provided. */int#if HAVE_STDARGfromstring_gmp_fscanf (const char *input, const char *fmt, ...)#elsefromstring_gmp_fscanf (va_alist) va_dcl#endif{ va_list ap; FILE *fp; int ret;#if HAVE_STDARG va_start (ap, fmt);#else const char *input; const char *fmt; va_start (ap); input = va_arg (ap, const char *); fmt = va_arg (ap, const char *);#endif fp = fopen (TEMPFILE, "w+"); ASSERT_ALWAYS (fp != NULL); ASSERT_ALWAYS (fputs (input, fp) != EOF); ASSERT_ALWAYS (fflush (fp) == 0); rewind (fp); ret = gmp_vfscanf (fp, fmt, ap); got_ftell = ftell (fp); ASSERT_ALWAYS (got_ftell != -1L); fromstring_next_c = getc (fp); ASSERT_ALWAYS (fclose (fp) == 0); va_end (ap); return ret;}intfun_gmp_sscanf (const char *input, const char *fmt, void *a1, void *a2){ if (a2 == NULL) return gmp_sscanf (input, fmt, a1); else return gmp_sscanf (input, fmt, a1, a2);}intfun_gmp_fscanf (const char *input, const char *fmt, void *a1, void *a2){ if (a2 == NULL) return fromstring_gmp_fscanf (input, fmt, a1); else return fromstring_gmp_fscanf (input, fmt, a1, a2);}intfun_fscanf (const char *input, const char *fmt, void *a1, void *a2){ FILE *fp; int ret; fp = fopen (TEMPFILE, "w+"); ASSERT_ALWAYS (fp != NULL); ASSERT_ALWAYS (fputs (input, fp) != EOF); ASSERT_ALWAYS (fflush (fp) == 0); rewind (fp); if (a2 == NULL) ret = fscanf (fp, fmt, a1); else ret = fscanf (fp, fmt, a1, a2); got_ftell = ftell (fp); ASSERT_ALWAYS (got_ftell != -1L); fromstring_next_c = getc (fp); ASSERT_ALWAYS (fclose (fp) == 0); return ret;}/* On various old systems, for instance HP-UX 9, the C library sscanf needs to be able to write into the input string. Ensure that this is possible, when gcc is putting the test data into a read-only section. Actually we ought to only need this under SSCANF_WRITABLE_INPUT from configure, but it's just as easy to do it unconditionally, and in any case this code is only executed under the -s option. */intfun_sscanf (const char *input, const char *fmt, void *a1, void *a2){ char *input_writable; size_t size; int ret; size = strlen (input) + 1; input_writable = (*__gmp_allocate_func) (size); memcpy (input_writable, input, size); if (a2 == NULL) ret = sscanf (input_writable, fmt, a1); else ret = sscanf (input_writable, fmt, a1, a2); (*__gmp_free_func) (input_writable, size); return ret;}/* whether the format string consists entirely of ignored fields */intfmt_allignore (const char *fmt){ int saw_star = 1; for ( ; *fmt != '\0'; fmt++) { switch (*fmt) { case '%': if (! saw_star) return 0; saw_star = 0; break; case '*': saw_star = 1; break; } } return 1;}voidcheck_z (void){ static const struct { const char *fmt; const char *input; const char *want; int want_ret; long want_ftell; int want_upto; int not_glibc; } data[] = { { "%Zd", "0", "0", 1, -1, -1 }, { "%Zd", "1", "1", 1, -1, -1 }, { "%Zd", "123", "123", 1, -1, -1 }, { "%Zd", "+0", "0", 1, -1, -1 }, { "%Zd", "+1", "1", 1, -1, -1 }, { "%Zd", "+123", "123", 1, -1, -1 }, { "%Zd", "-0", "0", 1, -1, -1 }, { "%Zd", "-1", "-1", 1, -1, -1 }, { "%Zd", "-123", "-123", 1, -1, -1 }, { "%Zo", "0", "0", 1, -1, -1 }, { "%Zo", "173", "123", 1, -1, -1 }, { "%Zo", "+0", "0", 1, -1, -1 }, { "%Zo", "+173", "123", 1, -1, -1 }, { "%Zo", "-0", "0", 1, -1, -1 }, { "%Zo", "-173", "-123", 1, -1, -1 }, { "%Zx", "0", "0", 1, -1, -1 }, { "%Zx", "7b", "123", 1, -1, -1 }, { "%Zx", "7b", "123", 1, -1, -1 }, { "%Zx", "+0", "0", 1, -1, -1 }, { "%Zx", "+7b", "123", 1, -1, -1 }, { "%Zx", "+7b", "123", 1, -1, -1 }, { "%Zx", "-0", "-0", 1, -1, -1 }, { "%Zx", "-7b", "-123", 1, -1, -1 }, { "%Zx", "-7b", "-123", 1, -1, -1 }, { "%ZX", "0", "0", 1, -1, -1 }, { "%ZX", "7b", "123", 1, -1, -1 }, { "%ZX", "7b", "123", 1, -1, -1 }, { "%ZX", "+0", "0", 1, -1, -1 }, { "%ZX", "+7b", "123", 1, -1, -1 }, { "%ZX", "+7b", "123", 1, -1, -1 }, { "%ZX", "-0", "-0", 1, -1, -1 }, { "%ZX", "-7b", "-123", 1, -1, -1 }, { "%ZX", "-7b", "-123", 1, -1, -1 }, { "%Zx", "0", "0", 1, -1, -1 }, { "%Zx", "7B", "123", 1, -1, -1 }, { "%Zx", "7B", "123", 1, -1, -1 }, { "%Zx", "+0", "0", 1, -1, -1 }, { "%Zx", "+7B", "123", 1, -1, -1 }, { "%Zx", "+7B", "123", 1, -1, -1 }, { "%Zx", "-0", "-0", 1, -1, -1 }, { "%Zx", "-7B", "-123", 1, -1, -1 }, { "%Zx", "-7B", "-123", 1, -1, -1 }, { "%ZX", "0", "0", 1, -1, -1 }, { "%ZX", "7B", "123", 1, -1, -1 }, { "%ZX", "7B", "123", 1, -1, -1 }, { "%ZX", "+0", "0", 1, -1, -1 }, { "%ZX", "+7B", "123", 1, -1, -1 }, { "%ZX", "+7B", "123", 1, -1, -1 }, { "%ZX", "-0", "-0", 1, -1, -1 }, { "%ZX", "-7B", "-123", 1, -1, -1 }, { "%ZX", "-7B", "-123", 1, -1, -1 }, { "%Zi", "0", "0", 1, -1, -1 }, { "%Zi", "1", "1", 1, -1, -1 }, { "%Zi", "123", "123", 1, -1, -1 }, { "%Zi", "+0", "0", 1, -1, -1 }, { "%Zi", "+1", "1", 1, -1, -1 }, { "%Zi", "+123", "123", 1, -1, -1 }, { "%Zi", "-0", "0", 1, -1, -1 }, { "%Zi", "-1", "-1", 1, -1, -1 }, { "%Zi", "-123", "-123", 1, -1, -1 }, { "%Zi", "00", "0", 1, -1, -1 }, { "%Zi", "0173", "123", 1, -1, -1 }, { "%Zi", "+00", "0", 1, -1, -1 }, { "%Zi", "+0173", "123", 1, -1, -1 }, { "%Zi", "-00", "0", 1, -1, -1 }, { "%Zi", "-0173", "-123", 1, -1, -1 }, { "%Zi", "0x0", "0", 1, -1, -1 }, { "%Zi", "0x7b", "123", 1, -1, -1 }, { "%Zi", "0x7b", "123", 1, -1, -1 }, { "%Zi", "+0x0", "0", 1, -1, -1 }, { "%Zi", "+0x7b", "123", 1, -1, -1 }, { "%Zi", "+0x7b", "123", 1, -1, -1 }, { "%Zi", "-0x0", "-0", 1, -1, -1 }, { "%Zi", "-0x7b", "-123", 1, -1, -1 }, { "%Zi", "-0x7b", "-123", 1, -1, -1 }, { "%Zi", "0X0", "0", 1, -1, -1 }, { "%Zi", "0X7b", "123", 1, -1, -1 }, { "%Zi", "0X7b", "123", 1, -1, -1 }, { "%Zi", "+0X0", "0", 1, -1, -1 }, { "%Zi", "+0X7b", "123", 1, -1, -1 }, { "%Zi", "+0X7b", "123", 1, -1, -1 }, { "%Zi", "-0X0", "-0", 1, -1, -1 }, { "%Zi", "-0X7b", "-123", 1, -1, -1 }, { "%Zi", "-0X7b", "-123", 1, -1, -1 }, { "%Zi", "0x0", "0", 1, -1, -1 }, { "%Zi", "0x7B", "123", 1, -1, -1 }, { "%Zi", "0x7B", "123", 1, -1, -1 }, { "%Zi", "+0x0", "0", 1, -1, -1 }, { "%Zi", "+0x7B", "123", 1, -1, -1 }, { "%Zi", "+0x7B", "123", 1, -1, -1 }, { "%Zi", "-0x0", "-0", 1, -1, -1 }, { "%Zi", "-0x7B", "-123", 1, -1, -1 }, { "%Zi", "-0x7B", "-123", 1, -1, -1 }, { "%Zi", "0X0", "0", 1, -1, -1 }, { "%Zi", "0X7B", "123", 1, -1, -1 }, { "%Zi", "0X7B", "123", 1, -1, -1 }, { "%Zi", "+0X0", "0", 1, -1, -1 }, { "%Zi", "+0X7B", "123", 1, -1, -1 }, { "%Zi", "+0X7B", "123", 1, -1, -1 }, { "%Zi", "-0X0", "-0", 1, -1, -1 }, { "%Zi", "-0X7B", "-123", 1, -1, -1 }, { "%Zi", "-0X7B", "-123", 1, -1, -1 }, { "%Zd", " 0", "0", 1, -1, -1 }, { "%Zd", " 0", "0", 1, -1, -1 }, { "%Zd", " 0", "0", 1, -1, -1 }, { "%Zd", "\t0", "0", 1, -1, -1 },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -