Deleted Added
full compact
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}