From 8d112a36bf2d93f8962fbb168132a3f80f573993 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Sat, 20 Feb 2010 23:40:53 -0600 Subject: Cygwin/X: Improve XWinrc loading and error recovery If $HOME/.XWinrc is present but badly formed, ignore it and try system.XWinrc instead. If neither file is present or both are badly formed, provide a built-in default which gives the user the chance to load their new or fixed configuration without restarting. Signed-off-by: Yaakov Selkowitz --- hw/xwin/winprefs.c | 74 ++++++++++++++++++++++++++++++++++++++++----------- hw/xwin/winprefslex.l | 10 ++++--- 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/hw/xwin/winprefs.c b/hw/xwin/winprefs.c index 14409ecae..745e4ed12 100644 --- a/hw/xwin/winprefs.c +++ b/hw/xwin/winprefs.c @@ -56,8 +56,8 @@ extern DWORD g_dwCurrentThreadID; extern const char *winGetBaseDir(void); -/* From winmultiwindowflex.l, the real parser */ -extern void parse_file (FILE *fp); +/* From winprefslex.l, the real parser */ +extern int parse_file (FILE *fp); /* From winprefyacc.y, the pref structure loaded by the parser */ extern WINPREFS pref; @@ -718,6 +718,54 @@ winIconIsOverride(unsigned hiconIn) +/* + * Open and parse the XWinrc config file @path. + * If @path is NULL, use the built-in default. + */ +static int +winPrefsLoadPreferences (char *path) +{ + FILE *prefFile = NULL; + + if (path) + prefFile = fopen (path, "r"); + else + { + char defaultPrefs[] = + "MENU rmenu {\n" + " \"How to customize this menu\" EXEC \"xterm +tb -e man XWinrc\"\n" + " \"Launch xterm\" EXEC xterm\n" + " \"Load .XWinrc\" RELOAD\n" + " SEPARATOR\n" + "}\n" + "\n" + "ROOTMENU rmenu\n"; + + path = "built-in default"; + prefFile = fmemopen(defaultPrefs, strlen(defaultPrefs), "r"); + } + + if (!prefFile) + { + ErrorF ("LoadPreferences: %s not found\n", path); + return FALSE; + } + + ErrorF ("LoadPreferences: Loading %s\n", path); + + if((parse_file (prefFile)) != 0) + { + ErrorF ("LoadPreferences: %s is badly formed!\n", path); + fclose (prefFile); + return FALSE; + } + + fclose (prefFile); + return TRUE; +} + + + /* * Try and open ~/.XWinrc and system.XWinrc * Load it into prefs structure for use by other functions @@ -727,16 +775,15 @@ LoadPreferences (void) { char *home; char fname[PATH_MAX+NAME_MAX+2]; - FILE *prefFile; char szDisplay[512]; char *szEnvDisplay; int i, j; char param[PARAM_MAX+1]; char *srcParam, *dstParam; + int parsed = FALSE; /* First, clear all preference settings */ memset (&pref, 0, sizeof(pref)); - prefFile = NULL; /* Now try and find a ~/.xwinrc file */ home = getenv ("HOME"); @@ -746,14 +793,11 @@ LoadPreferences (void) if (fname[strlen(fname)-1]!='/') strcat (fname, "/"); strcat (fname, ".XWinrc"); - - prefFile = fopen (fname, "r"); - if (prefFile) - ErrorF ("winPrefsLoadPreferences: %s\n", fname); + parsed = winPrefsLoadPreferences(fname); } /* No home file found, check system default */ - if (!prefFile) + if (!parsed) { char buffer[MAX_PATH]; #ifdef RELOCATE_PROJECTROOT @@ -762,16 +806,14 @@ LoadPreferences (void) strncpy(buffer, SYSCONFDIR"/X11/system.XWinrc", sizeof(buffer)); #endif buffer[sizeof(buffer)-1] = 0; - prefFile = fopen (buffer, "r"); - if (prefFile) - ErrorF ("winPrefsLoadPreferences: %s\n", buffer); + parsed = winPrefsLoadPreferences(buffer); } - /* If we could open it, then read the settings and close it */ - if (prefFile) + /* Neither user nor system configuration found, or were badly formed */ + if (!parsed) { - parse_file (prefFile); - fclose (prefFile); + ErrorF ("LoadPreferences: See \"man XWinrc\" to customize the XWin menu.\n"); + parsed = winPrefsLoadPreferences(NULL); } /* Setup a DISPLAY environment variable, need to allocate on heap */ diff --git a/hw/xwin/winprefslex.l b/hw/xwin/winprefslex.l index 463dff4ca..ba8aea696 100644 --- a/hw/xwin/winprefslex.l +++ b/hw/xwin/winprefslex.l @@ -113,14 +113,18 @@ yywrap (void) /* * Run a file through the yacc parser */ -void +int parse_file (FILE *file) { + int ret; + if (!file) - return; + return 1; yylineno = 1; yyin = file; - yyparse (); + ret = yyparse (); + yylex_destroy (); + return ret; } -- cgit v1.2.3