subr_scanf.c (52128) | subr_scanf.c (52757) |
---|---|
1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * | 1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * |
36 * $FreeBSD: head/sys/kern/subr_scanf.c 52128 1999-10-11 15:19:12Z peter $ | 36 * $FreeBSD: head/sys/kern/subr_scanf.c 52757 1999-11-01 15:04:04Z phk $ |
37 * From: Id: vfscanf.c,v 1.13 1998/09/25 12:20:27 obrien Exp | 37 * From: Id: vfscanf.c,v 1.13 1998/09/25 12:20:27 obrien Exp |
38 * From: static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; 39 * From: static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; |
|
38 */ 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <machine/limits.h> 43 44/* 45 * Note that stdarg.h and the ANSI style va_start macro is used for both --- 739 unchanged lines hidden (view full) --- 785 if (any < 0) { 786 acc = neg ? QUAD_MIN : QUAD_MAX; 787 } else if (neg) 788 acc = -acc; 789 if (endptr != 0) 790 *endptr = (const char *)(any ? s - 1 : nptr); 791 return (acc); 792} | 40 */ 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <machine/limits.h> 45 46/* 47 * Note that stdarg.h and the ANSI style va_start macro is used for both --- 739 unchanged lines hidden (view full) --- 787 if (any < 0) { 788 acc = neg ? QUAD_MIN : QUAD_MAX; 789 } else if (neg) 790 acc = -acc; 791 if (endptr != 0) 792 *endptr = (const char *)(any ? s - 1 : nptr); 793 return (acc); 794} |
795 796/* 797 * Convert a string to a long integer. 798 * 799 * Ignores `locale' stuff. Assumes that the upper and lower case 800 * alphabets and digits are each contiguous. 801 */ 802long 803strtol(nptr, endptr, base) 804 const char *nptr; 805 const char **endptr; 806 int base; 807{ 808 const char *s = nptr; 809 unsigned long acc; 810 unsigned char c; 811 unsigned long cutoff; 812 int neg = 0, any, cutlim; 813 814 /* 815 * Skip white space and pick up leading +/- sign if any. 816 * If base is 0, allow 0x for hex and 0 for octal, else 817 * assume decimal; if base is already 16, allow 0x. 818 */ 819 do { 820 c = *s++; 821 } while (isspace(c)); 822 if (c == '-') { 823 neg = 1; 824 c = *s++; 825 } else if (c == '+') 826 c = *s++; 827 if ((base == 0 || base == 16) && 828 c == '0' && (*s == 'x' || *s == 'X')) { 829 c = s[1]; 830 s += 2; 831 base = 16; 832 } 833 if (base == 0) 834 base = c == '0' ? 8 : 10; 835 836 /* 837 * Compute the cutoff value between legal numbers and illegal 838 * numbers. That is the largest legal value, divided by the 839 * base. An input number that is greater than this value, if 840 * followed by a legal input character, is too big. One that 841 * is equal to this value may be valid or not; the limit 842 * between valid and invalid numbers is then based on the last 843 * digit. For instance, if the range for longs is 844 * [-2147483648..2147483647] and the input base is 10, 845 * cutoff will be set to 214748364 and cutlim to either 846 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated 847 * a value > 214748364, or equal but the next digit is > 7 (or 8), 848 * the number is too big, and we will return a range error. 849 * 850 * Set any if any `digits' consumed; make it negative to indicate 851 * overflow. 852 */ 853 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 854 cutlim = cutoff % (unsigned long)base; 855 cutoff /= (unsigned long)base; 856 for (acc = 0, any = 0;; c = *s++) { 857 if (!isascii(c)) 858 break; 859 if (isdigit(c)) 860 c -= '0'; 861 else if (isalpha(c)) 862 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 863 else 864 break; 865 if (c >= base) 866 break; 867 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 868 any = -1; 869 else { 870 any = 1; 871 acc *= base; 872 acc += c; 873 } 874 } 875 if (any < 0) { 876 acc = neg ? LONG_MIN : LONG_MAX; 877 } else if (neg) 878 acc = -acc; 879 if (endptr != 0) 880 *endptr = (const char *)(any ? s - 1 : nptr); 881 return (acc); 882} 883 884/* 885 * Convert a string to an unsigned long integer. 886 * 887 * Ignores `locale' stuff. Assumes that the upper and lower case 888 * alphabets and digits are each contiguous. 889 */ 890unsigned long 891strtoul(nptr, endptr, base) 892 const char *nptr; 893 const char **endptr; 894 int base; 895{ 896 const char *s = nptr; 897 unsigned long acc; 898 unsigned char c; 899 unsigned long cutoff; 900 int neg = 0, any, cutlim; 901 902 /* 903 * See strtol for comments as to the logic used. 904 */ 905 do { 906 c = *s++; 907 } while (isspace(c)); 908 if (c == '-') { 909 neg = 1; 910 c = *s++; 911 } else if (c == '+') 912 c = *s++; 913 if ((base == 0 || base == 16) && 914 c == '0' && (*s == 'x' || *s == 'X')) { 915 c = s[1]; 916 s += 2; 917 base = 16; 918 } 919 if (base == 0) 920 base = c == '0' ? 8 : 10; 921 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 922 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 923 for (acc = 0, any = 0;; c = *s++) { 924 if (!isascii(c)) 925 break; 926 if (isdigit(c)) 927 c -= '0'; 928 else if (isalpha(c)) 929 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 930 else 931 break; 932 if (c >= base) 933 break; 934 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 935 any = -1; 936 else { 937 any = 1; 938 acc *= base; 939 acc += c; 940 } 941 } 942 if (any < 0) { 943 acc = ULONG_MAX; 944 } else if (neg) 945 acc = -acc; 946 if (endptr != 0) 947 *endptr = (const char *)(any ? s - 1 : nptr); 948 return (acc); 949} |
|