/* FILENAME: stdlib.c * * Functions normally found in a standard C lib. * * 12/28/2005 - added memcmp and memmove * * Notes: These functions support ASCII only!!! */ #include "common.h" #include "stdlib.h" /****************************************************************/ int isspace (int ch) { if ((ch == ' ') || (ch == '\t')) /* \n ??? */ return TRUE; else return FALSE; } /****************************************************************/ int isalnum (int ch) { /* ASCII only */ if (((ch >= '0') && (ch <= '9')) || ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'))) return TRUE; else return FALSE; } /****************************************************************/ int isdigit (int ch) { /* ASCII only */ if ((ch >= '0') && (ch <= '9')) return TRUE; else return FALSE; } /****************************************************************/ int isupper (int ch) { /* ASCII only */ if ((ch >= 'A') && (ch <= 'Z')) return TRUE; else return FALSE; } /****************************************************************/ int strcasecmp (const char *s1, const char *s2) { char c1, c2; int result = 0; while (result == 0) { c1 = *s1++; c2 = *s2++; if ((c1 >= 'a') && (c1 <= 'z')) c1 = (char)(c1 - ' '); if ((c2 >= 'a') && (c2 <= 'z')) c2 = (char)(c2 - ' '); if ((result = (c1 - c2)) != 0) break; if ((c1 == 0) || (c2 == 0)) break; } return result; } /****************************************************************/ int stricmp (const char *s1, const char *s2) { return (strcasecmp(s1, s2)); } /****************************************************************/ int strncasecmp (const char *s1, const char *s2, int n) { char c1, c2; int k = 0; int result = 0; while ( k++ < n ) { c1 = *s1++; c2 = *s2++; if ((c1 >= 'a') && (c1 <= 'z')) c1 = (char)(c1 - ' '); if ((c2 >= 'a') && (c2 <= 'z')) c2 = (char)(c2 - ' '); if ((result = (c1 - c2)) != 0) break; if ((c1 == 0) || (c2 == 0)) break; } return result; } /****************************************************************/ int strnicmp (const char *s1, const char *s2, int n) { return (strncasecmp(s1, s2, n)); } /****************************************************************/ uint32 strtoul (char *str, char **ptr, int base) { unsigned long rvalue = 0; int neg = 0; int c; /* Validate parameters */ if ((str != NULL) && (base >= 0) && (base <= 36)) { /* Skip leading white spaces */ while (isspace(*str)) { ++str; } /* Check for notations */ switch (str[0]) { case '0': if (base == 0) { if ((str[1] == 'x') || (str[1] == 'X')) { base = 16; str += 2; } else { base = 8; str++; } } break; case '-': neg = 1; str++; break; case '+': str++; break; default: break; } if (base == 0) base = 10; /* Valid "digits" are 0..9, A..Z, a..z */ while (isalnum(c = *str)) { /* Convert char to num in 0..36 */ if ((c -= ('a' - 10)) < 10) /* 'a'..'z' */ { if ((c += ('a' - 'A')) < 10) /* 'A'..'Z' */ { c += ('A' - '0' - 10); /* '0'..'9' */ } } /* check c against base */ if (c >= base) { break; } if (neg) { rvalue = (rvalue * base) - c; } else { rvalue = (rvalue * base) + c; } ++str; } } /* Upon exit, 'str' points to the character at which valid info */ /* STOPS. No chars including and beyond 'str' are used. */ if (ptr != NULL) *ptr = str; return rvalue; } /****************************************************************/ int atoi (const char *str) { char *s = (char *)str; return ((int)strtoul(s, NULL, 10)); } /****************************************************************/ int strlen (const char *str) { char *s = (char *)str; int len = 0; if (s == NULL) return 0; while (*s++ != '\0') ++len; return len; } /****************************************************************/ char * strcat (char *dest, const char *src) { char *dp; char *sp = (char *)src; if ((dest != NULL) && (src != NULL)) { dp = &dest[strlen(dest)]; while (*sp != '\0') { *dp++ = *sp++; } *dp = '\0'; } return dest; } /****************************************************************/ char * strncat (char *dest, const char *src, int n) { char *dp; char *sp = (char *)src; if ((dest != NULL) && (src != NULL) && (n > 0)) { dp = &dest[strlen(dest)]; while ((*sp != '\0') && (n-- > 0)) { *dp++ = *sp++; } *dp = '\0'; } return dest; } /****************************************************************/ char * strcpy (char *dest, const char *src) { char *dp = (char *)dest; char *sp = (char *)src; if ((dest != NULL) && (src != NULL)) { while (*sp != '\0') { *dp++ = *sp++; } *dp = '\0'; } return dest; } /****************************************************************/ char * strncpy (char *dest, const char *src, int n) { char *dp = (char *)dest; char *sp = (char *)src; if ((dest != NULL) && (src != NULL) && (n > 0)) { while ((*sp != '\0') && (n-- > 0)) { *dp++ = *sp++; } *dp = '\0'; } return dest; } /****************************************************************/ int strcmp (const char *s1, const char *s2) { /* No checks for NULL */ char *s1p = (char *)s1; char *s2p = (char *)s2; while (*s2p != '\0') { if (*s1p != *s2p) break; ++s1p; ++s2p; } return (*s1p - *s2p); } /****************************************************************/ int strncmp (const char *s1, const char *s2, int n) { /* No checks for NULL */ char *s1p = (char *)s1; char *s2p = (char *)s2; if (n <= 0) return 0; while (*s2p != '\0') { if (*s1p != *s2p) break; if (--n == 0) break; ++s1p; ++s2p; } return (*s1p - *s2p); } /****************************************************************/ char * strstr(const char *s1, const char *s2) { char *sp = (char *)s1; int len1 = strlen(s1); int len2 = strlen(s2); while (len1 >= len2) { if (strncmp(sp, s2, len2) == 0) { return (sp); } ++sp; --len1; } return (NULL); } /****************************************************************/ char * strchr(const char *str, int c) { char *sp = (char *)str; char ch = (char)(c & 0xff); while (*sp != '\0') { if (*sp == ch) { return (sp); } ++sp; } return (NULL); } /****************************************************************/ void * memcpy (void *dest, const void *src, unsigned n) { unsigned char *dbp = (unsigned char *)dest; unsigned char *sbp = (unsigned char *)src; if ((dest != NULL) && (src != NULL) && (n > 0)) { while (n--) *dbp++ = *sbp++; } return dest; } /****************************************************************/ void * memset (void *s, int c, unsigned n) { /* Not optimized, but very portable */ unsigned char *sp = (unsigned char *)s; if ((s != NULL) && (n > 0)) { while (n--) { *sp++ = (unsigned char)c; } } return s; } /****************************************************************/ int memcmp (const void *s1, const void *s2, unsigned n) { unsigned char *s1p, *s2p; if (s1 && s2 && (n > 0)) { s1p = (unsigned char *)s1; s2p = (unsigned char *)s2; while ((--n >= 0) && (*s1p == *s2p)) { if (*s1p != *s2p) return (*s1p - *s2p); ++s1p; ++s2p; } } return (0); } /****************************************************************/ void * memmove (void *dest, const void *src, unsigned n) { unsigned char *dbp = (unsigned char *)dest; unsigned char *sbp = (unsigned char *)src; unsigned char *dend = dbp + n; unsigned char *send = sbp + n; if ((dest != NULL) && (src != NULL) && (n > 0)) { /* see if a memcpy would overwrite source buffer */ if ((sbp < dbp) && (dbp < send)) { while (n--) *(--dend) = *(--send); } else { while (n--) *dbp++ = *sbp++; } } return dest; } /****************************************************************/