/* string.h ルーチン 2000-10 writen by tenk* */ #define GLOBAL #define assert(e) #define NULL 0 #ifndef TOUPPER /*#define TOUPPER(c) ((c) - ((('a' <= (c)) & ((c) <= 'z')) << 5))*/ /*#define TOLOWER(c) ((c) + ((('A' <= (c)) & ((c) <= 'Z')) << 5))*/ #define TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (c) - 0x20 : (c)) #define TOLOWER(c) ((((c) <= 'Z') && ((c) >= 'A')) ? (c) + 0x20 : (c)) #endif typedef unsigned size_t; GLOBAL void *memset(void *dst, int c, size_t n) /* STDC */ { char *d, *e; assert(dst != NULL); d = (char *)dst; e = d + n; while (d != e) *d++ = c; return dst; } GLOBAL void *memclr(void *dst, size_t n) /* KLDR */ { char *d, *e; assert(dst != NULL); d = (char *)dst; e = d + n; while (d != e) *d++ = 0; return dst; } GLOBAL void *memcpy(void *dst, const void *src, size_t n) /* STDC */ { char *d, *e; const char *s; assert(dst != NULL && src != NULL); d = (char *)dst; s = (const char *)src; e = d + n; while (d != e) *d++ = *s++; return dst; } GLOBAL void *memrcpy(void *dst, const void *src, size_t n) /* KLDR */ { char *d; const char *s; assert(dst != NULL && src != NULL); d = (char *)dst+n; s = (const char *)src+n; while (d != dst) *--d = *--s; return dst; } GLOBAL void *memmove(void *dst, const void *src, size_t n) /* STDC */ { char *d; const char *s; assert(dst != NULL && src != NULL); if (n) { d = (char *)dst; s = (const char *)src; if (d < s) { char *e = d + n; while (d != e) *d++ = *s++; } else if (d > s) { d += n; s += n; while (d != dst) *--d = *--s; } } return dst; } GLOBAL void *memccpy(void *dst, const void *src, int termChr, size_t n) /* DOS/GCC */ { char *d, *e; const char *s; char t,c; assert(dst != NULL && src != NULL); t = (char)termChr; s = (char *)src; d = (char *)dst; e = d+n; while (d != e) { *d++ = c = *s++; if (c == t) { return d; } } return NULL; } GLOBAL void _swab(void *src, const void *dst, size_t n) /* STDC */ { char *d, *e; const char *s; int a,b; assert(dst != NULL && src != NULL); d = (char *)dst; s = (const char *)src; e = d + (n & ~1); while (d != e) { a = *s++; b = *s++; d[1] = a; d[0] = b; d += 2; } return; } GLOBAL void *memchr(const void *src, int c, size_t n) /* STDC */ { const char *s, *e; assert(src != NULL); s = (const char *)src; e = s + n; c = (char)c; while (s != e) { if (*s == c) return (void *)s; s++; } return NULL; } GLOBAL int memcmp(const void *left, const void *right, size_t n) /* STDC */ { const unsigned char *l, *r, *e; int c; assert(left != NULL && right != NULL); l = (const unsigned char *)left; r = (const unsigned char *)right; e = l + n; c = 0; while (l != e && (c = *l - *r++) == 0) l++; return c; } GLOBAL int memicmp(const void *left, const void *right, size_t n) /* DOS/GCC */ { const unsigned char *l, *r, *e; int c; assert(left != NULL && right != NULL); l = (const unsigned char *)left; r = (const unsigned char *)right; e = l + n; c = 0; while (l != e && (c = TOUPPER(*l) - TOUPPER(*r)) == 0) { l++; r++; } return c; } GLOBAL size_t strlen(const char *src) /* STDC */ { const char *s; assert(src != NULL); s = src; while (*s != '\0') s++; return (size_t)(s - src); } GLOBAL char *strend(const char *src) /* KLDR */ { const char *s; assert(src != NULL); s = src; while (*s != '\0') s++; return (char *)s; } GLOBAL char *strcpy(char *dst, const char *s) /* STDC */ { char *d; assert(dst != NULL && s != NULL); d = dst; while ((*d++ = *s++) != '\0') ; return dst; } GLOBAL char *stpcpy(char *d, const char *s) /* GCC */ { assert(d != NULL && s != NULL); while ((*d = *s++) != '\0') d++; return d; } GLOBAL char *strncpy(char *dst, const char *s, size_t n) /* STDC */ { char *d, *e; assert(dst != NULL && s != NULL); d = dst; e = d + n; while (d < e) { if ((*d++ = *s++) == '\0') break; } while (d < e) *d++ = 0; return dst; } GLOBAL char *strcat(char *dst, const char *s) /* STDC */ { char *d; assert(dst != NULL && s != NULL); d = dst; while (*d) d++; while ((*d++ = *s++) != '\0') ; return dst; } GLOBAL char *strncat(char *dst, const char *s, size_t n) /* STDC */ { char *d, *e; assert(dst != NULL && s != NULL); d = dst; while (*d) d++; e = d + n; while (d < e) { if ((*d = *s++) == '\0') break; d++; } *d = 0; return dst; } GLOBAL char *strchr(const char *src, int c) /* STDC */ { const unsigned char *s; assert(src != NULL); s = (const unsigned char *)src; c = (unsigned char)c; while (*s) { if (*s == c) return (char *)s; s++; } return NULL; } GLOBAL char *strrchr(const char *src, int c) /* STDC */ { const char *s, *t; assert(src != NULL); s = src; t = NULL; c = (char)c; while (*s) { if (*s == c) t = s; s++; } return (char *)t; } GLOBAL void *strset(void *dst, int c) /* DOS/GCC */ { char *d, *e; assert(dst != NULL); d = (char *)dst; e = d; while (*e != '\0') e++; while (d != e) *d++ = c; return dst; } GLOBAL void *strnset(void *dst, int c, int n) /* DOS/GCC */ { char *d, *e; assert(dst != NULL); d = (char *)dst; e = d; d += n; while (*e != '\0' && e != d) e++; d = (char *)dst; while (d != e) *d++ = c; return dst; } GLOBAL size_t strspn(const char *src, const char *tbl) /* STDC */ { const char *s, *t; s = src; while (*s != '\0') { t = tbl; while (*s != *t) { if (*t == 0) goto RET; t++; } s++; } RET: return (size_t)(s - src); } GLOBAL size_t strcspn(const char *src, const char *tbl) /* STDC */ { const char *s, *t; assert(src != NULL && tbl != NULL); s = src; while (*s != 0) { t = tbl; while (*t != '\0') { if (*s == *t++) goto RET; } s++; } RET: return (size_t)(s - src); } GLOBAL char *strpbrk(const char *src, const char *tbl) /* STDC */ { const char *s, *t; assert(src != NULL && tbl != NULL); s = src; if (*s != '\0' && *tbl != '\0') { do { t = tbl; do { if (*s == *t++) return (char *)s; } while (*t != '\0'); s++; } while (*s != '\0'); } return NULL; } GLOBAL char *strtok(char *str, const char *tbl) /* STDC */ { static char *st = NULL; const char *t; char *s; /* assert(tbl != NULL); */ if (str) st = str; s = st; if (s == NULL /*|| tbl == NULL*/) return (char *)NULL; while (*s != '\0') { t = tbl; while (*s != *t) { if (*t == 0) goto RET; t++; } s++; } st = NULL; return NULL; RET: str = s; while (*s != '\0') { t = tbl; while (*t != '\0') { if (*s == *t++) { *s++ = 0; st = s; return str; } } s++; } st = NULL; return str; } GLOBAL int strcmp(const char *left, const char *right) /* STDC */ { const unsigned char *l, *r; int c; assert(left != NULL && right != NULL); l = (const unsigned char *)left; r = (const unsigned char *)right; while ((c = *l - *r++) == 0 && *l != '\0') l++; return c; } GLOBAL int strncmp(const char *left, const char *right, size_t n) /* STDC */ { const unsigned char *l, *r, *e; int c; assert(left != NULL && right != NULL); l = (const unsigned char *)left; r = (const unsigned char *)right; e = l + n; c = 0; while (l < e && (c = *l - *r++) == 0 && *l != '\0') l++; return c; } GLOBAL int stricmp(const char *left, const char *right) /* DOS/GCC */ { const unsigned char *l, *r; int c; assert(left != NULL && right != NULL); l = (const unsigned char *)left; r = (const unsigned char *)right; while ((c = TOUPPER(*l) - TOUPPER(*r)) == 0 && *l != '\0') { r++; l++; } return c; } GLOBAL int strnicmp(const char *left, const char *right, size_t n) /* DOS/GCC */ { const unsigned char *l, *r, *e; int c; assert(left != NULL && right != NULL); l = (const unsigned char *)left; r = (const unsigned char *)right; e = l + n; c = 0; while (l < e && (c = TOUPPER(*l) - TOUPPER(*r)) == 0 && *l != '\0') { l++; r++; } return c; } GLOBAL char *strupr(char *src) /* DOS/GCC */ { unsigned char *s; assert(src != NULL); s = (unsigned char *)src; while (*s) *s++ = TOUPPER(*s); return src; } GLOBAL char *strlwr(char *src) /* DOS/GCC */ { unsigned char *s; assert(src != NULL); s = (unsigned char *)src; while (*s) *s++ = TOLOWER(*s); return src; } GLOBAL char *strrev(char *src) /* STDC */ { unsigned char *s; unsigned char *e; int c; assert(src != NULL); s = (unsigned char *)src; e = s; while (*e) e++; while (s < e) { c = *--e; *e = *s; *s++ = c; } return src; } GLOBAL char *strstr(const char *src, const char *ptn) /* STDC */ { /* src : 検索される文字列 */ /* ptn : 探す文字列 */ size_t skp[256]; /* スタックが乏しいならば static にする */ size_t i, j, k, ptnlen, len; int c, tail; const unsigned char *s, *p; assert(src != NULL && ptn != NULL); /* ptn の長さを求める */ p = (const unsigned char *)ptn; while (*p != '\0') p++; ptnlen = (size_t)(p - (const unsigned char*)ptn); if (ptnlen == 0) return (char*)src; p = (const unsigned char *)ptn; s = (const unsigned char *)src; if (ptnlen == 1) { /* 長さ1なら簡単! */ while (*s != '\0') { if (*s == *p) /* 単純に同じ1byteが見つかるまで検索 */ return (char *)s; /* みつかった */ s++; } } else { /* 長さ2以上のとき表引き */ tail = p[ptnlen - 1]; /* 最後の文字(1byte) */ /* srcの長さを求める */ while (*s != '\0') s++; len = (size_t)(s - (const unsigned char*)src); if (len == 0) return NULL; s = (const unsigned char *)src; /* skp[]に、その文字が検索文字外のときに次の検索開始位置へスキップするバイト数を設定する */ for (i = 0; i < 256; i++) /* まず256文字すべて不一致の場合として検索データサイズ分のスキップ値を設定 */ skp[i] = ptnlen; for (i = 0; i < ptnlen-1; i++) /* 次に検索データを構成する文字の場合は、その文字より後ろの検索データのバイト数分をスキップにする */ skp[p[i]] = ptnlen - 1 - i; i = ptnlen - 1; /* for文の結果がこの式に等しいから不要 */ /* 指定範囲の検索開始! */ while (i < len) { c = s[i]; /* 検索データの尾穴の1byteをチェックする. */ if (c == tail) { /* ここで違えば、(最大)検索データバイト数は、比較せずスキップできる */ j = ptnlen - 1; /* 同じならば、さらに検索データを後ろから比較する */ k = i; while (p[--j] == s[--k]) { if (j == 0) { /* 検索データの先頭ならば */ return (char *)s + k; /* 見つかった */ } } } i += skp[c]; /* その位置でマッチしなかったので、次の位置までスキップ */ } } /* 見つからなかった */ return NULL; } #if 1 #include char *strdup(const char *s) /* STDC */ { char *m; int l; #if 0 if (s == NULL) l = 1; else #endif l = strlen(s)+1; m = (char *)malloc(l); if (m /*&& s*/) strcpy(m, s); return m; } #endif