//////////////////////////////////////////////
// NovaWM - Nova Window Manager for X11 //
//////////////////////////////////////////////
// By: Tim Walters //
//////////////////////////////////////////////
// Copyright (C) 2001-2002 Tim Walters //
//////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//This code is released under the terms of the GNU GPL. Refer //
//to the license file included with this source code. //
////////////////////////////////////////////////////////////////
#include "novawm.h"
using namespace std;
int curLine, domain, curByte;
char *line;
bool delQuotes;
#define DOMAIN_CONFIG 0
#define DOMAIN_MENU 1
#define DOMAIN_STYLE 2
#define NKEYWORDS 15
char *dKeyword[NKEYWORDS] = {
//Domain 0
"DisableBar", "ClockFormat", "ShowFocus", "FocusType",
"BarPosition", "HideClock", "StartupCommand", "MainColor",
//Domain 1
"item", "item_splitter", "item_restart", "item_shutdown",
//Doman 2
"name", "author", "info"
};
//Number of arguments accepted for each keyword
int knArgs[NKEYWORDS] = {
1, 1, 1, 1,
1, 1, 1, 1,
2, 0, 0, 0,
1, 1, 1
};
FILE *fIndex[5]; //Tmp index of open files
int lineIndex[5];
int byteIndex[5];
FILE *oFile;
bool shellHack;
void
Config::LoadConfig ()
{
string FName;
FName = getenv ("HOME");
FName += "/.novawm.cfg";
oFile = fopen (FName.c_str (), "r");
if (!oFile)
{
printf ("NovaWM: Failed to load ~/.novawm.cfg! Please create it!\n");
return;
}
printf ("NovaWM: Opened ~/.novawm.cfg...\n");
delQuotes = false;
Search ();
}
void
Config::Search ()
{
domain = -1;
bool srch4strt = false;
bool inArgs = false;
string kw;
vector < string > tmpVec;
line = (char *) malloc (1027);
curLine = -1;
curByte = 0;
shellHack = false;
while (1)
{
while (fgets (line, 1027, oFile) != NULL)
{
curLine++;
curByte += strlen (line);
if (strlen (line) < 0) //Empty Line
continue;
if (line[0] == '!') //This line is just a comment
continue;
//Check line for a }
// for (int i = 0; i < strlen (line); i++)
// {
if (line[0] == '}')
{
if (domain < 0)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Parse Error: Found unexpected '}'!\n",
curLine);
return;
}
else //domain > 0
{
domain = -1;
break;
}
}
if ((domain >= 0) && (srch4strt == false))
{
tmpVec = GetKeywordInfo (&kw);
AnalyzeKeyword (kw, tmpVec, tmpVec.size ());
// continue
continue; //Found one { in the line, probably a keyword so no extra parsing should be done
}
//if (line[i] != ' ')
//break;
//}
if (srch4strt)
{
//Search for {
for (int i = 0; i < strlen (line); i++)
{
if (line[i] == '{')
{
srch4strt = false;
break;
}
if (line[i] != ' ')
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Parse Error: Unexpected character found when searching for beginning of definition block.\n",
curLine);
return;
}
}
}
//Check of a "special" keyword
tmpVec = SplitStr (line, ' ');
if (strncmp (tmpVec[0].c_str (), "include", 7) == 0)
{
if (tmpVec.size () < 2)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Parse Error: include must be followed by a file name!\n",
curLine);
return;
}
for (int i = 0; i < 4; i++)
{
if (fIndex[i] == 0)
{
fIndex[i] = oFile;
lineIndex[i] = curLine;
byteIndex[i] = curByte;
curLine = 0;
curByte = 0;
string FName;
FName = getenv ("HOME");
FName += "/";
FName += tmpVec[1].c_str ();
vector < string > tmpVec2;
//Remove the newline
tmpVec2 = SplitStr (FName, '\n');
FName = tmpVec2[0];
oFile = fopen (FName.c_str (), "r");
if (!oFile)
{
printf
("NovaWM Error: ~/.novawm.cfg: Failed to open included file(%s)!\n",
FName.c_str ());
return;
}
printf ("NovaWM: Opened %s\n", FName.c_str ());
break;
}
}
continue;
}
if (strncmp (tmpVec[0].c_str (), "define", 6) == 0)
{
srch4strt = true;
if (tmpVec.size () < 2)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Parse error: define must be followed by definition block name!\n",
curLine);
return;
}
if (strncmp (tmpVec[1].c_str (), "NovaWM_Config", 13) == 0)
{
domain = DOMAIN_CONFIG;
continue;
}
if (strncmp (tmpVec[1].c_str (), "NovaWM_Menu", 11) == 0)
{
domain = DOMAIN_MENU;
continue;
}
if (strncmp (tmpVec[1].c_str (), "NovaWM_Style", 12) == 0)
{
domain = DOMAIN_STYLE;
continue;
}
if ((domain == -1) && (srch4strt == true))
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Parse Error: Invalid name of definition block!\n",
curLine);
return;
}
}
}
fclose (oFile);
if (fIndex[0] == 0)
return;
for (int i = 4; i > -1; i--)
{
if (fIndex[i] != 0)
{
oFile = fIndex[i];
fIndex[i] = 0;
curLine = lineIndex[i] + 2;
curByte = byteIndex[i];
lineIndex[i] = 0;
byteIndex[i] = 0;
fseek (oFile, curByte, SEEK_SET);
break;
}
}
}
}
vector < string > Config::SplitStr (string str, char tok)
{
vector < string > splitString;
string newString;
bool inQuotes = false;
for (unsigned int i = 0; i < str.size (); i++)
{
if (str[i] == tok)
{
if (newString.size () > 0) //Each string must have a greater than 0 length
{
splitString.push_back (newString);
newString = "";
}
}
else
{
if (str[i] == '"')
{
inQuotes = !inQuotes;
if (delQuotes == true)
continue; //In this paticular use of this function we want to ignore double quotes
}
if ((str[i] == ' ') || (str[i] == '\t')) //Ignore whitespaces
{
if (inQuotes == false)
continue;
}
newString += str[i];
}
}
splitString.push_back (newString);
return splitString;
}
vector < string > Config::GetKeywordInfo (string * keyword)
{
vector < string > tmpVec;
vector < string > arguments;
//First get the keyword
//NOTE: It is assumed there there is ONE keyword per line!
tmpVec = SplitStr (line, '{'); //Get rid of arguments
*keyword = tmpVec[0];
if (tmpVec.size () == 1) //zero arguments
{
tmpVec.clear ();
return arguments;
}
if ((tmpVec[tmpVec.size () - 1].
c_str ()[tmpVec[tmpVec.size () - 1].size () - 2] != '}')
&& (tmpVec[tmpVec.size () - 1].
c_str ()[tmpVec[tmpVec.size () - 1].size () - 2] != ','))
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Parse Error: Line did not end with a } or ,\n",
curLine);
return arguments;
}
//Remove the }
tmpVec = SplitStr (tmpVec[tmpVec.size () - 1], '}');
delQuotes = true;
//Get the final list of arguments
tmpVec = SplitStr (tmpVec[0], ',');
delQuotes = false;
return tmpVec;
}
void
Config::AnalyzeKeyword (string keyword, vector < string > argVec, int nArgs)
{
int keyValue = -1;
//Search for keyword
for (int i = 0; i < NKEYWORDS; i++)
{
if (strcmp (keyword.c_str (), dKeyword[i]) == 0)
{
keyValue = i;
break;
}
}
if (knArgs[keyValue] != nArgs)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Parse Error: invalid number of arguments for keyword! %s %d\n",
curLine, keyword.c_str (), nArgs);
return;
}
switch (keyValue)
{
case 0: //DisableBar
if (domain != 0)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Keyword in wrong definition block!\n",
curLine);
return;
}
if (strncmp (argVec[0].c_str (), "true", 4) == 0)
disableBar = true;
else
disableBar = false;
break;
case 1: //ClockFormat
if (domain != 0)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Keyword in wrong definition block!(%d)\n",
curLine, domain);
return;
}
clockFormat = atoi (argVec[0].c_str ());
break;
case 2: //ShowFocus
if (domain != 0)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Keyword in wrong definition block!\n",
curLine);
return;
}
if (strncmp (argVec[0].c_str (), "true", 4) == 0)
shwFocusMode = true;
else
shwFocusMode = false;
break;
case 3: //FocusType
if (domain != 0)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Keyword in wrong definition block!\n",
curLine);
return;
}
focusType = atoi (argVec[0].c_str ());
break;
case 4: //BarPosition
if (domain != 0)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Keyword in wrong definition block!\n",
curLine);
return;
}
barPosition = atoi (argVec[0].c_str ());
break;
case 5: //HideClock
if (domain != 0)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Keyword in wrong definition block!\n",
curLine);
return;
}
if (strncmp (argVec[0].c_str (), "true", 4) == 0)
hideClock = true;
else
hideClock = false;
break;
case 6: //StartupCommand
if (shellHack == true)
break; //Prevent running 4 times(Possibly causing SEVERE performance problems)
novawm.Run ((char *) argVec[0].c_str ());
shellHack = true;
break;
case 7: //MainColor
mainColor = argVec[0].c_str ();
break;
case 8: //item
if (domain != 1)
{
printf
("NovaWM Error: ~/.novawm.cfg:%d: Keyword in wrong definition block!\n",
curLine);
return;
}
for (int i = 0; i < itemExec.size (); i++) //Ignore duplicates
{
if (strcmp (itemExec[i].c_str (), argVec[1].c_str ()) == 0)
return;
}
novaMenu.AddItem ((char *) argVec[0].c_str ());
itemExec.push_back (argVec[1].c_str ());
break;
case 9: //item_splitter
novaMenu.AddItem ("?+MENU_SPLIT+?");
break;
case 10: //item_restart
novaMenu.AddItem ("?+MENU_RESTART+?");
break;
case 11: //item_shutdown
novaMenu.AddItem ("?+MENU_SHUTDOWN+?");
break;
}
}
Config::Config ()
{
fIndex[0] = 0;
fIndex[1] = 0;
fIndex[2] = 0;
fIndex[3] = 0;
fIndex[4] = 0;
lineIndex[0] = 0;
lineIndex[1] = 0;
lineIndex[2] = 0;
lineIndex[3] = 0;
lineIndex[4] = 0;
}
Config::~Config ()
{
}
syntax highlighted by Code2HTML, v. 0.9.1