]> granicus.if.org Git - php/commitdiff
minor performance improvement
authorGreg Beaver <cellog@php.net>
Sun, 15 Jun 2008 23:00:46 +0000 (23:00 +0000)
committerGreg Beaver <cellog@php.net>
Sun, 15 Jun 2008 23:00:46 +0000 (23:00 +0000)
ext/phar/phar.c
ext/phar/phar.phar

index 10df6d4c9bf0d64fdf973c343cacb6a4f0dceb27..04ea0762f81db8bc39248ea145a8b148586cfad8 100644 (file)
@@ -1894,74 +1894,84 @@ char *tsrm_strtok_r(char *s, const char *delim, char **last)
  */
 char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{ */
 {
+       char newpath[MAXPATHLEN];
+       int newpath_len;
        char *ptr, *free_path, *new_phar;
        char *tok;
        int ptr_length, new_phar_len = 1, path_length = *new_len;
 
        if (PHAR_G(cwd_len) && use_cwd && path_length > 2 && path[0] == '.' && path[1] == '/') {
-               free_path = path;
-               new_phar_len = PHAR_G(cwd_len);
-               new_phar = estrndup(PHAR_G(cwd), new_phar_len);
+               newpath_len = PHAR_G(cwd_len);
+               memcpy(newpath, PHAR_G(cwd), newpath_len);
        } else {
-               free_path = path;
-               new_phar = estrndup("/\0", 2);
+               newpath[0] = '/';
+               newpath_len = 1;
+       }
+       ptr = path;
+       if (*ptr == '/') ++ptr;
+       tok = ptr;
+       do {
+               ptr = memchr(ptr, '/', path_length - (ptr - path));
+       } while (ptr && ptr - tok == 0 && *ptr == '/' && ++ptr && ++tok);
+       if (!ptr && (path_length - (tok - path))) {
+               switch (path_length - (tok - path)) {
+                       case 1 :
+                               if (*tok == '.') {
+                                       efree(path);
+                                       *new_len = 1;
+                                       return estrndup("/", 1);
+                               }
+                               break;
+                       case 2 :
+                               if (tok[0] == '.' && tok[1] == '.') {
+                                       efree(path);
+                                       *new_len = 1;
+                                       return estrndup("/", 1);
+                               }
+               }
+               return path;
        }
-       tok = NULL;
-       ptr = tsrm_strtok_r(path, "/", &tok);
        while (ptr) {
-               ptr_length = strlen(ptr);
-
-               if (IS_DIRECTORY_UP(ptr, ptr_length)) {
-                       char save;
-
-                       save = '/';
-
-#define PREVIOUS new_phar[new_phar_len - 1]
+               ptr_length = ptr - tok;
+last_time:
+               if (IS_DIRECTORY_UP(tok, ptr_length)) {
+#define PREVIOUS newpath[newpath_len - 1]
 
-                       while (new_phar_len > 1 &&
-                                       !IS_BACKSLASH(PREVIOUS)) {
-                               save = PREVIOUS;
-                               PREVIOUS = '\0';
-                               new_phar_len--;
+                       while (newpath_len > 1 && !IS_BACKSLASH(PREVIOUS)) {
+                               newpath_len--;
                        }
 
-                       if (new_phar[0] != '/') {
-                               new_phar[new_phar_len++] = save;
-                               new_phar[new_phar_len] = '\0';
-                       } else if (new_phar_len > 1) {
-                               PREVIOUS = '\0';
-                               new_phar_len--;
+                       if (newpath[0] != '/') {
+                               newpath[newpath_len] = '\0';
+                       } else if (newpath_len > 1) {
+                               --newpath_len;
                        }
-               } else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
-                       if (new_phar_len > 1) {
-                               new_phar = (char *) erealloc(new_phar, new_phar_len+ptr_length+1+1);
-                               new_phar[new_phar_len++] = '/';
-                               memcpy(&new_phar[new_phar_len], ptr, ptr_length+1);
+               } else if (!IS_DIRECTORY_CURRENT(tok, ptr_length)) {
+                       if (newpath_len > 1) {
+                               newpath[newpath_len++] = '/';
+                               memcpy(newpath + newpath_len, tok, ptr_length+1);
                        } else {
-                               new_phar = (char *) erealloc(new_phar, new_phar_len+ptr_length+1);
-                               memcpy(&new_phar[new_phar_len], ptr, ptr_length+1);
+                               memcpy(newpath + newpath_len, tok, ptr_length+1);
                        }
 
-                       new_phar_len += ptr_length;
+                       newpath_len += ptr_length;
+               }
+               if (ptr == path + path_length) {
+                       break;
+               }
+               tok = ++ptr;
+               do {
+                       ptr = memchr(ptr, '/', path_length - (ptr - path));
+               } while (ptr && ptr - tok == 0 && *ptr == '/' && ++ptr && ++tok);
+               if (!ptr && (path_length - (tok - path))) {
+                       ptr_length = path_length - (tok - path);
+                       ptr = path + path_length;
+                       goto last_time;
                }
-               ptr = tsrm_strtok_r(NULL, "/", &tok);
-       }
-
-       if (path[path_length-1] == '/' && new_phar_len > 1) {
-               new_phar = (char*)erealloc(new_phar, new_phar_len + 2);
-               new_phar[new_phar_len++] = '/';
-               new_phar[new_phar_len] = 0;
-       }
-
-       efree(free_path);
-
-       if (new_phar_len == 0) {
-               new_phar = (char *) erealloc(new_phar, new_phar_len+1+1);
-               new_phar[new_phar_len] = '/';
-               new_phar[++new_phar_len] = '\0';
        }
-       *new_len = new_phar_len;
-       return new_phar;
+       efree(path);
+       *new_len = newpath_len;
+       return estrndup(newpath, newpath_len);
 }
 /* }}} */
 
index d45774867a5873f52758a63f09eb3ecd078756ac..e6e523773e86d2d4c0b377676f21a0d54142f0c0 100755 (executable)
Binary files a/ext/phar/phar.phar and b/ext/phar/phar.phar differ