Logo Search packages:      
Sourcecode: icemc version File versions  Download package

IceMenuInParser.cpp

/**
 * IceMC - a menu editor for IceWM
 * Copyright (c) 2000 Georg Mittendorfer
 */

////////////////////////////////////////////////////////////////////////////////
// IceMenuInParser.cpp implementation of CLASS IceMenuInParser
// created:       mig 000720
// last modified: mig 030222
//
// changes: 030222: grammar: added menufile and menuprog
//          001001: update (class IceListView)
//          000812: grammer (in connection with IceMenuScanner): everything between 2
//                  quotes is now an identString. therefore:
//                  Identifier = ident | '"' ident {ident} '"' is obsolete
//                  (all that is handled in scanner now) but Exec has to handle
//                  quoted identStrings extra (could be argument for executable)
//          000809: grammar
/////////////////////////////////////////////////////////////////////////////////

#include "IceMenuInCompiler.h"

///////////////////////////////////////////////////////////////////////////////
// constructor & destructor
///////////////////////////////////////////////////////////////////////////////

IceMenuInParser::IceMenuInParser()
{
  scanner = new IceMenuScanner();
  success = true;
}

IceMenuInParser::~IceMenuInParser()
{
  delete scanner;
}

////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////

void IceMenuInParser::parseFile(IceListView* menuList, const QString filePath)
{
  scanner->setFile(filePath);
  success = true;
  s(menuList);
  if (!success) {
    menuList->clear();
  }
}

bool IceMenuInParser::successful()
{
  return success;
}

void IceMenuInParser::errorPos(int& lineNr, int& charNr)
{
  lineNr = errlnr;
  charNr = errcnr;
}


/***** GRAMMAR ***********************************************************
 *
 * S = {Entry} eof.
 * Entry = (Menu | Prog | "separator" | Menufile | Menuprog | eol) .
 * Menu = "menu" Name Icon "{" eol {Entry} "}" (eol | eof).
 * Prog = ("prog" | "restart") Name Icon Exec (eol | eof).
 * Menufile = "menufile" Name Icon Exec (eol | eof).
 * Menuprog = "menuprog" Name Icon Exec (eol | eof).
 * Name = Identifier .
 * Icon = Identifier .
 * Exec = Identifier {ident | quotedIdent} . // special Identifier treatment
 * Identifier = ident | quotedIdent .
 *
 * Note: '#' handled as eol
 *
 **************************************************************************/

/////////////////////////////////////////////////////////////////////////////
// private methods
/////////////////////////////////////////////////////////////////////////////

void IceMenuInParser::s(IceListView* menuList)
{
  IceListViewItem* subList = 0;
  sy=scanner->newSy();
  while ((sy==IceMenuScanner::menuSy) || (sy==IceMenuScanner::progSy) || (sy==IceMenuScanner::restartSy) 
       || (sy==IceMenuScanner::separatorSy) || (sy==IceMenuScanner::menufileSy)
       || (sy==IceMenuScanner::menuprogSy) || (sy==IceMenuScanner::eolSy)) {
    entry(menuList, subList);
    if (!success) syntaxError();
  }
  if (sy!=IceMenuScanner::eofSy) syntaxError();
}

void IceMenuInParser::entry(IceListView* menuList, IceListViewItem* subList)
  // different handling depending on parameters
{
  IceListViewItem* e;
  IceListViewItem* lastItem; // remember last item because of item order
  if (menuList != 0) {
    lastItem = menuList->firstChild();
    if (lastItem != 0) {
      while (lastItem->nextSibling() != 0)
      lastItem = lastItem->nextSibling();
    }
  }
  else {
    lastItem = subList->firstChild();
    if (lastItem != 0) {
      while (lastItem->nextSibling() != 0)
      lastItem = lastItem->nextSibling();
    }
  }
  switch (sy) {
  case IceMenuScanner::menuSy:
    // sem
    e = createItem(menuList, subList, lastItem, "menu", "foldername", "foldericon", "");
    e->setExpandable (true);
    // endsem
    menu(e);
    if (!success) syntaxError();
    break;
  case IceMenuScanner::restartSy:
    // grammar = same as progSy
  case IceMenuScanner::progSy:
    // sem
    e = createItem(menuList, subList, lastItem, "prog/restart", "appname", "icon", "exec");
    // endsem
    prog(e);
    if (!success) syntaxError();
    break;
  case IceMenuScanner::menuprogSy:
    // just skip but preserve content (for output)
    e = createItem(menuList, subList, lastItem, "menuprog", "sometext", "", "");
    menuprog(e);
    if (!success) syntaxError();
    break;
  case IceMenuScanner::menufileSy:
    // just skip but preserve content (for output)
    e = createItem(menuList, subList, lastItem, "menufile", "sometext", "", "");
    menufile(e);
    if (!success) syntaxError();
    break;
  case IceMenuScanner::separatorSy:
    // sem
    e = createItem(menuList, subList, lastItem, "separator", " ------ ", "", "");
    // endsem
    sy=scanner->newSy();
    break;
  case IceMenuScanner::eolSy:
    sy=scanner->newSy();
    break;
  default:
    syntaxError();
    break;
  }
}

