Improve splitname memory allocation

We don't need to create a temporary copy of the string if we are smart with
our pointer manipulation and string copying. This saves a bunch of string
duplication during database parsing, both local and sync.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2011-01-19 12:20:32 -06:00
parent 01c8f39ab8
commit c86ff120c8

View file

@ -864,25 +864,23 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg)
* package name can contain hyphens, so parse from the back- go back * package name can contain hyphens, so parse from the back- go back
* two hyphens and we have split the version from the name. * two hyphens and we have split the version from the name.
*/ */
char *tmp, *p, *q; const char *version, *end;
if(target == NULL || pkg == NULL) { if(target == NULL || pkg == NULL) {
return(-1); return(-1);
} }
STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1)); end = target + strlen(target);
p = tmp + strlen(tmp);
/* remove any trailing '/' */ /* remove any trailing '/' */
while (*(p - 1) == '/') { while (*(end - 1) == '/') {
--p; --end;
*p = '\0';
} }
/* do the magic parsing- find the beginning of the version string /* do the magic parsing- find the beginning of the version string
* by doing two iterations of same loop to lop off two hyphens */ * by doing two iterations of same loop to lop off two hyphens */
for(q = --p; *q && *q != '-'; q--); for(version = end - 1; *version && *version != '-'; version--);
for(p = --q; *p && *p != '-'; p--); for(version = version - 1; *version && *version != '-'; version--);
if(*p != '-' || p == tmp) { if(*version != '-' || version == target) {
return(-1); return(-1);
} }
@ -890,16 +888,17 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg)
if(pkg->version) { if(pkg->version) {
FREE(pkg->version); FREE(pkg->version);
} }
STRDUP(pkg->version, p+1, RET_ERR(PM_ERR_MEMORY, -1)); /* version actually points to the dash, so need to increment 1 and account
/* insert a terminator at the end of the name (on hyphen)- then copy it */ * for potential end character */
*p = '\0'; STRNDUP(pkg->version, version + 1, end - version - 1,
RET_ERR(PM_ERR_MEMORY, -1));
if(pkg->name) { if(pkg->name) {
FREE(pkg->name); FREE(pkg->name);
} }
STRDUP(pkg->name, tmp, RET_ERR(PM_ERR_MEMORY, -1)); STRNDUP(pkg->name, target, version - target, RET_ERR(PM_ERR_MEMORY, -1));
pkg->name_hash = _alpm_hash_sdbm(pkg->name); pkg->name_hash = _alpm_hash_sdbm(pkg->name);
free(tmp);
return(0); return(0);
} }