From 48ef7704c03e7e554c05de01bf8d1d70c16cb6f4 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Wed, 20 Dec 2017 16:34:35 -0500 Subject: add libc building to agbcc. --- libc/string/strncat.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 libc/string/strncat.c (limited to 'libc/string/strncat.c') diff --git a/libc/string/strncat.c b/libc/string/strncat.c new file mode 100644 index 0000000..57ca068 --- /dev/null +++ b/libc/string/strncat.c @@ -0,0 +1,115 @@ +/* +FUNCTION + <>---concatenate strings + +INDEX + strncat + +ANSI_SYNOPSIS + #include + char *strncat(char *<[dst]>, const char *<[src]>, size_t <[length]>); + +TRAD_SYNOPSIS + #include + char *strncat(<[dst]>, <[src]>, <[length]>) + char *<[dst]>; + char *<[src]>; + size_t <[length]>; + +DESCRIPTION + <> appends not more than <[length]> characters from + the string pointed to by <[src]> (including the terminating + null character) to the end of the string pointed to by + <[dst]>. The initial character of <[src]> overwrites the null + character at the end of <[dst]>. A terminating null character + is always appended to the result + +WARNINGS + Note that a null is always appended, so that if the copy is + limited by the <[length]> argument, the number of characters + appended to <[dst]> is <>. + + +RETURNS + This function returns the initial value of <[dst]> + +PORTABILITY +<> is ANSI C. + +<> requires no supporting OS subroutines. + +QUICKREF + strncat ansi pure +*/ + +#include +#include + +/* Nonzero if X is aligned on a "long" boundary. */ +#define ALIGNED(X) \ + (((long)X & (sizeof (long) - 1)) == 0) + +#if LONG_MAX == 2147483647L +#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) +#else +#if LONG_MAX == 9223372036854775807L +/* Nonzero if X (a long int) contains a NULL byte. */ +#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) +#else +#error long int is not a 32bit or 64bit type. +#endif +#endif + +#ifndef DETECTNULL +#error long int is not a 32bit or 64bit byte +#endif + +char * +_DEFUN (strncat, (s1, s2, n), + char *s1 _AND + _CONST char *s2 _AND + size_t n) +{ +#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) + char *s = s1; + + while (*s1) + s1++; + while (n-- != 0 && (*s1++ = *s2++)) + { + if (n == 0) + *s1 = '\0'; + } + + return s; +#else + char *s = s1; + + /* Skip over the data in s1 as quickly as possible. */ + if (ALIGNED (s1)) + { + unsigned long *aligned_s1 = (unsigned long *)s1; + while (!DETECTNULL (*aligned_s1)) + aligned_s1++; + + s1 = (char *)aligned_s1; + } + + while (*s1) + s1++; + + /* s1 now points to the its trailing null character, now copy + up to N bytes from S2 into S1 stopping if a NULL is encountered + in S2. + + It is not safe to use strncpy here since it copies EXACTLY N + characters, NULL padding if necessary. */ + while (n-- != 0 && (*s1++ = *s2++)) + { + if (n == 0) + *s1 = '\0'; + } + + return s; +#endif /* not PREFER_SIZE_OVER_SPEED */ +} -- cgit v1.2.3