// // aegis - project change supervisor // Copyright (C) 1994, 1996, 2002-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 // . // #include #include #include // // NAME // strerror - string for error number // // SYNOPSIS // char *strerror(int errnum); // // DESCRIPTION // The strerror function maps the error number in errnum to an error // message string. // // RETURNS // The strerror function returns a pointer to the string, the contents of // which are implementation-defined. The array pointed to shall not be // modified by the program, but may be overwritten by a subsequent call to // the strerror function. // // CAVEAT // Unknown errors will be rendered in the form "Error %d", where %d will // be replaced by a decimal representation of the error number. // #ifndef HAVE_STRERROR char * strerror(int n) { extern int sys_nerr; extern const char *const sys_errlist[]; static char buffer[16]; if (n < 1 || n > sys_nerr) { snprintf(buffer, sizeof(buffer), "Error %d", n); return buffer; } return (char *)sys_errlist[n]; } #endif // !HAVE_STRERROR #ifndef HAVE_STRCASECMP #include int strcasecmp(const char *s1, const char *s2) { unsigned char c1; unsigned char c2; for (;;) { c1 = *s1++; if (isupper((unsigned char)c1)) c1 = tolower(c1); c2 = *s2++; if (isupper((unsigned char)c2)) c2 = tolower(c2); if (c1 != c2) { // // if s1 is a leading substring of s2, must // return -1, even if the next character of s2 // is negative. // if (!c1) return -1; if (!c2) return 1; if (c1 < c2) return -1; return 1; } if (!c1) return 0; } } #endif // !HAVE_STRCASECMP #ifndef HAVE_STRNCASECMP #include int strncasecmp(const char *s1, const char *s2, size_t len) { unsigned char c1; unsigned char c2; while (len-- > 0) { c1 = *s1++; if (isupper((unsigned char)c1)) c1 = tolower(c1); c2 = *s2++; if (isupper((unsigned char)c2)) c2 = tolower(c2); if (c1 != c2) { // // if s1 is a leading substring of s2, must // return -1, even if the next character of s2 // is negative. // if (!c1) return -1; if (!c2) return 1; if (c1 < c2) return -1; return 1; } if (!c1) return 0; } return 0; } #endif // !HAVE_STRNCASECMP #ifndef HAVE_STRSIGNAL extern "C" const char * strsignal(int n) { switch (n) { #ifdef SIGHUP case SIGHUP: return "hang up [SIGHUP]"; #endif // SIGHUP #ifdef SIGINT case SIGINT: return "user interrupt [SIGINT]"; #endif // SIGINT #ifdef SIGQUIT case SIGQUIT: return "user quit [SIGQUIT]"; #endif // SIGQUIT #ifdef SIGILL case SIGILL: return "illegal instruction [SIGILL]"; #endif // SIGILL #ifdef SIGTRAP case SIGTRAP: return "trace trap [SIGTRAP]"; #endif // SIGTRAP #ifdef SIGIOT case SIGIOT: return "abort [SIGIOT]"; #endif // SIGIOT #ifdef SIGEMT case SIGEMT: return "EMT instruction [SIGEMT]"; #endif // SIGEMT #ifdef SIGFPE case SIGFPE: return "floating point exception [SIGFPE]"; #endif // SIGFPE #ifdef SIGKILL case SIGKILL: return "kill [SIGKILL]"; #endif // SIGKILL #ifdef SIGBUS case SIGBUS: return "bus error [SIGBUS]"; #endif // SIGBUS #ifdef SIGSEGV case SIGSEGV: return "segmentation violation [SIGSEGV]"; #endif // SIGSEGV #ifdef SIGSYS case SIGSYS: return "bad argument to system call [SIGSYS]"; #endif // SIGSYS #ifdef SIGPIPE case SIGPIPE: return "write on a pipe with no one to read it [SIGPIPE]"; #endif // SIGPIPE #ifdef SIGALRM case SIGALRM: return "alarm clock [SIGALRM]"; #endif // SIGALRM #ifdef SIGTERM case SIGTERM: return "software termination [SIGTERM]"; #endif // SIGTERM #ifdef SIGUSR1 case SIGUSR1: return "user defined signal one [SIGUSR1]"; #endif // SIGUSR1 #ifdef SIGUSR2 case SIGUSR2: return "user defined signal two [SIGUSR2]"; #endif // SIGUSR2 #ifdef SIGCLD case SIGCLD: return "death of child [SIGCLD]"; #endif // SIGCLD #ifdef SIGPWR case SIGPWR: return "power failure [SIGPWR]"; #endif // SIGPWR } return 0; } #endif // !HAVE_STRSIGNAL #ifndef HAVE_STRVERSCMP // // Derived from sources marked... // // Compare strings while treating digits characters numerically. // Copyright (C) 1997 Free Software Foundation, Inc. // This file is part of the GNU C Library. // Contributed by Jean-Franc,ois Bignolles , 1997. // // The GNU C Library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // The GNU C Library 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 // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with the GNU C Library; see the file COPYING.LIB. If not, // write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth // Floor, Boston, MA 02110-1301 USA. // #include // // states: // S_N: normal, // S_I: comparing integral part, // S_F: comparing fractionnal parts, // S_Z: idem but with leading Zeroes only // #define S_N 0x0 #define S_I 0x4 #define S_F 0x8 #define S_Z 0xC // // result_type: // CMP: return diff; // LEN: compare using len_diff/diff // #define CMP 2 #define LEN 3 // // Compare S1 and S2 as strings holding indices/version numbers, returning // less than, equal to or greater than zero if S1 is less than, equal // to or greater than S2 (for more info, see the texinfo doc). // int strverscmp(const char *s1, const char *s2) { const unsigned char *p1; const unsigned char *p2; unsigned char c1; unsigned char c2; int state; int diff; // Symbol(s) others [0-9] 0 (padding) // Transition (00) x (01) d (10) 0 (11) - static const unsigned int next_state[] = { // state x d 0 - // S_N S_N, S_I, S_Z, S_N, // S_I S_N, S_I, S_I, S_I, // S_F S_N, S_F, S_F, S_F, // S_Z S_N, S_F, S_Z, S_Z }; static const int result_type[] = { // state x/x x/d x/0 x/- d/x d/d d/0 d/- // 0/x 0/d 0/0 0/- -/x -/d -/0 -/- // S_N CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, // S_I CMP, -1, -1, CMP, +1, LEN, LEN, CMP, +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, // S_F CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, // S_Z CMP, +1, +1, CMP, -1, CMP, CMP, CMP, -1, CMP, CMP, CMP, 0, 0, 0, 0, }; p1 = (const unsigned char *)s1; p2 = (const unsigned char *)s2; if (p1 == p2) return 0; c1 = *p1++; c2 = *p2++; // Hint: '0' is a digit too. state = S_N | ((c1 == '0') + (isdigit(c1) != 0)); while ((diff = c1 - c2) == 0 && c1 != '\0') { state = next_state[state]; c1 = *p1++; c2 = *p2++; state |= (c1 == '0') + (isdigit(c1) != 0); } state = result_type[state << 2 | (((c2 == '0') + (isdigit(c2) != 0)))]; switch (state) { case CMP: return diff; case LEN: while (isdigit(*p1++)) { if (!isdigit(*p2++)) return 1; } return isdigit(*p2) ? -1 : diff; default: return state; } } #endif // !HAVE_STRVERSCMP #if !HAVE_STRLCPY // // http://www.courtesan.com/todd/papers/strlcpy.html // // Like strncpy but does not 0 fill the buffer and always null // terminates. // // @param bufsize is the size of the destination buffer. // // @return index of the terminating byte. // size_t strlcpy(char *d, const char *s, size_t bufsize) { if (bufsize <= 0) return 0; size_t len = strlen(s); size_t ret = len; if (len >= bufsize) len = bufsize - 1; memcpy(d, s, len); d[len] = 0; return ret; } #endif // !HAVE_STRLCPY #if !HAVE_STRLCAT // // http://www.courtesan.com/todd/papers/strlcpy.html // // Like strncat() but does not 0 fill the buffer and always null // terminates. // // @param bufsize length of the buffer, which should be one more than // the maximum resulting string length. // size_t strlcat(char *d, const char *s, size_t bufsize) { size_t len1 = strlen(d); size_t len2 = strlen(s); size_t ret = len1 + len2; if (len1 + len2 >= bufsize) len2 = bufsize - len1 - 1; if (len2 > 0) { memcpy(d + len1, s, len2); d[len1 + len2] = 0; } return ret; } #endif // !HAVE_STRLCAT #ifndef HAVE_STRENDCPY char * strendcpy(char *dst, const char *src, const char *end) { if (dst < end) { // leave room for terminating NUL end--; while (dst < end && *src) *dst++ = *src++; *dst = '\0'; if (*src) { // return end parameter if truncated dst++; } } return dst; } #endif // !HAVE_STRENDCPY