Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

vuGuiParser.cpp

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include "vuGuiParser.h"
00005 
00006 //----------------------------------------------------------------------------
00007 //------------------------- Gui script tokens --------------------------------
00008 //----------------------------------------------------------------------------
00009 
00010 #define GUI_OPEN       " gui %s : %s %n"
00011 #define SECTION_OPEN   "%s { %n"
00012 #define CONTROL_DEFINE "%s %s { %n"
00013 #define STRING         "%s %n"
00014 
00015 
00016 //----------------------------------------------------------------------------
00017 //------------------------- vuGuiParser() ------------------------------------
00018 //----------------------------------------------------------------------------
00019 
00020 vuGuiParser::vuGuiParser() : vuParser()
00021 {
00022 }
00023 
00024 //----------------------------------------------------------------------------
00025 //------------------------- ~vuGuiParser() -----------------------------------
00026 //----------------------------------------------------------------------------
00027 
00028 vuGuiParser::~vuGuiParser()
00029 {
00030 }
00031 
00032 //----------------------------------------------------------------------------
00033 //------------------------- public Parse() -----------------------------------
00034 //----------------------------------------------------------------------------
00035 
00036 void vuGuiParser::Parse(const char* filename) throw (const char *)
00037 {
00038     //read in the file
00039     readBuffer(filename);
00040     FixBuffer();
00041   
00042     //parse the gui declaration
00043     ParseGui();
00044 }
00045 
00046 //----------------------------------------------------------------------------
00047 //------------------------- private: ParseGui() ------------------------------
00048 //----------------------------------------------------------------------------
00049 
00050 void vuGuiParser::ParseGui()
00051 {
00052     int len=0, ret;
00053     char name[64]="";
00054     char base[64]="";
00055 
00056     //Read in the gui declaration
00057     ret = sscanf(&m_Buffer[m_Pos], GUI_OPEN, name, base, &len);
00058     if (ret != 2) throw ("Gui declaration is missing or invalid.");
00059     m_Pos+=len; len = 0;
00060     m_Name = name; m_Base = base;
00061 
00062     //Create the output files for the code
00063     m_fHeader.open(m_Name + ".h",ios::out);
00064     m_fImpl.open(m_Name + ".cpp",ios::out);
00065     if (!m_fHeader.is_open()||!m_fImpl.is_open())
00066         throw ("Could not open files for output.");
00067 
00068     //Declare the gui class in the header file
00069     m_fHeader << "#include \"" << m_Base << ".h\"\n\n";
00070     m_fHeader << "class " << m_Name <<": public " << m_Base << "\n{\n";
00071     m_fHeader << "public:\n";
00072 
00073     //Parse the includes for the gui class
00074     ParseAPIs();
00075 
00076     //Parse the rest of the file.
00077     ParseSections();
00078 
00079     //Write the control, event, and api data.
00080     WriteData();
00081 
00082     //Close the output files
00083     m_fHeader.close();
00084     m_fImpl.close();
00085 }
00086 
00087 //----------------------------------------------------------------------------
00088 //------------------------- private: ParseAPIs() -----------------------------
00089 //----------------------------------------------------------------------------
00090 
00091 void vuGuiParser::ParseAPIs()
00092 {
00093     StringList Apis;
00094 
00095     //Parse the api list from the input file
00096     if (readToken('['))
00097     { 
00098         Apis = ParseList();
00099         if (!readToken(']')) 
00100             throw ("Include header listing not closed properly.");
00101     }
00102 
00103     //Now output the api data to the files.
00104     m_fImpl << "#include \"" << m_Name << ".h\"\n";
00105     int num = Apis.getLength();
00106     for (int i=0; i < num; i++)
00107         m_fImpl << "#include \"" << Apis[i] << "\"\n";
00108     m_fImpl << "\n";
00109 };
00110 
00111 //----------------------------------------------------------------------------
00112 //------------------------- private: ParseSections() -------------------------
00113 //----------------------------------------------------------------------------
00114 
00115 void vuGuiParser::ParseSections()
00116 {
00117     char name[256] = "";
00118     int len = 0;
00119 
00120     //Check for the gui declaration opening.
00121     if (!readToken('{')) return;
00122 
00123     //Read all the sections from the file 
00124     while (!readToken('}') && !finished())
00125     {
00126         if (sscanf(&m_Buffer[m_Pos],SECTION_OPEN,name,&len)!=1)
00127             throw ("Invalid gui section declaration.");
00128         m_Pos += len; len = 0;
00129 
00130         //Parse the section based on its type
00131         if (strcmp(name,"init") == 0)
00132             ParseMethod("init()");
00133         else if (strcmp(name,"close") == 0)
00134             ParseMethod("close()");
00135         else if (strcmp(name,"Top")==0  || strcmp(name,"Bottom")==0 ||
00136                  strcmp(name,"Left")==0 || strcmp(name,"Right")==0)
00137             ParseControls(name);
00138         else
00139             throw ("Undefined name for gui section declaration.");
00140     }
00141 }
00142 
00143 //----------------------------------------------------------------------------
00144 //------------------------- private: ParseControls() -------------------------
00145 //----------------------------------------------------------------------------
00146 
00147 void vuGuiParser::ParseControls(const char *Location)
00148 {
00149     char name[256],type[256];
00150     int len = 0;
00151     vuString addFunction;
00152 
00153     while (!readToken('}') && !finished())
00154     {
00155         if (sscanf(&m_Buffer[m_Pos],CONTROL_DEFINE,type,name,&len)!=2)
00156             throw ("Invalid user interface control declaration.");
00157         m_Pos+=len; len = 0;
00158 
00159         if (strcmp(type,"listbox")==0)
00160             addFunction += ParseListBox(name);
00161         else if (strcmp(type,"button")==0)
00162             addFunction += ParseButton(name);
00163         else if (strcmp(type,"slider")==0)
00164             addFunction += ParseSlider(name);
00165         else if (strcmp(type,"checkbox")==0)
00166                 addFunction += ParseCheckBox(name);
00167         else if (strcmp(type,"radiobox")==0)
00168             addFunction += ParseRadioBox(name);
00169                 addFunction += '\n';
00170     }
00171     
00172     //declare the control function in the header file
00173     m_fHeader << "    void add" << Location << "(wxSizer *Sizer);\n";
00174 
00175     //implement the function in the implementation file
00176     m_fImpl << "void " << m_Name << "::add" << Location;
00177     m_fImpl << "(wxSizer *Sizer)\n{\n" << addFunction << "};\n\n";
00178 }
00179 
00180 //----------------------------------------------------------------------------
00181 //------------------------- private: ParseList() -----------------------------
00182 //----------------------------------------------------------------------------
00183 
00184 StringList vuGuiParser::ParseList()
00185 {
00186     bool read = true;
00187     int len = 0;
00188     char value[256];
00189     StringList slist;
00190     
00191     while (read)
00192     {
00193         read = false;
00194         if (readToken(',')) 
00195             read = true;
00196         else if (readToken(';')) {}
00197         else if (readToken('}',false) || finished()) {}
00198         else if (readToken(']',false)) {}
00199         else if (sscanf(&m_Buffer[m_Pos],STRING,value,&len)==1)
00200         {
00201             m_Pos += len; len = 0;
00202             slist.add(value);
00203             read = true;
00204         }
00205     }
00206     return slist;
00207 }
00208 
00209 //----------------------------------------------------------------------------
00210 //------------------------- private: ParseMethod() ---------------------------
00211 //----------------------------------------------------------------------------
00212 
00213 void vuGuiParser::ParseMethod(const char *Header)
00214 {
00215         //declare the method in the header file
00216     m_fHeader << "    void " << Header << ";\n";
00217 
00218         //declare the method in the implementation file
00219     m_fImpl << "void " << m_Name << "::" << Header << "\n{\n";
00220 
00221         //Parse all the statements in the code block
00222     while (!readToken('}') && !finished())
00223         m_fImpl << "    " << ParseStatement() << ";\n";
00224 
00225     m_fImpl << "};\n\n";
00226 }
00227 
00228 //----------------------------------------------------------------------------
00229 //------------------------- private: ParseStatement() ------------------------
00230 //----------------------------------------------------------------------------
00231 
00232 vuString vuGuiParser::ParseStatement()
00233 {
00234     int len = 0;
00235     char name[256];
00236     vuString statement = "m_Data->";
00237 
00238         //check to see if it is an empty statement.
00239     if (readToken(';')||finished()) return "";
00240 
00241         //read in the statement.
00242     sscanf(&m_Buffer[m_Pos],STRING,name,&len);
00243     m_Pos+=len; len = 0;
00244         //translate the name into a method call
00245     statement << name << "(";
00246         //check if there is a parameter given
00247     if (readToken('('))
00248     {
00249         if (!readToken(')',false))
00250         {
00251             sscanf(&m_Buffer[m_Pos],STRING,name,&len);
00252             m_Pos+=len; len = 0;
00253                 //change the parameter into a value
00254             if (m_Controls.isMember(vuString("l")+name))
00255                 statement << "m_l" << name << "->GetSelection()";
00256             else if (m_Controls.isMember(vuString("s")+name))
00257                 statement << "m_s" << name << "->GetValue()";
00258             else if (m_Controls.isMember(vuString("c")+name))
00259                 statement << "m_c" << name << "->GetValue()";
00260             else if (m_Controls.isMember(vuString("r")+name))
00261                 statement << "m_r" << name << "->GetStringSelection()";
00262             else if (strcmp(name,"glwidth")==0)
00263                 statement << "m_glCanvas->getWidth()";
00264             else if (strcmp(name,"glheight")==0)
00265                 statement << "m_glCanvas->getHeight()";
00266             else if (m_Controls.isMember(vuString("b")+name))
00267                 throw ("Can't pass a button value as a parameter.");
00268             else
00269                 throw ("Undefined identifier passed as a parameter.");
00270         }
00271             //read the closing paranthesis
00272         if (!readToken(')')) throw ("Missing closing paranthesis in code block");
00273     }
00274     statement << ")";
00275         //Read in the ending semicolon.
00276     readToken(';');
00277     return statement;
00278 }
00279 
00280 //----------------------------------------------------------------------------
00281 //------------------------- private: WriteData() -----------------------------
00282 //----------------------------------------------------------------------------
00283 
00284 void vuGuiParser::WriteData()
00285 {
00286     //Declare the control variables in the header file
00287     m_fHeader << "\nprivate:\n";
00288     unsigned int num = m_Controls.getLength();
00289     for (unsigned int i=0; i < num; i++)
00290     {
00291         if (m_Controls[i][(long unsigned int) (0)]=='l')
00292             m_fHeader << "    wxListBox* m_" << m_Controls[i].c_str() << ";\n";
00293         else if (m_Controls[i][(long unsigned int) (0)]=='s')
00294             m_fHeader << "    wxSlider* m_" << m_Controls[i].c_str() << ";\n";
00295         else if (m_Controls[i][(long unsigned int) (0)]=='b')
00296             m_fHeader << "    wxButton* m_" << m_Controls[i].c_str() << ";\n";
00297         else if (m_Controls[i][(long unsigned int) (0)]=='c')
00298             m_fHeader << "    wxChoiceBox* m_" << m_Controls[i].c_str() << ";\n";
00299         else if (m_Controls[i][(long unsigned int) (0)]=='r')
00300             m_fHeader << "    wxRadioBox* m_" << m_Controls[i].c_str() << ";\n";
00301     }
00302         //add the event declartion
00303     m_fHeader << "\n    DECLARE_EVENT_TABLE()\n";
00304         //Close off the header
00305     m_fHeader << "};\n";
00306 
00307         //Declare the enums for the controls in the implementation file
00308     m_fImpl << "enum\n{\n";
00309     m_fImpl << "    START_VALUE = 100,\n";
00310     for (int i=0; i < int (num-1); i++)
00311         m_fImpl << "    id_" << m_Controls[i].c_str() << ",\n";
00312     m_fImpl << "    id_" << m_Controls[num-1].c_str() << "\n};\n\n";
00313 
00314         //Declare the event table for the controls
00315     m_fImpl << "BEGIN_EVENT_TABLE(" << m_Name << ", " << m_Base << ")\n";
00316     for (unsigned int i=0; i < num; i++)
00317     {
00318         if (m_Controls[i][(long unsigned int) (0)]=='l')
00319             m_fImpl << "    EVT_LISTBOX(id_" << m_Controls[i].c_str() << ", "
00320                   << m_Name.c_str() << "::On" << m_Controls[i].c_str() << ")\n";
00321         else if (m_Controls[i][(long unsigned int) (0)]=='s')
00322             m_fImpl << "    EVT_SLIDER(id_" << m_Controls[i].c_str() << ", "
00323                   << m_Name.c_str() << "::On" << m_Controls[i].c_str() << ")\n";
00324         else if (m_Controls[i][(long unsigned int) (0)]=='b')
00325             m_fImpl << "    EVT_BUTTON(id_" << m_Controls[i].c_str() << ", "
00326                   << m_Name.c_str() << "::On" << m_Controls[i].c_str() << ")\n";
00327         else if (m_Controls[i][(long unsigned int) (0)]=='c')
00328             m_fImpl << "    EVT_CHECKBOX(id_" << m_Controls[i].c_str() << ", "
00329                   << m_Name.c_str() << "::On" << m_Controls[i].c_str() << ")\n";
00330         else if (m_Controls[i][(long unsigned int) (0)]=='r')
00331             m_fImpl << "    EVT_RADIOBOX(id_" << m_Controls[i].c_str() << ", "
00332                       << m_Name.c_str() << "::On" << m_Controls[i].c_str() << ")\n";
00333     }
00334     m_fImpl << "END_EVENT_TABLE()\n\n";
00335     m_fImpl.seekp(0,ios::end);
00336 }
00337 
00338 //----------------------------------------------------------------------------
00339 //------------------------- private: ParseListBox() --------------------------
00340 //----------------------------------------------------------------------------
00341 
00342 vuString vuGuiParser::ParseListBox(const char *cname)
00343 {
00344     vuString name = vuString("l") + cname;
00345     if (m_Controls.isMember(name))
00346         throw ("Defined two controls of the same name.");
00347     m_Controls.add(name);
00348 
00349     //Parse the data for the listbox
00350     StringList values = ParseList();
00351     StringList initial = ParseList();
00352     if ((values.getLength()==0)||(initial.getLength()!=1))
00353         throw ("Invalid definition of a listbox control.");
00354 
00355     //Make the code to create the listbox
00356     vuString create;
00357     create << "    m_" << name << " = new wxListBox(this, ";
00358     create << "id_" << name << ");\n";
00359     int num = values.getLength();
00360     for (int i=0; i < num; i++)
00361         create << "    m_" << name << "->Append(\"" << values[i].c_str() << "\");\n";
00362     create << "    m_" << name << "->SetStringSelection(\"";
00363     create << initial[0].c_str() << "\");\n";
00364     create << "    Sizer->add(m_" << name << ");\n";
00365 
00366     //Finally process any code that goes along with the control
00367     ParseMethod("On" + name + "(wxCommandEvent &event)");
00368 
00369     //And return the creation code
00370     return create;
00371 }
00372 
00373 //----------------------------------------------------------------------------
00374 //------------------------- private: ParseSlider() ---------------------------
00375 //----------------------------------------------------------------------------
00376 
00377 vuString vuGuiParser::ParseSlider(const char *cname)
00378 {
00379     vuString name = vuString("s") + cname;
00380     if (m_Controls.isMember(name))
00381         throw ("Defined two controls of the same name.");
00382     m_Controls.add(name);
00383 
00384         //Parse the data for the slider
00385     StringList settings = ParseList();
00386     if (settings.getLength()!=4)
00387         throw ("Invalid definition of a slider control.");
00388 
00389         //Make the code to create the slider
00390     vuString create;
00391     create << "    m_" << name << " = new wxSlider(this, ";
00392     create << "id_" << name << "," << settings[2] << "," << settings[0].c_str();
00393     create << "," << settings[1].c_str() << ",wxDefaultPosition,wxDefaultSize,";
00394     if (strcmp(settings[3].c_str(),"vertical")==0)
00395         create << "wxSL_VERTICAL";
00396     else
00397         create << "wxSL_HORIZONTAL";
00398     create << ");\n    Sizer->add(m_" << name << ");\n";
00399 
00400         //Finally process any code that goes along with the control
00401     ParseMethod("On" + name + "(wxCommandEvent &event)");
00402 
00403         //And return the creation code
00404     return create;
00405 }
00406 //----------------------------------------------------------------------------
00407 //------------------------- private: ParseRadioBox() -------------------------
00408 //----------------------------------------------------------------------------
00409 
00410 vuString vuGuiParser::ParseRadioBox(const char *cname)
00411 {
00412     vuString name = vuString("r") + cname;
00413     if (m_Controls.isMember(name))
00414         throw ("Defined two controls of the same name.");
00415     m_Controls.add(name);
00416 
00417         //Parse the data for the radiobox
00418     StringList label = ParseList();
00419     StringList choices = ParseList();
00420     StringList initial = ParseList();
00421     if ((label.getLength()==0)||(choices.getLength()==0)
00422             ||(initial.getLength()!=1))
00423         throw ("Invalid definition of a radiobox control.");
00424 
00425         //Make the code to create the radiobox
00426     vuString create;
00427 
00428     create << "    vuString label" << name << " = \"";
00429     int num = label.getLength();
00430     for (int i=0; i < num-1; i++)
00431         create << label[i].c_str() << " ";
00432     create << label[num-1].c_str() << "\";\n";
00433     create << "    wxString choices[" << choices.getLength() << "];\n";
00434     num = choices.getLength();
00435     for (int i=0; i < num; i++)
00436        create << "    choices[" << i << "] = \"" << choices[i].c_str() << "\";\n";
00437     create << "    m_" << name << " = new wxRadioBox(this, ";
00438     create << "id_" << name << ",label" << name << ",wxDefaultPosition,";
00439     create << "wxDefaultSize," << num << ",choices);\n";
00440     create << "    Sizer->add(m_" << name << ");\n";
00441 
00442         //Finally process any code that goes along with the control
00443     ParseMethod("On" + name + "(wxCommandEvent &event)");
00444 
00445         //And return the creation code
00446     return create;
00447 }
00448 //----------------------------------------------------------------------------
00449 //------------------------- private: ParseCheckbox() -------------------------
00450 //----------------------------------------------------------------------------
00451 
00452 vuString vuGuiParser::ParseCheckBox(const char *cname)
00453 {
00454     vuString name = vuString("c") + cname;
00455     if (m_Controls.isMember(name))
00456         throw ("Defined two controls of the same name.");
00457     m_Controls.add(name);
00458 
00459         //Parse the data for the checkbox
00460     StringList label = ParseList();
00461     StringList initial = ParseList();
00462     if ((label.getLength()==0)||(initial.getLength()==0))
00463         throw ("Invalid definition of a checkbox control.");
00464 
00465         //Make the code to create the checkbox
00466     vuString create;
00467     create << "    wxString label" << name << " = \"";
00468     int num = label.getLength();
00469     for (int i=0; i < num-1; i++)
00470         create << label[i].c_str() << " ";
00471     create << label[num-1].c_str() << "\";\n";
00472     create << "    m_" << name << " = new wxCheckBox(this, ";
00473     create << "id_" << name << ",label" << name << ");\n";
00474     create << "    m_" << name << "->SetValue(" << initial[0];
00475     create << ");\n    Sizer->add(m_" << name << ");\n";
00476 
00477         //Finally process any code that goes along with the control
00478     ParseMethod("On" + name + "(wxCommandEvent &event)");
00479 
00480         //And return the creation code
00481     return create;
00482 }
00483 //----------------------------------------------------------------------------
00484 //------------------------- private: ParseButton() ---------------------------
00485 //----------------------------------------------------------------------------
00486 
00487 vuString vuGuiParser::ParseButton(const char *cname)
00488 {
00489     vuString name = vuString("b") + cname;
00490     if (m_Controls.isMember(name))
00491         throw ("Defined two controls of the same name.");
00492     m_Controls.add(name);
00493 
00494         //Parse the data for the button
00495     StringList label = ParseList();
00496     if (label.getLength()==0)
00497     throw ("Invalid definition of a button control.");
00498 
00499         //Make the code to create the button
00500     vuString create;
00501     create << "    wxString label" << name << " = \"";
00502     int num = label.getLength();
00503     for (int i=0; i < num-1; i++)
00504         create << label[i].c_str() << " ";
00505     create << label[num-1].c_str() << "\";\n";
00506     create << "    m_" << name << " = new wxButton(this, ";
00507     create << "id_" << name << ",label" << name << ");\n";
00508     create << "    Sizer->add(m_" << name << ");\n";
00509 
00510         //Finally process any code that goes along with the control
00511     ParseMethod("On" + name + "(wxCommandEvent &event)");
00512 
00513         //And return the creation code
00514     return create;
00515 }

Generated on Wed Dec 15 21:20:34 2004 for vuVolume by  doxygen 1.3.9.1