summaryrefslogtreecommitdiffstats
path: root/source/lib
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-09-05 19:59:55 +0000
committerJeremy Allison <jra@samba.org>2003-09-05 19:59:55 +0000
commitf35e9a8b909d3c74be47083ccc4a4e91a14938db (patch)
tree94bec8e4eb1017cd886adae1518c8ffe2d47ee4f /source/lib
parent3913e43724870c62a0d77ec3e73cbe9480cb6247 (diff)
downloadsamba-f35e9a8b909d3c74be47083ccc4a4e91a14938db.tar.gz
samba-f35e9a8b909d3c74be47083ccc4a4e91a14938db.tar.xz
samba-f35e9a8b909d3c74be47083ccc4a4e91a14938db.zip
More tuning from cachegrind. Change most trim_string() calls to trim_char(0,
as that's what they do. Fix string_replace() to fast-path ascii. Jeremy.
Diffstat (limited to 'source/lib')
-rw-r--r--source/lib/charcnv.c6
-rw-r--r--source/lib/substitute.c6
-rw-r--r--source/lib/util.c68
-rw-r--r--source/lib/util_str.c75
4 files changed, 81 insertions, 74 deletions
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index a07ff7399d9..ceb9d57fc71 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -879,9 +879,8 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_
}
if (flags & STR_TERMINATE) {
- if (src_len == (size_t)-1) {
- src_len = strlen_w(src)*2 + 2;
- } else {
+ /* src_len -1 is the default for null terminated strings. */
+ if (src_len != (size_t)-1) {
size_t len = strnlen_w(src, src_len/2);
if (len < src_len/2)
len++;
@@ -1051,4 +1050,3 @@ size_t align_string(const void *base_ptr, const char *p, int flags)
}
return 0;
}
-
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index a73f9d85dab..28466e43f29 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -57,7 +57,7 @@ void set_local_machine_name(const char* local_name, BOOL perm)
already_perm = perm;
fstrcpy(tmp_local_machine,local_name);
- trim_string(tmp_local_machine," "," ");
+ trim_char(tmp_local_machine,' ',' ');
alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
strlower_m(local_machine);
}
@@ -79,7 +79,7 @@ void set_remote_machine_name(const char* remote_name, BOOL perm)
already_perm = perm;
fstrcpy(tmp_remote_machine,remote_name);
- trim_string(tmp_remote_machine," "," ");
+ trim_char(tmp_remote_machine,' ',' ');
alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
strlower_m(remote_machine);
}
@@ -111,7 +111,7 @@ void sub_set_smb_name(const char *name)
return;
fstrcpy(tmp,name);
- trim_string(tmp," "," ");
+ trim_char(tmp,' ',' ');
strlower_m(tmp);
alpha_strcpy(smb_user_name,tmp,SAFE_NETBIOS_CHARS,sizeof(smb_user_name)-1);
}
diff --git a/source/lib/util.c b/source/lib/util.c
index 5f4fae9baa2..766c5041b4e 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -261,7 +261,7 @@ BOOL init_names(void)
}
fstrcpy( local_machine, global_myname() );
- trim_string( local_machine, " ", " " );
+ trim_char( local_machine, ' ', ' ' );
p = strchr( local_machine, ' ' );
if (p)
*p = 0;
@@ -605,68 +605,6 @@ void unix_clean_name(char *s)
trim_string(s,NULL,"/..");
}
-/*******************************************************************
- Convert '\' to '/'.
- Reduce a file name, removing or reducing /../ , /./ , // elements.
- Remove also any trailing . and /
- Return a new allocated string.
-********************************************************************/
-
-smb_ucs2_t *unix_clean_path(const smb_ucs2_t *s)
-{
- smb_ucs2_t *ns;
- smb_ucs2_t *p, *r, *t;
-
- DEBUG(3, ("unix_clean_path\n")); /* [%unicode]\n")); */
- if(!s)
- return NULL;
-
- /* convert '\' to '/' */
- ns = strdup_w(s);
- if (!ns)
- return NULL;
- unix_format_w(ns);
-
- /* remove all double slashes */
- p = ns;
- ns = all_string_sub_wa(p, "//", "/");
- SAFE_FREE(p);
- if (!ns)
- return NULL;
-
- /* remove any /./ */
- p = ns;
- ns = all_string_sub_wa(p, "/./", "/");
- SAFE_FREE(p);
- if (!ns)
- return NULL;
-
- /* reduce any /../ */
- t = ns;
- while (*t && (r = strstr_wa(t, "/.."))) {
- t = &(r[3]);
- if (*t == UCS2_CHAR('/') || *t == 0) {
- *r = 0;
- p = strrchr_w(ns, UCS2_CHAR('/'));
- if (!p)
- p = ns;
- if (*t == 0)
- *p = 0;
- else
- memmove(p, t, (strlen_w(t) + 1) * sizeof(smb_ucs2_t));
- t = p;
- }
- }
-
- /* remove any leading ./ trailing /. */
- trim_string_wa(ns, "./", "/.");
-
- /* remove any leading and trailing / */
- trim_string_wa(ns, "/", "/");
-
- return ns;
-}
-
/****************************************************************************
Make a dir struct.
****************************************************************************/
@@ -2205,7 +2143,7 @@ char *lock_path(const char *name)
static pstring fname;
pstrcpy(fname,lp_lockdir());
- trim_string(fname,"","/");
+ trim_char(fname,'\0','/');
if (!directory_exist(fname,NULL))
mkdir(fname,0755);
@@ -2225,7 +2163,7 @@ char *pid_path(const char *name)
static pstring fname;
pstrcpy(fname,lp_piddir());
- trim_string(fname,"","/");
+ trim_char(fname,'\0','/');
if (!directory_exist(fname,NULL))
mkdir(fname,0755);
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 70567f88afd..82b312e2415 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -364,9 +364,27 @@ BOOL strisnormal(const char *s)
void string_replace(pstring s,char oldc,char newc)
{
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
+ unsigned char *p;
+
+ /* 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 (p = (unsigned char *)s; *p; p++) {
+ if (*p & 0x80) /* mb string - slow path. */
+ break;
+ if (*p == oldc)
+ *p = newc;
+ }
+
+ if (!*p)
+ return;
+
+ /* Slow (mb) path. */
+ push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
- pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
+ pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
}
/**
@@ -406,6 +424,59 @@ size_t str_ascii_charnum(const char *s)
return strlen(tmpbuf2);
}
+BOOL trim_char(char *s,char cfront,char cback)
+{
+ BOOL ret = False;
+ char *ep;
+ char *fp = s;
+
+ /* Ignore null or empty strings. */
+ if (!s || (s[0] == '\0'))
+ return False;
+
+ if (cfront) {
+ while (*fp && *fp == cfront)
+ fp++;
+ if (!*fp) {
+ /* We ate the string. */
+ s[0] = '\0';
+ return True;
+ }
+ if (fp != s)
+ ret = True;
+ }
+
+ ep = fp + strlen(fp) - 1;
+ if (cback) {
+ /* Attempt ascii only. Bail for mb strings. */
+ while ((ep >= fp) && (*ep == cback)) {
+ ret = True;
+ if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
+ /* Could be mb... bail back to tim_string. */
+ char fs[2], bs[2];
+ if (cfront) {
+ fs[0] = cfront;
+ fs[1] = '\0';
+ }
+ bs[0] = cback;
+ bs[1] = '\0';
+ return trim_string(s, cfront ? fs : NULL, bs);
+ } else {
+ ep--;
+ }
+ }
+ if (ep < fp) {
+ /* We ate the string. */
+ s[0] = '\0';
+ return True;
+ }
+ }
+
+ ep[1] = '\0';
+ memmove(s, fp, ep-fp+2);
+ return ret;
+}
+
/**
Trim the specified elements off the front and back of a string.
**/