All pastes #434371 Raw Edit

Stuff

public c v1 · immutable
·published 2007-04-11 12:04 UTC
rendered paste body
diff --git a/plugins/ini.c b/plugins/ini.cindex a8696dc..2441e99 100644--- a/plugins/ini.c+++ b/plugins/ini.c@@ -52,6 +52,9 @@  static int displayPrivateIndex; +/*+ * IniFileData+ */ typedef struct _IniFileData IniFileData; struct _IniFileData {     char		 *filename;@@ -65,20 +68,9 @@ struct _IniFileData {     IniFileData		 *prev; }; -#define N_ACTION_PARTS 5-typedef struct _IniActionProxy {-    int               nSet;--    CompBindingType   type;-    CompKeyBinding    key;-    CompButtonBinding button;--    Bool bell;--    unsigned int edgeMask;-    int		 edgeButton;-} IniActionProxy;-+/*+ * IniDisplay+ */ typedef struct _IniDisplay {     int		                  screenPrivateIndex; @@ -91,30 +83,60 @@ typedef struct _IniDisplay {     IniFileData			*fileData; } IniDisplay; +/*+ * IniScreeen+ */ typedef struct _IniScreen {     InitPluginForScreenProc        initPluginForScreen;     SetScreenOptionProc		   setScreenOption;     SetScreenOptionForPluginProc   setScreenOptionForPlugin; } IniScreen; -static void-initActionProxy (IniActionProxy *a)-{-    a->type = 0;--    a->nSet = 0;--    a->key.keycode = 0;-    a->key.modifiers = 0;+/*+ * IniAction+ */+static char * validActionTypes[] = {+	"key",+	"button",+	"bell",+	"edge",+	"edgebutton"};++#define ACTION_VALUE_KEY	    (1 << 0)+#define ACTION_VALUE_BUTTON	    (1 << 1)+#define ACTION_VALUE_BELL	    (1 << 2)+#define ACTION_VALUE_EDGE	    (1 << 3)+#define ACTION_VALUE_EDGEBUTTON	    (1 << 4)+#define ACTION_VALUES_ALL \+	( ACTION_VALUE_KEY \+	| ACTION_VALUE_BUTTON \+	| ACTION_VALUE_BELL \+	| ACTION_VALUE_EDGE \+	| ACTION_VALUE_EDGEBUTTON )++static int actionValueMasks[] = {+    ACTION_VALUE_KEY,+    ACTION_VALUE_BUTTON,+    ACTION_VALUE_BELL,+    ACTION_VALUE_EDGE,+    ACTION_VALUE_EDGEBUTTON+}; -    a->button.button = 0;-    a->button.modifiers = 0;+enum {+    ACTION_TYPE_KEY = 0,+    ACTION_TYPE_BUTTON,+    ACTION_TYPE_BELL,+    ACTION_TYPE_EDGE,+    ACTION_TYPE_EDGEBUTTON,+    ACTION_TYPES_NUM+}; -    a->bell = FALSE;+typedef struct _IniAction {+    char *realOptionName;+    unsigned int valueMasks;+    CompAction a;+} IniAction; -    a->edgeMask = 0;-    a->edgeButton = 0;-}  static IniFileData * iniGetFileDataFromFilename (CompDisplay *d,@@ -471,6 +493,135 @@ iniMakeDirectories (void) }  static Bool+findActionType(char *optionName, int *type)+{ +    char * optionType = strrchr(optionName, '_');+    if (!optionType)+	return FALSE;++    optionType++; // skip the '_'+    +    int i;+    for (i = 0; i < ACTION_TYPES_NUM; i++)+    {+	if (strcmp(optionType, validActionTypes[i]) == 0)+	{+	    if (type)+		*type = i;+	    return TRUE;+	}+    }++    return FALSE;+}++static Bool+parseAction(CompDisplay *d, char *optionName, char *optionValue, IniAction *action)+{ +    int type;+    if (!findActionType(optionName, &type))+	return FALSE; // no action, exit the loop++    // we have a new action+    if (!action->realOptionName)+    {+	char *optionType = strrchr(optionName, '_');+	// chars until the last "_"+	int len = strlen(optionName) - strlen(optionType);+	+	action->realOptionName = malloc(sizeof(char)*(len+1));+	strncpy(action->realOptionName, optionName, len);+	action->realOptionName[len] = '\0';++	// make sure all defaults are set+	action->a.type = 0;+	action->a.key.keycode = 0;+	action->a.key.modifiers = 0;+	action->a.button.button = 0;+	action->a.button.modifiers = 0;+	action->a.bell = FALSE;+	action->a.edgeMask = 0;+	action->a.edgeButton = 0;+    }+    // detect a new option (might happen when the options are incomplete)+    else if (action->valueMasks != ACTION_VALUES_ALL)+    {+	char *optionType = strrchr(optionName, '_');+	// chars until the last "_"+	int len = strlen(optionName) - strlen(optionType);+	+	char *realOptionName = malloc(sizeof(char)*(len+1));+	strncpy(realOptionName, optionName, len);+	realOptionName[len] = '\0';++	if (strcmp(action->realOptionName, realOptionName) != 0) {+	    free(realOptionName);+	    return FALSE;+	}+	+	free(realOptionName);+    } ++    int i, j;+    CompListValue edges;+    switch (type)+    {+	case ACTION_TYPE_KEY: +	    if (optionValue[0] != '\0' &&+		strcasecmp(optionValue, "disabled") != 0 &&+		stringToKeyBinding (d, optionValue, &action->a.key))+		action->a.type |= CompBindingTypeKey;+	    break;++	case ACTION_TYPE_BUTTON:+	    if (optionValue[0] != '\0' &&+		strcasecmp(optionValue, "disabled") != 0 &&+		stringToButtonBinding (d, optionValue, &action->a.button))+		action->a.type |= CompBindingTypeButton;+	    break;++	case ACTION_TYPE_BELL:+	    action->a.bell  = (Bool) atoi(optionValue);+	    break;++	case ACTION_TYPE_EDGE:+	    if (optionValue[0] != '\0' &&+		csvToList (optionValue, &edges, CompOptionTypeString))+	    {+		for (i = 0; i < edges.nValue; i++) {+		    for (j = 0; j < SCREEN_EDGE_NUM; j++) {+			if (strcasecmp (edges.value[i].s, edgeToString(j)) == 0)+			{+			    action->a.edgeMask |= (1 << j);++			    // found corresponding mask, next value+			    break; +			}+		    }+		}+	    }+	    break;++	case ACTION_TYPE_EDGEBUTTON:+	    action->a.edgeButton = atoi(optionValue);+	    if (action->a.edgeButton != 0)+		action->a.type |= CompBindingTypeEdgeButton;+	    break;++	default:+	    break;+    }++    action->valueMasks |= actionValueMasks[type];++    // no need to read any further since all value are set+    if (action->valueMasks == ACTION_VALUES_ALL)+	return FALSE;++    return TRUE; // continue loop, not finished parsing yet+}++static Bool iniLoadOptionsFromFile (CompDisplay *d, 			FILE *optionFile, 			char *plugin,@@ -478,9 +629,6 @@ iniLoadOptionsFromFile (CompDisplay *d, {     char *optionName = NULL;     char *optionValue = NULL;-    char *actionTest = NULL;-    char *actionTmp = NULL;-    char *realOption = NULL;     char tmp[MAX_OPTION_LENGTH];     CompOption *option = NULL, *o;     int nOption;@@ -534,10 +682,9 @@ iniLoadOptionsFromFile (CompDisplay *d, 	    option = compGetDisplayOptions (d, &nOption);     } -    IniActionProxy actionProxy;--    initActionProxy (&actionProxy);-+    IniAction action;+    action.realOptionName = NULL;+    Bool continueReading = FALSE;     while (fgets (&tmp[0], MAX_OPTION_LENGTH, optionFile) != NULL)     { 	status = FALSE;@@ -554,42 +701,6 @@ iniLoadOptionsFromFile (CompDisplay *d, 	    o = compFindOption (option, nOption, optionName, 0); 	    if (o) 	    {-		if (actionProxy.nSet != 0)-		{-		    /* there is an action where a line is-		       missing / out of order.  realOption-		       should still be set from the last loop */--		    value.action.type       = actionProxy.type;-		    value.action.key        = actionProxy.key;-		    value.action.button     = actionProxy.button;-		    value.action.bell       = actionProxy.bell;-		    value.action.edgeMask   = actionProxy.edgeMask;-		    value.action.edgeButton = actionProxy.edgeButton;--		    if (plugin && p)-		    {-			if (s)-			    status = (*s->setScreenOptionForPlugin) (s,-								     plugin,-								     realOption,-								     &value);-			else-			    status = (*d->setDisplayOptionForPlugin) (d, plugin,-								      realOption,-								      &value);-		    }-		    else-		    {-			if (s)-			    status = (*s->setScreenOption) (s, realOption, &value);-			else-			    status = (*d->setDisplayOption) (d, realOption, &value);-		    }--		    initActionProxy (&actionProxy);-		}- 		value = o->value;  		switch (o->type)@@ -656,147 +767,61 @@ iniLoadOptionsFromFile (CompDisplay *d, 	    } 	    else 	    {-		/* option not found, it might be an action option */-		actionTmp = strchr (optionName, '_');-		if (actionTmp)+		// an action has several values, so we need+		// to read more then one line into our buffer+		continueReading = parseAction(d, optionName, optionValue, &action);+	    }++	    // parsing action finished, write it+	    if (action.realOptionName &&+		!continueReading)+	    {+		o = compFindOption (option, nOption, action.realOptionName, 0);+		value = o->value;++		value.action.type = action.a.type;+		value.action.key = action.a.key;+		value.action.button = action.a.button;+		value.action.bell = action.a.bell;+		value.action.edgeMask = action.a.edgeMask;+		value.action.edgeButton = action.a.edgeButton;++		if (plugin) 		{-		    actionTmp++;  /* skip the _ */-		    actionTest = strchr (actionTmp, '_');-		    while (actionTest)-		    {-			actionTmp++;-			actionTest = strchr (actionTmp, '_');-			if (actionTest)-			    actionTmp = strchr (actionTmp, '_');-		    }+		    if (s)+			status = (*s->setScreenOptionForPlugin) (s, plugin, action.realOptionName, &value);+		    else+			status = (*d->setDisplayOptionForPlugin) (d, plugin, action.realOptionName, &value);+		}+		else+		{+		    if (s)+			status = (*s->setScreenOption) (s, action.realOptionName, &value);+		    else+			status = (*d->setDisplayOption) (d, action.realOptionName, &value);+		} -		    if (actionTmp)-		    {-			/* find the real option */-			int len = strlen (optionName) - strlen (actionTmp) - 1;-			realOption = realloc (realOption, sizeof (char) * len);-			strncpy (realOption, optionName, len);-			realOption[len] = '\0';-			o = compFindOption (option, nOption, realOption, 0);--			if (o)-			{-			    value = o->value;--			    if (strcmp (actionTmp, "key") == 0)-			    {-				if (!*optionValue ||-				    strcasecmp (optionValue, "disabled") == 0)-				{-				    actionProxy.type &= ~CompBindingTypeKey;-				}-				else-				{-				    if (stringToKeyBinding (d,-							     optionValue,-							     &actionProxy.key))-					actionProxy.type |= CompBindingTypeKey;-				}-				actionProxy.nSet++;-			    }-			    else if (strcmp (actionTmp, "button") == 0)-			    {-				if (!*optionValue ||-				    strcasecmp (optionValue, "disabled") == 0)-				{-				    actionProxy.type &= ~CompBindingTypeButton;-				}-				else-				{-				    if (stringToButtonBinding (d, optionValue,-								&actionProxy.button))-					actionProxy.type |= CompBindingTypeButton;-				}-				actionProxy.nSet++;-			    }-			    else if (strcmp (actionTmp, "edge") == 0)-			    {-				actionProxy.edgeMask = 0;-				if (optionValue[0] != '\0')-				{-				    int i, e;-				    CompListValue edges;--				    if (csvToList (optionValue, &edges, CompOptionTypeString))-				    {-					for (i = 0; i < SCREEN_EDGE_NUM; i++)-					{-					    for (e=0; e<edges.nValue; e++)-					    {-						if (strcasecmp (edges.value[e].s, edgeToString (i)) == 0)-						    actionProxy.edgeMask |= 1 << i;-					    }-					}-				    }-				}-				actionProxy.nSet++;-			    }-			    else if (strcmp (actionTmp, "edgebutton") == 0)-			    {-				actionProxy.edgeButton = atoi (optionValue);--				if (actionProxy.edgeButton)-				    actionProxy.type |= CompBindingTypeEdgeButton;-				else-				    actionProxy.type &= ~CompBindingTypeEdgeButton;--				actionProxy.nSet++;-			    }-			    else if (strcmp (actionTmp, "bell") == 0)-			    {-				actionProxy.bell = (Bool) atoi (optionValue);-				actionProxy.nSet++;-			    }--			    if (actionProxy.nSet >= N_ACTION_PARTS)-			    {-				value.action.type       = actionProxy.type;-				value.action.key        = actionProxy.key;-				value.action.button     = actionProxy.button;-				value.action.bell       = actionProxy.bell;-				value.action.edgeMask   = actionProxy.edgeMask;-				value.action.edgeButton = actionProxy.edgeButton;--				if (plugin)-				{-				    if (s)-					status = (*s->setScreenOptionForPlugin) (s,-										plugin,-										realOption,-										&value);-				    else-					status = (*d->setDisplayOptionForPlugin) (d, plugin,-										realOption,-										&value);-				}-				else-				{-				    if (s)-					status = (*s->setScreenOption) (s, realOption, &value);-				    else-					status = (*d->setDisplayOption) (d, realOption, &value);-				}--				initActionProxy (&actionProxy);-			    }-			}-		    }+		// clear the buffer+		free(action.realOptionName);+		action.realOptionName = NULL;++		// we missed the current line because we exited it in the first call+		if (!o && action.valueMasks == ACTION_VALUES_ALL) {+		    action.valueMasks = 0;+		    parseAction(d, optionName, optionValue, &action);+		} else {+		    action.valueMasks = 0; 		} 	    } 	}-    } -    if (optionName)-	free (optionName);-    if (optionValue)-	free (optionValue);-    if (realOption)-	free (realOption);+	// clear up+	if (optionName)+	    free (optionName);+	if (optionValue)+	    free (optionValue);+	continueReading = FALSE;+    }       return TRUE; }