Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
3.4 KiB

  1. /***
  2. *strtok.c - tokenize a string with given delimiters
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines strtok() - breaks string into series of token
  8. * via repeated calls.
  9. *
  10. *Revision History:
  11. * 06-01-89 JCR C version created.
  12. * 02-27-90 GJF Fixed calling type, #include <cruntime.h>, fixed
  13. * copyright.
  14. * 08-14-90 SBM Removed now redundant #include <stddef.h>
  15. * 10-02-90 GJF New-style function declarator.
  16. * 07-17-91 GJF Multi-thread support for Win32 [_WIN32_].
  17. * 10-26-91 GJF Fixed nasty bug - search for end-of-token could run
  18. * off the end of the string.
  19. * 02-17-93 GJF Changed for new _getptd().
  20. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  21. * 05-25-93 GJF Revised to use unsigned char * pointers to access
  22. * the token and delimiter strings.
  23. * 09-03-93 GJF Replaced MTHREAD with _MT.
  24. *
  25. *******************************************************************************/
  26. #include <cruntime.h>
  27. #include <string.h>
  28. #ifdef _MT
  29. #include <mtdll.h>
  30. #endif
  31. /***
  32. *char *strtok(string, control) - tokenize string with delimiter in control
  33. *
  34. *Purpose:
  35. * strtok considers the string to consist of a sequence of zero or more
  36. * text tokens separated by spans of one or more control chars. the first
  37. * call, with string specified, returns a pointer to the first char of the
  38. * first token, and will write a null char into string immediately
  39. * following the returned token. subsequent calls with zero for the first
  40. * argument (string) will work thru the string until no tokens remain. the
  41. * control string may be different from call to call. when no tokens remain
  42. * in string a NULL pointer is returned. remember the control chars with a
  43. * bit map, one bit per ascii char. the null char is always a control char.
  44. *
  45. *Entry:
  46. * char *string - string to tokenize, or NULL to get next token
  47. * char *control - string of characters to use as delimiters
  48. *
  49. *Exit:
  50. * returns pointer to first token in string, or if string
  51. * was NULL, to next token
  52. * returns NULL when no more tokens remain.
  53. *
  54. *Uses:
  55. *
  56. *Exceptions:
  57. *
  58. *******************************************************************************/
  59. char * __cdecl strtok (
  60. char * string,
  61. const char * control
  62. )
  63. {
  64. unsigned char *str;
  65. const unsigned char *ctrl = control;
  66. unsigned char map[32];
  67. int count;
  68. #ifdef _MT
  69. _ptiddata ptd = _getptd();
  70. #else
  71. static char *nextoken;
  72. #endif
  73. /* Clear control map */
  74. for (count = 0; count < 32; count++)
  75. map[count] = 0;
  76. /* Set bits in delimiter table */
  77. do {
  78. map[*ctrl >> 3] |= (1 << (*ctrl & 7));
  79. } while (*ctrl++);
  80. /* Initialize str. If string is NULL, set str to the saved
  81. * pointer (i.e., continue breaking tokens out of the string
  82. * from the last strtok call) */
  83. if (string)
  84. str = string;
  85. else
  86. #ifdef _MT
  87. str = ptd->_token;
  88. #else
  89. str = nextoken;
  90. #endif
  91. /* Find beginning of token (skip over leading delimiters). Note that
  92. * there is no token iff this loop sets str to point to the terminal
  93. * null (*str == '\0') */
  94. while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
  95. str++;
  96. string = str;
  97. /* Find the end of the token. If it is not the end of the string,
  98. * put a null there. */
  99. for ( ; *str ; str++ )
  100. if ( map[*str >> 3] & (1 << (*str & 7)) ) {
  101. *str++ = '\0';
  102. break;
  103. }
  104. /* Update nextoken (or the corresponding field in the per-thread data
  105. * structure */
  106. #ifdef _MT
  107. ptd->_token = str;
  108. #else
  109. nextoken = str;
  110. #endif
  111. /* Determine if a token has been found. */
  112. if ( string == str )
  113. return NULL;
  114. else
  115. return string;
  116. }