⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _str2ul.c

📁 Nucleus Common Library for Integrator using ARM Developer Suite
💻 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 + -