str_util.c.svn-base

来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 1,161 行 · 第 1/2 页

SVN-BASE
1,161
字号
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)   The author disclaims copyright to this source code. *//* The most basic things, including string handling functions */#include "base_util.h"#include "str_util.h"#include "str_strsafe.h"/* TODO: should probably be based on MSVC version */#if defined(__GNUC__) || !defined(_WIN32) || (_MSC_VER < 1400)void strcpy_s(char *dst, size_t dstLen, const char *src){    size_t  toCopy;    assert(dst);    assert(src);    assert(dstLen > 0);    if (!dst || !src || dstLen <= 0)        return;    toCopy = strlen(src);    if (toCopy > (dstLen-1))        toCopy = dstLen - 1;    strncpy(dst, src, toCopy);    dst[toCopy] = 0;}#endifchar * str_cat_s(char * dst, size_t dst_cch_size, const char * src){    int len = str_len(dst), count = dst_cch_size - len;    int ret = _snprintf(dst + len, count, "%s", src);    return (ret<count ) ? dst : NULL;}char * str_catn_s(char *dst, size_t dst_cch_size, const char *src, size_t src_cch_size){    int len = str_len(dst);    if (dst_cch_size > len + src_cch_size) {        memcpy(dst + len, src, src_cch_size * sizeof *src);        dst[len] = 0;        return dst;    }    else        return NULL;}void no_op(void){    /* This really is a no-op, just to silence the compiler */}int char_is_ws_or_zero(char c){    switch (c) {        case ' ':        case '\t':        case '\r':        case '\n':        case 0:            return TRUE;    }    return FALSE;}int char_is_ws(char c){    switch (c) {        case ' ':        case '\t':        case '\r':        case '\n':            return TRUE;    }    return FALSE;}int char_is_digit(char c){    if ((c >= '0') && (c <= '9'))        return TRUE;    return FALSE;}int char_is_dir_sep(char c){#ifdef _WIN32    if ('/' == c || '\\' == c) {#else    if (DIR_SEP_CHAR == c) {#endif        return TRUE;    }    else {        return FALSE;    }}/* Concatenate 4 strings. Any string can be NULL.   Caller needs to free() memory. */char *str_cat4(const char *str1, const char *str2, const char *str3, const char *str4){    char *str;    char *tmp;    size_t str1_len = 0;    size_t str2_len = 0;    size_t str3_len = 0;    size_t str4_len = 0;    if (str1)        str1_len = strlen(str1);    if (str2)        str2_len = strlen(str2);    if (str3)        str3_len = strlen(str3);    if (str4)        str4_len = strlen(str4);    str = (char*)zmalloc(str1_len + str2_len + str3_len + str4_len + 1);    if (!str)        return NULL;    tmp = str;    if (str1) {        memcpy(tmp, str1, str1_len);        tmp += str1_len;    }    if (str2) {        memcpy(tmp, str2, str2_len);        tmp += str2_len;    }    if (str3) {        memcpy(tmp, str3, str3_len);        tmp += str3_len;    }    if (str4) {        memcpy(tmp, str4, str1_len);    }    return str;}/* Concatenate 3 strings. Any string can be NULL.   Caller needs to free() memory. */char *str_cat3(const char *str1, const char *str2, const char *str3){    return str_cat4(str1, str2, str3, NULL);}/* Concatenate 2 strings. Any string can be NULL.   Caller needs to free() memory. */char *str_cat(const char *str1, const char *str2){    return str_cat4(str1, str2, NULL, NULL);}char *str_dup(const char *str){    return str_cat4(str, NULL, NULL, NULL);}char *str_dupn(const char *str, size_t str_len_cch){    char *copy;    if (!str)        return NULL;    copy = (char*)malloc(str_len_cch+1);    if (!copy)        return NULL;    memcpy(copy, str, str_len_cch);    copy[str_len_cch] = 0;    return copy;}int str_copyn(char *dst, size_t dst_cch_size, const char *src, size_t src_cch_size){    char *end = dst + dst_cch_size - 1;    if (0 == dst_cch_size) {        if (0 == src_cch_size)            return TRUE;        else            return FALSE;    }    while ((dst < end) && (src_cch_size > 0)) {        *dst++ = *src++;        --src_cch_size;    }    *dst = 0;    if (0 == src_cch_size)        return TRUE;    else        return FALSE;}int str_copy(char *dst, size_t dst_cch_size, const char *src){    char *end = dst + dst_cch_size - 1;    if (0 == dst_cch_size)        return FALSE;    while ((dst < end) && *src) {        *dst++ = *src++;    }    *dst = 0;    if (0 == *src)        return TRUE;    else        return FALSE;}int str_eq(const char *str1, const char *str2){    if (!str1 && !str2)        return TRUE;    if (!str1 || !str2)        return FALSE;    if (0 == strcmp(str1, str2))        return TRUE;    return FALSE;}int str_ieq(const char *str1, const char *str2){    if (!str1 && !str2)        return TRUE;    if (!str1 || !str2)        return FALSE;    if (0 == _stricmp(str1, str2))        return TRUE;    return FALSE;}int str_eqn(const char *str1, const char *str2, int len){    if (!str1 && !str2)        return TRUE;    if (!str1 || !str2)        return FALSE;    if (0 == strncmp(str1, str2, len))        return TRUE;    return FALSE;}/* return true if 'str' starts with 'txt', case-sensitive */int  str_startswith(const char *str, const char *txt){    if (!str && !txt)        return TRUE;    if (!str || !txt)        return FALSE;    if (0 == strncmp(str, txt, strlen(txt)))        return TRUE;    return FALSE;}/* return true if 'str' starts with 'txt', NOT case-sensitive */int  str_startswithi(const char *str, const char *txt){    if (!str && !txt)        return TRUE;    if (!str || !txt)        return FALSE;    if (0 == _strnicmp(str, txt, strlen(txt)))        return TRUE;    return FALSE;}int str_endswith(const char *txt, const char *end){    size_t end_len;    size_t txt_len;    if (!txt || !end)        return FALSE;    txt_len = strlen(txt);    end_len = strlen(end);    if (end_len > txt_len)        return FALSE;    if (str_eq(txt+txt_len-end_len, end))        return TRUE;    return FALSE;}int str_endswithi(const char *txt, const char *end){    size_t end_len;    size_t txt_len;    if (!txt || !end)        return FALSE;    txt_len = strlen(txt);    end_len = strlen(end);    if (end_len > txt_len)        return FALSE;    if (str_ieq(txt+txt_len-end_len, end))        return TRUE;    return FALSE;}int str_endswith_char(const char *str, char c){    char end[2];    end[0] = c;    end[1] = 0;    return str_endswith(str, end);}int str_empty(const char *str){    if (!str)        return TRUE;    if (0 == *str)        return TRUE;    return FALSE;}/* Find character 'c' in string 'txt'.   Return pointer to this character or NULL if not found */const char *str_find_char(const char *txt, char c){    while (*txt != c) {        if (0 == *txt)            return NULL;        ++txt;    }    return txt;}/* split a string '*txt' at the border character 'c'. Something like python's   string.split() except called iteratively.   Returns a copy of the string (must be free()d by the caller).   Returns NULL to indicate there's no more items. */char *str_split_iter(char **txt, char c){    const char *tmp;    const char *pos;    char *result;    tmp = (const char*)*txt;    if (!tmp)        return NULL;    pos = str_find_char(tmp, c);    if (pos) {         result = str_dupn(tmp, (int)(pos-tmp));         *txt = (char*)pos+1;    } else {        result = str_dup(tmp);        *txt = NULL; /* next iteration will return NULL */    }    return result;}/* Replace all posible versions (Unix, Windows, Mac) of newline character   with 'replace'. Returns newly allocated string with normalized newlines   or NULL if error.   Caller needs to free() the result */char *str_normalize_newline(const char *txt, const char *replace){    size_t          replace_len;    char            c;    char *          result;    const char *    tmp;    char *          tmp_out;    size_t          result_len = 0;    replace_len = strlen(replace);    tmp = txt;    for (;;) {        c = *tmp++;        if (!c)            break;        if (0xa == c) {            /* a single 0xa => Unix */            result_len += replace_len;        } else if (0xd == c) {            if (0xa == *tmp) {                /* 0xd 0xa => dos */                result_len += replace_len;                ++tmp;            }            else {                /* just 0xd => Mac */                result_len += replace_len;            }        } else            ++result_len;    }    if (0 == result_len)        return NULL;    result = (char*)malloc(result_len+1);    if (!result)        return NULL;    tmp_out = result;    for (;;) {        c = *txt++;        if (!c)            break;        if (0xa == c) {            /* a single 0xa => Unix */            memcpy(tmp_out, replace, replace_len);            tmp_out += replace_len;        } else if (0xd == c) {            if (0xa == *txt) {                /* 0xd 0xa => dos */                memcpy(tmp_out, replace, replace_len);                tmp_out += replace_len;                ++txt;            }            else {                /* just 0xd => Mac */                memcpy(tmp_out, replace, replace_len);                tmp_out += replace_len;            }        } else            *tmp_out++ = c;    }    *tmp_out = 0;    return result;}#define WHITE_SPACE_CHARS " \n\t\r"/* Strip all 'to_strip' characters from the beginning of the string.   Does stripping in-place */void str_strip_left(char *txt, const char *to_strip){    char *new_start = txt;    char c;    if (!txt || !to_strip)        return;    for (;;) {        c = *new_start;        if (0 == c)            break;        if (!str_contains(to_strip, c))            break;        ++new_start;    }    if (new_start != txt) {        memmove(txt, new_start, strlen(new_start)+1);    }}/* Strip white-space characters from the beginning of the string.   Does stripping in-place */void str_strip_ws_left(char *txt){    str_strip_left(txt, WHITE_SPACE_CHARS);}void str_strip_right(char *txt, const char *to_strip){    char * new_end;    char   c;    if (!txt || !to_strip)        return;    if (0 == *txt)        return;    /* point at the last character in the string */    new_end = txt + strlen(txt) - 1;    for (;;) {        c = *new_end;        if (!str_contains(to_strip, c))            break;        if (txt == new_end)            break;        --new_end;    }    if (str_contains(to_strip, *new_end))        new_end[0] = 0;    else        new_end[1] = 0;}void str_strip_ws_right(char *txt){    str_strip_right(txt, WHITE_SPACE_CHARS);}void str_strip_both(char *txt, const char *to_strip){    str_strip_left(txt, to_strip);    str_strip_right(txt, to_strip);}void str_strip_ws_both(char *txt){    str_strip_ws_left(txt);    str_strip_ws_right(txt);}#if 0int utf8_eq(const utf8* str1, const utf8* str2){    return str_eq(str1, str2);}int utf8_eqn(const utf8* str1, const utf8* str2, int len){    return str_eqn(str1, str2, len);}int   utf8_copy(utf8 *dst, int dst_size_bytes, utf8* src){    return str_copy(dst, dst_size_bytes, src);}utf8 *utf8_dup(const utf8 *str){    return str_dup(str);}utf8 *utf8_cat4(const utf8 *str1, const utf8 *str2, const utf8 *str3, const utf8 *str4){    return str_cat4(str1, str2, str3, str4);}utf8 *utf8_cat3(const utf8 *str1, const utf8 *str2, const utf8 *str3){    return str_cat4(str1, str2, str3, NULL);}utf8 *utf8_cat(const utf8 *str1, const utf8 *str2){    return str_cat4(str1, str2, NULL, NULL);}int utf8_endswith(const utf8 *str, const utf8 *end){    return str_endswith(str, end);}#endif#define  HEX_NUMBERS "0123456789ABCDEF"static void char_to_hex(unsigned char c, char* buffer){    buffer[0] = HEX_NUMBERS[c / 16];    buffer[1] = HEX_NUMBERS[c % 16];}static int hex_char_to_num(char c){    if ((c >= '0') && (c <= '9'))        return c - '0';    if ((c >= 'a') && (c <= 'f'))        return c - 'a' + 10;    if ((c >= 'A') && (c <= 'F'))        return c - 'A' + 10;    return -1;}int hex_str_decode_byte(const char **txt){    const char *s;    int c1, c2;    if (!txt)         return -1;    s = *txt;    c1 = hex_char_to_num(*s++);    if (-1 == c1)        return -1;    c2 = hex_char_to_num(*s++);    if (-1 == c2)        return -1;    *txt = s;    return (16 * c1) + c2;}/* Convert binary data in <buf> of size <len> to a hex-encoded string */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?