stpncpy.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /* Copyright (C) 1993, 1995-1997, 2002-2003, 2005-2007, 2009-2020 Free Software
  2. * Foundation, Inc.
  3. NOTE: The canonical source of this file is maintained with the GNU C Library.
  4. Bugs can be reported to bug-glibc@gnu.org.
  5. This program is free software: you can redistribute it and/or modify it
  6. under the terms of the GNU General Public License as published by the
  7. Free Software Foundation; either version 3 of the License, or any
  8. later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <https://www.gnu.org/licenses/>. */
  15. /* This is almost copied from strncpy.c, written by Torbjorn Granlund. */
  16. #include <config.h>
  17. /* Specification. */
  18. #include <string.h>
  19. #ifndef weak_alias
  20. # define __stpncpy stpncpy
  21. #endif
  22. /* Copy no more than N bytes of SRC to DST, returning a pointer past the
  23. last non-NUL byte written into DST. */
  24. char *
  25. (__stpncpy) (char *dest, const char *src, size_t n)
  26. {
  27. char c;
  28. char *s = dest;
  29. if (n >= 4)
  30. {
  31. size_t n4 = n >> 2;
  32. for (;;)
  33. {
  34. c = *src++;
  35. *dest++ = c;
  36. if (c == '\0')
  37. break;
  38. c = *src++;
  39. *dest++ = c;
  40. if (c == '\0')
  41. break;
  42. c = *src++;
  43. *dest++ = c;
  44. if (c == '\0')
  45. break;
  46. c = *src++;
  47. *dest++ = c;
  48. if (c == '\0')
  49. break;
  50. if (--n4 == 0)
  51. goto last_chars;
  52. }
  53. n -= dest - s;
  54. goto zero_fill;
  55. }
  56. last_chars:
  57. n &= 3;
  58. if (n == 0)
  59. return dest;
  60. for (;;)
  61. {
  62. c = *src++;
  63. --n;
  64. *dest++ = c;
  65. if (c == '\0')
  66. break;
  67. if (n == 0)
  68. return dest;
  69. }
  70. zero_fill:
  71. while (n-- > 0)
  72. dest[n] = '\0';
  73. return dest - 1;
  74. }
  75. #ifdef weak_alias
  76. weak_alias (__stpncpy, stpncpy)
  77. #endif