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