00001 #include "labels.hh"
00002 #include "compatibility.hh"
00003
00004
00005
00019 Sym PATHROOT = symbol ("/");
00020 Tree pathRoot() { return tree(PATHROOT); }
00021 bool isPathRoot(Tree t) { return isTree(t, PATHROOT); }
00022
00023 Sym PATHPARENT = symbol ("..");
00024 Tree pathParent() { return tree(PATHPARENT); }
00025 bool isPathParent(Tree t) { return isTree(t, PATHPARENT); }
00026
00027 Sym PATHCURRENT = symbol (".");
00028 Tree pathCurrent() { return tree(PATHCURRENT); }
00029 bool isPathCurrent(Tree t) { return isTree(t, PATHCURRENT); }
00030
00031
00032
00037 static Tree encodeName(char g, const string& name)
00038 {
00039 switch (g) {
00040 case 'v':
00041 case 'V': return cons(tree(0), tree(name));
00042
00043 case 'h':
00044 case 'H': return cons(tree(1), tree(name));
00045
00046 case 't':
00047 case 'T': return cons(tree(2), tree(name));
00048
00049 default : return cons(tree(0), tree(name));
00050 }
00051 }
00052
00053
00058 static Tree label2path(const char* label)
00059 {
00060 if (label[0] == 0) {
00061 return cons(tree(""), nil);
00062
00063 } else if (label[0] == '/') {
00064 return cons(pathRoot(), label2path(&label[1]));
00065
00066 } else if ((label[0] == '.') && (label[1] == '/')) {
00067 return label2path(&label[2]);
00068
00069 } else if ((label[0] == '.') && (label[1] == '.') && (label[2] == '/')) {
00070 return cons(pathParent(), label2path(&label[3]));
00071
00072 } else if (label[1] == ':') {
00073 char g = label[0];
00074 string s;
00075 int i = 2;
00076 while ((label[i] != 0) && (label[i] != '/')) {
00077 s.push_back(label[i]);
00078 i++;
00079 }
00080 if (label[i] == '/') i++;
00081 return cons(encodeName(g,s), label2path(&label[i]));
00082
00083 } else {
00084 return cons(tree(label),nil);
00085 }
00086 }
00087
00088
00095 static Tree concatPath(Tree relpath, Tree abspath)
00096 {
00097 if (isList(relpath)) {
00098 Tree head = hd(relpath);
00099 if (isPathRoot(head)) {
00100 return concatPath(tl(relpath), nil);
00101 } else if (isPathParent(head)) {
00102 if (!isList(abspath)) {
00103
00104 return concatPath(tl(relpath), hd(relpath));
00105 } else {
00106 return concatPath(tl(relpath), tl(abspath));
00107 }
00108 } else if (isPathCurrent(head)) {
00109 return concatPath(tl(relpath), abspath);
00110 } else {
00111 return concatPath(tl(relpath), cons(head,abspath));
00112 }
00113 } else {
00114 assert(isNil(relpath));
00115 return abspath;
00116 }
00117 }
00118
00119
00120 static Tree normalizeLabel(Tree label, Tree path)
00121 {
00122
00123
00124 if (isList(label)) {
00125 return cons(label, path);
00126 } else {
00127 Sym s;
00128 assert (isSym(label->node(),&s));
00129 return concatPath(label2path(name(s)),path);
00130 }
00131 }
00132
00133 Tree normalizePath(Tree path)
00134 {
00135
00136 Tree npath;
00137 if (isNil(path)) {
00138 npath = path;
00139 } else {
00140 npath = normalizeLabel(hd(path), normalizePath(tl(path)));
00141 }
00142
00143 return npath;
00144 }
00145