////////////////////////////////////////////// // 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 () { }