On 8/17/05, Linus Torvalds <[EMAIL PROTECTED]> wrote:
> NOTE! This does _not_ handle ".." or "." in the _middle_ of a pathspec. If
> you have people who do

BTW, could this (below) be useful for something?

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

// an analog of "cd path" from a directory "cwd".
char* pathexpand(const char* cwd, const char* path)
{
    static const char SEP[] = "/";
    if ( !*path ) // empty path -> "." (don't move)
        path = ".";
    if ( !*cwd || *SEP == *path ) // no cwd, or path begins with "/"
        cwd = SEP;

    int len = strlen(cwd);
    char* out = (char*)malloc(len + 1 + strlen(path) + 1);
    char* p = strcpy(out, cwd) + len;

    if ( *SEP != p[-1] )
        *p++ = *SEP;

    for ( ; *path; ++path )
    {
        char * pl = p;
        while ( *path && *SEP != *path )
            *p++ = *path++;
        *p = '\0';

        if ( p == pl ) /* ..."//"... */
            ; // just ignore

        /* ..."/./"...  */
        else if ( p - pl == 1 && '.' == *pl )
            --p; // just ignore

        /* ..."/../"...  */
        else if ( p - pl == 2 && '.' == pl[0] && '.' == pl[1] )
        {
            // drop last element of the resulting path
            if ( --pl > out )
                for ( --pl; pl > out && *SEP != *pl; --pl );
            p = ++pl;
        }
        /* ..."/path/"...  */
        else if ( *path )
            *p++ = *path; // just add the separator
        if ( !*path )
            break;
    }
    if ( p > out+1 && *SEP == p[-1] )
        --p;
    *p = '\0';
    return out;
}

#ifdef CHECK_PATHEXPAND
static void check(const char * cwd, const char * path, const char * good)
{
    static int n = 0;
    printf("%-2d: %s$ cd %s", ++n, cwd, path);
    char* t = pathexpand(cwd, path);
    if ( strcmp(t, good) )
        printf(" failed(%s)\n", t);
    else
        printf(" \t\t%s\n", t);
    free(t);
}

int main(int argc, char** argv)
{
    /* 1 */ check("/onelevel", "aa", "/onelevel/aa");
    /* 2 */ check("/", "..", "/");
    /* 3 */ check("/", "../..", "/");
    /* 4 */ check("/one", "aa/../bb", "/one/bb");
    /* 5 */ check("/one/two", "aa//bb", "/one/two/aa/bb");
    /* 6 */ check("", "/aa//bb", "/aa/bb");
    /* 7 */ check("/one/two", "", "/one/two");
    /* 8 */ check("/one/two", "aa/..bb/x/../cc/", "/one/two/aa/..bb/cc");
    /* 9 */ check("/one/two", "aa/x/././cc////", "/one/two/aa/x/cc");
    /* 10 */ check("/one/two", "../../../../aa", "/aa");

    return 0;
}
#endif
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to