pete@eleazar.dartmouth.edu (Peter Robert Schmitt) (06/16/89)
I am looking for any info on the function strtol(). I can't seem to find it in the man pages on my BSD4.3. Any help appreciated. -pete schmitt Peter R. Schmitt - UNIX User Services Consultant - Peter.Schmitt@dartmouth.edu There are two fundamental facts of human enlightenment: #1, There is a God. #2, You are not Him!
chris@mimsy.UUCP (Chris Torek) (06/20/89)
In article <13949@dartvax.Dartmouth.EDU> pete@eleazar.dartmouth.edu (Peter Robert Schmitt) writes: >I am looking for any info on the function strtol(). I can't seem to >find it in the man pages on my BSD4.3. Any help appreciated. You will find neither information nor source---4BSD does (or rather, `did') not have strtol(), nor strtoul(). Here they are. These have been tested, although I cannot recall how strenuously. (As you can see by the copyright date, I wrote them last year. Why Copyright Regents of UC, rather than UM? Their license agreement already exists.) You will have to replace the `#include <limits.h>' line, e.g., with #define LONG_MIN (-2147483647L - 1) /* cannot use `-2147483648' as the type of the result is unsigned */ #define LONG_MAX 2147483647L #define ULONG_MAX ((unsigned long)4294967295) /* old BSD compiler does not have UL suffix */ although I am no longer sure as to whether the types here are correct (I seem to recall something about `removing suffixes from limits.h definitions'). In any case, strto*.c below do not depend on the types in limits.h, just the values. : Run this shell script with "sh" not "csh" PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH export PATH all=false if [ x$1 = x-a ]; then all=true fi echo Extracting strtol.c sed 's/^X//' <<'//go.sysin dd *' >strtol.c X/* X * Copyright (c) 1988 Regents of the University of California. X * All rights reserved. The Berkeley software License Agreement X * specifies the terms and conditions for redistribution. X */ X X#if defined(LIBC_SCCS) && !defined(lint) Xstatic char sccsid[] = "%W% (Berkeley) %G%"; X#endif /* LIBC_SCCS and not lint */ X X#include <limits.h> X#include <ctype.h> X#include <errno.h> X Xint errno; X X/* X * Convert a string to a long integer. X * X * Ignores `locale' stuff. Assumes that the upper and lower case X * alphabets and digits are each contiguous. X */ Xlong Xstrtol(nptr, endptr, base) X char *nptr, **endptr; X register int base; X{ X register char *s = nptr; X register unsigned long acc; X register int c; X register unsigned long cutoff; X register int neg = 0, any, cutlim; X X /* X * Skip white space and pick up leading +/- sign if any. X * If base is 0, allow 0x for hex and 0 for octal, else X * assume decimal; if base is already 16, allow 0x. X */ X do { X c = *s++; X } while (isspace(c)); X if (c == '-') { X neg = 1; X c = *s++; X } else if (c == '+') X c = *s++; X if ((base == 0 || base == 16) && X c == '0' && (*s == 'x' || *s == 'X')) { X c = s[1]; X s += 2; X base = 16; X } X if (base == 0) X base = c == '0' ? 8 : 10; X X /* X * Compute the cutoff value between legal numbers and illegal X * numbers. That is the largest legal value, divided by the X * base. An input number that is greater than this value, if X * followed by a legal input character, is too big. One that X * is equal to this value may be valid or not; the limit X * between valid and invalid numbers is then based on the last X * digit. For instance, if the range for longs is X * [-2147483648..2147483647] and the input base is 10, X * cutoff will be set to 214748364 and cutlim to either X * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated X * a value > 214748364, or equal but the next digit is > 7 (or 8), X * the number is too big, and we will return a range error. X * X * Set any if any `digits' consumed; make it negative to indicate X * overflow. X */ X cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; X cutlim = cutoff % (unsigned long)base; X cutoff /= (unsigned long)base; X for (acc = 0, any = 0;; c = *s++) { X if (isdigit(c)) X c -= '0'; X else if (isalpha(c)) X c -= isupper(c) ? 'A' - 10 : 'a' - 10; X else X break; X if (c >= base) X break; X if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) X any = -1; X else { X any = 1; X acc *= base; X acc += c; X } X } X if (any < 0) { X acc = neg ? LONG_MIN : LONG_MAX; X errno = ERANGE; X } else if (neg) X acc = -acc; X if (endptr != 0) X *endptr = any ? s - 1 : nptr; X return (acc); X} //go.sysin dd * if [ `wc -c < strtol.c` != 2648 ]; then made=false echo error transmitting strtol.c -- echo length should be 2648, not `wc -c < strtol.c` else made=true fi if $made; then chmod 644 strtol.c echo -n ' '; ls -ld strtol.c fi echo Extracting strtoul.c sed 's/^X//' <<'//go.sysin dd *' >strtoul.c X/* X * Copyright (c) 1988 Regents of the University of California. X * All rights reserved. The Berkeley software License Agreement X * specifies the terms and conditions for redistribution. X */ X X#if defined(LIBC_SCCS) && !defined(lint) Xstatic char sccsid[] = "%W% (Berkeley) %G%"; X#endif /* LIBC_SCCS and not lint */ X X#include <limits.h> X#include <ctype.h> X#include <errno.h> X Xint errno; X X/* X * Convert a string to an unsigned long integer. X * X * Ignores `locale' stuff. Assumes that the upper and lower case X * alphabets and digits are each contiguous. X */ Xunsigned long Xstrtoul(nptr, endptr, base) X char *nptr, **endptr; X register int base; X{ X register char *s = nptr; X register unsigned long acc; X register int c; X register unsigned long cutoff; X register int neg = 0, any, cutlim; X X /* X * See strtol for comments as to the logic used. X */ X do { X c = *s++; X } while (isspace(c)); X if (c == '-') { X neg = 1; X c = *s++; X } else if (c == '+') X c = *s++; X if ((base == 0 || base == 16) && X c == '0' && (*s == 'x' || *s == 'X')) { X c = s[1]; X s += 2; X base = 16; X } X if (base == 0) X base = c == '0' ? 8 : 10; X cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; X cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; X for (acc = 0, any = 0;; c = *s++) { X if (isdigit(c)) X c -= '0'; X else if (isalpha(c)) X c -= isupper(c) ? 'A' - 10 : 'a' - 10; X else X break; X if (c >= base) X break; X if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) X any = -1; X else { X any = 1; X acc *= base; X acc += c; X } X } X if (any < 0) { X acc = ULONG_MAX; X errno = ERANGE; X } else if (neg) X acc = -acc; X if (endptr != 0) X *endptr = any ? s - 1 : nptr; X return (acc); X} //go.sysin dd * if [ `wc -c < strtoul.c` != 1697 ]; then made=false echo error transmitting strtoul.c -- echo length should be 1697, not `wc -c < strtoul.c` else made=true fi if $made; then chmod 644 strtoul.c echo -n ' '; ls -ld strtoul.c fi -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (06/21/89)
In article <18164@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >X * All rights reserved. The Berkeley software License Agreement >X * specifies the terms and conditions for redistribution. Doubtful...For one thing, most people on Usenet don't even have a copy of the Berkeley software license agreement. For another, they probably never agreed to it. Finally, the very act of posting something to the net violates the Berkeley license agreement, if the one I have is any guide. It forbids distribution of software covered by it to anybody who doesn't have an AT&T source license. Perhaps the problem lies partly in calling this license agreement "*The* Berkeley software License Agreement," which implies there is only one. There is probably more than one, and we really should specify which one. (Presumably not the one in my file cabinet, -- Rahul Dhesi <dhesi@bsu-cs.bsu.edu> UUCP: ...!{iuvax,pur-ee}!bsu-cs!dhesi