|
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 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 += "<"; break; 00137 case '>' : dst += ">"; break; 00138 case '&' : dst += "&"; 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
1.8.0