bug#1205: [BusyBox] bug#1205: mount handles links differently in 0.60

Vladimir N. Oleynik dzo at simtreas.ru
Thu Aug 9 11:45:02 UTC 2001


Matt Kraai wrote:
> 
> On Thu, Aug 09, 2001 at 05:46:15PM +0400, Vladimir N. Oleynik wrote:
> > Manuel.
> > As a result of this not so beautiful dispute the beautiful idea was born: look
> > at realization strcpy_overlap() from this text. It is full analogue Uclibc
> > strcpy() but on
> > 14 bytes less (noninline - 10 bytes less :-0 ).
> >
> > Matt.
> > Result more on these bytes (the total difference with your variant makes 66
> > bytes and my variant seems to me much faster thanking inline "special" strcpy).
> 
> By simplifying the code to remove extra slashes, and using your
> new function, the following simplify_path is 17 bytes smaller than
> yours (when compiled on busybox.net with -Os).

Thank for new stimulus. 6 bytes I have made a difference, but it was necessary
to renounce
as well as to you in the speed - to remove dual slashsc for once instead of all
in
succession going.
;-))

--w
vodz
-------------- next part --------------
#include "libbb/libbb.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

/* Matt suggestion: strcpy rescue use with overlap */
static inline char *strcpy_overlap(char *dst, const char *src)
{
	char *ptr = dst;

	do *dst++ = *src; while (*src++);
	return ptr;
}

#ifdef MATT

#if 0
/* Chop out LEN bytes of a string, starting at S.  */
static void strchop(char *s, size_t len)
{
       memmove(s, s + len, strlen(s + len) + 1);
}
#endif
#define strchop(S, LEN) strcpy_overlap((S), (S) + (LEN))

/* Change PATH to an absolute path, remove duplicate and trailing
 * slashes, and eliminate `.' and `..' components.  */
char *simplify_path(const char *path)
{
       char *s;
       int i, j;

       /* Make the pathname absolute.  */
       if (path[0] == '/')
	       s = xstrdup(path);
       else {
	       char *cwd = xgetcwd(NULL);
	       s = concat_path_file(cwd, path);
	       free(cwd);
       }

       for (i = 0; s[i] != '\0'; i++) {
	       if (s[i] == '/') {
		       /* Strip extra slashes.  */
		       if (s[i+1] == '/') {
			       strchop(s+i+1, 1);
			       i--;
		       /* Strip the trailing slash.  */
		       } else if (i != 0 && s[i+1] == '\0')
			       s[i] = '\0';
		       else if (s[i+1] == '.') {
			       /* Remove `.' components.  */
			       if (s[i+2] == '\0' || s[i+2] == '/') {
				       strchop(s+i+1, 1);
				       i--;
			       /* Remove `..' components.  */
			       } else if (s[i+2] == '.' && (s[i+3] == '\0' || s[i+3] == '/')) {
				       for (j = i - 1; 0 < j && s[j] != '/'; j--)
					       /* Loop.  */;
				       if (j < 0)
					       j = 0;
				       strchop(s+j+1, (i - j) + 2);
				       i = j - 1;
			       }
		       }
	       }
       }

       return s;
}

#else

char *simplify_path(const char *path)
{
	char *s, *start, *next;

	if (path[0] == '/')
	       start = xstrdup(path);
	else {
	       s = xgetcwd(NULL);
	       start = concat_path_file(s, path);
	       free(s);
	}
	s = start;
	/* remove . and .. */
	while(*s) {
		if(*s++ == '/' && (*s == '/' || (*s == 0 && s!=(start+1)))) {
			/* remove duplicate and trailing slashes */
			s = strcpy_overlap(s-1, s);
		}
		else if(*(s-1) == '.' && *(s-2)=='/') {
			if(*s == '/' || *s == 0) {
				/* remove . */
				s = strcpy_overlap(s-1, s); /* maybe set // */
				s--;
			}
			else if(*s == '.' && (*(s+1) == '/' || *(s+1) == 0)) {
				/* remove "dir/.." */
				next = s+1;     /* set after ".." */
				/* skip previous slashes */
				for(s -= 2; s>start && *s == '/'; s--)
					;
				/* skip previous dir */
				while(*s != '/') s--;
				/* remove previous dir */
				strcpy_overlap(s, next);  /* maybe set // */
			}
		}
	}
	return start;
}
#endif

const char *applet_name = "sla";

int main(void)
{
	char buf[80];
	char *s;
	int l;

	for(;;) {
		printf("test => ");
		if(fgets(buf, 80, stdin)==NULL)
			return 0;
		l = strlen(buf);
		if(l<=1)
			return 0;
		buf[l-1]=0;
		s = simplify_path(buf);
		printf("path => %s\n", s);
		free(s);
	}
}


More information about the busybox mailing list