📄 util_str.c
字号:
while (lp <= ls && (p = strstr_m(s,pattern))) { if (ls + (li-lp) >= len) { DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), pattern, (int)len)); break; } if (li != lp) { memmove(p+li,p+lp,strlen(p+lp)+1); } memcpy(p, insert, li); s = p + li; ls += (li-lp); }}/** Similar to all_string_sub but for unicode strings. Return a new allocated unicode string. similar to string_sub() but allows for any character to be substituted. Use with caution!**/static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern, const smb_ucs2_t *insert){ smb_ucs2_t *r, *rp; const smb_ucs2_t *sp; size_t lr, lp, li, lt; if (!insert || !pattern || !*pattern || !s) return NULL; lt = (size_t)strlen_w(s); lp = (size_t)strlen_w(pattern); li = (size_t)strlen_w(insert); if (li > lp) { const smb_ucs2_t *st = s; int ld = li - lp; while ((sp = strstr_w(st, pattern))) { st = sp + lp; lt += ld; } } r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1); if (!r) { DEBUG(0, ("all_string_sub_w: out of memory!\n")); return NULL; } while ((sp = strstr_w(s, pattern))) { memcpy(rp, s, (sp - s)); rp += ((sp - s) / sizeof(smb_ucs2_t)); memcpy(rp, insert, (li * sizeof(smb_ucs2_t))); s = sp + lp; rp += li; } lr = ((rp - r) / sizeof(smb_ucs2_t)); if (lr < lt) { memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t))); rp += (lt - lr); } *rp = 0; return r;}smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern, const char *insert){ wpstring p, i; if (!insert || !pattern || !s) return NULL; push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE); push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE); return all_string_sub_w(s, p, i);}#if 0/** Splits out the front and back at a separator.**/static void split_at_last_component(char *path, char *front, char sep, char *back){ char *p = strrchr_m(path, sep); if (p != NULL) *p = 0; if (front != NULL) pstrcpy(front, path); if (p != NULL) { if (back != NULL) pstrcpy(back, p+1); *p = '\\'; } else { if (back != NULL) back[0] = 0; }}#endif/** Write an octal as a string.**/const char *octal_string(int i){ static char ret[64]; if (i == -1) return "-1"; slprintf(ret, sizeof(ret)-1, "0%o", i); return ret;}/** Truncate a string at a specified length.**/char *string_truncate(char *s, unsigned int length){ if (s && strlen(s) > length) s[length] = 0; return s;}/** Strchr and strrchr_m are very hard to do on general multi-byte strings. We convert via ucs2 for now.**/char *strchr_m(const char *src, char c){ wpstring ws; pstring s2; smb_ucs2_t *p; const char *s; /* characters below 0x3F are guaranteed to not appear in non-initial position in multi-byte charsets */ if ((c & 0xC0) == 0) { return strchr(src, c); } /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { if (*s == c) return (char *)s; } if (!*s) return NULL;#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS /* With compose characters we must restart from the beginning. JRA. */ s = src;#endif push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); p = strchr_w(ws, UCS2_CHAR(c)); if (!p) return NULL; *p = 0; pull_ucs2_pstring(s2, ws); return (char *)(s+strlen(s2));}char *strrchr_m(const char *s, char c){ /* characters below 0x3F are guaranteed to not appear in non-initial position in multi-byte charsets */ if ((c & 0xC0) == 0) { return strrchr(s, c); } /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars). Also, in Samba we only search for ascii characters in 'c' and that in all mb character sets with a compound character containing c, if 'c' is not a match at position p, then p[-1] > 0x7f. JRA. */ { size_t len = strlen(s); const char *cp = s; BOOL got_mb = False; if (len == 0) return NULL; cp += (len - 1); do { if (c == *cp) { /* Could be a match. Part of a multibyte ? */ if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) { /* Yep - go slow :-( */ got_mb = True; break; } /* No - we have a match ! */ return (char *)cp; } } while (cp-- != s); if (!got_mb) return NULL; } /* String contained a non-ascii char. Slow path. */ { wpstring ws; pstring s2; smb_ucs2_t *p; push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); p = strrchr_w(ws, UCS2_CHAR(c)); if (!p) return NULL; *p = 0; pull_ucs2_pstring(s2, ws); return (char *)(s+strlen(s2)); }}/*********************************************************************** Return the equivalent of doing strrchr 'n' times - always going backwards.***********************************************************************/char *strnrchr_m(const char *s, char c, unsigned int n){ wpstring ws; pstring s2; smb_ucs2_t *p; push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); p = strnrchr_w(ws, UCS2_CHAR(c), n); if (!p) return NULL; *p = 0; pull_ucs2_pstring(s2, ws); return (char *)(s+strlen(s2));}/*********************************************************************** strstr_m - We convert via ucs2 for now.***********************************************************************/char *strstr_m(const char *src, const char *findstr){ smb_ucs2_t *p; smb_ucs2_t *src_w, *find_w; const char *s; char *s2; char *retp; size_t findstr_len = 0; /* for correctness */ if (!findstr[0]) { return (char*)src; } /* Samba does single character findstr calls a *lot*. */ if (findstr[1] == '\0') return strchr_m(src, *findstr); /* We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { if (*s == *findstr) { if (!findstr_len) findstr_len = strlen(findstr); if (strncmp(s, findstr, findstr_len) == 0) { return (char *)s; } } } if (!*s) return NULL;#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */ /* 'make check' fails unless we do this */ /* With compose characters we must restart from the beginning. JRA. */ s = src;#endif if (push_ucs2_allocate(&src_w, src) == (size_t)-1) { DEBUG(0,("strstr_m: src malloc fail\n")); return NULL; } if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) { SAFE_FREE(src_w); DEBUG(0,("strstr_m: find malloc fail\n")); return NULL; } p = strstr_w(src_w, find_w); if (!p) { SAFE_FREE(src_w); SAFE_FREE(find_w); return NULL; } *p = 0; if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) { SAFE_FREE(src_w); SAFE_FREE(find_w); DEBUG(0,("strstr_m: dest malloc fail\n")); return NULL; } retp = (char *)(s+strlen(s2)); SAFE_FREE(src_w); SAFE_FREE(find_w); SAFE_FREE(s2); return retp;}/** Convert a string to lower case.**/void strlower_m(char *s){ size_t len; int errno_save; /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ while (*s && !(((unsigned char)s[0]) & 0x80)) { *s = tolower_ascii((unsigned char)*s); s++; } if (!*s) return; /* I assume that lowercased string takes the same number of bytes * as source string even in UTF-8 encoding. (VIV) */ len = strlen(s) + 1; errno_save = errno; errno = 0; unix_strlower(s,len,s,len); /* Catch mb conversion errors that may not terminate. */ if (errno) s[len-1] = '\0'; errno = errno_save;}/** Convert a string to upper case.**/void strupper_m(char *s){ size_t len; int errno_save; /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ while (*s && !(((unsigned char)s[0]) & 0x80)) { *s = toupper_ascii((unsigned char)*s); s++; } if (!*s) return; /* I assume that lowercased string takes the same number of bytes * as source string even in multibyte encoding. (VIV) */ len = strlen(s) + 1; errno_save = errno; errno = 0; unix_strupper(s,len,s,len); /* Catch mb conversion errors that may not terminate. */ if (errno) s[len-1] = '\0'; errno = errno_save;}/** Return a RFC2254 binary string representation of a buffer. Used in LDAP filters. Caller must free.**/char *binary_string(char *buf, int len){ char *s; int i, j; const char *hex = "0123456789ABCDEF"; s = SMB_MALLOC(len * 3 + 1); if (!s) return NULL; for (j=i=0;i<len;i++) { s[j] = '\\'; s[j+1] = hex[((unsigned char)buf[i]) >> 4]; s[j+2] = hex[((unsigned char)buf[i]) & 0xF]; j += 3; } s[j] = 0; return s;}/** Just a typesafety wrapper for snprintf into a pstring.**/ int pstr_sprintf(pstring s, const char *fmt, ...){ va_list ap; int ret; va_start(ap, fmt); ret = vsnprintf(s, PSTRING_LEN, fmt, ap); va_end(ap); return ret;}/** Just a typesafety wrapper for snprintf into a fstring.**/int fstr_sprintf(fstring s, const char *fmt, ...){ va_list ap; int ret; va_start(ap, fmt); ret = vsnprintf(s, FSTRING_LEN, fmt, ap); va_end(ap); return ret;}#if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)/** Some platforms don't have strndup.**/#if defined(PARANOID_MALLOC_CHECKER)#undef strndup#endif char *strndup(const char *s, size_t n){ char *ret; n = strnlen(s, n); ret = SMB_MALLOC(n+1); if (!ret) return NULL; memcpy(ret, s, n); ret[n] = 0; return ret;}#if defined(PARANOID_MALLOC_CHECKER)#define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY#endif#endif#if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)/** Some platforms don't have strnlen**/ size_t strnlen(const char *s, size_t n){ size_t i; for (i=0; i<n && s[i] != '\0'; i++) /* noop */ ; return i;}#endif/** List of Strings manipulation functions**/#define S_LIST_ABS 16 /* List Allocation Block Size */char **str_list_make(const char *string, const char *sep){ char **list, **rlist; const char *str; char *s; int num, lsize; pstring tok; if (!string || !*string) return NULL; s = SMB_STRDUP(string); if (!s) { DEBUG(0,("str_list_make: Unable to allocate memory")); return NULL; } if (!sep) sep = LIST_SEP; num = lsize = 0; list = NULL; str = s; while (next_token(&str, tok, sep, sizeof(tok))) { if (num == lsize) { lsize += S_LIST_ABS; rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1); if (!rlist) { DEBUG(0,("str_list_make: Unable to allocate memory")); str_list_free(&list); SAFE_FREE(s); return NULL; } else list = rlist; memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1))); } list[num] = SMB_STRDUP(tok); if (!list[num]) { DEBUG(0,("str_list_make: Unable to allocate memory")); str_list_free(&list); SAFE_FREE(s); return NULL; } num++; } SAFE_FREE(s); return list;}BOOL str_list_copy(char ***dest, const char **src){ char **list, **rlist; int num, lsize; *dest = NULL; if (!src) return False; num = lsize = 0; list = NULL; while (src[num]) { if (num == lsize) { lsize += S_LIST_ABS; rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1); if (!rlist) { DEBUG(0,("str_list_copy: Unable to re-allocate memory")); str_list_free(&list); return False; } else list = rlist; memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1))); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -