解读linux对string.h函数的实现

关键字: string 函数 实现

C代码
  1. /*  
  2. file:string.h  
  3. #ifndef _LINUX_STRING_H_  
  4. #define _LINUX_STRING_H_  
  5.  
  6. /* We don't want strings.h stuff being user by user stuff by accident */  
  7.   
  8. #ifdef __KERNEL__   
  9.   
  10. #include <linux/types.h>  /* for size_t */   
  11. #include <linux/stddef.h> /* for NULL */   
  12. #include <linux/compiler.h>   /* for inline ((always_inline)) */   
  13.   
  14. #ifdef __cplusplus   
  15. extern "C" {   
  16. #endif   
  17.   
  18. extern char * ___strtok;   
  19. extern char * strpbrk(const char *,const char *);   
  20. extern char * strtok(char *,const char *);   
  21. extern char * strsep(char **,const char *);   
  22. extern __kernel_size_t strspn(const char *,const char *);   
  23.   
  24.   
  25. /*  
  26.  * Include machine specific inline routines  
  27.  */  
  28. #include <asm/string.h>   
  29.   
  30. #ifndef __HAVE_ARCH_STRCPY   
  31. extern char * strcpy(char *,const char *);   
  32. #endif   
  33. #ifndef __HAVE_ARCH_STRNCPY   
  34. extern char * strncpy(char *,const char *, __kernel_size_t);   
  35. #endif   
  36. #ifndef __HAVE_ARCH_STRCAT   
  37. extern char * strcat(char *, const char *);   
  38. #endif   
  39. #ifndef __HAVE_ARCH_STRNCAT   
  40. extern char * strncat(char *, const char *, __kernel_size_t);   
  41. #endif   
  42. #ifndef __HAVE_ARCH_STRCMP   
  43. extern int strcmp(const char *,const char *);   
  44. #endif   
  45. #ifndef __HAVE_ARCH_STRNCMP   
  46. extern int strncmp(const char *,const char *,__kernel_size_t);   
  47. #endif   
  48. #ifndef __HAVE_ARCH_STRNICMP   
  49. extern int strnicmp(const char *, const char *, __kernel_size_t);   
  50. #endif   
  51. #ifndef __HAVE_ARCH_STRCHR   
  52. extern char * strchr(const char *,int);   
  53. #endif   
  54. #ifndef __HAVE_ARCH_STRRCHR   
  55. extern char * strrchr(const char *,int);   
  56. #endif   
  57. #ifndef __HAVE_ARCH_STRSTR   
  58. extern char * strstr(const char *,const char *);   
  59. #endif   
  60. #ifndef __HAVE_ARCH_STRLEN   
  61. extern __kernel_size_t strlen(const char *);   
  62. #endif   
  63. #ifndef __HAVE_ARCH_STRNLEN   
  64. extern __kernel_size_t strnlen(const char *,__kernel_size_t);   
  65. #endif   
  66.   
  67. #ifndef __HAVE_ARCH_MEMSET   
  68. extern void * memset(void *,int,__kernel_size_t);   
  69. #endif   
  70. #ifndef __HAVE_ARCH_MEMCPY   
  71. extern void * memcpy(void *,const void *,__kernel_size_t);   
  72. #endif   
  73. #ifndef __HAVE_ARCH_MEMMOVE   
  74. extern void * memmove(void *,const void *,__kernel_size_t);   
  75. #endif   
  76. #ifndef __HAVE_ARCH_MEMSCAN   
  77. extern void * memscan(void *,int,__kernel_size_t);   
  78. #endif   
  79. #ifndef __HAVE_ARCH_MEMCMP   
  80. extern int memcmp(const void *,const void *,__kernel_size_t);   
  81. #endif   
  82. #ifndef __HAVE_ARCH_MEMCHR   
  83. extern void * memchr(const void *,int,__kernel_size_t);   
  84. #endif   
  85.   
  86. #ifdef __cplusplus   
  87. }   
  88. #endif   
  89.   
  90. #endif   
  91. #endif /* _LINUX_STRING_H_ */   
  92. */  

