📄 _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 + -