FAUST compiler  0.9.9.6b8
labels.cpp
Go to the documentation of this file.
00001 #include "labels.hh"
00002 #include "compatibility.hh"
00003 
00004 //=========================== PATHNAME ===============================
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                 //cerr << "abspath : " << *abspath << endl; 
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     // we suppose label = "../label" ou "name/label" ou "name"  
00123     //cout << "Normalize Label " << *label << " with path " << *path << endl;
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     //cout << "Normalize Path [[" << *path << "]]" << endl;
00136     Tree npath;
00137     if (isNil(path)) {
00138         npath = path;
00139     } else {
00140         npath = normalizeLabel(hd(path), normalizePath(tl(path)));
00141     }
00142     //cout << "              -> [[" << *npath << "]]" << endl;
00143     return npath;
00144 }
00145