Uboot中如何将一个字符串IP转化为长整形数据
Ctype.c
#include
/*所有的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进制,如果用户输入base是0而且str开头是0则为8进制,如果用户输入base是0而且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
}
if(endp) // 此处if判断的作用是:用户在使用这个函数时,如果不关心endp则可以直接使用
*endp =(char *)cp; // null,而不必担心程序运行会出错。这种处理技巧很实用,用户可以自行决定是否使用这个函数提供的参数式返回值。
returnresult; }
如:
这个函数输入0xf则返回15
Net_utils.c
#include
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
static inline IPaddr_t getenv_IPaddr (char*var)
{
return(string_to_ip(getenv(var)));
}
调用:
gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr");