示例#1
0
struct pathnode *
relpath(struct pathnode *f, struct pathnode *t)
{
	struct pathnode *p = f;
	struct pathnode *q = t;	
	struct pathnode *r;	
	struct pathnode root;	

	/* We deal only with proper path-roots */
	if (f == NULL || t == NULL)
		return NULL;
	
	while (p->next != NULL &&
	       q->next != NULL &&
	       strcmp((p->next)->name, (q->next)->name) == 0) {
		p = p->next;
		q = q->next;
	}

	root.next = NULL;
	r = &root;
	while (p->next != NULL) {
		r->next = palloc();
		(r->next)->prev = r;
		r = r->next;
		r->name = strdup("..");
		r->next = NULL;
		p = p->next;
	}
	
	pathcopy(q->next,r);
	if (! root.next) {
		/*
		 * The two paths are the same, the relative path in between
		 * is NULL.
		 * We rather add a simple dot component and refrain from using
		 * NULL paths.
		 */
		r = palloc();
		root.next = r;
		r->name = strdup(".");
		r->next = NULL;
	}
	root.next->prev = NULL;
	return root.next;
}
示例#2
0
void
pathcopy(struct pathnode *f, struct pathnode *t)
{
	struct pathnode *p = palloc();

	if (f == NULL) {
		t->next = NULL;
		return;
	}
	p->prev = t;
	p->next = NULL;
	p->name = strdup(f->name);

	t->next = p;
	
	if ((f->next) != NULL)
		pathcopy(f->next,p);
}
示例#3
0
文件: path.c 项目: mytchel/bom
struct path *
strtopath(struct path *p, const char *str)
{
  struct path *path, *n;
  int i, j;

  if (str[0] == '/' || p == nil) {
    path = p = nil;
  } else {
    path = pathcopy(p);
    if (path == nil) {
      return nil;
    }
    
    for (p = path; p != nil && p->next != nil; p = p->next)
      ;
  }

  while (*str != 0) {
    for (i = 0; str[i] != 0 && str[i] != '/'; i++)
      ;

    if (i == 0) {
      str += 1;
      continue;
    } else if (i >= NAMEMAX) {
      pathfree(path);
      return nil;
    }

    if (str[0] == '.') {
      if (str[1] == '.' && i == 2) {
	/* Remove current and prev */

	if (p == nil) {
	  str += 2;
	  continue;
	} 

	n = p;

	if (p == path) {
	  path = p->prev;
	}

	p = p->prev;
	if (p != nil) {
	  p->next = nil;
	}

	lock(&pathalloc.lock);
	n->next = pathalloc.free;
	pathalloc.free = n;
	unlock(&pathalloc.lock);

	str += 2;
	continue;
      } else if (i == 1) {
	/* Remove current */
	str += 1;
	continue;
      }
    }

    lock(&pathalloc.lock);

    n = pathalloc.free;
    if (n == nil) {
      n = malloc(sizeof(struct path));
      if (n == nil) {
	pathfree(path);
	return nil;
      }
    } else {
      pathalloc.free = n->next;
    }

    unlock(&pathalloc.lock);
	
    for (j = 0; j < i; j++)
      n->s[j] = str[j];

    n->s[j] = 0;

    n->next = nil;
    n->prev = p;
    if (p != nil) {
      p->next = n;
    } else {
      path = n;
    }

    p = n;
    str += i;
  }

  return path;
}