//
// aegis - a project change supervisor
// Copyright (C) 1994, 1996, 1997, 2002, 2004-2008 Peter Miller
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// .
//
#ifndef COMMON_AC_STRING_H
#define COMMON_AC_STRING_H
#include
#if STDC_HEADERS || HAVE_STRING_H
# include
// An ANSI string.h and pre-ANSI memory.h might conflict.
# if !STDC_HEADERS && HAVE_MEMORY_H
# include
# endif
#else
// memory.h and strings.h conflict on some systems.
# include
#endif
extern "C" {
#if !HAVE_STRCASECMP
int strcasecmp(const char *, const char *);
#endif
#if !HAVE_STRNCASECMP
int strncasecmp(const char *, const char *, size_t);
#endif
#if !HAVE_DECL_STRSIGNAL
const char *strsignal(int);
#endif
#if !HAVE_STRVERSCMP
int strverscmp(const char *, const char *);
#endif
#if !HAVE_STRLCPY
size_t strlcpy(char *dst, const char *src, size_t size);
#endif
#if !HAVE_STRLCAT
size_t strlcat(char *dst, const char *src, size_t size);
#endif
#if !HAVE_STRENDCPY
/**
* The strendcpy function is a buffer-overrun-safe replacement for
* strcpy, strcat, and a more efficient replacement for strlcpy and
* strlcat.
*
* Unless there is no space left in the buffer (dst >= end), the result
* will always be NUL terminated.
*
* @param dst
* The position within the destination string buffer to be copied into.
* @param src
* The string to be copied into the buffer.
* @param end
* The end of the string buffer being copied into. In most cases
* this is of the form "buffer + sizeof(buffer)", a constant which
* may be calculated at compile time.
* @returns
* A pointer into the buffer where at the NUL terminator of the
* string in the buffer. EXCEPT when an overrun would occur, in
* which case the \a end parameter is returned.
*
* @note
* The return value is where the next string would be written into the
* buffer. For example, un-safe code such as
*
* strcat(strcpy(buffer, "Hello, "), "World\n");
*
* can be safely replaced by
*
* strendcpy(strendcpy(buffer, "Hello, ", buffer + sizeof(buffer)),
* "World\n", buffer + sizeof(buffer));
*
* and overruns will be handled safely. Similarly, more complex string
* manipulations can be written
*
* char buffer[100];
* char *bp = buffer;
* bp = strendcpy(bp, "Hello, ", buffer + sizeof(buffer));
* bp = strendcpy(bp, "World!\n", buffer + sizeof(buffer));
*
* all that is required to test for an overrun is
*
* if (bp == buffer + sizeof(buffer))
* fprintf(stderr, "Overrun!\n");
*
* On the plus side, there is only one functionto remember, not two,
* replacing both strcpy and strcat.
*
* There have been some quite viable replacements for strcpy and strcat
* in the BSD strlcpy and strlcat functions. These functions are
* indeed buffer-ovrrun-safe but they suffer from doing too much work
* (and touching too much memory) in the case of overruns.
*
* Code such as
*
* strlcpy(buffer, "Hello, ", sizeof(buffer));
* strlcat(buffer, "World!\n", sizeof(buffer));
*
* suffers from O(n**2) problem, constantly re-tracing the initial
* portions of the buffer. In addition, in the case of overruns, the
* BSD versions of these functions return how big the buffer should
* have been. This functionality is rarely used, but still requires
* the \a src to be traversed all the way to the NUL (and it could be
* megabytes away) before they can return. The strendcpy function does
* not suffer from either of these performance problems.
*/
char *strendcpy(char *dst, const char *src, const char *end);
#endif
#undef strcat
#define strcat strcat_is_unsafe__use_strendcat_instead@
#undef strcpy
#define strcpy strcpy_is_unsafe__use_strendcpy_instead@
#ifndef HAVE_MEMMEM
void *memmem(const void *, size_t, const void *, size_t);
#endif
void *memmem_replacement(const void *, size_t, const void *, size_t);
// It is possible memmem is present, but severely broken. See the GNU
// libc memmem(3) man page for just how broken it can get.
#define memmem memmem_replacement
}
#endif // COMMON_AC_STRING_H