实现文件string. c
C代码
  1. /*  
  2.  *  linux/lib/string.c  
  3.  *  
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds  
  5.  */  
  6.   
  7. /*  
  8.  * stupid library routines.. The optimized versions should generally be found  
  9.  * as inline code in <asm-xx/string.h>  
  10.  *  
  11.  * These are buggy as well..  
  12.  *  
  13.  * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>  
  14.  * -  Added strsep() which will replace strtok() soon (because strsep() is  
  15.  *    reentrant and should be faster). Use only strsep() in new code, please.  
  16.  */  
  17.     
  18. #include <linux/types.h>   
  19. #include <linux/string.h>   
  20. #include <linux/ctype.h>   
  21.   
  22. #ifndef __HAVE_ARCH_STRNICMP   
  23. /**  
  24.  * strnicmp - Case insensitive(忽视大小写), length-limited string comparison  
  25.  * @s1: One string  
  26.  * @s2: The other string  
  27.  * @len: the maximum number of characters to compare  
  28.  */  
  29. int strnicmp(const char *s1, const char *s2, size_t len)   
  30. {   
  31.     /* Yes, Virginia, it had better be unsigned */  
  32.     unsigned char c1, c2;   
  33.   
  34.     c1 = 0; c2 = 0;   
  35.     if (len) {   
  36.         do {   
  37.             c1 = *s1; c2 = *s2;   
  38.             s1++; s2++;   
  39.                           //是否已到字符串的末尾或两字符串是否有空串,如果到了末尾或有空串,则比较完毕   
  40.             if (!c1)   
  41.                 break;   
  42.             if (!c2)   
  43.                 break;   
  44.                           //如果没有,且字符串相等,则继续比较下个字符   
  45.             if (c1 == c2)   
  46.                 continue;   
  47.                           //如果不相同,则同时转换为小写字符再进行比较   
  48.             c1 = tolower(c1);   
  49.             c2 = tolower(c2);   
  50.                           //如果不相同,则比较完毕,否则继续   
  51.             if (c1 != c2)   
  52.                 break;   
  53.         } while (--len);   
  54.     }   
  55.     return (int)c1 - (int)c2;   
  56. }   
  57. #endif   
  58.   
  59. char * ___strtok;   
  60.   
  61. #ifndef __HAVE_ARCH_STRCPY   
  62. /**  
  63.  * strcpy - Copy a %NUL terminated string  
  64.  * @dest: Where to copy the string to  
  65.  * @src: Where to copy the string from  
  66.  */  
  67. char * strcpy(char * dest,const char *src)   
  68. {   
  69.     char *tmp = dest;   
  70.   
  71.     while ((*dest++ = *src++) != '/0')   
  72.         /* nothing */;   
  73.     return tmp;   
  74. }   
  75. #endif   
  76.   
  77. #ifndef __HAVE_ARCH_STRNCPY   
  78. /**  
  79.  * strncpy - Copy a length-limited, %NUL-terminated string  
  80.  * @dest: Where to copy the string to  
  81.  * @src: Where to copy the string from  
  82.  * @count: The maximum number of bytes to copy  
  83.  *  
  84.  * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.  
  85.  * However, the result is not %NUL-terminated if the source exceeds  
  86.  * @count bytes.  
  87.  */  
  88. char * strncpy(char * dest,const char *src,size_t count)   
  89. {   
  90.     char *tmp = dest;   
  91.   
  92.     while (count-- && (*dest++ = *src++) != '/0')   
  93.         /* nothing */;   
  94.   
  95.     return tmp;   
  96. }   
  97. #endif   
  98.   
  99. #ifndef __HAVE_ARCH_STRCAT   
  100. /**  
  101.  * strcat - Append one %NUL-terminated string to another  
  102.  * @dest: The string to be appended to  
  103.  * @src: The string to append to it  
  104.  */  
  105. char * strcat(char * dest, const char * src)   
  106. {   
  107.     char *tmp = dest;   
  108.   
  109.     while (*dest)   
  110.         dest++;   
  111.     while ((*dest++ = *src++) != '/0')   
  112.         ;   
  113.   
  114.     return tmp;   
  115. }   
  116. #endif   
  117.   
  118. #ifndef __HAVE_ARCH_STRNCAT   
  119. /**  
  120.  * strncat - Append a length-limited, %NUL-terminated string to another  
  121.  * @dest: The string to be appended to  
  122.  * @src: The string to append to it  
  123.  * @count: The maximum numbers of bytes to copy  
  124.  *  
  125.  * Note that in contrast to strncpy, strncat ensures the result is  
  126.  * terminated.  
  127.  */  
  128. char * strncat(char *dest, const char *src, size_t count)   
  129. {   
  130.     char *tmp = dest;   
  131.   
  132.     if (count) { //如果追加的字符数不为0   
  133.         while (*dest) //达到字符串的末尾   
  134.             dest++;   
  135.         while ((*dest++ = *src++)) { //如果没有到源字符串末尾   
  136.             if (--count == 0) { //如果已经追加了count字符   
  137.                 *dest = '/0';//末尾置null字符   
  138.                 break;//结束循环   
  139.             }   
  140.         }   
  141.     }   
  142.   
  143.     return tmp;   
  144. }   
  145. #endif   
  146.   
  147. #ifndef __HAVE_ARCH_STRCMP   
  148. /**  
  149.  * strcmp - Compare two strings  
  150.  * @cs: One string  
  151.  * @ct: Another string  
  152.  */  
  153. int strcmp(const char * cs,const char * ct)   
  154. {   
  155.     register signed char __res;   
  156.   
  157.     while (1) {   
  158.         if ((__res = *cs - *ct++) != 0 || !*cs++)   
  159.             break;   
  160.     }   
  161.   
  162.     return __res;   
  163. }   
  164. #endif   
  165.   
  166. #ifndef __HAVE_ARCH_STRNCMP   
  167. /**  
  168.  * strncmp - Compare two length-limited strings  
  169.  * @cs: One string  
  170.  * @ct: Another string  
  171.  * @count: The maximum number of bytes to compare  
  172.  */  
  173. int strncmp(const char * cs,const char * ct,size_t count)   
  174. {   
  175.     register signed char __res = 0;   
  176.   
  177.     while (count) {   
  178.         if ((__res = *cs - *ct++) != 0 || !*cs++)   
  179.             break;   
  180.         count--;   
  181.     }   
  182.   
  183.     return __res;   
  184. }   
  185. #endif   
  186.   
  187. #ifndef __HAVE_ARCH_STRCHR   
  188. /**  
  189.  * strchr - Find the first occurrence of a character in a string  
  190.  * @s: The string to be searched  
  191.  * @c: The character to search for  
  192.  */  
  193. char * strchr(const char * s, int c)   
  194. {   
  195.     for(; *s != (charc; ++s)   
  196.         if (*s == '/0')   
  197.             return NULL;   
  198.     return (char *) s;   
  199. }   
  200. #endif   
  201.   
  202. #ifndef __HAVE_ARCH_STRRCHR   
  203. /**  
  204.  * strrchr - Find the last occurrence of a character in a string  
  205.  * @s: The string to be searched  
  206.  * @c: The character to search for  
  207.  */  
  208. char * strrchr(const char * s, int c)   
  209. {   
  210.        const char *p = s + strlen(s);   
  211.        do {   
  212.            if (*p == (char)c)   
  213.                return (char *)p;   
  214.        } while (--p >= s);   
  215.        return NULL;   
  216. }   
  217. #endif   
  218.   
  219. #ifndef __HAVE_ARCH_STRLEN   
  220. /**  
  221.  * strlen - Find the length of a string  
  222.  * @s: The string to be sized  
  223.  */  
  224. size_t strlen(const char * s)   
  225. {   
  226.     const char *sc;   
  227.   
  228.     for (sc = s; *sc != '/0'; ++sc)   
  229.         /* nothing */;   
  230.     return sc - s;   
  231. }   
  232. #endif   
  233.   
  234. #ifndef __HAVE_ARCH_STRNLEN   
  235. /**  
  236.  * strnlen - Find the length of a length-limited string  
  237.  * @s: The string to be sized  
  238.  * @count: The maximum number of bytes to search  
  239.  */  
  240. size_t strnlen(const char * s, size_t count)   
  241. {   
  242.     const char *sc;   
  243.   
  244.     for (sc = s; count-- && *sc != '/0'; ++sc)   
  245.         /* nothing */;   
  246.     return sc - s;   
  247. }   
  248. #endif   
  249.   
  250. #ifndef __HAVE_ARCH_STRSPN   
  251. /**  
  252.  * strspn - Calculate the length of the initial substring of @s which only  
  253.  *  contain letters in @accept  
  254.  * @s: The string to be searched  
  255.  * @accept: The string to search for  
  256.  */  
  257. size_t strspn(const char *s, const char *accept)   
  258. {   
  259.     const char *p;   
  260.     const char *a;   
  261.     size_t count = 0;   
  262.   
  263.     for (p = s; *p != '/0'; ++p) {   
  264.         for (a = accept; *a != '/0'; ++a) {   
  265.             if (*p == *a)   
  266.                 break;   
  267.         }   
  268.         if (*a == '/0')   
  269.             return count;   
  270.         ++count;   
  271.     }   
  272.   
  273.     return count;   
  274. }   
  275. #endif   
  276.   
  277. #ifndef __HAVE_ARCH_STRPBRK   
  278. /**  
  279.  * strpbrk - Find the first occurrence of a set of characters  
  280.  * @cs: The string to be searched  
  281.  * @ct: The characters to search for  
  282.  */  
  283. char * strpbrk(const char * cs,const char * ct)   
  284. {   
  285.     const char *sc1,*sc2;   
  286.   
  287.     for( sc1 = cs; *sc1 != '/0'; ++sc1) {   
  288.         for( sc2 = ct; *sc2 != '/0'; ++sc2) {   
  289.             if (*sc1 == *sc2)   
  290.                 return (char *) sc1;   
  291.         }   
  292.     }   
  293.     return NULL;   
  294. }   
  295. #endif   
  296.   
  297. #ifndef __HAVE_ARCH_STRTOK   
  298. /**  
  299.  * strtok - Split a string into tokens  
  300.  * @s: The string to be searched  
  301.  * @ct: The characters to search for  
  302.  *  
  303.  * WARNING: strtok is deprecated, use strsep instead.  
  304.  */  
  305. char * strtok(char * s,const char * ct)   
  306. {   
  307.     char *sbegin, *send;   
  308.   
  309.     sbegin  = s ? s : ___strtok;   
  310.     if (!sbegin) {   
  311.         return NULL;   
  312.     }   
  313.     sbegin += strspn(sbegin,ct);   
  314.     if (*sbegin == '/0') {   
  315.         ___strtok = NULL;   
  316.         return( NULL );   
  317.     }   
  318.     send = strpbrk( sbegin, ct);   
  319.     if (send && *send != '/0')   
  320.         *send++ = '/0';   
  321.     ___strtok = send;   
  322.     return (sbegin);   
  323. }   
  324. #endif   
  325.   
  326. #ifndef __HAVE_ARCH_STRSEP   
  327. /**  
  328.  * strsep - Split a string into tokens  
  329.  * @s: The string to be searched  
  330.  * @ct: The characters to search for  
  331.  *  
  332.  * strsep() updates @s to point after the token, ready for the next call.  
  333.  *  
  334.  * It returns empty tokens, too, behaving exactly like the libc function  
  335.  * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.  
  336.  * Same semantics, slimmer shape. ;)  
  337.  */  
  338. char * strsep(char **s, const char *ct)   
  339. {   
  340.     char *sbegin = *s, *end;   
  341.   
  342.     if (sbegin == NULL)   
  343.         return NULL;   
  344.   
  345.     end = strpbrk(sbegin, ct);   
  346.     if (end)   
  347.         *end++ = '/0';   
  348.     *s = end;   
  349.   
  350.     return sbegin;   
  351. }   
  352. #endif   
  353.   
  354. #ifndef __HAVE_ARCH_MEMSET   
  355. /**  
  356.  * memset - Fill a region of memory with the given value  
  357.  * @s: Pointer to the start of the area.  
  358.  * @c: The byte to fill the area with  
  359.  * @count: The size of the area.  
  360.  *  
  361.  * Do not use memset() to access IO space, use memset_io() instead.  
  362.  */  
  363. void * memset(void * s,int c,size_t count)   
  364. {   
  365.     char *xs = (char *) s;   
  366.   
  367.     while (count--)   
  368.         *xs++ = c;   
  369.   
  370.     return s;   
  371. }   
  372. #endif   
  373.   
  374. #ifndef __HAVE_ARCH_BCOPY   
  375. /**  
  376.  * bcopy - Copy one area of memory to another  
  377.  * @src: Where to copy from  
  378.  * @dest: Where to copy to  
  379.  * @count: The size of the area.  
  380.  *  
  381.  * Note that this is the same as memcpy(), with the arguments reversed.  
  382.  * memcpy() is the standard, bcopy() is a legacy BSD function.  
  383.  *  
  384.  * You should not use this function to access IO space, use memcpy_toio()  
  385.  * or memcpy_fromio() instead.  
  386.  */  
  387. void bcopy(const void * srcp, void * destp, size_t count)   
  388. {   
  389.     const char *src = srcp;   
  390.     char *dest = destp;   
  391.   
  392.     while (count--)   
  393.         *dest++ = *src++;   
  394. }   
  395. #endif   
  396.   
  397. #ifndef __HAVE_ARCH_MEMCPY   
  398. /**  
  399.  * memcpy - Copy one area of memory to another  
  400.  * @dest: Where to copy to  
  401.  * @src: Where to copy from  
  402.  * @count: The size of the area.  
  403.  *  
  404.  * You should not use this function to access IO space, use memcpy_toio()  
  405.  * or memcpy_fromio() instead.  
  406.  */  
  407. void * memcpy(void * dest,const void *src,size_t count)   
  408. {   
  409.     char *tmp = (char *) dest, *s = (char *) src;   
  410.   
  411.     while (count--)   
  412.         *tmp++ = *s++;   
  413.   
  414.     return dest;   
  415. }   
  416. #endif   
  417.   
  418. #ifndef __HAVE_ARCH_MEMMOVE   
  419. /**  
  420.  * memmove - Copy one area of memory to another  
  421.  * @dest: Where to copy to  
  422.  * @src: Where to copy from  
  423.  * @count: The size of the area.  
  424.  *  
  425.  * Unlike memcpy(), memmove() copes with overlapping areas.  
  426.  */  
  427. void * memmove(void * dest,const void *src,size_t count)   
  428. {   
  429.     char *tmp, *s;   
  430.   
  431.     if (dest <= src) {   
  432.         tmp = (char *) dest;   
  433.         s = (char *) src;   
  434.         while (count--)   
  435.             *tmp++ = *s++;   
  436.         }   
  437.     else {   
  438.         tmp = (char *) dest + count;   
  439.         s = (char *) src + count;   
  440.         while (count--)   
  441.             *--tmp = *--s;   
  442.         }   
  443.   
  444.     return dest;   
  445. }   
  446. #endif   
  447.   
  448. #ifndef __HAVE_ARCH_MEMCMP   
  449. /**  
  450.  * memcmp - Compare two areas of memory  
  451.  * @cs: One area of memory  
  452.  * @ct: Another area of memory  
  453.  * @count: The size of the area.  
  454.  */  
  455. int memcmp(const void * cs,const void * ct,size_t count)   
  456. {   
  457.     const unsigned char *su1, *su2;   
  458.     int res = 0;   
  459.   
  460.     for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)   
  461.         if ((res = *su1 - *su2) != 0)   
  462.             break;   
  463.     return res;   
  464. }   
  465. #endif   
  466.   
  467. #ifndef __HAVE_ARCH_MEMSCAN   
  468. /**  
  469.  * memscan - Find a character in an area of memory.  
  470.  * @addr: The memory area  
  471.  * @c: The byte to search for  
  472.  * @size: The size of the area.  
  473.  *  
  474.  * returns the address of the first occurrence of @c, or 1 byte past  
  475.  * the area if @c is not found  
  476.  */  
  477. void * memscan(void * addr, int csize_t size)   
  478. {   
  479.     unsigned char * p = (unsigned char *) addr;   
  480.   
  481.     while (size) {   
  482.         if (*p == c)   
  483.             return (void *) p;   
  484.         p++;   
  485.         size--;   
  486.     }   
  487.     return (void *) p;   
  488. }   
  489. #endif   
  490.   
  491. #ifndef __HAVE_ARCH_STRSTR   
  492. /**  
  493.  * strstr - Find the first substring in a %NUL terminated string  
  494.  * @s1: The string to be searched  
  495.  * @s2: The string to search for  
  496.  */  
  497. char * strstr(const char * s1,const char * s2)   
  498. {   
  499.     int l1, l2;   
  500.   
  501.     l2 = strlen(s2);   
  502.     if (!l2)   
  503.         return (char *) s1;   
  504.     l1 = strlen(s1);   
  505.     while (l1 >= l2) {   
  506.         l1--;   
  507.         if (!memcmp(s1,s2,l2))   
  508.             return (char *) s1;   
  509.         s1++;   
  510.     }   
  511.     return NULL;   
  512. }   
  513. #endif   
  514.   
  515. #ifndef __HAVE_ARCH_MEMCHR   
  516. /**  
  517.  * memchr - Find a character in an area of memory.  
  518.  * @s: The memory area  
  519.  * @c: The byte to search for  
  520.  * @n: The size of the area.  
  521.  *  
  522.  * returns the address of the first occurrence of @c, or %NULL  
  523.  * if @c is not found  
  524.  */  
  525. void *memchr(const void *s, int csize_t n)   
  526. {   
  527.     const unsigned char *p = s;   
  528.     while (n-- != 0) {   
  529.             if ((unsigned char)c == *p++) {   
  530.             return (void *)(p-1);   
  531.         }   
  532.     }   
  533.     return NULL;   
  534. }   
  535.   
  536. #endif  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值