uboot里将字符串IP转化为长整型类型

来源:互联网 发布:淘宝商品分享 编辑:程序博客网 时间:2024/04/29 08:38

Uboot中如何将一个字符串IP转化为长整形数据

Ctype.c

#include <linux/ctype.h>

/*所有的ASCII码,标明每个字符码是什么类型的*/

unsigned char _ctype[] = {

_C,_C,_C,_C,_C,_C,_C,_C,                           /* 0-7 */

_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,              /* 8-15 */

_C,_C,_C,_C,_C,_C,_C,_C,                           /* 16-23 */

_C,_C,_C,_C,_C,_C,_C,_C,                           /* 24-31 */

_S|_SP,_P,_P,_P,_P,_P,_P,_P,                        /* 32-39 */

_P,_P,_P,_P,_P,_P,_P,_P,                       /* 40-47 */

_D,_D,_D,_D,_D,_D,_D,_D,                     /* 48-55 */

_D,_D,_P,_P,_P,_P,_P,_P,                    /* 56-63 */

_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */

_U,_U,_U,_U,_U,_U,_U,_U,                     /* 72-79 */

_U,_U,_U,_U,_U,_U,_U,_U,                     /* 80-87 */

_U,_U,_U,_P,_P,_P,_P,_P,                            /* 88-95 */

_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,        /* 96-103 */

_L,_L,_L,_L,_L,_L,_L,_L,                    /* 104-111 */

_L,_L,_L,_L,_L,_L,_L,_L,                    /* 112-119 */

_L,_L,_L,_P,_P,_P,_P,_C,                     /* 120-127 */

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */

_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */

_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */

_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */

_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */

_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */

_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */

Ctype.h

#ifndef _LINUX_CTYPE_H

#define _LINUX_CTYPE_H

 

/*

 *NOTE! This ctype does not handle EOF like the standard C

 *library is required to.

 */

/*每一位表示一个类型*/

#define _U        0x01          /* upper */

#define _L         0x02          /* lower */

#define _D        0x04          /* digit */

#define _C        0x08          /* cntrl */

#define _P        0x10          /* punct */

#define _S         0x20          /* white space (space/lf/tab) */

#define _X        0x40          /* hex digit */

#define _SP      0x80          /* hard space (0x20) */

//相当于汇编中的INPORT导入标号,在别处定义的数组,定义需要放在源文件里

extern unsigned char _ctype[];

//字符类的变量x转化为整形后就是对应的ASCII码值了,然后查表是什么类型的ASCII

#define __ismask(x) (_ctype[(int)(unsignedchar)(x)])

 

#define isalnum(c)   ((__ismask(c)&(_U|_L|_D)) != 0)

#define isalpha(c)     ((__ismask(c)&(_U|_L)) != 0)

#define iscntrl(c)      ((__ismask(c)&(_C)) != 0)

#define isdigit(c)       ((__ismask(c)&(_D)) != 0)

#define isgraph(c)    ((__ismask(c)&(_P|_U|_L|_D)) != 0)

#define islower(c)    ((__ismask(c)&(_L)) != 0)

#define isprint(c)      ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)

#define ispunct(c)    ((__ismask(c)&(_P)) != 0)

#define isspace(c)    ((__ismask(c)&(_S)) != 0)

#define isupper(c)    ((__ismask(c)&(_U)) != 0)

#define isxdigit(c)     ((__ismask(c)&(_D|_X)) != 0)

 

#define isascii(c) (((unsignedchar)(c))<=0x7f)

#define toascii(c) (((unsignedchar)(c))&0x7f)

 

static inline unsigned char__tolower(unsigned char c)

{

         if(isupper(c))

                   c-= 'A'-'a';

         returnc;

}

 

static inline unsigned char__toupper(unsigned char c)

{

         if(islower(c))

                   c-= 'a'-'A';

         returnc;

}

 

#define tolower(c) __tolower(c)

#define toupper(c) __toupper(c)

 

#endif

 

Vsprintf.c

unsigned long simple_strtoul(const char*cp,char **endp,unsigned int base)

{/*const 表示不修改指针指向的内容*/

/*c语言函数只能返回一个值,如果想返回多个值则可以用指针返回。当然如果这个指针如果为NULL则不返回值,这样给用户提供功能却不强迫用户一定要只用这个功能,这样的API的技巧很好*/

/*第三个变量:如果str中以0x开头则一定是16进制,如果用户输入base0而且str开头是0则为8进制,如果用户输入base0而且str开头不是0则是10进制。这些逻辑是根据用户习惯决定理念,理念决定代码逻辑*/

         unsignedlong result = 0,value;

 

         if(*cp == '0') {

                   cp++;

                   if((*cp == 'x') && isxdigit(cp[1])) {

                            base= 16; /*16进制数如:0xa*/

                            cp++;//cp指向a位置

                   }

                   if(!base) { /*8进制数如:04*/

                            base= 8;

                   }

         }

         if(!base) {

                   base= 10; /*否则是10进制,如9*/

         }

         while(isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)

             ? toupper(*cp) : *cp)-'A'+10) < base) {

                   result= result*base + value;

                   cp++;

/*每次取出一个字符,将这个字符如果是数字就转化为数字,如果是字母就同一转化为大写字母再用-'A'+10转化为10进制的值如12,13之类的*/

/*这里的精髓是while循环里value<base,首先必须是0~9~f,再者停止条件不是NULL,而是如果这个字符不是属于这个进制里的字符就退出,比如在8进制里9不算数字停止循环*/

         }

         if(endp)  // 此处if判断的作用是:用户在使用这个函数时,如果不关心endp则可以直接使用

        *endp =(char *)cp;        // null,而不必担心程序运行会出错。这种处理技巧很实用,用户可以自行决定是否使用这个函数提供的参数式返回值。

        returnresult;       }

如:

这个函数输入0xf则返回15

Net_utils.c

#include <common.h>

 

IPaddr_t string_to_ip(char *s)

{

         IPaddr_taddr;

         char*e;

         inti;

 

         if(s == NULL)

                   return(0);

 

         for(addr=0, i=0; i<4; ++i) {

                   ulongval = s ? simple_strtoul(s, &e, 10) : 0;

                   addr<<= 8;

                   addr|= (val & 0xFF);

                   if(s) {

                            s= (*e) ? e+1 : e;    //*e不是停止符'\0'

                   }

         }

 

         return(htonl(addr));

}

 

Common.h

#include <net.h>

static inline IPaddr_t getenv_IPaddr (char*var)

{

         return(string_to_ip(getenv(var)));

}

 

调用:

gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr");

 

 

 

原创粉丝点击