void IceMenuInParser::menu(IceListViewItem* e)
{
  QString nameStr;
  QString iconStr;
  IceListViewItem* m;
  if (sy!=IceMenuScanner::menuSy) syntaxError();
  sy=scanner->newSy();
  nameStr = name();
  if (!success) syntaxError();
  iconStr = icon();
  if (!success) syntaxError();
  // sem
  e->setText(0,nameStr);
  e->setText(1,iconStr);
  // endsem
  if (sy!=IceMenuScanner::lBraceSy) syntaxError();
  sy=scanner->newSy();
  if (sy!=IceMenuScanner::eolSy) syntaxError();
  sy=scanner->newSy();
  while ((sy==IceMenuScanner::menuSy) || (sy==IceMenuScanner::progSy) || (sy==IceMenuScanner::restartSy)
       || (sy==IceMenuScanner::separatorSy) || (sy==IceMenuScanner::eolSy)) {
    // sem
    m = e;
    // endsem
    entry(0,m);
    if (!success) syntaxError();
  }
  if (sy!=IceMenuScanner::rBraceSy) syntaxError();
  sy=scanner->newSy();
  if ((sy!=IceMenuScanner::eolSy) && (sy!=IceMenuScanner::eofSy)) syntaxError();
  sy=scanner->newSy();
}

void IceMenuInParser::prog(IceListViewItem* e)
{
  QString nameStr;
  QString iconStr;
  QString execStr;
  switch (sy) {
  case IceMenuScanner::restartSy:
    // sem
    e->setInfo("restart");
    // endsem
    sy=scanner->newSy();
    break;
  case IceMenuScanner::progSy:
    // sem
    e->setInfo("prog");
    // endsem
    sy=scanner->newSy();
    break;
  default:
    syntaxError();
    break;
  }
  nameStr = QString(name());
  if (!success) syntaxError();
  iconStr = icon();
  if (!success) syntaxError();
  execStr = exec();
  if (!success) syntaxError();
  // sem
  e->setText(0,nameStr);
  e->setText(1,iconStr);
  e->setText(2,execStr);
  // endsem
  if ((sy!=IceMenuScanner::eolSy) && (sy!=IceMenuScanner::eofSy)) syntaxError();
  sy=scanner->newSy();
}

void IceMenuInParser::menufile(IceListViewItem* e) {
  QString nameStr;
  QString iconStr;
  QString execStr;
  e->setInfo("menufile");
  sy=scanner->newSy();
  nameStr = QString(name());
  if (!success) syntaxError();
  iconStr = icon();
  if (!success) syntaxError();
  execStr = exec();
  if (!success) syntaxError();
  // sem
  e->setText(0,nameStr);
  e->setText(1,iconStr);
  e->setText(2,execStr);
  // endsem
  if ((sy!=IceMenuScanner::eolSy) && (sy!=IceMenuScanner::eofSy)) syntaxError();
  sy=scanner->newSy();
}

void IceMenuInParser::menuprog(IceListViewItem* e) {
  QString nameStr;
  QString iconStr;
  QString execStr;
  e->setInfo("menuprog");
  sy=scanner->newSy();
  nameStr = QString(name());
  if (!success) syntaxError();
  iconStr = icon();
  if (!success) syntaxError();
  execStr = exec();
  if (!success) syntaxError();
  // sem
  e->setText(0,nameStr);
  e->setText(1,iconStr);
  e->setText(2,execStr);
  // endsem
  if ((sy!=IceMenuScanner::eolSy) && (sy!=IceMenuScanner::eofSy)) syntaxError();
  sy=scanner->newSy();
}

QString IceMenuInParser::name()
{
  QString str;
  identifier(str);
  if (!success) syntaxError();
  return str;
}

QString IceMenuInParser::icon()
{
  QString str;
  identifier(str);
  if (!success) syntaxError();
  return str;
}

QString IceMenuInParser::exec()
{
  QString str;
  QString tempStr;
  identifier(tempStr);
  // sem
  str = tempStr;
  // endsem
  if (!success) syntaxError();
  while ((sy==IceMenuScanner::identSy) || (sy==IceMenuScanner::quotedIdentSy)) {
    // sem
    str += " ";
    if (sy==IceMenuScanner::quotedIdentSy) { // handle special !!! (e.g. for arguments of executables)
      identifier(tempStr);
      str += '"';
      str += tempStr;
      str += '"';
    }
    else {
      identifier(tempStr);
      str += tempStr;
    }
    // endsem
    if (!success) syntaxError();
    // sem
    if (str.length() > 1024)
      qFatal("FATAL: Exec: String too long");
    // endsem
  }
  return str;
}

void IceMenuInParser::identifier(QString& identStr)
{
  identStr = "";
  switch (sy) {
  case IceMenuScanner::quotedIdentSy:
  case IceMenuScanner::identSy:
    // sem
    identStr = scanner->getIdentStr();
    // endsem
    sy=scanner->newSy();
    break;
  default:
    syntaxError();
    break;
  }
}

IceListViewItem* IceMenuInParser::createItem(IceListView* menuList, IceListViewItem* subList,
                              IceListViewItem* lastItem, const QString command,
                              const QString name, const QString icon,
                              const QString exec)
{
  IceListViewItem* e;
  if (menuList != 0)
    e = new IceListViewItem(menuList, lastItem, command, name, icon, exec);
  else {
    if (subList != 0)
      e = new IceListViewItem(subList, lastItem, command, name, icon, exec);
    else qFatal("createItem: ListView (menulist) and ListViewItem (sublist) == 0 ");
  }
  return e;
}

void IceMenuInParser::syntaxError()
{
  int lnr, cnr;
  scanner->getActPos(lnr,cnr);
  if (success) {
    errlnr = lnr - 1;
    errcnr = cnr;
  }
  //cout << "Syntaxerror in line " << lnr;
  //cout << " at Position " << cnr << "\n";
  success = false;
}














Generated by  Doxygen 1.6.0   Back to index