FAUST compiler  0.9.9.6b8
description.cpp
Go to the documentation of this file.
00001 //------------------------------------
00002 // generation of an xml description
00003 //------------------------------------
00004 #include <map>
00005 #include <set>
00006 #include <string>
00007 
00008 #include "description.hh"
00009 #include "Text.hh"
00010 
00014 void extractMetadata(const string& fulllabel, string& label, map<string, set<string> >& metadata)
00015 {
00016     enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue};
00017     int state = kLabel; int deep = 0;
00018     string key, value;
00019 
00020     for (size_t i=0; i < fulllabel.size(); i++) {
00021         char c = fulllabel[i];
00022         switch (state) {
00023             case kLabel :
00024                 assert (deep == 0);
00025                 switch (c) {
00026                     case '\\' : state = kEscape1; break;
00027                     case '[' : state = kKey; deep++; break;
00028                     default : label += c;
00029                 }
00030                 break;
00031 
00032             case kEscape1 :
00033                 label += c;
00034                 state = kLabel;
00035                 break;
00036 
00037             case kEscape2 :
00038                 key += c;
00039                 state = kKey;
00040                 break;
00041 
00042             case kEscape3 :
00043                 value += c;
00044                 state = kValue;
00045                 break;
00046 
00047             case kKey :
00048                 assert (deep > 0);
00049                 switch (c) {
00050                     case '\\' :  state = kEscape2;
00051                                 break;
00052 
00053                     case '[' :  deep++;
00054                                 key += c;
00055                                 break;
00056 
00057                     case ':' :  if (deep == 1) {
00058                                     state = kValue;
00059                                 } else {
00060                                     key += c;
00061                                 }
00062                                 break;
00063                     case ']' :  deep--;
00064                                 if (deep < 1) {
00065                                     metadata[rmWhiteSpaces(key)].insert("");
00066                                     state = kLabel;
00067                                     key="";
00068                                     value="";
00069                                 } else {
00070                                     key += c;
00071                                 }
00072                                 break;
00073                     default :   key += c;
00074                 }
00075                 break;
00076 
00077             case kValue :
00078                 assert (deep > 0);
00079                 switch (c) {
00080                     case '\\' : state = kEscape3;
00081                                 break;
00082 
00083                     case '[' :  deep++;
00084                                 value += c;
00085                                 break;
00086 
00087                     case ']' :  deep--;
00088                                 if (deep < 1) {
00089                                     metadata[rmWhiteSpaces(key)].insert(rmWhiteSpaces(value));
00090                                     state = kLabel;
00091                                     key="";
00092                                     value="";
00093                                 } else {
00094                                     value += c;
00095                                 }
00096                                 break;
00097                     default :   value += c;
00098                 }
00099                 break;
00100 
00101             default :
00102                 cerr << "ERROR unrecognized state " << state << endl;
00103         }
00104     }
00105     label = rmWhiteSpaces(label);
00106 }
00107 
00108 //------------------------ specific schema -------------------------
00109 
00110 string extractName(Tree fulllabel)
00111 {
00112     string name;
00113     map<string, set<string> >   metadata;
00114 
00115     extractMetadata(tree2str(fulllabel), name, metadata);
00116     return name;
00117 }
00118 
00119 
00123 static string xmlize(const string& fullsrc)
00124 {
00125     map<string, set<string> > metadata;
00126     string dst;
00127     string src;
00128 
00129     extractMetadata(fullsrc, src, metadata);
00130 
00131     for (size_t i=0; i<src.size(); i++) {
00132         if (src[i] == '"' & (i==0 | i==src.size()-1)) {
00133             // nothing to do just skip the quotes
00134         } else {
00135             switch (src[i]) {
00136                 case '<' : dst += "&lt;"; break;
00137                 case '>' : dst += "&gt;"; break;
00138                 case '&' : dst += "&amp;"; break;
00139                 default :  dst += src[i];
00140             }
00141         }
00142     }
00143     return dst;
00144 }
00145 
00146 void Description::print(int n, ostream& fout)
00147 {
00148     list<string>::iterator  s;
00149     list<int>::iterator     t;
00150 
00151     tab(n,fout); fout << "<faust>";
00152 
00153         tab(n+1,fout);  fout << "<name>"        << xmlize(fName)        << "</name>";
00154         tab(n+1,fout);  fout << "<author>"      << xmlize(fAuthor)      << "</author>";
00155         tab(n+1,fout);  fout << "<copyright>"   << xmlize(fCopyright)   << "</copyright>";
00156         tab(n+1,fout);  fout << "<license>"     << xmlize(fLicense)     << "</license>";
00157         tab(n+1,fout);  fout << "<version>"     << xmlize(fVersion)     << "</version>";
00158         tab(n+1,fout);  fout << "<inputs>"      << fInputs              << "</inputs>";
00159         tab(n+1,fout);  fout << "<outputs>"     << fOutputs             << "</outputs>";
00160 
00161         tab(n+1,fout);  fout << "<ui>";
00162 
00163             // active widget list
00164             tab(n+2,fout);  fout << "<activewidgets>";
00165                 tab(n+3,fout);  fout << "<count>" << fActiveWidgetCount << "</count>";
00166                 for (s = fActiveLines.begin(); s != fActiveLines.end(); s++) {
00167                     tab(n+3, fout); fout << *s;
00168                 }
00169             tab(n+2,fout);  fout << "</activewidgets>";
00170 
00171             tab(n+2,fout);
00172 
00173             // passive widget list
00174             tab(n+2,fout);  fout << "<passivewidgets>";
00175                 tab(n+3,fout);  fout << "<count>" << fPassiveWidgetCount << "</count>";
00176                 for (s = fPassiveLines.begin(); s != fPassiveLines.end(); s++) {
00177                     tab(n+3, fout); fout << *s;
00178                 }
00179             tab(n+2,fout);  fout << "</passivewidgets>";
00180 
00181 
00182             tab(n+2,fout);
00183 
00184             // widget layout
00185             tab(n+2,fout);  fout << "<layout>";
00186                 for (   t = fLayoutTabs.begin(), s = fLayoutLines.begin();
00187                         s != fLayoutLines.end(); t++, s++) {
00188                     tab(n+3+*t, fout); fout << *s;
00189                 }
00190             tab(n+2,fout);  fout << "</layout>";
00191 
00192         tab(n+1,fout);  fout << "</ui>";
00193 
00194 
00195     tab(n,fout); fout << "</faust>" << endl;
00196 
00197 }
00198 
00199 void Description::ui(Tree t)
00200 {
00201     addGroup(0,t);
00202 }
00203 
00204 
00205 void Description::addGroup(int level, Tree t)
00206 {
00207     Tree    label, elements, varname, sig;
00208     const char* groupnames[] = {"vgroup", "hgroup", "tgroup"};
00209 
00210     if (isUiFolder(t, label, elements)) {
00211 
00212         const int       orient = tree2int(left(label));
00213         const char *    str = tree2str(right(label));
00214 
00215         addLayoutLine(level, subst("<group type=\"$0\">", groupnames[orient]));
00216         addLayoutLine(level+1, subst("<label>$0</label>", xmlize(str)));
00217         while (!isNil(elements)) {
00218             addGroup(level+1, right(hd(elements)));
00219             elements = tl(elements);
00220         }
00221         addLayoutLine(level, "</group>");
00222 
00223     } else if (isUiWidget(t, label, varname, sig)) {
00224 
00225         int w = addWidget(label, varname, sig);
00226         addLayoutLine(level, subst("<widgetref id=\"$0\" />", T(w)));
00227 
00228     } else {
00229 
00230         fprintf(stderr, "error in user interface generation 2\n");
00231         exit(1);
00232 
00233     }
00234 }
00235 
00236 void Description::tab (int n, ostream& fout)
00237 {
00238     fout << '\n';
00239     while (n--) fout << '\t';
00240 }
00241 
00242 int Description::addWidget(Tree label, Tree varname, Tree sig)
00243 {
00244     Tree path, c, x, y, z;
00245 
00246     // add an active widget description
00247 
00248     if ( isSigButton(sig, path) )                   {
00249 
00250         fWidgetID++;
00251         fActiveWidgetCount++;
00252         addActiveLine(subst("<widget type=\"button\" id=\"$0\">", T(fWidgetID)));
00253             addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00254             addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00255         addActiveLine("</widget>");
00256 
00257     } else if ( isSigCheckbox(sig, path) )          {
00258 
00259         fWidgetID++;
00260         fActiveWidgetCount++;
00261         addActiveLine(subst("<widget type=\"checkbox\" id=\"$0\">", T(fWidgetID)));
00262             addActiveLine(subst("\t<label>$0</label>", xmlize(tree2str(label))));
00263             addActiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00264         addActiveLine("</widget>");
00265 
00266     } else if ( isSigVSlider(sig, path,c,x,y,z) )   {
00267 
00268         fWidgetID++;
00269         fActiveWidgetCount++;
00270         addActiveLine(subst("<widget type=\"vslider\" id=\"$0\">", T(fWidgetID)));
00271             addActiveLine(subst("\t<label>$0</label>",      xmlize(tree2str(label))));
00272             addActiveLine(subst("\t<varname>$0</varname>",  tree2str(varname)));
00273             addActiveLine(subst("\t<init>$0</init>",        T(tree2double(c))));
00274             addActiveLine(subst("\t<min>$0</min>",          T(tree2double(x))));
00275             addActiveLine(subst("\t<max>$0</max>",          T(tree2double(y))));
00276             addActiveLine(subst("\t<step>$0</step>",        T(tree2double(z))));
00277         addActiveLine("</widget>");
00278 
00279     } else if ( isSigHSlider(sig, path,c,x,y,z) )   {
00280 
00281         fWidgetID++;
00282         fActiveWidgetCount++;
00283         addActiveLine(subst("<widget type=\"hslider\" id=\"$0\">", T(fWidgetID)));
00284             addActiveLine(subst("\t<label>$0</label>",      xmlize(tree2str(label))));
00285             addActiveLine(subst("\t<varname>$0</varname>",  tree2str(varname)));
00286             addActiveLine(subst("\t<init>$0</init>",        T(tree2double(c))));
00287             addActiveLine(subst("\t<min>$0</min>",          T(tree2double(x))));
00288             addActiveLine(subst("\t<max>$0</max>",          T(tree2double(y))));
00289             addActiveLine(subst("\t<step>$0</step>",        T(tree2double(z))));
00290         addActiveLine("</widget>");
00291 
00292     } else if ( isSigNumEntry(sig, path,c,x,y,z) )  {
00293 
00294         fWidgetID++;
00295         fActiveWidgetCount++;
00296         addActiveLine(subst("<widget type=\"nentry\" id=\"$0\">", T(fWidgetID)));
00297             addActiveLine(subst("\t<label>$0</label>",      xmlize(tree2str(label))));
00298             addActiveLine(subst("\t<varname>$0</varname>",  tree2str(varname)));
00299             addActiveLine(subst("\t<init>$0</init>",        T(tree2double(c))));
00300             addActiveLine(subst("\t<min>$0</min>",          T(tree2double(x))));
00301             addActiveLine(subst("\t<max>$0</max>",          T(tree2double(y))));
00302             addActiveLine(subst("\t<step>$0</step>",        T(tree2double(z))));
00303         addActiveLine("</widget>");
00304 
00305 
00306     // add a passive widget description
00307 
00308     } else if ( isSigVBargraph(sig,path,x,y,z) )    {
00309 
00310         fWidgetID++;
00311         fPassiveWidgetCount++;
00312         addPassiveLine(subst("<widget type=\"vbargraph\" id=\"$0\">", T(fWidgetID)));
00313             addPassiveLine(subst("\t<label>$0</label>",     xmlize(tree2str(label))));
00314             addPassiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00315             addPassiveLine(subst("\t<min>$0</min>",         T(tree2double(x))));
00316             addPassiveLine(subst("\t<max>$0</max>",         T(tree2double(y))));
00317         addPassiveLine("</widget>");
00318 
00319     } else if ( isSigHBargraph(sig,path,x,y,z) )    {
00320 
00321         fWidgetID++;
00322         fPassiveWidgetCount++;
00323         addPassiveLine(subst("<widget type=\"hbargraph\" id=\"$0\">", T(fWidgetID)));
00324             addPassiveLine(subst("\t<label>$0</label>",     xmlize(tree2str(label))));
00325             addPassiveLine(subst("\t<varname>$0</varname>", tree2str(varname)));
00326             addPassiveLine(subst("\t<min>$0</min>",         T(tree2double(x))));
00327             addPassiveLine(subst("\t<max>$0</max>",         T(tree2double(y))));
00328         addPassiveLine("</widget>");
00329 
00330     } else {
00331         fprintf(stderr, "Error describing widget : unrecognized expression\n");
00332         exit(1);
00333     }
00334 
00335     return fWidgetID;
00336 }
00337 
00338 
00339