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