📄 _str2ul.c
字号:
/*************************************************************************
*
* Copyright Mentor Graphics Corporation 2002
* All Rights Reserved.
*
* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS
* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS
* SUBJECT TO LICENSE TERMS.
*
*************************************************************************/
/*************************************************************************
* FILE NAME VERSION
*
* _str2ul.c Nucleus Common Library 1.1
*
* DESCRIPTION
*
* This file contains the implementation of NCL__str2ul.
*
* DATA STRUCTURES
*
* None.
*
* FUNCTIONS
*
* NCL__str2ul
*
* DEPENDENCIES
*
* ncl.h
* abbr.h
* convert.h
* string.h
* ctype.h
* nucleus.h
*
************************************************************************/
#define NU_NCL_SOURCE_FILE
#include "ncl\inc\ncl.h"
#include "ncl\inc\abbr.h" /* rcchar */
#include "ncl\inc\convert.h"
#include "ncl\inc\string.h"
#include "ncl\inc\ctype.h"
#include "plus\nucleus.h" /* MMU Support */
/* The constant string needed for the hex_XXXX macros */
const char _hexes [] = HEX_STRING;
/*************************************************************************
*
* FUNCTION
*
* NCL__str2ul
*
* DESCRIPTION
*
* This routine is used to read a single unsigned long integer value
* from a string. No whitespace or sign characters are allowed.
* An optional '0' or '0x' ('0X') prefix is allowed for octal and
* hexadecimal integers. Otherwise, the base is specified in "base"
* and is in the range 2-36. If "base" is 0, the integer is either
* octal or hexadecimal according to the prefix, or decimal if there
* is no base prefix. If 'eptr' is non-zero, '*eptr' is set to point
* to the first invalid character in the string, or 'ptr' if a valid
* integer is not found. If a valid integer is found, it is stored
* in '*value'. If 'width' is non-negative, the scanning is limited
* to only 'width' characters. Any additional characters in the
* string are ignored.
*
* INPUTS
*
* ptr Pointer to the start of the string to be
* scanned
* eptr Address of ptr which will point to 1st
* invalid char
* width Maximum # of chars to scan (-1 = unlimited)
* base Number system (binary, hex, octal, etc...)
*
* OUTPUTS
*
* value The resulting value is stored here
* (Passed by reference)
* S2L_ERROR: No valid integer was found in the string.
* S2L_VALID: A valid integer was found.
* S2L_OVERFLW: An integer was found, but it was larger than
* ULONG_MAX. The converted value is truncated
* before being stored in '*value'.
*
*************************************************************************/
int NCL__str2ul (ulong *value, rcchar *ptr, char **eptr, rint width,
int base)
{
rcchar *digits; /* points to first valid char in hexes string */
rulong val = 0L; /* current working value read from the string */
rint digval; /* value of a single digit */
rulong limit; /* an overflow limit (ULONG_MAX/base) */
rcchar *off; /* offset of a digit in the hexes string */
char valid = 0; /* if not set, there is no valid # found. */
char ovflw = 0; /* if set, the number was too large for a ulong */
NU_SUPERV_USER_VARIABLES
NU_SUPERVISOR_MODE();
/*******************************************************************
* Determine the base of the number. Determine which digits are
* valid. Handle any octal or hexadecimal prefix.
*******************************************************************/
if (*ptr == '0') /* octal or hex prefix? */
{
if (width == 0)
goto exit;
if (width > 0)
--width;
++ptr;
if (width && ((*ptr=='x')||(*ptr=='X')) && ((base==0)||(base==16)))
{
valid = 0; /* It is not a valid # yet. */
base = 16; /* hexadecimal integer */
if (width == 0)
goto exit;
if (width > 0)
--width;
++ptr;
}
else
{
valid = 1; /* 0 is a valid number */
if (base == 0)
base = 8; /* 0 is also the octal prefix */
}
}
if (base == 0)
base = 10; /* default base is 10 */
if ((base > 36) || (base < 2)) /* make sure base is valid! */
goto exit;
digits = HEX_BASE(base); /* get list of valid digits */
limit = ULONG_MAX / base; /* determine overflow limit */
/*********************************************************************
* Convert up to "width" characters (or until the end-of-string).
* If the value overflows an unsigned long, set "ovflw" to 1.
********************************************************************/
while ((*ptr != '\0') && (width != 0))
{
/* next char a valid digit? */
off = NCL_strchr (digits, NCL_toupper(*ptr));
if (off == (char*) 0)
break; /* if not, we are all done */
valid = 1; /* we have a valid integer */
digval = HEX_EVAL(off); /* determine digit's value */
if (width > 0)
--width;
++ptr;
if (val > limit)
ovflw = 1;
val *= base;
if (val > (ULONG_MAX - digval))
ovflw = 1;
val += digval;
}
/********************************************************************
* On exit, we save the converted value and the stopping address.
* We return a code indicating the status of the conversion.
********************************************************************/
exit:
if (eptr)
*eptr = (char *)ptr; /* save stopping address */
if (!valid) /* no valid integer found */
{
*value = 0L; /* return 0 value */
NU_USER_MODE();
return (S2L_ERROR); /* indicate failure */
}
*value = val; /* save the truncated value */
NU_USER_MODE();
return ((ovflw) ? S2L_OVFLW : S2L_VALID); /* overflow or success? */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -