compat_string.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file compat_string.c
  7. * \brief Useful string-processing functions that some platforms don't
  8. * provide.
  9. **/
  10. #include "lib/string/compat_string.h"
  11. #include "lib/err/torerr.h"
  12. /* Inline the strl functions if the platform doesn't have them. */
  13. #ifndef HAVE_STRLCPY
  14. #include "strlcpy.c"
  15. #endif
  16. #ifndef HAVE_STRLCAT
  17. #include "strlcat.c"
  18. #endif
  19. #include <stdlib.h>
  20. #include <string.h>
  21. /** Helper for tor_strtok_r_impl: Advances cp past all characters in
  22. * <b>sep</b>, and returns its new value. */
  23. static char *
  24. strtok_helper(char *cp, const char *sep)
  25. {
  26. if (sep[1]) {
  27. while (*cp && strchr(sep, *cp))
  28. ++cp;
  29. } else {
  30. while (*cp && *cp == *sep)
  31. ++cp;
  32. }
  33. return cp;
  34. }
  35. /** Implementation of strtok_r for platforms whose coders haven't figured out
  36. * how to write one. Hey, retrograde libc developers! You can use this code
  37. * here for free! */
  38. char *
  39. tor_strtok_r_impl(char *str, const char *sep, char **lasts)
  40. {
  41. char *cp, *start;
  42. raw_assert(*sep);
  43. if (str) {
  44. str = strtok_helper(str, sep);
  45. if (!*str)
  46. return NULL;
  47. start = cp = *lasts = str;
  48. } else if (!*lasts || !**lasts) {
  49. return NULL;
  50. } else {
  51. start = cp = *lasts;
  52. }
  53. if (sep[1]) {
  54. while (*cp && !strchr(sep, *cp))
  55. ++cp;
  56. } else {
  57. cp = strchr(cp, *sep);
  58. }
  59. if (!cp || !*cp) {
  60. *lasts = NULL;
  61. } else {
  62. *cp++ = '\0';
  63. *lasts = strtok_helper(cp, sep);
  64. }
  65. return start;
  66. }