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 + -
显示快捷键?